diff --git a/Makefile b/Makefile index 5084c408..aaba3c4c 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ $(foreach a,$(ALL_ARCHES),$(eval $(call build_arch_template,$(a)))) # Available build architectures based on the current suite BUILD_ARCHES_wheezy := amd64 powerpc BUILD_ARCHES_jessie := amd64 powerpc armel -BUILD_ARCHES_stretch := arm64 amd64 +BUILD_ARCHES_stretch := arm64 amd64 armel # Build available architectures by default. .DEFAULT_GOAL := all diff --git a/builds/any/installer/installer.sh.in b/builds/any/installer/installer.sh.in index c5e33f3b..401c4dd4 100644 --- a/builds/any/installer/installer.sh.in +++ b/builds/any/installer/installer.sh.in @@ -19,6 +19,7 @@ if test "$ARCH" != "$IARCH"; then # identify mappings between kernel arch and debian arch case "$IARCH:$ARCH" in armel:armv7l) ;; + armhf:armv7l) ;; arm64:aarch64) ;; powerpc:ppc) ;; *) diff --git a/builds/any/rootfs/jessie/common/armel-base-packages.yml b/builds/any/rootfs/jessie/common/armel-base-packages.yml index 71c41a67..6664ed16 100644 --- a/builds/any/rootfs/jessie/common/armel-base-packages.yml +++ b/builds/any/rootfs/jessie/common/armel-base-packages.yml @@ -1 +1,2 @@ - u-boot-tools +- onl-kernel-4.14-lts-armel-iproc-all-modules diff --git a/builds/any/rootfs/stretch/common/armel-base-packages.yml b/builds/any/rootfs/stretch/common/armel-base-packages.yml index 71c41a67..6664ed16 100644 --- a/builds/any/rootfs/stretch/common/armel-base-packages.yml +++ b/builds/any/rootfs/stretch/common/armel-base-packages.yml @@ -1 +1,2 @@ - u-boot-tools +- onl-kernel-4.14-lts-armel-iproc-all-modules diff --git a/builds/armel/rootfs/builds/Makefile b/builds/armel/rootfs/builds/Makefile index 46d1ce72..a83c7d3e 100644 --- a/builds/armel/rootfs/builds/Makefile +++ b/builds/armel/rootfs/builds/Makefile @@ -4,7 +4,9 @@ include $(ONL)/make/config.armel.mk # Default to include all available powerpc platforms. # You override this with you own list or yaml file. # +ifndef PLATFORM_LIST export PLATFORM_LIST=$(shell onlpm --list-platforms --arch armel --csv ) +endif RFS_CONFIG := $(ONL)/builds/any/rootfs/$(ONL_DEBIAN_SUITE)/standard/standard.yml RFS_DIR := rootfs-armel.d diff --git a/make/config.armhf.mk b/make/config.armhf.mk new file mode 100644 index 00000000..7aba1e5b --- /dev/null +++ b/make/config.armhf.mk @@ -0,0 +1,12 @@ +############################################################ +# +# Open Network Linux +# +############################################################ +include $(ONL)/make/config.mk +export TOOLCHAIN := arm-linux-gnueabihf +export CROSS_COMPILER := $(TOOLCHAIN)- +export ARCH := armhf +export UARCH := ARMHF +export ARCH_BOOT := uboot +export __$(ARCH)__ := 1 diff --git a/make/dtbs.mk b/make/dtbs.mk index 48753f1b..dd8b27d1 100644 --- a/make/dtbs.mk +++ b/make/dtbs.mk @@ -13,14 +13,30 @@ ifndef DTB_LIST DTB_LIST := $(patsubst %.dts,%.dtb,$(DTS_LIST)) endif -%.dtb: %.dts - $(ONL)/tools/dtc -I dts -O dtb -o $@ $< +ifndef DTC + ifdef KERNEL + DTC := $(shell $(ONLPM) --find-file $(KERNEL) dtc) + ifeq ($(DTC),) + $(error No device tree compiler.) + endif + else + DTC := $(ONL)/tools/dtc + endif +endif -.DEFAULT_GOAL := $(DTB_LIST) +%.dtb: %.dts + cpp -nostdinc -undef -x assembler-with-cpp $(foreach inc,$(INCLUDES),-I$(inc) ) $< > $(notdir $<).i + $(DTC) $(foreach inc,$(INCLUDES),-i$(inc) ) $(DTC_OPTIONS) -I dts -O dtb -o $@ $(notdir $<).i + rm $(notdir $<).i + +.DEFAULT_GOAL := dtbs + +dtbs: $(DTB_LIST) + echo $(DTB_LIST) $(VPATH) + $(MAKE) setup-clean $(DTB_LIST): setup clean:: - rm -rf *.dtb - setup:: +setup-clean:: diff --git a/make/kbuild.mk b/make/kbuild.mk index 12052db8..8be2961b 100644 --- a/make/kbuild.mk +++ b/make/kbuild.mk @@ -174,7 +174,7 @@ endif MODSYNCLIST_DEFAULT := .config Module.symvers Makefile include scripts drivers \ arch/x86/include arch/x86/Makefile \ arch/powerpc/include arch/powerpc/Makefile arch/powerpc/lib arch/powerpc/boot/dts \ - arch/arm/include arch/arm/Makefile arch/arm/lib arch/arm/boot/dts + arch/arm/include arch/arm/Makefile arch/arm/lib arch/arm/boot/dts arch/arm/kernel MODSYNCLIST := $(MODSYNCLIST_DEFAULT) $(MODSYNCLIST_EXTRA) $(K_MODSYNCLIST) diff --git a/make/kmodule.mk b/make/kmodule.mk index aa84a07c..e87225a8 100644 --- a/make/kmodule.mk +++ b/make/kmodule.mk @@ -26,4 +26,4 @@ endif modules: rm -rf lib - ARCH=$(ARCH) $(ONL)/tools/scripts/kmodbuild.sh "$(KERNELS)" "$(KMODULES)" "$(SUBDIR)" + ARCH=$(ARCH) $(ONL)/tools/scripts/kmodbuild.sh "$(KERNELS)" "$(KMODULES)" "$(SUBDIR)" "$(KINCLUDES)" diff --git a/make/pkg.mk b/make/pkg.mk index 2589308e..98d9dfd6 100644 --- a/make/pkg.mk +++ b/make/pkg.mk @@ -14,7 +14,7 @@ include $(ONL)/make/config.mk # directory tree. # ifndef ARCHES -ARCHES := amd64 powerpc armel arm64 all +ARCHES := amd64 powerpc armel armhf arm64 all endif ONLPM_ENVIRONMENT = \ diff --git a/packages/base/all/initrds/loader-initrd-files/src/bin/swiprep b/packages/base/all/initrds/loader-initrd-files/src/bin/swiprep index 88cb76c6..d5a72f8e 100755 --- a/packages/base/all/initrds/loader-initrd-files/src/bin/swiprep +++ b/packages/base/all/initrds/loader-initrd-files/src/bin/swiprep @@ -138,7 +138,7 @@ case $(uname -m) in ARCH_LIST="x86_64 amd64" ;; armv7l) - ARCH_LIST="armel" + ARCH_LIST="armel armhf" ;; aarch64) ARCH_LIST="arm64" diff --git a/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-uboot.yml b/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-uboot.yml index 25887edd..955ae7ff 100644 --- a/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-uboot.yml +++ b/packages/base/all/vendor-config-onl/src/lib/platform-config-defaults-uboot.yml @@ -46,12 +46,12 @@ default: =: kernel-3.2-lts-arm-iproc-all.bin.gz <<: *arm-iproc-kernel-package - arm-iproc-kernel-4-4-package: &arm-iproc-kernel-4-4-package - package: onl-kernel-4.4-lts-arm-iproc-all:armel + armel-iproc-4-14-kernel-package: &armel-iproc-4-14-kernel-package + package: onl-kernel-4.14-lts-armel-iproc-all:armel - arm-iproc-kernel-4-4: &arm-iproc-kernel-4-4 - =: kernel-4.4-lts-arm-iproc-all.bin.gz - <<: *arm-iproc-kernel-4-4-package + armel-iproc-4-14-kernel: &armel-iproc-4-14-kernel + =: kernel-4.14-lts-armel-iproc-all.bin.gz + <<: *armel-iproc-4-14-kernel-package arm64-kernel-package: &arm64-kernel-package package: onl-kernel-4.9-lts-arm64-all:arm64 diff --git a/packages/base/all/vendor-config-onl/src/python/onl/platform/baseconfig.py b/packages/base/all/vendor-config-onl/src/python/onl/platform/baseconfig.py index c30832bb..779009aa 100644 --- a/packages/base/all/vendor-config-onl/src/python/onl/platform/baseconfig.py +++ b/packages/base/all/vendor-config-onl/src/python/onl/platform/baseconfig.py @@ -33,6 +33,7 @@ def baseconfig(): 'i386-linux-gnu', 'x86_64-linux-gnu', 'arm-linux-gnueabi', + 'arm-linux-gnueabihf', 'aarch64-linux-gnu', ] diff --git a/packages/base/any/fit/loader/builds/Makefile b/packages/base/any/fit/loader/builds/Makefile index f257e3b8..840f6fa7 100644 --- a/packages/base/any/fit/loader/builds/Makefile +++ b/packages/base/any/fit/loader/builds/Makefile @@ -4,7 +4,7 @@ endif .PHONY: onl-loader-fit.itb onl-loader-fit.its -onl-loader-fit.itb: +onl-loader-fit.itb: its $(ONL)/tools/flat-image-tree.py --initrd onl-loader-initrd:$(ARCH),onl-loader-initrd-$(ARCH).cpio.gz --arch $(ARCH) --add-platform initrd --itb $@ $(ONLPM) --copy-file onl-loader-initrd:$(ARCH) manifest.json . diff --git a/packages/base/any/kernels/3.2-lts/configs/arm-iproc-all/arm-iproc-all.config b/packages/base/any/kernels/3.2-lts/configs/arm-iproc-all/arm-iproc-all.config index 6d420e0f..e70dd3b3 100644 --- a/packages/base/any/kernels/3.2-lts/configs/arm-iproc-all/arm-iproc-all.config +++ b/packages/base/any/kernels/3.2-lts/configs/arm-iproc-all/arm-iproc-all.config @@ -868,7 +868,7 @@ CONFIG_EEPROM_AT25=y # CONFIG_EEPROM_93CX6 is not set # CONFIG_EEPROM_93XX46 is not set # CONFIG_EEPROM_SFF_8436 is not set -CONFIG_EEPROM_OPTOE=y +CONFIG_EEPROM_ACCTON_AS4610_SFP=y # CONFIG_CB710_CORE is not set # CONFIG_IWMC3200TOP is not set @@ -1497,7 +1497,7 @@ CONFIG_SENSORS_W83781D=y # CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set -CONFIG_SENSORS_ACCTON_AS4610_CPLD=y +CONFIG_SENSORS_ACCTON_I2C_CPLD=y CONFIG_SENSORS_ACCTON_AS4610_FAN=y CONFIG_SENSORS_ACCTON_AS4610_PSU=y CONFIG_SENSORS_YM2651Y=y diff --git a/packages/base/any/kernels/3.2-lts/configs/arm-iproc-all/patches/arch_arm_boot_dts_accton_as4610_54.dts.patch b/packages/base/any/kernels/3.2-lts/configs/arm-iproc-all/patches/arch_arm_boot_dts_accton_as4610_54.dts.patch index 5d5e0485..7737f9ef 100644 --- a/packages/base/any/kernels/3.2-lts/configs/arm-iproc-all/patches/arch_arm_boot_dts_accton_as4610_54.dts.patch +++ b/packages/base/any/kernels/3.2-lts/configs/arm-iproc-all/patches/arch_arm_boot_dts_accton_as4610_54.dts.patch @@ -1,6 +1,6 @@ --- /dev/null +++ b/arch/arm/boot/dts/accton_as4610_54.dts -@@ -0,0 +1,256 @@ +@@ -0,0 +1,250 @@ +/* + * Accton AS4610 54 Device Tree Source + * @@ -117,7 +117,7 @@ + cpld@1,0 { + #address-cells = <1>; + #size-cells = <1>; -+ compatible = "accton,as4610_54_cpld"; ++ compatible = "accton,as4610-54-cpld"; + label = "cpld"; + reg = <0x30>; + }; @@ -142,8 +142,8 @@ + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; -+ optoe@50 { -+ compatible = "optoe2"; ++ sfp_eeprom@50 { ++ compatible = "at,24c04"; + reg = <0x50>; + label = "port49"; + }; @@ -154,8 +154,8 @@ + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; -+ optoe@50 { -+ compatible = "optoe2"; ++ sfp_eeprom@50 { ++ compatible = "at,24c04"; + reg = <0x50>; + label = "port50"; + }; @@ -166,8 +166,8 @@ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; -+ optoe@50 { -+ compatible = "optoe2"; ++ sfp_eeprom@50 { ++ compatible = "at,24c04"; + reg = <0x50>; + label = "port51"; + }; @@ -178,8 +178,8 @@ + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; -+ optoe@50 { -+ compatible = "optoe2"; ++ sfp_eeprom@50 { ++ compatible = "at,24c04"; + reg = <0x50>; + label = "port52"; + }; @@ -190,10 +190,9 @@ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; -+ optoe@50 { -+ compatible = "optoe1"; ++ sfp_eeprom@50 { ++ compatible = "at,24c04"; + reg = <0x50>; -+ label = "port53"; + }; + }; + @@ -202,10 +201,9 @@ + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; -+ optoe@50 { -+ compatible = "optoe1"; ++ sfp_eeprom@50 { ++ compatible = "at,24c04"; + reg = <0x50>; -+ label = "port54"; + }; + }; + @@ -214,21 +212,17 @@ + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; -+ psu1_eeprom@50 { -+ compatible = "accton,as4610_psu1"; ++ psu_eeprom@50 { ++ compatible = "at,24c02"; + reg = <0x50>; ++ label = "psu1_eeprom"; ++ read-only; + }; -+ psu1_pmbus@58 { -+ compatible = "3y-power,ym1921"; -+ reg = <0x58>; -+ }; -+ psu2_eeprom@51 { -+ compatible = "accton,as4610_psu2"; ++ psu_eeprom@51 { ++ compatible = "at,24c02"; + reg = <0x51>; -+ }; -+ psu2_pmbus@59 { -+ compatible = "3y-power,ym1921"; -+ reg = <0x59>; ++ label = "psu2_eeprom"; ++ read-only; + }; + }; + diff --git a/packages/base/any/kernels/3.2-lts/configs/arm-iproc-all/patches/platform-accton-as4610-device-drivers.patch b/packages/base/any/kernels/3.2-lts/configs/arm-iproc-all/patches/platform-accton-as4610-device-drivers.patch index 3964bfac..66ba4882 100644 --- a/packages/base/any/kernels/3.2-lts/configs/arm-iproc-all/patches/platform-accton-as4610-device-drivers.patch +++ b/packages/base/any/kernels/3.2-lts/configs/arm-iproc-all/patches/platform-accton-as4610-device-drivers.patch @@ -1,5 +1,162 @@ Device driver patches for accton as4610 54 (fan/psu/cpld/led/sfp) +diff --git a/arch/arm/boot/dts/accton_as4610_54.dts b/arch/arm/boot/dts/accton_as4610_54.dts +index 9276c0a..8848f8c 100644 +--- a/arch/arm/boot/dts/accton_as4610_54.dts ++++ b/arch/arm/boot/dts/accton_as4610_54.dts +@@ -105,46 +105,46 @@ + }; + + i2c0: i2c@18038000 { +- compatible = "iproc-smb"; +- reg = <0x18038000 0x1000>; ++ compatible = "iproc-smb"; ++ reg = <0x18038000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = < 127 >; ++ clock-frequency = <400000>; ++ cpld@1,0 { + #address-cells = <1>; +- #size-cells = <0>; +- interrupts = < 127 >; +- clock-frequency = <400000>; +- cpld@1,0 { +- #address-cells = <1>; +- #size-cells = <1>; +- compatible = "accton,as4610-54-cpld"; +- label = "cpld"; +- reg = <0x30>; +- }; ++ #size-cells = <1>; ++ compatible = "accton,as4610_54_cpld"; ++ label = "cpld"; ++ reg = <0x30>; ++ }; + }; + + i2c1: i2c@1803b000 { +- compatible = "iproc-smb"; +- reg = <0x1803b000 0x1000>; ++ compatible = "iproc-smb"; ++ reg = <0x1803b000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = < 128 >; ++ clock-frequency = <100000>; ++ mux@70 { ++ compatible = "ti,pca9548"; ++ reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; +- interrupts = < 128 >; +- clock-frequency = <100000>; +- mux@70 { +- compatible = "ti,pca9548"; +- reg = <0x70>; ++ deselect-on-exit; ++ ++ // SFP+ 1 ++ i2c@0 { + #address-cells = <1>; + #size-cells = <0>; +- deselect-on-exit; +- +- // SFP+ 1 +- i2c@0 { +- #address-cells = <1>; +- #size-cells = <0>; +- reg = <0>; +- sfp_eeprom@50 { +- compatible = "at,24c04"; +- reg = <0x50>; +- label = "port49"; +- }; ++ reg = <0>; ++ sfp_eeprom@50 { ++ compatible = "at,as4610_sfp1"; ++ reg = <0x50>; ++ label = "port49"; + }; ++ }; + + // SFP+ 2 + i2c@1 { +@@ -152,7 +152,7 @@ + #size-cells = <0>; + reg = <1>; + sfp_eeprom@50 { +- compatible = "at,24c04"; ++ compatible = "accton,as4610_sfp2"; + reg = <0x50>; + label = "port50"; + }; +@@ -164,7 +164,7 @@ + #size-cells = <0>; + reg = <2>; + sfp_eeprom@50 { +- compatible = "at,24c04"; ++ compatible = "accton,as4610_sfp3"; + reg = <0x50>; + label = "port51"; + }; +@@ -176,7 +176,7 @@ + #size-cells = <0>; + reg = <3>; + sfp_eeprom@50 { +- compatible = "at,24c04"; ++ compatible = "accton,as4610_sfp4"; + reg = <0x50>; + label = "port52"; + }; +@@ -188,7 +188,7 @@ + #size-cells = <0>; + reg = <4>; + sfp_eeprom@50 { +- compatible = "at,24c04"; ++ compatible = "accton,as4610_sfp5"; + reg = <0x50>; + }; + }; +@@ -199,7 +199,7 @@ + #size-cells = <0>; + reg = <5>; + sfp_eeprom@50 { +- compatible = "at,24c04"; ++ compatible = "accton,as4610_sfp6"; + reg = <0x50>; + }; + }; +@@ -209,17 +209,21 @@ + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; +- psu_eeprom@50 { +- compatible = "at,24c02"; ++ psu1_eeprom@50 { ++ compatible = "accton,as4610_psu1"; + reg = <0x50>; +- label = "psu1_eeprom"; +- read-only; + }; +- psu_eeprom@51 { +- compatible = "at,24c02"; ++ psu1_pmbus@58 { ++ compatible = "3y-power,ym1921"; ++ reg = <0x58>; ++ }; ++ psu2_eeprom@51 { ++ compatible = "accton,as4610_psu2"; + reg = <0x51>; +- label = "psu2_eeprom"; +- read-only; ++ }; ++ psu2_pmbus@59 { ++ compatible = "3y-power,ym1921"; ++ reg = <0x59>; + }; + }; + diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 5c984a6..df89e25 100644 --- a/drivers/hwmon/Kconfig @@ -8,18 +165,18 @@ index 5c984a6..df89e25 100644 help Support for the A/D converter on MC13783 PMIC. -+config SENSORS_ACCTON_AS4610_CPLD -+ tristate "Accton as4610 cpld" ++config SENSORS_ACCTON_I2C_CPLD ++ tristate "Accton i2c cpld" + depends on I2C + help -+ If you say yes here you get support for Accton as4610 cpld. ++ If you say yes here you get support for Accton i2c cpld. + + This driver can also be built as a module. If so, the module will -+ be called accton_as4610_cpld. ++ be called accton_i2c_cpld. + +config SENSORS_ACCTON_AS4610_FAN + tristate "Accton as4610 fan" -+ depends on I2C && SENSORS_ACCTON_AS4610_CPLD ++ depends on I2C && SENSORS_ACCTON_I2C_CPLD + help + If you say yes here you get support for Accton as4610 fan. + @@ -28,7 +185,7 @@ index 5c984a6..df89e25 100644 + +config SENSORS_ACCTON_AS4610_PSU + tristate "Accton as4610 psu" -+ depends on I2C && SENSORS_ACCTON_AS4610_CPLD ++ depends on I2C && SENSORS_ACCTON_I2C_CPLD + help + If you say yes here you get support for Accton as4610 psu. + @@ -56,7 +213,7 @@ index ff3a18e..39c9888 100644 obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o -+obj-$(CONFIG_SENSORS_ACCTON_AS4610_CPLD) += accton_as4610_cpld.o ++obj-$(CONFIG_SENSORS_ACCTON_I2C_CPLD) += accton_i2c_cpld.o +obj-$(CONFIG_SENSORS_ACCTON_AS4610_FAN) += accton_as4610_fan.o +obj-$(CONFIG_SENSORS_ACCTON_AS4610_PSU) += accton_as4610_psu.o obj-$(CONFIG_SENSORS_AD7314) += ad7314.o @@ -70,616 +227,12 @@ index ff3a18e..39c9888 100644 obj-$(CONFIG_PMBUS) += pmbus/ -diff --git a/drivers/hwmon/accton_as4610_cpld.c b/drivers/hwmon/accton_as4610_cpld.c -new file mode 100644 -index 0000000..26b3ae5 ---- /dev/null -+++ b/drivers/hwmon/accton_as4610_cpld.c -@@ -0,0 +1,598 @@ -+/* -+ * Copyright (C) Brandon Chuang -+ * -+ * This module supports the accton cpld that hold the channel select -+ * mechanism for other i2c slave devices, such as SFP. -+ * This includes the: -+ * Accton as4610_54 CPLD -+ * -+ * Based on: -+ * pca954x.c from Kumar Gala -+ * Copyright (C) 2006 -+ * -+ * Based on: -+ * pca954x.c from Ken Harrenstien -+ * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) -+ * -+ * Based on: -+ * i2c-virtual_cb.c from Brian Kuschak -+ * and -+ * pca9540.c from Jean Delvare . -+ * -+ * This file is licensed under the terms of the GNU General Public -+ * License version 2. This program is licensed "as is" without any -+ * warranty of any kind, whether express or implied. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define I2C_RW_RETRY_COUNT 10 -+#define I2C_RW_RETRY_INTERVAL 60 /* ms */ -+ -+static LIST_HEAD(cpld_client_list); -+static struct mutex list_lock; -+ -+struct cpld_client_node { -+ struct i2c_client *client; -+ struct list_head list; -+}; -+ -+enum cpld_type { -+ as4610_54_cpld -+}; -+ -+struct as4610_54_cpld_data { -+ enum cpld_type type; -+ struct device *hwmon_dev; -+ struct mutex update_lock; -+}; -+ -+static const struct i2c_device_id as4610_54_cpld_id[] = { -+ { "as4610_54_cpld", as4610_54_cpld }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, as4610_54_cpld_id); -+ -+#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index -+#define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index -+#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index -+#define TRANSCEIVER_TXFAULT_ATTR_ID(index) MODULE_TXFAULT_##index -+ -+enum as4610_54_cpld1_sysfs_attributes { -+ CPLD_VERSION, -+ PRODUCT_ID, -+ ACCESS, -+ MODULE_PRESENT_ALL, -+ MODULE_RXLOS_ALL, -+ /* transceiver attributes */ -+ TRANSCEIVER_PRESENT_ATTR_ID(1), -+ TRANSCEIVER_PRESENT_ATTR_ID(2), -+ TRANSCEIVER_PRESENT_ATTR_ID(3), -+ TRANSCEIVER_PRESENT_ATTR_ID(4), -+ TRANSCEIVER_PRESENT_ATTR_ID(5), -+ TRANSCEIVER_PRESENT_ATTR_ID(6), -+ TRANSCEIVER_TXDISABLE_ATTR_ID(1), -+ TRANSCEIVER_TXDISABLE_ATTR_ID(2), -+ TRANSCEIVER_TXDISABLE_ATTR_ID(3), -+ TRANSCEIVER_TXDISABLE_ATTR_ID(4), -+ TRANSCEIVER_RXLOS_ATTR_ID(1), -+ TRANSCEIVER_RXLOS_ATTR_ID(2), -+ TRANSCEIVER_RXLOS_ATTR_ID(3), -+ TRANSCEIVER_RXLOS_ATTR_ID(4), -+ TRANSCEIVER_TXFAULT_ATTR_ID(1), -+ TRANSCEIVER_TXFAULT_ATTR_ID(2), -+ TRANSCEIVER_TXFAULT_ATTR_ID(3), -+ TRANSCEIVER_TXFAULT_ATTR_ID(4), -+}; -+ -+/* sysfs attributes for hwmon -+ */ -+static ssize_t show_status(struct device *dev, struct device_attribute *da, -+ char *buf); -+static ssize_t show_present_all(struct device *dev, struct device_attribute *da, -+ char *buf); -+static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, -+ char *buf); -+static ssize_t access(struct device *dev, struct device_attribute *da, -+ const char *buf, size_t count); -+static ssize_t show_version(struct device *dev, struct device_attribute *da, -+ char *buf); -+static ssize_t show_product_id(struct device *dev, struct device_attribute *attr, -+ char *buf); -+static int as4610_54_cpld_read_internal(struct i2c_client *client, u8 reg); -+static int as4610_54_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value); -+ -+/* transceiver attributes */ -+#define DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(index) \ -+ static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, NULL, MODULE_PRESENT_##index) -+#define DECLARE_TRANSCEIVER_PRESENT_ATTR(index) &sensor_dev_attr_module_present_##index.dev_attr.attr -+ -+#define DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(index) \ -+ static SENSOR_DEVICE_ATTR(module_rx_los_##index, S_IRUGO, show_status, NULL, MODULE_RXLOS_##index); \ -+ static SENSOR_DEVICE_ATTR(module_tx_fault_##index, S_IRUGO, show_status, NULL, MODULE_TXFAULT_##index) -+ -+#define DECLARE_SFP_TRANSCEIVER_ATTR(index) \ -+ &sensor_dev_attr_module_rx_los_##index.dev_attr.attr, \ -+ &sensor_dev_attr_module_tx_fault_##index.dev_attr.attr -+ -+static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, NULL, CPLD_VERSION); -+static SENSOR_DEVICE_ATTR(access, S_IWUSR, NULL, access, ACCESS); -+static SENSOR_DEVICE_ATTR(product_id, S_IRUGO, show_product_id, NULL, PRODUCT_ID); -+/* transceiver attributes */ -+static SENSOR_DEVICE_ATTR(module_present_all, S_IRUGO, show_present_all, NULL, MODULE_PRESENT_ALL); -+static SENSOR_DEVICE_ATTR(module_rx_los_all, S_IRUGO, show_rxlos_all, NULL, MODULE_RXLOS_ALL); -+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(1); -+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(2); -+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(3); -+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(4); -+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(5); -+DECLARE_TRANSCEIVER_PRESENT_SENSOR_DEVICE_ATTR(6); -+ -+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(1); -+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(2); -+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(3); -+DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR(4); -+ -+static struct attribute *as4610_54_cpld_attributes[] = { -+ &sensor_dev_attr_version.dev_attr.attr, -+ &sensor_dev_attr_access.dev_attr.attr, -+ /* transceiver attributes */ -+ &sensor_dev_attr_module_present_all.dev_attr.attr, -+ &sensor_dev_attr_module_rx_los_all.dev_attr.attr, -+ DECLARE_TRANSCEIVER_PRESENT_ATTR(1), -+ DECLARE_TRANSCEIVER_PRESENT_ATTR(2), -+ DECLARE_TRANSCEIVER_PRESENT_ATTR(3), -+ DECLARE_TRANSCEIVER_PRESENT_ATTR(4), -+ DECLARE_TRANSCEIVER_PRESENT_ATTR(5), -+ DECLARE_TRANSCEIVER_PRESENT_ATTR(6), -+ DECLARE_SFP_TRANSCEIVER_ATTR(1), -+ DECLARE_SFP_TRANSCEIVER_ATTR(2), -+ DECLARE_SFP_TRANSCEIVER_ATTR(3), -+ DECLARE_SFP_TRANSCEIVER_ATTR(4), -+ NULL -+}; -+ -+static const struct attribute_group as4610_54_cpld_group = { -+ .attrs = as4610_54_cpld_attributes, -+}; -+ -+static ssize_t show_present_all(struct device *dev, struct device_attribute *da, -+ char *buf) -+{ -+ int i, status, present = 0; -+ u8 values[3] = {0}; -+ u8 regs[] = {0x2, 0x3, 0x21}; -+ struct i2c_client *client = to_i2c_client(dev); -+ struct as4610_54_cpld_data *data = i2c_get_clientdata(client); -+ -+ mutex_lock(&data->update_lock); -+ -+ for (i = 0; i < ARRAY_SIZE(regs); i++) { -+ status = as4610_54_cpld_read_internal(client, regs[i]); -+ -+ if (status < 0) { -+ goto exit; -+ } -+ -+ switch (i) { -+ case 0: -+ present |= (status & BIT(6)) >> 6; /* port 25/49 */ -+ present |= (status & BIT(2)) >> 1; /* port 26/50 */ -+ break; -+ case 1: -+ present |= (status & BIT(6)) >> 4; /* port 27/51 */ -+ present |= (status & BIT(2)) << 1; /* port 28/52 */ -+ break; -+ case 2: -+ present |= (status & BIT(0)) << 4; /* port 29/53 */ -+ present |= (status & BIT(4)) << 1; /* port 30/54 */ -+ break; -+ default: -+ break; -+ } -+ } -+ -+ mutex_unlock(&data->update_lock); -+ -+ return sprintf(buf, "%.2x\n", present); -+ -+exit: -+ mutex_unlock(&data->update_lock); -+ return status; -+} -+ -+static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da, -+ char *buf) -+{ -+ int i, status, rx_los = 0; -+ u8 values[2] = {0}; -+ u8 regs[] = {0x2, 0x3}; -+ struct i2c_client *client = to_i2c_client(dev); -+ struct as4610_54_cpld_data *data = i2c_get_clientdata(client); -+ -+ mutex_lock(&data->update_lock); -+ -+ for (i = 0; i < ARRAY_SIZE(regs); i++) { -+ status = as4610_54_cpld_read_internal(client, regs[i]); -+ -+ if (status < 0) { -+ goto exit; -+ } -+ switch (i) { -+ case 0: -+ rx_los |= (status & BIT(4)) >> 4; /* port 25/49 rx_los */ -+ rx_los |= (status & BIT(0)) << 1; /* port 26/50 rx_los */ -+ break; -+ case 1: -+ rx_los |= (status & BIT(4)) >> 2; /* port 27/51 rx_los */ -+ rx_los |= (status & BIT(0)) << 3; /* port 28/52 rx_los */ -+ break; -+ default: -+ break; -+ } -+ } -+ -+ mutex_unlock(&data->update_lock); -+ -+ /* Return values 25/49 -> 28/52 in order */ -+ return sprintf(buf, "%.2x\n", rx_los); -+ -+exit: -+ mutex_unlock(&data->update_lock); -+ return status; -+} -+ -+static ssize_t show_status(struct device *dev, struct device_attribute *da, -+ char *buf) -+{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); -+ struct i2c_client *client = to_i2c_client(dev); -+ struct as4610_54_cpld_data *data = i2c_get_clientdata(client); -+ int status = 0; -+ u8 reg = 0, mask = 0, revert = 0; -+ -+ switch (attr->index) { -+ case MODULE_PRESENT_1: -+ reg = 0x2; -+ mask = 0x40; -+ break; -+ case MODULE_PRESENT_2: -+ reg = 0x2; -+ mask = 0x4; -+ break; -+ case MODULE_PRESENT_3: -+ reg = 0x3; -+ mask = 0x40; -+ break; -+ case MODULE_PRESENT_4: -+ reg = 0x3; -+ mask = 0x4; -+ break; -+ case MODULE_PRESENT_5: -+ reg = 0x21; -+ mask = 0x1; -+ break; -+ case MODULE_PRESENT_6: -+ reg = 0x21; -+ mask = 0x10; -+ break; -+ case MODULE_TXFAULT_1: -+ reg = 0x2; -+ mask = 0x20; -+ break; -+ case MODULE_TXFAULT_2: -+ reg = 0x2; -+ mask = 0x2; -+ break; -+ case MODULE_TXFAULT_3: -+ reg = 0x3; -+ mask = 0x20; -+ break; -+ case MODULE_TXFAULT_4: -+ reg = 0x3; -+ mask = 0x2; -+ break; -+ case MODULE_RXLOS_1: -+ reg = 0x2; -+ mask = 0x10; -+ break; -+ case MODULE_RXLOS_2: -+ reg = 0x2; -+ mask = 0x1; -+ break; -+ case MODULE_RXLOS_3: -+ reg = 0x3; -+ mask = 0x10; -+ break; -+ case MODULE_RXLOS_4: -+ reg = 0x3; -+ mask = 0x1; -+ break; -+ default: -+ return 0; -+ } -+ -+ mutex_lock(&data->update_lock); -+ status = as4610_54_cpld_read_internal(client, reg); -+ if (unlikely(status < 0)) { -+ goto exit; -+ } -+ mutex_unlock(&data->update_lock); -+ -+ return sprintf(buf, "%d\n", !!(status & mask)); -+ -+exit: -+ mutex_unlock(&data->update_lock); -+ return status; -+} -+ -+static ssize_t access(struct device *dev, struct device_attribute *da, -+ const char *buf, size_t count) -+{ -+ int status; -+ u32 addr, val; -+ struct i2c_client *client = to_i2c_client(dev); -+ struct as4610_54_cpld_data *data = i2c_get_clientdata(client); -+ -+ if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) { -+ return -EINVAL; -+ } -+ -+ if (addr > 0xFF || val > 0xFF) { -+ return -EINVAL; -+ } -+ -+ mutex_lock(&data->update_lock); -+ status = as4610_54_cpld_write_internal(client, addr, val); -+ if (unlikely(status < 0)) { -+ goto exit; -+ } -+ mutex_unlock(&data->update_lock); -+ return count; -+ -+exit: -+ mutex_unlock(&data->update_lock); -+ return status; -+} -+ -+static void as4610_54_cpld_add_client(struct i2c_client *client) -+{ -+ struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); -+ -+ if (!node) { -+ dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); -+ return; -+ } -+ -+ node->client = client; -+ -+ mutex_lock(&list_lock); -+ list_add(&node->list, &cpld_client_list); -+ mutex_unlock(&list_lock); -+} -+ -+static void as4610_54_cpld_remove_client(struct i2c_client *client) -+{ -+ struct list_head *list_node = NULL; -+ struct cpld_client_node *cpld_node = NULL; -+ int found = 0; -+ -+ mutex_lock(&list_lock); -+ -+ list_for_each(list_node, &cpld_client_list) -+ { -+ cpld_node = list_entry(list_node, struct cpld_client_node, list); -+ -+ if (cpld_node->client == client) { -+ found = 1; -+ break; -+ } -+ } -+ -+ if (found) { -+ list_del(list_node); -+ kfree(cpld_node); -+ } -+ -+ mutex_unlock(&list_lock); -+} -+ -+static ssize_t show_product_id(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ int val = 0; -+ struct i2c_client *client = to_i2c_client(dev); -+ -+ val = i2c_smbus_read_byte_data(client, 0x1); -+ if (val < 0) { -+ dev_dbg(&client->dev, "cpld(0x%x) reg(0x1) err %d\n", client->addr, val); -+ } -+ -+ return sprintf(buf, "%d\n", (val & 0xF)); -+} -+ -+static ssize_t show_version(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ int val = 0; -+ struct i2c_client *client = to_i2c_client(dev); -+ -+ val = i2c_smbus_read_byte_data(client, 0xB); -+ -+ if (val < 0) { -+ dev_dbg(&client->dev, "cpld(0x%x) reg(0xB) err %d\n", client->addr, val); -+ } -+ -+ return sprintf(buf, "%d", val); -+} -+ -+/* I2C init/probing/exit functions */ -+static int as4610_54_cpld_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); -+ struct as4610_54_cpld_data *data; -+ int ret = -ENODEV; -+ const struct attribute_group *group = NULL; -+ -+ if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) -+ goto exit; -+ -+ data = kzalloc(sizeof(struct as4610_54_cpld_data), GFP_KERNEL); -+ if (!data) { -+ ret = -ENOMEM; -+ goto exit; -+ } -+ -+ i2c_set_clientdata(client, data); -+ mutex_init(&data->update_lock); -+ data->type = id->driver_data; -+ /* Bring QSFPs out of reset */ -+ as4610_54_cpld_write_internal(client, 0x2A, 0); -+ -+ ret = sysfs_create_group(&client->dev.kobj, &as4610_54_cpld_group); -+ if (ret) { -+ goto exit_free; -+ } -+ -+ as4610_54_cpld_add_client(client); -+ return 0; -+ -+exit_free: -+ kfree(data); -+exit: -+ return ret; -+} -+ -+static int as4610_54_cpld_remove(struct i2c_client *client) -+{ -+ struct as4610_54_cpld_data *data = i2c_get_clientdata(client); -+ const struct attribute_group *group = NULL; -+ -+ as4610_54_cpld_remove_client(client); -+ -+ /* Remove sysfs hooks */ -+ sysfs_remove_group(&client->dev.kobj, &as4610_54_cpld_group); -+ kfree(data); -+ -+ return 0; -+} -+ -+static int as4610_54_cpld_read_internal(struct i2c_client *client, u8 reg) -+{ -+ int status = 0, retry = I2C_RW_RETRY_COUNT; -+ -+ while (retry) { -+ status = i2c_smbus_read_byte_data(client, reg); -+ if (unlikely(status < 0)) { -+ msleep(I2C_RW_RETRY_INTERVAL); -+ retry--; -+ continue; -+ } -+ -+ break; -+ } -+ -+ return status; -+} -+ -+static int as4610_54_cpld_write_internal(struct i2c_client *client, u8 reg, u8 value) -+{ -+ int status = 0, retry = I2C_RW_RETRY_COUNT; -+ -+ while (retry) { -+ status = i2c_smbus_write_byte_data(client, reg, value); -+ if (unlikely(status < 0)) { -+ msleep(I2C_RW_RETRY_INTERVAL); -+ retry--; -+ continue; -+ } -+ -+ break; -+ } -+ -+ return status; -+} -+ -+int as4610_54_cpld_read(unsigned short cpld_addr, u8 reg) -+{ -+ struct list_head *list_node = NULL; -+ struct cpld_client_node *cpld_node = NULL; -+ int ret = -EPERM; -+ -+ mutex_lock(&list_lock); -+ -+ list_for_each(list_node, &cpld_client_list) -+ { -+ cpld_node = list_entry(list_node, struct cpld_client_node, list); -+ -+ if (cpld_node->client->addr == cpld_addr) { -+ ret = as4610_54_cpld_read_internal(cpld_node->client, reg); -+ break; -+ } -+ } -+ -+ mutex_unlock(&list_lock); -+ -+ return ret; -+} -+EXPORT_SYMBOL(as4610_54_cpld_read); -+ -+int as4610_54_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) -+{ -+ struct list_head *list_node = NULL; -+ struct cpld_client_node *cpld_node = NULL; -+ int ret = -EIO; -+ -+ mutex_lock(&list_lock); -+ -+ list_for_each(list_node, &cpld_client_list) -+ { -+ cpld_node = list_entry(list_node, struct cpld_client_node, list); -+ -+ if (cpld_node->client->addr == cpld_addr) { -+ ret = as4610_54_cpld_write_internal(cpld_node->client, reg, value); -+ break; -+ } -+ } -+ -+ mutex_unlock(&list_lock); -+ -+ return ret; -+} -+EXPORT_SYMBOL(as4610_54_cpld_write); -+ -+static struct i2c_driver as4610_54_cpld_driver = { -+ .driver = { -+ .name = "as4610_54_cpld", -+ .owner = THIS_MODULE, -+ }, -+ .probe = as4610_54_cpld_probe, -+ .remove = as4610_54_cpld_remove, -+ .id_table = as4610_54_cpld_id, -+}; -+ -+static int __init as4610_54_cpld_init(void) -+{ -+ mutex_init(&list_lock); -+ return i2c_add_driver(&as4610_54_cpld_driver); -+} -+ -+static void __exit as4610_54_cpld_exit(void) -+{ -+ i2c_del_driver(&as4610_54_cpld_driver); -+} -+ -+MODULE_AUTHOR("Brandon Chuang "); -+MODULE_DESCRIPTION("Accton I2C CPLD driver"); -+MODULE_LICENSE("GPL"); -+ -+module_init(as4610_54_cpld_init); -+module_exit(as4610_54_cpld_exit); -+ diff --git a/drivers/hwmon/accton_as4610_fan.c b/drivers/hwmon/accton_as4610_fan.c new file mode 100644 -index 0000000..612d5df +index 0000000..3934bcd --- /dev/null +++ b/drivers/hwmon/accton_as4610_fan.c -@@ -0,0 +1,345 @@ +@@ -0,0 +1,344 @@ +/* + * A hwmon driver for the Accton as4610 fan + * @@ -719,10 +272,9 @@ index 0000000..612d5df +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); -+extern int as4610_54_cpld_read(unsigned short cpld_addr, u8 reg); -+extern int as4610_54_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + -+/* fan related data, the index should match sysfs_fan_attributes */ ++/* fan related data, the index should match sysfs_fan_attributes ++ */ +static const u8 fan_reg[] = { + 0x2B, /* fan PWM(for all fan) */ + 0x2D, /* fan 1 speed(rpm) */ @@ -795,91 +347,91 @@ index 0000000..612d5df + +static int as4610_fan_read_value(u8 reg) +{ -+ return as4610_54_cpld_read(AS4610_CPLD_SLAVE_ADDR, reg); ++ return accton_i2c_cpld_read(AS4610_CPLD_SLAVE_ADDR, reg); +} + +static int as4610_fan_write_value(u8 reg, u8 value) +{ -+ return as4610_54_cpld_write(AS4610_CPLD_SLAVE_ADDR, reg, value); ++ return accton_i2c_cpld_write(AS4610_CPLD_SLAVE_ADDR, reg, value); +} + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ -+ reg_val &= FAN_DUTY_CYCLE_REG_MASK; -+ return (u32)((reg_val * 125 + 5)/10); ++ reg_val &= FAN_DUTY_CYCLE_REG_MASK; ++ return (u32)((reg_val * 125 + 5)/10); +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ -+ return ((u32)duty_cycle * 10 / 125); ++ return ((u32)duty_cycle * 10 / 125); +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ -+ /* Count Frequency is 1.515KHz= 0.66ms -+ * Count Period = 400 cycle = 400*0.66ms = 264ms -+ * R.P.M value = read value x3.79*60/2 -+ * 3.79 = 1000ms/264ms -+ * 60 = 1min =60s -+ * 2 = 1 rotation of fan has two pulses. -+ */ -+ return (u32)reg_val * 379 * 60 / 2 / 100; ++ /* Count Frequency is 1.515KHz= 0.66ms ++ * Count Period = 400 cycle = 400*0.66ms = 264ms ++ * R.P.M value = read value x3.79*60/2 ++ * 3.79 = 1000ms/264ms ++ * 60 = 1min =60s ++ * 2 = 1 rotation of fan has two pulses. ++ */ ++ return (u32)reg_val * 379 * 60 / 2 / 100; +} + +static u8 is_fan_fault(struct as4610_fan_data *data, enum fan_id id) +{ -+ u8 mask = (id == FAN1_ID) ? 0x20 : 0x10; ++ u8 mask = (id == FAN1_ID) ? 0x20 : 0x10; + -+ return !(data->reg_val[FAN_FAULT] & mask); ++ return !(data->reg_val[FAN_FAULT] & mask); +} + +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ -+ int error, value; ++ int error, value; + -+ error = kstrtoint(buf, 10, &value); -+ if (error) -+ return error; ++ error = kstrtoint(buf, 10, &value); ++ if (error) ++ return error; + -+ if (value < 0 || value > FAN_MAX_DUTY_CYCLE) -+ return -EINVAL; ++ if (value < 0 || value > FAN_MAX_DUTY_CYCLE) ++ return -EINVAL; + -+ as4610_fan_write_value(fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); -+ return count; ++ as4610_fan_write_value(fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); ++ return count; +} + +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); -+ struct as4610_fan_data *data = as4610_fan_update_device(dev); -+ ssize_t ret = 0; ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); ++ struct as4610_fan_data *data = as4610_fan_update_device(dev); ++ ssize_t ret = 0; + -+ if (data->valid) { -+ switch (attr->index) { -+ case FAN_DUTY_CYCLE_PERCENTAGE: -+ { -+ u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[attr->index]); -+ ret = sprintf(buf, "%u\n", duty_cycle); -+ break; -+ } -+ case FAN1_SPEED_RPM: -+ case FAN2_SPEED_RPM: -+ ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index])); -+ break; -+ case FAN1_FAULT: -+ case FAN2_FAULT: -+ ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); -+ break; -+ default: -+ break; -+ } -+ } ++ if (data->valid) { ++ switch (attr->index) { ++ case FAN_DUTY_CYCLE_PERCENTAGE: ++ { ++ u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[attr->index]); ++ ret = sprintf(buf, "%u\n", duty_cycle); ++ break; ++ } ++ case FAN1_SPEED_RPM: ++ case FAN2_SPEED_RPM: ++ ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index])); ++ break; ++ case FAN1_FAULT: ++ case FAN2_FAULT: ++ ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); ++ break; ++ default: ++ break; ++ } ++ } + -+ return ret; ++ return ret; +} + +static const struct attribute_group as4610_fan_group = { @@ -888,73 +440,73 @@ index 0000000..612d5df + +static struct as4610_fan_data *as4610_fan_update_device(struct device *dev) +{ -+ mutex_lock(&fan_data->update_lock); ++ mutex_lock(&fan_data->update_lock); + -+ if (time_after(jiffies, fan_data->last_updated + HZ + HZ / 2) || -+ !fan_data->valid) { -+ int i; ++ if (time_after(jiffies, fan_data->last_updated + HZ + HZ / 2) || ++ !fan_data->valid) { ++ int i; + -+ dev_dbg(fan_data->hwmon_dev, "Starting as4610_fan update\n"); -+ fan_data->valid = 0; ++ dev_dbg(fan_data->hwmon_dev, "Starting as4610_fan update\n"); ++ fan_data->valid = 0; + -+ /* Update fan data -+ */ -+ for (i = 0; i < ARRAY_SIZE(fan_data->reg_val); i++) { -+ int status = as4610_fan_read_value(fan_reg[i]); ++ /* Update fan data ++ */ ++ for (i = 0; i < ARRAY_SIZE(fan_data->reg_val); i++) { ++ int status = as4610_fan_read_value(fan_reg[i]); + -+ if (status < 0) { -+ fan_data->valid = 0; -+ mutex_unlock(&fan_data->update_lock); -+ dev_dbg(fan_data->hwmon_dev, "reg %d, err %d\n", fan_reg[i], status); -+ return fan_data; -+ } -+ else { -+ fan_data->reg_val[i] = status; -+ } -+ } ++ if (status < 0) { ++ fan_data->valid = 0; ++ mutex_unlock(&fan_data->update_lock); ++ dev_dbg(fan_data->hwmon_dev, "reg %d, err %d\n", fan_reg[i], status); ++ return fan_data; ++ } ++ else { ++ fan_data->reg_val[i] = status; ++ } ++ } + -+ fan_data->last_updated = jiffies; -+ fan_data->valid = 1; -+ } ++ fan_data->last_updated = jiffies; ++ fan_data->valid = 1; ++ } + -+ mutex_unlock(&fan_data->update_lock); ++ mutex_unlock(&fan_data->update_lock); + -+ return fan_data; ++ return fan_data; +} + +static int as4610_fan_probe(struct platform_device *pdev) +{ -+ int status = -1; ++ int status = -1; + -+ /* Register sysfs hooks */ -+ status = sysfs_create_group(&pdev->dev.kobj, &as4610_fan_group); -+ if (status) { -+ goto exit; ++ /* Register sysfs hooks */ ++ status = sysfs_create_group(&pdev->dev.kobj, &as4610_fan_group); ++ if (status) { ++ goto exit; + -+ } ++ } + -+ fan_data->hwmon_dev = hwmon_device_register(&pdev->dev); -+ if (IS_ERR(fan_data->hwmon_dev)) { -+ status = PTR_ERR(fan_data->hwmon_dev); -+ goto exit_remove; -+ } ++ fan_data->hwmon_dev = hwmon_device_register(&pdev->dev); ++ if (IS_ERR(fan_data->hwmon_dev)) { ++ status = PTR_ERR(fan_data->hwmon_dev); ++ goto exit_remove; ++ } + -+ dev_info(&pdev->dev, "accton_as4610_fan\n"); ++ dev_info(&pdev->dev, "accton_as4610_fan\n"); + -+ return 0; ++ return 0; + +exit_remove: -+ sysfs_remove_group(&pdev->dev.kobj, &as4610_fan_group); ++ sysfs_remove_group(&pdev->dev.kobj, &as4610_fan_group); +exit: -+ return status; ++ return status; +} + +static int as4610_fan_remove(struct platform_device *pdev) +{ -+ hwmon_device_unregister(fan_data->hwmon_dev); -+ sysfs_remove_group(&pdev->dev.kobj, &as4610_fan_group); ++ hwmon_device_unregister(fan_data->hwmon_dev); ++ sysfs_remove_group(&pdev->dev.kobj, &as4610_fan_group); + -+ return 0; ++ return 0; +} + +static const struct i2c_device_id as4610_fan_id[] = { @@ -974,48 +526,48 @@ index 0000000..612d5df + +static int __init as4610_fan_init(void) +{ -+ int ret; ++ int ret; + -+ if (as4610_number_of_system_fan() == 0) { -+ return -ENODEV; -+ } ++ if (as4610_number_of_system_fan() == 0) { ++ return -ENODEV; ++ } + -+ ret = platform_driver_register(&as4610_fan_driver); -+ if (ret < 0) { -+ goto exit; -+ } ++ ret = platform_driver_register(&as4610_fan_driver); ++ if (ret < 0) { ++ goto exit; ++ } + -+ fan_data = kzalloc(sizeof(struct as4610_fan_data), GFP_KERNEL); -+ if (!fan_data) { -+ ret = -ENOMEM; -+ platform_driver_unregister(&as4610_fan_driver); -+ goto exit; -+ } ++ fan_data = kzalloc(sizeof(struct as4610_fan_data), GFP_KERNEL); ++ if (!fan_data) { ++ ret = -ENOMEM; ++ platform_driver_unregister(&as4610_fan_driver); ++ goto exit; ++ } + -+ mutex_init(&fan_data->update_lock); -+ fan_data->valid = 0; ++ mutex_init(&fan_data->update_lock); ++ fan_data->valid = 0; + -+ fan_data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); -+ if (IS_ERR(fan_data->pdev)) { -+ ret = PTR_ERR(fan_data->pdev); -+ platform_driver_unregister(&as4610_fan_driver); -+ kfree(fan_data); -+ goto exit; -+ } ++ fan_data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); ++ if (IS_ERR(fan_data->pdev)) { ++ ret = PTR_ERR(fan_data->pdev); ++ platform_driver_unregister(&as4610_fan_driver); ++ kfree(fan_data); ++ goto exit; ++ } + +exit: -+ return ret; ++ return ret; +} + +static void __exit as4610_fan_exit(void) +{ -+ if (!fan_data) { -+ return; -+ } ++ if (!fan_data) { ++ return; ++ } + -+ platform_device_unregister(fan_data->pdev); -+ platform_driver_unregister(&as4610_fan_driver); -+ kfree(fan_data); ++ platform_device_unregister(fan_data->pdev); ++ platform_driver_unregister(&as4610_fan_driver); ++ kfree(fan_data); +} + +late_initcall(as4610_fan_init); @@ -1027,7 +579,7 @@ index 0000000..612d5df + diff --git a/drivers/hwmon/accton_as4610_psu.c b/drivers/hwmon/accton_as4610_psu.c new file mode 100644 -index 0000000..68f0348 +index 0000000..1f0d79d --- /dev/null +++ b/drivers/hwmon/accton_as4610_psu.c @@ -0,0 +1,286 @@ @@ -1070,7 +622,7 @@ index 0000000..68f0348 +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf); +static int as4610_psu_read_data(struct i2c_client *client, u8 command, u8 *data,int data_len); -+extern int as4610_54_cpld_read(unsigned short cpld_addr, u8 reg); ++extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); + +/* Addresses scanned + */ @@ -1103,100 +655,100 @@ index 0000000..68f0348 +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); + +static struct attribute *as4610_psu_attributes[] = { -+ &sensor_dev_attr_psu_present.dev_attr.attr, -+ &sensor_dev_attr_psu_model_name.dev_attr.attr, -+ &sensor_dev_attr_psu_power_good.dev_attr.attr, -+ NULL ++ &sensor_dev_attr_psu_present.dev_attr.attr, ++ &sensor_dev_attr_psu_model_name.dev_attr.attr, ++ &sensor_dev_attr_psu_power_good.dev_attr.attr, ++ NULL +}; + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ -+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); -+ struct as4610_psu_data *data = as4610_psu_update_device(dev); -+ u8 status = 0; ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); ++ struct as4610_psu_data *data = as4610_psu_update_device(dev); ++ u8 status = 0; + -+ if (attr->index == PSU_PRESENT) { -+ status = (data->status >> (data->index*2) & 0x1); -+ } -+ else { /* PSU_POWER_GOOD */ -+ status = (data->status >> (data->index*2 + 1) & 0x1); -+ } ++ if (attr->index == PSU_PRESENT) { ++ status = (data->status >> (data->index*2) & 0x1); ++ } ++ else { /* PSU_POWER_GOOD */ ++ status = (data->status >> (data->index*2 + 1) & 0x1); ++ } + -+ return sprintf(buf, "%d\n", status); ++ return sprintf(buf, "%d\n", status); +} + +static ssize_t show_model_name(struct device *dev, struct device_attribute *da, -+ char *buf) ++ char *buf) +{ -+ struct as4610_psu_data *data = as4610_psu_update_device(dev); ++ struct as4610_psu_data *data = as4610_psu_update_device(dev); + -+ return sprintf(buf, "%s\n", data->model_name); ++ return sprintf(buf, "%s\n", data->model_name); +} + +static const struct attribute_group as4610_psu_group = { -+ .attrs = as4610_psu_attributes, ++ .attrs = as4610_psu_attributes, +}; + +static int as4610_psu_probe(struct i2c_client *client, -+ const struct i2c_device_id *dev_id) ++ const struct i2c_device_id *dev_id) +{ -+ struct as4610_psu_data *data; -+ int status; ++ struct as4610_psu_data *data; ++ int status; + -+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { -+ status = -EIO; -+ goto exit; -+ } ++ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { ++ status = -EIO; ++ goto exit; ++ } + -+ data = kzalloc(sizeof(struct as4610_psu_data), GFP_KERNEL); -+ if (!data) { -+ status = -ENOMEM; -+ goto exit; -+ } ++ data = kzalloc(sizeof(struct as4610_psu_data), GFP_KERNEL); ++ if (!data) { ++ status = -ENOMEM; ++ goto exit; ++ } + -+ i2c_set_clientdata(client, data); -+ data->valid = 0; -+ data->index = dev_id->driver_data; -+ mutex_init(&data->update_lock); ++ i2c_set_clientdata(client, data); ++ data->valid = 0; ++ data->index = dev_id->driver_data; ++ mutex_init(&data->update_lock); + -+ dev_info(&client->dev, "chip found\n"); ++ dev_info(&client->dev, "chip found\n"); + -+ /* Register sysfs hooks */ -+ status = sysfs_create_group(&client->dev.kobj, &as4610_psu_group); -+ if (status) { -+ goto exit_free; -+ } ++ /* Register sysfs hooks */ ++ status = sysfs_create_group(&client->dev.kobj, &as4610_psu_group); ++ if (status) { ++ goto exit_free; ++ } + -+ data->hwmon_dev = hwmon_device_register(&client->dev); -+ if (IS_ERR(data->hwmon_dev)) { -+ status = PTR_ERR(data->hwmon_dev); -+ goto exit_remove; -+ } ++ data->hwmon_dev = hwmon_device_register(&client->dev); ++ if (IS_ERR(data->hwmon_dev)) { ++ status = PTR_ERR(data->hwmon_dev); ++ goto exit_remove; ++ } + -+ dev_info(&client->dev, "%s: psu '%s'\n", -+ dev_name(data->hwmon_dev), client->name); ++ dev_info(&client->dev, "%s: psu '%s'\n", ++ dev_name(data->hwmon_dev), client->name); + -+ return 0; ++ return 0; + +exit_remove: -+ sysfs_remove_group(&client->dev.kobj, &as4610_psu_group); ++ sysfs_remove_group(&client->dev.kobj, &as4610_psu_group); +exit_free: -+ kfree(data); ++ kfree(data); +exit: + -+ return status; ++ return status; +} + +static int as4610_psu_remove(struct i2c_client *client) +{ -+ struct as4610_psu_data *data = i2c_get_clientdata(client); ++ struct as4610_psu_data *data = i2c_get_clientdata(client); + -+ hwmon_device_unregister(data->hwmon_dev); -+ sysfs_remove_group(&client->dev.kobj, &as4610_psu_group); -+ kfree(data); ++ hwmon_device_unregister(data->hwmon_dev); ++ sysfs_remove_group(&client->dev.kobj, &as4610_psu_group); ++ kfree(data); + -+ return 0; ++ return 0; +} + +enum psu_index @@ -1226,88 +778,88 @@ index 0000000..68f0348 +static int as4610_psu_read_data(struct i2c_client *client, u8 command, u8 *data, + int count) +{ -+ int status = 0; ++ int status = 0; + -+ while (count) { -+ status = i2c_smbus_read_byte_data(client, command); -+ if (unlikely(status < 0)) { -+ break; -+ } ++ while (count) { ++ status = i2c_smbus_read_byte_data(client, command); ++ if (unlikely(status < 0)) { ++ break; ++ } + -+ *data = (u8)status; -+ data += 1; -+ command += 1; -+ count -= 1; -+ } ++ *data = (u8)status; ++ data += 1; ++ command += 1; ++ count -= 1; ++ } + -+ return status; ++ return status; +} + +static struct as4610_psu_data *as4610_psu_update_device(struct device *dev) +{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct as4610_psu_data *data = i2c_get_clientdata(client); ++ struct i2c_client *client = to_i2c_client(dev); ++ struct as4610_psu_data *data = i2c_get_clientdata(client); + -+ mutex_lock(&data->update_lock); ++ mutex_lock(&data->update_lock); + -+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2) -+ || !data->valid) { -+ int status; -+ int present = 0; ++ if (time_after(jiffies, data->last_updated + HZ + HZ / 2) ++ || !data->valid) { ++ int status; ++ int present = 0; + -+ data->valid = 0; -+ data->status = 0; -+ dev_dbg(&client->dev, "Starting as4610 update\n"); ++ data->valid = 0; ++ data->status = 0; ++ dev_dbg(&client->dev, "Starting as4610 update\n"); + -+ /* Read psu status */ -+ status = as4610_54_cpld_read(0x30, 0x11); ++ /* Read psu status */ ++ status = accton_i2c_cpld_read(0x30, 0x11); + -+ if (status < 0) { -+ dev_dbg(&client->dev, "cpld reg 0x30 err %d\n", status); -+ goto exit; -+ } -+ else { -+ data->status = status; -+ } ++ if (status < 0) { ++ dev_dbg(&client->dev, "cpld reg 0x30 err %d\n", status); ++ goto exit; ++ } ++ else { ++ data->status = status; ++ } + -+ /* Read model name */ -+ memset(data->model_name, 0, sizeof(data->model_name)); -+ present = (data->status >> (data->index*2) & 0x1); ++ /* Read model name */ ++ memset(data->model_name, 0, sizeof(data->model_name)); ++ present = (data->status >> (data->index*2) & 0x1); + -+ if (present) { -+ int len = ARRAY_SIZE(data->model_name)-1; ++ if (present) { ++ int len = ARRAY_SIZE(data->model_name)-1; + -+ status = as4610_psu_read_data(client, 0x20, data->model_name, -+ ARRAY_SIZE(data->model_name)-1); ++ status = as4610_psu_read_data(client, 0x20, data->model_name, ++ ARRAY_SIZE(data->model_name)-1); + -+ if (status < 0) { -+ data->model_name[0] = '\0'; -+ dev_dbg(&client->dev, "unable to read model name from (0x%x)\n", client->addr); -+ goto exit; -+ } -+ else { -+ data->model_name[ARRAY_SIZE(data->model_name)-1] = '\0'; -+ } -+ } ++ if (status < 0) { ++ data->model_name[0] = '\0'; ++ dev_dbg(&client->dev, "unable to read model name from (0x%x)\n", client->addr); ++ goto exit; ++ } ++ else { ++ data->model_name[ARRAY_SIZE(data->model_name)-1] = '\0'; ++ } ++ } + -+ data->last_updated = jiffies; -+ data->valid = 1; -+ } ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } + +exit: -+ mutex_unlock(&data->update_lock); ++ mutex_unlock(&data->update_lock); + -+ return data; ++ return data; +} + +static int __init as4610_psu_init(void) +{ -+ return i2c_add_driver(&as4610_psu_driver); ++ return i2c_add_driver(&as4610_psu_driver); +} + +static void __exit as4610_psu_exit(void) +{ -+ i2c_del_driver(&as4610_psu_driver); ++ i2c_del_driver(&as4610_psu_driver); +} + +module_init(as4610_psu_init); @@ -1317,6 +869,297 @@ index 0000000..68f0348 +MODULE_DESCRIPTION("as4610_psu driver"); +MODULE_LICENSE("GPL"); + +diff --git a/drivers/hwmon/accton_i2c_cpld.c b/drivers/hwmon/accton_i2c_cpld.c +new file mode 100644 +index 0000000..0b9762e +--- /dev/null ++++ b/drivers/hwmon/accton_i2c_cpld.c +@@ -0,0 +1,285 @@ ++/* ++ * A hwmon driver for the accton_i2c_cpld ++ * ++ * Copyright (C) 2013 Accton Technology Corporation. ++ * Brandon Chuang ++ * ++ * Based on ad7414.c ++ * Copyright 2006 Stefan Roese , DENX Software Engineering ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static LIST_HEAD(cpld_client_list); ++static struct mutex list_lock; ++ ++enum cpld_device_id { ++ as4610_30_cpld, ++ as4610_54_cpld ++}; ++ ++struct cpld_data { ++ enum cpld_device_id id; ++}; ++ ++struct cpld_client_node { ++ struct i2c_client *client; ++ struct list_head list; ++}; ++ ++/* Addresses scanned for accton_i2c_cpld ++ */ ++static const unsigned short normal_i2c[] = { 0x31, 0x35, 0x60, 0x61, 0x62, I2C_CLIENT_END }; ++ ++static u8 cpld_product_id_offset(enum cpld_device_id id) ++{ ++ switch (id) { ++ case as4610_30_cpld: ++ case as4610_54_cpld: ++ return 0x1; ++ } ++ ++ return 0; ++} ++ ++static int cpld_has_product_id(const struct i2c_device_id *dev_id) ++{ ++ return (dev_id->driver_data == as4610_30_cpld) || ++ (dev_id->driver_data == as4610_54_cpld); ++} ++ ++static ssize_t show_cpld_product_id(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ int val = 0; ++ struct i2c_client *client = to_i2c_client(dev); ++ struct cpld_data *data = i2c_get_clientdata(client); ++ ++ val = i2c_smbus_read_byte_data(client, cpld_product_id_offset(data->id)); ++ if (val < 0) { ++ dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", client->addr, cpld_product_id_offset(data->id), val); ++ } ++ ++ return sprintf(buf, "%d\n", (val & 0xF)); ++} ++ ++static u8 cpld_version_offset(enum cpld_device_id id) ++{ ++ switch (id) { ++ case as4610_30_cpld: ++ case as4610_54_cpld: ++ return 0xB; ++ } ++ ++ return 0; ++} ++ ++static ssize_t show_cpld_version(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ int val = 0; ++ struct i2c_client *client = to_i2c_client(dev); ++ struct cpld_data *data = i2c_get_clientdata(client); ++ ++ val = i2c_smbus_read_byte_data(client, cpld_version_offset(data->id)); ++ if (val < 0) { ++ dev_dbg(&client->dev, "cpld(0x%x) reg(0xB) err %d\n", client->addr, val); ++ } ++ ++ return sprintf(buf, "%d\n", val); ++} ++ ++static void accton_i2c_cpld_add_client(struct i2c_client *client, enum cpld_device_id id) ++{ ++ struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); ++ struct cpld_data *data = kzalloc(sizeof(struct cpld_data), GFP_KERNEL); ++ ++ if (!node) { ++ dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); ++ return; ++ } ++ ++ if (!data) { ++ dev_dbg(&client->dev, "Can't allocate cpld_client_data (0x%x)\n", client->addr); ++ return; ++ } ++ ++ data->id = id; ++ i2c_set_clientdata(client, data); ++ node->client = client; ++ ++ mutex_lock(&list_lock); ++ list_add(&node->list, &cpld_client_list); ++ mutex_unlock(&list_lock); ++} ++ ++static void accton_i2c_cpld_remove_client(struct i2c_client *client) ++{ ++ struct list_head *list_node = NULL; ++ struct cpld_client_node *cpld_node = NULL; ++ int found = 0; ++ ++ mutex_lock(&list_lock); ++ ++ list_for_each(list_node, &cpld_client_list) ++ { ++ cpld_node = list_entry(list_node, struct cpld_client_node, list); ++ ++ if (cpld_node->client == client) { ++ found = 1; ++ break; ++ } ++ } ++ ++ if (found) { ++ list_del(list_node); ++ kfree(cpld_node); ++ } ++ ++ mutex_unlock(&list_lock); ++} ++ ++static struct device_attribute ver = __ATTR(version, 0600, show_cpld_version, NULL); ++static struct device_attribute pid = __ATTR(product_id, 0600, show_cpld_product_id, NULL); ++ ++static int accton_i2c_cpld_probe(struct i2c_client *client, ++ const struct i2c_device_id *dev_id) ++{ ++ int status; ++ ++ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { ++ dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); ++ status = -EIO; ++ goto exit; ++ } ++ ++ status = sysfs_create_file(&client->dev.kobj, &ver.attr); ++ if (status) { ++ goto exit; ++ } ++ ++ if (cpld_has_product_id(dev_id)) { ++ status = sysfs_create_file(&client->dev.kobj, &pid.attr); ++ if (status) { ++ goto exit; ++ } ++ } ++ ++ dev_info(&client->dev, "chip found\n"); ++ accton_i2c_cpld_add_client(client, (enum cpld_device_id)dev_id->driver_data); ++ ++ return 0; ++ ++exit: ++ return status; ++} ++ ++static int accton_i2c_cpld_remove(struct i2c_client *client) ++{ ++ sysfs_remove_file(&client->dev.kobj, &ver.attr); ++ accton_i2c_cpld_remove_client(client); ++ ++ return 0; ++} ++ ++static const struct i2c_device_id accton_i2c_cpld_id[] = { ++ { "as4610_30_cpld", as4610_30_cpld }, ++ { "as4610_54_cpld", as4610_54_cpld }, ++ { /* LIST END */} ++}; ++MODULE_DEVICE_TABLE(i2c, accton_i2c_cpld_id); ++ ++static struct i2c_driver accton_i2c_cpld_driver = { ++ .class = I2C_CLASS_HWMON, ++ .driver = { ++ .name = "accton_i2c_cpld", ++ }, ++ .probe = accton_i2c_cpld_probe, ++ .remove = accton_i2c_cpld_remove, ++ .id_table = accton_i2c_cpld_id, ++ .address_list = normal_i2c, ++}; ++ ++int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg) ++{ ++ struct list_head *list_node = NULL; ++ struct cpld_client_node *cpld_node = NULL; ++ int ret = -EPERM; ++ ++ mutex_lock(&list_lock); ++ ++ list_for_each(list_node, &cpld_client_list) ++ { ++ cpld_node = list_entry(list_node, struct cpld_client_node, list); ++ ++ if (cpld_node->client->addr == cpld_addr) { ++ ret = i2c_smbus_read_byte_data(cpld_node->client, reg); ++ break; ++ } ++ } ++ ++ mutex_unlock(&list_lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL(accton_i2c_cpld_read); ++ ++int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) ++{ ++ struct list_head *list_node = NULL; ++ struct cpld_client_node *cpld_node = NULL; ++ int ret = -EIO; ++ ++ mutex_lock(&list_lock); ++ ++ list_for_each(list_node, &cpld_client_list) ++ { ++ cpld_node = list_entry(list_node, struct cpld_client_node, list); ++ ++ if (cpld_node->client->addr == cpld_addr) { ++ ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); ++ break; ++ } ++ } ++ ++ mutex_unlock(&list_lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL(accton_i2c_cpld_write); ++ ++static int __init accton_i2c_cpld_init(void) ++{ ++ mutex_init(&list_lock); ++ return i2c_add_driver(&accton_i2c_cpld_driver); ++} ++ ++static void __exit accton_i2c_cpld_exit(void) ++{ ++ i2c_del_driver(&accton_i2c_cpld_driver); ++} ++ ++MODULE_AUTHOR("Brandon Chuang "); ++MODULE_DESCRIPTION("accton_i2c_cpld driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(accton_i2c_cpld_init); ++module_exit(accton_i2c_cpld_exit); ++ diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index 8dfc678..b9eafcf 100644 --- a/drivers/hwmon/lm77.c @@ -1997,7 +1840,7 @@ index ff203a4..97d4d54 100644 +config LEDS_ACCTON_AS4610 + tristate "LED support for the Accton as4610" -+ depends on LEDS_CLASS && SENSORS_ACCTON_AS4610_CPLD ++ depends on LEDS_CLASS && SENSORS_ACCTON_I2C_CPLD + help + This option enables support for the LEDs on the Accton as4610. + Say Y to enable LEDs on the Accton as4610. @@ -2019,7 +1862,7 @@ index e4f6bf5..db2dab8 100644 obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o diff --git a/drivers/leds/leds-accton_as4610.c b/drivers/leds/leds-accton_as4610.c new file mode 100644 -index 0000000..7a8bf34 +index 0000000..0c4b535 --- /dev/null +++ b/drivers/leds/leds-accton_as4610.c @@ -0,0 +1,678 @@ @@ -2056,8 +1899,8 @@ index 0000000..7a8bf34 +#include +#include + -+extern int as4610_54_cpld_read (unsigned short cpld_addr, u8 reg); -+extern int as4610_54_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); ++extern int accton_i2c_cpld_read (unsigned short cpld_addr, u8 reg); ++extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); @@ -2173,12 +2016,12 @@ index 0000000..7a8bf34 + +static int as4610_led_read_value(u8 reg) +{ -+ return as4610_54_cpld_read(0x30, reg); ++ return accton_i2c_cpld_read(0x30, reg); +} + +static int as4610_led_write_value(u8 reg, u8 value) +{ -+ return as4610_54_cpld_write(0x30, reg, value); ++ return accton_i2c_cpld_write(0x30, reg, value); +} + +static void as4610_led_update(void) @@ -2710,14 +2553,14 @@ index 7c7b208..1c62b33 100644 This driver can also be built as a module. If so, the module will be called sff_8436. + -+config EEPROM_OPTOE -+ tristate "Optoe driver" -+ depends on I2C ++config EEPROM_ACCTON_AS4610_SFP ++ tristate "Accton as4610 sfp" ++ depends on I2C && SENSORS_ACCTON_I2C_CPLD + help -+ If you say yes here you get support for Optoe. ++ If you say yes here you get support for Accton as4610 sfp. + + This driver can also be built as a module. If so, the module will -+ be called optoe. ++ be called accton_as4610_sfp. endmenu diff --git a/drivers/misc/eeprom/Makefile b/drivers/misc/eeprom/Makefile @@ -2728,1167 +2571,1290 @@ index 9edd559..12f7cae 100644 obj-$(CONFIG_EEPROM_93XX46) += eeprom_93xx46.o obj-$(CONFIG_EEPROM_DIGSY_MTC_CFG) += digsy_mtc_eeprom.o obj-$(CONFIG_EEPROM_SFF_8436) += sff_8436_eeprom.o -+obj-$(CONFIG_EEPROM_OPTOE) += optoe.o -diff --git a/drivers/misc/eeprom/optoe.c b/drivers/misc/eeprom/optoe.c ++obj-$(CONFIG_EEPROM_ACCTON_AS4610_SFP) += accton_as4610_sfp.o +diff --git a/drivers/misc/eeprom/accton_as4610_sfp.c b/drivers/misc/eeprom/accton_as4610_sfp.c new file mode 100644 -index 0000000..b3064f0 +index 0000000..39c17ec --- /dev/null -+++ b/drivers/misc/eeprom/optoe.c -@@ -0,0 +1,1146 @@ ++++ b/drivers/misc/eeprom/accton_as4610_sfp.c +@@ -0,0 +1,1269 @@ +/* -+ * optoe.c - A driver to read and write the EEPROM on optical transceivers -+ * (SFP, QSFP and similar I2C based devices) ++ * SFP driver for accton as4610 sfp + * -+ * Copyright (C) 2014 Cumulus networks Inc. -+ * Copyright (C) 2017 Finisar Corp. ++ * Copyright (C) Brandon Chuang ++ * ++ * Based on ad7414.c ++ * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by -+ * the Freeoftware Foundation; either version 2 of the License, or ++ * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + -+/* -+ * Description: -+ * a) Optical transceiver EEPROM read/write transactions are just like -+ * the at24 eeproms managed by the at24.c i2c driver -+ * b) The register/memory layout is up to 256 128 byte pages defined by -+ * a "pages valid" register and switched via a "page select" -+ * register as explained in below diagram. -+ * c) 256 bytes are mapped at a time. 'Lower page 00h' is the first 128 -+ * bytes of address space, and always references the same -+ * location, independent of the page select register. -+ * All mapped pages are mapped into the upper 128 bytes -+ * (offset 128-255) of the i2c address. -+ * d) Devices with one I2C address (eg QSFP) use I2C address 0x50 -+ * (A0h in the spec), and map all pages in the upper 128 bytes -+ * of that address. -+ * e) Devices with two I2C addresses (eg SFP) have 256 bytes of data -+ * at I2C address 0x50, and 256 bytes of data at I2C address -+ * 0x51 (A2h in the spec). Page selection and paged access -+ * only apply to this second I2C address (0x51). -+ * e) The address space is presented, by the driver, as a linear -+ * address space. For devices with one I2C client at address -+ * 0x50 (eg QSFP), offset 0-127 are in the lower -+ * half of address 50/A0h/client[0]. Offset 128-255 are in -+ * page 0, 256-383 are page 1, etc. More generally, offset -+ * 'n' resides in page (n/128)-1. ('page -1' is the lower -+ * half, offset 0-127). -+ * f) For devices with two I2C clients at address 0x50 and 0x51 (eg SFP), -+ * the address space places offset 0-127 in the lower -+ * half of 50/A0/client[0], offset 128-255 in the upper -+ * half. Offset 256-383 is in the lower half of 51/A2/client[1]. -+ * Offset 384-511 is in page 0, in the upper half of 51/A2/... -+ * Offset 512-639 is in page 1, in the upper half of 51/A2/... -+ * Offset 'n' is in page (n/128)-3 (for n > 383) -+ * -+ * One I2c addressed (eg QSFP) Memory Map -+ * -+ * 2-Wire Serial Address: 1010000x -+ * -+ * Lower Page 00h (128 bytes) -+ * ===================== -+ * | | -+ * | | -+ * | | -+ * | | -+ * | | -+ * | | -+ * | | -+ * | | -+ * | | -+ * | | -+ * |Page Select Byte(127)| -+ * ===================== -+ * | -+ * | -+ * | -+ * | -+ * V -+ * ------------------------------------------------------------ -+ * | | | | -+ * | | | | -+ * | | | | -+ * | | | | -+ * | | | | -+ * | | | | -+ * | | | | -+ * | | | | -+ * | | | | -+ * V V V V -+ * ------------ -------------- --------------- -------------- -+ * | | | | | | | | -+ * | Upper | | Upper | | Upper | | Upper | -+ * | Page 00h | | Page 01h | | Page 02h | | Page 03h | -+ * | | | (Optional) | | (Optional) | | (Optional | -+ * | | | | | | | for Cable | -+ * | | | | | | | Assemblies) | -+ * | ID | | AST | | User | | | -+ * | Fields | | Table | | EEPROM Data | | | -+ * | | | | | | | | -+ * | | | | | | | | -+ * | | | | | | | | -+ * ------------ -------------- --------------- -------------- -+ * -+ * The SFF 8436 (QSFP) spec only defines the 4 pages described above. -+ * In anticipation of future applications and devices, this driver -+ * supports access to the full architected range, 256 pages. -+ * -+ **/ -+ -+/* #define DEBUG 1 */ -+ -+#undef EEPROM_CLASS -+#ifdef CONFIG_EEPROM_CLASS -+#define EEPROM_CLASS -+#endif -+#ifdef CONFIG_EEPROM_CLASS_MODULE -+#define EEPROM_CLASS -+#endif -+ -+#include -+#include +#include -+#include -+#include -+#include -+#include +#include +#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+#ifdef EEPROM_CLASS -+#include ++#define DRIVER_NAME "as4610_sfp" /* Platform dependent */ ++ ++#define DEBUG_MODE 0 ++ ++#if (DEBUG_MODE == 1) ++ #define DEBUG_PRINT(fmt, args...) \ ++ printk (KERN_INFO "%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args) ++#else ++ #define DEBUG_PRINT(fmt, args...) +#endif + -+#include ++#define NUM_OF_SFP_PORT 32 ++#define EEPROM_NAME "sfp_eeprom" ++#define EEPROM_SIZE 256 /* 256 byte eeprom */ ++#define BIT_INDEX(i) (1ULL << (i)) ++#define USE_I2C_BLOCK_READ 0 /* Platform dependent */ ++#define I2C_RW_RETRY_COUNT 3 ++#define I2C_RW_RETRY_INTERVAL 100 /* ms */ + -+/* The maximum length of a port name */ -+#define MAX_PORT_NAME_LEN 20 ++#define SFP_EEPROM_A0_I2C_ADDR (0xA0 >> 1) ++#define SFP_EEPROM_A2_I2C_ADDR (0xA2 >> 1) + -+struct optoe_platform_data { -+ u32 byte_len; /* size (sum of all addr) */ -+ u16 page_size; /* for writes */ -+ u8 flags; -+ void *dummy1; /* backward compatibility */ -+ void *dummy2; /* backward compatibility */ ++#define SFF8024_PHYSICAL_DEVICE_ID_ADDR 0x0 ++#define SFF8024_DEVICE_ID_SFP 0x3 ++#define SFF8024_DEVICE_ID_QSFP 0xC ++#define SFF8024_DEVICE_ID_QSFP_PLUS 0xD ++#define SFF8024_DEVICE_ID_QSFP28 0x11 + -+#ifdef EEPROM_CLASS -+ struct eeprom_platform_data *eeprom_data; -+#endif -+ char port_name[MAX_PORT_NAME_LEN]; ++#define SFF8472_DIAG_MON_TYPE_ADDR 92 ++#define SFF8472_DIAG_MON_TYPE_DDM_MASK 0x40 ++#define SFF8472_10G_ETH_COMPLIANCE_ADDR 0x3 ++#define SFF8472_10G_BASE_MASK 0xF0 ++ ++#define SFF8436_RX_LOS_ADDR 3 ++#define SFF8436_TX_FAULT_ADDR 4 ++#define SFF8436_TX_DISABLE_ADDR 86 ++ ++static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); ++static ssize_t show_port_type(struct device *dev, struct device_attribute *da, char *buf); ++static ssize_t show_present(struct device *dev, struct device_attribute *da, char *buf); ++static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); ++static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); ++static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count); ++static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count);; ++static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, char *buf); ++static ssize_t sfp_eeprom_read(struct i2c_client *, u8, u8 *,int); ++static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); ++extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); ++extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); ++ ++enum sfp_sysfs_attributes { ++ PRESENT, ++ PRESENT_ALL, ++ PORT_NUMBER, ++ PORT_TYPE, ++ DDM_IMPLEMENTED, ++ TX_FAULT, ++ TX_FAULT1, ++ TX_FAULT2, ++ TX_FAULT3, ++ TX_FAULT4, ++ TX_DISABLE, ++ TX_DISABLE1, ++ TX_DISABLE2, ++ TX_DISABLE3, ++ TX_DISABLE4, ++ RX_LOS, ++ RX_LOS1, ++ RX_LOS2, ++ RX_LOS3, ++ RX_LOS4, ++ RX_LOS_ALL +}; + -+/* fundamental unit of addressing for EEPROM */ -+#define OPTOE_PAGE_SIZE 128 -+/* -+ * Single address devices (eg QSFP) have 256 pages, plus the unpaged -+ * low 128 bytes. If the device does not support paging, it is -+ * only 2 'pages' long. -+ */ -+#define OPTOE_ARCH_PAGES 256 -+#define ONE_ADDR_EEPROM_SIZE ((1 + OPTOE_ARCH_PAGES) * OPTOE_PAGE_SIZE) -+#define ONE_ADDR_EEPROM_UNPAGED_SIZE (2 * OPTOE_PAGE_SIZE) -+/* -+ * Dual address devices (eg SFP) have 256 pages, plus the unpaged -+ * low 128 bytes, plus 256 bytes at 0x50. If the device does not -+ * support paging, it is 4 'pages' long. -+ */ -+#define TWO_ADDR_EEPROM_SIZE ((3 + OPTOE_ARCH_PAGES) * OPTOE_PAGE_SIZE) -+#define TWO_ADDR_EEPROM_UNPAGED_SIZE (4 * OPTOE_PAGE_SIZE) -+#define TWO_ADDR_NO_0X51_SIZE (2 * OPTOE_PAGE_SIZE) ++/* SFP/QSFP common attributes for sysfs */ ++static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, PORT_NUMBER); ++static SENSOR_DEVICE_ATTR(sfp_port_type, S_IRUGO, show_port_type, NULL, PORT_TYPE); ++static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_present, NULL, PRESENT); ++static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_present, NULL, PRESENT_ALL); ++static SENSOR_DEVICE_ATTR(sfp_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS); ++static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, TX_DISABLE); ++static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, TX_FAULT); + -+/* a few constants to find our way around the EEPROM */ -+#define OPTOE_PAGE_SELECT_REG 0x7F -+#define ONE_ADDR_PAGEABLE_REG 0x02 -+#define ONE_ADDR_NOT_PAGEABLE (1<<2) -+#define TWO_ADDR_PAGEABLE_REG 0x40 -+#define TWO_ADDR_PAGEABLE (1<<4) -+#define TWO_ADDR_0X51_REG 92 -+#define TWO_ADDR_0X51_SUPP (1<<6) -+#define OPTOE_ID_REG 0 -+#define OPTOE_READ_OP 0 -+#define OPTOE_WRITE_OP 1 -+#define OPTOE_EOF 0 /* used for access beyond end of device */ -+ -+struct optoe_data { -+ struct optoe_platform_data chip; -+ int use_smbus; -+ char port_name[MAX_PORT_NAME_LEN]; -+ -+ /* -+ * Lock protects against activities from other Linux tasks, -+ * but not from changes by other I2C masters. -+ */ -+ struct mutex lock; -+ struct bin_attribute bin; -+ struct attribute_group attr_group; -+ -+ u8 *writebuf; -+ unsigned int write_max; -+ -+ unsigned int num_addresses; -+ -+#ifdef EEPROM_CLASS -+ struct eeprom_device *eeprom_dev; -+#endif -+ -+ /* dev_class: ONE_ADDR (QSFP) or TWO_ADDR (SFP) */ -+ int dev_class; -+ -+ struct i2c_client *client[]; ++/* QSFP attributes for sysfs */ ++static SENSOR_DEVICE_ATTR(sfp_rx_los1, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS1); ++static SENSOR_DEVICE_ATTR(sfp_rx_los2, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS2); ++static SENSOR_DEVICE_ATTR(sfp_rx_los3, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS3); ++static SENSOR_DEVICE_ATTR(sfp_rx_los4, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS4); ++static SENSOR_DEVICE_ATTR(sfp_tx_disable1, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE1); ++static SENSOR_DEVICE_ATTR(sfp_tx_disable2, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE2); ++static SENSOR_DEVICE_ATTR(sfp_tx_disable3, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE3); ++static SENSOR_DEVICE_ATTR(sfp_tx_disable4, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE4); ++static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT1); ++static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2); ++static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3); ++static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4); ++static struct attribute *qsfp_attributes[] = { ++ &sensor_dev_attr_sfp_port_number.dev_attr.attr, ++ &sensor_dev_attr_sfp_port_type.dev_attr.attr, ++ &sensor_dev_attr_sfp_is_present.dev_attr.attr, ++ &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, ++ &sensor_dev_attr_sfp_rx_los.dev_attr.attr, ++ &sensor_dev_attr_sfp_rx_los1.dev_attr.attr, ++ &sensor_dev_attr_sfp_rx_los2.dev_attr.attr, ++ &sensor_dev_attr_sfp_rx_los3.dev_attr.attr, ++ &sensor_dev_attr_sfp_rx_los4.dev_attr.attr, ++ &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, ++ &sensor_dev_attr_sfp_tx_disable1.dev_attr.attr, ++ &sensor_dev_attr_sfp_tx_disable2.dev_attr.attr, ++ &sensor_dev_attr_sfp_tx_disable3.dev_attr.attr, ++ &sensor_dev_attr_sfp_tx_disable4.dev_attr.attr, ++ &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, ++ &sensor_dev_attr_sfp_tx_fault1.dev_attr.attr, ++ &sensor_dev_attr_sfp_tx_fault2.dev_attr.attr, ++ &sensor_dev_attr_sfp_tx_fault3.dev_attr.attr, ++ &sensor_dev_attr_sfp_tx_fault4.dev_attr.attr, ++ NULL +}; + -+ -+/* -+ * This parameter is to help this driver avoid blocking other drivers out -+ * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C -+ * clock, one 256 byte read takes about 1/43 second which is excessive; -+ * but the 1/170 second it takes at 400 kHz may be quite reasonable; and -+ * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible. -+ * -+ * This value is forced to be a power of two so that writes align on pages. -+ */ -+static unsigned int io_limit = OPTOE_PAGE_SIZE; -+ -+/* -+ * specs often allow 5 msec for a page write, sometimes 20 msec; -+ * it's important to recover from write timeouts. -+ */ -+static unsigned int write_timeout = 25; -+ -+/* -+ * flags to distinguish one-address (QSFP family) from two-address (SFP family) -+ * If the family is not known, figure it out when the device is accessed -+ */ -+#define ONE_ADDR 1 -+#define TWO_ADDR 2 -+ -+static const struct i2c_device_id optoe_ids[] = { -+ { "optoe1", ONE_ADDR }, -+ { "optoe2", TWO_ADDR }, -+ { "sff8436", ONE_ADDR }, -+ { "24c04", TWO_ADDR }, -+ { /* END OF LIST */ } ++/* SFP msa attributes for sysfs */ ++static SENSOR_DEVICE_ATTR(sfp_ddm_implemented, S_IRUGO, sfp_show_ddm_implemented, NULL, DDM_IMPLEMENTED); ++static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS_ALL); ++static struct attribute *sfp_msa_attributes[] = { ++ &sensor_dev_attr_sfp_port_number.dev_attr.attr, ++ &sensor_dev_attr_sfp_port_type.dev_attr.attr, ++ &sensor_dev_attr_sfp_is_present.dev_attr.attr, ++ &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, ++ &sensor_dev_attr_sfp_ddm_implemented.dev_attr.attr, ++ &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, ++ &sensor_dev_attr_sfp_rx_los.dev_attr.attr, ++ &sensor_dev_attr_sfp_rx_los_all.dev_attr.attr, ++ &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, ++ NULL +}; -+MODULE_DEVICE_TABLE(i2c, optoe_ids); + -+/*-------------------------------------------------------------------------*/ ++/* SFP ddm attributes for sysfs */ ++static struct attribute *sfp_ddm_attributes[] = { ++ NULL ++}; ++ ++/* Platform dependent +++ */ ++enum port_numbers { ++as4610_sfp1, /* Port 25 for as4610_30, Port 49 for as4610_54 */ ++as4610_sfp2, /* Port 26 for as4610_30, Port 50 for as4610_54 */ ++as4610_sfp3, /* Port 27 for as4610_30, Port 51 for as4610_54 */ ++as4610_sfp4, /* Port 28 for as4610_30, Port 52 for as4610_54 */ ++as4610_sfp5, /* Port 29 for as4610_30, Port 53 for as4610_54 */ ++as4610_sfp6, /* Port 30 for as4610_30, Port 54 for as4610_54 */ ++}; ++ ++static const struct i2c_device_id sfp_device_id[] = { ++{"as4610_sfp1", as4610_sfp1}, ++{"as4610_sfp2", as4610_sfp2}, ++{"as4610_sfp3", as4610_sfp3}, ++{"as4610_sfp4", as4610_sfp4}, ++{"as4610_sfp5", as4610_sfp5}, ++{"as4610_sfp6", as4610_sfp6}, ++{ /* LIST END */ } ++}; ++MODULE_DEVICE_TABLE(i2c, sfp_device_id); ++/* Platform dependent --- */ ++ +/* -+ * This routine computes the addressing information to be used for -+ * a given r/w request. -+ * -+ * Task is to calculate the client (0 = i2c addr 50, 1 = i2c addr 51), -+ * the page, and the offset. -+ * -+ * Handles both single address (eg QSFP) and two address (eg SFP). -+ * For SFP, offset 0-255 are on client[0], >255 is on client[1] -+ * Offset 256-383 are on the lower half of client[1] -+ * Pages are accessible on the upper half of client[1]. -+ * Offset >383 are in 128 byte pages mapped into the upper half -+ * -+ * For QSFP, all offsets are on client[0] -+ * offset 0-127 are on the lower half of client[0] (no paging) -+ * Pages are accessible on the upper half of client[1]. -+ * Offset >127 are in 128 byte pages mapped into the upper half -+ * -+ * Callers must not read/write beyond the end of a client or a page -+ * without recomputing the client/page. Hence offset (within page) -+ * plus length must be less than or equal to 128. (Note that this -+ * routine does not have access to the length of the call, hence -+ * cannot do the validity check.) -+ * -+ * Offset within Lower Page 00h and Upper Page 00h are not recomputed ++ * list of valid port types ++ * note OOM_PORT_TYPE_NOT_PRESENT to indicate no ++ * module is present in this port + */ ++typedef enum oom_driver_port_type_e { ++ OOM_DRIVER_PORT_TYPE_INVALID, ++ OOM_DRIVER_PORT_TYPE_NOT_PRESENT, ++ OOM_DRIVER_PORT_TYPE_SFP, ++ OOM_DRIVER_PORT_TYPE_SFP_PLUS, ++ OOM_DRIVER_PORT_TYPE_QSFP, ++ OOM_DRIVER_PORT_TYPE_QSFP_PLUS, ++ OOM_DRIVER_PORT_TYPE_QSFP28 ++} oom_driver_port_type_t; + -+static uint8_t optoe_translate_offset(struct optoe_data *optoe, -+ loff_t *offset, struct i2c_client **client) ++enum driver_type_e { ++ DRIVER_TYPE_SFP_MSA, ++ DRIVER_TYPE_SFP_DDM, ++ DRIVER_TYPE_QSFP ++}; ++ ++/* Each client has this additional data ++ */ ++struct eeprom_data { ++ char valid; /* !=0 if registers are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ struct bin_attribute bin; /* eeprom data */ ++}; ++ ++struct sfp_msa_data { ++ char valid; /* !=0 if registers are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ u64 status[6]; /* bit0:port0, bit1:port1 and so on */ ++ /* index 0 => tx_fail ++ 1 => tx_disable ++ 2 => rx_loss ++ 3 => device id ++ 4 => 10G Ethernet Compliance Codes ++ to distinguish SFP or SFP+ ++ 5 => DIAGNOSTIC MONITORING TYPE */ ++ struct eeprom_data eeprom; ++}; ++ ++struct sfp_ddm_data { ++ struct eeprom_data eeprom; ++}; ++ ++struct qsfp_data { ++ char valid; /* !=0 if registers are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ u8 status[3]; /* bit0:port0, bit1:port1 and so on */ ++ /* index 0 => tx_fail ++ 1 => tx_disable ++ 2 => rx_loss */ ++ ++ u8 device_id; ++ struct eeprom_data eeprom; ++}; ++ ++struct sfp_port_data { ++ struct mutex update_lock; ++ enum driver_type_e driver_type; ++ int port; /* CPLD port index */ ++ oom_driver_port_type_t port_type; ++ u64 present; /* present status, bit0:port0, bit1:port1 and so on */ ++ ++ struct sfp_msa_data *msa; ++ struct sfp_ddm_data *ddm; ++ struct qsfp_data *qsfp; ++ ++ struct i2c_client *client; ++}; ++ ++static ssize_t show_port_number(struct device *dev, struct device_attribute *da, ++ char *buf) +{ -+ unsigned int page = 0; ++ struct i2c_client *client = to_i2c_client(dev); ++ struct sfp_port_data *data = i2c_get_clientdata(client); + -+ *client = optoe->client[0]; -+ -+ /* if SFP style, offset > 255, shift to i2c addr 0x51 */ -+ if (optoe->dev_class == TWO_ADDR) { -+ if (*offset > 255) { -+ /* like QSFP, but shifted to client[1] */ -+ *client = optoe->client[1]; -+ *offset -= 256; -+ } -+ } -+ -+ /* -+ * if offset is in the range 0-128... -+ * page doesn't matter (using lower half), return 0. -+ * offset is already correct (don't add 128 to get to paged area) -+ */ -+ if (*offset < OPTOE_PAGE_SIZE) -+ return page; -+ -+ /* note, page will always be positive since *offset >= 128 */ -+ page = (*offset >> 7)-1; -+ /* 0x80 places the offset in the top half, offset is last 7 bits */ -+ *offset = OPTOE_PAGE_SIZE + (*offset & 0x7f); -+ -+ return page; /* note also returning client and offset */ ++ return sprintf(buf, "sfp %d\n", data->port); +} + -+static ssize_t optoe_eeprom_read(struct optoe_data *optoe, -+ struct i2c_client *client, -+ char *buf, unsigned int offset, size_t count) ++/* Platform dependent +++ */ ++static struct sfp_port_data *sfp_update_present(struct i2c_client *client) +{ -+ struct i2c_msg msg[2]; -+ u8 msgbuf[2]; -+ unsigned long timeout, read_time; -+ int status, i; -+ -+ memset(msg, 0, sizeof(msg)); -+ -+ switch (optoe->use_smbus) { -+ case I2C_SMBUS_I2C_BLOCK_DATA: -+ /*smaller eeproms can work given some SMBus extension calls */ -+ if (count > I2C_SMBUS_BLOCK_MAX) -+ count = I2C_SMBUS_BLOCK_MAX; -+ break; -+ case I2C_SMBUS_WORD_DATA: -+ /* Check for odd length transaction */ -+ count = (count == 1) ? 1 : 2; -+ break; -+ case I2C_SMBUS_BYTE_DATA: -+ count = 1; -+ break; -+ default: -+ /* -+ * When we have a better choice than SMBus calls, use a -+ * combined I2C message. Write address; then read up to -+ * io_limit data bytes. msgbuf is u8 and will cast to our -+ * needs. -+ */ -+ i = 0; -+ msgbuf[i++] = offset; -+ -+ msg[0].addr = client->addr; -+ msg[0].buf = msgbuf; -+ msg[0].len = i; -+ -+ msg[1].addr = client->addr; -+ msg[1].flags = I2C_M_RD; -+ msg[1].buf = buf; -+ msg[1].len = count; -+ } -+ -+ /* -+ * Reads fail if the previous write didn't complete yet. We may -+ * loop a few times until this one succeeds, waiting at least -+ * long enough for one entire page write to work. -+ */ -+ timeout = jiffies + msecs_to_jiffies(write_timeout); -+ do { -+ read_time = jiffies; -+ -+ switch (optoe->use_smbus) { -+ case I2C_SMBUS_I2C_BLOCK_DATA: -+ status = i2c_smbus_read_i2c_block_data(client, offset, -+ count, buf); -+ break; -+ case I2C_SMBUS_WORD_DATA: -+ status = i2c_smbus_read_word_data(client, offset); -+ if (status >= 0) { -+ buf[0] = status & 0xff; -+ if (count == 2) -+ buf[1] = status >> 8; -+ status = count; -+ } -+ break; -+ case I2C_SMBUS_BYTE_DATA: -+ status = i2c_smbus_read_byte_data(client, offset); -+ if (status >= 0) { -+ buf[0] = status; -+ status = count; -+ } -+ break; -+ default: -+ status = i2c_transfer(client->adapter, msg, 2); -+ if (status == 2) -+ status = count; -+ } -+ -+ dev_dbg(&client->dev, "eeprom read %zu@%d --> %d (%ld)\n", -+ count, offset, status, jiffies); -+ -+ if (status == count) /* happy path */ -+ return count; -+ -+ if (status == -ENXIO) /* no module present */ -+ return status; -+ -+ /* REVISIT: at HZ=100, this is sloooow */ -+ usleep_range(1000, 2000); -+ } while (time_before(read_time, timeout)); -+ -+ return -ETIMEDOUT; -+} -+ -+static ssize_t optoe_eeprom_write(struct optoe_data *optoe, -+ struct i2c_client *client, -+ const char *buf, -+ unsigned int offset, size_t count) -+{ -+ struct i2c_msg msg; -+ ssize_t status; -+ unsigned long timeout, write_time; -+ unsigned int next_page_start; ++ struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0; ++ int status = -1; ++ u8 regs[] = {0x2, 0x3, 0x21}; + -+ /* write max is at most a page -+ * (In this driver, write_max is actually one byte!) -+ */ -+ if (count > optoe->write_max) -+ count = optoe->write_max; ++ DEBUG_PRINT("Starting sfp present status update"); ++ mutex_lock(&data->update_lock); + -+ /* shorten count if necessary to avoid crossing page boundary */ -+ next_page_start = roundup(offset + 1, OPTOE_PAGE_SIZE); -+ if (offset + count > next_page_start) -+ count = next_page_start - offset; ++ /* Read present status of port 49~54 */ ++ data->present = 0; + -+ switch (optoe->use_smbus) { -+ case I2C_SMBUS_I2C_BLOCK_DATA: -+ /*smaller eeproms can work given some SMBus extension calls */ -+ if (count > I2C_SMBUS_BLOCK_MAX) -+ count = I2C_SMBUS_BLOCK_MAX; ++ for (i = 0; i < ARRAY_SIZE(regs); i++) { ++ status = accton_i2c_cpld_read(0x30, regs[i]); ++ ++ if (status < 0) { ++ DEBUG_PRINT("cpld(0x30) reg(0x%x) err %d", regs[i], status); ++ goto exit; ++ } ++ ++ DEBUG_PRINT("Present status = 0x%lx", data->present); ++ switch (i) { ++ case 0: ++ data->present |= (status & BIT_INDEX(6)) >> 6; /* port 25/49 */ ++ data->present |= (status & BIT_INDEX(2)) >> 1; /* port 26/50 */ ++ break; ++ case 1: ++ data->present |= (status & BIT_INDEX(6)) >> 4; /* port 27/51 */ ++ data->present |= (status & BIT_INDEX(2)) << 1; /* port 28/52 */ ++ break; ++ case 2: ++ data->present |= (status & BIT_INDEX(0)) << 4; /* port 29/53 */ ++ data->present |= (status & BIT_INDEX(4)) << 1; /* port 30/54 */ ++ break; ++ default: ++ break; ++ } ++ } ++ ++ DEBUG_PRINT("Present status = 0x%lx", data->present); ++exit: ++ mutex_unlock(&data->update_lock); ++ return (status < 0) ? ERR_PTR(status) : data; ++} ++ ++static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct sfp_port_data *data = i2c_get_clientdata(client); ++ int i = 0; ++ int status = -1; ++ u8 regs[] = {0x2, 0x3, 0x21}; ++ ++ if (time_before(jiffies, data->msa->last_updated + HZ + HZ / 2) && data->msa->valid) { ++ return data; ++ } ++ ++ DEBUG_PRINT("Starting as4610 sfp tx rx status update"); ++ mutex_lock(&data->update_lock); ++ data->msa->valid = 0; ++ memset(data->msa->status, 0, sizeof(data->msa->status)); ++ ++ /* Read status of port 49~52(SFP port) */ ++ for (i = 0; i < ARRAY_SIZE(regs); i++) { ++ status = accton_i2c_cpld_read(0x30, regs[i]); ++ ++ if (status < 0) { ++ DEBUG_PRINT("cpld(0x30) reg(0x%x) err %d", regs[i], status); ++ goto exit; ++ } ++ ++ DEBUG_PRINT("TX_FAULT = 0x%lx, TX_DISABLE = 0x%lx, TX_FAULT = 0x%lx", ++ data->msa->status[0], data->msa->status[1], data->msa->status[2]); ++ switch (i) { ++ case 0: ++ /* port 25/49 */ ++ data->msa->status[0] |= (status & BIT_INDEX(5)) >> 5; /* tx_fail */ ++ data->msa->status[2] |= (status & BIT_INDEX(4)) >> 4; /* rx_los */ ++ /* port 26/50 */ ++ data->msa->status[0] |= (status & BIT_INDEX(1)) << 0; /* tx_fail */ ++ data->msa->status[2] |= (status & BIT_INDEX(0)) << 1; /* rx_los */ ++ break; ++ case 1: ++ /* port 27/51 */ ++ data->msa->status[0] |= (status & BIT_INDEX(5)) >> 3; /* tx_fail */ ++ data->msa->status[2] |= (status & BIT_INDEX(4)) >> 2; /* rx_los */ ++ /* port 28/52 */ ++ data->msa->status[0] |= (status & BIT_INDEX(1)) << 1; /* tx_fail */ ++ data->msa->status[2] |= (status & BIT_INDEX(0)) << 2; /* rx_los */ ++ break; ++ default: ++ break; ++ } ++ } ++ ++ DEBUG_PRINT("TX_FAULT = 0x%lx, TX_DISABLE = 0x%lx, TX_FAULT = 0x%lx", ++ data->msa->status[0], data->msa->status[1], data->msa->status[2]); ++ data->msa->valid = 1; ++ data->msa->last_updated = jiffies; ++ ++exit: ++ mutex_unlock(&data->update_lock); ++ return data; ++} ++/* Platform dependent --- */ ++ ++static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, ++ const char *buf, size_t count) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct sfp_port_data *data = i2c_get_clientdata(client); ++ ++ if (data->driver_type == DRIVER_TYPE_QSFP) { ++ return qsfp_set_tx_disable(dev, da, buf, count); ++ } ++ ++ return 0; ++} ++ ++static int sfp_is_port_present(struct i2c_client *client, int port) ++{ ++ struct sfp_port_data *data = i2c_get_clientdata(client); ++ ++ data = sfp_update_present(client); ++ if (IS_ERR(data)) { ++ return PTR_ERR(data); ++ } ++ ++ return (data->present & BIT_INDEX(data->port)) ? 1 : 0; /* Platform dependent */ ++} ++ ++/* Platform dependent +++ */ ++static ssize_t show_present(struct device *dev, struct device_attribute *da, ++ char *buf) ++{ ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); ++ struct i2c_client *client = to_i2c_client(dev); ++ ++ if (PRESENT_ALL == attr->index) { ++ struct sfp_port_data *data = sfp_update_present(client); ++ ++ if (IS_ERR(data)) { ++ return PTR_ERR(data); ++ } ++ ++ /* Return values 25/49 -> 30/54 in order */ ++ return sprintf(buf, "%.2x\n", (u8)(data->present)); ++ } ++ else { ++ struct sfp_port_data *data = i2c_get_clientdata(client); ++ int present = sfp_is_port_present(client, data->port); ++ ++ if (IS_ERR_VALUE(present)) { ++ return present; ++ } ++ ++ /* PRESENT */ ++ return sprintf(buf, "%d\n", present); ++ } ++} ++/* Platform dependent --- */ ++ ++static struct sfp_port_data *sfp_update_port_type(struct device *dev) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct sfp_port_data *data = i2c_get_clientdata(client); ++ u8 buf = 0; ++ int status; ++ ++ mutex_lock(&data->update_lock); ++ ++ switch (data->driver_type) { ++ case DRIVER_TYPE_SFP_MSA: ++ { ++ status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); ++ if (unlikely(status < 0)) { ++ data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; ++ break; ++ } ++ ++ if (buf != SFF8024_DEVICE_ID_SFP) { ++ data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; ++ break; ++ } ++ ++ status = sfp_eeprom_read(client, SFF8472_10G_ETH_COMPLIANCE_ADDR, &buf, sizeof(buf)); ++ if (unlikely(status < 0)) { ++ data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; ++ break; ++ } ++ ++ DEBUG_PRINT("sfp port type (0x3) data = (0x%x)", buf); ++ data->port_type = buf & SFF8472_10G_BASE_MASK ? OOM_DRIVER_PORT_TYPE_SFP_PLUS : OOM_DRIVER_PORT_TYPE_SFP; ++ break; ++ } ++ case DRIVER_TYPE_QSFP: ++ { ++ status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); ++ if (unlikely(status < 0)) { ++ data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; ++ break; ++ } ++ ++ DEBUG_PRINT("qsfp port type (0x0) buf = (0x%x)", buf); ++ switch (buf) { ++ case SFF8024_DEVICE_ID_QSFP: ++ data->port_type = OOM_DRIVER_PORT_TYPE_QSFP; ++ break; ++ case SFF8024_DEVICE_ID_QSFP_PLUS: ++ data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; ++ break; ++ case SFF8024_DEVICE_ID_QSFP28: ++ data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; ++ break; ++ default: ++ data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; ++ break; ++ } ++ ++ break; ++ } ++ default: ++ break; ++ } ++ ++ mutex_unlock(&data->update_lock); ++ return data; ++} ++ ++static ssize_t show_port_type(struct device *dev, struct device_attribute *da, ++ char *buf) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct sfp_port_data *data = i2c_get_clientdata(client); ++ int present = sfp_is_port_present(client, data->port); ++ ++ if (IS_ERR_VALUE(present)) { ++ return present; ++ } ++ ++ if (!present) { ++ return sprintf(buf, "%d\n", OOM_DRIVER_PORT_TYPE_NOT_PRESENT); ++ } ++ ++ sfp_update_port_type(dev); ++ return sprintf(buf, "%d\n", data->port_type); ++} ++ ++static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct sfp_port_data *data = i2c_get_clientdata(client); ++ int i, status = -1; ++ u8 buf = 0; ++ u8 reg[] = {SFF8436_TX_FAULT_ADDR, SFF8436_TX_DISABLE_ADDR, SFF8436_RX_LOS_ADDR}; ++ ++ if (time_before(jiffies, data->qsfp->last_updated + HZ + HZ / 2) && data->qsfp->valid) { ++ return data; ++ } ++ ++ DEBUG_PRINT("Starting sfp tx rx status update"); ++ mutex_lock(&data->update_lock); ++ data->qsfp->valid = 0; ++ memset(data->qsfp->status, 0, sizeof(data->qsfp->status)); ++ ++ /* Notify device to update tx fault/ tx disable/ rx los status */ ++ for (i = 0; i < ARRAY_SIZE(reg); i++) { ++ status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); ++ if (unlikely(status < 0)) { ++ goto exit; ++ } ++ } ++ msleep(200); ++ ++ /* Read actual tx fault/ tx disable/ rx los status */ ++ for (i = 0; i < ARRAY_SIZE(reg); i++) { ++ status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); ++ if (unlikely(status < 0)) { ++ goto exit; ++ } ++ ++ DEBUG_PRINT("qsfp reg(0x%x) status = (0x%x)", reg[i], data->qsfp->status[i]); ++ data->qsfp->status[i] = (buf & 0xF); ++ } ++ ++ data->qsfp->valid = 1; ++ data->qsfp->last_updated = jiffies; ++ ++exit: ++ mutex_unlock(&data->update_lock); ++ return (status < 0) ? ERR_PTR(status) : data; ++} ++ ++static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, ++ char *buf) ++{ ++ int present; ++ u8 val = 0; ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); ++ struct i2c_client *client = to_i2c_client(dev); ++ struct sfp_port_data *data = i2c_get_clientdata(client); ++ ++ present = sfp_is_port_present(client, data->port); ++ if (IS_ERR_VALUE(present)) { ++ return present; ++ } ++ ++ if (present == 0) { ++ /* port is not present */ ++ return -ENXIO; ++ } ++ ++ data = qsfp_update_tx_rx_status(dev); ++ if (IS_ERR(data)) { ++ return PTR_ERR(data); ++ } ++ ++ switch (attr->index) { ++ case TX_FAULT: ++ val = !!(data->qsfp->status[2] & 0xF); + break; -+ case I2C_SMBUS_WORD_DATA: -+ /* Check for odd length transaction */ -+ count = (count == 1) ? 1 : 2; ++ case TX_FAULT1: ++ case TX_FAULT2: ++ case TX_FAULT3: ++ case TX_FAULT4: ++ val = !!(data->qsfp->status[2] & BIT_INDEX(attr->index - TX_FAULT1)); + break; -+ case I2C_SMBUS_BYTE_DATA: -+ count = 1; ++ case TX_DISABLE: ++ val = data->qsfp->status[1] & 0xF; ++ break; ++ case TX_DISABLE1: ++ case TX_DISABLE2: ++ case TX_DISABLE3: ++ case TX_DISABLE4: ++ val = !!(data->qsfp->status[1] & BIT_INDEX(attr->index - TX_DISABLE1)); ++ break; ++ case RX_LOS: ++ val = !!(data->qsfp->status[0] & 0xF); ++ break; ++ case RX_LOS1: ++ case RX_LOS2: ++ case RX_LOS3: ++ case RX_LOS4: ++ val = !!(data->qsfp->status[0] & BIT_INDEX(attr->index - RX_LOS1)); + break; + default: -+ /* If we'll use I2C calls for I/O, set up the message */ -+ msg.addr = client->addr; -+ msg.flags = 0; -+ -+ /* msg.buf is u8 and casts will mask the values */ -+ msg.buf = optoe->writebuf; -+ -+ msg.buf[i++] = offset; -+ memcpy(&msg.buf[i], buf, count); -+ msg.len = i + count; + break; + } + ++ return sprintf(buf, "%d\n", val); ++} ++ ++static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, ++ const char *buf, size_t count) ++{ ++ long disable; ++ int status; ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); ++ struct i2c_client *client = to_i2c_client(dev); ++ struct sfp_port_data *data = i2c_get_clientdata(client); ++ ++ status = sfp_is_port_present(client, data->port); ++ if (IS_ERR_VALUE(status)) { ++ return status; ++ } ++ ++ if (!status) { ++ /* port is not present */ ++ return -ENXIO; ++ } ++ ++ status = kstrtol(buf, 10, &disable); ++ if (status) { ++ return status; ++ } ++ ++ data = qsfp_update_tx_rx_status(dev); ++ if (IS_ERR(data)) { ++ return PTR_ERR(data); ++ } ++ ++ mutex_lock(&data->update_lock); ++ ++ if (attr->index == TX_DISABLE) { ++ data->qsfp->status[1] = disable & 0xF; ++ } ++ else {/* TX_DISABLE1 ~ TX_DISABLE4*/ ++ if (disable) { ++ data->qsfp->status[1] |= (1 << (attr->index - TX_DISABLE1)); ++ } ++ else { ++ data->qsfp->status[1] &= ~(1 << (attr->index - TX_DISABLE1)); ++ } ++ } ++ ++ DEBUG_PRINT("index = (%d), status = (0x%x)", attr->index, data->qsfp->status[1]); ++ status = sfp_eeprom_write(data->client, SFF8436_TX_DISABLE_ADDR, &data->qsfp->status[1], sizeof(data->qsfp->status[1])); ++ if (unlikely(status < 0)) { ++ count = status; ++ } ++ ++ mutex_unlock(&data->update_lock); ++ return count; ++} ++ ++static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, ++ char *buf) ++{ ++ int status; ++ char ddm; ++ struct i2c_client *client = to_i2c_client(dev); ++ struct sfp_port_data *data = i2c_get_clientdata(client); ++ ++ status = sfp_is_port_present(client, data->port); ++ if (IS_ERR_VALUE(status)) { ++ return status; ++ } ++ ++ if (status == 0) { ++ /* port is not present */ ++ return -ENODEV; ++ } ++ ++ status = sfp_eeprom_read(client, SFF8472_DIAG_MON_TYPE_ADDR, &ddm, sizeof(ddm)); ++ if (unlikely(status < 0)) { ++ return status; ++ } ++ ++ return sprintf(buf, "%d\n", !!(ddm & SFF8472_DIAG_MON_TYPE_DDM_MASK)); ++} ++ ++/* Platform dependent +++ */ ++static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, ++ char *buf) ++{ ++ u8 val = 0, index = 0; ++ struct i2c_client *client = to_i2c_client(dev); ++ struct sfp_port_data *data = i2c_get_clientdata(client); ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); ++ ++ if (data->driver_type == DRIVER_TYPE_QSFP) { ++ return qsfp_show_tx_rx_status(dev, da, buf); ++ } ++ ++ data = sfp_update_tx_rx_status(dev); ++ if (IS_ERR(data)) { ++ return PTR_ERR(data); ++ } ++ ++ if(attr->index == RX_LOS_ALL) { ++ /** Return values 25/49 -> 28/52 in order */ ++ return sprintf(buf, "%.2x\n", (u8)(data->msa->status[2])); ++ } ++ ++ switch (attr->index) { ++ case TX_FAULT: ++ index = 0; ++ break; ++ case TX_DISABLE: ++ index = 1; ++ break; ++ case RX_LOS: ++ index = 2; ++ break; ++ default: ++ return 0; ++ } ++ ++ val = (data->msa->status[index] & BIT_INDEX(data->port)) ? 1 : 0; ++ return sprintf(buf, "%d\n", val); ++} ++/* Platform dependent --- */ ++static ssize_t sfp_eeprom_write(struct i2c_client *client, u8 command, const char *data, ++ int data_len) ++{ ++#if USE_I2C_BLOCK_READ ++ int status, retry = I2C_RW_RETRY_COUNT; ++ ++ if (data_len > I2C_SMBUS_BLOCK_MAX) { ++ data_len = I2C_SMBUS_BLOCK_MAX; ++ } ++ ++ while (retry) { ++ status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); ++ if (unlikely(status < 0)) { ++ msleep(I2C_RW_RETRY_INTERVAL); ++ retry--; ++ continue; ++ } ++ ++ break; ++ } ++ ++ if (unlikely(status < 0)) { ++ return status; ++ } ++ ++ return data_len; ++#else ++ int status, retry = I2C_RW_RETRY_COUNT; ++ ++ while (retry) { ++ status = i2c_smbus_write_byte_data(client, command, *data); ++ if (unlikely(status < 0)) { ++ msleep(I2C_RW_RETRY_INTERVAL); ++ retry--; ++ continue; ++ } ++ ++ break; ++ } ++ ++ if (unlikely(status < 0)) { ++ return status; ++ } ++ ++ return 1; ++#endif ++ ++ ++} ++ ++static ssize_t sfp_port_write(struct sfp_port_data *data, ++ const char *buf, loff_t off, size_t count) ++{ ++ ssize_t retval = 0; ++ ++ if (unlikely(!count)) { ++ return count; ++ } ++ + /* -+ * Reads fail if the previous write didn't complete yet. We may -+ * loop a few times until this one succeeds, waiting at least -+ * long enough for one entire page write to work. ++ * Write data to chip, protecting against concurrent updates ++ * from this host, but not from other I2C masters. + */ -+ timeout = jiffies + msecs_to_jiffies(write_timeout); -+ do { -+ write_time = jiffies; -+ -+ switch (optoe->use_smbus) { -+ case I2C_SMBUS_I2C_BLOCK_DATA: -+ status = i2c_smbus_write_i2c_block_data(client, -+ offset, count, buf); -+ if (status == 0) -+ status = count; -+ break; -+ case I2C_SMBUS_WORD_DATA: -+ if (count == 2) { -+ status = i2c_smbus_write_word_data(client, -+ offset, (u16)((buf[0])|(buf[1] << 8))); -+ } else { -+ /* count = 1 */ -+ status = i2c_smbus_write_byte_data(client, -+ offset, buf[0]); -+ } -+ if (status == 0) -+ status = count; -+ break; -+ case I2C_SMBUS_BYTE_DATA: -+ status = i2c_smbus_write_byte_data(client, offset, -+ buf[0]); -+ if (status == 0) -+ status = count; -+ break; -+ default: -+ status = i2c_transfer(client->adapter, &msg, 1); -+ if (status == 1) -+ status = count; -+ break; -+ } -+ -+ dev_dbg(&client->dev, "eeprom write %zu@%d --> %ld (%lu)\n", -+ count, offset, (long int) status, jiffies); -+ -+ if (status == count) -+ return count; -+ -+ /* REVISIT: at HZ=100, this is sloooow */ -+ usleep_range(1000, 2000); -+ } while (time_before(write_time, timeout)); -+ -+ return -ETIMEDOUT; -+} -+ -+ -+static ssize_t optoe_eeprom_update_client(struct optoe_data *optoe, -+ char *buf, loff_t off, -+ size_t count, int opcode) -+{ -+ struct i2c_client *client; -+ ssize_t retval = 0; -+ uint8_t page = 0; -+ loff_t phy_offset = off; -+ int ret = 0; -+ -+ page = optoe_translate_offset(optoe, &phy_offset, &client); -+ dev_dbg(&client->dev, -+ "%s off %lld page:%d phy_offset:%lld, count:%ld, opcode:%d\n", -+ __func__, off, page, phy_offset, (long int) count, opcode); -+ if (page > 0) { -+ ret = optoe_eeprom_write(optoe, client, &page, -+ OPTOE_PAGE_SELECT_REG, 1); -+ if (ret < 0) { -+ dev_dbg(&client->dev, -+ "Write page register for page %d failed ret:%d!\n", -+ page, ret); -+ return ret; -+ } -+ } ++ mutex_lock(&data->update_lock); + + while (count) { -+ ssize_t status; ++ ssize_t status; + -+ if (opcode == OPTOE_READ_OP) { -+ status = optoe_eeprom_read(optoe, client, -+ buf, phy_offset, count); -+ } else { -+ status = optoe_eeprom_write(optoe, client, -+ buf, phy_offset, count); -+ } ++ status = sfp_eeprom_write(data->client, off, buf, count); + if (status <= 0) { -+ if (retval == 0) ++ if (retval == 0) { + retval = status; ++ } + break; + } + buf += status; -+ phy_offset += status; ++ off += status; + count -= status; + retval += status; + } + -+ -+ if (page > 0) { -+ /* return the page register to page 0 (why?) */ -+ page = 0; -+ ret = optoe_eeprom_write(optoe, client, &page, -+ OPTOE_PAGE_SELECT_REG, 1); -+ if (ret < 0) { -+ dev_err(&client->dev, -+ "Restore page register to 0 failed:%d!\n", ret); -+ /* error only if nothing has been transferred */ -+ if (retval == 0) -+ retval = ret; -+ } -+ } ++ mutex_unlock(&data->update_lock); + return retval; +} + -+/* -+ * Figure out if this access is within the range of supported pages. -+ * Note this is called on every access because we don't know if the -+ * module has been replaced since the last call. -+ * If/when modules support more pages, this is the routine to update -+ * to validate and allow access to additional pages. -+ * -+ * Returns updated len for this access: -+ * - entire access is legal, original len is returned. -+ * - access begins legal but is too long, len is truncated to fit. -+ * - initial offset exceeds supported pages, return OPTOE_EOF (zero) -+ */ -+static ssize_t optoe_page_legal(struct optoe_data *optoe, -+ loff_t off, size_t len) ++ ++static ssize_t sfp_bin_write(struct file *filp, struct kobject *kobj, ++ struct bin_attribute *attr, ++ char *buf, loff_t off, size_t count) +{ -+ struct i2c_client *client = optoe->client[0]; -+ u8 regval; -+ int status; -+ size_t maxlen; ++ int present; ++ struct sfp_port_data *data; ++ DEBUG_PRINT("%s(%d) offset = (%d), count = (%d)", off, count); ++ data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + -+ if (off < 0) -+ return -EINVAL; -+ if (optoe->dev_class == TWO_ADDR) { -+ /* SFP case */ -+ /* if only using addr 0x50 (first 256 bytes) we're good */ -+ if ((off + len) <= TWO_ADDR_NO_0X51_SIZE) -+ return len; -+ /* if offset exceeds possible pages, we're not good */ -+ if (off >= TWO_ADDR_EEPROM_SIZE) -+ return OPTOE_EOF; -+ /* in between, are pages supported? */ -+ status = optoe_eeprom_read(optoe, client, ®val, -+ TWO_ADDR_PAGEABLE_REG, 1); -+ if (status < 0) -+ return status; /* error out (no module?) */ -+ if (regval & TWO_ADDR_PAGEABLE) { -+ /* Pages supported, trim len to the end of pages */ -+ maxlen = TWO_ADDR_EEPROM_SIZE - off; -+ } else { -+ /* pages not supported, trim len to unpaged size */ -+ if (off >= TWO_ADDR_EEPROM_UNPAGED_SIZE) -+ return OPTOE_EOF; -+ -+ /* will be accessing addr 0x51, is that supported? */ -+ /* byte 92, bit 6 implies DDM support, 0x51 support */ -+ status = optoe_eeprom_read(optoe, client, ®val, -+ TWO_ADDR_0X51_REG, 1); -+ if (status < 0) -+ return status; -+ if (regval & TWO_ADDR_0X51_SUPP) { -+ /* addr 0x51 is OK */ -+ maxlen = TWO_ADDR_EEPROM_UNPAGED_SIZE - off; -+ } else { -+ /* addr 0x51 NOT supported, trim to 256 max */ -+ if (off >= TWO_ADDR_NO_0X51_SIZE) -+ return OPTOE_EOF; -+ maxlen = TWO_ADDR_NO_0X51_SIZE - off; -+ } -+ } -+ len = (len > maxlen) ? maxlen : len; -+ dev_dbg(&client->dev, -+ "page_legal, SFP, off %lld len %ld\n", -+ off, (long int) len); -+ } else { -+ /* QSFP case */ -+ /* if no pages needed, we're good */ -+ if ((off + len) <= ONE_ADDR_EEPROM_UNPAGED_SIZE) -+ return len; -+ /* if offset exceeds possible pages, we're not good */ -+ if (off >= ONE_ADDR_EEPROM_SIZE) -+ return OPTOE_EOF; -+ /* in between, are pages supported? */ -+ status = optoe_eeprom_read(optoe, client, ®val, -+ ONE_ADDR_PAGEABLE_REG, 1); -+ if (status < 0) -+ return status; /* error out (no module?) */ -+ if (regval & ONE_ADDR_NOT_PAGEABLE) { -+ /* pages not supported, trim len to unpaged size */ -+ if (off >= ONE_ADDR_EEPROM_UNPAGED_SIZE) -+ return OPTOE_EOF; -+ maxlen = ONE_ADDR_EEPROM_UNPAGED_SIZE - off; -+ } else { -+ /* Pages supported, trim len to the end of pages */ -+ maxlen = ONE_ADDR_EEPROM_SIZE - off; -+ } -+ len = (len > maxlen) ? maxlen : len; -+ dev_dbg(&client->dev, -+ "page_legal, QSFP, off %lld len %ld\n", -+ off, (long int) len); ++ present = sfp_is_port_present(data->client, data->port); ++ if (IS_ERR_VALUE(present)) { ++ return present; + } -+ return len; ++ ++ if (present == 0) { ++ /* port is not present */ ++ return -ENODEV; ++ } ++ ++ return sfp_port_write(data, buf, off, count); +} + -+static ssize_t optoe_read_write(struct optoe_data *optoe, -+ char *buf, loff_t off, size_t len, int opcode) ++static ssize_t sfp_eeprom_read(struct i2c_client *client, u8 command, u8 *data, ++ int data_len) +{ -+ struct i2c_client *client = optoe->client[0]; -+ int chunk; -+ int status = 0; -+ ssize_t retval; -+ size_t pending_len = 0, chunk_len = 0; -+ loff_t chunk_offset = 0, chunk_start_offset = 0; ++#if USE_I2C_BLOCK_READ ++ int status, retry = I2C_RW_RETRY_COUNT; + -+ dev_dbg(&client->dev, -+ "%s: off %lld len:%ld, opcode:%s\n", -+ __func__, off, (long int) len, -+ (opcode == OPTOE_READ_OP) ? "r" : "w"); -+ if (unlikely(!len)) -+ return len; ++ if (data_len > I2C_SMBUS_BLOCK_MAX) { ++ data_len = I2C_SMBUS_BLOCK_MAX; ++ } ++ ++ while (retry) { ++ status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); ++ if (unlikely(status < 0)) { ++ msleep(I2C_RW_RETRY_INTERVAL); ++ retry--; ++ continue; ++ } ++ ++ break; ++ } ++ ++ if (unlikely(status < 0)) { ++ goto abort; ++ } ++ if (unlikely(status != data_len)) { ++ status = -EIO; ++ goto abort; ++ } ++ ++ //result = data_len; ++ ++abort: ++ return status; ++#else ++ int status, retry = I2C_RW_RETRY_COUNT; ++ ++ while (retry) { ++ status = i2c_smbus_read_byte_data(client, command); ++ if (unlikely(status < 0)) { ++ msleep(I2C_RW_RETRY_INTERVAL); ++ retry--; ++ continue; ++ } ++ ++ break; ++ } ++ ++ if (unlikely(status < 0)) { ++ dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, status); ++ goto abort; ++ } ++ ++ *data = (u8)status; ++ status = 1; ++ ++abort: ++ return status; ++#endif ++} ++ ++static ssize_t sfp_port_read(struct sfp_port_data *data, ++ char *buf, loff_t off, size_t count) ++{ ++ ssize_t retval = 0; ++ ++ if (unlikely(!count)) { ++ DEBUG_PRINT("Count = 0, return"); ++ return count; ++ } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ -+ mutex_lock(&optoe->lock); ++ mutex_lock(&data->update_lock); + -+ /* -+ * Confirm this access fits within the device suppored addr range -+ */ -+ status = optoe_page_legal(optoe, off, len); -+ if ((status == OPTOE_EOF) || (status < 0)) { -+ mutex_unlock(&optoe->lock); -+ return status; -+ } -+ len = status; ++ while (count) { ++ ssize_t status; + -+ /* -+ * For each (128 byte) chunk involved in this request, issue a -+ * separate call to sff_eeprom_update_client(), to -+ * ensure that each access recalculates the client/page -+ * and writes the page register as needed. -+ * Note that chunk to page mapping is confusing, is different for -+ * QSFP and SFP, and never needs to be done. Don't try! -+ */ -+ pending_len = len; /* amount remaining to transfer */ -+ retval = 0; /* amount transferred */ -+ for (chunk = off >> 7; chunk <= (off + len - 1) >> 7; chunk++) { -+ -+ /* -+ * Compute the offset and number of bytes to be read/write -+ * -+ * 1. start at offset 0 (within the chunk), and read/write -+ * the entire chunk -+ * 2. start at offset 0 (within the chunk) and read/write less -+ * than entire chunk -+ * 3. start at an offset not equal to 0 and read/write the rest -+ * of the chunk -+ * 4. start at an offset not equal to 0 and read/write less than -+ * (end of chunk - offset) -+ */ -+ chunk_start_offset = chunk * OPTOE_PAGE_SIZE; -+ -+ if (chunk_start_offset < off) { -+ chunk_offset = off; -+ if ((off + pending_len) < (chunk_start_offset + -+ OPTOE_PAGE_SIZE)) -+ chunk_len = pending_len; -+ else -+ chunk_len = OPTOE_PAGE_SIZE - off; -+ } else { -+ chunk_offset = chunk_start_offset; -+ if (pending_len > OPTOE_PAGE_SIZE) -+ chunk_len = OPTOE_PAGE_SIZE; -+ else -+ chunk_len = pending_len; -+ } -+ -+ dev_dbg(&client->dev, -+ "sff_r/w: off %lld, len %ld, chunk_start_offset %lld, chunk_offset %lld, chunk_len %ld, pending_len %ld\n", -+ off, (long int) len, chunk_start_offset, chunk_offset, -+ (long int) chunk_len, (long int) pending_len); -+ -+ /* -+ * note: chunk_offset is from the start of the EEPROM, -+ * not the start of the chunk -+ */ -+ status = optoe_eeprom_update_client(optoe, buf, -+ chunk_offset, chunk_len, opcode); -+ if (status != chunk_len) { -+ /* This is another 'no device present' path */ -+ dev_dbg(&client->dev, -+ "o_u_c: chunk %d c_offset %lld c_len %ld failed %d!\n", -+ chunk, chunk_offset, (long int) chunk_len, status); -+ if (status > 0) -+ retval += status; -+ if (retval == 0) ++ status = sfp_eeprom_read(data->client, off, buf, count); ++ if (status <= 0) { ++ if (retval == 0) { + retval = status; ++ } + break; + } ++ + buf += status; -+ pending_len -= status; ++ off += status; ++ count -= status; + retval += status; + } -+ mutex_unlock(&optoe->lock); + ++ mutex_unlock(&data->update_lock); + return retval; ++ +} + -+static ssize_t optoe_bin_read(struct file *filp, struct kobject *kobj, ++static ssize_t sfp_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ -+ struct i2c_client *client = to_i2c_client(container_of(kobj, -+ struct device, kobj)); -+ struct optoe_data *optoe = i2c_get_clientdata(client); ++ int present; ++ struct sfp_port_data *data; ++ DEBUG_PRINT("offset = (%d), count = (%d)", off, count); ++ data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + -+ return optoe_read_write(optoe, buf, off, count, OPTOE_READ_OP); ++ present = sfp_is_port_present(data->client, data->port); ++ if (IS_ERR_VALUE(present)) { ++ return present; ++ } ++ ++ if (present == 0) { ++ /* port is not present */ ++ return -ENODEV; ++ } ++ ++ return sfp_port_read(data, buf, off, count); +} + -+ -+static ssize_t optoe_bin_write(struct file *filp, struct kobject *kobj, -+ struct bin_attribute *attr, -+ char *buf, loff_t off, size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(container_of(kobj, -+ struct device, kobj)); -+ struct optoe_data *optoe = i2c_get_clientdata(client); -+ -+ return optoe_read_write(optoe, buf, off, count, OPTOE_WRITE_OP); -+} -+ -+static int optoe_remove(struct i2c_client *client) -+{ -+ struct optoe_data *optoe; -+ int i; -+ -+ optoe = i2c_get_clientdata(client); -+ sysfs_remove_group(&client->dev.kobj, &optoe->attr_group); -+ sysfs_remove_bin_file(&client->dev.kobj, &optoe->bin); -+ -+ for (i = 1; i < optoe->num_addresses; i++) -+ i2c_unregister_device(optoe->client[i]); -+ -+#ifdef EEPROM_CLASS -+ eeprom_device_unregister(optoe->eeprom_dev); -+#endif -+ -+ kfree(optoe->writebuf); -+ kfree(optoe); -+ return 0; -+} -+ -+static ssize_t show_dev_class(struct device *dev, -+ struct device_attribute *dattr, char *buf) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct optoe_data *optoe = i2c_get_clientdata(client); -+ ssize_t count; -+ -+ mutex_lock(&optoe->lock); -+ count = sprintf(buf, "%d\n", optoe->dev_class); -+ mutex_unlock(&optoe->lock); -+ -+ return count; -+} -+ -+static ssize_t set_dev_class(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct optoe_data *optoe = i2c_get_clientdata(client); -+ int dev_class; -+ -+ /* -+ * dev_class is actually the number of i2c addresses used, thus -+ * legal values are "1" (QSFP class) and "2" (SFP class) -+ */ -+ -+ if (kstrtoint(buf, 0, &dev_class) != 0 || -+ dev_class < 1 || dev_class > 2) -+ return -EINVAL; -+ -+ mutex_lock(&optoe->lock); -+ optoe->dev_class = dev_class; -+ mutex_unlock(&optoe->lock); -+ -+ return count; -+} -+ -+/* -+ * if using the EEPROM CLASS driver, we don't report a port_name, -+ * the EEPROM CLASS drive handles that. Hence all this code is -+ * only compiled if we are NOT using the EEPROM CLASS driver. -+ */ -+#ifndef EEPROM_CLASS -+ -+static ssize_t show_port_name(struct device *dev, -+ struct device_attribute *dattr, char *buf) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct optoe_data *optoe = i2c_get_clientdata(client); -+ ssize_t count; -+ -+ mutex_lock(&optoe->lock); -+ count = sprintf(buf, "%s\n", optoe->port_name); -+ mutex_unlock(&optoe->lock); -+ -+ return count; -+} -+ -+static ssize_t set_port_name(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct optoe_data *optoe = i2c_get_clientdata(client); -+ char port_name[MAX_PORT_NAME_LEN]; -+ -+ /* no checking, this value is not used except by show_port_name */ -+ -+ if (sscanf(buf, "%19s", port_name) != 1) -+ return -EINVAL; -+ -+ mutex_lock(&optoe->lock); -+ strcpy(optoe->port_name, port_name); -+ mutex_unlock(&optoe->lock); -+ -+ return count; -+} -+ -+static DEVICE_ATTR(port_name, 0644, show_port_name, set_port_name); -+#endif /* if NOT defined EEPROM_CLASS, the common case */ -+ -+static DEVICE_ATTR(dev_class, 0644, show_dev_class, set_dev_class); -+ -+static struct attribute *optoe_attrs[] = { -+#ifndef EEPROM_CLASS -+ &dev_attr_port_name.attr, -+#endif -+ &dev_attr_dev_class.attr, -+ NULL, -+}; -+ -+static struct attribute_group optoe_attr_group = { -+ .attrs = optoe_attrs, -+}; -+ -+static int optoe_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) ++static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; -+ int use_smbus = 0; -+ struct optoe_platform_data chip; -+ struct optoe_data *optoe; -+ int num_addresses = 0; -+ char port_name[MAX_PORT_NAME_LEN]; + -+ if (client->addr != 0x50) { -+ dev_dbg(&client->dev, "probe, bad i2c addr: 0x%x\n", -+ client->addr); -+ err = -EINVAL; -+ goto exit; -+ } ++ sysfs_bin_attr_init(eeprom); ++ eeprom->attr.name = EEPROM_NAME; ++ eeprom->attr.mode = S_IWUSR | S_IRUGO; ++ eeprom->read = sfp_bin_read; ++ eeprom->write = sfp_bin_write; ++ eeprom->size = EEPROM_SIZE; + -+ if (client->dev.platform_data) { -+ chip = *(struct optoe_platform_data *)client->dev.platform_data; -+ /* take the port name from the supplied platform data */ -+#ifdef EEPROM_CLASS -+ strncpy(port_name, chip.eeprom_data->label, MAX_PORT_NAME_LEN); -+#else -+ memcpy(port_name, chip.port_name, MAX_PORT_NAME_LEN); -+#endif -+ dev_dbg(&client->dev, -+ "probe, chip provided, flags:0x%x; name: %s\n", -+ chip.flags, client->name); -+ } else { -+ if (!id->driver_data) { -+ err = -ENODEV; -+ goto exit; -+ } -+ dev_dbg(&client->dev, "probe, building chip\n"); -+ strcpy(port_name, "unitialized"); -+ chip.flags = 0; -+#ifdef EEPROM_CLASS -+ chip.eeprom_data = NULL; -+#endif -+ } -+ -+ /* Use I2C operations unless we're stuck with SMBus extensions. */ -+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { -+ if (i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { -+ use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; -+ } else if (i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_READ_WORD_DATA)) { -+ use_smbus = I2C_SMBUS_WORD_DATA; -+ } else if (i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_READ_BYTE_DATA)) { -+ use_smbus = I2C_SMBUS_BYTE_DATA; -+ } else { -+ err = -EPFNOSUPPORT; -+ goto exit; -+ } -+ } -+ -+ -+ /* -+ * Make room for two i2c clients -+ */ -+ num_addresses = 2; -+ -+ optoe = kzalloc(sizeof(struct optoe_data) + -+ num_addresses * sizeof(struct i2c_client *), -+ GFP_KERNEL); -+ if (!optoe) { -+ err = -ENOMEM; -+ goto exit; -+ } -+ -+ mutex_init(&optoe->lock); -+ -+ /* determine whether this is a one-address or two-address module */ -+ if ((strcmp(client->name, "optoe1") == 0) || -+ (strcmp(client->name, "sff8436") == 0)) { -+ /* one-address (eg QSFP) family */ -+ optoe->dev_class = ONE_ADDR; -+ chip.byte_len = ONE_ADDR_EEPROM_SIZE; -+ num_addresses = 1; -+ } else if ((strcmp(client->name, "optoe2") == 0) || -+ (strcmp(client->name, "24c04") == 0)) { -+ /* SFP family */ -+ optoe->dev_class = TWO_ADDR; -+ chip.byte_len = TWO_ADDR_EEPROM_SIZE; -+ } else { /* those were the only two choices */ -+ err = -EINVAL; -+ goto exit; -+ } -+ -+ dev_dbg(&client->dev, "dev_class: %d\n", optoe->dev_class); -+ optoe->use_smbus = use_smbus; -+ optoe->chip = chip; -+ optoe->num_addresses = num_addresses; -+ memcpy(optoe->port_name, port_name, MAX_PORT_NAME_LEN); -+ -+ /* -+ * Export the EEPROM bytes through sysfs, since that's convenient. -+ * By default, only root should see the data (maybe passwords etc) -+ */ -+ sysfs_bin_attr_init(&optoe->bin); -+ optoe->bin.attr.name = "eeprom"; -+ optoe->bin.attr.mode = 0444; -+ optoe->bin.read = optoe_bin_read; -+ optoe->bin.size = chip.byte_len; -+ -+ if (!use_smbus || -+ (i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) || -+ i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_WRITE_WORD_DATA) || -+ i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { -+ /* -+ * NOTE: AN-2079 -+ * Finisar recommends that the host implement 1 byte writes -+ * only since this module only supports 32 byte page boundaries. -+ * 2 byte writes are acceptable for PE and Vout changes per -+ * Application Note AN-2071. -+ */ -+ unsigned int write_max = 1; -+ -+ optoe->bin.write = optoe_bin_write; -+ optoe->bin.attr.mode |= 0200; -+ -+ if (write_max > io_limit) -+ write_max = io_limit; -+ if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) -+ write_max = I2C_SMBUS_BLOCK_MAX; -+ optoe->write_max = write_max; -+ -+ /* buffer (data + address at the beginning) */ -+ optoe->writebuf = kmalloc(write_max + 2, GFP_KERNEL); -+ if (!optoe->writebuf) { -+ err = -ENOMEM; -+ goto exit_kfree; -+ } -+ } else { -+ dev_warn(&client->dev, -+ "cannot write due to controller restrictions."); -+ } -+ -+ optoe->client[0] = client; -+ -+ /* SFF-8472 spec requires that the second I2C address be 0x51 */ -+ if (num_addresses == 2) { -+ optoe->client[1] = i2c_new_dummy(client->adapter, 0x51); -+ if (!optoe->client[1]) { -+ dev_err(&client->dev, "address 0x51 unavailable\n"); -+ err = -EADDRINUSE; -+ goto err_struct; -+ } -+ } -+ -+ /* create the sysfs eeprom file */ -+ err = sysfs_create_bin_file(&client->dev.kobj, &optoe->bin); -+ if (err) -+ goto err_struct; -+ -+ optoe->attr_group = optoe_attr_group; -+ -+ err = sysfs_create_group(&client->dev.kobj, &optoe->attr_group); ++ /* Create eeprom file */ ++ err = sysfs_create_bin_file(kobj, eeprom); + if (err) { -+ dev_err(&client->dev, "failed to create sysfs attribute group.\n"); -+ goto err_struct; -+ } -+ -+#ifdef EEPROM_CLASS -+ optoe->eeprom_dev = eeprom_device_register(&client->dev, -+ chip.eeprom_data); -+ if (IS_ERR(optoe->eeprom_dev)) { -+ dev_err(&client->dev, "error registering eeprom device.\n"); -+ err = PTR_ERR(optoe->eeprom_dev); -+ goto err_sysfs_cleanup; -+ } -+#endif -+ -+ i2c_set_clientdata(client, optoe); -+ -+ dev_info(&client->dev, "%zu byte %s EEPROM, %s\n", -+ optoe->bin.size, client->name, -+ optoe->bin.write ? "read/write" : "read-only"); -+ -+ if (use_smbus == I2C_SMBUS_WORD_DATA || -+ use_smbus == I2C_SMBUS_BYTE_DATA) { -+ dev_notice(&client->dev, -+ "Falling back to %s reads, performance will suffer\n", -+ use_smbus == I2C_SMBUS_WORD_DATA ? "word" : "byte"); ++ return err; + } + + return 0; -+ -+#ifdef EEPROM_CLASS -+err_sysfs_cleanup: -+ sysfs_remove_group(&client->dev.kobj, &optoe->attr_group); -+ sysfs_remove_bin_file(&client->dev.kobj, &optoe->bin); -+#endif -+ -+err_struct: -+ if (num_addresses == 2) { -+ if (optoe->client[1]) -+ i2c_unregister_device(optoe->client[1]); -+ } -+ -+ kfree(optoe->writebuf); -+exit_kfree: -+ kfree(optoe); -+exit: -+ dev_dbg(&client->dev, "probe error %d\n", err); -+ -+ return err; +} + -+/*-------------------------------------------------------------------------*/ ++static int sfp_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) ++{ ++ sysfs_remove_bin_file(kobj, eeprom); ++ return 0; ++} + -+static struct i2c_driver optoe_driver = { -+ .driver = { -+ .name = "optoe", -+ .owner = THIS_MODULE, -+ }, -+ .probe = optoe_probe, -+ .remove = optoe_remove, -+ .id_table = optoe_ids, ++static const struct attribute_group sfp_msa_group = { ++ .attrs = sfp_msa_attributes, +}; + -+static int __init optoe_init(void) ++static int sfp_i2c_check_functionality(struct i2c_client *client) +{ ++#if USE_I2C_BLOCK_READ ++ return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK); ++#else ++ return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA); ++#endif ++} + -+ if (!io_limit) { -+ pr_err("optoe: io_limit must not be 0!\n"); -+ return -EINVAL; ++static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, ++ struct sfp_msa_data **data) ++{ ++ int status; ++ struct sfp_msa_data *msa; ++ ++ if (!sfp_i2c_check_functionality(client)) { ++ status = -EIO; ++ goto exit; + } + -+ io_limit = rounddown_pow_of_two(io_limit); -+ return i2c_add_driver(&optoe_driver); -+} -+module_init(optoe_init); ++ msa = kzalloc(sizeof(struct sfp_msa_data), GFP_KERNEL); ++ if (!msa) { ++ status = -ENOMEM; ++ goto exit; ++ } + -+static void __exit optoe_exit(void) ++ /* Register sysfs hooks */ ++ status = sysfs_create_group(&client->dev.kobj, &sfp_msa_group); ++ if (status) { ++ goto exit_free; ++ } ++ ++ /* init eeprom */ ++ status = sfp_sysfs_eeprom_init(&client->dev.kobj, &msa->eeprom.bin); ++ if (status) { ++ goto exit_remove; ++ } ++ ++ *data = msa; ++ dev_info(&client->dev, "sfp msa '%s'\n", client->name); ++ ++ return 0; ++ ++exit_remove: ++ sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); ++exit_free: ++ kfree(msa); ++exit: ++ ++ return status; ++} ++ ++static const struct attribute_group sfp_ddm_group = { ++ .attrs = sfp_ddm_attributes, ++}; ++ ++static int sfp_ddm_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, ++ struct sfp_ddm_data **data) +{ -+ i2c_del_driver(&optoe_driver); -+} -+module_exit(optoe_exit); ++ int status; ++ struct sfp_ddm_data *ddm; + -+MODULE_DESCRIPTION("Driver for optical transceiver (SFP, QSFP, ...) EEPROMs"); -+MODULE_AUTHOR("DON BOLLINGER "); ++ if (!sfp_i2c_check_functionality(client)) { ++ status = -EIO; ++ goto exit; ++ } ++ ++ ddm = kzalloc(sizeof(struct sfp_ddm_data), GFP_KERNEL); ++ if (!ddm) { ++ status = -ENOMEM; ++ goto exit; ++ } ++ ++ /* Register sysfs hooks */ ++ status = sysfs_create_group(&client->dev.kobj, &sfp_ddm_group); ++ if (status) { ++ goto exit_free; ++ } ++ ++ /* init eeprom */ ++ status = sfp_sysfs_eeprom_init(&client->dev.kobj, &ddm->eeprom.bin); ++ if (status) { ++ goto exit_remove; ++ } ++ ++ *data = ddm; ++ dev_info(&client->dev, "sfp ddm '%s'\n", client->name); ++ ++ return 0; ++ ++exit_remove: ++ sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); ++exit_free: ++ kfree(ddm); ++exit: ++ ++ return status; ++} ++ ++static const struct attribute_group qsfp_group = { ++ .attrs = qsfp_attributes, ++}; ++ ++static int qsfp_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, ++ struct qsfp_data **data) ++{ ++ int status; ++ struct qsfp_data *qsfp; ++ ++ if (!sfp_i2c_check_functionality(client)) { ++ status = -EIO; ++ goto exit; ++ } ++ ++ qsfp = kzalloc(sizeof(struct qsfp_data), GFP_KERNEL); ++ if (!qsfp) { ++ status = -ENOMEM; ++ goto exit; ++ } ++ ++ /* Register sysfs hooks */ ++ status = sysfs_create_group(&client->dev.kobj, &qsfp_group); ++ if (status) { ++ goto exit_free; ++ } ++ ++ /* init eeprom */ ++ status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin); ++ if (status) { ++ goto exit_remove; ++ } ++ ++ *data = qsfp; ++ dev_info(&client->dev, "qsfp '%s'\n", client->name); ++ ++ return 0; ++ ++exit_remove: ++ sysfs_remove_group(&client->dev.kobj, &qsfp_group); ++exit_free: ++ kfree(qsfp); ++exit: ++ ++ return status; ++} ++ ++/* Platform dependent +++ */ ++static int sfp_device_probe(struct i2c_client *client, ++ const struct i2c_device_id *dev_id) ++{ ++ struct sfp_port_data *data = NULL; ++ ++ data = kzalloc(sizeof(struct sfp_port_data), GFP_KERNEL); ++ if (!data) { ++ return -ENOMEM; ++ } ++ ++ i2c_set_clientdata(client, data); ++ mutex_init(&data->update_lock); ++ data->port = dev_id->driver_data; ++ data->client = client; ++ ++ if (client->addr != SFP_EEPROM_A0_I2C_ADDR && ++ client->addr != SFP_EEPROM_A2_I2C_ADDR ) { ++ return -ENODEV; ++ } ++ ++ if (dev_id->driver_data >= as4610_sfp1 && dev_id->driver_data <= as4610_sfp4) { ++ if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { ++ data->driver_type = DRIVER_TYPE_SFP_MSA; ++ return sfp_msa_probe(client, dev_id, &data->msa); ++ } ++ else if (client->addr == SFP_EEPROM_A2_I2C_ADDR) { ++ data->driver_type = DRIVER_TYPE_SFP_DDM; ++ return sfp_ddm_probe(client, dev_id, &data->ddm); ++ } ++ } ++ else if (dev_id->driver_data >= as4610_sfp5 && dev_id->driver_data <= as4610_sfp6) { ++ if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { ++ data->driver_type = DRIVER_TYPE_QSFP; ++ return qsfp_probe(client, dev_id, &data->qsfp); ++ } ++ } ++ ++ return -ENODEV; ++} ++/* Platform dependent --- */ ++ ++static int sfp_msa_remove(struct i2c_client *client, struct sfp_msa_data *data) ++{ ++ sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); ++ sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); ++ kfree(data); ++ return 0; ++} ++ ++static int sfp_ddm_remove(struct i2c_client *client, struct sfp_ddm_data *data) ++{ ++ sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); ++ sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); ++ kfree(data); ++ return 0; ++} ++ ++static int qfp_remove(struct i2c_client *client, struct qsfp_data *data) ++{ ++ sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); ++ sysfs_remove_group(&client->dev.kobj, &qsfp_group); ++ kfree(data); ++ return 0; ++} ++ ++static int sfp_device_remove(struct i2c_client *client) ++{ ++ struct sfp_port_data *data = i2c_get_clientdata(client); ++ ++ switch (data->driver_type) { ++ case DRIVER_TYPE_SFP_MSA: ++ return sfp_msa_remove(client, data->msa); ++ case DRIVER_TYPE_SFP_DDM: ++ return sfp_ddm_remove(client, data->ddm); ++ case DRIVER_TYPE_QSFP: ++ return qfp_remove(client, data->qsfp); ++ } ++ ++ return 0; ++} ++ ++/* Addresses scanned ++ */ ++static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; ++ ++static struct i2c_driver sfp_driver = { ++ .driver = { ++ .name = DRIVER_NAME, ++ }, ++ .probe = sfp_device_probe, ++ .remove = sfp_device_remove, ++ .id_table = sfp_device_id, ++ .address_list = normal_i2c, ++}; ++ ++static int __init sfp_init(void) ++{ ++ return i2c_add_driver(&sfp_driver); ++} ++ ++static void __exit sfp_exit(void) ++{ ++ i2c_del_driver(&sfp_driver); ++} ++ ++MODULE_AUTHOR("Brandon Chuang "); ++MODULE_DESCRIPTION("accton as4610_sfp driver"); +MODULE_LICENSE("GPL"); ++ ++late_initcall(sfp_init); ++module_exit(sfp_exit); ++ diff --git a/include/linux/accton_i2c_cpld.h b/include/linux/accton_i2c_cpld.h new file mode 100644 index 0000000..9b75abd --- /dev/null -+++ b/include/linux/accton_as4610_cpld.h ++++ b/include/linux/accton_i2c_cpld.h @@ -0,0 +1,76 @@ +/* -+ * A hwmon driver for the accton as4610 cpld ++ * A hwmon driver for the accton_i2c_cpld + * + * Copyright (C) 2016 Accton Technology Corporation. + * Brandon Chuang @@ -3908,8 +3874,8 @@ index 0000000..9b75abd + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + -+extern int as4610_54_cpld_read(unsigned short cpld_addr, u8 reg); -+extern int as4610_54_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); ++extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); ++extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +#define AS4610_CPLD_SLAVE_ADDR 0x30 +#define AS4610_CPLD_PID_OFFSET 0x01 /* Product ID offset */ @@ -3926,7 +3892,7 @@ index 0000000..9b75abd + +static inline int as4610_product_id(void) +{ -+ int pid = as4610_54_cpld_read(AS4610_CPLD_SLAVE_ADDR, AS4610_CPLD_PID_OFFSET); ++ int pid = accton_i2c_cpld_read(AS4610_CPLD_SLAVE_ADDR, AS4610_CPLD_PID_OFFSET); + pid &= 0xF; + + if (pid < PID_AS4610_30T || pid > PID_AS4610_54T_B || pid == PID_RESERVED) { @@ -3963,3 +3929,4 @@ index 0000000..9b75abd + return nFan; +} + + diff --git a/packages/base/any/kernels/4.14-lts/configs/armel-iproc-all/.gitignore b/packages/base/any/kernels/4.14-lts/configs/armel-iproc-all/.gitignore new file mode 100644 index 00000000..285a565e --- /dev/null +++ b/packages/base/any/kernels/4.14-lts/configs/armel-iproc-all/.gitignore @@ -0,0 +1,2 @@ +linux-4.14* +kernel-4.14* diff --git a/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/Makefile b/packages/base/any/kernels/4.14-lts/configs/armel-iproc-all/Makefile similarity index 87% rename from packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/Makefile rename to packages/base/any/kernels/4.14-lts/configs/armel-iproc-all/Makefile index b3fcbd82..7c708593 100644 --- a/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/Makefile +++ b/packages/base/any/kernels/4.14-lts/configs/armel-iproc-all/Makefile @@ -1,4 +1,4 @@ -############################################################ +########################################################### # # # Copyright 2015 Big Switch Networks, Inc. @@ -29,13 +29,14 @@ endif K_PATCH_DIR := $(THIS_DIR)/patches include ../../kconfig.mk -K_CONFIG := arm-iproc-all.config +K_CONFIG := armel-iproc-all.config K_BUILD_TARGET := Image K_COPY_SRC := arch/arm/boot/Image K_COPY_GZIP := 1 ifndef K_COPY_DST -K_COPY_DST := kernel-4.4-lts-arm-iproc-all.bin.gz +K_COPY_DST := kernel-4.14-lts-armel-iproc-all.bin.gz endif export ARCH=arm + include $(ONL)/make/kbuild.mk diff --git a/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/arm-iproc-all.config b/packages/base/any/kernels/4.14-lts/configs/armel-iproc-all/armel-iproc-all.config similarity index 80% rename from packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/arm-iproc-all.config rename to packages/base/any/kernels/4.14-lts/configs/armel-iproc-all/armel-iproc-all.config index b1a38f03..5008a892 100644 --- a/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/arm-iproc-all.config +++ b/packages/base/any/kernels/4.14-lts/configs/armel-iproc-all/armel-iproc-all.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 4.4.39 Kernel Configuration +# Linux/arm 4.14.49 Kernel Configuration # CONFIG_ARM=y CONFIG_ARM_HAS_SG_CHAIN=y @@ -31,7 +31,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_CROSS_COMPILE="arm-linux-gnueabi-" # CONFIG_COMPILE_TEST is not set CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_LZMA=y CONFIG_HAVE_KERNEL_XZ=y @@ -48,7 +48,7 @@ CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set CONFIG_CROSS_MEMORY_ATTACH=y -# CONFIG_FHANDLE is not set +CONFIG_FHANDLE=y CONFIG_USELIB=y # CONFIG_AUDIT is not set CONFIG_HAVE_ARCH_AUDITSYSCALL=y @@ -59,14 +59,18 @@ CONFIG_HAVE_ARCH_AUDITSYSCALL=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_IRQ_SHOW=y CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_DOMAIN_HIERARCHY=y CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y CONFIG_HANDLE_DOMAIN_IRQ=y -# CONFIG_IRQ_DOMAIN_DEBUG is not set +CONFIG_IRQ_DOMAIN_DEBUG=y CONFIG_IRQ_FORCED_THREADING=y CONFIG_SPARSE_IRQ=y +# CONFIG_GENERIC_IRQ_DEBUGFS is not set +CONFIG_ARCH_CLOCKSOURCE_DATA=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_ARCH_HAS_TICK_BROADCAST=y CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y @@ -97,15 +101,16 @@ CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_PREEMPT_RCU=y # CONFIG_RCU_EXPERT is not set CONFIG_SRCU=y -# CONFIG_TASKS_RCU is not set +CONFIG_TREE_SRCU=y +CONFIG_TASKS_RCU=y CONFIG_RCU_STALL_COMMON=y -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_RCU_EXPEDITE_BOOT is not set +CONFIG_RCU_NEED_SEGCBLIST=y CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 +CONFIG_LOG_BUF_SHIFT=17 CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 CONFIG_GENERIC_SCHED_CLOCK=y # CONFIG_CGROUPS is not set # CONFIG_CHECKPOINT_RESTORE is not set @@ -113,9 +118,18 @@ CONFIG_GENERIC_SCHED_CLOCK=y # CONFIG_SCHED_AUTOGROUP is not set # CONFIG_SYSFS_DEPRECATED is not set # CONFIG_RELAY is not set -# CONFIG_BLK_DEV_INITRD is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_RD_XZ=y +CONFIG_RD_LZO=y +CONFIG_RD_LZ4=y +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_HAVE_UID16=y CONFIG_BPF=y CONFIG_EXPERT=y @@ -124,20 +138,25 @@ CONFIG_MULTIUSER=y # CONFIG_SGETMASK_SYSCALL is not set CONFIG_SYSFS_SYSCALL=y CONFIG_SYSCTL_SYSCALL=y +CONFIG_POSIX_TIMERS=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set +CONFIG_KALLSYMS_BASE_RELATIVE=y CONFIG_PRINTK=y +CONFIG_PRINTK_NMI=y CONFIG_BUG=y -# CONFIG_ELF_CORE is not set -# CONFIG_BASE_FULL is not set +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y -# CONFIG_EPOLL is not set -# CONFIG_SIGNALFD is not set -# CONFIG_TIMERFD is not set -# CONFIG_EVENTFD is not set +CONFIG_FUTEX_PI=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y # CONFIG_BPF_SYSCALL is not set # CONFIG_SHMEM is not set -# CONFIG_AIO is not set +CONFIG_AIO=y CONFIG_ADVISE_SYSCALLS=y # CONFIG_USERFAULTFD is not set CONFIG_PCI_QUIRKS=y @@ -145,6 +164,7 @@ CONFIG_MEMBARRIER=y CONFIG_EMBEDDED=y CONFIG_HAVE_PERF_EVENTS=y CONFIG_PERF_USE_VMALLOC=y +# CONFIG_PC104 is not set # # Kernel Performance Events And Counters @@ -156,6 +176,9 @@ CONFIG_VM_EVENT_COUNTERS=y # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set +CONFIG_SLAB_MERGE_DEFAULT=y +# CONFIG_SLAB_FREELIST_RANDOM is not set +# CONFIG_SLAB_FREELIST_HARDENED is not set CONFIG_SLUB_CPU_PARTIAL=y # CONFIG_SYSTEM_DATA_VERIFICATION is not set # CONFIG_PROFILING is not set @@ -169,11 +192,12 @@ CONFIG_ARCH_USE_BUILTIN_BSWAP=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_NMI=y CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_DMA_CONTIGUOUS=y CONFIG_GENERIC_SMP_IDLE_THREAD=y CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_ARCH_HAS_SET_MEMORY=y CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -182,20 +206,39 @@ CONFIG_HAVE_PERF_USER_STACK_DUMP=y CONFIG_HAVE_ARCH_JUMP_LABEL=y CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_HAVE_GCC_PLUGINS=y +# CONFIG_GCC_PLUGINS is not set CONFIG_HAVE_CC_STACKPROTECTOR=y # CONFIG_CC_STACKPROTECTOR is not set CONFIG_CC_STACKPROTECTOR_NONE=y # CONFIG_CC_STACKPROTECTOR_REGULAR is not set # CONFIG_CC_STACKPROTECTOR_STRONG is not set +CONFIG_THIN_ARCHIVES=y CONFIG_HAVE_CONTEXT_TRACKING=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y CONFIG_HAVE_MOD_ARCH_SPECIFIC=y CONFIG_MODULES_USE_ELF_REL=y CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_HAVE_EXIT_THREAD=y +CONFIG_ARCH_MMAP_RND_BITS_MIN=8 +CONFIG_ARCH_MMAP_RND_BITS_MAX=16 +CONFIG_ARCH_MMAP_RND_BITS=8 +# CONFIG_HAVE_ARCH_HASH is not set +# CONFIG_ISA_BUS_API is not set CONFIG_CLONE_BACKWARDS=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_OLD_SIGACTION=y +# CONFIG_CPU_NO_EFFICIENT_FFS is not set +# CONFIG_HAVE_ARCH_VMAP_STACK is not set +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_STRICT_MODULE_RWX=y +# CONFIG_REFCOUNT_FULL is not set # # GCOV-based kernel profiling @@ -204,7 +247,7 @@ CONFIG_OLD_SIGACTION=y CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=1 +CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y @@ -213,12 +256,18 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set # CONFIG_MODULE_SIG is not set # CONFIG_MODULE_COMPRESS is not set +# CONFIG_TRIM_UNUSED_KSYMS is not set CONFIG_BLOCK=y CONFIG_LBDAF=y +CONFIG_BLK_SCSI_REQUEST=y CONFIG_BLK_DEV_BSG=y # CONFIG_BLK_DEV_BSGLIB is not set # CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_ZONED is not set # CONFIG_BLK_CMDLINE_PARSER is not set +# CONFIG_BLK_WBT is not set +CONFIG_BLK_DEBUG_FS=y +# CONFIG_BLK_SED_OPAL is not set # # Partition Types @@ -243,6 +292,7 @@ CONFIG_MSDOS_PARTITION=y CONFIG_EFI_PARTITION=y # CONFIG_SYSV68_PARTITION is not set # CONFIG_CMDLINE_PARTITION is not set +CONFIG_BLK_MQ_PCI=y # # IO Schedulers @@ -254,6 +304,9 @@ CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_MQ_IOSCHED_DEADLINE=y +CONFIG_MQ_IOSCHED_KYBER=y +# CONFIG_IOSCHED_BFQ is not set CONFIG_UNINLINE_SPIN_UNLOCK=y CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y CONFIG_MUTEX_SPIN_ON_OWNER=y @@ -266,10 +319,6 @@ CONFIG_FREEZER=y # CONFIG_MMU=y CONFIG_ARCH_MULTIPLATFORM=y -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_GEMINI is not set # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set @@ -279,9 +328,6 @@ CONFIG_ARCH_MULTIPLATFORM=y # CONFIG_ARCH_IOP33X is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_DOVE is not set -# CONFIG_ARCH_MV78XX0 is not set -# CONFIG_ARCH_ORION5X is not set -# CONFIG_ARCH_MMP is not set # CONFIG_ARCH_KS8695 is not set # CONFIG_ARCH_W90X900 is not set # CONFIG_ARCH_LPC32XX is not set @@ -289,7 +335,6 @@ CONFIG_ARCH_MULTIPLATFORM=y # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set # CONFIG_ARCH_S3C24XX is not set -# CONFIG_ARCH_S3C64XX is not set # CONFIG_ARCH_DAVINCI is not set # CONFIG_ARCH_OMAP1 is not set @@ -306,7 +351,9 @@ CONFIG_ARCH_MULTI_V6_V7=y # CONFIG_ARCH_MULTI_CPU_AUTO is not set # CONFIG_ARCH_VIRT is not set # CONFIG_ARCH_MVEBU is not set +# CONFIG_ARCH_ACTIONS is not set # CONFIG_ARCH_ALPINE is not set +# CONFIG_ARCH_ARTPEC is not set # CONFIG_ARCH_AT91 is not set # CONFIG_ARCH_BCM is not set # CONFIG_ARCH_BERLIN is not set @@ -318,13 +365,15 @@ CONFIG_ARCH_XGS_IPROC=y # # XGS iProc SoC based Machine types # -CONFIG_MACH_HX4=y +CONFIG_XGS_IPROC_ARM32_PLATFORM=y +# CONFIG_MACH_HX4 is not set # CONFIG_MACH_HR2 is not set # CONFIG_MACH_KT2 is not set # CONFIG_MACH_GH is not set # CONFIG_MACH_SB2 is not set # CONFIG_MACH_HR3 is not set # CONFIG_MACH_GH2 is not set +# CONFIG_MACH_WH2 is not set # CONFIG_MACH_IPROC_EMULATION is not set # CONFIG_ARCH_KEYSTONE is not set # CONFIG_ARCH_MESON is not set @@ -340,16 +389,19 @@ CONFIG_MACH_HX4=y # CONFIG_SOC_AM33XX is not set # CONFIG_SOC_AM43XX is not set # CONFIG_SOC_DRA7XX is not set +# CONFIG_ARCH_MMP is not set # CONFIG_ARCH_QCOM is not set +# CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_ROCKCHIP is not set # CONFIG_ARCH_SOCFPGA is not set # CONFIG_PLAT_SPEAR is not set # CONFIG_ARCH_STI is not set # CONFIG_ARCH_S5PV210 is not set # CONFIG_ARCH_EXYNOS is not set -# CONFIG_ARCH_SHMOBILE_MULTI is not set +# CONFIG_ARCH_RENESAS is not set # CONFIG_ARCH_SUNXI is not set # CONFIG_ARCH_SIRF is not set +# CONFIG_ARCH_TANGO is not set # CONFIG_ARCH_TEGRA is not set # CONFIG_ARCH_UNIPHIER is not set # CONFIG_ARCH_U8500 is not set @@ -362,6 +414,7 @@ CONFIG_MACH_HX4=y # Processor Type # CONFIG_CPU_V7=y +CONFIG_CPU_THUMB_CAPABLE=y CONFIG_CPU_32v6K=y CONFIG_CPU_32v7=y CONFIG_CPU_ABRT_EV7=y @@ -401,7 +454,7 @@ CONFIG_ARM_L1_CACHE_SHIFT=6 CONFIG_ARM_DMA_MEM_BUFFERABLE=y CONFIG_ARM_HEAVY_MB=y CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y -# CONFIG_ARM_KERNMEM_PERMS is not set +CONFIG_DEBUG_ALIGN_RODATA=y CONFIG_MULTI_IRQ_HANDLER=y # CONFIG_ARM_ERRATA_430973 is not set # CONFIG_ARM_ERRATA_643719 is not set @@ -412,6 +465,11 @@ CONFIG_ARM_ERRATA_764369=y CONFIG_ARM_ERRATA_775420=y # CONFIG_ARM_ERRATA_798181 is not set # CONFIG_ARM_ERRATA_773022 is not set +# CONFIG_ARM_ERRATA_818325_852422 is not set +# CONFIG_ARM_ERRATA_821420 is not set +# CONFIG_ARM_ERRATA_825619 is not set +# CONFIG_ARM_ERRATA_852421 is not set +# CONFIG_ARM_ERRATA_852423 is not set # # Bus support @@ -420,23 +478,41 @@ CONFIG_PCI=y CONFIG_PCI_DOMAINS=y CONFIG_PCI_DOMAINS_GENERIC=y CONFIG_PCI_SYSCALL=y +# CONFIG_PCIEPORTBUS is not set CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y # CONFIG_PCI_DEBUG is not set # CONFIG_PCI_REALLOC_ENABLE_AUTO is not set # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set # CONFIG_PCI_PRI is not set # CONFIG_PCI_PASID is not set +# CONFIG_HOTPLUG_PCI is not set + +# +# DesignWare PCI Core Support +# +# CONFIG_PCIE_DW_PLAT is not set +# CONFIG_PCI_LAYERSCAPE is not set # # PCI host controller drivers # +# CONFIG_PCI_FTPCI100 is not set # CONFIG_PCI_HOST_GENERIC is not set -# CONFIG_PCI_LAYERSCAPE is not set CONFIG_PCIE_XGS_IPROC=y -# CONFIG_PCIE_IPROC is not set +CONFIG_PCIE_IPROC_MSI=y # CONFIG_PCIE_ALTERA is not set -# CONFIG_PCIEPORTBUS is not set + +# +# PCI Endpoint +# +# CONFIG_PCI_ENDPOINT is not set + +# +# PCI switch controller drivers +# +# CONFIG_PCI_SW_SWITCHTEC is not set # CONFIG_PCCARD is not set # @@ -476,6 +552,7 @@ CONFIG_HZ_100=y CONFIG_HZ=100 # CONFIG_SCHED_HRTICK is not set # CONFIG_THUMB2_KERNEL is not set +CONFIG_ARM_PATCH_IDIV=y CONFIG_AEABI=y # CONFIG_OABI_COMPAT is not set # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set @@ -484,7 +561,7 @@ CONFIG_HAVE_ARCH_PFN_VALID=y # CONFIG_HIGHMEM is not set CONFIG_CPU_SW_DOMAIN_PAN=y CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -# CONFIG_ARM_MODULE_PLTS is not set +CONFIG_ARM_MODULE_PLTS=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_HAVE_MEMBLOCK=y @@ -492,12 +569,12 @@ CONFIG_NO_BOOTMEM=y CONFIG_MEMORY_ISOLATION=y # CONFIG_HAVE_BOOTMEM_INFO_NODE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_COMPACTION is not set +CONFIG_COMPACTION=y CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_ARCH_WANTS_THP_SWAP is not set # CONFIG_CLEANCACHE is not set # CONFIG_FRONTSWAP is not set CONFIG_CMA=y @@ -507,13 +584,17 @@ CONFIG_CMA_AREAS=7 # CONFIG_ZPOOL is not set # CONFIG_ZBUD is not set # CONFIG_ZSMALLOC is not set +CONFIG_GENERIC_EARLY_IOREMAP=y # CONFIG_IDLE_PAGE_TRACKING is not set +# CONFIG_PERCPU_STATS is not set CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_ALIGNMENT_TRAP=y # CONFIG_UACCESS_WITH_MEMCPY is not set # CONFIG_SECCOMP is not set CONFIG_SWIOTLB=y CONFIG_IOMMU_HELPER=y +# CONFIG_PARAVIRT is not set +# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set # CONFIG_XEN is not set # @@ -525,13 +606,14 @@ CONFIG_ATAGS=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 # CONFIG_ARM_APPENDED_DTB is not set -CONFIG_CMDLINE="console=ttyS0,115200n8 maxcpus=2 mem=496M" +CONFIG_CMDLINE="console=ttyS0,115200n8 maxcpus=1 mem=240M" CONFIG_CMDLINE_FROM_BOOTLOADER=y # CONFIG_CMDLINE_EXTEND is not set # CONFIG_CMDLINE_FORCE is not set # CONFIG_KEXEC is not set # CONFIG_CRASH_DUMP is not set CONFIG_AUTO_ZRELADDR=y +# CONFIG_EFI is not set # # CPU Power Management @@ -561,7 +643,10 @@ CONFIG_AUTO_ZRELADDR=y # Userspace binary formats # CONFIG_BINFMT_ELF=y +CONFIG_ELFCORE=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y CONFIG_BINFMT_SCRIPT=y +# CONFIG_BINFMT_FLAT is not set # CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set CONFIG_COREDUMP=y @@ -596,11 +681,8 @@ CONFIG_PACKET=y # CONFIG_PACKET_DIAG is not set CONFIG_UNIX=y # CONFIG_UNIX_DIAG is not set -CONFIG_XFRM=y +# CONFIG_TLS is not set # CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -629,7 +711,6 @@ CONFIG_INET_TUNNEL=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y @@ -645,23 +726,24 @@ CONFIG_IPV6=y # CONFIG_IPV6_ILA is not set # CONFIG_INET6_XFRM_TUNNEL is not set CONFIG_INET6_TUNNEL=y -CONFIG_INET6_XFRM_MODE_TRANSPORT=y -CONFIG_INET6_XFRM_MODE_TUNNEL=y -CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -# CONFIG_IPV6_VTI is not set CONFIG_IPV6_SIT=y # CONFIG_IPV6_SIT_6RD is not set CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=y -# CONFIG_IPV6_GRE is not set +# CONFIG_IPV6_FOU is not set +# CONFIG_IPV6_FOU_TUNNEL is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_IPV6_MROUTE is not set +# CONFIG_IPV6_SEG6_LWTUNNEL is not set +# CONFIG_IPV6_SEG6_HMAC is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NET_PTP_CLASSIFY=y # CONFIG_NETWORK_PHY_TIMESTAMPING is not set CONFIG_NETFILTER=y -CONFIG_NETFILTER_DEBUG=y CONFIG_NETFILTER_ADVANCED=y CONFIG_BRIDGE_NETFILTER=y @@ -674,6 +756,7 @@ CONFIG_NETFILTER_NETLINK=y CONFIG_NETFILTER_NETLINK_QUEUE=y CONFIG_NETFILTER_NETLINK_LOG=y CONFIG_NF_CONNTRACK=y +# CONFIG_NF_LOG_NETDEV is not set CONFIG_NF_CONNTRACK_MARK=y # CONFIG_NF_CONNTRACK_ZONES is not set CONFIG_NF_CONNTRACK_PROCFS=y @@ -759,7 +842,6 @@ CONFIG_NETFILTER_XT_MATCH_HL=y # CONFIG_NETFILTER_XT_MATCH_NFACCT is not set # CONFIG_NETFILTER_XT_MATCH_OSF is not set # CONFIG_NETFILTER_XT_MATCH_OWNER is not set -# CONFIG_NETFILTER_XT_MATCH_POLICY is not set # CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set # CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set # CONFIG_NETFILTER_XT_MATCH_QUOTA is not set @@ -767,7 +849,6 @@ CONFIG_NETFILTER_XT_MATCH_HL=y # CONFIG_NETFILTER_XT_MATCH_REALM is not set # CONFIG_NETFILTER_XT_MATCH_RECENT is not set # CONFIG_NETFILTER_XT_MATCH_SCTP is not set -# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set CONFIG_NETFILTER_XT_MATCH_STATE=y # CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set # CONFIG_NETFILTER_XT_MATCH_STRING is not set @@ -782,7 +863,7 @@ CONFIG_NETFILTER_XT_MATCH_TCPMSS=y # CONFIG_NF_DEFRAG_IPV4=y CONFIG_NF_CONNTRACK_IPV4=y -CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_SOCKET_IPV4 is not set # CONFIG_NF_DUP_IPV4 is not set # CONFIG_NF_LOG_ARP is not set # CONFIG_NF_LOG_IPV4 is not set @@ -811,6 +892,7 @@ CONFIG_IP_NF_ARP_MANGLE=y # CONFIG_NF_DEFRAG_IPV6=y CONFIG_NF_CONNTRACK_IPV6=y +# CONFIG_NF_SOCKET_IPV6 is not set # CONFIG_NF_DUP_IPV6 is not set CONFIG_NF_REJECT_IPV6=y # CONFIG_NF_LOG_IPV6 is not set @@ -845,6 +927,7 @@ CONFIG_BRIDGE=y CONFIG_BRIDGE_IGMP_SNOOPING=y # CONFIG_BRIDGE_VLAN_FILTERING is not set CONFIG_HAVE_NET_DSA=y +# CONFIG_NET_DSA is not set CONFIG_VLAN_8021Q=y CONFIG_VLAN_8021Q_GVRP=y # CONFIG_VLAN_8021Q_MVRP is not set @@ -864,12 +947,13 @@ CONFIG_DNS_RESOLVER=y # CONFIG_BATMAN_ADV is not set # CONFIG_OPENVSWITCH is not set # CONFIG_VSOCKETS is not set -# CONFIG_NETLINK_MMAP is not set # CONFIG_NETLINK_DIAG is not set # CONFIG_MPLS is not set +# CONFIG_NET_NSH is not set # CONFIG_HSR is not set # CONFIG_NET_SWITCHDEV is not set # CONFIG_NET_L3_MASTER_DEV is not set +# CONFIG_NET_NCSI is not set CONFIG_RPS=y CONFIG_RFS_ACCEL=y CONFIG_XPS=y @@ -884,9 +968,10 @@ CONFIG_NET_FLOW_LIMIT=y # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set -# CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set +# CONFIG_AF_KCM is not set +# CONFIG_STREAM_PARSER is not set CONFIG_FIB_RULES=y # CONFIG_WIRELESS is not set # CONFIG_WIMAX is not set @@ -895,14 +980,19 @@ CONFIG_FIB_RULES=y # CONFIG_CAIF is not set # CONFIG_CEPH_LIB is not set # CONFIG_NFC is not set +# CONFIG_PSAMPLE is not set +# CONFIG_NET_IFE is not set # CONFIG_LWTUNNEL is not set -CONFIG_HAVE_BPF_JIT=y +CONFIG_DST_CACHE=y +CONFIG_GRO_CELLS=y +# CONFIG_NET_DEVLINK is not set +CONFIG_MAY_USE_DEVLINK=y +CONFIG_HAVE_EBPF_JIT=y # # Device Drivers # CONFIG_ARM_AMBA=y -# CONFIG_TEGRA_AHB is not set # # Generic Driver Options @@ -920,8 +1010,14 @@ CONFIG_EXTRA_FIRMWARE="" CONFIG_ALLOW_DEV_COREDUMP=y # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set +# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set # CONFIG_SYS_HYPERVISOR is not set # CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y # CONFIG_DMA_SHARED_BUFFER is not set CONFIG_DMA_CMA=y @@ -934,11 +1030,13 @@ CONFIG_CMA_SIZE_SEL_MBYTES=y # CONFIG_CMA_SIZE_SEL_MIN is not set # CONFIG_CMA_SIZE_SEL_MAX is not set CONFIG_CMA_ALIGNMENT=8 +CONFIG_GENERIC_ARCH_TOPOLOGY=y # # Bus devices # # CONFIG_BRCMSTB_GISB_ARB is not set +# CONFIG_SIMPLE_PM_BUS is not set # CONFIG_VEXPRESS_CONFIG is not set # CONFIG_CONNECTOR is not set CONFIG_MTD=y @@ -949,6 +1047,10 @@ CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_OF_PARTS=y # CONFIG_MTD_AR7_PARTS is not set +# +# Partition parsers +# + # # User Modules And Translation Layers # @@ -993,19 +1095,21 @@ CONFIG_MTD_CFI_UTIL=y # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_PHYSMAP_OF is not set -# CONFIG_MTD_NOR_XGS_IPROC is not set +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +CONFIG_MTD_PHYSMAP_OF=y # CONFIG_MTD_IMPA7 is not set # CONFIG_MTD_INTEL_VR_NOR is not set # CONFIG_MTD_PLATRAM is not set +CONFIG_MTD_NOR_XGS_IPROC=y # # Self-contained MTD device drivers # # CONFIG_MTD_PMC551 is not set # CONFIG_MTD_DATAFLASH is not set -CONFIG_MTD_M25P80_IPROC=y +CONFIG_MTD_M25P80=y +# CONFIG_MTD_MCHP23K256 is not set # CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set @@ -1025,16 +1129,13 @@ CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_DENALI_DT is not set # CONFIG_MTD_NAND_GPIO is not set # CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set -CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_RICOH is not set # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_DOCG4 is not set # CONFIG_MTD_NAND_CAFE is not set # CONFIG_MTD_NAND_NANDSIM is not set CONFIG_MTD_NAND_BRCMNAND=y -CONFIG_MTD_NAND_XGS_IPROC=y # CONFIG_MTD_NAND_PLATFORM is not set -# CONFIG_MTD_NAND_HISI504 is not set # CONFIG_MTD_ONENAND is not set # @@ -1042,10 +1143,10 @@ CONFIG_MTD_NAND_XGS_IPROC=y # # CONFIG_MTD_LPDDR is not set # CONFIG_MTD_LPDDR2_NVM is not set -# CONFIG_MTD_SPI_NOR is not set +CONFIG_MTD_SPI_NOR=y +# CONFIG_MTD_MT81xx_NOR is not set # CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -CONFIG_MTD_SPI_NOR_IPROC=y -CONFIG_M25PXX_STAY_IN_3BYTE_MODE=y +# CONFIG_SPI_CADENCE_QUADSPI is not set CONFIG_MTD_UBI=y CONFIG_MTD_UBI_WL_THRESHOLD=4096 CONFIG_MTD_UBI_BEB_LIMIT=20 @@ -1057,6 +1158,7 @@ CONFIG_OF=y # CONFIG_OF_UNITTEST is not set CONFIG_OF_FLATTREE=y CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_DYNAMIC=y CONFIG_OF_ADDRESS=y CONFIG_OF_ADDRESS_PCI=y CONFIG_OF_IRQ=y @@ -1064,31 +1166,33 @@ CONFIG_OF_NET=y CONFIG_OF_MDIO=y CONFIG_OF_PCI=y CONFIG_OF_PCI_IRQ=y -CONFIG_OF_MTD=y CONFIG_OF_RESERVED_MEM=y -# CONFIG_OF_OVERLAY is not set +CONFIG_OF_RESOLVE=y +CONFIG_OF_OVERLAY=y CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_NULL_BLK is not set # CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set -# CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +CONFIG_BLK_DEV_CRYPTOLOOP=y # CONFIG_BLK_DEV_DRBD is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_SIZE=32768 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -# CONFIG_MG_DISK is not set # CONFIG_BLK_DEV_RBD is not set # CONFIG_BLK_DEV_RSXX is not set # CONFIG_BLK_DEV_NVME is not set +# CONFIG_NVME_FC is not set +# CONFIG_NVME_TARGET is not set # # Misc devices @@ -1105,17 +1209,15 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ISL29003 is not set # CONFIG_ISL29020 is not set # CONFIG_SENSORS_TSL2550 is not set -# CONFIG_SENSORS_BH1780 is not set # CONFIG_SENSORS_BH1770 is not set # CONFIG_SENSORS_APDS990X is not set # CONFIG_HMC6352 is not set # CONFIG_DS1682 is not set # CONFIG_TI_DAC7512 is not set -# CONFIG_BMP085_I2C is not set -# CONFIG_BMP085_SPI is not set # CONFIG_USB_SWITCH_FSA9480 is not set # CONFIG_LATTICE_ECP3_CONFIG is not set # CONFIG_SRAM is not set +# CONFIG_PCI_ENDPOINT_TEST is not set # CONFIG_C2PORT is not set # @@ -1127,6 +1229,7 @@ CONFIG_EEPROM_AT24=y # CONFIG_EEPROM_MAX6875 is not set # CONFIG_EEPROM_93CX6 is not set # CONFIG_EEPROM_93XX46 is not set +# CONFIG_EEPROM_IDT_89HPESX is not set # CONFIG_CB710_CORE is not set # @@ -1147,6 +1250,10 @@ CONFIG_EEPROM_AT24=y # SCIF Bus Driver # +# +# VOP Bus Driver +# + # # Intel MIC Host Driver # @@ -1162,10 +1269,14 @@ CONFIG_EEPROM_AT24=y # # Intel MIC Coprocessor State Management (COSM) Drivers # + +# +# VOP Driver +# # CONFIG_ECHO is not set # CONFIG_CXL_BASE is not set -# CONFIG_CXL_KERNEL_API is not set -# CONFIG_CXL_EEH is not set +# CONFIG_CXL_AFU_DRIVER_OPS is not set +# CONFIG_CXL_LIB is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -1228,6 +1339,7 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_MEGARAID_SAS is not set # CONFIG_SCSI_MPT3SAS is not set # CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_SMARTPQI is not set # CONFIG_SCSI_UFSHCD is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_SNIC is not set @@ -1267,8 +1379,8 @@ CONFIG_BONDING=y # CONFIG_NET_FC is not set # CONFIG_NET_TEAM is not set # CONFIG_MACVLAN is not set -# CONFIG_IPVLAN is not set # CONFIG_VXLAN is not set +# CONFIG_MACSEC is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -1285,8 +1397,6 @@ CONFIG_BONDING=y # # Distributed Switch Architecture drivers # -# CONFIG_NET_DSA_MV88E6XXX is not set -# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set CONFIG_ETHERNET=y CONFIG_NET_VENDOR_3COM=y # CONFIG_VORTEX is not set @@ -1295,14 +1405,18 @@ CONFIG_NET_VENDOR_ADAPTEC=y # CONFIG_ADAPTEC_STARFIRE is not set CONFIG_NET_VENDOR_AGERE=y # CONFIG_ET131X is not set +CONFIG_NET_VENDOR_ALACRITECH=y +# CONFIG_SLICOSS is not set CONFIG_NET_VENDOR_ALTEON=y # CONFIG_ACENIC is not set # CONFIG_ALTERA_TSE is not set +CONFIG_NET_VENDOR_AMAZON=y CONFIG_NET_VENDOR_AMD=y # CONFIG_AMD8111_ETH is not set # CONFIG_PCNET32 is not set +# CONFIG_AMD_XGBE_HAVE_ECC is not set +CONFIG_NET_VENDOR_AQUANTIA=y CONFIG_NET_VENDOR_ARC=y -# CONFIG_ARC_EMAC is not set CONFIG_NET_VENDOR_ATHEROS=y # CONFIG_ATL2 is not set # CONFIG_ATL1 is not set @@ -1318,27 +1432,13 @@ CONFIG_NET_VENDOR_BROADCOM=y # CONFIG_BNX2 is not set # CONFIG_CNIC is not set CONFIG_TIGON3=y +CONFIG_TIGON3_HWMON=y # CONFIG_BNX2X is not set +CONFIG_BGMAC=y +CONFIG_BGMAC_PLATFORM=y +# CONFIG_APM is not set # CONFIG_SYSTEMPORT is not set # CONFIG_BNXT is not set -CONFIG_GMAC_XGS_IPROC=y - -# -# Broadcom HND network devices -# -CONFIG_HND=y -CONFIG_ET=y -# CONFIG_ET_NAPI2_POLL is not set -# CONFIG_BCM_IPROC_GMAC_ACP is not set -# CONFIG_BCM_IPROC_GMAC_PREFETCH is not set -# CONFIG_BCM_IPROC_GMAC_LOCK_OPT is not set -# CONFIG_BCM_IPROC_GMAC_RWREG_OPT is not set -# CONFIG_BCM_IPROC_GMAC_SG is not set -CONFIG_IPROC_SDK_MGT_PORT_HANDOFF=y -# CONFIG_IPROC_2STAGE_RX is not set -# CONFIG_SERDES_ASYMMETRIC_MODE is not set -# CONFIG_JUMBO_FRAME is not set -CONFIG_MDIO_XGS_IPROC=y CONFIG_NET_VENDOR_BROCADE=y # CONFIG_BNA is not set CONFIG_NET_VENDOR_CAVIUM=y @@ -1370,12 +1470,15 @@ CONFIG_NET_VENDOR_FARADAY=y # CONFIG_FTGMAC100 is not set CONFIG_NET_VENDOR_HISILICON=y # CONFIG_HIX5HD2_GMAC is not set +# CONFIG_HISI_FEMAC is not set # CONFIG_HIP04_ETH is not set # CONFIG_HNS is not set # CONFIG_HNS_DSAF is not set # CONFIG_HNS_ENET is not set +# CONFIG_HNS3 is not set CONFIG_NET_VENDOR_HP=y # CONFIG_HP100 is not set +CONFIG_NET_VENDOR_HUAWEI=y CONFIG_NET_VENDOR_INTEL=y # CONFIG_E100 is not set # CONFIG_E1000 is not set @@ -1392,6 +1495,7 @@ CONFIG_NET_VENDOR_I825XX=y # CONFIG_JME is not set CONFIG_NET_VENDOR_MARVELL=y # CONFIG_MVMDIO is not set +# CONFIG_MVNETA_BM is not set # CONFIG_SKGE is not set # CONFIG_SKY2 is not set CONFIG_NET_VENDOR_MELLANOX=y @@ -1399,6 +1503,7 @@ CONFIG_NET_VENDOR_MELLANOX=y # CONFIG_MLX4_CORE is not set # CONFIG_MLX5_CORE is not set # CONFIG_MLXSW_CORE is not set +# CONFIG_MLXFW is not set CONFIG_NET_VENDOR_MICREL=y # CONFIG_KS8842 is not set # CONFIG_KS8851 is not set @@ -1413,6 +1518,8 @@ CONFIG_NET_VENDOR_MYRI=y CONFIG_NET_VENDOR_NATSEMI=y # CONFIG_NATSEMI is not set # CONFIG_NS83820 is not set +CONFIG_NET_VENDOR_NETRONOME=y +# CONFIG_NFP is not set CONFIG_NET_VENDOR_8390=y # CONFIG_AX88796 is not set # CONFIG_NE2K_PCI is not set @@ -1430,7 +1537,9 @@ CONFIG_NET_VENDOR_QLOGIC=y # CONFIG_NETXEN_NIC is not set # CONFIG_QED is not set CONFIG_NET_VENDOR_QUALCOMM=y -# CONFIG_QCA7000 is not set +# CONFIG_QCA7000_SPI is not set +# CONFIG_QCOM_EMAC is not set +# CONFIG_RMNET is not set CONFIG_NET_VENDOR_REALTEK=y # CONFIG_8139CP is not set # CONFIG_8139TOO is not set @@ -1447,7 +1556,9 @@ CONFIG_NET_VENDOR_SILAN=y CONFIG_NET_VENDOR_SIS=y # CONFIG_SIS900 is not set # CONFIG_SIS190 is not set +CONFIG_NET_VENDOR_SOLARFLARE=y # CONFIG_SFC is not set +# CONFIG_SFC_FALCON is not set CONFIG_NET_VENDOR_SMSC=y # CONFIG_SMC91X is not set # CONFIG_EPIC100 is not set @@ -1461,8 +1572,6 @@ CONFIG_NET_VENDOR_SUN=y # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set # CONFIG_NIU is not set -CONFIG_NET_VENDOR_SYNOPSYS=y -# CONFIG_SYNOPSYS_DWC_ETH_QOS is not set CONFIG_NET_VENDOR_TEHUTI=y # CONFIG_TEHUTI is not set CONFIG_NET_VENDOR_TI=y @@ -1474,41 +1583,56 @@ CONFIG_NET_VENDOR_VIA=y CONFIG_NET_VENDOR_WIZNET=y # CONFIG_WIZNET_W5100 is not set # CONFIG_WIZNET_W5300 is not set +CONFIG_NET_VENDOR_SYNOPSYS=y +# CONFIG_DWC_XLGMAC is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_BUS=y +# CONFIG_MDIO_BCM_UNIMAC is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set +# CONFIG_MDIO_HISI_FEMAC is not set CONFIG_PHYLIB=y +CONFIG_SWPHY=y +CONFIG_MDIO_XGS_IPROC=y # # MII PHY device drivers # +# CONFIG_AMD_PHY is not set # CONFIG_AQUANTIA_PHY is not set # CONFIG_AT803X_PHY is not set -# CONFIG_AMD_PHY is not set -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_TERANETICS_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set # CONFIG_BCM7XXX_PHY is not set # CONFIG_BCM87XX_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_NATIONAL_PHY is not set -# CONFIG_STE10XP is not set -# CONFIG_LSI_ET1011C_PHY is not set -# CONFIG_MICREL_PHY is not set +CONFIG_BCM_NET_PHYLIB=y +CONFIG_BROADCOM_PHY=y +CONFIG_XGS_IPROC_SERDES=y +# CONFIG_CICADA_PHY is not set +# CONFIG_CORTINA_PHY is not set +# CONFIG_DAVICOM_PHY is not set # CONFIG_DP83848_PHY is not set # CONFIG_DP83867_PHY is not set +CONFIG_FIXED_PHY=y +# CONFIG_ICPLUS_PHY is not set +# CONFIG_INTEL_XWAY_PHY is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_MARVELL_10G_PHY is not set +# CONFIG_MICREL_PHY is not set # CONFIG_MICROCHIP_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -# CONFIG_MDIO_BUS_MUX_GPIO is not set -# CONFIG_MDIO_BUS_MUX_MMIOREG is not set -# CONFIG_MDIO_BCM_UNIMAC is not set +# CONFIG_MICROSEMI_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_ROCKCHIP_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_TERANETICS_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_XILINX_GMII2RGMII is not set # CONFIG_MICREL_KS8995MA is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -1549,6 +1673,7 @@ CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_PS2MULT is not set # CONFIG_SERIO_ARC_PS2 is not set # CONFIG_SERIO_APBPS2 is not set +# CONFIG_SERIO_GPIO_PS2 is not set # CONFIG_USERIO is not set # CONFIG_GAMEPORT is not set @@ -1558,7 +1683,6 @@ CONFIG_SERIO_LIBPS2=y CONFIG_TTY=y # CONFIG_VT is not set CONFIG_UNIX98_PTYS=y -CONFIG_DEVPTS_MULTIPLE_INSTANCES=y # CONFIG_LEGACY_PTYS is not set # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_NOZOMI is not set @@ -1573,13 +1697,16 @@ CONFIG_DEVKMEM=y CONFIG_SERIAL_EARLYCON=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +# CONFIG_SERIAL_8250_FINTEK is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_DMA=y CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_EXAR=y CONFIG_SERIAL_8250_NR_UARTS=2 CONFIG_SERIAL_8250_RUNTIME_UARTS=2 CONFIG_SERIAL_8250_EXTENDED=y # CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_ASPEED_VUART is not set CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_DETECT_IRQ=y CONFIG_SERIAL_8250_RSA=y @@ -1587,8 +1714,8 @@ CONFIG_SERIAL_8250_FSL=y CONFIG_SERIAL_8250_DW=y # CONFIG_SERIAL_8250_EM is not set # CONFIG_SERIAL_8250_RT288X is not set -# CONFIG_SERIAL_8250_INGENIC is not set -# CONFIG_SERIAL_8250_MID is not set +# CONFIG_SERIAL_8250_MOXA is not set +CONFIG_SERIAL_OF_PLATFORM=y # # Non-8250 serial port support @@ -1602,7 +1729,6 @@ CONFIG_SERIAL_8250_DW=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set -CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_SERIAL_SCCNXP is not set # CONFIG_SERIAL_SC16IS7XX is not set # CONFIG_SERIAL_BCM63XX is not set @@ -1615,13 +1741,13 @@ CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_SERIAL_FSL_LPUART is not set # CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set # CONFIG_SERIAL_ST_ASC is not set -# CONFIG_SERIAL_STM32 is not set +# CONFIG_SERIAL_DEV_BUS is not set # CONFIG_TTY_PRINTK is not set # CONFIG_HVC_DCC is not set # CONFIG_IPMI_HANDLER is not set CONFIG_HW_RANDOM=y # CONFIG_HW_RANDOM_TIMERIOMEM is not set -# CONFIG_HW_RANDOM_XGS_IPROC_RNG is not set +CONFIG_HW_RANDOM_XGS_IPROC_RNG=y # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_RAW_DRIVER is not set @@ -1634,18 +1760,23 @@ CONFIG_DEVPORT=y # CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y -# CONFIG_I2C_COMPAT is not set +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=y -# CONFIG_I2C_MUX is not set -# CONFIG_I2C_HELPER_AUTO is not set -# CONFIG_I2C_SMBUS is not set +CONFIG_I2C_MUX=y # -# I2C Algorithms +# Multiplexer I2C Chip support # -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set +# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set +CONFIG_I2C_MUX_GPIO=y +# CONFIG_I2C_MUX_GPMUX is not set +# CONFIG_I2C_MUX_LTC4306 is not set +CONFIG_I2C_MUX_PCA9541=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_MUX_PCA954X_DESELECT_ON_EXIT=y +CONFIG_I2C_MUX_REG=y +# CONFIG_I2C_MUX_MLXCPLD is not set +CONFIG_I2C_HELPER_AUTO=y # # I2C Hardware Bus support @@ -1672,8 +1803,8 @@ CONFIG_I2C_CHARDEV=y # # I2C system bus drivers (mostly embedded / system-on-chip) # -CONFIG_I2C_XGS_IPROC=y -# CONFIG_SMBUS_XGS_IPROC is not set +# CONFIG_I2C_XGS_IPROC is not set +CONFIG_SMBUS_XGS_IPROC=y # CONFIG_I2C_CBUS_GPIO is not set # CONFIG_I2C_DESIGNWARE_PLATFORM is not set # CONFIG_I2C_DESIGNWARE_PCI is not set @@ -1712,8 +1843,11 @@ CONFIG_SPI_MASTER=y # SPI Master Controller Drivers # # CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_AXI_SPI_ENGINE is not set +CONFIG_SPI_BCM_QSPI=y # CONFIG_SPI_BITBANG is not set # CONFIG_SPI_CADENCE is not set +# CONFIG_SPI_DESIGNWARE is not set # CONFIG_SPI_GPIO is not set # CONFIG_SPI_FSL_SPI is not set # CONFIG_SPI_OC_TINY is not set @@ -1725,24 +1859,16 @@ CONFIG_SPI_MASTER=y # CONFIG_SPI_XCOMM is not set # CONFIG_SPI_XILINX is not set # CONFIG_SPI_ZYNQMP_GQSPI is not set -CONFIG_SPI_XGS_IPROC=y -CONFIG_IPROC_QSPI_SINGLE_MODE=y -# CONFIG_IPROC_QSPI_DUAL_MODE is not set -# CONFIG_IPROC_QSPI_QUAD_MODE is not set -CONFIG_IPROC_QSPI_MAX_HZ=62500000 -# CONFIG_SPI_DESIGNWARE is not set # # SPI Protocol Masters # # CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_LOOPBACK_TEST is not set # CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPI_SLAVE is not set # CONFIG_SPMI is not set # CONFIG_HSI is not set - -# -# PPS support -# CONFIG_PPS=y # CONFIG_PPS_DEBUG is not set @@ -1766,10 +1892,7 @@ CONFIG_PTP_1588_CLOCK=y # Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. # CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y -CONFIG_ARCH_REQUIRE_GPIOLIB=y CONFIG_GPIOLIB=y -CONFIG_GPIO_DEVRES=y CONFIG_OF_GPIO=y CONFIG_GPIOLIB_IRQCHIP=y # CONFIG_DEBUG_GPIO is not set @@ -1783,14 +1906,15 @@ CONFIG_GPIO_GENERIC=y # CONFIG_GPIO_ALTERA is not set CONFIG_GPIO_XGS_IPROC=y # CONFIG_GPIO_DWAPB is not set -# CONFIG_GPIO_EM is not set +# CONFIG_GPIO_EXAR is not set +# CONFIG_GPIO_FTGPIO010 is not set # CONFIG_GPIO_GENERIC_PLATFORM is not set # CONFIG_GPIO_GRGPIO is not set +# CONFIG_GPIO_MOCKUP is not set +# CONFIG_GPIO_MPC8XXX is not set # CONFIG_GPIO_PL061 is not set -# CONFIG_GPIO_VX855 is not set # CONFIG_GPIO_XILINX is not set # CONFIG_GPIO_ZEVIO is not set -# CONFIG_GPIO_ZX is not set # # I2C GPIO expanders @@ -1801,18 +1925,18 @@ CONFIG_GPIO_XGS_IPROC=y # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set -# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_TPIC2810 is not set # # MFD GPIO expanders # +# CONFIG_HTC_EGPIO is not set # # PCI GPIO expanders # -# CONFIG_GPIO_AMD8111 is not set # CONFIG_GPIO_BT8XX is not set -# CONFIG_GPIO_ML_IOH is not set +# CONFIG_GPIO_PCI_IDIO_16 is not set # CONFIG_GPIO_RDC321X is not set # @@ -1821,20 +1945,18 @@ CONFIG_GPIO_XGS_IPROC=y # CONFIG_GPIO_74X164 is not set # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MC33880 is not set - -# -# SPI or I2C GPIO expanders -# -# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_PISOSR is not set +# CONFIG_GPIO_XRA1403 is not set # # USB GPIO expanders # # CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set # CONFIG_POWER_AVS is not set +# CONFIG_POWER_RESET is not set +# CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set +CONFIG_HWMON_VID=y # CONFIG_HWMON_DEBUG_CHIP is not set # @@ -1856,6 +1978,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADT7470 is not set # CONFIG_SENSORS_ADT7475 is not set # CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ASPEED is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS620 is not set # CONFIG_SENSORS_DS1621 is not set @@ -1863,6 +1986,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_F71882FG is not set # CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_FTSTEUTATES is not set # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_G760A is not set @@ -1874,6 +1998,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_POWR1220 is not set # CONFIG_SENSORS_LINEAGE is not set # CONFIG_SENSORS_LTC2945 is not set +# CONFIG_SENSORS_LTC2990 is not set # CONFIG_SENSORS_LTC4151 is not set # CONFIG_SENSORS_LTC4215 is not set # CONFIG_SENSORS_LTC4222 is not set @@ -1885,27 +2010,28 @@ CONFIG_HWMON=y # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX1668 is not set # CONFIG_SENSORS_MAX197 is not set +# CONFIG_SENSORS_MAX31722 is not set # CONFIG_SENSORS_MAX6639 is not set # CONFIG_SENSORS_MAX6642 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_MAX6697 is not set # CONFIG_SENSORS_MAX31790 is not set -# CONFIG_SENSORS_HTU21 is not set # CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_TC654 is not set # CONFIG_SENSORS_ADCXX is not set # CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM70 is not set -# CONFIG_SENSORS_LM73 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set +CONFIG_SENSORS_LM70=y +CONFIG_SENSORS_LM73=y +CONFIG_SENSORS_LM75=y +CONFIG_SENSORS_LM77=y +CONFIG_SENSORS_LM78=y +CONFIG_SENSORS_LM80=y +CONFIG_SENSORS_LM83=y +CONFIG_SENSORS_LM85=y +CONFIG_SENSORS_LM87=y +CONFIG_SENSORS_LM90=y +CONFIG_SENSORS_LM92=y +CONFIG_SENSORS_LM93=y # CONFIG_SENSORS_LM95234 is not set # CONFIG_SENSORS_LM95241 is not set # CONFIG_SENSORS_LM95245 is not set @@ -1920,6 +2046,7 @@ CONFIG_HWMON=y # CONFIG_PMBUS is not set # CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SHT3x is not set # CONFIG_SENSORS_SHTC1 is not set # CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_DME1737 is not set @@ -1932,6 +2059,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_SCH56XX_COMMON is not set # CONFIG_SENSORS_SCH5627 is not set # CONFIG_SENSORS_SCH5636 is not set +# CONFIG_SENSORS_STTS751 is not set # CONFIG_SENSORS_SMM665 is not set # CONFIG_SENSORS_ADC128D818 is not set # CONFIG_SENSORS_ADS1015 is not set @@ -1940,10 +2068,12 @@ CONFIG_HWMON=y # CONFIG_SENSORS_AMC6821 is not set # CONFIG_SENSORS_INA209 is not set # CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_INA3221 is not set # CONFIG_SENSORS_TC74 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_TMP102 is not set # CONFIG_SENSORS_TMP103 is not set +# CONFIG_SENSORS_TMP108 is not set # CONFIG_SENSORS_TMP401 is not set # CONFIG_SENSORS_TMP421 is not set # CONFIG_SENSORS_VIA686A is not set @@ -1958,10 +2088,31 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set -# CONFIG_THERMAL is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +# CONFIG_THERMAL_WRITABLE_TRIPS is not set +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set +# CONFIG_THERMAL_GOV_FAIR_SHARE is not set +CONFIG_THERMAL_GOV_STEP_WISE=y +# CONFIG_THERMAL_GOV_BANG_BANG is not set +# CONFIG_THERMAL_GOV_USER_SPACE is not set +# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set +# CONFIG_THERMAL_EMULATION is not set +# CONFIG_QORIQ_THERMAL is not set + +# +# ACPI INT340X thermal drivers +# CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y # CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y +# CONFIG_WATCHDOG_SYSFS is not set # # Watchdog Device Drivers @@ -1969,14 +2120,13 @@ CONFIG_WATCHDOG_CORE=y # CONFIG_SOFT_WATCHDOG is not set # CONFIG_GPIO_WATCHDOG is not set # CONFIG_XILINX_WATCHDOG is not set -# CONFIG_ARM_SP805_WATCHDOG is not set +# CONFIG_ZIIRAVE_WATCHDOG is not set +CONFIG_ARM_SP805_WATCHDOG=y # CONFIG_CADENCE_WATCHDOG is not set # CONFIG_DW_WATCHDOG is not set # CONFIG_MAX63XX_WATCHDOG is not set -CONFIG_XGS_IPROC_SP805_WDT=y # CONFIG_ALIM7101_WDT is not set # CONFIG_I6300ESB_WDT is not set -# CONFIG_BCM7038_WDT is not set # CONFIG_MEN_A21_WDT is not set # @@ -1989,6 +2139,11 @@ CONFIG_XGS_IPROC_SP805_WDT=y # USB-based Watchdog Cards # # CONFIG_USBPCWATCHDOG is not set + +# +# Watchdog Pretimeout Governors +# +# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set CONFIG_SSB_POSSIBLE=y # @@ -1996,16 +2151,13 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_SSB is not set CONFIG_BCMA_POSSIBLE=y - -# -# Broadcom specific AMBA -# # CONFIG_BCMA is not set # # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_ACT8945A is not set # CONFIG_MFD_AS3711 is not set # CONFIG_MFD_AS3722 is not set # CONFIG_PMIC_ADP5520 is not set @@ -2013,7 +2165,8 @@ CONFIG_BCMA_POSSIBLE=y # CONFIG_MFD_ATMEL_FLEXCOM is not set # CONFIG_MFD_ATMEL_HLCDC is not set # CONFIG_MFD_BCM590XX is not set -# CONFIG_MFD_AXP20X is not set +# CONFIG_MFD_BD9571MWV is not set +# CONFIG_MFD_AXP20X_I2C is not set # CONFIG_MFD_CROS_EC is not set # CONFIG_MFD_ASIC3 is not set # CONFIG_PMIC_DA903X is not set @@ -2027,18 +2180,17 @@ CONFIG_BCMA_POSSIBLE=y # CONFIG_MFD_MC13XXX_SPI is not set # CONFIG_MFD_MC13XXX_I2C is not set # CONFIG_MFD_HI6421_PMIC is not set -# CONFIG_HTC_EGPIO is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_HTC_I2CPLD is not set # CONFIG_LPC_ICH is not set # CONFIG_LPC_SCH is not set -# CONFIG_INTEL_SOC_PMIC is not set # CONFIG_MFD_JANZ_CMODIO is not set # CONFIG_MFD_KEMPLD is not set # CONFIG_MFD_88PM800 is not set # CONFIG_MFD_88PM805 is not set # CONFIG_MFD_88PM860X is not set # CONFIG_MFD_MAX14577 is not set +# CONFIG_MFD_MAX77620 is not set # CONFIG_MFD_MAX77686 is not set # CONFIG_MFD_MAX77693 is not set # CONFIG_MFD_MAX77843 is not set @@ -2049,10 +2201,11 @@ CONFIG_BCMA_POSSIBLE=y # CONFIG_MFD_MT6397 is not set # CONFIG_MFD_MENF21BMC is not set # CONFIG_EZX_PCAP is not set +# CONFIG_MFD_CPCAP is not set # CONFIG_MFD_VIPERBOARD is not set # CONFIG_MFD_RETU is not set # CONFIG_MFD_PCF50633 is not set -# CONFIG_MFD_PM8921_CORE is not set +# CONFIG_MFD_PM8XXX is not set # CONFIG_MFD_RDC321X is not set # CONFIG_MFD_RTSX_PCI is not set # CONFIG_MFD_RT5033 is not set @@ -2071,16 +2224,19 @@ CONFIG_BCMA_POSSIBLE=y # CONFIG_MFD_TI_AM335X_TSCADC is not set # CONFIG_MFD_LP3943 is not set # CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_TI_LMU is not set # CONFIG_MFD_PALMAS is not set # CONFIG_TPS6105X is not set # CONFIG_TPS65010 is not set # CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65086 is not set # CONFIG_MFD_TPS65090 is not set # CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TI_LP873X is not set +# CONFIG_MFD_TI_LP87565 is not set # CONFIG_MFD_TPS65218 is not set # CONFIG_MFD_TPS6586X is not set # CONFIG_MFD_TPS65910 is not set -# CONFIG_MFD_TPS65912 is not set # CONFIG_MFD_TPS65912_I2C is not set # CONFIG_MFD_TPS65912_SPI is not set # CONFIG_MFD_TPS80031 is not set @@ -2108,8 +2264,14 @@ CONFIG_BCMA_POSSIBLE=y # Graphics support # # CONFIG_VGA_ARB is not set +# CONFIG_IMX_IPUV3_CORE is not set # CONFIG_DRM is not set +# +# ACP (Audio CoProcessor) Configuration +# +# CONFIG_DRM_LIB_RANDOM is not set + # # Frame buffer Devices # @@ -2122,6 +2284,7 @@ CONFIG_USB_SUPPORT=y CONFIG_USB_COMMON=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB=y +CONFIG_USB_PCI=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y # @@ -2132,7 +2295,6 @@ CONFIG_USB_DYNAMIC_MINORS=y # CONFIG_USB_OTG is not set # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set -# CONFIG_USB_ULPI_BUS is not set # CONFIG_USB_MON is not set # CONFIG_USB_WUSB_CBAF is not set @@ -2145,8 +2307,8 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_TT_NEWSCHED=y CONFIG_USB_EHCI_PCI=y -CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_EHCI_XGS_IPROC=y +CONFIG_USB_EHCI_HCD_PLATFORM=y # CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_ISP1362_HCD is not set @@ -2219,7 +2381,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_IDMOUSE is not set @@ -2234,7 +2395,9 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_ISIGHTFW is not set # CONFIG_USB_YUREX is not set # CONFIG_USB_EZUSB_FX2 is not set +# CONFIG_USB_HUB_USB251XB is not set # CONFIG_USB_HSIC_USB3503 is not set +# CONFIG_USB_HSIC_USB4604 is not set # CONFIG_USB_LINK_LAYER_TEST is not set # CONFIG_USB_CHAOSKEY is not set @@ -2243,17 +2406,18 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_PHY=y # CONFIG_NOP_USB_XCEIV is not set -# CONFIG_AM335X_PHY_USB is not set # CONFIG_USB_GPIO_VBUS is not set # CONFIG_USB_ISP1301 is not set # CONFIG_USB_ULPI is not set CONFIG_USBPHY_XGS_IPROC=y +# CONFIG_USB_XGS_IPROC_DRD is not set CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set # CONFIG_USB_GADGET_DEBUG_FS is not set CONFIG_USB_GADGET_VBUS_DRAW=2 CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 +# CONFIG_U_SERIAL_CONSOLE is not set # # USB Peripheral Controller @@ -2265,6 +2429,7 @@ CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 # CONFIG_USB_PXA27X is not set # CONFIG_USB_MV_UDC is not set # CONFIG_USB_MV_U3D is not set +# CONFIG_USB_SNP_UDC_PLAT is not set # CONFIG_USB_M66592 is not set # CONFIG_USB_BDC_UDC is not set # CONFIG_USB_AMD5536UDC is not set @@ -2273,7 +2438,7 @@ CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 # CONFIG_USB_GOKU is not set # CONFIG_USB_EG20T is not set # CONFIG_USB_GADGET_XILINX is not set -CONFIG_USB_XGS_IPROC_UDC=m +CONFIG_USB_XGS_IPROC_UDC=y # CONFIG_USB_DUMMY_HCD is not set CONFIG_USB_LIBCOMPOSITE=m CONFIG_USB_F_ACM=m @@ -2294,27 +2459,34 @@ CONFIG_USB_G_SERIAL=m # CONFIG_USB_G_MULTI is not set # CONFIG_USB_G_HID is not set # CONFIG_USB_G_DBGP is not set -# CONFIG_UWB is not set -CONFIG_MMC=y -# CONFIG_MMC_DEBUG is not set # -# MMC/SD/SDIO Card Drivers +# USB Power Delivery and Type-C drivers # +# CONFIG_TYPEC_UCSI is not set +# CONFIG_USB_ULPI_BUS is not set +# CONFIG_UWB is not set +CONFIG_MMC=y +CONFIG_PWRSEQ_EMMC=y +CONFIG_PWRSEQ_SIMPLE=y CONFIG_MMC_BLOCK=y CONFIG_MMC_BLOCK_MINORS=8 -CONFIG_MMC_BLOCK_BOUNCE=y # CONFIG_SDIO_UART is not set # CONFIG_MMC_TEST is not set # # MMC/SD/SDIO Host Controller Drivers # +# CONFIG_MMC_DEBUG is not set # CONFIG_MMC_ARMMMCI is not set CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_IO_ACCESSORS=y # CONFIG_MMC_SDHCI_PCI is not set -# CONFIG_MMC_SDHCI_PLTFM is not set +CONFIG_MMC_SDHCI_PLTFM=y +# CONFIG_MMC_SDHCI_OF_ARASAN is not set +# CONFIG_MMC_SDHCI_OF_AT91 is not set +# CONFIG_MMC_SDHCI_CADENCE is not set +# CONFIG_MMC_SDHCI_F_SDH30 is not set # CONFIG_MMC_TIFM_SD is not set # CONFIG_MMC_SPI is not set # CONFIG_MMC_CB710 is not set @@ -2326,15 +2498,159 @@ CONFIG_MMC_SDHCI_IO_ACCESSORS=y # CONFIG_MMC_TOSHIBA_PCI is not set # CONFIG_MMC_MTK is not set CONFIG_MMC_SDHCI_XGS_IPROC=y +# CONFIG_MMC_SDHCI_XENON is not set # CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +# CONFIG_LEDS_CLASS_FLASH is not set +# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set + +# +# LED drivers +# +# CONFIG_LEDS_BCM6328 is not set +# CONFIG_LEDS_BCM6358 is not set +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_LM3642 is not set +# CONFIG_LEDS_GPIO is not set +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP3952 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_LP5562 is not set +# CONFIG_LEDS_LP8501 is not set +# CONFIG_LEDS_LP8860 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA963X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_TLC591XX is not set +# CONFIG_LEDS_LM355x is not set +# CONFIG_LEDS_IS31FL319X is not set +# CONFIG_LEDS_IS31FL32XX is not set + +# +# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) +# +# CONFIG_LEDS_BLINKM is not set +# CONFIG_LEDS_USER is not set + +# +# LED Triggers +# +# CONFIG_LEDS_TRIGGERS is not set # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set CONFIG_EDAC_ATOMIC_SCRUB=y CONFIG_EDAC_SUPPORT=y -# CONFIG_EDAC is not set CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_SYSTOHC is not set +# CONFIG_RTC_DEBUG is not set +CONFIG_RTC_NVMEM=y + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_ABB5ZES3 is not set +# CONFIG_RTC_DRV_ABX80X is not set +CONFIG_RTC_DRV_DS1307=y +CONFIG_RTC_DRV_DS1307_HWMON=y +CONFIG_RTC_DRV_DS1307_CENTURY=y +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_HYM8563 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8523 is not set +# CONFIG_RTC_DRV_PCF85063 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8010 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV8803 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1302 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1343 is not set +# CONFIG_RTC_DRV_DS1347 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6916 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RX4581 is not set +# CONFIG_RTC_DRV_RX6110 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_PCF2123 is not set +# CONFIG_RTC_DRV_MCP795 is not set +CONFIG_RTC_I2C_AND_SPI=y + +# +# SPI and I2C RTC drivers +# +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_PCF2127 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1685_FAMILY is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_DS2404 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_ZYNQMP is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +# CONFIG_RTC_DRV_FTRTC010 is not set +# CONFIG_RTC_DRV_SNVS is not set +# CONFIG_RTC_DRV_R7301 is not set + +# +# HID Sensor RTC drivers +# CONFIG_DMADEVICES=y CONFIG_DMADEVICES_DEBUG=y CONFIG_DMADEVICES_VDEBUG=y @@ -2344,12 +2660,14 @@ CONFIG_DMADEVICES_VDEBUG=y # CONFIG_DMA_ENGINE=y CONFIG_DMA_OF=y +# CONFIG_ALTERA_MSGDMA is not set # CONFIG_AMBA_PL08X is not set # CONFIG_FSL_EDMA is not set # CONFIG_INTEL_IDMA64 is not set # CONFIG_NBPFAXI_DMA is not set CONFIG_PL330_DMA=y -# CONFIG_XGS_IPROC_DMA330_DMA is not set +# CONFIG_QCOM_HIDMA_MGMT is not set +# CONFIG_QCOM_HIDMA is not set # CONFIG_DW_DMAC is not set # CONFIG_DW_DMAC_PCI is not set @@ -2358,6 +2676,11 @@ CONFIG_PL330_DMA=y # # CONFIG_ASYNC_TX_DMA is not set # CONFIG_DMATEST is not set + +# +# DMABUF options +# +# CONFIG_SYNC_FILE is not set # CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set # CONFIG_VIRT_DRIVERS is not set @@ -2371,7 +2694,9 @@ CONFIG_PL330_DMA=y # # Microsoft Hyper-V guest support # +# CONFIG_HYPERV_TSCPAGE is not set # CONFIG_STAGING is not set +# CONFIG_GOLDFISH is not set # CONFIG_CHROME_PLATFORMS is not set CONFIG_CLKDEV_LOOKUP=y CONFIG_HAVE_CLK_PREPARE=y @@ -2380,25 +2705,27 @@ CONFIG_COMMON_CLK=y # # Common Clock Framework # +# CONFIG_CLK_HSDK is not set # CONFIG_COMMON_CLK_SI5351 is not set # CONFIG_COMMON_CLK_SI514 is not set # CONFIG_COMMON_CLK_SI570 is not set -# CONFIG_COMMON_CLK_CDCE925 is not set -# CONFIG_CLK_QORIQ is not set -# CONFIG_COMMON_CLK_PXA is not set # CONFIG_COMMON_CLK_CDCE706 is not set +# CONFIG_COMMON_CLK_CDCE925 is not set +# CONFIG_COMMON_CLK_CS2000_CP is not set +# CONFIG_CLK_QORIQ is not set +# CONFIG_COMMON_CLK_NXP is not set +# CONFIG_COMMON_CLK_PXA is not set +# CONFIG_COMMON_CLK_PIC32 is not set +# CONFIG_COMMON_CLK_VC5 is not set CONFIG_COMMON_CLK_IPROC=y CONFIG_CLK_XGS_IPROC=y - -# -# Hardware Spinlock drivers -# +# CONFIG_HWSPINLOCK is not set # # Clock Source drivers # -CONFIG_CLKSRC_OF=y -CONFIG_CLKSRC_PROBE=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y CONFIG_ARM_GLOBAL_TIMER=y # CONFIG_ARM_TIMER_SP804 is not set CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y @@ -2414,12 +2741,13 @@ CONFIG_IOMMU_SUPPORT=y # Generic IOMMU Pagetable Support # # CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set # CONFIG_ARM_SMMU is not set # # Remoteproc drivers # -# CONFIG_STE_MODEM_RPROC is not set +# CONFIG_REMOTEPROC is not set # # Rpmsg drivers @@ -2428,12 +2756,36 @@ CONFIG_IOMMU_SUPPORT=y # # SOC (System On Chip) specific Drivers # + +# +# Amlogic SoC drivers +# + +# +# Broadcom SoC drivers +# # CONFIG_SOC_BRCMSTB is not set -CONFIG_SOC_XGS_IPROC=y + +# +# i.MX SoC drivers +# + +# +# Qualcomm SoC drivers +# # CONFIG_SUNXI_SRAM is not set # CONFIG_SOC_TI is not set # CONFIG_PM_DEVFREQ is not set -# CONFIG_EXTCON is not set +CONFIG_EXTCON=y + +# +# Extcon Device Drivers +# +# CONFIG_EXTCON_GPIO is not set +# CONFIG_EXTCON_MAX3355 is not set +# CONFIG_EXTCON_RT8973A is not set +# CONFIG_EXTCON_SM5502 is not set +# CONFIG_EXTCON_USB_GPIO is not set # CONFIG_MEMORY is not set # CONFIG_IIO is not set # CONFIG_NTB is not set @@ -2441,6 +2793,7 @@ CONFIG_SOC_XGS_IPROC=y # CONFIG_PWM is not set CONFIG_IRQCHIP=y CONFIG_ARM_GIC=y +CONFIG_ARM_GIC_MAX_NR=1 # CONFIG_IPACK_BUS is not set # CONFIG_RESET_CONTROLLER is not set # CONFIG_FMC is not set @@ -2448,38 +2801,41 @@ CONFIG_ARM_GIC=y # # PHY Subsystem # -# CONFIG_GENERIC_PHY is not set +CONFIG_GENERIC_PHY=y +# CONFIG_BCM_KONA_USB2_PHY is not set # CONFIG_PHY_PXA_28NM_HSIC is not set # CONFIG_PHY_PXA_28NM_USB2 is not set -# CONFIG_BCM_KONA_USB2_PHY is not set # CONFIG_POWERCAP is not set # CONFIG_MCB is not set - -# -# Performance monitor support -# # CONFIG_RAS is not set -# CONFIG_THUNDERBOLT is not set # # Android # # CONFIG_ANDROID is not set -# CONFIG_NVMEM is not set +# CONFIG_DAX is not set +CONFIG_NVMEM=y # CONFIG_STM is not set -# CONFIG_STM_DUMMY is not set -# CONFIG_STM_SOURCE_CONSOLE is not set # CONFIG_INTEL_TH is not set +# CONFIG_FPGA is not set # -# FPGA Configuration Support +# FSI support # -# CONFIG_FPGA is not set +# CONFIG_FSI is not set +# CONFIG_TEE is not set # # Firmware Drivers # # CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_FW_CFG_SYSFS is not set +CONFIG_HAVE_ARM_SMCCC=y +# CONFIG_GOOGLE_FIRMWARE is not set + +# +# Tegra firmware driver +# # # File systems @@ -2508,16 +2864,21 @@ CONFIG_FS_MBCACHE=y # CONFIG_F2FS_FS is not set CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y +# CONFIG_EXPORTFS_BLOCK_OPS is not set CONFIG_FILE_LOCKING=y -# CONFIG_FSNOTIFY is not set +CONFIG_MANDATORY_FILE_LOCKING=y +# CONFIG_FS_ENCRYPTION is not set +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set -# CONFIG_INOTIFY_USER is not set +CONFIG_INOTIFY_USER=y # CONFIG_FANOTIFY is not set # CONFIG_QUOTA is not set # CONFIG_QUOTACTL is not set CONFIG_AUTOFS4_FS=y # CONFIG_FUSE_FS is not set CONFIG_OVERLAY_FS=y +# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set +# CONFIG_OVERLAY_FS_INDEX is not set # # Caches @@ -2538,6 +2899,7 @@ CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_FAT_DEFAULT_UTF8 is not set CONFIG_NTFS_FS=y # CONFIG_NTFS_DEBUG is not set # CONFIG_NTFS_RW is not set @@ -2547,13 +2909,14 @@ CONFIG_NTFS_FS=y # CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y -# CONFIG_PROC_PAGE_MONITOR is not set +CONFIG_PROC_PAGE_MONITOR=y # CONFIG_PROC_CHILDREN is not set CONFIG_KERNFS=y CONFIG_SYSFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_CONFIGFS_FS=m CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ORANGEFS_FS is not set # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_ECRYPT_FS is not set @@ -2578,9 +2941,24 @@ CONFIG_UBIFS_FS=y CONFIG_UBIFS_FS_LZO=y CONFIG_UBIFS_FS_ZLIB=y # CONFIG_UBIFS_ATIME_SUPPORT is not set -# CONFIG_LOGFS is not set +# CONFIG_UBIFS_FS_ENCRYPTION is not set +CONFIG_UBIFS_FS_SECURITY=y # CONFIG_CRAMFS is not set -# CONFIG_SQUASHFS is not set +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_FILE_CACHE is not set +CONFIG_SQUASHFS_FILE_DIRECT=y +# CONFIG_SQUASHFS_DECOMP_SINGLE is not set +CONFIG_SQUASHFS_DECOMP_MULTI=y +# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_ZSTD=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -2680,6 +3058,7 @@ CONFIG_NLS_ISO8859_1=y # printk and dmesg options # # CONFIG_PRINTK_TIME is not set +CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_DYNAMIC_DEBUG is not set @@ -2692,8 +3071,8 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_INFO_SPLIT is not set # CONFIG_DEBUG_INFO_DWARF4 is not set # CONFIG_GDB_SCRIPTS is not set -# CONFIG_ENABLE_WARN_DEPRECATED is not set -# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 # CONFIG_STRIP_ASM_SYMS is not set # CONFIG_READABLE_ASM is not set @@ -2703,10 +3082,10 @@ CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_SECTION_MISMATCH is not set CONFIG_SECTION_MISMATCH_WARN_ONLY=y -CONFIG_FRAME_POINTER=y # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 +CONFIG_MAGIC_SYSRQ_SERIAL=y CONFIG_DEBUG_KERNEL=y # @@ -2714,12 +3093,16 @@ CONFIG_DEBUG_KERNEL=y # # CONFIG_PAGE_EXTENSION is not set # CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_PAGE_POISONING is not set +# CONFIG_DEBUG_RODATA_TEST is not set # CONFIG_DEBUG_OBJECTS is not set # CONFIG_SLUB_STATS is not set CONFIG_HAVE_DEBUG_KMEMLEAK=y # CONFIG_DEBUG_KMEMLEAK is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_VM is not set +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +# CONFIG_DEBUG_VIRTUAL is not set # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_PER_CPU_MAPS is not set # CONFIG_DEBUG_SHIRQ is not set @@ -2727,8 +3110,9 @@ CONFIG_HAVE_DEBUG_KMEMLEAK=y # # Debug Lockups and Hangs # -# CONFIG_LOCKUP_DETECTOR is not set +# CONFIG_SOFTLOCKUP_DETECTOR is not set # CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_WQ_WATCHDOG is not set # CONFIG_PANIC_ON_OOPS is not set CONFIG_PANIC_ON_OOPS_VALUE=0 CONFIG_PANIC_TIMEOUT=0 @@ -2737,7 +3121,6 @@ CONFIG_PANIC_TIMEOUT=0 # CONFIG_SCHEDSTATS is not set # CONFIG_SCHED_STACK_END_CHECK is not set # CONFIG_DEBUG_TIMEKEEPING is not set -# CONFIG_TIMER_STATS is not set CONFIG_DEBUG_PREEMPT=y # @@ -2753,7 +3136,9 @@ CONFIG_DEBUG_PREEMPT=y # CONFIG_DEBUG_ATOMIC_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_LOCK_TORTURE_TEST is not set +# CONFIG_WW_MUTEX_SELFTEST is not set # CONFIG_STACKTRACE is not set +# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_LIST is not set @@ -2766,29 +3151,35 @@ CONFIG_DEBUG_BUGVERBOSE=y # RCU Debugging # # CONFIG_PROVE_RCU is not set -# CONFIG_SPARSE_RCU_POINTER is not set # CONFIG_TORTURE_TEST is not set +# CONFIG_RCU_PERF_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set -CONFIG_RCU_CPU_STALL_TIMEOUT=60 +CONFIG_RCU_CPU_STALL_TIMEOUT=21 # CONFIG_RCU_TRACE is not set # CONFIG_RCU_EQS_DEBUG is not set +# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set # CONFIG_NOTIFIER_ERROR_INJECTION is not set # CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_HAVE_C_RECORDMCOUNT=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set +# CONFIG_DMA_API_DEBUG is not set # # Runtime Testing # # CONFIG_LKDTM is not set # CONFIG_TEST_LIST_SORT is not set +# CONFIG_TEST_SORT is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_RBTREE_TEST is not set # CONFIG_INTERVAL_TREE_TEST is not set @@ -2798,28 +3189,35 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_TEST_STRING_HELPERS is not set # CONFIG_TEST_KSTRTOX is not set # CONFIG_TEST_PRINTF is not set +# CONFIG_TEST_BITMAP is not set +# CONFIG_TEST_UUID is not set # CONFIG_TEST_RHASHTABLE is not set -# CONFIG_DMA_API_DEBUG is not set +# CONFIG_TEST_HASH is not set # CONFIG_TEST_LKM is not set # CONFIG_TEST_USER_COPY is not set # CONFIG_TEST_BPF is not set # CONFIG_TEST_FIRMWARE is not set +# CONFIG_TEST_SYSCTL is not set # CONFIG_TEST_UDELAY is not set -# CONFIG_MEMTEST is not set # CONFIG_TEST_STATIC_KEYS is not set +# CONFIG_TEST_KMOD is not set +# CONFIG_MEMTEST is not set +# CONFIG_BUG_ON_DATA_CORRUPTION is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set -# CONFIG_ARM_PTDUMP is not set +# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set +# CONFIG_UBSAN is not set +CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y # CONFIG_STRICT_DEVMEM is not set -# CONFIG_ARM_UNWIND is not set +# CONFIG_ARM_PTDUMP is not set +CONFIG_ARM_UNWIND=y CONFIG_DEBUG_USER=y # CONFIG_DEBUG_LL is not set CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" # CONFIG_DEBUG_UART_8250 is not set CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" # CONFIG_PID_IN_CONTEXTIDR is not set -# CONFIG_DEBUG_SET_MODULE_RONX is not set # CONFIG_CORESIGHT is not set # @@ -2828,9 +3226,13 @@ CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" CONFIG_KEYS=y # CONFIG_PERSISTENT_KEYRINGS is not set # CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_KEY_DH_OPERATIONS is not set # CONFIG_SECURITY_DMESG_RESTRICT is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set +CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y +# CONFIG_HARDENED_USERCOPY is not set +# CONFIG_STATIC_USERMODEHELPER is not set CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y @@ -2849,9 +3251,12 @@ CONFIG_CRYPTO_HASH2=y CONFIG_CRYPTO_RNG=m CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_RNG_DEFAULT=m -CONFIG_CRYPTO_PCOMP2=y CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_KPP2=y +CONFIG_CRYPTO_ACOMP2=y # CONFIG_CRYPTO_RSA is not set +# CONFIG_CRYPTO_DH is not set +# CONFIG_CRYPTO_ECDH is not set CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_USER is not set @@ -2913,6 +3318,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA1 is not set CONFIG_CRYPTO_SHA256=m # CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_SHA3 is not set # CONFIG_CRYPTO_TGR192 is not set # CONFIG_CRYPTO_WP512 is not set @@ -2920,6 +3326,7 @@ CONFIG_CRYPTO_SHA256=m # Ciphers # CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_AES_TI is not set # CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_ARC4 is not set # CONFIG_CRYPTO_BLOWFISH is not set @@ -2940,7 +3347,6 @@ CONFIG_CRYPTO_DES=y # Compression # CONFIG_CRYPTO_DEFLATE=y -# CONFIG_CRYPTO_ZLIB is not set CONFIG_CRYPTO_LZO=y # CONFIG_CRYPTO_842 is not set # CONFIG_CRYPTO_LZ4 is not set @@ -2953,7 +3359,6 @@ CONFIG_CRYPTO_ANSI_CPRNG=m CONFIG_CRYPTO_DRBG_MENU=m CONFIG_CRYPTO_DRBG_HMAC=y # CONFIG_CRYPTO_DRBG_HASH is not set -# CONFIG_CRYPTO_DRBG_CTR is not set CONFIG_CRYPTO_DRBG=m CONFIG_CRYPTO_JITTERENTROPY=m # CONFIG_CRYPTO_USER_API_HASH is not set @@ -2962,12 +3367,13 @@ CONFIG_CRYPTO_JITTERENTROPY=m # CONFIG_CRYPTO_USER_API_AEAD is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC is not set # CONFIG_ASYMMETRIC_KEY_TYPE is not set # # Certificates for signature checking # -# CONFIG_SYSTEM_TRUSTED_KEYRING is not set +# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set # CONFIG_ARM_CRYPTO is not set # CONFIG_BINARY_PRINTF is not set @@ -2993,15 +3399,19 @@ CONFIG_CRC32_SLICEBY8=y # CONFIG_CRC32_SLICEBY4 is not set # CONFIG_CRC32_SARWATE is not set # CONFIG_CRC32_BIT is not set +# CONFIG_CRC4 is not set # CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set # CONFIG_CRC8 is not set +CONFIG_XXHASH=y # CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set # CONFIG_RANDOM32_SELFTEST is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y CONFIG_LZO_COMPRESS=y CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_DECOMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y CONFIG_XZ_DEC=y CONFIG_XZ_DEC_X86=y CONFIG_XZ_DEC_POWERPC=y @@ -3011,19 +3421,30 @@ CONFIG_XZ_DEC_ARMTHUMB=y CONFIG_XZ_DEC_SPARC=y CONFIG_XZ_DEC_BCJ=y # CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DECOMPRESS_XZ=y +CONFIG_DECOMPRESS_LZO=y +CONFIG_DECOMPRESS_LZ4=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_ASSOCIATIVE_ARRAY=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT_MAP=y CONFIG_HAS_DMA=y +# CONFIG_DMA_NOOP_OPS is not set +# CONFIG_DMA_VIRT_OPS is not set CONFIG_CPU_RMAP=y CONFIG_DQL=y CONFIG_NLATTR=y -CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y # CONFIG_CORDIC is not set # CONFIG_DDR is not set +# CONFIG_IRQ_POLL is not set CONFIG_LIBFDT=y CONFIG_OID_REGISTRY=y # CONFIG_SG_SPLIT is not set +CONFIG_SG_POOL=y CONFIG_ARCH_HAS_SG_CHAIN=y +CONFIG_SBITMAP=y +# CONFIG_STRING_SELFTEST is not set # CONFIG_VIRTUALIZATION is not set diff --git a/packages/base/any/kernels/4.14-lts/patches/brcm-iproc-4.14.patch b/packages/base/any/kernels/4.14-lts/patches/brcm-iproc-4.14.patch new file mode 100644 index 00000000..d2023acb --- /dev/null +++ b/packages/base/any/kernels/4.14-lts/patches/brcm-iproc-4.14.patch @@ -0,0 +1,32416 @@ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/Kconfig b/arch/arm/Kconfig +--- a/arch/arm/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/arch/arm/Kconfig 2018-05-10 11:31:28.281398222 +0800 +@@ -759,6 +759,8 @@ source "arch/arm/mach-iop33x/Kconfig" + + source "arch/arm/mach-iop13xx/Kconfig" + ++source "arch/arm/mach-iproc/Kconfig" ++ + source "arch/arm/mach-ixp4xx/Kconfig" + + source "arch/arm/mach-keystone/Kconfig" +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/Makefile b/arch/arm/Makefile +--- a/arch/arm/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/arch/arm/Makefile 2018-05-10 11:31:28.281398222 +0800 +@@ -177,6 +177,7 @@ machine-$(CONFIG_ARCH_INTEGRATOR) += int + machine-$(CONFIG_ARCH_IOP13XX) += iop13xx + machine-$(CONFIG_ARCH_IOP32X) += iop32x + machine-$(CONFIG_ARCH_IOP33X) += iop33x ++machine-$(CONFIG_ARCH_XGS_IPROC) += iproc + machine-$(CONFIG_ARCH_IXP4XX) += ixp4xx + machine-$(CONFIG_ARCH_KEYSTONE) += keystone + machine-$(CONFIG_ARCH_KS8695) += ks8695 +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/compressed/ashldi3.S b/arch/arm/boot/compressed/ashldi3.S +--- a/arch/arm/boot/compressed/ashldi3.S 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/compressed/ashldi3.S 2018-02-27 17:12:26.660706150 +0800 +@@ -0,0 +1,54 @@ ++/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005 ++ Free Software Foundation, Inc. ++ ++This file is free software; you can redistribute it and/or modify it ++under the terms of the GNU General Public License as published by the ++Free Software Foundation; either version 2, or (at your option) any ++later version. ++ ++In addition to the permissions in the GNU General Public License, the ++Free Software Foundation gives you unlimited permission to link the ++compiled version of this file into combinations with other programs, ++and to distribute those combinations without any restriction coming ++from the use of this file. (The General Public License restrictions ++do apply in other respects; for example, they cover modification of ++the file, and distribution when not linked into a combine ++executable.) ++ ++This file is distributed in the hope that it will be useful, but ++WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program; see the file COPYING. If not, write to ++the Free Software Foundation, 51 Franklin Street, Fifth Floor, ++Boston, MA 02110-1301, USA. */ ++ ++ ++#include ++#include ++ ++#ifdef __ARMEB__ ++#define al r1 ++#define ah r0 ++#else ++#define al r0 ++#define ah r1 ++#endif ++ ++ENTRY(__ashldi3) ++ENTRY(__aeabi_llsl) ++ ++ subs r3, r2, #32 ++ rsb ip, r2, #32 ++ movmi ah, ah, lsl r2 ++ movpl ah, al, lsl r3 ++ ARM( orrmi ah, ah, al, lsr ip ) ++ THUMB( lsrmi r3, al, ip ) ++ THUMB( orrmi ah, ah, r3 ) ++ mov al, al, lsl r2 ++ ret lr ++ ++ENDPROC(__ashldi3) ++ENDPROC(__aeabi_llsl) +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/compressed/bswapsdi2.S b/arch/arm/boot/compressed/bswapsdi2.S +--- a/arch/arm/boot/compressed/bswapsdi2.S 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/compressed/bswapsdi2.S 2018-02-27 17:12:26.688706343 +0800 +@@ -0,0 +1,38 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#include ++#include ++ ++#if __LINUX_ARM_ARCH__ >= 6 ++ENTRY(__bswapsi2) ++ rev r0, r0 ++ bx lr ++ENDPROC(__bswapsi2) ++ ++ENTRY(__bswapdi2) ++ rev r3, r0 ++ rev r0, r1 ++ mov r1, r3 ++ bx lr ++ENDPROC(__bswapdi2) ++#else ++ENTRY(__bswapsi2) ++ eor r3, r0, r0, ror #16 ++ mov r3, r3, lsr #8 ++ bic r3, r3, #0xff00 ++ eor r0, r3, r0, ror #8 ++ ret lr ++ENDPROC(__bswapsi2) ++ ++ENTRY(__bswapdi2) ++ mov ip, r1 ++ eor r3, ip, ip, ror #16 ++ eor r1, r0, r0, ror #16 ++ mov r1, r1, lsr #8 ++ mov r3, r3, lsr #8 ++ bic r3, r3, #0xff00 ++ bic r1, r1, #0xff00 ++ eor r1, r1, r0, ror #8 ++ eor r0, r3, ip, ror #8 ++ ret lr ++ENDPROC(__bswapdi2) ++#endif +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/compressed/hyp-stub.S b/arch/arm/boot/compressed/hyp-stub.S +--- a/arch/arm/boot/compressed/hyp-stub.S 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/compressed/hyp-stub.S 2018-02-27 17:12:26.604705764 +0800 +@@ -0,0 +1,285 @@ ++/* ++ * Copyright (c) 2012 Linaro Limited. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef ZIMAGE ++/* ++ * For the kernel proper, we need to find out the CPU boot mode long after ++ * boot, so we need to store it in a writable variable. ++ * ++ * This is not in .bss, because we set it sufficiently early that the boot-time ++ * zeroing of .bss would clobber it. ++ */ ++.data ++ .align 2 ++ENTRY(__boot_cpu_mode) ++ .long 0 ++.text ++ ++ /* ++ * Save the primary CPU boot mode. Requires 3 scratch registers. ++ */ ++ .macro store_primary_cpu_mode reg1, reg2, reg3 ++ mrs \reg1, cpsr ++ and \reg1, \reg1, #MODE_MASK ++ adr \reg2, .L__boot_cpu_mode_offset ++ ldr \reg3, [\reg2] ++ str \reg1, [\reg2, \reg3] ++ .endm ++ ++ /* ++ * Compare the current mode with the one saved on the primary CPU. ++ * If they don't match, record that fact. The Z bit indicates ++ * if there's a match or not. ++ * Requires 3 additionnal scratch registers. ++ */ ++ .macro compare_cpu_mode_with_primary mode, reg1, reg2, reg3 ++ adr \reg2, .L__boot_cpu_mode_offset ++ ldr \reg3, [\reg2] ++ ldr \reg1, [\reg2, \reg3] ++ cmp \mode, \reg1 @ matches primary CPU boot mode? ++ orrne \reg1, \reg1, #BOOT_CPU_MODE_MISMATCH ++ strne \reg1, [\reg2, \reg3] @ record what happened and give up ++ .endm ++ ++#else /* ZIMAGE */ ++ ++ .macro store_primary_cpu_mode reg1:req, reg2:req, reg3:req ++ .endm ++ ++/* ++ * The zImage loader only runs on one CPU, so we don't bother with mult-CPU ++ * consistency checking: ++ */ ++ .macro compare_cpu_mode_with_primary mode, reg1, reg2, reg3 ++ cmp \mode, \mode ++ .endm ++ ++#endif /* ZIMAGE */ ++ ++/* ++ * Hypervisor stub installation functions. ++ * ++ * These must be called with the MMU and D-cache off. ++ * They are not ABI compliant and are only intended to be called from the kernel ++ * entry points in head.S. ++ */ ++@ Call this from the primary CPU ++ENTRY(__hyp_stub_install) ++ store_primary_cpu_mode r4, r5, r6 ++ENDPROC(__hyp_stub_install) ++ ++ @ fall through... ++ ++@ Secondary CPUs should call here ++ENTRY(__hyp_stub_install_secondary) ++ mrs r4, cpsr ++ and r4, r4, #MODE_MASK ++ ++ /* ++ * If the secondary has booted with a different mode, give up ++ * immediately. ++ */ ++ compare_cpu_mode_with_primary r4, r5, r6, r7 ++ retne lr ++ ++ /* ++ * Once we have given up on one CPU, we do not try to install the ++ * stub hypervisor on the remaining ones: because the saved boot mode ++ * is modified, it can't compare equal to the CPSR mode field any ++ * more. ++ * ++ * Otherwise... ++ */ ++ ++ cmp r4, #HYP_MODE ++ retne lr @ give up if the CPU is not in HYP mode ++ ++/* ++ * Configure HSCTLR to set correct exception endianness/instruction set ++ * state etc. ++ * Turn off all traps ++ * Eventually, CPU-specific code might be needed -- assume not for now ++ * ++ * This code relies on the "eret" instruction to synchronize the ++ * various coprocessor accesses. This is done when we switch to SVC ++ * (see safe_svcmode_maskall). ++ */ ++ @ Now install the hypervisor stub: ++ W(adr) r7, __hyp_stub_vectors ++ mcr p15, 4, r7, c12, c0, 0 @ set hypervisor vector base (HVBAR) ++ ++ @ Disable all traps, so we don't get any nasty surprise ++ mov r7, #0 ++ mcr p15, 4, r7, c1, c1, 0 @ HCR ++ mcr p15, 4, r7, c1, c1, 2 @ HCPTR ++ mcr p15, 4, r7, c1, c1, 3 @ HSTR ++ ++THUMB( orr r7, #(1 << 30) ) @ HSCTLR.TE ++ARM_BE8(orr r7, r7, #(1 << 25)) @ HSCTLR.EE ++ mcr p15, 4, r7, c1, c0, 0 @ HSCTLR ++ ++ mrc p15, 4, r7, c1, c1, 1 @ HDCR ++ and r7, #0x1f @ Preserve HPMN ++ mcr p15, 4, r7, c1, c1, 1 @ HDCR ++ ++ @ Make sure NS-SVC is initialised appropriately ++ mrc p15, 0, r7, c1, c0, 0 @ SCTLR ++ orr r7, #(1 << 5) @ CP15 barriers enabled ++ bic r7, #(3 << 7) @ Clear SED/ITD for v8 (RES0 for v7) ++ bic r7, #(3 << 19) @ WXN and UWXN disabled ++ mcr p15, 0, r7, c1, c0, 0 @ SCTLR ++ ++ mrc p15, 0, r7, c0, c0, 0 @ MIDR ++ mcr p15, 4, r7, c0, c0, 0 @ VPIDR ++ ++ mrc p15, 0, r7, c0, c0, 5 @ MPIDR ++ mcr p15, 4, r7, c0, c0, 5 @ VMPIDR ++ ++#if !defined(ZIMAGE) && defined(CONFIG_ARM_ARCH_TIMER) ++ @ make CNTP_* and CNTPCT accessible from PL1 ++ mrc p15, 0, r7, c0, c1, 1 @ ID_PFR1 ++ lsr r7, #16 ++ and r7, #0xf ++ cmp r7, #1 ++ bne 1f ++ mrc p15, 4, r7, c14, c1, 0 @ CNTHCTL ++ orr r7, r7, #3 @ PL1PCEN | PL1PCTEN ++ mcr p15, 4, r7, c14, c1, 0 @ CNTHCTL ++ mov r7, #0 ++ mcrr p15, 4, r7, r7, c14 @ CNTVOFF ++ ++ @ Disable virtual timer in case it was counting ++ mrc p15, 0, r7, c14, c3, 1 @ CNTV_CTL ++ bic r7, #1 @ Clear ENABLE ++ mcr p15, 0, r7, c14, c3, 1 @ CNTV_CTL ++1: ++#endif ++ ++#ifdef CONFIG_ARM_GIC_V3 ++ @ Check whether GICv3 system registers are available ++ mrc p15, 0, r7, c0, c1, 1 @ ID_PFR1 ++ ubfx r7, r7, #28, #4 ++ cmp r7, #1 ++ bne 2f ++ ++ @ Enable system register accesses ++ mrc p15, 4, r7, c12, c9, 5 @ ICC_HSRE ++ orr r7, r7, #(ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_SRE) ++ mcr p15, 4, r7, c12, c9, 5 @ ICC_HSRE ++ isb ++ ++ @ SRE bit could be forced to 0 by firmware. ++ @ Check whether it sticks before accessing any other sysreg ++ mrc p15, 4, r7, c12, c9, 5 @ ICC_HSRE ++ tst r7, #ICC_SRE_EL2_SRE ++ beq 2f ++ mov r7, #0 ++ mcr p15, 4, r7, c12, c11, 0 @ ICH_HCR ++2: ++#endif ++ ++ bx lr @ The boot CPU mode is left in r4. ++ENDPROC(__hyp_stub_install_secondary) ++ ++__hyp_stub_do_trap: ++ teq r0, #HVC_SET_VECTORS ++ bne 1f ++ mcr p15, 4, r1, c12, c0, 0 @ set HVBAR ++ b __hyp_stub_exit ++ ++1: teq r0, #HVC_SOFT_RESTART ++ bne 1f ++ bx r1 ++ ++1: teq r0, #HVC_RESET_VECTORS ++ beq __hyp_stub_exit ++ ++ ldr r0, =HVC_STUB_ERR ++ __ERET ++ ++__hyp_stub_exit: ++ mov r0, #0 ++ __ERET ++ENDPROC(__hyp_stub_do_trap) ++ ++/* ++ * __hyp_set_vectors: Call this after boot to set the initial hypervisor ++ * vectors as part of hypervisor installation. On an SMP system, this should ++ * be called on each CPU. ++ * ++ * r0 must be the physical address of the new vector table (which must lie in ++ * the bottom 4GB of physical address space. ++ * ++ * r0 must be 32-byte aligned. ++ * ++ * Before calling this, you must check that the stub hypervisor is installed ++ * everywhere, by waiting for any secondary CPUs to be brought up and then ++ * checking that BOOT_CPU_MODE_HAVE_HYP(__boot_cpu_mode) is true. ++ * ++ * If not, there is a pre-existing hypervisor, some CPUs failed to boot, or ++ * something else went wrong... in such cases, trying to install a new ++ * hypervisor is unlikely to work as desired. ++ * ++ * When you call into your shiny new hypervisor, sp_hyp will contain junk, ++ * so you will need to set that to something sensible at the new hypervisor's ++ * initialisation entry point. ++ */ ++ENTRY(__hyp_set_vectors) ++ mov r1, r0 ++ mov r0, #HVC_SET_VECTORS ++ __HVC(0) ++ ret lr ++ENDPROC(__hyp_set_vectors) ++ ++ENTRY(__hyp_soft_restart) ++ mov r1, r0 ++ mov r0, #HVC_SOFT_RESTART ++ __HVC(0) ++ ret lr ++ENDPROC(__hyp_soft_restart) ++ ++ENTRY(__hyp_reset_vectors) ++ mov r0, #HVC_RESET_VECTORS ++ __HVC(0) ++ ret lr ++ENDPROC(__hyp_reset_vectors) ++ ++#ifndef ZIMAGE ++.align 2 ++.L__boot_cpu_mode_offset: ++ .long __boot_cpu_mode - . ++#endif ++ ++.align 5 ++ENTRY(__hyp_stub_vectors) ++__hyp_stub_reset: W(b) . ++__hyp_stub_und: W(b) . ++__hyp_stub_svc: W(b) . ++__hyp_stub_pabort: W(b) . ++__hyp_stub_dabort: W(b) . ++__hyp_stub_trap: W(b) __hyp_stub_do_trap ++__hyp_stub_irq: W(b) . ++__hyp_stub_fiq: W(b) . ++ENDPROC(__hyp_stub_vectors) ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/compressed/lib1funcs.S b/arch/arm/boot/compressed/lib1funcs.S +--- a/arch/arm/boot/compressed/lib1funcs.S 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/compressed/lib1funcs.S 2018-02-27 17:12:26.632705957 +0800 +@@ -0,0 +1,371 @@ ++/* ++ * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines ++ * ++ * Author: Nicolas Pitre ++ * - contributed to gcc-3.4 on Sep 30, 2003 ++ * - adapted for the Linux kernel on Oct 2, 2003 ++ */ ++ ++/* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc. ++ ++This file is free software; you can redistribute it and/or modify it ++under the terms of the GNU General Public License as published by the ++Free Software Foundation; either version 2, or (at your option) any ++later version. ++ ++In addition to the permissions in the GNU General Public License, the ++Free Software Foundation gives you unlimited permission to link the ++compiled version of this file into combinations with other programs, ++and to distribute those combinations without any restriction coming ++from the use of this file. (The General Public License restrictions ++do apply in other respects; for example, they cover modification of ++the file, and distribution when not linked into a combine ++executable.) ++ ++This file is distributed in the hope that it will be useful, but ++WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program; see the file COPYING. If not, write to ++the Free Software Foundation, 59 Temple Place - Suite 330, ++Boston, MA 02111-1307, USA. */ ++ ++ ++#include ++#include ++#include ++ ++.macro ARM_DIV_BODY dividend, divisor, result, curbit ++ ++#if __LINUX_ARM_ARCH__ >= 5 ++ ++ clz \curbit, \divisor ++ clz \result, \dividend ++ sub \result, \curbit, \result ++ mov \curbit, #1 ++ mov \divisor, \divisor, lsl \result ++ mov \curbit, \curbit, lsl \result ++ mov \result, #0 ++ ++#else ++ ++ @ Initially shift the divisor left 3 bits if possible, ++ @ set curbit accordingly. This allows for curbit to be located ++ @ at the left end of each 4 bit nibbles in the division loop ++ @ to save one loop in most cases. ++ tst \divisor, #0xe0000000 ++ moveq \divisor, \divisor, lsl #3 ++ moveq \curbit, #8 ++ movne \curbit, #1 ++ ++ @ Unless the divisor is very big, shift it up in multiples of ++ @ four bits, since this is the amount of unwinding in the main ++ @ division loop. Continue shifting until the divisor is ++ @ larger than the dividend. ++1: cmp \divisor, #0x10000000 ++ cmplo \divisor, \dividend ++ movlo \divisor, \divisor, lsl #4 ++ movlo \curbit, \curbit, lsl #4 ++ blo 1b ++ ++ @ For very big divisors, we must shift it a bit at a time, or ++ @ we will be in danger of overflowing. ++1: cmp \divisor, #0x80000000 ++ cmplo \divisor, \dividend ++ movlo \divisor, \divisor, lsl #1 ++ movlo \curbit, \curbit, lsl #1 ++ blo 1b ++ ++ mov \result, #0 ++ ++#endif ++ ++ @ Division loop ++1: cmp \dividend, \divisor ++ subhs \dividend, \dividend, \divisor ++ orrhs \result, \result, \curbit ++ cmp \dividend, \divisor, lsr #1 ++ subhs \dividend, \dividend, \divisor, lsr #1 ++ orrhs \result, \result, \curbit, lsr #1 ++ cmp \dividend, \divisor, lsr #2 ++ subhs \dividend, \dividend, \divisor, lsr #2 ++ orrhs \result, \result, \curbit, lsr #2 ++ cmp \dividend, \divisor, lsr #3 ++ subhs \dividend, \dividend, \divisor, lsr #3 ++ orrhs \result, \result, \curbit, lsr #3 ++ cmp \dividend, #0 @ Early termination? ++ movnes \curbit, \curbit, lsr #4 @ No, any more bits to do? ++ movne \divisor, \divisor, lsr #4 ++ bne 1b ++ ++.endm ++ ++ ++.macro ARM_DIV2_ORDER divisor, order ++ ++#if __LINUX_ARM_ARCH__ >= 5 ++ ++ clz \order, \divisor ++ rsb \order, \order, #31 ++ ++#else ++ ++ cmp \divisor, #(1 << 16) ++ movhs \divisor, \divisor, lsr #16 ++ movhs \order, #16 ++ movlo \order, #0 ++ ++ cmp \divisor, #(1 << 8) ++ movhs \divisor, \divisor, lsr #8 ++ addhs \order, \order, #8 ++ ++ cmp \divisor, #(1 << 4) ++ movhs \divisor, \divisor, lsr #4 ++ addhs \order, \order, #4 ++ ++ cmp \divisor, #(1 << 2) ++ addhi \order, \order, #3 ++ addls \order, \order, \divisor, lsr #1 ++ ++#endif ++ ++.endm ++ ++ ++.macro ARM_MOD_BODY dividend, divisor, order, spare ++ ++#if __LINUX_ARM_ARCH__ >= 5 ++ ++ clz \order, \divisor ++ clz \spare, \dividend ++ sub \order, \order, \spare ++ mov \divisor, \divisor, lsl \order ++ ++#else ++ ++ mov \order, #0 ++ ++ @ Unless the divisor is very big, shift it up in multiples of ++ @ four bits, since this is the amount of unwinding in the main ++ @ division loop. Continue shifting until the divisor is ++ @ larger than the dividend. ++1: cmp \divisor, #0x10000000 ++ cmplo \divisor, \dividend ++ movlo \divisor, \divisor, lsl #4 ++ addlo \order, \order, #4 ++ blo 1b ++ ++ @ For very big divisors, we must shift it a bit at a time, or ++ @ we will be in danger of overflowing. ++1: cmp \divisor, #0x80000000 ++ cmplo \divisor, \dividend ++ movlo \divisor, \divisor, lsl #1 ++ addlo \order, \order, #1 ++ blo 1b ++ ++#endif ++ ++ @ Perform all needed subtractions to keep only the reminder. ++ @ Do comparisons in batch of 4 first. ++ subs \order, \order, #3 @ yes, 3 is intended here ++ blt 2f ++ ++1: cmp \dividend, \divisor ++ subhs \dividend, \dividend, \divisor ++ cmp \dividend, \divisor, lsr #1 ++ subhs \dividend, \dividend, \divisor, lsr #1 ++ cmp \dividend, \divisor, lsr #2 ++ subhs \dividend, \dividend, \divisor, lsr #2 ++ cmp \dividend, \divisor, lsr #3 ++ subhs \dividend, \dividend, \divisor, lsr #3 ++ cmp \dividend, #1 ++ mov \divisor, \divisor, lsr #4 ++ subges \order, \order, #4 ++ bge 1b ++ ++ tst \order, #3 ++ teqne \dividend, #0 ++ beq 5f ++ ++ @ Either 1, 2 or 3 comparison/subtractions are left. ++2: cmn \order, #2 ++ blt 4f ++ beq 3f ++ cmp \dividend, \divisor ++ subhs \dividend, \dividend, \divisor ++ mov \divisor, \divisor, lsr #1 ++3: cmp \dividend, \divisor ++ subhs \dividend, \dividend, \divisor ++ mov \divisor, \divisor, lsr #1 ++4: cmp \dividend, \divisor ++ subhs \dividend, \dividend, \divisor ++5: ++.endm ++ ++ ++#ifdef CONFIG_ARM_PATCH_IDIV ++ .align 3 ++#endif ++ ++ENTRY(__udivsi3) ++ENTRY(__aeabi_uidiv) ++UNWIND(.fnstart) ++ ++ subs r2, r1, #1 ++ reteq lr ++ bcc Ldiv0 ++ cmp r0, r1 ++ bls 11f ++ tst r1, r2 ++ beq 12f ++ ++ ARM_DIV_BODY r0, r1, r2, r3 ++ ++ mov r0, r2 ++ ret lr ++ ++11: moveq r0, #1 ++ movne r0, #0 ++ ret lr ++ ++12: ARM_DIV2_ORDER r1, r2 ++ ++ mov r0, r0, lsr r2 ++ ret lr ++ ++UNWIND(.fnend) ++ENDPROC(__udivsi3) ++ENDPROC(__aeabi_uidiv) ++ ++ENTRY(__umodsi3) ++UNWIND(.fnstart) ++ ++ subs r2, r1, #1 @ compare divisor with 1 ++ bcc Ldiv0 ++ cmpne r0, r1 @ compare dividend with divisor ++ moveq r0, #0 ++ tsthi r1, r2 @ see if divisor is power of 2 ++ andeq r0, r0, r2 ++ retls lr ++ ++ ARM_MOD_BODY r0, r1, r2, r3 ++ ++ ret lr ++ ++UNWIND(.fnend) ++ENDPROC(__umodsi3) ++ ++#ifdef CONFIG_ARM_PATCH_IDIV ++ .align 3 ++#endif ++ ++ENTRY(__divsi3) ++ENTRY(__aeabi_idiv) ++UNWIND(.fnstart) ++ ++ cmp r1, #0 ++ eor ip, r0, r1 @ save the sign of the result. ++ beq Ldiv0 ++ rsbmi r1, r1, #0 @ loops below use unsigned. ++ subs r2, r1, #1 @ division by 1 or -1 ? ++ beq 10f ++ movs r3, r0 ++ rsbmi r3, r0, #0 @ positive dividend value ++ cmp r3, r1 ++ bls 11f ++ tst r1, r2 @ divisor is power of 2 ? ++ beq 12f ++ ++ ARM_DIV_BODY r3, r1, r0, r2 ++ ++ cmp ip, #0 ++ rsbmi r0, r0, #0 ++ ret lr ++ ++10: teq ip, r0 @ same sign ? ++ rsbmi r0, r0, #0 ++ ret lr ++ ++11: movlo r0, #0 ++ moveq r0, ip, asr #31 ++ orreq r0, r0, #1 ++ ret lr ++ ++12: ARM_DIV2_ORDER r1, r2 ++ ++ cmp ip, #0 ++ mov r0, r3, lsr r2 ++ rsbmi r0, r0, #0 ++ ret lr ++ ++UNWIND(.fnend) ++ENDPROC(__divsi3) ++ENDPROC(__aeabi_idiv) ++ ++ENTRY(__modsi3) ++UNWIND(.fnstart) ++ ++ cmp r1, #0 ++ beq Ldiv0 ++ rsbmi r1, r1, #0 @ loops below use unsigned. ++ movs ip, r0 @ preserve sign of dividend ++ rsbmi r0, r0, #0 @ if negative make positive ++ subs r2, r1, #1 @ compare divisor with 1 ++ cmpne r0, r1 @ compare dividend with divisor ++ moveq r0, #0 ++ tsthi r1, r2 @ see if divisor is power of 2 ++ andeq r0, r0, r2 ++ bls 10f ++ ++ ARM_MOD_BODY r0, r1, r2, r3 ++ ++10: cmp ip, #0 ++ rsbmi r0, r0, #0 ++ ret lr ++ ++UNWIND(.fnend) ++ENDPROC(__modsi3) ++ ++#ifdef CONFIG_AEABI ++ ++ENTRY(__aeabi_uidivmod) ++UNWIND(.fnstart) ++UNWIND(.save {r0, r1, ip, lr} ) ++ ++ stmfd sp!, {r0, r1, ip, lr} ++ bl __aeabi_uidiv ++ ldmfd sp!, {r1, r2, ip, lr} ++ mul r3, r0, r2 ++ sub r1, r1, r3 ++ ret lr ++ ++UNWIND(.fnend) ++ENDPROC(__aeabi_uidivmod) ++ ++ENTRY(__aeabi_idivmod) ++UNWIND(.fnstart) ++UNWIND(.save {r0, r1, ip, lr} ) ++ stmfd sp!, {r0, r1, ip, lr} ++ bl __aeabi_idiv ++ ldmfd sp!, {r1, r2, ip, lr} ++ mul r3, r0, r2 ++ sub r1, r1, r3 ++ ret lr ++ ++UNWIND(.fnend) ++ENDPROC(__aeabi_idivmod) ++ ++#endif ++ ++Ldiv0: ++UNWIND(.fnstart) ++UNWIND(.pad #4) ++UNWIND(.save {lr}) ++ str lr, [sp, #-8]! ++ bl __div0 ++ mov r0, #0 @ About as wrong as it could be. ++ ldr pc, [sp], #8 ++UNWIND(.fnend) ++ENDPROC(Ldiv0) +Binary files a/arch/arm/boot/compressed/piggy_data and b/arch/arm/boot/compressed/piggy_data differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +--- a/arch/arm/boot/dts/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/arch/arm/boot/dts/Makefile 2018-05-10 11:31:28.285398226 +0800 +@@ -1069,6 +1069,24 @@ dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dt + dtb-$(CONFIG_ARCH_ASPEED) += aspeed-bmc-opp-palmetto.dtb \ + aspeed-bmc-opp-romulus.dtb \ + aspeed-ast2500-evb.dtb ++dtb-$(CONFIG_MACH_HX4) += bcm956340.dtb ++dtb-$(CONFIG_MACH_KT2) += bcm956450.dtb ++dtb-$(CONFIG_MACH_GH) += bcm95341x.dtb ++dtb-$(CONFIG_MACH_GH2) += bcm956170.dtb ++dtb-$(CONFIG_MACH_SB2) += bcm956260.dtb ++dtb-$(CONFIG_MACH_HR3) += \ ++ bcm956160.dtb \ ++ bcm953444.dtb ++dtb-$(CONFIG_MACH_WH2) += bcm953547.dtb ++dtb-$(CONFIG_XGS_IPROC_ARM32_PLATFORM) += \ ++ bcm956340.dtb \ ++ bcm956450.dtb \ ++ bcm95341x.dtb \ ++ bcm956260.dtb \ ++ bcm956160.dtb \ ++ bcm953444.dtb \ ++ bcm956170.dtb \ ++ bcm953547.dtb + endif + + dtstree := $(srctree)/$(src) +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-greyhound.dtsi b/arch/arm/boot/dts/bcm-greyhound.dtsi +--- a/arch/arm/boot/dts/bcm-greyhound.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-greyhound.dtsi 2018-05-10 11:31:28.309398252 +0800 +@@ -0,0 +1,408 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom GH iProc"; ++ compatible = "brcm,greyhound"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ /*clocks = <&osc_50M>;*/ /* 50MHZ crystal/oscillator */ ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ /* 50MHZ crystal/oscillator clock source */ ++ /* ++ osc_50M: oscillator_50M { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <50000000>; ++ }; ++ */ ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@0x1800fc00 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk"; ++ clocks = <&osc>; ++ reg = <0x1800fc00 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18020000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18020000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18021000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18021000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18042000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x18042000 0x1000>, ++ <0x18110000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@1800a000 { ++ compatible = "brcm,iproc-gpio-ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x1800a000 0x50>; ++ ngpios = <12>; ++ pin-reg-bit-shift = <4>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy-gh"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18111000 0x1000>; ++ vbus-gpio = <&gpio_ccg 6 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@18048000 { ++ compatible = "generic-ehci"; ++ reg = <0x18048000 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ ohci0: usb@18048800 { ++ compatible = "generic-ohci"; ++ reg = <0x18048800 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ /* Over Current Protect Mode fix */ ++ iproc-ocpm-fix; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@1804c000 { ++ compatible = "brcm,usbd-xgs-iproc"; ++ reg = <0x1804c000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18046000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18046000 0x600>, ++ <0xf8105408 0x10>, ++ <0x18046f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,spi-bcm-qspi", "brcm,spi-xgs-iproc-qspi"; ++ reg = <0x18047200 0x188>, ++ <0x18047000 0x124>, ++ <0xf8106408 0x004>, ++ <0x180473a0 0x01c>, ++ <0x1800e000 0x004>; ++ reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg", "cru_ctrl"; ++ interrupts = ; ++ num-cs = <2>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18008000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18008000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_ext: mdio_ext@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <2>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ pnor_flash: pnor_flash@18045000 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "brcm,iproc-nor"; ++ reg = nor_regs: <0x18045000 0x1000>, ++ nor_mem: <0xE8000000 0x8000000>, ++ nor_strap: <0x18000a5c 0x4>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18032000 { ++ compatible = "brcm,iproc-rng200"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18032000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18009000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18009000 0x1000>, ++ iproc_reset_reg: <0x1800f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18040000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = pl330_base: <0x18040000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@03200000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x03200000 0x100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x20000000, ++ * cpu addr 0x20000000, size 0x0 0x20000000 ++ */ ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; ++ wa-list = "pcie_rc", "pcie_perst"; ++ status = "disabled"; ++ ++ msi-parent = <&msi0>; ++ msi0: msi@18012000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ }; ++ }; ++ ++ dmu_pcu: dmu_pcu@1800f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0x1800f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0x1800fc00 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ reg = idm0: <0x18100000 0x100000>, ++ idm1: <0xf8100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-greyhound2.dtsi b/arch/arm/boot/dts/bcm-greyhound2.dtsi +--- a/arch/arm/boot/dts/bcm-greyhound2.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-greyhound2.dtsi 2018-05-10 11:31:28.309398252 +0800 +@@ -0,0 +1,429 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom GH2 iProc"; ++ compatible = "brcm,greyhound2"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@0x1800fc00 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk"; ++ clocks = <&osc>; ++ reg = <0x1800fc00 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18020000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18020000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18021000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18021000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18042000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x18042000 0x1000>, ++ <0x18110000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac1: ethernet@1804a000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x1804a000 0x1000>, ++ <0x1811f000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@1800a000 { ++ compatible = "brcm,iproc-gpio-ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x1800a000 0x50>; ++ ngpios = <12>; ++ pin-reg-bit-shift = <4>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy-gh2"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18111000 0x1000>, ++ idm_utmih: <0x18049500 0x100>; ++ vbus-gpio = <&gpio_ccg 6 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@18048000 { ++ compatible = "generic-ehci"; ++ reg = <0x18048000 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ ohci0: usb@18048800 { ++ compatible = "generic-ohci"; ++ reg = <0x18048800 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ /* Over Current Protect Mode fix */ ++ iproc-ocpm-fix; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@1804c000 { ++ compatible = "brcm,usbd-xgs-iproc"; ++ reg = <0x1804c000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18046000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18046000 0x600>, ++ <0xf8105408 0x10>, ++ <0x18046f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,spi-bcm-qspi", "brcm,spi-xgs-iproc-qspi"; ++ reg = <0x18047200 0x188>, ++ <0x18047000 0x124>, ++ <0xf8106408 0x004>, ++ <0x180473a0 0x01c>, ++ <0x1800e000 0x004>; ++ reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg", "cru_ctrl"; ++ interrupts = ; ++ num-cs = <2>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18008000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18008000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ ccg_mdio_int: ccg_mdio_int@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_int: mdio_int@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_ext: mdio_ext@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <2>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ pnor_flash: pnor_flash@18045000 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "brcm,iproc-nor"; ++ reg = nor_regs: <0x18045000 0x1000>, ++ nor_mem: <0xE8000000 0x8000000>, ++ nor_strap: <0x18000a5c 0x4>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18032000 { ++ compatible = "brcm,iproc-rng200"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18032000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18009000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18009000 0x1000>, ++ iproc_reset_reg: <0x1800f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18018000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = pl330_base: <0x18018000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ crypto: crypto@03100000 { ++ compatible = "brcm,iproc-crypto"; ++ reg = axi: <0x03100000 0x100>, /* SPUM AXI registers */ ++ apb: <0x18037000 0x100>, /* SPUM control registers */ ++ idm: <0x1811a000 0x1000>; /* Crypto control registers */ ++ brcm,max-pkt-size = <65536>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@03200000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x03200000 0x100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x20000000, ++ * cpu addr 0x20000000, size 0x0 0x20000000 ++ */ ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; ++ wa-list = "pcie_rc", "pcie_perst"; ++ status = "disabled"; ++ ++ msi-parent = <&msi0>; ++ msi0: msi@18012000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ }; ++ }; ++ ++ dmu_pcu: dmu_pcu@1800f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0x1800f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0x1800fc00 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ reg = idm0: <0x18100000 0x100000>, ++ idm1: <0xf8100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-helix4.dtsi b/arch/arm/boot/dts/bcm-helix4.dtsi +--- a/arch/arm/boot/dts/bcm-helix4.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-helix4.dtsi 2018-05-10 11:31:28.309398252 +0800 +@@ -0,0 +1,483 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom HX4 iProc"; ++ compatible = "brcm,helix4"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ ++ cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ enable-method = "brcm,bcm-nsp-smp"; ++ secondary-boot-reg = <0xffff042c>; ++ reg = <0x1>; ++ }; ++ }; ++ ++ mpcore { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ /*arm,parity-enable; ++ interrupts = ;*/ ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@0x1803fc00 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk", "axi-clk-hx4"; ++ clocks = <&osc>; ++ reg = <0x1803fc00 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18000300 { ++ compatible = "ns16550a"; ++ reg = <0x18000300 0x100>; ++ interrupts = ; ++ clock-frequency = <62500000>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18000400 { ++ compatible = "ns16550a"; ++ reg = <0x18000400 0x100>; ++ interrupts = ; ++ clock-frequency = <62500000>; ++ status = "disabled"; ++ }; ++ ++ uart2: serial@18037000 { ++ compatible = "ns16550a"; ++ reg = <0x18037000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_cca: gpio@18000060 { ++ compatible = "brcm,iproc-gpio-cca"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x18000060 0x50>, ++ intr: <0x18000000 0x50>; ++ ngpios = <8>; ++ pin-reg-bit-shift = <0>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18022000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x18022000 0x1000>, ++ <0x18110000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac1: ethernet@18023000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x18023000 0x1000>, ++ <0x18111000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18026000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18026000 0x600>, ++ <0x1811b408 0x10>, ++ <0x18026f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ }; ++ ++ qspi: spi@18027000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,spi-bcm-qspi", "brcm,spi-xgs-iproc-qspi"; ++ reg = <0x18027200 0x188>, ++ <0x18027000 0x124>, ++ <0x1811c408 0x004>, ++ <0x180273a0 0x01c>, ++ <0x1803e000 0x004>; ++ reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg", "cru_ctrl"; ++ interrupts = ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ interrupt-names = ++ "spi_lr_fullness_reached", ++ "spi_lr_session_aborted", ++ "spi_lr_impatient", ++ "spi_lr_session_done", ++ "spi_lr_overread", ++ "mspi_done", ++ "mspi_halted"; ++ num-cs = <2>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy-hx4"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18116000 0x1000>; ++ vbus-gpio = <&gpio_cca 1 GPIO_ACTIVE_LOW>; ++ usbdev-gpio = <&gpio_cca 0 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@1802a000 { ++ compatible = "generic-ehci"; ++ reg = <0x1802a000 0x1000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@18042000 { ++ compatible = "brcm,usbd-xgs-hx4"; ++ reg = <0x18042000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18038000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18038000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@1803b000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x1803b000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@18032000 { ++ compatible = "brcm,iproc-ccb-mdio"; ++ reg = <0x18032000 0x1000>, ++ <0x1803fc3c 0x4>; ++ reg-names = "mdio-base", "iproc-mdio-enable"; ++ iproc-mdio-sel-bit = <4>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ mdio_ext: mdio_ext@18032000 { ++ compatible = "brcm,iproc-ccb-mdio"; ++ reg = <0x18032000 0x1000>, ++ <0x1803fc3c 0x4>; ++ reg-names = "mdio-base", "iproc-mdio-enable"; ++ iproc-mdio-sel-bit = <4>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18033000 { ++ compatible = "brcm,iproc-rng100"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18033000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@0x18039000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18039000 0x1000>, ++ iproc_reset_reg: <0x1803f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18020000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = pl330_base: <0x18020000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ /*arm,primecell-periphid = <0x00041330>;*/ ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@48000000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x48000000 0x40000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x08000000, ++ * cpu addr 0x08000000, size 0x0 0x08000000 ++ */ ++ ranges = <0x82000000 0 0x08000000 0x08000000 0 0x08000000>; ++ wa-list = "pcie_wrong_gen2"; ++ status = "disabled"; ++ ++ msi-parent = <&msi0>; ++ msi0: msi@18012000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ brcm,pcie-msi-inten; ++ }; ++ }; ++ ++ pcie1: pcie@18013000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18013000 0x1000>; ++ linux,pci-domain = <1>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x40000000, ++ * cpu addr 0x40000000, size 0x0 0x08000000 ++ */ ++ ranges = <0x82000000 0 0x40000000 0x40000000 0 0x08000000>; ++ wa-list = "pcie_wrong_gen2"; ++ status = "disabled"; ++ ++ msi-parent = <&msi1>; ++ msi1: msi@18013000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ brcm,pcie-msi-inten; ++ }; ++ }; ++ ++ dmu_pcu: dmu_pcu@1803f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x1803f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1803fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x1803fc00 0x100>; ++ /* offset to 0x1803fc00, ctrl bit, mdio bit */ ++ amac-serdes-mdio-ctrl-sel = <0x3c>, <0x2>, <0x3>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-hurricane3.dtsi b/arch/arm/boot/dts/bcm-hurricane3.dtsi +--- a/arch/arm/boot/dts/bcm-hurricane3.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-hurricane3.dtsi 2018-05-10 11:31:28.309398252 +0800 +@@ -0,0 +1,416 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom HR3 iProc"; ++ compatible = "brcm,hurricane3"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ /*clocks = <&osc_50M>;*/ /* 50MHZ crystal/oscillator */ ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ /* 50MHZ crystal/oscillator clock source */ ++ /* ++ osc_50M: oscillator_50M { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <50000000>; ++ }; ++ */ ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@1800fc00 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk"; ++ clocks = <&osc>; ++ reg = <0x1800fc00 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18020000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18020000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18021000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18021000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18042000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x18042000 0x1000>, ++ <0x18110000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@1800a000 { ++ compatible = "brcm,iproc-gpio-ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x1800a000 0x50>; ++ ngpios = <12>; ++ pin-reg-bit-shift = <4>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy@1800fc40 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy-gh"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18111000 0x1000>; ++ vbus-gpio = <&gpio_ccg 3 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@18048000 { ++ compatible = "generic-ehci"; ++ reg = <0x18048000 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ ohci0: usb@18048800 { ++ compatible = "generic-ohci"; ++ reg = <0x18048800 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ /* Over Current Protect Mode fix */ ++ iproc-ocpm-fix; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@1804c000 { ++ compatible = "brcm,usbd-xgs-iproc"; ++ reg = <0x1804c000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ sdio: sdio@18041000 { ++ compatible = "brcm,iproc-hr3-sdio"; ++ reg = <0x18041000 0x1000>, ++ <0x18116408 0x1000>; ++ reg-names = "sdio", "iproc-idm"; ++ interrupts = ; ++ bus-width = <8>; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18046000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18046000 0x600>, ++ <0x1811d408 0x10>, ++ <0x18046f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,spi-bcm-qspi", "brcm,spi-xgs-iproc-qspi"; ++ reg = <0x18047200 0x188>, ++ <0x18047000 0x124>, ++ <0x1811f408 0x004>, ++ <0x180473a0 0x01c>, ++ <0x1800e000 0x004>; ++ reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg", "cru_ctrl"; ++ interrupts = ; ++ num-cs = <2>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18008000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18008000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_ext: mdio_ext { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <2>; ++ bus-type = "external"; ++ /* Currently clocks is not used by driver */ ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ pnor_flash: pnor_flash@18045000 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "brcm,iproc-nor"; ++ reg = nor_regs: <0x18045000 0x1000>, ++ nor_mem: <0xE8000000 0x8000000>, ++ nor_strap: <0x18000a5c 0x4>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18032000 { ++ compatible = "brcm,iproc-rng200"; ++ reg = <0x18032000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18009000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18009000 0x1000>, ++ iproc_reset_reg: <0x1800f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18018000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = pl330_base: <0x18018000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ /*arm,primecell-periphid = <0x00041330>;*/ ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@03200000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x03200000 0x100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x20000000, ++ * cpu addr 0x20000000, size 0x0 0x20000000 ++ */ ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; ++ wa-list = "pcie_rc", "pcie_perst"; ++ status = "disabled"; ++ ++ msi-parent = <&msi0>; ++ msi0: msi@18012000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ }; ++ }; ++ ++ dmu_pcu: dmu_pcu@1800f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0x1800f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0x1800fc00 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ reg = <0x18100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-katana2.dtsi b/arch/arm/boot/dts/bcm-katana2.dtsi +--- a/arch/arm/boot/dts/bcm-katana2.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-katana2.dtsi 2018-05-10 11:31:28.309398252 +0800 +@@ -0,0 +1,480 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom KT2 iProc"; ++ compatible = "brcm,katana2"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ ++ cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ enable-method = "brcm,bcm-nsp-smp"; ++ secondary-boot-reg = <0xffff042c>; ++ reg = <0x1>; ++ }; ++ }; ++ ++ mpcore { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: axi_clk_fixed_495M { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <495000000>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18000300 { ++ compatible = "ns16550a"; ++ reg = <0x18000300 0x100>; ++ interrupts = ; ++ clock-frequency = <61875000>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18000400 { ++ compatible = "ns16550a"; ++ reg = <0x18000400 0x100>; ++ interrupts = ; ++ clock-frequency = <61875000>; ++ status = "disabled"; ++ }; ++ ++ uart2: serial@18037000 { ++ compatible = "ns16550a"; ++ reg = <0x18037000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_cca: gpio@18000060 { ++ compatible = "brcm,iproc-gpio-cca"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x18000060 0x50>, ++ intr: <0x18000000 0x50>; ++ ngpios = <8>; ++ pin-reg-bit-shift = <0>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18022000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x18022000 0x1000>, ++ <0x18110000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac1: ethernet@18023000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x18023000 0x1000>, ++ <0x18111000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18026000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18026000 0x600>, ++ <0x1811b408 0x10>, ++ <0x18026f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ }; ++ ++ qspi: spi@18027000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,spi-bcm-qspi", "brcm,spi-xgs-iproc-qspi"; ++ reg = <0x18027200 0x188>, ++ <0x18027000 0x124>, ++ <0x1811c408 0x004>, ++ <0x180273a0 0x01c>, ++ <0x1803e000 0x004>; ++ reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg", "cru_ctrl"; ++ interrupts = ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ interrupt-names = ++ "spi_lr_fullness_reached", ++ "spi_lr_session_aborted", ++ "spi_lr_impatient", ++ "spi_lr_session_done", ++ "spi_lr_overread", ++ "mspi_done", ++ "mspi_halted"; ++ num-cs = <2>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy-kt2"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18116000 0x1000>; ++ vbus-gpio = <&gpio_cca 1 GPIO_ACTIVE_LOW>; ++ usbdev-gpio = <&gpio_cca 0 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@1802a000 { ++ compatible = "generic-ehci"; ++ reg = <0x1802a000 0x1000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@18042000 { ++ compatible = "brcm,usbd-xgs-hx4"; ++ reg = <0x18042000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@0x18038000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18038000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@1803b000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x1803b000 0x100>; ++ interrupts = ; ++ #bus-id = <1>; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@18032000 { ++ compatible = "brcm,iproc-ccb-mdio"; ++ reg = <0x18032000 0x1000>, ++ <0x1803fc24 0x4>; ++ reg-names = "mdio-base", "iproc-mdio-enable"; ++ iproc-mdio-sel-bit = <3>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ mdio_ext: mdio_ext@18032000 { ++ compatible = "brcm,iproc-ccb-mdio"; ++ reg = <0x18032000 0x1000>, ++ <0x1803fc24 0x4>; ++ reg-names = "mdio-base", "iproc-mdio-enable"; ++ iproc-mdio-sel-bit = <3>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18033000 { ++ compatible = "brcm,iproc-rng100"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18033000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18039000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18039000 0x1000>, ++ iproc_reset_reg: <0x1803f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18020000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = pl330_base: <0x18020000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ /*arm,primecell-periphid = <0x00041330>;*/ ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@48000000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x48000000 0x40000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x08000000, ++ * cpu addr 0x08000000, size 0x0 0x08000000 ++ */ ++ ranges = <0x82000000 0 0x08000000 0x08000000 0 0x08000000>; ++ wa-list = "pcie_wrong_gen2"; ++ status = "disabled"; ++ ++ msi-parent = <&msi0>; ++ msi0: msi@18012000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ brcm,pcie-msi-inten; ++ }; ++ }; ++ ++ pcie1: pcie@18013000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18013000 0x1000>; ++ linux,pci-domain = <1>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x40000000, ++ * cpu addr 0x40000000, size 0x0 0x08000000 ++ */ ++ ranges = <0x82000000 0 0x40000000 0x40000000 0 0x08000000>; ++ wa-list = "pcie_wrong_gen2"; ++ status = "disabled"; ++ ++ msi-parent = <&msi1>; ++ msi1: msi@18013000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ brcm,pcie-msi-inten; ++ }; ++ }; ++ ++ dmu_pcu: dmu_pcu@1803f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x1803f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1803fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x1803fc00 0x100>; ++ /* offset to 0x1803fc00, ctrl bit, mdio bit */ ++ amac-serdes-mdio-ctrl-sel = <0x24>, <0x1>, <0x2>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-saber2.dtsi b/arch/arm/boot/dts/bcm-saber2.dtsi +--- a/arch/arm/boot/dts/bcm-saber2.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-saber2.dtsi 2018-05-10 11:31:28.309398252 +0800 +@@ -0,0 +1,396 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++/ { ++ model = "Broadcom SB2 iProc"; ++ compatible = "brcm,saber2"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator_25M { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ osc_1: oscillator_50M { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <50000000>; ++ }; ++ ++ periph_clk: periph_clk@19000000 { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@1800fc50 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk", "axi-clk-sb2"; ++ clocks = <&osc_1>; ++ reg = <0x1800fc50 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18020000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18020000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18021000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18021000 0x1000>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,spi-bcm-qspi", "brcm,spi-xgs-iproc-qspi"; ++ reg = <0x18047200 0x188>, ++ <0x18047000 0x124>, ++ <0xf8106408 0x004>, ++ <0x180473a0 0x01c>, ++ <0x1800e000 0x004>; ++ reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg", "cru_ctrl"; ++ interrupts = ; ++ num-cs = <2>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18042000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x18042000 0x1000>, ++ <0x18110000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy-sb2"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18111000 0x1000>; ++ vbus-gpio = <&gpio_ccg 1 GPIO_ACTIVE_LOW>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@18048000 { ++ compatible = "generic-ehci"; ++ reg = <0x18048000 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ ohci0: usb@18048800 { ++ compatible = "generic-ohci"; ++ reg = <0x18048800 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@1804c000 { ++ compatible = "brcm,usbd-xgs-iproc"; ++ reg = usb2d: <0x1804c000 0x2000>, ++ idm_usb: <0x18111000 0x1000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@1800a000 { ++ compatible = "brcm,iproc-gpio-ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x1800a000 0x50>; ++ ngpios = <16>; ++ pin-reg-bit-shift = <0>; ++ pin-base = <0>; ++ gpio-controller; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18046000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18046000 0x600>, ++ <0xf8105408 0x10>, ++ <0x18046f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18008000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18008000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>, ++ <0x1800fc40 0x4>; ++ reg-names = "mdio-base", "ipoc-mdio-enable"; ++ iproc-mdio-sel-bit = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ mdio_ext: mdio_ext@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>, ++ <0x1800fc40 0x4>; ++ reg-names = "mdio-base", "iproc-mdio-enable"; ++ iproc-mdio-sel-bit = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18032000 { ++ compatible = "brcm,iproc-rng200"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18032000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18009000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18009000 0x1000>, ++ iproc_reset_reg: <0x1800f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18018000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = pl330_base: <0x18018000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@03200000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x03200000 0x100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x20000000, ++ * cpu addr 0x20000000, size 0x0 0x20000000 ++ */ ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; ++ wa-list = "pcie_rc"; ++ status = "disabled"; ++ ++ msi-parent = <&msi0>; ++ msi0: msi@18012000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ }; ++ }; ++ ++ dmu_pcu: dmu_pcu@1800f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0x1800f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0x1800fc00 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ reg = idm0: <0x18100000 0x100000>, ++ idm1: <0xf8100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-wolfhound2.dtsi b/arch/arm/boot/dts/bcm-wolfhound2.dtsi +--- a/arch/arm/boot/dts/bcm-wolfhound2.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-wolfhound2.dtsi 2018-05-10 11:31:28.309398252 +0800 +@@ -0,0 +1,385 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom HR3 iProc"; ++ compatible = "brcm,hurricane3"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@1800fc00 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk"; ++ clocks = <&osc>; ++ reg = <0x1800fc00 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18020000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18020000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18021000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18021000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18042000 { ++ compatible = "brcm,xgs-wh2-amac"; ++ reg = <0x18042000 0x1000>, ++ <0x18110000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@1800a000 { ++ compatible = "brcm,iproc-gpio-ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x1800a000 0x50>; ++ ngpios = <12>; ++ pin-reg-bit-shift = <4>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy@1800fc40 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy-gh"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18111000 0x1000>; ++ vbus-gpio = <&gpio_ccg 3 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@18048000 { ++ compatible = "generic-ehci"; ++ reg = <0x18048000 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ ohci0: usb@18048800 { ++ compatible = "generic-ohci"; ++ reg = <0x18048800 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ /* Over Current Protect Mode fix */ ++ iproc-ocpm-fix; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@1804c000 { ++ compatible = "brcm,usbd-xgs-iproc"; ++ reg = <0x1804c000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,spi-bcm-qspi", "brcm,spi-xgs-iproc-qspi"; ++ reg = <0x18047200 0x188>, ++ <0x18047000 0x124>, ++ <0x1811f408 0x004>, ++ <0x180473a0 0x01c>, ++ <0x1800e000 0x004>; ++ reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg", "cru_ctrl"; ++ interrupts = ; ++ num-cs = <2>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18008000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18008000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_int0: mdio_int0@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_int1: mdio_int1@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <1>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* CCG mdio */ ++ mdio_int2: mdio_int2@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18032000 { ++ compatible = "brcm,iproc-rng200"; ++ reg = <0x18032000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18009000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18009000 0x1000>, ++ iproc_reset_reg: <0x1800f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18018000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = pl330_base: <0x18018000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ /*arm,primecell-periphid = <0x00041330>;*/ ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@03200000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x03200000 0x100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x20000000, ++ * cpu addr 0x20000000, size 0x0 0x20000000 ++ */ ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; ++ wa-list = "pcie_rc", "pcie_perst"; ++ status = "disabled"; ++ ++ msi-parent = <&msi0>; ++ msi0: msi@18012000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ }; ++ }; ++ ++ dmu_pcu: dmu_pcu@1800f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0x1800f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0x1800fc00 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ reg = <0x18100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +Binary files a/arch/arm/boot/dts/bcm95341x.dtb and b/arch/arm/boot/dts/bcm95341x.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm95341x.dts b/arch/arm/boot/dts/bcm95341x.dts +--- a/arch/arm/boot/dts/bcm95341x.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm95341x.dts 2018-05-10 11:31:28.313398255 +0800 +@@ -0,0 +1,220 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-greyhound.dtsi" ++ ++/ { ++ model = "Broadcom GH SVK (BCM95341x)"; ++ compatible = "brcm,bcm95341x", "brcm,greyhound"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&amac_phy0>; ++ phy-mode = "gmii"; /* "gmii-id", "gmii-rxid" */ ++}; ++ ++&usbphy0 { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy0>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x30000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&pnor_flash { ++ status = "okay"; ++ ++ partition@0 { ++ label = "pboot"; ++ reg = <0x0 0xc0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "penv"; ++ reg = <0xc0000 0x40000>; ++ }; ++ partition@2 { ++ label = "psystem"; ++ reg = <0x100000 0xf00000>; ++ }; ++ partition@3 { ++ label = "prootfs"; ++ reg = <0x1000000 0x1000000>; ++ }; ++ partition@4 { ++ label = "pcustfs"; ++ reg = <0x2000000 0x2000000>; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++ pcie_phy0: pcie_phy@0 { ++ reg = <2>; ++ }; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <24>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; +Binary files a/arch/arm/boot/dts/bcm953444.dtb and b/arch/arm/boot/dts/bcm953444.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm953444.dts b/arch/arm/boot/dts/bcm953444.dts +--- a/arch/arm/boot/dts/bcm953444.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm953444.dts 2018-05-10 11:31:28.313398255 +0800 +@@ -0,0 +1,135 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-hurricane3.dtsi" ++ ++/ { ++ model = "Broadcom HR3 SVK (BCM953444K)"; ++ compatible = "brcm,bcm953444k", "brcm,hurricane3"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&amac_phy0>; ++ phy-mode = "gmii"; /* "gmii-id", "gmii-rxid" */ ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy0>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++ pcie_phy0: pcie_phy@0 { ++ reg = <2>; ++ }; ++}; ++ ++&mdio_ext { ++ #bus-id = <1>; ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <24>; ++ }; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; ++ +Binary files a/arch/arm/boot/dts/bcm953547.dtb and b/arch/arm/boot/dts/bcm953547.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm953547.dts b/arch/arm/boot/dts/bcm953547.dts +--- a/arch/arm/boot/dts/bcm953547.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm953547.dts 2018-05-10 11:31:28.313398255 +0800 +@@ -0,0 +1,167 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-wolfhound2.dtsi" ++ ++/ { ++ model = "Broadcom WH2 SVK (BCM953547K)"; ++ compatible = "brcm,bcm953547k", "brcm,wolfhound2"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&amac_phy0>; ++ phy-mode = "gmii"; /* "gmii-id", "gmii-rxid" */ ++ serdes-phy-handle = <&amac_serdes0>; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy0>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&mdio_int0 { ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <24>; ++ }; ++}; ++ ++&mdio_int1 { ++ status = "okay"; ++ amac_serdes0: amac_serdes@0 { ++ reg = <20>; ++ lane-num = <3>; ++ }; ++}; ++ ++&mdio_int2 { ++ status = "okay"; ++ pcie_phy0: pcie_phy@0 { ++ reg = <2>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; ++ +Binary files a/arch/arm/boot/dts/bcm956160.dtb and b/arch/arm/boot/dts/bcm956160.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956160.dts b/arch/arm/boot/dts/bcm956160.dts +--- a/arch/arm/boot/dts/bcm956160.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm956160.dts 2018-05-10 11:31:28.313398255 +0800 +@@ -0,0 +1,225 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-hurricane3.dtsi" ++ ++/ { ++ model = "Broadcom HR3 SVK (BCM956160K)"; ++ compatible = "brcm,bcm956160k", "brcm,hurricane3"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&amac_phy0>; ++ phy-mode = "gmii"; /* "gmii-id", "gmii-rxid" */ ++}; ++ ++&usbphy0 { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&sdio { ++ status = "okay"; ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy0>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x30000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&pnor_flash { ++ status = "okay"; ++ ++ partition@0 { ++ label = "pboot"; ++ reg = <0x0 0xc0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "penv"; ++ reg = <0xc0000 0x40000>; ++ }; ++ partition@2 { ++ label = "psystem"; ++ reg = <0x100000 0xf00000>; ++ }; ++ partition@3 { ++ label = "prootfs"; ++ reg = <0x1000000 0x1000000>; ++ }; ++ partition@4 { ++ label = "pcustfs"; ++ reg = <0x2000000 0x2000000>; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++ pcie_phy0: pcie_phy@0 { ++ reg = <2>; ++ }; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <24>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; ++ +Binary files a/arch/arm/boot/dts/bcm956170.dtb and b/arch/arm/boot/dts/bcm956170.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956170.dts b/arch/arm/boot/dts/bcm956170.dts +--- a/arch/arm/boot/dts/bcm956170.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm956170.dts 2018-05-10 17:50:42.895946853 +0800 +@@ -0,0 +1,248 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-greyhound2.dtsi" ++ ++/ { ++ model = "Broadcom GH2 SVK (BCM956170)"; ++ compatible = "brcm,bcm956170", "brcm,greyhound2"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&amac_phy0>; ++ phy-mode = "sgmii"; ++ serdes-handle = <&amac_serdes0>; ++}; ++ ++&gmac1 { ++ status = "okay"; ++ phy-handle = <&amac_phy1>; ++ phy-mode = "sgmii"; ++ serdes-handle = <&amac_serdes1>; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy0>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x30000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&pnor_flash { ++ status = "okay"; ++ ++ partition@0 { ++ label = "pboot"; ++ reg = <0x0 0xc0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "penv"; ++ reg = <0xc0000 0x40000>; ++ }; ++ partition@2 { ++ label = "psystem"; ++ reg = <0x100000 0xf00000>; ++ }; ++ partition@3 { ++ label = "prootfs"; ++ reg = <0x1000000 0x1000000>; ++ }; ++ partition@4 { ++ label = "pcustfs"; ++ reg = <0x2000000 0x2000000>; ++ }; ++}; ++ ++&ccg_mdio_int { ++ status = "okay"; ++ pcie_phy0: pcie_phy@0 { ++ reg = <2>; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++ amac_serdes0: amac_serdes@0 { ++ reg = <25>; ++ lane-num = <0>; ++ }; ++ amac_serdes1: amac_serdes@1 { ++ reg = <26>; ++ lane-num = <1>; ++ }; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <16>; ++ }; ++ amac_phy1: amac_phy@1 { ++ reg = <17>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&crypto { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; +Binary files a/arch/arm/boot/dts/bcm956260.dtb and b/arch/arm/boot/dts/bcm956260.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956260.dts b/arch/arm/boot/dts/bcm956260.dts +--- a/arch/arm/boot/dts/bcm956260.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm956260.dts 2018-05-10 11:31:28.317398259 +0800 +@@ -0,0 +1,203 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-saber2.dtsi" ++ ++/ { ++ model = "Broadcom SB2 SVK (BCM956260K)"; ++ compatible = "brcm,bcm956260k", "brcm,saber2"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&amac_phy0>; ++ phy-mode = "sgmii"; ++ serdes-handle = <&amac_serdes0>; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++ mdio-phy-handle = <&usb_phy>; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy0>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c64"; ++ reg = <0x50>; ++ pagesize = <32>; ++ }; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x70000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x01000000>; ++ }; ++ }; ++}; ++ ++ ++&mdio_int { ++ status = "okay"; ++ amac_serdes0: amac_serdes@0 { ++ reg = <1>; ++ }; ++ pcie_phy0: pcie_phy@0 { ++ reg = <2>; ++ }; ++ usb_phy: usb_phy@0 { ++ reg = <3>; ++ }; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <1>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; +Binary files a/arch/arm/boot/dts/bcm956340.dtb and b/arch/arm/boot/dts/bcm956340.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956340.dts b/arch/arm/boot/dts/bcm956340.dts +--- a/arch/arm/boot/dts/bcm956340.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm956340.dts 2018-05-10 11:31:28.317398259 +0800 +@@ -0,0 +1,230 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-helix4.dtsi" ++ ++/ { ++ model = "Broadcom HX4 SVK (BCM956340K)"; ++ compatible = "brcm,bcm956340k", "brcm,helix4"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ sdk-serdes-lane2 = &amac_serdes2; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=2 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&amac_phy0>; ++ phy-mode = "sgmii"; /* "gmii-id", "gmii-rxid", "sgmii" */ ++ serdes-handle = <&amac_serdes0>; ++}; ++ ++&gmac1 { ++ status = "okay"; ++ phy-handle = <&amac_phy1>; ++ phy-mode = "sgmii"; /* "gmii-id", "gmii-rxid", "sgmii" */ ++ serdes-handle = <&amac_serdes1>; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++ mdio-phy-handle = <&usb_phy>; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_cca { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy0>; ++}; ++ ++&pcie1 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy1>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&i2c1 { ++ status = "okay"; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x70000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x01000000>; ++ }; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++ /* 3 AMAC serdes, amac_serdes2 is for switch front port */ ++ amac_serdes0: amac_serdes@0 { ++ reg = <1>; ++ }; ++ amac_serdes1: amac_serdes@1 { ++ reg = <2>; ++ }; ++ amac_serdes2: amac_serdes@2 { ++ reg = <3>; ++ }; ++ usb_phy: usb_phy@0 { ++ reg = <6>; ++ }; ++ pcie_phy0: pcie_phy@0 { ++ reg = <7>; ++ }; ++ pcie_phy1: pcie_phy@1 { ++ reg = <8>; ++ }; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <1>; ++ }; ++ amac_phy1: amac_phy@1 { ++ reg = <2>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; ++ +Binary files a/arch/arm/boot/dts/bcm956450.dtb and b/arch/arm/boot/dts/bcm956450.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956450.dts b/arch/arm/boot/dts/bcm956450.dts +--- a/arch/arm/boot/dts/bcm956450.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm956450.dts 2018-05-10 11:31:28.317398259 +0800 +@@ -0,0 +1,229 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-katana2.dtsi" ++ ++/ { ++ model = "Broadcom KT2 SVK (BCM956450K)"; ++ compatible = "brcm,bcm956450k", "brcm,katana2"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ sdk-serdes-lane2 = &amac_serdes2; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=2 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&amac_phy0>; ++ phy-mode = "sgmii"; /* "gmii-id", "gmii-rxid", "sgmii" */ ++ serdes-handle = <&amac_serdes0>; ++}; ++ ++&gmac1 { ++ status = "okay"; ++ phy-handle = <&amac_phy1>; ++ phy-mode = "sgmii"; /* "gmii-id", "gmii-rxid", "sgmii" */ ++ serdes-handle = <&amac_serdes1>; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++ mdio-phy-handle = <&usb_phy>; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_cca { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy0>; ++}; ++ ++&pcie1 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy1>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&i2c1 { ++ status = "okay"; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x70000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x01000000>; ++ }; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++ /* 3 AMAC serdes, amac_serdes2 is for switch front port */ ++ amac_serdes0: amac_serdes@0 { ++ reg = <1>; ++ }; ++ amac_serdes1: amac_serdes@1 { ++ reg = <2>; ++ }; ++ amac_serdes2: amac_serdes@2 { ++ reg = <3>; ++ }; ++ usb_phy: usb_phy@0 { ++ reg = <6>; ++ }; ++ pcie_phy0: pcie_phy@0 { ++ reg = <7>; ++ }; ++ pcie_phy1: pcie_phy@1 { ++ reg = <8>; ++ }; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <1>; ++ }; ++ amac_phy1: amac_phy@1 { ++ reg = <2>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/greyhound.its b/arch/arm/boot/dts/greyhound.its +--- a/arch/arm/boot/dts/greyhound.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/greyhound.its 2018-05-10 11:31:28.333398276 +0800 +@@ -0,0 +1,62 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm95341x.dtb"; ++ data = /incbin/("./bcm95341x.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++/* ++ fdt@2 { ++ description = "Flattened Device Tree blob - bcm95606x.dtb"; ++ data = /incbin/("./bcm95606x.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "md5"; ++ }; ++ }; ++*/ ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++/* ++ conf@2 { ++ description = "Boot Linux kernel with FDT blob"; ++ kernel = "kernel@1"; ++ fdt = "fdt@2"; ++ }; ++*/ ++ }; ++}; ++ +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/greyhound2.its b/arch/arm/boot/dts/greyhound2.its +--- a/arch/arm/boot/dts/greyhound2.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/greyhound2.its 2018-05-10 11:31:28.333398276 +0800 +@@ -0,0 +1,62 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm956170.dtb"; ++ data = /incbin/("./bcm956170.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ /*fdt@2 { ++ description = "Flattened Device Tree blob - bcm95357x.dtb"; ++ data = /incbin/("./bcm95357x.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ };*/ ++ ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++/* ++ conf@2 { ++ description = "Boot Linux kernel with FDT blob"; ++ kernel = "kernel@1"; ++ fdt = "fdt@2"; ++ }; ++*/ ++ }; ++}; ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/helix4.its b/arch/arm/boot/dts/helix4.its +--- a/arch/arm/boot/dts/helix4.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/helix4.its 2018-05-10 11:31:28.333398276 +0800 +@@ -0,0 +1,42 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm956340.dtb"; ++ data = /incbin/("./bcm956340.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/hurricane3.its b/arch/arm/boot/dts/hurricane3.its +--- a/arch/arm/boot/dts/hurricane3.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/hurricane3.its 2018-05-10 11:31:28.333398276 +0800 +@@ -0,0 +1,59 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm956160.dtb"; ++ data = /incbin/("./bcm956160.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@2 { ++ description = "Flattened Device Tree blob - bcm953444.dtb"; ++ data = /incbin/("./bcm953444.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob 1"; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++ ++ conf@2 { ++ description = "Boot Linux kernel with FDT blob 2"; ++ kernel = "kernel@1"; ++ fdt = "fdt@2"; ++ }; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/katana2.its b/arch/arm/boot/dts/katana2.its +--- a/arch/arm/boot/dts/katana2.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/katana2.its 2018-05-10 11:31:28.361398305 +0800 +@@ -0,0 +1,43 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm956450.dtb"; ++ data = /incbin/("./bcm956450.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++ }; ++}; ++ +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/saber2.its b/arch/arm/boot/dts/saber2.its +--- a/arch/arm/boot/dts/saber2.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/saber2.its 2018-05-10 11:31:28.397398343 +0800 +@@ -0,0 +1,42 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm956260.dtb"; ++ data = /incbin/("./bcm956260.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/wolfhound2.its b/arch/arm/boot/dts/wolfhound2.its +--- a/arch/arm/boot/dts/wolfhound2.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/wolfhound2.its 2018-05-10 11:31:28.421398368 +0800 +@@ -0,0 +1,60 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm953547.dtb"; ++ data = /incbin/("./bcm953547.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ /* fdt@2 { ++ description = "Flattened Device Tree blob - bcm953444.dtb"; ++ data = /incbin/("./bcm953444.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; */ ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob 1"; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++ ++ /* conf@2 { ++ description = "Boot Linux kernel with FDT blob 2"; ++ kernel = "kernel@1"; ++ fdt = "fdt@2"; ++ }; */ ++ }; ++}; ++ +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/xgs-iproc-arm32.its b/arch/arm/boot/dts/xgs-iproc-arm32.its +--- a/arch/arm/boot/dts/xgs-iproc-arm32.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/xgs-iproc-arm32.its 2018-05-10 11:31:28.421398368 +0800 +@@ -0,0 +1,163 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel_iproc { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_hx4 { ++ description = "Helix4 Device Tree blob - bcm956340.dtb"; ++ data = /incbin/("./bcm956340.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_kt2 { ++ description = "Katana2 Device Tree blob - bcm956450.dtb"; ++ data = /incbin/("./bcm956450.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_sb2 { ++ description = "Saber2 Device Tree blob - bcm956260.dtb"; ++ data = /incbin/("./bcm956260.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_gh { ++ description = "Greyhound Device Tree blob - bcm95341x.dtb"; ++ data = /incbin/("./bcm95341x.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_hr3 { ++ description = "Hurricane3 Device Tree blob - bcm956160.dtb"; ++ data = /incbin/("./bcm956160.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_hr3_lite { ++ description = "Hurricane3 Lite Device Tree blob - bcm953444.dtb"; ++ data = /incbin/("./bcm953444.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_gh2 { ++ description = "Greyhound2 Device Tree blob - bcm956170.dtb"; ++ data = /incbin/("./bcm956170.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_wh2 { ++ description = "Wolfhound2 Device Tree blob - bcm953547.dtb"; ++ data = /incbin/("./bcm953547.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "hx4"; ++ /* use "bootm 0x64000000#katana2" for booting Katana2 */ ++ hx4 { ++ description = "Boot Linux kernel with Helix4 FDT blob "; ++ kernel = "kernel_iproc"; ++ fdt = "fdt_hx4"; ++ }; ++ ++ kt2 { ++ description = "Boot Linux kernel with Katana2 FDT blob "; ++ kernel = "kernel_iproc"; ++ fdt = "fdt_kt2"; ++ }; ++ ++ sb2 { ++ description = "Boot Linux kernel with Saber2 FDT blob "; ++ kernel = "kernel_iproc"; ++ fdt = "fdt_sb2"; ++ }; ++ ++ gh { ++ description = "Boot Linux kernel with Greyhound FDT blob "; ++ kernel = "kernel_iproc"; ++ fdt = "fdt_gh"; ++ }; ++ ++ hr3 { ++ description = "Boot Linux kernel with Hurricane3 FDT blob "; ++ kernel = "kernel_iproc"; ++ fdt = "fdt_hr3"; ++ }; ++ ++ hr3_lite { ++ description = "Boot Linux kernel with Hurricane3 Lite FDT blob "; ++ kernel = "kernel_iproc"; ++ fdt = "fdt_hr3_lite"; ++ }; ++ ++ gh2 { ++ description = "Boot Linux kernel with Greyhound2 FDT blob "; ++ kernel = "kernel_iproc"; ++ fdt = "fdt_gh2"; ++ }; ++ ++ wh2 { ++ description = "Boot Linux kernel with Wolfhound2 FDT blob "; ++ kernel = "kernel_iproc"; ++ fdt = "fdt_wh2"; ++ }; ++ ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/configs/iproc_arm32_be_defconfig b/arch/arm/configs/iproc_arm32_be_defconfig +--- a/arch/arm/configs/iproc_arm32_be_defconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/configs/iproc_arm32_be_defconfig 2018-05-10 11:31:28.429398377 +0800 +@@ -0,0 +1,210 @@ ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_USELIB=y ++CONFIG_IRQ_DOMAIN_DEBUG=y ++CONFIG_NO_HZ=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_SYSCTL_SYSCALL=y ++# CONFIG_SHMEM is not set ++CONFIG_EMBEDDED=y ++# CONFIG_SLUB_DEBUG is not set ++# CONFIG_COMPAT_BRK is not set ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_ARCH_XGS_IPROC=y ++CONFIG_CPU_BIG_ENDIAN=y ++# CONFIG_ARM_ERRATA_643719 is not set ++CONFIG_PCI=y ++CONFIG_PCI_MSI=y ++CONFIG_PCIE_XGS_IPROC=y ++CONFIG_PCIE_IPROC_MSI=y ++CONFIG_SMP=y ++CONFIG_PREEMPT=y ++CONFIG_ARM_MODULE_PLTS=y ++CONFIG_CMA=y ++CONFIG_CMA_DEBUG=y ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 ++CONFIG_CMDLINE="console=ttyS0,115200n8 maxcpus=1 mem=240M" ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET6_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET6_XFRM_MODE_BEET is not set ++CONFIG_IPV6_TUNNEL=y ++CONFIG_NETFILTER=y ++CONFIG_BRIDGE_NETFILTER=y ++CONFIG_NETFILTER_NETLINK_QUEUE=y ++CONFIG_NETFILTER_NETLINK_LOG=y ++CONFIG_NF_CONNTRACK=y ++# CONFIG_NF_CT_PROTO_DCCP is not set ++# CONFIG_NF_CT_PROTO_SCTP is not set ++# CONFIG_NF_CT_PROTO_UDPLITE is not set ++CONFIG_NF_CONNTRACK_FTP=y ++CONFIG_NF_CONNTRACK_TFTP=y ++CONFIG_NETFILTER_XT_MARK=y ++CONFIG_NETFILTER_XT_TARGET_CT=y ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=y ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y ++CONFIG_NETFILTER_XT_MATCH_HELPER=y ++CONFIG_NETFILTER_XT_MATCH_STATE=y ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=y ++CONFIG_NF_CONNTRACK_IPV4=y ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_AH=y ++CONFIG_IP_NF_MATCH_ECN=y ++CONFIG_IP_NF_MATCH_TTL=y ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=y ++CONFIG_IP_NF_MANGLE=y ++CONFIG_IP_NF_TARGET_ECN=y ++CONFIG_IP_NF_TARGET_TTL=y ++CONFIG_IP_NF_RAW=y ++CONFIG_IP_NF_ARPTABLES=y ++CONFIG_IP_NF_ARPFILTER=y ++CONFIG_IP_NF_ARP_MANGLE=y ++CONFIG_NF_CONNTRACK_IPV6=y ++CONFIG_IP6_NF_IPTABLES=y ++CONFIG_IP6_NF_MATCH_RPFILTER=y ++CONFIG_IP6_NF_MATCH_RT=y ++CONFIG_IP6_NF_FILTER=y ++CONFIG_IP6_NF_TARGET_REJECT=y ++CONFIG_IP6_NF_MANGLE=y ++CONFIG_IP6_NF_RAW=y ++CONFIG_BRIDGE=y ++CONFIG_VLAN_8021Q=y ++CONFIG_VLAN_8021Q_GVRP=y ++# CONFIG_WIRELESS is not set ++CONFIG_UEVENT_HELPER_PATH="/sbin/mdev" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=32 ++CONFIG_MTD=y ++CONFIG_MTD_TESTS=m ++CONFIG_MTD_CMDLINE_PARTS=y ++CONFIG_MTD_BLOCK=y ++CONFIG_MTD_CFI=y ++CONFIG_MTD_JEDECPROBE=y ++CONFIG_MTD_CFI_ADV_OPTIONS=y ++CONFIG_MTD_CFI_LE_BYTE_SWAP=y ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_CFI_AMDSTD=y ++CONFIG_MTD_CFI_STAA=y ++CONFIG_MTD_NOR_XGS_IPROC=y ++CONFIG_MTD_M25P80=y ++CONFIG_MTD_NAND=y ++CONFIG_MTD_NAND_BRCMNAND=y ++CONFIG_MTD_SPI_NOR=y ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++CONFIG_MTD_UBI=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_EEPROM_AT24=y ++CONFIG_SCSI=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_CHR_DEV_ST=y ++CONFIG_CHR_DEV_SG=y ++CONFIG_SCSI_CONSTANTS=y ++CONFIG_SCSI_LOGGING=y ++CONFIG_NETDEVICES=y ++CONFIG_BONDING=y ++CONFIG_TIGON3=y ++CONFIG_MDIO_XGS_IPROC=y ++CONFIG_BROADCOM_PHY=y ++CONFIG_XGS_IPROC_SERDES=y ++# CONFIG_WLAN is not set ++# CONFIG_INPUT is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_VT is not set ++# CONFIG_LEGACY_PTYS is not set ++CONFIG_DEVKMEM=y ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=2 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=2 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_8250_DETECT_IRQ=y ++CONFIG_SERIAL_8250_RSA=y ++CONFIG_SERIAL_8250_DW=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_XGS_IPROC_RNG=y ++CONFIG_I2C=y ++# CONFIG_I2C_COMPAT is not set ++CONFIG_I2C_CHARDEV=y ++# CONFIG_I2C_HELPER_AUTO is not set ++CONFIG_SPI=y ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_WATCHDOG=y ++CONFIG_ARM_SP805_WATCHDOG=y ++# CONFIG_VGA_ARB is not set ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_DYNAMIC_MINORS=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_ROOT_HUB_TT=y ++CONFIG_USB_EHCI_XGS_IPROC=y ++CONFIG_USB_EHCI_HCD_PLATFORM=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_HCD_PLATFORM=y ++CONFIG_USB_OHCI_XGS_IPROC=y ++CONFIG_USB_STORAGE=y ++CONFIG_USBPHY_XGS_IPROC=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_XGS_IPROC_UDC=m ++CONFIG_USB_G_SERIAL=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_XGS_IPROC=y ++CONFIG_DMADEVICES=y ++CONFIG_DMADEVICES_DEBUG=y ++CONFIG_DMADEVICES_VDEBUG=y ++CONFIG_PL330_DMA=y ++CONFIG_GENERIC_PHY=y ++CONFIG_EXT2_FS=y ++CONFIG_EXT3_FS=y ++# CONFIG_DNOTIFY is not set ++CONFIG_AUTOFS4_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_NTFS_FS=y ++CONFIG_JFFS2_FS=y ++CONFIG_UBIFS_FS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFSD=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_DEBUG_INFO=y ++CONFIG_DEBUG_FS=y ++CONFIG_MAGIC_SYSRQ=y ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_FTRACE is not set ++CONFIG_DEBUG_USER=y ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_ANSI_CPRNG=m ++CONFIG_XZ_DEC=y +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/configs/iproc_arm32_defconfig b/arch/arm/configs/iproc_arm32_defconfig +--- a/arch/arm/configs/iproc_arm32_defconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/configs/iproc_arm32_defconfig 2018-05-10 11:31:28.429398377 +0800 +@@ -0,0 +1,207 @@ ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_USELIB=y ++CONFIG_IRQ_DOMAIN_DEBUG=y ++CONFIG_NO_HZ=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_SYSCTL_SYSCALL=y ++# CONFIG_SHMEM is not set ++CONFIG_EMBEDDED=y ++# CONFIG_SLUB_DEBUG is not set ++# CONFIG_COMPAT_BRK is not set ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_ARCH_XGS_IPROC=y ++# CONFIG_ARM_ERRATA_643719 is not set ++CONFIG_PCI=y ++CONFIG_PCI_MSI=y ++CONFIG_PCIE_XGS_IPROC=y ++CONFIG_PCIE_IPROC_MSI=y ++CONFIG_SMP=y ++CONFIG_PREEMPT=y ++CONFIG_ARM_MODULE_PLTS=y ++CONFIG_CMA=y ++CONFIG_CMA_DEBUG=y ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 ++CONFIG_CMDLINE="console=ttyS0,115200n8 maxcpus=1 mem=240M" ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET6_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET6_XFRM_MODE_BEET is not set ++CONFIG_IPV6_TUNNEL=y ++CONFIG_NETFILTER=y ++CONFIG_BRIDGE_NETFILTER=y ++CONFIG_NETFILTER_NETLINK_QUEUE=y ++CONFIG_NETFILTER_NETLINK_LOG=y ++CONFIG_NF_CONNTRACK=y ++# CONFIG_NF_CT_PROTO_DCCP is not set ++# CONFIG_NF_CT_PROTO_SCTP is not set ++# CONFIG_NF_CT_PROTO_UDPLITE is not set ++CONFIG_NF_CONNTRACK_FTP=y ++CONFIG_NF_CONNTRACK_TFTP=y ++CONFIG_NETFILTER_XT_MARK=y ++CONFIG_NETFILTER_XT_TARGET_CT=y ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=y ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y ++CONFIG_NETFILTER_XT_MATCH_HELPER=y ++CONFIG_NETFILTER_XT_MATCH_STATE=y ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=y ++CONFIG_NF_CONNTRACK_IPV4=y ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_AH=y ++CONFIG_IP_NF_MATCH_ECN=y ++CONFIG_IP_NF_MATCH_TTL=y ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=y ++CONFIG_IP_NF_MANGLE=y ++CONFIG_IP_NF_TARGET_ECN=y ++CONFIG_IP_NF_TARGET_TTL=y ++CONFIG_IP_NF_RAW=y ++CONFIG_IP_NF_ARPTABLES=y ++CONFIG_IP_NF_ARPFILTER=y ++CONFIG_IP_NF_ARP_MANGLE=y ++CONFIG_NF_CONNTRACK_IPV6=y ++CONFIG_IP6_NF_IPTABLES=y ++CONFIG_IP6_NF_MATCH_RPFILTER=y ++CONFIG_IP6_NF_MATCH_RT=y ++CONFIG_IP6_NF_FILTER=y ++CONFIG_IP6_NF_TARGET_REJECT=y ++CONFIG_IP6_NF_MANGLE=y ++CONFIG_IP6_NF_RAW=y ++CONFIG_BRIDGE=y ++CONFIG_VLAN_8021Q=y ++CONFIG_VLAN_8021Q_GVRP=y ++# CONFIG_WIRELESS is not set ++CONFIG_UEVENT_HELPER_PATH="/sbin/mdev" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=32 ++CONFIG_MTD=y ++CONFIG_MTD_TESTS=m ++CONFIG_MTD_CMDLINE_PARTS=y ++CONFIG_MTD_BLOCK=y ++CONFIG_MTD_CFI=y ++CONFIG_MTD_JEDECPROBE=y ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_CFI_AMDSTD=y ++CONFIG_MTD_CFI_STAA=y ++CONFIG_MTD_NOR_XGS_IPROC=y ++CONFIG_MTD_M25P80=y ++CONFIG_MTD_NAND=y ++CONFIG_MTD_NAND_BRCMNAND=y ++CONFIG_MTD_SPI_NOR=y ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++CONFIG_MTD_UBI=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_EEPROM_AT24=y ++CONFIG_SCSI=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_CHR_DEV_ST=y ++CONFIG_CHR_DEV_SG=y ++CONFIG_SCSI_CONSTANTS=y ++CONFIG_SCSI_LOGGING=y ++CONFIG_NETDEVICES=y ++CONFIG_BONDING=y ++CONFIG_TIGON3=y ++CONFIG_MDIO_XGS_IPROC=y ++CONFIG_BROADCOM_PHY=y ++CONFIG_XGS_IPROC_SERDES=y ++# CONFIG_WLAN is not set ++# CONFIG_INPUT is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_VT is not set ++# CONFIG_LEGACY_PTYS is not set ++CONFIG_DEVKMEM=y ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=2 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=2 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_8250_DETECT_IRQ=y ++CONFIG_SERIAL_8250_RSA=y ++CONFIG_SERIAL_8250_DW=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_XGS_IPROC_RNG=y ++CONFIG_I2C=y ++# CONFIG_I2C_COMPAT is not set ++CONFIG_I2C_CHARDEV=y ++# CONFIG_I2C_HELPER_AUTO is not set ++CONFIG_SPI=y ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_WATCHDOG=y ++CONFIG_ARM_SP805_WATCHDOG=y ++# CONFIG_VGA_ARB is not set ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_DYNAMIC_MINORS=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_ROOT_HUB_TT=y ++CONFIG_USB_EHCI_XGS_IPROC=y ++CONFIG_USB_EHCI_HCD_PLATFORM=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_HCD_PLATFORM=y ++CONFIG_USB_OHCI_XGS_IPROC=y ++CONFIG_USB_STORAGE=y ++CONFIG_USBPHY_XGS_IPROC=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_XGS_IPROC_UDC=m ++CONFIG_USB_G_SERIAL=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_XGS_IPROC=y ++CONFIG_DMADEVICES=y ++CONFIG_DMADEVICES_DEBUG=y ++CONFIG_DMADEVICES_VDEBUG=y ++CONFIG_PL330_DMA=y ++CONFIG_GENERIC_PHY=y ++CONFIG_EXT2_FS=y ++CONFIG_EXT3_FS=y ++# CONFIG_DNOTIFY is not set ++CONFIG_AUTOFS4_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_NTFS_FS=y ++CONFIG_JFFS2_FS=y ++CONFIG_UBIFS_FS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFSD=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_DEBUG_INFO=y ++CONFIG_DEBUG_FS=y ++CONFIG_MAGIC_SYSRQ=y ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_FTRACE is not set ++CONFIG_DEBUG_USER=y ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_ANSI_CPRNG=m ++CONFIG_XZ_DEC=y +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/Kconfig b/arch/arm/mach-iproc/Kconfig +--- a/arch/arm/mach-iproc/Kconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/Kconfig 2018-05-10 11:31:28.505398457 +0800 +@@ -0,0 +1,77 @@ ++menuconfig ARCH_XGS_IPROC ++ bool "Broadcom XGS iProc Support" if ARCH_MULTI_V7 ++ select HAVE_ARM_TWD if SMP ++ select HAVE_ARM_SCU if SMP ++ select ARM_GLOBAL_TIMER ++ select ARM_GIC ++ select ARCH_REQUIRE_GPIOLIB ++ select CACHE_L2X0 ++ select ARM_AMBA ++ select ARCH_SUPPORTS_BIG_ENDIAN ++ select CPU_ENDIAN_BE8 if CPU_BIG_ENDIAN ++ select ARM_ERRATA_754322 ++ select ARM_ERRATA_764369 if SMP ++ select ARM_ERRATA_775420 ++ help ++ This enables support for Broadcom XGS iProc based SoC chips ++ ++if ARCH_XGS_IPROC ++ ++comment "XGS iProc SoC based Machine types" ++ ++choice ++ prompt "XGS iProc SoC based Machine types" ++ default XGS_IPROC_ARM32_PLATFORM ++ ++config XGS_IPROC_ARM32_PLATFORM ++ bool "Support all XGS iProc ARM32 platforms" ++ help ++ Support for all XGS iProc ARM32 platforms. ++ ++config MACH_HX4 ++ bool "Support Broadcom Helix4 bring-up board" ++ help ++ Support for the Broadcom Helix4 bring-up board. ++ ++config MACH_HR2 ++ bool "Support Broadcom Hurricane2 bring-up board" ++ help ++ Support for the Broadcom Hurricane2 bring-up board. ++ ++config MACH_KT2 ++ bool "Support Broadcom Katana2 bring-up board" ++ help ++ Support for the Broadcom Katana2 bring-up board. ++ ++config MACH_GH ++ bool "Support Broadcom Greyhound bring-up board" ++ help ++ Support for the Broadcom Greyhound bring-up board. ++ ++config MACH_SB2 ++ bool "Support Broadcom Saber2 bring-up board" ++ help ++ Support for the Broadcom Saber2 bring-up board. ++ ++config MACH_HR3 ++ bool "Support Broadcom Hurricane3 bring-up board" ++ help ++ Support for the Broadcom Hurricane3 bring-up board. ++ ++config MACH_GH2 ++ bool "Support Broadcom Greyhound2 bring-up board" ++ help ++ Support for the Broadcom Greyhound2 bring-up board. ++ ++config MACH_WH2 ++ bool "Support Broadcom wolfhound2 bring-up board" ++ help ++ Support for the Broadcom Wolfhound2 bring-up board. ++endchoice ++ ++config MACH_IPROC_EMULATION ++ bool "Support iProc emulation" ++ help ++ Support for the iProc emulation. ++ ++endif +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/Makefile b/arch/arm/mach-iproc/Makefile +--- a/arch/arm/mach-iproc/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/Makefile 2018-05-10 11:31:28.505398457 +0800 +@@ -0,0 +1,3 @@ ++obj-y := board_bu.o ++obj-y += shm.o ++obj-$(CONFIG_SMP) += platsmp.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/board_bu.c b/arch/arm/mach-iproc/board_bu.c +--- a/arch/arm/mach-iproc/board_bu.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/board_bu.c 2018-05-10 11:31:28.505398457 +0800 +@@ -0,0 +1,108 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DMU_CRU_RESET_BASE 0x200 ++ ++enum xgs_iproc_dev_id { ++ XGS_IPROC_HX4=0, ++ XGS_IPROC_KT2, ++ XGS_IPROC_HR2, ++ XGS_IPROC_GH, ++ XGS_IPROC_SB2, ++ XGS_IPROC_HR3, ++ XGS_IPROC_GH2, ++ XGS_IPROC_WH2, ++ XGS_IPROC_GENERIC, ++}; ++ ++const char *const xgs_iproc_dt_compat[] = { ++ "brcm,helix4", ++ "brcm,katana2", ++ "brcm,hurricane2", ++ "brcm,greyhound", ++ "brcm,saber2", ++ "brcm,hurricane3", ++ "brcm,greyhound2", ++ "brcm,wolfhound2", ++ "brcm,xgs-iproc", ++ NULL, ++}; ++ ++void __init xgs_iproc_init_early(void) ++{ ++ /* ++ * SDK allocates coherent buffers from atomic context. ++ * Increase size of atomic coherent pool to make sure such ++ * allocations won't fail. ++ */ ++ /* can be overrided by "coherent_pool" in kernel boot argument */ ++ if (IS_ENABLED(CONFIG_DMA_CMA)) ++ init_dma_coherent_pool_size(SZ_1M * 16); ++} ++ ++static void __init xgs_iproc_init(void) ++{ ++ int ret; ++ ++ ret = xgs_iproc_misc_setup(); ++ if (ret < 0) ++ return; ++ ++ /* Init idm and setup idm timeout handler for debug purpose */ ++ /* xgs_iproc_idm_init should be init before reset dmac */ ++ ret = xgs_iproc_idm_init(); ++ if (ret < 0) ++ return; ++ ++ xgs_iproc_idm_dmac_reset(); ++ ++ /* Populate platform devices */ ++ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); ++} ++ ++ ++static void xgs_iproc_restart(enum reboot_mode mode, const char *cmd) ++{ ++ void * __iomem reg_addr; ++ u32 reg; ++ ++ /* CRU_RESET register */ ++ reg_addr = (void * __iomem)(get_iproc_dmu_pcu_base() + ++ DMU_CRU_RESET_BASE); ++ /* set iproc_reset_n to 0 */ ++ reg = readl(reg_addr); ++ reg &= ~((u32) 1 << 1); ++ ++ writel(reg, reg_addr); ++ ++ /* Wait for reset */ ++ while (1) ++ cpu_do_idle(); ++} ++ ++DT_MACHINE_START(XGS_iProc_DT, "BRCM XGS iProc") ++ .init_early = xgs_iproc_init_early, ++ .init_machine = xgs_iproc_init, ++ .dt_compat = xgs_iproc_dt_compat, ++ .restart = xgs_iproc_restart, ++ .l2c_aux_val = 0, ++ .l2c_aux_mask = ~0, ++MACHINE_END +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/include/plat/shm.h b/arch/arm/mach-iproc/include/plat/shm.h +--- a/arch/arm/mach-iproc/include/plat/shm.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/include/plat/shm.h 2018-05-10 11:31:28.505398457 +0800 +@@ -0,0 +1,72 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * 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. ++ */ ++/* ++ * Header for declaring shim layer exports. ++ */ ++ ++#ifndef __SHM_DOT_H_INCLUDED__ ++#define __SHM_DOT_H_INCLUDED__ ++ ++#include ++#include ++#include ++ ++ ++#define iproc_class_create(owner, name) \ ++({ \ ++ static struct lock_class_key __key; \ ++ iproc__class_create(owner, name, &__key); \ ++}) ++ ++extern int iproc_platform_get_irq(struct platform_device *dev, unsigned int num); ++extern struct resource * ++iproc_platform_get_resource_byname(struct platform_device *dev, unsigned int type, const char *name); ++extern struct resource * ++iproc_platform_get_resource(struct platform_device *dev, unsigned int type, ++ unsigned int num); ++extern int iproc_platform_device_add_resources(struct platform_device *pdev, const struct resource *res, unsigned int num); ++ ++extern int iproc_platform_device_register(struct platform_device * pdev); ++extern void iproc_platform_device_unregister(struct platform_device * pdev); ++extern int iproc_platform_driver_register(struct platform_driver *drv); ++extern void iproc_platform_driver_unregister(struct platform_driver *drv); ++ ++extern struct platform_device *iproc_platform_device_alloc(const char *name, int id); ++ ++extern int iproc_platform_device_add(struct platform_device *pdev); ++extern void iproc_platform_device_put(struct platform_device *pdev); ++ ++extern void iproc_platform_device_put(struct platform_device *pdev); ++extern int iproc_platform_device_add(struct platform_device *pdev); ++extern void iproc_platform_device_del(struct platform_device *pdev); ++extern int iproc_sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp); ++extern void iproc_sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp); ++ ++ ++extern struct class *iproc__class_create(struct module *owner, const char *name, ++ struct lock_class_key *key); ++extern void iproc_class_destroy(struct class *cls); ++extern int iproc_device_create_file(struct device *dev, ++ const struct device_attribute *attr); ++extern struct device *iproc_device_create(struct class *class, ++ struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...); ++extern void iproc_device_destroy(struct class *class, dev_t devt); ++extern void iproc_device_remove_file(struct device *dev, ++ const struct device_attribute *attr); ++extern int iproc_platform_get_irq_byname(struct platform_device *, const char *); ++ ++extern int iproc_gpio_to_irq(unsigned gpio); ++#endif /*#ifndef __SHM_DOT_H_INCLUDED__*/ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/platsmp.c b/arch/arm/mach-iproc/platsmp.c +--- a/arch/arm/mach-iproc/platsmp.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/platsmp.c 2018-05-10 11:31:28.505398457 +0800 +@@ -0,0 +1,309 @@ ++/* ++ * Copyright (C) 2014-2015 Broadcom Corporation ++ * Copyright 2014 Linaro Limited ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++#include "../mach-bcm/platsmp.c" ++ ++#if 0 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* Size of mapped Cortex A9 SCU address space */ ++#define CORTEX_A9_SCU_SIZE 0x58 ++ ++#define SECONDARY_TIMEOUT_NS NSEC_PER_MSEC /* 1 msec (in nanoseconds) */ ++#define BOOT_ADDR_CPUID_MASK 0x3 ++ ++/* Name of device node property defining secondary boot register location */ ++#define OF_SECONDARY_BOOT "secondary-boot-reg" ++#define MPIDR_CPUID_BITMASK 0x3 ++ ++/* ++ * Enable the Cortex A9 Snoop Control Unit ++ * ++ * By the time this is called we already know there are multiple ++ * cores present. We assume we're running on a Cortex A9 processor, ++ * so any trouble getting the base address register or getting the ++ * SCU base is a problem. ++ * ++ * Return 0 if successful or an error code otherwise. ++ */ ++static int __init scu_a9_enable(void) ++{ ++ unsigned long config_base; ++ void __iomem *scu_base; ++ ++ if (!scu_a9_has_base()) { ++ pr_err("no configuration base address register!\n"); ++ return -ENXIO; ++ } ++ ++ /* Config base address register value is zero for uniprocessor */ ++ config_base = scu_a9_get_base(); ++ if (!config_base) { ++ pr_err("hardware reports only one core\n"); ++ return -ENOENT; ++ } ++ ++ scu_base = ioremap((phys_addr_t)config_base, CORTEX_A9_SCU_SIZE); ++ if (!scu_base) { ++ pr_err("failed to remap config base (%lu/%u) for SCU\n", ++ config_base, CORTEX_A9_SCU_SIZE); ++ return -ENOMEM; ++ } ++ ++ scu_enable(scu_base); ++ ++ iounmap(scu_base); /* That's the last we'll need of this */ ++ ++ return 0; ++} ++ ++static u32 secondary_boot_addr_for(unsigned int cpu) ++{ ++ u32 secondary_boot_addr = 0; ++ struct device_node *cpu_node = of_get_cpu_node(cpu, NULL); ++ ++ if (!cpu_node) { ++ pr_err("Failed to find device tree node for CPU%u\n", cpu); ++ return 0; ++ } ++ ++ if (of_property_read_u32(cpu_node, ++ OF_SECONDARY_BOOT, ++ &secondary_boot_addr)) ++ pr_err("required secondary boot register not specified for CPU%u\n", ++ cpu); ++ ++ of_node_put(cpu_node); ++ ++ return secondary_boot_addr; ++} ++ ++static int nsp_write_lut(unsigned int cpu) ++{ ++ void __iomem *sku_rom_lut; ++ phys_addr_t secondary_startup_phy; ++ const u32 secondary_boot_addr = secondary_boot_addr_for(cpu); ++ ++ if (!secondary_boot_addr) ++ return -EINVAL; ++ ++ sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot_addr, ++ sizeof(phys_addr_t)); ++ if (!sku_rom_lut) { ++ pr_warn("unable to ioremap SKU-ROM LUT register for cpu %u\n", cpu); ++ return -ENOMEM; ++ } ++ ++ secondary_startup_phy = virt_to_phys(secondary_startup); ++ BUG_ON(secondary_startup_phy > (phys_addr_t)U32_MAX); ++ ++ writel_relaxed(secondary_startup_phy, sku_rom_lut); ++ ++ /* Ensure the write is visible to the secondary core */ ++ smp_wmb(); ++ ++ iounmap(sku_rom_lut); ++ ++ return 0; ++} ++ ++static void __init bcm_smp_prepare_cpus(unsigned int max_cpus) ++{ ++ const cpumask_t only_cpu_0 = { CPU_BITS_CPU0 }; ++ ++ /* Enable the SCU on Cortex A9 based SoCs */ ++ if (scu_a9_enable()) { ++ /* Update the CPU present map to reflect uniprocessor mode */ ++ pr_warn("failed to enable A9 SCU - disabling SMP\n"); ++ init_cpu_present(&only_cpu_0); ++ } ++} ++ ++/* ++ * The ROM code has the secondary cores looping, waiting for an event. ++ * When an event occurs each core examines the bottom two bits of the ++ * secondary boot register. When a core finds those bits contain its ++ * own core id, it performs initialization, including computing its boot ++ * address by clearing the boot register value's bottom two bits. The ++ * core signals that it is beginning its execution by writing its boot ++ * address back to the secondary boot register, and finally jumps to ++ * that address. ++ * ++ * So to start a core executing we need to: ++ * - Encode the (hardware) CPU id with the bottom bits of the secondary ++ * start address. ++ * - Write that value into the secondary boot register. ++ * - Generate an event to wake up the secondary CPU(s). ++ * - Wait for the secondary boot register to be re-written, which ++ * indicates the secondary core has started. ++ */ ++static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle) ++{ ++ void __iomem *boot_reg; ++ phys_addr_t boot_func; ++ u64 start_clock; ++ u32 cpu_id; ++ u32 boot_val; ++ bool timeout = false; ++ const u32 secondary_boot_addr = secondary_boot_addr_for(cpu); ++ ++ cpu_id = cpu_logical_map(cpu); ++ if (cpu_id & ~BOOT_ADDR_CPUID_MASK) { ++ pr_err("bad cpu id (%u > %u)\n", cpu_id, BOOT_ADDR_CPUID_MASK); ++ return -EINVAL; ++ } ++ ++ if (!secondary_boot_addr) ++ return -EINVAL; ++ ++ boot_reg = ioremap_nocache((phys_addr_t)secondary_boot_addr, ++ sizeof(phys_addr_t)); ++ if (!boot_reg) { ++ pr_err("unable to map boot register for cpu %u\n", cpu_id); ++ return -ENOMEM; ++ } ++ ++ /* ++ * Secondary cores will start in secondary_startup(), ++ * defined in "arch/arm/kernel/head.S" ++ */ ++ boot_func = virt_to_phys(secondary_startup); ++ BUG_ON(boot_func & BOOT_ADDR_CPUID_MASK); ++ BUG_ON(boot_func > (phys_addr_t)U32_MAX); ++ ++ /* The core to start is encoded in the low bits */ ++ boot_val = (u32)boot_func | cpu_id; ++ writel_relaxed(boot_val, boot_reg); ++ ++ sev(); ++ ++ /* The low bits will be cleared once the core has started */ ++ start_clock = local_clock(); ++ while (!timeout && readl_relaxed(boot_reg) == boot_val) ++ timeout = local_clock() - start_clock > SECONDARY_TIMEOUT_NS; ++ ++ iounmap(boot_reg); ++ ++ if (!timeout) ++ return 0; ++ ++ pr_err("timeout waiting for cpu %u to start\n", cpu_id); ++ ++ return -ENXIO; ++} ++ ++/* Cluster Dormant Control command to bring CPU into a running state */ ++#define CDC_CMD 6 ++#define CDC_CMD_OFFSET 0 ++#define CDC_CMD_REG(cpu) (CDC_CMD_OFFSET + 4*(cpu)) ++ ++/* ++ * BCM23550 has a Cluster Dormant Control block that keeps the core in ++ * idle state. A command needs to be sent to the block to bring the CPU ++ * into running state. ++ */ ++static int bcm23550_boot_secondary(unsigned int cpu, struct task_struct *idle) ++{ ++ void __iomem *cdc_base; ++ struct device_node *dn; ++ char *name; ++ int ret; ++ ++ /* Make sure a CDC node exists before booting the ++ * secondary core. ++ */ ++ name = "brcm,bcm23550-cdc"; ++ dn = of_find_compatible_node(NULL, NULL, name); ++ if (!dn) { ++ pr_err("unable to find cdc node\n"); ++ return -ENODEV; ++ } ++ ++ cdc_base = of_iomap(dn, 0); ++ of_node_put(dn); ++ ++ if (!cdc_base) { ++ pr_err("unable to remap cdc base register\n"); ++ return -ENOMEM; ++ } ++ ++ /* Boot the secondary core */ ++ ret = kona_boot_secondary(cpu, idle); ++ if (ret) ++ goto out; ++ ++ /* Bring this CPU to RUN state so that nIRQ nFIQ ++ * signals are unblocked. ++ */ ++ writel_relaxed(CDC_CMD, cdc_base + CDC_CMD_REG(cpu)); ++ ++out: ++ iounmap(cdc_base); ++ ++ return ret; ++} ++ ++static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle) ++{ ++ int ret; ++ ++ /* ++ * After wake up, secondary core branches to the startup ++ * address programmed at SKU ROM LUT location. ++ */ ++ ret = nsp_write_lut(cpu); ++ if (ret) { ++ pr_err("unable to write startup addr to SKU ROM LUT\n"); ++ goto out; ++ } ++ ++ /* Send a CPU wakeup interrupt to the secondary core */ ++ arch_send_wakeup_ipi_mask(cpumask_of(cpu)); ++ ++out: ++ return ret; ++} ++ ++static const struct smp_operations kona_smp_ops __initconst = { ++ .smp_prepare_cpus = bcm_smp_prepare_cpus, ++ .smp_boot_secondary = kona_boot_secondary, ++}; ++CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method", ++ &kona_smp_ops); ++ ++static const struct smp_operations bcm23550_smp_ops __initconst = { ++ .smp_boot_secondary = bcm23550_boot_secondary, ++}; ++CPU_METHOD_OF_DECLARE(bcm_smp_bcm23550, "brcm,bcm23550", ++ &bcm23550_smp_ops); ++ ++static const struct smp_operations nsp_smp_ops __initconst = { ++ .smp_prepare_cpus = bcm_smp_prepare_cpus, ++ .smp_boot_secondary = nsp_boot_secondary, ++}; ++CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops); ++#endif +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/shm.c b/arch/arm/mach-iproc/shm.c +--- a/arch/arm/mach-iproc/shm.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/shm.c 2018-05-10 11:31:28.505398457 +0800 +@@ -0,0 +1,309 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * 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. ++ */ ++ ++#include "include/plat/shm.h" ++/** ++ * iproc_platform_get_irq - get an IRQ for a device ++ * wrapper function for platform_get_irq ++ * @dev: platform device ++ * @num: IRQ number index ++ */ ++int iproc_platform_get_irq(struct platform_device *dev, unsigned int num) ++{ ++ return platform_get_irq(dev, num); ++} ++EXPORT_SYMBOL(iproc_platform_get_irq); ++ ++ ++/** ++ * iproc_platform_get_resource_byname - ++ * wrapper function for platform_get_resource_byname ++ * @dev: platform device ++ * @type: resource type ++ * @name: resource name ++ */ ++struct resource * ++iproc_platform_get_resource_byname(struct platform_device *dev, ++ unsigned int type, ++ const char *name) ++{ ++ return platform_get_resource_byname(dev, type, name); ++} ++EXPORT_SYMBOL(iproc_platform_get_resource_byname); ++ ++ ++/** ++ * iproc_platform_get_resource - ++ * wrapper function for platform_get_resource ++ * @dev: platform device ++ * @type: resource type ++ * @num: resource index ++ */ ++struct resource * ++iproc_platform_get_resource(struct platform_device *dev, unsigned int type, ++ unsigned int num) ++{ ++ return platform_get_resource(dev, type, num); ++} ++EXPORT_SYMBOL(iproc_platform_get_resource); ++ ++ ++/** ++ * iproc_platform_driver_register - ++ * wrapper function for platform_driver_register ++ * @drv: platform driver structure ++ */ ++int iproc_platform_driver_register(struct platform_driver *drv) ++{ ++ return platform_driver_register(drv); ++} ++EXPORT_SYMBOL(iproc_platform_driver_register); ++ ++ ++/** ++ * iproc_platform_driver_unregister ++ * wrapper function for platform_driver_unregister ++ * @drv: platform driver structure ++ */ ++void iproc_platform_driver_unregister(struct platform_driver *drv) ++{ ++ return platform_driver_unregister(drv); ++} ++EXPORT_SYMBOL(iproc_platform_driver_unregister); ++ ++ ++/** ++ * iproc_platform_device_register - add a platform-level device ++ * wrapper function for platform_device_register ++ * @pdev: platform device we're adding ++ * ++ */ ++int iproc_platform_device_register(struct platform_device * pdev) ++{ ++ return platform_device_register(pdev); ++} ++EXPORT_SYMBOL(iproc_platform_device_register); ++ ++ ++/** ++ * iproc_platform_device_unregister - ++ * wrapper function for platform_device_unregister ++ * @pdev: platform device we're unregistering ++ */ ++void iproc_platform_device_unregister(struct platform_device * pdev) ++{ ++ return platform_device_unregister(pdev); ++} ++EXPORT_SYMBOL(iproc_platform_device_unregister); ++ ++ ++/** ++ * iproc_platform_device_alloc - ++ * wrapper function for platform_device_alloc ++ * @name: base name of the device we're adding ++ * @id: instance id ++ */ ++struct platform_device *iproc_platform_device_alloc(const char *name, int id) ++{ ++ return platform_device_alloc(name, id); ++} ++EXPORT_SYMBOL(iproc_platform_device_alloc); ++ ++/** ++ * iproc_platform_device_add - ++ * wrapper function for platform_device_add ++ * @pdev: platform device we're adding ++ */ ++int iproc_platform_device_add(struct platform_device *pdev) ++{ ++ return platform_device_add(pdev); ++} ++EXPORT_SYMBOL(iproc_platform_device_add); ++ ++/** ++ * iproc_platform_device_del - ++ * wrapper function for platform_device_del ++ * @pdev: platform device we're removing ++ */ ++void iproc_platform_device_del(struct platform_device *pdev) ++{ ++ platform_device_del(pdev); ++} ++EXPORT_SYMBOL(iproc_platform_device_del); ++ ++ ++/** ++ * iproc_platform_device_put - ++ * wrapper function for platform_device_put ++ * @pdev: platform device to free ++ */ ++void iproc_platform_device_put(struct platform_device *pdev) ++{ ++ platform_device_put(pdev); ++} ++EXPORT_SYMBOL(iproc_platform_device_put); ++ ++ ++/** ++ * iproc_platform_device_add_resources - ++ * wrapper function for platform_device_add_resources ++ * @pdev: platform device allocated by platform_device_alloc to add resources to ++ * @res: set of resources that needs to be allocated for the device ++ * @num: number of resources ++ */ ++int iproc_platform_device_add_resources(struct platform_device *pdev, ++ const struct resource *res, unsigned int num) ++{ ++ return platform_device_add_resources(pdev, res, num); ++} ++EXPORT_SYMBOL(iproc_platform_device_add_resources); ++ ++ ++/** ++ * iproc_platform_device_put - ++ * wrapper function for sysfs_create_group ++ * @kobj: The kobject to create the group on ++ * @grp: The attribute group to create ++ */ ++int iproc_sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp) ++{ ++ return sysfs_create_group(kobj, grp); ++} ++EXPORT_SYMBOL(iproc_sysfs_create_group); ++ ++ ++/** ++ * iproc_sysfs_remove_group - ++ * wrapper function for sysfs_remove_group ++ * @kobj: The kobject which the group is on ++ * @grp: The attribute group to remove ++ */ ++void iproc_sysfs_remove_group(struct kobject * kobj, const struct attribute_group * grp) ++{ ++ sysfs_remove_group(kobj, grp); ++} ++EXPORT_SYMBOL(iproc_sysfs_remove_group); ++ ++/** ++ * iproc__class_create - ++ * wrapper function for __class_create ++ * @ower: pointer to the module that is to "own" this struct class ++ * @name: pointer to a string for the name of this class. ++ * @key: the lock_class_key for this class; used by mutex lock debugging ++ */ ++struct class *iproc__class_create(struct module *owner, const char *name, ++ struct lock_class_key *key) ++{ ++ return __class_create(owner, name, key); ++} ++EXPORT_SYMBOL(iproc__class_create); ++ ++/** ++ * iproc_class_destroy - ++ * wrapper function for class_destroy ++ * @cls: pointer to the struct class that is to be destroyed ++ */ ++void iproc_class_destroy(struct class *cls) ++{ ++ class_destroy(cls); ++} ++EXPORT_SYMBOL(iproc_class_destroy); ++ ++/** ++ * iproc_device_create_file - ++ * wrapper function for device_create_file ++ * @dev: device. ++ * @attr: device attribute descriptor. ++ */ ++int iproc_device_create_file(struct device *dev, ++ const struct device_attribute *attr) ++{ ++ return device_create_file(dev, attr); ++} ++EXPORT_SYMBOL(iproc_device_create_file); ++ ++/** ++ * iproc_device_create - ++ * wrapper function for device_create ++ * ++ * @class: pointer to the struct class that this device should be ++ * registered to ++ * @parent: pointer to the parent struct device of this new device, if any ++ * @devt: the dev_t for the char device to be added ++ * @drvdata: the data to be added to the device for callbacks ++ * @fmt: string for the device's name ++ */ ++struct device *iproc_device_create(struct class *class, ++ struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...) ++{ ++ va_list args; ++ struct device *r; ++ ++ va_start(args, fmt); ++ r = device_create_vargs(class, parent, devt, drvdata, fmt, args); ++ va_end(args); ++ ++ return r; ++} ++EXPORT_SYMBOL(iproc_device_create); ++ ++/** ++ * iproc_device_destroy - ++ * wrapper function for device_destroy ++ * @class: pointer to the struct class that this device was registered with ++ * @devt: the dev_t of the device that was previously registered ++ */ ++void iproc_device_destroy(struct class *class, dev_t devt) ++{ ++ return device_destroy(class, devt); ++} ++EXPORT_SYMBOL(iproc_device_destroy); ++ ++/** ++ * proc_device_remove_file - ++ * wrapper function for device_remove_file ++ * @dev: device. ++ * @attr: device attribute descriptor. ++ */ ++void iproc_device_remove_file(struct device *dev, ++ const struct device_attribute *attr) ++{ ++ return device_remove_file(dev, attr); ++} ++EXPORT_SYMBOL(iproc_device_remove_file); ++ ++/** ++ * iproc_platform_get_irq_byname - ++ * wrapper function for platform_get_irq_byname ++ * @dev: platform device ++ * @name: IRQ name ++ */ ++int iproc_platform_get_irq_byname(struct platform_device *dev, const char *n) ++{ ++ return platform_get_irq_byname(dev,n); ++} ++EXPORT_SYMBOL(iproc_platform_get_irq_byname); ++ ++/** ++ * iproc_gpio_to_irq - ++ * wrapper function for gpio_to_irq ++ * @gpio: gpio whose IRQ will be returned (already requested) ++ */ ++int iproc_gpio_to_irq(unsigned gpio) ++{ ++ return gpio_to_irq(gpio); ++} ++EXPORT_SYMBOL(iproc_gpio_to_irq); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/mm/init.c b/arch/arm/mm/init.c +--- a/arch/arm/mm/init.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/arch/arm/mm/init.c 2018-05-10 11:31:28.609398566 +0800 +@@ -721,6 +721,16 @@ static void update_sections_early(struct + for_each_process(t) { + if (t->flags & PF_KTHREAD) + continue; ++ ++ /* ++ * A process in getting shut down state (PF_EXITING), with its ++ * task mmu pointer (mm) being NULL, causes hang in ++ * set_section_perms(). ++ * NOTE: update_sections_early() runs if CONFIG_DEBUG_RODATA=y ++ */ ++ if (t->flags & PF_EXITING) ++ continue; ++ + for_each_thread(t, s) + set_section_perms(perms, n, true, s->mm); + } +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms +--- a/arch/arm64/Kconfig.platforms 2017-11-13 02:46:13.000000000 +0800 ++++ b/arch/arm64/Kconfig.platforms 2018-05-10 11:31:28.629398587 +0800 +@@ -254,6 +254,14 @@ config ARCH_XGENE + help + This enables support for AppliedMicro X-Gene SOC Family + ++config ARCH_XGS_IPROC ++ bool "Broadcom iProc XGS SoC Family" ++ select ARCH_REQUIRE_GPIOLIB ++ select ARM_ARCH_TIMER ++ select ARM_GIC ++ help ++ This enables support for Broadcom XGS iProcbased SoC chips ++ + config ARCH_ZX + bool "ZTE ZX SoC Family" + select PINCTRL +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/boot/dts/broadcom/Makefile b/arch/arm64/boot/dts/broadcom/Makefile +--- a/arch/arm64/boot/dts/broadcom/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/arch/arm64/boot/dts/broadcom/Makefile 2018-05-10 11:31:28.637398596 +0800 +@@ -3,6 +3,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rp + + dts-dirs += northstar2 + dts-dirs += stingray ++dts-dirs += helix5 + always := $(dtb-y) + subdir-y := $(dts-dirs) + clean-files := *.dtb +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/boot/dts/broadcom/helix5/Makefile b/arch/arm64/boot/dts/broadcom/helix5/Makefile +--- a/arch/arm64/boot/dts/broadcom/helix5/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm64/boot/dts/broadcom/helix5/Makefile 2018-05-10 11:31:28.637398596 +0800 +@@ -0,0 +1,5 @@ ++dtb-$(CONFIG_ARCH_XGS_IPROC) += bcm956370.dtb ++ ++always := $(dtb-y) ++subdir-y := $(dts-dirs) ++clean-files := *.dtb +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/boot/dts/broadcom/helix5/bcm-helix5.dtsi b/arch/arm64/boot/dts/broadcom/helix5/bcm-helix5.dtsi +--- a/arch/arm64/boot/dts/broadcom/helix5/bcm-helix5.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm64/boot/dts/broadcom/helix5/bcm-helix5.dtsi 2018-05-31 15:24:26.192724756 +0800 +@@ -0,0 +1,377 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGdLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++ ++/ { ++ model = "Broadcom HX5 iProc"; ++ compatible = "brcm,helix5"; ++ interrupt-parent = <&gic>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ cpus { ++ #address-cells = <2>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a72", "arm,armv8"; ++ next-level-cache = <&L2>; ++ reg = <0 0>; ++ }; ++ ++ L2: l2-cache@000 { ++ compatible = "cache"; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ gic: interrupt-controller@10781000 { ++ compatible = "arm,gic-400"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x10781000 0x1000>, ++ <0x10782000 0x2000>, ++ <0x10784000 0x2000>, ++ <0x10786000 0x2000>; ++ interrupts = ; ++ }; ++ ++ timer { ++ compatible = "arm,armv8-timer"; ++ interrupts = , ++ , ++ , ++ ; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ osc: oscillator_50M { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <50000000>; ++ // clock-frequency = <35029>; ++ }; ++ ++ iproc_clk: iproc_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&osc>; ++ clock-div = <7>; ++ clock-mult = <120>; ++ }; ++ ++ iproc_clk250: iproc_clk250 { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&osc>; ++ clock-div = <24>; ++ clock-mult = <120>; ++// compatible = "fixed-clock"; ++// clock-frequency = <153600>; ++ }; ++ ++ iproc_clk200: iproc_clk200 { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&osc>; ++ clock-div = <1>; ++ clock-mult = <4>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@10200000 { ++ compatible = "ns16550a"; ++ reg = <0x10200000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_clk250>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@10201000 { ++ compatible = "ns16550a"; ++ reg = <0x10201000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_clk250>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,spi-bcm-qspi", "brcm,spi-xgs-iproc-qspi"; ++ reg = <0x15000200 0x188>, ++ <0x15000000 0x050>, ++ <0x10236460 0x004>, ++ <0x150003a0 0x01c>, ++ <0x10241000 0x004>; ++ reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg", "cru_ctrl"; ++ interrupts = ; ++ #chip-select = <0>; ++ clocks = <&iproc_clk250>; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18046000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x15001000 0x600>, ++ <0x1023787c 0x10>, ++ <0x15001f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@10239000 { ++ compatible = "brcm,xgs-iproc-apm,hx5"; ++ reg = <0x10239000 0x1000>, ++ <0x1025e000 0x1000>; ++ reg-names = "apm_base", "idm_base"; ++ pm-type = "pm4x10"; ++ land-idx = <0>; ++ tx-channels = <1>; ++ strict-mode = <1>; ++ interrupts = , ++ , ++ ; ++ status = "disabled"; ++ }; ++ ++ gmac1: ethernet@1023a000 { ++ compatible = "brcm,xgs-iproc-apm,hx5"; ++ reg = <0x1023a000 0x1000>, ++ <0x1025f000 0x1000>; ++ reg-names = "apm_base", "idm_base"; ++ pm-type = "pm4x10"; ++ land-idx = <2>; ++ tx-channels = <1>; ++ strict-mode = <1>; ++ interrupts = , ++ , ++ ; ++ status = "disabled"; ++ }; ++ ++ usbphy: usbphy { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy,hx5"; ++ reg = icfg_usb: <0x102378c0 0x50>; ++ status = "disabled"; ++ }; ++ ++ xhci: usb@10243000 { ++ compatible = "generic-xhci"; ++ reg = <0x10243000 0x1000>; ++ interrupts = ; ++ usb-phy = <&usbphy>; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@10242000 { ++ compatible = "brcm,bdc,hx5"; ++ reg = <0x10242000 0x1000>; ++ interrupts = ; ++ usb-phy = <&usbphy>; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@10207000 { ++ compatible = "brcm,iproc-gpio,ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x10207000 0x50>; ++ ngpios = <10>; ++ pin-reg-bit-shift = <0>; ++ pin-base = <0>; ++ gpio-controller; ++ interrupt-controller; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@10202000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x10202000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@10203000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x10203000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ i2c2: i2c@10204000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x10204000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ i2c3: i2c@10205000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x10205000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@10019000 { ++ compatible = "brcm,iproc-cmicx-mdio"; ++ reg = <0x10019000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <3>; ++ bus-type = "internal"; ++ clocks = <&iproc_clk250>; ++ status = "disabled"; ++ }; ++ ++ mdio_ext: mdio_ext@10019000 { ++ compatible = "brcm,iproc-cmicx-mdio"; ++ reg = <0x10019000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <3>; ++ bus-type = "external"; ++ clocks = <&iproc_clk250>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@1021e000 { ++ compatible = "brcm,iproc-rng200"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x1021e000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@10211000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x10211000 0x1000>, ++ iproc_reset_reg: <0x10220020 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ interrupts = ; ++ clocks = <&iproc_clk250>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@10234000 { ++ compatible = "brcm,dma330", "arm,primecell"; ++ reg = dma330_base: <0x10234000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ clocks = <&iproc_clk250>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ pl022: dma@10206000 { ++ compatible = "arm,pl022", "arm,primecell"; ++ reg = pl022_base: <0x10206000 0x1000>; ++ interrupts = ; ++ clocks = <&iproc_clk250>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ }; ++ ++ dmu_pcu: dmu_pcu@10220000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0 0x10220000 0 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@10220c00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0 0x10220c00 0 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@10250000 { ++ compatible = "brcm,iproc-idm"; ++ reg = idm0: <0x10250000 0x100000>; ++ interrupts = ; ++ }; ++ ++ iproc_cmicx: iproc_cmicx@10100000 { ++ compatible = "brcm,iproc-cmicx"; ++ reg = cmicx: <0x10100000 0x200000>; ++ top-blkid = <7>; ++ amac-blkid = <38>; ++ interrupts = ; ++ }; ++}; +Binary files a/arch/arm64/boot/dts/broadcom/helix5/bcm956370.dtb and b/arch/arm64/boot/dts/broadcom/helix5/bcm956370.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/boot/dts/broadcom/helix5/bcm956370.dts b/arch/arm64/boot/dts/broadcom/helix5/bcm956370.dts +--- a/arch/arm64/boot/dts/broadcom/helix5/bcm956370.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm64/boot/dts/broadcom/helix5/bcm956370.dts 2018-05-31 15:24:26.196724803 +0800 +@@ -0,0 +1,216 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-helix5.dtsi" ++ ++/ { ++ model = "Broadcom HX5 SVK (BCM956370K)"; ++ compatible = "brcm,bcm956370k", "brcm,helix5"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&apm_phy0>; ++ phy-mode = "sgmii"; ++}; ++ ++&gmac1 { ++ status = "okay"; ++ phy-handle = <&apm_phy1>; ++ phy-mode = "sgmii"; ++}; ++/* ++&usbphy { ++ status = "okay"; ++}; ++ ++&xhci { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++*/ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++/* ++&pcie0 { ++ status = "okay"; ++}; ++*/ ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c64"; ++ reg = <0x50>; ++ pagesize = <32>; ++ }; ++}; ++ ++&i2c1 { ++ status = "okay"; ++}; ++ ++&i2c2 { ++ status = "okay"; ++}; ++ ++&i2c3 { ++ status = "okay"; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ //nand-bus-width = <8>; ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x00000000 0x00200000>; ++ /* read-only; */ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x00200000 0x00400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x00600000 0x00a00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x01000000 0x00f000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x070000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ //read-only; ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++ apm_serdes0: apm_serdes@0 { ++ reg = <3>; ++ }; ++ apm_serdes1: apm_serdes@1 { ++ reg = <5>; ++ }; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++ apm_phy0: apm_phy@0 { ++ reg = <16>; ++ }; ++ apm_phy1: apm_phy@1 { ++ reg = <17>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&pl022 { ++ status = "okay"; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/boot/dts/broadcom/helix5/helix5.its b/arch/arm64/boot/dts/broadcom/helix5/helix5.its +--- a/arch/arm64/boot/dts/broadcom/helix5/helix5.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm64/boot/dts/broadcom/helix5/helix5.its 2018-05-10 11:31:28.641398600 +0800 +@@ -0,0 +1,44 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel_1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../../../Image.gz"); ++ type = "kernel"; ++ arch = "arm64"; ++ os = "linux"; ++ compression = "gzip"; ++ load = <0x60080000>; ++ entry = <0x60080000>; ++ hash_1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_1 { ++ description = "Flattened Device Tree blob - bcm956370.dtb"; ++ data = /incbin/("./bcm956370.dtb"); ++ type = "flat_dt"; ++ arch = "arm64"; ++ compression = "none"; ++ load = <0x60000000>; ++ hash_1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "conf_1"; ++ conf_1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel_1"; ++ fdt = "fdt_1"; ++ }; ++ }; ++}; ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/configs/iproc_a72_be_defconfig b/arch/arm64/configs/iproc_a72_be_defconfig +--- a/arch/arm64/configs/iproc_a72_be_defconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm64/configs/iproc_a72_be_defconfig 2018-05-30 15:50:51.028753148 +0800 +@@ -0,0 +1,217 @@ ++CONFIG_CROSS_COMPILE="$CROSS_COMPILE" ++CONFIG_SYSVIPC=y ++# CONFIG_FHANDLE is not set ++CONFIG_USELIB=y ++CONFIG_NO_HZ=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_LOG_BUF_SHIFT=16 ++CONFIG_LOG_CPU_MAX_BUF_SHIFT=13 ++CONFIG_SYSCTL_SYSCALL=y ++# CONFIG_ELF_CORE is not set ++# CONFIG_BASE_FULL is not set ++# CONFIG_EPOLL is not set ++# CONFIG_SIGNALFD is not set ++# CONFIG_TIMERFD is not set ++# CONFIG_EVENTFD is not set ++# CONFIG_SHMEM is not set ++# CONFIG_AIO is not set ++CONFIG_EMBEDDED=y ++# CONFIG_SLUB_DEBUG is not set ++# CONFIG_COMPAT_BRK is not set ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_ARCH_XGS_IPROC=y ++CONFIG_PCI=y ++CONFIG_CPU_BIG_ENDIAN=y ++CONFIG_NR_CPUS=4 ++CONFIG_PREEMPT=y ++CONFIG_HZ_100=y ++# CONFIG_COMPACTION is not set ++CONFIG_CMA=y ++CONFIG_CMA_DEBUG=y ++CONFIG_CMDLINE="console=ttyS0,115200n8 maxcpus=2 mem=496M" ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_DIAG is not set ++CONFIG_IPV6_TUNNEL=y ++CONFIG_NETFILTER=y ++CONFIG_BRIDGE_NETFILTER=y ++CONFIG_NETFILTER_NETLINK_QUEUE=y ++CONFIG_NETFILTER_NETLINK_LOG=y ++CONFIG_NF_CONNTRACK=y ++# CONFIG_NF_CT_PROTO_DCCP is not set ++# CONFIG_NF_CT_PROTO_SCTP is not set ++# CONFIG_NF_CT_PROTO_UDPLITE is not set ++CONFIG_NF_CONNTRACK_FTP=y ++CONFIG_NF_CONNTRACK_TFTP=y ++CONFIG_NETFILTER_XT_MARK=y ++CONFIG_NETFILTER_XT_TARGET_CT=y ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=y ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y ++CONFIG_NETFILTER_XT_MATCH_HELPER=y ++CONFIG_NETFILTER_XT_MATCH_STATE=y ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=y ++CONFIG_NF_CONNTRACK_IPV4=y ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_AH=y ++CONFIG_IP_NF_MATCH_ECN=y ++CONFIG_IP_NF_MATCH_TTL=y ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=y ++CONFIG_IP_NF_MANGLE=y ++CONFIG_IP_NF_TARGET_ECN=y ++CONFIG_IP_NF_TARGET_TTL=y ++CONFIG_IP_NF_RAW=y ++CONFIG_IP_NF_ARPTABLES=y ++CONFIG_IP_NF_ARPFILTER=y ++CONFIG_IP_NF_ARP_MANGLE=y ++CONFIG_NF_CONNTRACK_IPV6=y ++CONFIG_IP6_NF_IPTABLES=y ++CONFIG_IP6_NF_MATCH_RPFILTER=y ++CONFIG_IP6_NF_MATCH_RT=y ++CONFIG_IP6_NF_FILTER=y ++CONFIG_IP6_NF_TARGET_REJECT=y ++CONFIG_IP6_NF_MANGLE=y ++CONFIG_IP6_NF_RAW=y ++CONFIG_BRIDGE=y ++CONFIG_VLAN_8021Q=y ++CONFIG_VLAN_8021Q_GVRP=y ++# CONFIG_WIRELESS is not set ++CONFIG_UEVENT_HELPER_PATH="/sbin/mdev" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=32 ++CONFIG_MTD=y ++CONFIG_MTD_TESTS=m ++CONFIG_MTD_CMDLINE_PARTS=y ++CONFIG_MTD_BLOCK=y ++CONFIG_MTD_CFI=y ++CONFIG_MTD_JEDECPROBE=y ++CONFIG_MTD_CFI_ADV_OPTIONS=y ++CONFIG_MTD_CFI_LE_BYTE_SWAP=y ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_CFI_AMDSTD=y ++CONFIG_MTD_CFI_STAA=y ++CONFIG_MTD_M25P80=y ++CONFIG_MTD_NAND=y ++CONFIG_MTD_NAND_BRCMNAND=y ++CONFIG_MTD_SPI_NOR=y ++CONFIG_MTD_UBI=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_EEPROM_AT24=y ++CONFIG_SCSI=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_CHR_DEV_ST=y ++CONFIG_CHR_DEV_SG=y ++CONFIG_SCSI_CONSTANTS=y ++CONFIG_SCSI_LOGGING=y ++CONFIG_NETDEVICES=y ++CONFIG_BONDING=y ++CONFIG_TIGON3=y ++# CONFIG_BGMAC_PLATFORM is not set ++CONFIG_APM=y ++CONFIG_MDIO_XGS_IPROC=y ++CONFIG_BROADCOM_PHY=y ++CONFIG_XGS_IPROC_SERDES=y ++# CONFIG_WLAN is not set ++# CONFIG_INPUT is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_VT is not set ++# CONFIG_LEGACY_PTYS is not set ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=2 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=2 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_8250_DETECT_IRQ=y ++CONFIG_SERIAL_8250_RSA=y ++CONFIG_SERIAL_8250_DW=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_XGS_IPROC_RNG=y ++CONFIG_I2C=y ++# CONFIG_I2C_COMPAT is not set ++CONFIG_I2C_CHARDEV=y ++# CONFIG_I2C_HELPER_AUTO is not set ++CONFIG_SPI=y ++CONFIG_SPI_PL022=y ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_WATCHDOG=y ++CONFIG_ARM_SP805_WATCHDOG=y ++# CONFIG_VGA_ARB is not set ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_DYNAMIC_MINORS=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PLATFORM=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_XGS_IPROC_DRD=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_BDC_UDC=y ++CONFIG_USB_BDC_XGS_IPROC=y ++CONFIG_USB_G_SERIAL=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_DMADEVICES=y ++CONFIG_DMADEVICES_DEBUG=y ++CONFIG_DMADEVICES_VDEBUG=y ++CONFIG_PL330_DMA=y ++# CONFIG_COMMON_CLK_XGENE is not set ++CONFIG_ACPI=y ++CONFIG_EXT2_FS=y ++CONFIG_EXT3_FS=y ++# CONFIG_DNOTIFY is not set ++CONFIG_AUTOFS4_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_NTFS_FS=y ++# CONFIG_PROC_PAGE_MONITOR is not set ++CONFIG_JFFS2_FS=y ++CONFIG_UBIFS_FS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFSD=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_DEBUG_INFO=y ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++CONFIG_DEBUG_FS=y ++CONFIG_MAGIC_SYSRQ=y ++# CONFIG_SCHED_DEBUG is not set ++CONFIG_RCU_CPU_STALL_TIMEOUT=60 ++# CONFIG_FTRACE is not set ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_ANSI_CPRNG=m ++# CONFIG_CRYPTO_HW is not set ++CONFIG_ARM64_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM64_CE=y ++CONFIG_CRYPTO_SHA2_ARM64_CE=y ++CONFIG_CRYPTO_GHASH_ARM64_CE=y ++CONFIG_CRYPTO_AES_ARM64_CE_CCM=y ++CONFIG_CRYPTO_AES_ARM64_CE_BLK=y ++CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/configs/iproc_a72_defconfig b/arch/arm64/configs/iproc_a72_defconfig +--- a/arch/arm64/configs/iproc_a72_defconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm64/configs/iproc_a72_defconfig 2018-05-30 15:50:51.028753148 +0800 +@@ -0,0 +1,214 @@ ++CONFIG_CROSS_COMPILE="$CROSS_COMPILE" ++CONFIG_SYSVIPC=y ++# CONFIG_FHANDLE is not set ++CONFIG_USELIB=y ++CONFIG_NO_HZ=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_LOG_BUF_SHIFT=16 ++CONFIG_LOG_CPU_MAX_BUF_SHIFT=13 ++CONFIG_SYSCTL_SYSCALL=y ++# CONFIG_ELF_CORE is not set ++# CONFIG_BASE_FULL is not set ++# CONFIG_EPOLL is not set ++# CONFIG_SIGNALFD is not set ++# CONFIG_TIMERFD is not set ++# CONFIG_EVENTFD is not set ++# CONFIG_SHMEM is not set ++# CONFIG_AIO is not set ++CONFIG_EMBEDDED=y ++# CONFIG_SLUB_DEBUG is not set ++# CONFIG_COMPAT_BRK is not set ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_ARCH_XGS_IPROC=y ++CONFIG_PCI=y ++CONFIG_NR_CPUS=4 ++CONFIG_PREEMPT=y ++CONFIG_HZ_100=y ++# CONFIG_COMPACTION is not set ++CONFIG_CMA=y ++CONFIG_CMA_DEBUG=y ++CONFIG_CMDLINE="console=ttyS0,115200n8 maxcpus=2 mem=496M" ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_DIAG is not set ++CONFIG_IPV6_TUNNEL=y ++CONFIG_NETFILTER=y ++CONFIG_BRIDGE_NETFILTER=y ++CONFIG_NETFILTER_NETLINK_QUEUE=y ++CONFIG_NETFILTER_NETLINK_LOG=y ++CONFIG_NF_CONNTRACK=y ++# CONFIG_NF_CT_PROTO_DCCP is not set ++# CONFIG_NF_CT_PROTO_SCTP is not set ++# CONFIG_NF_CT_PROTO_UDPLITE is not set ++CONFIG_NF_CONNTRACK_FTP=y ++CONFIG_NF_CONNTRACK_TFTP=y ++CONFIG_NETFILTER_XT_MARK=y ++CONFIG_NETFILTER_XT_TARGET_CT=y ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=y ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y ++CONFIG_NETFILTER_XT_MATCH_HELPER=y ++CONFIG_NETFILTER_XT_MATCH_STATE=y ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=y ++CONFIG_NF_CONNTRACK_IPV4=y ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_AH=y ++CONFIG_IP_NF_MATCH_ECN=y ++CONFIG_IP_NF_MATCH_TTL=y ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=y ++CONFIG_IP_NF_MANGLE=y ++CONFIG_IP_NF_TARGET_ECN=y ++CONFIG_IP_NF_TARGET_TTL=y ++CONFIG_IP_NF_RAW=y ++CONFIG_IP_NF_ARPTABLES=y ++CONFIG_IP_NF_ARPFILTER=y ++CONFIG_IP_NF_ARP_MANGLE=y ++CONFIG_NF_CONNTRACK_IPV6=y ++CONFIG_IP6_NF_IPTABLES=y ++CONFIG_IP6_NF_MATCH_RPFILTER=y ++CONFIG_IP6_NF_MATCH_RT=y ++CONFIG_IP6_NF_FILTER=y ++CONFIG_IP6_NF_TARGET_REJECT=y ++CONFIG_IP6_NF_MANGLE=y ++CONFIG_IP6_NF_RAW=y ++CONFIG_BRIDGE=y ++CONFIG_VLAN_8021Q=y ++CONFIG_VLAN_8021Q_GVRP=y ++# CONFIG_WIRELESS is not set ++CONFIG_UEVENT_HELPER_PATH="/sbin/mdev" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=32 ++CONFIG_MTD=y ++CONFIG_MTD_TESTS=m ++CONFIG_MTD_CMDLINE_PARTS=y ++CONFIG_MTD_BLOCK=y ++CONFIG_MTD_CFI=y ++CONFIG_MTD_JEDECPROBE=y ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_CFI_AMDSTD=y ++CONFIG_MTD_CFI_STAA=y ++CONFIG_MTD_M25P80=y ++CONFIG_MTD_NAND=y ++CONFIG_MTD_NAND_BRCMNAND=y ++CONFIG_MTD_SPI_NOR=y ++CONFIG_MTD_UBI=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_EEPROM_AT24=y ++CONFIG_SCSI=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_CHR_DEV_ST=y ++CONFIG_CHR_DEV_SG=y ++CONFIG_SCSI_CONSTANTS=y ++CONFIG_SCSI_LOGGING=y ++CONFIG_NETDEVICES=y ++CONFIG_BONDING=y ++CONFIG_TIGON3=y ++# CONFIG_BGMAC_PLATFORM is not set ++CONFIG_APM=y ++CONFIG_MDIO_XGS_IPROC=y ++CONFIG_BROADCOM_PHY=y ++CONFIG_XGS_IPROC_SERDES=y ++# CONFIG_WLAN is not set ++# CONFIG_INPUT is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_VT is not set ++# CONFIG_LEGACY_PTYS is not set ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=2 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=2 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_8250_DETECT_IRQ=y ++CONFIG_SERIAL_8250_RSA=y ++CONFIG_SERIAL_8250_DW=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_XGS_IPROC_RNG=y ++CONFIG_I2C=y ++# CONFIG_I2C_COMPAT is not set ++CONFIG_I2C_CHARDEV=y ++# CONFIG_I2C_HELPER_AUTO is not set ++CONFIG_SPI=y ++CONFIG_SPI_PL022=y ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_WATCHDOG=y ++CONFIG_ARM_SP805_WATCHDOG=y ++# CONFIG_VGA_ARB is not set ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_DYNAMIC_MINORS=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PLATFORM=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_XGS_IPROC_DRD=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_BDC_UDC=y ++CONFIG_USB_BDC_XGS_IPROC=y ++CONFIG_USB_G_SERIAL=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_DMADEVICES=y ++CONFIG_DMADEVICES_DEBUG=y ++CONFIG_DMADEVICES_VDEBUG=y ++CONFIG_PL330_DMA=y ++# CONFIG_COMMON_CLK_XGENE is not set ++CONFIG_ACPI=y ++CONFIG_EXT2_FS=y ++CONFIG_EXT3_FS=y ++# CONFIG_DNOTIFY is not set ++CONFIG_AUTOFS4_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_NTFS_FS=y ++# CONFIG_PROC_PAGE_MONITOR is not set ++CONFIG_JFFS2_FS=y ++CONFIG_UBIFS_FS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFSD=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_DEBUG_INFO=y ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++CONFIG_DEBUG_FS=y ++CONFIG_MAGIC_SYSRQ=y ++# CONFIG_SCHED_DEBUG is not set ++CONFIG_RCU_CPU_STALL_TIMEOUT=60 ++# CONFIG_FTRACE is not set ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_ANSI_CPRNG=m ++# CONFIG_CRYPTO_HW is not set ++CONFIG_ARM64_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM64_CE=y ++CONFIG_CRYPTO_SHA2_ARM64_CE=y ++CONFIG_CRYPTO_GHASH_ARM64_CE=y ++CONFIG_CRYPTO_AES_ARM64_CE_CCM=y ++CONFIG_CRYPTO_AES_ARM64_CE_BLK=y ++CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/crypto/sha256-core.S b/arch/arm64/crypto/sha256-core.S +--- a/arch/arm64/crypto/sha256-core.S 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm64/crypto/sha256-core.S 2018-05-10 12:01:00.939666414 +0800 +@@ -0,0 +1,2061 @@ ++// Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. ++// ++// Licensed under the OpenSSL license (the "License"). You may not use ++// this file except in compliance with the License. You can obtain a copy ++// in the file LICENSE in the source distribution or at ++// https://www.openssl.org/source/license.html ++ ++// ==================================================================== ++// Written by Andy Polyakov for the OpenSSL ++// project. The module is, however, dual licensed under OpenSSL and ++// CRYPTOGAMS licenses depending on where you obtain it. For further ++// details see http://www.openssl.org/~appro/cryptogams/. ++// ++// Permission to use under GPLv2 terms is granted. ++// ==================================================================== ++// ++// SHA256/512 for ARMv8. ++// ++// Performance in cycles per processed byte and improvement coefficient ++// over code generated with "default" compiler: ++// ++// SHA256-hw SHA256(*) SHA512 ++// Apple A7 1.97 10.5 (+33%) 6.73 (-1%(**)) ++// Cortex-A53 2.38 15.5 (+115%) 10.0 (+150%(***)) ++// Cortex-A57 2.31 11.6 (+86%) 7.51 (+260%(***)) ++// Denver 2.01 10.5 (+26%) 6.70 (+8%) ++// X-Gene 20.0 (+100%) 12.8 (+300%(***)) ++// Mongoose 2.36 13.0 (+50%) 8.36 (+33%) ++// ++// (*) Software SHA256 results are of lesser relevance, presented ++// mostly for informational purposes. ++// (**) The result is a trade-off: it's possible to improve it by ++// 10% (or by 1 cycle per round), but at the cost of 20% loss ++// on Cortex-A53 (or by 4 cycles per round). ++// (***) Super-impressive coefficients over gcc-generated code are ++// indication of some compiler "pathology", most notably code ++// generated with -mgeneral-regs-only is significanty faster ++// and the gap is only 40-90%. ++// ++// October 2016. ++// ++// Originally it was reckoned that it makes no sense to implement NEON ++// version of SHA256 for 64-bit processors. This is because performance ++// improvement on most wide-spread Cortex-A5x processors was observed ++// to be marginal, same on Cortex-A53 and ~10% on A57. But then it was ++// observed that 32-bit NEON SHA256 performs significantly better than ++// 64-bit scalar version on *some* of the more recent processors. As ++// result 64-bit NEON version of SHA256 was added to provide best ++// all-round performance. For example it executes ~30% faster on X-Gene ++// and Mongoose. [For reference, NEON version of SHA512 is bound to ++// deliver much less improvement, likely *negative* on Cortex-A5x. ++// Which is why NEON support is limited to SHA256.] ++ ++#ifndef __KERNEL__ ++# include "arm_arch.h" ++#endif ++ ++.text ++ ++.extern OPENSSL_armcap_P ++.globl sha256_block_data_order ++.type sha256_block_data_order,%function ++.align 6 ++sha256_block_data_order: ++#ifndef __KERNEL__ ++# ifdef __ILP32__ ++ ldrsw x16,.LOPENSSL_armcap_P ++# else ++ ldr x16,.LOPENSSL_armcap_P ++# endif ++ adr x17,.LOPENSSL_armcap_P ++ add x16,x16,x17 ++ ldr w16,[x16] ++ tst w16,#ARMV8_SHA256 ++ b.ne .Lv8_entry ++ tst w16,#ARMV7_NEON ++ b.ne .Lneon_entry ++#endif ++ stp x29,x30,[sp,#-128]! ++ add x29,sp,#0 ++ ++ stp x19,x20,[sp,#16] ++ stp x21,x22,[sp,#32] ++ stp x23,x24,[sp,#48] ++ stp x25,x26,[sp,#64] ++ stp x27,x28,[sp,#80] ++ sub sp,sp,#4*4 ++ ++ ldp w20,w21,[x0] // load context ++ ldp w22,w23,[x0,#2*4] ++ ldp w24,w25,[x0,#4*4] ++ add x2,x1,x2,lsl#6 // end of input ++ ldp w26,w27,[x0,#6*4] ++ adr x30,.LK256 ++ stp x0,x2,[x29,#96] ++ ++.Loop: ++ ldp w3,w4,[x1],#2*4 ++ ldr w19,[x30],#4 // *K++ ++ eor w28,w21,w22 // magic seed ++ str x1,[x29,#112] ++#ifndef __AARCH64EB__ ++ rev w3,w3 // 0 ++#endif ++ ror w16,w24,#6 ++ add w27,w27,w19 // h+=K[i] ++ eor w6,w24,w24,ror#14 ++ and w17,w25,w24 ++ bic w19,w26,w24 ++ add w27,w27,w3 // h+=X[i] ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w20,w21 // a^b, b^c in next round ++ eor w16,w16,w6,ror#11 // Sigma1(e) ++ ror w6,w20,#2 ++ add w27,w27,w17 // h+=Ch(e,f,g) ++ eor w17,w20,w20,ror#9 ++ add w27,w27,w16 // h+=Sigma1(e) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ add w23,w23,w27 // d+=h ++ eor w28,w28,w21 // Maj(a,b,c) ++ eor w17,w6,w17,ror#13 // Sigma0(a) ++ add w27,w27,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ //add w27,w27,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w4,w4 // 1 ++#endif ++ ldp w5,w6,[x1],#2*4 ++ add w27,w27,w17 // h+=Sigma0(a) ++ ror w16,w23,#6 ++ add w26,w26,w28 // h+=K[i] ++ eor w7,w23,w23,ror#14 ++ and w17,w24,w23 ++ bic w28,w25,w23 ++ add w26,w26,w4 // h+=X[i] ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w27,w20 // a^b, b^c in next round ++ eor w16,w16,w7,ror#11 // Sigma1(e) ++ ror w7,w27,#2 ++ add w26,w26,w17 // h+=Ch(e,f,g) ++ eor w17,w27,w27,ror#9 ++ add w26,w26,w16 // h+=Sigma1(e) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ add w22,w22,w26 // d+=h ++ eor w19,w19,w20 // Maj(a,b,c) ++ eor w17,w7,w17,ror#13 // Sigma0(a) ++ add w26,w26,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ //add w26,w26,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w5,w5 // 2 ++#endif ++ add w26,w26,w17 // h+=Sigma0(a) ++ ror w16,w22,#6 ++ add w25,w25,w19 // h+=K[i] ++ eor w8,w22,w22,ror#14 ++ and w17,w23,w22 ++ bic w19,w24,w22 ++ add w25,w25,w5 // h+=X[i] ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w26,w27 // a^b, b^c in next round ++ eor w16,w16,w8,ror#11 // Sigma1(e) ++ ror w8,w26,#2 ++ add w25,w25,w17 // h+=Ch(e,f,g) ++ eor w17,w26,w26,ror#9 ++ add w25,w25,w16 // h+=Sigma1(e) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ add w21,w21,w25 // d+=h ++ eor w28,w28,w27 // Maj(a,b,c) ++ eor w17,w8,w17,ror#13 // Sigma0(a) ++ add w25,w25,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ //add w25,w25,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w6,w6 // 3 ++#endif ++ ldp w7,w8,[x1],#2*4 ++ add w25,w25,w17 // h+=Sigma0(a) ++ ror w16,w21,#6 ++ add w24,w24,w28 // h+=K[i] ++ eor w9,w21,w21,ror#14 ++ and w17,w22,w21 ++ bic w28,w23,w21 ++ add w24,w24,w6 // h+=X[i] ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w25,w26 // a^b, b^c in next round ++ eor w16,w16,w9,ror#11 // Sigma1(e) ++ ror w9,w25,#2 ++ add w24,w24,w17 // h+=Ch(e,f,g) ++ eor w17,w25,w25,ror#9 ++ add w24,w24,w16 // h+=Sigma1(e) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ add w20,w20,w24 // d+=h ++ eor w19,w19,w26 // Maj(a,b,c) ++ eor w17,w9,w17,ror#13 // Sigma0(a) ++ add w24,w24,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ //add w24,w24,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w7,w7 // 4 ++#endif ++ add w24,w24,w17 // h+=Sigma0(a) ++ ror w16,w20,#6 ++ add w23,w23,w19 // h+=K[i] ++ eor w10,w20,w20,ror#14 ++ and w17,w21,w20 ++ bic w19,w22,w20 ++ add w23,w23,w7 // h+=X[i] ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w24,w25 // a^b, b^c in next round ++ eor w16,w16,w10,ror#11 // Sigma1(e) ++ ror w10,w24,#2 ++ add w23,w23,w17 // h+=Ch(e,f,g) ++ eor w17,w24,w24,ror#9 ++ add w23,w23,w16 // h+=Sigma1(e) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ add w27,w27,w23 // d+=h ++ eor w28,w28,w25 // Maj(a,b,c) ++ eor w17,w10,w17,ror#13 // Sigma0(a) ++ add w23,w23,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ //add w23,w23,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w8,w8 // 5 ++#endif ++ ldp w9,w10,[x1],#2*4 ++ add w23,w23,w17 // h+=Sigma0(a) ++ ror w16,w27,#6 ++ add w22,w22,w28 // h+=K[i] ++ eor w11,w27,w27,ror#14 ++ and w17,w20,w27 ++ bic w28,w21,w27 ++ add w22,w22,w8 // h+=X[i] ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w23,w24 // a^b, b^c in next round ++ eor w16,w16,w11,ror#11 // Sigma1(e) ++ ror w11,w23,#2 ++ add w22,w22,w17 // h+=Ch(e,f,g) ++ eor w17,w23,w23,ror#9 ++ add w22,w22,w16 // h+=Sigma1(e) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ add w26,w26,w22 // d+=h ++ eor w19,w19,w24 // Maj(a,b,c) ++ eor w17,w11,w17,ror#13 // Sigma0(a) ++ add w22,w22,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ //add w22,w22,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w9,w9 // 6 ++#endif ++ add w22,w22,w17 // h+=Sigma0(a) ++ ror w16,w26,#6 ++ add w21,w21,w19 // h+=K[i] ++ eor w12,w26,w26,ror#14 ++ and w17,w27,w26 ++ bic w19,w20,w26 ++ add w21,w21,w9 // h+=X[i] ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w22,w23 // a^b, b^c in next round ++ eor w16,w16,w12,ror#11 // Sigma1(e) ++ ror w12,w22,#2 ++ add w21,w21,w17 // h+=Ch(e,f,g) ++ eor w17,w22,w22,ror#9 ++ add w21,w21,w16 // h+=Sigma1(e) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ add w25,w25,w21 // d+=h ++ eor w28,w28,w23 // Maj(a,b,c) ++ eor w17,w12,w17,ror#13 // Sigma0(a) ++ add w21,w21,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ //add w21,w21,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w10,w10 // 7 ++#endif ++ ldp w11,w12,[x1],#2*4 ++ add w21,w21,w17 // h+=Sigma0(a) ++ ror w16,w25,#6 ++ add w20,w20,w28 // h+=K[i] ++ eor w13,w25,w25,ror#14 ++ and w17,w26,w25 ++ bic w28,w27,w25 ++ add w20,w20,w10 // h+=X[i] ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w21,w22 // a^b, b^c in next round ++ eor w16,w16,w13,ror#11 // Sigma1(e) ++ ror w13,w21,#2 ++ add w20,w20,w17 // h+=Ch(e,f,g) ++ eor w17,w21,w21,ror#9 ++ add w20,w20,w16 // h+=Sigma1(e) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ add w24,w24,w20 // d+=h ++ eor w19,w19,w22 // Maj(a,b,c) ++ eor w17,w13,w17,ror#13 // Sigma0(a) ++ add w20,w20,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ //add w20,w20,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w11,w11 // 8 ++#endif ++ add w20,w20,w17 // h+=Sigma0(a) ++ ror w16,w24,#6 ++ add w27,w27,w19 // h+=K[i] ++ eor w14,w24,w24,ror#14 ++ and w17,w25,w24 ++ bic w19,w26,w24 ++ add w27,w27,w11 // h+=X[i] ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w20,w21 // a^b, b^c in next round ++ eor w16,w16,w14,ror#11 // Sigma1(e) ++ ror w14,w20,#2 ++ add w27,w27,w17 // h+=Ch(e,f,g) ++ eor w17,w20,w20,ror#9 ++ add w27,w27,w16 // h+=Sigma1(e) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ add w23,w23,w27 // d+=h ++ eor w28,w28,w21 // Maj(a,b,c) ++ eor w17,w14,w17,ror#13 // Sigma0(a) ++ add w27,w27,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ //add w27,w27,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w12,w12 // 9 ++#endif ++ ldp w13,w14,[x1],#2*4 ++ add w27,w27,w17 // h+=Sigma0(a) ++ ror w16,w23,#6 ++ add w26,w26,w28 // h+=K[i] ++ eor w15,w23,w23,ror#14 ++ and w17,w24,w23 ++ bic w28,w25,w23 ++ add w26,w26,w12 // h+=X[i] ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w27,w20 // a^b, b^c in next round ++ eor w16,w16,w15,ror#11 // Sigma1(e) ++ ror w15,w27,#2 ++ add w26,w26,w17 // h+=Ch(e,f,g) ++ eor w17,w27,w27,ror#9 ++ add w26,w26,w16 // h+=Sigma1(e) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ add w22,w22,w26 // d+=h ++ eor w19,w19,w20 // Maj(a,b,c) ++ eor w17,w15,w17,ror#13 // Sigma0(a) ++ add w26,w26,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ //add w26,w26,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w13,w13 // 10 ++#endif ++ add w26,w26,w17 // h+=Sigma0(a) ++ ror w16,w22,#6 ++ add w25,w25,w19 // h+=K[i] ++ eor w0,w22,w22,ror#14 ++ and w17,w23,w22 ++ bic w19,w24,w22 ++ add w25,w25,w13 // h+=X[i] ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w26,w27 // a^b, b^c in next round ++ eor w16,w16,w0,ror#11 // Sigma1(e) ++ ror w0,w26,#2 ++ add w25,w25,w17 // h+=Ch(e,f,g) ++ eor w17,w26,w26,ror#9 ++ add w25,w25,w16 // h+=Sigma1(e) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ add w21,w21,w25 // d+=h ++ eor w28,w28,w27 // Maj(a,b,c) ++ eor w17,w0,w17,ror#13 // Sigma0(a) ++ add w25,w25,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ //add w25,w25,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w14,w14 // 11 ++#endif ++ ldp w15,w0,[x1],#2*4 ++ add w25,w25,w17 // h+=Sigma0(a) ++ str w6,[sp,#12] ++ ror w16,w21,#6 ++ add w24,w24,w28 // h+=K[i] ++ eor w6,w21,w21,ror#14 ++ and w17,w22,w21 ++ bic w28,w23,w21 ++ add w24,w24,w14 // h+=X[i] ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w25,w26 // a^b, b^c in next round ++ eor w16,w16,w6,ror#11 // Sigma1(e) ++ ror w6,w25,#2 ++ add w24,w24,w17 // h+=Ch(e,f,g) ++ eor w17,w25,w25,ror#9 ++ add w24,w24,w16 // h+=Sigma1(e) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ add w20,w20,w24 // d+=h ++ eor w19,w19,w26 // Maj(a,b,c) ++ eor w17,w6,w17,ror#13 // Sigma0(a) ++ add w24,w24,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ //add w24,w24,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w15,w15 // 12 ++#endif ++ add w24,w24,w17 // h+=Sigma0(a) ++ str w7,[sp,#0] ++ ror w16,w20,#6 ++ add w23,w23,w19 // h+=K[i] ++ eor w7,w20,w20,ror#14 ++ and w17,w21,w20 ++ bic w19,w22,w20 ++ add w23,w23,w15 // h+=X[i] ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w24,w25 // a^b, b^c in next round ++ eor w16,w16,w7,ror#11 // Sigma1(e) ++ ror w7,w24,#2 ++ add w23,w23,w17 // h+=Ch(e,f,g) ++ eor w17,w24,w24,ror#9 ++ add w23,w23,w16 // h+=Sigma1(e) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ add w27,w27,w23 // d+=h ++ eor w28,w28,w25 // Maj(a,b,c) ++ eor w17,w7,w17,ror#13 // Sigma0(a) ++ add w23,w23,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ //add w23,w23,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w0,w0 // 13 ++#endif ++ ldp w1,w2,[x1] ++ add w23,w23,w17 // h+=Sigma0(a) ++ str w8,[sp,#4] ++ ror w16,w27,#6 ++ add w22,w22,w28 // h+=K[i] ++ eor w8,w27,w27,ror#14 ++ and w17,w20,w27 ++ bic w28,w21,w27 ++ add w22,w22,w0 // h+=X[i] ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w23,w24 // a^b, b^c in next round ++ eor w16,w16,w8,ror#11 // Sigma1(e) ++ ror w8,w23,#2 ++ add w22,w22,w17 // h+=Ch(e,f,g) ++ eor w17,w23,w23,ror#9 ++ add w22,w22,w16 // h+=Sigma1(e) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ add w26,w26,w22 // d+=h ++ eor w19,w19,w24 // Maj(a,b,c) ++ eor w17,w8,w17,ror#13 // Sigma0(a) ++ add w22,w22,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ //add w22,w22,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w1,w1 // 14 ++#endif ++ ldr w6,[sp,#12] ++ add w22,w22,w17 // h+=Sigma0(a) ++ str w9,[sp,#8] ++ ror w16,w26,#6 ++ add w21,w21,w19 // h+=K[i] ++ eor w9,w26,w26,ror#14 ++ and w17,w27,w26 ++ bic w19,w20,w26 ++ add w21,w21,w1 // h+=X[i] ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w22,w23 // a^b, b^c in next round ++ eor w16,w16,w9,ror#11 // Sigma1(e) ++ ror w9,w22,#2 ++ add w21,w21,w17 // h+=Ch(e,f,g) ++ eor w17,w22,w22,ror#9 ++ add w21,w21,w16 // h+=Sigma1(e) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ add w25,w25,w21 // d+=h ++ eor w28,w28,w23 // Maj(a,b,c) ++ eor w17,w9,w17,ror#13 // Sigma0(a) ++ add w21,w21,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ //add w21,w21,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w2,w2 // 15 ++#endif ++ ldr w7,[sp,#0] ++ add w21,w21,w17 // h+=Sigma0(a) ++ str w10,[sp,#12] ++ ror w16,w25,#6 ++ add w20,w20,w28 // h+=K[i] ++ ror w9,w4,#7 ++ and w17,w26,w25 ++ ror w8,w1,#17 ++ bic w28,w27,w25 ++ ror w10,w21,#2 ++ add w20,w20,w2 // h+=X[i] ++ eor w16,w16,w25,ror#11 ++ eor w9,w9,w4,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w21,w22 // a^b, b^c in next round ++ eor w16,w16,w25,ror#25 // Sigma1(e) ++ eor w10,w10,w21,ror#13 ++ add w20,w20,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w8,w8,w1,ror#19 ++ eor w9,w9,w4,lsr#3 // sigma0(X[i+1]) ++ add w20,w20,w16 // h+=Sigma1(e) ++ eor w19,w19,w22 // Maj(a,b,c) ++ eor w17,w10,w21,ror#22 // Sigma0(a) ++ eor w8,w8,w1,lsr#10 // sigma1(X[i+14]) ++ add w3,w3,w12 ++ add w24,w24,w20 // d+=h ++ add w20,w20,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w3,w3,w9 ++ add w20,w20,w17 // h+=Sigma0(a) ++ add w3,w3,w8 ++.Loop_16_xx: ++ ldr w8,[sp,#4] ++ str w11,[sp,#0] ++ ror w16,w24,#6 ++ add w27,w27,w19 // h+=K[i] ++ ror w10,w5,#7 ++ and w17,w25,w24 ++ ror w9,w2,#17 ++ bic w19,w26,w24 ++ ror w11,w20,#2 ++ add w27,w27,w3 // h+=X[i] ++ eor w16,w16,w24,ror#11 ++ eor w10,w10,w5,ror#18 ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w20,w21 // a^b, b^c in next round ++ eor w16,w16,w24,ror#25 // Sigma1(e) ++ eor w11,w11,w20,ror#13 ++ add w27,w27,w17 // h+=Ch(e,f,g) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ eor w9,w9,w2,ror#19 ++ eor w10,w10,w5,lsr#3 // sigma0(X[i+1]) ++ add w27,w27,w16 // h+=Sigma1(e) ++ eor w28,w28,w21 // Maj(a,b,c) ++ eor w17,w11,w20,ror#22 // Sigma0(a) ++ eor w9,w9,w2,lsr#10 // sigma1(X[i+14]) ++ add w4,w4,w13 ++ add w23,w23,w27 // d+=h ++ add w27,w27,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ add w4,w4,w10 ++ add w27,w27,w17 // h+=Sigma0(a) ++ add w4,w4,w9 ++ ldr w9,[sp,#8] ++ str w12,[sp,#4] ++ ror w16,w23,#6 ++ add w26,w26,w28 // h+=K[i] ++ ror w11,w6,#7 ++ and w17,w24,w23 ++ ror w10,w3,#17 ++ bic w28,w25,w23 ++ ror w12,w27,#2 ++ add w26,w26,w4 // h+=X[i] ++ eor w16,w16,w23,ror#11 ++ eor w11,w11,w6,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w27,w20 // a^b, b^c in next round ++ eor w16,w16,w23,ror#25 // Sigma1(e) ++ eor w12,w12,w27,ror#13 ++ add w26,w26,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w10,w10,w3,ror#19 ++ eor w11,w11,w6,lsr#3 // sigma0(X[i+1]) ++ add w26,w26,w16 // h+=Sigma1(e) ++ eor w19,w19,w20 // Maj(a,b,c) ++ eor w17,w12,w27,ror#22 // Sigma0(a) ++ eor w10,w10,w3,lsr#10 // sigma1(X[i+14]) ++ add w5,w5,w14 ++ add w22,w22,w26 // d+=h ++ add w26,w26,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w5,w5,w11 ++ add w26,w26,w17 // h+=Sigma0(a) ++ add w5,w5,w10 ++ ldr w10,[sp,#12] ++ str w13,[sp,#8] ++ ror w16,w22,#6 ++ add w25,w25,w19 // h+=K[i] ++ ror w12,w7,#7 ++ and w17,w23,w22 ++ ror w11,w4,#17 ++ bic w19,w24,w22 ++ ror w13,w26,#2 ++ add w25,w25,w5 // h+=X[i] ++ eor w16,w16,w22,ror#11 ++ eor w12,w12,w7,ror#18 ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w26,w27 // a^b, b^c in next round ++ eor w16,w16,w22,ror#25 // Sigma1(e) ++ eor w13,w13,w26,ror#13 ++ add w25,w25,w17 // h+=Ch(e,f,g) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ eor w11,w11,w4,ror#19 ++ eor w12,w12,w7,lsr#3 // sigma0(X[i+1]) ++ add w25,w25,w16 // h+=Sigma1(e) ++ eor w28,w28,w27 // Maj(a,b,c) ++ eor w17,w13,w26,ror#22 // Sigma0(a) ++ eor w11,w11,w4,lsr#10 // sigma1(X[i+14]) ++ add w6,w6,w15 ++ add w21,w21,w25 // d+=h ++ add w25,w25,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ add w6,w6,w12 ++ add w25,w25,w17 // h+=Sigma0(a) ++ add w6,w6,w11 ++ ldr w11,[sp,#0] ++ str w14,[sp,#12] ++ ror w16,w21,#6 ++ add w24,w24,w28 // h+=K[i] ++ ror w13,w8,#7 ++ and w17,w22,w21 ++ ror w12,w5,#17 ++ bic w28,w23,w21 ++ ror w14,w25,#2 ++ add w24,w24,w6 // h+=X[i] ++ eor w16,w16,w21,ror#11 ++ eor w13,w13,w8,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w25,w26 // a^b, b^c in next round ++ eor w16,w16,w21,ror#25 // Sigma1(e) ++ eor w14,w14,w25,ror#13 ++ add w24,w24,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w12,w12,w5,ror#19 ++ eor w13,w13,w8,lsr#3 // sigma0(X[i+1]) ++ add w24,w24,w16 // h+=Sigma1(e) ++ eor w19,w19,w26 // Maj(a,b,c) ++ eor w17,w14,w25,ror#22 // Sigma0(a) ++ eor w12,w12,w5,lsr#10 // sigma1(X[i+14]) ++ add w7,w7,w0 ++ add w20,w20,w24 // d+=h ++ add w24,w24,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w7,w7,w13 ++ add w24,w24,w17 // h+=Sigma0(a) ++ add w7,w7,w12 ++ ldr w12,[sp,#4] ++ str w15,[sp,#0] ++ ror w16,w20,#6 ++ add w23,w23,w19 // h+=K[i] ++ ror w14,w9,#7 ++ and w17,w21,w20 ++ ror w13,w6,#17 ++ bic w19,w22,w20 ++ ror w15,w24,#2 ++ add w23,w23,w7 // h+=X[i] ++ eor w16,w16,w20,ror#11 ++ eor w14,w14,w9,ror#18 ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w24,w25 // a^b, b^c in next round ++ eor w16,w16,w20,ror#25 // Sigma1(e) ++ eor w15,w15,w24,ror#13 ++ add w23,w23,w17 // h+=Ch(e,f,g) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ eor w13,w13,w6,ror#19 ++ eor w14,w14,w9,lsr#3 // sigma0(X[i+1]) ++ add w23,w23,w16 // h+=Sigma1(e) ++ eor w28,w28,w25 // Maj(a,b,c) ++ eor w17,w15,w24,ror#22 // Sigma0(a) ++ eor w13,w13,w6,lsr#10 // sigma1(X[i+14]) ++ add w8,w8,w1 ++ add w27,w27,w23 // d+=h ++ add w23,w23,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ add w8,w8,w14 ++ add w23,w23,w17 // h+=Sigma0(a) ++ add w8,w8,w13 ++ ldr w13,[sp,#8] ++ str w0,[sp,#4] ++ ror w16,w27,#6 ++ add w22,w22,w28 // h+=K[i] ++ ror w15,w10,#7 ++ and w17,w20,w27 ++ ror w14,w7,#17 ++ bic w28,w21,w27 ++ ror w0,w23,#2 ++ add w22,w22,w8 // h+=X[i] ++ eor w16,w16,w27,ror#11 ++ eor w15,w15,w10,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w23,w24 // a^b, b^c in next round ++ eor w16,w16,w27,ror#25 // Sigma1(e) ++ eor w0,w0,w23,ror#13 ++ add w22,w22,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w14,w14,w7,ror#19 ++ eor w15,w15,w10,lsr#3 // sigma0(X[i+1]) ++ add w22,w22,w16 // h+=Sigma1(e) ++ eor w19,w19,w24 // Maj(a,b,c) ++ eor w17,w0,w23,ror#22 // Sigma0(a) ++ eor w14,w14,w7,lsr#10 // sigma1(X[i+14]) ++ add w9,w9,w2 ++ add w26,w26,w22 // d+=h ++ add w22,w22,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w9,w9,w15 ++ add w22,w22,w17 // h+=Sigma0(a) ++ add w9,w9,w14 ++ ldr w14,[sp,#12] ++ str w1,[sp,#8] ++ ror w16,w26,#6 ++ add w21,w21,w19 // h+=K[i] ++ ror w0,w11,#7 ++ and w17,w27,w26 ++ ror w15,w8,#17 ++ bic w19,w20,w26 ++ ror w1,w22,#2 ++ add w21,w21,w9 // h+=X[i] ++ eor w16,w16,w26,ror#11 ++ eor w0,w0,w11,ror#18 ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w22,w23 // a^b, b^c in next round ++ eor w16,w16,w26,ror#25 // Sigma1(e) ++ eor w1,w1,w22,ror#13 ++ add w21,w21,w17 // h+=Ch(e,f,g) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ eor w15,w15,w8,ror#19 ++ eor w0,w0,w11,lsr#3 // sigma0(X[i+1]) ++ add w21,w21,w16 // h+=Sigma1(e) ++ eor w28,w28,w23 // Maj(a,b,c) ++ eor w17,w1,w22,ror#22 // Sigma0(a) ++ eor w15,w15,w8,lsr#10 // sigma1(X[i+14]) ++ add w10,w10,w3 ++ add w25,w25,w21 // d+=h ++ add w21,w21,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ add w10,w10,w0 ++ add w21,w21,w17 // h+=Sigma0(a) ++ add w10,w10,w15 ++ ldr w15,[sp,#0] ++ str w2,[sp,#12] ++ ror w16,w25,#6 ++ add w20,w20,w28 // h+=K[i] ++ ror w1,w12,#7 ++ and w17,w26,w25 ++ ror w0,w9,#17 ++ bic w28,w27,w25 ++ ror w2,w21,#2 ++ add w20,w20,w10 // h+=X[i] ++ eor w16,w16,w25,ror#11 ++ eor w1,w1,w12,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w21,w22 // a^b, b^c in next round ++ eor w16,w16,w25,ror#25 // Sigma1(e) ++ eor w2,w2,w21,ror#13 ++ add w20,w20,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w0,w0,w9,ror#19 ++ eor w1,w1,w12,lsr#3 // sigma0(X[i+1]) ++ add w20,w20,w16 // h+=Sigma1(e) ++ eor w19,w19,w22 // Maj(a,b,c) ++ eor w17,w2,w21,ror#22 // Sigma0(a) ++ eor w0,w0,w9,lsr#10 // sigma1(X[i+14]) ++ add w11,w11,w4 ++ add w24,w24,w20 // d+=h ++ add w20,w20,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w11,w11,w1 ++ add w20,w20,w17 // h+=Sigma0(a) ++ add w11,w11,w0 ++ ldr w0,[sp,#4] ++ str w3,[sp,#0] ++ ror w16,w24,#6 ++ add w27,w27,w19 // h+=K[i] ++ ror w2,w13,#7 ++ and w17,w25,w24 ++ ror w1,w10,#17 ++ bic w19,w26,w24 ++ ror w3,w20,#2 ++ add w27,w27,w11 // h+=X[i] ++ eor w16,w16,w24,ror#11 ++ eor w2,w2,w13,ror#18 ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w20,w21 // a^b, b^c in next round ++ eor w16,w16,w24,ror#25 // Sigma1(e) ++ eor w3,w3,w20,ror#13 ++ add w27,w27,w17 // h+=Ch(e,f,g) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ eor w1,w1,w10,ror#19 ++ eor w2,w2,w13,lsr#3 // sigma0(X[i+1]) ++ add w27,w27,w16 // h+=Sigma1(e) ++ eor w28,w28,w21 // Maj(a,b,c) ++ eor w17,w3,w20,ror#22 // Sigma0(a) ++ eor w1,w1,w10,lsr#10 // sigma1(X[i+14]) ++ add w12,w12,w5 ++ add w23,w23,w27 // d+=h ++ add w27,w27,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ add w12,w12,w2 ++ add w27,w27,w17 // h+=Sigma0(a) ++ add w12,w12,w1 ++ ldr w1,[sp,#8] ++ str w4,[sp,#4] ++ ror w16,w23,#6 ++ add w26,w26,w28 // h+=K[i] ++ ror w3,w14,#7 ++ and w17,w24,w23 ++ ror w2,w11,#17 ++ bic w28,w25,w23 ++ ror w4,w27,#2 ++ add w26,w26,w12 // h+=X[i] ++ eor w16,w16,w23,ror#11 ++ eor w3,w3,w14,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w27,w20 // a^b, b^c in next round ++ eor w16,w16,w23,ror#25 // Sigma1(e) ++ eor w4,w4,w27,ror#13 ++ add w26,w26,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w2,w2,w11,ror#19 ++ eor w3,w3,w14,lsr#3 // sigma0(X[i+1]) ++ add w26,w26,w16 // h+=Sigma1(e) ++ eor w19,w19,w20 // Maj(a,b,c) ++ eor w17,w4,w27,ror#22 // Sigma0(a) ++ eor w2,w2,w11,lsr#10 // sigma1(X[i+14]) ++ add w13,w13,w6 ++ add w22,w22,w26 // d+=h ++ add w26,w26,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w13,w13,w3 ++ add w26,w26,w17 // h+=Sigma0(a) ++ add w13,w13,w2 ++ ldr w2,[sp,#12] ++ str w5,[sp,#8] ++ ror w16,w22,#6 ++ add w25,w25,w19 // h+=K[i] ++ ror w4,w15,#7 ++ and w17,w23,w22 ++ ror w3,w12,#17 ++ bic w19,w24,w22 ++ ror w5,w26,#2 ++ add w25,w25,w13 // h+=X[i] ++ eor w16,w16,w22,ror#11 ++ eor w4,w4,w15,ror#18 ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w26,w27 // a^b, b^c in next round ++ eor w16,w16,w22,ror#25 // Sigma1(e) ++ eor w5,w5,w26,ror#13 ++ add w25,w25,w17 // h+=Ch(e,f,g) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ eor w3,w3,w12,ror#19 ++ eor w4,w4,w15,lsr#3 // sigma0(X[i+1]) ++ add w25,w25,w16 // h+=Sigma1(e) ++ eor w28,w28,w27 // Maj(a,b,c) ++ eor w17,w5,w26,ror#22 // Sigma0(a) ++ eor w3,w3,w12,lsr#10 // sigma1(X[i+14]) ++ add w14,w14,w7 ++ add w21,w21,w25 // d+=h ++ add w25,w25,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ add w14,w14,w4 ++ add w25,w25,w17 // h+=Sigma0(a) ++ add w14,w14,w3 ++ ldr w3,[sp,#0] ++ str w6,[sp,#12] ++ ror w16,w21,#6 ++ add w24,w24,w28 // h+=K[i] ++ ror w5,w0,#7 ++ and w17,w22,w21 ++ ror w4,w13,#17 ++ bic w28,w23,w21 ++ ror w6,w25,#2 ++ add w24,w24,w14 // h+=X[i] ++ eor w16,w16,w21,ror#11 ++ eor w5,w5,w0,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w25,w26 // a^b, b^c in next round ++ eor w16,w16,w21,ror#25 // Sigma1(e) ++ eor w6,w6,w25,ror#13 ++ add w24,w24,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w4,w4,w13,ror#19 ++ eor w5,w5,w0,lsr#3 // sigma0(X[i+1]) ++ add w24,w24,w16 // h+=Sigma1(e) ++ eor w19,w19,w26 // Maj(a,b,c) ++ eor w17,w6,w25,ror#22 // Sigma0(a) ++ eor w4,w4,w13,lsr#10 // sigma1(X[i+14]) ++ add w15,w15,w8 ++ add w20,w20,w24 // d+=h ++ add w24,w24,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w15,w15,w5 ++ add w24,w24,w17 // h+=Sigma0(a) ++ add w15,w15,w4 ++ ldr w4,[sp,#4] ++ str w7,[sp,#0] ++ ror w16,w20,#6 ++ add w23,w23,w19 // h+=K[i] ++ ror w6,w1,#7 ++ and w17,w21,w20 ++ ror w5,w14,#17 ++ bic w19,w22,w20 ++ ror w7,w24,#2 ++ add w23,w23,w15 // h+=X[i] ++ eor w16,w16,w20,ror#11 ++ eor w6,w6,w1,ror#18 ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w24,w25 // a^b, b^c in next round ++ eor w16,w16,w20,ror#25 // Sigma1(e) ++ eor w7,w7,w24,ror#13 ++ add w23,w23,w17 // h+=Ch(e,f,g) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ eor w5,w5,w14,ror#19 ++ eor w6,w6,w1,lsr#3 // sigma0(X[i+1]) ++ add w23,w23,w16 // h+=Sigma1(e) ++ eor w28,w28,w25 // Maj(a,b,c) ++ eor w17,w7,w24,ror#22 // Sigma0(a) ++ eor w5,w5,w14,lsr#10 // sigma1(X[i+14]) ++ add w0,w0,w9 ++ add w27,w27,w23 // d+=h ++ add w23,w23,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ add w0,w0,w6 ++ add w23,w23,w17 // h+=Sigma0(a) ++ add w0,w0,w5 ++ ldr w5,[sp,#8] ++ str w8,[sp,#4] ++ ror w16,w27,#6 ++ add w22,w22,w28 // h+=K[i] ++ ror w7,w2,#7 ++ and w17,w20,w27 ++ ror w6,w15,#17 ++ bic w28,w21,w27 ++ ror w8,w23,#2 ++ add w22,w22,w0 // h+=X[i] ++ eor w16,w16,w27,ror#11 ++ eor w7,w7,w2,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w23,w24 // a^b, b^c in next round ++ eor w16,w16,w27,ror#25 // Sigma1(e) ++ eor w8,w8,w23,ror#13 ++ add w22,w22,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w6,w6,w15,ror#19 ++ eor w7,w7,w2,lsr#3 // sigma0(X[i+1]) ++ add w22,w22,w16 // h+=Sigma1(e) ++ eor w19,w19,w24 // Maj(a,b,c) ++ eor w17,w8,w23,ror#22 // Sigma0(a) ++ eor w6,w6,w15,lsr#10 // sigma1(X[i+14]) ++ add w1,w1,w10 ++ add w26,w26,w22 // d+=h ++ add w22,w22,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w1,w1,w7 ++ add w22,w22,w17 // h+=Sigma0(a) ++ add w1,w1,w6 ++ ldr w6,[sp,#12] ++ str w9,[sp,#8] ++ ror w16,w26,#6 ++ add w21,w21,w19 // h+=K[i] ++ ror w8,w3,#7 ++ and w17,w27,w26 ++ ror w7,w0,#17 ++ bic w19,w20,w26 ++ ror w9,w22,#2 ++ add w21,w21,w1 // h+=X[i] ++ eor w16,w16,w26,ror#11 ++ eor w8,w8,w3,ror#18 ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w22,w23 // a^b, b^c in next round ++ eor w16,w16,w26,ror#25 // Sigma1(e) ++ eor w9,w9,w22,ror#13 ++ add w21,w21,w17 // h+=Ch(e,f,g) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ eor w7,w7,w0,ror#19 ++ eor w8,w8,w3,lsr#3 // sigma0(X[i+1]) ++ add w21,w21,w16 // h+=Sigma1(e) ++ eor w28,w28,w23 // Maj(a,b,c) ++ eor w17,w9,w22,ror#22 // Sigma0(a) ++ eor w7,w7,w0,lsr#10 // sigma1(X[i+14]) ++ add w2,w2,w11 ++ add w25,w25,w21 // d+=h ++ add w21,w21,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ add w2,w2,w8 ++ add w21,w21,w17 // h+=Sigma0(a) ++ add w2,w2,w7 ++ ldr w7,[sp,#0] ++ str w10,[sp,#12] ++ ror w16,w25,#6 ++ add w20,w20,w28 // h+=K[i] ++ ror w9,w4,#7 ++ and w17,w26,w25 ++ ror w8,w1,#17 ++ bic w28,w27,w25 ++ ror w10,w21,#2 ++ add w20,w20,w2 // h+=X[i] ++ eor w16,w16,w25,ror#11 ++ eor w9,w9,w4,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w21,w22 // a^b, b^c in next round ++ eor w16,w16,w25,ror#25 // Sigma1(e) ++ eor w10,w10,w21,ror#13 ++ add w20,w20,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w8,w8,w1,ror#19 ++ eor w9,w9,w4,lsr#3 // sigma0(X[i+1]) ++ add w20,w20,w16 // h+=Sigma1(e) ++ eor w19,w19,w22 // Maj(a,b,c) ++ eor w17,w10,w21,ror#22 // Sigma0(a) ++ eor w8,w8,w1,lsr#10 // sigma1(X[i+14]) ++ add w3,w3,w12 ++ add w24,w24,w20 // d+=h ++ add w20,w20,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w3,w3,w9 ++ add w20,w20,w17 // h+=Sigma0(a) ++ add w3,w3,w8 ++ cbnz w19,.Loop_16_xx ++ ++ ldp x0,x2,[x29,#96] ++ ldr x1,[x29,#112] ++ sub x30,x30,#260 // rewind ++ ++ ldp w3,w4,[x0] ++ ldp w5,w6,[x0,#2*4] ++ add x1,x1,#14*4 // advance input pointer ++ ldp w7,w8,[x0,#4*4] ++ add w20,w20,w3 ++ ldp w9,w10,[x0,#6*4] ++ add w21,w21,w4 ++ add w22,w22,w5 ++ add w23,w23,w6 ++ stp w20,w21,[x0] ++ add w24,w24,w7 ++ add w25,w25,w8 ++ stp w22,w23,[x0,#2*4] ++ add w26,w26,w9 ++ add w27,w27,w10 ++ cmp x1,x2 ++ stp w24,w25,[x0,#4*4] ++ stp w26,w27,[x0,#6*4] ++ b.ne .Loop ++ ++ ldp x19,x20,[x29,#16] ++ add sp,sp,#4*4 ++ ldp x21,x22,[x29,#32] ++ ldp x23,x24,[x29,#48] ++ ldp x25,x26,[x29,#64] ++ ldp x27,x28,[x29,#80] ++ ldp x29,x30,[sp],#128 ++ ret ++.size sha256_block_data_order,.-sha256_block_data_order ++ ++.align 6 ++.type .LK256,%object ++.LK256: ++ .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 ++ .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 ++ .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 ++ .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 ++ .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc ++ .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da ++ .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 ++ .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 ++ .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 ++ .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 ++ .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 ++ .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 ++ .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 ++ .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 ++ .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 ++ .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 ++ .long 0 //terminator ++.size .LK256,.-.LK256 ++#ifndef __KERNEL__ ++.align 3 ++.LOPENSSL_armcap_P: ++# ifdef __ILP32__ ++ .long OPENSSL_armcap_P-. ++# else ++ .quad OPENSSL_armcap_P-. ++# endif ++#endif ++.asciz "SHA256 block transform for ARMv8, CRYPTOGAMS by " ++.align 2 ++#ifndef __KERNEL__ ++.type sha256_block_armv8,%function ++.align 6 ++sha256_block_armv8: ++.Lv8_entry: ++ stp x29,x30,[sp,#-16]! ++ add x29,sp,#0 ++ ++ ld1 {v0.4s,v1.4s},[x0] ++ adr x3,.LK256 ++ ++.Loop_hw: ++ ld1 {v4.16b-v7.16b},[x1],#64 ++ sub x2,x2,#1 ++ ld1 {v16.4s},[x3],#16 ++ rev32 v4.16b,v4.16b ++ rev32 v5.16b,v5.16b ++ rev32 v6.16b,v6.16b ++ rev32 v7.16b,v7.16b ++ orr v18.16b,v0.16b,v0.16b // offload ++ orr v19.16b,v1.16b,v1.16b ++ ld1 {v17.4s},[x3],#16 ++ add v16.4s,v16.4s,v4.4s ++ .inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s ++ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s ++ .inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b ++ ld1 {v16.4s},[x3],#16 ++ add v17.4s,v17.4s,v5.4s ++ .inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s ++ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s ++ .inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b ++ ld1 {v17.4s},[x3],#16 ++ add v16.4s,v16.4s,v6.4s ++ .inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s ++ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s ++ .inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b ++ ld1 {v16.4s},[x3],#16 ++ add v17.4s,v17.4s,v7.4s ++ .inst 0x5e282887 //sha256su0 v7.16b,v4.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s ++ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s ++ .inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b ++ ld1 {v17.4s},[x3],#16 ++ add v16.4s,v16.4s,v4.4s ++ .inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s ++ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s ++ .inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b ++ ld1 {v16.4s},[x3],#16 ++ add v17.4s,v17.4s,v5.4s ++ .inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s ++ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s ++ .inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b ++ ld1 {v17.4s},[x3],#16 ++ add v16.4s,v16.4s,v6.4s ++ .inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s ++ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s ++ .inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b ++ ld1 {v16.4s},[x3],#16 ++ add v17.4s,v17.4s,v7.4s ++ .inst 0x5e282887 //sha256su0 v7.16b,v4.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s ++ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s ++ .inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b ++ ld1 {v17.4s},[x3],#16 ++ add v16.4s,v16.4s,v4.4s ++ .inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s ++ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s ++ .inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b ++ ld1 {v16.4s},[x3],#16 ++ add v17.4s,v17.4s,v5.4s ++ .inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s ++ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s ++ .inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b ++ ld1 {v17.4s},[x3],#16 ++ add v16.4s,v16.4s,v6.4s ++ .inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s ++ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s ++ .inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b ++ ld1 {v16.4s},[x3],#16 ++ add v17.4s,v17.4s,v7.4s ++ .inst 0x5e282887 //sha256su0 v7.16b,v4.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s ++ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s ++ .inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b ++ ld1 {v17.4s},[x3],#16 ++ add v16.4s,v16.4s,v4.4s ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s ++ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s ++ ++ ld1 {v16.4s},[x3],#16 ++ add v17.4s,v17.4s,v5.4s ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s ++ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s ++ ++ ld1 {v17.4s},[x3] ++ add v16.4s,v16.4s,v6.4s ++ sub x3,x3,#64*4-16 // rewind ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s ++ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s ++ ++ add v17.4s,v17.4s,v7.4s ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s ++ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s ++ ++ add v0.4s,v0.4s,v18.4s ++ add v1.4s,v1.4s,v19.4s ++ ++ cbnz x2,.Loop_hw ++ ++ st1 {v0.4s,v1.4s},[x0] ++ ++ ldr x29,[sp],#16 ++ ret ++.size sha256_block_armv8,.-sha256_block_armv8 ++#endif ++#ifdef __KERNEL__ ++.globl sha256_block_neon ++#endif ++.type sha256_block_neon,%function ++.align 4 ++sha256_block_neon: ++.Lneon_entry: ++ stp x29, x30, [sp, #-16]! ++ mov x29, sp ++ sub sp,sp,#16*4 ++ ++ adr x16,.LK256 ++ add x2,x1,x2,lsl#6 // len to point at the end of inp ++ ++ ld1 {v0.16b},[x1], #16 ++ ld1 {v1.16b},[x1], #16 ++ ld1 {v2.16b},[x1], #16 ++ ld1 {v3.16b},[x1], #16 ++ ld1 {v4.4s},[x16], #16 ++ ld1 {v5.4s},[x16], #16 ++ ld1 {v6.4s},[x16], #16 ++ ld1 {v7.4s},[x16], #16 ++ rev32 v0.16b,v0.16b // yes, even on ++ rev32 v1.16b,v1.16b // big-endian ++ rev32 v2.16b,v2.16b ++ rev32 v3.16b,v3.16b ++ mov x17,sp ++ add v4.4s,v4.4s,v0.4s ++ add v5.4s,v5.4s,v1.4s ++ add v6.4s,v6.4s,v2.4s ++ st1 {v4.4s-v5.4s},[x17], #32 ++ add v7.4s,v7.4s,v3.4s ++ st1 {v6.4s-v7.4s},[x17] ++ sub x17,x17,#32 ++ ++ ldp w3,w4,[x0] ++ ldp w5,w6,[x0,#8] ++ ldp w7,w8,[x0,#16] ++ ldp w9,w10,[x0,#24] ++ ldr w12,[sp,#0] ++ mov w13,wzr ++ eor w14,w4,w5 ++ mov w15,wzr ++ b .L_00_48 ++ ++.align 4 ++.L_00_48: ++ ext v4.16b,v0.16b,v1.16b,#4 ++ add w10,w10,w12 ++ add w3,w3,w15 ++ and w12,w8,w7 ++ bic w15,w9,w7 ++ ext v7.16b,v2.16b,v3.16b,#4 ++ eor w11,w7,w7,ror#5 ++ add w3,w3,w13 ++ mov d19,v3.d[1] ++ orr w12,w12,w15 ++ eor w11,w11,w7,ror#19 ++ ushr v6.4s,v4.4s,#7 ++ eor w15,w3,w3,ror#11 ++ ushr v5.4s,v4.4s,#3 ++ add w10,w10,w12 ++ add v0.4s,v0.4s,v7.4s ++ ror w11,w11,#6 ++ sli v6.4s,v4.4s,#25 ++ eor w13,w3,w4 ++ eor w15,w15,w3,ror#20 ++ ushr v7.4s,v4.4s,#18 ++ add w10,w10,w11 ++ ldr w12,[sp,#4] ++ and w14,w14,w13 ++ eor v5.16b,v5.16b,v6.16b ++ ror w15,w15,#2 ++ add w6,w6,w10 ++ sli v7.4s,v4.4s,#14 ++ eor w14,w14,w4 ++ ushr v16.4s,v19.4s,#17 ++ add w9,w9,w12 ++ add w10,w10,w15 ++ and w12,w7,w6 ++ eor v5.16b,v5.16b,v7.16b ++ bic w15,w8,w6 ++ eor w11,w6,w6,ror#5 ++ sli v16.4s,v19.4s,#15 ++ add w10,w10,w14 ++ orr w12,w12,w15 ++ ushr v17.4s,v19.4s,#10 ++ eor w11,w11,w6,ror#19 ++ eor w15,w10,w10,ror#11 ++ ushr v7.4s,v19.4s,#19 ++ add w9,w9,w12 ++ ror w11,w11,#6 ++ add v0.4s,v0.4s,v5.4s ++ eor w14,w10,w3 ++ eor w15,w15,w10,ror#20 ++ sli v7.4s,v19.4s,#13 ++ add w9,w9,w11 ++ ldr w12,[sp,#8] ++ and w13,w13,w14 ++ eor v17.16b,v17.16b,v16.16b ++ ror w15,w15,#2 ++ add w5,w5,w9 ++ eor w13,w13,w3 ++ eor v17.16b,v17.16b,v7.16b ++ add w8,w8,w12 ++ add w9,w9,w15 ++ and w12,w6,w5 ++ add v0.4s,v0.4s,v17.4s ++ bic w15,w7,w5 ++ eor w11,w5,w5,ror#5 ++ add w9,w9,w13 ++ ushr v18.4s,v0.4s,#17 ++ orr w12,w12,w15 ++ ushr v19.4s,v0.4s,#10 ++ eor w11,w11,w5,ror#19 ++ eor w15,w9,w9,ror#11 ++ sli v18.4s,v0.4s,#15 ++ add w8,w8,w12 ++ ushr v17.4s,v0.4s,#19 ++ ror w11,w11,#6 ++ eor w13,w9,w10 ++ eor v19.16b,v19.16b,v18.16b ++ eor w15,w15,w9,ror#20 ++ add w8,w8,w11 ++ sli v17.4s,v0.4s,#13 ++ ldr w12,[sp,#12] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ ld1 {v4.4s},[x16], #16 ++ add w4,w4,w8 ++ eor v19.16b,v19.16b,v17.16b ++ eor w14,w14,w10 ++ eor v17.16b,v17.16b,v17.16b ++ add w7,w7,w12 ++ add w8,w8,w15 ++ and w12,w5,w4 ++ mov v17.d[1],v19.d[0] ++ bic w15,w6,w4 ++ eor w11,w4,w4,ror#5 ++ add w8,w8,w14 ++ add v0.4s,v0.4s,v17.4s ++ orr w12,w12,w15 ++ eor w11,w11,w4,ror#19 ++ eor w15,w8,w8,ror#11 ++ add v4.4s,v4.4s,v0.4s ++ add w7,w7,w12 ++ ror w11,w11,#6 ++ eor w14,w8,w9 ++ eor w15,w15,w8,ror#20 ++ add w7,w7,w11 ++ ldr w12,[sp,#16] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w3,w3,w7 ++ eor w13,w13,w9 ++ st1 {v4.4s},[x17], #16 ++ ext v4.16b,v1.16b,v2.16b,#4 ++ add w6,w6,w12 ++ add w7,w7,w15 ++ and w12,w4,w3 ++ bic w15,w5,w3 ++ ext v7.16b,v3.16b,v0.16b,#4 ++ eor w11,w3,w3,ror#5 ++ add w7,w7,w13 ++ mov d19,v0.d[1] ++ orr w12,w12,w15 ++ eor w11,w11,w3,ror#19 ++ ushr v6.4s,v4.4s,#7 ++ eor w15,w7,w7,ror#11 ++ ushr v5.4s,v4.4s,#3 ++ add w6,w6,w12 ++ add v1.4s,v1.4s,v7.4s ++ ror w11,w11,#6 ++ sli v6.4s,v4.4s,#25 ++ eor w13,w7,w8 ++ eor w15,w15,w7,ror#20 ++ ushr v7.4s,v4.4s,#18 ++ add w6,w6,w11 ++ ldr w12,[sp,#20] ++ and w14,w14,w13 ++ eor v5.16b,v5.16b,v6.16b ++ ror w15,w15,#2 ++ add w10,w10,w6 ++ sli v7.4s,v4.4s,#14 ++ eor w14,w14,w8 ++ ushr v16.4s,v19.4s,#17 ++ add w5,w5,w12 ++ add w6,w6,w15 ++ and w12,w3,w10 ++ eor v5.16b,v5.16b,v7.16b ++ bic w15,w4,w10 ++ eor w11,w10,w10,ror#5 ++ sli v16.4s,v19.4s,#15 ++ add w6,w6,w14 ++ orr w12,w12,w15 ++ ushr v17.4s,v19.4s,#10 ++ eor w11,w11,w10,ror#19 ++ eor w15,w6,w6,ror#11 ++ ushr v7.4s,v19.4s,#19 ++ add w5,w5,w12 ++ ror w11,w11,#6 ++ add v1.4s,v1.4s,v5.4s ++ eor w14,w6,w7 ++ eor w15,w15,w6,ror#20 ++ sli v7.4s,v19.4s,#13 ++ add w5,w5,w11 ++ ldr w12,[sp,#24] ++ and w13,w13,w14 ++ eor v17.16b,v17.16b,v16.16b ++ ror w15,w15,#2 ++ add w9,w9,w5 ++ eor w13,w13,w7 ++ eor v17.16b,v17.16b,v7.16b ++ add w4,w4,w12 ++ add w5,w5,w15 ++ and w12,w10,w9 ++ add v1.4s,v1.4s,v17.4s ++ bic w15,w3,w9 ++ eor w11,w9,w9,ror#5 ++ add w5,w5,w13 ++ ushr v18.4s,v1.4s,#17 ++ orr w12,w12,w15 ++ ushr v19.4s,v1.4s,#10 ++ eor w11,w11,w9,ror#19 ++ eor w15,w5,w5,ror#11 ++ sli v18.4s,v1.4s,#15 ++ add w4,w4,w12 ++ ushr v17.4s,v1.4s,#19 ++ ror w11,w11,#6 ++ eor w13,w5,w6 ++ eor v19.16b,v19.16b,v18.16b ++ eor w15,w15,w5,ror#20 ++ add w4,w4,w11 ++ sli v17.4s,v1.4s,#13 ++ ldr w12,[sp,#28] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ ld1 {v4.4s},[x16], #16 ++ add w8,w8,w4 ++ eor v19.16b,v19.16b,v17.16b ++ eor w14,w14,w6 ++ eor v17.16b,v17.16b,v17.16b ++ add w3,w3,w12 ++ add w4,w4,w15 ++ and w12,w9,w8 ++ mov v17.d[1],v19.d[0] ++ bic w15,w10,w8 ++ eor w11,w8,w8,ror#5 ++ add w4,w4,w14 ++ add v1.4s,v1.4s,v17.4s ++ orr w12,w12,w15 ++ eor w11,w11,w8,ror#19 ++ eor w15,w4,w4,ror#11 ++ add v4.4s,v4.4s,v1.4s ++ add w3,w3,w12 ++ ror w11,w11,#6 ++ eor w14,w4,w5 ++ eor w15,w15,w4,ror#20 ++ add w3,w3,w11 ++ ldr w12,[sp,#32] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w7,w7,w3 ++ eor w13,w13,w5 ++ st1 {v4.4s},[x17], #16 ++ ext v4.16b,v2.16b,v3.16b,#4 ++ add w10,w10,w12 ++ add w3,w3,w15 ++ and w12,w8,w7 ++ bic w15,w9,w7 ++ ext v7.16b,v0.16b,v1.16b,#4 ++ eor w11,w7,w7,ror#5 ++ add w3,w3,w13 ++ mov d19,v1.d[1] ++ orr w12,w12,w15 ++ eor w11,w11,w7,ror#19 ++ ushr v6.4s,v4.4s,#7 ++ eor w15,w3,w3,ror#11 ++ ushr v5.4s,v4.4s,#3 ++ add w10,w10,w12 ++ add v2.4s,v2.4s,v7.4s ++ ror w11,w11,#6 ++ sli v6.4s,v4.4s,#25 ++ eor w13,w3,w4 ++ eor w15,w15,w3,ror#20 ++ ushr v7.4s,v4.4s,#18 ++ add w10,w10,w11 ++ ldr w12,[sp,#36] ++ and w14,w14,w13 ++ eor v5.16b,v5.16b,v6.16b ++ ror w15,w15,#2 ++ add w6,w6,w10 ++ sli v7.4s,v4.4s,#14 ++ eor w14,w14,w4 ++ ushr v16.4s,v19.4s,#17 ++ add w9,w9,w12 ++ add w10,w10,w15 ++ and w12,w7,w6 ++ eor v5.16b,v5.16b,v7.16b ++ bic w15,w8,w6 ++ eor w11,w6,w6,ror#5 ++ sli v16.4s,v19.4s,#15 ++ add w10,w10,w14 ++ orr w12,w12,w15 ++ ushr v17.4s,v19.4s,#10 ++ eor w11,w11,w6,ror#19 ++ eor w15,w10,w10,ror#11 ++ ushr v7.4s,v19.4s,#19 ++ add w9,w9,w12 ++ ror w11,w11,#6 ++ add v2.4s,v2.4s,v5.4s ++ eor w14,w10,w3 ++ eor w15,w15,w10,ror#20 ++ sli v7.4s,v19.4s,#13 ++ add w9,w9,w11 ++ ldr w12,[sp,#40] ++ and w13,w13,w14 ++ eor v17.16b,v17.16b,v16.16b ++ ror w15,w15,#2 ++ add w5,w5,w9 ++ eor w13,w13,w3 ++ eor v17.16b,v17.16b,v7.16b ++ add w8,w8,w12 ++ add w9,w9,w15 ++ and w12,w6,w5 ++ add v2.4s,v2.4s,v17.4s ++ bic w15,w7,w5 ++ eor w11,w5,w5,ror#5 ++ add w9,w9,w13 ++ ushr v18.4s,v2.4s,#17 ++ orr w12,w12,w15 ++ ushr v19.4s,v2.4s,#10 ++ eor w11,w11,w5,ror#19 ++ eor w15,w9,w9,ror#11 ++ sli v18.4s,v2.4s,#15 ++ add w8,w8,w12 ++ ushr v17.4s,v2.4s,#19 ++ ror w11,w11,#6 ++ eor w13,w9,w10 ++ eor v19.16b,v19.16b,v18.16b ++ eor w15,w15,w9,ror#20 ++ add w8,w8,w11 ++ sli v17.4s,v2.4s,#13 ++ ldr w12,[sp,#44] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ ld1 {v4.4s},[x16], #16 ++ add w4,w4,w8 ++ eor v19.16b,v19.16b,v17.16b ++ eor w14,w14,w10 ++ eor v17.16b,v17.16b,v17.16b ++ add w7,w7,w12 ++ add w8,w8,w15 ++ and w12,w5,w4 ++ mov v17.d[1],v19.d[0] ++ bic w15,w6,w4 ++ eor w11,w4,w4,ror#5 ++ add w8,w8,w14 ++ add v2.4s,v2.4s,v17.4s ++ orr w12,w12,w15 ++ eor w11,w11,w4,ror#19 ++ eor w15,w8,w8,ror#11 ++ add v4.4s,v4.4s,v2.4s ++ add w7,w7,w12 ++ ror w11,w11,#6 ++ eor w14,w8,w9 ++ eor w15,w15,w8,ror#20 ++ add w7,w7,w11 ++ ldr w12,[sp,#48] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w3,w3,w7 ++ eor w13,w13,w9 ++ st1 {v4.4s},[x17], #16 ++ ext v4.16b,v3.16b,v0.16b,#4 ++ add w6,w6,w12 ++ add w7,w7,w15 ++ and w12,w4,w3 ++ bic w15,w5,w3 ++ ext v7.16b,v1.16b,v2.16b,#4 ++ eor w11,w3,w3,ror#5 ++ add w7,w7,w13 ++ mov d19,v2.d[1] ++ orr w12,w12,w15 ++ eor w11,w11,w3,ror#19 ++ ushr v6.4s,v4.4s,#7 ++ eor w15,w7,w7,ror#11 ++ ushr v5.4s,v4.4s,#3 ++ add w6,w6,w12 ++ add v3.4s,v3.4s,v7.4s ++ ror w11,w11,#6 ++ sli v6.4s,v4.4s,#25 ++ eor w13,w7,w8 ++ eor w15,w15,w7,ror#20 ++ ushr v7.4s,v4.4s,#18 ++ add w6,w6,w11 ++ ldr w12,[sp,#52] ++ and w14,w14,w13 ++ eor v5.16b,v5.16b,v6.16b ++ ror w15,w15,#2 ++ add w10,w10,w6 ++ sli v7.4s,v4.4s,#14 ++ eor w14,w14,w8 ++ ushr v16.4s,v19.4s,#17 ++ add w5,w5,w12 ++ add w6,w6,w15 ++ and w12,w3,w10 ++ eor v5.16b,v5.16b,v7.16b ++ bic w15,w4,w10 ++ eor w11,w10,w10,ror#5 ++ sli v16.4s,v19.4s,#15 ++ add w6,w6,w14 ++ orr w12,w12,w15 ++ ushr v17.4s,v19.4s,#10 ++ eor w11,w11,w10,ror#19 ++ eor w15,w6,w6,ror#11 ++ ushr v7.4s,v19.4s,#19 ++ add w5,w5,w12 ++ ror w11,w11,#6 ++ add v3.4s,v3.4s,v5.4s ++ eor w14,w6,w7 ++ eor w15,w15,w6,ror#20 ++ sli v7.4s,v19.4s,#13 ++ add w5,w5,w11 ++ ldr w12,[sp,#56] ++ and w13,w13,w14 ++ eor v17.16b,v17.16b,v16.16b ++ ror w15,w15,#2 ++ add w9,w9,w5 ++ eor w13,w13,w7 ++ eor v17.16b,v17.16b,v7.16b ++ add w4,w4,w12 ++ add w5,w5,w15 ++ and w12,w10,w9 ++ add v3.4s,v3.4s,v17.4s ++ bic w15,w3,w9 ++ eor w11,w9,w9,ror#5 ++ add w5,w5,w13 ++ ushr v18.4s,v3.4s,#17 ++ orr w12,w12,w15 ++ ushr v19.4s,v3.4s,#10 ++ eor w11,w11,w9,ror#19 ++ eor w15,w5,w5,ror#11 ++ sli v18.4s,v3.4s,#15 ++ add w4,w4,w12 ++ ushr v17.4s,v3.4s,#19 ++ ror w11,w11,#6 ++ eor w13,w5,w6 ++ eor v19.16b,v19.16b,v18.16b ++ eor w15,w15,w5,ror#20 ++ add w4,w4,w11 ++ sli v17.4s,v3.4s,#13 ++ ldr w12,[sp,#60] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ ld1 {v4.4s},[x16], #16 ++ add w8,w8,w4 ++ eor v19.16b,v19.16b,v17.16b ++ eor w14,w14,w6 ++ eor v17.16b,v17.16b,v17.16b ++ add w3,w3,w12 ++ add w4,w4,w15 ++ and w12,w9,w8 ++ mov v17.d[1],v19.d[0] ++ bic w15,w10,w8 ++ eor w11,w8,w8,ror#5 ++ add w4,w4,w14 ++ add v3.4s,v3.4s,v17.4s ++ orr w12,w12,w15 ++ eor w11,w11,w8,ror#19 ++ eor w15,w4,w4,ror#11 ++ add v4.4s,v4.4s,v3.4s ++ add w3,w3,w12 ++ ror w11,w11,#6 ++ eor w14,w4,w5 ++ eor w15,w15,w4,ror#20 ++ add w3,w3,w11 ++ ldr w12,[x16] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w7,w7,w3 ++ eor w13,w13,w5 ++ st1 {v4.4s},[x17], #16 ++ cmp w12,#0 // check for K256 terminator ++ ldr w12,[sp,#0] ++ sub x17,x17,#64 ++ bne .L_00_48 ++ ++ sub x16,x16,#256 // rewind x16 ++ cmp x1,x2 ++ mov x17, #64 ++ csel x17, x17, xzr, eq ++ sub x1,x1,x17 // avoid SEGV ++ mov x17,sp ++ add w10,w10,w12 ++ add w3,w3,w15 ++ and w12,w8,w7 ++ ld1 {v0.16b},[x1],#16 ++ bic w15,w9,w7 ++ eor w11,w7,w7,ror#5 ++ ld1 {v4.4s},[x16],#16 ++ add w3,w3,w13 ++ orr w12,w12,w15 ++ eor w11,w11,w7,ror#19 ++ eor w15,w3,w3,ror#11 ++ rev32 v0.16b,v0.16b ++ add w10,w10,w12 ++ ror w11,w11,#6 ++ eor w13,w3,w4 ++ eor w15,w15,w3,ror#20 ++ add v4.4s,v4.4s,v0.4s ++ add w10,w10,w11 ++ ldr w12,[sp,#4] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ add w6,w6,w10 ++ eor w14,w14,w4 ++ add w9,w9,w12 ++ add w10,w10,w15 ++ and w12,w7,w6 ++ bic w15,w8,w6 ++ eor w11,w6,w6,ror#5 ++ add w10,w10,w14 ++ orr w12,w12,w15 ++ eor w11,w11,w6,ror#19 ++ eor w15,w10,w10,ror#11 ++ add w9,w9,w12 ++ ror w11,w11,#6 ++ eor w14,w10,w3 ++ eor w15,w15,w10,ror#20 ++ add w9,w9,w11 ++ ldr w12,[sp,#8] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w5,w5,w9 ++ eor w13,w13,w3 ++ add w8,w8,w12 ++ add w9,w9,w15 ++ and w12,w6,w5 ++ bic w15,w7,w5 ++ eor w11,w5,w5,ror#5 ++ add w9,w9,w13 ++ orr w12,w12,w15 ++ eor w11,w11,w5,ror#19 ++ eor w15,w9,w9,ror#11 ++ add w8,w8,w12 ++ ror w11,w11,#6 ++ eor w13,w9,w10 ++ eor w15,w15,w9,ror#20 ++ add w8,w8,w11 ++ ldr w12,[sp,#12] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ add w4,w4,w8 ++ eor w14,w14,w10 ++ add w7,w7,w12 ++ add w8,w8,w15 ++ and w12,w5,w4 ++ bic w15,w6,w4 ++ eor w11,w4,w4,ror#5 ++ add w8,w8,w14 ++ orr w12,w12,w15 ++ eor w11,w11,w4,ror#19 ++ eor w15,w8,w8,ror#11 ++ add w7,w7,w12 ++ ror w11,w11,#6 ++ eor w14,w8,w9 ++ eor w15,w15,w8,ror#20 ++ add w7,w7,w11 ++ ldr w12,[sp,#16] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w3,w3,w7 ++ eor w13,w13,w9 ++ st1 {v4.4s},[x17], #16 ++ add w6,w6,w12 ++ add w7,w7,w15 ++ and w12,w4,w3 ++ ld1 {v1.16b},[x1],#16 ++ bic w15,w5,w3 ++ eor w11,w3,w3,ror#5 ++ ld1 {v4.4s},[x16],#16 ++ add w7,w7,w13 ++ orr w12,w12,w15 ++ eor w11,w11,w3,ror#19 ++ eor w15,w7,w7,ror#11 ++ rev32 v1.16b,v1.16b ++ add w6,w6,w12 ++ ror w11,w11,#6 ++ eor w13,w7,w8 ++ eor w15,w15,w7,ror#20 ++ add v4.4s,v4.4s,v1.4s ++ add w6,w6,w11 ++ ldr w12,[sp,#20] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ add w10,w10,w6 ++ eor w14,w14,w8 ++ add w5,w5,w12 ++ add w6,w6,w15 ++ and w12,w3,w10 ++ bic w15,w4,w10 ++ eor w11,w10,w10,ror#5 ++ add w6,w6,w14 ++ orr w12,w12,w15 ++ eor w11,w11,w10,ror#19 ++ eor w15,w6,w6,ror#11 ++ add w5,w5,w12 ++ ror w11,w11,#6 ++ eor w14,w6,w7 ++ eor w15,w15,w6,ror#20 ++ add w5,w5,w11 ++ ldr w12,[sp,#24] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w9,w9,w5 ++ eor w13,w13,w7 ++ add w4,w4,w12 ++ add w5,w5,w15 ++ and w12,w10,w9 ++ bic w15,w3,w9 ++ eor w11,w9,w9,ror#5 ++ add w5,w5,w13 ++ orr w12,w12,w15 ++ eor w11,w11,w9,ror#19 ++ eor w15,w5,w5,ror#11 ++ add w4,w4,w12 ++ ror w11,w11,#6 ++ eor w13,w5,w6 ++ eor w15,w15,w5,ror#20 ++ add w4,w4,w11 ++ ldr w12,[sp,#28] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ add w8,w8,w4 ++ eor w14,w14,w6 ++ add w3,w3,w12 ++ add w4,w4,w15 ++ and w12,w9,w8 ++ bic w15,w10,w8 ++ eor w11,w8,w8,ror#5 ++ add w4,w4,w14 ++ orr w12,w12,w15 ++ eor w11,w11,w8,ror#19 ++ eor w15,w4,w4,ror#11 ++ add w3,w3,w12 ++ ror w11,w11,#6 ++ eor w14,w4,w5 ++ eor w15,w15,w4,ror#20 ++ add w3,w3,w11 ++ ldr w12,[sp,#32] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w7,w7,w3 ++ eor w13,w13,w5 ++ st1 {v4.4s},[x17], #16 ++ add w10,w10,w12 ++ add w3,w3,w15 ++ and w12,w8,w7 ++ ld1 {v2.16b},[x1],#16 ++ bic w15,w9,w7 ++ eor w11,w7,w7,ror#5 ++ ld1 {v4.4s},[x16],#16 ++ add w3,w3,w13 ++ orr w12,w12,w15 ++ eor w11,w11,w7,ror#19 ++ eor w15,w3,w3,ror#11 ++ rev32 v2.16b,v2.16b ++ add w10,w10,w12 ++ ror w11,w11,#6 ++ eor w13,w3,w4 ++ eor w15,w15,w3,ror#20 ++ add v4.4s,v4.4s,v2.4s ++ add w10,w10,w11 ++ ldr w12,[sp,#36] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ add w6,w6,w10 ++ eor w14,w14,w4 ++ add w9,w9,w12 ++ add w10,w10,w15 ++ and w12,w7,w6 ++ bic w15,w8,w6 ++ eor w11,w6,w6,ror#5 ++ add w10,w10,w14 ++ orr w12,w12,w15 ++ eor w11,w11,w6,ror#19 ++ eor w15,w10,w10,ror#11 ++ add w9,w9,w12 ++ ror w11,w11,#6 ++ eor w14,w10,w3 ++ eor w15,w15,w10,ror#20 ++ add w9,w9,w11 ++ ldr w12,[sp,#40] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w5,w5,w9 ++ eor w13,w13,w3 ++ add w8,w8,w12 ++ add w9,w9,w15 ++ and w12,w6,w5 ++ bic w15,w7,w5 ++ eor w11,w5,w5,ror#5 ++ add w9,w9,w13 ++ orr w12,w12,w15 ++ eor w11,w11,w5,ror#19 ++ eor w15,w9,w9,ror#11 ++ add w8,w8,w12 ++ ror w11,w11,#6 ++ eor w13,w9,w10 ++ eor w15,w15,w9,ror#20 ++ add w8,w8,w11 ++ ldr w12,[sp,#44] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ add w4,w4,w8 ++ eor w14,w14,w10 ++ add w7,w7,w12 ++ add w8,w8,w15 ++ and w12,w5,w4 ++ bic w15,w6,w4 ++ eor w11,w4,w4,ror#5 ++ add w8,w8,w14 ++ orr w12,w12,w15 ++ eor w11,w11,w4,ror#19 ++ eor w15,w8,w8,ror#11 ++ add w7,w7,w12 ++ ror w11,w11,#6 ++ eor w14,w8,w9 ++ eor w15,w15,w8,ror#20 ++ add w7,w7,w11 ++ ldr w12,[sp,#48] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w3,w3,w7 ++ eor w13,w13,w9 ++ st1 {v4.4s},[x17], #16 ++ add w6,w6,w12 ++ add w7,w7,w15 ++ and w12,w4,w3 ++ ld1 {v3.16b},[x1],#16 ++ bic w15,w5,w3 ++ eor w11,w3,w3,ror#5 ++ ld1 {v4.4s},[x16],#16 ++ add w7,w7,w13 ++ orr w12,w12,w15 ++ eor w11,w11,w3,ror#19 ++ eor w15,w7,w7,ror#11 ++ rev32 v3.16b,v3.16b ++ add w6,w6,w12 ++ ror w11,w11,#6 ++ eor w13,w7,w8 ++ eor w15,w15,w7,ror#20 ++ add v4.4s,v4.4s,v3.4s ++ add w6,w6,w11 ++ ldr w12,[sp,#52] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ add w10,w10,w6 ++ eor w14,w14,w8 ++ add w5,w5,w12 ++ add w6,w6,w15 ++ and w12,w3,w10 ++ bic w15,w4,w10 ++ eor w11,w10,w10,ror#5 ++ add w6,w6,w14 ++ orr w12,w12,w15 ++ eor w11,w11,w10,ror#19 ++ eor w15,w6,w6,ror#11 ++ add w5,w5,w12 ++ ror w11,w11,#6 ++ eor w14,w6,w7 ++ eor w15,w15,w6,ror#20 ++ add w5,w5,w11 ++ ldr w12,[sp,#56] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w9,w9,w5 ++ eor w13,w13,w7 ++ add w4,w4,w12 ++ add w5,w5,w15 ++ and w12,w10,w9 ++ bic w15,w3,w9 ++ eor w11,w9,w9,ror#5 ++ add w5,w5,w13 ++ orr w12,w12,w15 ++ eor w11,w11,w9,ror#19 ++ eor w15,w5,w5,ror#11 ++ add w4,w4,w12 ++ ror w11,w11,#6 ++ eor w13,w5,w6 ++ eor w15,w15,w5,ror#20 ++ add w4,w4,w11 ++ ldr w12,[sp,#60] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ add w8,w8,w4 ++ eor w14,w14,w6 ++ add w3,w3,w12 ++ add w4,w4,w15 ++ and w12,w9,w8 ++ bic w15,w10,w8 ++ eor w11,w8,w8,ror#5 ++ add w4,w4,w14 ++ orr w12,w12,w15 ++ eor w11,w11,w8,ror#19 ++ eor w15,w4,w4,ror#11 ++ add w3,w3,w12 ++ ror w11,w11,#6 ++ eor w14,w4,w5 ++ eor w15,w15,w4,ror#20 ++ add w3,w3,w11 ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w7,w7,w3 ++ eor w13,w13,w5 ++ st1 {v4.4s},[x17], #16 ++ add w3,w3,w15 // h+=Sigma0(a) from the past ++ ldp w11,w12,[x0,#0] ++ add w3,w3,w13 // h+=Maj(a,b,c) from the past ++ ldp w13,w14,[x0,#8] ++ add w3,w3,w11 // accumulate ++ add w4,w4,w12 ++ ldp w11,w12,[x0,#16] ++ add w5,w5,w13 ++ add w6,w6,w14 ++ ldp w13,w14,[x0,#24] ++ add w7,w7,w11 ++ add w8,w8,w12 ++ ldr w12,[sp,#0] ++ stp w3,w4,[x0,#0] ++ add w9,w9,w13 ++ mov w13,wzr ++ stp w5,w6,[x0,#8] ++ add w10,w10,w14 ++ stp w7,w8,[x0,#16] ++ eor w14,w4,w5 ++ stp w9,w10,[x0,#24] ++ mov w15,wzr ++ mov x17,sp ++ b.ne .L_00_48 ++ ++ ldr x29,[x29] ++ add sp,sp,#16*4+16 ++ ret ++.size sha256_block_neon,.-sha256_block_neon ++#ifndef __KERNEL__ ++.comm OPENSSL_armcap_P,4,4 ++#endif +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/defconfig b/defconfig +--- a/defconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/defconfig 2018-05-10 15:33:01.717312107 +0800 +@@ -0,0 +1,216 @@ ++CONFIG_CROSS_COMPILE="$CROSS_COMPILE" ++CONFIG_SYSVIPC=y ++# CONFIG_FHANDLE is not set ++CONFIG_USELIB=y ++CONFIG_NO_HZ=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_LOG_BUF_SHIFT=16 ++CONFIG_LOG_CPU_MAX_BUF_SHIFT=13 ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="${BR_BINARIES_DIR}/rootfs.cpio" ++CONFIG_SYSCTL_SYSCALL=y ++# CONFIG_ELF_CORE is not set ++# CONFIG_BASE_FULL is not set ++# CONFIG_EPOLL is not set ++# CONFIG_SIGNALFD is not set ++# CONFIG_TIMERFD is not set ++# CONFIG_EVENTFD is not set ++# CONFIG_SHMEM is not set ++# CONFIG_AIO is not set ++CONFIG_EMBEDDED=y ++# CONFIG_SLUB_DEBUG is not set ++# CONFIG_COMPAT_BRK is not set ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_ARCH_XGS_IPROC=y ++CONFIG_PCI=y ++CONFIG_NR_CPUS=4 ++CONFIG_PREEMPT=y ++CONFIG_HZ_100=y ++# CONFIG_COMPACTION is not set ++CONFIG_CMA=y ++CONFIG_CMA_DEBUG=y ++CONFIG_CMDLINE="console=ttyS0,115200n8 maxcpus=2 mem=496M" ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_DIAG is not set ++CONFIG_IPV6_TUNNEL=y ++CONFIG_NETFILTER=y ++CONFIG_BRIDGE_NETFILTER=y ++CONFIG_NETFILTER_NETLINK_QUEUE=y ++CONFIG_NETFILTER_NETLINK_LOG=y ++CONFIG_NF_CONNTRACK=y ++# CONFIG_NF_CT_PROTO_DCCP is not set ++# CONFIG_NF_CT_PROTO_SCTP is not set ++# CONFIG_NF_CT_PROTO_UDPLITE is not set ++CONFIG_NF_CONNTRACK_FTP=y ++CONFIG_NF_CONNTRACK_TFTP=y ++CONFIG_NETFILTER_XT_MARK=y ++CONFIG_NETFILTER_XT_TARGET_CT=y ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=y ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y ++CONFIG_NETFILTER_XT_MATCH_HELPER=y ++CONFIG_NETFILTER_XT_MATCH_STATE=y ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=y ++CONFIG_NF_CONNTRACK_IPV4=y ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_AH=y ++CONFIG_IP_NF_MATCH_ECN=y ++CONFIG_IP_NF_MATCH_TTL=y ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=y ++CONFIG_IP_NF_MANGLE=y ++CONFIG_IP_NF_TARGET_ECN=y ++CONFIG_IP_NF_TARGET_TTL=y ++CONFIG_IP_NF_RAW=y ++CONFIG_IP_NF_ARPTABLES=y ++CONFIG_IP_NF_ARPFILTER=y ++CONFIG_IP_NF_ARP_MANGLE=y ++CONFIG_NF_CONNTRACK_IPV6=y ++CONFIG_IP6_NF_IPTABLES=y ++CONFIG_IP6_NF_MATCH_RPFILTER=y ++CONFIG_IP6_NF_MATCH_RT=y ++CONFIG_IP6_NF_FILTER=y ++CONFIG_IP6_NF_TARGET_REJECT=y ++CONFIG_IP6_NF_MANGLE=y ++CONFIG_IP6_NF_RAW=y ++CONFIG_BRIDGE=y ++CONFIG_VLAN_8021Q=y ++CONFIG_VLAN_8021Q_GVRP=y ++# CONFIG_WIRELESS is not set ++CONFIG_UEVENT_HELPER_PATH="/sbin/mdev" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=32 ++CONFIG_MTD=y ++CONFIG_MTD_TESTS=m ++CONFIG_MTD_CMDLINE_PARTS=y ++CONFIG_MTD_BLOCK=y ++CONFIG_MTD_CFI=y ++CONFIG_MTD_JEDECPROBE=y ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_CFI_AMDSTD=y ++CONFIG_MTD_CFI_STAA=y ++CONFIG_MTD_M25P80=y ++CONFIG_MTD_NAND=y ++CONFIG_MTD_NAND_BRCMNAND=y ++CONFIG_MTD_SPI_NOR=y ++CONFIG_MTD_UBI=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_EEPROM_AT24=y ++CONFIG_SCSI=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_CHR_DEV_ST=y ++CONFIG_CHR_DEV_SG=y ++CONFIG_SCSI_CONSTANTS=y ++CONFIG_SCSI_LOGGING=y ++CONFIG_NETDEVICES=y ++CONFIG_BONDING=y ++CONFIG_TIGON3=y ++# CONFIG_BGMAC_PLATFORM is not set ++CONFIG_APM=y ++CONFIG_MDIO_XGS_IPROC=y ++CONFIG_BROADCOM_PHY=y ++CONFIG_XGS_IPROC_SERDES=y ++# CONFIG_WLAN is not set ++# CONFIG_INPUT is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_VT is not set ++# CONFIG_LEGACY_PTYS is not set ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=2 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=2 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_8250_DETECT_IRQ=y ++CONFIG_SERIAL_8250_RSA=y ++CONFIG_SERIAL_8250_DW=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_XGS_IPROC_RNG=y ++CONFIG_I2C=y ++# CONFIG_I2C_COMPAT is not set ++CONFIG_I2C_CHARDEV=y ++# CONFIG_I2C_HELPER_AUTO is not set ++CONFIG_SPI=y ++CONFIG_SPI_PL022=y ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_WATCHDOG=y ++CONFIG_ARM_SP805_WATCHDOG=y ++# CONFIG_VGA_ARB is not set ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_DYNAMIC_MINORS=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PLATFORM=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_XGS_IPROC_DRD=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_BDC_UDC=y ++CONFIG_USB_BDC_XGS_IPROC=y ++CONFIG_USB_G_SERIAL=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_DMADEVICES=y ++CONFIG_DMADEVICES_DEBUG=y ++CONFIG_DMADEVICES_VDEBUG=y ++CONFIG_PL330_DMA=y ++# CONFIG_COMMON_CLK_XGENE is not set ++CONFIG_ACPI=y ++CONFIG_EXT2_FS=y ++CONFIG_EXT3_FS=y ++# CONFIG_DNOTIFY is not set ++CONFIG_AUTOFS4_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_NTFS_FS=y ++# CONFIG_PROC_PAGE_MONITOR is not set ++CONFIG_JFFS2_FS=y ++CONFIG_UBIFS_FS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFSD=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_DEBUG_INFO=y ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++CONFIG_DEBUG_FS=y ++CONFIG_MAGIC_SYSRQ=y ++# CONFIG_SCHED_DEBUG is not set ++CONFIG_RCU_CPU_STALL_TIMEOUT=60 ++# CONFIG_FTRACE is not set ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_ANSI_CPRNG=m ++# CONFIG_CRYPTO_HW is not set ++CONFIG_ARM64_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM64_CE=y ++CONFIG_CRYPTO_SHA2_ARM64_CE=y ++CONFIG_CRYPTO_GHASH_ARM64_CE=y ++CONFIG_CRYPTO_AES_ARM64_CE_CCM=y ++CONFIG_CRYPTO_AES_ARM64_CE_BLK=y ++CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig +--- a/drivers/char/hw_random/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/char/hw_random/Kconfig 2018-05-10 11:31:29.825399854 +0800 +@@ -112,6 +112,18 @@ config HW_RANDOM_IPROC_RNG200 + + If unsure, say Y. + ++config HW_RANDOM_XGS_IPROC_RNG ++ tristate "Broadcom iProc RNG support" ++ depends on (ARCH_XGS_IPROC && HW_RANDOM) ++ ---help--- ++ This driver provides kernel-side support for the RNG ++ hardware found on the Broadcom iProc SoCs. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called iproc-rng ++ ++ If unsure, say Y. ++ + config HW_RANDOM_GEODE + tristate "AMD Geode HW Random Number Generator support" + depends on X86_32 && PCI +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile +--- a/drivers/char/hw_random/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/char/hw_random/Makefile 2018-05-10 11:31:29.825399854 +0800 +@@ -30,6 +30,7 @@ obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng + obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o + obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o + obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o ++obj-$(CONFIG_HW_RANDOM_XGS_IPROC_RNG) += xgs-iproc-rng100.o iproc-rng200.o + obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o + obj-$(CONFIG_HW_RANDOM_ST) += st-rng.o + obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/char/hw_random/xgs-iproc-rng100.c b/drivers/char/hw_random/xgs-iproc-rng100.c +--- a/drivers/char/hw_random/xgs-iproc-rng100.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/char/hw_random/xgs-iproc-rng100.c 2018-05-10 11:31:29.829399858 +0800 +@@ -0,0 +1,211 @@ ++/* ++ * Copyright (C) 2017 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Registers for RNG */ ++#define RNG_CTRL_OFFSET 0x00000000 ++#define RNG_CTRL_RESERVED_MASK 0xF00000CC ++#define RNG_CTRL_COMBLK2_OSC_DIS_SHIFT 22 ++#define RNG_CTRL_COMBLK2_OSC_DIS_MASK 0x0FC00000 ++#define RNG_CTRL_COMBLK1_OSC_DIS_SHIFT 16 ++#define RNG_CTRL_COMBLK1_OSC_DIS_MASK 0x003F0000 ++#define RNG_CTRL_JCLK_BYP_DIV_CNT_SHIFT 8 ++#define RNG_CTRL_JCLK_BYP_DIV_CNT_MASK 0x0000FF00 ++#define RNG_CTRL_JCLK_BYP_SRC_SHIFT 5 ++#define RNG_CTRL_JCLK_BYP_SRC_MASK 0x00000020 ++#define RNG_CTRL_JCLK_BYP_SEL_SHIFT 4 ++#define RNG_CTRL_JCLK_BYP_SEL_MASK 0x00000010 ++#define RNG_CTRL_RBG2X_SHIFT 1 ++#define RNG_CTRL_RBG2X_MASK 0x00000002 ++#define RNG_CTRL_RBGEN_SHIFT 0 ++#define RNG_CTRL_RBGEN_MASK 0x00000001 ++ ++#define RNG_STATUS_OFFSET 0x00000004 ++#define RNG_STATUS_RESERVED_MASK 0x00F00000 ++#define RNG_STATUS_RND_VAL_SHIFT 24 ++#define RNG_STATUS_RND_VAL_MASK 0xFF000000 ++#define RNG_STATUS_WARM_CNT_SHIFT 0 ++#define RNG_STATUS_WARM_CNT_MASK 0x000FFFFF ++ ++#define RNG_DATA_OFFSET 0x00000008 ++#define RNG_DATA_RESERVED_MASK 0x00000000 ++#define RNG_DATA_RNG_NUM_SHIFT 0 ++#define RNG_DATA_RNG_NUM_MASK 0xFFFFFFFF ++ ++#define RNG_FF_THRES_OFFSET 0x0000000C ++#define RNG_FF_THRES_RESERVED_MASK 0xFFFFFFE0 ++#define RNG_FF_THRES_RNG_FF_THRESH_SHIFT 0 ++#define RNG_FF_THRES_RNG_FF_THRESH_MASK 0x0000001F ++ ++#define RNG_INT_MASK_OFFSET 0x00000010 ++#define RNG_INT_MASK_RESERVED_MASK 0xFFFFFFFE ++#define RNG_INT_MASK_OFF_SHIFT 0 ++#define RNG_INT_MASK_OFF_MASK 0x00000001 ++ ++static int rng100_read(struct hwrng *rng, void *buf, size_t max, bool wait) ++{ ++ u32 num_words = 0; ++ u32 num_remaining = max; ++ ++ #define MAX_IDLE_TIME (1 * HZ) ++ unsigned long idle_endtime = jiffies + MAX_IDLE_TIME; ++ ++ /* Retrieve HW RNG registers base address. */ ++ void __iomem *base_addr = (void __iomem *)rng->priv; ++ ++ while ((num_remaining > 0) && time_before(jiffies, idle_endtime)) { ++ /* Are there any random numbers available? */ ++ num_words = (ioread32(base_addr + RNG_STATUS_OFFSET) & ++ RNG_STATUS_RND_VAL_MASK) >> RNG_STATUS_RND_VAL_SHIFT; ++ if (num_words > 0) { ++ if (num_remaining >= sizeof(u32)) { ++ /* Buffer has room to store entire word */ ++ *(u32 *)buf = ioread32(base_addr + ++ RNG_DATA_OFFSET); ++ buf += sizeof(u32); ++ num_remaining -= sizeof(u32); ++ } else { ++ /* Buffer can only store partial word */ ++ u32 rnd_number = ioread32(base_addr + ++ RNG_DATA_OFFSET); ++ memcpy(buf, &rnd_number, num_remaining); ++ buf += num_remaining; ++ num_remaining = 0; ++ } ++ ++ /* Reset the IDLE timeout */ ++ idle_endtime = jiffies + MAX_IDLE_TIME; ++ } else if (!wait) { ++ /* Cannot wait, return immediately */ ++ break; ++ } else { ++ /* Can wait, give others chance to run */ ++ cpu_relax(); ++ } ++ } ++ ++ return max - num_remaining; ++} ++ ++static struct hwrng rng100_ops = { ++ .name = "iproc-rng100", ++ .read = rng100_read, ++}; ++ ++static int iproc_rng100_probe(struct platform_device *pdev) ++{ ++ int error; ++ u32 val; ++ struct device *dev = &pdev->dev; ++ void __iomem *base_addr; ++ struct device_node *node = pdev->dev.of_node; ++ ++ pr_info("Broadcom IPROC RNG100 Driver\n"); ++ /* We only accept one device, and it must have an id of -1 */ ++ if (pdev->id != -1) ++ return -ENODEV; ++ ++ base_addr = of_iomap(node, 0); ++ if (!base_addr) { ++ dev_err(&pdev->dev, "can't iomap base_addr for rng100\n"); ++ return -EIO; ++ } ++ rng100_ops.priv = (unsigned long)base_addr; ++ ++ /* Start RNG block */ ++ val = ioread32(base_addr + RNG_CTRL_OFFSET); ++ val |= RNG_CTRL_RBGEN_MASK; ++ iowrite32(val, base_addr + RNG_CTRL_OFFSET); ++ ++ /* Enable RNG RBG2X */ ++ val = ioread32(base_addr + RNG_CTRL_OFFSET); ++ val |= RNG_CTRL_RBG2X_MASK; ++ iowrite32(val, base_addr + RNG_CTRL_OFFSET); ++ ++ /* Disable RNG INTERRUPT */ ++ val = ioread32(base_addr + RNG_INT_MASK_OFFSET); ++ val |= RNG_INT_MASK_OFF_MASK; ++ iowrite32(val, base_addr + RNG_INT_MASK_OFFSET); ++ ++ /* set warmup cycle 0xfff */ ++ iowrite32(RNG_STATUS_WARM_CNT_MASK - ++ (0xfff & RNG_STATUS_WARM_CNT_MASK), ++ base_addr + RNG_STATUS_OFFSET); ++ while ((ioread32(base_addr + RNG_STATUS_OFFSET) & ++ RNG_STATUS_WARM_CNT_MASK) != RNG_STATUS_WARM_CNT_MASK) ++ cpu_relax(); ++ ++ /* register to the Linux RNG framework */ ++ error = hwrng_register(&rng100_ops); ++ if (error) { ++ dev_err(dev, "hwrng registration failed\n"); ++ iounmap(base_addr); ++ return error; ++ } ++ dev_dbg(dev, "hwrng registered\n"); ++ ++ return 0; ++} ++ ++static int iproc_rng100_remove(struct platform_device *pdev) ++{ ++ u32 val; ++ void __iomem *base_addr = (void __iomem *)rng100_ops.priv; ++ ++ hwrng_unregister(&rng100_ops); ++ ++ if (base_addr) { ++ /* Disable RNG hardware */ ++ val = ioread32(base_addr + RNG_CTRL_OFFSET); ++ val &= ~RNG_CTRL_RBGEN_MASK; ++ iowrite32(val, base_addr + RNG_CTRL_OFFSET); ++ ++ val = ioread32(base_addr + RNG_CTRL_OFFSET); ++ val &= ~RNG_CTRL_RBG2X_MASK; ++ iowrite32(val, base_addr + RNG_CTRL_OFFSET); ++ ++ iounmap(base_addr); ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm_iproc_dt_ids[] = { ++ { .compatible = "brcm,iproc-rng100"}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, bcm_iproc_dt_ids); ++ ++static struct platform_driver iproc_rng100_driver = { ++ .driver = { ++ .name = "iproc-rng100", ++ .owner = THIS_MODULE, ++ .of_match_table = bcm_iproc_dt_ids, ++ }, ++ .probe = iproc_rng100_probe, ++ .remove = iproc_rng100_remove, ++}; ++module_platform_driver(iproc_rng100_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("iProc RNG100 Random Number Generator driver"); ++MODULE_LICENSE("GPL v2"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig +--- a/drivers/clk/bcm/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/clk/bcm/Kconfig 2018-05-10 11:31:29.849399879 +0800 +@@ -54,3 +54,11 @@ config CLK_BCM_SR + default ARCH_BCM_IPROC + help + Enable common clock framework support for the Broadcom Stingray SoC ++ ++config CLK_XGS_IPROC ++ bool "BRCM XGS iProc clock support" ++ depends on ARCH_XGS_IPROC || COMPILE_TEST ++ select COMMON_CLK_IPROC ++ default ARCH_XGS_IPROC ++ help ++ Enable clock support for Broadcom XGS iProc SoC +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile +--- a/drivers/clk/bcm/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/clk/bcm/Makefile 2018-05-10 11:31:29.849399879 +0800 +@@ -12,3 +12,4 @@ obj-$(CONFIG_CLK_BCM_CYGNUS) += clk-cygn + obj-$(CONFIG_CLK_BCM_NSP) += clk-nsp.o + obj-$(CONFIG_CLK_BCM_NS2) += clk-ns2.o + obj-$(CONFIG_CLK_BCM_SR) += clk-sr.o ++obj-$(CONFIG_CLK_XGS_IPROC) += clk-xgs-iproc.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/clk/bcm/clk-iproc-armpll.c b/drivers/clk/bcm/clk-iproc-armpll.c +--- a/drivers/clk/bcm/clk-iproc-armpll.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/clk/bcm/clk-iproc-armpll.c 2018-05-10 11:31:29.853399884 +0800 +@@ -197,9 +197,9 @@ static unsigned long iproc_arm_pll_recal + { + struct iproc_arm_pll *pll = to_iproc_arm_pll(hw); + u32 val; +- int mdiv; ++ u32 mdiv; + u64 ndiv; +- unsigned int pdiv; ++ u32 pdiv; + + /* in bypass mode, use parent rate */ + val = readl(pll->base + IPROC_CLK_PLLARMC_OFFSET); +@@ -226,8 +226,10 @@ static unsigned long iproc_arm_pll_recal + pll->rate = 0; + return 0; + } ++ ++ /* To avoid pll->rate overflow, do divide before multiply */ ++ parent_rate = (parent_rate / pdiv) / mdiv; + pll->rate = (ndiv * parent_rate) >> 20; +- pll->rate = (pll->rate / pdiv) / mdiv; + + pr_debug("%s: ARM PLL rate: %lu. parent rate: %lu\n", __func__, + pll->rate, parent_rate); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/clk/bcm/clk-xgs-iproc.c b/drivers/clk/bcm/clk-xgs-iproc.c +--- a/drivers/clk/bcm/clk-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/clk/bcm/clk-xgs-iproc.c 2018-05-10 11:31:29.853399884 +0800 +@@ -0,0 +1,168 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "clk-iproc.h" ++ ++#define SB2_GEN_PLL_CTRL_1_OFFSET 0x04 ++#define SB2_GEN_PLL_CTRL_3_OFFSET 0x0C ++#define SB2_GEN_PLL_CTRL_5_OFFSET 0x14 ++#define SB2_GEN_PLL_CTRL_1_PDIV_R 27 ++#define SB2_GEN_PLL_CTRL_3_NDIV_INT_R 20 ++#define SB2_GEN_PLL_CTRL_5_CH1_MDIV_R 8 ++#define SB2_GEN_PLL_CTRL_1_PDIV_WIDTH 4 ++#define SB2_GEN_PLL_CTRL_3_NDIV_INT_WIDTH 10 ++#define SB2_GEN_PLL_CTRL_5_CH1_MDIV_WIDTH 8 ++ ++#define GEN_PLL_CTRL1_OFFSET 0x4 ++#define GEN_PLL_CTRL2_OFFSET 0x8 ++#define GEN_PLL_CTRL1_NDIV_INT_R 0 ++#define GEN_PLL_CTRL1_NDIV_INT_WIDTH 10 ++#define GEN_PLL_CTRL1_PDIV_R 10 ++#define GEN_PLL_CTRL2_CH3_MDIV_R 8 ++#define GEN_PLL_CTRL2_CH3_MDIV_WIDTH 8 ++#define GEN_PLL_CTRL1_PDIV_WIDTH_3 3 ++#define GEN_PLL_CTRL1_PDIV_WIDTH_4 4 ++ ++ ++struct iproc_gen_pll { ++ struct clk_hw hw; ++ void __iomem *base; ++ unsigned long rate; ++}; ++ ++#define to_iproc_gen_pll(phw) container_of(phw, struct iproc_gen_pll, hw) ++ ++static u32 genpll_pdiv_width; ++ ++static unsigned long iproc_axi_clk_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ uint32_t ndiv, mdiv, pdiv; ++ struct iproc_gen_pll *pll = to_iproc_gen_pll(hw); ++ ++ ndiv = readl(pll->base + GEN_PLL_CTRL1_OFFSET) >> ++ GEN_PLL_CTRL1_NDIV_INT_R; ++ ndiv &= (1 << GEN_PLL_CTRL1_NDIV_INT_WIDTH) - 1; ++ if (ndiv == 0) ++ ndiv = 1 << GEN_PLL_CTRL1_NDIV_INT_WIDTH; ++ ++ pdiv = readl(pll->base + GEN_PLL_CTRL1_OFFSET) >> GEN_PLL_CTRL1_PDIV_R; ++ pdiv &= (1 << genpll_pdiv_width) -1; ++ if (pdiv == 0) ++ pdiv = 1 << genpll_pdiv_width; ++ ++ mdiv = readl(pll->base + GEN_PLL_CTRL2_OFFSET) >> ++ GEN_PLL_CTRL2_CH3_MDIV_R; ++ mdiv &= (1 << GEN_PLL_CTRL2_CH3_MDIV_WIDTH) - 1; ++ if (mdiv == 0) ++ mdiv = 1 << GEN_PLL_CTRL2_CH3_MDIV_WIDTH; ++ ++ pll->rate = parent_rate * ndiv / pdiv / mdiv; ++ return pll->rate; ++} ++ ++static unsigned long iproc_sb2_axi_clk_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ uint32_t ndiv, mdiv, pdiv; ++ struct iproc_gen_pll *pll = to_iproc_gen_pll(hw); ++ ++ ndiv = readl(pll->base + SB2_GEN_PLL_CTRL_3_OFFSET) >> ++ SB2_GEN_PLL_CTRL_3_NDIV_INT_R; ++ ndiv &= (1 << SB2_GEN_PLL_CTRL_3_NDIV_INT_WIDTH) - 1; ++ ++ mdiv = readl(pll->base + SB2_GEN_PLL_CTRL_5_OFFSET) >> ++ SB2_GEN_PLL_CTRL_5_CH1_MDIV_R; ++ mdiv &= (1 << SB2_GEN_PLL_CTRL_5_CH1_MDIV_WIDTH) - 1; ++ ++ pdiv = readl(pll->base + SB2_GEN_PLL_CTRL_1_OFFSET) >> ++ SB2_GEN_PLL_CTRL_1_PDIV_R; ++ pdiv &= (1 << SB2_GEN_PLL_CTRL_1_PDIV_WIDTH) - 1; ++ ++ pll->rate = parent_rate * ndiv / pdiv / mdiv; ++ return pll->rate; ++} ++ ++ ++static struct clk_ops iproc_axi_clk_ops = { ++ .recalc_rate = iproc_axi_clk_recalc_rate, ++}; ++ ++void __init xgs_iproc_axi_clk_setup(struct device_node *node) ++{ ++ int ret; ++ struct clk *clk; ++ struct iproc_gen_pll *pll; ++ struct clk_init_data init; ++ const char *parent_name; ++ ++ pll = kzalloc(sizeof(*pll), GFP_KERNEL); ++ if (WARN_ON(!pll)) ++ return; ++ ++ pll->base = of_iomap(node, 0); ++ if (WARN_ON(!pll->base)) ++ goto err_free_pll; ++ ++ init.name = node->name; ++ if (of_device_is_compatible(node, "axi-clk-sb2")) ++ iproc_axi_clk_ops.recalc_rate = iproc_sb2_axi_clk_recalc_rate; ++ if (of_device_is_compatible(node, "axi-clk-hx4") || ++ of_device_is_compatible(node, "axi-clk-hr2")) ++ genpll_pdiv_width = GEN_PLL_CTRL1_PDIV_WIDTH_3; ++ else ++ genpll_pdiv_width = GEN_PLL_CTRL1_PDIV_WIDTH_4; ++ ++ init.ops = &iproc_axi_clk_ops; ++ init.flags = 0; ++ parent_name = of_clk_get_parent_name(node, 0); ++ init.parent_names = (parent_name ? &parent_name : NULL); ++ init.num_parents = (parent_name ? 1 : 0); ++ pll->hw.init = &init; ++ ++ clk = clk_register(NULL, &pll->hw); ++ if (WARN_ON(IS_ERR(clk))) ++ goto err_iounmap; ++ ++ ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); ++ if (WARN_ON(ret)) ++ goto err_clk_unregister; ++ ++ return; ++ ++err_clk_unregister: ++ clk_unregister(clk); ++err_iounmap: ++ iounmap(pll->base); ++err_free_pll: ++ kfree(pll); ++} ++CLK_OF_DECLARE(xgs_iproc_axi_clk, "brcm,xgs-iproc-axi-clk", ++ xgs_iproc_axi_clk_setup); ++ ++ ++static void __init xgs_iproc_armpll_init(struct device_node *node) ++{ ++ iproc_armpll_setup(node); ++} ++CLK_OF_DECLARE(xgs_iproc_armpll, "brcm,xgs-iproc-armpll", ++ xgs_iproc_armpll_init); +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig +--- a/drivers/gpio/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/gpio/Kconfig 2018-05-10 11:31:30.057400102 +0800 +@@ -143,6 +143,15 @@ config GPIO_BRCMSTB + help + Say yes here to enable GPIO support for Broadcom STB (BCM7XXX) SoCs. + ++config GPIO_XGS_IPROC ++ tristate "BRCM XGS iProc GPIO support" ++ default y if ARCH_XGS_IPROC ++ depends on OF_GPIO && (ARCH_XGS_IPROC || COMPILE_TEST) ++ select GPIO_GENERIC ++ select GPIOLIB_IRQCHIP ++ help ++ Say yes here to enable GPIO support for Broadcom XGS iProc SoCs. ++ + config GPIO_CLPS711X + tristate "CLPS711X GPIO support" + depends on ARCH_CLPS711X || COMPILE_TEST +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/gpio/Makefile b/drivers/gpio/Makefile +--- a/drivers/gpio/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/gpio/Makefile 2018-05-10 11:31:30.057400102 +0800 +@@ -36,6 +36,7 @@ obj-$(CONFIG_GPIO_AXP209) += gpio-axp209 + obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o + obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o + obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o ++obj-$(CONFIG_GPIO_XGS_IPROC) += gpio-xgs-iproc.o + obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o + obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o + obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/gpio/gpio-xgs-iproc.c b/drivers/gpio/gpio-xgs-iproc.c +--- a/drivers/gpio/gpio-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/gpio/gpio-xgs-iproc.c 2018-05-10 11:31:30.069400115 +0800 +@@ -0,0 +1,739 @@ ++/* ++ * Copyright (C) 2017 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define IPROC_GPIO_CCA_ID 0 ++#define IPROC_GPIO_CCB_ID 1 ++#define IPROC_GPIO_CCG_ID 2 ++ ++#define REGOFFSET_GPIO_DIN 0x0 ++#define REGOFFSET_GPIO_DOUT 0x4 ++#define REGOFFSET_GPIO_OUT_EN 0x8 ++ ++#define CCA_INT_F_GPIOINT 1 ++#define CCA_INT_STS 0x20 ++#define CCA_INT_MASK 0x24 ++#define GPIO_CCA_DIN 0x0 ++#define GPIO_CCA_INT_LEVEL 0x10 ++#define GPIO_CCA_INT_LEVEL_MASK 0x14 ++#define GPIO_CCA_INT_EVENT 0x18 ++#define GPIO_CCA_INT_EVENT_MASK 0x1C ++#define GPIO_CCA_INT_EDGE 0x24 ++ ++#define GPIO_CCB_INT_TYPE 0xC ++#define GPIO_CCB_INT_DE 0x10 ++#define GPIO_CCB_INT_EDGE 0x14 ++#define GPIO_CCB_INT_MSTAT 0x20 ++#define GPIO_CCB_INT_CLR 0x24 ++#define GPIO_CCB_INT_MASK 0x18 ++ ++/* locking wrappers to deal with multiple access to the same gpio bank */ ++#define iproc_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl) ++#define iproc_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl) ++ ++struct iproc_gpio_irqcfg { ++ unsigned long flags; ++ irqreturn_t (*handler)(int irq, void *dev); ++ void (*ack)(unsigned int irq); ++ void (*unmask)(unsigned int irq); ++ void (*mask)(unsigned int irq); ++ int (*set_type)(unsigned int irq, unsigned int type); ++}; ++ ++struct iproc_gpio_chip { ++ int id; ++ struct gpio_chip chip; ++ struct iproc_gpio_cfg *config; ++ void __iomem *ioaddr; ++ void __iomem *intr_ioaddr; ++ spinlock_t lock; ++ struct irq_domain *irq_domain; ++ struct resource *resource; ++ int irq; ++ struct iproc_gpio_irqcfg *irqcfg; ++ /* GPIO register bit shift */ ++ int pin_reg_bit_shift; ++}; ++ ++static inline struct iproc_gpio_chip *to_iproc_gpio(struct gpio_chip *gpc) ++{ ++ return container_of(gpc, struct iproc_gpio_chip, chip); ++} ++ ++static u32 _iproc_gpio_readl(struct iproc_gpio_chip *chip, int reg) ++{ ++ return readl(chip->ioaddr + reg); ++} ++ ++static void _iproc_gpio_writel(struct iproc_gpio_chip *chip, u32 val, int reg) ++{ ++ writel(val, chip->ioaddr + reg); ++} ++ ++/* ++@ pin : GPIO register bit ++*/ ++static int iproc_gpio_to_irq(struct iproc_gpio_chip *chip, u32 pin) ++{ ++ return irq_linear_revmap(chip->irq_domain, pin - chip->pin_reg_bit_shift); ++} ++ ++/* returns the corresponding gpio register bit */ ++static int iproc_irq_to_gpio(struct iproc_gpio_chip *chip, u32 irq) ++{ ++ struct irq_data *data = irq_domain_get_irq_data(chip->irq_domain, irq); ++ ++ return data->hwirq + chip->pin_reg_bit_shift; ++} ++ ++static void iproc_gpio_irq_ack(struct irq_data *d) ++{ ++ u32 irq = d->irq; ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ ++ if (ourchip) { ++ struct iproc_gpio_irqcfg *irqcfg = ourchip->irqcfg; ++ if (irqcfg && irqcfg->ack) ++ irqcfg->ack(irq); ++ } ++} ++ ++static void iproc_gpio_irq_unmask(struct irq_data *d) ++{ ++ u32 irq = d->irq; ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ ++ if (ourchip) { ++ struct iproc_gpio_irqcfg *irqcfg = ourchip->irqcfg; ++ if (irqcfg && irqcfg->unmask) ++ irqcfg->unmask(irq); ++ } ++} ++ ++static void iproc_gpio_irq_mask(struct irq_data *d) ++{ ++ u32 irq = d->irq; ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ ++ if (ourchip) { ++ struct iproc_gpio_irqcfg *irqcfg = ourchip->irqcfg; ++ if (irqcfg && irqcfg->mask) ++ irqcfg->mask(irq); ++ } ++} ++ ++ ++static int iproc_gpio_irq_set_type(struct irq_data *d, u32 type) ++{ ++ u32 irq = d->irq; ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ ++ if (ourchip) { ++ struct iproc_gpio_irqcfg *irqcfg = ourchip->irqcfg; ++ if (irqcfg && irqcfg->set_type) ++ return irqcfg->set_type(irq, type); ++ } ++ ++ return -EINVAL; ++} ++ ++static irqreturn_t iproc_gpio_irq_handler_cca(int irq, void *data) ++{ ++ struct iproc_gpio_chip *iproc_gpio = (struct iproc_gpio_chip *)data; ++ struct gpio_chip gc = iproc_gpio->chip; ++ int bit; ++ unsigned long int_bits = 0; ++ u32 int_status; ++ ++ /* go through the entire GPIOs and handle all interrupts */ ++ int_status = readl(iproc_gpio->intr_ioaddr + CCA_INT_STS); ++ if (int_status & CCA_INT_F_GPIOINT) { ++ u32 event, level; ++ ++ /* Get level and edge interrupts */ ++ event = readl(iproc_gpio->ioaddr + GPIO_CCA_INT_EVENT_MASK); ++ event &= readl(iproc_gpio->ioaddr + GPIO_CCA_INT_EVENT); ++ level = readl(iproc_gpio->ioaddr + GPIO_CCA_DIN); ++ level ^= readl(iproc_gpio->ioaddr + GPIO_CCA_INT_LEVEL); ++ level &= readl(iproc_gpio->ioaddr + GPIO_CCA_INT_LEVEL_MASK); ++ int_bits = level | event; ++ ++ for_each_set_bit(bit, &int_bits, gc.ngpio) ++ generic_handle_irq( ++ irq_linear_revmap(iproc_gpio->irq_domain, bit)); ++ } ++ ++ return int_bits ? IRQ_HANDLED : IRQ_NONE; ++} ++ ++ ++static void iproc_gpio_irq_ack_cca(u32 irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ u32 irq_type, event_status = 0; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ irq_type = irq_get_trigger_type(irq); ++ if (irq_type & IRQ_TYPE_EDGE_BOTH) { ++ event_status |= (1 << pin); ++ _iproc_gpio_writel(ourchip, event_status, GPIO_CCA_INT_EVENT); ++ } ++} ++ ++static void iproc_gpio_irq_unmask_cca(u32 irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ u32 int_mask, irq_type, event_mask; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ irq_type = irq_get_trigger_type(irq); ++ event_mask = _iproc_gpio_readl(ourchip, GPIO_CCA_INT_EVENT_MASK); ++ int_mask = _iproc_gpio_readl(ourchip, GPIO_CCA_INT_LEVEL_MASK); ++ ++ if (irq_type & IRQ_TYPE_EDGE_BOTH) { ++ event_mask |= 1 << pin; ++ _iproc_gpio_writel(ourchip, event_mask, GPIO_CCA_INT_EVENT_MASK); ++ } else { ++ int_mask |= 1 << pin; ++ _iproc_gpio_writel(ourchip, int_mask, GPIO_CCA_INT_LEVEL_MASK); ++ } ++} ++ ++static void iproc_gpio_irq_mask_cca(u32 irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ u32 irq_type, int_mask, event_mask; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ irq_type = irq_get_trigger_type(irq); ++ event_mask = _iproc_gpio_readl(ourchip, GPIO_CCA_INT_EVENT_MASK); ++ int_mask = _iproc_gpio_readl(ourchip, GPIO_CCA_INT_LEVEL_MASK); ++ ++ if (irq_type & IRQ_TYPE_EDGE_BOTH) { ++ event_mask &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, event_mask, GPIO_CCA_INT_EVENT_MASK); ++ } else { ++ int_mask &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, int_mask, GPIO_CCA_INT_LEVEL_MASK); ++ } ++} ++ ++static int iproc_gpio_irq_set_type_cca(u32 irq, u32 type) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ u32 event_pol, int_pol; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ ++ switch (type & IRQ_TYPE_SENSE_MASK) { ++ case IRQ_TYPE_EDGE_RISING: ++ event_pol = _iproc_gpio_readl(ourchip, GPIO_CCA_INT_EDGE); ++ event_pol &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, event_pol, GPIO_CCA_INT_EDGE); ++ break; ++ case IRQ_TYPE_EDGE_FALLING: ++ event_pol = _iproc_gpio_readl(ourchip, GPIO_CCA_INT_EDGE); ++ event_pol |= (1 << pin); ++ _iproc_gpio_writel(ourchip, event_pol, GPIO_CCA_INT_EDGE); ++ break; ++ case IRQ_TYPE_LEVEL_HIGH: ++ int_pol = _iproc_gpio_readl(ourchip, GPIO_CCA_INT_LEVEL); ++ int_pol &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, int_pol, GPIO_CCA_INT_LEVEL); ++ break; ++ case IRQ_TYPE_LEVEL_LOW: ++ int_pol = _iproc_gpio_readl(ourchip,GPIO_CCA_INT_LEVEL); ++ int_pol |= (1 << pin); ++ _iproc_gpio_writel(ourchip, int_pol, GPIO_CCA_INT_LEVEL); ++ break; ++ default: ++ /* should not come here */ ++ return -EINVAL; ++ } ++ ++ if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) ++ irq_set_handler_locked(irq_get_irq_data(irq), handle_level_irq); ++ else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) ++ irq_set_handler_locked(irq_get_irq_data(irq), handle_edge_irq); ++ ++ return 0; ++} ++ ++struct iproc_gpio_irqcfg cca_gpio_irqcfg = { ++ /* ++ * Remove IRQF_NO_SUSPEND to be consistent with 8250_core.c setting, ++ * since CCA gpio and uart share the same IRQ. ++ */ ++ .flags = IRQF_SHARED, ++ .handler = iproc_gpio_irq_handler_cca, ++ .ack = iproc_gpio_irq_ack_cca, ++ .mask = iproc_gpio_irq_mask_cca, ++ .unmask = iproc_gpio_irq_unmask_cca, ++ .set_type = iproc_gpio_irq_set_type_cca, ++}; ++ ++static irqreturn_t iproc_gpio_irq_handler_ccb(int irq, void *dev) ++{ ++ struct iproc_gpio_chip *ourchip = dev; ++ int iter, max_pin; ++ u32 val; ++ ++ val = _iproc_gpio_readl(ourchip, GPIO_CCB_INT_MSTAT); ++ if (!val) ++ return IRQ_NONE; ++ ++ /* Max GPIO register bit */ ++ max_pin = ourchip->pin_reg_bit_shift + ourchip->chip.ngpio; ++ for (iter = ourchip->pin_reg_bit_shift; iter < max_pin; iter++) ++ if (val & (1 << iter)) ++ generic_handle_irq(iproc_gpio_to_irq(ourchip, iter)); ++ ++ return IRQ_HANDLED; ++} ++ ++static void iproc_gpio_irq_ack_ccb(u32 irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ u32 int_clear = 0; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ int_clear |= (1 << pin); ++ _iproc_gpio_writel(ourchip, int_clear, GPIO_CCB_INT_CLR); ++} ++ ++static void iproc_gpio_irq_unmask_ccb(u32 irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ u32 int_mask; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ int_mask = _iproc_gpio_readl(ourchip, GPIO_CCB_INT_MASK); ++ int_mask |= (1 << pin); ++ _iproc_gpio_writel(ourchip, int_mask, GPIO_CCB_INT_MASK); ++} ++ ++static void iproc_gpio_irq_mask_ccb(u32 irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ u32 int_mask; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ int_mask = _iproc_gpio_readl(ourchip, GPIO_CCB_INT_MASK); ++ int_mask &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, int_mask,GPIO_CCB_INT_MASK); ++} ++ ++static int iproc_gpio_irq_set_type_ccb(u32 irq, u32 type) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ u32 int_type, int_de, int_edge; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ int_type = _iproc_gpio_readl(ourchip, GPIO_CCB_INT_TYPE); ++ int_edge = _iproc_gpio_readl(ourchip, GPIO_CCB_INT_EDGE); ++ ++ switch (type) { ++ case IRQ_TYPE_EDGE_BOTH: ++ int_type &= ~(1 << pin); ++ int_de = _iproc_gpio_readl(ourchip, GPIO_CCB_INT_DE); ++ int_de |= (1 << pin); ++ _iproc_gpio_writel(ourchip, int_de, GPIO_CCB_INT_DE); ++ break; ++ case IRQ_TYPE_EDGE_RISING: ++ int_type &= ~(1 << pin); ++ int_edge |= (1 << pin); ++ int_de = _iproc_gpio_readl(ourchip, GPIO_CCB_INT_DE); ++ int_de &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, int_de, GPIO_CCB_INT_DE); ++ break; ++ case IRQ_TYPE_EDGE_FALLING: ++ int_type &= ~(1 << pin); ++ int_edge &= ~(1 << pin); ++ int_de = _iproc_gpio_readl(ourchip, GPIO_CCB_INT_DE); ++ int_de &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, int_de, GPIO_CCB_INT_DE); ++ break; ++ case IRQ_TYPE_LEVEL_HIGH: ++ int_type |= (1 << pin); ++ int_edge |= (1 << pin); ++ break; ++ case IRQ_TYPE_LEVEL_LOW: ++ int_type |= (1 << pin); ++ int_edge &= ~(1 << pin); ++ break; ++ default: ++ /* should not come here */ ++ return -EINVAL; ++ } ++ ++ _iproc_gpio_writel(ourchip, int_type, GPIO_CCB_INT_TYPE); ++ _iproc_gpio_writel(ourchip, int_edge, GPIO_CCB_INT_EDGE); ++ ++ if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) ++ irq_set_handler_locked(irq_get_irq_data(irq), handle_level_irq); ++ else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) ++ irq_set_handler_locked(irq_get_irq_data(irq), handle_edge_irq); ++ ++ return 0; ++} ++ ++struct iproc_gpio_irqcfg ccb_gpio_irqcfg = { ++ .flags = IRQF_NO_SUSPEND, ++ .handler = iproc_gpio_irq_handler_ccb, ++ .ack = iproc_gpio_irq_ack_ccb, ++ .mask = iproc_gpio_irq_mask_ccb, ++ .unmask = iproc_gpio_irq_unmask_ccb, ++ .set_type = iproc_gpio_irq_set_type_ccb, ++}; ++ ++static struct irq_chip iproc_gpio_irq_chip = { ++ .name = "IPROC-GPIO", ++ .irq_ack = (void *) iproc_gpio_irq_ack, ++ .irq_mask = (void *) iproc_gpio_irq_mask, ++ .irq_unmask = (void *) iproc_gpio_irq_unmask, ++ .irq_set_type = (void *) iproc_gpio_irq_set_type, ++}; ++ ++ ++static int iproc_gpiolib_input(struct gpio_chip *chip, u32 gpio) ++{ ++ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); ++ unsigned long flags; ++ u32 val, nBitMask; ++ int reg_offset; ++ u32 pin_offset = gpio + ourchip->pin_reg_bit_shift; ++ ++ iproc_gpio_lock(ourchip, flags); ++ ++ nBitMask = 1 << pin_offset; ++ reg_offset = REGOFFSET_GPIO_OUT_EN; ++ ++ val = _iproc_gpio_readl(ourchip, reg_offset); ++ val &= ~nBitMask; ++ _iproc_gpio_writel(ourchip, val, reg_offset); ++ ++ iproc_gpio_unlock(ourchip, flags); ++ ++ return 0; ++} ++ ++static int iproc_gpiolib_output(struct gpio_chip *chip, u32 gpio, int value) ++{ ++ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); ++ unsigned long flags, val; ++ u32 nBitMask; ++ int reg_offset; ++ /* GPIO register bit */ ++ u32 pin_offset = gpio + ourchip->pin_reg_bit_shift; ++ ++ iproc_gpio_lock(ourchip, flags); ++ ++ nBitMask = 1 << pin_offset; ++ reg_offset = REGOFFSET_GPIO_OUT_EN; ++ ++ val = _iproc_gpio_readl(ourchip, reg_offset); ++ val |= nBitMask; ++ _iproc_gpio_writel(ourchip, val, reg_offset); ++ ++ iproc_gpio_unlock(ourchip, flags); ++ ++ return 0; ++} ++ ++static void iproc_gpiolib_set(struct gpio_chip *chip, u32 gpio, int value) ++{ ++ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); ++ unsigned long flags, val; ++ u32 nBitMask; ++ /* GPIO register bit */ ++ u32 pin_offset = gpio + ourchip->pin_reg_bit_shift; ++ ++ iproc_gpio_lock(ourchip, flags); ++ ++ nBitMask = 1 << pin_offset; ++ ++ val = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_OUT_EN); ++ val &= nBitMask; ++ ++ /* this function only applies to output pin */ ++ if (!val) ++ return; ++ ++ val = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_DOUT); ++ if (value == 0) ++ /* Set the pin to zero */ ++ val &= ~nBitMask; ++ else ++ /* Set the pin to 1 */ ++ val |= nBitMask; ++ ++ _iproc_gpio_writel(ourchip, val, REGOFFSET_GPIO_DOUT); ++ ++ iproc_gpio_unlock(ourchip, flags); ++} ++ ++static int iproc_gpiolib_get(struct gpio_chip *chip, u32 gpio) ++{ ++ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); ++ unsigned long flags; ++ u32 val, offset, nBitMask; ++ /* GPIO register bit */ ++ u32 pin_offset = gpio + ourchip->pin_reg_bit_shift; ++ ++ iproc_gpio_lock(ourchip, flags); ++ ++ nBitMask = 1 << pin_offset; ++ ++ /* determine the GPIO pin direction */ ++ offset = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_OUT_EN); ++ offset &= nBitMask; ++ ++ if (offset) ++ val = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_DOUT); ++ else ++ val = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_DIN); ++ ++ val >>= pin_offset; ++ val &= 1; ++ ++ iproc_gpio_unlock(ourchip, flags); ++ ++ return val; ++} ++ ++/* ++@offset : the gpio pin index number from gpiolib view (minus gpio base only) ++*/ ++static int iproc_gpiolib_to_irq(struct gpio_chip *chip, u32 offset) ++{ ++ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); ++ ++ return irq_linear_revmap(ourchip->irq_domain, offset); ++} ++ ++static struct __initconst of_device_id bcm_iproc_gpio_of_match[] = { ++ { .compatible = "brcm,iproc-gpio-cca" }, ++ { .compatible = "brcm,iproc-gpio-ccb" }, ++ { .compatible = "brcm,iproc-gpio-ccg" }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, bcm_iproc_gpio_of_match); ++ ++static int iproc_gpio_probe(struct platform_device *pdev) ++{ ++ struct device_node *dn = pdev->dev.of_node; ++ struct iproc_gpio_chip *iproc_gpio; ++ u32 num_gpios, count; ++ int ret; ++ ++ iproc_gpio = devm_kzalloc(&pdev->dev, sizeof(*iproc_gpio), GFP_KERNEL); ++ if (!iproc_gpio) { ++ dev_err(&pdev->dev, "Error allocating memory\n"); ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(pdev, iproc_gpio); ++ ++ /* Determine type of gpio controller to allocate */ ++ if (of_device_is_compatible(dn, "brcm,iproc-gpio-cca")) { ++ iproc_gpio->chip.label = "gpio_cca"; ++ iproc_gpio->id = IPROC_GPIO_CCA_ID; ++ iproc_gpio->irqcfg = &cca_gpio_irqcfg; ++ ++ iproc_gpio->intr_ioaddr = of_iomap(dn, 1); ++ if (!iproc_gpio->intr_ioaddr) { ++ dev_err(&pdev->dev, "gpio interrupt base addr fail\n"); ++ return -ENOMEM; ++ } ++ ++ dev_info(&pdev->dev, "%s intr_ioaddr: %p\n", ++ iproc_gpio->chip.label, iproc_gpio->intr_ioaddr); ++ } else if (of_device_is_compatible(dn, "brcm,iproc-gpio-ccb")) { ++ iproc_gpio->chip.label = "gpio_ccb"; ++ iproc_gpio->id = IPROC_GPIO_CCB_ID; ++ iproc_gpio->irqcfg = &ccb_gpio_irqcfg; ++ } else if (of_device_is_compatible(dn, "brcm,iproc-gpio-ccg")) { ++ iproc_gpio->chip.label = "gpio_ccg"; ++ iproc_gpio->id = IPROC_GPIO_CCG_ID; ++ iproc_gpio->irqcfg = &ccb_gpio_irqcfg; ++ } else { ++ dev_err(&pdev->dev, "Error parsing device tree of GPIO\n"); ++ return -ENODEV; ++ } ++ ++ /* Map gpio base ioaddr address */ ++ iproc_gpio->ioaddr = of_iomap(dn, 0); ++ if (!iproc_gpio->ioaddr) { ++ dev_err(&pdev->dev, "can't iomap gpio base address\n"); ++ return -ENOMEM; ++ } ++ dev_info(&pdev->dev, "%s ioaddr: %p\n", iproc_gpio->chip.label, ++ iproc_gpio->ioaddr); ++ ++ /* pin_base: gpio pin base */ ++ if (of_property_read_u32(dn, "pin-base", &iproc_gpio->chip.base)) { ++ dev_err(&pdev->dev, "Missing pin-base property\n"); ++ return -EINVAL; ++ } ++ ++ /* pin_reg_bit_shift: GPIO register bit offset */ ++ if (of_property_read_u32(dn, "pin-reg-bit-shift", ++ &iproc_gpio->pin_reg_bit_shift)) { ++ dev_err(&pdev->dev, "Missing pin-reg-bit-shift property\n"); ++ return -EINVAL; ++ } ++ ++ /* Get number of GPIO pin */ ++ if (of_property_read_u32(dn, "ngpios", &num_gpios)) { ++ dev_err(&pdev->dev, "Missing ngpios property\n"); ++ return -EINVAL; ++ } ++ iproc_gpio->chip.ngpio = num_gpios; ++ ++ iproc_gpio->chip.parent = &pdev->dev; ++ iproc_gpio->chip.of_node = dn; ++ ++ iproc_gpio->chip.direction_input = iproc_gpiolib_input; ++ iproc_gpio->chip.direction_output = iproc_gpiolib_output; ++ iproc_gpio->chip.set = iproc_gpiolib_set; ++ iproc_gpio->chip.get = iproc_gpiolib_get; ++ iproc_gpio->chip.to_irq = iproc_gpiolib_to_irq; ++ ++ ret = gpiochip_add_data(&iproc_gpio->chip, iproc_gpio); ++ if (ret) { ++ dev_err(&pdev->dev, "Could not add gpiochip for %s\n", ++ iproc_gpio->chip.label); ++ return ret; ++ } ++ ++ iproc_gpio->irq = platform_get_irq(pdev, 0); ++ ++ if (iproc_gpio->irq < 0) { ++ dev_warn(&pdev->dev, "No IRQ specified for %s\n", ++ iproc_gpio->chip.label); ++ return 0; ++ } ++ ++ /* Create irq domain */ ++ iproc_gpio->irq_domain = irq_domain_add_linear(dn, num_gpios, ++ &irq_domain_simple_ops, iproc_gpio); ++ ++ if (!iproc_gpio->irq_domain) { ++ dev_err(&pdev->dev, "Couldn't allocate IRQ domain\n"); ++ ret = -ENODEV; ++ goto err_irq_domain; ++ } ++ ++ /* Map each gpio pin to an IRQ and set the handler */ ++ for (count = 0; count < num_gpios; count++) { ++ int irq; ++ ++ irq = irq_create_mapping(iproc_gpio->irq_domain, count); ++ irq_set_chip_and_handler(irq, &iproc_gpio_irq_chip, ++ handle_simple_irq); ++ irq_set_chip_data(irq, iproc_gpio); ++ } ++ ++ /* Enable GPIO interrupts for CCA GPIO */ ++ if (iproc_gpio->id == IPROC_GPIO_CCA_ID) { ++ u32 val; ++ val = readl(iproc_gpio->intr_ioaddr + CCA_INT_MASK); ++ val |= CCA_INT_F_GPIOINT; ++ writel(val, iproc_gpio->intr_ioaddr + CCA_INT_MASK); ++ } ++ ++ /* Install ISR for this GPIO controller */ ++ if (iproc_gpio->irqcfg) { ++ struct iproc_gpio_irqcfg *irqcfg = iproc_gpio->irqcfg; ++ if (irqcfg->handler) { ++ ret = request_irq(iproc_gpio->irq, irqcfg->handler, ++ irqcfg->flags, iproc_gpio->chip.label, ++ iproc_gpio); ++ if (ret) { ++ dev_err(&pdev->dev, "Fail to request IRQ%d\n", ++ iproc_gpio->irq); ++ goto err_irq_request; ++ } ++ } else { ++ dev_warn(&pdev->dev, "%s has no isr!\n", ++ iproc_gpio->chip.label); ++ } ++ } ++ ++ return 0; ++ ++err_irq_request: ++ irq_domain_remove(iproc_gpio->irq_domain); ++ iproc_gpio->irq_domain = NULL; ++ ++err_irq_domain: ++ gpiochip_remove(&iproc_gpio->chip); ++ ++ return ret; ++} ++ ++static int __exit iproc_gpio_remove(struct platform_device *pdev) ++{ ++ struct iproc_gpio_chip *iproc_gpio; ++ ++ iproc_gpio = platform_get_drvdata(pdev); ++ if (iproc_gpio == NULL) ++ return -ENODEV; ++ ++ if (iproc_gpio->intr_ioaddr) { ++ /* Disable GPIO interrupts for CCA GPIO */ ++ if (iproc_gpio->id == IPROC_GPIO_CCA_ID) { ++ u32 val; ++ val = readl(iproc_gpio->intr_ioaddr + CCA_INT_MASK); ++ val &= ~(CCA_INT_F_GPIOINT); ++ writel(val, iproc_gpio->intr_ioaddr + CCA_INT_MASK); ++ } ++ } ++ ++ gpiochip_remove(&iproc_gpio->chip); ++ ++ return 0; ++} ++ ++static struct platform_driver bcm_iproc_gpio_driver = { ++ .driver = { ++ .name = "iproc-gpio", ++ .owner = THIS_MODULE, ++ .of_match_table = bcm_iproc_gpio_of_match, ++ }, ++ .probe = iproc_gpio_probe, ++ .remove = iproc_gpio_remove, ++}; ++ ++module_platform_driver(bcm_iproc_gpio_driver); ++ ++MODULE_DESCRIPTION("XGS IPROC GPIO driver"); ++MODULE_LICENSE("GPL v2"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +--- a/drivers/i2c/busses/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/i2c/busses/Kconfig 2018-05-10 11:31:30.853400956 +0800 +@@ -418,6 +418,26 @@ config I2C_BCM_IPROC + + If you don't know what to do here, say N. + ++config I2C_XGS_IPROC ++ tristate "Broadcom XGS iProc I2C controller" ++ depends on ARCH_XGS_IPROC ++ default ARCH_XGS_IPROC ++ help ++ If you say yes to this option, support will be included for the ++ Broadcom XGS iProc I2C controller. ++ ++ If you don't know what to do here, say N. ++ ++config SMBUS_XGS_IPROC ++ tristate "Broadcom XGS iProc SMBUS controller" ++ depends on ARCH_XGS_IPROC && !I2C_XGS_IPROC ++ default n ++ help ++ If you say yes to this option, support will be included for the ++ Broadcom XGS iProc SMBUS controller. ++ ++ If you don't know what to do here, say N. ++ + config I2C_BCM_KONA + tristate "BCM Kona I2C adapter" + depends on ARCH_BCM_MOBILE +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile +--- a/drivers/i2c/busses/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/i2c/busses/Makefile 2018-05-10 11:31:30.853400956 +0800 +@@ -108,6 +108,8 @@ i2c-octeon-objs := i2c-octeon-core.o i2c + obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o + i2c-thunderx-objs := i2c-octeon-core.o i2c-thunderx-pcidrv.o + obj-$(CONFIG_I2C_THUNDERX) += i2c-thunderx.o ++obj-$(CONFIG_I2C_XGS_IPROC) += i2c-xgs-iproc.o ++obj-$(CONFIG_SMBUS_XGS_IPROC) += xgs_iproc_smbus.o + obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o + obj-$(CONFIG_I2C_XLR) += i2c-xlr.o + obj-$(CONFIG_I2C_XLP9XX) += i2c-xlp9xx.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/i2c-xgs-iproc.c b/drivers/i2c/busses/i2c-xgs-iproc.c +--- a/drivers/i2c/busses/i2c-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/i2c/busses/i2c-xgs-iproc.c 2018-05-10 11:31:30.877400982 +0800 +@@ -0,0 +1,584 @@ ++/* ++ * Copyright (C) 2014 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++/* ++ * This file is based on i2c-bcm-iproc.c with the following changes. ++ * 1. Enable read support with data len >= 64B ++ * 2. Different implementation of write support for data len >= 64B ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define CFG_OFFSET 0x00 ++#define CFG_RESET_SHIFT 31 ++#define CFG_EN_SHIFT 30 ++#define CFG_M_RETRY_CNT_SHIFT 16 ++#define CFG_M_RETRY_CNT_MASK 0x0f ++ ++#define TIM_CFG_OFFSET 0x04 ++#define TIM_CFG_MODE_400_SHIFT 31 ++ ++#define M_FIFO_CTRL_OFFSET 0x0c ++#define M_FIFO_RX_FLUSH_SHIFT 31 ++#define M_FIFO_TX_FLUSH_SHIFT 30 ++#define M_FIFO_RX_CNT_SHIFT 16 ++#define M_FIFO_RX_CNT_MASK 0x7f ++#define M_FIFO_RX_THLD_SHIFT 8 ++#define M_FIFO_RX_THLD_MASK 0x3f ++ ++#define M_CMD_OFFSET 0x30 ++#define M_CMD_START_BUSY_SHIFT 31 ++#define M_CMD_STATUS_SHIFT 25 ++#define M_CMD_STATUS_MASK 0x07 ++#define M_CMD_STATUS_SUCCESS 0x0 ++#define M_CMD_STATUS_LOST_ARB 0x1 ++#define M_CMD_STATUS_NACK_ADDR 0x2 ++#define M_CMD_STATUS_NACK_DATA 0x3 ++#define M_CMD_STATUS_TIMEOUT 0x4 ++#define M_CMD_PROTOCOL_SHIFT 9 ++#define M_CMD_PROTOCOL_MASK 0xf ++#define M_CMD_PROTOCOL_BLK_WR 0x7 ++#define M_CMD_PROTOCOL_BLK_RD 0x8 ++#define M_CMD_PEC_SHIFT 8 ++#define M_CMD_RD_CNT_SHIFT 0 ++#define M_CMD_RD_CNT_MASK 0xff ++ ++#define IE_OFFSET 0x38 ++#define IE_M_RX_FIFO_FULL_SHIFT 31 ++#define IE_M_RX_THLD_SHIFT 30 ++#define IE_M_START_BUSY_SHIFT 28 ++ ++#define IS_OFFSET 0x3c ++#define IS_M_RX_FIFO_FULL_SHIFT 31 ++#define IS_M_RX_THLD_SHIFT 30 ++#define IS_M_START_BUSY_SHIFT 28 ++ ++#define M_TX_OFFSET 0x40 ++#define M_TX_WR_STATUS_SHIFT 31 ++#define M_TX_DATA_SHIFT 0 ++#define M_TX_DATA_MASK 0xff ++ ++#define M_RX_OFFSET 0x44 ++#define M_RX_STATUS_SHIFT 30 ++#define M_RX_STATUS_MASK 0x03 ++#define M_RX_PEC_ERR_SHIFT 29 ++#define M_RX_DATA_SHIFT 0 ++#define M_RX_DATA_MASK 0xff ++ ++#define I2C_TIMEOUT_MSEC 100 ++ ++#define M_TX_RX_FIFO_SIZE 64 ++#define I2C_MAX_DATA_LEN (M_TX_RX_FIFO_SIZE - 1) ++ ++/* ++ * Enable support of EEPROM I2C devices with 2-byte addressing mode ++ * (total size > 256B)and page size >= 64B. ++ */ ++#define CONFIG_ENABLE_WRITE_MSG_SPLIT 1 ++ ++ ++enum bus_speed_index { ++ I2C_SPD_100K = 0, ++ I2C_SPD_400K, ++}; ++ ++struct bcm_iproc_i2c_dev { ++ struct device *device; ++ int irq; ++ ++ void __iomem *base; ++ ++ struct i2c_adapter adapter; ++ unsigned int bus_speed; ++ ++ struct completion done; ++ int xfer_is_done; ++}; ++ ++/* ++ * Can be expanded in the future if more interrupt status bits are utilized ++ */ ++#define ISR_MASK (1 << IS_M_START_BUSY_SHIFT) ++ ++static irqreturn_t bcm_iproc_i2c_isr(int irq, void *data) ++{ ++ struct bcm_iproc_i2c_dev *iproc_i2c = data; ++ u32 status = readl(iproc_i2c->base + IS_OFFSET); ++ ++ status &= ISR_MASK; ++ ++ if (!status) ++ return IRQ_NONE; ++ ++ writel(status, iproc_i2c->base + IS_OFFSET); ++ iproc_i2c->xfer_is_done = 1; ++ complete(&iproc_i2c->done); ++ ++ return IRQ_HANDLED; ++} ++ ++static int bcm_iproc_i2c_check_status(struct bcm_iproc_i2c_dev *iproc_i2c, ++ struct i2c_msg *msg) ++{ ++ u32 val; ++ ++ val = readl(iproc_i2c->base + M_CMD_OFFSET); ++ val = (val >> M_CMD_STATUS_SHIFT) & M_CMD_STATUS_MASK; ++ ++ switch (val) { ++ case M_CMD_STATUS_SUCCESS: ++ return 0; ++ ++ case M_CMD_STATUS_LOST_ARB: ++ dev_dbg(iproc_i2c->device, "lost bus arbitration\n"); ++ return -EAGAIN; ++ ++ case M_CMD_STATUS_NACK_ADDR: ++ dev_dbg(iproc_i2c->device, "NAK addr:0x%02x\n", msg->addr); ++ return -ENXIO; ++ ++ case M_CMD_STATUS_NACK_DATA: ++ dev_dbg(iproc_i2c->device, "NAK data\n"); ++ return -ENXIO; ++ ++ case M_CMD_STATUS_TIMEOUT: ++ dev_dbg(iproc_i2c->device, "bus timeout\n"); ++ return -ETIMEDOUT; ++ ++ default: ++ dev_dbg(iproc_i2c->device, "unknown error code=%d\n", val); ++ return -EIO; ++ } ++} ++ ++static int bcm_iproc_i2c_xfer_one_msg(struct bcm_iproc_i2c_dev *iproc_i2c, ++ struct i2c_msg *msg) ++{ ++ int ret, i; ++ u8 addr; ++ u32 val; ++ unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT_MSEC); ++ ++ /* check if bus is busy */ ++ if (!!(readl(iproc_i2c->base + M_CMD_OFFSET) & ++ BIT(M_CMD_START_BUSY_SHIFT))) { ++ dev_warn(iproc_i2c->device, "bus is busy\n"); ++ return -EBUSY; ++ } ++ ++ /* format and load slave address into the TX FIFO */ ++ addr = i2c_8bit_addr_from_msg(msg); ++ writel(addr, iproc_i2c->base + M_TX_OFFSET); ++ ++ /* for a write transaction, load data into the TX FIFO */ ++ if (!(msg->flags & I2C_M_RD)) { ++ for (i = 0; i < msg->len; i++) { ++ val = msg->buf[i]; ++ ++ /* mark the last byte */ ++ if (i == msg->len - 1) ++ val |= 1 << M_TX_WR_STATUS_SHIFT; ++ ++ writel(val, iproc_i2c->base + M_TX_OFFSET); ++ } ++ } ++ ++ /* mark as incomplete before starting the transaction */ ++ reinit_completion(&iproc_i2c->done); ++ iproc_i2c->xfer_is_done = 0; ++ ++ /* ++ * Enable the "start busy" interrupt, which will be triggered after the ++ * transaction is done, i.e., the internal start_busy bit, transitions ++ * from 1 to 0. ++ */ ++ writel(1 << IE_M_START_BUSY_SHIFT, iproc_i2c->base + IE_OFFSET); ++ ++ /* ++ * Now we can activate the transfer. For a read operation, specify the ++ * number of bytes to read ++ */ ++ val = 1 << M_CMD_START_BUSY_SHIFT; ++ if (msg->flags & I2C_M_RD) { ++ val |= (M_CMD_PROTOCOL_BLK_RD << M_CMD_PROTOCOL_SHIFT) | ++ (msg->len << M_CMD_RD_CNT_SHIFT); ++ } else { ++ val |= (M_CMD_PROTOCOL_BLK_WR << M_CMD_PROTOCOL_SHIFT); ++ } ++ writel(val, iproc_i2c->base + M_CMD_OFFSET); ++ ++ time_left = wait_for_completion_timeout(&iproc_i2c->done, time_left); ++ ++ /* disable all interrupts */ ++ writel(0, iproc_i2c->base + IE_OFFSET); ++ /* read it back to flush the write */ ++ readl(iproc_i2c->base + IE_OFFSET); ++ ++ /* make sure the interrupt handler isn't running */ ++ synchronize_irq(iproc_i2c->irq); ++ ++ if (!time_left && !iproc_i2c->xfer_is_done) { ++ dev_err(iproc_i2c->device, "transaction timed out\n"); ++ ++ /* flush FIFOs */ ++ val = (1 << M_FIFO_RX_FLUSH_SHIFT) | ++ (1 << M_FIFO_TX_FLUSH_SHIFT); ++ writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); ++ return -ETIMEDOUT; ++ } ++ ++ ret = bcm_iproc_i2c_check_status(iproc_i2c, msg); ++ if (ret) { ++ /* flush both TX/RX FIFOs */ ++ val = (1 << M_FIFO_RX_FLUSH_SHIFT) | ++ (1 << M_FIFO_TX_FLUSH_SHIFT); ++ writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); ++ return ret; ++ } ++ ++ /* ++ * For a read operation, we now need to load the data from FIFO ++ * into the memory buffer ++ */ ++ if (msg->flags & I2C_M_RD) { ++ for (i = 0; i < msg->len; i++) { ++ msg->buf[i] = (readl(iproc_i2c->base + M_RX_OFFSET) >> ++ M_RX_DATA_SHIFT) & M_RX_DATA_MASK; ++ } ++ } ++ ++ return 0; ++} ++ ++static int bcm_iproc_i2c_xfer(struct i2c_adapter *adapter, ++ struct i2c_msg msgs[], int num) ++{ ++ struct bcm_iproc_i2c_dev *iproc_i2c = i2c_get_adapdata(adapter); ++ int ret, i; ++ int xfer_msg_len; ++ u8 addr_h, addr_l; ++ ++ /* go through all messages */ ++ for (i = 0; i < num; i++) { ++ xfer_msg_len = msgs[i].len; ++ ++ while (xfer_msg_len) { ++ if (xfer_msg_len > I2C_MAX_DATA_LEN) ++ msgs[i].len = I2C_MAX_DATA_LEN; ++ ++ ret = bcm_iproc_i2c_xfer_one_msg(iproc_i2c, &msgs[i]); ++ if (ret) { ++ dev_dbg(iproc_i2c->device, "xfer failed\n"); ++ return ret; ++ } ++ ++ xfer_msg_len -= msgs[i].len; ++ if (xfer_msg_len == 0) ++ break; ++ ++#if defined(CONFIG_ENABLE_WRITE_MSG_SPLIT) ++ /* Keep the addr offset for later use */ ++ addr_h = msgs[i].buf[0]; ++ addr_l = msgs[i].buf[1]; ++#endif ++ ++ msgs[i].len = xfer_msg_len; ++ msgs[i].buf += I2C_MAX_DATA_LEN; ++ ++#if defined(CONFIG_ENABLE_WRITE_MSG_SPLIT) ++ if (!(msgs[i].flags & I2C_M_RD)) { ++ /* ++ * For write transfer with len >= 64B, assuming ++ * 2-byte addressing should be reasonable. ++ */ ++ xfer_msg_len += 2; ++ msgs[i].len = xfer_msg_len; ++ /* ++ * Append a new 2-byte address offset. ++ * The upper byte should be unchanged, and the ++ * lower byte is increased by actually written ++ * bytes: (I2C_MAX_DATA_LEN - 2) ++ */ ++ msgs[i].buf -= 2; ++ msgs[i].buf[0] = addr_h; ++ msgs[i].buf[1] = addr_l + I2C_MAX_DATA_LEN - 2; ++ ++ /* ++ * Wait some time so that EEPROM is ready to ++ * respond after previous partial page write. ++ */ ++ if (!(msgs[i].flags & I2C_M_RD)) ++ mdelay(10); ++ } ++#endif /* CONFIG_ENABLE_WRITE_MSG_SPLIT */ ++ } /* while */ ++ } /* for */ ++ ++ return num; ++} ++ ++ ++static uint32_t bcm_iproc_i2c_functionality(struct i2c_adapter *adap) ++{ ++ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; ++} ++ ++static const struct i2c_algorithm bcm_iproc_algo = { ++ .master_xfer = bcm_iproc_i2c_xfer, ++ .functionality = bcm_iproc_i2c_functionality, ++}; ++ ++/* ++ * Don't limit the max write length for Linux I2C core, if support of ++ * write msg split is enabled. ++ * Read msg split is supported, so max_read_len is commented out. ++ */ ++#if !defined(CONFIG_ENABLE_WRITE_MSG_SPLIT) ++static const struct i2c_adapter_quirks bcm_iproc_i2c_quirks = { ++ /* need to reserve one byte in the FIFO for the slave address */ ++ //.max_read_len = M_TX_RX_FIFO_SIZE - 1, ++ .max_write_len = M_TX_RX_FIFO_SIZE - 1, ++}; ++#endif ++ ++static int bcm_iproc_i2c_cfg_speed(struct bcm_iproc_i2c_dev *iproc_i2c) ++{ ++ unsigned int bus_speed; ++ u32 val; ++ int ret = of_property_read_u32(iproc_i2c->device->of_node, ++ "clock-frequency", &bus_speed); ++ if (ret < 0) { ++ dev_info(iproc_i2c->device, ++ "unable to interpret clock-frequency DT property\n"); ++ bus_speed = 100000; ++ } ++ ++ if (bus_speed < 100000) { ++ dev_err(iproc_i2c->device, "%d Hz bus speed not supported\n", ++ bus_speed); ++ dev_err(iproc_i2c->device, ++ "valid speeds are 100khz and 400khz\n"); ++ return -EINVAL; ++ } else if (bus_speed < 400000) { ++ bus_speed = 100000; ++ } else { ++ bus_speed = 400000; ++ } ++ ++ iproc_i2c->bus_speed = bus_speed; ++ val = readl(iproc_i2c->base + TIM_CFG_OFFSET); ++ val &= ~(1 << TIM_CFG_MODE_400_SHIFT); ++ val |= (bus_speed == 400000) << TIM_CFG_MODE_400_SHIFT; ++ writel(val, iproc_i2c->base + TIM_CFG_OFFSET); ++ ++ dev_info(iproc_i2c->device, "bus set to %u Hz\n", bus_speed); ++ ++ return 0; ++} ++ ++static int bcm_iproc_i2c_init(struct bcm_iproc_i2c_dev *iproc_i2c) ++{ ++ u32 val; ++ ++ /* put controller in reset */ ++ val = readl(iproc_i2c->base + CFG_OFFSET); ++ val |= 1 << CFG_RESET_SHIFT; ++ val &= ~(1 << CFG_EN_SHIFT); ++ writel(val, iproc_i2c->base + CFG_OFFSET); ++ ++ /* wait 100 usec per spec */ ++ udelay(100); ++ ++ /* bring controller out of reset */ ++ val &= ~(1 << CFG_RESET_SHIFT); ++ writel(val, iproc_i2c->base + CFG_OFFSET); ++ ++ /* flush TX/RX FIFOs and set RX FIFO threshold to zero */ ++ val = (1 << M_FIFO_RX_FLUSH_SHIFT) | (1 << M_FIFO_TX_FLUSH_SHIFT); ++ writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); ++ ++ /* disable all interrupts */ ++ writel(0, iproc_i2c->base + IE_OFFSET); ++ ++ /* clear all pending interrupts */ ++ writel(0xffffffff, iproc_i2c->base + IS_OFFSET); ++ ++ return 0; ++} ++ ++static void bcm_iproc_i2c_enable_disable(struct bcm_iproc_i2c_dev *iproc_i2c, ++ bool enable) ++{ ++ u32 val; ++ ++ val = readl(iproc_i2c->base + CFG_OFFSET); ++ if (enable) ++ val |= BIT(CFG_EN_SHIFT); ++ else ++ val &= ~BIT(CFG_EN_SHIFT); ++ writel(val, iproc_i2c->base + CFG_OFFSET); ++} ++ ++static int bcm_iproc_i2c_probe(struct platform_device *pdev) ++{ ++ int irq, ret = 0; ++ struct bcm_iproc_i2c_dev *iproc_i2c; ++ struct i2c_adapter *adap; ++ struct resource *res; ++ ++ iproc_i2c = devm_kzalloc(&pdev->dev, sizeof(*iproc_i2c), ++ GFP_KERNEL); ++ if (!iproc_i2c) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, iproc_i2c); ++ iproc_i2c->device = &pdev->dev; ++ init_completion(&iproc_i2c->done); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ iproc_i2c->base = devm_ioremap_resource(iproc_i2c->device, res); ++ if (IS_ERR(iproc_i2c->base)) ++ return PTR_ERR(iproc_i2c->base); ++ ++ ret = bcm_iproc_i2c_init(iproc_i2c); ++ if (ret) ++ return ret; ++ ++ ret = bcm_iproc_i2c_cfg_speed(iproc_i2c); ++ if (ret) ++ return ret; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq <= 0) { ++ dev_err(iproc_i2c->device, "no irq resource\n"); ++ return irq; ++ } ++ iproc_i2c->irq = irq; ++ ++ ret = devm_request_irq(iproc_i2c->device, irq, bcm_iproc_i2c_isr, 0, ++ pdev->name, iproc_i2c); ++ if (ret < 0) { ++ dev_err(iproc_i2c->device, "unable to request irq %i\n", irq); ++ return ret; ++ } ++ ++ bcm_iproc_i2c_enable_disable(iproc_i2c, true); ++ ++ adap = &iproc_i2c->adapter; ++ i2c_set_adapdata(adap, iproc_i2c); ++ strlcpy(adap->name, "Broadcom iProc I2C adapter", sizeof(adap->name)); ++ adap->algo = &bcm_iproc_algo; ++#if !defined(CONFIG_ENABLE_WRITE_MSG_SPLIT) ++ adap->quirks = &bcm_iproc_i2c_quirks; ++#endif ++ adap->dev.parent = &pdev->dev; ++ adap->dev.of_node = pdev->dev.of_node; ++ ++ return i2c_add_adapter(adap); ++} ++ ++static int bcm_iproc_i2c_remove(struct platform_device *pdev) ++{ ++ struct bcm_iproc_i2c_dev *iproc_i2c = platform_get_drvdata(pdev); ++ ++ /* make sure there's no pending interrupt when we remove the adapter */ ++ writel(0, iproc_i2c->base + IE_OFFSET); ++ readl(iproc_i2c->base + IE_OFFSET); ++ synchronize_irq(iproc_i2c->irq); ++ ++ i2c_del_adapter(&iproc_i2c->adapter); ++ bcm_iproc_i2c_enable_disable(iproc_i2c, false); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM_SLEEP ++ ++static int bcm_iproc_i2c_suspend(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct bcm_iproc_i2c_dev *iproc_i2c = platform_get_drvdata(pdev); ++ ++ /* make sure there's no pending interrupt when we go into suspend */ ++ writel(0, iproc_i2c->base + IE_OFFSET); ++ readl(iproc_i2c->base + IE_OFFSET); ++ synchronize_irq(iproc_i2c->irq); ++ ++ /* now disable the controller */ ++ bcm_iproc_i2c_enable_disable(iproc_i2c, false); ++ ++ return 0; ++} ++ ++static int bcm_iproc_i2c_resume(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct bcm_iproc_i2c_dev *iproc_i2c = platform_get_drvdata(pdev); ++ int ret; ++ u32 val; ++ ++ /* ++ * Power domain could have been shut off completely in system deep ++ * sleep, so re-initialize the block here ++ */ ++ ret = bcm_iproc_i2c_init(iproc_i2c); ++ if (ret) ++ return ret; ++ ++ /* configure to the desired bus speed */ ++ val = readl(iproc_i2c->base + TIM_CFG_OFFSET); ++ val &= ~(1 << TIM_CFG_MODE_400_SHIFT); ++ val |= (iproc_i2c->bus_speed == 400000) << TIM_CFG_MODE_400_SHIFT; ++ writel(val, iproc_i2c->base + TIM_CFG_OFFSET); ++ ++ bcm_iproc_i2c_enable_disable(iproc_i2c, true); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops bcm_iproc_i2c_pm_ops = { ++ .suspend_late = &bcm_iproc_i2c_suspend, ++ .resume_early = &bcm_iproc_i2c_resume ++}; ++ ++#define BCM_IPROC_I2C_PM_OPS (&bcm_iproc_i2c_pm_ops) ++#else ++#define BCM_IPROC_I2C_PM_OPS NULL ++#endif /* CONFIG_PM_SLEEP */ ++ ++static const struct of_device_id bcm_iproc_i2c_of_match[] = { ++ { .compatible = "brcm,iproc-i2c" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, bcm_iproc_i2c_of_match); ++ ++static struct platform_driver bcm_iproc_i2c_driver = { ++ .driver = { ++ .name = "bcm-iproc-i2c", ++ .of_match_table = bcm_iproc_i2c_of_match, ++ .pm = BCM_IPROC_I2C_PM_OPS, ++ }, ++ .probe = bcm_iproc_i2c_probe, ++ .remove = bcm_iproc_i2c_remove, ++}; ++module_platform_driver(bcm_iproc_i2c_driver); ++ ++MODULE_DESCRIPTION("Broadcom iProc I2C Driver"); ++MODULE_LICENSE("GPL v2"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/iproc_smbus_regs.h b/drivers/i2c/busses/iproc_smbus_regs.h +--- a/drivers/i2c/busses/iproc_smbus_regs.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/i2c/busses/iproc_smbus_regs.h 2018-05-10 11:31:30.877400982 +0800 +@@ -0,0 +1,287 @@ ++/* ++ * Copyright (C) 2013 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __IPROC_SMBUS_REGS_H__ ++#define __IPROC_SMBUS_REGS_H__ ++ ++/* --- */ ++#define CCB_SMB_CFG_REG 0x0 ++ ++#define CCB_SMB_CFG_RST_MASK 0x80000000 ++#define CCB_SMB_CFG_RST_SHIFT 31 ++ ++#define CCB_SMB_CFG_SMBEN_MASK 0x40000000 ++#define CCB_SMB_CFG_SMBEN_SHIFT 30 ++ ++#define CCB_SMB_CFG_BITBANGEN_MASK 0x20000000 ++#define CCB_SMB_CFG_BITBANGEN_SHIFT 29 ++ ++#define CCB_SMB_CFG_EN_NIC_SMBADDR0_MASK 0x10000000 ++#define CCB_SMB_CFG_EN_NIC_SMBADDR0_SHIFT 28 ++ ++#define CCB_SMB_CFG_PROMISCMODE_MASK 0x08000000 ++#define CCB_SMB_CFG_PROMISCMODE_SHIFT 27 ++ ++#define CCB_SMB_CFG_TSTMPCNTEN_MASK 0x04000000 ++#define CCB_SMB_CFG_TSTMPCNTEN_SHIFT 26 ++ ++#define CCB_SMB_CFG_MSTRRTRYCNT_MASK 0x000F0000 ++#define CCB_SMB_CFG_MSTRRTRYCNT_SHIFT 16 ++ ++ ++/* --- */ ++#define CCB_SMB_TIMGCFG_REG 0x4 ++ ++#define CCB_SMB_TIMGCFG_MODE400_MASK 0x80000000 ++#define CCB_SMB_TIMGCFG_MODE400_SHIFT 31 ++ ++#define CCB_SMB_TIMGCFG_RNDSLVSTR_MASK 0x7F000000 ++#define CCB_SMB_TIMGCFG_RNDSLVSTR_SHIFT 24 ++ ++#define CCB_SMB_TIMGCFG_PERSLVSTR_MASK 0x00FF0000 ++#define CCB_SMB_TIMGCFG_PERSLVSTR_SHIFT 16 ++ ++#define CCB_SMB_TIMGCFG_IDLTIME_MASK 0x0000FF00 ++#define CCB_SMB_TIMGCFG_IDLTIME_SHIFT 8 ++ ++/* --- */ ++#define CCB_SMB_ADDR_REG 0x8 ++ ++#define CCB_SMB_EN_NIC_SMBADDR3_MASK 0x80000000 ++#define CCB_SMB_EN_NIC_SMBADDR3_SHIFT 31 ++ ++#define CCB_SMB_NIC_SMBADDR3_MASK 0x7F000000 ++#define CCB_SMB_NIC_SMBADDR3_SHIFT 24 ++ ++#define CCB_SMB_EN_NIC_SMBADDR2_MASK 0x00800000 ++#define CCB_SMB_EN_NIC_SMBADDR2_SHIFT 23 ++ ++#define CCB_SMB_NIC_SMBADDR2_MASK 0x007F0000 ++#define CCB_SMB_NIC_SMBADDR2_SHIFT 16 ++ ++#define CCB_SMB_EN_NIC_SMBADDR1_MASK 0x00008000 ++#define CCB_SMB_EN_NIC_SMBADDR1_SHIFT 15 ++ ++#define CCB_SMB_NIC_SMBADDR1_MASK 0x00007F00 ++#define CCB_SMB_NIC_SMBADDR1_SHIFT 8 ++ ++#define CCB_SMB_EN_NIC_SMBADDR0_MASK 0x00000080 ++#define CCB_SMB_EN_NIC_SMBADDR0_SHIFT 7 ++ ++#define CCB_SMB_NIC_SMBADDR0_MASK 0x0000007F ++#define CCB_SMB_NIC_SMBADDR0_SHIFT 0 ++ ++/* --- */ ++#define CCB_SMB_MSTRFIFOCTL_REG 0xC ++ ++#define CCB_SMB_MSTRRXFIFOFLSH_MASK 0x80000000 ++#define CCB_SMB_MSTRRXFIFOFLSH_SHIFT 31 ++ ++#define CCB_SMB_MSTRTXFIFOFLSH_MASK 0x40000000 ++#define CCB_SMB_MSTRTXFIFOFLSH_SHIFT 30 ++ ++#define CCB_SMB_MSTRRXPKTCNT_MASK 0x007F0000 ++#define CCB_SMB_MSTRRXPKTCNT_SHIFT 16 ++ ++#define CCB_SMB_MSTRRXFIFOTHR_MASK 0x00003F00 ++#define CCB_SMB_MSTRRXFIFOTHR_SHIFT 8 ++ ++/* --- */ ++#define CCB_SMB_SLVFIFOCTL_REG 0x10 ++ ++#define CCB_SMB_SLVRXFIFOFLSH_MASK 0x80000000 ++#define CCB_SMB_SLVRXFIFOFLSH_SHIFT 31 ++ ++#define CCB_SMB_SLVTXFIFOFLSH_MASK 0x40000000 ++#define CCB_SMB_SLVTXFIFOFLSH_SHIFT 30 ++ ++#define CCB_SMB_SLVRXPKTCNT_MASK 0x007F0000 ++#define CCB_SMB_SLVRXPKTCNT_SHIFT 16 ++ ++#define CCB_SMB_SLVRXFIFOTHR_MASK 0x00003F00 ++#define CCB_SMB_SLVRXFIFOTHR_SHIFT 8 ++ ++/* --- */ ++#define CCB_SMB_BITBANGCTL_REG 0x14 ++ ++#define CCB_SMB_SMBCLKIN_MASK 0x80000000 ++#define CCB_SMB_SMBCLKIN_SHIFT 31 ++ ++#define CCB_SMB_SMBCLKOUTEN_MASK 0x40000000 ++#define CCB_SMB_SMBCLKOUTEN_SHIFT 30 ++ ++#define CCB_SMB_SMBDATAIN_MASK 0x20000000 ++#define CCB_SMB_SMBDATAIN_SHIFT 29 ++ ++#define CCB_SMB_SMBDATAOUTEN_MASK 0x10000000 ++#define CCB_SMB_SMBDATAOUTEN_SHIFT 28 ++ ++/* --- */ ++#define CCB_SMB_MSTRCMD_REG 0x30 ++ ++#define CCB_SMB_MSTRSTARTBUSYCMD_MASK 0x80000000 ++#define CCB_SMB_MSTRSTARTBUSYCMD_SHIFT 31 ++ ++#define CCB_SMB_MSTRABORT_MASK 0x40000000 ++#define CCB_SMB_MSTRABORT_SHIFT 30 ++ ++#define CCB_SMB_MSTRSTS_MASK 0x0E000000 ++#define CCB_SMB_MSTRSTS_SHIFT 25 ++ ++#define CCB_SMB_MSTRSMBUSPROTO_MASK 0x00001E00 ++#define CCB_SMB_MSTRSMBUSPROTO_SHIFT 9 ++ ++#define CCB_SMB_MSTRPEC_MASK 0x00000100 ++#define CCB_SMB_MSTRPEC_SHIFT 8 ++ ++#define CCB_SMB_MSTRRDBYTECNT_MASK 0x000000FF ++#define CCB_SMB_MSTRRDBYTECNT_SHIFT 0 ++ ++/* --- */ ++#define CCB_SMB_SLVCMD_REG 0x34 ++ ++#define CCB_SMB_SLVSTARTBUSYCMD_MASK 0x80000000 ++#define CCB_SMB_SLVSTARTBUSYCMD_SHIFT 31 ++ ++#define CCB_SMB_SLVABORT_MASK 0x40000000 ++#define CCB_SMB_SLVABORT_SHIFT 30 ++ ++#define CCB_SMB_SLVSTS_MASK 0x03800000 ++#define CCB_SMB_SLVSTS_SHIFT 23 ++ ++#define CCB_SMB_SLVPEC_MASK 0x00000100 ++#define CCB_SMB_SLVPEC_SHIFT 8 ++ ++ ++/* --- */ ++#define CCB_SMB_EVTEN_REG 0x38 ++ ++#define CCB_SMB_MSTRRXFIFOFULLEN_MASK 0x80000000 ++#define CCB_SMB_MSTRRXFIFOFULLEN_SHIFT 31 ++ ++#define CCB_SMB_MSTRRXFIFOTHRHITEN_MASK 0x40000000 ++#define CCB_SMB_MSTRRXFIFOTHRHITEN_SHIFT 30 ++ ++#define CCB_SMB_MSTRRXEVTEN_MASK 0x20000000 ++#define CCB_SMB_MSTRRXEVTEN_SHIFT 29 ++ ++#define CCB_SMB_MSTRSTARTBUSYEN_MASK 0x10000000 ++#define CCB_SMB_MSTRSTARTBUSYEN_SHIFT 28 ++ ++#define CCB_SMB_MSTRTXUNDEN_MASK 0x08000000 ++#define CCB_SMB_MSTRTXUNDEN_SHIFT 27 ++ ++ ++#define CCB_SMB_SLVRXFIFOFULLEN_MASK 0x04000000 ++#define CCB_SMB_SLVRXFIFOFULLEN_SHIFT 26 ++ ++#define CCB_SMB_SLVRXFIFOTHRHITEN_MASK 0x02000000 ++#define CCB_SMB_SLVRXFIFOTHRHITEN_SHIFT 25 ++ ++#define CCB_SMB_SLVRXEVTEN_MASK 0x01000000 ++#define CCB_SMB_SLVRXEVTEN_SHIFT 24 ++ ++#define CCB_SMB_SLVSTARTBUSYEN_MASK 0x00800000 ++#define CCB_SMB_SLVSTARTBUSYEN_SHIFT 23 ++ ++#define CCB_SMB_SLVTXUNDEN_MASK 0x00400000 ++#define CCB_SMB_SLVTXUNDEN_SHIFT 22 ++ ++#define CCB_SMB_SLVRDEVTEN_MASK 0x00200000 ++#define CCB_SMB_SLVRDEVTEN_SHIFT 21 ++ ++ ++/* --- */ ++#define CCB_SMB_EVTSTS_REG 0x3C ++ ++#define CCB_SMB_MSTRRXFIFOFULLSTS_MASK 0x80000000 ++#define CCB_SMB_MSTRRXFIFOFULLSTS_SHIFT 31 ++ ++#define CCB_SMB_MSTRRXFIFOTHRHITSTS_MASK 0x40000000 ++#define CCB_SMB_MSTRRXFIFOTHRHITSTS_SHIFT 30 ++ ++#define CCB_SMB_MSTRRXEVTSTS_MASK 0x20000000 ++#define CCB_SMB_MSTRRXEVTSTS_SHIFT 29 ++ ++#define CCB_SMB_MSTRSTARTBUSYSTS_MASK 0x10000000 ++#define CCB_SMB_MSTRSTARTBUSYSTS_SHIFT 28 ++ ++#define CCB_SMB_MSTRTXUNDSTS_MASK 0x08000000 ++#define CCB_SMB_MSTRTXUNDSTS_SHIFT 27 ++ ++ ++#define CCB_SMB_SLVRXFIFOFULLSTS_MASK 0x04000000 ++#define CCB_SMB_SLVRXFIFOFULLSTS_SHIFT 26 ++ ++#define CCB_SMB_SLVRXFIFOTHRHITSTS_MASK 0x02000000 ++#define CCB_SMB_SLVRXFIFOTHRHITSTS_SHIFT 25 ++ ++#define CCB_SMB_SLVRXEVTSTS_MASK 0x01000000 ++#define CCB_SMB_SLVRXEVTSTS_SHIFT 24 ++ ++#define CCB_SMB_SLVSTARTBUSYSTS_MASK 0x00800000 ++#define CCB_SMB_SLVSTARTBUSYSTS_SHIFT 23 ++ ++#define CCB_SMB_SLVTXUNDSTS_MASK 0x00400000 ++#define CCB_SMB_SLVTXUNDSTS_SHIFT 22 ++ ++#define CCB_SMB_SLVRDEVTSTS_MASK 0x00200000 ++#define CCB_SMB_SLVRDEVTSTS_SHIFT 21 ++ ++ ++/* --- */ ++#define CCB_SMB_MSTRDATAWR_REG 0x40 ++ ++#define CCB_SMB_MSTRWRSTS_MASK 0x80000000 ++#define CCB_SMB_MSTRWRSTS_SHIFT 31 ++ ++#define CCB_SMB_MSTRWRDATA_MASK 0x000000FF ++#define CCB_SMB_MSTRWRDATA_SHIFT 0 ++ ++ ++/* --- */ ++#define CCB_SMB_MSTRDATARD_REG 0x44 ++ ++#define CCB_SMB_MSTRRDSTS_MASK 0xC0000000 ++#define CCB_SMB_MSTRRDSTS_SHIFT 30 ++ ++#define CCB_SMB_MSTRRDPECERR_MASK 0x20000000 ++#define CCB_SMB_MSTRRDPECERR_SHIFT 29 ++ ++#define CCB_SMB_MSTRRDDATA_MASK 0x000000FF ++#define CCB_SMB_MSTRRDDATA_SHIFT 0 ++ ++ ++/* --- */ ++#define CCB_SMB_SLVDATAWR_REG 0x48 ++ ++#define CCB_SMB_SLVWRSTS_MASK 0x80000000 ++#define CCB_SMB_SLVWRSTS_SHIFT 31 ++ ++#define CCB_SMB_SLVWRDATA_MASK 0x000000FF ++#define CCB_SMB_SLVWRDATA_SHIFT 0 ++ ++ ++/* --- */ ++#define CCB_SMB_SLVDATARD_REG 0x4C ++ ++#define CCB_SMB_SLVRDSTS_MASK 0xC0000000 ++#define CCB_SMB_SLVRDSTS_SHIFT 30 ++ ++#define CCB_SMB_SLVRDERRSTS_MASK 0x30000000 ++#define CCB_SMB_SLVRDERRSTS_SHIFT 28 ++ ++#define CCB_SMB_SLVRDDATA_MASK 0x000000FF ++#define CCB_SMB_SLVRDDATA_SHIFT 0 ++ ++#endif /* __IPROC_SMBUS_REGS_H__ */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/xgs_iproc_smbus.c b/drivers/i2c/busses/xgs_iproc_smbus.c +--- a/drivers/i2c/busses/xgs_iproc_smbus.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/i2c/busses/xgs_iproc_smbus.c 2018-05-10 11:31:30.881400987 +0800 +@@ -0,0 +1,1075 @@ ++/* ++ * Copyright (C) 2013 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "iproc_smbus_regs.h" ++ ++/* SMBUS protocol values defined in register 0x30 */ ++#define SMBUS_PROT_QUICK_CMD 0 ++#define SMBUS_PROT_SEND_BYTE 1 ++#define SMBUS_PROT_RECV_BYTE 2 ++#define SMBUS_PROT_WR_BYTE 3 ++#define SMBUS_PROT_RD_BYTE 4 ++#define SMBUS_PROT_WR_WORD 5 ++#define SMBUS_PROT_RD_WORD 6 ++#define SMBUS_PROT_BLK_WR 7 ++#define SMBUS_PROT_BLK_RD 8 ++#define SMBUS_PROT_PROC_CALL 9 ++#define SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL 10 ++ ++#define MSTR_STS_XACT_SUCCESS 0 ++#define DISABLE_INTR 0 ++#define ENABLE_INTR 1 ++#define SMB_MAX_DATA_SIZE 32 ++#define XACT_TIMEOUT msecs_to_jiffies(100) ++#define init_MUTEX(x) sema_init(x,1) ++#define IPROC_SMB_MAX_RETRIES 35 ++ ++#define GETREGFLDVAL(regval, mask, startbit) (((regval) & (mask)) >> (startbit)) ++ ++#define SETREGFLDVAL(regval, fldval, mask, startbit) regval = \ ++ (regval & ~(mask)) | \ ++ ((fldval) << (startbit)) ++ ++typedef enum iproc_smb_clk_freq { ++ I2C_SPEED_100KHz = 0, ++ I2C_SPEED_400KHz = 1, ++ I2C_SPEED_INVALID = 255 ++} smb_clk_freq_t; ++ ++/* Counters will be used mainly for testing and debugging */ ++struct iproc_smb_counters { ++ unsigned int num_read_requests; ++ unsigned int num_write_requests; ++ unsigned int num_read_errors; ++ unsigned int num_write_errors; ++ unsigned int mstr_rx_evt_cnt; /* ISR counter to check recv event */ ++ unsigned int mstr_start_busy_cnt; /* ISR counter to checking xact sts */ ++ unsigned int mstr_rx_fifo_full_cnt; /* ISR counter to detect rx fifo full */ ++ unsigned int last_int_sts; /* last value of intr status reg */ ++}; ++ ++/* This structure will be used internally by the driver to maintain its ++ * configuration information as well as information programmed into the hardware ++ */ ++struct iproc_smb_drv_int_data { ++ struct device *dev; ++ struct iproc_smb_drv_int_data *next; ++ int irq; ++ unsigned int drv_state_init; /* 1 = Initialized, 0 = not initialized */ ++ unsigned int drv_state_open; /* 1 = Accepting transaction requests, ++ 0 = Not accepting transaction requests */ ++ smb_clk_freq_t clk_speed; ++ void __iomem *base; /* virtual base address for register access */ ++ struct i2c_adapter adapter; ++ unsigned int i2c_slave_addr; ++ struct semaphore xfer_lock; /* Lock for data transfer */ ++ struct completion ses_done; /* To signal the command completion */ ++ volatile int debug; ++ unsigned int master_rx_fifo_thr; /* Master FIFO threshold */ ++ unsigned int slave_rx_fifo_thr; /* Slave FIFO threshold */ ++ unsigned int enable_evts; ++ unsigned int evt_enable_bmap; /* Bit map of events enabled by the driver */ ++ struct iproc_smb_counters smb_counters; /* Statistics maintained by driver */ ++}; ++ ++/* Structure used to pass information to read/write functions. */ ++struct iproc_xact_info { ++ bool cmd_valid; /* true if command field below is valid. Otherwise, false */ ++ unsigned short command; /* Passed by caller to send SMBus command code */ ++ unsigned char *data; /* actual data pased by the caller */ ++ unsigned int size; /* Size of data buffer passed */ ++ unsigned short flags; /* Sent by caller specifying PEC, 10-bit addresses */ ++ unsigned char smb_proto; /* SMBus protocol to use to perform transaction */ ++}; ++ ++static irqreturn_t iproc_smb_isr(int irq, void *devid) ++{ ++ struct iproc_smb_drv_int_data *dev = ++ (struct iproc_smb_drv_int_data *)devid; ++ unsigned int intsts; ++ unsigned int regval; ++ ++ intsts = readl(dev->base + CCB_SMB_EVTSTS_REG); ++ dev->smb_counters.last_int_sts = intsts; ++ ++ if (!intsts) ++ /* Likely received a spurious interrupt */ ++ return IRQ_NONE; ++ ++ /* Clear interrupts */ ++ writel(intsts, dev->base + CCB_SMB_EVTSTS_REG); ++ ++ /* Master read or write complete */ ++ if ((intsts & CCB_SMB_MSTRSTARTBUSYEN_MASK) || ++ (intsts & CCB_SMB_MSTRRXEVTSTS_MASK)) { ++ ++ if (intsts & CCB_SMB_MSTRSTARTBUSYEN_MASK) ++ dev->smb_counters.mstr_start_busy_cnt++; ++ ++ if (intsts & CCB_SMB_MSTRRXEVTSTS_MASK) ++ dev->smb_counters.mstr_rx_evt_cnt++; ++ ++ complete(&dev->ses_done); ++ } ++ ++ /* If RX FIFO was full we can either read and then flush the FIFO. ++ * Or, only flush the FIFO, and then the client process can restart ++ * the transaction. ++ * For now, we will flush the later action. ++ */ ++ if (intsts & CCB_SMB_MSTRRXFIFOFULLSTS_MASK) { ++ dev->smb_counters.mstr_rx_fifo_full_cnt++; ++ regval = readl(dev->base + CCB_SMB_MSTRFIFOCTL_REG); ++ regval |= CCB_SMB_MSTRRXFIFOFLSH_MASK; ++ writel(regval, dev->base + CCB_SMB_MSTRFIFOCTL_REG); ++ complete(&dev->ses_done); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++/* ++ * This function set clock frequency for SMBus block. As per hardware ++ * engineering, the clock frequency can be changed dynamically. ++ */ ++static int iproc_smb_set_clk_freq(void __iomem *base_addr, ++ smb_clk_freq_t freq) ++{ ++ unsigned int regval; ++ unsigned int val; ++ ++ switch (freq) { ++ case I2C_SPEED_100KHz: ++ val = 0; ++ break; ++ ++ case I2C_SPEED_400KHz: ++ val = 1; ++ break; ++ ++ default: ++ return -EINVAL; ++ break; ++ } ++ ++ regval = readl(base_addr + CCB_SMB_TIMGCFG_REG); ++ SETREGFLDVAL(regval, val, CCB_SMB_TIMGCFG_MODE400_MASK, ++ CCB_SMB_TIMGCFG_MODE400_SHIFT); ++ writel(regval, base_addr + CCB_SMB_TIMGCFG_REG); ++ ++ return 0; ++} ++ ++static int iproc_smbus_block_init(struct iproc_smb_drv_int_data *dev) ++{ ++ ++ void __iomem *base_addr = dev->base; ++ unsigned int regval; ++ u32 i2c_clk_freq; ++ struct device_node *dn = dev->dev->of_node; ++ ++ /* Flush Tx, Rx FIFOs. Note we are setting the Rx FIFO threshold to 0. ++ * May be OK since we are setting RX_EVENT and RX_FIFO_FULL interrupts ++ */ ++ regval = CCB_SMB_MSTRRXFIFOFLSH_MASK | CCB_SMB_MSTRTXFIFOFLSH_MASK; ++ ++ writel(regval, base_addr + CCB_SMB_MSTRFIFOCTL_REG); ++ ++ /* Enable SMbus block. Note, we are setting MASTER_RETRY_COUNT to zero ++ * since there will be only one master ++ */ ++ regval = CCB_SMB_CFG_SMBEN_MASK; ++ ++ writel(regval, base_addr + CCB_SMB_CFG_REG); ++ ++ /* Wait a minimum of 50 Usec, as per SMB hw doc. But we wait longer */ ++ udelay(100); ++ ++ /* Set default clock frequency */ ++ if (of_property_read_u32(dn, "clock-frequency", &i2c_clk_freq)) ++ /*no property available, use default: 100KHz*/ ++ i2c_clk_freq = I2C_SPEED_100KHz; ++ iproc_smb_set_clk_freq(base_addr, i2c_clk_freq); ++ ++ /* Disable intrs */ ++ regval = 0x0; ++ writel(regval, base_addr + CCB_SMB_EVTEN_REG); ++ ++ /* Clear intrs (W1TC) */ ++ regval = readl(base_addr + CCB_SMB_EVTSTS_REG); ++ writel(regval, base_addr + CCB_SMB_EVTSTS_REG); ++ ++ return(0); ++} ++ ++/* ++ * Function to ensure that the previous transaction was completed before ++ * initiating a new transaction. It can also be used in polling mode to ++ * check status of completion of a command ++ */ ++static int iproc_smb_startbusy_wait(struct iproc_smb_drv_int_data *dev) ++{ ++ unsigned int regval; ++ ++ regval = readl(dev->base + CCB_SMB_MSTRCMD_REG); ++ ++ /* Check if an operation is in progress. During probe it won't be. ++ * But when shutdown/remove was called we want to make sure that ++ * the transaction in progress completed ++ */ ++ if (regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK) { ++ unsigned int i = 0; ++ ++ do { ++ msleep(1); ++ i++; ++ regval = readl(dev->base + CCB_SMB_MSTRCMD_REG); ++ /* If start-busy bit cleared, exit the loop */ ++ } while ((regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK) && ++ (i < IPROC_SMB_MAX_RETRIES)); ++ ++ if (i >= IPROC_SMB_MAX_RETRIES) { ++ dev_err(dev->dev, "START_BUSY bit didn't clear\n"); ++ return -ETIMEDOUT; ++ } ++ } ++ ++ return 0; ++} ++ ++ ++static u32 smbus0_sdaRecoveryCnt=0, smbus0_sdaFailedCnt=0, smbus0_startBusyCnt=0; ++static u32 smbus1_sdaRecoveryCnt=0, smbus1_sdaFailedCnt=0, smbus1_startBusyCnt=0; ++ ++/* ++ * Function to recover SMB hangs caused stuck master START_BUSY. ++ * Returns 0 if recovery procedure executed successfully. ++ * Returns -1 if recovery failed. ++ */ ++static int iproc_smb_startbusy_recovery(struct iproc_smb_drv_int_data *dev) ++{ ++ int rc = -1; ++ unsigned int recoveryCnt; ++ ++ if (dev->adapter.nr == 0) ++ recoveryCnt = ++smbus0_startBusyCnt; ++ else ++ recoveryCnt = ++smbus1_startBusyCnt; ++ ++ dev_info(dev->dev, "START_BUSY recovery #%d \n", recoveryCnt); ++ ++ /* reset the SMBus block, wait a minimum of 50 uSecs and then re-initialize */ ++ writel(CCB_SMB_CFG_RST_MASK, dev->base + CCB_SMB_CFG_REG); ++ udelay(60); ++ ++ if (iproc_smbus_block_init(dev) == 0) ++ rc = 0; ++ ++ return rc; ++} ++ ++ ++/* ++ * Function to recover SMB hang caused by a slave device holding SDA low. ++ * Returns 0 if recovery procedure executed successfully. ++ * Returns -1 if recovery failed. ++ */ ++ ++static int iproc_smb_sda_low_recovery(struct iproc_smb_drv_int_data *dev) ++{ ++ unsigned int bbReg, cfgReg, cfgSave, recoveryCnt, failedCnt, i; ++ int rc = -1; ++ ++ /* enable bit-bang */ ++ cfgSave = readl(dev->base + CCB_SMB_CFG_REG); ++ cfgReg = cfgSave; ++ cfgReg |= CCB_SMB_CFG_BITBANGEN_MASK; ++ writel(cfgReg, dev->base + CCB_SMB_CFG_REG); ++ udelay(50); ++ ++ /* start with clock and SDA set high */ ++ bbReg = readl(dev->base + CCB_SMB_BITBANGCTL_REG); ++ bbReg |= (CCB_SMB_SMBCLKOUTEN_MASK | CCB_SMB_SMBDATAOUTEN_MASK); ++ writel(bbReg, dev->base + CCB_SMB_BITBANGCTL_REG); ++ udelay(5); /* should be sufficient for 100 KHz bus */ ++ ++ /* set up to toggle the clock line with SDA out held high for 9 cycles */ ++ for (i = 0; i < 18; i++) { ++ /* toggle CLK out */ ++ if ( (bbReg & CCB_SMB_SMBCLKOUTEN_MASK) == 0 ) ++ bbReg |= CCB_SMB_SMBCLKOUTEN_MASK; /* set clock high */ ++ else ++ bbReg &= ~CCB_SMB_SMBCLKOUTEN_MASK; /* set clock low */ ++ ++ writel(bbReg, dev->base + CCB_SMB_BITBANGCTL_REG); ++ udelay(5); ++ } ++ ++ /* check bit 29 -- SMBDAT_IN and make sure SDA not being held low any more */ ++ for (i = 0; i < 10; i++) { ++ bbReg = readl(dev->base + CCB_SMB_BITBANGCTL_REG); ++ bbReg &= CCB_SMB_SMBDATAIN_MASK; ++ if (bbReg) ++ break; ++ udelay(1); ++ } ++ ++ if (bbReg == 0) { ++ /* SDA is still low */ ++ if (dev->adapter.nr == 0) ++ failedCnt = ++smbus0_sdaFailedCnt; ++ else ++ failedCnt = ++smbus1_sdaFailedCnt; ++ ++ dev_info(dev->dev, "SDA release #%d FAILED.\n", failedCnt); ++ } else { ++ if (dev->adapter.nr == 0) ++ recoveryCnt = ++smbus0_sdaRecoveryCnt; ++ else ++ recoveryCnt = ++smbus1_sdaRecoveryCnt; ++ ++ dev_info(dev->dev, "SDA release #%d SUCCESS.\n", recoveryCnt); ++ rc = 0; ++ } ++ ++ /* manually issue a stop by transitioning SDA from low to high with clock held high */ ++ bbReg = readl(dev->base + CCB_SMB_BITBANGCTL_REG); ++ bbReg &= ~CCB_SMB_SMBCLKOUTEN_MASK; /* set clock low */ ++ writel(bbReg, dev->base + CCB_SMB_BITBANGCTL_REG); ++ udelay(2); ++ ++ bbReg &= ~CCB_SMB_SMBDATAOUTEN_MASK; /* drop SDA low */ ++ writel(bbReg, dev->base + CCB_SMB_BITBANGCTL_REG); ++ udelay(2); ++ ++ bbReg |= CCB_SMB_SMBCLKOUTEN_MASK; /* set clock high */ ++ writel(bbReg, dev->base + CCB_SMB_BITBANGCTL_REG); ++ udelay(5); ++ ++ bbReg |= CCB_SMB_SMBDATAOUTEN_MASK; /* pull SDA high */ ++ writel(bbReg, dev->base + CCB_SMB_BITBANGCTL_REG); ++ udelay(2); ++ ++ /* disable bit-bang and then re-enable the SMB with the saved configuration */ ++ cfgReg = readl(dev->base + CCB_SMB_CFG_REG); ++ cfgReg &= ~CCB_SMB_CFG_BITBANGEN_MASK; ++ writel(cfgReg, dev->base + CCB_SMB_CFG_REG); ++ udelay(10); ++ ++ writel(cfgSave, dev->base + CCB_SMB_CFG_REG); ++ ++ return rc; ++} ++ ++ ++/* ++ * Function to recover SMB hang caused by a slave device hold SDA low. ++ * Returns 0 if recovery procedure executed successfully. ++ * Returns -1 if recovery failed. ++ */ ++static int iproc_smb_timeout_recovery(struct iproc_smb_drv_int_data *dev) ++{ ++ unsigned int bbReg, mCmdReg; ++ int rc = -1; ++ ++ /* read bit-bang control. If SDA low, attempt SDA release recovery */ ++ bbReg = readl(dev->base + CCB_SMB_BITBANGCTL_REG); ++ ++ if ((bbReg & CCB_SMB_SMBDATAIN_MASK) == 0) ++ if (iproc_smb_sda_low_recovery(dev) == 0) ++ rc = 0; ++ ++ /* regardless of whether there was an SDA hang or not, see if START_BUSY stuck high */ ++ mCmdReg = readl( dev->base + CCB_SMB_MSTRCMD_REG ); ++ if (mCmdReg & CCB_SMB_MSTRSTARTBUSYCMD_MASK) ++ /* attempt to recover the bus */ ++ if (iproc_smb_startbusy_recovery(dev) == 0) ++ rc = 0; ++ ++ return rc; ++} ++ ++/* ++ * Copy data to SMBus's Tx FIFO. Valid for write transactions only ++ * ++ * base_addr: Mapped address of this SMBus instance ++ * dev_addr: SMBus device address. Assuming 7-bit addresses initially ++ * info: Data to copy in to Tx FIFO. For read commands, the size should be ++ * set to zero by the caller ++ * ++ */ ++static void iproc_smb_write_trans_data(void __iomem *base_addr, ++ unsigned short dev_addr, ++ struct iproc_xact_info *info) ++{ ++ unsigned int regval; ++ unsigned int i; ++ unsigned int num_data_bytes = 0; ++ ++ /* Write SMBus device address first */ ++ /* We are assuming 7-bit addresses for now. For 10-bit addresses, ++ * we may have one more write to send the upper 3 bits of 10-bit addr ++ */ ++ writel(dev_addr, base_addr + CCB_SMB_MSTRDATAWR_REG); ++ ++ /* If the protocol needs command code, copy it */ ++ if (info->cmd_valid == true) ++ writel(info->command, base_addr + CCB_SMB_MSTRDATAWR_REG); ++ ++ /* ++ * Depending on the SMBus protocol, we need to write additional ++ * transaction data into Tx FIFO. ++ * Refer to section 5.5 of SMBus spec for sequence for a transaction ++ */ ++ switch (info->smb_proto) { ++ case SMBUS_PROT_RECV_BYTE: ++ /* No additional data to be written */ ++ num_data_bytes = 0; ++ break; ++ ++ case SMBUS_PROT_SEND_BYTE: ++ num_data_bytes = info->size; ++ break; ++ ++ case SMBUS_PROT_RD_BYTE: ++ case SMBUS_PROT_RD_WORD: ++ case SMBUS_PROT_BLK_RD: ++ /* Write slave address with R/W~ set (bit #0) */ ++ writel(dev_addr | 0x1, base_addr + CCB_SMB_MSTRDATAWR_REG); ++ num_data_bytes = 0; ++ break; ++ ++ case SMBUS_PROT_WR_BYTE: ++ case SMBUS_PROT_WR_WORD: ++ /* No additional bytes to be written */ ++ /* Data portion is written in the 'for' loop below */ ++ num_data_bytes = info->size; ++ break; ++ ++ case SMBUS_PROT_BLK_WR: ++ /* 3rd byte is byte count */ ++ writel(info->size, base_addr + CCB_SMB_MSTRDATAWR_REG); ++ num_data_bytes = info->size; ++ break; ++ ++ case SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL: ++ /* Write byte count */ ++ writel(info->size, base_addr + CCB_SMB_MSTRDATAWR_REG); ++ num_data_bytes = info->size; ++ break; ++ ++ default: ++ break; ++ } ++ ++ /* Copy actual data from caller */ ++ for (i = 0; num_data_bytes; --num_data_bytes, i++) { ++ /* For the last byte, set MASTER_WR_STATUS bit. For block rd/wr process ++ * call, we need to program slave addr after copying data byte(s), so ++ * master status bit is set later, after the loop ++ */ ++ if ((num_data_bytes == 1) && ++ (info->smb_proto != SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL)) ++ regval = info->data[i] | CCB_SMB_MSTRWRSTS_MASK; ++ else ++ regval = info->data[i]; ++ ++ writel(regval, base_addr + CCB_SMB_MSTRDATAWR_REG); ++ } ++ ++ if (info->smb_proto == SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL) ++ /* Write device address needed during repeat start condition */ ++ writel(CCB_SMB_MSTRWRSTS_MASK | dev_addr | 0x1, ++ base_addr + CCB_SMB_MSTRDATAWR_REG); ++ ++ return; ++} ++ ++static int iproc_smb_data_send(struct i2c_adapter *adapter, ++ unsigned short addr, ++ struct iproc_xact_info *info) ++{ ++ int rc; ++ unsigned int regval; ++ struct iproc_smb_drv_int_data *dev = i2c_get_adapdata(adapter); ++ unsigned long time_left; ++ ++ /* Make sure the previous transaction completed */ ++ rc = iproc_smb_startbusy_wait(dev); ++ if (rc < 0) { ++ dev_err(dev->dev, "Send: bus is busy, attempt recovery \n"); ++ /* attempt to recover the bus */ ++ if (iproc_smb_startbusy_recovery(dev) != 0) ++ return rc; ++ } ++ ++ if (dev->enable_evts == ENABLE_INTR) { ++ /* Enable start_busy interrupt */ ++ regval = readl(dev->base + CCB_SMB_EVTEN_REG); ++ regval |= CCB_SMB_MSTRSTARTBUSYEN_MASK; ++ writel(regval, dev->base + CCB_SMB_EVTEN_REG); ++ /* Mark as incomplete before sending the data */ ++ reinit_completion(&dev->ses_done); ++ } ++ ++ /* Write transaction bytes to Tx FIFO */ ++ iproc_smb_write_trans_data(dev->base, addr, info); ++ ++ /* Program master command register (0x30) with protocol type and ++ * set start_busy_command bit to initiate the write transaction ++ */ ++ regval = (info->smb_proto << CCB_SMB_MSTRSMBUSPROTO_SHIFT) | ++ CCB_SMB_MSTRSTARTBUSYCMD_MASK; ++ writel(regval, dev->base + CCB_SMB_MSTRCMD_REG); ++ ++ if (dev->enable_evts == ENABLE_INTR) { ++ /* ++ * Block waiting for the transaction to finish. When finished, ++ * we'll be signaled by an interrupt ++ */ ++ time_left = wait_for_completion_timeout(&dev->ses_done, ++ XACT_TIMEOUT); ++ /* Disable start_busy interrupt */ ++ regval = readl(dev->base + CCB_SMB_EVTEN_REG); ++ regval &= ~CCB_SMB_MSTRSTARTBUSYEN_MASK; ++ writel(regval, dev->base + CCB_SMB_EVTEN_REG); ++ ++ if (time_left == 0) { ++ dev_info(dev->dev, "Send: timeout accessing device"); ++ /* attempt to recover the bus */ ++ rc = iproc_smb_timeout_recovery(dev); ++ if (rc != 0) ++ return -ETIMEDOUT; ++ else ++ return -ECOMM; ++ } ++ } ++ ++ regval = readl(dev->base + CCB_SMB_MSTRCMD_REG); ++ ++ /* If start_busy bit cleared, check if there are any errors */ ++ if (!(regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK)) { ++ /* start_busy bit cleared, check master_status field now */ ++ regval &= CCB_SMB_MSTRSTS_MASK; ++ regval >>= CCB_SMB_MSTRSTS_SHIFT; ++ ++ if (regval != MSTR_STS_XACT_SUCCESS) { ++ /* We can flush Tx FIFO here */ ++ dev_err(dev->dev, "Send: Error in transaction\n"); ++ return -EREMOTEIO; ++ } ++ } ++ ++ return 0; ++} ++ ++static int iproc_smb_data_recv(struct i2c_adapter *adapter, ++ unsigned short addr, ++ struct iproc_xact_info *info, ++ unsigned int *num_bytes_read) ++{ ++ int rc; ++ unsigned int regval; ++ struct iproc_smb_drv_int_data *dev = i2c_get_adapdata(adapter); ++ unsigned long time_left; ++ ++ /* Make sure the previous transaction completed */ ++ rc = iproc_smb_startbusy_wait(dev); ++ ++ if (rc < 0) { ++ dev_err(dev->dev, "Receive: bus is busy, attempt recovery \n"); ++ /* attempt to recover the bus */ ++ if (iproc_smb_startbusy_recovery(dev) != 0) ++ return rc; ++ } ++ ++ if (dev->enable_evts == ENABLE_INTR) { ++ /* Enable start_busy interrupt */ ++ regval = readl(dev->base + CCB_SMB_EVTEN_REG); ++ ++ /* Set Rx_event_en bit for notification of reception event */ ++ regval |= (CCB_SMB_MSTRSTARTBUSYEN_MASK); ++ ++ writel(regval, dev->base + CCB_SMB_EVTEN_REG); ++ ++ /* Mark as incomplete before sending the data */ ++ reinit_completion(&dev->ses_done); ++ } ++ ++ /* Program all transaction bytes into master Tx FIFO */ ++ iproc_smb_write_trans_data(dev->base, addr, info); ++ ++ /* Program master command register (0x30) with protocol type and set ++ * start_busy_command bit to initiate the write transaction ++ */ ++ regval = (info->smb_proto << CCB_SMB_MSTRSMBUSPROTO_SHIFT) | ++ CCB_SMB_MSTRSTARTBUSYCMD_MASK | info->size; ++ writel(regval, dev->base + CCB_SMB_MSTRCMD_REG); ++ ++ if (dev->enable_evts == ENABLE_INTR) { ++ /* ++ * Block waiting for the transaction to finish. When finished, ++ * we'll be signaled by an interrupt ++ */ ++ time_left = wait_for_completion_timeout(&dev->ses_done, ++ XACT_TIMEOUT); ++ ++ /* Disable start_busy and rx_event interrupts */ ++ regval = readl(dev->base + CCB_SMB_EVTEN_REG); ++ regval &= ~(CCB_SMB_MSTRSTARTBUSYEN_MASK); ++ writel(regval, dev->base + CCB_SMB_EVTEN_REG); ++ ++ if (time_left == 0) { ++ dev_err(dev->dev, "Receive: timeout accessing device\n"); ++ /* attempt to recover the bus */ ++ rc = iproc_smb_timeout_recovery(dev); ++ if (rc != 0) ++ return -ETIMEDOUT; ++ else ++ return -ECOMM; ++ } ++ } ++ ++ regval = readl(dev->base + CCB_SMB_MSTRCMD_REG); ++ ++ /* If start_busy bit cleared, check if there are any errors */ ++ if (!(regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK)) { ++ /* start_busy bit cleared, check master_status field now */ ++ regval &= CCB_SMB_MSTRSTS_MASK; ++ regval >>= CCB_SMB_MSTRSTS_SHIFT; ++ ++ if (regval != MSTR_STS_XACT_SUCCESS) { ++ /* We can flush Tx FIFO here */ ++ dev_info(dev->dev, "Error in transaction\n"); ++ return -EREMOTEIO; ++ } ++ } ++ ++ /* In the isr we will read the received byte, and also deal with ++ * rx fifo full event. The above check is for timeout error. If needed ++ * we may move it to rx isr ++ */ ++ ++ /* For block read, protocol (hw) returns byte count, as the first byte */ ++ if ((info->smb_proto == SMBUS_PROT_BLK_RD) || ++ (info->smb_proto == SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL)) { ++ int i, adj; ++ ++ /* Read received byte(s) */ ++ regval = readl(dev->base + CCB_SMB_MSTRDATARD_REG); ++ *num_bytes_read = regval & CCB_SMB_MSTRRDDATA_MASK; ++ ++ adj = 0; ++ ++ /* SMBUS spec ver. 3 (2015) extends max block transfer byte count from 32 to 256 */ ++ /* Use SMB_MAX_DATA_SIZE (according to HW FIFO) instead of I2C_SMBUS_BLOCK_MAX (defined in Linux)*/ ++ /* ++ * Current SMBUS HW FIFO length is 64B. For block write xfer, ++ * the first three FIFO entries are for slave adress, register ofFset, ++ * and length count. ++ */ ++ for (i = 0; (i < *num_bytes_read) && (i < (SMB_MAX_DATA_SIZE - adj)); i++) { ++ /* Read Rx FIFO for data bytes */ ++ regval = readl(dev->base + CCB_SMB_MSTRDATARD_REG); ++ info->data[i + adj] = regval & CCB_SMB_MSTRRDDATA_MASK; ++ } ++ ++ *num_bytes_read = i + adj; ++ } ++ else { ++ regval = readl(dev->base + CCB_SMB_MSTRDATARD_REG); ++ *info->data = regval & CCB_SMB_MSTRRDDATA_MASK; ++ *num_bytes_read = 1; ++ if (info->smb_proto == SMBUS_PROT_RD_WORD) { ++ /* Read Rx FIFO for data bytes */ ++ regval = readl(dev->base + CCB_SMB_MSTRDATARD_REG); ++ info->data[1] = regval & CCB_SMB_MSTRRDDATA_MASK; ++ *num_bytes_read = 2; ++ } ++ } ++ ++ return 0; ++} ++ ++static int iproc_smb_xfer(struct i2c_adapter *i2c_adap, u16 addr, ++ unsigned short flags, char read_write, ++ u8 command, int size, union i2c_smbus_data *data) ++{ ++ int rc = 0; ++ struct iproc_smb_drv_int_data *dev = i2c_get_adapdata(i2c_adap); ++ struct iproc_xact_info info; ++ unsigned int num_bytes_read = 0; ++ int smb_xfer_size; ++ ++ down(&dev->xfer_lock); ++ ++ addr <<= 1; ++ ++ switch (size /* protocol */) { ++ case I2C_SMBUS_BYTE: ++ info.cmd_valid = false; ++ info.command = command; /* not used */ ++ if (read_write == I2C_SMBUS_WRITE) ++ info.data = &command; ++ else ++ info.data = &data->byte; ++ info.size = 1; ++ info.flags = flags; ++ if (read_write == I2C_SMBUS_READ) { ++ addr |= 0x1; /* Read operation */ ++ info.smb_proto = SMBUS_PROT_RECV_BYTE; ++ info.data = &data->byte; ++ } ++ else { ++ info.smb_proto = SMBUS_PROT_SEND_BYTE; ++ } ++ break; ++ ++ case I2C_SMBUS_BYTE_DATA: ++ info.cmd_valid = true; ++ info.command = command; ++ info.data = &data->byte; ++ info.size = 1; ++ info.flags = flags; ++ if (read_write == I2C_SMBUS_READ) ++ info.smb_proto = SMBUS_PROT_RD_BYTE; ++ else ++ info.smb_proto = SMBUS_PROT_WR_BYTE; ++ break; ++ ++ case I2C_SMBUS_WORD_DATA: ++ info.cmd_valid = true; ++ info.command = command; ++ info.data = (unsigned char *)(&data->word); ++ info.size = 2; ++ info.flags = flags; ++ if (read_write == I2C_SMBUS_READ) ++ info.smb_proto = SMBUS_PROT_RD_WORD; ++ else ++ info.smb_proto = SMBUS_PROT_WR_WORD; ++ break; ++ ++ case I2C_SMBUS_BLOCK_DATA: ++ case I2C_SMBUS_I2C_BLOCK_DATA: ++ info.cmd_valid = true; ++ info.command = command; ++ info.data = &data->block[1]; ++ info.flags = flags; ++ ++ if (read_write == I2C_SMBUS_READ) { ++ info.smb_proto = SMBUS_PROT_BLK_RD; ++ /* Refer to RD_BYTE_COUNT in reg 0x30 about 'block read' ++ * If '0', protocol(hw) returns data byte count as part of ++ * response. ++ */ ++ info.size = 0; ++ } ++ else { ++ info.smb_proto = SMBUS_PROT_BLK_WR; ++ /* i2c-core passes the length in this field */ ++ info.size = data->block[0]; ++ } ++ break; ++ ++ case I2C_SMBUS_BLOCK_PROC_CALL: ++ info.cmd_valid = true; ++ info.command = command; ++ info.data = &data->block[1]; ++ info.flags = flags; ++ info.size = data->block[0]; ++ info.smb_proto = SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL; ++ break; ++ ++ default: ++ dev_err(dev->dev, "Unsupported transaction\n"); ++ up(&dev->xfer_lock); ++ return -EINVAL; ++ } ++ ++ /* Handle large packet by spliting into SMB_MAX_DATA_SIZE packet */ ++ smb_xfer_size = (int)info.size; ++ if ((info.smb_proto == SMBUS_PROT_BLK_RD) || ++ (info.smb_proto == SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL)) ++ data->block[0] = 0; ++ ++ while (smb_xfer_size) { ++ if (info.size >= SMB_MAX_DATA_SIZE) ++ info.size = SMB_MAX_DATA_SIZE; ++ ++ if (read_write == I2C_SMBUS_READ) { ++ /* Refer to i2c_smbus_read_byte for params passed. */ ++ rc = iproc_smb_data_recv(i2c_adap, addr, &info, ++ &num_bytes_read); ++ /* if failed due to bus hang, but recovered, retry once */ ++ if (rc == -ECOMM) ++ rc = iproc_smb_data_recv(i2c_adap, addr, &info, ++ &num_bytes_read); ++ /* pass the actual amount of data sent by slave */ ++ if ((info.smb_proto == SMBUS_PROT_BLK_RD) || ++ (info.smb_proto == SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL)) ++ if (rc == 0) ++ data->block[0] += num_bytes_read; ++ } else { ++ /* Refer to i2c_smbus_write_byte params passed. */ ++ rc = iproc_smb_data_send(i2c_adap, addr, &info); ++ /* if failed due to bus hang, but recovered, retry */ ++ if (rc == -ECOMM) ++ rc = iproc_smb_data_send(i2c_adap, addr, &info); ++ } ++ ++ if (rc < 0) { ++ dev_info(dev->dev, "%s error accessing\n", ++ (read_write == I2C_SMBUS_READ) ? "Read" : "Write"); ++ up(&dev->xfer_lock); ++ return -EREMOTEIO; ++ } ++ if (info.size == SMB_MAX_DATA_SIZE) { ++ smb_xfer_size -= SMB_MAX_DATA_SIZE; ++ info.size = smb_xfer_size; ++ info.data += SMB_MAX_DATA_SIZE; ++ /* Adjust I2c device register offset */ ++ info.command += SMB_MAX_DATA_SIZE; ++ } else { ++ break; ++ } ++ } ++ ++ msleep(1); ++ up(&dev->xfer_lock); ++ ++ return (rc); ++} ++ ++static int iproc_intr_enable(struct iproc_smb_drv_int_data *dev, u32 bmap) ++{ ++ void __iomem *base_addr = dev->base; ++ unsigned int regval; ++ ++ regval = readl(base_addr + CCB_SMB_EVTEN_REG); ++ regval |= bmap; ++ writel(regval, base_addr + CCB_SMB_EVTEN_REG); ++ ++ /* ++ * Store all interrupts enabled so far. Note bmap can have only ++ * 'incremental' set of events ++ */ ++ dev->evt_enable_bmap = regval; ++ ++ return 0; ++} ++ ++static int iproc_intr_disable(struct iproc_smb_drv_int_data *dev, u32 bmap) ++{ ++ void __iomem *base_addr = dev->base; ++ unsigned int regval; ++ ++ regval = readl(base_addr + CCB_SMB_EVTEN_REG); ++ regval &= ~bmap; ++ writel(regval, base_addr + CCB_SMB_EVTEN_REG); ++ ++ dev->evt_enable_bmap = regval; ++ ++ return 0; ++} ++ ++/* Verify this sequence with hw engg */ ++static int iproc_smbus_block_deinit(struct iproc_smb_drv_int_data *dev) ++{ ++ unsigned int regval; ++ int rc; ++ ++ /* Disable all interrupts */ ++ regval = 0x0; ++ ++ writel(regval, dev->base + CCB_SMB_EVTEN_REG); ++ ++ /* Check if a transaction is in progress */ ++ rc = iproc_smb_startbusy_wait(dev); ++ if (rc < 0) { ++ dev_err(dev->dev, "A transaction is still in progress"); ++ /* Wait for some time */ ++ udelay(100); ++ } ++ ++ /* Disable SMBus block */ ++ regval = readl(dev->base + CCB_SMB_CFG_REG); ++ regval &= ~CCB_SMB_CFG_SMBEN_MASK; ++ writel(regval, dev->base + CCB_SMB_CFG_REG); ++ ++ /* Wait for some time */ ++ udelay(100); ++ ++ /* Put the block under reset. Note the RESET bit in reg 0x0 is ++ * self clearing ++ */ ++ regval = CCB_SMB_CFG_RST_MASK; ++ writel(regval, dev->base + CCB_SMB_CFG_REG); ++ ++ return 0; ++} ++ ++static u32 iproc_smb_funcs(struct i2c_adapter *adapter) ++{ ++ /* I2C_FUNC_SMBUS_I2C_BLOCK */ ++ return (I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | ++ I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA); ++} ++ ++static struct i2c_algorithm iproc_smb_algorithm = { ++ /*.name = "iproc-smb", */ ++ .smbus_xfer = iproc_smb_xfer, ++ .master_xfer = NULL, ++ .functionality = iproc_smb_funcs, ++}; ++ ++static int iproc_smb_probe(struct platform_device *pdev) ++{ ++ int rc=0, irq; ++ struct iproc_smb_drv_int_data *dev; ++ struct i2c_adapter *adap; ++ struct resource *res; ++ ++ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); ++ if (!dev) ++ return -ENOMEM; ++ ++ dev->dev = &pdev->dev; ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ dev->base = devm_ioremap_resource(dev->dev, res); ++ if (IS_ERR(dev->base)) ++ return PTR_ERR(dev->base); ++ ++ /* Get the interrupt number */ ++ irq = platform_get_irq(pdev, 0); ++ if (irq <= 0) { ++ dev_err(dev->dev, "no irq resource\n"); ++ return irq; ++ } ++ ++ init_MUTEX(&dev->xfer_lock); ++ init_completion(&dev->ses_done); ++ dev->irq = irq; ++ ++ /* Default value, can be changed after initial testing */ ++ dev->enable_evts = ENABLE_INTR; ++ ++ platform_set_drvdata(pdev, dev); ++ ++ /* ++ * Init internal regs, disable intrs (and then clear intrs), set fifo ++ * thresholds, etc. ++ */ ++ iproc_smbus_block_init(dev); ++ ++ /* Register ISR handler */ ++ rc = devm_request_irq(dev->dev, dev->irq, iproc_smb_isr, 0, ++ pdev->name, dev); ++ if (rc) { ++ dev_err(dev->dev, "unable to request irq %i\n", irq); ++ goto err_smb_deinit; ++ } ++ ++ adap = &dev->adapter; ++ i2c_set_adapdata(adap, dev); ++ adap->owner = THIS_MODULE; ++ adap->class = UINT_MAX; ++ adap->algo = &iproc_smb_algorithm; ++ adap->dev.parent = &pdev->dev; ++ adap->nr = pdev->id; ++ adap->dev.of_node = pdev->dev.of_node; ++ strlcpy(adap->name, "iproc-smbus", sizeof(adap->name)); ++ ++ rc = i2c_add_numbered_adapter(adap); ++ if (rc) ++ goto err_free_irq; ++ ++ /* Turn on default set of interrupts */ ++ /* ++ * For Rx, enable RX fifo full, threshold hit interrupts. Other rx ++ * interrupts will be set in the read/recv transactions, as required ++ * For Tx, enable fifo under run intr. Other intrs will be set in send ++ * write access functions ++ */ ++ iproc_intr_enable(dev, CCB_SMB_MSTRRXFIFOFULLEN_MASK); ++ ++ return 0; ++ ++err_free_irq: ++ free_irq(dev->irq, dev); ++ ++err_smb_deinit: ++ iproc_smbus_block_deinit(dev); ++ platform_set_drvdata(pdev, NULL); ++ ++ dev_err(dev->dev, "probe failed, error=%d", rc); ++ return (rc); ++} ++ ++static int iproc_smb_remove(struct platform_device *pdev) ++{ ++ struct iproc_smb_drv_int_data *dev = platform_get_drvdata(pdev); ++ unsigned int regval; ++ ++ /* Disable interrupts. */ ++ /* Verify: Should we wait for any in-progress xact to complete? */ ++ synchronize_irq(dev->irq); ++ iproc_intr_disable(dev, ~0); ++ free_irq(dev->irq, dev); ++ ++ /* Disable SMbus block */ ++ regval = readl(dev->base + CCB_SMB_CFG_REG); ++ regval &= ~CCB_SMB_CFG_SMBEN_MASK; ++ writel(regval, dev->base + CCB_SMB_CFG_REG); ++ ++ i2c_del_adapter(&dev->adapter); ++ ++ platform_set_drvdata(pdev, NULL); ++ ++ iproc_smbus_block_deinit(dev); ++ ++ devm_iounmap(&pdev->dev, dev->base); ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm_iproc_smb_of_match[] = { ++ { .compatible = "brcm,iproc-i2c" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, bcm_iproc_smb_of_match); ++ ++static struct platform_driver bcm_iproc_smbus_driver = { ++ .driver = { ++ .name = "bcm-iproc-smbus", ++ .of_match_table = bcm_iproc_smb_of_match, ++ }, ++ .probe = iproc_smb_probe, ++ .remove = iproc_smb_remove, ++}; ++module_platform_driver(bcm_iproc_smbus_driver); ++ ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_DESCRIPTION("IPROC SMBus Bus Driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig +--- a/drivers/mmc/host/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/mmc/host/Kconfig 2018-05-10 11:31:31.593401757 +0800 +@@ -892,6 +892,16 @@ config MMC_SDHCI_BRCMSTB + + If unsure, say Y. + ++config MMC_SDHCI_XGS_IPROC ++ tristate "Broadcom XGS iProc SD/MMC Card Interface support" ++ depends on ARCH_XGS_IPROC ++ depends on MMC_SDHCI_PLTFM ++ select MMC_SDHCI_IO_ACCESSORS ++ default n ++ help ++ This selects the platform Secure Digital Host Controller Interface. ++ If unsure, say N. ++ + config MMC_SDHCI_XENON + tristate "Marvell Xenon eMMC/SD/SDIO SDHCI driver" + depends on MMC_SDHCI_PLTFM +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile +--- a/drivers/mmc/host/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/mmc/host/Makefile 2018-05-10 11:31:31.593401757 +0800 +@@ -90,6 +90,7 @@ obj-$(CONFIG_MMC_SDHCI_MSM) += sdhci-ms + obj-$(CONFIG_MMC_SDHCI_ST) += sdhci-st.o + obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32) += sdhci-pic32.o + obj-$(CONFIG_MMC_SDHCI_BRCMSTB) += sdhci-brcmstb.o ++obj-$(CONFIG_MMC_SDHCI_XGS_IPROC) += sdhci-bcm-hr3.o + + ifeq ($(CONFIG_CB710_DEBUG),y) + CFLAGS-cb710-mmc += -DDEBUG +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/mmc/host/sdhci-bcm-hr3.c b/drivers/mmc/host/sdhci-bcm-hr3.c +--- a/drivers/mmc/host/sdhci-bcm-hr3.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/mmc/host/sdhci-bcm-hr3.c 2018-05-10 11:31:31.609401775 +0800 +@@ -0,0 +1,458 @@ ++/* ++ * drivers/mmc/host/sdhci-bcm-hr3 - Broadcom HR3 SDHCI Platform driver ++ * ++ * Copyright (C) 2014-2016, Broadcom Corporation. All Rights Reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 and ++ * only version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "sdhci-pltfm.h" ++ ++struct xgs_iproc_sdhci_host { ++ struct device_node *dn; ++ void __iomem *wrap_base; ++ void __iomem *idm_base; ++ u32 shadow_cmd; ++ u32 shadow_blk; ++}; ++ ++static int iproc_top_sdio_config(void); ++ ++static void iproc_sdhci_writel(struct sdhci_host *host, u32 val, int reg) ++{ ++ /* WAR for SDIO/GPIO setting might be reset by SDK for HR3. */ ++ struct xgs_iproc_sdhci_host *iproc_host = ++ sdhci_pltfm_priv(sdhci_priv(host)); ++ if (of_device_is_compatible(iproc_host->dn, "brcm,iproc-hr3-sdio")) { ++ if (reg == SDHCI_INT_STATUS) { ++ iproc_top_sdio_config(); ++ } ++ } ++ ++ writel(val, host->ioaddr + reg); ++} ++ ++static inline u32 iproc_sdhci_readl(struct sdhci_host *host, int reg) ++{ ++ return readl(host->ioaddr + reg); ++} ++ ++static void iproc_sdhci_writew(struct sdhci_host *host, u16 val, int reg) ++{ ++ struct xgs_iproc_sdhci_host *iproc_host = ++ sdhci_pltfm_priv(sdhci_priv(host)); ++ u32 oldval, newval; ++ u32 word_num = (reg >> 1) & 1; ++ u32 word_shift = word_num * 16; ++ u32 mask = 0xffff << word_shift; ++ ++ if (reg == SDHCI_COMMAND) { ++ if (iproc_host->shadow_blk != 0) { ++ iproc_sdhci_writel(host, iproc_host->shadow_blk, SDHCI_BLOCK_SIZE); ++ iproc_host->shadow_blk = 0; ++ } ++ oldval = iproc_host->shadow_cmd; ++ } else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) { ++ oldval = iproc_host->shadow_blk; ++ } else { ++ oldval = iproc_sdhci_readl(host, reg & ~3); ++ } ++ newval = (oldval & ~mask) | (val << word_shift); ++ ++ if (reg == SDHCI_TRANSFER_MODE) ++ /* Save the transfer mode until the command is issued */ ++ iproc_host->shadow_cmd = newval; ++ else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) ++ /* Save the block info until the command is issued */ ++ iproc_host->shadow_blk = newval; ++ else ++ /* Command or other regular 32-bit write */ ++ iproc_sdhci_writel(host, newval, reg & ~3); ++} ++ ++static u16 iproc_sdhci_readw(struct sdhci_host *host, int reg) ++{ ++ u32 val, word; ++ u32 word_num = (reg >> 1) & 1; ++ u32 word_shift = word_num * 16; ++ ++ val = iproc_sdhci_readl(host, (reg & ~3)); ++ word = (val >> word_shift) & 0xffff; ++ ++ return word; ++} ++ ++static void iproc_sdhci_writeb(struct sdhci_host *host, u8 val, int reg) ++{ ++ u32 oldval, newval; ++ u32 byte_num = reg & 3; ++ u32 byte_shift = byte_num * 8; ++ u32 mask = 0xff << byte_shift; ++ ++ oldval = iproc_sdhci_readl(host, reg & ~3); ++ newval = (oldval & ~mask) | (val << byte_shift); ++ ++ iproc_sdhci_writel(host, newval, reg & ~3); ++} ++ ++static u8 iproc_sdhci_readb(struct sdhci_host *host, int reg) ++{ ++ u32 val, byte; ++ u32 byte_num = reg & 3; ++ u32 byte_shift = byte_num * 8; ++ ++ val = iproc_sdhci_readl(host, (reg & ~3)); ++ byte = (val >> byte_shift) & 0xff; ++ ++ return byte; ++} ++ ++static u32 iproc_sdhci_get_max_clock(struct sdhci_host *host) ++{ ++ unsigned long max_clock; ++ ++ max_clock = (host->caps & SDHCI_CLOCK_V3_BASE_MASK) ++ >> SDHCI_CLOCK_BASE_SHIFT; ++ max_clock *= 1000000; ++ ++ return max_clock; ++} ++ ++static u32 iproc_sdhci_get_min_clock(struct sdhci_host *host) ++{ ++ return (host->max_clk / SDHCI_MAX_DIV_SPEC_300); ++} ++ ++static int iproc_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode) ++{ ++ /* ++ * Tuning is unnecessary for SDR50 and DDR50; moreover, the IPROC platform ++ * doesn't support SDR104, HS200 and HS400 cards. So, we needn't do anything ++ * for tuning. ++ */ ++ return 0; ++} ++ ++static void iproc_sdhci_set_clock(struct sdhci_host *host, unsigned int clock) ++{ ++ /* ++ * WAR that IPROC SD/MMC host need to set the driver strength ++ * to TYPE_A in 3.3v DS/HS mode even if the driver strength is ++ * meaningless for 3.3V signaling. ++ */ ++ if ((host->timing == MMC_TIMING_LEGACY) || ++ (host->timing == MMC_TIMING_MMC_HS) || ++ (host->timing == MMC_TIMING_SD_HS)) ++ host->mmc->ios.drv_type = MMC_SET_DRIVER_TYPE_A; ++ ++ sdhci_set_clock(host, clock); ++} ++ ++static struct sdhci_ops sdhci_iproc_ops = { ++#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS ++ .write_l = iproc_sdhci_writel, ++ .write_w = iproc_sdhci_writew, ++ .write_b = iproc_sdhci_writeb, ++ .read_l = iproc_sdhci_readl, ++ .read_w = iproc_sdhci_readw, ++ .read_b = iproc_sdhci_readb, ++#else ++#error The iproc SDHCI driver needs CONFIG_MMC_SDHCI_IO_ACCESSORS to be set ++#endif ++ .reset = sdhci_reset, ++ .set_bus_width = sdhci_set_bus_width, ++ .set_uhs_signaling = sdhci_set_uhs_signaling, ++ .set_clock = iproc_sdhci_set_clock, ++ .get_max_clock = iproc_sdhci_get_max_clock, ++ .get_min_clock = iproc_sdhci_get_min_clock, ++ .platform_execute_tuning = iproc_sdhci_execute_tuning, ++}; ++ ++/* TOP registers */ ++#define TOP_SDIO_MISC_CONTROL 0x0207e500 ++#define TOP_SDIO_MISC_CONTROL__TOP_SDIO_8B_INF 4 ++#define TOP_SDIO_MISC_CONTROL__TOP_SDIO_GPIO_INF_SEL_R 0 ++ ++/* SDIO IDM registers */ ++#define SDIO_IDM0_IO_CONTROL_DIRECT(base) (base + 0x0) ++#define SDIO_IDM0_IO_CONTROL_DIRECT__CMD_COMFLICT_DISABLE 22 ++#define SDIO_IDM0_IO_CONTROL_DIRECT__FEEDBACK_CLK_EN 21 ++#define SDIO_IDM0_IO_CONTROL_DIRECT__clk_enable 0 ++#define SDIO_IDM0_IDM_RESET_CONTROL(base) (base + 0x3F8) ++ ++/* IPROC WRAP registers */ ++#define IPROC_WRAP_SDIO_CONTROL(base) (base + 0xb0) ++#define IPROC_WRAP_SDIO_CONTROL1(base) (base + 0xb4) ++#define IPROC_WRAP_SDIO_CONTROL2(base) (base + 0xb8) ++#define IPROC_WRAP_SDIO_CONTROL3(base) (base + 0xbc) ++#define IPROC_WRAP_SDIO_CONTROL4(base) (base + 0xc0) ++#define IPROC_WRAP_SDIO_CONTROL5(base) (base + 0xc4) ++#define IPROC_WRAP_SDIO_1P8_FAIL_CONTROL(base) (base + 0xc8) ++#define IPROC_WRAP_SDIO_1P8_FAIL_CONTROL__SDIO_VDDO_18V_FAIL_SOVW 1 ++#define IPROC_WRAP_SDIO_1P8_FAIL_CONTROL__SDIO_UHS1_18V_VREG_FAIL 0 ++ ++/* ++ * SDIO_CAPS_L ++ * ++ * Field Bit(s) ++ * =========================== ++ * DDR50 31 ++ * SDR104 30 ++ * SDR50 29 ++ * SLOTTYPE 28:27 ++ * ASYNCHIRQ 26 ++ * SYSBUS64 25 ++ * V18 24 ++ * V3 23 ++ * V33 22 ++ * SUPRSM 21 ++ * SDMA 20 ++ * HSPEED 19 ++ * ADMA2 18 ++ * EXTBUSMED 17 ++ * MAXBLK 16:15 ++ * BCLK 14:7 ++ * TOUT 6 ++ * TOUTFREQ 5:0 ++ */ ++#define SDIO_CAPS_L 0xA17f6470 ++ ++/* ++ * SDIO_CAPS_H ++ * ++ * Field Bit(s) ++ * =========================== ++ * reserved 31:20 ++ * SPIBLOCKMODE 19 ++ * SPIMODE_CAP 18 ++ * CLOCKMULT 17:10 ++ * RETUNE_MODE 9:8 ++ * USETUNE_SDR50 7 ++ * TMRCNT_RETUNE 6:3 ++ * DRVR_TYPED 2 ++ * DRVR_TYPEC 1 ++ * DRVR_TYPEA 0 ++ */ ++#define SDIO_CAPS_H 0x000C000f ++ ++/* ++ * Preset value ++ * ++ * Field Bit(s) ++ * =========================== ++ * Driver Strength 12:11 ++ * Clock Generator 10 ++ * SDCLK Frequeency 9:0 ++ */ ++ ++/* ++ * SDIO_PRESETVAL1 ++ * ++ * Field Bit(s) Description ++ * ============================================================ ++ * DDR50_PRESET 25:13 Preset Value for DDR50 ++ * DEFAULT_PRESET 12:0 Preset Value for Default Speed ++ */ ++#define SDIO_PRESETVAL1 0x01004004 ++ ++/* ++ * SDIO_PRESETVAL2 ++ * ++ * Field Bit(s) Description ++ * ============================================================ ++ * HIGH_SPEED_PRESET 25:13 Preset Value for High Speed ++ * INIT_PRESET 12:0 Preset Value for Initialization ++ */ ++#define SDIO_PRESETVAL2 0x01004100 ++ ++/* ++ * SDIO_PRESETVAL3 ++ * ++ * Field Bit(s) Description ++ * ============================================================ ++ * SDR104_PRESET 25:13 Preset Value for SDR104 ++ * SDR12_PRESET 12:0 Preset Value for SDR12 ++ */ ++#define SDIO_PRESETVAL3 0x00000004 ++ ++/* ++ * SDIO_PRESETVAL4 ++ * ++ * Field Bit(s) Description ++ * ============================================================ ++ * SDR25_PRESET 25:13 Preset Value for SDR25 ++ * SDR50_PRESET 12:0 Preset Value for SDR50 ++ */ ++#define SDIO_PRESETVAL4 0x01005001 ++ ++static int iproc_top_sdio_config(void) ++{ ++ u32 val; ++ ++ val = iproc_cmic_schan_reg32_read(CMIC_BLOCK_TYPE_TOP, TOP_SDIO_MISC_CONTROL); ++ if ((val & 0x1f) != 0x1f) { ++ val |= (0x1 << TOP_SDIO_MISC_CONTROL__TOP_SDIO_8B_INF); ++ val |= (0xf << TOP_SDIO_MISC_CONTROL__TOP_SDIO_GPIO_INF_SEL_R); ++ iproc_cmic_schan_reg32_write(CMIC_BLOCK_TYPE_TOP, TOP_SDIO_MISC_CONTROL, val); ++ } ++ ++ return 0; ++} ++ ++static int iproc_sdio_init(struct xgs_iproc_sdhci_host *iproc_host) ++{ ++ int ret = 0; ++ u32 val; ++ ++ /* Enable SDIO for SDIO/GPIO selection */ ++ ret = iproc_top_sdio_config(); ++ if (ret < 0) ++ return ret; ++ ++ /* Release reset */ ++ writel(0x1, SDIO_IDM0_IDM_RESET_CONTROL(iproc_host->idm_base)); ++ udelay(1000); ++ writel(0x0, SDIO_IDM0_IDM_RESET_CONTROL(iproc_host->idm_base)); ++ ++ /* Enable the SDIO clock */ ++ val = readl(SDIO_IDM0_IO_CONTROL_DIRECT(iproc_host->idm_base)); ++ val |= (1 << SDIO_IDM0_IO_CONTROL_DIRECT__CMD_COMFLICT_DISABLE); ++ val |= (1 << SDIO_IDM0_IO_CONTROL_DIRECT__FEEDBACK_CLK_EN); ++ val |= (1 << SDIO_IDM0_IO_CONTROL_DIRECT__clk_enable); ++ writel(val, SDIO_IDM0_IO_CONTROL_DIRECT(iproc_host->idm_base)); ++ ++ /* Set the 1.8v fail control for HR3. ++ * This setting will not impact the uboot SD/MMC driver, since uboot doesn't ++ * support 1.8v. The 1.8v SDIO will be supportted in Kernel. ++ */ ++ val = readl(IPROC_WRAP_SDIO_1P8_FAIL_CONTROL(iproc_host->wrap_base)); ++ val |= (1 << IPROC_WRAP_SDIO_1P8_FAIL_CONTROL__SDIO_VDDO_18V_FAIL_SOVW); ++ val &= ~(1 << IPROC_WRAP_SDIO_1P8_FAIL_CONTROL__SDIO_UHS1_18V_VREG_FAIL); ++ writel(val, IPROC_WRAP_SDIO_1P8_FAIL_CONTROL(iproc_host->wrap_base)); ++ ++ /* ++ * Configure SDIO host controller capabilities ++ * (common setting for all SDIO controllers) ++ */ ++ writel(SDIO_CAPS_H, IPROC_WRAP_SDIO_CONTROL(iproc_host->wrap_base)); ++ writel(SDIO_CAPS_L, IPROC_WRAP_SDIO_CONTROL1(iproc_host->wrap_base)); ++ ++ /* ++ * Configure SDIO host controller preset values ++ * (common setting for all SDIO controllers) ++ */ ++ writel(SDIO_PRESETVAL1, IPROC_WRAP_SDIO_CONTROL2(iproc_host->wrap_base)); ++ writel(SDIO_PRESETVAL2, IPROC_WRAP_SDIO_CONTROL3(iproc_host->wrap_base)); ++ writel(SDIO_PRESETVAL3, IPROC_WRAP_SDIO_CONTROL4(iproc_host->wrap_base)); ++ writel(SDIO_PRESETVAL4, IPROC_WRAP_SDIO_CONTROL5(iproc_host->wrap_base)); ++ ++ return 0; ++} ++ ++static const struct sdhci_pltfm_data sdhci_iproc_pltfm_data = { ++ .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | ++ SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, ++ /*.quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN,*/ ++ .ops = &sdhci_iproc_ops, ++}; ++ ++static const struct of_device_id sdhci_xgs_iproc_of_match[] = { ++ { .compatible = "brcm,iproc-hr3-sdio", .data = &sdhci_iproc_pltfm_data }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, sdhci_xgs_iproc_of_match); ++ ++static int sdhci_xgs_iproc_probe(struct platform_device *pdev) ++{ ++ const struct of_device_id *match; ++ struct xgs_iproc_sdhci_host *iproc_host; ++ struct sdhci_host *host; ++ const struct sdhci_pltfm_data *pltfm_data; ++ struct sdhci_pltfm_host *pltfm_host; ++ struct resource *res; ++ int ret = 0; ++ ++ match = of_match_device(sdhci_xgs_iproc_of_match, &pdev->dev); ++ if (!match) ++ return -EINVAL; ++ ++ pltfm_data = match->data; ++ host = sdhci_pltfm_init(pdev, pltfm_data, sizeof(*iproc_host)); ++ if (IS_ERR(host)) ++ return PTR_ERR(host); ++ ++ pltfm_host = sdhci_priv(host); ++ iproc_host = sdhci_pltfm_priv(pltfm_host); ++ ++ iproc_host->dn = pdev->dev.of_node; ++ ++ mmc_of_parse(host->mmc); ++ sdhci_get_of_property(pdev); ++ ++ host->hw_name = "XGS-IPROC-SDIO"; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ iproc_host->idm_base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(iproc_host->idm_base)) { ++ dev_err(&pdev->dev, "SDIO IDM base ioremap fail\n"); ++ ret = PTR_ERR(iproc_host->idm_base); ++ goto err1; ++ } ++ ++ iproc_host->wrap_base = get_iproc_wrap_ctrl_base(); ++ if (!iproc_host->wrap_base) { ++ dev_err(&pdev->dev, "SDIO wrap ctrl base ioremap fail\n"); ++ ret = -ENXIO; ++ goto err1; ++ } ++ ++ ret = iproc_sdio_init(iproc_host); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "SDIO%d init failed\n", pdev->id); ++ ret = -ENXIO; ++ goto err1; ++ } ++ ++ ret = sdhci_add_host(host); ++ if (ret) { ++ dev_err(&pdev->dev, "SDIO add host fail\n"); ++ goto err1; ++ } ++ ++err1: ++ sdhci_pltfm_free(pdev); ++ return ret; ++} ++ ++static struct platform_driver sdhci_xgs_iproc_driver = { ++ .probe = sdhci_xgs_iproc_probe, ++ .remove = sdhci_pltfm_unregister, ++ .driver = { ++ .name = "iproc-hr3-sdio", ++ .pm = &sdhci_pltfm_pmops, ++ .of_match_table = sdhci_xgs_iproc_of_match, ++ }, ++}; ++ ++module_platform_driver(sdhci_xgs_iproc_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("SDHCI XGS HR3 driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig +--- a/drivers/mtd/maps/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/mtd/maps/Kconfig 2018-05-10 11:31:31.625401792 +0800 +@@ -419,4 +419,13 @@ config MTD_LATCH_ADDR + + If compiled as a module, it will be called latch-addr-flash. + ++config MTD_NOR_XGS_IPROC ++ bool "Broadcom XGS iProc CFI NOR support" ++ depends on (ARCH_XGS_IPROC || COMPILE_TEST) && MTD_CFI ++ default n ++ help ++ This selects a driver for the iProc NOR support. ++ ++ If unsure, say N. ++ + endmenu +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile +--- a/drivers/mtd/maps/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/mtd/maps/Makefile 2018-05-10 11:31:31.625401792 +0800 +@@ -48,3 +48,4 @@ obj-$(CONFIG_MTD_VMU) += vmu-flash.o + obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o + obj-$(CONFIG_MTD_LATCH_ADDR) += latch-addr-flash.o + obj-$(CONFIG_MTD_LANTIQ) += lantiq-flash.o ++obj-$(CONFIG_MTD_NOR_XGS_IPROC) += xgs-iproc-flash.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/mtd/maps/xgs-iproc-flash.c b/drivers/mtd/maps/xgs-iproc-flash.c +--- a/drivers/mtd/maps/xgs-iproc-flash.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/mtd/maps/xgs-iproc-flash.c 2018-05-10 11:31:31.629401796 +0800 +@@ -0,0 +1,184 @@ ++/* ++ * Copyright 2017 Broadcom Limited ++ * ++ * 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. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern void __iomem *get_iproc_dmu_pcu_base(void); ++ ++#define PNOR_DIRECT_CMD_OFFSET 0x10 ++#define PNOR_SET_OPMODE_OFFSET 0X18 ++ ++#define IPROC_STRAP_BOOT_DEV_NAND 1 ++#define IPROC_STRAP_BOOT_DEV_PNOR 4 ++#define ICFG_PNOR_STRAPS__PNOR_SRAM_MW_R 0 ++#define PNOR_set_opmode__set_mw_R 0 ++#define PNOR_direct_cmd__cmd_type_R 21 ++#define IPROC_DMU_STRAPS_OFFSET 0x28 ++#define IPROC_BOOT_STRAP_MASK 0x7 ++ ++struct iproc_nor_mtd { ++ void __iomem *reg_base; ++ void __iomem *reg_strap; ++ struct map_info map; ++ struct mtd_info *mtd; ++}; ++ ++static int xgs_iproc_nor_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ struct device *dev = &pdev->dev; ++ struct iproc_nor_mtd *iproc_data = NULL; ++ struct resource *res; ++ u32 straps, val; ++ u32 strap_boot_dev_shift; ++ void __iomem *reg_base; ++ ++ dev_info(dev, "XGS iProc pnor interface driver\n"); ++ ++ iproc_data = devm_kzalloc(dev, sizeof(*iproc_data), GFP_KERNEL); ++ if (!iproc_data) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, iproc_data); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ iproc_data->reg_base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(iproc_data->reg_base)) { ++ dev_err(dev, "can't ioremap pnor base addr\n"); ++ return PTR_ERR(iproc_data->reg_base); ++ } ++ ++ /* Check boot device */ ++ if (of_machine_is_compatible("brcm,hurricane2") || ++ of_machine_is_compatible("brcm,greyhound")) ++ strap_boot_dev_shift = 9; ++ else ++ strap_boot_dev_shift = 10; ++ ++ straps = readl(get_iproc_dmu_pcu_base() + IPROC_DMU_STRAPS_OFFSET); ++ straps = (straps >> strap_boot_dev_shift) & IPROC_BOOT_STRAP_MASK; ++ ++ if (straps == IPROC_STRAP_BOOT_DEV_NAND) { ++ /* If booting from NAND, PNOR cannot be used */ ++ return -ENODEV; ++ } else if (straps != IPROC_STRAP_BOOT_DEV_PNOR) { ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); ++ iproc_data->reg_strap = devm_ioremap_resource(dev, res); ++ ++ if (!IS_ERR(iproc_data->reg_strap)) { ++ /* Configure controller memory width based on strap */ ++ reg_base = iproc_data->reg_base; ++ straps = readl(iproc_data->reg_strap) & ++ (1 << ICFG_PNOR_STRAPS__PNOR_SRAM_MW_R); ++ ++ if (straps) { ++ /* 16-bit */ ++ val = readl(reg_base + PNOR_SET_OPMODE_OFFSET); ++ val |= (1 << PNOR_set_opmode__set_mw_R); ++ writel(val, reg_base + PNOR_SET_OPMODE_OFFSET); ++ } else { ++ /* 8-bit */ ++ val = readl(reg_base + PNOR_SET_OPMODE_OFFSET); ++ val &= ~(1 << PNOR_set_opmode__set_mw_R); ++ writel(val, reg_base + PNOR_SET_OPMODE_OFFSET); ++ } ++ ++ val = readl(reg_base + PNOR_DIRECT_CMD_OFFSET); ++ val |= (2 << PNOR_direct_cmd__cmd_type_R); ++ writel(val, reg_base + PNOR_DIRECT_CMD_OFFSET); ++ } ++ } ++ ++ mdelay(1); ++ ++ iproc_data->map.bankwidth = 2; ++ iproc_data->map.name = "XGS-IPROC-PNOR-FLASH"; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ iproc_data->map.phys = res->start; ++ iproc_data->map.size = resource_size(res); ++ iproc_data->map.virt = devm_ioremap_resource(dev, res); ++ ++ if (IS_ERR(iproc_data->map.virt)) { ++ dev_err(dev, "can't ioremap pnor flash addr space\n"); ++ return PTR_ERR(iproc_data->map.virt); ++ } ++ ++ simple_map_init(&iproc_data->map); ++ ++ dev_info(dev, "MTD probing 16 bit PNOR FLASH\n"); ++ iproc_data->mtd = do_map_probe("cfi_probe", &iproc_data->map); ++ if (!iproc_data->mtd) { ++ /* Probe for bankwidth 1 */ ++ dev_info(dev, "MTD probing 8 bit PNOR FLASH\n"); ++ iproc_data->map.bankwidth = 1; ++ iproc_data->mtd = do_map_probe("cfi_probe", &iproc_data->map); ++ } ++ ++ if (iproc_data->mtd) { ++ iproc_data->mtd->owner = THIS_MODULE; ++ iproc_data->mtd->dev.parent = dev; ++ mtd_set_of_node(iproc_data->mtd, np); ++ mtd_device_parse_register(iproc_data->mtd, NULL, NULL, NULL, 0); ++ dev_info(dev, "PNOR MTD partitions parsed!\n"); ++ return 0; ++ } ++ ++ dev_warn(dev, "NO PNOR FLASH found!\n"); ++ ++ return -ENXIO; ++} ++ ++static int xgs_iproc_nor_remove(struct platform_device *pdev) ++{ ++ struct iproc_nor_mtd *iproc_data = platform_get_drvdata(pdev); ++ ++ if (!iproc_data) ++ return 0; ++ ++ if (iproc_data->mtd) { ++ mtd_device_unregister(iproc_data->mtd); ++ map_destroy(iproc_data->mtd); ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id xgs_iproc_nor_dt_ids[] = { ++ { .compatible = "brcm,iproc-nor", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, xgs_iproc_nor_dt_ids); ++ ++static struct platform_driver xgs_iproc_nor_driver = ++{ ++ .driver = { ++ .name = "xgs-iproc-nor", ++ .owner = THIS_MODULE, ++ .of_match_table = xgs_iproc_nor_dt_ids, ++ }, ++ .probe = xgs_iproc_nor_probe, ++ .remove = xgs_iproc_nor_remove, ++}; ++ ++module_platform_driver(xgs_iproc_nor_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("MTD map driver for XGS iProc PNOR controller"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c +--- a/drivers/mtd/nand/brcmnand/brcmnand.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/mtd/nand/brcmnand/brcmnand.c 2018-05-30 15:50:51.028753148 +0800 +@@ -1220,6 +1220,8 @@ static void brcmnand_send_cmd(struct brc + ctrl->cmd_pending = cmd; + + ret = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0); ++ /* mark out this warning for XGS iProc */ ++ if (!IS_ENABLED(CONFIG_ARCH_XGS_IPROC)) + WARN_ON(ret); + + mb(); /* flush previous writes */ +@@ -1698,7 +1700,9 @@ static int brcmstb_nand_verify_erased_pa + ret = nand_check_erased_ecc_chunk(buf, chip->ecc.size, + oob, sas, NULL, 0, + chip->ecc.strength); ++ buf += chip->ecc.size; ++ + if (ret < 0) + return ret; + + +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig +--- a/drivers/net/ethernet/broadcom/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/Kconfig 2018-05-10 11:31:31.725401901 +0800 +@@ -171,16 +171,26 @@ config BGMAC_BCMA + config BGMAC_PLATFORM + tristate "Broadcom iProc GBit platform support" + depends on HAS_DMA +- depends on ARCH_BCM_IPROC || COMPILE_TEST ++ depends on ARCH_BCM_IPROC || ARCH_XGS_IPROC || COMPILE_TEST + depends on OF + select BGMAC + select PHYLIB + select FIXED_PHY +- default ARCH_BCM_IPROC ++ default ARCH_BCM_IPROC || ARCH_XGS_IPROC + ---help--- + Say Y here if you want to use the Broadcom iProc Gigabit Ethernet + controller through the generic platform interface + ++config APM ++ tristate "Broadcom iProc AXI Port Macro (APM) support" ++ depends on HAS_DMA ++ depends on ARCH_XGS_IPROC || COMPILE_TEST ++ depends on OF ++ ---help--- ++ This driver supports AXI Port Macro (APM) module. ++ The APM provides a bridge function between a standard Port Macro (PM 4X10) ++ interface and the AXI interconnect (128 bits data bus) for data transfer. ++ + config SYSTEMPORT + tristate "Broadcom SYSTEMPORT internal MAC support" + depends on OF +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/Makefile b/drivers/net/ethernet/broadcom/Makefile +--- a/drivers/net/ethernet/broadcom/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/Makefile 2018-05-10 11:31:31.725401901 +0800 +@@ -16,3 +16,4 @@ obj-$(CONFIG_BGMAC_BCMA) += bgmac-bcma.o + obj-$(CONFIG_BGMAC_PLATFORM) += bgmac-platform.o + obj-$(CONFIG_SYSTEMPORT) += bcmsysport.o + obj-$(CONFIG_BNXT) += bnxt/ ++obj-$(CONFIG_APM) += apm.o apm_ethtool.o pm4x10.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/apm.c b/drivers/net/ethernet/broadcom/apm.c +--- a/drivers/net/ethernet/broadcom/apm.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/apm.c 2018-05-31 15:24:26.196724803 +0800 +@@ -0,0 +1,1414 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include "pm.h" ++#include "apm.h" ++ ++static bool apm_clk_enabled(struct apm *apm); ++ ++static u32 apm_read(struct apm *apm, u16 offset) ++{ ++ return readl(apm->plat.base + offset); ++} ++ ++static void apm_write(struct apm *apm, u16 offset, u32 value) ++{ ++ writel(value, apm->plat.base + offset); ++} ++ ++static u32 apm_idm_read(struct apm *apm, u16 offset) ++{ ++ return readl(apm->plat.idm_base + offset); ++} ++ ++static void apm_idm_write(struct apm *apm, u16 offset, u32 value) ++{ ++ return writel(value, apm->plat.idm_base + offset); ++} ++ ++static bool apm_wait_value(struct apm *apm, u16 reg, u32 mask, ++ u32 value, int timeout) ++{ ++ u32 val; ++ int i; ++ ++ for (i = 0; i < timeout / 10; i++) { ++ val = apm_read(apm, reg); ++ if ((val & mask) == value) ++ return true; ++ udelay(10); ++ } ++ dev_err(apm->dev, "Timeout waiting for reg 0x%X\n", reg); ++ return false; ++} ++ ++/************************************************** ++ * DMA ++ **************************************************/ ++static void apm_dma_tx_reset(struct apm *apm, struct apm_dma_ring *tx_ring) ++{ ++ u32 val; ++ int i; ++ ++ if (!tx_ring->mmio_base) ++ return; ++ ++ /* Suspend DMA TX ring first. ++ * apm_wait_value doesn't support waiting for any of few values, so ++ * implement whole loop here. ++ */ ++ val = apm_read(apm, tx_ring->mmio_base + APM_DMA_TX_CTL); ++ apm_write(apm, tx_ring->mmio_base + APM_DMA_TX_CTL, ++ (val | APM_DMA_TX_SUSPEND)); ++ for (i = 0; i < 10000 / 10; i++) { ++ val = apm_read(apm, tx_ring->mmio_base + APM_DMA_TX_STATUS); ++ val &= APM_DMA_TX_STAT; ++ if (val == APM_DMA_TX_STAT_DISABLED || ++ val == APM_DMA_TX_STAT_IDLEWAIT || ++ val == APM_DMA_TX_STAT_STOPPED) { ++ i = 0; ++ break; ++ } ++ udelay(10); ++ } ++ if (i) { ++ dev_err(apm->dev, "Timeout suspending DMA TX ring 0x%X (APM_DMA_TX_STAT: 0x%08X)\n", ++ tx_ring->mmio_base, val); ++ } ++ ++ /* Disable the transmit channel */ ++ val = apm_read(apm, tx_ring->mmio_base + APM_DMA_TX_CTL); ++ apm_write(apm, tx_ring->mmio_base + APM_DMA_TX_CTL, ++ (val & ~APM_DMA_TX_SUSPEND)); ++ if (!apm_wait_value(apm, tx_ring->mmio_base + APM_DMA_TX_STATUS, ++ APM_DMA_TX_STAT, APM_DMA_TX_STAT_DISABLED, 10000)) { ++ dev_warn(apm->dev, "DMA TX ring 0x%X wasn't disabled on time, waiting additional 300us\n", ++ tx_ring->mmio_base); ++ udelay(300); ++ ++ val = apm_read(apm, tx_ring->mmio_base + APM_DMA_TX_STATUS); ++ if ((val & APM_DMA_TX_STAT) != APM_DMA_TX_STAT_DISABLED) ++ dev_err(apm->dev, "Reset of DMA TX ring 0x%X failed\n", ++ tx_ring->mmio_base); ++ } ++} ++ ++static void apm_dma_tx_enable(struct apm *apm, ++ struct apm_dma_ring *tx_ring) ++{ ++ u32 ctl; ++ ++ ctl = apm_read(apm, tx_ring->mmio_base + APM_DMA_TX_CTL); ++ if (apm->feature_flags & APM_FEAT_TX_MASK_SETUP) { ++ ctl &= ~APM_DMA_TX_BL_MASK; ++ ctl |= APM_DMA_TX_BL_128 << APM_DMA_TX_BL_SHIFT; ++ ++// ctl &= ~APM_DMA_TX_MR_MASK; ++// ctl |= APM_DMA_TX_MR_2 << APM_DMA_TX_MR_SHIFT; ++ ++ ctl &= ~APM_DMA_TX_PC_MASK; ++ ctl |= APM_DMA_TX_PC_16 << APM_DMA_TX_PC_SHIFT; ++ ++ ctl &= ~APM_DMA_TX_PT_MASK; ++ ctl |= APM_DMA_TX_PT_8 << APM_DMA_TX_PT_SHIFT; ++ } ++ ctl |= APM_DMA_TX_ENABLE; ++// ctl |= APM_DMA_TX_PARITY_DISABLE; ++ apm_write(apm, tx_ring->mmio_base + APM_DMA_TX_CTL, ctl); ++} ++ ++static void ++apm_dma_tx_add_buf(struct apm *apm, struct apm_dma_ring *tx_ring, ++ int i, int len, u32 ctl0) ++{ ++ struct apm_slot_info *slot; ++ struct apm_dma_desc *dma_desc; ++ u32 ctl1; ++ ++ if (i == tx_ring->desc_num - 1) ++ ctl0 |= APM_DESC_CTL0_EOT; ++ ++ ctl1 = len & APM_DESC_CTL1_LEN; ++ ++ slot = &tx_ring->slots[i]; ++ dma_desc = &tx_ring->desc_base[i]; ++ dma_desc->addr_low = cpu_to_le32(lower_32_bits(slot->dma_addr)); ++ dma_desc->addr_high = cpu_to_le32(upper_32_bits(slot->dma_addr)); ++ dma_desc->ctl0 = cpu_to_le32(ctl0); ++ dma_desc->ctl1 = cpu_to_le32(ctl1); ++} ++ ++static netdev_tx_t apm_dma_tx_add(struct apm *apm, ++ struct apm_dma_ring *tx_ring, struct sk_buff *skb) ++{ ++ struct device *dma_dev = apm->dma_dev; ++ struct net_device *net_dev = apm->net_dev; ++ int index = tx_ring->end % tx_ring->desc_num; ++ struct apm_slot_info *slot = &tx_ring->slots[index]; ++ int nr_frags; ++ u32 flags; ++ int i; ++ ++ if (skb->len > APM_DESC_CTL1_LEN) { ++ netdev_err(apm->net_dev, "Too long skb (%d)\n", skb->len); ++ goto err_drop; ++ } ++ ++ if (skb->ip_summed == CHECKSUM_PARTIAL) ++ skb_checksum_help(skb); ++ ++ nr_frags = skb_shinfo(skb)->nr_frags; ++ ++ /* ring->end - ring->start will return the number of valid slots, ++ * even when tx_ring->end overflows ++ */ ++ if (tx_ring->end - tx_ring->start + nr_frags + 1 >= tx_ring->desc_num) { ++ netdev_err(apm->net_dev, "TX ring is full, queue should be stopped!\n"); ++ netif_stop_queue(net_dev); ++ return NETDEV_TX_BUSY; ++ } ++ ++ slot->dma_addr = dma_map_single(dma_dev, skb->data, skb_headlen(skb), ++ DMA_TO_DEVICE); ++ if (unlikely(dma_mapping_error(dma_dev, slot->dma_addr))) ++ goto err_dma_head; ++ ++ flags = APM_DESC_CTL0_SOF; ++ if (!nr_frags) ++ flags |= APM_DESC_CTL0_EOF | APM_DESC_CTL0_IOC; ++ ++ apm_dma_tx_add_buf(apm, tx_ring, index, skb->len + 4, flags); ++ flags = 0; ++ ++ for (i = 0; i < nr_frags; i++) { ++ struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; ++ int len = skb_frag_size(frag); ++ ++ index = (index + 1) % tx_ring->desc_num; ++ slot = &tx_ring->slots[index]; ++ slot->dma_addr = skb_frag_dma_map(dma_dev, frag, 0, ++ len, DMA_TO_DEVICE); ++ if (unlikely(dma_mapping_error(dma_dev, slot->dma_addr))) ++ goto err_dma; ++ ++ if (i == nr_frags - 1) ++ flags |= APM_DESC_CTL0_EOF | APM_DESC_CTL0_IOC; ++ ++ apm_dma_tx_add_buf(apm, tx_ring, index, len, flags); ++ } ++ ++ slot->skb = skb; ++ tx_ring->end += nr_frags + 1; ++ netdev_sent_queue(net_dev, skb->len); ++ ++ wmb(); ++ ++ /* Increase tx_ring->end to point empty slot. We tell hardware the first ++ * slot it should *not* read. ++ */ ++ apm_write(apm, tx_ring->mmio_base + APM_DMA_TX_INDEX, ++ tx_ring->index_base + ++ (tx_ring->end % tx_ring->desc_num) * ++ sizeof(struct apm_dma_desc)); ++ ++ if (tx_ring->end - tx_ring->start >= tx_ring->desc_num - 8) ++ netif_stop_queue(net_dev); ++ ++ return NETDEV_TX_OK; ++ ++err_dma: ++ dma_unmap_single(dma_dev, slot->dma_addr, skb_headlen(skb), ++ DMA_TO_DEVICE); ++ ++ while (i-- > 0) { ++ int index = (tx_ring->end + i) % tx_ring->desc_num; ++ struct apm_slot_info *slot = &tx_ring->slots[index]; ++ u32 ctl1 = le32_to_cpu(tx_ring->desc_base[index].ctl1); ++ int len = ctl1 & APM_DESC_CTL1_LEN; ++ ++ dma_unmap_page(dma_dev, slot->dma_addr, len, DMA_TO_DEVICE); ++ } ++ ++err_dma_head: ++ netdev_err(apm->net_dev, "Mapping error of skb on TX ring 0x%X\n", ++ tx_ring->mmio_base); ++ ++err_drop: ++ dev_kfree_skb(skb); ++ net_dev->stats.tx_dropped++; ++ net_dev->stats.tx_errors++; ++ return NETDEV_TX_OK; ++} ++ ++/* Free transmitted packets */ ++static void apm_dma_tx_free(struct apm *apm, struct apm_dma_ring *tx_ring) ++{ ++ struct device *dma_dev = apm->dma_dev; ++ int empty_slot; ++ bool freed = false; ++ unsigned bytes_compl = 0, pkts_compl = 0; ++ ++ /* The last slot that hardware didn't consume yet */ ++ empty_slot = apm_read(apm, tx_ring->mmio_base + APM_DMA_TX_STATUS); ++ empty_slot &= APM_DMA_TX_STATDPTR; ++ empty_slot -= tx_ring->index_base; ++ empty_slot &= APM_DMA_TX_STATDPTR; ++ empty_slot /= sizeof(struct apm_dma_desc); ++ ++ while (tx_ring->start != tx_ring->end) { ++ int index = tx_ring->start % tx_ring->desc_num; ++ struct apm_slot_info *slot = &tx_ring->slots[index]; ++ u32 ctl0, ctl1; ++ int len; ++ ++ if (index == empty_slot) ++ break; ++ ++ ctl0 = le32_to_cpu(tx_ring->desc_base[index].ctl0); ++ ctl1 = le32_to_cpu(tx_ring->desc_base[index].ctl1); ++ len = ctl1 & APM_DESC_CTL1_LEN; ++ if (ctl0 & APM_DESC_CTL0_SOF) ++ /* Unmap no longer used buffer */ ++ dma_unmap_single(dma_dev, slot->dma_addr, len, ++ DMA_TO_DEVICE); ++ else ++ dma_unmap_page(dma_dev, slot->dma_addr, len, ++ DMA_TO_DEVICE); ++ ++ if (slot->skb) { ++ apm->net_dev->stats.tx_bytes += slot->skb->len; ++ apm->net_dev->stats.tx_packets++; ++ bytes_compl += slot->skb->len; ++ pkts_compl++; ++ ++ /* Free memory! :) */ ++ dev_kfree_skb(slot->skb); ++ slot->skb = NULL; ++ } ++ ++ slot->dma_addr = 0; ++ tx_ring->start++; ++ freed = true; ++ } ++ ++ if (!pkts_compl) ++ return; ++ ++ netdev_completed_queue(apm->net_dev, pkts_compl, bytes_compl); ++ ++ if (netif_queue_stopped(apm->net_dev)) ++ netif_wake_queue(apm->net_dev); ++} ++ ++static void apm_dma_rx_reset(struct apm *apm, struct apm_dma_ring *rx_ring) ++{ ++ if (!rx_ring->mmio_base) ++ return; ++ ++ apm_write(apm, rx_ring->mmio_base + APM_DMA_RX_CTL, 0); ++ if (!apm_wait_value(apm, ++ rx_ring->mmio_base + APM_DMA_RX_STATUS, ++ APM_DMA_RX_STAT, APM_DMA_RX_STAT_DISABLED, ++ 10000)) ++ dev_err(apm->dev, "Reset of RX ring 0x%X RX failed\n", ++ rx_ring->mmio_base); ++} ++ ++static void apm_dma_rx_enable(struct apm *apm, ++ struct apm_dma_ring *rx_ring) ++{ ++ u32 ctl; ++ ++ ctl = apm_read(apm, rx_ring->mmio_base + APM_DMA_RX_CTL); ++ ++// /* preserve ONLY bits 16-17 from current hardware value */ ++// ctl &= APM_DMA_RX_ADDREXT_MASK; ++ ++ if (apm->feature_flags & APM_FEAT_RX_MASK_SETUP) { ++ ctl &= ~APM_DMA_RX_BL_MASK; ++ ctl |= APM_DMA_RX_BL_128 << APM_DMA_RX_BL_SHIFT; ++ ++ ctl &= ~APM_DMA_RX_PC_MASK; ++ ctl |= APM_DMA_RX_PC_8 << APM_DMA_RX_PC_SHIFT; ++ ++ ctl &= ~APM_DMA_RX_PT_MASK; ++ ctl |= APM_DMA_RX_PT_1 << APM_DMA_RX_PT_SHIFT; ++ } ++ ctl |= APM_DMA_RX_ENABLE; ++// ctl |= APM_DMA_RX_PARITY_DISABLE; ++ ctl |= APM_DMA_RX_OVERFLOW_CONT; ++ ctl |= APM_RX_FRAME_OFFSET << APM_DMA_RX_FRAME_OFFSET_SHIFT; ++ apm_write(apm, rx_ring->mmio_base + APM_DMA_RX_CTL, ctl); ++} ++ ++static int apm_dma_rx_skb_for_slot(struct apm *apm, ++ struct apm_slot_info *slot) ++{ ++ struct device *dma_dev = apm->dma_dev; ++ dma_addr_t dma_addr; ++ struct apm_rx_header *rx; ++ void *buf; ++ ++ /* Alloc skb */ ++ buf = netdev_alloc_frag(APM_RX_ALLOC_SIZE); ++ if (!buf) ++ return -ENOMEM; ++ ++ /* Poison - if everything goes fine, hardware will overwrite it */ ++ rx = buf + APM_RX_BUF_OFFSET; ++ rx->len = cpu_to_le16(0xdead); ++ rx->flags = cpu_to_le16(0xbeef); ++ ++ /* Map skb for the DMA */ ++ dma_addr = dma_map_single(dma_dev, buf + APM_RX_BUF_OFFSET, ++ APM_RX_BUF_SIZE, DMA_FROM_DEVICE); ++ if (dma_mapping_error(dma_dev, dma_addr)) { ++ netdev_err(apm->net_dev, "DMA mapping error\n"); ++ put_page(virt_to_head_page(buf)); ++ return -ENOMEM; ++ } ++ ++ /* Update the slot */ ++ slot->buf = buf; ++ slot->dma_addr = dma_addr; ++ ++ return 0; ++} ++ ++static void apm_dma_rx_update_index(struct apm *apm, ++ struct apm_dma_ring *rx_ring) ++{ ++ dma_wmb(); ++ ++ apm_write(apm, rx_ring->mmio_base + APM_DMA_RX_INDEX, ++ rx_ring->index_base + ++ rx_ring->end * sizeof(struct apm_dma_desc)); ++} ++ ++static void apm_dma_rx_setup_desc(struct apm *apm, ++ struct apm_dma_ring *rx_ring, int index) ++{ ++ struct apm_dma_desc *dma_desc = rx_ring->desc_base + index; ++ u32 ctl0 = 0, ctl1 = 0; ++ ++ if (index == rx_ring->desc_num - 1) ++ ctl0 |= APM_DESC_CTL0_EOT; ++ ctl1 |= APM_RX_BUF_SIZE & APM_DESC_CTL1_LEN; ++ /* Is there any APM device that requires extension? */ ++ /* ctl1 |= (addrext << B43_DMA64_DCTL1_ADDREXT_SHIFT) & ++ * B43_DMA64_DCTL1_ADDREXT_MASK; ++ */ ++ ++ dma_desc->addr_low = cpu_to_le32(lower_32_bits(rx_ring->slots[index].dma_addr)); ++ dma_desc->addr_high = cpu_to_le32(upper_32_bits(rx_ring->slots[index].dma_addr)); ++ dma_desc->ctl0 = cpu_to_le32(ctl0); ++ dma_desc->ctl1 = cpu_to_le32(ctl1); ++ ++ rx_ring->end = index; ++} ++ ++static void apm_dma_rx_poison_buf(struct device *dma_dev, ++ struct apm_slot_info *slot) ++{ ++ struct apm_rx_header *rx = slot->buf + APM_RX_BUF_OFFSET; ++ ++ dma_sync_single_for_cpu(dma_dev, slot->dma_addr, APM_RX_BUF_SIZE, ++ DMA_FROM_DEVICE); ++ rx->len = cpu_to_le16(0xdead); ++ rx->flags = cpu_to_le16(0xbeef); ++ dma_sync_single_for_device(dma_dev, slot->dma_addr, APM_RX_BUF_SIZE, ++ DMA_FROM_DEVICE); ++} ++ ++static int apm_dma_rx_read(struct apm *apm, struct apm_dma_ring *rx_ring, ++ int weight) ++{ ++ u32 end_slot; ++ int handled = 0; ++ ++ end_slot = apm_read(apm, rx_ring->mmio_base + APM_DMA_RX_STATUS); ++ end_slot &= APM_DMA_RX_STATDPTR; ++ end_slot -= rx_ring->index_base; ++ end_slot &= APM_DMA_RX_STATDPTR; ++ end_slot /= sizeof(struct apm_dma_desc); ++ ++ while (rx_ring->start != end_slot) { ++ struct device *dma_dev = apm->dma_dev; ++ struct apm_slot_info *slot = &rx_ring->slots[rx_ring->start]; ++ struct apm_rx_header *rx = slot->buf + APM_RX_BUF_OFFSET; ++ struct sk_buff *skb; ++ void *buf = slot->buf; ++ dma_addr_t dma_addr = slot->dma_addr; ++ u16 len, flags; ++ ++ do { ++ /* Prepare new skb as replacement */ ++ if (apm_dma_rx_skb_for_slot(apm, slot)) { ++ apm_dma_rx_poison_buf(dma_dev, slot); ++ break; ++ } ++ ++ /* Unmap buffer to make it accessible to the CPU */ ++ dma_unmap_single(dma_dev, dma_addr, ++ APM_RX_BUF_SIZE, DMA_FROM_DEVICE); ++ ++ /* Get info from the header */ ++ len = le16_to_cpu(rx->len); ++ flags = le16_to_cpu(rx->flags); ++ ++ /* Check for poison and drop or pass the packet */ ++ if (len == 0xdead && flags == 0xbeef) { ++ netdev_err(apm->net_dev, "Found poisoned packet at slot %d, DMA issue!\n", ++ rx_ring->start); ++ put_page(virt_to_head_page(buf)); ++ apm->net_dev->stats.rx_errors++; ++ break; ++ } ++ ++ if (len > APM_RX_ALLOC_SIZE) { ++ netdev_err(apm->net_dev, "Found oversized packet at slot %d, DMA issue!\n", ++ rx_ring->start); ++ put_page(virt_to_head_page(buf)); ++ apm->net_dev->stats.rx_length_errors++; ++ apm->net_dev->stats.rx_errors++; ++ break; ++ } ++ ++ /* Omit CRC. */ ++ len -= ETH_FCS_LEN; ++ ++ skb = build_skb(buf, APM_RX_ALLOC_SIZE); ++ if (unlikely(!skb)) { ++ netdev_err(apm->net_dev, "build_skb failed\n"); ++ put_page(virt_to_head_page(buf)); ++ apm->net_dev->stats.rx_errors++; ++ break; ++ } ++ skb_put(skb, APM_RX_FRAME_OFFSET + ++ APM_RX_BUF_OFFSET + len); ++ skb_pull(skb, APM_RX_FRAME_OFFSET + ++ APM_RX_BUF_OFFSET); ++ ++ skb_checksum_none_assert(skb); ++ skb->protocol = eth_type_trans(skb, apm->net_dev); ++ apm->net_dev->stats.rx_bytes += len; ++ apm->net_dev->stats.rx_packets++; ++ napi_gro_receive(&apm->napi, skb); ++ handled++; ++ } while (0); ++ ++ apm_dma_rx_setup_desc(apm, rx_ring, rx_ring->start); ++ ++ if (++rx_ring->start >= rx_ring->desc_num) ++ rx_ring->start = 0; ++ ++ if (handled >= weight) /* Should never be greater */ ++ break; ++ } ++ ++ apm_dma_rx_update_index(apm, rx_ring); ++ ++ return handled; ++} ++ ++/* Does ring support unaligned addressing? */ ++static bool apm_dma_unaligned(struct apm *apm, ++ struct apm_dma_ring *ring, ++ enum apm_dma_ring_type ring_type) ++{ ++ switch (ring_type) { ++ case APM_DMA_RING_TYPE_TX: ++ apm_write(apm, ring->mmio_base + APM_DMA_TX_RINGLO, 0xff0); ++ if (apm_read(apm, ring->mmio_base + APM_DMA_TX_RINGLO)) ++ return true; ++ break; ++ case APM_DMA_RING_TYPE_RX: ++ apm_write(apm, ring->mmio_base + APM_DMA_RX_RINGLO, 0xff0); ++ if (apm_read(apm, ring->mmio_base + APM_DMA_RX_RINGLO)) ++ return true; ++ break; ++ default: ++ return false; ++ } ++ return false; ++} ++ ++static void apm_dma_tx_ring_free(struct apm *apm, ++ struct apm_dma_ring *tx_ring) ++{ ++ struct device *dma_dev = apm->dma_dev; ++ struct apm_dma_desc *dma_desc = tx_ring->desc_base; ++ struct apm_slot_info *slot; ++ int i; ++ ++ for (i = 0; i < tx_ring->desc_num; i++) { ++ int len = dma_desc[i].ctl1 & APM_DESC_CTL1_LEN; ++ ++ slot = &tx_ring->slots[i]; ++ dev_kfree_skb(slot->skb); ++ if (!slot->dma_addr) ++ continue; ++ ++ if (slot->skb) ++ dma_unmap_single(dma_dev, slot->dma_addr, ++ len, DMA_TO_DEVICE); ++ else ++ dma_unmap_page(dma_dev, slot->dma_addr, ++ len, DMA_TO_DEVICE); ++ } ++} ++ ++static void apm_dma_rx_ring_free(struct apm *apm, ++ struct apm_dma_ring *rx_ring) ++{ ++ struct device *dma_dev = apm->dma_dev; ++ struct apm_slot_info *slot; ++ int i; ++ ++ for (i = 0; i < rx_ring->desc_num; i++) { ++ slot = &rx_ring->slots[i]; ++ if (!slot->dma_addr) ++ continue; ++ ++ dma_unmap_single(dma_dev, slot->dma_addr, ++ APM_RX_BUF_SIZE, ++ DMA_FROM_DEVICE); ++ put_page(virt_to_head_page(slot->buf)); ++ slot->dma_addr = 0; ++ } ++} ++ ++static void apm_dma_cleanup(struct apm *apm) ++{ ++ int i; ++ ++ for (i = 0; i < apm->tx_channel; i++) { ++ apm_dma_tx_ring_free(apm, &apm->tx_ring[i]); ++ } ++ ++ apm_dma_rx_ring_free(apm, &apm->rx_ring[0]); ++} ++ ++static void apm_dma_free(struct apm *apm) ++{ ++ struct device *dma_dev = apm->dma_dev; ++ int size; ++ ++ if (apm->desc_buf) { ++ size = (APM_TX_MAX_DESCS + APM_RX_MAX_DESCS) * ++ sizeof(struct apm_dma_desc); ++ dma_free_coherent(dma_dev, size, apm->desc_buf, apm->dma_addr); ++ } ++ ++ if (apm->slot_buf) { ++ kfree(apm->slot_buf); ++ } ++} ++ ++static int apm_dma_alloc(struct apm *apm) ++{ ++ struct device *dma_dev = apm->dma_dev; ++ int size; ++ ++ size = (APM_TX_MAX_DESCS + APM_RX_MAX_DESCS) * ++ sizeof(struct apm_dma_desc); ++ apm->desc_buf = dma_zalloc_coherent(dma_dev, size, ++ &apm->dma_addr, GFP_KERNEL); ++ if (!apm->desc_buf) { ++ dev_err(apm->dev, "Descriptor buffer allocation failed\n"); ++ goto err_dma_free; ++ } ++ memset(apm->desc_buf, 0, size); ++ ++ size = (APM_TX_MAX_DESCS + APM_RX_MAX_DESCS) * ++ sizeof(struct apm_slot_info); ++ apm->slot_buf = kmalloc(size, GFP_KERNEL); ++ if (!apm->slot_buf) { ++ dev_err(apm->dev, "Data buffer allocation failed\n"); ++ goto err_dma_free; ++ } ++ memset(apm->slot_buf, 0, size); ++ return 0; ++ ++err_dma_free: ++ apm_dma_free(apm); ++ return -ENOMEM; ++} ++ ++static int apm_tx_dma_init(struct apm *apm, ++ struct apm_dma_ring *tx_ring, int channel) ++{ ++ const u16 ring_base[] = { APM_DMA_BASE0, APM_DMA_BASE1, ++ APM_DMA_BASE2, APM_DMA_BASE3,}; ++ int desc_num = APM_TX_MAX_DESCS / apm->tx_channel; ++ int offset = channel * desc_num; ++ ++ BUILD_BUG_ON(APM_MAX_TX_RINGS > ARRAY_SIZE(ring_base)); ++ ++ tx_ring->mmio_base = ring_base[channel]; ++ if ((apm->tx_channel == 2) && (channel == 1)) { ++ tx_ring->mmio_base = ring_base[2]; ++ } ++ ++ tx_ring->desc_num = desc_num; ++ tx_ring->desc_base = apm->desc_buf + offset; ++ tx_ring->dma_base = (dma_addr_t)((u32)apm->dma_addr + ++ offset * sizeof(struct apm_dma_desc)); ++ tx_ring->slots = apm->slot_buf + offset; ++ ++ tx_ring->index_base = 0; ++ tx_ring->unaligned = apm_dma_unaligned(apm, ++ tx_ring, APM_DMA_RING_TYPE_TX); ++ if (tx_ring->unaligned) { ++ tx_ring->index_base = lower_32_bits(tx_ring->dma_base); ++ } ++ ++ tx_ring->start = 0; ++ tx_ring->end = 0; /* Points the slot that should *not* be read */ ++ ++ return 0; ++} ++ ++static int apm_rx_dma_init(struct apm *apm, struct apm_dma_ring *rx_ring) ++{ ++ int offset = APM_TX_MAX_DESCS; ++ ++ rx_ring->desc_num = APM_RX_MAX_DESCS; ++ rx_ring->mmio_base = APM_DMA_BASE0; ++ rx_ring->desc_base = apm->desc_buf + offset; ++ rx_ring->dma_base = (dma_addr_t)((u32)apm->dma_addr + ++ offset * sizeof(struct apm_dma_desc)); ++ rx_ring->slots = apm->slot_buf + offset; ++ ++ rx_ring->index_base = 0; ++ rx_ring->unaligned = apm_dma_unaligned(apm, ++ rx_ring, APM_DMA_RING_TYPE_RX); ++ if (rx_ring->unaligned) { ++ rx_ring->index_base = lower_32_bits(rx_ring->dma_base); ++ } ++ ++ rx_ring->start = 0; ++ rx_ring->end = 0; /* Points the slot that should *not* be read */ ++ ++ return 0; ++} ++ ++static int apm_dma_init(struct apm *apm) ++{ ++ struct apm_dma_ring *tx_ring, *rx_ring; ++ int i, err; ++ ++ /* TX DMA init */ ++ for (i = 0; i < apm->tx_channel; i++) { ++ tx_ring = &apm->tx_ring[i]; ++ apm_tx_dma_init(apm, tx_ring, i); ++ ++ if (!tx_ring->unaligned) { ++ apm_dma_tx_enable(apm, tx_ring); ++ } ++ ++ apm_write(apm, tx_ring->mmio_base + APM_DMA_TX_RINGLO, ++ lower_32_bits(tx_ring->dma_base)); ++ apm_write(apm, tx_ring->mmio_base + APM_DMA_TX_RINGHI, ++ upper_32_bits(tx_ring->dma_base)); ++ ++ if (tx_ring->unaligned) { ++ apm_dma_tx_enable(apm, tx_ring); ++ } ++ } ++ ++ /* RX DMA init */ ++ rx_ring = &apm->rx_ring[0]; ++ apm_rx_dma_init(apm, rx_ring); ++ ++ if (!rx_ring->unaligned) { ++ apm_dma_rx_enable(apm, rx_ring); ++ } ++ ++ apm_write(apm, rx_ring->mmio_base + APM_DMA_RX_RINGLO, ++ lower_32_bits(rx_ring->dma_base)); ++ apm_write(apm, rx_ring->mmio_base + APM_DMA_RX_RINGHI, ++ upper_32_bits(rx_ring->dma_base)); ++ ++ if (rx_ring->unaligned) { ++ apm_dma_rx_enable(apm, rx_ring); ++ } ++ ++ for (i = 0; i < rx_ring->desc_num; i++) { ++ err = apm_dma_rx_skb_for_slot(apm, &rx_ring->slots[i]); ++ if (err) { ++ goto error; ++ } ++ apm_dma_rx_setup_desc(apm, rx_ring, i); ++ } ++ apm_dma_rx_update_index(apm, rx_ring); ++ ++ return 0; ++ ++error: ++ apm_dma_cleanup(apm); ++ return err; ++} ++ ++ ++/************************************************** ++ * Chip ops ++ **************************************************/ ++ ++/* TODO: can we just drop @force? Can we don't reset MAC at all if there is ++ * nothing to change? Try if after stabilizng driver. ++ */ ++//static void apm_cmdcfg_maskset(struct apm *apm, u32 mask, u32 set, ++// bool force) ++//{ ++// u32 cmdcfg = apm_read(apm, APM_CMDCFG); ++// u32 new_val = (cmdcfg & mask) | set; ++// u32 cmdcfg_sr; ++// ++// apm_set(apm, APM_CMDCFG, cmdcfg_sr); ++// udelay(2); ++// ++// if (new_val != cmdcfg || force) ++// apm_write(apm, APM_CMDCFG, new_val); ++// ++// apm_mask(apm, APM_CMDCFG, ~cmdcfg_sr); ++// udelay(2); ++//} ++ ++//static void apm_set_rx_mode(struct net_device *net_dev) ++//{ ++// struct apm *apm = netdev_priv(net_dev); ++// ++// if (net_dev->flags & IFF_PROMISC) ++// apm_cmdcfg_maskset(apm, ~0, APM_CMDCFG_PROM, true); ++// else ++// apm_cmdcfg_maskset(apm, ~APM_CMDCFG_PROM, 0, true); ++//} ++ ++static int apm_port_loopback(struct apm *apm, int lb_type) ++{ ++ struct iproc_pm_ops *pm_ops = apm->pm_ops; ++ ++ if (!pm_ops) { ++ dev_err(apm->dev, "(%s) PM does not exist\n", __func__); ++ return -EINVAL; ++ } ++ ++ if (lb_type == APM_LOOPBACK_TYPE_NONE) { ++ pm_ops->port_loopback(apm->land_idx, pmLoopbackMac, 0); ++ pm_ops->port_loopback(apm->land_idx, pmLoopbackPhy, 0); ++ } else if (lb_type == APM_LOOPBACK_TYPE_MAC) { ++ pm_ops->port_loopback(apm->land_idx, pmLoopbackMac, 1); ++ } else if (lb_type == APM_LOOPBACK_TYPE_PHY) { ++ pm_ops->port_loopback(apm->land_idx, pmLoopbackPhy, 1); ++ } ++ return 0; ++} ++ ++static int apm_port_mac_address_set(struct apm *apm, u8 *addr) ++{ ++ struct iproc_pm_ops *pm_ops = apm->pm_ops; ++ ++ if (!pm_ops) { ++ dev_err(apm->dev, "(%s) PM does not exist\n", __func__); ++ return -EINVAL; ++ } ++ ++ return pm_ops->port_mac_addr(apm->land_idx, addr); ++} ++ ++static int apm_port_speed(struct apm *apm) ++{ ++ struct iproc_pm_ops *pm_ops = apm->pm_ops; ++ ++ if (!pm_ops) { ++ dev_err(apm->dev, "(%s) PM does not exist\n", __func__); ++ return -EINVAL; ++ } ++ ++ switch (apm->mac_speed) { ++ case SPEED_10: ++ case SPEED_100: ++ case SPEED_1000: ++ return pm_ops->port_speed(apm->land_idx, apm->mac_speed); ++ default: ++ dev_err(apm->dev, "Unsupported speed: %d\n", apm->mac_speed); ++ } ++ ++ return -EINVAL; ++} ++ ++static int apm_port_enable(struct apm *apm, int enable) ++{ ++ struct iproc_pm_ops *pm_ops = apm->pm_ops; ++ ++ if (!pm_ops) { ++ dev_err(apm->dev, "(%s) PM does not exist\n", __func__); ++ return -EINVAL; ++ } ++ ++ return pm_ops->port_enable(apm->land_idx, enable); ++} ++ ++static int apm_port_stats_clear(struct apm *apm) ++{ ++ struct iproc_pm_ops *pm_ops = apm->pm_ops; ++ ++ if (!pm_ops) { ++ dev_err(apm->dev, "(%s) PM does not exist\n", __func__); ++ return -EINVAL; ++ } ++ ++ return pm_ops->port_stats_clear(apm->land_idx); ++} ++ ++static void apm_chip_init(struct apm *apm) ++{ ++ u32 dev_ctl; ++// u32 cmdcfg; ++ ++ /* 1 interrupt per received frame */ ++ apm_write(apm, APM_INT_RECV_LAZY, 1 << APM_IRL_FC_SHIFT); ++ ++ /* TX QoS mode */ ++ dev_ctl = apm_read(apm, APM_DEV_CTL); ++ if (apm->strict_mode) { ++ dev_ctl |= APM_DC_TSM; ++ } else { ++ dev_ctl &= ~APM_DC_TSM; ++ } ++ apm_write(apm, APM_DEV_CTL, dev_ctl); ++ ++// /* Enable 802.3x tx flow control (honor received PAUSE frames) */ ++// apm_cmdcfg_maskset(apm, ~APM_CMDCFG_RPI, 0, true); ++// ++// /* Activate apm tx & rx */ ++// cmdcfg = apm_read(apm, APM_CMDCFG); ++// cmdcfg |= APM_CMDCFG_TE | APM_CMDCFG_RE; ++// apm_write(apm, APM_CMDCFG, cmdcfg); ++ ++ apm_port_mac_address_set(apm, apm->net_dev->dev_addr); ++ ++ /* Enable the pm port */ ++ apm_port_enable(apm, 1); ++} ++ ++static void apm_chip_reset(struct apm *apm) ++{ ++ int i; ++ ++ if (apm_clk_enabled(apm)) { ++ for (i = 0; i < apm->tx_channel; i++) { ++ apm_dma_tx_reset(apm, &apm->tx_ring[i]); ++ } ++ ++ apm_port_loopback (apm, APM_LOOPBACK_TYPE_NONE); ++ udelay(1); ++ ++ apm_dma_rx_reset(apm, &apm->rx_ring[0]); ++ ++ /* TODO: Clear software multicast filter list */ ++ } ++ ++ /* Disable the pm port */ ++ apm_port_enable(apm, 0); ++ ++ /* Clear the MIB */ ++ apm_port_stats_clear(apm); ++ ++ apm->mac_speed = SPEED_1000; ++ apm->mac_duplex = DUPLEX_FULL; ++ apm_port_speed(apm); ++ ++ if (apm->mii_bus) { ++ apm->mii_bus->reset(apm->mii_bus); ++ } ++ ++ netdev_reset_queue(apm->net_dev); ++} ++ ++ ++static void apm_intrs_on(struct apm *apm) ++{ ++ apm_write(apm, APM_INT_MASK, apm->int_mask); ++} ++ ++static void apm_intrs_off(struct apm *apm) ++{ ++ apm_write(apm, APM_INT_MASK, 0); ++ apm_read(apm, APM_INT_MASK); ++} ++ ++static bool apm_clk_enabled(struct apm *apm) ++{ ++ if ((apm_idm_read(apm, BCMA_IOCTL) & ++ (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC)) != BCMA_IOCTL_CLK) ++ return false; ++ if (apm_idm_read(apm, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET) ++ return false; ++ return true; ++} ++ ++static void apm_clk_enable(struct apm *apm, u32 flags) ++{ ++ apm_idm_write(apm, BCMA_IOCTL, ++ (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags)); ++ apm_idm_read(apm, BCMA_IOCTL); ++ ++ apm_idm_write(apm, BCMA_RESET_CTL, 0); ++ apm_idm_read(apm, BCMA_RESET_CTL); ++ udelay(1); ++ ++ apm_idm_write(apm, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags)); ++ apm_idm_read(apm, BCMA_IOCTL); ++ udelay(1); ++} ++ ++static irqreturn_t apm_interrupt(int irq, void *dev_id) ++{ ++ struct apm *apm = netdev_priv(dev_id); ++ u32 int_status = apm_read(apm, APM_INT_STATUS); ++ int_status &= apm->int_mask; ++ ++ if (!int_status) ++ return IRQ_NONE; ++ ++ int_status &= ~(APM_IS_TX0 | APM_IS_RX); ++ if (int_status) ++ dev_err(apm->dev, "Unknown IRQs: 0x%08X\n", int_status); ++ ++ /* Disable new interrupts until handling existing ones */ ++ apm_intrs_off(apm); ++ ++ napi_schedule(&apm->napi); ++ ++ return IRQ_HANDLED; ++} ++ ++static int apm_poll(struct napi_struct *napi, int weight) ++{ ++ struct apm *apm = container_of(napi, struct apm, napi); ++ int handled = 0; ++ ++ /* Ack */ ++ apm_write(apm, APM_INT_STATUS, ~0); ++ ++ apm_dma_tx_free(apm, &apm->tx_ring[0]); ++ handled += apm_dma_rx_read(apm, &apm->rx_ring[0], weight); ++ ++ /* Poll again if more events arrived in the meantime */ ++ if (apm_read(apm, APM_INT_STATUS) & (APM_IS_TX0 | APM_IS_RX)) ++ return weight; ++ ++ if (handled < weight) { ++ napi_complete(napi); ++ apm_intrs_on(apm); ++ } ++ ++ return handled; ++} ++ ++/************************************************** ++ * net_device_ops ++ **************************************************/ ++static int apm_open(struct net_device *net_dev) ++{ ++ struct apm *apm = netdev_priv(net_dev); ++ int err = 0; ++ ++ apm_chip_reset(apm); ++ ++ err = apm_dma_init(apm); ++ if (err) ++ return err; ++ ++ /* Specs say about reclaiming rings here, but we do that in DMA init */ ++ apm_chip_init(apm); ++ ++ ++ err = request_irq(apm->irq0, apm_interrupt, IRQF_SHARED, ++ KBUILD_MODNAME, net_dev); ++ if (err < 0) { ++ dev_err(apm->dev, "IRQ 0 request error: %d!\n", err); ++ apm_dma_cleanup(apm); ++ return err; ++ } ++ err = request_irq(apm->irq1, apm_interrupt, IRQF_SHARED, ++ KBUILD_MODNAME, net_dev); ++ if (err < 0) { ++ dev_err(apm->dev, "IRQ 1 request error: %d!\n", err); ++ apm_dma_cleanup(apm); ++ return err; ++ } ++ err = request_irq(apm->irq2, apm_interrupt, IRQF_SHARED, ++ KBUILD_MODNAME, net_dev); ++ if (err < 0) { ++ dev_err(apm->dev, "IRQ 2 request error: %d!\n", err); ++ apm_dma_cleanup(apm); ++ return err; ++ } ++ napi_enable(&apm->napi); ++ ++ phy_start(net_dev->phydev); ++ ++ netif_start_queue(net_dev); ++ ++ apm_intrs_on(apm); ++ ++ return 0; ++} ++ ++static int apm_stop(struct net_device *net_dev) ++{ ++ struct apm *apm = netdev_priv(net_dev); ++ ++ netif_carrier_off(net_dev); ++ ++ phy_stop(net_dev->phydev); ++ ++ napi_disable(&apm->napi); ++ apm_intrs_off(apm); ++ ++ free_irq(apm->irq0, net_dev); ++ free_irq(apm->irq1, net_dev); ++ free_irq(apm->irq2, net_dev); ++ ++ apm_chip_reset(apm); ++ apm_dma_cleanup(apm); ++ ++ return 0; ++} ++ ++static netdev_tx_t apm_start_xmit(struct sk_buff *skb, ++ struct net_device *net_dev) ++{ ++ struct apm *apm = netdev_priv(net_dev); ++ struct apm_dma_ring *tx_ring; ++ u32 channel; ++ ++ /* Remap the priority to 8 priorities first and transmit the packet ++ * to corresponding tx channel. ++ */ ++ channel = (skb->priority % 8) / (8 / apm->tx_channel); ++ channel = 0; // FIXME, GH2 doesn't support multiple channel ++ ++ tx_ring = &apm->tx_ring[channel]; ++ return apm_dma_tx_add(apm, tx_ring, skb); ++} ++ ++static int apm_set_mac_address(struct net_device *net_dev, void *addr) ++{ ++ struct apm *apm = netdev_priv(net_dev); ++ int ret; ++ ++ ret = eth_prepare_mac_addr_change(net_dev, addr); ++ if (ret < 0) ++ return ret; ++ apm_port_mac_address_set(apm, (u8 *)addr); ++ eth_commit_mac_addr_change(net_dev, addr); ++ ++ return 0; ++} ++ ++static int apm_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd) ++{ ++ if (!netif_running(net_dev)) ++ return -EINVAL; ++ ++ return phy_mii_ioctl(net_dev->phydev, ifr, cmd); ++} ++ ++static const struct net_device_ops apm_netdev_ops = { ++ .ndo_open = apm_open, ++ .ndo_stop = apm_stop, ++ .ndo_start_xmit = apm_start_xmit, ++// .ndo_set_rx_mode = apm_set_rx_mode, ++ .ndo_set_mac_address = apm_set_mac_address, ++ .ndo_validate_addr = eth_validate_addr, ++ .ndo_do_ioctl = apm_ioctl, ++}; ++ ++/************************************************** ++ * MII ++ **************************************************/ ++static void apm_adjust_link(struct net_device *net_dev) ++{ ++ struct apm *apm = netdev_priv(net_dev); ++ struct phy_device *phy_dev = net_dev->phydev; ++ bool update = false; ++ ++ if (phy_dev->link) { ++ if (phy_dev->speed != apm->mac_speed) { ++ apm->mac_speed = phy_dev->speed; ++ update = true; ++ } ++ ++ if (phy_dev->duplex != apm->mac_duplex) { ++ apm->mac_duplex = phy_dev->duplex; ++ update = true; ++ } ++ } ++ ++ if (update) { ++ apm_port_speed(apm); ++ phy_print_status(phy_dev); ++ } ++} ++ ++static int apm_enet_probe(struct apm *info) ++{ ++ struct net_device *net_dev; ++ struct apm *apm; ++ struct phy_device *phy_dev; ++ int err; ++ ++ /* Allocation and references */ ++ net_dev = alloc_etherdev(sizeof(*apm)); ++ if (!net_dev) ++ return -ENOMEM; ++ ++ net_dev->netdev_ops = &apm_netdev_ops; ++ ++ apm = netdev_priv(net_dev); ++ memcpy(apm, info, sizeof(*apm)); ++ apm->net_dev = net_dev; ++ net_dev->irq = apm->irq0; /* irq1, irq2 ?? */ ++ SET_NETDEV_DEV(net_dev, apm->dev); ++ ++ if (!is_valid_ether_addr(apm->mac_addr)) { ++ dev_err(apm->dev, "Invalid MAC addr: %pM\n", apm->mac_addr); ++ eth_random_addr(apm->mac_addr); ++ dev_warn(apm->dev, "Using random MAC: %pM\n", apm->mac_addr); ++ } ++ ether_addr_copy(net_dev->dev_addr, apm->mac_addr); ++ ++ /* This (reset &) enable is not preset in specs or reference driver but ++ * Broadcom does it in arch PCI code when enabling fake PCI device. ++ */ ++ apm_clk_enable(apm, 0); ++ ++ apm_chip_reset(apm); ++ ++ err = apm_ethtool_init(net_dev); ++ if (err) { ++ dev_err(apm->dev, "Init ethtool failed\n"); ++ goto err_netdev_free; ++ } ++ ++ err = apm_dma_alloc(apm); ++ if (err) { ++ dev_err(apm->dev, "Unable to alloc memory for DMA\n"); ++ goto err_netdev_free; ++ } ++ ++ apm->int_mask = APM_IS_ERRMASK | APM_IS_RX | APM_IS_TX_MASK; ++ ++ netif_napi_add(net_dev, &apm->napi, apm_poll, APM_WEIGHT); ++ ++ /* phy init; serdes init is already done in pm.c */ ++ phy_dev = of_phy_get_and_connect(apm->net_dev, apm->dev->of_node, ++ &apm_adjust_link); ++ if (!phy_dev) { ++ dev_warn(apm->dev, "No phy available in DT"); ++ } ++ ++ net_dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; ++ net_dev->hw_features = net_dev->features; ++ net_dev->vlan_features = net_dev->features; ++ ++ err = register_netdev(apm->net_dev); ++ if (err) { ++ dev_err(apm->dev, "Cannot register net device\n"); ++ goto err_phy_disconnect; ++ } ++ ++ netif_carrier_off(net_dev); ++ ++ return 0; ++ ++err_phy_disconnect: ++ phy_disconnect(net_dev->phydev); ++err_netdev_free: ++ free_netdev(net_dev); ++ ++ return err; ++} ++ ++static void apm_enet_remove(struct apm *apm) ++{ ++ unregister_netdev(apm->net_dev); ++ phy_disconnect(apm->net_dev->phydev); ++ netif_napi_del(&apm->napi); ++ apm_dma_free(apm); ++ free_netdev(apm->net_dev); ++} ++ ++/************************************************** ++ * Platform related code ++ **************************************************/ ++static int apm_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ struct apm *apm; ++ struct resource *regs; ++ const u8 *mac_addr; ++ const char *pm_type; ++ u32 value; ++ ++ apm = devm_kzalloc(&pdev->dev, sizeof(*apm), GFP_KERNEL); ++ if (!apm) { ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(pdev, apm); ++ ++ /* Set the features */ ++ apm->feature_flags |= APM_FEAT_TX_MASK_SETUP; ++ apm->feature_flags |= APM_FEAT_RX_MASK_SETUP; ++ ++ apm->dev = &pdev->dev; ++ apm->dma_dev = &pdev->dev; ++ ++ mac_addr = of_get_mac_address(np); ++ if (mac_addr) ++ ether_addr_copy(apm->mac_addr, mac_addr); ++ else ++ dev_warn(&pdev->dev, "MAC address not present in device tree\n"); ++ ++ apm->irq0 = platform_get_irq(pdev, 0); ++ if (apm->irq0 < 0) { ++ dev_err(&pdev->dev, "Unable to obtain IRQ 0\n"); ++ return apm->irq0; ++ } ++ apm->irq1 = platform_get_irq(pdev, 1); ++ if (apm->irq1 < 0) { ++ dev_err(&pdev->dev, "Unable to obtain IRQ 1\n"); ++ return apm->irq1; ++ } ++ apm->irq2 = platform_get_irq(pdev, 2); ++ if (apm->irq2 < 0) { ++ dev_err(&pdev->dev, "Unable to obtain IRQ 2\n"); ++ return apm->irq2; ++ } ++ ++ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apm_base"); ++ if (!regs) { ++ dev_err(&pdev->dev, "Unable to obtain base resource\n"); ++ return -EINVAL; ++ } ++ ++ apm->plat.base = devm_ioremap_resource(&pdev->dev, regs); ++ if (IS_ERR(apm->plat.base)) ++ return PTR_ERR(apm->plat.base); ++ ++ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "idm_base"); ++ if (!regs) { ++ dev_err(&pdev->dev, "Unable to obtain idm resource\n"); ++ return -EINVAL; ++ } ++ ++ apm->plat.idm_base = devm_ioremap_resource(&pdev->dev, regs); ++ if (IS_ERR(apm->plat.idm_base)) { ++ return PTR_ERR(apm->plat.idm_base); ++ } ++ ++ /* Get TX queue number and QoS mode from DTS file */ ++ if (of_property_read_u32(np, "tx-channels", &value)) { ++ /* Set the default TX channel number */ ++ apm->tx_channel = 1; ++ } else { ++ apm->tx_channel = value; ++ if (value == 0) { ++ apm->tx_channel = 1; ++ } else if (value > APM_MAX_TX_RINGS) { ++ apm->tx_channel = APM_MAX_TX_RINGS; ++ } ++ } ++ ++ if (of_property_read_u32(np, "strict-mode", &value)) { ++ /* Set the default strict mode */ ++ apm->strict_mode = true; ++ } else { ++ apm->strict_mode = true; ++ if (value == 0) { ++ apm->strict_mode = false; ++ } ++ } ++ ++ /* Get lane index in PM */ ++ if (of_property_read_u32(np, "land-idx", &value)) { ++ dev_err(&pdev->dev, "Unable to get the PM land index\n"); ++ return -EINVAL; ++ } ++ apm->land_idx = value; ++ ++ /* Get the PM type */ ++ if (of_property_read_string(np, "pm-type", &pm_type)) { ++ dev_err(&pdev->dev, "Unable to get the PM type\n"); ++ return -EINVAL; ++ } ++ ++ if (!strcmp(pm_type, "pm4x10")) { ++ //pm4x10_pm_init(apm->pm_ops); ++ apm->pm_ops = kmalloc(sizeof(struct iproc_pm_ops), GFP_KERNEL); ++ apm->pm_ops->port_enable= pm4x10_pm_xlport_port_config; ++ apm->pm_ops->port_speed = pm4x10_xlport_speed_set; ++ apm->pm_ops->port_loopback = pm4x10_xlport_loopback_set; ++ apm->pm_ops->port_mac_addr = pm4x10_xlport_mac_addr_set; ++ apm->pm_ops->port_stats = pm4x10_xlport_stats_get; ++ apm->pm_ops->port_stats_clear = pm4x10_xlport_mib_reset; ++ pm4x10_pm_init(apm->pm_ops, apm->land_idx); ++ ++ } else { ++ dev_err(&pdev->dev, "Unknown the PM type - %s\n", pm_type); ++ return -EINVAL; ++ } ++ ++ return apm_enet_probe(apm); ++} ++ ++static int apm_remove(struct platform_device *pdev) ++{ ++ struct apm *apm = platform_get_drvdata(pdev); ++ ++ //pm4x10_pm_deinit(apm->pm_ops); ++ kfree(apm->pm_ops); ++ apm->pm_ops = NULL; ++ pm4x10_pm_deinit(apm->pm_ops); ++ apm_enet_remove(apm); ++ ++ return 0; ++} ++ ++static const struct of_device_id apm_of_enet_match[] = { ++ {.compatible = "brcm,xgs-iproc-apm",}, ++ {.compatible = "brcm,xgs-iproc-apm,hx5",}, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, apm_of_enet_match); ++ ++static struct platform_driver apm_enet_driver = { ++ .driver = { ++ .name = "apm-enet", ++ .of_match_table = apm_of_enet_match, ++ }, ++ .probe = apm_probe, ++ .remove = apm_remove, ++}; ++ ++module_platform_driver(apm_enet_driver); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/apm.h b/drivers/net/ethernet/broadcom/apm.h +--- a/drivers/net/ethernet/broadcom/apm.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/apm.h 2018-05-30 15:50:51.028753148 +0800 +@@ -0,0 +1,617 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++#ifndef _APM_H ++#define _APM_H ++ ++#include ++ ++#define APM_DEV_CTL 0x000 ++//#define APM_DC_TSM 0x00000002 ++#define APM_DC_TSM 0x00000001 ++#define APM_DC_ROCS 0x00000002 ++#define APM_DC_CFCO 0x00000004 ++//#define APM_DC_MROR 0x00000010 ++//#define APM_DC_RLSS   0x00000008 ++#define APM_DC_FCM_MASK 0x00000060 ++#define APM_DC_FCM_SHIFT 5 ++//#define APM_DC_NAE 0x00000080 ++//#define APM_DC_TF 0x00000100 ++//#define APM_DC_RDS_MASK 0x00030000 ++//#define APM_DC_RDS_SHIFT 16 ++//#define APM_DC_TDS_MASK 0x000c0000 ++//#define APM_DC_TDS_SHIFT 18 ++ ++#define APM_DEV_STATUS 0x004 /* Configuration of the interface */ ++#define APM_DS_RBF 0x00000001 ++#define APM_DS_RDF 0x00000002 ++#define APM_DS_RIF 0x00000004 ++//#define APM_DS_TBF 0x00000008 ++#define APM_DS_TDF 0x00000010 ++//#define APM_DS_TIF 0x00000020 ++#define APM_DS_PO 0x00000040 ++//#define APM_DS_MM_MASK 0x00000300 /* Mode of the interface */ ++//#define APM_DS_MM_SHIFT 8 ++#define APM_DS_RQS_MASK 0x000f0000 ++#define APM_DS_RQS_SHIFT 16 ++#define APM_DS_TQS_MASK 0x00f00000 ++#define APM_DS_TQS_SHIFT 20 ++#define APM_DS_TOC_MASK 0x3f000000 ++#define APM_DS_TOC_SHIFT 24 ++ ++//#define APM_BIST_STATUS 0x00c ++ ++#define APM_DATA_SWAP_CTL 0x010 ++#define APM_DSC_TBSWD 0x00000001 ++#define APM_DSC_TDS 0x00000002 ++#define APM_DSC_RBSWD 0x00000004 ++#define APM_DSC_RDS 0x00000008 ++ ++#define APM_ERROR_STATIS 0x014 ++#define APM_ES_DESC_READ_ERR_TC0 0x00000001 ++#define APM_ES_DESC_READ_ERR_TC1 0x00000002 ++#define APM_ES_DESC_READ_ERR_TC2 0x00000004 ++#define APM_ES_DESC_READ_ERR_TC3 0x00000008 ++#define APM_ES_DESC_READ_ERR_RC0 0x00000010 ++#define APM_ES_DATA_ERR_TC0 0x00000100 ++#define APM_ES_DATA_ERR_TC1 0x00000200 ++#define APM_ES_DATA_ERR_TC2 0x00000400 ++#define APM_ES_DATA_ERR_TC3 0x00000800 ++#define APM_ES_DATA_ERR_RC0 0x00001000 ++#define APM_ES_DESC_PROT_ERR_TC0 0x00010000 ++#define APM_ES_DESC_PROT_ERR_TC1 0x00020000 ++#define APM_ES_DESC_PROT_ERR_TC2 0x00040000 ++#define APM_ES_DESC_PROT_ERR_TC3 0x00080000 ++#define APM_ES_DESC_PROT_ERR_RC0 0x00100000 ++ ++#define APM_INT_STATUS 0x020 /* Interrupt status */ ++//#define APM_IS_MRO 0x00000001 ++//#define APM_IS_MTO 0x00000002 ++//#define APM_IS_TFD 0x00000004 ++//#define APM_IS_LS 0x00000008 ++//#define APM_IS_MDIO 0x00000010 ++//#define APM_IS_MR 0x00000020 ++//#define APM_IS_MT 0x00000040 ++#define APM_IS_TO 0x00000080 /* Timeout */ ++#define APM_IS_SL_SC 0x00000100 /* Software link status change */ ++#define APM_IS_PM_LS 0x00000200 /* Port Macro link status */ ++#define APM_IS_DESC_ERR 0x00000400 /* Descriptor error */ ++#define APM_IS_DATA_ERR 0x00000800 /* Data error */ ++#define APM_IS_DESC_PROT_ERR 0x00001000 /* Descriptor protocol error */ ++#define APM_IS_RX_DESC_UNDERF 0x00002000 /* Receive descriptor underflow */ ++#define APM_IS_RX_F_OVERF 0x00004000 /* Receive FIFO overflow */ ++//#define APM_IS_TX_F_UNDERF 0x00008000 /* Transmit FIFO underflow */ ++#define APM_IS_RX 0x00010000 /* Interrupt for RX queue 0 */ ++#define APM_IS_RX_INFO_ECC_CORR 0x00100000 /* RXQ info memory corrected error */ ++#define APM_IS_RX_INFO_ECC_UNCORR 0x00200000 /* RXQ info memory uncorrected error */ ++#define APM_IS_AXI_SHARED_ECC_CORR 0x00400000 /* AXI share memory corrected error */ ++#define APM_IS_AXI_SHARED_ECC_UNCORR 0x00800000 /* AXI share memory uncorrected error */ ++#define APM_IS_TX0 0x01000000 /* Interrupt for TX queue 0 */ ++#define APM_IS_TX1 0x02000000 /* Interrupt for TX queue 1 */ ++#define APM_IS_TX2 0x04000000 /* Interrupt for TX queue 2 */ ++#define APM_IS_TX3 0x08000000 /* Interrupt for TX queue 3 */ ++#define APM_IS_ECC_MASK 0x00f00000 ++#define APM_IS_TX_MASK 0x0f000000 ++//#define APM_IS_INTMASK 0x0f01fcff ++#define APM_IS_INTMASK 0x0ff17f80 ++//#define APM_IS_ERRMASK 0x0000fc00 ++#define APM_IS_ERRMASK 0x00007c00 ++ ++#define APM_INT_MASK 0x024 /* Interrupt mask */ ++#define APM_GP_TIMER 0x028 ++ ++#define APM_TXQ_COMMON_CTL 0x040 ++#define APM_TCCTL_FLUSH_CREDIT 0x00000001 ++#define APM_TCCTL_FUNC_MODE_MASK 0x00000006 ++#define APM_TCCTL_FUNC_MODE_SHIFT 1 ++#define APM_FUNC_MODE_SINGLE 0 ++#define APM_FUNC_MODE_DUAL 1 ++#define APM_FUNC_MODE_QUAD 2 ++#define APM_TCCTL_WR_FUNC_MODE 0x00000008 ++#define APM_TCCTL_INTERRUPT_SEL 0x00000010 ++ ++#define APM_TXQ_DATA_TXREQ_CTL0 0x044 ++#define APM_TXQ_DATA_TXREQ_CTL1 0x048 ++#define APM_TXQ_SHARED_BUF_DEPTH0 0x050 ++#define APM_TXQ_SHARED_BUF_DEPTH1 0x054 ++#define APM_RXQ_BUF_DEPTH 0x058 ++#define APM_DMA_TOTAL_OUTSTD_TRANS_LIMIT 0x080 ++#define APM_DMA_RD_PER_ID_OUTSTD_TRANS_LIMIT 0x084 ++#define APM_PKT_DMA_RD_AXI_MAP_CTRL 0x088 ++#define APM_RX_PKT_DMA_WR_AXI_MAP_CTRL 0x08c ++#define APM_TX_PKT_DMA_RD_ARB_CTRL 0x090 ++#define APM_RX_PKT_DMA_RD_ARB_CTRL 0x094 ++#define APM_RX_PKT_DMA_WR_ARB_CTRL 0x098 ++#define APM_RCBUF_MAX_FLIST_ENTRIES 0x09c ++#define APM_STAT_COUNTER_CTL 0x0a0 ++#define APM_STAT_RXQ_TRANSFERRED_PKT_CNT 0x0b0 ++#define APM_STAT_RXQ_COMPLETE_PKT_DROP_CNT 0x0b4 ++#define APM_STAT_RXQ_PARTIAL_PKT_DROP_CNT 0x0b8 ++#define APM_STAT_RXQ_TRUNCATED_PKT_CNT 0x0bc ++#define APM_STAT_TXQ_CH0_GOOD_PKT_CNT 0x0c0 ++#define APM_STAT_TXQ_CH0_ERR_PKT_CNT 0x0c4 ++#define APM_STAT_TXQ_CH1_GOOD_PKT_CNT 0x0c8 ++#define APM_STAT_TXQ_CH1_ERR_PKT_CNT 0x0cc ++#define APM_STAT_TXQ_CH2_GOOD_PKT_CNT 0x0d0 ++#define APM_STAT_TXQ_CH2_ERR_PKT_CNT 0x0d4 ++#define APM_STAT_TXQ_CH3_GOOD_PKT_CNT 0x0d8 ++#define APM_STAT_TXQ_CH3_ERR_PKT_CNT 0x0dc ++#define APM_DBG_TXQ_CH0_STM 0x0e0 ++#define APM_DBG_TXQ_CH1_STM 0x0e4 ++#define APM_DBG_TXQ_CH2_STM 0x0e8 ++#define APM_DBG_TXQ_CH3_STM 0x0ec ++#define APM_DBG_RXQ_STM 0x0f0 ++#define APM_DBG_DMA_HOSTRD_STM 0x0f8 ++#define APM_DBG_DMA_HOSTWR_STM 0x0fc ++ ++#define APM_INT_RECV_LAZY 0x100 ++#define APM_IRL_TO_MASK 0x00ffffff ++#define APM_IRL_TO_SHIFT 0 ++#define APM_IRL_FC_MASK 0xff000000 ++#define APM_IRL_FC_SHIFT 24 /* Shift the number of interrupts triggered per received frame */ ++#define APM_FLOW_CTL_THRESH 0x104 /* Flow control thresholds */ ++#define APM_WRRTHRESH 0x108 ++//#define APM_GMAC_IDLE_CNT_THRESH 0x10c ++//#define APM_PHY_ACCESS 0x180 /* PHY access address */ ++//#define APM_PA_DATA_MASK 0x0000ffff ++//#define APM_PA_ADDR_MASK 0x001f0000 ++//#define APM_PA_ADDR_SHIFT 16 ++//#define APM_PA_REG_MASK 0x1f000000 ++//#define APM_PA_REG_SHIFT 24 ++//#define APM_PA_WRITE 0x20000000 ++//#define APM_PA_START 0x40000000 ++//#define APM_PHY_CNTL 0x188 /* PHY control address */ ++//#define APM_PC_EPA_MASK 0x0000001f ++//#define APM_PC_MCT_MASK 0x007f0000 ++//#define APM_PC_MCT_SHIFT 16 ++//#define APM_PC_MTE 0x00800000 ++//#define APM_TXQ_CTL 0x18c ++//#define APM_TXQ_CTL_DBT_MASK 0x00000fff ++//#define APM_TXQ_CTL_DBT_SHIFT 0 ++#define APM_RXQ_CTL 0x190 ++//#define APM_RXQ_CTL_DBT_MASK 0x00000fff ++#define APM_RXQ_CTL_DBT_MASK 0x00000f7ff ++#define APM_RXQ_CTL_DBT_SHIFT 0 ++//#define APM_RXQ_CTL_PTE 0x00001000 ++//#define APM_RXQ_CTL_MDP_MASK 0x3f000000 ++//#define APM_RXQ_CTL_MDP_SHIFT 24 ++#define APM_RXQ_CTL_RPT_EN 0x40000000 ++ ++//#define APM_GPIO_SELECT 0x194 ++//#define APM_GPIO_OUTPUT_EN 0x198 ++ ++///* For 0x1e0 see BCMA_CLKCTLST. Below are APM specific bits */ ++//#define APM_BCMA_CLKCTLST_MISC_PLL_REQ 0x00000100 ++//#define APM_BCMA_CLKCTLST_MISC_PLL_ST 0x01000000 ++ ++//#define APM_HW_WAR 0x1e4 ++//#define APM_PWR_CTL 0x1e8 ++ ++#define APM_MEM_ECC_CTL 0x1F0 ++#define APM_MEM_ECC_STAT 0x1F4 ++ ++#define APM_DMA_BASE0 0x200 /* Tx and Rx controller */ ++#define APM_DMA_BASE1 0x240 /* Tx controller only */ ++#define APM_DMA_BASE2 0x280 /* Tx controller only */ ++#define APM_DMA_BASE3 0x2C0 /* Tx controller only */ ++ ++//#define APM_TX_GOOD_OCTETS 0x300 ++//#define APM_TX_GOOD_OCTETS_HIGH 0x304 ++//#define APM_TX_GOOD_PKTS 0x308 ++//#define APM_TX_OCTETS 0x30c ++//#define APM_TX_OCTETS_HIGH 0x310 ++//#define APM_TX_PKTS 0x314 ++//#define APM_TX_BROADCAST_PKTS 0x318 ++//#define APM_TX_MULTICAST_PKTS 0x31c ++//#define APM_TX_LEN_64 0x320 ++//#define APM_TX_LEN_65_TO_127 0x324 ++//#define APM_TX_LEN_128_TO_255 0x328 ++//#define APM_TX_LEN_256_TO_511 0x32c ++//#define APM_TX_LEN_512_TO_1023 0x330 ++//#define APM_TX_LEN_1024_TO_1522 0x334 ++//#define APM_TX_LEN_1523_TO_2047 0x338 ++//#define APM_TX_LEN_2048_TO_4095 0x33c ++//#define APM_TX_LEN_4096_TO_8191 0x340 ++//#define APM_TX_LEN_8192_TO_MAX 0x344 ++//#define APM_TX_JABBER_PKTS 0x348 /* Error */ ++//#define APM_TX_OVERSIZE_PKTS 0x34c /* Error */ ++//#define APM_TX_FRAGMENT_PKTS 0x350 ++//#define APM_TX_UNDERRUNS 0x354 /* Error */ ++//#define APM_TX_TOTAL_COLS 0x358 ++//#define APM_TX_SINGLE_COLS 0x35c ++//#define APM_TX_MULTIPLE_COLS 0x360 ++//#define APM_TX_EXCESSIVE_COLS 0x364 /* Error */ ++//#define APM_TX_LATE_COLS 0x368 /* Error */ ++//#define APM_TX_DEFERED 0x36c ++//#define APM_TX_CARRIER_LOST 0x370 ++//#define APM_TX_PAUSE_PKTS 0x374 ++//#define APM_TX_UNI_PKTS 0x378 ++//#define APM_TX_Q0_PKTS 0x37c ++//#define APM_TX_Q0_OCTETS 0x380 ++//#define APM_TX_Q0_OCTETS_HIGH 0x384 ++//#define APM_TX_Q1_PKTS 0x388 ++//#define APM_TX_Q1_OCTETS 0x38c ++//#define APM_TX_Q1_OCTETS_HIGH 0x390 ++//#define APM_TX_Q2_PKTS 0x394 ++//#define APM_TX_Q2_OCTETS 0x398 ++//#define APM_TX_Q2_OCTETS_HIGH 0x39c ++//#define APM_TX_Q3_PKTS 0x3a0 ++//#define APM_TX_Q3_OCTETS 0x3a4 ++//#define APM_TX_Q3_OCTETS_HIGH 0x3a8 ++//#define APM_RX_GOOD_OCTETS 0x3b0 ++//#define APM_RX_GOOD_OCTETS_HIGH 0x3b4 ++//#define APM_RX_GOOD_PKTS 0x3b8 ++//#define APM_RX_OCTETS 0x3bc ++//#define APM_RX_OCTETS_HIGH 0x3c0 ++//#define APM_RX_PKTS 0x3c4 ++//#define APM_RX_BROADCAST_PKTS 0x3c8 ++//#define APM_RX_MULTICAST_PKTS 0x3cc ++//#define APM_RX_LEN_64 0x3d0 ++//#define APM_RX_LEN_65_TO_127 0x3d4 ++//#define APM_RX_LEN_128_TO_255 0x3d8 ++//#define APM_RX_LEN_256_TO_511 0x3dc ++//#define APM_RX_LEN_512_TO_1023 0x3e0 ++//#define APM_RX_LEN_1024_TO_1522 0x3e4 ++//#define APM_RX_LEN_1523_TO_2047 0x3e8 ++//#define APM_RX_LEN_2048_TO_4095 0x3ec ++//#define APM_RX_LEN_4096_TO_8191 0x3f0 ++//#define APM_RX_LEN_8192_TO_MAX 0x3f4 ++//#define APM_RX_JABBER_PKTS 0x3f8 /* Error */ ++//#define APM_RX_OVERSIZE_PKTS 0x3fc /* Error */ ++//#define APM_RX_FRAGMENT_PKTS 0x400 ++//#define APM_RX_MISSED_PKTS 0x404 /* Error */ ++//#define APM_RX_CRC_ALIGN_ERRS 0x408 /* Error */ ++//#define APM_RX_UNDERSIZE 0x40c /* Error */ ++//#define APM_RX_CRC_ERRS 0x410 /* Error */ ++//#define APM_RX_ALIGN_ERRS 0x414 /* Error */ ++//#define APM_RX_SYMBOL_ERRS 0x418 /* Error */ ++//#define APM_RX_PAUSE_PKTS 0x41c ++//#define APM_RX_NONPAUSE_PKTS 0x420 ++//#define APM_RX_SACHANGES 0x424 ++//#define APM_RX_UNI_PKTS 0x428 ++//#define APM_UNIMAC_VERSION 0x800 ++//#define APM_HDBKP_CTL 0x804 ++//#define APM_CMDCFG 0x808 /* Configuration */ ++//#define APM_CMDCFG_TE 0x00000001 /* Set to activate TX */ ++//#define APM_CMDCFG_RE 0x00000002 /* Set to activate RX */ ++//#define APM_CMDCFG_ES_MASK 0x0000000c /* Ethernet speed see gmac_speed */ ++//#define APM_CMDCFG_ES_10 0x00000000 ++//#define APM_CMDCFG_ES_100 0x00000004 ++//#define APM_CMDCFG_ES_1000 0x00000008 ++//#define APM_CMDCFG_ES_2500 0x0000000C ++//#define APM_CMDCFG_PROM 0x00000010 /* Set to activate promiscuous mode */ ++//#define APM_CMDCFG_PAD_EN 0x00000020 ++//#define APM_CMDCFG_CF 0x00000040 ++//#define APM_CMDCFG_PF 0x00000080 ++//#define APM_CMDCFG_RPI 0x00000100 /* Unset to enable 802.3x tx flow control */ ++//#define APM_CMDCFG_TAI 0x00000200 ++//#define APM_CMDCFG_HD 0x00000400 /* Set if in half duplex mode */ ++//#define APM_CMDCFG_HD_SHIFT 10 ++//#define APM_CMDCFG_SR_REV0 0x00000800 /* Set to reset mode, for core rev 0-3 */ ++//#define APM_CMDCFG_SR_REV4 0x00002000 /* Set to reset mode, for core rev >= 4 */ ++//#define APM_CMDCFG_ML 0x00008000 /* Set to activate mac loopback mode */ ++//#define APM_CMDCFG_AE 0x00400000 ++//#define APM_CMDCFG_CFE 0x00800000 ++//#define APM_CMDCFG_NLC 0x01000000 ++//#define APM_CMDCFG_RL 0x02000000 ++//#define APM_CMDCFG_RED 0x04000000 ++//#define APM_CMDCFG_PE 0x08000000 ++//#define APM_CMDCFG_TPI 0x10000000 ++//#define APM_CMDCFG_AT 0x20000000 ++//#define APM_MACADDR_HIGH 0x80c /* High 4 octets of own mac address */ ++//#define APM_MACADDR_LOW 0x810 /* Low 2 octets of own mac address */ ++//#define APM_RXMAX_LENGTH 0x814 /* Max receive frame length with vlan tag */ ++//#define APM_PAUSEQUANTA 0x818 ++//#define APM_MAC_MODE 0x844 ++//#define APM_OUTERTAG 0x848 ++//#define APM_INNERTAG 0x84c ++//#define APM_TXIPG 0x85c ++//#define APM_PAUSE_CTL 0xb30 ++//#define APM_TX_FLUSH 0xb34 ++//#define APM_RX_STATUS 0xb38 ++//#define APM_TX_STATUS 0xb3c ++// ++///* BCMA GMAC core specific IO Control (BCMA_IOCTL) flags */ ++//#define APM_BCMA_IOCTL_SW_CLKEN 0x00000004 /* PHY Clock Enable */ ++//#define APM_BCMA_IOCTL_SW_RESET 0x00000008 /* PHY Reset */ ++// ++///* BCMA GMAC core specific IO status (BCMA_IOST) flags */ ++//#define APM_BCMA_IOST_ATTACHED 0x00000800 ++// ++//#define APM_NUM_MIB_TX_REGS (((APM_TX_Q3_OCTETS_HIGH - APM_TX_GOOD_OCTETS) / 4) + 1) ++//#define APM_NUM_MIB_RX_REGS (((APM_RX_UNI_PKTS - APM_RX_GOOD_OCTETS) / 4) + 1) ++ ++#define APM_DMA_TX_CTL 0x00 ++#define APM_DMA_TX_ENABLE 0x00000001 ++#define APM_DMA_TX_SUSPEND 0x00000002 ++//#define APM_DMA_TX_LOOPBACK 0x00000004 ++//#define APM_DMA_TX_FLUSH 0x00000010 ++//#define APM_DMA_TX_MR_MASK 0x000000C0 /* Multiple outstanding reads */ ++//#define APM_DMA_TX_MR_SHIFT 6 ++//#define APM_DMA_TX_MR_1 0 ++//#define APM_DMA_TX_MR_2 1 ++//#define APM_DMA_TX_PARITY_DISABLE 0x00000800 ++#define APM_DMA_TX_SBAI 0x00002000 ++//#define APM_DMA_TX_ADDREXT_MASK 0x00030000 ++//#define APM_DMA_TX_ADDREXT_SHIFT 16 ++#define APM_DMA_TX_BL_MASK 0x001C0000 /* BurstLen bits */ ++#define APM_DMA_TX_BL_SHIFT 18 ++#define APM_DMA_TX_BL_16 0 ++#define APM_DMA_TX_BL_32 1 ++#define APM_DMA_TX_BL_64 2 ++#define APM_DMA_TX_BL_128 3 ++//#define APM_DMA_TX_BL_256 4 ++//#define APM_DMA_TX_BL_512 5 ++//#define APM_DMA_TX_BL_1024 6 ++#define APM_DMA_TX_PC_MASK 0x00E00000 /* Prefetch control */ ++#define APM_DMA_TX_PC_SHIFT 21 ++#define APM_DMA_TX_PC_0 0 ++#define APM_DMA_TX_PC_4 1 ++#define APM_DMA_TX_PC_8 2 ++#define APM_DMA_TX_PC_16 3 ++#define APM_DMA_TX_PT_MASK 0x03000000 /* Prefetch threshold */ ++#define APM_DMA_TX_PT_SHIFT 24 ++#define APM_DMA_TX_PT_1 0 ++#define APM_DMA_TX_PT_2 1 ++#define APM_DMA_TX_PT_4 2 ++#define APM_DMA_TX_PT_8 3 ++ ++#define APM_DMA_TX_INDEX 0x04 ++#define APM_DMA_TX_RINGLO 0x08 ++#define APM_DMA_TX_RINGHI 0x0C ++#define APM_DMA_TX_STATUS 0x10 ++#define APM_DMA_TX_STATDPTR 0x00001FFF ++#define APM_DMA_TX_STAT 0xF0000000 ++#define APM_DMA_TX_STAT_DISABLED 0x00000000 ++#define APM_DMA_TX_STAT_ACTIVE 0x10000000 ++#define APM_DMA_TX_STAT_IDLEWAIT 0x20000000 ++#define APM_DMA_TX_STAT_STOPPED 0x30000000 ++#define APM_DMA_TX_STAT_SUSP 0x40000000 ++#define APM_DMA_TX_ERROR 0x14 ++#define APM_DMA_TX_ERRDPTR 0x0001FFFF ++#define APM_DMA_TX_ERR 0xF0000000 ++#define APM_DMA_TX_ERR_NOERR 0x00000000 ++#define APM_DMA_TX_ERR_PROT 0x10000000 ++//#define APM_DMA_TX_ERR_UNDERRUN 0x20000000 ++#define APM_DMA_TX_ERR_TRANSFER 0x30000000 ++#define APM_DMA_TX_ERR_DESCREAD 0x40000000 ++#define APM_DMA_TX_ERR_CORE 0x50000000 ++ ++#define APM_DMA_RX_CTL 0x20 ++#define APM_DMA_RX_ENABLE 0x00000001 ++#define APM_DMA_RX_FRAME_OFFSET_MASK 0x000000FE ++#define APM_DMA_RX_FRAME_OFFSET_SHIFT 1 ++//#define APM_DMA_RX_DIRECT_FIFO 0x00000100 ++#define APM_DMA_RX_OVERFLOW_CONT 0x00000400 ++//#define APM_DMA_RX_PARITY_DISABLE 0x00000800 ++//#define APM_DMA_RX_MR_MASK 0x000000C0 /* Multiple outstanding reads */ ++//#define APM_DMA_RX_MR_SHIFT 6 ++//#define APM_DMA_TX_MR_1 0 ++//#define APM_DMA_TX_MR_2 1 ++//#define APM_DMA_RX_ADDREXT_MASK 0x00030000 ++//#define APM_DMA_RX_ADDREXT_SHIFT 16 ++#define APM_DMA_RX_BL_MASK 0x001C0000 /* BurstLen bits */ ++#define APM_DMA_RX_BL_SHIFT 18 ++#define APM_DMA_RX_BL_16 0 ++#define APM_DMA_RX_BL_32 1 ++#define APM_DMA_RX_BL_64 2 ++#define APM_DMA_RX_BL_128 3 ++//#define APM_DMA_RX_BL_256 4 ++//#define APM_DMA_RX_BL_512 5 ++//#define APM_DMA_RX_BL_1024 6 ++#define APM_DMA_RX_PC_MASK 0x00E00000 /* Prefetch control */ ++#define APM_DMA_RX_PC_SHIFT 21 ++#define APM_DMA_RX_PC_0 0 ++#define APM_DMA_RX_PC_4 1 ++#define APM_DMA_RX_PC_8 2 ++#define APM_DMA_RX_PC_16 3 ++#define APM_DMA_RX_PT_MASK 0x03000000 /* Prefetch threshold */ ++#define APM_DMA_RX_PT_SHIFT 24 ++#define APM_DMA_RX_PT_1 0 ++#define APM_DMA_RX_PT_2 1 ++#define APM_DMA_RX_PT_4 2 ++#define APM_DMA_RX_PT_8 3 ++#define APM_DMA_RX_INDEX 0x24 ++#define APM_DMA_RX_RINGLO 0x28 ++#define APM_DMA_RX_RINGHI 0x2C ++#define APM_DMA_RX_STATUS 0x30 ++#define APM_DMA_RX_STATDPTR 0x00001FFF ++#define APM_DMA_RX_STAT 0xF0000000 ++#define APM_DMA_RX_STAT_DISABLED 0x00000000 ++#define APM_DMA_RX_STAT_ACTIVE 0x10000000 ++#define APM_DMA_RX_STAT_IDLEWAIT 0x20000000 ++#define APM_DMA_RX_STAT_STOPPED 0x30000000 ++//#define APM_DMA_RX_STAT_SUSP 0x40000000 ++#define APM_DMA_RX_ERROR 0x34 ++#define APM_DMA_RX_ERRDPTR 0x0001FFFF ++#define APM_DMA_RX_ERR 0xF0000000 ++#define APM_DMA_RX_ERR_NOERR 0x00000000 ++#define APM_DMA_RX_ERR_PROT 0x10000000 ++#define APM_DMA_RX_ERR_UNDERRUN 0x20000000 ++#define APM_DMA_RX_ERR_TRANSFER 0x30000000 ++#define APM_DMA_RX_ERR_DESCREAD 0x40000000 ++#define APM_DMA_RX_ERR_CORE 0x50000000 ++ ++ ++ ++ ++ ++ ++#define APM_DESC_CTL0_CRC 0x00300000 /* CRC mode */ ++#define APM_DESC_CRC_APPEND 0x00000000 /* CRC append mode */ ++#define APM_DESC_CRC_OVERWRITE 0x00100000 /* CRC overwrite mode */ ++#define APM_DESC_CRC_FORWARD 0x00200000 /* CRC forward mode */ ++#define APM_DESC_CTL0_EOT 0x10000000 /* End of ring */ ++#define APM_DESC_CTL0_IOC 0x20000000 /* IRQ on complete */ ++#define APM_DESC_CTL0_EOF 0x40000000 /* End of frame */ ++#define APM_DESC_CTL0_SOF 0x80000000 /* Start of frame */ ++//#define APM_DESC_CTL1_LEN 0x00001FFF ++#define APM_DESC_CTL1_LEN 0x00007FFF ++ ++//#define APM_PHY_NOREGS BRCM_PSEUDO_PHY_ADDR ++//#define APM_PHY_MASK 0x1F ++ ++#define APM_MAX_TX_RINGS 4 ++#define APM_MAX_RX_RINGS 1 ++#define APM_TX_MAX_DESCS 512 ++#define APM_RX_MAX_DESCS 512 ++ ++#define APM_RX_HEADER_LEN 28 /* Last 24 bytes are unused. Well... */ ++#define APM_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */ ++#define APM_RX_BUF_OFFSET (NET_SKB_PAD + NET_IP_ALIGN - APM_RX_FRAME_OFFSET) ++#define APM_RX_MAX_FRAME_SIZE 1536 /* Copied from b44/tg3 */ ++#define APM_RX_BUF_SIZE (APM_RX_FRAME_OFFSET + APM_RX_MAX_FRAME_SIZE) ++#define APM_RX_ALLOC_SIZE (SKB_DATA_ALIGN(APM_RX_BUF_SIZE + APM_RX_BUF_OFFSET) + \ ++ SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) ++ ++//#define APM_BFL_ENETROBO 0x0010 /* has ephy roboswitch spi */ ++//#define APM_BFL_ENETADM 0x0080 /* has ADMtek switch */ ++//#define APM_BFL_ENETVLAN 0x0100 /* can do vlan */ ++ ++//#define APM_CHIPCTL_1_IF_TYPE_MASK 0x00000030 ++//#define APM_CHIPCTL_1_IF_TYPE_RMII 0x00000000 ++//#define APM_CHIPCTL_1_IF_TYPE_MII 0x00000010 ++//#define APM_CHIPCTL_1_IF_TYPE_RGMII 0x00000020 ++//#define APM_CHIPCTL_1_SW_TYPE_MASK 0x000000C0 ++//#define APM_CHIPCTL_1_SW_TYPE_EPHY 0x00000000 ++//#define APM_CHIPCTL_1_SW_TYPE_EPHYMII 0x00000040 ++//#define APM_CHIPCTL_1_SW_TYPE_EPHYRMII 0x00000080 ++//#define APM_CHIPCTL_1_SW_TYPE_RGMII 0x000000C0 ++//#define APM_CHIPCTL_1_RXC_DLL_BYPASS 0x00010000 ++// ++//#define APM_CHIPCTL_4_IF_TYPE_MASK 0x00003000 ++//#define APM_CHIPCTL_4_IF_TYPE_RMII 0x00000000 ++//#define APM_CHIPCTL_4_IF_TYPE_MII 0x00001000 ++//#define APM_CHIPCTL_4_IF_TYPE_RGMII 0x00002000 ++//#define APM_CHIPCTL_4_SW_TYPE_MASK 0x0000C000 ++//#define APM_CHIPCTL_4_SW_TYPE_EPHY 0x00000000 ++//#define APM_CHIPCTL_4_SW_TYPE_EPHYMII 0x00004000 ++//#define APM_CHIPCTL_4_SW_TYPE_EPHYRMII 0x00008000 ++//#define APM_CHIPCTL_4_SW_TYPE_RGMII 0x0000C000 ++// ++//#define APM_CHIPCTL_7_IF_TYPE_MASK 0x000000C0 ++//#define APM_CHIPCTL_7_IF_TYPE_RMII 0x00000000 ++//#define APM_CHIPCTL_7_IF_TYPE_MII 0x00000040 ++//#define APM_CHIPCTL_7_IF_TYPE_RGMII 0x00000080 ++ ++#define APM_WEIGHT 64 ++#define ETHER_MAX_LEN 1518 ++ ++/* Feature flags */ ++#define APM_FEAT_TX_MASK_SETUP BIT(0) ++#define APM_FEAT_RX_MASK_SETUP BIT(1) ++ ++/* Loopback flags */ ++#define APM_LOOPBACK_TYPE_NONE 0 ++#define APM_LOOPBACK_TYPE_MAC 1 ++#define APM_LOOPBACK_TYPE_PHY 2 ++ ++struct apm_slot_info { ++ union { ++ struct sk_buff *skb; ++ void *buf; ++ }; ++ dma_addr_t dma_addr; ++}; ++ ++struct apm_dma_desc { ++ __le32 ctl0; ++ __le32 ctl1; ++ __le32 addr_low; ++ __le32 addr_high; ++} __packed; ++ ++enum apm_dma_ring_type { ++ APM_DMA_RING_TYPE_TX = 0, ++ APM_DMA_RING_TYPE_RX, ++ APM_DMA_RING_TYPE_NUM ++}; ++ ++/** ++ * apm_dma_ring - contains info about DMA ring (either TX or RX one) ++ * @start: index of the first slot containing data ++ * @end: index of a slot that can *not* be read (yet) ++ * ++ * Be really aware of the specific @end meaning. It's an index of a slot *after* ++ * the one containing data that can be read. If @start equals @end the ring is ++ * empty. ++ */ ++struct apm_dma_ring { ++ u32 start; ++ u32 end; ++ ++ int desc_num; ++ struct apm_dma_desc *desc_base; ++ dma_addr_t dma_base; ++ u32 index_base; /* Used for unaligned rings only, otherwise 0 */ ++ u16 mmio_base; ++ bool unaligned; ++ ++ struct apm_slot_info *slots; ++}; ++ ++ ++struct apm_rx_header { ++ __le16 len; ++ __le16 flags; ++ __le16 pad[12]; ++}; ++ ++struct apm { ++ union { ++ struct { ++ void *base; ++ void *idm_base; ++ } plat; ++ }; ++ ++ struct device *dev; ++ struct device *dma_dev; ++ ++ struct iproc_pm_ops *pm_ops; ++ u8 land_idx; ++ ++ u8 mac_addr[ETH_ALEN]; ++ u32 feature_flags; ++ ++ struct net_device *net_dev; ++ struct napi_struct napi; ++ struct mii_bus *mii_bus; ++ ++ /* DMA */ ++ struct apm_dma_desc *desc_buf; ++ dma_addr_t dma_addr; ++ struct apm_slot_info *slot_buf; ++ ++ struct apm_dma_ring tx_ring[APM_MAX_TX_RINGS]; ++ struct apm_dma_ring rx_ring[APM_MAX_RX_RINGS]; ++ ++ /* QoS */ ++ u8 tx_channel; ++ bool strict_mode; ++ ++ /* Int */ ++ int irq0; ++ int irq1; ++ int irq2; ++ u32 int_mask; ++ ++ /* Current MAC state */ ++ int mac_speed; ++ int mac_duplex; ++ ++ u8 phyaddr; ++ bool loopback; ++}; ++ ++extern int apm_ethtool_init(struct net_device *net_dev); ++#endif /* _APM_H */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/apm_ethtool.c b/drivers/net/ethernet/broadcom/apm_ethtool.c +--- a/drivers/net/ethernet/broadcom/apm_ethtool.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/apm_ethtool.c 2018-05-10 11:31:31.729401905 +0800 +@@ -0,0 +1,227 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "pm.h" ++#include "apm.h" ++ ++static const struct { ++ const char name[ETH_GSTRING_LEN]; ++} apm_stat_name[] = { ++ { "rx_frames" }, ++ { "rx_frame_good" }, ++ { "rx_bytes" }, ++ { "rx_frame_64" }, ++ { "rx_frame_127" }, ++ { "rx_frame_255" }, ++ { "rx_frame_511" }, ++ { "rx_frame_1023" }, ++ { "rx_frame_1518" }, ++ { "rx_frame_1522" }, ++ { "rx_frame_jumbo" }, ++ { "rx_frame_unicast" }, ++ { "rx_frame_multicast" }, ++ { "rx_frame_broadcast" }, ++ { "rx_frame_control" }, ++ { "rx_frame_pause" }, ++ { "rx_frame_jabber" }, ++ { "rx_frame_fragment" }, ++ { "rx_frame_vlan" }, ++ { "rx_frame_dvlan" }, ++ { "rx_frame_fcs_error" }, ++ { "rx_frame_unsupport" }, ++ { "rx_frame_wrong_sa" }, ++ { "rx_frame_align_err" }, ++ { "rx_frame_length_err" }, ++ { "rx_frame_oversize" }, ++ { "rx_frame_mtu_err" }, ++ { "rx_frame_truncated_err" }, ++ { "rx_frame_undersize" }, ++ { "tx_frames" }, ++ { "tx_frame_good" }, ++ { "tx_bytes" }, ++ { "tx_frame_64" }, ++ { "tx_frame_127" }, ++ { "tx_frame_255" }, ++ { "tx_frame_511" }, ++ { "tx_frame_1023" }, ++ { "tx_frame_1518" }, ++ { "tx_frame_1522" }, ++ { "tx_frame_jumbo" }, ++ { "tx_frame_unicast" }, ++ { "tx_frame_multicast" }, ++ { "tx_frame_broadcast" }, ++ { "tx_frame_control" }, ++ { "tx_frame_pause" }, ++ { "tx_frame_jabber" }, ++ { "tx_frame_fragment" }, ++ { "tx_frame_vlan" }, ++ { "tx_frame_dvlan" }, ++ { "tx_frame_fcs_error" }, ++ { "tx_frame_oversize" }, ++ { "tx_frame_error" }, ++ { "tx_frame_fifo_underrun" }, ++ { "tx_frame_collision" }, ++}; ++ ++static int apm_get_sset_count(struct net_device *net_dev, int sset) ++{ ++ switch (sset) { ++ case ETH_SS_STATS: ++ return ARRAY_SIZE(apm_stat_name); ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static void apm_get_strings(struct net_device *net_dev, u32 stringset, ++ u8 *data) ++{ ++ if (stringset == ETH_SS_STATS) { ++ memcpy(data, apm_stat_name, sizeof(apm_stat_name)); ++ } ++} ++ ++static void apm_get_ethtool_stats(struct net_device *net_dev, ++ struct ethtool_stats *ss, uint64_t *data) ++{ ++ struct apm *apm = netdev_priv(net_dev); ++ struct iproc_pm_ops *pm_ops = apm->pm_ops; ++ struct iproc_pm_stats stats; ++ int i = 0; ++ ++ if (pm_ops) { ++ pm_ops->port_stats(apm->land_idx, &stats); ++ ++ data[i++] = stats.rx_frames; ++ data[i++] = stats.rx_frame_good; ++ data[i++] = stats.rx_bytes; ++ data[i++] = stats.rx_frame_64; ++ data[i++] = stats.rx_frame_127; ++ data[i++] = stats.rx_frame_255; ++ data[i++] = stats.rx_frame_511; ++ data[i++] = stats.rx_frame_1023; ++ data[i++] = stats.rx_frame_1518; ++ data[i++] = stats.rx_frame_1522; ++ data[i++] = stats.rx_frame_jumbo; ++ data[i++] = stats.rx_frame_unicast; ++ data[i++] = stats.rx_frame_multicast; ++ data[i++] = stats.rx_frame_broadcast; ++ data[i++] = stats.rx_frame_control; ++ data[i++] = stats.rx_frame_pause; ++ data[i++] = stats.rx_frame_jabber; ++ data[i++] = stats.rx_frame_fragment; ++ data[i++] = stats.rx_frame_vlan; ++ data[i++] = stats.rx_frame_dvlan; ++ data[i++] = stats.rx_frame_fcs_error; ++ data[i++] = stats.rx_frame_unsupport; ++ data[i++] = stats.rx_frame_wrong_sa; ++ data[i++] = stats.rx_frame_align_err; ++ data[i++] = stats.rx_frame_length_err; ++ data[i++] = stats.rx_frame_oversize; ++ data[i++] = stats.rx_frame_mtu_err; ++ data[i++] = stats.rx_frame_truncated_err; ++ data[i++] = stats.rx_frame_undersize; ++ data[i++] = stats.tx_frames; ++ data[i++] = stats.tx_frame_good; ++ data[i++] = stats.tx_bytes; ++ data[i++] = stats.tx_frame_64; ++ data[i++] = stats.tx_frame_127; ++ data[i++] = stats.tx_frame_255; ++ data[i++] = stats.tx_frame_511; ++ data[i++] = stats.tx_frame_1023; ++ data[i++] = stats.tx_frame_1518; ++ data[i++] = stats.tx_frame_1522; ++ data[i++] = stats.tx_frame_jumbo; ++ data[i++] = stats.tx_frame_unicast; ++ data[i++] = stats.tx_frame_multicast; ++ data[i++] = stats.tx_frame_broadcast; ++ data[i++] = stats.tx_frame_control; ++ data[i++] = stats.tx_frame_pause; ++ data[i++] = stats.tx_frame_jabber; ++ data[i++] = stats.tx_frame_fragment; ++ data[i++] = stats.tx_frame_vlan; ++ data[i++] = stats.tx_frame_dvlan; ++ data[i++] = stats.tx_frame_fcs_error; ++ data[i++] = stats.tx_frame_oversize; ++ data[i++] = stats.tx_frame_error; ++ data[i++] = stats.tx_frame_fifo_underrun; ++ data[i++] = stats.tx_frame_collision; ++ } ++} ++ ++static int apm_dump_phy_regs(struct apm *apm, int try_run, char *reg_buf) ++{ ++ struct phy_device *phydev = apm->net_dev->phydev; ++ int idx, len = 0; ++ char *buf, tmp[32]; ++ u16 data = 0; ++ ++ if (phydev) { ++ for (idx = 0; idx < 16; idx++) { ++ if (try_run || !reg_buf) { ++ buf = tmp; ++ } else { ++ buf = reg_buf + len; ++ data = phy_read(phydev, idx); ++ } ++ len += sprintf(buf, "PHY REG %d: 0x%.4x\n", idx, data); ++ } ++ } ++ return len; ++} ++ ++static int apm_get_regs_len(struct net_device *dev) ++{ ++ struct apm *apm = netdev_priv(dev); ++ u32 len = 0; ++ ++ len += apm_dump_phy_regs(apm, 1, NULL); ++ ++ return len; ++} ++ ++static void apm_get_regs(struct net_device *dev, ++ struct ethtool_regs *regs, void *_p) ++{ ++ struct apm *apm = netdev_priv(dev); ++ u32 len = 0; ++ ++ regs->version = 0; ++ ++ /* Dump phy register */ ++ len += apm_dump_phy_regs(apm, 0, (char *)_p + len); ++} ++ ++static void apm_get_drvinfo(struct net_device *net_dev, ++ struct ethtool_drvinfo *info) ++{ ++ strlcpy(info->driver, "apm", sizeof(info->driver)); ++ strlcpy(info->version, "0.1", sizeof(info->version)); ++ strlcpy(info->bus_info, "axi", sizeof(info->bus_info)); ++ info->regdump_len = apm_get_regs_len(net_dev); ++} ++ ++static const struct ethtool_ops apm_ethtool_ops = { ++ .get_regs = apm_get_regs, ++ .get_regs_len = apm_get_regs_len, ++ .get_strings = apm_get_strings, ++ .get_sset_count = apm_get_sset_count, ++ .get_ethtool_stats = apm_get_ethtool_stats, ++ .get_drvinfo = apm_get_drvinfo, ++ .get_link_ksettings = phy_ethtool_get_link_ksettings, ++ .set_link_ksettings = phy_ethtool_set_link_ksettings, ++}; ++ ++int apm_ethtool_init(struct net_device *net_dev) ++{ ++ net_dev->ethtool_ops = &apm_ethtool_ops; ++ return 0; ++} ++ ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c +--- a/drivers/net/ethernet/broadcom/bgmac-platform.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/bgmac-platform.c 2018-05-10 11:31:31.729401905 +0800 +@@ -19,6 +19,12 @@ + #include + #include + #include ++ ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++#include ++#include ++#endif ++ + #include "bgmac.h" + + #define NICPM_PADRING_CFG 0x00000004 +@@ -84,9 +90,16 @@ static void platform_bgmac_clk_enable(st + } + + val = bgmac_idm_read(bgmac, BCMA_IOCTL); ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++ /* To make HX4/KT2 GMAC work */ ++ val |= flags; ++ val &= ~(BGMAC_AWCACHE | BGMAC_ARCACHE | BGMAC_AWUSER | ++ BGMAC_ARUSER); ++#else + /* Some bits of BCMA_IOCTL set by HW/ATF and should not change */ + val |= flags & ~(BGMAC_AWCACHE | BGMAC_ARCACHE | BGMAC_AWUSER | + BGMAC_ARUSER); ++#endif + val |= BGMAC_CLK_EN; + bgmac_idm_write(bgmac, BCMA_IOCTL, val); + bgmac_idm_read(bgmac, BCMA_IOCTL); +@@ -147,18 +160,123 @@ static void bgmac_nicpm_speed_set(struct + bgmac_adjust_link(bgmac->net_dev); + } + ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++#define SERDES_CONTROL_OFFSET 0x1a8 ++#define SC_TX1G_FIFO_RST_MASK 0x00f00000 ++#define SC_TX1G_FIFO_RST_VAL 0x00f00000 ++#define SC_FORCE_SPD_STRAP_MASK 0x00060000 ++#define SC_FORCE_SPD_STRAP_VAL 0x00040000 ++#define SC_FORCE_SPD_100M_VAL 0x00020000 ++#define SC_FORCE_SPD_1G_VAL 0x00040000 ++#define SC_REF_TERM_SEL_MASK 0x00001000 ++#define SC_REFSEL_MASK 0x00000c00 ++#define SC_REFSEL_VAL 0x00000400 ++#define SC_REFDIV_MASK 0x00000300 ++#define SC_REFDIV_VAL 0x00000000 ++#define SC_LCREF_EN_MASK 0x00000040 ++#define SC_RSTB_PLL_MASK 0x00000010 ++#define SC_RSTB_MDIOREGS_MASK 0x00000008 ++#define SC_RSTB_HW_MASK 0x00000004 ++#define SC_IDDQ_MASK 0x00000002 ++#define SC_PWR_DOWN_MASK 0x00000001 ++ ++void amac_serdes_init(struct bgmac *info, struct phy_device *phy_dev) ++{ ++ u32 sdctl; ++ void *serdes_ctl_reg; ++ struct phy_device *phydev = phy_dev; ++ ++ serdes_ctl_reg = info->plat.base + SERDES_CONTROL_OFFSET; ++ ++ sdctl = (SC_TX1G_FIFO_RST_VAL | SC_FORCE_SPD_STRAP_VAL); ++ if (xgs_serdes_hx4_amac(phydev)) ++ sdctl |= (SC_REFSEL_VAL | SC_REF_TERM_SEL_MASK); ++ ++ else if (xgs_serdes_kt2_amac(phydev)) ++ sdctl |= SC_REF_TERM_SEL_MASK; ++ ++ writel(sdctl, serdes_ctl_reg); ++ ++ udelay(1000); ++ ++ sdctl = readl(serdes_ctl_reg); ++ sdctl |= (SC_IDDQ_MASK | SC_PWR_DOWN_MASK); ++ writel(sdctl, serdes_ctl_reg); ++ ++ sdctl = readl(serdes_ctl_reg); ++ sdctl &= ~(SC_IDDQ_MASK | SC_PWR_DOWN_MASK); ++ writel(sdctl, serdes_ctl_reg); ++ ++ /* Bring hardware out of reset */ ++ sdctl = readl(serdes_ctl_reg); ++ sdctl |= SC_RSTB_HW_MASK; ++ writel(sdctl, serdes_ctl_reg); ++ ++ /* Bring MDIOREGS out of reset */ ++ sdctl = readl(serdes_ctl_reg); ++ sdctl |= SC_RSTB_MDIOREGS_MASK; ++ writel(sdctl, serdes_ctl_reg); ++ ++ udelay(1000); ++ ++ /* Bring PLL out of reset */ ++ sdctl = readl(serdes_ctl_reg); ++ sdctl |= SC_RSTB_PLL_MASK; ++ writel(sdctl, serdes_ctl_reg); ++ ++ udelay(1000); ++ ++ return; ++} ++#endif /* IS_ENABLED(CONFIG_ARCH_XGS_IPROC) */ ++ + static int platform_phy_connect(struct bgmac *bgmac) + { + struct phy_device *phy_dev; + +- if (bgmac->plat.nicpm_base) ++ if (bgmac->plat.nicpm_base) { + phy_dev = of_phy_get_and_connect(bgmac->net_dev, + bgmac->dev->of_node, + bgmac_nicpm_speed_set); +- else ++ } ++ else { ++ struct device_node *np = bgmac->dev->of_node; ++ u32 lane; ++ ++ /* For WH2 SGMII case, treat SERDES as PHY */ ++ if (of_device_is_compatible(np, "brcm,xgs-wh2-amac") && ++ is_wh2_amac_sgmii()) { ++ struct device_node *phy_np; ++ phy_interface_t iface = PHY_INTERFACE_MODE_SGMII; ++ ++ phy_np = of_parse_phandle(np, "serdes-phy-handle", 0); ++ if (!phy_np) ++ return -ENODEV; ++ ++ phy_dev = of_phy_find_device(phy_np); ++ if (!phy_dev) ++ return -ENODEV; ++ ++ /* Get lane from DT, otherwise set to default 3 */ ++ if (of_property_read_u32(phy_np, "lane-num", &lane)) ++ lane = 3; ++ xgs_serdes_set_lane(phy_dev, lane); ++ ++ amac_serdes_init(bgmac, phy_dev); ++ ++ phy_connect_direct(bgmac->net_dev, phy_dev, ++ bgmac_adjust_link, iface); ++ ++ put_device(&phy_dev->mdio.dev); ++ of_node_put(phy_np); ++ } ++ else { + phy_dev = of_phy_get_and_connect(bgmac->net_dev, + bgmac->dev->of_node, + bgmac_adjust_link); ++ } ++ } ++ + if (!phy_dev) { + dev_err(bgmac->dev, "PHY connection failed\n"); + return -ENODEV; +@@ -285,6 +403,8 @@ static const struct dev_pm_ops bgmac_pm_ + static const struct of_device_id bgmac_of_enet_match[] = { + {.compatible = "brcm,amac",}, + {.compatible = "brcm,nsp-amac",}, ++ {.compatible = "brcm,xgs-iproc-amac",}, ++ {.compatible = "brcm,xgs-wh2-amac",}, + {.compatible = "brcm,ns2-amac",}, + {}, + }; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c +--- a/drivers/net/ethernet/broadcom/bgmac.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/bgmac.c 2018-05-10 11:31:31.733401909 +0800 +@@ -17,6 +17,13 @@ + #include + #include "bgmac.h" + ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++#include ++#include ++extern bool xgs_mdio_bus_release(void); ++extern void amac_serdes_init(struct bgmac *, struct phy_device *); ++#endif ++ + static bool bgmac_wait_value(struct bgmac *bgmac, u16 reg, u32 mask, + u32 value, int timeout) + { +@@ -1120,6 +1127,7 @@ static void bgmac_chip_init(struct bgmac + + bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN); + ++ if (!IS_ENABLED(CONFIG_ARCH_XGS_IPROC)) + bgmac_chip_intrs_on(bgmac); + + bgmac_enable(bgmac); +@@ -1197,10 +1204,33 @@ static int bgmac_open(struct net_device + } + napi_enable(&bgmac->napi); + ++ if (IS_ENABLED(CONFIG_ARCH_XGS_IPROC)) { ++ /* Reset emulated MIB statistics to zero */ ++ memset(&bgmac->estats, 0, sizeof(struct bgmac_ethtool_stats)); ++ ++ /* ++ * phy_state_machine reschedule could be stopped due to the code ++ * change in phy.c to handle MDIO bus sharing between iProc and ++ * CIMCd of HX4/KT2. ++ */ ++ if (xgs_mdio_bus_release()) ++ phy_start_machine(net_dev->phydev); ++ } ++ + phy_start(net_dev->phydev); + + netif_start_queue(net_dev); + ++ /* ++ * This interrupt enable was originally set in "bgmac_chip_init" which ++ * was run before "napi_enable". If interrupt events come before ++ * napi_enable was run, the NAPI poll routine "bgmac_poll" will not yet ++ * be available for either handling interrupt events or re-enabling the ++ * AMAC interrupt disabled by "bgmac_interrupt". ++ */ ++ if (IS_ENABLED(CONFIG_ARCH_XGS_IPROC)) ++ bgmac_chip_intrs_on(bgmac); ++ + return 0; + } + +@@ -1379,6 +1409,9 @@ static void bgmac_get_ethtool_stats(stru + const struct bgmac_stat *s; + unsigned int i; + u64 val; ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++ u64 *estats = (u64*)&bgmac->estats; ++#endif + + if (!netif_running(dev)) + return; +@@ -1389,18 +1422,70 @@ static void bgmac_get_ethtool_stats(stru + if (s->size == 8) + val = (u64)bgmac_read(bgmac, s->offset + 4) << 32; + val |= bgmac_read(bgmac, s->offset); ++ if (IS_ENABLED(CONFIG_ARCH_XGS_IPROC)) { ++ estats[i] += val; ++ data[i] = estats[i]; ++ } ++ else { + data[i] = val; + } + } ++} ++ ++static int bgmac_dump_phy_regs(struct bgmac *bgmac, int try_run, char *reg_buf) ++{ ++ struct phy_device *phydev = bgmac->net_dev->phydev; ++ int idx, len = 0; ++ char *buf, tmp[32]; ++ u16 data = 0; ++ ++ if (phydev) { ++ for (idx = 0; idx < 16; idx++) { ++ if (try_run || !reg_buf) { ++ buf = tmp; ++ } else { ++ buf = reg_buf + len; ++ data = phy_read(phydev, idx); ++ } ++ len += sprintf(buf, "PHY REG %d: 0x%.4x\n", idx, data); ++ } ++ } ++ return len; ++} ++ ++static int bgmac_get_regs_len(struct net_device *dev) ++{ ++ struct bgmac *bgmac = netdev_priv(dev); ++ u32 len = 0; ++ ++ len += bgmac_dump_phy_regs(bgmac, 1, NULL); ++ ++ return len; ++} ++ ++static void bgmac_get_regs(struct net_device *dev, ++ struct ethtool_regs *regs, void *_p) ++{ ++ struct bgmac *bgmac = netdev_priv(dev); ++ u32 len = 0; ++ ++ regs->version = 0; ++ ++ /* Dump phy register */ ++ len += bgmac_dump_phy_regs(bgmac, 0, (char *)_p + len); ++} + + static void bgmac_get_drvinfo(struct net_device *net_dev, + struct ethtool_drvinfo *info) + { + strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); + strlcpy(info->bus_info, "AXI", sizeof(info->bus_info)); ++ info->regdump_len = bgmac_get_regs_len(net_dev); + } + + static const struct ethtool_ops bgmac_ethtool_ops = { ++ .get_regs = bgmac_get_regs, ++ .get_regs_len = bgmac_get_regs_len, + .get_strings = bgmac_get_strings, + .get_sset_count = bgmac_get_sset_count, + .get_ethtool_stats = bgmac_get_ethtool_stats, +@@ -1431,11 +1516,11 @@ void bgmac_adjust_link(struct net_device + } + } + +- if (update) { ++ if (update) + bgmac_mac_speed(bgmac); ++ + phy_print_status(phy_dev); + } +-} + EXPORT_SYMBOL_GPL(bgmac_adjust_link); + + int bgmac_phy_connect_direct(struct bgmac *bgmac) +@@ -1490,6 +1576,12 @@ int bgmac_enet_probe(struct bgmac *bgmac + { + struct net_device *net_dev = bgmac->net_dev; + int err; ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++ struct device_node *serdes_np; ++ struct device_node *amac_np; ++ struct phy_device *serdes_phy_dev = NULL; ++ static u32 serdes_lane2_init = 0; ++#endif + + net_dev->irq = bgmac->irq; + SET_NETDEV_DEV(net_dev, bgmac->dev); +@@ -1534,6 +1626,37 @@ int bgmac_enet_probe(struct bgmac *bgmac + goto err_dma_free; + } + ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++ /* SERDES init required for HX4/KT2/SB2/GH2/WH2 */ ++ amac_np = bgmac->dev->of_node; ++ serdes_np = of_parse_phandle(amac_np, "serdes-handle", 0); ++ if (serdes_np) ++ serdes_phy_dev = of_phy_find_device(serdes_np); ++ ++ if (serdes_phy_dev) { ++ u32 lane; ++ /* If lane available in DT, set lane num */ ++ if (!of_property_read_u32(serdes_np, "lane-num", &lane)) ++ xgs_serdes_set_lane(serdes_phy_dev, lane); ++ ++ amac_serdes_init(bgmac, serdes_phy_dev); ++ phy_init_hw(serdes_phy_dev); ++ } ++ ++ /* Init SERDES lane 2 required by SDK for HX4/KT2 */ ++ if (!serdes_lane2_init) { ++ /* Use alias defined in DTS rather than full path */ ++ serdes_np = of_find_node_by_path("sdk-serdes-lane2"); ++ if (serdes_np) { ++ serdes_phy_dev = of_phy_find_device(serdes_np); ++ if (serdes_phy_dev) { ++ phy_init_hw(serdes_phy_dev); ++ serdes_lane2_init = 1; ++ } ++ } ++ } ++#endif ++ + net_dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + net_dev->hw_features = net_dev->features; + net_dev->vlan_features = net_dev->features; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h +--- a/drivers/net/ethernet/broadcom/bgmac.h 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/bgmac.h 2018-05-10 11:31:31.733401909 +0800 +@@ -476,6 +476,78 @@ struct bgmac_rx_header { + __le16 pad[12]; + }; + ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++struct bgmac_ethtool_stats { ++ u64 tx_good_octets; ++ u64 tx_good; ++ u64 tx_octets; ++ u64 tx_pkts; ++ u64 tx_broadcast; ++ u64 tx_multicast; ++ u64 tx_64; ++ u64 tx_65_127; ++ u64 tx_128_255; ++ u64 tx_256_511; ++ u64 tx_512_1023; ++ u64 tx_1024_1522; ++ u64 tx_1523_2047; ++ u64 tx_2048_4095; ++ u64 tx_4096_8191; ++ u64 tx_8192_max; ++ u64 tx_jabber; ++ u64 tx_oversize; ++ u64 tx_fragment; ++ u64 tx_underruns; ++ u64 tx_total_cols; ++ u64 tx_single_cols; ++ u64 tx_multiple_cols; ++ u64 tx_excessive_cols; ++ u64 tx_late_cols; ++ u64 tx_defered; ++ u64 tx_carrier_lost; ++ u64 tx_pause; ++ u64 tx_unicast; ++ u64 tx_q0; ++ u64 tx_q0_octets; ++ u64 tx_q1; ++ u64 tx_q1_octets; ++ u64 tx_q2; ++ u64 tx_q2_octets; ++ u64 tx_q3; ++ u64 tx_q3_octets; ++ ++ u64 rx_good_octets; ++ u64 rx_good; ++ u64 rx_octets; ++ u64 rx_pkts; ++ u64 rx_broadcast; ++ u64 rx_multicast; ++ u64 rx_64; ++ u64 rx_65_127; ++ u64 rx_128_255; ++ u64 rx_256_511; ++ u64 rx_512_1023; ++ u64 rx_1024_1522; ++ u64 rx_1523_2047; ++ u64 rx_2048_4095; ++ u64 rx_4096_8191; ++ u64 rx_8192_max; ++ u64 rx_jabber; ++ u64 rx_oversize; ++ u64 rx_fragment; ++ u64 rx_missed; ++ u64 rx_crc_align; ++ u64 rx_undersize; ++ u64 rx_crc; ++ u64 rx_align; ++ u64 rx_symbol; ++ u64 rx_pause; ++ u64 rx_nonpause; ++ u64 rx_sa_changes; ++ u64 rx_unicast; ++}; ++#endif ++ + struct bgmac { + union { + struct { +@@ -520,6 +592,14 @@ struct bgmac { + + bool loopback; + ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++ /* For XGS iProc, SW emulated MIB registers are required as the HW ++ * MIB registers will be cleared to zero after reading. ++ * mib_tx_regs/mib_rx_regs defined above seem for the same purpose, ++ * but not used so far. ++ */ ++ struct bgmac_ethtool_stats estats; ++#endif + u32 (*read)(struct bgmac *bgmac, u16 offset); + void (*write)(struct bgmac *bgmac, u16 offset, u32 value); + u32 (*idm_read)(struct bgmac *bgmac, u16 offset); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/merlin16_ucode.h b/drivers/net/ethernet/broadcom/merlin16_ucode.h +--- a/drivers/net/ethernet/broadcom/merlin16_ucode.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/merlin16_ucode.h 2018-05-30 15:50:51.032753168 +0800 +@@ -0,0 +1,1977 @@ ++/* ++ * $Id: merlin16_ucode.c $ ++ * $Copyright: (c) 2013 Broadcom Corporation All Rights Reserved.$ ++ * All Rights Reserved.$ ++ */ ++ ++#define MERLIN16_UCODE_IMAGE_VERSION "D101_0C" /* matches the version number from microcode */ ++#define MERLIN16_UCODE_IMAGE_SIZE 31368 ++#define MERLIN16_UCODE_IMAGE_CRC 0x2C25 ++ ++unsigned short merlin16_ucode_ver = 0xD101; ++unsigned short merlin16_ucode_crc = MERLIN16_UCODE_IMAGE_CRC; ++unsigned short merlin16_ucode_len = MERLIN16_UCODE_IMAGE_SIZE; ++ ++unsigned char merlin16_ucode[] = { ++ 0xf0, 0x0f, 0x00, 0x20, 0x7d, 0x02, 0x00, 0x00, 0x51, 0x74, 0x00, 0x00, 0x5f, 0x74, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x74, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x02, 0x00, 0x00, 0x7b, 0x74, 0x00, 0x00, ++ 0x89, 0x74, 0x00, 0x00, 0x97, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, ++ 0xa5, 0x74, 0x00, 0x00, 0xab, 0x74, 0x00, 0x00, 0xb1, 0x74, 0x00, 0x00, 0xb7, 0x74, 0x00, 0x00, ++ 0xbd, 0x74, 0x00, 0x00, 0xc3, 0x74, 0x00, 0x00, 0xc9, 0x74, 0x00, 0x00, 0xcf, 0x74, 0x00, 0x00, ++ 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, ++ 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, ++ 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, ++ 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, ++ 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x49, 0x6e, 0x66, 0x35, 0x0c, 0x01, 0xd1, 0x00, 0x00, 0x03, 0x00, 0x01, 0x04, 0x24, 0x00, 0x01, ++ 0x00, 0x01, 0x00, 0x20, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x20, ++ 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x24, 0x04, 0x00, 0x20, 0x00, 0x0e, 0x00, 0x20, ++ 0x00, 0x0a, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x20, 0x44, 0x04, 0x00, 0x20, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0xf0, 0x02, 0xf8, 0x00, 0xf0, 0x3e, 0xf8, 0x0c, 0xa0, 0x30, 0xc8, 0x08, 0x38, 0x24, 0x18, ++ 0x2d, 0x18, 0xa2, 0x46, 0x67, 0x1e, 0xab, 0x46, 0x54, 0x46, 0x5d, 0x46, 0xac, 0x42, 0x01, 0xd1, ++ 0x00, 0xf0, 0x30, 0xf8, 0x7e, 0x46, 0x0f, 0x3e, 0x0f, 0xcc, 0xb6, 0x46, 0x01, 0x26, 0x33, 0x42, ++ 0x00, 0xd0, 0xfb, 0x1a, 0xa2, 0x46, 0xab, 0x46, 0x33, 0x43, 0x18, 0x47, 0x98, 0x78, 0x00, 0x00, ++ 0xb8, 0x78, 0x00, 0x00, 0x10, 0x3a, 0x02, 0xd3, 0x78, 0xc8, 0x78, 0xc1, 0xfa, 0xd8, 0x52, 0x07, ++ 0x01, 0xd3, 0x30, 0xc8, 0x30, 0xc1, 0x01, 0xd5, 0x04, 0x68, 0x0c, 0x60, 0x70, 0x47, 0x00, 0x00, ++ 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x10, 0x3a, 0x01, 0xd3, 0x78, 0xc1, 0xfb, 0xd8, ++ 0x52, 0x07, 0x00, 0xd3, 0x30, 0xc1, 0x00, 0xd5, 0x0b, 0x60, 0x70, 0x47, 0x1f, 0xb5, 0x1f, 0xbd, ++ 0x10, 0xb5, 0x10, 0xbd, 0x07, 0xf0, 0x92, 0xfb, 0x11, 0x46, 0xff, 0xf7, 0xf7, 0xff, 0x00, 0xf0, ++ 0x3f, 0xf8, 0x07, 0xf0, 0xaa, 0xfb, 0x03, 0xb4, 0xff, 0xf7, 0xf2, 0xff, 0x03, 0xbc, 0x00, 0xf0, ++ 0x34, 0xf8, 0x00, 0x00, 0x70, 0xb5, 0x05, 0x46, 0x0c, 0x46, 0x16, 0x46, 0x02, 0xe0, 0x0f, 0xcc, ++ 0x0f, 0xc5, 0x10, 0x3e, 0x10, 0x2e, 0xfa, 0xd2, 0x08, 0x2e, 0x02, 0xd3, 0x03, 0xcc, 0x03, 0xc5, ++ 0x08, 0x3e, 0x04, 0x2e, 0x07, 0xd3, 0x01, 0xcc, 0x01, 0xc5, 0x36, 0x1f, 0x03, 0xe0, 0x21, 0x78, ++ 0x29, 0x70, 0x64, 0x1c, 0x6d, 0x1c, 0x76, 0x1e, 0xf9, 0xd2, 0x70, 0xbd, 0xfe, 0xe7, 0xfe, 0xe7, ++ 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, ++ 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0x10, 0xb5, 0xff, 0xf7, ++ 0x7f, 0xff, 0x10, 0xbd, 0x0a, 0x46, 0x03, 0x46, 0x70, 0x47, 0xfe, 0xe7, 0x70, 0x47, 0x00, 0x00, ++ 0xff, 0xf7, 0xfc, 0xff, 0x07, 0xf0, 0x3a, 0xf9, 0x07, 0xf0, 0x96, 0xf9, 0x2f, 0x4d, 0x00, 0x20, ++ 0x2c, 0x46, 0x28, 0x60, 0x05, 0x21, 0x09, 0x07, 0x40, 0x18, 0x28, 0x60, 0x07, 0xf0, 0x6a, 0xf8, ++ 0x07, 0xf0, 0x05, 0xf8, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x29, 0x49, 0x81, 0x82, 0x22, 0x68, ++ 0x49, 0x1c, 0x28, 0x48, 0x12, 0x18, 0x11, 0x85, 0x21, 0x68, 0x08, 0x18, 0x80, 0x8e, 0x2f, 0x1f, ++ 0x00, 0x0b, 0x38, 0x70, 0x02, 0xf0, 0x58, 0xfd, 0x07, 0xf0, 0x94, 0xfa, 0x23, 0x49, 0x22, 0x4e, ++ 0x0e, 0x60, 0x03, 0x20, 0x22, 0x68, 0x40, 0x04, 0x82, 0x43, 0x22, 0x60, 0x2f, 0x46, 0x00, 0x24, ++ 0x0d, 0x46, 0x1a, 0xe0, 0x28, 0x68, 0x92, 0x21, 0x09, 0x5c, 0xc0, 0x22, 0x51, 0x43, 0x40, 0x30, ++ 0x81, 0x80, 0x02, 0xf0, 0x8f, 0xfd, 0x28, 0x68, 0x03, 0x22, 0x80, 0x30, 0xc0, 0x7c, 0x52, 0x04, ++ 0x00, 0x02, 0x80, 0x19, 0x28, 0x60, 0x80, 0x30, 0x80, 0x7c, 0x39, 0x68, 0x80, 0x07, 0x91, 0x43, ++ 0x40, 0x0b, 0x01, 0x43, 0x64, 0x1c, 0xe4, 0xb2, 0x39, 0x60, 0x0c, 0x48, 0x00, 0x1f, 0x00, 0x78, ++ 0x84, 0x42, 0xdf, 0xd3, 0x03, 0x24, 0x64, 0x04, 0x00, 0xf0, 0xdf, 0xf9, 0x28, 0x68, 0x80, 0x30, ++ 0xc0, 0x7c, 0x00, 0x02, 0x80, 0x19, 0x28, 0x60, 0x80, 0x30, 0x80, 0x7c, 0x39, 0x68, 0x80, 0x07, ++ 0xa1, 0x43, 0x40, 0x0b, 0x01, 0x43, 0x39, 0x60, 0xee, 0xe7, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, ++ 0xff, 0x7f, 0x00, 0x00, 0xc0, 0xa1, 0x01, 0x00, 0x00, 0x05, 0x00, 0x20, 0x90, 0x00, 0x00, 0x20, ++ 0xfe, 0x48, 0x56, 0x21, 0x00, 0x68, 0x0a, 0x5c, 0x01, 0x46, 0x80, 0x31, 0x01, 0x2a, 0x04, 0xd0, ++ 0x82, 0x79, 0x4a, 0x73, 0xc0, 0x79, 0x88, 0x73, 0x70, 0x47, 0x02, 0x7a, 0x4a, 0x73, 0x40, 0x7a, ++ 0xf9, 0xe7, 0xf7, 0x49, 0x08, 0x5c, 0x70, 0x47, 0x1c, 0xb5, 0x00, 0x21, 0x6a, 0x46, 0x11, 0x80, ++ 0x90, 0x80, 0xf4, 0x49, 0xf2, 0x4a, 0x09, 0x7b, 0xf0, 0x4c, 0x52, 0x5c, 0x21, 0x68, 0x60, 0x31, ++ 0x0b, 0x78, 0x9a, 0x42, 0x17, 0xd9, 0x16, 0x22, 0x8a, 0x56, 0x01, 0x23, 0xdb, 0x07, 0x9a, 0x42, ++ 0x11, 0xd1, 0x00, 0x07, 0x80, 0x0f, 0x02, 0x28, 0x0d, 0xd0, 0x08, 0x20, 0x6b, 0x46, 0x18, 0x80, ++ 0x52, 0x1e, 0x8a, 0x75, 0x09, 0x7d, 0x01, 0x29, 0x01, 0xd0, 0x05, 0xf0, 0x80, 0xfe, 0x20, 0x68, ++ 0x60, 0x30, 0x00, 0x7d, 0x1c, 0xbd, 0x01, 0x20, 0x08, 0x75, 0xf8, 0xe7, 0xe2, 0x48, 0x02, 0x68, ++ 0xe2, 0x49, 0x52, 0x18, 0xd2, 0x8e, 0x03, 0x68, 0x92, 0x04, 0x52, 0x0f, 0x5b, 0x18, 0xdb, 0x8e, ++ 0x00, 0x68, 0x5b, 0x05, 0x5b, 0x0f, 0xd2, 0x18, 0x52, 0x08, 0x40, 0x18, 0xc0, 0x8e, 0x80, 0x06, ++ 0x80, 0x0e, 0x10, 0x18, 0x70, 0x47, 0xd6, 0x49, 0x15, 0x31, 0x08, 0x5c, 0x70, 0x47, 0x7c, 0xb5, ++ 0x05, 0x46, 0xd4, 0x48, 0xd2, 0x49, 0x00, 0x7b, 0x15, 0x31, 0x0c, 0x5c, 0x00, 0x20, 0x69, 0x46, ++ 0x08, 0x80, 0x8d, 0x80, 0xff, 0xf7, 0xda, 0xff, 0xa9, 0x06, 0x89, 0x0f, 0xcb, 0x4d, 0xa0, 0x42, ++ 0x0a, 0xd8, 0x2a, 0x68, 0x60, 0x32, 0x52, 0x7d, 0xa2, 0x42, 0x05, 0xd2, 0x03, 0x29, 0x03, 0xd0, ++ 0x10, 0x21, 0x6a, 0x46, 0x11, 0x80, 0x15, 0xe0, 0x01, 0x26, 0xa0, 0x42, 0x0f, 0xd9, 0x2a, 0x68, ++ 0x60, 0x32, 0x53, 0x7d, 0xa3, 0x42, 0x0a, 0xd2, 0x1b, 0x18, 0x64, 0x00, 0xa3, 0x42, 0x06, 0xd9, ++ 0x02, 0x29, 0x04, 0xd0, 0x20, 0x21, 0x6b, 0x46, 0x19, 0x80, 0xd6, 0x74, 0x02, 0xe0, 0x29, 0x68, ++ 0x60, 0x31, 0xce, 0x74, 0x29, 0x68, 0x60, 0x31, 0x48, 0x75, 0x68, 0x46, 0x00, 0x88, 0x81, 0x06, ++ 0x89, 0x0f, 0x01, 0xd0, 0x05, 0xf0, 0x23, 0xfe, 0x28, 0x68, 0x60, 0x30, 0xc0, 0x7c, 0x7c, 0xbd, ++ 0xf8, 0xb5, 0xb2, 0x4c, 0x03, 0x26, 0x20, 0x68, 0x36, 0x07, 0x40, 0x30, 0xc0, 0x7a, 0x01, 0x27, ++ 0x25, 0x38, 0xb1, 0x4d, 0x03, 0x00, 0x07, 0xf0, 0x63, 0xfa, 0x07, 0x21, 0x6f, 0x8f, 0x81, 0xa1, ++ 0xb1, 0xbf, 0x05, 0x00, 0xb0, 0x8a, 0x07, 0x20, 0xc0, 0x43, 0xb0, 0x82, 0x2a, 0x68, 0x07, 0x21, ++ 0xaa, 0x48, 0x40, 0x30, 0x12, 0x18, 0x11, 0x85, 0xb1, 0x8a, 0x02, 0x21, 0xc9, 0x43, 0xb1, 0x82, ++ 0x2a, 0x68, 0x02, 0x21, 0x10, 0x18, 0x01, 0x84, 0x08, 0x20, 0x07, 0xf0, 0x73, 0xf9, 0x06, 0xf0, ++ 0x23, 0xff, 0x21, 0x68, 0x48, 0x84, 0x00, 0x20, 0x40, 0x31, 0x08, 0x76, 0x20, 0x68, 0x01, 0x46, ++ 0x80, 0x31, 0x8a, 0x7d, 0x00, 0x2a, 0x09, 0xd0, 0x42, 0x7f, 0x52, 0x07, 0x3c, 0xd5, 0x2b, 0x22, ++ 0x40, 0x30, 0x82, 0x72, 0x4f, 0x76, 0x05, 0xf0, 0x16, 0xfe, 0xf8, 0xbd, 0x06, 0xf0, 0x0c, 0xff, ++ 0x81, 0xb2, 0x20, 0x68, 0x42, 0x8c, 0x51, 0x1a, 0x64, 0x29, 0x2b, 0xdb, 0x58, 0x21, 0x09, 0x5c, ++ 0x00, 0x29, 0x02, 0xd1, 0x00, 0x88, 0xc0, 0x05, 0x0d, 0xd4, 0x02, 0x21, 0x0f, 0x20, 0x07, 0xf0, ++ 0x49, 0xf9, 0xb0, 0x8a, 0x01, 0x20, 0xc0, 0x43, 0xb0, 0x82, 0x28, 0x68, 0x0d, 0x21, 0x49, 0x03, ++ 0x40, 0x18, 0x47, 0x86, 0x16, 0xe0, 0xb0, 0x8a, 0x01, 0x20, 0xc0, 0x43, 0xb0, 0x82, 0x28, 0x68, ++ 0x87, 0x49, 0x40, 0x18, 0xc0, 0x8c, 0x3a, 0x46, 0x82, 0x43, 0x28, 0x68, 0x40, 0x18, 0xc2, 0x84, ++ 0x06, 0xf0, 0xe2, 0xfe, 0x21, 0x68, 0x48, 0x84, 0x40, 0x31, 0x0f, 0x76, 0x02, 0x21, 0x1d, 0x20, ++ 0x07, 0xf0, 0x28, 0xf9, 0x25, 0x21, 0x7f, 0xe0, 0x29, 0x68, 0xff, 0x31, 0x01, 0x31, 0x49, 0x8e, ++ 0x89, 0x06, 0x89, 0x0e, 0x40, 0x30, 0x41, 0x80, 0x20, 0x68, 0x26, 0x22, 0x01, 0x46, 0x40, 0x31, ++ 0xca, 0x72, 0x80, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0xb7, 0xd0, 0x48, 0x88, 0xff, 0xf7, 0x37, 0xff, ++ 0x01, 0x28, 0x0d, 0xd0, 0x20, 0x68, 0x28, 0x21, 0x40, 0x30, 0xc1, 0x72, 0x20, 0x68, 0x98, 0x21, ++ 0x09, 0x5c, 0x00, 0x29, 0xa9, 0xd0, 0x14, 0x21, 0x40, 0x30, 0x81, 0x72, 0x26, 0x21, 0x5d, 0xe0, ++ 0x21, 0x68, 0x00, 0x20, 0x40, 0x31, 0x48, 0x80, 0x20, 0x68, 0x27, 0x22, 0x01, 0x46, 0x40, 0x31, ++ 0xca, 0x72, 0x80, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0x97, 0xd0, 0x48, 0x88, 0xff, 0xf7, 0xd4, 0xfe, ++ 0x01, 0x28, 0x0d, 0xd0, 0x20, 0x68, 0x29, 0x21, 0x40, 0x30, 0xc1, 0x72, 0x20, 0x68, 0x98, 0x21, ++ 0x09, 0x5c, 0x00, 0x29, 0x89, 0xd0, 0x14, 0x21, 0x40, 0x30, 0x81, 0x72, 0x27, 0x21, 0x3d, 0xe0, ++ 0x05, 0xf0, 0x99, 0xfd, 0x20, 0x68, 0x2a, 0x21, 0x40, 0x30, 0xc1, 0x72, 0x28, 0x68, 0x57, 0x49, ++ 0x80, 0x31, 0x40, 0x18, 0x80, 0x88, 0x40, 0x07, 0xc0, 0x0f, 0xbd, 0xd0, 0x20, 0x68, 0x99, 0x21, ++ 0x0f, 0x54, 0x2b, 0x21, 0x40, 0x30, 0xc1, 0x72, 0x28, 0x68, 0xff, 0x30, 0x01, 0x30, 0xc0, 0x8d, ++ 0xc0, 0x08, 0xc0, 0x07, 0xc0, 0x0f, 0x00, 0xd0, 0x67, 0xe7, 0x28, 0x68, 0xff, 0x30, 0x01, 0x30, ++ 0xc0, 0x8d, 0x40, 0x07, 0xc0, 0x0f, 0xf7, 0xd1, 0x28, 0x68, 0xff, 0x30, 0x01, 0x30, 0xc0, 0x8d, ++ 0x80, 0x07, 0xc0, 0x0f, 0xf0, 0xd1, 0x28, 0x68, 0xff, 0x30, 0x01, 0x30, 0xc0, 0x8d, 0xc0, 0x07, ++ 0xea, 0xd0, 0xb0, 0x8a, 0x04, 0x20, 0xc0, 0x43, 0xb0, 0x82, 0x2a, 0x68, 0x04, 0x21, 0x3f, 0x48, ++ 0x40, 0x30, 0x10, 0x18, 0x01, 0x84, 0x2c, 0x21, 0x20, 0x68, 0x40, 0x30, 0xc1, 0x72, 0xf8, 0xbd, ++ 0xf8, 0xb5, 0x39, 0x4c, 0x20, 0x68, 0xff, 0x30, 0x01, 0x30, 0x80, 0x8d, 0x33, 0x4a, 0x80, 0x07, ++ 0xc1, 0x0f, 0x36, 0x4f, 0x95, 0x23, 0x10, 0x68, 0x03, 0x25, 0x2d, 0x07, 0x35, 0x4e, 0x40, 0x37, ++ 0x19, 0x54, 0x00, 0x29, 0x19, 0xd0, 0x40, 0x7f, 0x00, 0x07, 0x09, 0xd4, 0x2d, 0x4b, 0x18, 0x22, ++ 0x16, 0x21, 0x17, 0x20, 0x9a, 0x56, 0x59, 0x56, 0x18, 0x56, 0x00, 0x23, 0x06, 0xf0, 0xa1, 0xf9, ++ 0xa8, 0x8a, 0xae, 0x82, 0x21, 0x68, 0x01, 0x20, 0xc9, 0x19, 0x08, 0x84, 0x23, 0x48, 0x00, 0x68, ++ 0x00, 0x78, 0x80, 0x07, 0xc0, 0x17, 0x40, 0x1c, 0xf8, 0xbd, 0xa8, 0x8a, 0xae, 0x82, 0x21, 0x68, ++ 0x04, 0x20, 0xc9, 0x19, 0x08, 0x84, 0x00, 0x20, 0xf8, 0xbd, 0xfe, 0xb5, 0x1b, 0x4d, 0x00, 0x24, ++ 0x28, 0x68, 0x80, 0x30, 0x80, 0x7c, 0x00, 0x28, 0x19, 0xd1, 0x02, 0xf0, 0x0c, 0xfb, 0x0f, 0x27, ++ 0x3f, 0x03, 0x06, 0xf0, 0xdf, 0xfd, 0x1c, 0x4e, 0x00, 0x0c, 0x31, 0x68, 0x09, 0x0c, 0x40, 0x1a, ++ 0xb8, 0x42, 0x0c, 0xdd, 0x19, 0x48, 0xff, 0x21, 0x81, 0x70, 0xf0, 0x21, 0x41, 0x70, 0x04, 0x70, ++ 0x03, 0x20, 0x06, 0xf0, 0xc1, 0xff, 0x30, 0x68, 0x39, 0x04, 0x40, 0x18, 0x30, 0x60, 0x0e, 0x4e, ++ 0x31, 0x68, 0x0f, 0x48, 0x40, 0x30, 0x08, 0x18, 0x00, 0x8d, 0xc0, 0x0b, 0x06, 0xd1, 0x00, 0x23, ++ 0x07, 0x99, 0x1a, 0x46, 0x01, 0x20, 0x00, 0x94, 0x06, 0xf0, 0x73, 0xff, 0x29, 0x68, 0x80, 0x31, ++ 0x88, 0x7a, 0xc8, 0x72, 0x04, 0x48, 0x02, 0x68, 0x0d, 0x20, 0x11, 0xe0, 0x90, 0x00, 0x00, 0x20, ++ 0x9a, 0x79, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, 0x40, 0xa0, 0x01, 0x00, ++ 0x80, 0xa1, 0x01, 0x00, 0xfa, 0xff, 0x00, 0x00, 0x88, 0x00, 0x00, 0x20, 0x8c, 0x00, 0x00, 0x20, ++ 0x40, 0x03, 0x10, 0x18, 0x80, 0x8f, 0xc2, 0x0a, 0x8a, 0x72, 0x01, 0x06, 0xc9, 0x0f, 0x03, 0xd1, ++ 0x80, 0x06, 0x80, 0x0e, 0x01, 0xf0, 0xf6, 0xfe, 0x29, 0x68, 0x48, 0x7c, 0x00, 0x28, 0x09, 0xd0, ++ 0x01, 0x28, 0x26, 0xd0, 0x02, 0x28, 0x22, 0xd0, 0x03, 0x28, 0x23, 0xd0, 0x04, 0x28, 0x24, 0xd0, ++ 0x05, 0x28, 0x25, 0xd0, 0x00, 0x20, 0x52, 0x22, 0x50, 0x54, 0x08, 0x88, 0xfa, 0x4e, 0x82, 0x07, ++ 0x01, 0x24, 0x00, 0x2a, 0x31, 0xdb, 0x80, 0x05, 0x2f, 0xd5, 0x80, 0x31, 0x88, 0x7a, 0x03, 0x28, ++ 0x2b, 0xd9, 0x11, 0x28, 0x29, 0xd0, 0x48, 0x7d, 0x00, 0x28, 0x26, 0xd0, 0xf3, 0x4d, 0x28, 0x68, ++ 0x0d, 0x27, 0x7f, 0x03, 0xc0, 0x19, 0x80, 0x8e, 0xc0, 0x07, 0x0c, 0xd0, 0x1d, 0xe0, 0x00, 0xf0, ++ 0x2e, 0xfe, 0xfe, 0xbd, 0x00, 0xf0, 0xa0, 0xfe, 0xfe, 0xbd, 0x01, 0xf0, 0x57, 0xfc, 0xfe, 0xbd, ++ 0x01, 0xf0, 0x32, 0xf9, 0xfe, 0xbd, 0x06, 0xf0, 0x8f, 0xfd, 0x40, 0x1c, 0xe8, 0x49, 0x40, 0x42, ++ 0x88, 0x42, 0x0a, 0xd3, 0x02, 0x21, 0x1e, 0x20, 0x06, 0xf0, 0xd4, 0xff, 0x03, 0x20, 0x00, 0x07, ++ 0x81, 0x8a, 0x86, 0x82, 0x28, 0x68, 0xc0, 0x19, 0xf0, 0xe2, 0xe2, 0x4d, 0x28, 0x68, 0x80, 0x30, ++ 0xc1, 0x7a, 0x00, 0x29, 0x06, 0xd1, 0x80, 0x7a, 0x00, 0x28, 0x13, 0xd0, 0x01, 0x21, 0x03, 0x20, ++ 0x06, 0xf0, 0xc0, 0xff, 0x28, 0x68, 0x80, 0x30, 0xc1, 0x7a, 0x03, 0x29, 0x01, 0xd9, 0x11, 0x29, ++ 0x08, 0xd1, 0x80, 0x7a, 0x03, 0x28, 0x05, 0xd9, 0x11, 0x28, 0x03, 0xd0, 0x01, 0x21, 0x26, 0x20, ++ 0x06, 0xf0, 0xb0, 0xff, 0xd3, 0x48, 0xd4, 0x4d, 0x00, 0x68, 0x02, 0x46, 0x80, 0x32, 0x91, 0x7a, ++ 0x00, 0x29, 0x21, 0xd0, 0x01, 0x29, 0x7d, 0xd0, 0x02, 0x29, 0x7c, 0xd0, 0x03, 0x29, 0x7b, 0xd0, ++ 0x40, 0x30, 0x82, 0x7a, 0xc8, 0x4f, 0xcb, 0x4d, 0x7f, 0x3f, 0x13, 0x00, 0x07, 0xf0, 0x70, 0xf8, ++ 0x25, 0xfd, 0xfc, 0xfb, 0xfa, 0xfa, 0xfa, 0xf9, 0xf9, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, ++ 0xf2, 0xf1, 0xf0, 0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xea, 0xe9, 0xea, 0xea, 0xea, 0xea, 0xea, ++ 0xe9, 0xea, 0xea, 0xe9, 0xe8, 0xe8, 0xe9, 0x00, 0xd0, 0x7a, 0x00, 0x28, 0x03, 0xd0, 0x02, 0x21, ++ 0x01, 0x20, 0x06, 0xf0, 0x7f, 0xff, 0xb9, 0x4f, 0x39, 0x68, 0xbb, 0x48, 0x08, 0x18, 0x40, 0x8a, ++ 0x40, 0x07, 0x80, 0x0f, 0x24, 0xd0, 0x01, 0x28, 0x2b, 0xd0, 0xb6, 0x4d, 0x28, 0x68, 0x40, 0x30, ++ 0x40, 0x7a, 0x00, 0x28, 0x01, 0xd0, 0x02, 0xf0, 0xa1, 0xf9, 0x28, 0x68, 0x01, 0x21, 0x40, 0x30, ++ 0x81, 0x74, 0x38, 0x68, 0xb1, 0x4d, 0x40, 0x19, 0x00, 0x8e, 0x40, 0x07, 0x80, 0x0f, 0x01, 0x28, ++ 0x7e, 0xd0, 0xaf, 0x4c, 0x20, 0x7d, 0x00, 0x28, 0x00, 0xd0, 0x7b, 0xe7, 0x00, 0x90, 0x03, 0x46, ++ 0x01, 0x22, 0x04, 0x21, 0x01, 0x90, 0x06, 0xf0, 0xdf, 0xfe, 0x01, 0x20, 0x20, 0x75, 0xfe, 0xbd, ++ 0xa4, 0x48, 0x00, 0x68, 0x40, 0x30, 0x40, 0x7a, 0x00, 0x28, 0xf8, 0xd0, 0x02, 0xf0, 0x7e, 0xf9, ++ 0xfe, 0xbd, 0x39, 0x68, 0xa1, 0x48, 0xc0, 0x38, 0x08, 0x18, 0x80, 0x89, 0xc0, 0x07, 0xc0, 0x0f, ++ 0x0b, 0xd0, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x86, 0x82, 0x3a, 0x68, 0x00, 0x20, 0x9b, 0x49, ++ 0xc0, 0x39, 0x51, 0x18, 0x88, 0x81, 0x02, 0xf0, 0x96, 0xf9, 0x03, 0x25, 0x2d, 0x07, 0xa8, 0x8a, ++ 0x02, 0x20, 0xc0, 0x43, 0xa8, 0x82, 0x3a, 0x68, 0x02, 0x20, 0x94, 0x49, 0xc0, 0x39, 0x51, 0x18, ++ 0x48, 0x81, 0x02, 0xe0, 0xb2, 0xe0, 0x2b, 0xe1, 0x12, 0xe2, 0x02, 0xf0, 0x57, 0xf9, 0x8d, 0x48, ++ 0x00, 0x68, 0x00, 0x78, 0xc0, 0x07, 0x01, 0xd0, 0x06, 0xf0, 0xe4, 0xfb, 0x39, 0x68, 0x8a, 0x48, ++ 0x08, 0x18, 0xc0, 0x8a, 0x39, 0x68, 0x00, 0x07, 0x00, 0x0f, 0xff, 0x31, 0x01, 0x31, 0x89, 0x8d, ++ 0x00, 0x23, 0x89, 0x07, 0xc9, 0x0f, 0x09, 0x01, 0x01, 0x43, 0x82, 0x48, 0x00, 0x68, 0x00, 0x88, ++ 0x02, 0x0a, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 0x00, 0x0a, 0x01, 0x43, 0x03, 0x20, 0x02, 0x22, ++ 0x01, 0x91, 0x00, 0x90, 0x11, 0x46, 0x01, 0x20, 0x06, 0xf0, 0x86, 0xfe, 0x02, 0xf0, 0x89, 0xfa, ++ 0xff, 0xf7, 0x56, 0xfe, 0x00, 0x28, 0x7b, 0x4b, 0xa8, 0x8a, 0x12, 0xd0, 0x02, 0x20, 0xc0, 0x43, ++ 0xa8, 0x82, 0x3a, 0x68, 0x02, 0x20, 0x78, 0x49, 0x51, 0x18, 0xc8, 0x80, 0xa8, 0x8a, 0xab, 0x82, ++ 0x0d, 0x21, 0x3a, 0x68, 0x89, 0x01, 0xd1, 0x20, 0x40, 0x02, 0x10, 0x18, 0xc1, 0x84, 0x11, 0xe0, ++ 0x1d, 0xe0, 0xab, 0x82, 0xff, 0x21, 0x3a, 0x68, 0x41, 0x31, 0xd1, 0x20, 0x40, 0x02, 0x10, 0x18, ++ 0xc1, 0x84, 0xa8, 0x8a, 0x02, 0x20, 0xc0, 0x43, 0xa8, 0x82, 0x3a, 0x68, 0x00, 0x20, 0x6a, 0x49, ++ 0x51, 0x18, 0xc8, 0x80, 0xa8, 0x8a, 0xae, 0x82, 0x39, 0x68, 0x67, 0x48, 0x40, 0x30, 0x08, 0x18, ++ 0x44, 0x81, 0x60, 0x48, 0x00, 0x68, 0xc1, 0x7a, 0x49, 0x1c, 0xc1, 0x72, 0xfe, 0xbd, 0x03, 0x24, ++ 0x24, 0x07, 0xa0, 0x8a, 0x02, 0x20, 0xc0, 0x43, 0xa0, 0x82, 0x39, 0x68, 0x02, 0x20, 0x49, 0x19, ++ 0x48, 0x85, 0x38, 0x68, 0x40, 0x19, 0x80, 0x8d, 0xc0, 0x07, 0xc0, 0x0f, 0x1e, 0xd0, 0x15, 0xe0, ++ 0x42, 0xe3, 0xc2, 0xe1, 0xdd, 0xe2, 0x57, 0xe3, 0xd6, 0xe3, 0x51, 0xe2, 0xc2, 0xe2, 0xbd, 0xe2, ++ 0x66, 0xe3, 0xf3, 0xe2, 0xd1, 0xe2, 0xae, 0xe2, 0x97, 0xe2, 0x43, 0xe3, 0x2b, 0xe2, 0x03, 0xe2, ++ 0x80, 0xe2, 0xf9, 0xe1, 0xdf, 0xe1, 0xbd, 0xe2, 0xca, 0xe1, 0xc1, 0xe1, 0xa0, 0x8a, 0xa6, 0x82, ++ 0x39, 0x68, 0x00, 0x20, 0x49, 0x19, 0x88, 0x85, 0x02, 0xf0, 0x3c, 0xf9, 0x02, 0xf0, 0xe0, 0xf8, ++ 0x47, 0x48, 0x00, 0x78, 0xc0, 0x07, 0x01, 0xd0, 0x06, 0xf0, 0xe8, 0xfb, 0x44, 0x48, 0x02, 0x21, ++ 0x00, 0x88, 0x00, 0x23, 0x40, 0xba, 0x00, 0x91, 0x01, 0x90, 0x01, 0x22, 0x05, 0x21, 0x18, 0x46, ++ 0x06, 0xf0, 0x0a, 0xfe, 0x3e, 0x49, 0x00, 0x20, 0x08, 0x75, 0x02, 0xf0, 0xc6, 0xf9, 0xa0, 0x8a, ++ 0xa6, 0x82, 0x39, 0x68, 0x01, 0x20, 0x49, 0x19, 0x48, 0x85, 0xfe, 0xbd, 0x01, 0x46, 0x40, 0x31, ++ 0x4a, 0x7a, 0x34, 0x4d, 0x00, 0x2a, 0x05, 0xd0, 0x80, 0x78, 0x00, 0x28, 0x0e, 0xd1, 0x08, 0x7a, ++ 0x00, 0x28, 0x0b, 0xd0, 0x00, 0x20, 0x88, 0x72, 0x2c, 0x4b, 0x18, 0x68, 0x0d, 0x26, 0x76, 0x03, ++ 0x80, 0x19, 0x40, 0x8e, 0x80, 0x07, 0xc0, 0x0f, 0x1d, 0xd0, 0x26, 0xe0, 0x02, 0xf0, 0x8e, 0xf8, ++ 0xff, 0xf7, 0xb6, 0xfd, 0x00, 0x28, 0xef, 0xd0, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x86, 0x82, ++ 0x22, 0x49, 0x0b, 0x68, 0xd1, 0x22, 0x52, 0x02, 0x9b, 0x18, 0xdc, 0x84, 0x83, 0x8a, 0x86, 0x82, ++ 0x0b, 0x68, 0xff, 0x33, 0x01, 0x33, 0x9c, 0x85, 0x83, 0x8a, 0x86, 0x82, 0x09, 0x68, 0x00, 0x20, ++ 0x89, 0x18, 0xc8, 0x84, 0xd8, 0xe7, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x1f, 0x49, 0x81, 0x82, ++ 0x01, 0x20, 0x19, 0x68, 0x40, 0x03, 0x89, 0x19, 0x08, 0x84, 0x18, 0x68, 0x80, 0x19, 0x80, 0x8f, ++ 0xc2, 0x0a, 0x28, 0x68, 0x01, 0x46, 0x80, 0x31, 0x8a, 0x72, 0x01, 0x2a, 0x0c, 0xd0, 0x81, 0x7a, ++ 0x49, 0x1c, 0x81, 0x72, 0x18, 0x68, 0x80, 0x19, 0x40, 0x8f, 0x00, 0x23, 0xc0, 0xb2, 0x02, 0x22, ++ 0x07, 0x21, 0x00, 0x94, 0x01, 0x90, 0x0b, 0xe0, 0xc8, 0x7a, 0x01, 0x28, 0x0b, 0xd0, 0x18, 0x68, ++ 0x80, 0x19, 0x40, 0x8f, 0x00, 0x23, 0xc0, 0xb2, 0x02, 0x22, 0x06, 0x21, 0x00, 0x94, 0x01, 0x90, ++ 0x01, 0x20, 0x06, 0xf0, 0x99, 0xfd, 0x1c, 0xe1, 0xfe, 0xff, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, ++ 0x60, 0xea, 0x00, 0x00, 0x90, 0x00, 0x00, 0x20, 0x00, 0xa3, 0x01, 0x00, 0xc0, 0xa1, 0x01, 0x00, ++ 0x00, 0x04, 0x00, 0x20, 0x0f, 0xfc, 0x00, 0x00, 0xc0, 0xa0, 0x01, 0x00, 0xff, 0xdf, 0x00, 0x00, ++ 0x01, 0x46, 0x40, 0x31, 0x8a, 0x7a, 0xf7, 0x4f, 0x00, 0x2a, 0x4c, 0x72, 0x03, 0xd0, 0x02, 0x20, ++ 0x00, 0x94, 0x01, 0x90, 0x04, 0xe1, 0xca, 0x79, 0x52, 0x08, 0x52, 0x00, 0xca, 0x71, 0x80, 0x78, ++ 0x00, 0x28, 0x58, 0xd1, 0x08, 0x7a, 0x00, 0x28, 0x55, 0xd0, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, ++ 0x20, 0x21, 0xc9, 0x43, 0x81, 0x82, 0xec, 0x48, 0x00, 0x21, 0x02, 0x68, 0x0d, 0x20, 0x40, 0x03, ++ 0x10, 0x18, 0x01, 0x84, 0x02, 0xf0, 0x4f, 0xfb, 0xe7, 0x49, 0x08, 0x68, 0x40, 0x19, 0xc0, 0x8a, ++ 0x09, 0x68, 0x00, 0x07, 0x00, 0x0f, 0xff, 0x31, 0x01, 0x31, 0x89, 0x8d, 0x00, 0x23, 0x89, 0x07, ++ 0xc9, 0x0f, 0x09, 0x01, 0x01, 0x43, 0x38, 0x68, 0x00, 0x88, 0x02, 0x0a, 0x12, 0x02, 0x11, 0x43, ++ 0x00, 0x06, 0x00, 0x0a, 0x01, 0x43, 0x03, 0x20, 0x01, 0x91, 0x00, 0x90, 0x02, 0x22, 0x1a, 0x21, ++ 0x01, 0x20, 0x06, 0xf0, 0x41, 0xfd, 0xd9, 0x48, 0x02, 0x21, 0x00, 0x88, 0x0a, 0x46, 0x40, 0xba, ++ 0x00, 0x91, 0x01, 0x90, 0x00, 0x23, 0x19, 0x21, 0x01, 0x20, 0x06, 0xf0, 0x35, 0xfd, 0x38, 0x68, ++ 0x80, 0x30, 0x84, 0x46, 0x00, 0x7a, 0x40, 0x06, 0x7e, 0xd4, 0xcf, 0x4d, 0x00, 0x22, 0x03, 0x21, ++ 0x09, 0x07, 0x88, 0x8a, 0x84, 0x20, 0xc0, 0x43, 0x88, 0x82, 0xd0, 0x07, 0x2e, 0x68, 0x00, 0x0e, ++ 0xcb, 0x4b, 0xf6, 0x18, 0x00, 0x1d, 0xb0, 0x85, 0x00, 0x20, 0x00, 0x21, 0x10, 0x28, 0x05, 0xd2, ++ 0x1f, 0x23, 0x1b, 0x1a, 0x04, 0xe0, 0x02, 0xf0, 0x76, 0xfa, 0xb5, 0xe7, 0x03, 0x46, 0x10, 0x3b, ++ 0xc4, 0x4f, 0xdb, 0xb2, 0xbe, 0x8a, 0x00, 0x2a, 0x07, 0xd0, 0x1f, 0x26, 0xf6, 0x43, 0xbe, 0x82, ++ 0x2f, 0x68, 0xbf, 0x4e, 0xbe, 0x19, 0xf3, 0x85, 0x06, 0xe0, 0xbf, 0x4e, 0xbe, 0x82, 0x2f, 0x68, ++ 0x1e, 0x02, 0xbb, 0x4b, 0xfb, 0x18, 0x9e, 0x85, 0xb9, 0x4f, 0x00, 0x23, 0x80, 0x37, 0x2e, 0x68, ++ 0xf6, 0x19, 0x36, 0x8a, 0x36, 0x0a, 0xf6, 0x07, 0xf6, 0x0f, 0x01, 0xd0, 0x49, 0x1c, 0xc9, 0xb2, ++ 0x5b, 0x1c, 0xdb, 0xb2, 0x0a, 0x2b, 0xf2, 0xd3, 0x00, 0x28, 0x04, 0xd0, 0x05, 0x29, 0x2d, 0xd8, ++ 0x1f, 0x28, 0x0f, 0xd0, 0x26, 0xe0, 0x05, 0x29, 0x24, 0xd9, 0x00, 0x2a, 0x17, 0xd0, 0xad, 0x48, ++ 0x81, 0x8a, 0x1f, 0x21, 0xc9, 0x43, 0x81, 0x82, 0x2b, 0x68, 0x10, 0x21, 0xa8, 0x48, 0x18, 0x18, ++ 0xc1, 0x85, 0x1b, 0xe0, 0x00, 0x2a, 0x0a, 0xd0, 0xa6, 0x48, 0x81, 0x8a, 0x1f, 0x21, 0xc9, 0x43, ++ 0x81, 0x82, 0x2b, 0x68, 0x10, 0x20, 0xa2, 0x49, 0x59, 0x18, 0xc8, 0x85, 0x0e, 0xe0, 0xa1, 0x48, ++ 0x81, 0x8a, 0xa1, 0x49, 0x81, 0x82, 0x01, 0x20, 0x2b, 0x68, 0x00, 0x03, 0x9c, 0x49, 0x59, 0x18, ++ 0x88, 0x85, 0x03, 0xe0, 0x40, 0x1c, 0xc0, 0xb2, 0x20, 0x28, 0x9e, 0xd3, 0x52, 0x1c, 0xd2, 0xb2, ++ 0x02, 0x2a, 0x8c, 0xd3, 0x97, 0x48, 0x81, 0x8a, 0x04, 0x21, 0xc9, 0x43, 0x81, 0x82, 0x2a, 0x68, ++ 0x00, 0x20, 0x93, 0x49, 0x51, 0x18, 0x00, 0xe0, 0x06, 0xe0, 0x88, 0x85, 0x60, 0x46, 0x00, 0x7a, ++ 0x40, 0x21, 0x08, 0x43, 0x61, 0x46, 0x08, 0x72, 0x8e, 0x48, 0x81, 0x8a, 0x8f, 0x49, 0x81, 0x82, ++ 0x89, 0x48, 0x01, 0x22, 0x01, 0x68, 0x92, 0x03, 0x0d, 0x20, 0x40, 0x03, 0x08, 0x18, 0x02, 0x84, ++ 0x85, 0x48, 0x01, 0x68, 0x0d, 0x20, 0x40, 0x03, 0x08, 0x18, 0x80, 0x8f, 0x81, 0x4d, 0xc0, 0x0a, ++ 0x29, 0x68, 0x80, 0x31, 0x88, 0x72, 0x03, 0x28, 0x05, 0xd0, 0xc9, 0x7a, 0x03, 0x29, 0x08, 0xd9, ++ 0x11, 0x29, 0x06, 0xd0, 0x0d, 0xe0, 0xc8, 0x7a, 0x03, 0x28, 0x0a, 0xd0, 0x01, 0x21, 0x25, 0x20, ++ 0x05, 0xe0, 0x03, 0x28, 0x05, 0xd9, 0x11, 0x28, 0x03, 0xd0, 0x01, 0x21, 0x26, 0x20, 0x06, 0xf0, ++ 0xf1, 0xfc, 0x28, 0x68, 0x40, 0x30, 0x84, 0x74, 0xfe, 0xbd, 0x44, 0x72, 0x00, 0x94, 0x01, 0x94, ++ 0x00, 0x23, 0x02, 0x22, 0x15, 0x21, 0x01, 0x20, 0x06, 0xf0, 0x6e, 0xfc, 0x71, 0x48, 0x81, 0x8a, ++ 0x86, 0x82, 0x6d, 0x48, 0x01, 0x68, 0x0d, 0x20, 0x40, 0x03, 0x08, 0x18, 0x44, 0x86, 0xfe, 0xbd, ++ 0x11, 0x29, 0x0a, 0xd0, 0x00, 0x20, 0xc0, 0x43, 0x06, 0xf0, 0x62, 0xfa, 0x06, 0xf0, 0x75, 0xfa, ++ 0x28, 0x68, 0x8a, 0x21, 0x09, 0x5c, 0x07, 0x29, 0x03, 0xd0, 0x28, 0x68, 0x40, 0x30, 0x84, 0x72, ++ 0xfe, 0xbd, 0x81, 0x78, 0x00, 0x29, 0x06, 0xd1, 0x40, 0x30, 0x01, 0x7a, 0x00, 0x29, 0x02, 0xd0, ++ 0x13, 0x21, 0x81, 0x72, 0xd6, 0xe0, 0x03, 0xf0, 0x17, 0xf9, 0x02, 0x28, 0xf0, 0xd0, 0x5d, 0x48, ++ 0x81, 0x8a, 0x87, 0x82, 0x58, 0x4c, 0x80, 0x23, 0x26, 0x68, 0x0d, 0x22, 0x52, 0x03, 0xb6, 0x18, ++ 0x73, 0x80, 0x83, 0x8a, 0x87, 0x82, 0x21, 0x68, 0x00, 0x20, 0x89, 0x18, 0x48, 0x80, 0x28, 0x68, ++ 0x06, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfe, 0xbd, 0x04, 0xf0, 0xc3, 0xfd, 0x02, 0x28, 0xfa, 0xd0, ++ 0x04, 0xf0, 0xbf, 0xfd, 0x01, 0x28, 0xf6, 0xd0, 0x03, 0xf0, 0xcd, 0xfe, 0x02, 0x28, 0xf2, 0xd0, ++ 0x28, 0x68, 0x53, 0x21, 0x09, 0x5c, 0x00, 0x29, 0x04, 0xd0, 0x01, 0x29, 0x26, 0xd1, 0x01, 0x78, ++ 0x49, 0x07, 0x23, 0xd5, 0x00, 0x78, 0x00, 0x06, 0x20, 0xd4, 0x17, 0x20, 0x00, 0xf0, 0x82, 0xfa, ++ 0x03, 0xf0, 0xca, 0xf8, 0x28, 0x68, 0x05, 0x21, 0x41, 0x84, 0x09, 0x20, 0x03, 0xf0, 0x19, 0xff, ++ 0x03, 0xf0, 0x9a, 0xfc, 0x29, 0x68, 0x60, 0x31, 0x08, 0x70, 0x00, 0xf0, 0x48, 0xfa, 0x28, 0x68, ++ 0x0b, 0x21, 0x40, 0x30, 0x81, 0x72, 0x00, 0xf0, 0x8a, 0xfa, 0x00, 0x28, 0xcb, 0xd0, 0x04, 0xf0, ++ 0x8f, 0xf8, 0x28, 0x68, 0x40, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0xee, 0xd0, 0x28, 0x68, 0x00, 0x23, ++ 0x60, 0x30, 0x02, 0x78, 0x41, 0x78, 0x12, 0x02, 0x80, 0x78, 0x11, 0x43, 0x00, 0x04, 0x01, 0x43, ++ 0x03, 0x20, 0x01, 0x22, 0x01, 0x91, 0x00, 0x90, 0x12, 0x21, 0x10, 0x46, 0x06, 0xf0, 0xe4, 0xfb, ++ 0x28, 0x68, 0x00, 0x21, 0x40, 0x30, 0x81, 0x74, 0x01, 0x75, 0x28, 0x68, 0x01, 0x46, 0x40, 0x31, ++ 0xca, 0x7a, 0x28, 0x2a, 0x01, 0xd0, 0x29, 0x2a, 0x02, 0xd1, 0x0a, 0x7d, 0x01, 0x2a, 0x73, 0xd0, ++ 0xca, 0x7c, 0x00, 0x2a, 0x04, 0xd0, 0x01, 0x2a, 0x0a, 0xd1, 0x03, 0x78, 0x5b, 0x07, 0x07, 0xd5, ++ 0x03, 0x78, 0x1b, 0x06, 0x04, 0xd4, 0x00, 0x23, 0x60, 0x30, 0x83, 0x71, 0x03, 0x72, 0x02, 0xe0, ++ 0x60, 0x30, 0x84, 0x71, 0x04, 0x72, 0x02, 0x2a, 0x27, 0xd3, 0x1a, 0x48, 0x82, 0x8a, 0x0f, 0x22, ++ 0xd2, 0x43, 0x82, 0x82, 0x14, 0x4a, 0x02, 0x24, 0x15, 0x68, 0x0d, 0x23, 0x5b, 0x03, 0xed, 0x18, ++ 0x2c, 0x86, 0x84, 0x8a, 0x16, 0x4c, 0x84, 0x82, 0x12, 0x68, 0x00, 0x15, 0xd2, 0x18, 0x10, 0x86, ++ 0x09, 0x20, 0x27, 0xe1, 0x00, 0x21, 0x81, 0x72, 0x0e, 0x48, 0x82, 0x8a, 0x0f, 0x22, 0xd2, 0x43, ++ 0x82, 0x82, 0x09, 0x4a, 0x13, 0x68, 0x0d, 0x26, 0x76, 0x03, 0x9b, 0x19, 0x19, 0x86, 0x83, 0x8a, ++ 0x0b, 0x4b, 0x83, 0x82, 0x10, 0x68, 0x80, 0x19, 0x01, 0x86, 0x04, 0xf0, 0xb1, 0xfc, 0x00, 0x28, ++ 0x10, 0xd0, 0x60, 0xe7, 0x90, 0x00, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x20, ++ 0x00, 0xa1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0xe0, 0x00, 0x00, 0xff, 0xbf, 0x00, 0x00, ++ 0xff, 0xfc, 0x00, 0x00, 0x52, 0xe0, 0x03, 0xf0, 0x53, 0xfe, 0x02, 0x28, 0xe9, 0xd0, 0x28, 0x68, ++ 0x80, 0x30, 0xc1, 0x7b, 0x00, 0x29, 0x18, 0xd0, 0x00, 0x21, 0xc1, 0x73, 0x04, 0xf0, 0xd2, 0xfd, ++ 0x00, 0x28, 0xde, 0xd1, 0x92, 0x49, 0x0a, 0x68, 0x0d, 0x20, 0x40, 0x03, 0x12, 0x18, 0x92, 0x8e, ++ 0xd2, 0x07, 0x7d, 0xd0, 0x28, 0x68, 0x88, 0x21, 0x09, 0x5c, 0x49, 0x07, 0x79, 0xd5, 0x40, 0x30, ++ 0xc0, 0x7c, 0x00, 0x28, 0x76, 0xd0, 0xe3, 0xe0, 0x44, 0xe0, 0x04, 0xf0, 0xa2, 0xfb, 0x02, 0x28, ++ 0xc7, 0xd0, 0x28, 0x68, 0x40, 0x30, 0x81, 0x79, 0x49, 0x07, 0x05, 0xd5, 0x80, 0x7d, 0x01, 0x28, ++ 0x02, 0xd0, 0x04, 0xf0, 0xd4, 0xf9, 0x01, 0xe0, 0x04, 0xf0, 0x27, 0xfa, 0x02, 0x28, 0xb8, 0xd0, ++ 0x28, 0x68, 0x84, 0x21, 0x09, 0x5c, 0x00, 0x29, 0x4e, 0xd1, 0x60, 0x30, 0x81, 0x79, 0x02, 0x29, ++ 0x02, 0xd0, 0x00, 0x29, 0x02, 0xd0, 0x05, 0xe0, 0x84, 0x71, 0x08, 0xe0, 0x04, 0xf0, 0xb5, 0xfa, ++ 0x02, 0x28, 0xa6, 0xd0, 0x28, 0x68, 0x60, 0x30, 0x80, 0x79, 0x01, 0x28, 0xb3, 0xd1, 0x28, 0x68, ++ 0x60, 0x30, 0x01, 0x7a, 0x02, 0x29, 0x1c, 0xd0, 0x04, 0xf0, 0x93, 0xf8, 0x28, 0x68, 0x60, 0x30, ++ 0x81, 0x79, 0x01, 0x29, 0xa7, 0xd1, 0x00, 0x7a, 0x01, 0x28, 0xa4, 0xd1, 0x28, 0x68, 0x40, 0x30, ++ 0x81, 0x7d, 0x01, 0x29, 0x06, 0xd0, 0x01, 0x7d, 0x49, 0x1c, 0xc9, 0xb2, 0x01, 0x75, 0x04, 0x29, ++ 0x00, 0xd2, 0x3a, 0xe7, 0x29, 0x68, 0x0a, 0x46, 0x40, 0x32, 0xd0, 0x7c, 0x00, 0x28, 0x02, 0xd0, ++ 0x23, 0xe0, 0x04, 0x72, 0xea, 0xe7, 0x08, 0x88, 0x43, 0x07, 0x1e, 0xd5, 0x0b, 0x79, 0x1e, 0x06, ++ 0x05, 0xd5, 0x58, 0x06, 0x40, 0x0e, 0xd0, 0x73, 0x00, 0xf0, 0xee, 0xfb, 0x15, 0xe0, 0x83, 0x06, ++ 0x9b, 0x0f, 0x02, 0x2b, 0x11, 0xd0, 0x92, 0x79, 0x12, 0x07, 0x0e, 0xd5, 0x00, 0x06, 0x0c, 0xd4, ++ 0x80, 0x31, 0x48, 0x7b, 0xc0, 0x06, 0x08, 0xd4, 0x04, 0xf0, 0x92, 0xfe, 0x02, 0x28, 0x97, 0xd0, ++ 0x28, 0x68, 0x80, 0x30, 0x00, 0x79, 0x00, 0x28, 0x8f, 0xd1, 0x95, 0x21, 0x28, 0x68, 0x02, 0xe0, ++ 0x2b, 0xe0, 0x73, 0xe0, 0x68, 0xe0, 0x09, 0x5c, 0x00, 0x29, 0x0d, 0xd0, 0x40, 0x30, 0xc1, 0x7a, ++ 0x2c, 0x29, 0x09, 0xd0, 0x16, 0x21, 0x81, 0x72, 0xff, 0xf7, 0xba, 0xf9, 0x28, 0x68, 0x40, 0x30, ++ 0xc0, 0x7a, 0x2c, 0x28, 0x00, 0xd0, 0xa6, 0xe6, 0x28, 0x68, 0x56, 0x21, 0x09, 0x5c, 0x01, 0x29, ++ 0x00, 0xd1, 0x5b, 0xe7, 0x01, 0x78, 0x09, 0x06, 0xfb, 0xd4, 0x00, 0x21, 0x60, 0x30, 0xc1, 0x71, ++ 0x04, 0xf0, 0x57, 0xfb, 0x02, 0x28, 0xee, 0xd0, 0x28, 0x68, 0x60, 0x30, 0xc0, 0x79, 0x00, 0x28, ++ 0xf6, 0xd0, 0x28, 0x68, 0x80, 0x30, 0xc4, 0x73, 0x3d, 0xe7, 0x03, 0x26, 0x36, 0x07, 0xb2, 0x8a, ++ 0x38, 0x4b, 0xb3, 0x82, 0x36, 0x4a, 0x00, 0x27, 0x11, 0x68, 0x09, 0x18, 0x0f, 0x84, 0xb1, 0x8a, ++ 0xb3, 0x82, 0x12, 0x68, 0x20, 0x21, 0x10, 0x18, 0x01, 0x84, 0x06, 0xf0, 0xd5, 0xf8, 0x40, 0x1c, ++ 0x40, 0x42, 0x01, 0x21, 0xc0, 0x08, 0x09, 0x04, 0x88, 0x42, 0x01, 0xd3, 0x49, 0x1e, 0x00, 0xe0, ++ 0x81, 0xb2, 0x28, 0x68, 0x41, 0x82, 0x01, 0x7b, 0x49, 0x1c, 0x01, 0x73, 0x40, 0x30, 0x04, 0x72, ++ 0x02, 0x21, 0x0e, 0x20, 0x06, 0xf0, 0x0e, 0xfb, 0x28, 0x68, 0x01, 0x46, 0x80, 0x30, 0x42, 0x7d, ++ 0x00, 0x2a, 0x0b, 0xd0, 0x42, 0x7e, 0x00, 0x2a, 0x08, 0xd0, 0xb2, 0x8a, 0x07, 0x22, 0xd2, 0x43, ++ 0xb2, 0x82, 0x1f, 0x4a, 0x12, 0x68, 0x20, 0x4b, 0xd2, 0x18, 0x17, 0x85, 0x07, 0x73, 0x40, 0x31, ++ 0x8c, 0x74, 0x02, 0x20, 0x88, 0x72, 0xfe, 0xbd, 0x03, 0xf0, 0x26, 0xf8, 0x02, 0x28, 0xfa, 0xd0, ++ 0x28, 0x68, 0xfb, 0x22, 0x80, 0x30, 0x01, 0x7a, 0x11, 0x40, 0x01, 0x72, 0x1f, 0x20, 0x03, 0xf0, ++ 0xd8, 0xfd, 0x28, 0x68, 0x15, 0x21, 0x40, 0x30, 0x81, 0x72, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, ++ 0x87, 0x82, 0x0f, 0x48, 0x80, 0x21, 0x02, 0x68, 0x0d, 0x20, 0x40, 0x03, 0x10, 0x18, 0x01, 0x84, ++ 0x29, 0x68, 0xff, 0x20, 0x80, 0x31, 0x88, 0x72, 0x28, 0x68, 0x40, 0x30, 0x84, 0x74, 0x00, 0xf0, ++ 0xe6, 0xf8, 0x00, 0x28, 0xd7, 0xd0, 0x28, 0x68, 0x01, 0x7a, 0xc9, 0x09, 0xe5, 0xd1, 0x90, 0x21, ++ 0x09, 0x5c, 0x00, 0x29, 0xe1, 0xd1, 0x40, 0x30, 0x84, 0x75, 0xff, 0xf7, 0x91, 0xf8, 0x67, 0xe6, ++ 0x84, 0x00, 0x00, 0x20, 0xdf, 0xff, 0x00, 0x00, 0x80, 0xa0, 0x01, 0x00, 0x00, 0x28, 0x16, 0xd0, ++ 0x01, 0x28, 0x15, 0xd0, 0x00, 0x21, 0x40, 0x00, 0x40, 0x08, 0x49, 0x1c, 0x40, 0x00, 0x49, 0xb2, ++ 0x00, 0x28, 0xfa, 0xda, 0xc0, 0x0d, 0xe0, 0x22, 0x10, 0x40, 0xca, 0x17, 0xd2, 0x0e, 0x52, 0x18, ++ 0x52, 0x09, 0x52, 0x01, 0x89, 0x1a, 0x1f, 0x22, 0x51, 0x1a, 0x40, 0x18, 0xc0, 0xb2, 0x70, 0x47, ++ 0xe0, 0x20, 0x70, 0x47, 0xf0, 0xb5, 0x03, 0x24, 0x24, 0x07, 0xa1, 0x8a, 0xfa, 0x49, 0xa1, 0x82, ++ 0x00, 0x28, 0x01, 0xdd, 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0xf8, 0x4a, 0x89, 0x02, 0xf8, 0x4e, ++ 0x89, 0x18, 0x32, 0x68, 0x0d, 0x27, 0x7f, 0x03, 0xd2, 0x19, 0x11, 0x81, 0x01, 0x23, 0x00, 0x21, ++ 0x5b, 0x02, 0x45, 0x42, 0x07, 0xe0, 0xa2, 0x8a, 0xf2, 0x4a, 0xa2, 0x82, 0x32, 0x68, 0xd2, 0x19, ++ 0x13, 0x81, 0x49, 0x1c, 0x49, 0xb2, 0x00, 0x28, 0x01, 0xdb, 0x02, 0x46, 0x00, 0xe0, 0x2a, 0x46, ++ 0x8a, 0x42, 0xf0, 0xdc, 0xf0, 0xbd, 0xf0, 0xb5, 0xeb, 0x48, 0x53, 0x21, 0x00, 0x68, 0x01, 0x23, ++ 0x09, 0x5c, 0x0d, 0x27, 0x03, 0x24, 0xe7, 0x4a, 0x5b, 0x02, 0x7f, 0x03, 0x24, 0x07, 0xe4, 0x4d, ++ 0x00, 0x29, 0x0c, 0xd0, 0x26, 0x21, 0x41, 0x5e, 0xe4, 0x4e, 0x08, 0x46, 0x11, 0x30, 0x0c, 0xd0, ++ 0x0f, 0x29, 0x17, 0xd0, 0xa0, 0x8a, 0xa2, 0x82, 0x28, 0x68, 0xc0, 0x19, 0x03, 0x81, 0xa0, 0x8a, ++ 0xa2, 0x82, 0x28, 0x68, 0xc0, 0x19, 0x03, 0x81, 0x1b, 0xe0, 0x3e, 0x20, 0xc0, 0x43, 0xff, 0xf7, ++ 0xb1, 0xff, 0x01, 0x20, 0xff, 0xf7, 0xae, 0xff, 0xa0, 0x8a, 0xff, 0x20, 0xa0, 0x82, 0x01, 0x20, ++ 0x80, 0x02, 0x0b, 0xe0, 0x3e, 0x20, 0xc0, 0x43, 0xff, 0xf7, 0xa4, 0xff, 0x01, 0x20, 0xff, 0xf7, ++ 0xa1, 0xff, 0xa0, 0x8a, 0xff, 0x20, 0xa0, 0x82, 0x01, 0x20, 0xc0, 0x02, 0x29, 0x68, 0x89, 0x19, ++ 0x88, 0x84, 0xcd, 0x48, 0x00, 0x68, 0xc1, 0x8c, 0x49, 0x1c, 0xc1, 0x84, 0xf0, 0xbd, 0x30, 0xb5, ++ 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0xca, 0x4a, 0x82, 0x82, 0xc5, 0x49, 0x00, 0x24, 0x0d, 0x68, ++ 0xc6, 0x4b, 0xed, 0x18, 0x2c, 0x84, 0x84, 0x8a, 0x82, 0x82, 0x0c, 0x68, 0x52, 0x1c, 0xe3, 0x18, ++ 0x1a, 0x84, 0x82, 0x8a, 0x80, 0x22, 0xd2, 0x43, 0x82, 0x82, 0x09, 0x68, 0x80, 0x20, 0x0d, 0x22, ++ 0x52, 0x03, 0x89, 0x18, 0x08, 0x84, 0xbc, 0x48, 0xff, 0x21, 0x00, 0x68, 0x80, 0x30, 0x81, 0x72, ++ 0x30, 0xbd, 0xb7, 0x48, 0x00, 0x68, 0xb9, 0x49, 0x40, 0x18, 0x80, 0x8e, 0x80, 0x04, 0x80, 0x16, ++ 0x40, 0x42, 0x70, 0x47, 0x30, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x8a, 0x13, 0x8a, 0x82, ++ 0x42, 0x42, 0x92, 0x06, 0x0d, 0x23, 0xd2, 0x0d, 0x5b, 0x02, 0xd4, 0x18, 0xac, 0x4b, 0x1d, 0x68, ++ 0xae, 0x4a, 0xad, 0x18, 0xec, 0x82, 0x8c, 0x8a, 0xad, 0x4c, 0x8c, 0x82, 0x1b, 0x68, 0x61, 0x1c, ++ 0x9a, 0x18, 0xd1, 0x82, 0xa8, 0x49, 0x09, 0x68, 0x60, 0x31, 0x48, 0x70, 0x30, 0xbd, 0xa6, 0x48, ++ 0x00, 0x68, 0x80, 0x30, 0x80, 0x7a, 0x07, 0x28, 0x01, 0xd0, 0x00, 0x20, 0x70, 0x47, 0x01, 0x20, ++ 0x70, 0x47, 0x70, 0xb5, 0xa0, 0x48, 0x00, 0x21, 0x04, 0x68, 0x22, 0x7f, 0xa3, 0x7d, 0x9a, 0x42, ++ 0x01, 0xd3, 0xd0, 0x1a, 0x02, 0xe0, 0xbf, 0x20, 0xc0, 0x1a, 0x80, 0x18, 0xc5, 0xb2, 0xe0, 0x8c, ++ 0x63, 0x28, 0x01, 0xd1, 0x01, 0x21, 0xc9, 0x03, 0xbf, 0x2a, 0x01, 0xd3, 0x00, 0x20, 0x00, 0xe0, ++ 0x50, 0x1c, 0xc0, 0xb2, 0x83, 0x42, 0x02, 0xd1, 0x01, 0x26, 0xb6, 0x03, 0x31, 0x43, 0x9a, 0x42, ++ 0x02, 0xd1, 0x01, 0x22, 0x52, 0x03, 0x11, 0x43, 0x29, 0x43, 0xa1, 0x82, 0x70, 0xbd, 0x70, 0xb5, ++ 0xff, 0xf7, 0xd7, 0xff, 0x05, 0x46, 0xff, 0xf7, 0xca, 0xff, 0x00, 0x28, 0x63, 0xd0, 0x8a, 0x4c, ++ 0x21, 0x68, 0x08, 0x7d, 0xbb, 0x28, 0x5e, 0xd2, 0x26, 0x22, 0x8a, 0x5e, 0x63, 0x2a, 0x5a, 0xd0, ++ 0x40, 0x31, 0xce, 0x7c, 0x82, 0x48, 0x85, 0x49, 0x86, 0x4b, 0x00, 0x2e, 0x16, 0xd0, 0x10, 0x32, ++ 0x1f, 0x2a, 0x02, 0x68, 0x1d, 0xd8, 0x56, 0x18, 0x28, 0x22, 0xb2, 0x5e, 0x00, 0x68, 0x92, 0x02, ++ 0x40, 0x18, 0x40, 0x8d, 0xc0, 0xb2, 0x10, 0x43, 0xff, 0xf7, 0xd8, 0xfe, 0x02, 0x46, 0x20, 0x68, ++ 0x44, 0x21, 0x09, 0x5a, 0x00, 0x7f, 0x08, 0x18, 0x1a, 0x54, 0x1c, 0xe0, 0x02, 0x68, 0x56, 0x18, ++ 0x30, 0x22, 0xb2, 0x5e, 0x00, 0x68, 0x92, 0x02, 0x40, 0x18, 0x40, 0x8e, 0x80, 0x05, 0x80, 0x0d, ++ 0x07, 0xe0, 0x56, 0x18, 0x2c, 0x22, 0xb2, 0x5e, 0x00, 0x68, 0x92, 0x02, 0x40, 0x18, 0xc0, 0x8d, ++ 0xc0, 0xb2, 0x10, 0x43, 0xff, 0xf7, 0xba, 0xfe, 0x01, 0x46, 0x20, 0x68, 0x44, 0x22, 0x12, 0x5a, ++ 0x00, 0x7f, 0x10, 0x18, 0x19, 0x54, 0x20, 0x68, 0x05, 0x77, 0xff, 0xf7, 0x5a, 0xff, 0x1f, 0x21, ++ 0xc8, 0x42, 0x1c, 0xdc, 0x20, 0x68, 0x44, 0x22, 0x12, 0x5a, 0x04, 0x7f, 0x00, 0x21, 0x12, 0x19, ++ 0x99, 0x54, 0x01, 0x7f, 0xbf, 0x29, 0x01, 0xd3, 0x00, 0x21, 0x00, 0xe0, 0x49, 0x1c, 0x01, 0x77, ++ 0x26, 0x21, 0x41, 0x5e, 0x1f, 0x29, 0x07, 0xda, 0xff, 0xf7, 0xdd, 0xfe, 0x1f, 0x20, 0xff, 0xf7, ++ 0x49, 0xff, 0xff, 0xf7, 0x1c, 0xff, 0x70, 0xbd, 0x63, 0x21, 0xc1, 0x84, 0x70, 0xbd, 0xff, 0xf7, ++ 0x38, 0xff, 0x40, 0x1e, 0x40, 0xb2, 0xf2, 0xe7, 0xf0, 0xb5, 0xff, 0xf7, 0x62, 0xff, 0x07, 0x46, ++ 0xff, 0xf7, 0x55, 0xff, 0x00, 0x28, 0x6f, 0xd0, 0x4f, 0x4e, 0x30, 0x68, 0x01, 0x7d, 0xbb, 0x29, ++ 0x6a, 0xd2, 0x26, 0x21, 0x41, 0x5e, 0x63, 0x29, 0x66, 0xd0, 0x40, 0x30, 0xc0, 0x7c, 0x48, 0x4c, ++ 0x4a, 0x4d, 0x4c, 0x4b, 0x00, 0x28, 0x0b, 0xd0, 0x10, 0x31, 0x20, 0x68, 0x1f, 0x29, 0x12, 0xd8, ++ 0x41, 0x19, 0x28, 0x20, 0x08, 0x5e, 0x21, 0x68, 0x80, 0x02, 0x49, 0x19, 0x49, 0x8d, 0x11, 0xe0, ++ 0x20, 0x68, 0x41, 0x19, 0x30, 0x20, 0x08, 0x5e, 0x21, 0x68, 0x80, 0x02, 0x49, 0x19, 0x49, 0x8e, ++ 0x89, 0x05, 0x89, 0x0d, 0x07, 0xe0, 0x41, 0x19, 0x2c, 0x20, 0x08, 0x5e, 0x21, 0x68, 0x80, 0x02, ++ 0x49, 0x19, 0xc9, 0x8d, 0xc9, 0xb2, 0x08, 0x43, 0xff, 0xf7, 0x50, 0xfe, 0x01, 0x46, 0x30, 0x68, ++ 0x44, 0x22, 0x12, 0x5a, 0x00, 0x7f, 0x10, 0x18, 0x19, 0x54, 0x30, 0x68, 0x26, 0x21, 0x07, 0x77, ++ 0x41, 0x5e, 0x1f, 0x29, 0x02, 0xda, 0xff, 0xf7, 0x86, 0xfe, 0x2b, 0xe0, 0x44, 0x22, 0x12, 0x5a, ++ 0x00, 0x21, 0xd2, 0x19, 0x99, 0x54, 0x01, 0x7f, 0xbf, 0x29, 0x01, 0xd3, 0x00, 0x21, 0x00, 0xe0, ++ 0x49, 0x1c, 0x01, 0x77, 0xff, 0xf7, 0xdd, 0xfe, 0x1e, 0x27, 0xff, 0x43, 0xb8, 0x42, 0x24, 0xdd, ++ 0x30, 0x68, 0x40, 0x30, 0xc0, 0x7c, 0x00, 0x28, 0x17, 0xd0, 0x04, 0x20, 0xff, 0xf7, 0x42, 0xfe, ++ 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0xff, 0x21, 0x81, 0x82, 0x01, 0x20, 0x21, 0x68, 0x40, 0x02, ++ 0x49, 0x19, 0x88, 0x84, 0x30, 0x68, 0xc7, 0x84, 0xff, 0xf7, 0xc3, 0xfe, 0x40, 0x1e, 0x40, 0xb2, ++ 0xff, 0xf7, 0xc8, 0xfe, 0xff, 0xf7, 0x9b, 0xfe, 0xf0, 0xbd, 0x3e, 0x20, 0xc0, 0x43, 0xff, 0xf7, ++ 0x29, 0xfe, 0x01, 0x20, 0xff, 0xf7, 0x26, 0xfe, 0xec, 0xe7, 0x31, 0x68, 0x63, 0x20, 0xc8, 0x84, ++ 0xf0, 0xbd, 0x10, 0xb5, 0x05, 0xf0, 0x3e, 0xfe, 0x0f, 0x49, 0x02, 0x0c, 0x09, 0x68, 0x08, 0x87, ++ 0xca, 0x86, 0x88, 0x84, 0x4a, 0x84, 0x10, 0xbd, 0x10, 0xb5, 0x09, 0x4a, 0x11, 0x68, 0x0e, 0x4b, ++ 0xc9, 0x18, 0x89, 0x8e, 0x00, 0x24, 0x49, 0x04, 0x04, 0x70, 0x48, 0x08, 0x11, 0x68, 0xc9, 0x18, ++ 0xc9, 0x8e, 0x08, 0x43, 0x10, 0xbd, 0x00, 0x00, 0x80, 0x8b, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, ++ 0x84, 0x00, 0x00, 0x20, 0xff, 0xfd, 0x00, 0x00, 0x90, 0x00, 0x00, 0x20, 0x40, 0xa0, 0x01, 0x00, ++ 0xff, 0x7f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x80, 0xa1, 0x01, 0x00, 0x10, 0xb5, 0x03, 0x20, ++ 0x00, 0x07, 0x81, 0x8a, 0xff, 0x21, 0x04, 0x31, 0x81, 0x82, 0xff, 0x4a, 0x00, 0x21, 0x14, 0x68, ++ 0xfe, 0x4b, 0xe4, 0x18, 0x21, 0x84, 0x84, 0x8a, 0x81, 0x82, 0x14, 0x68, 0xe4, 0x18, 0x61, 0x84, ++ 0x84, 0x8a, 0x81, 0x82, 0x14, 0x68, 0xe4, 0x18, 0xa1, 0x84, 0x84, 0x8a, 0x81, 0x82, 0x10, 0x68, ++ 0xc0, 0x18, 0xc1, 0x84, 0xce, 0xe7, 0x10, 0xb5, 0x04, 0x46, 0xff, 0xf7, 0xdf, 0xff, 0x03, 0x21, ++ 0x09, 0x07, 0x88, 0x8a, 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0xef, 0x48, 0xe2, 0x06, 0x03, 0x68, ++ 0xd2, 0x0e, 0x0d, 0x24, 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, 0xec, 0x4a, 0x8a, 0x82, ++ 0x04, 0x68, 0x0b, 0x14, 0xe9, 0x4a, 0xa4, 0x18, 0x23, 0x84, 0x8b, 0x8a, 0xff, 0x23, 0x8b, 0x82, ++ 0x01, 0x23, 0x04, 0x68, 0x9b, 0x02, 0xa4, 0x18, 0xa3, 0x84, 0x8b, 0x8a, 0x03, 0x23, 0xdb, 0x43, ++ 0x8b, 0x82, 0x00, 0x68, 0x03, 0x21, 0x80, 0x18, 0xc1, 0x84, 0xa3, 0xe7, 0x10, 0xb5, 0x1f, 0x20, ++ 0xff, 0xf7, 0xd1, 0xff, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x30, 0x21, 0xc9, 0x43, 0x81, 0x82, ++ 0xd9, 0x49, 0x10, 0x22, 0x0b, 0x68, 0x0d, 0x24, 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x84, 0x82, 0x8a, ++ 0xd8, 0x4a, 0x82, 0x82, 0x01, 0x20, 0x09, 0x68, 0x80, 0x02, 0xd7, 0x4a, 0x89, 0x18, 0x48, 0x84, ++ 0x88, 0xe7, 0xf8, 0xb5, 0xd5, 0x4e, 0x26, 0x21, 0x30, 0x68, 0x41, 0x5e, 0x0c, 0x12, 0x4d, 0xb2, ++ 0x29, 0x46, 0x1f, 0x31, 0x3f, 0x29, 0x04, 0xd2, 0x1f, 0x2c, 0x02, 0xdc, 0x1f, 0x21, 0xcc, 0x42, ++ 0x09, 0xda, 0x01, 0x22, 0xe1, 0xb2, 0xd2, 0x03, 0x89, 0x18, 0x81, 0x82, 0x80, 0x30, 0x44, 0x70, ++ 0x85, 0x70, 0x01, 0x20, 0xf8, 0xbd, 0xff, 0xf7, 0x04, 0xfe, 0x31, 0x68, 0x40, 0x31, 0x48, 0x76, ++ 0x28, 0x46, 0xff, 0xf7, 0x07, 0xfe, 0xff, 0xf7, 0xc1, 0xff, 0x31, 0x68, 0x53, 0x20, 0x40, 0x5c, ++ 0x00, 0x28, 0x0e, 0xd0, 0x03, 0x20, 0x10, 0x27, 0x00, 0x07, 0xff, 0x22, 0xba, 0x4b, 0xfc, 0x42, ++ 0x09, 0xda, 0x67, 0x00, 0x40, 0x37, 0xcf, 0x84, 0x87, 0x8a, 0x82, 0x82, 0x01, 0x22, 0x52, 0x02, ++ 0x0a, 0xe0, 0xcc, 0x84, 0x0f, 0xe0, 0x0f, 0x2c, 0x0b, 0xdd, 0x67, 0x00, 0x3c, 0x3f, 0xcf, 0x84, ++ 0x87, 0x8a, 0x82, 0x82, 0x01, 0x22, 0xd2, 0x02, 0x1b, 0x68, 0xb0, 0x48, 0x18, 0x18, 0x82, 0x84, ++ 0x01, 0xe0, 0x60, 0x00, 0xc8, 0x84, 0xc8, 0x8c, 0x40, 0xb2, 0xff, 0xf7, 0x43, 0xfd, 0x68, 0x46, ++ 0xff, 0xf7, 0x2a, 0xff, 0xff, 0xf7, 0x1d, 0xff, 0xff, 0xf7, 0xa9, 0xfd, 0x30, 0x68, 0x01, 0x21, ++ 0x81, 0x82, 0x80, 0x30, 0x44, 0x70, 0x85, 0x70, 0x00, 0x20, 0xf8, 0xbd, 0xf0, 0xb5, 0xa2, 0x4c, ++ 0x21, 0x68, 0x0d, 0x23, 0x5b, 0x03, 0xc9, 0x18, 0x89, 0x8a, 0xa4, 0x4a, 0x09, 0x12, 0x15, 0x68, ++ 0x77, 0x22, 0x52, 0x5d, 0x09, 0x18, 0x51, 0x18, 0x49, 0x00, 0x49, 0xb2, 0x49, 0x10, 0x03, 0x22, ++ 0x12, 0x07, 0x96, 0x8a, 0x9a, 0x4e, 0x0c, 0x36, 0x96, 0x82, 0x01, 0x26, 0x27, 0x68, 0x76, 0x03, ++ 0xff, 0x18, 0x3e, 0x81, 0x0f, 0x06, 0x97, 0x4e, 0x97, 0x8a, 0x96, 0x82, 0x05, 0xd5, 0x27, 0x68, ++ 0x00, 0x26, 0xff, 0x18, 0x3e, 0x81, 0x49, 0x42, 0x04, 0xe0, 0x01, 0x26, 0x27, 0x68, 0xb6, 0x02, ++ 0xff, 0x18, 0x3e, 0x81, 0x96, 0x8a, 0x7f, 0x26, 0xf6, 0x43, 0x96, 0x82, 0x27, 0x68, 0x01, 0x26, ++ 0xff, 0x18, 0x3e, 0x81, 0x00, 0x26, 0x0a, 0xe0, 0x94, 0x8a, 0x8d, 0x4c, 0x94, 0x82, 0x86, 0x4f, ++ 0x01, 0x24, 0x3f, 0x68, 0x64, 0x02, 0xff, 0x18, 0x3c, 0x81, 0x76, 0x1c, 0x76, 0xb2, 0x8e, 0x42, ++ 0xf2, 0xdb, 0x40, 0x35, 0x28, 0x74, 0xf0, 0xbd, 0xf0, 0xb5, 0x7f, 0x4d, 0x29, 0x68, 0x0d, 0x26, ++ 0x76, 0x03, 0x89, 0x19, 0x89, 0x8a, 0x03, 0x24, 0x08, 0x18, 0x40, 0x00, 0x40, 0xb2, 0x40, 0x10, ++ 0x24, 0x07, 0xa1, 0x8a, 0x7a, 0x49, 0x0c, 0x31, 0xa1, 0x82, 0x01, 0x21, 0x2a, 0x68, 0x89, 0x03, ++ 0x92, 0x19, 0x11, 0x81, 0x03, 0x06, 0x00, 0x21, 0x00, 0x2b, 0x76, 0x4a, 0xa3, 0x8a, 0xa2, 0x82, ++ 0x04, 0xda, 0x2a, 0x68, 0x92, 0x19, 0x11, 0x81, 0x40, 0x42, 0x04, 0xe0, 0x01, 0x22, 0x2b, 0x68, ++ 0x92, 0x02, 0x9b, 0x19, 0x1a, 0x81, 0x71, 0x4a, 0x71, 0x4f, 0x12, 0x68, 0x40, 0x32, 0x93, 0x7b, ++ 0x01, 0x22, 0x52, 0x02, 0x00, 0x2b, 0x13, 0xd0, 0xa1, 0x8a, 0x7f, 0x21, 0xc9, 0x43, 0xa1, 0x82, ++ 0x2b, 0x68, 0x01, 0x21, 0x9b, 0x19, 0x19, 0x81, 0x00, 0x21, 0x06, 0xe0, 0xa3, 0x8a, 0xa7, 0x82, ++ 0x2b, 0x68, 0x9b, 0x19, 0x1a, 0x81, 0x49, 0x1c, 0x49, 0xb2, 0x81, 0x42, 0xf6, 0xdb, 0xf0, 0xbd, ++ 0xa3, 0x8a, 0x64, 0x4b, 0xa3, 0x82, 0x40, 0x06, 0x01, 0x23, 0x40, 0x0e, 0xdb, 0x02, 0xc0, 0x18, ++ 0x2b, 0x68, 0x9b, 0x19, 0x18, 0x81, 0xa0, 0x8a, 0xa7, 0x82, 0x28, 0x68, 0x80, 0x19, 0x02, 0x81, ++ 0xa0, 0x8a, 0x5c, 0x48, 0x7f, 0x30, 0xa0, 0x82, 0x28, 0x68, 0x80, 0x19, 0x01, 0x81, 0xf0, 0xbd, ++ 0x0f, 0x30, 0x40, 0x10, 0x70, 0x47, 0x10, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x8a, 0x13, ++ 0x8a, 0x82, 0xc0, 0x05, 0x11, 0x22, 0xc0, 0x0d, 0x52, 0x02, 0x83, 0x18, 0x4a, 0x4a, 0x14, 0x68, ++ 0x4a, 0x48, 0x24, 0x18, 0xe3, 0x82, 0x8b, 0x8a, 0x4f, 0x4b, 0x8b, 0x82, 0x12, 0x68, 0x59, 0x1c, ++ 0x10, 0x18, 0xc1, 0x82, 0x6e, 0xe6, 0x10, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x8a, 0x13, ++ 0x8a, 0x82, 0xc0, 0x05, 0x09, 0x22, 0xc0, 0x0d, 0x92, 0x02, 0x83, 0x18, 0x3e, 0x4a, 0x14, 0x68, ++ 0x3e, 0x48, 0x24, 0x18, 0xe3, 0x82, 0x8b, 0x8a, 0x43, 0x4b, 0x8b, 0x82, 0x12, 0x68, 0x59, 0x1c, ++ 0x10, 0x18, 0xc1, 0x82, 0x56, 0xe6, 0x10, 0xb5, 0x3c, 0x4c, 0x20, 0x68, 0xc2, 0x7d, 0x01, 0x46, ++ 0x53, 0x07, 0x40, 0x31, 0x00, 0x2b, 0x14, 0xda, 0x92, 0x07, 0x0d, 0xd4, 0x81, 0x21, 0x41, 0x56, ++ 0x0f, 0x31, 0x48, 0x10, 0xff, 0xf7, 0xd7, 0xff, 0x21, 0x68, 0x82, 0x20, 0x08, 0x56, 0x0f, 0x30, ++ 0x40, 0x10, 0xff, 0xf7, 0xb8, 0xff, 0x0d, 0xe0, 0x0f, 0x20, 0x08, 0x56, 0xff, 0xf7, 0x54, 0xff, ++ 0x08, 0xe0, 0x19, 0x20, 0x08, 0x56, 0xff, 0xf7, 0xd5, 0xfc, 0x21, 0x68, 0x50, 0x20, 0x08, 0x56, ++ 0xff, 0xf7, 0x04, 0xff, 0x21, 0x68, 0x01, 0x20, 0x48, 0x74, 0x2b, 0xe6, 0x70, 0xb5, 0x06, 0x46, ++ 0x05, 0xf0, 0x50, 0xfc, 0x25, 0x4d, 0x04, 0x46, 0x28, 0x68, 0x22, 0x30, 0x05, 0xf0, 0x64, 0xff, ++ 0x01, 0x46, 0x10, 0x20, 0xc1, 0x41, 0x60, 0x1a, 0x30, 0x60, 0x2d, 0x68, 0x28, 0x46, 0x36, 0x30, ++ 0x05, 0xf0, 0x5a, 0xff, 0x01, 0x46, 0x10, 0x20, 0xc1, 0x41, 0x20, 0x48, 0x6a, 0x7c, 0x61, 0x1a, ++ 0x40, 0x7c, 0x05, 0x2a, 0x04, 0xd0, 0x40, 0x04, 0x88, 0x42, 0x03, 0xd2, 0x01, 0x20, 0x70, 0xbd, ++ 0xc0, 0x01, 0xf9, 0xe7, 0x00, 0x20, 0x70, 0xbd, 0xf8, 0xb5, 0x14, 0x48, 0x00, 0x68, 0x80, 0x8a, ++ 0x00, 0x04, 0x18, 0xd4, 0x03, 0x26, 0x36, 0x07, 0xb0, 0x8a, 0x15, 0x4f, 0xb7, 0x82, 0x0a, 0x4c, ++ 0x20, 0x21, 0x22, 0x68, 0x0d, 0x20, 0x40, 0x03, 0x10, 0x18, 0x41, 0x84, 0x68, 0x46, 0xff, 0xf7, ++ 0xc5, 0xff, 0x00, 0x25, 0x01, 0x28, 0x1d, 0xd0, 0xb0, 0x8a, 0xb7, 0x82, 0x21, 0x68, 0x0d, 0x20, ++ 0x40, 0x03, 0x08, 0x18, 0x45, 0x84, 0xf8, 0xbd, 0x84, 0x00, 0x00, 0x20, 0x40, 0xa0, 0x01, 0x00, ++ 0xf3, 0x8f, 0x00, 0x00, 0xff, 0xfb, 0x00, 0x00, 0x80, 0xa1, 0x01, 0x00, 0x90, 0x00, 0x00, 0x20, ++ 0xff, 0xfd, 0x00, 0x00, 0x80, 0xf7, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, ++ 0xdf, 0xff, 0x00, 0x00, 0xff, 0xf7, 0x77, 0xff, 0xf9, 0x48, 0x53, 0x21, 0x00, 0x68, 0x09, 0x5c, ++ 0x00, 0x29, 0x0e, 0xd0, 0x81, 0x22, 0x11, 0x56, 0xf6, 0x4a, 0x10, 0x31, 0x1f, 0x29, 0x21, 0x68, ++ 0x0a, 0xd8, 0x8b, 0x18, 0x28, 0x21, 0x59, 0x5e, 0x23, 0x68, 0x89, 0x02, 0x9a, 0x18, 0x52, 0x8d, ++ 0x09, 0xe0, 0x05, 0x83, 0x45, 0x83, 0x0b, 0xe0, 0x8b, 0x18, 0x2c, 0x21, 0x59, 0x5e, 0x23, 0x68, ++ 0x89, 0x02, 0x9a, 0x18, 0xd2, 0x8d, 0xd2, 0xb2, 0x11, 0x43, 0x0a, 0x0c, 0x02, 0x83, 0x41, 0x83, ++ 0xe9, 0x49, 0x81, 0x82, 0xbf, 0xe7, 0x30, 0xb5, 0xff, 0xf7, 0x3b, 0xfc, 0xe4, 0x4d, 0x29, 0x68, ++ 0x40, 0x31, 0x48, 0x76, 0x1f, 0x20, 0xff, 0xf7, 0x3d, 0xfc, 0x1e, 0x21, 0x28, 0x68, 0xc9, 0x43, ++ 0xc1, 0x84, 0x40, 0x30, 0xc0, 0x7c, 0x00, 0x28, 0x1d, 0xd0, 0x02, 0x20, 0xff, 0xf7, 0x9a, 0xfb, ++ 0x28, 0x68, 0x00, 0x24, 0x04, 0x85, 0x04, 0x77, 0x84, 0x75, 0x1f, 0x20, 0xff, 0xf7, 0xbb, 0xfd, ++ 0x28, 0x68, 0x53, 0x21, 0x09, 0x5c, 0x00, 0x29, 0x0b, 0xd0, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, ++ 0xff, 0x22, 0x8a, 0x82, 0xd5, 0x4a, 0x01, 0x21, 0x12, 0x68, 0x49, 0x02, 0xd1, 0x4b, 0xd2, 0x18, ++ 0x91, 0x84, 0x84, 0x82, 0x30, 0xbd, 0x1f, 0x20, 0xc0, 0x43, 0xff, 0xf7, 0x7b, 0xfb, 0x01, 0x20, ++ 0xdc, 0xe7, 0x10, 0xb5, 0x04, 0x46, 0xff, 0xf7, 0x81, 0xfd, 0x03, 0x21, 0x09, 0x07, 0x88, 0x8a, ++ 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0xc9, 0x48, 0xe2, 0x06, 0x03, 0x68, 0xd2, 0x0e, 0x0d, 0x24, ++ 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, 0xc5, 0x4a, 0x8a, 0x82, 0xc5, 0x4b, 0x04, 0x68, ++ 0xc0, 0x4a, 0xa4, 0x18, 0x23, 0x84, 0x8b, 0x8a, 0xff, 0x23, 0x8b, 0x82, 0x01, 0x21, 0x00, 0x68, ++ 0x89, 0x02, 0x80, 0x18, 0x81, 0x84, 0x4d, 0xe5, 0x00, 0xb5, 0xff, 0xf7, 0xe2, 0xfb, 0xb8, 0x49, ++ 0x59, 0x22, 0x09, 0x68, 0x50, 0x54, 0x00, 0x20, 0x08, 0x77, 0x88, 0x75, 0x1c, 0x20, 0xff, 0xf7, ++ 0xd0, 0xff, 0x00, 0xbd, 0x00, 0xb5, 0xff, 0xf7, 0xe6, 0xfe, 0xff, 0xf7, 0x4f, 0xfd, 0x03, 0x20, ++ 0x00, 0x07, 0x81, 0x8a, 0x30, 0x21, 0xc9, 0x43, 0x81, 0x82, 0xb0, 0x49, 0x00, 0x20, 0x09, 0x68, ++ 0x0d, 0x22, 0x52, 0x03, 0x89, 0x18, 0x48, 0x84, 0x00, 0xbd, 0x10, 0xb5, 0x00, 0x23, 0x00, 0x28, ++ 0x1c, 0xd0, 0xad, 0x4c, 0x00, 0x22, 0xa0, 0x42, 0x00, 0xd9, 0x20, 0x46, 0x52, 0x1c, 0x40, 0x00, ++ 0x52, 0xb2, 0x00, 0x28, 0xfa, 0xda, 0xd4, 0x17, 0xe4, 0x0e, 0xa4, 0x18, 0x64, 0x09, 0x64, 0x01, ++ 0x12, 0x1b, 0x1f, 0x24, 0xa2, 0x1a, 0xd2, 0xb2, 0x0a, 0x70, 0x08, 0x2a, 0x09, 0xd2, 0x00, 0x0e, ++ 0x00, 0x06, 0xa2, 0x1a, 0xd0, 0x40, 0xc0, 0xb2, 0x0b, 0x70, 0x0b, 0xe5, 0x0b, 0x70, 0x00, 0x20, ++ 0x08, 0xe5, 0x00, 0x0e, 0xd2, 0x1f, 0x0a, 0x70, 0x04, 0xe5, 0xf0, 0xb5, 0x03, 0x24, 0x24, 0x07, ++ 0xa1, 0x8a, 0x9a, 0x49, 0xa1, 0x82, 0x00, 0x28, 0x01, 0xdd, 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, ++ 0x97, 0x4a, 0x89, 0x02, 0x91, 0x4e, 0x89, 0x18, 0x32, 0x68, 0x0d, 0x27, 0x7f, 0x03, 0xd2, 0x19, ++ 0x11, 0x81, 0x01, 0x23, 0x00, 0x21, 0x5b, 0x02, 0x45, 0x42, 0x07, 0xe0, 0xa2, 0x8a, 0x91, 0x4a, ++ 0xa2, 0x82, 0x32, 0x68, 0xd2, 0x19, 0x13, 0x81, 0x49, 0x1c, 0x49, 0xb2, 0x00, 0x28, 0x01, 0xdb, ++ 0x02, 0x46, 0x00, 0xe0, 0x2a, 0x46, 0x8a, 0x42, 0xf0, 0xdc, 0xf0, 0xbd, 0xf0, 0xb5, 0x0e, 0x27, ++ 0x00, 0x22, 0x82, 0x4d, 0x88, 0x4e, 0xff, 0x43, 0x7d, 0x4c, 0x0f, 0x23, 0x00, 0x29, 0x16, 0xd0, ++ 0x00, 0x28, 0x09, 0xd0, 0x10, 0x46, 0x09, 0xe0, 0x29, 0x68, 0x89, 0x19, 0x89, 0x88, 0x89, 0x06, ++ 0x89, 0x16, 0x79, 0x1a, 0xc1, 0x84, 0xf0, 0xbd, 0x1f, 0x46, 0x18, 0x46, 0xff, 0xf7, 0x53, 0xfe, ++ 0x20, 0x68, 0xc1, 0x7d, 0x09, 0x09, 0xc9, 0x43, 0x89, 0x07, 0xed, 0xd1, 0xf0, 0xbd, 0x00, 0x28, ++ 0x01, 0xd0, 0x10, 0x46, 0x01, 0xe0, 0x1f, 0x46, 0x18, 0x46, 0xff, 0xf7, 0x2c, 0xfe, 0x28, 0x68, ++ 0x80, 0x19, 0x40, 0x88, 0x21, 0x68, 0x80, 0x06, 0x80, 0x16, 0x38, 0x1a, 0xc8, 0x84, 0xf0, 0xbd, ++ 0x40, 0x00, 0x0f, 0x38, 0x40, 0xb2, 0x70, 0x47, 0x30, 0xb5, 0x65, 0x4c, 0x00, 0x20, 0x21, 0x68, ++ 0x66, 0x4a, 0x08, 0x85, 0x10, 0x68, 0x6c, 0x4b, 0xc0, 0x18, 0x80, 0x88, 0x80, 0x06, 0x80, 0x16, ++ 0xff, 0xf7, 0xee, 0xff, 0x21, 0x68, 0x80, 0x31, 0x48, 0x70, 0x10, 0x68, 0xc0, 0x18, 0x40, 0x88, ++ 0x80, 0x06, 0x80, 0x16, 0xff, 0xf7, 0xe4, 0xff, 0x21, 0x68, 0x01, 0x22, 0x0b, 0x46, 0x80, 0x33, ++ 0x98, 0x70, 0x9a, 0x56, 0x00, 0x2a, 0x01, 0xdb, 0x15, 0x46, 0x00, 0xe0, 0x55, 0x42, 0x00, 0x28, ++ 0x01, 0xdb, 0x03, 0x46, 0x00, 0xe0, 0x43, 0x42, 0x9d, 0x42, 0x03, 0xdd, 0x0b, 0x8d, 0x04, 0x25, ++ 0x2b, 0x43, 0x0b, 0x85, 0x00, 0x2a, 0x03, 0xdd, 0x0a, 0x8d, 0x02, 0x23, 0x1a, 0x43, 0x0a, 0x85, ++ 0x00, 0x28, 0x03, 0xdd, 0x08, 0x8d, 0x01, 0x22, 0x10, 0x43, 0x08, 0x85, 0xca, 0x7d, 0x90, 0x06, ++ 0x80, 0x0f, 0x13, 0xd0, 0x01, 0x28, 0x20, 0xd0, 0x02, 0x28, 0x21, 0xd0, 0x03, 0x28, 0x0c, 0xd1, ++ 0x08, 0x8d, 0x01, 0x21, 0x80, 0x07, 0xc0, 0x0f, 0xff, 0xf7, 0x80, 0xff, 0x20, 0x68, 0x00, 0x8d, ++ 0xc0, 0x07, 0xc0, 0x0f, 0x00, 0x21, 0xff, 0xf7, 0x79, 0xff, 0x30, 0xbd, 0x28, 0x20, 0x08, 0x5e, ++ 0x04, 0x28, 0x01, 0xdb, 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0x04, 0x28, 0x02, 0xdb, 0x80, 0x07, ++ 0xc0, 0x0f, 0xf0, 0xe7, 0xc0, 0x07, 0xc0, 0x0f, 0xed, 0xe7, 0xd0, 0x07, 0xc0, 0x0f, 0xe9, 0xe7, ++ 0xd0, 0x07, 0xc0, 0x0f, 0x01, 0x21, 0xe6, 0xe7, 0xf8, 0xb5, 0xff, 0xf7, 0xd2, 0xfa, 0x30, 0x4c, ++ 0x59, 0x22, 0x21, 0x68, 0x00, 0x27, 0x50, 0x54, 0x8f, 0x82, 0xc8, 0x7d, 0x39, 0x4d, 0x03, 0x07, ++ 0x36, 0x48, 0x37, 0x4a, 0xab, 0x8a, 0xa8, 0x82, 0x04, 0xd5, 0x2c, 0x48, 0x00, 0x68, 0x80, 0x18, ++ 0x07, 0x80, 0x04, 0xe0, 0x29, 0x48, 0x08, 0x23, 0x00, 0x68, 0x80, 0x18, 0x03, 0x80, 0xc8, 0x7d, ++ 0x1e, 0x26, 0x40, 0x07, 0x40, 0x0f, 0xf6, 0x43, 0x03, 0x00, 0x05, 0xf0, 0x99, 0xfd, 0x08, 0x05, ++ 0x0e, 0x17, 0x2d, 0x5d, 0x5d, 0x85, 0x8d, 0x5f, 0x1f, 0x20, 0xff, 0xf7, 0xb3, 0xfa, 0x21, 0x68, ++ 0x50, 0x20, 0x08, 0x56, 0xff, 0xf7, 0xe2, 0xfc, 0x14, 0xe0, 0x30, 0x46, 0xff, 0xf7, 0xaa, 0xfa, ++ 0x21, 0x68, 0x50, 0x20, 0x08, 0x56, 0xff, 0xf7, 0xd9, 0xfc, 0x20, 0xe0, 0x00, 0x20, 0xff, 0xf7, ++ 0xa1, 0xfa, 0x20, 0x68, 0x40, 0x30, 0xc0, 0x7c, 0x00, 0x28, 0x07, 0xd0, 0x01, 0x20, 0xc0, 0x43, ++ 0xff, 0xf7, 0x00, 0xfa, 0x21, 0x68, 0x1f, 0x20, 0xc8, 0x84, 0x37, 0xe0, 0x20, 0x20, 0xff, 0xf7, ++ 0xf9, 0xf9, 0x00, 0x20, 0xc0, 0x43, 0xf3, 0xe7, 0x00, 0x20, 0xff, 0xf7, 0x8b, 0xfa, 0x20, 0x68, ++ 0x40, 0x30, 0xc0, 0x7c, 0x00, 0x28, 0x05, 0xd0, 0x02, 0x20, 0xff, 0xf7, 0xeb, 0xf9, 0x20, 0x68, ++ 0xc6, 0x84, 0x23, 0xe0, 0x1f, 0x20, 0xc0, 0x43, 0xff, 0xf7, 0xe4, 0xf9, 0x01, 0x20, 0xf4, 0xe7, ++ 0x90, 0x00, 0x00, 0x20, 0x40, 0xa0, 0x01, 0x00, 0x01, 0xec, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, ++ 0xf3, 0x0f, 0x00, 0x00, 0x0c, 0xb0, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x80, 0x8b, 0x00, 0x00, ++ 0x01, 0x40, 0x00, 0x00, 0xff, 0xfd, 0x00, 0x00, 0x80, 0xa2, 0x01, 0x00, 0xf7, 0xff, 0x00, 0x00, ++ 0x80, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0xf7, 0x16, 0xff, 0x20, 0x68, 0xc0, 0x7d, ++ 0x40, 0x07, 0x15, 0xd4, 0xff, 0xf7, 0x12, 0xfc, 0x20, 0x68, 0x53, 0x21, 0x09, 0x5c, 0x00, 0x29, ++ 0x0c, 0xd0, 0xc0, 0x7d, 0x80, 0x07, 0x09, 0xd5, 0xa8, 0x8a, 0xff, 0x20, 0xa8, 0x82, 0xf9, 0x48, ++ 0x01, 0x21, 0x00, 0x68, 0xc9, 0x02, 0xf8, 0x4a, 0x80, 0x18, 0x81, 0x84, 0xff, 0xf7, 0x17, 0xfa, ++ 0xff, 0xf7, 0x87, 0xfb, 0x20, 0x68, 0x5e, 0x30, 0xff, 0xf7, 0x8e, 0xfb, 0x20, 0x68, 0x87, 0x75, ++ 0x07, 0x77, 0x47, 0x87, 0x87, 0x87, 0xae, 0xe5, 0x20, 0x20, 0xff, 0xf7, 0x8e, 0xfe, 0x00, 0x20, ++ 0xc0, 0x43, 0xff, 0xf7, 0x8a, 0xfe, 0x95, 0xe7, 0x1f, 0x20, 0xc0, 0x43, 0xff, 0xf7, 0x85, 0xfe, ++ 0x01, 0x20, 0xff, 0xf7, 0x82, 0xfe, 0xa2, 0xe7, 0x10, 0xb5, 0x05, 0xf0, 0xab, 0xf9, 0xe7, 0x49, ++ 0x09, 0x68, 0x88, 0x84, 0x00, 0x0c, 0x48, 0x84, 0x0c, 0xe5, 0x7c, 0xb5, 0x06, 0x46, 0x08, 0x68, ++ 0x69, 0x46, 0xc0, 0x08, 0xff, 0xf7, 0x49, 0xfe, 0xe0, 0x4d, 0x44, 0x22, 0x29, 0x68, 0xe0, 0x4c, ++ 0x52, 0x5a, 0x0b, 0x7f, 0xd2, 0x18, 0xa0, 0x54, 0x08, 0x7f, 0xbf, 0x28, 0x01, 0xd3, 0xbf, 0x20, ++ 0x00, 0xe0, 0x40, 0x1c, 0x08, 0x77, 0x01, 0xa9, 0x30, 0x68, 0xff, 0xf7, 0x36, 0xfe, 0x69, 0x46, ++ 0x09, 0x78, 0x0a, 0x01, 0x69, 0x46, 0x09, 0x79, 0x0a, 0x43, 0x29, 0x68, 0x0b, 0x46, 0x40, 0x33, ++ 0x9d, 0x88, 0x0e, 0x7f, 0xad, 0x19, 0x62, 0x55, 0x0a, 0x7f, 0xbf, 0x2a, 0x01, 0xd3, 0xbf, 0x22, ++ 0x00, 0xe0, 0x52, 0x1c, 0xd2, 0xb2, 0x0a, 0x77, 0x9b, 0x88, 0x9a, 0x18, 0xa0, 0x54, 0x08, 0x7f, ++ 0xbf, 0x28, 0x01, 0xd3, 0xbf, 0x20, 0x00, 0xe0, 0x40, 0x1c, 0x08, 0x77, 0x7c, 0xbd, 0x70, 0xb5, ++ 0xc6, 0x4a, 0x0e, 0x23, 0x14, 0x68, 0x00, 0x25, 0xe3, 0x84, 0xc2, 0x4b, 0xc5, 0x4c, 0x00, 0x29, ++ 0x2b, 0xd0, 0x00, 0x28, 0x18, 0x68, 0x11, 0xd0, 0x00, 0x19, 0x80, 0x88, 0x80, 0x06, 0x80, 0x16, ++ 0xff, 0xf7, 0x86, 0xfe, 0x11, 0x68, 0x81, 0x26, 0x8e, 0x57, 0xb0, 0x42, 0x1a, 0xda, 0x18, 0x68, ++ 0x00, 0x19, 0x80, 0x88, 0x80, 0x06, 0x80, 0x16, 0x40, 0x1c, 0x10, 0xe0, 0x00, 0x19, 0x80, 0x88, ++ 0x80, 0x06, 0x80, 0x16, 0xff, 0xf7, 0x74, 0xfe, 0x11, 0x68, 0x81, 0x26, 0x8e, 0x57, 0xb0, 0x42, ++ 0x08, 0xdd, 0x18, 0x68, 0x00, 0x19, 0x80, 0x88, 0x80, 0x06, 0x80, 0x16, 0x40, 0x1e, 0xff, 0xf7, ++ 0xa2, 0xfc, 0x70, 0xbd, 0x10, 0x68, 0xc5, 0x84, 0x70, 0xbd, 0x00, 0x28, 0x18, 0x68, 0x11, 0xd0, ++ 0x00, 0x19, 0x40, 0x88, 0x80, 0x06, 0x80, 0x16, 0xff, 0xf7, 0x5a, 0xfe, 0x11, 0x68, 0x82, 0x26, ++ 0x8e, 0x57, 0xb0, 0x42, 0xee, 0xda, 0x18, 0x68, 0x00, 0x19, 0x40, 0x88, 0x80, 0x06, 0x80, 0x16, ++ 0x40, 0x1c, 0x10, 0xe0, 0x00, 0x19, 0x40, 0x88, 0x80, 0x06, 0x80, 0x16, 0xff, 0xf7, 0x48, 0xfe, ++ 0x11, 0x68, 0x82, 0x26, 0x8e, 0x57, 0xb0, 0x42, 0xdc, 0xdd, 0x18, 0x68, 0x00, 0x19, 0x40, 0x88, ++ 0x80, 0x06, 0x80, 0x16, 0x40, 0x1e, 0xff, 0xf7, 0x5e, 0xfc, 0x70, 0xbd, 0xf0, 0xb5, 0x85, 0xb0, ++ 0x00, 0x20, 0x69, 0x46, 0x95, 0x4f, 0x08, 0x72, 0x38, 0x68, 0x81, 0x8a, 0x09, 0x04, 0x7d, 0xd4, ++ 0x03, 0x25, 0x2d, 0x07, 0xa9, 0x8a, 0x20, 0x21, 0xc9, 0x43, 0xa9, 0x82, 0x8d, 0x4c, 0x20, 0x21, ++ 0x22, 0x68, 0x0d, 0x26, 0x76, 0x03, 0x92, 0x19, 0x51, 0x84, 0x53, 0x21, 0x09, 0x5c, 0x00, 0x29, ++ 0x11, 0xd0, 0x26, 0x21, 0x41, 0x5e, 0x10, 0x31, 0x1f, 0x29, 0x02, 0xd9, 0xc0, 0x7d, 0x80, 0x07, ++ 0x0d, 0xd4, 0x20, 0x68, 0x84, 0x49, 0x42, 0x18, 0x28, 0x20, 0x10, 0x5e, 0x22, 0x68, 0x80, 0x02, ++ 0x51, 0x18, 0x49, 0x8d, 0x0c, 0xe0, 0x02, 0xa8, 0xff, 0xf7, 0xa6, 0xfa, 0x0a, 0xe0, 0x20, 0x68, ++ 0x7d, 0x49, 0x42, 0x18, 0x2c, 0x20, 0x10, 0x5e, 0x22, 0x68, 0x80, 0x02, 0x51, 0x18, 0xc9, 0x8d, ++ 0xc9, 0xb2, 0x08, 0x43, 0x00, 0x90, 0x01, 0xa8, 0xff, 0xf7, 0x78, 0xfc, 0x03, 0x90, 0x77, 0x48, ++ 0x07, 0x68, 0x38, 0x46, 0x3a, 0x30, 0x05, 0xf0, 0xdf, 0xfb, 0x10, 0x21, 0xc8, 0x41, 0x00, 0x99, ++ 0x40, 0x18, 0x88, 0x42, 0x01, 0xd2, 0x00, 0x20, 0xc0, 0x43, 0x03, 0x99, 0x00, 0x90, 0x01, 0x29, ++ 0x21, 0xd0, 0xf9, 0x8c, 0x00, 0x29, 0x1e, 0xd0, 0x6f, 0x49, 0x89, 0x7c, 0x09, 0x01, 0x81, 0x42, ++ 0x7c, 0xd2, 0x27, 0x22, 0x01, 0x99, 0x12, 0x02, 0x91, 0x42, 0x05, 0xd8, 0x6b, 0x4a, 0x91, 0x42, ++ 0x74, 0xd9, 0xf9, 0x7d, 0x49, 0x06, 0x71, 0xd5, 0x01, 0xa9, 0x68, 0x46, 0xff, 0xf7, 0xfd, 0xfe, ++ 0x62, 0x4a, 0x11, 0x68, 0xcb, 0x7d, 0xd8, 0x07, 0x65, 0x48, 0x08, 0x5e, 0x20, 0xd0, 0x00, 0x28, ++ 0x1c, 0xda, 0x40, 0x1c, 0x1f, 0xe0, 0x01, 0xa9, 0x68, 0x46, 0xff, 0xf7, 0xee, 0xfe, 0x68, 0x46, ++ 0x00, 0x7a, 0x00, 0x28, 0x10, 0xd0, 0x00, 0x20, 0x01, 0x21, 0x80, 0x03, 0xc9, 0x03, 0x41, 0x18, ++ 0x03, 0x98, 0x40, 0x03, 0x01, 0x43, 0x55, 0x48, 0x00, 0x68, 0x00, 0xe0, 0x02, 0xe0, 0x02, 0x7f, ++ 0x11, 0x43, 0x81, 0x82, 0x05, 0xb0, 0xf0, 0xbd, 0x01, 0x20, 0xed, 0xe7, 0x00, 0x20, 0x02, 0xe0, ++ 0x00, 0x28, 0xfb, 0xdd, 0x40, 0x1e, 0xc8, 0x84, 0x98, 0x07, 0x40, 0xd5, 0x53, 0x20, 0x47, 0x5c, ++ 0x01, 0x20, 0x50, 0x4a, 0x40, 0x02, 0x00, 0x2f, 0x01, 0xd0, 0x5f, 0x07, 0x05, 0xd5, 0xa9, 0x8a, ++ 0xaa, 0x82, 0x21, 0x68, 0x89, 0x19, 0x08, 0x81, 0x66, 0xe0, 0xdb, 0x07, 0xff, 0x27, 0x00, 0x2b, ++ 0x13, 0xd0, 0x26, 0x23, 0xcb, 0x5e, 0x10, 0x33, 0x12, 0xd1, 0x3e, 0x20, 0xc0, 0x43, 0xff, 0xf7, ++ 0x39, 0xf8, 0x01, 0x20, 0xff, 0xf7, 0x36, 0xf8, 0xa8, 0x8a, 0xaf, 0x82, 0x01, 0x21, 0x22, 0x68, ++ 0x89, 0x02, 0x39, 0x48, 0x10, 0x18, 0x81, 0x84, 0x4e, 0xe0, 0xc9, 0x8c, 0x0f, 0x29, 0x05, 0xd0, ++ 0xa9, 0x8a, 0xaa, 0x82, 0x21, 0x68, 0x89, 0x19, 0x08, 0x81, 0xd8, 0xe7, 0x3f, 0x20, 0xff, 0xf7, ++ 0x21, 0xf8, 0x00, 0x20, 0xc0, 0x43, 0xff, 0xf7, 0x1d, 0xf8, 0xa8, 0x8a, 0xaf, 0x82, 0x01, 0x20, ++ 0x22, 0x68, 0x80, 0x02, 0x2c, 0x49, 0x51, 0x18, 0x88, 0x84, 0x35, 0xe0, 0x64, 0xe0, 0x2b, 0x4f, ++ 0x58, 0x07, 0x2d, 0xd5, 0x98, 0x06, 0x80, 0x0f, 0x06, 0xd0, 0x01, 0x28, 0x15, 0xd0, 0x02, 0x28, ++ 0x16, 0xd0, 0x03, 0x28, 0x28, 0xd1, 0x17, 0xe0, 0x28, 0x20, 0x08, 0x5e, 0x04, 0x28, 0x01, 0xdb, ++ 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0x03, 0x28, 0x02, 0xdb, 0x80, 0x07, 0xc0, 0x0f, 0x01, 0xe0, ++ 0xc0, 0x07, 0xc0, 0x0f, 0xff, 0xf7, 0xab, 0xfe, 0x16, 0xe0, 0xd8, 0x07, 0xc0, 0x0f, 0x0d, 0xe0, ++ 0xd8, 0x07, 0xc0, 0x0f, 0x01, 0x21, 0xf5, 0xe7, 0x08, 0x8d, 0x01, 0x21, 0x80, 0x07, 0xc0, 0x0f, ++ 0xff, 0xf7, 0x9d, 0xfe, 0x38, 0x68, 0x00, 0x8d, 0xc0, 0x07, 0xc0, 0x0f, 0x00, 0x21, 0xe9, 0xe7, ++ 0xc8, 0x8c, 0x40, 0xb2, 0xff, 0xf7, 0x76, 0xf8, 0xff, 0xf7, 0x4e, 0xfe, 0x0f, 0x48, 0x00, 0x27, ++ 0x00, 0x68, 0x47, 0x87, 0x87, 0x87, 0xff, 0xf7, 0x42, 0xf8, 0x02, 0xa8, 0xff, 0xf7, 0xbc, 0xf9, ++ 0x00, 0x90, 0xa8, 0x8a, 0x20, 0x20, 0xc0, 0x43, 0xa8, 0x82, 0x20, 0x68, 0x80, 0x19, 0x47, 0x84, ++ 0x06, 0x48, 0x00, 0x68, 0xc1, 0x8c, 0x02, 0x7f, 0x49, 0x06, 0x49, 0x0c, 0x0a, 0x43, 0x82, 0x82, ++ 0x60, 0xe7, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, 0x40, 0xa0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x20, ++ 0x00, 0x01, 0x00, 0x20, 0x80, 0xa2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x20, 0xcc, 0x07, 0x00, 0x00, ++ 0x26, 0x00, 0x00, 0x00, 0xff, 0xfd, 0x00, 0x00, 0x01, 0x0c, 0x79, 0x87, 0xb8, 0x87, 0xff, 0xf7, ++ 0x16, 0xf8, 0xa8, 0x8a, 0x20, 0x20, 0xc0, 0x43, 0xa8, 0x82, 0x21, 0x68, 0x00, 0x20, 0x89, 0x19, ++ 0x48, 0x84, 0xd5, 0xe7, 0xf0, 0xb5, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0xfa, 0x49, 0x81, 0x82, ++ 0xfa, 0x49, 0x00, 0x22, 0x0c, 0x68, 0x0d, 0x23, 0x5b, 0x03, 0xe4, 0x18, 0x62, 0x80, 0x84, 0x8a, ++ 0x01, 0x26, 0x86, 0x82, 0x69, 0x24, 0x0d, 0x68, 0x24, 0x01, 0xed, 0x18, 0xac, 0x80, 0x84, 0x8a, ++ 0x94, 0x1e, 0x84, 0x82, 0x0c, 0x68, 0xe4, 0x18, 0xe2, 0x80, 0x84, 0x8a, 0xf0, 0x4c, 0x84, 0x82, ++ 0x0c, 0x68, 0xe4, 0x18, 0x22, 0x81, 0x84, 0x8a, 0xee, 0x4c, 0x84, 0x82, 0x0c, 0x68, 0xe4, 0x18, ++ 0x22, 0x84, 0x84, 0x8a, 0xec, 0x4d, 0x85, 0x82, 0x0c, 0x68, 0xe4, 0x18, 0x62, 0x84, 0x84, 0x8a, ++ 0xea, 0x4c, 0x84, 0x82, 0x0f, 0x68, 0xdc, 0x10, 0xff, 0x18, 0x3c, 0x85, 0x84, 0x8a, 0x1f, 0x24, ++ 0xe4, 0x43, 0x84, 0x82, 0x0f, 0x68, 0x0d, 0x24, 0xff, 0x18, 0x7c, 0x85, 0x84, 0x8a, 0xe4, 0x4c, ++ 0x84, 0x82, 0x0c, 0x68, 0xe3, 0x18, 0x1e, 0x86, 0x83, 0x8a, 0xe2, 0x4b, 0x83, 0x82, 0x0c, 0x68, ++ 0xe1, 0x4b, 0xe4, 0x18, 0x22, 0x80, 0x84, 0x8a, 0xe0, 0x4e, 0x86, 0x82, 0x0c, 0x68, 0xe4, 0x18, ++ 0x62, 0x80, 0x84, 0x8a, 0x86, 0x82, 0x0c, 0x68, 0xe4, 0x18, 0xa2, 0x80, 0x84, 0x8a, 0xb4, 0x1c, ++ 0x84, 0x82, 0x0e, 0x68, 0xf6, 0x18, 0xf2, 0x80, 0x86, 0x8a, 0x84, 0x82, 0x0e, 0x68, 0xf6, 0x18, ++ 0x32, 0x81, 0x86, 0x8a, 0x84, 0x82, 0x0c, 0x68, 0xe4, 0x18, 0x62, 0x81, 0x84, 0x8a, 0xd4, 0x4c, ++ 0x84, 0x82, 0x0c, 0x68, 0xe4, 0x18, 0xa2, 0x81, 0x84, 0x8a, 0xc0, 0x24, 0xe4, 0x43, 0x84, 0x82, ++ 0x0e, 0x68, 0x40, 0x24, 0xf6, 0x18, 0xf4, 0x81, 0x84, 0x8a, 0x01, 0x24, 0xa4, 0x03, 0x84, 0x82, ++ 0x0c, 0x68, 0xe4, 0x18, 0xe2, 0x82, 0x84, 0x8a, 0xff, 0x24, 0x04, 0x34, 0x84, 0x82, 0x0c, 0x68, ++ 0xe4, 0x18, 0x22, 0x84, 0x84, 0x8a, 0x82, 0x82, 0x0c, 0x68, 0xe4, 0x18, 0x62, 0x84, 0x84, 0x8a, ++ 0x82, 0x82, 0x0c, 0x68, 0xe4, 0x18, 0xa2, 0x84, 0x84, 0x8a, 0x82, 0x82, 0x0c, 0x68, 0xe3, 0x18, ++ 0xda, 0x84, 0x83, 0x8a, 0x19, 0x23, 0xdb, 0x43, 0x83, 0x82, 0x0e, 0x68, 0x10, 0x24, 0xba, 0x4b, ++ 0x40, 0x33, 0xf6, 0x18, 0x34, 0x80, 0x84, 0x8a, 0x0f, 0x24, 0xe4, 0x43, 0x84, 0x82, 0x0c, 0x68, ++ 0xe4, 0x18, 0x62, 0x80, 0x84, 0x8a, 0xb0, 0x4c, 0x29, 0x34, 0x84, 0x82, 0x0e, 0x68, 0xf6, 0x18, ++ 0xb2, 0x80, 0x86, 0x8a, 0x84, 0x82, 0x0f, 0x68, 0x04, 0x26, 0xff, 0x18, 0x3e, 0x84, 0x86, 0x8a, ++ 0x84, 0x82, 0x0e, 0x68, 0xf3, 0x18, 0x1a, 0x85, 0x83, 0x8a, 0x82, 0x82, 0x0e, 0x68, 0xaa, 0x4b, ++ 0x80, 0x33, 0xf6, 0x18, 0x32, 0x80, 0x86, 0x8a, 0x82, 0x82, 0x0e, 0x68, 0xf6, 0x18, 0x72, 0x80, ++ 0x86, 0x8a, 0x84, 0x82, 0x0c, 0x68, 0xe3, 0x18, 0x9a, 0x80, 0x83, 0x8a, 0x85, 0x82, 0x0b, 0x68, ++ 0xa1, 0x4c, 0xc0, 0x34, 0x1b, 0x19, 0xda, 0x84, 0x83, 0x8a, 0x9d, 0x4b, 0xf1, 0x3b, 0x83, 0x82, ++ 0x08, 0x68, 0xa0, 0x49, 0x40, 0x18, 0x42, 0x84, 0xf0, 0xbd, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, ++ 0x00, 0x22, 0x8a, 0x82, 0x91, 0x49, 0x00, 0x02, 0x09, 0x68, 0x0d, 0x22, 0x52, 0x03, 0x89, 0x18, ++ 0x80, 0x30, 0x48, 0x83, 0x70, 0x47, 0x10, 0xb5, 0x00, 0x22, 0x11, 0x46, 0x96, 0x4c, 0x07, 0xe0, ++ 0xc3, 0x07, 0x02, 0xd0, 0x4b, 0x00, 0xe3, 0x5a, 0x5a, 0x40, 0x49, 0x1c, 0x89, 0xb2, 0x40, 0x08, ++ 0x00, 0x28, 0xf5, 0xd1, 0x10, 0x46, 0x27, 0xe5, 0xf0, 0xb5, 0x84, 0x48, 0x86, 0x4d, 0x00, 0x68, ++ 0x30, 0x35, 0x0d, 0x21, 0x49, 0x03, 0x40, 0x18, 0x86, 0x8b, 0x00, 0x27, 0x3c, 0x46, 0x09, 0xe0, ++ 0x38, 0x5d, 0x29, 0x0a, 0x48, 0x40, 0xff, 0xf7, 0xde, 0xff, 0x29, 0x02, 0x48, 0x40, 0x64, 0x1c, ++ 0x85, 0xb2, 0xa4, 0xb2, 0xb4, 0x42, 0xf3, 0xd3, 0x28, 0x46, 0xf0, 0xbd, 0x03, 0x22, 0x12, 0x07, ++ 0x93, 0x8a, 0x00, 0x23, 0x93, 0x82, 0x09, 0x07, 0x00, 0x01, 0x09, 0x0f, 0x08, 0x43, 0x00, 0x02, ++ 0x80, 0x21, 0x40, 0x30, 0x08, 0x43, 0x71, 0x49, 0x09, 0x68, 0x0d, 0x22, 0x52, 0x03, 0x89, 0x18, ++ 0x48, 0x83, 0x70, 0x47, 0xfe, 0xb5, 0x02, 0x46, 0x78, 0x48, 0x6c, 0x4f, 0x40, 0x7d, 0x00, 0x26, ++ 0xc0, 0x00, 0x01, 0x90, 0x76, 0x48, 0x13, 0x00, 0x04, 0x68, 0x21, 0x46, 0x80, 0x31, 0x00, 0x91, ++ 0x25, 0x46, 0x74, 0x49, 0x40, 0x35, 0x05, 0xf0, 0xe3, 0xf9, 0x15, 0x0c, 0x19, 0x18, 0x18, 0x8b, ++ 0xb8, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, 0xef, 0xee, 0xed, 0x18, 0xec, 0xeb, 0xea, 0xe9, 0xe8, 0xe7, ++ 0x18, 0x00, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0xc0, 0x21, 0xc9, 0x43, 0x81, 0x82, 0x3a, 0x68, ++ 0x80, 0x21, 0x0d, 0x20, 0x40, 0x03, 0x10, 0x18, 0x41, 0x83, 0xfe, 0xbd, 0x57, 0x49, 0x09, 0x68, ++ 0x0d, 0x27, 0x7f, 0x03, 0xc9, 0x19, 0x49, 0x8b, 0x09, 0x0a, 0x06, 0xd0, 0x01, 0x29, 0x0a, 0xd0, ++ 0x02, 0x29, 0x2c, 0xd0, 0x01, 0x21, 0x08, 0x46, 0x34, 0xe1, 0xa8, 0x7c, 0x00, 0x28, 0xec, 0xd0, ++ 0x01, 0x20, 0x60, 0x74, 0xfb, 0xe1, 0x05, 0x46, 0x00, 0x98, 0x04, 0x21, 0x82, 0x7c, 0x57, 0x48, ++ 0x08, 0x24, 0x43, 0x7e, 0x9a, 0x42, 0x10, 0xd0, 0x83, 0x7e, 0x9a, 0x42, 0x02, 0xd1, 0x05, 0x21, ++ 0x09, 0x24, 0x0a, 0xe0, 0xc3, 0x7e, 0x9a, 0x42, 0x02, 0xd1, 0x06, 0x21, 0x0a, 0x24, 0x04, 0xe0, ++ 0x00, 0x7f, 0x82, 0x42, 0x01, 0xd1, 0x07, 0x21, 0x0b, 0x24, 0x08, 0x46, 0x00, 0xf0, 0x93, 0xff, ++ 0x20, 0x46, 0x00, 0xf0, 0x90, 0xff, 0x29, 0x68, 0x01, 0x20, 0x48, 0x74, 0xd7, 0xe1, 0x01, 0x21, ++ 0x69, 0x72, 0x66, 0x74, 0xfd, 0xf7, 0x84, 0xfe, 0x38, 0x48, 0x01, 0x68, 0xc9, 0x19, 0x89, 0x8e, ++ 0xc9, 0x07, 0x09, 0xd0, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x20, 0x22, 0xd2, 0x43, 0x8a, 0x82, ++ 0x00, 0x68, 0x20, 0x21, 0xc0, 0x19, 0x01, 0x84, 0x00, 0x20, 0xff, 0xf7, 0x36, 0xff, 0x3c, 0x49, ++ 0x3a, 0x4a, 0x09, 0x68, 0x53, 0x7e, 0x80, 0x31, 0x89, 0x7c, 0x04, 0x20, 0x08, 0x24, 0x99, 0x42, ++ 0x10, 0xd0, 0x93, 0x7e, 0x99, 0x42, 0x02, 0xd1, 0x05, 0x20, 0x09, 0x24, 0x0a, 0xe0, 0xd3, 0x7e, ++ 0x99, 0x42, 0x02, 0xd1, 0x06, 0x20, 0x0a, 0x24, 0x04, 0xe0, 0x12, 0x7f, 0x91, 0x42, 0x01, 0xd1, ++ 0x07, 0x20, 0x0b, 0x24, 0x00, 0xf0, 0x4d, 0xff, 0x20, 0x46, 0x00, 0xf0, 0x4a, 0xff, 0xfe, 0xbd, ++ 0x38, 0x68, 0x0d, 0x24, 0x64, 0x03, 0x00, 0x19, 0x40, 0x8b, 0x00, 0x0a, 0x06, 0xd0, 0x01, 0x28, ++ 0x0b, 0xd0, 0x02, 0x28, 0x13, 0xd0, 0x03, 0x28, 0x94, 0xd1, 0x17, 0xe0, 0x03, 0x20, 0x00, 0x07, ++ 0x81, 0x8a, 0x86, 0x82, 0x04, 0xf0, 0xf6, 0xfd, 0x05, 0xe0, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, ++ 0x86, 0x82, 0x04, 0xf0, 0xea, 0xfd, 0x39, 0x68, 0x09, 0x19, 0x88, 0x83, 0x7f, 0xe1, 0x03, 0x20, ++ 0x00, 0x07, 0x81, 0x8a, 0x86, 0x82, 0x00, 0x98, 0x80, 0x7c, 0xf4, 0xe7, 0x03, 0x20, 0x00, 0x07, ++ 0x81, 0x8a, 0x86, 0x82, 0x04, 0xf0, 0x08, 0xfe, 0xed, 0xe7, 0x3a, 0x68, 0x0d, 0x21, 0x49, 0x03, ++ 0x52, 0x18, 0x52, 0x8b, 0x12, 0x0a, 0x92, 0x1e, 0x13, 0x00, 0x05, 0xf0, 0x21, 0xf9, 0x05, 0x55, ++ 0x62, 0x7b, 0x8d, 0x33, 0x04, 0x00, 0xc2, 0xe7, 0x7f, 0xf8, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, ++ 0x80, 0x81, 0x00, 0x00, 0x1f, 0xbf, 0x00, 0x00, 0xcf, 0xff, 0x00, 0x00, 0xff, 0x83, 0x00, 0x00, ++ 0xf0, 0xfc, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x40, 0xa0, 0x01, 0x00, 0xfd, 0x13, 0x00, 0x00, ++ 0xc0, 0xc0, 0x00, 0x00, 0x80, 0xa1, 0x01, 0x00, 0xc4, 0x79, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, ++ 0x90, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x20, 0xf9, 0xe1, 0x88, 0xe1, 0xd9, 0xe1, 0xc3, 0xe1, ++ 0x44, 0xe1, 0xef, 0xe0, 0xdb, 0xe0, 0xc7, 0xe0, 0xb8, 0xe0, 0xa5, 0xe0, 0x98, 0xe0, 0x8e, 0xe0, ++ 0x82, 0xe0, 0x79, 0xe0, 0x62, 0x7c, 0x02, 0x2a, 0x01, 0xd3, 0x11, 0x46, 0x3c, 0xe1, 0xeb, 0x7c, ++ 0x01, 0x2b, 0x70, 0xd8, 0xab, 0x7c, 0x00, 0x2b, 0x01, 0xd1, 0x00, 0x2a, 0x87, 0xd0, 0x2a, 0x76, ++ 0x38, 0x68, 0x0d, 0x46, 0x40, 0x19, 0x80, 0x8b, 0xe0, 0x84, 0xfe, 0xf7, 0xd2, 0xff, 0x01, 0x00, ++ 0x01, 0xd0, 0x06, 0x20, 0x4e, 0xe0, 0xff, 0x48, 0x05, 0x21, 0x00, 0x68, 0x41, 0x74, 0x03, 0x21, ++ 0x09, 0x07, 0x8a, 0x8a, 0x8e, 0x82, 0x56, 0xe1, 0xa8, 0x7c, 0x00, 0x28, 0x02, 0xd1, 0x60, 0x7c, ++ 0x00, 0x28, 0xa8, 0xd0, 0x60, 0x7c, 0x28, 0x76, 0x01, 0x20, 0x60, 0x74, 0xff, 0xf7, 0xf4, 0xf9, ++ 0x05, 0xe1, 0x01, 0x21, 0x07, 0x46, 0x69, 0x72, 0x60, 0x7c, 0x02, 0x28, 0x0a, 0xd3, 0xf2, 0x48, ++ 0xf3, 0x4c, 0x06, 0x60, 0xf1, 0x48, 0x60, 0x81, 0x20, 0x81, 0x41, 0x1c, 0xf1, 0x48, 0x05, 0xf0, ++ 0x6f, 0xf8, 0x66, 0x75, 0xff, 0xf7, 0xee, 0xf9, 0x38, 0x68, 0x58, 0x21, 0x09, 0x5c, 0x41, 0x74, ++ 0x86, 0x82, 0xec, 0xe0, 0x60, 0x7c, 0x02, 0x28, 0x11, 0xd2, 0xe9, 0x7c, 0x01, 0x29, 0xb8, 0xd8, ++ 0xa9, 0x7c, 0x00, 0x29, 0x01, 0xd1, 0x00, 0x28, 0xb8, 0xd0, 0xe5, 0x49, 0x01, 0x20, 0x48, 0x75, ++ 0x60, 0x7c, 0x28, 0x76, 0x02, 0x20, 0x18, 0xe0, 0x60, 0x7c, 0x02, 0x28, 0x03, 0xd3, 0x01, 0x99, ++ 0x01, 0x43, 0xc9, 0xb2, 0xe0, 0xe0, 0xe9, 0x7c, 0x01, 0x29, 0xa2, 0xd8, 0xa9, 0x7c, 0x00, 0x29, ++ 0x05, 0xd1, 0x02, 0xe0, 0xff, 0xf7, 0x7a, 0xfe, 0xfe, 0xbd, 0x00, 0x28, 0xfc, 0xd0, 0xd8, 0x49, ++ 0x01, 0x20, 0x48, 0x75, 0x60, 0x7c, 0x28, 0x76, 0x03, 0x20, 0x60, 0x74, 0xff, 0xf7, 0x53, 0xf9, ++ 0xfe, 0xf7, 0x6d, 0xfd, 0xbb, 0xe0, 0xda, 0xe0, 0x38, 0x68, 0x0d, 0x22, 0x52, 0x03, 0x80, 0x18, ++ 0x40, 0x8b, 0x00, 0x0a, 0x20, 0x5c, 0x2a, 0xe0, 0x39, 0x68, 0x0d, 0x20, 0x40, 0x03, 0x09, 0x18, ++ 0x49, 0x8b, 0x3a, 0x68, 0x09, 0x0a, 0x10, 0x18, 0x80, 0x8b, 0x60, 0x54, 0xa7, 0xe0, 0x38, 0x68, ++ 0x0d, 0x22, 0x52, 0x03, 0x80, 0x18, 0x40, 0x8b, 0x01, 0x0a, 0xc5, 0x48, 0x40, 0x5c, 0x16, 0xe0, ++ 0x38, 0x68, 0x0d, 0x21, 0x49, 0x03, 0x40, 0x18, 0x80, 0x8b, 0x3a, 0x68, 0x51, 0x18, 0x49, 0x8b, ++ 0x0a, 0x0a, 0xbf, 0x49, 0x88, 0x54, 0x92, 0xe0, 0x38, 0x68, 0x0d, 0x22, 0x52, 0x03, 0x80, 0x18, ++ 0x40, 0x8b, 0x00, 0x0a, 0x21, 0x18, 0x49, 0x78, 0x20, 0x5c, 0x09, 0x02, 0x08, 0x43, 0x03, 0x21, ++ 0x09, 0x07, 0x8b, 0x8a, 0x8e, 0x82, 0x39, 0x68, 0x89, 0x18, 0xfe, 0xe6, 0x38, 0x68, 0x0d, 0x21, ++ 0x49, 0x03, 0x40, 0x18, 0x80, 0x8b, 0x3a, 0x68, 0x51, 0x18, 0x49, 0x8b, 0x09, 0x0a, 0x60, 0x54, ++ 0x00, 0x0a, 0x61, 0x18, 0x48, 0x70, 0x72, 0xe0, 0x38, 0x68, 0x0d, 0x23, 0x5b, 0x03, 0xc0, 0x18, ++ 0x40, 0x8b, 0xab, 0x4a, 0x00, 0x0a, 0x11, 0x18, 0x49, 0x78, 0x10, 0x5c, 0x09, 0x02, 0x08, 0x43, ++ 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x8e, 0x82, 0x39, 0x68, 0xc9, 0x18, 0xdd, 0xe6, 0x38, 0x68, ++ 0x0d, 0x21, 0x49, 0x03, 0x40, 0x18, 0x80, 0x8b, 0x3a, 0x68, 0x03, 0x0a, 0x52, 0x18, 0x52, 0x8b, ++ 0x14, 0x0a, 0x9f, 0x4a, 0xa4, 0x18, 0x63, 0x70, 0x3b, 0x68, 0x59, 0x18, 0x49, 0x8b, 0x09, 0x0a, ++ 0x50, 0x54, 0x4c, 0xe0, 0x60, 0x7c, 0x02, 0x28, 0x4d, 0xd2, 0x38, 0x68, 0x0d, 0x23, 0x5b, 0x03, ++ 0xc0, 0x18, 0x40, 0x8b, 0x00, 0x0a, 0x10, 0xd0, 0x01, 0x28, 0x23, 0xd0, 0x02, 0x28, 0x00, 0xd0, ++ 0x72, 0xe7, 0x93, 0x48, 0x90, 0x49, 0x46, 0x75, 0x0e, 0x60, 0x90, 0x49, 0x41, 0x81, 0x01, 0x81, ++ 0x49, 0x1c, 0x90, 0x48, 0x04, 0xf0, 0xac, 0xff, 0x2f, 0xe0, 0x00, 0x23, 0x00, 0x96, 0x1a, 0x46, ++ 0x11, 0x21, 0x02, 0x20, 0x01, 0x96, 0x04, 0xf0, 0x97, 0xfe, 0x89, 0x49, 0x01, 0x20, 0x48, 0x75, ++ 0x48, 0x89, 0x86, 0x4a, 0x08, 0x81, 0x90, 0x42, 0x01, 0xd1, 0x00, 0x20, 0x00, 0xe0, 0x40, 0x1c, ++ 0x08, 0x81, 0x1c, 0xe0, 0x82, 0x4c, 0x22, 0x89, 0x88, 0x5c, 0x61, 0x89, 0x8a, 0x42, 0x03, 0xd1, ++ 0xff, 0x21, 0x01, 0x31, 0x08, 0x43, 0x06, 0xe0, 0x7c, 0x49, 0x8a, 0x42, 0x01, 0xd1, 0x00, 0x22, ++ 0x00, 0xe0, 0x52, 0x1c, 0x22, 0x81, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x8e, 0x82, 0x3a, 0x68, ++ 0xc1, 0xb2, 0xd2, 0x18, 0x91, 0x83, 0x00, 0x0a, 0x01, 0xd0, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, ++ 0xff, 0xf7, 0x73, 0xfd, 0xfe, 0xbd, 0x00, 0x21, 0x05, 0x20, 0x2b, 0xe7, 0x61, 0x7c, 0x02, 0x29, ++ 0x04, 0xd3, 0x01, 0x98, 0x08, 0x43, 0xc1, 0xb2, 0x0c, 0x20, 0x23, 0xe7, 0x3a, 0x68, 0x0d, 0x20, ++ 0x40, 0x03, 0x12, 0x18, 0x52, 0x8b, 0x12, 0x0a, 0x52, 0x07, 0x05, 0xd5, 0x3b, 0x68, 0x6a, 0x4a, ++ 0x9b, 0x18, 0x5b, 0x8e, 0xdb, 0x07, 0x05, 0xd0, 0xeb, 0x7c, 0x01, 0x2b, 0x09, 0xd9, 0x02, 0x21, ++ 0x0d, 0x20, 0x0f, 0xe7, 0x38, 0x68, 0x80, 0x18, 0x40, 0x8e, 0xc1, 0x07, 0xc9, 0x0f, 0x08, 0x20, ++ 0x08, 0xe7, 0xab, 0x7c, 0x00, 0x2b, 0x01, 0xd1, 0x00, 0x29, 0xd3, 0xd0, 0x5c, 0x4b, 0x01, 0x21, ++ 0x59, 0x75, 0x61, 0x7c, 0x29, 0x76, 0x04, 0x21, 0x61, 0x74, 0x39, 0x68, 0x05, 0x46, 0x48, 0x19, ++ 0x40, 0x8b, 0x00, 0x0a, 0xe0, 0x75, 0xff, 0xf7, 0xbf, 0xf9, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, ++ 0x86, 0x82, 0x50, 0x48, 0x00, 0x68, 0x39, 0x68, 0xc0, 0x8c, 0x49, 0x19, 0x35, 0xe6, 0x01, 0x21, ++ 0x69, 0x72, 0x4d, 0x48, 0x00, 0x21, 0x01, 0x60, 0x4c, 0x48, 0x4d, 0x4e, 0x41, 0x1c, 0x70, 0x81, ++ 0x30, 0x81, 0x4c, 0x48, 0x04, 0xf0, 0x24, 0xff, 0x00, 0x20, 0x70, 0x75, 0xe0, 0x7d, 0x41, 0x07, ++ 0x15, 0xd5, 0x44, 0x4c, 0x80, 0x07, 0x0e, 0xd4, 0x00, 0x99, 0x01, 0x20, 0x08, 0x56, 0x0f, 0x30, ++ 0x40, 0x10, 0xfe, 0xf7, 0x68, 0xff, 0x21, 0x68, 0x82, 0x20, 0x08, 0x56, 0x0f, 0x30, 0x40, 0x10, ++ 0xfe, 0xf7, 0x49, 0xff, 0x03, 0xe0, 0x0f, 0x20, 0x28, 0x56, 0xfe, 0xf7, 0xe5, 0xfe, 0xff, 0xf7, ++ 0x89, 0xf8, 0x38, 0x48, 0x00, 0x21, 0x00, 0x68, 0x81, 0x82, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, ++ 0x08, 0x22, 0xd2, 0x43, 0x8a, 0x82, 0x3a, 0x68, 0x08, 0x21, 0x38, 0x4b, 0xd2, 0x18, 0x11, 0x80, ++ 0x58, 0x21, 0x09, 0x5c, 0x41, 0x74, 0x7a, 0xe7, 0xa8, 0x88, 0xa2, 0x7d, 0x80, 0x18, 0x08, 0x5c, ++ 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x8e, 0x82, 0x3a, 0x68, 0x0d, 0x21, 0x49, 0x03, 0x51, 0x18, ++ 0x88, 0x83, 0xa0, 0x7d, 0xbf, 0x28, 0x01, 0xd3, 0x00, 0x20, 0x00, 0xe0, 0x40, 0x1c, 0xa0, 0x75, ++ 0x65, 0xe7, 0xaa, 0x88, 0xa0, 0x7d, 0x13, 0x18, 0xcb, 0x5c, 0xbf, 0x28, 0x01, 0xd3, 0x00, 0x20, ++ 0x00, 0xe0, 0x40, 0x1c, 0xc0, 0xb2, 0xa0, 0x75, 0x12, 0x18, 0x89, 0x5c, 0xbf, 0x28, 0x01, 0xd3, ++ 0x00, 0x20, 0x00, 0xe0, 0x40, 0x1c, 0xa0, 0x75, 0x03, 0x20, 0x00, 0x07, 0x82, 0x8a, 0x86, 0x82, ++ 0x18, 0x02, 0x08, 0x43, 0x3a, 0x68, 0x0d, 0x21, 0x49, 0x03, 0x51, 0x18, 0xc5, 0xe5, 0x03, 0x20, ++ 0x00, 0x07, 0x81, 0x8a, 0x86, 0x82, 0xff, 0xf7, 0xd7, 0xfc, 0xf3, 0xe7, 0x70, 0xb5, 0x01, 0xf0, ++ 0x63, 0xfa, 0x10, 0x49, 0x00, 0x20, 0x0b, 0x68, 0x11, 0x49, 0x18, 0x86, 0x1a, 0x46, 0x58, 0x86, ++ 0x80, 0x32, 0x90, 0x72, 0x1c, 0x46, 0xd0, 0x72, 0x40, 0x34, 0x20, 0x72, 0x60, 0x72, 0xa0, 0x72, ++ 0xe0, 0x72, 0x20, 0x73, 0xd0, 0x73, 0xa0, 0x73, 0x89, 0x7f, 0xe1, 0x73, 0x19, 0x46, 0x20, 0x74, ++ 0x60, 0x31, 0xc8, 0x75, 0x10, 0x71, 0x50, 0x71, 0x20, 0x75, 0xa0, 0x75, 0x08, 0x71, 0x48, 0x71, ++ 0x50, 0x72, 0x0d, 0xe0, 0x90, 0x00, 0x00, 0x20, 0x88, 0x00, 0x00, 0x20, 0xff, 0x02, 0x00, 0x00, ++ 0x00, 0x04, 0x00, 0x20, 0x00, 0x01, 0x00, 0x20, 0x80, 0xa1, 0x01, 0x00, 0x80, 0xa0, 0x01, 0x00, ++ 0xe0, 0x77, 0x58, 0x85, 0x88, 0x71, 0xc8, 0x71, 0x08, 0x72, 0x98, 0x85, 0xd8, 0x85, 0x48, 0x72, ++ 0x08, 0x75, 0xc8, 0x74, 0x48, 0x75, 0x88, 0x75, 0x48, 0x76, 0x88, 0x76, 0xc8, 0x76, 0x08, 0x77, ++ 0x90, 0x75, 0x10, 0x76, 0x01, 0x25, 0xd5, 0x75, 0x60, 0x80, 0x50, 0x76, 0x90, 0x76, 0xd0, 0x76, ++ 0x58, 0x82, 0x58, 0x73, 0x98, 0x73, 0xd8, 0x73, 0x18, 0x74, 0x48, 0x77, 0x88, 0x77, 0xc8, 0x77, ++ 0x10, 0x70, 0x08, 0x76, 0x90, 0x71, 0x98, 0x86, 0x10, 0x74, 0x70, 0xbd, 0x10, 0xb5, 0xff, 0xf7, ++ 0x89, 0xfb, 0xff, 0xf7, 0xa3, 0xff, 0x00, 0x21, 0x01, 0x20, 0x01, 0xf0, 0x81, 0xfb, 0x00, 0x21, ++ 0x02, 0x20, 0x01, 0xf0, 0x7d, 0xfb, 0x00, 0x21, 0x03, 0x20, 0x01, 0xf0, 0x79, 0xfb, 0x00, 0x21, ++ 0x04, 0x20, 0x01, 0xf0, 0x75, 0xfb, 0x00, 0x21, 0x05, 0x20, 0x01, 0xf0, 0x71, 0xfb, 0x62, 0xe4, ++ 0xf8, 0x48, 0x00, 0x68, 0xf8, 0x49, 0x40, 0x18, 0x80, 0x8a, 0xf8, 0x49, 0x00, 0x06, 0x02, 0x0f, ++ 0x08, 0x7c, 0xd2, 0x1e, 0x0b, 0x2a, 0x02, 0xd3, 0x10, 0x22, 0x10, 0x43, 0x01, 0xe0, 0xef, 0x22, ++ 0x10, 0x40, 0x08, 0x74, 0x70, 0x47, 0x70, 0xb5, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0xf0, 0x49, ++ 0x81, 0x82, 0xec, 0x49, 0x01, 0x22, 0x0c, 0x68, 0xd2, 0x02, 0xeb, 0x4b, 0x40, 0x3b, 0xe4, 0x18, ++ 0x22, 0x85, 0x82, 0x8a, 0x40, 0x22, 0xd2, 0x43, 0x82, 0x82, 0x0c, 0x68, 0x40, 0x22, 0xe4, 0x18, ++ 0x22, 0x84, 0xe6, 0x4a, 0xd2, 0x7b, 0x00, 0x2a, 0x2b, 0xd1, 0x82, 0x8a, 0xe5, 0x4a, 0x82, 0x82, ++ 0x0d, 0x68, 0x84, 0x14, 0xe0, 0x4a, 0xad, 0x18, 0xec, 0x81, 0x85, 0x8a, 0xe2, 0x4d, 0x85, 0x82, ++ 0x0e, 0x68, 0x80, 0x25, 0xb6, 0x18, 0xf5, 0x81, 0x85, 0x8a, 0xe0, 0x4d, 0x85, 0x82, 0x0d, 0x68, ++ 0xad, 0x18, 0xec, 0x80, 0x84, 0x8a, 0xde, 0x4c, 0x84, 0x82, 0xff, 0x24, 0x0d, 0x68, 0xc1, 0x34, ++ 0xad, 0x18, 0xec, 0x80, 0x84, 0x8a, 0x78, 0x24, 0xe4, 0x43, 0x84, 0x82, 0x0d, 0x68, 0x08, 0x24, ++ 0xaa, 0x18, 0x14, 0x80, 0x82, 0x8a, 0xd7, 0x4a, 0x82, 0x82, 0x09, 0x68, 0xa0, 0x02, 0xc9, 0x18, ++ 0xc8, 0x84, 0x70, 0xbd, 0x70, 0x47, 0x70, 0xb5, 0x04, 0xf0, 0xdc, 0xfa, 0xcb, 0x4a, 0xd1, 0x88, ++ 0x00, 0x29, 0x14, 0xd0, 0xcb, 0x08, 0xc0, 0x1a, 0x08, 0x18, 0xd0, 0x80, 0x10, 0x7b, 0x01, 0x21, ++ 0x14, 0x28, 0x0e, 0xd2, 0xcc, 0x4b, 0xcd, 0x4d, 0x43, 0x43, 0x5b, 0x19, 0x9b, 0x12, 0xd4, 0x88, ++ 0x5b, 0x1c, 0x5b, 0x10, 0x9c, 0x42, 0x04, 0xdc, 0xd1, 0x74, 0x40, 0x1c, 0x0f, 0xe0, 0xc0, 0x00, ++ 0xeb, 0xe7, 0x00, 0x28, 0x0d, 0xd0, 0xc4, 0x4b, 0xc5, 0x4d, 0x43, 0x43, 0x5b, 0x19, 0x9b, 0x12, ++ 0xd4, 0x88, 0x5b, 0x1c, 0x5b, 0x10, 0x9c, 0x42, 0x03, 0xdb, 0xd1, 0x74, 0x40, 0x1e, 0x10, 0x73, ++ 0x70, 0xbd, 0x00, 0x20, 0xd0, 0x74, 0x70, 0xbd, 0x70, 0xb5, 0x24, 0x21, 0xb3, 0x48, 0x04, 0xf0, ++ 0xb7, 0xfd, 0xb2, 0x4c, 0x26, 0x20, 0x20, 0x80, 0xba, 0x48, 0xa0, 0x80, 0x0c, 0x20, 0xa0, 0x73, ++ 0x0b, 0x20, 0x00, 0x26, 0x20, 0x73, 0xe6, 0x74, 0x26, 0x75, 0x66, 0x75, 0x04, 0xf0, 0x9a, 0xfa, ++ 0xc0, 0x00, 0xe0, 0x80, 0x00, 0x25, 0xff, 0xf7, 0xb6, 0xff, 0x6d, 0x1c, 0xed, 0xb2, 0x08, 0x2d, ++ 0xf9, 0xd3, 0xa4, 0x48, 0x00, 0x68, 0xa4, 0x49, 0x40, 0x18, 0xc0, 0x8f, 0x28, 0x21, 0x00, 0x07, ++ 0x00, 0x0f, 0xe0, 0x73, 0x26, 0x74, 0x01, 0x20, 0x60, 0x73, 0xa1, 0x75, 0x04, 0x21, 0xe1, 0x75, ++ 0x10, 0x21, 0x21, 0x76, 0x66, 0x76, 0xa0, 0x76, 0x02, 0x20, 0xe0, 0x76, 0x03, 0x20, 0x20, 0x77, ++ 0x24, 0x20, 0x60, 0x77, 0x20, 0x20, 0xa0, 0x77, 0x05, 0x20, 0xe6, 0x77, 0xc0, 0x01, 0x20, 0x84, ++ 0x0b, 0x20, 0x80, 0x01, 0x60, 0x84, 0x5f, 0x21, 0xc9, 0x00, 0x9f, 0x48, 0x04, 0xf0, 0x78, 0xfd, ++ 0x9e, 0x48, 0x06, 0x60, 0x9e, 0x48, 0x60, 0x81, 0x20, 0x81, 0x41, 0x1c, 0x9a, 0x48, 0x04, 0xf0, ++ 0x6f, 0xfd, 0x70, 0xbd, 0x10, 0xb5, 0x9b, 0x48, 0x00, 0x21, 0x00, 0x68, 0x0a, 0x23, 0x02, 0x46, ++ 0x01, 0x80, 0x40, 0x32, 0x93, 0x71, 0xd1, 0x71, 0xc1, 0x72, 0x81, 0x72, 0x01, 0x73, 0x41, 0x73, ++ 0x81, 0x73, 0x01, 0x74, 0xc1, 0x73, 0x41, 0x82, 0x41, 0x74, 0x91, 0x74, 0x01, 0x71, 0x81, 0x71, ++ 0xc1, 0x71, 0x01, 0x72, 0x41, 0x72, 0x41, 0x77, 0x02, 0x22, 0x42, 0x71, 0x01, 0x22, 0x82, 0x70, ++ 0x80, 0x30, 0x01, 0x72, 0xff, 0xf7, 0x92, 0xfe, 0x01, 0xe7, 0x70, 0xb5, 0x7b, 0x4a, 0x79, 0x4b, ++ 0xd0, 0x7b, 0x00, 0x28, 0x22, 0xd1, 0x18, 0x68, 0x77, 0x4c, 0x00, 0x19, 0x80, 0x8a, 0x0f, 0x21, ++ 0x00, 0x06, 0x00, 0x0f, 0x09, 0x1a, 0x03, 0x20, 0x00, 0x07, 0x85, 0x8a, 0x77, 0x4d, 0x0f, 0x3d, ++ 0x85, 0x82, 0x8d, 0x02, 0x1e, 0x68, 0x0d, 0x43, 0x36, 0x19, 0xb5, 0x84, 0x85, 0x8a, 0x0f, 0x25, ++ 0xed, 0x43, 0x85, 0x82, 0x1d, 0x68, 0x2c, 0x19, 0xa1, 0x85, 0x81, 0x8a, 0x2a, 0x21, 0xc9, 0x43, ++ 0x81, 0x82, 0x19, 0x68, 0x2a, 0x20, 0x78, 0x4c, 0x09, 0x19, 0x88, 0x81, 0x19, 0x68, 0x76, 0x48, ++ 0x40, 0x30, 0x09, 0x18, 0x09, 0x8c, 0xc9, 0x06, 0xc9, 0x0e, 0x51, 0x76, 0x19, 0x68, 0x09, 0x18, ++ 0x49, 0x8c, 0xc9, 0x06, 0xc9, 0x0e, 0x91, 0x76, 0x19, 0x68, 0x09, 0x18, 0x89, 0x8c, 0xc9, 0x06, ++ 0xc9, 0x0e, 0xd1, 0x76, 0x19, 0x68, 0x08, 0x18, 0xc0, 0x8c, 0xc0, 0x06, 0xc0, 0x0e, 0x10, 0x77, ++ 0x70, 0xbd, 0xf8, 0xb5, 0x57, 0x4d, 0x29, 0x68, 0x67, 0x48, 0xc0, 0x30, 0x08, 0x18, 0xc0, 0x8a, ++ 0x64, 0x4f, 0x01, 0x07, 0x38, 0x68, 0x09, 0x0f, 0x40, 0x30, 0xc1, 0x74, 0x53, 0x48, 0x03, 0x24, ++ 0xc0, 0x7b, 0x51, 0x4e, 0x24, 0x07, 0x00, 0x28, 0x2e, 0xd1, 0x28, 0x68, 0x80, 0x19, 0x80, 0x8a, ++ 0x0f, 0x21, 0x00, 0x06, 0x00, 0x0f, 0x0b, 0x1a, 0xa0, 0x8a, 0x5c, 0x48, 0xa0, 0x82, 0x2a, 0x68, ++ 0x19, 0x03, 0x49, 0x48, 0x40, 0x38, 0x12, 0x18, 0x11, 0x85, 0xa1, 0x8a, 0x0f, 0x21, 0xc9, 0x43, ++ 0xa1, 0x82, 0x29, 0x68, 0x09, 0x18, 0x4b, 0x85, 0xa1, 0x8a, 0x03, 0x21, 0xc9, 0x43, 0xa1, 0x82, ++ 0x2a, 0x68, 0x03, 0x21, 0x10, 0x18, 0x01, 0x86, 0xa0, 0x8a, 0x78, 0x20, 0xc0, 0x43, 0xa0, 0x82, ++ 0x29, 0x68, 0xd8, 0x00, 0x89, 0x19, 0x08, 0x80, 0xa0, 0x8a, 0x02, 0x20, 0xc0, 0x43, 0xa0, 0x82, ++ 0x29, 0x68, 0x02, 0x20, 0x89, 0x19, 0x48, 0x82, 0xfd, 0xf7, 0xfa, 0xf9, 0x38, 0x68, 0x36, 0x4a, ++ 0x01, 0x78, 0x47, 0x4b, 0x4f, 0x07, 0xc0, 0x3a, 0x00, 0x21, 0x00, 0x2f, 0x09, 0xdb, 0x53, 0x27, ++ 0x3f, 0x5c, 0x00, 0x2f, 0x0b, 0xd1, 0x31, 0x4f, 0x3f, 0x78, 0xbf, 0x06, 0xff, 0x0e, 0x06, 0x2f, ++ 0x05, 0xd3, 0xa7, 0x8a, 0xa3, 0x82, 0x2b, 0x68, 0x9b, 0x18, 0x19, 0x80, 0x05, 0xe0, 0xa7, 0x8a, ++ 0xa3, 0x82, 0x2f, 0x68, 0x04, 0x23, 0xbf, 0x18, 0x3b, 0x80, 0x03, 0x78, 0x5b, 0x07, 0x12, 0xd4, ++ 0x53, 0x23, 0x1b, 0x5c, 0x00, 0x2b, 0x0e, 0xd1, 0x24, 0x4b, 0x1b, 0x78, 0x9b, 0x06, 0xdb, 0x0e, ++ 0x0e, 0x2b, 0x08, 0xd9, 0xa3, 0x8a, 0x80, 0x23, 0xdb, 0x43, 0xa3, 0x82, 0x2f, 0x68, 0x80, 0x23, ++ 0xba, 0x18, 0x13, 0x80, 0x06, 0xe0, 0xa3, 0x8a, 0x80, 0x23, 0xdb, 0x43, 0xa3, 0x82, 0x2b, 0x68, ++ 0x9a, 0x18, 0x11, 0x80, 0x02, 0x78, 0x52, 0x07, 0x14, 0xd5, 0x53, 0x22, 0x12, 0x5c, 0x00, 0x2a, ++ 0x10, 0xd1, 0x16, 0x4a, 0x12, 0x78, 0x92, 0x06, 0xd2, 0x0e, 0x16, 0x2a, 0x0a, 0xd9, 0xa2, 0x8a, ++ 0x02, 0x22, 0xd2, 0x43, 0xa2, 0x82, 0x2f, 0x68, 0x02, 0x22, 0x0f, 0x4b, 0x40, 0x3b, 0xfb, 0x18, ++ 0x9a, 0x85, 0x08, 0xe0, 0xa2, 0x8a, 0x02, 0x22, 0xd2, 0x43, 0xa2, 0x82, 0x2b, 0x68, 0x0a, 0x4a, ++ 0x40, 0x3a, 0x9a, 0x18, 0x91, 0x85, 0x02, 0x78, 0x53, 0x07, 0x09, 0x4a, 0xa3, 0x8a, 0xa2, 0x82, ++ 0x30, 0xd5, 0x01, 0x23, 0x2f, 0x68, 0xdb, 0x02, 0x03, 0x4a, 0x40, 0x3a, 0xba, 0x18, 0x53, 0x85, ++ 0x2c, 0xe0, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, 0x40, 0xa1, 0x01, 0x00, 0x00, 0x04, 0x00, 0x20, ++ 0xff, 0xf7, 0x00, 0x00, 0xff, 0xe1, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0xff, 0xc3, 0x00, 0x00, ++ 0x3f, 0xfc, 0x00, 0x00, 0xff, 0xdf, 0x00, 0x00, 0x99, 0x56, 0xfc, 0xff, 0xe6, 0xf7, 0xd3, 0x00, ++ 0x5a, 0x60, 0xda, 0x00, 0x01, 0xd1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x88, 0x00, 0x00, 0x20, ++ 0xff, 0x02, 0x00, 0x00, 0x90, 0x00, 0x00, 0x20, 0x40, 0xa2, 0x01, 0x00, 0xff, 0x0f, 0x00, 0x00, ++ 0xfb, 0xff, 0x00, 0x00, 0x2b, 0x68, 0xfe, 0x4a, 0x9a, 0x18, 0x51, 0x85, 0x2a, 0x68, 0xff, 0x32, ++ 0x01, 0x32, 0x92, 0x8d, 0x92, 0x07, 0xd3, 0x0f, 0x02, 0x46, 0x80, 0x32, 0x53, 0x75, 0x94, 0x46, ++ 0x00, 0x2b, 0xf8, 0x4a, 0xa3, 0x8a, 0xa2, 0x82, 0x02, 0xd0, 0x1b, 0x23, 0x5b, 0x01, 0x01, 0xe0, ++ 0x11, 0x23, 0x5b, 0x01, 0x2f, 0x68, 0xf2, 0x4a, 0x80, 0x32, 0xba, 0x18, 0x13, 0x80, 0x62, 0x46, ++ 0x52, 0x7d, 0x00, 0x2a, 0x07, 0xd0, 0xa2, 0x8a, 0xef, 0x4a, 0xa2, 0x82, 0x07, 0x22, 0x2b, 0x68, ++ 0xd2, 0x02, 0x9b, 0x19, 0x5a, 0x81, 0xa2, 0x8a, 0x01, 0x22, 0xd2, 0x43, 0xa2, 0x82, 0x2f, 0x68, ++ 0x01, 0x22, 0x0d, 0x23, 0x5b, 0x03, 0xfb, 0x18, 0x5a, 0x80, 0x40, 0x30, 0xc2, 0x7c, 0xe5, 0x48, ++ 0x92, 0x1e, 0xe0, 0x30, 0x13, 0x00, 0x04, 0xf0, 0x33, 0xfc, 0x08, 0x05, 0x05, 0x05, 0x0a, 0x0a, ++ 0x05, 0x05, 0x0a, 0x14, 0xa2, 0x8a, 0xa0, 0x82, 0xff, 0x22, 0x01, 0x32, 0x03, 0xe0, 0xa2, 0x8a, ++ 0xa0, 0x82, 0x01, 0x22, 0x52, 0x02, 0x2b, 0x68, 0x0d, 0x20, 0x40, 0x03, 0x18, 0x18, 0xc2, 0x80, ++ 0x06, 0xe0, 0xa2, 0x8a, 0xa0, 0x82, 0x2a, 0x68, 0x0d, 0x20, 0x40, 0x03, 0x10, 0x18, 0xc1, 0x80, ++ 0x2a, 0x68, 0xd6, 0x48, 0x10, 0x18, 0xc0, 0x8e, 0x00, 0x07, 0x00, 0x0f, 0x01, 0x28, 0x0f, 0xd0, ++ 0x04, 0x28, 0xa0, 0x8a, 0xd2, 0x48, 0xa0, 0x82, 0x28, 0x68, 0x11, 0xd0, 0x80, 0x19, 0x01, 0x80, ++ 0xa0, 0x8a, 0x01, 0x20, 0xc0, 0x43, 0xa0, 0x82, 0x28, 0x68, 0x80, 0x19, 0x41, 0x80, 0xf8, 0xbd, ++ 0xa0, 0x8a, 0xcb, 0x48, 0xa0, 0x82, 0x2a, 0x68, 0x80, 0x20, 0x92, 0x19, 0x10, 0x80, 0xef, 0xe7, ++ 0x80, 0x19, 0x01, 0x80, 0xa0, 0x8a, 0x01, 0x20, 0xc0, 0x43, 0xa0, 0x82, 0x29, 0x68, 0x01, 0x20, ++ 0x89, 0x19, 0x48, 0x80, 0xf8, 0xbd, 0xf8, 0xb5, 0x1f, 0x20, 0x01, 0xf0, 0x9e, 0xfd, 0x01, 0xf0, ++ 0x2b, 0xfb, 0xc0, 0x4f, 0x03, 0x24, 0x39, 0x68, 0x60, 0x31, 0x08, 0x70, 0x24, 0x07, 0xa0, 0x8a, ++ 0x09, 0x20, 0xc0, 0x43, 0xa0, 0x82, 0xbc, 0x4d, 0x08, 0x20, 0x29, 0x68, 0xb4, 0x4e, 0x80, 0x3e, ++ 0x89, 0x19, 0x08, 0x80, 0x00, 0x20, 0xfe, 0xf7, 0xf5, 0xf8, 0xb8, 0x49, 0xb8, 0x4a, 0xc8, 0x7f, ++ 0x03, 0x06, 0x15, 0xd5, 0xa3, 0x8a, 0xa2, 0x82, 0x40, 0x06, 0x40, 0x0e, 0x2a, 0x68, 0x92, 0x19, ++ 0x50, 0x80, 0xb0, 0x48, 0x00, 0x27, 0x00, 0x68, 0x02, 0x46, 0x40, 0x32, 0xd6, 0x7c, 0x33, 0x00, ++ 0x04, 0xf0, 0xbe, 0xfb, 0x09, 0x1b, 0x19, 0x43, 0x14, 0x43, 0x43, 0x14, 0x43, 0x14, 0x43, 0x00, ++ 0x38, 0x68, 0x03, 0x88, 0x9c, 0x46, 0x1b, 0x06, 0xeb, 0xd4, 0x83, 0x79, 0xdb, 0x07, 0xe8, 0xd1, ++ 0x63, 0x46, 0xa0, 0x8a, 0x5b, 0x07, 0xa2, 0x82, 0x07, 0x20, 0xdf, 0xe7, 0x2a, 0x21, 0xd1, 0x73, ++ 0x15, 0x21, 0x11, 0x74, 0x0d, 0xe0, 0xd7, 0x73, 0x0a, 0xe0, 0x03, 0x79, 0x1e, 0x06, 0x02, 0xd5, ++ 0x59, 0x06, 0x49, 0x0e, 0x03, 0xe0, 0x03, 0x78, 0x5b, 0x07, 0x1e, 0xd5, 0x49, 0x7f, 0xd1, 0x73, ++ 0x17, 0x74, 0x60, 0x30, 0xc7, 0x75, 0x0f, 0x20, 0x96, 0x4e, 0x10, 0x56, 0xfe, 0xf7, 0x2c, 0xfb, ++ 0x31, 0x68, 0x50, 0x20, 0x08, 0x56, 0xfe, 0xf7, 0xe1, 0xfa, 0x30, 0x68, 0x95, 0x4f, 0x00, 0x78, ++ 0x40, 0x07, 0x1b, 0xd5, 0x01, 0xf0, 0xef, 0xfd, 0x30, 0x68, 0x01, 0x78, 0x49, 0x07, 0x15, 0xd5, ++ 0x40, 0x30, 0xc0, 0x7c, 0x01, 0x28, 0x02, 0xd0, 0x10, 0xe0, 0x89, 0x7f, 0xdf, 0xe7, 0xa0, 0x8a, ++ 0x10, 0x20, 0xc0, 0x43, 0xa0, 0x82, 0x2a, 0x68, 0x10, 0x21, 0x81, 0x48, 0x12, 0x18, 0xd1, 0x84, ++ 0xa1, 0x8a, 0xa7, 0x82, 0x2a, 0x68, 0x20, 0x21, 0x10, 0x18, 0xc1, 0x84, 0xa0, 0x8a, 0xa7, 0x82, ++ 0x29, 0x68, 0x20, 0x20, 0x0d, 0x22, 0x52, 0x03, 0x89, 0x18, 0x08, 0x84, 0x30, 0x68, 0x01, 0x21, ++ 0x40, 0x30, 0x81, 0x73, 0xf8, 0xbd, 0x10, 0xb5, 0x7a, 0x4c, 0x20, 0x68, 0x60, 0x30, 0x00, 0x78, ++ 0x01, 0xf0, 0x0b, 0xfd, 0x21, 0x68, 0x61, 0x20, 0x08, 0x56, 0xfe, 0xf7, 0x73, 0xf8, 0x21, 0x68, ++ 0x00, 0x20, 0x40, 0x31, 0x88, 0x73, 0x0f, 0x20, 0x08, 0x56, 0xfe, 0xf7, 0xe5, 0xfa, 0x21, 0x68, ++ 0x50, 0x20, 0x08, 0x56, 0xfe, 0xf7, 0x9a, 0xfa, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x20, 0x21, ++ 0xc9, 0x43, 0x81, 0x82, 0x6c, 0x49, 0x20, 0x20, 0x09, 0x68, 0x0d, 0x22, 0x52, 0x03, 0x89, 0x18, ++ 0x08, 0x84, 0x20, 0x68, 0x01, 0x21, 0x40, 0x30, 0x81, 0x73, 0xa8, 0xe4, 0x30, 0xb5, 0x66, 0x4c, ++ 0x20, 0x68, 0x5f, 0x4d, 0xc0, 0x3d, 0x40, 0x19, 0xc0, 0x8e, 0x21, 0x68, 0x80, 0x04, 0x40, 0x0f, ++ 0x49, 0x19, 0xc9, 0x8e, 0x49, 0x05, 0x49, 0x0f, 0x40, 0x18, 0x21, 0x68, 0x40, 0x08, 0x49, 0x19, ++ 0xc9, 0x8e, 0x89, 0x06, 0x89, 0x0e, 0x43, 0x18, 0x20, 0x68, 0x40, 0x19, 0x00, 0x8f, 0x21, 0x68, ++ 0x80, 0x04, 0x40, 0x0f, 0x49, 0x19, 0x09, 0x8f, 0xc9, 0x06, 0xc9, 0x0e, 0x40, 0x18, 0x21, 0x68, ++ 0x49, 0x19, 0x09, 0x8f, 0x89, 0x09, 0xc9, 0x07, 0xc9, 0x0f, 0x00, 0xd0, 0x40, 0x42, 0x21, 0x68, ++ 0x49, 0x19, 0x09, 0x8f, 0x22, 0x68, 0x49, 0x05, 0x49, 0x0f, 0x52, 0x19, 0x12, 0x8f, 0xd2, 0x06, ++ 0xd2, 0x0e, 0x89, 0x18, 0x22, 0x68, 0x52, 0x19, 0x12, 0x8f, 0x52, 0x09, 0xd2, 0x07, 0xd2, 0x0f, ++ 0x00, 0xd0, 0x49, 0x42, 0x40, 0x18, 0x42, 0x10, 0x20, 0x68, 0x40, 0x19, 0x40, 0x8f, 0x80, 0x06, ++ 0x81, 0x16, 0x20, 0x68, 0x40, 0x19, 0x40, 0x8f, 0x24, 0x68, 0x40, 0x05, 0xc0, 0x16, 0x65, 0x19, ++ 0x3a, 0x24, 0x2c, 0x5f, 0xe4, 0x12, 0x00, 0x2b, 0x00, 0xda, 0x5b, 0x42, 0x00, 0x2a, 0x00, 0xda, ++ 0x52, 0x42, 0x9a, 0x18, 0x00, 0x29, 0x00, 0xda, 0x49, 0x42, 0x51, 0x18, 0x00, 0x28, 0x00, 0xda, ++ 0x40, 0x42, 0x08, 0x18, 0x00, 0x2c, 0x00, 0xda, 0x64, 0x42, 0x00, 0x19, 0x80, 0xb2, 0x30, 0xbd, ++ 0xf0, 0xb5, 0x35, 0x4c, 0x21, 0x68, 0x2e, 0x48, 0xc0, 0x38, 0x09, 0x18, 0xc9, 0x8e, 0x22, 0x68, ++ 0x89, 0x04, 0x49, 0x0f, 0x12, 0x18, 0xd2, 0x8e, 0x52, 0x05, 0x52, 0x0f, 0x89, 0x18, 0x22, 0x68, ++ 0x49, 0x08, 0x12, 0x18, 0xd2, 0x8e, 0x92, 0x06, 0x92, 0x0e, 0x8e, 0x18, 0x21, 0x68, 0x09, 0x18, ++ 0x09, 0x8f, 0x22, 0x68, 0x89, 0x04, 0x49, 0x0f, 0x12, 0x18, 0x12, 0x8f, 0xd2, 0x06, 0xd2, 0x0e, ++ 0x89, 0x18, 0x22, 0x68, 0x12, 0x18, 0x12, 0x8f, 0x92, 0x09, 0xd2, 0x07, 0xd2, 0x0f, 0x00, 0xd0, ++ 0x49, 0x42, 0x22, 0x68, 0x12, 0x18, 0x12, 0x8f, 0x23, 0x68, 0x52, 0x05, 0x52, 0x0f, 0x1b, 0x18, ++ 0x1b, 0x8f, 0xdb, 0x06, 0xdb, 0x0e, 0xd2, 0x18, 0x23, 0x68, 0x1b, 0x18, 0x1b, 0x8f, 0x5b, 0x09, ++ 0xdb, 0x07, 0xdb, 0x0f, 0x00, 0xd0, 0x52, 0x42, 0x89, 0x18, 0x4a, 0x10, 0x21, 0x68, 0x10, 0x48, ++ 0xc0, 0x38, 0x09, 0x18, 0x49, 0x8f, 0x27, 0x68, 0x89, 0x06, 0x89, 0x16, 0x55, 0x18, 0x4b, 0x00, ++ 0x5d, 0x19, 0x3f, 0x18, 0x7f, 0x8f, 0x7f, 0x05, 0xff, 0x16, 0x7f, 0x00, 0xed, 0x19, 0x27, 0x68, ++ 0x3f, 0x18, 0x3a, 0x20, 0x38, 0x5e, 0xc0, 0x12, 0x28, 0x18, 0x0a, 0x4d, 0x2d, 0x68, 0x2d, 0x88, ++ 0xaf, 0x06, 0xbf, 0x0f, 0x02, 0x2f, 0x28, 0xd1, 0x6d, 0x07, 0x26, 0xd5, 0x50, 0x00, 0x13, 0xe0, ++ 0x00, 0xa1, 0x01, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0xff, 0xc7, 0x00, 0x00, 0x00, 0xa3, 0x01, 0x00, ++ 0x7f, 0xff, 0xff, 0xff, 0x90, 0x00, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x20, ++ 0xf0, 0xff, 0x00, 0x00, 0xdf, 0xff, 0x00, 0x00, 0x80, 0x19, 0x40, 0x18, 0x22, 0x68, 0xc1, 0x18, ++ 0x2e, 0x48, 0x12, 0x18, 0x52, 0x8f, 0x52, 0x05, 0xd2, 0x16, 0x52, 0x00, 0x89, 0x18, 0x22, 0x68, ++ 0x12, 0x18, 0x3a, 0x20, 0x10, 0x5e, 0xc0, 0x12, 0x08, 0x18, 0xf0, 0xbd, 0x00, 0xb5, 0xff, 0xf7, ++ 0x15, 0xff, 0x81, 0x00, 0x40, 0x00, 0x08, 0x18, 0x80, 0xb2, 0x00, 0xbd, 0x00, 0xb5, 0x00, 0x22, ++ 0xfd, 0xf7, 0x57, 0xff, 0x00, 0x28, 0x01, 0xda, 0x40, 0x42, 0x01, 0x22, 0x20, 0x49, 0x09, 0x68, ++ 0x1e, 0x4b, 0x40, 0x33, 0xc9, 0x18, 0x09, 0x88, 0xc9, 0x08, 0xc9, 0x07, 0xc9, 0x0f, 0x02, 0xd0, ++ 0x40, 0x00, 0x1c, 0x49, 0x02, 0xe0, 0x1b, 0x49, 0x40, 0x00, 0x40, 0x39, 0x08, 0x5e, 0x00, 0x2a, ++ 0x01, 0xd0, 0x40, 0x42, 0x00, 0xb2, 0x00, 0xbd, 0x10, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, ++ 0x8a, 0x13, 0x8a, 0x82, 0x12, 0x4a, 0x80, 0x06, 0x14, 0x68, 0xc3, 0x0d, 0x0f, 0x48, 0x24, 0x18, ++ 0xe3, 0x82, 0x8b, 0x8a, 0x10, 0x4b, 0x8b, 0x82, 0x12, 0x68, 0x59, 0x1c, 0x10, 0x18, 0xc1, 0x82, ++ 0x82, 0xe4, 0xc2, 0x06, 0xd2, 0x0e, 0x01, 0x21, 0x91, 0x40, 0x40, 0x09, 0x0b, 0x4a, 0x80, 0x00, ++ 0x80, 0x18, 0x01, 0x60, 0x70, 0x47, 0xc2, 0x06, 0xd2, 0x0e, 0x01, 0x21, 0x91, 0x40, 0x07, 0x4a, ++ 0x40, 0x09, 0x80, 0x00, 0x80, 0x32, 0x80, 0x18, 0x01, 0x60, 0x70, 0x47, 0x40, 0xa0, 0x01, 0x00, ++ 0x84, 0x00, 0x00, 0x20, 0x14, 0x7a, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0xe1, 0x00, 0xe0, ++ 0x70, 0xb5, 0xfd, 0x49, 0x00, 0x25, 0x0a, 0x68, 0x11, 0x46, 0x40, 0x31, 0x13, 0x46, 0x60, 0x33, ++ 0xcd, 0x75, 0x4d, 0x77, 0x1d, 0x73, 0xd5, 0x83, 0x1c, 0x46, 0x15, 0x84, 0x00, 0x28, 0x09, 0xd0, ++ 0x0f, 0x24, 0xe4, 0x43, 0x01, 0x28, 0x08, 0xd0, 0x00, 0x23, 0x02, 0x28, 0x1a, 0xd0, 0x03, 0x28, ++ 0x17, 0xd0, 0x05, 0xe0, 0x0f, 0x23, 0xe5, 0x77, 0x02, 0xe0, 0x80, 0x32, 0x23, 0x46, 0x15, 0x70, ++ 0x10, 0x24, 0x0c, 0x57, 0x02, 0x28, 0x0d, 0xd0, 0x03, 0x28, 0x0b, 0xd0, 0x4b, 0x76, 0xcd, 0x76, ++ 0x48, 0x7e, 0x88, 0x76, 0x18, 0x46, 0xfd, 0xf7, 0xe5, 0xfe, 0x20, 0x46, 0xfe, 0xf7, 0x16, 0xf9, ++ 0x70, 0xbd, 0x0f, 0x24, 0x4c, 0x76, 0xf2, 0xe7, 0x70, 0xb5, 0xe3, 0x4c, 0x00, 0x25, 0x21, 0x68, ++ 0x0a, 0x46, 0x40, 0x32, 0x0b, 0x46, 0x60, 0x33, 0xd5, 0x75, 0x00, 0x28, 0x07, 0xd0, 0x01, 0x28, ++ 0x0c, 0xd0, 0xd5, 0x76, 0x02, 0x28, 0x1d, 0xd0, 0x03, 0x28, 0x22, 0xd0, 0x0f, 0xe0, 0xc8, 0x7b, ++ 0xc6, 0x08, 0xd6, 0x76, 0xdb, 0x7f, 0x00, 0x02, 0xc0, 0x18, 0x07, 0xe0, 0x08, 0x7c, 0xc3, 0x08, ++ 0x5b, 0x42, 0xd3, 0x76, 0x03, 0x02, 0x80, 0x20, 0x40, 0x5c, 0x18, 0x18, 0x88, 0x84, 0x95, 0x76, ++ 0x1b, 0x20, 0x10, 0x56, 0xfd, 0xf7, 0xb6, 0xfe, 0x21, 0x68, 0x5a, 0x20, 0x08, 0x56, 0xfe, 0xf7, ++ 0xe5, 0xf8, 0x70, 0xbd, 0x48, 0x7b, 0xc5, 0x08, 0x6d, 0x42, 0x95, 0x76, 0x00, 0x02, 0x5b, 0x7f, ++ 0x04, 0xe0, 0x88, 0x7b, 0xc5, 0x08, 0x95, 0x76, 0x9b, 0x7f, 0x00, 0x02, 0xc0, 0x18, 0x88, 0x84, ++ 0xe6, 0xe7, 0xf0, 0xb5, 0xc4, 0x4c, 0x94, 0x46, 0x24, 0x68, 0x08, 0x9a, 0x01, 0x25, 0x05, 0x9f, ++ 0x06, 0x9e, 0x60, 0x34, 0x01, 0x2a, 0x03, 0xd0, 0x00, 0x29, 0x16, 0xdb, 0x01, 0x21, 0x0a, 0xe0, ++ 0x00, 0x29, 0x06, 0xd0, 0x02, 0xda, 0x00, 0x2b, 0x03, 0xdc, 0x0e, 0xe0, 0x00, 0x2b, 0xf5, 0xda, ++ 0x60, 0x46, 0x25, 0x73, 0x05, 0xe0, 0x07, 0x9a, 0x51, 0x43, 0x40, 0x1a, 0x00, 0x21, 0x40, 0xb2, ++ 0x21, 0x73, 0xb0, 0x42, 0x04, 0xdd, 0x30, 0x46, 0x05, 0xe0, 0x00, 0x21, 0xc9, 0x43, 0xf2, 0xe7, ++ 0xb8, 0x42, 0x01, 0xda, 0x38, 0x46, 0x25, 0x73, 0xf0, 0xbd, 0xf0, 0xb5, 0x85, 0xb0, 0x05, 0x00, ++ 0x4c, 0xd0, 0x1e, 0x20, 0xc0, 0x43, 0x01, 0x2d, 0x01, 0xd0, 0x03, 0x2d, 0x46, 0xd0, 0x00, 0x22, ++ 0xa9, 0x49, 0x1e, 0x23, 0x09, 0x68, 0x20, 0x24, 0xcb, 0x5e, 0x0c, 0x5f, 0x9b, 0x02, 0x23, 0x43, ++ 0x0c, 0x46, 0x40, 0x34, 0xe6, 0x7c, 0x0f, 0x3b, 0x01, 0x2e, 0xa4, 0x4e, 0x36, 0x68, 0xa4, 0x4f, ++ 0x37, 0xd0, 0xf6, 0x19, 0x36, 0x8e, 0xce, 0x83, 0xa0, 0x4e, 0x36, 0x68, 0xf6, 0x19, 0x76, 0x8e, ++ 0xb6, 0x05, 0xb6, 0x0d, 0x0e, 0x84, 0x1e, 0x26, 0x8e, 0x5f, 0x20, 0x27, 0xcf, 0x5f, 0xb6, 0x02, ++ 0x3e, 0x43, 0x19, 0x21, 0x0f, 0x3e, 0x61, 0x56, 0xb4, 0x46, 0x4e, 0x1c, 0x02, 0x2e, 0x01, 0xd9, ++ 0x49, 0x10, 0x61, 0x76, 0x61, 0x7f, 0x5a, 0x27, 0x49, 0x1c, 0xce, 0xb2, 0x92, 0x49, 0x66, 0x77, ++ 0x09, 0x68, 0x05, 0x2e, 0xcf, 0x57, 0x1d, 0xd8, 0x19, 0x21, 0x61, 0x56, 0x00, 0x26, 0x01, 0x92, ++ 0x02, 0x91, 0x00, 0x90, 0x03, 0x96, 0x1b, 0x22, 0xa2, 0x56, 0x38, 0x46, 0x61, 0x46, 0xff, 0xf7, ++ 0x88, 0xff, 0x89, 0x49, 0x09, 0x68, 0x40, 0x31, 0xce, 0x75, 0x23, 0xe0, 0x1f, 0x22, 0x00, 0x20, ++ 0xb6, 0xe7, 0xf6, 0x19, 0x36, 0x8d, 0xce, 0x83, 0x84, 0x4e, 0x36, 0x68, 0xf6, 0x19, 0x76, 0x8d, ++ 0xf6, 0xb2, 0xc7, 0xe7, 0x01, 0x21, 0x07, 0x2e, 0x12, 0xd8, 0x19, 0x26, 0xa6, 0x57, 0x01, 0x92, ++ 0x03, 0x91, 0x00, 0x90, 0x02, 0x96, 0x1b, 0x22, 0xa2, 0x56, 0x38, 0x46, 0x61, 0x46, 0xff, 0xf7, ++ 0x68, 0xff, 0x79, 0x49, 0x6c, 0x22, 0x09, 0x68, 0x52, 0x5c, 0x40, 0x31, 0xca, 0x75, 0x01, 0xe0, ++ 0x38, 0x46, 0xe1, 0x75, 0x74, 0x4c, 0x21, 0x68, 0x40, 0x31, 0x8a, 0x7e, 0xca, 0x76, 0x88, 0x76, ++ 0x00, 0x2d, 0x0a, 0xd0, 0x01, 0x2d, 0x08, 0xd0, 0xfe, 0xf7, 0x28, 0xf8, 0x20, 0x68, 0x01, 0x46, ++ 0x40, 0x30, 0xc2, 0x7d, 0x01, 0x2a, 0x03, 0xd0, 0x0f, 0xe0, 0xfd, 0xf7, 0xeb, 0xfd, 0xf5, 0xe7, ++ 0x00, 0x2d, 0x0d, 0xd0, 0x01, 0x2d, 0x13, 0xd0, 0x6a, 0x4a, 0x02, 0x2d, 0x82, 0x56, 0x17, 0xd0, ++ 0x00, 0x2a, 0x00, 0xda, 0x52, 0x42, 0xd0, 0x00, 0x88, 0x73, 0x00, 0x20, 0x05, 0xb0, 0xf0, 0xbd, ++ 0x1a, 0x22, 0x82, 0x56, 0x00, 0x2a, 0x00, 0xda, 0x52, 0x42, 0xd0, 0x00, 0xc8, 0x73, 0xf4, 0xe7, ++ 0x1a, 0x22, 0x82, 0x56, 0x00, 0x2a, 0x00, 0xda, 0x52, 0x42, 0xd0, 0x00, 0x08, 0x74, 0xec, 0xe7, ++ 0x00, 0x2a, 0x00, 0xda, 0x52, 0x42, 0xd0, 0x00, 0x48, 0x73, 0xe6, 0xe7, 0xf8, 0xb5, 0x56, 0x4e, ++ 0x04, 0x46, 0x30, 0x68, 0x53, 0x21, 0x0b, 0x5c, 0x00, 0x25, 0x54, 0x49, 0x01, 0x2b, 0x54, 0x4a, ++ 0x0b, 0x68, 0x17, 0xd0, 0x9b, 0x18, 0x1b, 0x8e, 0xc3, 0x83, 0x09, 0x68, 0x89, 0x18, 0x49, 0x8e, ++ 0x89, 0x05, 0x89, 0x0d, 0x01, 0x84, 0xfd, 0xf7, 0xa4, 0xfd, 0x31, 0x68, 0x0b, 0x46, 0x40, 0x33, ++ 0xd8, 0x76, 0x02, 0x2c, 0x0e, 0xd0, 0x03, 0x2c, 0x0f, 0xd0, 0x01, 0x2c, 0x10, 0xd0, 0x00, 0x2c, ++ 0x11, 0xd0, 0x12, 0xe0, 0x9b, 0x18, 0x1b, 0x8d, 0xc3, 0x83, 0x09, 0x68, 0x89, 0x18, 0x49, 0x8d, ++ 0xc9, 0xb2, 0xe7, 0xe7, 0x79, 0x20, 0x45, 0x5c, 0x07, 0xe0, 0x7a, 0x20, 0x45, 0x5c, 0x04, 0xe0, ++ 0x7b, 0x20, 0x45, 0x5c, 0x01, 0xe0, 0x7c, 0x20, 0x45, 0x5c, 0xca, 0x8b, 0x00, 0x20, 0x00, 0x2a, ++ 0x05, 0xd0, 0x0a, 0x20, 0x0c, 0xe0, 0x52, 0x10, 0x40, 0x1c, 0x0a, 0x84, 0x40, 0xb2, 0x20, 0x22, ++ 0x8a, 0x5e, 0x00, 0x2a, 0xf7, 0xdc, 0x07, 0xe0, 0x52, 0x10, 0x40, 0x1c, 0xca, 0x83, 0x40, 0xb2, ++ 0x1e, 0x22, 0x8a, 0x5e, 0x00, 0x2a, 0xf7, 0xdc, 0x00, 0x1f, 0x40, 0xb2, 0x8a, 0x8c, 0xc0, 0x01, ++ 0xd2, 0x08, 0xc0, 0x10, 0x1f, 0x27, 0x10, 0x1a, 0x3f, 0x02, 0x02, 0x2c, 0x05, 0xd0, 0x03, 0x2c, ++ 0x03, 0xd0, 0x01, 0x2c, 0x01, 0xd0, 0x00, 0x2c, 0x02, 0xd1, 0xb8, 0x42, 0x00, 0xdd, 0x38, 0x46, ++ 0xc2, 0x04, 0x16, 0x0c, 0xea, 0x00, 0x12, 0x18, 0x8e, 0x84, 0x02, 0x2c, 0x05, 0xd0, 0x03, 0x2c, ++ 0x03, 0xd0, 0x01, 0x2c, 0x01, 0xd0, 0x00, 0x2c, 0x02, 0xd1, 0xba, 0x42, 0x00, 0xdd, 0x3a, 0x46, ++ 0xd0, 0x04, 0x00, 0x0c, 0x42, 0x05, 0x1f, 0x27, 0x12, 0x0e, 0x7d, 0x42, 0x00, 0x2c, 0x0a, 0xd0, ++ 0x03, 0x2c, 0x08, 0xd0, 0xc0, 0x0a, 0x40, 0x42, 0x01, 0x2c, 0x07, 0xd0, 0x02, 0x2c, 0x11, 0xd0, ++ 0x03, 0x2c, 0x0f, 0xd0, 0x19, 0xe0, 0xc0, 0x0a, 0x00, 0x2c, 0xf5, 0xd1, 0x1f, 0x28, 0x01, 0xdd, ++ 0xdf, 0x76, 0x12, 0xe0, 0xa8, 0x42, 0x01, 0xda, 0xdd, 0x76, 0x0e, 0xe0, 0x00, 0x28, 0x0c, 0xd0, ++ 0xd8, 0x76, 0x0a, 0xe0, 0x1f, 0x28, 0x01, 0xdd, 0x9f, 0x76, 0x06, 0xe0, 0xa8, 0x42, 0x01, 0xda, ++ 0x9d, 0x76, 0x02, 0xe0, 0x00, 0x28, 0x00, 0xd0, 0x98, 0x76, 0x01, 0x20, 0xd8, 0x75, 0x00, 0x2c, ++ 0x12, 0xd0, 0x01, 0x2c, 0x16, 0xd0, 0x02, 0x2c, 0x1b, 0xd0, 0x30, 0x0a, 0x88, 0x73, 0x60, 0x31, ++ 0x8e, 0x77, 0x8a, 0x76, 0x00, 0x20, 0xf8, 0xbd, 0x90, 0x00, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, ++ 0x40, 0xa0, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x30, 0x0a, 0xc8, 0x73, 0x60, 0x31, 0xce, 0x77, ++ 0x0a, 0x77, 0xef, 0xe7, 0x30, 0x0a, 0x08, 0x74, 0x80, 0x20, 0x46, 0x54, 0x60, 0x31, 0xca, 0x76, ++ 0xe8, 0xe7, 0x30, 0x0a, 0x48, 0x73, 0x60, 0x31, 0x4e, 0x77, 0x4a, 0x76, 0xe2, 0xe7, 0x30, 0xb5, ++ 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x80, 0x22, 0xd2, 0x43, 0x8a, 0x82, 0xfe, 0x4a, 0xc4, 0x01, ++ 0x15, 0x68, 0xfe, 0x4b, 0xed, 0x18, 0xec, 0x81, 0x8c, 0x8a, 0x40, 0x24, 0xe4, 0x43, 0x8c, 0x82, ++ 0x11, 0x68, 0x80, 0x01, 0xc9, 0x18, 0xc8, 0x81, 0x30, 0xbd, 0x10, 0xb5, 0x03, 0x21, 0x09, 0x07, ++ 0x8a, 0x8a, 0x8a, 0x13, 0x8a, 0x82, 0xc0, 0x05, 0x15, 0x22, 0xc0, 0x0d, 0x52, 0x02, 0x83, 0x18, ++ 0xf1, 0x4a, 0x14, 0x68, 0xf1, 0x48, 0x24, 0x18, 0xe3, 0x82, 0x8b, 0x8a, 0xf0, 0x4b, 0x8b, 0x82, ++ 0x12, 0x68, 0x59, 0x1c, 0x10, 0x18, 0xc1, 0x82, 0x10, 0xbd, 0x10, 0xb5, 0x03, 0x21, 0x09, 0x07, ++ 0x8a, 0x8a, 0x8a, 0x13, 0x8a, 0x82, 0xc0, 0x05, 0x0b, 0x22, 0xc0, 0x0d, 0x92, 0x02, 0x83, 0x18, ++ 0xe5, 0x4a, 0x14, 0x68, 0xe5, 0x48, 0x24, 0x18, 0xe3, 0x82, 0x8b, 0x8a, 0xe4, 0x4b, 0x8b, 0x82, ++ 0x12, 0x68, 0x59, 0x1c, 0x10, 0x18, 0xc1, 0x82, 0x10, 0xbd, 0x10, 0xb5, 0x03, 0x21, 0x09, 0x07, ++ 0x8a, 0x8a, 0x8a, 0x13, 0x8a, 0x82, 0xc0, 0x05, 0x13, 0x22, 0xc0, 0x0d, 0x52, 0x02, 0x83, 0x18, ++ 0xd9, 0x4a, 0x14, 0x68, 0xd9, 0x48, 0x24, 0x18, 0xe3, 0x82, 0x8b, 0x8a, 0xd8, 0x4b, 0x8b, 0x82, ++ 0x12, 0x68, 0x59, 0x1c, 0x10, 0x18, 0xc1, 0x82, 0x10, 0xbd, 0x10, 0xb5, 0x03, 0x21, 0x09, 0x07, ++ 0x8a, 0x8a, 0x8a, 0x13, 0x8a, 0x82, 0xc0, 0x05, 0x05, 0x22, 0xc0, 0x0d, 0xd2, 0x02, 0x83, 0x18, ++ 0xcd, 0x4a, 0x14, 0x68, 0xcd, 0x48, 0x24, 0x18, 0xe3, 0x82, 0x8b, 0x8a, 0xcc, 0x4b, 0x8b, 0x82, ++ 0x12, 0x68, 0x59, 0x1c, 0x10, 0x18, 0xc1, 0x82, 0x10, 0xbd, 0x10, 0xb5, 0x00, 0x24, 0x00, 0x28, ++ 0x06, 0xdd, 0x20, 0x46, 0xff, 0xf7, 0xe1, 0xff, 0x20, 0x46, 0xff, 0xf7, 0xc6, 0xff, 0x10, 0xbd, ++ 0x00, 0x28, 0x20, 0x46, 0x05, 0xda, 0xff, 0xf7, 0xa8, 0xff, 0x20, 0x46, 0xff, 0xf7, 0x8d, 0xff, ++ 0x10, 0xbd, 0xfd, 0xf7, 0x60, 0xff, 0x20, 0x46, 0xfd, 0xf7, 0x45, 0xff, 0x10, 0xbd, 0x10, 0xb5, ++ 0xbc, 0x4b, 0x8a, 0x40, 0x1b, 0x68, 0x02, 0x40, 0x1c, 0x8e, 0x84, 0x43, 0x14, 0x43, 0x1c, 0x86, ++ 0x10, 0xbd, 0x10, 0xb5, 0xb7, 0x4b, 0x8a, 0x40, 0x1b, 0x68, 0x02, 0x40, 0x5c, 0x8e, 0x84, 0x43, ++ 0x14, 0x43, 0x5c, 0x86, 0x10, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0xfd, 0xf7, 0xc7, 0xfd, 0x03, 0x21, ++ 0x09, 0x07, 0x88, 0x8a, 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0xab, 0x48, 0xe2, 0x06, 0x03, 0x68, ++ 0xd2, 0x0e, 0x0d, 0x24, 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, 0xaa, 0x4a, 0x8a, 0x82, ++ 0xaa, 0x4b, 0x04, 0x68, 0xa5, 0x4a, 0xa4, 0x18, 0x23, 0x84, 0x8b, 0x8a, 0xff, 0x23, 0x8b, 0x82, ++ 0x01, 0x21, 0x00, 0x68, 0x89, 0x02, 0x80, 0x18, 0x81, 0x84, 0x10, 0xbd, 0x10, 0xb5, 0x04, 0x46, ++ 0xfd, 0xf7, 0xa4, 0xfd, 0x03, 0x21, 0x09, 0x07, 0x88, 0x8a, 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, ++ 0x99, 0x48, 0xe2, 0x06, 0x03, 0x68, 0xd2, 0x0e, 0x0d, 0x24, 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, ++ 0x8a, 0x8a, 0x99, 0x4a, 0x8a, 0x82, 0x09, 0x23, 0x04, 0x68, 0x1b, 0x03, 0x93, 0x4a, 0xa4, 0x18, ++ 0x23, 0x84, 0x8b, 0x8a, 0xff, 0x23, 0x8b, 0x82, 0x01, 0x21, 0x00, 0x68, 0x89, 0x02, 0x80, 0x18, ++ 0x81, 0x84, 0x10, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0xfd, 0xf7, 0x80, 0xfd, 0x03, 0x21, 0x09, 0x07, ++ 0x88, 0x8a, 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0x87, 0x48, 0xe2, 0x06, 0x03, 0x68, 0xd2, 0x0e, ++ 0x0d, 0x24, 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, 0x87, 0x4a, 0x20, 0x3a, 0x8a, 0x82, ++ 0x86, 0x4b, 0x04, 0x68, 0x14, 0x33, 0x81, 0x4a, 0xa4, 0x18, 0x23, 0x84, 0x8b, 0x8a, 0x00, 0x23, ++ 0x8b, 0x82, 0x83, 0x4b, 0x04, 0x68, 0xa4, 0x18, 0x63, 0x84, 0x8b, 0x8a, 0xff, 0x23, 0x8b, 0x82, ++ 0x01, 0x21, 0x00, 0x68, 0x89, 0x02, 0x80, 0x18, 0x81, 0x84, 0x10, 0xbd, 0x00, 0x28, 0x00, 0xda, ++ 0xc0, 0x43, 0x80, 0xb2, 0x70, 0x47, 0xff, 0xb5, 0x76, 0x4c, 0x07, 0x46, 0x20, 0x68, 0x00, 0x22, ++ 0x09, 0x9e, 0x0a, 0x9d, 0x60, 0x30, 0x94, 0x46, 0x00, 0x29, 0x03, 0xd0, 0x04, 0xda, 0x00, 0x2b, ++ 0x04, 0xdc, 0x14, 0xe0, 0x01, 0x21, 0x19, 0xe0, 0x00, 0x2b, 0x0e, 0xda, 0x08, 0x46, 0xff, 0xf7, ++ 0xe5, 0xff, 0x01, 0x46, 0x18, 0x46, 0xff, 0xf7, 0xe1, 0xff, 0x81, 0x42, 0x00, 0xd3, 0x02, 0x9f, ++ 0x21, 0x68, 0x01, 0x20, 0x60, 0x31, 0x08, 0x73, 0x09, 0xe0, 0x01, 0x21, 0x01, 0xe0, 0x00, 0x21, ++ 0xc9, 0x43, 0x0b, 0x9b, 0x59, 0x43, 0x79, 0x1a, 0x4f, 0xb2, 0x00, 0x21, 0x01, 0x73, 0xaf, 0x42, ++ 0x01, 0xdd, 0x2f, 0x46, 0x02, 0xe0, 0xb7, 0x42, 0x04, 0xda, 0x37, 0x46, 0x21, 0x68, 0x01, 0x22, ++ 0x60, 0x31, 0x0a, 0x73, 0xaf, 0x42, 0x01, 0xd0, 0xb7, 0x42, 0x01, 0xd1, 0x01, 0x20, 0x84, 0x46, ++ 0x20, 0x68, 0x61, 0x46, 0x60, 0x30, 0x82, 0x72, 0xc1, 0x72, 0x38, 0x46, 0x04, 0xb0, 0xf0, 0xbd, ++ 0xf0, 0xb5, 0x04, 0x24, 0xa6, 0x46, 0x01, 0x27, 0x06, 0x9d, 0x00, 0x24, 0x05, 0x9e, 0xbc, 0x46, ++ 0xa8, 0x42, 0x36, 0xdc, 0xaa, 0x42, 0x34, 0xdc, 0xb0, 0x42, 0x32, 0xdb, 0xb2, 0x42, 0x30, 0xdb, ++ 0x07, 0x9f, 0x4d, 0x42, 0x5e, 0x42, 0x87, 0x42, 0x0e, 0xd1, 0x00, 0x29, 0x29, 0xd0, 0x90, 0x42, ++ 0x01, 0xdd, 0x60, 0x1e, 0x84, 0x46, 0x00, 0x29, 0x00, 0xda, 0x29, 0x46, 0x08, 0xb2, 0x00, 0x2b, ++ 0x00, 0xda, 0x33, 0x46, 0x19, 0xb2, 0x10, 0xe0, 0x97, 0x42, 0x1a, 0xd1, 0x00, 0x2b, 0x18, 0xd0, ++ 0x82, 0x42, 0x02, 0xdd, 0x00, 0x20, 0xc0, 0x43, 0x84, 0x46, 0x00, 0x2b, 0x00, 0xda, 0x33, 0x46, ++ 0x18, 0xb2, 0x00, 0x29, 0x00, 0xda, 0x29, 0x46, 0x09, 0xb2, 0x00, 0x22, 0x01, 0x23, 0xdb, 0x03, ++ 0x88, 0x42, 0x08, 0xda, 0x09, 0x1a, 0x64, 0x00, 0xc9, 0x03, 0xc9, 0x18, 0x64, 0xb2, 0x09, 0x14, ++ 0x08, 0xe0, 0x00, 0x20, 0xf0, 0xbd, 0x64, 0x00, 0x64, 0x1c, 0x40, 0x1a, 0xc0, 0x03, 0xc0, 0x18, ++ 0x64, 0xb2, 0x00, 0x14, 0x52, 0x1c, 0xd2, 0xb2, 0x72, 0x45, 0xe9, 0xd9, 0x64, 0x1c, 0x60, 0x10, ++ 0x61, 0x46, 0x49, 0x1c, 0xee, 0xd1, 0x40, 0x42, 0x40, 0xb2, 0xf0, 0xbd, 0xf0, 0xb5, 0x04, 0x46, ++ 0x87, 0xb0, 0x01, 0x20, 0x05, 0x90, 0x2b, 0x48, 0x23, 0x4f, 0x00, 0x2c, 0x08, 0xdd, 0x39, 0x68, ++ 0x09, 0x18, 0x09, 0x89, 0x89, 0x06, 0x8e, 0x16, 0x39, 0x68, 0x08, 0x18, 0xc0, 0x88, 0x11, 0xe0, ++ 0x39, 0x68, 0x00, 0x2c, 0x07, 0xda, 0x09, 0x18, 0x89, 0x89, 0x89, 0x06, 0x8e, 0x16, 0x39, 0x68, ++ 0x08, 0x18, 0x40, 0x89, 0x06, 0xe0, 0x09, 0x18, 0x89, 0x88, 0x89, 0x06, 0x8e, 0x16, 0x39, 0x68, ++ 0x08, 0x18, 0x40, 0x88, 0x80, 0x06, 0x85, 0x16, 0x16, 0x48, 0x00, 0x68, 0x01, 0x46, 0x40, 0x31, ++ 0x8c, 0x46, 0x49, 0x7f, 0x00, 0x29, 0x76, 0xd1, 0x3a, 0x68, 0x10, 0x49, 0x52, 0x18, 0x28, 0x21, ++ 0x51, 0x5e, 0x1f, 0x22, 0x03, 0x91, 0x05, 0x9b, 0x51, 0x42, 0x02, 0x93, 0x01, 0x92, 0x00, 0x91, ++ 0x1e, 0x23, 0xc3, 0x5e, 0x60, 0x46, 0x18, 0x22, 0x82, 0x56, 0x30, 0x46, 0x03, 0x99, 0xff, 0xf7, ++ 0x22, 0xff, 0x04, 0x90, 0x07, 0x48, 0x6c, 0x21, 0x00, 0x68, 0x09, 0x5c, 0x00, 0x29, 0x2f, 0xd0, ++ 0x1f, 0x22, 0x51, 0x42, 0x04, 0x9b, 0x0f, 0xe0, 0x84, 0x00, 0x00, 0x20, 0x40, 0xa0, 0x01, 0x00, ++ 0xff, 0x7f, 0x00, 0x00, 0x90, 0x00, 0x00, 0x20, 0xf3, 0x0f, 0x00, 0x00, 0x0c, 0xa0, 0x00, 0x00, ++ 0x20, 0x20, 0x00, 0x00, 0x80, 0xa2, 0x01, 0x00, 0x02, 0x93, 0x01, 0x92, 0x00, 0x91, 0x1e, 0x23, ++ 0x58, 0x22, 0xc3, 0x5e, 0x82, 0x56, 0x30, 0x46, 0x03, 0x99, 0xff, 0xf7, 0x41, 0xff, 0x01, 0x46, ++ 0xfe, 0x48, 0x5b, 0x22, 0x00, 0x68, 0x00, 0x2c, 0x11, 0x54, 0x02, 0xdd, 0x60, 0x30, 0x41, 0x74, ++ 0x06, 0xe0, 0x00, 0x2c, 0x02, 0xda, 0x60, 0x30, 0xc1, 0x73, 0x01, 0xe0, 0x60, 0x30, 0x41, 0x73, ++ 0xf6, 0x48, 0x00, 0x68, 0x01, 0x46, 0x40, 0x31, 0x0e, 0x76, 0x03, 0x9a, 0xc2, 0x83, 0x60, 0x30, ++ 0x00, 0x7b, 0x48, 0x77, 0x00, 0x2c, 0x03, 0xdd, 0x04, 0x98, 0xff, 0xf7, 0x1e, 0xfe, 0x07, 0xe0, ++ 0x04, 0x98, 0x00, 0x2c, 0x02, 0xda, 0xff, 0xf7, 0xe8, 0xfd, 0x01, 0xe0, 0xfd, 0xf7, 0xa3, 0xfd, ++ 0xea, 0x4e, 0x30, 0x68, 0x60, 0x30, 0x01, 0x7b, 0x00, 0x29, 0x25, 0xd0, 0x00, 0x2c, 0x0b, 0xdd, ++ 0x82, 0x7a, 0x05, 0x21, 0x20, 0x20, 0xff, 0xf7, 0x3a, 0xfe, 0x30, 0x68, 0x05, 0x21, 0x60, 0x30, ++ 0xc2, 0x7a, 0x20, 0x20, 0x16, 0xe0, 0x17, 0xe0, 0x82, 0x7a, 0x00, 0x2c, 0x09, 0xda, 0x01, 0x21, ++ 0x02, 0x20, 0xff, 0xf7, 0x2c, 0xfe, 0x30, 0x68, 0x01, 0x21, 0x60, 0x30, 0xc2, 0x7a, 0x02, 0x20, ++ 0x08, 0xe0, 0x03, 0x21, 0x08, 0x20, 0xff, 0xf7, 0x22, 0xfe, 0x30, 0x68, 0x03, 0x21, 0x60, 0x30, ++ 0xc2, 0x7a, 0x08, 0x20, 0xff, 0xf7, 0x25, 0xfe, 0xd4, 0x4e, 0x31, 0x68, 0x08, 0x46, 0x40, 0x30, ++ 0x82, 0x7f, 0x00, 0x2a, 0x77, 0xd1, 0x3b, 0x68, 0xd1, 0x4a, 0x9b, 0x18, 0x2c, 0x22, 0x9a, 0x5e, ++ 0x1f, 0x23, 0x03, 0x92, 0x5a, 0x42, 0x05, 0x9f, 0x01, 0x93, 0x00, 0x92, 0x02, 0x97, 0x20, 0x23, ++ 0x19, 0x22, 0xcb, 0x5e, 0x82, 0x56, 0x28, 0x46, 0x03, 0x99, 0xff, 0xf7, 0x8c, 0xfe, 0x07, 0x46, ++ 0x30, 0x68, 0x6c, 0x21, 0x09, 0x5c, 0x00, 0x29, 0x1c, 0xd0, 0x1f, 0x21, 0x4a, 0x42, 0x00, 0x92, ++ 0x01, 0x91, 0x02, 0x97, 0x20, 0x23, 0x59, 0x22, 0xc3, 0x5e, 0x82, 0x56, 0x28, 0x46, 0x03, 0x99, ++ 0xff, 0xf7, 0xbe, 0xfe, 0x01, 0x46, 0x5a, 0x22, 0x30, 0x68, 0x00, 0x2c, 0x11, 0x54, 0x02, 0xdd, ++ 0x60, 0x30, 0x81, 0x74, 0x06, 0xe0, 0x00, 0x2c, 0x02, 0xda, 0x60, 0x30, 0x01, 0x74, 0x01, 0xe0, ++ 0x60, 0x30, 0x81, 0x73, 0x30, 0x68, 0x01, 0x46, 0x40, 0x31, 0x4d, 0x76, 0x03, 0x9a, 0x02, 0x84, ++ 0x60, 0x30, 0x00, 0x7b, 0x88, 0x77, 0x00, 0x2c, 0x03, 0xdd, 0x38, 0x46, 0xff, 0xf7, 0x85, 0xfd, ++ 0x07, 0xe0, 0x00, 0x2c, 0x38, 0x46, 0x02, 0xda, 0xff, 0xf7, 0x4f, 0xfd, 0x01, 0xe0, 0xfd, 0xf7, ++ 0x0a, 0xfd, 0x30, 0x68, 0x60, 0x30, 0x01, 0x7b, 0x00, 0x29, 0x24, 0xd0, 0x00, 0x2c, 0x0a, 0xdd, ++ 0x82, 0x7a, 0x04, 0x21, 0x10, 0x20, 0xff, 0xf7, 0xba, 0xfd, 0x30, 0x68, 0x04, 0x21, 0x60, 0x30, ++ 0xc2, 0x7a, 0x10, 0x20, 0x15, 0xe0, 0x82, 0x7a, 0x00, 0x2c, 0x09, 0xda, 0x00, 0x21, 0x01, 0x20, ++ 0xff, 0xf7, 0xad, 0xfd, 0x30, 0x68, 0x00, 0x21, 0x60, 0x30, 0xc2, 0x7a, 0x01, 0x20, 0x08, 0xe0, ++ 0x02, 0x21, 0x04, 0x20, 0xff, 0xf7, 0xa3, 0xfd, 0x30, 0x68, 0x02, 0x21, 0x60, 0x30, 0xc2, 0x7a, ++ 0x04, 0x20, 0xff, 0xf7, 0xa6, 0xfd, 0x30, 0x68, 0x40, 0x30, 0x41, 0x7f, 0x00, 0x29, 0x04, 0xd0, ++ 0x81, 0x7f, 0x00, 0x29, 0x01, 0xd0, 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0xc1, 0x75, 0x07, 0xb0, ++ 0xf0, 0xbd, 0xf0, 0xb5, 0x8d, 0x48, 0x07, 0x27, 0x03, 0x68, 0xff, 0x43, 0x60, 0x33, 0x58, 0x7c, ++ 0x59, 0x7b, 0xfa, 0x10, 0x40, 0x1a, 0x40, 0xb2, 0xb8, 0x42, 0x01, 0xdc, 0x01, 0x21, 0x04, 0xe0, ++ 0x08, 0x28, 0x01, 0xdb, 0x11, 0x46, 0x00, 0xe0, 0x00, 0x21, 0x86, 0x4c, 0x20, 0x68, 0x86, 0x4e, ++ 0x80, 0x19, 0x00, 0x89, 0x1e, 0x25, 0x80, 0x06, 0x80, 0x16, 0x40, 0x18, 0xed, 0x43, 0xa8, 0x42, ++ 0x01, 0xda, 0x28, 0x46, 0x02, 0xe0, 0x1f, 0x28, 0x00, 0xdd, 0x1f, 0x20, 0x99, 0x7c, 0x9b, 0x7b, ++ 0xc9, 0x1a, 0x49, 0xb2, 0xb9, 0x42, 0x01, 0xdc, 0x01, 0x22, 0x02, 0xe0, 0x08, 0x29, 0x00, 0xda, ++ 0x00, 0x22, 0x21, 0x68, 0x89, 0x19, 0xc9, 0x88, 0x89, 0x06, 0x89, 0x16, 0x8c, 0x18, 0xac, 0x42, ++ 0x01, 0xda, 0x2c, 0x46, 0x02, 0xe0, 0x1f, 0x2c, 0x00, 0xdd, 0x1f, 0x24, 0xff, 0xf7, 0x1d, 0xfd, ++ 0x20, 0x46, 0xff, 0xf7, 0x02, 0xfd, 0xf0, 0xbd, 0x6c, 0x48, 0x00, 0x22, 0x00, 0x68, 0xc2, 0x83, ++ 0x01, 0x46, 0x02, 0x84, 0x40, 0x31, 0x4a, 0x75, 0xca, 0x75, 0x0a, 0x76, 0x4a, 0x76, 0x8a, 0x76, ++ 0xca, 0x76, 0x4a, 0x77, 0x8a, 0x77, 0x84, 0x21, 0x09, 0x5c, 0x01, 0x29, 0x01, 0xd0, 0x42, 0x84, ++ 0xc2, 0x84, 0x82, 0x84, 0x02, 0x85, 0x70, 0x47, 0x70, 0xb5, 0x60, 0x4c, 0x20, 0x68, 0x40, 0x30, ++ 0x81, 0x7a, 0x03, 0x29, 0x5a, 0xd0, 0x00, 0x25, 0xed, 0x43, 0x04, 0x29, 0x1f, 0xd0, 0x05, 0x29, ++ 0x37, 0xd0, 0x01, 0x20, 0xff, 0xf7, 0x93, 0xfc, 0x03, 0x21, 0x09, 0x07, 0x88, 0x8a, 0x10, 0x20, ++ 0xc0, 0x43, 0x88, 0x82, 0x57, 0x49, 0x10, 0x20, 0x09, 0x68, 0x55, 0x4a, 0x40, 0x32, 0x89, 0x18, ++ 0x08, 0x80, 0x28, 0x46, 0xff, 0xf7, 0xf9, 0xfc, 0xff, 0xf7, 0xc6, 0xff, 0x09, 0x20, 0xff, 0xf7, ++ 0x22, 0xfd, 0xfd, 0xf7, 0x4c, 0xf9, 0x20, 0x68, 0x04, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfd, 0xf7, ++ 0x8e, 0xf9, 0x00, 0x28, 0x45, 0xd0, 0x28, 0x46, 0xff, 0xf7, 0x28, 0xfe, 0x20, 0x68, 0x40, 0x30, ++ 0xc0, 0x7d, 0x00, 0x28, 0xed, 0xd0, 0x00, 0x20, 0xff, 0xf7, 0xdf, 0xfc, 0xff, 0xf7, 0xac, 0xff, ++ 0x09, 0x20, 0xff, 0xf7, 0x2b, 0xfd, 0xfd, 0xf7, 0x32, 0xf9, 0x20, 0x68, 0x05, 0x21, 0x40, 0x30, ++ 0x81, 0x72, 0xfd, 0xf7, 0x74, 0xf9, 0x00, 0x28, 0x2b, 0xd0, 0x00, 0x20, 0xff, 0xf7, 0x0e, 0xfe, ++ 0x20, 0x68, 0x40, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0xed, 0xd0, 0x00, 0x20, 0xfd, 0xf7, 0x4a, 0xf9, ++ 0x01, 0x20, 0xff, 0xf7, 0xc2, 0xfc, 0xff, 0xf7, 0x8f, 0xff, 0x09, 0x20, 0xfd, 0xf7, 0x31, 0xfd, ++ 0xfd, 0xf7, 0x15, 0xf9, 0x20, 0x68, 0x03, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfd, 0xf7, 0x57, 0xf9, ++ 0x00, 0x28, 0x0e, 0xd0, 0x01, 0x20, 0xff, 0xf7, 0xf1, 0xfd, 0x20, 0x68, 0x40, 0x30, 0xc0, 0x7d, ++ 0x00, 0x28, 0xed, 0xd0, 0xff, 0xf7, 0x35, 0xff, 0x00, 0x20, 0xff, 0xf7, 0x30, 0xfc, 0x00, 0x20, ++ 0x70, 0xbd, 0x02, 0x20, 0x70, 0xbd, 0xf0, 0xb5, 0x26, 0x4a, 0x1e, 0x27, 0xff, 0x43, 0x1f, 0x26, ++ 0x10, 0x68, 0x85, 0xb0, 0x79, 0x11, 0x22, 0x4b, 0xc4, 0x18, 0x30, 0x20, 0x20, 0x5e, 0x1f, 0x28, ++ 0x01, 0xdd, 0x4c, 0x0c, 0x0c, 0xe0, 0x20, 0x24, 0xe0, 0x42, 0x01, 0xda, 0x0c, 0x46, 0x07, 0xe0, ++ 0x12, 0x68, 0x80, 0x02, 0xd2, 0x18, 0x52, 0x8e, 0x92, 0x05, 0x92, 0x0d, 0x10, 0x43, 0x04, 0xb2, ++ 0x16, 0x48, 0x10, 0x23, 0x02, 0x68, 0x10, 0x46, 0x40, 0x30, 0xc3, 0x56, 0x03, 0x93, 0x02, 0x91, ++ 0x00, 0x97, 0x01, 0x96, 0x20, 0x23, 0xd3, 0x5e, 0x18, 0x22, 0x82, 0x56, 0x21, 0x46, 0x03, 0x98, ++ 0xff, 0xf7, 0x19, 0xfd, 0x05, 0x46, 0x0d, 0x48, 0x6c, 0x21, 0x00, 0x68, 0x09, 0x5c, 0x00, 0x29, ++ 0x12, 0xd0, 0x29, 0x01, 0x81, 0x86, 0x00, 0x97, 0x01, 0x96, 0x02, 0x95, 0x20, 0x23, 0x58, 0x22, ++ 0xc3, 0x5e, 0x82, 0x56, 0x21, 0x46, 0x03, 0x98, 0xff, 0xf7, 0x4a, 0xfd, 0x01, 0x46, 0x03, 0x48, ++ 0x00, 0x68, 0x82, 0x8e, 0x89, 0x18, 0x81, 0x86, 0x00, 0x48, 0x07, 0xe0, 0x90, 0x00, 0x00, 0x20, ++ 0x40, 0xa0, 0x01, 0x00, 0x84, 0x00, 0x00, 0x20, 0x80, 0xa2, 0x01, 0x00, 0x00, 0x68, 0x03, 0x9a, ++ 0x01, 0x46, 0x40, 0x31, 0x0a, 0x76, 0x04, 0x84, 0x60, 0x30, 0x00, 0x7b, 0xc8, 0x75, 0x28, 0x46, ++ 0xfd, 0xf7, 0xfc, 0xfa, 0x05, 0xb0, 0xf0, 0xbd, 0xf8, 0xb5, 0xfe, 0x4c, 0x03, 0x25, 0x20, 0x68, ++ 0x2d, 0x07, 0x40, 0x30, 0x80, 0x7a, 0xfc, 0x4e, 0xfc, 0x4f, 0x0c, 0x28, 0x21, 0xd0, 0xff, 0xf7, ++ 0x03, 0xff, 0x20, 0x68, 0x40, 0x30, 0x01, 0x7c, 0x41, 0x76, 0xfd, 0xf7, 0xaa, 0xf8, 0x21, 0x68, ++ 0x40, 0x31, 0x88, 0x76, 0x00, 0x20, 0xfd, 0xf7, 0xe1, 0xfa, 0x00, 0x20, 0xfd, 0xf7, 0xaa, 0xf8, ++ 0xa8, 0x8a, 0xae, 0x82, 0x3a, 0x68, 0x01, 0x21, 0x0d, 0x20, 0x40, 0x03, 0x10, 0x18, 0xc1, 0x80, ++ 0x09, 0x20, 0xff, 0xf7, 0x8f, 0xfc, 0xfd, 0xf7, 0x72, 0xf8, 0x20, 0x68, 0x0c, 0x21, 0x40, 0x30, ++ 0x81, 0x72, 0xfd, 0xf7, 0xb4, 0xf8, 0x00, 0x28, 0x07, 0xd0, 0xff, 0xf7, 0x6c, 0xff, 0x21, 0x68, ++ 0x40, 0x31, 0xc8, 0x7d, 0x00, 0x28, 0x02, 0xd0, 0x04, 0xe0, 0x02, 0x20, 0xf8, 0xbd, 0x48, 0x7d, ++ 0x20, 0x28, 0xe8, 0xd3, 0xa8, 0x8a, 0xae, 0x82, 0x3b, 0x68, 0x00, 0x22, 0x0d, 0x20, 0x40, 0x03, ++ 0x18, 0x18, 0xc2, 0x80, 0x19, 0x20, 0x08, 0x56, 0xfd, 0xf7, 0xb0, 0xfa, 0x21, 0x68, 0x5a, 0x20, ++ 0x08, 0x56, 0xfd, 0xf7, 0x77, 0xf8, 0x00, 0x20, 0xf8, 0xbd, 0x70, 0xb5, 0x0d, 0x46, 0x03, 0x00, ++ 0x03, 0xf0, 0x4e, 0xfb, 0x06, 0x0e, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x08, 0x24, 0x08, 0xe0, ++ 0x10, 0x24, 0x06, 0xe0, 0x20, 0x24, 0x04, 0xe0, 0x40, 0x24, 0x02, 0xe0, 0x80, 0x24, 0x00, 0xe0, ++ 0x00, 0x24, 0xfd, 0xf7, 0xd3, 0xf9, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x1f, 0x21, 0xc9, 0x43, ++ 0x81, 0x82, 0xca, 0x49, 0xea, 0x06, 0x0b, 0x68, 0xd2, 0x0e, 0x0d, 0x25, 0x6d, 0x03, 0x5b, 0x19, ++ 0x5a, 0x85, 0x82, 0x8a, 0xc6, 0x4a, 0x82, 0x82, 0x0d, 0x68, 0x20, 0x23, 0xc5, 0x4a, 0xad, 0x18, ++ 0x2b, 0x84, 0x83, 0x8a, 0x00, 0x23, 0x83, 0x82, 0xc3, 0x4b, 0x0d, 0x68, 0xad, 0x18, 0x6b, 0x84, ++ 0x83, 0x8a, 0xff, 0x23, 0x83, 0x82, 0x09, 0x68, 0x20, 0x02, 0x89, 0x18, 0x88, 0x84, 0x70, 0xbd, ++ 0xf0, 0xb5, 0x03, 0x22, 0xcf, 0x05, 0x12, 0x07, 0xff, 0x0d, 0x96, 0x13, 0xb7, 0x4c, 0xb9, 0x4d, ++ 0x03, 0x00, 0x03, 0xf0, 0x0d, 0xfb, 0x06, 0x44, 0x04, 0x45, 0xb1, 0xb6, 0xbb, 0x44, 0x46, 0x29, ++ 0x01, 0xdd, 0x46, 0x21, 0x01, 0xe0, 0x3f, 0x29, 0x02, 0xdd, 0x08, 0x46, 0x3f, 0x38, 0x00, 0xe0, ++ 0x00, 0x20, 0x93, 0x8a, 0x40, 0xb2, 0x03, 0x23, 0x9b, 0x03, 0x93, 0x82, 0xc3, 0x05, 0x01, 0x26, ++ 0xdb, 0x0d, 0xb6, 0x02, 0x27, 0x68, 0x9e, 0x19, 0x7f, 0x19, 0xfe, 0x82, 0x96, 0x8a, 0xab, 0x4e, ++ 0x96, 0x82, 0x27, 0x68, 0x76, 0x1c, 0x7f, 0x19, 0xfe, 0x82, 0x97, 0x8a, 0x03, 0x27, 0xbf, 0x03, ++ 0x97, 0x82, 0x7f, 0x11, 0xdb, 0x19, 0x27, 0x68, 0x7f, 0x19, 0xfb, 0x82, 0x93, 0x8a, 0x73, 0x1e, ++ 0x93, 0x82, 0x23, 0x68, 0x5b, 0x19, 0xde, 0x82, 0x93, 0x8a, 0x03, 0x23, 0x9b, 0x03, 0x93, 0x82, ++ 0x08, 0x1a, 0xc0, 0x05, 0x21, 0x68, 0xc0, 0x0d, 0xff, 0x30, 0x49, 0x19, 0xff, 0x30, 0x02, 0x30, ++ 0xc8, 0x82, 0x90, 0x8a, 0x70, 0x1e, 0x90, 0x82, 0x20, 0x68, 0x40, 0x19, 0xc6, 0x82, 0xf0, 0xbd, ++ 0x0b, 0x46, 0x1f, 0x33, 0x48, 0x42, 0x3e, 0x2b, 0x06, 0xd9, 0x00, 0x29, 0x01, 0xdb, 0x0b, 0x46, ++ 0x00, 0xe0, 0x03, 0x46, 0x1f, 0x3b, 0x00, 0xe0, 0x00, 0x23, 0x97, 0x8a, 0x5b, 0xb2, 0x03, 0x26, ++ 0xb6, 0x03, 0x96, 0x82, 0xde, 0x05, 0xf6, 0x0d, 0x05, 0x27, 0x7f, 0x02, 0x87, 0x4c, 0xb4, 0x46, ++ 0xf7, 0x19, 0x26, 0x68, 0x76, 0x19, 0xf7, 0x82, 0x97, 0x8a, 0x88, 0x4f, 0x97, 0x82, 0x26, 0x68, ++ 0x7f, 0x1c, 0x76, 0x19, 0xf7, 0x82, 0x97, 0x8a, 0x03, 0x27, 0xbf, 0x03, 0x97, 0x82, 0x66, 0x46, ++ 0x3f, 0x11, 0xf6, 0x19, 0x27, 0x68, 0x7f, 0x19, 0xfe, 0x82, 0x97, 0x8a, 0x7f, 0x4f, 0x97, 0x82, ++ 0x24, 0x68, 0x7f, 0x1c, 0x64, 0x19, 0xe7, 0x82, 0x94, 0x8a, 0x03, 0x24, 0xa4, 0x03, 0x94, 0x82, ++ 0x00, 0x29, 0x00, 0xdb, 0x08, 0x46, 0xc0, 0x1a, 0xc0, 0x05, 0x01, 0x23, 0xc0, 0x0d, 0xdb, 0x02, ++ 0xc3, 0x18, 0x72, 0x48, 0x04, 0x68, 0x64, 0x19, 0xe3, 0x82, 0x93, 0x8a, 0x73, 0x4b, 0x93, 0x82, ++ 0x07, 0x68, 0x5c, 0x1c, 0x7f, 0x19, 0xfc, 0x82, 0x96, 0x8a, 0x03, 0x26, 0xb6, 0x03, 0x96, 0x82, ++ 0x05, 0x26, 0xc9, 0x0f, 0xb6, 0x02, 0x07, 0x68, 0x8e, 0x19, 0x7f, 0x19, 0xfe, 0x82, 0x96, 0x8a, ++ 0x93, 0x82, 0x06, 0x68, 0x76, 0x19, 0xf4, 0x82, 0x96, 0x8a, 0x03, 0x26, 0xb6, 0x03, 0x96, 0x82, ++ 0x0b, 0x26, 0x76, 0x02, 0x89, 0x19, 0x06, 0x68, 0x76, 0x19, 0xf1, 0x82, 0x91, 0x8a, 0x93, 0x82, ++ 0x00, 0x68, 0x40, 0x19, 0xc4, 0x82, 0xf0, 0xbd, 0x90, 0x8a, 0x96, 0x82, 0x07, 0x20, 0x40, 0x02, ++ 0x08, 0xe0, 0x90, 0x8a, 0x96, 0x82, 0x01, 0x20, 0x00, 0x03, 0x03, 0xe0, 0x90, 0x8a, 0x96, 0x82, ++ 0x09, 0x20, 0x40, 0x02, 0x21, 0x68, 0x38, 0x18, 0x49, 0x19, 0xc8, 0x82, 0x90, 0x8a, 0x57, 0x48, ++ 0x90, 0x82, 0x21, 0x68, 0x40, 0x1c, 0x49, 0x19, 0xc8, 0x82, 0xf0, 0xbd, 0x0f, 0xb4, 0xfe, 0xb5, ++ 0x08, 0xaf, 0xbc, 0x7b, 0xfb, 0x7b, 0x3d, 0x7c, 0x7f, 0x7c, 0x26, 0x46, 0x00, 0x2a, 0x01, 0xd1, ++ 0x1c, 0x46, 0x33, 0x46, 0x01, 0x29, 0x02, 0xd0, 0x49, 0x1c, 0x0c, 0xd0, 0x18, 0xe0, 0x07, 0x2c, ++ 0x01, 0xd2, 0x64, 0x1c, 0x0a, 0xe0, 0x00, 0x2b, 0x01, 0xd0, 0x5b, 0x1e, 0xdb, 0xb2, 0xbd, 0x42, ++ 0x0e, 0xd2, 0x6d, 0x1c, 0x0b, 0xe0, 0x00, 0x2c, 0x02, 0xd0, 0x64, 0x1e, 0xe4, 0xb2, 0x07, 0xe0, ++ 0x07, 0x2b, 0x01, 0xd2, 0x5b, 0x1c, 0xdb, 0xb2, 0x00, 0x2d, 0x01, 0xd0, 0x6d, 0x1e, 0xed, 0xb2, ++ 0x69, 0x46, 0x0d, 0x71, 0x00, 0x2a, 0x11, 0xd0, 0x8c, 0x70, 0xcb, 0x70, 0x08, 0xaa, 0x11, 0x7b, ++ 0x6a, 0x46, 0x11, 0x70, 0x08, 0xaa, 0x51, 0x7b, 0x6a, 0x46, 0x51, 0x70, 0x06, 0x22, 0x69, 0x46, ++ 0x03, 0xf0, 0x69, 0xf9, 0xfe, 0xbc, 0x08, 0xbc, 0x04, 0xb0, 0x18, 0x47, 0xcc, 0x70, 0x8b, 0x70, ++ 0xec, 0xe7, 0xfe, 0xb5, 0xd3, 0x1a, 0x2d, 0x4c, 0x2e, 0x4d, 0x5e, 0xb2, 0x01, 0x28, 0x05, 0xd0, ++ 0x02, 0x28, 0x7c, 0xd0, 0x11, 0x46, 0xff, 0xf7, 0xdb, 0xfe, 0xfe, 0xbd, 0x20, 0x68, 0x40, 0x19, ++ 0xc0, 0x8e, 0x6a, 0x46, 0x80, 0x04, 0x40, 0x0f, 0x90, 0x71, 0x20, 0x68, 0x40, 0x19, 0xc0, 0x8e, ++ 0x40, 0x05, 0x40, 0x0f, 0xd0, 0x71, 0x20, 0x68, 0x40, 0x19, 0xc0, 0x8e, 0x80, 0x06, 0x80, 0x0e, ++ 0x10, 0x72, 0x3f, 0x20, 0x50, 0x72, 0x00, 0x29, 0x02, 0xd0, 0x01, 0x29, 0x1d, 0xd1, 0x14, 0xe0, ++ 0x10, 0x89, 0x10, 0x80, 0x01, 0x22, 0x31, 0x46, 0x01, 0xa8, 0x01, 0x9b, 0xff, 0xf7, 0x8e, 0xff, ++ 0x14, 0x48, 0x00, 0x68, 0x80, 0x30, 0x01, 0x7a, 0xc9, 0x06, 0x02, 0xd5, 0x80, 0x7b, 0x80, 0x06, ++ 0x0b, 0xd5, 0x69, 0x46, 0x88, 0x79, 0xc8, 0x71, 0x07, 0xe0, 0x10, 0x89, 0x10, 0x80, 0x00, 0x22, ++ 0x31, 0x46, 0x01, 0xa8, 0x01, 0x9b, 0xff, 0xf7, 0x79, 0xff, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, ++ 0x81, 0x13, 0x81, 0x82, 0x6b, 0x46, 0xda, 0x79, 0x01, 0x23, 0x9b, 0x02, 0xd2, 0x18, 0x23, 0x68, ++ 0x5b, 0x19, 0xda, 0x82, 0x82, 0x8a, 0x09, 0x4a, 0x82, 0x82, 0x23, 0x68, 0x56, 0x1c, 0x5b, 0x19, ++ 0xde, 0x82, 0x0d, 0xe0, 0x90, 0x00, 0x00, 0x20, 0xfe, 0xff, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, ++ 0xd3, 0x8b, 0x00, 0x00, 0x40, 0xa0, 0x01, 0x00, 0x20, 0x20, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, ++ 0x83, 0x8a, 0x81, 0x82, 0x6b, 0x46, 0x9b, 0x79, 0xc7, 0x14, 0xdb, 0x19, 0x27, 0x68, 0x7f, 0x19, ++ 0xfb, 0x82, 0x83, 0x8a, 0x82, 0x82, 0x23, 0x68, 0x5b, 0x19, 0xde, 0x82, 0x83, 0x8a, 0x81, 0x82, ++ 0x6b, 0x46, 0x19, 0x7a, 0x23, 0x68, 0xff, 0x31, 0x5b, 0x19, 0xff, 0x31, 0x02, 0x31, 0xd9, 0x82, ++ 0x81, 0x8a, 0x82, 0x82, 0x20, 0x68, 0x40, 0x19, 0xc6, 0x82, 0xfe, 0xbd, 0xff, 0xe7, 0x22, 0x68, ++ 0xfe, 0x48, 0x12, 0x18, 0x12, 0x8f, 0x6d, 0x46, 0x52, 0x06, 0xd2, 0x0f, 0x2a, 0x71, 0x22, 0x68, ++ 0x12, 0x18, 0x12, 0x8f, 0x92, 0x06, 0xd2, 0x0f, 0x6a, 0x71, 0x22, 0x68, 0x12, 0x18, 0x12, 0x8f, ++ 0x92, 0x04, 0x53, 0x0f, 0xab, 0x71, 0x22, 0x68, 0x12, 0x18, 0x12, 0x8f, 0x52, 0x05, 0x52, 0x0f, ++ 0xea, 0x71, 0x25, 0x68, 0x28, 0x18, 0x00, 0x8f, 0x6d, 0x46, 0xc0, 0x06, 0xc0, 0x0e, 0x28, 0x72, ++ 0x1f, 0x27, 0x6f, 0x72, 0x00, 0x25, 0x00, 0x29, 0x02, 0xd0, 0x01, 0x29, 0x44, 0xd1, 0x28, 0xe0, ++ 0xc3, 0x42, 0x04, 0xd1, 0x70, 0x1c, 0x02, 0xd1, 0x01, 0x20, 0x69, 0x46, 0x08, 0x71, 0x6a, 0x46, ++ 0x10, 0x79, 0x40, 0x00, 0x40, 0x42, 0x40, 0x1c, 0x70, 0x43, 0x41, 0xb2, 0x10, 0x89, 0x10, 0x80, ++ 0x01, 0x22, 0x01, 0xa8, 0x01, 0x9b, 0xff, 0xf7, 0xf9, 0xfe, 0x6a, 0x46, 0x91, 0x79, 0x10, 0x7a, ++ 0xc1, 0x42, 0x00, 0xd1, 0x15, 0x71, 0xde, 0x48, 0x00, 0x68, 0x80, 0x30, 0x02, 0x7a, 0xd2, 0x06, ++ 0x02, 0xd5, 0x80, 0x7b, 0x40, 0x06, 0x1f, 0xd5, 0x6a, 0x46, 0xd1, 0x71, 0x10, 0x79, 0x50, 0x71, ++ 0x1a, 0xe0, 0xc2, 0x42, 0x04, 0xd1, 0x70, 0x1c, 0x02, 0xd1, 0x01, 0x20, 0x69, 0x46, 0x48, 0x71, ++ 0x6a, 0x46, 0x50, 0x79, 0x40, 0x00, 0x40, 0x42, 0x40, 0x1c, 0x70, 0x43, 0x41, 0xb2, 0x10, 0x89, ++ 0x10, 0x80, 0x00, 0x22, 0x01, 0xa8, 0x01, 0x9b, 0xff, 0xf7, 0xd0, 0xfe, 0x6a, 0x46, 0xd0, 0x79, ++ 0x11, 0x7a, 0xc8, 0x42, 0x00, 0xd1, 0x55, 0x71, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x82, 0x13, ++ 0x82, 0x82, 0x6e, 0x46, 0xf1, 0x79, 0x05, 0x23, 0x5b, 0x02, 0x25, 0x68, 0xcb, 0x18, 0xc3, 0x49, ++ 0x6d, 0x18, 0xeb, 0x82, 0x83, 0x8a, 0xc3, 0x4b, 0x83, 0x82, 0x26, 0x68, 0x5d, 0x1c, 0x76, 0x18, ++ 0xf5, 0x82, 0x86, 0x8a, 0x82, 0x82, 0x6e, 0x46, 0xb6, 0x79, 0x87, 0x14, 0xf6, 0x19, 0x27, 0x68, ++ 0x7f, 0x18, 0xfe, 0x82, 0x86, 0x8a, 0x83, 0x82, 0x26, 0x68, 0x76, 0x18, 0xf5, 0x82, 0x86, 0x8a, ++ 0x82, 0x82, 0x6e, 0x46, 0x36, 0x7a, 0x2f, 0x11, 0xf6, 0x19, 0x27, 0x68, 0x7f, 0x18, 0xfe, 0x82, ++ 0x86, 0x8a, 0x83, 0x82, 0x26, 0x68, 0x76, 0x18, 0xf5, 0x82, 0x86, 0x8a, 0x82, 0x82, 0x6e, 0x46, ++ 0x36, 0x79, 0x05, 0x27, 0xbf, 0x02, 0xf6, 0x19, 0x27, 0x68, 0x7f, 0x18, 0xfe, 0x82, 0x86, 0x8a, ++ 0x83, 0x82, 0x26, 0x68, 0x76, 0x18, 0xf5, 0x82, 0x86, 0x8a, 0x82, 0x82, 0x6e, 0x46, 0x72, 0x79, ++ 0x0b, 0x26, 0x76, 0x02, 0x92, 0x19, 0x26, 0x68, 0x76, 0x18, 0xf2, 0x82, 0x82, 0x8a, 0x83, 0x82, ++ 0x20, 0x68, 0x40, 0x18, 0xc5, 0x82, 0x40, 0xe7, 0xa3, 0x48, 0x00, 0x68, 0x9f, 0x49, 0x40, 0x18, ++ 0x80, 0x8e, 0x80, 0x06, 0x80, 0x0e, 0x70, 0x47, 0xf3, 0xb5, 0x9d, 0x48, 0x87, 0xb0, 0x00, 0x68, ++ 0x05, 0x90, 0x40, 0x30, 0x04, 0x90, 0xc0, 0x7c, 0x98, 0x4e, 0x01, 0x28, 0x1a, 0xd0, 0x05, 0x98, ++ 0x80, 0x30, 0x01, 0x7a, 0xc9, 0x06, 0x1b, 0xd5, 0x07, 0x99, 0x01, 0x29, 0x02, 0xd0, 0x02, 0x29, ++ 0x03, 0xd0, 0x15, 0xe0, 0x80, 0x7b, 0x80, 0x06, 0x01, 0xe0, 0x80, 0x7b, 0x40, 0x06, 0x00, 0x28, ++ 0x0e, 0xdb, 0x08, 0x98, 0x00, 0x28, 0x05, 0xd0, 0x8f, 0x48, 0x00, 0x68, 0x81, 0x19, 0x2c, 0x20, ++ 0x08, 0x5e, 0x0a, 0xe0, 0x8c, 0x48, 0x00, 0x68, 0x81, 0x19, 0x28, 0x20, 0x08, 0x5e, 0x04, 0xe0, ++ 0x89, 0x48, 0x00, 0x68, 0x81, 0x19, 0x30, 0x20, 0x08, 0x5e, 0x07, 0x99, 0x0e, 0x22, 0xd2, 0x43, ++ 0x0b, 0x00, 0x03, 0xf0, 0x7d, 0xf8, 0x06, 0x6c, 0x04, 0x1b, 0x52, 0x5c, 0x63, 0x6c, 0x08, 0x99, ++ 0x81, 0x4a, 0x00, 0x29, 0x11, 0x68, 0x0d, 0xd0, 0x89, 0x19, 0xc9, 0x8e, 0x09, 0x0a, 0x49, 0x07, ++ 0x12, 0x68, 0x49, 0x0f, 0x92, 0x19, 0xd2, 0x8e, 0x00, 0x24, 0x92, 0x06, 0x92, 0x0e, 0x8f, 0x18, ++ 0x46, 0x25, 0x55, 0xe0, 0x89, 0x19, 0xc9, 0x8e, 0xc9, 0x0a, 0xf0, 0xe7, 0x08, 0x99, 0x00, 0x29, ++ 0x75, 0x49, 0x0a, 0x68, 0x13, 0xd0, 0x92, 0x19, 0x12, 0x8f, 0x52, 0x09, 0xd2, 0x07, 0xd2, 0x0f, ++ 0x0a, 0x68, 0x1b, 0xd0, 0x92, 0x19, 0x12, 0x8f, 0x12, 0x0a, 0x52, 0x07, 0x09, 0x68, 0x52, 0x0f, ++ 0x89, 0x19, 0x09, 0x8f, 0xc9, 0x06, 0xc9, 0x0e, 0x51, 0x18, 0x4f, 0x42, 0x19, 0xe0, 0x92, 0x19, ++ 0x12, 0x8f, 0x92, 0x09, 0xd2, 0x07, 0xd2, 0x0f, 0x0a, 0x68, 0x03, 0xd0, 0x92, 0x19, 0x12, 0x8f, ++ 0xd2, 0x0a, 0xea, 0xe7, 0x92, 0x19, 0x12, 0x8f, 0xd2, 0x0a, 0x02, 0xe0, 0x92, 0x19, 0x12, 0x8f, ++ 0x12, 0x0a, 0x52, 0x07, 0x09, 0x68, 0x52, 0x0f, 0x89, 0x19, 0x09, 0x8f, 0xc9, 0x06, 0xc9, 0x0e, ++ 0x57, 0x18, 0x25, 0x24, 0xe4, 0x43, 0x26, 0x25, 0x1a, 0xe0, 0x5b, 0x49, 0x09, 0x68, 0x89, 0x19, ++ 0x49, 0x8f, 0x1e, 0x24, 0x89, 0x06, 0x8f, 0x16, 0xe4, 0x43, 0x1f, 0x25, 0x10, 0xe0, 0x56, 0x49, ++ 0x09, 0x68, 0x89, 0x19, 0x49, 0x8f, 0x49, 0x05, 0xcf, 0x16, 0x05, 0xe0, 0x52, 0x49, 0x09, 0x68, ++ 0x8b, 0x19, 0x3a, 0x21, 0x59, 0x5e, 0xcf, 0x12, 0x14, 0x46, 0x0f, 0x25, 0x00, 0xe0, 0x00, 0x27, ++ 0x04, 0x99, 0x00, 0x2f, 0x4f, 0x76, 0x02, 0xd0, 0x03, 0xdb, 0x01, 0x21, 0x03, 0xe0, 0x00, 0x21, ++ 0x01, 0xe0, 0x00, 0x21, 0xc9, 0x43, 0x40, 0x1a, 0x00, 0xb2, 0x03, 0x90, 0x04, 0x98, 0x40, 0x7d, ++ 0x00, 0x28, 0x15, 0xd0, 0x00, 0x20, 0xc0, 0x43, 0x00, 0x94, 0x02, 0x90, 0x05, 0x98, 0x01, 0x95, ++ 0x20, 0x23, 0xc3, 0x5e, 0x04, 0x98, 0x18, 0x22, 0x82, 0x56, 0x38, 0x46, 0x03, 0x99, 0xff, 0xf7, ++ 0x32, 0xf9, 0x07, 0x46, 0x3a, 0x48, 0x6c, 0x21, 0x00, 0x68, 0x09, 0x5c, 0x40, 0x30, 0xc1, 0x75, ++ 0x07, 0x98, 0x01, 0x28, 0x0b, 0xd1, 0xa7, 0x42, 0x04, 0xd1, 0x03, 0x99, 0x48, 0x1c, 0x01, 0xda, ++ 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0x32, 0x48, 0x00, 0x68, 0x80, 0x30, 0x41, 0x71, 0x30, 0x48, ++ 0x00, 0x68, 0x40, 0x30, 0x81, 0x7d, 0x01, 0x29, 0x02, 0xd0, 0x00, 0x7d, 0x03, 0x28, 0x06, 0xd1, ++ 0x07, 0x98, 0x01, 0x28, 0x04, 0xd0, 0x02, 0x28, 0x05, 0xd0, 0x03, 0x28, 0x03, 0xd0, 0x96, 0xe0, ++ 0xaf, 0x42, 0x04, 0xd0, 0x93, 0xe0, 0xaf, 0x42, 0x01, 0xd0, 0xa7, 0x42, 0x7e, 0xd1, 0x03, 0x20, ++ 0x00, 0x07, 0x81, 0x8a, 0x01, 0x21, 0xc9, 0x43, 0x81, 0x82, 0x23, 0x4c, 0x01, 0x20, 0x21, 0x68, ++ 0x0d, 0x22, 0x52, 0x03, 0x89, 0x18, 0x48, 0x86, 0x01, 0x46, 0x1c, 0x20, 0x02, 0xf0, 0xda, 0xfe, ++ 0x08, 0x98, 0x00, 0x28, 0x20, 0x68, 0x1e, 0xd0, 0x80, 0x19, 0xc0, 0x8e, 0x21, 0x68, 0x40, 0x05, ++ 0x40, 0x0f, 0x89, 0x19, 0xc9, 0x8e, 0x89, 0x06, 0x89, 0x0e, 0x41, 0x18, 0x20, 0x68, 0x80, 0x19, ++ 0x00, 0x8f, 0x40, 0x09, 0xc0, 0x07, 0xc0, 0x0f, 0x20, 0x68, 0x2f, 0xd0, 0x80, 0x19, 0x00, 0x8f, ++ 0x00, 0x0a, 0x40, 0x07, 0x22, 0x68, 0x40, 0x0f, 0x92, 0x19, 0x12, 0x8f, 0xd2, 0x06, 0xd2, 0x0e, ++ 0x80, 0x18, 0x40, 0x42, 0x2d, 0xe0, 0x80, 0x19, 0xc0, 0x8e, 0x21, 0x68, 0x80, 0x04, 0x40, 0x0f, ++ 0x89, 0x19, 0xc9, 0x8e, 0x89, 0x06, 0x89, 0x0e, 0x41, 0x18, 0x20, 0x68, 0x80, 0x19, 0x00, 0x8f, ++ 0x80, 0x09, 0xc0, 0x07, 0xc0, 0x0f, 0x20, 0x68, 0x0c, 0xd0, 0x07, 0xe0, 0x40, 0xa0, 0x01, 0x00, ++ 0x90, 0x00, 0x00, 0x20, 0xff, 0x7f, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, 0x80, 0x19, 0x00, 0x8f, ++ 0xc0, 0x0a, 0xd6, 0xe7, 0x80, 0x19, 0x00, 0x8f, 0xc0, 0x0a, 0x02, 0xe0, 0x80, 0x19, 0x00, 0x8f, ++ 0x00, 0x0a, 0x40, 0x07, 0x22, 0x68, 0x40, 0x0f, 0x92, 0x19, 0x12, 0x8f, 0xd2, 0x06, 0xd2, 0x0e, ++ 0x80, 0x18, 0x00, 0x06, 0x00, 0x0c, 0x01, 0x43, 0x20, 0x68, 0x80, 0x19, 0x40, 0x8f, 0x03, 0x25, ++ 0x80, 0x06, 0x80, 0x16, 0x00, 0x06, 0x00, 0x0a, 0x01, 0x43, 0x01, 0x91, 0x00, 0x23, 0x2a, 0x46, ++ 0x00, 0x95, 0x12, 0x21, 0x01, 0x20, 0x02, 0xf0, 0xff, 0xfd, 0xff, 0xf7, 0x8d, 0xfe, 0x21, 0x68, ++ 0x00, 0x02, 0xfe, 0x4a, 0x89, 0x18, 0x49, 0x88, 0x09, 0x07, 0x00, 0xe0, 0x0f, 0xe0, 0x09, 0x0f, ++ 0x08, 0x43, 0xfb, 0x49, 0x00, 0x23, 0x09, 0x68, 0x03, 0x22, 0x40, 0x31, 0xc9, 0x7b, 0x00, 0x95, ++ 0x09, 0x04, 0x08, 0x43, 0x01, 0x90, 0x13, 0x21, 0x01, 0x20, 0x02, 0xf0, 0xe5, 0xfd, 0xf4, 0x4c, ++ 0x20, 0x68, 0x40, 0x30, 0xc1, 0x7c, 0x01, 0x29, 0x11, 0xd0, 0x19, 0x23, 0xc3, 0x56, 0x3a, 0x46, ++ 0x08, 0x99, 0x07, 0x98, 0xff, 0xf7, 0x25, 0xfd, 0x20, 0x68, 0x03, 0x99, 0x01, 0x84, 0x40, 0x30, ++ 0x41, 0x7e, 0x01, 0x76, 0x41, 0x7d, 0x49, 0x1c, 0x41, 0x75, 0x09, 0xb0, 0xf0, 0xbd, 0x39, 0x46, ++ 0x07, 0x98, 0xff, 0xf7, 0xfd, 0xfb, 0xef, 0xe7, 0x10, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, ++ 0x8a, 0x13, 0x8a, 0x82, 0xc0, 0x05, 0x17, 0x22, 0xc0, 0x0d, 0x52, 0x02, 0x83, 0x18, 0xe1, 0x4a, ++ 0x14, 0x68, 0xde, 0x48, 0x40, 0x38, 0x24, 0x18, 0xe3, 0x82, 0x8b, 0x8a, 0xde, 0x4b, 0x8b, 0x82, ++ 0x12, 0x68, 0x59, 0x1c, 0x10, 0x18, 0xc1, 0x82, 0x10, 0xbd, 0xfe, 0xb5, 0xd8, 0x48, 0xd7, 0x4f, ++ 0x01, 0x68, 0x3e, 0x23, 0x08, 0x46, 0x40, 0x30, 0xc4, 0x7c, 0xdb, 0x43, 0x3f, 0x22, 0x01, 0x25, ++ 0x40, 0x3f, 0xd4, 0x4e, 0x00, 0x2c, 0x01, 0xd0, 0x01, 0x2c, 0x21, 0xd0, 0x34, 0x68, 0xe7, 0x19, ++ 0x30, 0x24, 0x3c, 0x5f, 0x36, 0x68, 0xd1, 0x4f, 0xf6, 0x19, 0xf6, 0x89, 0x02, 0x95, 0x00, 0x93, ++ 0x01, 0x92, 0x76, 0x06, 0x20, 0x23, 0x18, 0x22, 0x77, 0x16, 0xcb, 0x5e, 0x82, 0x56, 0xc8, 0x4d, ++ 0x21, 0x46, 0x38, 0x46, 0xff, 0xf7, 0x17, 0xf8, 0x06, 0x46, 0x28, 0x68, 0x01, 0x46, 0x40, 0x31, ++ 0x0f, 0x76, 0x04, 0x84, 0x60, 0x30, 0x02, 0x7b, 0xca, 0x75, 0x01, 0x2a, 0x05, 0xd0, 0x10, 0xe0, ++ 0x34, 0x68, 0xe7, 0x19, 0x2c, 0x24, 0x3c, 0x5f, 0xdc, 0xe7, 0x82, 0x7a, 0x06, 0x21, 0x40, 0x20, ++ 0xfe, 0xf7, 0x75, 0xff, 0x28, 0x68, 0x06, 0x21, 0x60, 0x30, 0xc2, 0x7a, 0x40, 0x20, 0xfe, 0xf7, ++ 0x78, 0xff, 0x30, 0x46, 0xff, 0xf7, 0xa0, 0xff, 0x3e, 0x36, 0x28, 0x68, 0x7c, 0x2e, 0x04, 0xd9, ++ 0x40, 0x30, 0xc1, 0x79, 0x02, 0x22, 0x11, 0x43, 0x03, 0xe0, 0x40, 0x30, 0xc1, 0x79, 0xfd, 0x22, ++ 0x11, 0x40, 0xc1, 0x71, 0x29, 0xe5, 0x10, 0xb5, 0xad, 0x4c, 0x4a, 0x21, 0x20, 0x68, 0x09, 0x5c, ++ 0x0a, 0x29, 0x16, 0xd0, 0x80, 0x30, 0x40, 0x7b, 0x80, 0x07, 0x1d, 0xd4, 0x00, 0x20, 0xff, 0xf7, ++ 0x83, 0xff, 0x20, 0x68, 0x40, 0x30, 0xc0, 0x7c, 0x01, 0x28, 0x15, 0xd8, 0xff, 0xf7, 0xfc, 0xf9, ++ 0x10, 0x20, 0xfe, 0xf7, 0x58, 0xff, 0xfc, 0xf7, 0x82, 0xfb, 0x20, 0x68, 0x0a, 0x21, 0x40, 0x30, ++ 0x81, 0x72, 0xfc, 0xf7, 0xc4, 0xfb, 0x00, 0x28, 0x08, 0xd0, 0xff, 0xf7, 0x86, 0xff, 0x20, 0x68, ++ 0x40, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0xee, 0xd0, 0x00, 0x20, 0x10, 0xbd, 0x02, 0x20, 0x10, 0xbd, ++ 0x10, 0xb5, 0x97, 0x4c, 0x20, 0x68, 0x01, 0x46, 0x40, 0x30, 0x82, 0x7a, 0x0e, 0x2a, 0x11, 0xd0, ++ 0x80, 0x31, 0x49, 0x7b, 0x89, 0x07, 0x18, 0xd4, 0xc0, 0x7c, 0x01, 0x28, 0x15, 0xd8, 0xff, 0xf7, ++ 0xd3, 0xf9, 0x10, 0x20, 0xfe, 0xf7, 0x2f, 0xff, 0xfc, 0xf7, 0x59, 0xfb, 0x20, 0x68, 0x0e, 0x21, ++ 0x40, 0x30, 0x81, 0x72, 0xfc, 0xf7, 0x9b, 0xfb, 0x00, 0x28, 0x0c, 0xd0, 0xff, 0xf7, 0x5d, 0xff, ++ 0x20, 0x68, 0x40, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0xee, 0xd0, 0x20, 0x68, 0x2f, 0x21, 0x40, 0x30, ++ 0x81, 0x72, 0x00, 0x20, 0x10, 0xbd, 0x02, 0x20, 0x10, 0xbd, 0x10, 0xb5, 0x1f, 0x28, 0x01, 0xd9, ++ 0x1f, 0x20, 0x03, 0xe0, 0x41, 0xb2, 0x00, 0x29, 0x00, 0xda, 0x00, 0x20, 0xfe, 0xf7, 0x1c, 0xfc, ++ 0x10, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0xfc, 0xf7, 0xd1, 0xfc, 0x03, 0x21, 0x09, 0x07, 0x88, 0x8a, ++ 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0x77, 0x48, 0xe2, 0x06, 0x03, 0x68, 0xd2, 0x0e, 0x0d, 0x24, ++ 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, 0x75, 0x4a, 0x8a, 0x82, 0x75, 0x4b, 0x04, 0x68, ++ 0x6e, 0x4a, 0x40, 0x3a, 0xa4, 0x18, 0x23, 0x84, 0x8b, 0x8a, 0x00, 0x23, 0x8b, 0x82, 0x72, 0x4b, ++ 0x04, 0x68, 0xa4, 0x18, 0x63, 0x84, 0x8b, 0x8a, 0xff, 0x23, 0x8b, 0x82, 0x01, 0x21, 0x00, 0x68, ++ 0x89, 0x02, 0x80, 0x18, 0x81, 0x84, 0x10, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0xfc, 0xf7, 0xa6, 0xfc, ++ 0x03, 0x21, 0x09, 0x07, 0x88, 0x8a, 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0x61, 0x48, 0xe2, 0x06, ++ 0x03, 0x68, 0xd2, 0x0e, 0x0d, 0x24, 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, 0x63, 0x4a, ++ 0x8a, 0x82, 0x09, 0x23, 0x04, 0x68, 0x9b, 0x02, 0x58, 0x4a, 0x40, 0x3a, 0xa4, 0x18, 0x23, 0x84, ++ 0x8b, 0x8a, 0x00, 0x23, 0x8b, 0x82, 0x5c, 0x4b, 0x04, 0x68, 0x40, 0x33, 0xa4, 0x18, 0x63, 0x84, ++ 0x8b, 0x8a, 0xff, 0x23, 0x8b, 0x82, 0x07, 0x21, 0x00, 0x68, 0xc9, 0x02, 0x80, 0x18, 0x81, 0x84, ++ 0x10, 0xbd, 0x70, 0xb5, 0x04, 0x46, 0xfc, 0xf7, 0x79, 0xfc, 0x03, 0x21, 0x09, 0x07, 0x88, 0x8a, ++ 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0x4b, 0x48, 0xe3, 0x06, 0x04, 0x68, 0xdb, 0x0e, 0x0d, 0x22, ++ 0x52, 0x03, 0xa4, 0x18, 0x63, 0x85, 0x8b, 0x8a, 0x47, 0x4b, 0x8b, 0x82, 0x04, 0x68, 0x5b, 0x1c, ++ 0x42, 0x4d, 0x40, 0x3d, 0x64, 0x19, 0x23, 0x84, 0x8b, 0x8a, 0x80, 0x23, 0xdb, 0x43, 0x8b, 0x82, ++ 0x00, 0x68, 0x80, 0x21, 0x80, 0x18, 0x01, 0x84, 0x70, 0xbd, 0x10, 0xb5, 0x3d, 0x4a, 0x10, 0x68, ++ 0x3a, 0x4b, 0x40, 0x3b, 0xc0, 0x18, 0x00, 0x8f, 0x11, 0x68, 0x80, 0x04, 0x40, 0x0f, 0xc9, 0x18, ++ 0x09, 0x8f, 0xc9, 0x06, 0xc9, 0x0e, 0x41, 0x18, 0x10, 0x68, 0xc0, 0x18, 0x00, 0x8f, 0x80, 0x09, ++ 0xc0, 0x07, 0xc0, 0x0f, 0x00, 0xd0, 0x49, 0x42, 0x10, 0x68, 0xc0, 0x18, 0x00, 0x8f, 0x14, 0x68, ++ 0x40, 0x05, 0x40, 0x0f, 0xe4, 0x18, 0x24, 0x8f, 0x12, 0x68, 0xe4, 0x06, 0xe4, 0x0e, 0x00, 0x19, ++ 0xd2, 0x18, 0x12, 0x8f, 0x52, 0x09, 0xd2, 0x07, 0xd2, 0x0f, 0x00, 0xd0, 0x40, 0x42, 0x08, 0x18, ++ 0x40, 0x10, 0x11, 0x38, 0x10, 0xbd, 0xf0, 0xb5, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x2c, 0x49, ++ 0x81, 0x82, 0x24, 0x4a, 0x81, 0x13, 0x14, 0x68, 0x20, 0x4b, 0x40, 0x3b, 0xe4, 0x18, 0x21, 0x80, ++ 0x81, 0x8a, 0x28, 0x4e, 0x86, 0x82, 0x1e, 0x49, 0x09, 0x68, 0x80, 0x31, 0x0c, 0x7a, 0xe4, 0x06, ++ 0x02, 0xd5, 0x8c, 0x7b, 0xa4, 0x06, 0x01, 0xd5, 0x01, 0x24, 0x00, 0xe0, 0x00, 0x24, 0x01, 0x25, ++ 0x64, 0x00, 0xad, 0x02, 0x17, 0x68, 0x64, 0x19, 0xff, 0x18, 0x7c, 0x80, 0x84, 0x8a, 0x86, 0x82, ++ 0x0c, 0x7a, 0xe4, 0x06, 0x02, 0xd5, 0x89, 0x7b, 0x49, 0x06, 0x01, 0xd5, 0x01, 0x21, 0x00, 0xe0, ++ 0x00, 0x21, 0x49, 0x00, 0x14, 0x68, 0x49, 0x19, 0xe4, 0x18, 0xa1, 0x80, 0x81, 0x8a, 0x15, 0x49, ++ 0x89, 0x1c, 0x81, 0x82, 0x14, 0x68, 0xe4, 0x18, 0xe5, 0x80, 0x84, 0x8a, 0x81, 0x82, 0x14, 0x68, ++ 0xe4, 0x18, 0x25, 0x81, 0x84, 0x8a, 0x81, 0x82, 0x11, 0x68, 0xc9, 0x18, 0x4d, 0x81, 0x81, 0x8a, ++ 0x0d, 0x49, 0x81, 0x82, 0x08, 0x48, 0x11, 0x68, 0xc9, 0x18, 0x17, 0xe0, 0x80, 0xa0, 0x01, 0x00, ++ 0x90, 0x00, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, 0xff, 0x7f, 0x00, 0x00, 0x80, 0xa2, 0x01, 0x00, ++ 0xf3, 0x8f, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0xf3, 0x8b, 0x00, 0x00, ++ 0xff, 0x3f, 0x00, 0x00, 0xfd, 0x93, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x88, 0x81, 0xf0, 0xbd, ++ 0x70, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0xfb, 0x4a, 0x8a, 0x82, 0x82, 0x02, 0xfb, 0x48, ++ 0x04, 0x68, 0x0d, 0x23, 0x5b, 0x03, 0xe4, 0x18, 0x22, 0x85, 0x8a, 0x8a, 0xf8, 0x4a, 0x8a, 0x82, ++ 0x06, 0x68, 0x00, 0x25, 0xf7, 0x4c, 0x36, 0x19, 0x75, 0x80, 0xf7, 0x4d, 0x2d, 0x68, 0x80, 0x35, ++ 0xad, 0x7b, 0xed, 0x07, 0x0d, 0xd1, 0x8d, 0x8a, 0x8a, 0x82, 0x05, 0x68, 0x52, 0x1c, 0x2c, 0x19, ++ 0x62, 0x80, 0x8a, 0x8a, 0x40, 0x22, 0xd2, 0x43, 0x8a, 0x82, 0x00, 0x68, 0x40, 0x21, 0xc0, 0x18, ++ 0x01, 0x84, 0x70, 0xbd, 0xf0, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0xe6, 0x4a, 0x8a, 0x82, ++ 0x82, 0x02, 0xe6, 0x48, 0x03, 0x68, 0x0d, 0x27, 0x7f, 0x03, 0xdb, 0x19, 0x1a, 0x85, 0x8a, 0x8a, ++ 0xe3, 0x4a, 0x8a, 0x82, 0x05, 0x68, 0x00, 0x24, 0xe2, 0x4b, 0xed, 0x18, 0x6c, 0x80, 0x8d, 0x8a, ++ 0x8a, 0x82, 0x05, 0x68, 0xed, 0x18, 0xac, 0x80, 0x8d, 0x8a, 0x8a, 0x82, 0x05, 0x68, 0xed, 0x18, ++ 0xec, 0x80, 0x8d, 0x8a, 0x8a, 0x82, 0x05, 0x68, 0xed, 0x18, 0x2c, 0x81, 0x8d, 0x8a, 0x8a, 0x82, ++ 0x05, 0x68, 0xed, 0x18, 0x6c, 0x81, 0xd8, 0x4c, 0x24, 0x68, 0x80, 0x34, 0xa5, 0x7b, 0xee, 0x07, ++ 0xd6, 0x4d, 0x04, 0xd1, 0x8e, 0x8a, 0x8a, 0x82, 0x06, 0x68, 0xf6, 0x18, 0x75, 0x80, 0xa6, 0x7b, ++ 0xb6, 0x07, 0x04, 0xd4, 0x8e, 0x8a, 0x8a, 0x82, 0x06, 0x68, 0xf6, 0x18, 0xb5, 0x80, 0xa4, 0x7b, ++ 0x64, 0x07, 0x04, 0xd4, 0x8c, 0x8a, 0x8a, 0x82, 0x02, 0x68, 0xd2, 0x18, 0xd5, 0x80, 0x8a, 0x8a, ++ 0x40, 0x22, 0xd2, 0x43, 0x8a, 0x82, 0x00, 0x68, 0x40, 0x21, 0xc0, 0x19, 0x01, 0x84, 0xf0, 0xbd, ++ 0xfe, 0xb5, 0xc5, 0x4e, 0xc1, 0x4a, 0x30, 0x68, 0xc2, 0x49, 0x04, 0x46, 0x40, 0x30, 0xc3, 0x7c, ++ 0x12, 0x68, 0x01, 0x2b, 0x28, 0xd0, 0x51, 0x18, 0x09, 0x8e, 0x25, 0x46, 0xe1, 0x83, 0x60, 0x35, ++ 0x29, 0x78, 0xa1, 0x84, 0x61, 0x8c, 0x01, 0x22, 0x1f, 0x23, 0x49, 0xb2, 0x01, 0x93, 0x02, 0x92, ++ 0x00, 0x91, 0x18, 0x22, 0x82, 0x56, 0x20, 0x23, 0x1e, 0x21, 0x00, 0x20, 0xe3, 0x5e, 0x61, 0x5e, ++ 0x28, 0x56, 0xfe, 0xf7, 0xd8, 0xfd, 0x31, 0x68, 0xc0, 0xb2, 0x0a, 0x46, 0x60, 0x32, 0x10, 0x70, ++ 0x13, 0x46, 0x20, 0x3a, 0x8d, 0x8c, 0x14, 0x46, 0x15, 0x76, 0x1a, 0x7b, 0xe2, 0x75, 0xca, 0x8b, ++ 0x0a, 0x84, 0xff, 0xf7, 0x3a, 0xfe, 0xdd, 0xe5, 0x51, 0x18, 0x09, 0x8d, 0xd5, 0xe7, 0xfe, 0xb5, ++ 0xa9, 0x4e, 0xa6, 0x4a, 0x31, 0x68, 0xa7, 0x4b, 0x0c, 0x46, 0x40, 0x31, 0xcd, 0x7c, 0x12, 0x68, ++ 0x01, 0x2d, 0x2d, 0xd0, 0xd2, 0x18, 0x12, 0x8e, 0x1f, 0x23, 0x10, 0x18, 0xe0, 0x83, 0x61, 0x22, ++ 0x10, 0x57, 0x20, 0x85, 0x00, 0x22, 0xd2, 0x43, 0x00, 0x25, 0x01, 0x93, 0x02, 0x92, 0x00, 0x95, ++ 0x18, 0x22, 0x8a, 0x56, 0x20, 0x23, 0x1e, 0x21, 0xe3, 0x5e, 0x61, 0x5e, 0xfe, 0xf7, 0xa3, 0xfd, ++ 0x31, 0x68, 0x0a, 0x46, 0x60, 0x32, 0x50, 0x70, 0x13, 0x46, 0x20, 0x3a, 0x0c, 0x8d, 0x17, 0x46, ++ 0x14, 0x76, 0x1a, 0x7b, 0xfa, 0x75, 0xca, 0x8b, 0x0a, 0x84, 0xfc, 0xf7, 0x73, 0xf9, 0x30, 0x68, ++ 0x6a, 0x21, 0x09, 0x5c, 0x00, 0x29, 0x06, 0xd0, 0x01, 0x21, 0x80, 0x30, 0x41, 0x72, 0xa1, 0xe5, ++ 0xd2, 0x18, 0x12, 0x8d, 0xd0, 0xe7, 0x80, 0x30, 0x45, 0x72, 0x9b, 0xe5, 0xfe, 0xb5, 0x87, 0x48, ++ 0x01, 0x68, 0x88, 0x48, 0x40, 0x30, 0x08, 0x18, 0x40, 0x88, 0x87, 0x4c, 0x02, 0x07, 0x20, 0x68, ++ 0x12, 0x0f, 0x07, 0x46, 0x60, 0x37, 0xba, 0x70, 0x82, 0x84, 0x2a, 0x21, 0x41, 0x5e, 0x01, 0x25, ++ 0x0b, 0x1d, 0x08, 0x2b, 0x03, 0xd8, 0x56, 0x23, 0x1b, 0x5c, 0x01, 0x2b, 0x22, 0xd0, 0x00, 0x22, ++ 0xd2, 0x43, 0x0f, 0x23, 0x00, 0x26, 0x01, 0x93, 0x02, 0x92, 0x00, 0x96, 0x2c, 0x23, 0xc3, 0x5e, ++ 0x04, 0x22, 0x02, 0x20, 0xba, 0x56, 0x38, 0x56, 0xfe, 0xf7, 0x5d, 0xfd, 0x22, 0x68, 0xc1, 0xb2, ++ 0x10, 0x46, 0x60, 0x30, 0x81, 0x70, 0x92, 0x8c, 0xd2, 0xb2, 0x02, 0x71, 0x03, 0x7b, 0x01, 0x2b, ++ 0x01, 0xd0, 0x86, 0x71, 0x08, 0xe0, 0x91, 0x42, 0x01, 0xd1, 0x85, 0x71, 0x04, 0xe0, 0x02, 0x21, ++ 0x81, 0x71, 0x01, 0xe0, 0x3a, 0x71, 0xbd, 0x71, 0x20, 0x68, 0x41, 0x8d, 0x81, 0x85, 0x56, 0x21, ++ 0x09, 0x5c, 0x01, 0x29, 0x06, 0xd1, 0x01, 0x46, 0x60, 0x31, 0x8a, 0x79, 0x01, 0x2a, 0x01, 0xd0, ++ 0x02, 0x22, 0x8a, 0x71, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x0f, 0x22, 0xd2, 0x43, 0x8a, 0x82, ++ 0x60, 0x30, 0x81, 0x78, 0x5d, 0x48, 0x02, 0x68, 0x5e, 0x48, 0x40, 0x30, 0x10, 0x18, 0x41, 0x80, ++ 0x40, 0xe5, 0xf8, 0xb5, 0x5c, 0x4c, 0x01, 0x25, 0x20, 0x68, 0x01, 0x46, 0x40, 0x31, 0xcb, 0x7c, ++ 0x02, 0x46, 0x60, 0x32, 0x00, 0x2b, 0x04, 0xd0, 0x01, 0x2b, 0x06, 0xd1, 0x03, 0x78, 0x5b, 0x07, ++ 0x03, 0xd5, 0x8d, 0x23, 0x1b, 0x5c, 0x5b, 0x07, 0x01, 0xd5, 0x15, 0x72, 0x66, 0xe0, 0x00, 0x78, ++ 0x42, 0x07, 0x05, 0x20, 0x00, 0x2a, 0x48, 0x77, 0x03, 0xda, 0xfe, 0xf7, 0x7f, 0xf9, 0x21, 0x68, ++ 0x48, 0x84, 0xfe, 0xf7, 0x83, 0xf9, 0x4c, 0x4a, 0x11, 0x68, 0xc8, 0x84, 0xff, 0xf7, 0x04, 0xfb, ++ 0x12, 0x68, 0x04, 0x46, 0x11, 0x46, 0x60, 0x31, 0x08, 0x70, 0x10, 0x78, 0x40, 0x07, 0x40, 0xd5, ++ 0x13, 0x46, 0x80, 0x33, 0x58, 0x79, 0x00, 0x28, 0x05, 0xd0, 0x00, 0x20, 0x08, 0x56, 0x00, 0x28, ++ 0x01, 0xda, 0x60, 0x1c, 0x1a, 0xe0, 0x26, 0x20, 0x56, 0x8c, 0x10, 0x5e, 0xb4, 0x46, 0x40, 0x4f, ++ 0x86, 0x19, 0x38, 0x8c, 0xb6, 0x46, 0x86, 0x42, 0x08, 0xda, 0x58, 0x7a, 0x00, 0x28, 0x05, 0xd1, ++ 0xff, 0x26, 0x76, 0x36, 0xb4, 0x45, 0x01, 0xd2, 0x1f, 0x2c, 0xea, 0xd3, 0x7e, 0x8c, 0xb6, 0x45, ++ 0x23, 0xdc, 0x58, 0x7a, 0x00, 0x28, 0x20, 0xd1, 0x01, 0xe0, 0x60, 0x1e, 0x08, 0x70, 0x32, 0x4e, ++ 0x08, 0x78, 0xff, 0xf7, 0x42, 0xfd, 0x30, 0x68, 0x02, 0x46, 0x60, 0x30, 0x01, 0x78, 0xa1, 0x42, ++ 0x1b, 0xd0, 0x03, 0x7a, 0x01, 0x2b, 0x18, 0xd0, 0x02, 0x25, 0xa1, 0x42, 0x1a, 0xd9, 0x04, 0x2b, ++ 0x16, 0xd0, 0x40, 0x32, 0x92, 0x7d, 0x01, 0x2a, 0x12, 0xd0, 0x03, 0x22, 0x02, 0x72, 0x08, 0x1b, ++ 0x1a, 0xe0, 0x89, 0x20, 0x80, 0x5c, 0x00, 0x28, 0x04, 0xd0, 0x40, 0x32, 0x52, 0x7f, 0x94, 0x42, ++ 0xdb, 0xd8, 0xdc, 0xe7, 0x1f, 0x2c, 0xbc, 0xd3, 0xd9, 0xe7, 0x05, 0x72, 0x00, 0x20, 0xf8, 0xbd, ++ 0x05, 0x72, 0xec, 0xe7, 0x03, 0x2b, 0x09, 0xd0, 0x40, 0x32, 0x92, 0x7d, 0x01, 0x2a, 0x05, 0xd0, ++ 0x04, 0x22, 0x02, 0x72, 0x60, 0x1a, 0x40, 0x42, 0x40, 0xb2, 0xf8, 0xbd, 0x05, 0x72, 0xf9, 0xe7, ++ 0x10, 0xb5, 0x04, 0x46, 0xfc, 0xf7, 0xea, 0xf9, 0x03, 0x21, 0x09, 0x07, 0x88, 0x8a, 0x1f, 0x20, ++ 0xc0, 0x43, 0x88, 0x82, 0x0d, 0x48, 0xe2, 0x06, 0x03, 0x68, 0xd2, 0x0e, 0x0d, 0x24, 0x64, 0x03, ++ 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, 0x0f, 0x4a, 0x8a, 0x82, 0x09, 0x23, 0x04, 0x68, 0x9b, 0x02, ++ 0x08, 0x4a, 0xa4, 0x18, 0x23, 0x84, 0x8b, 0x8a, 0x00, 0x23, 0x8b, 0x82, 0x0a, 0x49, 0x00, 0x68, ++ 0x80, 0x18, 0x41, 0x84, 0x10, 0xbd, 0x00, 0x00, 0xff, 0x83, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, ++ 0xff, 0x7f, 0x00, 0x00, 0x40, 0xa0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, ++ 0x00, 0x04, 0x00, 0x20, 0xff, 0x8b, 0x00, 0x00, 0x60, 0x20, 0x00, 0x00, 0xf0, 0xb5, 0x03, 0x21, ++ 0x09, 0x07, 0xff, 0x25, 0x01, 0x26, 0xf7, 0x4a, 0xf7, 0x4b, 0xf8, 0x4c, 0x8f, 0x8a, 0x0d, 0x28, ++ 0x8d, 0x82, 0x09, 0xd8, 0x80, 0x1f, 0x86, 0x40, 0x15, 0x68, 0x30, 0x02, 0xed, 0x18, 0xa8, 0x84, ++ 0x88, 0x8a, 0x8c, 0x82, 0x04, 0x20, 0x08, 0xe0, 0x0e, 0x38, 0x86, 0x40, 0x15, 0x68, 0x30, 0x02, ++ 0xed, 0x18, 0xa8, 0x84, 0x88, 0x8a, 0x8c, 0x82, 0x08, 0x20, 0x11, 0x68, 0xc9, 0x18, 0x08, 0x84, ++ 0xf0, 0xbd, 0xfe, 0xb5, 0xe7, 0x4d, 0x28, 0x68, 0xe7, 0x4e, 0x40, 0x36, 0x80, 0x19, 0x80, 0x88, ++ 0xe7, 0x4f, 0x41, 0x07, 0x3c, 0x68, 0x49, 0x0f, 0x20, 0x46, 0x60, 0x30, 0xc1, 0x70, 0xa1, 0x84, ++ 0x00, 0x23, 0xdb, 0x43, 0x07, 0x22, 0x00, 0x21, 0x02, 0x93, 0x01, 0x92, 0x00, 0x91, 0x2e, 0x23, ++ 0x26, 0x21, 0xe3, 0x5e, 0x05, 0x22, 0x61, 0x5e, 0x82, 0x56, 0x04, 0x46, 0x03, 0x20, 0x20, 0x56, ++ 0xfe, 0xf7, 0x21, 0xfc, 0x3a, 0x68, 0x11, 0x46, 0x60, 0x31, 0xc8, 0x70, 0x90, 0x8c, 0x48, 0x71, ++ 0x08, 0x7b, 0xc8, 0x71, 0xd0, 0x8c, 0xd0, 0x85, 0x03, 0x20, 0x00, 0x07, 0x82, 0x8a, 0x07, 0x22, ++ 0xd2, 0x43, 0x82, 0x82, 0xc8, 0x78, 0x29, 0x68, 0x89, 0x19, 0x88, 0x80, 0x22, 0xe4, 0x70, 0xb5, ++ 0xcf, 0x4c, 0xff, 0x25, 0x20, 0x68, 0x01, 0x46, 0x40, 0x31, 0x8a, 0x7a, 0x17, 0x2a, 0x17, 0xd0, ++ 0x18, 0x2a, 0x22, 0xd0, 0xc9, 0x7c, 0x00, 0x29, 0x23, 0xd1, 0x01, 0x78, 0x49, 0x07, 0x20, 0xd5, ++ 0x60, 0x30, 0x40, 0x7a, 0x00, 0x28, 0x0f, 0xd1, 0x09, 0x20, 0xff, 0xf7, 0x81, 0xfd, 0x20, 0x68, ++ 0x01, 0x22, 0x69, 0x21, 0x0a, 0x54, 0x17, 0x22, 0x4a, 0x21, 0x0a, 0x54, 0x80, 0x30, 0x85, 0x72, ++ 0xfb, 0xf7, 0xe5, 0xff, 0x00, 0x28, 0x12, 0xd0, 0x09, 0x20, 0xff, 0xf7, 0x9b, 0xfd, 0x20, 0x68, ++ 0x18, 0x22, 0x4a, 0x21, 0x0a, 0x54, 0x80, 0x30, 0x85, 0x72, 0xfb, 0xf7, 0xd8, 0xff, 0x00, 0x28, ++ 0x05, 0xd0, 0x20, 0x68, 0x19, 0x21, 0x40, 0x30, 0x81, 0x72, 0x00, 0x20, 0x70, 0xbd, 0x02, 0x20, ++ 0x70, 0xbd, 0x00, 0xb5, 0xb2, 0x49, 0x03, 0x00, 0x09, 0x68, 0x80, 0x31, 0x02, 0xf0, 0x88, 0xfa, ++ 0x06, 0x14, 0x04, 0x07, 0x0a, 0x0d, 0x10, 0x14, 0x88, 0x7b, 0xc0, 0x07, 0x0a, 0xe0, 0x88, 0x7b, ++ 0x80, 0x07, 0x07, 0xe0, 0x88, 0x7b, 0x40, 0x07, 0x04, 0xe0, 0x88, 0x7b, 0x00, 0x07, 0x01, 0xe0, ++ 0x88, 0x7b, 0xc0, 0x06, 0xc0, 0x17, 0x40, 0x1c, 0x00, 0xbd, 0xf8, 0xb5, 0xa4, 0x4c, 0x01, 0x26, ++ 0x20, 0x68, 0x00, 0x25, 0x40, 0x30, 0x80, 0x7a, 0x20, 0x28, 0x28, 0xd0, 0x21, 0x28, 0x76, 0xd0, ++ 0xfe, 0xf7, 0xd2, 0xfd, 0x20, 0x68, 0x01, 0x46, 0x40, 0x30, 0xc2, 0x7c, 0x00, 0x2a, 0x02, 0xd0, ++ 0x01, 0x2a, 0x4f, 0xd0, 0x82, 0xe0, 0x09, 0x78, 0x49, 0x07, 0x7f, 0xd5, 0x86, 0x76, 0xc5, 0x76, ++ 0x20, 0x68, 0x40, 0x30, 0x80, 0x7e, 0xff, 0xf7, 0xc4, 0xff, 0x00, 0x28, 0x1e, 0xd0, 0x20, 0x68, ++ 0x06, 0x21, 0x40, 0x30, 0x80, 0x7e, 0xfe, 0xf7, 0xf8, 0xfe, 0x20, 0x68, 0x40, 0x30, 0xc5, 0x75, ++ 0x45, 0x75, 0xfb, 0xf7, 0x3c, 0xff, 0x20, 0x68, 0x20, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfb, 0xf7, ++ 0x7e, 0xff, 0x00, 0x28, 0x67, 0xd0, 0x20, 0x68, 0x40, 0x30, 0xc1, 0x7e, 0x80, 0x7e, 0xff, 0xf7, ++ 0x83, 0xf9, 0x20, 0x68, 0x40, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0xea, 0xd0, 0x20, 0x68, 0x02, 0x46, ++ 0x80, 0x32, 0x11, 0x7a, 0xc9, 0x06, 0x10, 0xd5, 0x01, 0x46, 0x40, 0x31, 0x1a, 0x23, 0xcb, 0x56, ++ 0x01, 0x2b, 0x02, 0xd1, 0x97, 0x7b, 0xbf, 0x06, 0x04, 0xd5, 0x02, 0x2b, 0x05, 0xd1, 0x92, 0x7b, ++ 0x52, 0x06, 0x02, 0xd4, 0xca, 0x7e, 0x00, 0x2a, 0x0a, 0xd0, 0x01, 0x46, 0x40, 0x31, 0xcd, 0x76, ++ 0x8a, 0x7e, 0x52, 0x1c, 0x8a, 0x76, 0x5a, 0x21, 0x41, 0x56, 0x06, 0x29, 0xb8, 0xdb, 0x35, 0xe0, ++ 0xce, 0x76, 0xf8, 0xe7, 0x09, 0x78, 0x49, 0x07, 0x30, 0xd5, 0x02, 0x21, 0x81, 0x76, 0xc5, 0x76, ++ 0x20, 0x68, 0x40, 0x30, 0x80, 0x7e, 0xff, 0xf7, 0x74, 0xff, 0x00, 0x28, 0x1e, 0xd0, 0x20, 0x68, ++ 0x06, 0x21, 0x40, 0x30, 0x80, 0x7e, 0xfe, 0xf7, 0xa8, 0xfe, 0x20, 0x68, 0x40, 0x30, 0xc5, 0x75, ++ 0x45, 0x75, 0xfb, 0xf7, 0xec, 0xfe, 0x20, 0x68, 0x21, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfb, 0xf7, ++ 0x2e, 0xff, 0x00, 0x28, 0x17, 0xd0, 0x20, 0x68, 0x40, 0x30, 0xc1, 0x7e, 0x80, 0x7e, 0xff, 0xf7, ++ 0x33, 0xf9, 0x20, 0x68, 0x40, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0xea, 0xd0, 0x20, 0x68, 0x40, 0x30, ++ 0x81, 0x7e, 0x89, 0x1c, 0x49, 0xb2, 0x81, 0x76, 0x05, 0x29, 0xd1, 0xdb, 0x20, 0x68, 0x40, 0x30, ++ 0x85, 0x72, 0x00, 0x20, 0xf8, 0xbd, 0x02, 0x20, 0xf8, 0xbd, 0xf8, 0xb5, 0x54, 0x4d, 0x00, 0x24, ++ 0x28, 0x68, 0x02, 0x46, 0x40, 0x30, 0x81, 0x7a, 0x10, 0x29, 0x4d, 0xd0, 0xc1, 0x7c, 0x28, 0x46, ++ 0x00, 0x68, 0x80, 0x30, 0x00, 0x29, 0x02, 0xd0, 0x01, 0x29, 0x77, 0xd0, 0x79, 0xe0, 0x40, 0x7b, ++ 0xc0, 0x07, 0x76, 0xd1, 0xfe, 0xf7, 0x28, 0xfd, 0x28, 0x68, 0x00, 0x78, 0x40, 0x07, 0x06, 0xd4, ++ 0x0c, 0x20, 0xff, 0xf7, 0xa1, 0xfb, 0x28, 0x68, 0x00, 0x78, 0x40, 0x07, 0x2e, 0xd5, 0x28, 0x68, ++ 0x01, 0x46, 0x40, 0x31, 0x8a, 0x7d, 0x01, 0x2a, 0x0d, 0xd0, 0x85, 0x21, 0x09, 0x5c, 0x00, 0x29, ++ 0x02, 0xd0, 0x00, 0x21, 0xc9, 0x43, 0x36, 0xe0, 0xfd, 0xf7, 0xd2, 0xfe, 0x29, 0x68, 0x48, 0x85, ++ 0xff, 0xf7, 0x5c, 0xfd, 0x47, 0xe0, 0xc9, 0x7f, 0x00, 0x29, 0x00, 0xd1, 0x44, 0x85, 0x85, 0x21, ++ 0x09, 0x5c, 0x00, 0x29, 0x03, 0xd0, 0x41, 0x8d, 0x49, 0x1e, 0x41, 0x85, 0x05, 0xe0, 0xfd, 0xf7, ++ 0xbf, 0xfe, 0x29, 0x68, 0x4a, 0x8d, 0x80, 0x18, 0x48, 0x85, 0x28, 0x68, 0x40, 0x30, 0xc1, 0x7f, ++ 0x49, 0x1c, 0xc9, 0xb2, 0xc1, 0x77, 0x08, 0x29, 0x28, 0xd0, 0x2c, 0xe0, 0xfb, 0xf7, 0x77, 0xfe, ++ 0x28, 0x68, 0x10, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfb, 0xf7, 0xb9, 0xfe, 0x00, 0x28, 0x0c, 0xd0, ++ 0x28, 0x68, 0x24, 0x4b, 0x01, 0x46, 0x40, 0x31, 0x8a, 0x7d, 0x23, 0x4e, 0x01, 0x2a, 0x06, 0xd0, ++ 0x19, 0x68, 0x89, 0x19, 0x09, 0x8e, 0x41, 0x85, 0xca, 0xe7, 0x02, 0x20, 0xf8, 0xbd, 0xca, 0x7f, ++ 0x00, 0x2a, 0x00, 0xd1, 0x44, 0x85, 0x47, 0x8d, 0x1b, 0x68, 0x9b, 0x19, 0x1b, 0x8e, 0x52, 0x1c, ++ 0xfb, 0x18, 0x43, 0x85, 0xd0, 0xb2, 0xc8, 0x77, 0x08, 0x28, 0x04, 0xd1, 0xff, 0xf7, 0x16, 0xfd, ++ 0x28, 0x68, 0x40, 0x30, 0xc4, 0x77, 0x28, 0x68, 0x01, 0x78, 0x49, 0x07, 0x0c, 0xd4, 0x60, 0x30, ++ 0x80, 0x79, 0x00, 0x28, 0x97, 0xd0, 0x07, 0xe0, 0x00, 0xe0, 0x02, 0xe0, 0x40, 0x7b, 0xc0, 0x07, ++ 0x08, 0xd0, 0x01, 0x20, 0x60, 0x32, 0x90, 0x71, 0x28, 0x68, 0x33, 0x21, 0x40, 0x30, 0x81, 0x72, ++ 0x00, 0x20, 0xf8, 0xbd, 0xfe, 0xf7, 0xa8, 0xfc, 0x28, 0x68, 0x01, 0x46, 0x40, 0x30, 0x82, 0x7d, ++ 0x01, 0x2a, 0x0f, 0xd0, 0xff, 0xf7, 0x71, 0xfb, 0x29, 0x68, 0x48, 0x85, 0xff, 0xf7, 0xee, 0xfc, ++ 0x1e, 0xe0, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, 0x40, 0xa0, 0x01, 0x00, 0xf3, 0xff, 0x00, 0x00, ++ 0x90, 0x00, 0x00, 0x20, 0xc0, 0x7f, 0x00, 0x28, 0x00, 0xd1, 0x4c, 0x85, 0xff, 0xf7, 0x5d, 0xfb, ++ 0x29, 0x68, 0x4a, 0x8d, 0x80, 0x18, 0x48, 0x85, 0x40, 0x31, 0xc8, 0x7f, 0x40, 0x1c, 0xc0, 0xb2, ++ 0xc8, 0x77, 0x08, 0x28, 0x04, 0xd1, 0xff, 0xf7, 0xd1, 0xfc, 0x28, 0x68, 0x40, 0x30, 0xc4, 0x77, ++ 0x28, 0x68, 0x01, 0x78, 0x49, 0x07, 0xc7, 0xd4, 0x60, 0x30, 0x80, 0x79, 0x00, 0x28, 0xcb, 0xd0, ++ 0xc2, 0xe7, 0x10, 0xb5, 0xfb, 0x4c, 0x20, 0x68, 0x01, 0x46, 0x40, 0x31, 0xca, 0x7c, 0x00, 0x2a, ++ 0x06, 0xd0, 0x01, 0x2a, 0x02, 0xd1, 0x02, 0x78, 0x52, 0x07, 0x01, 0xd4, 0x00, 0x20, 0xc1, 0xe5, ++ 0x89, 0x7a, 0x0f, 0x29, 0x22, 0xd0, 0x80, 0x30, 0x40, 0x7b, 0x80, 0x06, 0x2a, 0xd4, 0xfe, 0xf7, ++ 0x5b, 0xfc, 0x00, 0x20, 0xfc, 0xf7, 0x42, 0xf8, 0x09, 0x20, 0xff, 0xf7, 0xaa, 0xfa, 0x03, 0x20, ++ 0x00, 0x07, 0x81, 0x8a, 0x20, 0x21, 0xc9, 0x43, 0x81, 0x82, 0xeb, 0x49, 0x20, 0x20, 0x09, 0x68, ++ 0xea, 0x4a, 0x89, 0x18, 0x08, 0x84, 0xfb, 0xf7, 0xf4, 0xfd, 0x21, 0x68, 0x60, 0x31, 0x48, 0x70, ++ 0xfb, 0xf7, 0xcd, 0xfd, 0x20, 0x68, 0x0f, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfb, 0xf7, 0x0f, 0xfe, ++ 0x00, 0x28, 0x0c, 0xd0, 0x3c, 0x20, 0xff, 0xf7, 0x4a, 0xfc, 0x20, 0x68, 0x40, 0x30, 0xc0, 0x7d, ++ 0x00, 0x28, 0xed, 0xd0, 0x20, 0x68, 0x32, 0x21, 0x40, 0x30, 0x81, 0x72, 0xc6, 0xe7, 0x02, 0x20, ++ 0x88, 0xe5, 0x10, 0xb5, 0xd7, 0x4c, 0x20, 0x68, 0x01, 0x46, 0x40, 0x31, 0x8a, 0x7a, 0x11, 0x2a, ++ 0x21, 0xd0, 0xc9, 0x7c, 0x00, 0x29, 0x45, 0xd1, 0x88, 0x21, 0x09, 0x5c, 0xc9, 0x09, 0x41, 0xd1, ++ 0x01, 0x78, 0x89, 0x06, 0x89, 0x0f, 0x02, 0x29, 0x3c, 0xd0, 0xfe, 0xf7, 0x15, 0xfc, 0x0c, 0x20, ++ 0xff, 0xf7, 0x4e, 0xfd, 0x20, 0x68, 0x00, 0x21, 0xc1, 0x84, 0x06, 0x21, 0x40, 0x30, 0x41, 0x75, ++ 0x20, 0x68, 0x40, 0x30, 0x40, 0x7d, 0xff, 0xf7, 0x79, 0xfd, 0xfb, 0xf7, 0x90, 0xfd, 0x20, 0x68, ++ 0x11, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfb, 0xf7, 0xd2, 0xfd, 0x00, 0x28, 0x11, 0xd0, 0xc2, 0x49, ++ 0x08, 0x68, 0xc2, 0x4a, 0x80, 0x18, 0x00, 0x8e, 0x00, 0x28, 0x10, 0xd0, 0x20, 0x68, 0x26, 0x23, ++ 0xc3, 0x5e, 0x09, 0x68, 0x8a, 0x18, 0x30, 0x21, 0x51, 0x5e, 0x00, 0x29, 0x03, 0xdd, 0x01, 0x21, ++ 0x03, 0xe0, 0x02, 0x20, 0x46, 0xe5, 0x00, 0x21, 0xc9, 0x43, 0x59, 0x18, 0xc1, 0x84, 0x20, 0x68, ++ 0x40, 0x30, 0x41, 0x7d, 0x49, 0x1c, 0xc9, 0xb2, 0x41, 0x75, 0x16, 0x29, 0xd0, 0xd3, 0xff, 0xf7, ++ 0x70, 0xfd, 0x02, 0xe0, 0x01, 0x21, 0x60, 0x30, 0xc1, 0x71, 0x20, 0x68, 0x31, 0x21, 0x40, 0x30, ++ 0x81, 0x72, 0x00, 0x20, 0x2e, 0xe5, 0xf8, 0xb5, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0xac, 0x49, ++ 0x81, 0x82, 0xa9, 0x4e, 0x01, 0x20, 0x31, 0x68, 0x40, 0x02, 0x0d, 0x27, 0x7f, 0x03, 0xc9, 0x19, ++ 0x48, 0x80, 0x30, 0x68, 0xc0, 0x19, 0x80, 0x8f, 0x01, 0xf0, 0xff, 0xfc, 0x05, 0x46, 0x01, 0xe0, ++ 0x00, 0x2c, 0x08, 0xd0, 0x30, 0x68, 0xc0, 0x19, 0x80, 0x8f, 0x80, 0x09, 0xc0, 0x07, 0xc0, 0x0f, ++ 0x01, 0xd0, 0x01, 0x24, 0x00, 0xe0, 0x00, 0x24, 0x00, 0x2c, 0x05, 0xd0, 0x01, 0xf0, 0xed, 0xfc, ++ 0x40, 0x1b, 0x80, 0xb2, 0x0b, 0x28, 0xeb, 0xd3, 0x30, 0x68, 0xc1, 0x19, 0x0a, 0x20, 0x08, 0x5e, ++ 0x00, 0x2c, 0x03, 0xd0, 0x00, 0x28, 0x01, 0xda, 0x00, 0x24, 0xe4, 0x43, 0x20, 0x46, 0xf8, 0xbd, ++ 0x10, 0xb5, 0x90, 0x48, 0x00, 0x68, 0x80, 0x30, 0x00, 0x7a, 0x80, 0x07, 0x01, 0xd5, 0x00, 0x20, ++ 0xf0, 0xe4, 0xff, 0xf7, 0xc0, 0xff, 0x00, 0x28, 0xfa, 0xd0, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, ++ 0x01, 0x21, 0xc9, 0x43, 0x81, 0x82, 0x88, 0x49, 0x01, 0x20, 0x09, 0x68, 0x0d, 0x22, 0x52, 0x03, ++ 0x89, 0x18, 0x48, 0x86, 0x01, 0x46, 0x17, 0x20, 0x01, 0xf0, 0x3c, 0xff, 0x01, 0x20, 0xd9, 0xe4, ++ 0xf0, 0xb5, 0x80, 0x4c, 0x00, 0x21, 0x20, 0x68, 0x03, 0x25, 0x02, 0x78, 0x2d, 0x07, 0x52, 0x07, ++ 0x7d, 0x4e, 0x0f, 0x46, 0x00, 0x2a, 0x2c, 0xda, 0x58, 0x22, 0x82, 0x56, 0x20, 0x46, 0x00, 0x68, ++ 0xd3, 0x1d, 0x60, 0x30, 0x0e, 0x2b, 0x01, 0xd8, 0x87, 0x70, 0x13, 0xe0, 0x13, 0x46, 0x0f, 0x33, ++ 0x1e, 0x2b, 0x02, 0xd8, 0x10, 0x21, 0x04, 0x22, 0x0b, 0xe0, 0x13, 0x46, 0x17, 0x33, 0x2e, 0x2b, ++ 0x02, 0xd8, 0x20, 0x21, 0x08, 0x22, 0x04, 0xe0, 0x1f, 0x32, 0x3e, 0x2a, 0x02, 0xd8, 0x30, 0x21, ++ 0x0c, 0x22, 0x82, 0x70, 0x01, 0x20, 0xfe, 0xf7, 0xcb, 0xfc, 0xa8, 0x8a, 0x0f, 0x20, 0xc0, 0x43, ++ 0xa8, 0x82, 0x20, 0x68, 0x31, 0x68, 0x60, 0x30, 0x80, 0x78, 0x68, 0x4a, 0x40, 0x32, 0x89, 0x18, ++ 0x48, 0x80, 0x20, 0x68, 0x58, 0x21, 0x41, 0x56, 0x00, 0x29, 0x01, 0xda, 0x65, 0x48, 0x01, 0xe0, ++ 0x03, 0x20, 0x80, 0x03, 0xa9, 0x8a, 0x01, 0x21, 0xa9, 0x82, 0x32, 0x68, 0x41, 0x00, 0x0d, 0x20, ++ 0x40, 0x03, 0x12, 0x18, 0x91, 0x80, 0xa9, 0x8a, 0x5f, 0x49, 0xa9, 0x82, 0x33, 0x68, 0x80, 0x22, ++ 0x1b, 0x18, 0x5a, 0x80, 0xaa, 0x8a, 0xa9, 0x82, 0x31, 0x68, 0x08, 0x18, 0x47, 0x80, 0x00, 0x20, ++ 0xf0, 0xbd, 0x70, 0xb5, 0x53, 0x4c, 0x88, 0x21, 0x20, 0x68, 0x00, 0x25, 0x09, 0x5c, 0x40, 0x30, ++ 0xc9, 0x07, 0x00, 0x29, 0x03, 0xd0, 0x05, 0x76, 0x45, 0x76, 0x00, 0x20, 0x70, 0xbd, 0x81, 0x7a, ++ 0x07, 0x29, 0x01, 0xd0, 0x05, 0x76, 0x45, 0x76, 0xff, 0xf7, 0x3d, 0xff, 0x00, 0x28, 0x28, 0xd0, ++ 0x21, 0x68, 0x40, 0x31, 0x0a, 0x7e, 0x10, 0x18, 0x40, 0xb2, 0x08, 0x76, 0x4a, 0x7e, 0x52, 0x1c, ++ 0x52, 0xb2, 0x4a, 0x76, 0x20, 0x28, 0x09, 0xda, 0x30, 0x2a, 0x07, 0xda, 0xff, 0xf7, 0x80, 0xff, ++ 0x20, 0x68, 0x07, 0x21, 0x40, 0x30, 0x81, 0x72, 0x02, 0x20, 0x70, 0xbd, 0x03, 0x20, 0x00, 0x07, ++ 0x81, 0x8a, 0x01, 0x21, 0xc9, 0x43, 0x81, 0x82, 0x3b, 0x49, 0x01, 0x20, 0x09, 0x68, 0x0d, 0x22, ++ 0x52, 0x03, 0x89, 0x18, 0x48, 0x86, 0x01, 0x46, 0x17, 0x20, 0x01, 0xf0, 0xa3, 0xfe, 0x01, 0x20, ++ 0x70, 0xbd, 0x20, 0x68, 0x40, 0x30, 0xc6, 0xe7, 0x32, 0x48, 0x53, 0x21, 0x00, 0x68, 0x0a, 0x5c, ++ 0xc1, 0x7b, 0xc9, 0x08, 0x00, 0x2a, 0x07, 0xd0, 0x01, 0x29, 0x11, 0xd9, 0x00, 0x7c, 0xc0, 0x08, ++ 0x01, 0x28, 0x0d, 0xd9, 0x00, 0x20, 0x70, 0x47, 0x01, 0x29, 0x09, 0xd9, 0x01, 0x7c, 0xc9, 0x08, ++ 0x01, 0x29, 0x05, 0xd9, 0x41, 0x7b, 0xc9, 0x08, 0x01, 0x29, 0x01, 0xd9, 0x80, 0x7b, 0xee, 0xe7, ++ 0x01, 0x20, 0x70, 0x47, 0xf8, 0xb5, 0x23, 0x4d, 0x0f, 0x23, 0x2a, 0x68, 0x11, 0x46, 0x40, 0x31, ++ 0xcb, 0x56, 0x4b, 0x76, 0x90, 0x7b, 0x54, 0x7b, 0x00, 0x1b, 0x40, 0x10, 0xd0, 0x84, 0x8e, 0x7d, ++ 0x00, 0x24, 0x01, 0x2e, 0x06, 0xd0, 0x01, 0x26, 0x40, 0x05, 0xf6, 0x05, 0x80, 0x19, 0x00, 0x16, ++ 0x18, 0x1a, 0x0d, 0xe0, 0x16, 0x46, 0x80, 0x36, 0xb7, 0x79, 0x07, 0x2f, 0x09, 0xd3, 0xb4, 0x71, ++ 0x0c, 0x28, 0x01, 0xdd, 0x58, 0x1e, 0x03, 0xe0, 0x0c, 0x26, 0xf0, 0x42, 0x01, 0xda, 0x58, 0x1c, ++ 0x48, 0x76, 0x19, 0x20, 0x08, 0x56, 0x18, 0x28, 0x01, 0xda, 0x18, 0x20, 0x02, 0xe0, 0x2c, 0x28, ++ 0x01, 0xdd, 0x2c, 0x20, 0x48, 0x76, 0x19, 0x20, 0x08, 0x56, 0x83, 0x42, 0x30, 0xd0, 0xc3, 0x1a, ++ 0xdb, 0x00, 0xd3, 0x84, 0xc8, 0x73, 0xfb, 0xf7, 0xb7, 0xfe, 0x28, 0x68, 0x26, 0x22, 0x81, 0x7b, ++ 0x82, 0x5e, 0xf8, 0x23, 0x89, 0x18, 0x09, 0xb2, 0x01, 0x85, 0x00, 0x29, 0x0e, 0xda, 0x04, 0x85, ++ 0x0f, 0xe0, 0x00, 0x00, 0x90, 0x00, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, 0x40, 0xa0, 0x01, 0x00, ++ 0xff, 0xf8, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x00, 0xf8, 0x29, 0x00, 0xdd, ++ 0x03, 0x85, 0x01, 0x8d, 0x81, 0x73, 0x41, 0x7b, 0x89, 0x1a, 0x09, 0xb2, 0x01, 0x85, 0x00, 0x29, ++ 0x01, 0xda, 0x04, 0x85, 0x02, 0xe0, 0xf8, 0x29, 0x00, 0xdd, 0x03, 0x85, 0x01, 0x8d, 0x41, 0x73, ++ 0x00, 0x20, 0xf8, 0xbd, 0x10, 0xb5, 0xfa, 0x4c, 0x20, 0x68, 0x01, 0x46, 0x40, 0x30, 0x82, 0x7a, ++ 0x12, 0x2a, 0x23, 0xd0, 0xc0, 0x7c, 0x00, 0x28, 0x01, 0xd0, 0x01, 0x28, 0x70, 0xd1, 0x80, 0x31, ++ 0x48, 0x7b, 0x40, 0x06, 0x6c, 0xd4, 0xfe, 0xf7, 0x47, 0xfa, 0xfb, 0xf7, 0xf2, 0xfb, 0x21, 0x68, ++ 0x40, 0x31, 0x08, 0x76, 0x08, 0x7c, 0x08, 0x77, 0x0f, 0x20, 0xfb, 0xf7, 0x84, 0xfd, 0x20, 0x68, ++ 0x00, 0x21, 0x40, 0x30, 0x1d, 0xe0, 0x89, 0x7d, 0x01, 0x29, 0x32, 0xd0, 0xfd, 0xf7, 0xd8, 0xfc, ++ 0xfb, 0xf7, 0xbd, 0xfb, 0x20, 0x68, 0x12, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfb, 0xf7, 0xff, 0xfb, ++ 0x00, 0x28, 0x29, 0xd0, 0x20, 0x68, 0x40, 0x30, 0x81, 0x7d, 0x40, 0x7d, 0x01, 0x29, 0x25, 0xd0, ++ 0xfd, 0xf7, 0x63, 0xfd, 0x20, 0x68, 0x40, 0x30, 0xc1, 0x7d, 0x00, 0x29, 0xe8, 0xd0, 0x41, 0x7d, ++ 0x49, 0x1c, 0x41, 0x75, 0x21, 0x68, 0x40, 0x31, 0xca, 0x7c, 0x48, 0x7d, 0x00, 0x2a, 0x18, 0xd0, ++ 0x02, 0x22, 0x90, 0x42, 0xd7, 0xd3, 0x1c, 0x20, 0x08, 0x56, 0xfb, 0xf7, 0xf7, 0xfd, 0x21, 0x68, ++ 0x58, 0x20, 0x08, 0x56, 0xfb, 0xf7, 0xbe, 0xfb, 0xff, 0xf7, 0x26, 0xff, 0x01, 0x28, 0x0a, 0xd0, ++ 0x26, 0xe0, 0xfd, 0xf7, 0xd9, 0xfc, 0xcb, 0xe7, 0x02, 0x20, 0x98, 0xe5, 0xfd, 0xf7, 0xee, 0xfd, ++ 0xd8, 0xe7, 0x04, 0x22, 0xe5, 0xe7, 0x20, 0x68, 0x80, 0x79, 0x40, 0x06, 0x18, 0xd4, 0x01, 0x21, ++ 0x1b, 0x20, 0x01, 0xf0, 0xaf, 0xfd, 0x20, 0x68, 0x80, 0x30, 0x01, 0x7a, 0x0a, 0x07, 0x01, 0x21, ++ 0x00, 0x2a, 0x0c, 0xdb, 0x03, 0x20, 0x00, 0x07, 0x82, 0x8a, 0xca, 0x1e, 0x82, 0x82, 0xc1, 0x48, ++ 0x00, 0x68, 0x0d, 0x22, 0x52, 0x03, 0x80, 0x18, 0x41, 0x86, 0x01, 0x20, 0x77, 0xe5, 0x01, 0x74, ++ 0x20, 0x68, 0x30, 0x23, 0x01, 0x46, 0x02, 0x46, 0x40, 0x31, 0x8b, 0x72, 0x80, 0x30, 0x84, 0x79, ++ 0x03, 0x46, 0x64, 0x1c, 0x84, 0x71, 0xc8, 0x7c, 0x00, 0x28, 0x0a, 0xd1, 0x10, 0x88, 0x41, 0x07, ++ 0x07, 0xd4, 0x00, 0x06, 0x05, 0xd4, 0x58, 0x7b, 0xc0, 0x06, 0x02, 0xd4, 0xff, 0xf7, 0x02, 0xff, ++ 0x5d, 0xe5, 0x00, 0x20, 0x5b, 0xe5, 0x10, 0xb5, 0x04, 0x46, 0xfb, 0xf7, 0xe7, 0xfc, 0x03, 0x21, ++ 0x09, 0x07, 0x88, 0x8a, 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0xaa, 0x48, 0xe2, 0x06, 0x03, 0x68, ++ 0xd2, 0x0e, 0x0d, 0x24, 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, 0xa6, 0x4a, 0x8a, 0x82, ++ 0xa6, 0x4b, 0x04, 0x68, 0xa6, 0x4a, 0xa4, 0x18, 0x23, 0x84, 0x8b, 0x8a, 0x00, 0x23, 0x8b, 0x82, ++ 0xa4, 0x4b, 0x04, 0x68, 0xa4, 0x18, 0x63, 0x84, 0x8b, 0x8a, 0xff, 0x23, 0x8b, 0x82, 0x01, 0x21, ++ 0x00, 0x68, 0x89, 0x02, 0x80, 0x18, 0x81, 0x84, 0x31, 0xe5, 0x10, 0xb5, 0x04, 0x46, 0xfb, 0xf7, ++ 0xbd, 0xfc, 0x03, 0x21, 0x09, 0x07, 0x88, 0x8a, 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0x95, 0x48, ++ 0xe2, 0x06, 0x03, 0x68, 0xd2, 0x0e, 0x0d, 0x24, 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, ++ 0x91, 0x4a, 0x8a, 0x82, 0x91, 0x4b, 0x04, 0x68, 0x91, 0x4a, 0xa4, 0x18, 0x23, 0x84, 0x8b, 0x8a, ++ 0x00, 0x23, 0x8b, 0x82, 0x90, 0x4b, 0x04, 0x68, 0xa4, 0x18, 0x63, 0x84, 0x8b, 0x8a, 0xff, 0x23, ++ 0x8b, 0x82, 0x01, 0x21, 0x00, 0x68, 0x89, 0x02, 0x80, 0x18, 0x81, 0x84, 0x07, 0xe5, 0x70, 0xb5, ++ 0x83, 0x4c, 0x4d, 0x22, 0x20, 0x68, 0x00, 0x25, 0x11, 0x56, 0x2d, 0x29, 0x2b, 0xd0, 0x2e, 0x29, ++ 0x0e, 0xd0, 0x61, 0x21, 0x09, 0x5c, 0x80, 0x30, 0x41, 0x74, 0x14, 0x20, 0xff, 0xf7, 0x9b, 0xff, ++ 0x20, 0x68, 0x05, 0x84, 0xfb, 0xf7, 0xe3, 0xfa, 0x20, 0x68, 0x2e, 0x21, 0x40, 0x30, 0x41, 0x73, ++ 0xfb, 0xf7, 0x25, 0xfb, 0x00, 0x28, 0x31, 0xd0, 0x00, 0x20, 0xff, 0xf7, 0x60, 0xf9, 0x20, 0x68, ++ 0x01, 0x46, 0x40, 0x30, 0xc2, 0x7d, 0x00, 0x2a, 0xec, 0xd0, 0x60, 0x31, 0x49, 0x78, 0x41, 0x77, ++ 0x14, 0x20, 0xff, 0xf7, 0xaa, 0xff, 0x20, 0x68, 0x05, 0x84, 0xfb, 0xf7, 0xc8, 0xfa, 0x20, 0x68, ++ 0x2d, 0x21, 0x40, 0x30, 0x41, 0x73, 0xfb, 0xf7, 0x0a, 0xfb, 0x00, 0x28, 0x16, 0xd0, 0x00, 0x20, ++ 0xff, 0xf7, 0x45, 0xf9, 0x22, 0x68, 0x11, 0x46, 0x40, 0x31, 0xc8, 0x7d, 0x00, 0x28, 0xec, 0xd0, ++ 0x4d, 0x73, 0x61, 0x24, 0x48, 0x7f, 0xa3, 0x56, 0x98, 0x42, 0x00, 0xdd, 0x18, 0x46, 0x48, 0x77, ++ 0x91, 0x20, 0x10, 0x56, 0xfb, 0xf7, 0xd6, 0xfa, 0x00, 0x20, 0x70, 0xbd, 0x02, 0x20, 0x70, 0xbd, ++ 0xf8, 0xb5, 0x62, 0x48, 0x5a, 0x4c, 0x82, 0x7f, 0x20, 0x68, 0x01, 0x46, 0x40, 0x30, 0x83, 0x7a, ++ 0x23, 0x2b, 0x2c, 0xd0, 0x24, 0x2b, 0x39, 0xd0, 0xc3, 0x7c, 0x00, 0x2b, 0x02, 0xd1, 0x0b, 0x78, ++ 0x5b, 0x07, 0x01, 0xd4, 0x00, 0x20, 0xf8, 0xbd, 0x00, 0x25, 0x0b, 0x46, 0x4d, 0x84, 0x80, 0x33, ++ 0x1e, 0x79, 0x01, 0x2e, 0x00, 0xd0, 0x45, 0x75, 0x5b, 0x79, 0x00, 0x2b, 0x0f, 0xd0, 0x0f, 0x23, ++ 0xc3, 0x56, 0x9d, 0x1a, 0x00, 0x2d, 0x01, 0xdd, 0x5b, 0x1e, 0xc3, 0x73, 0x0f, 0x23, 0xc3, 0x56, ++ 0x9a, 0x1a, 0x01, 0xd5, 0x5b, 0x1c, 0xc3, 0x73, 0x01, 0x20, 0x48, 0x84, 0x53, 0xe0, 0x07, 0x20, ++ 0xc0, 0x43, 0xfb, 0xf7, 0xd3, 0xfc, 0x20, 0x68, 0x23, 0x21, 0x40, 0x30, 0x81, 0x72, 0xff, 0xf7, ++ 0x76, 0xff, 0x02, 0x28, 0xd7, 0xd0, 0x20, 0x68, 0x5d, 0x21, 0x09, 0x5c, 0xc1, 0x84, 0x08, 0x20, ++ 0xfb, 0xf7, 0xc4, 0xfc, 0x20, 0x68, 0x24, 0x21, 0x40, 0x30, 0x81, 0x72, 0xff, 0xf7, 0x67, 0xff, ++ 0x02, 0x28, 0xc8, 0xd0, 0x22, 0x68, 0x00, 0x26, 0x10, 0x46, 0x40, 0x30, 0x41, 0x7f, 0xd3, 0x8c, ++ 0xf6, 0x43, 0xc9, 0x1a, 0x09, 0xb2, 0xd1, 0x84, 0x00, 0x29, 0x10, 0xd0, 0x43, 0x7d, 0x00, 0x2b, ++ 0x31, 0xd0, 0x00, 0x29, 0x01, 0xdb, 0x01, 0x23, 0x00, 0xe0, 0x33, 0x46, 0x1c, 0x25, 0x45, 0x57, ++ 0x00, 0x2d, 0x01, 0xdb, 0x01, 0x25, 0x00, 0xe0, 0x35, 0x46, 0xab, 0x42, 0x23, 0xd0, 0x01, 0x23, ++ 0x53, 0x84, 0x00, 0x29, 0x01, 0xdb, 0x0d, 0x46, 0x00, 0xe0, 0x4d, 0x42, 0x1c, 0x23, 0xc3, 0x56, ++ 0x00, 0x2b, 0x01, 0xdb, 0x1f, 0x46, 0x00, 0xe0, 0x5f, 0x42, 0xbd, 0x42, 0x0a, 0xdd, 0x80, 0x32, ++ 0xd2, 0x78, 0x01, 0x2a, 0x1a, 0xd0, 0x0f, 0x22, 0x82, 0x56, 0x00, 0x2b, 0x00, 0xdb, 0x01, 0x26, ++ 0x92, 0x19, 0xc2, 0x73, 0x01, 0x77, 0x21, 0x68, 0x0f, 0x20, 0x40, 0x31, 0x08, 0x56, 0x18, 0x28, ++ 0x0f, 0xda, 0x18, 0x20, 0x10, 0xe0, 0x80, 0x32, 0xd2, 0x78, 0x01, 0x2a, 0x06, 0xd0, 0x0f, 0x22, ++ 0x82, 0x56, 0x00, 0x29, 0x00, 0xdb, 0x01, 0x26, 0x92, 0x1b, 0xea, 0xe7, 0x0f, 0x22, 0x82, 0x56, ++ 0xe7, 0xe7, 0x2c, 0x28, 0x01, 0xdd, 0x2c, 0x20, 0xc8, 0x73, 0x0f, 0x20, 0x08, 0x56, 0xfb, 0xf7, ++ 0xab, 0xfc, 0x20, 0x68, 0x01, 0x46, 0x40, 0x30, 0x42, 0x7d, 0x03, 0x46, 0x52, 0x1c, 0xd2, 0xb2, ++ 0x42, 0x75, 0x48, 0x8c, 0x01, 0x28, 0x03, 0xd0, 0x10, 0x2a, 0x01, 0xd2, 0x01, 0x20, 0x00, 0xe0, ++ 0x00, 0x20, 0x80, 0x31, 0x08, 0x71, 0x00, 0x20, 0x98, 0x72, 0xfb, 0xf7, 0x4f, 0xfc, 0x59, 0xe7, ++ 0x90, 0x00, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, 0xf3, 0x8f, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, ++ 0x40, 0xa0, 0x01, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, ++ 0xfe, 0xb5, 0xfe, 0x4e, 0x30, 0x68, 0xff, 0x30, 0x01, 0x30, 0x45, 0x8e, 0x68, 0x46, 0x05, 0x80, ++ 0xac, 0x06, 0x30, 0x68, 0xa4, 0x0e, 0xfa, 0x4f, 0xc0, 0x19, 0x80, 0x88, 0x40, 0x07, 0xc0, 0x0f, ++ 0x0e, 0xd1, 0xe8, 0x0b, 0x0c, 0xd0, 0xb8, 0x05, 0x81, 0x8a, 0x04, 0x21, 0xc9, 0x43, 0x81, 0x82, ++ 0x31, 0x68, 0x04, 0x20, 0xc9, 0x19, 0x88, 0x80, 0x01, 0x21, 0x10, 0x20, 0x01, 0xf0, 0xf2, 0xfb, ++ 0xf0, 0x48, 0x01, 0x68, 0x08, 0x46, 0x80, 0x30, 0xc2, 0x7e, 0xa2, 0x42, 0x1b, 0xd0, 0x00, 0x23, ++ 0x01, 0x22, 0x00, 0x2c, 0x0e, 0xd0, 0x42, 0x31, 0x0d, 0x80, 0x02, 0x76, 0x03, 0x20, 0x00, 0x07, ++ 0x81, 0x8a, 0x83, 0x82, 0x30, 0x68, 0xc0, 0x19, 0x03, 0x80, 0x01, 0x23, 0x00, 0x92, 0x01, 0x94, ++ 0x03, 0x22, 0x04, 0xe0, 0xc2, 0x75, 0x01, 0x93, 0x00, 0x92, 0x01, 0x23, 0x04, 0x22, 0x09, 0x21, ++ 0x01, 0x20, 0x01, 0xf0, 0x59, 0xfb, 0xdf, 0x48, 0x00, 0x68, 0x80, 0x30, 0xc4, 0x76, 0xfe, 0xbd, ++ 0x7c, 0xb5, 0xda, 0x4c, 0x20, 0x68, 0xda, 0x49, 0x40, 0x39, 0x40, 0x18, 0xc0, 0x8c, 0x03, 0x23, ++ 0xc6, 0x07, 0xd8, 0x48, 0x1b, 0x07, 0x00, 0x68, 0x00, 0x21, 0x80, 0x30, 0x00, 0x2e, 0xd6, 0x4a, ++ 0xd3, 0x4d, 0x9e, 0x8a, 0x9a, 0x82, 0x0b, 0xd0, 0x23, 0x68, 0x02, 0x22, 0x5b, 0x19, 0x9a, 0x80, ++ 0x01, 0x22, 0x82, 0x75, 0xc2, 0x75, 0x00, 0x91, 0x01, 0x91, 0x13, 0x46, 0x0b, 0x21, 0x19, 0xe0, ++ 0x22, 0x68, 0x52, 0x19, 0x91, 0x80, 0x22, 0x68, 0x52, 0x19, 0x92, 0x88, 0x52, 0x07, 0xd2, 0x0f, ++ 0x0b, 0xd1, 0x9a, 0x8a, 0x99, 0x82, 0x22, 0x68, 0x52, 0x19, 0x52, 0x88, 0x23, 0x68, 0x52, 0x04, ++ 0x52, 0x0c, 0x5b, 0x19, 0x5a, 0x80, 0x81, 0x75, 0x41, 0x76, 0x00, 0x91, 0x01, 0x23, 0x04, 0x22, ++ 0x01, 0x91, 0x21, 0x21, 0x01, 0x20, 0x01, 0xf0, 0x17, 0xfb, 0x7c, 0xbd, 0x10, 0xb5, 0xbb, 0x48, ++ 0x00, 0x68, 0xbb, 0x49, 0x40, 0x39, 0x40, 0x18, 0x84, 0x8d, 0x60, 0x08, 0xc0, 0x07, 0x01, 0xd0, ++ 0xff, 0xf7, 0xb6, 0xff, 0xe0, 0x07, 0x01, 0xd0, 0xff, 0xf7, 0x6a, 0xff, 0x10, 0xbd, 0x7c, 0xb5, ++ 0xb4, 0x4e, 0x05, 0x46, 0x30, 0x68, 0x01, 0x24, 0x80, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0x08, 0xd1, ++ 0x05, 0x20, 0x01, 0x90, 0x00, 0x23, 0x02, 0x22, 0x15, 0x21, 0x00, 0x94, 0x01, 0x20, 0x01, 0xf0, ++ 0xf3, 0xfa, 0x31, 0x68, 0x00, 0x20, 0x80, 0x31, 0x08, 0x76, 0x03, 0x22, 0xc8, 0x75, 0x12, 0x07, ++ 0x93, 0x8a, 0x90, 0x82, 0xa5, 0x48, 0x00, 0x68, 0xa5, 0x4a, 0x80, 0x18, 0x05, 0x80, 0x88, 0x7e, ++ 0x40, 0x1c, 0xc2, 0xb2, 0x8a, 0x76, 0xe8, 0xb2, 0x01, 0x2a, 0x00, 0x94, 0x01, 0x90, 0x06, 0xd0, ++ 0x00, 0x23, 0x02, 0x22, 0x0a, 0x21, 0x01, 0x20, 0x01, 0xf0, 0xd6, 0xfa, 0x7c, 0xbd, 0x00, 0x23, ++ 0x01, 0x22, 0x20, 0x21, 0xf7, 0xe7, 0x70, 0xb5, 0x98, 0x49, 0x08, 0x68, 0x98, 0x4a, 0x80, 0x18, ++ 0x43, 0x88, 0x01, 0x20, 0xc0, 0x03, 0x03, 0x43, 0x90, 0x05, 0x84, 0x8a, 0x01, 0x24, 0xe4, 0x43, ++ 0x84, 0x82, 0x0d, 0x68, 0x01, 0x24, 0xad, 0x18, 0xac, 0x80, 0x84, 0x8a, 0x00, 0x24, 0x84, 0x82, ++ 0x08, 0x68, 0x80, 0x18, 0x43, 0x80, 0x01, 0x21, 0x0c, 0x20, 0x01, 0xf0, 0x2b, 0xfb, 0x70, 0xbd, ++ 0x0f, 0xb4, 0x10, 0xb5, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0xff, 0x21, 0x09, 0x02, 0x81, 0x82, ++ 0x6c, 0x46, 0xe1, 0x8e, 0xc9, 0x07, 0x0b, 0x0e, 0xa1, 0x8e, 0xc9, 0x07, 0x49, 0x0e, 0x0b, 0x43, ++ 0x61, 0x8e, 0xc9, 0x07, 0x89, 0x0e, 0x0b, 0x43, 0x21, 0x8e, 0xc9, 0x07, 0xc9, 0x0e, 0x0b, 0x43, ++ 0xe1, 0x8d, 0xc9, 0x07, 0x09, 0x0f, 0x0b, 0x43, 0xa1, 0x8d, 0xc9, 0x07, 0x49, 0x0f, 0x0b, 0x43, ++ 0x61, 0x8d, 0xc9, 0x07, 0x89, 0x0f, 0x0b, 0x43, 0x21, 0x8d, 0xc9, 0x07, 0xc9, 0x0f, 0x0b, 0x43, ++ 0x76, 0x49, 0x0c, 0x68, 0xd1, 0x22, 0x52, 0x02, 0xa4, 0x18, 0xe3, 0x86, 0x83, 0x8a, 0x23, 0x23, ++ 0x9b, 0x02, 0x83, 0x82, 0x6c, 0x46, 0x63, 0x8c, 0x24, 0x8c, 0xdb, 0x07, 0xe4, 0x07, 0x5b, 0x0c, ++ 0xa4, 0x0c, 0x23, 0x43, 0x6c, 0x46, 0xe4, 0x8b, 0xe4, 0x07, 0xe4, 0x0c, 0x23, 0x43, 0x6c, 0x46, ++ 0x64, 0x8b, 0xe4, 0x07, 0xa4, 0x0d, 0x23, 0x43, 0x6c, 0x46, 0x24, 0x8b, 0xe4, 0x07, 0xe4, 0x0d, ++ 0x23, 0x43, 0x6c, 0x46, 0xe4, 0x8a, 0xe4, 0x07, 0x24, 0x0e, 0x23, 0x43, 0x6c, 0x46, 0xa4, 0x8a, ++ 0xe4, 0x07, 0x64, 0x0e, 0x23, 0x43, 0x6c, 0x46, 0x64, 0x8a, 0xe4, 0x07, 0xa4, 0x0e, 0x23, 0x43, ++ 0x6c, 0x46, 0x24, 0x8a, 0xe4, 0x07, 0xe4, 0x0e, 0x23, 0x43, 0x6c, 0x46, 0xe4, 0x89, 0xe4, 0x07, ++ 0x24, 0x0f, 0x23, 0x43, 0x6c, 0x46, 0xa4, 0x89, 0xe4, 0x07, 0x64, 0x0f, 0x23, 0x43, 0x6c, 0x46, ++ 0x64, 0x89, 0xe4, 0x07, 0xa4, 0x0f, 0x23, 0x43, 0x6c, 0x46, 0x24, 0x89, 0xe4, 0x07, 0xe4, 0x0f, ++ 0x23, 0x43, 0x0c, 0x68, 0xa4, 0x18, 0x23, 0x87, 0x83, 0x8a, 0x01, 0x23, 0xdb, 0x03, 0x83, 0x82, ++ 0x10, 0xac, 0xa3, 0x8c, 0x64, 0x8c, 0xdb, 0x07, 0xe4, 0x07, 0x5b, 0x0c, 0xa4, 0x0c, 0x23, 0x43, ++ 0x10, 0xac, 0x24, 0x8c, 0xe4, 0x07, 0xe4, 0x0c, 0x23, 0x43, 0x10, 0xac, 0xe4, 0x8b, 0xe4, 0x07, ++ 0x24, 0x0d, 0x23, 0x43, 0x10, 0xac, 0xa4, 0x8b, 0xe4, 0x07, 0x64, 0x0d, 0x23, 0x43, 0x10, 0xac, ++ 0x64, 0x8b, 0xe4, 0x07, 0xa4, 0x0d, 0x23, 0x43, 0x10, 0xac, 0x24, 0x8b, 0xe4, 0x07, 0xe4, 0x0d, ++ 0x23, 0x43, 0x10, 0xac, 0xe4, 0x8a, 0xe4, 0x07, 0x24, 0x0e, 0x23, 0x43, 0x10, 0xac, 0xa4, 0x8a, ++ 0xe4, 0x07, 0x64, 0x0e, 0x23, 0x43, 0x10, 0xac, 0x64, 0x8a, 0xe4, 0x07, 0xa4, 0x0e, 0x23, 0x43, ++ 0x10, 0xac, 0x24, 0x8a, 0xe4, 0x07, 0xe4, 0x0e, 0x23, 0x43, 0x10, 0xac, 0xe4, 0x89, 0xe4, 0x07, ++ 0x24, 0x0f, 0x23, 0x43, 0x10, 0xac, 0xa4, 0x89, 0xe4, 0x07, 0x64, 0x0f, 0x23, 0x43, 0x10, 0xac, ++ 0x64, 0x89, 0xe4, 0x07, 0xa4, 0x0f, 0x23, 0x43, 0x10, 0xac, 0x24, 0x89, 0xe4, 0x07, 0xe4, 0x0f, ++ 0x23, 0x43, 0x0c, 0x68, 0xa4, 0x18, 0x63, 0x87, 0x83, 0x8a, 0x0f, 0x23, 0xdb, 0x43, 0x83, 0x82, ++ 0x10, 0xac, 0x60, 0x88, 0x23, 0x88, 0xc0, 0x07, 0xdb, 0x07, 0x00, 0x0f, 0x5b, 0x0f, 0x18, 0x43, ++ 0x6c, 0x46, 0xe3, 0x8f, 0x09, 0x68, 0xdb, 0x07, 0x9b, 0x0f, 0x18, 0x43, 0xa3, 0x8f, 0xdb, 0x07, ++ 0xdb, 0x0f, 0x18, 0x43, 0x89, 0x18, 0x88, 0x87, 0x10, 0xbc, 0x08, 0xbc, 0x00, 0x20, 0x04, 0xb0, ++ 0x18, 0x47, 0xff, 0xb5, 0xab, 0xb0, 0x1e, 0x00, 0x15, 0x46, 0x04, 0x46, 0x18, 0xd0, 0x00, 0x27, ++ 0x20, 0x21, 0x15, 0xa8, 0x01, 0xf0, 0xd6, 0xfa, 0x14, 0x21, 0x26, 0xa8, 0x01, 0xf0, 0xd2, 0xfa, ++ 0x00, 0x20, 0x00, 0x90, 0x01, 0x90, 0x02, 0x90, 0x24, 0x21, 0x1d, 0xa8, 0x01, 0xf0, 0xca, 0xfa, ++ 0x00, 0x2f, 0x0a, 0xd0, 0x12, 0x2d, 0x05, 0xdd, 0x06, 0x20, 0xad, 0x1f, 0xe9, 0xb2, 0x06, 0xe0, ++ 0x01, 0x27, 0xe5, 0xe7, 0xe9, 0xb2, 0x00, 0x20, 0x01, 0xe0, 0xe9, 0xb2, 0xf0, 0xb2, 0x2c, 0x9a, ++ 0xc3, 0x07, 0x12, 0x1b, 0x52, 0x1a, 0x12, 0x1a, 0xd5, 0xb2, 0x01, 0x22, 0x00, 0x2b, 0x01, 0xd1, ++ 0x06, 0x28, 0x01, 0xd3, 0x20, 0xab, 0x1a, 0x83, 0x02, 0x28, 0x07, 0xe0, 0x84, 0x00, 0x00, 0x20, ++ 0xc0, 0xa0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x20, 0xfd, 0xff, 0x00, 0x00, 0x01, 0xd3, 0x20, 0xab, ++ 0x1a, 0x84, 0x04, 0x28, 0x04, 0xd3, 0x20, 0xab, 0x9a, 0x84, 0x06, 0x28, 0x00, 0xd3, 0x9a, 0x83, ++ 0xfe, 0x48, 0x20, 0x40, 0x01, 0x28, 0x01, 0xd0, 0x0a, 0x2c, 0x01, 0xdb, 0x10, 0xa8, 0x82, 0x86, ++ 0x02, 0x2c, 0x01, 0xdb, 0x20, 0xa8, 0x82, 0x81, 0x04, 0x2c, 0x01, 0xdb, 0x20, 0xa8, 0xc2, 0x80, ++ 0x06, 0x2c, 0x01, 0xdb, 0x20, 0xa8, 0x02, 0x80, 0x08, 0x2c, 0x04, 0xdb, 0x10, 0xa8, 0x42, 0x87, ++ 0x0a, 0x2c, 0x00, 0xdb, 0x42, 0x85, 0xc8, 0x07, 0x01, 0xd1, 0x08, 0x29, 0x01, 0xd3, 0x10, 0xa8, ++ 0x82, 0x82, 0x02, 0x29, 0x01, 0xd3, 0x10, 0xa8, 0x82, 0x83, 0x04, 0x29, 0x01, 0xd3, 0x10, 0xa8, ++ 0x02, 0x84, 0x06, 0x29, 0x04, 0xd3, 0x10, 0xa8, 0x82, 0x84, 0x08, 0x29, 0x00, 0xd3, 0x02, 0x83, ++ 0x10, 0xa8, 0x44, 0x8d, 0x00, 0x2c, 0x1f, 0xd1, 0xc8, 0x07, 0x01, 0xd0, 0x08, 0x29, 0x19, 0xd2, ++ 0x12, 0x29, 0x17, 0xd2, 0x10, 0xa8, 0x40, 0x8f, 0x01, 0x28, 0x01, 0xd1, 0x0a, 0x29, 0x11, 0xd2, ++ 0x20, 0xa8, 0x00, 0x88, 0x01, 0x28, 0x01, 0xd1, 0x0c, 0x29, 0x0b, 0xd2, 0x20, 0xa8, 0xc0, 0x88, ++ 0x01, 0x28, 0x01, 0xd1, 0x0e, 0x29, 0x05, 0xd2, 0x20, 0xa8, 0x80, 0x89, 0x01, 0x28, 0x03, 0xd1, ++ 0x10, 0x29, 0x01, 0xd3, 0x10, 0xa8, 0x82, 0x85, 0x10, 0xab, 0x58, 0x8f, 0x03, 0x90, 0x00, 0x28, ++ 0x02, 0xd1, 0x0a, 0x29, 0x00, 0xd3, 0x9a, 0x87, 0x20, 0xa8, 0x00, 0x88, 0x84, 0x46, 0x00, 0x28, ++ 0x03, 0xd1, 0x0c, 0x29, 0x01, 0xd3, 0x20, 0xa8, 0x42, 0x80, 0x20, 0xa8, 0xc7, 0x88, 0x00, 0x2f, ++ 0x02, 0xd1, 0x0e, 0x29, 0x00, 0xd3, 0x02, 0x81, 0x86, 0x89, 0x00, 0x2e, 0x02, 0xd1, 0x10, 0x29, ++ 0x00, 0xd3, 0xc2, 0x81, 0x9b, 0x8e, 0x00, 0x2b, 0x15, 0xd1, 0x12, 0x29, 0x11, 0xd2, 0x03, 0x98, ++ 0x01, 0x28, 0x01, 0xd1, 0x0a, 0x29, 0x0c, 0xd2, 0x60, 0x46, 0x01, 0x28, 0x01, 0xd1, 0x0c, 0x29, ++ 0x07, 0xd2, 0x01, 0x2f, 0x01, 0xd1, 0x0e, 0x29, 0x03, 0xd2, 0x01, 0x2e, 0x03, 0xd1, 0x10, 0x29, ++ 0x01, 0xd3, 0x10, 0xa8, 0xc2, 0x86, 0x00, 0x2d, 0x7e, 0xd0, 0x6d, 0x1e, 0xe8, 0xb2, 0xc1, 0x07, ++ 0x01, 0xd0, 0x69, 0x46, 0x0a, 0x80, 0x40, 0x08, 0xf6, 0xd0, 0xc1, 0x07, 0x05, 0xd0, 0x40, 0x1e, ++ 0x69, 0x46, 0x00, 0x06, 0x4a, 0x80, 0x00, 0x0e, 0xee, 0xd0, 0x69, 0x46, 0x89, 0x88, 0x00, 0x29, ++ 0x05, 0xd1, 0x80, 0x1e, 0x69, 0x46, 0x00, 0x06, 0x8a, 0x80, 0x00, 0x0e, 0xe4, 0xd0, 0x69, 0x46, ++ 0xc9, 0x88, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, 0x69, 0x46, 0x00, 0x06, 0xca, 0x80, 0x00, 0x0e, ++ 0xda, 0xd0, 0x69, 0x46, 0x49, 0x88, 0x00, 0x29, 0x6f, 0xd1, 0x20, 0xa9, 0xc9, 0x8b, 0x00, 0x29, ++ 0x0d, 0xd1, 0x20, 0xa9, 0x89, 0x8b, 0x00, 0x29, 0x09, 0xd1, 0x69, 0x46, 0x4a, 0x80, 0x80, 0x1e, ++ 0x20, 0xa9, 0x00, 0x06, 0xca, 0x83, 0x00, 0x0e, 0xc6, 0xd0, 0x00, 0x2a, 0x5d, 0xd1, 0x20, 0xa9, ++ 0x49, 0x8b, 0x00, 0x29, 0x0d, 0xd1, 0x20, 0xa9, 0x09, 0x8b, 0x00, 0x29, 0x09, 0xd1, 0x69, 0x46, ++ 0x4a, 0x80, 0x80, 0x1e, 0x20, 0xa9, 0x00, 0x06, 0x4a, 0x83, 0x00, 0x0e, 0xb4, 0xd0, 0x00, 0x2a, ++ 0x4b, 0xd1, 0x10, 0xa9, 0x49, 0x8b, 0x00, 0x29, 0x0d, 0xd1, 0x10, 0xa9, 0x09, 0x8b, 0x00, 0x29, ++ 0x09, 0xd1, 0x69, 0x46, 0x4a, 0x80, 0x80, 0x1e, 0x10, 0xa9, 0x00, 0x06, 0x4a, 0x83, 0x00, 0x0e, ++ 0xa2, 0xd0, 0x00, 0x2a, 0x39, 0xd1, 0x10, 0xa9, 0xc9, 0x8a, 0x00, 0x29, 0x0d, 0xd1, 0x10, 0xa9, ++ 0x89, 0x8a, 0x00, 0x29, 0x09, 0xd1, 0x69, 0x46, 0x4a, 0x80, 0x80, 0x1e, 0x10, 0xa9, 0x00, 0x06, ++ 0xca, 0x82, 0x00, 0x0e, 0x90, 0xd0, 0x00, 0x2a, 0x27, 0xd1, 0x10, 0xa9, 0x09, 0x8f, 0x00, 0x29, ++ 0x11, 0xd1, 0x00, 0x2b, 0x0f, 0xd1, 0x10, 0xa9, 0xc9, 0x8e, 0x00, 0x29, 0x0b, 0xd1, 0x69, 0x46, ++ 0x4a, 0x80, 0x10, 0xa9, 0x0a, 0x87, 0x00, 0xe0, 0x1e, 0xe1, 0x80, 0x1e, 0x00, 0x06, 0x00, 0x0e, ++ 0x8a, 0xd0, 0x00, 0x2a, 0x11, 0xd1, 0x10, 0xa9, 0xc9, 0x8d, 0x00, 0x29, 0x0d, 0xd1, 0x00, 0x2c, ++ 0x0b, 0xd1, 0x10, 0xa9, 0x89, 0x8d, 0x00, 0x29, 0x07, 0xd1, 0x69, 0x46, 0x4a, 0x80, 0x80, 0x1e, ++ 0x10, 0xa9, 0x00, 0x06, 0xca, 0x85, 0x00, 0x0e, 0x8a, 0xd0, 0x20, 0xa9, 0xc9, 0x8c, 0x00, 0x29, ++ 0x09, 0xd1, 0x20, 0xa9, 0x89, 0x8c, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, 0x20, 0xa9, 0x00, 0x06, ++ 0xca, 0x84, 0x00, 0x0e, 0x90, 0xd0, 0x20, 0xa9, 0x49, 0x8c, 0x00, 0x29, 0x09, 0xd1, 0x20, 0xa9, ++ 0x09, 0x8c, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, 0x20, 0xa9, 0x00, 0x06, 0x4a, 0x84, 0x00, 0x0e, ++ 0x94, 0xd0, 0x10, 0xa9, 0xc9, 0x8c, 0x00, 0x29, 0x09, 0xd1, 0x10, 0xa9, 0x89, 0x8c, 0x00, 0x29, ++ 0x05, 0xd1, 0x80, 0x1e, 0x10, 0xa9, 0x00, 0x06, 0xca, 0x84, 0x00, 0x0e, 0x86, 0xd0, 0x10, 0xa9, ++ 0x49, 0x8c, 0x00, 0x29, 0x09, 0xd1, 0x10, 0xa9, 0x09, 0x8c, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, ++ 0x10, 0xa9, 0x00, 0x06, 0x4a, 0x84, 0x00, 0x0e, 0x8a, 0xd0, 0x10, 0xa9, 0xc9, 0x8b, 0x00, 0x29, ++ 0x09, 0xd1, 0x10, 0xa9, 0x89, 0x8b, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, 0x10, 0xa9, 0x00, 0x06, ++ 0xca, 0x83, 0x00, 0x0e, 0x8e, 0xd0, 0x20, 0xa9, 0x09, 0x8a, 0x00, 0x29, 0x0b, 0xd1, 0x00, 0x2e, ++ 0x09, 0xd1, 0x20, 0xa9, 0xc9, 0x89, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, 0x20, 0xa9, 0x00, 0x06, ++ 0x0a, 0x82, 0x00, 0x0e, 0x94, 0xd0, 0x20, 0xa9, 0x49, 0x89, 0x00, 0x29, 0x0b, 0xd1, 0x00, 0x2f, ++ 0x09, 0xd1, 0x20, 0xa9, 0x09, 0x89, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, 0x20, 0xa9, 0x00, 0x06, ++ 0x4a, 0x81, 0x00, 0x0e, 0x84, 0xd0, 0x20, 0xa9, 0x89, 0x88, 0x00, 0x29, 0x0c, 0xd1, 0x61, 0x46, ++ 0x00, 0x29, 0x09, 0xd1, 0x20, 0xa9, 0x49, 0x88, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, 0x20, 0xa9, ++ 0x00, 0x06, 0x8a, 0x80, 0x00, 0x0e, 0x87, 0xd0, 0x10, 0xa9, 0xc9, 0x8f, 0x00, 0x29, 0x0c, 0xd1, ++ 0x03, 0x99, 0x00, 0x29, 0x09, 0xd1, 0x10, 0xa9, 0x89, 0x8f, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, ++ 0x10, 0xa9, 0x00, 0x06, 0xca, 0x87, 0x00, 0x0e, 0x7e, 0xd0, 0x20, 0xa9, 0xc9, 0x8b, 0x00, 0x29, ++ 0x3a, 0xd1, 0x20, 0xa9, 0x89, 0x8b, 0x00, 0x29, 0x36, 0xd1, 0x20, 0xad, 0x6d, 0x8b, 0x00, 0x2d, ++ 0x0e, 0xd1, 0x20, 0xad, 0x2d, 0x8b, 0x00, 0x2d, 0x0a, 0xd1, 0x20, 0xad, 0x80, 0x1e, 0xea, 0x83, ++ 0x00, 0x06, 0x6a, 0x83, 0x00, 0x0e, 0x67, 0xd0, 0x00, 0x2a, 0x25, 0xd1, 0x00, 0x29, 0x23, 0xd1, ++ 0x10, 0xad, 0x6d, 0x8b, 0x00, 0x2d, 0x0f, 0xd1, 0x10, 0xad, 0x2d, 0x8b, 0x00, 0x2d, 0x0b, 0xd1, ++ 0x20, 0xad, 0xea, 0x83, 0x80, 0x1e, 0x10, 0xad, 0x00, 0x06, 0x6a, 0x83, 0x00, 0x0e, 0x53, 0xd0, ++ 0x00, 0x2a, 0x11, 0xd1, 0x00, 0x29, 0x0f, 0xd1, 0x10, 0xa9, 0xc9, 0x8a, 0x00, 0x29, 0x0b, 0xd1, ++ 0x10, 0xa9, 0x89, 0x8a, 0x00, 0x29, 0x07, 0xd1, 0x20, 0xa9, 0xca, 0x83, 0x80, 0x1e, 0x10, 0xa9, ++ 0x00, 0x06, 0xca, 0x82, 0x00, 0x0e, 0x3f, 0xd0, 0x20, 0xa9, 0x49, 0x8b, 0x00, 0x29, 0x2a, 0xd1, ++ 0x20, 0xa9, 0x09, 0x8b, 0x00, 0x29, 0x26, 0xd1, 0x10, 0xad, 0x6d, 0x8b, 0x00, 0x2d, 0x12, 0xd1, ++ 0x10, 0xad, 0x2d, 0x8b, 0x00, 0x2d, 0x0e, 0xd1, 0x20, 0xad, 0x01, 0xe0, 0x01, 0x00, 0x00, 0x80, ++ 0x6a, 0x83, 0x80, 0x1e, 0x10, 0xad, 0x00, 0x06, 0x6a, 0x83, 0x00, 0x0e, 0x24, 0xd0, 0x00, 0x2a, ++ 0x11, 0xd1, 0x00, 0x29, 0x0f, 0xd1, 0x10, 0xa9, 0xc9, 0x8a, 0x00, 0x29, 0x0b, 0xd1, 0x10, 0xa9, ++ 0x89, 0x8a, 0x00, 0x29, 0x07, 0xd1, 0x20, 0xa9, 0x4a, 0x83, 0x80, 0x1e, 0x10, 0xa9, 0x00, 0x06, ++ 0xca, 0x82, 0x00, 0x0e, 0x10, 0xd0, 0x10, 0xa9, 0x49, 0x8b, 0x00, 0x29, 0x14, 0xd1, 0x10, 0xa9, ++ 0x09, 0x8b, 0x00, 0x29, 0x10, 0xd1, 0x10, 0xa9, 0xc9, 0x8a, 0x00, 0x29, 0x0c, 0xd1, 0x10, 0xa9, ++ 0x89, 0x8a, 0x00, 0x29, 0x08, 0xd1, 0x00, 0xe0, 0x84, 0xe0, 0x10, 0xa9, 0x80, 0x1e, 0x4a, 0x83, ++ 0x00, 0x06, 0xca, 0x82, 0x00, 0x0e, 0x7d, 0xd0, 0x20, 0xa9, 0xc9, 0x8b, 0x00, 0x29, 0x2b, 0xd1, ++ 0x20, 0xa9, 0x89, 0x8b, 0x00, 0x29, 0x27, 0xd1, 0x10, 0xad, 0x2d, 0x8f, 0x00, 0x2d, 0x11, 0xd1, ++ 0x00, 0x2b, 0x0f, 0xd1, 0x10, 0xad, 0xed, 0x8e, 0x00, 0x2d, 0x0b, 0xd1, 0x20, 0xad, 0xea, 0x83, ++ 0x80, 0x1e, 0x10, 0xad, 0x00, 0x06, 0x2a, 0x87, 0x00, 0x0e, 0x63, 0xd0, 0x00, 0x2a, 0x13, 0xd1, ++ 0x00, 0x29, 0x11, 0xd1, 0x10, 0xa9, 0xc9, 0x8d, 0x00, 0x29, 0x0d, 0xd1, 0x00, 0x2c, 0x0b, 0xd1, ++ 0x10, 0xa9, 0x89, 0x8d, 0x00, 0x29, 0x07, 0xd1, 0x20, 0xa9, 0xca, 0x83, 0x80, 0x1e, 0x10, 0xa9, ++ 0x00, 0x06, 0xca, 0x85, 0x00, 0x0e, 0x4d, 0xd0, 0x20, 0xa9, 0x49, 0x8b, 0x00, 0x29, 0x2b, 0xd1, ++ 0x20, 0xa9, 0x09, 0x8b, 0x00, 0x29, 0x27, 0xd1, 0x10, 0xad, 0x2d, 0x8f, 0x00, 0x2d, 0x11, 0xd1, ++ 0x00, 0x2b, 0x0f, 0xd1, 0x10, 0xad, 0xed, 0x8e, 0x00, 0x2d, 0x0b, 0xd1, 0x20, 0xad, 0x6a, 0x83, ++ 0x80, 0x1e, 0x10, 0xad, 0x00, 0x06, 0x2a, 0x87, 0x00, 0x0e, 0x33, 0xd0, 0x00, 0x2a, 0x13, 0xd1, ++ 0x00, 0x29, 0x11, 0xd1, 0x10, 0xa9, 0xc9, 0x8d, 0x00, 0x29, 0x0d, 0xd1, 0x00, 0x2c, 0x0b, 0xd1, ++ 0x10, 0xa9, 0x89, 0x8d, 0x00, 0x29, 0x07, 0xd1, 0x20, 0xa9, 0x4a, 0x83, 0x80, 0x1e, 0x10, 0xa9, ++ 0x00, 0x06, 0xca, 0x85, 0x00, 0x0e, 0x74, 0xd0, 0x10, 0xa9, 0x49, 0x8b, 0x00, 0x29, 0x2b, 0xd1, ++ 0x10, 0xa9, 0x09, 0x8b, 0x00, 0x29, 0x27, 0xd1, 0x10, 0xad, 0x2d, 0x8f, 0x00, 0x2d, 0x10, 0xd1, ++ 0x00, 0x2b, 0x0e, 0xd1, 0x10, 0xad, 0xed, 0x8e, 0x00, 0x2d, 0x0a, 0xd1, 0x10, 0xad, 0x80, 0x1e, ++ 0x6a, 0x83, 0x00, 0x06, 0x2a, 0x87, 0x00, 0x0e, 0x5b, 0xd0, 0x00, 0x2a, 0x14, 0xd1, 0x00, 0x29, ++ 0x12, 0xd1, 0x00, 0xe0, 0x55, 0xe0, 0x10, 0xa9, 0xc9, 0x8d, 0x00, 0x29, 0x0c, 0xd1, 0x00, 0x2c, ++ 0x0a, 0xd1, 0x10, 0xa9, 0x89, 0x8d, 0x00, 0x29, 0x06, 0xd1, 0x10, 0xa9, 0x80, 0x1e, 0x4a, 0x83, ++ 0x00, 0x06, 0xca, 0x85, 0x00, 0x0e, 0x44, 0xd0, 0x10, 0xa9, 0xc9, 0x8a, 0x00, 0x29, 0x29, 0xd1, ++ 0x10, 0xa9, 0x89, 0x8a, 0x00, 0x29, 0x25, 0xd1, 0x10, 0xad, 0x2d, 0x8f, 0x00, 0x2d, 0x10, 0xd1, ++ 0x00, 0x2b, 0x0e, 0xd1, 0x10, 0xad, 0xed, 0x8e, 0x00, 0x2d, 0x0a, 0xd1, 0x10, 0xad, 0x80, 0x1e, ++ 0xea, 0x82, 0x00, 0x06, 0x2a, 0x87, 0x00, 0x0e, 0x2b, 0xd0, 0x00, 0x2a, 0x12, 0xd1, 0x00, 0x29, ++ 0x10, 0xd1, 0x10, 0xa9, 0xc9, 0x8d, 0x00, 0x29, 0x0c, 0xd1, 0x00, 0x2c, 0x0a, 0xd1, 0x10, 0xa9, ++ 0x89, 0x8d, 0x00, 0x29, 0x06, 0xd1, 0x10, 0xa9, 0x80, 0x1e, 0xca, 0x82, 0x00, 0x06, 0xca, 0x85, ++ 0x00, 0x0e, 0x16, 0xd0, 0x10, 0xa8, 0x00, 0x8f, 0x00, 0x28, 0x12, 0xd1, 0x00, 0x2b, 0x10, 0xd1, ++ 0x10, 0xa8, 0xc0, 0x8e, 0x00, 0x28, 0x0c, 0xd1, 0x10, 0xa8, 0xc0, 0x8d, 0x00, 0x28, 0x08, 0xd1, ++ 0x00, 0x2c, 0x06, 0xd1, 0x10, 0xa8, 0x80, 0x8d, 0x00, 0x28, 0x02, 0xd1, 0x10, 0xa8, 0x02, 0x87, ++ 0xc2, 0x85, 0x22, 0x22, 0x1d, 0xa9, 0x0c, 0xa8, 0xf9, 0xf7, 0x1c, 0xfc, 0x6b, 0x46, 0x07, 0xcb, ++ 0x09, 0xab, 0x07, 0xc3, 0x14, 0x22, 0x26, 0xa9, 0x04, 0xa8, 0xf9, 0xf7, 0x13, 0xfc, 0x19, 0xac, ++ 0x0f, 0xcc, 0x6c, 0x46, 0x0f, 0xc4, 0x15, 0xac, 0x0f, 0xcc, 0xff, 0xf7, 0xb9, 0xfb, 0x2f, 0xb0, ++ 0xf0, 0xbd, 0xf8, 0xb5, 0x03, 0x24, 0x24, 0x07, 0xa5, 0x8a, 0xca, 0x4d, 0xa5, 0x82, 0x06, 0x07, ++ 0x36, 0x0f, 0xd5, 0x06, 0xed, 0x0c, 0x2e, 0x43, 0xc7, 0x4d, 0x2f, 0x68, 0xc7, 0x4d, 0x7f, 0x19, ++ 0x3e, 0x81, 0xa6, 0x8a, 0x3f, 0x26, 0xf6, 0x43, 0xa6, 0x82, 0xc3, 0x4f, 0x8e, 0x06, 0x3f, 0x68, ++ 0xb6, 0x0e, 0x7d, 0x19, 0x6e, 0x81, 0xa5, 0x8a, 0xc1, 0x4d, 0xa5, 0x82, 0x00, 0x2b, 0x05, 0xd0, ++ 0x00, 0x24, 0x65, 0x03, 0x00, 0x28, 0x03, 0xdd, 0x01, 0x24, 0x02, 0xe0, 0x01, 0x24, 0xf8, 0xe7, ++ 0x00, 0x24, 0x24, 0x03, 0x25, 0x43, 0x00, 0x2a, 0x01, 0xdd, 0x01, 0x24, 0x00, 0xe0, 0x00, 0x24, ++ 0xe4, 0x02, 0x25, 0x43, 0x00, 0x2b, 0x01, 0xdd, 0x01, 0x24, 0x00, 0xe0, 0x00, 0x24, 0xa4, 0x02, ++ 0x25, 0x43, 0xb1, 0x4c, 0x26, 0x68, 0xb1, 0x4f, 0x80, 0x37, 0xf6, 0x19, 0x75, 0x81, 0x03, 0x25, ++ 0x2d, 0x07, 0xae, 0x8a, 0x0f, 0x26, 0xf6, 0x43, 0xae, 0x82, 0x1d, 0x07, 0x24, 0x68, 0x2d, 0x0f, ++ 0xd1, 0x26, 0x76, 0x02, 0xa4, 0x19, 0x25, 0x84, 0xff, 0xf7, 0x4b, 0xfc, 0xf8, 0xbd, 0xfe, 0xb5, ++ 0x00, 0x20, 0x69, 0x46, 0x08, 0x81, 0xa4, 0x48, 0x01, 0x68, 0xa4, 0x4a, 0x40, 0x3a, 0x89, 0x18, ++ 0x49, 0x8d, 0x00, 0x68, 0xff, 0x30, 0x01, 0x30, 0x00, 0x8e, 0x69, 0x46, 0x08, 0x80, 0x00, 0x20, ++ 0x0d, 0x88, 0x84, 0x46, 0xa8, 0x04, 0x0c, 0x27, 0x30, 0x26, 0x00, 0x28, 0x0a, 0xda, 0x00, 0x20, ++ 0x02, 0x46, 0x3c, 0x21, 0x63, 0x46, 0xff, 0xf7, 0x94, 0xff, 0xb7, 0x43, 0x10, 0x37, 0xb8, 0x08, ++ 0x80, 0x00, 0x10, 0xe0, 0xe8, 0x04, 0x12, 0xd5, 0x96, 0x4b, 0x17, 0x20, 0x18, 0x22, 0x16, 0x21, ++ 0x18, 0x56, 0x9a, 0x56, 0x59, 0x56, 0x63, 0x46, 0xff, 0xf7, 0x83, 0xff, 0x04, 0x20, 0xb0, 0x43, ++ 0x10, 0x30, 0x80, 0x08, 0x80, 0x00, 0x69, 0x46, 0x40, 0x1c, 0x08, 0x81, 0xfe, 0xe0, 0xa8, 0x06, ++ 0xfc, 0xd0, 0x89, 0x4a, 0x10, 0x68, 0x89, 0x4b, 0xc0, 0x18, 0x40, 0x89, 0x81, 0x06, 0x10, 0x68, ++ 0x89, 0x0e, 0xc0, 0x18, 0x00, 0x89, 0x12, 0x68, 0x00, 0x07, 0x00, 0x0f, 0xd2, 0x18, 0x12, 0x89, ++ 0x2b, 0x07, 0xd2, 0x04, 0xd2, 0x0e, 0x00, 0x24, 0x9b, 0x0f, 0x01, 0x2b, 0x02, 0xd0, 0x02, 0x2b, ++ 0x18, 0xd0, 0x31, 0xe0, 0x49, 0x1c, 0x21, 0x29, 0x07, 0xdb, 0x3c, 0x29, 0x03, 0xdc, 0x43, 0x18, ++ 0x9b, 0x18, 0x3c, 0x2b, 0x01, 0xdd, 0x49, 0x1e, 0x17, 0xe0, 0x01, 0x24, 0x4b, 0x1c, 0x21, 0x2b, ++ 0x06, 0xdb, 0x3c, 0x2b, 0x1e, 0xdc, 0x43, 0x18, 0x9b, 0x18, 0x5b, 0x1c, 0x3c, 0x2b, 0x19, 0xdc, ++ 0x04, 0x27, 0x17, 0xe0, 0x08, 0x27, 0x49, 0x1e, 0x3c, 0x29, 0x08, 0xdc, 0x21, 0x29, 0x03, 0xdb, ++ 0x0b, 0x1a, 0x9b, 0x1a, 0x06, 0x2b, 0x02, 0xda, 0x49, 0x1c, 0x49, 0xb2, 0x0a, 0xe0, 0x01, 0x24, ++ 0x4b, 0x1e, 0x3c, 0x2b, 0xec, 0xdc, 0x21, 0x2b, 0x04, 0xdb, 0x0b, 0x1a, 0x9b, 0x1a, 0x5b, 0x1e, ++ 0x06, 0x2b, 0xe5, 0xda, 0x6b, 0x46, 0x1f, 0x81, 0xab, 0x06, 0x9b, 0x0f, 0x01, 0x2b, 0x02, 0xd0, ++ 0x02, 0x2b, 0x1a, 0xd0, 0x47, 0xe0, 0x52, 0x1e, 0x18, 0x2a, 0x07, 0xdc, 0x00, 0x2a, 0x05, 0xda, ++ 0x6f, 0x46, 0x3b, 0x89, 0x33, 0x43, 0x3b, 0x81, 0x52, 0x1c, 0x3c, 0xe0, 0x01, 0x24, 0x53, 0x1e, ++ 0x18, 0x2b, 0x05, 0xdc, 0x00, 0x2b, 0x03, 0xda, 0x6f, 0x46, 0x3b, 0x89, 0x33, 0x43, 0x31, 0xe0, ++ 0x6f, 0x46, 0x3b, 0x89, 0xb3, 0x43, 0x10, 0x33, 0x2c, 0xe0, 0x52, 0x1c, 0x13, 0xd4, 0x18, 0x2a, ++ 0x0a, 0xdc, 0x43, 0x18, 0x9b, 0x18, 0x3c, 0x2b, 0x06, 0xdc, 0x0b, 0x1a, 0x9b, 0x1a, 0x06, 0x2b, ++ 0x02, 0xdb, 0x83, 0x18, 0x18, 0x2b, 0x06, 0xdd, 0x6f, 0x46, 0x3b, 0x89, 0xb3, 0x43, 0x20, 0x33, ++ 0x3b, 0x81, 0x52, 0x1e, 0x17, 0xe0, 0x01, 0x24, 0x53, 0x1c, 0xe1, 0xd4, 0x18, 0x2b, 0x0d, 0xdc, ++ 0x43, 0x18, 0x9b, 0x18, 0x5b, 0x1c, 0x3c, 0x2b, 0x08, 0xdc, 0x0b, 0x1a, 0x9b, 0x1a, 0x5b, 0x1e, ++ 0x06, 0x2b, 0x03, 0xdb, 0x83, 0x18, 0x5b, 0x1c, 0x18, 0x2b, 0xd1, 0xdd, 0x6f, 0x46, 0x3b, 0x89, ++ 0xb3, 0x43, 0x20, 0x33, 0x3b, 0x81, 0xab, 0x07, 0x9b, 0x0f, 0x01, 0x2b, 0x02, 0xd0, 0x02, 0x2b, ++ 0x1d, 0xd0, 0x4c, 0xe0, 0x03, 0x26, 0x40, 0x1e, 0x0a, 0x28, 0x07, 0xdc, 0x00, 0x28, 0x05, 0xda, ++ 0x6f, 0x46, 0x3b, 0x89, 0x33, 0x43, 0x3b, 0x81, 0x40, 0x1c, 0x40, 0xe0, 0x01, 0x24, 0x43, 0x1e, ++ 0x0a, 0x2b, 0x06, 0xdc, 0x00, 0x2b, 0x04, 0xda, 0x6f, 0x46, 0x3b, 0x89, 0x33, 0x43, 0x3b, 0x81, ++ 0x35, 0xe0, 0x6e, 0x46, 0x33, 0x89, 0x9b, 0x08, 0x9b, 0x00, 0x5b, 0x1c, 0x2e, 0xe0, 0x40, 0x1c, ++ 0x14, 0xd4, 0x0a, 0x28, 0x0a, 0xdc, 0x43, 0x18, 0x9b, 0x18, 0x3c, 0x2b, 0x06, 0xdc, 0x0b, 0x1a, ++ 0x9b, 0x1a, 0x06, 0x2b, 0x02, 0xdb, 0x83, 0x18, 0x18, 0x2b, 0x07, 0xdd, 0x6e, 0x46, 0x33, 0x89, ++ 0x9b, 0x08, 0x9b, 0x00, 0x9b, 0x1c, 0x33, 0x81, 0x40, 0x1e, 0x18, 0xe0, 0x01, 0x24, 0x43, 0x1c, ++ 0xdf, 0xd4, 0x0a, 0x2b, 0x0d, 0xdc, 0x43, 0x18, 0x9b, 0x18, 0x5b, 0x1c, 0x3c, 0x2b, 0x08, 0xdc, ++ 0x0b, 0x1a, 0x9b, 0x1a, 0x5b, 0x1e, 0x06, 0x2b, 0x03, 0xdb, 0x83, 0x18, 0x5b, 0x1c, 0x18, 0x2b, ++ 0xcf, 0xdd, 0x6e, 0x46, 0x33, 0x89, 0x9b, 0x08, 0x9b, 0x00, 0x9b, 0x1c, 0x33, 0x81, 0x63, 0x46, ++ 0xff, 0xf7, 0x87, 0xfe, 0x00, 0x2c, 0x09, 0xd0, 0xa9, 0x06, 0x89, 0x0e, 0x01, 0x20, 0x01, 0x91, ++ 0x03, 0x46, 0x04, 0x22, 0x00, 0x90, 0x1f, 0x21, 0x00, 0xf0, 0xe6, 0xfc, 0x0a, 0x4a, 0x10, 0x68, ++ 0x0a, 0x4b, 0xc0, 0x18, 0x80, 0x89, 0xc1, 0x03, 0x68, 0x46, 0x00, 0x89, 0x40, 0x04, 0x40, 0x0c, ++ 0x08, 0x43, 0x99, 0x05, 0x8c, 0x8a, 0x00, 0x24, 0x8c, 0x82, 0x11, 0x68, 0xc9, 0x18, 0x48, 0x80, ++ 0xfe, 0xbd, 0x00, 0x00, 0xf0, 0xe0, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, 0xc0, 0xa0, 0x01, 0x00, ++ 0xff, 0xc3, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, 0xf0, 0xb5, 0xf9, 0x4a, 0x3e, 0x23, 0x11, 0x88, ++ 0x00, 0x25, 0x99, 0x43, 0xf4, 0x4c, 0xf5, 0x4e, 0x03, 0x00, 0x00, 0xf0, 0x09, 0xfe, 0x09, 0x06, ++ 0x37, 0x68, 0x99, 0xca, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0x00, 0x03, 0x20, 0x00, 0x07, 0x83, 0x8a, ++ 0x3f, 0x23, 0x9b, 0x02, 0x83, 0x82, 0xef, 0x4f, 0x48, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x3b, 0x86, ++ 0x83, 0x8a, 0x83, 0x13, 0x83, 0x82, 0xeb, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0xdd, 0x85, 0x83, 0x8a, ++ 0xe9, 0x4b, 0x83, 0x82, 0xe7, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x9d, 0x85, 0x83, 0x8a, 0x06, 0x23, ++ 0xdb, 0x43, 0x83, 0x82, 0xe3, 0x4f, 0x04, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x7b, 0x86, 0x83, 0x8a, ++ 0x86, 0x82, 0xe0, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x5d, 0x86, 0x83, 0x8a, 0x86, 0x82, 0xdd, 0x4b, ++ 0x01, 0x20, 0x1b, 0x68, 0x1b, 0x19, 0x58, 0x86, 0x2e, 0x31, 0x8c, 0xe1, 0x03, 0x20, 0x00, 0x07, ++ 0x83, 0x8a, 0x3f, 0x23, 0x9b, 0x02, 0x83, 0x82, 0xd6, 0x4f, 0x28, 0x23, 0x3f, 0x68, 0x3f, 0x19, ++ 0x3b, 0x86, 0x83, 0x8a, 0x83, 0x13, 0x83, 0x82, 0xd2, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0xdd, 0x85, ++ 0x83, 0x8a, 0xd1, 0x4b, 0x83, 0x82, 0xcf, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x9d, 0x85, 0x83, 0x8a, ++ 0x06, 0x23, 0xdb, 0x43, 0x83, 0x82, 0xcb, 0x4f, 0x04, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x7b, 0x86, ++ 0x83, 0x8a, 0x86, 0x82, 0xc7, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x5d, 0x86, 0x83, 0x8a, 0x86, 0x82, ++ 0xc4, 0x48, 0x01, 0x23, 0x00, 0x68, 0x00, 0x19, 0x43, 0x86, 0x89, 0x1d, 0x5b, 0xe1, 0x03, 0x20, ++ 0x00, 0x07, 0x83, 0x8a, 0x3f, 0x23, 0x9b, 0x02, 0x83, 0x82, 0xbe, 0x4f, 0x2a, 0x23, 0x3f, 0x68, ++ 0x3f, 0x19, 0x3b, 0x86, 0x83, 0x8a, 0x83, 0x13, 0x83, 0x82, 0xba, 0x4b, 0x1b, 0x68, 0x1b, 0x19, ++ 0xdd, 0x85, 0x83, 0x8a, 0xb8, 0x4b, 0x83, 0x82, 0xb6, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x9d, 0x85, ++ 0x83, 0x8a, 0x06, 0x23, 0xdb, 0x43, 0x83, 0x82, 0xb2, 0x4f, 0x04, 0x23, 0x3f, 0x68, 0x3f, 0x19, ++ 0x7b, 0x86, 0x83, 0x8a, 0x86, 0x82, 0xaf, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x5d, 0x86, 0x83, 0x8a, ++ 0x86, 0x82, 0xac, 0x4b, 0x01, 0x20, 0x1b, 0x68, 0x1b, 0x19, 0x58, 0x86, 0x08, 0x31, 0x2a, 0xe1, ++ 0x03, 0x20, 0x00, 0x07, 0x83, 0x8a, 0x3f, 0x23, 0x9b, 0x02, 0x83, 0x82, 0xa5, 0x4f, 0x34, 0x23, ++ 0x3f, 0x68, 0x3f, 0x19, 0x3b, 0x86, 0x83, 0x8a, 0x83, 0x13, 0x83, 0x82, 0xa1, 0x4b, 0x1b, 0x68, ++ 0x1b, 0x19, 0xdd, 0x85, 0x83, 0x8a, 0xa0, 0x4b, 0x83, 0x82, 0x9e, 0x4b, 0x1b, 0x68, 0x1b, 0x19, ++ 0x9d, 0x85, 0x83, 0x8a, 0x06, 0x23, 0xdb, 0x43, 0x83, 0x82, 0x9a, 0x4f, 0x04, 0x23, 0x3f, 0x68, ++ 0x3f, 0x19, 0x7b, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x96, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x5d, 0x86, ++ 0x83, 0x8a, 0x86, 0x82, 0x93, 0x4b, 0x01, 0x20, 0x1b, 0x68, 0x1b, 0x19, 0x58, 0x86, 0x16, 0x31, ++ 0xf9, 0xe0, 0x03, 0x20, 0x00, 0x07, 0x83, 0x8a, 0x3f, 0x23, 0x9b, 0x02, 0x83, 0x82, 0x8d, 0x4f, ++ 0x3c, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x3b, 0x86, 0x83, 0x8a, 0x83, 0x13, 0x83, 0x82, 0x89, 0x4b, ++ 0x1b, 0x68, 0x1b, 0x19, 0xdd, 0x85, 0x83, 0x8a, 0x87, 0x4b, 0x83, 0x82, 0x85, 0x4b, 0x1b, 0x68, ++ 0x1b, 0x19, 0x9d, 0x85, 0x83, 0x8a, 0x06, 0x23, 0xdb, 0x43, 0x83, 0x82, 0x81, 0x4f, 0x04, 0x23, ++ 0x3f, 0x68, 0x3f, 0x19, 0x7b, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x7e, 0x4b, 0x1b, 0x68, 0x1b, 0x19, ++ 0x5d, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x7b, 0x4b, 0x01, 0x20, 0x1b, 0x68, 0x1b, 0x19, 0x04, 0xe0, ++ 0xca, 0xe0, 0x98, 0xe0, 0x66, 0xe0, 0x34, 0xe0, 0x02, 0xe0, 0x58, 0x86, 0x20, 0x31, 0xc2, 0xe0, ++ 0x03, 0x20, 0x00, 0x07, 0x83, 0x8a, 0x3f, 0x23, 0x9b, 0x02, 0x83, 0x82, 0x71, 0x4f, 0x40, 0x23, ++ 0x3f, 0x68, 0x3f, 0x19, 0x3b, 0x86, 0x83, 0x8a, 0x83, 0x13, 0x83, 0x82, 0x6d, 0x4b, 0x1b, 0x68, ++ 0x1b, 0x19, 0xdd, 0x85, 0x83, 0x8a, 0x6c, 0x4b, 0x83, 0x82, 0x6a, 0x4b, 0x1b, 0x68, 0x1b, 0x19, ++ 0x9d, 0x85, 0x83, 0x8a, 0x06, 0x23, 0xdb, 0x43, 0x83, 0x82, 0x66, 0x4f, 0x04, 0x23, 0x3f, 0x68, ++ 0x3f, 0x19, 0x7b, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x62, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x5d, 0x86, ++ 0x83, 0x8a, 0x86, 0x82, 0x5f, 0x4b, 0x01, 0x20, 0x1b, 0x68, 0x1b, 0x19, 0x58, 0x86, 0x24, 0x31, ++ 0x91, 0xe0, 0x03, 0x20, 0x00, 0x07, 0x83, 0x8a, 0x3f, 0x23, 0x9b, 0x02, 0x83, 0x82, 0x59, 0x4f, ++ 0x42, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x3b, 0x86, 0x83, 0x8a, 0x83, 0x13, 0x83, 0x82, 0x55, 0x4b, ++ 0x1b, 0x68, 0x1b, 0x19, 0xdd, 0x85, 0x83, 0x8a, 0x53, 0x4b, 0x83, 0x82, 0x51, 0x4b, 0x1b, 0x68, ++ 0x1b, 0x19, 0x9d, 0x85, 0x83, 0x8a, 0x06, 0x23, 0xdb, 0x43, 0x83, 0x82, 0x4d, 0x4f, 0x04, 0x23, ++ 0x3f, 0x68, 0x3f, 0x19, 0x7b, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x4a, 0x4b, 0x1b, 0x68, 0x1b, 0x19, ++ 0x5d, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x47, 0x4b, 0x01, 0x20, 0x1b, 0x68, 0x1b, 0x19, 0x58, 0x86, ++ 0x26, 0x31, 0x60, 0xe0, 0x03, 0x20, 0x00, 0x07, 0x83, 0x8a, 0x3f, 0x23, 0x9b, 0x02, 0x83, 0x82, ++ 0x40, 0x4f, 0x46, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x3b, 0x86, 0x83, 0x8a, 0x83, 0x13, 0x83, 0x82, ++ 0x3c, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0xdd, 0x85, 0x83, 0x8a, 0x3b, 0x4b, 0x83, 0x82, 0x39, 0x4b, ++ 0x1b, 0x68, 0x1b, 0x19, 0x9d, 0x85, 0x83, 0x8a, 0x06, 0x23, 0xdb, 0x43, 0x83, 0x82, 0x35, 0x4f, ++ 0x04, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x7b, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x31, 0x4b, 0x1b, 0x68, ++ 0x1b, 0x19, 0x5d, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x2e, 0x4b, 0x01, 0x20, 0x1b, 0x68, 0x1b, 0x19, ++ 0x58, 0x86, 0x2c, 0x31, 0x2f, 0xe0, 0x03, 0x20, 0x00, 0x07, 0x83, 0x8a, 0x3f, 0x23, 0x9b, 0x02, ++ 0x83, 0x82, 0x28, 0x4f, 0x50, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x3b, 0x86, 0x83, 0x8a, 0x83, 0x13, ++ 0x83, 0x82, 0x24, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0xdd, 0x85, 0x83, 0x8a, 0x22, 0x4b, 0x83, 0x82, ++ 0x20, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x9d, 0x85, 0x83, 0x8a, 0x06, 0x23, 0xdb, 0x43, 0x83, 0x82, ++ 0x1c, 0x4f, 0x04, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x7b, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x19, 0x4b, ++ 0x1b, 0x68, 0x1b, 0x19, 0x5d, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x16, 0x4b, 0x01, 0x20, 0x1b, 0x68, ++ 0x1b, 0x19, 0x58, 0x86, 0x38, 0x31, 0x11, 0x80, 0xf0, 0xbd, 0x00, 0xb5, 0x03, 0x00, 0x00, 0xf0, ++ 0x3f, 0xfc, 0x2b, 0x17, 0x29, 0x29, 0x29, 0x29, 0x17, 0x29, 0x17, 0x29, 0x29, 0x29, 0x19, 0x2d, ++ 0x2b, 0x29, 0x29, 0x29, 0x29, 0x25, 0x25, 0x25, 0x25, 0x19, 0x19, 0x17, 0x17, 0x17, 0x17, 0x17, ++ 0x27, 0x17, 0x17, 0x27, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x29, 0x29, 0x29, 0x17, 0x00, ++ 0x06, 0x20, 0x14, 0xe0, 0x03, 0x20, 0x12, 0xe0, 0x40, 0xa1, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, ++ 0x00, 0x04, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, 0xff, 0x0f, 0x00, 0x00, 0x02, 0x20, 0x06, 0xe0, ++ 0x07, 0x20, 0x04, 0xe0, 0x08, 0x20, 0x02, 0xe0, 0x05, 0x20, 0x00, 0xe0, 0x04, 0x20, 0xff, 0xf7, ++ 0xfb, 0xfd, 0x00, 0xbd, 0xf0, 0xb5, 0x4d, 0x48, 0x00, 0x21, 0x00, 0x68, 0x4c, 0x4a, 0x80, 0x18, ++ 0x02, 0x8a, 0x8c, 0x27, 0xd3, 0x05, 0xde, 0x0f, 0xd0, 0xb2, 0x93, 0x05, 0x52, 0x05, 0xd5, 0x0f, ++ 0x48, 0x4a, 0xdb, 0x0f, 0x12, 0x68, 0xdb, 0x01, 0x14, 0x88, 0xbc, 0x43, 0x1c, 0x43, 0x14, 0x80, ++ 0x0d, 0x28, 0x26, 0xd0, 0x0a, 0xdc, 0x03, 0x00, 0x00, 0xf0, 0xf2, 0xfb, 0x0d, 0x29, 0x2b, 0x2b, ++ 0x2b, 0x2b, 0x29, 0x27, 0x2c, 0x27, 0x27, 0x27, 0x23, 0x23, 0x2c, 0x00, 0x36, 0x28, 0x1e, 0xd0, ++ 0x0e, 0xdc, 0x11, 0x28, 0x15, 0xd0, 0x06, 0xdc, 0x0e, 0x28, 0x12, 0xd0, 0x0f, 0x28, 0x10, 0xd0, ++ 0x10, 0x28, 0x17, 0xd1, 0x0d, 0xe0, 0x31, 0x28, 0x0b, 0xd0, 0x35, 0x28, 0x12, 0xd1, 0x0e, 0xe0, ++ 0x07, 0x46, 0x37, 0x3f, 0x3b, 0x00, 0x00, 0xf0, 0xd3, 0xfb, 0x05, 0x0a, 0x06, 0x06, 0x06, 0x06, ++ 0x0d, 0x00, 0x01, 0x21, 0x06, 0xe0, 0x03, 0x21, 0x04, 0xe0, 0x04, 0x21, 0x02, 0xe0, 0x08, 0x21, ++ 0x00, 0xe0, 0x09, 0x21, 0x1b, 0x28, 0x23, 0xd0, 0x17, 0x28, 0x21, 0xd0, 0x15, 0x28, 0x1f, 0xd0, ++ 0x13, 0x28, 0x1d, 0xd0, 0x11, 0x28, 0x1b, 0xd0, 0x19, 0x28, 0x19, 0xd0, 0x1a, 0x28, 0x17, 0xd0, ++ 0x16, 0x28, 0x15, 0xd0, 0x14, 0x28, 0x13, 0xd0, 0x12, 0x28, 0x11, 0xd0, 0x1c, 0x28, 0x0f, 0xd0, ++ 0x1e, 0x28, 0x0d, 0xd0, 0x1f, 0x28, 0x0b, 0xd0, 0x21, 0x28, 0x09, 0xd0, 0x22, 0x28, 0x07, 0xd0, ++ 0x24, 0x28, 0x05, 0xd0, 0x28, 0x28, 0x03, 0xd0, 0x29, 0x28, 0x01, 0xd0, 0x2a, 0x28, 0x02, 0xd1, ++ 0x04, 0x20, 0x04, 0x43, 0x14, 0x80, 0x03, 0x20, 0x00, 0x07, 0x82, 0x8a, 0x0f, 0x22, 0xd2, 0x43, ++ 0x82, 0x82, 0x12, 0x4a, 0x14, 0x68, 0x14, 0x4b, 0xe4, 0x18, 0x21, 0x80, 0x81, 0x8a, 0x13, 0x49, ++ 0x81, 0x82, 0x14, 0x68, 0x49, 0x1c, 0xe3, 0x18, 0x19, 0x80, 0x81, 0x8a, 0x10, 0x49, 0x81, 0x82, ++ 0x14, 0x68, 0x73, 0x00, 0x0d, 0x26, 0x76, 0x03, 0xa4, 0x19, 0x23, 0x84, 0x83, 0x8a, 0x81, 0x82, ++ 0x10, 0x68, 0x69, 0x00, 0xff, 0x30, 0x01, 0x30, 0x81, 0x85, 0xf0, 0xbd, 0x03, 0x48, 0x00, 0x68, ++ 0x05, 0x49, 0xc0, 0x31, 0x40, 0x18, 0x40, 0x8e, 0xc0, 0xb2, 0x2e, 0xe7, 0x84, 0x00, 0x00, 0x20, ++ 0xc0, 0xa2, 0x01, 0x00, 0x90, 0x00, 0x00, 0x20, 0x00, 0xa1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x00, ++ 0xfd, 0xff, 0x00, 0x00, 0x31, 0x48, 0x00, 0x79, 0xc0, 0x07, 0xc0, 0x0f, 0x70, 0x47, 0x2f, 0x48, ++ 0x01, 0x78, 0x8f, 0x22, 0x11, 0x40, 0x01, 0x70, 0x01, 0x79, 0x01, 0x78, 0x01, 0x22, 0x11, 0x43, ++ 0x01, 0x70, 0x70, 0x47, 0x29, 0x48, 0x80, 0x68, 0x70, 0x47, 0x28, 0x48, 0x00, 0x89, 0x80, 0xb2, ++ 0x70, 0x47, 0x70, 0x47, 0x03, 0x20, 0x00, 0x07, 0x00, 0x8a, 0x80, 0x05, 0x80, 0x0d, 0x70, 0x47, ++ 0x23, 0x49, 0x09, 0x68, 0x80, 0x31, 0x89, 0x7c, 0x09, 0x07, 0x09, 0x0e, 0x8a, 0x00, 0x1f, 0x49, ++ 0x40, 0x31, 0x51, 0x18, 0x88, 0x60, 0x08, 0x78, 0x8f, 0x22, 0x10, 0x40, 0x10, 0x30, 0x08, 0x70, ++ 0x08, 0x78, 0x01, 0x22, 0x10, 0x43, 0x08, 0x70, 0x70, 0x47, 0x19, 0x48, 0x00, 0x68, 0x80, 0x30, ++ 0x80, 0x7c, 0x00, 0x07, 0x00, 0x0e, 0x81, 0x00, 0x14, 0x48, 0x40, 0x30, 0x08, 0x18, 0x01, 0x78, ++ 0x02, 0x22, 0x11, 0x43, 0x01, 0x70, 0x70, 0x47, 0x11, 0x48, 0x10, 0x49, 0x00, 0x68, 0x40, 0x31, ++ 0x80, 0x30, 0x80, 0x7c, 0x00, 0x07, 0x00, 0x0e, 0x80, 0x00, 0x40, 0x18, 0xc0, 0x68, 0x70, 0x47, ++ 0x0b, 0x48, 0x0a, 0x49, 0x00, 0x68, 0x40, 0x31, 0x80, 0x30, 0x80, 0x7c, 0x00, 0x07, 0x00, 0x0e, ++ 0x80, 0x00, 0x40, 0x18, 0x00, 0x79, 0xc0, 0x07, 0xc0, 0x0f, 0x70, 0x47, 0x03, 0x21, 0x09, 0x07, ++ 0x08, 0x60, 0x08, 0x7b, 0x01, 0x22, 0x10, 0x43, 0x08, 0x73, 0x70, 0x47, 0xc0, 0x00, 0x00, 0x30, ++ 0x90, 0x00, 0x00, 0x20, 0x10, 0xb5, 0x72, 0xb6, 0x56, 0x49, 0xc8, 0x69, 0xff, 0x22, 0x12, 0x04, ++ 0x90, 0x43, 0x01, 0x22, 0x92, 0x05, 0x10, 0x43, 0xc8, 0x61, 0x54, 0x48, 0x52, 0x49, 0x41, 0x60, ++ 0x81, 0x60, 0x00, 0x20, 0x52, 0x4a, 0x01, 0x21, 0xc4, 0x06, 0xe4, 0x0e, 0x0b, 0x46, 0xa3, 0x40, ++ 0x44, 0x09, 0xa4, 0x00, 0xa4, 0x18, 0x23, 0x60, 0x40, 0x1c, 0x40, 0xb2, 0x0c, 0x28, 0xf3, 0xdb, ++ 0x4c, 0x4a, 0x04, 0x20, 0xc4, 0x06, 0xe4, 0x0e, 0x0b, 0x46, 0xa3, 0x40, 0x44, 0x09, 0xa4, 0x00, ++ 0xa4, 0x18, 0x23, 0x60, 0x40, 0x1c, 0x40, 0xb2, 0x0c, 0x28, 0xf3, 0xdb, 0x62, 0xb6, 0x10, 0xbd, ++ 0xfe, 0xb5, 0x45, 0x4c, 0x21, 0x68, 0x00, 0x91, 0x44, 0x4d, 0x45, 0x4f, 0x2e, 0x68, 0x39, 0x68, ++ 0x01, 0x91, 0x01, 0x02, 0x43, 0x4a, 0x80, 0x07, 0x89, 0x18, 0x29, 0x60, 0x21, 0x68, 0xfa, 0x12, ++ 0x91, 0x43, 0x40, 0x0b, 0x01, 0x43, 0x21, 0x60, 0xff, 0xf7, 0x51, 0xfb, 0x00, 0x98, 0x20, 0x60, ++ 0x2e, 0x60, 0x01, 0x98, 0x38, 0x60, 0xfe, 0xbd, 0xfe, 0xb5, 0x37, 0x4c, 0x21, 0x68, 0x00, 0x91, ++ 0x36, 0x4d, 0x37, 0x4f, 0x2e, 0x68, 0x39, 0x68, 0x01, 0x91, 0x01, 0x02, 0x35, 0x4a, 0x80, 0x07, ++ 0x89, 0x18, 0x29, 0x60, 0x21, 0x68, 0xfa, 0x12, 0x91, 0x43, 0x40, 0x0b, 0x01, 0x43, 0x21, 0x60, ++ 0xfe, 0xf7, 0x3c, 0xfe, 0x00, 0x98, 0x20, 0x60, 0x2e, 0x60, 0x01, 0x98, 0x38, 0x60, 0xfe, 0xbd, ++ 0x10, 0xb5, 0x00, 0x22, 0x11, 0x46, 0x01, 0x98, 0x00, 0xf0, 0xc0, 0xf8, 0x10, 0xbd, 0x10, 0xb5, ++ 0x00, 0x22, 0x11, 0x46, 0x01, 0x98, 0x00, 0xf0, 0xb9, 0xf8, 0x10, 0xbd, 0x10, 0xb5, 0x00, 0x22, ++ 0x11, 0x46, 0x01, 0x98, 0x00, 0xf0, 0xb2, 0xf8, 0x10, 0xbd, 0x10, 0xb5, 0x00, 0x22, 0x11, 0x46, ++ 0x01, 0x98, 0x00, 0xf0, 0xab, 0xf8, 0x10, 0xbd, 0x10, 0xb5, 0x00, 0x22, 0x11, 0x46, 0x01, 0x98, ++ 0x00, 0xf0, 0xa4, 0xf8, 0x10, 0xbd, 0x10, 0xb5, 0x00, 0x22, 0x11, 0x46, 0x01, 0x98, 0x00, 0xf0, ++ 0x9d, 0xf8, 0x10, 0xbd, 0x18, 0x48, 0x40, 0x7e, 0x9a, 0xe7, 0x17, 0x48, 0x80, 0x7e, 0x97, 0xe7, ++ 0x15, 0x48, 0xc0, 0x7e, 0x94, 0xe7, 0x14, 0x48, 0x00, 0x7f, 0x91, 0xe7, 0x12, 0x48, 0x40, 0x7e, ++ 0xaa, 0xe7, 0x11, 0x48, 0x80, 0x7e, 0xa7, 0xe7, 0x0f, 0x48, 0xc0, 0x7e, 0xa4, 0xe7, 0x0e, 0x48, ++ 0x00, 0x7f, 0xa1, 0xe7, 0x10, 0xb5, 0x00, 0x22, 0x11, 0x46, 0x01, 0x98, 0x00, 0xf0, 0x7e, 0xf8, ++ 0x10, 0xbd, 0x00, 0x00, 0x04, 0xed, 0x00, 0xe0, 0x80, 0x80, 0x80, 0x80, 0x00, 0xe4, 0x00, 0xe0, ++ 0x80, 0xe2, 0x00, 0xe0, 0x00, 0xe1, 0x00, 0xe0, 0x84, 0x00, 0x00, 0x20, 0x90, 0x00, 0x00, 0x20, ++ 0x14, 0x00, 0x00, 0x30, 0x00, 0x05, 0x00, 0x20, 0x00, 0x04, 0x00, 0x20, 0x10, 0xb5, 0xff, 0x21, ++ 0x01, 0x31, 0x2b, 0x48, 0x00, 0xf0, 0xf6, 0xf9, 0x10, 0xbd, 0xc1, 0x08, 0x10, 0xb5, 0x09, 0x1d, ++ 0x1f, 0x28, 0x13, 0xd8, 0x72, 0xb6, 0x27, 0x4a, 0x25, 0x4b, 0x12, 0x68, 0x80, 0x32, 0x92, 0x7c, ++ 0x92, 0x01, 0x9c, 0x5c, 0x01, 0x2c, 0x00, 0xd1, 0x09, 0x1d, 0xd2, 0x18, 0x44, 0x07, 0x53, 0x5c, ++ 0x64, 0x0f, 0x01, 0x20, 0xa0, 0x40, 0x03, 0x43, 0x53, 0x54, 0x62, 0xb6, 0x10, 0xbd, 0xf0, 0xb5, ++ 0x1c, 0x49, 0x1b, 0x4e, 0x0b, 0x68, 0x80, 0x33, 0x99, 0x7c, 0x89, 0x01, 0x8d, 0x19, 0xa9, 0x78, ++ 0xff, 0x29, 0x2c, 0xd0, 0x6a, 0x78, 0xfe, 0x29, 0x04, 0xd0, 0x8f, 0x1a, 0x91, 0x42, 0x03, 0xd8, ++ 0x0d, 0x24, 0x02, 0xe0, 0x02, 0x24, 0x02, 0xe0, 0x00, 0x24, 0x3c, 0x19, 0x64, 0x1e, 0x24, 0x06, ++ 0x24, 0x0e, 0x1c, 0xd0, 0x01, 0x2c, 0x00, 0xd1, 0xa0, 0x1e, 0x94, 0x00, 0x2c, 0x19, 0x52, 0x1c, ++ 0xe0, 0x60, 0xd0, 0xb2, 0x0d, 0x28, 0x00, 0xd3, 0x00, 0x20, 0x9a, 0x7c, 0x92, 0x01, 0x92, 0x19, ++ 0x50, 0x70, 0xfe, 0x29, 0x0b, 0xd1, 0x99, 0x7c, 0x89, 0x01, 0x8a, 0x19, 0xd1, 0x78, 0x81, 0x42, ++ 0x05, 0xd1, 0x49, 0x1c, 0xc8, 0xb2, 0x0d, 0x28, 0x00, 0xd3, 0x00, 0x20, 0xd0, 0x70, 0xf0, 0xbd, ++ 0x00, 0x09, 0x00, 0x20, 0x90, 0x00, 0x00, 0x20, 0x10, 0xb5, 0x20, 0x21, 0x37, 0x48, 0x00, 0xf0, ++ 0x99, 0xf9, 0x20, 0x21, 0x36, 0x48, 0x00, 0xf0, 0x95, 0xf9, 0x10, 0xbd, 0x72, 0xb6, 0xbf, 0xf3, ++ 0x40, 0x8f, 0x34, 0x4b, 0x20, 0x25, 0x1c, 0x7c, 0x2c, 0x43, 0x1c, 0x74, 0xef, 0xf3, 0x05, 0x83, ++ 0x2e, 0x4c, 0x9b, 0x06, 0x9b, 0x0e, 0x25, 0x78, 0x23, 0x70, 0x00, 0x2d, 0x09, 0xd1, 0xa3, 0x70, ++ 0xa0, 0x60, 0xef, 0xf3, 0x08, 0x80, 0xe0, 0x60, 0xef, 0xf3, 0x09, 0x80, 0xe2, 0x61, 0xa1, 0x61, ++ 0x20, 0x61, 0x01, 0x20, 0x10, 0x2b, 0x06, 0xd3, 0x02, 0x46, 0x10, 0x3b, 0x61, 0x69, 0x9a, 0x40, ++ 0x11, 0x43, 0x61, 0x61, 0x04, 0xe0, 0x02, 0x46, 0x61, 0x68, 0x9a, 0x40, 0x11, 0x43, 0x61, 0x60, ++ 0x00, 0x21, 0x61, 0x70, 0xbf, 0xf3, 0x40, 0x8f, 0x62, 0xb6, 0xe1, 0x78, 0x01, 0x43, 0xe1, 0x70, ++ 0xfe, 0xe7, 0xf0, 0xb5, 0x05, 0x9d, 0x72, 0xb6, 0xbf, 0xf3, 0x40, 0x8f, 0x19, 0x4c, 0x40, 0x27, ++ 0x26, 0x7c, 0x3e, 0x43, 0x26, 0x74, 0x16, 0x4c, 0x26, 0x78, 0x20, 0x70, 0x00, 0x2e, 0x09, 0xd1, ++ 0xa0, 0x70, 0xa1, 0x60, 0xef, 0xf3, 0x08, 0x81, 0xe1, 0x60, 0xef, 0xf3, 0x09, 0x81, 0xe5, 0x61, ++ 0xa3, 0x61, 0x21, 0x61, 0x01, 0x21, 0x20, 0x28, 0x06, 0xd3, 0x0d, 0x46, 0x20, 0x38, 0x63, 0x69, ++ 0x85, 0x40, 0x2b, 0x43, 0x63, 0x61, 0x04, 0xe0, 0x0b, 0x46, 0x65, 0x68, 0x83, 0x40, 0x1d, 0x43, ++ 0x65, 0x60, 0x00, 0x20, 0x60, 0x70, 0xbf, 0xf3, 0x40, 0x8f, 0x62, 0xb6, 0x00, 0x2a, 0x03, 0xd0, ++ 0xe0, 0x78, 0x08, 0x43, 0xe0, 0x70, 0xfe, 0xe7, 0xf0, 0xbd, 0x00, 0x00, 0x24, 0x04, 0x00, 0x20, ++ 0x44, 0x04, 0x00, 0x20, 0x00, 0x04, 0x00, 0x20, 0xf0, 0xb5, 0x4c, 0x4d, 0x0a, 0x21, 0x69, 0x5e, ++ 0x00, 0x22, 0x4b, 0x4e, 0x4b, 0x4b, 0x4c, 0x4f, 0x0a, 0xe0, 0xb4, 0x5c, 0x5c, 0x54, 0x40, 0x1e, ++ 0x52, 0x1c, 0x49, 0x1e, 0x09, 0xb2, 0xc0, 0xb2, 0xd2, 0xb2, 0x00, 0x29, 0x00, 0xda, 0x39, 0x46, ++ 0x00, 0x28, 0xf2, 0xd1, 0x69, 0x81, 0xf0, 0xbd, 0xff, 0xb5, 0x81, 0xb0, 0x05, 0x46, 0x04, 0x98, ++ 0x0b, 0x9e, 0x00, 0x28, 0x00, 0xd1, 0x72, 0xb6, 0x3c, 0x49, 0x48, 0x7b, 0xff, 0x28, 0x02, 0xd1, ++ 0x4b, 0x89, 0x08, 0x2b, 0x01, 0xd3, 0x01, 0x24, 0x00, 0xe0, 0x00, 0x24, 0x02, 0x9b, 0x5b, 0x1e, ++ 0x2f, 0x2b, 0x52, 0xd2, 0x00, 0x2c, 0x50, 0xd0, 0x34, 0x49, 0x49, 0x7d, 0x00, 0x29, 0x4c, 0xd1, ++ 0x01, 0x2d, 0x02, 0xd0, 0x00, 0x2d, 0x03, 0xd0, 0x04, 0xe0, 0x34, 0x48, 0x00, 0x68, 0x40, 0x79, ++ 0x90, 0x42, 0x42, 0xd3, 0xff, 0xf7, 0xce, 0xfd, 0x07, 0x46, 0x01, 0x0c, 0x30, 0x48, 0x00, 0x68, ++ 0x00, 0x0c, 0x08, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x12, 0xd0, 0x29, 0x49, 0xff, 0x22, 0x8a, 0x70, ++ 0x02, 0x0a, 0x4a, 0x70, 0x08, 0x70, 0x03, 0x20, 0xff, 0xf7, 0xae, 0xff, 0x23, 0x48, 0x41, 0x7b, ++ 0xff, 0x29, 0x04, 0xd1, 0x40, 0x89, 0x08, 0x28, 0x01, 0xd2, 0x00, 0x24, 0x00, 0xe0, 0x01, 0x24, ++ 0x23, 0x48, 0x00, 0x2c, 0x07, 0x60, 0x20, 0xd0, 0x01, 0x2d, 0x24, 0xd0, 0x00, 0x2d, 0x27, 0xd0, ++ 0x08, 0x24, 0x0a, 0x98, 0x00, 0x28, 0x08, 0xd0, 0x19, 0x48, 0x31, 0x0a, 0x06, 0x70, 0x41, 0x70, ++ 0x31, 0x0c, 0x81, 0x70, 0x0a, 0x98, 0xff, 0xf7, 0x8f, 0xff, 0x0a, 0x98, 0x14, 0x49, 0x00, 0x1d, ++ 0x40, 0x01, 0x20, 0x43, 0xc8, 0x70, 0x16, 0x48, 0x00, 0x88, 0x02, 0x0a, 0x8a, 0x70, 0x48, 0x70, ++ 0x02, 0x98, 0x08, 0x70, 0x04, 0x20, 0xff, 0xf7, 0x7f, 0xff, 0x04, 0x98, 0x00, 0x28, 0x00, 0xd1, ++ 0x62, 0xb6, 0x05, 0xb0, 0xf0, 0xbd, 0x0d, 0x48, 0x00, 0x68, 0x80, 0x30, 0x84, 0x7c, 0xd8, 0xe7, ++ 0x0f, 0x24, 0xd6, 0xe7, 0x1c, 0xb5, 0x0a, 0x46, 0x00, 0x21, 0x00, 0x91, 0x0b, 0x46, 0x01, 0x91, ++ 0x01, 0x46, 0x01, 0x20, 0xff, 0xf7, 0x80, 0xff, 0x1c, 0xbd, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, ++ 0x8c, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x20, 0xff, 0x02, 0x00, 0x00, 0x90, 0x00, 0x00, 0x20, ++ 0x88, 0x00, 0x00, 0x20, 0x30, 0xb5, 0x0e, 0x49, 0x00, 0x20, 0x09, 0x78, 0x0b, 0x4d, 0x4c, 0x1e, ++ 0x11, 0xe0, 0x02, 0x02, 0x52, 0x19, 0x80, 0x32, 0x90, 0x74, 0x00, 0x28, 0x05, 0xd0, 0x43, 0x1e, ++ 0x13, 0x75, 0xa0, 0x42, 0x03, 0xd1, 0x00, 0x23, 0x02, 0xe0, 0x23, 0x46, 0xf8, 0xe7, 0x43, 0x1c, ++ 0x40, 0x1c, 0xd3, 0x74, 0xc0, 0xb2, 0x88, 0x42, 0xeb, 0xd3, 0x30, 0xbd, 0x00, 0x05, 0x00, 0x20, ++ 0x80, 0x00, 0x00, 0x20, 0x70, 0x47, 0xf8, 0xb5, 0x04, 0x2a, 0x2c, 0xd3, 0x83, 0x07, 0x12, 0xd0, ++ 0x0b, 0x78, 0x49, 0x1c, 0x03, 0x70, 0x40, 0x1c, 0x52, 0x1e, 0x83, 0x07, 0x0b, 0xd0, 0x0b, 0x78, ++ 0x49, 0x1c, 0x03, 0x70, 0x40, 0x1c, 0x52, 0x1e, 0x83, 0x07, 0x04, 0xd0, 0x0b, 0x78, 0x49, 0x1c, ++ 0x03, 0x70, 0x40, 0x1c, 0x52, 0x1e, 0x8b, 0x07, 0x9b, 0x0f, 0x05, 0xd0, 0xc9, 0x1a, 0xdf, 0x00, ++ 0x20, 0x23, 0xde, 0x1b, 0x08, 0xc9, 0x0a, 0xe0, 0xf8, 0xf7, 0xcc, 0xfc, 0xf8, 0xbd, 0x1d, 0x46, ++ 0x08, 0xc9, 0xfd, 0x40, 0x1c, 0x46, 0xb4, 0x40, 0x2c, 0x43, 0x10, 0xc0, 0x12, 0x1f, 0x04, 0x2a, ++ 0xf5, 0xd2, 0xf3, 0x08, 0xc9, 0x1a, 0x52, 0x1e, 0xf0, 0xd4, 0x0b, 0x78, 0x49, 0x1c, 0x03, 0x70, ++ 0x40, 0x1c, 0x52, 0x1e, 0xea, 0xd4, 0x0b, 0x78, 0x49, 0x1c, 0x03, 0x70, 0x40, 0x1c, 0x01, 0x2a, ++ 0xe4, 0xd4, 0x09, 0x78, 0x01, 0x70, 0xf8, 0xbd, 0x01, 0xe0, 0x04, 0xc0, 0x09, 0x1f, 0x04, 0x29, ++ 0xfb, 0xd2, 0x8b, 0x07, 0x01, 0xd5, 0x02, 0x80, 0x80, 0x1c, 0xc9, 0x07, 0x00, 0xd0, 0x02, 0x70, ++ 0x70, 0x47, 0x00, 0x29, 0x0b, 0xd0, 0xc3, 0x07, 0x02, 0xd0, 0x02, 0x70, 0x40, 0x1c, 0x49, 0x1e, ++ 0x02, 0x29, 0x04, 0xd3, 0x83, 0x07, 0x02, 0xd5, 0x02, 0x80, 0x80, 0x1c, 0x89, 0x1e, 0xe3, 0xe7, ++ 0x00, 0x22, 0xee, 0xe7, 0x00, 0x22, 0xdf, 0xe7, 0x03, 0x78, 0xc2, 0x78, 0x19, 0x46, 0x43, 0x78, ++ 0x12, 0x06, 0x1b, 0x02, 0x19, 0x43, 0x83, 0x78, 0xc0, 0x78, 0x1b, 0x04, 0x19, 0x43, 0x11, 0x43, ++ 0x09, 0x02, 0x09, 0x0a, 0x00, 0x06, 0x08, 0x43, 0x70, 0x47, 0x70, 0x47, 0x75, 0x46, 0x00, 0xf0, ++ 0x23, 0xf8, 0xae, 0x46, 0x05, 0x00, 0x69, 0x46, 0x53, 0x46, 0xc0, 0x08, 0xc0, 0x00, 0x85, 0x46, ++ 0x18, 0xb0, 0x20, 0xb5, 0xf8, 0xf7, 0x9e, 0xfc, 0x60, 0xbc, 0x00, 0x27, 0x49, 0x08, 0xb6, 0x46, ++ 0x00, 0x26, 0xc0, 0xc5, 0xc0, 0xc5, 0xc0, 0xc5, 0xc0, 0xc5, 0xc0, 0xc5, 0xc0, 0xc5, 0xc0, 0xc5, ++ 0xc0, 0xc5, 0x40, 0x3d, 0x49, 0x00, 0x8d, 0x46, 0x70, 0x47, 0x04, 0x46, 0xc0, 0x46, 0xc0, 0x46, ++ 0x20, 0x46, 0xf8, 0xf7, 0x50, 0xfc, 0x00, 0x00, 0x00, 0x48, 0x70, 0x47, 0x94, 0x00, 0x00, 0x20, ++ 0x30, 0xb4, 0x74, 0x46, 0x64, 0x1e, 0x25, 0x78, 0x64, 0x1c, 0xab, 0x42, 0x00, 0xd2, 0x1d, 0x46, ++ 0x63, 0x5d, 0x5b, 0x00, 0xe3, 0x18, 0x30, 0xbc, 0x18, 0x47, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, ++ 0x19, 0x19, 0x19, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x1a, 0x22, ++ 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x30, ++ 0x31, 0x31, 0x32, 0x32, 0x21, 0x10, 0x42, 0x20, 0x84, 0x40, 0x08, 0x81, 0x31, 0x12, 0x62, 0x24, ++ 0xc4, 0x48, 0x88, 0x91, 0x00, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x1f, 0x00, 0x29, 0x00, 0x34, 0x00, ++ 0x3e, 0x00, 0x49, 0x00, 0x53, 0x00, 0x5d, 0x00, 0x68, 0x00, 0x72, 0x00, 0x7c, 0x00, 0x87, 0x00, ++ 0x91, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0xb0, 0x00, 0xba, 0x00, 0xc5, 0x00, 0xcf, 0x00, 0xda, 0x00, ++ 0xe4, 0x00, 0xee, 0x00, 0xf9, 0x00, 0x03, 0x01, 0x0d, 0x01, 0x18, 0x01, 0x22, 0x01, 0x2c, 0x01, ++ 0x37, 0x01, 0x41, 0x01, 0x00, 0x00, 0x11, 0x00, 0x23, 0x00, 0x34, 0x00, 0x46, 0x00, 0x57, 0x00, ++ 0x69, 0x00, 0x7a, 0x00, 0x8c, 0x00, 0x9d, 0x00, 0xaf, 0x00, 0xc0, 0x00, 0xd2, 0x00, 0xe3, 0x00, ++ 0xf5, 0x00, 0x06, 0x01, 0x18, 0x01, 0x29, 0x01, 0x3b, 0x01, 0x4c, 0x01, 0x5d, 0x01, 0x6f, 0x01, ++ 0x80, 0x01, 0x92, 0x01, 0xa3, 0x01, 0xb5, 0x01, 0xc6, 0x01, 0xd8, 0x01, 0xe9, 0x01, 0xfb, 0x01, ++ 0x0c, 0x02, 0x1e, 0x02, 0x74, 0x7a, 0x00, 0x00, 0x80, 0x00, 0x00, 0x20, 0x14, 0x00, 0x00, 0x00, ++ 0xc4, 0x01, 0x00, 0x00, 0x88, 0x7a, 0x00, 0x00, 0x94, 0x00, 0x00, 0x20, 0x6c, 0x09, 0x00, 0x00, ++ 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/pm.h b/drivers/net/ethernet/broadcom/pm.h +--- a/drivers/net/ethernet/broadcom/pm.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/pm.h 2018-05-30 15:50:51.032753168 +0800 +@@ -0,0 +1,96 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++#ifndef _PM_H ++#define _PM_H ++ ++ ++#define pmLoopbackMac 0 ++#define pmLoopbackPhy 1 ++ ++struct iproc_pm_stats { ++ u64 rx_frames;//XLMIB_GRxPkt ++ u64 rx_frame_good;//XLMIB_GRxPOK ++ u64 rx_bytes;//XLMIB_GRxByt ++ u64 rx_frame_64;//XLMIB_GRx64 ++ u64 rx_frame_127;//XLMIB_GRx127 ++ u64 rx_frame_255;//XLMIB_GRx255 ++ u64 rx_frame_511;//XLMIB_GRx511 ++ u64 rx_frame_1023;//XLMIB_GRx1023 ++ u64 rx_frame_1518;//XLMIB_GRx1518 ++ u64 rx_frame_1522;//XLMIB_GRx1522 ++ u64 rx_frame_jumbo;//XLMIB_GRx2047 + XLMIB_GRx4095 + XLMIB_GRx9216+ XLMIB_GRx16383 ++ u64 rx_frame_unicast;//XLMIB_GRxUCA ++ u64 rx_frame_multicast;//XLMIB_GRxMCA ++ u64 rx_frame_broadcast;//XLMIB_GRxBCA ++ u64 rx_frame_control;//XLMIB_GRxCF ++ u64 rx_frame_pause;//XLMIB_GRxPF ++ u64 rx_frame_jabber;//XLMIB_GRxJBR ++ u64 rx_frame_fragment;//XLMIB_GRxFRG ++ u64 rx_frame_vlan;//XLMIB_GRxVLN ++ u64 rx_frame_dvlan;//XLMIB_GRxDVLN ++ u64 rx_frame_fcs_error;//XLMIB_GRxFCS ++ u64 rx_frame_unsupport;//XLMIB_GRxUO ++ u64 rx_frame_wrong_sa;//XLMIB_GRxWSA ++ u64 rx_frame_align_err;//XLMIB_GRxALN ++ u64 rx_frame_length_err;//XLMIB_GRxFLR ++ u64 rx_frame_oversize;//XLMIB_GRxOVR ++ u64 rx_frame_mtu_err;//XLMIB_GRxMTUE ++ u64 rx_frame_truncated_err;//XLMIB_GRxTRFU ++ u64 rx_frame_undersize;//XLMIB_GRxUND ++ u64 tx_frames;//XLMIB_GTxPkt ++ u64 tx_frame_good;//XLMIB_GTxPOK ++ u64 tx_bytes;//XLMIB_GTxBYT ++ u64 tx_frame_64;//XLMIB_GTx64 ++ u64 tx_frame_127;//XLMIB_GTx127 ++ u64 tx_frame_255;//XLMIB_GTx255 ++ u64 tx_frame_511;//XLMIB_GTx511 ++ u64 tx_frame_1023;//XLMIB_GTx1023 ++ u64 tx_frame_1518;//XLMIB_GTx1518 ++ u64 tx_frame_1522;//XLMIB_GTx1522 ++ u64 tx_frame_jumbo;//XLMIB_GTx2047 + XLMIB_GTx4095 + XLMIB_GTx9216 + XLMIB_GTx16383 ++ u64 tx_frame_unicast;//XLMIB_GTxUCA ++ u64 tx_frame_multicast;//XLMIB_GTxMCA ++ u64 tx_frame_broadcast;//XLMIB_GTxBCA ++ u64 tx_frame_control;//XLMIB_GTxCF ++ u64 tx_frame_pause;//XLMIB_GTxPF ++ u64 tx_frame_jabber;//XLMIB_GTxJBR ++ u64 tx_frame_fragment;//XLMIB_GTxFRG ++ u64 tx_frame_vlan;//XLMIB_GTxVLN ++ u64 tx_frame_dvlan;//XLMIB_GTxDVLN ++ u64 tx_frame_fcs_error;//XLMIB_GTxFCS ++ u64 tx_frame_oversize;//XLMIB_GTxOVR ++ u64 tx_frame_error;//XLMIB_GTxErr ++ u64 tx_frame_fifo_underrun;//XLMIB_GTxUFL ++ u64 tx_frame_collision;//XLMIB_GTxNCL ++}; ++ ++struct iproc_pm_ops { ++ int (*port_enable)(int port, int enable); ++ int (*port_speed)(int port, int speed); ++ int (*port_loopback)(int port, int lb_type, int lb_en); ++ int (*port_mac_addr)(int port, u8 *mac); ++ int (*port_stats)(int port, struct iproc_pm_stats *stats); ++ int (*port_stats_clear)(int port); ++}; ++ ++extern int pm4x10_pm_init(struct iproc_pm_ops *pm_ops, u8 lane_idx); ++extern int pm4x10_pm_deinit(struct iproc_pm_ops *pm_ops); ++ ++extern int pm4x10_pm_xlport_port_config(int port, int enable); ++extern int pm4x10_xlport_speed_set(int port, int speed); ++extern int pm4x10_xlport_loopback_set(int port, int lb_type, int lb_en); ++extern int pm4x10_xlport_mac_addr_set(int port, u8 *mac); ++extern int pm4x10_xlport_stats_get(int port, struct iproc_pm_stats *stats); ++extern int pm4x10_xlport_mib_reset(int port); ++ ++#endif /* _PM_H */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/pm4x10.c b/drivers/net/ethernet/broadcom/pm4x10.c +--- a/drivers/net/ethernet/broadcom/pm4x10.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/pm4x10.c 2018-05-31 16:19:28.761893937 +0800 +@@ -0,0 +1,1175 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include "pm.h" ++#include "merlin16_ucode.h" ++ ++#define JUMBO_MAXSZ 0x3fe8 ++ ++#define debug(fmt, args...) do {} while (0) ++ ++ ++#define PM_CORE_ADDR(port) ((1 << (port + 1)) + 1) ++ ++#define PM_PMD_X1_CTL_REG(port) (0x00009010 | (PM_CORE_ADDR(port) << 19)) ++#define PM_PMD_X4_CTL_REG(port) (0x0000c010 | (PM_CORE_ADDR(port) << 19)) ++#define PM_CKRST_LN_CLK_RST_N_PWRDWN_CTL_REG(port) (0x0001d0b1 | (PM_CORE_ADDR(port) << 19)) ++#define PM_DIG_TOP_USER_CTL0_REG(port) (0x0001d104 | (PM_CORE_ADDR(port) << 19)) ++#define PM_TXFIR_MISC_CTL1_REG(port) (0x0001d139 | (PM_CORE_ADDR(port) << 19)) ++ ++#define TSC_OPERATION_WRITE 0x1 ++#define TSC_OPERATION_READ 0x0 ++ ++ ++/* S-channel address */ ++/* Per port registers */ ++#define XLMIB_GRx64(port) (0x00000000 + port) ++#define XLMIB_GRx127(port) (0x00000100 + port) ++#define XLMIB_GRx255(port) (0x00000200 + port) ++#define XLMIB_GRx511(port) (0x00000300 + port) ++#define XLMIB_GRx1023(port) (0x00000400 + port) ++#define XLMIB_GRx1518(port) (0x00000500 + port) ++#define XLMIB_GRx1522(port) (0x00000600 + port) ++#define XLMIB_GRx2047(port) (0x00000700 + port) ++#define XLMIB_GRx4095(port) (0x00000800 + port) ++#define XLMIB_GRx9216(port) (0x00000900 + port) ++#define XLMIB_GRx16383(port) (0x00000a00 + port) ++#define XLMIB_GRxPkt(port) (0x00000b00 + port) ++#define XLMIB_GRxUCA(port) (0x00000c00 + port) ++#define XLMIB_GRxMCA(port) (0x00000d00 + port) ++#define XLMIB_GRxBCA(port) (0x00000e00 + port) ++#define XLMIB_GRxFCS(port) (0x00000f00 + port) ++#define XLMIB_GRxCF(port) (0x00001000 + port) ++#define XLMIB_GRxPF(port) (0x00001100 + port) ++#define XLMIB_GRxUO(port) (0x00001300 + port) ++#define XLMIB_GRxWSA(port) (0x00001500 + port) ++#define XLMIB_GRxALN(port) (0x00001600 + port) ++#define XLMIB_GRxFLR(port) (0x00001700 + port) ++#define XLMIB_GRxOVR(port) (0x00001a00 + port) ++#define XLMIB_GRxJBR(port) (0x00001b00 + port) ++#define XLMIB_GRxMTUE(port) (0x00001c00 + port) ++#define XLMIB_GRxVLN(port) (0x00001f00 + port) ++#define XLMIB_GRxDVLN(port) (0x00002000 + port) ++#define XLMIB_GRxTRFU(port) (0x00002100 + port) ++#define XLMIB_GRxPOK(port) (0x00002200 + port) ++#define XLMIB_GRxUND(port) (0x00003400 + port) ++#define XLMIB_GRxFRG(port) (0x00003500 + port) ++#define XLMIB_GRxByt(port) (0x00003d00 + port) ++#define XLMIB_GTx64(port) (0x00004000 + port) ++#define XLMIB_GTx127(port) (0x00004100 + port) ++#define XLMIB_GTx255(port) (0x00004200 + port) ++#define XLMIB_GTx511(port) (0x00004300 + port) ++#define XLMIB_GTx1023(port) (0x00004400 + port) ++#define XLMIB_GTx1518(port) (0x00004500 + port) ++#define XLMIB_GTx1522(port) (0x00004600 + port) ++#define XLMIB_GTx2047(port) (0x00004700 + port) ++#define XLMIB_GTx4095(port) (0x00004800 + port) ++#define XLMIB_GTx9216(port) (0x00004900 + port) ++#define XLMIB_GTx16383(port) (0x00004a00 + port) ++#define XLMIB_GTxPOK(port) (0x00004b00 + port) ++#define XLMIB_GTxPkt(port) (0x00004c00 + port) ++#define XLMIB_GTxUCA(port) (0x00004d00 + port) ++#define XLMIB_GTxMCA(port) (0x00004e00 + port) ++#define XLMIB_GTxBCA(port) (0x00004f00 + port) ++#define XLMIB_GTxPF(port) (0x00005000 + port) ++#define XLMIB_GTxJBR(port) (0x00005200 + port) ++#define XLMIB_GTxFCS(port) (0x00005300 + port) ++#define XLMIB_GTxCF(port) (0x00005400 + port) ++#define XLMIB_GTxOVR(port) (0x00005500 + port) ++#define XLMIB_GTxFRG(port) (0x00005c00 + port) ++#define XLMIB_GTxErr(port) (0x00005d00 + port) ++#define XLMIB_GTxVLN(port) (0x00005e00 + port) ++#define XLMIB_GTxDVLN(port) (0x00005f00 + port) ++#define XLMIB_GTxUFL(port) (0x00006100 + port) ++#define XLMIB_GTxNCL(port) (0x00006e00 + port) ++#define XLMIB_GTxBYT(port) (0x00006f00 + port) ++ ++#define XLPORT_CONFIG(port) (0x00020000 + port) ++#define XLMAC_CTRL(port) (0x00060000 + port) ++#define XLMAC_CTRL__SW_LINK_STATUS 12 ++#define XLMAC_CTRL__XGMII_IPG_CHECK_DISABLE 11 ++#define XLMAC_CTRL__SOFT_RESET 6 ++#define XLMAC_CTRL__LOCAL_LPBK 2 ++#define XLMAC_CTRL__RX_EN 1 ++#define XLMAC_CTRL__TX_EN 0 ++#define XLMAC_MODE(port) (0x00060100 + port) ++#define XLMAC_MODE_OFFSET 0x1 ++#define XLMAC_MODE__SPEED_MODE_L 6 ++#define XLMAC_MODE__SPEED_MODE_R 4 ++#define XLMAC_MODE__SPEED_MODE_WIDTH 3 ++#define SPEED_MODE_LINK_10M 0x0 ++#define SPEED_MODE_LINK_100M 0x1 ++#define SPEED_MODE_LINK_1G 0x2 ++#define SPEED_MODE_LINK_2G5 0x3 ++#define SPEED_MODE_LINK_10G_PLUS 0x4 ++#define XLMAC_MODE__SPEED_MODE_RESETVALUE 0x4 ++#define XLMAC_MODE__NO_SOP_FOR_CRC_HG 3 ++#define XLMAC_MODE__NO_SOP_FOR_CRC_HG_WIDTH 1 ++#define XLMAC_MODE__NO_SOP_FOR_CRC_HG_RESETVALUE 0x0 ++#define XLMAC_MODE__HDR_MODE_L 2 ++#define XLMAC_MODE__HDR_MODE_R 0 ++#define XLMAC_MODE__HDR_MODE_WIDTH 3 ++#define HDR_MODE_IEEE 0x0 ++#define HDR_MODE_HG_PLUS 0x1 ++#define HDR_MODE_HG_2 0x2 ++#define HDR_MODE_SOP_ONLY_IEEE 0x5 ++#define XLMAC_TX_CTRL(port) (0x00060400 + port) ++#define XLMAC_TX_CTRL__AVERAGE_IPG_R 12 ++#define XLMAC_TX_CTRL__PAD_EN 4 ++#define XLMAC_TX_CTRL__CRC_MODE_R 0 ++#define CRC_MODE_APPEND 0x0 ++#define CRC_MODE_KEEP 0x1 ++#define CRC_MODE_REPLACE 0x2 ++#define CRC_MODE_PER_PKT_MODE 0x3 ++#define XLMAC_TX_MAC_SA(port) (0x00060500 + port) ++#define XLMAC_RX_MAX_SIZE(port) (0x00060800 + port) ++#define XLMAC_RX_MAX_SIZE__RX_MAX_SIZE_L 13 ++#define XLMAC_RX_MAX_SIZE__RX_MAX_SIZE_R 0 ++#define XLMAC_RX_MAX_SIZE__RX_MAX_SIZE_WIDTH 14 ++#define XLMAC_RX_CTRL(port) (0x00060600 + port) ++#define XLMAC_RX_CTRL__STRIP_CRC 2 ++#define XLMAC_RX_LSS_CTRL(port) (0x00060a00 + port) ++#define XLMAC_RX_LSS_CTRL__DROP_TX_DATA_ON_LINK_INTERRUPT 6 ++#define XLMAC_RX_LSS_CTRL__DROP_TX_DATA_ON_REMOTE_FAULT 5 ++#define XLMAC_RX_LSS_CTRL__DROP_TX_DATA_ON_LOCAL_FAULT 4 ++#define XLMAC_RX_LSS_CTRL__REMOTE_FAULT_DISABLE 1 ++#define XLMAC_RX_LSS_CTRL__LOCAL_FAULT_DISABLE 0 ++#define XLMAC_PAUSE_CTRL(port) (0x00060d00 + port) ++#define XLMAC_PAUSE_CTRL__RX_PAUSE_EN 18 ++#define XLMAC_PAUSE_CTRL__TX_PAUSE_EN 17 ++#define XLMAC_PFC_CTRL(port) (0x00060e00 + port) ++#define XLMAC_PFC_CTRL__PFC_REFRESH_EN 32 ++/* General type registers */ ++#define XLPORT_MODE_REG (0x02020a00) ++#define XLPORT_MODE_REG__RESET_MASK 0x3f ++#define XLPORT_MODE_REG__XPORT0_CORE_PORT_MODE_L 5 ++#define XLPORT_MODE_REG__XPORT0_CORE_PORT_MODE_R 3 ++#define XLPORT_MODE_REG__XPORT0_CORE_PORT_MODE_WIDTH 3 ++#define XPORT0_CORE_PORT_MODE_QUAD 0x0 ++#define XPORT0_CORE_PORT_MODE_TRI_012 0x1 ++#define XPORT0_CORE_PORT_MODE_TRI_023 0x2 ++#define XPORT0_CORE_PORT_MODE_DUAL 0x3 ++#define XPORT0_CORE_PORT_MODE_SINGLE 0x4 ++#define XLPORT_MODE_REG__XPORT0_PHY_PORT_MODE_L 2 ++#define XLPORT_MODE_REG__XPORT0_PHY_PORT_MODE_R 0 ++#define XLPORT_MODE_REG__XPORT0_PHY_PORT_MODE_WIDTH 3 ++#define XPORT0_PHY_PORT_MODE_QUAD 0x0 ++#define XPORT0_PHY_PORT_MODE_TRI_012 0x1 ++#define XPORT0_PHY_PORT_MODE_TRI_023 0x2 ++#define XPORT0_PHY_PORT_MODE_DUAL 0x3 ++#define XPORT0_PHY_PORT_MODE_SINGLE 0x4 ++#define XLPORT_ENABLE_REG (0x02020b00) ++#define XLPORT_ENABLE_REG__PORT3 3 ++#define XLPORT_ENABLE_REG__PORT2 2 ++#define XLPORT_ENABLE_REG__PORT1 1 ++#define XLPORT_ENABLE_REG__PORT0 0 ++#define XLPORT_MAC_CONTROL (0x02021000) ++#define XLPORT_MAC_CONTROL__RX_DUAL_CYCLE_TDM_EN 5 ++#define XLPORT_MAC_CONTROL__RX_NON_LINEAR_QUAD_TDM_EN 3 ++#define XLPORT_MAC_CONTROL__RX_FLEX_TDM_ENABLE 2 ++#define XLPORT_MAC_CONTROL__XMAC0_BYPASS_OSTS 1 ++#define XLPORT_MAC_CONTROL__XMAC0_RESET 0 ++#define XLPORT_XGXS0_CTRL_REG (0x02021400) ++#define XLPORT_XGXS0_CTRL_REG__RefSel 8 ++#define XLPORT_XGXS0_CTRL_REG__RefCMOS 7 ++#define XLPORT_XGXS0_CTRL_REG__Pwrdwn_CML_LC 6 ++#define XLPORT_XGXS0_CTRL_REG__Pwrdwn_CML 5 ++#define XLPORT_XGXS0_CTRL_REG__IDDQ 4 ++#define XLPORT_XGXS0_CTRL_REG__PWRDWN 3 ++#define XLPORT_XGXS0_CTRL_REG__Refin_EN 2 ++#define XLPORT_XGXS0_CTRL_REG__RSTB_HW 0 ++#define XLPORT_WC_UCMEM_CTRL (0x02021900) ++#define XLPORT_WC_UCMEM_CTRL__ACCESS_MODE 0 ++#define XLPORT_MIB_RESET (0x02022400) ++#define XLPORT_MIB_RESET__CLR_CNT_L 3 ++#define XLPORT_MIB_RESET__CLR_CNT_R 0 ++#define XLPORT_INTR_STATUS (0x02022900) ++#define XLPORT_INTR_ENABLE (0x02022a00) ++#define XLPORT_SOFT_RESET (0x02020c00) ++#define XLPORT_SOFT_RESET__PORT3 3 ++#define XLPORT_SOFT_RESET__PORT2 2 ++#define XLPORT_SOFT_RESET__PORT1 1 ++#define XLPORT_SOFT_RESET__PORT0 0 ++#define XLPORT_POWER_SAVE (0x02020d00) ++#define XLPORT_POWER_SAVE__XPORT_CORE0 0 ++ ++#define XLPORT_PORT_FIELD(reg, port) reg##__PORT##port ++#define XLPORT_PORT_FIELD_SET(_r, _p, _v) { \ ++ if (_p == 0) val |= (1 << _r##__PORT0); \ ++ else if (_p == 1) val |= (1 << _r##__PORT1); \ ++ else if (_p == 2) val |= (1 << _r##__PORT2); \ ++ else if (_p == 3) val |= (1 << _r##__PORT3); \ ++} ++ ++#define XLPORT_PORT_FIELD_CLEAR(_r, _p, _v) { \ ++ if (_p == 0) val &= ~(1 << _r##__PORT0); \ ++ else if (_p == 1) val &= ~(1 << _r##__PORT1); \ ++ else if (_p == 2) val &= ~(1 << _r##__PORT2); \ ++ else if (_p == 3) val &= ~(1 << _r##__PORT3); \ ++} ++ ++static u32 pm4x10_enabled = 0; ++ ++static inline void ++xlmac_reg64_write(u32 addr, u64 val) ++{ ++ iproc_cmic_schan_reg64_write(CMIC_BLOCK_TYPE_APM, addr, val); ++} ++ ++static inline u64 ++xlmac_reg64_read(u32 addr) ++{ ++ return iproc_cmic_schan_reg64_read(CMIC_BLOCK_TYPE_APM, addr); ++} ++ ++static inline void ++xlport_reg32_write(u32 addr, u32 val) ++{ ++ iproc_cmic_schan_reg32_write(CMIC_BLOCK_TYPE_APM, addr, val); ++} ++ ++static inline u32 ++xlport_reg32_read(u32 addr) ++{ ++ return iproc_cmic_schan_reg32_read(CMIC_BLOCK_TYPE_APM, addr); ++} ++ ++ ++/* MDIO address for each lane in this PM */ ++static u32 lane_mdio_addr[4] = { 3, 4, 5, 6 }; ++ ++static inline void ++pm_phy_sbus_write(u32 lane, u32 addr, u32 val, u32 mask, u32 shift) ++{ ++ u32 device, mem_data[4]; ++ ++ /* TSC register address (indirect access) */ ++ if ((addr == 0x0002) || (addr == 0x0003) || ((addr <= 0xc340) && (addr >= 0x9000))) ++ device = 0; /* PCS (TSC) */ ++ else ++ device = 1; /* PMA/PMD (Physical Media Device or called serdes(merlin)) */ ++ ++ mem_data[0] = (device << 27) | (lane_mdio_addr[lane] << 19) | (lane << 16) | addr; ++ mem_data[1] = ((val << shift) << 16) | /* data */ ++ (~(mask << shift) & 0xffff); /* mask */ ++ mem_data[2] = TSC_OPERATION_WRITE; ++ mem_data[3] = 0; ++ iproc_cmic_schan_ucmem_write(CMIC_BLOCK_TYPE_APM, mem_data); ++ } ++ ++static inline u32 ++pm_phy_sbus_read(u32 lane, u32 addr, u32 *val) ++{ ++ u32 device, mem_data[4]; ++ ++ /* TSC register address (indirect access) */ ++ if ((addr == 0x0002) || (addr == 0x0003) || ((addr <= 0xc340) && (addr >= 0x9000))) ++ device = 0; /* PCS (TSC) */ ++ else ++ device = 1; /* PMA/PMD (Physical Media Device or called serdes(merlin)) */ ++ ++ mem_data[0] = (device << 27) | (lane_mdio_addr[lane] << 19) | (lane << 16) | addr; ++ mem_data[1] = 0; ++ mem_data[2] = TSC_OPERATION_READ; ++ mem_data[3] = 0; ++ iproc_cmic_schan_ucmem_write(CMIC_BLOCK_TYPE_APM, mem_data); ++ *val = iproc_cmic_schan_ucmem_read(CMIC_BLOCK_TYPE_APM, mem_data); ++ return 0; ++} ++ ++ ++static void cmpw(u8 readonly, u32 addr, u32 val) ++{ ++ u8 i; ++ ++ if (readonly) ++ { ++ //printk("(read only) Reg addr = 0x%x, current = 0x%x, expect = 0x%x\n", reg_addr, get_val, reg_data_val); ++ } else ++ { ++ //printk("(write) Reg addr = 0x%x, current = 0x%x, expect = 0x%x\n", reg_addr, get_val, reg_data_val); ++ for (i=0; i<4; ++i) /* per lane */ ++ if ((i % 2) == 0) ++ pm_phy_sbus_write(i, addr, val, 0xffff, 0); ++ } ++} ++ ++static inline u32 ++pm_phy_configure(int port) ++{ ++ cmpw(0, 0x0002, 0x600d); cmpw(0, 0x0003, 0x8770); cmpw(0, 0x000d, 0x0000); cmpw(0, 0x000e, 0x0000); ++ cmpw(0, 0x0096, 0x0000); cmpw(0, 0x0097, 0x0000); cmpw(0, 0x0098, 0x0000); cmpw(0, 0x0099, 0x0000); ++ cmpw(0, 0x009a, 0x0000); cmpw(0, 0x009b, 0x0000); cmpw(0, 0x9000, 0x6000); cmpw(0, 0x9001, 0x00aa); ++ cmpw(0, 0x9003, 0xe4e4); cmpw(0, 0x9004, 0x0083); cmpw(0, 0x9005, 0x0000); cmpw(0, 0x9007, 0x0000); ++ cmpw(0, 0x9008, 0x0000); cmpw(0, 0x9009, 0x0000); cmpw(0, 0x900a, 0xf800); cmpw(0, 0x900e, 0x0312); ++ cmpw(0, 0x9010, 0x0003); cmpw(0, 0x9011, 0x0000); cmpw(1, 0x9012, 0x0002); cmpw(1, 0x9013, 0x0002); ++ cmpw(0, 0x9014, 0x0000); cmpw(0, 0x9030, 0x0000); cmpw(0, 0x9031, 0x0028); cmpw(0, 0x9032, 0x0000); ++ cmpw(0, 0x9033, 0x0000); cmpw(0, 0x9034, 0x0000); cmpw(0, 0x9035, 0x0000); cmpw(0, 0x9037, 0x0000); ++ cmpw(0, 0x9038, 0x0000); cmpw(0, 0x9039, 0x0000); cmpw(0, 0x903a, 0x0000); cmpw(0, 0x903b, 0x0000); ++ cmpw(0, 0x903c, 0x0000); cmpw(0, 0x903d, 0x0000); cmpw(0, 0x903e, 0x0000); cmpw(0, 0x9040, 0x0000); ++ cmpw(0, 0x9041, 0x0000); cmpw(0, 0x9042, 0x0000); cmpw(0, 0x9043, 0x0000); cmpw(0, 0x9044, 0x0000); ++ cmpw(0, 0x9045, 0x0000); cmpw(0, 0x9050, 0x0000); cmpw(0, 0x9051, 0x0000); cmpw(0, 0x9052, 0x0000); ++ cmpw(0, 0x9053, 0x0000); cmpw(0, 0x9054, 0x0000); cmpw(0, 0x9055, 0x0000); cmpw(0, 0x9056, 0x0000); ++ cmpw(0, 0x9057, 0x0000); cmpw(0, 0x9058, 0x0000); cmpw(0, 0x9059, 0x0000); cmpw(0, 0x905a, 0x0000); ++ cmpw(0, 0x9060, 0x0000); cmpw(0, 0x9061, 0x0000); cmpw(0, 0x9062, 0x0000); cmpw(1, 0x90b1, 0x0000); ++ cmpw(0, 0x90b3, 0x0000); cmpw(0, 0x90b4, 0x001d); cmpw(0, 0x90b5, 0xffff); cmpw(0, 0x9123, 0x3fff); ++ cmpw(0, 0x9130, 0x7690); cmpw(0, 0x9131, 0xc4f0); cmpw(0, 0x9132, 0xe647); cmpw(0, 0x9140, 0x0000); ++ cmpw(0, 0x9141, 0x0000); cmpw(0, 0x9142, 0x0000); cmpw(0, 0x9220, 0x0101); cmpw(0, 0x9221, 0x6140); ++ cmpw(0, 0x9222, 0xeea7); cmpw(0, 0x9230, 0x4010); cmpw(0, 0x9231, 0x0400); cmpw(0, 0x9232, 0x0041); ++ cmpw(0, 0x9233, 0x8090); cmpw(0, 0x9234, 0xa0b0); cmpw(0, 0x9235, 0xc0d0); cmpw(0, 0x9236, 0xe070); ++ cmpw(0, 0x9237, 0x0001); cmpw(0, 0x9238, 0xf0f0); cmpw(0, 0x9239, 0xf0f0); cmpw(0, 0x923a, 0xf0f0); ++ cmpw(0, 0x923b, 0xf0f0); cmpw(0, 0x923c, 0x0003); cmpw(0, 0x9240, 0x0000); cmpw(0, 0x9241, 0x0000); ++ cmpw(0, 0x9242, 0x0000); cmpw(0, 0x9243, 0x0000); cmpw(0, 0x9244, 0x0000); cmpw(0, 0x9245, 0x0000); ++ cmpw(0, 0x9246, 0x0000); cmpw(0, 0x9247, 0x0000); cmpw(0, 0x9248, 0x0000); cmpw(0, 0x9251, 0x029a); ++ cmpw(0, 0x9252, 0x0000); cmpw(0, 0x9253, 0x10ed); cmpw(0, 0x9254, 0x0000); cmpw(0, 0x9255, 0x14d4); ++ cmpw(0, 0x9256, 0x029a); cmpw(0, 0x9257, 0x8382); cmpw(0, 0x9258, 0x0bb8); cmpw(0, 0x9259, 0x0a6a); ++ cmpw(0, 0x925a, 0x029a); cmpw(0, 0x925b, 0x0a6a); cmpw(0, 0x925c, 0x029a); cmpw(0, 0x925d, 0x3b5f); ++ cmpw(0, 0x925e, 0x006b); cmpw(0, 0x9260, 0x0000); cmpw(0, 0x9261, 0x0000); cmpw(0, 0x9262, 0x00ff); ++ cmpw(0, 0x9263, 0x0002); cmpw(0, 0x9264, 0x0000); cmpw(0, 0x9270, 0xff00); cmpw(0, 0x9272, 0x0000); ++ cmpw(0, 0x9273, 0x0000); cmpw(0, 0x9274, 0x0400); cmpw(0, 0x9275, 0x0000); cmpw(0, 0x9276, 0x0000); ++ cmpw(0, 0x9277, 0x0000); cmpw(0, 0x9278, 0x0000); cmpw(0, 0x9279, 0x0000); cmpw(0, 0x927a, 0x0000); ++ cmpw(0, 0x9280, 0xff00); cmpw(0, 0x9282, 0x0000); cmpw(0, 0x9283, 0x0000); cmpw(0, 0x9284, 0x0400); ++ cmpw(0, 0x9285, 0x0000); cmpw(0, 0x9286, 0x0000); cmpw(0, 0x9287, 0x0000); cmpw(0, 0x9288, 0x0000); ++ cmpw(0, 0x9289, 0x0000); cmpw(0, 0x928a, 0x0000); cmpw(0, 0x9290, 0xff00); cmpw(0, 0x9292, 0x0000); ++ cmpw(0, 0x9293, 0x0000); cmpw(0, 0x9294, 0x0400); cmpw(0, 0x9295, 0x0000); cmpw(0, 0x9296, 0x0000); ++ cmpw(0, 0x9297, 0x0000); cmpw(0, 0x9298, 0x0000); cmpw(0, 0x9299, 0x0000); cmpw(0, 0x929a, 0x0000); ++ cmpw(0, 0x92a0, 0xff00); cmpw(0, 0x92a2, 0x0000); cmpw(0, 0x92a3, 0x0000); cmpw(0, 0x92a4, 0x0400); ++ cmpw(0, 0x92a5, 0x0000); cmpw(0, 0x92a6, 0x0000); cmpw(0, 0x92a7, 0x0000); cmpw(0, 0x92a8, 0x0000); ++ cmpw(0, 0x92a9, 0x0000); cmpw(0, 0x92aa, 0x0000); cmpw(0, 0xa000, 0xfffc); cmpw(0, 0xa001, 0x8030); ++ cmpw(0, 0xa002, 0x0070); cmpw(0, 0xa003, 0x0064); cmpw(1, 0xa011, 0x0812); cmpw(0, 0xa020, 0x0000); ++ cmpw(0, 0xa021, 0x0000); cmpw(0, 0xa022, 0x0000); cmpw(0, 0xa023, 0x1400); cmpw(0, 0xa024, 0x030f); ++ cmpw(0, 0xa031, 0x0000); cmpw(0, 0xa032, 0x0000); cmpw(0, 0xa080, 0x0000); cmpw(0, 0xa081, 0x0000); ++ cmpw(0, 0xa085, 0x0000); cmpw(0, 0xa086, 0x8000); cmpw(0, 0xc010, 0xc003); cmpw(0, 0xc011, 0x0000); ++ cmpw(1, 0xc012, 0x000e); cmpw(0, 0xc013, 0x000c); cmpw(0, 0xc014, 0x0000); cmpw(0, 0xc018, 0x0000); ++ cmpw(0, 0xc019, 0x0000); cmpw(0, 0xc040, 0x0000); cmpw(0, 0xc041, 0x0000); cmpw(0, 0xc042, 0x0000); ++ cmpw(0, 0xc043, 0x0000); ++ //cmpw(0, 0xc050, 0x0135); /* speed = 10M */ ++ //cmpw(0, 0xc050, 0x0136); /* speed = 100M */ ++ cmpw(0, 0xc050, 0x0137); /* speed = 1000M */ ++ //cmpw(0, 0xc050, 0x011c); /* speed = 10G */ ++ cmpw(1, 0xc051, 0x0000); cmpw(0, 0xc052, 0x0000); cmpw(1, 0xc054, 0xef62); cmpw(0, 0xc055, 0x0000); ++ cmpw(0, 0xc058, 0x0000); cmpw(0, 0xc060, 0x0000); cmpw(0, 0xc061, 0x0000); cmpw(0, 0xc070, 0x1c00); ++ cmpw(0, 0xc072, 0x0e05); cmpw(0, 0xc073, 0x0830); cmpw(0, 0xc074, 0x0010); cmpw(0, 0xc075, 0x0021); ++ cmpw(0, 0xc076, 0x0000); cmpw(0, 0xc077, 0x0040); cmpw(0, 0xc078, 0x0004); cmpw(0, 0xc079, 0x0000); ++ cmpw(0, 0xc07a, 0x0000); cmpw(0, 0xc100, 0x0000); cmpw(0, 0xc101, 0x0000); cmpw(0, 0xc102, 0x0000); ++ cmpw(0, 0xc103, 0x0000); cmpw(0, 0xc104, 0x0000); cmpw(0, 0xc105, 0x0000); cmpw(0, 0xc111, 0x0000); ++ cmpw(0, 0xc112, 0x01b4); cmpw(0, 0xc113, 0x01cb); cmpw(0, 0xc114, 0x0000); cmpw(1, 0xc120, 0x4811); ++ cmpw(1, 0xc121, 0x0084); cmpw(0, 0xc130, 0x0000); cmpw(0, 0xc131, 0x2000); cmpw(0, 0xc132, 0x442c); ++ cmpw(0, 0xc133, 0x0000); cmpw(0, 0xc134, 0x0870); cmpw(0, 0xc135, 0x0000); cmpw(0, 0xc136, 0x0000); ++ cmpw(0, 0xc137, 0x0001); cmpw(0, 0xc139, 0x0000); cmpw(0, 0xc13d, 0x14a0); cmpw(0, 0xc140, 0x0000); ++ cmpw(0, 0xc141, 0x0000); cmpw(0, 0xc142, 0x0000); cmpw(0, 0xc143, 0x0000); cmpw(0, 0xc144, 0x0000); ++ cmpw(0, 0xc145, 0x0000); cmpw(0, 0xc146, 0x0000); cmpw(0, 0xc147, 0x0000); cmpw(0, 0xc148, 0x0000); ++ cmpw(0, 0xc149, 0x0000); cmpw(0, 0xc14a, 0x0000); cmpw(0, 0xc14b, 0x0000); cmpw(0, 0xc14c, 0x0000); ++ cmpw(0, 0xc14d, 0x0000); cmpw(0, 0xc14e, 0x0000); cmpw(0, 0xc152, 0x0000); cmpw(0, 0xc153, 0x0000); ++ cmpw(0, 0xc154, 0x0000); cmpw(0, 0xc155, 0x0000); cmpw(0, 0xc156, 0x0000); cmpw(0, 0xc157, 0x0000); ++ cmpw(0, 0xc158, 0x0000); cmpw(0, 0xc159, 0x0000); cmpw(0, 0xc15a, 0x0000); cmpw(0, 0xc15b, 0x0000); ++ cmpw(0, 0xc15c, 0x0000); cmpw(0, 0xc161, 0x0000); cmpw(0, 0xc162, 0x0000); cmpw(0, 0xc163, 0x0000); ++ cmpw(0, 0xc170, 0x0000); cmpw(0, 0xc171, 0x0000); cmpw(0, 0xc172, 0x0000); cmpw(0, 0xc173, 0x0000); ++ cmpw(0, 0xc174, 0x0000); cmpw(0, 0xc175, 0x0000); cmpw(0, 0xc176, 0x0000); cmpw(0, 0xc177, 0x0000); ++ cmpw(0, 0xc178, 0x0000); cmpw(0, 0xc179, 0x0000); cmpw(0, 0xc17a, 0x0000); cmpw(0, 0xc17b, 0x0000); ++ cmpw(0, 0xc17c, 0x0000); cmpw(0, 0xc17d, 0x0000); cmpw(0, 0xc180, 0x0000); cmpw(0, 0xc181, 0x0056); ++ cmpw(0, 0xc182, 0x0005); cmpw(0, 0xc183, 0x2000); cmpw(0, 0xc184, 0x0001); cmpw(0, 0xc185, 0x02a1); ++ cmpw(0, 0xc186, 0x0168); cmpw(0, 0xc187, 0x0000); cmpw(0, 0xc188, 0x0000); cmpw(0, 0xc190, 0x0000); ++ cmpw(0, 0xc191, 0x0000); cmpw(0, 0xc192, 0x0000); cmpw(0, 0xc193, 0x0000); cmpw(0, 0xc194, 0x0000); ++ cmpw(0, 0xc195, 0x0000); cmpw(0, 0xc196, 0x0000); cmpw(0, 0xc197, 0x0000); cmpw(0, 0xc198, 0x0000); ++ cmpw(0, 0xc199, 0x0000); cmpw(0, 0xc19a, 0x0000); cmpw(0, 0xc1a0, 0x0000); cmpw(0, 0xc1a1, 0x0000); ++ cmpw(0, 0xc1a2, 0x0000); cmpw(0, 0xc1a3, 0x0000); cmpw(0, 0xc1a4, 0x0000); cmpw(0, 0xc1a5, 0x0000); ++ cmpw(0, 0xc1a6, 0x0000); cmpw(0, 0xc1a7, 0x0000); cmpw(0, 0xc1a8, 0x0000); cmpw(0, 0xc1a9, 0x0000); ++ cmpw(0, 0xc1aa, 0x0000); cmpw(0, 0xc1ab, 0x0030); cmpw(0, 0xc1ac, 0x0000); cmpw(0, 0xc1ad, 0x0001); ++ cmpw(0, 0xc1ae, 0x0000); cmpw(0, 0xc253, 0x4000); cmpw(0, 0xc30a, 0x0000); cmpw(0, 0xc30b, 0x0000); ++ cmpw(0, 0xc330, 0x0002); cmpw(0, 0xc340, 0x0011); cmpw(0, 0xd001, 0x0205); cmpw(0, 0xd002, 0x0690); ++ cmpw(0, 0xd003, 0x00f0); cmpw(0, 0xd004, 0x2401); cmpw(1, 0xd005, 0xf07c); cmpw(1, 0xd006, 0x0002); ++ cmpw(1, 0xd007, 0x6969); cmpw(1, 0xd008, 0x3414); cmpw(1, 0xd009, 0x5878); cmpw(1, 0xd00a, 0x00e0); ++ cmpw(0, 0xd00b, 0x0060); cmpw(0, 0xd00d, 0x0805); cmpw(0, 0xd00e, 0x0000); cmpw(0, 0xd010, 0x0028); ++ cmpw(0, 0xd011, 0x0200); cmpw(0, 0xd012, 0x0087); cmpw(0, 0xd013, 0x1c1e); cmpw(0, 0xd014, 0x35ad); ++ cmpw(0, 0xd015, 0x35af); cmpw(0, 0xd016, 0x340d); cmpw(0, 0xd017, 0x0000); cmpw(0, 0xd018, 0x0011); ++ cmpw(0, 0xd019, 0x0000); cmpw(1, 0xd01a, 0x0004); cmpw(1, 0xd01b, 0x0dff); cmpw(1, 0xd01c, 0x0000); ++ cmpw(1, 0xd01d, 0x0000); cmpw(1, 0xd01e, 0x0880); cmpw(0, 0xd020, 0x0000); cmpw(0, 0xd021, 0x0000); ++ cmpw(0, 0xd022, 0x0000); cmpw(0, 0xd023, 0x0000); cmpw(0, 0xd024, 0x0000); cmpw(0, 0xd025, 0x0000); ++ cmpw(0, 0xd026, 0x0000); cmpw(0, 0xd027, 0x8400); cmpw(0, 0xd029, 0x0000); cmpw(0, 0xd02a, 0x0000); ++ cmpw(0, 0xd02b, 0x2e02); cmpw(0, 0xd02c, 0x0000); cmpw(0, 0xd02d, 0x0000); cmpw(0, 0xd02e, 0xc400); ++ cmpw(0, 0xd030, 0xa404); cmpw(0, 0xd031, 0x2060); cmpw(0, 0xd032, 0x0100); cmpw(0, 0xd033, 0x0000); ++ cmpw(1, 0xd034, 0xfff0); cmpw(1, 0xd035, 0x00d0); cmpw(1, 0xd036, 0xfffa); cmpw(1, 0xd037, 0x0096); ++ cmpw(1, 0xd038, 0x000b); cmpw(1, 0xd039, 0x0108); cmpw(1, 0xd03a, 0x2118); cmpw(1, 0xd03b, 0x0000); ++ cmpw(1, 0xd03c, 0x0000); cmpw(1, 0xd03d, 0x0000); cmpw(1, 0xd03e, 0x009f); cmpw(0, 0xd040, 0x00b8); ++ cmpw(0, 0xd041, 0x0000); cmpw(0, 0xd042, 0x0001); cmpw(0, 0xd050, 0x0004); cmpw(0, 0xd051, 0x0052); ++ cmpw(0, 0xd052, 0x0310); cmpw(0, 0xd053, 0x0000); cmpw(0, 0xd054, 0x0000); cmpw(0, 0xd055, 0x0000); ++ cmpw(0, 0xd056, 0x0000); cmpw(0, 0xd060, 0x0000); cmpw(0, 0xd061, 0x0000); cmpw(0, 0xd062, 0x0000); ++ cmpw(0, 0xd063, 0x0004); cmpw(0, 0xd064, 0x0a00); cmpw(0, 0xd065, 0x0032); cmpw(1, 0xd066, 0x0002); ++ cmpw(0, 0xd067, 0x03f5); cmpw(0, 0xd070, 0x0000); cmpw(0, 0xd071, 0x0000); cmpw(0, 0xd072, 0x0000); ++ cmpw(0, 0xd073, 0x3100); cmpw(0, 0xd074, 0x0004); cmpw(0, 0xd075, 0x0004); cmpw(0, 0xd078, 0x0000); ++ cmpw(0, 0xd079, 0x0000); cmpw(0, 0xd07a, 0x0000); cmpw(0, 0xd07b, 0x0000); cmpw(0, 0xd07c, 0x0000); ++ cmpw(1, 0xd07d, 0x0002); ++ //cmpw(0, 0xd080, 0x8008); /* speed = 10M */ ++ //cmpw(0, 0xd080, 0x8008); /* speed = 100M */ ++ cmpw(0, 0xd080, 0x8008); /* speed = 1000M */ ++ //cmpw(0, 0xd080, 0x8000); /* speed = 10G */ ++ cmpw(0, 0xd081, 0x0001); cmpw(0, 0xd083, 0x0000); cmpw(0, 0xd085, 0x0000); cmpw(0, 0xd086, 0x0000); ++ cmpw(1, 0xd089, 0x0000); cmpw(0, 0xd08a, 0x0000); cmpw(1, 0xd08b, 0x0000); cmpw(1, 0xd08c, 0x0000); ++ cmpw(0, 0xd08e, 0x0001); cmpw(0, 0xd090, 0x1c40); cmpw(0, 0xd091, 0x1048); cmpw(0, 0xd092, 0x7e92); ++ cmpw(0, 0xd093, 0x288f); cmpw(0, 0xd094, 0x0820); cmpw(0, 0xd095, 0x07a0); cmpw(0, 0xd096, 0x14f8); ++ cmpw(0, 0xd097, 0x0121); cmpw(0, 0xd098, 0x0000); cmpw(0, 0xd099, 0x0088); cmpw(0, 0xd0a0, 0x2800); ++ cmpw(0, 0xd0a1, 0x0744); cmpw(0, 0xd0a2, 0x5250); cmpw(0, 0xd0a3, 0x1556); cmpw(0, 0xd0a4, 0x0000); ++ cmpw(0, 0xd0a5, 0x2800); cmpw(0, 0xd0a6, 0x0001); cmpw(0, 0xd0a7, 0x0aa0); cmpw(0, 0xd0a8, 0x0000); ++ cmpw(0, 0xd0a9, 0x0000); cmpw(0, 0xd0aa, 0x0088); cmpw(0, 0xd0b0, 0x2480); cmpw(0, 0xd0b1, 0x0007); ++ cmpw(0, 0xd0b2, 0x0080); cmpw(0, 0xd0b3, 0x460e); cmpw(0, 0xd0b4, 0x0501); cmpw(0, 0xd0b5, 0x1405); ++ cmpw(0, 0xd0b6, 0x0000); cmpw(0, 0xd0b7, 0x0000); cmpw(0, 0xd0b8, 0x4442); cmpw(0, 0xd0b9, 0x5285); ++ cmpw(0, 0xd0ba, 0x0015); cmpw(0, 0xd0be, 0x0000); cmpw(0, 0xd0bf, 0x0001); cmpw(0, 0xd0c0, 0x5229); ++ cmpw(0, 0xd0c1, 0x0008); cmpw(0, 0xd0c2, 0xfd29); cmpw(1, 0xd0c8, 0x0333); cmpw(1, 0xd0c9, 0x0303); ++ cmpw(1, 0xd0ca, 0x0000); cmpw(1, 0xd0cb, 0x0001); cmpw(1, 0xd0cc, 0x0009); cmpw(0, 0xd0d0, 0x0602); ++ cmpw(0, 0xd0d1, 0x002a); cmpw(0, 0xd0d2, 0x000e); cmpw(0, 0xd0d3, 0x0000); cmpw(0, 0xd0d4, 0x0000); ++ cmpw(0, 0xd0d5, 0x0000); cmpw(0, 0xd0d6, 0x0000); cmpw(0, 0xd0d7, 0x0000); cmpw(0, 0xd0d8, 0x0002); ++ cmpw(0, 0xd0d9, 0x0000); cmpw(0, 0xd0da, 0x8000); cmpw(0, 0xd0db, 0x0000); cmpw(0, 0xd0dc, 0x0000); ++ cmpw(0, 0xd0e0, 0x0000); cmpw(0, 0xd0e1, 0x000a); cmpw(0, 0xd0e2, 0x0002); cmpw(0, 0xd0e3, 0x0000); ++ cmpw(0, 0xd0e8, 0x0002); cmpw(0, 0xd0f0, 0x0363); cmpw(0, 0xd0f1, 0x0001); cmpw(0, 0xd0f2, 0x0000); ++ cmpw(0, 0xd0f3, 0x0000); cmpw(0, 0xd0f4, 0xa271); cmpw(0, 0xd0f5, 0x0000); cmpw(0, 0xd0f6, 0x0000); ++ cmpw(0, 0xd0f7, 0x8604); cmpw(1, 0xd0f8, 0x0000); cmpw(1, 0xd0f9, 0x001c); cmpw(1, 0xd0fa, 0x403c); ++ cmpw(0, 0xd0fe, 0x0000); cmpw(0, 0xd100, 0xff00); cmpw(0, 0xd101, 0xff00); cmpw(0, 0xd102, 0xff00); ++ cmpw(0, 0xd103, 0xff00); cmpw(0, 0xd104, 0xff00); cmpw(0, 0xd105, 0xff00); cmpw(0, 0xd106, 0xff00); ++ cmpw(0, 0xd107, 0xff00); cmpw(0, 0xd108, 0xff00); cmpw(0, 0xd109, 0xff00); cmpw(0, 0xd10a, 0xff00); ++ cmpw(0, 0xd10b, 0xff00); cmpw(0, 0xd10c, 0xff00); cmpw(0, 0xd10d, 0xff00); cmpw(0, 0xd10e, 0xff00); ++ cmpw(0, 0xd110, 0x0000); cmpw(0, 0xd111, 0x0020); cmpw(1, 0xd112, 0x0000); cmpw(0, 0xd113, 0xc140); ++ cmpw(0, 0xd11b, 0x00aa); cmpw(0, 0xd11c, 0x4155); cmpw(0, 0xd11d, 0x4914); cmpw(0, 0xd11e, 0x000f); ++ cmpw(0, 0xd120, 0x1ffa); cmpw(0, 0xd121, 0xfff0); cmpw(0, 0xd122, 0x0fff); cmpw(0, 0xd123, 0x1007); ++ cmpw(0, 0xd124, 0x8240); cmpw(0, 0xd125, 0x8160); cmpw(0, 0xd126, 0x0000); cmpw(1, 0xd128, 0x4f52); ++ cmpw(1, 0xd129, 0x1fdb); cmpw(1, 0xd12a, 0xbffd); cmpw(1, 0xd12b, 0xfff3); cmpw(1, 0xd12c, 0xfff3); ++ cmpw(1, 0xd12d, 0x23ff); cmpw(1, 0xd12e, 0x5288); cmpw(0, 0xd130, 0x01f4); cmpw(0, 0xd131, 0x00c8); ++ cmpw(1, 0xd141, 0x003f); cmpw(1, 0xd142, 0x0003); cmpw(1, 0xd143, 0x0000); cmpw(1, 0xd144, 0x003f); ++ cmpw(1, 0xd145, 0x0003); cmpw(1, 0xd146, 0x0000); cmpw(1, 0xd147, 0x0010); cmpw(0, 0xd150, 0x0000); ++ cmpw(0, 0xd151, 0x0101); cmpw(0, 0xd152, 0x0202); cmpw(0, 0xd153, 0x0303); cmpw(0, 0xd161, 0x0000); ++ cmpw(0, 0xd162, 0x0000); cmpw(0, 0xd163, 0x0000); cmpw(0, 0xd164, 0x0003); cmpw(0, 0xd167, 0x0000); ++ cmpw(0, 0xd168, 0x041c); cmpw(1, 0xd16c, 0x0000); cmpw(0, 0xd171, 0x0000); cmpw(0, 0xd172, 0x0000); ++ cmpw(0, 0xd174, 0x0003); cmpw(0, 0xd177, 0x0000); cmpw(1, 0xd17c, 0x0000); cmpw(0, 0xd17d, 0x0001); ++ cmpw(0, 0xd180, 0x8000); cmpw(0, 0xd181, 0x0001); cmpw(0, 0xd183, 0x0000); cmpw(1, 0xd185, 0x0000); ++ cmpw(0, 0xd186, 0x0000); cmpw(1, 0xd189, 0x0000); cmpw(1, 0xd18a, 0x0000); cmpw(1, 0xd18b, 0x0000); ++ cmpw(1, 0xd18c, 0x0000); cmpw(0, 0xd18e, 0x0001); cmpw(0, 0xd190, 0x8000); cmpw(0, 0xd191, 0x0001); ++ cmpw(0, 0xd193, 0x0000); cmpw(1, 0xd195, 0x0000); cmpw(0, 0xd196, 0x0000); cmpw(1, 0xd199, 0x0000); ++ cmpw(0, 0xd19a, 0x0000); cmpw(1, 0xd19b, 0x0000); cmpw(1, 0xd19c, 0x0000); cmpw(0, 0xd19e, 0x0001); ++ cmpw(0, 0xd200, 0x0003); cmpw(0, 0xd201, 0x000b); cmpw(0, 0xd202, 0x0011); cmpw(0, 0xd200, 0x0003); ++ cmpw(1, 0xd203, 0x0001); cmpw(0, 0xd204, 0x0800); cmpw(0, 0xd205, 0x2000); cmpw(0, 0xd206, 0x0200); ++ cmpw(0, 0xd207, 0x0000); cmpw(0, 0xd208, 0x0800); cmpw(0, 0xd209, 0x2000); cmpw(1, 0xd20a, 0x0200); ++ cmpw(1, 0xd20b, 0x0000); cmpw(0, 0xd20c, 0x0000); cmpw(0, 0xd20d, 0x0000); cmpw(0, 0xd20e, 0x0000); ++ cmpw(1, 0xd210, 0x02ec); cmpw(0, 0xd211, 0x0000); cmpw(0, 0xd212, 0x0000); cmpw(1, 0xd213, 0x0000); ++ cmpw(1, 0xd214, 0x0000); cmpw(0, 0xd215, 0x0000); cmpw(0, 0xd216, 0x0007); cmpw(1, 0xd217, 0x0000); ++ cmpw(1, 0xd218, 0x0802); cmpw(1, 0xd219, 0x0802); cmpw(1, 0xd21a, 0x7a90); cmpw(0, 0xd21b, 0x0000); ++ cmpw(0, 0xd220, 0x0000); cmpw(0, 0xd221, 0x0000); cmpw(1, 0xd222, 0x0000); cmpw(1, 0xd223, 0x0018); ++ cmpw(0, 0xd224, 0x0000); cmpw(0, 0xd225, 0x8401); cmpw(0, 0xd226, 0x0000); cmpw(1, 0xd227, 0x0000); ++ cmpw(0, 0xd228, 0x0101); cmpw(0, 0xd229, 0x0000); cmpw(1, 0xd22a, 0x0007); cmpw(0, 0xffdc, 0x001f); ++ cmpw(0, 0xffdd, 0x404d); cmpw(0, 0xffde, 0x0000); cmpw(0, 0xffdf, 0x0000); ++} ++ ++ ++static inline u32 ++pm_ucode_download(u8 *ucode_image, u16 ucode_len) ++{ ++ u32 get_val; ++ u8 i, wrdata_lsb; ++ u16 wrdata_lsw, ucode_len_padded, count = 0; ++ ++ /* Check array pointer */ ++ if (ucode_image == (u8 *)NULL) { ++ printk("uCode Image is empty !!\n"); ++ return -1; ++ } ++ ++ /* Check ucode size */ ++ if (ucode_len > (32768)) { /* 16 x 2048 */ ++ printk("Can't fit all of the firmware into the device load table(max = 16 x 2048 bytes) \n"); ++ return -1; ++ } ++ ++ //[1] EFUN(wrc_micro_master_clk_en(0x1)); /* Enable clock to microcontroller subsystem */ ++ /* [0xd200] Write to Clock control register 0 to enable micro core clock (m0) */ ++ pm_phy_sbus_write(0, 0xd200, 0x0001, 0x0001, 0); ++ ++ //[2] EFUN(wrc_micro_master_rstb(0x1)); /* De-assert reset to microcontroller sybsystem */ ++ /* [0xd201] Write to Reset control registers 0 to make micro_master_rstb = 1 */ ++ pm_phy_sbus_write(0, 0xd201, 0x0001, 0x0001, 0); ++ ++ //[3] EFUN(wrc_micro_master_rstb(0x0)); /* Assert reset to microcontroller sybsystem - Toggling reset */ ++ /* [0xd201] Write to Reset control registers 0 to make micro_master_rstb = 0 */ ++ pm_phy_sbus_write(0, 0xd201, 0x0000, 0x0001, 0); ++ ++ //[4] EFUN(wrc_micro_master_rstb(0x1)); /* De-assert reset to microcontroller sybsystem */ ++ /* [0xd201] Write to Reset control registers 0 to make micro_master_rstb = 1 */ ++ pm_phy_sbus_write(0, 0xd201, 0x0001, 0x0001, 0); ++ ++ //[5] EFUN(wrc_micro_ra_init(0x1)); /* Set initialization command to initialize code RAM */ ++ /* [0xd202] Write to rmi to ahb control register 0 to initialize code RAMs */ ++ pm_phy_sbus_write(0, 0xd202, 0x0001, 0x0003, 8); ++ ++ //[6] EFUN(merlin16_INTERNAL_poll_micro_ra_initdone(sa__, 250)); /* Poll for micro_ra_initdone = 1 to indicate initialization done */ ++ /* [0xd203] Read from ahb status register 0 to make sure all are done */ ++ for (i=0; i<100; ++i) ++ { ++ pm_phy_sbus_read(0, 0xd203, &get_val); ++ if (get_val == 0x1) /* code/data RAM initialization process is complete */ ++ break; ++ udelay(2500); ++ } ++ if (i == 100) ++ { ++ printk("code/data RAM initialization process is timeout !!\n"); ++ return -1; ++ } ++ ++ //[7] EFUN(wrc_micro_ra_init(0x0)); /* Clear initialization command */ ++ /* [0xd202] Write to rmi to ahb control register 0 to clear intialize code/data RAM command */ ++ pm_phy_sbus_write(0, 0xd202, 0x0000, 0x0003, 8); ++ ++ ucode_len_padded = ((ucode_len + 3) & 0xFFFC); /* Aligning ucode size to 4-byte boundary */ ++ ++ /* Code to Load microcode */ ++ //[8] EFUN(wrc_micro_autoinc_wraddr_en(0x1)); /* To auto increment RAM write address */ ++ /* [0xd202] Write to rmi to ahb control register 0 to make Automatic increment write address enable */ ++ pm_phy_sbus_write(0, 0xd202, 0x0001, 0x0001, 12); ++ ++ //[9] EFUN(wrc_micro_ra_wrdatasize(0x1)); /* Select 16bit transfers */ ++ /* [0xd202] Write to rmi to ahb control register 0 to select write data size = 16 bits */ ++ pm_phy_sbus_write(0, 0xd202, 0x0001, 0x0003, 0); ++ ++ //[10] EFUN(wrc_micro_ra_wraddr_msw(0x0)); /* Upper 16bits of start address of Program RAM where the ucode is to be loaded */ ++ /* [0xd205] Write to rmi to ahb write address MSW (bits 31:16) register with 0 */ ++ pm_phy_sbus_write(0, 0xd205, 0x0000, 0xffff, 0); ++ ++ //[11] EFUN(wrc_micro_ra_wraddr_lsw(0x0)); /* Lower 16bits of start address of Program RAM where the ucode is to be loaded */ ++ /* [0xd206] Write to rmi to ahb write data LSW (bits 15:0) register with 0 (starting address = 0x0) */ ++ pm_phy_sbus_write(0, 0xd206, 0x0000, 0xffff, 0); ++ ++ do { /* ucode_image loaded 16bits at a time */ ++ /* wrdata_lsb read from ucode_image; zero padded to 4byte boundary */ ++ wrdata_lsb = (count < ucode_len) ? ucode_image[count] : 0x0; ++ count++; ++ /* wrdata_msb read from ucode_image; zero padded to 4byte boundary */ ++ wrdata_lsw = (count < ucode_len) ? ucode_image[count] : 0x0; ++ count++; ++ /* 16bit wrdata_lsw formed from 8bit msb and lsb values read from ucode_image */ ++ wrdata_lsw = ((wrdata_lsw << 8) | wrdata_lsb); ++ ++ //[12] EFUN(wrc_micro_ra_wrdata_lsw(wrdata_lsw)); /* Program RAM lower 16bits write data */ ++ /* [0xd206] Write to rmi to ahb write data LSW (bits 15:0) register with data */ ++ pm_phy_sbus_write(0, 0xd206, wrdata_lsw, 0xffff, 0); ++ } while (count < ucode_len_padded); /* Loop repeated till entire image loaded (upto the 4byte boundary) */ ++ ++ //[13] EFUN(wrc_micro_ra_wrdatasize(0x2)); /* Select 32bit transfers as default */ ++ /* [0xd202] Write to rmi to ahb control register 0 to Select 32bit transfers as default */ ++ pm_phy_sbus_write(0, 0xd202, 0x0002, 0x0003, 0); ++ ++ //[14] EFUN(wrc_micro_core_clk_en(0x1)); /* Enable clock to M0 core */ ++ /* [0xd200] Write to Clock control register 0 to enable micro core clock enable (m0) */ ++ pm_phy_sbus_write(0, 0xd200, 0x0001, 0x0001, 1); ++ ++ return 0; ++} ++ ++static int __xlmac_credit_reset(int port) ++{ ++ return 0; ++} ++ ++static void __xlmac_enable_set(int port, bool enable) ++{ ++ u64 ctrl, octrl; ++ int soft_reset; ++ ++ ctrl = xlmac_reg64_read(XLMAC_CTRL(port)); ++ octrl = ctrl; ++ /* Don't disable TX since it stops egress and hangs if CPU sends */ ++ ctrl |= (1 << XLMAC_CTRL__TX_EN); ++ ctrl &= ~(1 << XLMAC_CTRL__RX_EN); ++ if (enable) { ++ ctrl |= (1 << XLMAC_CTRL__RX_EN); ++ } ++ ++ if (ctrl == octrl) { ++ /* SDK-49952 fix soluition : ++ * >> to avoid the unexpected early return to prevent this problem. ++ * 1. Problem occurred for disabling process only. ++ * 2. To comply origianl designing senario, XLMAC_CTRLr.SOFT_RESETf is ++ * used to early check to see if this port is at disabled state ++ * already. ++ */ ++ soft_reset = ctrl & (1 << XLMAC_CTRL__SOFT_RESET); ++ if ((enable) || (!enable && soft_reset)){ ++ return; ++ } ++ } ++ ++ ctrl |= (1 << XLMAC_CTRL__SOFT_RESET); ++ if (enable) { ++ /* Reset EP credit before de-assert SOFT_RESET */ ++ __xlmac_credit_reset(port); ++ /* Deassert SOFT_RESET */ ++ ctrl &= ~(1 << XLMAC_CTRL__SOFT_RESET); ++ } ++ ++ xlmac_reg64_write(XLMAC_CTRL(port), ctrl); ++} ++ ++static int __xlmac_enable_get(int port) ++{ ++ u64 ctrl; ++ int tx_en, rx_en; ++ ++ ctrl = xlmac_reg64_read(XLMAC_CTRL(port)); ++ tx_en = ctrl & (1 << XLMAC_CTRL__TX_EN); ++ rx_en = ctrl & (1 << XLMAC_CTRL__RX_EN); ++ ++ return (tx_en && rx_en); ++} ++ ++static int __xlmac_speed_set(int port, int speed) ++{ ++ u64 speed_cfg, val64; ++ int enable; ++ ++ //pm_phy_sbus_write(port, 0xd080, 0x8008, 0x8008, 0); /* CKRST_CTRL_OSR_MODE_CONTROL */ ++ ++ if (speed == 1000) { ++ speed_cfg = SPEED_MODE_LINK_1G; ++ pm_phy_sbus_write(port, 0xc050, 0x0037, 0x01ff, 0); /* SC_X4_CONTROL_CONTROL */ ++ } else if (speed == 100) { ++ speed_cfg = SPEED_MODE_LINK_100M; ++ pm_phy_sbus_write(port, 0xc050, 0x0036, 0x01ff, 0); /* SC_X4_CONTROL_CONTROL */ ++ } else if (speed == 10) { ++ speed_cfg = SPEED_MODE_LINK_10M; ++ pm_phy_sbus_write(port, 0xc050, 0x0035, 0x01ff, 0); /* SC_X4_CONTROL_CONTROL */ ++ } else { ++ printk("%s: Invalid xlport speed(%d)!\n", __func__, speed); ++ return -1; ++ } ++ ++ pm_phy_sbus_write(port, 0xc050, 0x0000, 0x0001, 8); /* SC_X4_CONTROL_CONTROL */ ++ pm_phy_sbus_write(port, 0xc050, 0x0001, 0x0001, 8); /* SC_X4_CONTROL_CONTROL */ ++ ++ enable = __xlmac_enable_get(port); ++ /* disable before updating the speed */ ++ if (enable) { ++ __xlmac_enable_set(port, 0); ++ } ++ ++ /* Update the speed */ ++ val64 = xlmac_reg64_read(XLMAC_MODE(port)); ++ val64 &= ~(0x70); ++ val64 |= speed_cfg << XLMAC_MODE__SPEED_MODE_R; ++ xlmac_reg64_write(XLMAC_MODE(port), val64); ++ debug("%s XLMAC_MODE = 0x%llx\n", __func__, xlmac_reg64_read(XLMAC_MODE(port))); ++ ++ if (enable) { ++ __xlmac_enable_set(port, 1); ++ } ++ return 0; ++} ++ ++static int __xlmac_rx_max_size_set(int port, int value) ++{ ++ u64 val64; ++ u64 mask64; ++ ++ val64 = xlmac_reg64_read(XLMAC_RX_MAX_SIZE(port)); ++ mask64 = (1 << XLMAC_RX_MAX_SIZE__RX_MAX_SIZE_WIDTH) - 1; ++ val64 &= ~(mask64 << XLMAC_RX_MAX_SIZE__RX_MAX_SIZE_R); ++ val64 |= value << XLMAC_RX_MAX_SIZE__RX_MAX_SIZE_R; ++ xlmac_reg64_write(XLMAC_RX_MAX_SIZE(port), val64); ++ ++ return 0; ++} ++ ++static int __xlmac_tx_mac_addr_set(int port, u8 *mac) ++{ ++ u64 val64; ++ ++ /* set our local address */ ++ debug("GMAC: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); ++ ++ val64 = (u64)htonl(*(u32 *)&mac[2]); ++ val64 |= ((u64)htons(*(u32 *)mac) << 32); ++ xlmac_reg64_write(XLMAC_TX_MAC_SA(port), val64); ++ ++ debug("%s XLMAC_TX_MAC_SA = 0x%llx\n", __func__, xlmac_reg64_read(XLMAC_TX_MAC_SA(port))); ++ return 0; ++} ++ ++static int __xlmac_init(int port) ++{ ++ u64 val64; ++ ++ /* Disable Tx/Rx, assume that MAC is stable (or out of reset) */ ++ val64 = xlmac_reg64_read(XLMAC_CTRL(port)); ++ val64 &= ~(1 << XLMAC_CTRL__XGMII_IPG_CHECK_DISABLE); ++ val64 &= ~(1 << XLMAC_CTRL__RX_EN); ++ val64 &= ~(1 << XLMAC_CTRL__TX_EN); ++ xlmac_reg64_write(XLMAC_CTRL(port), val64); ++ ++ /* XLMAC_RX_CTRL */ ++ val64 = xlmac_reg64_read(XLMAC_RX_CTRL(port)); ++ val64 &= ~(1 << XLMAC_RX_CTRL__STRIP_CRC); ++ xlmac_reg64_write(XLMAC_RX_CTRL(port), val64); ++ ++ /* XLMAC_TX_CTRL */ ++ val64 = xlmac_reg64_read(XLMAC_TX_CTRL(port)); ++ val64 &= ~(0x3 << XLMAC_TX_CTRL__CRC_MODE_R); ++ val64 |= (CRC_MODE_REPLACE << XLMAC_TX_CTRL__CRC_MODE_R); ++ val64 |= (1 << XLMAC_TX_CTRL__PAD_EN); ++ xlmac_reg64_write(XLMAC_TX_CTRL(port), val64); ++ ++ /* PAUSE */ ++ val64 = xlmac_reg64_read(XLMAC_PAUSE_CTRL(port)); ++ val64 |= 1 << XLMAC_PAUSE_CTRL__RX_PAUSE_EN; ++ val64 |= 1 << XLMAC_PAUSE_CTRL__TX_PAUSE_EN; ++ xlmac_reg64_write(XLMAC_PAUSE_CTRL(port), val64); ++ ++ /* PFC */ ++ val64 = xlmac_reg64_read(XLMAC_PFC_CTRL(port)); ++ val64 |= ((u64)1 << XLMAC_PFC_CTRL__PFC_REFRESH_EN); ++ xlmac_reg64_write(XLMAC_PFC_CTRL(port), val64); ++ ++ /* Set jumbo max size (8000 byte payload) */ ++ __xlmac_rx_max_size_set(port, JUMBO_MAXSZ); ++ ++ /* XLMAC_RX_LSS_CTRL */ ++ val64 = xlmac_reg64_read(XLMAC_RX_LSS_CTRL(port)); ++ val64 |= 1 << XLMAC_RX_LSS_CTRL__DROP_TX_DATA_ON_LINK_INTERRUPT; ++ val64 |= 1 << XLMAC_RX_LSS_CTRL__DROP_TX_DATA_ON_REMOTE_FAULT; ++ val64 |= 1 << XLMAC_RX_LSS_CTRL__DROP_TX_DATA_ON_LOCAL_FAULT; ++ xlmac_reg64_write(XLMAC_RX_LSS_CTRL(port), val64); ++ ++ /* Disable loopback and bring XLMAC out of reset */ ++ val64 = xlmac_reg64_read(XLMAC_CTRL(port)); ++ val64 &= ~(1 << XLMAC_CTRL__SOFT_RESET);; ++ val64 &= ~(1 << XLMAC_CTRL__LOCAL_LPBK); ++ val64 |= 1 << XLMAC_CTRL__RX_EN; ++ val64 |= 1 << XLMAC_CTRL__TX_EN; ++ xlmac_reg64_write(XLMAC_CTRL(port), val64); ++ ++ return 0; ++} ++ ++static int __tsc_reset(int in_reset) ++{ ++ u32 val; ++ ++ val = xlport_reg32_read(XLPORT_XGXS0_CTRL_REG); ++ if (in_reset) { ++ //val &= ~(7 << XLPORT_XGXS0_CTRL_REG__RefSel); ++ val |= (1 << XLPORT_XGXS0_CTRL_REG__IDDQ); ++ //val &= ~(1 << XLPORT_XGXS0_CTRL_REG__Refin_EN); ++ val |= 1 << XLPORT_XGXS0_CTRL_REG__PWRDWN; ++ val &= ~(1 << XLPORT_XGXS0_CTRL_REG__RSTB_HW); ++ } else { ++ //val |= (5 << XLPORT_XGXS0_CTRL_REG__RefSel); ++ val &= ~(1 << XLPORT_XGXS0_CTRL_REG__IDDQ); ++ //val |= (1 << XLPORT_XGXS0_CTRL_REG__Refin_EN); ++ val &= ~(1 << XLPORT_XGXS0_CTRL_REG__PWRDWN); ++ //val &= ~(0 << XLPORT_XGXS0_CTRL_REG__RSTB_HW); ++ val |= (1 << XLPORT_XGXS0_CTRL_REG__RSTB_HW); ++ } ++ xlport_reg32_write(XLPORT_XGXS0_CTRL_REG, val); ++ ++ ++/* if (!in_reset) ++ { ++ msleep(1); ++ val |= (1 << XLPORT_XGXS0_CTRL_REG__RSTB_HW); ++ xlport_reg32_write(XLPORT_XGXS0_CTRL_REG, val); ++ } */ ++ msleep(1); ++ return 0; ++} ++ ++static void pm4x10_tsc_config(int port) ++{ ++#ifdef CONFIG_IPROC_EMULATION ++ printf("skip %s... in emulation\n", __func__); ++#else ++ u32 val; ++ int i; ++ ++ /* Global PMD reset controls */ ++ pm_phy_sbus_write(port, 0x9010, 0x0000, 0xffff, 0); ++ udelay(10); ++ pm_phy_sbus_write(port, 0x9010, 0x0003, 0xffff, 0); ++ udelay(10); ++ ++ /* PMD lane reset controls */ ++ for (i=0; i<4; ++i) ++ { ++ pm_phy_sbus_write(i, 0xc010, 0x0000, 0xc003, 0); ++ udelay(10); ++ pm_phy_sbus_write(i, 0xc010, 0xc003, 0xc003, 0); ++ } ++ /* set refclk_sel = 156.25 MHz */ ++ pm_phy_sbus_write(port, 0x9000, 0x0003, 0x0007, 13); ++ /* set heartbeat_count_1us = 0x271 */ ++ pm_phy_sbus_write(port, 0xd0f4, 0x0271, 0x03ff, 0); ++#endif ++ return 0; ++} ++ ++/***************************************************************************** ++*****************************************************************************/ ++static void pm4x10_xlport_mac_enable(int port) ++{ ++ __xlmac_enable_set(port, 1); ++} ++ ++static void pm4x10_xlport_mac_disable(int port) ++{ ++ __xlmac_enable_set(port, 0); ++} ++ ++//static int pm4x10_xlport_speed_set(int port, int speed) ++int pm4x10_xlport_speed_set(int port, int speed) ++{ ++ return __xlmac_speed_set(port, speed); ++} ++ ++//static int pm4x10_xlport_mac_addr_set(int port, u8 *mac) ++int pm4x10_xlport_mac_addr_set(int port, u8 *mac) ++{ ++ return __xlmac_tx_mac_addr_set(port, mac); ++} ++ ++static int pm4x10_xlport_max_packet_size_set(int port, int value) ++{ ++ return __xlmac_rx_max_size_set(port, value); ++} ++ ++//static int pm4x10_xlport_loopback_set(int port, int lb_type, int lb_en) ++int pm4x10_xlport_loopback_set(int port, int lb_type, int lb_en) ++{ ++ u64 val64; ++ u32 val32; ++//printk(" (%s) enter.....port = %d, lb_type = %d, lb_en = %d\n", __func__, port, lb_type, lb_en); ++ ++ switch(lb_type) { ++ case pmLoopbackMac: ++ val64 = xlmac_reg64_read(XLMAC_CTRL(port)); ++ val64 &= ~(1 << XLMAC_CTRL__LOCAL_LPBK); ++ if (lb_en) { ++ printk("(%s) MAC port = %d, lb_en = %d\n", __func__, port, lb_en); ++ val64 |= (1 << XLMAC_CTRL__LOCAL_LPBK); ++ } ++ xlmac_reg64_write(XLMAC_CTRL(port), val64); ++ break; ++ ++ case pmLoopbackPhy: ++ if (lb_en) { ++ printk("(%s) PHY port = %d, lb_en = %d\n", __func__, port, lb_en); ++ pm_phy_sbus_write(port*2, 0x9009, (1 << port*2), 0x000f, 4); /* MAIN0_LOOPBACK_CONTROL */ ++ pm_phy_sbus_write(port*2, 0xc014, 0x0043, 0x0043, 0); /* PMD_X4_OVERRIDE */ ++ pm_phy_sbus_write(port*2, 0xc010, 0x0001, 0x0001, 8); /* PMD_X4_CONTROL */ ++ } else { ++ pm_phy_sbus_write(port*2, 0x9009, 0x0000, 0x000f, 4); /* MAIN0_LOOPBACK_CONTROL */ ++ pm_phy_sbus_write(port*2, 0xc014, 0x0000, 0x0043, 0); /* PMD_X4_OVERRIDE */ ++ pm_phy_sbus_write(port*2, 0xc010, 0x0000, 0x0001, 8); /* PMD_X4_CONTROL */ ++ } ++ break; ++ ++ default: ++ break; ++ } ++ return 0; ++} ++ ++//static int pm4x10_xlport_stats_get(int port, struct iproc_pm_stats *stats) ++int pm4x10_xlport_stats_get(int port, struct iproc_pm_stats *stats) ++{ ++ stats->rx_frames = xlmac_reg64_read(XLMIB_GRxPkt(port)); ++ stats->rx_frame_good = xlmac_reg64_read(XLMIB_GRxPOK(port)); ++ stats->rx_bytes = xlmac_reg64_read(XLMIB_GRxByt(port)); ++ stats->rx_frame_64 = xlmac_reg64_read(XLMIB_GRx64(port)); ++ stats->rx_frame_127 = xlmac_reg64_read(XLMIB_GRx127(port)); ++ stats->rx_frame_255 = xlmac_reg64_read(XLMIB_GRx255(port)); ++ stats->rx_frame_511 = xlmac_reg64_read(XLMIB_GRx511(port)); ++ stats->rx_frame_1023 = xlmac_reg64_read(XLMIB_GRx1023(port)); ++ stats->rx_frame_1518 = xlmac_reg64_read(XLMIB_GRx1518(port)); ++ stats->rx_frame_1522 = xlmac_reg64_read(XLMIB_GRx1522(port)); ++ stats->rx_frame_jumbo = xlmac_reg64_read(XLMIB_GRx2047(port)) + ++ xlmac_reg64_read(XLMIB_GRx4095(port)) + ++ xlmac_reg64_read(XLMIB_GRx9216(port)) + ++ xlmac_reg64_read(XLMIB_GRx16383(port)); ++ stats->rx_frame_unicast = xlmac_reg64_read(XLMIB_GRxUCA(port)); ++ stats->rx_frame_multicast = xlmac_reg64_read(XLMIB_GRxMCA(port)); ++ stats->rx_frame_broadcast = xlmac_reg64_read(XLMIB_GRxBCA(port)); ++ stats->rx_frame_control = xlmac_reg64_read(XLMIB_GRxCF(port)); ++ stats->rx_frame_pause = xlmac_reg64_read(XLMIB_GRxPF(port)); ++ stats->rx_frame_jabber = xlmac_reg64_read(XLMIB_GRxJBR(port)); ++ stats->rx_frame_fragment = xlmac_reg64_read(XLMIB_GRxFRG(port)); ++ stats->rx_frame_vlan = xlmac_reg64_read(XLMIB_GRxVLN(port)); ++ stats->rx_frame_dvlan = xlmac_reg64_read(XLMIB_GRxDVLN(port)); ++ stats->rx_frame_fcs_error = xlmac_reg64_read(XLMIB_GRxFCS(port)); ++ stats->rx_frame_unsupport = xlmac_reg64_read(XLMIB_GRxUO(port)); ++ stats->rx_frame_wrong_sa = xlmac_reg64_read(XLMIB_GRxWSA(port)); ++ stats->rx_frame_align_err = xlmac_reg64_read(XLMIB_GRxALN(port)); ++ stats->rx_frame_length_err = xlmac_reg64_read(XLMIB_GRxFLR(port)); ++ stats->rx_frame_oversize = xlmac_reg64_read(XLMIB_GRxOVR(port)); ++ stats->rx_frame_mtu_err = xlmac_reg64_read(XLMIB_GRxMTUE(port)); ++ stats->rx_frame_truncated_err = xlmac_reg64_read(XLMIB_GRxTRFU(port)); ++ stats->rx_frame_undersize = xlmac_reg64_read(XLMIB_GRxUND(port)); ++ stats->tx_frames = xlmac_reg64_read(XLMIB_GTxPkt(port)); ++ stats->tx_frame_good = xlmac_reg64_read(XLMIB_GTxPOK(port)); ++ stats->tx_bytes = xlmac_reg64_read(XLMIB_GTxBYT(port)); ++ stats->tx_frame_64 = xlmac_reg64_read(XLMIB_GTx64(port)); ++ stats->tx_frame_127 = xlmac_reg64_read(XLMIB_GTx127(port)); ++ stats->tx_frame_255 = xlmac_reg64_read(XLMIB_GTx255(port)); ++ stats->tx_frame_511 = xlmac_reg64_read(XLMIB_GTx511(port)); ++ stats->tx_frame_1023 = xlmac_reg64_read(XLMIB_GTx1023(port)); ++ stats->tx_frame_1518 = xlmac_reg64_read(XLMIB_GTx1518(port)); ++ stats->tx_frame_1522 = xlmac_reg64_read(XLMIB_GTx1522(port)); ++ stats->tx_frame_jumbo = xlmac_reg64_read(XLMIB_GTx2047(port)) + ++ xlmac_reg64_read(XLMIB_GTx4095(port)) + ++ xlmac_reg64_read(XLMIB_GTx9216(port)) + ++ xlmac_reg64_read(XLMIB_GTx16383(port)); ++ stats->tx_frame_unicast = xlmac_reg64_read(XLMIB_GTxUCA(port)); ++ stats->tx_frame_multicast = xlmac_reg64_read(XLMIB_GTxMCA(port)); ++ stats->tx_frame_broadcast = xlmac_reg64_read(XLMIB_GTxBCA(port)); ++ stats->tx_frame_control = xlmac_reg64_read(XLMIB_GTxCF(port)); ++ stats->tx_frame_pause = xlmac_reg64_read(XLMIB_GTxPF(port)); ++ stats->tx_frame_jabber = xlmac_reg64_read(XLMIB_GTxJBR(port)); ++ stats->tx_frame_fragment = xlmac_reg64_read(XLMIB_GTxFRG(port)); ++ stats->tx_frame_vlan = xlmac_reg64_read(XLMIB_GTxVLN(port)); ++ stats->tx_frame_dvlan = xlmac_reg64_read(XLMIB_GTxDVLN(port)); ++ stats->tx_frame_fcs_error = xlmac_reg64_read(XLMIB_GTxFCS(port)); ++ stats->tx_frame_oversize = xlmac_reg64_read(XLMIB_GTxOVR(port)); ++ stats->tx_frame_error = xlmac_reg64_read(XLMIB_GTxErr(port)); ++ stats->tx_frame_fifo_underrun = xlmac_reg64_read(XLMIB_GTxUFL(port)); ++ stats->tx_frame_collision = xlmac_reg64_read(XLMIB_GTxNCL(port)); ++ ++ return 0; ++} ++ ++//static int pm4x10_xlport_mib_reset(int port) ++int pm4x10_xlport_mib_reset(int port) ++{ ++ u32 val; ++ ++ /* MIB reset */ ++ val = xlport_reg32_read(XLPORT_MIB_RESET); ++ val |= (1 << port) << XLPORT_MIB_RESET__CLR_CNT_R; ++ xlport_reg32_write(XLPORT_MIB_RESET, val); ++ ++ val &= ~((1 << port) << XLPORT_MIB_RESET__CLR_CNT_R); ++ xlport_reg32_write(XLPORT_MIB_RESET, val); ++ ++ return 0; ++} ++ ++//static int pm4x10_pm_xlport_port_config(int port, int enable) ++int pm4x10_pm_xlport_port_config(int port, int enable) ++{ ++ u32 val; ++ ++ if (enable) { ++ /* Soft reset */ ++ val = xlport_reg32_read(XLPORT_SOFT_RESET); ++ XLPORT_PORT_FIELD_SET(XLPORT_SOFT_RESET, port, val); ++ xlport_reg32_write(XLPORT_SOFT_RESET, val); ++ ++ XLPORT_PORT_FIELD_CLEAR(XLPORT_SOFT_RESET, port, val); ++ xlport_reg32_write(XLPORT_SOFT_RESET, val); ++ ++ /* Port enable */ ++ val = xlport_reg32_read(XLPORT_ENABLE_REG); ++ XLPORT_PORT_FIELD_SET(XLPORT_ENABLE_REG, port, val); ++ xlport_reg32_write(XLPORT_ENABLE_REG, val); ++ ++ /* Init MAC */ ++ __xlmac_init(port); ++ ++#if 0 //FIXME ++ /* LSS */ ++ val = xlport_reg32_read(XLPORT_FAULT_LINK_STATUS(port)); ++ val |= 1 << XLPORT_FAULT_LINK_STATUS__REMOTE_FAULT; ++ val |= 1 << XLPORT_FAULT_LINK_STATUS__LOCAL_FAULT; ++ xlport_reg32_write(XLPORT_FAULT_LINK_STATUS(port), val); ++#endif /* 0 */ ++ ++ /* MIB reset */ ++ val = xlport_reg32_read(XLPORT_MIB_RESET); ++ val |= (1 << port) << XLPORT_MIB_RESET__CLR_CNT_R; ++ xlport_reg32_write(XLPORT_MIB_RESET, val); ++ ++ val &= ~((1 << port) << XLPORT_MIB_RESET__CLR_CNT_R); ++ xlport_reg32_write(XLPORT_MIB_RESET, val); ++ } else { ++ /* Port disable */ ++ val = xlport_reg32_read(XLPORT_ENABLE_REG); ++ XLPORT_PORT_FIELD_CLEAR(XLPORT_ENABLE_REG, port, val); ++ xlport_reg32_write(XLPORT_ENABLE_REG, val); ++ ++ /* Soft reset */ ++ val = xlport_reg32_read(XLPORT_SOFT_RESET); ++ XLPORT_PORT_FIELD_CLEAR(XLPORT_SOFT_RESET, port, val); ++ xlport_reg32_write(XLPORT_SOFT_RESET, val); ++ } ++ ++ return 0; ++} ++ ++static int pm4x10_pm_disable(void) ++{ ++ u32 val; ++ ++ /* Put MAC in reset */ ++ val = xlport_reg32_read(XLPORT_MAC_CONTROL); ++ val |= 1 << XLPORT_MAC_CONTROL__XMAC0_RESET; ++ xlport_reg32_write(XLPORT_MAC_CONTROL, val); ++ ++ /* Put Serdes in reset*/ ++ __tsc_reset(1); ++ ++ return 0; ++} ++ ++static int pm4x10_pm_enable(void) ++{ ++ u32 val; ++ u32 mask; ++ ++ /* Power Save */ ++ val = xlport_reg32_read(XLPORT_POWER_SAVE); ++ val &= ~(1 << XLPORT_POWER_SAVE__XPORT_CORE0); ++ xlport_reg32_write(XLPORT_POWER_SAVE, val); ++ ++ /* Port configuration */ ++ val = xlport_reg32_read(XLPORT_MODE_REG); ++ mask = (1 << XLPORT_MODE_REG__XPORT0_CORE_PORT_MODE_WIDTH) - 1; ++ val &= ~(mask << XLPORT_MODE_REG__XPORT0_CORE_PORT_MODE_R); ++ val |= (XPORT0_CORE_PORT_MODE_QUAD << XLPORT_MODE_REG__XPORT0_CORE_PORT_MODE_R); ++ mask = (1 << XLPORT_MODE_REG__XPORT0_PHY_PORT_MODE_WIDTH) - 1; ++ val &= ~(mask << XLPORT_MODE_REG__XPORT0_PHY_PORT_MODE_R); ++ val |= (XPORT0_CORE_PORT_MODE_QUAD << XLPORT_MODE_REG__XPORT0_PHY_PORT_MODE_R); ++ xlport_reg32_write(XLPORT_MODE_REG, val); ++ ++ /* Get Serdes OOR */ ++ __tsc_reset(1); ++ __tsc_reset(0); ++ ++ /* Bring MAC OOR */ ++ val = xlport_reg32_read(XLPORT_MAC_CONTROL); ++ val &= ~(1 << XLPORT_MAC_CONTROL__XMAC0_RESET); ++ xlport_reg32_write(XLPORT_MAC_CONTROL, val); ++ ++ return 0; ++} ++ ++int pm4x10_pm_init(struct iproc_pm_ops *pm_ops, u8 land_idx) ++{ ++#if 0 ++ pm_ops = kmalloc(sizeof(struct iproc_pm_ops), GFP_KERNEL); ++ if (!pm_ops) { ++ return -ENOMEM; ++ } ++ pm_ops->port_enable= pm4x10_pm_xlport_port_config; ++ pm_ops->port_speed = pm4x10_xlport_speed_set; ++ pm_ops->port_loopback = pm4x10_xlport_loopback_set; ++ pm_ops->port_mac_addr = pm4x10_xlport_mac_addr_set; ++ pm_ops->port_stats = pm4x10_xlport_stats_get; ++ pm_ops->port_stats_clear = pm4x10_xlport_mib_reset; ++#endif ++ ++#if 0 ++ if (!pm4x10_enabled) /* check initialize for first time */ ++#else ++ if (pm4x10_enabled == 0x100) /* don't do it now */ ++#endif ++ { ++ /* configure TSC registers before download ucode */ ++ pm4x10_tsc_config(land_idx); ++ ++ /* ucode download */ ++ pm_ucode_download(merlin16_ucode, merlin16_ucode_len); ++ ++ /* Configure TSC/merlin16 registers */ ++ pm_phy_configure(land_idx); ++ ++ /* Enable PM4x10 */ ++ pm4x10_pm_enable(); ++ pm4x10_enabled++; ++ } ++ ++ return 0; ++} ++ ++int pm4x10_pm_deinit(struct iproc_pm_ops *pm_ops) ++{ ++#if 0 ++ kfree(pm_ops); ++ pm_ops = NULL; ++#endif ++ pm4x10_enabled--; ++ if (!pm4x10_enabled) { ++ pm4x10_pm_disable(); ++ } ++ ++ return 0; ++} ++ ++#if 0 ++static void pm4x10_xlport_config(int port) ++{ ++ u32 val; ++ u64 val64; ++ ++ /* xlport_mac_config */ ++ val = xlport_reg32_read(XLPORT_ENABLE_REG); ++ val |= ((1 << XLPORT_ENABLE_REG__PORT0) | (1 << XLPORT_ENABLE_REG__PORT2)); ++ xlport_reg32_write(XLPORT_ENABLE_REG, val); ++ debug("%s XLPORT_ENABLE_REG = 0x%x\n", __func__, xlport_reg32_read(XLPORT_ENABLE_REG)); ++ ++ val = xlport_reg32_read(XLPORT_MAC_CONTROL); ++ val &= ~(1 << XLPORT_MAC_CONTROL__XMAC0_RESET); ++ xlport_reg32_write(XLPORT_MAC_CONTROL, val); ++ ++ /* xlport_intr_enable ? */ ++ ++ /* Resetting MIB counter */ ++ xlport_reg32_write(XLPORT_MIB_RESET, 0xf); ++ /* FIXME : delay? */ ++ /* udelay(10); */ ++ xlport_reg32_write(XLPORT_MIB_RESET, 0x0); ++ ++ /* Ethernet mode, 1G */ ++ val64 = xlmac_reg64_read(XLMAC_MODE(port)); ++ val64 &= ~(0x70); ++ val64 |= SPEED_MODE_LINK_1G << XLMAC_MODE__SPEED_MODE_R; ++ xlmac_reg64_write(XLMAC_MODE(port), val64); ++ debug("%s XLMAC_MODE = 0x%llx\n", __func__, xlmac_reg64_read(XLMAC_MODE(port))); ++ ++ val64 = xlmac_reg64_read(XLMAC_RX_CTRL(port)); ++ val64 &= ~(1 << XLMAC_RX_CTRL__STRIP_CRC); ++ xlmac_reg64_write(XLMAC_RX_CTRL(port), val64); ++ debug("%s XLMAC_RX_CTRL = 0x%llx\n", __func__, xlmac_reg64_read(XLMAC_RX_CTRL(port))); ++ ++ val64 = xlmac_reg64_read(XLMAC_TX_CTRL(port)); ++ val64 &= ~(0x3 << XLMAC_TX_CTRL__CRC_MODE_R); ++ val64 |= (CRC_MODE_REPLACE << XLMAC_TX_CTRL__CRC_MODE_R); ++ val64 |= (1 << XLMAC_TX_CTRL__PAD_EN); ++ xlmac_reg64_write(XLMAC_TX_CTRL(port), val64); ++ debug("%s XLMAC_TX_CTRL = 0x%llx\n", __func__, xlmac_reg64_read(XLMAC_TX_CTRL(port))); ++ ++#if 0 ++ val64 = xlmac_reg64_read(XLMAC_CTRL(port)); ++ val64 &= ~(1 << XLMAC_CTRL__SOFT_RESET); ++ val64 |= ((1 << XLMAC_CTRL__RX_EN) | (1 << XLMAC_CTRL__TX_EN)); ++ xlmac_reg64_write(XLMAC_CTRL(port), val64); ++ debug("%s XLMAC_CTRL = 0x%llx\n", __func__, xlmac_reg64_read(XLMAC_CTRL(port))); ++#endif ++} ++#endif /* 0 */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig +--- a/drivers/net/phy/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/net/phy/Kconfig 2018-05-10 11:31:32.077402284 +0800 +@@ -198,6 +198,14 @@ config LED_TRIGGER_PHY + Mbps or Gbps + + ++config MDIO_XGS_IPROC ++ tristate "Broadcom XGS iProc MDIO bus controller" ++ depends on ARCH_XGS_IPROC || COMPILE_TEST ++ depends on HAS_IOMEM && OF_MDIO ++ help ++ This module provides a driver for the MDIO busses found in the ++ Broadcom XGS iProc SoC's. ++ + comment "MII PHY device drivers" + + config SFP +@@ -262,6 +270,12 @@ config BROADCOM_PHY + Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464, + BCM5481, BCM54810 and BCM5482 PHYs. + ++config XGS_IPROC_SERDES ++ tristate "Broadcom XGS iProc SERDES" ++ depends on MDIO_XGS_IPROC ++ ---help--- ++ Supports HX4/KT2/GH2 SERDES. ++ + config CICADA_PHY + tristate "Cicada PHYs" + ---help--- +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile +--- a/drivers/net/phy/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/net/phy/Makefile 2018-05-10 11:31:32.081402288 +0800 +@@ -38,6 +38,7 @@ obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon + obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o + obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o + obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o ++obj-$(CONFIG_MDIO_XGS_IPROC) += mdio-xgs-iproc-cmicx.o mdio-xgs-iproc-cmicd.o mdio-xgs-iproc-cc.o + + obj-$(CONFIG_SFP) += sfp.o + sfp-obj-$(CONFIG_SFP) += sfp-bus.o +@@ -52,6 +53,7 @@ obj-$(CONFIG_BCM87XX_PHY) += bcm87xx.o + obj-$(CONFIG_BCM_CYGNUS_PHY) += bcm-cygnus.o + obj-$(CONFIG_BCM_NET_PHYLIB) += bcm-phy-lib.o + obj-$(CONFIG_BROADCOM_PHY) += broadcom.o ++obj-$(CONFIG_XGS_IPROC_SERDES) += xgs-iproc-serdes.o + obj-$(CONFIG_CICADA_PHY) += cicada.o + obj-$(CONFIG_CORTINA_PHY) += cortina.o + obj-$(CONFIG_DAVICOM_PHY) += davicom.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/mdio-xgs-iproc-cc.c b/drivers/net/phy/mdio-xgs-iproc-cc.c +--- a/drivers/net/phy/mdio-xgs-iproc-cc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/phy/mdio-xgs-iproc-cc.c 2018-05-10 11:31:32.085402292 +0800 +@@ -0,0 +1,492 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "mdio-xgs-iproc.h" ++ ++#define MGMT_CTL_REG 0x000 ++#define MGMT_CTL__BYP_SHIFT 10 ++#define MGMT_CTL__BYP_WIDTH 1 ++#define MGMT_CTL__BYP_MASK ((1 << MGMT_CTL__BYP_WIDTH) - 1) ++#define MGMT_CTL__EXT_SHIFT 9 ++#define MGMT_CTL__EXT_WIDTH 1 ++#define MGMT_CTL__EXT_MASK ((1 << MGMT_CTL__EXT_WIDTH) - 1) ++#define MGMT_CTL__BSY_SHIFT 8 ++#define MGMT_CTL__BSY_WIDTH 1 ++#define MGMT_CTL__BSY_MASK ((1 << MGMT_CTL__BSY_WIDTH) - 1) ++#define MGMT_CTL__PRE_SHIFT 7 ++#define MGMT_CTL__PRE_WIDTH 1 ++#define MGMT_CTL__PRE_MASK ((1 << MGMT_CTL__BSY_WIDTH) - 1) ++#define MGMT_CTL__MDCDIV_SHIFT 0 ++#define MGMT_CTL__MDCDIV_WIDTH 7 ++#define MGMT_CTL__MDCDIV_MASK ((1 << MGMT_CTL__MDCDIV_WIDTH) - 1) ++ ++#define MGMT_CMD_DATA_REG 0x004 ++#define MGMT_CMD_DATA__SB_SHIFT 30 ++#define MGMT_CMD_DATA__SB_WIDTH 2 ++#define MGMT_CMD_DATA__SB_MASK ((1 << MGMT_CMD_DATA__SB_WIDTH) - 1) ++#define MGMT_CMD_DATA__OP_SHIFT 28 ++#define MGMT_CMD_DATA__OP_WIDTH 2 ++#define MGMT_CMD_DATA__OP_MASK ((1 << MGMT_CMD_DATA__OP_WIDTH) - 1) ++#define MGMT_CMD_DATA__PA_SHIFT 23 ++#define MGMT_CMD_DATA__PA_WIDTH 5 ++#define MGMT_CMD_DATA__PA_MASK ((1 << MGMT_CMD_DATA__PA_WIDTH) - 1) ++#define MGMT_CMD_DATA__RA_SHIFT 18 ++#define MGMT_CMD_DATA__RA_WIDTH 5 ++#define MGMT_CMD_DATA__RA_MASK ((1 << MGMT_CMD_DATA__RA_WIDTH) - 1) ++#define MGMT_CMD_DATA__TA_SHIFT 16 ++#define MGMT_CMD_DATA__TA_WIDTH 2 ++#define MGMT_CMD_DATA__TA_MASK ((1 << MGMT_CMD_DATA__TA_WIDTH) - 1) ++#define MGMT_CMD_DATA__DATA_SHIFT 0 ++#define MGMT_CMD_DATA__DATA_WIDTH 16 ++#define MGMT_CMD_DATA__DATA_MASK ((1 << MGMT_CMD_DATA__DATA_WIDTH) - 1) ++ ++#define MII_OP_HALT_USEC 10 ++ ++struct cc_mii_cmd { ++ int bus_id; ++ int ext_sel; ++ int phy_id; ++ int regnum; ++ u16 op_mode; ++ u16 val; ++}; ++ ++static struct iproc_mdio_ctrl *cc_mdio_ctrl = NULL; ++ ++/* ++ * For HX4/KT2, the mdio bus is shared with iProc mdio and CMICd mdio ++ * controllers. By default the mdio bus is released to CMICd for SDK to run. ++ * Set kernel argument mdio_bus_release to 0 if ethtool test is required. ++ */ ++static bool mdio_bus_release = true; ++static int __init set_mdio_bus_release(char *str) ++{ ++ return strtobool(str, &mdio_bus_release); ++} ++__setup("mdio_bus_release=", set_mdio_bus_release); ++ ++ ++/* HX4/KT2 need to release mdio bus from iProc to cmicd */ ++bool xgs_mdio_bus_release(void) ++{ ++ if (of_machine_is_compatible("brcm,helix4") || ++ of_machine_is_compatible("brcm,katana2")) ++ return mdio_bus_release; ++ else ++ return 0; ++} ++ ++/* HX4/KT2/SB2 needs to enable iProc mdio bus access, default is cimcd access */ ++static void xgs_iproc_mdio_enable(struct iproc_mdio_ctrl *ctrl, int enable) ++{ ++ void __iomem *iproc_mdio_enable_reg = NULL; ++ u32 iproc_mdio_sel; ++ u32 tmp; ++ ++ if (!ctrl->iproc_mdio_enable_reg) ++ return; ++ ++ iproc_mdio_enable_reg = ctrl->iproc_mdio_enable_reg; ++ iproc_mdio_sel = ctrl->iproc_mdio_sel_bit; ++ ++ tmp = readl(iproc_mdio_enable_reg); ++ ++ if (enable) ++ tmp |= (1 << iproc_mdio_sel); ++ else ++ tmp &= ~(1 << iproc_mdio_sel); ++ ++ writel(tmp, iproc_mdio_enable_reg); ++} ++ ++static inline u32 cc_mii_reg_read(struct iproc_mdio_ctrl *cc_mii, u32 reg) ++{ ++ return readl(cc_mii->base + reg); ++} ++ ++static inline void cc_mii_reg_write(struct iproc_mdio_ctrl *cc_mii, ++ u32 reg, u32 data) ++{ ++ writel(data, cc_mii->base + reg); ++} ++ ++static int cc_mii_busy(struct iproc_mdio_ctrl *cc_mii, int to_usec) ++{ ++ do { ++ if(!GET_REG_FIELD(cc_mii_reg_read(cc_mii, MGMT_CTL_REG), ++ MGMT_CTL__BSY_SHIFT, MGMT_CTL__BSY_MASK)) ++ return 0; ++ ++ udelay(MII_OP_HALT_USEC); ++ to_usec -= MII_OP_HALT_USEC; ++ } while (to_usec > 0); ++ ++ return 1; ++} ++ ++static int do_cc_mii_op(struct iproc_mdio_ctrl *cc_mii, struct cc_mii_cmd *cmd) ++{ ++ u32 cmd_data = 0; ++ u32 mgt_ctrl; ++ u32 op_mode = cmd->op_mode; ++ unsigned long flags; ++ int ret = 0; ++ ++ if (MII_OP_MODE_WRITE == op_mode) { ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__OP_SHIFT, ++ MGMT_CMD_DATA__OP_MASK, 1); ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__DATA_SHIFT, ++ MGMT_CMD_DATA__DATA_MASK, cmd->val); ++ } ++ else if (MII_OP_MODE_READ == op_mode) { ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__OP_SHIFT, ++ MGMT_CMD_DATA__OP_MASK, 2); ++ } ++ else { ++ pr_err("%s : invalid op code %d\n", __func__, op_mode); ++ return -EINVAL; ++ } ++ ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__PA_SHIFT, ++ MGMT_CMD_DATA__PA_MASK, cmd->phy_id); ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__RA_SHIFT, ++ MGMT_CMD_DATA__RA_MASK, cmd->regnum); ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__TA_SHIFT, ++ MGMT_CMD_DATA__TA_MASK, 2); ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__SB_SHIFT, ++ MGMT_CMD_DATA__SB_MASK, 1); ++ ++ spin_lock_irqsave(&cc_mii->lock, flags); ++ ++ if (cc_mii_busy(cc_mii, MII_OP_MAX_HALT_USEC)) { ++ ret = -EBUSY; ++ pr_err("%s : bus busy (1)\n", __func__); ++ goto err_exit_unlock; ++ } ++ ++ mgt_ctrl = cc_mii_reg_read(cc_mii, MGMT_CTL_REG); ++ if (cmd->ext_sel != GET_REG_FIELD(mgt_ctrl, MGMT_CTL__EXT_SHIFT, ++ MGMT_CTL__EXT_MASK)) { ++ SET_REG_FIELD(mgt_ctrl, MGMT_CTL__EXT_SHIFT, ++ MGMT_CTL__EXT_MASK, cmd->ext_sel); ++ cc_mii_reg_write(cc_mii, MGMT_CTL_REG, mgt_ctrl); ++ } ++ ++ cc_mii_reg_write(cc_mii, MGMT_CMD_DATA_REG, cmd_data); ++ ++ if (cc_mii_busy(cc_mii, MII_OP_MAX_HALT_USEC)) { ++ ret = -EBUSY; ++ pr_err("%s : bus busy (2)\n", __func__); ++ goto err_exit_unlock; ++ } ++ ++ if (MII_OP_MODE_READ == cmd->op_mode) { ++ ret = GET_REG_FIELD(cc_mii_reg_read(cc_mii, MGMT_CMD_DATA_REG), ++ MGMT_CMD_DATA__DATA_SHIFT, MGMT_CMD_DATA__DATA_MASK); ++ } ++ ++ spin_unlock_irqrestore(&cc_mii->lock, flags); ++ ++ return ret; ++ ++err_exit_unlock: ++ spin_unlock_irqrestore(&cc_mii->lock, flags); ++ return ret; ++} ++ ++static int cc_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum) ++{ ++ struct iproc_mdiobus_private *bus_priv = bus->priv; ++ struct iproc_mdiobus_data *bus_data = bus_priv->bus_data; ++ struct cc_mii_cmd cmd = {0}; ++ int ret; ++ ++ xgs_iproc_mdio_enable(bus_priv->hw_ctrl, 1); ++ ++ cmd.bus_id = bus_data->phybus_num; ++ if (IPROC_MDIOBUS_TYPE_EXTERNAL == bus_data->phybus_type) ++ cmd.ext_sel = 1; ++ cmd.phy_id = phy_id; ++ cmd.regnum = regnum; ++ cmd.op_mode = MII_OP_MODE_READ; ++ ++ ret = do_cc_mii_op(bus_priv->hw_ctrl, &cmd); ++ ++ xgs_iproc_mdio_enable(bus_priv->hw_ctrl, 0); ++ ++ return ret; ++} ++ ++static int cc_mdiobus_write(struct mii_bus *bus, int phy_id, ++ int regnum, u16 val) ++{ ++ struct iproc_mdiobus_private *bus_priv = bus->priv; ++ struct iproc_mdiobus_data *bus_data = bus_priv->bus_data; ++ struct cc_mii_cmd cmd = {0}; ++ int ret; ++ ++ xgs_iproc_mdio_enable(bus_priv->hw_ctrl, 1); ++ ++ cmd.bus_id = bus_data->phybus_num; ++ ++ if (IPROC_MDIOBUS_TYPE_EXTERNAL == bus_data->phybus_type) ++ cmd.ext_sel = 1; ++ ++ cmd.phy_id = phy_id; ++ cmd.regnum = regnum; ++ cmd.op_mode = MII_OP_MODE_WRITE; ++ cmd.val = val; ++ ++ ret = do_cc_mii_op(bus_priv->hw_ctrl, &cmd); ++ ++ xgs_iproc_mdio_enable(bus_priv->hw_ctrl, 0); ++ ++ return ret; ++} ++ ++static struct iproc_mdio_ctrl * cc_mdio_res_alloc(void) ++{ ++ if (!cc_mdio_ctrl) { ++ cc_mdio_ctrl = kzalloc(sizeof(*cc_mdio_ctrl), GFP_KERNEL); ++ if (!cc_mdio_ctrl) ++ return NULL; ++ ++ spin_lock_init(&cc_mdio_ctrl->lock); ++ cc_mdio_ctrl->ref_cnt = 1; ++ } ++ else ++ cc_mdio_ctrl->ref_cnt++; ++ ++ return cc_mdio_ctrl; ++} ++ ++static void cc_mdio_res_free(struct iproc_mdio_ctrl *ctrl) ++{ ++ if (ctrl) { ++ ctrl->ref_cnt--; ++ if (ctrl->ref_cnt == 0) { ++ iounmap(ctrl->base); ++ kfree(ctrl); ++ cc_mdio_ctrl = NULL; ++ } ++ } ++} ++ ++static void cc_mii_init(struct iproc_mdio_ctrl *cc_mii, u32 mdio_clk_rate) ++{ ++ u32 val = 0; ++ ++ if(cc_mii->ref_cnt == 1) { ++ /* Set preamble enabled */ ++ ISET_REG_FIELD(val, MGMT_CTL__PRE_SHIFT, MGMT_CTL__PRE_MASK, 1); ++ /* Set the MII clock to 1 MHz */ ++ ISET_REG_FIELD(val, MGMT_CTL__MDCDIV_SHIFT, MGMT_CTL__MDCDIV_MASK, ++ mdio_clk_rate/(1000000)); ++ cc_mii_reg_write(cc_mii, MGMT_CTL_REG, val); ++ } ++} ++ ++static int cc_mdiobus_probe(struct platform_device *pdev) ++{ ++ struct mii_bus *mii_bus; ++ struct device_node *dn = pdev->dev.of_node; ++ struct resource *res; ++ struct iproc_mdiobus_private *bus_priv; ++ struct iproc_mdiobus_data *bus_data; ++ struct iproc_mdio_ctrl *cc_ctrl; ++ u32 mdio_clk_rate; ++ const char *mdio_bus_type; ++ struct clk *clk=NULL; ++ int ret; ++ ++ /* hw_ctrl is shared */ ++ if (cc_mdio_ctrl) ++ goto hw_ctrl_allocated; ++ ++ cc_ctrl = cc_mdio_res_alloc(); ++ if (!cc_ctrl) { ++ dev_err(&pdev->dev, "CC mdio resource alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_exit; ++ } ++ ++ cc_ctrl->base = (void *)of_iomap(dn, 0); ++ if (!cc_ctrl->base) { ++ dev_err(&pdev->dev, "cc mdio register base map error\n"); ++ ret = -ENXIO; ++ goto err_ctrl_free; ++ } ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, ++ "iproc-mdio-enable"); ++ if (res) { ++ cc_ctrl->iproc_mdio_enable_reg = ++ devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(cc_ctrl->iproc_mdio_enable_reg)) { ++ ret = PTR_ERR(cc_ctrl->iproc_mdio_enable_reg); ++ goto err_ctrl_free; ++ } ++ } ++ ++ if (cc_ctrl->iproc_mdio_enable_reg) { ++ if (of_property_read_u32(dn, "iproc-mdio-sel-bit", ++ &cc_ctrl->iproc_mdio_sel_bit)) { ++ dev_err(&pdev->dev, "No mdio bus select bit!\n"); ++ ret = -EINVAL; ++ goto err_ctrl_free; ++ } ++ } ++ ++hw_ctrl_allocated: ++ cc_ctrl = cc_mdio_ctrl; ++ ++ clk = of_clk_get(dn, 0); ++ if (clk) { ++ mdio_clk_rate = clk_get_rate(clk) / 2; ++ } else { ++ dev_warn(&pdev->dev, "No CC MDIO clock available in DT, \ ++ use default clock rate: 50MHz\n"); ++ mdio_clk_rate = 50000000; ++ } ++ ++ cc_mii_init(cc_ctrl, mdio_clk_rate); ++ ++ /* If no property available, use default: "internal" */ ++ if (of_property_read_string(dn, "bus-type", &mdio_bus_type)) ++ mdio_bus_type = "internal"; ++ ++ bus_data = devm_kzalloc(&pdev->dev, sizeof(*bus_data), GFP_KERNEL); ++ if (!bus_data) { ++ dev_err(&pdev->dev, "iProc MDIO bus data alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_bus_data_free; ++ } ++ ++ bus_priv = devm_kzalloc(&pdev->dev, sizeof(*bus_priv), GFP_KERNEL); ++ if (!bus_priv) { ++ dev_err(&pdev->dev, "iProc MDIO private data alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_bus_priv_free; ++ } ++ ++ if (!strcmp(mdio_bus_type, "internal")) ++ bus_data->phybus_type = IPROC_MDIOBUS_TYPE_INTERNAL; ++ else ++ bus_data->phybus_type = IPROC_MDIOBUS_TYPE_EXTERNAL; ++ ++ bus_priv->bus_data = bus_data; ++ bus_priv->hw_ctrl = cc_ctrl; ++ ++ mii_bus = mdiobus_alloc(); ++ if (!mii_bus) { ++ dev_err(&pdev->dev, "mdiobus alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_ctrl_free; ++ } ++ ++ mii_bus->name = "iproc_cc_mdiobus"; ++ snprintf(mii_bus->id, MII_BUS_ID_SIZE, "%s-%s", "cc mdio", ++ bus_data->phybus_type? "external":"internal"); ++ mii_bus->parent = &pdev->dev; ++ mii_bus->read = cc_mdiobus_read; ++ mii_bus->write = cc_mdiobus_write; ++ mii_bus->priv = bus_priv; ++ ++ ret = of_mdiobus_register(mii_bus, dn); ++ if (ret) { ++ dev_err(&pdev->dev, "mdiobus register failed\n"); ++ goto err_bus_free; ++ } ++ ++ platform_set_drvdata(pdev, mii_bus); ++ ++ return 0; ++ ++err_bus_free: ++ mdiobus_free(mii_bus); ++err_bus_priv_free: ++ kfree(bus_priv); ++err_bus_data_free: ++ kfree(bus_data); ++err_ctrl_free: ++ cc_mdio_res_free(cc_ctrl); ++err_exit: ++ return ret; ++} ++ ++static int cc_mdiobus_remove(struct platform_device *pdev) ++{ ++ struct mii_bus *mii_bus = platform_get_drvdata(pdev); ++ struct iproc_mdiobus_private *bus_priv; ++ ++ if (mii_bus) { ++ bus_priv = mii_bus->priv; ++ ++ mdiobus_unregister(mii_bus); ++ if (bus_priv) ++ cc_mdio_res_free(bus_priv->hw_ctrl); ++ mdiobus_free(mii_bus); ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id cc_mdio_dt_ids[] = { ++ { .compatible = "brcm,iproc-ccb-mdio"}, ++ { .compatible = "brcm,iproc-ccg-mdio"}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, cc_mdio_dt_ids); ++ ++ ++static struct platform_driver iproc_cc_mdiobus_driver = ++{ ++ .driver = { ++ .name = "iproc_cc_mdio", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(cc_mdio_dt_ids), ++ }, ++ .probe = cc_mdiobus_probe, ++ .remove = cc_mdiobus_remove, ++}; ++ ++static int __init cc_mdio_init(void) ++{ ++ return platform_driver_register(&iproc_cc_mdiobus_driver); ++} ++ ++static void __exit cc_mdio_exit(void) ++{ ++ platform_driver_unregister(&iproc_cc_mdiobus_driver); ++} ++ ++//module_init(cc_mdio_init); ++subsys_initcall(cc_mdio_init); ++module_exit(cc_mdio_exit); ++ ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_DESCRIPTION("iProc CC mdio driver"); ++MODULE_LICENSE("GPL"); ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/mdio-xgs-iproc-cmicd.c b/drivers/net/phy/mdio-xgs-iproc-cmicd.c +--- a/drivers/net/phy/mdio-xgs-iproc-cmicd.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/phy/mdio-xgs-iproc-cmicd.c 2018-05-10 11:31:32.085402292 +0800 +@@ -0,0 +1,457 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mdio-xgs-iproc.h" ++ ++/* CMICD MDIO */ ++#define CMIC_MIIM_PARAM_OFFSET 0x080 ++#define CMIC_MIIM_PARAM_MIIM_CYCLE_R 29 ++#define CMIC_MIIM_PARAM_MIIM_CYCLE_W 3 ++#define CMIC_MIIM_PARAM_INTERNAL_SEL 25 ++#define CMIC_MIIM_PARAM_INTERNAL_SEL_W 1 ++#define CMIC_MIIM_PARAM_BUS_ID_R 22 ++#define CMIC_MIIM_PARAM_BUS_ID_W 3 ++#define CMIC_MIIM_PARAM_C45_SEL 21 ++#define CMIC_MIIM_PARAM_C45_SEL_W 1 ++#define CMIC_MIIM_PARAM_PHY_ID_R 16 ++#define CMIC_MIIM_PARAM_PHY_ID_W 5 ++#define CMIC_MIIM_PARAM_PHY_DATA_R 0 ++#define CMIC_MIIM_PARAM_PHY_DATA_W 16 ++ ++#define CMIC_MIIM_READ_DATA_OFFSET 0x084 ++#define CMIC_MIIM_READ_DATA_DATA_R 0 ++#define CMIC_MIIM_READ_DATA_DATA_W 16 ++ ++#define CMIC_MIIM_ADDR_OFFSET 0x088 ++#define CMIC_MIIM_ADDR_C45_DTYPE_R 16 ++#define CMIC_MIIM_ADDR_C45_DTYPE_W 5 ++#define CMIC_MIIM_ADDR_C45_REGADR_R 0 ++#define CMIC_MIIM_ADDR_C45_REGADR_W 16 ++#define CMIC_MIIM_ADDR_C22_REGADR_R 0 ++#define CMIC_MIIM_ADDR_C22_REGADR_W 5 ++ ++#define CMIC_MIIM_CTRL_OFFSET 0x08c ++#define CMIC_MIIM_CTRL_RD_START 1 ++#define CMIC_MIIM_CTRL_RD_START_W 1 ++#define CMIC_MIIM_CTRL_WR_START 0 ++#define CMIC_MIIM_CTRL_WR_START_W 1 ++ ++#define CMIC_MIIM_STAT_OFFSET 0x090 ++#define CMIC_MIIM_STAT_OPN_DONE 0 ++#define CMIC_MIIM_STAT_OPN_DONE_W 1 ++ ++#define CMIC_COMMON_UC0_PIO_ENDIANESS 0x1F0 ++ ++#define MIIM_PARAM_REG CMIC_MIIM_PARAM_OFFSET ++#define MIIM_PARAM_MIIM_CYCLE_SHIFT CMIC_MIIM_PARAM_MIIM_CYCLE_R ++#define MIIM_PARAM_MIIM_CYCLE_MASK ((1 << CMIC_MIIM_PARAM_MIIM_CYCLE_W)-1) ++#define MIIM_PARAM_INTERNAL_SEL_SHIFT CMIC_MIIM_PARAM_INTERNAL_SEL ++#define MIIM_PARAM_INTERNAL_SEL_MASK ((1<base + reg); ++#if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) ++ if (readl(cmic_mdio->base + CMIC_COMMON_UC0_PIO_ENDIANESS) != 0) ++ /* CMICD is in big-endian mode */ ++ value = swab32(value); ++#endif ++ return value; ++} ++ ++static inline void cmicd_miim_reg_write(struct iproc_mdio_ctrl *cmic_mdio, ++ u32 reg, u32 data) ++{ ++ u32 value = data; ++#if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) ++ if (readl(cmic_mdio->base + CMIC_COMMON_UC0_PIO_ENDIANESS) != 0) ++ /* CMICD is in big-endian mode */ ++ value = swab32(data); ++#endif ++ writel(value, cmic_mdio->base + reg); ++} ++ ++static inline void cmicd_miim_set_op_read(u32 *data, u32 set) ++{ ++ SET_REG_FIELD(*data, MIIM_CTRL_RD_START_SHIFT, ++ MIIM_CTRL_RD_START_MASK, set); ++} ++ ++static inline void cmicd_miim_set_op_write(u32 *data, u32 set) ++{ ++ SET_REG_FIELD(*data, MIIM_CTRL_WR_START_SHIFT, ++ MIIM_CTRL_WR_START_MASK, set); ++} ++ ++static int do_cmicd_miim_op(struct iproc_mdio_ctrl *cmic_mdio, u32 op, ++ u32 param, u32 addr) ++{ ++ u32 val, op_done; ++ unsigned long flags; ++ int ret = 0; ++ int usec = MII_OP_MAX_HALT_USEC; ++ ++ if (op >= MII_OP_MODE_MAX) { ++ pr_err("%s : invalid op code %d\n", __func__, op); ++ return -EINVAL; ++ } ++ ++ spin_lock_irqsave(&cmic_mdio->lock, flags); ++ ++ cmicd_miim_reg_write(cmic_mdio, MIIM_PARAM_REG, param); ++ cmicd_miim_reg_write(cmic_mdio, MIIM_ADDRESS_REG, addr); ++ val = cmicd_miim_reg_read(cmic_mdio, MIIM_CTRL_REG); ++ if(op == MII_OP_MODE_READ) ++ cmicd_miim_set_op_read(&val, 1); ++ else ++ cmicd_miim_set_op_write(&val, 1); ++ cmicd_miim_reg_write(cmic_mdio, MIIM_CTRL_REG, val); ++ ++ do { ++ op_done = GET_REG_FIELD( ++ cmicd_miim_reg_read(cmic_mdio, MIIM_STAT_REG), ++ MIIM_STAT_OPN_DONE_SHIFT, ++ MIIM_STAT_OPN_DONE_MASK); ++ if (op_done) ++ break; ++ ++ udelay(1); ++ } while (usec-- > 0); ++ ++ if (op_done) { ++ if(op == MII_OP_MODE_READ) ++ ret = cmicd_miim_reg_read(cmic_mdio, MIIM_READ_DATA_REG); ++ } else { ++ ret = -ETIME; ++ } ++ ++ val = cmicd_miim_reg_read(cmic_mdio, MIIM_CTRL_REG); ++ if(op == MII_OP_MODE_READ) ++ cmicd_miim_set_op_read(&val, 0); ++ else ++ cmicd_miim_set_op_write(&val, 0); ++ cmicd_miim_reg_write(cmic_mdio, MIIM_CTRL_REG, val); ++ ++ spin_unlock_irqrestore(&cmic_mdio->lock, flags); ++ ++ return ret; ++} ++ ++ ++static int cmicd_miim_op(struct iproc_mdio_ctrl *cmic_mdio, ++ struct cmicd_miim_cmd *cmd) ++{ ++ u32 miim_param =0, miim_addr = 0; ++ ++ ISET_REG_FIELD(miim_param, MIIM_PARAM_BUS_ID_SHIFT, ++ MIIM_PARAM_BUS_ID_MASK, cmd->bus_id); ++ ++ if (cmd->int_sel) ++ ISET_REG_FIELD(miim_param, MIIM_PARAM_INTERNAL_SEL_SHIFT, ++ MIIM_PARAM_INTERNAL_SEL_MASK, 1); ++ ++ ISET_REG_FIELD(miim_param, MIIM_PARAM_PHY_ID_SHIFT, ++ MIIM_PARAM_PHY_ID_MASK, cmd->phy_id); ++ ++ if (cmd->op_mode == MII_OP_MODE_WRITE) ++ ISET_REG_FIELD(miim_param, MIIM_PARAM_PHY_DATA_SHIFT, ++ MIIM_PARAM_PHY_DATA_MASK, cmd->val); ++ ++ if (cmd->c45_sel) { ++ ISET_REG_FIELD(miim_param, MIIM_PARAM_C45_SEL_SHIFT, ++ MIIM_PARAM_C45_SEL_MASK, 1); ++ ISET_REG_FIELD(miim_addr, MIIM_ADDR_C45_REGADR_SHIFT, ++ MIIM_ADDR_C45_REGADR_MASK, cmd->regnum); ++ ISET_REG_FIELD(miim_addr, MIIM_ADDR_C45_DTYPE_SHIFT, ++ MIIM_ADDR_C45_REGADR_MASK, cmd->regnum >> 16); ++ } ++ else { ++ ISET_REG_FIELD(miim_addr, MIIM_ADDR_C22_REGADR_SHIFT, ++ MIIM_ADDR_C22_REGADR_MASK, cmd->regnum); ++ } ++ ++ return do_cmicd_miim_op(cmic_mdio, cmd->op_mode, miim_param, miim_addr); ++} ++ ++ ++static int cmicd_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum) ++{ ++ struct iproc_mdiobus_private *bus_priv = bus->priv; ++ struct iproc_mdiobus_data *bus_data = bus_priv->bus_data; ++ struct cmicd_miim_cmd cmd = {0}; ++ ++ cmd.bus_id = bus_data->phybus_num; ++ if (IPROC_MDIOBUS_TYPE_INTERNAL == bus_data->phybus_type) ++ cmd.int_sel = 1; ++ cmd.phy_id = phy_id; ++ cmd.regnum = regnum; ++ ++ if (regnum & MII_ADDR_C45) ++ cmd.c45_sel = 1; ++ ++ cmd.op_mode = MII_OP_MODE_READ; ++ ++ return cmicd_miim_op(bus_priv->hw_ctrl, &cmd); ++} ++ ++static int cmicd_mdiobus_write(struct mii_bus *bus, int phy_id, ++ int regnum, u16 val) ++{ ++ struct iproc_mdiobus_private *bus_priv = bus->priv; ++ struct iproc_mdiobus_data *bus_data = bus_priv->bus_data; ++ struct cmicd_miim_cmd cmd = {0}; ++ ++ cmd.bus_id = bus_data->phybus_num; ++ if (IPROC_MDIOBUS_TYPE_INTERNAL == bus_data->phybus_type) ++ cmd.int_sel = 1; ++ cmd.phy_id = phy_id; ++ cmd.regnum = regnum; ++ cmd.val = val; ++ ++ if (regnum & MII_ADDR_C45) ++ cmd.c45_sel = 1; ++ ++ cmd.op_mode = MII_OP_MODE_WRITE; ++ ++ return cmicd_miim_op(bus_priv->hw_ctrl, &cmd); ++} ++ ++static struct iproc_mdio_ctrl * cmicd_mdio_res_alloc(void) ++{ ++ if (!cmic_common) { ++ cmic_common = kzalloc(sizeof(*cmic_common), GFP_KERNEL); ++ if (!cmic_common) ++ return NULL; ++ spin_lock_init(&cmic_common->lock); ++ cmic_common->ref_cnt = 1; ++ } ++ else ++ cmic_common->ref_cnt++; ++ ++ return cmic_common; ++} ++ ++static void cmicd_mdio_res_free(struct iproc_mdio_ctrl *ctrl) ++{ ++ if (ctrl) { ++ ctrl->ref_cnt--; ++ if (ctrl->ref_cnt == 0) { ++ iounmap(ctrl->base); ++ kfree(ctrl); ++ cmic_common = NULL; ++ } ++ } ++} ++ ++static int cmicd_mdiobus_probe(struct platform_device *pdev) ++{ ++ struct mii_bus *mii_bus; ++ struct device_node *dn = pdev->dev.of_node; ++ struct iproc_mdiobus_private *bus_priv; ++ struct iproc_mdiobus_data *bus_data; ++ struct iproc_mdio_ctrl *cmicd_ctrl; ++ u32 mdio_bus_id; ++ const char *mdio_bus_type; ++ int ret; ++ ++ cmicd_ctrl = cmicd_mdio_res_alloc(); ++ if (!cmicd_ctrl) { ++ dev_err(&pdev->dev, "cmicd mdio resource alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_exit; ++ } ++ ++ /* Get register base address for the first mdio node only */ ++ if (!cmicd_ctrl->base) ++ cmicd_ctrl->base = of_iomap(dn, 0); ++ if (!cmicd_ctrl->base) { ++ dev_err(&pdev->dev, "cmicd mdio register base map error\n"); ++ ret = -ENXIO; ++ goto err_ctrl_free; ++ } ++ ++ /* If no property available, use default: 2 */ ++ if (of_property_read_u32(dn, "#bus-id", &mdio_bus_id)) ++ mdio_bus_id = 2; ++ ++ /* If no property available, use default: "external" */ ++ if (of_property_read_string(dn, "bus-type", &mdio_bus_type)) ++ mdio_bus_type = "external"; ++ ++ bus_data = devm_kzalloc(&pdev->dev, sizeof(*bus_data), GFP_KERNEL); ++ if (!bus_data) { ++ dev_err(&pdev->dev, "iProc MDIO bus data alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_bus_data_free; ++ } ++ ++ bus_priv = devm_kzalloc(&pdev->dev, sizeof(*bus_priv), GFP_KERNEL); ++ if (!bus_priv) { ++ dev_err(&pdev->dev, "iProc MDIO private data alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_bus_priv_free; ++ } ++ ++ bus_data->phybus_num = mdio_bus_id; ++ if (!strcmp(mdio_bus_type, "internal")) ++ bus_data->phybus_type = IPROC_MDIOBUS_TYPE_INTERNAL; ++ else ++ bus_data->phybus_type = IPROC_MDIOBUS_TYPE_EXTERNAL; ++ ++ bus_priv->bus_data = bus_data; ++ bus_priv->hw_ctrl = cmicd_ctrl; ++ ++ mii_bus = mdiobus_alloc(); ++ if (!mii_bus) { ++ dev_err(&pdev->dev, "mdiobus_alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_ctrl_free; ++ } ++ ++ mii_bus->name = "iproc_cmicd_mdiobus"; ++ snprintf(mii_bus->id, MII_BUS_ID_SIZE, "%s-%d-%d", "cmicd mdio", ++ mdio_bus_id, bus_data->phybus_type? 1:0); ++ mii_bus->parent = &pdev->dev; ++ mii_bus->read = cmicd_mdiobus_read; ++ mii_bus->write = cmicd_mdiobus_write; ++ mii_bus->priv = bus_priv; ++ ++ ret = of_mdiobus_register(mii_bus, dn); ++ if (ret) { ++ dev_err(&pdev->dev, "mdiobus register failed\n"); ++ goto err_bus_free; ++ } ++ ++ platform_set_drvdata(pdev, mii_bus); ++ ++ return 0; ++ ++err_bus_free: ++ mdiobus_free(mii_bus); ++err_bus_priv_free: ++ kfree(bus_priv); ++err_bus_data_free: ++ kfree(bus_data); ++err_ctrl_free: ++ cmicd_mdio_res_free(cmicd_ctrl); ++err_exit: ++ return ret; ++} ++ ++static int cmicd_mdiobus_remove(struct platform_device *pdev) ++{ ++ struct mii_bus *mii_bus = platform_get_drvdata(pdev); ++ struct iproc_mdiobus_private *bus_priv; ++ ++ if (mii_bus) { ++ bus_priv = mii_bus->priv; ++ ++ mdiobus_unregister(mii_bus); ++ if (bus_priv) ++ cmicd_mdio_res_free(bus_priv->hw_ctrl); ++ mdiobus_free(mii_bus); ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id cmicd_mdio_dt_ids[] = { ++ { .compatible = "brcm,iproc-cmicd-mdio"}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, cmicd_mdio_dt_ids); ++ ++static struct platform_driver iproc_cmicd_mdiobus_driver = ++{ ++ .driver = { ++ .name = "iproc_cmicd_mdio", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(cmicd_mdio_dt_ids), ++ }, ++ .probe = cmicd_mdiobus_probe, ++ .remove = cmicd_mdiobus_remove, ++}; ++ ++static int __init cmicd_mdio_init(void) ++{ ++ return platform_driver_register(&iproc_cmicd_mdiobus_driver); ++} ++ ++static void __exit cmicd_mdio_exit(void) ++{ ++ platform_driver_unregister(&iproc_cmicd_mdiobus_driver); ++} ++ ++//module_init(cmicd_mdio_init); ++subsys_initcall(cmicd_mdio_init); ++module_exit(cmicd_mdio_exit); ++ ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_DESCRIPTION("iProc CMICd mdio driver"); ++MODULE_LICENSE("GPL"); ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/mdio-xgs-iproc-cmicx.c b/drivers/net/phy/mdio-xgs-iproc-cmicx.c +--- a/drivers/net/phy/mdio-xgs-iproc-cmicx.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/phy/mdio-xgs-iproc-cmicx.c 2018-05-30 15:50:51.032753168 +0800 +@@ -0,0 +1,543 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mdio-xgs-iproc.h" ++ ++#define MIIM_CH0_CONTROL_REG 0x000 ++#define MIIM_CH1_CONTROL_REG 0x010 ++#define MIIM_CH2_CONTROL_REG 0x020 ++#define MIIM_CH3_CONTROL_REG 0x030 ++#define MIIM_CONTROL__START_SHIFT 0 ++#define MIIM_CONTROL__START_WIDTH 1 ++#define MIIM_CONTROL__START_MASK ((1 << MIIM_CONTROL__START_WIDTH) - 1) ++#define MIIM_CH0_PARAMS_REG 0x004 ++#define MIIM_CH1_PARAMS_REG 0x014 ++#define MIIM_CH2_PARAMS_REG 0x024 ++#define MIIM_CH3_PARAMS_REG 0x034 ++#define MIIM_PARAMS__RING_MAP_SHIFT 20 ++#define MIIM_PARAMS__RING_MAP_WIDTH 12 ++#define MIIM_PARAMS__RING_MAP_MASK ((1 << MIIM_PARAMS__RING_MAP_WIDTH) - 1) ++#define MIIM_PARAMS__MDIO_OP_TYPE_SHIFT 17 ++#define MIIM_PARAMS__MDIO_OP_TYPE_WIDTH 3 ++#define MIIM_PARAMS__MDIO_OP_TYPE_MASK ((1 << MIIM_PARAMS__MDIO_OP_TYPE_WIDTH) - 1) ++#define CLAUSE_22_WRITE_OP_MODE 0x0 ++#define CLAUSE_22_READ_OP_MODE 0x1 ++#define CLAUSE_45_WRITE_OP_MODE 0x5 ++#define CLAUSE_45_READ_OP_MODE 0x6 ++#define MIIM_PARAMS__SEL_INT_PHY_SHIFT 16 ++#define MIIM_PARAMS__SEL_INT_PHY_WIDTH 1 ++#define MIIM_PARAMS__SEL_INT_PHY_MASK ((1 << MIIM_PARAMS__SEL_INT_PHY_WIDTH) - 1) ++#define MIIM_PARAMS__PHY_WR_DATA_SHIFT 0 ++#define MIIM_PARAMS__PHY_WR_DATA_WIDTH 16 ++#define MIIM_PARAMS__PHY_WR_DATA_MASK ((1 << MIIM_PARAMS__PHY_WR_DATA_WIDTH) - 1) ++#define MIIM_CH0_ADDRESS_REG 0x008 ++#define MIIM_CH1_ADDRESS_REG 0x018 ++#define MIIM_CH2_ADDRESS_REG 0x028 ++#define MIIM_CH3_ADDRESS_REG 0x038 ++#define MIIM_ADDRESS__C45_REGADDR_SHIFT 16 ++#define MIIM_ADDRESS__C45_REGADDR_WIDTH 16 ++#define MIIM_ADDRESS__C45_REGADDR_MASK ((1 << MIIM_ADDRESS__C45_REGADDR_WIDTH) - 1) ++#define MIIM_ADDRESS__C22_REGADDR_C45_DTYPE_SHIFT 11 ++#define MIIM_ADDRESS__C22_REGADDR_C45_DTYPE_WIDTH 5 ++#define MIIM_ADDRESS__C22_REGADDR_C45_DTYPE_MASK ((1 << MIIM_ADDRESS__C22_REGADDR_C45_DTYPE_WIDTH) - 1) ++#define MIIM_ADDRESS__PHY_ID_SHIFT 6 ++#define MIIM_ADDRESS__PHY_ID_WIDTH 5 ++#define MIIM_ADDRESS__PHY_ID_MASK ((1 << MIIM_ADDRESS__PHY_ID_WIDTH) - 1) ++#define MIIM_CH0_STATUS_REG 0x00c ++#define MIIM_CH1_STATUS_REG 0x01c ++#define MIIM_CH2_STATUS_REG 0x02c ++#define MIIM_CH3_STATUS_REG 0x03c ++#define MIIM_STATUS__DONE_SHIFT 18 ++#define MIIM_STATUS__DONE_WIDTH 1 ++#define MIIM_STATUS__DONE_MASK ((1 << MIIM_STATUS__DONE_WIDTH) - 1) ++#define MIIM_STATUS__ERROR_SHIFT 17 ++#define MIIM_STATUS__ERROR_WIDTH 1 ++#define MIIM_STATUS__ERROR_MASK ((1 << MIIM_STATUS__ERROR_WIDTH) - 1) ++#define MIIM_STATUS__ACTIVE_SHIFT 16 ++#define MIIM_STATUS__ACTIVE_WIDTH 1 ++#define MIIM_STATUS__ACTIVE_MASK ((1 << MIIM_STATUS__ACTIVE_WIDTH) - 1) ++#define MIIM_STATUS__PHY_RD_DATA_SHIFT 0 ++#define MIIM_STATUS__PHY_RD_DATA_WIDTH 16 ++#define MIIM_STATUS__PHY_RD_DATA_MASK ((1 << MIIM_STATUS__PHY_RD_DATA_WIDTH) - 1) ++#define MIIM_RING0_CONTROL_REG 0x0f0 ++#define MIIM_RING1_CONTROL_REG 0x0f4 ++#define MIIM_RING2_CONTROL_REG 0x0f8 ++#define MIIM_RING3_CONTROL_REG 0x0fc ++#define MIIM_RING4_CONTROL_REG 0x100 ++#define MIIM_RING5_CONTROL_REG 0x104 ++#define MIIM_RING6_CONTROL_REG 0x108 ++#define MIIM_RING7_CONTROL_REG 0x10c ++#define MIIM_RING8_CONTROL_REG 0x110 ++#define MIIM_RING9_CONTROL_REG 0x114 ++#define MIIM_RING10_CONTROL_REG 0x118 ++#define MIIM_RING11_CONTROL_REG 0x11c ++#define MIIM_RING_CTRL__MDC_MODE_SHIFT 26 ++#define MIIM_RING_CTRL__MDC_MODE_WIDTH 1 ++#define MIIM_RING_CTRL__MDC_MODE_MASK ((1 << MIIM_RING_CTRL__MDC_MODE_WIDTH) - 1) ++#define MIIM_RING_CTRL__PREAMBLE_SHIFT 24 ++#define MIIM_RING_CTRL__PREAMBLE_WIDTH 2 ++#define MIIM_RING_CTRL__PREAMBLE_MASK ((1 << MIIM_RING_CTRL__PREAMBLE_WIDTH) - 1) ++#define MIIM_RING_CTRL__MDIO_OUT_DELAY_SHIFT 16 ++#define MIIM_RING_CTRL__MDIO_OUT_DELAY_WIDTH 8 ++#define MIIM_RING_CTRL__MDIO_OUT_DELAY_MASK ((1 << MIIM_RING_CTRL__MDIO_OUT_DELAY_WIDTH) - 1) ++#define MIIM_RING_CTRL__CLOCK_DIVIDER_EXT_SHIFT 8 ++#define MIIM_RING_CTRL__CLOCK_DIVIDER_EXT_WIDTH 8 ++#define MIIM_RING_CTRL__CLOCK_DIVIDER_EXT_MASK ((1 << MIIM_RING_CTRL__CLOCK_DIVIDER_EXT_WIDTH) - 1) ++#define MIIM_RING_CTRL__CLOCK_DIVIDER_INT_SHIFT 0 ++#define MIIM_RING_CTRL__CLOCK_DIVIDER_INT_WIDTH 8 ++#define MIIM_RING_CTRL__CLOCK_DIVIDER_INT_MASK ((1 << MIIM_RING_CTRL__CLOCK_DIVIDER_INT_WIDTH) - 1) ++#define MIIM_COMMON_CONTROL_REG 0x140 ++#define MIIM_COMM_CTRL__EXT_MDIO_MSTR_CNTRL_SHIFT 0 ++#define MIIM_COMM_CTRL__EXT_MDIO_MSTR_CNTRL_WIDTH 1 ++#define MIIM_COMM_CTRL__EXT_MDIO_MSTR_CNTRL_MASK ((1 << MIIM_COMM_CTRL__EXT_MDIO_MSTR_CNTRL_WIDTH) - 1) ++ ++#define MIIM_MAX_RINGS 12 ++ ++struct cmicx_miim_cmd { ++ u32 bus_id; ++ u32 int_sel; ++ u32 phy_id; ++ u32 reg_num; ++ u32 c45_sel; ++ u16 op_mode; ++ u16 phy_data; ++}; ++ ++static inline u32 cmicx_miim_read(struct iproc_mdio_ctrl *mdio_ctrl, u32 reg) ++{ ++ return readl(mdio_ctrl->base + reg); ++} ++ ++static inline void cmicx_miim_write(struct iproc_mdio_ctrl *mdio_ctrl, ++ u32 reg, u32 data) ++{ ++ writel(data, mdio_ctrl->base + reg); ++} ++ ++static int cmicx_miim_init(struct iproc_mdio_ctrl *mdio_ctrl) ++{ ++ u32 val; ++ u32 mstr_ctrl; ++ ++ /* Give MDIO control to IPROC */ ++ val = cmicx_miim_read(mdio_ctrl, MIIM_COMMON_CONTROL_REG); ++ mstr_ctrl = GET_REG_FIELD(val, MIIM_COMM_CTRL__EXT_MDIO_MSTR_CNTRL_SHIFT, ++ MIIM_COMM_CTRL__EXT_MDIO_MSTR_CNTRL_MASK); ++ if (!mstr_ctrl) { ++ ISET_REG_FIELD(val, MIIM_COMM_CTRL__EXT_MDIO_MSTR_CNTRL_SHIFT, ++ MIIM_COMM_CTRL__EXT_MDIO_MSTR_CNTRL_MASK, 1); ++ cmicx_miim_write(mdio_ctrl, MIIM_COMMON_CONTROL_REG, val); ++ } ++ return 0; ++} ++ ++static int cmicx_miim_ring_init(struct iproc_mdio_ctrl *mdio_ctrl, u32 ring_idx, ++ int int_divider, int ext_divider, int out_delay) ++{ ++ u32 ring_ctrl_reg[] = { MIIM_RING0_CONTROL_REG, ++ MIIM_RING1_CONTROL_REG, ++ MIIM_RING2_CONTROL_REG, ++ MIIM_RING3_CONTROL_REG, ++ MIIM_RING4_CONTROL_REG, ++ MIIM_RING5_CONTROL_REG, ++ MIIM_RING6_CONTROL_REG, ++ MIIM_RING7_CONTROL_REG, ++ MIIM_RING8_CONTROL_REG, ++ MIIM_RING9_CONTROL_REG, ++ MIIM_RING10_CONTROL_REG, ++ MIIM_RING11_CONTROL_REG }; ++ u32 val; ++ ++ if (ring_idx >= MIIM_MAX_RINGS) { ++ return -EINVAL; ++ } ++ ++ val = cmicx_miim_read(mdio_ctrl, ring_ctrl_reg[ring_idx]); ++ if (int_divider != -1) { ++ ISET_REG_FIELD(val, MIIM_RING_CTRL__CLOCK_DIVIDER_INT_SHIFT, ++ MIIM_RING_CTRL__CLOCK_DIVIDER_INT_MASK, int_divider); ++ } ++ if (ext_divider != -1) { ++ ISET_REG_FIELD(val, MIIM_RING_CTRL__CLOCK_DIVIDER_EXT_SHIFT, ++ MIIM_RING_CTRL__CLOCK_DIVIDER_EXT_MASK, ext_divider); ++ } ++ if (out_delay != -1) { ++ ISET_REG_FIELD(val, MIIM_RING_CTRL__MDIO_OUT_DELAY_SHIFT, ++ MIIM_RING_CTRL__MDIO_OUT_DELAY_MASK, out_delay); ++ } ++ cmicx_miim_write(mdio_ctrl, ring_ctrl_reg[ring_idx], val); ++ ++ return 0; ++} ++ ++static int cmicx_miim_operation(struct iproc_mdio_ctrl *mdio_ctrl, ++ struct cmicx_miim_cmd *miim_cmd) ++{ ++ unsigned long flags; ++ u32 is_done, is_error; ++ u32 optype = 0; ++ u32 val; ++ int usec = MII_OP_MAX_HALT_USEC; ++ int ret = 0,bus_id = miim_cmd->bus_id; ++ ++ spin_lock_irqsave(&mdio_ctrl->lock, flags); ++ ++ /* prepare transaction data */ ++ //val = cmicx_miim_read(mdio_ctrl, (MIIM_CH0_ADDRESS_REG + 0x10 * bus_id)); ++ val = 0; ++ ISET_REG_FIELD(val, MIIM_ADDRESS__PHY_ID_SHIFT, ++ MIIM_ADDRESS__PHY_ID_MASK, miim_cmd->phy_id); ++ if (miim_cmd->c45_sel) { ++ ISET_REG_FIELD(val, MIIM_ADDRESS__C45_REGADDR_SHIFT, ++ MIIM_ADDRESS__C45_REGADDR_MASK, miim_cmd->reg_num); ++ ISET_REG_FIELD(val, MIIM_ADDRESS__C22_REGADDR_C45_DTYPE_SHIFT, ++ MIIM_ADDRESS__C22_REGADDR_C45_DTYPE_MASK, (miim_cmd->reg_num >> 16)); ++ } else { ++ ISET_REG_FIELD(val, MIIM_ADDRESS__C22_REGADDR_C45_DTYPE_SHIFT, ++ MIIM_ADDRESS__C22_REGADDR_C45_DTYPE_MASK, miim_cmd->reg_num); ++ } ++ //cmicx_miim_write(mdio_ctrl, MIIM_CH1_ADDRESS_REG, val); ++ cmicx_miim_write(mdio_ctrl, (MIIM_CH0_ADDRESS_REG + 0x10 * bus_id), val); ++ ++ /* _SOC_IF_ERR_EXIT(READ_MIIM_CH0_PARAMSr(unit, ®_val)); */ ++ //val = cmicx_miim_read(mdio_ctrl, (MIIM_CH0_PARAMS_REG + 0x10 * bus_id)); ++ val = 0; ++ ISET_REG_FIELD(val, MIIM_PARAMS__PHY_WR_DATA_SHIFT, ++ MIIM_PARAMS__PHY_WR_DATA_MASK, miim_cmd->phy_data); ++ ISET_REG_FIELD(val, MIIM_PARAMS__SEL_INT_PHY_SHIFT, ++ MIIM_PARAMS__SEL_INT_PHY_MASK, miim_cmd->int_sel); ++ ISET_REG_FIELD(val, MIIM_PARAMS__RING_MAP_SHIFT, ++ MIIM_PARAMS__RING_MAP_MASK, (1 << miim_cmd->bus_id)); ++ if (miim_cmd->c45_sel) { ++ optype = CLAUSE_45_READ_OP_MODE; ++ if (miim_cmd->op_mode == MII_OP_MODE_WRITE) { ++ optype = CLAUSE_45_WRITE_OP_MODE; ++ } ++ } else { ++ optype = CLAUSE_22_READ_OP_MODE; ++ if (miim_cmd->op_mode == MII_OP_MODE_WRITE) { ++ optype = CLAUSE_22_WRITE_OP_MODE; ++ } ++ } ++ ISET_REG_FIELD(val, MIIM_PARAMS__MDIO_OP_TYPE_SHIFT, ++ MIIM_PARAMS__MDIO_OP_TYPE_MASK, optype); ++ //cmicx_miim_write(mdio_ctrl, MIIM_CH1_PARAMS_REG, val); ++ cmicx_miim_write(mdio_ctrl, (MIIM_CH0_PARAMS_REG + 0x10 * bus_id), val); ++ ++ /* start transaction */ ++ val = 0; ++ ISET_REG_FIELD(val, MIIM_CONTROL__START_SHIFT, ++ MIIM_CONTROL__START_MASK, 0x1); ++ //cmicx_miim_write(mdio_ctrl, MIIM_CH1_CONTROL_REG, val); ++ cmicx_miim_write(mdio_ctrl, (MIIM_CH0_CONTROL_REG + 0x10 * bus_id), val); ++ ++ /* poll for DONE bit */ ++ do { ++ //val = cmicx_miim_read(mdio_ctrl, MIIM_CH1_STATUS_REG); ++ val = cmicx_miim_read(mdio_ctrl, (MIIM_CH0_STATUS_REG + 0x10 * bus_id)); ++ is_done = GET_REG_FIELD(val, MIIM_STATUS__DONE_SHIFT, MIIM_STATUS__DONE_MASK); ++ if (is_done) { ++ break; /* MIIM operation is done */ ++ } ++ ++ udelay(1); ++ } while (usec-- > 0); ++ ++ /* check for transaction error */ ++ //val = cmicx_miim_read(mdio_ctrl, MIIM_CH1_STATUS_REG); ++ val = cmicx_miim_read(mdio_ctrl, (MIIM_CH0_STATUS_REG + 0x10 * bus_id)); ++ is_error = GET_REG_FIELD(val, MIIM_STATUS__ERROR_SHIFT, MIIM_STATUS__ERROR_MASK); ++ if (is_error) { ++ printk(KERN_ERR "%s : mdio execution error.\n", __func__); ++ ret = -EIO; ++ goto exit; ++ } ++ ++ /* in case of read - get data */ ++ if (miim_cmd->op_mode == MII_OP_MODE_READ) { ++ miim_cmd->phy_data = GET_REG_FIELD(val, MIIM_STATUS__PHY_RD_DATA_SHIFT, ++ MIIM_STATUS__PHY_RD_DATA_MASK); ++ } ++ ++exit: ++ /* cleanup */ ++ //cmicx_miim_write(mdio_ctrl, MIIM_CH1_CONTROL_REG, 0); ++ cmicx_miim_write(mdio_ctrl, (MIIM_CH0_CONTROL_REG + 0x10 * bus_id), 0); ++ spin_unlock_irqrestore(&mdio_ctrl->lock, flags); ++ ++ return ret; ++} ++ ++static int cmicx_mdiobus_read(struct mii_bus *bus, int phy_id, int reg_num) ++{ ++ struct iproc_mdiobus_private *mdio_bus_priv = bus->priv; ++ struct iproc_mdiobus_data *mdio_bus_data = mdio_bus_priv->bus_data; ++ struct cmicx_miim_cmd miim_cmd = { 0 }; ++ int ret = 0; ++ ++ if (IPROC_MDIOBUS_TYPE_INTERNAL == mdio_bus_data->phybus_type) { ++ miim_cmd.int_sel = 1; ++ } ++ if (reg_num & MII_ADDR_C45) { ++ miim_cmd.c45_sel = 1; ++ } ++ miim_cmd.bus_id = mdio_bus_data->phybus_num; ++ miim_cmd.phy_id = phy_id; ++ miim_cmd.reg_num = reg_num; ++ miim_cmd.op_mode = MII_OP_MODE_READ; ++ miim_cmd.phy_data = 0; ++ ++ ret = cmicx_miim_operation(mdio_bus_priv->hw_ctrl, &miim_cmd); ++ if (ret == 0) { ++ return miim_cmd.phy_data; ++ } ++ return ret; ++} ++ ++static int cmicx_mdiobus_write(struct mii_bus *bus, int phy_id, ++ int reg_num, u16 val) ++{ ++ struct iproc_mdiobus_private *mdio_bus_priv = bus->priv; ++ struct iproc_mdiobus_data *mdio_bus_data = mdio_bus_priv->bus_data; ++ struct cmicx_miim_cmd miim_cmd = {0}; ++ ++ if (IPROC_MDIOBUS_TYPE_INTERNAL == mdio_bus_data->phybus_type) { ++ miim_cmd.int_sel = 1; ++ } ++ if (reg_num & MII_ADDR_C45) { ++ miim_cmd.c45_sel = 1; ++ } ++ miim_cmd.bus_id = mdio_bus_data->phybus_num; ++ miim_cmd.phy_id = phy_id; ++ miim_cmd.reg_num = reg_num; ++ miim_cmd.op_mode = MII_OP_MODE_WRITE; ++ miim_cmd.phy_data = val; ++ ++ return cmicx_miim_operation(mdio_bus_priv->hw_ctrl, &miim_cmd); ++} ++ ++/************************************************************************************* ++**************************************************************************************/ ++static int cmicx_mdiobus_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *dn = pdev->dev.of_node; ++ struct mii_bus *mii_bus = NULL; ++ struct iproc_mdiobus_private *mdio_bus_priv = NULL; ++ struct iproc_mdiobus_data *mdio_bus_data = NULL; ++ struct iproc_mdio_ctrl *mdio_ctrl = NULL; ++ u32 mdio_bus_id; ++ int clock_divider, out_delay; ++ int divider_int = -1, divider_ext = -1; ++ const char *mdio_bus_type; ++ int ret; ++ ++ mdio_ctrl = devm_kzalloc(dev, sizeof(*mdio_ctrl), GFP_KERNEL); ++ if (!mdio_ctrl) { ++ dev_err(dev, "cmicx mdio resource allocated failed\n"); ++ return -ENOMEM; ++ } ++ ++ spin_lock_init(&mdio_ctrl->lock); ++ ++ /* Get register base address */ ++ mdio_ctrl->base = of_iomap(dn, 0); ++ if (!mdio_ctrl->base) { ++ dev_err(dev, "cmicx mdio register base map error\n"); ++ ret = -ENXIO; ++ goto err; ++ } ++ ++ /* If no property available, use default: 2 */ ++ if (of_property_read_u32(dn, "#bus-id", &mdio_bus_id)) { ++ mdio_bus_id = 2; ++ } ++ ++ /* If no property available, use default: "external" */ ++ if (of_property_read_string(dn, "bus-type", &mdio_bus_type)) { ++ mdio_bus_type = "external"; ++ } ++ ++ /* If no property available, use default: -1 */ ++ if (of_property_read_u32(dn, "#divider", &clock_divider)) { ++ clock_divider = -1; ++ } ++ ++ /* If no property available, use default: -1 */ ++ if (of_property_read_u32(dn, "#delay", &out_delay)) { ++ out_delay = -1; ++ } ++ ++ mdio_bus_data = devm_kzalloc(dev, sizeof(*mdio_bus_data), GFP_KERNEL); ++ if (!mdio_bus_data) { ++ dev_err(dev, "iProc MDIO bus data allocated failed\n"); ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ mdio_bus_data->phybus_num = mdio_bus_id; ++ if (!strcmp(mdio_bus_type, "internal")) { ++ mdio_bus_data->phybus_type = IPROC_MDIOBUS_TYPE_INTERNAL; ++ divider_int = clock_divider; ++ } else { ++ mdio_bus_data->phybus_type = IPROC_MDIOBUS_TYPE_EXTERNAL; ++ divider_ext = clock_divider; ++ } ++ ++ mdio_bus_priv = devm_kzalloc(dev, sizeof(*mdio_bus_priv), GFP_KERNEL); ++ if (!mdio_bus_priv) { ++ dev_err(dev, "iProc MDIO private data allocated failed\n"); ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ mdio_bus_priv->bus_data = mdio_bus_data; ++ mdio_bus_priv->hw_ctrl = mdio_ctrl; ++ ++ ret = cmicx_miim_init(mdio_ctrl); ++ if (ret) { ++ dev_err(dev, "cmicx init failed\n"); ++ goto err; ++ } ++ ++ ret = cmicx_miim_ring_init(mdio_ctrl, mdio_bus_id, ++ divider_int, divider_ext, out_delay); ++ if (ret) { ++ dev_err(dev, "cmicx init ring failed\n"); ++ goto err; ++ } ++ ++ mii_bus = mdiobus_alloc(); ++ if (!mii_bus) { ++ dev_err(dev, "MII bus memory allocated failed\n"); ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ mii_bus->name = "iproc_cmicx_mdiobus"; ++ snprintf(mii_bus->id, MII_BUS_ID_SIZE, "%s-%d-%d", "cmicx mdio", mdio_bus_id, ++ (mdio_bus_data->phybus_type == IPROC_MDIOBUS_TYPE_EXTERNAL) ? 1 : 0); ++ mii_bus->parent = dev; ++ mii_bus->read = cmicx_mdiobus_read; ++ mii_bus->write = cmicx_mdiobus_write; ++ mii_bus->priv = mdio_bus_priv; ++ ++ ret = of_mdiobus_register(mii_bus, dn); ++ if (ret) { ++ dev_err(dev, "mdiobus register failed\n"); ++ goto err; ++ } ++ ++ platform_set_drvdata(pdev, mii_bus); ++ ++ return 0; ++ ++err: ++ if (mii_bus) { ++ mdiobus_free(mii_bus); ++ } ++ if (mdio_bus_priv) { ++ devm_kfree(dev, mdio_bus_priv); ++ } ++ if (mdio_bus_data) { ++ devm_kfree(dev, mdio_bus_data); ++ } ++ if (mdio_ctrl->base) { ++ iounmap(mdio_ctrl->base); ++ } ++ if (mdio_ctrl) { ++ devm_kfree(dev, mdio_ctrl); ++ } ++ ++ return ret; ++} ++ ++static int cmicx_mdiobus_remove(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct mii_bus *mii_bus = platform_get_drvdata(pdev); ++ struct iproc_mdiobus_private *mdio_bus_priv; ++ struct iproc_mdiobus_data *mdio_bus_data; ++ struct iproc_mdio_ctrl *mdio_ctrl; ++ ++ if (mii_bus) { ++ mdio_bus_priv = mii_bus->priv; ++ mdio_bus_data = mdio_bus_priv->bus_data; ++ mdio_ctrl = mdio_bus_priv->hw_ctrl; ++ ++ mdiobus_unregister(mii_bus); ++ mdiobus_free(mii_bus); ++ ++ if (mdio_bus_priv) { ++ if (mdio_ctrl) { ++ if (mdio_ctrl->base) { ++ iounmap(mdio_ctrl->base); ++ } ++ devm_kfree(dev, mdio_ctrl); ++ } ++ if (mdio_bus_data) { ++ devm_kfree(dev, mdio_bus_data); ++ } ++ devm_kfree(dev, mdio_bus_priv); ++ } ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id cmicx_mdio_dt_ids[] = { ++ { .compatible = "brcm,iproc-cmicx-mdio"}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, cmicx_mdio_dt_ids); ++ ++static struct platform_driver iproc_cmicx_mdiobus_driver = ++{ ++ .driver = { ++ .name = "iproc_cmicx_mdio", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(cmicx_mdio_dt_ids), ++ }, ++ .probe = cmicx_mdiobus_probe, ++ .remove = cmicx_mdiobus_remove, ++}; ++ ++static int __init cmicx_mdio_init(void) ++{ ++ return platform_driver_register(&iproc_cmicx_mdiobus_driver); ++} ++ ++static void __exit cmicx_mdio_exit(void) ++{ ++ platform_driver_unregister(&iproc_cmicx_mdiobus_driver); ++} ++ ++subsys_initcall(cmicx_mdio_init); ++module_exit(cmicx_mdio_exit); ++ ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_DESCRIPTION("iProc CMICx mdio driver"); ++MODULE_LICENSE("GPL"); ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/mdio-xgs-iproc.h b/drivers/net/phy/mdio-xgs-iproc.h +--- a/drivers/net/phy/mdio-xgs-iproc.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/phy/mdio-xgs-iproc.h 2018-05-10 11:31:32.085402292 +0800 +@@ -0,0 +1,55 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++ ++ ++#ifndef _XGS_IPROC_MDIO_H_ ++#define _XGS_IPROC_MDIO_H_ ++ ++enum { ++ MII_OP_MODE_READ, ++ MII_OP_MODE_WRITE, ++ MII_OP_MODE_MAX ++}; ++ ++/* iProc General Interface for mdio bus support */ ++struct iproc_mdiobus_data { ++ /* required for cmicd mdio controller supports several buses */ ++ u32 phybus_num; ++ u32 phybus_type; ++}; ++ ++/* ++ * struct iproc_mdio_ctrl ++ * @base: base address of cmic_common ++ * @iproc_mdio_enable_reg: register addr of mdio bus enable ++ * @iproc_mdio_sel_bit: bit position in register for enabling mdio bus access ++ * @lock: spin lock protecting io access ++ */ ++struct iproc_mdio_ctrl { ++ void __iomem *base; ++ void __iomem *iproc_mdio_enable_reg; ++ u32 iproc_mdio_sel_bit; ++ spinlock_t lock; ++ int ref_cnt; ++}; ++ ++struct iproc_mdiobus_private { ++ struct iproc_mdiobus_data *bus_data; ++ struct iproc_mdio_ctrl *hw_ctrl; ++}; ++ ++#define SET_REG_FIELD(reg_value, fshift, fmask, fvalue) \ ++ (reg_value) = ((reg_value) & ~((fmask) << (fshift))) | \ ++ (((fvalue) & (fmask)) << (fshift)) ++#define ISET_REG_FIELD(reg_value, fshift, fmask, fvalue) \ ++ (reg_value) = (reg_value) | (((fvalue) & (fmask)) << (fshift)) ++#define GET_REG_FIELD(reg_value, fshift, fmask) \ ++ (((reg_value) & ((fmask) << (fshift))) >> (fshift)) ++ ++#define MII_OP_MAX_HALT_USEC 500 ++ ++#define IPROC_MDIOBUS_TYPE_INTERNAL 0 ++#define IPROC_MDIOBUS_TYPE_EXTERNAL 1 ++ ++#endif /* _XGS_IPROC_MDIO_H_ */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c +--- a/drivers/net/phy/phy.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/net/phy/phy.c 2018-05-10 11:31:32.085402292 +0800 +@@ -42,6 +42,11 @@ + case PHY_##_state: \ + return __stringify(_state); \ + ++#if IS_ENABLED(CONFIG_MDIO_XGS_IPROC) ++#define MAX_IPROC_PHY_ADDR 4 ++extern bool xgs_mdio_bus_release(void); ++#endif ++ + static const char *phy_state_to_str(enum phy_state st) + { + switch (st) { +@@ -889,6 +894,9 @@ void phy_state_machine(struct work_struc + enum phy_state old_state; + int err = 0; + int old_link; ++#if IS_ENABLED(CONFIG_MDIO_XGS_IPROC) ++ static u32 schedule_cnt[MAX_IPROC_PHY_ADDR]= {0}; ++#endif + + mutex_lock(&phydev->lock); + +@@ -1078,9 +1086,32 @@ void phy_state_machine(struct work_struc + * PHY, if PHY_IGNORE_INTERRUPT is set, then we will be moving + * between states from phy_mac_interrupt() + */ ++#if IS_ENABLED(CONFIG_MDIO_XGS_IPROC) ++ if (phydev->irq == PHY_POLL) { ++ /* Re-schedule PHY state machine change if mdio_bus_release=0 */ ++ if (!xgs_mdio_bus_release()) { ++ queue_delayed_work(system_power_efficient_wq, ++ &phydev->state_queue, PHY_STATE_TIME * HZ); ++ } ++ /* If mdio_bus_release=1, stop re-schedule of PHY state machine ++ * change after 5 * PHY_STATE_TIME seconds for HX4/KT2 ++ * which shares the mdio bus between iProc and CMICd. ++ */ ++ else { ++ schedule_cnt[phydev->mdio.addr] += 1; ++ if (schedule_cnt[phydev->mdio.addr] > 5) { ++ schedule_cnt[phydev->mdio.addr] = 0; ++ return; ++ } ++ queue_delayed_work(system_power_efficient_wq, ++ &phydev->state_queue, PHY_STATE_TIME * HZ); ++ } ++ } ++#else + if (phydev->irq == PHY_POLL) + queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, + PHY_STATE_TIME * HZ); ++#endif + } + + /** +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/xgs-iproc-serdes.c b/drivers/net/phy/xgs-iproc-serdes.c +--- a/drivers/net/phy/xgs-iproc-serdes.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/phy/xgs-iproc-serdes.c 2018-05-10 11:31:32.089402296 +0800 +@@ -0,0 +1,644 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "xgs_iproc_serdes_def.h" ++ ++/* the SERDES PHY ID for HX4/KT2/SB2/GH2/WH2 is the same */ ++#define PHY_ID_XGS_AMAC_SERDES 0x0143bff0 ++ ++#define SERDES_ID_HX4_AMAC 0x828f4e00 ++#define SERDES_ID_KT2_AMAC 0x42814fc0 ++/* The amac serdes id (id0,id1) of SB2/GH2/WH2 is the same */ ++#define SERDES_ID_SB2_AMAC 0x02cf1a00 ++#define SERDES_ID_GH2_AMAC 0x02cf1a00 /* apply to WH2 */ ++/* When ID is the same, use id2 for further identification */ ++#define SERDES_ID2_HX4_AMAC 0x000f ++#define SERDES_ID2_KT2_AMAC 0x03ff ++#define SERDES_ID2_SB2_AMAC 0x8007 ++#define SERDES_ID2_GH2_AMAC 0x800f /* apply to WH2 */ ++ ++#define PHY_REG_BLK_ADDR 0x001f ++#define PHY_REG_AER_BLK 0xffd0 ++#define PHY_REG_AER_OFFSET 0x001e ++#define PHY_REG_BLK_ADDR_MASK 0x7ff0 ++#define PHY_REG_ADDR_MASK 0xf ++#define PHY_REG_ADDR_32_MASK 0x8000 ++ ++#define PHY_AER_REG_ADDR_AER(_addr) (((_addr) >> XGXS16G_SERDES_LANE_SHIFT) \ ++ & 0xFFFF) ++#define PHY_REG_ADDR_BLK(_addr) ((_addr) & PHY_REG_BLK_ADDR_MASK) ++#define PHY_REG_ADDR_REGAD(_addr) (((_addr & PHY_REG_ADDR_32_MASK) >> 11) \ ++ | (_addr & PHY_REG_ADDR_MASK)) ++ ++//#define BCMDBG ++//#define BCMDBG_ERR ++#ifdef BCMDBG ++#define SERDES_ERROR(args) pr_err args ++#define SERDES_TRACE(args) pr_info args ++#elif defined(BCMDBG_ERR) ++#define SERDES_ERROR(args) pr_err args ++#define SERDES_TRACE(args) ++#else ++#define SERDES_ERROR(args) ++#define SERDES_TRACE(args) ++#endif /* BCMDBG */ ++ ++/* For pcie/usb serdes and phy write */ ++void xgs_phy_wr_reg(struct phy_device *phydev, u32 regnum, u16 data) ++{ ++ u16 phy_reg_blk=0; ++ u32 phy_reg_addr=0; ++ ++ phy_reg_blk = regnum & PHY_REG_BLK_ADDR_MASK; ++ phy_reg_addr = regnum & PHY_REG_ADDR_MASK; ++ phy_reg_addr |= (regnum & PHY_REG_ADDR_32_MASK) ? 0x10 : 0x0; ++ ++ phy_write(phydev, PHY_REG_BLK_ADDR, phy_reg_blk); ++ phy_write(phydev, phy_reg_addr, data); ++} ++ ++/* For pcie/usb serdes and phy read */ ++u16 xgs_phy_rd_reg(struct phy_device *phydev, u32 regnum) ++{ ++ u16 phy_reg_blk=0; ++ u32 phy_reg_addr=0; ++ int data; ++ ++ phy_reg_blk = regnum & PHY_REG_BLK_ADDR_MASK; ++ phy_reg_addr = regnum & PHY_REG_ADDR_MASK; ++ phy_reg_addr |= (regnum & PHY_REG_ADDR_32_MASK) ? 0x10 : 0x0; ++ ++ phy_write(phydev, PHY_REG_BLK_ADDR, phy_reg_blk); ++ data = phy_read(phydev, phy_reg_addr); ++ ++ return (u16)data; ++} ++ ++/* for SB2 USB PHY write */ ++void xgs_sb2_usb_phy_wr_reg(struct phy_device *phydev, u32 regnum, u16 data) ++{ ++ u16 phy_reg_blk=0; ++ u32 phy_reg_addr=0; ++ ++ phy_reg_blk = regnum & 0xfff0; ++ phy_reg_addr = regnum & 0xf; ++ ++ phy_write(phydev, PHY_REG_BLK_ADDR, phy_reg_blk); ++ phy_write(phydev, phy_reg_addr, data); ++} ++ ++/* for SB2 USB PHY read */ ++u16 xgs_sb2_usb_phy_rd_reg(struct phy_device *phydev, u32 regnum) ++{ ++ u16 phy_reg_blk=0; ++ u32 phy_reg_addr=0; ++ int data; ++ ++ phy_reg_blk = regnum & 0xfff0; ++ phy_reg_addr = regnum & 0xf; ++ ++ phy_write(phydev, PHY_REG_BLK_ADDR, phy_reg_blk); ++ data = phy_read(phydev, phy_reg_addr); ++ ++ return (u16)data; ++} ++ ++/* SB2/GH2/WH2 amac serdes supports AER */ ++static u16 xgs_serdes_rd_reg(struct phy_device *phydev, u32 regnum) ++{ ++ int data; ++ u16 phy_reg_blk=0; ++ u32 phy_reg_addr=0; ++ u32 phy_reg_aer=0; ++ ++ phy_reg_aer = PHY_AER_REG_ADDR_AER(regnum); ++ phy_reg_blk = PHY_REG_ADDR_BLK(regnum); ++ phy_reg_addr = PHY_REG_ADDR_REGAD(regnum); ++ ++ if (phy_reg_aer) { ++ phy_write(phydev, PHY_REG_BLK_ADDR, PHY_REG_AER_BLK); ++ phy_write(phydev, PHY_REG_AER_OFFSET, phy_reg_aer); ++ } ++ ++ phy_write(phydev, PHY_REG_BLK_ADDR, phy_reg_blk); ++ data = phy_read(phydev, phy_reg_addr); ++ ++ if (phy_reg_aer) { ++ phy_write(phydev, PHY_REG_BLK_ADDR, PHY_REG_AER_BLK); ++ phy_write(phydev, PHY_REG_AER_OFFSET, 0x0); ++ } ++ ++ return (u16)data; ++} ++ ++static void xgs_serdes_wr_reg(struct phy_device *phydev, u32 regnum, u16 data) ++{ ++ u16 phy_reg_blk=0; ++ u32 phy_reg_addr=0; ++ u32 phy_reg_aer=0; ++ ++ phy_reg_aer = PHY_AER_REG_ADDR_AER(regnum); ++ phy_reg_blk = PHY_REG_ADDR_BLK(regnum); ++ phy_reg_addr = PHY_REG_ADDR_REGAD(regnum); ++ ++ if (phy_reg_aer) { ++ phy_write(phydev, PHY_REG_BLK_ADDR, PHY_REG_AER_BLK); ++ phy_write(phydev, PHY_REG_AER_OFFSET, phy_reg_aer); ++ } ++ ++ phy_write(phydev, PHY_REG_BLK_ADDR, phy_reg_blk); ++ phy_write(phydev, phy_reg_addr, data); ++ ++ if (phy_reg_aer) { ++ phy_write(phydev, PHY_REG_BLK_ADDR, PHY_REG_AER_BLK); ++ phy_write(phydev, PHY_REG_AER_OFFSET, 0x0); ++ } ++} ++ ++static u32 serdes_get_id(struct phy_device *phy_dev) ++{ ++ u16 serdes_id0, serdes_id1; ++ u32 serdes_id; ++ struct phy_device *phydev = phy_dev; ++ ++ serdes_id0 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID0r); ++ serdes_id1 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID1r); ++ serdes_id = (serdes_id0 << 16) | serdes_id1; ++ ++ return serdes_id; ++} ++ ++void xgs_serdes_set_lane(struct phy_device *phy_dev, u32 lane) ++{ ++ xgs_serdes_info_t *serdes_info; ++ ++ serdes_info = devm_kzalloc(&phy_dev->mdio.dev, sizeof(*serdes_info), ++ GFP_KERNEL); ++ if (!serdes_info) { ++ dev_err(&phy_dev->mdio.dev, "Fail to allocate xgs_serdes_info\n"); ++ return; ++ } ++ ++ serdes_info->lane = lane; ++ phy_dev->priv = serdes_info; ++} ++ ++static inline u32 xgs_serdes_get_lane(struct phy_device *phy_dev) ++{ ++ xgs_serdes_info_t *lane_info = (xgs_serdes_info_t *) phy_dev->priv; ++ ++ return lane_info->lane; ++} ++ ++bool xgs_serdes_hx4_amac(struct phy_device *phy_dev) ++{ ++ return (serdes_get_id(phy_dev) == SERDES_ID_HX4_AMAC); ++} ++ ++bool xgs_serdes_kt2_amac(struct phy_device *phy_dev) ++{ ++ return (serdes_get_id(phy_dev) == SERDES_ID_KT2_AMAC); ++} ++ ++/* Needed for HX4/KT2/GH2/WH2, WH2 has the same ID as GH2 */ ++static void xgs_serdes_reset_core(struct phy_device *phy_dev) ++{ ++ u16 data16; ++ u32 serdes_id; ++ u16 serdes_id2; ++ static u32 serdes_core_reset = 0; ++ struct phy_device *phydev = phy_dev; ++ ++ if (phydev->phy_id != PHY_ID_XGS_AMAC_SERDES) ++ return; ++ ++ /* Only reset once */ ++ if (serdes_core_reset) ++ return; ++ ++ serdes_id = serdes_get_id(phydev); ++ serdes_id2 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID2r); ++ SERDES_TRACE(("-----SERDESID2: 0x%x\n", serdes_id2)); ++ ++ if (!((serdes_id == SERDES_ID_HX4_AMAC) || ++ (serdes_id == SERDES_ID_KT2_AMAC) || ++ (serdes_id == SERDES_ID_GH2_AMAC))) ++ return; ++ ++ /* GH2/WH2 specific code */ ++ if (serdes_id == SERDES_ID_GH2_AMAC) { ++ if (serdes_id2 != SERDES_ID2_GH2_AMAC) ++ return; ++ ++ /* Disable pll start sequencer */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr); ++ data16 &= ~XGXSBLK0_CONTROL_PLL_SEQUENCER_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr, data16); ++ serdes_core_reset = 1; ++ return; ++ } ++ ++ /* The following is HX4/KT2 related */ ++ /* unlock lane */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_WC40_DIGITAL4_MISC3r); ++ data16 &= ~(DIGITAL4_MISC3_LANEDISABLE_MASK); ++ xgs_serdes_wr_reg(phydev, XGXS16G_WC40_DIGITAL4_MISC3r, data16); ++ ++ /* Reset the core */ ++ /* Stop PLL Sequencer and configure the core into correct mode */ ++ data16 = (XGXSBLK0_XGXSCONTROL_MODE_10G_IndLane << ++ XGXSBLK0_XGXSCONTROL_MODE_10G_SHIFT) | ++ XGXSBLK0_XGXSCONTROL_HSTL_MASK | ++ XGXSBLK0_XGXSCONTROL_CDET_EN_MASK | ++ XGXSBLK0_XGXSCONTROL_EDEN_MASK | ++ XGXSBLK0_XGXSCONTROL_AFRST_EN_MASK | ++ XGXSBLK0_XGXSCONTROL_TXCKO_DIV_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr, data16); ++ ++ /* ++ * Disable IEEE block select auto-detect. ++ * The driver will select desired block as necessary. ++ * By default, the driver keeps the XAUI block in IEEE address space. ++ */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_XGXSBLK0_MISCCONTROL1r); ++ data16 &= ~(XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_MASK | ++ XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_MASK); ++ if (!XGXS16G_2p5G_ID(serdes_id2) && (serdes_id == SERDES_ID_HX4_AMAC)) ++ data16 |= XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_XGXSBLK0_MISCCONTROL1r, data16); ++ ++ /* disable in-band MDIO. PHY-443 */ ++ data16 = xgs_serdes_rd_reg(phydev, 0x8111); ++ /* rx_inBandMdio_rst */ ++ data16 |= 1 << 3; ++ xgs_serdes_wr_reg(phydev, 0x8111, data16); ++ ++ serdes_core_reset = 1; ++} ++ ++static void xgs_serdes_reset(struct phy_device *phy_dev) ++{ ++ u16 ctrl; ++ struct phy_device *phydev = phy_dev; ++ u32 serdes_id; ++ u16 serdes_id2; ++ u32 aer = 0; ++ u32 aer_blk_reg = 0; ++ ++ if (phydev->phy_id != PHY_ID_XGS_AMAC_SERDES) ++ return; ++ ++ serdes_id = serdes_get_id(phydev); ++ serdes_id2 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID2r); ++ ++ /* AER required for GH2/WH2 serdes */ ++ if ((serdes_id == SERDES_ID_GH2_AMAC) && ++ (serdes_id2 == SERDES_ID2_GH2_AMAC)) ++ aer = xgs_serdes_get_lane(phy_dev) << XGXS16G_SERDES_LANE_SHIFT; ++ ++ /* de-assert reset */ ++ aer_blk_reg = aer | XGXS16G_IEEE0BLK_IEEECONTROL0r; ++ ctrl = xgs_serdes_rd_reg(phydev, aer_blk_reg); ++ ctrl |= IEEE0BLK_IEEECONTROL0_RST_HW_MASK; ++ xgs_serdes_wr_reg(phydev, aer_blk_reg, ctrl); ++ udelay(100); ++ ++ /* check if out of reset */ ++ if (xgs_serdes_rd_reg(phydev, aer_blk_reg) & ++ IEEE0BLK_IEEECONTROL0_RST_HW_MASK) ++ SERDES_ERROR(("amac serdes reset not completed.\n")); ++} ++ ++static void xgs_serdes_init(struct phy_device *phy_dev) ++{ ++ u16 data16; ++ u32 serdes_id; ++ u16 serdes_id2; ++ u32 __maybe_unused aer_blk_reg, aer; ++ struct phy_device *phydev = phy_dev; ++ ++#ifdef BCMDBG ++ u16 tmp0, tmp1; ++ tmp0 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID0r); ++ tmp1 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID1r); ++ SERDES_TRACE(("-----SERDESID0: 0x%x; SERDESID1: 0x%x\n", tmp0, tmp1)); ++ ++ tmp0 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID2r); ++ tmp1 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID3r); ++ SERDES_TRACE(("-----SERDESID2: 0x%x;SERDESID3: 0x%x\n", tmp0, tmp1)); ++#endif /* BCMDBG */ ++ ++ SERDES_TRACE(("%s: phyaddr %d\n",__FUNCTION__, phydev->mdio.addr)); ++ ++ if (phydev->phy_id != PHY_ID_XGS_AMAC_SERDES) ++ return; ++ ++ serdes_id = serdes_get_id(phydev); ++ serdes_id2 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID2r); ++ ++ if ((serdes_id == SERDES_ID_SB2_AMAC) && ++ (serdes_id2 == SERDES_ID2_SB2_AMAC)) { ++ /* Auto Negotiation 10M/100M/1G ¡V SGMII Slave */ ++ /* Disable pll start sequencer */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr); ++ data16 &= ~XGXSBLK0_CONTROL_PLL_SEQUENCER_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr, data16); ++ ++ /* Set SGMII slave mode */ ++ xgs_serdes_wr_reg(phydev, XGXS16G_SERDESDIGITAL_CONTROL1000X1r, ++ SERDESDIGITAL_CONTROL1000X1_SLAVE_MODE); ++ ++ /* Enable AN 10M/100M/1G */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_IEEE0BLK_IEEECONTROL0r); ++ data16 |= IEEE0BLK_IEEECONTROL0_ENABLE_AN_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_IEEE0BLK_IEEECONTROL0r, data16); ++ ++ /* Enable pll start sequencer */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr); ++ data16 |= XGXSBLK0_CONTROL_PLL_SEQUENCER_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr, data16); ++ } else if ((serdes_id == SERDES_ID_GH2_AMAC) && ++ (serdes_id2 == SERDES_ID2_GH2_AMAC)) { ++ aer = xgs_serdes_get_lane(phydev) << XGXS16G_SERDES_LANE_SHIFT; ++ ++ /* Disable IEEE block select auto-detect */ ++ data16 = 0; ++ aer_blk_reg = (aer | XGXS16G_XGXSBLK0_MISCCONTROL1r); ++ xgs_serdes_wr_reg(phydev, aer_blk_reg, data16); ++ ++ /* Disable lmtcal (broadcast to all lanes) */ ++ data16 = 0x83f8; ++ aer_blk_reg = (aer | XGXS16G_RX3_CONTROL2r); ++ xgs_serdes_wr_reg(phydev, aer_blk_reg, data16); ++ ++ /* Set SGMII slave mode */ ++ aer_blk_reg = (aer | XGXS16G_SERDESDIGITAL_CONTROL1000X1r); ++ xgs_serdes_wr_reg(phydev, aer_blk_reg, ++ SERDESDIGITAL_CONTROL1000X1_SLAVE_MODE); ++ ++ /* Enable AN 10M/100M/1G */ ++ aer_blk_reg = (aer | XGXS16G_IEEE0BLK_IEEECONTROL0r); ++ data16 = xgs_serdes_rd_reg(phydev, aer_blk_reg); ++ data16 |= IEEE0BLK_IEEECONTROL0_ENABLE_AN_MASK; ++ xgs_serdes_wr_reg(phydev, aer_blk_reg, data16); ++ } else if ((serdes_id == SERDES_ID_HX4_AMAC) || ++ (serdes_id == SERDES_ID_KT2_AMAC)) { ++ /* unlock lane */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_WC40_DIGITAL4_MISC3r); ++ data16 &= ~(DIGITAL4_MISC3_LANEDISABLE_MASK); ++ xgs_serdes_wr_reg(phydev, XGXS16G_WC40_DIGITAL4_MISC3r, data16); ++ ++ /* disable CL73 BAM */ ++ data16 = xgs_serdes_rd_reg(phydev, ++ XGXS16G_CL73_USERB0_CL73_BAMCTRL1r); ++ data16 &= ~(CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_MASK); ++ xgs_serdes_wr_reg(phydev, XGXS16G_CL73_USERB0_CL73_BAMCTRL1r, ++ data16); ++ ++ /* Set Local Advertising Configuration */ ++ data16 = MII_ANA_C37_FD | MII_ANA_C37_PAUSE | ++ MII_ANA_C37_ASYM_PAUSE; ++ xgs_serdes_wr_reg(phydev, XGXS16G_COMBO_IEEE0_AUTONEGADVr, data16); ++ ++ /* Disable BAM in Independent Lane mode. Over 1G AN not supported */ ++ data16 = 0; ++ xgs_serdes_wr_reg(phydev, XGXS16G_BAM_NEXTPAGE_MP5_NEXTPAGECTRLr, ++ data16); ++ xgs_serdes_wr_reg(phydev, XGXS16G_BAM_NEXTPAGE_UD_FIELDr, data16); ++ ++ data16 = SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_MASK | ++ SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_MASK; ++ /* Set SGMII mode */ ++ xgs_serdes_wr_reg(phydev, XGXS16G_SERDESDIGITAL_CONTROL1000X1r, ++ data16); ++ ++ /* Set autoneg */ ++ data16 = IEEE0BLK_IEEECONTROL0_ENABLE_AN_MASK | ++ IEEE0BLK_IEEECONTROL0_RESTART_AN_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_COMBO_IEEE0_MIICNTLr, data16); ++ ++ /* Disable 10G parallel detect */ ++ data16 = 0; ++ xgs_serdes_wr_reg(phydev, XGXS16G_AN73_PDET_PARDET10GCONTROLr, ++ data16); ++ ++ /* Disable BAM mode and Teton mode */ ++ xgs_serdes_wr_reg(phydev, XGXS16G_BAM_NEXTPAGE_MP5_NEXTPAGECTRLr, ++ data16); ++ ++ /* Enable lanes */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_XGXSBLK1_LANECTRL0r); ++ data16 |= XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_MASK | ++ XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_XGXSBLK1_LANECTRL0r, data16); ++ ++ /* Set elasticity fifo size to 13.5k to support 12k jumbo pkt size*/ ++ data16 = xgs_serdes_rd_reg(phydev, ++ XGXS16G_SERDESDIGITAL_CONTROL1000X3r); ++ data16 &= SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_MASK; ++ data16 |= (1 << 2); ++ xgs_serdes_wr_reg(phydev, XGXS16G_SERDESDIGITAL_CONTROL1000X3r, ++ data16); ++ ++ /* Enable LPI passthru' for native mode EEE */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_REMOTEPHY_MISC5r); ++ data16 |= XGXS16G_REMOTEPHY_MISC5_LPI_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_REMOTEPHY_MISC5r, data16); ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_XGXSBLK7_EEECONTROLr); ++ data16 |= 0x0007; ++ xgs_serdes_wr_reg(phydev, XGXS16G_XGXSBLK7_EEECONTROLr, data16); ++ } ++} ++ ++/* Needed for HX4/KT2/GH2/WH2 */ ++static void xgs_serdes_start_pll(struct phy_device *phy_dev) ++{ ++ u16 data16; ++ u32 serdes_id; ++ u16 serdes_id2; ++ u32 count = 100; ++ struct phy_device *phydev = phy_dev; ++ static u32 serdes_pll_started = 0; ++ ++ if (phydev->phy_id != PHY_ID_XGS_AMAC_SERDES) ++ return; ++ ++ /* PLL started or not */ ++ if (serdes_pll_started) ++ return; ++ ++ serdes_id = serdes_get_id(phydev); ++ serdes_id2 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID2r); ++ ++ if (!((serdes_id == SERDES_ID_HX4_AMAC) || ++ (serdes_id == SERDES_ID_KT2_AMAC) || ++ (serdes_id == SERDES_ID_GH2_AMAC))) ++ return; ++ ++ /* Change PLL calibration threshold to 0xc for GH2/WH2*/ ++ if ((serdes_id == SERDES_ID_GH2_AMAC) && ++ (serdes_id2 == SERDES_ID2_GH2_AMAC)) { ++ data16 = 0xc << XGXS16G_PLL2_CTRL_CAL_TH_SHIFT; ++ xgs_serdes_wr_reg(phydev, XGXS16G_PLL2_CTRL1r, data16); ++ } ++ ++ /* Start PLL Sequencer and wait for PLL to lock */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr); ++ data16 |= XGXSBLK0_XGXSCONTROL_START_SEQUENCER_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr, data16); ++ ++ /* wait for PLL to lock */ ++ while (count--) { ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_XGXSBLK0_XGXSSTATUSr); ++ if (data16 & XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_MASK) ++ break; ++ udelay(10); ++ } ++ if (!count) ++ SERDES_ERROR(("amac serdes TXPLL did not lock\n")); ++ else ++ serdes_pll_started = 1; ++} ++ ++static int xgs_serdes_config_init(struct phy_device *phydev) ++{ ++ xgs_serdes_reset_core(phydev); ++ xgs_serdes_reset(phydev); ++ xgs_serdes_init(phydev); ++ xgs_serdes_start_pll(phydev); ++ ++ return 0; ++} ++ ++/* ++ * REGADDR: 0x8304 ++ * DESC: 1000X status 1 register ++ * SGMII_MODE 1 = sgmii mode0 = fiber mode (1000-X) ++ * LINK_STATUS 1 = link is up0 = link is down ++ * DUPLEX_STATUS 1 = full-duplex0 = half-duplex ++ * SPEED_STATUS 11 = 2.5G10 = gigabit01 = 100 mbps00 = 10 mbps ++ */ ++static int xgs_serdes_read_status(struct phy_device *phydev) ++{ ++ u16 link_stat; ++ u32 serdes_lane; ++ u32 reg; ++ ++ serdes_lane = xgs_serdes_get_lane(phydev); ++ reg = (serdes_lane << XGXS16G_SERDES_LANE_SHIFT) | ++ XGXS16G_SERDESDIGITAL_STATUS1000X1r; ++ link_stat = xgs_serdes_rd_reg(phydev, reg); ++ ++ if (link_stat & 0x2) ++ phydev->link = 1; ++ else ++ phydev->link = 0; ++ ++ if (link_stat & 0x4) ++ phydev->duplex = 1; ++ else ++ phydev->duplex = 0; ++ ++ phydev->pause = 0; ++ phydev->asym_pause = 0; ++/* ++ link_stat >>= 3; ++ link_stat &= 0x3; ++*/ ++ link_stat >>= SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_SHIFT; ++ link_stat &= ((1 << SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_BITS) - 1); ++ switch(link_stat) { ++ case 0: ++ phydev->speed = SPEED_10; ++ break; ++ case 1: ++ phydev->speed = SPEED_100; ++ break; ++ case 2: ++ phydev->speed = SPEED_1000; ++ break; ++ case 3: ++ phydev->speed = SPEED_2500; ++ break; ++ }; ++ ++ return 0; ++} ++ ++static int xgs_serdes_config_aneg(struct phy_device *phydev) ++{ ++ u32 serdes_lane; ++ u32 reg; ++ u16 data16; ++ ++ if (AUTONEG_ENABLE != phydev->autoneg) ++ return 0; ++ ++ serdes_lane = xgs_serdes_get_lane(phydev); ++ ++ /* Enable AN 10M/100M/1G */ ++ reg = (serdes_lane << XGXS16G_SERDES_LANE_SHIFT) | ++ XGXS16G_IEEE0BLK_IEEECONTROL0r; ++ data16 = xgs_serdes_rd_reg(phydev, reg); ++ //data16 |= IEEE0BLK_IEEECONTROL0_ENABLE_AN_MASK; ++ data16 |= IEEE0BLK_IEEECONTROL0_RESTART_AN_MASK; ++ xgs_serdes_wr_reg(phydev, reg, data16); ++ ++ return 0; ++} ++ ++static int xgs_serdes_aneg_done(struct phy_device *phydev) ++{ ++ u16 link_stat; ++ u32 serdes_lane; ++ u32 reg; ++ ++ serdes_lane = xgs_serdes_get_lane(phydev); ++ reg = (serdes_lane << XGXS16G_SERDES_LANE_SHIFT) | ++ XGXS16G_SERDESDIGITAL_STATUS1000X2r; ++ link_stat = xgs_serdes_rd_reg(phydev, reg); ++ if (link_stat & XGXS16G_SERDES_ANEG_MASK) ++ return 1; ++ ++ return 0; ++} ++ ++static struct mdio_device_id __maybe_unused xgs_serdes_tbl[] = { ++ { PHY_ID_XGS_AMAC_SERDES, 0xfffffff0 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(mdio, xgs_serdes_tbl); ++ ++static struct phy_driver xgs_serdes_drivers[] = { ++ { ++ .phy_id = PHY_ID_XGS_AMAC_SERDES, ++ .phy_id_mask = 0xfffffff0, ++ .name = "Broadcom XGS AMAC SERDES", ++ .config_init = xgs_serdes_config_init, ++ .read_status = xgs_serdes_read_status, ++ .config_aneg = xgs_serdes_config_aneg, ++ .aneg_done = xgs_serdes_aneg_done, ++ } ++}; ++ ++module_phy_driver(xgs_serdes_drivers); ++ ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_DESCRIPTION("XGS iProc AMAC serdes driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/xgs_iproc_serdes_def.h b/drivers/net/phy/xgs_iproc_serdes_def.h +--- a/drivers/net/phy/xgs_iproc_serdes_def.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/phy/xgs_iproc_serdes_def.h 2018-05-10 11:31:32.089402296 +0800 +@@ -0,0 +1,339 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * 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. ++ * ++ * These are serdes defines ++ * ++ */ ++ ++#ifndef _PHY_XGXS16G_H_ ++#define _PHY_XGXS16G_H_ ++ ++/* macros */ ++ ++/* Macros ONLY used after initialization */ ++#define XGXS16G_2p5G_ID(id2) ((id2 & 0xff) == 0xf) ++ ++/****************************************************************************/ ++/***** Starting below is auto-generated register macros from RDB files *****/ ++/****************************************************************************/ ++ ++/**************************************************************************** ++ * Core Enums. ++ ***************************************************************************/ ++ ++#define XGXS16G_IEEE0BLK_IEEECONTROL0r 0x00000000 ++#define XGXS16G_XGXSBLK0_XGXSCONTROLr 0x00008000 ++#define XGXS16G_XGXSBLK0_XGXSSTATUSr 0x00008001 ++#define XGXS16G_XGXSBLK0_MMDSELECTr 0x0000800d ++#define XGXS16G_XGXSBLK0_MISCCONTROL1r 0x0000800e ++#define XGXS16G_XGXSBLK1_LANECTRL0r 0x00008015 ++#define XGXS16G_XGXSBLK1_LANECTRL1r 0x00008016 ++#define XGXS16G_XGXSBLK1_LANECTRL3r 0x00008018 ++#define XGXS16G_TX0_TX_ACONTROL0r 0x00008061 ++#define XGXS16G_RX0_RX_CONTROLr 0x000080b1 ++#define XGXS16G_AN73_PDET_PARDET10GCONTROLr 0x00008131 ++#define XGXS16G_XGXSBLK7_EEECONTROLr 0x00008150 ++#define XGXS16G_TX_LN_SWAP1r 0x00008169 ++#define XGXS16G_SERDESDIGITAL_CONTROL1000X1r 0x00008300 ++#define XGXS16G_SERDESDIGITAL_CONTROL1000X2r 0x00008301 ++#define XGXS16G_SERDESDIGITAL_CONTROL1000X3r 0x00008302 ++#define XGXS16G_SERDESDIGITAL_STATUS1000X1r 0x00008304 ++#define XGXS16G_SERDESDIGITAL_MISC1r 0x00008308 ++#define XGXS16G_SERDESID_SERDESID0r 0x00008310 ++#define XGXS16G_SERDESID_SERDESID1r 0x00008311 ++#define XGXS16G_SERDESID_SERDESID2r 0x00008312 ++#define XGXS16G_SERDESID_SERDESID3r 0x00008313 ++#define XGXS16G_REMOTEPHY_MISC3r 0x0000833c ++#define XGXS16G_REMOTEPHY_MISC5r 0x0000833e ++#define XGXS16G_BAM_NEXTPAGE_MP5_NEXTPAGECTRLr 0x00008350 ++#define XGXS16G_BAM_NEXTPAGE_UD_FIELDr 0x00008357 ++#define XGXS16G_COMBO_IEEE0_MIICNTLr 0x0000ffe0 ++#define XGXS16G_COMBO_IEEE0_AUTONEGADVr 0x0000ffe4 ++#define XGXS16G_WC40_DIGITAL4_MISC3r 0x0000833c ++ ++/* Digital4 :: Misc3 :: laneDisable [06:06] */ ++#define DIGITAL4_MISC3_LANEDISABLE_MASK 0x0040 ++#define DIGITAL4_MISC3_LANEDISABLE_ALIGN 0 ++#define DIGITAL4_MISC3_LANEDISABLE_BITS 1 ++#define DIGITAL4_MISC3_LANEDISABLE_SHIFT 6 ++ ++ ++/**************************************************************************** ++ * XGXS16G_IEEE_ieee0Blk ++ ***************************************************************************/ ++/**************************************************************************** ++ * ieee0Blk :: ieeeControl0 ++ ***************************************************************************/ ++/* ieee0Blk :: ieeeControl0 :: rst_hw [15:15] */ ++#define IEEE0BLK_IEEECONTROL0_RST_HW_MASK 0x8000 ++#define IEEE0BLK_IEEECONTROL0_RST_HW_ALIGN 0 ++#define IEEE0BLK_IEEECONTROL0_RST_HW_BITS 1 ++#define IEEE0BLK_IEEECONTROL0_RST_HW_SHIFT 15 ++ ++/* ieee0Blk :: ieeeControl0 :: gloopback [14:14] */ ++#define IEEE0BLK_IEEECONTROL0_GLOOPBACK_MASK 0x4000 ++#define IEEE0BLK_IEEECONTROL0_GLOOPBACK_ALIGN 0 ++#define IEEE0BLK_IEEECONTROL0_GLOOPBACK_BITS 1 ++#define IEEE0BLK_IEEECONTROL0_GLOOPBACK_SHIFT 14 ++ ++ ++/**************************************************************************** ++ * XGXS16G_USER_XgxsBlk0 ++ ***************************************************************************/ ++/**************************************************************************** ++ * XgxsBlk0 :: xgxsControl ++ ***************************************************************************/ ++/* XgxsBlk0 :: xgxsControl :: start_sequencer [13:13] */ ++#define XGXSBLK0_XGXSCONTROL_START_SEQUENCER_MASK 0x2000 ++#define XGXSBLK0_XGXSCONTROL_START_SEQUENCER_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_START_SEQUENCER_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_START_SEQUENCER_SHIFT 13 ++ ++/* XgxsBlk0 :: xgxsControl :: mode_10g [11:08] */ ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_MASK 0x0f00 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_BITS 4 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_SHIFT 8 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_XGXS 0 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_XGXS_noCC 1 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_IndLane 6 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_XGXS_noLss 8 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_XGXS_noLss_noCC 9 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_protBypass 10 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_protBypass_noDsk 11 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_ComboCoreMode 12 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_ClocksOff 15 ++ ++/* XgxsBlk0 :: xgxsControl :: hstl [05:05] */ ++#define XGXSBLK0_XGXSCONTROL_HSTL_MASK 0x0020 ++#define XGXSBLK0_XGXSCONTROL_HSTL_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_HSTL_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_HSTL_SHIFT 5 ++ ++/* XgxsBlk0 :: xgxsControl :: cdet_en [03:03] */ ++#define XGXSBLK0_XGXSCONTROL_CDET_EN_MASK 0x0008 ++#define XGXSBLK0_XGXSCONTROL_CDET_EN_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_CDET_EN_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_CDET_EN_SHIFT 3 ++ ++/* XgxsBlk0 :: xgxsControl :: eden [02:02] */ ++#define XGXSBLK0_XGXSCONTROL_EDEN_MASK 0x0004 ++#define XGXSBLK0_XGXSCONTROL_EDEN_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_EDEN_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_EDEN_SHIFT 2 ++ ++/* XgxsBlk0 :: xgxsControl :: afrst_en [01:01] */ ++#define XGXSBLK0_XGXSCONTROL_AFRST_EN_MASK 0x0002 ++#define XGXSBLK0_XGXSCONTROL_AFRST_EN_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_AFRST_EN_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_AFRST_EN_SHIFT 1 ++ ++/* XgxsBlk0 :: xgxsControl :: txcko_div [00:00] */ ++#define XGXSBLK0_XGXSCONTROL_TXCKO_DIV_MASK 0x0001 ++#define XGXSBLK0_XGXSCONTROL_TXCKO_DIV_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_TXCKO_DIV_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_TXCKO_DIV_SHIFT 0 ++ ++ ++/**************************************************************************** ++ * XgxsBlk0 :: xgxsStatus ++ ***************************************************************************/ ++/* XgxsBlk0 :: xgxsStatus :: txpll_lock [11:11] */ ++#define XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_MASK 0x0800 ++#define XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_ALIGN 0 ++#define XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_BITS 1 ++#define XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_SHIFT 11 ++ ++ ++/**************************************************************************** ++ * XgxsBlk0 :: miscControl1 ++ ***************************************************************************/ ++/* XgxsBlk0 :: miscControl1 :: PCS_dev_en_override [10:10] */ ++#define XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_MASK 0x0400 ++#define XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_ALIGN 0 ++#define XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_BITS 1 ++#define XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_SHIFT 10 ++ ++/* XgxsBlk0 :: miscControl1 :: PMD_dev_en_override [09:09] */ ++#define XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_MASK 0x0200 ++#define XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_ALIGN 0 ++#define XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_BITS 1 ++#define XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_SHIFT 9 ++ ++/* XgxsBlk0 :: miscControl1 :: ieee_blksel_autodet [01:01] */ ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_MASK 0x0002 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_ALIGN 0 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_BITS 1 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_SHIFT 1 ++ ++/* XgxsBlk0 :: miscControl1 :: ieee_blksel_val [00:00] */ ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_MASK 0x0001 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_ALIGN 0 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_BITS 1 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_SHIFT 0 ++ ++ ++/**************************************************************************** ++ * XGXS16G_USER_XgxsBlk1 ++ ***************************************************************************/ ++/**************************************************************************** ++ * XgxsBlk1 :: laneCtrl0 ++ ***************************************************************************/ ++/* XgxsBlk1 :: laneCtrl0 :: cl36_pcs_en_rx [07:04] */ ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_MASK 0x00f0 ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_ALIGN 0 ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_BITS 4 ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_SHIFT 4 ++ ++/* XgxsBlk1 :: laneCtrl0 :: cl36_pcs_en_tx [03:00] */ ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_MASK 0x000f ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_ALIGN 0 ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_BITS 4 ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_SHIFT 0 ++ ++ ++/**************************************************************************** ++ * XGXS16G_USER_TX0 ++ ***************************************************************************/ ++/**************************************************************************** ++ * TX0 :: Tx_AControl0 ++ ***************************************************************************/ ++/* TX0 :: Tx_AControl0 :: txpol_flip [05:05] */ ++#define TX0_TX_ACONTROL0_TXPOL_FLIP_MASK 0x0020 ++#define TX0_TX_ACONTROL0_TXPOL_FLIP_ALIGN 0 ++#define TX0_TX_ACONTROL0_TXPOL_FLIP_BITS 1 ++#define TX0_TX_ACONTROL0_TXPOL_FLIP_SHIFT 5 ++ ++ ++/**************************************************************************** ++ * XGXS16G_USER_dsc_2_0 ++ ***************************************************************************/ ++/**************************************************************************** ++ * dsc_2_0 :: dsc_ctrl0 ++ ***************************************************************************/ ++/* dsc_2_0 :: dsc_ctrl0 :: rxSeqStart [15:15] */ ++#define DSC_2_0_DSC_CTRL0_RXSEQSTART_MASK 0x8000 ++#define DSC_2_0_DSC_CTRL0_RXSEQSTART_ALIGN 0 ++#define DSC_2_0_DSC_CTRL0_RXSEQSTART_BITS 1 ++#define DSC_2_0_DSC_CTRL0_RXSEQSTART_SHIFT 15 ++ ++ ++/**************************************************************************** ++ * XGXS16G_USER_SerdesDigital ++ ***************************************************************************/ ++/**************************************************************************** ++ * SerdesDigital :: Control1000X1 ++ ***************************************************************************/ ++/* SerdesDigital :: Control1000X1 :: crc_checker_disable [07:07] */ ++#define SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_MASK 0x0080 ++#define SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_ALIGN 0 ++#define SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_BITS 1 ++#define SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_SHIFT 7 ++ ++/* SerdesDigital :: Control1000X1 :: disable_pll_pwrdwn [06:06] */ ++#define SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_MASK 0x0040 ++#define SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_ALIGN 0 ++#define SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_BITS 1 ++#define SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_SHIFT 6 ++ ++/* SerdesDigital :: Control1000X1 :: fiber_mode_1000X [00:00] */ ++#define SERDESDIGITAL_CONTROL1000X1_FIBER_MODE_1000X_MASK 0x0001 ++#define SERDESDIGITAL_CONTROL1000X1_FIBER_MODE_1000X_ALIGN 0 ++#define SERDESDIGITAL_CONTROL1000X1_FIBER_MODE_1000X_BITS 1 ++#define SERDESDIGITAL_CONTROL1000X1_FIBER_MODE_1000X_SHIFT 0 ++ ++/**************************************************************************** ++ * SerdesDigital :: Control1000X3 ++ ***************************************************************************/ ++/* SerdesDigital :: Control1000X3 :: fifo_elasicity_tx_rx [02:01] */ ++#define SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_MASK 0x0006 ++#define SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_ALIGN 0 ++#define SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_BITS 2 ++#define SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_SHIFT 1 ++ ++/* SerdesDigital :: Control1000X3 :: tx_fifo_rst [00:00] */ ++#define SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_MASK 0x0001 ++#define SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_ALIGN 0 ++#define SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_BITS 1 ++#define SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_SHIFT 0 ++ ++/**************************************************************************** ++ * SerdesDigital :: Status1000X1 ++ ***************************************************************************/ ++/* SerdesDigital :: Status1000X1 :: speed_status [04:03] */ ++#define SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_MASK 0x0018 ++#define SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_ALIGN 0 ++#define SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_BITS 2 ++#define SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_SHIFT 3 ++ ++/**************************************************************************** ++ * SerdesDigital :: Misc1 ++ ***************************************************************************/ ++/* SerdesDigital :: Misc1 :: refclk_sel [15:13] */ ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_MASK 0xe000 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_ALIGN 0 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_BITS 3 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_SHIFT 13 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_25MHz 0 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_100MHz 1 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_125MHz 2 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_156p25MHz 3 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_187p5MHz 4 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_161p25Mhz 5 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_50Mhz 6 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_106p25Mhz 7 ++ ++/* SerdesDigital :: Misc1 :: force_speed_sel [04:04] */ ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_MASK 0x0010 ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_ALIGN 0 ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_BITS 1 ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_SHIFT 4 ++ ++/* SerdesDigital :: Misc1 :: force_speed [03:00] */ ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_MASK 0x000f ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_ALIGN 0 ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_BITS 4 ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_SHIFT 0 ++ ++ ++/**************************************************************************** ++ * CL73_UserB0 :: CL73_BAMCtrl1 ++ ***************************************************************************/ ++/* CL73_UserB0 :: CL73_BAMCtrl1 :: CL73_bamEn [15:15] */ ++#define CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_MASK 0x8000 ++#define CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_ALIGN 0 ++#define CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_BITS 1 ++#define CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_SHIFT 15 ++ ++/* Definitions required in addition to the above auto-generated */ ++#define XGXS16G_REMOTEPHY_MISC5_LPI_MASK 0xc000 ++#define IEEE0BLK_IEEECONTROL0_ENABLE_AN_MASK BIT(12) ++#define IEEE0BLK_IEEECONTROL0_RESTART_AN_MASK BIT(9) ++#define XGXSBLK0_CONTROL_PLL_SEQUENCER_MASK BIT(13) ++#define SERDESDIGITAL_CONTROL1000X1_SLAVE_MODE BIT(8) ++#define XGXS16G_PLL2_CTRL1r 0x00008081 ++#define XGXS16G_SERDESDIGITAL_STATUS1000X2r 0x00008305 ++#define XGXS16G_CL73_USERB0_CL73_BAMCTRL1r 0x00008372 ++#define XGXS16G_RX3_CONTROL2r 0x00008482 ++#define XGXS16G_PLL2_CTRL_CAL_TH_SHIFT 7 ++#define XGXS16G_SERDES_LANE_SHIFT 16 ++#define XGXS16G_SERDES_ANEG_MASK BIT(4) ++#define MII_ANA_C37_PAUSE BIT(7) ++#define MII_ANA_C37_ASYM_PAUSE BIT(8) ++#define MII_ANA_C37_FD BIT(5) ++ ++#endif /* _PHY_XGXS16G_H_ */ ++ ++/* End of File */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig +--- a/drivers/pci/host/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/pci/host/Kconfig 2018-05-10 11:31:32.457402700 +0800 +@@ -99,6 +99,15 @@ config PCI_VERSATILE + bool "ARM Versatile PB PCI controller" + depends on ARCH_VERSATILE + ++config PCIE_XGS_IPROC ++ bool "Broadcom XGS iProc PCIe controller" ++ select PCI_DOMAINS ++ depends on ARCH_XGS_IPROC ++ default n ++ help ++ This enables the XGS iProc PCIe core controller support for Broadcom's ++ iProc family of SoCs. ++ + config PCIE_IPROC + tristate + select PCI_DOMAINS +@@ -129,7 +138,7 @@ config PCIE_IPROC_BCMA + + config PCIE_IPROC_MSI + bool "Broadcom iProc PCIe MSI support" +- depends on PCIE_IPROC_PLATFORM || PCIE_IPROC_BCMA ++ depends on PCIE_IPROC_PLATFORM || PCIE_IPROC_BCMA || PCIE_XGS_IPROC + depends on PCI_MSI_IRQ_DOMAIN + default ARCH_BCM_IPROC + help +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile +--- a/drivers/pci/host/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/pci/host/Makefile 2018-05-10 11:31:32.457402700 +0800 +@@ -16,6 +16,7 @@ obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o + obj-$(CONFIG_PCIE_IPROC_MSI) += pcie-iproc-msi.o + obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o + obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o ++obj-$(CONFIG_PCIE_XGS_IPROC) += pcie-xgs-iproc.o + obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o + obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o + obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/pci/host/pcie-iproc.h b/drivers/pci/host/pcie-iproc.h +--- a/drivers/pci/host/pcie-iproc.h 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/pci/host/pcie-iproc.h 2018-05-10 11:31:32.461402704 +0800 +@@ -93,6 +93,9 @@ struct iproc_pcie { + struct resource mem; + struct pci_bus *root_bus; + struct phy *phy; ++#ifdef CONFIG_PCIE_XGS_IPROC ++ struct phy_device *mdio_phy; ++#endif + int (*map_irq)(const struct pci_dev *, u8, u8); + bool ep_is_internal; + bool has_apb_err_disable; +@@ -108,9 +111,11 @@ struct iproc_pcie { + struct iproc_msi *msi; + }; + ++#ifndef CONFIG_PCIE_XGS_IPROC + int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res); + int iproc_pcie_remove(struct iproc_pcie *pcie); + int iproc_pcie_shutdown(struct iproc_pcie *pcie); ++#endif + + #ifdef CONFIG_PCIE_IPROC_MSI + int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/pci/host/pcie-xgs-iproc.c b/drivers/pci/host/pcie-xgs-iproc.c +--- a/drivers/pci/host/pcie-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/pci/host/pcie-xgs-iproc.c 2018-05-10 11:31:32.461402704 +0800 +@@ -0,0 +1,541 @@ ++/* ++ * Copyright (C) 2014 Hauke Mehrtens ++ * Copyright (C) 2015 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "pcie-iproc.h" ++ ++#define CLK_CONTROL_OFFSET 0x000 ++ ++#define CFG_IND_ADDR_OFFSET 0x120 ++#define CFG_IND_ADDR_MASK 0x00001ffc ++#define CFG_IND_DATA_OFFSET 0x124 ++ ++#define CFG_ADDR_OFFSET 0x1f8 ++#define CFG_ADDR_BUS_NUM_SHIFT 20 ++#define CFG_ADDR_BUS_NUM_MASK 0x0ff00000 ++#define CFG_ADDR_DEV_NUM_SHIFT 15 ++#define CFG_ADDR_DEV_NUM_MASK 0x000f8000 ++#define CFG_ADDR_FUNC_NUM_SHIFT 12 ++#define CFG_ADDR_FUNC_NUM_MASK 0x00007000 ++#define CFG_ADDR_REG_NUM_SHIFT 2 ++#define CFG_ADDR_REG_NUM_MASK 0x00000ffc ++#define CFG_ADDR_CFG_TYPE_SHIFT 0 ++#define CFG_ADDR_CFG_TYPE_MASK 0x00000003 ++ ++#define CFG_DATA_OFFSET 0x1fc ++ ++#define SYS_RC_INTX_EN 0x330 ++#define SYS_RC_INTX_MASK 0xf ++ ++#define IPROC_PCI_EXP_CAP 0xac ++ ++struct pcie_sw_wa { ++ const char *wa_name; ++ void (*wa_func)(struct iproc_pcie *pcie); ++}; ++ ++extern void xgs_phy_wr_reg(struct phy_device *phydev, u32 regnum, u16 data); ++ ++static inline struct iproc_pcie *iproc_pcie_data(struct pci_bus *bus) ++{ ++ struct iproc_pcie *pcie; ++#ifdef CONFIG_ARM ++ struct pci_sys_data *sys = bus->sysdata; ++ ++ pcie = sys->private_data; ++#else ++ pcie = bus->sysdata; ++#endif ++ return pcie; ++} ++ ++/** ++ * Note access to the configuration registers are protected at the higher layer ++ * by 'pci_lock' in drivers/pci/access.c ++ */ ++static void __iomem *iproc_pcie_map_cfg_bus(struct iproc_pcie *pcie, ++ int busno, unsigned int devfn, ++ int where) ++{ ++ u32 slot = PCI_SLOT(devfn); ++ u32 fn = PCI_FUNC(devfn); ++ u32 val; ++ ++ /* root complex access */ ++ if (busno == 0) { ++ if (slot >= 1) ++ return NULL; ++ writel(where & CFG_IND_ADDR_MASK, ++ pcie->base + CFG_IND_ADDR_OFFSET); ++ return (pcie->base + CFG_IND_DATA_OFFSET); ++ } ++ ++ if (fn > 1) ++ return NULL; ++ ++ /* EP device access */ ++ val = (busno << CFG_ADDR_BUS_NUM_SHIFT) | ++ (slot << CFG_ADDR_DEV_NUM_SHIFT) | ++ (fn << CFG_ADDR_FUNC_NUM_SHIFT) | ++ (where & CFG_ADDR_REG_NUM_MASK) | ++ (1 & CFG_ADDR_CFG_TYPE_MASK); ++ writel(val, pcie->base + CFG_ADDR_OFFSET); ++ ++ return (pcie->base + CFG_DATA_OFFSET); ++} ++ ++static void __iomem *iproc_pcie_bus_map_cfg_bus(struct pci_bus *bus, ++ unsigned int devfn, ++ int where) ++{ ++ return iproc_pcie_map_cfg_bus(iproc_pcie_data(bus), bus->number, devfn, ++ where); ++} ++ ++static int iproc_pci_raw_config_read32(struct iproc_pcie *pcie, ++ unsigned int devfn, int where, ++ int size, u32 *val) ++{ ++ void __iomem *addr; ++ ++ addr = iproc_pcie_map_cfg_bus(pcie, 0, devfn, where & ~0x3); ++ if (!addr) { ++ *val = ~0; ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ } ++ ++ *val = readl(addr); ++ ++ if (size <= 2) ++ *val = (*val >> (8 * (where & 3))) & ((1 << (size * 8)) - 1); ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static int iproc_pci_raw_config_write32(struct iproc_pcie *pcie, ++ unsigned int devfn, int where, ++ int size, u32 val) ++{ ++ void __iomem *addr; ++ u32 mask, tmp; ++ ++ addr = iproc_pcie_map_cfg_bus(pcie, 0, devfn, where & ~0x3); ++ if (!addr) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ if (size == 4) { ++ writel(val, addr); ++ return PCIBIOS_SUCCESSFUL; ++ } ++ ++ mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8)); ++ tmp = readl(addr) & mask; ++ tmp |= val << ((where & 0x3) * 8); ++ writel(tmp, addr); ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++ ++static struct pci_ops iproc_pcie_ops = { ++ .map_bus = iproc_pcie_bus_map_cfg_bus, ++ .read = pci_generic_config_read32, ++ .write = pci_generic_config_write32, ++}; ++ ++static inline void pcie_wrong_gen2_wa(struct iproc_pcie * pcie) ++{ ++ xgs_phy_wr_reg(pcie->mdio_phy, 0x8633, 0x190); ++ xgs_phy_wr_reg(pcie->mdio_phy, 0x8639, 0x191); ++} ++ ++static void iproc_pcie_reset(struct iproc_pcie *pcie) ++{ ++ /* configured as RC and send a downstream reset */ ++ writel(0, pcie->base + CLK_CONTROL_OFFSET); ++ mdelay(1); ++ writel(1, pcie->base + CLK_CONTROL_OFFSET); ++ msleep(100); ++} ++ ++static void pcie_rc_wa(struct iproc_pcie * pcie) ++{ ++ /* Setting for PCIe Serdes PLL output */ ++ xgs_phy_wr_reg(pcie->mdio_phy, 0x2103, 0x2b1c); ++ xgs_phy_wr_reg(pcie->mdio_phy, 0x1300, 0x000b); ++ msleep(100); ++} ++ ++/* currently for Greyhound */ ++static void pcie_tx_de_emp_wa(struct iproc_pcie * pcie) ++{ ++ u32 tmp32; ++ ++ iproc_pci_raw_config_read32(pcie, 0, 0xdc, 4, &tmp32); ++ tmp32 |= (0x1 << 6); ++ iproc_pci_raw_config_write32(pcie, 0, 0xdc, 4, tmp32); ++ iproc_pci_raw_config_read32(pcie, 0, 0xdc, 4, &tmp32); ++} ++ ++static const struct pcie_sw_wa pcie_wa_tab[] = { ++ { ++ .wa_name = "pcie_wrong_gen2", ++ .wa_func = pcie_wrong_gen2_wa, ++ }, ++ { ++ .wa_name = "pcie_rc", ++ .wa_func = pcie_rc_wa, ++ }, ++ { ++ .wa_name = "pcie_perst", ++ .wa_func = iproc_pcie_reset, ++ }, ++ { ++ .wa_name = "pcie_tx_de_emp", ++ .wa_func = pcie_tx_de_emp_wa, ++ }, ++}; ++ ++/* ++ * Run the specific pcie workaround function specified in "pcie_wa_tab", ++ * if "wa_name" is found on the "wa-list" property of pcie node. ++ */ ++static void pcie_sw_wa_func(const char *wa_name, struct iproc_pcie *pcie) ++{ ++ struct device_node *np = pcie->dev->of_node; ++ int wa_num_max = ARRAY_SIZE(pcie_wa_tab); ++ int wa_num = of_property_count_strings(np, "wa-list"); ++ const char *wa_name_dts; ++ int i; ++ ++ /* workaround required? */ ++ if (wa_num <= 0) ++ return; ++ ++ for (i = 0; i < wa_num; i++) { ++ of_property_read_string_index(np, "wa-list", i, &wa_name_dts); ++ if (!strcmp(wa_name, wa_name_dts)) ++ break; ++ } ++ ++ /* The wa_name is found on wa-list of pcie node? */ ++ if (i == wa_num) ++ return; ++ ++ for (i = 0; i < wa_num_max; i++) ++ if (!strcmp(pcie_wa_tab[i].wa_name, wa_name)) { ++ pcie_wa_tab[i].wa_func(pcie); ++ break; ++ } ++} ++ ++static int iproc_pcie_check_link(struct iproc_pcie *pcie) ++{ ++ struct device *dev = pcie->dev; ++ u32 hdr_type, link_ctrl, link_status, class; ++ bool link_is_active = false; ++ ++ /* make sure we are not in EP mode */ ++ iproc_pci_raw_config_read32(pcie, 0, PCI_HEADER_TYPE, 1, &hdr_type); ++ if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) { ++ dev_err(dev, "in EP mode, hdr=%#02x\n", hdr_type); ++ return -EFAULT; ++ } ++ ++ /* SB2/GH/HR3/GH2 */ ++ pcie_sw_wa_func("pcie_rc", pcie); ++ ++ /* GH/HR3/GH2 */ ++ pcie_sw_wa_func("pcie_perst", pcie); ++ ++ /* Not enabled in DT file currently */ ++ pcie_sw_wa_func("pcie_tx_de_emp", pcie); ++ ++ /* Force class to PCI_CLASS_BRIDGE_PCI (0x0604) */ ++#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c ++#define PCI_CLASS_BRIDGE_MASK 0xffff00 ++#define PCI_CLASS_BRIDGE_SHIFT 8 ++ iproc_pci_raw_config_read32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET, ++ 4, &class); ++ class &= ~PCI_CLASS_BRIDGE_MASK; ++ class |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT); ++ iproc_pci_raw_config_write32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET, ++ 4, class); ++ ++ /* check link status to see if link is active */ ++ iproc_pci_raw_config_read32(pcie, 0, IPROC_PCI_EXP_CAP + PCI_EXP_LNKSTA, ++ 2, &link_status); ++ if (link_status & PCI_EXP_LNKSTA_NLW) ++ link_is_active = true; ++ ++ if (!link_is_active) { ++ /* try GEN 1 link speed */ ++#define PCI_TARGET_LINK_SPEED_MASK 0xf ++#define PCI_TARGET_LINK_SPEED_GEN2 0x2 ++#define PCI_TARGET_LINK_SPEED_GEN1 0x1 ++ iproc_pci_raw_config_read32(pcie, 0, ++ IPROC_PCI_EXP_CAP + PCI_EXP_LNKCTL2, ++ 4, &link_ctrl); ++ if ((link_ctrl & PCI_TARGET_LINK_SPEED_MASK) == ++ PCI_TARGET_LINK_SPEED_GEN2) { ++ link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK; ++ link_ctrl |= PCI_TARGET_LINK_SPEED_GEN1; ++ iproc_pci_raw_config_write32(pcie, 0, ++ IPROC_PCI_EXP_CAP + PCI_EXP_LNKCTL2, ++ 4, link_ctrl); ++ msleep(100); ++ ++ iproc_pci_raw_config_read32(pcie, 0, ++ IPROC_PCI_EXP_CAP + PCI_EXP_LNKSTA, ++ 2, &link_status); ++ if (link_status & PCI_EXP_LNKSTA_NLW) ++ link_is_active = true; ++ } ++ } ++ ++ dev_info(pcie->dev, "link: %s\n", link_is_active ? "UP" : "DOWN"); ++ ++ return link_is_active ? 0 : -ENODEV; ++} ++ ++static void iproc_pcie_enable(struct iproc_pcie *pcie) ++{ ++ writel(SYS_RC_INTX_MASK, pcie->base + SYS_RC_INTX_EN); ++} ++ ++static int iproc_pcie_msi_enable(struct iproc_pcie *pcie) ++{ ++ struct device_node *msi_node; ++ ++ msi_node = of_parse_phandle(pcie->dev->of_node, "msi-parent", 0); ++ if (!msi_node) ++ return -ENODEV; ++ ++ /* ++ * If another MSI controller is being used, the call below should fail ++ * but that is okay ++ */ ++ return iproc_msi_init(pcie, msi_node); ++} ++ ++static void iproc_pcie_msi_disable(struct iproc_pcie *pcie) ++{ ++ iproc_msi_exit(pcie); ++} ++ ++static int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) ++{ ++ struct device *dev; ++ int ret; ++ void *sysdata; ++ struct pci_bus *child; ++ struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); ++ ++ if (!pcie || !pcie->dev || !pcie->base) ++ return -EINVAL; ++ ++ dev = pcie->dev; ++ ++ ret = devm_request_pci_bus_resources(dev, res); ++ if (ret) ++ return ret; ++ ++ ret = phy_init(pcie->phy); ++ if (ret) { ++ dev_err(pcie->dev, "unable to initialize PCIe PHY\n"); ++ return ret; ++ } ++ ++ ret = phy_power_on(pcie->phy); ++ if (ret) { ++ dev_err(pcie->dev, "unable to power on PCIe PHY\n"); ++ goto err_exit_phy; ++ } ++ ++ iproc_pcie_reset(pcie); ++ ++#ifdef CONFIG_ARM ++ pcie->sysdata.private_data = pcie; ++ sysdata = &pcie->sysdata; ++#else ++ sysdata = pcie; ++#endif ++ ++ ret = iproc_pcie_check_link(pcie); ++ if (ret) { ++ dev_err(pcie->dev, "no PCIe EP device detected\n"); ++ goto err_power_off_phy; ++ } ++ ++ iproc_pcie_enable(pcie); ++ ++ if (IS_ENABLED(CONFIG_PCI_MSI)) ++ if (iproc_pcie_msi_enable(pcie)) ++ dev_info(pcie->dev, "not using iProc MSI\n"); ++ ++ list_splice_init(res, &host->windows); ++ host->busnr = 0; ++ host->dev.parent = dev; ++ host->ops = &iproc_pcie_ops; ++ host->sysdata = sysdata; ++ host->map_irq = pcie->map_irq; ++ host->swizzle_irq = pci_common_swizzle; ++ ++ ret = pci_scan_root_bus_bridge(host); ++ if (ret < 0) { ++ dev_err(dev, "failed to scan host: %d\n", ret); ++ goto err_power_off_phy; ++ } ++ ++ pci_assign_unassigned_bus_resources(host->bus); ++ ++ pcie->root_bus = host->bus; ++ ++ list_for_each_entry(child, &host->bus->children, node) ++ pcie_bus_configure_settings(child); ++ ++ pci_bus_add_devices(host->bus); ++ ++ return 0; ++ ++err_power_off_phy: ++ phy_power_off(pcie->phy); ++err_exit_phy: ++ phy_exit(pcie->phy); ++ ++ return ret; ++} ++ ++static int iproc_pcie_probe(struct platform_device *pdev) ++{ ++ struct iproc_pcie *pcie; ++ struct device_node *np = pdev->dev.of_node; ++ struct device_node *mdio_phy_np = NULL; ++ struct resource reg; ++ struct pci_host_bridge *bridge; ++ resource_size_t iobase = 0; ++ LIST_HEAD(res); ++ int ret; ++ ++ bridge = devm_pci_alloc_host_bridge(&pdev->dev, sizeof(*pcie)); ++ if (!bridge) ++ return -ENOMEM; ++ ++ pcie = pci_host_bridge_priv(bridge); ++ ++ pcie->dev = &pdev->dev; ++ platform_set_drvdata(pdev, pcie); ++ ++ pcie->type = (enum iproc_pcie_type)np->data; ++ ++ ret = of_address_to_resource(np, 0, ®); ++ if (ret < 0) { ++ dev_err(pcie->dev, "unable to obtain controller resources\n"); ++ return ret; ++ } ++ ++ pcie->base = devm_ioremap_resource(pcie->dev, ®); ++ if (IS_ERR(pcie->base)) ++ return PTR_ERR(pcie->base); ++ ++ /* MSI message base addr*/ ++ pcie->base_addr = reg.start; ++ ++ /* PHY use is optional */ ++ pcie->phy = devm_phy_get(&pdev->dev, "pcie-phy"); ++ if (IS_ERR(pcie->phy)) { ++ if (PTR_ERR(pcie->phy) == -EPROBE_DEFER) ++ return -EPROBE_DEFER; ++ pcie->phy = NULL; ++ } ++ ++ /* PHY controlled through MDIO for HX4/KT2 */ ++ mdio_phy_np = of_parse_phandle(np, "mdio-phy-handle", 0); ++ if (mdio_phy_np) ++ pcie->mdio_phy = of_phy_find_device(mdio_phy_np); ++ ++ ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &iobase); ++ if (ret) { ++ dev_err(pcie->dev, ++ "unable to get PCI host bridge resources\n"); ++ return ret; ++ } ++ ++ /* HX4/KT2/HR2 */ ++ pcie_sw_wa_func("pcie_wrong_gen2", pcie); ++ ++ pcie->map_irq = of_irq_parse_and_map_pci; ++ ++ ret = iproc_pcie_setup(pcie, &res); ++ if (ret) ++ dev_err(pcie->dev, "PCIe controller setup failed\n"); ++ ++ pci_free_resource_list(&res); ++ ++ return ret; ++} ++ ++static int iproc_pcie_remove(struct platform_device *pdev) ++{ ++ struct iproc_pcie *pcie = platform_get_drvdata(pdev); ++ ++ pci_stop_root_bus(pcie->root_bus); ++ pci_remove_root_bus(pcie->root_bus); ++ ++ iproc_pcie_msi_disable(pcie); ++ ++ phy_power_off(pcie->phy); ++ phy_exit(pcie->phy); ++ ++ return 0; ++} ++ ++static const struct of_device_id iproc_pcie_of_match_table[] = { ++ { ++ .compatible = "brcm,iproc-pcie", ++ .data = (int *)IPROC_PCIE_PAXB, ++ }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, iproc_pcie_of_match_table); ++ ++static struct platform_driver iproc_pcie_pltfm_driver = { ++ .driver = { ++ .name = "iproc-pcie", ++ .of_match_table = of_match_ptr(iproc_pcie_of_match_table), ++ }, ++ .probe = iproc_pcie_probe, ++ .remove = iproc_pcie_remove, ++}; ++ ++module_platform_driver(iproc_pcie_pltfm_driver); ++ ++MODULE_DESCRIPTION("Broadcom XGS iProc PCIe driver"); ++MODULE_LICENSE("GPL v2"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/Makefile b/drivers/soc/bcm/Makefile +--- a/drivers/soc/bcm/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/soc/bcm/Makefile 2018-05-10 11:31:33.013403309 +0800 +@@ -1,2 +1,3 @@ + obj-$(CONFIG_RASPBERRYPI_POWER) += raspberrypi-power.o + obj-$(CONFIG_SOC_BRCMSTB) += brcmstb/ ++obj-$(CONFIG_ARCH_XGS_IPROC) += xgs_iproc/ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/xgs_iproc/Makefile b/drivers/soc/bcm/xgs_iproc/Makefile +--- a/drivers/soc/bcm/xgs_iproc/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/xgs_iproc/Makefile 2018-05-10 11:31:33.017403314 +0800 +@@ -0,0 +1 @@ ++obj-$(CONFIG_ARCH_XGS_IPROC) += xgs-iproc-misc-setup.o xgs-iproc-idm.o xgs-iproc.o iproc-cmic.o iproc-cmicx.o iproc-cmicd.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/xgs_iproc/iproc-cmic.c b/drivers/soc/bcm/xgs_iproc/iproc-cmic.c +--- a/drivers/soc/bcm/xgs_iproc/iproc-cmic.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/xgs_iproc/iproc-cmic.c 2018-05-10 11:31:33.017403314 +0800 +@@ -0,0 +1,161 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++extern const struct sbus_ops cmicx_sbus_ops; ++extern const struct sbus_ops cmicd_sbus_ops; ++ ++static struct iproc_cmic *cmic; ++ ++int iproc_cmic_schan_reg32_write(u32 blk_type, u32 addr, u32 val) ++{ ++ if (cmic && cmic->sbus_ops) { ++ if (cmic->sbus_ops->reg32_write) { ++ return cmic->sbus_ops->reg32_write(cmic, blk_type, addr, val); ++ } ++ } ++ return -EINVAL; ++} ++ ++u32 iproc_cmic_schan_reg32_read(u32 blk_type, u32 addr) ++{ ++ if (cmic && cmic->sbus_ops) { ++ if (cmic->sbus_ops->reg32_read) { ++ return cmic->sbus_ops->reg32_read(cmic, blk_type, addr); ++ } ++ } ++ return 0; ++} ++ ++int iproc_cmic_schan_reg64_write(u32 blk_type, u32 addr, u64 val) ++{ ++ if (cmic && cmic->sbus_ops) { ++ if (cmic->sbus_ops->reg64_write) { ++ return cmic->sbus_ops->reg64_write(cmic, blk_type, addr, val); ++ } ++ } ++ return -EINVAL; ++} ++ ++u64 iproc_cmic_schan_reg64_read(u32 blk_type, u32 addr) ++{ ++ if (cmic && cmic->sbus_ops) { ++ if (cmic->sbus_ops->reg64_read) { ++ return cmic->sbus_ops->reg64_read(cmic, blk_type, addr); ++ } ++ } ++ return 0; ++} ++ ++int iproc_cmic_schan_ucmem_write(u32 blk_type, u32 *mem) ++{ ++ if (cmic && cmic->sbus_ops) { ++ if (cmic->sbus_ops->ucmem_write) { ++ return cmic->sbus_ops->ucmem_write(cmic, blk_type, mem); ++ } ++ } ++ return -EINVAL; ++} ++ ++int iproc_cmic_schan_ucmem_read(u32 blk_type, u32 *mem) ++{ ++ if (cmic && cmic->sbus_ops) { ++ if (cmic->sbus_ops->ucmem_read) { ++ return cmic->sbus_ops->ucmem_read(cmic, blk_type, mem); ++ } ++ } ++ return -EINVAL; ++} ++ ++void inline __iomem *iproc_cmic_base_get(void) ++{ ++ if (cmic && cmic->base) { ++ return cmic->base; ++ } ++ return NULL; ++} ++ ++/**************************************************************************** ++ ***************************************************************************/ ++static int cmic_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ ++ cmic = devm_kzalloc(&pdev->dev, sizeof(*cmic), GFP_KERNEL); ++ if (!cmic) { ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(pdev, cmic); ++ cmic->dev = &pdev->dev; ++ ++ cmic->base = (void *)of_iomap(np, 0); ++ if (IS_ERR(cmic->base)) { ++ dev_err(&pdev->dev, "Unable to iomap CMIC resource\n"); ++ return PTR_ERR(cmic->base); ++ } ++ ++ if (of_device_is_compatible(np, "brcm,iproc-cmicx")) { ++ cmic->sbus_ops = &cmicx_sbus_ops; ++ } else if (of_device_is_compatible(np, "brcm,iproc-cmicd")) { ++ cmic->sbus_ops = &cmicd_sbus_ops; ++ } ++ ++ if (cmic->sbus_ops) { ++ if (cmic->sbus_ops->init) { ++ /* Initial cmic */ ++ cmic->sbus_ops->init(cmic); ++ } ++ } ++ ++ return 0; ++} ++ ++static int cmic_remove(struct platform_device *pdev) ++{ ++ if (cmic->base) { ++ iounmap(cmic->base); ++ } ++ ++ devm_kfree(&pdev->dev, cmic); ++ cmic = NULL; ++ ++ return 0; ++} ++ ++static const struct of_device_id iproc_cmic_of_match[] = { ++ {.compatible = "brcm,iproc-cmicx",}, ++ {.compatible = "brcm,iproc-cmicd",}, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, iproc_cmic_of_match); ++ ++static struct platform_driver iproc_cmic_driver = { ++ .driver = { ++ .name = "iproc_cmic", ++ .of_match_table = iproc_cmic_of_match, ++ }, ++ .probe = cmic_probe, ++ .remove = cmic_remove, ++}; ++ ++module_platform_driver(iproc_cmic_driver); ++MODULE_LICENSE("GPL"); ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/xgs_iproc/iproc-cmicd.c b/drivers/soc/bcm/xgs_iproc/iproc-cmicd.c +--- a/drivers/soc/bcm/xgs_iproc/iproc-cmicd.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/xgs_iproc/iproc-cmicd.c 2018-05-10 11:31:33.017403314 +0800 +@@ -0,0 +1,166 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define CMICD_SBUS_RING_MAP_0_7(base) (base + 0x10098) ++#define CMICD_SBUS_RING_MAP_8_15(base) (base + 0x1009C) ++#define CMICD_SBUS_RING_MAP_16_23(base) (base + 0x100A0) ++#define CMICD_SBUS_RING_MAP_24_31(base) (base + 0x100A4) ++#define CMICD_SCHAN_CH0_CTRL(base) (base + 0x10000) ++#define CMICD_SCHAN_CH0_MESSAGE(base) (base + 0x1000c) ++ ++#define READ_MEMORY_CMD_MSG 0x07 ++#define READ_MEMORY_ACK_MSG 0x08 ++#define WRITE_MEMORY_CMD_MSG 0x09 ++#define WRITE_MEMORY_ACK_MSG 0x0a ++#define READ_REGISTER_CMD_MSG 0x0b ++#define READ_REGISTER_ACK_MSG 0x0c ++#define WRITE_REGISTER_CMD_MSG 0x0d ++#define WRITE_REGISTER_ACK_MSG 0x0e ++#define SBUSV4_REGTYPE_SHIFT 25 ++#define SBUSV4_REGADDR_SHIFT 8 ++#define SBUSV4_OPCODE_SHIFT 26 ++#define SBUSV4_BLOCKID_SHIFT 19 ++#define SBUSV4_DLEN_SHIFT 7 ++ ++#define CMICD_XLPORT_WC_UCMEM_DATA 0x0 ++#define REG32_DATA_LEN 4 ++#define REG64_DATA_LEN 8 ++#define UCMEM_DATA_LEN 16 ++ ++#define CMICD_BLOCK_ID_TOP 16 ++ ++ ++#define CMICD_CMD(mode, blk, len) ((mode << SBUSV4_OPCODE_SHIFT) | \ ++ (blk << SBUSV4_BLOCKID_SHIFT) | \ ++ (len << SBUSV4_DLEN_SHIFT)) ++ ++static int __cmicd_schan_write(struct iproc_cmic *cmic, ++ u32 cmd, u32 addr, u32 *val, int len) ++{ ++ u32 read = 0x0; ++ void __iomem *msg_addr; ++ int i; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ msg_addr = CMICD_SCHAN_CH0_MESSAGE(cmic->base); ++ writel(cmd, msg_addr); ++ ++ msg_addr += 4; ++ writel(addr, msg_addr); ++ ++ for (i = 0; i < len; i++) { ++ msg_addr += 4; ++ writel(val[i], msg_addr); ++ } ++ ++ writel(0x1, CMICD_SCHAN_CH0_CTRL(cmic->base)); ++ ++ // FIXME, should set timeout ++ while (read != 0x2) { ++ read = readl(CMICD_SCHAN_CH0_CTRL(cmic->base)); ++ } ++ return read; ++} ++ ++static int __cmicd_schan_read(struct iproc_cmic *cmic, ++ u32 cmd, u32 addr, u32 *val, int len) ++{ ++ u32 read = 0x0; ++ void __iomem *msg_addr; ++ int i; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ read = __cmicd_schan_write(cmic, cmd, addr, NULL, 0); ++ if (read != 0x02) { ++ return read; ++ } ++ ++ msg_addr = CMICD_SCHAN_CH0_MESSAGE(cmic->base); ++ for (i = 0; i < len; i++) { ++ msg_addr += 4; ++ val[i] = readl(msg_addr); ++ } ++ return val[0]; ++} ++ ++static int iproc_cmicd_schan_reg32_write(struct iproc_cmic *cmic, ++ u32 blk_type, u32 addr, u32 val) ++{ ++ u32 cmd, block; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ if (blk_type == CMIC_BLOCK_TYPE_TOP) { ++ block = CMICD_BLOCK_ID_TOP; ++ } else { ++ return -EINVAL; ++ } ++ ++ cmd = CMICD_CMD(WRITE_REGISTER_CMD_MSG, block, REG32_DATA_LEN); ++ return __cmicd_schan_write(cmic, cmd, addr, &val, 1); ++} ++ ++static u32 iproc_cmicd_schan_reg32_read(struct iproc_cmic *cmic, ++ u32 blk_type, u32 addr) ++{ ++ u32 cmd, block, val; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ if (blk_type == CMIC_BLOCK_TYPE_TOP) { ++ block = CMICD_BLOCK_ID_TOP; ++ } else { ++ return -EINVAL; ++ } ++ ++ cmd = CMICD_CMD(READ_REGISTER_CMD_MSG, block, REG32_DATA_LEN); ++ return __cmicd_schan_read(cmic, cmd, addr, &val, 1); ++} ++ ++static int iproc_cmicd_init(struct iproc_cmic *cmic) ++{ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ /* Configure SBUS Ring Map for TOP, block id = 16, ring number = 4 */ ++ writel(0x11112200, CMICD_SBUS_RING_MAP_0_7(cmic->base)); ++ writel(0x00430001, CMICD_SBUS_RING_MAP_8_15(cmic->base)); ++ writel(0x00005064, CMICD_SBUS_RING_MAP_16_23(cmic->base)); ++ writel(0x00000000, CMICD_SBUS_RING_MAP_24_31(cmic->base)); ++ ++ return 0; ++} ++ ++const struct sbus_ops cmicd_sbus_ops = { ++ .init = iproc_cmicd_init, ++ .reg32_write = iproc_cmicd_schan_reg32_write, ++ .reg32_read = iproc_cmicd_schan_reg32_read, ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/xgs_iproc/iproc-cmicx.c b/drivers/soc/bcm/xgs_iproc/iproc-cmicx.c +--- a/drivers/soc/bcm/xgs_iproc/iproc-cmicx.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/xgs_iproc/iproc-cmicx.c 2018-05-30 15:50:51.032753168 +0800 +@@ -0,0 +1,269 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define CMICX_TOP_SBUS_TIMEOUT(base) (base + 0x00000) ++#define CMICX_TOP_SBUS_RING_MAP_0_7(base) (base + 0x0000c) ++#define CMICX_TOP_SBUS_RING_MAP_32_39(base) (base + 0x0001c) ++#define CMICX_SCHAN_CH0_CTRL(base) (base + 0x10000) ++#define CMICX_SCHAN_CH0_MESSAGE(base) (base + 0x1000c) ++ ++#define READ_MEMORY_CMD_MSG 0x07 ++#define READ_MEMORY_ACK_MSG 0x08 ++#define WRITE_MEMORY_CMD_MSG 0x09 ++#define WRITE_MEMORY_ACK_MSG 0x0a ++#define READ_REGISTER_CMD_MSG 0x0b ++#define READ_REGISTER_ACK_MSG 0x0c ++#define WRITE_REGISTER_CMD_MSG 0x0d ++#define WRITE_REGISTER_ACK_MSG 0x0e ++#define SBUSV4_REGTYPE_SHIFT 25 ++#define SBUSV4_REGADDR_SHIFT 8 ++#define SBUSV4_OPCODE_SHIFT 26 ++#define SBUSV4_BLOCKID_SHIFT 19 ++#define SBUSV4_DLEN_SHIFT 7 ++ ++#define CMICX_XLPORT_WC_UCMEM_DATA 0x0 ++#define REG32_DATA_LEN 4 ++#define REG64_DATA_LEN 8 ++#define UCMEM_DATA_LEN 16 ++ ++#define CMICX_BLOCK_ID_TOP 7 ++#define CMICX_BLOCK_ID_XLPORT7 38 ++ ++ ++#define CMICX_CMD(mode, blk, len) ((mode << SBUSV4_OPCODE_SHIFT) | \ ++ (blk << SBUSV4_BLOCKID_SHIFT) | \ ++ (len << SBUSV4_DLEN_SHIFT)) ++ ++static int __cmicx_schan_write(struct iproc_cmic *cmic, ++ u32 cmd, u32 addr, u32 *val, int len) ++{ ++ u32 read = 0x0; ++ void __iomem *msg_addr; ++ int i; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ msg_addr = CMICX_SCHAN_CH0_MESSAGE(cmic->base); ++ writel(cmd, msg_addr); ++ ++ msg_addr += 4; ++ writel(addr, msg_addr); ++ ++ for (i = 0; i < len; i++) { ++ msg_addr += 4; ++ writel(val[i], msg_addr); ++ } ++ ++ writel(0x1, CMICX_SCHAN_CH0_CTRL(cmic->base)); ++ ++ // FIXME, should set timeout ++ while (read != 0x2) { ++ read = readl(CMICX_SCHAN_CH0_CTRL(cmic->base)); ++ } ++ return read; ++} ++ ++static int __cmicx_schan_read(struct iproc_cmic *cmic, ++ u32 cmd, u32 addr, u32 *val, int len) ++{ ++ u32 read = 0; ++ void __iomem *msg_addr; ++ int i; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ msg_addr = CMICX_SCHAN_CH0_MESSAGE(cmic->base); ++ writel(cmd, msg_addr); ++ ++ msg_addr += 4; ++ writel(addr, msg_addr); ++ ++ writel(0x1, CMICX_SCHAN_CH0_CTRL(cmic->base)); ++ ++ // FIXME, should set timeout ++ while (read != 0x2) { ++ read = readl(CMICX_SCHAN_CH0_CTRL(cmic->base)); ++ } ++ ++ msg_addr = CMICX_SCHAN_CH0_MESSAGE(cmic->base); ++ for (i = 0; i < len; i++) { ++ msg_addr += 4; ++ val[i] = readl(msg_addr); ++ } ++ ++ if (len == 1) ++ return val[0]; ++ else ++ return val[1]; ++} ++ ++static int iproc_cmicx_schan_reg32_write(struct iproc_cmic *cmic, ++ u32 blk_type, u32 addr, u32 val) ++{ ++ u32 cmd, block; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ if (blk_type == CMIC_BLOCK_TYPE_TOP) { ++ block = CMICX_BLOCK_ID_TOP; ++ } else if (blk_type == CMIC_BLOCK_TYPE_APM) { ++ block = CMICX_BLOCK_ID_XLPORT7; } else { ++ return -EINVAL; ++ } ++ ++ cmd = CMICX_CMD(WRITE_REGISTER_CMD_MSG, block, REG32_DATA_LEN); ++ return __cmicx_schan_write(cmic, cmd, addr, &val, 1); ++} ++ ++static u32 iproc_cmicx_schan_reg32_read(struct iproc_cmic *cmic, ++ u32 blk_type, u32 addr) ++{ ++ u32 cmd, block, val; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ if (blk_type == CMIC_BLOCK_TYPE_TOP) { ++ block = CMICX_BLOCK_ID_TOP; ++ } else if (blk_type == CMIC_BLOCK_TYPE_APM) { ++ block = CMICX_BLOCK_ID_XLPORT7; } else { ++ return -EINVAL; ++ } ++ ++ cmd = CMICX_CMD(READ_REGISTER_CMD_MSG, block, REG32_DATA_LEN); ++ return __cmicx_schan_read(cmic, cmd, addr, &val, 1); ++} ++ ++static int iproc_cmicx_schan_reg64_write(struct iproc_cmic *cmic, ++ u32 blk_type, u32 addr, u64 val) ++{ ++ u32 cmd, block; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ if (blk_type == CMIC_BLOCK_TYPE_TOP) { ++ block = CMICX_BLOCK_ID_TOP; ++ } else if (blk_type == CMIC_BLOCK_TYPE_APM) { ++ block = CMICX_BLOCK_ID_XLPORT7; } else { ++ return -EINVAL; ++ } ++ ++ cmd = CMICX_CMD(WRITE_REGISTER_CMD_MSG, block, REG64_DATA_LEN); ++ return __cmicx_schan_write(cmic, cmd, addr, (u32 *)&val, 2); ++} ++ ++static u64 iproc_cmicx_schan_reg64_read(struct iproc_cmic *cmic, ++ u32 blk_type, u32 addr) ++{ ++ u32 cmd, block; ++ u64 val; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ if (blk_type == CMIC_BLOCK_TYPE_TOP) { ++ block = CMICX_BLOCK_ID_TOP; ++ } else if (blk_type == CMIC_BLOCK_TYPE_APM) { ++ block = CMICX_BLOCK_ID_XLPORT7; } else { ++ return -EINVAL; ++ } ++ ++ cmd = CMICX_CMD(READ_REGISTER_CMD_MSG, block, REG64_DATA_LEN); ++ __cmicx_schan_read(cmic, cmd, addr, (u32 *)&val, 2); ++ return val; ++} ++ ++static int iproc_cmicx_schan_ucmem_write(struct iproc_cmic *cmic, ++ u32 blk_type, u32 *mem) ++{ ++ u32 cmd, block; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ if (blk_type == CMIC_BLOCK_TYPE_TOP) { ++ block = CMICX_BLOCK_ID_TOP; ++ } else if (blk_type == CMIC_BLOCK_TYPE_APM) { ++ block = CMICX_BLOCK_ID_XLPORT7; } else { ++ return -EINVAL; ++ } ++ ++ cmd = CMICX_CMD(WRITE_MEMORY_CMD_MSG, block, UCMEM_DATA_LEN); ++ return __cmicx_schan_write(cmic, cmd, CMICX_XLPORT_WC_UCMEM_DATA, mem, 4); ++} ++ ++static int iproc_cmicx_schan_ucmem_read(struct iproc_cmic *cmic, ++ u32 blk_type, u32 *mem) ++{ ++ u32 cmd, block; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ if (blk_type == CMIC_BLOCK_TYPE_TOP) { ++ block = CMICX_BLOCK_ID_TOP; ++ } else if (blk_type == CMIC_BLOCK_TYPE_APM) { ++ block = CMICX_BLOCK_ID_XLPORT7; } else { ++ return -EINVAL; ++ } ++ ++ cmd = CMICX_CMD(READ_MEMORY_CMD_MSG, block, UCMEM_DATA_LEN); ++ return __cmicx_schan_read(cmic, cmd, CMICX_XLPORT_WC_UCMEM_DATA, mem, 2); ++} ++ ++static int iproc_cmicx_init(struct iproc_cmic *cmic) ++{ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ /* ++ * SBUS ring and block number: ++ * ring 5: TOP(7) ++ * ring 7: XLPORT7(38) ++ */ ++ writel(0x52222100, CMICX_TOP_SBUS_RING_MAP_0_7(cmic->base)); ++ writel(0x07500066, CMICX_TOP_SBUS_RING_MAP_32_39(cmic->base)); ++ writel(0x5000, CMICX_TOP_SBUS_TIMEOUT(cmic->base)); ++ ++ return 0; ++} ++ ++const struct sbus_ops cmicx_sbus_ops = { ++ .init = iproc_cmicx_init, ++ .reg32_write = iproc_cmicx_schan_reg32_write, ++ .reg32_read = iproc_cmicx_schan_reg32_read, ++ .reg64_write = iproc_cmicx_schan_reg64_write, ++ .reg64_read = iproc_cmicx_schan_reg64_read, ++ .ucmem_write = iproc_cmicx_schan_ucmem_write, ++ .ucmem_read = iproc_cmicx_schan_ucmem_read, ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/xgs_iproc/xgs-iproc-idm.c b/drivers/soc/bcm/xgs_iproc/xgs-iproc-idm.c +--- a/drivers/soc/bcm/xgs_iproc/xgs-iproc-idm.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/xgs_iproc/xgs-iproc-idm.c 2018-05-10 11:31:33.017403314 +0800 +@@ -0,0 +1,309 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define IPROC_IDM_COMPATIBLE "brcm,iproc-idm" ++ ++#define IDM_ERROR_LOG_ENABLE 0x33A ++#define IDM_ERROR_LOG_CLEAR 0x3 ++ ++#define IDM_ERROR_LOG_CONTROL_REG(base) (base + 0x900) ++#define IDM_ERROR_LOG_COMPLETE_REG(base) (base + 0x904) ++#define IDM_ERROR_LOG_STATUS_REG(base) (base + 0x908) ++#define IDM_ERROR_LOG_ADDR_LSB_REG(base) (base + 0x90c) ++#define IDM_ERROR_LOG_ID_REG(base) (base + 0x914) ++#define IDM_ERROR_LOG_FLAGS_REG(base) (base + 0x91c) ++#define IDM_INTERRUPT_STATUS_REG(base) (base + 0xa00) ++ ++enum support_dev_ids { ++ XGS_IPROC_HX4 = 0, ++ XGS_IPROC_KT2, ++ XGS_IPROC_HR2, ++ XGS_IPROC_GH, ++ XGS_IPROC_SB2, ++ XGS_IPROC_HR3, ++ XGS_IPROC_GH2, ++ XGS_IPROC_WH2, ++ XGS_IPROC_HX5, ++ XGS_IPROC_MAX_DEVS, ++}; ++ ++static struct xgs_iproc_dev_infos_s { ++ char dt_compat_str[32]; ++ u32 dev_id; ++ u32 dmac_reset_offset; ++} xgs_iproc_dev_infos[] = { ++ { "brcm,helix4", XGS_IPROC_HX4, 0x14800 }, ++ { "brcm,katana2", XGS_IPROC_KT2, 0x14800 }, ++ { "brcm,hurricane2", XGS_IPROC_HR2, 0x14800 }, ++ { "brcm,greyhound", XGS_IPROC_GH, 0x14800 }, ++ { "brcm,saber2", XGS_IPROC_SB2, 0xf800 }, ++ { "brcm,hurricane3", XGS_IPROC_HR3, 0xf800 }, ++ { "brcm,greyhound2", XGS_IPROC_GH2, 0xf800 }, ++ { "brcm,wolfhound2", XGS_IPROC_WH2, 0xf800 }, ++ { "brcm,helix5", XGS_IPROC_HX5, 0x10800 }, ++ { "", 0, 0 } ++}; ++ ++#define IDM_BASE_ADDR_NUM 2 ++#define IDM_BASE_ADDR_MASK 0x10000000 ++#define IDM_BASE_ADDR_AREA(val) ((val & IDM_BASE_ADDR_MASK) >> 28) ++#define IDM_OFFSET_MASK 0x0FFFFFFF ++ ++static struct xgs_iproc_idm_err_offset_s { ++ u32 ihost_s1[XGS_IPROC_MAX_DEVS]; ++ u32 ihost_s0[XGS_IPROC_MAX_DEVS]; ++ u32 axi_pcie_s0[XGS_IPROC_MAX_DEVS]; ++ u32 ddr_s1[XGS_IPROC_MAX_DEVS]; ++ u32 ddr_s2[XGS_IPROC_MAX_DEVS]; ++ u32 cmic_s0[XGS_IPROC_MAX_DEVS]; ++ u32 apby_s0[XGS_IPROC_MAX_DEVS]; ++ u32 rom_s0[XGS_IPROC_MAX_DEVS]; ++ u32 nand_idm[XGS_IPROC_MAX_DEVS]; ++ u32 qspi_idm[XGS_IPROC_MAX_DEVS]; ++ u32 a9jtag_s0[XGS_IPROC_MAX_DEVS]; ++ u32 sram_s0[XGS_IPROC_MAX_DEVS]; ++ u32 apbz_s0[XGS_IPROC_MAX_DEVS]; ++ u32 axiic_ds_3[XGS_IPROC_MAX_DEVS]; ++ u32 apbw_idm[XGS_IPROC_MAX_DEVS]; ++ u32 apbx_idm[XGS_IPROC_MAX_DEVS]; ++ u32 axiic_ds_0[XGS_IPROC_MAX_DEVS]; ++ u32 periph_s0[XGS_IPROC_MAX_DEVS]; ++ u32 genres_s0[XGS_IPROC_MAX_DEVS]; ++} xgs_iproc_idm_err_offset = { ++ /* HX4, KT2, HR2, GH, SB2, HR3, ++ GH2, WH2, HX5 */ ++ { 0x00007000, 0x00007000, 0x00007000, 0x00006000, 0x00006000, 0x00006000, ++ 0x00006000, 0x00006000, 0x0 }, /* IHOST_S1_IDM */ ++ { 0x00008000, 0x00008000, 0x00008000, 0x00007000, 0x00007000, 0x00007000, ++ 0x00007000, 0x00007000, 0x00014000 }, /* IHOST_S0_IDM */ ++ { 0x0000b000, 0x0000b000, 0x0000b000, 0x00008000, 0x00008000, 0x00008000, ++ 0x00008000, 0x00008000, 0x0000a000 }, /* AXI_PCIE_S0_IDM */ ++ { 0x00009000, 0x00009000, 0x00009000, 0x10002000, 0x10002000, 0x00004000, ++ 0x10002000, 0x00004000, 0x0001a000 }, /* DDR_S1_IDM */ ++ { 0x0000a000, 0x0000a000, 0x0000a000, 0x10003000, 0x10003000, 0x00005000, ++ 0x10003000, 0x00005000, 0x0001b000 }, /* DDR_S2_IDM */ ++ { 0x0000d000, 0x0000d000, 0x0000d000, 0x0000a000, 0x0000a000, 0x0000a000, ++ 0x0000a000, 0x0000a000, 0x0000b000 }, /* CMICD_S0_IDM */ ++ { 0x0000f000, 0x0000f000, 0x0000f000, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0000c000 }, /* APBY_S0_IDM */ ++ { 0x0001a000, 0x0001a000, 0x0001a000, 0x10004000, 0x10004000, 0x0001a000, ++ 0x10004000, 0x0001a000, 0x0 }, /* ROM_S0_IDM */ ++ { 0x0001b000, 0x0001b000, 0x0001b000, 0x10005000, 0x10005000, 0x0001d000, ++ 0x10005000, 0x0001d000, 0x0 }, /* NAND_IDM */ ++ { 0x0001c000, 0x0001c000, 0x0001c000, 0x10006000, 0x10006000, 0x0001f000, ++ 0x10006000, 0x0001f000, 0x0 }, /* QSPI_IDM */ ++ { 0x0001d000, 0x0001d000, 0x0001d000, 0x00019000, 0x00019000, 0x00019000, ++ 0x00019000, 0x00019000, 0x0 }, /* A9JTAG_S0_IDM */ ++ { 0x00020000, 0x00020000, 0x00020000, 0x0001b000, 0x0001b000, 0x0, ++ 0x0001b000, 0x0, 0x0 }, /* SRAM_S0_IDM */ ++ { 0x00021000, 0x00021000, 0x00021000, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x00017000 }, /* APBZ_S0_IDM */ ++ { 0x00023000, 0x00023000, 0x00023000, 0x0001e000, 0x0001e000, 0x0, ++ 0x0001e000, 0x0, 0x0 }, /* AXIIC_DS_3_IDM */ ++ { 0x00031000, 0x00031000, 0x00031000, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0 }, /* APBW_IDM */ ++ { 0x00032000, 0x00032000, 0x00032000, 0x00030000, 0x00030000, 0x00030000, ++ 0x00030000, 0x00030000, 0x0 }, /* APBX_IDM */ ++ { 0x00041000, 0x00041000, 0x00041000, 0x00020000, 0x00020000, 0x00020000, ++ 0x00020000, 0x00020000, 0x00053000 }, /* AXIIC_DS_0_IDM */ ++ { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x00018000 }, /* PERIPH_S0_IDM */ ++ { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x00019000 }, /* GENRES_S0_IDM */ ++}; ++ ++struct xgs_iproc_idm { ++ u32 curr_dev; ++ void __iomem *idm_base[IDM_BASE_ADDR_NUM]; ++ u32 dmac_reset_offset; ++}; ++ ++static struct xgs_iproc_idm xgs_iproc_idm = { 0 }; ++ ++/********************************************************************************** ++***********************************************************************************/ ++void inline __iomem *get_iproc_idm_base(int idx) ++{ ++ if (idx >= IDM_BASE_ADDR_NUM) ++ return NULL; ++ ++ return xgs_iproc_idm.idm_base[idx]; ++} ++ ++int xgs_iproc_idm_dmac_reset(void) ++{ ++ void __iomem *reset_base = NULL; ++ ++ if (xgs_iproc_idm.idm_base[0] == NULL || ++ xgs_iproc_idm.dmac_reset_offset == 0) { ++ return -EINVAL; ++ } ++ ++ reset_base = xgs_iproc_idm.idm_base[0] + xgs_iproc_idm.dmac_reset_offset; ++ writel(readl(reset_base) & ~0x1, reset_base); ++ ++ return 0; ++} ++ ++static int idm_error_log_dump(void __iomem *idm_addr) ++{ ++ void __iomem *reg_addr; ++ u32 val; ++ ++ reg_addr = (void __iomem *)IDM_ERROR_LOG_STATUS_REG(idm_addr); ++ if ((val = readl(reg_addr)) > 0) { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, val); ++ ++ reg_addr = (void __iomem *)IDM_ERROR_LOG_ADDR_LSB_REG(idm_addr); ++ val = readl(reg_addr); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, val); ++ ++ reg_addr = (void __iomem *)IDM_ERROR_LOG_ID_REG(idm_addr); ++ val = readl(reg_addr); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, val); ++ ++ reg_addr = (void __iomem *)IDM_ERROR_LOG_FLAGS_REG(idm_addr); ++ val = readl(reg_addr); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, val); ++ ++ reg_addr = (void __iomem *)IDM_ERROR_LOG_COMPLETE_REG(idm_addr); ++ writel(IDM_ERROR_LOG_CLEAR, reg_addr); ++ ++ reg_addr = (void __iomem *)IDM_ERROR_LOG_STATUS_REG(idm_addr); ++ val = readl(reg_addr); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, val); ++ } ++ ++ return 0; ++} ++ ++static irqreturn_t idm_timeout_handler(int val, void *ptr) ++{ ++ u32 idx, offset; ++ void __iomem *idm_addr; ++ u32 i, cnt, *idm_item; ++ ++ if (xgs_iproc_idm.curr_dev == XGS_IPROC_MAX_DEVS) ++ return IRQ_HANDLED; ++ ++ cnt = sizeof(struct xgs_iproc_idm_err_offset_s) / (sizeof(u32) * XGS_IPROC_MAX_DEVS); ++ for (i = 0; i < cnt; i++) { ++ idm_item = (u32*)((u32*)(&xgs_iproc_idm_err_offset) + i * XGS_IPROC_MAX_DEVS); ++ offset = idm_item[xgs_iproc_idm.curr_dev]; ++ if (offset != 0) { ++ idx = IDM_BASE_ADDR_AREA(offset); ++ if (xgs_iproc_idm.idm_base[idx]) { ++ idm_addr = xgs_iproc_idm.idm_base[idx] + (offset & IDM_OFFSET_MASK); ++ idm_error_log_dump(idm_addr); ++ } ++ } ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static int init_request_idm_timeout(void) ++{ ++ void __iomem *idm_addr; ++ void __iomem *reg_addr; ++ u32 i, cnt, *idm_item; ++ u32 idx, offset; ++ ++ if (xgs_iproc_idm.curr_dev == XGS_IPROC_MAX_DEVS) ++ return IRQ_HANDLED; ++ ++ /* clear all pending idm interrupts */ ++ idm_timeout_handler(0, NULL); ++ ++ /* enable idm error log for all slaves */ ++ cnt = sizeof(struct xgs_iproc_idm_err_offset_s) / (sizeof(u32) * XGS_IPROC_MAX_DEVS); ++ for (i = 0; i < cnt; i++) { ++ idm_item = (u32*)((u32*)(&xgs_iproc_idm_err_offset) + i * XGS_IPROC_MAX_DEVS); ++ offset = idm_item[xgs_iproc_idm.curr_dev]; ++ if (offset != 0) { ++ idx = IDM_BASE_ADDR_AREA(offset); ++ if (xgs_iproc_idm.idm_base[idx]) { ++ idm_addr = xgs_iproc_idm.idm_base[idx] + (offset & IDM_OFFSET_MASK); ++ reg_addr = (void __iomem *)IDM_ERROR_LOG_CONTROL_REG(idm_addr); ++ writel(IDM_ERROR_LOG_ENABLE, reg_addr); ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++int xgs_iproc_idm_init(void) ++{ ++ struct device_node *np; ++ int idx, ret = 0; ++ int irq, irqs_total; ++ ++ /* Get IDM base addr */ ++ np = of_find_compatible_node(NULL, NULL, IPROC_IDM_COMPATIBLE); ++ if (!np) { ++ pr_err("%s: No IDM node found\n", __func__); ++ return -ENODEV; ++ } ++ ++ xgs_iproc_idm.idm_base[0] = of_iomap(np, 0); ++ if (!xgs_iproc_idm.idm_base[0]) { ++ return -ENOMEM; ++ } ++ ++ /* ++ * Second IDM base addr required for GH/SB2/GH2 IDM timeout handling. ++ * For other devices, the second IDM base addr is not used. So, it is ++ * fine even the addr is NULL. ++ */ ++ xgs_iproc_idm.idm_base[1] = of_iomap(np, 1); ++ ++ /* Get the current platform */ ++ idx = 0; ++ while(1) { ++ if (strlen(xgs_iproc_dev_infos[idx].dt_compat_str) == 0) ++ return -EINVAL; ++ if (of_machine_is_compatible(xgs_iproc_dev_infos[idx].dt_compat_str)) ++ break; ++ idx++; ++ } ++ xgs_iproc_idm.curr_dev = xgs_iproc_dev_infos[idx].dev_id; ++ xgs_iproc_idm.dmac_reset_offset = xgs_iproc_dev_infos[idx].dmac_reset_offset; ++ ++ /* Setup idm timeout handler for debug purpose */ ++ init_request_idm_timeout(); ++ ++ irqs_total = of_irq_count(np); ++ if (!irqs_total) ++ return -EINVAL; ++ ++ for (idx = 0; idx < irqs_total; idx++) { ++ irq = of_irq_get(np, idx); ++ ret = request_irq(irq, (irq_handler_t)idm_timeout_handler, ++ IRQF_PERCPU, "IDM", NULL); ++ if (ret != 0) ++ printk(KERN_WARNING "%s: request_irq return = %d\n", __func__, ret); ++ } ++ ++ return ret; ++} +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/xgs_iproc/xgs-iproc-misc-setup.c b/drivers/soc/bcm/xgs_iproc/xgs-iproc-misc-setup.c +--- a/drivers/soc/bcm/xgs_iproc/xgs-iproc-misc-setup.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/xgs_iproc/xgs-iproc-misc-setup.c 2018-05-10 11:31:33.017403314 +0800 +@@ -0,0 +1,88 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#define IPROC_DMU_PCU_COMPATIBLE "brcm,iproc-dmu-pcu" ++#define IPROC_WRAP_CTRL_COMPATIBLE "brcm,iproc-wrap-ctrl" ++#define KT2_WRAP_MISC_COMPATIBLE "brcm,kt2-wrap-misc" ++ ++static void __iomem *iproc_dmu_pcu_base = NULL; ++static void __iomem *iproc_wrap_ctrl_base = NULL; ++ ++extern void request_idm_timeout_interrupts(struct platform_device *); ++ ++void inline __iomem *get_iproc_dmu_pcu_base(void) ++{ ++ return iproc_dmu_pcu_base; ++} ++ ++void inline __iomem *get_iproc_wrap_ctrl_base(void) ++{ ++ return iproc_wrap_ctrl_base; ++} ++ ++int inline is_wh2_amac_sgmii(void) ++{ ++ return readl(get_iproc_wrap_ctrl_base() + 0xa8) & 0x04; ++} ++ ++int xgs_iproc_misc_setup(void) ++{ ++ struct device_node *np; ++ void __iomem *wrap_misc_reg = NULL; ++ u32 tmp; ++ u32 wrap_misc_offset, serdes_ctrl_sel, serdes_mdio_sel; ++ ++ /* Get DMU/PCU base addr */ ++ np = of_find_compatible_node(NULL, NULL, IPROC_DMU_PCU_COMPATIBLE); ++ if (!np) { ++ pr_err("%s: No dmu/pcu node found\n", __func__); ++ return -ENODEV ; ++ } ++ ++ iproc_dmu_pcu_base = of_iomap(np, 0); ++ if (!iproc_dmu_pcu_base) ++ return -ENOMEM; ++ ++ /* Get WRAP CTRL base addr */ ++ np = of_find_compatible_node(NULL, NULL, IPROC_WRAP_CTRL_COMPATIBLE); ++ if (!np) { ++ pr_err("%s: No wrap ctrl node found\n", __func__); ++ return -ENODEV; ++ } ++ ++ iproc_wrap_ctrl_base = of_iomap(np, 0); ++ if (!iproc_wrap_ctrl_base) ++ return -ENOMEM; ++ ++ /* Enable AMAC SERDES MDIO SEL/CTRL for HX4/KT2 */ ++ if (!of_property_read_u32_index(np, "amac-serdes-mdio-ctrl-sel", 0, ++ &wrap_misc_offset)) { ++ of_property_read_u32_index(np, "amac-serdes-mdio-ctrl-sel", 1, ++ &serdes_ctrl_sel); ++ of_property_read_u32_index(np, "amac-serdes-mdio-ctrl-sel", 2, ++ &serdes_mdio_sel); ++ ++ wrap_misc_reg = (void __iomem *)(iproc_wrap_ctrl_base + ++ wrap_misc_offset); ++ tmp = readl(wrap_misc_reg); ++ tmp |= (1 << serdes_ctrl_sel) | (1 << serdes_mdio_sel); ++ writel(tmp, wrap_misc_reg); ++ } ++ ++ return 1; ++} +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/xgs_iproc/xgs-iproc.c b/drivers/soc/bcm/xgs_iproc/xgs-iproc.c +--- a/drivers/soc/bcm/xgs_iproc/xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/xgs_iproc/xgs-iproc.c 2018-05-10 11:31:33.021403318 +0800 +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++/* Currently, this driver is only support for Helix5. As for the other ++ * XGS IProc chips, the initial code and reset handler are defined in ++ * mach-iproc/board_bu.c ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define DMU_CRU_RESET_OFFSET 0x200 ++ ++static int xgs_iproc_restart(struct notifier_block *nb, ++ unsigned long action, void *data) ++{ ++ void * __iomem reg_addr; ++ u32 val; ++ ++ /* CRU_RESET register */ ++ reg_addr = get_iproc_dmu_pcu_base() + DMU_CRU_RESET_OFFSET; ++ ++ /* set iproc_reset_n to 0 */ ++ val = readl(reg_addr); ++ val &= ~((u32) 1 << 1); ++ ++ writel(val, reg_addr); ++ ++ /* Wait for reset */ ++ while (1) { ++ cpu_do_idle(); ++ } ++ ++ return 0; ++} ++ ++static struct notifier_block xgs_iproc_nb = { ++ .notifier_call = xgs_iproc_restart, ++ .priority = 192, ++}; ++ ++static char * xgs_iproc_dt_compat_str[] = { ++ "brcm,helix5", ++ "", ++}; ++ ++static int __init xgs_iproc_init(void) ++{ ++ int ret; ++ int idx = 0; ++ ++ while(1) { ++ if (strlen(xgs_iproc_dt_compat_str[idx]) == 0) { ++ return -EINVAL; ++ } ++ if (of_machine_is_compatible(xgs_iproc_dt_compat_str[idx])) { ++ break; ++ } ++ idx++; ++ } ++ ++ ret = xgs_iproc_misc_setup(); ++ if (ret < 0) { ++ return ret; ++ } ++ ++ /* Init idm and setup idm timeout handler for debug purpose */ ++ /* xgs_iproc_idm_init should be init before reset dmac */ ++ ret = xgs_iproc_idm_init(); ++ if (ret < 0) { ++ return ret; ++ } ++ ++ /* FIXME, need confirm whether we need reset the DMAC or not */ ++ xgs_iproc_idm_dmac_reset(); ++ ++ /* Populate platform devices */ ++ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); ++ ++ if (register_reboot_notifier(&xgs_iproc_nb)) { ++ printk("Register reboot handler failed\n"); ++ } ++ ++ return 0; ++} ++arch_initcall(xgs_iproc_init); ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/spi/Kconfig b/drivers/spi/Kconfig +--- a/drivers/spi/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/spi/Kconfig 2018-05-10 11:31:33.033403332 +0800 +@@ -162,8 +162,8 @@ config SPI_BCM63XX_HSSPI + config SPI_BCM_QSPI + tristate "Broadcom BSPI and MSPI controller support" + depends on ARCH_BRCMSTB || ARCH_BCM || ARCH_BCM_IPROC || \ +- BMIPS_GENERIC || COMPILE_TEST +- default ARCH_BCM_IPROC ++ ARCH_XGS_IPROC || BMIPS_GENERIC || COMPILE_TEST ++ default ARCH_BCM_IPROC || ARCH_XGS_IPROC + help + Enables support for the Broadcom SPI flash and MSPI controller. + Select this option for any one of BRCMSTB, iProc NSP and NS2 SoCs +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c +--- a/drivers/spi/spi-bcm-qspi.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/spi/spi-bcm-qspi.c 2018-05-10 11:31:33.033403332 +0800 +@@ -88,7 +88,7 @@ + #define BSPI_BPP_MODE_SELECT_MASK BIT(8) + #define BSPI_BPP_ADDR_SELECT_MASK BIT(16) + +-#define BSPI_READ_LENGTH 512 ++//#define BSPI_READ_LENGTH 512 + + /* MSPI register offsets */ + #define MSPI_SPCR0_LSB 0x000 +@@ -118,6 +118,8 @@ + + #define MSPI_MSPI_STATUS_SPIF BIT(0) + ++#define CRU_CTRL_REG 0x0 ++ + #define INTR_BASE_BIT_SHIFT 0x02 + #define INTR_COUNT 0x07 + +@@ -171,6 +173,7 @@ enum base_type { + MSPI, + BSPI, + CHIP_SELECT, ++ CRU_CTRL, + BASEMAX, + }; + +@@ -195,12 +197,14 @@ struct bcm_qspi_dev_id { + struct qspi_trans { + struct spi_transfer *trans; + int byte; ++ int slots; + bool mspi_last_trans; + }; + + struct bcm_qspi { + struct platform_device *pdev; + struct spi_master *master; ++ struct spi_device *spi_dev; + struct clk *clk; + u32 base_clk; + u32 max_speed_hz; +@@ -453,11 +457,12 @@ static int bcm_qspi_bspi_set_mode(struct + qspi->xfer_mode.flex_mode = true; + + if (!bcm_qspi_bspi_ver_three(qspi)) { +- u32 val, mask; ++ u32 val, mask, endian; + +- val = bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL); ++ val = qspi->s3_strap_override_ctrl; + mask = BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE; +- if (val & mask || qspi->s3_strap_override_ctrl & mask) { ++ endian = BSPI_STRAP_OVERRIDE_CTRL_ENDAIN_MODE; ++ if ((val & mask) && (val & ~(mask | endian))) { + qspi->xfer_mode.flex_mode = false; + bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, 0); + error = bcm_qspi_bspi_set_override(qspi, msg, hp); +@@ -570,6 +575,8 @@ static void bcm_qspi_update_parms(struct + static int bcm_qspi_setup(struct spi_device *spi) + { + struct bcm_qspi_parms *xp; ++ struct bcm_qspi *qspi = spi_master_get_devdata(spi->master); ++ u32 tmp; + + if (spi->bits_per_word > 16) + return -EINVAL; +@@ -581,8 +588,20 @@ static int bcm_qspi_setup(struct spi_dev + return -ENOMEM; + spi_set_ctldata(spi, xp); + } +- xp->speed_hz = spi->max_speed_hz; ++ + xp->mode = spi->mode; ++ xp->speed_hz = spi->max_speed_hz; ++ ++ /* Set BSPI clock rate */ ++ tmp = bcm_qspi_read(qspi, CRU_CTRL, CRU_CTRL_REG); ++ tmp &= ~0x6; ++ if (spi->max_speed_hz >= 62500000) ++ tmp |= 0x6; ++ else if (spi->max_speed_hz >= 50000000) ++ tmp |= 0x2; ++ else if (spi->max_speed_hz >= 31250000) ++ tmp |= 0x4; ++ bcm_qspi_write(qspi, CRU_CTRL, CRU_CTRL_REG, tmp); + + if (spi->bits_per_word) + xp->bits_per_word = spi->bits_per_word; +@@ -674,22 +693,25 @@ static void read_from_hw(struct bcm_qspi + tp = qspi->trans_pos; + + for (slot = 0; slot < slots; slot++) { ++ if (tp.trans->rx_buf) { + if (tp.trans->bits_per_word <= 8) { + u8 *buf = tp.trans->rx_buf; + + if (buf) +- buf[tp.byte] = read_rxram_slot_u8(qspi, slot); ++ buf[tp.byte] = ++ read_rxram_slot_u8(qspi, slot); + dev_dbg(&qspi->pdev->dev, "RD %02x\n", + buf ? buf[tp.byte] : 0xff); + } else { + u16 *buf = tp.trans->rx_buf; + + if (buf) +- buf[tp.byte / 2] = read_rxram_slot_u16(qspi, +- slot); ++ buf[tp.byte / 2] = ++ read_rxram_slot_u16(qspi, slot); + dev_dbg(&qspi->pdev->dev, "RD %04x\n", + buf ? buf[tp.byte] : 0xffff); + } ++ } + + update_qspi_trans_byte_count(qspi, &tp, + TRANS_STATUS_BREAK_NONE); +@@ -767,6 +789,9 @@ static int write_to_hw(struct bcm_qspi * + slot++; + } + ++ /* save slot number for read_from_hw() */ ++ qspi->trans_pos.slots = slot; ++ + if (!slot) { + dev_err(&qspi->pdev->dev, "%s: no data to send?", __func__); + goto done; +@@ -798,9 +823,9 @@ static int bcm_qspi_bspi_flash_read(stru + struct spi_flash_read_message *msg) + { + struct bcm_qspi *qspi = spi_master_get_devdata(spi->master); +- u32 addr = 0, len, rdlen, len_words; ++ u32 addr = 0, len, len_words; + int ret = 0; +- unsigned long timeo = msecs_to_jiffies(100); ++ unsigned long timeo = msecs_to_jiffies(1000); + struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc; + + if (bcm_qspi_bspi_ver_three(qspi)) +@@ -825,30 +850,20 @@ static int bcm_qspi_bspi_flash_read(stru + else + addr = msg->from & 0x00ffffff; + +- if (bcm_qspi_bspi_ver_three(qspi) == true) +- addr = (addr + 0xc00000) & 0xffffff; +- +- /* +- * read into the entire buffer by breaking the reads +- * into RAF buffer read lengths +- */ + len = msg->len; +- qspi->bspi_rf_msg_idx = 0; + +- do { +- if (len > BSPI_READ_LENGTH) +- rdlen = BSPI_READ_LENGTH; +- else +- rdlen = len; ++ if (bcm_qspi_bspi_ver_three(qspi) == true) ++ addr = (addr + 0xc00000) & 0xffffff; + + reinit_completion(&qspi->bspi_done); + bcm_qspi_enable_bspi(qspi); +- len_words = (rdlen + 3) >> 2; ++ len_words = (len + 3) >> 2; + qspi->bspi_rf_msg = msg; + qspi->bspi_rf_msg_status = 0; +- qspi->bspi_rf_msg_len = rdlen; +- dev_dbg(&qspi->pdev->dev, +- "bspi xfr addr 0x%x len 0x%x", addr, rdlen); ++ qspi->bspi_rf_msg_idx = 0; ++ qspi->bspi_rf_msg_len = len; ++ dev_dbg(&qspi->pdev->dev, "bspi xfr addr 0x%x len 0x%x", addr, len); ++ + bcm_qspi_write(qspi, BSPI, BSPI_RAF_START_ADDR, addr); + bcm_qspi_write(qspi, BSPI, BSPI_RAF_NUM_WORDS, len_words); + bcm_qspi_write(qspi, BSPI, BSPI_RAF_WATERMARK, 0); +@@ -867,15 +884,11 @@ static int bcm_qspi_bspi_flash_read(stru + if (!wait_for_completion_timeout(&qspi->bspi_done, timeo)) { + dev_err(&qspi->pdev->dev, "timeout waiting for BSPI\n"); + ret = -ETIMEDOUT; +- break; ++ } else { ++ /* set the return length for the caller */ ++ msg->retlen = len; + } + +- /* set msg return length */ +- msg->retlen += rdlen; +- addr += rdlen; +- len -= rdlen; +- } while (len); +- + return ret; + } + +@@ -884,25 +897,22 @@ static int bcm_qspi_transfer_one(struct + struct spi_transfer *trans) + { + struct bcm_qspi *qspi = spi_master_get_devdata(master); +- int slots; +- unsigned long timeo = msecs_to_jiffies(100); ++ unsigned long timeo = msecs_to_jiffies(1000); + + bcm_qspi_chip_select(qspi, spi->chip_select); + qspi->trans_pos.trans = trans; + qspi->trans_pos.byte = 0; ++ qspi->spi_dev = spi; + +- while (qspi->trans_pos.byte < trans->len) { + reinit_completion(&qspi->mspi_done); + +- slots = write_to_hw(qspi, spi); ++ write_to_hw(qspi, spi); ++ + if (!wait_for_completion_timeout(&qspi->mspi_done, timeo)) { + dev_err(&qspi->pdev->dev, "timeout waiting for MSPI\n"); + return -ETIMEDOUT; + } + +- read_from_hw(qspi, slots); +- } +- + return 0; + } + +@@ -1012,7 +1022,24 @@ static irqreturn_t bcm_qspi_mspi_l2_isr( + bcm_qspi_write(qspi, MSPI, MSPI_MSPI_STATUS, status); + if (qspi->soc_intc) + soc_intc->bcm_qspi_int_ack(soc_intc, MSPI_DONE); ++ ++ if (qspi->trans_pos.trans->tx_buf && ++ (qspi->trans_pos.trans->len <= MSPI_NUM_CDRAM)) { + complete(&qspi->mspi_done); ++ spi_finalize_current_transfer(qspi->master); ++ return IRQ_HANDLED; ++ } ++ ++ read_from_hw(qspi, qspi->trans_pos.slots); ++ ++ if (qspi->trans_pos.trans) { ++ write_to_hw(qspi, qspi->spi_dev); ++ } ++ else { ++ complete(&qspi->mspi_done); ++ spi_finalize_current_transfer(qspi->master); ++ } ++ + return IRQ_HANDLED; + } + +@@ -1031,6 +1058,8 @@ static irqreturn_t bcm_qspi_bspi_lr_l2_i + if (qspi->bspi_rf_msg_len == 0) { + qspi->bspi_rf_msg = NULL; + if (qspi->soc_intc) { ++ /* Ack BSPI done interrupt */ ++ soc_intc->bcm_qspi_int_ack(soc_intc, BSPI_DONE); + /* disable soc BSPI interrupt */ + soc_intc->bcm_qspi_int_set(soc_intc, BSPI_DONE, + false); +@@ -1042,11 +1071,12 @@ static irqreturn_t bcm_qspi_bspi_lr_l2_i + bcm_qspi_bspi_lr_clear(qspi); + else + bcm_qspi_bspi_flush_prefetch_buffers(qspi); +- } +- ++ } else { + if (qspi->soc_intc) +- /* clear soc BSPI interrupt */ +- soc_intc->bcm_qspi_int_ack(soc_intc, BSPI_DONE); ++ /* Ack FIFO full interrupt */ ++ soc_intc->bcm_qspi_int_ack(soc_intc, ++ BSPI_FIFO_FULL); ++ } + } + + status &= INTR_BSPI_LR_SESSION_DONE_MASK; +@@ -1233,8 +1263,6 @@ int bcm_qspi_probe(struct platform_devic + master->dev.of_node = dev->of_node; + master->num_chipselect = NUM_CHIPSELECT; + +- qspi->big_endian = of_device_is_big_endian(dev->of_node); +- + if (!of_property_read_u32(dev->of_node, "num-cs", &val)) + master->num_chipselect = val; + +@@ -1276,6 +1304,26 @@ int bcm_qspi_probe(struct platform_devic + } + } + ++ /* iProc BSPI clock is set through CRU control */ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cru_ctrl"); ++ if (res) { ++ qspi->base[CRU_CTRL] = devm_ioremap_resource(dev, res); ++ if (IS_ERR(qspi->base[CRU_CTRL])) { ++ ret = PTR_ERR(qspi->base[CRU_CTRL]); ++ goto qspi_probe_err; ++ } ++ } ++ ++ qspi->big_endian = of_device_is_big_endian(dev->of_node); ++ ++ val = bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL); ++ if (qspi->big_endian == 0 && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) { ++ val |= BSPI_STRAP_OVERRIDE_CTRL_ENDAIN_MODE; ++ val |= BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE; ++ bcm_qspi_write(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL, val); ++ } ++ qspi->s3_strap_override_ctrl = val; ++ + qspi->dev_ids = kcalloc(num_irqs, sizeof(struct bcm_qspi_dev_id), + GFP_KERNEL); + if (!qspi->dev_ids) { +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/spi/spi-bcm-qspi.h b/drivers/spi/spi-bcm-qspi.h +--- a/drivers/spi/spi-bcm-qspi.h 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/spi/spi-bcm-qspi.h 2018-05-10 11:31:33.033403332 +0800 +@@ -59,7 +59,8 @@ enum { + MSPI_DONE = 0x1, + BSPI_DONE = 0x2, + BSPI_ERR = 0x4, +- MSPI_BSPI_DONE = 0x7 ++ MSPI_BSPI_DONE = 0x7, ++ BSPI_FIFO_FULL = 0x8 + }; + + struct bcm_qspi_soc_intc { +@@ -95,6 +96,8 @@ static inline u32 get_qspi_mask(int type + return INTR_MSPI_DONE_MASK; + case BSPI_DONE: + return BSPI_LR_INTERRUPTS_ALL; ++ case BSPI_FIFO_FULL: ++ return INTR_BSPI_LR_FULLNESS_REACHED_MASK; + case MSPI_BSPI_DONE: + return QSPI_INTERRUPTS_ALL; + case BSPI_ERR: +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/spi/spi-iproc-qspi.c b/drivers/spi/spi-iproc-qspi.c +--- a/drivers/spi/spi-iproc-qspi.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/spi/spi-iproc-qspi.c 2018-05-10 11:31:33.041403341 +0800 +@@ -143,6 +143,7 @@ static int bcm_iproc_remove(struct platf + static const struct of_device_id bcm_iproc_of_match[] = { + { .compatible = "brcm,spi-nsp-qspi" }, + { .compatible = "brcm,spi-ns2-qspi" }, ++ { .compatible = "brcm,spi-xgs-iproc-qspi" }, + {}, + }; + MODULE_DEVICE_TABLE(of, bcm_iproc_of_match); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/legacy/serial.c b/drivers/usb/gadget/legacy/serial.c +--- a/drivers/usb/gadget/legacy/serial.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/gadget/legacy/serial.c 2018-05-10 11:31:33.753404129 +0800 +@@ -250,7 +250,7 @@ static int __init init(void) + */ + if (use_acm) { + serial_config_driver.label = "CDC ACM config"; +- serial_config_driver.bConfigurationValue = 2; ++ serial_config_driver.bConfigurationValue = 1; + device_desc.bDeviceClass = USB_CLASS_COMM; + device_desc.idProduct = + cpu_to_le16(GS_CDC_PRODUCT_ID); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig +--- a/drivers/usb/gadget/udc/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/gadget/udc/Kconfig 2018-05-10 11:31:33.753404129 +0800 +@@ -439,6 +439,17 @@ config USB_GADGET_XILINX + dynamically linked module called "udc-xilinx" and force all + gadget drivers to also be dynamically linked. + ++config USB_XGS_IPROC_UDC ++ tristate "Broadcom XGS IPROC USB Device driver" ++ depends on ARCH_XGS_IPROC && USB_GADGET ++ default n ++ help ++ USB peripheral controller driver for Broadcom XGS IPROC USB 2 device. ++ ++ Say "y" to link the driver statically, or "m" to build a dynamically ++ linked module called "xgs_iproc_udc" and force all gadget drivers to ++ also be dynamically linked. ++ + # + # LAST -- dummy/emulated controller + # +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile +--- a/drivers/usb/gadget/udc/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/gadget/udc/Makefile 2018-05-10 11:31:33.753404129 +0800 +@@ -38,5 +38,6 @@ obj-$(CONFIG_USB_FOTG210_UDC) += fotg210 + obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o + obj-$(CONFIG_USB_GR_UDC) += gr_udc.o + obj-$(CONFIG_USB_GADGET_XILINX) += udc-xilinx.o ++obj-$(CONFIG_USB_XGS_IPROC_UDC) += xgs_iproc_udc.o + obj-$(CONFIG_USB_SNP_UDC_PLAT) += snps_udc_plat.o + obj-$(CONFIG_USB_BDC_UDC) += bdc/ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/bdc/Kconfig b/drivers/usb/gadget/udc/bdc/Kconfig +--- a/drivers/usb/gadget/udc/bdc/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/gadget/udc/bdc/Kconfig 2018-05-10 11:31:33.757404134 +0800 +@@ -16,7 +16,21 @@ comment "Platform Support" + config USB_BDC_PCI + tristate "BDC support for PCIe based platforms" + depends on USB_PCI +- default USB_BDC_UDC ++ default n + help + Enable support for platforms which have BDC connected through PCIe, such as Lego3 FPGA platform. ++ ++config USB_BDC_XGS_IPROC ++ tristate "BDC support for broadcom XGS IPROC platforms" ++ depends on ARCH_XGS_IPROC && USB_GADGET ++ default n ++ ++ help ++ Enable support for Broadcom XGS IPROC platforms which have BDC, such ++ as Helix 5 platform. ++ ++ Say "y" to link the driver statically, or "m" to build a dynamically ++ linked module called "xgs_iproc_udc" and force all gadget drivers to ++ also be dynamically linked. ++ + endif +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/bdc/Makefile b/drivers/usb/gadget/udc/bdc/Makefile +--- a/drivers/usb/gadget/udc/bdc/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/gadget/udc/bdc/Makefile 2018-05-10 11:31:33.757404134 +0800 +@@ -7,3 +7,5 @@ ifneq ($(CONFIG_USB_GADGET_VERBOSE),) + endif + + obj-$(CONFIG_USB_BDC_PCI) += bdc_pci.o ++obj-$(CONFIG_USB_BDC_XGS_IPROC) += bdc_xgs_iproc.o ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/bdc/bdc_xgs_iproc.c b/drivers/usb/gadget/udc/bdc/bdc_xgs_iproc.c +--- a/drivers/usb/gadget/udc/bdc/bdc_xgs_iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/usb/gadget/udc/bdc/bdc_xgs_iproc.c 2018-05-10 11:31:33.761404138 +0800 +@@ -0,0 +1,126 @@ ++/* ++ * bdc_xgs_iproc.c - BDC platform driver for Broadco XGS IPROC platforms. ++ * ++ * Copyright (C) 2014-2016, Broadcom Corporation. All Rights Reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 and ++ * only version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "bdc.h" ++ ++struct bdc_xgs_iproc { ++ struct device *dev; ++ struct platform_device *bdc; ++}; ++ ++static int bdc_xgs_iproc_probe(struct platform_device *pdev) ++{ ++ struct resource res[2]; ++ struct platform_device *bdc; ++ struct bdc_xgs_iproc *data; ++ struct device_node *np = pdev->dev.of_node; ++ int irq; ++ int ret = -ENOMEM; ++ ++ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); ++ if (!data) { ++ return -ENOMEM; ++ } ++ data->dev = &pdev->dev; ++ ++ bdc = platform_device_alloc(BRCM_BDC_NAME, PLATFORM_DEVID_AUTO); ++ if (!bdc) { ++ return -ENOMEM; ++ } ++ ++ memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); ++ ++ if (of_address_to_resource(np, 0, &res[0]) < 0) { ++ dev_err(&pdev->dev, ++ "failed to get BDC registers\n"); ++ of_node_put(np); ++ return -ENXIO; ++ } ++ res[0].name = BRCM_BDC_NAME; ++ res[0].flags = IORESOURCE_MEM; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ dev_err(&pdev->dev, ++ "failed to get BDC IRQ\n"); ++ return -ENXIO; ++ } ++ res[1].start = irq; ++ res[1].name = BRCM_BDC_NAME; ++ res[1].flags = IORESOURCE_IRQ; ++ ++ ret = platform_device_add_resources(bdc, res, ARRAY_SIZE(res)); ++ if (ret) { ++ dev_err(&pdev->dev, ++ "couldn't add resources to bdc device\n"); ++ return ret; ++ } ++ ++ platform_set_drvdata(pdev, data); ++ ++ dma_set_coherent_mask(&bdc->dev, pdev->dev.coherent_dma_mask); ++ bdc->dev.dma_mask = pdev->dev.dma_mask; ++ bdc->dev.dma_parms = pdev->dev.dma_parms; ++ bdc->dev.parent = &pdev->dev; ++ data->bdc = bdc; ++ ++ ret = platform_device_add(bdc); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to register bdc device\n"); ++ platform_device_put(bdc); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int bdc_xgs_iproc_remove(struct platform_device *pdev) ++{ ++ struct bdc_xgs_iproc *data = platform_get_drvdata(pdev); ++ ++ platform_device_unregister(data->bdc); ++ devm_kfree(&pdev->dev, data); ++ ++ return 0; ++} ++ ++static const struct of_device_id bdc_xgs_iproc_ids[] = { ++ { .compatible = "brcm,bdc,hx5", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, bdc_xgs_iproc_ids); ++ ++static struct platform_driver bdc_xgs_iproc_driver = { ++ .probe = bdc_xgs_iproc_probe, ++ .remove = bdc_xgs_iproc_remove, ++ .driver = { ++ .name = "bdc-xgs-iproc", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(bdc_xgs_iproc_ids), ++ }, ++}; ++ ++module_platform_driver(bdc_xgs_iproc_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("BDC platform driver for Broadcom XGS IPROC platforms"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/xgs_iproc_udc.c b/drivers/usb/gadget/udc/xgs_iproc_udc.c +--- a/drivers/usb/gadget/udc/xgs_iproc_udc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/usb/gadget/udc/xgs_iproc_udc.c 2018-05-10 11:31:33.789404169 +0800 +@@ -0,0 +1,2039 @@ ++/* ++ * Copyright 2017 Broadcom Limited ++ * ++ * 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. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++/****************************************************************************/ ++/** ++* @file bcm_dwc_udc.c ++* ++* @brief Broadcom Linux driver for DWC USB 2.0 Device Controller (UDC) ++* ++* This driver implements the Linux Gadget driver API as defined in usb_gadget.h ++* ++* @note ++* ++* This driver was written with the intent of being able to support any ++* variations on how this block is integrated into different Broadcom chips. ++* ++* There is a requirement on how the DWC UDC is configured. In particular, this ++* driver requires that the following options be defined and enabled in the ++* UDC core. ++* ++* UDC20AHB_CNAK_CLR_ENH_CC ++* UDC20AHB_STALL_SET_ENH_CC ++* UDC20AHB_SNAK_ENH_CC ++* ++* Some other UDC attributes can be supported by setting compile time options ++* or with some minor modifications to the source code. Ideally these would ++* be run-time info that is provided by the device instance to the driver. ++* These attributes include the following. ++* ++* IPROC_UDC_EP_CNT ++* IPROC_UDC_EP_MAX_PKG_SIZE ++* Type of each endpoint: Control, IN, OUT, or Bidirectional ++*/ ++/****************************************************************************/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "xgs_iproc_udc.h" ++ ++#define XGS_IPROC_UDC_NAME "xgs-iproc-udc" ++ ++#define DMA_ADDR_INVALID (~(dma_addr_t)0) ++/* ++ * FRAME_NUM_INVALID is used for ISOC IN transfers for frame alignment. ++ * The device specifies the interval at which it wants to do transfers, ++ * but the host initiates all transfers. If the interval is some multiple ++ * number of frames, the device has no idea which frame in an interval ++ * window the host is going to start transfers. This could even be at a ++ * point many frames beyond the current window, as the starting point ++ * can be very application dependant and subject to an indeterminate ++ * amount of latency. ++ */ ++#define FRAME_NUM_INVALID (~(u32)0) ++#define ENOERROR 0 ++ ++/* ---- Private Function Prototypes -------------------------------------- */ ++#ifdef IPROC_UDC_DEBUG ++static void iproc_dbg_dma_dump(struct iproc_udc *udc); ++static void iproc_dbg_dma_dump_desc(char *label, struct iproc_udc_dma_desc *virt, ++ struct iproc_udc_dma_desc *phys); ++static void iproc_dbg_dma_dump_ep(struct iproc_ep *ep); ++#endif /* IPROC_UDC_DEBUG */ ++ ++/* ---- Private Variables ------------------------------------------------ */ ++static const struct { ++ const char *name; ++ const int type; ++ const int msize; ++ const struct usb_ep_caps caps; ++} xgs_iproc_ep_info[] = { ++#define EP_INFO(_name, _type, _size, _caps) \ ++ { \ ++ .name = _name, \ ++ .type = _type, \ ++ .msize = _size, \ ++ .caps = _caps, \ ++ } ++ ++ EP_INFO("ep0", USB_ENDPOINT_XFER_CONTROL, IPROC_UDC_CTRL_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_CONTROL, USB_EP_CAPS_DIR_ALL)), ++ EP_INFO("ep1in", USB_ENDPOINT_XFER_ISOC, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_IN)), ++ EP_INFO("ep2out", USB_ENDPOINT_XFER_ISOC, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_OUT)), ++ EP_INFO("ep3in", USB_ENDPOINT_XFER_BULK, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)), ++ EP_INFO("ep4out", USB_ENDPOINT_XFER_BULK, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)), ++ EP_INFO("ep5in", USB_ENDPOINT_XFER_INT, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN)), ++ EP_INFO("ep6out", USB_ENDPOINT_XFER_INT, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_OUT)), ++#undef EP_INFO ++}; ++ ++/*********************************************************************** ++ * Convenience functions ++ ***********************************************************************/ ++static inline struct iproc_udc *gadget_to_udc(struct usb_gadget *g) ++{ ++ return container_of(g, struct iproc_udc, gadget); ++} ++ ++static inline struct iproc_ep *our_ep(struct usb_ep *ep) ++{ ++ return container_of(ep, struct iproc_ep, usb_ep); ++} ++ ++static inline struct iproc_ep_req *our_req(struct usb_request *req) ++{ ++ return container_of(req, struct iproc_ep_req, usb_req); ++} ++ ++/**************************************************************************** ++ * DMA descriptor chain routines. ++ * ++ * dma_desc_chain_reset - Initialize chain in preparation for transfer ++ * dma_desc_chain_full - Indicates if no descriptors in chain for available for use. ++ * dma_desc_chain_alloc - Get next free descriptor for use. Have to check if chain not full first. ++ * dma_desc_chain_empty - Indicates if no descriptors in the chain are being used. ++ * dma_desc_chain_head - Pointer to 1st entry in chain. Have to check if chain not empty first. ++ * dma_desc_chain_free - Frees up 1st entry for use. Only do this if DMA for this descriptor has completed. ++ * ++ ***************************************************************************/ ++static inline struct iproc_udc_dma_desc *dma_desc_chain_alloc(struct iproc_ep *ep) ++{ ++ u32 idx; ++ ++ idx = ep->dma.add_idx++; ++ ++ return &ep->dma.vir_addr->desc[IPROC_EP_DMA_DESC_IDX(idx)]; ++} ++ ++static inline int dma_desc_chain_empty(struct iproc_ep *ep) ++{ ++ return ep->dma.add_idx == ep->dma.rm_idx; ++} ++ ++static inline void dma_desc_chain_free(struct iproc_ep *ep) ++{ ++ ep->dma.rm_idx++; ++} ++ ++static inline int dma_desc_chain_full(struct iproc_ep *ep) ++{ ++ return (!dma_desc_chain_empty(ep) && (IPROC_EP_DMA_DESC_IDX(ep->dma.add_idx) == IPROC_EP_DMA_DESC_IDX(ep->dma.rm_idx))); ++} ++ ++static inline struct iproc_udc_dma_desc *dma_desc_chain_head(struct iproc_ep *ep) ++{ ++ return (&ep->dma.vir_addr->desc[IPROC_EP_DMA_DESC_IDX(ep->dma.rm_idx)]); ++} ++ ++static inline void dma_desc_chain_reset(struct iproc_ep *ep) ++{ ++ ep->dma.add_idx = 0; ++ ep->dma.rm_idx = 0; ++} ++ ++/**************************************************************************** ++ * ++ * Platform device level alloc / free of memory used for DMA descriptors. ++ * A single block of memory static in size is used for DMA descriptors. ++ * Each endpoint has a small number of descriptors for its exclusive use. ++ * These are chained in a loop. See bcm_udc_dwc.h and iproc_dma_ep_init() ++ * for more details. ++ * ++ ***************************************************************************/ ++static int iproc_platform_dma_alloc(struct platform_device *platformDevP, ++ struct iproc_udc *udc) ++{ ++ udc->dma.vir_addr = dma_alloc_coherent(&platformDevP->dev, ++ sizeof(struct iproc_udc_dma), ++ (dma_addr_t *)&udc->dma.phy_addr, GFP_KERNEL); ++ ++ if (!udc->dma.vir_addr) { ++ dev_err(udc->dev, "dma_alloc_coherent() failed\n"); ++ return -ENOMEM; ++ } ++ ++ return ENOERROR; ++} ++ ++static void iproc_platform_dma_free(struct platform_device *platformDevP, ++ struct iproc_udc *udc) ++{ ++ int idx; ++ ++ dma_free_coherent(&platformDevP->dev, sizeof(struct iproc_udc_dma), ++ udc->dma.vir_addr, (dma_addr_t)udc->dma.phy_addr); ++ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx ++) { ++ if (udc->ep[idx].dma.align_buff) { ++ dma_free_coherent(NULL, udc->ep[idx].dma.align_len, ++ udc->ep[idx].dma.align_buff, ++ udc->ep[idx].dma.align_addr); ++ udc->ep[idx].dma.align_buff = NULL; ++ } ++ } ++} ++ ++/*************************************************************************** ++ * Routines for debug dump of DMA descriptors ++ **************************************************************************/ ++#ifdef IPROC_UDC_DEBUG ++static void iproc_dbg_dma_dump(struct iproc_udc *udc) ++{ ++ int idx; ++ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) ++ iproc_dbg_dma_dump_ep(&udc->ep[idx]); ++} ++ ++static void iproc_dbg_dma_dump_desc(char *label, struct iproc_udc_dma_desc *virt, ++ struct iproc_udc_dma_desc *phys) ++{ ++ printk("%s virt=0x%p phys=0x%p: 0x%08x 0x%08x 0x%08x", ++ label, virt, phys, virt->status, virt->reserved, virt->buf_addr); ++} ++ ++static void iproc_dbg_dma_dump_ep(struct iproc_ep *ep) ++{ ++ int idx; ++ ++ printk("EP %d DMA\n", ep->num); ++ printk(" setup\n"); ++ iproc_dbg_dma_dump_desc(" ", ++ (struct iproc_udc_dma_desc *)&ep->dma.vir_addr->setup, ++ (struct iproc_udc_dma_desc *)&ep->dma.phy_addr->setup); ++ printk(" desc\n"); ++ ++ for (idx = 0; idx < IPROC_EP_DMA_DESC_CNT; idx++) { ++ iproc_dbg_dma_dump_desc(" ", &ep->dma.vir_addr->desc[idx], ++ &ep->dma.phy_addr->desc[idx]); ++ ++ /* Don't bother displaying entries beyond the last. */ ++ if (IPROC_USBD_READ(ep->dma.vir_addr->desc[idx].status) & ++ REG_DMA_STAT_LAST_DESC) ++ break; ++ } ++} ++#endif /* IPROC_UDC_DEBUG */ ++ ++/**************************************************************************** ++ * Initialization of DMA descriptors at the endpoint level. ++ ***************************************************************************/ ++static void iproc_dma_ep_init(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ int idx; ++ ++ /** @todo shorten names to virtAddr physAddr?? */ ++ ep->dma.vir_addr = &udc->dma.vir_addr->ep[ep->num]; ++ ep->dma.phy_addr = &udc->dma.phy_addr->ep[ep->num]; ++ ++ /* ++ * Control endpoints only do setup in the OUT direction, so only need to set the ++ * buffer address for that direction. The buffer is set, even if not a control ++ * endpoint, just to simplify things. There's no harm with this. ++ */ ++ ep->dma.vir_addr->setup.status = cpu_to_le32(REG_DMA_STAT_BUF_HOST_BUSY); ++ wmb(); ++ iproc_usbd_ep_dma_buf_addr_set(udc->usbd_regs, ep->num, USB_DIR_OUT, &ep->dma.phy_addr->setup); ++ ++ /* ++ * Take ownership of the DMA descriptors, and chain them in a loop. This allows a small number ++ * descriptors to be used for requests. Need to have the DWC DMA Descriptor Update option enabled ++ * in the device control register in order to do this. When a transfer for a descriptor completes, ++ * the descriptor will get re-used if there's still data left in a request to transfer. See the ++ * iproc_dma_data_rm_done() and iproc_dma_data_add_ready() routines. ++ */ ++ /** @todo Put these in endpoint context?? */ ++ for (idx = 0; idx < IPROC_EP_DMA_DESC_CNT; idx++) { ++ ep->dma.vir_addr->desc[idx].status = ++ cpu_to_le32(REG_DMA_STAT_BUF_HOST_BUSY); ++ wmb(); ++ ep->dma.vir_addr->desc[idx].next_addr = ++ cpu_to_le32((u32)&ep->dma.phy_addr->desc[idx+1]); ++ } ++ ep->dma.vir_addr->desc[(IPROC_EP_DMA_DESC_CNT - 1)].next_addr = ++ cpu_to_le32((u32)&ep->dma.phy_addr->desc[0]); ++ ++ /* ++ * To simplify things, register the descriptor chain in both directions. Control endpoints are the ++ * only type that will be transferring in both directions, but they will only be transferring in one ++ * direction at a time, so should not be any issues with using the same descriptor set for both directions. ++ * For single direction endpoints, the other direction will not be used. ++ */ ++ ++ iproc_usbd_ep_dma_desc_addr_set(udc->usbd_regs, ep->num, USB_DIR_OUT, ++ &ep->dma.phy_addr->desc[0]); ++ iproc_usbd_ep_dma_desc_addr_set(udc->usbd_regs, ep->num, USB_DIR_IN, ++ &ep->dma.phy_addr->desc[0]); ++} ++ ++/**************************************************************************** ++ * DMA data routines. ++ * ++ * A gadget usb_request buf is used for the data. The entire buf contents may ++ * or may not fit into the descriptor chain at once. When the DMA transfer ++ * associated with a descriptor completes, the descriptor is re-used to add ++ * more segments of the usb_request to the chain as necessary. ++ * ++ * iproc_dma_data_init - Initialization in preparation for DMA of usb_request. ++ * iproc_dma_data_add_ready - Adds usb_request segments into DMA chain until full or no segments left ++ * iproc_dma_data_rm_done - Removes usb_request segments from DMA chain that have completed transfer ++ * iproc_dma_data_finish - Final stage of DMA of the usb_request ++ * ++ ***************************************************************************/ ++static void iproc_dma_data_init(struct iproc_ep *ep) ++{ ++ struct iproc_ep_req *req; ++ struct iproc_udc *udc = ep->udc; ++ ++ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); ++ ++ if (req->dma_aligned) { ++ /* ++ * This buffer needs to be aligned in order to DMA. We do this by copying into a special buffer we ++ * have for this purpose. Save the original DMA physical address so it can be restored later. ++ * This may not be used, but we'll do it anyways. Then set the DMA address to the aligned buffer ++ * address. Only the DMA physical address is used for the transfers, so the original buffer virtual ++ * address does not need to be changed. Then copy the data into the aligned buffer. ++ */ ++ /** @todo Really only need to do the memcpy for IN data */ ++ ++ req->orig_dma_addr = req->usb_req.dma; ++ req->usb_req.dma = ep->dma.align_addr; ++ memcpy(ep->dma.align_buff, req->usb_req.buf, req->usb_req.length); ++ } ++ ++ ep->dma.done = 0; ++ ep->dma.done_len = 0; ++ ep->dma.todo_len = ep->dma.usb_req->length; ++ ep->dma.buf_addr = ep->dma.usb_req->dma; ++ ep->dma.status = REG_DMA_STAT_RX_SUCCESS; ++ ++ if ((ep->dir == USB_DIR_IN) && (ep->type != USB_ENDPOINT_XFER_ISOC)) { ++ /* ++ * For IN transfers, do not need to segment the buffer into max packet portions ++ * for the DMA descriptors. The hardware will automatically segment into max ++ * packet sizes as necessary. ++ */ ++ ep->dma.max_buf_len = ep->usb_ep.maxpacket; ++ ++ /* ++ * If the request is of zero length, then force the zero flag so iproc_dma_data_add_ready() ++ * will queue the request. Conversely, if the gadget has set the zero flag, leave ++ * it set only if it is needed (request length is a multiple of maxpacket) ++ */ ++ if (ep->dma.usb_req->length == 0) ++ ep->dma.usb_req->zero = 1; ++ else if (ep->dma.usb_req->zero) ++ ep->dma.usb_req->zero = ++ (ep->dma.usb_req->length % ep->usb_ep.maxpacket)? 0 : 1; ++ } else { ++ ep->dma.max_buf_len = ep->usb_ep.maxpacket; ++ } ++ ++ dma_desc_chain_reset(ep); ++ ++ iproc_usbd_ep_irq_en(udc->usbd_regs, ep->num, ep->dir); ++} ++ ++static void iproc_dma_data_finish(struct iproc_ep *ep) ++{ ++ struct iproc_ep_req *req; ++ struct iproc_udc *udc = ep->udc; ++ ++ iproc_usbd_ep_irq_dis(udc->usbd_regs, ep->num, ep->dir); ++ iproc_usbd_ep_dma_dis(udc->usbd_regs, ep->num, ep->dir); ++ ++ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); ++ ++ if (req->dma_aligned) { ++ /* ++ * The original request buffer was not aligned properly, so a special buffer was used ++ * for the transfer. Copy the aligned buffer contents into the original. Also restore ++ * the original dma physical address. ++ */ ++ /** @todo Really only need to do the memcpy for OUT setup/data */ ++ memcpy(req->usb_req.buf, ep->dma.align_buff, req->usb_req.length); ++ req->usb_req.dma = req->orig_dma_addr; ++ } ++} ++ ++static void iproc_dma_data_add_ready(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ volatile struct iproc_udc_dma_desc *dma_desc = NULL; ++ u32 status; ++ u32 len; ++ int enable_dma = 0; ++ ++ /* ++ * DMA must be disabled while this loop is running, as multi-descriptor transfers ++ * will have the descriptor chain in an intermediate state until the last descriptor ++ * is written and the chain terminated. ++ */ ++ if (iproc_usbd_dma_status(udc->usbd_regs)) { ++ enable_dma = 1; ++ iproc_usbd_dma_dis(udc->usbd_regs); ++ } ++ ++ if (!ep->dma.todo_len) ++ ep->dma.usb_req->zero = 1; ++ ++ /* ++ * Will only have one request in the chain at a time. Add request segments to the ++ * chain until all parts of the request have been put in the chain or the chain ++ * has no more room. ++ */ ++ while (!dma_desc_chain_full(ep) && (ep->dma.todo_len || ep->dma.usb_req->zero)) { ++ /* ++ * Get the next descriptor in the chain, and then fill the descriptor contents as needed. ++ * Do not set the descriptor buffer status to ready until last to ensure there's no ++ * contention with the hardware. ++ */ ++ dma_desc = dma_desc_chain_alloc(ep); ++ ++ len = ep->dma.todo_len < ep->dma.max_buf_len ? ep->dma.todo_len : ep->dma.max_buf_len; ++ ep->dma.todo_len -= len; ++ ++ status = 0; ++ ++ if (len < ep->dma.max_buf_len) { ++ /* ++ * If this segment is less than the max, then it is the last segment. There's no need to ++ * send a closing ZLP, although this segment might be a ZLP. Regardless, clear the ZLP flag ++ * to ensure that the processing of this request finishes. Also set the end of the descriptor ++ * chain. ++ */ ++ ep->dma.usb_req->zero = 0; ++ status |= REG_DMA_STAT_LAST_DESC; ++ } else if ((ep->dma.todo_len == 0) && !ep->dma.usb_req->zero) { ++ /* ++ * Segment is of the max packet length. Since there's nothing left, it has to also be the last ++ * last segment. No closing ZLP segment requested, just set the end of the descriptor chain. ++ */ ++ status |= REG_DMA_STAT_LAST_DESC; ++ } ++ ++ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC)) { ++ /* ++ * Increment the frame number for transmit, then use it for the next packet. The frame number ++ * may get larger than its 13-bit size, but the mask will handle the wrap-around so we don't ++ * need to add checks for this condition. E.g. 0x7ff + 1 = 0x800. 0x800 & 0x7ff = 0 which ++ * is the next number in the sequence. ++ */ ++ /** @todo Handle ISOC PIDs and frame numbers used with HS high bandwidth transfers */ ++ /** @todo Might not need to set the last descriptor status. Currently restricting ++ * IN ISOC transfers to the max packet size. ++ */ ++ status |= REG_DMA_STAT_LAST_DESC; ++ ++ ep->dma.frame_num += ep->dma.frame_incr; ++ status |= ((ep->dma.frame_num << REG_DMA_STAT_FRAME_NUM_SHIFT) & ++ REG_DMA_STAT_FRAME_NUM_MASK); ++ } ++ ++ IPROC_USBD_WRITE(dma_desc->buf_addr, ep->dma.buf_addr); ++ status |= (len << REG_DMA_STAT_BYTE_CNT_SHIFT); ++ IPROC_USBD_WRITE(dma_desc->status, status | REG_DMA_STAT_BUF_HOST_READY); ++ wmb(); ++ ep->dma.buf_addr += len; ++ ++ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC)) { ++ /* With ISOC transfers, only enable one DMA descriptors at a time. ++ */ ++ /** @todo Determine if FIFO will overflow. If it does not, then can remove this check. ++ * This may not even be an issue if the buffer size is restricted to the max packet size ++ * when a request is submitted to the endpoint. ++ */ ++ break; ++ } ++ } /* while */ ++ ++ /* Set LAST bit on last descriptor we've configured */ ++ if (dma_desc) ++ IPROC_USBD_BITS_SET(dma_desc->status, REG_DMA_STAT_LAST_DESC); ++ ++ if (enable_dma) ++ iproc_usbd_dma_en(udc->usbd_regs); ++} ++ ++static void iproc_dma_data_rm_done(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ volatile struct iproc_udc_dma_desc *dma_desc; ++ u32 status; ++ u32 len; ++ ++ /* ++ * Will only have one request in the chain at a time. Remove any completed ++ * request segments from the chain so any segments awaiting transfer can ++ * be put in the chain. ++ */ ++ while (!dma_desc_chain_empty(ep)) { ++ /* ++ * Examine the first entry in the chain. If its status is not done, then there's ++ * nothing to remove. ++ */ ++ dma_desc = dma_desc_chain_head(ep); ++ ++ if ((IPROC_USBD_READ(dma_desc->status) & REG_DMA_STAT_BUF_MASK) != ++ REG_DMA_STAT_BUF_DMA_DONE) ++ break; ++ ++ /* ++ * The transfer of this request segment has completed. Save the status info and then ++ * take ownership of the descriptor. It is simpler to do this than modifying parts of ++ * the descriptor in order to take ownership. Don't put the descriptor back in the chain ++ * until all info affected by the status has been updated, just to be safe. ++ */ ++ status = IPROC_USBD_READ(dma_desc->status); ++ IPROC_USBD_WRITE(dma_desc->status, REG_DMA_STAT_BUF_HOST_BUSY); ++ wmb(); ++ ++ len = (status & REG_DMA_STAT_NON_ISO_BYTE_CNT_MASK) >> ++ REG_DMA_STAT_NON_ISO_BYTE_CNT_SHIFT; ++ ++ /* RX: For multiple descriptors, len is cumulative, not absolute. ++ * RX: So only adjust the dma fields when we get to the last descriptor ++ * TX: Each descriptor entry is absolute, count them all ++ */ ++ if ((ep->dir == USB_DIR_IN) || (status & REG_DMA_STAT_LAST_DESC)) { ++ ep->dma.done_len += len; ++ ep->dma.usb_req->actual += len; ++ } ++ ++ if ((status & REG_DMA_STAT_RX_MASK) != REG_DMA_STAT_RX_SUCCESS) { ++ ep->dma.status = status & REG_DMA_STAT_RX_MASK; ++ ep->dma.usb_req->status = -EIO; ++ dev_warn(udc->dev, "%s: DMA error: desc=0x%p status=0x%x len=%d add=0x%x remove=0x%x\n", ++ ep->usb_ep.name, dma_desc, status, len, ep->dma.add_idx, ep->dma.rm_idx); ++ } ++ ++ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC)){ ++ /** @todo Determine if this special processing needs to be done. May not to do this if the ++ * buffer size is restricted to the max packet size when a request is submitted to the endpoint. ++ */ ++ if (ep->dma.usb_req->actual == ep->dma.usb_req->length) ++ ep->dma.usb_req->status = ENOERROR; ++ dma_desc_chain_reset(ep); ++ } else { ++ dma_desc_chain_free(ep); ++ } ++ } ++ ++ /* When last segment processed, update status if there has not been an error */ ++ if (!ep->dma.todo_len && (ep->dma.usb_req->status == -EINPROGRESS)) ++ ep->dma.usb_req->status = ENOERROR; ++} ++ ++/**************************************************************************** ++ * Control Endpoint SETUP related routines. ++ * ++ * iproc_ep_setup_init - Prepares for next SETUP Rx. Status indicates if STALL req'd. ++ * iproc_ep_setup_process - Handle Rx of a SETUP. ++ ***************************************************************************/ ++static void iproc_ep_setup_init(struct iproc_ep *ep, int status) ++{ ++ struct iproc_udc *udc = ep->udc; ++ ++ /* Re-enable transfers to the SETUP buffer, clear IN and OUT NAKs, and re-enable OUT interrupts. */ ++ ep->dma.vir_addr->setup.status = cpu_to_le32(REG_DMA_STAT_BUF_HOST_READY); ++ ep->dir = USB_DIR_OUT; ++ ep->stopped = 0; ++ ++ if (status == ENOERROR) { ++ /* Handling of previous SETUP was OK. Just clear any NAKs. */ ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, USB_DIR_OUT); ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, USB_DIR_IN); ++ } else { ++ /* ++ * Handling of previous SETUP failed. Set the STALL. This will get cleared ++ * when the next SETUP is rx'd. ++ */ ++ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, USB_DIR_IN); ++ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, USB_DIR_OUT); ++ } ++ ++ iproc_usbd_ep_irq_en(udc->usbd_regs, ep->num, USB_DIR_OUT); ++ iproc_usbd_ep_dma_en(udc->usbd_regs, ep->num, USB_DIR_OUT); ++} ++ ++void iproc_ep_setup_process(struct iproc_ep *ep, struct usb_ctrlrequest *setup) ++{ ++ struct iproc_udc *udc = ep->udc; ++ u32 value; ++ u32 index; ++ u32 length; ++ int status; ++ ++ value = le16_to_cpu(setup->wValue); ++ index = le16_to_cpu(setup->wIndex); ++ length = le16_to_cpu(setup->wLength); ++ ++ /* ++ * Any SETUP packets appearing here need to be handled by the gadget driver. Some SETUPs may have ++ * already been silently handled and acknowledged by the DWC UDC. The exceptions to this rule are the ++ * USB_REQ_SET_CONFIGURATION and USB_REQ_SET_INTERFACE, which have been only partially handled with ++ * the expectation that some additional software processing is required in order to complete these requests. ++ * Thus, they have not been acknowledged by the DWC UDC. There is no DATA stage for these requests. ++ */ ++ ++ /* ++ * Set the direction of the subsequent DATA stage of a control transfer. This is an ++ * optional stage. It may not exist for all control transfers. If there is a DATA ++ * stage, this info is used for DMA operations for any requests received from the ++ * Gadget driver. ++ */ ++ ++ ep->dir = setup->bRequestType & USB_ENDPOINT_DIR_MASK; ++ ++ if (ep->num != 0) { ++ /** @todo Make changes here if the Linux USB gadget ever supports a control endpoint other ++ * than endpoint 0. The DWC UDC supports multiple control endpoints, and this driver has ++ * been written with this in mind. To make things work, really need to change the Gadget ++ * setup() callback parameters to provide an endpoint context, or add something similar ++ * to the usb_ep structure, or possibly use a usb_request to hold a setup data packet. ++ */ ++ dev_err(udc->dev, "%s: control transfer not supported\n", ep->usb_ep.name); ++ status = -EOPNOTSUPP; ++ } else { ++ /* ++ * Forward the SETUP to the gadget driver for processing. The appropriate directional ++ * interrupt and NAK clear will happen when the DATA stage request is queued. ++ */ ++ spin_unlock(&udc->lock); ++ status = udc->gadget_driver->setup(&udc->gadget, setup); ++ spin_lock(&udc->lock); ++ } ++ ++ if (status < 0) { ++ /* ++ * Error occurred during the processing of the SETUP, so enable STALL. This condition ++ * can only be cleared with the RX of another SETUP, so prepare for that event. ++ */ ++ dev_err(udc->dev, "%s: SETUP %02x.%02x STALL; status=%d\n", ++ ep->usb_ep.name, setup->bRequestType, setup->bRequest, status); ++ ++ iproc_ep_setup_init(ep, status); ++ } else if (length == 0) { ++ /* No DATA stage. Just need to prepare for the next SETUP. */ ++ iproc_ep_setup_init(ep, ENOERROR); ++ } else { ++ /* ++ * The SETUP stage processing has completed OK, and there may or may not be a request queued ++ * for the DATA stage. When the DATA stage completes, preparation for the RX of the next ++ * SETUP will be done. ++ */ ++ } ++} ++ ++static void iproc_udc_req_xfer_done(struct iproc_ep *ep, struct iproc_ep_req *req, int status) ++{ ++ struct iproc_udc *udc = ep->udc; ++ u32 stopped; ++ ++ list_del_init(&req->list_node); ++ ++ if (req->usb_req.status == -EINPROGRESS) ++ req->usb_req.status = status; ++ ++ if (req->dma_aligned) { ++ req->dma_aligned = 0; ++ } else if (req->dma_mapped) { ++ /* ++ * A physical address was not provided for the DMA buffer. Release any resources ++ * that were requested by the driver. ++ */ ++ dma_unmap_single(udc->gadget.dev.parent, req->usb_req.dma, req->usb_req.length, ++ (ep->dir == USB_DIR_IN ? DMA_TO_DEVICE : DMA_FROM_DEVICE)); ++ ++ req->dma_mapped = 0; ++ req->usb_req.dma = DMA_ADDR_INVALID; ++ } ++ ++ /* ++ * Disable DMA operations during completion callback. The callback may cause requests to be ++ * added to the queue, but we don't want to change the state of the queue head. ++ */ ++ stopped = ep->stopped; ++ ep->stopped = 1; ++ spin_unlock(&udc->lock); ++ req->usb_req.complete(&ep->usb_ep, &req->usb_req); ++ spin_lock(&udc->lock); ++ ep->stopped = stopped; ++} ++ ++static void iproc_udc_req_xfer_process(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ struct iproc_ep_req *req; ++ ++ /* @todo Current transfer is always the queue head. ++ * Do we need a separate pointer? Maybe just a pointer to usb_request ++ */ ++ if (!ep->dma.usb_req) { ++ dev_err(udc->dev, "%s: No request being transferred\n", ep->usb_ep.name); ++ return; ++ } ++ ++ iproc_usbd_ep_dma_dis(udc->usbd_regs, ep->num, ep->dir); ++ iproc_dma_data_rm_done(ep); ++ ++ if (ep->dma.usb_req->status != -EINPROGRESS) { ++ /* ++ * Current transfer stage has finished. This may or may not be with error. ++ * Complete the transfer as needed before starting the next one, if any. ++ */ ++ iproc_dma_data_finish(ep); ++ ++ if ((ep->type == USB_ENDPOINT_XFER_CONTROL) && (ep->dir == USB_DIR_IN) ++ && (ep->dma.usb_req->status == ENOERROR)) { ++ /* ++ * For the status phase of control IN transfers, the hardware requires that an OUT DMA transfer ++ * actually takes place. This should be just an OUT ZLP, and we will re-use the IN buffer that ++ * just completed transfer for this purpose. There should be no harm in doing this, even if the ++ * OUT status is more than a ZLP. ++ */ ++ ep->dir = USB_DIR_OUT; ++ iproc_dma_data_init(ep); ++ } else { ++ /* ++ * All transfer stages have completed. Return the request to the gadget driver, and then ++ * setup for the next transfer. ++ */ ++ iproc_udc_req_xfer_done(ep, list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node), ENOERROR); ++ ++ if (ep->type == USB_ENDPOINT_XFER_CONTROL) ++ iproc_ep_setup_init(ep, ENOERROR); ++ ++ if (list_empty(&ep->list_queue)) { ++ /** @todo Probably should more closely bind this to iproc_dma_data_finish. */ ++ ep->dma.usb_req = NULL; ++ } else { ++ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); ++ ep->dma.usb_req = &req->usb_req; ++ iproc_dma_data_init(ep); ++ } ++ } ++ } ++ ++ if (ep->dma.usb_req != NULL) { ++ iproc_dma_data_add_ready(ep); ++ iproc_usbd_ep_dma_en(udc->usbd_regs, ep->num, ep->dir); ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, ep->dir); ++ } ++} ++ ++static void iproc_udc_req_xfer_error(struct iproc_ep *ep, int status) ++{ ++ struct iproc_udc *udc = ep->udc; ++ ++ if (!ep->dma.usb_req) { ++ dev_err(udc->dev, "%s: No request being transferred\n", ep->usb_ep.name); ++ return; ++ } ++ ++ /** @todo abort current DMA, start next transfer if there is one. */ ++ ep->dma.usb_req->status = status; ++ iproc_udc_req_xfer_process(ep); ++} ++ ++static void iproc_udc_ops_disconnect(struct iproc_udc *udc) ++{ ++ struct iproc_ep *ep; ++ int idx; ++ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { ++ ep = &udc->ep[idx]; ++ ++ if (ep->dma.usb_req) { ++ /* Flush DMA, reqeust still pending */ ++ iproc_usbd_ep_fifo_flush_en(udc->usbd_regs, 0, USB_DIR_IN); ++ iproc_usbd_ep_fifo_flush_dis(udc->usbd_regs, 0, USB_DIR_IN); ++ ++ iproc_udc_req_xfer_process(ep); ++ } ++ } ++} ++ ++static void iproc_udc_ops_shutdown(struct iproc_udc *udc) ++{ ++ struct iproc_ep *ep; ++ ++ udc->ep[0].desc = NULL; ++ list_for_each_entry(ep, &udc->gadget.ep_list, usb_ep.ep_list) ++ ep->desc = NULL; ++ ++ udc->gadget.dev.driver = NULL; ++ udc->gadget_driver = NULL; ++} ++ ++/**************************************************************************** ++ * IRQ routines. ++ * ++ * xgs_iproc_udc_isr - top level entry point. ++ * iproc_cfg_isr - device (endpoint 0) set config interrupt handler ++ * iproc_inf_isr - device (endpoint 0) set interface interrupt handler ++ * iproc_speed_isr - device speed enumeration done interrupt handler ++ * iproc_ep_in_isr - top level IN endpoint related interrupt handler ++ * iproc_ep_out_isr - top level OUT endpoint related interrupt handler ++ * iproc_ep_out_setup_isr - Control endpoint SETUP Rx handler. This may get ++ * called directly as the result of an endpoint OUT interrupt, or ++ * indirectly as the result of device SET_CFG or SET_INTF. ++ ***************************************************************************/ ++static void iproc_cfg_isr(struct iproc_udc *udc) ++{ ++ struct usb_ctrlrequest setup; ++ int idx; ++ u16 cfg; ++ ++ /* ++ * Device Configuration SETUP has been received. This is not placed in the SETUP ++ * DMA buffer. The packet has to be re-created here so it can be forwarded to the ++ * gadget driver to act upon. ++ */ ++ ++ cfg = (u16) iproc_usbd_cfg_num(udc->usbd_regs); ++ ++ setup.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE; ++ setup.bRequest = USB_REQ_SET_CONFIGURATION; ++ setup.wValue = cpu_to_le16(cfg); ++ setup.wIndex = 0; ++ setup.wLength = 0; ++ ++ /* ++ * Setting the configuration number before the gadget responds is a bit presumptious, but should ++ * not be fatal. ++ */ ++ /** @todo Do not set endpoint 0? Or is it a don't care? */ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) ++ iproc_usbd_ep_cfg_set(udc->usbd_regs, idx, cfg); ++ ++ printk(KERN_INFO "SET CFG=%d\n", cfg); ++ ++ iproc_ep_setup_process(&udc->ep[0], &setup); ++ iproc_usbd_setup_done(udc->usbd_regs); ++} ++ ++static void iproc_inf_isr(struct iproc_udc *udc) ++{ ++ struct usb_ctrlrequest setup; ++ u32 idx; ++ u16 intf; ++ u16 alt; ++ ++ /* ++ * Device Interface SETUP has been received. This is not placed in the SETUP ++ * DMA buffer. The packet has to be re-created here so it can be forwarded to the ++ * gadget driver to act upon. ++ */ ++ intf = (u16)iproc_usbd_intf_num(udc->usbd_regs); ++ alt = (u16)iproc_usbd_alt_num(udc->usbd_regs); ++ ++ setup.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_INTERFACE; ++ setup.bRequest = USB_REQ_SET_INTERFACE; ++ setup.wValue = cpu_to_le16(alt); ++ setup.wIndex = cpu_to_le16(intf); ++ setup.wLength = 0; ++ ++ /* ++ * Setting the interface numbers before the gadget responds is a bit ++ * presumptious, but should not be fatal. ++ */ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { ++ iproc_usbd_ep_alt_set(udc->usbd_regs, idx, alt); ++ iproc_usbd_ep_intf_set(udc->usbd_regs, idx, intf); ++ } ++ ++ iproc_ep_setup_process(&udc->ep[0], &setup); ++ iproc_usbd_setup_done(udc->usbd_regs); ++} ++ ++static void iproc_speed_isr(struct iproc_udc *udc) ++{ ++ u32 speed; ++ ++ speed = udc->gadget.speed; ++ ++ switch(iproc_usbd_speed_get(udc->usbd_regs)) { ++ case USB_SPEED_HIGH: ++ printk(KERN_INFO "HIGH SPEED\n"); ++ udc->gadget.speed = USB_SPEED_HIGH; ++ break; ++ case USB_SPEED_FULL: ++ printk(KERN_INFO "FULL SPEED\n"); ++ udc->gadget.speed = USB_SPEED_FULL; ++ break; ++ case USB_SPEED_LOW: ++ dev_warn(udc->dev, "low speed not supported\n"); ++ udc->gadget.speed = USB_SPEED_LOW; ++ break; ++ default: ++ dev_err(udc->dev, "unknown speed=0x%x\n", iproc_usbd_speed_get(udc->usbd_regs)); ++ break; ++ } ++ ++ if ((speed == USB_SPEED_UNKNOWN) && (udc->gadget.speed != USB_SPEED_UNKNOWN)) { ++ /* ++ * Speed has not been enumerated before, so now we can initialize transfers on endpoint 0. ++ * Also have to disable the NAKs at a global level, which has been in place while waiting ++ * for enumeration to complete. ++ */ ++ iproc_ep_setup_init(&udc->ep[0], ENOERROR); ++ iproc_usbd_nak_response_dis(udc->usbd_regs); ++ } ++} ++ ++static void iproc_ep_in_isr(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ u32 status; ++ ++ status = iproc_usbd_ep_stat_active(udc->usbd_regs, ep->num, USB_DIR_IN); ++ iproc_usbd_ep_stat_clear(udc->usbd_regs, ep->num, USB_DIR_IN, status); ++ ++ if (!status) ++ return; ++ ++ /** @todo check might only be for direction... */ ++ if ((ep->dir != USB_DIR_IN) && (ep->type != USB_ENDPOINT_XFER_CONTROL)) { ++ dev_err(udc->dev, "%s: unexpected IN interrupt\n", ep->usb_ep.name); ++ return; ++ } ++ ++ if (ep->dir != USB_DIR_IN) ++ /* This probably should not be happening */ ++ dev_warn(udc->dev, "%s: CTRL dir OUT\n", ep->usb_ep.name); ++ ++ if ((ep->type == USB_ENDPOINT_XFER_ISOC) && ++ (status & (USBD_EP_STAT_IN_XFER_DONE | USBD_EP_STAT_DMA_BUF_UNAVAIL))) ++ dev_warn(udc->dev, "%s: ISOC IN unexpected status=0x%x\n", ep->usb_ep.name, status); ++ ++ if (status & USBD_EP_STAT_IN_TOKEN_RX) { ++ /* ++ * If there's any IN requests, the DMA should be setup and ready to go if ++ * the endpoint is not an ISOC. Nothing to do in this case. However, if ++ * this is an ISOC endpoint, then this interrupt implies there was no ++ * data available for this frame number. This will happen if the gadget ++ * does not have any data queued to send in this frame, or we have been ++ * waiting for this event to occur so we can get alignment with the host ++ * for the interval. This alignment is necessary when the interval is ++ * greater than one frame / uframe. E.g. for an audio stream sending ++ * samples @ 5ms intervals on a FS link, this corresponds to a period ++ * of 5 frames. Samples with be queued for every 5th frame number after ++ * the frame number in which this interrupt occurred. ++ */ ++ status &= ~USBD_EP_STAT_IN_TOKEN_RX; ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, USB_DIR_IN); ++ ++ if ((ep->type == USB_ENDPOINT_XFER_ISOC)) { ++ /* Always align to the current frame number for subsequent transfers. */ ++ ep->dma.frame_num = iproc_usbd_last_rx_frame_num(udc->usbd_regs); ++ if (ep->dma.usb_req != NULL) { ++ /* ++ * Might have something queued when waiting for alignment. If something is queued, ++ * it is already too late for the current transfer point. It will also have been ++ * placed in the queue at some point before this interrupt, and it will be stale ++ * if we try to transmit at the next transfer point. ++ */ ++ ep->dma.usb_req->status = -EREMOTEIO; ++ iproc_udc_req_xfer_process(ep); ++ } ++ } ++ } ++ ++ if (status & USBD_EP_STAT_IN_DMA_DONE) { ++ /* ++ * DMA has completed, but cannot start next transfer until USBD_EP_STAT_IN_XFER_DONE. ++ * To avoid race conditions and other issues, do not release the current transfer until both ++ * interrupts have arrived. Normally this interrupt will arrive at or before the IN_XFER_DONE, ++ * but there have been situations when the system is under load that this interrupt might ++ * arrive after the IN_XFER_DONE, in which case we will need to do the processing now. ++ * The exception to this rule is for ISOC endpoints. They will only get this interrupt to ++ * indicate that DMA has completed. ++ */ ++ status &= ~USBD_EP_STAT_IN_DMA_DONE; ++ ++ if ((ep->type == USB_ENDPOINT_XFER_ISOC)) { ++ iproc_udc_req_xfer_process(ep); ++ } else if (ep->dma.done & USBD_EP_STAT_IN_XFER_DONE) { ++ /* ++ * Did not receive the IN_DMA_DONE interrupt for this request before or ++ * at the same time as the IN_XFER_DONE interrupt, so the request ++ * processing was postponed until the IN_DMA_DONE interrupt arrived. ++ * See handling of IN_XFER_DONE status below. ++ */ ++ iproc_udc_req_xfer_process(ep); ++ } else { ++ /* ++ * IN_DMA_DONE received. Save this info so request processing will be ++ * done when the IN_XFER_DONE interrupt is received. This may happen ++ * immediately, idx.e. both IN_DMA_DONE and IN_XFER_DONE status are ++ * set when the interrupt processing takes place. ++ */ ++ ep->dma.done = USBD_EP_STAT_IN_DMA_DONE; ++ } ++ } ++ ++ if (status & USBD_EP_STAT_IN_XFER_DONE) { ++ status &= ~(USBD_EP_STAT_IN_XFER_DONE); ++ status &= ~(USBD_EP_STAT_IN_FIFO_EMPTY); ++ ++ if (ep->dma.done & USBD_EP_STAT_IN_DMA_DONE) { ++ /* ++ * Have received both the IN_DMA_DONE and IN_XFER_DONE interrupts ++ * for this request. OK to process the request (remove the request ++ * and start the next one). ++ */ ++ iproc_udc_req_xfer_process(ep); ++ } else { ++ /* ++ * Have not received the IN_DMA_DONE interrupt for this request. ++ * Need to postpone processing of the request until the IN_DMA_DONE ++ * interrupt occurs. See handling of IN_DMA_DONE status above. ++ */ ++ ep->dma.done = USBD_EP_STAT_IN_XFER_DONE; ++ } ++ } ++ ++ /* Clear the FIFO EMPTY bit, not to print error message */ ++ status &= ~(USBD_EP_STAT_IN_FIFO_EMPTY); ++ ++ if (status & USBD_EP_STAT_DMA_BUF_UNAVAIL) { ++ dev_err(udc->dev, "%s: DMA BUF NOT AVAIL\n", ep->usb_ep.name); ++ status &= ~(USBD_EP_STAT_DMA_BUF_UNAVAIL); ++ iproc_udc_req_xfer_process(ep); ++ } ++ ++ if (status & USBD_EP_STAT_DMA_ERROR) { ++ status &= ~USBD_EP_STAT_DMA_ERROR; ++ dev_err(udc->dev, "%s: DMA ERROR\n", ep->usb_ep.name); ++ iproc_udc_req_xfer_error(ep, -EIO); ++ } ++ ++ if (status) ++ dev_err(udc->dev, "exit: %s %s: unknown status=0x%x\n", ++ __func__, ep->usb_ep.name, status); ++} ++ ++static void iproc_ep_out_setup_isr(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ struct iproc_udc_dma_setup *dma; ++ ++ dma = &ep->dma.vir_addr->setup; ++ if ((IPROC_USBD_READ(dma->status) & REG_DMA_STAT_BUF_MASK) != ++ REG_DMA_STAT_BUF_DMA_DONE) { ++ dev_err(udc->dev, "%s: unexpected DMA buf status=0x%x\n", ep->usb_ep.name, ++ (IPROC_USBD_READ(dma->status) & REG_DMA_STAT_BUF_MASK)); ++ iproc_ep_setup_init(ep, ENOERROR); ++ } else if ((IPROC_USBD_READ(dma->status) & REG_DMA_STAT_RX_MASK) ++ != REG_DMA_STAT_RX_SUCCESS) { ++ dev_err(udc->dev, "%s: unexpected DMA rx status=0x%x\n", ep->usb_ep.name, ++ (IPROC_USBD_READ(dma->status) & REG_DMA_STAT_RX_MASK)); ++ iproc_ep_setup_init(ep, ENOERROR); ++ } else { ++ if (ep->num != 0) { ++ /** @todo Handle the cfg / intf / alt fields of the DMA status. This will only be any issue ++ * once the Linux Gadget driver framework supports control transfers on an endpoint other ++ * than 0. ++ */ ++ dev_warn(udc->dev, "%s: CTRL xfr support not complete\n", ep->usb_ep.name); ++ } ++ /* ++ * Take ownership of the descriptor while processing the request. Ownership will be released ++ * when ready to Rx SETUP again. ++ */ ++ IPROC_USBD_BITS_MODIFY(dma->status, REG_DMA_STAT_BUF_MASK, ++ REG_DMA_STAT_BUF_HOST_BUSY); ++ iproc_ep_setup_process(ep, (struct usb_ctrlrequest *)&dma->data1); ++ } ++} ++ ++static void iproc_ep_out_isr(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ u32 status; ++ ++ status = iproc_usbd_ep_stat_active(udc->usbd_regs, ep->num, USB_DIR_OUT); ++ iproc_usbd_ep_stat_clear(udc->usbd_regs, ep->num, USB_DIR_OUT, status); ++ ++ /* ++ * Remove the Rx packet size field from the status. The datasheet states this field is not used ++ * in DMA mode, but that is not true. ++ */ ++ status &= USBD_EP_STAT_ALL; ++ ++ if (!status) ++ return; ++ ++ if ((ep->dir != USB_DIR_OUT) && (ep->type != USB_ENDPOINT_XFER_CONTROL)) { ++ dev_err(udc->dev, "%s: unexpected OUT interrupt\n", ep->usb_ep.name); ++ return; ++ } ++ ++ if (ep->dir != USB_DIR_OUT) ++ /* This probably should not be happening */ ++ dev_err(udc->dev, "%s: CTRL dir IN\n", ep->usb_ep.name); ++ ++ if (status & USBD_EP_STAT_OUT_DMA_DATA_DONE) { ++ status &= ~USBD_EP_STAT_OUT_DMA_DATA_DONE; ++ iproc_udc_req_xfer_process(ep); ++ } ++ ++ if (status & USBD_EP_STAT_OUT_DMA_SETUP_DONE) { ++ status &= ~USBD_EP_STAT_OUT_DMA_SETUP_DONE; ++ iproc_ep_out_setup_isr(ep); ++ } ++ ++ if (status & USBD_EP_STAT_DMA_BUF_UNAVAIL) { ++ /** @todo Verify under what situations this can happen. Should be when chain has emptied but last desc not reached */ ++ /** @todo status for desc updates */ ++ ++ status &= ~USBD_EP_STAT_DMA_BUF_UNAVAIL; ++ dev_err(udc->dev, "%s: DMA BUF NOT AVAIL\n", ep->usb_ep.name); ++ iproc_udc_req_xfer_process(ep); ++ } ++ ++ if (status & USBD_EP_STAT_DMA_ERROR) { ++ status &= ~USBD_EP_STAT_DMA_ERROR; ++ dev_err(udc->dev, "%s: DMA ERROR\n", ep->usb_ep.name); ++ /** @todo merge XferError and XferProcess?? */ ++ iproc_udc_req_xfer_error(ep, -EIO); ++ } ++ ++ if (status) ++ dev_err(udc->dev, "%s: unknown status=0x%x\n", ep->usb_ep.name, status); ++} ++ ++irqreturn_t xgs_iproc_udc_isr(int irq, void *context) ++{ ++ struct iproc_udc *udc = NULL; ++ unsigned long flags; ++ u32 stat, epin_stat, epout_stat; ++ int idx; ++ ++ udc = (struct iproc_udc *)context; ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ if (!udc || !udc->gadget_driver) { ++ dev_err(udc->dev, "Invalid context or no driver registered: irq dev=0x%x\n", ++ iproc_usbd_irq_active(udc->usbd_regs)); ++ ++ iproc_usbd_irq_clear(udc->usbd_regs, USBD_IRQ_ALL); ++ iproc_usbd_ep_irq_list_clear(udc->usbd_regs, USB_DIR_IN, ~0); ++ iproc_usbd_ep_irq_list_clear(udc->usbd_regs, USB_DIR_OUT, ~0); ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ return IRQ_HANDLED; ++ } ++ ++ stat = iproc_usbd_irq_active(udc->usbd_regs); ++ epin_stat = iproc_usbd_ep_irq_list_active(udc->usbd_regs, USB_DIR_IN); ++ epout_stat = iproc_usbd_ep_irq_list_active(udc->usbd_regs, USB_DIR_OUT); ++ ++ if (!(stat || epin_stat || epout_stat)) ++ return IRQ_NONE; ++ ++ iproc_usbd_irq_clear(udc->usbd_regs, stat); ++ iproc_usbd_ep_irq_list_clear(udc->usbd_regs, USB_DIR_IN, epin_stat); ++ iproc_usbd_ep_irq_list_clear(udc->usbd_regs, USB_DIR_OUT, epout_stat); ++ ++ /* ++ * Handle the SET_CFG and SET_INTF interrupts after the endpoint and other device interrupts. ++ * There can be some race conditions where we have an endpoint 0 interrupt pending for the ++ * completion of a previous endpoint 0 transfer (e.g. a GET config) when a SETUP arrives ++ * corresponding to the SET_CFG and SET_INTF. Need to complete the processing of the previous ++ * transfer before handling the next one, idx.e. the SET_CFG or SET_INTF. ++ */ ++ if (stat & USBD_IRQ_BUS_RESET) ++ dev_info(udc->dev, "BUS reset\n"); ++ ++ if (stat & USBD_IRQ_BUS_SUSPEND) ++ dev_dbg(udc->dev, "BUS suspend\n"); ++ ++ if (stat & USBD_IRQ_BUS_IDLE) { ++ dev_dbg(udc->dev, "BUS idle\n"); ++ iproc_udc_ops_disconnect(udc); ++ } ++ ++ if (stat & USBD_IRQ_SPEED_ENUM_DONE) { ++ dev_dbg(udc->dev, "BUS speed enum done\n"); ++ iproc_speed_isr(udc); ++ } ++ ++ /* endpoint interrupts handler */ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { ++ if (epin_stat & (1 << idx)) ++ iproc_ep_in_isr(&udc->ep[idx]); ++ if (epout_stat & (1 << idx)) ++ iproc_ep_out_isr(&udc->ep[idx]); ++ } ++ ++ /* SET_CFG and SET_INTF interrupts handler */ ++ if (stat & USBD_IRQ_SET_CFG) ++ iproc_cfg_isr(udc); ++ if (stat & USBD_IRQ_SET_INTF) ++ iproc_inf_isr(udc); ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return IRQ_HANDLED; ++} ++ ++/*************************************************************************** ++* Endpoint request operations ++***************************************************************************/ ++static void iproc_udc_req_queue_flush(struct iproc_ep *ep, int status) ++{ ++ struct iproc_udc *udc = ep->udc; ++ struct iproc_ep_req *req; ++ ++ ep->stopped = 1; ++ iproc_usbd_ep_ops_finish(udc->usbd_regs, ep->num); ++ ++ while (!list_empty(&ep->list_queue)) { ++ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); ++ iproc_udc_req_xfer_done(ep, req, status); ++ } ++ ++ ep->dma.usb_req = NULL; ++} ++ ++ ++static void iproc_udc_req_xfer_add(struct iproc_ep *ep, struct iproc_ep_req *req) ++{ ++ struct iproc_udc *udc = ep->udc; ++ list_add_tail(&req->list_node, &ep->list_queue); ++ ++ /** @todo Is this necessary?? Stopped happens as a result of a halt, complete(), dequeue(), nuke(). ++ * nuke() is called when ep disabled, during setup processing, and by udc_queisce(). The latter is ++ * called during vbus state change (cable insert/remove), USB reset interrupt, and gadget deregister. ++ */ ++ if (ep->stopped) ++ return; ++ ++ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC) && ++ ep->dma.usb_req && (ep->dma.frame_num == FRAME_NUM_INVALID)) { ++ /* ++ * Gadget has a request already queued, but still have not received an IN token from the host ++ * and the interval window is not aligned. Queued packet is now very stale, so remove it. ++ */ ++ ++ iproc_dma_data_finish(ep); ++ /** @todo Move set of ep->dma.usb_req to iproc_dma_data_init() and iproc_dma_data_finish() routines. */ ++ ep->dma.usb_req = NULL; ++ iproc_udc_req_xfer_done(ep, list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node), -EREMOTEIO); ++ } ++ ++ /** @todo Current transfer is always the queue head. Do we need a separate pointer? Maybe just a pointer to usb_request ++ * need to know if the queue head has already been loaded. Maybe that's the point of the "stopped". ++ */ ++ if (!ep->dma.usb_req) { ++ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC) && ++ (ep->dma.frame_num == FRAME_NUM_INVALID)) { ++ /* ++ * Delay any ISOC IN DMA operations until it is known what frame number the host ++ * is going to start transfers with. Normally might just return requests until ++ * this event occurs. However, the zero gadget does not submit requests based on ++ * its own timer or similar, so if the request is returned right away things are ++ * going to thrash, as another request will be immediately submitted. ++ */ ++ ep->dma.usb_req = &(list_first_entry(&ep->list_queue, ++ struct iproc_ep_req, list_node))->usb_req; ++ iproc_dma_data_init(ep); ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, ep->dir); ++ iproc_usbd_ep_irq_en(udc->usbd_regs, ep->num, ep->dir); ++ } else { ++ req = list_first_entry(&ep->list_queue, ++ struct iproc_ep_req, list_node); ++ ep->dma.usb_req = &req->usb_req; ++ iproc_dma_data_init(ep); ++ iproc_dma_data_add_ready(ep); ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, ep->dir); ++ iproc_usbd_ep_dma_en(udc->usbd_regs, ep->num, ep->dir); ++ ++ /* needed for gadget commands to complete correctly - possible locking issue */ ++ mdelay(3); ++ } ++ } ++} ++ ++/* ++ * UDC Operations routines. ++ * iproc_udc_ops_finish - Finish / terminate all UDC operations ++ * iproc_udc_ops_start - Start UDC operations. Happens after a Gadget driver attaches. ++ * iproc_udc_ops_stop - Stop UDC operations. Happens after a Gadget driver detaches. ++ */ ++static void iproc_udc_ops_finish(struct iproc_udc *udc) ++{ ++ /* do nothing */ ++ return; ++} ++ ++static void iproc_udc_ops_start(struct iproc_udc *udc) ++{ ++ int idx; ++ ++ /* ++ * Just enable interrupts for now. Endpoint 0 will get enabled once the speed enumeration ++ * has completed. The Device DMA enable is global in scope. There's endpoint specific ++ * DMA enables that will happen later. ++ */ ++ iproc_usbd_irq_en(udc->usbd_regs, (USBD_IRQ_SPEED_ENUM_DONE | ++ USBD_IRQ_BUS_SUSPEND | ++ USBD_IRQ_BUS_IDLE | ++ USBD_IRQ_BUS_RESET | ++ USBD_IRQ_SET_INTF | ++ USBD_IRQ_SET_CFG)); ++ iproc_usbd_dma_en(udc->usbd_regs); ++ ++ /* Enable interrupts for all configured endpoints */ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; ++idx) { ++ if (udc->ep[idx].usb_ep.name) { ++ iproc_usbd_ep_irq_en(udc->usbd_regs, udc->ep[idx].num, USB_DIR_OUT); ++ iproc_usbd_ep_irq_en(udc->usbd_regs, udc->ep[idx].num, USB_DIR_IN); ++ } ++ } ++ iproc_usbd_nak_response_dis(udc->usbd_regs); ++} ++ ++static void iproc_udc_ops_stop(struct iproc_udc *udc) ++{ ++ struct iproc_ep *ep; ++ ++ iproc_usbd_dma_dis(udc->usbd_regs); ++ iproc_usbd_irq_dis(udc->usbd_regs, USBD_IRQ_ALL); ++ iproc_usbd_irq_clear(udc->usbd_regs, USBD_IRQ_ALL); ++ ++ udc->gadget.speed = USB_SPEED_UNKNOWN; ++ ++ iproc_udc_req_queue_flush(&udc->ep[0], -ESHUTDOWN); ++ ++ list_for_each_entry(ep, &udc->gadget.ep_list, usb_ep.ep_list) ++ iproc_udc_req_queue_flush(ep, -ESHUTDOWN); ++} ++ ++/* ++ * APIs used by a Gadget driver to attach / detach from the UDC driver. ++ */ ++static int xgs_iproc_udc_start(struct usb_gadget *gadget, ++ struct usb_gadget_driver *gadget_driver) ++{ ++ struct iproc_udc *udc = gadget_to_udc(gadget); ++ unsigned long flags; ++ ++ if (!udc) { ++ dev_err(udc->dev, "UDC driver not initialized\n"); ++ return -ENODEV; ++ } ++ ++ if (!gadget_driver || !gadget_driver->setup || ++ gadget_driver->max_speed < USB_SPEED_FULL) { ++ dev_err(udc->dev, "invalid gadget driver\n" ); ++ return -EINVAL; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ if (udc->gadget_driver) { ++ spin_unlock_irqrestore(&udc->lock, flags); ++ dev_err(udc->dev, "UDC driver busy\n"); ++ return -EBUSY; ++ } ++ ++ /* Hook up the gadget driver to the UDC controller driver */ ++ gadget_driver->driver.bus = NULL; ++ udc->gadget_driver = gadget_driver; ++ udc->gadget.dev.driver = &gadget_driver->driver; ++ udc->pullup_on = 1; ++ ++ iproc_udc_ops_start(udc); ++ /* un-stop the control endpoint */ ++ udc->ep[0].stopped = 0; ++ iproc_usbd_bus_conn(udc->usbd_regs); ++ ++ iproc_usbd_setup_done(udc->usbd_regs); ++ iproc_usbd_dma_en(udc->usbd_regs); ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ENOERROR; ++} ++ ++static int xgs_iproc_udc_stop(struct usb_gadget *gadget) ++{ ++ unsigned long flags; ++ struct iproc_udc *udc = gadget_to_udc(gadget); ++ ++ if (!udc) { ++ dev_err(udc->dev, "UDC driver not initialized\n"); ++ return -ENODEV; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ udc->ep[0].stopped = 1; ++ iproc_udc_ops_stop(udc); ++ udelay(20); ++ udc->pullup_on = 0; ++ iproc_usbd_bus_disconn(udc->usbd_regs); ++ iproc_udc_ops_shutdown(udc); ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ENOERROR; ++} ++ ++/* ++ * Linux Gadget endpoint operations. See usb_ep_ops in usb_gadget.h. ++ */ ++static int xgs_iproc_ep_enable(struct usb_ep *usb_ep, const struct usb_endpoint_descriptor *desc) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ unsigned long flags; ++ u32 xferType; ++ int ret = ENOERROR; ++ ++ if (!usb_ep || (ep->beq_addr != desc->bEndpointAddress)) { ++ dev_err(udc->dev, "invalid endpoint (%p)\n", usb_ep); ++ return -EINVAL; ++ } ++ ++ if (!desc || (desc->bDescriptorType != USB_DT_ENDPOINT)) { ++ dev_err(udc->dev, "ep%d: invalid descriptor=%p type=%d\n", ep->num, desc, desc ? desc->bDescriptorType : -1); ++ return -EINVAL; ++ } ++ ++ if (desc == ep->desc) { ++ dev_warn(udc->dev, "ep%d: already enabled with same descriptor\n", ep->num); ++ return -EEXIST; ++ } ++ ++ if (ep->desc) { ++ dev_warn(udc->dev, "ep%d: already enabled with another descriptor\n", ep->num); ++ return -EBUSY; ++ } ++ ++ if (!udc->gadget_driver || (udc->gadget.speed == USB_SPEED_UNKNOWN)) { ++ dev_warn(udc->dev, "%s: invalid device state\n", ep->usb_ep.name); ++ return -ESHUTDOWN; ++ } ++ ++ xferType = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; ++ if ((ep->dir == USB_DIR_IN) && (xferType == USB_ENDPOINT_XFER_ISOC)) { ++ if ((desc->bInterval < 1) || (desc->bInterval > 16)) { ++ dev_err(udc->dev, "%s: invalid ISOC bInterval=%u\n", ep->usb_ep.name, desc->bInterval); ++ return -ERANGE; ++ } ++ ++ /* ++ * We don't know when the host will send the first ISO IN request, so we need to set up ++ * to capture that event so we can align subsequent transfers to that particular frame ++ * number. Also set the frame number increment. The endpoint descriptor specifies this ++ * as a power of 2 (2**(n-1)). Translate this into a specific number of frames. ++ */ ++ ep->dma.frame_num = FRAME_NUM_INVALID; ++ ep->dma.frame_incr = 1 << (desc->bInterval - 1); ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ ep->desc = desc; ++ ep->stopped = 0; ++ ++ /** @todo Rework the UdcEpCfg() so it includes iproc_usbd_ep_cfg_set() ... */ ++ iproc_usbd_ep_cfg_set(udc->usbd_regs, ep->num, iproc_usbd_cfg_num(udc->usbd_regs)); ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ret; ++} ++ ++static int xgs_iproc_ep_disable(struct usb_ep *usb_ep) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ unsigned long flags; ++ int ret = ENOERROR; ++ ++ if (!usb_ep) { ++ dev_err(udc->dev, "invalid endpoint\n"); ++ return -EINVAL; ++ } ++ ++ if (!ep->desc) { ++ dev_warn(udc->dev, "%s: already disabled\n", ep->usb_ep.name); ++ return ENOERROR; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ iproc_udc_req_queue_flush(ep, -ESHUTDOWN); ++ iproc_usbd_ep_irq_dis(udc->usbd_regs, ep->num, ep->dir); ++ ep->desc = NULL; ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ret; ++} ++ ++struct usb_request * xgs_iproc_ep_alloc_request(struct usb_ep *usb_ep, gfp_t gfp_flags) ++{ ++ struct iproc_ep_req *req; ++ ++ if (!usb_ep) ++ return NULL; ++ ++ if ((req = kzalloc(sizeof(*req), gfp_flags)) != NULL) { ++ /* ++ * Set the usb_req.dma to DMA_ADDR_INVALID so it can be determined if the usb_req.buf needs ++ * to be mapped when the request is subsequently queued. ++ */ ++ INIT_LIST_HEAD(&req->list_node); ++ req->usb_req.dma = DMA_ADDR_INVALID; ++ ++ return &req->usb_req; ++ } ++ ++ return NULL; ++} ++ ++static void xgs_iproc_ep_free_request(struct usb_ep *usb_ep, struct usb_request *usb_req) ++{ ++ struct iproc_ep_req *req = our_req(usb_req); ++ ++ if (usb_req) ++ kfree(req); ++} ++ ++static int xgs_iproc_ep_queue(struct usb_ep *usb_ep, struct usb_request *usb_req, gfp_t gfp_flags) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ struct iproc_ep_req *req = our_req(usb_req); ++ unsigned long flags; ++ int ret = ENOERROR; ++ ++ if (!usb_ep || !usb_req || !req->usb_req.complete || !req->usb_req.buf || !list_empty(&req->list_node)) { ++ dev_err(udc->dev, "invalid request\n"); ++ return -EINVAL; ++ } ++ ++ if (!ep->desc && (ep->num != 0)) { ++ dev_err(udc->dev, "%s: invalid EP state\n", ep->usb_ep.name); ++ return -EFAULT; ++ } ++ ++ if ((ep->type == USB_ENDPOINT_XFER_CONTROL) && !list_empty(&ep->list_queue)) { ++ dev_err(udc->dev, "%s: CTRL EP queue not empty\n", ep->usb_ep.name); ++ return -EPERM; ++ } ++ ++ if (usb_req->length > 16384 /* FSG_BUFLEN */) { ++ dev_err(udc->dev, "%s: request too big, length=%u\n", ep->usb_ep.name, usb_req->length); ++ return -E2BIG; ++ } ++ ++ /* ++ * Restrict ISOC IN requests to the max packet size. Assumption is that it does not make ++ * much sense to have more than one interval's (scheduled bandwidth's) worth of data. ++ */ ++ if ((ep->type == USB_ENDPOINT_XFER_ISOC) && (ep->dir == USB_DIR_IN) && (usb_req->length > ep->usb_ep.maxpacket)) { ++ dev_err(udc->dev, "%s: request > scheduled bandwidth, length=%u\n", ep->usb_ep.name, usb_req->length); ++ return -EFBIG; ++ } ++ ++ if (!udc->gadget_driver || (udc->gadget.speed == USB_SPEED_UNKNOWN)) { ++ dev_warn(udc->dev, "%s: invalid device state\n", ep->usb_ep.name); ++ return -ESHUTDOWN; ++ } ++ ++ if (((u32)req->usb_req.buf) & 0x3UL) { ++ /* ++ * The DMA buffer does not have the alignment required by the hardware. We keep an endpoint level ++ * buffer available to handle this situation if it arises. If we don't currently have one available ++ * for this purpose, or if the current one is not large enough, then allocate a new one. Since ++ * we only have one buffer, we won't copy into the buffer until we are ready to do the DMA transfer. ++ * Mark the request as needing this alignment (copy). ++ */ ++ if ((ep->dma.align_buff != NULL) && (ep->dma.align_len < req->usb_req.length)) { ++ dma_free_coherent(NULL, ep->dma.align_len, ep->dma.align_buff, ep->dma.align_addr); ++ ep->dma.align_buff = NULL; ++ } ++ ++ if (ep->dma.align_buff == NULL) { ++ ep->dma.align_len = req->usb_req.length; ++ ep->dma.align_buff = dma_alloc_coherent(NULL, ep->dma.align_len, &(ep->dma.align_addr), GFP_KERNEL); ++ } ++ ++ if (ep->dma.align_buff == NULL) { ++ dev_err(udc->dev, "%s: dma_alloc_coherent() failed, length=%u\n", ep->usb_ep.name, usb_req->length); ++ return -ENOMEM; ++ } ++ req->dma_aligned = 1; ++ } else if ((req->usb_req.dma == DMA_ADDR_INVALID) || (req->usb_req.dma == 0)) { ++ /* A physical address was not provided for the DMA buffer, so request it. */ ++ req->dma_mapped = 1; ++ req->usb_req.dma = dma_map_single(udc->gadget.dev.parent, ++ req->usb_req.buf, ++ req->usb_req.length, ++ ep->dir == USB_DIR_IN ? ++ DMA_TO_DEVICE : DMA_FROM_DEVICE); ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ req->usb_req.status = -EINPROGRESS; ++ req->usb_req.actual = 0; ++ ++ if ((ep->type == USB_ENDPOINT_XFER_CONTROL) && (ep->dir == USB_DIR_OUT) && (req->usb_req.length == 0)) { ++ /* ++ * This might happen if gadget driver decides to send zero length packet (ZLP) during STATUS phase ++ * of a control transfer. This may happen for the cases where there is not a DATA phase. Just consider ++ * things complete. ZLP will be issued by hardware. See the handling of SETUP packets for more details ++ * on control transfer processing. ++ */ ++ iproc_udc_req_xfer_done(ep, req, ENOERROR); ++ } else { ++ if (req->usb_req.length == 0) ++ req->usb_req.zero = 1; ++ iproc_udc_req_xfer_add(ep, req); ++ } ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ret; ++} ++ ++static int xgs_iproc_ep_dequeue(struct usb_ep *usb_ep, struct usb_request *usb_req) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ struct iproc_ep_req *req = our_req(usb_req); ++ unsigned long flags; ++ int ret = ENOERROR; ++ ++ if (!usb_ep || !usb_req) { ++ dev_err(udc->dev, "invalid request\n"); ++ return -EINVAL; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ /* Make sure it's actually queued on this endpoint */ ++ list_for_each_entry(req, &ep->list_queue, list_node) { ++ if (&req->usb_req == usb_req) ++ break; ++ } ++ ++ if (&req->usb_req != usb_req) { ++ spin_unlock_irqrestore(&udc->lock, flags); ++ dev_err(udc->dev, "%s: request not queued\n", ep->usb_ep.name); ++ return -ENOLINK; ++ } ++ ++ /** @todo Handle case where the request is in progress, or completed but not dequeued */ ++ ++ iproc_udc_req_xfer_done(ep, req, -ECONNRESET); ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ret; ++} ++ ++static int xgs_iproc_ep_set_halt(struct usb_ep *usb_ep, int enable) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ unsigned long flags; ++ int ret = ENOERROR; ++ ++ if (!usb_ep) { ++ dev_err(udc->dev, "invalid request\n"); ++ return -EINVAL; ++ } ++ ++ if (ep->type == USB_ENDPOINT_XFER_ISOC) { ++ dev_warn(udc->dev, "%s: ISO HALT operations not supported\n", ep->usb_ep.name); ++ return -EOPNOTSUPP; ++ } ++ ++ if (enable && (ep->dir == USB_DIR_IN) && !list_empty(&ep->list_queue)) { ++ /* Only allow halt on an IN EP if its queue is empty */ ++ dev_err(udc->dev, "%s: IN queue not empty\n", ep->usb_ep.name); ++ return -EAGAIN; ++ } ++ ++ if (!enable && (ep->type == USB_ENDPOINT_XFER_CONTROL)) { ++ /* ++ * Halt clear for a control EP should only be handled as part of the subsequent SETUP ++ * exchange that occurs after the Halt was set. ++ */ ++ dev_warn(udc->dev, "%s: CTRL HALT clear\n", ep->usb_ep.name); ++ return -EPROTO; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ if (!enable) { ++ iproc_usbd_ep_stall_dis(udc->usbd_regs, ep->num, ep->dir); ++ } else if (ep->type != USB_ENDPOINT_XFER_CONTROL) { ++ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, ep->dir); ++ } else { ++ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, USB_DIR_IN); ++ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, USB_DIR_OUT); ++ } ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ mdelay(2); ++ ++ return ret; ++} ++ ++static int xgs_iproc_ep_fifo_status(struct usb_ep *usb_ep) ++{ ++ /* ++ * The DWC UDC core doesn't have a mechanism for determining the number of bytes ++ * currently in a FIFO. The best that can be done is determine whether or not a ++ * FIFO is empty. However, for the situation where a single Rx FIFO is being ++ * used for all endpoints, if cannot be determined which OUT and CTRL EP's are ++ * affected if the Rx FIFO is not empty. ++ */ ++ return -EOPNOTSUPP; ++} ++ ++static void xgs_iproc_ep_fifo_flush(struct usb_ep *usb_ep) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ unsigned long flags; ++ ++ if (!usb_ep) { ++ dev_err(udc->dev, "invalid request\n"); ++ return; ++ } ++ ++ /* ++ * FIFO flush for a control EP does not make any sense. The SETUP protocol ++ * should eliminate the need to flush. ++ */ ++ if (ep->type == USB_ENDPOINT_XFER_CONTROL) { ++ dev_warn(udc->dev, "%s: CTRL FIFO flush\n", ep->usb_ep.name); ++ return; ++ } ++ ++ if (iproc_usbd_ep_fifo_empty(udc->usbd_regs, ep->num, ep->dir)) { ++ dev_warn(udc->dev, "%s: FIFO empty\n", ep->usb_ep.name); ++ return; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ iproc_usbd_ep_fifo_flush_en(udc->usbd_regs, ep->num, ep->dir); ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++} ++ ++ ++/*************************************************************************** ++ * Linux proc file system functions ++ ***************************************************************************/ ++#ifdef CONFIG_USB_GADGET_DEBUG_FILES ++#include ++ ++static const char udc_proc_file_name[] = "driver/" XGS_IPROC_UDC_NAME; ++ ++static int proc_file_show(struct seq_file *s, void *_) ++{ ++ return 0; ++} ++ ++static int proc_file_open(struct inode *inode, struct file *file) ++{ ++ return(single_open(file, proc_file_show, NULL)); ++} ++ ++static struct file_operations udc_proc_file_ops = ++{ ++ .open = proc_file_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static void xgs_iproc_udc_proc_create(void) ++{ ++ proc_create(udc_proc_file_name, 0, NULL, &udc_proc_file_ops); ++} ++ ++static void xgs_iproc_udc_proc_remove(void) ++{ ++ remove_proc_entry(udc_proc_file_name, NULL); ++} ++ ++#else ++ ++static void xgs_iproc_udc_proc_create(void) {} ++static void xgs_iproc_udc_proc_remove(void) {} ++ ++#endif ++ ++static struct usb_gadget_ops xgs_iproc_udc_ops = { ++ .udc_start = xgs_iproc_udc_start, ++ .udc_stop = xgs_iproc_udc_stop, ++}; ++ ++static struct usb_ep_ops xgs_iproc_udc_ep_ops = { ++ .enable = xgs_iproc_ep_enable, ++ .disable = xgs_iproc_ep_disable, ++ .alloc_request = xgs_iproc_ep_alloc_request, ++ .free_request = xgs_iproc_ep_free_request, ++ .queue = xgs_iproc_ep_queue, ++ .dequeue = xgs_iproc_ep_dequeue, ++ .set_halt = xgs_iproc_ep_set_halt, ++ .fifo_status = xgs_iproc_ep_fifo_status, ++ .fifo_flush = xgs_iproc_ep_fifo_flush, ++}; ++ ++static const struct of_device_id xgs_iproc_udc_ids[] = { ++ { .compatible = "brcm,usbd-xgs-iproc", }, ++ { .compatible = "brcm,usbd-xgs-hx4", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, xgs_iproc_udc_ids); ++ ++static void iproc_udc_ops_init(struct iproc_udc *udc) ++{ ++ int idx; ++ struct iproc_ep *ep; ++ ++ iproc_usbd_ops_init(udc->usbd_regs); ++ ++ /* ++ * See usb/gadget/epautoconf.c for endpoint naming conventions. ++ * Control endpoints are bi-directional, but initial transfer (SETUP stage) is always OUT. ++ */ ++ /** @todo Really should make the non endpoint 0 init attributes configurable by the chip specific part ++ * of the driver, idx.e. the device instantiation. The settings below are for a chip specific DWG UDC ++ * core configuration. Also should incorporate the DWG UDC endpoint type attribute as part of this, ++ * which can be control, IN, OUT, or bidirectional. ++ */ ++ INIT_LIST_HEAD(&udc->gadget.ep_list); ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { ++ ep = &udc->ep[idx]; ++ ++ ep->udc = udc; ++ ep->num = idx; ++ ++ ep->dir = (xgs_iproc_ep_info[idx].caps.dir_in) ? USB_DIR_IN : USB_DIR_OUT;; ++ ep->beq_addr = idx | ep->dir; ++ ep->stopped = 0; ++ ep->type = xgs_iproc_ep_info[idx].type; ++ ++ ep->usb_ep.name = xgs_iproc_ep_info[idx].name; ++ ep->usb_ep.caps = xgs_iproc_ep_info[idx].caps; ++ ep->usb_ep.ops = &xgs_iproc_udc_ep_ops; ++ list_add_tail(&ep->usb_ep.ep_list, &udc->gadget.ep_list); ++ usb_ep_set_maxpacket_limit(&ep->usb_ep, xgs_iproc_ep_info[idx].msize); ++ ep->usb_ep.desc = NULL; ++ INIT_LIST_HEAD(&ep->list_queue); ++ ++ iproc_usbd_ep_ops_init(udc->usbd_regs, ep->num, ep->type, ++ ep->dir, xgs_iproc_ep_info[idx].msize); ++ ++ iproc_dma_ep_init(ep); ++ } ++ ++ udc->gadget.ep0 = &udc->ep[0].usb_ep; ++ list_del(&udc->ep[0].usb_ep.ep_list); ++ ++ iproc_usbd_self_pwr_en(udc->usbd_regs); ++} ++ ++ ++/**************************************************************************** ++ ***************************************************************************/ ++static int xgs_iproc_udc_probe(struct platform_device *pdev) ++{ ++ int ret = ENOERROR; ++ struct device *dev = &pdev->dev; ++ struct device_node *dn = dev->of_node; ++ struct iproc_udc *udc = NULL; ++ struct usb_phy *phy; ++ struct resource *res; ++ void __iomem *usbd_base; ++ int irq; ++ ++ phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0); ++ if (IS_ERR(phy)) { ++ dev_err(dev, "unable to find transceiver\n"); ++ return PTR_ERR(phy); ++ } ++ ++ /* HX4 SVK always is identified as HOST, because GPIO pin 0 is always low, ++ * even the strap setting of JP1803 is device mode. ++ */ ++ if (!of_device_is_compatible(dn, "brcm,usbd-xgs-hx4")) ++ if (phy->flags != IPROC_USB_MODE_DEVICE) ++ return -ENODEV; ++ ++ irq = platform_get_irq(pdev, 0); ++ ++ udc = devm_kzalloc(dev, sizeof(*udc), GFP_KERNEL); ++ if (!udc) { ++ dev_err(dev, "devm_kzalloc() failed\n" ); ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(pdev, udc); ++ udc->dev = dev; ++ spin_lock_init(&udc->lock); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ usbd_base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(usbd_base)) { ++ dev_err(dev, "can't ioremap USB2D base addr\n"); ++ return PTR_ERR(usbd_base); ++ } ++ ++ udc->usbd_regs = (struct iproc_usbd_regs *)usbd_base; ++ ++ ret = usb_phy_init(phy); ++ if (ret < 0) { ++ dev_err(dev, "initial usb transceiver failed.\n"); ++ return ret; ++ } ++ ++ ret = iproc_platform_dma_alloc(pdev, udc); ++ if (ret < 0) { ++ dev_err(dev, "iproc_platform_dma_alloc() failed\n"); ++ return ret; ++ } ++ ++ /* gadget init */ ++ udc->gadget.name = XGS_IPROC_UDC_NAME; ++ udc->gadget.speed = USB_SPEED_UNKNOWN; ++ udc->gadget.max_speed = USB_SPEED_HIGH; ++ udc->gadget.ops = &xgs_iproc_udc_ops; ++ ++ iproc_udc_ops_init(udc); ++ ++ iproc_usbd_irq_dis(udc->usbd_regs, USBD_IRQ_ALL); ++ iproc_usbd_irq_clear(udc->usbd_regs, USBD_IRQ_ALL); ++ ++ ret = devm_request_irq(dev, irq, xgs_iproc_udc_isr, 0, ++ XGS_IPROC_UDC_NAME, (void *)udc); ++ if (ret < 0) { ++ dev_err(dev, "error requesting IRQ #%d\n", irq); ++ goto err1; ++ } ++ ++ ret = usb_add_gadget_udc(dev, &udc->gadget); ++ if (ret < 0) { ++ dev_err(dev, "usb_add_gadget_udc() failed\n"); ++ goto err1; ++ } ++ ++ xgs_iproc_udc_proc_create(); ++ ++ return ENOERROR; ++ ++err1: ++ iproc_platform_dma_free(pdev, udc); ++ ++ return ret; ++} ++ ++static int xgs_iproc_udc_remove(struct platform_device *pdev) ++{ ++ struct iproc_udc *udc = platform_get_drvdata(pdev); ++ ++ if (udc) { ++ xgs_iproc_udc_proc_remove(); ++ ++ usb_del_gadget_udc(&udc->gadget); ++ iproc_udc_ops_finish(udc); ++ ++ platform_set_drvdata(pdev, NULL); ++ iproc_platform_dma_free(pdev, udc); ++ } ++ ++ return ENOERROR; ++} ++ ++/* ++ * Generic platform device driver definition. ++ */ ++static struct platform_driver xgs_iproc_udc_driver = ++{ ++ .probe = xgs_iproc_udc_probe, ++ .remove = xgs_iproc_udc_remove, ++ .driver = { ++ .name = XGS_IPROC_UDC_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = xgs_iproc_udc_ids, ++ }, ++}; ++ ++module_platform_driver(xgs_iproc_udc_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("Broadcom USB Device Controller(UDC) driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/xgs_iproc_udc.h b/drivers/usb/gadget/udc/xgs_iproc_udc.h +--- a/drivers/usb/gadget/udc/xgs_iproc_udc.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/usb/gadget/udc/xgs_iproc_udc.h 2018-05-10 11:31:33.789404169 +0800 +@@ -0,0 +1,157 @@ ++/* ++ * Copyright 2017 Broadcom Limited ++ * ++ * 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. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _XGS_IPROC_UDC_H_ ++#define _XGS_IPROC_UDC_H_ ++ ++#include ++#include "xgs_iproc_usbd_regs.h" ++ ++#define IPROC_UDC_EP_CNT 7 ++#define IPROC_UDC_CTRL_MAX_PKG_SIZE 64 ++#define IPROC_UDC_EP_MAX_PKG_SIZE 512 ++ ++/* ++ * Some unsigned number trickery for indexing into DMA descriptor chain. If the ++ * decriptor count is some power of 2, then we can use the mask to extract ++ * an index and not worry about wrap around as the unsigned variables are ++ * incremented. E.g. in following, IDX(0), IDX(4), IDX(8), ..., IDX(0xffffc) ++ * all produce the same result, i.e. 0. ++ */ ++#define IPROC_EP_DMA_DESC_CNT 1 ++#define IPROC_EP_DMA_DESC_IDX_MASK (IPROC_EP_DMA_DESC_CNT - 1) ++#define IPROC_EP_DMA_DESC_IDX(_idx) ((_idx) & IPROC_EP_DMA_DESC_IDX_MASK) ++ ++/* Some DWC UDC DMA descriptor layout definitions. See datasheet for details. */ ++ ++struct iproc_udc_dma_setup { ++ unsigned int status; ++ unsigned int reserved; ++ unsigned int data1; ++ unsigned int data2; ++}; ++ ++struct iproc_udc_dma_desc { ++ unsigned int status; ++ unsigned int reserved; ++ unsigned int buf_addr; ++ unsigned int next_addr; ++}; ++ ++/* ++ * Common DMA descriptor layout used for all endpoints. Only control endpoints ++ * need the setup descriptor, but in order to simply things it is defined for ++ * all. It may be possible to omit this altogether, and just use one of data ++ * descriptors for setup instead. The control transfer protocol should allow ++ * this to be done. ++ */ ++struct iproc_ep_dma { ++ struct iproc_udc_dma_setup setup; ++ struct iproc_udc_dma_desc desc[IPROC_EP_DMA_DESC_CNT]; ++}; ++ ++/* Structure used for DMA descriptor allocation. Not really necessary but convenient. */ ++struct iproc_udc_dma { ++ struct iproc_ep_dma ep[IPROC_UDC_EP_CNT]; ++}; ++ ++/* ++ * Structure used to hold endpoint specific information. There's one of these for ++ * each endpoint. ++ * ++ * The Rx/Tx FIFO sizes are used for RAM allocation purposes. Each transfer ++ * direction has its own RAM that is used for all the FIFOs in that direction. ++ * The RAM gets segmented (allocated) as each endpoint gets enabled. This dynamic ++ * allocation FIFO sizes gives flexibility, and does not require that an ++ * endpoint's size be fixed at run-time or during compilation. If there's not ++ * enough FIFO RAM as required by a gadget's endpoint definitions, then an ++ * error will occur for the enabling of any endpoints after the FIFO RAM has ++ * become exhausted. ++ * ++ * The DMA virtual address is used for all descriptor operations. The DMA ++ * physical address is for convenience (setting hardware registers, obtaining ++ * addresses for descriptor chaining, etc.). The DMA descriptors are not ++ * allocated on a per-endpoint basis. These are just pointers into the ++ * large block that was allocated for all endpoints. ++ */ ++struct iproc_ep { ++ struct usb_ep usb_ep; /* usb_gadget.h */ ++ const struct usb_endpoint_descriptor *desc; /* usb/ch9.h */ ++ struct list_head list_queue; /* active BCM_UDC_EP_REQ's for the endpoint */ ++ struct iproc_udc *udc; /* endpoint owner (UDC controller) */ ++ unsigned int num; ++ unsigned int dir; /* USB_DIR_xxx (direction) */ ++ unsigned int type; /* USB_ENDPOINT_XFER_xxx */ ++ unsigned int beq_addr; /* dirn | type */ ++ unsigned int stopped : 1; ++ struct { ++ struct iproc_ep_dma *vir_addr; ++ struct iproc_ep_dma *phy_addr; ++ struct usb_request *usb_req; /* Current request being DMA'd */ ++ ++ /** @todo Some of the below are duplicates of usb_request elements. Use usb_request instead. */ ++ unsigned int max_buf_len; /* Max buffer length to use with a descriptor */ ++ unsigned int done_len; /* Length of request DMA'd so far */ ++ unsigned int todo_len; /* Length of request left to DMA */ ++ unsigned int add_idx; /* descriptor chain index */ ++ unsigned int rm_idx; /* descriptor chain index */ ++ unsigned int buf_addr; /* Location in request to DMA */ ++ unsigned int frame_num; /* Frame number for ISOC transfers */ ++ unsigned int frame_incr; /* Frame number increment (period) */ ++ unsigned int status; ++ unsigned int done; /* DMA and USB transfer completion indication (IN_DMA_DONE and IN_XFER_DONE) */ ++ void *align_buff; /* Aligned buffer. Only used if usb_req buffer not aligned properly. */ ++ dma_addr_t align_addr; /* Aligned buffer physical address */ ++ unsigned int align_len; /* Aligned buffer length */ ++ } dma; ++}; ++ ++/* ++ * Structure used to hold controller information. There should be one of these ++ * for each controller. Most likely there's only one. ++ * ++ * The Rx/Tx FIFO space are used for RAM allocation purposes. These track how ++ * much RAM is available for use as a FIFO. When an endpoint is enabled, these ++ * are check to see if there's enough RAM for a FIFO of the desired length as ++ * implied by the max packet size. ++ */ ++struct iproc_udc { ++ struct usb_gadget gadget; /* usb_gadget.h */ ++ struct usb_gadget_driver *gadget_driver; /* usb_gadget.h */ ++ struct completion *dev_release; /* Used for coordination during device removal */ ++ spinlock_t lock; ++ struct device *dev; ++ unsigned int irq_num; ++ struct iproc_ep ep[IPROC_UDC_EP_CNT]; ++ struct iproc_usbd_regs *usbd_regs; ++ struct { ++ struct iproc_udc_dma *vir_addr; ++ struct iproc_udc_dma *phy_addr; ++ } dma; ++ unsigned int vbus_active : 1; /* Indicates if VBUS is present */ ++ unsigned int pullup_on : 1; /* Indicates if pull up is on */ ++}; ++ ++/* ++ * Structure used to hold an endpoint transfer request. Can be any number of ++ * these for an endpoint. ++ */ ++struct iproc_ep_req { ++ struct usb_request usb_req; /* usb_gadget.h */ ++ struct list_head list_node; /* For linking in the BCM_UDC_EP request queue */ ++ dma_addr_t orig_dma_addr; /* Original buffer DMA address (physical). */ ++ unsigned dma_mapped : 1; /* Indicates if address mapping req'd. See usb_gadget.h */ ++ unsigned dma_aligned : 1; /* Indicates if buffer duplication done for alignment. */ ++}; ++ ++#endif /* _XGS_IPROC_UDC_H_ */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/xgs_iproc_usbd_regs.h b/drivers/usb/gadget/udc/xgs_iproc_usbd_regs.h +--- a/drivers/usb/gadget/udc/xgs_iproc_usbd_regs.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/usb/gadget/udc/xgs_iproc_usbd_regs.h 2018-05-10 11:31:33.789404169 +0800 +@@ -0,0 +1,969 @@ ++/* ++ * Copyright 2017 Broadcom Limited ++ * ++ * 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. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _USBD_REGS_H_ ++#define _USBD_REGS_H_ ++ ++#include ++#include ++ ++#define USBD_MULTI_RX_FIFO 0 ++ ++#define USBD_EP_CFG_CNT 10 ++#define USBD_REG_EP_CNT 16 ++ ++#define USBD_IRQ_REMOTEWAKEUP_DELTA REG_INTR_REMOTE_WAKEUP_DELTA ++#define USBD_IRQ_SPEED_ENUM_DONE REG_INTR_SPD_ENUM_DONE ++#define USBD_IRQ_SOF_DETECTED REG_INTR_SOF_RX ++#define USBD_IRQ_BUS_SUSPEND REG_INTR_BUS_SUSPEND ++#define USBD_IRQ_BUS_RESET REG_INTR_BUS_RESET ++#define USBD_IRQ_BUS_IDLE REG_INTR_BUS_IDLE ++#define USBD_IRQ_SET_INTF REG_INTR_SET_INTF_RX ++#define USBD_IRQ_SET_CFG REG_INTR_SET_CFG_RX ++#define USBD_IRQ_ALL (USBD_IRQ_REMOTEWAKEUP_DELTA | \ ++ USBD_IRQ_SPEED_ENUM_DONE | \ ++ USBD_IRQ_SOF_DETECTED | \ ++ USBD_IRQ_BUS_SUSPEND | \ ++ USBD_IRQ_BUS_RESET | \ ++ USBD_IRQ_BUS_IDLE | \ ++ USBD_IRQ_SET_INTF | \ ++ USBD_IRQ_SET_CFG) ++ ++#define USBD_EP_STAT_DMA_ERROR REG_EP_FIFO_STATUS_AHB_BUS_ERROR ++#define USBD_EP_STAT_DMA_BUF_UNAVAIL REG_EP_FIFO_STATUS_DMA_BUF_NOT_AVAIL ++#define USBD_EP_STAT_IN_TOKEN_RX REG_EP_FIFO_STATUS_IN_TOKEN_RX ++#define USBD_EP_STAT_IN_DMA_DONE REG_EP_FIFO_STATUS_IN_DMA_DONE ++#define USBD_EP_STAT_IN_FIFO_EMPTY REG_EP_FIFO_STATUS_IN_FIFO_EMPTY ++#define USBD_EP_STAT_IN_XFER_DONE REG_EP_FIFO_STATUS_IN_XFER_DONE ++#define USBD_EP_STAT_OUT_DMA_DATA_DONE REG_EP_FIFO_STATUS_OUT_DMA_DATA_DONE ++#define USBD_EP_STAT_OUT_DMA_SETUP_DONE REG_EP_FIFO_STATUS_OUT_DMA_SETUP_DONE ++#define USBD_EP_STAT_ALL (USBD_EP_STAT_DMA_ERROR | \ ++ USBD_EP_STAT_DMA_BUF_UNAVAIL | \ ++ USBD_EP_STAT_IN_TOKEN_RX | \ ++ USBD_EP_STAT_IN_DMA_DONE | \ ++ USBD_EP_STAT_IN_XFER_DONE | \ ++ USBD_EP_STAT_OUT_DMA_DATA_DONE | \ ++ USBD_EP_STAT_OUT_DMA_SETUP_DONE) ++ ++ ++#define REG8_RSVD(start, end) u8 rsvd_##start[(end - start) / sizeof(u8)] ++#define REG16_RSVD(start, end) u16 rsvd_##start[(end - start) / sizeof(u16)] ++#define REG32_RSVD(start, end) u32 rsvd_##start[(end - start) / sizeof(u32)] ++ ++struct iproc_usbd_ep_fifo_regs { ++ uint ctrl; ++ uint status; ++ uint size1; ++ uint size2; /* Buf Size OUT/Max PKT SIZE */ ++ uint buf_addr; ++ uint desc_addr; ++ REG32_RSVD(0x18, 0x20); ++}; ++ ++struct iproc_usbd_regs { ++ struct iproc_usbd_ep_fifo_regs ep_fifo_in[USBD_REG_EP_CNT]; ++ struct iproc_usbd_ep_fifo_regs ep_fifo_out[USBD_REG_EP_CNT]; ++ uint dev_cfg; ++ uint dev_ctrl; ++ uint dev_status; ++ uint dev_irq_status; ++ uint dev_irq_mask; ++ uint ep_irq_status; ++ uint ep_irq_mask; ++ uint test_mode; ++ uint rel_num; ++ REG32_RSVD(0x424, 0x500); ++ REG32_RSVD(0x500, 0x504); ++ uint ep_cfg[USBD_REG_EP_CNT]; ++ REG32_RSVD(0x544, 0x800); ++ uint rx_fifo[256]; ++ uint tx_fifo[256]; ++ uint strap; ++}; ++ ++ ++struct iproc_usbd_idm_regs { ++ REG32_RSVD(0x000, 0x408); ++ uint io_ctrl; ++ REG32_RSVD(0x40C, 0x500); ++ uint io_status; ++ REG32_RSVD(0x504, 0x800); ++ uint reset_ctrl; ++ uint reset_status; ++ REG32_RSVD(0x808, 0xA00); ++ uint irq_status; ++}; ++ ++/* ++ * The endpoint type field in the FIFO control register has the same enumeration ++ * as the USB protocol. Not going to define it here. ++ */ ++#define REG_EP_FIFO_CTRL_OUT_FLUSH_ENABLE (1 << 12) ++#define REG_EP_FIFO_CTRL_OUT_CLOSE_DESC (1 << 11) ++#define REG_EP_FIFO_CTRL_IN_SEND_NULL (1 << 10) ++#define REG_EP_FIFO_CTRL_OUT_DMA_ENABLE (1 << 9) ++#define REG_EP_FIFO_CTRL_NAK_CLEAR (1 << 8) ++#define REG_EP_FIFO_CTRL_NAK_SET (1 << 7) ++#define REG_EP_FIFO_CTRL_NAK_IN_PROGRESS (1 << 6) ++#define REG_EP_FIFO_CTRL_TYPE_SHIFT 4 ++#define REG_EP_FIFO_CTRL_TYPE_MASK (3 << REG_EP_FIFO_CTRL_TYPE_SHIFT) ++#define REG_EP_FIFO_CTRL_IN_DMA_ENABLE (1 << 3) ++#define REG_EP_FIFO_CTRL_SNOOP_ENABLE (1 << 2) ++#define REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE (1 << 1) ++#define REG_EP_FIFO_CTRL_STALL_ENABLE (1 << 0) ++ ++#define REG_EP_FIFO_STATUS_CLOSE_DESC_CLEAR (1 << 28) ++#define REG_EP_FIFO_STATUS_IN_XFER_DONE (1 << 27) ++#define REG_EP_FIFO_STATUS_STALL_SET_RX (1 << 26) ++#define REG_EP_FIFO_STATUS_STALL_CLEAR_RX (1 << 25) ++#define REG_EP_FIFO_STATUS_IN_FIFO_EMPTY (1 << 24) ++#define REG_EP_FIFO_STATUS_IN_DMA_DONE (1 << 10) ++#define REG_EP_FIFO_STATUS_AHB_BUS_ERROR (1 << 9) ++#define REG_EP_FIFO_STATUS_OUT_FIFO_EMPTY (1 << 8) ++#define REG_EP_FIFO_STATUS_DMA_BUF_NOT_AVAIL (1 << 7) ++#define REG_EP_FIFO_STATUS_IN_TOKEN_RX (1 << 6) ++#define REG_EP_FIFO_STATUS_OUT_DMA_SETUP_DONE (1 << 5) ++#define REG_EP_FIFO_STATUS_OUT_DMA_DATA_DONE (1 << 4) ++ ++#define REG_EP_FIFO_SIZE1_OUT_ISOC_PID_SHIFT 16 ++#define REG_EP_FIFO_SIZE1_OUT_ISOC_PID_MASK (3 << REG_EP_FIFO_SIZE1_OUT_ISOC_PID_SHIFT) ++#define REG_EP_FIFO_SIZE1_IN_DEPTH_SHIFT 0 ++#define REG_EP_FIFO_SIZE1_IN_DEPTH_MASK (0xffff << REG_EP_FIFO_SIZE1_IN_DEPTH_SHIFT) ++#define REG_EP_FIFO_SIZE1_OUT_FRAME_NUM_SHIFT REG_EP_FIFO_SIZE1_IN_DEPTH_SHIFT ++#define REG_EP_FIFO_SIZE1_OUT_FRAME_NUM_MASK REG_EP_FIFO_SIZE1_IN_DEPTH_MASK ++ ++#define REG_EP_FIFO_SIZE2_OUT_DEPTH_SHIFT 16 ++#define REG_EP_FIFO_SIZE2_OUT_DEPTH_MASK (0xffff << REG_EP_FIFO_SIZE2_OUT_DEPTH_SHIFT) ++#define REG_EP_FIFO_SIZE2_PKT_MAX_SHIFT 0 ++#define REG_EP_FIFO_SIZE2_PKT_MAX_MASK (0xffff << REG_EP_FIFO_SIZE2_PKT_MAX_SHIFT) ++ ++/* ++ * The endpoint type field in the config register has the same enumeration ++ * as the USB protocol. Not going to define it here. ++ */ ++#define REG_EP_CFG_PKT_MAX_SHIFT 19 ++#define REG_EP_CFG_PKT_MAX_MASK (0x7ff << REG_EP_CFG_PKT_MAX_SHIFT) ++#define REG_EP_CFG_ALT_NUM_SHIFT 15 ++#define REG_EP_CFG_ALT_NUM_MASK (0xf << REG_EP_CFG_ALT_NUM_SHIFT) ++#define REG_EP_CFG_INTF_NUM_SHIFT 11 ++#define REG_EP_CFG_INTF_NUM_MASK (0xf << REG_EP_CFG_INTF_NUM_SHIFT) ++#define REG_EP_CFG_CFG_NUM_SHIFT 7 ++#define REG_EP_CFG_CFG_NUM_MASK (0xf << REG_EP_CFG_CFG_NUM_SHIFT) ++#define REG_EP_CFG_TYPE_SHIFT 5 ++#define REG_EP_CFG_TYPE_MASK (0x3 << REG_EP_CFG_TYPE_SHIFT) ++#define REG_EP_CFG_DIRN_IN (1 << 4) ++#define REG_EP_CFG_DIRN_OUT 0 ++#define REG_EP_CFG_FIFO_NUM_SHIFT 0 ++#define REG_EP_CFG_FIFO_NUM_MASK (0xf << REG_EP_CFG_FIFO_NUM_SHIFT) ++ ++/* Endpoint Interrupt register definitions */ ++#define REG_EP_INTR_OUT_SHIFT 16 ++#define REG_EP_INTR_OUT_MASK (0xffff << REG_EP_INTR_OUT_SHIFT) ++#define REG_EP_INTR_IN_SHIFT 0 ++#define REG_EP_INTR_IN_MASK (0xffff << REG_EP_INTR_IN_SHIFT) ++ ++/* Device Controller register definitions */ ++#define REG_CFG_ULPI_DDR_ENABLE (1 << 19) ++#define REG_CFG_SET_DESCRIPTOR_ENABLE (1 << 18) ++#define REG_CFG_CSR_PROGRAM_ENABLE (1 << 17) ++#define REG_CFG_HALT_STALL_ENABLE (1 << 16) ++#define REG_CFG_HS_TIMEOUT_CALIB_SHIFT 13 ++#define REG_CFG_HS_TIMEOUT_CALIB_MASK (7 << REG_CFG_HS_TIMEOUT_CALIB_SHIFT) ++#define REG_CFG_FS_TIMEOUT_CALIB_SHIFT 10 ++#define REG_CFG_FS_TIMEOUT_CALIB_MASK (7 << REG_CFG_FS_TIMEOUT_CALIB_SHIFT) ++#define REG_CFG_STATUS_1_ENABLE (1 << 8) ++#define REG_CFG_STATUS_ENABLE (1 << 7) ++#define REG_CFG_UTMI_BI_DIRN_ENABLE (1 << 6) ++#define REG_CFG_UTMI_8BIT_ENABLE (1 << 5) ++#define REG_CFG_SYNC_FRAME_ENABLE (1 << 4) ++#define REG_CFG_SELF_PWR_ENABLE (1 << 3) ++#define REG_CFG_REMOTE_WAKEUP_ENABLE (1 << 2) ++#define REG_CFG_SPD_SHIFT 0 ++#define REG_CFG_SPD_MASK (3 << REG_CFG_SPD_SHIFT) ++#define REG_CFG_SPD_HS (0 << REG_CFG_SPD_SHIFT) ++#define REG_CFG_SPD_FS (1 << REG_CFG_SPD_SHIFT) ++#define REG_CFG_SPD_LS (2 << REG_CFG_SPD_SHIFT) ++#define REG_CFG_SPD_FS_48MHZ (3 << REG_CFG_SPD_SHIFT) ++ ++#define REG_CTRL_DMA_OUT_THRESHOLD_LEN_SHIFT 24 ++#define REG_CTRL_DMA_OUT_THRESHOLD_LEN_MASK (0xff << REG_CTRL_DMA_OUT_THRESHOLD_LEN_SHIFT) ++#define REG_CTRL_DMA_BURST_LEN_SHIFT 16 ++#define REG_CTRL_DMA_BURST_LEN_MASK (0xff << REG_CTRL_DMA_BURST_LEN_SHIFT) ++#define REG_CTRL_OUT_FIFO_FLUSH_ENABLE (1 << 14) ++#define REG_CTRL_CSR_DONE (1 << 13) ++#define REG_CTRL_OUT_NAK_ALL_ENABLE (1 << 12) ++#define REG_CTRL_DISCONNECT_ENABLE (1 << 10) ++#define REG_CTRL_DMA_MODE_ENABLE (1 << 9) ++#define REG_CTRL_DMA_BURST_ENABLE (1 << 8) ++#define REG_CTRL_DMA_OUT_THRESHOLD_ENABLE (1 << 7) ++#define REG_CTRL_DMA_BUFF_FILL_MODE_ENABLE (1 << 6) ++#define REG_CTRL_ENDIAN_BIG_ENABLE (1 << 5) ++#define REG_CTRL_DMA_DESC_UPDATE_ENABLE (1 << 4) ++#define REG_CTRL_DMA_IN_ENABLE (1 << 3) /*TX DMA Enable */ ++#define REG_CTRL_DMA_OUT_ENABLE (1 << 2) /*RX DMA Enable */ ++#define REG_CTRL_RESUME_SIGNAL_ENABLE (1 << 0) ++#define REG_CTRL_LE_ENABLE 0 ++ ++#define REG_STAT_SOF_FRAME_NUM_SHIFT 18 ++#define REG_STAT_SOF_FRAME_NUM_MASK (0x3fff << REG_STAT_SOF_FRAME_NUM_SHIFT) ++#define REG_STAT_REMOTE_WAKEUP_ALLOWED (1 << 17) ++#define REG_STAT_PHY_ERROR (1 << 16) ++#define REG_STAT_OUT_FIFO_EMPTY (1 << 15) ++#define REG_STAT_SPD_SHIFT 13 ++#define REG_STAT_SPD_MASK (3 << REG_STAT_SPD_SHIFT) ++#define REG_STAT_SPD_HS (0 << REG_STAT_SPD_SHIFT) ++#define REG_STAT_SPD_FS (1 << REG_STAT_SPD_SHIFT) ++#define REG_STAT_SPD_LS (2 << REG_STAT_SPD_SHIFT) ++#define REG_STAT_SPD_FS_48MHZ (3 << REG_STAT_SPD_SHIFT) ++#define REG_STAT_BUS_SUSPENDED (1 << 12) ++#define REG_STAT_ALT_NUM_SHIFT 8 ++#define REG_STAT_ALT_NUM_MASK (0xf << REG_STAT_ALT_NUM_SHIFT) ++#define REG_STAT_INTF_NUM_SHIFT 4 ++#define REG_STAT_INTF_NUM_MASK (0xf << REG_STAT_INTF_NUM_SHIFT) ++#define REG_STAT_CFG_NUM_SHIFT 0 ++#define REG_STAT_CFG_NUM_MASK (0xf << REG_STAT_CFG_NUM_SHIFT) ++ ++#define REG_INTR_REMOTE_WAKEUP_DELTA (1 << 7) /*Remote Wakeup Delta*/ ++#define REG_INTR_SPD_ENUM_DONE (1 << 6) /*ENUM Speed Completed*/ ++#define REG_INTR_SOF_RX (1 << 5) /*SOF Token Detected */ ++#define REG_INTR_BUS_SUSPEND (1 << 4) /*SUSPEND State Detected*/ ++#define REG_INTR_BUS_RESET (1 << 3) /*RESET State Detected */ ++#define REG_INTR_BUS_IDLE (1 << 2) /*IDLE State Detected*/ ++#define REG_INTR_SET_INTF_RX (1 << 1) /*Received SET_INTERFACE CMD*/ ++#define REG_INTR_SET_CFG_RX (1 << 0) /*Received SET_CONFIG CMD*/ ++ ++/* DMA Descriptor definitions */ ++#define REG_DMA_STAT_BUF_SHIFT 30 ++#define REG_DMA_STAT_BUF_HOST_READY (0 << REG_DMA_STAT_BUF_SHIFT) ++#define REG_DMA_STAT_BUF_DMA_BUSY (1 << REG_DMA_STAT_BUF_SHIFT) ++#define REG_DMA_STAT_BUF_DMA_DONE (2 << REG_DMA_STAT_BUF_SHIFT) ++#define REG_DMA_STAT_BUF_HOST_BUSY (3 << REG_DMA_STAT_BUF_SHIFT) ++#define REG_DMA_STAT_BUF_MASK (3 << REG_DMA_STAT_BUF_SHIFT) ++#define REG_DMA_STAT_RX_SHIFT 28 ++#define REG_DMA_STAT_RX_SUCCESS (0 << REG_DMA_STAT_RX_SHIFT) ++#define REG_DMA_STAT_RX_ERR_DESC (1 << REG_DMA_STAT_RX_SHIFT) ++#define REG_DMA_STAT_RX_ERR_BUF (3 << REG_DMA_STAT_RX_SHIFT) ++#define REG_DMA_STAT_RX_MASK (3 << REG_DMA_STAT_RX_SHIFT) ++#define REG_DMA_STAT_CFG_NUM_SHIFT 24 ++#define REG_DMA_STAT_CFG_NUM_MASK (0xf << REG_DMA_STAT_CFG_NUM_SHIFT) ++#define REG_DMA_STAT_INTF_NUM_SHIFT 20 ++#define REG_DMA_STAT_INTF_NUM_MASK (0xf << REG_DMA_STAT_INTF_NUM_SHIFT) ++#define REG_DMA_STAT_ALT_NUM_SHIFT 16 ++#define REG_DMA_STAT_ALT_NUM_MASK (0xf << REG_DMA_STAT_ALT_NUM_SHIFT) ++#define REG_DMA_STAT_LAST_DESC (1 << 27) ++#define REG_DMA_STAT_FRAME_NUM_SHIFT 16 ++#define REG_DMA_STAT_FRAME_NUM_MASK (0x7ff << REG_DMA_STAT_FRAME_NUM_SHIFT) ++#define REG_DMA_STAT_BYTE_CNT_SHIFT 0 ++#define REG_DMA_STAT_ISO_PID_SHIFT 14 ++#define REG_DMA_STAT_ISO_PID_MASK (0x3 << REG_DMA_STAT_ISO_PID_SHIFT) ++#define REG_DMA_STAT_ISO_BYTE_CNT_SHIFT REG_DMA_STAT_BYTE_CNT_SHIFT ++#define REG_DMA_STAT_ISO_BYTE_CNT_MASK (0x3fff << REG_DMA_STAT_ISO_BYTE_CNT_SHIFT) ++#define REG_DMA_STAT_NON_ISO_BYTE_CNT_SHIFT REG_DMA_STAT_BYTE_CNT_SHIFT ++#define REG_DMA_STAT_NON_ISO_BYTE_CNT_MASK (0xffff << REG_DMA_STAT_NON_ISO_BYTE_CNT_SHIFT) ++ ++/* USB2D IDM definitions */ ++#define IPROC_USB2D_IDM_REG_IO_CTRL_DIRECT_CLK_ENABLE (1 << 0) ++#define IPROC_USB2D_IDM_REG_RESET_CTRL_RESET (1 << 0) ++ ++/* Inline Function Definitions */ ++static inline uint ++usbd_reg32_read(volatile uint *reg) ++{ ++ return (le32_to_cpu(*reg)); ++} ++ ++static inline void usbd_reg32_write(volatile uint *reg, uint value) ++{ ++ *reg = cpu_to_le32(value); ++} ++ ++static inline void usbd_reg32_bits_set(volatile uint *reg, uint bits) ++{ ++ uint tmp; ++ tmp = usbd_reg32_read(reg); ++ tmp |= bits; ++ usbd_reg32_write(reg, tmp); ++} ++ ++static inline void usbd_reg32_bits_clear(volatile uint *reg, uint bits) ++{ ++ uint tmp; ++ tmp = usbd_reg32_read(reg); ++ tmp &= ~bits; ++ usbd_reg32_write(reg, tmp); ++} ++ ++static inline void usbd_reg32_bits_modify(volatile uint *reg, uint mask, uint value) ++{ ++ uint tmp; ++ tmp = usbd_reg32_read(reg); ++ tmp &= ~mask; ++ tmp |= value; ++ usbd_reg32_write(reg, tmp); ++} ++ ++#define IPROC_USBD_READ(_r) usbd_reg32_read(&_r) ++#define IPROC_USBD_WRITE(_r, _v) usbd_reg32_write(&_r, _v) ++#define IPROC_USBD_BITS_SET(_r, _b) usbd_reg32_bits_set(&_r, _b) ++#define IPROC_USBD_BITS_CLEAR(_r, _b) usbd_reg32_bits_clear(&_r, _b) ++#define IPROC_USBD_BITS_MODIFY(_r, _m, _v) usbd_reg32_bits_modify(&_r, _m, _v) ++ ++/***************************************************************************** ++* @brief Connect / Disconnect to USB BUS ++*****************************************************************************/ ++static inline void iproc_usbd_bus_conn(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, REG_CTRL_DISCONNECT_ENABLE); ++} ++ ++static inline void iproc_usbd_bus_disconn(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_ctrl, REG_CTRL_DISCONNECT_ENABLE); ++} ++ ++/***************************************************************************** ++* @brief USB BUS suspend status ++* @return ++* true : BUS is in suspend state ++* false : BUS is not in suspend state ++*****************************************************************************/ ++static inline bool iproc_usbd_bus_suspend(struct iproc_usbd_regs *base) ++{ ++ return (IPROC_USBD_READ(base->dev_status) & REG_STAT_BUS_SUSPENDED) ? true : false; ++} ++ ++/***************************************************************************** ++* @brief Retrieve setting numbers from last Rx'd SET_CONFIGURATION or ++* SET_INTERFACE request ++* @return ++* Setting Number ++*****************************************************************************/ ++static inline uint iproc_usbd_alt_num(struct iproc_usbd_regs *base) ++{ ++ return ((IPROC_USBD_READ(base->dev_status) & REG_STAT_ALT_NUM_MASK) >> REG_STAT_ALT_NUM_SHIFT); ++} ++ ++static inline uint iproc_usbd_cfg_num(struct iproc_usbd_regs *base) ++{ ++ return ((IPROC_USBD_READ(base->dev_status) & REG_STAT_CFG_NUM_MASK) >> REG_STAT_CFG_NUM_SHIFT); ++} ++ ++static inline uint iproc_usbd_intf_num(struct iproc_usbd_regs *base) ++{ ++ return ((IPROC_USBD_READ(base->dev_status) & REG_STAT_INTF_NUM_MASK) >> REG_STAT_INTF_NUM_SHIFT); ++} ++ ++ ++/***************************************************************************** ++* @brief Disable / Enable DMA operations at the device level (all endpoints) ++*****************************************************************************/ ++static inline void iproc_usbd_dma_dis(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, (REG_CTRL_DMA_IN_ENABLE | REG_CTRL_DMA_OUT_ENABLE)); ++} ++ ++static inline void iproc_usbd_dma_en(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_ctrl, (REG_CTRL_DMA_IN_ENABLE | REG_CTRL_DMA_OUT_ENABLE)); ++} ++ ++static inline bool iproc_usbd_dma_status(struct iproc_usbd_regs *base) ++{ ++ return (IPROC_USBD_READ(base->dev_ctrl) & REG_CTRL_DMA_OUT_ENABLE ? true : false); ++} ++ ++/***************************************************************************** ++* @brief Retrieve Frame number contained in last Rx'd SOF packet ++* @return ++* Frame Number in the following format. ++* bits[13:3] milli-second frame number ++* bits[2:0] micro-frame number ++* @note ++* For full and low speed connections, the microframe number will be zero. ++*****************************************************************************/ ++static inline uint iproc_usbd_last_rx_frame_num(struct iproc_usbd_regs *base) ++{ ++ return((IPROC_USBD_READ(base->dev_status) & REG_STAT_SOF_FRAME_NUM_MASK) >> REG_STAT_SOF_FRAME_NUM_SHIFT); ++} ++ ++/***************************************************************************** ++* @brief Device level interrupt operations ++* @note ++* Use the USBD_IRQ_xxx definitions with these routines. These ++* definitions are bit-wise, and allow operations on multiple interrupts ++* by OR'ing the definitions together. ++* DeviceIrqClear(), DeviceIrqDisable(), DeviceIrqEnable() use their mask ++* parameter to operate only on the interrupts set in the mask. E.g. ++* DeviceIrqEnable( DEVICE_IRQ_SET_INTF ); ++* DeviceIrqEnable( DEVICE_IRQ_SET_CFG ); ++* and ++* DeviceIrqEnable( DEVICE_IRQ_SET_INTF | DEVICE_IRQ_SET_CFG ); ++* are equivalent. ++* DeviceIrqMask() returns a mask of all the interrupts that are enabled. ++* DeviceIrqStatus() returns a mask of all the interrupts that have an active status. ++*****************************************************************************/ ++static inline uint iproc_usbd_irq_active(struct iproc_usbd_regs *base) ++{ ++ return(IPROC_USBD_READ(base->dev_irq_status)); ++} ++ ++static inline void iproc_usbd_irq_clear(struct iproc_usbd_regs *base, uint mask) ++{ ++ IPROC_USBD_WRITE(base->dev_irq_status, mask); ++} ++ ++static inline void iproc_usbd_irq_dis(struct iproc_usbd_regs *base, uint mask) ++{ ++ IPROC_USBD_BITS_SET(base->dev_irq_mask, mask); ++} ++ ++static inline void iproc_usbd_irq_en(struct iproc_usbd_regs *base, uint mask) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_irq_mask, mask); ++} ++static inline uint iproc_usbd_irq_mask(struct iproc_usbd_regs *base) ++{ ++ return((~IPROC_USBD_READ(base->dev_irq_mask)) & USBD_IRQ_ALL); ++} ++ ++/***************************************************************************** ++* @brief Disable / Enable NAK responses for all OUT endpoints. ++*****************************************************************************/ ++static inline void iproc_usbd_nak_response_dis(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, REG_CTRL_OUT_NAK_ALL_ENABLE); ++} ++ ++static inline void iproc_usbd_nak_response_en(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_ctrl, REG_CTRL_OUT_NAK_ALL_ENABLE); ++} ++ ++/***************************************************************************** ++* @brief PHY error detected ++*****************************************************************************/ ++static inline bool iproc_usbd_phy_err_detect(struct iproc_usbd_regs *base) ++{ ++ return(IPROC_USBD_READ(base->dev_status) & REG_STAT_PHY_ERROR ? true : false); ++} ++ ++/***************************************************************************** ++* @brief Remote Wakeup operations. ++* DeviceRemoteWakeupEnable() and DeviceRemoteWakeupDisable() are used to ++* specify device if is going to attempt this. ++* DeviceRemoteWakeupAllowed() indicates if host has enabled this feature. ++* The associated DEVICE_IRQ_REMOTEWAKEUP_DELTA can be used to determine ++* changes to the status of this feature. ++* DeviceRemoteWakeupStart(); delayMsec(1); DeviceRemoteWakeupStop(); is ++* used for controlling the wakeup signalling. ++*****************************************************************************/ ++static inline bool iproc_usbd_wakeup_allow(struct iproc_usbd_regs *base) ++{ ++ return(IPROC_USBD_READ(base->dev_status) & REG_STAT_REMOTE_WAKEUP_ALLOWED ? true : false); ++} ++ ++static inline void iproc_usbd_wakeup_dis(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_cfg, REG_CFG_REMOTE_WAKEUP_ENABLE); ++} ++ ++static inline void iproc_usbd_wakeup_en(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_cfg, REG_CFG_REMOTE_WAKEUP_ENABLE); ++} ++ ++static inline void iproc_usbd_wakeup_start(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_ctrl, REG_CTRL_RESUME_SIGNAL_ENABLE); ++} ++ ++static inline void iproc_usbd_wakeup_stop(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, REG_CTRL_RESUME_SIGNAL_ENABLE); ++} ++ ++/***************************************************************************** ++* @brief Control whether or not device advertises itself as self-powered. ++*****************************************************************************/ ++static inline void iproc_usbd_self_pwr_dis(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_cfg, REG_CFG_SELF_PWR_ENABLE); ++} ++ ++static inline void iproc_usbd_self_pwr_en(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_cfg, REG_CFG_SELF_PWR_ENABLE); ++} ++ ++/***************************************************************************** ++* @brief Control whether or not device SET DESCRIPTOR support is enabled. ++* If disabled, STALL will be issued upon receipt of a SET DESCRIPTOR request. ++*****************************************************************************/ ++static inline void iproc_usbd_set_desc_dis(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_cfg, REG_CFG_SET_DESCRIPTOR_ENABLE); ++} ++ ++static inline void iproc_usbd_set_desc_en(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_cfg, REG_CFG_SET_DESCRIPTOR_ENABLE); ++} ++ ++/***************************************************************************** ++* @brief Device SET configuration or SET interface has completed. ++* If disabled, STALL will be issued upon receipt of a SET DESCRIPTOR request. ++*****************************************************************************/ ++static inline void iproc_usbd_setup_done(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_ctrl, REG_CTRL_CSR_DONE); ++} ++ ++/***************************************************************************** ++* @brief Link speed routines. ++* Use the usbDevHw_DEVICE_SPEED_xxx definitions with these routines. These ++* DeviceSpeedRequested() indicates the desired link speed. ++* DeviceSpeedEnumerated() returns the speed negotiated with the host. ++* The associated DEVICE_IRQ_SPEED_ENUM_DONE can be used to determine ++* when speed negotiation has completed. ++*****************************************************************************/ ++static inline uint iproc_usbd_speed_get(struct iproc_usbd_regs *base) ++{ ++ switch(IPROC_USBD_READ(base->dev_status) & REG_STAT_SPD_MASK) { ++ case REG_STAT_SPD_LS: ++ return(USB_SPEED_LOW); ++ ++ case REG_STAT_SPD_HS: ++ return(USB_SPEED_HIGH); ++ ++ case REG_STAT_SPD_FS: ++ case REG_STAT_SPD_FS_48MHZ: ++ return(USB_SPEED_FULL); ++ } ++ ++ return USB_SPEED_FULL; ++} ++ ++static inline void iproc_usbd_speed_req(struct iproc_usbd_regs *base, uint speed) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_cfg, REG_CFG_SPD_MASK); ++ ++ switch(speed) { ++ case USB_SPEED_LOW: ++ IPROC_USBD_BITS_SET(base->dev_cfg, REG_CFG_SPD_LS); ++ break; ++ ++ case USB_SPEED_HIGH: ++ IPROC_USBD_BITS_SET(base->dev_cfg, REG_CFG_SPD_HS); ++ break; ++ ++ case USB_SPEED_FULL: ++ default: ++ IPROC_USBD_BITS_SET(base->dev_cfg, REG_CFG_SPD_FS); ++ break; ++ } ++} ++ ++/***************************************************************************** ++* @brief Finalize (terminate) / Initialize Endpoint operations ++* @param num - Endpoint number ++* @param dirn - Endpoint direction. See ENDPT_DIRN_xxx definitions ++* @param dirn - Endpoint type. See ENDPT_TYPE_xxx definitions ++* @param dirn - Endpoint max packet size. ++*****************************************************************************/ ++static inline void iproc_usbd_ep_ops_finish(struct iproc_usbd_regs *base, uint num) ++{ ++} ++ ++static inline void iproc_usbd_ep_ops_init(struct iproc_usbd_regs *base, uint num, uint type, uint dirn, uint maxPktSize) ++{ ++ if ((type == USB_ENDPOINT_XFER_CONTROL) || (dirn == USB_DIR_OUT)) { ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].ctrl, (type << REG_EP_FIFO_CTRL_TYPE_SHIFT)); ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].status, IPROC_USBD_READ(base->ep_fifo_out[num].status)); ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].size1, 0); ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].size2, ((maxPktSize >> 2) << 16) | maxPktSize); ++#if USBD_MULTI_RX_FIFO ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].size2, ((maxPktSize + 3) >> 2) << REG_EP_FIFO_SIZE2_OUT_DEPTH_SHIFT)); ++#endif ++ } ++ ++ if ((type == USB_ENDPOINT_XFER_CONTROL) || (dirn == USB_DIR_IN)) { ++ IPROC_USBD_WRITE(base->ep_fifo_in[num].ctrl, (type << REG_EP_FIFO_CTRL_TYPE_SHIFT)); ++ IPROC_USBD_WRITE(base->ep_fifo_in[num].size2, (maxPktSize << REG_EP_FIFO_SIZE2_PKT_MAX_SHIFT)); ++ IPROC_USBD_WRITE(base->ep_fifo_in[num].size1, (maxPktSize >> 2)); ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE); ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, (REG_EP_FIFO_CTRL_NAK_SET | REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE)); ++ } ++ ++ IPROC_USBD_WRITE(base->ep_cfg[num], (num << REG_EP_CFG_FIFO_NUM_SHIFT) | ++ (type << REG_EP_CFG_TYPE_SHIFT) | ++ (maxPktSize << REG_EP_CFG_PKT_MAX_SHIFT) | ++ (dirn == USB_DIR_OUT ? REG_EP_CFG_DIRN_OUT : REG_EP_CFG_DIRN_IN)); ++} ++ ++/***************************************************************************** ++* @brief Endpoint Configuration / Interface / Alternate number operations ++* @param num - Endpoint number ++* @param cfg - Configuration number ++* @param intf - Interface number ++* @param alt - Alternate number ++*****************************************************************************/ ++static inline void iproc_usbd_ep_alt_set(struct iproc_usbd_regs *base, uint num, uint alt) ++{ ++ IPROC_USBD_BITS_MODIFY(base->ep_cfg[num], REG_EP_CFG_ALT_NUM_MASK, (alt << REG_EP_CFG_ALT_NUM_SHIFT)); ++} ++ ++static inline void iproc_usbd_ep_cfg_set(struct iproc_usbd_regs *base, uint num, uint cfg) ++{ ++ IPROC_USBD_BITS_MODIFY(base->ep_cfg[num], REG_EP_CFG_CFG_NUM_MASK, (cfg << REG_EP_CFG_CFG_NUM_SHIFT)); ++} ++ ++static inline void iproc_usbd_ep_intf_set(struct iproc_usbd_regs *base, uint num, uint intf) ++{ ++ IPROC_USBD_BITS_MODIFY(base->ep_cfg[num], REG_EP_CFG_INTF_NUM_MASK, (intf << REG_EP_CFG_INTF_NUM_SHIFT)); ++} ++ ++ ++/***************************************************************************** ++* @brief Endpoint DMA routines ++* @param num - Endpoint number ++* @param addr - physical address of buffer or descriptor ++*****************************************************************************/ ++static inline void iproc_usbd_ep_dma_dis(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) { ++#if USBD_MULTI_RX_FIFO ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_OUT_DMA_ENABLE); ++#else ++ /* ++ * With a single RX FIFO, do not want to do anything, as there might be another OUT capable ++ * endpoint still active and wanting DMA enabled. If theory this should be OK, as long as ++ * the DMA descriptor buffer status fields are the last thing updated before being set to ++ * HOST ready, or the first thing updated when being set to HOST busy. Hopefully no ++ * situations arise such that there's contention with the hardware with doing this. ++ */ ++#endif ++ } else { ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_IN_DMA_ENABLE); ++ } ++} ++ ++static inline void iproc_usbd_ep_dma_en(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) { ++#if USBD_MULTI_RX_FIFO ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_OUT_DMA_ENABLE); ++#else ++ IPROC_USBD_BITS_SET(base->dev_ctrl, REG_CTRL_DMA_OUT_ENABLE); ++#endif ++ } else { ++ /* Set the Poll bit in the control register */ ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_IN_DMA_ENABLE); ++ } ++} ++ ++static inline void iproc_usbd_ep_dma_buf_addr_set(struct iproc_usbd_regs *base, uint num, uint dirn, void *addr) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].buf_addr, (uint)addr); ++} ++ ++static inline void iproc_usbd_ep_dma_desc_addr_set(struct iproc_usbd_regs *base, uint num, uint dirn, void *addr) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].desc_addr, (uint)addr); ++ else ++ IPROC_USBD_WRITE(base->ep_fifo_in[num].desc_addr, (uint)addr); ++} ++ ++/***************************************************************************** ++* @brief Endpoint FIFO routines ++* @param num - Endpoint number ++* @note The flush operation is a state. Once enabled, FIFO contents are discared ++* until disabled. Usually enable upon endpoint termination or error, and ++* then disable once operations are to resume normally. ++*****************************************************************************/ ++static inline bool iproc_usbd_ep_fifo_empty(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) { ++#if USBD_MULTI_RX_FIFO ++ return(base->ep_fifo_out[num].status & REG_EP_FIFO_STATUS_OUT_FIFO_EMPTY ? true : false); ++#else ++ return(base->dev_status & REG_STAT_OUT_FIFO_EMPTY ? true : false); ++#endif ++ } ++ ++ return(base->ep_fifo_in[num].status & REG_EP_FIFO_STATUS_IN_FIFO_EMPTY ? true : false); ++} ++ ++static inline void iproc_usbd_ep_fifo_flush_dis(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) { ++#if USBD_MULTI_RX_FIFO ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_OUT_FLUSH_ENABLE); ++#else ++ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, REG_CTRL_OUT_FIFO_FLUSH_ENABLE); ++#endif ++ } ++ else { ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE); ++ } ++} ++ ++static inline void iproc_usbd_ep_fifo_flush_en(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) { ++#if USBD_MULTI_RX_FIFO ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_OUT_FLUSH_ENABLE); ++#else ++ IPROC_USBD_BITS_SET(base->dev_ctrl, REG_CTRL_OUT_FIFO_FLUSH_ENABLE); ++#endif ++ } else { ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE); ++ } ++} ++ ++/***************************************************************************** ++* @brief Endpoint Frame Number routines ++* @param num - Endpoint number ++* @return Frame number of last packet received on the endpoint, and in the following format. ++* bits[13:3] milli-second frame number ++* bits[2:0] micro-frame number ++* @note Really only applicable to OUT endpoints. IN will always return 0. ++*****************************************************************************/ ++static inline uint iproc_usbd_ep_frame_num(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ return((IPROC_USBD_READ(base->ep_fifo_out[num].size1) & REG_EP_FIFO_SIZE1_OUT_FRAME_NUM_MASK) >> ++ REG_EP_FIFO_SIZE1_OUT_FRAME_NUM_SHIFT); ++ ++ return(0); ++} ++ ++/***************************************************************************** ++* @brief Endpoint IRQ / status routines ++* @param num - Endpoint number ++* @note ++* Cannot set specific status for Endpoint interrupts. Can only do operations ++* in a global sense. Once an interrupt occurs for an endpoint, the endpoint ++* status has to be checked for the particular type of interrupt that occurred. ++* ++* The iproc_usbd_ep_irq_en() and iproc_usbd_ep_irq_dis() are used for ++* operations on a specific endpoint. These routines may or may not be used in ++* the context of interrupt processing. ++* ++* Use the usbDevHw_EndptIrqListXxx() routines for operations using a bit-wise ++* list of endpoints (bit 0 for endpoint 0, etc.). Typical use would be for ++* interrupt processing. ++* ++* Use the USBD_EP_STAT_xxx definitions with the status routines. These ++* definitions are bit-wise, and allow operations on multiple conditions ++* by OR'ing the definitions together. ++*****************************************************************************/ ++static inline void iproc_usbd_ep_irq_clear(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_WRITE(base->ep_irq_status, (1 << num) << REG_EP_INTR_OUT_SHIFT); ++ else ++ IPROC_USBD_WRITE(base->ep_irq_status, (1 << num) << REG_EP_INTR_IN_SHIFT); ++} ++ ++static inline void iproc_usbd_ep_irq_dis(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_BITS_SET(base->ep_irq_mask, ((1 << num) << REG_EP_INTR_OUT_SHIFT)); ++ else ++ IPROC_USBD_BITS_SET(base->ep_irq_mask, ((1 << num) << REG_EP_INTR_IN_SHIFT)); ++} ++ ++static inline void iproc_usbd_ep_irq_en(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_BITS_CLEAR(base->ep_irq_mask, ((1 << num) << REG_EP_INTR_OUT_SHIFT)); ++ else ++ IPROC_USBD_BITS_CLEAR(base->ep_irq_mask, ((1 << num) << REG_EP_INTR_IN_SHIFT)); ++} ++ ++static inline uint iproc_usbd_ep_irq_list_active(struct iproc_usbd_regs *base, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ return((IPROC_USBD_READ(base->ep_irq_status) & REG_EP_INTR_OUT_MASK) >> REG_EP_INTR_OUT_SHIFT); ++ ++ return((IPROC_USBD_READ(base->ep_irq_status) & REG_EP_INTR_IN_MASK) >> REG_EP_INTR_IN_SHIFT); ++} ++ ++static inline void iproc_usbd_ep_irq_list_clear(struct iproc_usbd_regs *base, uint dirn, uint mask) ++{ ++ if (dirn == USB_DIR_OUT) /*strat from bit 16 */ ++ IPROC_USBD_WRITE(base->ep_irq_status, (mask << REG_EP_INTR_OUT_SHIFT)); ++ else /* start from bit 0 */ ++ IPROC_USBD_WRITE(base->ep_irq_status, (mask << REG_EP_INTR_IN_SHIFT)); ++} ++ ++static inline uint iproc_usbd_ep_stat_active(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) /* End Point Status register */ ++ return(IPROC_USBD_READ(base->ep_fifo_out[num].status)); ++ ++ return(IPROC_USBD_READ(base->ep_fifo_in[num].status)); ++} ++ ++static inline void iproc_usbd_ep_stat_clear(struct iproc_usbd_regs *base, uint num, uint dirn, uint mask) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].status, mask); ++ else ++ IPROC_USBD_WRITE(base->ep_fifo_in[num].status, mask); ++} ++ ++/***************************************************************************** ++* @brief Endpoint NAK routines ++* @param num - Endpoint number ++* @note A NAK response can be enabled by the application by the EndptNakEnable(). ++* The EndptNakInProgress() is used to determine if the controller is ++* currently actively sending NAKs. This may have been a result of the ++* EndptNakEnable() or automatically by the controller under certain ++* conditions. The EndptNakClear() must be used to terminate the NAKs. ++*****************************************************************************/ ++static inline void iproc_usbd_ep_nak_clear(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_NAK_CLEAR); ++ else ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_NAK_CLEAR); ++} ++ ++static inline void iproc_usbd_ep_nak_en(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_NAK_SET); ++ else ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_NAK_SET); ++} ++ ++static inline void iproc_usbd_ep_nak_dis(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_NAK_SET); ++ else ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_NAK_SET); ++} ++ ++static inline bool iproc_usbd_ep_nak_progress(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ return (IPROC_USBD_READ(base->ep_fifo_out[num].ctrl) & REG_EP_FIFO_CTRL_NAK_IN_PROGRESS) ? true : false; ++ ++ return (IPROC_USBD_READ(base->ep_fifo_in[num].ctrl) & REG_EP_FIFO_CTRL_NAK_IN_PROGRESS) ? true : false; ++} ++ ++/***************************************************************************** ++* @brief Endpoint Stall routines ++* Disable / Enable STALL responses (halt feature) on a given endpoint. ++* @param num - Endpoint number ++*****************************************************************************/ ++static inline void iproc_usbd_ep_stall_dis(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_STALL_ENABLE); ++ else ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_STALL_ENABLE); ++} ++ ++static inline void iproc_usbd_ep_stall_en(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++#if USBD_MULTI_RX_FIFO ++ if (!(IPROC_USBD_READ(base->ep_fifo_out[num].status) & REG_EP_FIFO_STATUS_OUT_FIFO_EMPTY)) ++#else ++ if (!(IPROC_USBD_READ(base->dev_status) & REG_STAT_OUT_FIFO_EMPTY)) ++#endif ++ return; ++ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_STALL_ENABLE); ++ else ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_STALL_ENABLE); ++} ++ ++ ++/***************************************************************************** ++* @brief Initialize device controller operations ++*****************************************************************************/ ++static inline void iproc_usbd_ops_init(struct iproc_usbd_regs *base) ++{ ++ int idx; ++ ++ iproc_usbd_dma_dis(base); ++ iproc_usbd_irq_dis(base, USBD_IRQ_ALL); ++ iproc_usbd_irq_clear(base, USBD_IRQ_ALL); ++ ++ /* @todo Create and use usbDevHw_EndptIrqListDisable?? */ ++ for (idx = 0; idx < USBD_EP_CFG_CNT; idx++) { ++ iproc_usbd_ep_irq_dis(base, idx, USB_DIR_IN); ++ iproc_usbd_ep_irq_clear(base, idx, USB_DIR_IN); ++ iproc_usbd_ep_stat_clear(base, idx, USB_DIR_IN, ++ iproc_usbd_ep_stat_active(base, idx, USB_DIR_IN)); ++ ++ iproc_usbd_ep_irq_dis(base, idx, USB_DIR_OUT); ++ iproc_usbd_ep_irq_clear(base, idx, USB_DIR_OUT); ++ iproc_usbd_ep_stat_clear(base, idx, USB_DIR_OUT, ++ iproc_usbd_ep_stat_active(base, idx, USB_DIR_OUT)); ++ } ++ ++ IPROC_USBD_WRITE(base->dev_cfg, (REG_CFG_SET_DESCRIPTOR_ENABLE | ++ REG_CFG_UTMI_8BIT_ENABLE | ++ REG_CFG_CSR_PROGRAM_ENABLE | ++ REG_CFG_SPD_HS)); ++ ++ IPROC_USBD_WRITE(base->dev_ctrl, (REG_CTRL_LE_ENABLE | ++ REG_CTRL_DISCONNECT_ENABLE | ++ REG_CTRL_DMA_MODE_ENABLE | ++ REG_CTRL_DMA_IN_ENABLE | ++ REG_CTRL_DMA_OUT_ENABLE | ++ REG_CTRL_DMA_DESC_UPDATE_ENABLE | ++ REG_CTRL_OUT_NAK_ALL_ENABLE | ++ REG_CTRL_DMA_OUT_THRESHOLD_LEN_MASK | ++ REG_CTRL_DMA_BURST_LEN_MASK | ++#if !USBD_MULTI_RX_FIFO ++ REG_CTRL_OUT_FIFO_FLUSH_ENABLE | ++#endif ++ REG_CTRL_DMA_BURST_ENABLE)); ++ ++ IPROC_USBD_WRITE(base->dev_irq_mask, (REG_INTR_BUS_IDLE | REG_INTR_SOF_RX)); ++ IPROC_USBD_WRITE(base->ep_irq_mask,0); ++} ++ ++/***************************************************************************** ++* @brief Disable / Enable USB device ++*****************************************************************************/ ++static inline void iproc_usbd_dis(struct iproc_usbd_idm_regs *idm_base) ++{ ++ /* reset usb device */ ++ IPROC_USBD_BITS_SET(idm_base->reset_ctrl, IPROC_USB2D_IDM_REG_RESET_CTRL_RESET); ++ ++ /* disable usb device clock */ ++ IPROC_USBD_BITS_CLEAR(idm_base->io_ctrl, IPROC_USB2D_IDM_REG_IO_CTRL_DIRECT_CLK_ENABLE); ++ mdelay(10); ++} ++ ++static inline void iproc_usbd_en(struct iproc_usbd_idm_regs *idm_base) ++{ ++ /* enable usb device clock */ ++ IPROC_USBD_BITS_SET(idm_base->io_ctrl, IPROC_USB2D_IDM_REG_IO_CTRL_DIRECT_CLK_ENABLE); ++ mdelay(10); ++ ++ /* get usb device out of reset */ ++ IPROC_USBD_BITS_CLEAR(idm_base->reset_ctrl, IPROC_USB2D_IDM_REG_RESET_CTRL_RESET); ++ mdelay(100); ++} ++ ++#endif /* _USBD_REGS_H_ */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig +--- a/drivers/usb/host/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/host/Kconfig 2018-05-10 11:31:33.793404173 +0800 +@@ -214,6 +214,13 @@ config USB_EHCI_HCD_STI + Enable support for the on-chip EHCI controller found on + STMicroelectronics consumer electronics SoC's. + ++config USB_EHCI_XGS_IPROC ++ bool "BRCM XGS iProc EHCI patch" ++ depends on (ARCH_XGS_IPROC && USB_EHCI_HCD_PLATFORM) ++ default n ++ ---help--- ++ This option is for BRCM XGS iProc EHCI patch ++ + config USB_EHCI_HCD_AT91 + tristate "Support for Atmel on-chip EHCI USB controller" + depends on USB_EHCI_HCD && ARCH_AT91 +@@ -591,6 +598,13 @@ config USB_OHCI_HCD_PLATFORM + + If unsure, say N. + ++config USB_OHCI_XGS_IPROC ++ bool "BRCM XGS iProc OHCI patch" ++ depends on (ARCH_XGS_IPROC && USB_OHCI_HCD_PLATFORM) ++ default n ++ ---help--- ++ This option is for BRCM XGS iProc OHCI patch ++ + config USB_OCTEON_OHCI + bool "Octeon on-chip OHCI support (DEPRECATED)" + depends on CAVIUM_OCTEON_SOC +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c +--- a/drivers/usb/host/ehci-platform.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/host/ehci-platform.c 2018-05-10 11:31:33.793404173 +0800 +@@ -43,6 +43,12 @@ + #define EHCI_MAX_RSTS 4 + #define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv) + ++#if IS_ENABLED(CONFIG_USB_EHCI_XGS_IPROC) ++#include ++#include ++#define BCM_USB_FIFO_THRESHOLD 0x00800040 ++#endif ++ + struct ehci_platform_priv { + struct clk *clks[EHCI_MAX_CLKS]; + struct reset_control *rsts[EHCI_MAX_RSTS]; +@@ -152,10 +158,24 @@ static int ehci_platform_probe(struct pl + struct ehci_platform_priv *priv; + struct ehci_hcd *ehci; + int err, irq, phy_num, clk = 0, rst; ++ struct usb_phy __maybe_unused *phy; + + if (usb_disabled()) + return -ENODEV; + ++ if (IS_ENABLED(CONFIG_USB_EHCI_XGS_IPROC)) { ++ phy = devm_usb_get_phy_by_phandle(&dev->dev, "usb-phy", 0); ++ if (IS_ERR(phy)) { ++ dev_err(&dev->dev, "unable to find transceiver\n"); ++ return PTR_ERR(phy); ++ } ++ ++ if (phy->flags != IPROC_USB_MODE_HOST) ++ return -ENODEV; ++ ++ usb_phy_init(phy); ++ } ++ + /* + * Use reasonable defaults so platforms don't have to provide these + * with DT probing on ARM. +@@ -296,12 +316,20 @@ static int ehci_platform_probe(struct pl + hcd->rsrc_start = res_mem->start; + hcd->rsrc_len = resource_size(res_mem); + ++ if (IS_ENABLED(CONFIG_USB_EHCI_XGS_IPROC)) ++ hcd->usb_phy = phy; ++ + err = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (err) + goto err_power; + + device_wakeup_enable(hcd->self.controller); + device_enable_async_suspend(hcd->self.controller); ++ ++ if (IS_ENABLED(CONFIG_USB_EHCI_XGS_IPROC)) ++ ehci_writel(ehci, BCM_USB_FIFO_THRESHOLD, ++ &ehci->regs->reserved4[6]); ++ + platform_set_drvdata(dev, hcd); + + return err; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c +--- a/drivers/usb/host/ohci-platform.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/host/ohci-platform.c 2018-05-10 11:31:33.805404187 +0800 +@@ -37,6 +37,13 @@ + #define OHCI_MAX_RESETS 2 + #define hcd_to_ohci_priv(h) ((struct ohci_platform_priv *)hcd_to_ohci(h)->priv) + ++#if IS_ENABLED(CONFIG_USB_OHCI_XGS_IPROC) ++#include ++#include ++#define UHCRHDA_REG_OFFSET 0x48 ++#define UHCRHDA_OCPM BIT(11) ++#endif ++ + struct ohci_platform_priv { + struct clk *clks[OHCI_MAX_CLKS]; + struct reset_control *resets[OHCI_MAX_RESETS]; +@@ -120,10 +127,24 @@ static int ohci_platform_probe(struct pl + struct ohci_platform_priv *priv; + struct ohci_hcd *ohci; + int err, irq, phy_num, clk = 0, rst = 0; ++ struct usb_phy __maybe_unused *phy; + + if (usb_disabled()) + return -ENODEV; + ++ if (IS_ENABLED(CONFIG_USB_OHCI_XGS_IPROC)) { ++ phy = devm_usb_get_phy_by_phandle(&dev->dev, "usb-phy", 0); ++ if (IS_ERR(phy)) { ++ dev_err(&dev->dev, "unable to find transceiver\n"); ++ return PTR_ERR(phy); ++ } ++ ++ if (phy->flags != IPROC_USB_MODE_HOST) ++ return -ENODEV; ++ ++ usb_phy_init(phy); ++ } ++ + /* + * Use reasonable defaults so platforms don't have to provide these + * with DT probing on ARM. +@@ -264,6 +285,13 @@ static int ohci_platform_probe(struct pl + hcd->rsrc_start = res_mem->start; + hcd->rsrc_len = resource_size(res_mem); + ++ if (IS_ENABLED(CONFIG_USB_OHCI_XGS_IPROC)) { ++ if (of_find_property(dev->dev.of_node, "iproc-ocpm-fix", NULL)) ++ writel(readl(hcd->regs + UHCRHDA_REG_OFFSET) | ++ UHCRHDA_OCPM, hcd->regs + UHCRHDA_REG_OFFSET); ++ hcd->usb_phy = phy; ++ } ++ + err = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (err) + goto err_power; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig +--- a/drivers/usb/phy/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/phy/Kconfig 2018-05-10 11:31:33.833404217 +0800 +@@ -202,4 +202,18 @@ config USB_ULPI_VIEWPORT + Provides read/write operations to the ULPI phy register set for + controllers with a viewport register (e.g. Chipidea/ARC controllers). + ++config USBPHY_XGS_IPROC ++ tristate "BRCM iProc USB controller support" ++ depends on ARCH_XGS_IPROC ++ select USB_PHY ++ help ++ BRCM iProc USB controller support ++ ++config USB_XGS_IPROC_DRD ++ tristate "BRCM iProc USB DRD controller support" ++ depends on ARCH_XGS_IPROC ++ select USB_PHY ++ help ++ BRCM iProc USB DRD controller support ++ + endmenu +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile +--- a/drivers/usb/phy/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/phy/Makefile 2018-05-10 11:31:33.833404217 +0800 +@@ -26,3 +26,5 @@ obj-$(CONFIG_USB_MXS_PHY) += phy-mxs-us + obj-$(CONFIG_USB_ULPI) += phy-ulpi.o + obj-$(CONFIG_USB_ULPI_VIEWPORT) += phy-ulpi-viewport.o + obj-$(CONFIG_KEYSTONE_USB_PHY) += phy-keystone.o ++obj-$(CONFIG_USBPHY_XGS_IPROC) += phy-xgs-iproc.o ++obj-$(CONFIG_USB_XGS_IPROC_DRD) += phy-xgs-iproc-drd.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/phy/phy-xgs-iproc-drd.c b/drivers/usb/phy/phy-xgs-iproc-drd.c +--- a/drivers/usb/phy/phy-xgs-iproc-drd.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/usb/phy/phy-xgs-iproc-drd.c 2018-05-10 11:31:33.837404222 +0800 +@@ -0,0 +1,270 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define ICFG_USB_CTRL_ADDR(base) (base + 0x00) ++#define ICFG_USB_CTRL__DRD_FORCE_HOST_MODE 6 ++#define ICFG_USB_CTRL__DRD_FORCE_DEVICE_MODE 5 ++#define ICFG_USB_CTRL__XHC_CSR_RESET 4 ++#define ICFG_USB_CTRL__BDC_CSR_RESET 3 ++#define ICFG_USB_CTRL__DRD_SOFT_RESET 2 ++#define ICFG_USB_CTRL__XHC_SOFT_RESET 1 ++#define ICFG_USB_CTRL__BDC_SOFT_RESET 0 ++ ++#define IPROC_WRAP_USBPHY_CTRL_0_ADDR(base) (base + 0x00) ++#define IPROC_WRAP_USBPHY_CTRL_0__PHY_ISO 18 ++#define IPROC_WRAP_USBPHY_CTRL_0__PLL_CTRL_45 17 ++#define IPROC_WRAP_USBPHY_CTRL_0__PLL_SUSPEND_EN 16 ++#define IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB 15 ++#define IPROC_WRAP_USBPHY_CTRL_0__RESETB 14 ++#define IPROC_WRAP_USBPHY_CTRL_2_ADDR(base) (base + 0x08) ++#define IPROC_WRAP_USBPHY_CTRL_2__AFE_LDO_PWRDWNB 2 ++#define IPROC_WRAP_USBPHY_CTRL_2__AFE_PLL_PWRDWNB 1 ++#define IPROC_WRAP_USBPHY_CTRL_2__AFE_BG_PWRDWNB 0 ++#define IPROC_WRAP_MISC_STATUS_0_ADDR(base) (base + 0x1c) ++#define IPROC_WRAP_MISC_STATUS_0__USBPHY_PLL_LOCK 0 ++#define IPROC_WRAP_MISC_STATUS_1_ADDR(base) (base + 0x20) ++ ++struct iproc_usb_priv { ++ struct usb_phy phy; ++ struct device *dev; ++ struct device_node *dn; ++ void __iomem *wrap_base; ++ void __iomem *icfg_usb_base; ++}; ++ ++extern void __iomem *get_iproc_wrap_ctrl_base(void); ++ ++/*************************************************************************** ++**************************************************************************** ++***************************************************************************/ ++static int iproc_usb_phy_init(struct usb_phy *phy) ++{ ++ struct iproc_usb_priv *iproc_usb_data = container_of(phy, struct iproc_usb_priv, phy); ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ struct device *dev = iproc_usb_data->dev; ++ uint val; ++ ulong mask, count = 0; ++ ++ if (!wrap_base) { ++ return -EINVAL; ++ } ++ ++ /* FIXME. PHY initial sequence, need to get the sequence from DE */ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_0__PHY_ISO); ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_0__PLL_SUSPEND_EN); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB); ++ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_0__RESETB); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_2__AFE_BG_PWRDWNB); ++ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_2__AFE_LDO_PWRDWNB); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ udelay(10); ++ ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_2__AFE_BG_PWRDWNB); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ udelay(150); ++ ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_2__AFE_LDO_PWRDWNB); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ udelay(160); ++ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_0__PHY_ISO); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ udelay(20); ++ ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ mdelay(20); ++ ++ ++ /* check pll_lock */ ++ mask = (1 << IPROC_WRAP_MISC_STATUS_0__USBPHY_PLL_LOCK); ++ do { ++ val = readl_relaxed(IPROC_WRAP_MISC_STATUS_0_ADDR(wrap_base)); ++ if ((val & mask) == mask) { ++ break; ++ } else { ++ udelay(10); ++ count ++; ++ } ++ } while(count <= 10); ++ if (count > 10) { ++ dev_err(dev, "%s : PLL not lock! IPROC_WRAP_MISC_STATUS_0 = 0x%.8x\n", ++ __FUNCTION__, val); ++ } ++ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_0__RESETB); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ udelay(2); ++ ++ return 0; ++} ++ ++static int iproc_usb_reset(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *icfg_usb_base = iproc_usb_data->icfg_usb_base; ++ uint val; ++ ++ if (!icfg_usb_base) { ++ return -EINVAL; ++ } ++ ++ /* Put DRD into reset state */ ++ val = readl_relaxed(ICFG_USB_CTRL_ADDR(icfg_usb_base)); ++ val |= (1 << ICFG_USB_CTRL__DRD_SOFT_RESET); ++ writel_relaxed(val, ICFG_USB_CTRL_ADDR(icfg_usb_base)); ++ ++ /* Put BDC and XHC into reset state */ ++ val = readl_relaxed(ICFG_USB_CTRL_ADDR(icfg_usb_base)); ++ val |= (1 << ICFG_USB_CTRL__BDC_SOFT_RESET); ++ val |= (1 << ICFG_USB_CTRL__XHC_SOFT_RESET); ++ writel_relaxed(val, ICFG_USB_CTRL_ADDR(icfg_usb_base)); ++ ++ mdelay(10); ++ ++ /* Get the BDC and XHC out of reset */ ++ val = readl_relaxed(ICFG_USB_CTRL_ADDR(icfg_usb_base)); ++ val &= ~(1 << ICFG_USB_CTRL__BDC_SOFT_RESET); ++ val &= ~(1 << ICFG_USB_CTRL__XHC_SOFT_RESET); ++ writel_relaxed(val, ICFG_USB_CTRL_ADDR(icfg_usb_base)); ++ ++ /* Get the DRD out of reset */ ++ val = readl_relaxed(ICFG_USB_CTRL_ADDR(icfg_usb_base)); ++ val &= ~(1 << ICFG_USB_CTRL__DRD_SOFT_RESET); ++ writel_relaxed(val, ICFG_USB_CTRL_ADDR(icfg_usb_base)); ++ ++ return 0; ++} ++ ++static int xgs_iproc_drd_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *dn = pdev->dev.of_node; ++ struct iproc_usb_priv *iproc_usb_data; ++ int ret; ++ ++ if (!of_device_is_available(dn)) { ++ return -ENODEV; ++ } ++ ++ iproc_usb_data = devm_kzalloc(dev, sizeof(*iproc_usb_data), GFP_KERNEL); ++ if (!iproc_usb_data) { ++ dev_err(dev, "devm_kzalloc() failed\n" ); ++ return -ENOMEM; ++ } ++ memset(iproc_usb_data, 0, sizeof(*iproc_usb_data)); ++ platform_set_drvdata(pdev, iproc_usb_data); ++ ++ iproc_usb_data->dev = dev; ++ ++ iproc_usb_data->wrap_base = get_iproc_wrap_ctrl_base(); ++ if (!iproc_usb_data->wrap_base) { ++ dev_err(&pdev->dev, "can't iomap usb phy base address\n"); ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ iproc_usb_data->icfg_usb_base = (void *)of_iomap(dn, 1); ++ if (!iproc_usb_data->icfg_usb_base) { ++ dev_err(&pdev->dev, "can't iomap icfg usb base address\n"); ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ iproc_usb_data->phy.dev = dev; ++ iproc_usb_data->phy.type = USB_PHY_TYPE_USB2; ++ iproc_usb_data->phy.init = iproc_usb_phy_init; ++ ++ iproc_usb_reset(iproc_usb_data); ++ iproc_usb_phy_init(&iproc_usb_data->phy); ++ ++ ret = usb_add_phy_dev(&iproc_usb_data->phy); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to add the phy device\n"); ++ goto err; ++ } ++ ++ return 0; ++ ++err: ++ if (iproc_usb_data->icfg_usb_base) { ++ iounmap(iproc_usb_data->icfg_usb_base); ++ } ++ if (iproc_usb_data) { ++ iounmap(iproc_usb_data); ++ } ++ ++ return ret; ++} ++ ++static int xgs_iproc_drd_remove(struct platform_device *pdev) ++{ ++ struct iproc_usb_priv *iproc_usb_data = platform_get_drvdata(pdev); ++ ++ usb_remove_phy(&iproc_usb_data->phy); ++ ++ platform_set_drvdata(pdev, NULL); ++ if (iproc_usb_data->icfg_usb_base) { ++ iounmap(iproc_usb_data->icfg_usb_base); ++ } ++ ++ if (iproc_usb_data) { ++ iounmap(iproc_usb_data); ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id xgs_iproc_drd_dt_ids[] = { ++ { .compatible = "brcm,usb-phy,hx5", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, xgs_iproc_drd_dt_ids); ++ ++static struct platform_driver xgs_iproc_drd_driver = ++{ ++ .driver = { ++ .name = "usb-phy", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(xgs_iproc_drd_dt_ids), ++ }, ++ .probe = xgs_iproc_drd_probe, ++ .remove = xgs_iproc_drd_remove, ++}; ++ ++module_platform_driver(xgs_iproc_drd_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("Broadcom USB DRD controller driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/phy/phy-xgs-iproc.c b/drivers/usb/phy/phy-xgs-iproc.c +--- a/drivers/usb/phy/phy-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/usb/phy/phy-xgs-iproc.c 2018-05-10 11:31:33.837404222 +0800 +@@ -0,0 +1,701 @@ ++/* ++ * Copyright 2017 Broadcom Limited ++ * ++ * 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. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define USB2_IDM_IO_CONTROL_DIRECT_ADDR(base) (base + 0x408) ++#define USB2_IDM_RESET_CONTROL_ADDR(base) (base + 0x800) ++#define IPROC_WRAP_MISC_STATUS__USBPHY_PLL_LOCK BIT(1) ++#define USB2_IDM_RESET_CONTROL__RESET BIT(0) ++#define USB2_IDM_IO_CONTROL_DIRECT__clk_enable BIT(0) ++ ++/* HX4 */ ++#define HX4_WRAP_XGPLL_CTRL_0_ADDR(base) (base + 0x1c) ++#define HX4_WRAP_XGPLL_CTRL_4_ADDR(base) (base + 0x2c) ++#define HX4_WRAP_USBPHY_CTRL_ADDR(base) (base + 0x34) ++#define HX4_WRAP_MISC_STATUS_ADDR(base) (base + 0x38) ++#define IPROC_CLK_NDIV_40 0x80 ++#define IPROC_CLK_NDIV_20 0x8C ++#define USB_CLK_NDIV_MASK 0xFE7FFE00 ++#define USB_CLK_PLL_RESET_MASK 0xFF7FFE00 ++#define USB_CLK_PHY_RESET_MASK 0xFFFFFE00 ++#define USB_CLK_NDIV_40 0x30 ++#define USB_CLK_NDIV_20 0x60 ++#define HX4_XGPLL_CTRL_4__NDIV_INT_R 0 ++#define HX4_XGPLL_CTRL_4__NDIV_INT_WIDTH 8 ++#define HX4_XGPLL_CTRL_0__CH3_MDIV_R 8 ++#define HX4_XGPLL_CTRL_0__CH3_MDIV_WIDTH 8 ++ ++/* KT2 */ ++#define KT2_PLL_CTRL_REG_3_ADDR(base) (base + 0x0c) ++#define KT2_PLL_CTRL_REG_5_ADDR(base) (base + 0x14) ++#define KT2_WRAP_USBPHY_CTRL_ADDR(base) (base + 0x20) ++#define KT2_WRAP_MISC_STATUS_ADDR(base) (base + 0x28) ++#define KT2_PLL_CTRL_REG_3__NDIV_INT_R 0 ++#define KT2_PLL_CTRL_REG_3__NDIV_INT_WIDTH 10 ++#define KT2_PLL_CTRL_REG_5__CH1_MDIV_R 0 ++#define KT2_PLL_CTRL_REG_5__CH1_MDIV_WIDTH 8 ++ ++/* SB2/GH/GH2/HR3 */ ++#define IPROC_WRAP_USBPHY_CTRL_0__PHY_IDDQ BIT(26) ++#define IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB BIT(25) ++#define IPROC_WRAP_USBPHY_CTRL_0__RESETB BIT(24) ++#define IPROC_WRAP_USBPHY_CTRL_2__PHY_ISO BIT(17) ++#define IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B0 BIT(0) ++#define IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B11 BIT(11) ++ ++/* SB2 */ ++#define SB2_WRAP_USBPHY_CTRL_0_ADDR(base) (base + 0x28) ++#define SB2_WRAP_USBPHY_CTRL_2_ADDR(base) (base + 0x30) ++#define SB2_WRAP_MISC_STATUS_ADDR(base) (base + 0x44) ++#define IPROC_WRAP_TOP_STRAP_CTRL_ADDR(base) (base + 0x70) ++#define IPROC_WRAP_TOP_STRAP_CTRL__USB_DEVICE BIT(10) ++ ++/* GH/GH2/HR3 */ ++#define GH_WRAP_USBPHY_CTRL_0_ADDR(base) (base + 0x44) ++#define GH_WRAP_USBPHY_CTRL_2_ADDR(base) (base + 0x4c) ++#define GH_WRAP_MISC_STATUS_ADDR(base) (base + 0x58) ++#define IPROC_WRAP_TOP_STRAP_STATUS_ADDR(base) (base + 0xa4) ++#define IPROC_WRAP_TOP_STRAP_STATUS__USB2_SEL BIT(17) ++ ++/* GH2 */ ++#define USBH_Utmi_p0Ctl(base) (base + 0x10) ++ ++ ++struct iproc_usb_priv { ++ struct usb_phy phy; ++ struct phy_device *mdio_phy; ++ void __iomem *wrap_base; ++ void __iomem *idm_base; ++ void __iomem *utmi_base; ++ int usb_mode; ++ int init_count; ++}; ++ ++extern void __iomem *get_iproc_wrap_ctrl_base(void); ++extern void xgs_phy_wr_reg(struct phy_device *phydev, u32 regnum, u16 data); ++extern u16 xgs_phy_rd_reg(struct phy_device *phydev, u32 regnum); ++extern void xgs_sb2_usb_phy_wr_reg(struct phy_device *phydev, u32 regnum, ++ u16 data); ++ ++/*************************************************************************** ++**************************************************************************** ++***************************************************************************/ ++ ++ ++/* check pll_lock */ ++static bool check_usbphy_pll_lock(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ void __iomem *wrap_addr = NULL; ++ struct device_node *dn = iproc_usb_data->phy.dev->of_node; ++ u32 val=0, mask; ++ u32 count = 0; ++ ++ if (of_device_is_compatible(dn, "brcm,usb-phy-hx4")) ++ wrap_addr = HX4_WRAP_MISC_STATUS_ADDR(wrap_base); ++ else if (of_device_is_compatible(dn, "brcm,usb-phy-kt2")) ++ wrap_addr = KT2_WRAP_MISC_STATUS_ADDR(wrap_base); ++ else if (of_device_is_compatible(dn, "brcm,usb-phy-sb2")) ++ wrap_addr = SB2_WRAP_MISC_STATUS_ADDR(wrap_base); ++ else if (of_device_is_compatible(dn, "brcm,usb-phy-gh") || ++ of_device_is_compatible(dn, "brcm,usb-phy-hr3") || ++ of_device_is_compatible(dn, "brcm,usb-phy-gh2")) ++ wrap_addr = GH_WRAP_MISC_STATUS_ADDR(wrap_base); ++ ++ if (!wrap_addr) { ++ dev_warn(iproc_usb_data->phy.dev, "No wrap addr specified\n"); ++ return 0; ++ } ++ ++ mask = IPROC_WRAP_MISC_STATUS__USBPHY_PLL_LOCK; ++ do { ++ val = readl(wrap_addr); ++ if ((val & mask) == mask) ++ break; ++ ++ udelay(10); ++ count ++; ++ } while(count <= 10); ++ ++ if (count <= 10) ++ return 1; ++ ++ dev_warn(iproc_usb_data->phy.dev, ++ "PLL not locked: IPROC_WRAP_MISC_STATUS = %x\n", val); ++ return 0; ++} ++ ++static int xgs_iproc_usb_phy_mode(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ struct device *dev = iproc_usb_data->phy.dev; ++ struct device_node *dn = dev->of_node; ++ int usb_mode = IPROC_USB_MODE_HOST; ++ u32 __maybe_unused val; ++ int __maybe_unused gpio_pin, ret; ++ ++ if (!wrap_base) ++ dev_warn(dev, "no wrap base addr"); ++ ++ if (of_device_is_compatible(dn, "brcm,usb-phy-hx4") || ++ of_device_is_compatible(dn, "brcm,usb-phy-kt2")) { ++ /* gpio pin 4 to control host/device mode */ ++ gpio_pin = of_get_named_gpio(dev->of_node, "usbdev-gpio", 0); ++ ++ if (gpio_pin < 0) { ++ /* default to 4 */ ++ dev_warn(dev, "No gpio pin set for USB device detection\n"); ++ gpio_pin = 4; ++ } ++ ++ ret = devm_gpio_request(dev, gpio_pin, "usbdev-gpio"); ++ if (ret) { ++ dev_warn(dev, "request gpio #%d fail\n", gpio_pin); ++ /* Use default host mode */ ++ return usb_mode; ++ } ++ ++ gpio_direction_input(gpio_pin); ++ val = gpio_get_value(gpio_pin); ++ if (val) ++ usb_mode = IPROC_USB_MODE_DEVICE; ++ ++ devm_gpio_free(dev, gpio_pin); ++ } else if (of_device_is_compatible(dn, "brcm,usb-phy-sb2")) { ++ /* u-boot enable this bit to indicate usb in host mode */ ++ val = readl(IPROC_WRAP_TOP_STRAP_CTRL_ADDR(wrap_base)); ++ if (!(val & IPROC_WRAP_TOP_STRAP_CTRL__USB_DEVICE)) ++ usb_mode = IPROC_USB_MODE_DEVICE; ++ } else if (of_device_is_compatible(dn, "brcm,usb-phy-gh") || ++ of_device_is_compatible(dn, "brcm,usb-phy-hr3") || ++ of_device_is_compatible(dn, "brcm,usb-phy-gh2")) { ++ /* u-boot enable this bit to indicate usb in host mode */ ++ val = readl(IPROC_WRAP_TOP_STRAP_STATUS_ADDR(wrap_base)); ++ if (!(val & IPROC_WRAP_TOP_STRAP_STATUS__USB2_SEL)) ++ usb_mode = IPROC_USB_MODE_DEVICE; ++ } ++ ++ dev_info(dev, "usb mode: %s\n", ++ usb_mode == IPROC_USB_MODE_DEVICE ? "DEVICE" : "HOST"); ++ ++ return usb_mode; ++} ++ ++/* Returns USB PHY PLL ref clock in MHz for HX4/KT2 */ ++static u32 _get_usb_clk(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ struct device_node *dn = iproc_usb_data->phy.dev->of_node; ++ u32 ndiv, mdiv, refclk; ++ u32 val; ++ ++ if (of_device_is_compatible(dn, "brcm,usb-phy-hx4")) { ++ val = readl(HX4_WRAP_XGPLL_CTRL_4_ADDR(wrap_base)); ++ ndiv = ((val >> HX4_XGPLL_CTRL_4__NDIV_INT_R) & ++ ~(0xFFFFFFFF << HX4_XGPLL_CTRL_4__NDIV_INT_WIDTH)); ++ ++ val = readl(HX4_WRAP_XGPLL_CTRL_0_ADDR(wrap_base)); ++ mdiv = ((val >> HX4_XGPLL_CTRL_0__CH3_MDIV_R) & ++ ~(0xFFFFFFFF << HX4_XGPLL_CTRL_0__CH3_MDIV_WIDTH)); ++ } else /*if (of_device_is_compatible(dn, "brcm,usb-phy-kt2"))*/ { ++ val = readl(KT2_PLL_CTRL_REG_3_ADDR(wrap_base)); ++ ndiv = ((val >> KT2_PLL_CTRL_REG_3__NDIV_INT_R) & ++ ~(0xFFFFFFFF << KT2_PLL_CTRL_REG_3__NDIV_INT_WIDTH)); ++ ++ /* read channel 1 mdiv */ ++ val = readl(KT2_PLL_CTRL_REG_5_ADDR(wrap_base)); ++ mdiv = ((val >> KT2_PLL_CTRL_REG_5__CH1_MDIV_R) & ++ ~(0xFFFFFFFF << KT2_PLL_CTRL_REG_5__CH1_MDIV_WIDTH)); ++ } ++ ++ refclk = (25 * ndiv) / mdiv; ++ ++ return refclk; ++} ++ ++static void hx4_clk_setup(void __iomem *wrap_base) ++{ ++ u32 val, ndiv; ++ void __iomem *wrap_addr = HX4_WRAP_USBPHY_CTRL_ADDR(wrap_base); ++ ++ val = readl(HX4_WRAP_XGPLL_CTRL_4_ADDR(wrap_base)); ++ ndiv = ((val >> HX4_XGPLL_CTRL_4__NDIV_INT_R) & ++ ~(0xFFFFFFFF << HX4_XGPLL_CTRL_4__NDIV_INT_WIDTH)); ++ ++ if (ndiv == IPROC_CLK_NDIV_40) { ++ val = readl(wrap_addr); ++ val = (val & USB_CLK_NDIV_MASK) | USB_CLK_NDIV_40; ++ writel(val, wrap_addr); ++ udelay(10); ++ val = (val & USB_CLK_PLL_RESET_MASK) | USB_CLK_NDIV_40; ++ writel(val, wrap_addr); ++ udelay(10); ++ val = (val & USB_CLK_PHY_RESET_MASK) | USB_CLK_NDIV_40; ++ writel(val, wrap_addr); ++ udelay(10); ++ } else if (ndiv == IPROC_CLK_NDIV_20) { ++ val = readl(wrap_addr); ++ val = (val & USB_CLK_NDIV_MASK) | USB_CLK_NDIV_20; ++ writel(val, wrap_addr); ++ udelay(10); ++ val = (val & USB_CLK_PLL_RESET_MASK) | USB_CLK_NDIV_20; ++ writel(val, wrap_addr); ++ udelay(10); ++ val = (val & USB_CLK_PHY_RESET_MASK) | USB_CLK_NDIV_20; ++ writel(val, wrap_addr); ++ udelay(10); ++ } ++} ++ ++static int iproc_usb_phy_hx4_config(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ void __iomem *wrap_addr = NULL; ++ struct device_node *dn = iproc_usb_data->phy.dev->of_node; ++ u32 ndiv, pdiv, miidata; ++ u32 val; ++ ++ if (!wrap_base) ++ return -EINVAL; ++ ++ if (iproc_usb_data->usb_mode == IPROC_USB_MODE_DEVICE) { ++ ndiv = 1920 / _get_usb_clk(iproc_usb_data); ++ pdiv = 1 << 12; ++ miidata = pdiv + ndiv; ++ ++ /* Program NDIV and PDIV into 0x1C register */ ++ xgs_phy_wr_reg(iproc_usb_data->mdio_phy, 0x800c, miidata); ++ mdelay(10); ++ ++ /* Program other PLL parameters into 0x1D register, disable suspend and ++ put PHY into reset */ ++ miidata = 1 << 13 | 3 << 8 | 3 << 4 | 0xa; ++ xgs_phy_wr_reg(iproc_usb_data->mdio_phy, 0x800d, miidata); ++ mdelay(10); ++ ++ /* Program register 0x15, USB device mode set and get PHY out ++ of reset */ ++ miidata = 1 << 2 | 1 << 1; ++ xgs_phy_wr_reg(iproc_usb_data->mdio_phy, 0x8005, miidata); ++ mdelay(10); ++ ++ /* Program register 0x19, set mdio mode */ ++ miidata = 1 << 7; ++ xgs_phy_wr_reg(iproc_usb_data->mdio_phy, 0x8009, miidata); ++ mdelay(10); ++ ++ /* get the PLL out of reset */ ++ miidata = xgs_phy_rd_reg(iproc_usb_data->mdio_phy, 0x800d); ++ miidata |= (1 << 12); ++ xgs_phy_wr_reg(iproc_usb_data->mdio_phy, 0x800d, miidata); ++ mdelay(10); ++ } else { ++ if (of_device_is_compatible(dn, "brcm,usb-phy-hx4")) ++ wrap_addr = HX4_WRAP_USBPHY_CTRL_ADDR(wrap_base); ++ else if (of_device_is_compatible(dn, "brcm,usb-phy-kt2")) ++ wrap_addr = KT2_WRAP_USBPHY_CTRL_ADDR(wrap_base); ++ ++ val = readl(wrap_addr); ++ /* PLL_RESETB = 1 */ ++ val |= BIT(24); ++ writel(val, wrap_addr); ++ ++ mdelay(10); ++ ++ /* check pll_lock */ ++ check_usbphy_pll_lock(iproc_usb_data); ++ ++ val = readl(wrap_addr); ++ /* RESETB = 0 */ ++ val &= ~BIT(23); ++ writel(val, wrap_addr); ++ mdelay(100); ++ ++ if (of_device_is_compatible(dn, "brcm,usb-phy-hx4")) ++ hx4_clk_setup(wrap_base); ++ ++ val = readl(wrap_addr); ++ /* RESETB = 1 */ ++ val |= BIT(23); ++ writel(val, wrap_addr); ++ mdelay(1); ++ } ++ ++ return 0; ++} ++ ++static int iproc_usb_phy_sb2_config(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ u32 val; ++ ++ if (!wrap_base) ++ return -EINVAL; ++ ++ val = readl(SB2_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= 0x0c000000; /* 27:PHY_ISO & 26:PLL_SUSPEND_EN = 1 */ ++ writel(val, SB2_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~0x03000000; /* 25:PLL_RESETB & 24:RESETB = 0 */ ++ writel(val, SB2_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ val = readl(SB2_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val &= ~0x03000000; /* 25:AFE_BG_PWRDWNB & 24:AFE_LDO_PWRDWNB = 0 */ ++ writel(val, SB2_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ udelay(10); ++ val |= 0x02000000; /* 25:AFE_BG_PWRDWNB = 1 */ ++ writel(val, SB2_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ udelay(150); ++ val |= 0x01000000; /* 24:AFE_LDO_PWRDWNB = 1 */ ++ writel(val, SB2_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ udelay(160); ++ ++ val = readl(SB2_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~0x08000000; /* 27:PHY_ISO = 0 */ ++ writel(val, SB2_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ udelay(20); ++ val |= 0x02000000; /* 25:PLL_RESETB = 1 */ ++ writel(val, SB2_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ mdelay(20); ++ ++ /* check pll_lock */ ++ check_usbphy_pll_lock(iproc_usb_data); ++ ++ val = readl(SB2_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= 0x01000000; /* 24:RESETB = 1 */ ++ writel(val, SB2_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ udelay(2); ++ ++ /* adjust tx amplitude */ ++ xgs_sb2_usb_phy_wr_reg(iproc_usb_data->mdio_phy, 0x80aa, 0xeea0); ++ ++ return 0; ++} ++ ++static int iproc_usb_phy_gh_config(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ u32 val; ++ ++ if (!wrap_base) ++ return -EINVAL; ++ ++ val = readl(GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val |= IPROC_WRAP_USBPHY_CTRL_2__PHY_ISO; ++ writel(val, GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ val = readl(GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= IPROC_WRAP_USBPHY_CTRL_0__PHY_IDDQ; ++ writel(val, GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ val = readl(GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val |= IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B0; ++ writel(val, GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ /* set phy_resetb to 0, pll_resetb to 0 */ ++ val = readl(GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~IPROC_WRAP_USBPHY_CTRL_0__RESETB; ++ writel(val, GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ val = readl(GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB; ++ writel(val, GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ /* set p1ctl[11] to 0 */ ++ val = readl(GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val &= ~IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B11; ++ writel(val, GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ /* set phy_iso to 0 */ ++ val = readl(GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val &= ~IPROC_WRAP_USBPHY_CTRL_2__PHY_ISO; ++ writel(val, GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ /* set phy_iddq to 0 */ ++ val = readl(GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~IPROC_WRAP_USBPHY_CTRL_0__PHY_IDDQ; ++ writel(val, GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ mdelay(1); ++ ++ /* set pll_resetb to 1, phy_resetb to 1 */ ++ val = readl(GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB; ++ writel(val, GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ val = readl(GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= IPROC_WRAP_USBPHY_CTRL_0__RESETB; ++ writel(val, GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ mdelay(20); ++ ++ /* check pll_lock */ ++ check_usbphy_pll_lock(iproc_usb_data); ++ ++ /* set non_drving to 0 */ ++ val = readl(GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val &= ~IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B0; ++ writel(val, GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ /* set p1ctl[11] to 1 */ ++ val = readl(GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val |= IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B11; ++ writel(val, GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ return 0; ++} ++ ++static int iproc_usb_phy_gh2_config(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ void __iomem *utmi_base = NULL; ++ u32 val; ++ ++ if (!wrap_base) ++ return -EINVAL; ++ ++ /* This value is from DE team to set Internal Power Sequence Mode */ ++ val = readl(IPROC_WRAP_TOP_STRAP_STATUS_ADDR(wrap_base)); ++ if (val & IPROC_WRAP_TOP_STRAP_STATUS__USB2_SEL) { ++ /* host mode */ ++ utmi_base = iproc_usb_data->utmi_base; ++ if (!utmi_base) ++ return -EINVAL; ++ writel(0x0802, USBH_Utmi_p0Ctl(utmi_base)); ++ } else { ++ /* device mode */ ++ writel(0x0806, GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ } ++ ++ mdelay(20); ++ ++ /* check pll_lock */ ++ check_usbphy_pll_lock(iproc_usb_data); ++ ++ return 0; ++} ++ ++static int iproc_usb_phy_init(struct usb_phy *phy) ++{ ++ struct iproc_usb_priv *iproc_usb_data = ++ container_of(phy, struct iproc_usb_priv, phy); ++ struct device *dev = phy->dev; ++ void __iomem *idm_base = iproc_usb_data->idm_base; ++ int ret = 0; ++ u32 val; ++ ++ if (iproc_usb_data->init_count) ++ return 0; ++ else ++ iproc_usb_data->init_count++; ++ ++ if (!iproc_usb_data->wrap_base || !iproc_usb_data->idm_base) ++ return -EINVAL; ++ ++ /* Put USB controller into reset state and disable clock */ ++ val = readl(USB2_IDM_RESET_CONTROL_ADDR(idm_base)); ++ val |= USB2_IDM_RESET_CONTROL__RESET; ++ writel(val, USB2_IDM_RESET_CONTROL_ADDR(idm_base)); ++ ++ val = readl(USB2_IDM_IO_CONTROL_DIRECT_ADDR(idm_base)); ++ val &= ~USB2_IDM_IO_CONTROL_DIRECT__clk_enable; ++ writel(val, USB2_IDM_IO_CONTROL_DIRECT_ADDR(idm_base)); ++ ++ if (of_device_is_compatible(dev->of_node, "brcm,usb-phy-hx4") || ++ of_device_is_compatible(dev->of_node, "brcm,usb-phy-kt2")) ++ ret = iproc_usb_phy_hx4_config(iproc_usb_data); ++ else if (of_device_is_compatible(dev->of_node, "brcm,usb-phy-sb2")) ++ ret = iproc_usb_phy_sb2_config(iproc_usb_data); ++ else if (of_device_is_compatible(dev->of_node, "brcm,usb-phy-gh") || ++ of_device_is_compatible(dev->of_node, "brcm,usb-phy-hr3")) ++ ret = iproc_usb_phy_gh_config(iproc_usb_data); ++ ++ /* Enable clock to USB and get the USB out of reset */ ++ val = readl(USB2_IDM_IO_CONTROL_DIRECT_ADDR(idm_base)); ++ val |= USB2_IDM_IO_CONTROL_DIRECT__clk_enable; ++ writel(val, USB2_IDM_IO_CONTROL_DIRECT_ADDR(idm_base)); ++ ++ mdelay(10); ++ val = readl(USB2_IDM_RESET_CONTROL_ADDR(idm_base)); ++ val &= ~USB2_IDM_RESET_CONTROL__RESET; ++ writel(val, USB2_IDM_RESET_CONTROL_ADDR(idm_base)); ++ mdelay(100); ++ ++ /* For GH2, PHY should be inited after RESET */ ++ if (of_device_is_compatible(dev->of_node, "brcm,usb-phy-gh2")) ++ ret = iproc_usb_phy_gh2_config(iproc_usb_data); ++ ++ return ret; ++} ++ ++static int xgs_iproc_usb_phy_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *dn = pdev->dev.of_node; ++ struct device_node *mdio_phy_np = NULL; ++ struct iproc_usb_priv *iproc_usb_data; ++ struct resource *res; ++ int gpio_pin; ++ enum of_gpio_flags flags; ++ u32 gpio_active_low; ++ int ret, usb_mode; ++ ++ if (!of_device_is_available(dn)) ++ return -ENODEV; ++ ++ iproc_usb_data = devm_kzalloc(dev, sizeof(*iproc_usb_data), GFP_KERNEL); ++ if (!iproc_usb_data) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, iproc_usb_data); ++ ++ iproc_usb_data->wrap_base = get_iproc_wrap_ctrl_base(); ++ if (!iproc_usb_data->wrap_base) { ++ dev_err(dev, "No wrap_base addr in DT"); ++ return -ENXIO; ++ } ++ ++ gpio_pin = of_get_named_gpio_flags(dn, "vbus-gpio", 0, &flags); ++ if (gpio_pin < 0) { ++ dev_err(dev, "No gpio pin set for USB power\n"); ++ return gpio_pin; ++ } ++ ++ gpio_active_low = flags & OF_GPIO_ACTIVE_LOW; ++ ++ ret = devm_gpio_request(dev, gpio_pin, "usbphy-vbus"); ++ if (ret != 0) { ++ dev_err(dev, "Failed to request gpio #%d\n", gpio_pin); ++ return ret; ++ } ++ ++ iproc_usb_data->phy.dev = dev; ++ usb_mode = xgs_iproc_usb_phy_mode(iproc_usb_data); ++ ++ iproc_usb_data->usb_mode = usb_mode; ++ /* Save host/device mode in phy.flags for use by ECHI/OHCI drivers */ ++ iproc_usb_data->phy.flags = usb_mode; ++ iproc_usb_data->phy.init = iproc_usb_phy_init; ++ iproc_usb_data->phy.type = USB_PHY_TYPE_USB2; ++ ++ if (usb_mode == IPROC_USB_MODE_HOST) { ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ iproc_usb_data->idm_base = ++ devm_ioremap_resource(dev, res); ++ if (IS_ERR(iproc_usb_data->idm_base)) { ++ dev_err(dev, "can't iomap usb2h idm base\n"); ++ return PTR_ERR(iproc_usb_data->idm_base); ++ } ++ ++ /* required for GH2 */ ++ if (of_device_is_compatible(dev->of_node, "brcm,usb-phy-gh2")) { ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); ++ iproc_usb_data->utmi_base = ++ devm_ioremap_resource(dev, res); ++ } ++ ++ gpio_direction_output(gpio_pin, 1); ++ /* turn off the power: if active low, then set 1 to turn off */ ++ if (gpio_active_low) ++ gpio_set_value(gpio_pin, 1); ++ else ++ gpio_set_value(gpio_pin, 0); ++ } else { ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ iproc_usb_data->idm_base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(iproc_usb_data->idm_base)) { ++ dev_err(dev, "can't iomap usb2d idm base\n"); ++ return PTR_ERR(iproc_usb_data->idm_base); ++ } ++ } ++ ++ ++ /* PHY controlled through MDIO */ ++ mdio_phy_np = of_parse_phandle(dn, "mdio-phy-handle", 0); ++ if (mdio_phy_np) ++ iproc_usb_data->mdio_phy = of_phy_find_device(mdio_phy_np); ++ ++ ret = usb_add_phy_dev(&iproc_usb_data->phy); ++ if (ret) ++ return ret; ++ ++ /* supply power for USB device connected to the host */ ++ if (usb_mode == IPROC_USB_MODE_HOST) { ++ if (gpio_active_low) ++ gpio_set_value(gpio_pin, 0); ++ else ++ gpio_set_value(gpio_pin, 1); ++ } ++ ++ devm_gpio_free(dev, gpio_pin); ++ ++ return 0; ++} ++ ++static int xgs_iproc_usb_phy_remove(struct platform_device *pdev) ++{ ++ struct iproc_usb_priv *iproc_usb_data = platform_get_drvdata(pdev); ++ ++ if (iproc_usb_data) ++ usb_remove_phy(&iproc_usb_data->phy); ++ ++ platform_set_drvdata(pdev, NULL); ++ ++ return 0; ++} ++ ++static const struct of_device_id xgs_iproc_usb_phy_dt_ids[] = { ++ { .compatible = "brcm,usb-phy-hx4", }, ++ { .compatible = "brcm,usb-phy-kt2", }, ++ { .compatible = "brcm,usb-phy-gh", }, ++ { .compatible = "brcm,usb-phy-sb2", }, ++ { .compatible = "brcm,usb-phy-hr3", }, ++ { .compatible = "brcm,usb-phy-gh2", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, xgs_iproc_usb_phy_dt_ids); ++ ++static struct platform_driver xgs_iproc_usb_phy_driver = ++{ ++ .driver = { ++ .name = "xgs-usb-phy", ++ .owner = THIS_MODULE, ++ .of_match_table = xgs_iproc_usb_phy_dt_ids, ++ }, ++ .probe = xgs_iproc_usb_phy_probe, ++ .remove = xgs_iproc_usb_phy_remove, ++}; ++ ++module_platform_driver(xgs_iproc_usb_phy_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("Broadcom USB phy driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c +--- a/drivers/watchdog/sp805_wdt.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/watchdog/sp805_wdt.c 2018-05-10 11:31:34.017404421 +0800 +@@ -27,6 +27,8 @@ + #include + #include + #include ++#include ++ + + /* default timeout in seconds */ + #define DEFAULT_TIMEOUT 60 +@@ -74,6 +76,24 @@ module_param(nowayout, bool, 0); + MODULE_PARM_DESC(nowayout, + "Set to 1 to keep watchdog running after device release"); + ++/* This routine get boot status to indicate if the last boot is from WDT */ ++static unsigned int wdt_get_clear_bootstatus( ++ void __iomem *wdt_bootstatus, ++ unsigned int wdt_bootstatus_bit) ++{ ++ unsigned int reg; ++ unsigned int bootstatus = 0; ++ ++ reg = readl_relaxed(wdt_bootstatus); ++ bootstatus = reg & (1 << wdt_bootstatus_bit); ++ ++ if (bootstatus) ++ /* write 1 to clear boot status bit */ ++ writel_relaxed(reg, wdt_bootstatus); ++ ++ return bootstatus; ++} ++ + /* This routine finds load value that will reset system in required timout */ + static int wdt_setload(struct watchdog_device *wdd, unsigned int timeout) + { +@@ -204,6 +224,8 @@ sp805_wdt_probe(struct amba_device *adev + { + struct sp805_wdt *wdt; + int ret = 0; ++ void __iomem *wdt_bootstatus = NULL; ++ unsigned int bootstatus_bit = 0; + + wdt = devm_kzalloc(&adev->dev, sizeof(*wdt), GFP_KERNEL); + if (!wdt) { +@@ -215,6 +237,13 @@ sp805_wdt_probe(struct amba_device *adev + if (IS_ERR(wdt->base)) + return PTR_ERR(wdt->base); + ++ wdt_bootstatus = of_iomap(adev->dev.of_node, 1); ++ if (!wdt_bootstatus) { ++ ret = -ENOMEM; ++ dev_warn(&adev->dev, "of_iomap failed\n"); ++ goto err; ++ } ++ + wdt->clk = devm_clk_get(&adev->dev, NULL); + if (IS_ERR(wdt->clk)) { + dev_warn(&adev->dev, "Clock not found\n"); +@@ -240,6 +269,9 @@ sp805_wdt_probe(struct amba_device *adev + } + amba_set_drvdata(adev, wdt); + ++ wdt->wdd.bootstatus = wdt_get_clear_bootstatus( ++ wdt_bootstatus, bootstatus_bit); ++ + dev_info(&adev->dev, "registration successful\n"); + return 0; + +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/include/linux/phy/xgs_iproc_serdes.h b/include/linux/phy/xgs_iproc_serdes.h +--- a/include/linux/phy/xgs_iproc_serdes.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/include/linux/phy/xgs_iproc_serdes.h 2018-05-10 11:31:34.757405249 +0800 +@@ -0,0 +1,27 @@ ++/* ++ * Copyright (C) 2017 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _XGS_IPROC_SERDES_H_ ++#define _XGS_IPROC_SERDES_H_ ++ ++/* Specify the used lane number of SERDES */ ++typedef struct xgs_serdes_info_s { ++ u32 lane; ++} xgs_serdes_info_t; ++ ++extern bool xgs_serdes_hx4_amac(struct phy_device *); ++extern bool xgs_serdes_kt2_amac(struct phy_device *); ++extern void xgs_serdes_set_lane(struct phy_device *phy_dev, u32 lane); ++ ++#endif /* _XGS_IPROC_SERDES_H_ */ ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/include/linux/soc/bcm/iproc-cmic.h b/include/linux/soc/bcm/iproc-cmic.h +--- a/include/linux/soc/bcm/iproc-cmic.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/include/linux/soc/bcm/iproc-cmic.h 2018-05-10 11:31:34.797405294 +0800 +@@ -0,0 +1,34 @@ ++#ifndef _IPROC_CMIC_H ++#define _IPROC_CMIC_H ++ ++struct iproc_cmic { ++ void __iomem *base; ++ struct device *dev; ++ ++ const struct sbus_ops *sbus_ops; ++}; ++ ++struct sbus_ops { ++ int (*init)(struct iproc_cmic *cmic); ++ int (*reg32_write)(struct iproc_cmic *cmic, u32 block, u32 addr, u32 val); ++ u32 (*reg32_read)(struct iproc_cmic *cmic, u32 block, u32 addr); ++ int (*reg64_write)(struct iproc_cmic *cmic, u32 block, u32 addr, u64 val); ++ u64 (*reg64_read)(struct iproc_cmic *cmic, u32 block, u32 addr); ++ int (*ucmem_write)(struct iproc_cmic *cmic, u32 block, u32 *mem); ++ int (*ucmem_read)(struct iproc_cmic *cmic, u32 block, u32 *mem); ++}; ++ ++enum cmic_block_type { ++ CMIC_BLOCK_TYPE_TOP = 0, ++ CMIC_BLOCK_TYPE_APM = 1, ++}; ++ ++extern int iproc_cmic_schan_reg32_write(u32 blk_type, u32 addr, u32 val); ++extern u32 iproc_cmic_schan_reg32_read(u32 blk_type, u32 addr); ++extern int iproc_cmic_schan_reg64_write(u32 blk_type, u32 addr, u64 val); ++extern u64 iproc_cmic_schan_reg64_read(u32 blk_type, u32 addr); ++extern int iproc_cmic_schan_ucmem_write(u32 blk_type, u32 *mem); ++extern int iproc_cmic_schan_ucmem_read(u32 blk_type, u32 *mem); ++extern void inline __iomem *iproc_cmic_base_get(void); ++ ++#endif /* _IPROC_CMIC_H */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/include/linux/soc/bcm/xgs-iproc-idm.h b/include/linux/soc/bcm/xgs-iproc-idm.h +--- a/include/linux/soc/bcm/xgs-iproc-idm.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/include/linux/soc/bcm/xgs-iproc-idm.h 2018-05-10 11:31:34.797405294 +0800 +@@ -0,0 +1,21 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef XGS_IPROC_IDM_H ++#define XGS_IPROC_IDM_H ++ ++extern void inline __iomem *get_iproc_idm_base(int idx); ++extern int xgs_iproc_idm_dmac_reset(void); ++extern int xgs_iproc_idm_init(void); ++ ++#endif /* XGS_IPROC_IDM_H */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/include/linux/soc/bcm/xgs-iproc-misc-setup.h b/include/linux/soc/bcm/xgs-iproc-misc-setup.h +--- a/include/linux/soc/bcm/xgs-iproc-misc-setup.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/include/linux/soc/bcm/xgs-iproc-misc-setup.h 2018-05-10 11:31:34.797405294 +0800 +@@ -0,0 +1,22 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef XGS_IPROC_MISC_SETUP_H ++#define XGS_IPROC_MISC_SETUP_H ++ ++extern int xgs_iproc_misc_setup(void); ++extern void __iomem *get_iproc_wrap_ctrl_base(void); ++extern void __iomem *get_iproc_dmu_pcu_base(void); ++extern int is_wh2_amac_sgmii(void); ++ ++#endif /* XGS_IPROC_MISC_SETUP_H */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/include/linux/usb/iproc_usb.h b/include/linux/usb/iproc_usb.h +--- a/include/linux/usb/iproc_usb.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/include/linux/usb/iproc_usb.h 2018-05-10 11:31:34.817405317 +0800 +@@ -0,0 +1,23 @@ ++/* ++ * Copyright 2017 Broadcom Limited ++ * ++ * 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. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __LINUX_USB_IPROC_USB_H ++#define __LINUX_USB_IPROC_USB_H ++ ++/* USB Flags */ ++ ++#define IPROC_USB_MODE_HOST (0) ++#define IPROC_USB_MODE_DEVICE (1) ++ ++#endif /* __LINUX_USB_IPROC_USB_H */ ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/acpidbg/Makefile b/tools/power/acpi/tools/acpidbg/Makefile +--- a/tools/power/acpi/tools/acpidbg/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/acpidbg/Makefile 1970-01-01 08:00:00.000000000 +0800 +@@ -1,25 +0,0 @@ +-# tools/power/acpi/tools/acpidbg/Makefile - ACPI tool Makefile +-# +-# Copyright (c) 2015, Intel Corporation +-# Author: Lv Zheng +-# +-# This program is free software; you can redistribute it and/or +-# modify it under the terms of the GNU General Public License +-# as published by the Free Software Foundation; version 2 +-# of the License. +- +-include ../../Makefile.config +- +-TOOL = acpidbg +-vpath %.c \ +- ../../../../../drivers/acpi/acpica\ +- ../../common\ +- ../../os_specific/service_layers\ +- . +-CFLAGS += -DACPI_APPLICATION -DACPI_SINGLE_THREAD -DACPI_DEBUGGER\ +- -I. +-LDFLAGS += -lpthread +-TOOL_OBJS = \ +- acpidbg.o +- +-include ../../Makefile.rules +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/acpidbg/acpidbg.c b/tools/power/acpi/tools/acpidbg/acpidbg.c +--- a/tools/power/acpi/tools/acpidbg/acpidbg.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/acpidbg/acpidbg.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,444 +0,0 @@ +-/* +- * ACPI AML interfacing userspace utility +- * +- * Copyright (C) 2015, Intel Corporation +- * Authors: Lv Zheng +- * +- * 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 +- +-/* Headers not included by include/acpi/platform/aclinux.h */ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "../../../../../include/linux/circ_buf.h" +- +-#define ACPI_AML_FILE "/sys/kernel/debug/acpi/acpidbg" +-#define ACPI_AML_SEC_TICK 1 +-#define ACPI_AML_USEC_PEEK 200 +-#define ACPI_AML_BUF_SIZE 4096 +- +-#define ACPI_AML_BATCH_WRITE_CMD 0x00 /* Write command to kernel */ +-#define ACPI_AML_BATCH_READ_LOG 0x01 /* Read log from kernel */ +-#define ACPI_AML_BATCH_WRITE_LOG 0x02 /* Write log to console */ +- +-#define ACPI_AML_LOG_START 0x00 +-#define ACPI_AML_PROMPT_START 0x01 +-#define ACPI_AML_PROMPT_STOP 0x02 +-#define ACPI_AML_LOG_STOP 0x03 +-#define ACPI_AML_PROMPT_ROLL 0x04 +- +-#define ACPI_AML_INTERACTIVE 0x00 +-#define ACPI_AML_BATCH 0x01 +- +-#define circ_count(circ) \ +- (CIRC_CNT((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE)) +-#define circ_count_to_end(circ) \ +- (CIRC_CNT_TO_END((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE)) +-#define circ_space(circ) \ +- (CIRC_SPACE((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE)) +-#define circ_space_to_end(circ) \ +- (CIRC_SPACE_TO_END((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE)) +- +-#define acpi_aml_cmd_count() circ_count(&acpi_aml_cmd_crc) +-#define acpi_aml_log_count() circ_count(&acpi_aml_log_crc) +-#define acpi_aml_cmd_space() circ_space(&acpi_aml_cmd_crc) +-#define acpi_aml_log_space() circ_space(&acpi_aml_log_crc) +- +-#define ACPI_AML_DO(_fd, _op, _buf, _ret) \ +- do { \ +- _ret = acpi_aml_##_op(_fd, &acpi_aml_##_buf##_crc); \ +- if (_ret == 0) { \ +- fprintf(stderr, \ +- "%s %s pipe closed.\n", #_buf, #_op); \ +- return; \ +- } \ +- } while (0) +-#define ACPI_AML_BATCH_DO(_fd, _op, _buf, _ret) \ +- do { \ +- _ret = acpi_aml_##_op##_batch_##_buf(_fd, \ +- &acpi_aml_##_buf##_crc); \ +- if (_ret == 0) \ +- return; \ +- } while (0) +- +- +-static char acpi_aml_cmd_buf[ACPI_AML_BUF_SIZE]; +-static char acpi_aml_log_buf[ACPI_AML_BUF_SIZE]; +-static struct circ_buf acpi_aml_cmd_crc = { +- .buf = acpi_aml_cmd_buf, +- .head = 0, +- .tail = 0, +-}; +-static struct circ_buf acpi_aml_log_crc = { +- .buf = acpi_aml_log_buf, +- .head = 0, +- .tail = 0, +-}; +-static const char *acpi_aml_file_path = ACPI_AML_FILE; +-static unsigned long acpi_aml_mode = ACPI_AML_INTERACTIVE; +-static bool acpi_aml_exit; +- +-static bool acpi_aml_batch_drain; +-static unsigned long acpi_aml_batch_state; +-static char acpi_aml_batch_prompt; +-static char acpi_aml_batch_roll; +-static unsigned long acpi_aml_log_state; +-static char *acpi_aml_batch_cmd = NULL; +-static char *acpi_aml_batch_pos = NULL; +- +-static int acpi_aml_set_fl(int fd, int flags) +-{ +- int ret; +- +- ret = fcntl(fd, F_GETFL, 0); +- if (ret < 0) { +- perror("fcntl(F_GETFL)"); +- return ret; +- } +- flags |= ret; +- ret = fcntl(fd, F_SETFL, flags); +- if (ret < 0) { +- perror("fcntl(F_SETFL)"); +- return ret; +- } +- return ret; +-} +- +-static int acpi_aml_set_fd(int fd, int maxfd, fd_set *set) +-{ +- if (fd > maxfd) +- maxfd = fd; +- FD_SET(fd, set); +- return maxfd; +-} +- +-static int acpi_aml_read(int fd, struct circ_buf *crc) +-{ +- char *p; +- int len; +- +- p = &crc->buf[crc->head]; +- len = circ_space_to_end(crc); +- len = read(fd, p, len); +- if (len < 0) +- perror("read"); +- else if (len > 0) +- crc->head = (crc->head + len) & (ACPI_AML_BUF_SIZE - 1); +- return len; +-} +- +-static int acpi_aml_read_batch_cmd(int unused, struct circ_buf *crc) +-{ +- char *p; +- int len; +- int remained = strlen(acpi_aml_batch_pos); +- +- p = &crc->buf[crc->head]; +- len = circ_space_to_end(crc); +- if (len > remained) { +- memcpy(p, acpi_aml_batch_pos, remained); +- acpi_aml_batch_pos += remained; +- len = remained; +- } else { +- memcpy(p, acpi_aml_batch_pos, len); +- acpi_aml_batch_pos += len; +- } +- if (len > 0) +- crc->head = (crc->head + len) & (ACPI_AML_BUF_SIZE - 1); +- return len; +-} +- +-static int acpi_aml_read_batch_log(int fd, struct circ_buf *crc) +-{ +- char *p; +- int len; +- int ret = 0; +- +- p = &crc->buf[crc->head]; +- len = circ_space_to_end(crc); +- while (ret < len && acpi_aml_log_state != ACPI_AML_LOG_STOP) { +- if (acpi_aml_log_state == ACPI_AML_PROMPT_ROLL) { +- *p = acpi_aml_batch_roll; +- len = 1; +- crc->head = (crc->head + 1) & (ACPI_AML_BUF_SIZE - 1); +- ret += 1; +- acpi_aml_log_state = ACPI_AML_LOG_START; +- } else { +- len = read(fd, p, 1); +- if (len <= 0) { +- if (len < 0) +- perror("read"); +- ret = len; +- break; +- } +- } +- switch (acpi_aml_log_state) { +- case ACPI_AML_LOG_START: +- if (*p == '\n') +- acpi_aml_log_state = ACPI_AML_PROMPT_START; +- crc->head = (crc->head + 1) & (ACPI_AML_BUF_SIZE - 1); +- ret += 1; +- break; +- case ACPI_AML_PROMPT_START: +- if (*p == ACPI_DEBUGGER_COMMAND_PROMPT || +- *p == ACPI_DEBUGGER_EXECUTE_PROMPT) { +- acpi_aml_batch_prompt = *p; +- acpi_aml_log_state = ACPI_AML_PROMPT_STOP; +- } else { +- if (*p != '\n') +- acpi_aml_log_state = ACPI_AML_LOG_START; +- crc->head = (crc->head + 1) & (ACPI_AML_BUF_SIZE - 1); +- ret += 1; +- } +- break; +- case ACPI_AML_PROMPT_STOP: +- if (*p == ' ') { +- acpi_aml_log_state = ACPI_AML_LOG_STOP; +- acpi_aml_exit = true; +- } else { +- /* Roll back */ +- acpi_aml_log_state = ACPI_AML_PROMPT_ROLL; +- acpi_aml_batch_roll = *p; +- *p = acpi_aml_batch_prompt; +- crc->head = (crc->head + 1) & (ACPI_AML_BUF_SIZE - 1); +- ret += 1; +- } +- break; +- default: +- assert(0); +- break; +- } +- } +- return ret; +-} +- +-static int acpi_aml_write(int fd, struct circ_buf *crc) +-{ +- char *p; +- int len; +- +- p = &crc->buf[crc->tail]; +- len = circ_count_to_end(crc); +- len = write(fd, p, len); +- if (len < 0) +- perror("write"); +- else if (len > 0) +- crc->tail = (crc->tail + len) & (ACPI_AML_BUF_SIZE - 1); +- return len; +-} +- +-static int acpi_aml_write_batch_log(int fd, struct circ_buf *crc) +-{ +- char *p; +- int len; +- +- p = &crc->buf[crc->tail]; +- len = circ_count_to_end(crc); +- if (!acpi_aml_batch_drain) { +- len = write(fd, p, len); +- if (len < 0) +- perror("write"); +- } +- if (len > 0) +- crc->tail = (crc->tail + len) & (ACPI_AML_BUF_SIZE - 1); +- return len; +-} +- +-static int acpi_aml_write_batch_cmd(int fd, struct circ_buf *crc) +-{ +- int len; +- +- len = acpi_aml_write(fd, crc); +- if (circ_count_to_end(crc) == 0) +- acpi_aml_batch_state = ACPI_AML_BATCH_READ_LOG; +- return len; +-} +- +-static void acpi_aml_loop(int fd) +-{ +- fd_set rfds; +- fd_set wfds; +- struct timeval tv; +- int ret; +- int maxfd = 0; +- +- if (acpi_aml_mode == ACPI_AML_BATCH) { +- acpi_aml_log_state = ACPI_AML_LOG_START; +- acpi_aml_batch_pos = acpi_aml_batch_cmd; +- if (acpi_aml_batch_drain) +- acpi_aml_batch_state = ACPI_AML_BATCH_READ_LOG; +- else +- acpi_aml_batch_state = ACPI_AML_BATCH_WRITE_CMD; +- } +- acpi_aml_exit = false; +- while (!acpi_aml_exit) { +- tv.tv_sec = ACPI_AML_SEC_TICK; +- tv.tv_usec = 0; +- FD_ZERO(&rfds); +- FD_ZERO(&wfds); +- +- if (acpi_aml_cmd_space()) { +- if (acpi_aml_mode == ACPI_AML_INTERACTIVE) +- maxfd = acpi_aml_set_fd(STDIN_FILENO, maxfd, &rfds); +- else if (strlen(acpi_aml_batch_pos) && +- acpi_aml_batch_state == ACPI_AML_BATCH_WRITE_CMD) +- ACPI_AML_BATCH_DO(STDIN_FILENO, read, cmd, ret); +- } +- if (acpi_aml_cmd_count() && +- (acpi_aml_mode == ACPI_AML_INTERACTIVE || +- acpi_aml_batch_state == ACPI_AML_BATCH_WRITE_CMD)) +- maxfd = acpi_aml_set_fd(fd, maxfd, &wfds); +- if (acpi_aml_log_space() && +- (acpi_aml_mode == ACPI_AML_INTERACTIVE || +- acpi_aml_batch_state == ACPI_AML_BATCH_READ_LOG)) +- maxfd = acpi_aml_set_fd(fd, maxfd, &rfds); +- if (acpi_aml_log_count()) +- maxfd = acpi_aml_set_fd(STDOUT_FILENO, maxfd, &wfds); +- +- ret = select(maxfd+1, &rfds, &wfds, NULL, &tv); +- if (ret < 0) { +- perror("select"); +- break; +- } +- if (ret > 0) { +- if (FD_ISSET(STDIN_FILENO, &rfds)) +- ACPI_AML_DO(STDIN_FILENO, read, cmd, ret); +- if (FD_ISSET(fd, &wfds)) { +- if (acpi_aml_mode == ACPI_AML_BATCH) +- ACPI_AML_BATCH_DO(fd, write, cmd, ret); +- else +- ACPI_AML_DO(fd, write, cmd, ret); +- } +- if (FD_ISSET(fd, &rfds)) { +- if (acpi_aml_mode == ACPI_AML_BATCH) +- ACPI_AML_BATCH_DO(fd, read, log, ret); +- else +- ACPI_AML_DO(fd, read, log, ret); +- } +- if (FD_ISSET(STDOUT_FILENO, &wfds)) { +- if (acpi_aml_mode == ACPI_AML_BATCH) +- ACPI_AML_BATCH_DO(STDOUT_FILENO, write, log, ret); +- else +- ACPI_AML_DO(STDOUT_FILENO, write, log, ret); +- } +- } +- } +-} +- +-static bool acpi_aml_readable(int fd) +-{ +- fd_set rfds; +- struct timeval tv; +- int ret; +- int maxfd = 0; +- +- tv.tv_sec = 0; +- tv.tv_usec = ACPI_AML_USEC_PEEK; +- FD_ZERO(&rfds); +- maxfd = acpi_aml_set_fd(fd, maxfd, &rfds); +- ret = select(maxfd+1, &rfds, NULL, NULL, &tv); +- if (ret < 0) +- perror("select"); +- if (ret > 0 && FD_ISSET(fd, &rfds)) +- return true; +- return false; +-} +- +-/* +- * This is a userspace IO flush implementation, replying on the prompt +- * characters and can be turned into a flush() call after kernel implements +- * .flush() filesystem operation. +- */ +-static void acpi_aml_flush(int fd) +-{ +- while (acpi_aml_readable(fd)) { +- acpi_aml_batch_drain = true; +- acpi_aml_loop(fd); +- acpi_aml_batch_drain = false; +- } +-} +- +-void usage(FILE *file, char *progname) +-{ +- fprintf(file, "usage: %s [-b cmd] [-f file] [-h]\n", progname); +- fprintf(file, "\nOptions:\n"); +- fprintf(file, " -b Specify command to be executed in batch mode\n"); +- fprintf(file, " -f Specify interface file other than"); +- fprintf(file, " /sys/kernel/debug/acpi/acpidbg\n"); +- fprintf(file, " -h Print this help message\n"); +-} +- +-int main(int argc, char **argv) +-{ +- int fd = -1; +- int ch; +- int len; +- int ret = EXIT_SUCCESS; +- +- while ((ch = getopt(argc, argv, "b:f:h")) != -1) { +- switch (ch) { +- case 'b': +- if (acpi_aml_batch_cmd) { +- fprintf(stderr, "Already specify %s\n", +- acpi_aml_batch_cmd); +- ret = EXIT_FAILURE; +- goto exit; +- } +- len = strlen(optarg); +- acpi_aml_batch_cmd = calloc(len + 2, 1); +- if (!acpi_aml_batch_cmd) { +- perror("calloc"); +- ret = EXIT_FAILURE; +- goto exit; +- } +- memcpy(acpi_aml_batch_cmd, optarg, len); +- acpi_aml_batch_cmd[len] = '\n'; +- acpi_aml_mode = ACPI_AML_BATCH; +- break; +- case 'f': +- acpi_aml_file_path = optarg; +- break; +- case 'h': +- usage(stdout, argv[0]); +- goto exit; +- break; +- case '?': +- default: +- usage(stderr, argv[0]); +- ret = EXIT_FAILURE; +- goto exit; +- break; +- } +- } +- +- fd = open(acpi_aml_file_path, O_RDWR | O_NONBLOCK); +- if (fd < 0) { +- perror("open"); +- ret = EXIT_FAILURE; +- goto exit; +- } +- acpi_aml_set_fl(STDIN_FILENO, O_NONBLOCK); +- acpi_aml_set_fl(STDOUT_FILENO, O_NONBLOCK); +- +- if (acpi_aml_mode == ACPI_AML_BATCH) +- acpi_aml_flush(fd); +- acpi_aml_loop(fd); +- +-exit: +- if (fd >= 0) +- close(fd); +- if (acpi_aml_batch_cmd) +- free(acpi_aml_batch_cmd); +- return ret; +-} +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/acpidump/Makefile b/tools/power/acpi/tools/acpidump/Makefile +--- a/tools/power/acpi/tools/acpidump/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/acpidump/Makefile 1970-01-01 08:00:00.000000000 +0800 +@@ -1,55 +0,0 @@ +-# tools/power/acpi/tools/acpidump/Makefile - ACPI tool Makefile +-# +-# Copyright (c) 2015, Intel Corporation +-# Author: Lv Zheng +-# +-# This program is free software; you can redistribute it and/or +-# modify it under the terms of the GNU General Public License +-# as published by the Free Software Foundation; version 2 +-# of the License. +- +-include ../../Makefile.config +- +-TOOL = acpidump +-EXTRA_INSTALL = install-man +-EXTRA_UNINSTALL = uninstall-man +- +-vpath %.c \ +- ../../../../../drivers/acpi/acpica\ +- ./\ +- ../../common\ +- ../../os_specific/service_layers +-CFLAGS += -DACPI_DUMP_APP -I. +-TOOL_OBJS = \ +- apdump.o\ +- apfiles.o\ +- apmain.o\ +- osunixdir.o\ +- osunixmap.o\ +- osunixxf.o\ +- tbprint.o\ +- tbxfroot.o\ +- utascii.o\ +- utbuffer.o\ +- utdebug.o\ +- utexcep.o\ +- utglobal.o\ +- uthex.o\ +- utmath.o\ +- utnonansi.o\ +- utprint.o\ +- utstring.o\ +- utstrtoul64.o\ +- utxferror.o\ +- oslinuxtbl.o\ +- cmfsize.o\ +- getopt.o +- +-include ../../Makefile.rules +- +-install-man: $(srctree)/man/acpidump.8 +- $(ECHO) " INST " acpidump.8 +- $(QUIET) $(INSTALL_DATA) -D $< $(DESTDIR)$(mandir)/man8/acpidump.8 +-uninstall-man: +- $(ECHO) " UNINST " acpidump.8 +- $(QUIET) rm -f $(DESTDIR)$(mandir)/man8/acpidump.8 +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/acpidump/acpidump.h b/tools/power/acpi/tools/acpidump/acpidump.h +--- a/tools/power/acpi/tools/acpidump/acpidump.h 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/acpidump/acpidump.h 1970-01-01 08:00:00.000000000 +0800 +@@ -1,119 +0,0 @@ +-/****************************************************************************** +- * +- * Module Name: acpidump.h - Include file for acpi_dump utility +- * +- *****************************************************************************/ +- +-/* +- * Copyright (C) 2000 - 2017, Intel Corp. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions, and the following disclaimer, +- * without modification. +- * 2. Redistributions in binary form must reproduce at minimum a disclaimer +- * substantially similar to the "NO WARRANTY" disclaimer below +- * ("Disclaimer") and any redistribution must be conditioned upon +- * including a substantially similar Disclaimer requirement for further +- * binary redistribution. +- * 3. Neither the names of the above-listed copyright holders nor the names +- * of any contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * Alternatively, this software may be distributed under the terms of the +- * GNU General Public License ("GPL") version 2 as published by the Free +- * Software Foundation. +- * +- * NO WARRANTY +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR +- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +- * POSSIBILITY OF SUCH DAMAGES. +- */ +- +-/* +- * Global variables. Defined in main.c only, externed in all other files +- */ +-#ifdef _DECLARE_GLOBALS +-#define EXTERN +-#define INIT_GLOBAL(a,b) a=b +-#else +-#define EXTERN extern +-#define INIT_GLOBAL(a,b) a +-#endif +- +-#include +-#include "accommon.h" +-#include "actables.h" +-#include "acapps.h" +- +-/* Globals */ +- +-EXTERN u8 INIT_GLOBAL(gbl_summary_mode, FALSE); +-EXTERN u8 INIT_GLOBAL(gbl_verbose_mode, FALSE); +-EXTERN u8 INIT_GLOBAL(gbl_binary_mode, FALSE); +-EXTERN u8 INIT_GLOBAL(gbl_dump_customized_tables, TRUE); +-EXTERN u8 INIT_GLOBAL(gbl_do_not_dump_xsdt, FALSE); +-EXTERN ACPI_FILE INIT_GLOBAL(gbl_output_file, NULL); +-EXTERN char INIT_GLOBAL(*gbl_output_filename, NULL); +-EXTERN u64 INIT_GLOBAL(gbl_rsdp_base, 0); +- +-/* Action table used to defer requested options */ +- +-struct ap_dump_action { +- char *argument; +- u32 to_be_done; +-}; +- +-#define AP_MAX_ACTIONS 32 +- +-#define AP_DUMP_ALL_TABLES 0 +-#define AP_DUMP_TABLE_BY_ADDRESS 1 +-#define AP_DUMP_TABLE_BY_NAME 2 +-#define AP_DUMP_TABLE_BY_FILE 3 +- +-#define AP_MAX_ACPI_FILES 256 /* Prevent infinite loops */ +- +-/* Minimum FADT sizes for various table addresses */ +- +-#define MIN_FADT_FOR_DSDT (ACPI_FADT_OFFSET (dsdt) + sizeof (u32)) +-#define MIN_FADT_FOR_FACS (ACPI_FADT_OFFSET (facs) + sizeof (u32)) +-#define MIN_FADT_FOR_XDSDT (ACPI_FADT_OFFSET (Xdsdt) + sizeof (u64)) +-#define MIN_FADT_FOR_XFACS (ACPI_FADT_OFFSET (Xfacs) + sizeof (u64)) +- +-/* +- * apdump - Table get/dump routines +- */ +-int ap_dump_table_from_file(char *pathname); +- +-int ap_dump_table_by_name(char *signature); +- +-int ap_dump_table_by_address(char *ascii_address); +- +-int ap_dump_all_tables(void); +- +-u8 ap_is_valid_header(struct acpi_table_header *table); +- +-u8 ap_is_valid_checksum(struct acpi_table_header *table); +- +-u32 ap_get_table_length(struct acpi_table_header *table); +- +-/* +- * apfiles - File I/O utilities +- */ +-int ap_open_output_file(char *pathname); +- +-int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance); +- +-struct acpi_table_header *ap_get_table_from_file(char *pathname, +- u32 *file_size); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/acpidump/apdump.c b/tools/power/acpi/tools/acpidump/apdump.c +--- a/tools/power/acpi/tools/acpidump/apdump.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/acpidump/apdump.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,437 +0,0 @@ +-/****************************************************************************** +- * +- * Module Name: apdump - Dump routines for ACPI tables (acpidump) +- * +- *****************************************************************************/ +- +-/* +- * Copyright (C) 2000 - 2017, Intel Corp. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions, and the following disclaimer, +- * without modification. +- * 2. Redistributions in binary form must reproduce at minimum a disclaimer +- * substantially similar to the "NO WARRANTY" disclaimer below +- * ("Disclaimer") and any redistribution must be conditioned upon +- * including a substantially similar Disclaimer requirement for further +- * binary redistribution. +- * 3. Neither the names of the above-listed copyright holders nor the names +- * of any contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * Alternatively, this software may be distributed under the terms of the +- * GNU General Public License ("GPL") version 2 as published by the Free +- * Software Foundation. +- * +- * NO WARRANTY +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR +- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +- * POSSIBILITY OF SUCH DAMAGES. +- */ +- +-#include "acpidump.h" +- +-/* Local prototypes */ +- +-static int +-ap_dump_table_buffer(struct acpi_table_header *table, +- u32 instance, acpi_physical_address address); +- +-/****************************************************************************** +- * +- * FUNCTION: ap_is_valid_header +- * +- * PARAMETERS: table - Pointer to table to be validated +- * +- * RETURN: TRUE if the header appears to be valid. FALSE otherwise +- * +- * DESCRIPTION: Check for a valid ACPI table header +- * +- ******************************************************************************/ +- +-u8 ap_is_valid_header(struct acpi_table_header *table) +-{ +- +- if (!ACPI_VALIDATE_RSDP_SIG(table->signature)) { +- +- /* Make sure signature is all ASCII and a valid ACPI name */ +- +- if (!acpi_ut_valid_nameseg(table->signature)) { +- fprintf(stderr, +- "Table signature (0x%8.8X) is invalid\n", +- *(u32 *)table->signature); +- return (FALSE); +- } +- +- /* Check for minimum table length */ +- +- if (table->length < sizeof(struct acpi_table_header)) { +- fprintf(stderr, "Table length (0x%8.8X) is invalid\n", +- table->length); +- return (FALSE); +- } +- } +- +- return (TRUE); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_is_valid_checksum +- * +- * PARAMETERS: table - Pointer to table to be validated +- * +- * RETURN: TRUE if the checksum appears to be valid. FALSE otherwise. +- * +- * DESCRIPTION: Check for a valid ACPI table checksum. +- * +- ******************************************************************************/ +- +-u8 ap_is_valid_checksum(struct acpi_table_header *table) +-{ +- acpi_status status; +- struct acpi_table_rsdp *rsdp; +- +- if (ACPI_VALIDATE_RSDP_SIG(table->signature)) { +- /* +- * Checksum for RSDP. +- * Note: Other checksums are computed during the table dump. +- */ +- rsdp = ACPI_CAST_PTR(struct acpi_table_rsdp, table); +- status = acpi_tb_validate_rsdp(rsdp); +- } else { +- status = acpi_tb_verify_checksum(table, table->length); +- } +- +- if (ACPI_FAILURE(status)) { +- fprintf(stderr, "%4.4s: Warning: wrong checksum in table\n", +- table->signature); +- } +- +- return (AE_OK); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_get_table_length +- * +- * PARAMETERS: table - Pointer to the table +- * +- * RETURN: Table length +- * +- * DESCRIPTION: Obtain table length according to table signature. +- * +- ******************************************************************************/ +- +-u32 ap_get_table_length(struct acpi_table_header *table) +-{ +- struct acpi_table_rsdp *rsdp; +- +- /* Check if table is valid */ +- +- if (!ap_is_valid_header(table)) { +- return (0); +- } +- +- if (ACPI_VALIDATE_RSDP_SIG(table->signature)) { +- rsdp = ACPI_CAST_PTR(struct acpi_table_rsdp, table); +- return (acpi_tb_get_rsdp_length(rsdp)); +- } +- +- /* Normal ACPI table */ +- +- return (table->length); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_dump_table_buffer +- * +- * PARAMETERS: table - ACPI table to be dumped +- * instance - ACPI table instance no. to be dumped +- * address - Physical address of the table +- * +- * RETURN: None +- * +- * DESCRIPTION: Dump an ACPI table in standard ASCII hex format, with a +- * header that is compatible with the acpi_xtract utility. +- * +- ******************************************************************************/ +- +-static int +-ap_dump_table_buffer(struct acpi_table_header *table, +- u32 instance, acpi_physical_address address) +-{ +- u32 table_length; +- +- table_length = ap_get_table_length(table); +- +- /* Print only the header if requested */ +- +- if (gbl_summary_mode) { +- acpi_tb_print_table_header(address, table); +- return (0); +- } +- +- /* Dump to binary file if requested */ +- +- if (gbl_binary_mode) { +- return (ap_write_to_binary_file(table, instance)); +- } +- +- /* +- * Dump the table with header for use with acpixtract utility. +- * Note: simplest to just always emit a 64-bit address. acpi_xtract +- * utility can handle this. +- */ +- fprintf(gbl_output_file, "%4.4s @ 0x%8.8X%8.8X\n", +- table->signature, ACPI_FORMAT_UINT64(address)); +- +- acpi_ut_dump_buffer_to_file(gbl_output_file, +- ACPI_CAST_PTR(u8, table), table_length, +- DB_BYTE_DISPLAY, 0); +- fprintf(gbl_output_file, "\n"); +- return (0); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_dump_all_tables +- * +- * PARAMETERS: None +- * +- * RETURN: Status +- * +- * DESCRIPTION: Get all tables from the RSDT/XSDT (or at least all of the +- * tables that we can possibly get). +- * +- ******************************************************************************/ +- +-int ap_dump_all_tables(void) +-{ +- struct acpi_table_header *table; +- u32 instance = 0; +- acpi_physical_address address; +- acpi_status status; +- int table_status; +- u32 i; +- +- /* Get and dump all available ACPI tables */ +- +- for (i = 0; i < AP_MAX_ACPI_FILES; i++) { +- status = +- acpi_os_get_table_by_index(i, &table, &instance, &address); +- if (ACPI_FAILURE(status)) { +- +- /* AE_LIMIT means that no more tables are available */ +- +- if (status == AE_LIMIT) { +- return (0); +- } else if (i == 0) { +- fprintf(stderr, +- "Could not get ACPI tables, %s\n", +- acpi_format_exception(status)); +- return (-1); +- } else { +- fprintf(stderr, +- "Could not get ACPI table at index %u, %s\n", +- i, acpi_format_exception(status)); +- continue; +- } +- } +- +- table_status = ap_dump_table_buffer(table, instance, address); +- ACPI_FREE(table); +- +- if (table_status) { +- break; +- } +- } +- +- /* Something seriously bad happened if the loop terminates here */ +- +- return (-1); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_dump_table_by_address +- * +- * PARAMETERS: ascii_address - Address for requested ACPI table +- * +- * RETURN: Status +- * +- * DESCRIPTION: Get an ACPI table via a physical address and dump it. +- * +- ******************************************************************************/ +- +-int ap_dump_table_by_address(char *ascii_address) +-{ +- acpi_physical_address address; +- struct acpi_table_header *table; +- acpi_status status; +- int table_status; +- u64 long_address; +- +- /* Convert argument to an integer physical address */ +- +- status = acpi_ut_strtoul64(ascii_address, ACPI_STRTOUL_64BIT, +- &long_address); +- if (ACPI_FAILURE(status)) { +- fprintf(stderr, "%s: Could not convert to a physical address\n", +- ascii_address); +- return (-1); +- } +- +- address = (acpi_physical_address)long_address; +- status = acpi_os_get_table_by_address(address, &table); +- if (ACPI_FAILURE(status)) { +- fprintf(stderr, "Could not get table at 0x%8.8X%8.8X, %s\n", +- ACPI_FORMAT_UINT64(address), +- acpi_format_exception(status)); +- return (-1); +- } +- +- table_status = ap_dump_table_buffer(table, 0, address); +- ACPI_FREE(table); +- return (table_status); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_dump_table_by_name +- * +- * PARAMETERS: signature - Requested ACPI table signature +- * +- * RETURN: Status +- * +- * DESCRIPTION: Get an ACPI table via a signature and dump it. Handles +- * multiple tables with the same signature (SSDTs). +- * +- ******************************************************************************/ +- +-int ap_dump_table_by_name(char *signature) +-{ +- char local_signature[ACPI_NAME_SIZE + 1]; +- u32 instance; +- struct acpi_table_header *table; +- acpi_physical_address address; +- acpi_status status; +- int table_status; +- +- if (strlen(signature) != ACPI_NAME_SIZE) { +- fprintf(stderr, +- "Invalid table signature [%s]: must be exactly 4 characters\n", +- signature); +- return (-1); +- } +- +- /* Table signatures are expected to be uppercase */ +- +- strcpy(local_signature, signature); +- acpi_ut_strupr(local_signature); +- +- /* To be friendly, handle tables whose signatures do not match the name */ +- +- if (ACPI_COMPARE_NAME(local_signature, "FADT")) { +- strcpy(local_signature, ACPI_SIG_FADT); +- } else if (ACPI_COMPARE_NAME(local_signature, "MADT")) { +- strcpy(local_signature, ACPI_SIG_MADT); +- } +- +- /* Dump all instances of this signature (to handle multiple SSDTs) */ +- +- for (instance = 0; instance < AP_MAX_ACPI_FILES; instance++) { +- status = acpi_os_get_table_by_name(local_signature, instance, +- &table, &address); +- if (ACPI_FAILURE(status)) { +- +- /* AE_LIMIT means that no more tables are available */ +- +- if (status == AE_LIMIT) { +- return (0); +- } +- +- fprintf(stderr, +- "Could not get ACPI table with signature [%s], %s\n", +- local_signature, acpi_format_exception(status)); +- return (-1); +- } +- +- table_status = ap_dump_table_buffer(table, instance, address); +- ACPI_FREE(table); +- +- if (table_status) { +- break; +- } +- } +- +- /* Something seriously bad happened if the loop terminates here */ +- +- return (-1); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_dump_table_from_file +- * +- * PARAMETERS: pathname - File containing the binary ACPI table +- * +- * RETURN: Status +- * +- * DESCRIPTION: Dump an ACPI table from a binary file +- * +- ******************************************************************************/ +- +-int ap_dump_table_from_file(char *pathname) +-{ +- struct acpi_table_header *table; +- u32 file_size = 0; +- int table_status = -1; +- +- /* Get the entire ACPI table from the file */ +- +- table = ap_get_table_from_file(pathname, &file_size); +- if (!table) { +- return (-1); +- } +- +- if (!acpi_ut_valid_nameseg(table->signature)) { +- fprintf(stderr, +- "No valid ACPI signature was found in input file %s\n", +- pathname); +- } +- +- /* File must be at least as long as the table length */ +- +- if (table->length > file_size) { +- fprintf(stderr, +- "Table length (0x%X) is too large for input file (0x%X) %s\n", +- table->length, file_size, pathname); +- goto exit; +- } +- +- if (gbl_verbose_mode) { +- fprintf(stderr, +- "Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n", +- pathname, table->signature, file_size, file_size); +- } +- +- table_status = ap_dump_table_buffer(table, 0, 0); +- +-exit: +- ACPI_FREE(table); +- return (table_status); +-} +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c +--- a/tools/power/acpi/tools/acpidump/apfiles.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/acpidump/apfiles.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,257 +0,0 @@ +-/****************************************************************************** +- * +- * Module Name: apfiles - File-related functions for acpidump utility +- * +- *****************************************************************************/ +- +-/* +- * Copyright (C) 2000 - 2017, Intel Corp. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions, and the following disclaimer, +- * without modification. +- * 2. Redistributions in binary form must reproduce at minimum a disclaimer +- * substantially similar to the "NO WARRANTY" disclaimer below +- * ("Disclaimer") and any redistribution must be conditioned upon +- * including a substantially similar Disclaimer requirement for further +- * binary redistribution. +- * 3. Neither the names of the above-listed copyright holders nor the names +- * of any contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * Alternatively, this software may be distributed under the terms of the +- * GNU General Public License ("GPL") version 2 as published by the Free +- * Software Foundation. +- * +- * NO WARRANTY +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR +- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +- * POSSIBILITY OF SUCH DAMAGES. +- */ +- +-#include "acpidump.h" +- +-/* Local prototypes */ +- +-static int ap_is_existing_file(char *pathname); +- +-/****************************************************************************** +- * +- * FUNCTION: ap_is_existing_file +- * +- * PARAMETERS: pathname - Output filename +- * +- * RETURN: 0 on success +- * +- * DESCRIPTION: Query for file overwrite if it already exists. +- * +- ******************************************************************************/ +- +-static int ap_is_existing_file(char *pathname) +-{ +-#if !defined(_GNU_EFI) && !defined(_EDK2_EFI) +- struct stat stat_info; +- +- if (!stat(pathname, &stat_info)) { +- fprintf(stderr, +- "Target path already exists, overwrite? [y|n] "); +- +- if (getchar() != 'y') { +- return (-1); +- } +- } +-#endif +- +- return 0; +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_open_output_file +- * +- * PARAMETERS: pathname - Output filename +- * +- * RETURN: Open file handle +- * +- * DESCRIPTION: Open a text output file for acpidump. Checks if file already +- * exists. +- * +- ******************************************************************************/ +- +-int ap_open_output_file(char *pathname) +-{ +- ACPI_FILE file; +- +- /* If file exists, prompt for overwrite */ +- +- if (ap_is_existing_file(pathname) != 0) { +- return (-1); +- } +- +- /* Point stdout to the file */ +- +- file = fopen(pathname, "w"); +- if (!file) { +- fprintf(stderr, "Could not open output file: %s\n", pathname); +- return (-1); +- } +- +- /* Save the file and path */ +- +- gbl_output_file = file; +- gbl_output_filename = pathname; +- return (0); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_write_to_binary_file +- * +- * PARAMETERS: table - ACPI table to be written +- * instance - ACPI table instance no. to be written +- * +- * RETURN: Status +- * +- * DESCRIPTION: Write an ACPI table to a binary file. Builds the output +- * filename from the table signature. +- * +- ******************************************************************************/ +- +-int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance) +-{ +- char filename[ACPI_NAME_SIZE + 16]; +- char instance_str[16]; +- ACPI_FILE file; +- acpi_size actual; +- u32 table_length; +- +- /* Obtain table length */ +- +- table_length = ap_get_table_length(table); +- +- /* Construct lower-case filename from the table local signature */ +- +- if (ACPI_VALIDATE_RSDP_SIG(table->signature)) { +- ACPI_MOVE_NAME(filename, ACPI_RSDP_NAME); +- } else { +- ACPI_MOVE_NAME(filename, table->signature); +- } +- +- filename[0] = (char)tolower((int)filename[0]); +- filename[1] = (char)tolower((int)filename[1]); +- filename[2] = (char)tolower((int)filename[2]); +- filename[3] = (char)tolower((int)filename[3]); +- filename[ACPI_NAME_SIZE] = 0; +- +- /* Handle multiple SSDts - create different filenames for each */ +- +- if (instance > 0) { +- snprintf(instance_str, sizeof(instance_str), "%u", instance); +- strcat(filename, instance_str); +- } +- +- strcat(filename, FILE_SUFFIX_BINARY_TABLE); +- +- if (gbl_verbose_mode) { +- fprintf(stderr, +- "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n", +- table->signature, filename, table->length, +- table->length); +- } +- +- /* Open the file and dump the entire table in binary mode */ +- +- file = fopen(filename, "wb"); +- if (!file) { +- fprintf(stderr, "Could not open output file: %s\n", filename); +- return (-1); +- } +- +- actual = fwrite(table, 1, table_length, file); +- if (actual != table_length) { +- fprintf(stderr, "Error writing binary output file: %s\n", +- filename); +- fclose(file); +- return (-1); +- } +- +- fclose(file); +- return (0); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_get_table_from_file +- * +- * PARAMETERS: pathname - File containing the binary ACPI table +- * out_file_size - Where the file size is returned +- * +- * RETURN: Buffer containing the ACPI table. NULL on error. +- * +- * DESCRIPTION: Open a file and read it entirely into a new buffer +- * +- ******************************************************************************/ +- +-struct acpi_table_header *ap_get_table_from_file(char *pathname, +- u32 *out_file_size) +-{ +- struct acpi_table_header *buffer = NULL; +- ACPI_FILE file; +- u32 file_size; +- acpi_size actual; +- +- /* Must use binary mode */ +- +- file = fopen(pathname, "rb"); +- if (!file) { +- fprintf(stderr, "Could not open input file: %s\n", pathname); +- return (NULL); +- } +- +- /* Need file size to allocate a buffer */ +- +- file_size = cm_get_file_size(file); +- if (file_size == ACPI_UINT32_MAX) { +- fprintf(stderr, +- "Could not get input file size: %s\n", pathname); +- goto cleanup; +- } +- +- /* Allocate a buffer for the entire file */ +- +- buffer = ACPI_ALLOCATE_ZEROED(file_size); +- if (!buffer) { +- fprintf(stderr, +- "Could not allocate file buffer of size: %u\n", +- file_size); +- goto cleanup; +- } +- +- /* Read the entire file */ +- +- actual = fread(buffer, 1, file_size, file); +- if (actual != file_size) { +- fprintf(stderr, "Could not read input file: %s\n", pathname); +- ACPI_FREE(buffer); +- buffer = NULL; +- goto cleanup; +- } +- +- *out_file_size = file_size; +- +-cleanup: +- fclose(file); +- return (buffer); +-} +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c +--- a/tools/power/acpi/tools/acpidump/apmain.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/acpidump/apmain.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,382 +0,0 @@ +-/****************************************************************************** +- * +- * Module Name: apmain - Main module for the acpidump utility +- * +- *****************************************************************************/ +- +-/* +- * Copyright (C) 2000 - 2017, Intel Corp. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions, and the following disclaimer, +- * without modification. +- * 2. Redistributions in binary form must reproduce at minimum a disclaimer +- * substantially similar to the "NO WARRANTY" disclaimer below +- * ("Disclaimer") and any redistribution must be conditioned upon +- * including a substantially similar Disclaimer requirement for further +- * binary redistribution. +- * 3. Neither the names of the above-listed copyright holders nor the names +- * of any contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * Alternatively, this software may be distributed under the terms of the +- * GNU General Public License ("GPL") version 2 as published by the Free +- * Software Foundation. +- * +- * NO WARRANTY +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR +- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +- * POSSIBILITY OF SUCH DAMAGES. +- */ +- +-#define _DECLARE_GLOBALS +-#include "acpidump.h" +- +-/* +- * acpidump - A portable utility for obtaining system ACPI tables and dumping +- * them in an ASCII hex format suitable for binary extraction via acpixtract. +- * +- * Obtaining the system ACPI tables is an OS-specific operation. +- * +- * This utility can be ported to any host operating system by providing a +- * module containing system-specific versions of these interfaces: +- * +- * acpi_os_get_table_by_address +- * acpi_os_get_table_by_index +- * acpi_os_get_table_by_name +- * +- * See the ACPICA Reference Guide for the exact definitions of these +- * interfaces. Also, see these ACPICA source code modules for example +- * implementations: +- * +- * source/os_specific/service_layers/oswintbl.c +- * source/os_specific/service_layers/oslinuxtbl.c +- */ +- +-/* Local prototypes */ +- +-static void ap_display_usage(void); +- +-static int ap_do_options(int argc, char **argv); +- +-static int ap_insert_action(char *argument, u32 to_be_done); +- +-/* Table for deferred actions from command line options */ +- +-struct ap_dump_action action_table[AP_MAX_ACTIONS]; +-u32 current_action = 0; +- +-#define AP_UTILITY_NAME "ACPI Binary Table Dump Utility" +-#define AP_SUPPORTED_OPTIONS "?a:bc:f:hn:o:r:svxz" +- +-/****************************************************************************** +- * +- * FUNCTION: ap_display_usage +- * +- * DESCRIPTION: Usage message for the acpi_dump utility +- * +- ******************************************************************************/ +- +-static void ap_display_usage(void) +-{ +- +- ACPI_USAGE_HEADER("acpidump [options]"); +- +- ACPI_OPTION("-b", "Dump tables to binary files"); +- ACPI_OPTION("-h -?", "This help message"); +- ACPI_OPTION("-o ", "Redirect output to file"); +- ACPI_OPTION("-r
", "Dump tables from specified RSDP"); +- ACPI_OPTION("-s", "Print table summaries only"); +- ACPI_OPTION("-v", "Display version information"); +- ACPI_OPTION("-z", "Verbose mode"); +- +- ACPI_USAGE_TEXT("\nTable Options:\n"); +- +- ACPI_OPTION("-a
", "Get table via a physical address"); +- ACPI_OPTION("-c ", "Turning on/off customized table dumping"); +- ACPI_OPTION("-f ", "Get table via a binary file"); +- ACPI_OPTION("-n ", "Get table via a name/signature"); +- ACPI_OPTION("-x", "Do not use but dump XSDT"); +- ACPI_OPTION("-x -x", "Do not use or dump XSDT"); +- +- ACPI_USAGE_TEXT("\n" +- "Invocation without parameters dumps all available tables\n" +- "Multiple mixed instances of -a, -f, and -n are supported\n\n"); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_insert_action +- * +- * PARAMETERS: argument - Pointer to the argument for this action +- * to_be_done - What to do to process this action +- * +- * RETURN: Status +- * +- * DESCRIPTION: Add an action item to the action table +- * +- ******************************************************************************/ +- +-static int ap_insert_action(char *argument, u32 to_be_done) +-{ +- +- /* Insert action and check for table overflow */ +- +- action_table[current_action].argument = argument; +- action_table[current_action].to_be_done = to_be_done; +- +- current_action++; +- if (current_action > AP_MAX_ACTIONS) { +- fprintf(stderr, "Too many table options (max %u)\n", +- AP_MAX_ACTIONS); +- return (-1); +- } +- +- return (0); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_do_options +- * +- * PARAMETERS: argc/argv - Standard argc/argv +- * +- * RETURN: Status +- * +- * DESCRIPTION: Command line option processing. The main actions for getting +- * and dumping tables are deferred via the action table. +- * +- *****************************************************************************/ +- +-static int ap_do_options(int argc, char **argv) +-{ +- int j; +- acpi_status status; +- +- /* Command line options */ +- +- while ((j = +- acpi_getopt(argc, argv, AP_SUPPORTED_OPTIONS)) != ACPI_OPT_END) +- switch (j) { +- /* +- * Global options +- */ +- case 'b': /* Dump all input tables to binary files */ +- +- gbl_binary_mode = TRUE; +- continue; +- +- case 'c': /* Dump customized tables */ +- +- if (!strcmp(acpi_gbl_optarg, "on")) { +- gbl_dump_customized_tables = TRUE; +- } else if (!strcmp(acpi_gbl_optarg, "off")) { +- gbl_dump_customized_tables = FALSE; +- } else { +- fprintf(stderr, +- "%s: Cannot handle this switch, please use on|off\n", +- acpi_gbl_optarg); +- return (-1); +- } +- continue; +- +- case 'h': +- case '?': +- +- ap_display_usage(); +- return (1); +- +- case 'o': /* Redirect output to a single file */ +- +- if (ap_open_output_file(acpi_gbl_optarg)) { +- return (-1); +- } +- continue; +- +- case 'r': /* Dump tables from specified RSDP */ +- +- status = +- acpi_ut_strtoul64(acpi_gbl_optarg, +- ACPI_STRTOUL_64BIT, +- &gbl_rsdp_base); +- if (ACPI_FAILURE(status)) { +- fprintf(stderr, +- "%s: Could not convert to a physical address\n", +- acpi_gbl_optarg); +- return (-1); +- } +- continue; +- +- case 's': /* Print table summaries only */ +- +- gbl_summary_mode = TRUE; +- continue; +- +- case 'x': /* Do not use XSDT */ +- +- if (!acpi_gbl_do_not_use_xsdt) { +- acpi_gbl_do_not_use_xsdt = TRUE; +- } else { +- gbl_do_not_dump_xsdt = TRUE; +- } +- continue; +- +- case 'v': /* Revision/version */ +- +- acpi_os_printf(ACPI_COMMON_SIGNON(AP_UTILITY_NAME)); +- return (1); +- +- case 'z': /* Verbose mode */ +- +- gbl_verbose_mode = TRUE; +- fprintf(stderr, ACPI_COMMON_SIGNON(AP_UTILITY_NAME)); +- continue; +- +- /* +- * Table options +- */ +- case 'a': /* Get table by physical address */ +- +- if (ap_insert_action +- (acpi_gbl_optarg, AP_DUMP_TABLE_BY_ADDRESS)) { +- return (-1); +- } +- break; +- +- case 'f': /* Get table from a file */ +- +- if (ap_insert_action +- (acpi_gbl_optarg, AP_DUMP_TABLE_BY_FILE)) { +- return (-1); +- } +- break; +- +- case 'n': /* Get table by input name (signature) */ +- +- if (ap_insert_action +- (acpi_gbl_optarg, AP_DUMP_TABLE_BY_NAME)) { +- return (-1); +- } +- break; +- +- default: +- +- ap_display_usage(); +- return (-1); +- } +- +- /* If there are no actions, this means "get/dump all tables" */ +- +- if (current_action == 0) { +- if (ap_insert_action(NULL, AP_DUMP_ALL_TABLES)) { +- return (-1); +- } +- } +- +- return (0); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: main +- * +- * PARAMETERS: argc/argv - Standard argc/argv +- * +- * RETURN: Status +- * +- * DESCRIPTION: C main function for acpidump utility +- * +- ******************************************************************************/ +- +-#if !defined(_GNU_EFI) && !defined(_EDK2_EFI) +-int ACPI_SYSTEM_XFACE main(int argc, char *argv[]) +-#else +-int ACPI_SYSTEM_XFACE acpi_main(int argc, char *argv[]) +-#endif +-{ +- int status = 0; +- struct ap_dump_action *action; +- u32 file_size; +- u32 i; +- +- ACPI_DEBUG_INITIALIZE(); /* For debug version only */ +- acpi_os_initialize(); +- gbl_output_file = ACPI_FILE_OUT; +- acpi_gbl_integer_byte_width = 8; +- +- /* Process command line options */ +- +- status = ap_do_options(argc, argv); +- if (status > 0) { +- return (0); +- } +- if (status < 0) { +- return (status); +- } +- +- /* Get/dump ACPI table(s) as requested */ +- +- for (i = 0; i < current_action; i++) { +- action = &action_table[i]; +- switch (action->to_be_done) { +- case AP_DUMP_ALL_TABLES: +- +- status = ap_dump_all_tables(); +- break; +- +- case AP_DUMP_TABLE_BY_ADDRESS: +- +- status = ap_dump_table_by_address(action->argument); +- break; +- +- case AP_DUMP_TABLE_BY_NAME: +- +- status = ap_dump_table_by_name(action->argument); +- break; +- +- case AP_DUMP_TABLE_BY_FILE: +- +- status = ap_dump_table_from_file(action->argument); +- break; +- +- default: +- +- fprintf(stderr, +- "Internal error, invalid action: 0x%X\n", +- action->to_be_done); +- return (-1); +- } +- +- if (status) { +- return (status); +- } +- } +- +- if (gbl_output_filename) { +- if (gbl_verbose_mode) { +- +- /* Summary for the output file */ +- +- file_size = cm_get_file_size(gbl_output_file); +- fprintf(stderr, +- "Output file %s contains 0x%X (%u) bytes\n\n", +- gbl_output_filename, file_size, file_size); +- } +- +- fclose(gbl_output_file); +- } +- +- return (status); +-} +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/ec/Makefile b/tools/power/acpi/tools/ec/Makefile +--- a/tools/power/acpi/tools/ec/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/ec/Makefile 1970-01-01 08:00:00.000000000 +0800 +@@ -1,17 +0,0 @@ +-# tools/power/acpi/tools/acpidump/Makefile - ACPI tool Makefile +-# +-# Copyright (c) 2015, Intel Corporation +-# Author: Lv Zheng +-# +-# This program is free software; you can redistribute it and/or +-# modify it under the terms of the GNU General Public License +-# as published by the Free Software Foundation; version 2 +-# of the License. +- +-include ../../Makefile.config +- +-TOOL = ec +-TOOL_OBJS = \ +- ec_access.o +- +-include ../../Makefile.rules +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/ec/ec_access.c b/tools/power/acpi/tools/ec/ec_access.c +--- a/tools/power/acpi/tools/ec/ec_access.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/ec/ec_access.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,238 +0,0 @@ +-/* +- * ec_access.c +- * +- * Copyright (C) 2010 SUSE Linux Products GmbH +- * Author: +- * Thomas Renninger +- * +- * This work is licensed under the terms of the GNU GPL, version 2. +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +- +-#define EC_SPACE_SIZE 256 +-#define SYSFS_PATH "/sys/kernel/debug/ec/ec0/io" +- +-/* TBD/Enhancements: +- - Provide param for accessing different ECs (not supported by kernel yet) +-*/ +- +-static int read_mode = -1; +-static int sleep_time; +-static int write_byte_offset = -1; +-static int read_byte_offset = -1; +-static uint8_t write_value = -1; +- +-void usage(char progname[], int exit_status) +-{ +- printf("Usage:\n"); +- printf("1) %s -r [-s sleep]\n", basename(progname)); +- printf("2) %s -b byte_offset\n", basename(progname)); +- printf("3) %s -w byte_offset -v value\n\n", basename(progname)); +- +- puts("\t-r [-s sleep] : Dump EC registers"); +- puts("\t If sleep is given, sleep x seconds,"); +- puts("\t re-read EC registers and show changes"); +- puts("\t-b offset : Read value at byte_offset (in hex)"); +- puts("\t-w offset -v value : Write value at byte_offset"); +- puts("\t-h : Print this help\n\n"); +- puts("Offsets and values are in hexadecimal number system."); +- puts("The offset and value must be between 0 and 0xff."); +- exit(exit_status); +-} +- +-void parse_opts(int argc, char *argv[]) +-{ +- int c; +- +- while ((c = getopt(argc, argv, "rs:b:w:v:h")) != -1) { +- +- switch (c) { +- case 'r': +- if (read_mode != -1) +- usage(argv[0], EXIT_FAILURE); +- read_mode = 1; +- break; +- case 's': +- if (read_mode != -1 && read_mode != 1) +- usage(argv[0], EXIT_FAILURE); +- +- sleep_time = atoi(optarg); +- if (sleep_time <= 0) { +- sleep_time = 0; +- usage(argv[0], EXIT_FAILURE); +- printf("Bad sleep time: %s\n", optarg); +- } +- break; +- case 'b': +- if (read_mode != -1) +- usage(argv[0], EXIT_FAILURE); +- read_mode = 1; +- read_byte_offset = strtoul(optarg, NULL, 16); +- break; +- case 'w': +- if (read_mode != -1) +- usage(argv[0], EXIT_FAILURE); +- read_mode = 0; +- write_byte_offset = strtoul(optarg, NULL, 16); +- break; +- case 'v': +- write_value = strtoul(optarg, NULL, 16); +- break; +- case 'h': +- usage(argv[0], EXIT_SUCCESS); +- default: +- fprintf(stderr, "Unknown option!\n"); +- usage(argv[0], EXIT_FAILURE); +- } +- } +- if (read_mode == 0) { +- if (write_byte_offset < 0 || +- write_byte_offset >= EC_SPACE_SIZE) { +- fprintf(stderr, "Wrong byte offset 0x%.2x, valid: " +- "[0-0x%.2x]\n", +- write_byte_offset, EC_SPACE_SIZE - 1); +- usage(argv[0], EXIT_FAILURE); +- } +- if (write_value < 0 || +- write_value >= 255) { +- fprintf(stderr, "Wrong byte offset 0x%.2x, valid:" +- "[0-0xff]\n", write_byte_offset); +- usage(argv[0], EXIT_FAILURE); +- } +- } +- if (read_mode == 1 && read_byte_offset != -1) { +- if (read_byte_offset < -1 || +- read_byte_offset >= EC_SPACE_SIZE) { +- fprintf(stderr, "Wrong byte offset 0x%.2x, valid: " +- "[0-0x%.2x]\n", +- read_byte_offset, EC_SPACE_SIZE - 1); +- usage(argv[0], EXIT_FAILURE); +- } +- } +- /* Add additional parameter checks here */ +-} +- +-void dump_ec(int fd) +-{ +- char buf[EC_SPACE_SIZE]; +- char buf2[EC_SPACE_SIZE]; +- int byte_off, bytes_read; +- +- bytes_read = read(fd, buf, EC_SPACE_SIZE); +- +- if (bytes_read == -1) +- err(EXIT_FAILURE, "Could not read from %s\n", SYSFS_PATH); +- +- if (bytes_read != EC_SPACE_SIZE) +- fprintf(stderr, "Could only read %d bytes\n", bytes_read); +- +- printf(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F"); +- for (byte_off = 0; byte_off < bytes_read; byte_off++) { +- if ((byte_off % 16) == 0) +- printf("\n%.2X: ", byte_off); +- printf(" %.2x ", (uint8_t)buf[byte_off]); +- } +- printf("\n"); +- +- if (!sleep_time) +- return; +- +- printf("\n"); +- lseek(fd, 0, SEEK_SET); +- sleep(sleep_time); +- +- bytes_read = read(fd, buf2, EC_SPACE_SIZE); +- +- if (bytes_read == -1) +- err(EXIT_FAILURE, "Could not read from %s\n", SYSFS_PATH); +- +- if (bytes_read != EC_SPACE_SIZE) +- fprintf(stderr, "Could only read %d bytes\n", bytes_read); +- +- printf(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F"); +- for (byte_off = 0; byte_off < bytes_read; byte_off++) { +- if ((byte_off % 16) == 0) +- printf("\n%.2X: ", byte_off); +- +- if (buf[byte_off] == buf2[byte_off]) +- printf(" %.2x ", (uint8_t)buf2[byte_off]); +- else +- printf("*%.2x ", (uint8_t)buf2[byte_off]); +- } +- printf("\n"); +-} +- +-void read_ec_val(int fd, int byte_offset) +-{ +- uint8_t buf; +- int error; +- +- error = lseek(fd, byte_offset, SEEK_SET); +- if (error != byte_offset) +- err(EXIT_FAILURE, "Cannot set offset to 0x%.2x", byte_offset); +- +- error = read(fd, &buf, 1); +- if (error != 1) +- err(EXIT_FAILURE, "Could not read byte 0x%.2x from %s\n", +- byte_offset, SYSFS_PATH); +- printf("0x%.2x\n", buf); +- return; +-} +- +-void write_ec_val(int fd, int byte_offset, uint8_t value) +-{ +- int error; +- +- error = lseek(fd, byte_offset, SEEK_SET); +- if (error != byte_offset) +- err(EXIT_FAILURE, "Cannot set offset to 0x%.2x", byte_offset); +- +- error = write(fd, &value, 1); +- if (error != 1) +- err(EXIT_FAILURE, "Cannot write value 0x%.2x to offset 0x%.2x", +- value, byte_offset); +-} +- +-int main(int argc, char *argv[]) +-{ +- int file_mode = O_RDONLY; +- int fd; +- +- parse_opts(argc, argv); +- +- if (read_mode == 0) +- file_mode = O_WRONLY; +- else if (read_mode == 1) +- file_mode = O_RDONLY; +- else +- usage(argv[0], EXIT_FAILURE); +- +- fd = open(SYSFS_PATH, file_mode); +- if (fd == -1) +- err(EXIT_FAILURE, "%s", SYSFS_PATH); +- +- if (read_mode) +- if (read_byte_offset == -1) +- dump_ec(fd); +- else if (read_byte_offset < 0 || +- read_byte_offset >= EC_SPACE_SIZE) +- usage(argv[0], EXIT_FAILURE); +- else +- read_ec_val(fd, read_byte_offset); +- else +- write_ec_val(fd, write_byte_offset, write_value); +- close(fd); +- +- exit(EXIT_SUCCESS); +-} diff --git a/packages/base/any/kernels/4.14-lts/patches/drivers-i2c-busses-xgs_iproc_smbus-clk-freq.patch b/packages/base/any/kernels/4.14-lts/patches/drivers-i2c-busses-xgs_iproc_smbus-clk-freq.patch new file mode 100644 index 00000000..3042bbd9 --- /dev/null +++ b/packages/base/any/kernels/4.14-lts/patches/drivers-i2c-busses-xgs_iproc_smbus-clk-freq.patch @@ -0,0 +1,86 @@ +diff -urpN a/drivers/i2c/busses/xgs_iproc_smbus.c b/drivers/i2c/busses/xgs_iproc_smbus.c +--- a/drivers/i2c/busses/xgs_iproc_smbus.c 2018-12-17 15:00:29.412457650 +0000 ++++ b/drivers/i2c/busses/xgs_iproc_smbus.c 2018-12-17 15:01:26.255275662 +0000 +@@ -52,6 +52,8 @@ + (regval & ~(mask)) | \ + ((fldval) << (startbit)) + ++//#define IPROC_SMB_DBG 1 ++ + typedef enum iproc_smb_clk_freq { + I2C_SPEED_100KHz = 0, + I2C_SPEED_400KHz = 1, +@@ -178,7 +180,7 @@ static int iproc_smb_set_clk_freq(void _ + SETREGFLDVAL(regval, val, CCB_SMB_TIMGCFG_MODE400_MASK, + CCB_SMB_TIMGCFG_MODE400_SHIFT); + writel(regval, base_addr + CCB_SMB_TIMGCFG_REG); +- ++ + return 0; + } + +@@ -208,9 +210,20 @@ static int iproc_smbus_block_init(struct + udelay(100); + + /* Set default clock frequency */ +- if (of_property_read_u32(dn, "clock-frequency", &i2c_clk_freq)) +- /*no property available, use default: 100KHz*/ +- i2c_clk_freq = I2C_SPEED_100KHz; ++ if (of_property_read_u32(dn, "clock-frequency", &i2c_clk_freq)) { ++ /*no property available, use default: 100KHz*/ ++ i2c_clk_freq = 100000; ++ } ++ ++/* Edgecore patch */ ++ if (i2c_clk_freq == 400000) { ++ dev_info(dev->dev, "bus set to %u Hz\n", i2c_clk_freq); ++ i2c_clk_freq = I2C_SPEED_400KHz; ++ } else { ++ dev_info(dev->dev, "bus set to %u Hz\n", 100000); ++ i2c_clk_freq = I2C_SPEED_100KHz; ++ } ++ + iproc_smb_set_clk_freq(base_addr, i2c_clk_freq); + + /* Disable intrs */ +@@ -577,7 +590,9 @@ static int iproc_smb_data_send(struct i2 + + if (regval != MSTR_STS_XACT_SUCCESS) { + /* We can flush Tx FIFO here */ ++#ifdef IPROC_SMB_DBG + dev_err(dev->dev, "Send: Error in transaction\n"); ++#endif + return -EREMOTEIO; + } + } +@@ -662,7 +677,9 @@ static int iproc_smb_data_recv(struct i2 + + if (regval != MSTR_STS_XACT_SUCCESS) { + /* We can flush Tx FIFO here */ ++#ifdef IPROC_SMB_DBG + dev_info(dev->dev, "Error in transaction\n"); ++#endif + return -EREMOTEIO; + } + } +@@ -840,8 +857,10 @@ static int iproc_smb_xfer(struct i2c_ada + } + + if (rc < 0) { ++#ifdef IPROC_SMB_DBG + dev_info(dev->dev, "%s error accessing\n", + (read_write == I2C_SMBUS_READ) ? "Read" : "Write"); ++#endif + up(&dev->xfer_lock); + return -EREMOTEIO; + } +@@ -856,7 +875,8 @@ static int iproc_smb_xfer(struct i2c_ada + } + } + +- msleep(1); ++ /* Edge-core comments out the sleep to speed up EEPROM dump */ ++ //msleep(1); + up(&dev->xfer_lock); + + return (rc); diff --git a/packages/base/any/kernels/4.14-lts/patches/drivers-usb-phy-phy-xgs-iproc-usb-phy-mode.patch b/packages/base/any/kernels/4.14-lts/patches/drivers-usb-phy-phy-xgs-iproc-usb-phy-mode.patch new file mode 100644 index 00000000..56cc0e8b --- /dev/null +++ b/packages/base/any/kernels/4.14-lts/patches/drivers-usb-phy-phy-xgs-iproc-usb-phy-mode.patch @@ -0,0 +1,26 @@ +diff -urpN a/drivers/usb/phy/phy-xgs-iproc.c b/drivers/usb/phy/phy-xgs-iproc.c +--- a/drivers/usb/phy/phy-xgs-iproc.c 2018-12-17 14:49:55.121649311 +0000 ++++ b/drivers/usb/phy/phy-xgs-iproc.c 2018-12-17 14:50:06.529412019 +0000 +@@ -161,12 +161,22 @@ static int xgs_iproc_usb_phy_mode(struct + int usb_mode = IPROC_USB_MODE_HOST; + u32 __maybe_unused val; + int __maybe_unused gpio_pin, ret; ++ const char *phy_mode_str; + + if (!wrap_base) + dev_warn(dev, "no wrap base addr"); + + if (of_device_is_compatible(dn, "brcm,usb-phy-hx4") || + of_device_is_compatible(dn, "brcm,usb-phy-kt2")) { ++ ++ /* Edge-core patch: use "usb-phy-mode" in dts to decide host/device mode */ ++ if (!of_property_read_string(dn, "usb-phy-mode", &phy_mode_str)) { ++ if (!strcasecmp(phy_mode_str, "host")) ++ return IPROC_USB_MODE_HOST; ++ if (!strcasecmp(phy_mode_str, "device")) ++ return IPROC_USB_MODE_DEVICE; ++ } ++ + /* gpio pin 4 to control host/device mode */ + gpio_pin = of_get_named_gpio(dev->of_node, "usbdev-gpio", 0); + diff --git a/packages/base/any/kernels/4.14-lts/patches/series b/packages/base/any/kernels/4.14-lts/patches/series index 3659add7..365505b3 100644 --- a/packages/base/any/kernels/4.14-lts/patches/series +++ b/packages/base/any/kernels/4.14-lts/patches/series @@ -1,3 +1,5 @@ +brcm-iproc-4.14.patch +drivers-usb-phy-phy-xgs-iproc-usb-phy-mode.patch +drivers-i2c-busses-xgs_iproc_smbus-clk-freq.patch 0001-drivers-i2c-muxes-pca954x-deselect-on-exit.patch 0002-driver-support-intel-igb-bcm5461S-phy.patch - diff --git a/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/.gitignore b/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/.gitignore deleted file mode 100644 index 5540b78d..00000000 --- a/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -kernel-* -linux-* -lib/ diff --git a/packages/base/any/kernels/4.4-lts/kconfig.mk b/packages/base/any/kernels/4.4-lts/kconfig.mk deleted file mode 100644 index 4262cad1..00000000 --- a/packages/base/any/kernels/4.4-lts/kconfig.mk +++ /dev/null @@ -1,26 +0,0 @@ -############################################################ -# -# -# Copyright 2015 Big Switch Networks, Inc. -# -# Licensed under the Eclipse Public License, Version 1.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.eclipse.org/legal/epl-v10.html -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -# either express or implied. See the License for the specific -# language governing permissions and limitations under the -# License. -# -# -############################################################ -THIS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) -K_MAJOR_VERSION := 4 -K_PATCH_LEVEL := 4 -K_SUB_LEVEL := 39 -K_SUFFIX := -K_PATCH_DIR := $(THIS_DIR)/patches diff --git a/packages/base/any/kernels/4.4-lts/patches/kernel-4.4-brcm-iproc.patch b/packages/base/any/kernels/4.4-lts/patches/kernel-4.4-brcm-iproc.patch deleted file mode 100644 index 4da5c804..00000000 --- a/packages/base/any/kernels/4.4-lts/patches/kernel-4.4-brcm-iproc.patch +++ /dev/null @@ -1,75281 +0,0 @@ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/Documentation/devicetree/bindings/gpio/xgs-gpio-iproc.txt b/Documentation/devicetree/bindings/gpio/xgs-gpio-iproc.txt ---- a/Documentation/devicetree/bindings/gpio/xgs-gpio-iproc.txt 1970-01-01 08:00:00.000000000 +0800 -+++ b/Documentation/devicetree/bindings/gpio/xgs-gpio-iproc.txt 2017-11-09 17:52:48.421892000 +0800 -@@ -0,0 +1,46 @@ -+Broadcom XGS iProc GPIO Controller -+ -+Required properties: -+- compatible : Should be "brcm,iproc-gpio,cca" or "brcm,iproc-gpio,ccg". -+ "brcm,iproc-gpio,cca" is used for CCA type gpio controllers on Helix4/Katana2/HR2. -+ "brcm,iproc-gpio,ccg" is used for CCG type gpio controllers on Grehound/Saber2/HR3/Greyhound2. -+- reg : Physical base address and length of the controller's registers. -+- #gpio-cells : should be 2 -+- ngpios : The number of GPIO's the controller provides. -+- interrupts : The interrupt id for the controller. -+- pin-base : The first chip GPIO pin provided by CCA or CCG. For Helix4, set to 4. -+- pin-offset : The offset of available CCA or CCG GPIO pins. For Helix4, set to 0. -+- gpio-controller : Marks the device node as a GPIO controller. -+ -+Optional properties: -+- interrupt-controller : Marks the device node as an interrupt controller. -+ -+ -+Examples for cca gpio: -+ -+ gpio_cca: gpio@18000060 { -+ compatible = "brcm,iproc-gpio,cca"; -+ #gpio-cells = <2>; -+ reg = gpio: <0x18000060 0x50>, -+ intr: <0x18000000 0x50>; -+ ngpios = <8>; -+ pin-offset = <0>; -+ pin-base = <4>; -+ gpio-controller; -+ interrupt-controller; -+ interrupts = ; -+ }; -+ -+ gpio_ccg: gpio@1800a000 { -+ compatible = "brcm,iproc-gpio,ccg"; -+ #gpio-cells = <2>; -+ reg = gpio: <0x1800a000 0x50>; -+ ngpios = <12>; -+ pin-offset = <4>; -+ pin-base = <4>; -+ gpio-controller; -+ interrupt-controller; -+ interrupts = ; -+ }; -+ -+ -\ No newline at end of file -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/Documentation/devicetree/bindings/net/xgs-iproc-mdio.txt b/Documentation/devicetree/bindings/net/xgs-iproc-mdio.txt ---- a/Documentation/devicetree/bindings/net/xgs-iproc-mdio.txt 1970-01-01 08:00:00.000000000 +0800 -+++ b/Documentation/devicetree/bindings/net/xgs-iproc-mdio.txt 2017-11-09 17:52:49.481900000 +0800 -@@ -0,0 +1,30 @@ -+* Broadcom XGS iProc MDIO bus controller -+ -+Required properties: -+- compatible: should be "brcm,iproc-ccb-mdio" or "brcm,iproc-ccg-mdio" or "brcm,iproc-cmicd-mdio" -+- reg: address and length of the register set for the MDIO interface -+- #size-cells: must be 0 -+- #address-cells: must be 1 -+- #bus-id: Physical bus ID -+- #logical-bus-id: Logical bus ID, required for cmicd -+- bus-type: "internal" or "external" -+- clocks: clock source -+ -+Example: -+ -+ mdio_int: mdio_int@18002000 { -+ compatible = "brcm,iproc-ccg-mdio"; -+ reg = <0x18002000 0x1000>; -+ #bus-id = <0>; -+ bus-type = "internal"; -+ clocks = <&iproc_apb_clk>; -+ }; -+ -+ mdio_ext: mdio_ext@03210000 { -+ compatible = "brcm,iproc-cmicd-mdio"; -+ reg = <0x03210000 0x1000>; -+ #bus-id = <2>; -+ #logical-bus-id = <0>; -+ bus-type = "external"; -+ clocks = <&iproc_apb_clk>; -+ }; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/Documentation/devicetree/bindings/pci/xgs-iproc-pcie.txt b/Documentation/devicetree/bindings/pci/xgs-iproc-pcie.txt ---- a/Documentation/devicetree/bindings/pci/xgs-iproc-pcie.txt 1970-01-01 08:00:00.000000000 +0800 -+++ b/Documentation/devicetree/bindings/pci/xgs-iproc-pcie.txt 2017-11-09 17:52:49.540901000 +0800 -@@ -0,0 +1,35 @@ -+* Broadcom XGS iProc PCIe controller -+ -+Required properties: -+- compatible: set to "brcm,iproc-pcie" -+- reg: base address and length of the PCIe controller -+- linux,pci-domain: PCI domain ID. Should be unique for each host controller -+- interrupts: interrupt ID -+- #address-cells: set to <3> -+- #size-cells: set to <2> -+- device_type: set to "pci" -+- ranges: ranges for the PCI memory and I/O regions -+ -+Optional properties: -+- phy-addr: PCIe PHY addr for MDIO access -+- bus-range: PCI bus numbers covered -+ -+Example: -+ -+ pcie0: pcie@18012000 { -+ compatible = "brcm,iproc-pcie"; -+ reg = <0x18012000 0x1000>; -+ linux,pci-domain = <0>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ ; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; -+ phy-addr = <0>; -+ }; -+ -\ No newline at end of file -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/Documentation/devicetree/bindings/spi/xgs-iproc-qspi.txt b/Documentation/devicetree/bindings/spi/xgs-iproc-qspi.txt ---- a/Documentation/devicetree/bindings/spi/xgs-iproc-qspi.txt 1970-01-01 08:00:00.000000000 +0800 -+++ b/Documentation/devicetree/bindings/spi/xgs-iproc-qspi.txt 2017-11-09 17:52:50.501910000 +0800 -@@ -0,0 +1,34 @@ -+BROADCOM XGS iProc QSPI controller -+ -+Required properties: -+- compatible: "brcm,iproc-qspi"; -+- reg: Offset and length of the register set including -+ mspi_hw: Master SPI -+ bspi_hw: Boot SPI -+ bspi_hw_raf: Boot SPI read ahead fifo -+ qspi_intr: QSPI interrupt related -+ idm_qspi:QSPI IDM related -+ cru_hw: QSPI CRU related -+- interrupts: interrupt id of the QSPI controller -+- clocks: clock source -+ -+Optional properties: -+- #chip-select: Specify the used chip select for controller with multi chip selects -+ -+Example: -+ -+ qspi: spi@18047000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "brcm,iproc-qspi"; -+ reg = mspi_hw:<0x18047200 0x188>, -+ bspi_hw:<0x18047000 0x050>, -+ bspi_hw_raf:<0x18047100 0x024>, -+ qspi_intr:<0x180473a0 0x01c>, -+ idm_qspi:<0x1811f408 0x004>, -+ cru_hw:<0x1800e000 0x004>; -+ interrupts = ; -+ #chip-select = <0>; -+ clocks = <&iproc_apb_clk>; -+ }; -+ -\ No newline at end of file -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/Kconfig b/arch/arm/Kconfig ---- a/arch/arm/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/arch/arm/Kconfig 2017-11-09 17:52:54.375925000 +0800 -@@ -850,6 +850,8 @@ source "arch/arm/mach-iop33x/Kconfig" - - source "arch/arm/mach-iop13xx/Kconfig" - -+source "arch/arm/mach-iproc/Kconfig" -+ - source "arch/arm/mach-ixp4xx/Kconfig" - - source "arch/arm/mach-keystone/Kconfig" -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/Makefile b/arch/arm/Makefile ---- a/arch/arm/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/arch/arm/Makefile 2017-11-09 17:52:54.385925000 +0800 -@@ -176,6 +176,7 @@ machine-$(CONFIG_ARCH_INTEGRATOR) += int - machine-$(CONFIG_ARCH_IOP13XX) += iop13xx - machine-$(CONFIG_ARCH_IOP32X) += iop32x - machine-$(CONFIG_ARCH_IOP33X) += iop33x -+machine-$(CONFIG_ARCH_XGS_IPROC) += iproc - machine-$(CONFIG_ARCH_IXP4XX) += ixp4xx - machine-$(CONFIG_ARCH_KEYSTONE) += keystone - machine-$(CONFIG_ARCH_KS8695) += ks8695 -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile ---- a/arch/arm/boot/dts/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/arch/arm/boot/dts/Makefile 2017-11-09 17:52:54.462930000 +0800 -@@ -777,6 +777,17 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ - mt8127-moose.dtb \ - mt8135-evbp1.dtb - dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb -+ -+dtb-$(CONFIG_MACH_HX4) += bcm956340.dtb -+dtb-$(CONFIG_MACH_KT2) += bcm956450.dtb -+dtb-$(CONFIG_MACH_HR2) += bcm956150.dtb -+dtb-$(CONFIG_MACH_GH) += bcm95341x.dtb -+dtb-$(CONFIG_MACH_GH2) += bcm956170.dtb bcm95357x.dtb -+dtb-$(CONFIG_MACH_SB2) += bcm956260.dtb -+dtb-$(CONFIG_MACH_WH2) += bcm953547.dtb -+dtb-$(CONFIG_MACH_HR3) += bcm956160.dtb \ -+ bcm953444.dtb -+ - endif - - dtstree := $(srctree)/$(src) -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-greyhound.dtsi b/arch/arm/boot/dts/bcm-greyhound.dtsi ---- a/arch/arm/boot/dts/bcm-greyhound.dtsi 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm-greyhound.dtsi 2017-11-09 17:52:54.682932000 +0800 -@@ -0,0 +1,362 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include -+#include "skeleton.dtsi" -+ -+ -+/ { -+ model = "Broadcom GH iProc"; -+ compatible = "brcm,greyhound"; -+ interrupt-parent = <&gic>; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a9"; -+ next-level-cache = <&L2>; -+ reg = <0x0>; -+ }; -+ }; -+ -+ core { -+ compatible = "simple-bus"; -+ ranges = <0x00000000 0x19000000 0x00023000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ a9pll: arm_clk@00000 { -+ #clock-cells = <0>; -+ compatible = "brcm,xgs-iproc-armpll"; -+ clocks = <&osc>; -+ reg = <0x0 0x1000>; -+ }; -+ -+ gic: interrupt-controller@21000 { -+ compatible = "arm,cortex-a9-gic"; -+ #interrupt-cells = <3>; -+ interrupt-controller; -+ reg = <0x21000 0x1000>, <0x20100 0x100>; -+ }; -+ -+ twd-timer@20600 { -+ compatible = "arm,cortex-a9-twd-timer"; -+ reg = <0x20600 0x100>; -+ interrupts = ; -+ clocks = <&periph_clk>; -+ }; -+ -+ timer@20200 { -+ compatible = "arm,cortex-a9-global-timer"; -+ reg = <0x20200 0x100>; -+ interrupts = ; -+ clocks = <&periph_clk>; -+ }; -+ -+ L2: l2-cache { -+ compatible = "arm,pl310-cache"; -+ reg = <0x22000 0x1000>; -+ cache-unified; -+ cache-level = <2>; -+ arm,filter-ranges = <0x60000000 0x80000000>; -+ }; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ osc: oscillator { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <25000000>; -+ }; -+ -+ periph_clk: periph_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&a9pll>; -+ clock-div = <2>; -+ clock-mult = <1>; -+ }; -+ -+ iproc_axi_clk: iproc_axi_clk@0x1800fc00 { -+ #clock-cells = <0>; -+ compatible = "brcm,xgs-iproc-axi-clk"; -+ clocks = <&osc>; -+ reg = <0x1800fc00 0x1c>; -+ }; -+ -+ iproc_apb_clk: iproc_apb_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&iproc_axi_clk>; -+ clock-div = <4>; -+ clock-mult = <1>; -+ }; -+ }; -+ -+ axi { -+ compatible = "simple-bus"; -+ ranges; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ uart0: serial@18020000 { -+ compatible = "snps,dw-apb-uart"; -+ reg = <0x18020000 0x100>; -+ interrupts = ; -+ clocks = <&iproc_apb_clk>; -+ reg-io-width = <4>; -+ reg-shift = <2>; -+ status = "disabled"; -+ }; -+ -+ uart1: serial@18021000 { -+ compatible = "snps,dw-apb-uart"; -+ reg = <0x18021000 0x100>; -+ interrupts = ; -+ clocks = <&iproc_apb_clk>; -+ reg-io-width = <4>; -+ reg-shift = <2>; -+ status = "disabled"; -+ }; -+ -+ gmac0: ethernet@18042000 { -+ compatible = "brcm,iproc-gmac"; -+ reg = <0x18042000 0x1000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ gpio_ccg: gpio@1800a000 { -+ compatible = "brcm,iproc-gpio,ccg"; -+ #gpio-cells = <2>; -+ reg = gpio: <0x1800a000 0x50>; -+ ngpios = <12>; -+ pin-offset = <4>; -+ pin-base = <4>; -+ gpio-controller; -+ interrupt-controller; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ usbphy0: usbphy0 { -+ #phy-cells = <0>; -+ compatible = "brcm,usb-phy,gh"; -+ reg = idm_usb2h: <0x18115000 0x1000>, -+ idm_usb2d: <0x18111000 0x1000>; -+ vbus-gpio = <&gpio_ccg 6 GPIO_ACTIVE_HIGH>; -+ status = "disabled"; -+ }; -+ -+ ehci0: usb@18048000 { -+ compatible = "generic-ehci"; -+ reg = <0x18048000 0x800>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ ohci0: usb@18048800 { -+ compatible = "generic-ohci"; -+ reg = <0x18048800 0x800>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ usbd: usbd@1804c000 { -+ compatible = "brcm,usbd,gh"; -+ reg = <0x1804c000 0x2000>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ nand: nand@18046000 { -+ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; -+ reg = <0x18046000 0x600>, -+ <0xf8105408 0x10>, -+ <0x18046f00 0x20>; -+ reg-names = "nand", "iproc-idm", "iproc-ext"; -+ interrupts = ; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ brcm,nand-has-wp; -+ status = "disabled"; -+ }; -+ -+ qspi: spi@18047000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "brcm,iproc-qspi"; -+ reg = mspi_hw:<0x18047200 0x188>, -+ bspi_hw:<0x18047000 0x050>, -+ bspi_hw_raf:<0x18047100 0x024>, -+ qspi_intr:<0x180473a0 0x01c>, -+ idm_qspi:<0xf8106408 0x004>, -+ cru_hw:<0x1800e000 0x004>; -+ interrupts = ; -+ #chip-select = <0>; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ i2c0: i2c@18008000 { -+ compatible = "brcm,iproc-i2c"; -+ reg = <0x18008000 0x100>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = ; -+ clock-frequency = <100000>; -+ status = "disabled"; -+ }; -+ -+ mdio_int: mdio_int@18002000 { -+ compatible = "brcm,iproc-ccg-mdio"; -+ reg = <0x18002000 0x1000>; -+ #bus-id = <0>; -+ bus-type = "internal"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ /* cmicd cmic_common mdio */ -+ mdio_ext: mdio_ext@03210000 { -+ compatible = "brcm,iproc-cmicd-mdio"; -+ reg = <0x03210000 0x1000>; -+ #bus-id = <2>; -+ #logical-bus-id = <0>; -+ bus-type = "external"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ pnor_flash: pnor_flash@18045000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "brcm,iproc-nor"; -+ reg = nor_regs: <0x18045000 0x1000>, -+ nor_mem: <0xE8000000 0x8000000>, -+ nor_sel: <0x18000c8c 0x4>, -+ nor_strap: <0x18000a5c 0x4>; -+ status = "disabled"; -+ }; -+ -+ hwrng: hwrng@18032000 { -+ compatible = "brcm,iproc-rng"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x18032000 0x1000>; -+ rng-type = "rng200"; -+ status = "disabled"; -+ }; -+ -+ iproc_wdt: iproc_wdt@18009000 { -+ compatible = "arm,sp805", "arm,primecell"; -+ reg = iproc_wdt_base: <0x18009000 0x1000>, -+ iproc_reset_reg: <0x1800f014 0x4>; -+ wdt_boot_status_bit = <0x0>; -+ clocks = <&iproc_apb_clk>; -+ clock-names = "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ /* cmicd */ -+ iproc_cmicd: iproc_cmicd@03200000 { -+ compatible = "brcm,iproc-cmicd"; -+ reg = <0x03200000 0x100000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ }; -+ -+ pcie0: pcie@18012000 { -+ compatible = "brcm,iproc-pcie", "iproc-p7"; -+ reg = <0x18012000 0x1000>; -+ linux,pci-domain = <0>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ ; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ /*non-prefetchable mem space, pcie addr 0x0 0x20000000, -+ * cpu addr 0x20000000, size 0x0 0x20000000 -+ */ -+ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; -+ phy-addr = <0>; -+ status = "disabled"; -+ }; -+ -+ dmu_pcu: dmu_pcu@1800f000 { -+ compatible = "brcm,iproc-dmu-pcu"; -+ reg = <0x1800f000 0xc00>; -+ }; -+ -+ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { -+ compatible = "brcm,iproc-wrap-ctrl"; -+ reg = <0x1800fc00 0x100>; -+ }; -+ -+ iproc_idm: iproc_idm@18100000 { -+ compatible = "brcm,iproc-idm"; -+ reg = idm0: <0x18100000 0x100000>, -+ idm1: <0xf8100000 0x100000>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ }; -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-greyhound2.dtsi b/arch/arm/boot/dts/bcm-greyhound2.dtsi ---- a/arch/arm/boot/dts/bcm-greyhound2.dtsi 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm-greyhound2.dtsi 2017-11-09 17:52:54.683934000 +0800 -@@ -0,0 +1,415 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include -+#include "skeleton.dtsi" -+ -+ -+/ { -+ model = "Broadcom GH2 iProc"; -+ compatible = "brcm,greyhound2"; -+ interrupt-parent = <&gic>; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a9"; -+ next-level-cache = <&L2>; -+ reg = <0x0>; -+ }; -+ }; -+ -+ core { -+ compatible = "simple-bus"; -+ ranges = <0x00000000 0x19000000 0x00023000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ a9pll: arm_clk@00000 { -+ #clock-cells = <0>; -+ compatible = "brcm,xgs-iproc-armpll"; -+ clocks = <&osc>; -+ reg = <0x0 0x1000>; -+ }; -+ -+ gic: interrupt-controller@21000 { -+ compatible = "arm,cortex-a9-gic"; -+ #interrupt-cells = <3>; -+ interrupt-controller; -+ reg = <0x21000 0x1000>, <0x20100 0x100>; -+ }; -+ -+ twd-timer@20600 { -+ compatible = "arm,cortex-a9-twd-timer"; -+ reg = <0x20600 0x100>; -+ interrupts = ; -+ clocks = <&periph_clk>; -+ }; -+ -+ timer@20200 { -+ compatible = "arm,cortex-a9-global-timer"; -+ reg = <0x20200 0x100>; -+ interrupts = ; -+ clocks = <&periph_clk>; -+ }; -+ -+ L2: l2-cache { -+ compatible = "arm,pl310-cache"; -+ reg = <0x22000 0x1000>; -+ cache-unified; -+ cache-level = <2>; -+ arm,filter-ranges = <0x60000000 0x80000000>; -+ }; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ osc: oscillator { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <25000000>; -+ }; -+ -+ periph_clk: periph_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&a9pll>; -+ clock-div = <2>; -+ clock-mult = <1>; -+ }; -+ -+ iproc_axi_clk: iproc_axi_clk@0x1800fc00 { -+ #clock-cells = <0>; -+ compatible = "brcm,xgs-iproc-axi-clk"; -+ clocks = <&osc>; -+ reg = <0x1800fc00 0x1c>; -+ }; -+ -+ iproc_apb_clk: iproc_apb_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&iproc_axi_clk>; -+ clock-div = <4>; -+ clock-mult = <1>; -+ }; -+ }; -+ -+ axi { -+ compatible = "simple-bus"; -+ ranges; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ uart0: serial@18020000 { -+ compatible = "snps,dw-apb-uart"; -+ reg = <0x18020000 0x100>; -+ interrupts = ; -+ clocks = <&iproc_apb_clk>; -+ reg-io-width = <4>; -+ reg-shift = <2>; -+ status = "disabled"; -+ }; -+ -+ uart1: serial@18021000 { -+ compatible = "snps,dw-apb-uart"; -+ reg = <0x18021000 0x100>; -+ interrupts = ; -+ clocks = <&iproc_apb_clk>; -+ reg-io-width = <4>; -+ reg-shift = <2>; -+ status = "disabled"; -+ }; -+ -+ gmac0: ethernet@18042000 { -+ compatible = "brcm,iproc-gmac"; -+ reg = <0x18042000 0x1000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ gmac1: ethernet@1804a000 { -+ compatible = "brcm,iproc-gmac"; -+ reg = <0x1804a000 0x1000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ gpio_ccg: gpio@1800a000 { -+ compatible = "brcm,iproc-gpio,ccg"; -+ #gpio-cells = <2>; -+ reg = gpio: <0x1800a000 0x50>; -+ ngpios = <12>; -+ pin-offset = <4>; -+ pin-base = <4>; -+ gpio-controller; -+ interrupt-controller; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ usbphy0: usbphy0 { -+ #phy-cells = <0>; -+ compatible = "brcm,usb-phy,gh"; -+ reg = idm_usb2h: <0x18115000 0x1000>, -+ idm_usb2d: <0x18111000 0x1000>, -+ idm_utmih: <0x18049500 0x100>; -+ vbus-gpio = <&gpio_ccg 6 GPIO_ACTIVE_HIGH>; -+ status = "disabled"; -+ }; -+ -+ ehci0: usb@18048000 { -+ compatible = "generic-ehci"; -+ reg = <0x18048000 0x800>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ ohci0: usb@18048800 { -+ compatible = "generic-ohci"; -+ reg = <0x18048800 0x800>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ usbd: usbd@1804c000 { -+ compatible = "brcm,usbd,gh"; -+ reg = <0x1804c000 0x2000>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ nand: nand@18046000 { -+ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; -+ reg = <0x18046000 0x600>, -+ <0xf8105408 0x10>, -+ <0x18046f00 0x20>; -+ reg-names = "nand", "iproc-idm", "iproc-ext"; -+ interrupts = ; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ brcm,nand-has-wp; -+ status = "disabled"; -+ }; -+ -+ qspi: spi@18047000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "brcm,iproc-qspi"; -+ reg = mspi_hw:<0x18047200 0x188>, -+ bspi_hw:<0x18047000 0x050>, -+ bspi_hw_raf:<0x18047100 0x024>, -+ qspi_intr:<0x180473a0 0x01c>, -+ idm_qspi:<0xf8106408 0x004>, -+ cru_hw:<0x1800e000 0x004>; -+ interrupts = ; -+ #chip-select = <0>; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ i2c0: i2c@18008000 { -+ compatible = "brcm,iproc-i2c"; -+ reg = <0x18008000 0x100>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = ; -+ clock-frequency = <100000>; -+ status = "disabled"; -+ }; -+ -+ ccg_mdio_int: ccg_mdio_int@18002000 { -+ compatible = "brcm,iproc-ccg-mdio"; -+ reg = <0x18002000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ #bus-id = <0>; -+ bus-type = "internal"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ /* cmicd cmic_common mdio */ -+ mdio_int: mdio_int@03210000 { -+ compatible = "brcm,iproc-cmicd-mdio"; -+ reg = <0x03210000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ #bus-id = <0>; -+ #logical-bus-id = <1>; -+ bus-type = "internal"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ /* cmicd cmic_common mdio */ -+ mdio_ext: mdio_ext@03210000 { -+ compatible = "brcm,iproc-cmicd-mdio"; -+ reg = <0x03210000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ #bus-id = <2>; -+ #logical-bus-id = <0>; -+ bus-type = "external"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ pnor_flash: pnor_flash@18045000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "brcm,iproc-nor"; -+ reg = nor_regs: <0x18045000 0x1000>, -+ nor_mem: <0xE8000000 0x8000000>, -+ nor_sel: <0x18000c8c 0x4>, -+ nor_strap: <0x18000a5c 0x4>; -+ status = "disabled"; -+ }; -+ -+ hwrng: hwrng@18032000 { -+ compatible = "brcm,iproc-rng"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x18032000 0x1000>; -+ rng-type = "rng200"; -+ status = "disabled"; -+ }; -+ -+ iproc_wdt: iproc_wdt@18009000 { -+ compatible = "arm,sp805", "arm,primecell"; -+ reg = iproc_wdt_base: <0x18009000 0x1000>, -+ iproc_reset_reg: <0x1800f014 0x4>; -+ wdt_boot_status_bit = <0x0>; -+ clocks = <&iproc_apb_clk>; -+ clock-names = "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ dmac0: dma@18018000 { -+ compatible = "brcm,dma330", "arm,primecell"; -+ reg = dma330_base: <0x18018000 0x1000>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ clocks = <&iproc_apb_clk>; -+ clock-names = "apb_pclk"; -+ #dma-cells = <1>; -+ #dma-channels = <8>; -+ #dma-requests = <16>; -+ status = "disabled"; -+ }; -+ -+ crypto: crypto@03100000 { -+ compatible = "brcm,iproc-crypto"; -+ reg = axi: <0x03100000 0x100>, /* SPUM AXI registers */ -+ apb: <0x18037000 0x100>, /* SPUM control registers */ -+ idm: <0x1811a000 0x1000>; /* Crypto control registers */ -+ brcm,max-pkt-size = <65536>; -+ status = "disabled"; -+ }; -+ -+ /* cmicd */ -+ iproc_cmicd: iproc_cmicd@03200000 { -+ compatible = "brcm,iproc-cmicd"; -+ reg = <0x03200000 0x100000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ }; -+ -+ pcie0: pcie@18012000 { -+ compatible = "brcm,iproc-pcie", "iproc-p7"; -+ reg = <0x18012000 0x1000>; -+ linux,pci-domain = <0>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ ; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ /*non-prefetchable mem space, pcie addr 0x0 0x20000000, -+ * cpu addr 0x20000000, size 0x0 0x20000000 -+ */ -+ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; -+ phy-addr = <0>; -+ status = "disabled"; -+ }; -+ -+ dmu_pcu: dmu_pcu@1800f000 { -+ compatible = "brcm,iproc-dmu-pcu"; -+ reg = <0x1800f000 0xc00>; -+ }; -+ -+ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { -+ compatible = "brcm,iproc-wrap-ctrl"; -+ reg = <0x1800fc00 0x100>; -+ }; -+ -+ iproc_idm: iproc_idm@18100000 { -+ compatible = "brcm,iproc-idm"; -+ reg = idm0: <0x18100000 0x100000>, -+ idm1: <0xf8100000 0x100000>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ }; -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-helix4.dtsi b/arch/arm/boot/dts/bcm-helix4.dtsi ---- a/arch/arm/boot/dts/bcm-helix4.dtsi 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm-helix4.dtsi 2017-11-09 17:52:54.684933000 +0800 -@@ -0,0 +1,434 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include -+#include "skeleton.dtsi" -+ -+ -+/ { -+ model = "Broadcom HX4 iProc"; -+ compatible = "brcm,helix4"; -+ interrupt-parent = <&gic>; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu0: cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a9"; -+ next-level-cache = <&L2>; -+ reg = <0x0>; -+ }; -+ -+ cpu1: cpu@1 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a9"; -+ next-level-cache = <&L2>; -+ enable-method = "brcm,bcm-nsp-smp"; -+ secondary-boot-reg = <0xffff042c>; -+ reg = <0x1>; -+ }; -+ }; -+ -+ mpcore { -+ compatible = "simple-bus"; -+ ranges = <0x00000000 0x19000000 0x00023000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ a9pll: arm_clk@00000 { -+ #clock-cells = <0>; -+ compatible = "brcm,xgs-iproc-armpll"; -+ clocks = <&osc>; -+ reg = <0x0 0x1000>; -+ }; -+ -+ gic: interrupt-controller@21000 { -+ compatible = "arm,cortex-a9-gic"; -+ #interrupt-cells = <3>; -+ interrupt-controller; -+ reg = <0x21000 0x1000>, <0x20100 0x100>; -+ }; -+ -+ twd-timer@20600 { -+ compatible = "arm,cortex-a9-twd-timer"; -+ reg = <0x20600 0x100>; -+ interrupts = ; -+ clocks = <&periph_clk>; -+ }; -+ -+ timer@20200 { -+ compatible = "arm,cortex-a9-global-timer"; -+ reg = <0x20200 0x100>; -+ interrupts = ; -+ clocks = <&periph_clk>; -+ }; -+ -+ L2: l2-cache { -+ compatible = "arm,pl310-cache"; -+ reg = <0x22000 0x1000>; -+ cache-unified; -+ cache-level = <2>; -+ arm,filter-ranges = <0x60000000 0x80000000>; -+ /*arm,parity-enable = <1>; -+ interrupts = ;*/ -+ }; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ osc: oscillator { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <25000000>; -+ }; -+ -+ periph_clk: periph_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&a9pll>; -+ clock-div = <2>; -+ clock-mult = <1>; -+ }; -+ -+ iproc_axi_clk: iproc_axi_clk@0x1803fc00 { -+ #clock-cells = <0>; -+ compatible = "brcm,xgs-iproc-axi-clk", "axi-clk-hx4"; -+ clocks = <&osc>; -+ reg = <0x1803fc00 0x1c>; -+ }; -+ -+ iproc_apb_clk: iproc_apb_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&iproc_axi_clk>; -+ clock-div = <4>; -+ clock-mult = <1>; -+ }; -+ }; -+ -+ axi { -+ compatible = "simple-bus"; -+ ranges; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ uart0: serial@18000300 { -+ compatible = "ns16550a"; -+ reg = <0x18000300 0x100>; -+ interrupts = ; -+ clock-frequency = <62500000>; -+ status = "disabled"; -+ }; -+ -+ uart1: serial@18000400 { -+ compatible = "ns16550a"; -+ reg = <0x18000400 0x100>; -+ interrupts = ; -+ clock-frequency = <62500000>; -+ status = "disabled"; -+ }; -+ -+ uart2: serial@18037000 { -+ compatible = "ns16550a"; -+ reg = <0x18037000 0x100>; -+ interrupts = ; -+ clocks = <&iproc_apb_clk>; -+ reg-io-width = <4>; -+ reg-shift = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_cca: gpio@18000060 { -+ compatible = "brcm,iproc-gpio,cca"; -+ #gpio-cells = <2>; -+ reg = gpio: <0x18000060 0x50>, -+ intr: <0x18000000 0x50>; -+ ngpios = <8>; -+ pin-offset = <0>; -+ pin-base = <4>; -+ gpio-controller; -+ interrupt-controller; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ gmac0: ethernet@18022000 { -+ compatible = "brcm,iproc-gmac"; -+ reg = <0x18022000 0x1000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ gmac1: ethernet@18023000 { -+ compatible = "brcm,iproc-gmac"; -+ reg = <0x18023000 0x1000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ nand: nand@18026000 { -+ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; -+ reg = <0x18026000 0x600>, -+ <0x1811b408 0x10>, -+ <0x18026f00 0x20>; -+ reg-names = "nand", "iproc-idm", "iproc-ext"; -+ interrupts = ; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ brcm,nand-has-wp; -+ }; -+ -+ qspi: spi@18027000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "brcm,iproc-qspi"; -+ reg = mspi_hw:<0x18027200 0x188>, -+ bspi_hw:<0x18027000 0x050>, -+ bspi_hw_raf:<0x18027100 0x024>, -+ qspi_intr:<0x180273a0 0x01c>, -+ idm_qspi:<0x1811c408 0x004>, -+ cru_hw:<0x1803e000 0x004>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ ; -+ #chip-select = <0>; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ usbphy0: usbphy0 { -+ #phy-cells = <0>; -+ compatible = "brcm,usb-phy,hx4"; -+ reg = idm_usb2h: <0x18115000 0x1000>, -+ idm_usb2d: <0x18116000 0x1000>; -+ vbus-gpio = <&gpio_cca 1 GPIO_ACTIVE_LOW>; -+ usbdev-gpio = <&gpio_cca 0 GPIO_ACTIVE_HIGH>; -+ status = "disabled"; -+ }; -+ -+ ehci0: usb@1802a000 { -+ compatible = "generic-ehci"; -+ reg = <0x1802a000 0x1000>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ usbd: usbd@18042000 { -+ compatible = "brcm,usbd,hx4"; -+ reg = <0x18042000 0x2000>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ i2c0: i2c@18038000 { -+ compatible = "brcm,iproc-i2c"; -+ reg = <0x18038000 0x100>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = ; -+ clock-frequency = <100000>; -+ status = "disabled"; -+ }; -+ -+ i2c1: i2c@1803b000 { -+ compatible = "brcm,iproc-i2c"; -+ reg = <0x1803b000 0x100>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = ; -+ clock-frequency = <100000>; -+ status = "disabled"; -+ }; -+ -+ mdio_int: mdio_int@18032000 { -+ compatible = "brcm,iproc-ccb-mdio"; -+ reg = <0x18032000 0x1000>; -+ #bus-id = <0>; -+ bus-type = "internal"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ mdio_ext: mdio_ext@18032000 { -+ compatible = "brcm,iproc-ccb-mdio"; -+ reg = <0x18032000 0x1000>; -+ #bus-id = <0>; -+ bus-type = "external"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ hwrng: hwrng@18033000 { -+ compatible = "brcm,iproc-rng"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x18033000 0x1000>; -+ rng-type = "rng"; -+ status = "disabled"; -+ }; -+ -+ iproc_wdt: iproc_wdt@0x18039000 { -+ compatible = "arm,sp805", "arm,primecell"; -+ reg = iproc_wdt_base: <0x18039000 0x1000>, -+ iproc_reset_reg: <0x1803f014 0x4>; -+ wdt_boot_status_bit = <0x0>; -+ clocks = <&iproc_apb_clk>; -+ clock-names = "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ dmac0: dma@18020000 { -+ compatible = "arm,pl330", "arm,primecell"; -+ reg = pl330_base: <0x18020000 0x1000>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ /*arm,primecell-periphid = <0x00041330>;*/ -+ clocks = <&iproc_apb_clk>; -+ clock-names = "apb_pclk"; -+ #dma-cells = <1>; -+ #dma-channels = <8>; -+ #dma-requests = <16>; -+ status = "disabled"; -+ }; -+ -+ /* cmicd */ -+ iproc_cmicd: iproc_cmicd@48000000 { -+ compatible = "brcm,iproc-cmicd"; -+ reg = <0x48000000 0x40000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ }; -+ -+ pcie0: pcie@18012000 { -+ compatible = "brcm,iproc-pcie", "iproc-p2"; -+ reg = <0x18012000 0x1000>; -+ linux,pci-domain = <0>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ ; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ /*non-prefetchable mem space, pcie addr 0x0 0x08000000, -+ * cpu addr 0x08000000, size 0x0 0x08000000 -+ */ -+ ranges = <0x82000000 0 0x08000000 0x08000000 0 0x08000000>; -+ phy-addr = <0>; -+ status = "disabled"; -+ }; -+ -+ pcie1: pcie@18013000 { -+ compatible = "brcm,iproc-pcie", "iproc-p2"; -+ reg = <0x18013000 0x1000>; -+ linux,pci-domain = <1>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ ; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ /*non-prefetchable mem space, pcie addr 0x0 0x40000000, -+ * cpu addr 0x40000000, size 0x0 0x08000000 -+ */ -+ ranges = <0x82000000 0 0x40000000 0x40000000 0 0x08000000>; -+ phy-addr = <1>; -+ status = "disabled"; -+ }; -+ -+ dmu_pcu: dmu_pcu@1803f000 { -+ compatible = "brcm,iproc-dmu-pcu"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x1803f000 0xc00>; -+ }; -+ -+ iproc_wrap_ctrl: iproc_wrap_ctrl@1803fc00 { -+ compatible = "brcm,iproc-wrap-ctrl"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x1803fc00 0x100>; -+ }; -+ -+ iproc_idm: iproc_idm@18100000 { -+ compatible = "brcm,iproc-idm"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x18100000 0x100000>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ }; -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-hurricane2.dtsi b/arch/arm/boot/dts/bcm-hurricane2.dtsi ---- a/arch/arm/boot/dts/bcm-hurricane2.dtsi 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm-hurricane2.dtsi 2017-11-09 17:52:54.685935000 +0800 -@@ -0,0 +1,314 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include "skeleton.dtsi" -+ -+ -+/ { -+ model = "Broadcom HR2 iProc"; -+ compatible = "brcm,hurricane2"; -+ interrupt-parent = <&gic>; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a9"; -+ next-level-cache = <&L2>; -+ reg = <0x0>; -+ }; -+ }; -+ -+ core { -+ compatible = "simple-bus"; -+ ranges = <0x00000000 0x19000000 0x00023000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ a9pll: arm_clk@00000 { -+ #clock-cells = <0>; -+ compatible = "brcm,xgs-iproc-armpll"; -+ clocks = <&osc>; -+ reg = <0x0 0x1000>; -+ }; -+ -+ gic: interrupt-controller@21000 { -+ compatible = "arm,cortex-a9-gic"; -+ #interrupt-cells = <3>; -+ interrupt-controller; -+ reg = <0x21000 0x1000>, <0x20100 0x100>; -+ }; -+ -+ twd-timer@20600 { -+ compatible = "arm,cortex-a9-twd-timer"; -+ reg = <0x20600 0x100>; -+ interrupts = ; -+ clocks = <&periph_clk>; -+ }; -+ -+ timer@20200 { -+ compatible = "arm,cortex-a9-global-timer"; -+ reg = <0x20200 0x100>; -+ interrupts = ; -+ clocks = <&periph_clk>; -+ }; -+ -+ L2: l2-cache { -+ compatible = "arm,pl310-cache"; -+ reg = <0x22000 0x1000>; -+ cache-unified; -+ cache-level = <2>; -+ arm,filter-ranges = <0x60000000 0x80000000>; -+ }; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ osc: oscillator { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <25000000>; -+ }; -+ -+ periph_clk: periph_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&a9pll>; -+ clock-div = <2>; -+ clock-mult = <1>; -+ }; -+ -+ iproc_axi_clk: iproc_axi_clk@1803fc00 { -+ #clock-cells = <0>; -+ compatible = "brcm,xgs-iproc-axi-clk", "axi-clk-hr2"; -+ clocks = <&osc>; -+ reg = <0x1803fc00 0x1c>; -+ }; -+ -+ iproc_apb_clk: iproc_apb_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&iproc_axi_clk>; -+ clock-div = <4>; -+ clock-mult = <1>; -+ }; -+ }; -+ -+ axi { -+ compatible = "simple-bus"; -+ ranges; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ uart0: serial@18000300 { -+ compatible = "ns16550a"; -+ reg = <0x18000300 0x100>; -+ interrupts = ; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ uart1: serial@18000400 { -+ compatible = "ns16550a"; -+ reg = <0x18000400 0x100>; -+ interrupts = ; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ gpio_cca: gpio@18000060 { -+ compatible = "brcm,iproc-gpio,cca"; -+ #gpio-cells = <2>; -+ reg = gpio: <0x18000060 0x50>, -+ intr: <0x18000000 0x50>, -+ dmu: <0x18020000 0x200>; -+ ngpios = <12>; -+ pin-offset = <0>; -+ pin-base = <4>; -+ gpio-controller; -+ interrupt-controller; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ gmac0: ethernet@18022000 { -+ compatible = "brcm,iproc-gmac"; -+ reg = <0x18022000 0x1000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ nand: nand@18026000 { -+ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; -+ reg = <0x18026000 0x600>, -+ <0x1811b408 0x10>, -+ <0x18026f00 0x20>; -+ reg-names = "nand", "iproc-idm", "iproc-ext"; -+ interrupts = ; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ brcm,nand-has-wp; -+ status = "disabled"; -+ }; -+ -+ qspi: spi@18027000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "brcm,iproc-qspi"; -+ reg = mspi_hw:<0x18027200 0x188>, -+ bspi_hw:<0x18027000 0x050>, -+ bspi_hw_raf:<0x18027100 0x024>, -+ qspi_intr:<0x180273a0 0x01c>, -+ idm_qspi:<0x1811c408 0x004>, -+ cru_hw:<0x1803e000 0x004>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ ; -+ #chip-select = <0>; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ mdio_int: mdio_int@18032000 { -+ compatible = "brcm,iproc-ccb-mdio"; -+ reg = <0x18032000 0x1000>; -+ #bus-id = <0>; -+ bus-type = "internal"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ mdio_ext: mdio_ext@18032000 { -+ compatible = "brcm,iproc-ccb-mdio"; -+ reg = <0x18032000 0x1000>; -+ #bus-id = <0>; -+ bus-type = "external"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ pnor_flash: pnor_flash@18021000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "brcm,iproc-nor"; -+ reg = nor_regs: <0x18021000 0x1000>, -+ nor_mem: <0x20000000 0x4000000>, -+ nor_sel: <0x1803fc3c 0x4>; -+ status = "disabled"; -+ }; -+ -+ iproc_wdt: iproc_wdt@18039000 { -+ compatible = "arm,sp805", "arm,primecell"; -+ reg = iproc_wdt_base: <0x18039000 0x1000>, -+ iproc_reset_reg: <0x1803f014 0x4>; -+ wdt_boot_status_bit = <0x0>; -+ clocks = <&iproc_apb_clk>; -+ clock-names = "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ /* cmicd */ -+ iproc_cmicd: iproc_cmicd@48000000 { -+ compatible = "brcm,iproc-cmicd"; -+ reg = <0x48000000 0x40000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ }; -+ -+ pcie0: pcie@18012000 { -+ compatible = "brcm,iproc-pcie", "iproc-p2"; -+ reg = <0x18012000 0x1000>; -+ linux,pci-domain = <0>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ ; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ /*non-prefetchable mem space, pcie addr 0x0 0x08000000, -+ * cpu addr 0x08000000, size 0x0 0x08000000 -+ */ -+ ranges = <0x82000000 0 0x08000000 0x08000000 0 0x08000000>; -+ phy-addr = <0>; -+ status = "disabled"; -+ }; -+ -+ dmu_pcu: dmu_pcu@1803f000 { -+ compatible = "brcm,iproc-dmu-pcu"; -+ reg = <0x1803f000 0xc00>; -+ }; -+ -+ iproc_wrap_ctrl: iproc_wrap_ctrl@1803fc00 { -+ compatible = "brcm,iproc-wrap-ctrl"; -+ reg = <0x1803fc00 0x100>; -+ }; -+ -+ iproc_idm: iproc_idm@18100000 { -+ compatible = "brcm,iproc-idm"; -+ reg = <0x18100000 0x100000>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ }; -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-hurricane3.dtsi b/arch/arm/boot/dts/bcm-hurricane3.dtsi ---- a/arch/arm/boot/dts/bcm-hurricane3.dtsi 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm-hurricane3.dtsi 2017-11-09 17:52:54.686936000 +0800 -@@ -0,0 +1,369 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include -+#include "skeleton.dtsi" -+ -+ -+/ { -+ model = "Broadcom HR3 iProc"; -+ compatible = "brcm,hurricane3"; -+ interrupt-parent = <&gic>; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a9"; -+ next-level-cache = <&L2>; -+ reg = <0x0>; -+ }; -+ }; -+ -+ core { -+ compatible = "simple-bus"; -+ ranges = <0x00000000 0x19000000 0x00023000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ a9pll: arm_clk@00000 { -+ #clock-cells = <0>; -+ compatible = "brcm,xgs-iproc-armpll"; -+ clocks = <&osc>; -+ reg = <0x0 0x1000>; -+ }; -+ -+ gic: interrupt-controller@21000 { -+ compatible = "arm,cortex-a9-gic"; -+ #interrupt-cells = <3>; -+ interrupt-controller; -+ reg = <0x21000 0x1000>, <0x20100 0x100>; -+ }; -+ -+ twd-timer@20600 { -+ compatible = "arm,cortex-a9-twd-timer"; -+ reg = <0x20600 0x100>; -+ interrupts = ; -+ clocks = <&periph_clk>; -+ }; -+ -+ timer@20200 { -+ compatible = "arm,cortex-a9-global-timer"; -+ reg = <0x20200 0x100>; -+ interrupts = ; -+ clocks = <&periph_clk>; -+ }; -+ -+ L2: l2-cache { -+ compatible = "arm,pl310-cache"; -+ reg = <0x22000 0x1000>; -+ cache-unified; -+ cache-level = <2>; -+ arm,filter-ranges = <0x60000000 0x80000000>; -+ }; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ osc: oscillator { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <25000000>; -+ }; -+ -+ periph_clk: periph_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&a9pll>; -+ clock-div = <2>; -+ clock-mult = <1>; -+ }; -+ -+ iproc_axi_clk: iproc_axi_clk@1800fc00 { -+ #clock-cells = <0>; -+ compatible = "brcm,xgs-iproc-axi-clk"; -+ clocks = <&osc>; -+ reg = <0x1800fc00 0x1c>; -+ }; -+ -+ iproc_apb_clk: iproc_apb_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&iproc_axi_clk>; -+ clock-div = <4>; -+ clock-mult = <1>; -+ }; -+ }; -+ -+ axi { -+ compatible = "simple-bus"; -+ ranges; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ uart0: serial@18020000 { -+ compatible = "snps,dw-apb-uart"; -+ reg = <0x18020000 0x100>; -+ interrupts = ; -+ clocks = <&iproc_apb_clk>; -+ reg-io-width = <4>; -+ reg-shift = <2>; -+ status = "disabled"; -+ }; -+ -+ uart1: serial@18021000 { -+ compatible = "snps,dw-apb-uart"; -+ reg = <0x18021000 0x100>; -+ interrupts = ; -+ clocks = <&iproc_apb_clk>; -+ reg-io-width = <4>; -+ reg-shift = <2>; -+ status = "disabled"; -+ }; -+ -+ gmac0: ethernet@18042000 { -+ compatible = "brcm,iproc-gmac"; -+ reg = <0x18042000 0x1000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ gpio_ccg: gpio@1800a000 { -+ compatible = "brcm,iproc-gpio,ccg"; -+ #gpio-cells = <2>; -+ reg = gpio: <0x1800a000 0x50>; -+ ngpios = <12>; -+ pin-offset = <4>; -+ pin-base = <4>; -+ gpio-controller; -+ interrupt-controller; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ usbphy0: usbphy0 { -+ #phy-cells = <0>; -+ compatible = "brcm,usb-phy,gh"; -+ reg = idm_usb2h: <0x18115000 0x1000>, -+ idm_usb2d: <0x18111000 0x1000>; -+ vbus-gpio = <&gpio_ccg 3 GPIO_ACTIVE_HIGH>; -+ status = "disabled"; -+ }; -+ -+ ehci0: usb@0x18048000 { -+ compatible = "generic-ehci"; -+ reg = <0x18048000 0x800>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ ohci0: usb@0x18048800 { -+ compatible = "generic-ohci"; -+ reg = <0x18048800 0x800>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ usbd: usbd@1804c000 { -+ compatible = "brcm,usbd,hr3"; -+ reg = <0x1804c000 0x2000>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ sdio: sdio@18041000 { -+ compatible = "brcm,iproc-hr3-sdio"; -+ reg = <0x18041000 0x1000>, -+ <0x18116408 0x1000>; -+ reg-names = "sdio", "iproc-idm"; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ nand: nand@18046000 { -+ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; -+ reg = <0x18046000 0x600>, -+ <0x1811d408 0x10>, -+ <0x18046f00 0x20>; -+ reg-names = "nand", "iproc-idm", "iproc-ext"; -+ interrupts = ; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ brcm,nand-has-wp; -+ status = "disabled"; -+ }; -+ -+ qspi: spi@18047000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "brcm,iproc-qspi"; -+ reg = mspi_hw:<0x18047200 0x188>, -+ bspi_hw:<0x18047000 0x050>, -+ bspi_hw_raf:<0x18047100 0x024>, -+ qspi_intr:<0x180473a0 0x01c>, -+ idm_qspi:<0x1811f408 0x004>, -+ cru_hw:<0x1800e000 0x004>; -+ interrupts = ; -+ #chip-select = <0>; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ i2c0: i2c@18008000 { -+ compatible = "brcm,iproc-i2c"; -+ reg = <0x18008000 0x100>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = ; -+ clock-frequency = <100000>; -+ status = "disabled"; -+ }; -+ -+ mdio_int: mdio_int@18002000 { -+ compatible = "brcm,iproc-ccg-mdio"; -+ reg = <0x18002000 0x1000>; -+ #bus-id = <0>; -+ bus-type = "internal"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ /* cmicd cmic_common mdio */ -+ mdio_ext: mdio_ext@03210000 { -+ compatible = "brcm,iproc-cmicd-mdio"; -+ reg = <0x03210000 0x1000>; -+ #bus-id = <2>; -+ #logical-bus-id = <0>; -+ bus-type = "external"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ pnor_flash: pnor_flash@18045000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "brcm,iproc-nor"; -+ reg = nor_regs: <0x18045000 0x1000>, -+ nor_mem: <0xE8000000 0x8000000>, -+ nor_sel: <0x18000c8c 0x4>, -+ nor_strap: <0x18000a5c 0x4>; -+ status = "disabled"; -+ }; -+ -+ hwrng: hwrng@18032000 { -+ compatible = "brcm,iproc-rng"; -+ reg = <0x18032000 0x1000>; -+ rng-type = "rng200"; -+ status = "disabled"; -+ }; -+ -+ iproc_wdt: iproc_wdt@18009000 { -+ compatible = "arm,sp805", "arm,primecell"; -+ reg = iproc_wdt_base: <0x18009000 0x1000>, -+ iproc_reset_reg: <0x1800f014 0x4>; -+ wdt_boot_status_bit = <0x0>; -+ clocks = <&iproc_apb_clk>; -+ clock-names = "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ /* cmicd */ -+ iproc_cmicd: iproc_cmicd@03200000 { -+ compatible = "brcm,iproc-cmicd"; -+ reg = <0x03200000 0x100000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ }; -+ -+ pcie0: pcie@18012000 { -+ compatible = "brcm,iproc-pcie"; -+ reg = <0x18012000 0x1000>; -+ linux,pci-domain = <0>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ ; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ /*non-prefetchable mem space, pcie addr 0x0 0x20000000, -+ * cpu addr 0x20000000, size 0x0 0x20000000 -+ */ -+ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; -+ phy-addr = <0>; -+ status = "disabled"; -+ }; -+ -+ dmu_pcu: dmu_pcu@1800f000 { -+ compatible = "brcm,iproc-dmu-pcu"; -+ reg = <0x1800f000 0xc00>; -+ }; -+ -+ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { -+ compatible = "brcm,iproc-wrap-ctrl"; -+ reg = <0x1800fc00 0x100>; -+ -+ }; -+ -+ iproc_idm: iproc_idm@18100000 { -+ compatible = "brcm,iproc-idm"; -+ reg = <0x18100000 0x100000>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ }; -+ -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-katana2.dtsi b/arch/arm/boot/dts/bcm-katana2.dtsi ---- a/arch/arm/boot/dts/bcm-katana2.dtsi 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm-katana2.dtsi 2017-11-09 17:52:54.687932000 +0800 -@@ -0,0 +1,431 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include -+#include "skeleton.dtsi" -+ -+ -+/ { -+ model = "Broadcom KT2 iProc"; -+ compatible = "brcm,katana2"; -+ interrupt-parent = <&gic>; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu0: cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a9"; -+ next-level-cache = <&L2>; -+ reg = <0x0>; -+ }; -+ -+ cpu1: cpu@1 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a9"; -+ next-level-cache = <&L2>; -+ enable-method = "brcm,bcm-nsp-smp"; -+ secondary-boot-reg = <0xffff042c>; -+ reg = <0x1>; -+ }; -+ }; -+ -+ mpcore { -+ compatible = "simple-bus"; -+ ranges = <0x00000000 0x19000000 0x00023000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ a9pll: arm_clk@00000 { -+ #clock-cells = <0>; -+ compatible = "brcm,xgs-iproc-armpll"; -+ clocks = <&osc>; -+ reg = <0x0 0x1000>; -+ }; -+ -+ gic: interrupt-controller@21000 { -+ compatible = "arm,cortex-a9-gic"; -+ #interrupt-cells = <3>; -+ interrupt-controller; -+ reg = <0x21000 0x1000>, <0x20100 0x100>; -+ }; -+ -+ twd-timer@20600 { -+ compatible = "arm,cortex-a9-twd-timer"; -+ reg = <0x20600 0x100>; -+ interrupts = ; -+ clocks = <&periph_clk>; -+ }; -+ -+ timer@20200 { -+ compatible = "arm,cortex-a9-global-timer"; -+ reg = <0x20200 0x100>; -+ interrupts = ; -+ clocks = <&periph_clk>; -+ }; -+ -+ L2: l2-cache { -+ compatible = "arm,pl310-cache"; -+ reg = <0x22000 0x1000>; -+ cache-unified; -+ cache-level = <2>; -+ arm,filter-ranges = <0x60000000 0x80000000>; -+ }; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ osc: oscillator { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <25000000>; -+ }; -+ -+ periph_clk: periph_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&a9pll>; -+ clock-div = <2>; -+ clock-mult = <1>; -+ }; -+ -+ iproc_axi_clk: axi_clk_fixed_495M { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <495000000>; -+ }; -+ -+ iproc_apb_clk: iproc_apb_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&iproc_axi_clk>; -+ clock-div = <4>; -+ clock-mult = <1>; -+ }; -+ }; -+ -+ axi { -+ compatible = "simple-bus"; -+ ranges; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ uart0: serial@18000300 { -+ compatible = "ns16550a"; -+ reg = <0x18000300 0x100>; -+ interrupts = ; -+ clock-frequency = <61875000>; -+ status = "disabled"; -+ }; -+ -+ uart1: serial@18000400 { -+ compatible = "ns16550a"; -+ reg = <0x18000400 0x100>; -+ interrupts = ; -+ clock-frequency = <61875000>; -+ status = "disabled"; -+ }; -+ -+ uart2: serial@18037000 { -+ compatible = "ns16550a"; -+ reg = <0x18037000 0x100>; -+ interrupts = ; -+ clocks = <&iproc_apb_clk>; -+ reg-io-width = <4>; -+ reg-shift = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_cca: gpio@18000060 { -+ compatible = "brcm,iproc-gpio,cca"; -+ #gpio-cells = <2>; -+ reg = gpio: <0x18000060 0x50>, -+ intr: <0x18000000 0x50>; -+ ngpios = <8>; -+ pin-offset = <0>; -+ pin-base = <4>; -+ gpio-controller; -+ interrupt-controller; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ gmac0: ethernet@18022000 { -+ compatible = "brcm,iproc-gmac"; -+ reg = <0x18022000 0x1000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ gmac1: ethernet@18023000 { -+ compatible = "brcm,iproc-gmac"; -+ reg = <0x18023000 0x1000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ nand: nand@18026000 { -+ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; -+ reg = <0x18026000 0x600>, -+ <0x1811b408 0x10>, -+ <0x18026f00 0x20>; -+ reg-names = "nand", "iproc-idm", "iproc-ext"; -+ interrupts = ; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ brcm,nand-has-wp; -+ }; -+ -+ qspi: spi@18027000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "brcm,iproc-qspi"; -+ reg = mspi_hw:<0x18027200 0x188>, -+ bspi_hw:<0x18027000 0x050>, -+ bspi_hw_raf:<0x18027100 0x024>, -+ qspi_intr:<0x180273a0 0x01c>, -+ idm_qspi:<0x1811c408 0x004>, -+ cru_hw:<0x1803e000 0x004>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ ; -+ #chip-select = <0>; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ usbphy0: usbphy0 { -+ #phy-cells = <0>; -+ compatible = "brcm,usb-phy,kt2"; -+ reg = idm_usb2h: <0x18115000 0x1000>, -+ idm_usb2d: <0x18116000 0x1000>; -+ vbus-gpio = <&gpio_cca 1 GPIO_ACTIVE_LOW>; -+ usbdev-gpio = <&gpio_cca 0 GPIO_ACTIVE_HIGH>; -+ status = "disabled"; -+ }; -+ -+ ehci0: usb@1802a000 { -+ compatible = "generic-ehci"; -+ reg = <0x1802a000 0x1000>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ usbd: usbd@18042000 { -+ compatible = "brcm,usbd,kt2"; -+ reg = <0x18042000 0x2000>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ i2c0: i2c@0x18038000 { -+ compatible = "brcm,iproc-i2c"; -+ reg = <0x18038000 0x100>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = ; -+ clock-frequency = <100000>; -+ status = "disabled"; -+ }; -+ -+ i2c1: i2c@1803b000 { -+ compatible = "brcm,iproc-i2c"; -+ reg = <0x1803b000 0x100>; -+ interrupts = ; -+ #bus-id = <1>; -+ clock-frequency = <100000>; -+ status = "disabled"; -+ }; -+ -+ mdio_int: mdio_int@18032000 { -+ compatible = "brcm,iproc-ccb-mdio"; -+ reg = <0x18032000 0x1000>; -+ #bus-id = <0>; -+ bus-type = "internal"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ mdio_ext: mdio_ext@18032000 { -+ compatible = "brcm,iproc-ccb-mdio"; -+ reg = <0x18032000 0x1000>; -+ #bus-id = <0>; -+ bus-type = "external"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ hwrng: hwrng@18033000 { -+ compatible = "brcm,iproc-rng"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x18033000 0x1000>; -+ rng-type = "rng"; -+ status = "disabled"; -+ }; -+ -+ iproc_wdt: iproc_wdt@18039000 { -+ compatible = "arm,sp805", "arm,primecell"; -+ reg = iproc_wdt_base: <0x18039000 0x1000>, -+ iproc_reset_reg: <0x1803f014 0x4>; -+ wdt_boot_status_bit = <0x0>; -+ clocks = <&iproc_apb_clk>; -+ clock-names = "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ dmac0: dma@18020000 { -+ compatible = "arm,pl330", "arm,primecell"; -+ reg = pl330_base: <0x18020000 0x1000>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ /*arm,primecell-periphid = <0x00041330>;*/ -+ clocks = <&iproc_apb_clk>; -+ clock-names = "apb_pclk"; -+ #dma-cells = <1>; -+ #dma-channels = <8>; -+ #dma-requests = <16>; -+ status = "disabled"; -+ }; -+ -+ /* cmicd */ -+ iproc_cmicd: iproc_cmicd@48000000 { -+ compatible = "brcm,iproc-cmicd"; -+ reg = <0x48000000 0x40000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ }; -+ -+ pcie0: pcie@18012000 { -+ compatible = "brcm,iproc-pcie", "iproc-p2"; -+ reg = <0x18012000 0x1000>; -+ linux,pci-domain = <0>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ ; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ /*non-prefetchable mem space, pcie addr 0x0 0x08000000, -+ * cpu addr 0x08000000, size 0x0 0x08000000 -+ */ -+ ranges = <0x82000000 0 0x08000000 0x08000000 0 0x08000000>; -+ phy-addr = <0>; -+ status = "disabled"; -+ }; -+ -+ pcie1: pcie@18013000 { -+ compatible = "brcm,iproc-pcie", "iproc-p2"; -+ reg = <0x18013000 0x1000>; -+ linux,pci-domain = <1>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ ; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ /*non-prefetchable mem space, pcie addr 0x0 0x40000000, -+ * cpu addr 0x40000000, size 0x0 0x08000000 -+ */ -+ ranges = <0x82000000 0 0x40000000 0x40000000 0 0x08000000>; -+ phy-addr = <1>; -+ status = "disabled"; -+ }; -+ -+ dmu_pcu: dmu_pcu@1803f000 { -+ compatible = "brcm,iproc-dmu-pcu"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x1803f000 0xc00>; -+ }; -+ -+ iproc_wrap_ctrl: iproc_wrap_ctrl@1803fc00 { -+ compatible = "brcm,iproc-wrap-ctrl"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x1803fc00 0x100>; -+ }; -+ -+ iproc_idm: iproc_idm@18100000 { -+ compatible = "brcm,iproc-idm"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x18100000 0x100000>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ }; -+}; -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-saber2.dtsi b/arch/arm/boot/dts/bcm-saber2.dtsi ---- a/arch/arm/boot/dts/bcm-saber2.dtsi 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm-saber2.dtsi 2017-11-09 17:52:54.689928000 +0800 -@@ -0,0 +1,356 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include -+#include "skeleton.dtsi" -+ -+/ { -+ model = "Broadcom SB2 iProc"; -+ compatible = "brcm,saber2"; -+ interrupt-parent = <&gic>; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a9"; -+ next-level-cache = <&L2>; -+ reg = <0x0>; -+ }; -+ }; -+ -+ core { -+ compatible = "simple-bus"; -+ ranges = <0x00000000 0x19000000 0x00023000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ a9pll: arm_clk@00000 { -+ #clock-cells = <0>; -+ compatible = "brcm,xgs-iproc-armpll"; -+ clocks = <&osc>; -+ reg = <0x0 0x1000>; -+ }; -+ -+ gic: interrupt-controller@21000 { -+ compatible = "arm,cortex-a9-gic"; -+ #interrupt-cells = <3>; -+ interrupt-controller; -+ reg = <0x21000 0x1000>, <0x20100 0x100>; -+ }; -+ -+ twd-timer@20600 { -+ compatible = "arm,cortex-a9-twd-timer"; -+ reg = <0x20600 0x100>; -+ interrupts = ; -+ clocks = <&periph_clk>; -+ }; -+ -+ timer@20200 { -+ compatible = "arm,cortex-a9-global-timer"; -+ reg = <0x20200 0x100>; -+ interrupts = ; -+ clocks = <&periph_clk>; -+ }; -+ -+ L2: l2-cache { -+ compatible = "arm,pl310-cache"; -+ reg = <0x22000 0x1000>; -+ cache-unified; -+ cache-level = <2>; -+ arm,filter-ranges = <0x60000000 0x80000000>; -+ }; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ osc: oscillator_25M { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <25000000>; -+ }; -+ -+ osc_1: oscillator_50M { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <50000000>; -+ }; -+ -+ periph_clk: periph_clk@19000000 { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&a9pll>; -+ clock-div = <2>; -+ clock-mult = <1>; -+ }; -+ -+ iproc_axi_clk: iproc_axi_clk@1800fc50 { -+ #clock-cells = <0>; -+ compatible = "brcm,xgs-iproc-axi-clk", "axi-clk-sb2"; -+ clocks = <&osc_1>; -+ reg = <0x1800fc50 0x1c>; -+ }; -+ -+ iproc_apb_clk: iproc_apb_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&iproc_axi_clk>; -+ clock-div = <4>; -+ clock-mult = <1>; -+ }; -+ }; -+ -+ axi { -+ compatible = "simple-bus"; -+ ranges; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ uart0: serial@18020000 { -+ compatible = "snps,dw-apb-uart"; -+ reg = <0x18020000 0x100>; -+ interrupts = ; -+ clocks = <&iproc_apb_clk>; -+ reg-io-width = <4>; -+ reg-shift = <2>; -+ status = "disabled"; -+ }; -+ -+ uart1: serial@18021000 { -+ compatible = "snps,dw-apb-uart"; -+ reg = <0x18021000 0x1000>; -+ interrupts = ; -+ clocks = <&iproc_apb_clk>; -+ reg-io-width = <4>; -+ reg-shift = <2>; -+ status = "disabled"; -+ }; -+ -+ qspi: spi@18047000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "brcm,iproc-qspi"; -+ reg = mspi_hw:<0x18047200 0x188>, -+ bspi_hw:<0x18047000 0x050>, -+ bspi_hw_raf:<0x18047100 0x024>, -+ qspi_intr:<0x180473a0 0x01c>, -+ idm_qspi:<0xf8106408 0x004>, -+ cru_hw:<0x1800e000 0x004>; -+ interrupts = ; -+ #chip-select = <0>; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ -+ gmac0: ethernet@18042000 { -+ compatible = "brcm,iproc-gmac"; -+ reg = <0x18042000 0x1000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ usbphy0: usbphy0 { -+ #phy-cells = <0>; -+ compatible = "brcm,usb-phy,sb2"; -+ reg = idm_usb2h: <0x18115000 0x1000>, -+ idm_usb2d: <0x18111000 0x1000>; -+ vbus-gpio = <&gpio_ccg 1 GPIO_ACTIVE_LOW>; -+ status = "disabled"; -+ }; -+ -+ ehci0: usb@18048000 { -+ compatible = "generic-ehci"; -+ reg = <0x18048000 0x800>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ ohci0: usb@18048800 { -+ compatible = "generic-ohci"; -+ reg = <0x18048800 0x800>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ usbd: usbd@1804c000 { -+ compatible = "brcm,usbd,sb2"; -+ reg = usb2d: <0x1804c000 0x2000>, -+ idm_usb: <0x18111000 0x1000>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ gpio_ccg: gpio@1800a000 { -+ compatible = "brcm,iproc-gpio,ccg"; -+ #gpio-cells = <2>; -+ reg = gpio: <0x1800a000 0x50>; -+ ngpios = <16>; -+ pin-offset = <0>; -+ pin-base = <0>; -+ gpio-controller; -+ interrupt-controller; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ nand: nand@18046000 { -+ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; -+ reg = <0x18046000 0x600>, -+ <0xf8105408 0x10>, -+ <0x18046f00 0x20>; -+ reg-names = "nand", "iproc-idm", "iproc-ext"; -+ interrupts = ; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ brcm,nand-has-wp; -+ status = "disabled"; -+ }; -+ -+ i2c0: i2c@18008000 { -+ compatible = "brcm,iproc-i2c"; -+ reg = <0x18008000 0x100>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = ; -+ clock-frequency = <100000>; -+ status = "disabled"; -+ }; -+ -+ mdio_int: mdio_int@18002000 { -+ compatible = "brcm,iproc-ccg-mdio"; -+ reg = <0x18002000 0x1000>; -+ #bus-id = <0>; -+ bus-type = "internal"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ mdio_ext: mdio_ext@18002000 { -+ compatible = "brcm,iproc-ccg-mdio"; -+ reg = <0x18002000 0x1000>; -+ #bus-id = <0>; -+ bus-type = "external"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ hwrng: hwrng@18032000 { -+ compatible = "brcm,iproc-rng"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x18032000 0x1000>; -+ rng-type = "rng200"; -+ status = "disabled"; -+ }; -+ -+ iproc_wdt: iproc_wdt@18009000 { -+ compatible = "arm,sp805", "arm,primecell"; -+ reg = iproc_wdt_base: <0x18009000 0x1000>, -+ iproc_reset_reg: <0x1800f014 0x4>; -+ wdt_boot_status_bit = <0x0>; -+ clocks = <&iproc_apb_clk>; -+ clock-names = "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ /* cmicd */ -+ iproc_cmicd: iproc_cmicd@03200000 { -+ compatible = "brcm,iproc-cmicd"; -+ reg = <0x03200000 0x100000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ }; -+ -+ pcie0: pcie@18012000 { -+ compatible = "brcm,iproc-pcie", "iproc-p7"; -+ reg = <0x18012000 0x1000>; -+ linux,pci-domain = <0>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ ; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ /*non-prefetchable mem space, pcie addr 0x0 0x20000000, -+ * cpu addr 0x20000000, size 0x0 0x20000000 -+ */ -+ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; -+ phy-addr = <0>; -+ status = "disabled"; -+ }; -+ -+ dmu_pcu: dmu_pcu@1800f000 { -+ compatible = "brcm,iproc-dmu-pcu"; -+ reg = <0x1800f000 0xc00>; -+ }; -+ -+ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { -+ compatible = "brcm,iproc-wrap-ctrl"; -+ reg = <0x1800fc00 0x100>; -+ }; -+ -+ iproc_idm: iproc_idm@18100000 { -+ compatible = "brcm,iproc-idm"; -+ reg = idm0: <0x18100000 0x100000>, -+ idm1: <0xf8100000 0x100000>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ }; -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-wolfhound2.dtsi b/arch/arm/boot/dts/bcm-wolfhound2.dtsi ---- a/arch/arm/boot/dts/bcm-wolfhound2.dtsi 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm-wolfhound2.dtsi 2017-11-09 17:52:54.690928000 +0800 -@@ -0,0 +1,354 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include -+#include "skeleton.dtsi" -+ -+ -+/ { -+ model = "Broadcom HR3 iProc"; -+ compatible = "brcm,hurricane3"; -+ interrupt-parent = <&gic>; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a9"; -+ next-level-cache = <&L2>; -+ reg = <0x0>; -+ }; -+ }; -+ -+ core { -+ compatible = "simple-bus"; -+ ranges = <0x00000000 0x19000000 0x00023000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ a9pll: arm_clk@00000 { -+ #clock-cells = <0>; -+ compatible = "brcm,xgs-iproc-armpll"; -+ clocks = <&osc>; -+ reg = <0x0 0x1000>; -+ }; -+ -+ gic: interrupt-controller@21000 { -+ compatible = "arm,cortex-a9-gic"; -+ #interrupt-cells = <3>; -+ interrupt-controller; -+ reg = <0x21000 0x1000>, <0x20100 0x100>; -+ }; -+ -+ twd-timer@20600 { -+ compatible = "arm,cortex-a9-twd-timer"; -+ reg = <0x20600 0x100>; -+ interrupts = ; -+ clocks = <&periph_clk>; -+ }; -+ -+ timer@20200 { -+ compatible = "arm,cortex-a9-global-timer"; -+ reg = <0x20200 0x100>; -+ interrupts = ; -+ clocks = <&periph_clk>; -+ }; -+ -+ L2: l2-cache { -+ compatible = "arm,pl310-cache"; -+ reg = <0x22000 0x1000>; -+ cache-unified; -+ cache-level = <2>; -+ arm,filter-ranges = <0x60000000 0x80000000>; -+ }; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ osc: oscillator { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <25000000>; -+ }; -+ -+ periph_clk: periph_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&a9pll>; -+ clock-div = <2>; -+ clock-mult = <1>; -+ }; -+ -+ iproc_axi_clk: iproc_axi_clk@1800fc00 { -+ #clock-cells = <0>; -+ compatible = "brcm,xgs-iproc-axi-clk"; -+ clocks = <&osc>; -+ reg = <0x1800fc00 0x1c>; -+ }; -+ -+ iproc_apb_clk: iproc_apb_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-factor-clock"; -+ clocks = <&iproc_axi_clk>; -+ clock-div = <4>; -+ clock-mult = <1>; -+ }; -+ }; -+ -+ axi { -+ compatible = "simple-bus"; -+ ranges; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ uart0: serial@18020000 { -+ compatible = "snps,dw-apb-uart"; -+ reg = <0x18020000 0x100>; -+ interrupts = ; -+ clocks = <&iproc_apb_clk>; -+ reg-io-width = <4>; -+ reg-shift = <2>; -+ status = "disabled"; -+ }; -+ -+ uart1: serial@18021000 { -+ compatible = "snps,dw-apb-uart"; -+ reg = <0x18021000 0x100>; -+ interrupts = ; -+ clocks = <&iproc_apb_clk>; -+ reg-io-width = <4>; -+ reg-shift = <2>; -+ status = "disabled"; -+ }; -+ -+ gmac0: ethernet@18042000 { -+ compatible = "brcm,iproc-gmac"; -+ reg = <0x18042000 0x1000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ gpio_ccg: gpio@1800a000 { -+ compatible = "brcm,iproc-gpio,ccg"; -+ #gpio-cells = <2>; -+ reg = gpio: <0x1800a000 0x50>; -+ ngpios = <12>; -+ pin-offset = <4>; -+ pin-base = <4>; -+ gpio-controller; -+ interrupt-controller; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ -+ usbphy0: usbphy0 { -+ #phy-cells = <0>; -+ compatible = "brcm,usb-phy,gh"; -+ reg = idm_usb2h: <0x18115000 0x1000>, -+ idm_usb2d: <0x18111000 0x1000>; -+ vbus-gpio = <&gpio_ccg 3 GPIO_ACTIVE_HIGH>; -+ status = "disabled"; -+ }; -+ -+ ehci0: usb@0x18048000 { -+ compatible = "generic-ehci"; -+ reg = <0x18048000 0x800>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ ohci0: usb@0x18048800 { -+ compatible = "generic-ohci"; -+ reg = <0x18048800 0x800>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ usbd: usbd@1804c000 { -+ compatible = "brcm,usbd,hr3"; -+ reg = <0x1804c000 0x2000>; -+ interrupts = ; -+ usb-phy = <&usbphy0>; -+ status = "disabled"; -+ }; -+ -+ qspi: spi@18047000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "brcm,iproc-qspi"; -+ reg = mspi_hw:<0x18047200 0x188>, -+ bspi_hw:<0x18047000 0x050>, -+ bspi_hw_raf:<0x18047100 0x024>, -+ qspi_intr:<0x180473a0 0x01c>, -+ idm_qspi:<0x1811f408 0x004>, -+ cru_hw:<0x1800e000 0x004>; -+ interrupts = ; -+ #chip-select = <0>; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ i2c0: i2c@18008000 { -+ compatible = "brcm,iproc-i2c"; -+ reg = <0x18008000 0x100>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = ; -+ clock-frequency = <100000>; -+ status = "disabled"; -+ }; -+ -+ /* cmicd cmic_common mdio */ -+ mdio_int0: mdio_int0@03210000 { -+ compatible = "brcm,iproc-cmicd-mdio"; -+ reg = <0x03210000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ #bus-id = <0>; -+ #logical-bus-id = <0>; -+ bus-type = "internal"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ /* cmicd cmic_common mdio */ -+ mdio_int1: mdio_int1@03210000 { -+ compatible = "brcm,iproc-cmicd-mdio"; -+ reg = <0x03210000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ #bus-id = <1>; -+ #logical-bus-id = <1>; -+ bus-type = "internal"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ /* CCG mdio */ -+ mdio_int2: mdio_int2@18002000 { -+ compatible = "brcm,iproc-ccg-mdio"; -+ reg = <0x18002000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ #bus-id = <2>; -+ bus-type = "internal"; -+ clocks = <&iproc_apb_clk>; -+ status = "disabled"; -+ }; -+ -+ hwrng: hwrng@18032000 { -+ compatible = "brcm,iproc-rng"; -+ reg = <0x18032000 0x1000>; -+ rng-type = "rng200"; -+ status = "disabled"; -+ }; -+ -+ iproc_wdt: iproc_wdt@18009000 { -+ compatible = "arm,sp805", "arm,primecell"; -+ reg = iproc_wdt_base: <0x18009000 0x1000>, -+ iproc_reset_reg: <0x1800f014 0x4>; -+ wdt_boot_status_bit = <0x0>; -+ clocks = <&iproc_apb_clk>; -+ clock-names = "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ /* cmicd */ -+ iproc_cmicd: iproc_cmicd@03200000 { -+ compatible = "brcm,iproc-cmicd"; -+ reg = <0x03200000 0x100000>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ }; -+ -+ pcie0: pcie@18012000 { -+ compatible = "brcm,iproc-pcie"; -+ reg = <0x18012000 0x1000>; -+ linux,pci-domain = <0>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ ; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ /*non-prefetchable mem space, pcie addr 0x0 0x20000000, -+ * cpu addr 0x20000000, size 0x0 0x20000000 -+ */ -+ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; -+ phy-addr = <0>; -+ status = "disabled"; -+ }; -+ -+ dmu_pcu: dmu_pcu@1800f000 { -+ compatible = "brcm,iproc-dmu-pcu"; -+ reg = <0x1800f000 0xc00>; -+ }; -+ -+ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { -+ compatible = "brcm,iproc-wrap-ctrl"; -+ reg = <0x1800fc00 0x100>; -+ -+ }; -+ -+ iproc_idm: iproc_idm@18100000 { -+ compatible = "brcm,iproc-idm"; -+ reg = <0x18100000 0x100000>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ }; -+ -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm95341x.dts b/arch/arm/boot/dts/bcm95341x.dts ---- a/arch/arm/boot/dts/bcm95341x.dts 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm95341x.dts 2017-11-09 17:52:54.730934000 +0800 -@@ -0,0 +1,207 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/dts-v1/; -+ -+#include "bcm-greyhound.dtsi" -+ -+/ { -+ model = "Broadcom GH SVK (BCM95341x)"; -+ compatible = "brcm,bcm95341x", "brcm,greyhound"; -+ -+ aliases { -+ serial0 = &uart0; -+ serial1 = &uart1; -+ ethernet0 = &gmac0; -+ }; -+ -+ chosen { -+ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart1 { -+ status = "okay"; -+}; -+ -+&gmac0 { -+ status = "okay"; -+}; -+ -+&usbphy0 { -+ status = "okay"; -+}; -+ -+&ehci0 { -+ status = "okay"; -+}; -+ -+&ohci0 { -+ status = "okay"; -+}; -+ -+&usbd { -+ status = "okay"; -+}; -+ -+&gpio_ccg { -+ status = "okay"; -+}; -+ -+&pcie0 { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ eeprom@0x50 { -+ compatible = "atmel,24c01"; -+ reg = <0x50>; -+ pagesize = <8>; -+ }; -+}; -+ -+&nand { -+ status = "okay"; -+ nandcs@1 { -+ compatible = "brcm,nandcs"; -+ reg = <0>; -+ nand-on-flash-bbt; -+ /*nand-bus-width = <8>;*/ -+ nand-ecc-strength = <24>; -+ nand-ecc-step-size = <1024>; -+ brcm,nand-oob-sector-size = <27>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "nboot"; -+ reg = <0x0 0x200000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "nenv"; -+ reg = <0x200000 0x400000>; -+ }; -+ partition@2 { -+ label = "nsystem"; -+ reg = <0x600000 0xa00000>; -+ }; -+ partition@3 { -+ label = "nrootfs"; -+ reg = <0x1000000 0xf000000>; -+ }; -+ partition@4 { -+ label = "ncustfs"; -+ reg = <0x10000000 0x30000000>; -+ }; -+ }; -+}; -+ -+&qspi { -+ status = "okay"; -+ flash: m25p80@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "m25p80"; -+ m25p,fast-read = <1>; -+ spi-max-frequency = <62500000>; -+ reg = <0x0>; -+ partition@0 { -+ label = "boot"; -+ reg = <0x00000000 0x000c0000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "env"; -+ reg = <0x000c0000 0x00040000>; -+ }; -+ partition@2 { -+ label = "system"; -+ reg = <0x00100000 0x00f00000>; -+ }; -+ partition@3 { -+ label = "rootfs"; -+ reg = <0x01000000 0x03000000>; -+ }; -+ }; -+}; -+ -+&pnor_flash { -+ status = "okay"; -+ -+ partition@0 { -+ label = "pboot"; -+ reg = <0x0 0xc0000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "penv"; -+ reg = <0xc0000 0x40000>; -+ }; -+ partition@2 { -+ label = "psystem"; -+ reg = <0x100000 0xf00000>; -+ }; -+ partition@3 { -+ label = "prootfs"; -+ reg = <0x1000000 0x1000000>; -+ }; -+ partition@4 { -+ label = "pcustfs"; -+ reg = <0x2000000 0x2000000>; -+ }; -+}; -+ -+&mdio_int { -+ status = "okay"; -+}; -+ -+&mdio_ext { -+ status = "okay"; -+}; -+ -+&hwrng { -+ status = "okay"; -+}; -+ -+&iproc_wdt { -+ status = "okay"; -+}; -+ -+&iproc_cmicd { -+ status = "okay"; -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm953444.dts b/arch/arm/boot/dts/bcm953444.dts ---- a/arch/arm/boot/dts/bcm953444.dts 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm953444.dts 2017-11-09 17:52:54.731931000 +0800 -@@ -0,0 +1,128 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/dts-v1/; -+ -+#include "bcm-hurricane3.dtsi" -+ -+/ { -+ model = "Broadcom HR3 SVK (BCM953444K)"; -+ compatible = "brcm,bcm953444k", "brcm,hurricane3"; -+ -+ aliases { -+ serial0 = &uart0; -+ serial1 = &uart1; -+ ethernet0 = &gmac0; -+ }; -+ -+ chosen { -+ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart1 { -+ status = "okay"; -+}; -+ -+&gmac0 { -+ status = "okay"; -+}; -+ -+ -+&gpio_ccg { -+ status = "okay"; -+}; -+ -+&pcie0 { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ eeprom@0x50 { -+ compatible = "atmel,24c01"; -+ reg = <0x50>; -+ pagesize = <8>; -+ }; -+}; -+ -+&qspi { -+ status = "okay"; -+ flash: m25p80@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "m25p80"; -+ m25p,fast-read = <1>; -+ spi-max-frequency = <62500000>; -+ reg = <0x0>; -+ partition@0 { -+ label = "boot"; -+ reg = <0x00000000 0x000c0000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "env"; -+ reg = <0x000c0000 0x00040000>; -+ }; -+ partition@2 { -+ label = "system"; -+ reg = <0x00100000 0x00f00000>; -+ }; -+ partition@3 { -+ label = "rootfs"; -+ reg = <0x01000000 0x03000000>; -+ }; -+ }; -+}; -+ -+&mdio_int { -+ status = "okay"; -+}; -+ -+&mdio_ext { -+ #bus-id = <1>; /* cmicd mdio needs #logical-bus-id in addition to #bus-id (physical) */ -+ #logical-bus-id = <1>; -+ status = "okay"; -+}; -+ -+&iproc_wdt { -+ status = "okay"; -+}; -+ -+&iproc_cmicd { -+ status = "okay"; -+}; -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm953547.dts b/arch/arm/boot/dts/bcm953547.dts ---- a/arch/arm/boot/dts/bcm953547.dts 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm953547.dts 2017-11-09 17:52:54.740928000 +0800 -@@ -0,0 +1,154 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/dts-v1/; -+ -+#include "bcm-wolfhound2.dtsi" -+ -+/ { -+ model = "Broadcom HR3-WH2 SVK (BCM953547K)"; -+ compatible = "brcm,bcm953547k", "brcm,hurricane3"; -+ -+ aliases { -+ serial0 = &uart0; -+ serial1 = &uart1; -+ ethernet0 = &gmac0; -+ }; -+ -+ chosen { -+ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart1 { -+ status = "okay"; -+}; -+ -+&gmac0 { -+ status = "okay"; -+}; -+ -+&usbphy0 { -+ status = "okay"; -+}; -+ -+&ehci0 { -+ status = "okay"; -+}; -+ -+&ohci0 { -+ status = "okay"; -+}; -+ -+&usbd { -+ status = "okay"; -+}; -+ -+&gpio_ccg { -+ status = "okay"; -+}; -+ -+&pcie0 { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ eeprom@0x50 { -+ compatible = "atmel,24c01"; -+ reg = <0x50>; -+ pagesize = <8>; -+ }; -+}; -+ -+&qspi { -+ status = "okay"; -+ flash: m25p80@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "m25p80"; -+ m25p,fast-read = <1>; -+ spi-max-frequency = <62500000>; -+ reg = <0x0>; -+ partition@0 { -+ label = "boot"; -+ reg = <0x00000000 0x000c0000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "env"; -+ reg = <0x000c0000 0x00040000>; -+ }; -+ partition@2 { -+ label = "system"; -+ reg = <0x00100000 0x00f00000>; -+ }; -+ partition@3 { -+ label = "rootfs"; -+ reg = <0x01000000 0x03000000>; -+ }; -+ }; -+}; -+ -+&mdio_int0 { -+ status = "okay"; -+ amac_phy0: amac_phy@0 { -+ reg = <24>; -+ }; -+}; -+ -+&mdio_int1 { -+ status = "okay"; -+ amac_serdes: amac_serdes@0 { -+ reg = <20>; -+ }; -+}; -+ -+&mdio_int2 { -+ status = "okay"; -+ pcie_phy0: pcie_phy@0 { -+ reg = <2>; -+ }; -+}; -+ -+&iproc_wdt { -+ status = "okay"; -+}; -+ -+&iproc_cmicd { -+ status = "okay"; -+}; -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm95357x.dts b/arch/arm/boot/dts/bcm95357x.dts ---- a/arch/arm/boot/dts/bcm95357x.dts 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm95357x.dts 2017-11-09 17:52:54.744928000 +0800 -@@ -0,0 +1,224 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/dts-v1/; -+ -+#include "bcm-greyhound2.dtsi" -+ -+/ { -+ model = "Broadcom RG3 SVK (BCM95357x)"; -+ compatible = "brcm,bcm95357x", "brcm,greyhound2"; -+ -+ aliases { -+ serial0 = &uart0; -+ serial1 = &uart1; -+ ethernet0 = &gmac0; -+ ethernet1 = &gmac1; -+ }; -+ -+ chosen { -+ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart1 { -+ status = "okay"; -+}; -+ -+&gmac0 { -+ status = "okay"; -+}; -+ -+&gmac1 { -+ status = "okay"; -+}; -+ -+&usbphy0 { -+ status = "okay"; -+}; -+ -+&ehci0 { -+ status = "okay"; -+}; -+ -+&ohci0 { -+ status = "okay"; -+}; -+ -+&usbd { -+ status = "okay"; -+}; -+ -+&gpio_ccg { -+ status = "okay"; -+}; -+ -+&pcie0 { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ eeprom@0x50 { -+ compatible = "atmel,24c01"; -+ reg = <0x50>; -+ pagesize = <8>; -+ }; -+}; -+ -+&nand { -+ status = "okay"; -+ nandcs@1 { -+ compatible = "brcm,nandcs"; -+ reg = <0>; -+ nand-on-flash-bbt; -+ /*nand-bus-width = <8>;*/ -+ nand-ecc-strength = <24>; -+ nand-ecc-step-size = <1024>; -+ brcm,nand-oob-sector-size = <27>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "nboot"; -+ reg = <0x0 0x200000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "nenv"; -+ reg = <0x200000 0x400000>; -+ }; -+ partition@2 { -+ label = "nsystem"; -+ reg = <0x600000 0xa00000>; -+ }; -+ partition@3 { -+ label = "nrootfs"; -+ reg = <0x1000000 0xf000000>; -+ }; -+ partition@4 { -+ label = "ncustfs"; -+ reg = <0x10000000 0x30000000>; -+ }; -+ }; -+}; -+ -+&qspi { -+ status = "okay"; -+ flash: m25p80@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "m25p80"; -+ m25p,fast-read = <1>; -+ spi-max-frequency = <62500000>; -+ reg = <0x0>; -+ partition@0 { -+ label = "boot"; -+ reg = <0x00000000 0x000c0000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "env"; -+ reg = <0x000c0000 0x00040000>; -+ }; -+ partition@2 { -+ label = "system"; -+ reg = <0x00100000 0x00f00000>; -+ }; -+ partition@3 { -+ label = "rootfs"; -+ reg = <0x01000000 0x03000000>; -+ }; -+ }; -+}; -+ -+&pnor_flash { -+ status = "okay"; -+ -+ partition@0 { -+ label = "pboot"; -+ reg = <0x0 0xc0000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "penv"; -+ reg = <0xc0000 0x40000>; -+ }; -+ partition@2 { -+ label = "psystem"; -+ reg = <0x100000 0xf00000>; -+ }; -+ partition@3 { -+ label = "prootfs"; -+ reg = <0x1000000 0x1000000>; -+ }; -+ partition@4 { -+ label = "pcustfs"; -+ reg = <0x2000000 0x2000000>; -+ }; -+}; -+ -+&ccg_mdio_int { -+ status = "okay"; -+}; -+ -+&mdio_int { -+ status = "okay"; -+}; -+ -+&mdio_ext { -+ status = "okay"; -+}; -+ -+&hwrng { -+ status = "okay"; -+}; -+ -+&iproc_wdt { -+ status = "okay"; -+}; -+ -+&dmac0 { -+ status = "okay"; -+}; -+ -+&crypto { -+ status = "okay"; -+}; -+ -+&iproc_cmicd { -+ status = "okay"; -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956150.dts b/arch/arm/boot/dts/bcm956150.dts ---- a/arch/arm/boot/dts/bcm956150.dts 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm956150.dts 2017-11-09 17:52:54.744938000 +0800 -@@ -0,0 +1,180 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/dts-v1/; -+ -+#include "bcm-hurricane2.dtsi" -+ -+/ { -+ model = "Broadcom HR2 SVK (BCM956150K)"; -+ compatible = "brcm,bcm956150k", "brcm,hurricane2"; -+ -+ aliases { -+ serial0 = &uart1; -+ serial1 = &uart0; -+ ethernet0 = &gmac0; -+ }; -+ -+ chosen { -+ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart1 { -+ status = "okay"; -+}; -+ -+&gmac0 { -+ status = "okay"; -+}; -+ -+&gpio_cca { -+ status = "okay"; -+}; -+ -+&pcie0 { -+ status = "okay"; -+}; -+ -+&nand { -+ status = "okay"; -+ nandcs@1 { -+ compatible = "brcm,nandcs"; -+ reg = <0>; -+ nand-on-flash-bbt; -+ /*nand-bus-width = <8>;*/ -+ nand-ecc-strength = <24>; -+ nand-ecc-step-size = <1024>; -+ brcm,nand-oob-sector-size = <27>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "nboot"; -+ reg = <0x0 0x200000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "nenv"; -+ reg = <0x200000 0x400000>; -+ }; -+ partition@2 { -+ label = "nsystem"; -+ reg = <0x600000 0xa00000>; -+ }; -+ partition@3 { -+ label = "nrootfs"; -+ reg = <0x1000000 0xf000000>; -+ }; -+ partition@4 { -+ label = "ncustfs"; -+ reg = <0x10000000 0x70000000>; -+ }; -+ }; -+}; -+ -+&qspi { -+ status = "okay"; -+ flash: m25p80@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "m25p80"; -+ m25p,fast-read = <1>; -+ spi-max-frequency = <62500000>; -+ reg = <0x0>; -+ partition@0 { -+ label = "boot"; -+ reg = <0x00000000 0x000c0000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "env"; -+ reg = <0x000c0000 0x00040000>; -+ }; -+ partition@2 { -+ label = "system"; -+ reg = <0x00100000 0x00f00000>; -+ }; -+ partition@3 { -+ label = "rootfs"; -+ reg = <0x01000000 0x01000000>; -+ }; -+ }; -+}; -+ -+&pnor_flash { -+ status = "okay"; -+ -+ partition@0 { -+ label = "pboot"; -+ reg = <0x0 0xc0000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "penv"; -+ reg = <0xc0000 0x40000>; -+ }; -+ partition@2 { -+ label = "psystem"; -+ reg = <0x100000 0xf00000>; -+ }; -+ partition@3 { -+ label = "prootfs"; -+ reg = <0x1000000 0x1000000>; -+ }; -+ partition@4 { -+ label = "pcustfs"; -+ reg = <0x2000000 0x2000000>; -+ }; -+}; -+ -+&mdio_int { -+ status = "okay"; -+}; -+ -+&mdio_ext { -+ status = "okay"; -+}; -+ -+ -+&iproc_wdt { -+ status = "okay"; -+}; -+ -+&iproc_cmicd { -+ status = "okay"; -+}; -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956160.dts b/arch/arm/boot/dts/bcm956160.dts ---- a/arch/arm/boot/dts/bcm956160.dts 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm956160.dts 2017-11-09 17:52:54.745938000 +0800 -@@ -0,0 +1,212 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/dts-v1/; -+ -+#include "bcm-hurricane3.dtsi" -+ -+/ { -+ model = "Broadcom HR3 SVK (BCM956160K)"; -+ compatible = "brcm,bcm956160k", "brcm,hurricane3"; -+ -+ aliases { -+ serial0 = &uart0; -+ serial1 = &uart1; -+ ethernet0 = &gmac0; -+ }; -+ -+ chosen { -+ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart1 { -+ status = "okay"; -+}; -+ -+&gmac0 { -+ status = "okay"; -+}; -+ -+&usbphy0 { -+ status = "okay"; -+}; -+ -+&ehci0 { -+ status = "okay"; -+}; -+ -+&ohci0 { -+ status = "okay"; -+}; -+ -+&usbd { -+ status = "okay"; -+}; -+ -+&sdio { -+ status = "okay"; -+}; -+ -+&gpio_ccg { -+ status = "okay"; -+}; -+ -+&pcie0 { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ eeprom@0x50 { -+ compatible = "atmel,24c01"; -+ reg = <0x50>; -+ pagesize = <8>; -+ }; -+}; -+ -+&nand { -+ status = "okay"; -+ nandcs@1 { -+ compatible = "brcm,nandcs"; -+ reg = <0>; -+ nand-on-flash-bbt; -+ /*nand-bus-width = <8>;*/ -+ nand-ecc-strength = <24>; -+ nand-ecc-step-size = <1024>; -+ brcm,nand-oob-sector-size = <27>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "nboot"; -+ reg = <0x0 0x200000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "nenv"; -+ reg = <0x200000 0x400000>; -+ }; -+ partition@2 { -+ label = "nsystem"; -+ reg = <0x600000 0xa00000>; -+ }; -+ partition@3 { -+ label = "nrootfs"; -+ reg = <0x1000000 0xf000000>; -+ }; -+ partition@4 { -+ label = "ncustfs"; -+ reg = <0x10000000 0x30000000>; -+ }; -+ }; -+}; -+ -+&qspi { -+ status = "okay"; -+ flash: m25p80@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "m25p80"; -+ m25p,fast-read = <1>; -+ spi-max-frequency = <62500000>; -+ reg = <0x0>; -+ partition@0 { -+ label = "boot"; -+ reg = <0x00000000 0x000c0000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "env"; -+ reg = <0x000c0000 0x00040000>; -+ }; -+ partition@2 { -+ label = "system"; -+ reg = <0x00100000 0x00f00000>; -+ }; -+ partition@3 { -+ label = "rootfs"; -+ reg = <0x01000000 0x03000000>; -+ }; -+ }; -+}; -+ -+&pnor_flash { -+ status = "okay"; -+ -+ partition@0 { -+ label = "pboot"; -+ reg = <0x0 0xc0000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "penv"; -+ reg = <0xc0000 0x40000>; -+ }; -+ partition@2 { -+ label = "psystem"; -+ reg = <0x100000 0xf00000>; -+ }; -+ partition@3 { -+ label = "prootfs"; -+ reg = <0x1000000 0x1000000>; -+ }; -+ partition@4 { -+ label = "pcustfs"; -+ reg = <0x2000000 0x2000000>; -+ }; -+}; -+ -+&mdio_int { -+ status = "okay"; -+}; -+ -+&mdio_ext { -+ status = "okay"; -+}; -+ -+&hwrng { -+ status = "okay"; -+}; -+ -+&iproc_wdt { -+ status = "okay"; -+}; -+ -+&iproc_cmicd { -+ status = "okay"; -+}; -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956170.dts b/arch/arm/boot/dts/bcm956170.dts ---- a/arch/arm/boot/dts/bcm956170.dts 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm956170.dts 2017-11-09 17:52:54.746936000 +0800 -@@ -0,0 +1,239 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/dts-v1/; -+ -+#include "bcm-greyhound2.dtsi" -+ -+/ { -+ model = "Broadcom GH2 SVK (BCM956170)"; -+ compatible = "brcm,bcm956170", "brcm,greyhound2"; -+ -+ aliases { -+ serial0 = &uart0; -+ serial1 = &uart1; -+ ethernet0 = &gmac0; -+ ethernet1 = &gmac1; -+ }; -+ -+ chosen { -+ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart1 { -+ status = "okay"; -+}; -+ -+&gmac0 { -+ status = "okay"; -+}; -+ -+&gmac1 { -+ status = "okay"; -+}; -+ -+&usbphy0 { -+ status = "okay"; -+}; -+ -+&ehci0 { -+ status = "okay"; -+}; -+ -+&ohci0 { -+ status = "okay"; -+}; -+ -+&usbd { -+ status = "okay"; -+}; -+ -+&gpio_ccg { -+ status = "okay"; -+}; -+ -+&pcie0 { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ eeprom@0x50 { -+ compatible = "atmel,24c01"; -+ reg = <0x50>; -+ pagesize = <8>; -+ }; -+}; -+ -+&nand { -+ status = "okay"; -+ nandcs@1 { -+ compatible = "brcm,nandcs"; -+ reg = <0>; -+ nand-on-flash-bbt; -+ /*nand-bus-width = <8>;*/ -+ nand-ecc-strength = <24>; -+ nand-ecc-step-size = <1024>; -+ brcm,nand-oob-sector-size = <27>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "nboot"; -+ reg = <0x0 0x200000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "nenv"; -+ reg = <0x200000 0x400000>; -+ }; -+ partition@2 { -+ label = "nsystem"; -+ reg = <0x600000 0xa00000>; -+ }; -+ partition@3 { -+ label = "nrootfs"; -+ reg = <0x1000000 0xf000000>; -+ }; -+ partition@4 { -+ label = "ncustfs"; -+ reg = <0x10000000 0x30000000>; -+ }; -+ }; -+}; -+ -+&qspi { -+ status = "okay"; -+ flash: m25p80@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "m25p80"; -+ m25p,fast-read = <1>; -+ spi-max-frequency = <62500000>; -+ reg = <0x0>; -+ partition@0 { -+ label = "boot"; -+ reg = <0x00000000 0x000c0000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "env"; -+ reg = <0x000c0000 0x00040000>; -+ }; -+ partition@2 { -+ label = "system"; -+ reg = <0x00100000 0x00f00000>; -+ }; -+ partition@3 { -+ label = "rootfs"; -+ reg = <0x01000000 0x03000000>; -+ }; -+ }; -+}; -+ -+&pnor_flash { -+ status = "okay"; -+ -+ partition@0 { -+ label = "pboot"; -+ reg = <0x0 0xc0000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "penv"; -+ reg = <0xc0000 0x40000>; -+ }; -+ partition@2 { -+ label = "psystem"; -+ reg = <0x100000 0xf00000>; -+ }; -+ partition@3 { -+ label = "prootfs"; -+ reg = <0x1000000 0x1000000>; -+ }; -+ partition@4 { -+ label = "pcustfs"; -+ reg = <0x2000000 0x2000000>; -+ }; -+}; -+ -+&ccg_mdio_int { -+ status = "okay"; -+ pcie_phy0: pcie_phy@0 { -+ reg = <2>; -+ }; -+}; -+ -+&mdio_int { -+ status = "okay"; -+ amac_serdes0: amac_serdes@0 { -+ reg = <25>; -+ }; -+ amac_serdes1: amac_serdes@1 { -+ reg = <26>; -+ }; -+}; -+ -+&mdio_ext { -+ status = "okay"; -+ amac_phy0: amac_phy@0 { -+ reg = <16>; -+ }; -+ amac_phy1: amac_phy@1 { -+ reg = <17>; -+ }; -+}; -+ -+&hwrng { -+ status = "okay"; -+}; -+ -+&iproc_wdt { -+ status = "okay"; -+}; -+ -+&dmac0 { -+ status = "okay"; -+}; -+ -+&crypto { -+ status = "okay"; -+}; -+ -+&iproc_cmicd { -+ status = "okay"; -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956260.dts b/arch/arm/boot/dts/bcm956260.dts ---- a/arch/arm/boot/dts/bcm956260.dts 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm956260.dts 2017-11-09 17:52:54.747931000 +0800 -@@ -0,0 +1,182 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/dts-v1/; -+ -+#include "bcm-saber2.dtsi" -+ -+/ { -+ model = "Broadcom SB2 SVK (BCM956260K)"; -+ compatible = "brcm,bcm956260k", "brcm,saber2"; -+ -+ aliases { -+ serial0 = &uart0; -+ serial1 = &uart1; -+ ethernet0 = &gmac0; -+ }; -+ -+ chosen { -+ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart1 { -+ status = "okay"; -+}; -+ -+&gmac0 { -+ status = "okay"; -+}; -+ -+&usbphy0 { -+ status = "okay"; -+}; -+ -+&ehci0 { -+ status = "okay"; -+}; -+ -+&ohci0 { -+ status = "okay"; -+}; -+ -+&usbd { -+ status = "okay"; -+}; -+ -+&gpio_ccg { -+ status = "okay"; -+}; -+ -+&pcie0 { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ eeprom@0x50 { -+ compatible = "atmel,24c64"; -+ reg = <0x50>; -+ pagesize = <32>; -+ }; -+}; -+ -+&nand { -+ status = "okay"; -+ nandcs@1 { -+ compatible = "brcm,nandcs"; -+ reg = <0>; -+ nand-on-flash-bbt; -+ /*nand-bus-width = <8>;*/ -+ nand-ecc-strength = <24>; -+ nand-ecc-step-size = <1024>; -+ brcm,nand-oob-sector-size = <27>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "nboot"; -+ reg = <0x0 0x200000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "nenv"; -+ reg = <0x200000 0x400000>; -+ }; -+ partition@2 { -+ label = "nsystem"; -+ reg = <0x600000 0xa00000>; -+ }; -+ partition@3 { -+ label = "nrootfs"; -+ reg = <0x1000000 0xf000000>; -+ }; -+ partition@4 { -+ label = "ncustfs"; -+ reg = <0x10000000 0x70000000>; -+ }; -+ }; -+}; -+ -+&qspi { -+ status = "okay"; -+ flash: m25p80@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "m25p80"; -+ m25p,fast-read = <1>; -+ spi-max-frequency = <62500000>; -+ reg = <0x0>; -+ partition@0 { -+ label = "boot"; -+ reg = <0x00000000 0x000c0000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "env"; -+ reg = <0x000c0000 0x00040000>; -+ }; -+ partition@2 { -+ label = "system"; -+ reg = <0x00100000 0x00f00000>; -+ }; -+ partition@3 { -+ label = "rootfs"; -+ reg = <0x01000000 0x01000000>; -+ }; -+ }; -+}; -+ -+ -+&mdio_int { -+ status = "okay"; -+}; -+ -+&mdio_ext { -+ status = "okay"; -+}; -+ -+&hwrng { -+ status = "okay"; -+}; -+ -+&iproc_wdt { -+ status = "okay"; -+}; -+ -+&iproc_cmicd { -+ status = "okay"; -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956340.dts b/arch/arm/boot/dts/bcm956340.dts ---- a/arch/arm/boot/dts/bcm956340.dts 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm956340.dts 2017-11-09 17:52:54.748928000 +0800 -@@ -0,0 +1,196 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/dts-v1/; -+ -+#include "bcm-helix4.dtsi" -+ -+/ { -+ model = "Broadcom HX4 SVK (BCM956340K)"; -+ compatible = "brcm,bcm956340k", "brcm,helix4"; -+ -+ aliases { -+ serial0 = &uart0; -+ serial1 = &uart1; -+ ethernet0 = &gmac0; -+ ethernet1 = &gmac1; -+ }; -+ -+ chosen { -+ bootargs = "console=ttyS0,115200n8 maxcpus=2 mem=496M"; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart1 { -+ status = "okay"; -+}; -+ -+&gmac0 { -+ status = "okay"; -+}; -+ -+&gmac1 { -+ status = "okay"; -+}; -+ -+&usbphy0 { -+ status = "okay"; -+}; -+ -+&ehci0 { -+ status = "okay"; -+}; -+ -+&usbd { -+ status = "okay"; -+}; -+ -+&gpio_cca { -+ status = "okay"; -+}; -+ -+&pcie0 { -+ status = "okay"; -+}; -+ -+&pcie1 { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ eeprom@0x50 { -+ compatible = "atmel,24c01"; -+ reg = <0x50>; -+ pagesize = <8>; -+ }; -+}; -+ -+&i2c1 { -+ status = "okay"; -+}; -+ -+&nand { -+ status = "okay"; -+ nandcs@1 { -+ compatible = "brcm,nandcs"; -+ reg = <0>; -+ nand-on-flash-bbt; -+ /*nand-bus-width = <8>;*/ -+ nand-ecc-strength = <24>; -+ nand-ecc-step-size = <1024>; -+ brcm,nand-oob-sector-size = <27>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "nboot"; -+ reg = <0x0 0x200000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "nenv"; -+ reg = <0x200000 0x400000>; -+ }; -+ partition@2 { -+ label = "nsystem"; -+ reg = <0x600000 0xa00000>; -+ }; -+ partition@3 { -+ label = "nrootfs"; -+ reg = <0x1000000 0xf000000>; -+ }; -+ partition@4 { -+ label = "ncustfs"; -+ reg = <0x10000000 0x70000000>; -+ }; -+ }; -+}; -+ -+&qspi { -+ status = "okay"; -+ flash: m25p80@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "m25p80"; -+ m25p,fast-read = <1>; -+ spi-max-frequency = <62500000>; -+ reg = <0x0>; -+ partition@0 { -+ label = "boot"; -+ reg = <0x00000000 0x000c0000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "env"; -+ reg = <0x000c0000 0x00040000>; -+ }; -+ partition@2 { -+ label = "system"; -+ reg = <0x00100000 0x00f00000>; -+ }; -+ partition@3 { -+ label = "rootfs"; -+ reg = <0x01000000 0x01000000>; -+ }; -+ }; -+}; -+ -+ -+&mdio_int { -+ status = "okay"; -+}; -+ -+&mdio_ext { -+ status = "okay"; -+}; -+ -+&hwrng { -+ status = "okay"; -+}; -+ -+&iproc_wdt { -+ status = "okay"; -+}; -+ -+&dmac0 { -+ status = "okay"; -+}; -+ -+&iproc_cmicd { -+ status = "okay"; -+}; -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956450.dts b/arch/arm/boot/dts/bcm956450.dts ---- a/arch/arm/boot/dts/bcm956450.dts 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/bcm956450.dts 2017-11-09 17:52:54.748939000 +0800 -@@ -0,0 +1,195 @@ -+/* -+ * BSD LICENSE -+ * -+ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Broadcom Corporation nor the names of its -+ * contributors may be used to endorse or promote products derived -+ * from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/dts-v1/; -+ -+#include "bcm-katana2.dtsi" -+ -+/ { -+ model = "Broadcom KT2 SVK (BCM956450K)"; -+ compatible = "brcm,bcm956450k", "brcm,katana2"; -+ -+ aliases { -+ serial0 = &uart0; -+ serial1 = &uart1; -+ ethernet0 = &gmac0; -+ ethernet1 = &gmac1; -+ }; -+ -+ chosen { -+ bootargs = "console=ttyS0,115200n8 maxcpus=2 mem=496M"; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart1 { -+ status = "okay"; -+}; -+ -+&gmac0 { -+ status = "okay"; -+}; -+ -+&gmac1 { -+ status = "okay"; -+}; -+ -+&usbphy0 { -+ status = "okay"; -+}; -+ -+&ehci0 { -+ status = "okay"; -+}; -+ -+&usbd { -+ status = "okay"; -+}; -+ -+&gpio_cca { -+ status = "okay"; -+}; -+ -+&pcie0 { -+ status = "okay"; -+}; -+ -+&pcie1 { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ eeprom@0x50 { -+ compatible = "atmel,24c01"; -+ reg = <0x50>; -+ pagesize = <8>; -+ }; -+}; -+ -+&i2c1 { -+ status = "okay"; -+}; -+ -+&nand { -+ status = "okay"; -+ nandcs@1 { -+ compatible = "brcm,nandcs"; -+ reg = <0>; -+ nand-on-flash-bbt; -+ /*nand-bus-width = <8>;*/ -+ nand-ecc-strength = <24>; -+ nand-ecc-step-size = <1024>; -+ brcm,nand-oob-sector-size = <27>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "nboot"; -+ reg = <0x0 0x200000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "nenv"; -+ reg = <0x200000 0x400000>; -+ }; -+ partition@2 { -+ label = "nsystem"; -+ reg = <0x600000 0xa00000>; -+ }; -+ partition@3 { -+ label = "nrootfs"; -+ reg = <0x1000000 0xf000000>; -+ }; -+ partition@4 { -+ label = "ncustfs"; -+ reg = <0x10000000 0x70000000>; -+ }; -+ }; -+}; -+ -+&qspi { -+ status = "okay"; -+ flash: m25p80@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "m25p80"; -+ m25p,fast-read = <1>; -+ spi-max-frequency = <62500000>; -+ reg = <0x0>; -+ partition@0 { -+ label = "boot"; -+ reg = <0x00000000 0x000c0000>; -+ /*read-only;*/ -+ }; -+ partition@1 { -+ label = "env"; -+ reg = <0x000c0000 0x00040000>; -+ }; -+ partition@2 { -+ label = "system"; -+ reg = <0x00100000 0x00f00000>; -+ }; -+ partition@3 { -+ label = "rootfs"; -+ reg = <0x01000000 0x01000000>; -+ }; -+ }; -+}; -+ -+ -+&mdio_int { -+ status = "okay"; -+}; -+ -+&mdio_ext { -+ status = "okay"; -+}; -+ -+&hwrng { -+ status = "okay"; -+}; -+ -+&iproc_wdt { -+ status = "okay"; -+}; -+ -+&dmac0 { -+ status = "okay"; -+}; -+ -+&iproc_cmicd { -+ status = "okay"; -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/greyhound.its b/arch/arm/boot/dts/greyhound.its ---- a/arch/arm/boot/dts/greyhound.its 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/greyhound.its 2017-11-09 17:52:54.939941000 +0800 -@@ -0,0 +1,62 @@ -+/dts-v1/; -+ -+/ { -+ description = "Linux kernel and FDT blob"; -+ #address-cells = <1>; -+ -+ images { -+ kernel@1 { -+ description = "Broadcom iProc Linux"; -+ data = /incbin/("../zImage"); -+ type = "kernel"; -+ arch = "arm"; -+ os = "linux"; -+ compression = "none"; -+ load = <0x61008000>; -+ entry = <0x61008000>; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ -+ fdt@1 { -+ description = "Flattened Device Tree blob - bcm95341x.dtb"; -+ data = /incbin/("./bcm95341x.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+/* -+ fdt@2 { -+ description = "Flattened Device Tree blob - bcm95606x.dtb"; -+ data = /incbin/("./bcm95606x.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ hash@1 { -+ algo = "md5"; -+ }; -+ }; -+*/ -+ }; -+ -+ configurations { -+ default = "conf@1"; -+ conf@1 { -+ description = "Boot Linux kernel with FDT blob "; -+ kernel = "kernel@1"; -+ fdt = "fdt@1"; -+ }; -+/* -+ conf@2 { -+ description = "Boot Linux kernel with FDT blob"; -+ kernel = "kernel@1"; -+ fdt = "fdt@2"; -+ }; -+*/ -+ }; -+}; -+ -\ No newline at end of file -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/greyhound2.its b/arch/arm/boot/dts/greyhound2.its ---- a/arch/arm/boot/dts/greyhound2.its 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/greyhound2.its 2017-11-09 17:52:54.945934000 +0800 -@@ -0,0 +1,62 @@ -+/dts-v1/; -+ -+/ { -+ description = "Linux kernel and FDT blob"; -+ #address-cells = <1>; -+ -+ images { -+ kernel@1 { -+ description = "Broadcom iProc Linux"; -+ data = /incbin/("../zImage"); -+ type = "kernel"; -+ arch = "arm"; -+ os = "linux"; -+ compression = "none"; -+ load = <0x61008000>; -+ entry = <0x61008000>; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ -+ fdt@1 { -+ description = "Flattened Device Tree blob - bcm956170.dtb"; -+ data = /incbin/("./bcm956170.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ -+ fdt@2 { -+ description = "Flattened Device Tree blob - bcm95357x.dtb"; -+ data = /incbin/("./bcm95357x.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ -+ }; -+ -+ configurations { -+ default = "conf@1"; -+ conf@1 { -+ description = "Boot Linux kernel with FDT blob "; -+ kernel = "kernel@1"; -+ fdt = "fdt@1"; -+ }; -+/* -+ conf@2 { -+ description = "Boot Linux kernel with FDT blob"; -+ kernel = "kernel@1"; -+ fdt = "fdt@2"; -+ }; -+*/ -+ }; -+}; -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/helix4.its b/arch/arm/boot/dts/helix4.its ---- a/arch/arm/boot/dts/helix4.its 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/helix4.its 2017-11-09 17:52:54.946939000 +0800 -@@ -0,0 +1,43 @@ -+/dts-v1/; -+ -+/ { -+ description = "Linux kernel and FDT blob"; -+ #address-cells = <1>; -+ -+ images { -+ kernel@1 { -+ description = "Broadcom iProc Linux"; -+ data = /incbin/("../zImage"); -+ type = "kernel"; -+ arch = "arm"; -+ os = "linux"; -+ compression = "none"; -+ load = <0x61008000>; -+ entry = <0x61008000>; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ -+ fdt@1 { -+ description = "Flattened Device Tree blob - bcm956340.dtb"; -+ data = /incbin/("./bcm956340.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ }; -+ -+ configurations { -+ default = "conf@1"; -+ conf@1 { -+ description = "Boot Linux kernel with FDT blob "; -+ kernel = "kernel@1"; -+ fdt = "fdt@1"; -+ }; -+ }; -+}; -+ -\ No newline at end of file -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/hurricane2.its b/arch/arm/boot/dts/hurricane2.its ---- a/arch/arm/boot/dts/hurricane2.its 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/hurricane2.its 2017-11-09 17:52:54.966932000 +0800 -@@ -0,0 +1,43 @@ -+/dts-v1/; -+ -+/ { -+ description = "Linux kernel and FDT blob"; -+ #address-cells = <1>; -+ -+ images { -+ kernel@1 { -+ description = "Broadcom iProc Linux"; -+ data = /incbin/("../zImage"); -+ type = "kernel"; -+ arch = "arm"; -+ os = "linux"; -+ compression = "none"; -+ load = <0x81008000>; -+ entry = <0x81008000>; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ -+ fdt@1 { -+ description = "Flattened Device Tree blob - bcm956150.dtb"; -+ data = /incbin/("./bcm956150.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ }; -+ -+ configurations { -+ default = "conf@1"; -+ conf@1 { -+ description = "Boot Linux kernel with FDT blob "; -+ kernel = "kernel@1"; -+ fdt = "fdt@1"; -+ }; -+ }; -+}; -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/hurricane3.its b/arch/arm/boot/dts/hurricane3.its ---- a/arch/arm/boot/dts/hurricane3.its 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/hurricane3.its 2017-11-09 17:52:54.966943000 +0800 -@@ -0,0 +1,60 @@ -+/dts-v1/; -+ -+/ { -+ description = "Linux kernel and FDT blob"; -+ #address-cells = <1>; -+ -+ images { -+ kernel@1 { -+ description = "Broadcom iProc Linux"; -+ data = /incbin/("../zImage"); -+ type = "kernel"; -+ arch = "arm"; -+ os = "linux"; -+ compression = "none"; -+ load = <0x61008000>; -+ entry = <0x61008000>; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ -+ fdt@1 { -+ description = "Flattened Device Tree blob - bcm956160.dtb"; -+ data = /incbin/("./bcm956160.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ -+ fdt@2 { -+ description = "Flattened Device Tree blob - bcm953444.dtb"; -+ data = /incbin/("./bcm953444.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ }; -+ -+ configurations { -+ default = "conf@1"; -+ conf@1 { -+ description = "Boot Linux kernel with FDT blob 1"; -+ kernel = "kernel@1"; -+ fdt = "fdt@1"; -+ }; -+ -+ conf@2 { -+ description = "Boot Linux kernel with FDT blob 2"; -+ kernel = "kernel@1"; -+ fdt = "fdt@2"; -+ }; -+ }; -+}; -+ -\ No newline at end of file -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/katana2.its b/arch/arm/boot/dts/katana2.its ---- a/arch/arm/boot/dts/katana2.its 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/katana2.its 2017-11-09 17:52:55.281942000 +0800 -@@ -0,0 +1,43 @@ -+/dts-v1/; -+ -+/ { -+ description = "Linux kernel and FDT blob"; -+ #address-cells = <1>; -+ -+ images { -+ kernel@1 { -+ description = "Broadcom iProc Linux"; -+ data = /incbin/("../zImage"); -+ type = "kernel"; -+ arch = "arm"; -+ os = "linux"; -+ compression = "none"; -+ load = <0x61008000>; -+ entry = <0x61008000>; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ -+ fdt@1 { -+ description = "Flattened Device Tree blob - bcm956450.dtb"; -+ data = /incbin/("./bcm956450.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ }; -+ -+ configurations { -+ default = "conf@1"; -+ conf@1 { -+ description = "Boot Linux kernel with FDT blob "; -+ kernel = "kernel@1"; -+ fdt = "fdt@1"; -+ }; -+ }; -+}; -+ -\ No newline at end of file -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/saber2.its b/arch/arm/boot/dts/saber2.its ---- a/arch/arm/boot/dts/saber2.its 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/saber2.its 2017-11-09 17:52:55.880949000 +0800 -@@ -0,0 +1,43 @@ -+/dts-v1/; -+ -+/ { -+ description = "Linux kernel and FDT blob"; -+ #address-cells = <1>; -+ -+ images { -+ kernel@1 { -+ description = "Broadcom iProc Linux"; -+ data = /incbin/("../zImage"); -+ type = "kernel"; -+ arch = "arm"; -+ os = "linux"; -+ compression = "none"; -+ load = <0x61008000>; -+ entry = <0x61008000>; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ -+ fdt@1 { -+ description = "Flattened Device Tree blob - bcm956260.dtb"; -+ data = /incbin/("./bcm956260.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ }; -+ -+ configurations { -+ default = "conf@1"; -+ conf@1 { -+ description = "Boot Linux kernel with FDT blob "; -+ kernel = "kernel@1"; -+ fdt = "fdt@1"; -+ }; -+ }; -+}; -+ -\ No newline at end of file -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/wolfhound2.its b/arch/arm/boot/dts/wolfhound2.its ---- a/arch/arm/boot/dts/wolfhound2.its 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/boot/dts/wolfhound2.its 2017-11-09 17:52:56.333945000 +0800 -@@ -0,0 +1,60 @@ -+/dts-v1/; -+ -+/ { -+ description = "Linux kernel and FDT blob"; -+ #address-cells = <1>; -+ -+ images { -+ kernel@1 { -+ description = "Broadcom iProc Linux"; -+ data = /incbin/("../zImage"); -+ type = "kernel"; -+ arch = "arm"; -+ os = "linux"; -+ compression = "none"; -+ load = <0x61008000>; -+ entry = <0x61008000>; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ -+ fdt@1 { -+ description = "Flattened Device Tree blob - bcm953547.dtb"; -+ data = /incbin/("./bcm953547.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; -+ -+ /* fdt@2 { -+ description = "Flattened Device Tree blob - bcm953444.dtb"; -+ data = /incbin/("./bcm953444.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ hash@1 { -+ algo = "crc32"; -+ }; -+ }; */ -+ }; -+ -+ configurations { -+ default = "conf@1"; -+ conf@1 { -+ description = "Boot Linux kernel with FDT blob 1"; -+ kernel = "kernel@1"; -+ fdt = "fdt@1"; -+ }; -+ -+ /* conf@2 { -+ description = "Boot Linux kernel with FDT blob 2"; -+ kernel = "kernel@1"; -+ fdt = "fdt@2"; -+ }; */ -+ }; -+}; -+ -\ No newline at end of file -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/Kconfig b/arch/arm/mach-iproc/Kconfig ---- a/arch/arm/mach-iproc/Kconfig 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/mach-iproc/Kconfig 2017-11-09 17:52:58.315964000 +0800 -@@ -0,0 +1,84 @@ -+menuconfig ARCH_XGS_IPROC -+ bool "Broadcom XGS iProc Support" if ARCH_MULTI_V7 -+ select HAVE_ARM_TWD if SMP -+ select HAVE_ARM_SCU if SMP -+ select ARM_GLOBAL_TIMER -+ select ARM_GIC -+ select ARCH_REQUIRE_GPIOLIB -+ select CACHE_L2X0 -+ select ARM_AMBA -+ select ARCH_SUPPORTS_BIG_ENDIAN -+ select CPU_ENDIAN_BE8 if CPU_BIG_ENDIAN -+ select ARM_ERRATA_754322 -+ select ARM_ERRATA_764369 if SMP -+ select ARM_ERRATA_775420 -+ help -+ This enables support for Broadcom XGS iProc based SoC chips -+ -+if ARCH_XGS_IPROC -+ -+comment "XGS iProc SoC based Machine types" -+ -+choice -+ prompt "XGS iProc SoC based Machine types" -+ default MACH_HX4 -+ -+config MACH_HX4 -+ bool "Support Broadcom Helix4 bring-up board" -+ help -+ Support for the Broadcom Helix4 bring-up board. -+ -+config MACH_HR2 -+ bool "Support Broadcom Hurricane2 bring-up board" -+ help -+ Support for the Broadcom Hurricane2 bring-up board. -+ -+config MACH_KT2 -+ bool "Support Broadcom Katana2 bring-up board" -+ help -+ Support for the Broadcom Katana2 bring-up board. -+ -+config MACH_GH -+ bool "Support Broadcom Greyhound bring-up board" -+ select MACH_IPROC_P7 -+ help -+ Support for the Broadcom Greyhound bring-up board. -+ -+config MACH_SB2 -+ bool "Support Broadcom Saber2 bring-up board" -+ select MACH_IPROC_P7 -+ help -+ Support for the Broadcom Saber2 bring-up board. -+ -+config MACH_HR3 -+ bool "Support Broadcom Hurricane3 bring-up board" -+ select MACH_IPROC_P7 -+ help -+ Support for the Broadcom Hurricane3 bring-up board. -+ -+config MACH_GH2 -+ bool "Support Broadcom Greyhound2 bring-up board" -+ select MACH_IPROC_P7 -+ help -+ Support for the Broadcom Greyhound2 bring-up board. -+endchoice -+ -+config MACH_IPROC_P7 -+ bool "Support iProc Profile 7 architecture" -+ depends on (MACH_GH || MACH_SB2 || MACH_HR3 || MACH_GH2 || MACH_WH2) -+ help -+ Support for iProc Profile 7 architecture. -+ -+config MACH_WH2 -+ bool "Support Broadcom Wolfhound2 bring-up board" -+ depends on MACH_HR3 -+ default n -+ help -+ Support for the Broadcom Wolfhound2 bring-up board. -+ -+config MACH_IPROC_EMULATION -+ bool "Support iProc emulation" -+ help -+ Support for the iProc emulation. -+ -+endif -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/Makefile b/arch/arm/mach-iproc/Makefile ---- a/arch/arm/mach-iproc/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/mach-iproc/Makefile 2017-11-09 17:52:58.316963000 +0800 -@@ -0,0 +1,3 @@ -+obj-y := board_bu.o -+obj-y += shm.o -+obj-$(CONFIG_SMP) += platsmp.o -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/board_bu.c b/arch/arm/mach-iproc/board_bu.c ---- a/arch/arm/mach-iproc/board_bu.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/mach-iproc/board_bu.c 2017-11-09 17:52:58.317968000 +0800 -@@ -0,0 +1,120 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DMU_CRU_RESET_BASE 0x200 -+ -+#if defined(CONFIG_PL330_DMA) || defined(CONFIG_XGS_IPROC_DMA330_DMA) -+/* SB2/HR3 */ -+#define DMAC_IDM_RESET_OFFSET 0xf800 -+/* HX4/KT2/HR2/GH */ -+#define DMAC_IDM_RESET_OFFSET_1 0x14800 -+#endif /* CONFIG_PL330_DMA || CONFIG_XGS_IPROC_DMA330_DMA */ -+ -+enum xgs_iproc_dev_id { -+ XGS_IPROC_HX4=0, -+ XGS_IPROC_KT2, -+ XGS_IPROC_HR2, -+ XGS_IPROC_GH, -+ XGS_IPROC_SB2, -+ XGS_IPROC_HR3, -+ XGS_IPROC_GH2, -+ XGS_IPROC_GENERIC, -+}; -+ -+const char *const xgs_iproc_dt_compat[] = { -+ "brcm,helix4", -+ "brcm,katana2", -+ "brcm,hurricane2", -+ "brcm,greyhound", -+ "brcm,saber2", -+ "brcm,hurricane3", -+ "brcm,greyhound2", -+ "brcm,xgs-iproc", -+ NULL, -+}; -+ -+#if defined(CONFIG_PL330_DMA) || defined(CONFIG_XGS_IPROC_DMA330_DMA) -+void xgs_iproc_dmac_idm_reset(void) -+{ -+ void __iomem *reset_base = NULL; -+ -+ /* Need to de-assert reset of DMAC before of_platform_populate */ -+ if (of_machine_is_compatible(xgs_iproc_dt_compat[XGS_IPROC_SB2]) || -+ of_machine_is_compatible(xgs_iproc_dt_compat[XGS_IPROC_HR3]) || -+ of_machine_is_compatible(xgs_iproc_dt_compat[XGS_IPROC_GH2])) -+ reset_base = get_iproc_idm_base(0) + DMAC_IDM_RESET_OFFSET; -+ else -+ reset_base = get_iproc_idm_base(0) + DMAC_IDM_RESET_OFFSET_1; -+ -+ if (reset_base != NULL) -+ writel(readl(reset_base) & 0xFFFFFFFE, reset_base); -+} -+#endif /* CONFIG_PL330_DMA || CONFIG_XGS_IPROC_DMA330_DMA */ -+ -+void __init xgs_iproc_init_early(void) -+{ -+ /* -+ * SDK allocates coherent buffers from atomic context. -+ * Increase size of atomic coherent pool to make sure such -+ * the allocations won't fail. -+ */ -+#ifdef CONFIG_DMA_CMA -+ /*can be overrided by "coherent_pool" in bootargs */ -+ init_dma_coherent_pool_size(SZ_1M * 16); -+#endif -+} -+ -+static void __init xgs_iproc_init(void) -+{ -+ int ret; -+ -+ ret = xgs_iproc_wrap_idm_dmu_base_reg_setup(); -+ if (ret < 0) -+ return; -+ -+#if defined(CONFIG_PL330_DMA) || defined(CONFIG_XGS_IPROC_DMA330_DMA) -+ xgs_iproc_dmac_idm_reset(); -+#endif -+ /* Populate platform devices */ -+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); -+ -+ /* Setup IDM timeout handler */ -+ xgs_iproc_idm_timeout_handler_setup(); -+} -+ -+ -+static void xgs_iproc_restart(enum reboot_mode mode, const char *cmd) -+{ -+ void * __iomem reg_addr; -+ u32 reg; -+ -+ /* CRU_RESET register */ -+ reg_addr = (void * __iomem)(get_iproc_dmu_pcu_base() + -+ DMU_CRU_RESET_BASE); -+ /* set iproc_reset_n to 0 */ -+ reg = readl(reg_addr); -+ reg &= ~((u32) 1 << 1); -+ -+ writel(reg, reg_addr); -+ -+ /* Wait for reset */ -+ while (1) -+ cpu_do_idle(); -+} -+ -+DT_MACHINE_START(XGS_iProc_DT, "BRCM XGS iProc") -+ .init_early = xgs_iproc_init_early, -+ .init_machine = xgs_iproc_init, -+ .dt_compat = xgs_iproc_dt_compat, -+ .restart = xgs_iproc_restart, -+ .l2c_aux_val = 0, -+ .l2c_aux_mask = ~0, -+MACHINE_END -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/include/plat/shm.h b/arch/arm/mach-iproc/include/plat/shm.h ---- a/arch/arm/mach-iproc/include/plat/shm.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/mach-iproc/include/plat/shm.h 2017-11-09 17:52:58.322965000 +0800 -@@ -0,0 +1,72 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ */ -+/* -+ * Header for declaring shim layer exports. -+ */ -+ -+#ifndef __SHM_DOT_H_INCLUDED__ -+#define __SHM_DOT_H_INCLUDED__ -+ -+#include -+#include -+#include -+ -+ -+#define iproc_class_create(owner, name) \ -+({ \ -+ static struct lock_class_key __key; \ -+ iproc__class_create(owner, name, &__key); \ -+}) -+ -+extern int iproc_platform_get_irq(struct platform_device *dev, unsigned int num); -+extern struct resource * -+iproc_platform_get_resource_byname(struct platform_device *dev, unsigned int type, const char *name); -+extern struct resource * -+iproc_platform_get_resource(struct platform_device *dev, unsigned int type, -+ unsigned int num); -+extern int iproc_platform_device_add_resources(struct platform_device *pdev, const struct resource *res, unsigned int num); -+ -+extern int iproc_platform_device_register(struct platform_device * pdev); -+extern void iproc_platform_device_unregister(struct platform_device * pdev); -+extern int iproc_platform_driver_register(struct platform_driver *drv); -+extern void iproc_platform_driver_unregister(struct platform_driver *drv); -+ -+extern struct platform_device *iproc_platform_device_alloc(const char *name, int id); -+ -+extern int iproc_platform_device_add(struct platform_device *pdev); -+extern void iproc_platform_device_put(struct platform_device *pdev); -+ -+extern void iproc_platform_device_put(struct platform_device *pdev); -+extern int iproc_platform_device_add(struct platform_device *pdev); -+extern void iproc_platform_device_del(struct platform_device *pdev); -+extern int iproc_sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp); -+extern void iproc_sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp); -+ -+ -+extern struct class *iproc__class_create(struct module *owner, const char *name, -+ struct lock_class_key *key); -+extern void iproc_class_destroy(struct class *cls); -+extern int iproc_device_create_file(struct device *dev, -+ const struct device_attribute *attr); -+extern struct device *iproc_device_create(struct class *class, -+ struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...); -+extern void iproc_device_destroy(struct class *class, dev_t devt); -+extern void iproc_device_remove_file(struct device *dev, -+ const struct device_attribute *attr); -+extern int iproc_platform_get_irq_byname(struct platform_device *, const char *); -+ -+extern int iproc_gpio_to_irq(unsigned gpio); -+#endif /*#ifndef __SHM_DOT_H_INCLUDED__*/ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/platsmp.c b/arch/arm/mach-iproc/platsmp.c ---- a/arch/arm/mach-iproc/platsmp.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/mach-iproc/platsmp.c 2017-11-09 17:52:58.323963000 +0800 -@@ -0,0 +1,210 @@ -+/* -+ * Copyright (C) 2014-2015 Broadcom Corporation -+ * Copyright 2014 Linaro Limited -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+/* Size of mapped Cortex A9 SCU address space */ -+#define CORTEX_A9_SCU_SIZE 0x58 -+ -+#define SECONDARY_TIMEOUT_NS NSEC_PER_MSEC /* 1 msec (in nanoseconds) */ -+#define BOOT_ADDR_CPUID_MASK 0x3 -+ -+/* Name of device node property defining secondary boot register location */ -+#define OF_SECONDARY_BOOT "secondary-boot-reg" -+#define MPIDR_CPUID_BITMASK 0x3 -+ -+/* I/O address of register used to coordinate secondary core startup */ -+static u32 secondary_boot_addr; -+ -+/* -+ * Enable the Cortex A9 Snoop Control Unit -+ * -+ * By the time this is called we already know there are multiple -+ * cores present. We assume we're running on a Cortex A9 processor, -+ * so any trouble getting the base address register or getting the -+ * SCU base is a problem. -+ * -+ * Return 0 if successful or an error code otherwise. -+ */ -+static int __init scu_a9_enable(void) -+{ -+ unsigned long config_base; -+ void __iomem *scu_base; -+ -+ if (!scu_a9_has_base()) { -+ pr_err("no configuration base address register!\n"); -+ return -ENXIO; -+ } -+ -+ /* Config base address register value is zero for uniprocessor */ -+ config_base = scu_a9_get_base(); -+ if (!config_base) { -+ pr_err("hardware reports only one core\n"); -+ return -ENOENT; -+ } -+ -+ scu_base = ioremap((phys_addr_t)config_base, CORTEX_A9_SCU_SIZE); -+ if (!scu_base) { -+ pr_err("failed to remap config base (%lu/%u) for SCU\n", -+ config_base, CORTEX_A9_SCU_SIZE); -+ return -ENOMEM; -+ } -+ -+ scu_enable(scu_base); -+ -+ iounmap(scu_base); /* That's the last we'll need of this */ -+ -+ return 0; -+} -+ -+static int nsp_write_lut(void) -+{ -+ void __iomem *sku_rom_lut; -+ phys_addr_t secondary_startup_phy; -+ -+ if (!secondary_boot_addr) { -+ pr_warn("required secondary boot register not specified\n"); -+ return -EINVAL; -+ } -+ -+ sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot_addr, -+ sizeof(secondary_boot_addr)); -+ if (!sku_rom_lut) { -+ pr_warn("unable to ioremap SKU-ROM LUT register\n"); -+ return -ENOMEM; -+ } -+ -+ secondary_startup_phy = virt_to_phys(secondary_startup); -+ BUG_ON(secondary_startup_phy > (phys_addr_t)U32_MAX); -+ -+ writel_relaxed(secondary_startup_phy, sku_rom_lut); -+ -+ /* Ensure the write is visible to the secondary core */ -+ smp_wmb(); -+ -+ iounmap(sku_rom_lut); -+ -+ return 0; -+} -+ -+static void __init bcm_smp_prepare_cpus(unsigned int max_cpus) -+{ -+ static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 }; -+ struct device_node *cpus_node = NULL; -+ struct device_node *cpu_node = NULL; -+ int ret; -+ -+ /* -+ * This function is only called via smp_ops->smp_prepare_cpu(). -+ * That only happens if a "/cpus" device tree node exists -+ * and has an "enable-method" property that selects the SMP -+ * operations defined herein. -+ */ -+ cpus_node = of_find_node_by_path("/cpus"); -+ if (!cpus_node) -+ return; -+ -+ for_each_child_of_node(cpus_node, cpu_node) { -+ u32 cpuid; -+ -+ if (of_node_cmp(cpu_node->type, "cpu")) -+ continue; -+ -+ if (of_property_read_u32(cpu_node, "reg", &cpuid)) { -+ pr_debug("%s: missing reg property\n", -+ cpu_node->full_name); -+ ret = -ENOENT; -+ goto out; -+ } -+ -+ /* -+ * "secondary-boot-reg" property should be defined only -+ * for secondary cpu -+ */ -+ if ((cpuid & MPIDR_CPUID_BITMASK) == 1) { -+ /* -+ * Our secondary enable method requires a -+ * "secondary-boot-reg" property to specify a register -+ * address used to request the ROM code boot a secondary -+ * core. If we have any trouble getting this we fall -+ * back to uniprocessor mode. -+ */ -+ if (of_property_read_u32(cpu_node, -+ OF_SECONDARY_BOOT, -+ &secondary_boot_addr)) { -+ pr_warn("%s: no" OF_SECONDARY_BOOT "property\n", -+ cpu_node->name); -+ ret = -ENOENT; -+ goto out; -+ } -+ } -+ } -+ -+ /* -+ * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is -+ * returned, the SoC reported a uniprocessor configuration. -+ * We bail on any other error. -+ */ -+ ret = scu_a9_enable(); -+out: -+ of_node_put(cpu_node); -+ of_node_put(cpus_node); -+ -+ if (ret) { -+ /* Update the CPU present map to reflect uniprocessor mode */ -+ pr_warn("disabling SMP\n"); -+ init_cpu_present(&only_cpu_0); -+ } -+} -+ -+static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle) -+{ -+ int ret; -+ -+ /* -+ * After wake up, secondary core branches to the startup -+ * address programmed at SKU ROM LUT location. -+ */ -+ ret = nsp_write_lut(); -+ if (ret) { -+ pr_err("unable to write startup addr to SKU ROM LUT\n"); -+ goto out; -+ } -+ -+ /* Send a CPU wakeup interrupt to the secondary core */ -+ arch_send_wakeup_ipi_mask(cpumask_of(cpu)); -+ -+out: -+ return ret; -+} -+ -+/* Leverage NSP SMP code for HX4/KT2 */ -+static const struct smp_operations nsp_smp_ops __initconst = { -+ .smp_prepare_cpus = bcm_smp_prepare_cpus, -+ .smp_boot_secondary = nsp_boot_secondary, -+}; -+CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/shm.c b/arch/arm/mach-iproc/shm.c ---- a/arch/arm/mach-iproc/shm.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/arch/arm/mach-iproc/shm.c 2017-11-09 17:52:58.324964000 +0800 -@@ -0,0 +1,309 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ */ -+ -+#include "include/plat/shm.h" -+/** -+ * iproc_platform_get_irq - get an IRQ for a device -+ * wrapper function for platform_get_irq -+ * @dev: platform device -+ * @num: IRQ number index -+ */ -+int iproc_platform_get_irq(struct platform_device *dev, unsigned int num) -+{ -+ return platform_get_irq(dev, num); -+} -+EXPORT_SYMBOL(iproc_platform_get_irq); -+ -+ -+/** -+ * iproc_platform_get_resource_byname - -+ * wrapper function for platform_get_resource_byname -+ * @dev: platform device -+ * @type: resource type -+ * @name: resource name -+ */ -+struct resource * -+iproc_platform_get_resource_byname(struct platform_device *dev, -+ unsigned int type, -+ const char *name) -+{ -+ return platform_get_resource_byname(dev, type, name); -+} -+EXPORT_SYMBOL(iproc_platform_get_resource_byname); -+ -+ -+/** -+ * iproc_platform_get_resource - -+ * wrapper function for platform_get_resource -+ * @dev: platform device -+ * @type: resource type -+ * @num: resource index -+ */ -+struct resource * -+iproc_platform_get_resource(struct platform_device *dev, unsigned int type, -+ unsigned int num) -+{ -+ return platform_get_resource(dev, type, num); -+} -+EXPORT_SYMBOL(iproc_platform_get_resource); -+ -+ -+/** -+ * iproc_platform_driver_register - -+ * wrapper function for platform_driver_register -+ * @drv: platform driver structure -+ */ -+int iproc_platform_driver_register(struct platform_driver *drv) -+{ -+ return platform_driver_register(drv); -+} -+EXPORT_SYMBOL(iproc_platform_driver_register); -+ -+ -+/** -+ * iproc_platform_driver_unregister -+ * wrapper function for platform_driver_unregister -+ * @drv: platform driver structure -+ */ -+void iproc_platform_driver_unregister(struct platform_driver *drv) -+{ -+ return platform_driver_unregister(drv); -+} -+EXPORT_SYMBOL(iproc_platform_driver_unregister); -+ -+ -+/** -+ * iproc_platform_device_register - add a platform-level device -+ * wrapper function for platform_device_register -+ * @pdev: platform device we're adding -+ * -+ */ -+int iproc_platform_device_register(struct platform_device * pdev) -+{ -+ return platform_device_register(pdev); -+} -+EXPORT_SYMBOL(iproc_platform_device_register); -+ -+ -+/** -+ * iproc_platform_device_unregister - -+ * wrapper function for platform_device_unregister -+ * @pdev: platform device we're unregistering -+ */ -+void iproc_platform_device_unregister(struct platform_device * pdev) -+{ -+ return platform_device_unregister(pdev); -+} -+EXPORT_SYMBOL(iproc_platform_device_unregister); -+ -+ -+/** -+ * iproc_platform_device_alloc - -+ * wrapper function for platform_device_alloc -+ * @name: base name of the device we're adding -+ * @id: instance id -+ */ -+struct platform_device *iproc_platform_device_alloc(const char *name, int id) -+{ -+ return platform_device_alloc(name, id); -+} -+EXPORT_SYMBOL(iproc_platform_device_alloc); -+ -+/** -+ * iproc_platform_device_add - -+ * wrapper function for platform_device_add -+ * @pdev: platform device we're adding -+ */ -+int iproc_platform_device_add(struct platform_device *pdev) -+{ -+ return platform_device_add(pdev); -+} -+EXPORT_SYMBOL(iproc_platform_device_add); -+ -+/** -+ * iproc_platform_device_del - -+ * wrapper function for platform_device_del -+ * @pdev: platform device we're removing -+ */ -+void iproc_platform_device_del(struct platform_device *pdev) -+{ -+ platform_device_del(pdev); -+} -+EXPORT_SYMBOL(iproc_platform_device_del); -+ -+ -+/** -+ * iproc_platform_device_put - -+ * wrapper function for platform_device_put -+ * @pdev: platform device to free -+ */ -+void iproc_platform_device_put(struct platform_device *pdev) -+{ -+ platform_device_put(pdev); -+} -+EXPORT_SYMBOL(iproc_platform_device_put); -+ -+ -+/** -+ * iproc_platform_device_add_resources - -+ * wrapper function for platform_device_add_resources -+ * @pdev: platform device allocated by platform_device_alloc to add resources to -+ * @res: set of resources that needs to be allocated for the device -+ * @num: number of resources -+ */ -+int iproc_platform_device_add_resources(struct platform_device *pdev, -+ const struct resource *res, unsigned int num) -+{ -+ return platform_device_add_resources(pdev, res, num); -+} -+EXPORT_SYMBOL(iproc_platform_device_add_resources); -+ -+ -+/** -+ * iproc_platform_device_put - -+ * wrapper function for sysfs_create_group -+ * @kobj: The kobject to create the group on -+ * @grp: The attribute group to create -+ */ -+int iproc_sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp) -+{ -+ return sysfs_create_group(kobj, grp); -+} -+EXPORT_SYMBOL(iproc_sysfs_create_group); -+ -+ -+/** -+ * iproc_sysfs_remove_group - -+ * wrapper function for sysfs_remove_group -+ * @kobj: The kobject which the group is on -+ * @grp: The attribute group to remove -+ */ -+void iproc_sysfs_remove_group(struct kobject * kobj, const struct attribute_group * grp) -+{ -+ sysfs_remove_group(kobj, grp); -+} -+EXPORT_SYMBOL(iproc_sysfs_remove_group); -+ -+/** -+ * iproc__class_create - -+ * wrapper function for __class_create -+ * @ower: pointer to the module that is to "own" this struct class -+ * @name: pointer to a string for the name of this class. -+ * @key: the lock_class_key for this class; used by mutex lock debugging -+ */ -+struct class *iproc__class_create(struct module *owner, const char *name, -+ struct lock_class_key *key) -+{ -+ return __class_create(owner, name, key); -+} -+EXPORT_SYMBOL(iproc__class_create); -+ -+/** -+ * iproc_class_destroy - -+ * wrapper function for class_destroy -+ * @cls: pointer to the struct class that is to be destroyed -+ */ -+void iproc_class_destroy(struct class *cls) -+{ -+ class_destroy(cls); -+} -+EXPORT_SYMBOL(iproc_class_destroy); -+ -+/** -+ * iproc_device_create_file - -+ * wrapper function for device_create_file -+ * @dev: device. -+ * @attr: device attribute descriptor. -+ */ -+int iproc_device_create_file(struct device *dev, -+ const struct device_attribute *attr) -+{ -+ return device_create_file(dev, attr); -+} -+EXPORT_SYMBOL(iproc_device_create_file); -+ -+/** -+ * iproc_device_create - -+ * wrapper function for device_create -+ * -+ * @class: pointer to the struct class that this device should be -+ * registered to -+ * @parent: pointer to the parent struct device of this new device, if any -+ * @devt: the dev_t for the char device to be added -+ * @drvdata: the data to be added to the device for callbacks -+ * @fmt: string for the device's name -+ */ -+struct device *iproc_device_create(struct class *class, -+ struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...) -+{ -+ va_list args; -+ struct device *r; -+ -+ va_start(args, fmt); -+ r = device_create_vargs(class, parent, devt, drvdata, fmt, args); -+ va_end(args); -+ -+ return r; -+} -+EXPORT_SYMBOL(iproc_device_create); -+ -+/** -+ * iproc_device_destroy - -+ * wrapper function for device_destroy -+ * @class: pointer to the struct class that this device was registered with -+ * @devt: the dev_t of the device that was previously registered -+ */ -+void iproc_device_destroy(struct class *class, dev_t devt) -+{ -+ return device_destroy(class, devt); -+} -+EXPORT_SYMBOL(iproc_device_destroy); -+ -+/** -+ * proc_device_remove_file - -+ * wrapper function for device_remove_file -+ * @dev: device. -+ * @attr: device attribute descriptor. -+ */ -+void iproc_device_remove_file(struct device *dev, -+ const struct device_attribute *attr) -+{ -+ return device_remove_file(dev, attr); -+} -+EXPORT_SYMBOL(iproc_device_remove_file); -+ -+/** -+ * iproc_platform_get_irq_byname - -+ * wrapper function for platform_get_irq_byname -+ * @dev: platform device -+ * @name: IRQ name -+ */ -+int iproc_platform_get_irq_byname(struct platform_device *dev, const char *n) -+{ -+ return platform_get_irq_byname(dev,n); -+} -+EXPORT_SYMBOL(iproc_platform_get_irq_byname); -+ -+/** -+ * iproc_gpio_to_irq - -+ * wrapper function for gpio_to_irq -+ * @gpio: gpio whose IRQ will be returned (already requested) -+ */ -+int iproc_gpio_to_irq(unsigned gpio) -+{ -+ return gpio_to_irq(gpio); -+} -+EXPORT_SYMBOL(iproc_gpio_to_irq); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig ---- a/drivers/char/hw_random/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/char/hw_random/Kconfig 2017-11-09 17:53:25.197163000 +0800 -@@ -114,6 +114,18 @@ config HW_RANDOM_IPROC_RNG200 - - If unsure, say Y. - -+config HW_RANDOM_XGS_IPROC_RNG -+ tristate "Broadcom iProc RNG support" -+ depends on (ARCH_XGS_IPROC && HW_RANDOM) -+ ---help--- -+ This driver provides kernel-side support for the RNG -+ hardware found on the Broadcom iProc SoCs. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called iproc-rng -+ -+ If unsure, say Y. -+ - config HW_RANDOM_GEODE - tristate "AMD Geode HW Random Number Generator support" - depends on X86_32 && PCI -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile ---- a/drivers/char/hw_random/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/char/hw_random/Makefile 2017-11-09 17:53:25.198159000 +0800 -@@ -29,6 +29,7 @@ obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos - obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o - obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o - obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o -+obj-$(CONFIG_HW_RANDOM_XGS_IPROC_RNG) += xgs-iproc-rng200.o - obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o - obj-$(CONFIG_HW_RANDOM_ST) += st-rng.o - obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/char/hw_random/xgs-iproc-rng200.c b/drivers/char/hw_random/xgs-iproc-rng200.c ---- a/drivers/char/hw_random/xgs-iproc-rng200.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/char/hw_random/xgs-iproc-rng200.c 2017-11-09 17:53:25.250157000 +0800 -@@ -0,0 +1,442 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ */ -+ -+/* -+ * DESCRIPTION: The Broadcom iProc RNG200 Driver -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Registers for RNG */ -+#define RNG_CTRL_OFFSET 0x00000000 -+#define RNG_CTRL_RESERVED_MASK 0xF00000CC -+#define RNG_CTRL_COMBLK2_OSC_DIS_SHIFT 22 -+#define RNG_CTRL_COMBLK2_OSC_DIS_MASK 0x0FC00000 -+#define RNG_CTRL_COMBLK1_OSC_DIS_SHIFT 16 -+#define RNG_CTRL_COMBLK1_OSC_DIS_MASK 0x003F0000 -+#define RNG_CTRL_JCLK_BYP_DIV_CNT_SHIFT 8 -+#define RNG_CTRL_JCLK_BYP_DIV_CNT_MASK 0x0000FF00 -+#define RNG_CTRL_JCLK_BYP_SRC_SHIFT 5 -+#define RNG_CTRL_JCLK_BYP_SRC_MASK 0x00000020 -+#define RNG_CTRL_JCLK_BYP_SEL_SHIFT 4 -+#define RNG_CTRL_JCLK_BYP_SEL_MASK 0x00000010 -+#define RNG_CTRL_RBG2X_SHIFT 1 -+#define RNG_CTRL_RBG2X_MASK 0x00000002 -+#define RNG_CTRL_RBGEN_SHIFT 0 -+#define RNG_CTRL_RBGEN_MASK 0x00000001 -+ -+#define RNG_STATUS_OFFSET 0x00000004 -+#define RNG_STATUS_RESERVED_MASK 0x00F00000 -+#define RNG_STATUS_RND_VAL_SHIFT 24 -+#define RNG_STATUS_RND_VAL_MASK 0xFF000000 -+#define RNG_STATUS_WARM_CNT_SHIFT 0 -+#define RNG_STATUS_WARM_CNT_MASK 0x000FFFFF -+ -+#define RNG_DATA_OFFSET 0x00000008 -+#define RNG_DATA_RESERVED_MASK 0x00000000 -+#define RNG_DATA_RNG_NUM_SHIFT 0 -+#define RNG_DATA_RNG_NUM_MASK 0xFFFFFFFF -+ -+#define RNG_FF_THRES_OFFSET 0x0000000C -+#define RNG_FF_THRES_RESERVED_MASK 0xFFFFFFE0 -+#define RNG_FF_THRES_RNG_FF_THRESH_SHIFT 0 -+#define RNG_FF_THRES_RNG_FF_THRESH_MASK 0x0000001F -+ -+#define RNG_INT_MASK_OFFSET 0x00000010 -+#define RNG_INT_MASK_RESERVED_MASK 0xFFFFFFFE -+#define RNG_INT_MASK_OFF_SHIFT 0 -+#define RNG_INT_MASK_OFF_MASK 0x00000001 -+ -+/* Registers for RNG200*/ -+#define RNG200_CTRL_OFFSET 0x00 -+#define RNG200_CTRL_RBGEN_MASK 0x00001FFF -+#define RNG200_CTRL_RBGEN_ENABLE 0x00000001 -+#define RNG200_CTRL_RBGEN_DISABLE 0x00000000 -+ -+#define RNG200_SOFT_RESET_OFFSET 0x04 -+#define RNG200_SOFT_RESET_MASK 0x00000001 -+#define RNG200_SOFT_RESET_ACTIVE 0x00000001 -+#define RNG200_SOFT_RESET_CLEAR 0x00000000 -+ -+#define RBG_SOFT_RESET_OFFSET 0x08 -+#define RBG_RNG_SOFT_RESET_MASK 0x00000001 -+#define RBG_RNG_SOFT_RESET_ACTIVE 0x00000001 -+#define RBG_RNG_SOFT_RESET_CLEAR 0x00000000 -+ -+#define RNG200_INT_STATUS_OFFSET 0x18 -+#define RNG200_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK 0x80000000 -+#define RNG200_INT_STATUS_STARTUP_TRANSITIONS_MET_IRQ_MASK 0x00020000 -+#define RNG200_INT_STATUS_NIST_FAIL_IRQ_MASK 0x00000020 -+#define RNG200_INT_STATUS_TOTAL_BITS_COUNT_IRQ_MASK 0x00000001 -+ -+#define RNG200_FIFO_DATA_OFFSET 0x20 -+#define RNG200_FIFO_COUNT_OFFSET 0x24 -+#define RNG200_FIFO_COUNT_MASK 0x000000FF -+ -+static int rng_read(struct hwrng *rng, void *buf, size_t max, -+ bool wait) -+{ -+ u32 num_words = 0; -+ u32 num_remaining = max; -+ -+ #define MAX_IDLE_TIME (1 * HZ) -+ unsigned long idle_endtime = jiffies + MAX_IDLE_TIME; -+ -+ /* Retrieve HW RNG registers base address. */ -+ void __iomem *base_addr = (void __iomem *)rng->priv; -+ -+ while ((num_remaining > 0) && time_before(jiffies, idle_endtime)) { -+ /* Are there any random numbers available? */ -+ num_words = (ioread32(base_addr + RNG_STATUS_OFFSET) & -+ RNG_STATUS_RND_VAL_MASK) >> RNG_STATUS_RND_VAL_SHIFT; -+ if (num_words > 0) { -+ if (num_remaining >= sizeof(u32)) { -+ /* Buffer has room to store entire word */ -+ *(u32 *)buf = ioread32(base_addr + -+ RNG_DATA_OFFSET); -+ buf += sizeof(u32); -+ num_remaining -= sizeof(u32); -+ } else { -+ /* Buffer can only store partial word */ -+ u32 rnd_number = ioread32(base_addr + -+ RNG_DATA_OFFSET); -+ memcpy(buf, &rnd_number, num_remaining); -+ buf += num_remaining; -+ num_remaining = 0; -+ } -+ -+ /* Reset the IDLE timeout */ -+ idle_endtime = jiffies + MAX_IDLE_TIME; -+ } else if (!wait) { -+ /* Cannot wait, return immediately */ -+ break; -+ } else { -+ /* Can wait, give others chance to run */ -+ cpu_relax(); -+ } -+ } -+ -+ return max - num_remaining; -+} -+ -+static struct hwrng rng_ops = { -+ .name = "iproc-rng", -+ .read = rng_read, -+}; -+ -+static int rng_probe(struct platform_device *pdev) -+{ -+ int error; -+ u32 val; -+ struct device *dev = &pdev->dev; -+ void __iomem *base_addr; -+ struct device_node *node; -+ -+ pr_info("Broadcom IPROC RNG Driver\n"); -+ /* We only accept one device, and it must have an id of -1 */ -+ if (pdev->id != -1) -+ return -ENODEV; -+ -+ node = pdev->dev.of_node; -+ base_addr = of_iomap(node, 0); -+ if (!base_addr) { -+ dev_err(&pdev->dev, "can't iomap base_addr for rng\n"); -+ return -EIO; -+ } -+ rng_ops.priv = (unsigned long)base_addr; -+ -+ /* Start RNG block */ -+ val = ioread32(base_addr + RNG_CTRL_OFFSET); -+ val |= RNG_CTRL_RBGEN_MASK; -+ iowrite32(val, base_addr + RNG_CTRL_OFFSET); -+ -+ /* Enable RNG RBG2X */ -+ val = ioread32(base_addr + RNG_CTRL_OFFSET); -+ val |= RNG_CTRL_RBG2X_MASK; -+ iowrite32(val, base_addr + RNG_CTRL_OFFSET); -+ -+ /* Disable RNG INTERRUPT */ -+ val = ioread32(base_addr + RNG_INT_MASK_OFFSET); -+ val |= RNG_INT_MASK_OFF_MASK; -+ iowrite32(val, base_addr + RNG_INT_MASK_OFFSET); -+ -+ /* set warmup cycle 0xfff */ -+ iowrite32(RNG_STATUS_WARM_CNT_MASK - -+ (0xfff & RNG_STATUS_WARM_CNT_MASK), -+ base_addr + RNG_STATUS_OFFSET); -+ while ((ioread32(base_addr + RNG_STATUS_OFFSET) & -+ RNG_STATUS_WARM_CNT_MASK) != RNG_STATUS_WARM_CNT_MASK) -+ cpu_relax(); -+ -+ /* register to the Linux RNG framework */ -+ error = hwrng_register(&rng_ops); -+ if (error) { -+ dev_err(dev, "hwrng registration failed\n"); -+ iounmap(base_addr); -+ return error; -+ } -+ dev_dbg(dev, "hwrng registered\n"); -+ -+ return 0; -+} -+ -+static int rng_remove(struct platform_device *pdev) -+{ -+ u32 val; -+ void __iomem *base_addr = (void __iomem *)rng_ops.priv; -+ /* Unregister driver */ -+ hwrng_unregister(&rng_ops); -+ -+ if (base_addr) { -+ /* Disable RNG hardware */ -+ val = ioread32(base_addr + RNG_CTRL_OFFSET); -+ val &= ~RNG_CTRL_RBGEN_MASK; -+ iowrite32(val, base_addr + RNG_CTRL_OFFSET); -+ -+ val = ioread32(base_addr + RNG_CTRL_OFFSET); -+ val &= ~RNG_CTRL_RBG2X_MASK; -+ iowrite32(val, base_addr + RNG_CTRL_OFFSET); -+ -+ iounmap(base_addr); -+ } -+ -+ return 0; -+} -+ -+static void iproc_rng200_restart(void __iomem *rng_base) -+{ -+ u32 val; -+ -+ /* Disable RBG */ -+ val = ioread32(rng_base + RNG200_CTRL_OFFSET); -+ val &= ~RNG200_CTRL_RBGEN_MASK; -+ val |= RNG200_CTRL_RBGEN_DISABLE; -+ iowrite32(val, rng_base + RNG200_CTRL_OFFSET); -+ -+ /* Clear all interrupt status */ -+ iowrite32(0xFFFFFFFFUL, rng_base + RNG200_INT_STATUS_OFFSET); -+ -+ /* Reset RNG and RBG */ -+ val = ioread32(rng_base + RBG_SOFT_RESET_OFFSET); -+ val &= ~RBG_RNG_SOFT_RESET_MASK; -+ val |= RBG_RNG_SOFT_RESET_ACTIVE; -+ iowrite32(val, rng_base + RBG_SOFT_RESET_OFFSET); -+ -+ val = ioread32(rng_base + RNG200_SOFT_RESET_OFFSET); -+ val &= ~RNG200_SOFT_RESET_MASK; -+ val |= RNG200_SOFT_RESET_ACTIVE; -+ iowrite32(val, rng_base + RNG200_SOFT_RESET_OFFSET); -+ -+ val = ioread32(rng_base + RNG200_SOFT_RESET_OFFSET); -+ val &= ~RNG200_SOFT_RESET_MASK; -+ val |= RNG200_SOFT_RESET_CLEAR; -+ iowrite32(val, rng_base + RNG200_SOFT_RESET_OFFSET); -+ -+ val = ioread32(rng_base + RBG_SOFT_RESET_OFFSET); -+ val &= ~RBG_RNG_SOFT_RESET_MASK; -+ val |= RBG_RNG_SOFT_RESET_CLEAR; -+ iowrite32(val, rng_base + RBG_SOFT_RESET_OFFSET); -+ -+ /* Enable RBG */ -+ val = ioread32(rng_base + RNG200_CTRL_OFFSET); -+ val &= ~RNG200_CTRL_RBGEN_MASK; -+ val |= RNG200_CTRL_RBGEN_ENABLE; -+ iowrite32(val, rng_base + RNG200_CTRL_OFFSET); -+} -+ -+static int iproc_rng200_read(struct hwrng *rng, void *buf, size_t max, -+ bool wait) -+{ -+ u32 status; -+ u32 rng_fifo; -+ u32 num_remaining = max; -+ -+ #define MAX_RESETS_PER_READ 1 -+ u32 num_resets = 0; -+ -+ #define MAX_IDLE_TIME (1 * HZ) -+ unsigned long idle_endtime = jiffies + MAX_IDLE_TIME; -+ -+ /* Retrieve HW RNG registers base address. */ -+ void __iomem *rng_base = (void __iomem *)rng->priv; -+ -+ while ((num_remaining > 0) && time_before(jiffies, idle_endtime)) { -+ -+ /* Is RNG sane? If not, reset it. */ -+ status = ioread32(rng_base + RNG200_INT_STATUS_OFFSET); -+ if ((status & (RNG200_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK | -+ RNG200_INT_STATUS_NIST_FAIL_IRQ_MASK)) != 0) { -+ -+ if (num_resets >= MAX_RESETS_PER_READ) -+ return max - num_remaining; -+ -+ iproc_rng200_restart(rng_base); -+ num_resets++; -+ } -+ -+ /* Are there any random numbers available? */ -+ rng_fifo = ioread32(rng_base + RNG200_FIFO_COUNT_OFFSET); -+ if ((rng_fifo & RNG200_FIFO_COUNT_MASK) > 0) { -+ -+ if (num_remaining >= sizeof(u32)) { -+ /* Buffer has room to store entire word */ -+ *(u32 *)buf = ioread32(rng_base + -+ RNG200_FIFO_DATA_OFFSET); -+ buf += sizeof(u32); -+ num_remaining -= sizeof(u32); -+ } else { -+ /* Buffer can only store partial word */ -+ u32 rnd_number = ioread32(rng_base + -+ RNG200_FIFO_DATA_OFFSET); -+ memcpy(buf, &rnd_number, num_remaining); -+ buf += num_remaining; -+ num_remaining = 0; -+ } -+ -+ /* Reset the IDLE timeout */ -+ idle_endtime = jiffies + MAX_IDLE_TIME; -+ } else { -+ if (!wait) -+ /* Cannot wait, return immediately */ -+ break; -+ -+ /* Can wait, give others chance to run */ -+ cpu_relax(); -+ } -+ } -+ -+ return max - num_remaining; -+} -+ -+static struct hwrng iproc_rng200_ops = { -+ .name = "iproc-rng200", -+ .read = iproc_rng200_read, -+}; -+ -+static int iproc_rng200_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ void __iomem *rng_base; -+ struct resource *res; -+ u32 val; -+ int err; -+ -+ pr_info("Broadcom IPROC RNG200 Driver\n"); -+ /* Map peripheral */ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(dev, "failed to get rng resources"); -+ return -ENODEV; -+ } -+ -+ rng_base = devm_ioremap_resource(dev, res); -+ //rng_base = ioremap(res->start, res->end - res->start); -+ if (!rng_base) { -+ dev_err(dev, "failed to remap rng regs"); -+ return -ENODEV; -+ } -+ -+ iproc_rng200_ops.priv = (unsigned long)rng_base; -+ -+ /* Setup RNG. */ -+ val = ioread32(rng_base + RNG200_CTRL_OFFSET); -+ val &= ~RNG200_CTRL_RBGEN_MASK; -+ val |= RNG200_CTRL_RBGEN_ENABLE; -+ iowrite32(val, rng_base + RNG200_CTRL_OFFSET); -+ -+ /* Register driver */ -+ err = hwrng_register(&iproc_rng200_ops); -+ if (err) { -+ dev_err(dev, "hwrng registration failed\n"); -+ return err; -+ } -+ dev_dbg(dev, "hwrng registered\n"); -+ -+ return 0; -+} -+ -+static int iproc_rng200_remove(struct platform_device *pdev) -+{ -+ u32 val; -+ void __iomem *rng_base = (void __iomem *)iproc_rng200_ops.priv; -+ -+ /* Unregister driver */ -+ hwrng_unregister(&iproc_rng200_ops); -+ if (rng_base) { -+ /* Disable RNG hardware */ -+ val = ioread32(rng_base + RNG200_CTRL_OFFSET); -+ val &= ~RNG200_CTRL_RBGEN_MASK; -+ val |= RNG200_CTRL_RBGEN_DISABLE; -+ iowrite32(val, rng_base + RNG200_CTRL_OFFSET); -+ } -+ return 0; -+} -+static int rng_probe_gen(struct platform_device *pdev) -+{ -+ int ret = -ENODEV; -+ struct device_node *node; -+ const char *rng_name; -+ node = pdev->dev.of_node; -+ rng_name = node->name; -+ -+ if (!of_device_is_available(node)) -+ return -ENODEV; -+ -+ of_property_read_string(node, "rng-type", &rng_name); -+ if (strcmp(rng_name, "rng200") == 0) -+ ret = iproc_rng200_probe(pdev); -+ else if (strcmp(rng_name, "rng") == 0) -+ ret = rng_probe(pdev); -+ -+ return ret; -+} -+ -+static int rng_remove_gen(struct platform_device *pdev) -+{ -+ int ret = -ENODEV; -+ struct device_node *node; -+ const char *rng_name; -+ node = pdev->dev.of_node; -+ rng_name = node->name; -+ -+ if (!of_device_is_available(node)) -+ return -ENODEV; -+ -+ of_property_read_string(node, "rng-type", &rng_name); -+ if (strcmp(rng_name, "rng200") == 0) -+ ret = iproc_rng200_remove(pdev); -+ else if (strcmp(rng_name, "rng") == 0) -+ ret = rng_remove(pdev); -+ -+ return ret; -+} -+ -+static const struct of_device_id bcm_iproc_dt_ids[] = { -+ { .compatible = "brcm,iproc-rng"}, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, bcm_iproc_dt_ids); -+ -+static struct platform_driver iproc_rng_driver = { -+ .driver = { -+ .name = "iproc-rng", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(bcm_iproc_dt_ids), -+ }, -+ .probe = rng_probe_gen, -+ .remove = rng_remove_gen, -+}; -+module_platform_driver(iproc_rng_driver); -+ -+MODULE_AUTHOR("Broadcom"); -+MODULE_DESCRIPTION("iProc RNG/RNG200 Random Number Generator driver"); -+MODULE_LICENSE("GPL v2"); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig ---- a/drivers/clk/bcm/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/clk/bcm/Kconfig 2017-11-09 17:53:25.478158000 +0800 -@@ -14,3 +14,15 @@ config COMMON_CLK_IPROC - help - Enable common clock framework support for Broadcom SoCs - based on the iProc architecture -+ -+config CLK_XGS_IPROC -+ bool "BRCM XGS iProc clock support" -+ depends on COMMON_CLK && ARCH_XGS_IPROC -+ select COMMON_CLK_IPROC -+ default ARCH_XGS_IPROC -+ help -+ Enable XGS iProc clock -+ -+ -+ -+ -\ No newline at end of file -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile ---- a/drivers/clk/bcm/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/clk/bcm/Makefile 2017-11-09 17:53:25.479153000 +0800 -@@ -8,3 +8,4 @@ obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns - obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o - obj-$(CONFIG_ARCH_BCM_NSP) += clk-nsp.o - obj-$(CONFIG_ARCH_BCM_5301X) += clk-nsp.o -+obj-$(CONFIG_CLK_XGS_IPROC) += clk-xgs-iproc.o -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/clk/bcm/clk-iproc-armpll.c b/drivers/clk/bcm/clk-iproc-armpll.c ---- a/drivers/clk/bcm/clk-iproc-armpll.c 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/clk/bcm/clk-iproc-armpll.c 2017-11-09 17:53:25.494157000 +0800 -@@ -224,8 +224,10 @@ static unsigned long iproc_arm_pll_recal - pll->rate = 0; - return 0; - } -+ -+ /* To avoid pll->rate overflow, do divide before multiply */ -+ parent_rate = (parent_rate / pdiv) / mdiv; - pll->rate = (ndiv * parent_rate) >> 20; -- pll->rate = (pll->rate / pdiv) / mdiv; - - pr_debug("%s: ARM PLL rate: %lu. parent rate: %lu\n", __func__, - pll->rate, parent_rate); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/clk/bcm/clk-xgs-iproc.c b/drivers/clk/bcm/clk-xgs-iproc.c ---- a/drivers/clk/bcm/clk-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/clk/bcm/clk-xgs-iproc.c 2017-11-09 17:53:25.512166000 +0800 -@@ -0,0 +1,170 @@ -+/* -+ * Copyright (C) 2014 Broadcom Corporation -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "clk-iproc.h" -+ -+#define SB2_GEN_PLL_CTRL_1_OFFSET 0x04 -+#define SB2_GEN_PLL_CTRL_3_OFFSET 0x0C -+#define SB2_GEN_PLL_CTRL_5_OFFSET 0x14 -+#define SB2_GEN_PLL_CTRL_1_PDIV_R 27 -+#define SB2_GEN_PLL_CTRL_3_NDIV_INT_R 20 -+#define SB2_GEN_PLL_CTRL_5_CH1_MDIV_R 8 -+#define SB2_GEN_PLL_CTRL_1_PDIV_WIDTH 4 -+#define SB2_GEN_PLL_CTRL_3_NDIV_INT_WIDTH 10 -+#define SB2_GEN_PLL_CTRL_5_CH1_MDIV_WIDTH 8 -+ -+#define GEN_PLL_CTRL1_OFFSET 0x4 -+#define GEN_PLL_CTRL2_OFFSET 0x8 -+#define GEN_PLL_CTRL1_NDIV_INT_R 0 -+#define GEN_PLL_CTRL1_NDIV_INT_WIDTH 10 -+#define GEN_PLL_CTRL1_PDIV_R 10 -+#define GEN_PLL_CTRL2_CH3_MDIV_R 8 -+#define GEN_PLL_CTRL2_CH3_MDIV_WIDTH 8 -+#define GEN_PLL_CTRL1_PDIV_WIDTH_3 3 -+#define GEN_PLL_CTRL1_PDIV_WIDTH_4 4 -+ -+ -+struct iproc_gen_pll { -+ struct clk_hw hw; -+ void __iomem *base; -+ unsigned long rate; -+}; -+ -+#define to_iproc_gen_pll(phw) container_of(phw, struct iproc_gen_pll, hw) -+ -+static u32 genpll_pdiv_width; -+ -+static unsigned long iproc_axi_clk_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ uint32_t ndiv, mdiv, pdiv; -+ struct iproc_gen_pll *pll = to_iproc_gen_pll(hw); -+ -+ -+ ndiv = readl(pll->base + GEN_PLL_CTRL1_OFFSET) >> -+ GEN_PLL_CTRL1_NDIV_INT_R; -+ ndiv &= (1 << GEN_PLL_CTRL1_NDIV_INT_WIDTH) - 1; -+ if (ndiv == 0) -+ ndiv = 1 << GEN_PLL_CTRL1_NDIV_INT_WIDTH; -+ -+ pdiv = readl(pll->base + GEN_PLL_CTRL1_OFFSET) >> GEN_PLL_CTRL1_PDIV_R; -+ pdiv &= (1 << genpll_pdiv_width) -1; -+ if (pdiv == 0) -+ pdiv = 1 << genpll_pdiv_width; -+ -+ mdiv = readl(pll->base + GEN_PLL_CTRL2_OFFSET) >> -+ GEN_PLL_CTRL2_CH3_MDIV_R; -+ mdiv &= (1 << GEN_PLL_CTRL2_CH3_MDIV_WIDTH) - 1; -+ if (mdiv == 0) -+ mdiv = 1 << GEN_PLL_CTRL2_CH3_MDIV_WIDTH; -+ -+ pll->rate = parent_rate * ndiv / pdiv / mdiv; -+ return pll->rate; -+} -+ -+static unsigned long iproc_sb2_axi_clk_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ uint32_t ndiv, mdiv, pdiv; -+ struct iproc_gen_pll *pll = to_iproc_gen_pll(hw); -+ -+ ndiv = readl(pll->base + SB2_GEN_PLL_CTRL_3_OFFSET) >> -+ SB2_GEN_PLL_CTRL_3_NDIV_INT_R; -+ ndiv &= (1 << SB2_GEN_PLL_CTRL_3_NDIV_INT_WIDTH) - 1; -+ -+ mdiv = readl(pll->base + SB2_GEN_PLL_CTRL_5_OFFSET) >> -+ SB2_GEN_PLL_CTRL_5_CH1_MDIV_R; -+ mdiv &= (1 << SB2_GEN_PLL_CTRL_5_CH1_MDIV_WIDTH) - 1; -+ -+ pdiv = readl(pll->base + SB2_GEN_PLL_CTRL_1_OFFSET) >> -+ SB2_GEN_PLL_CTRL_1_PDIV_R; -+ pdiv &= (1 << SB2_GEN_PLL_CTRL_1_PDIV_WIDTH) - 1; -+ -+ pll->rate = parent_rate * ndiv / pdiv / mdiv; -+ return pll->rate; -+} -+ -+ -+static struct clk_ops iproc_axi_clk_ops = { -+ .recalc_rate = iproc_axi_clk_recalc_rate, -+}; -+ -+void __init xgs_iproc_axi_clk_setup(struct device_node *node) -+{ -+ int ret; -+ struct clk *clk; -+ struct iproc_gen_pll *pll; -+ struct clk_init_data init; -+ const char *parent_name; -+ -+ pll = kzalloc(sizeof(*pll), GFP_KERNEL); -+ if (WARN_ON(!pll)) -+ return; -+ -+ pll->base = of_iomap(node, 0); -+ if (WARN_ON(!pll->base)) -+ goto err_free_pll; -+ -+ init.name = node->name; -+ if ( of_device_is_compatible(node, "axi-clk-sb2") ) -+ iproc_axi_clk_ops.recalc_rate = iproc_sb2_axi_clk_recalc_rate; -+ if ( of_device_is_compatible(node, "axi-clk-hx4") || -+ of_device_is_compatible(node, "axi-clk-hr2") ) -+ genpll_pdiv_width = GEN_PLL_CTRL1_PDIV_WIDTH_3; -+ else -+ genpll_pdiv_width = GEN_PLL_CTRL1_PDIV_WIDTH_4; -+ -+ init.ops = &iproc_axi_clk_ops; -+ init.flags = 0; -+ parent_name = of_clk_get_parent_name(node, 0); -+ init.parent_names = (parent_name ? &parent_name : NULL); -+ init.num_parents = (parent_name ? 1 : 0); -+ pll->hw.init = &init; -+ -+ clk = clk_register(NULL, &pll->hw); -+ if (WARN_ON(IS_ERR(clk))) -+ goto err_iounmap; -+ -+ ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); -+ if (WARN_ON(ret)) -+ goto err_clk_unregister; -+ -+ return; -+ -+err_clk_unregister: -+ clk_unregister(clk); -+err_iounmap: -+ iounmap(pll->base); -+err_free_pll: -+ kfree(pll); -+} -+ -+CLK_OF_DECLARE(xgs_iproc_axi_clk, "brcm,xgs-iproc-axi-clk", -+ xgs_iproc_axi_clk_setup); -+ -+ -+static void __init xgs_iproc_armpll_init(struct device_node *node) -+{ -+ iproc_armpll_setup(node); -+} -+CLK_OF_DECLARE(xgs_iproc_armpll, "brcm,xgs-iproc-armpll", -+ xgs_iproc_armpll_init); -\ No newline at end of file -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/dma/Kconfig b/drivers/dma/Kconfig ---- a/drivers/dma/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/dma/Kconfig 2017-11-09 17:53:27.047177000 +0800 -@@ -397,6 +397,14 @@ config PL330_DMA - You need to provide platform specific settings via - platform_data for a dma-pl330 device. - -+config XGS_IPROC_DMA330_DMA -+ tristate "DMA API Driver for XGS IPROC DMA330" -+ select DMA_ENGINE -+ depends on ARM_AMBA -+ help -+ Support the DMA engine for BRCM IPROC CoreLink -+ DMA Controller (DMA-330). -+ - config PXA_DMA - bool "PXA DMA support" - depends on (ARCH_MMP || ARCH_PXA) -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/dma/Makefile b/drivers/dma/Makefile ---- a/drivers/dma/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/dma/Makefile 2017-11-09 17:53:27.048171000 +0800 -@@ -50,6 +50,7 @@ obj-$(CONFIG_MX3_IPU) += ipu/ - obj-$(CONFIG_NBPFAXI_DMA) += nbpfaxi.o - obj-$(CONFIG_PCH_DMA) += pch_dma.o - obj-$(CONFIG_PL330_DMA) += pl330.o -+obj-$(CONFIG_XGS_IPROC_DMA330_DMA) += iproc-dma330.o - obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/ - obj-$(CONFIG_PXA_DMA) += pxa_dma.o - obj-$(CONFIG_QCOM_BAM_DMA) += qcom_bam_dma.o -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/dma/iproc-dma330.c b/drivers/dma/iproc-dma330.c ---- a/drivers/dma/iproc-dma330.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/dma/iproc-dma330.c 2017-11-09 17:53:27.192174000 +0800 -@@ -0,0 +1,3067 @@ -+/* -+ * BRCM IPROC DMA330 support -+ * -+ * This driver, modified from pl330.c, supports CoreLink DMA Controller -+ * (DMA-330). -+ * -+ * Copyright (C) 2016 Broadcom Corporation -+ * -+ * Copyright (C) 2010 Samsung Electronics Co. Ltd. -+ * Jaswinder Singh -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dmaengine.h" -+#define DMA330_MAX_CHAN 8 -+#define DMA330_MAX_IRQS 32 -+#define DMA330_MAX_PERI 32 -+ -+struct dma_dma330_platdata { -+ u8 nr_valid_peri; -+ u8 *peri_id; -+ dma_cap_mask_t cap_mask; -+ unsigned mcbuf_sz; -+}; -+ -+enum dma330_cachectrl { -+ CCTRL0, /* Noncacheable and nonbufferable */ -+ CCTRL1, /* Bufferable only */ -+ CCTRL2, /* Cacheable, but do not allocate */ -+ CCTRL3, /* Cacheable and bufferable, but do not allocate */ -+ INVALID1, /* AWCACHE = 0x1000 */ -+ INVALID2, -+ CCTRL6, /* Cacheable write-through, allocate on writes only */ -+ CCTRL7, /* Cacheable write-back, allocate on writes only */ -+}; -+ -+enum dma330_byteswap { -+ SWAP_NO, -+ SWAP_2, -+ SWAP_4, -+ SWAP_8, -+ SWAP_16, -+}; -+ -+/* Register and Bit field Definitions */ -+#define DS 0x0 -+#define DS_ST_STOP 0x0 -+#define DS_ST_EXEC 0x1 -+#define DS_ST_CMISS 0x2 -+#define DS_ST_UPDTPC 0x3 -+#define DS_ST_WFE 0x4 -+#define DS_ST_ATBRR 0x5 -+#define DS_ST_QBUSY 0x6 -+#define DS_ST_WFP 0x7 -+#define DS_ST_KILL 0x8 -+#define DS_ST_CMPLT 0x9 -+#define DS_ST_FLTCMP 0xe -+#define DS_ST_FAULT 0xf -+ -+#define DPC 0x4 -+#define INTEN 0x20 -+#define ES 0x24 -+#define INTSTATUS 0x28 -+#define INTCLR 0x2c -+#define FSM 0x30 -+#define FSC 0x34 -+#define FTM 0x38 -+ -+#define _FTC 0x40 -+#define FTC(n) (_FTC + (n)*0x4) -+ -+#define _CS 0x100 -+#define CS(n) (_CS + (n)*0x8) -+#define CS_CNS (1 << 21) -+ -+#define _CPC 0x104 -+#define CPC(n) (_CPC + (n)*0x8) -+ -+#define _SA 0x400 -+#define SA(n) (_SA + (n)*0x20) -+ -+#define _DA 0x404 -+#define DA(n) (_DA + (n)*0x20) -+ -+#define _CC 0x408 -+#define CC(n) (_CC + (n)*0x20) -+ -+#define CC_SRCINC (1 << 0) -+#define CC_DSTINC (1 << 14) -+#define CC_SRCPRI (1 << 8) -+#define CC_DSTPRI (1 << 22) -+#define CC_SRCNS (1 << 9) -+#define CC_DSTNS (1 << 23) -+#define CC_SRCIA (1 << 10) -+#define CC_DSTIA (1 << 24) -+#define CC_SRCBRSTLEN_SHFT 4 -+#define CC_DSTBRSTLEN_SHFT 18 -+#define CC_SRCBRSTSIZE_SHFT 1 -+#define CC_DSTBRSTSIZE_SHFT 15 -+#define CC_SRCCCTRL_SHFT 11 -+#define CC_SRCCCTRL_MASK 0x7 -+#define CC_DSTCCTRL_SHFT 25 -+#define CC_DRCCCTRL_MASK 0x7 -+#define CC_SWAP_SHFT 28 -+ -+#define _LC0 0x40c -+#define LC0(n) (_LC0 + (n)*0x20) -+ -+#define _LC1 0x410 -+#define LC1(n) (_LC1 + (n)*0x20) -+ -+#define DBGSTATUS 0xd00 -+#define DBG_BUSY (1 << 0) -+ -+#define DBGCMD 0xd04 -+#define DBGINST0 0xd08 -+#define DBGINST1 0xd0c -+ -+#define CR0 0xe00 -+#define CR1 0xe04 -+#define CR2 0xe08 -+#define CR3 0xe0c -+#define CR4 0xe10 -+#define CRD 0xe14 -+ -+#define PERIPH_ID 0xfe0 -+#define PERIPH_REV_SHIFT 20 -+#define PERIPH_REV_MASK 0xf -+#define PERIPH_REV_R0P0 0 -+#define PERIPH_REV_R1P0 1 -+#define PERIPH_REV_R1P1 2 -+ -+#define CR0_PERIPH_REQ_SET (1 << 0) -+#define CR0_BOOT_EN_SET (1 << 1) -+#define CR0_BOOT_MAN_NS (1 << 2) -+#define CR0_NUM_CHANS_SHIFT 4 -+#define CR0_NUM_CHANS_MASK 0x7 -+#define CR0_NUM_PERIPH_SHIFT 12 -+#define CR0_NUM_PERIPH_MASK 0x1f -+#define CR0_NUM_EVENTS_SHIFT 17 -+#define CR0_NUM_EVENTS_MASK 0x1f -+ -+#define CR1_ICACHE_LEN_SHIFT 0 -+#define CR1_ICACHE_LEN_MASK 0x7 -+#define CR1_NUM_ICACHELINES_SHIFT 4 -+#define CR1_NUM_ICACHELINES_MASK 0xf -+ -+#define CRD_DATA_WIDTH_SHIFT 0 -+#define CRD_DATA_WIDTH_MASK 0x7 -+#define CRD_WR_CAP_SHIFT 4 -+#define CRD_WR_CAP_MASK 0x7 -+#define CRD_WR_Q_DEP_SHIFT 8 -+#define CRD_WR_Q_DEP_MASK 0xf -+#define CRD_RD_CAP_SHIFT 12 -+#define CRD_RD_CAP_MASK 0x7 -+#define CRD_RD_Q_DEP_SHIFT 16 -+#define CRD_RD_Q_DEP_MASK 0xf -+#define CRD_DATA_BUFF_SHIFT 20 -+#define CRD_DATA_BUFF_MASK 0x3ff -+ -+#define PART 0x330 -+#define DESIGNER 0x41 -+#define REVISION 0x2 -+#define INTEG_CFG 0x0 -+#define PERIPH_ID_VAL ((PART << 0) | (DESIGNER << 12) | (REVISION << 20)) -+ -+#define DMA330_STATE_STOPPED (1 << 0) -+#define DMA330_STATE_EXECUTING (1 << 1) -+#define DMA330_STATE_WFE (1 << 2) -+#define DMA330_STATE_FAULTING (1 << 3) -+#define DMA330_STATE_COMPLETING (1 << 4) -+#define DMA330_STATE_WFP (1 << 5) -+#define DMA330_STATE_KILLING (1 << 6) -+#define DMA330_STATE_FAULT_COMPLETING (1 << 7) -+#define DMA330_STATE_CACHEMISS (1 << 8) -+#define DMA330_STATE_UPDTPC (1 << 9) -+#define DMA330_STATE_ATBARRIER (1 << 10) -+#define DMA330_STATE_QUEUEBUSY (1 << 11) -+#define DMA330_STATE_INVALID (1 << 15) -+ -+#define DMA330_STABLE_STATES (DMA330_STATE_STOPPED | DMA330_STATE_EXECUTING \ -+ | DMA330_STATE_WFE | DMA330_STATE_FAULTING) -+ -+#define CMD_DMAADDH 0x54 -+#define CMD_DMAEND 0x00 -+#define CMD_DMAFLUSHP 0x35 -+#define CMD_DMAGO 0xa0 -+#define CMD_DMALD 0x04 -+#define CMD_DMALDP 0x25 -+#define CMD_DMALP 0x20 -+#define CMD_DMALPEND 0x28 -+#define CMD_DMAKILL 0x01 -+#define CMD_DMAMOV 0xbc -+#define CMD_DMANOP 0x18 -+#define CMD_DMARMB 0x12 -+#define CMD_DMASEV 0x34 -+#define CMD_DMAST 0x08 -+#define CMD_DMASTP 0x29 -+#define CMD_DMASTZ 0x0c -+#define CMD_DMAWFE 0x36 -+#define CMD_DMAWFP 0x30 -+#define CMD_DMAWMB 0x13 -+ -+#define SZ_DMAADDH 3 -+#define SZ_DMAEND 1 -+#define SZ_DMAFLUSHP 2 -+#define SZ_DMALD 1 -+#define SZ_DMALDP 2 -+#define SZ_DMALP 2 -+#define SZ_DMALPEND 2 -+#define SZ_DMAKILL 1 -+#define SZ_DMAMOV 6 -+#define SZ_DMANOP 1 -+#define SZ_DMARMB 1 -+#define SZ_DMASEV 2 -+#define SZ_DMAST 1 -+#define SZ_DMASTP 2 -+#define SZ_DMASTZ 1 -+#define SZ_DMAWFE 2 -+#define SZ_DMAWFP 2 -+#define SZ_DMAWMB 1 -+#define SZ_DMAGO 6 -+ -+#define BRST_LEN(ccr) ((((ccr) >> CC_SRCBRSTLEN_SHFT) & 0xf) + 1) -+#define BRST_SIZE(ccr) (1 << (((ccr) >> CC_SRCBRSTSIZE_SHFT) & 0x7)) -+ -+#define BYTE_TO_BURST(b, ccr) ((b) / BRST_SIZE(ccr) / BRST_LEN(ccr)) -+#define BURST_TO_BYTE(c, ccr) ((c) * BRST_SIZE(ccr) * BRST_LEN(ccr)) -+ -+/* -+ * With 256 bytes, we can do more than 2.5MB and 5MB xfers per req -+ * at 1byte/burst for P<->M and M<->M respectively. -+ * For typical scenario, at 1word/burst, 10MB and 20MB xfers per req -+ * should be enough for P<->M and M<->M respectively. -+ */ -+#define MCODE_BUFF_PER_REQ 256 -+ -+/* Use this _only_ to wait on transient states */ -+#define UNTIL(t, s) while (!(_state(t) & (s))) cpu_relax(); -+ -+#ifdef DMA330_DEBUG_MCGEN -+static unsigned cmd_line; -+#define DMA330_DBGCMD_DUMP(off, x...) do { \ -+ printk("%x:", cmd_line); \ -+ printk(x); \ -+ cmd_line += off; \ -+ } while (0) -+#define DMA330_DBGMC_START(addr) (cmd_line = addr) -+#else -+#define DMA330_DBGCMD_DUMP(off, x...) do {} while (0) -+#define DMA330_DBGMC_START(addr) do {} while (0) -+#endif -+ -+/* The number of default descriptors */ -+ -+#define NR_DEFAULT_DESC 16 -+ -+/* Delay for runtime PM autosuspend, ms */ -+#define DMA330_AUTOSUSPEND_DELAY 20 -+ -+/* Populated by the DMA330 core driver for DMA API driver's info */ -+struct dma330_config { -+ u32 periph_id; -+#define DMAC_MODE_NS (1 << 0) -+ unsigned int mode; -+ unsigned int data_bus_width:10; /* In number of bits */ -+ unsigned int data_buf_dep:11; -+ unsigned int num_chan:4; -+ unsigned int num_peri:6; -+ u32 peri_ns; -+ unsigned int num_events:6; -+ u32 irq_ns; -+}; -+ -+/** -+ * Request Configuration. -+ * The DMA330 core does not modify this and uses the last -+ * working configuration if the request doesn't provide any. -+ * -+ * The Client may want to provide this info only for the -+ * first request and a request with new settings. -+ */ -+struct dma330_reqcfg { -+ /* Address Incrementing */ -+ unsigned dst_inc:1; -+ unsigned src_inc:1; -+ -+ /* -+ * For now, the SRC & DST protection levels -+ * and burst size/length are assumed same. -+ */ -+ bool nonsecure; -+ bool privileged; -+ bool insnaccess; -+ unsigned brst_len:5; -+ unsigned brst_size:3; /* in power of 2 */ -+ -+ enum dma330_cachectrl dcctl; -+ enum dma330_cachectrl scctl; -+ enum dma330_byteswap swap; -+ struct dma330_config *pcfg; -+}; -+ -+/* -+ * One cycle of DMAC operation. -+ * There may be more than one xfer in a request. -+ */ -+struct dma330_xfer { -+ u32 src_addr; -+ u32 dst_addr; -+ /* Size to xfer */ -+ u32 bytes; -+}; -+ -+/* The xfer callbacks are made with one of these arguments. */ -+enum dma330_op_err { -+ /* The all xfers in the request were success. */ -+ DMA330_ERR_NONE, -+ /* If req aborted due to global error. */ -+ DMA330_ERR_ABORT, -+ /* If req failed due to problem with Channel. */ -+ DMA330_ERR_FAIL, -+}; -+ -+enum dmamov_dst { -+ SAR = 0, -+ CCR, -+ DAR, -+}; -+ -+enum dma330_dst { -+ SRC = 0, -+ DST, -+}; -+ -+enum dma330_cond { -+ SINGLE, -+ BURST, -+ ALWAYS, -+}; -+ -+struct dma_dma330_desc; -+ -+struct _dma330_req { -+ u32 mc_bus; -+ void *mc_cpu; -+ struct dma_dma330_desc *desc; -+}; -+ -+/* ToBeDone for tasklet */ -+struct _dma330_tbd { -+ bool reset_dmac; -+ bool reset_mngr; -+ u8 reset_chan; -+}; -+ -+/* A DMAC Thread */ -+struct dma330_thread { -+ u8 id; -+ int ev; -+ /* If the channel is not yet acquired by any client */ -+ bool free; -+ /* Parent DMAC */ -+ struct dma330_dmac *dmac; -+ /* Only two at a time */ -+ struct _dma330_req req[2]; -+ /* Index of the last enqueued request */ -+ unsigned lstenq; -+ /* Index of the last submitted request or -1 if the DMA is stopped */ -+ int req_running; -+}; -+ -+enum dma330_dmac_state { -+ UNINIT, -+ INIT, -+ DYING, -+}; -+ -+enum desc_status { -+ /* In the DMAC pool */ -+ FREE, -+ /* -+ * Allocated to some channel during prep_xxx -+ * Also may be sitting on the work_list. -+ */ -+ PREP, -+ /* -+ * Sitting on the work_list and already submitted -+ * to the DMA330 core. Not more than two descriptors -+ * of a channel can be BUSY at any time. -+ */ -+ BUSY, -+ /* -+ * Sitting on the channel work_list but xfer done -+ * by DMA330 core -+ */ -+ DONE, -+}; -+ -+struct dma_dma330_chan { -+ /* Schedule desc completion */ -+ struct tasklet_struct task; -+ -+ /* DMA-Engine Channel */ -+ struct dma_chan chan; -+ -+ /* List of submitted descriptors */ -+ struct list_head submitted_list; -+ /* List of issued descriptors */ -+ struct list_head work_list; -+ /* List of completed descriptors */ -+ struct list_head completed_list; -+ -+ /* Pointer to the DMAC that manages this channel, -+ * NULL if the channel is available to be acquired. -+ * As the parent, this DMAC also provides descriptors -+ * to the channel. -+ */ -+ struct dma330_dmac *dmac; -+ -+ /* To protect channel manipulation */ -+ spinlock_t lock; -+ -+ /* -+ * Hardware channel thread of DMA330 DMAC. NULL if the channel is -+ * available. -+ */ -+ struct dma330_thread *thread; -+ -+ /* For D-to-M and M-to-D channels */ -+ int burst_sz; /* the peripheral fifo width */ -+ int burst_len; /* the number of burst */ -+ dma_addr_t fifo_addr; -+ -+ /* for cyclic capability */ -+ bool cyclic; -+}; -+ -+struct dma330_dmac { -+ /* DMA-Engine Device */ -+ struct dma_device ddma; -+ -+ /* Holds info about sg limitations */ -+ struct device_dma_parameters dma_parms; -+ -+ /* Pool of descriptors available for the DMAC's channels */ -+ struct list_head desc_pool; -+ /* To protect desc_pool manipulation */ -+ spinlock_t pool_lock; -+ -+ /* Size of MicroCode buffers for each channel. */ -+ unsigned mcbufsz; -+ /* ioremap'ed address of DMA330 registers. */ -+ void __iomem *base; -+ /* Populated by the DMA330 core driver during dma330_add */ -+ struct dma330_config pcfg; -+ -+ spinlock_t lock; -+ /* Maximum possible events/irqs */ -+ int events[32]; -+ /* BUS address of MicroCode buffer */ -+ dma_addr_t mcode_bus; -+ /* CPU address of MicroCode buffer */ -+ void *mcode_cpu; -+ /* List of all Channel threads */ -+ struct dma330_thread *channels; -+ /* Pointer to the MANAGER thread */ -+ struct dma330_thread *manager; -+ /* To handle bad news in interrupt */ -+ struct tasklet_struct tasks; -+ struct _dma330_tbd dmac_tbd; -+ /* State of DMAC operation */ -+ enum dma330_dmac_state state; -+ /* Holds list of reqs with due callbacks */ -+ struct list_head req_done; -+ -+ /* Peripheral channels connected to this DMAC */ -+ unsigned int num_peripherals; -+ struct dma_dma330_chan *peripherals; /* keep at end */ -+}; -+ -+struct dma_dma330_desc { -+ /* To attach to a queue as child */ -+ struct list_head node; -+ -+ /* Descriptor for the DMA Engine API */ -+ struct dma_async_tx_descriptor txd; -+ -+ /* Xfer for DMA330 core */ -+ struct dma330_xfer px; -+ -+ struct dma330_reqcfg rqcfg; -+ -+ enum desc_status status; -+ -+ int bytes_requested; -+ bool last; -+ -+ /* The channel which currently holds this desc */ -+ struct dma_dma330_chan *pchan; -+ -+ enum dma_transfer_direction rqtype; -+ /* Index of peripheral for the xfer. */ -+ unsigned peri:5; -+ /* Hook to attach to DMAC's list of reqs with due callback */ -+ struct list_head rqd; -+}; -+ -+struct _xfer_spec { -+ u32 ccr; -+ struct dma_dma330_desc *desc; -+}; -+ -+static inline bool _queue_empty(struct dma330_thread *thrd) -+{ -+ return thrd->req[0].desc == NULL && thrd->req[1].desc == NULL; -+} -+ -+static inline bool _queue_full(struct dma330_thread *thrd) -+{ -+ return thrd->req[0].desc != NULL && thrd->req[1].desc != NULL; -+} -+ -+static inline bool is_manager(struct dma330_thread *thrd) -+{ -+ return thrd->dmac->manager == thrd; -+} -+ -+/* If manager of the thread is in Non-Secure mode */ -+static inline bool _manager_ns(struct dma330_thread *thrd) -+{ -+ return (thrd->dmac->pcfg.mode & DMAC_MODE_NS) ? true : false; -+} -+ -+static inline u32 get_revision(u32 periph_id) -+{ -+ return (periph_id >> PERIPH_REV_SHIFT) & PERIPH_REV_MASK; -+} -+ -+static inline u32 _emit_ADDH(unsigned dry_run, u8 buf[], -+ enum dma330_dst da, u16 val) -+{ -+ if (dry_run) -+ return SZ_DMAADDH; -+ -+ buf[0] = CMD_DMAADDH; -+ buf[0] |= (da << 1); -+ *((__le16 *)&buf[1]) = cpu_to_le16(val); -+ -+ DMA330_DBGCMD_DUMP(SZ_DMAADDH, "\tDMAADDH %s %u\n", -+ da == 1 ? "DA" : "SA", val); -+ -+ return SZ_DMAADDH; -+} -+ -+static inline u32 _emit_END(unsigned dry_run, u8 buf[]) -+{ -+ if (dry_run) -+ return SZ_DMAEND; -+ -+ buf[0] = CMD_DMAEND; -+ -+ DMA330_DBGCMD_DUMP(SZ_DMAEND, "\tDMAEND\n"); -+ -+ return SZ_DMAEND; -+} -+ -+static inline u32 _emit_FLUSHP(unsigned dry_run, u8 buf[], u8 peri) -+{ -+ if (dry_run) -+ return SZ_DMAFLUSHP; -+ -+ buf[0] = CMD_DMAFLUSHP; -+ -+ peri &= 0x1f; -+ peri <<= 3; -+ buf[1] = peri; -+ -+ DMA330_DBGCMD_DUMP(SZ_DMAFLUSHP, "\tDMAFLUSHP %u\n", peri >> 3); -+ -+ return SZ_DMAFLUSHP; -+} -+ -+static inline u32 _emit_LD(unsigned dry_run, u8 buf[], enum dma330_cond cond) -+{ -+ if (dry_run) -+ return SZ_DMALD; -+ -+ buf[0] = CMD_DMALD; -+ -+ if (cond == SINGLE) -+ buf[0] |= (0 << 1) | (1 << 0); -+ else if (cond == BURST) -+ buf[0] |= (1 << 1) | (1 << 0); -+ -+ DMA330_DBGCMD_DUMP(SZ_DMALD, "\tDMALD%c\n", -+ cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A')); -+ -+ return SZ_DMALD; -+} -+ -+static inline u32 _emit_LDP(unsigned dry_run, u8 buf[], -+ enum dma330_cond cond, u8 peri) -+{ -+ if (dry_run) -+ return SZ_DMALDP; -+ -+ buf[0] = CMD_DMALDP; -+ -+ if (cond == BURST) -+ buf[0] |= (1 << 1); -+ -+ peri &= 0x1f; -+ peri <<= 3; -+ buf[1] = peri; -+ -+ DMA330_DBGCMD_DUMP(SZ_DMALDP, "\tDMALDP%c %u\n", -+ cond == SINGLE ? 'S' : 'B', peri >> 3); -+ -+ return SZ_DMALDP; -+} -+ -+static inline u32 _emit_LP(unsigned dry_run, u8 buf[], -+ unsigned loop, u8 cnt) -+{ -+ if (dry_run) -+ return SZ_DMALP; -+ -+ buf[0] = CMD_DMALP; -+ -+ if (loop) -+ buf[0] |= (1 << 1); -+ -+ cnt--; /* DMAC increments by 1 internally */ -+ buf[1] = cnt; -+ -+ DMA330_DBGCMD_DUMP(SZ_DMALP, "\tDMALP_%c %u\n", loop ? '1' : '0', cnt); -+ -+ return SZ_DMALP; -+} -+ -+struct _arg_LPEND { -+ enum dma330_cond cond; -+ bool forever; -+ unsigned loop; -+ u8 bjump; -+}; -+ -+static inline u32 _emit_LPEND(unsigned dry_run, u8 buf[], -+ const struct _arg_LPEND *arg) -+{ -+ enum dma330_cond cond = arg->cond; -+ bool forever = arg->forever; -+ unsigned loop = arg->loop; -+ u8 bjump = arg->bjump; -+ -+ if (dry_run) -+ return SZ_DMALPEND; -+ -+ buf[0] = CMD_DMALPEND; -+ -+ if (loop) -+ buf[0] |= (1 << 2); -+ -+ if (!forever) -+ buf[0] |= (1 << 4); -+ -+ if (cond == SINGLE) -+ buf[0] |= (0 << 1) | (1 << 0); -+ else if (cond == BURST) -+ buf[0] |= (1 << 1) | (1 << 0); -+ -+ buf[1] = bjump; -+ -+ DMA330_DBGCMD_DUMP(SZ_DMALPEND, "\tDMALP%s%c_%c bjmpto_%x\n", -+ forever ? "FE" : "END", -+ cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A'), -+ loop ? '1' : '0', -+ bjump); -+ -+ return SZ_DMALPEND; -+} -+ -+static inline u32 _emit_KILL(unsigned dry_run, u8 buf[]) -+{ -+ if (dry_run) -+ return SZ_DMAKILL; -+ -+ buf[0] = CMD_DMAKILL; -+ -+ return SZ_DMAKILL; -+} -+ -+static inline u32 _emit_MOV(unsigned dry_run, u8 buf[], -+ enum dmamov_dst dst, u32 val) -+{ -+ if (dry_run) -+ return SZ_DMAMOV; -+ -+ buf[0] = CMD_DMAMOV; -+ buf[1] = dst; -+ *((__le32 *)&buf[2]) = cpu_to_le32(val); -+ -+ DMA330_DBGCMD_DUMP(SZ_DMAMOV, "\tDMAMOV %s 0x%x\n", -+ dst == SAR ? "SAR" : (dst == DAR ? "DAR" : "CCR"), val); -+ -+ return SZ_DMAMOV; -+} -+ -+static inline u32 _emit_NOP(unsigned dry_run, u8 buf[]) -+{ -+ if (dry_run) -+ return SZ_DMANOP; -+ -+ buf[0] = CMD_DMANOP; -+ -+ DMA330_DBGCMD_DUMP(SZ_DMANOP, "\tDMANOP\n"); -+ -+ return SZ_DMANOP; -+} -+ -+static inline u32 _emit_RMB(unsigned dry_run, u8 buf[]) -+{ -+ if (dry_run) -+ return SZ_DMARMB; -+ -+ buf[0] = CMD_DMARMB; -+ -+ DMA330_DBGCMD_DUMP(SZ_DMARMB, "\tDMARMB\n"); -+ -+ return SZ_DMARMB; -+} -+ -+static inline u32 _emit_SEV(unsigned dry_run, u8 buf[], u8 ev) -+{ -+ if (dry_run) -+ return SZ_DMASEV; -+ -+ buf[0] = CMD_DMASEV; -+ -+ ev &= 0x1f; -+ ev <<= 3; -+ buf[1] = ev; -+ -+ DMA330_DBGCMD_DUMP(SZ_DMASEV, "\tDMASEV %u\n", ev >> 3); -+ -+ return SZ_DMASEV; -+} -+ -+static inline u32 _emit_ST(unsigned dry_run, u8 buf[], enum dma330_cond cond) -+{ -+ if (dry_run) -+ return SZ_DMAST; -+ -+ buf[0] = CMD_DMAST; -+ -+ if (cond == SINGLE) -+ buf[0] |= (0 << 1) | (1 << 0); -+ else if (cond == BURST) -+ buf[0] |= (1 << 1) | (1 << 0); -+ -+ DMA330_DBGCMD_DUMP(SZ_DMAST, "\tDMAST%c\n", -+ cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A')); -+ -+ return SZ_DMAST; -+} -+ -+static inline u32 _emit_STP(unsigned dry_run, u8 buf[], -+ enum dma330_cond cond, u8 peri) -+{ -+ if (dry_run) -+ return SZ_DMASTP; -+ -+ buf[0] = CMD_DMASTP; -+ -+ if (cond == BURST) -+ buf[0] |= (1 << 1); -+ -+ peri &= 0x1f; -+ peri <<= 3; -+ buf[1] = peri; -+ -+ DMA330_DBGCMD_DUMP(SZ_DMASTP, "\tDMASTP%c %u\n", -+ cond == SINGLE ? 'S' : 'B', peri >> 3); -+ -+ return SZ_DMASTP; -+} -+ -+static inline u32 _emit_STZ(unsigned dry_run, u8 buf[]) -+{ -+ if (dry_run) -+ return SZ_DMASTZ; -+ -+ buf[0] = CMD_DMASTZ; -+ -+ DMA330_DBGCMD_DUMP(SZ_DMASTZ, "\tDMASTZ\n"); -+ -+ return SZ_DMASTZ; -+} -+ -+static inline u32 _emit_WFE(unsigned dry_run, u8 buf[], u8 ev, -+ unsigned invalidate) -+{ -+ if (dry_run) -+ return SZ_DMAWFE; -+ -+ buf[0] = CMD_DMAWFE; -+ -+ ev &= 0x1f; -+ ev <<= 3; -+ buf[1] = ev; -+ -+ if (invalidate) -+ buf[1] |= (1 << 1); -+ -+ DMA330_DBGCMD_DUMP(SZ_DMAWFE, "\tDMAWFE %u%s\n", -+ ev >> 3, invalidate ? ", I" : ""); -+ -+ return SZ_DMAWFE; -+} -+ -+static inline u32 _emit_WFP(unsigned dry_run, u8 buf[], -+ enum dma330_cond cond, u8 peri) -+{ -+ if (dry_run) -+ return SZ_DMAWFP; -+ -+ buf[0] = CMD_DMAWFP; -+ -+ if (cond == SINGLE) -+ buf[0] |= (0 << 1) | (0 << 0); -+ else if (cond == BURST) -+ buf[0] |= (1 << 1) | (0 << 0); -+ else -+ buf[0] |= (0 << 1) | (1 << 0); -+ -+ peri &= 0x1f; -+ peri <<= 3; -+ buf[1] = peri; -+ -+ DMA330_DBGCMD_DUMP(SZ_DMAWFP, "\tDMAWFP%c %u\n", -+ cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'P'), peri >> 3); -+ -+ return SZ_DMAWFP; -+} -+ -+static inline u32 _emit_WMB(unsigned dry_run, u8 buf[]) -+{ -+ if (dry_run) -+ return SZ_DMAWMB; -+ -+ buf[0] = CMD_DMAWMB; -+ -+ DMA330_DBGCMD_DUMP(SZ_DMAWMB, "\tDMAWMB\n"); -+ -+ return SZ_DMAWMB; -+} -+ -+struct _arg_GO { -+ u8 chan; -+ u32 addr; -+ unsigned ns; -+}; -+ -+static inline u32 _emit_GO(unsigned dry_run, u8 buf[], -+ const struct _arg_GO *arg) -+{ -+ u8 chan = arg->chan; -+ u32 addr = arg->addr; -+ unsigned ns = arg->ns; -+ -+ if (dry_run) -+ return SZ_DMAGO; -+ -+ buf[0] = CMD_DMAGO; -+ buf[0] |= (ns << 1); -+ -+ buf[1] = chan & 0x7; -+ -+ *((__le32 *)&buf[2]) = cpu_to_le32(addr); -+ -+ return SZ_DMAGO; -+} -+ -+#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) -+ -+/* Returns Time-Out */ -+static bool _until_dmac_idle(struct dma330_thread *thrd) -+{ -+ void __iomem *regs = thrd->dmac->base; -+ unsigned long loops = msecs_to_loops(5); -+ -+ do { -+ /* Until Manager is Idle */ -+ if (!(readl(regs + DBGSTATUS) & DBG_BUSY)) -+ break; -+ -+ cpu_relax(); -+ } while (--loops); -+ -+ if (!loops) -+ return true; -+ -+ return false; -+} -+ -+static inline void _execute_DBGINSN(struct dma330_thread *thrd, -+ u8 insn[], bool as_manager) -+{ -+ void __iomem *regs = thrd->dmac->base; -+ u32 val; -+ -+ val = (insn[0] << 16) | (insn[1] << 24); -+ if (!as_manager) { -+ val |= (1 << 0); -+ val |= (thrd->id << 8); /* Channel Number */ -+ } -+ writel(val, regs + DBGINST0); -+ -+ val = le32_to_cpu(*((__le32 *)&insn[2])); -+ writel(val, regs + DBGINST1); -+ -+ /* If timed out due to halted state-machine */ -+ if (_until_dmac_idle(thrd)) { -+ dev_err(thrd->dmac->ddma.dev, "DMAC halted!\n"); -+ return; -+ } -+ -+ /* Get going */ -+ writel(0, regs + DBGCMD); -+} -+ -+static inline u32 _state(struct dma330_thread *thrd) -+{ -+ void __iomem *regs = thrd->dmac->base; -+ u32 val; -+ -+ if (is_manager(thrd)) -+ val = readl(regs + DS) & 0xf; -+ else -+ val = readl(regs + CS(thrd->id)) & 0xf; -+ -+ switch (val) { -+ case DS_ST_STOP: -+ return DMA330_STATE_STOPPED; -+ case DS_ST_EXEC: -+ return DMA330_STATE_EXECUTING; -+ case DS_ST_CMISS: -+ return DMA330_STATE_CACHEMISS; -+ case DS_ST_UPDTPC: -+ return DMA330_STATE_UPDTPC; -+ case DS_ST_WFE: -+ return DMA330_STATE_WFE; -+ case DS_ST_FAULT: -+ return DMA330_STATE_FAULTING; -+ case DS_ST_ATBRR: -+ if (is_manager(thrd)) -+ return DMA330_STATE_INVALID; -+ else -+ return DMA330_STATE_ATBARRIER; -+ case DS_ST_QBUSY: -+ if (is_manager(thrd)) -+ return DMA330_STATE_INVALID; -+ else -+ return DMA330_STATE_QUEUEBUSY; -+ case DS_ST_WFP: -+ if (is_manager(thrd)) -+ return DMA330_STATE_INVALID; -+ else -+ return DMA330_STATE_WFP; -+ case DS_ST_KILL: -+ if (is_manager(thrd)) -+ return DMA330_STATE_INVALID; -+ else -+ return DMA330_STATE_KILLING; -+ case DS_ST_CMPLT: -+ if (is_manager(thrd)) -+ return DMA330_STATE_INVALID; -+ else -+ return DMA330_STATE_COMPLETING; -+ case DS_ST_FLTCMP: -+ if (is_manager(thrd)) -+ return DMA330_STATE_INVALID; -+ else -+ return DMA330_STATE_FAULT_COMPLETING; -+ default: -+ return DMA330_STATE_INVALID; -+ } -+} -+ -+static void _stop(struct dma330_thread *thrd) -+{ -+ void __iomem *regs = thrd->dmac->base; -+ u8 insn[6] = {0, 0, 0, 0, 0, 0}; -+ -+ if (_state(thrd) == DMA330_STATE_FAULT_COMPLETING) -+ UNTIL(thrd, DMA330_STATE_FAULTING | DMA330_STATE_KILLING); -+ -+ /* Return if nothing needs to be done */ -+ if (_state(thrd) == DMA330_STATE_COMPLETING -+ || _state(thrd) == DMA330_STATE_KILLING -+ || _state(thrd) == DMA330_STATE_STOPPED) -+ return; -+ -+ _emit_KILL(0, insn); -+ -+ /* Stop generating interrupts for SEV */ -+ writel(readl(regs + INTEN) & ~(1 << thrd->ev), regs + INTEN); -+ -+ _execute_DBGINSN(thrd, insn, is_manager(thrd)); -+} -+ -+/* Start doing req 'idx' of thread 'thrd' */ -+static bool _trigger(struct dma330_thread *thrd) -+{ -+ void __iomem *regs = thrd->dmac->base; -+ struct _dma330_req *req; -+ struct dma_dma330_desc *desc; -+ struct _arg_GO go; -+ unsigned ns; -+ u8 insn[6] = {0, 0, 0, 0, 0, 0}; -+ int idx; -+ -+ /* Return if already ACTIVE */ -+ if (_state(thrd) != DMA330_STATE_STOPPED) -+ return true; -+ -+ idx = 1 - thrd->lstenq; -+ if (thrd->req[idx].desc != NULL) { -+ req = &thrd->req[idx]; -+ } else { -+ idx = thrd->lstenq; -+ if (thrd->req[idx].desc != NULL) -+ req = &thrd->req[idx]; -+ else -+ req = NULL; -+ } -+ -+ /* Return if no request */ -+ if (!req) -+ return true; -+ -+ /* Return if req is running */ -+ if (idx == thrd->req_running) -+ return true; -+ -+ desc = req->desc; -+ -+ ns = desc->rqcfg.nonsecure ? 1 : 0; -+ -+ /* See 'Abort Sources' point-4 at Page 2-25 */ -+ if (_manager_ns(thrd) && !ns) -+ dev_info(thrd->dmac->ddma.dev, "%s:%d Recipe for ABORT!\n", -+ __func__, __LINE__); -+ -+ go.chan = thrd->id; -+ go.addr = req->mc_bus; -+ go.ns = ns; -+ _emit_GO(0, insn, &go); -+ -+ /* Set to generate interrupts for SEV */ -+ writel(readl(regs + INTEN) | (1 << thrd->ev), regs + INTEN); -+ -+ /* Only manager can execute GO */ -+ _execute_DBGINSN(thrd, insn, true); -+ -+ thrd->req_running = idx; -+ -+ return true; -+} -+ -+static bool _start(struct dma330_thread *thrd) -+{ -+ switch (_state(thrd)) { -+ case DMA330_STATE_FAULT_COMPLETING: -+ UNTIL(thrd, DMA330_STATE_FAULTING | DMA330_STATE_KILLING); -+ -+ if (_state(thrd) == DMA330_STATE_KILLING) -+ UNTIL(thrd, DMA330_STATE_STOPPED) -+ -+ case DMA330_STATE_FAULTING: -+ _stop(thrd); -+ -+ case DMA330_STATE_KILLING: -+ case DMA330_STATE_COMPLETING: -+ UNTIL(thrd, DMA330_STATE_STOPPED) -+ -+ case DMA330_STATE_STOPPED: -+ return _trigger(thrd); -+ -+ case DMA330_STATE_WFP: -+ case DMA330_STATE_QUEUEBUSY: -+ case DMA330_STATE_ATBARRIER: -+ case DMA330_STATE_UPDTPC: -+ case DMA330_STATE_CACHEMISS: -+ case DMA330_STATE_EXECUTING: -+ return true; -+ -+ case DMA330_STATE_WFE: /* For RESUME, nothing yet */ -+ default: -+ return false; -+ } -+} -+ -+static inline int _ldst_memtomem(unsigned dry_run, u8 buf[], -+ const struct _xfer_spec *pxs, int cyc) -+{ -+ int off = 0; -+ -+ while (cyc--) { -+ off += _emit_LD(dry_run, &buf[off], ALWAYS); -+ off += _emit_ST(dry_run, &buf[off], ALWAYS); -+ } -+ -+ return off; -+} -+ -+static inline int _ldst_devtomem(unsigned dry_run, u8 buf[], -+ const struct _xfer_spec *pxs, int cyc) -+{ -+ int off = 0; -+ -+ while (cyc--) { -+ off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri); -+ off += _emit_LD(dry_run, &buf[off], ALWAYS); -+ off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->desc->peri); -+ off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri); -+ } -+ -+ return off; -+} -+ -+static inline int _ldst_memtodev(unsigned dry_run, u8 buf[], -+ const struct _xfer_spec *pxs, int cyc) -+{ -+ int off = 0; -+ -+ while (cyc--) { -+ off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri); -+ off += _emit_LD(dry_run, &buf[off], ALWAYS); -+ off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->desc->peri); -+ off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri); -+ } -+ -+ return off; -+} -+ -+static int _bursts(unsigned dry_run, u8 buf[], -+ const struct _xfer_spec *pxs, int cyc) -+{ -+ int off = 0; -+ -+ switch (pxs->desc->rqtype) { -+ case DMA_MEM_TO_DEV: -+ off += _ldst_memtodev(dry_run, &buf[off], pxs, cyc); -+ break; -+ case DMA_DEV_TO_MEM: -+ off += _ldst_devtomem(dry_run, &buf[off], pxs, cyc); -+ break; -+ case DMA_MEM_TO_MEM: -+ off += _ldst_memtomem(dry_run, &buf[off], pxs, cyc); -+ break; -+ default: -+ off += 0x40000000; /* Scare off the Client */ -+ break; -+ } -+ -+ return off; -+} -+ -+/* Returns bytes consumed and updates bursts */ -+static inline int _loop(unsigned dry_run, u8 buf[], -+ unsigned long *bursts, const struct _xfer_spec *pxs) -+{ -+ int cyc, cycmax, szlp, szlpend, szbrst, off; -+ unsigned lcnt0, lcnt1, ljmp0, ljmp1; -+ struct _arg_LPEND lpend; -+ -+ if (*bursts == 1) -+ return _bursts(dry_run, buf, pxs, 1); -+ -+ /* Max iterations possible in DMALP is 256 */ -+ if (*bursts >= 256*256) { -+ lcnt1 = 256; -+ lcnt0 = 256; -+ cyc = *bursts / lcnt1 / lcnt0; -+ } else if (*bursts > 256) { -+ lcnt1 = 256; -+ lcnt0 = *bursts / lcnt1; -+ cyc = 1; -+ } else { -+ lcnt1 = *bursts; -+ lcnt0 = 0; -+ cyc = 1; -+ } -+ -+ szlp = _emit_LP(1, buf, 0, 0); -+ szbrst = _bursts(1, buf, pxs, 1); -+ -+ lpend.cond = ALWAYS; -+ lpend.forever = false; -+ lpend.loop = 0; -+ lpend.bjump = 0; -+ szlpend = _emit_LPEND(1, buf, &lpend); -+ -+ if (lcnt0) { -+ szlp *= 2; -+ szlpend *= 2; -+ } -+ -+ /* -+ * Max bursts that we can unroll due to limit on the -+ * size of backward jump that can be encoded in DMALPEND -+ * which is 8-bits and hence 255 -+ */ -+ cycmax = (255 - (szlp + szlpend)) / szbrst; -+ -+ cyc = (cycmax < cyc) ? cycmax : cyc; -+ -+ off = 0; -+ -+ if (lcnt0) { -+ off += _emit_LP(dry_run, &buf[off], 0, lcnt0); -+ ljmp0 = off; -+ } -+ -+ off += _emit_LP(dry_run, &buf[off], 1, lcnt1); -+ ljmp1 = off; -+ -+ off += _bursts(dry_run, &buf[off], pxs, cyc); -+ -+ lpend.cond = ALWAYS; -+ lpend.forever = false; -+ lpend.loop = 1; -+ lpend.bjump = off - ljmp1; -+ off += _emit_LPEND(dry_run, &buf[off], &lpend); -+ -+ if (lcnt0) { -+ lpend.cond = ALWAYS; -+ lpend.forever = false; -+ lpend.loop = 0; -+ lpend.bjump = off - ljmp0; -+ off += _emit_LPEND(dry_run, &buf[off], &lpend); -+ } -+ -+ *bursts = lcnt1 * cyc; -+ if (lcnt0) -+ *bursts *= lcnt0; -+ -+ return off; -+} -+ -+static inline int _req_loop(unsigned dry_run, u8 buf[], enum dma330_cond cond, -+ unsigned long *count, const struct _xfer_spec *pxs) -+{ -+ unsigned ljmp0; -+ struct _arg_LPEND lpend; -+ int off = 0; -+ -+ off += _emit_LP(dry_run, &buf[off], 0, *count); -+ ljmp0 = off; -+ -+ off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri); -+ off += _emit_LD(dry_run, &buf[off], cond); -+ off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri); -+ -+ lpend.cond = cond; -+ lpend.forever = false; -+ lpend.loop = 0; -+ lpend.bjump = off - ljmp0; -+ off += _emit_LPEND(dry_run, &buf[off], &lpend); -+ -+ return off; -+} -+ -+static inline u32 _prepare_ccr(const struct dma330_reqcfg *rqc, -+ enum dma330_cond cond) -+{ -+ u32 ccr = 0; -+ -+ if (rqc->src_inc) -+ ccr |= CC_SRCINC; -+ -+ if (rqc->dst_inc) -+ ccr |= CC_DSTINC; -+ -+ /* We set same protection levels for Src and DST for now */ -+ if (rqc->privileged) -+ ccr |= CC_SRCPRI | CC_DSTPRI; -+ if (rqc->nonsecure) -+ ccr |= CC_SRCNS | CC_DSTNS; -+ if (rqc->insnaccess) -+ ccr |= CC_SRCIA | CC_DSTIA; -+ -+ if (cond != SINGLE) { -+ ccr |= (((rqc->brst_len - 1) & 0xf) << CC_SRCBRSTLEN_SHFT); -+ ccr |= (((rqc->brst_len - 1) & 0xf) << CC_DSTBRSTLEN_SHFT); -+ } -+ -+ ccr |= (rqc->brst_size << CC_SRCBRSTSIZE_SHFT); -+ ccr |= (rqc->brst_size << CC_DSTBRSTSIZE_SHFT); -+ -+ ccr |= (rqc->scctl << CC_SRCCCTRL_SHFT); -+ ccr |= (rqc->dcctl << CC_DSTCCTRL_SHFT); -+ -+ ccr |= (rqc->swap << CC_SWAP_SHFT); -+ -+ return ccr; -+} -+ -+ -+static inline int _setup_xfer(unsigned dry_run, u8 buf[], -+ const struct _xfer_spec *pxs) -+{ -+ u32 bytes = pxs->desc->px.bytes; -+ u32 bursts = BYTE_TO_BURST(bytes, pxs->ccr); -+ u32 singles = (bytes - BURST_TO_BYTE(bursts, pxs->ccr)) >> 2; -+ u32 ccr = pxs->ccr; -+ u32 src_addr = pxs->desc->px.src_addr; -+ u32 dst_addr = pxs->desc->px.dst_addr; -+ unsigned long c; -+ int off = 0; -+ -+ if ((pxs->desc->rqtype == DMA_DEV_TO_MEM) || -+ (pxs->desc->rqtype == DMA_MEM_TO_DEV)) { -+ if(bursts) { -+ off += _emit_MOV(dry_run, &buf[off], CCR, ccr); -+ off += _emit_MOV(dry_run, &buf[off], SAR, src_addr); -+ off += _emit_MOV(dry_run, &buf[off], DAR, dst_addr); -+ -+ off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri); -+ -+ while(bursts) { -+ c = (bursts > 256) ? 256 : bursts; -+ off += _req_loop(dry_run, &buf[off], BURST, &c, pxs); -+ bursts -= c; -+ } -+ } -+ -+ if (singles) { -+ ccr = _prepare_ccr(&pxs->desc->rqcfg, SINGLE); -+ if (pxs->desc->rqtype == DMA_MEM_TO_DEV) { -+ src_addr += bytes - singles * 4; -+ } else { -+ dst_addr += bytes - singles * 4; -+ } -+ off += _emit_MOV(dry_run, &buf[off], CCR, ccr); -+ off += _emit_MOV(dry_run, &buf[off], SAR, src_addr); -+ off += _emit_MOV(dry_run, &buf[off], DAR, dst_addr); -+ -+ while(singles) { -+ c = (singles > 256) ? 256 : singles; -+ off += _req_loop(dry_run, &buf[off], SINGLE, &c, pxs); -+ singles -= c; -+ } -+ -+ off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri); -+ } -+ } else { -+ /* Error if xfer length is not aligned at burst size */ -+ if (bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr))) -+ return -EINVAL; -+ -+ off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr); -+ off += _emit_MOV(dry_run, &buf[off], SAR, src_addr); -+ off += _emit_MOV(dry_run, &buf[off], DAR, dst_addr); -+ -+ while (bursts) { -+ c = bursts; -+ off += _loop(dry_run, &buf[off], &c, pxs); -+ bursts -= c; -+ } -+ } -+ -+ return off; -+} -+ -+/* -+ * A req is a sequence of one or more xfer units. -+ * Returns the number of bytes taken to setup the MC for the req. -+ */ -+static int _setup_req(unsigned dry_run, struct dma330_thread *thrd, -+ unsigned index, struct _xfer_spec *pxs) -+{ -+ struct _dma330_req *req = &thrd->req[index]; -+ u8 *buf = req->mc_cpu; -+ int off = 0; -+ -+ DMA330_DBGMC_START(req->mc_bus); -+ -+ off += _setup_xfer(dry_run, &buf[off], pxs); -+ -+ /* DMASEV peripheral/event */ -+ off += _emit_SEV(dry_run, &buf[off], thrd->ev); -+ /* DMAEND */ -+ off += _emit_END(dry_run, &buf[off]); -+ -+ return off; -+} -+ -+/* -+ * Submit a list of xfers after which the client wants notification. -+ * Client is not notified after each xfer unit, just once after all -+ * xfer units are done or some error occurs. -+ */ -+static int dma330_submit_req(struct dma330_thread *thrd, -+ struct dma_dma330_desc *desc) -+{ -+ struct dma330_dmac *dma330 = thrd->dmac; -+ struct _xfer_spec xs; -+ unsigned long flags; -+ unsigned idx; -+ u32 ccr; -+ int ret = 0; -+ -+ if (dma330->state == DYING -+ || dma330->dmac_tbd.reset_chan & (1 << thrd->id)) { -+ dev_info(thrd->dmac->ddma.dev, "%s:%d\n", -+ __func__, __LINE__); -+ return -EAGAIN; -+ } -+ -+ /* If request for non-existing peripheral */ -+ if (desc->rqtype != DMA_MEM_TO_MEM && -+ desc->peri >= dma330->pcfg.num_peri) { -+ dev_info(thrd->dmac->ddma.dev, -+ "%s:%d Invalid peripheral(%u)!\n", -+ __func__, __LINE__, desc->peri); -+ return -EINVAL; -+ } -+ -+ spin_lock_irqsave(&dma330->lock, flags); -+ -+ if (_queue_full(thrd)) { -+ ret = -EAGAIN; -+ goto xfer_exit; -+ } -+ -+ /* Prefer Secure Channel */ -+ if (!_manager_ns(thrd)) -+ desc->rqcfg.nonsecure = 0; -+ else -+ desc->rqcfg.nonsecure = 1; -+ -+ ccr = _prepare_ccr(&desc->rqcfg, BURST); -+ -+ idx = thrd->req[0].desc == NULL ? 0 : 1; -+ -+ xs.ccr = ccr; -+ xs.desc = desc; -+ -+ /* First dry run to check if req is acceptable */ -+ ret = _setup_req(1, thrd, idx, &xs); -+ if (ret < 0) -+ goto xfer_exit; -+ -+ if (ret > dma330->mcbufsz / 2) { -+ dev_info(dma330->ddma.dev, "%s:%d Try increasing mcbufsz (%i/%i)\n", -+ __func__, __LINE__, ret, dma330->mcbufsz / 2); -+ ret = -ENOMEM; -+ goto xfer_exit; -+ } -+ -+ /* Hook the request */ -+ thrd->lstenq = idx; -+ thrd->req[idx].desc = desc; -+ _setup_req(0, thrd, idx, &xs); -+ -+ ret = 0; -+ -+xfer_exit: -+ spin_unlock_irqrestore(&dma330->lock, flags); -+ -+ return ret; -+} -+ -+static void dma_dma330_rqcb(struct dma_dma330_desc *desc, enum dma330_op_err err) -+{ -+ struct dma_dma330_chan *pch; -+ unsigned long flags; -+ -+ if (!desc) -+ return; -+ -+ pch = desc->pchan; -+ -+ /* If desc aborted */ -+ if (!pch) -+ return; -+ -+ spin_lock_irqsave(&pch->lock, flags); -+ -+ desc->status = DONE; -+ -+ spin_unlock_irqrestore(&pch->lock, flags); -+ -+ tasklet_schedule(&pch->task); -+} -+ -+static void dma330_dotask(unsigned long data) -+{ -+ struct dma330_dmac *dma330 = (struct dma330_dmac *) data; -+ unsigned long flags; -+ int i; -+ -+ spin_lock_irqsave(&dma330->lock, flags); -+ -+ /* The DMAC itself gone nuts */ -+ if (dma330->dmac_tbd.reset_dmac) { -+ dma330->state = DYING; -+ /* Reset the manager too */ -+ dma330->dmac_tbd.reset_mngr = true; -+ /* Clear the reset flag */ -+ dma330->dmac_tbd.reset_dmac = false; -+ } -+ -+ if (dma330->dmac_tbd.reset_mngr) { -+ _stop(dma330->manager); -+ /* Reset all channels */ -+ dma330->dmac_tbd.reset_chan = (1 << dma330->pcfg.num_chan) - 1; -+ /* Clear the reset flag */ -+ dma330->dmac_tbd.reset_mngr = false; -+ } -+ -+ for (i = 0; i < dma330->pcfg.num_chan; i++) { -+ -+ if (dma330->dmac_tbd.reset_chan & (1 << i)) { -+ struct dma330_thread *thrd = &dma330->channels[i]; -+ void __iomem *regs = dma330->base; -+ enum dma330_op_err err; -+ -+ _stop(thrd); -+ -+ if (readl(regs + FSC) & (1 << thrd->id)) -+ err = DMA330_ERR_FAIL; -+ else -+ err = DMA330_ERR_ABORT; -+ -+ spin_unlock_irqrestore(&dma330->lock, flags); -+ dma_dma330_rqcb(thrd->req[1 - thrd->lstenq].desc, err); -+ dma_dma330_rqcb(thrd->req[thrd->lstenq].desc, err); -+ spin_lock_irqsave(&dma330->lock, flags); -+ -+ thrd->req[0].desc = NULL; -+ thrd->req[1].desc = NULL; -+ thrd->req_running = -1; -+ -+ /* Clear the reset flag */ -+ dma330->dmac_tbd.reset_chan &= ~(1 << i); -+ } -+ } -+ -+ spin_unlock_irqrestore(&dma330->lock, flags); -+ -+ return; -+} -+ -+/* Returns 1 if state was updated, 0 otherwise */ -+static int dma330_update(struct dma330_dmac *dma330) -+{ -+ struct dma_dma330_desc *descdone, *tmp; -+ unsigned long flags; -+ void __iomem *regs; -+ u32 val; -+ int id, ev, ret = 0; -+ -+ regs = dma330->base; -+ -+ spin_lock_irqsave(&dma330->lock, flags); -+ -+ val = readl(regs + FSM) & 0x1; -+ if (val) -+ dma330->dmac_tbd.reset_mngr = true; -+ else -+ dma330->dmac_tbd.reset_mngr = false; -+ -+ val = readl(regs + FSC) & ((1 << dma330->pcfg.num_chan) - 1); -+ dma330->dmac_tbd.reset_chan |= val; -+ if (val) { -+ int i = 0; -+ while (i < dma330->pcfg.num_chan) { -+ if (val & (1 << i)) { -+ dev_info(dma330->ddma.dev, -+ "Reset Channel-%d\t CS-%x FTC-%x\n", -+ i, readl(regs + CS(i)), -+ readl(regs + FTC(i))); -+ _stop(&dma330->channels[i]); -+ } -+ i++; -+ } -+ } -+ -+ /* Check which event happened i.e, thread notified */ -+ val = readl(regs + ES); -+ if (dma330->pcfg.num_events < 32 -+ && val & ~((1 << dma330->pcfg.num_events) - 1)) { -+ dma330->dmac_tbd.reset_dmac = true; -+ dev_err(dma330->ddma.dev, "%s:%d Unexpected!\n", __func__, -+ __LINE__); -+ ret = 1; -+ goto updt_exit; -+ } -+ -+ for (ev = 0; ev < dma330->pcfg.num_events; ev++) { -+ if (val & (1 << ev)) { /* Event occurred */ -+ struct dma330_thread *thrd; -+ u32 inten = readl(regs + INTEN); -+ int active; -+ -+ /* Clear the event */ -+ if (inten & (1 << ev)) -+ writel(1 << ev, regs + INTCLR); -+ -+ ret = 1; -+ -+ id = dma330->events[ev]; -+ -+ thrd = &dma330->channels[id]; -+ -+ active = thrd->req_running; -+ if (active == -1) /* Aborted */ -+ continue; -+ -+ /* Detach the req */ -+ descdone = thrd->req[active].desc; -+ thrd->req[active].desc = NULL; -+ -+ thrd->req_running = -1; -+ -+ /* Get going again ASAP */ -+ _start(thrd); -+ -+ /* For now, just make a list of callbacks to be done */ -+ list_add_tail(&descdone->rqd, &dma330->req_done); -+ } -+ } -+ -+ /* Now that we are in no hurry, do the callbacks */ -+ list_for_each_entry_safe(descdone, tmp, &dma330->req_done, rqd) { -+ list_del(&descdone->rqd); -+ spin_unlock_irqrestore(&dma330->lock, flags); -+ dma_dma330_rqcb(descdone, DMA330_ERR_NONE); -+ spin_lock_irqsave(&dma330->lock, flags); -+ } -+ -+updt_exit: -+ spin_unlock_irqrestore(&dma330->lock, flags); -+ -+ if (dma330->dmac_tbd.reset_dmac -+ || dma330->dmac_tbd.reset_mngr -+ || dma330->dmac_tbd.reset_chan) { -+ ret = 1; -+ tasklet_schedule(&dma330->tasks); -+ } -+ -+ return ret; -+} -+ -+/* Reserve an event */ -+static inline int _alloc_event(struct dma330_thread *thrd) -+{ -+ struct dma330_dmac *dma330 = thrd->dmac; -+ int ev; -+ -+ for (ev = 0; ev < dma330->pcfg.num_events; ev++) -+ if (dma330->events[ev] == -1) { -+ dma330->events[ev] = thrd->id; -+ return ev; -+ } -+ -+ return -1; -+} -+ -+static bool _chan_ns(const struct dma330_dmac *dma330, int i) -+{ -+ return dma330->pcfg.irq_ns & (1 << i); -+} -+ -+/* Upon success, returns IdentityToken for the -+ * allocated channel, NULL otherwise. -+ */ -+static struct dma330_thread *dma330_request_channel(struct dma330_dmac *dma330) -+{ -+ struct dma330_thread *thrd = NULL; -+ unsigned long flags; -+ int chans, i; -+ -+ if (dma330->state == DYING) -+ return NULL; -+ -+ chans = dma330->pcfg.num_chan; -+ -+ spin_lock_irqsave(&dma330->lock, flags); -+ -+ for (i = 0; i < chans; i++) { -+ thrd = &dma330->channels[i]; -+ if ((thrd->free) && (!_manager_ns(thrd) || -+ _chan_ns(dma330, i))) { -+ thrd->ev = _alloc_event(thrd); -+ if (thrd->ev >= 0) { -+ thrd->free = false; -+ thrd->lstenq = 1; -+ thrd->req[0].desc = NULL; -+ thrd->req[1].desc = NULL; -+ thrd->req_running = -1; -+ break; -+ } -+ } -+ thrd = NULL; -+ } -+ -+ spin_unlock_irqrestore(&dma330->lock, flags); -+ -+ return thrd; -+} -+ -+/* Release an event */ -+static inline void _free_event(struct dma330_thread *thrd, int ev) -+{ -+ struct dma330_dmac *dma330 = thrd->dmac; -+ -+ /* If the event is valid and was held by the thread */ -+ if (ev >= 0 && ev < dma330->pcfg.num_events -+ && dma330->events[ev] == thrd->id) -+ dma330->events[ev] = -1; -+} -+ -+static void dma330_release_channel(struct dma330_thread *thrd) -+{ -+ struct dma330_dmac *dma330; -+ unsigned long flags; -+ -+ if (!thrd || thrd->free) -+ return; -+ -+ _stop(thrd); -+ -+ dma_dma330_rqcb(thrd->req[1 - thrd->lstenq].desc, DMA330_ERR_ABORT); -+ dma_dma330_rqcb(thrd->req[thrd->lstenq].desc, DMA330_ERR_ABORT); -+ -+ dma330 = thrd->dmac; -+ -+ spin_lock_irqsave(&dma330->lock, flags); -+ _free_event(thrd, thrd->ev); -+ thrd->free = true; -+ spin_unlock_irqrestore(&dma330->lock, flags); -+} -+ -+/* Initialize the structure for DMA330 configuration, that can be used -+ * by the client driver the make best use of the DMAC -+ */ -+static void read_dmac_config(struct dma330_dmac *dma330) -+{ -+ void __iomem *regs = dma330->base; -+ u32 val; -+ -+ val = readl(regs + CRD) >> CRD_DATA_WIDTH_SHIFT; -+ val &= CRD_DATA_WIDTH_MASK; -+ dma330->pcfg.data_bus_width = 8 * (1 << val); -+ -+ val = readl(regs + CRD) >> CRD_DATA_BUFF_SHIFT; -+ val &= CRD_DATA_BUFF_MASK; -+ dma330->pcfg.data_buf_dep = val + 1; -+ -+ val = readl(regs + CR0) >> CR0_NUM_CHANS_SHIFT; -+ val &= CR0_NUM_CHANS_MASK; -+ val += 1; -+ dma330->pcfg.num_chan = val; -+ -+ val = readl(regs + CR0); -+ if (val & CR0_PERIPH_REQ_SET) { -+ val = (val >> CR0_NUM_PERIPH_SHIFT) & CR0_NUM_PERIPH_MASK; -+ val += 1; -+ dma330->pcfg.num_peri = val; -+ dma330->pcfg.peri_ns = readl(regs + CR4); -+ } else { -+ dma330->pcfg.num_peri = 0; -+ } -+ -+ val = readl(regs + CR0); -+ if (val & CR0_BOOT_MAN_NS) -+ dma330->pcfg.mode |= DMAC_MODE_NS; -+ else -+ dma330->pcfg.mode &= ~DMAC_MODE_NS; -+ -+ val = readl(regs + CR0) >> CR0_NUM_EVENTS_SHIFT; -+ val &= CR0_NUM_EVENTS_MASK; -+ val += 1; -+ dma330->pcfg.num_events = val; -+ -+ dma330->pcfg.irq_ns = readl(regs + CR3); -+} -+ -+static inline void _reset_thread(struct dma330_thread *thrd) -+{ -+ struct dma330_dmac *dma330 = thrd->dmac; -+ -+ thrd->req[0].mc_cpu = dma330->mcode_cpu -+ + (thrd->id * dma330->mcbufsz); -+ thrd->req[0].mc_bus = dma330->mcode_bus -+ + (thrd->id * dma330->mcbufsz); -+ thrd->req[0].desc = NULL; -+ -+ thrd->req[1].mc_cpu = thrd->req[0].mc_cpu -+ + dma330->mcbufsz / 2; -+ thrd->req[1].mc_bus = thrd->req[0].mc_bus -+ + dma330->mcbufsz / 2; -+ thrd->req[1].desc = NULL; -+ -+ thrd->req_running = -1; -+} -+ -+static int dmac_alloc_threads(struct dma330_dmac *dma330) -+{ -+ int chans = dma330->pcfg.num_chan; -+ struct dma330_thread *thrd; -+ int i; -+ -+ /* Allocate 1 Manager and 'chans' Channel threads */ -+ dma330->channels = kzalloc((1 + chans) * sizeof(*thrd), -+ GFP_KERNEL); -+ if (!dma330->channels) -+ return -ENOMEM; -+ -+ /* Init Channel threads */ -+ for (i = 0; i < chans; i++) { -+ thrd = &dma330->channels[i]; -+ thrd->id = i; -+ thrd->dmac = dma330; -+ _reset_thread(thrd); -+ thrd->free = true; -+ } -+ -+ /* MANAGER is indexed at the end */ -+ thrd = &dma330->channels[chans]; -+ thrd->id = chans; -+ thrd->dmac = dma330; -+ thrd->free = false; -+ dma330->manager = thrd; -+ -+ return 0; -+} -+ -+static int dmac_alloc_resources(struct dma330_dmac *dma330) -+{ -+ int chans = dma330->pcfg.num_chan; -+ int ret; -+ -+ /* -+ * Alloc MicroCode buffer for 'chans' Channel threads. -+ * A channel's buffer offset is (Channel_Id * MCODE_BUFF_PERCHAN) -+ */ -+ dma330->mcode_cpu = dma_alloc_coherent(dma330->ddma.dev, -+ chans * dma330->mcbufsz, -+ &dma330->mcode_bus, GFP_KERNEL); -+ if (!dma330->mcode_cpu) { -+ dev_err(dma330->ddma.dev, "%s:%d Can't allocate memory!\n", -+ __func__, __LINE__); -+ return -ENOMEM; -+ } -+ -+ ret = dmac_alloc_threads(dma330); -+ if (ret) { -+ dev_err(dma330->ddma.dev, "%s:%d Can't to create channels for DMAC!\n", -+ __func__, __LINE__); -+ dma_free_coherent(dma330->ddma.dev, -+ chans * dma330->mcbufsz, -+ dma330->mcode_cpu, dma330->mcode_bus); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int dma330_add(struct dma330_dmac *dma330) -+{ -+ void __iomem *regs; -+ int i, ret; -+ -+ regs = dma330->base; -+ -+ /* Check if we can handle this DMAC */ -+ if ((dma330->pcfg.periph_id & 0xffffff) != PERIPH_ID_VAL) { -+ dev_err(dma330->ddma.dev, "PERIPH_ID 0x%x !\n", -+ dma330->pcfg.periph_id); -+ return -EINVAL; -+ } -+ -+ /* Read the configuration of the DMAC */ -+ read_dmac_config(dma330); -+ -+ if (dma330->pcfg.num_events == 0) { -+ dev_err(dma330->ddma.dev, "%s:%d Can't work without events!\n", -+ __func__, __LINE__); -+ return -EINVAL; -+ } -+ -+ spin_lock_init(&dma330->lock); -+ -+ INIT_LIST_HEAD(&dma330->req_done); -+ -+ /* Use default MC buffer size if not provided */ -+ if (!dma330->mcbufsz) -+ dma330->mcbufsz = MCODE_BUFF_PER_REQ * 2; -+ -+ /* Mark all events as free */ -+ for (i = 0; i < dma330->pcfg.num_events; i++) -+ dma330->events[i] = -1; -+ -+ /* Allocate resources needed by the DMAC */ -+ ret = dmac_alloc_resources(dma330); -+ if (ret) { -+ dev_err(dma330->ddma.dev, "Unable to create channels for DMAC\n"); -+ return ret; -+ } -+ -+ tasklet_init(&dma330->tasks, dma330_dotask, (unsigned long) dma330); -+ -+ dma330->state = INIT; -+ -+ return 0; -+} -+ -+static int dmac_free_threads(struct dma330_dmac *dma330) -+{ -+ struct dma330_thread *thrd; -+ int i; -+ -+ /* Release Channel threads */ -+ for (i = 0; i < dma330->pcfg.num_chan; i++) { -+ thrd = &dma330->channels[i]; -+ dma330_release_channel(thrd); -+ } -+ -+ /* Free memory */ -+ kfree(dma330->channels); -+ -+ return 0; -+} -+ -+static void dma330_del(struct dma330_dmac *dma330) -+{ -+ dma330->state = UNINIT; -+ -+ tasklet_kill(&dma330->tasks); -+ -+ /* Free DMAC resources */ -+ dmac_free_threads(dma330); -+ -+ dma_free_coherent(dma330->ddma.dev, -+ dma330->pcfg.num_chan * dma330->mcbufsz, dma330->mcode_cpu, -+ dma330->mcode_bus); -+} -+ -+/* forward declaration */ -+static struct amba_driver iproc_dma330_driver; -+ -+static inline struct dma_dma330_chan * -+to_pchan(struct dma_chan *ch) -+{ -+ if (!ch) -+ return NULL; -+ -+ return container_of(ch, struct dma_dma330_chan, chan); -+} -+ -+static inline struct dma_dma330_desc * -+to_desc(struct dma_async_tx_descriptor *tx) -+{ -+ return container_of(tx, struct dma_dma330_desc, txd); -+} -+ -+static inline void fill_queue(struct dma_dma330_chan *pch) -+{ -+ struct dma_dma330_desc *desc; -+ int ret; -+ -+ list_for_each_entry(desc, &pch->work_list, node) { -+ -+ /* If already submitted */ -+ if (desc->status == BUSY) -+ continue; -+ -+ ret = dma330_submit_req(pch->thread, desc); -+ if (!ret) { -+ desc->status = BUSY; -+ } else if (ret == -EAGAIN) { -+ /* QFull or DMAC Dying */ -+ break; -+ } else { -+ /* Unacceptable request */ -+ desc->status = DONE; -+ dev_err(pch->dmac->ddma.dev, "%s:%d Bad Desc(%d)\n", -+ __func__, __LINE__, desc->txd.cookie); -+ tasklet_schedule(&pch->task); -+ } -+ } -+} -+ -+static void dma330_tasklet(unsigned long data) -+{ -+ struct dma_dma330_chan *pch = (struct dma_dma330_chan *)data; -+ struct dma_dma330_desc *desc, *_dt; -+ unsigned long flags; -+ bool power_down = false; -+ -+ spin_lock_irqsave(&pch->lock, flags); -+ -+ /* Pick up ripe tomatoes */ -+ list_for_each_entry_safe(desc, _dt, &pch->work_list, node) -+ if (desc->status == DONE) { -+ if (!pch->cyclic) -+ dma_cookie_complete(&desc->txd); -+ list_move_tail(&desc->node, &pch->completed_list); -+ } -+ -+ /* Try to submit a req imm. next to the last completed cookie */ -+ fill_queue(pch); -+ -+ if (list_empty(&pch->work_list)) { -+ spin_lock(&pch->thread->dmac->lock); -+ _stop(pch->thread); -+ spin_unlock(&pch->thread->dmac->lock); -+ power_down = true; -+ } else { -+ /* Make sure the DMA330 Channel thread is active */ -+ spin_lock(&pch->thread->dmac->lock); -+ _start(pch->thread); -+ spin_unlock(&pch->thread->dmac->lock); -+ } -+ -+ while (!list_empty(&pch->completed_list)) { -+ dma_async_tx_callback callback; -+ void *callback_param; -+ -+ desc = list_first_entry(&pch->completed_list, -+ struct dma_dma330_desc, node); -+ -+ callback = desc->txd.callback; -+ callback_param = desc->txd.callback_param; -+ -+ if (pch->cyclic) { -+ desc->status = PREP; -+ list_move_tail(&desc->node, &pch->work_list); -+ if (power_down) { -+ spin_lock(&pch->thread->dmac->lock); -+ _start(pch->thread); -+ spin_unlock(&pch->thread->dmac->lock); -+ power_down = false; -+ } -+ } else { -+ desc->status = FREE; -+ list_move_tail(&desc->node, &pch->dmac->desc_pool); -+ } -+ -+ dma_descriptor_unmap(&desc->txd); -+ -+ if (callback) { -+ spin_unlock_irqrestore(&pch->lock, flags); -+ callback(callback_param); -+ spin_lock_irqsave(&pch->lock, flags); -+ } -+ } -+ spin_unlock_irqrestore(&pch->lock, flags); -+ -+ /* If work list empty, power down */ -+ if (power_down) { -+ pm_runtime_mark_last_busy(pch->dmac->ddma.dev); -+ pm_runtime_put_autosuspend(pch->dmac->ddma.dev); -+ } -+} -+ -+bool dma330_filter(struct dma_chan *chan, void *param) -+{ -+ u8 *peri_id; -+ -+ if (chan->device->dev->driver != &iproc_dma330_driver.drv) -+ return false; -+ -+ peri_id = chan->private; -+ return *peri_id == (unsigned long)param; -+} -+EXPORT_SYMBOL(dma330_filter); -+ -+static struct dma_chan *of_dma_dma330_xlate(struct of_phandle_args *dma_spec, -+ struct of_dma *ofdma) -+{ -+ int count = dma_spec->args_count; -+ struct dma330_dmac *dma330 = ofdma->of_dma_data; -+ unsigned int chan_id; -+ -+ if (!dma330) -+ return NULL; -+ -+ if (count != 1) -+ return NULL; -+ -+ chan_id = dma_spec->args[0]; -+ if (chan_id >= dma330->num_peripherals) -+ return NULL; -+ -+ return dma_get_slave_channel(&dma330->peripherals[chan_id].chan); -+} -+ -+static int dma330_alloc_chan_resources(struct dma_chan *chan) -+{ -+ struct dma_dma330_chan *pch = to_pchan(chan); -+ struct dma330_dmac *dma330 = pch->dmac; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&pch->lock, flags); -+ -+ dma_cookie_init(chan); -+ pch->cyclic = false; -+ -+ pch->thread = dma330_request_channel(dma330); -+ if (!pch->thread) { -+ spin_unlock_irqrestore(&pch->lock, flags); -+ return -ENOMEM; -+ } -+ -+ tasklet_init(&pch->task, dma330_tasklet, (unsigned long) pch); -+ -+ spin_unlock_irqrestore(&pch->lock, flags); -+ -+ return 1; -+} -+ -+static int dma330_config(struct dma_chan *chan, -+ struct dma_slave_config *slave_config) -+{ -+ struct dma_dma330_chan *pch = to_pchan(chan); -+ -+ if (slave_config->direction == DMA_MEM_TO_DEV) { -+ if (slave_config->dst_addr) -+ pch->fifo_addr = slave_config->dst_addr; -+ if (slave_config->dst_addr_width) -+ pch->burst_sz = __ffs(slave_config->dst_addr_width); -+ if (slave_config->dst_maxburst) -+ pch->burst_len = slave_config->dst_maxburst; -+ } else if (slave_config->direction == DMA_DEV_TO_MEM) { -+ if (slave_config->src_addr) -+ pch->fifo_addr = slave_config->src_addr; -+ if (slave_config->src_addr_width) -+ pch->burst_sz = __ffs(slave_config->src_addr_width); -+ if (slave_config->src_maxburst) -+ pch->burst_len = slave_config->src_maxburst; -+ } -+ -+ return 0; -+} -+ -+static int dma330_terminate_all(struct dma_chan *chan) -+{ -+ struct dma_dma330_chan *pch = to_pchan(chan); -+ struct dma_dma330_desc *desc; -+ unsigned long flags; -+ struct dma330_dmac *dma330 = pch->dmac; -+ LIST_HEAD(list); -+ -+ pm_runtime_get_sync(dma330->ddma.dev); -+ spin_lock_irqsave(&pch->lock, flags); -+ spin_lock(&dma330->lock); -+ _stop(pch->thread); -+ spin_unlock(&dma330->lock); -+ -+ pch->thread->req[0].desc = NULL; -+ pch->thread->req[1].desc = NULL; -+ pch->thread->req_running = -1; -+ -+ /* Mark all desc done */ -+ list_for_each_entry(desc, &pch->submitted_list, node) { -+ desc->status = FREE; -+ dma_cookie_complete(&desc->txd); -+ } -+ -+ list_for_each_entry(desc, &pch->work_list , node) { -+ desc->status = FREE; -+ dma_cookie_complete(&desc->txd); -+ } -+ -+ list_splice_tail_init(&pch->submitted_list, &dma330->desc_pool); -+ list_splice_tail_init(&pch->work_list, &dma330->desc_pool); -+ list_splice_tail_init(&pch->completed_list, &dma330->desc_pool); -+ spin_unlock_irqrestore(&pch->lock, flags); -+ pm_runtime_mark_last_busy(dma330->ddma.dev); -+ pm_runtime_put_autosuspend(dma330->ddma.dev); -+ -+ return 0; -+} -+ -+/* -+ * We don't support DMA_RESUME command because of hardware -+ * limitations, so after pausing the channel we cannot restore -+ * it to active state. We have to terminate channel and setup -+ * DMA transfer again. This pause feature was implemented to -+ * allow safely read residue before channel termination. -+ */ -+static int dma330_pause(struct dma_chan *chan) -+{ -+ struct dma_dma330_chan *pch = to_pchan(chan); -+ struct dma330_dmac *dma330 = pch->dmac; -+ unsigned long flags; -+ -+ pm_runtime_get_sync(dma330->ddma.dev); -+ spin_lock_irqsave(&pch->lock, flags); -+ -+ spin_lock(&dma330->lock); -+ _stop(pch->thread); -+ spin_unlock(&dma330->lock); -+ -+ spin_unlock_irqrestore(&pch->lock, flags); -+ pm_runtime_mark_last_busy(dma330->ddma.dev); -+ pm_runtime_put_autosuspend(dma330->ddma.dev); -+ -+ return 0; -+} -+ -+static void dma330_free_chan_resources(struct dma_chan *chan) -+{ -+ struct dma_dma330_chan *pch = to_pchan(chan); -+ unsigned long flags; -+ -+ tasklet_kill(&pch->task); -+ -+ pm_runtime_get_sync(pch->dmac->ddma.dev); -+ spin_lock_irqsave(&pch->lock, flags); -+ -+ dma330_release_channel(pch->thread); -+ pch->thread = NULL; -+ -+ if (pch->cyclic) -+ list_splice_tail_init(&pch->work_list, &pch->dmac->desc_pool); -+ -+ spin_unlock_irqrestore(&pch->lock, flags); -+ pm_runtime_mark_last_busy(pch->dmac->ddma.dev); -+ pm_runtime_put_autosuspend(pch->dmac->ddma.dev); -+} -+ -+static int dma330_get_current_xferred_count(struct dma_dma330_chan *pch, -+ struct dma_dma330_desc *desc) -+{ -+ struct dma330_thread *thrd = pch->thread; -+ struct dma330_dmac *dma330 = pch->dmac; -+ void __iomem *regs = thrd->dmac->base; -+ u32 val, addr; -+ -+ pm_runtime_get_sync(dma330->ddma.dev); -+ val = addr = 0; -+ if (desc->rqcfg.src_inc) { -+ val = readl(regs + SA(thrd->id)); -+ addr = desc->px.src_addr; -+ } else { -+ val = readl(regs + DA(thrd->id)); -+ addr = desc->px.dst_addr; -+ } -+ pm_runtime_mark_last_busy(pch->dmac->ddma.dev); -+ pm_runtime_put_autosuspend(dma330->ddma.dev); -+ return val - addr; -+} -+ -+static enum dma_status -+dma330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, -+ struct dma_tx_state *txstate) -+{ -+ enum dma_status ret; -+ unsigned long flags; -+ struct dma_dma330_desc *desc, *running = NULL; -+ struct dma_dma330_chan *pch = to_pchan(chan); -+ unsigned int transferred, residual = 0; -+ -+ ret = dma_cookie_status(chan, cookie, txstate); -+ -+ if (!txstate) -+ return ret; -+ -+ if (ret == DMA_COMPLETE) -+ goto out; -+ -+ spin_lock_irqsave(&pch->lock, flags); -+ -+ if (pch->thread->req_running != -1) -+ running = pch->thread->req[pch->thread->req_running].desc; -+ -+ /* Check in pending list */ -+ list_for_each_entry(desc, &pch->work_list, node) { -+ if (desc->status == DONE) -+ transferred = desc->bytes_requested; -+ else if (running && desc == running) -+ transferred = -+ dma330_get_current_xferred_count(pch, desc); -+ else -+ transferred = 0; -+ residual += desc->bytes_requested - transferred; -+ if (desc->txd.cookie == cookie) { -+ switch (desc->status) { -+ case DONE: -+ ret = DMA_COMPLETE; -+ break; -+ case PREP: -+ case BUSY: -+ ret = DMA_IN_PROGRESS; -+ break; -+ default: -+ WARN_ON(1); -+ } -+ break; -+ } -+ if (desc->last) -+ residual = 0; -+ } -+ spin_unlock_irqrestore(&pch->lock, flags); -+ -+out: -+ dma_set_residue(txstate, residual); -+ -+ return ret; -+} -+ -+static void dma330_issue_pending(struct dma_chan *chan) -+{ -+ struct dma_dma330_chan *pch = to_pchan(chan); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&pch->lock, flags); -+ if (list_empty(&pch->work_list)) { -+ /* -+ * Warn on nothing pending. Empty submitted_list may -+ * break our pm_runtime usage counter as it is -+ * updated on work_list emptiness status. -+ */ -+ WARN_ON(list_empty(&pch->submitted_list)); -+ pm_runtime_get_sync(pch->dmac->ddma.dev); -+ } -+ list_splice_tail_init(&pch->submitted_list, &pch->work_list); -+ spin_unlock_irqrestore(&pch->lock, flags); -+ -+ dma330_tasklet((unsigned long)pch); -+} -+ -+/* -+ * We returned the last one of the circular list of descriptor(s) -+ * from prep_xxx, so the argument to submit corresponds to the last -+ * descriptor of the list. -+ */ -+static dma_cookie_t dma330_tx_submit(struct dma_async_tx_descriptor *tx) -+{ -+ struct dma_dma330_desc *desc, *last = to_desc(tx); -+ struct dma_dma330_chan *pch = to_pchan(tx->chan); -+ dma_cookie_t cookie; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&pch->lock, flags); -+ -+ /* Assign cookies to all nodes */ -+ while (!list_empty(&last->node)) { -+ desc = list_entry(last->node.next, struct dma_dma330_desc, node); -+ if (pch->cyclic) { -+ desc->txd.callback = last->txd.callback; -+ desc->txd.callback_param = last->txd.callback_param; -+ } -+ desc->last = false; -+ -+ dma_cookie_assign(&desc->txd); -+ -+ list_move_tail(&desc->node, &pch->submitted_list); -+ } -+ -+ last->last = true; -+ cookie = dma_cookie_assign(&last->txd); -+ list_add_tail(&last->node, &pch->submitted_list); -+ spin_unlock_irqrestore(&pch->lock, flags); -+ -+ return cookie; -+} -+ -+static inline void _init_desc(struct dma_dma330_desc *desc) -+{ -+#ifdef __LITTLE_ENDIAN -+ desc->rqcfg.swap = SWAP_NO; -+#else -+ desc->rqcfg.swap = SWAP_4; -+#endif /* __LITTLE_ENDIAN */ -+ desc->rqcfg.scctl = CCTRL0; -+ desc->rqcfg.dcctl = CCTRL0; -+ desc->txd.tx_submit = dma330_tx_submit; -+ -+ INIT_LIST_HEAD(&desc->node); -+} -+ -+/* Returns the number of descriptors added to the DMAC pool */ -+static int add_desc(struct dma330_dmac *dma330, gfp_t flg, int count) -+{ -+ struct dma_dma330_desc *desc; -+ unsigned long flags; -+ int i; -+ -+ desc = kcalloc(count, sizeof(*desc), flg); -+ if (!desc) -+ return 0; -+ -+ spin_lock_irqsave(&dma330->pool_lock, flags); -+ -+ for (i = 0; i < count; i++) { -+ _init_desc(&desc[i]); -+ list_add_tail(&desc[i].node, &dma330->desc_pool); -+ } -+ -+ spin_unlock_irqrestore(&dma330->pool_lock, flags); -+ -+ return count; -+} -+ -+static struct dma_dma330_desc *pluck_desc(struct dma330_dmac *dma330) -+{ -+ struct dma_dma330_desc *desc = NULL; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&dma330->pool_lock, flags); -+ -+ if (!list_empty(&dma330->desc_pool)) { -+ desc = list_entry(dma330->desc_pool.next, -+ struct dma_dma330_desc, node); -+ -+ list_del_init(&desc->node); -+ -+ desc->status = PREP; -+ desc->txd.callback = NULL; -+ } -+ -+ spin_unlock_irqrestore(&dma330->pool_lock, flags); -+ -+ return desc; -+} -+ -+static struct dma_dma330_desc *dma330_get_desc(struct dma_dma330_chan *pch) -+{ -+ struct dma330_dmac *dma330 = pch->dmac; -+ u8 *peri_id = pch->chan.private; -+ struct dma_dma330_desc *desc; -+ -+ /* Pluck one desc from the pool of DMAC */ -+ desc = pluck_desc(dma330); -+ -+ /* If the DMAC pool is empty, alloc new */ -+ if (!desc) { -+ if (!add_desc(dma330, GFP_ATOMIC, 1)) -+ return NULL; -+ -+ /* Try again */ -+ desc = pluck_desc(dma330); -+ if (!desc) { -+ dev_err(pch->dmac->ddma.dev, -+ "%s:%d ALERT!\n", __func__, __LINE__); -+ return NULL; -+ } -+ } -+ -+ /* Initialize the descriptor */ -+ desc->pchan = pch; -+ desc->txd.cookie = 0; -+ async_tx_ack(&desc->txd); -+ -+ desc->peri = peri_id ? pch->chan.chan_id : 0; -+ desc->rqcfg.pcfg = &pch->dmac->pcfg; -+ -+ dma_async_tx_descriptor_init(&desc->txd, &pch->chan); -+ -+ return desc; -+} -+ -+static inline void fill_px(struct dma330_xfer *px, -+ dma_addr_t dst, dma_addr_t src, size_t len) -+{ -+ px->bytes = len; -+ px->dst_addr = dst; -+ px->src_addr = src; -+} -+ -+static struct dma_dma330_desc * -+__dma330_prep_dma_memcpy(struct dma_dma330_chan *pch, dma_addr_t dst, -+ dma_addr_t src, size_t len) -+{ -+ struct dma_dma330_desc *desc = dma330_get_desc(pch); -+ -+ if (!desc) { -+ dev_err(pch->dmac->ddma.dev, "%s:%d Unable to fetch desc\n", -+ __func__, __LINE__); -+ return NULL; -+ } -+ -+ /* -+ * Ideally we should lookout for reqs bigger than -+ * those that can be programmed with 256 bytes of -+ * MC buffer, but considering a req size is seldom -+ * going to be word-unaligned and more than 200MB, -+ * we take it easy. -+ * Also, should the limit is reached we'd rather -+ * have the platform increase MC buffer size than -+ * complicating this API driver. -+ */ -+ fill_px(&desc->px, dst, src, len); -+ -+ return desc; -+} -+ -+/* Call after fixing burst size */ -+static inline int get_burst_len(struct dma_dma330_desc *desc, size_t len) -+{ -+ struct dma_dma330_chan *pch = desc->pchan; -+ struct dma330_dmac *dma330 = pch->dmac; -+ int burst_len; -+ -+ burst_len = dma330->pcfg.data_bus_width / 8; -+ burst_len *= dma330->pcfg.data_buf_dep / dma330->pcfg.num_chan; -+ burst_len >>= desc->rqcfg.brst_size; -+ -+ /* src/dst_burst_len can't be more than 16 */ -+ if (burst_len > 16) -+ burst_len = 16; -+ -+ while (burst_len > 1) { -+ if (!(len % (burst_len << desc->rqcfg.brst_size))) -+ break; -+ burst_len--; -+ } -+ -+ return burst_len; -+} -+ -+static struct dma_async_tx_descriptor *dma330_prep_dma_cyclic( -+ struct dma_chan *chan, dma_addr_t dma_addr, size_t len, -+ size_t period_len, enum dma_transfer_direction direction, -+ unsigned long flags) -+{ -+ struct dma_dma330_desc *desc = NULL, *first = NULL; -+ struct dma_dma330_chan *pch = to_pchan(chan); -+ struct dma330_dmac *dma330 = pch->dmac; -+ unsigned int i; -+ dma_addr_t dst; -+ dma_addr_t src; -+ -+ if (len % period_len != 0) -+ return NULL; -+ -+ if (!is_slave_direction(direction)) { -+ dev_err(pch->dmac->ddma.dev, "%s:%d Invalid dma direction\n", -+ __func__, __LINE__); -+ return NULL; -+ } -+ -+ for (i = 0; i < len / period_len; i++) { -+ desc = dma330_get_desc(pch); -+ if (!desc) { -+ dev_err(pch->dmac->ddma.dev, "%s:%d Unable to fetch desc\n", -+ __func__, __LINE__); -+ -+ if (!first) -+ return NULL; -+ -+ spin_lock_irqsave(&dma330->pool_lock, flags); -+ -+ while (!list_empty(&first->node)) { -+ desc = list_entry(first->node.next, -+ struct dma_dma330_desc, node); -+ list_move_tail(&desc->node, &dma330->desc_pool); -+ } -+ -+ list_move_tail(&first->node, &dma330->desc_pool); -+ -+ spin_unlock_irqrestore(&dma330->pool_lock, flags); -+ -+ return NULL; -+ } -+ -+ switch (direction) { -+ case DMA_MEM_TO_DEV: -+ desc->rqcfg.src_inc = 1; -+ desc->rqcfg.dst_inc = 0; -+ src = dma_addr; -+ dst = pch->fifo_addr; -+ break; -+ case DMA_DEV_TO_MEM: -+ desc->rqcfg.src_inc = 0; -+ desc->rqcfg.dst_inc = 1; -+ src = pch->fifo_addr; -+ dst = dma_addr; -+ break; -+ default: -+ break; -+ } -+ -+ desc->rqtype = direction; -+ desc->rqcfg.brst_size = pch->burst_sz; -+ desc->rqcfg.brst_len = pch->burst_len; -+ desc->bytes_requested = period_len; -+ fill_px(&desc->px, dst, src, period_len); -+ -+ if (!first) -+ first = desc; -+ else -+ list_add_tail(&desc->node, &first->node); -+ -+ dma_addr += period_len; -+ } -+ -+ if (!desc) -+ return NULL; -+ -+ pch->cyclic = true; -+ desc->txd.flags = flags; -+ -+ return &desc->txd; -+} -+ -+static struct dma_async_tx_descriptor * -+dma330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, -+ dma_addr_t src, size_t len, unsigned long flags) -+{ -+ struct dma_dma330_desc *desc; -+ struct dma_dma330_chan *pch = to_pchan(chan); -+ struct dma330_dmac *dma330; -+ int burst; -+ -+ if (unlikely(!pch || !len)) -+ return NULL; -+ -+ dma330 = pch->dmac; -+ -+ desc = __dma330_prep_dma_memcpy(pch, dst, src, len); -+ if (!desc) -+ return NULL; -+ -+ desc->rqcfg.src_inc = 1; -+ desc->rqcfg.dst_inc = 1; -+ desc->rqtype = DMA_MEM_TO_MEM; -+ -+ /* Select max possible burst size */ -+ burst = dma330->pcfg.data_bus_width / 8; -+ -+ /* -+ * Make sure we use a burst size that aligns with all the memcpy -+ * parameters because our DMA programming algorithm doesn't cope with -+ * transfers which straddle an entry in the DMA device's MFIFO. -+ */ -+ while ((src | dst | len) & (burst - 1)) -+ burst /= 2; -+ -+ desc->rqcfg.brst_size = 0; -+ while (burst != (1 << desc->rqcfg.brst_size)) -+ desc->rqcfg.brst_size++; -+ -+ /* -+ * If burst size is smaller than bus width then make sure we only -+ * transfer one at a time to avoid a burst stradling an MFIFO entry. -+ */ -+ if (desc->rqcfg.brst_size * 8 < dma330->pcfg.data_bus_width) -+ desc->rqcfg.brst_len = 1; -+ -+ desc->rqcfg.brst_len = get_burst_len(desc, len); -+ desc->bytes_requested = len; -+ -+ desc->txd.flags = flags; -+ -+ return &desc->txd; -+} -+ -+static void __dma330_giveback_desc(struct dma330_dmac *dma330, -+ struct dma_dma330_desc *first) -+{ -+ unsigned long flags; -+ struct dma_dma330_desc *desc; -+ -+ if (!first) -+ return; -+ -+ spin_lock_irqsave(&dma330->pool_lock, flags); -+ -+ while (!list_empty(&first->node)) { -+ desc = list_entry(first->node.next, -+ struct dma_dma330_desc, node); -+ list_move_tail(&desc->node, &dma330->desc_pool); -+ } -+ -+ list_move_tail(&first->node, &dma330->desc_pool); -+ -+ spin_unlock_irqrestore(&dma330->pool_lock, flags); -+} -+ -+static struct dma_async_tx_descriptor * -+dma330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, -+ unsigned int sg_len, enum dma_transfer_direction direction, -+ unsigned long flg, void *context) -+{ -+ struct dma_dma330_desc *first, *desc = NULL; -+ struct dma_dma330_chan *pch = to_pchan(chan); -+ struct scatterlist *sg; -+ int i; -+ dma_addr_t addr; -+ -+ if (unlikely(!pch || !sgl || !sg_len)) -+ return NULL; -+ -+ addr = pch->fifo_addr; -+ -+ first = NULL; -+ -+ for_each_sg(sgl, sg, sg_len, i) { -+ -+ desc = dma330_get_desc(pch); -+ if (!desc) { -+ struct dma330_dmac *dma330 = pch->dmac; -+ -+ dev_err(pch->dmac->ddma.dev, -+ "%s:%d Unable to fetch desc\n", -+ __func__, __LINE__); -+ __dma330_giveback_desc(dma330, first); -+ -+ return NULL; -+ } -+ -+ if (!first) -+ first = desc; -+ else -+ list_add_tail(&desc->node, &first->node); -+ -+ if (direction == DMA_MEM_TO_DEV) { -+ desc->rqcfg.src_inc = 1; -+ desc->rqcfg.dst_inc = 0; -+ fill_px(&desc->px, -+ addr, sg_dma_address(sg), sg_dma_len(sg)); -+ } else { -+ desc->rqcfg.src_inc = 0; -+ desc->rqcfg.dst_inc = 1; -+ fill_px(&desc->px, -+ sg_dma_address(sg), addr, sg_dma_len(sg)); -+ } -+ -+ desc->rqcfg.brst_size = pch->burst_sz; -+ desc->rqcfg.brst_len = pch->burst_len; -+ desc->rqtype = direction; -+ desc->bytes_requested = sg_dma_len(sg); -+ } -+ -+ /* Return the last desc in the chain */ -+ desc->txd.flags = flg; -+ return &desc->txd; -+} -+ -+static irqreturn_t dma330_irq_handler(int irq, void *data) -+{ -+ if (dma330_update(data)) -+ return IRQ_HANDLED; -+ else -+ return IRQ_NONE; -+} -+ -+#define DMA330_DMA_BUSWIDTHS \ -+ BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) | \ -+ BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ -+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ -+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \ -+ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES) -+ -+/* -+ * Runtime PM callbacks are provided by amba/bus.c driver. -+ * -+ * It is assumed here that IRQ safe runtime PM is chosen in probe and amba -+ * bus driver will only disable/enable the clock in runtime PM callbacks. -+ */ -+static int __maybe_unused iproc_dma330_suspend(struct device *dev) -+{ -+ struct amba_device *pcdev = to_amba_device(dev); -+ -+ pm_runtime_disable(dev); -+ -+ if (!pm_runtime_status_suspended(dev)) { -+ /* amba did not disable the clock */ -+ amba_pclk_disable(pcdev); -+ } -+ amba_pclk_unprepare(pcdev); -+ -+ return 0; -+} -+ -+static int __maybe_unused iproc_dma330_resume(struct device *dev) -+{ -+ struct amba_device *pcdev = to_amba_device(dev); -+ int ret; -+ -+ ret = amba_pclk_prepare(pcdev); -+ if (ret) -+ return ret; -+ -+ if (!pm_runtime_status_suspended(dev)) -+ ret = amba_pclk_enable(pcdev); -+ -+ pm_runtime_enable(dev); -+ -+ return ret; -+} -+ -+static SIMPLE_DEV_PM_OPS(iproc_dma330_pm, iproc_dma330_suspend, iproc_dma330_resume); -+ -+static int -+iproc_dma330_probe(struct amba_device *adev, const struct amba_id *id) -+{ -+ struct dma_dma330_platdata *pdat; -+ struct dma330_config *pcfg; -+ struct dma330_dmac *dma330; -+ struct dma_dma330_chan *pch, *_p; -+ struct dma_device *pd; -+ struct resource *res; -+ int i, ret, irq; -+ int num_chan; -+ -+ pdat = dev_get_platdata(&adev->dev); -+ -+ ret = dma_set_mask_and_coherent(&adev->dev, DMA_BIT_MASK(32)); -+ if (ret) -+ return ret; -+ -+ /* Allocate a new DMAC and its Channels */ -+ dma330 = devm_kzalloc(&adev->dev, sizeof(*dma330), GFP_KERNEL); -+ if (!dma330) { -+ dev_err(&adev->dev, "unable to allocate mem\n"); -+ return -ENOMEM; -+ } -+ -+ pd = &dma330->ddma; -+ pd->dev = &adev->dev; -+ -+ dma330->mcbufsz = pdat ? pdat->mcbuf_sz : 0; -+ -+ res = &adev->res; -+ dma330->base = devm_ioremap_resource(&adev->dev, res); -+ if (IS_ERR(dma330->base)) -+ return PTR_ERR(dma330->base); -+ -+ amba_set_drvdata(adev, dma330); -+ -+ for (i = 0; i < AMBA_NR_IRQS; i++) { -+ irq = adev->irq[i]; -+ if (irq) { -+ ret = devm_request_irq(&adev->dev, irq, -+ dma330_irq_handler, 0, -+ dev_name(&adev->dev), dma330); -+ if (ret) -+ return ret; -+ } else { -+ break; -+ } -+ } -+ -+ pcfg = &dma330->pcfg; -+ -+ pcfg->periph_id = adev->periphid; -+ ret = dma330_add(dma330); -+ if (ret) -+ return ret; -+ -+ INIT_LIST_HEAD(&dma330->desc_pool); -+ spin_lock_init(&dma330->pool_lock); -+ -+ /* Create a descriptor pool of default size */ -+ if (!add_desc(dma330, GFP_KERNEL, NR_DEFAULT_DESC)) -+ dev_warn(&adev->dev, "unable to allocate desc\n"); -+ -+ INIT_LIST_HEAD(&pd->channels); -+ -+ /* Initialize channel parameters */ -+ if (pdat) -+ num_chan = max_t(int, pdat->nr_valid_peri, pcfg->num_chan); -+ else -+ num_chan = max_t(int, pcfg->num_peri, pcfg->num_chan); -+ -+ dma330->num_peripherals = num_chan; -+ -+ dma330->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL); -+ if (!dma330->peripherals) { -+ ret = -ENOMEM; -+ dev_err(&adev->dev, "unable to allocate dma330->peripherals\n"); -+ goto probe_err2; -+ } -+ -+ for (i = 0; i < num_chan; i++) { -+ pch = &dma330->peripherals[i]; -+ if (!adev->dev.of_node) -+ pch->chan.private = pdat ? &pdat->peri_id[i] : NULL; -+ else -+ pch->chan.private = adev->dev.of_node; -+ -+ INIT_LIST_HEAD(&pch->submitted_list); -+ INIT_LIST_HEAD(&pch->work_list); -+ INIT_LIST_HEAD(&pch->completed_list); -+ spin_lock_init(&pch->lock); -+ pch->thread = NULL; -+ pch->chan.device = pd; -+ pch->dmac = dma330; -+ -+ /* Add the channel to the DMAC list */ -+ list_add_tail(&pch->chan.device_node, &pd->channels); -+ } -+ -+ if (pdat) { -+ pd->cap_mask = pdat->cap_mask; -+ } else { -+ dma_cap_set(DMA_MEMCPY, pd->cap_mask); -+ if (pcfg->num_peri) { -+ dma_cap_set(DMA_SLAVE, pd->cap_mask); -+ dma_cap_set(DMA_CYCLIC, pd->cap_mask); -+ dma_cap_set(DMA_PRIVATE, pd->cap_mask); -+ } -+ } -+ -+ pd->device_alloc_chan_resources = dma330_alloc_chan_resources; -+ pd->device_free_chan_resources = dma330_free_chan_resources; -+ pd->device_prep_dma_memcpy = dma330_prep_dma_memcpy; -+ pd->device_prep_dma_cyclic = dma330_prep_dma_cyclic; -+ pd->device_tx_status = dma330_tx_status; -+ pd->device_prep_slave_sg = dma330_prep_slave_sg; -+ pd->device_config = dma330_config; -+ pd->device_pause = dma330_pause; -+ pd->device_terminate_all = dma330_terminate_all; -+ pd->device_issue_pending = dma330_issue_pending; -+ pd->src_addr_widths = DMA330_DMA_BUSWIDTHS; -+ pd->dst_addr_widths = DMA330_DMA_BUSWIDTHS; -+ pd->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); -+ pd->residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; -+ -+ ret = dma_async_device_register(pd); -+ if (ret) { -+ dev_err(&adev->dev, "unable to register DMAC\n"); -+ goto probe_err3; -+ } -+ -+ if (adev->dev.of_node) { -+ ret = of_dma_controller_register(adev->dev.of_node, -+ of_dma_dma330_xlate, dma330); -+ if (ret) { -+ dev_err(&adev->dev, -+ "unable to register DMA to the generic DT DMA helpers\n"); -+ } -+ } -+ -+ adev->dev.dma_parms = &dma330->dma_parms; -+ -+ /* -+ * This is the limit for transfers with a buswidth of 1, larger -+ * buswidths will have larger limits. -+ */ -+ ret = dma_set_max_seg_size(&adev->dev, 1900800); -+ if (ret) -+ dev_err(&adev->dev, "unable to set the seg size\n"); -+ -+ -+ dev_info(&adev->dev, -+ "Loaded driver for DMA330 DMAC-%x\n", adev->periphid); -+ dev_info(&adev->dev, -+ "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n", -+ pcfg->data_buf_dep, pcfg->data_bus_width / 8, pcfg->num_chan, -+ pcfg->num_peri, pcfg->num_events); -+ -+ pm_runtime_irq_safe(&adev->dev); -+ pm_runtime_use_autosuspend(&adev->dev); -+ pm_runtime_set_autosuspend_delay(&adev->dev, DMA330_AUTOSUSPEND_DELAY); -+ pm_runtime_mark_last_busy(&adev->dev); -+ pm_runtime_put_autosuspend(&adev->dev); -+ -+ return 0; -+probe_err3: -+ /* Idle the DMAC */ -+ list_for_each_entry_safe(pch, _p, &dma330->ddma.channels, -+ chan.device_node) { -+ -+ /* Remove the channel */ -+ list_del(&pch->chan.device_node); -+ -+ /* Flush the channel */ -+ if (pch->thread) { -+ dma330_terminate_all(&pch->chan); -+ dma330_free_chan_resources(&pch->chan); -+ } -+ } -+probe_err2: -+ dma330_del(dma330); -+ -+ return ret; -+} -+ -+static int iproc_dma330_remove(struct amba_device *adev) -+{ -+ struct dma330_dmac *dma330 = amba_get_drvdata(adev); -+ struct dma_dma330_chan *pch, *_p; -+ -+ pm_runtime_get_noresume(dma330->ddma.dev); -+ -+ if (adev->dev.of_node) -+ of_dma_controller_free(adev->dev.of_node); -+ -+ dma_async_device_unregister(&dma330->ddma); -+ -+ /* Idle the DMAC */ -+ list_for_each_entry_safe(pch, _p, &dma330->ddma.channels, -+ chan.device_node) { -+ -+ /* Remove the channel */ -+ list_del(&pch->chan.device_node); -+ -+ /* Flush the channel */ -+ if (pch->thread) { -+ dma330_terminate_all(&pch->chan); -+ dma330_free_chan_resources(&pch->chan); -+ } -+ } -+ -+ dma330_del(dma330); -+ -+ return 0; -+} -+ -+static struct amba_id iproc_dma330_ids[] = { -+ { -+ .id = 0x00241330, -+ .mask = 0x00ffffff, -+ }, -+ { 0, 0 }, -+}; -+ -+MODULE_DEVICE_TABLE(amba, iproc_dma330_ids); -+ -+static struct amba_driver iproc_dma330_driver = { -+ .drv = { -+ .owner = THIS_MODULE, -+ .name = "dma-dma330", -+ .pm = &iproc_dma330_pm, -+ }, -+ .id_table = iproc_dma330_ids, -+ .probe = iproc_dma330_probe, -+ .remove = iproc_dma330_remove, -+}; -+ -+module_amba_driver(iproc_dma330_driver); -+ -+MODULE_DESCRIPTION("API Driver for DMA330 DMAC"); -+MODULE_LICENSE("GPL"); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig ---- a/drivers/gpio/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/gpio/Kconfig 2017-11-09 17:53:27.600169000 +0800 -@@ -142,6 +142,15 @@ config GPIO_BRCMSTB - help - Say yes here to enable GPIO support for Broadcom STB (BCM7XXX) SoCs. - -+config GPIO_XGS_IPROC -+ tristate "BRCM XGS iProc GPIO support" -+ default y if ARCH_XGS_IPROC -+ depends on OF_GPIO && (ARCH_XGS_IPROC || COMPILE_TEST) -+ select GPIO_GENERIC -+ select GPIOLIB_IRQCHIP -+ help -+ Say yes here to enable GPIO support for Broadcom XGS iProc SoCs. -+ - config GPIO_CLPS711X - tristate "CLPS711X GPIO support" - depends on ARCH_CLPS711X || COMPILE_TEST -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/gpio/Makefile b/drivers/gpio/Makefile ---- a/drivers/gpio/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/gpio/Makefile 2017-11-09 17:53:27.601169000 +0800 -@@ -25,6 +25,7 @@ obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizo - obj-$(CONFIG_ATH79) += gpio-ath79.o - obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o - obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o -+obj-$(CONFIG_GPIO_XGS_IPROC) += gpio-xgs-iproc.o - obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o - obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o - obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/gpio/gpio-xgs-iproc.c b/drivers/gpio/gpio-xgs-iproc.c ---- a/drivers/gpio/gpio-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/gpio/gpio-xgs-iproc.c 2017-11-09 17:53:27.757170000 +0800 -@@ -0,0 +1,815 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "gpio-xgs-iproc.h" -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37) -+#define irq_get_chip_data get_irq_chip_data -+#define irq_set_chip_data set_irq_chip_data -+#define irq_set_chip set_irq_chip -+#define irq_set_handler set_irq_handler -+#define status_use_accessors status -+#endif -+ -+ -+#define IPROC_CCA_INT_F_GPIOINT 1 -+#define IPROC_CCA_INT_MASK 0x24 -+#define IPROC_GPIO_CCA_DIN 0x0 -+#define IPROC_GPIO_CCA_INT_LEVEL 0x10 -+#define IPROC_GPIO_CCA_INT_LEVEL_MASK 0x14 -+#define IPROC_GPIO_CCA_INT_EVENT 0x18 -+#define IPROC_GPIO_CCA_INT_EVENT_MASK 0x1C -+#define IPROC_CCA_INT_STS 0x20 -+#define IPROC_GPIO_CCA_INT_EDGE 0x24 -+ -+#define IPROC_GPIO_CCB_INT_TYPE 0xC -+#define IPROC_GPIO_CCB_INT_DE 0x10 -+#define IPROC_GPIO_CCB_INT_EDGE 0x14 -+#define IPROC_GPIO_CCB_INT_MSTAT 0x20 -+#define IPROC_GPIO_CCB_INT_CLR 0x24 -+#define IPROC_GPIO_CCB_INT_MASK 0x18 -+ -+ -+static unsigned int _iproc_gpio_readl(struct iproc_gpio_chip *chip, int reg) -+{ -+ return readl(chip->ioaddr + reg); -+} -+ -+static void _iproc_gpio_writel(struct iproc_gpio_chip *chip, unsigned int val, int reg) -+{ -+ writel(val, chip->ioaddr + reg); -+} -+ -+ -+/* -+@ pin : the actual pin number of the gpiochip -+*/ -+static int iproc_gpio_to_irq(struct iproc_gpio_chip *chip, unsigned int pin) { -+ return irq_linear_revmap(chip->irq_domain, pin - chip->pin_offset); -+} -+ -+/* -+returns the actual pin number of the gpiochip -+*/ -+static int iproc_irq_to_gpio(struct iproc_gpio_chip *chip, unsigned int irq) { -+ struct irq_data *data = irq_domain_get_irq_data(chip->irq_domain, irq); -+ -+ return data->hwirq + chip->pin_offset; -+} -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 5) -+static void iproc_gpio_irq_ack(unsigned int irq) -+{ -+#else -+static void iproc_gpio_irq_ack(struct irq_data *d) -+{ -+ unsigned int irq = d->irq; -+#endif -+ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); -+ -+ if (ourchip) { -+ struct iproc_gpio_irqcfg *irqcfg = ourchip->irqcfg; -+ if (irqcfg && irqcfg->ack) -+ irqcfg->ack(irq); -+ -+ } -+} -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 5) -+static void iproc_gpio_irq_unmask(unsigned int irq) -+{ -+#else -+static void iproc_gpio_irq_unmask(struct irq_data *d) -+{ -+ unsigned int irq = d->irq; -+#endif -+ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); -+ -+ if (ourchip) { -+ struct iproc_gpio_irqcfg *irqcfg = ourchip->irqcfg; -+ if (irqcfg && irqcfg->unmask) -+ irqcfg->unmask(irq); -+ } -+} -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 5) -+static void iproc_gpio_irq_mask(unsigned int irq) -+{ -+#else -+static void iproc_gpio_irq_mask(struct irq_data *d) -+{ -+ unsigned int irq = d->irq; -+#endif -+ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); -+ -+ if (ourchip) { -+ struct iproc_gpio_irqcfg *irqcfg = ourchip->irqcfg; -+ if (irqcfg && irqcfg->mask) -+ irqcfg->mask(irq); -+ } -+} -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 5) -+static int iproc_gpio_irq_set_type(unsigned int irq, unsigned int type) -+{ -+#else -+static int iproc_gpio_irq_set_type(struct irq_data *d, unsigned int type) -+{ -+ unsigned int irq = d->irq; -+#endif -+ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); -+ -+ if (ourchip) { -+ struct iproc_gpio_irqcfg *irqcfg = ourchip->irqcfg; -+ if (irqcfg && irqcfg->set_type) -+ return irqcfg->set_type(irq, type); -+ } -+ return -EINVAL; -+} -+ -+#if defined(IPROC_GPIO_CCA) -+static irqreturn_t iproc_gpio_irq_handler_cca(int irq, void *data) -+{ -+ struct iproc_gpio_chip *iproc_gpio = (struct iproc_gpio_chip *)data; -+ struct gpio_chip gc = iproc_gpio->chip; -+ int bit; -+ unsigned long int_bits = 0; -+ u32 int_status; -+ -+ /* go through the entire GPIOs and handle all interrupts */ -+ int_status = readl(iproc_gpio->intr_ioaddr + IPROC_CCA_INT_STS); -+ if (int_status & IPROC_CCA_INT_F_GPIOINT) { -+ unsigned int event, level; -+ -+ /* Get level and edge interrupts */ -+ event = readl(iproc_gpio->ioaddr + IPROC_GPIO_CCA_INT_EVENT_MASK) & readl(iproc_gpio->ioaddr + IPROC_GPIO_CCA_INT_EVENT); -+ level = readl(iproc_gpio->ioaddr + IPROC_GPIO_CCA_DIN) ^ -+ readl(iproc_gpio->ioaddr + IPROC_GPIO_CCA_INT_LEVEL); -+ level &= readl(iproc_gpio->ioaddr + IPROC_GPIO_CCA_INT_LEVEL_MASK); -+ int_bits = level | event; -+ -+ for_each_set_bit(bit, &int_bits, gc.ngpio) -+ generic_handle_irq( -+ irq_linear_revmap(iproc_gpio->irq_domain, bit)); -+ } -+ -+ return int_bits ? IRQ_HANDLED : IRQ_NONE; -+} -+ -+ -+static void iproc_gpio_irq_ack_cca(unsigned int irq) -+{ -+ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); -+ int pin; -+ -+ pin = iproc_irq_to_gpio(ourchip, irq); -+ -+ if (ourchip->id == IPROC_GPIO_CCA_ID) { -+ unsigned int event_status, irq_type; -+ -+ event_status = 0; -+ irq_type = irq_get_trigger_type(irq); -+ if (irq_type & IRQ_TYPE_EDGE_BOTH) -+ { -+ event_status |= (1 << pin); -+ _iproc_gpio_writel(ourchip, event_status, -+ IPROC_GPIO_CCA_INT_EVENT); -+ } -+ -+ } -+} -+ -+static void iproc_gpio_irq_unmask_cca(unsigned int irq) -+{ -+ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); -+ int pin; -+ unsigned int int_mask, irq_type; -+ -+ pin = iproc_irq_to_gpio(ourchip, irq); -+ irq_type = irq_get_trigger_type(irq); -+ -+ if (ourchip->id == IPROC_GPIO_CCA_ID) { -+ unsigned int event_mask; -+ -+ event_mask = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCA_INT_EVENT_MASK); -+ int_mask = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCA_INT_LEVEL_MASK); -+ -+ if (irq_type & IRQ_TYPE_EDGE_BOTH) { -+ event_mask |= 1 << pin; -+ _iproc_gpio_writel(ourchip, event_mask, -+ IPROC_GPIO_CCA_INT_EVENT_MASK); -+ } else { -+ int_mask |= 1 << pin; -+ _iproc_gpio_writel(ourchip, int_mask, -+ IPROC_GPIO_CCA_INT_LEVEL_MASK); -+ } -+ } -+ -+} -+ -+static void iproc_gpio_irq_mask_cca(unsigned int irq) -+{ -+ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); -+ int pin; -+ unsigned int irq_type, int_mask; -+ -+ pin = iproc_irq_to_gpio(ourchip, irq); -+ irq_type = irq_get_trigger_type(irq); -+ -+ if (ourchip->id == IPROC_GPIO_CCA_ID) { -+ unsigned int event_mask; -+ -+ event_mask = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCA_INT_EVENT_MASK); -+ int_mask = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCA_INT_LEVEL_MASK); -+ -+ if (irq_type & IRQ_TYPE_EDGE_BOTH) { -+ event_mask &= ~(1 << pin); -+ _iproc_gpio_writel(ourchip, event_mask, -+ IPROC_GPIO_CCA_INT_EVENT_MASK); -+ } else { -+ int_mask &= ~(1 << pin); -+ _iproc_gpio_writel(ourchip, int_mask, -+ IPROC_GPIO_CCA_INT_LEVEL_MASK); -+ } -+ } -+} -+ -+static int iproc_gpio_irq_set_type_cca(unsigned int irq, unsigned int type) -+{ -+ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); -+ int pin; -+ -+ pin = iproc_irq_to_gpio(ourchip, irq); -+ -+ if (ourchip->id == IPROC_GPIO_CCA_ID) { -+ unsigned int event_pol, int_pol; -+ -+ switch (type & IRQ_TYPE_SENSE_MASK) { -+ case IRQ_TYPE_EDGE_RISING: -+ event_pol = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCA_INT_EDGE); -+ event_pol &= ~(1 << pin); -+ _iproc_gpio_writel(ourchip, event_pol, IPROC_GPIO_CCA_INT_EDGE); -+ break; -+ case IRQ_TYPE_EDGE_FALLING: -+ event_pol = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCA_INT_EDGE); -+ event_pol |= (1 << pin); -+ _iproc_gpio_writel(ourchip, event_pol, IPROC_GPIO_CCA_INT_EDGE); -+ break; -+ case IRQ_TYPE_LEVEL_HIGH: -+ int_pol = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCA_INT_LEVEL); -+ int_pol &= ~(1 << pin); -+ _iproc_gpio_writel(ourchip, int_pol, IPROC_GPIO_CCA_INT_LEVEL); -+ break; -+ case IRQ_TYPE_LEVEL_LOW: -+ int_pol = _iproc_gpio_readl(ourchip,IPROC_GPIO_CCA_INT_LEVEL); -+ int_pol |= (1 << pin); -+ _iproc_gpio_writel(ourchip, int_pol, IPROC_GPIO_CCA_INT_LEVEL); -+ break; -+ default: -+ printk(KERN_ERR "unsupport irq type !\n"); -+ return -EINVAL; -+ } -+ } -+ -+ if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) -+ irq_set_handler_locked(irq_get_irq_data(irq), handle_level_irq); -+ else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) -+ irq_set_handler_locked(irq_get_irq_data(irq), handle_edge_irq); -+ -+ return 0; -+} -+ -+struct iproc_gpio_irqcfg cca_gpio_irqcfg = { -+ /* Remove IRQF_NO_SUSPEND to be consistent with 8250_core.c setting -+ * since CCA gpio and uart share the same IRQ. -+ */ -+ .flags = IRQF_SHARED, -+ .handler = iproc_gpio_irq_handler_cca, -+ .ack = iproc_gpio_irq_ack_cca, -+ .mask = iproc_gpio_irq_mask_cca, -+ .unmask = iproc_gpio_irq_unmask_cca, -+ .set_type = iproc_gpio_irq_set_type_cca, -+}; -+#endif /* IPROC_GPIO_CCA */ -+ -+#if defined(IPROC_GPIO_CCB) || defined(IPROC_GPIO_CCG) -+static irqreturn_t -+iproc_gpio_irq_handler_ccb(int irq, void *dev) -+{ -+ struct iproc_gpio_chip *ourchip = dev; -+ int iter, max_pin; -+ unsigned int val; -+ -+ val = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCB_INT_MSTAT); -+ if(!val){ -+ return IRQ_NONE; -+ } -+ -+ max_pin = ourchip->pin_offset + ourchip->chip.ngpio; -+ for (iter = ourchip->pin_offset; iter < max_pin; iter ++) { -+ if (val & (1 << iter)) { -+ //writel(1 << iter, ourchip->ioaddr + IPROC_GPIO_CCB_INT_CLR); -+ generic_handle_irq(iproc_gpio_to_irq(ourchip, iter)); -+ } -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static void iproc_gpio_irq_ack_ccb(unsigned int irq) -+{ -+ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); -+ int pin; -+ -+ pin = iproc_irq_to_gpio(ourchip, irq); -+ -+ if ((ourchip->id == IPROC_GPIO_CCB_ID) || -+ (ourchip->id == IPROC_GPIO_CCG_ID)) { -+ unsigned int int_clear = 0; -+ -+ int_clear |= (1 << pin); -+ _iproc_gpio_writel(ourchip, int_clear, IPROC_GPIO_CCB_INT_CLR); -+ -+ } -+} -+ -+static void iproc_gpio_irq_unmask_ccb(unsigned int irq) -+{ -+ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); -+ int pin; -+ unsigned int int_mask; -+ -+ pin = iproc_irq_to_gpio(ourchip, irq); -+ -+ if ((ourchip->id == IPROC_GPIO_CCB_ID) || -+ (ourchip->id == IPROC_GPIO_CCG_ID)) { -+ int_mask = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCB_INT_MASK); -+ int_mask |= (1 << pin); -+ _iproc_gpio_writel(ourchip, int_mask, IPROC_GPIO_CCB_INT_MASK); -+ } -+ -+} -+ -+static void iproc_gpio_irq_mask_ccb(unsigned int irq) -+{ -+ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); -+ int pin; -+ unsigned int int_mask; -+ -+ pin = iproc_irq_to_gpio(ourchip, irq); -+ -+ if ((ourchip->id == IPROC_GPIO_CCB_ID) || -+ (ourchip->id == IPROC_GPIO_CCG_ID)) { -+ int_mask = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCB_INT_MASK); -+ int_mask &= ~(1 << pin); -+ _iproc_gpio_writel(ourchip, int_mask,IPROC_GPIO_CCB_INT_MASK); -+ } -+} -+ -+static int iproc_gpio_irq_set_type_ccb(unsigned int irq, unsigned int type) -+{ -+ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); -+ int pin; -+ -+ -+ pin = iproc_irq_to_gpio(ourchip, irq); -+ -+ if ((ourchip->id == IPROC_GPIO_CCB_ID) || -+ (ourchip->id == IPROC_GPIO_CCG_ID)) { -+ unsigned int int_type, int_de, int_edge; -+ int_type = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCB_INT_TYPE); -+ int_edge = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCB_INT_EDGE); -+ switch (type) { -+ case IRQ_TYPE_EDGE_BOTH: -+ int_type &= ~(1 << pin); -+ int_de = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCB_INT_DE); -+ int_de |= (1 << pin); -+ _iproc_gpio_writel(ourchip, int_de, IPROC_GPIO_CCB_INT_DE); -+ break; -+ case IRQ_TYPE_EDGE_RISING: -+ int_type &= ~(1 << pin); -+ int_edge |= (1 << pin); -+ -+ int_de = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCB_INT_DE); -+ int_de &= ~(1 << pin); -+ _iproc_gpio_writel(ourchip, int_de, IPROC_GPIO_CCB_INT_DE); -+ break; -+ case IRQ_TYPE_EDGE_FALLING: -+ int_type &= ~(1 << pin); -+ int_edge &= ~(1 << pin); -+ -+ int_de = _iproc_gpio_readl(ourchip, IPROC_GPIO_CCB_INT_DE); -+ int_de &= ~(1 << pin); -+ _iproc_gpio_writel(ourchip, int_de, IPROC_GPIO_CCB_INT_DE); -+ break; -+ case IRQ_TYPE_LEVEL_HIGH: -+ int_type |= (1 << pin); -+ int_edge |= (1 << pin); -+ break; -+ case IRQ_TYPE_LEVEL_LOW: -+ int_type |= (1 << pin); -+ int_edge &= ~(1 << pin); -+ break; -+ default: -+ printk(KERN_ERR "unsupport irq type !\n"); -+ return -EINVAL; -+ } -+ _iproc_gpio_writel(ourchip, int_type, IPROC_GPIO_CCB_INT_TYPE); -+ _iproc_gpio_writel(ourchip, int_edge, IPROC_GPIO_CCB_INT_EDGE); -+ } -+ -+ if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) -+ irq_set_handler_locked(irq_get_irq_data(irq), handle_level_irq); -+ else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) -+ irq_set_handler_locked(irq_get_irq_data(irq), handle_edge_irq); -+ -+ return 0; -+} -+ -+struct iproc_gpio_irqcfg ccb_gpio_irqcfg = { -+ .flags = IRQF_NO_SUSPEND, -+ .handler = iproc_gpio_irq_handler_ccb, -+ .ack = iproc_gpio_irq_ack_ccb, -+ .mask = iproc_gpio_irq_mask_ccb, -+ .unmask = iproc_gpio_irq_unmask_ccb, -+ .set_type = iproc_gpio_irq_set_type_ccb, -+}; -+#endif /* IPROC_GPIO_CCB || IPROC_GPIO_CCG*/ -+ -+static struct irq_chip iproc_gpio_irq_chip = { -+ .name = "IPROC-GPIO", -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 5) -+ .ack = (void *) iproc_gpio_irq_ack, -+ .mask = (void *) iproc_gpio_irq_mask, -+ .unmask = (void *) iproc_gpio_irq_unmask, -+ .set_type = (void *) iproc_gpio_irq_set_type, -+#else -+ .irq_ack = (void *) iproc_gpio_irq_ack, -+ .irq_mask = (void *) iproc_gpio_irq_mask, -+ .irq_unmask = (void *) iproc_gpio_irq_unmask, -+ .irq_set_type = (void *) iproc_gpio_irq_set_type, -+#endif -+}; -+ -+ -+static int iproc_gpiolib_input(struct gpio_chip *chip, unsigned gpio) -+{ -+ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); -+ unsigned long flags; -+ unsigned int val, nBitMask; -+ int reg_offset; -+ unsigned int pin_offset = gpio + ourchip->pin_offset; -+ -+ iproc_gpio_lock(ourchip, flags); -+ -+ nBitMask = 1 << pin_offset; -+ reg_offset = REGOFFSET_GPIO_EN; -+ -+ val = _iproc_gpio_readl(ourchip, reg_offset); -+ val &= ~nBitMask; -+ _iproc_gpio_writel(ourchip, val, reg_offset); -+ -+ iproc_gpio_unlock(ourchip, flags); -+ return 0; -+} -+ -+static int iproc_gpiolib_output(struct gpio_chip *chip, -+ unsigned gpio, int value) -+{ -+ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); -+ unsigned long flags, val; -+ unsigned int nBitMask; -+ int reg_offset; -+ unsigned int pin_offset = gpio + ourchip->pin_offset; -+ -+ iproc_gpio_lock(ourchip, flags); -+ -+ nBitMask = 1 << pin_offset; -+ reg_offset = REGOFFSET_GPIO_EN; -+ -+ val = _iproc_gpio_readl(ourchip, reg_offset); -+ val |= nBitMask; -+ _iproc_gpio_writel(ourchip, val, reg_offset); -+ -+ iproc_gpio_unlock(ourchip, flags); -+ return 0; -+} -+ -+static void iproc_gpiolib_set(struct gpio_chip *chip, -+ unsigned gpio, int value) -+{ -+ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); -+ unsigned long flags, val; -+ unsigned int nBitMask; -+ int reg_offset = 0; -+ unsigned int pin_offset = gpio + ourchip->pin_offset; -+ -+ iproc_gpio_lock(ourchip, flags); -+ -+ nBitMask = 1 << pin_offset; -+ -+ val = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_EN + reg_offset); -+ val &= nBitMask; -+ -+ /* this function only applies to output pin -+ */ -+ if (!val) -+ return; -+ -+ val = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_DOUT + reg_offset); -+ -+ if ( value == 0 ){ -+ /* Set the pin to zero */ -+ val &= ~nBitMask; -+ }else{ -+ /* Set the pin to 1 */ -+ val |= nBitMask; -+ } -+ _iproc_gpio_writel(ourchip, val, REGOFFSET_GPIO_DOUT + reg_offset); -+ -+ iproc_gpio_unlock(ourchip, flags); -+ -+} -+ -+ -+static int iproc_gpiolib_get(struct gpio_chip *chip, unsigned gpio) -+{ -+ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); -+ unsigned long flags; -+ unsigned int val, offset, nBitMask; -+ int reg_offset = 0; -+ unsigned int pin_offset = gpio + ourchip->pin_offset; -+ -+ iproc_gpio_lock(ourchip, flags); -+ -+ nBitMask = 1 << pin_offset; -+ -+ /* determine the GPIO pin direction -+ */ -+ offset = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_EN + reg_offset); -+ offset &= nBitMask; -+ -+ if (offset){ -+ val = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_DOUT + reg_offset); -+ } else { -+ val = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_DIN + reg_offset); -+ } -+ -+ val >>= pin_offset; -+ -+ val &= 1; -+ -+ iproc_gpio_unlock(ourchip, flags); -+ -+ return val; -+} -+ -+/* -+@offset : the gpio pin index number from gpiolib view (minus gpio base only) -+*/ -+static int iproc_gpiolib_to_irq(struct gpio_chip *chip, -+ unsigned offset) -+{ -+ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); -+ return irq_linear_revmap(ourchip->irq_domain, offset); -+} -+ -+static struct __initconst of_device_id bcm_iproc_gpio_of_match[] = { -+ { .compatible = "brcm,iproc-gpio,cca" }, -+ { .compatible = "brcm,iproc-gpio,ccb" }, -+ { .compatible = "brcm,iproc-gpio,ccg" }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, bcm_iproc_gpio_of_match); -+ -+void iproc_gpiolib_add(struct iproc_gpio_chip *chip) -+{ -+ struct gpio_chip *gc = &chip->chip; -+ int ret; -+ -+ BUG_ON(!gc->label); -+ BUG_ON(!gc->ngpio); -+ -+ /* -+ * The register offsets for data in, out, and enable are the same for -+ * all GPIO's. -+ */ -+ if (!gc->direction_input) -+ gc->direction_input = iproc_gpiolib_input; -+ if (!gc->direction_output) -+ gc->direction_output = iproc_gpiolib_output; -+ if (!gc->set) -+ gc->set = iproc_gpiolib_set; -+ if (!gc->get) -+ gc->get = iproc_gpiolib_get; -+ if (!gc->to_irq) -+ gc->to_irq = iproc_gpiolib_to_irq; -+ -+ ret = gpiochip_add(gc); -+ if (ret >= 0) -+ printk(KERN_INFO "iproc gpiochip add %s\n", gc->label); -+ -+ return; -+} -+ -+/* -+ * Handles CCA, CCB, and CCG type GPIO's and registers the gpio -+ * controller. -+ */ -+ -+static int iproc_gpio_probe(struct platform_device *pdev) -+{ -+ const struct of_device_id *match; -+ struct device_node *dn = pdev->dev.of_node; -+ struct iproc_gpio_chip *iproc_gpio; -+ u32 num_gpios, pin_base, pin_offset, count/*, irq_base*/; -+ int ret; -+ -+ match = of_match_device(bcm_iproc_gpio_of_match, &pdev->dev); -+ if (!match) { -+ dev_err(&pdev->dev, "Failed to find gpio controller\n"); -+ return -ENODEV; -+ } -+ -+ iproc_gpio = devm_kzalloc(&pdev->dev, sizeof(*iproc_gpio), GFP_KERNEL); -+ if (!iproc_gpio) { -+ dev_err(&pdev->dev, "Error allocating memory\n"); -+ return -ENOMEM; -+ } -+ -+ platform_set_drvdata(pdev, iproc_gpio); -+ -+ /* Determine type of gpio controller to allocate. */ -+#if defined(IPROC_GPIO_CCA) -+ if (strstr(match->compatible, "cca")) { -+ iproc_gpio->chip.label = "gpio_cca"; -+ iproc_gpio->id = IPROC_GPIO_CCA_ID; -+ iproc_gpio->irqcfg = &cca_gpio_irqcfg; -+ -+ iproc_gpio->intr_ioaddr = of_iomap(dn, 1); -+ if (!iproc_gpio->intr_ioaddr) { -+ dev_err(&pdev->dev, "can't iomap gpio interrupt base address\n"); -+ return -ENOMEM; -+ } -+ -+ dev_info(&pdev->dev, "%s intr_ioaddr: %p\n", -+ iproc_gpio->chip.label, iproc_gpio->intr_ioaddr); -+ } -+ else -+#endif -+#if defined(IPROC_GPIO_CCB) -+ if (strstr(match->compatible, "ccb")) { -+ iproc_gpio->chip.label = "gpio_ccb"; -+ iproc_gpio->id = IPROC_GPIO_CCB_ID; -+ iproc_gpio->irqcfg = &ccb_gpio_irqcfg; -+ } -+ else -+#endif -+#if defined(IPROC_GPIO_CCG) -+ if (strstr(match->compatible, "ccg")) { -+ iproc_gpio->chip.label = "gpio_ccg"; -+ iproc_gpio->id = IPROC_GPIO_CCG_ID; -+ iproc_gpio->irqcfg = &ccb_gpio_irqcfg; -+ } -+ else -+#endif -+ { -+ dev_err(&pdev->dev, "Error parsing device tree of GPIO\n"); -+ return -ENODEV; -+ } -+ -+ /* Map gpio base ioaddr address. */ -+ iproc_gpio->ioaddr = of_iomap(dn, 0); -+ if (!iproc_gpio->ioaddr) { -+ dev_err(&pdev->dev, "can't iomap gpio base address\n"); -+ return -ENOMEM; -+ } -+ dev_info(&pdev->dev, "%s iaddr: %p\n", iproc_gpio->chip.label, iproc_gpio->ioaddr); -+ -+ if (of_property_read_u32(dn, "pin-base", &pin_base)) { -+ dev_err(&pdev->dev, "Missing pin-base property\n"); -+ return -EINVAL; -+ } -+ iproc_gpio->chip.base = pin_base; -+ -+ /* get pin_offset */ -+ if (of_property_read_u32(dn, "pin-offset", &pin_offset)) { -+ dev_err(&pdev->dev, "Missing pin-offset property\n"); -+ return -EINVAL; -+ } -+ iproc_gpio->pin_offset = pin_offset; -+ -+ /* Get number of GPIO's from device tree for gpiolib. */ -+ if (of_property_read_u32(dn, "ngpios", &num_gpios)) { -+ dev_err(&pdev->dev, "Missing ngpios property\n"); -+ return -EINVAL; -+ } -+ iproc_gpio->chip.ngpio = num_gpios; -+ -+ /* Register controller with gpiolib. */ -+ iproc_gpio->chip.dev = &pdev->dev; -+ iproc_gpiolib_add(iproc_gpio); -+ -+ /* Get interrupt number from device tree. */ -+ iproc_gpio->irq = irq_of_parse_and_map(dn, 0); -+ -+ /* Install ISR for this GPIO controller. */ -+ if (iproc_gpio->irq > 0) { -+ /* Create irq domain so that each pin can be assigned an IRQ.*/ -+ iproc_gpio->irq_domain = irq_domain_add_linear(dn, num_gpios, -+ &irq_domain_simple_ops, iproc_gpio); -+ -+ if (!iproc_gpio->irq_domain) { -+ dev_err(&pdev->dev, "Couldn't allocate IRQ domain\n"); -+ return -ENXIO; -+ } -+ -+ /* Map each gpio to an IRQ and set the handler for gpiolib. */ -+ for (count = 0; count < num_gpios; count++) { -+ int irq; -+ -+ irq = irq_create_mapping(iproc_gpio->irq_domain, count); -+ irq_set_chip_and_handler(irq, &iproc_gpio_irq_chip, -+ handle_simple_irq); -+ irq_set_chip_data(irq, iproc_gpio); -+ } -+ -+ /* Enable GPIO interrupts in CCA interrupt mask. */ -+#if defined(IPROC_GPIO_CCA) -+ if (iproc_gpio->id == IPROC_GPIO_CCA_ID) { -+ unsigned int val; -+ val = readl(iproc_gpio->intr_ioaddr + IPROC_CCA_INT_MASK); -+ val |= IPROC_CCA_INT_F_GPIOINT; -+ writel(val, iproc_gpio->intr_ioaddr + IPROC_CCA_INT_MASK); -+ } -+#endif /* IPROC_GPIO_CCA */ -+ if (iproc_gpio->irqcfg) { -+ struct iproc_gpio_irqcfg *irqcfg = iproc_gpio->irqcfg; -+ if (irqcfg->handler) { -+ ret = request_irq(iproc_gpio->irq, -+ irqcfg->handler, irqcfg->flags, -+ iproc_gpio->chip.label, iproc_gpio); -+ if (ret) { -+ printk(KERN_ERR "Unable to request IRQ%d: %d\n", iproc_gpio->irq, ret); -+ return -ENODEV; -+ } -+ } -+ else -+ printk(KERN_ERR "%s is added without isr!\n", iproc_gpio->chip.label); -+ } -+ } -+ else -+ dev_warn(&pdev->dev, "IRQ not specified. No ISR installed\n"); -+ -+ return 0; -+} -+ -+static int __exit iproc_gpio_remove(struct platform_device *pdev) -+{ -+ struct iproc_gpio_chip *iproc_gpio; -+ -+ iproc_gpio = platform_get_drvdata(pdev); -+ if (iproc_gpio == NULL) -+ return -ENODEV; -+ -+ if (iproc_gpio->intr_ioaddr) { -+#if defined(IPROC_GPIO_CCA) -+ if (iproc_gpio->id == IPROC_GPIO_CCA_ID) { -+ unsigned int val; -+ val = readl(iproc_gpio->intr_ioaddr + IPROC_CCA_INT_MASK); -+ val &= ~(IPROC_CCA_INT_F_GPIOINT); -+ writel(val, iproc_gpio->intr_ioaddr + IPROC_CCA_INT_MASK); -+ } -+#endif -+ } -+ -+ gpiochip_remove(&iproc_gpio->chip); -+ -+ return 0; -+} -+ -+static struct platform_driver bcm_iproc_gpio_driver = { -+ .driver = { -+ .name = "iproc-gpio", -+ .owner = THIS_MODULE, -+ .of_match_table = bcm_iproc_gpio_of_match, -+ }, -+ .probe = iproc_gpio_probe, -+ .remove = iproc_gpio_remove, -+}; -+ -+module_platform_driver(bcm_iproc_gpio_driver); -+ -+MODULE_DESCRIPTION("IPROC GPIO driver"); -+MODULE_LICENSE("GPL"); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/gpio/gpio-xgs-iproc.h b/drivers/gpio/gpio-xgs-iproc.h ---- a/drivers/gpio/gpio-xgs-iproc.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/gpio/gpio-xgs-iproc.h 2017-11-09 17:53:27.757186000 +0800 -@@ -0,0 +1,61 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ */ -+ -+#ifndef __IPROC_PLAT_GPIO_H -+#define __IPROC_PLAT_GPIO_H -+ -+#if defined(CONFIG_MACH_IPROC_P7) -+#define IPROC_GPIO_CCG -+#else -+#define IPROC_GPIO_CCA -+#define IPROC_GPIO_CCB -+#endif -+ -+#define IPROC_GPIO_REG_SIZE (0x50) -+ -+#define REGOFFSET_GPIO_DIN 0x000 /* GPIO Data in register */ -+#define REGOFFSET_GPIO_DOUT 0x004 /* GPIO Data out register */ -+#define REGOFFSET_GPIO_EN 0x008 /* GPIO output enable register */ -+ -+#define IPROC_GPIO_CCA_ID (0) -+#define IPROC_GPIO_CCB_ID (1) -+#define IPROC_GPIO_CCG_ID (2) -+ -+struct iproc_gpio_irqcfg { -+ unsigned long flags; -+ irqreturn_t (*handler)(int irq, void *dev); -+ void (*ack)(unsigned int irq); -+ void (*unmask)(unsigned int irq); -+ void (*mask)(unsigned int irq); -+ int (*set_type)(unsigned int irq, unsigned int type); -+}; -+ -+struct iproc_gpio_chip { -+ int id; -+ struct gpio_chip chip; -+ struct iproc_gpio_cfg *config; -+ void __iomem *ioaddr; -+ void __iomem *intr_ioaddr; -+ spinlock_t lock; -+ struct irq_domain *irq_domain; -+ struct resource * resource; -+ int irq; -+ struct iproc_gpio_irqcfg *irqcfg; -+ int pin_offset; -+}; -+ -+ -+static inline struct iproc_gpio_chip *to_iproc_gpio(struct gpio_chip *gpc) -+{ -+ return container_of(gpc, struct iproc_gpio_chip, chip); -+} -+ -+ -+/* locking wrappers to deal with multiple access to the same gpio bank */ -+#define iproc_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl) -+#define iproc_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl) -+ -+extern void iproc_gpiolib_add(struct iproc_gpio_chip *chip); -+ -+#endif -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig ---- a/drivers/i2c/busses/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/i2c/busses/Kconfig 2017-11-09 17:53:33.506215000 +0800 -@@ -385,6 +385,26 @@ config I2C_BCM_IPROC - - If you don't know what to do here, say N. - -+config I2C_XGS_IPROC -+ tristate "Broadcom XGS iProc I2C controller" -+ depends on ARCH_XGS_IPROC -+ default ARCH_XGS_IPROC -+ help -+ If you say yes to this option, support will be included for the -+ Broadcom XGS iProc I2C controller. -+ -+ If you don't know what to do here, say N. -+ -+config SMBUS_XGS_IPROC -+ tristate "Broadcom XGS iProc SMBUS controller" -+ depends on ARCH_XGS_IPROC -+ default !I2C_XGS_IPROC -+ help -+ If you say yes to this option, support will be included for the -+ Broadcom XGS iProc SMBUS controller. -+ -+ If you don't know what to do here, say N. -+ - config I2C_BCM_KONA - tristate "BCM Kona I2C adapter" - depends on ARCH_BCM_MOBILE -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile ---- a/drivers/i2c/busses/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/i2c/busses/Makefile 2017-11-09 17:53:33.507214000 +0800 -@@ -92,6 +92,8 @@ obj-$(CONFIG_I2C_UNIPHIER_F) += i2c-unip - obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o - obj-$(CONFIG_I2C_WMT) += i2c-wmt.o - obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o -+obj-$(CONFIG_I2C_XGS_IPROC) += i2c-xgs-iproc.o -+obj-$(CONFIG_SMBUS_XGS_IPROC) += xgs_iproc_smbus.o - obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o - obj-$(CONFIG_I2C_XLR) += i2c-xlr.o - obj-$(CONFIG_I2C_XLP9XX) += i2c-xlp9xx.o -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/i2c-xgs-iproc.c b/drivers/i2c/busses/i2c-xgs-iproc.c ---- a/drivers/i2c/busses/i2c-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/i2c/busses/i2c-xgs-iproc.c 2017-11-09 17:53:33.700222000 +0800 -@@ -0,0 +1,598 @@ -+/* -+ * Copyright (C) 2014 Broadcom Corporation -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define CFG_OFFSET 0x00 -+#define CFG_RESET_SHIFT 31 -+#define CFG_EN_SHIFT 30 -+#define CFG_M_RETRY_CNT_SHIFT 16 -+#define CFG_M_RETRY_CNT_MASK 0x0f -+ -+#define TIM_CFG_OFFSET 0x04 -+#define TIM_CFG_MODE_400_SHIFT 31 -+ -+#define M_FIFO_CTRL_OFFSET 0x0c -+#define M_FIFO_RX_FLUSH_SHIFT 31 -+#define M_FIFO_TX_FLUSH_SHIFT 30 -+#define M_FIFO_RX_CNT_SHIFT 16 -+#define M_FIFO_RX_CNT_MASK 0x7f -+#define M_FIFO_RX_THLD_SHIFT 8 -+#define M_FIFO_RX_THLD_MASK 0x3f -+ -+#define M_CMD_OFFSET 0x30 -+#define M_CMD_START_BUSY_SHIFT 31 -+#define M_CMD_STATUS_SHIFT 25 -+#define M_CMD_STATUS_MASK 0x07 -+#define M_CMD_STATUS_SUCCESS 0x0 -+#define M_CMD_STATUS_LOST_ARB 0x1 -+#define M_CMD_STATUS_NACK_ADDR 0x2 -+#define M_CMD_STATUS_NACK_DATA 0x3 -+#define M_CMD_STATUS_TIMEOUT 0x4 -+#define M_CMD_PROTOCOL_SHIFT 9 -+#define M_CMD_PROTOCOL_MASK 0xf -+#define M_CMD_PROTOCOL_BLK_WR 0x7 -+#define M_CMD_PROTOCOL_BLK_RD 0x8 -+#define M_CMD_PEC_SHIFT 8 -+#define M_CMD_RD_CNT_SHIFT 0 -+#define M_CMD_RD_CNT_MASK 0xff -+ -+#define IE_OFFSET 0x38 -+#define IE_M_RX_FIFO_FULL_SHIFT 31 -+#define IE_M_RX_THLD_SHIFT 30 -+#define IE_M_START_BUSY_SHIFT 28 -+ -+#define IS_OFFSET 0x3c -+#define IS_M_RX_FIFO_FULL_SHIFT 31 -+#define IS_M_RX_THLD_SHIFT 30 -+#define IS_M_START_BUSY_SHIFT 28 -+ -+#define M_TX_OFFSET 0x40 -+#define M_TX_WR_STATUS_SHIFT 31 -+#define M_TX_DATA_SHIFT 0 -+#define M_TX_DATA_MASK 0xff -+ -+#define M_RX_OFFSET 0x44 -+#define M_RX_STATUS_SHIFT 30 -+#define M_RX_STATUS_MASK 0x03 -+#define M_RX_PEC_ERR_SHIFT 29 -+#define M_RX_DATA_SHIFT 0 -+#define M_RX_DATA_MASK 0xff -+ -+#define I2C_TIMEOUT_MESC 100 -+ -+#define M_TX_RX_FIFO_SIZE 64 -+#define I2C_MAX_DATA_READ_LEN (M_TX_RX_FIFO_SIZE - 1) -+#define I2C_MAX_DATA_WRITE_LEN (M_TX_RX_FIFO_SIZE - 1) -+ -+/* -+ * Enable support of EEPROM I2C devices with 2 byte addressing mode and page -+ * size >= 64B. -+ */ -+#define CONFIG_ENABLE_WRITE_MSG_SPLIT 1 -+ -+ -+enum bus_speed_index { -+ I2C_SPD_100K = 0, -+ I2C_SPD_400K, -+}; -+ -+struct bcm_iproc_i2c_dev { -+ struct device *device; -+ int irq; -+ -+ void __iomem *base; -+ -+ struct i2c_adapter adapter; -+ unsigned int bus_speed; -+ -+ struct completion done; -+ int xfer_is_done; -+}; -+ -+/* -+ * Can be expanded in the future if more interrupt status bits are utilized -+ */ -+#define ISR_MASK (1 << IS_M_START_BUSY_SHIFT) -+ -+static irqreturn_t bcm_iproc_i2c_isr(int irq, void *data) -+{ -+ struct bcm_iproc_i2c_dev *iproc_i2c = data; -+ u32 status = readl(iproc_i2c->base + IS_OFFSET); -+ -+ status &= ISR_MASK; -+ -+ if (!status) -+ return IRQ_NONE; -+ -+ writel(status, iproc_i2c->base + IS_OFFSET); -+ iproc_i2c->xfer_is_done = 1; -+ complete_all(&iproc_i2c->done); -+ -+ return IRQ_HANDLED; -+} -+ -+static int bcm_iproc_i2c_check_status(struct bcm_iproc_i2c_dev *iproc_i2c, -+ struct i2c_msg *msg) -+{ -+ u32 val; -+ -+ val = readl(iproc_i2c->base + M_CMD_OFFSET); -+ val = (val >> M_CMD_STATUS_SHIFT) & M_CMD_STATUS_MASK; -+ -+ switch (val) { -+ case M_CMD_STATUS_SUCCESS: -+ return 0; -+ -+ case M_CMD_STATUS_LOST_ARB: -+ dev_dbg(iproc_i2c->device, "lost bus arbitration\n"); -+ return -EAGAIN; -+ -+ case M_CMD_STATUS_NACK_ADDR: -+ dev_dbg(iproc_i2c->device, "NAK addr:0x%02x\n", msg->addr); -+ return -ENXIO; -+ -+ case M_CMD_STATUS_NACK_DATA: -+ dev_dbg(iproc_i2c->device, "NAK data\n"); -+ return -ENXIO; -+ -+ case M_CMD_STATUS_TIMEOUT: -+ dev_dbg(iproc_i2c->device, "bus timeout\n"); -+ return -ETIMEDOUT; -+ -+ default: -+ dev_dbg(iproc_i2c->device, "unknown error code=%d\n", val); -+ return -EIO; -+ } -+} -+ -+static int bcm_iproc_i2c_xfer_single_msg(struct bcm_iproc_i2c_dev *iproc_i2c, -+ struct i2c_msg *msg) -+{ -+ int ret, i; -+ u8 addr; -+ u32 val; -+ unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT_MESC); -+ -+ /* check if bus is busy */ -+ if (!!(readl(iproc_i2c->base + M_CMD_OFFSET) & -+ BIT(M_CMD_START_BUSY_SHIFT))) { -+ dev_warn(iproc_i2c->device, "bus is busy\n"); -+ return -EBUSY; -+ } -+ -+ /* format and load slave address into the TX FIFO */ -+ addr = msg->addr << 1 | (msg->flags & I2C_M_RD ? 1 : 0); -+ writel(addr, iproc_i2c->base + M_TX_OFFSET); -+ -+ /* for a write transaction, load data into the TX FIFO */ -+ if (!(msg->flags & I2C_M_RD)) { -+ for (i = 0; i < msg->len; i++) { -+ val = msg->buf[i]; -+ -+ /* mark the last byte */ -+ if (i == msg->len - 1) -+ val |= 1 << M_TX_WR_STATUS_SHIFT; -+ -+ writel(val, iproc_i2c->base + M_TX_OFFSET); -+ } -+ } -+ -+ /* mark as incomplete before starting the transaction */ -+ reinit_completion(&iproc_i2c->done); -+ iproc_i2c->xfer_is_done = 0; -+ -+ /* -+ * Enable the "start busy" interrupt, which will be triggered after the -+ * transaction is done, i.e., the internal start_busy bit, transitions -+ * from 1 to 0. -+ */ -+ writel(1 << IE_M_START_BUSY_SHIFT, iproc_i2c->base + IE_OFFSET); -+ -+ /* -+ * Now we can activate the transfer. For a read operation, specify the -+ * number of bytes to read -+ */ -+ val = 1 << M_CMD_START_BUSY_SHIFT; -+ if (msg->flags & I2C_M_RD) { -+ val |= (M_CMD_PROTOCOL_BLK_RD << M_CMD_PROTOCOL_SHIFT) | -+ (msg->len << M_CMD_RD_CNT_SHIFT); -+ } else { -+ val |= (M_CMD_PROTOCOL_BLK_WR << M_CMD_PROTOCOL_SHIFT); -+ } -+ writel(val, iproc_i2c->base + M_CMD_OFFSET); -+ -+ time_left = wait_for_completion_timeout(&iproc_i2c->done, time_left); -+ -+ /* disable all interrupts */ -+ writel(0, iproc_i2c->base + IE_OFFSET); -+ /* read it back to flush the write */ -+ readl(iproc_i2c->base + IE_OFFSET); -+ -+ /* make sure the interrupt handler isn't running */ -+ synchronize_irq(iproc_i2c->irq); -+ -+ if (!time_left && !iproc_i2c->xfer_is_done) { -+ dev_err(iproc_i2c->device, "transaction timed out\n"); -+ -+ /* flush FIFOs */ -+ val = (1 << M_FIFO_RX_FLUSH_SHIFT) | -+ (1 << M_FIFO_TX_FLUSH_SHIFT); -+ writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); -+ return -ETIMEDOUT; -+ } -+ -+ ret = bcm_iproc_i2c_check_status(iproc_i2c, msg); -+ if (ret) { -+ /* flush both TX/RX FIFOs */ -+ val = (1 << M_FIFO_RX_FLUSH_SHIFT) | -+ (1 << M_FIFO_TX_FLUSH_SHIFT); -+ writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); -+ return ret; -+ } -+ -+ /* -+ * For a read operation, we now need to load the data from FIFO -+ * into the memory buffer -+ */ -+ if (msg->flags & I2C_M_RD) { -+ for (i = 0; i < msg->len; i++) { -+ msg->buf[i] = (readl(iproc_i2c->base + M_RX_OFFSET) >> -+ M_RX_DATA_SHIFT) & M_RX_DATA_MASK; -+ } -+ } -+ -+ return 0; -+} -+ -+static int bcm_iproc_i2c_xfer(struct i2c_adapter *adapter, -+ struct i2c_msg msgs[], int num) -+{ -+ struct bcm_iproc_i2c_dev *iproc_i2c = i2c_get_adapdata(adapter); -+ int ret, i; -+ int xfer_msg_len, xfer_msg_len_max; -+ u8 addr_h, addr_l; -+ -+ /* go through all messages */ -+ for (i = 0; i < num; i++) { -+ xfer_msg_len = msgs[i].len; -+ if (msgs[i].flags & I2C_M_RD) -+ xfer_msg_len_max = I2C_MAX_DATA_READ_LEN; -+ else -+ xfer_msg_len_max = I2C_MAX_DATA_WRITE_LEN; -+ -+ while (xfer_msg_len) { -+ if (xfer_msg_len > xfer_msg_len_max) -+ msgs[i].len = xfer_msg_len_max; -+ ret = bcm_iproc_i2c_xfer_single_msg(iproc_i2c, &msgs[i]); -+ if (ret) { -+ dev_dbg(iproc_i2c->device, "xfer failed\n"); -+ return ret; -+ } -+ -+ if (msgs[i].len == xfer_msg_len_max) { -+ xfer_msg_len -= xfer_msg_len_max; -+ if (xfer_msg_len == 0) -+ break; -+ /* Keep the addr offset for later use */ -+ addr_h = *(msgs[i].buf); -+ addr_l = *(msgs[i].buf + 1); -+ -+ msgs[i].len = xfer_msg_len; -+ msgs[i].buf += xfer_msg_len_max; -+ -+#if defined(CONFIG_ENABLE_WRITE_MSG_SPLIT) -+ if (!(msgs[i].flags & I2C_M_RD)) { -+ /* -+ * For write transfer with len >= 64B, -+ * assuming 2 byte addressing should be -+ * reasonable. -+ */ -+ xfer_msg_len += 2; -+ msgs[i].len = xfer_msg_len; -+ -+ /* -+ * Append new 2-byte address offset. -+ * The upper byte should be unchanged. -+ * The lower byte is increased by -+ * actually written bytes: -+ * (xfer_msg_len_max - 2) -+ */ -+ msgs[i].buf -= 2; -+ *(msgs[i].buf) = addr_h; -+ *(msgs[i].buf + 1) = addr_l - 2 + -+ xfer_msg_len_max; -+ -+ /* -+ * Wait some time so that EEPROM -+ * is ready to respond after previous -+ * partial page write. -+ */ -+ mdelay(10); -+ } -+#endif /* CONFIG_ENABLE_WRITE_MSG_SPLIT */ -+ } else { -+ /* -+ * msgs[i] is transfered completely, -+ * if msgs[i].len is less than xfer_msg_len_max. -+ */ -+ break; -+ } -+ } /* while */ -+ } /* for */ -+ -+ return num; -+} -+ -+ -+static uint32_t bcm_iproc_i2c_functionality(struct i2c_adapter *adap) -+{ -+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -+} -+ -+static const struct i2c_algorithm bcm_iproc_algo = { -+ .master_xfer = bcm_iproc_i2c_xfer, -+ .functionality = bcm_iproc_i2c_functionality, -+}; -+ -+/* -+ * Don't limit the max write length for Linux I2C core, if support of -+ * write msg split is enabled. -+ * Read msg split is support, so max_read_len is commented out. -+ */ -+#if !defined(CONFIG_ENABLE_WRITE_MSG_SPLIT) -+static struct i2c_adapter_quirks bcm_iproc_i2c_quirks = { -+ /* need to reserve one byte in the FIFO for the slave address */ -+ //.max_read_len = M_TX_RX_FIFO_SIZE - 1, -+ .max_write_len = M_TX_RX_FIFO_SIZE - 1, -+}; -+#endif -+ -+static int bcm_iproc_i2c_cfg_speed(struct bcm_iproc_i2c_dev *iproc_i2c) -+{ -+ unsigned int bus_speed; -+ u32 val; -+ int ret = of_property_read_u32(iproc_i2c->device->of_node, -+ "clock-frequency", &bus_speed); -+ if (ret < 0) { -+ dev_info(iproc_i2c->device, -+ "unable to interpret clock-frequency DT property\n"); -+ bus_speed = 100000; -+ } -+ -+ if (bus_speed < 100000) { -+ dev_err(iproc_i2c->device, "%d Hz bus speed not supported\n", -+ bus_speed); -+ dev_err(iproc_i2c->device, -+ "valid speeds are 100khz and 400khz\n"); -+ return -EINVAL; -+ } else if (bus_speed < 400000) { -+ bus_speed = 100000; -+ } else { -+ bus_speed = 400000; -+ } -+ -+ iproc_i2c->bus_speed = bus_speed; -+ val = readl(iproc_i2c->base + TIM_CFG_OFFSET); -+ val &= ~(1 << TIM_CFG_MODE_400_SHIFT); -+ val |= (bus_speed == 400000) << TIM_CFG_MODE_400_SHIFT; -+ writel(val, iproc_i2c->base + TIM_CFG_OFFSET); -+ -+ dev_info(iproc_i2c->device, "bus set to %u Hz\n", bus_speed); -+ -+ return 0; -+} -+ -+static int bcm_iproc_i2c_init(struct bcm_iproc_i2c_dev *iproc_i2c) -+{ -+ u32 val; -+ -+ /* put controller in reset */ -+ val = readl(iproc_i2c->base + CFG_OFFSET); -+ val |= 1 << CFG_RESET_SHIFT; -+ val &= ~(1 << CFG_EN_SHIFT); -+ writel(val, iproc_i2c->base + CFG_OFFSET); -+ -+ /* wait 100 usec per spec */ -+ udelay(100); -+ -+ /* bring controller out of reset */ -+ val &= ~(1 << CFG_RESET_SHIFT); -+ writel(val, iproc_i2c->base + CFG_OFFSET); -+ -+ /* flush TX/RX FIFOs and set RX FIFO threshold to zero */ -+ val = (1 << M_FIFO_RX_FLUSH_SHIFT) | (1 << M_FIFO_TX_FLUSH_SHIFT); -+ writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); -+ -+ /* disable all interrupts */ -+ writel(0, iproc_i2c->base + IE_OFFSET); -+ -+ /* clear all pending interrupts */ -+ writel(0xffffffff, iproc_i2c->base + IS_OFFSET); -+ -+ return 0; -+} -+ -+static void bcm_iproc_i2c_enable_disable(struct bcm_iproc_i2c_dev *iproc_i2c, -+ bool enable) -+{ -+ u32 val; -+ -+ val = readl(iproc_i2c->base + CFG_OFFSET); -+ if (enable) -+ val |= BIT(CFG_EN_SHIFT); -+ else -+ val &= ~BIT(CFG_EN_SHIFT); -+ writel(val, iproc_i2c->base + CFG_OFFSET); -+} -+ -+static int bcm_iproc_i2c_probe(struct platform_device *pdev) -+{ -+ int irq, ret = 0; -+ struct bcm_iproc_i2c_dev *iproc_i2c; -+ struct i2c_adapter *adap; -+ struct resource *res; -+ -+ iproc_i2c = devm_kzalloc(&pdev->dev, sizeof(*iproc_i2c), -+ GFP_KERNEL); -+ if (!iproc_i2c) -+ return -ENOMEM; -+ -+ platform_set_drvdata(pdev, iproc_i2c); -+ iproc_i2c->device = &pdev->dev; -+ init_completion(&iproc_i2c->done); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ iproc_i2c->base = devm_ioremap_resource(iproc_i2c->device, res); -+ if (IS_ERR(iproc_i2c->base)) -+ return PTR_ERR(iproc_i2c->base); -+ -+ ret = bcm_iproc_i2c_init(iproc_i2c); -+ if (ret) -+ return ret; -+ -+ ret = bcm_iproc_i2c_cfg_speed(iproc_i2c); -+ if (ret) -+ return ret; -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq <= 0) { -+ dev_err(iproc_i2c->device, "no irq resource\n"); -+ return irq; -+ } -+ iproc_i2c->irq = irq; -+ -+ ret = devm_request_irq(iproc_i2c->device, irq, bcm_iproc_i2c_isr, 0, -+ pdev->name, iproc_i2c); -+ if (ret < 0) { -+ dev_err(iproc_i2c->device, "unable to request irq %i\n", irq); -+ return ret; -+ } -+ -+ bcm_iproc_i2c_enable_disable(iproc_i2c, true); -+ -+ adap = &iproc_i2c->adapter; -+ i2c_set_adapdata(adap, iproc_i2c); -+ strlcpy(adap->name, "Broadcom iProc I2C adapter", sizeof(adap->name)); -+ adap->algo = &bcm_iproc_algo; -+#if !defined(CONFIG_ENABLE_WRITE_MSG_SPLIT) -+ adap->quirks = &bcm_iproc_i2c_quirks; -+#endif -+ adap->dev.parent = &pdev->dev; -+ adap->dev.of_node = pdev->dev.of_node; -+ -+ ret = i2c_add_adapter(adap); -+ if (ret) { -+ dev_err(iproc_i2c->device, "failed to add adapter\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int bcm_iproc_i2c_remove(struct platform_device *pdev) -+{ -+ struct bcm_iproc_i2c_dev *iproc_i2c = platform_get_drvdata(pdev); -+ -+ /* make sure there's no pending interrupt when we remove the adapter */ -+ writel(0, iproc_i2c->base + IE_OFFSET); -+ readl(iproc_i2c->base + IE_OFFSET); -+ synchronize_irq(iproc_i2c->irq); -+ -+ i2c_del_adapter(&iproc_i2c->adapter); -+ bcm_iproc_i2c_enable_disable(iproc_i2c, false); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM_SLEEP -+ -+static int bcm_iproc_i2c_suspend(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct bcm_iproc_i2c_dev *iproc_i2c = platform_get_drvdata(pdev); -+ -+ /* make sure there's no pending interrupt when we go into suspend */ -+ writel(0, iproc_i2c->base + IE_OFFSET); -+ readl(iproc_i2c->base + IE_OFFSET); -+ synchronize_irq(iproc_i2c->irq); -+ -+ /* now disable the controller */ -+ bcm_iproc_i2c_enable_disable(iproc_i2c, false); -+ -+ return 0; -+} -+ -+static int bcm_iproc_i2c_resume(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct bcm_iproc_i2c_dev *iproc_i2c = platform_get_drvdata(pdev); -+ int ret; -+ u32 val; -+ -+ /* -+ * Power domain could have been shut off completely in system deep -+ * sleep, so re-initialize the block here -+ */ -+ ret = bcm_iproc_i2c_init(iproc_i2c); -+ if (ret) -+ return ret; -+ -+ /* configure to the desired bus speed */ -+ val = readl(iproc_i2c->base + TIM_CFG_OFFSET); -+ val &= ~(1 << TIM_CFG_MODE_400_SHIFT); -+ val |= (iproc_i2c->bus_speed == 400000) << TIM_CFG_MODE_400_SHIFT; -+ writel(val, iproc_i2c->base + TIM_CFG_OFFSET); -+ -+ bcm_iproc_i2c_enable_disable(iproc_i2c, true); -+ -+ return 0; -+} -+ -+static const struct dev_pm_ops bcm_iproc_i2c_pm_ops = { -+ .suspend_late = &bcm_iproc_i2c_suspend, -+ .resume_early = &bcm_iproc_i2c_resume -+}; -+ -+#define BCM_IPROC_I2C_PM_OPS (&bcm_iproc_i2c_pm_ops) -+#else -+#define BCM_IPROC_I2C_PM_OPS NULL -+#endif /* CONFIG_PM_SLEEP */ -+ -+static const struct of_device_id bcm_iproc_i2c_of_match[] = { -+ { .compatible = "brcm,iproc-i2c" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, bcm_iproc_i2c_of_match); -+ -+static struct platform_driver bcm_iproc_i2c_driver = { -+ .driver = { -+ .name = "bcm-iproc-i2c", -+ .of_match_table = bcm_iproc_i2c_of_match, -+ .pm = BCM_IPROC_I2C_PM_OPS, -+ }, -+ .probe = bcm_iproc_i2c_probe, -+ .remove = bcm_iproc_i2c_remove, -+}; -+module_platform_driver(bcm_iproc_i2c_driver); -+ -+MODULE_AUTHOR("Ray Jui "); -+MODULE_DESCRIPTION("Broadcom iProc I2C Driver"); -+MODULE_LICENSE("GPL v2"); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/iproc_smbus.h b/drivers/i2c/busses/iproc_smbus.h ---- a/drivers/i2c/busses/iproc_smbus.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/i2c/busses/iproc_smbus.h 2017-11-09 17:53:33.705215000 +0800 -@@ -0,0 +1,189 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ */ -+ -+#ifndef __IPROC_SMBUS_H__ -+#define __IPROC_SMBUS_H__ -+ -+#define IPROC_I2C_INVALID_ADDR 0xFF -+ -+#define MAX_PROC_BUF_SIZE 256 -+#define MAX_PROC_NAME_SIZE 15 -+#define PROC_GLOBAL_PARENT_DIR "iproc-i2c" -+#define PROC_ENTRY_DEBUG "iproc-i2c-dbg" -+ -+#define IPROC_SMB_MAX_RETRIES 35 -+ -+#define GETREGFLDVAL(regval, mask, startbit) (((regval) & (mask)) >> (startbit)) -+ -+#define SETREGFLDVAL(regval, fldval, mask, startbit) regval = \ -+ (regval & ~(mask)) | \ -+ ((fldval) << (startbit)) -+ -+/* Enum to specify clock speed. The user will provide it during initialization. -+ * If needed, it can be changed dynamically -+ */ -+typedef enum iproc_smb_clk_freq { -+ I2C_SPEED_100KHz = 0, -+ I2C_SPEED_400KHz = 1, -+ I2C_SPEED_INVALID = 255 -+} smb_clk_freq_t; -+ -+/* This enum will be used to notify the user of status of a data transfer -+ * request -+ */ -+typedef enum iproc_smb_error_code { -+ I2C_NO_ERR = 0, -+ I2C_TIMEOUT_ERR = 1, -+ I2C_INVALID_PARAM_ERR = 2, /* Invalid parameter(s) passed to the driver */ -+ I2C_OPER_IN_PROGRESS = 3, /* The driver API was called before the present -+ transfer was completed */ -+ I2C_OPER_ABORT_ERR = 4, /* Transfer aborted unexpectedly, for example a NACK -+ received, before last byte was read/written */ -+ I2C_FUNC_NOT_SUPPORTED = 5, /* Feature or function not supported -+ (e.g., 10-bit addresses, or clock speeds -+ other than 100KHz, 400KHz) */ -+} iproc_smb_error_code_t; -+ -+/* Counters will be used mainly for testing and debugging */ -+struct iproc_smb_counters { -+ unsigned int num_read_requests; -+ unsigned int num_write_requests; -+ unsigned int num_read_errors; -+ unsigned int num_write_errors; -+ unsigned int mstr_rx_evt_cnt; /* ISR counter to check recv event */ -+ unsigned int mstr_start_busy_cnt; /* ISR counter to checking xact sts */ -+ unsigned int mstr_rx_fifo_full_cnt; /* ISR counter to detect rx fifo full */ -+ unsigned int last_int_sts; /* last value of intr status reg */ -+}; -+ -+ -+/* This enum may be used in a call back function to provide the user of the -+ * type of request sent by the user. It can also be used for testing and -+ * debugging purposes -+ */ -+typedef enum iproc_smb_message_type { -+ I2C_DISABLE_MSG = 0, /* To be used after hardware initialization. -+ Driver will _not_ respond to API calls */ -+ I2C_ENABLE_MSG = 1, /* Used after hardware initialization, if required. -+ Driver will start responding to API calls. -+ Will not (re-)program the hardware. */ -+ I2C_READ_MSG = 2, /* I2C read request from application */ -+ I2C_WRITE_MSG = 3 /* I2C write request from application */ -+} iproc_smb_message_type_t; -+ -+/* For debugging purposes, we will store the information about the last -+ * (latest) transfer request from the client application -+ */ -+struct iproc_smb_dbg_trans_info -+{ -+ iproc_smb_message_type_t i2c_last_mesg_type; -+ unsigned int i2c_last_dev_addr; -+ unsigned int i2c_last_num_bytes_xfer_req; -+}; -+ -+struct procfs { -+ char name[MAX_PROC_NAME_SIZE]; -+ struct proc_dir_entry *parent; -+}; -+ -+/* This structure will be used internally by the driver to maintain its -+ * configuration information as well as information programmed in to the -+ * hardware -+ */ -+struct iproc_smb_drv_int_data { -+ struct device *dev; -+ struct iproc_smb_drv_int_data *next; -+ -+ int irq; -+ -+ unsigned int drv_state_init; /* 1 = Initialized, 0 = not initialized */ -+ -+ unsigned int drv_state_open; /* 1 = Accepting transaction requests, -+ 0 = Not accepting transaction requests */ -+ smb_clk_freq_t clk_speed; -+ -+ void __iomem *block_base_addr; /* iomapped virtual base address for -+ register access */ -+ -+ struct i2c_adapter adapter; -+ -+ unsigned int i2c_slave_addr; /* Up to four 7-bit SMB slave addresses can be -+ assigned, we will assume only one for now. -+ Valid only if SMBus will act as a slave -+ device */ -+ -+ struct semaphore xfer_lock; /* Lock for data transfer */ -+ -+ struct completion ses_done; /* To signal the command completion */ -+ -+ struct procfs proc; -+ -+ volatile int debug; -+ -+ unsigned int master_rx_fifo_thr; /* Master FIFO threshold. Interrupt will be -+ generated if the threshold is exceeded */ -+ -+ unsigned int slave_rx_fifo_thr; /* Slave FIFO threshold. Interrupt will be -+ generated if the threshold is exceeded */ -+ -+ unsigned int enable_evts; /* If true, enable interrupts. If false, -+ disable interrupts. Default is false */ -+ unsigned int evt_enable_bmap; /* Bit map of events enabled by the driver */ -+ -+ struct iproc_smb_counters smb_counters; /* Statistics maintained by driver. A caller -+ can request them through an API */ -+}; -+ -+/* Data to be supplied by the platform to initialise the IPROC SMBus (I2C). -+ * block -+ * init: Function called during driver initialization. Used by platform to -+ * configure GPIO functions and similar. -+ */ -+struct iproc_smb_platform_data { -+ int (*init)(struct iproc_smb_drv_int_data *iproc_i2c_info_ptr, int flags); -+ -+ unsigned int flags; -+}; -+ -+/* This structure will be used by the user during driver initialization to pass -+ * initial configuration information to the driver -+ */ -+struct iproc_smb_init_params { -+ unsigned int intr_mode; /* TRUE (1) for enabling interrupt mode, -+ FALSE (0) for polling mode */ -+ unsigned int clock_freq; /* 0=100KHz, 1=400KHz */ -+ void (*i2c_callback_func)(unsigned char *data); /* Application can -+ register a callback -+ function for driver to -+ notify the application -+ of any asynchronous -+ event(s), or exception. -+ Can be NULL */ -+}; -+ -+/* Structure used to pass information to read/write functions. */ -+struct iproc_xact_info { -+ bool cmd_valid; /* true if command field below is valid. Otherwise, false */ -+ unsigned short command; /* Passed by caller to send SMBus command code */ -+ unsigned char *data; /* actual data pased by the caller */ -+ unsigned int size; /* Size of data buffer passed */ -+ unsigned short flags; /* Sent by caller specifying PEC, 10-bit addresses */ -+ unsigned char smb_proto; /* SMBus protocol to use to perform transaction */ -+}; -+ -+#define XACT_TIMEOUT (msecs_to_jiffies(100)) /* Verify if 100 is OK */ -+ -+#endif /* __IPROC_SMBUS_H__ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/iproc_smbus_defs.h b/drivers/i2c/busses/iproc_smbus_defs.h ---- a/drivers/i2c/busses/iproc_smbus_defs.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/i2c/busses/iproc_smbus_defs.h 2017-11-09 17:53:33.705243000 +0800 -@@ -0,0 +1,47 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ */ -+ -+#ifndef __IPROC_SMBUS_DEFS_H__ -+#define __IPROC_SMBUS_DEFS_H__ -+ -+/* Transaction error codes defined in Master command register (0x30) */ -+#define MSTR_STS_XACT_SUCCESS 0 -+#define MSTR_STS_LOST_ARB 1 -+#define MSTR_STS_NACK_FIRST_BYTE 2 -+#define MSTR_STS_NACK_NON_FIRST_BYTE 3 /* NACK on a byte other than -+ the first byte */ -+#define MSTR_STS_TTIMEOUT_EXCEEDED 4 -+#define MSTR_STS_TX_TLOW_MEXT_EXCEEDED 5 -+#define MSTR_STS_RX_TLOW_MEXT_EXCEEDED 6 -+ -+/* SMBUS protocol values defined in register 0x30 */ -+#define SMBUS_PROT_QUICK_CMD 0 -+#define SMBUS_PROT_SEND_BYTE 1 -+#define SMBUS_PROT_RECV_BYTE 2 -+#define SMBUS_PROT_WR_BYTE 3 -+#define SMBUS_PROT_RD_BYTE 4 -+#define SMBUS_PROT_WR_WORD 5 -+#define SMBUS_PROT_RD_WORD 6 -+#define SMBUS_PROT_BLK_WR 7 -+#define SMBUS_PROT_BLK_RD 8 -+#define SMBUS_PROT_PROC_CALL 9 -+#define SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL 10 -+ -+#define BUS_BUSY_COUNT 100000 /* Number can be changed later */ -+ -+#define DISABLE_INTR 0 -+#define ENABLE_INTR 1 -+#endif /* __IPROC_SMBUS_DEFS_H__ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/iproc_smbus_regs.h b/drivers/i2c/busses/iproc_smbus_regs.h ---- a/drivers/i2c/busses/iproc_smbus_regs.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/i2c/busses/iproc_smbus_regs.h 2017-11-09 17:53:33.706235000 +0800 -@@ -0,0 +1,290 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ */ -+ -+#ifndef __IPROC_SMBUS_REGS_H__ -+#define __IPROC_SMBUS_REGS_H__ -+ -+/* --- */ -+#define CCB_SMB_CFG_REG 0x0 -+ -+#define CCB_SMB_CFG_RST_MASK 0x80000000 -+#define CCB_SMB_CFG_RST_SHIFT 31 -+ -+#define CCB_SMB_CFG_SMBEN_MASK 0x40000000 -+#define CCB_SMB_CFG_SMBEN_SHIFT 30 -+ -+#define CCB_SMB_CFG_BITBANGEN_MASK 0x20000000 -+#define CCB_SMB_CFG_BITBANGEN_SHIFT 29 -+ -+#define CCB_SMB_CFG_EN_NIC_SMBADDR0_MASK 0x10000000 -+#define CCB_SMB_CFG_EN_NIC_SMBADDR0_SHIFT 28 -+ -+#define CCB_SMB_CFG_PROMISCMODE_MASK 0x08000000 -+#define CCB_SMB_CFG_PROMISCMODE_SHIFT 27 -+ -+#define CCB_SMB_CFG_TSTMPCNTEN_MASK 0x04000000 -+#define CCB_SMB_CFG_TSTMPCNTEN_SHIFT 26 -+ -+#define CCB_SMB_CFG_MSTRRTRYCNT_MASK 0x000F0000 -+#define CCB_SMB_CFG_MSTRRTRYCNT_SHIFT 16 -+ -+ -+/* --- */ -+#define CCB_SMB_TIMGCFG_REG 0x4 -+ -+#define CCB_SMB_TIMGCFG_MODE400_MASK 0x80000000 -+#define CCB_SMB_TIMGCFG_MODE400_SHIFT 31 -+ -+#define CCB_SMB_TIMGCFG_RNDSLVSTR_MASK 0x7F000000 -+#define CCB_SMB_TIMGCFG_RNDSLVSTR_SHIFT 24 -+ -+#define CCB_SMB_TIMGCFG_PERSLVSTR_MASK 0x00FF0000 -+#define CCB_SMB_TIMGCFG_PERSLVSTR_SHIFT 16 -+ -+#define CCB_SMB_TIMGCFG_IDLTIME_MASK 0x0000FF00 -+#define CCB_SMB_TIMGCFG_IDLTIME_SHIFT 8 -+ -+/* --- */ -+#define CCB_SMB_ADDR_REG 0x8 -+ -+#define CCB_SMB_EN_NIC_SMBADDR3_MASK 0x80000000 -+#define CCB_SMB_EN_NIC_SMBADDR3_SHIFT 31 -+ -+#define CCB_SMB_NIC_SMBADDR3_MASK 0x7F000000 -+#define CCB_SMB_NIC_SMBADDR3_SHIFT 24 -+ -+#define CCB_SMB_EN_NIC_SMBADDR2_MASK 0x00800000 -+#define CCB_SMB_EN_NIC_SMBADDR2_SHIFT 23 -+ -+#define CCB_SMB_NIC_SMBADDR2_MASK 0x007F0000 -+#define CCB_SMB_NIC_SMBADDR2_SHIFT 16 -+ -+#define CCB_SMB_EN_NIC_SMBADDR1_MASK 0x00008000 -+#define CCB_SMB_EN_NIC_SMBADDR1_SHIFT 15 -+ -+#define CCB_SMB_NIC_SMBADDR1_MASK 0x00007F00 -+#define CCB_SMB_NIC_SMBADDR1_SHIFT 8 -+ -+#define CCB_SMB_EN_NIC_SMBADDR0_MASK 0x00000080 -+#define CCB_SMB_EN_NIC_SMBADDR0_SHIFT 7 -+ -+#define CCB_SMB_NIC_SMBADDR0_MASK 0x0000007F -+#define CCB_SMB_NIC_SMBADDR0_SHIFT 0 -+ -+/* --- */ -+#define CCB_SMB_MSTRFIFOCTL_REG 0xC -+ -+#define CCB_SMB_MSTRRXFIFOFLSH_MASK 0x80000000 -+#define CCB_SMB_MSTRRXFIFOFLSH_SHIFT 31 -+ -+#define CCB_SMB_MSTRTXFIFOFLSH_MASK 0x40000000 -+#define CCB_SMB_MSTRTXFIFOFLSH_SHIFT 30 -+ -+#define CCB_SMB_MSTRRXPKTCNT_MASK 0x007F0000 -+#define CCB_SMB_MSTRRXPKTCNT_SHIFT 16 -+ -+#define CCB_SMB_MSTRRXFIFOTHR_MASK 0x00003F00 -+#define CCB_SMB_MSTRRXFIFOTHR_SHIFT 8 -+ -+/* --- */ -+#define CCB_SMB_SLVFIFOCTL_REG 0x10 -+ -+#define CCB_SMB_SLVRXFIFOFLSH_MASK 0x80000000 -+#define CCB_SMB_SLVRXFIFOFLSH_SHIFT 31 -+ -+#define CCB_SMB_SLVTXFIFOFLSH_MASK 0x40000000 -+#define CCB_SMB_SLVTXFIFOFLSH_SHIFT 30 -+ -+#define CCB_SMB_SLVRXPKTCNT_MASK 0x007F0000 -+#define CCB_SMB_SLVRXPKTCNT_SHIFT 16 -+ -+#define CCB_SMB_SLVRXFIFOTHR_MASK 0x00003F00 -+#define CCB_SMB_SLVRXFIFOTHR_SHIFT 8 -+ -+/* --- */ -+#define CCB_SMB_BITBANGCTL_REG 0x14 -+ -+#define CCB_SMB_SMBCLKIN_MASK 0x80000000 -+#define CCB_SMB_SMBCLKIN_SHIFT 31 -+ -+#define CCB_SMB_SMBCLKOUTEN_MASK 0x40000000 -+#define CCB_SMB_SMBCLKOUTEN_SHIFT 30 -+ -+#define CCB_SMB_SMBDATAIN_MASK 0x20000000 -+#define CCB_SMB_SMBDATAIN_SHIFT 29 -+ -+#define CCB_SMB_SMBDATAOUTEN_MASK 0x10000000 -+#define CCB_SMB_SMBDATAOUTEN_SHIFT 28 -+ -+/* --- */ -+#define CCB_SMB_MSTRCMD_REG 0x30 -+ -+#define CCB_SMB_MSTRSTARTBUSYCMD_MASK 0x80000000 -+#define CCB_SMB_MSTRSTARTBUSYCMD_SHIFT 31 -+ -+#define CCB_SMB_MSTRABORT_MASK 0x40000000 -+#define CCB_SMB_MSTRABORT_SHIFT 30 -+ -+#define CCB_SMB_MSTRSTS_MASK 0x0E000000 -+#define CCB_SMB_MSTRSTS_SHIFT 25 -+ -+#define CCB_SMB_MSTRSMBUSPROTO_MASK 0x00001E00 -+#define CCB_SMB_MSTRSMBUSPROTO_SHIFT 9 -+ -+#define CCB_SMB_MSTRPEC_MASK 0x00000100 -+#define CCB_SMB_MSTRPEC_SHIFT 8 -+ -+#define CCB_SMB_MSTRRDBYTECNT_MASK 0x000000FF -+#define CCB_SMB_MSTRRDBYTECNT_SHIFT 0 -+ -+/* --- */ -+#define CCB_SMB_SLVCMD_REG 0x34 -+ -+#define CCB_SMB_SLVSTARTBUSYCMD_MASK 0x80000000 -+#define CCB_SMB_SLVSTARTBUSYCMD_SHIFT 31 -+ -+#define CCB_SMB_SLVABORT_MASK 0x40000000 -+#define CCB_SMB_SLVABORT_SHIFT 30 -+ -+#define CCB_SMB_SLVSTS_MASK 0x03800000 -+#define CCB_SMB_SLVSTS_SHIFT 23 -+ -+#define CCB_SMB_SLVPEC_MASK 0x00000100 -+#define CCB_SMB_SLVPEC_SHIFT 8 -+ -+ -+/* --- */ -+#define CCB_SMB_EVTEN_REG 0x38 -+ -+#define CCB_SMB_MSTRRXFIFOFULLEN_MASK 0x80000000 -+#define CCB_SMB_MSTRRXFIFOFULLEN_SHIFT 31 -+ -+#define CCB_SMB_MSTRRXFIFOTHRHITEN_MASK 0x40000000 -+#define CCB_SMB_MSTRRXFIFOTHRHITEN_SHIFT 30 -+ -+#define CCB_SMB_MSTRRXEVTEN_MASK 0x20000000 -+#define CCB_SMB_MSTRRXEVTEN_SHIFT 29 -+ -+#define CCB_SMB_MSTRSTARTBUSYEN_MASK 0x10000000 -+#define CCB_SMB_MSTRSTARTBUSYEN_SHIFT 28 -+ -+#define CCB_SMB_MSTRTXUNDEN_MASK 0x08000000 -+#define CCB_SMB_MSTRTXUNDEN_SHIFT 27 -+ -+ -+#define CCB_SMB_SLVRXFIFOFULLEN_MASK 0x04000000 -+#define CCB_SMB_SLVRXFIFOFULLEN_SHIFT 26 -+ -+#define CCB_SMB_SLVRXFIFOTHRHITEN_MASK 0x02000000 -+#define CCB_SMB_SLVRXFIFOTHRHITEN_SHIFT 25 -+ -+#define CCB_SMB_SLVRXEVTEN_MASK 0x01000000 -+#define CCB_SMB_SLVRXEVTEN_SHIFT 24 -+ -+#define CCB_SMB_SLVSTARTBUSYEN_MASK 0x00800000 -+#define CCB_SMB_SLVSTARTBUSYEN_SHIFT 23 -+ -+#define CCB_SMB_SLVTXUNDEN_MASK 0x00400000 -+#define CCB_SMB_SLVTXUNDEN_SHIFT 22 -+ -+#define CCB_SMB_SLVRDEVTEN_MASK 0x00200000 -+#define CCB_SMB_SLVRDEVTEN_SHIFT 21 -+ -+ -+/* --- */ -+#define CCB_SMB_EVTSTS_REG 0x3C -+ -+#define CCB_SMB_MSTRRXFIFOFULLSTS_MASK 0x80000000 -+#define CCB_SMB_MSTRRXFIFOFULLSTS_SHIFT 31 -+ -+#define CCB_SMB_MSTRRXFIFOTHRHITSTS_MASK 0x40000000 -+#define CCB_SMB_MSTRRXFIFOTHRHITSTS_SHIFT 30 -+ -+#define CCB_SMB_MSTRRXEVTSTS_MASK 0x20000000 -+#define CCB_SMB_MSTRRXEVTSTS_SHIFT 29 -+ -+#define CCB_SMB_MSTRSTARTBUSYSTS_MASK 0x10000000 -+#define CCB_SMB_MSTRSTARTBUSYSTS_SHIFT 28 -+ -+#define CCB_SMB_MSTRTXUNDSTS_MASK 0x08000000 -+#define CCB_SMB_MSTRTXUNDSTS_SHIFT 27 -+ -+ -+#define CCB_SMB_SLVRXFIFOFULLSTS_MASK 0x04000000 -+#define CCB_SMB_SLVRXFIFOFULLSTS_SHIFT 26 -+ -+#define CCB_SMB_SLVRXFIFOTHRHITSTS_MASK 0x02000000 -+#define CCB_SMB_SLVRXFIFOTHRHITSTS_SHIFT 25 -+ -+#define CCB_SMB_SLVRXEVTSTS_MASK 0x01000000 -+#define CCB_SMB_SLVRXEVTSTS_SHIFT 24 -+ -+#define CCB_SMB_SLVSTARTBUSYSTS_MASK 0x00800000 -+#define CCB_SMB_SLVSTARTBUSYSTS_SHIFT 23 -+ -+#define CCB_SMB_SLVTXUNDSTS_MASK 0x00400000 -+#define CCB_SMB_SLVTXUNDSTS_SHIFT 22 -+ -+#define CCB_SMB_SLVRDEVTSTS_MASK 0x00200000 -+#define CCB_SMB_SLVRDEVTSTS_SHIFT 21 -+ -+ -+/* --- */ -+#define CCB_SMB_MSTRDATAWR_REG 0x40 -+ -+#define CCB_SMB_MSTRWRSTS_MASK 0x80000000 -+#define CCB_SMB_MSTRWRSTS_SHIFT 31 -+ -+#define CCB_SMB_MSTRWRDATA_MASK 0x000000FF -+#define CCB_SMB_MSTRWRDATA_SHIFT 0 -+ -+ -+/* --- */ -+#define CCB_SMB_MSTRDATARD_REG 0x44 -+ -+#define CCB_SMB_MSTRRDSTS_MASK 0xC0000000 -+#define CCB_SMB_MSTRRDSTS_SHIFT 30 -+ -+#define CCB_SMB_MSTRRDPECERR_MASK 0x20000000 -+#define CCB_SMB_MSTRRDPECERR_SHIFT 29 -+ -+#define CCB_SMB_MSTRRDDATA_MASK 0x000000FF -+#define CCB_SMB_MSTRRDDATA_SHIFT 0 -+ -+ -+/* --- */ -+#define CCB_SMB_SLVDATAWR_REG 0x48 -+ -+#define CCB_SMB_SLVWRSTS_MASK 0x80000000 -+#define CCB_SMB_SLVWRSTS_SHIFT 31 -+ -+#define CCB_SMB_SLVWRDATA_MASK 0x000000FF -+#define CCB_SMB_SLVWRDATA_SHIFT 0 -+ -+ -+/* --- */ -+#define CCB_SMB_SLVDATARD_REG 0x4C -+ -+#define CCB_SMB_SLVRDSTS_MASK 0xC0000000 -+#define CCB_SMB_SLVRDSTS_SHIFT 30 -+ -+#define CCB_SMB_SLVRDERRSTS_MASK 0x30000000 -+#define CCB_SMB_SLVRDERRSTS_SHIFT 28 -+ -+#define CCB_SMB_SLVRDDATA_MASK 0x000000FF -+#define CCB_SMB_SLVRDDATA_SHIFT 0 -+ -+#endif /* __IPROC_SMBUS_REGS_H__ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/xgs_iproc_smbus.c b/drivers/i2c/busses/xgs_iproc_smbus.c ---- a/drivers/i2c/busses/xgs_iproc_smbus.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/i2c/busses/xgs_iproc_smbus.c 2017-11-09 17:53:33.709223000 +0800 -@@ -0,0 +1,2014 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "iproc_smbus_regs.h" -+#include "iproc_smbus_defs.h" -+#include "iproc_smbus.h" -+ -+#ifdef CONFIG_OF -+#include -+#include -+#include -+#endif /* CONFIG_OF */ -+ -+#undef IPROC_SMB_DBG -+ -+/* Support I2C devices without length field xfer*/ -+//#define SMB_BLOCK_XFER_VARIANT -+ -+#define SMB_MAX_DATA_SIZE 32 -+#define SMB_BLK_XFER_TEST -+ -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 37) -+#define init_MUTEX(x) sema_init(x,1) -+#endif -+ -+static struct proc_dir_entry *gProcParent=NULL; -+//static int use_svk_version; -+#undef CONFIG_USE_SVK_VERSION -+ -+static int smb_in_intr; -+ -+static struct iproc_smb_drv_int_data *iproc_smbus_list = NULL; -+static int iproc_smbus_block_init(struct iproc_smb_drv_int_data *dev); -+ -+/* Function to read a value from specified register. */ -+static unsigned int iproc_smb_reg_read(unsigned long reg_addr) -+{ -+ unsigned int val; -+ -+ val = ioread32((void *)reg_addr); -+ -+#ifdef IPROC_SMB_DBG -+ if (!smb_in_intr) { -+ printk(KERN_DEBUG "\nRd: addr:0x%08X, val:0x%08X", (unsigned int)reg_addr, val); -+ } -+#endif -+ -+ return(val); -+} -+ -+/* Function to write a value ('val') in to a specified register. */ -+static int iproc_smb_reg_write(unsigned long reg_addr, unsigned int val) -+{ -+ iowrite32(val, (void *)reg_addr); -+ -+#ifdef IPROC_SMB_DBG -+ if (!smb_in_intr) { -+ printk(KERN_DEBUG "\nWr: addr:0x%08X, val:0x%08X", (unsigned int)reg_addr, val); -+ } -+#endif -+ -+ return (0); -+} -+ -+#ifdef IPROC_SMB_DBG -+static int iproc_dump_smb_regs(struct iproc_smb_drv_int_data *dev) -+{ -+ unsigned int regval; -+ unsigned long base_addr = (unsigned long)dev->block_base_addr; -+ -+ printk(KERN_DEBUG "\n----------------------------------------------"); -+ -+ printk(KERN_DEBUG "\nBase addr=0x%08X", (unsigned int)base_addr); -+ -+ printk(KERN_DEBUG "%s: Dumping SMBus registers... ", __func__); -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_CFG_REG); -+ printk(KERN_DEBUG "\nCCB_SMB_CFG_REG=0x%08X", regval); -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_TIMGCFG_REG); -+ printk(KERN_DEBUG "\nCCB_SMB_TIMGCFG_REG=0x%08X", regval); -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_ADDR_REG); -+ printk(KERN_DEBUG "\nCCB_SMB_ADDR_REG=0x%08X", regval); -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_MSTRFIFOCTL_REG); -+ printk(KERN_DEBUG "\nCCB_SMB_MSTRFIFOCTL_REG=0x%08X", regval); -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_SLVFIFOCTL_REG); -+ printk(KERN_DEBUG "\nCCB_SMB_SLVFIFOCTL_REG=0x%08X", regval); -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_BITBANGCTL_REG); -+ printk(KERN_DEBUG "\nCCB_SMB_BITBANGCTL_REG=0x%08X", regval); -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_MSTRCMD_REG); -+ printk(KERN_DEBUG "\nCCB_SMB_MSTRCMD_REG=0x%08X", regval); -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_SLVCMD_REG); -+ printk(KERN_DEBUG "\nCCB_SMB_SLVCMD_REG=0x%08X", regval); -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_EVTEN_REG); -+ printk(KERN_DEBUG "\nCCB_SMB_EVTEN_REG=0x%08X", regval); -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_EVTSTS_REG); -+ printk(KERN_DEBUG "\nCCB_SMB_EVTSTS_REG=0x%08X", regval); -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_MSTRDATAWR_REG); -+ printk(KERN_DEBUG "\nCCB_SMB_MSTRDATAWR_REG=0x%08X", regval); -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_MSTRDATARD_REG); -+ printk(KERN_DEBUG "\nCCB_SMB_MSTRDATARD_REG=0x%08X", regval); -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_SLVDATAWR_REG); -+ printk(KERN_DEBUG "\nCCB_SMB_SLVDATAWR_REG=0x%08X", regval); -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_SLVDATARD_REG); -+ printk(KERN_DEBUG "\nCCB_SMB_SLVDATARD_REG=0x%08X", regval); -+ -+ printk(KERN_DEBUG "\n----------------------------------------------\n\n"); -+ -+ return(0); -+} -+#endif /* IPROC_SMB_DBG */ -+ -+static irqreturn_t iproc_smb_isr(int irq, void*devid) -+{ -+ struct iproc_smb_drv_int_data *dev = -+ (struct iproc_smb_drv_int_data *)devid; -+ unsigned int intsts; -+ unsigned int regval; -+ -+ -+ smb_in_intr = 1; -+ -+ intsts = iproc_smb_reg_read((unsigned long)dev->block_base_addr + -+ CCB_SMB_EVTSTS_REG); -+ -+ dev->smb_counters.last_int_sts = intsts; -+ -+ if (!intsts) { -+ -+ /* Likely received a spurious interrupt */ -+ -+ return IRQ_NONE; -+ -+ } -+ -+ /* Clear interrupts */ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + -+ CCB_SMB_EVTSTS_REG, intsts); -+ -+ /* Master read or write complete */ -+ if ((intsts & CCB_SMB_MSTRSTARTBUSYEN_MASK) || -+ (intsts & CCB_SMB_MSTRRXEVTSTS_MASK)) { -+ -+ if (intsts & CCB_SMB_MSTRSTARTBUSYEN_MASK) { -+ -+ dev->smb_counters.mstr_start_busy_cnt++; -+ -+ } -+ -+ if (intsts & CCB_SMB_MSTRRXEVTSTS_MASK) { -+ -+ dev->smb_counters.mstr_rx_evt_cnt++; -+ -+ } -+ -+ /* In case of a receive transaction, data will be copied in the recv -+ * function -+ */ -+ complete(&dev->ses_done); -+ -+ } -+ -+ /* If RX FIFO was full we can either read and then flush the FIFO. Or, only -+ * flush the FIFO (since the client process did not read the data on time), -+ * and then the client process can restart the transaction -+ * For now, we will flush the later action. -+ */ -+ if (intsts & CCB_SMB_MSTRRXFIFOFULLSTS_MASK) { -+ -+ dev->smb_counters.mstr_rx_fifo_full_cnt++; -+ -+ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + -+ CCB_SMB_MSTRFIFOCTL_REG); -+ -+ regval |= CCB_SMB_MSTRRXFIFOFLSH_MASK; -+ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + -+ CCB_SMB_MSTRFIFOCTL_REG, regval); -+ -+ complete(&dev->ses_done); -+ -+ } -+ -+ smb_in_intr = 0; -+ -+ return IRQ_HANDLED; -+} -+ -+/* -+ * Function to ensure that the previous transaction was completed before -+ * initiating a new transaction. It can also be used in polling mode to -+ * check status of completion of a command -+ */ -+static int iproc_smb_startbusy_wait(struct iproc_smb_drv_int_data *dev) -+{ -+ unsigned int regval; -+ -+ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + -+ CCB_SMB_MSTRCMD_REG); -+ -+ /* Check if an operation is in progress. During probe it won't be. -+ * But when shutdown/remove was called we want to make sure that -+ * the transaction in progress completed -+ */ -+ if (regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK) { -+ unsigned int i = 0; -+ -+ do { -+ -+ msleep(1); /* Wait for 1 msec */ -+ -+ i++; -+ -+ regval = iproc_smb_reg_read( -+ (unsigned long)dev->block_base_addr + CCB_SMB_MSTRCMD_REG); -+ -+ /* If start-busy bit cleared, exit the loop */ -+ } while ((regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK) && -+ (i < IPROC_SMB_MAX_RETRIES)); -+ -+ if (i >= IPROC_SMB_MAX_RETRIES) { -+ printk(KERN_ERR "%s: %s START_BUSY bit didn't clear, exiting\n", -+ __func__, dev->adapter.name); -+ return -ETIMEDOUT; -+ -+ } -+ -+ } -+ -+ return 0; -+} -+ -+ -+static unsigned int smbus0_sdaRecoveryCnt = 0, smbus0_sdaFailedCnt = 0, smbus0_startBusyCnt = 0; -+static unsigned int smbus1_sdaRecoveryCnt = 0, smbus1_sdaFailedCnt = 0, smbus1_startBusyCnt = 0; -+ -+/* -+ * Function to recover SMB hangs caused stuck master START_BUSY. -+ * Returns 0 if recovery procedure executed successfully. -+ * Returns -1 if recovery failed. -+ */ -+static int iproc_smb_startbusy_recovery(struct iproc_smb_drv_int_data *dev) -+{ -+ int rc = -1; -+ unsigned int recoveryCnt; -+ -+ if (dev->adapter.nr == 0) { -+ recoveryCnt = ++smbus0_startBusyCnt; -+ } -+ else { -+ recoveryCnt = ++smbus1_startBusyCnt; -+ } -+ -+ printk(KERN_INFO "%s: %s START_BUSY recovery #%d \n", __func__, dev->adapter.name, recoveryCnt); -+ -+ /* reset the SMBus block, wait a minimum of 50 uSecs and then re-initialize */ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG, CCB_SMB_CFG_RST_MASK); -+ udelay(60); -+ -+ if ( iproc_smbus_block_init(dev) == 0 ) { -+ rc = 0; -+ } -+ -+ return rc; -+} -+ -+ -+ -+/* -+ * Function to recover SMB hang caused by a slave device holding SDA low. -+ * Returns 0 if recovery procedure executed successfully. -+ * Returns -1 if recovery failed. -+ */ -+ -+static int iproc_smb_sda_low_recovery(struct iproc_smb_drv_int_data *dev) -+{ -+ unsigned int bbReg, cfgReg, cfgSave, recoveryCnt, failedCnt, i; -+ int rc = -1; -+ -+ -+ /* enable bit-bang */ -+ cfgSave = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG); -+ cfgReg = cfgSave; -+ cfgReg |= CCB_SMB_CFG_BITBANGEN_MASK; -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG, cfgReg); -+ udelay(50); -+ -+ /* start with clock and SDA set high */ -+ bbReg = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG); -+ -+ bbReg |= (CCB_SMB_SMBCLKOUTEN_MASK | CCB_SMB_SMBDATAOUTEN_MASK); -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG, bbReg); -+ udelay(5); /* should be sufficient for 100 KHz bus */ -+ -+ /* set up to toggle the clock line with SDA out held high for 9 cycles */ -+ for (i=0; i<18; i++) -+ { -+ /* toggle CLK out */ -+ if ( (bbReg & CCB_SMB_SMBCLKOUTEN_MASK) == 0 ) { -+ bbReg |= CCB_SMB_SMBCLKOUTEN_MASK; /* set clock high */ -+ } -+ else { -+ bbReg &= ~CCB_SMB_SMBCLKOUTEN_MASK; /* set clock low */ -+ } -+ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG, bbReg); -+ udelay(5); -+ } -+ -+ /* check bit 29 -- SMBDAT_IN and make sure SDA not being held low any more */ -+ for ( i=0; i<10; i++ ) -+ { -+ bbReg = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG); -+ bbReg &= CCB_SMB_SMBDATAIN_MASK; -+ -+ if (bbReg) -+ break; -+ -+ udelay(1); -+ } -+ -+ if ( bbReg == 0 ) { -+ /* SDA is still low */ -+ if (dev->adapter.nr == 0) { -+ failedCnt = ++smbus0_sdaFailedCnt; -+ } -+ else { -+ failedCnt = ++smbus1_sdaFailedCnt; -+ } -+ printk(KERN_INFO "\n%s: %s SDA release #%d FAILED.\n", __func__, dev->adapter.name, failedCnt); -+ } -+ else { -+ if (dev->adapter.nr == 0) { -+ recoveryCnt = ++smbus0_sdaRecoveryCnt; -+ } -+ else { -+ recoveryCnt = ++smbus1_sdaRecoveryCnt; -+ } -+ -+ printk(KERN_INFO "%s: %s SDA release #%d SUCCESSFUL.\n", __func__, dev->adapter.name, recoveryCnt); -+ rc = 0; -+ } -+ -+ -+ /* manually issue a stop by transitioning SDA from low to high with clock held high */ -+ bbReg = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG); -+ bbReg &= ~CCB_SMB_SMBCLKOUTEN_MASK; /* set clock low */ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG, bbReg); -+ udelay(2); -+ -+ bbReg &= ~CCB_SMB_SMBDATAOUTEN_MASK; /* drop SDA low */ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG, bbReg); -+ udelay(2); -+ -+ bbReg |= CCB_SMB_SMBCLKOUTEN_MASK; /* set clock high */ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG, bbReg); -+ udelay(5); -+ -+ bbReg |= CCB_SMB_SMBDATAOUTEN_MASK; /* pull SDA high */ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG, bbReg); -+ udelay(2); -+ -+ -+ /* disable bit-bang and then re-enable the SMB with the saved configuration */ -+ cfgReg = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG); -+ cfgReg &= ~CCB_SMB_CFG_BITBANGEN_MASK; -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG, cfgReg); -+ udelay(10); -+ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG, cfgSave); -+ -+ return rc; -+} -+ -+ -+/* -+ * Function to recover SMB hang caused by a slave device hold SDA low. -+ * Returns 0 if recovery procedure executed successfully. -+ * Returns -1 if recovery failed. -+ */ -+static int iproc_smb_timeout_recovery(struct iproc_smb_drv_int_data *dev) -+{ -+ unsigned int bbReg, mCmdReg; -+ int rc = -1; -+ -+ /* read bit-bang control. If SDA low, attempt SDA release recovery */ -+ bbReg = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_BITBANGCTL_REG); -+ -+ if ( (bbReg & CCB_SMB_SMBDATAIN_MASK) == 0 ) { -+ if ( iproc_smb_sda_low_recovery( dev ) == 0 ) { -+ rc = 0; -+ } -+ } -+ -+ /* regardless of whether there was an SDA hang or not, see if START_BUSY stuck high */ -+ mCmdReg = iproc_smb_reg_read( (unsigned long)dev->block_base_addr + CCB_SMB_MSTRCMD_REG ); -+ if ( mCmdReg & CCB_SMB_MSTRSTARTBUSYCMD_MASK ) { -+ /* attempt to recover the bus */ -+ if (iproc_smb_startbusy_recovery(dev) == 0) { -+ rc = 0; -+ } -+ } -+ -+ return rc; -+ -+} -+ -+/* -+ * This function copies data to SMBus's Tx FIFO. Valid for write transactions -+ * only -+ * -+ * base_addr: Mapped address of this SMBus instance -+ * dev_addr: SMBus (I2C) device address. We are assuming 7-bit addresses -+ * initially -+ * info: Data to copy in to Tx FIFO. For read commands, the size should be -+ * set to zero by the caller -+ * -+ */ -+static void iproc_smb_write_trans_data(unsigned long base_addr, -+ unsigned short dev_addr, -+ struct iproc_xact_info *info) -+{ -+ unsigned int regval; -+ unsigned int i; -+ unsigned int num_data_bytes = 0; -+ -+#ifdef IPROC_SMB_DBG -+ printk(KERN_DEBUG "\n%s: dev_addr=0x%X, offset=%u, cmd_valid=%u, size=%u\n", __func__, dev_addr, info->command, info->cmd_valid, info->size); -+#endif /* IPROC_SMB_DBG */ -+ -+ /* Write SMBus device address first */ -+ /* Note, we are assuming 7-bit addresses for now. For 10-bit addresses, -+ * we may have one more write to send the upper 3 bits of 10-bit addr -+ */ -+ iproc_smb_reg_write(base_addr + CCB_SMB_MSTRDATAWR_REG, dev_addr); -+ -+ /* If the protocol needs command code, copy it */ -+ if (info->cmd_valid == true) { -+ iproc_smb_reg_write(base_addr + CCB_SMB_MSTRDATAWR_REG, info->command); -+ } -+ -+ /* Depending on the SMBus protocol, we need to write additional transaction -+ * data in to Tx FIFO. Refer to section 5.5 of SMBus spec for sequence for a -+ * transaction -+ */ -+ switch (info->smb_proto) { -+ -+ case SMBUS_PROT_RECV_BYTE: -+ /* No additional data to be written */ -+ num_data_bytes = 0; -+ break; -+ -+ case SMBUS_PROT_SEND_BYTE: -+ num_data_bytes = info->size; -+ break; -+ -+ case SMBUS_PROT_RD_BYTE: -+ case SMBUS_PROT_RD_WORD: -+ case SMBUS_PROT_BLK_RD: -+ /* Write slave address with R/W~ set (bit #0) */ -+ iproc_smb_reg_write(base_addr + CCB_SMB_MSTRDATAWR_REG, dev_addr | 0x1); -+ num_data_bytes = 0; -+ break; -+ -+ case SMBUS_PROT_WR_BYTE: -+ case SMBUS_PROT_WR_WORD: -+ /* No additional bytes to be written. Data portion is written in the -+ * 'for' loop below -+ */ -+ num_data_bytes = info->size; -+ -+ /* Note for hx4 eeprom (at24c64). the low addr bytes can be passed -+ * in to 1st byte of info->data -+ */ -+ break; -+ -+ case SMBUS_PROT_BLK_WR: -+ /* 3rd byte is byte count */ -+#ifndef SMB_BLOCK_XFER_VARIANT -+ iproc_smb_reg_write(base_addr + CCB_SMB_MSTRDATAWR_REG, info->size); -+#endif -+ num_data_bytes = info->size; -+ break; -+ -+ case SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL: -+ /* Write byte count */ -+ iproc_smb_reg_write(base_addr + CCB_SMB_MSTRDATAWR_REG, info->size); -+ num_data_bytes = info->size; -+ break; -+ -+ default: -+ break; -+ -+ } -+ -+ /* Copy actual data from caller, next. In general, for reads, no data is -+ * copied -+ */ -+ for (i = 0; num_data_bytes; --num_data_bytes, i++) { -+ -+ /* For the last byte, set MASTER_WR_STATUS bit. For block rd/wr process -+ * call, we need to program slave addr after copying data byte(s), so -+ * master status bit is set later, after the loop -+ */ -+ if ((num_data_bytes == 1) && -+ (info->smb_proto != SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL)) { -+ regval = info->data[i] | CCB_SMB_MSTRWRSTS_MASK; -+ } -+ else { -+ regval = info->data[i]; -+ } -+ -+ iproc_smb_reg_write(base_addr + CCB_SMB_MSTRDATAWR_REG, regval); -+ -+ } -+ -+ if (info->smb_proto == SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL) { -+ /* Write device address needed during repeat start condition */ -+ iproc_smb_reg_write(base_addr + CCB_SMB_MSTRDATAWR_REG, -+ CCB_SMB_MSTRWRSTS_MASK | dev_addr | 0x1); -+ } -+ -+ return; -+} -+ -+static int iproc_smb_data_send(struct i2c_adapter *adapter, -+ unsigned short addr, -+ struct iproc_xact_info *info) -+{ -+ int rc; -+ unsigned int regval; -+ struct iproc_smb_drv_int_data *dev = i2c_get_adapdata(adapter); -+ unsigned long time_left; -+ -+ -+ /* Make sure the previous transaction completed */ -+ rc = iproc_smb_startbusy_wait(dev); -+ -+ if (rc < 0) { -+ printk(KERN_ERR "%s: Send: %s bus is busy, attempt recovery \n", __func__, dev->adapter.name); -+ /* attempt to recover the bus */ -+ if (iproc_smb_startbusy_recovery(dev) != 0) { -+ return rc; -+ } -+ } -+ -+ if (dev->enable_evts == ENABLE_INTR) { -+ -+ /* Enable start_busy interrupt */ -+ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + -+ CCB_SMB_EVTEN_REG); -+ -+ regval |= CCB_SMB_MSTRSTARTBUSYEN_MASK; -+ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + -+ CCB_SMB_EVTEN_REG, regval); -+ -+ /* Mark as incomplete before sending the data */ -+ reinit_completion(&dev->ses_done); -+ -+ } -+ -+ /* Write transaction bytes to Tx FIFO */ -+ iproc_smb_write_trans_data((unsigned long)dev->block_base_addr, addr, info); -+ -+ /* Program master command register (0x30) with protocol type and set -+ * start_busy_command bit to initiate the write transaction -+ */ -+ regval = (info->smb_proto << CCB_SMB_MSTRSMBUSPROTO_SHIFT) | -+ CCB_SMB_MSTRSTARTBUSYCMD_MASK; -+ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_MSTRCMD_REG, regval); -+ if (dev->enable_evts == ENABLE_INTR) { -+ /* -+ * Block waiting for the transaction to finish. When it's finished, -+ * we'll be signaled by an interrupt -+ */ -+ time_left = wait_for_completion_timeout(&dev->ses_done, XACT_TIMEOUT); -+ /* Disable start_busy interrupt */ -+ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG); -+ regval &= ~CCB_SMB_MSTRSTARTBUSYEN_MASK; -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG, regval); -+ -+ if (time_left == 0) { -+ printk (KERN_INFO "%s: Send: %s timeout accessing device x%02x\n", -+ __func__, dev->adapter.name, addr); -+ -+ /* attempt to recover the bus */ -+ rc = iproc_smb_timeout_recovery(dev); -+ if ( rc != 0 ) { -+ return -ETIMEDOUT; -+ } -+ else { -+ return -ECOMM; -+ } -+ } -+ } -+ -+ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_MSTRCMD_REG); -+ -+ /* If start_busy bit cleared, check if there are any errors */ -+ if (!(regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK)) { -+ /* start_busy bit cleared, check master_status field now */ -+ regval &= CCB_SMB_MSTRSTS_MASK; -+ regval >>= CCB_SMB_MSTRSTS_SHIFT; -+ -+ if (regval != MSTR_STS_XACT_SUCCESS) { -+ /* We can flush Tx FIFO here */ -+ printk(KERN_ERR "\n\n%s:Send: %s Error in transaction %d to device x%02x, exiting\n", -+ __func__, dev->adapter.name, regval, addr); -+ -+ return -EREMOTEIO; -+ } -+ } -+ -+ return(0); -+} -+ -+static int iproc_smb_data_recv(struct i2c_adapter *adapter, -+ unsigned short addr, -+ struct iproc_xact_info *info, -+ unsigned int *num_bytes_read) -+{ -+ int rc; -+ unsigned int regval; -+ struct iproc_smb_drv_int_data *dev = i2c_get_adapdata(adapter); -+ unsigned long time_left; -+ -+ /* Make sure the previous transaction completed */ -+ rc = iproc_smb_startbusy_wait(dev); -+ -+ if (rc < 0) { -+ printk(KERN_ERR "%s: Receive: %s bus is busy, attempt recovery \n", __func__, dev->adapter.name); -+ /* attempt to recover the bus */ -+ if (iproc_smb_startbusy_recovery(dev) != 0) { -+ return rc; -+ } -+ } -+ -+ if (dev->enable_evts == ENABLE_INTR) { -+ /* Enable start_busy interrupt */ -+ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG); -+ -+ /* Set Rx_event_en bit for notification of reception event */ -+ regval |= (CCB_SMB_MSTRSTARTBUSYEN_MASK); -+ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG, regval); -+ -+ /* Mark as incomplete before sending the data */ -+ reinit_completion(&dev->ses_done); -+ } -+ -+ /* Program all transaction bytes into master Tx FIFO */ -+ iproc_smb_write_trans_data((unsigned long)dev->block_base_addr, addr, info); -+ -+ /* Program master command register (0x30) with protocol type and set -+ * start_busy_command bit to initiate the write transaction -+ */ -+ regval = (info->smb_proto << CCB_SMB_MSTRSMBUSPROTO_SHIFT) | -+ CCB_SMB_MSTRSTARTBUSYCMD_MASK | info->size; -+ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + -+ CCB_SMB_MSTRCMD_REG, regval); -+ -+ if (dev->enable_evts == ENABLE_INTR) { -+ /* -+ * Block waiting for the transaction to finish. When it's finished, -+ * we'll be signaled by an interrupt -+ */ -+ time_left = wait_for_completion_timeout(&dev->ses_done, XACT_TIMEOUT); -+ -+ /* Disable start_busy and rx_event interrupts. Above call has handled -+ * the interrupt -+ */ -+ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG); -+ regval &= ~(CCB_SMB_MSTRSTARTBUSYEN_MASK); -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG, regval); -+ -+ if (time_left == 0) { -+ printk (KERN_ERR "\n%s: Receive: %s timeout accessing device 0x%02x\n", -+ __func__, dev->adapter.name, addr); -+ /* attempt to recover the bus */ -+ rc = iproc_smb_timeout_recovery(dev); -+ if ( rc != 0 ) { -+ return -ETIMEDOUT; -+ } -+ else { -+ return -ECOMM; -+ } -+ } -+ } -+ -+ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_MSTRCMD_REG); -+ -+ /* If start_busy bit cleared, check if there are any errors */ -+ if (!(regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK)) { -+ /* start_busy bit cleared, check master_status field now */ -+ regval &= CCB_SMB_MSTRSTS_MASK; -+ regval >>= CCB_SMB_MSTRSTS_SHIFT; -+ -+ if (regval != MSTR_STS_XACT_SUCCESS) { -+ /* We can flush Tx FIFO here */ -+ printk(KERN_INFO "\n%s: %s Error in transaction %d to device x%02x, exiting\n", -+ __func__, dev->adapter.name, regval, addr); -+ return -EREMOTEIO; -+ } -+ } -+ -+ /* In the isr we will read the received byte, and also deal with -+ * rx fifo full event. The above check is for timeout error. If needed -+ * we may move it to rx isr -+ */ -+ -+ /* For block read, protocol (hw) returns byte count, as the first byte */ -+ if ((info->smb_proto == SMBUS_PROT_BLK_RD) || (info->smb_proto == SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL)) { -+ int i, adj; -+#ifndef SMB_BLOCK_XFER_VARIANT -+ /* Read received byte(s) */ -+ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_MSTRDATARD_REG); -+ *num_bytes_read = regval & CCB_SMB_MSTRRDDATA_MASK; -+#else -+ *num_bytes_read = info->size; -+#endif -+ adj = 0; -+ -+ /* Limit to reading a max of 32 bytes only; just a safeguard. If -+ * # bytes read is a number > 32, check transaction set up, and contact -+ * hw engg. Assumption: PEC is disabled -+ */ -+ /* SMBUS spec ver. 3 (2015) extends max block transfer byte count from 32 to 256 */ -+ /* Use SMB_MAX_DATA_SIZE (according to HW FIFO) instead of I2C_SMBUS_BLOCK_MAX (defined in Linux)*/ -+ /* Current SMBUS HW FIFO length is 64B. For block write xfer, the first three FIFO entries are for slave adress, register ofset, and length count*/ -+ //for (i = 0; (i < *num_bytes_read) && (i < (I2C_SMBUS_BLOCK_MAX - adj)); i++) { -+ for (i = 0; (i < *num_bytes_read) && (i < (SMB_MAX_DATA_SIZE - adj)); i++) { -+ /* Read Rx FIFO for data bytes */ -+ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_MSTRDATARD_REG); -+ info->data[i + adj] = regval & CCB_SMB_MSTRRDDATA_MASK; -+ } -+ /* To make sure that atmost 32 bytes are read */ -+ *num_bytes_read = i + adj; -+ } -+ else { -+ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_MSTRDATARD_REG); -+ *info->data = regval & CCB_SMB_MSTRRDDATA_MASK; -+ *num_bytes_read = 1; -+ if (info->smb_proto == SMBUS_PROT_RD_WORD) { -+ /* Read Rx FIFO for data bytes */ -+ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_MSTRDATARD_REG); -+ info->data[1] = regval & CCB_SMB_MSTRRDDATA_MASK; -+ *num_bytes_read = 2; -+ } -+ } -+ -+ return(0); -+} -+ -+static int iproc_smb_xfer(struct i2c_adapter *i2c_adap, u16 addr, -+ unsigned short flags, char read_write, -+ u8 command, int size, union i2c_smbus_data *data) -+{ -+ int rc = 0; -+ struct iproc_smb_drv_int_data *dev = i2c_get_adapdata(i2c_adap); -+ struct iproc_xact_info info; -+ unsigned int num_bytes_read = 0; -+ int smb_xfer_size; -+ -+#ifdef IPROC_SMB_DBG -+ printk(KERN_DEBUG "\n%s: dev=0x%08X\n", __func__, (unsigned int)dev); -+#endif -+ -+ down(&dev->xfer_lock); -+ -+ addr <<= 1; -+ -+ switch (size /* protocol */) { -+ -+ case I2C_SMBUS_BYTE: -+ info.cmd_valid = false; -+ info.command = command; /* not used */ -+ if (read_write == I2C_SMBUS_WRITE) { -+ info.data = &command; -+ } -+ else { -+ info.data = &data->byte; -+ } -+ info.size = 1; -+ info.flags = flags; -+ if (read_write == I2C_SMBUS_READ) { -+ addr |= 0x1; /* Read operation */ -+ info.smb_proto = SMBUS_PROT_RECV_BYTE; -+ info.data = &data->byte; -+ } -+ else { -+ info.smb_proto = SMBUS_PROT_SEND_BYTE; -+ } -+ break; -+ -+ case I2C_SMBUS_BYTE_DATA: -+ info.cmd_valid = true; -+ info.command = command; -+ info.data = &data->byte; -+ info.size = 1; -+ info.flags = flags; -+ -+ if (read_write == I2C_SMBUS_READ) { -+ info.smb_proto = SMBUS_PROT_RD_BYTE; -+ } -+ else { -+ info.smb_proto = SMBUS_PROT_WR_BYTE; -+ //info.smb_proto = SMBUS_PROT_WR_WORD; /* TEMP chg. remove later */ -+ } -+ break; -+ -+ case I2C_SMBUS_WORD_DATA: -+ info.cmd_valid = true; -+ info.command = command; -+ info.data = (unsigned char *)(&data->word); -+ info.size = 2; -+ info.flags = flags; -+ if (read_write == I2C_SMBUS_READ) { -+ info.smb_proto = SMBUS_PROT_RD_WORD; -+ /* Protocol(hw) returns data byte count as part of response, -+ for smbus compliant devices */ -+ // info.size = 0; -+ } -+ else { -+ info.smb_proto = SMBUS_PROT_WR_WORD; -+ info.size = 2; -+ } -+ break; -+ -+ case I2C_SMBUS_BLOCK_DATA: -+ case I2C_SMBUS_I2C_BLOCK_DATA: -+ info.cmd_valid = true; -+ info.command = command; -+ info.data = &data->block[1]; -+ info.flags = flags; -+ -+ if (read_write == I2C_SMBUS_READ) { -+ info.smb_proto = SMBUS_PROT_BLK_RD; -+ /* See desc for RD_BYTE_COUNT in reg 0x30 about 'block read'. -+ * If '0', protocol(hw) returns data byte count as part of -+ * response. -+ */ -+#ifdef SMB_BLOCK_XFER_VARIANT -+ info.size = data->block[0]; -+#else -+ info.size = 0; -+#endif -+ } -+ else { -+ info.smb_proto = SMBUS_PROT_BLK_WR; -+ info.size = data->block[0]; /* i2c-core passes the length in this field */ -+ } -+ -+ break; -+ -+ case I2C_SMBUS_BLOCK_PROC_CALL: -+ info.cmd_valid = true; -+ info.command = command; -+ info.data = &data->block[1]; -+ info.flags = flags; -+ info.size = data->block[0]; -+ info.smb_proto = SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL; -+ break; -+ -+ default: -+ printk(KERN_ERR "%s: Unsupported transaction %d\n", __func__, size); -+ up(&dev->xfer_lock); -+ return -EINVAL; -+ -+ } -+ -+ /* Handle of large packet by spliting into SMB_MAX_DATA_SIZE packet */ -+ smb_xfer_size = (int)info.size; -+ if ((info.smb_proto == SMBUS_PROT_BLK_RD) || (info.smb_proto == SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL)) -+ data->block[0] = 0; -+ while ( smb_xfer_size ) { -+ if (info.size >= SMB_MAX_DATA_SIZE) -+ info.size = SMB_MAX_DATA_SIZE; -+ -+ if (read_write == I2C_SMBUS_READ) { -+ /* Refer to i2c_smbus_read_byte for params passed. */ -+ rc = iproc_smb_data_recv(i2c_adap, addr, &info, &num_bytes_read); -+ /* if failed due to bus hang, but recovered, retry once */ -+ if (rc == -ECOMM) { -+ rc = iproc_smb_data_recv(i2c_adap, addr, &info, &num_bytes_read); -+ } -+ /* For block read call, we pass the actual amount of data sent by -+ * slave, as expected by std Linux API */ -+ if ((info.smb_proto == SMBUS_PROT_BLK_RD) || -+ (info.smb_proto == SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL)) { -+ if (rc == 0) { -+ data->block[0] += num_bytes_read; -+#ifdef IPROC_SMB_DBG -+ printk(KERN_DEBUG "%s: num bytes read=%u\n", -+ __func__, data->block[0]); -+#endif -+ } -+ } -+ } -+ else { -+ /* Refer to i2c_smbus_write_byte params passed. */ -+ rc = iproc_smb_data_send(i2c_adap, addr, &info); -+ /* if failed due to bus hang, but recovered, retry */ -+ if (rc == -ECOMM) { -+ rc = iproc_smb_data_send(i2c_adap, addr, &info); -+ } -+ } -+ -+ if (rc < 0) { -+ printk(KERN_INFO "%s %s: %s error accessing device 0x%X rc=%d", __func__, dev->adapter.name, -+ (read_write == I2C_SMBUS_READ) ? "Read" : "Write", addr, rc); -+ up(&dev->xfer_lock); -+ return -EREMOTEIO; -+ } -+ if (info.size == SMB_MAX_DATA_SIZE) { -+ smb_xfer_size -= SMB_MAX_DATA_SIZE; -+ info.size = smb_xfer_size; -+ info.data += SMB_MAX_DATA_SIZE; -+ info.command += SMB_MAX_DATA_SIZE; /* Adjust I2c device register offset. Not required if the access register addr pointing to FIFO */ -+ } -+ else -+ break; -+ } -+ msleep(1); -+ up(&dev->xfer_lock); -+ -+ return (rc); -+} -+ -+static int -+proc_debug_read(struct file *file, char __user *buffer, size_t count, loff_t *off) -+{ -+ unsigned int len = 0; -+ struct iproc_smb_drv_int_data *dev = (struct iproc_smb_drv_int_data *) PDE_DATA (file->f_inode); -+ -+ if (off > 0) -+ return 0; -+ -+ len += sprintf(buffer + len, "Debug print is %s\n", -+ dev->debug ? "enabled" : "disabled"); -+ -+ return len; -+} -+ -+/* Command interface for reading/writing to various I2C/SMBus devices */ -+#ifndef SMB_BLK_XFER_TEST -+static int -+proc_debug_write(struct file *file, const char __user *buffer, -+ unsigned long count, void *data) -+{ -+ struct iproc_smb_drv_int_data *dev = (struct iproc_smb_drv_int_data *)data; -+ int rc; -+ unsigned char kbuf[MAX_PROC_BUF_SIZE]; -+ union i2c_smbus_data i2cdata; -+ unsigned int val, i2cdev_addr, rd_wr_op; -+ int addr; -+ -+ if (count > MAX_PROC_BUF_SIZE) { -+ count = MAX_PROC_BUF_SIZE; -+ } -+ -+ rc = copy_from_user(kbuf, buffer, count); -+ if (rc) { -+ printk(KERN_ERR "%s: copy_from_user failed status=%d\n", __func__, rc); -+ return -EFAULT; -+ } -+ -+ rc = sscanf(kbuf, "%u %u %d %u", &rd_wr_op, &i2cdev_addr, &addr, &val); -+ if (rc != 4) { -+ printk(KERN_ERR "\necho args > %s", PROC_ENTRY_DEBUG); -+ printk(KERN_ERR "\nargs (all values should be in decimal)):"); -+ printk(KERN_ERR "\nrd_wr_op: 1 = read, 0 = write"); -+ printk(KERN_ERR "\ni2cdev_addr: I2C device address in decimal"); -+ printk(KERN_ERR "\noffset: offset of location within I2C device"); -+ printk(KERN_ERR "\naddr -1 if offset not applicable"); -+ printk(KERN_ERR "\nval: For write op: 8-bit value.\n" -+ " For read op: not used, may be 0\n\n"); -+ return count; -+ } -+ -+ printk("\nArg values :"); -+ printk("\nrd_wr_op = %u", rd_wr_op); -+ printk("\ni2cdev_addr = 0x%X", i2cdev_addr); -+ printk("\noffset = %d", addr); -+ printk("\nval = %u", val); -+ if (rd_wr_op > 1) { -+ printk(KERN_ERR "Error: Invalid rd_wr_op value %u\n", rd_wr_op); -+ return count; -+ } -+ -+ if (i2cdev_addr > 127) { -+ printk(KERN_ERR "Error: i2cdev_addr must be 7-bit value\n"); -+ return count; -+ } -+ -+ if (addr > 255) { -+ printk(KERN_ERR "Error: offset out of range for this device\n"); -+ return count; -+ } -+ -+ printk("Command can execute slow, please wait...\n"); -+ -+ if (rd_wr_op == 0) { /* Write operation */ -+ i2cdata.byte = val; -+ if (addr == -1) { -+ /* Device does not support, or require an offset to write to the -+ * location -+ */ -+ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, -+ I2C_SMBUS_WRITE, (unsigned char)0, -+ I2C_SMBUS_BYTE, &i2cdata); -+ } else { -+ /* Address required for write access */ -+ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, -+ I2C_SMBUS_WRITE, addr, I2C_SMBUS_BYTE_DATA, -+ &i2cdata); -+ } -+ -+ if (rc) { -+ printk(KERN_ERR "%s: iproc_smb_xfer:write failed status=%d," -+ " addr=%u, val = 0x%X\n", __func__, rc, addr, val); -+ /* return -EFAULT; */ -+ } else { -+ printk("Write OK.Wrote 0x%X at addr %u\n", val, addr); -+ } -+ -+ msleep(1); /* Delay required, since smb(i2c) interface is slow */ -+ } -+ -+ if (rd_wr_op == 1) { /* Read operation */ -+ if (addr == -1) { -+ /* Device does not support, or require an offset to read from the -+ * location -+ */ -+ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, I2C_SMBUS_READ, -+ (unsigned char)0, I2C_SMBUS_BYTE, &i2cdata); -+ } else { -+ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, I2C_SMBUS_READ, -+ addr, I2C_SMBUS_BYTE_DATA, &i2cdata); -+ } -+ -+ if (rc) { -+ printk(KERN_ERR "%s: iproc_smb_xfer failed status=%d\n", __func__, rc); -+ /* return -EFAULT; */ -+ } else { -+ printk("Read OK.Value read at %u = 0x%X\n", addr, i2cdata.byte); -+ } -+ msleep(1); /* Delay required, since smb(i2c) interface is slow */ -+ } -+ -+#ifdef IPROC_SMB_DBG -+ iproc_dump_smb_regs(dev); -+#endif /* IPROC_SMB_DBG */ -+ -+ printk("Last intr sts = 0x%08X\n", dev->smb_counters.last_int_sts); -+ printk("mstr_start_busy_cnt = %u, mstr_rx_evt_cnt = %u, rx fifo full cnt = %u\n\n", -+ dev->smb_counters.mstr_start_busy_cnt, -+ dev->smb_counters.mstr_rx_evt_cnt, -+ dev->smb_counters.mstr_rx_fifo_full_cnt); -+ -+ return count; -+} -+#endif -+ -+#ifdef SMB_BLK_XFER_TEST -+static int -+proc_debug_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) -+{ -+ struct iproc_smb_drv_int_data *dev = (struct iproc_smb_drv_int_data *) PDE_DATA (file->f_inode); -+ int rc; -+ unsigned char kbuf[MAX_PROC_BUF_SIZE]; -+ union i2c_smbus_data i2cdata; -+ unsigned int val, i2cdev_addr, rd_wr_op; -+ int addr; -+ int i, j; -+ unsigned int burst_len, repated_cnt, total_cnt; -+ -+ if (count > MAX_PROC_BUF_SIZE) { -+ count = MAX_PROC_BUF_SIZE; -+ } -+ -+ rc = copy_from_user(kbuf, buffer, count); -+ -+ if (rc) { -+ printk (KERN_ERR "%s: copy_from_user failed status=%d", __func__, rc); -+ return -EFAULT; -+ -+ } -+ -+ rc = sscanf(kbuf, "%u %u %d %u %u %u", &rd_wr_op, &i2cdev_addr, &addr, &val, &burst_len, &repated_cnt); -+ if (rc != 6) { -+ burst_len = 1; -+ repated_cnt = 1; -+ -+ if (rc < 4 ) { -+ printk(KERN_ERR "\necho args > %s", PROC_ENTRY_DEBUG); -+ printk(KERN_ERR "\nargs (all values should be in decimal)):"); -+ printk(KERN_ERR "\nrd_wr_op: 1 = read, 0 = write"); -+ printk(KERN_ERR "\ni2cdev_addr: I2C device address in decimal"); -+ printk(KERN_ERR "\noffset: offset of location within I2C device"); -+ printk(KERN_ERR "\naddr -1 if offset not applicable"); -+ printk(KERN_ERR "\nval: For write op: 8-bit value.\n" -+ " For read op: not used, may be 0\n\n"); -+ printk(KERN_ERR "\burst_length: write block transfer byte length (<=8 for many EEPROM devices)"); -+ printk(KERN_ERR "\repated_cnt: number of repated write transfer of burst_len"); -+ return -EFAULT; -+ } -+ } -+ total_cnt = burst_len * repated_cnt; -+ -+ printk(KERN_DEBUG "\nArg values :"); -+ printk(KERN_DEBUG "\nrd_wr_op = %u", rd_wr_op); -+ printk(KERN_DEBUG "\ni2cdev_addr = 0x%X", i2cdev_addr); -+ printk(KERN_DEBUG "\noffset = %d", addr); -+ printk(KERN_DEBUG "\nval = %u", val); -+ -+ if (rd_wr_op > 1) { -+ printk(KERN_ERR "\nError: Invalid rd_wr_op value %u\n", rd_wr_op); -+ return count; -+ } -+ -+ if (i2cdev_addr > 127) { -+ printk(KERN_ERR "\nError: i2cdev_addr must be 7-bit value\n"); -+ return count; -+ } -+ -+ if (addr > 255) { -+ printk(KERN_ERR "\nError: offset out of range for this device\n"); -+ return count; -+ } -+ -+ printk (KERN_ERR "\nCommand can execute slow, please wait...\n"); -+ -+ if (rd_wr_op == 0) { /* Write operation */ -+ if (total_cnt == 1) { -+#if defined(CONFIG_MACH_SB2) -+ /* Testing EEPROM that requires 2-byte address */ -+ unsigned char *data = &i2cdata.word; -+ data[0] = addr; -+ data[1] = val; -+ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, -+ I2C_SMBUS_WRITE, (unsigned char)0, I2C_SMBUS_WORD_DATA, &i2cdata); -+#else -+ i2cdata.byte = val; -+ if (addr == -1) { -+ /* Device does not support, or require an offset to write to the -+ * location -+ */ -+ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, -+ I2C_SMBUS_WRITE, (unsigned char)0, -+ I2C_SMBUS_BYTE, &i2cdata); -+ } -+ else { -+ /* Address required for write access */ -+ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, -+ I2C_SMBUS_WRITE, addr, I2C_SMBUS_BYTE_DATA, &i2cdata); -+ } -+#endif -+ if (rc) { -+ printk (KERN_ERR "\n%s: iproc_smb_xfer:write failed status=%d," -+ " addr=%u, val = 0x%X\n", __func__, rc, addr, val); -+ /* return -EFAULT; */ -+ } -+ else { -+ printk(KERN_ERR "Write OK. Wrote 0x%X at addr %u\n", val, addr); -+ } -+ msleep(1); /* Delay required, since smb(i2c) interface is slow */ -+ } -+ else { -+/* test of block xfer: echo "0 80 0 0 8 16" > /proc/iproc-i2c/iproc-i2c0/iproc-i2c-dbg */ -+/* write to EEPROM I2c device (slave addr 80=0x50), addr offset: 0, vlaue: starting from 0, block xfer size:8, repeat_cnt:16 (EEPROM doesn't accept block xfer length > 8) */ -+/* repeat_cnt times of write block transfer */ -+/* for single address cycle I2C device only */ -+ for(j=0;jadapter, i2cdev_addr, 0x0, I2C_SMBUS_WRITE, -+ addr+j*burst_len, I2C_SMBUS_BLOCK_DATA, &i2cdata); -+ if (rc) { -+ printk (KERN_ERR "\n%s: iproc_smb_xfer:write failed status=%d," -+ " addr=%u, val = 0x%X\n", __func__, rc, addr, val); -+ return -EFAULT; -+ } -+ msleep(1); -+ } -+ } /* ! total_cnt == 1 */ -+ } -+ -+ if (rd_wr_op == 1) { /* Read operation */ -+ if (total_cnt == 1) { -+#if defined(CONFIG_MACH_SB2) -+ /* Testing EEPROM that requires 2-byte address: to support random read, -+ * issue dummy write and then current address read -+ */ -+ i2cdata.byte = addr; -+ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, -+ I2C_SMBUS_WRITE, 0, I2C_SMBUS_BYTE_DATA, &i2cdata); -+ if (rc) { -+ printk (KERN_ERR "\n%s: iproc_smb_xfer dummy write failed status=%d\n", __func__, rc); -+ } -+ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, I2C_SMBUS_READ, -+ (unsigned char)0, I2C_SMBUS_BYTE, &i2cdata); -+#else -+ if (addr == -1) { -+ /* Device does not support, or require an offset to read from the -+ * location -+ */ -+ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, I2C_SMBUS_READ, -+ (unsigned char)0, I2C_SMBUS_BYTE, &i2cdata); -+ } -+ else { -+ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, I2C_SMBUS_READ, -+ addr, I2C_SMBUS_BYTE_DATA, &i2cdata); -+ } -+#endif -+ if (rc) { -+ printk (KERN_ERR "\n%s: iproc_smb_xfer failed status=%d\n", __func__, rc); -+ -+ /* return -EFAULT; */ -+ } -+ else { -+ printk(KERN_ERR "\nRead OK.\n--------Value read at %u = 0x%X\n", addr, i2cdata.byte); -+ } -+ -+ msleep(1); /* Delay required, since smb(i2c) interface is slow */ -+ } -+ else { -+ for (i = 1; i <= total_cnt; i++) -+ i2cdata.block[i] = 0; -+ i2cdata.block[0] = total_cnt; -+ rc = iproc_smb_xfer(&dev->adapter, i2cdev_addr, 0x0, I2C_SMBUS_READ, -+ addr, I2C_SMBUS_BLOCK_DATA, &i2cdata); -+ if (rc) { -+ printk (KERN_ERR "\n%s: iproc_smb_xfer:read failed status=%d," -+ " addr=%u, val = 0x%X\n", __func__, rc, addr, val); -+ return -EFAULT; -+ } -+ msleep(1); -+ for (i = 1; i <= total_cnt; i++) -+ printk("%d ", i2cdata.block[i]); -+ } /* ! total_cnt == 1 */ -+ } -+ -+#ifdef IPROC_SMB_DBG -+ iproc_dump_smb_regs(dev); -+#endif -+ -+ printk(KERN_DEBUG "Last intr sts = 0x%08X\n", dev->smb_counters.last_int_sts); -+ -+ printk(KERN_DEBUG "mstr_start_busy_cnt = %u, mstr_rx_evt_cnt = %u, rx fifo full cnt = %u\n", -+ dev->smb_counters.mstr_start_busy_cnt, -+ dev->smb_counters.mstr_rx_evt_cnt, -+ dev->smb_counters.mstr_rx_fifo_full_cnt); -+ -+ return count; -+} -+#endif -+ -+ -+#ifdef CONFIG_USE_SVK_VERSION -+/* Written for SVK boards */ -+static int -+proc_debug_write_svk(struct file *file, const char __user *buffer, size_t count, loff_t *off) -+{ -+ struct iproc_smb_drv_int_data *dev = (struct iproc_smb_drv_int_data *) PDE_DATA (file->f_inode); -+ int rc; -+ unsigned int debug; -+ unsigned char kbuf[MAX_PROC_BUF_SIZE]; -+ union i2c_smbus_data i2cdata; -+ unsigned int val, addr; -+ -+ if (count > MAX_PROC_BUF_SIZE) { -+ count = MAX_PROC_BUF_SIZE; -+ } -+ -+ rc = copy_from_user(kbuf, buffer, count); -+ if (rc) { -+ printk(KERN_ERR "%s: copy_from_user failed status=%d\n", __func__, rc); -+ return -EFAULT; -+ } -+ -+ if (sscanf(kbuf, "%u", &debug) != 1) { -+ printk(KERN_ERR "%s: echo > %s\n", __func__, PROC_ENTRY_DEBUG); -+ return count; -+ } -+ -+ if (debug) { -+ dev->debug = 1; -+ } else { -+ dev->debug = 0; -+ } -+ -+ printk ("Command can execute slow, please wait...\n"); -+ if (!dev->debug) { -+ val = 0xFF; /* Initial value to write */ -+ for(addr = 0x0; addr < 256; val--, addr++) { -+ i2cdata.byte = val; -+ rc = iproc_smb_xfer(&dev->adapter, 0xA0 >> 1, 0x0, I2C_SMBUS_WRITE, -+ addr, I2C_SMBUS_BYTE_DATA, &i2cdata); -+ if (rc) { -+ printk(KERN_ERR "%s: iproc_smb_xfer:write failed status=%d," -+ " addr=%u, val = 0x%X", __func__, rc, addr, val); -+ } else { -+ printk("Write OK. Wrote 0x%X at addr %u\n", val, addr); -+ } -+ msleep(1); /* Delay required, since smb(i2c) interface is slow */ -+ } -+ } else { -+ int i; -+ -+ /* Note about address expected by AT24C02: To write in correct order -+ * to AT24C02 using block write, refer bottom of page 9 (Write -+ * Operations) of the data sheet regarding internal incrementing of -+ * address. Based on that explanation, we program the addr value below. -+ * Select the 'highest' address in that page (7, 15, 23, and so on) to -+ * write to that page -+ */ -+ addr = debug - 1; -+ val = jiffies % 256; -+ printk("EEPROM page write. Page start addr = %u," -+ " write data: \n", debug - 8); -+ -+ for (i = 1; i <= 8; i++) { -+ i2cdata.block[i] = val % 256; /* Fill a sequence pattern */ -+ val++; -+ printk("byte%d = 0x%02X\n", i, i2cdata.block[i]); -+ } -+ -+ i2cdata.block[0] = 8; -+ rc = iproc_smb_xfer(&dev->adapter, 0xA0 >> 1, 0x0, I2C_SMBUS_WRITE, -+ addr, I2C_SMBUS_BLOCK_DATA, &i2cdata); -+ if (rc) { -+ printk(KERN_ERR "%s: iproc_smb_xfer:write failed status=%d," -+ " addr=%u, val = 0x%X\n", __func__, rc, addr, val); -+ } else { -+ printk("Block Write OK.\n"); -+ } -+ } -+ -+#ifdef IPROC_SMB_DBG -+ iproc_dump_smb_regs(dev); -+#endif /* IPROC_SMB_DBG */ -+ -+ printk("Last intr sts = 0x%08X\n", -+ dev->smb_counters.last_int_sts); -+ printk("mstr_start_busy_cnt = %u, mstr_rx_evt_cnt = %u, rx fifo full cnt = %u\n\n", -+ dev->smb_counters.mstr_start_busy_cnt, -+ dev->smb_counters.mstr_rx_evt_cnt, -+ dev->smb_counters.mstr_rx_fifo_full_cnt); -+ -+ return count; -+} -+ -+ -+/* Written for SVK boards */ -+static int -+proc_debug_read_svk(struct file *file, char __user *buffer, size_t count, loff_t *off) -+{ -+ unsigned int len = 0; -+ struct iproc_smb_drv_int_data *dev = (struct iproc_smb_drv_int_data *) PDE_DATA (file->f_inode); -+ int rc; -+ union i2c_smbus_data i2cdata; -+ unsigned int addr; -+ -+ if (off > 0) { -+ return 0; -+ } -+ -+ len += sprintf(buffer + len, "Read\n"); -+ -+ printk(KERN_ERR "\nCommand can execute slow, please wait...\n"); -+ -+ for(addr = 0x0; addr < 256; addr++) { -+ -+ /* Read operation */ -+ rc = iproc_smb_xfer(&dev->adapter, 0xA0 >> 1, 0x0, I2C_SMBUS_READ, addr, -+ I2C_SMBUS_BYTE_DATA, &i2cdata); -+ -+ if (rc) { -+ printk (KERN_ERR "%s: iproc_smb_xfer failed status=%d", __func__, rc); -+ } -+ else { -+ printk(KERN_DEBUG "Read OK.Value read at %u = 0x%X\n", addr, i2cdata.byte); -+ } -+ -+ msleep(1); -+ } -+ -+#ifdef IPROC_SMB_DBG -+ iproc_dump_smb_regs(dev); -+#endif /* IPROC_SMB_DBG */ -+ -+ printk(KERN_DEBUG "\n\nLast intr sts = 0x%08X", dev->smb_counters.last_int_sts); -+ -+ printk(KERN_DEBUG "mstr_start_busy_cnt = %u, mstr_rx_evt_cnt = %u, rx fifo full cnt = %u\n\n", -+ dev->smb_counters.mstr_start_busy_cnt, -+ dev->smb_counters.mstr_rx_evt_cnt, -+ dev->smb_counters.mstr_rx_fifo_full_cnt); -+ -+ return len; -+} -+#endif /* #ifdef CONFIG_USE_SVK_VERSION */ -+ -+static const struct file_operations proc_smb_file_fops= { -+#ifdef CONFIG_USE_SVK_VERSION -+ .read = proc_debug_read_svk, -+ .write = proc_debug_write_svk, -+#else -+ .read = proc_debug_read, -+ .write = proc_debug_write, -+#endif -+ -+}; -+ -+ -+ -+static int proc_init(struct platform_device *pdev) -+{ -+ int rc; -+ struct iproc_smb_drv_int_data *dev = platform_get_drvdata(pdev); -+ struct procfs *proc = &dev->proc; -+ struct proc_dir_entry *proc_debug; -+ -+ -+ snprintf(proc->name, sizeof(proc->name), "%s%d", PROC_GLOBAL_PARENT_DIR, pdev->id); -+ -+ /* sub directory */ -+ proc->parent = proc_mkdir(proc->name, gProcParent); -+ -+ if (proc->parent == NULL) { -+ return -ENOMEM; -+ } -+ -+ proc_debug = proc_create_data(PROC_ENTRY_DEBUG, 0644, proc->parent, &proc_smb_file_fops, dev); -+ -+ if (proc_debug == NULL) { -+ rc = -ENOMEM; -+ goto err_del_parent; -+ } -+ -+ return 0; -+ -+err_del_parent: -+ remove_proc_entry(proc->name, gProcParent); -+ -+ return rc; -+} -+ -+static int proc_term(struct platform_device *pdev) -+{ -+ struct iproc_smb_drv_int_data *dev = platform_get_drvdata(pdev); -+ struct procfs *proc = &dev->proc; -+ -+ remove_proc_entry(PROC_ENTRY_DEBUG, proc->parent); -+ remove_proc_entry(proc->name, gProcParent); -+ -+ return 0; -+} -+ -+/* -+ * This function set clock frequency for SMBus block. As per hardware -+ * engineering, the clock frequency can be changed dynamically. -+ */ -+static int iproc_smb_set_clk_freq(unsigned long base_addr, -+ smb_clk_freq_t freq) -+{ -+ unsigned int regval; -+ unsigned int val; -+ -+ switch (freq) { -+ -+ case I2C_SPEED_100KHz: -+ val = 0; -+ break; -+ -+ case I2C_SPEED_400KHz: -+ val = 1; -+ break; -+ -+ default: -+ return -EINVAL; -+ break; -+ -+ } -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_TIMGCFG_REG); -+ -+ SETREGFLDVAL(regval, val, CCB_SMB_TIMGCFG_MODE400_MASK, -+ CCB_SMB_TIMGCFG_MODE400_SHIFT); -+ -+ iproc_smb_reg_write(base_addr + CCB_SMB_TIMGCFG_REG, regval); -+ -+ return(0); -+} -+ -+static int iproc_smbus_block_init(struct iproc_smb_drv_int_data *dev) -+{ -+ -+ unsigned long base_addr = (unsigned long)dev->block_base_addr; -+ unsigned int regval; -+#ifdef CONFIG_OF -+ u32 i2c_clk_freq; -+ struct device_node *dn = dev->dev->of_node; -+#endif -+ -+ /* Flush Tx, Rx FIFOs. Note we are setting the Rx FIFO threshold to 0. -+ * May be OK since we are setting RX_EVENT and RX_FIFO_FULL interrupts -+ */ -+ regval = CCB_SMB_MSTRRXFIFOFLSH_MASK | CCB_SMB_MSTRTXFIFOFLSH_MASK; -+ -+ iproc_smb_reg_write(base_addr + CCB_SMB_MSTRFIFOCTL_REG, regval); -+ -+ /* Enable SMbus block. Note, we are setting MASTER_RETRY_COUNT to zero -+ * since there will be only one master -+ */ -+ regval = CCB_SMB_CFG_SMBEN_MASK; -+ -+ iproc_smb_reg_write(base_addr + CCB_SMB_CFG_REG, regval); -+ -+ /* Wait a minimum of 50 Usec, as per SMB hw doc. But we wait longer */ -+ udelay(100); -+ -+ -+ /* Set default clock frequency */ -+#ifndef CONFIG_OF -+ iproc_smb_set_clk_freq(base_addr, I2C_SPEED_100KHz); -+#else -+ if (of_property_read_u32(dn, "clock-frequency", &i2c_clk_freq)) { -+ i2c_clk_freq = I2C_SPEED_100KHz; /*no property available, use default: 100KHz*/ -+ } -+ iproc_smb_set_clk_freq(base_addr, i2c_clk_freq); -+#endif /* CONFIG_OF */ -+ /* Disable intrs */ -+ regval = 0x0; -+ iproc_smb_reg_write(base_addr + CCB_SMB_EVTEN_REG, regval); -+ -+ /* Clear intrs (W1TC) */ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_EVTSTS_REG); -+ -+ iproc_smb_reg_write(base_addr + CCB_SMB_EVTSTS_REG, regval); -+ -+ return(0); -+} -+ -+/* This function enables interrupts */ -+static int iproc_intr_enable(struct iproc_smb_drv_int_data *dev, unsigned int bmap) -+{ -+ unsigned long base_addr = (unsigned long)dev->block_base_addr; -+ unsigned int regval; -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_EVTEN_REG); -+ -+ regval |= bmap; -+ -+ iproc_smb_reg_write(base_addr + CCB_SMB_EVTEN_REG, regval); -+ -+ /* Store all interrupts enabled so far. Note bmap can have only 'incremental' -+ * set of events -+ */ -+ dev->evt_enable_bmap = regval; -+ -+ return(0); -+} -+ -+/* This function disables interrupts */ -+static int iproc_intr_disable(struct iproc_smb_drv_int_data *dev, unsigned int bmap) -+{ -+ unsigned long base_addr = (unsigned long)dev->block_base_addr; -+ unsigned int regval; -+ -+ regval = iproc_smb_reg_read(base_addr + CCB_SMB_EVTEN_REG); -+ -+ regval &= ~bmap; -+ -+ iproc_smb_reg_write(base_addr + CCB_SMB_EVTEN_REG, regval); -+ -+ dev->evt_enable_bmap = regval; -+ -+ return(0); -+} -+ -+/* Verify this sequence with hw engg */ -+static int iproc_smbus_block_deinit(struct iproc_smb_drv_int_data *dev) -+{ -+ unsigned int regval; -+ int rc; -+ -+ /* Disable all interrupts */ -+ regval = 0x0; -+ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_EVTEN_REG, regval); -+ -+ /* Check if a transaction is in progress */ -+ rc = iproc_smb_startbusy_wait(dev); -+ -+ if (rc < 0) { -+ -+ /* Do not exit the function, since we are most likely shutting down */ -+ printk(KERN_ERR "%s: A transaction is still in progress," -+ "but still continuing ", __func__); -+ -+ } -+ -+ /* Disable SMBus block */ -+ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG); -+ -+ regval &= ~CCB_SMB_CFG_SMBEN_MASK; -+ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG, regval); -+ -+ -+ /* Wait for some time */ -+ udelay(100); -+ -+ /* Put the block under reset. Note the RESET bit in reg 0x0 is -+ * self clearing -+ */ -+ regval = CCB_SMB_CFG_RST_MASK; -+ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG, regval); -+ -+ return(0); -+} -+ -+static u32 iproc_smb_funcs(struct i2c_adapter *adapter) -+{ -+ /* I2C_FUNC_SMBUS_I2C_BLOCK */ -+ return (I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | -+ I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA); -+} -+ -+static struct i2c_algorithm iproc_smb_algorithm = { -+ /* .name = "iproc-smb", */ -+ .smbus_xfer = iproc_smb_xfer, -+ .master_xfer = NULL, -+ .functionality = iproc_smb_funcs, -+}; -+ -+ -+static int iproc_smb_probe(struct platform_device *pdev) -+{ -+ int rc=0, irq; -+ struct iproc_smb_drv_int_data *dev; -+ struct i2c_adapter *adap; -+ struct resource *iomem; -+ struct resource *ioarea; -+#ifdef CONFIG_OF -+ struct device_node *dn = pdev->dev.of_node; -+ u32 smb_bus_id; -+#endif -+ -+#ifdef IPROC_SMB_DBG -+ printk(KERN_DEBUG "\n%s: Entering probe\n", __func__); -+#endif /* IPROC_SMB_DBG */ -+ -+#ifdef CONFIG_OF -+ /* first I2C init */ -+ if (gProcParent == NULL) { -+ gProcParent = proc_mkdir(PROC_GLOBAL_PARENT_DIR, NULL); -+ if (gProcParent == NULL) { -+ printk(KERN_ERR "%s: SMBus driver procfs failed\n", __func__); -+ return -ENOMEM; -+ } -+ iproc_smbus_list = NULL; -+ } -+#endif /* CONFIG_OF */ -+ -+ /* Get register memory resource */ -+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ -+ if (!iomem) { -+ printk(KERN_ERR "%s: No mem resource\n", __func__); -+ return -ENODEV; -+ } -+ -+#ifdef IPROC_SMB_DBG -+ printk(KERN_DEBUG "\nGot iomem 0x%p\n", iomem); -+#endif /* IPROC_SMB_DBG */ -+ -+ /* Get the interrupt number */ -+ irq = platform_get_irq(pdev, 0); -+ -+ if (irq == -ENXIO) { -+ printk(KERN_ERR "%s: No irq resource\n", __func__); -+ return -ENODEV; -+ } -+ -+#ifdef IPROC_SMB_DBG -+ printk(KERN_DEBUG "\nGot irqnum %d\n", irq); -+#endif /* IPROC_SMB_DBG */ -+ -+ /* Mark the memory region as used */ -+ ioarea = request_mem_region(iomem->start, resource_size(iomem), -+ pdev->name); -+ if (!ioarea) { -+ printk(KERN_ERR "%s: SMBus region already claimed\n", __func__); -+ return -EBUSY; -+ } -+ -+#ifdef IPROC_SMB_DBG -+ printk(KERN_DEBUG "\nGot ioarea 0x%p\n", ioarea); -+#endif /* IPROC_SMB_DBG */ -+ -+ /* Allocate memory for driver's internal data structure */ -+ dev = kzalloc(sizeof(*dev), GFP_KERNEL); -+ -+ if (!dev) { -+ printk(KERN_ERR "%s: Couldn't allocate memory for driver's internaldb\n", __func__); -+ rc = -ENOMEM; -+ goto err_release_mem_region; -+ } -+ -+#ifdef IPROC_SMB_DBG -+ printk(KERN_DEBUG "\nGot dev 0x%p\n", dev); -+#endif /* IPROC_SMB_DBG */ -+ -+ dev->dev = &pdev->dev; -+ init_MUTEX(&dev->xfer_lock); -+ init_completion(&dev->ses_done); -+ dev->irq = irq; -+ -+ dev->block_base_addr = ioremap(iomem->start, resource_size(iomem)); -+ -+ if (!dev->block_base_addr) { -+ printk(KERN_ERR "%s: ioremap of register space failed\n", __func__); -+ rc = -ENOMEM; -+ goto err_free_dev_mem; -+ } -+ -+#ifdef IPROC_SMB_DBG -+ printk(KERN_DEBUG "\n ==== Got block_base_addr=0x%08X\n", (unsigned int)dev->block_base_addr); -+ /* iproc_dump_smb_regs(dev); */ -+#endif /* IPROC_SMB_DBG */ -+ -+ dev->enable_evts = ENABLE_INTR; /* Default value, can be changed after -+ initial testing */ -+ -+ platform_set_drvdata(pdev, dev); -+ -+ /* Init internal regs, disable intrs (and then clear intrs), set fifo -+ * thresholds, etc. -+ */ -+ iproc_smbus_block_init(dev); -+ -+ /* Register ISR handler */ -+ rc = request_irq(dev->irq, iproc_smb_isr, IRQF_SHARED, pdev->name, dev); -+ -+ if (rc) { -+ printk(KERN_ERR "%s: failed to request irq %d, rc=%d\n", __func__, dev->irq, rc); -+ goto err_smb_deinit; -+ } -+ -+#ifdef IPROC_SMB_DBG -+ printk(KERN_DEBUG "\nrequest_irq succeeded\n"); -+#endif /* IPROC_SMB_DBG */ -+ -+ adap = &dev->adapter; -+ i2c_set_adapdata(adap, dev); /* Verify if this place is OK */ -+ adap->owner = THIS_MODULE; -+ adap->class = UINT_MAX; /* Can be used by any I2C device */ -+ adap->algo = &iproc_smb_algorithm; -+ adap->dev.parent = &pdev->dev; /* */ -+#ifndef CONFIG_OF -+ adap->nr = pdev->id; -+#else -+ if (of_property_read_u32(dn, "#bus-id", &smb_bus_id)) { -+ dev_warn(&pdev->dev, "missing #bus-id property (default to 0)\n"); -+ smb_bus_id = 0; -+ } -+ adap->nr = smb_bus_id; -+ pdev->id = smb_bus_id; -+ adap->dev.of_node = pdev->dev.of_node; /* needed for adding I2C child devices */ -+#endif /* CONFIG_OF */ -+ snprintf(adap->name, sizeof(adap->name), "iproc-smb%d", pdev->id); -+ -+ /* -+ * I2C device drivers may be active on return from -+ * i2c_add_numbered_adapter() -+ */ -+ rc = i2c_add_numbered_adapter(adap); -+ -+ if (rc) { -+ printk(KERN_ERR "%s: Failed to add I2C adapter, rc=%d\n", __func__, rc); -+ goto err_free_irq; -+ } -+ -+#ifdef IPROC_SMB_DBG -+ printk(KERN_DEBUG "\ni2c_add_numbered_adapter succeeded\n"); -+#endif /* IPROC_SMB_DBG */ -+ -+ /* Turn on default set of interrupts */ -+ /* For Rx, enable RX fifo full, threshold hit interrupts. Other rx -+ * interrupts will be set in the read/recv transactions, as required -+ * For Tx, enable fifo under run intr. Other intrs will be set in send -+ * write access functions -+ */ -+ iproc_intr_enable(dev, CCB_SMB_MSTRRXFIFOFULLEN_MASK); -+ -+#ifdef IPROC_SMB_DBG -+ printk(KERN_DEBUG "\niproc_intr_enable complete, intrs enabled\n"); -+#endif /* IPROC_SMB_DBG */ -+ -+ rc = proc_init(pdev); -+ -+ if (rc) { -+ printk(KERN_ERR "%s: Failed to install procfs entry, rc=%d\n", __func__, rc); -+ goto err_proc_term; -+ } -+ -+ dev->next = iproc_smbus_list; -+ iproc_smbus_list = dev; -+ -+#ifdef IPROC_SMB_DBG -+ iproc_dump_smb_regs(dev); -+ printk(KERN_DEBUG "%s: probe successful", __func__); -+#endif /* IPROC_SMB_DBG */ -+ -+ return 0; -+ -+err_proc_term: -+ proc_term(pdev); -+ -+err_free_irq: -+ free_irq(dev->irq, dev); -+ -+err_smb_deinit: -+ iproc_smbus_block_deinit(dev); -+ -+ iounmap(dev->block_base_addr); -+ -+ platform_set_drvdata(pdev, NULL); -+ -+err_free_dev_mem: -+ kfree(dev); -+ -+err_release_mem_region: -+ release_mem_region(iomem->start, resource_size(iomem)); -+ -+ printk(KERN_ERR "%s: probe failed, error=%d", __func__, rc); -+ -+ return (rc); -+} -+ -+static int iproc_smb_remove(struct platform_device *pdev) -+{ -+ struct iproc_smb_drv_int_data *dev = platform_get_drvdata(pdev); -+ struct resource *iomem; -+ unsigned int regval; -+ -+ /* Disable interrupts. */ -+ /* Verify: Should we wait for any in-progress xact to complete? */ -+ iproc_intr_disable(dev, ~0); -+ -+ /* Disable SMbus block */ -+ regval = iproc_smb_reg_read((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG); -+ -+ regval &= ~CCB_SMB_CFG_SMBEN_MASK; -+ -+ iproc_smb_reg_write((unsigned long)dev->block_base_addr + CCB_SMB_CFG_REG, regval); -+ -+ i2c_del_adapter(&dev->adapter); -+ -+ platform_set_drvdata(pdev, NULL); -+ -+ free_irq(dev->irq, dev); -+ -+ iproc_smbus_block_deinit(dev); -+ -+ iounmap(dev->block_base_addr); -+ -+ kfree(dev); -+ -+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ -+ release_mem_region(iomem->start, resource_size(iomem)); -+ -+ return 0; -+} -+ -+#ifndef CONFIG_OF -+static int iproc_smb_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+/* struct iproc_smb_drv_int_data *dev = platform_get_drvdata(pdev); */ -+ -+ /* Add additional processing, if required */ -+ -+ return (0); -+} -+ -+static int iproc_smb_resume(struct platform_device *pdev) -+{ -+/* struct iproc_smb_drv_int_data *dev = platform_get_drvdata(pdev); */ -+ -+ /* Add additional processing, if required */ -+ -+ return (0); -+} -+ -+static struct platform_driver iproc_smb_driver = { -+ .driver = { -+ .name = "iproc-smb", -+ .owner = THIS_MODULE, -+ }, -+ .probe = iproc_smb_probe, -+ .remove = iproc_smb_remove, -+ .suspend = iproc_smb_suspend, -+ .resume = iproc_smb_resume, -+}; -+ -+static int __init iproc_smb_init(void) -+{ -+ int rc; -+ -+#ifdef IPROC_SMB_DBG -+ printk(KERN_DEBUG "%s: Entering init", __func__); -+#endif /* IPROC_SMB_DBG */ -+ -+ gProcParent = proc_mkdir(PROC_GLOBAL_PARENT_DIR, NULL); -+ -+ if (gProcParent == NULL) { -+ -+ printk(KERN_ERR "%s: SMBus driver procfs failed\n", __func__); -+ -+ return -ENOMEM; -+ -+ } -+ -+#ifdef IPROC_SMB_DBG -+ printk(KERN_DEBUG "\nproc_mkdir succeeded, gProcParent=0x%08X\n", (unsigned int)gProcParent); -+#endif /* IPROC_SMB_DBG */ -+ -+ rc = platform_driver_register(&iproc_smb_driver); -+ -+ if (rc < 0) { -+ -+ printk(KERN_ERR "%s: SMBus driver init failed, error %d\n", __func__, rc); -+ -+ } -+ -+#ifdef IPROC_SMB_DBG -+ printk(KERN_DEBUG "\n%s: Called platform_driver_register, rc=%d\n", __func__, rc); -+#endif /* IPROC_SMB_DBG */ -+ -+ -+ iproc_smbus_list = NULL; -+ -+ /* Should we set RESET bit (reg 0x0) here?: Not necessary as per hw engg */ -+ -+ return rc; -+} -+ -+static void __exit iproc_smb_exit(void) -+{ -+ platform_driver_unregister(&iproc_smb_driver); -+ -+ remove_proc_entry(PROC_GLOBAL_PARENT_DIR, NULL); -+} -+ -+module_init(iproc_smb_init); -+module_exit(iproc_smb_exit); -+ -+#else /* CONFIG_OF */ -+ -+static const struct of_device_id bcm_iproc_i2c_of_match[] = { -+ { .compatible = "brcm,iproc-i2c" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, bcm_iproc_i2c_of_match); -+ -+static struct platform_driver bcm_iproc_i2c_driver = { -+ .driver = { -+ .name = "bcm-iproc-i2c", -+ .of_match_table = bcm_iproc_i2c_of_match, -+ }, -+ .probe = iproc_smb_probe, -+ .remove = iproc_smb_remove, -+}; -+module_platform_driver(bcm_iproc_i2c_driver); -+#endif /* !CONFIG_OF */ -+ -+MODULE_AUTHOR("Broadcom Corporation"); -+MODULE_DESCRIPTION("IPROC I2C (SMBus) Bus Driver"); -+MODULE_LICENSE("GPL"); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig ---- a/drivers/mmc/host/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/mmc/host/Kconfig 2017-11-09 17:53:42.449278000 +0800 -@@ -786,3 +786,12 @@ config MMC_MTK - If you have a machine with a integrated SD/MMC card reader, say Y or M here. - This is needed if support for any SD/SDIO/MMC devices is required. - If unsure, say N. -+ -+config MMC_SDHCI_XGS_IPROC -+ tristate "Broadcom XGS iProc SD/MMC Card Interface support" -+ select MMC_SDHCI_IO_ACCESSORS -+ default n -+ help -+ This selects the platform Secure Digital Host Controller Interface. -+ If unsure, say N. -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile ---- a/drivers/mmc/host/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/mmc/host/Makefile 2017-11-09 17:53:42.457283000 +0800 -@@ -75,6 +75,7 @@ obj-$(CONFIG_MMC_SDHCI_BCM2835) += sdhc - obj-$(CONFIG_MMC_SDHCI_IPROC) += sdhci-iproc.o - obj-$(CONFIG_MMC_SDHCI_MSM) += sdhci-msm.o - obj-$(CONFIG_MMC_SDHCI_ST) += sdhci-st.o -+obj-$(CONFIG_MMC_SDHCI_XGS_IPROC) += sdhci-bcm-hr3.o sdhci-xgs-iproc.o - - ifeq ($(CONFIG_CB710_DEBUG),y) - CFLAGS-cb710-mmc += -DDEBUG -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mmc/host/sdhci-bcm-hr3.c b/drivers/mmc/host/sdhci-bcm-hr3.c ---- a/drivers/mmc/host/sdhci-bcm-hr3.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/mmc/host/sdhci-bcm-hr3.c 2017-11-09 17:53:42.528279000 +0800 -@@ -0,0 +1,611 @@ -+/* -+ * drivers/mmc/host/sdhci-bcm-hr3 - Broadcom HR3 SDHCI Platform driver -+ * -+ * Copyright (C) 2014-2016, Broadcom Corporation. All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 and -+ * only version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "sdhci.h" -+ -+struct sdhci_xgs_iproc_data { -+ struct sdhci_host *host; -+ struct clk *clk; -+ unsigned host_num; -+}; -+ -+struct xgs_iproc_sdhci_host { -+ struct sdhci_host host; -+ void __iomem *wrap_base; -+ void __iomem *idm_base; -+ void __iomem *cmicd_base; -+ u32 shadow_cmd; -+ u32 shadow_blk; -+}; -+ -+extern void __iomem *get_iproc_wrap_ctrl_base(void); -+static int iproc_top_sdio_config(void __iomem *cmicd_base); -+ -+static inline void -+iproc_sdhci_writel(struct sdhci_host *host, u32 val, int reg) -+{ -+ /* WAR for SDIO/GPIO setting might be reset by SDK for HR3. */ -+ if (reg == SDHCI_INT_STATUS) { -+ struct xgs_iproc_sdhci_host *iproc_host = (struct xgs_iproc_sdhci_host *)host; -+ iproc_top_sdio_config(iproc_host->cmicd_base); -+ } -+ -+ writel(val, host->ioaddr + reg); -+} -+ -+static inline u32 -+iproc_sdhci_readl(struct sdhci_host *host, int reg) -+{ -+ return readl(host->ioaddr + reg); -+} -+ -+static void -+iproc_sdhci_writew(struct sdhci_host *host, u16 val, int reg) -+{ -+ struct xgs_iproc_sdhci_host *iproc_host = (struct xgs_iproc_sdhci_host *)host; -+ u32 oldval, newval; -+ u32 word_num = (reg >> 1) & 1; -+ u32 word_shift = word_num * 16; -+ u32 mask = 0xffff << word_shift; -+ -+ if (reg == SDHCI_COMMAND) { -+ if (iproc_host->shadow_blk != 0) { -+ iproc_sdhci_writel(host, iproc_host->shadow_blk, SDHCI_BLOCK_SIZE); -+ iproc_host->shadow_blk = 0; -+ } -+ oldval = iproc_host->shadow_cmd; -+ } else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) { -+ oldval = iproc_host->shadow_blk; -+ } else { -+ oldval = iproc_sdhci_readl(host, reg & ~3); -+ } -+ newval = (oldval & ~mask) | (val << word_shift); -+ -+ if (reg == SDHCI_TRANSFER_MODE) { -+ iproc_host->shadow_cmd = newval; -+ } else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) { -+ iproc_host->shadow_blk = newval; -+ } else { -+ iproc_sdhci_writel(host, newval, reg & ~3); -+ } -+} -+ -+static u16 -+iproc_sdhci_readw(struct sdhci_host *host, int reg) -+{ -+ u32 val, word; -+ u32 word_num = (reg >> 1) & 1; -+ u32 word_shift = word_num * 16; -+ -+ val = iproc_sdhci_readl(host, (reg & ~3)); -+ word = (val >> word_shift) & 0xffff; -+ return word; -+} -+ -+static void -+iproc_sdhci_writeb(struct sdhci_host *host, u8 val, int reg) -+{ -+ u32 oldval, newval; -+ u32 byte_num = reg & 3; -+ u32 byte_shift = byte_num * 8; -+ u32 mask = 0xff << byte_shift; -+ -+ oldval = iproc_sdhci_readl(host, reg & ~3); -+ newval = (oldval & ~mask) | (val << byte_shift); -+ -+ iproc_sdhci_writel(host, newval, reg & ~3); -+} -+ -+static u8 -+iproc_sdhci_readb(struct sdhci_host *host, int reg) -+{ -+ u32 val, byte; -+ u32 byte_num = reg & 3; -+ u32 byte_shift = byte_num * 8; -+ -+ val = iproc_sdhci_readl(host, (reg & ~3)); -+ byte = (val >> byte_shift) & 0xff; -+ return byte; -+} -+ -+static u32 -+iproc_sdhci_get_max_clock(struct sdhci_host *host) -+{ -+ unsigned long max_clock; -+ -+ max_clock = (host->caps & SDHCI_CLOCK_V3_BASE_MASK) -+ >> SDHCI_CLOCK_BASE_SHIFT; -+ max_clock *= 1000000; -+ -+ return max_clock; -+} -+ -+static u32 -+iproc_sdhci_get_min_clock(struct sdhci_host *host) -+{ -+ return (host->max_clk / SDHCI_MAX_DIV_SPEC_300); -+} -+ -+static int -+iproc_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode) -+{ -+ /* -+ * Tuning is unnecessary for SDR50 and DDR50; moreover, the IPROC platform -+ * doesn't support SDR104, HS200 and Hs400 cards. So, we needn't do anything -+ * for tuning. -+ */ -+ return 0; -+} -+ -+static void -+iproc_sdhci_set_clock(struct sdhci_host *host, unsigned int clock) -+{ -+ /* -+ * WAR that IPROC SD/MMC host need to set the driver strength -+ * to TYPE_A in 3.3v DS/HS mode even if the driver strength is -+ * meaningless for 3.3V signaling. -+ */ -+ if ((host->timing == MMC_TIMING_LEGACY) || -+ (host->timing == MMC_TIMING_MMC_HS) || -+ (host->timing == MMC_TIMING_SD_HS)) { -+ host->mmc->ios.drv_type = MMC_SET_DRIVER_TYPE_A; -+ } -+ -+ sdhci_set_clock(host, clock); -+} -+ -+static struct sdhci_ops sdhci_xgs_iproc_ops = { -+#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS -+ .write_l = iproc_sdhci_writel, -+ .write_w = iproc_sdhci_writew, -+ .write_b = iproc_sdhci_writeb, -+ .read_l = iproc_sdhci_readl, -+ .read_w = iproc_sdhci_readw, -+ .read_b = iproc_sdhci_readb, -+#else -+#error The iproc SDHCI driver needs CONFIG_MMC_SDHCI_IO_ACCESSORS to be set -+#endif -+ .reset = sdhci_reset, -+ .set_bus_width = sdhci_set_bus_width, -+ .set_uhs_signaling = sdhci_set_uhs_signaling, -+ .set_clock = iproc_sdhci_set_clock, -+ .get_max_clock = iproc_sdhci_get_max_clock, -+ .get_min_clock = iproc_sdhci_get_min_clock, -+ .platform_execute_tuning = iproc_sdhci_execute_tuning, -+}; -+ -+#define IPROC_CMICD_COMPATIBLE "brcm,iproc-cmicd" -+ -+#define CMIC_SBUS_RING_MAP_0_7(base) (base + 0x10098) -+#define CMIC_SBUS_RING_MAP_8_15(base) (base + 0x1009C) -+#define CMIC_SBUS_RING_MAP_16_23(base) (base + 0x100A0) -+#define CMIC_SBUS_RING_MAP_24_31(base) (base + 0x100A4) -+#define CMIC_COMMON_SCHAN_CTRL(base) (base + 0x10000) -+#define CMIC_COMMON_SCHAN_MESSAGE0(base) (base + 0x1000C) -+#define CMIC_COMMON_SCHAN_MESSAGE1(base) (base + 0x10010) -+#define CMIC_COMMON_SCHAN_MESSAGE2(base) (base + 0x10014) -+ -+/* TOP registers */ -+#define TOP_SDIO_MISC_CONTROL 0x0207e500 -+#define TOP_SDIO_MISC_CONTROL__TOP_SDIO_8B_INF 4 -+#define TOP_SDIO_MISC_CONTROL__TOP_SDIO_GPIO_INF_SEL_R 0 -+ -+/* SDIO IDM registers */ -+#define SDIO_IDM0_IO_CONTROL_DIRECT(base) (base + 0x0) -+#define SDIO_IDM0_IO_CONTROL_DIRECT__CMD_COMFLICT_DISABLE 22 -+#define SDIO_IDM0_IO_CONTROL_DIRECT__FEEDBACK_CLK_EN 21 -+#define SDIO_IDM0_IO_CONTROL_DIRECT__clk_enable 0 -+#define SDIO_IDM0_IDM_RESET_CONTROL(base) (base + 0x3F8) -+ -+/* IPROC WRAP registers */ -+#define IPROC_WRAP_SDIO_CONTROL(base) (base + 0xb0) -+#define IPROC_WRAP_SDIO_CONTROL1(base) (base + 0xb4) -+#define IPROC_WRAP_SDIO_CONTROL2(base) (base + 0xb8) -+#define IPROC_WRAP_SDIO_CONTROL3(base) (base + 0xbc) -+#define IPROC_WRAP_SDIO_CONTROL4(base) (base + 0xc0) -+#define IPROC_WRAP_SDIO_CONTROL5(base) (base + 0xc4) -+#define IPROC_WRAP_SDIO_1P8_FAIL_CONTROL(base) (base + 0xc8) -+#define IPROC_WRAP_SDIO_1P8_FAIL_CONTROL__SDIO_VDDO_18V_FAIL_SOVW 1 -+#define IPROC_WRAP_SDIO_1P8_FAIL_CONTROL__SDIO_UHS1_18V_VREG_FAIL 0 -+ -+/* -+ * SDIO_CAPS_L -+ * -+ * Field Bit(s) -+ * =========================== -+ * DDR50 31 -+ * SDR104 30 -+ * SDR50 29 -+ * SLOTTYPE 28:27 -+ * ASYNCHIRQ 26 -+ * SYSBUS64 25 -+ * V18 24 -+ * V3 23 -+ * V33 22 -+ * SUPRSM 21 -+ * SDMA 20 -+ * HSPEED 19 -+ * ADMA2 18 -+ * EXTBUSMED 17 -+ * MAXBLK 16:15 -+ * BCLK 14:7 -+ * TOUT 6 -+ * TOUTFREQ 5:0 -+ */ -+#define SDIO_CAPS_L 0xA17f6470 -+ -+/* -+ * SDIO_CAPS_H -+ * -+ * Field Bit(s) -+ * =========================== -+ * reserved 31:20 -+ * SPIBLOCKMODE 19 -+ * SPIMODE_CAP 18 -+ * CLOCKMULT 17:10 -+ * RETUNE_MODE 9:8 -+ * USETUNE_SDR50 7 -+ * TMRCNT_RETUNE 6:3 -+ * DRVR_TYPED 2 -+ * DRVR_TYPEC 1 -+ * DRVR_TYPEA 0 -+ */ -+#define SDIO_CAPS_H 0x000C000f -+ -+/* -+ * Preset value -+ * -+ * Field Bit(s) -+ * =========================== -+ * Driver Strength 12:11 -+ * Clock Generator 10 -+ * SDCLK Frequeency 9:0 -+ */ -+ -+/* -+ * SDIO_PRESETVAL1 -+ * -+ * Field Bit(s) Description -+ * ============================================================ -+ * DDR50_PRESET 25:13 Preset Value for DDR50 -+ * DEFAULT_PRESET 12:0 Preset Value for Default Speed -+ */ -+#define SDIO_PRESETVAL1 0x01004004 -+ -+/* -+ * SDIO_PRESETVAL2 -+ * -+ * Field Bit(s) Description -+ * ============================================================ -+ * HIGH_SPEED_PRESET 25:13 Preset Value for High Speed -+ * INIT_PRESET 12:0 Preset Value for Initialization -+ */ -+#define SDIO_PRESETVAL2 0x01004100 -+ -+/* -+ * SDIO_PRESETVAL3 -+ * -+ * Field Bit(s) Description -+ * ============================================================ -+ * SDR104_PRESET 25:13 Preset Value for SDR104 -+ * SDR12_PRESET 12:0 Preset Value for SDR12 -+ */ -+#define SDIO_PRESETVAL3 0x00000004 -+ -+/* -+ * SDIO_PRESETVAL4 -+ * -+ * Field Bit(s) Description -+ * ============================================================ -+ * SDR25_PRESET 25:13 Preset Value for SDR25 -+ * SDR50_PRESET 12:0 Preset Value for SDR50 -+ */ -+#define SDIO_PRESETVAL4 0x01005001 -+ -+u32 -+cmicd_schan_read(void __iomem *base, u32 ctrl, u32 addr) { -+ u32 read = 0x0; -+ -+ writel(ctrl, CMIC_COMMON_SCHAN_MESSAGE0(base)); -+ writel(addr, CMIC_COMMON_SCHAN_MESSAGE1(base)); -+ -+ writel(0x1, CMIC_COMMON_SCHAN_CTRL(base)); -+ -+ while (read != 0x2) { -+ read = readl(CMIC_COMMON_SCHAN_CTRL(base)); -+ } -+ read = readl(CMIC_COMMON_SCHAN_MESSAGE1(base)); -+ return read; -+} -+ -+u32 -+cmicd_schan_write(void __iomem *base, u32 ctrl, u32 addr, u32 val) { -+ u32 read = 0x0; -+ -+ writel(ctrl, CMIC_COMMON_SCHAN_MESSAGE0(base)); -+ writel(addr, CMIC_COMMON_SCHAN_MESSAGE1(base)); -+ writel(val, CMIC_COMMON_SCHAN_MESSAGE2(base)); -+ -+ writel(0x1, CMIC_COMMON_SCHAN_CTRL(base)); -+ -+ while (read != 0x2) { -+ read = readl(CMIC_COMMON_SCHAN_CTRL(base)); -+ } -+ return read; -+} -+ -+static void -+cmicd_init_soc(void __iomem *base) { -+ /* Configure SBUS Ring Map for TOP, block id = 16, ring number = 4 */ -+ writel(0x11112200, CMIC_SBUS_RING_MAP_0_7(base)); -+ writel(0x00430001, CMIC_SBUS_RING_MAP_8_15(base)); -+ writel(0x00005064, CMIC_SBUS_RING_MAP_16_23(base)); -+ writel(0x00000000, CMIC_SBUS_RING_MAP_24_31(base)); -+} -+ -+static int -+iproc_top_sdio_config(void __iomem *cmicd_base) -+{ -+ u32 val; -+ -+ cmicd_init_soc(cmicd_base); -+ -+ /* Enable SDIO 8 bit mode */ -+ val = cmicd_schan_read(cmicd_base, 0x2c800200, TOP_SDIO_MISC_CONTROL); -+ if ((val & 0x1f) != 0x1f) { -+ val |= (0x1 << TOP_SDIO_MISC_CONTROL__TOP_SDIO_8B_INF); -+ val |= (0xf << TOP_SDIO_MISC_CONTROL__TOP_SDIO_GPIO_INF_SEL_R); -+ cmicd_schan_write(cmicd_base, 0x34800200, TOP_SDIO_MISC_CONTROL, val); -+ } -+ -+ return 0; -+} -+ -+static int -+iproc_sdio_init(struct xgs_iproc_sdhci_host *iproc_host) -+{ -+ int ret = 0; -+ u32 val; -+ -+ /* Enable SDIO for SDIO/GPIO selection */ -+ ret = iproc_top_sdio_config(iproc_host->cmicd_base); -+ if (ret < 0) { -+ return ret; -+ } -+ -+ /* Release reset */ -+ writel(0x1, SDIO_IDM0_IDM_RESET_CONTROL(iproc_host->idm_base)); -+ udelay(1000); -+ writel(0x0, SDIO_IDM0_IDM_RESET_CONTROL(iproc_host->idm_base)); -+ -+ /* Enable the SDIO clock */ -+ val = readl(SDIO_IDM0_IO_CONTROL_DIRECT(iproc_host->idm_base)); -+ val |= (1 << SDIO_IDM0_IO_CONTROL_DIRECT__CMD_COMFLICT_DISABLE); -+ val |= (1 << SDIO_IDM0_IO_CONTROL_DIRECT__FEEDBACK_CLK_EN); -+ val |= (1 << SDIO_IDM0_IO_CONTROL_DIRECT__clk_enable); -+ writel(val, SDIO_IDM0_IO_CONTROL_DIRECT(iproc_host->idm_base)); -+ -+ /* Set the 1.8v fail control for HR3. -+ * This setting will not impact the uboot SD/MMC driver, since uboot doesn't -+ * support 1.8v. The 1.8v SDIO will be supportted in Kernel. -+ */ -+ val = readl(IPROC_WRAP_SDIO_1P8_FAIL_CONTROL(iproc_host->wrap_base)); -+ val |= (1 << IPROC_WRAP_SDIO_1P8_FAIL_CONTROL__SDIO_VDDO_18V_FAIL_SOVW); -+ val &= ~(1 << IPROC_WRAP_SDIO_1P8_FAIL_CONTROL__SDIO_UHS1_18V_VREG_FAIL); -+ writel(val, IPROC_WRAP_SDIO_1P8_FAIL_CONTROL(iproc_host->wrap_base)); -+ -+ /* -+ * Configure SDIO host controller capabilities -+ * (common setting for all SDIO controllers) -+ */ -+ writel(SDIO_CAPS_H, IPROC_WRAP_SDIO_CONTROL(iproc_host->wrap_base)); -+ writel(SDIO_CAPS_L, IPROC_WRAP_SDIO_CONTROL1(iproc_host->wrap_base)); -+ -+ /* -+ * Configure SDIO host controller preset values -+ * (common setting for all SDIO controllers) -+ */ -+ writel(SDIO_PRESETVAL1, IPROC_WRAP_SDIO_CONTROL2(iproc_host->wrap_base)); -+ writel(SDIO_PRESETVAL2, IPROC_WRAP_SDIO_CONTROL3(iproc_host->wrap_base)); -+ writel(SDIO_PRESETVAL3, IPROC_WRAP_SDIO_CONTROL4(iproc_host->wrap_base)); -+ writel(SDIO_PRESETVAL4, IPROC_WRAP_SDIO_CONTROL5(iproc_host->wrap_base)); -+ -+ return 0; -+} -+ -+static int -+sdhci_xgs_iproc_probe(struct platform_device *pdev) -+{ -+ struct xgs_iproc_sdhci_host *iproc_host; -+ struct sdhci_host *host; -+ struct sdhci_xgs_iproc_data *data; -+ struct device_node *np = pdev->dev.of_node; -+ int ret = 0; -+ -+ /* allocate SDHCI host + platform data memory */ -+ host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_xgs_iproc_data)); -+ if (IS_ERR(host)) { -+ printk(KERN_ERR "SDIO%d: Unable to allocate SDHCI host\n", pdev->id); -+ return PTR_ERR(host); -+ } -+ -+ iproc_host = (struct xgs_iproc_sdhci_host *)host; -+ -+ /* set up data structure */ -+ data = sdhci_priv(host); -+ data->host = host; -+ data->host_num = pdev->id; -+ host->hw_name = "IPROC-SDIO"; -+ host->ops = &sdhci_xgs_iproc_ops; -+ host->mmc->caps = MMC_CAP_8_BIT_DATA; -+ host->quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | -+ SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12; -+ host->irq = (unsigned int)irq_of_parse_and_map(np, 0); -+ host->ioaddr = (void *)of_iomap(np, 0); -+ if (!host->ioaddr) { -+ printk(KERN_ERR "SDIO%d: Unable to iomap SDIO registers\n", pdev->id); -+ ret = -ENXIO; -+ goto err_free_host; -+ } -+ -+ iproc_host->idm_base = of_iomap(np, 1); -+ if (!iproc_host->idm_base) { -+ printk(KERN_ERR "Unable to iomap SDIO IDM base address\n"); -+ ret = -ENXIO; -+ goto err_iounmap; -+ } -+ -+ np = of_find_compatible_node(NULL, NULL, IPROC_CMICD_COMPATIBLE); -+ if (!np) { -+ printk(KERN_ERR "Failed to find IPROC_CMICD defined in DT\n"); -+ ret = -ENODEV; -+ goto err_iounmap; -+ } -+ -+ iproc_host->cmicd_base = of_iomap(np, 0); -+ if (!iproc_host->cmicd_base) { -+ printk(KERN_ERR "Unable to iomap IPROC CMICD base address\n"); -+ ret = -ENXIO; -+ goto err_iounmap; -+ } -+ -+ iproc_host->wrap_base = get_iproc_wrap_ctrl_base(); -+ if (!iproc_host->wrap_base) { -+ printk(KERN_ERR "Unable to get IPROC WRAP base address\n"); -+ ret = -ENXIO; -+ goto err_iounmap; -+ } -+ -+ ret = iproc_sdio_init(iproc_host); -+ if (ret < 0) { -+ printk(KERN_ERR "SDIO%d: SDIO initial failed\n", pdev->id); -+ ret = -ENXIO; -+ goto err_iounmap; -+ } -+ -+ platform_set_drvdata(pdev, data); -+ -+ ret = sdhci_add_host(host); -+ if (ret) { -+ printk(KERN_ERR "SDIO%d: Failed to add SDHCI host\n", pdev->id); -+ goto err_iounmap; -+ } -+ -+ return ret; -+ -+err_iounmap: -+ if (iproc_host->idm_base) -+ iounmap(iproc_host->idm_base); -+ if (iproc_host->cmicd_base) -+ iounmap(iproc_host->cmicd_base); -+ if (host->ioaddr) -+ iounmap(host->ioaddr); -+ -+err_free_host: -+ sdhci_free_host(host); -+ -+ return ret; -+} -+ -+static int __exit -+sdhci_xgs_iproc_remove(struct platform_device *pdev) -+{ -+ struct sdhci_xgs_iproc_data *data = platform_get_drvdata(pdev); -+ struct sdhci_host *host = data->host; -+ struct xgs_iproc_sdhci_host *iproc_host = (struct xgs_iproc_sdhci_host *)host; -+ -+ sdhci_remove_host(host, 0); -+ platform_set_drvdata(pdev, NULL); -+ -+ if (iproc_host->idm_base) -+ iounmap(iproc_host->idm_base); -+ if (iproc_host->cmicd_base) -+ iounmap(iproc_host->cmicd_base); -+ if (host->ioaddr) -+ iounmap(host->ioaddr); -+ -+ sdhci_free_host(host); -+ release_mem_region(pdev->resource[0].start, -+ pdev->resource[0].end - pdev->resource[0].start + 1); -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int -+sdhci_xgs_iproc_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ int ret = 0; -+ struct sdhci_xgs_iproc_data *data = platform_get_drvdata(pdev); -+ -+ ret = sdhci_suspend_host(data->host); -+ if (ret < 0) { -+ printk("%s: %d\n", __FILE__, __LINE__); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int -+sdhci_xgs_iproc_resume(struct platform_device *pdev) -+{ -+ int ret = 0; -+ struct sdhci_xgs_iproc_data *data = platform_get_drvdata(pdev); -+ -+ ret = sdhci_resume_host(data->host); -+ if (ret < 0) { -+ printk("%s: %d\n", __FILE__, __LINE__); -+ return ret; -+ } -+ return 0; -+} -+#else /* CONFIG_PM */ -+ -+#define sdhci_xgs_iproc_suspend NULL -+#define sdhci_xgs_iproc_resume NULL -+ -+#endif /* CONFIG_PM */ -+ -+ -+static const struct of_device_id brcm_iproc_hr3_dt_ids[] = { -+ { .compatible = "brcm,iproc-hr3-sdio"}, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, brcm_iproc_dt_ids); -+ -+static struct platform_driver sdhci_xgs_iproc_driver = { -+ .probe = sdhci_xgs_iproc_probe, -+ .remove = __exit_p(sdhci_xgs_iproc_remove), -+ .suspend = sdhci_xgs_iproc_suspend, -+ .resume = sdhci_xgs_iproc_resume, -+ .driver = { -+ .name = "iproc-hr3-sdio", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(brcm_iproc_hr3_dt_ids), -+ }, -+}; -+ -+module_platform_driver(sdhci_xgs_iproc_driver); -+ -+MODULE_AUTHOR("Broadcom"); -+MODULE_DESCRIPTION("SDHCI XGS HR3 driver"); -+MODULE_LICENSE("GPL"); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mmc/host/sdhci-xgs-iproc.c b/drivers/mmc/host/sdhci-xgs-iproc.c ---- a/drivers/mmc/host/sdhci-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/mmc/host/sdhci-xgs-iproc.c 2017-11-09 17:53:42.564288000 +0800 -@@ -0,0 +1,311 @@ -+/* -+ * drivers/mmc/host/sdhci-iproc.c - Broadcom IPROC SDHCI Platform driver -+ * -+ * Copyright (C) 2014-2016, Broadcom Corporation. All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 and -+ * only version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "sdhci.h" -+ -+struct sdhci_xgs_iproc_data { -+ struct sdhci_host *host; -+ struct clk *clk; -+ unsigned host_num; -+}; -+ -+struct xgs_iproc_sdhci_host { -+ struct sdhci_host host; -+ u32 shadow_cmd; -+ u32 shadow_blk; -+}; -+ -+static inline void -+iproc_sdhci_writel(struct sdhci_host *host, u32 val, int reg) -+{ -+ writel(val, host->ioaddr + reg); -+} -+ -+static inline u32 -+iproc_sdhci_readl(struct sdhci_host *host, int reg) -+{ -+ return readl(host->ioaddr + reg); -+} -+ -+static void -+iproc_sdhci_writew(struct sdhci_host *host, u16 val, int reg) -+{ -+ struct xgs_iproc_sdhci_host *iproc_host = (struct xgs_iproc_sdhci_host *)host; -+ u32 oldval, newval; -+ u32 word_num = (reg >> 1) & 1; -+ u32 word_shift = word_num * 16; -+ u32 mask = 0xffff << word_shift; -+ -+ if (reg == SDHCI_COMMAND) { -+ if (iproc_host->shadow_blk != 0) { -+ iproc_sdhci_writel(host, iproc_host->shadow_blk, SDHCI_BLOCK_SIZE); -+ iproc_host->shadow_blk = 0; -+ } -+ oldval = iproc_host->shadow_cmd; -+ } else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) { -+ oldval = iproc_host->shadow_blk; -+ } else { -+ oldval = iproc_sdhci_readl(host, reg & ~3); -+ } -+ newval = (oldval & ~mask) | (val << word_shift); -+ -+ if (reg == SDHCI_TRANSFER_MODE) { -+ iproc_host->shadow_cmd = newval; -+ } else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) { -+ iproc_host->shadow_blk = newval; -+ } else { -+ iproc_sdhci_writel(host, newval, reg & ~3); -+ } -+} -+ -+static u16 -+iproc_sdhci_readw(struct sdhci_host *host, int reg) -+{ -+ u32 val, word; -+ u32 word_num = (reg >> 1) & 1; -+ u32 word_shift = word_num * 16; -+ -+ val = iproc_sdhci_readl(host, (reg & ~3)); -+ word = (val >> word_shift) & 0xffff; -+ return word; -+} -+ -+ -+static void -+iproc_sdhci_writeb(struct sdhci_host *host, u8 val, int reg) -+{ -+ u32 oldval, newval; -+ u32 byte_num = reg & 3; -+ u32 byte_shift = byte_num * 8; -+ u32 mask = 0xff << byte_shift; -+ -+ oldval = iproc_sdhci_readl(host, reg & ~3); -+ newval = (oldval & ~mask) | (val << byte_shift); -+ -+ iproc_sdhci_writel(host, newval, reg & ~3); -+} -+ -+static u8 -+iproc_sdhci_readb(struct sdhci_host *host, int reg) -+{ -+ u32 val, byte; -+ u32 byte_num = reg & 3; -+ u32 byte_shift = byte_num * 8; -+ -+ val = iproc_sdhci_readl(host, (reg & ~3)); -+ byte = (val >> byte_shift) & 0xff; -+ return byte; -+} -+ -+static u32 -+iproc_sdhci_get_max_clock(struct sdhci_host *host) -+{ -+ unsigned long max_clock; -+ -+ max_clock = (host->caps & SDHCI_CLOCK_V3_BASE_MASK) -+ >> SDHCI_CLOCK_BASE_SHIFT; -+ max_clock *= 1000000; -+ -+ return max_clock; -+} -+ -+static u32 -+iproc_sdhci_get_min_clock(struct sdhci_host *host) -+{ -+ return (host->max_clk / SDHCI_MAX_DIV_SPEC_300); -+} -+ -+static int -+iproc_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode) -+{ -+ /* -+ * Tuning is unnecessary for SDR50 and DDR50; moreover, the IPROC platform -+ * doesn't support SDR104, HS200 and Hs400 cards. So, we needn't do anything -+ * for tuning. -+ */ -+ return 0; -+} -+ -+static void -+iproc_sdhci_set_clock(struct sdhci_host *host, unsigned int clock) -+{ -+ /* -+ * WAR that IPROC SD/MMC host need to set the driver strength -+ * to TYPE_A in 3.3v DS/HS mode even if the driver strength is -+ * meaningless for 3.3V signaling. -+ */ -+ if ((host->timing == MMC_TIMING_LEGACY) || -+ (host->timing == MMC_TIMING_MMC_HS) || -+ (host->timing == MMC_TIMING_SD_HS)) { -+ host->mmc->ios.drv_type = MMC_SET_DRIVER_TYPE_A; -+ } -+ -+ sdhci_set_clock(host, clock); -+} -+ -+static struct sdhci_ops sdhci_xgs_iproc_ops = { -+#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS -+ .write_l = iproc_sdhci_writel, -+ .write_w = iproc_sdhci_writew, -+ .write_b = iproc_sdhci_writeb, -+ .read_l = iproc_sdhci_readl, -+ .read_w = iproc_sdhci_readw, -+ .read_b = iproc_sdhci_readb, -+#else -+#error The iproc SDHCI driver needs CONFIG_MMC_SDHCI_IO_ACCESSORS to be set -+#endif -+ .reset = sdhci_reset, -+ .set_bus_width = sdhci_set_bus_width, -+ .set_uhs_signaling = sdhci_set_uhs_signaling, -+ .set_clock = iproc_sdhci_set_clock, -+ .get_max_clock = iproc_sdhci_get_max_clock, -+ .get_min_clock = iproc_sdhci_get_min_clock, -+ .platform_execute_tuning = iproc_sdhci_execute_tuning, -+}; -+ -+static int -+sdhci_xgs_iproc_probe(struct platform_device *pdev) -+{ -+ struct sdhci_host *host; -+ struct sdhci_xgs_iproc_data *data; -+ struct device_node *np = pdev->dev.of_node; -+ int ret = 0; -+ -+ /* allocate SDHCI host + platform data memory */ -+ host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_xgs_iproc_data)); -+ if (IS_ERR(host)) { -+ printk(KERN_ERR "SDIO%d: Unable to allocate SDHCI host\n", pdev->id); -+ return PTR_ERR(host); -+ } -+ -+ /* set up data structure */ -+ data = sdhci_priv(host); -+ data->host = host; -+ data->host_num = pdev->id; -+ host->hw_name = "IPROC-SDIO"; -+ host->ops = &sdhci_xgs_iproc_ops; -+ host->mmc->caps = MMC_CAP_8_BIT_DATA; -+ host->quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | -+ SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12; -+ -+ host->irq = (unsigned int)irq_of_parse_and_map(np, 0); -+ host->ioaddr = (void *)of_iomap(np, 0); -+ if (!host->ioaddr) { -+ printk(KERN_ERR "SDIO%d: Unable to iomap SDIO registers\n", pdev->id); -+ ret = -ENXIO; -+ goto err_free_host; -+ } -+ -+ platform_set_drvdata(pdev, data); -+ -+ ret = sdhci_add_host(host); -+ if (ret) { -+ printk(KERN_ERR "SDIO%d: Failed to add SDHCI host\n", pdev->id); -+ goto err_iounmap; -+ } -+ -+ return ret; -+ -+err_iounmap: -+ iounmap(host->ioaddr); -+ -+err_free_host: -+ sdhci_free_host(host); -+ -+ return ret; -+} -+ -+static int __exit -+sdhci_xgs_iproc_remove(struct platform_device *pdev) -+{ -+ struct sdhci_xgs_iproc_data *data = platform_get_drvdata(pdev); -+ struct sdhci_host *host = data->host; -+ -+ sdhci_remove_host(host, 0); -+ platform_set_drvdata(pdev, NULL); -+ iounmap(host->ioaddr); -+ sdhci_free_host(host); -+ release_mem_region(pdev->resource[0].start, -+ pdev->resource[0].end - pdev->resource[0].start + 1); -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int -+sdhci_xgs_iproc_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ int ret = 0; -+ struct sdhci_xgs_iproc_data *data = platform_get_drvdata(pdev); -+ -+ ret = sdhci_suspend_host(data->host); -+ if (ret < 0) { -+ printk("%s: %d\n", __FILE__, __LINE__); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int -+sdhci_xgs_iproc_resume(struct platform_device *pdev) -+{ -+ int ret = 0; -+ struct sdhci_xgs_iproc_data *data = platform_get_drvdata(pdev); -+ -+ ret = sdhci_resume_host(data->host); -+ if (ret < 0) { -+ printk("%s: %d\n", __FILE__, __LINE__); -+ return ret; -+ } -+ return 0; -+} -+#else /* CONFIG_PM */ -+ -+#define sdhci_xgs_iproc_suspend NULL -+#define sdhci_xgs_iproc_resume NULL -+ -+#endif /* CONFIG_PM */ -+ -+ -+static const struct of_device_id brcm_iproc_xgs_dt_ids[] = { -+ { .compatible = "brcm,iproc-xgs-sdio"}, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, brcm_iproc_dt_ids); -+ -+static struct platform_driver sdhci_xgs_iproc_driver = { -+ .probe = sdhci_xgs_iproc_probe, -+ .remove = __exit_p(sdhci_xgs_iproc_remove), -+ .suspend = sdhci_xgs_iproc_suspend, -+ .resume = sdhci_xgs_iproc_resume, -+ .driver = { -+ .name = "iproc-xgs-sdio", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(brcm_iproc_xgs_dt_ids), -+ }, -+}; -+ -+module_platform_driver(sdhci_xgs_iproc_driver); -+ -+MODULE_AUTHOR("Broadcom"); -+MODULE_DESCRIPTION("SDHCI XGS IPROC driver"); -+MODULE_LICENSE("GPL"); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/Makefile b/drivers/mtd/Makefile ---- a/drivers/mtd/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/mtd/Makefile 2017-11-09 17:53:42.613320000 +0800 -@@ -33,4 +33,5 @@ inftl-objs := inftlcore.o inftlmount.o - obj-y += chips/ lpddr/ maps/ devices/ nand/ onenand/ tests/ - - obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ -+obj-$(CONFIG_MTD_SPI_NOR_IPROC) += spi-nor/ - obj-$(CONFIG_MTD_UBI) += ubi/ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig ---- a/drivers/mtd/devices/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/mtd/devices/Kconfig 2017-11-09 17:53:42.646279000 +0800 -@@ -95,6 +95,12 @@ config MTD_M25P80 - if you want to specify device partitioning or to use a device which - doesn't support the JEDEC ID instruction. - -+config MTD_M25P80_IPROC -+ tristate "M25P80 modified for BRCM iProc" -+ depends on SPI_MASTER && MTD_SPI_NOR_IPROC -+ help -+ This enables access to most modern SPI flash chips for BRCM iProc QSPI controller -+ - config MTD_SPEAR_SMI - tristate "SPEAR MTD NOR Support through SMI controller" - depends on PLAT_SPEAR -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile ---- a/drivers/mtd/devices/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/mtd/devices/Makefile 2017-11-09 17:53:42.647286000 +0800 -@@ -12,6 +12,7 @@ obj-$(CONFIG_MTD_LART) += lart.o - obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o - obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o - obj-$(CONFIG_MTD_M25P80) += m25p80.o -+obj-$(CONFIG_MTD_M25P80_IPROC) += m25p80-iproc.o - obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o - obj-$(CONFIG_MTD_SST25L) += sst25l.o - obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/devices/m25p80-iproc.c b/drivers/mtd/devices/m25p80-iproc.c ---- a/drivers/mtd/devices/m25p80-iproc.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/mtd/devices/m25p80-iproc.c 2017-11-09 17:53:42.661287000 +0800 -@@ -0,0 +1,328 @@ -+/* -+ * MTD SPI driver for ST M25Pxx (and similar) serial flash chips based -+ * on m25p80.c with BRCM iProc patch -+ * -+ * This code 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 -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+ -+#define MAX_CMD_SIZE 6 -+struct m25p { -+ struct spi_device *spi; -+ struct spi_nor spi_nor; -+ u8 command[MAX_CMD_SIZE]; -+}; -+ -+static int m25p80_read_reg(struct spi_nor *nor, u8 code, u8 *val, int len) -+{ -+ struct m25p *flash = nor->priv; -+ struct spi_device *spi = flash->spi; -+ int ret; -+ -+ ret = spi_write_then_read(spi, &code, 1, val, len); -+ if (ret < 0) -+ dev_err(&spi->dev, "error %d reading %x\n", ret, code); -+ -+ return ret; -+} -+ -+static void m25p_addr2cmd(struct spi_nor *nor, unsigned int addr, unsigned int len, u8 *cmd) -+{ -+ u16 addr_width = nor->addr_width; -+ -+#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ /* Use 4-byte mode only if (address + len) is > 16MB */ -+ if (addr + len > 0x1000000) { -+ addr_width = 4; -+ } -+#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ -+ -+ /* opcode is in cmd[0] */ -+ cmd[1] = addr >> (addr_width * 8 - 8); -+ cmd[2] = addr >> (addr_width * 8 - 16); -+ cmd[3] = addr >> (addr_width * 8 - 24); -+ cmd[4] = addr >> (addr_width * 8 - 32); -+} -+ -+static int m25p_cmdsz(struct spi_nor *nor, unsigned int addr) -+{ -+#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ /* Use 4-byte mode only if the address is >= 16MB */ -+ if (addr >= 0x1000000) { -+ return 1 + 4; -+ } -+#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ -+ return 1 + nor->addr_width; -+} -+ -+static int m25p80_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len) -+{ -+ struct m25p *flash = nor->priv; -+ struct spi_device *spi = flash->spi; -+ -+ flash->command[0] = opcode; -+ if (buf) -+ memcpy(&flash->command[1], buf, len); -+ -+ return spi_write(spi, flash->command, len + 1); -+} -+ -+static void m25p80_write(struct spi_nor *nor, loff_t to, size_t len, -+ size_t *retlen, const u_char *buf) -+{ -+ struct m25p *flash = nor->priv; -+ struct spi_device *spi = flash->spi; -+ struct spi_transfer t[2] = {}; -+ struct spi_message m; -+ int cmd_sz = m25p_cmdsz(nor, to); -+ -+ spi_message_init(&m); -+ -+ if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second) -+ cmd_sz = 1; -+ -+ flash->command[0] = nor->program_opcode; -+ m25p_addr2cmd(nor, to, 1, flash->command); -+ -+ t[0].tx_buf = flash->command; -+ t[0].len = cmd_sz; -+ spi_message_add_tail(&t[0], &m); -+ -+ t[1].tx_buf = buf; -+ t[1].len = len; -+ spi_message_add_tail(&t[1], &m); -+ -+ spi_sync(spi, &m); -+ -+ *retlen += m.actual_length - cmd_sz; -+} -+ -+static inline unsigned int m25p80_rx_nbits(struct spi_nor *nor) -+{ -+ switch (nor->flash_read) { -+ case SPI_NOR_DUAL: -+ return 2; -+ case SPI_NOR_QUAD: -+ return 4; -+ default: -+ return 0; -+ } -+} -+ -+/* -+ * Read an address range from the nor chip. The address range -+ * may be any size provided it is within the physical boundaries. -+ */ -+static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len, -+ size_t *retlen, u_char *buf) -+{ -+ struct m25p *flash = nor->priv; -+ struct spi_device *spi = flash->spi; -+ struct spi_transfer t[2]; -+ struct spi_message m; -+ unsigned int dummy = nor->read_dummy; -+ -+ /* convert the dummy cycles to the number of bytes */ -+ dummy /= 8; -+ -+ spi_message_init(&m); -+ memset(t, 0, (sizeof t)); -+ -+ flash->command[0] = nor->read_opcode; -+ m25p_addr2cmd(nor, from, len, flash->command); -+ -+ t[0].tx_buf = flash->command; -+ t[0].len = m25p_cmdsz(nor, from + len - 1) + dummy; -+ spi_message_add_tail(&t[0], &m); -+ -+ t[1].rx_buf = buf; -+ t[1].rx_nbits = m25p80_rx_nbits(nor); -+ t[1].len = len; -+ spi_message_add_tail(&t[1], &m); -+ -+ spi_sync(spi, &m); -+ -+ *retlen = m.actual_length - m25p_cmdsz(nor, from + len - 1) - dummy; -+ return 0; -+} -+ -+static int m25p80_erase(struct spi_nor *nor, loff_t offset) -+{ -+ struct m25p *flash = nor->priv; -+ -+ dev_dbg(nor->dev, "%dKiB at 0x%08x\n", -+ flash->spi_nor.mtd.erasesize / 1024, (u32)offset); -+ -+ /* Set up command buffer. */ -+ flash->command[0] = nor->erase_opcode; -+ m25p_addr2cmd(nor, offset, 1, flash->command); -+ -+ spi_write(flash->spi, flash->command, m25p_cmdsz(nor, offset)); -+ -+ return 0; -+} -+ -+/* -+ * board specific setup should have ensured the SPI clock used here -+ * matches what the READ command supports, at least until this driver -+ * understands FAST_READ (for clocks over 25 MHz). -+ */ -+static int m25p_probe(struct spi_device *spi) -+{ -+ struct mtd_part_parser_data ppdata; -+ struct flash_platform_data *data; -+ struct m25p *flash; -+ struct spi_nor *nor; -+ enum read_mode mode = SPI_NOR_NORMAL; -+ char *flash_name = NULL; -+ int ret; -+ -+ data = dev_get_platdata(&spi->dev); -+ -+ flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL); -+ if (!flash) -+ return -ENOMEM; -+ -+ nor = &flash->spi_nor; -+ -+ /* install the hooks */ -+ nor->read = m25p80_read; -+ nor->write = m25p80_write; -+ nor->erase = m25p80_erase; -+ nor->write_reg = m25p80_write_reg; -+ nor->read_reg = m25p80_read_reg; -+ -+ nor->dev = &spi->dev; -+ nor->flash_node = spi->dev.of_node; -+ nor->priv = flash; -+ -+ spi_set_drvdata(spi, flash); -+ flash->spi = spi; -+ -+ if (spi->mode & SPI_RX_QUAD) -+ mode = SPI_NOR_QUAD; -+ else if (spi->mode & SPI_RX_DUAL) -+ mode = SPI_NOR_DUAL; -+ -+ if (data && data->name) -+ nor->mtd.name = data->name; -+ -+ /* For some (historical?) reason many platforms provide two different -+ * names in flash_platform_data: "name" and "type". Quite often name is -+ * set to "m25p80" and then "type" provides a real chip name. -+ * If that's the case, respect "type" and ignore a "name". -+ */ -+ if (data && data->type) -+ flash_name = data->type; -+ else -+ flash_name = spi->modalias; -+ -+ ret = spi_nor_scan(nor, flash_name, mode); -+ if (ret) -+ return ret; -+ -+ ppdata.of_node = spi->dev.of_node; -+ -+ return mtd_device_parse_register(&nor->mtd, NULL, &ppdata, -+ data ? data->parts : NULL, -+ data ? data->nr_parts : 0); -+} -+ -+ -+static int m25p_remove(struct spi_device *spi) -+{ -+ struct m25p *flash = spi_get_drvdata(spi); -+ -+ /* Clean up MTD stuff. */ -+ return mtd_device_unregister(&flash->spi_nor.mtd); -+} -+ -+/* -+ * Do NOT add to this array without reading the following: -+ * -+ * Historically, many flash devices are bound to this driver by their name. But -+ * since most of these flash are compatible to some extent, and their -+ * differences can often be differentiated by the JEDEC read-ID command, we -+ * encourage new users to add support to the spi-nor library, and simply bind -+ * against a generic string here (e.g., "jedec,spi-nor"). -+ * -+ * Many flash names are kept here in this list (as well as in spi-nor.c) to -+ * keep them available as module aliases for existing platforms. -+ */ -+static const struct spi_device_id m25p_ids[] = { -+ /* -+ * Entries not used in DTs that should be safe to drop after replacing -+ * them with "nor-jedec" in platform data. -+ */ -+ {"s25sl064a"}, {"w25x16"}, {"m25p10"}, {"m25px64"}, -+ -+ /* -+ * Entries that were used in DTs without "nor-jedec" fallback and should -+ * be kept for backward compatibility. -+ */ -+ {"at25df321a"}, {"at25df641"}, {"at26df081a"}, -+ {"mr25h256"}, -+ {"mx25l4005a"}, {"mx25l1606e"}, {"mx25l6405d"}, {"mx25l12805d"}, -+ {"mx25l25635e"},{"mx66l51235l"}, -+ {"n25q064"}, {"n25q128a11"}, {"n25q128a13"}, {"n25q512a"}, -+ {"s25fl256s1"}, {"s25fl512s"}, {"s25sl12801"}, {"s25fl008k"}, -+ {"s25fl064k"}, -+ {"sst25vf040b"},{"sst25vf016b"},{"sst25vf032b"},{"sst25wf040"}, -+ {"m25p40"}, {"m25p80"}, {"m25p16"}, {"m25p32"}, -+ {"m25p64"}, {"m25p128"}, -+ {"w25x80"}, {"w25x32"}, {"w25q32"}, {"w25q32dw"}, -+ {"w25q80bl"}, {"w25q128"}, {"w25q256"}, -+ -+ /* Flashes that can't be detected using JEDEC */ -+ {"m25p05-nonjedec"}, {"m25p10-nonjedec"}, {"m25p20-nonjedec"}, -+ {"m25p40-nonjedec"}, {"m25p80-nonjedec"}, {"m25p16-nonjedec"}, -+ {"m25p32-nonjedec"}, {"m25p64-nonjedec"}, {"m25p128-nonjedec"}, -+ -+ { }, -+}; -+MODULE_DEVICE_TABLE(spi, m25p_ids); -+ -+static const struct of_device_id m25p_of_table[] = { -+ /* -+ * Generic compatibility for SPI NOR that can be identified by the -+ * JEDEC READ ID opcode (0x9F). Use this, if possible. -+ */ -+ { .compatible = "jedec,spi-nor" }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, m25p_of_table); -+ -+static struct spi_driver m25p80_driver = { -+ .driver = { -+ .name = "m25p80", -+ .of_match_table = m25p_of_table, -+ }, -+ .id_table = m25p_ids, -+ .probe = m25p_probe, -+ .remove = m25p_remove, -+ -+ /* REVISIT: many of these chips have deep power-down modes, which -+ * should clearly be entered on suspend() to minimize power use. -+ * And also when they're otherwise idle... -+ */ -+}; -+ -+module_spi_driver(m25p80_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Mike Lavender"); -+MODULE_DESCRIPTION("MTD SPI driver for ST M25Pxx flash chips"); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig ---- a/drivers/mtd/maps/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/mtd/maps/Kconfig 2017-11-09 17:53:42.700292000 +0800 -@@ -97,6 +97,15 @@ config MSP_FLASH_MAP_LIMIT - default "0x02000000" - depends on MSP_FLASH_MAP_LIMIT_32M - -+config MTD_NOR_XGS_IPROC -+ bool "Broadcom XGS iProc CFI NOR support" -+ depends on (ARCH_XGS_IPROC || COMPILE_TEST) && MTD_CFI -+ default n -+ help -+ This selects a driver for the iProc NOR support. -+ -+ If unsure, say N. -+ - config MTD_SUN_UFLASH - tristate "Sun Microsystems userflash support" - depends on SPARC && MTD_CFI && PCI -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile ---- a/drivers/mtd/maps/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/mtd/maps/Makefile 2017-11-09 17:53:42.701291000 +0800 -@@ -43,3 +43,4 @@ obj-$(CONFIG_MTD_VMU) += vmu-flash.o - obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o - obj-$(CONFIG_MTD_LATCH_ADDR) += latch-addr-flash.o - obj-$(CONFIG_MTD_LANTIQ) += lantiq-flash.o -+obj-$(CONFIG_MTD_NOR_XGS_IPROC) += xgs-iproc-flash.o -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/maps/xgs-iproc-flash.c b/drivers/mtd/maps/xgs-iproc-flash.c ---- a/drivers/mtd/maps/xgs-iproc-flash.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/mtd/maps/xgs-iproc-flash.c 2017-11-09 17:53:42.757297000 +0800 -@@ -0,0 +1,229 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#define IPROC_NOR_COMPATIBLE "brcm,iproc-nor" -+extern void __iomem *get_iproc_dmu_pcu_base(void); -+ -+/* HR2 */ -+#define PNOR_NAND_SEL_REG_OVERRIDE_HR2 2 -+#define PNOR_NAND_SEL_REG_PNOR_SEL_HR2 3 -+ -+/* GH/HR3 */ -+#define PNOR_NAND_SEL_REG_OVERRIDE_GH 0 -+#define PNOR_NAND_SEL_REG_PNOR_SEL_GH 1 -+#define PNOR_DIRECT_CMD_OFFSET 0x10 -+#define PNOR_SET_OPMODE_OFFSET 0X18 -+ -+ -+#define IPROC_STRAP_BOOT_DEV_NAND 1 -+#define IPROC_STRAP_BOOT_DEV_PNOR 4 -+#define ICFG_PNOR_STRAPS__PNOR_SRAM_MW_R 0 -+#define PNOR_set_opmode__set_mw_R 0 -+#define PNOR_direct_cmd__cmd_type_R 21 -+#define IPROC_DMU_STRAPS_OFFSET 0x28 -+#define IPROC_BOOT_STRAP_MASK 0x7 -+#if defined(CONFIG_MACH_HR2) || defined(CONFIG_MACH_GH) -+#define IPROC_STRAP_BOOT_DEV_SHIFT 9 -+#elif defined(CONFIG_MACH_GH2) || defined(CONFIG_MACH_SB2) || \ -+ defined(CONFIG_MACH_HR3) -+#define IPROC_STRAP_BOOT_DEV_SHIFT 10 -+#endif -+ -+ -+static struct mtd_info *nor_mtd; -+ -+static struct map_info s29gl_map = { -+ .name = "S29GL", -+ .bankwidth = 4, -+}; -+ -+ -+/* -+ * Initialize FLASH support -+ */ -+static int __init s29gl_mtd_init(void) -+{ -+ struct device_node *np; -+ void __iomem *reg_addr; -+#ifdef CONFIG_MACH_IPROC_P7 -+ void __iomem *reg_strap; -+#endif -+ void __iomem *nor_enable=NULL; -+ struct platform_device *pdev; -+ struct resource *memres; -+ struct mtd_part_parser_data ppdata; -+ u32 straps, val; -+ -+ np = of_find_compatible_node(NULL, NULL, IPROC_NOR_COMPATIBLE); -+ if (!np) { -+ printk(KERN_INFO "No NOR flash controller enabled in DT\n"); -+ return -ENODEV; -+ } -+ -+ if (!of_device_is_available(np)) { -+ printk(KERN_INFO "NOR flash controller disabled in DT\n"); -+ return -ENODEV; -+ } -+ -+ reg_addr = of_iomap(np, 0); -+ if (!reg_addr) { -+ printk(KERN_ERR "NOR base addr ioremap eror\n"); -+ return -EIO; -+ } -+ -+ nor_enable = of_iomap(np, 2); -+ if (!nor_enable) { -+ printk(KERN_ERR "PNOR sel ioremap eror\n"); -+ return -EIO; -+ } -+ -+ /* Check boot device */ -+ straps = readl(get_iproc_dmu_pcu_base() + IPROC_DMU_STRAPS_OFFSET); -+ straps = (straps >> IPROC_STRAP_BOOT_DEV_SHIFT) & IPROC_BOOT_STRAP_MASK; -+ -+ if (straps == IPROC_STRAP_BOOT_DEV_NAND) { -+ /* If booting from NAND, PNOR cannot be used */ -+ return -ENODEV; -+ } else if (straps != IPROC_STRAP_BOOT_DEV_PNOR) { -+ /* Switching to PNOR only if not booting from PNOR */ -+ val = readl_relaxed(nor_enable); -+ if (of_find_compatible_node(NULL, NULL, "brcm,hurricane2")) { -+ val |= (1UL << PNOR_NAND_SEL_REG_OVERRIDE_HR2) | -+ (1UL << PNOR_NAND_SEL_REG_PNOR_SEL_HR2); -+ } else { -+ val |= (1UL << PNOR_NAND_SEL_REG_OVERRIDE_GH) | -+ (1UL << PNOR_NAND_SEL_REG_PNOR_SEL_GH); -+ } -+ writel_relaxed(val, nor_enable); -+ -+#ifdef CONFIG_MACH_IPROC_P7 -+ /* Configure controller memory width based on strap */ -+ reg_strap = of_iomap(np, 3); -+ if (!reg_strap) { -+ printk(KERN_ERR "NOR strap addr ioremap eror\n"); -+ return -EIO; -+ } -+ straps = readl_relaxed(reg_strap) & -+ (1 << ICFG_PNOR_STRAPS__PNOR_SRAM_MW_R); -+ if (straps) { -+ /* 16-bit */ -+ val = readl_relaxed ((void * __iomem) -+ (reg_addr + PNOR_SET_OPMODE_OFFSET)); -+ val |= (1 << PNOR_set_opmode__set_mw_R); -+ writel_relaxed(val, (void * __iomem)( -+ reg_addr + PNOR_SET_OPMODE_OFFSET)); -+ } else { -+ /* 8-bit */ -+ val = readl_relaxed((void * __iomem) -+ (reg_addr + PNOR_SET_OPMODE_OFFSET)); -+ val &= ~(1 << PNOR_set_opmode__set_mw_R); -+ writel_relaxed(val, (void * __iomem) -+ (reg_addr + PNOR_SET_OPMODE_OFFSET)); -+ } -+ val = readl_relaxed((void * __iomem)(reg_addr + -+ PNOR_DIRECT_CMD_OFFSET)); -+ val |= (2 << PNOR_direct_cmd__cmd_type_R); -+ writel_relaxed(val, (void * __iomem)(reg_addr + -+ PNOR_DIRECT_CMD_OFFSET)); -+#endif -+ } -+ -+ printk(KERN_INFO "S29GL-MTD: NOR_INTERFACE Enabled\n"); -+ -+ udelay(1000); -+ -+ pdev = of_find_device_by_node(np); -+ memres = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ s29gl_map.phys = memres->start; -+ s29gl_map.size = resource_size(memres); -+ s29gl_map.virt = ioremap(s29gl_map.phys, s29gl_map.size); -+ -+ if (!s29gl_map.virt) { -+ printk(KERN_ERR "S29GL-MTD: ioremap failed\n"); -+ if (nor_enable) { -+ /* revert to NAND mode */ -+ val = readl_relaxed(nor_enable); -+ if (of_find_compatible_node(NULL, NULL, -+ "brcm,hurricane2")) -+ val &= ~(1UL << PNOR_NAND_SEL_REG_PNOR_SEL_HR2); -+ else -+ val &= ~(1UL << PNOR_NAND_SEL_REG_PNOR_SEL_GH); -+ writel_relaxed(val, nor_enable); -+ } -+ return -EIO; -+ } -+ -+ simple_map_init(&s29gl_map); -+ -+ // Probe for flash bankwidth 4 -+ printk (KERN_INFO "S29GL-MTD probing 32bit FLASH\n"); -+ nor_mtd = do_map_probe("cfi_probe", &s29gl_map); -+ if (!nor_mtd) { -+ printk (KERN_INFO "S29GL-MTD probing 16bit FLASH\n"); -+ // Probe for bankwidth 2 -+ s29gl_map.bankwidth = 2; -+ nor_mtd = do_map_probe("cfi_probe", &s29gl_map); -+ } -+ -+ if (nor_mtd) { -+ nor_mtd->owner = THIS_MODULE; -+ ppdata.of_node = np; -+ mtd_device_parse_register(nor_mtd, NULL, &ppdata, NULL, 0); -+ printk (KERN_INFO "S29GL-MTD MTD partitions parsed!\n"); -+ return 0; -+ } -+ -+ printk (KERN_INFO "S29GL-MTD NO FLASH found!\n"); -+ if (nor_enable) { -+ /* revert to NAND mode */ -+ val = readl_relaxed(nor_enable); -+ if (of_find_compatible_node(NULL, NULL, "brcm,hurricane2")) -+ val &= ~(1UL << PNOR_NAND_SEL_REG_PNOR_SEL_HR2); -+ else -+ val &= ~(1UL << PNOR_NAND_SEL_REG_PNOR_SEL_GH); -+ writel_relaxed(val, nor_enable); -+ } -+ iounmap((void *)s29gl_map.virt); -+ return -ENXIO; -+} -+ -+/* -+ * Cleanup -+ */ -+static void __exit s29gl_mtd_cleanup(void) -+{ -+ if (nor_mtd) { -+ mtd_device_unregister(nor_mtd); -+ map_destroy(nor_mtd); -+ } -+ -+ if (s29gl_map.virt) { -+ iounmap((void *)s29gl_map.virt); -+ s29gl_map.virt = 0; -+ } -+} -+ -+ -+module_init(s29gl_mtd_init); -+module_exit(s29gl_mtd_cleanup); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MTD map driver for Hurricane2 Deerhound evaluation boards"); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig ---- a/drivers/mtd/nand/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/mtd/nand/Kconfig 2017-11-09 17:53:42.777285000 +0800 -@@ -399,6 +399,17 @@ config MTD_NAND_BRCMNAND - originally designed for Set-Top Box but is used on various BCM7xxx, - BCM3xxx, BCM63xxx, iProc/Cygnus and more. - -+if MTD_NAND_BRCMNAND -+config MTD_NAND_XGS_IPROC -+ bool "XGS iProc NAND controller" -+ depends on ARCH_XGS_IPROC -+ default n -+ help -+ Enable XGS iProc NAND controller. -+ -+ If unsure, say N. -+endif # MTD_NAND_BRCMNAND -+ - config MTD_NAND_BCM47XXNFLASH - tristate "Support for NAND flash on BCM4706 BCMA bus" - depends on BCMA_NFLASH -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c ---- a/drivers/mtd/nand/brcmnand/brcmnand.c 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/mtd/nand/brcmnand/brcmnand.c 2017-11-09 17:53:42.804318000 +0800 -@@ -14,7 +14,7 @@ - #include - #include - #include --#include -+/*#include */ - #include - #include - #include -@@ -26,7 +26,7 @@ - #include - #include - #include --#include -+/*#include */ - #include - #include - #include -@@ -1053,8 +1053,16 @@ static void brcmnand_send_cmd(struct brc - ctrl->cmd_pending = cmd; - - intfc = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS); -+ /* Currently one DTS file supports both NAND and PNOR flash, -+ * but not both controllers can be activated at the same time. -+ * The strap pin on board determines either NAND or PNOR flash -+ * controller is active. Need to comment out the following checking -+ * of NAND controller ready, otherwise it will fail as actually the -+ * NAND controller might be disabled. -+ */ -+#if !defined (CONFIG_MTD_NAND_XGS_IPROC) - BUG_ON(!(intfc & INTFC_CTLR_READY)); -- -+#endif - mb(); /* flush previous writes */ - brcmnand_write_reg(ctrl, BRCMNAND_CMD_START, - cmd << brcmnand_cmd_shift(ctrl)); -@@ -1282,9 +1290,20 @@ static uint8_t brcmnand_read_byte(struct - if (host->last_byte > 0 && offs == 0) - chip->cmdfunc(mtd, NAND_CMD_RNDOUT, addr, -1); - -+ /* For XGS iproc, no byte swap needed for little-endian mode */ -+#if defined (CONFIG_MTD_NAND_XGS_IPROC) -+ if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) -+ ret = ctrl->flash_cache[offs >> 2] >> -+ (24 - ((offs & 0x03) << 3)); -+ else -+ ret = ctrl->flash_cache[offs >> 2] >> -+ ((offs & 0x03) << 3); -+#else - ret = ctrl->flash_cache[offs >> 2] >> - (24 - ((offs & 0x03) << 3)); -+#endif - break; -+ - case NAND_CMD_GET_FEATURES: - if (host->last_byte >= ONFI_SUBFEATURE_PARAM_LEN) { - ret = 0; -@@ -1483,6 +1502,56 @@ static int brcmnand_read_by_pio(struct m - return ret; - } - -+/* -+ * Check a page to see if it is erased (w/ bitflips) after an uncorrectable ECC -+ * error -+ * -+ * Because the HW ECC signals an ECC error if an erase paged has even a single -+ * bitflip, we must check each ECC error to see if it is actually an erased -+ * page with bitflips, not a truly corrupted page. -+ * -+ * On a real error, return a negative error code (-EBADMSG for ECC error), and -+ * buf will contain raw data. -+ * Otherwise, buf gets filled with 0xffs and return the maximum number of -+ * bitflips-per-ECC-sector to the caller. -+ * -+ */ -+static int brcmstb_nand_verify_erased_page(struct mtd_info *mtd, -+ struct nand_chip *chip, void *buf, u64 addr) -+{ -+ int i, sas; -+ void *oob = chip->oob_poi; -+ int bitflips = 0; -+ int page = addr >> chip->page_shift; -+ int ret; -+ -+ if (!buf) { -+ buf = chip->buffers->databuf; -+ /* Invalidate page cache */ -+ chip->pagebuf = -1; -+ } -+ -+ sas = mtd->oobsize / chip->ecc.steps; -+ -+ /* read without ecc for verification */ -+ chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); -+ ret = chip->ecc.read_page_raw(mtd, chip, buf, true, page); -+ if (ret) -+ return ret; -+ -+ for (i = 0; i < chip->ecc.steps; i++, oob += sas) { -+ ret = nand_check_erased_ecc_chunk(buf, chip->ecc.size, -+ oob, sas, NULL, 0, -+ chip->ecc.strength); -+ if (ret < 0) -+ return ret; -+ -+ bitflips = max(bitflips, ret); -+ } -+ -+ return bitflips; -+} -+ - static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip, - u64 addr, unsigned int trans, u32 *buf, u8 *oob) - { -@@ -1513,6 +1582,18 @@ static int brcmnand_read(struct mtd_info - } - - if (mtd_is_eccerr(err)) { -+ /* -+ * Controller version 7.2 has hw encoder to detect erased page -+ * bitflips, apply sw verification for older controllers only -+ */ -+ if (ctrl->nand_version < 0x0702) { -+ err = brcmstb_nand_verify_erased_page(mtd, chip, buf, -+ addr); -+ /* erased page bitflips corrected */ -+ if (err >= 0) -+ return err; -+ } -+ - dev_dbg(ctrl->dev, "uncorrectable error at 0x%llx\n", - (unsigned long long)err_addr); - mtd->ecc_stats.failed++; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig ---- a/drivers/mtd/spi-nor/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/mtd/spi-nor/Kconfig 2017-11-09 17:53:42.932285000 +0800 -@@ -42,3 +42,38 @@ config SPI_NXP_SPIFI - controller and want to access the Flash as a mtd device. - - endif # MTD_SPI_NOR -+ -+ -+menuconfig MTD_SPI_NOR_IPROC -+ tristate "BRCM IPROC SPI-NOR device support" -+ depends on MTD -+ help -+ This is the framework for the SPI NOR which can be used by the SPI -+ device drivers and the SPI-NOR device driver. -+ -+if MTD_SPI_NOR_IPROC -+ -+config M25PXX_STAY_IN_3BYTE_MODE -+ bool "Stay in 3-byte address mode when idle" -+ default n -+ help -+ This option forces the flash to stay in 3-byte address mode when idle -+ (even for flashes that require 4-byte address). This is work around the -+ reset problem if the controller cannot issue 4-byte OPCODE when booting. -+ -+endif # MTD_SPI_NOR_IPROC -+ -+config MTD_SPI_NOR_USE_4K_SECTORS -+ bool "Use small 4096 B erase sectors" -+ default n -+ help -+ Many flash memories support erasing small (4096 B) sectors. Depending -+ on the usage this feature may provide performance gain in comparison -+ to erasing whole blocks (32/64 KiB). -+ Changing a small part of the flash's contents is usually faster with -+ small sectors. On the other hand erasing should be faster when using -+ 64 KiB block instead of 16 × 4 KiB sectors. -+ -+ Please note that some tools/drivers/filesystems may not work with -+ 4096 B erase size (e.g. UBIFS requires 15 KiB as a minimum). -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile ---- a/drivers/mtd/spi-nor/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/mtd/spi-nor/Makefile 2017-11-09 17:53:42.933281000 +0800 -@@ -1,3 +1,5 @@ - obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o -+obj-$(CONFIG_MTD_SPI_NOR_IPROC) += spi-nor-iproc.o - obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o - obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/mtd/spi-nor/spi-nor-iproc.c b/drivers/mtd/spi-nor/spi-nor-iproc.c ---- a/drivers/mtd/spi-nor/spi-nor-iproc.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/mtd/spi-nor/spi-nor-iproc.c 2017-11-09 17:53:42.936293000 +0800 -@@ -0,0 +1,1467 @@ -+/* -+ Based on spi-nor.c -+ -+ * This code 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 -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+/* Define max times to check status register before we give up. */ -+ -+/* -+ * For everything but full-chip erase; probably could be much smaller, but kept -+ * around for safety for now -+ */ -+#define DEFAULT_READY_WAIT_JIFFIES (40UL * HZ) -+ -+/* -+ * For full-chip erase, calibrated to a 2MB flash (M25P16); should be scaled up -+ * for larger flash -+ */ -+#define CHIP_ERASE_2MB_READY_WAIT_JIFFIES (40UL * HZ) -+ -+#define SPI_NOR_MAX_ID_LEN 6 -+ -+struct flash_info { -+ char *name; -+ -+ /* -+ * This array stores the ID bytes. -+ * The first three bytes are the JEDIC ID. -+ * JEDEC ID zero means "no ID" (mostly older chips). -+ */ -+ u8 id[SPI_NOR_MAX_ID_LEN]; -+ u8 id_len; -+ -+ /* The size listed here is what works with SPINOR_OP_SE, which isn't -+ * necessarily called a "sector" by the vendor. -+ */ -+ unsigned sector_size; -+ u16 n_sectors; -+ -+ u16 page_size; -+ u16 addr_width; -+ -+ u16 flags; -+#define SECT_4K 0x01 /* SPINOR_OP_BE_4K works uniformly */ -+#define SPI_NOR_NO_ERASE 0x02 /* No erase command needed */ -+#define SST_WRITE 0x04 /* use SST byte programming */ -+#define SPI_NOR_NO_FR 0x08 /* Can't do fastread */ -+#define SECT_4K_PMC 0x10 /* SPINOR_OP_BE_4K_PMC works uniformly */ -+#define SPI_NOR_DUAL_READ 0x20 /* Flash supports Dual Read */ -+#define SPI_NOR_QUAD_READ 0x40 /* Flash supports Quad Read */ -+#define USE_FSR 0x80 /* use flag status register */ -+}; -+ -+#define JEDEC_MFR(info) ((info)->id[0]) -+ -+static const struct flash_info *spi_nor_match_id(const char *name); -+ -+/* -+ * Read the status register, returning its value in the location -+ * Return the status register value. -+ * Returns negative if error occurred. -+ */ -+static int read_sr(struct spi_nor *nor) -+{ -+ int ret; -+ u8 val; -+ -+ ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val, 1); -+ if (ret < 0) { -+ pr_err("error %d reading SR\n", (int) ret); -+ return ret; -+ } -+ -+ return val; -+} -+ -+/* -+ * Read the flag status register, returning its value in the location -+ * Return the status register value. -+ * Returns negative if error occurred. -+ */ -+static int read_fsr(struct spi_nor *nor) -+{ -+ int ret; -+ u8 val; -+ -+ ret = nor->read_reg(nor, SPINOR_OP_RDFSR, &val, 1); -+ if (ret < 0) { -+ pr_err("error %d reading FSR\n", ret); -+ return ret; -+ } -+ -+ return val; -+} -+ -+/* -+ * Read configuration register, returning its value in the -+ * location. Return the configuration register value. -+ * Returns negative if error occured. -+ */ -+static int read_cr(struct spi_nor *nor) -+{ -+ int ret; -+ u8 val; -+ -+ ret = nor->read_reg(nor, SPINOR_OP_RDCR, &val, 1); -+ if (ret < 0) { -+ dev_err(nor->dev, "error %d reading CR\n", ret); -+ return ret; -+ } -+ -+ return val; -+} -+ -+/* -+ * Dummy Cycle calculation for different type of read. -+ * It can be used to support more commands with -+ * different dummy cycle requirements. -+ */ -+static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor) -+{ -+ switch (nor->flash_read) { -+ case SPI_NOR_FAST: -+ case SPI_NOR_DUAL: -+ case SPI_NOR_QUAD: -+ return 8; -+ case SPI_NOR_NORMAL: -+ return 0; -+ } -+ return 0; -+} -+ -+/* -+ * Write status register 1 byte -+ * Returns negative if error occurred. -+ */ -+static inline int write_sr(struct spi_nor *nor, u8 val) -+{ -+ nor->cmd_buf[0] = val; -+ return nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 1); -+} -+ -+/* -+ * Set write enable latch with Write Enable command. -+ * Returns negative if error occurred. -+ */ -+static inline int write_enable(struct spi_nor *nor) -+{ -+ return nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0); -+} -+ -+/* -+ * Send write disble instruction to the chip. -+ */ -+static inline int write_disable(struct spi_nor *nor) -+{ -+ return nor->write_reg(nor, SPINOR_OP_WRDI, NULL, 0); -+} -+ -+static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd) -+{ -+ return mtd->priv; -+} -+ -+/* Enable/disable 4-byte addressing mode. */ -+static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info, -+ int enable) -+{ -+ int status; -+ bool need_wren = false; -+ u8 cmd; -+ -+ switch (JEDEC_MFR(info)) { -+ case SNOR_MFR_MICRON: -+ /* Some Micron need WREN command; all will accept it */ -+ need_wren = true; -+ case SNOR_MFR_MACRONIX: -+ case SNOR_MFR_WINBOND: -+ if (need_wren) -+ write_enable(nor); -+ -+ cmd = enable ? SPINOR_OP_EN4B : SPINOR_OP_EX4B; -+ status = nor->write_reg(nor, cmd, NULL, 0); -+ if (need_wren) -+ write_disable(nor); -+ -+ return status; -+ default: -+ /* Spansion style */ -+ nor->cmd_buf[0] = enable << 7; -+ return nor->write_reg(nor, SPINOR_OP_BRWR, nor->cmd_buf, 1); -+ } -+} -+static inline int spi_nor_sr_ready(struct spi_nor *nor) -+{ -+ int sr = read_sr(nor); -+ if (sr < 0) -+ return sr; -+ else -+ return !(sr & SR_WIP); -+} -+ -+static inline int spi_nor_fsr_ready(struct spi_nor *nor) -+{ -+ int fsr = read_fsr(nor); -+ if (fsr < 0) -+ return fsr; -+ else -+ return fsr & FSR_READY; -+} -+ -+static int spi_nor_ready(struct spi_nor *nor) -+{ -+ int sr, fsr; -+ sr = spi_nor_sr_ready(nor); -+ if (sr < 0) -+ return sr; -+ fsr = nor->flags & SNOR_F_USE_FSR ? spi_nor_fsr_ready(nor) : 1; -+ if (fsr < 0) -+ return fsr; -+ return sr && fsr; -+} -+ -+/* -+ * Service routine to read status register until ready, or timeout occurs. -+ * Returns non-zero if error. -+ */ -+static int spi_nor_wait_till_ready_with_timeout(struct spi_nor *nor, -+ unsigned long timeout_jiffies) -+{ -+ unsigned long deadline; -+ int timeout = 0, ret; -+ -+ deadline = jiffies + timeout_jiffies; -+ -+ while (!timeout) { -+ if (time_after_eq(jiffies, deadline)) -+ timeout = 1; -+ -+ ret = spi_nor_ready(nor); -+ if (ret < 0) -+ return ret; -+ if (ret) -+ return 0; -+ -+ cond_resched(); -+ } -+ -+ dev_err(nor->dev, "flash operation timed out\n"); -+ -+ return -ETIMEDOUT; -+} -+ -+static int spi_nor_wait_till_ready(struct spi_nor *nor) -+{ -+ return spi_nor_wait_till_ready_with_timeout(nor, -+ DEFAULT_READY_WAIT_JIFFIES); -+} -+ -+/* -+ * Erase the whole flash memory -+ * -+ * Returns 0 if successful, non-zero otherwise. -+ */ -+static int erase_chip(struct spi_nor *nor) -+{ -+ dev_dbg(nor->dev, " %lldKiB\n", (long long)(nor->mtd.size >> 10)); -+ -+ return nor->write_reg(nor, SPINOR_OP_CHIP_ERASE, NULL, 0); -+} -+ -+static int spi_nor_lock_and_prep(struct spi_nor *nor, enum spi_nor_ops ops) -+{ -+ int ret = 0; -+ -+ mutex_lock(&nor->lock); -+ -+ if (nor->prepare) { -+ ret = nor->prepare(nor, ops); -+ if (ret) { -+ dev_err(nor->dev, "failed in the preparation.\n"); -+ mutex_unlock(&nor->lock); -+ return ret; -+ } -+ } -+ return ret; -+} -+ -+static void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops) -+{ -+ if (nor->unprepare) -+ nor->unprepare(nor, ops); -+ mutex_unlock(&nor->lock); -+} -+ -+/* -+ * Erase an address range on the nor chip. The address range may extend -+ * one or more erase sectors. Return an error is there is a problem erasing. -+ */ -+static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) -+{ -+ struct spi_nor *nor = mtd_to_spi_nor(mtd); -+ u32 addr, len; -+ uint32_t rem; -+ int ret; -+ -+ dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr, -+ (long long)instr->len); -+ -+ div_u64_rem(instr->len, mtd->erasesize, &rem); -+ if (rem) -+ return -EINVAL; -+ -+ addr = instr->addr; -+ len = instr->len; -+ -+ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_ERASE); -+ if (ret) -+ return ret; -+ -+ /* whole-chip erase? */ -+ if (len == mtd->size) { -+ unsigned long timeout; -+ -+ write_enable(nor); -+ -+ if (erase_chip(nor)) { -+ ret = -EIO; -+ goto erase_err; -+ } -+ -+ /* -+ * Scale the timeout linearly with the size of the flash, with -+ * a minimum calibrated to an old 2MB flash. We could try to -+ * pull these from CFI/SFDP, but these values should be good -+ * enough for now. -+ */ -+ timeout = max(CHIP_ERASE_2MB_READY_WAIT_JIFFIES, -+ CHIP_ERASE_2MB_READY_WAIT_JIFFIES * -+ (unsigned long)(mtd->size / SZ_2M)); -+ ret = spi_nor_wait_till_ready_with_timeout(nor, timeout); -+ if (ret) -+ goto erase_err; -+ -+ /* REVISIT in some cases we could speed up erasing large regions -+ * by using SPINOR_OP_SE instead of SPINOR_OP_BE_4K. We may have set up -+ * to use "small sector erase", but that's not always optimal. -+ */ -+ -+ /* "sector"-at-a-time erase */ -+ } else { -+ while (len) { -+#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ /* Set to 4-byte mode if addr >= 16M */ -+ /* Note: set_4byte will call write_disable for Micron flash, so set_4byte should be called before the following write_enable(nor) */ -+ if ( addr >= 0x1000000 ) -+ set_4byte(nor, nor->priv1, 1); -+#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ -+ -+ write_enable(nor); -+ -+ if (nor->erase(nor, addr)) { -+ ret = -EIO; -+ goto erase_err; -+ } -+ -+ addr += mtd->erasesize; -+ len -= mtd->erasesize; -+ -+ ret = spi_nor_wait_till_ready(nor); -+ if (ret) -+ goto erase_err; -+ } -+ } -+ -+#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ /* Reset to 3-byte mode if it was set to 4-byte mode */ -+ if (addr >= 0x1000000) { -+ spi_nor_wait_till_ready(nor); -+ set_4byte(nor, nor->priv1, 0); -+ } -+#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ -+ -+ write_disable(nor); -+ -+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE); -+ -+ instr->state = MTD_ERASE_DONE; -+ mtd_erase_callback(instr); -+ -+ return ret; -+ -+erase_err: -+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE); -+ instr->state = MTD_ERASE_FAILED; -+ return ret; -+} -+ -+static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs, -+ uint64_t *len) -+{ -+ struct mtd_info *mtd = &nor->mtd; -+ u8 mask = SR_BP2 | SR_BP1 | SR_BP0; -+ int shift = ffs(mask) - 1; -+ int pow; -+ -+ if (!(sr & mask)) { -+ /* No protection */ -+ *ofs = 0; -+ *len = 0; -+ } else { -+ pow = ((sr & mask) ^ mask) >> shift; -+ *len = mtd->size >> pow; -+ *ofs = mtd->size - *len; -+ } -+} -+ -+/* -+ * Return 1 if the entire region is locked, 0 otherwise -+ */ -+static int stm_is_locked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len, -+ u8 sr) -+{ -+ loff_t lock_offs; -+ uint64_t lock_len; -+ -+ stm_get_locked_range(nor, sr, &lock_offs, &lock_len); -+ -+ return (ofs + len <= lock_offs + lock_len) && (ofs >= lock_offs); -+} -+ -+/* -+ * Lock a region of the flash. Compatible with ST Micro and similar flash. -+ * Supports only the block protection bits BP{0,1,2} in the status register -+ * (SR). Does not support these features found in newer SR bitfields: -+ * - TB: top/bottom protect - only handle TB=0 (top protect) -+ * - SEC: sector/block protect - only handle SEC=0 (block protect) -+ * - CMP: complement protect - only support CMP=0 (range is not complemented) -+ * -+ * Sample table portion for 8MB flash (Winbond w25q64fw): -+ * -+ * SEC | TB | BP2 | BP1 | BP0 | Prot Length | Protected Portion -+ * -------------------------------------------------------------------------- -+ * X | X | 0 | 0 | 0 | NONE | NONE -+ * 0 | 0 | 0 | 0 | 1 | 128 KB | Upper 1/64 -+ * 0 | 0 | 0 | 1 | 0 | 256 KB | Upper 1/32 -+ * 0 | 0 | 0 | 1 | 1 | 512 KB | Upper 1/16 -+ * 0 | 0 | 1 | 0 | 0 | 1 MB | Upper 1/8 -+ * 0 | 0 | 1 | 0 | 1 | 2 MB | Upper 1/4 -+ * 0 | 0 | 1 | 1 | 0 | 4 MB | Upper 1/2 -+ * X | X | 1 | 1 | 1 | 8 MB | ALL -+ * -+ * Returns negative on errors, 0 on success. -+ */ -+static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) -+{ -+ struct mtd_info *mtd = &nor->mtd; -+ u8 status_old, status_new; -+ u8 mask = SR_BP2 | SR_BP1 | SR_BP0; -+ u8 shift = ffs(mask) - 1, pow, val; -+ -+ status_old = read_sr(nor); -+ -+ /* SPI NOR always locks to the end */ -+ if (ofs + len != mtd->size) { -+ /* Does combined region extend to end? */ -+ if (!stm_is_locked_sr(nor, ofs + len, mtd->size - ofs - len, -+ status_old)) -+ return -EINVAL; -+ len = mtd->size - ofs; -+ } -+ -+ /* -+ * Need smallest pow such that: -+ * -+ * 1 / (2^pow) <= (len / size) -+ * -+ * so (assuming power-of-2 size) we do: -+ * -+ * pow = ceil(log2(size / len)) = log2(size) - floor(log2(len)) -+ */ -+ pow = ilog2(mtd->size) - ilog2(len); -+ val = mask - (pow << shift); -+ if (val & ~mask) -+ return -EINVAL; -+ /* Don't "lock" with no region! */ -+ if (!(val & mask)) -+ return -EINVAL; -+ -+ status_new = (status_old & ~mask) | val; -+ -+ /* Only modify protection if it will not unlock other areas */ -+ if ((status_new & mask) <= (status_old & mask)) -+ return -EINVAL; -+ -+ write_enable(nor); -+ return write_sr(nor, status_new); -+} -+ -+/* -+ * Unlock a region of the flash. See stm_lock() for more info -+ * -+ * Returns negative on errors, 0 on success. -+ */ -+static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) -+{ -+ struct mtd_info *mtd = &nor->mtd; -+ uint8_t status_old, status_new; -+ u8 mask = SR_BP2 | SR_BP1 | SR_BP0; -+ u8 shift = ffs(mask) - 1, pow, val; -+ -+ status_old = read_sr(nor); -+ -+ /* Cannot unlock; would unlock larger region than requested */ -+ if (stm_is_locked_sr(nor, ofs - mtd->erasesize, mtd->erasesize, -+ status_old)) -+ return -EINVAL; -+ -+ /* -+ * Need largest pow such that: -+ * -+ * 1 / (2^pow) >= (len / size) -+ * -+ * so (assuming power-of-2 size) we do: -+ * -+ * pow = floor(log2(size / len)) = log2(size) - ceil(log2(len)) -+ */ -+ pow = ilog2(mtd->size) - order_base_2(mtd->size - (ofs + len)); -+ if (ofs + len == mtd->size) { -+ val = 0; /* fully unlocked */ -+ } else { -+ val = mask - (pow << shift); -+ /* Some power-of-two sizes are not supported */ -+ if (val & ~mask) -+ return -EINVAL; -+ } -+ -+ status_new = (status_old & ~mask) | val; -+ -+ /* Only modify protection if it will not lock other areas */ -+ if ((status_new & mask) >= (status_old & mask)) -+ return -EINVAL; -+ -+ write_enable(nor); -+ return write_sr(nor, status_new); -+} -+ -+/* -+ * Check if a region of the flash is (completely) locked. See stm_lock() for -+ * more info. -+ * -+ * Returns 1 if entire region is locked, 0 if any portion is unlocked, and -+ * negative on errors. -+ */ -+static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len) -+{ -+ int status; -+ -+ status = read_sr(nor); -+ if (status < 0) -+ return status; -+ -+ return stm_is_locked_sr(nor, ofs, len, status); -+} -+ -+static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) -+{ -+ struct spi_nor *nor = mtd_to_spi_nor(mtd); -+ int ret; -+ -+ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_LOCK); -+ if (ret) -+ return ret; -+ -+ ret = nor->flash_lock(nor, ofs, len); -+ -+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK); -+ return ret; -+} -+ -+static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) -+{ -+ struct spi_nor *nor = mtd_to_spi_nor(mtd); -+ int ret; -+ -+ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_UNLOCK); -+ if (ret) -+ return ret; -+ -+ ret = nor->flash_unlock(nor, ofs, len); -+ -+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK); -+ return ret; -+} -+ -+static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) -+{ -+ struct spi_nor *nor = mtd_to_spi_nor(mtd); -+ int ret; -+ -+ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_UNLOCK); -+ if (ret) -+ return ret; -+ -+ ret = nor->flash_is_locked(nor, ofs, len); -+ -+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK); -+ return ret; -+} -+ -+/* Used when the "_ext_id" is two bytes at most */ -+#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ -+ .id = { \ -+ ((_jedec_id) >> 16) & 0xff, \ -+ ((_jedec_id) >> 8) & 0xff, \ -+ (_jedec_id) & 0xff, \ -+ ((_ext_id) >> 8) & 0xff, \ -+ (_ext_id) & 0xff, \ -+ }, \ -+ .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \ -+ .sector_size = (_sector_size), \ -+ .n_sectors = (_n_sectors), \ -+ .page_size = 256, \ -+ .flags = (_flags), -+ -+#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ -+ .id = { \ -+ ((_jedec_id) >> 16) & 0xff, \ -+ ((_jedec_id) >> 8) & 0xff, \ -+ (_jedec_id) & 0xff, \ -+ ((_ext_id) >> 16) & 0xff, \ -+ ((_ext_id) >> 8) & 0xff, \ -+ (_ext_id) & 0xff, \ -+ }, \ -+ .id_len = 6, \ -+ .sector_size = (_sector_size), \ -+ .n_sectors = (_n_sectors), \ -+ .page_size = 256, \ -+ .flags = (_flags), -+ -+#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags) \ -+ .sector_size = (_sector_size), \ -+ .n_sectors = (_n_sectors), \ -+ .page_size = (_page_size), \ -+ .addr_width = (_addr_width), \ -+ .flags = (_flags), -+ -+/* NOTE: double check command sets and memory organization when you add -+ * more nor chips. This current list focusses on newer chips, which -+ * have been converging on command sets which including JEDEC ID. -+ * -+ * All newly added entries should describe *hardware* and should use SECT_4K -+ * (or SECT_4K_PMC) if hardware supports erasing 4 KiB sectors. For usage -+ * scenarios excluding small sectors there is config option that can be -+ * disabled: CONFIG_MTD_SPI_NOR_USE_4K_SECTORS. -+ * For historical (and compatibility) reasons (before we got above config) some -+ * old entries may be missing 4K flag. -+ */ -+static const struct flash_info spi_nor_ids[] = { -+ /* Atmel -- some are (confusingly) marketed as "DataFlash" */ -+ { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) }, -+ { "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8, SECT_4K) }, -+ -+ { "at25df041a", INFO(0x1f4401, 0, 64 * 1024, 8, SECT_4K) }, -+ { "at25df321a", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) }, -+ { "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) }, -+ -+ { "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8, SECT_4K) }, -+ { "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) }, -+ { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) }, -+ { "at26df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) }, -+ -+ { "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) }, -+ -+ /* EON -- en25xxx */ -+ { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, -+ { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, -+ { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, -+ { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, -+ { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, -+ { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, -+ { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, -+ -+ /* ESMT */ -+ { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K) }, -+ -+ /* Everspin */ -+ { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, -+ { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, -+ -+ /* Fujitsu */ -+ { "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) }, -+ -+ /* GigaDevice */ -+ { "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, SECT_4K) }, -+ { "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, SECT_4K) }, -+ -+ /* Intel/Numonyx -- xxxs33b */ -+ { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) }, -+ { "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) }, -+ { "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) }, -+ -+ /* ISSI */ -+ { "is25cd512", INFO(0x7f9d20, 0, 32 * 1024, 2, SECT_4K) }, -+ -+ /* Macronix */ -+ { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, -+ { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) }, -+ { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, -+ { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, -+ { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, -+ { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) }, -+ { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, -+ { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) }, -+ { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) }, -+ { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, -+ { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, -+ { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, -+ { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, -+ { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) }, -+ { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, -+ -+ /* Micron */ -+ { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, -+ { "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, -+ { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, -+ { "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, -+ { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ) }, -+ { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ) }, -+ { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, -+ { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, -+ { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, -+ { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, -+ -+ /* PMC */ -+ { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, -+ { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) }, -+ { "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024, 64, SECT_4K) }, -+ -+ /* Spansion -- single (large) sector size only, at least -+ * for the chips listed here (without boot sectors). -+ */ -+ { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, -+ { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, -+ { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, -+ { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, -+ { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, -+ { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) }, -+ { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) }, -+ { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) }, -+ { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, -+ { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, -+ { "s25fl004k", INFO(0xef4013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) }, -+ { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ) }, -+ -+ /* SST -- large erase sizes are "overlays", "sectors" are 4K */ -+ { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, -+ { "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, -+ { "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) }, -+ { "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) }, -+ { "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128, SECT_4K) }, -+ { "sst25wf512", INFO(0xbf2501, 0, 64 * 1024, 1, SECT_4K | SST_WRITE) }, -+ { "sst25wf010", INFO(0xbf2502, 0, 64 * 1024, 2, SECT_4K | SST_WRITE) }, -+ { "sst25wf020", INFO(0xbf2503, 0, 64 * 1024, 4, SECT_4K | SST_WRITE) }, -+ { "sst25wf020a", INFO(0x621612, 0, 64 * 1024, 4, SECT_4K) }, -+ { "sst25wf040b", INFO(0x621613, 0, 64 * 1024, 8, SECT_4K) }, -+ { "sst25wf040", INFO(0xbf2504, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, -+ { "sst25wf080", INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, -+ { "sst26vf016", INFO(0xbf2601, 0, 64 * 1024, 32, SECT_4K) }, -+ { "sst26vf032", INFO(0xbf2602, 0, 64 * 1024, 64, SECT_4K) }, -+ -+ /* ST Microelectronics -- newer production may have feature updates */ -+ { "m25p05", INFO(0x202010, 0, 32 * 1024, 2, 0) }, -+ { "m25p10", INFO(0x202011, 0, 32 * 1024, 4, 0) }, -+ { "m25p20", INFO(0x202012, 0, 64 * 1024, 4, 0) }, -+ { "m25p40", INFO(0x202013, 0, 64 * 1024, 8, 0) }, -+ { "m25p80", INFO(0x202014, 0, 64 * 1024, 16, 0) }, -+ { "m25p16", INFO(0x202015, 0, 64 * 1024, 32, 0) }, -+ { "m25p32", INFO(0x202016, 0, 64 * 1024, 64, 0) }, -+ { "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) }, -+ { "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) }, -+ -+ { "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2, 0) }, -+ { "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4, 0) }, -+ { "m25p20-nonjedec", INFO(0, 0, 64 * 1024, 4, 0) }, -+ { "m25p40-nonjedec", INFO(0, 0, 64 * 1024, 8, 0) }, -+ { "m25p80-nonjedec", INFO(0, 0, 64 * 1024, 16, 0) }, -+ { "m25p16-nonjedec", INFO(0, 0, 64 * 1024, 32, 0) }, -+ { "m25p32-nonjedec", INFO(0, 0, 64 * 1024, 64, 0) }, -+ { "m25p64-nonjedec", INFO(0, 0, 64 * 1024, 128, 0) }, -+ { "m25p128-nonjedec", INFO(0, 0, 256 * 1024, 64, 0) }, -+ -+ { "m45pe10", INFO(0x204011, 0, 64 * 1024, 2, 0) }, -+ { "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) }, -+ { "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) }, -+ -+ { "m25pe20", INFO(0x208012, 0, 64 * 1024, 4, 0) }, -+ { "m25pe80", INFO(0x208014, 0, 64 * 1024, 16, 0) }, -+ { "m25pe16", INFO(0x208015, 0, 64 * 1024, 32, SECT_4K) }, -+ -+ { "m25px16", INFO(0x207115, 0, 64 * 1024, 32, SECT_4K) }, -+ { "m25px32", INFO(0x207116, 0, 64 * 1024, 64, SECT_4K) }, -+ { "m25px32-s0", INFO(0x207316, 0, 64 * 1024, 64, SECT_4K) }, -+ { "m25px32-s1", INFO(0x206316, 0, 64 * 1024, 64, SECT_4K) }, -+ { "m25px64", INFO(0x207117, 0, 64 * 1024, 128, 0) }, -+ { "m25px80", INFO(0x207114, 0, 64 * 1024, 16, 0) }, -+ -+ /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ -+ { "w25x05", INFO(0xef3010, 0, 64 * 1024, 1, SECT_4K) }, -+ { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, -+ { "w25x20", INFO(0xef3012, 0, 64 * 1024, 4, SECT_4K) }, -+ { "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) }, -+ { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) }, -+ { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, -+ { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, -+ { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) }, -+ { "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, -+ { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, -+ { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, -+ { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) }, -+ { "w25m512", INFO(0xef7119, 0, 64 * 1024, 1024, SECT_4K) }, -+ -+ /* Catalyst / On Semiconductor -- non-JEDEC */ -+ { "cat25c11", CAT25_INFO( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, -+ { "cat25c03", CAT25_INFO( 32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, -+ { "cat25c09", CAT25_INFO( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, -+ { "cat25c17", CAT25_INFO( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, -+ { "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, -+ { }, -+}; -+ -+static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) -+{ -+ int tmp; -+ u8 id[SPI_NOR_MAX_ID_LEN]; -+ const struct flash_info *info; -+ -+ tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN); -+ if (tmp < 0) { -+ dev_dbg(nor->dev, " error %d reading JEDEC ID\n", tmp); -+ return ERR_PTR(tmp); -+ } -+ -+ for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) { -+ info = &spi_nor_ids[tmp]; -+ if (info->id_len) { -+ if (!memcmp(info->id, id, info->id_len)) -+ return &spi_nor_ids[tmp]; -+ } -+ } -+ dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %2x, %2x\n", -+ id[0], id[1], id[2]); -+ return ERR_PTR(-ENODEV); -+} -+ -+static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, -+ size_t *retlen, u_char *buf) -+{ -+ struct spi_nor *nor = mtd_to_spi_nor(mtd); -+ int ret; -+ -+ dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len); -+ -+ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_READ); -+ if (ret) -+ return ret; -+ -+#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ /* set to 4-byte mode */ -+ if (from + len > 0x1000000) -+ set_4byte(nor, nor->priv1, 1); -+#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ -+ -+ ret = nor->read(nor, from, len, retlen, buf); -+ -+#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ /* set to 3-byte mode */ -+ if (from + len > 0x1000000) -+ set_4byte(nor, nor->priv1, 0); -+#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ -+ -+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ); -+ return ret; -+} -+ -+static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, -+ size_t *retlen, const u_char *buf) -+{ -+ struct spi_nor *nor = mtd_to_spi_nor(mtd); -+ size_t actual; -+ int ret; -+#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ int addr_4byte = 0; -+#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ -+ -+ dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len); -+ -+ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_WRITE); -+ if (ret) -+ return ret; -+ -+#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ /* set to 4-byte mode */ -+ if (to >= 0x1000000) { -+ set_4byte(nor, nor->priv1, 1); -+ addr_4byte = 1; -+ } -+#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ -+ -+ write_enable(nor); -+ -+ nor->sst_write_second = false; -+ -+ actual = to % 2; -+ /* Start write from odd address. */ -+ if (actual) { -+ nor->program_opcode = SPINOR_OP_BP; -+ -+ /* write one byte. */ -+ nor->write(nor, to, 1, retlen, buf); -+ ret = spi_nor_wait_till_ready(nor); -+ if (ret) -+ goto time_out; -+ } -+ to += actual; -+ -+#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ /* Use 4-byte mode only if the address is > 16MB */ -+ if (to >= 0x1000000 && !addr_4byte) { -+ set_4byte(nor, nor->priv1, 1); -+ addr_4byte = 1; -+ } -+#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ -+ -+ /* Write out most of the data here. */ -+ for (; actual < len - 1; actual += 2) { -+ nor->program_opcode = SPINOR_OP_AAI_WP; -+ -+ /* write two bytes. */ -+ nor->write(nor, to, 2, retlen, buf + actual); -+ ret = spi_nor_wait_till_ready(nor); -+ if (ret) -+ goto time_out; -+ to += 2; -+ nor->sst_write_second = true; -+ } -+ nor->sst_write_second = false; -+ -+ write_disable(nor); -+ ret = spi_nor_wait_till_ready(nor); -+ if (ret) -+ goto time_out; -+ -+ /* Write out trailing byte if it exists. */ -+ if (actual != len) { -+#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ /* Use 4-byte mode only if the address is > 16MB */ -+ if (to >= 0x1000000 && !addr_4byte) { -+ set_4byte(nor, nor->priv1, 1); -+ addr_4byte = 1; -+ } -+#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ -+ -+ write_enable(nor); -+ -+ nor->program_opcode = SPINOR_OP_BP; -+ nor->write(nor, to, 1, retlen, buf + actual); -+ -+ ret = spi_nor_wait_till_ready(nor); -+ if (ret) -+ goto time_out; -+ write_disable(nor); -+ } -+ -+#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ /* Reset to 3-byte mode if the address is > 16MB */ -+ if (addr_4byte) -+ set_4byte(nor, nor->priv1, 0); -+#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ -+ -+time_out: -+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE); -+ return ret; -+} -+ -+/* -+ * Write an address range to the nor chip. Data must be written in -+ * FLASH_PAGESIZE chunks. The address range may be any size provided -+ * it is within the physical boundaries. -+ */ -+static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, -+ size_t *retlen, const u_char *buf) -+{ -+ struct spi_nor *nor = mtd_to_spi_nor(mtd); -+ u32 page_offset, page_size, i; -+ int ret; -+ -+ dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len); -+ -+ ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_WRITE); -+ if (ret) -+ return ret; -+ -+#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ /* set to 4-byte mode */ -+ /* Note: set_4byte will call write_disable for Micron flash, so set_4byte should be called before the following write_enable(nor) */ -+ if (to >= 0x1000000) -+ set_4byte(nor, nor->priv1, 1); -+#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ -+ -+ write_enable(nor); -+ -+ page_offset = to & (nor->page_size - 1); -+ -+ /* do all the bytes fit onto one page? */ -+ if (page_offset + len <= nor->page_size) { -+ nor->write(nor, to, len, retlen, buf); -+ } else { -+ /* the size of data remaining on the first page */ -+ page_size = nor->page_size - page_offset; -+ nor->write(nor, to, page_size, retlen, buf); -+ -+ /* write everything in nor->page_size chunks */ -+ for (i = page_size; i < len; i += page_size) { -+ page_size = len - i; -+ if (page_size > nor->page_size) -+ page_size = nor->page_size; -+ -+ ret = spi_nor_wait_till_ready(nor); -+ if (ret) -+ goto write_err; -+ -+#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ /* set to 4-byte mode if this is the first time > 16MB*/ -+ if ( (to + i - page_size < 0x1000000) && (to + i >= 0x1000000) ) -+ set_4byte(nor, nor->priv1, 1); -+#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ -+ -+ write_enable(nor); -+ -+ nor->write(nor, to + i, page_size, retlen, buf + i); -+ } -+ } -+ -+ ret = spi_nor_wait_till_ready(nor); -+ -+#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ /* reset to 3-byte mode*/ -+ if (to + len >= 0x1000000) -+ set_4byte(nor, nor->priv1, 0); -+#endif /* CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ -+ -+write_err: -+ spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE); -+ return ret; -+} -+ -+static int macronix_quad_enable(struct spi_nor *nor) -+{ -+ int ret, val; -+ -+ val = read_sr(nor); -+ write_enable(nor); -+ -+ write_sr(nor, val | SR_QUAD_EN_MX); -+ -+ if (spi_nor_wait_till_ready(nor)) -+ return 1; -+ -+ ret = read_sr(nor); -+ if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) { -+ dev_err(nor->dev, "Macronix Quad bit not set\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* -+ * Write status Register and configuration register with 2 bytes -+ * The first byte will be written to the status register, while the -+ * second byte will be written to the configuration register. -+ * Return negative if error occured. -+ */ -+static int write_sr_cr(struct spi_nor *nor, u16 val) -+{ -+ nor->cmd_buf[0] = val & 0xff; -+ nor->cmd_buf[1] = (val >> 8); -+ -+ return nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 2); -+} -+ -+static int spansion_quad_enable(struct spi_nor *nor) -+{ -+ int ret; -+ int quad_en = CR_QUAD_EN_SPAN << 8; -+ -+ write_enable(nor); -+ -+ ret = write_sr_cr(nor, quad_en); -+ if (ret < 0) { -+ dev_err(nor->dev, -+ "error while writing configuration register\n"); -+ return -EINVAL; -+ } -+ -+ /* read back and check it */ -+ ret = read_cr(nor); -+ if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) { -+ dev_err(nor->dev, "Spansion Quad bit not set\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int micron_quad_enable(struct spi_nor *nor) -+{ -+ int ret; -+ u8 val; -+ -+ ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &val, 1); -+ if (ret < 0) { -+ dev_err(nor->dev, "error %d reading EVCR\n", ret); -+ return ret; -+ } -+ -+ write_enable(nor); -+ -+ /* set EVCR, enable quad I/O */ -+ nor->cmd_buf[0] = val & ~EVCR_QUAD_EN_MICRON; -+ ret = nor->write_reg(nor, SPINOR_OP_WD_EVCR, nor->cmd_buf, 1); -+ if (ret < 0) { -+ dev_err(nor->dev, "error while writing EVCR register\n"); -+ return ret; -+ } -+ -+ ret = spi_nor_wait_till_ready(nor); -+ if (ret) -+ return ret; -+ -+ /* read EVCR and check it */ -+ ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &val, 1); -+ if (ret < 0) { -+ dev_err(nor->dev, "error %d reading EVCR\n", ret); -+ return ret; -+ } -+ if (val & EVCR_QUAD_EN_MICRON) { -+ dev_err(nor->dev, "Micron EVCR Quad bit not clear\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info) -+{ -+ int status; -+ -+ switch (JEDEC_MFR(info)) { -+ case SNOR_MFR_MACRONIX: -+ status = macronix_quad_enable(nor); -+ if (status) { -+ dev_err(nor->dev, "Macronix quad-read not enabled\n"); -+ return -EINVAL; -+ } -+ return status; -+ case SNOR_MFR_MICRON: -+ status = micron_quad_enable(nor); -+ if (status) { -+ dev_err(nor->dev, "Micron quad-read not enabled\n"); -+ return -EINVAL; -+ } -+ return status; -+ default: -+ status = spansion_quad_enable(nor); -+ if (status) { -+ dev_err(nor->dev, "Spansion quad-read not enabled\n"); -+ return -EINVAL; -+ } -+ return status; -+ } -+} -+ -+static int spi_nor_check(struct spi_nor *nor) -+{ -+ if (!nor->dev || !nor->read || !nor->write || -+ !nor->read_reg || !nor->write_reg || !nor->erase) { -+ pr_err("spi-nor: please fill all the necessary fields!\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) -+{ -+ const struct flash_info *info = NULL; -+ struct device *dev = nor->dev; -+ struct mtd_info *mtd = &nor->mtd; -+ struct device_node *np = nor->flash_node; -+ int ret; -+ int i; -+ -+ ret = spi_nor_check(nor); -+ if (ret) -+ return ret; -+ -+ if (name) -+ info = spi_nor_match_id(name); -+ /* Try to auto-detect if chip name wasn't specified or not found */ -+ if (!info) -+ info = spi_nor_read_id(nor); -+ if (IS_ERR_OR_NULL(info)) -+ return -ENOENT; -+ -+ /* -+ * If caller has specified name of flash model that can normally be -+ * detected using JEDEC, let's verify it. -+ */ -+ if (name && info->id_len) { -+ const struct flash_info *jinfo; -+ -+ jinfo = spi_nor_read_id(nor); -+ if (IS_ERR(jinfo)) { -+ return PTR_ERR(jinfo); -+ } else if (jinfo != info) { -+ /* -+ * JEDEC knows better, so overwrite platform ID. We -+ * can't trust partitions any longer, but we'll let -+ * mtd apply them anyway, since some partitions may be -+ * marked read-only, and we don't want to lose that -+ * information, even if it's not 100% accurate. -+ */ -+ dev_warn(dev, "found %s, expected %s\n", -+ jinfo->name, info->name); -+ info = jinfo; -+ } -+ } -+ -+#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ /* keep the flash_info pointer for use with call to set_4byte() */ -+ nor->priv1 = info; -+#endif -+ -+ mutex_init(&nor->lock); -+ -+ /* -+ * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up -+ * with the software protection bits set -+ */ -+ -+ if (JEDEC_MFR(info) == SNOR_MFR_ATMEL || -+ JEDEC_MFR(info) == SNOR_MFR_INTEL || -+ JEDEC_MFR(info) == SNOR_MFR_SST) { -+ write_enable(nor); -+ write_sr(nor, 0); -+ } -+ -+ if (!mtd->name) -+ mtd->name = dev_name(dev); -+ mtd->priv = nor; -+ mtd->type = MTD_NORFLASH; -+ mtd->writesize = 1; -+ mtd->flags = MTD_CAP_NORFLASH; -+ mtd->size = info->sector_size * info->n_sectors; -+ mtd->_erase = spi_nor_erase; -+ mtd->_read = spi_nor_read; -+ -+ /* NOR protection support for STmicro/Micron chips and similar */ -+ if (JEDEC_MFR(info) == SNOR_MFR_MICRON) { -+ nor->flash_lock = stm_lock; -+ nor->flash_unlock = stm_unlock; -+ nor->flash_is_locked = stm_is_locked; -+ } -+ -+ if (nor->flash_lock && nor->flash_unlock && nor->flash_is_locked) { -+ mtd->_lock = spi_nor_lock; -+ mtd->_unlock = spi_nor_unlock; -+ mtd->_is_locked = spi_nor_is_locked; -+ } -+ -+ /* sst nor chips use AAI word program */ -+ if (info->flags & SST_WRITE) -+ mtd->_write = sst_write; -+ else -+ mtd->_write = spi_nor_write; -+ -+ if (info->flags & USE_FSR) -+ nor->flags |= SNOR_F_USE_FSR; -+ -+#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS -+ /* prefer "small sector" erase if possible */ -+ if (info->flags & SECT_4K) { -+ nor->erase_opcode = SPINOR_OP_BE_4K; -+ mtd->erasesize = 4096; -+ } else if (info->flags & SECT_4K_PMC) { -+ nor->erase_opcode = SPINOR_OP_BE_4K_PMC; -+ mtd->erasesize = 4096; -+ } else -+#endif -+ { -+ nor->erase_opcode = SPINOR_OP_SE; -+ mtd->erasesize = info->sector_size; -+ } -+ -+ if (info->flags & SPI_NOR_NO_ERASE) -+ mtd->flags |= MTD_NO_ERASE; -+ -+ mtd->dev.parent = dev; -+ nor->page_size = info->page_size; -+ mtd->writebufsize = nor->page_size; -+ -+ if (np) { -+ /* If we were instantiated by DT, use it */ -+ if (of_property_read_bool(np, "m25p,fast-read")) -+ nor->flash_read = SPI_NOR_FAST; -+ else -+ nor->flash_read = SPI_NOR_NORMAL; -+ } else { -+ /* If we weren't instantiated by DT, default to fast-read */ -+ nor->flash_read = SPI_NOR_FAST; -+ } -+ -+ /* Some devices cannot do fast-read, no matter what DT tells us */ -+ if (info->flags & SPI_NOR_NO_FR) -+ nor->flash_read = SPI_NOR_NORMAL; -+ -+ /* Quad/Dual-read mode takes precedence over fast/normal */ -+ if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) { -+ ret = set_quad_mode(nor, info); -+ if (ret) { -+ dev_err(dev, "quad mode not supported\n"); -+ return ret; -+ } -+ nor->flash_read = SPI_NOR_QUAD; -+ } else if (mode == SPI_NOR_DUAL && info->flags & SPI_NOR_DUAL_READ) { -+ nor->flash_read = SPI_NOR_DUAL; -+ } -+ -+ /* Default commands */ -+ switch (nor->flash_read) { -+ case SPI_NOR_QUAD: -+ nor->read_opcode = SPINOR_OP_READ_1_1_4; -+ break; -+ case SPI_NOR_DUAL: -+ nor->read_opcode = SPINOR_OP_READ_1_1_2; -+ break; -+ case SPI_NOR_FAST: -+ nor->read_opcode = SPINOR_OP_READ_FAST; -+ break; -+ case SPI_NOR_NORMAL: -+ nor->read_opcode = SPINOR_OP_READ; -+ break; -+ default: -+ dev_err(dev, "No Read opcode defined\n"); -+ return -EINVAL; -+ } -+ -+ nor->program_opcode = SPINOR_OP_PP; -+ -+ if (info->addr_width) -+ nor->addr_width = info->addr_width; -+ else { -+#ifndef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ if (mtd->size > 0x1000000) { -+ /* enable 4-byte addressing if the device exceeds 16MiB */ -+ nor->addr_width = 4; -+ if (JEDEC_MFR(info) == CFI_MFR_AMD) { -+ /* Dedicated 4-byte command set */ -+ switch (nor->flash_read) { -+ case SPI_NOR_QUAD: -+ nor->read_opcode = SPINOR_OP_READ4_1_1_4; -+ break; -+ case SPI_NOR_DUAL: -+ nor->read_opcode = SPINOR_OP_READ4_1_1_2; -+ break; -+ case SPI_NOR_FAST: -+ nor->read_opcode = SPINOR_OP_READ4_FAST; -+ break; -+ case SPI_NOR_NORMAL: -+ nor->read_opcode = SPINOR_OP_READ4; -+ break; -+ } -+ nor->program_opcode = SPINOR_OP_PP_4B; -+ /* No small sector erase for 4-byte command set */ -+ nor->erase_opcode = SPINOR_OP_SE_4B; -+ mtd->erasesize = info->sector_size; -+ } else -+ set_4byte(nor, info, 1); -+ } else -+#endif /* !CONFIG_M25PXX_STAY_IN_3BYTE_MODE */ -+ nor->addr_width = 3; -+ } -+ -+ nor->read_dummy = spi_nor_read_dummy_cycles(nor); -+ -+ dev_info(dev, "%s (%lld Kbytes)\n", info->name, -+ (long long)mtd->size >> 10); -+ -+ dev_dbg(dev, -+ "mtd .name = %s, .size = 0x%llx (%lldMiB), " -+ ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n", -+ mtd->name, (long long)mtd->size, (long long)(mtd->size >> 20), -+ mtd->erasesize, mtd->erasesize / 1024, mtd->numeraseregions); -+ -+ if (mtd->numeraseregions) -+ for (i = 0; i < mtd->numeraseregions; i++) -+ dev_dbg(dev, -+ "mtd.eraseregions[%d] = { .offset = 0x%llx, " -+ ".erasesize = 0x%.8x (%uKiB), " -+ ".numblocks = %d }\n", -+ i, (long long)mtd->eraseregions[i].offset, -+ mtd->eraseregions[i].erasesize, -+ mtd->eraseregions[i].erasesize / 1024, -+ mtd->eraseregions[i].numblocks); -+ return 0; -+} -+EXPORT_SYMBOL_GPL(spi_nor_scan); -+ -+static const struct flash_info *spi_nor_match_id(const char *name) -+{ -+ const struct flash_info *id = spi_nor_ids; -+ -+ while (id->name) { -+ if (!strcmp(name, id->name)) -+ return id; -+ id++; -+ } -+ return NULL; -+} -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("framework for SPI NOR"); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig ---- a/drivers/net/ethernet/broadcom/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/Kconfig 2017-11-09 17:53:43.698295000 +0800 -@@ -190,4 +190,8 @@ config BNXT_SRIOV - Virtualization support in the NetXtreme-C/E products. This - allows for virtual function acceleration in virtual environments. - -+source "drivers/net/ethernet/broadcom/gmac/et/Kconfig" -+source "drivers/net/ethernet/broadcom/gmac/hnd/Kconfig" -+source "drivers/net/ethernet/broadcom/mdio/Kconfig" -+ - endif # NET_VENDOR_BROADCOM -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/Makefile b/drivers/net/ethernet/broadcom/Makefile ---- a/drivers/net/ethernet/broadcom/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/Makefile 2017-11-09 17:53:43.699295000 +0800 -@@ -11,5 +11,8 @@ obj-$(CONFIG_BNX2X) += bnx2x/ - obj-$(CONFIG_SB1250_MAC) += sb1250-mac.o - obj-$(CONFIG_TIGON3) += tg3.o - obj-$(CONFIG_BGMAC) += bgmac.o -+obj-$(CONFIG_MDIO_XGS_IPROC) += mdio/ -+obj-$(CONFIG_GMAC_XGS_IPROC) += gmac/et/ -+obj-$(CONFIG_GMAC_XGS_IPROC) += gmac/hnd/ - obj-$(CONFIG_SYSTEMPORT) += bcmsysport.o - obj-$(CONFIG_BNXT) += bnxt/ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/et/Kconfig b/drivers/net/ethernet/broadcom/gmac/et/Kconfig ---- a/drivers/net/ethernet/broadcom/gmac/et/Kconfig 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/et/Kconfig 2017-11-09 17:53:43.878296000 +0800 -@@ -0,0 +1,26 @@ -+# -+# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+# -+# 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 GMAC_XGS_IPROC -+ tristate "BRCM XGS iProc GMAC support " -+ select HND -+ select ET -+ select ET_ALL_PASSIVE_ON -+ depends on ARCH_XGS_IPROC -+ default n -+ help -+ Add GMAC support -+ -+ If unsure, say N. -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/et/Makefile b/drivers/net/ethernet/broadcom/gmac/et/Makefile ---- a/drivers/net/ethernet/broadcom/gmac/et/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/et/Makefile 2017-11-09 17:53:43.879292000 +0800 -@@ -0,0 +1,67 @@ -+# -+# Makefile for the Broadcom et driver -+# -+# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+# -+# 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. -+# -+ETSRCDIR := ../src/et -+ -+et-objs := $(ETSRCDIR)/sys/et_linux.o $(ETSRCDIR)/sys/etc.o -+ -+## from linux dir ########## -+export SRCBASE_et := $(src)/$(ETSRCDIR)/sys/../../ -+KBUILD_CFLAGS += -I$(SRCBASE_et)/include -DBCMDRIVER -Dlinux -+KBUILD_AFLAGS += -I$(SRCBASE_et)/include -+################################# -+obj-$(CONFIG_ET) := et.o -+ -+et-objs += $(ETSRCDIR)/sys/etcgmac.o -+EXTRA_CFLAGS += -DDMA -Wno-error -+EXTRA_CFLAGS += -DGMAC_RATE_LIMITING -DBCMDMA32 -DBCMDBG_ERR -+ -+ifeq ($(CONFIG_BCM_IPROC_GMAC_SG),y) -+EXTRA_CFLAGS += -DBCMDMASGLISTOSL -+endif -+ -+ifeq ($(CONFIG_ET_ALL_PASSIVE_ON),y) -+EXTRA_CFLAGS += -DGMAC_ALL_PASSIVE -+else -+ifeq ($(CONFIG_ET_ALL_PASSIVE_RUNTIME),y) -+EXTRA_CFLAGS += -DGMAC_ALL_PASSIVE -+endif -+endif -+ -+ifeq ($(CONFIG_ET_NAPI_POLL),y) -+EXTRA_CFLAGS += -DGMAC_NAPI_POLL -+else -+ifeq ($(CONFIG_ET_NAPI2_POLL),y) -+EXTRA_CFLAGS += -DGMAC_NAPI2_POLL -+endif -+endif -+ -+EXTRA_CFLAGS += -I$(src)/$(ETSRCDIR)/sys -+ -+ifneq ($(KERNELRELEASE),) -+# kbuild part of makefile -+else -+# Normal makefile -+KERNELDIR := ../../kernel/linux -+all: -+ $(MAKE) -C $(KERNELDIR) M=`pwd` -+ -+clean: -+ $(MAKE) -C $(KERNELDIR) M=`pwd` clean -+endif -+ -+clean-files += $(ETSRCDIR)/sys/*.o $(ETSRCDIR)/sys/.*.o.cmd -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/hnd/Kconfig b/drivers/net/ethernet/broadcom/gmac/hnd/Kconfig ---- a/drivers/net/ethernet/broadcom/gmac/hnd/Kconfig 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/hnd/Kconfig 2017-11-09 17:53:43.880305000 +0800 -@@ -0,0 +1,100 @@ -+# -+# Broadcom Home Networking Division (HND) driver configuration -+# -+# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+# -+# 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. -+# -+ -+menu "Broadcom HND network devices" -+# Kenlo depends on PCI -+config HND -+ bool "Broadcom HND network device support" -+ depends on GMAC_XGS_IPROC -+config ET -+ tristate "10/100 Ethernet support" -+ depends on HND -+choice -+ prompt "ET ALL PASSIVE mode" -+ depends on ET -+ optional -+config ET_ALL_PASSIVE_ON -+ bool "ET ALL PASSIVE on" -+config ET_ALL_PASSIVE_RUNTIME -+ bool "ET ALL PASSIVE with runtime setting" -+endchoice -+config ET_NAPI2_POLL -+ bool "BCM GMAC NAPI2_POLL" -+ default n -+ depends on !ET_ALL_PASSIVE_ON && !ET_ALL_PASSIVE_RUNTIME -+config BCM_IPROC_GMAC_ACP -+ tristate "BCM GMAC_ACP support" -+ depends on HND -+ default n -+ help -+ Add GMAC_ACP support to improve performance without -+ cache flushing/invalidate. The uboot's bootargs must -+ include "mem=240M" to limit whole Kernel memory inside -+ ACP region which is 256MB from 0x80000000; since kernel -+ starts from 0x81000000, total mem is 240MB only -+ If unsure, say N. -+config BCM_IPROC_GMAC_PREFETCH -+ tristate "BCM GMAC prefetching support" -+ depends on HND -+ default n -+ help -+ If unsure, say N. -+config BCM_IPROC_GMAC_TXONCPU1 -+ tristate "BCM GMAC TX-ON-CPU1 support" -+ depends on HND && SMP && (ET_ALL_PASSIVE_ON || ET_ALL_PASSIVE_RUNTIME) -+ default n -+ help -+ Run "Passive Mode" Tx workthread on CPU1 for -+ multi-cores utilizing; -+ If unsure, say N. -+config BCM_IPROC_GMAC_LOCK_OPT -+ tristate "BCM GMAC LOCK OPTIMIZATION support" -+ depends on HND -+ default n -+ help -+ Minimize locks during Tx/Rx tasks; -+ it is tested under "Passive Mode" (workthread) only. -+ If unsure, say N. -+config BCM_IPROC_GMAC_RWREG_OPT -+ tristate "BCM GMAC R/W_REG OPTIMIZATION support" -+ depends on HND -+ default n -+ help -+ Remove unnecessary "DSB" intructions of R/W_REG Macro. -+ If unsure, say N. -+config BCM_IPROC_GMAC_SG -+ bool "BCM GMAC Scatter Gather support" -+ default n -+ depends on HND -+config IPROC_SDK_MGT_PORT_HANDOFF -+ bool "GMAC SDK Management port handoff" -+ default y -+ depends on HND -+config IPROC_2STAGE_RX -+ bool "GMAC 2 stage packet RX" -+ default n -+ depends on HND -+config SERDES_ASYMMETRIC_MODE -+ bool "GMAC SDK Serdes Asymmetric Mode" -+ default n -+ depends on HND && (MACH_KT2 || MACH_HX4) -+config JUMBO_FRAME -+ bool "GMAC Jumbo Frame Support" -+ default n -+ depends on HND -+endmenu -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/hnd/Makefile b/drivers/net/ethernet/broadcom/gmac/hnd/Makefile ---- a/drivers/net/ethernet/broadcom/gmac/hnd/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/hnd/Makefile 2017-11-09 17:53:43.881317000 +0800 -@@ -0,0 +1,121 @@ -+# -+# Makefile for Broadcom Home Networking Division (HND) shared driver code -+# -+# $Copyright Open Broadcom Corporation$ -+# -+# $Id: Makefile,v 1.5 2008-05-02 22:49:54 pmoutarl Exp $ -+# -+ -+SHARED := ../src/shared -+ -+## from linux dir ########## -+export SRCBASE_hnd := $(src)/$(SHARED)/../ -+KBUILD_CFLAGS += -I$(SRCBASE_hnd)/include -DBCMDRIVER -Dlinux -+KBUILD_AFLAGS += -I$(SRCBASE_hnd)/include -+################################# -+obj-$(CONFIG_HND) := hnd.o -+ -+EXTRA_CFLAGS += -DBCMDBG_ERR -DBCMDMA32 -+ -+ifeq ($(CONFIG_BCM_IPROC_GMAC_SG),y) -+EXTRA_CFLAGS += -DBCMDMASGLISTOSL -+endif -+ -+HND_OBJS += $(src)/$(SHARED)/nvramstubs.o -+hnd-objs += $(SHARED)/nvramstubs.o -+ -+HND_OBJS += $(src)/$(SHARED)/hnddma.o -+hnd-objs += $(SHARED)/hnddma.o -+ -+HND_OBJS += $(src)/$(SHARED)/bcmutils.o -+hnd-objs += $(SHARED)/bcmutils.o -+ -+HND_OBJS += $(src)/$(SHARED)/linux_osl.o -+hnd-objs += $(SHARED)/linux_osl.o -+ -+HND_OBJS += $(src)/$(SHARED)/siutils.o -+hnd-objs += $(SHARED)/siutils.o -+ -+HND_OBJS += $(src)/$(SHARED)/aiutils.o -+hnd-objs += $(SHARED)/aiutils.o -+ -+ -+ifeq ($(CONFIG_MACH_HX4),y) -+HND_OBJS += $(src)/$(SHARED)/bcmiproc_serdes.o -+hnd-objs += $(SHARED)/bcmiproc_serdes.o -+ -+HND_OBJS += $(src)/$(SHARED)/bcmiproc_phy5461s.o -+hnd-objs += $(SHARED)/bcmiproc_phy5461s.o -+ -+HND_OBJS += $(src)/$(SHARED)/hx4_erom.o -+hnd-objs += $(SHARED)/hx4_erom.o -+endif -+ -+ifeq ($(CONFIG_MACH_SB2),y) -+HND_OBJS += $(src)/$(SHARED)/bcmiproc_serdes.o -+hnd-objs += $(SHARED)/bcmiproc_serdes.o -+ -+HND_OBJS += $(src)/$(SHARED)/bcmiproc_phy5461s.o -+hnd-objs += $(SHARED)/bcmiproc_phy5461s.o -+ -+HND_OBJS += $(src)/$(SHARED)/sb2_erom.o -+hnd-objs += $(SHARED)/sb2_erom.o -+endif -+ -+ifeq ($(CONFIG_MACH_KT2),y) -+HND_OBJS += $(src)/$(SHARED)/bcmiproc_serdes.o -+hnd-objs += $(SHARED)/bcmiproc_serdes.o -+ -+HND_OBJS += $(src)/$(SHARED)/bcmiproc_phy5461s.o -+hnd-objs += $(SHARED)/bcmiproc_phy5461s.o -+ -+HND_OBJS += $(src)/$(SHARED)/kt2_erom.o -+hnd-objs += $(SHARED)/kt2_erom.o -+endif -+ -+ifeq ($(CONFIG_MACH_HR2),y) -+HND_OBJS += $(src)/$(SHARED)/bcmiproc_phy5221.o -+hnd-objs += $(SHARED)/bcmiproc_phy5221.o -+ -+HND_OBJS += $(src)/$(SHARED)/hr2_erom.o -+hnd-objs += $(SHARED)/hr2_erom.o -+endif -+ -+ifeq ($(CONFIG_MACH_GH),y) -+HND_OBJS += $(src)/$(SHARED)/bcmiproc_phy5481.o -+hnd-objs += $(SHARED)/bcmiproc_phy5481.o -+ -+HND_OBJS += $(src)/$(SHARED)/gh_erom.o -+hnd-objs += $(SHARED)/gh_erom.o -+endif -+ -+ifeq ($(CONFIG_MACH_HR3),y) -+ifeq ($(CONFIG_MACH_WH2),y) -+HND_OBJS += $(src)/$(SHARED)/sgmiiplus2_serdes.o -+hnd-objs += $(SHARED)/sgmiiplus2_serdes.o -+ -+HND_OBJS += $(src)/$(SHARED)/bcmiproc_egphy28.o -+hnd-objs += $(SHARED)/bcmiproc_egphy28.o -+else -+HND_OBJS += $(src)/$(SHARED)/bcmiproc_phy5481.o -+hnd-objs += $(SHARED)/bcmiproc_phy5481.o -+endif -+HND_OBJS += $(src)/$(SHARED)/hr3_erom.o -+hnd-objs += $(SHARED)/hr3_erom.o -+endif -+ -+ifeq ($(CONFIG_MACH_GH2),y) -+HND_OBJS += $(src)/$(SHARED)/sgmiiplus2_serdes.o -+hnd-objs += $(SHARED)/sgmiiplus2_serdes.o -+ -+HND_OBJS += $(src)/$(SHARED)/phy542xx.o -+hnd-objs += $(SHARED)/phy542xx.o -+ -+HND_OBJS += $(src)/$(SHARED)/gh2_erom.o -+hnd-objs += $(SHARED)/gh2_erom.o -+endif -+ -+#$(src)/shared_ksyms.c: $(src)/shared_ksyms.sh $(HND_OBJS) -+# sh -e $< $(HND_OBJS) > $@ -+ -+hnd-objs += shared_ksyms.o -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/hnd/shared_ksyms.c b/drivers/net/ethernet/broadcom/gmac/hnd/shared_ksyms.c ---- a/drivers/net/ethernet/broadcom/gmac/hnd/shared_ksyms.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/hnd/shared_ksyms.c 2017-11-09 17:53:43.882312000 +0800 -@@ -0,0 +1,43 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ */ -+#include -+#include -+#include -+#include -+EXPORT_SYMBOL(bcm_atoi); -+EXPORT_SYMBOL(bcm_binit); -+EXPORT_SYMBOL(bcm_bprintf); -+EXPORT_SYMBOL(bcm_ether_atoe); -+EXPORT_SYMBOL(bcm_ether_ntoa); -+EXPORT_SYMBOL(bcm_strtoul); -+EXPORT_SYMBOL(getgpiopin); -+EXPORT_SYMBOL(getintvar); -+EXPORT_SYMBOL(getvar); -+EXPORT_SYMBOL(nvram_env_gmac_name); -+EXPORT_SYMBOL(nvram_get); -+EXPORT_SYMBOL(osl_delay); -+EXPORT_SYMBOL(osl_detach); -+EXPORT_SYMBOL(osl_dma_map); -+EXPORT_SYMBOL(osl_malloc); -+EXPORT_SYMBOL(osl_malloced); -+EXPORT_SYMBOL(osl_mfree); -+EXPORT_SYMBOL(osl_pkt_frmnative); -+EXPORT_SYMBOL(osl_pkt_tonative); -+EXPORT_SYMBOL(osl_pktfree); -+EXPORT_SYMBOL(pktsetprio); -+EXPORT_SYMBOL(si_attach); -+EXPORT_SYMBOL(si_setcore); -+EXPORT_SYMBOL(si_core_cflags); -+EXPORT_SYMBOL(si_core_disable); -+EXPORT_SYMBOL(si_core_reset); -+EXPORT_SYMBOL(si_core_sflags); -+EXPORT_SYMBOL(si_coreid); -+EXPORT_SYMBOL(si_coreidx); -+EXPORT_SYMBOL(si_corerev); -+EXPORT_SYMBOL(si_coreunit); -+EXPORT_SYMBOL(si_detach); -+EXPORT_SYMBOL(si_gpioout); -+EXPORT_SYMBOL(si_gpioouten); -+EXPORT_SYMBOL(si_iscoreup); -+EXPORT_SYMBOL(si_setcoreidx); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/hnd/shared_ksyms.sh b/drivers/net/ethernet/broadcom/gmac/hnd/shared_ksyms.sh ---- a/drivers/net/ethernet/broadcom/gmac/hnd/shared_ksyms.sh 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/hnd/shared_ksyms.sh 2017-11-09 17:53:43.883313000 +0800 -@@ -0,0 +1,30 @@ -+#!/bin/sh -+# -+# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+# -+# 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. -+# -+# $Id: shared_ksyms.sh,v 1.2 2008-12-05 20:10:41 $ -+# -+ -+cat < -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) -+#include -+#endif -+EOF -+ -+for file in $* ; do -+ ${NM} $file | sed -ne 's/[0-9A-Fa-f]* [BDRT] \([^ ]*\)/extern void \1; EXPORT_SYMBOL(\1);/p' -+done -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_cfg.h b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_cfg.h ---- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_cfg.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_cfg.h 2017-11-09 17:53:43.886293000 +0800 -@@ -0,0 +1,12 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * BCM ET driver config options -+ * -+ * $Id: et_cfg.h,v 1.1.4.1 2010-08-05 19:17:00 jaredh Exp $ -+ */ -+ -+#if defined(__NetBSD__) || defined(__FreeBSD__) -+#include -+#include -+#endif /* defined(__NetBSD__) || defined(__FreeBSD__) */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_dbg.h b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_dbg.h ---- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_dbg.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_dbg.h 2017-11-09 17:53:43.896296000 +0800 -@@ -0,0 +1,47 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * Minimal debug/trace/assert driver definitions for -+ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet -+ * Device Driver. -+ * -+ * $Id: et_dbg.h 286404 2011-09-27 19:29:08Z nisar $ -+ */ -+ -+#ifndef _et_dbg_ -+#define _et_dbg_ -+ -+#ifdef BCMDBG -+struct ether_header; -+extern void etc_prhdr(char *msg, struct ether_header *eh, uint len, int unit); -+extern void etc_prhex(char *msg, uchar *buf, uint nbytes, int unit); -+/* -+ * et_msg_level is a bitvector: -+ * 0 errors -+ * 1 function-level tracing -+ * 2 one-line frame tx/rx summary -+ * 3 complex frame tx/rx in hex -+ */ -+#define ET_ERROR(args) if (!(et_msg_level & 1)) ; else printf args -+#define ET_TRACE(args) if (!(et_msg_level & 2)) ; else printf args -+#define ET_PRHDR(msg, eh, len, unit) if (!(et_msg_level & 4)) ; else etc_prhdr(msg, eh, len, unit) -+#define ET_PRPKT(msg, buf, len, unit) if (!(et_msg_level & 8)) ; else etc_prhex(msg, buf, len, unit) -+#else /* BCMDBG */ -+#define ET_ERROR(args) -+#define ET_TRACE(args) -+#define ET_PRHDR(msg, eh, len, unit) -+#define ET_PRPKT(msg, buf, len, unit) -+#endif /* BCMDBG */ -+ -+extern uint32 et_msg_level; -+ -+#define ET_LOG(fmt, a1, a2) -+ -+/* include port-specific tunables */ -+#if defined(linux) -+#include -+#else -+#error -+#endif -+ -+#endif /* _et_dbg_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_export.h b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_export.h ---- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_export.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_export.h 2017-11-09 17:53:43.897291000 +0800 -@@ -0,0 +1,28 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * Required functions exported by the port-specific (os-dependent) driver -+ * to common (os-independent) driver code. -+ * -+ * $Id: et_export.h 322208 2012-03-20 01:53:23Z rnuti $ -+ */ -+ -+#ifndef _et_export_h_ -+#define _et_export_h_ -+ -+/* misc callbacks */ -+extern void et_init(void *et, uint options); -+extern void et_reset(void *et); -+extern void et_link_up(void *et); -+extern void et_link_down(void *et); -+extern bool et_is_link_up(void *et); -+extern int et_up(void *et); -+extern int et_down(void *et, int reset); -+extern void et_dump(void *et, struct bcmstrbuf *b); -+extern void et_intrson(void *et); -+ -+/* for BCM5222 dual-phy shared mdio contortion */ -+extern void *et_phyfind(void *et, uint coreunit); -+extern uint16 et_phyrd(void *et, uint phyaddr, uint reg); -+extern void et_phywr(void *et, uint reg, uint phyaddr, uint16 val); -+#endif /* _et_export_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_linux.c b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_linux.c ---- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_linux.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_linux.c 2017-11-09 17:53:43.899291000 +0800 -@@ -0,0 +1,2603 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * Linux device driver for -+ * Broadcom BCM47XX 10/100/1000 Mbps Ethernet Controller -+ * -+ * $Id: et_linux.c 327582 2012-04-14 05:02:37Z kenlo $ -+ */ -+ -+#include -+#define __UNDEF_NO_VERSION__ -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef SIOCETHTOOL -+#include -+#endif /* SIOCETHTOOL */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_OF -+#include -+#include -+#include -+#include -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* to be cleaned and fixed */ -+/* to be cleaned Makefile */ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH -+#include -+ -+#define SKB_PREFETCH_LEN (128) -+/* 30 rxhdr + 34 mac & ip */ -+#define SKB_DATA_PREFETCH_LEN (96) -+#endif /* CONFIG_BCM_IPROC_GMAC_PREFETCH */ -+ -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 4, 5) -+#error Linux version must be newer than 2.4.5 -+#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(2, 4, 5) */ -+ -+#define MIN_PACKET_SIZE 70 /* for gmac2 (&GMAC3?) */ -+/* if packet is less than 64 bytes, it will not tx */ -+/* if packet is less than 66 bytes, CRC is not generated) */ -+/* this length is after brm tag is stripped off */ -+ -+#define DATAHIWAT 1000 /* data msg txq hiwat mark */ -+ -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36) -+#define HAVE_NET_DEVICE_OPS 1 -+#define HAVE_NETDEV_PRIV 1 -+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36) */ -+ -+#ifndef HAVE_NETDEV_PRIV -+#define HAVE_NETDEV_PRIV -+#define netdev_priv(dev) ((dev)->priv) -+#define ET_INFO(dev) (et_info_t *)((dev)->priv) -+#else -+#define ET_INFO(dev) netdev_priv(dev) -+#endif /* HAVE_NETDEV_PRIV */ -+ -+#ifdef GMAC_ALL_PASSIVE -+#define ET_LIMIT_TXQ -+#define ET_ALL_PASSIVE_ENAB(et) (!(et)->all_dispatch_mode) -+ -+/* passive mode: 1: enable, 0: disable */ -+static int passivemode = 0; -+module_param(passivemode, int, 0); -+#else /* GMAC_ALL_PASSIVE */ -+#define ET_ALL_PASSIVE_ENAB(et) 0 -+#endif /* GMAC_ALL_PASSIVE */ -+ -+#ifdef ET_LIMIT_TXQ -+#define ET_TXQ_THRESH 0 -+static int et_txq_thresh = ET_TXQ_THRESH; -+module_param(et_txq_thresh, int, 0); -+#endif /* ET_LIMIT_TXQ */ -+ -+ -+/* In 2.6.20 kernels work functions get passed a pointer to the -+ * struct work, so things will continue to work as long as the work -+ * structure is the first component of the task structure. -+ */ -+typedef struct et_task { -+ struct work_struct work; -+ void *context; -+} et_task_t; -+ -+typedef struct et_info { -+ etc_info_t *etc; /* pointer to common os-independent data */ -+ struct net_device *dev; /* backpoint to device */ -+ struct pci_dev *pdev; /* backpoint to pci_dev */ -+ void *osh; /* pointer to os handle */ -+ struct semaphore sem; /* use semaphore to allow sleep */ -+ spinlock_t lock; /* per-device perimeter lock */ -+ spinlock_t txq_lock; /* lock for txq protection */ -+ spinlock_t tx_lock; /* lock for tx protection */ -+ spinlock_t isr_lock; /* lock for irq reentrancy protection */ -+ struct sk_buff_head txq[NUMTXQ];/* send queue */ -+ void *regsva; /* opaque chip registers virtual address */ -+ struct timer_list timer; /* one second watchdog timer */ -+ bool set; /* indicate the timer is set or not */ -+ struct net_device_stats stats; /* stat counter reporting structure */ -+ int events; /* bit channel between isr and dpc */ -+ struct et_info *next; /* pointer to next et_info_t in chain */ -+#ifdef GMAC_NAPI2_POLL -+ struct napi_struct napi_poll; -+#endif /* GMAC_NAPI2_POLL */ -+#ifndef GMAC_NAPI_POLL -+ struct tasklet_struct tasklet;/* dpc tasklet */ -+#endif /* GMAC_NAPI_POLL */ -+#ifdef GMAC_ALL_PASSIVE -+ et_task_t dpc_task; /* work queue for rx dpc */ -+ et_task_t txq_task; /* work queue for tx frames */ -+ bool all_dispatch_mode; /* dispatch mode: tasklets or passive */ -+#endif /* GMAC_ALL_PASSIVE */ -+ bool resched; /* dpc was rescheduled */ -+#ifdef CONFIG_IPROC_2STAGE_RX -+ bool rxinisr; -+#endif /* CONFIG_IPROC_2STAGE_RX */ -+} et_info_t; -+ -+#define ET_LOCK(et) \ -+do { \ -+ if (ET_ALL_PASSIVE_ENAB(et)) \ -+ down(&(et)->sem); \ -+ else \ -+ spin_lock_bh(&(et)->lock); \ -+} while (0) -+ -+#define ET_UNLOCK(et) \ -+do { \ -+ if (ET_ALL_PASSIVE_ENAB(et)) \ -+ up(&(et)->sem); \ -+ else \ -+ spin_unlock_bh(&(et)->lock); \ -+} while (0) -+ -+#define ET_TXQ_LOCK(et) spin_lock_bh(&(et)->txq_lock) -+#define ET_TXQ_UNLOCK(et) spin_unlock_bh(&(et)->txq_lock) -+#define ET_TX_LOCK(et) spin_lock_bh(&(et)->tx_lock) -+#define ET_TX_UNLOCK(et) spin_unlock_bh(&(et)->tx_lock) -+#define INT_LOCK(et, flags) spin_lock_irqsave(&(et)->isr_lock, flags) -+#define INT_UNLOCK(et, flags) spin_unlock_irqrestore(&(et)->isr_lock, flags) -+ -+#ifdef GMAC_RATE_LIMITING -+static int et_rx_rate_limit = 0; -+extern void etc_check_rate_limiting(etc_info_t *etc, void *pch); -+#endif /* GMAC_RATE_LIMITING */ -+ -+#if defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) -+extern int gmac_has_mdio_access(void); -+#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) */ -+#endif /* defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) */ -+ -+static int et_found = 0; -+static et_info_t *et_list = NULL; -+ -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 37) -+#define init_MUTEX(x) sema_init(x,1) -+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 37) */ -+ -+/* linux 2.4 doesn't have in_atomic */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) -+#define in_atomic() 0 -+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 37) */ -+ -+/* Prototypes called by etc.c */ -+#ifdef CONFIG_BCM_GRO_ENABLE -+void et_flush(void *dev_id); -+#endif /* CONFIG_BCM_GRO_ENABLE */ -+void et_init(et_info_t *et, uint options); -+void et_reset(et_info_t *et); -+void et_up(et_info_t *et); -+void et_down(et_info_t *et, int reset); -+void et_intrson(et_info_t *et); -+void et_dump(et_info_t *et, struct bcmstrbuf *b); -+void et_link_up(et_info_t *et); -+void et_link_down(et_info_t *et); -+bool et_is_link_up(et_info_t *et); -+ -+/* Local prototypes */ -+static void et_free(et_info_t *et); -+static int et_open(struct net_device *dev); -+static int et_close(struct net_device *dev); -+static int et_start(struct sk_buff *skb, struct net_device *dev); -+static int et_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); -+static struct net_device_stats *et_get_stats(struct net_device *dev); -+static int et_set_mac_address(struct net_device *dev, void *addr); -+static void et_set_multicast_list(struct net_device *dev); -+ -+static void et_sendnext(et_info_t *et); -+static void _et_watchdog(struct net_device *data); -+static void et_watchdog(ulong data); -+#ifdef GMAC_ALL_PASSIVE -+static void et_watchdog_task(et_task_t *task); -+static void et_dpc_work(struct et_task *task); -+static int et_schedule_task(et_info_t *et, void (*fn)(struct et_task *task), void *context); -+static void et_txq_work(struct et_task *task); -+#endif /* GMAC_ALL_PASSIVE */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) -+static irqreturn_t et_isr(int irq, void *dev_id); -+#else -+static irqreturn_t et_isr(int irq, void *dev_id, struct pt_regs *ptregs); -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) */ -+static int et_rxevent(osl_t *osh, et_info_t *et, struct chops *chops, void *ch, int quota); -+#ifdef GMAC_NAPI2_POLL -+static int et_poll(struct napi_struct *napi, int budget); -+#elif defined(GMAC_NAPI_POLL) -+static int et_poll(struct net_device *dev, int *budget); -+#else /* ! GMAC_NAPI_POLL */ -+static void et_dpc(ulong data); -+#endif /* GMAC_NAPI_POLL */ -+static void et_error(et_info_t *et, struct sk_buff *skb, void *rxh); -+static void et_sendup(et_info_t *et, struct sk_buff *skb); -+static void et_dumpet(et_info_t *et, struct bcmstrbuf *b); -+static int et_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd); -+static int et_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd); -+static void et_get_driver_info(struct net_device *dev, struct ethtool_drvinfo *info); -+ -+static int eth_mac_proc_create(struct net_device *dev); -+#ifndef CONFIG_OF -+static void eth_mac_proc_remove(void); -+#else -+static void eth_mac_proc_remove(struct net_device *dev); -+#endif -+static int iproc_gmac_drv_probe(struct platform_device*); -+static int __exit iproc_gmac_drv_remove(struct platform_device*); -+#ifdef CONFIG_PM -+static int iproc_gmac_drv_suspend(struct platform_device *pdev, pm_message_t state); -+static int iproc_gmac_drv_resume(struct platform_device *pdev); -+#else /* CONFIG_PM */ -+#define iproc_gmac_drv_suspend NULL -+#define iproc_gmac_drv_resume NULL -+#endif /* CONFIG_PM */ -+ -+#define DISABLE_FA_BYPASS 0 -+#define ENABLE_FA_BYPASS 1 -+ -+#if 0 -+static unsigned int gBypass = DISABLE_FA_BYPASS; -+#endif -+ -+#ifdef BCMDBG -+static uint32 msglevel = 0xdeadbeef; -+module_param(msglevel, uint, 0644); -+#endif /* BCMDBG */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) -+static const struct ethtool_ops et_ethtool_ops = { -+ .get_settings = et_get_settings, -+ .set_settings = et_set_settings, -+ .get_drvinfo = et_get_driver_info, -+}; -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) */ -+ -+#ifdef HAVE_NET_DEVICE_OPS -+static const struct net_device_ops et_netdev_ops = { -+ .ndo_open = et_open, -+ .ndo_stop = et_close, -+ .ndo_start_xmit = et_start, -+ .ndo_get_stats = et_get_stats, -+ .ndo_set_mac_address = et_set_mac_address, -+ .ndo_set_rx_mode = et_set_multicast_list, -+ .ndo_do_ioctl = et_ioctl, -+}; -+#endif /*HAVE_NET_DEVICE_OPS*/ -+ -+#ifndef CONFIG_OF -+static struct platform_driver gmac_pdrv[IPROC_MAX_GMAC_CORES] = { -+ { -+ .probe = iproc_gmac_drv_probe, -+ .remove = __exit_p(iproc_gmac_drv_remove), -+ .suspend = iproc_gmac_drv_suspend, -+ .resume = iproc_gmac_drv_resume, -+ .driver = { -+ .name = "bcm-gmac0", -+ }, -+ }, -+ { -+ .probe = iproc_gmac_drv_probe, -+ .remove = __exit_p(iproc_gmac_drv_remove), -+ .suspend = iproc_gmac_drv_suspend, -+ .resume = iproc_gmac_drv_resume, -+ .driver = { -+ .name = "bcm-gmac1", -+ }, -+ }, -+ { -+ .probe = iproc_gmac_drv_probe, -+ .remove = __exit_p(iproc_gmac_drv_remove), -+ .suspend = iproc_gmac_drv_suspend, -+ .resume = iproc_gmac_drv_resume, -+ .driver = { -+ .name = "bcm-gmac2", -+ }, -+ }, -+ { -+ .probe = iproc_gmac_drv_probe, -+ .remove = __exit_p(iproc_gmac_drv_remove), -+ .suspend = iproc_gmac_drv_suspend, -+ .resume = iproc_gmac_drv_resume, -+ .driver = { -+ .name = "bcm-gmac3", -+ }, -+ } -+}; -+#endif -+ -+/*int gmac_pdev_loaded[IPROC_NUM_GMACS];*/ -+ -+/***************************************************************************** -+*****************************************************************************/ -+static bool __maybe_unused -+et_ctf_pipeline_loopback(et_info_t *et) -+{ -+ if (et->etc->unit == 3) { -+ return true; -+ } else { -+ return false; -+ } -+} -+ -+#ifdef BCMDMASGLISTOSL -+static int -+et_bcmtag_len(et_info_t *et) -+{ -+ return (et_ctf_pipeline_loopback(et)) ? 8 : 0; -+} -+#endif /* BCMDMASGLISTOSL */ -+ -+static void -+et_free(et_info_t *et) -+{ -+ et_info_t **prev; -+ osl_t *osh; -+ -+ ET_TRACE(("et: et_free\n")); -+ -+ if (et == NULL) { -+ return; -+ } -+ -+ if (et->dev && et->dev->irq) { -+ free_irq(et->dev->irq, et); -+ } -+ -+#ifdef GMAC_NAPI2_POLL -+ napi_disable(&et->napi_poll); -+ netif_napi_del(&et->napi_poll); -+#endif /* GMAC_NAPI2_POLL */ -+ -+ if (et->dev) { -+ unregister_netdev(et->dev); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) -+ free_netdev(et->dev); -+#else -+ MFREE(et->osh, et->dev, sizeof(struct net_device)); -+#endif -+ et->dev = NULL; -+ } -+ -+ /* free common resources */ -+ if (et->etc) { -+ etc_detach(et->etc); -+ et->etc = NULL; -+ } -+ -+ /* unregister_netdev() calls get_stats() which may read chip registers -+ * so we cannot unmap the chip registers until after calling unregister_netdev() . -+ */ -+ if (et->regsva) { -+ iounmap((void *)et->regsva); -+ et->regsva = NULL; -+ } -+ -+ /* remove us from the global linked list */ -+ for (prev = &et_list; *prev; prev = &(*prev)->next) { -+ if (*prev == et) { -+ *prev = et->next; -+ break; -+ } -+ } -+ -+ osh = et->osh; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) -+ free_netdev(et->dev); -+ et->dev = NULL; -+#else -+ MFREE(et->osh, et, sizeof(et_info_t)); -+#endif -+ -+ if (MALLOCED(osh)) { -+ ET_ERROR(("Memory leak of bytes %d\n", MALLOCED(osh))); -+ } -+ ASSERT(MALLOCED(osh) == 0); -+ -+ osl_detach(osh); -+} -+ -+static int -+et_open(struct net_device *dev) -+{ -+ et_info_t *et = ET_INFO(dev); -+ -+ ET_TRACE(("et%d: et_open\n", et->etc->unit)); -+ -+ et->etc->promisc = (dev->flags & IFF_PROMISC)? TRUE: FALSE; -+ et->etc->allmulti = (dev->flags & IFF_ALLMULTI)? TRUE: et->etc->promisc; -+#ifdef GMAC_RATE_LIMITING -+ et->etc->rl_enabled = et_rx_rate_limit; -+#endif /* GMAC_RATE_LIMITING */ -+ -+ ET_LOCK(et); -+ et_up(et); -+ ET_UNLOCK(et); -+ -+ OLD_MOD_INC_USE_COUNT; -+ -+ return (0); -+} -+ -+static int -+et_close(struct net_device *dev) -+{ -+ et_info_t *et = ET_INFO(dev); -+ -+ ET_TRACE(("et%d: et_close\n", et->etc->unit)); -+ -+ et->etc->promisc = FALSE; -+ et->etc->allmulti = FALSE; -+ -+ ET_LOCK(et); -+ et_down(et, 1); -+ ET_UNLOCK(et); -+ -+ OLD_MOD_DEC_USE_COUNT; -+ -+ return (0); -+} -+ -+#if defined(BCMDMASGLISTOSL) -+/* -+ * Driver level checksum offload. This is being done so that we can advertise -+ * checksum offload support to Linux. -+ */ -+static void BCMFASTPATH_HOST -+et_cso(et_info_t *et, struct sk_buff *skb) -+{ -+ struct ethervlan_header *evh; -+ uint8 *th = skb_transport_header(skb); -+ uint16 thoff, eth_type, *check; -+ uint8 prot; -+ -+ ASSERT(!PKTISCTF(et->osh, skb)); -+ -+ evh = (struct ethervlan_header *)PKTDATA(et->osh, skb); -+ eth_type = ((evh->vlan_type == HTON16(ETHER_TYPE_8021Q)) ? -+ evh->ether_type : evh->vlan_type); -+ -+ /* tcp/udp checksum calculation */ -+ thoff = (th - skb->data); -+ if (eth_type == HTON16(ETHER_TYPE_IP)) { -+ struct iphdr *ih = ip_hdr(skb); -+ prot = ih->protocol; -+ ASSERT((prot == IP_PROT_TCP) || (prot == IP_PROT_UDP)); -+ check = (uint16 *)(th + ((prot == IP_PROT_UDP) ? -+ offsetof(struct udphdr, check) : offsetof(struct tcphdr, check))); -+ *check = 0; -+ skb->csum = skb_checksum(skb, thoff, skb->len - thoff, 0); -+ *check = csum_tcpudp_magic(ih->saddr, ih->daddr, -+ skb->len - thoff, prot, skb->csum); -+ } else if (eth_type == HTON16(ETHER_TYPE_IPV6)) { -+ struct ipv6hdr *ih = ipv6_hdr(skb); -+ prot = IPV6_PROT(ih); -+ ASSERT((prot == IP_PROT_TCP) || (prot == IP_PROT_UDP)); -+ check = (uint16 *)(th + ((prot == IP_PROT_UDP) ? -+ offsetof(struct udphdr, check) : offsetof(struct tcphdr, check))); -+ *check = 0; -+ skb->csum = skb_checksum(skb, thoff, skb->len - thoff, 0); -+ *check = csum_ipv6_magic(&ih->saddr, &ih->daddr, -+ skb->len - thoff, prot, skb->csum); -+ } else { -+ return; -+ } -+ -+ if ((*check == 0) && (prot == IP_PROT_UDP)) { -+ *check = CSUM_MANGLED_0; -+ } -+} -+#endif /* defined(BCMDMASGLISTOSL) */ -+ -+/* -+ * Yeah, queueing the packets on a tx queue instead of throwing them -+ * directly into the descriptor ring in the case of dma is kinda lame, -+ * but this results in a unified transmit path for both dma and pio -+ * and localizes/simplifies the netif_*_queue semantics, too. -+ */ -+static int BCMFASTPATH -+et_start(struct sk_buff *skb, struct net_device *dev) -+{ -+ et_info_t *et = ET_INFO(dev); -+ uint32 q = 0; -+#ifdef BCMDMASGLISTOSL -+ bool sw_cksum = true; -+ struct iphdr *iph = NULL; -+#endif /* BCMDMASGLISTOSL */ -+#ifdef ET_LIMIT_TXQ -+ int qlen; -+#endif /* ET_LIMIT_TXQ */ -+ -+#ifdef BCMDMASGLISTOSL -+ if (!PKTSUMNEEDED(skb)) { -+ sw_cksum = false; -+ } -+ -+ /* can only update checksum once. */ -+ /* if checksum is updated later, don't do it here */ -+ iph = (struct iphdr *)skb->network_header; -+ if (((skb->len + et_bcmtag_len(et)) < MIN_PACKET_SIZE) && -+ ((iph->protocol == IPPROTO_TCP) || (iph->protocol == IPPROTO_UDP))) { -+ sw_cksum = false; -+ } -+ -+ if (sw_cksum) { -+ et_cso(et, skb); -+ } -+#endif /* BCMDMASGLISTOSL */ -+ -+ if (skb_is_nonlinear(skb)) { -+ et->etc->txsgpkt++; -+ } -+ -+ if (skb->len > et->etc->txmaxlen) { -+ et->etc->txmaxlen = skb->len; -+ } -+ -+ ET_TRACE(("et%d: et_start: len %d\n", et->etc->unit, skb->len)); -+ ET_LOG("et%d: et_start: len %d", et->etc->unit, skb->len); -+ -+ et->etc->txfrm++; -+#ifdef ET_LIMIT_TXQ -+#ifndef CONFIG_BCM_IPROC_GMAC_LOCK_OPT -+ ET_TXQ_LOCK(et); -+#endif /* CONFIG_BCM_IPROC_GMAC_LOCK_OPT */ -+ qlen = skb_queue_len(&et->txq[q]); -+#ifndef CONFIG_BCM_IPROC_GMAC_LOCK_OPT -+ ET_TXQ_UNLOCK(et); -+#endif /* CONFIG_BCM_IPROC_GMAC_LOCK_OPT */ -+ if (qlen > et->etc->txqlen) { -+ et->etc->txqlen = qlen; -+ } -+ -+ if (et_txq_thresh && (qlen >= et_txq_thresh)) { -+ //PKTCFREE(et->osh, skb, TRUE); -+ //return 0; -+ et->etc->txfrmdropped++; -+ /* schedule work */ -+#ifdef GMAC_ALL_PASSIVE -+ if (ET_ALL_PASSIVE_ENAB(et)) { -+#ifdef CONFIG_BCM_IPROC_GMAC_TXONCPU1 -+ schedule_work_on(1, &et->txq_task.work); -+#else -+ schedule_work(&et->txq_task.work); -+#endif -+ } -+#endif /* GMAC_ALL_PASSIVE */ -+ return NETDEV_TX_BUSY; -+ } -+#endif /* ET_LIMIT_TXQ */ -+ -+ /* put it on the tx queue and call sendnext */ -+ ET_TXQ_LOCK(et); -+ __skb_queue_tail(&et->txq[q], skb); -+ et->etc->txq_state |= (1 << q); -+ ET_TXQ_UNLOCK(et); -+ -+ if (!ET_ALL_PASSIVE_ENAB(et)) { -+ ET_LOCK(et); -+ et_sendnext(et); -+ ET_UNLOCK(et); -+ } -+#ifdef GMAC_ALL_PASSIVE -+ else { -+#ifdef CONFIG_BCM_IPROC_GMAC_TXONCPU1 -+ schedule_work_on(1, &et->txq_task.work); -+#else -+ schedule_work(&et->txq_task.work); -+#endif /* CONFIG_BCM_IPROC_GMAC_TXONCPU1 */ -+ } -+#endif /* GMAC_ALL_PASSIVE */ -+ -+ ET_LOG("et%d: et_start ret\n", et->etc->unit, 0); -+ -+ return (0); -+} -+ -+static void BCMFASTPATH -+et_sendnext(et_info_t *et) -+{ -+ etc_info_t *etc; -+ struct sk_buff *skb; -+ void *p, *n; -+ uint32 priq = TX_Q0; -+#ifdef DMA -+ uint32 txavail; -+#endif -+#ifdef DBG_PRINT_PKT -+ int tagoff, idx; -+#endif /* DBG_PRINT_PKT */ -+ -+ etc = et->etc; -+ -+ ET_TRACE(("et%d: et_sendnext\n", etc->unit)); -+ ET_LOG("et%d: et_sendnext", etc->unit, 0); -+ -+ /* dequeue packets from highest priority queue and send */ -+ while (1) { -+ ET_TXQ_LOCK(et); -+ -+ if (etc->txq_state == 0) -+ break; -+ -+ priq = etc_priq(etc->txq_state); -+ -+ ET_TRACE(("et%d: txq_state %x priq %d txavail %d\n", -+ etc->unit, etc->txq_state, priq, -+ *(uint *)etc->txavail[priq])); -+ -+ if ((skb = skb_peek(&et->txq[priq])) == NULL) { -+ etc->txq_state &= ~(1 << priq); -+ ET_TXQ_UNLOCK(et); -+ continue; -+ } -+ -+#ifdef DMA -+ /* current highest priority dma queue is full */ -+ txavail = *(uint *)(etc->txavail[priq]); -+ if ((PKTISCHAINED(skb) && (txavail < PKTCCNT(skb))) || (txavail == 0)) -+#else /* DMA */ -+ if (etc->pioactive != NULL) -+#endif /* DMA */ -+ { -+ etc->txdmafull++; -+ break; -+ } -+ -+ skb = __skb_dequeue(&et->txq[priq]); -+ -+ ET_TXQ_UNLOCK(et); -+ ET_PRHDR("tx", (struct ether_header *)skb->data, skb->len, etc->unit); -+ ET_PRPKT("txpkt", skb->data, skb->len, etc->unit); -+ -+#ifdef DBG_PRINT_PKT -+ tagoff = 16; -+ printf("et%d: txpkt len(0x%x) tag:0x%02x%02x%02x%02x\n", etc->unit, skb->len, -+ skb->data[tagoff], skb->data[tagoff+1], skb->data[tagoff+2], skb->data[tagoff+3]); -+ -+ printk("et%d: %s len(0x%x) txpkt:", etc->unit, __FUNCTION__, skb->len); -+ for (idx = 0; idx < skb->len; idx++) { -+ if ((idx % 16) == 0) { -+ printk("\n"); -+ } -+ printk("%02x ", skb->data[idx]); -+ } -+ printk("\n"); -+#endif /* DBG_PRINT_PKT */ -+ -+ /* convert the packet. */ -+ p = PKTFRMNATIVE(etc->osh, skb); -+ ASSERT(p != NULL); -+ -+ ET_TRACE(("%s: sdu %p chained %d chain sz %d next %p\n", -+ __FUNCTION__, p, PKTISCHAINED(p), PKTCCNT(p), PKTCLINK(p))); -+ -+ ET_TX_LOCK(et); -+ FOREACH_CHAINED_PKT(p, n) { -+ /* replicate vlan header contents from curr frame */ -+ if (n != NULL) { -+ uint8 *n_evh; -+ n_evh = PKTPUSH(et->osh, n, VLAN_TAG_LEN); -+ *(struct ethervlan_header *)n_evh = -+ *(struct ethervlan_header *)PKTDATA(et->osh, p); -+ } -+ (*etc->chops->tx)(etc->ch, p); -+#ifdef CONFIG_BCM_IPROC_GMAC_LOCK_OPT -+ ET_LOCK(et); -+#endif /* CONFIG_BCM_IPROC_GMAC_LOCK_OPT */ -+ etc->txframe++; -+ etc->txbyte += PKTLEN(et->osh, p); -+#ifdef CONFIG_BCM_IPROC_GMAC_LOCK_OPT -+ ET_UNLOCK(et); -+#endif /* CONFIG_BCM_IPROC_GMAC_LOCK_OPT */ -+ } -+ ET_TX_UNLOCK(et); -+ } -+ -+ /* no flow control when qos is enabled */ -+ if (!et->etc->qos) { -+ /* stop the queue whenever txq fills */ -+ if ((skb_queue_len(&et->txq[TX_Q0]) > DATAHIWAT) && !netif_queue_stopped(et->dev)) { -+ et->etc->txqstop++; -+ netif_stop_queue(et->dev); -+ } else if (netif_queue_stopped(et->dev) && -+ (skb_queue_len(&et->txq[TX_Q0]) < (DATAHIWAT/2))) { -+ netif_wake_queue(et->dev); -+ } -+ } else { -+ /* drop the frame if corresponding prec txq len exceeds hiwat -+ * when qos is enabled. -+ */ -+ if ((priq != TC_NONE) && (skb_queue_len(&et->txq[priq]) > DATAHIWAT)) { -+ skb = __skb_dequeue(&et->txq[priq]); -+ PKTCFREE(et->osh, skb, TRUE); -+ ET_ERROR(("et%d: %s: txqlen %d\n", et->etc->unit, -+ __FUNCTION__, skb_queue_len(&et->txq[priq]))); -+ } -+ } -+ -+ ET_TXQ_UNLOCK(et); -+} -+ -+#ifdef CONFIG_BCM_GRO_ENABLE -+#ifdef CONFIG_ET_MODULE -+extern int et_flushptr_ready; -+extern void (*et_flushptr)(void *dev_id); -+#endif /* CONFIG_ET_MODULE */ -+ -+void -+et_flush(void *dev_id) -+{ -+ et_info_t *et; -+ struct chops *chops; -+ void *ch; -+ osl_t *osh; -+ -+ et = (et_info_t *)dev_id; -+ chops = et->etc->chops; -+ ch = et->etc->ch; -+ osh = et->etc->osh; -+ -+ /* guard against shared interrupts */ -+ if (!et->etc->up) { -+ ET_TRACE(("et%d: et_isr: not up\n", et->etc->unit)); -+ return; -+ } -+ if (!et->napi_poll.gro_list) { -+ return; -+ } -+ -+ /* disable interrupts */ -+ (*chops->intrsoff)(ch); -+ -+ et->resched = TRUE; -+ -+ napi_gro_flush(&et->napi_poll); -+ -+ /* enable interrupts now */ -+ (*chops->intrson)(ch); -+} -+#endif /* CONFIG_BCM_GRO_ENABLE */ -+ -+void -+et_init(et_info_t *et, uint options) -+{ -+ ET_TRACE(("et%d: et_init\n", et->etc->unit)); -+ ET_LOG("et%d: et_init", et->etc->unit, 0); -+ -+ etc_init(et->etc, options); -+ -+#ifdef CONFIG_BCM_GRO_ENABLE -+#ifdef CONFIG_ET_MODULE -+ et_flushptr = &et_flush; -+ et_flushptr_ready = 1; -+#endif /* CONFIG_ET_MODULE */ -+#endif /* CONFIG_BCM_GRO_ENABLE */ -+ -+#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_HR2) || defined(CONFIG_MACH_KT2) -+ netif_carrier_off(et->dev); -+#endif /* defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_HR2) || defined(CONFIG_MACH_KT2) */ -+} -+ -+ -+void -+et_reset(et_info_t *et) -+{ -+ ET_TRACE(("et%d: et_reset\n", et->etc->unit)); -+ -+ etc_reset(et->etc); -+ -+ /* zap any pending dpc interrupt bits */ -+ et->events = 0; -+ -+ /* dpc will not be rescheduled */ -+ et->resched = 0; -+} -+ -+void -+et_up(et_info_t *et) -+{ -+ etc_info_t *etc; -+ -+ etc = et->etc; -+ -+ if (etc->up) { -+ return; -+ } -+ -+ ET_TRACE(("et%d: et_up\n", etc->unit)); -+ -+ etc_up(etc); -+ -+#if defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) -+ if (et->set) { -+ /* This will happen if running watchdog to monitor mdio bus */ -+ /* and port not up */ -+ del_timer(&et->timer); -+ et->set = FALSE; -+ } -+#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) */ -+#endif /* defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) */ -+ -+ /* schedule one second watchdog timer */ -+ et->timer.expires = jiffies + HZ; -+ add_timer(&et->timer); -+ et->set=TRUE; -+ -+ netif_start_queue(et->dev); -+} -+ -+void -+et_down(et_info_t *et, int reset) -+{ -+ etc_info_t *etc; -+ struct sk_buff *skb; -+ int32 i; -+ bool stoptmr = TRUE; -+ -+ etc = et->etc; -+ -+ ET_TRACE(("et%d: et_down\n", etc->unit)); -+ -+ netif_down(et->dev); -+ netif_stop_queue(et->dev); -+ -+#ifdef CONFIG_IPROC_SDK_MGT_PORT_HANDOFF -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) -+ if (gmac_has_mdio_access()) { -+ /* we have mdio bus don't stop timer so we can continue to monitor */ -+ stoptmr = FALSE; -+ } -+#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) */ -+#endif /* CONFIG_IPROC_SDK_MGT_PORT_HANDOFF */ -+ -+ if ( stoptmr ) { -+ /* stop watchdog timer */ -+ del_timer(&et->timer); -+ et->set = FALSE; -+ } -+ -+#ifdef GMAC_RATE_LIMITING -+ /* stop ratelimiting timer */ -+ del_timer(&et->etc->rl_timer); -+ et->etc->rl_set = FALSE; -+#endif /* GMAC_RATE_LIMITING */ -+ -+ etc_down(etc, reset); -+ -+ /* flush the txq(s) */ -+ for (i = 0; i < NUMTXQ; i++) { -+ while ((skb = skb_dequeue(&et->txq[i]))) { -+ PKTFREE(etc->osh, skb, TRUE); -+ } -+ } -+ -+#if !defined(GMAC_NAPI_POLL) && !defined(GMAC_NAPI2_POLL) -+ /* kill dpc */ -+ ET_UNLOCK(et); -+ tasklet_kill(&et->tasklet); -+ ET_LOCK(et); -+#endif /* GMAC_NAPI_POLL */ -+} -+ -+/* -+ * These are interrupt on/off entry points. Disable interrupts -+ * during interrupt state transition. -+ */ -+void -+et_intrson(et_info_t *et) -+{ -+ unsigned long flags; -+ INT_LOCK(et, flags); -+ (*et->etc->chops->intrson)(et->etc->ch); -+ INT_UNLOCK(et, flags); -+} -+ -+static void -+_et_watchdog(struct net_device *dev) -+{ -+ et_info_t *et; -+ -+ et = ET_INFO(dev); -+ -+ ET_LOCK(et); -+ -+ etc_watchdog(et->etc); -+ -+ if (et->set) { -+ /* reschedule one second watchdog timer */ -+ et->timer.expires = jiffies + HZ; -+ add_timer(&et->timer); -+ } -+#if defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) -+ /* this in case port when up then down before we released mdio */ -+ else if (gmac_has_mdio_access()) { -+ /* interface not up but we have mdio bus */ -+ /* reschedule one second watchdog timer */ -+ et->timer.expires = jiffies + HZ; -+ add_timer(&et->timer); -+ et->set = TRUE; -+ } -+#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) */ -+#endif /* defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) */ -+ -+ ET_UNLOCK(et); -+} -+ -+#ifdef GMAC_ALL_PASSIVE -+/* Schedule a completion handler to run at safe time */ -+static int -+et_schedule_task(et_info_t *et, void (*fn)(struct et_task *task), void *context) -+{ -+ et_task_t *task; -+ -+ ET_TRACE(("et%d: et_schedule_task\n", et->etc->unit)); -+ -+ if (!(task = MALLOC(et->osh, sizeof(et_task_t)))) { -+ ET_ERROR(("et%d: et_schedule_task: out of memory, malloced %d bytes\n", -+ et->etc->unit, MALLOCED(et->osh))); -+ return -ENOMEM; -+ } -+ -+ MY_INIT_WORK(&task->work, (work_func_t)fn); -+ task->context = context; -+ -+ if (!schedule_work(&task->work)) { -+ ET_ERROR(("et%d: schedule_work() failed\n", et->etc->unit)); -+ MFREE(et->osh, task, sizeof(et_task_t)); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+static void BCMFASTPATH -+et_txq_work(struct et_task *task) -+{ -+ et_info_t *et = (et_info_t *)task->context; -+ -+#ifndef CONFIG_BCM_IPROC_GMAC_LOCK_OPT -+ ET_LOCK(et); -+#endif /* !CONFIG_BCM_IPROC_GMAC_LOCK_OPT */ -+ -+ et_sendnext(et); -+ -+#ifndef CONFIG_BCM_IPROC_GMAC_LOCK_OPT -+ ET_UNLOCK(et); -+#endif /* !CONFIG_BCM_IPROC_GMAC_LOCK_OPT */ -+ return; -+} -+ -+static void -+et_watchdog_task(et_task_t *task) -+{ -+ et_info_t *et = ET_INFO((struct net_device *)task->context); -+ -+ _et_watchdog((struct net_device *)task->context); -+ MFREE(et->osh, task, sizeof(et_task_t)); -+} -+#endif /* GMAC_ALL_PASSIVE */ -+ -+static void -+et_watchdog(ulong data) -+{ -+ struct net_device *dev = (struct net_device *)data; -+ -+#ifdef GMAC_ALL_PASSIVE -+ et_info_t *et = ET_INFO(dev); -+#endif /* GMAC_ALL_PASSIVE */ -+ -+ if (!ET_ALL_PASSIVE_ENAB(et)) { -+ _et_watchdog(dev); -+ } -+#ifdef GMAC_ALL_PASSIVE -+ else { -+ et_schedule_task(et, et_watchdog_task, dev); -+ } -+#endif /* GMAC_ALL_PASSIVE */ -+} -+ -+/* Rate limiting */ -+#ifdef GMAC_RATE_LIMITING -+static void et_release_congestion(ulong data) -+{ -+ struct net_device *dev = (struct net_device *)data; -+ et_info_t *et = ET_INFO(dev); -+ -+ if (!et) { -+ return; -+ } -+ -+ if (et->etc->rl_stopping_broadcasts) { -+ et->etc->rl_stopping_broadcasts = 0; -+ /* Clear the number of dropped broadcast packets */ -+ et->etc->rl_dropped_bc_packets = 0; -+ } -+ if (et->etc->rl_stopping_all_packets) { -+ et->etc->rl_stopping_all_packets = 0; -+ et->etc->rl_dropped_all_packets = 0; -+ } -+} -+#endif /* GMAC_RATE_LIMITING */ -+ -+ -+ -+static int -+et_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) -+{ -+ et_info_t *et = ET_INFO(dev); -+ -+ ecmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | -+ SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | -+ SUPPORTED_Autoneg | SUPPORTED_TP); -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) -+ ecmd->supported |= SUPPORTED_1000baseT_Full | SUPPORTED_Pause; -+#endif -+#if defined(CONFIG_MACH_HR2) -+ ecmd->supported |= SUPPORTED_Pause; -+#endif -+ -+ ecmd->advertising = ADVERTISED_TP; -+ ecmd->advertising |= (et->etc->advertise & ADV_10HALF) ? -+ ADVERTISED_10baseT_Half : 0; -+ ecmd->advertising |= (et->etc->advertise & ADV_10FULL) ? -+ ADVERTISED_10baseT_Full : 0; -+ ecmd->advertising |= (et->etc->advertise & ADV_100HALF) ? -+ ADVERTISED_100baseT_Half : 0; -+ ecmd->advertising |= (et->etc->advertise & ADV_100FULL) ? -+ ADVERTISED_100baseT_Full : 0; -+ ecmd->advertising |= (et->etc->advertise2 & ADV_1000FULL) ? -+ ADVERTISED_1000baseT_Full : 0; -+ ecmd->advertising |= (et->etc->advertise2 & ADV_1000HALF) ? -+ ADVERTISED_1000baseT_Half : 0; -+ ecmd->advertising |= (et->etc->forcespeed == ET_AUTO) ? -+ ADVERTISED_Autoneg : 0; -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_HR2)) -+ ecmd->advertising |= ADVERTISED_Pause; -+#endif -+ if (et->etc->linkstate) { -+ ecmd->speed = (et->etc->speed == 1000) ? SPEED_1000 : -+ ((et->etc->speed == 100) ? SPEED_100 : SPEED_10); -+ ecmd->duplex = (et->etc->duplex == 1) ? DUPLEX_FULL : DUPLEX_HALF; -+ } else { -+ ecmd->speed = 0; -+ ecmd->duplex = 0; -+ } -+ ecmd->port = PORT_TP; -+ ecmd->phy_address = et->etc->phyaddr; -+ ecmd->transceiver = XCVR_INTERNAL; -+ ecmd->autoneg = (et->etc->forcespeed == ET_AUTO) ? AUTONEG_ENABLE : AUTONEG_DISABLE; -+ ecmd->maxtxpkt = 0; -+ ecmd->maxrxpkt = 0; -+ -+ return 0; -+} -+ -+static int -+et_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) -+{ -+ int speed[2]; -+ -+ et_info_t *et = ET_INFO(dev); -+ -+ if (!capable(CAP_NET_ADMIN)) -+ return (-EPERM); -+ -+ if (ecmd->autoneg == AUTONEG_ENABLE) { -+ speed[0] = ET_AUTO; -+ speed[1] = ecmd->advertising; -+ } else if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_HALF) { -+ speed[0] = ET_10HALF; -+ } else if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_FULL) { -+ speed[0] = ET_10FULL; -+ } else if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_HALF) { -+ speed[0] = ET_100HALF; -+ } else if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_FULL) { -+ speed[0] = ET_100FULL; -+ } else if (ecmd->speed == SPEED_1000 && ecmd->duplex == DUPLEX_FULL) { -+ speed[0] = ET_1000FULL; -+ } else { -+ return (-EINVAL); -+ } -+ -+ return etc_ioctl(et->etc, ETCSPEED, speed); -+} -+ -+static void -+et_get_driver_info(struct net_device *dev, struct ethtool_drvinfo *info) -+{ -+ et_info_t *et = ET_INFO(dev); -+ bzero(info, sizeof(struct ethtool_drvinfo)); -+ info->cmd = ETHTOOL_GDRVINFO; -+ sprintf(info->driver, "et%d", et->etc->unit); -+ strncpy(info->version, EPI_VERSION_STR, sizeof(info->version)); -+ info->version[(sizeof(info->version))-1] = '\0'; -+} -+ -+#ifdef SIOCETHTOOL -+static int -+et_ethtool(et_info_t *et, struct ethtool_cmd *ecmd) -+{ -+ int ret = 0; -+ -+ ET_LOCK(et); -+ -+ switch (ecmd->cmd) { -+ case ETHTOOL_GSET: -+ ret = et_get_settings(et->dev, ecmd); -+ break; -+ case ETHTOOL_SSET: -+ ret = et_set_settings(et->dev, ecmd); -+ break; -+ case ETHTOOL_GDRVINFO: -+ et_get_driver_info(et->dev, (struct ethtool_drvinfo *)ecmd); -+ break; -+ default: -+ ret = -EINVAL; -+ break; -+ } -+ -+ ET_UNLOCK(et); -+ -+ return (ret); -+} -+#endif /* SIOCETHTOOL */ -+ -+static int -+et_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -+{ -+ et_info_t *et; -+ int error; -+ char *buf; -+ int size, ethtoolcmd; -+ bool get = 0, set; -+ et_var_t *var = NULL; -+ void *buffer = NULL; -+ -+ et = ET_INFO(dev); -+ -+ ET_TRACE(("et%d: et_ioctl: cmd 0x%x\n", et->etc->unit, cmd)); -+ -+ switch (cmd) { -+#ifdef SIOCETHTOOL -+ case SIOCETHTOOL: -+ if (copy_from_user(ðtoolcmd, ifr->ifr_data, sizeof(uint32))) -+ return (-EFAULT); -+ -+ if (ethtoolcmd == ETHTOOL_GDRVINFO) -+ size = sizeof(struct ethtool_drvinfo); -+ else -+ size = sizeof(struct ethtool_cmd); -+ get = TRUE; set = TRUE; -+ break; -+#endif /* SIOCETHTOOL */ -+ case SIOCGETCDUMP: -+ size = IOCBUFSZ; -+ get = TRUE; set = FALSE; -+ break; -+ case SIOCGETCPHYRD: -+ case SIOCGETCPHYRD2: -+ case SIOCGETCROBORD: -+ size = sizeof(int) * 2; -+ get = TRUE; set = TRUE; -+ break; -+ case SIOCSETCSPEED: -+ case SIOCSETCPHYWR: -+ case SIOCSETCPHYWR2: -+ case SIOCSETCROBOWR: -+ size = sizeof(int) * 2; -+ get = FALSE; set = TRUE; -+ break; -+ case SIOCSETGETVAR: -+ size = sizeof(et_var_t); -+ set = TRUE; -+ break; -+ default: -+ size = sizeof(int); -+ get = FALSE; set = TRUE; -+ break; -+ } -+ -+ if ((buf = MALLOC(et->osh, size)) == NULL) { -+ ET_ERROR(("et: et_ioctl: out of memory, malloced %d bytes\n", MALLOCED(et->osh))); -+ return (-ENOMEM); -+ } -+ -+ if (set && copy_from_user(buf, ifr->ifr_data, size)) { -+ MFREE(et->osh, buf, size); -+ return (-EFAULT); -+ } -+ -+ if (cmd == SIOCSETGETVAR) { -+ var = (et_var_t *)buf; -+ if (var->buf) { -+ if (!var->set) -+ get = TRUE; -+ -+ if (!(buffer = (void *) MALLOC(et->osh, var->len))) { -+ ET_ERROR(("et: et_ioctl: out of memory, malloced %d bytes\n", -+ MALLOCED(et->osh))); -+ MFREE(et->osh, buf, size); -+ return (-ENOMEM); -+ } -+ -+ if (copy_from_user(buffer, var->buf, var->len)) { -+ MFREE(et->osh, buffer, var->len); -+ MFREE(et->osh, buf, size); -+ return (-EFAULT); -+ } -+ } -+ } -+ -+ switch (cmd) { -+#ifdef SIOCETHTOOL -+ case SIOCETHTOOL: -+ error = et_ethtool(et, (struct ethtool_cmd *)buf); -+ break; -+#endif /* SIOCETHTOOL */ -+ case SIOCSETGETVAR: -+ ET_LOCK(et); -+ error = etc_iovar(et->etc, var->cmd, var->set, buffer); -+ ET_UNLOCK(et); -+ if (!error && get) { -+ error = copy_to_user(var->buf, buffer, var->len); -+ } -+ -+ if (buffer) { -+ MFREE(et->osh, buffer, var->len); -+ } -+ break; -+ default: -+ ET_LOCK(et); -+ error = etc_ioctl(et->etc, cmd - SIOCSETCUP, buf) ? -EINVAL : 0; -+ ET_UNLOCK(et); -+ break; -+ } -+ -+ if (!error && get) { -+ error = copy_to_user(ifr->ifr_data, buf, size); -+ } -+ -+ MFREE(et->osh, buf, size); -+ -+ return (error); -+} -+ -+static struct net_device_stats * -+et_get_stats(struct net_device *dev) -+{ -+ et_info_t *et; -+ etc_info_t *etc; -+ struct net_device_stats *stats; -+ int locked = 0; -+ -+ et = ET_INFO(dev); -+ -+ ET_TRACE(("et%d: et_get_stats\n", et->etc->unit)); -+ -+ if (!in_atomic()) { -+ locked = 1; -+ ET_LOCK(et); -+ } -+ -+ etc = et->etc; -+ stats = &et->stats; -+ bzero(stats, sizeof(struct net_device_stats)); -+ -+ /* refresh stats */ -+ if (et->etc->up) { -+ (*etc->chops->statsupd)(etc->ch); -+ } -+ -+ /* SWAG */ -+ stats->rx_packets = etc->rxframe; -+ stats->tx_packets = etc->txframe; -+ stats->rx_bytes = etc->rxbyte; -+ stats->tx_bytes = etc->txbyte; -+ stats->rx_errors = etc->rxerror; -+ stats->tx_errors = etc->txerror; -+ -+ if (ET_GMAC(etc)) { -+ gmacmib_t *mib; -+ -+ mib = etc->mib; -+ stats->collisions = mib->tx_total_cols; -+ stats->rx_length_errors = (mib->rx_oversize_pkts + mib->rx_undersize); -+ stats->rx_crc_errors = mib->rx_crc_errs; -+ stats->rx_frame_errors = mib->rx_align_errs; -+ stats->rx_missed_errors = mib->rx_missed_pkts; -+ } else { -+ bcmenetmib_t *mib; -+ -+ mib = etc->mib; -+ stats->collisions = mib->tx_total_cols; -+ stats->rx_length_errors = (mib->rx_oversize_pkts + mib->rx_undersize); -+ stats->rx_crc_errors = mib->rx_crc_errs; -+ stats->rx_frame_errors = mib->rx_align_errs; -+ stats->rx_missed_errors = mib->rx_missed_pkts; -+ -+ } -+ -+ stats->rx_fifo_errors = etc->rxoflo; -+ stats->rx_over_errors = etc->rxoflo; -+ stats->tx_fifo_errors = etc->txuflo; -+ -+ if (locked) { -+ ET_UNLOCK(et); -+ } -+ -+ return (stats); -+} -+ -+static int -+et_set_mac_address(struct net_device *dev, void *addr) -+{ -+ et_info_t *et; -+ struct sockaddr *sa = (struct sockaddr *) addr; -+ -+ et = ET_INFO(dev); -+ ET_TRACE(("et%d: et_set_mac_address\n", et->etc->unit)); -+ -+ if (et->etc->up) { -+ return -EBUSY; -+ } -+ -+ bcopy(sa->sa_data, dev->dev_addr, ETHER_ADDR_LEN); -+ bcopy(dev->dev_addr, &et->etc->cur_etheraddr, ETHER_ADDR_LEN); -+ -+ return 0; -+} -+ -+static void -+et_set_multicast_list(struct net_device *dev) -+{ -+ et_info_t *et; -+ etc_info_t *etc; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) -+ struct dev_mc_list *mclist; -+#else -+ struct netdev_hw_addr *ha ; -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) */ -+ int i; -+ int locked = 0; -+ -+ et = ET_INFO(dev); -+ etc = et->etc; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) -+ mclist = NULL ; /* fend off warnings */ -+#else -+ ha = NULL ; -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) */ -+ -+ ET_TRACE(("et%d: et_set_multicast_list\n", etc->unit)); -+ -+ if (!in_atomic()) { -+ locked = 1; -+ ET_LOCK(et); -+ } -+ -+ if (etc->up) { -+ etc->promisc = (dev->flags & IFF_PROMISC)? TRUE: FALSE; -+ etc->allmulti = (dev->flags & IFF_ALLMULTI)? TRUE: etc->promisc; -+ -+ /* copy the list of multicasts into our private table */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) -+ for (i = 0, mclist = dev->mc_list; mclist && (i < dev->mc_count); -+ i++, mclist = mclist->next) { -+ if (i >= MAXMULTILIST) { -+ etc->allmulti = TRUE; -+ i = 0; -+ break; -+ } -+ etc->multicast[i] = *((struct ether_addr *)mclist->dmi_addr); -+ } -+#else /* >= 2.6.36 */ -+ i = 0; -+ netdev_for_each_mc_addr(ha, dev) { -+ i ++; -+ if (i >= MAXMULTILIST) { -+ etc->allmulti = TRUE; -+ i = 0; -+ break; -+ } -+ etc->multicast[i] = *((struct ether_addr *)ha->addr); -+ } /* for each ha */ -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) */ -+ etc->nmulticast = i; -+ -+ /* LR: partial re-init, DMA is already initialized */ -+ et_init(et, ET_INIT_INTRON); -+ } -+ -+ if (locked) { -+ ET_UNLOCK(et); -+ } -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) -+static irqreturn_t BCMFASTPATH -+et_isr(int irq, void *dev_id) -+#else -+static irqreturn_t BCMFASTPATH -+et_isr(int irq, void *dev_id, struct pt_regs *ptregs) -+#endif -+{ -+ et_info_t *et; -+ struct chops *chops; -+ void *ch; -+ uint events = 0; -+ osl_t *osh; -+ -+ et = (et_info_t *)dev_id; -+ chops = et->etc->chops; -+ ch = et->etc->ch; -+ osh = et->etc->osh; -+ -+ /* guard against shared interrupts */ -+ if (!et->etc->up) { -+ ET_TRACE(("et%d: et_isr: not up\n", et->etc->unit)); -+ goto done; -+ } -+ -+ /* get interrupt condition bits */ -+ events = (*chops->getintrevents)(ch, TRUE); -+ -+ /* not for us */ -+ if (!(events & INTR_NEW)) { -+ goto done; -+ } -+ -+ ET_TRACE(("et%d: et_isr: events 0x%x\n", et->etc->unit, events)); -+ ET_LOG("et%d: et_isr: events 0x%x", et->etc->unit, events); -+ -+#ifdef CONFIG_IPROC_2STAGE_RX -+ if (events & INTR_RX) { -+ et->rxinisr = true; -+ /* process a few RX interrupts */ -+ et_rxevent(osh, et, chops, ch, 1); -+ -+ et->rxinisr = false; -+ /* get interrupt condition bits */ -+ events = (*chops->getintrevents)(ch, TRUE); -+ et->resched = FALSE; -+ -+ /* not for us */ -+ if (!(events & INTR_NEW)) { -+ goto done; -+ } -+ } -+#endif /* CONFIG_IPROC_2STAGE_RX */ -+ -+ /* disable interrupts */ -+ (*chops->intrsoff)(ch); -+ -+ /* save intstatus bits */ -+ ASSERT(et->events == 0); -+ et->events = events; -+ -+ ASSERT(et->resched == FALSE); -+ -+#ifdef GMAC_NAPI2_POLL -+ napi_schedule(&et->napi_poll); -+#elif defined(GMAC_NAPI_POLL) -+ /* allow the device to be added to the cpu polling list if we are up */ -+ if (netif_rx_schedule_prep(et->dev)) { -+ /* tell the network core that we have packets to send up */ -+ __netif_rx_schedule(et->dev); -+ } else { -+ ET_ERROR(("et%d: et_isr: intr while in poll!\n", -+ et->etc->unit)); -+ (*chops->intrson)(ch); -+ } -+#else /* ! GMAC_NAPI_POLL && ! GMAC_NAPI2_POLL */ -+ /* schedule dpc */ -+#ifdef GMAC_ALL_PASSIVE -+ if (ET_ALL_PASSIVE_ENAB(et)) { -+ schedule_work(&et->dpc_task.work); -+ } else -+#endif /* GMAC_ALL_PASSIVE */ -+ { -+ tasklet_schedule(&et->tasklet); -+ } -+#endif /* GMAC_NAPI_POLL */ -+ -+done: -+ ET_LOG("et%d: et_isr ret", et->etc->unit, 0); -+ -+ return IRQ_RETVAL(events & INTR_NEW); -+} -+ -+static inline int -+et_rxevent(osl_t *osh, et_info_t *et, struct chops *chops, void *ch, int quota) -+{ -+ uint processed = 0; -+ void *p, *h = NULL, *t = NULL; -+ struct sk_buff *skb; -+ -+#ifdef GMAC_RATE_LIMITING -+ /* rate limiting */ -+ if (et->etc->rl_enabled) { -+ etc_check_rate_limiting(et->etc, ch); -+ } -+#endif /* GMAC_RATE_LIMITING */ -+ -+ /* read the buffers first */ -+ while ((p = (*chops->rx)(ch))) { -+ PKTSETLINK(p, NULL); -+ if (t == NULL) { -+ h = t = p; -+ } else { -+ PKTSETLINK(t, p); -+ t = p; -+ } -+ -+ /* we reached quota already */ -+ if (++processed >= quota) { -+ /* reschedule et_dpc()/et_poll() */ -+ et->resched = TRUE; -+ et->etc->rxquota++; -+ break; -+ } -+ } -+ -+ /* prefetch the headers */ -+ if (h != NULL) { -+#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH -+ prefetch_range(PKTDATA(osh, h), SKB_DATA_PREFETCH_LEN); -+#else -+ ETPREFHDRS(PKTDATA(osh, h), PREFSZ); -+#endif -+ } -+ -+ /* post more rx bufs */ -+ (*chops->rxfill)(ch); -+ -+ while ((p = h) != NULL) { -+ h = PKTLINK(h); -+ PKTSETLINK(p, NULL); -+ -+ /* prefetch the headers */ -+ if (h != NULL) { -+#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH -+ prefetch_range(PKTDATA(osh, h), SKB_DATA_PREFETCH_LEN); -+#else -+ ETPREFHDRS(PKTDATA(osh, h), PREFSZ); -+#endif -+ } -+ -+ skb = PKTTONATIVE(osh, p); -+ et->etc->unchained++; -+ et_sendup(et, skb); -+ } -+ -+ return (processed); -+} -+ -+#if defined(GMAC_NAPI2_POLL) -+static int BCMFASTPATH -+et_poll(struct napi_struct *napi, int budget) -+{ -+ int quota = budget; -+ struct net_device *dev = napi->dev; -+ et_info_t *et = ET_INFO(dev); -+ -+#elif defined(GMAC_NAPI_POLL) -+static int BCMFASTPATH -+et_poll(struct net_device *dev, int *budget) -+{ -+ int quota = min(RXBND, *budget); -+ et_info_t *et = ET_INFO(dev); -+#else /* GMAC_NAPI_POLL */ -+static void BCMFASTPATH -+et_dpc(ulong data) -+{ -+ et_info_t *et = (et_info_t *)data; -+ int quota = RXBND; -+#endif /* GMAC_NAPI_POLL */ -+ struct chops *chops; -+ void *ch; -+ osl_t *osh; -+ uint nrx = 0; -+ -+ chops = et->etc->chops; -+ ch = et->etc->ch; -+ osh = et->etc->osh; -+ -+ ET_TRACE(("et%d: et_dpc: events 0x%x\n", et->etc->unit, et->events)); -+ ET_LOG("et%d: et_dpc: events 0x%x", et->etc->unit, et->events); -+ -+#if !defined(GMAC_NAPI_POLL) && !defined(GMAC_NAPI2_POLL) -+ ET_LOCK(et); -+#endif /* ! NAPIx_POLL */ -+ -+ if (!et->etc->up) { -+ goto done; -+ } -+ -+ /* get interrupt condition bits again when dpc was rescheduled */ -+ if (et->resched) { -+ et->events = (*chops->getintrevents)(ch, FALSE); -+ et->resched = FALSE; -+ } -+ -+ if (et->events & INTR_RX) { -+ nrx = et_rxevent(osh, et, chops, ch, quota); -+ } -+ -+ if (et->events & INTR_TX) { -+ (*chops->txreclaim)(ch, FALSE); -+ } -+ -+ (*chops->rxfill)(ch); -+ -+ /* handle error conditions, if reset required leave interrupts off! */ -+ if (et->events & INTR_ERROR) { -+ if ((*chops->errors)(ch)) { -+ printk("%s error, calling et_init() for et%d\n", __FUNCTION__, et->etc->unit); -+ et_init(et, ET_INIT_INTROFF); -+ } else { -+ if (nrx < quota) { -+ nrx += et_rxevent(osh, et, chops, ch, quota); -+ } -+ } -+ } -+ -+ /* run the tx queue */ -+ if (et->etc->txq_state != 0) { -+ if (!ET_ALL_PASSIVE_ENAB(et)) { -+ et_sendnext(et); -+ } -+#ifdef GMAC_ALL_PASSIVE -+ else { -+#ifdef CONFIG_BCM_IPROC_GMAC_TXONCPU1 -+ schedule_work_on(1, &et->txq_task.work); -+#else -+ schedule_work(&et->txq_task.work); -+#endif -+ } -+#endif /* GMAC_ALL_PASSIVE */ -+ } -+ -+ /* clear this before re-enabling interrupts */ -+ et->events = 0; -+ -+ /* something may bring the driver down */ -+ if (!et->etc->up) { -+ et->resched = FALSE; -+ goto done; -+ } -+ -+#if !defined(GMAC_NAPI_POLL) && !defined(GMAC_NAPI2_POLL) -+#ifdef GMAC_ALL_PASSIVE -+ if (et->resched) { -+ if (!ET_ALL_PASSIVE_ENAB(et)) { -+ tasklet_schedule(&et->tasklet); -+ } else { -+ schedule_work(&et->dpc_task.work); -+ } -+ } else { -+ (*chops->intrson)(ch); -+ } -+#else /* GMAC_ALL_PASSIVE */ -+ if (et->resched) { /* there may be frames left, reschedule et_dpc() */ -+ tasklet_schedule(&et->tasklet); -+ } else { /* re-enable interrupts */ -+ (*chops->intrson)(ch); -+ } -+#endif /* GMAC_ALL_PASSIVE */ -+#endif /* ! NAPIx_POLL */ -+ -+done: -+#if defined(GMAC_NAPI_POLL) -+ /* update number of frames processed */ -+ *budget -= nrx; -+ dev->quota -= nrx; -+ -+ ET_TRACE(("et%d: et_poll: quota %d budget %d\n", -+ et->etc->unit, dev->quota, *budget)); -+ -+ /* we got packets but no quota */ -+ if (et->resched) { -+ return (1); -+ } -+ -+ netif_rx_complete(dev); -+ -+ /* enable interrupts now */ -+ (*chops->intrson)(ch); -+ -+ /* indicate that we are done */ -+ return (0); -+#elif defined(GMAC_NAPI2_POLL) -+ ET_TRACE(("et%d: et_poll: budget %d\n", -+ et->etc->unit, budget)); -+ -+ /* we got packets but no quota */ -+ if (et->resched) { -+ return (1); -+ } -+ -+ napi_complete(napi); -+ -+ /* enable interrupts now */ -+ (*chops->intrson)(ch); -+ -+ /* indicate that we are done */ -+ return (0); -+#else /* !defined(GMAC_NAPI_POLL) && !defined(GMAC_NAPI2_POLL) */ -+ ET_UNLOCK(et); -+ return; -+#endif -+} -+ -+#ifdef GMAC_ALL_PASSIVE -+static void BCMFASTPATH -+et_dpc_work(struct et_task *task) -+{ -+#if !defined(GMAC_NAPI_POLL) && !defined(GMAC_NAPI2_POLL) -+ et_info_t *et = (et_info_t *)task->context; -+ et_dpc((unsigned long)et); -+#else -+ BUG_ON(1); -+#endif -+ return; -+} -+#endif /* GMAC_ALL_PASSIVE */ -+ -+static void -+et_error(et_info_t *et, struct sk_buff *skb, void *rxh) -+{ -+ uchar eabuf[32]; -+ struct ether_header *eh; -+ -+ eh = (struct ether_header *)skb->data; -+ bcm_ether_ntoa((struct ether_addr *)eh->ether_shost, eabuf); -+ -+ if (RXH_OVERSIZE(et->etc, rxh)) { -+ ET_ERROR(("et%d: rx: over size packet from %s\n", et->etc->unit, eabuf)); -+ } -+ if (RXH_CRC(et->etc, rxh)) { -+ ET_ERROR(("et%d: rx: crc error from %s\n", et->etc->unit, eabuf)); -+ } -+ if (RXH_OVF(et->etc, rxh)) { -+ ET_ERROR(("et%d: rx: fifo overflow\n", et->etc->unit)); -+ } -+ if (RXH_NO(et->etc, rxh)) { -+ ET_ERROR(("et%d: rx: crc error (odd nibbles) from %s\n", -+ et->etc->unit, eabuf)); -+ } -+ if (RXH_RXER(et->etc, rxh)) { -+ ET_ERROR(("et%d: rx: symbol error from %s\n", et->etc->unit, eabuf)); -+ } -+} -+ -+static void BCMFASTPATH -+et_sendup(et_info_t *et, struct sk_buff *skb) -+{ -+ etc_info_t *etc; -+ void *rxh; -+ uint16 flags; -+#ifdef DBG_PRINT_PKT -+ int idx; -+#endif /* DBG_PRINT_PKT */ -+#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH -+ struct sk_buff *next; -+#endif /* CONFIG_BCM_IPROC_GMAC_PREFETCH */ -+ -+ etc = et->etc; -+ -+ /* packet buffer starts with rxhdr */ -+ rxh = skb->data; -+ -+ /* strip off rxhdr */ -+ __skb_pull(skb, HWRXOFF); -+ -+ ET_TRACE(("et%d: et_sendup: %d bytes\n", et->etc->unit, skb->len)); -+ ET_LOG("et%d: et_sendup: len %d", et->etc->unit, skb->len); -+ -+ etc->rxframe++; -+ etc->rxbyte += skb->len; -+ -+ /* eh should now be aligned 2-mod-4 */ -+ ASSERT(((ulong)skb->data & 3) == 2); -+ -+ /* strip off crc32 */ -+ __skb_trim(skb, skb->len - ETHER_CRC_LEN); -+ -+ ET_PRHDR("rx", (struct ether_header *)skb->data, skb->len, etc->unit); -+ ET_PRPKT("rxpkt", skb->data, skb->len, etc->unit); -+ -+#ifdef DBG_PRINT_PKT -+ printk("et%d: rxpkt len(0x%x) tag:0x%02x%02x%02x%02x\n", etc->unit, skb->len, -+ skb->data[12], skb->data[13], skb->data[14], skb->data[15]); -+ -+ printk("et%d: %s len(0x%x) rxpkt:", etc->unit, __FUNCTION__, skb->len); -+ for (idx = 0; idx < skb->len; idx++) { -+ if ((idx % 16) == 0) { -+ printk("\n"); -+ } -+ printk("%02x ", skb->data[idx]); -+ } -+ printk("\n"); -+#endif /* DBG_PRINT_PKT */ -+ -+ /* get the error flags */ -+ flags = RXH_FLAGS(etc, rxh); -+ -+ /* check for reported frame errors */ -+ if (flags) { -+ goto err; -+ } -+ -+ skb->dev = et->dev; -+ -+ ASSERT(!PKTISCHAINED(skb)); -+ -+ /* extract priority from payload and store it out-of-band -+ * in skb->priority -+ */ -+ if (et->etc->qos) { -+ pktsetprio(skb, TRUE); -+ } -+ -+ skb->protocol = eth_type_trans(skb, et->dev); -+ -+#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH -+ next = skb->next; -+ while (1) { -+ if (next != NULL) { -+ -+ prefetch_range(next, SKB_PREFETCH_LEN); -+ next = next->next; -+ } else { -+ break; -+ } -+ } -+#endif /* CONFIG_BCM_IPROC_GMAC_PREFETCH */ -+ -+ /* send it up */ -+#if defined(GMAC_NAPI_POLL) || defined(GMAC_NAPI2_POLL) -+#ifdef CONFIG_IPROC_2STAGE_RX -+ if (!et->rxinisr) { -+ netif_receive_skb(skb); -+ } else { -+ netif_rx(skb); -+ } -+#else /* CONFIG_IPROC_2STAGE_RX */ -+ if (et->dev->features & NETIF_F_GRO) { -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) { -+ skb = vlan_untag(skb); -+ if (unlikely(!skb)) { -+ goto err; -+ } -+ } -+ napi_gro_receive(&et->napi_poll, skb); -+ } else { -+ netif_receive_skb(skb); -+ } -+#endif /* CONFIG_IPROC_2STAGE_RX */ -+#else -+ netif_rx(skb); -+#endif /* defined(GMAC_NAPI_POLL) || defined(GMAC_NAPI2_POLL) */ -+ -+ ET_LOG("et%d: et_sendup ret", et->etc->unit, 0); -+ -+ return; -+ -+err: -+ et_error(et, skb, rxh); -+ -+ PKTFRMNATIVE(etc->osh, skb); -+ PKTFREE(etc->osh, skb, FALSE); -+ -+ return; -+} -+ -+static void -+et_dumpet(et_info_t *et, struct bcmstrbuf *b) -+{ -+ bcm_bprintf(b, "et %p dev %p name %s tbusy %d txq[0].qlen %d malloced %d\n", -+ et, et->dev, et->dev->name, (uint)netif_queue_stopped(et->dev), et->txq[0].qlen, -+ MALLOCED(et->osh)); -+} -+ -+void -+et_dump(et_info_t *et, struct bcmstrbuf *b) -+{ -+/* bcm_bprintf(b, "et%d: %s %s version %s\n", et->etc->unit, -+ __DATE__, __TIME__, EPI_VERSION_STR); -+*/ -+ bcm_bprintf(b, "et%d: version %s\n", et->etc->unit, EPI_VERSION_STR); -+ -+ et_dumpet(et, b); -+ etc_dump(et->etc, b); -+ -+ bcm_bprintf(b, "txdfrm(%d); txdfrmropped(%d); txqlen(%d); txqstop(%d); txdmafull(%d) txmaxlen(%d) txsgpkt(%d)\n", -+ et->etc->txfrm, et->etc->txfrmdropped, et->etc->txqlen, et->etc->txqstop, et->etc->txdmafull, -+ et->etc->txmaxlen, et->etc->txsgpkt); -+ et->etc->txfrm=0; -+ et->etc->txfrmdropped=0; -+ et->etc->txqlen=0; -+ et->etc->txqstop=0; -+ et->etc->txdmafull=0; -+ et->etc->txmaxlen=0; -+ et->etc->txsgpkt=0; -+ -+ bcm_bprintf(b, "rxquota(%d); rxdmastopped(%d)\n", -+ et->etc->rxquota, et->etc->rxdmastopped); -+ et->etc->rxquota=0; -+ et->etc->rxdmastopped=0; -+#ifdef GMAC_RATE_LIMITING -+ bcm_bprintf(b, "rxd_dropped_packets(%d)\n", -+ et->etc->rl_dropped_packets); -+ et->etc->rl_dropped_packets=0; -+#endif /* GMAC_RATE_LIMITING */ -+ -+} -+ -+void -+et_link_up(et_info_t *et) -+{ -+ ET_ERROR(("et%d: link up (%d%s)\n", -+ et->etc->unit, et->etc->speed, (et->etc->duplex? "FD" : "HD"))); -+ printk(KERN_DEBUG "et%d Link Up: %d%s\n", et->etc->unit, et->etc->speed, et->etc->duplex?"FD":"HD"); -+ netif_carrier_on(et->dev); -+} -+ -+void -+et_link_down(et_info_t *et) -+{ -+ ET_ERROR(("et%d: link down\n", et->etc->unit)); -+ printk(KERN_DEBUG "et%d Link Down\n", et->etc->unit); -+ netif_carrier_off(et->dev); -+} -+ -+bool -+et_is_link_up(et_info_t *et) -+{ -+ return netif_carrier_ok(et->dev); -+} -+ -+/********************************************************************** -+ * iproc_gmac_drv_probe(device) -+ * -+ * The Platform Driver Probe function. -+ * -+ * Input parameters: -+ * device: The Device Context -+ * -+ * Return value: -+ * 0: Driver Probe is Succesful -+ * not 0: ERROR -+ **********************************************************************/ -+static int iproc_gmac_drv_probe(struct platform_device* pldev) -+{ -+ struct net_device *dev = NULL; -+ osl_t *osh = NULL; -+ et_info_t *et = NULL; -+ int unit = et_found; -+ int err = 0; -+ unsigned char devname[8] = {0}; -+ char name[128]; -+ int idx; -+ struct device_node *np = pldev->dev.of_node; -+ const void *macaddr; -+ -+ printk("%s enter :%s; id:0x%x; unit:%d\n", __FUNCTION__, pldev->name, pldev->id, unit); -+ -+ /* Validation of platform device structure */ -+ if (!pldev) { -+ ET_ERROR(("WRONG INPUT\nplatfrom_device pointer should not be NULL.\n")); -+ return -EINVAL; -+ } -+ -+ et_found++; -+ -+ macaddr = of_get_mac_address(np); -+ if (!macaddr) { -+ dev_err(&pldev->dev, "can't find MAC address\n"); -+ return -ENODEV; -+ } -+ -+ osh = osl_attach(pldev, PCI_BUS, FALSE); -+ ASSERT(osh); -+ -+ ET_TRACE(("%s call alloc_etherdev\n", __FUNCTION__)); -+ if ((dev = alloc_etherdev(sizeof( et_info_t ))) == NULL) { -+ ET_ERROR(("%s: alloc_etherdev() failed\n", __FUNCTION__)); -+ err = -ENOMEM; -+ goto exit; -+ } -+ -+ et = ET_INFO(dev); -+ bzero(et, sizeof(et_info_t)); /* Is this needed in 2.6.36 ? -LR */ -+ et->dev = dev; -+ et->osh = osh; -+ -+ dev->base_addr = (unsigned long)of_iomap(np, 0); -+ dev->irq = (unsigned int)irq_of_parse_and_map(np, 0); -+ -+ printk("et%d: base_addr (0x%x) irq (%d)\n", unit, (uint32)dev->base_addr, dev->irq); -+ -+ if ((et->regsva = ioremap_nocache(dev->base_addr, 0xc00)) == NULL) { -+ ET_ERROR(("et%d: ioremap() failed\n", unit)); -+ err = -ENOMEM; -+ goto exit; -+ } -+ ET_TRACE(("%s base_addr: 0x%x; regsva:0x%x\n", __FUNCTION__, (uint32)dev->base_addr, (uint32)et->regsva)); -+ -+ pldev->id = dev->base_addr; -+ dev_set_drvdata(&(pldev->dev), dev); -+ SET_NETDEV_DEV(dev, (&pldev->dev)); -+ -+ init_MUTEX(&et->sem); -+ spin_lock_init(&et->lock); -+ spin_lock_init(&et->txq_lock); -+ spin_lock_init(&et->tx_lock); -+ spin_lock_init(&et->isr_lock); -+ -+ for (idx = 0; idx < NUMTXQ; idx++) { -+ skb_queue_head_init(&et->txq[idx]); -+ } -+ -+ /* Common load-time initialization */ -+ et->etc = etc_attach((void *)et, VENDOR_BROADCOM, BCMIPROC_CHIP_ID, unit, osh, et->regsva); -+ if (et->etc == NULL) { -+ ET_ERROR(("et%d: etc_attach() failed\n", unit)); -+ err = -ENOMEM; -+ goto exit; -+ } -+ -+ ether_addr_copy(dev->dev_addr, macaddr); -+ bcopy(macaddr, (char *)&et->etc->cur_etheraddr, ETHER_ADDR_LEN); -+ -+ /* init 1 second watchdog timer */ -+ init_timer(&et->timer); -+ et->timer.data = (ulong)dev; -+ et->timer.function = et_watchdog; -+ -+#if defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) -+ /* schedule one second watchdog timer */ -+ et->timer.expires = jiffies + HZ; -+ add_timer(&et->timer); -+ et->set = TRUE; -+#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) */ -+#endif /* defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) */ -+ -+#ifdef GMAC_RATE_LIMITING -+ /* Init 1 second watchdog timer */ -+ init_timer(&et->etc->rl_timer); -+ et->etc->rl_timer.data = (ulong)dev; -+ et->etc->rl_timer.function = et_release_congestion; -+#endif /* GMAC_RATE_LIMITING */ -+ -+#ifdef GMAC_ALL_PASSIVE -+ if (ET_ALL_PASSIVE_ENAB(et)) { -+ MY_INIT_WORK(&et->dpc_task.work, (work_func_t)et_dpc_work); -+ et->dpc_task.context = et; -+ MY_INIT_WORK(&et->txq_task.work, (work_func_t)et_txq_work); -+ et->txq_task.context = et; -+ } -+ if (et_ctf_pipeline_loopback(et)) { -+ et->all_dispatch_mode = FALSE; -+ } else { -+ et->all_dispatch_mode = (passivemode == 0) ? TRUE : FALSE; -+ } -+#endif /* GMAC_ALL_PASSIVE */ -+ -+ ET_TRACE(("%s request irq\n", __FUNCTION__)); -+ /* register our interrupt handler */ -+ if (request_irq(dev->irq, et_isr, IRQF_SHARED, dev->name, et)) { -+ ET_ERROR(("%s: request_irq(%d) failed\n", __FUNCTION__, dev->irq)); -+ err = -ENOMEM; -+ goto exit; -+ } -+ -+ /* add us to the global linked list */ -+ et->next = et_list; -+ et_list = et; -+ -+#ifdef HAVE_NET_DEVICE_OPS -+ dev->netdev_ops = &et_netdev_ops ; -+#else /* HAVE_NET_DEVICE_OPS */ -+ dev->open = et_open; -+ dev->stop = et_close; -+ dev->hard_start_xmit = et_start; -+ dev->get_stats = et_get_stats; -+ dev->set_mac_address = et_set_mac_address; -+ dev->set_multicast_list = et_set_multicast_list; -+ dev->do_ioctl = et_ioctl; -+#endif /* HAVE_NET_DEVICE_OPS */ -+ -+#if defined(GMAC_NAPI_POLL) -+ dev->poll = et_poll; -+ dev->weight = (ET_GMAC(et->etc) ? 64 : 32); -+#elif defined(GMAC_NAPI2_POLL) -+ netif_napi_add(dev, & et->napi_poll, et_poll, 64); -+ napi_enable(&et->napi_poll); -+#else /* !GMAC_NAPI_POLL && !GMAC_NAPI2_POLL */ -+ /* Setup the bottom half handler */ -+ tasklet_init(&et->tasklet, et_dpc, (ulong)et); -+#endif -+ -+#if defined(BCMDMASGLISTOSL) -+ dev->features = (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_ALL_CSUM); -+ dev->vlan_features = (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_ALL_CSUM); -+ -+#ifdef CONFIG_BCM_GRO_ENABLE -+ dev->features |= NETIF_F_GRO; -+ dev->vlan_features |= NETIF_F_GRO; -+ printk("et%d: Enable Checksum-SG-GRO\n", unit); -+#endif /* CONFIG_BCM_GRO_ENABLE */ -+#endif /* BCMDMASGLISTOSL */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) -+ dev->ethtool_ops = &et_ethtool_ops; -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) */ -+ -+ /* Assign netdev name consistently, even if GMAC0 or 1 is disabled */ -+ snprintf(devname, 8, "eth%d", unit); -+ dev_alloc_name(dev, devname); -+ -+ ET_TRACE(("%s register netdev\n", __FUNCTION__)); -+ if (register_netdev(dev)) { -+ ET_ERROR(("%s register_netdev() failed\n", __FUNCTION__)); -+ err = -ENOMEM; -+ goto exit; -+ } -+ -+ /* Print hello string */ -+ (*et->etc->chops->longname)(et->etc->ch, name, sizeof(name)); -+ printk("%s: %s %s\n", dev->name, name, EPI_VERSION_STR); -+ -+ eth_mac_proc_create(dev); -+ -+ ET_TRACE(("%s: exit\n", __FUNCTION__)); -+ -+ return 0; -+ -+exit: -+#ifndef CONFIG_OF -+ if (macbase) { -+ iounmap(macbase); -+ macbase=NULL; -+ } -+ if (memres) { -+ release_mem_region(memres->start, (memres->end - memres->start + 1)); -+ memres=NULL; -+ } -+#endif -+ if (dev) { -+ free_netdev(dev); -+ dev = NULL; -+ } -+ if (osh) { -+ osl_detach(osh); -+ osh=NULL; -+ } -+ if (et) { -+ etc_detach(et->etc); -+ et->dev = NULL; -+ et->osh = NULL; -+ et_free(et); -+ et=NULL; -+ } -+ return err; -+} -+ -+ -+/********************************************************************** -+ * iproc_gmac_drv_remove(device) -+ * -+ * The Removal of Platform Device, and un-initialize the previously -+ * added MAC, and it's MEM Regions and Resources. -+ * -+ * Input parameters: -+ * device: The Device Context -+ * -+ * Return value: -+ * 0: Driver Entry is Succesfull -+ **********************************************************************/ -+static int __exit iproc_gmac_drv_remove(struct platform_device *pldev) -+{ -+ struct net_device *dev = platform_get_drvdata(pldev); -+ int retVal = 0; -+ et_info_t *et = NULL; -+ struct resource *memres = NULL; -+ -+ ET_TRACE(("%s: enter\n", __FUNCTION__)); -+ printk("%s: enter\n", __FUNCTION__); -+ -+#ifdef CONFIG_PM -+ iproc_gmac_drv_suspend(pldev, PMSG_SUSPEND); -+#endif -+ -+ et = ET_INFO(dev); -+ -+ iounmap(et->regsva); -+ unregister_netdev(dev); -+ -+ memres = platform_get_resource(pldev, IORESOURCE_MEM, 0); -+ if (memres) { -+ release_mem_region(memres->start, (memres->end - memres->start + 1)); -+ } else { -+ ET_ERROR(("ERROR: Could not get Platform Resource GMAC Register Memory Resource\n")); -+ retVal = -ENOMEM; -+ } -+ -+ free_netdev(dev); -+ -+#ifdef CONFIG_OF -+ eth_mac_proc_remove (dev); -+#endif -+ -+ et->dev = NULL; -+ et_free(et); -+ -+ ET_TRACE(("%s: exit\n", __FUNCTION__)); -+ -+ return retVal; -+} -+ -+#ifdef CONFIG_PM -+static int iproc_gmac_drv_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ int ret; -+ char *filename = "/usr/sbin/ifdown"; -+ char *argv[] = {filename, "eth0", NULL}; -+ char *envp[] = {"HOME=/", -+ "TERM=linux", -+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", -+ NULL}; -+ -+ ET_TRACE(("%s: enter\n", __FUNCTION__)); -+ printk("%s: enter\n", __FUNCTION__); -+ -+/* ret = kernel_execve(filename, (const char * const*) argv, (const char * const*) envp);*/ -+ ret = do_execve(getname_kernel(filename), (const char *const *)argv, (const char *const *)envp); -+ ET_TRACE(("%s: exit\n", __FUNCTION__)); -+ -+ return 0; -+} -+ -+static int iproc_gmac_drv_resume(struct platform_device *pdev) -+{ -+ int ret; -+ char *filename = "/usr/sbin/ifup"; -+ char *argv[] = {filename, "eth0", NULL}; -+ char *envp[] = {"HOME=/", -+ "TERM=linux", -+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", -+ NULL}; -+ -+ ET_TRACE(("%s: enter\n", __FUNCTION__)); -+ printk("%s: enter\n", __FUNCTION__); -+ /*ret = kernel_execve(filename, (const char * const*) argv, (const char * const*) envp);*/ -+ ret = do_execve(getname_kernel(filename), (const char *const *)argv, (const char *const *)envp); -+ -+ ET_TRACE(("%s: exit\n", __FUNCTION__)); -+ -+ return 0; -+} -+#endif /* CONFIG_PM */ -+ -+ -+/********************************************************************** -+ * iproc_gmac_init_module(VOID) -+ * -+ * The Driver Entry Function -+ * -+ * Input parameters: -+ * None -+ * -+ * Return value: -+ * 0: Driver Entry is Succesful -+ * not 0: ERROR -+ **********************************************************************/ -+static int __init -+iproc_gmac_init_module(void) -+{ -+ ET_TRACE(("%s: enter\n", __FUNCTION__)); -+ -+#ifdef BCMDBG -+ if (msglevel != 0xdeadbeef) { -+ et_msg_level = msglevel; -+ } else { -+ char *var = getvar(NULL, "et_msglevel"); -+ if (var) { -+ et_msg_level = bcm_strtoul(var, NULL, 0); -+ } -+ } -+ -+ printk("%s: msglevel set to 0x%x\n", __FUNCTION__, et_msg_level); -+#endif /* BCMDBG */ -+ -+#ifdef GMAC_ALL_PASSIVE -+ { -+ char *var = getvar(NULL, "et_dispatch_mode"); -+ if (var) -+ passivemode = bcm_strtoul(var, NULL, 0); -+ printk("%s: passivemode set to 0x%x\n", __FUNCTION__, passivemode); -+ } -+#endif /* GMAC_ALL_PASSIVE */ -+ -+#ifdef GMAC_NAPI_POLL -+ printk("%s: GMAC_NAPI_POLL mode\n", __FUNCTION__); -+#endif /* GMAC_NAPI_POLL */ -+ -+#ifdef GMAC_NAPI2_POLL -+ printk("%s: GMAC_NAPI2_POLL mode\n", __FUNCTION__); -+#endif /* GMAC_NAPI2_POLL */ -+ -+#ifdef ET_LIMIT_TXQ -+ { -+ char *var = getvar(NULL, "et_txq_thresh"); -+ if (var) { -+ et_txq_thresh = bcm_strtoul(var, NULL, 0); -+ } -+ printk("%s: et_txq_thresh set to 0x%x\n", __FUNCTION__, et_txq_thresh); -+ } -+#endif /* ET_LIMIT_TXQ */ -+ -+#ifdef GMAC_RATE_LIMITING -+ { -+ char *var = getvar(NULL, "et_rx_rate_limit"); -+ if (var) { -+ et_rx_rate_limit = bcm_strtoul(var, NULL, 0); -+ } -+ printk("%s: et_rx_rate_limit set to 0x%x\n", __FUNCTION__, et_rx_rate_limit); -+ } -+#endif /* GMAC_RATE_LIMITING */ -+ -+ ET_TRACE(("%s: exit\n", __FUNCTION__)); -+ return 0; -+} -+ -+ -+#ifndef CONFIG_OF -+/********************************************************************** -+ * iproc_gmac_cleanup_module(VOID) -+ * -+ * The Driver Exit Function -+ * -+ * Input parameters: -+ * None -+ * -+ * Return value: -+ * Nothing -+ **********************************************************************/ -+static void __exit -+iproc_gmac_cleanup_module(void) -+{ -+ int idx; -+ -+ ET_TRACE(("%s: enter\n", __FUNCTION__)); -+ -+ for (idx = 0; idx < IPROC_NUM_GMACS; idx++) { -+ if (gmac_pdev_loaded[idx]) { -+ /* Unregister GMAC driver */ -+ iproc_platform_driver_unregister(&gmac_pdrv[idx]); -+ } -+ } -+ -+ /* Clean up the proc directory */ -+ eth_mac_proc_remove(); -+ -+ ET_TRACE(("%s: exit\n", __FUNCTION__)); -+ return; -+} -+#endif /*CONFIG_OF*/ -+ -+#if 0 -+static int get_fa_bypass(char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ unsigned int len=0; -+ len += sprintf(page+len, "\n\n## Current FA Bypass setting = 0x%x, %s ##\n\n",gBypass, gBypass?"enabled":"disabled"); -+ *eof = 1; -+ return len; -+} -+ -+static int set_fa_bypass(struct file *file, const char *buffer, unsigned long count, void *data) -+{ -+ unsigned int len=1; -+ unsigned char debug_buffer[2]; -+ int bypass =0; -+ -+ if (count != 2) { -+ ET_ERROR(("Please pass (one:1) digit FA bypass value only, 0=disable FA bypass, 1 = enable FA bypass\n")); -+ return -EINVAL; -+ } -+ -+ /* Last buffer byte will be LF or CR only */ -+ if(copy_from_user(&debug_buffer[0], buffer, len)) { -+ ET_ERROR(("Problem in copying invalid user buffer\n")); -+ return -EFAULT; -+ } -+ -+ debug_buffer[len]='\0'; /* Only one byte value is available now */ -+ if ( sscanf(debug_buffer,"%d",&bypass) != 1) { -+ ET_ERROR(("\n##Invalid value :%s: is passed ##\n",debug_buffer)); -+ return -EINVAL; -+ } -+ if (!((bypass >=DISABLE_FA_BYPASS) && (bypass <= ENABLE_FA_BYPASS))) { -+ ET_ERROR(("\n##Passed value :%d: is not in valid range %d-%d \n",bypass,DISABLE_FA_BYPASS,ENABLE_FA_BYPASS)); -+ return -EINVAL; -+ } -+ ET_TRACE(("\n##set_fa_bypass(): Previous: 0x%x %s ##\n", gBypass, gBypass?"enabled":"disabled")); -+ gBypass = bypass; -+ ET_TRACE(("\n##set_fa_bypass(): New: 0x%x %s ##\n", gBypass, gBypass?"enabled":"disabled")); -+ return count; -+} -+#endif -+ -+static char* iproc_eth_proc_root="iproc_eth"; -+static struct proc_dir_entry *iproc_eth_root_dir=NULL; // BCM5892 eth proc root directory -+static int eth_mac_proc_create(struct net_device *dev ) -+{ -+/* struct proc_dir_entry *dent, *ent;*/ -+ struct proc_dir_entry *dent; -+ et_info_t *et = NULL; -+ etc_info_t *etc = NULL; -+ char fname[32]; -+ -+ et = ET_INFO(dev); -+ if (et != NULL) { -+ etc = et->etc; -+ } -+ -+ if ((et == NULL) || (etc == NULL)) { -+ printk("%s: error: Unit probably not initialized by probe function." -+ " et=0x%pm etc=0x%p\n", __FUNCTION__, et, etc); -+ return -1; -+ } -+ -+ ET_TRACE(("%s: enter\n", __FUNCTION__)); -+ -+ snprintf(fname, 32, "%s%u", iproc_eth_proc_root, etc->unit); -+ -+ dent = proc_mkdir(fname,iproc_eth_root_dir); -+#if 0 -+ if (dent) { -+ /* unit 2 has FA connectivity, create bypass path only for unit 2 */ -+ if (etc->unit == 2) { -+ printk("\nCreating fa bypass proc entry\n"); -+ -+ ent = create_proc_entry("fa_bypass", S_IFREG|S_IRUGO, dent); -+ if (ent) { -+ ent->read_proc = get_fa_bypass; -+ ent->write_proc = set_fa_bypass; -+ } else { -+ printk("Error creating proc_entry, returning\n"); -+ return -1; -+ } -+ } -+ } -+#endif -+ ET_TRACE(("%s: exit\n", __FUNCTION__)); -+ return 0; -+} -+ -+#ifndef CONFIG_OF -+static void eth_mac_proc_remove(void) -+{ -+ ET_TRACE(("%s: enter\n", __FUNCTION__)); -+ printk("%s: enter\n", __FUNCTION__); -+ remove_proc_entry(iproc_eth_proc_root,NULL); -+ ET_TRACE(("%s: exit\n", __FUNCTION__)); -+} -+#else -+static void eth_mac_proc_remove(struct net_device *dev) -+{ -+ et_info_t *et; -+ etc_info_t *etc; -+ char fname[32]; -+ -+ ET_TRACE(("%s: enter\n", __FUNCTION__)); -+ printk("%s: enter\n", __FUNCTION__); -+ -+ et = ET_INFO(dev); -+ if (et == NULL) { -+ printk("%s: error: Unit probably not initialized by probe function.\n", __FUNCTION__); -+ return; -+ } -+ -+ etc = et->etc; -+ if (etc == NULL) { -+ printk("%s: error: Unit probably not initialized by probe \ -+ function.\n", __FUNCTION__); -+ return; -+ } -+ -+ snprintf(fname, 32, "%s%u", iproc_eth_proc_root, etc->unit); -+ remove_proc_entry(fname,NULL); -+ -+ ET_TRACE(("%s: exit\n", __FUNCTION__)); -+} -+#endif /* CONFIG_OF */ -+ -+#ifdef CONFIG_OF -+static const struct of_device_id brcm_iproc_dt_ids[] = { -+ { .compatible = "brcm,iproc-gmac"}, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, brcm_iproc_dt_ids); -+ -+static struct platform_driver iproc_gmac_driver = -+{ -+ .probe = iproc_gmac_drv_probe, -+ .remove = __exit_p(iproc_gmac_drv_remove), -+ .suspend = iproc_gmac_drv_suspend, -+ .resume = iproc_gmac_drv_resume, -+ .driver = -+ { -+ .name = "bcmiproc-gmac", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(brcm_iproc_dt_ids), -+ }, -+}; -+module_init(iproc_gmac_init_module); -+module_platform_driver(iproc_gmac_driver); -+#else -+module_init(iproc_gmac_init_module); -+module_exit(iproc_gmac_cleanup_module); -+#endif /*CONFIG_OF*/ -+ -+MODULE_DESCRIPTION("Broadcom Northstar Ethernet Driver"); -+MODULE_LICENSE("GPL"); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_linux.h b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_linux.h ---- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_linux.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/et_linux.h 2017-11-09 17:53:43.900292000 +0800 -@@ -0,0 +1,50 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * Linux device driver tunables for -+ * Broadcom BCM47XX 10/100Mbps Ethernet Device Driver -+ * -+ * $Id: et_linux.h 320789 2012-03-13 04:01:27Z rnuti $ -+ */ -+ -+#ifndef _et_linux_h_ -+#define _et_linux_h_ -+ -+/* tunables */ -+#define NTXD 512 /* # tx dma ring descriptors (must be ^2) */ -+#define NRXD 512 /* # rx dma ring descriptors (must be ^2) */ -+#if defined(CONFIG_RAM_SIZE) && (CONFIG_RAM_SIZE <= 16) -+#define NRXBUFPOST 256 /* try to keep this # rbufs posted to the chip */ -+#else -+#define NRXBUFPOST 420 /* try to keep this # rbufs posted to the chip */ -+#endif -+#ifdef CONFIG_JUMBO_FRAME -+#define BCM_ETHER_MAX_LEN 2500 -+#define RXBUFSZ (BCM_ETHER_MAX_LEN + HWRXOFF + BCMEXTRAHDROOM) /* receive buffer size */ -+#else -+#define BCM_ETHER_MAX_LEN 1518 //ETHER_MAX_LEN (1518) -+#define RXBUFSZ 1792 -+#endif /* CONFIG_JUMBO_FRAME */ -+ -+ -+#ifndef RXBND -+#define RXBND 64 //32 /* max # rx frames to process in dpc */ -+#endif -+ -+#if defined(ILSIM) || defined(__arch_um__) -+#undef NTXD -+#define NTXD 16 -+#undef NRXD -+#define NRXD 16 -+#undef NRXBUFPOST -+#define NRXBUFPOST 2 -+#endif -+ -+#define PKTCBND 48 -+ -+#define CTFPOOLSZ 768 -+ -+#define PREFSZ 96 -+#define ETPREFHDRS(h, sz) OSL_PREF_RANGE_ST((h), (sz)) -+ -+#endif /* _et_linux_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/etc.c b/drivers/net/ethernet/broadcom/gmac/src/et/sys/etc.c ---- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/etc.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/etc.c 2017-11-09 17:53:43.901298000 +0800 -@@ -0,0 +1,746 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * Common [OS-independent] portion of -+ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet -+ * Device Driver. -+ * -+ * $Id: etc.c 323634 2012-03-26 10:26:11Z groques $ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "etcgmac.h" -+ -+#ifdef BCMDBG -+uint32 et_msg_level = 1; -+#else -+uint32 et_msg_level = 0; -+#endif /* BCMDBG */ -+uint8 ethup = 0; -+uint8 ethupmask = 0; -+etc_info_t *ethupetcptr[IPROC_NUM_GMACS]; -+ -+/* local prototypes */ -+static void etc_loopback(etc_info_t *etc, int on); -+static void etc_dumpetc(etc_info_t *etc, struct bcmstrbuf *b); -+int etc_gmac_speed(int gmac); -+ -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) -+extern void gmac_set_amac_mdio(int en); -+extern int gmac_has_mdio_access(void); -+#elif defined(CONFIG_MACH_WH2) -+extern void __iomem *get_iproc_wrap_ctrl_base(void); -+extern int egphy28_reg_read(uint32 phy_addr, int reg_addr, uint16 *data); -+#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) */ -+ -+#ifdef CONFIG_SERDES_ASYMMETRIC_MODE -+void gmac_serdes_asym_mode(etc_info_t *etcptrs[]); -+#endif /* CONFIG_SERDES_ASYMMETRIC_MODE */ -+ -+/* 802.1d priority to traffic class mapping. queues correspond one-to-one -+ * with traffic classes. -+ */ -+uint32 up2tc[NUMPRIO] = { -+ TC_BE, /* 0 BE TC_BE Best Effort */ -+ TC_BK, /* 1 BK TC_BK Background */ -+ TC_BK, /* 2 -- TC_BK Background */ -+ TC_BE, /* 3 EE TC_BE Best Effort */ -+ TC_CL, /* 4 CL TC_CL Controlled Load */ -+ TC_CL, /* 5 VI TC_CL Controlled Load */ -+ TC_VO, /* 6 VO TC_VO Voice */ -+ TC_VO /* 7 NC TC_VO Voice */ -+}; -+ -+uint32 priq_selector[] = { -+ [0x0] = TC_NONE, [0x1] = TC_BK, [0x2] = TC_BE, [0x3] = TC_BE, -+ [0x4] = TC_CL, [0x5] = TC_CL, [0x6] = TC_CL, [0x7] = TC_CL, -+ [0x8] = TC_VO, [0x9] = TC_VO, [0xa] = TC_VO, [0xb] = TC_VO, -+ [0xc] = TC_VO, [0xd] = TC_VO, [0xe] = TC_VO, [0xf] = TC_VO -+}; -+ -+/* find the chip opsvec for this chip */ -+struct chops* -+etc_chipmatch(uint vendor, uint device) -+{ -+ extern struct chops bcmgmac_et_chops; -+ -+ if (bcmgmac_et_chops.id(vendor, device)) { -+ return (&bcmgmac_et_chops); -+ } -+ -+ return (NULL); -+} -+ -+void* -+etc_attach(void *et, uint vendor, uint device, uint unit, void *osh, void *regsva) -+{ -+ etc_info_t *etc; -+ char *var; -+ -+ ET_TRACE(("et%d: etc_attach: vendor 0x%x device 0x%x\n", unit, vendor, device)); -+ -+ /* some code depends on packed structures */ -+ ASSERT(sizeof(struct ether_addr) == ETHER_ADDR_LEN); -+ ASSERT(sizeof(struct ether_header) == ETHER_HDR_LEN); -+ -+ /* allocate etc_info_t state structure */ -+ if ((etc = (etc_info_t*) MALLOC(osh, sizeof(etc_info_t))) == NULL) { -+ ET_ERROR(("et%d: etc_attach: out of memory, malloced %d bytes\n", unit, -+ MALLOCED(osh))); -+ return (NULL); -+ } -+ bzero((char*)etc, sizeof(etc_info_t)); -+ -+ etc->et = et; -+ etc->unit = unit; -+ etc->osh = osh; -+ etc->vendorid = (uint16) vendor; -+ etc->deviceid = (uint16) device; -+ etc->forcespeed = etc_gmac_speed(unit); -+ etc->linkstate = FALSE; -+ etc->mdio_init_time = 5; /* number of seconds to wait before release mdio bus */ -+ var = getvar(NULL, "eth_init_time"); -+ if (var) { -+ etc->mdio_init_time = bcm_strtoul(var, NULL, 0); -+ } -+ printk("%s() mdio_init_time = %d\n", __FUNCTION__, etc->mdio_init_time); -+ ethupmask |= 1<unit; -+ ethupetcptr[unit] = etc; -+ -+ /* set chip opsvec */ -+ etc->chops = etc_chipmatch(vendor, device); -+ ASSERT(etc->chops); -+ -+ /* chip attach */ -+ if ((etc->ch = (*etc->chops->attach)(etc, osh, regsva)) == NULL) { -+ ET_ERROR(("et%d: chipattach error\n", unit)); -+ goto fail; -+ } -+ -+ return ((void*)etc); -+ -+fail: -+ etc_detach(etc); -+ return (NULL); -+} -+ -+void -+etc_detach(etc_info_t *etc) -+{ -+ if (etc == NULL) -+ return; -+ -+ /* free chip private state */ -+ if (etc->ch) { -+ (*etc->chops->detach)(etc->ch); -+ etc->chops = etc->ch = NULL; -+ } -+ -+ MFREE(etc->osh, etc, sizeof(etc_info_t)); -+} -+ -+void -+etc_reset(etc_info_t *etc) -+{ -+ ET_TRACE(("et%d: etc_reset\n", etc->unit)); -+ -+ etc->reset++; -+ -+ /* reset the chip */ -+ (*etc->chops->reset)(etc->ch); -+ -+ /* free any posted tx packets */ -+ (*etc->chops->txreclaim)(etc->ch, TRUE); -+ -+#ifdef DMA -+ /* free any posted rx packets */ -+ (*etc->chops->rxreclaim)(etc->ch); -+#endif /* DMA */ -+} -+ -+void -+etc_init(etc_info_t *etc, uint options) -+{ -+ ET_TRACE(("et%d: etc_init\n", etc->unit)); -+ -+ ASSERT(etc->pioactive == NULL); -+ ASSERT(!ETHER_ISNULLADDR(&etc->cur_etheraddr)); -+ ASSERT(!ETHER_ISMULTI(&etc->cur_etheraddr)); -+ -+ /* init the chip */ -+ (*etc->chops->init)(etc->ch, options); -+ /* init the PM change mode and linkstate */ -+ etc->pm_modechange = FALSE; -+ etc->linkstate = FALSE; -+} -+ -+/* mark interface up */ -+void -+etc_up(etc_info_t *etc) -+{ -+ etc->up = TRUE; -+ -+ /* enable the port phy */ -+ (*etc->chops->phyenable)(etc->ch, etc->unit, etc->phyaddr, 1); -+ -+ et_init(etc->et, ET_INIT_FULL | ET_INIT_INTRON); -+} -+ -+/* mark interface down */ -+uint -+etc_down(etc_info_t *etc, int reset) -+{ -+ uint callback; -+ -+ callback = 0; -+ -+ ET_FLAG_DOWN(etc); -+ -+ /* disable the port phy */ -+ (*etc->chops->phyenable)(etc->ch, etc->unit, etc->phyaddr, 0); -+ -+ if (reset) { -+ et_reset(etc->et); -+ } -+ -+ /* suppress link state changes during power management mode changes */ -+ if (etc->linkstate) { -+ etc->linkstate = FALSE; -+ if (!etc->pm_modechange) { -+ et_link_down(etc->et); -+ } -+ } -+ -+ return (callback); -+} -+ -+/* common iovar handler. return 0=ok, -1=error */ -+int -+etc_iovar(etc_info_t *etc, uint cmd, uint set, void *arg) -+{ -+ int error; -+ uint *vecarg; -+ -+ error = 0; -+ vecarg = (uint *)arg; -+ ET_TRACE(("et%d: etc_iovar: cmd 0x%x\n", etc->unit, cmd)); -+ -+ switch (cmd) { -+#ifdef BCMDBG -+ case IOV_ET_CLEAR_DUMP: -+ if (set) { -+ uint size = ((char *)(&etc->rxbadlen) - (char *)(&etc->txframe)); -+ -+ bzero((char *)&etc->txframe, size + sizeof(etc->rxbadlen)); -+ (*etc->chops->dumpmib)(etc->ch, NULL, TRUE); -+ error = 0; -+ } -+ break; -+#endif /* BCMDBG */ -+ case IOV_PKTC: -+ if (set) { -+ etc->pktc = *vecarg; -+ } else { -+ *vecarg = (uint)etc->pktc; -+ } -+ break; -+ -+ case IOV_PKTCBND: -+ if (set) { -+ etc->pktcbnd = MAX(*vecarg, 32); -+ } else { -+ *vecarg = etc->pktcbnd; -+ } -+ break; -+ -+ case IOV_COUNTERS: -+ { -+ struct bcmstrbuf b; -+ bcm_binit(&b, (char*)arg, IOCBUFSZ); -+ etc_dumpetc(etc, &b); -+ } -+ break; -+ -+ default: -+ error = -1; -+ } -+ -+ return (error); -+} -+ -+/* common ioctl handler. return: 0=ok, -1=error */ -+int -+etc_ioctl(etc_info_t *etc, int cmd, void *arg) -+{ -+ int error; -+ int val; -+ int *vec = (int*)arg; -+ -+ error = 0; -+ -+ val = arg ? *(int*)arg : 0; -+ -+ ET_TRACE(("et%d: etc_ioctl: cmd 0x%x\n", etc->unit, cmd)); -+ -+ switch (cmd) { -+ case ETCUP: -+ et_up(etc->et); -+ break; -+ -+ case ETCDOWN: -+ et_down(etc->et, TRUE); -+ break; -+ -+ case ETCLOOP: -+ etc_loopback(etc, val); -+ break; -+ -+ case ETCDUMP: -+ if (et_msg_level & 0x10000) { -+ bcmdumplog((char *)arg, IOCBUFSZ); -+ } else { -+ struct bcmstrbuf b; -+ bcm_binit(&b, (char*)arg, IOCBUFSZ); -+ et_dump(etc->et, &b); -+ } -+ break; -+ -+ case ETCSETMSGLEVEL: -+ et_msg_level = val; -+ break; -+ -+ case ETCPROMISC: -+ etc_promisc(etc, val); -+ break; -+ -+ case ETCQOS: -+ etc_qos(etc, val); -+ break; -+ -+ case ETCSPEED: -+ if (vec) { -+ if (vec[0] < ET_AUTO || vec[0] > ET_1000FULL) { -+ goto err; -+ } -+ -+ etc->forcespeed = vec[0]; -+ -+ /* explicitly reset the phy */ -+ (*etc->chops->phyreset)(etc->ch); -+ -+ /* request restart autonegotiation if we're reverting to adv mode */ -+ etc->advertise = etc->advertise2 = 0; -+ if (etc->forcespeed == ET_AUTO) { -+ if (vec[1] & ADVERTISED_10baseT_Half) { -+ etc->advertise |= ADV_10HALF; -+ } -+ if (vec[1] & ADVERTISED_10baseT_Full) { -+ etc->advertise |= ADV_10FULL; -+ } -+ if (vec[1] & ADVERTISED_100baseT_Half) { -+ etc->advertise |= ADV_100HALF; -+ } -+ if (vec[1] & ADVERTISED_100baseT_Full) { -+ etc->advertise |= ADV_100FULL; -+ } -+ if (vec[1] & ADVERTISED_1000baseT_Full) { -+ etc->advertise2 |= ADV_1000FULL; -+ } -+ etc->needautoneg = TRUE; -+ } else { -+ etc->needautoneg = FALSE; -+ } -+ et_init(etc->et, ET_INIT_INTRON); -+ } -+ break; -+ -+ case ETCPHYRD: -+ if (vec) { -+ vec[1] = (*etc->chops->phyrd)(etc->ch, etc->phyaddr, vec[0]); -+ ET_TRACE(("etc_ioctl: ETCPHYRD of reg 0x%x => 0x%x\n", vec[0], vec[1])); -+ } -+ break; -+ -+ case ETCPHYRD2: -+ if (vec) { -+ uint phyaddr, reg; -+ phyaddr = vec[0] >> 16; -+ reg = vec[0] & 0xffff; -+ vec[1] = (*etc->chops->phyrd)(etc->ch, phyaddr, reg); -+ ET_TRACE(("etc_ioctl: ETCPHYRD2 of phy 0x%x, reg 0x%x => 0x%x\n", -+ phyaddr, reg, vec[1])); -+ } -+ break; -+ -+ case ETCPHYWR: -+ if (vec) { -+ ET_TRACE(("etc_ioctl: ETCPHYWR to reg 0x%x <= 0x%x\n", vec[0], vec[1])); -+ (*etc->chops->phywr)(etc->ch, etc->phyaddr, vec[0], (uint16)vec[1]); -+ } -+ break; -+ -+ case ETCPHYWR2: -+ if (vec) { -+ uint phyaddr, reg; -+ phyaddr = vec[0] >> 16; -+ reg = vec[0] & 0xffff; -+ (*etc->chops->phywr)(etc->ch, phyaddr, reg, (uint16)vec[1]); -+ ET_TRACE(("etc_ioctl: ETCPHYWR2 to phy 0x%x, reg 0x%x <= 0x%x\n", -+ phyaddr, reg, vec[1])); -+ } -+ break; -+ -+ default: -+err: -+ error = -1; -+ } -+ -+ return (error); -+} -+ -+/* called once per second */ -+void -+etc_watchdog(etc_info_t *etc) -+{ -+ uint16 status; -+ uint16 lpa; -+ -+#if defined(CONFIG_MACH_WH2) -+ uint32 select = (ioread32(get_iproc_wrap_ctrl_base() + 0xa8)); /* IPROC_WRAP_TOP_STRAP_STATUS_1 */ -+ if (select & 0x04) /* select SGMII path */ -+ { -+ etc->speed = 1000; -+ etc->duplex = 1; -+ etc->linkstate = true; -+ (*etc->chops->duplexupd)(etc->ch); -+ return; -+ } -+#endif -+ etc->now++; -+ -+ /* no local phy registers */ -+ if (etc->phyaddr == EPHY_NOREG) -+ { -+ etc->linkstate = TRUE; -+ etc->duplex = 1; -+ /* keep emac txcontrol duplex bit consistent with current phy duplex */ -+ (*etc->chops->duplexupd)(etc->ch); -+ return; -+ } -+ -+ if (etc->up && etc->linkstate) { -+ if (!(ethup & 1<unit)) { -+ printk(KERN_DEBUG "et%d Interface up\n", etc->unit); -+ } -+ ethup |= 1<unit; -+ } -+ -+#if defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) -+ if ( !gmac_has_mdio_access()) { -+ /* we can't monitor link so force link up */ -+ /* if GMAC does not have access to MDIO then exit */ -+ if (!etc->linkstate) { -+ etc->linkstate = TRUE; -+ etc->duplex = 1; -+ etc->speed = 1000; -+ } -+ /* keep emac txcontrol duplex bit consistent with current phy duplex */ -+ (*etc->chops->duplexupd)(etc->ch); -+ if (!et_is_link_up(etc->et)) { -+ printk(KERN_DEBUG "%s rcan't access PHY, forcing link up\n", __FUNCTION__); -+ et_link_up(etc->et); -+ } -+ return; -+ } -+ -+ /* check if need to release mdio access */ -+ if ((ethup==ethupmask) || (etc->now > etc->mdio_init_time)) { -+ /* either both links up or (5) "eth_init_time" seconds elapsed */ -+ /* keep mdio access if ethtool is set */ -+ char *s = getvar(NULL, "ethtool"); -+ if (!s) { -+#ifdef CONFIG_SERDES_ASYMMETRIC_MODE -+ gmac_serdes_asym_mode(ethupetcptr); -+#endif /* CONFIG_SERDES_ASYMMETRIC_MODE */ -+ printk(KERN_DEBUG "%s releasing MDIO access; ethup(0x%x)\n", __FUNCTION__, ethup); -+ gmac_set_amac_mdio(0); -+ return; -+ } -+ } -+#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) */ -+#endif /* defined(CONFIG_IPROC_SDK_MGT_PORT_HANDOFF) */ -+ -+ status = (*etc->chops->phyrd)(etc->ch, etc->phyaddr, 1); -+ /* check for bad mdio read */ -+ if (status == 0xffff) { -+ ET_ERROR(("et%d: etc_watchdog: bad mdio read: phyaddr %d mdcport %d\n", -+ etc->unit, etc->phyaddr, etc->mdcport)); -+ return; -+ } -+ -+ if (etc->forcespeed == ET_AUTO) { -+ uint16 adv, adv2 = 0, status2 = 0, estatus; -+ -+ adv = (*etc->chops->phyrd)(etc->ch, etc->phyaddr, 4); -+ lpa = (*etc->chops->phyrd)(etc->ch, etc->phyaddr, 5); -+ -+ /* read extended status register. if we are 1000BASE-T -+ * capable then get our advertised capabilities and the -+ * link partner capabilities from 1000BASE-T control and -+ * status registers. -+ */ -+ estatus = (*etc->chops->phyrd)(etc->ch, etc->phyaddr, 15); -+ if ((estatus != 0xffff) && (estatus & EST_1000TFULL)) { -+ /* read 1000BASE-T control and status registers */ -+ adv2 = (*etc->chops->phyrd)(etc->ch, etc->phyaddr, 9); -+ status2 = (*etc->chops->phyrd)(etc->ch, etc->phyaddr, 10); -+ } -+ -+ /* update current speed and duplex */ -+ if ((adv2 & ADV_1000FULL) && (status2 & LPA_1000FULL)) { -+ etc->speed = 1000; -+ etc->duplex = 1; -+ } else if ((adv2 & ADV_1000HALF) && (status2 & LPA_1000HALF)) { -+ etc->speed = 1000; -+ etc->duplex = 0; -+ } else if ((adv & ADV_100FULL) && (lpa & LPA_100FULL)) { -+ etc->speed = 100; -+ etc->duplex = 1; -+ } else if ((adv & ADV_100HALF) && (lpa & LPA_100HALF)) { -+ etc->speed = 100; -+ etc->duplex = 0; -+ } else if ((adv & ADV_10FULL) && (lpa & LPA_10FULL)) { -+ etc->speed = 10; -+ etc->duplex = 1; -+ } else { -+ etc->speed = 10; -+ etc->duplex = 0; -+ } -+ } -+ -+ /* monitor link state */ -+ if (!etc->linkstate && (status & STAT_LINK)) { -+ etc->linkstate = TRUE; -+ if (etc->pm_modechange) { -+ etc->pm_modechange = FALSE; -+ } else { -+ et_link_up(etc->et); -+#ifdef CONFIG_SERDES_ASYMMETRIC_MODE -+ (*etc->chops->forcespddpx)(etc->ch); -+#endif /* CONFIG_SERDES_ASYMMETRIC_MODE */ -+ } -+ } else if (etc->linkstate && !(status & STAT_LINK)) { -+ etc->linkstate = FALSE; -+ if (!etc->pm_modechange) { -+ et_link_down(etc->et); -+ } -+ } -+ -+ /* keep emac txcontrol duplex bit consistent with current phy duplex */ -+ (*etc->chops->duplexupd)(etc->ch); -+ -+ /* check for remote fault error */ -+ if (status & STAT_REMFAULT) { -+ ET_ERROR(("et%d: remote fault\n", etc->unit)); -+ } -+ -+ /* check for jabber error */ -+ if (status & STAT_JAB) { -+ ET_ERROR(("et%d: jabber\n", etc->unit)); -+ } -+ -+ /* -+ * Read chip mib counters occationally before the 16bit ones can wrap. -+ * We don't use the high-rate mib counters. -+ */ -+ if ((etc->now % 30) == 0) { -+ (*etc->chops->statsupd)(etc->ch); -+ } -+} -+ -+static void -+etc_loopback(etc_info_t *etc, int on) -+{ -+ ET_TRACE(("et%d: etc_loopback: %d\n", etc->unit, on)); -+ -+ etc->loopbk = (bool) on; -+ et_init(etc->et, ET_INIT_INTRON); -+} -+ -+void -+etc_promisc(etc_info_t *etc, uint on) -+{ -+ ET_TRACE(("et%d: etc_promisc: %d\n", etc->unit, on)); -+ -+ etc->promisc = (bool) on; -+ et_init(etc->et, ET_INIT_INTRON); -+} -+ -+void -+etc_qos(etc_info_t *etc, uint on) -+{ -+ ET_TRACE(("et%d: etc_qos: %d\n", etc->unit, on)); -+ -+ etc->qos = (bool) on; -+ et_init(etc->et, ET_INIT_INTRON); -+} -+ -+void -+etc_dump(etc_info_t *etc, struct bcmstrbuf *b) -+{ -+ etc_dumpetc(etc, b); -+ (*etc->chops->dump)(etc->ch, b); -+} -+ -+static void -+etc_dumpetc(etc_info_t *etc, struct bcmstrbuf *b) -+{ -+ char perm[32], cur[32]; -+ uint i; -+ -+ bcm_bprintf(b, "etc 0x%x et 0x%x unit %d msglevel %d speed/duplex %d%s\n", -+ (ulong)etc, (ulong)etc->et, etc->unit, et_msg_level, -+ etc->speed, (etc->duplex ? "full": "half")); -+ bcm_bprintf(b, "up %d promisc %d loopbk %d forcespeed %d advertise 0x%x " -+ "advertise2 0x%x needautoneg %d\n", -+ etc->up, etc->promisc, etc->loopbk, etc->forcespeed, -+ etc->advertise, etc->advertise2, etc->needautoneg); -+ bcm_bprintf(b, "piomode %d pioactive 0x%x nmulticast %d allmulti %d qos %d\n", -+ etc->piomode, (ulong)etc->pioactive, etc->nmulticast, etc->allmulti, etc->qos); -+ bcm_bprintf(b, "vendor 0x%x device 0x%x rev %d coreunit %d phyaddr %d mdcport %d\n", -+ etc->vendorid, etc->deviceid, etc->chiprev, -+ etc->coreunit, etc->phyaddr, etc->mdcport); -+ -+ bcm_bprintf(b, "perm_etheraddr %s cur_etheraddr %s\n", -+ bcm_ether_ntoa(&etc->perm_etheraddr, perm), -+ bcm_ether_ntoa(&etc->cur_etheraddr, cur)); -+ -+ if (etc->nmulticast) { -+ bcm_bprintf(b, "multicast: "); -+ for (i = 0; i < etc->nmulticast; i++) { -+ bcm_bprintf(b, "%s ", bcm_ether_ntoa(&etc->multicast[i], cur)); -+ } -+ bcm_bprintf(b, "\n"); -+ } -+ -+ bcm_bprintf(b, "linkstate %d\n", etc->linkstate); -+ bcm_bprintf(b, "\n"); -+ -+ /* refresh stat counters */ -+ (*etc->chops->statsupd)(etc->ch); -+ -+ /* summary stat counter line */ -+ /* use sw frame and byte counters -- hw mib counters wrap too quickly */ -+ bcm_bprintf(b, "txframe %d txbyte %d txerror %d rxframe %d rxbyte %d rxerror %d\n", -+ etc->txframe, etc->txbyte, etc->txerror, -+ etc->rxframe, etc->rxbyte, etc->rxerror); -+ -+ /* transmit & receive stat counters */ -+ /* hardware mib pkt and octet counters wrap too quickly to be useful */ -+ (*etc->chops->dumpmib)(etc->ch, b, FALSE); -+ -+ bcm_bprintf(b, "txnobuf %d reset %d dmade %d dmada %d dmape %d\n", -+ etc->txnobuf, etc->reset, etc->dmade, etc->dmada, etc->dmape); -+ -+ /* hardware mib pkt and octet counters wrap too quickly to be useful */ -+ bcm_bprintf(b, "rxnobuf %d rxdmauflo %d rxoflo %d rxbadlen %d " -+ "rxgiants %d rxoflodiscards %d\n", -+ etc->rxnobuf, etc->rxdmauflo, etc->rxoflo, etc->rxbadlen, -+ etc->rxgiants, etc->rxoflodiscards); -+ -+ bcm_bprintf(b, "chained %d chainedsz1 %d unchained %d maxchainsz %d currchainsz %d\n", -+ etc->chained, etc->chainedsz1, etc->unchained, etc->maxchainsz, -+ etc->currchainsz); -+ -+ bcm_bprintf(b, "\n"); -+} -+ -+uint -+etc_totlen(etc_info_t *etc, void *p) -+{ -+ uint total; -+ -+ total = 0; -+ for (; p; p = PKTNEXT(etc->osh, p)) { -+ total += PKTLEN(etc->osh, p); -+ } -+ return (total); -+} -+ -+#ifdef BCMDBG -+void -+etc_prhdr(char *msg, struct ether_header *eh, uint len, int unit) -+{ -+ char da[32], sa[32]; -+ -+ if (msg && (msg[0] != '\0')) { -+ printf("et%d: %s: ", unit, msg); -+ } else { -+ printf("et%d: ", unit); -+ } -+ -+ printf("dst %s src %s type 0x%04X len %d\n", -+ bcm_ether_ntoa((struct ether_addr *)eh->ether_dhost, da), -+ bcm_ether_ntoa((struct ether_addr *)eh->ether_shost, sa), -+ ntoh16(eh->ether_type), -+ len); -+} -+void -+etc_prhex(char *msg, uchar *buf, uint nbytes, int unit) -+{ -+ if (msg && (msg[0] != '\0')) { -+ printf("et%d: %s:\n", unit, msg); -+ } else { -+ printf("et%d:\n", unit); -+ } -+ -+ prhex(NULL, buf, nbytes); -+} -+#endif /* BCMDBG */ -+ -+int -+etc_gmac_speed(int gmac) -+{ -+ char name[16], *speed; -+ sprintf(name, "et%dspeed", gmac); -+ -+ speed = nvram_get(name); -+ if (speed == NULL) { -+ printf("%s default GMAC%d speed: auto\n", __FUNCTION__, gmac); -+ return ET_AUTO; -+ } -+ -+ if (!strcmp(speed, "2500")) { -+ printf("%s specifing GMAC%d speed: 2500\n", __FUNCTION__, gmac); -+ return ET_2500FULL; -+ } else if (!strcmp(speed, "1000")) { -+ printf("%s specifing GMAC%d speed: 1000\n", __FUNCTION__, gmac); -+ return ET_1000FULL; -+ } else if (!strcmp(speed, "100")) { -+ printf("%s specifing GMAC%d speed: 100\n", __FUNCTION__, gmac); -+ return ET_100FULL; -+ } else if (!strcmp(speed, "10")) { -+ printf("%s specifing GMAC%d speed: 10\n", __FUNCTION__, gmac); -+ return ET_10FULL; -+ } -+ -+ printf("%s default GMAC%d speed: auto\n", __FUNCTION__, gmac); -+ return ET_AUTO; -+} -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/etc.h b/drivers/net/ethernet/broadcom/gmac/src/et/sys/etc.h ---- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/etc.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/etc.h 2017-11-09 17:53:43.902294000 +0800 -@@ -0,0 +1,295 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * Common [OS-independent] header file for -+ * Broadcom BCM47XX 10/100Mbps Ethernet Device Driver -+ * -+ * $Id: etc.h 327582 2012-04-14 05:02:37Z kenlo $ -+ */ -+ -+#ifndef _ETC_H_ -+#define _ETC_H_ -+ -+#include -+ -+#define MAXMULTILIST 32 -+ -+#ifndef ch_t -+#define ch_t void -+#endif -+ -+#define NUMTXQ 1 -+ -+ -+#define TXREC_THR 8 -+ -+#if defined(__ECOS) -+#define IOCBUFSZ 4096 -+#elif defined(__linux__) -+#define IOCBUFSZ 16384 -+#else -+#define IOCBUFSZ 4096 -+#endif -+ -+struct etc_info; /* forward declaration */ -+struct bcmstrbuf; /* forward declaration */ -+ -+/* each chip type supports a set of chip-type-specific ops */ -+struct chops { -+ bool (*id)(uint vendor, uint device); /* return true if match */ -+ void *(*attach)(struct etc_info *etc, void *dev, void *regs); -+ void (*detach)(ch_t *ch); /* free chip private state */ -+ void (*reset)(ch_t *ch); /* chip reset */ -+ void (*init)(ch_t *ch, uint options); /* chip init */ -+ bool (*tx)(ch_t *ch, void *p); /* transmit frame */ -+ void *(*rx)(ch_t *ch); /* receive frame */ -+ void (*rxfill)(ch_t *ch); /* post dma rx buffers */ -+ int (*getintrevents)(ch_t *ch, bool in_isr); /* return intr events */ -+ bool (*errors)(ch_t *ch); /* handle chip errors */ -+ void (*intrson)(ch_t *ch); /* enable chip interrupts */ -+ void (*intrsoff)(ch_t *ch); /* disable chip interrupts */ -+ void (*txreclaim)(ch_t *ch, bool all); /* reclaim transmit resources */ -+ void (*rxreclaim)(ch_t *ch); /* reclaim receive resources */ -+ void (*statsupd)(ch_t *ch); /* update sw stat counters */ -+ void (*dumpmib)(ch_t *ch, struct bcmstrbuf *, bool clear); /* get sw mib counters */ -+ void (*enablepme)(ch_t *ch); /* enable PME */ -+ void (*disablepme)(ch_t *ch); /* disable PME */ -+ void (*phyreset)(ch_t *ch); /* reset phy */ -+ uint16 (*phyrd)(ch_t *ch, uint phyaddr, uint reg); /* read phy register */ -+ void (*phywr)(ch_t *ch, uint phyaddr, uint reg, uint16 val); /* write phy register */ -+ void (*dump)(ch_t *ch, struct bcmstrbuf *b); /* debugging output */ -+ void (*longname)(ch_t *ch, char *buf, uint bufsize); /* return descriptive name */ -+ void (*duplexupd)(ch_t *ch); /* keep mac duplex consistent */ -+#if defined(CONFIG_SERDES_ASYMMETRIC_MODE) -+ void (*forcespddpx)(ch_t *ch); /* force the speed and duplex */ -+#endif /* (defined(CONFIG_SERDES_ASYMMETRIC_MODE)) */ -+ void (*phyenable)(ch_t *ch, uint eth_num, uint phyaddr, int enable); /* enable phy */ -+}; -+ -+/* -+ * "Common" os-independent software state structure. -+ */ -+typedef struct etc_info { -+ void *et; /* pointer to os-specific private state */ -+ uint unit; /* device instance number */ -+ void *osh; /* pointer to os handler */ -+ bool pktc; /* packet chaining enabled or not */ -+ int pktcbnd; /* max # of packets to chain */ -+ void *mib; /* pointer to s/w maintained mib counters */ -+ bool up; /* interface up and running */ -+ bool promisc; /* promiscuous destination address */ -+ bool qos; /* QoS priority determination on rx */ -+ bool loopbk; /* loopback override mode */ -+ -+ int forcespeed; /* disable autonegotiation and force speed/duplex */ -+ uint advertise; /* control speed/duplex advertised caps */ -+ uint advertise2; /* control gige speed/duplex advertised caps */ -+ bool needautoneg; /* request restart autonegotiation */ -+ int speed; /* current speed: 10, 100 */ -+ int duplex; /* current duplex: 0=half, 1=full */ -+ -+ bool piomode; /* enable programmed io (!dma) */ -+ void *pioactive; /* points to pio packet being transmitted */ -+ volatile uint *txavail[NUMTXQ]; /* dma: # tx descriptors available */ -+ -+ uint16 vendorid; /* pci function vendor id */ -+ uint16 deviceid; /* pci function device id */ -+ uint chip; /* chip number */ -+ uint chiprev; /* chip revision */ -+ uint coreid; /* core id */ -+ uint corerev; /* core revision */ -+ -+ bool nicmode; /* is this core using its own pci i/f */ -+ -+ struct chops *chops; /* pointer to chip-specific opsvec */ -+ void *ch; /* pointer to chip-specific state */ -+ void *robo; /* optional robo private data */ -+ -+ uint txq_state; /* tx queues state bits */ -+ uint coreunit; /* sb chips: chip enet instance # */ -+ uint phyaddr; /* mdio 5-bit phy address for external phy */ -+ uint int_phyaddr; /* mdio 5-bit phy address for internal serdes*/ -+ uint mdcport; /* sb chips: which mii to use (enet core #) to access phy */ -+ -+ struct ether_addr cur_etheraddr; /* our local ethernet address */ -+ struct ether_addr perm_etheraddr; /* original sprom local ethernet address */ -+ -+ struct ether_addr multicast[MAXMULTILIST]; -+ uint nmulticast; -+ bool allmulti; /* enable all multicasts */ -+ -+ bool linkstate; /* link integrity state */ -+ bool pm_modechange; /* true if mode change is to due pm */ -+ -+ uint32 now; /* elapsed seconds */ -+ -+ uint32 boardflags; /* board flags */ -+ uint32 txrec_thresh; /* # of tx frames after which reclaim is done */ -+ uint32 switch_mode; /* switch mode */ -+ -+ uint32 mdio_init_time; /* # of seconds to wait before release mdio bus */ -+ -+#ifdef GMAC_RATE_LIMITING -+ /* rate limiting */ -+ bool rl_enabled; /* enable rate limiting logic */ -+ struct timer_list rl_timer; /* one second ratelimiting timer */ -+ bool rl_set; /* indicate the timer is set or not */ -+ uint32 rl_stopping_all_packets; -+ uint32 rl_stopping_broadcasts; -+ uint32 rl_dropped_all_packets; -+ uint32 rl_dropped_bc_packets; -+ uint32 rl_dropped_packets; -+ uint32 rl_prior_jiffies; -+ uint32 rx_bc_frame_cnt; -+#endif /* GMAC_RATE_LIMITING */ -+ -+ /* sw-maintained stat counters */ -+ uint32 txframes[NUMTXQ]; /* transmitted frames on each tx fifo */ -+ uint32 txframe; /* transmitted frames */ -+ uint32 txbyte; /* transmitted bytes */ -+ uint32 rxframe; /* received frames */ -+ uint32 rxbyte; /* received bytes */ -+ uint32 txerror; /* total tx errors */ -+ uint32 txnobuf; /* tx out-of-buffer errors */ -+ uint32 rxerror; /* total rx errors */ -+ uint32 rxgiants; /* total rx giant frames */ -+ uint32 rxnobuf; /* rx out-of-buffer errors */ -+ uint32 reset; /* reset count */ -+ uint32 dmade; /* pci descriptor errors */ -+ uint32 dmada; /* pci data errors */ -+ uint32 dmape; /* descriptor protocol error */ -+ uint32 rxdmauflo; /* receive descriptor underflow */ -+ uint32 rxoflo; /* receive fifo overflow */ -+ uint32 txuflo; /* transmit fifo underflow */ -+ uint32 rxoflodiscards; /* frames discarded during rx fifo overflow */ -+ uint32 rxbadlen; /* 802.3 len field != read length */ -+ uint32 chained; /* number of frames chained */ -+ uint32 chainedsz1; /* number of chain size 1 frames */ -+ uint32 unchained; /* number of frames not chained */ -+ uint32 maxchainsz; /* max chain size so far */ -+ uint32 currchainsz; /* current chain size */ -+ /* my counters */ -+ uint32 txfrm; /* tx frames */ -+ uint32 txfrmdropped; /* tx dropped frames */ -+ uint32 txqlen; -+ uint32 txqstop; -+ uint32 txdmafull; -+ uint32 txmaxlen; -+ uint32 txsgpkt; -+ uint32 rxquota; -+ uint32 rxdmastopped; -+} etc_info_t; -+ -+/* interrupt event bitvec */ -+#define INTR_TX 0x1 -+#define INTR_RX 0x2 -+#define INTR_ERROR 0x4 -+#define INTR_TO 0x8 -+#define INTR_NEW 0x10 -+ -+/* forcespeed values */ -+#define ET_AUTO -1 -+#define ET_10HALF 0 -+#define ET_10FULL 1 -+#define ET_100HALF 2 -+#define ET_100FULL 3 -+#define ET_1000HALF 4 -+#define ET_1000FULL 5 -+#define ET_2500FULL 6 /* 2.5Gigabit */ -+ -+/* init options */ -+#define ET_INIT_FULL 0x1 -+#define ET_INIT_INTRON 0x2 -+ -+/* Specific init options for et_init */ -+#define ET_INIT_DEF_OPTIONS (ET_INIT_FULL | ET_INIT_INTRON) -+#define ET_INIT_INTROFF (ET_INIT_FULL) -+#define ET_INIT_PARTIAL (0) -+ -+/* macro to safely clear the UP flag */ -+#define ET_FLAG_DOWN(x) (*(x)->chops->intrsoff)((x)->ch); \ -+ (x)->up = FALSE; -+ -+/* -+ * Least-common denominator rxbuf start-of-data offset: -+ * Must be >= size of largest rxhdr -+ * Must be 2-mod-4 aligned so IP is 0-mod-4 -+ */ -+#define HWRXOFF 30 -+ -+#define TC_BK 0 /* background traffic class */ -+#define TC_BE 1 /* best effort traffic class */ -+#define TC_CL 2 /* controlled load traffic class */ -+#define TC_VO 3 /* voice traffic class */ -+#define TC_NONE -1 /* traffic class none */ -+ -+#define RX_Q0 0 /* receive DMA queue */ -+#define NUMRXQ 1 /* gmac has one rx queue */ -+ -+#define TX_Q0 TC_BK /* DMA txq 0 */ -+#define TX_Q1 TC_BE /* DMA txq 1 */ -+#define TX_Q2 TC_CL /* DMA txq 2 */ -+#define TX_Q3 TC_VO /* DMA txq 3 */ -+ -+static inline uint32 -+etc_up2tc(uint32 up) -+{ -+ extern uint32 up2tc[]; -+ return (up2tc[up]); -+} -+ -+static inline uint32 -+etc_priq(uint32 txq_state) -+{ -+ extern uint32 priq_selector[]; -+ return (priq_selector[txq_state]); -+} -+ -+/* rx header flags bits */ -+#define RXH_FLAGS(etc, rxh) (((etc)->coreid == GMAC_CORE_ID) ? \ -+ ((((bcmgmacrxh_t *)(rxh))->flags) & htol16(GRXF_CRC | GRXF_OVF | GRXF_OVERSIZE)) : \ -+ ((((bcmenetrxh_t *)(rxh))->flags) & htol16(RXF_NO | RXF_RXER | RXF_CRC | RXF_OV))) -+ -+#define RXH_OVERSIZE(etc, rxh) (((etc)->coreid == GMAC_CORE_ID) ? \ -+ (ltoh16(((bcmgmacrxh_t *)(rxh))->flags) & GRXF_OVERSIZE) : FALSE) -+ -+#define RXH_PT(etc, rxh) (ltoh16(((bcmgmacrxh_t *)(rxh))->flags) & GRXF_PT_MASK) -+ -+#define RXH_CRC(etc, rxh) (((etc)->coreid == GMAC_CORE_ID) ? \ -+ (ltoh16(((bcmgmacrxh_t *)(rxh))->flags) & GRXF_CRC) : \ -+ (ltoh16(((bcmenetrxh_t *)(rxh))->flags) & RXF_CRC)) -+ -+#define RXH_OVF(etc, rxh) (((etc)->coreid == GMAC_CORE_ID) ? \ -+ (ltoh16(((bcmgmacrxh_t *)(rxh))->flags) & GRXF_OVF) : \ -+ (ltoh16(((bcmenetrxh_t *)(rxh))->flags) & RXF_OV)) -+ -+#define RXH_RXER(etc, rxh) (((etc)->coreid == GMAC_CORE_ID) ? \ -+ FALSE : (ltoh16(((bcmenetrxh_t *)(rxh))->flags) & RXF_RXER)) -+ -+#define RXH_NO(etc, rxh) (((etc)->coreid == GMAC_CORE_ID) ? \ -+ FALSE : (ltoh16(((bcmenetrxh_t *)(rxh))->flags) & RXF_NO)) -+ -+/* Used for fa+ error determination */ -+#define RXH_CTFERROR(etc, rxh) (((etc)->coreid == GMAC_CORE_ID) ? \ -+ (ltoh16(((bcmenetrxh_t *)(rxh))->flags) & (GRXF_CTFERR | GRXF_CRC | GRXF_OVF)) : FALSE) -+ -+#define ET_GMAC(etc) ((etc)->coreid == GMAC_CORE_ID) -+ -+/* exported prototypes */ -+extern struct chops *etc_chipmatch(uint vendor, uint device); -+extern void *etc_attach(void *et, uint vendor, uint device, uint unit, void *dev, void *regsva); -+extern void etc_detach(etc_info_t *etc); -+extern void etc_reset(etc_info_t *etc); -+extern void etc_init(etc_info_t *etc, uint options); -+extern void etc_up(etc_info_t *etc); -+extern uint etc_down(etc_info_t *etc, int reset); -+extern int etc_ioctl(etc_info_t *etc, int cmd, void *arg); -+extern int etc_iovar(etc_info_t *etc, uint cmd, uint set, void *arg); -+extern void etc_promisc(etc_info_t *etc, uint on); -+extern void etc_qos(etc_info_t *etc, uint on); -+extern void etc_dump(etc_info_t *etc, struct bcmstrbuf *b); -+extern void etc_watchdog(etc_info_t *etc); -+extern uint etc_totlen(etc_info_t *etc, void *p); -+extern void etc_robomib(etc_info_t *etc); -+ -+#endif /* _ETC_H_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/etcgmac.c b/drivers/net/ethernet/broadcom/gmac/src/et/sys/etcgmac.c ---- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/etcgmac.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/etcgmac.c 2017-11-09 17:53:43.904292000 +0800 -@@ -0,0 +1,2593 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * Broadcom Gigabit Ethernet MAC (Unimac) core. -+ * This file implements the chip-specific routines for the GMAC core. -+ * -+ * $Id: etcgmac.c 327582 2012-04-14 05:02:37Z kenlo $ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include /* for et_phyxx() routines */ -+#include -+#include -+#include -+#include "bcmiproc_phy.h" -+ -+#define ENABLE_MIB_REG_DUMP -+ -+/* MDIO address definitation */ -+#if defined(CONFIG_MACH_HR3) -+#if defined(CONFIG_MACH_WH2) -+#define GMAC_EXT_PHY_ADDR 0x18 -+#define GMAC_INT_PHY_ADDR 0x14 -+#else -+#define GMAC_EXT_PHY_ADDR 0x18 -+#define GMAC_INT_PHY_ADDR 0xFF -+#endif -+#elif defined(CONFIG_MACH_GH) -+#define GMAC_EXT_PHY_ADDR 0x18 -+#define GMAC_INT_PHY_ADDR 0xFF -+#elif defined(CONFIG_MACH_GH2) -+#define GMAC_EXT_PHY_ADDR 0x10 -+#define GMAC_INT_PHY_ADDR 0x19 -+#else -+#define GMAC_EXT_PHY_ADDR 0x01 -+#define GMAC_INT_PHY_ADDR 0x01 -+#endif -+ -+ -+extern void __iomem *get_iproc_wrap_ctrl_base(void); -+extern void __iomem *get_iproc_idm_base(int index); -+#if defined (CONFIG_MACH_KT2) -+#define IPROC_WRAP_MISC_CONTROL_OFFSET 0x24 -+#elif (defined (CONFIG_MACH_HX4) || defined (CONFIG_MACH_HR2)) -+#define IPROC_WRAP_MISC_CONTROL_OFFSET 0x3C -+#else -+#define IPROC_WRAP_MISC_CONTROL_OFFSET 0x40 -+#endif -+ -+static const u32 idm_ioctl_offset[] = { -+ 0x10408, -+#if defined (CONFIG_MACH_HX4) || defined (CONFIG_MACH_KT2) -+ 0x11408, -+#elif defined (CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) -+ 0x1f408, -+#endif -+}; -+#define AMAC_IDM_IO_CONTROL_DIRECT__CLK_250_SEL 6 -+#define AMAC_IDM_IO_CONTROL_DIRECT__DIRECT_GMII_MODE 5 -+#define AMAC_IDM_IO_CONTROL_DIRECT__DEST_SYNC_MODE_EN 3 -+ -+#if defined(CONFIG_MACH_HX4) -+#define IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_MDIO_SEL 3 -+#define IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_CTRL_SEL 2 -+#define IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL 4 -+#endif /* defined(CONFIG_MACH_HX4) */ -+ -+#if defined(CONFIG_MACH_KT2) -+#define IPROC_WRAP_MISC_CONTROL__UNICORE_SERDES_CTRL_SEL 1 -+#define IPROC_WRAP_MISC_CONTROL__UNICORE_SERDES_MDIO_SEL 2 -+#define IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL 3 -+#endif /* defined(CONFIG_MACH_KT2) */ -+ -+#if defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_WH2) -+#define IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL 1 -+#endif /* defined(CONFIG_MACH_SB2) */ -+ -+ -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) -+#include "bcmiproc_serdes.h" -+#include "bcmiproc_phy5461s.h" -+#elif defined(CONFIG_MACH_GH2) -+#include "sgmiiplus2_serdes.h" -+#include "phy542xx.h" -+#elif defined(CONFIG_MACH_HR3) -+#if defined(CONFIG_MACH_WH2) -+#include "../../../mdio/iproc_mdio.h" -+#include "sgmiiplus2_serdes.h" -+#include "bcmiproc_egphy28.h" -+#include -+#define IPROC_CMICD_COMPATIBLE "brcm,iproc-cmicd" -+#define CMIC_SBUS_RING_MAP_0_7(base) (base + 0x10098) -+#define CMIC_SBUS_RING_MAP_8_15(base) (base + 0x1009C) -+#define CMIC_SBUS_RING_MAP_16_23(base) (base + 0x100A0) -+#define CMIC_SBUS_RING_MAP_24_31(base) (base + 0x100A4) -+extern u32 cmicd_schan_read(void __iomem *base, u32 ctrl, u32 addr); -+extern u32 cmicd_schan_write(void __iomem *base, u32 ctrl, u32 addr, u32 val); -+extern int egphy28_init(void __iomem *base, u32 phy_addr); -+#else -+#include "bcmiproc_phy5481.h" -+#endif -+#elif defined(CONFIG_MACH_HR2) -+#include "bcmiproc_phy5221.h" -+#elif defined(CONFIG_MACH_GH) -+#include "bcmiproc_phy5481.h" -+#endif -+ -+ -+#if !defined(CONFIG_MACH_HR2) -+/* BCM5221 on HR2 board does not support this feature */ -+#define CONFIG_FORCED_MODE_AUTO_MDIX 1 -+#endif -+ -+struct bcmgmac; /* forward declaration */ -+#define ch_t struct bcmgmac -+#include -+ -+extern int nvram_env_gmac_name(int gmac, char *name); -+ -+/* private chip state */ -+struct bcmgmac { -+ void *et; /* pointer to et private state */ -+ etc_info_t *etc; /* pointer to etc public state */ -+ -+ gmac_commonregs_t *regscomm; /* pointer to GMAC COMMON registers */ -+ gmacregs_t *regs; /* pointer to chip registers */ -+ osl_t *osh; /* os handle */ -+ -+ void *etphy; /* pointer to et for shared mdc/mdio contortion */ -+ -+ uint32 intstatus; /* saved interrupt condition bits */ -+ uint32 intmask; /* current software interrupt mask */ -+ uint32 def_intmask;/* default interrupt mask */ -+ -+ hnddma_t *di[NUMTXQ];/* dma engine software state */ -+ -+ bool mibgood; /* true once mib registers have been cleared */ -+ gmacmib_t mib; /* mib statistic counters */ -+ si_t *sih; /* si utils handle */ -+ -+ char *vars; /* sprom name=value */ -+ uint vars_size; -+ -+ void *adm; /* optional admtek private data */ -+ mcfilter_t mf; /* multicast filter */ -+}; -+ -+/* local prototypes */ -+static bool chipid(uint vendor, uint device); -+static void *chipattach(etc_info_t *etc, void *osh, void *regsva); -+static void chipdetach(ch_t *ch); -+static void chipreset(ch_t *ch); -+static void chipinit(ch_t *ch, uint options); -+static bool chiptx(ch_t *ch, void *p); -+static void *chiprx(ch_t *ch); -+static void chiprxfill(ch_t *ch); -+static int chipgetintrevents(ch_t *ch, bool in_isr); -+static bool chiperrors(ch_t *ch); -+static void chipintrson(ch_t *ch); -+static void chipintrsoff(ch_t *ch); -+static void chiptxreclaim(ch_t *ch, bool all); -+static void chiprxreclaim(ch_t *ch); -+static void chipstatsupd(ch_t *ch); -+static void chipdumpmib(ch_t *ch, struct bcmstrbuf *b, bool clear); -+static void chipenablepme(ch_t *ch); -+static void chipdisablepme(ch_t *ch); -+static void chipphyreset(ch_t *ch); -+static uint16 chipphyrd(ch_t *ch, uint phyaddr, uint reg); -+static void chipphywr(ch_t *ch, uint phyaddr, uint reg, uint16 val); -+static void chipdump(ch_t *ch, struct bcmstrbuf *b); -+static void chiplongname(ch_t *ch, char *buf, uint bufsize); -+static void chipduplexupd(ch_t *ch); -+#ifdef CONFIG_SERDES_ASYMMETRIC_MODE -+static void chipforcespddpx(ch_t *ch); -+#endif /* CONFIG_SERDES_ASYMMETRIC_MODE */ -+ -+static void chipphyinit(ch_t *ch); -+static void chipphyor(ch_t *ch, uint phyaddr, uint reg, uint16 v); -+static void chipphyforce(ch_t *ch, uint phyaddr); -+static void chipphyadvertise(ch_t *ch, uint phyaddr); -+static void chipphyenable(ch_t *ch, uint eth_num, uint phyaddr, int enable); -+static void chipdumpregs(ch_t *ch, gmacregs_t *regs, struct bcmstrbuf *b); -+static void gmac_mf_cleanup(ch_t *ch); -+static int gmac_speed(ch_t *ch, uint32 speed); -+#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ -+ defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) || defined(CONFIG_MACH_WH2) -+static void gmac_serdes_init(ch_t *ch); -+#endif -+static void gmac_miiconfig(ch_t *ch); -+ -+struct chops bcmgmac_et_chops = { -+ chipid, -+ chipattach, -+ chipdetach, -+ chipreset, -+ chipinit, -+ chiptx, -+ chiprx, -+ chiprxfill, -+ chipgetintrevents, -+ chiperrors, -+ chipintrson, -+ chipintrsoff, -+ chiptxreclaim, -+ chiprxreclaim, -+ chipstatsupd, -+ chipdumpmib, -+ chipenablepme, -+ chipdisablepme, -+ chipphyreset, -+ chipphyrd, -+ chipphywr, -+ chipdump, -+ chiplongname, -+ chipduplexupd, -+#ifdef CONFIG_SERDES_ASYMMETRIC_MODE -+ chipforcespddpx, -+#endif /* CONFIG_SERDES_ASYMMETRIC_MODE */ -+ chipphyenable -+}; -+ -+static uint devices[] = { -+ BCM56150_CHIP_ID, -+ BCM56340_CHIP_ID, -+ BCM56450_CHIP_ID, -+ BCM53400_CHIP_ID, -+ BCM56260_CHIP_ID, -+ BCM56160_CHIP_ID, -+ BCM56170_CHIP_ID, -+ BCM53540_CHIP_ID, -+ 0x0000 -+}; -+ -+ -+#if defined(CONFIG_MACH_WH2) -+static uint32 select = 0x06; -+ -+static void -+cmid_schan_modify(void __iomem *base, u32 ctrl, u32 addr, u32 val, u32 mask) -+{ -+ u32 ori_val; -+ -+ ori_val = cmicd_schan_read(base, ctrl, addr); -+ ori_val &= ~mask; -+ ori_val |= (val & mask); -+ cmicd_schan_write(base, ctrl + 0x08000000, addr, ori_val); -+} -+ -+static void power_on_serdesphy(ch_t *ch) -+{ -+ void __iomem *base; -+ uint32 val; -+ int i; -+ -+ select = (ioread32(get_iproc_wrap_ctrl_base() + 0xa8)); /* IPROC_WRAP_TOP_STRAP_STATUS_1 */ -+ base = of_iomap(of_find_compatible_node(NULL, NULL, IPROC_CMICD_COMPATIBLE), 0); -+ //* Configure SBUS Ring Map for TOP, block id = 16, ring number = 4 */ -+ writel(0x00000000, CMIC_SBUS_RING_MAP_0_7(base)); -+ writel(0x00430000, CMIC_SBUS_RING_MAP_8_15(base)); -+ writel(0x00005064, CMIC_SBUS_RING_MAP_16_23(base)); -+ writel(0x00000000, CMIC_SBUS_RING_MAP_24_31(base)); -+ -+ if (select & 0x04) /* select Serdes (SGMII Plus2) path */ -+ { -+ printf("AMAC selects SGMII path... \n"); -+ -+ /* Reset TOP_SGMII_CTRL_REG through S-Channel */ -+ /* bit 2 (RSTB_HW) & 3 (IDDQ) & 4 (PWRDWN) = 0 */ -+ cmid_schan_modify(base, 0x2c800200, 0x0207e800, 0x0, 0x0000001c); -+ /* bit 2 (RSTB_HW) & 1 (RSTB_MDIOREGS) & 0 (RSTB_PLL) = 1 */ -+ cmid_schan_modify(base, 0x2c800200, 0x0207e800, 0x00000007, 0x00000007); -+ -+ /* Hardware reset 4th lane. PHY addr = 0x17, Reg addr = 0x0000, bit 15 = 1 */ -+ val = chipphyrd(ch, GMAC_INT_PHY_ADDR, 0x0000); -+ val |= (1 << 15); -+ chipphywr(ch, GMAC_INT_PHY_ADDR, 0x0000, val); -+ -+ /* Power down other 3 lanes. PHY addr = (0x14, 0x15, 0x16) */ -+ for (i = 0; i < 3; ++i) -+ { -+ val = chipphyrd(ch, GMAC_INT_PHY_ADDR + i, 0x0); -+ val |= (1 << 11); -+ chipphywr(ch, GMAC_INT_PHY_ADDR + i, 0x0, val); -+ } -+ } else /* select EGPHY28 path */ -+ { -+ printf("AMAC selects EGPHY path... \n"); -+ -+ /* TOP_QGPHY_CTRL_0.EXT_PWRDOWN[23:20] = HIGH */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033800, 0x00F00000, 0x00F00000); -+ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x040000); -+ /* TOP_QGPHY_CTRL_2.IDDQ_BIAS[5] = HIGH */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x20, 0x20); -+ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = HIGH */ -+ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x200000, 0x200000); -+ -+ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = HIGH */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x040000, 0x040000); -+ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x0, 0x200000); -+ /* Reset TOP_SOFT_RESET_REG bit 4 (GXP2_RST) & 5 (GXP0_RST) & 6 (GXP1_RST) = 0 */ -+ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x0, 0x00000070); -+ -+ mdelay(100); -+ -+ /* Give initial value */ -+ /* TOP_QGPHY_CTRL_0.EXT_PWRDOWN[23:20] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033800, 0x0, 0x00F00000); -+ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = HIGH */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x40000, 0x040000); -+ /* TOP_QGPHY_CTRL_2.IDDQ_BIAS[5] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x20); -+ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x0, 0x200000); -+ -+ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x040000); -+ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = HIGH */ -+ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x200000, 0x200000); -+ /* Reset TOP_SOFT_RESET_REG bit 4 (GXP2_RST) & 5 (GXP0_RST) & 6 (GXP1_RST) = 1 */ -+ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x00000070, 0x00000070); -+ } -+} -+#endif -+ -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) -+static void *wrapaddr = 0; -+void gmac_set_amac_mdio(int en) -+{ -+ u32 tmp; -+#if defined(CONFIG_MACH_HX4) -+ u32 mdio_sel= IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_MDIO_SEL; -+ u32 ctrl_sel= IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_CTRL_SEL; -+#elif defined(CONFIG_MACH_KT2) -+ u32 mdio_sel= IPROC_WRAP_MISC_CONTROL__UNICORE_SERDES_MDIO_SEL; -+ u32 ctrl_sel= IPROC_WRAP_MISC_CONTROL__UNICORE_SERDES_CTRL_SEL; -+#endif -+ u32 iproc_mdio_sel= IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL; -+ -+ if (en) { -+ /* Get register base address */ -+ wrapaddr = get_iproc_wrap_ctrl_base() + IPROC_WRAP_MISC_CONTROL_OFFSET; -+ } -+ -+ tmp = ioread32(wrapaddr); -+ if (en) { -+#if defined(CONFIG_MACH_SB2) -+ /* set bits IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL -+ so AMAC can access the Serdes and Phy */ -+ tmp |= (1 << iproc_mdio_sel); -+#else -+ /* set bits IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL, -+ IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_MDIO_SEL & -+ IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_CTRL_SEL -+ so AMAC can access the Serdes and Phy */ -+ tmp |= ((1 << mdio_sel) | (1 << ctrl_sel) | (1 << iproc_mdio_sel)); -+#endif -+ } else { -+#if defined(CONFIG_MACH_SB2) -+ /* clear bits IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL -+ so CMIC can access the Serdes and Phy */ -+ tmp &= ~(1 << iproc_mdio_sel); -+#else -+ /* clear bits IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL & -+ IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_MDIO_SEL -+ so CMIC can access the Serdes and Phy */ -+ tmp &= ~((1 << mdio_sel) | (1 << iproc_mdio_sel)); -+#endif -+ } -+ iowrite32(tmp, wrapaddr); -+ -+ if (!en) { -+ wrapaddr=0; -+ } -+} -+ -+int gmac_has_mdio_access(void) -+{ -+ u32 tmp; -+ u32 regmsk = (1 << IPROC_WRAP_MISC_CONTROL__IPROC_MDIO_SEL); -+ -+#if defined(CONFIG_MACH_HX4) -+ regmsk |= ((1 << IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_MDIO_SEL) | -+ (1 << IPROC_WRAP_MISC_CONTROL__QUAD_SERDES_CTRL_SEL)); -+#elif defined(CONFIG_MACH_KT2) -+ regmsk |= ((1 << IPROC_WRAP_MISC_CONTROL__UNICORE_SERDES_MDIO_SEL) | -+ (1 << IPROC_WRAP_MISC_CONTROL__UNICORE_SERDES_CTRL_SEL)); -+#endif -+ -+ if (wrapaddr==0) { -+ /* if no wrapaddr then no access */ -+ return 0; -+ } -+ -+ tmp = ioread32(wrapaddr); -+ tmp &= ~regmsk; -+ if (tmp == regmsk) { -+ return 0; -+ } -+ -+ return 1; -+} -+#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) */ -+ -+/* This api will determine if this unit specified is the last interface. */ -+bool gmac_last_interface(int unit) -+{ -+ char name[128]; -+ int idx; -+ -+ /* if interface 2 or greater then must be last */ -+ if (unit >= 2) { -+ return true; -+ } -+ -+ /* Look to see if there is a next interface specified */ -+ for (idx = unit + 1; idx <= 2; idx++) { -+ nvram_env_gmac_name(idx, name); -+ if (getvar(NULL, name) != NULL) { -+ /* there is a next interface */ -+ return false; -+ } -+ } -+ /* no other interfaces */ -+ return true; -+} -+ -+ -+static bool -+chipid(uint vendor, uint device) -+{ -+ int idx; -+ -+ if (vendor != VENDOR_BROADCOM) { -+ ET_ERROR(("%s ERROR: NOT a BROADCOM Vendor ID (0x%x)\n", __FUNCTION__, vendor)); -+ return (FALSE); -+ } -+ -+ for (idx = 0; devices[idx]; idx++) { -+ if (device == devices[idx]) { -+ return (TRUE); -+ } -+ } -+ -+ ET_ERROR(("%s ERROR: UNKNOWN Device ID (0x%x)\n", __FUNCTION__, device)); -+ printk("%s ERROR: UNKNOWN Device ID (0x%x)\n", __FUNCTION__, device); -+ return (FALSE); -+} -+ -+static void * -+chipattach(etc_info_t *etc, void *osh, void *regsva) -+{ -+ ch_t *ch; -+ gmacregs_t *regs; -+ void *amacidmaddr; -+ uint32 idx, tmp; -+ char name[16], *var; -+ uint boardflags, boardtype; -+ uint coreidx; -+ ulong flags; -+ -+ ET_TRACE(("et%d: chipattach: regsva 0x%lx\n", etc->unit, (ulong)regsva)); -+ -+ if ((ch = (ch_t *)MALLOC(osh, sizeof(ch_t))) == NULL) { -+ ET_ERROR(("et%d: chipattach: out of memory, malloced %d bytes\n", etc->unit, MALLOCED(osh))); -+ return (NULL); -+ } -+ bzero((char *)ch, sizeof(ch_t)); -+ -+ ch->etc = etc; -+ ch->et = etc->et; -+ ch->osh = osh; -+ -+ /* store the pointer to the sw mib */ -+ etc->mib = (void *)&ch->mib; -+ -+ /* get si handle */ -+ if ((ch->sih = si_attach(etc->deviceid, ch->osh, regsva, SI_BUS, NULL, &ch->vars, -+ &ch->vars_size)) == NULL) { -+ ET_ERROR(("et%d: chipattach: si_attach error\n", etc->unit)); -+ goto fail; -+ } -+ -+ if ((regs = (gmacregs_t *)si_setcore(ch->sih, GMAC_CORE_ID, etc->unit)) == NULL) { -+ ET_ERROR(("et%d: chipattach: Could not setcore to GMAC\n", etc->unit)); -+ goto fail; -+ } -+ -+ /* 2G_ENABLED: Enable IDM 250MHz for 2G mode */ -+ spin_lock_irqsave((spinlock_t *)&ch->sih->sih_lock, flags); -+ -+ coreidx = si_coreidx(ch->sih); -+ si_core_reset(ch->sih, 0, 0); -+ si_setcoreidx(ch->sih, coreidx); -+ -+ spin_unlock_irqrestore((spinlock_t *)&ch->sih->sih_lock, flags); -+ -+ ch->regs = regs; -+ etc->chip = ch->sih->chip; -+ etc->chiprev = ch->sih->chiprev; -+ etc->coreid = si_coreid(ch->sih); -+ etc->nicmode = !(ch->sih->bustype == SI_BUS); -+ etc->coreunit = si_coreunit(ch->sih); -+ etc->boardflags = getintvar(ch->vars, "boardflags"); -+ -+ boardflags = etc->boardflags; -+ boardtype = ch->sih->boardtype; -+ -+ etc->switch_mode = 0; -+ -+ /* -+ * Too much can go wrong in scanning MDC/MDIO playing "whos my phy?" . -+ * Instead, explicitly require the environment var "etphyaddr=". -+ */ -+ -+ /* get our phyaddr value */ -+ sprintf(name, "et%dphyaddr", etc->coreunit); -+ var = getvar(NULL, name); -+ if (var == NULL) { -+ etc->phyaddr = etc->unit + GMAC_EXT_PHY_ADDR; -+ etc->int_phyaddr = etc->unit + GMAC_INT_PHY_ADDR; -+ } else { -+ etc->phyaddr = bcm_atoi(var) & EPHY_MASK; -+ etc->int_phyaddr = etc->unit + GMAC_INT_PHY_ADDR; -+ } -+ printf("et%d: chipattach: phyaddr(0x%x)\n", etc->unit, etc->phyaddr); -+ -+ /* nvram says no phy is present */ -+ if (etc->phyaddr == EPHY_NONE) { -+ ET_ERROR(("et%d: chipattach: phy not present\n", etc->unit)); -+ goto fail; -+ } -+ -+ /* reset the gmac core */ -+ chipreset(ch); -+ -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) -+ /* flip switch so AMAC can access serdes */ -+ if (wrapaddr == 0) { -+ gmac_set_amac_mdio(1); -+ } -+#elif defined(CONFIG_MACH_WH2) -+ /* power on SGMII/EGPHY most before chipphyreset() to read PHY ID */ -+ power_on_serdesphy(ch); -+#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) */ -+ -+ /* Get register base address */ -+ amacidmaddr = get_iproc_idm_base(0) + idm_ioctl_offset[etc->unit]; -+ tmp = ioread32(amacidmaddr); -+ tmp &= ~(1 << AMAC_IDM_IO_CONTROL_DIRECT__CLK_250_SEL); -+ tmp |= (1 << AMAC_IDM_IO_CONTROL_DIRECT__DIRECT_GMII_MODE); -+ tmp |= (1 << AMAC_IDM_IO_CONTROL_DIRECT__DEST_SYNC_MODE_EN); -+ iowrite32(tmp, amacidmaddr); -+ -+#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ -+ defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) -+ /* enable serdes */ -+ gmac_serdes_init(ch); -+#elif defined(CONFIG_MACH_WH2) -+ if (select & 0x04) /* select Serdes (SGMII Plus2) path */ -+ gmac_serdes_init(ch); -+#endif -+ -+ /* dma attach */ -+ sprintf(name, "et%d", etc->coreunit); -+ -+ /* allocate dma resources for txqs */ -+ /* TX: TC_BK, RX: RX_Q0 */ -+ ch->di[0] = dma_attach(osh, name, ch->sih, -+ DMAREG(ch, DMA_TX, TX_Q0), -+ DMAREG(ch, DMA_RX, RX_Q0), -+ NTXD, NRXD, RXBUFSZ, -1, NRXBUFPOST, HWRXOFF, -+ &et_msg_level); -+ -+ for (idx = 0; idx < NUMTXQ; idx++) { -+ if (ch->di[idx] == NULL) { -+ ET_ERROR(("et%d: chipattach: dma_attach failed\n", etc->unit)); -+ goto fail; -+ } -+ } -+ -+ for (idx = 0; idx < NUMTXQ; idx++) { -+ if (ch->di[idx] != NULL) { -+ etc->txavail[idx] = (uint *)&ch->di[idx]->txavail; -+ } -+ } -+ -+ /* set default sofware intmask */ -+ sprintf(name, "et%d_no_txint", etc->coreunit); -+ if (getintvar(ch->vars, name)) { -+ /* if no_txint variable is non-zero we disable tx interrupts. -+ * we do the tx buffer reclaim once every few frames. -+ */ -+ ch->def_intmask = (DEF_INTMASK & ~(I_XI0 | I_XI1 | I_XI2 | I_XI3)); -+ etc->txrec_thresh = (((NTXD >> 2) > TXREC_THR) ? TXREC_THR - 1 : 1); -+ } else { -+ ch->def_intmask = DEF_INTMASK; -+ } -+ -+ ch->intmask = ch->def_intmask; -+ -+ /* reset phy: reset it once now */ -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) -+ if (ch->etc->unit == 0) { -+ serdes_reset_core(ch->etc->unit, etc->int_phyaddr); -+ } -+#endif -+ -+ chipphyreset(ch); -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) -+ if (gmac_last_interface(etc->unit)) { -+ /* -+ * The 4-lane serdes is shared between XLDK and SDK. XLDK has to -+ * initialize the 3rd lane (phy address 3) that is used by SDK. -+ */ -+ serdes_init(etc->unit, 3); -+ serdes_start_pll(etc->unit, 1); -+ } -+#endif -+ -+ if (etc->forcespeed == ET_AUTO) { -+ etc->needautoneg = TRUE; -+ etc->advertise = (ADV_100FULL | ADV_100HALF | ADV_10FULL | ADV_10HALF); -+#if defined(CONFIG_MACH_HR2) -+ etc->advertise2 = 0; -+#else -+ etc->advertise2 = ADV_1000FULL; -+#endif -+ } -+ -+ return ((void *) ch); -+ -+fail: -+ chipdetach(ch); -+ return (NULL); -+} -+ -+static void -+chipdetach(ch_t *ch) -+{ -+ int32 idx; -+ -+ ET_TRACE(("et%d: chipdetach\n", ch->etc->unit)); -+ -+ if (ch == NULL) { -+ return; -+ } -+ -+ /* free dma state */ -+ for (idx = 0; idx < NUMTXQ; idx++) { -+ if (ch->di[idx] != NULL) { -+ dma_detach(ch->di[idx]); -+ ch->di[idx] = NULL; -+ } -+ } -+ -+ /* put the core back into reset */ -+ if (ch->sih) { -+ si_core_disable(ch->sih, 0); -+ } -+ -+ if (ch->etc) { -+ if (ch->etc->mib) { -+ ch->etc->mib = NULL; -+ } -+ } -+ -+ /* free si handle */ -+ if (ch->sih) { -+ si_detach(ch->sih); -+ ch->sih = NULL; -+ } -+ -+ /* free vars */ -+ if (ch->vars) { -+ MFREE(ch->osh, ch->vars, ch->vars_size); -+ } -+ -+ /* free chip private state */ -+ MFREE(ch->osh, ch, sizeof(ch_t)); -+} -+ -+static void -+chiplongname(ch_t *ch, char *buf, uint bufsize) -+{ -+ char *s; -+ -+ switch (ch->etc->deviceid) { -+ case BCM56150_CHIP_ID: -+ s = "Broadcom BCM5615x 10/100 Mbps Ethernet Controller"; -+ break; -+ case BCM56340_CHIP_ID: -+ s = "Broadcom BCM5634x 10/100/1000 Mbps Ethernet Controller"; -+ break; -+ case BCM56450_CHIP_ID: -+ s = "Broadcom BCM5645x 10/100/1000 Mbps Ethernet Controller"; -+ break; -+ case BCM53400_CHIP_ID: -+ s = "Broadcom BCM5340x 10/100/1000 Mbps Ethernet Controller"; -+ break; -+ case BCM56260_CHIP_ID: -+ s = "Broadcom BCM5626x 10/100/1000 Mbps Ethernet Controller"; -+ break; -+ case BCM56160_CHIP_ID: -+ s = "Broadcom BCM5616x 10/100/1000 Mbps Ethernet Controller"; -+ break; -+ case BCM53540_CHIP_ID: -+ s = "Broadcom BCM5354x 10/100/1000 Mbps Ethernet Controller"; -+ break; -+ case BCM56170_CHIP_ID: -+ s = "Broadcom BCM5617x 10/100/1000 Mbps Ethernet Controller"; -+ break; -+ default: -+ s = "Broadcom BCM5301x 10/100/1000 Mbps Ethernet Controller"; -+ break; -+ } -+ -+ strncpy(buf, s, bufsize); -+ buf[bufsize - 1] = '\0'; -+} -+ -+static void -+chipdump(ch_t *ch, struct bcmstrbuf *b) -+{ -+ bcm_bprintf(b, "regs 0x%lx etphy 0x%lx ch->intstatus 0x%x intmask 0x%x\n", -+ (ulong)ch->regs, (ulong)ch->etphy, ch->intstatus, ch->intmask); -+ bcm_bprintf(b, "\n"); -+ -+ /* registers */ -+ chipdumpregs(ch, ch->regs, b); -+ bcm_bprintf(b, "\n"); -+} -+ -+ -+#define PRREG(name) bcm_bprintf(b, #name " 0x%x ", R_REG(ch->osh, ®s->name)) -+#define PRMIBREG(name) bcm_bprintf(b, #name " 0x%x ", R_REG(ch->osh, ®s->mib.name)) -+ -+static void -+chipdumpregs(ch_t *ch, gmacregs_t *regs, struct bcmstrbuf *b) -+{ -+ uint phyaddr; -+ -+ phyaddr = ch->etc->phyaddr; -+ -+ PRREG(devcontrol); PRREG(devstatus); -+ bcm_bprintf(b, "\n"); -+ PRREG(biststatus); -+ bcm_bprintf(b, "\n"); -+ PRREG(intstatus); PRREG(intmask); PRREG(gptimer); -+ bcm_bprintf(b, "\n"); -+ PRREG(intrecvlazy); -+ bcm_bprintf(b, "\n"); -+ PRREG(flowctlthresh); PRREG(wrrthresh); PRREG(gmac_idle_cnt_thresh); -+ bcm_bprintf(b, "\n"); -+ PRREG(phyaccess); PRREG(phycontrol); -+ bcm_bprintf(b, "\n"); -+ -+ PRREG(txqctl); PRREG(rxqctl); -+ bcm_bprintf(b, "\n"); -+ PRREG(gpioselect); PRREG(gpio_output_en); -+ bcm_bprintf(b, "\n"); -+ PRREG(clk_ctl_st); PRREG(pwrctl); -+ bcm_bprintf(b, "\n"); -+ -+ /* unimac registers */ -+ PRREG(hdbkpctl); -+ bcm_bprintf(b, "\n"); -+ PRREG(cmdcfg); -+ bcm_bprintf(b, "\n"); -+ PRREG(macaddrhigh); PRREG(macaddrlow); -+ bcm_bprintf(b, "\n"); -+ PRREG(rxmaxlength); PRREG(pausequanta); PRREG(macmode); -+ bcm_bprintf(b, "\n"); -+ PRREG(outertag); PRREG(innertag); PRREG(txipg); PRREG(pausectl); -+ bcm_bprintf(b, "\n"); -+ PRREG(txflush); PRREG(rxstatus); PRREG(txstatus); -+ bcm_bprintf(b, "\n"); -+#ifdef ENABLE_MIB_REG_DUMP -+ /* mib registers */ -+ PRMIBREG(tx_good_octets); PRMIBREG(tx_good_pkts); PRMIBREG(tx_octets); PRMIBREG(tx_pkts); -+ bcm_bprintf(b, "\n"); -+ PRMIBREG(tx_broadcast_pkts); PRMIBREG(tx_multicast_pkts); -+ bcm_bprintf(b, "\n"); -+ PRMIBREG(tx_jabber_pkts); PRMIBREG(tx_oversize_pkts); PRMIBREG(tx_fragment_pkts); -+ bcm_bprintf(b, "\n"); -+ PRMIBREG(tx_underruns); PRMIBREG(tx_total_cols); PRMIBREG(tx_single_cols); -+ bcm_bprintf(b, "\n"); -+ PRMIBREG(tx_multiple_cols); PRMIBREG(tx_excessive_cols); PRMIBREG(tx_late_cols); -+ bcm_bprintf(b, "\n"); -+ PRMIBREG(tx_defered); PRMIBREG(tx_carrier_lost); PRMIBREG(tx_pause_pkts); -+ bcm_bprintf(b, "\n"); -+ -+ PRMIBREG(rx_good_octets); PRMIBREG(rx_good_pkts); PRMIBREG(rx_octets); PRMIBREG(rx_pkts); -+ bcm_bprintf(b, "\n"); -+ PRMIBREG(rx_broadcast_pkts); PRMIBREG(rx_multicast_pkts); -+ bcm_bprintf(b, "\n"); -+ PRMIBREG(rx_jabber_pkts); -+ PRMIBREG(rx_oversize_pkts); PRMIBREG(rx_fragment_pkts); -+ bcm_bprintf(b, "\n"); -+ PRMIBREG(rx_missed_pkts); PRMIBREG(rx_crc_align_errs); PRMIBREG(rx_undersize); -+ bcm_bprintf(b, "\n"); -+ PRMIBREG(rx_crc_errs); PRMIBREG(rx_align_errs); PRMIBREG(rx_symbol_errs); -+ bcm_bprintf(b, "\n"); -+ PRMIBREG(rx_pause_pkts); PRMIBREG(rx_nonpause_pkts); -+#endif /* ENABLE_MIB_REG_DUMP */ -+ bcm_bprintf(b, "\n"); -+ if (phyaddr != EPHY_NOREG) { -+ /* print a few interesting phy registers */ -+ bcm_bprintf(b, "phy0 0x%x phy1 0x%x phy2 0x%x phy3 0x%x\n", -+ chipphyrd(ch, phyaddr, 0), -+ chipphyrd(ch, phyaddr, 1), -+ chipphyrd(ch, phyaddr, 2), -+ chipphyrd(ch, phyaddr, 3)); -+ bcm_bprintf(b, "phy4 0x%x phy5 0x%x phy24 0x%x phy25 0x%x\n", -+ chipphyrd(ch, phyaddr, 4), -+ chipphyrd(ch, phyaddr, 5), -+ chipphyrd(ch, phyaddr, 24), -+ chipphyrd(ch, phyaddr, 25)); -+ } -+ -+} -+ -+static void -+gmac_clearmib(ch_t *ch) -+{ -+ volatile uint32 *ptr; -+ -+ /* enable clear on read */ -+ OR_REG(ch->osh, &ch->regs->devcontrol, DC_MROR); -+ -+ for (ptr = &ch->regs->mib.tx_good_octets; ptr <= &ch->regs->mib.rx_uni_pkts; ptr++) { -+ (void)R_REG(ch->osh, ptr); -+ if (ptr == &ch->regs->mib.tx_q3_octets_high) { -+ ptr++; -+ } -+ } -+ -+ return; -+} -+ -+static void -+gmac_init_reset(ch_t *ch) -+{ -+ OR_REG(ch->osh, &ch->regs->cmdcfg, CC_SR); -+ OSL_DELAY(GMAC_RESET_DELAY); -+} -+ -+static void -+gmac_clear_reset(ch_t *ch) -+{ -+ AND_REG(ch->osh, &ch->regs->cmdcfg, ~CC_SR); -+ OSL_DELAY(GMAC_RESET_DELAY); -+} -+ -+static void -+gmac_reset(ch_t *ch) -+{ -+ uint32 ocmdcfg, cmdcfg; -+ -+ /* put the mac in reset */ -+ gmac_init_reset(ch); -+ -+ /* initialize default config */ -+ ocmdcfg = cmdcfg = R_REG(ch->osh, &ch->regs->cmdcfg); -+ -+ cmdcfg &= ~(CC_TE | CC_RE | CC_RPI | CC_TAI | CC_HD | CC_ML | -+ CC_CFE | CC_RL | CC_RED | CC_PE | CC_TPI | CC_PAD_EN | CC_PF); -+ cmdcfg |= (CC_PROM | CC_NLC | CC_CFE); -+ -+#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ -+ defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) -+ cmdcfg |= (CC_AE | CC_OT | CC_OR); -+#endif -+ -+ if (cmdcfg != ocmdcfg) { -+ W_REG(ch->osh, &ch->regs->cmdcfg, cmdcfg); -+ } -+ -+ /* bring mac out of reset */ -+ gmac_clear_reset(ch); -+} -+ -+static void -+gmac_promisc(ch_t *ch, bool mode) -+{ -+ uint32 cmdcfg; -+ -+ cmdcfg = R_REG(ch->osh, &ch->regs->cmdcfg); -+ -+ /* put the mac in reset */ -+ gmac_init_reset(ch); -+ -+ /* enable or disable promiscuous mode */ -+ if (mode) { -+ cmdcfg |= CC_PROM; -+ } else { -+ cmdcfg &= ~CC_PROM; -+ } -+ -+ W_REG(ch->osh, &ch->regs->cmdcfg, cmdcfg); -+ -+ /* bring mac out of reset */ -+ gmac_clear_reset(ch); -+} -+ -+static int -+gmac_speed(ch_t *ch, uint32 speed) -+{ -+ uint32 cmdcfg; -+ uint32 hd_ena = 0; -+#if (defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3)) -+ uint32_t sdctl; -+ uint32 set_speed = speed; -+#endif /* CONFIG_MACH_GH || CONFIG_MACH_HR3 */ -+ -+ switch (speed) { -+ case ET_10HALF: -+ hd_ena = CC_HD; -+ /* FALLTHRU */ -+ -+ case ET_10FULL: -+ speed = 0; -+ break; -+ -+ case ET_100HALF: -+ hd_ena = CC_HD; -+ /* FALLTHRU */ -+ -+ case ET_100FULL: -+ speed = 1; -+ break; -+ -+ case ET_1000FULL: -+ speed = 2; -+ break; -+ -+ case ET_1000HALF: -+ ET_ERROR(("et%d: gmac_speed: supports 1000 mbps full duplex only\n", -+ ch->etc->unit)); -+ return (FAILURE); -+ -+ case ET_2500FULL: -+ speed = 3; -+ break; -+ -+ default: -+ ET_ERROR(("et%d: gmac_speed: speed %d not supported\n", -+ ch->etc->unit, speed)); -+ return (FAILURE); -+ } -+ -+ cmdcfg = R_REG(ch->osh, &ch->regs->cmdcfg); -+ -+ /* put mac in reset */ -+ gmac_init_reset(ch); -+ -+ /* set the speed */ -+ cmdcfg &= ~(CC_ES_MASK | CC_HD); -+ cmdcfg |= ((speed << CC_ES_SHIFT) | hd_ena); -+ -+#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ -+ defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) -+ cmdcfg |= (CC_AE | CC_OT | CC_OR); -+#endif -+ -+ W_REG(ch->osh, &ch->regs->cmdcfg, cmdcfg); -+ -+ /* bring mac out of reset */ -+ gmac_clear_reset(ch); -+ -+#if (defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3)) -+ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); -+ sdctl &= ~(SC_FORCE_SPD_STRAP_MASK); -+ switch (set_speed) { -+ case ET_1000FULL: -+ sdctl |= SC_FORCE_SPD_1G_VAL; -+ break; -+ case ET_100FULL: -+ case ET_100HALF: -+ sdctl |= SC_FORCE_SPD_100M_VAL; -+ break; -+ default: -+ break; -+ } -+ W_REG(ch->osh, &ch->regs->serdes_ctl, sdctl); -+ -+ udelay(1000); -+#endif /* CONFIG_MACH_GH || CONFIG_MACH_HR3 */ -+ -+ return (SUCCESS); -+} -+ -+static void -+gmac_macloopback(ch_t *ch, bool on) -+{ -+ uint32 ocmdcfg, cmdcfg; -+ -+ ocmdcfg = cmdcfg = R_REG(ch->osh, &ch->regs->cmdcfg); -+ -+ /* put mac in reset */ -+ gmac_init_reset(ch); -+ -+ /* set/clear the mac loopback mode */ -+ if (on) { -+ cmdcfg |= CC_ML; -+ } else { -+ cmdcfg &= ~CC_ML; -+ } -+ -+ if (cmdcfg != ocmdcfg) { -+ W_REG(ch->osh, &ch->regs->cmdcfg, cmdcfg); -+ } -+ -+ /* bring mac out of reset */ -+ gmac_clear_reset(ch); -+} -+ -+static int -+gmac_loopback(ch_t *ch, uint32 mode) -+{ -+ switch (mode) { -+ case LOOPBACK_MODE_DMA: -+ /* to enable loopback for any channel set the loopback -+ * enable bit in xmt0control register. -+ */ -+ dma_fifoloopbackenable(ch->di[TX_Q0]); -+ break; -+ -+ case LOOPBACK_MODE_MAC: -+ gmac_macloopback(ch, TRUE); -+ break; -+ -+ case LOOPBACK_MODE_NONE: -+ gmac_macloopback(ch, FALSE); -+ break; -+ -+ default: -+ ET_ERROR(("et%d: gmac_loopaback: Unknown loopback mode %d\n", -+ ch->etc->unit, mode)); -+ return (FAILURE); -+ } -+ -+ return (SUCCESS); -+} -+ -+static void -+gmac_enable(ch_t *ch) -+{ -+ uint32 cmdcfg; -+ gmacregs_t *regs; -+ -+ regs = ch->regs; -+ -+ cmdcfg = R_REG(ch->osh, &ch->regs->cmdcfg); -+ -+ /* put mac in reset */ -+ gmac_init_reset(ch); -+ -+ cmdcfg |= CC_SR; -+ -+ /* first deassert rx_ena and tx_ena while in reset */ -+ cmdcfg &= ~(CC_RE | CC_TE); -+ W_REG(ch->osh, ®s->cmdcfg, cmdcfg); -+ -+ /* bring mac out of reset */ -+ gmac_clear_reset(ch); -+ -+ /* enable the mac transmit and receive paths now */ -+ OSL_DELAY(2); -+ cmdcfg &= ~CC_SR; -+ cmdcfg |= (CC_RE | CC_TE); -+ -+ /* assert rx_ena and tx_ena when out of reset to enable the mac */ -+ W_REG(ch->osh, ®s->cmdcfg, cmdcfg); -+ -+ /* request ht clock */ -+ OR_REG(ch->osh, ®s->clk_ctl_st, CS_FH); -+ -+ return; -+} -+ -+static void -+gmac_txflowcontrol(ch_t *ch, bool on) -+{ -+ uint32 cmdcfg; -+ -+ cmdcfg = R_REG(ch->osh, &ch->regs->cmdcfg); -+ -+ /* put the mac in reset */ -+ gmac_init_reset(ch); -+ -+ /* to enable tx flow control clear the rx pause ignore bit */ -+ if (on) { -+ cmdcfg &= ~CC_RPI; -+ } else { -+ cmdcfg |= CC_RPI; -+ } -+ -+ W_REG(ch->osh, &ch->regs->cmdcfg, cmdcfg); -+ -+ /* bring mac out of reset */ -+ gmac_clear_reset(ch); -+} -+ -+ -+#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ -+ defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) || defined(CONFIG_MACH_WH2) -+static void -+gmac_serdes_init(ch_t *ch) -+{ -+ uint32_t sdctl, sdstat0, sdstat1; -+ gmacregs_t *regs; -+ -+ regs = ch->regs; -+ -+ ET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); -+ sdstat0 = R_REG(ch->osh, &ch->regs->serdes_status0); -+ sdstat1 = R_REG(ch->osh, &ch->regs->serdes_status1); -+ -+ /* -+ * Bring up both digital and analog clocks -+ * -+ * NOTE: Many MAC registers are not accessible until the PLL is locked. -+ * An S-Channel timeout will occur before that. -+ */ -+ -+ sdctl = (SC_TX1G_FIFO_RST_VAL|SC_FORCE_SPD_STRAP_VAL); -+#if defined(CONFIG_MACH_HX4) -+ sdctl |= (SC_REFSEL_VAL|SC_REF_TERM_SEL_MASK); -+#elif defined(CONFIG_MACH_KT2) -+ sdctl |= SC_REF_TERM_SEL_MASK; -+#endif /* (defined(CONFIG_MACH_HX4) */ -+ W_REG(ch->osh, &ch->regs->serdes_ctl, sdctl); -+ -+ udelay(1000); -+ -+ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); -+ sdctl |= (SC_IDDQ_MASK|SC_PWR_DOWN_MASK); -+ W_REG(ch->osh, &ch->regs->serdes_ctl, sdctl); -+ -+ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); -+ sdctl &= ~(SC_IDDQ_MASK|SC_PWR_DOWN_MASK); -+ W_REG(ch->osh, &ch->regs->serdes_ctl, sdctl); -+ -+ /* Bring hardware out of reset */ -+ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); -+ sdctl |= (SC_RSTB_HW_MASK); -+ W_REG(ch->osh, &ch->regs->serdes_ctl, sdctl); -+ -+ /* Bring MDIOREGS out of reset */ -+ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); -+ sdctl |= (SC_RSTB_MDIOREGS_MASK); -+ W_REG(ch->osh, &ch->regs->serdes_ctl, sdctl); -+ -+ udelay(1000); -+ -+ /* Bring PLL out of reset */ -+ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); -+ sdctl |= (SC_RSTB_PLL_MASK); -+ W_REG(ch->osh, &ch->regs->serdes_ctl, sdctl); -+ -+ udelay(1000); -+ -+ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); -+ sdstat0 = R_REG(ch->osh, &ch->regs->serdes_status0); -+ sdstat1 = R_REG(ch->osh, &ch->regs->serdes_status1); -+ -+ return; -+} -+#endif /* defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ -+ defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) || defined(CONFIG_MACH_WH2) */ -+ -+static void -+gmac_miiconfig(ch_t *ch) -+{ -+ /* BCM53010 GMAC DevStatus register has different definition of "Interface Mode" -+ * Bit 12:8 "interface_mode" This field is programmed through IDM control bits [6:2] -+ * -+ * Bit 0 : SOURCE_SYNC_MODE_EN - If set, Rx line clock input will be used by Unimac for -+ * sampling data.If this is reset, PLL reference clock (Clock 250 or Clk 125 based -+ * on CLK_250_SEL) will be used as receive side line clock. -+ * Bit 1 : DEST_SYNC_MODE_EN - If this is reset, PLL reference clock input (Clock 250 or -+ * Clk 125 based on CLK_250_SEL) will be used as transmit line clock. -+ * If this is set, TX line clock input (from external switch/PHY) is used as -+ * transmit line clock. -+ * Bit 2 : TX_CLK_OUT_INVERT_EN - If set, this will invert the TX clock out of AMAC. -+ * Bit 3 : DIRECT_GMII_MODE - If direct gmii is set to 0, then only 25 MHz clock needs to -+ * be fed at 25MHz reference clock input, for both 10/100 Mbps speeds. -+ * Unimac will internally divide the clock to 2.5 MHz for 10 Mbps speed -+ * Bit 4 : CLK_250_SEL - When set, this selects 250Mhz reference clock input and hence -+ * Unimac line rate will be 2G. -+ * If reset, this selects 125MHz reference clock input. -+ */ -+ -+ if (ch->etc->forcespeed == ET_AUTO) { -+ if (ch->etc->deviceid == BCM56150_CHIP_ID) { -+ gmac_speed(ch, ET_100FULL); -+ } else { -+ gmac_speed(ch, ET_1000FULL); -+ } -+ } else { -+ gmac_speed(ch, ch->etc->forcespeed); -+ } -+} -+ -+#ifdef CONFIG_SERDES_ASYMMETRIC_MODE -+void -+gmac_serdes_asym_mode(etc_info_t *etcptrs[]) -+{ -+ etc_info_t *etc; -+ -+ etc = etcptrs[0]; -+ -+ /* initialize serdes */ -+ gmac_serdes_init(etc->ch); -+ serdes_reset_core(etc->unit, etc->int_phyaddr); -+ -+ /* initialize lane 0 */ -+ serdes_set_asym_mode(etc->unit, etc->int_phyaddr); -+ serdes_init(etc->unit, etc->int_phyaddr); -+ serdes_speeddpx_set(etc->unit, etc->int_phyaddr, etc->speed, etc->duplex); -+ /* initialize lane 1 */ -+ etc = etcptrs[1]; -+ if (etc->linkstate) { -+ serdes_set_asym_mode(etc->unit, etc->int_phyaddr); -+ serdes_init(etc->unit, etc->int_phyaddr); -+ serdes_speeddpx_set(etc->unit, etc->int_phyaddr, etc->speed, etc->duplex); -+ } -+ -+ /* -+ * The 4-lane serdes is shared between XLDK and SDK. XLDK has to -+ * initialize the 3rd lane (phy address 3) that is used by SDK. -+ */ -+ serdes_init(etc->unit, 3); -+ -+ /* start PLL */ -+ serdes_start_pll(etc->unit, 1); -+} -+#endif /* CONFIG_SERDES_ASYMMETRIC_MODE */ -+ -+ -+static void -+chipreset(ch_t *ch) -+{ -+ gmacregs_t *regs; -+ uint32 idx, sflags, flagbits = 0; -+ -+ ET_TRACE(("et%d: chipreset\n", ch->etc->unit)); -+ -+ regs = ch->regs; -+ -+ if (!si_iscoreup(ch->sih)) { -+ /* power on reset: reset the enet core */ -+ goto chipinreset; -+ } -+ -+ /* Reset other three GMAC cores if needed */ -+ for (idx = 0; idx < IPROC_NUM_GMACS; idx++) { -+ /* As northstar requirement, we have to reset all GAMCs before accessing them. -+ * et_probe() call pci_enable_device() for etx and do si_core_reset for GAMCx only. -+ * then the other three GAMC didn't reset. -+ * We do it here. -+ */ -+ si_setcore(ch->sih, GMAC_CORE_ID, idx); -+ if (!si_iscoreup(ch->sih)) { -+ ET_TRACE(("et%d: reset NorthStar GMAC[%d] core\n", ch->etc->unit, idx)); -+ si_core_reset(ch->sih, flagbits, 0); -+ } -+ } -+ si_setcore(ch->sih, GMAC_CORE_ID, 0); -+ -+ /* update software counters before resetting the chip */ -+ if (ch->mibgood) { -+ chipstatsupd(ch); -+ } -+ -+ /* reset the tx dma engines */ -+ for (idx = 0; idx < NUMTXQ; idx++) { -+ if (ch->di[idx]) { -+ ET_TRACE(("et%d: resetting tx dma%d\n", ch->etc->unit, idx)); -+ dma_txreset(ch->di[idx]); -+ } -+ } -+ -+ /* set gmac into loopback mode to ensure no rx traffic */ -+ gmac_loopback(ch, LOOPBACK_MODE_MAC); -+ OSL_DELAY(1); -+ -+ /* reset the rx dma engine */ -+ if (ch->di[RX_Q0]) { -+ ET_TRACE(("et%d: resetting rx dma\n", ch->etc->unit)); -+ dma_rxreset(ch->di[RX_Q0]); -+ } -+ -+ /* clear the multicast filter table */ -+ gmac_mf_cleanup(ch); -+ -+chipinreset: -+ sflags = si_core_sflags(ch->sih, 0, 0); -+ if (sflags & SISF_SW_ATTACHED) { -+ ET_TRACE(("et%d: internal switch attached\n", ch->etc->unit)); -+ flagbits = SICF_SWCLKE; -+ if (!ch->etc->robo) { -+ ET_TRACE(("et%d: reseting switch\n", ch->etc->unit)); -+ flagbits |= SICF_SWRST; -+ } -+ } -+ -+ /* Reset all GMAC cores */ -+ for (idx = 0; idx < IPROC_NUM_GMACS; idx++) { -+ /* As northstar requirement, we have to reset all GAMCs before accessing them. -+ * et_probe() call pci_enable_device() for etx and do si_core_reset for GAMCx only. -+ * then the other three GAMC didn't reset. -+ * We do it here. -+ */ -+ si_setcore(ch->sih, GMAC_CORE_ID, idx); -+ if (!si_iscoreup(ch->sih)) { -+ ET_TRACE(("et%d: reset NorthStar GMAC[%d] core\n", ch->etc->unit, idx)); -+ si_core_reset(ch->sih, flagbits, 0); -+ } -+ } -+ si_setcore(ch->sih, GMAC_CORE_ID, 0); -+ -+ if ((sflags & SISF_SW_ATTACHED) && (!ch->etc->robo)) { -+ ET_TRACE(("et%d: taking switch out of reset\n", ch->etc->unit)); -+ si_core_cflags(ch->sih, SICF_SWRST, 0); -+ } -+ -+ /* reset gmac */ -+ gmac_reset(ch); -+ -+ /* clear mib */ -+ gmac_clearmib(ch); -+ ch->mibgood = TRUE; -+ -+ /* set mdc_transition_en */ -+ OR_REG(ch->osh, ®s->phycontrol, PC_MTE); -+ -+ /* Read the devstatus to figure out the configuration mode of -+ * the interface. Set the speed to 100 if the switch interface -+ * is mii/rmii. -+ */ -+ gmac_miiconfig(ch); -+ -+ /* clear persistent sw intstatus */ -+ ch->intstatus = 0; -+} -+ -+/* -+ * Lookup a multicast address in the filter hash table. -+ */ -+static int -+gmac_mf_lkup(ch_t *ch, struct ether_addr *mcaddr) -+{ -+ mflist_t *ptr; -+ -+ /* find the multicast address */ -+ for (ptr = ch->mf.bucket[GMAC_MCADDR_HASH(mcaddr)]; ptr != NULL; ptr = ptr->next) { -+ if (!ETHER_MCADDR_CMP(&ptr->mc_addr, mcaddr)) { -+ return (SUCCESS); -+ } -+ } -+ -+ return (FAILURE); -+} -+ -+/* -+ * Add a multicast address to the filter hash table. -+ */ -+static int -+gmac_mf_add(ch_t *ch, struct ether_addr *mcaddr) -+{ -+ uint32 hash; -+ mflist_t *entry; -+#ifdef BCMDBG -+ char mac[ETHER_ADDR_STR_LEN]; -+#endif /* BCMDBG */ -+ -+ /* add multicast addresses only */ -+ if (!ETHER_ISMULTI(mcaddr)) { -+ ET_ERROR(("et%d: adding invalid multicast address %s\n", -+ ch->etc->unit, bcm_ether_ntoa(mcaddr, mac))); -+ return (FAILURE); -+ } -+ -+ /* discard duplicate add requests */ -+ if (gmac_mf_lkup(ch, mcaddr) == SUCCESS) { -+ ET_ERROR(("et%d: adding duplicate mcast filter entry\n", ch->etc->unit)); -+ return (FAILURE); -+ } -+ -+ /* allocate memory for list entry */ -+ entry = MALLOC(ch->osh, sizeof(mflist_t)); -+ if (entry == NULL) { -+ ET_ERROR(("et%d: out of memory allocating mcast filter entry\n", ch->etc->unit)); -+ return (FAILURE); -+ } -+ -+ /* add the entry to the hash bucket */ -+ ether_copy(mcaddr, &entry->mc_addr); -+ hash = GMAC_MCADDR_HASH(mcaddr); -+ entry->next = ch->mf.bucket[hash]; -+ ch->mf.bucket[hash] = entry; -+ -+ return (SUCCESS); -+} -+ -+/* -+ * Cleanup the multicast filter hash table. -+ */ -+static void -+gmac_mf_cleanup(ch_t *ch) -+{ -+ mflist_t *ptr, *tmp; -+ int32 idx; -+ -+ for (idx = 0; idx < GMAC_HASHT_SIZE; idx++) { -+ ptr = ch->mf.bucket[idx]; -+ while (ptr) { -+ tmp = ptr; -+ ptr = ptr->next; -+ MFREE(ch->osh, tmp, sizeof(mflist_t)); -+ } -+ ch->mf.bucket[idx] = NULL; -+ } -+} -+ -+/* -+ * Initialize all the chip registers. If dma mode, init tx and rx dma engines -+ * but leave the devcontrol tx and rx (fifos) disabled. -+ */ -+static void -+chipinit(ch_t *ch, uint options) -+{ -+ etc_info_t *etc; -+ gmacregs_t *regs; -+ uint idx; -+ -+ regs = ch->regs; -+ etc = ch->etc; -+ -+ ET_TRACE(("et%d: chipinit\n", etc->unit)); -+ -+ /* enable one rx interrupt per received frame */ -+ W_REG(ch->osh, ®s->intrecvlazy, (1 << IRL_FC_SHIFT)); -+ -+ /* enable 802.3x tx flow control (honor received PAUSE frames) */ -+ gmac_txflowcontrol(ch, TRUE); -+ -+ /* enable/disable promiscuous mode */ -+ gmac_promisc(ch, etc->promisc); -+ -+ /* set our local address */ -+ W_REG(ch->osh, ®s->macaddrhigh, -+ hton32(*(uint32 *)&etc->cur_etheraddr.octet[0])); -+ W_REG(ch->osh, ®s->macaddrlow, -+ hton16(*(uint16 *)&etc->cur_etheraddr.octet[4])); -+ -+ if (!etc->promisc) { -+ /* gmac doesn't have a cam, hence do the multicast address filtering -+ * in the software -+ */ -+ /* allmulti or a list of discrete multicast addresses */ -+ if (!etc->allmulti && etc->nmulticast) { -+ for (idx = 0; idx < etc->nmulticast; idx++) { -+ (void)gmac_mf_add(ch, &etc->multicast[idx]); -+ } -+ } -+ } -+ -+ /* optionally enable mac-level loopback */ -+ if (etc->loopbk) { -+ gmac_loopback(ch, LOOPBACK_MODE_MAC); -+ } else { -+ gmac_loopback(ch, LOOPBACK_MODE_NONE); -+ } -+ -+ /* set max frame lengths - account for possible vlan tag */ -+ W_REG(ch->osh, ®s->rxmaxlength, BCM_ETHER_MAX_LEN + 32); -+ -+ /* -+ * Optionally, disable phy autonegotiation and force our speed/duplex -+ * or constrain our advertised capabilities. -+ */ -+ if (etc->forcespeed != ET_AUTO) { -+ gmac_speed(ch, etc->forcespeed); -+ chipphyforce(ch, etc->phyaddr); -+ switch (etc->forcespeed) { -+ case ET_1000FULL: -+ etc->speed = 1000; -+ etc->duplex = 1; -+ break; -+ case ET_1000HALF: -+ etc->speed = 1000; -+ etc->duplex = 0; -+ break; -+ case ET_100FULL: -+ etc->speed = 100; -+ etc->duplex = 1; -+ break; -+ case ET_100HALF: -+ etc->speed = 100; -+ etc->duplex = 0; -+ break; -+ case ET_10FULL: -+ etc->speed = 10; -+ etc->duplex = 1; -+ break; -+ case ET_10HALF: -+ etc->speed = 10; -+ etc->duplex = 0; -+ break; -+ default: -+ break; -+ } -+ } else if (etc->advertise && etc->needautoneg) { -+ chipphyadvertise(ch, etc->phyaddr); -+ } -+ /* enable the overflow continue feature and disable parity */ -+ dma_ctrlflags(ch->di[0], DMA_CTRL_ROC | DMA_CTRL_PEN /* mask */, -+ DMA_CTRL_ROC /* value */); -+ -+ if (options & ET_INIT_FULL) { -+ /* initialize the tx and rx dma channels */ -+ for (idx = 0; idx < NUMTXQ; idx++) { -+ dma_txinit(ch->di[idx]); -+ } -+ dma_rxinit(ch->di[RX_Q0]); -+ -+ /* post dma receive buffers */ -+ dma_rxfill(ch->di[RX_Q0]); -+ -+ /* lastly, enable interrupts */ -+ if (options & ET_INIT_INTRON) { -+ et_intrson(etc->et); -+ } -+ } else { -+ dma_rxenable(ch->di[RX_Q0]); -+ } -+ -+ /* turn on the emac */ -+ gmac_enable(ch); -+} -+ -+/* dma transmit */ -+static bool BCMFASTPATH -+chiptx(ch_t *ch, void *p0) -+{ -+ int error, len; -+ uint32 q = TX_Q0; -+ -+ ET_TRACE(("et%d: chiptx\n", ch->etc->unit)); -+ ET_LOG("et%d: chiptx", ch->etc->unit, 0); -+ -+ len = PKTLEN(ch->osh, p0); -+ -+ /* check tx max length */ -+ if (len > (BCM_ETHER_MAX_LEN + 32)) { -+ ET_ERROR(("et%d: chiptx: max frame length exceeded\n", -+ ch->etc->unit)); -+ PKTFREE(ch->osh, p0, TRUE); -+ return FALSE; -+ } -+ -+ /* gmac rev 0 workaround: unimac can only transmit frames of -+ * length 17 bytes or greater. so pad the frame and send a -+ * 17 byte frame. to do the padding just modify the packet -+ * length that we provide to the dma. unimac does the extra -+ * padding * required to send 64 byte frames. -+ */ -+ if ((len < GMAC_MIN_FRAMESIZE) && (ch->etc->corerev == 0)) { -+ PKTSETLEN(ch->osh, p0, GMAC_MIN_FRAMESIZE); -+ } -+ -+ ASSERT(q < NUMTXQ); -+ -+ /* if tx completion intr is disabled then do the reclaim -+ * once every few frames transmitted. -+ */ -+ if ((ch->etc->txframes[q] & ch->etc->txrec_thresh) == 1) { -+ dma_txreclaim(ch->di[q], HNDDMA_RANGE_TRANSMITTED); -+ } -+ -+ error = dma_txfast(ch->di[q], p0, TRUE); -+ -+ if (error) { -+ ET_ERROR(("et%d: chiptx: out of txds\n", ch->etc->unit)); -+ ch->etc->txnobuf++; -+ return FALSE; -+ } -+ -+ ch->etc->txframes[q]++; -+ -+ if ((len < GMAC_MIN_FRAMESIZE) && (ch->etc->corerev == 0)) { -+ if (skb_is_nonlinear((struct sk_buff*)p0)) { -+ printk("Modified nonlinear skb (et_ctf_pipeline_loopback) - not calling skb_trim\n"); -+ } else { -+ /* set back the orig length */ -+ PKTSETLEN(ch->osh, p0, len); -+ } -+ } -+ -+ return TRUE; -+} -+ -+/* reclaim completed transmit descriptors and packets */ -+static void BCMFASTPATH -+chiptxreclaim(ch_t *ch, bool forceall) -+{ -+ int32 idx; -+ -+ ET_TRACE(("et%d: chiptxreclaim\n", ch->etc->unit)); -+ -+ for (idx = 0; idx < NUMTXQ; idx++) { -+ dma_txreclaim(ch->di[idx], forceall ? HNDDMA_RANGE_ALL : HNDDMA_RANGE_TRANSMITTED); -+ ch->intstatus &= ~(I_XI0 << idx); -+ } -+} -+ -+/* dma receive: returns a pointer to the next frame received, or NULL if there are no more */ -+static void * BCMFASTPATH -+chiprx(ch_t *ch) -+{ -+ void *p; -+ struct ether_addr *da; -+ -+ ET_TRACE(("et%d: chiprx\n", ch->etc->unit)); -+ ET_LOG("et%d: chiprx", ch->etc->unit, 0); -+ -+ if (dma_rxstopped(ch->di[RX_Q0])) { -+ ch->etc->rxdmastopped++; -+ } -+ -+ /* gmac doesn't have a cam to do address filtering. so we implement -+ * the multicast address filtering here. -+ */ -+ while ((p = dma_rx(ch->di[RX_Q0])) != NULL) { -+ /* check for overflow error packet */ -+ if (RXH_FLAGS(ch->etc, PKTDATA(ch->osh, p)) & GRXF_OVF) { -+ PKTFREE(ch->osh, p, FALSE); -+ ch->etc->rxoflodiscards++; -+ continue; -+ } -+ -+#ifdef GMAC_RATE_LIMITING -+ /* rate limiting */ -+ /* printf("et%d: chiprx RXH_PT(0x%x)\n", ch->etc->unit, RXH_PT(ch->etc, PKTDATA(ch->osh, p))); */ -+ if (RXH_PT(ch->etc, PKTDATA(ch->osh, p)) == 2) -+ ch->etc->rx_bc_frame_cnt++; -+ if (ch->etc->rl_stopping_broadcasts) { -+ /* check if broadcast packet */ -+ if (RXH_PT(ch->etc, PKTDATA(ch->osh, p)) == 2) { -+ /* broadcast packet */ -+ PKTFREE(ch->osh, p, FALSE); -+ ch->etc->rl_dropped_bc_packets++; -+ ch->etc->rl_dropped_packets++; -+ continue; -+ } -+ } else if (ch->etc->rl_stopping_all_packets) { -+ PKTFREE(ch->osh, p, FALSE); -+ ch->etc->rl_dropped_all_packets++; -+ ch->etc->rl_dropped_packets++; -+ continue; -+ } -+#endif /* GMAC_RATE_LIMITING */ -+ -+ if (ch->etc->allmulti) { -+ return (p); -+ } else { -+ /* skip the rx header */ -+ PKTPULL(ch->osh, p, HWRXOFF); -+ -+ /* do filtering only for multicast packets when allmulti is false */ -+ da = (struct ether_addr *)PKTDATA(ch->osh, p); -+ if (!ETHER_ISMULTI(da) || -+ (gmac_mf_lkup(ch, da) == SUCCESS) || ETHER_ISBCAST(da)) { -+ PKTPUSH(ch->osh, p, HWRXOFF); -+ return (p); -+ } -+ PKTFREE(ch->osh, p, FALSE); -+ } -+ } -+ -+ ch->intstatus &= ~I_RI; -+ -+ /* post more rx buffers since we consumed a few */ -+ dma_rxfill(ch->di[RX_Q0]); -+ -+ return (NULL); -+} -+ -+/* reclaim completed dma receive descriptors and packets */ -+static void -+chiprxreclaim(ch_t *ch) -+{ -+ ET_TRACE(("et%d: chiprxreclaim\n", ch->etc->unit)); -+ dma_rxreclaim(ch->di[RX_Q0]); -+ ch->intstatus &= ~I_RI; -+} -+ -+/* allocate and post dma receive buffers */ -+static void BCMFASTPATH -+chiprxfill(ch_t *ch) -+{ -+ ET_TRACE(("et%d: chiprxfill\n", ch->etc->unit)); -+ ET_LOG("et%d: chiprxfill", ch->etc->unit, 0); -+ dma_rxfill(ch->di[RX_Q0]); -+} -+ -+#ifdef DBG_CHECK_ERR -+/* get current and pending interrupt events */ -+static void -+check_errs(ch_t *ch) -+{ -+ static uint32 crserrs = 0; -+ uint32 err; -+ -+ /* read the interrupt status register */ -+ err = R_REG(ch->osh, &ch->regs->mib.tx_jabber_pkts); -+ if (err) { -+ printk("%s tx_jabber_pkts (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.tx_oversize_pkts); -+ if (err) { -+ printk("%s tx_oversize_pkts (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.tx_fragment_pkts); -+ if (err) { -+ printk("%s tx_fragment_pkts (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.tx_underruns); -+ if (err) { -+ printk("%s tx_underruns (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.tx_total_cols); -+ if (err) { -+ printk("%s tx_total_cols (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.tx_single_cols); -+ if (err) { -+ printk("%s tx_single_cols (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.tx_multiple_cols); -+ if (err) { -+ printk("%s tx_multiple_cols (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.tx_excessive_cols); -+ if (err) { -+ printk("%s tx_excessive_cols (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.tx_late_cols); -+ if (err) { -+ printk("%s tx_late_cols (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.tx_defered); -+ if (err) { -+ printk("%s tx_defered (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.tx_carrier_lost); -+ crserrs += err; -+ if (crserrs > 100) { -+ printk("%s tx_carrier_lost crserrs(0x%x)\n", __FUNCTION__, crserrs); -+ crserrs = 0; -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.tx_pause_pkts); -+ if (err) { -+ printk("%s tx_pause_pkts (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.rx_jabber_pkts); -+ if (err) { -+ printk("%s rx_jabber_pkts (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.rx_oversize_pkts); -+ if (err) { -+ printk("%s rx_oversize_pkts (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.rx_fragment_pkts); -+ if (err) { -+ printk("%s rx_fragment_pkts (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.rx_missed_pkts); -+ if (err) { -+ printk("%s rx_missed_pkts (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.rx_crc_align_errs); -+ if (err) { -+ printk("%s rx_crc_align_errs (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.rx_undersize); -+ if (err) { -+ printk("%s rx_undersize (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.rx_crc_errs); -+ if (err) { -+ printk("%s rx_crc_errs (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.rx_align_errs); -+ if (err) { -+ printk("%s rx_align_errs (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.rx_symbol_errs); -+ if (err) { -+ printk("%s rx_symbol_errs (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.rx_pause_pkts); -+ if (err) { -+ printk("%s rx_pause_pkts (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.rx_nonpause_pkts); -+ if (err) { -+ printk("%s rx_nonpause_pkts (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->mib.rx_sachanges); -+ if (err) { -+ printk("%s rx_sachanges (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->dmaregs[0].dmaxmt.status1); -+ if (err & 0xf0000000) { -+ printk("%s dma0 xmit status (0x%x)\n", __FUNCTION__, err); -+ } -+ -+ err = R_REG(ch->osh, &ch->regs->dmaregs[0].dmarcv.status1); -+ if (err & 0xf0000000) { -+ printk("%s dma0 rcv status (0x%x)\n", __FUNCTION__, err); -+ } -+ -+#if defined(CONFIG_MACH_HR2) -+ phy5221_chk_err(ch->etc->unit, ch->etc->phyaddr); -+#endif /* defined(CONFIG_MACH_HR2) */ -+} -+#endif /* DBG_CHECK_ERR */ -+ -+/* get current and pending interrupt events */ -+static int BCMFASTPATH -+chipgetintrevents(ch_t *ch, bool in_isr) -+{ -+ uint32 intstatus; -+ int events; -+ -+ events = 0; -+ -+ /* read the interrupt status register */ -+ intstatus = R_REG(ch->osh, &ch->regs->intstatus); -+ -+ /* defer unsolicited interrupts */ -+ intstatus &= (in_isr ? ch->intmask : ch->def_intmask); -+ -+ if (intstatus != 0) { -+ events = INTR_NEW; -+ } -+ -+ /* or new bits into persistent intstatus */ -+ intstatus = (ch->intstatus |= intstatus); -+ -+ /* return if no events */ -+ if (intstatus == 0) { -+ return (0); -+ } -+ -+#ifdef DBG_CHECK_ERR -+ check_errs(ch); -+#endif /* DBG_CHECK_ERR */ -+ -+ /* convert chip-specific intstatus bits into generic intr event bits */ -+ if (intstatus & I_RI) { -+ events |= INTR_RX; -+ } -+ if (intstatus & (I_XI0 | I_XI1 | I_XI2 | I_XI3)) { -+ events |= INTR_TX; -+ } -+ if (intstatus & I_ERRORS) { -+ events |= INTR_ERROR; -+ } -+ -+ return (events); -+} -+ -+/* enable chip interrupts */ -+static void BCMFASTPATH -+chipintrson(ch_t *ch) -+{ -+ ch->intmask = ch->def_intmask; -+ W_REG(ch->osh, &ch->regs->intmask, ch->intmask); -+} -+ -+/* disable chip interrupts */ -+static void BCMFASTPATH -+chipintrsoff(ch_t *ch) -+{ -+ /* disable further interrupts from gmac */ -+ W_REG(ch->osh, &ch->regs->intmask, 0); -+ (void) R_REG(ch->osh, &ch->regs->intmask); /* sync readback */ -+ ch->intmask = 0; -+ -+ /* clear the interrupt conditions */ -+ W_REG(ch->osh, &ch->regs->intstatus, ch->intstatus); -+} -+ -+/* return true of caller should re-initialize, otherwise false */ -+static bool BCMFASTPATH -+chiperrors(ch_t *ch) -+{ -+ uint32 intstatus; -+ etc_info_t *etc; -+ -+ etc = ch->etc; -+ -+ intstatus = ch->intstatus; -+ ch->intstatus &= ~(I_ERRORS); -+ -+ ET_TRACE(("et%d: chiperrors: intstatus 0x%x\n", etc->unit, intstatus)); -+ -+ if (intstatus & I_PDEE) { -+ ET_ERROR(("et%d: descriptor error\n", etc->unit)); -+ etc->dmade++; -+ } -+ -+ if (intstatus & I_PDE) { -+ ET_ERROR(("et%d: data error\n", etc->unit)); -+ etc->dmada++; -+ } -+ -+ if (intstatus & I_DE) { -+ ET_ERROR(("et%d: descriptor protocol error\n", etc->unit)); -+ etc->dmape++; -+ } -+ -+ if (intstatus & I_RDU) { -+ ET_ERROR(("et%d: receive descriptor underflow\n", etc->unit)); -+ etc->rxdmauflo++; -+ } -+ -+ if (intstatus & I_RFO) { -+ ET_TRACE(("et%d: receive fifo overflow\n", etc->unit)); -+ etc->rxoflo++; -+ } -+ -+ if (intstatus & I_XFU) { -+ ET_ERROR(("et%d: transmit fifo underflow\n", etc->unit)); -+ etc->txuflo++; -+ } -+ -+ /* if overflows or decriptors underflow, don't report it -+ * as an error and provoque a reset -+ */ -+ if (intstatus & ~(I_RDU | I_RFO) & I_ERRORS) { -+ return (TRUE); -+ } -+ -+ return (FALSE); -+} -+ -+static void -+chipstatsupd(ch_t *ch) -+{ -+ etc_info_t *etc; -+ gmacregs_t *regs; -+ volatile uint32 *s; -+ uint32 *d; -+ -+ etc = ch->etc; -+ regs = ch->regs; -+ -+ /* read the mib counters and update the driver maintained software -+ * counters. -+ */ -+ OR_REG(ch->osh, ®s->devcontrol, DC_MROR); -+ for (s = ®s->mib.tx_good_octets, d = &ch->mib.tx_good_octets; -+ s <= ®s->mib.rx_uni_pkts; s++, d++) { -+ *d += R_REG(ch->osh, s); -+ if (s == &ch->regs->mib.tx_q3_octets_high) { -+ s++; -+ d++; -+ } -+ } -+ -+ /* -+ * Aggregate transmit and receive errors that probably resulted -+ * in the loss of a frame are computed on the fly. -+ * -+ * We seem to get lots of tx_carrier_lost errors when flipping -+ * speed modes so don't count these as tx errors. -+ * -+ * Arbitrarily lump the non-specific dma errors as tx errors. -+ */ -+ etc->txerror = ch->mib.tx_jabber_pkts + ch->mib.tx_oversize_pkts -+ + ch->mib.tx_underruns + ch->mib.tx_excessive_cols -+ + ch->mib.tx_late_cols + etc->txnobuf + etc->dmade -+ + etc->dmada + etc->dmape + etc->txuflo; -+ etc->rxerror = ch->mib.rx_jabber_pkts + ch->mib.rx_oversize_pkts -+ + ch->mib.rx_missed_pkts + ch->mib.rx_crc_align_errs -+ + ch->mib.rx_undersize + ch->mib.rx_crc_errs -+ + ch->mib.rx_align_errs -+ + etc->rxnobuf + etc->rxdmauflo + etc->rxoflo + etc->rxbadlen; -+ etc->rxgiants = (ch->di[RX_Q0])->rxgiants; -+} -+ -+static void -+chipdumpmib(ch_t *ch, struct bcmstrbuf *b, bool clear) -+{ -+ gmacmib_t *m; -+ -+ m = &ch->mib; -+ -+ if (clear) { -+ bzero((char *)m, sizeof(gmacmib_t)); -+ return; -+ } -+ -+ bcm_bprintf(b, "tx_broadcast_pkts %d tx_multicast_pkts %d tx_jabber_pkts %d " -+ "tx_oversize_pkts %d\n", -+ m->tx_broadcast_pkts, m->tx_multicast_pkts, -+ m->tx_jabber_pkts, -+ m->tx_oversize_pkts); -+ bcm_bprintf(b, "tx_fragment_pkts %d tx_underruns %d\n", -+ m->tx_fragment_pkts, m->tx_underruns); -+ bcm_bprintf(b, "tx_total_cols %d tx_single_cols %d tx_multiple_cols %d " -+ "tx_excessive_cols %d\n", -+ m->tx_total_cols, m->tx_single_cols, m->tx_multiple_cols, -+ m->tx_excessive_cols); -+ bcm_bprintf(b, "tx_late_cols %d tx_defered %d tx_carrier_lost %d tx_pause_pkts %d\n", -+ m->tx_late_cols, m->tx_defered, m->tx_carrier_lost, -+ m->tx_pause_pkts); -+ -+ /* receive stat counters */ -+ /* hardware mib pkt and octet counters wrap too quickly to be useful */ -+ bcm_bprintf(b, "rx_broadcast_pkts %d rx_multicast_pkts %d rx_jabber_pkts %d " -+ "rx_oversize_pkts %d\n", -+ m->rx_broadcast_pkts, m->rx_multicast_pkts, -+ m->rx_jabber_pkts, m->rx_oversize_pkts); -+ bcm_bprintf(b, "rx_fragment_pkts %d rx_missed_pkts %d rx_crc_align_errs %d " -+ "rx_undersize %d\n", -+ m->rx_fragment_pkts, m->rx_missed_pkts, -+ m->rx_crc_align_errs, m->rx_undersize); -+ bcm_bprintf(b, "rx_crc_errs %d rx_align_errs %d rx_symbol_errs %d\n", -+ m->rx_crc_errs, m->rx_align_errs, m->rx_symbol_errs); -+ bcm_bprintf(b, "rx_pause_pkts %d rx_nonpause_pkts %d\n", -+ m->rx_pause_pkts, m->rx_nonpause_pkts); -+} -+ -+static void -+chipenablepme(ch_t *ch) -+{ -+ return; -+} -+ -+static void -+chipdisablepme(ch_t *ch) -+{ -+ return; -+} -+ -+static void -+chipduplexupd(ch_t *ch) -+{ -+ uint32 cmdcfg; -+ int32 duplex, speed; -+#if (defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3)) -+ uint32_t sdctl; -+#endif /* defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3) */ -+ -+ cmdcfg = R_REG(ch->osh, &ch->regs->cmdcfg); -+ -+ /* check if duplex mode changed */ -+ if (ch->etc->duplex && (cmdcfg & CC_HD)) { -+ duplex = 0; -+ } else if (!ch->etc->duplex && ((cmdcfg & CC_HD) == 0)) { -+ duplex = CC_HD; -+ } else { -+ duplex = -1; -+ } -+ -+ /* check if the speed changed */ -+ speed = ((cmdcfg & CC_ES_MASK) >> CC_ES_SHIFT); -+ if ((ch->etc->speed == 1000) && (speed != 2)) { -+ speed = 2; -+ } else if ((ch->etc->speed == 100) && (speed != 1)) { -+ speed = 1; -+ } else if ((ch->etc->speed == 10) && (speed != 0)) { -+ speed = 0; -+ } else { -+ speed = -1; -+ } -+ -+ /* no duplex or speed change required */ -+ if ((speed == -1) && (duplex == -1)) { -+ return; -+ } -+ -+ /* update the speed */ -+ if (speed != -1) { -+ cmdcfg &= ~CC_ES_MASK; -+ cmdcfg |= (speed << CC_ES_SHIFT); -+ } -+ -+ /* update the duplex mode */ -+ if (duplex != -1) { -+ cmdcfg &= ~CC_HD; -+ cmdcfg |= duplex; -+ } -+ -+#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ -+ defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) -+ cmdcfg |= (CC_AE | CC_OT | CC_OR); -+#endif /* defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ -+ defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2) */ -+ -+ ET_TRACE(("chipduplexupd: updating speed & duplex %x\n", cmdcfg)); -+ -+ /* put mac in reset */ -+ gmac_init_reset(ch); -+ -+ W_REG(ch->osh, &ch->regs->cmdcfg, cmdcfg); -+ -+ /* bring mac out of reset */ -+ gmac_clear_reset(ch); -+ -+#if (defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3)) -+ sdctl = R_REG(ch->osh, &ch->regs->serdes_ctl); -+ sdctl &= ~(SC_FORCE_SPD_STRAP_MASK); -+ switch (ch->etc->speed) { -+ case 1000: -+ sdctl |= SC_FORCE_SPD_1G_VAL; -+ break; -+ case 100: -+ sdctl |= SC_FORCE_SPD_100M_VAL; -+ break; -+ default: -+ break; -+ } -+ W_REG(ch->osh, &ch->regs->serdes_ctl, sdctl); -+#endif /* (defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3)) */ -+} -+ -+#ifdef CONFIG_SERDES_ASYMMETRIC_MODE -+static void -+chipforcespddpx(ch_t *ch) -+{ -+ uint32 cmdcfg; -+ int32 duplex=0, speed; -+ -+ cmdcfg = R_REG(ch->osh, &ch->regs->cmdcfg); -+ -+ /* set duplex */ -+ if (!ch->etc->duplex) -+ duplex = CC_HD; -+ -+ /* set speed */ -+ if (ch->etc->speed == 10) { -+ speed = 0; -+ } else if (ch->etc->speed == 100) { -+ speed = 1; -+ } else { -+ speed = 2; -+ } -+ -+ /* update the speed */ -+ cmdcfg &= ~CC_ES_MASK; -+ cmdcfg |= (speed << CC_ES_SHIFT); -+ -+ /* update the duplex mode */ -+ cmdcfg &= ~CC_HD; -+ cmdcfg |= duplex; -+ -+ ET_TRACE(("chipforcespddpx: forcing speed & duplex %x\n", cmdcfg)); -+ -+ /* put mac in reset */ -+ gmac_init_reset(ch); -+ -+ W_REG(ch->osh, &ch->regs->cmdcfg, cmdcfg); -+ -+ /* bring mac out of reset */ -+ gmac_clear_reset(ch); -+ -+ if (ch->etc->up) { -+ serdes_speeddpx_set(ch->etc->unit, ch->etc->int_phyaddr, ch->etc->speed, ch->etc->duplex); -+ } -+} -+#endif /* CONFIG_SERDES_ASYMMETRIC_MODE */ -+ -+ -+static uint16 -+chipphyrd(ch_t *ch, uint phyaddr, uint reg) -+{ -+ uint16 val = 0; -+ uint32 addr = PHY_REG_ADDR(phyaddr); -+ -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) -+ if (PHY_REG_BUS(phyaddr)) { /* Internal serdes */ -+ val = serdes_rd_reg(ch->etc->unit, addr, reg); -+ } else { -+ phy5461_rd_reg(ch->etc->unit, addr, -+ PHY_REG_FLAGS(phyaddr) ? SOC_PHY_REG_1000X : 0, -+ PHY_REG_BANK(phyaddr), reg, &val); -+ } -+#elif defined(CONFIG_MACH_HR2) -+ phy5221_rd_reg(ch->etc->unit, addr, PHY_REG_BANK(phyaddr), reg, &val); -+#elif defined(CONFIG_MACH_HR3) -+#if defined(CONFIG_MACH_WH2) -+ iproc_mii_read(MII_DEV_LOCAL, addr, reg, &val); -+#else -+ phy5481_rd_reg(ch->etc->unit, addr, PHY_REG_BANK(phyaddr), reg, &val); -+#endif -+#elif defined(CONFIG_MACH_GH) -+ phy5481_rd_reg(ch->etc->unit, addr, PHY_REG_BANK(phyaddr), reg, &val); -+#elif defined(CONFIG_MACH_GH2) -+ phy542xx_rd_reg(addr, PHY_REG_FLAGS(phyaddr), reg, &val); -+#endif /* defined(CONFIG_MACH_GH2) */ -+ -+ return val; -+} -+ -+static void -+chipphywr(ch_t *ch, uint phyaddr, uint reg, uint16 val) -+{ -+ uint32 addr = PHY_REG_ADDR(phyaddr); -+ -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) -+ if (PHY_REG_BUS(phyaddr)) { /* Internal serdes */ -+ serdes_wr_reg(ch->etc->unit, addr, reg, val); -+ } else { -+ phy5461_wr_reg(ch->etc->unit, addr, -+ PHY_REG_FLAGS(phyaddr) ? SOC_PHY_REG_1000X : 0, -+ PHY_REG_BANK(phyaddr), reg, &val); -+ } -+#elif defined(CONFIG_MACH_HR2) -+ phy5221_wr_reg(ch->etc->unit, addr, PHY_REG_BANK(phyaddr), reg, &val); -+#elif defined(CONFIG_MACH_HR3) -+#if defined(CONFIG_MACH_WH2) -+ iproc_mii_write(MII_DEV_LOCAL, addr, reg, val); -+#else -+ phy5481_wr_reg(ch->etc->unit, addr, PHY_REG_BANK(phyaddr), reg, &val); -+#endif -+#elif defined(CONFIG_MACH_GH) -+ phy5481_wr_reg(ch->etc->unit, addr, PHY_REG_BANK(phyaddr), reg, &val); -+#elif defined(CONFIG_MACH_GH2) -+ phy542xx_wr_reg(addr, PHY_REG_FLAGS(phyaddr), reg, val); -+#endif /* defined(CONFIG_MACH_GH2) */ -+} -+ -+static void -+chipphyor(ch_t *ch, uint phyaddr, uint reg, uint16 val) -+{ -+ uint16 tmp; -+ -+ tmp = chipphyrd(ch, phyaddr, reg); -+ tmp |= val; -+ chipphywr(ch, phyaddr, reg, tmp); -+} -+ -+static void -+chipphyreset(ch_t *ch) -+{ -+ uint ext_phyaddr = ch->etc->phyaddr; -+ uint int_phyaddr = ch->etc->int_phyaddr; -+ -+ ASSERT(ext_phyaddr < MAXEPHY); -+ if (ext_phyaddr == EPHY_NOREG) { -+ return; -+ } -+ -+ ET_TRACE(("et%d: chipphyreset, ext_phyaddr: 0x%x, int_phyaddr: 0x%x\n", -+ ch->etc->unit, ext_phyaddr, int_phyaddr)); -+ -+ chipphywr(ch, ext_phyaddr, 0, CTL_RESET); -+ OSL_DELAY(100); -+ if (chipphyrd(ch, ext_phyaddr, 0) & CTL_RESET) { -+ ET_ERROR(("et%d: chipphyreset: reset not complete\n", ch->etc->unit)); -+ } -+ -+ /* Internal serdes reset */ -+ if (int_phyaddr < MAXEPHY) { -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) -+ serdes_reset(ch->etc->unit, int_phyaddr); -+#elif defined(CONFIG_MACH_GH2) -+ sgmiiplus2_serdes_reset(ch->etc->unit, int_phyaddr); -+#elif defined(CONFIG_MACH_WH2) -+ if (select & 0x04) /* select Serdes (SGMII Plus2) path */ -+ sgmiiplus2_serdes_reset(ch->etc->unit, int_phyaddr); -+#endif -+ } -+ -+ chipphyinit(ch); -+} -+ -+static void -+chipphyinit(ch_t *ch) -+{ -+ uint ext_phyaddr = ch->etc->phyaddr; -+ uint int_phyaddr = ch->etc->int_phyaddr; -+ -+ ASSERT(ext_phyaddr < MAXEPHY); -+ if (ext_phyaddr == EPHY_NOREG) { -+ return; -+ } -+ -+ ET_TRACE(("et%d: chipphyinit, ext_phyaddr: 0x%x, int_phyaddr: 0x%x\n", -+ ch->etc->unit, ext_phyaddr, int_phyaddr)); -+ -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) -+ phy5461_init(ch->etc->unit, ext_phyaddr); -+#elif defined(CONFIG_MACH_HR2) -+ phy5221_init(ch->etc->unit, ext_phyaddr); -+#elif defined(CONFIG_MACH_GH) -+ phy5481_init(ch->etc->unit, ext_phyaddr); -+#elif defined(CONFIG_MACH_HR3) -+ -+#if defined(CONFIG_MACH_WH2) -+ if ((select & 0x04) == 0x0) /* select egphy28 path */ -+ { -+ void __iomem *base; -+ base = of_iomap(of_find_compatible_node(NULL, NULL, IPROC_CMICD_COMPATIBLE), 0); -+ egphy28_init(base, ext_phyaddr); -+ } -+#else -+ phy5481_init(ch->etc->unit, ext_phyaddr); -+#endif -+ -+#elif defined(CONFIG_MACH_GH2) -+ phy542xx_init(ext_phyaddr); -+#endif /* defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3) */ -+ -+ /* Internal serdes reset */ -+ if (int_phyaddr < MAXEPHY) { -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) -+ serdes_init(ch->etc->unit, int_phyaddr); -+#elif defined(CONFIG_MACH_GH2) -+ sgmiiplus2_serdes_init(ch->etc->unit, int_phyaddr); -+#elif defined(CONFIG_MACH_WH2) -+ if (select & 0x04) /* select Serdes (SGMII Plus2) path */ -+ { -+ sgmiiplus2_serdes_init(ch->etc->unit, int_phyaddr); -+ } -+#endif -+ } -+} -+ -+static void -+chipphyforce(ch_t *ch, uint phyaddr) -+{ -+ etc_info_t *etc; -+ uint16 ctl; -+#ifdef CONFIG_FORCED_MODE_AUTO_MDIX -+ uint16 adv; -+#endif -+ ASSERT(phyaddr < MAXEPHY); -+ -+ if (phyaddr == EPHY_NOREG) { -+ return; -+ } -+ -+ etc = ch->etc; -+ -+ if (etc->forcespeed == ET_AUTO) { -+ return; -+ } -+ -+ ET_TRACE(("et%d: chipphyforce: phyaddr %d speed %d\n", -+ ch->etc->unit, phyaddr, etc->forcespeed)); -+ -+ ctl = chipphyrd(ch, phyaddr, PHY_MII_CTRLr_ADDR); -+ ctl &= ~(CTL_SPEED | CTL_SPEED_MSB | CTL_ANENAB | CTL_DUPLEX); -+#ifdef CONFIG_FORCED_MODE_AUTO_MDIX -+ adv = chipphyrd(ch, phyaddr, PHY_MII_GB_CTRLr_ADDR); -+ adv &= ~(ADV_1000FULL | ADV_1000HALF); -+ chipphywr(ch, phyaddr, PHY_MII_GB_CTRLr_ADDR, adv); -+ -+ adv = chipphyrd(ch, phyaddr, PHY_MII_ANAr_ADDR); -+ adv &= ~(ADV_100FULL | ADV_100HALF | ADV_10FULL | ADV_10HALF); -+#endif -+ switch (etc->forcespeed) { -+ case ET_10HALF: -+#ifdef CONFIG_FORCED_MODE_AUTO_MDIX -+ adv |= ADV_10HALF; -+#endif -+ break; -+ -+ case ET_10FULL: -+ ctl |= CTL_DUPLEX; -+#ifdef CONFIG_FORCED_MODE_AUTO_MDIX -+ adv |= ADV_10FULL; -+#endif -+ break; -+ -+ case ET_100HALF: -+ ctl |= CTL_SPEED_100; -+#ifdef CONFIG_FORCED_MODE_AUTO_MDIX -+ adv |= ADV_100HALF; -+#endif -+ break; -+ -+ case ET_100FULL: -+ ctl |= (CTL_SPEED_100 | CTL_DUPLEX); -+#ifdef CONFIG_FORCED_MODE_AUTO_MDIX -+ adv |= ADV_100FULL; -+#endif -+ break; -+ -+ case ET_1000FULL: -+ ctl |= (CTL_SPEED_1000 | CTL_DUPLEX); -+ break; -+ } -+ -+ chipphywr(ch, phyaddr, PHY_MII_CTRLr_ADDR, ctl); -+#ifdef CONFIG_FORCED_MODE_AUTO_MDIX -+ chipphywr(ch, phyaddr, PHY_MII_ANAr_ADDR, adv); -+ if (etc->forcespeed != ET_1000FULL) { -+#if defined(CONFIG_MACH_GH2) -+ phy542xx_force_auto_mdix(phyaddr, 0); -+#else -+ adv = chipphyrd(ch, phyaddr | (PHY_MII_MISC_CTRLr_BANK << 8), PHY_MII_MISC_CTRLr_ADDR); -+ adv |= MII_FORCED_AUTO_MDIX; -+ chipphywr(ch, phyaddr | (PHY_MII_MISC_CTRLr_BANK << 8), PHY_MII_MISC_CTRLr_ADDR, adv); -+#endif /* defined(CONFIG_MACH_GH2) */ -+ } -+#endif -+} -+ -+/* set selected capability bits in autonegotiation advertisement */ -+static void -+chipphyadvertise(ch_t *ch, uint phyaddr) -+{ -+ etc_info_t *etc; -+ uint16 adv, adv2; -+ -+ ASSERT(phyaddr < MAXEPHY); -+ -+ if (phyaddr == EPHY_NOREG) { -+ return; -+ } -+ -+ etc = ch->etc; -+ -+ if ((etc->forcespeed != ET_AUTO) || !etc->needautoneg) { -+ return; -+ } -+ -+ ASSERT(etc->advertise); -+ -+ ET_TRACE(("et%d: chipphyadvertise: phyaddr %d advertise %x\n", -+ ch->etc->unit, phyaddr, etc->advertise)); -+ -+ /* reset our advertised capabilitity bits */ -+ adv = chipphyrd(ch, phyaddr, PHY_MII_ANAr_ADDR); -+ adv &= ~(ADV_100FULL | ADV_100HALF | ADV_10FULL | ADV_10HALF); -+ adv |= (etc->advertise | ADV_PAUSE); -+ chipphywr(ch, phyaddr, PHY_MII_ANAr_ADDR, adv); -+ -+ adv2 = chipphyrd(ch, phyaddr, PHY_MII_GB_CTRLr_ADDR); -+ adv2 &= ~(ADV_1000FULL | ADV_1000HALF); -+ adv2 |= etc->advertise2; -+ chipphywr(ch, phyaddr, PHY_MII_GB_CTRLr_ADDR, adv2); -+ -+ ET_TRACE(("et%d: chipphyadvertise: phyaddr %d adv %x adv2 %x phyad0 %x\n", -+ ch->etc->unit, phyaddr, adv, adv2, chipphyrd(ch, phyaddr, 0))); -+#ifdef CONFIG_FORCED_MODE_AUTO_MDIX -+#if defined(CONFIG_MACH_GH2) -+ phy542xx_force_auto_mdix(phyaddr, 0); -+#else -+ adv = chipphyrd(ch, phyaddr | (PHY_MII_MISC_CTRLr_BANK << 8), PHY_MII_MISC_CTRLr_ADDR); -+ if (adv & MII_FORCED_AUTO_MDIX) { -+ adv &= ~MII_FORCED_AUTO_MDIX; -+ chipphywr(ch, phyaddr | (PHY_MII_MISC_CTRLr_BANK << 8), PHY_MII_MISC_CTRLr_ADDR, adv); -+ } -+#endif /* defined(CONFIG_MACH_GH2) */ -+#endif -+ /* restart autonegotiation */ -+ chipphyor(ch, phyaddr, PHY_MII_CTRLr_ADDR, CTL_RESTART); -+ etc->needautoneg = FALSE; -+} -+ -+static void -+chipphyenable(ch_t *ch, uint eth_num, uint phyaddr, int enable) -+{ -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2)) -+ phy5461_enable_set(eth_num, phyaddr, enable); -+#elif defined(CONFIG_MACH_HR2) -+ phy5221_enable_set(eth_num, phyaddr, enable); -+#elif defined(CONFIG_MACH_GH) -+ phy5481_enable_set(eth_num, phyaddr, enable); -+#elif defined(CONFIG_MACH_HR3) -+#if defined(CONFIG_MACH_WH2) -+ if ((select & 0x04) == 0x0) /* Select EGPHY28 path */ -+ egphy28_enable_set(phyaddr, enable); -+#else -+ phy5481_enable_set(eth_num, phyaddr, enable); -+#endif -+#elif defined(CONFIG_MACH_GH2) -+ phy542xx_enable_set(phyaddr, enable); -+#endif /* defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2) */ -+} -+ -+#ifdef GMAC_RATE_LIMITING -+void -+etc_check_rate_limiting(etc_info_t *etc, void *pch) -+{ -+ /*ch_t *ch = (ch_t*)pch;*/ -+ uint32 timediff, unit; -+ int bc_cnt_diff; -+ static uint32 first_run[2]={1,1}; -+ static uint32 prev_bc_frame_cnt[2]={0,0}, bc_frame_cnt[2]={0,0}; -+ -+ unit = etc->unit; -+ if (first_run[unit]) { -+ bc_frame_cnt[unit] = etc->rx_bc_frame_cnt; -+ prev_bc_frame_cnt[unit] = bc_frame_cnt[unit]; -+ first_run[unit] = 0; -+ } -+ else { -+ bc_cnt_diff = etc->rx_bc_frame_cnt - prev_bc_frame_cnt[unit]; -+ if (bc_cnt_diff >= 0) -+ bc_frame_cnt[unit] += bc_cnt_diff; -+ else -+ bc_frame_cnt[unit] += (bc_cnt_diff + 0xffffffff + 0x1); -+ prev_bc_frame_cnt[unit] = etc->rx_bc_frame_cnt; -+ } -+ -+ timediff = ((long)jiffies - (long)(etc->rl_prior_jiffies)); -+ if ((timediff >> 5) != 0) { -+ /* -+ * 32 or more jiffies have gone by, See if -+ * we're seeing too many broadcast packets. -+ */ -+ if ((timediff >> 5) == 1) { -+ /* 32-63 jiffies elapsed */ -+ if (((bc_frame_cnt[unit] >> 10) != 0) && -+ !(etc->rl_stopping_broadcasts)) { -+ /* 1K or more broadcast packets have arrived in -+ * 32-63 jiffies; try to throttle back the -+ * incoming packets -+ */ -+ etc->rl_stopping_broadcasts = 1; -+ printk("et%d: %s: stopping broadcasts bc_frame_cnts(0x%x)\n", -+ etc->unit, __FUNCTION__, bc_frame_cnt[unit]); -+ if (!timer_pending(&etc->rl_timer)) { -+ etc->rl_timer.expires = jiffies + HZ; -+ add_timer(&etc->rl_timer); -+ etc->rl_set=TRUE; -+ } -+ } -+ } -+ etc->rl_prior_jiffies = jiffies; -+ bc_frame_cnt[unit] = 0; -+ } -+} -+#endif /* GMAC_RATE_LIMITING */ -+ -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/et/sys/etcgmac.h b/drivers/net/ethernet/broadcom/gmac/src/et/sys/etcgmac.h ---- a/drivers/net/ethernet/broadcom/gmac/src/et/sys/etcgmac.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/et/sys/etcgmac.h 2017-11-09 17:53:43.905290000 +0800 -@@ -0,0 +1,65 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * Broadcom Gigabit Ethernet MAC defines. -+ * -+ * $Id: etcgmac.h 267700 2011-06-19 15:41:07Z sudhirbs $ -+ */ -+ -+#ifndef _ETCGMAC_H_ -+#define _ETCGMAC_H_ -+ -+#if (defined(CONFIG_MACH_HR2) || defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3)) -+#define IPROC_NUM_GMACS 1 -+#else -+#define IPROC_NUM_GMACS 2 -+#endif -+ -+/* chip interrupt bit error summary */ -+#define I_ERRORS (I_PDEE | I_PDE | I_DE | I_RDU | I_RFO | I_XFU) -+#define DEF_INTMASK (I_XI0 | I_XI1 | I_XI2 | I_XI3 | I_RI | I_ERRORS) -+ -+#define GMAC_RESET_DELAY 2 -+ -+#define GMAC_MIN_FRAMESIZE 17 /* gmac can only send frames of -+ * size above 17 octetes. -+ */ -+ -+#define LOOPBACK_MODE_DMA 0 /* loopback the packet at the DMA engine */ -+#define LOOPBACK_MODE_MAC 1 /* loopback the packet at MAC */ -+#define LOOPBACK_MODE_NONE 2 /* no Loopback */ -+ -+#define FA2_GMAC_MAX_LEN 2048 -+ -+#define DMAREG(ch, dir, qnum) ((dir == DMA_TX) ? \ -+ (void *)(uintptr)&(ch->regs->dmaregs[qnum].dmaxmt) : \ -+ (void *)(uintptr)&(ch->regs->dmaregs[qnum].dmarcv)) -+ -+/* -+ * Add multicast address to the list. Multicast address are maintained as -+ * hash table with chaining. -+ */ -+typedef struct mclist { -+ struct ether_addr mc_addr; /* multicast address to allow */ -+ struct mclist *next; /* next entry */ -+} mflist_t; -+ -+#define GMAC_HASHT_SIZE 16 /* hash table size */ -+#define GMAC_MCADDR_HASH(m) ((((uint8 *)(m))[3] + ((uint8 *)(m))[4] + \ -+ ((uint8 *)(m))[5]) & (GMAC_HASHT_SIZE - 1)) -+ -+#define ETHER_MCADDR_CMP(x, y) ((((uint16 *)(x))[0] ^ ((uint16 *)(y))[0]) | \ -+ (((uint16 *)(x))[1] ^ ((uint16 *)(y))[1]) | \ -+ (((uint16 *)(x))[2] ^ ((uint16 *)(y))[2])) -+ -+#define SUCCESS 0 -+#define FAILURE -1 -+ -+typedef struct mcfilter { -+ /* hash table for multicast filtering */ -+ mflist_t *bucket[GMAC_HASHT_SIZE]; -+} mcfilter_t; -+ -+extern uint32 find_priq(uint32 pri_map); -+ -+#endif /* _ETCGMAC_H_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/Makefile b/drivers/net/ethernet/broadcom/gmac/src/include/Makefile ---- a/drivers/net/ethernet/broadcom/gmac/src/include/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/Makefile 2017-11-09 17:53:43.912294000 +0800 -@@ -0,0 +1,62 @@ -+# This script serves following purpose: -+# -+# 1. It generates native version information by querying -+# automerger maintained database to see where src/include -+# came from -+# 2. For select components, as listed in compvers.sh -+# it generates component version files -+# -+# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+# -+# 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. -+# -+# -+ -+SRCBASE := .. -+ -+TARGETS := epivers.h -+ -+ifdef VERBOSE -+export VERBOSE -+endif -+ -+all release: epivers compvers -+ -+# Generate epivers.h for native branch version -+epivers: -+ bash epivers.sh -+ -+# Generate epivers.h for native branch version -+compvers: -+ @if [ -s "compvers.sh" ]; then \ -+ echo "Generating component versions, if any"; \ -+ bash compvers.sh; \ -+ else \ -+ echo "Skipping component version generation"; \ -+ fi -+ -+# Generate epivers.h for native branch version -+clean_compvers: -+ @if [ -s "compvers.sh" ]; then \ -+ echo "bash compvers.sh clean"; \ -+ bash compvers.sh clean; \ -+ else \ -+ echo "Skipping component version clean"; \ -+ fi -+ -+clean: -+ rm -f $(TARGETS) *.prev -+ -+clean_all: clean clean_compvers -+ -+.PHONY: all release clean epivers compvers clean_compvers -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/aidmp.h b/drivers/net/ethernet/broadcom/gmac/src/include/aidmp.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/aidmp.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/aidmp.h 2017-11-09 17:53:43.913291000 +0800 -@@ -0,0 +1,383 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom AMBA Interconnect definitions. -+ * -+ * $Id: aidmp.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _AIDMP_H -+#define _AIDMP_H -+ -+/* Manufacturer Ids */ -+#define MFGID_ARM 0x43b -+#define MFGID_BRCM 0x4bf -+#define MFGID_MIPS 0x4a7 -+ -+/* Component Classes */ -+#define CC_SIM 0 -+#define CC_EROM 1 -+#define CC_CORESIGHT 9 -+#define CC_VERIF 0xb -+#define CC_OPTIMO 0xd -+#define CC_GEN 0xe -+#define CC_PRIMECELL 0xf -+ -+/* Enumeration ROM registers */ -+#define ER_EROMENTRY 0x000 -+#define ER_REMAPCONTROL 0xe00 -+#define ER_REMAPSELECT 0xe04 -+#define ER_MASTERSELECT 0xe10 -+#define ER_ITCR 0xf00 -+#define ER_ITIP 0xf04 -+ -+/* Erom entries */ -+#define ER_TAG 0xe -+#define ER_TAG1 0x6 -+#define ER_VALID 1 -+#define ER_CI 0 -+#define ER_MP 2 -+#define ER_ADD 4 -+#define ER_END 0xe -+#define ER_BAD 0xffffffff -+ -+/* EROM CompIdentA */ -+#define CIA_MFG_MASK 0xfff00000 -+#define CIA_MFG_SHIFT 20 -+#define CIA_CID_MASK 0x000fff00 -+#define CIA_CID_SHIFT 8 -+#define CIA_CCL_MASK 0x000000f0 -+#define CIA_CCL_SHIFT 4 -+ -+/* EROM CompIdentB */ -+#define CIB_REV_MASK 0xff000000 -+#define CIB_REV_SHIFT 24 -+#define CIB_NSW_MASK 0x00f80000 -+#define CIB_NSW_SHIFT 19 -+#define CIB_NMW_MASK 0x0007c000 -+#define CIB_NMW_SHIFT 14 -+#define CIB_NSP_MASK 0x00003e00 -+#define CIB_NSP_SHIFT 9 -+#define CIB_NMP_MASK 0x000001f0 -+#define CIB_NMP_SHIFT 4 -+ -+/* EROM MasterPortDesc */ -+#define MPD_MUI_MASK 0x0000ff00 -+#define MPD_MUI_SHIFT 8 -+#define MPD_MP_MASK 0x000000f0 -+#define MPD_MP_SHIFT 4 -+ -+/* EROM AddrDesc */ -+#define AD_ADDR_MASK 0xfffff000 -+#define AD_SP_MASK 0x00000f00 -+#define AD_SP_SHIFT 8 -+#define AD_ST_MASK 0x000000c0 -+#define AD_ST_SHIFT 6 -+#define AD_ST_SLAVE 0x00000000 -+#define AD_ST_BRIDGE 0x00000040 -+#define AD_ST_SWRAP 0x00000080 -+#define AD_ST_MWRAP 0x000000c0 -+#define AD_SZ_MASK 0x00000030 -+#define AD_SZ_SHIFT 4 -+#define AD_SZ_4K 0x00000000 -+#define AD_SZ_8K 0x00000010 -+#define AD_SZ_16K 0x00000020 -+#define AD_SZ_SZD 0x00000030 -+#define AD_AG32 0x00000008 -+#define AD_ADDR_ALIGN 0x00000fff -+#define AD_SZ_BASE 0x00001000 /* 4KB */ -+ -+/* EROM SizeDesc */ -+#define SD_SZ_MASK 0xfffff000 -+#define SD_SG32 0x00000008 -+#define SD_SZ_ALIGN 0x00000fff -+ -+ -+#ifndef _LANGUAGE_ASSEMBLY -+ -+typedef volatile struct _aidmp { -+ uint32 oobselina30; /* 0x000 */ -+ uint32 oobselina74; /* 0x004 */ -+ uint32 PAD[6]; -+ uint32 oobselinb30; /* 0x020 */ -+ uint32 oobselinb74; /* 0x024 */ -+ uint32 PAD[6]; -+ uint32 oobselinc30; /* 0x040 */ -+ uint32 oobselinc74; /* 0x044 */ -+ uint32 PAD[6]; -+ uint32 oobselind30; /* 0x060 */ -+ uint32 oobselind74; /* 0x064 */ -+ uint32 PAD[38]; -+ uint32 oobselouta30; /* 0x100 */ -+ uint32 oobselouta74; /* 0x104 */ -+ uint32 PAD[6]; -+ uint32 oobseloutb30; /* 0x120 */ -+ uint32 oobseloutb74; /* 0x124 */ -+ uint32 PAD[6]; -+ uint32 oobseloutc30; /* 0x140 */ -+ uint32 oobseloutc74; /* 0x144 */ -+ uint32 PAD[6]; -+ uint32 oobseloutd30; /* 0x160 */ -+ uint32 oobseloutd74; /* 0x164 */ -+ uint32 PAD[38]; -+ uint32 oobsynca; /* 0x200 */ -+ uint32 oobseloutaen; /* 0x204 */ -+ uint32 PAD[6]; -+ uint32 oobsyncb; /* 0x220 */ -+ uint32 oobseloutben; /* 0x224 */ -+ uint32 PAD[6]; -+ uint32 oobsyncc; /* 0x240 */ -+ uint32 oobseloutcen; /* 0x244 */ -+ uint32 PAD[6]; -+ uint32 oobsyncd; /* 0x260 */ -+ uint32 oobseloutden; /* 0x264 */ -+ uint32 PAD[38]; -+ uint32 oobaextwidth; /* 0x300 */ -+ uint32 oobainwidth; /* 0x304 */ -+ uint32 oobaoutwidth; /* 0x308 */ -+ uint32 PAD[5]; -+ uint32 oobbextwidth; /* 0x320 */ -+ uint32 oobbinwidth; /* 0x324 */ -+ uint32 oobboutwidth; /* 0x328 */ -+ uint32 PAD[5]; -+ uint32 oobcextwidth; /* 0x340 */ -+ uint32 oobcinwidth; /* 0x344 */ -+ uint32 oobcoutwidth; /* 0x348 */ -+ uint32 PAD[5]; -+ uint32 oobdextwidth; /* 0x360 */ -+ uint32 oobdinwidth; /* 0x364 */ -+ uint32 oobdoutwidth; /* 0x368 */ -+ uint32 PAD[37]; -+ uint32 ioctrlset; /* 0x400 */ -+ uint32 ioctrlclear; /* 0x404 */ -+ uint32 ioctrl; /* 0x408 */ -+ uint32 PAD[61]; -+ uint32 iostatus; /* 0x500 */ -+ uint32 PAD[127]; -+ uint32 ioctrlwidth; /* 0x700 */ -+ uint32 iostatuswidth; /* 0x704 */ -+ uint32 PAD[62]; -+ uint32 resetctrl; /* 0x800 */ -+ uint32 resetstatus; /* 0x804 */ -+ uint32 resetreadid; /* 0x808 */ -+ uint32 resetwriteid; /* 0x80c */ -+ uint32 PAD[60]; -+ uint32 errlogctrl; /* 0x900 */ -+ uint32 errlogdone; /* 0x904 */ -+ uint32 errlogstatus; /* 0x908 */ -+ uint32 errlogaddrlo; /* 0x90c */ -+ uint32 errlogaddrhi; /* 0x910 */ -+ uint32 errlogid; /* 0x914 */ -+ uint32 errloguser; /* 0x918 */ -+ uint32 errlogflags; /* 0x91c */ -+ uint32 PAD[56]; -+ uint32 intstatus; /* 0xa00 */ -+ uint32 PAD[255]; -+ uint32 config; /* 0xe00 */ -+ uint32 PAD[63]; -+ uint32 itcr; /* 0xf00 */ -+ uint32 PAD[3]; -+ uint32 itipooba; /* 0xf10 */ -+ uint32 itipoobb; /* 0xf14 */ -+ uint32 itipoobc; /* 0xf18 */ -+ uint32 itipoobd; /* 0xf1c */ -+ uint32 PAD[4]; -+ uint32 itipoobaout; /* 0xf30 */ -+ uint32 itipoobbout; /* 0xf34 */ -+ uint32 itipoobcout; /* 0xf38 */ -+ uint32 itipoobdout; /* 0xf3c */ -+ uint32 PAD[4]; -+ uint32 itopooba; /* 0xf50 */ -+ uint32 itopoobb; /* 0xf54 */ -+ uint32 itopoobc; /* 0xf58 */ -+ uint32 itopoobd; /* 0xf5c */ -+ uint32 PAD[4]; -+ uint32 itopoobain; /* 0xf70 */ -+ uint32 itopoobbin; /* 0xf74 */ -+ uint32 itopoobcin; /* 0xf78 */ -+ uint32 itopoobdin; /* 0xf7c */ -+ uint32 PAD[4]; -+ uint32 itopreset; /* 0xf90 */ -+ uint32 PAD[15]; -+ uint32 peripherialid4; /* 0xfd0 */ -+ uint32 peripherialid5; /* 0xfd4 */ -+ uint32 peripherialid6; /* 0xfd8 */ -+ uint32 peripherialid7; /* 0xfdc */ -+ uint32 peripherialid0; /* 0xfe0 */ -+ uint32 peripherialid1; /* 0xfe4 */ -+ uint32 peripherialid2; /* 0xfe8 */ -+ uint32 peripherialid3; /* 0xfec */ -+ uint32 componentid0; /* 0xff0 */ -+ uint32 componentid1; /* 0xff4 */ -+ uint32 componentid2; /* 0xff8 */ -+ uint32 componentid3; /* 0xffc */ -+} aidmp_t; -+ -+#endif /* _LANGUAGE_ASSEMBLY */ -+ -+/* Out-of-band Router registers */ -+#define OOB_BUSCONFIG 0x020 -+#define OOB_STATUSA 0x100 -+#define OOB_STATUSB 0x104 -+#define OOB_STATUSC 0x108 -+#define OOB_STATUSD 0x10c -+#define OOB_ENABLEA0 0x200 -+#define OOB_ENABLEA1 0x204 -+#define OOB_ENABLEA2 0x208 -+#define OOB_ENABLEA3 0x20c -+#define OOB_ENABLEB0 0x280 -+#define OOB_ENABLEB1 0x284 -+#define OOB_ENABLEB2 0x288 -+#define OOB_ENABLEB3 0x28c -+#define OOB_ENABLEC0 0x300 -+#define OOB_ENABLEC1 0x304 -+#define OOB_ENABLEC2 0x308 -+#define OOB_ENABLEC3 0x30c -+#define OOB_ENABLED0 0x380 -+#define OOB_ENABLED1 0x384 -+#define OOB_ENABLED2 0x388 -+#define OOB_ENABLED3 0x38c -+#define OOB_ITCR 0xf00 -+#define OOB_ITIPOOBA 0xf10 -+#define OOB_ITIPOOBB 0xf14 -+#define OOB_ITIPOOBC 0xf18 -+#define OOB_ITIPOOBD 0xf1c -+#define OOB_ITOPOOBA 0xf30 -+#define OOB_ITOPOOBB 0xf34 -+#define OOB_ITOPOOBC 0xf38 -+#define OOB_ITOPOOBD 0xf3c -+ -+/* DMP wrapper registers */ -+#define AI_OOBSELINA30 0x000 -+#define AI_OOBSELINA74 0x004 -+#define AI_OOBSELINB30 0x020 -+#define AI_OOBSELINB74 0x024 -+#define AI_OOBSELINC30 0x040 -+#define AI_OOBSELINC74 0x044 -+#define AI_OOBSELIND30 0x060 -+#define AI_OOBSELIND74 0x064 -+#define AI_OOBSELOUTA30 0x100 -+#define AI_OOBSELOUTA74 0x104 -+#define AI_OOBSELOUTB30 0x120 -+#define AI_OOBSELOUTB74 0x124 -+#define AI_OOBSELOUTC30 0x140 -+#define AI_OOBSELOUTC74 0x144 -+#define AI_OOBSELOUTD30 0x160 -+#define AI_OOBSELOUTD74 0x164 -+#define AI_OOBSYNCA 0x200 -+#define AI_OOBSELOUTAEN 0x204 -+#define AI_OOBSYNCB 0x220 -+#define AI_OOBSELOUTBEN 0x224 -+#define AI_OOBSYNCC 0x240 -+#define AI_OOBSELOUTCEN 0x244 -+#define AI_OOBSYNCD 0x260 -+#define AI_OOBSELOUTDEN 0x264 -+#define AI_OOBAEXTWIDTH 0x300 -+#define AI_OOBAINWIDTH 0x304 -+#define AI_OOBAOUTWIDTH 0x308 -+#define AI_OOBBEXTWIDTH 0x320 -+#define AI_OOBBINWIDTH 0x324 -+#define AI_OOBBOUTWIDTH 0x328 -+#define AI_OOBCEXTWIDTH 0x340 -+#define AI_OOBCINWIDTH 0x344 -+#define AI_OOBCOUTWIDTH 0x348 -+#define AI_OOBDEXTWIDTH 0x360 -+#define AI_OOBDINWIDTH 0x364 -+#define AI_OOBDOUTWIDTH 0x368 -+ -+#if defined(IL_BIGENDIAN) && defined(BCMHND74K) -+/* Selective swapped defines for those registers we need in -+ * big-endian code. -+ */ -+#define AI_IOCTRLSET 0x404 -+#define AI_IOCTRLCLEAR 0x400 -+#define AI_IOCTRL 0x40c -+#define AI_IOSTATUS 0x504 -+#define AI_RESETCTRL 0x804 -+#define AI_RESETSTATUS 0x800 -+ -+#else /* !IL_BIGENDIAN || !BCMHND74K */ -+ -+#define AI_IOCTRLSET 0x400 -+#define AI_IOCTRLCLEAR 0x404 -+#define AI_IOCTRL 0x408 -+#define AI_IOSTATUS 0x500 -+#define AI_RESETCTRL 0x800 -+#define AI_RESETSTATUS 0x804 -+ -+#endif /* IL_BIGENDIAN && BCMHND74K */ -+ -+#define AI_IOCTRLWIDTH 0x700 -+#define AI_IOSTATUSWIDTH 0x704 -+ -+#define AI_RESETREADID 0x808 -+#define AI_RESETWRITEID 0x80c -+#define AI_ERRLOGCTRL 0xa00 -+#define AI_ERRLOGDONE 0xa04 -+#define AI_ERRLOGSTATUS 0xa08 -+#define AI_ERRLOGADDRLO 0xa0c -+#define AI_ERRLOGADDRHI 0xa10 -+#define AI_ERRLOGID 0xa14 -+#define AI_ERRLOGUSER 0xa18 -+#define AI_ERRLOGFLAGS 0xa1c -+#define AI_INTSTATUS 0xa00 -+#define AI_CONFIG 0xe00 -+#define AI_ITCR 0xf00 -+#define AI_ITIPOOBA 0xf10 -+#define AI_ITIPOOBB 0xf14 -+#define AI_ITIPOOBC 0xf18 -+#define AI_ITIPOOBD 0xf1c -+#define AI_ITIPOOBAOUT 0xf30 -+#define AI_ITIPOOBBOUT 0xf34 -+#define AI_ITIPOOBCOUT 0xf38 -+#define AI_ITIPOOBDOUT 0xf3c -+#define AI_ITOPOOBA 0xf50 -+#define AI_ITOPOOBB 0xf54 -+#define AI_ITOPOOBC 0xf58 -+#define AI_ITOPOOBD 0xf5c -+#define AI_ITOPOOBAIN 0xf70 -+#define AI_ITOPOOBBIN 0xf74 -+#define AI_ITOPOOBCIN 0xf78 -+#define AI_ITOPOOBDIN 0xf7c -+#define AI_ITOPRESET 0xf90 -+#define AI_PERIPHERIALID4 0xfd0 -+#define AI_PERIPHERIALID5 0xfd4 -+#define AI_PERIPHERIALID6 0xfd8 -+#define AI_PERIPHERIALID7 0xfdc -+#define AI_PERIPHERIALID0 0xfe0 -+#define AI_PERIPHERIALID1 0xfe4 -+#define AI_PERIPHERIALID2 0xfe8 -+#define AI_PERIPHERIALID3 0xfec -+#define AI_COMPONENTID0 0xff0 -+#define AI_COMPONENTID1 0xff4 -+#define AI_COMPONENTID2 0xff8 -+#define AI_COMPONENTID3 0xffc -+ -+/* resetctrl */ -+#define AIRC_RESET 1 -+ -+/* config */ -+#define AICFG_OOB 0x00000020 -+#define AICFG_IOS 0x00000010 -+#define AICFG_IOC 0x00000008 -+#define AICFG_TO 0x00000004 -+#define AICFG_ERRL 0x00000002 -+#define AICFG_RST 0x00000001 -+ -+/* bit defines for AI_OOBSELOUTB74 reg */ -+#define OOB_SEL_OUTEN_B_5 15 -+#define OOB_SEL_OUTEN_B_6 23 -+ -+#endif /* _AIDMP_H */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/arminc.h b/drivers/net/ethernet/broadcom/gmac/src/include/arminc.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/arminc.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/arminc.h 2017-11-09 17:53:43.914306000 +0800 -@@ -0,0 +1,317 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * HND Run Time Environment for standalone ARM programs. -+ * -+ * $Id: arminc.h 325951 2012-04-05 06:03:27Z $ -+ */ -+ -+#ifndef _ARMINC_H -+#define _ARMINC_H -+ -+ -+/* ARM defines */ -+ -+#ifdef _LANGUAGE_ASSEMBLY -+ -+/* -+ * LEAF - declare leaf routine -+ */ -+#define LEAF(function) \ -+ .section .text.function, "ax"; \ -+ .global function; \ -+ .func function; \ -+function: -+ -+#define THUMBLEAF(function) \ -+ .section .text.function, "ax"; \ -+ .global function; \ -+ .func function; \ -+ .thumb; \ -+ .thumb_func; \ -+function: -+ -+/* -+ * END - mark end of function -+ */ -+#define END(function) \ -+ .ltorg; \ -+ .endfunc; \ -+ .size function, . - function -+ -+#define DW(var, val) \ -+ .global var; \ -+ .type var, %object; \ -+ .size var, 4; \ -+ .align 2; \ -+var: .word val -+ -+ -+#define _ULCAST_ -+ -+#else -+ -+/* -+ * The following macros are especially useful for __asm__ -+ * inline assembler. -+ */ -+#ifndef __STR -+#define __STR(x) #x -+#endif -+#ifndef STR -+#define STR(x) __STR(x) -+#endif -+ -+#define _ULCAST_ (unsigned long) -+ -+#endif /* _LANGUAGE_ASSEMBLY */ -+ -+ -+#if defined(__ARM_ARCH_7M__) /* Cortex-M3 */ -+ -+/* Data Watchpoint and Trigger */ -+#define CM3_DWT_CTRL 0xe0001000 -+#define CM3_DWT_CYCCNT 0xe0001004 -+#define CM3_DWT_CPICNT 0xe0001008 -+#define CM3_DWT_EXCCNT 0xe000100c -+#define CM3_DWT_SLEEPCNT 0xe0001010 -+#define CM3_DWT_LSUCNT 0xe0001014 -+#define CM3_DWT_FOLDCNT 0xe0001018 -+#define CM3_DWT_COMP0 0xe0001020 -+#define CM3_DWT_MASK0 0xe0001024 -+#define CM3_DWT_FUNCTION0 0xe0001028 -+#define CM3_DWT_COMP1 0xe0001030 -+#define CM3_DWT_MASK1 0xe0001034 -+#define CM3_DWT_FUNCTION1 0xe0001038 -+#define CM3_DWT_COMP2 0xe0001040 -+#define CM3_DWT_MASK2 0xe0001044 -+#define CM3_DWT_FUNCTION2 0xe0001048 -+#define CM3_DWT_COMP3 0xe0001050 -+#define CM3_DWT_MASK3 0xe0001054 -+#define CM3_DWT_FUNCTION3 0xe0001058 -+ -+#define CM3_DWT_FUNCTION_DISAB 0 -+#define CM3_DWT_FUNCTION_WP_PCMATCH 4 -+#define CM3_DWT_FUNCTION_WP_READ 5 -+#define CM3_DWT_FUNCTION_WP_WRITE 6 -+#define CM3_DWT_FUNCTION_WP_RDWR 7 -+ -+#define CM3_NVIC_IC_TYPE 0xe000e004 /* Interrupt Control Type Reg */ -+#define CM3_NVIC_TICK_CSR 0xe000e010 /* SysTick Control and Status Reg */ -+#define CM3_NVIC_TICK_CSR_COUNTFLAG 0x10000 -+#define CM3_NVIC_TICK_CSR_CLKSOURCE 0x4 /* Set for core clock, 0 for ext ref */ -+#define CM3_NVIC_TICK_CSR_TICKINT 0x2 /* Set for intr on count going 1 => 0 */ -+#define CM3_NVIC_TICK_CSR_ENABLE 0x1 -+#define CM3_NVIC_TICK_RLDVAL 0xe000e014 /* SysTick Reload Value Reg */ -+#define CM3_NVIC_TICK_CURVAL 0xe000e018 /* SysTick Current Value Reg */ -+#define CM3_NVIC_TICK_CALVAL 0xe000e01c /* SysTick Calibration Value Reg */ -+ -+/* Interrupt enable/disable register */ -+#define CM3_NVIC_IRQ_SET_EN0 0xe000e100 /* Irq 0 to 31 Set Enable Reg */ -+#define CM3_NVIC_IRQ_SET_EN(n) (0xe000e100 + (n) * 4) /* Irq 0-31, 32-63, ..., 224-239 */ -+ -+#define CM3_NVIC_IRQ_CLR_EN0 0xe000e180 /* Irq 0 to 31 Clear Enable Reg [...] */ -+#define CM3_NVIC_IRQ_CLR_EN(n) (0xe000e180 + (n) * 4) /* Irq 0-31, 32-63, ..., 224-239 */ -+ -+#define CM3_NVIC_IRQ_SET_PND0 0xe000e200 /* Irq 0 to 31 Set Pending Reg [...] */ -+#define CM3_NVIC_IRQ_SET_PND(n) (0xe000e200 + (n) * 4) /* Irq 0-31, 32-63, ..., 224-239 */ -+ -+#define CM3_NVIC_IRQ_CLR_PND0 0xe000e280 /* Irq 0 to 31 Clear Pending Reg [...] */ -+#define CM3_NVIC_IRQ_CLR_PND(n) (0xe000e280 + (n) * 4) /* Irq 0-31, 32-63, ..., 224-239 */ -+ -+#define CM3_NVIC_IRQ_ACT_BIT0 0xe000e300 /* Irq 0 to 31 Active Bit Reg [...] */ -+#define CM3_NVIC_IRQ_ACT_BIT(n) (0xe000e300 + (n) * 4) /* Irq 0-31, 32-63, ..., 224-239 */ -+ -+#define CM3_NVIC_IRQ_PRIO0 0xe000e400 /* Irq 0 to 31 Priority Reg [...] */ -+#define CM3_NVIC_IRQ_PRIO(n) (0xe000e400 + (n) * 4) /* Irq 0-31, 32-63, ..., 224-239 */ -+ -+/* CPU control */ -+#define CM3_CPUID 0xe000ed00 -+#define CM3_INTCTLSTATE 0xe000ed04 -+#define CM3_VTOFF 0xe000ed08 /* Vector Table Offset */ -+#define CM3_SYSCTRL 0xe000ed10 -+#define CM3_CFGCTRL 0xe000ed14 -+#define CM3_CFGCTRL_UNALIGN_TRP 0x8 -+#define CM3_CFGCTRL_DIV_0_TRP 0x10 -+#define CM3_CFGCTRL_STKALIGN 0x200 -+ -+#define CM3_PFR0 0xe000ed40 -+#define CM3_PFR1 0xe000ed44 -+#define CM3_DFR0 0xe000ed48 -+#define CM3_AFR0 0xe000ed4c -+#define CM3_MMFR0 0xe000ed50 -+#define CM3_MMFR1 0xe000ed54 -+#define CM3_MMFR2 0xe000ed58 -+#define CM3_MMFR3 0xe000ed5c -+#define CM3_ISAR0 0xe000ed60 -+#define CM3_ISAR1 0xe000ed64 -+#define CM3_ISAR2 0xe000ed68 -+#define CM3_ISAR3 0xe000ed6c -+#define CM3_ISAR4 0xe000ed70 -+#define CM3_ISAR5 0xe000ed74 -+ -+#define CM3_MPUTYPE 0xe000ed90 -+#define CM3_MPUCTRL 0xe000ed94 -+#define CM3_REGNUM 0xe000ed98 -+#define CM3_REGBAR 0xe000ed9c -+#define CM3_REGASZ 0xe000eda0 -+#define CM3_AL1BAR 0xe000eda4 -+#define CM3_AL1ASZ 0xe000eda8 -+#define CM3_AL2BAR 0xe000edac -+#define CM3_AL2ASZ 0xe000edb0 -+#define CM3_AL3BAR 0xe000edb4 -+#define CM3_AL3ASZ 0xe000edb8 -+ -+#define CM3_DBG_HCSR 0xe000edf0 /* Debug Halting Control and Status Reg */ -+#define CM3_DBG_CRSR 0xe000edf4 /* Debug Core Register Selector Reg */ -+#define CM3_DBG_CRDR 0xe000edf8 /* Debug Core Register Data Reg */ -+#define CM3_DBG_EMCR 0xe000edfc /* Debug Exception and Monitor Control Reg */ -+#define CM3_DBG_EMCR_TRCENA (1U << 24) -+#define CM3_DBG_EMCR_MON_EN (1U << 16) -+ -+/* Trap types */ -+#define TR_RST 1 /* Reset */ -+#define TR_NMI 2 /* NMI */ -+#define TR_FAULT 3 /* Hard Fault */ -+#define TR_MM 4 /* Memory Management */ -+#define TR_BUS 5 /* Bus Fault */ -+#define TR_USAGE 6 /* Usage Fault */ -+#define TR_SVC 11 /* SVCall */ -+#define TR_DMON 12 /* Debug Monitor */ -+#define TR_PENDSV 14 /* PendSV */ -+#define TR_SYSTICK 15 /* SysTick */ -+#define TR_ISR 16 /* External Interrupts start here */ -+ -+#define TR_BAD 256 /* Bad trap: Not used by CM3 */ -+ -+/* Offsets of automatically saved registers from sp upon trap */ -+#define CM3_TROFF_R0 0 -+#define CM3_TROFF_R1 4 -+#define CM3_TROFF_R2 8 -+#define CM3_TROFF_R3 12 -+#define CM3_TROFF_R12 16 -+#define CM3_TROFF_LR 20 -+#define CM3_TROFF_PC 24 -+#define CM3_TROFF_xPSR 28 -+ -+#elif defined(__ARM_ARCH_7A__) /* Cortex-A9 */ -+/* Fields in cpsr */ -+#define PS_USR 0x00000010 /* Mode: User */ -+#define PS_FIQ 0x00000011 /* Mode: FIQ */ -+#define PS_IRQ 0x00000012 /* Mode: IRQ */ -+#define PS_SVC 0x00000013 /* Mode: Supervisor */ -+#define PS_ABT 0x00000017 /* Mode: Abort */ -+#define PS_UND 0x0000001b /* Mode: Undefined */ -+#define PS_SYS 0x0000001f /* Mode: System */ -+#define PS_MM 0x0000001f /* Mode bits mask */ -+#define PS_T 0x00000020 /* Thumb mode */ -+#define PS_F 0x00000040 /* FIQ disable */ -+#define PS_I 0x00000080 /* IRQ disable */ -+#define PS_A 0x00000100 /* Imprecise abort */ -+#define PS_E 0x00000200 /* Endianess */ -+#define PS_IT72 0x0000fc00 /* IT[7:2] */ -+#define PS_GE 0x000f0000 /* IT[7:2] */ -+#define PS_J 0x01000000 /* Java state */ -+#define PS_IT10 0x06000000 /* IT[1:0] */ -+#define PS_Q 0x08000000 /* Sticky overflow */ -+#define PS_V 0x10000000 /* Overflow cc */ -+#define PS_C 0x20000000 /* Carry cc */ -+#define PS_Z 0x40000000 /* Zero cc */ -+#define PS_N 0x80000000 /* Negative cc */ -+ -+/* Trap types */ -+#define TR_RST 0 /* Reset trap */ -+#define TR_UND 1 /* Indefined instruction trap */ -+#define TR_SWI 2 /* Software intrrupt */ -+#define TR_IAB 3 /* Instruction fetch abort */ -+#define TR_DAB 4 /* Data access abort */ -+#define TR_BAD 5 /* Bad trap: Not used by ARM */ -+#define TR_IRQ 6 /* Interrupt */ -+#define TR_FIQ 7 /* Fast interrupt */ -+ -+/* -+ * Memory segments (32bit kernel mode addresses) -+ */ -+#define PHYSADDR_MASK 0xffffffff -+ -+/* -+ * Map an address to a certain kernel segment -+ */ -+#undef PHYSADDR -+#define PHYSADDR(a) (_ULCAST_(a) & PHYSADDR_MASK) -+#else /* !__ARM_ARCH_7M__ */ -+ -+/* Fields in cpsr */ -+#define PS_USR 0x00000010 /* Mode: User */ -+#define PS_FIQ 0x00000011 /* Mode: FIQ */ -+#define PS_IRQ 0x00000012 /* Mode: IRQ */ -+#define PS_SVC 0x00000013 /* Mode: Supervisor */ -+#define PS_ABT 0x00000017 /* Mode: Abort */ -+#define PS_UND 0x0000001b /* Mode: Undefined */ -+#define PS_SYS 0x0000001f /* Mode: System */ -+#define PS_MM 0x0000001f /* Mode bits mask */ -+#define PS_T 0x00000020 /* Thumb mode */ -+#define PS_F 0x00000040 /* FIQ disable */ -+#define PS_I 0x00000080 /* IRQ disable */ -+#define PS_A 0x00000100 /* Imprecise abort */ -+#define PS_E 0x00000200 /* Endianess */ -+#define PS_IT72 0x0000fc00 /* IT[7:2] */ -+#define PS_GE 0x000f0000 /* IT[7:2] */ -+#define PS_J 0x01000000 /* Java state */ -+#define PS_IT10 0x06000000 /* IT[1:0] */ -+#define PS_Q 0x08000000 /* Sticky overflow */ -+#define PS_V 0x10000000 /* Overflow cc */ -+#define PS_C 0x20000000 /* Carry cc */ -+#define PS_Z 0x40000000 /* Zero cc */ -+#define PS_N 0x80000000 /* Negative cc */ -+ -+/* Trap types */ -+#define TR_RST 0 /* Reset trap */ -+#define TR_UND 1 /* Indefined instruction trap */ -+#define TR_SWI 2 /* Software intrrupt */ -+#define TR_IAB 3 /* Instruction fetch abort */ -+#define TR_DAB 4 /* Data access abort */ -+#define TR_BAD 5 /* Bad trap: Not used by ARM */ -+#define TR_IRQ 6 /* Interrupt */ -+#define TR_FIQ 7 /* Fast interrupt */ -+ -+#ifdef BCMDBG_ARMRST -+#define TR_ARMRST 0xF /* Debug facility to trap Arm reset */ -+#endif -+ -+/* used to fill an overlay region with nop's */ -+#define NOP_UINT32 0x46c046c0 -+ -+ -+#define mrc(cp, a, b, n) \ -+({ \ -+ int __res; \ -+ __asm__ __volatile__("\tmrc\tp"STR(cp)", 0, %0, c"STR(a)", c"STR(b)", "STR(n) \ -+ :"=r" (__res)); \ -+ __res; \ -+}) -+ -+ -+#endif /* !__ARM_ARCH_7M__ */ -+ -+/* Pieces of a CPU Id */ -+#define CID_IMPL 0xff000000 /* Implementor: 0x41 for ARM Ltd. */ -+#define CID_VARIANT 0x00f00000 -+#define CID_ARCH 0x000f0000 -+#define CID_PART 0x0000fff0 -+#define CID_REV 0x0000000f -+#define CID_MASK (CID_IMPL | CID_ARCH | CID_PART) -+ -+#endif /* _ARMINC_H */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcm_cfg.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcm_cfg.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcm_cfg.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcm_cfg.h 2017-11-09 17:53:43.915303000 +0800 -@@ -0,0 +1,28 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * BCM common config options -+ * -+ * $Id: bcm_cfg.h 294399 2011-11-07 03:31:22Z $ -+ */ -+ -+#ifndef _bcm_cfg_h_ -+#define _bcm_cfg_h_ -+#if defined(__NetBSD__) || defined(__FreeBSD__) -+#if defined(_KERNEL) -+#include -+#endif /* defined(_KERNEL) */ -+#endif /* defined(__NetBSD__) || defined(__FreeBSD__) */ -+#endif /* _bcm_cfg_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcm_mpool_pub.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcm_mpool_pub.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcm_mpool_pub.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcm_mpool_pub.h 2017-11-09 17:53:43.916305000 +0800 -@@ -0,0 +1,355 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Memory pools library, Public interface -+ * -+ * API Overview -+ * -+ * This package provides a memory allocation subsystem based on pools of -+ * homogenous objects. -+ * -+ * Instrumentation is available for reporting memory utilization both -+ * on a per-data-structure basis and system wide. -+ * -+ * There are two main types defined in this API. -+ * -+ * pool manager: A singleton object that acts as a factory for -+ * pool allocators. It also is used for global -+ * instrumentation, such as reporting all blocks -+ * in use across all data structures. The pool manager -+ * creates and provides individual memory pools -+ * upon request to application code. -+ * -+ * memory pool: An object for allocating homogenous memory blocks. -+ * -+ * Global identifiers in this module use the following prefixes: -+ * bcm_mpm_* Memory pool manager -+ * bcm_mp_* Memory pool -+ * -+ * There are two main types of memory pools: -+ * -+ * prealloc: The contiguous memory block of objects can either be supplied -+ * by the client or malloc'ed by the memory manager. The objects are -+ * allocated out of a block of memory and freed back to the block. -+ * -+ * heap: The memory pool allocator uses the heap (malloc/free) for memory. -+ * In this case, the pool allocator is just providing statistics -+ * and instrumentation on top of the heap, without modifying the heap -+ * allocation implementation. -+ * -+ * $Id$ -+ */ -+ -+#ifndef _BCM_MPOOL_PUB_H -+#define _BCM_MPOOL_PUB_H 1 -+ -+#include /* needed for uint16 */ -+ -+ -+/* -+************************************************************************** -+* -+* Type definitions, handles -+* -+************************************************************************** -+*/ -+ -+/* Forward declaration of OSL handle. */ -+struct osl_info; -+ -+/* Forward declaration of string buffer. */ -+struct bcmstrbuf; -+ -+/* -+ * Opaque type definition for the pool manager handle. This object is used for global -+ * memory pool operations such as obtaining a new pool, deleting a pool, iterating and -+ * instrumentation/debugging. -+ */ -+struct bcm_mpm_mgr; -+typedef struct bcm_mpm_mgr *bcm_mpm_mgr_h; -+ -+/* -+ * Opaque type definition for an instance of a pool. This handle is used for allocating -+ * and freeing memory through the pool, as well as management/instrumentation on this -+ * specific pool. -+ */ -+struct bcm_mp_pool; -+typedef struct bcm_mp_pool *bcm_mp_pool_h; -+ -+ -+/* -+ * To make instrumentation more readable, every memory -+ * pool must have a readable name. Pool names are up to -+ * 8 bytes including '\0' termination. (7 printable characters.) -+ */ -+#define BCM_MP_NAMELEN 8 -+ -+ -+/* -+ * Type definition for pool statistics. -+ */ -+typedef struct bcm_mp_stats { -+ char name[BCM_MP_NAMELEN]; /* Name of this pool. */ -+ unsigned int objsz; /* Object size allocated in this pool */ -+ uint16 nobj; /* Total number of objects in this pool */ -+ uint16 num_alloc; /* Number of objects currently allocated */ -+ uint16 high_water; /* Max number of allocated objects. */ -+ uint16 failed_alloc; /* Failed allocations. */ -+} bcm_mp_stats_t; -+ -+ -+/* -+************************************************************************** -+* -+* API Routines on the pool manager. -+* -+************************************************************************** -+*/ -+ -+/* -+ * bcm_mpm_init() - initialize the whole memory pool system. -+ * -+ * Parameters: -+ * osh: INPUT Operating system handle. Needed for heap memory allocation. -+ * max_pools: INPUT Maximum number of mempools supported. -+ * mgr: OUTPUT The handle is written with the new pools manager object/handle. -+ * -+ * Returns: -+ * BCME_OK Object initialized successfully. May be used. -+ * BCME_NOMEM Initialization failed due to no memory. Object must not be used. -+ */ -+int bcm_mpm_init(struct osl_info *osh, int max_pools, bcm_mpm_mgr_h *mgrp); -+ -+ -+/* -+ * bcm_mpm_deinit() - de-initialize the whole memory pool system. -+ * -+ * Parameters: -+ * mgr: INPUT Pointer to pool manager handle. -+ * -+ * Returns: -+ * BCME_OK Memory pool manager successfully de-initialized. -+ * other Indicated error occured during de-initialization. -+ */ -+int bcm_mpm_deinit(bcm_mpm_mgr_h *mgrp); -+ -+/* -+ * bcm_mpm_create_prealloc_pool() - Create a new pool for fixed size objects. The -+ * pool uses a contiguous block of pre-alloced -+ * memory. The memory block may either be provided -+ * by the client or dynamically allocated by the -+ * pool manager. -+ * -+ * Parameters: -+ * mgr: INPUT The handle to the pool manager -+ * obj_sz: INPUT Size of objects that will be allocated by the new pool -+ * Must be >= sizeof(void *). -+ * nobj: INPUT Maximum number of concurrently existing objects to support -+ * memstart INPUT Pointer to the memory to use, or NULL to malloc() -+ * memsize INPUT Number of bytes referenced from memstart (for error checking). -+ * Must be 0 if 'memstart' is NULL. -+ * poolname INPUT For instrumentation, the name of the pool -+ * newp: OUTPUT The handle for the new pool, if creation is successful -+ * -+ * Returns: -+ * BCME_OK Pool created ok. -+ * other Pool not created due to indicated error. newpoolp set to NULL. -+ * -+ * -+ */ -+int bcm_mpm_create_prealloc_pool(bcm_mpm_mgr_h mgr, -+ unsigned int obj_sz, -+ int nobj, -+ void *memstart, -+ unsigned int memsize, -+ char poolname[BCM_MP_NAMELEN], -+ bcm_mp_pool_h *newp); -+ -+ -+/* -+ * bcm_mpm_delete_prealloc_pool() - Delete a memory pool. This should only be called after -+ * all memory objects have been freed back to the pool. -+ * -+ * Parameters: -+ * mgr: INPUT The handle to the pools manager -+ * pool: INPUT The handle of the pool to delete -+ * -+ * Returns: -+ * BCME_OK Pool deleted ok. -+ * other Pool not deleted due to indicated error. -+ * -+ */ -+int bcm_mpm_delete_prealloc_pool(bcm_mpm_mgr_h mgr, bcm_mp_pool_h *poolp); -+ -+/* -+ * bcm_mpm_create_heap_pool() - Create a new pool for fixed size objects. The memory -+ * pool allocator uses the heap (malloc/free) for memory. -+ * In this case, the pool allocator is just providing -+ * statistics and instrumentation on top of the heap, -+ * without modifying the heap allocation implementation. -+ * -+ * Parameters: -+ * mgr: INPUT The handle to the pool manager -+ * obj_sz: INPUT Size of objects that will be allocated by the new pool -+ * poolname INPUT For instrumentation, the name of the pool -+ * newp: OUTPUT The handle for the new pool, if creation is successful -+ * -+ * Returns: -+ * BCME_OK Pool created ok. -+ * other Pool not created due to indicated error. newpoolp set to NULL. -+ * -+ * -+ */ -+int bcm_mpm_create_heap_pool(bcm_mpm_mgr_h mgr, unsigned int obj_sz, -+ char poolname[BCM_MP_NAMELEN], -+ bcm_mp_pool_h *newp); -+ -+ -+/* -+ * bcm_mpm_delete_heap_pool() - Delete a memory pool. This should only be called after -+ * all memory objects have been freed back to the pool. -+ * -+ * Parameters: -+ * mgr: INPUT The handle to the pools manager -+ * pool: INPUT The handle of the pool to delete -+ * -+ * Returns: -+ * BCME_OK Pool deleted ok. -+ * other Pool not deleted due to indicated error. -+ * -+ */ -+int bcm_mpm_delete_heap_pool(bcm_mpm_mgr_h mgr, bcm_mp_pool_h *poolp); -+ -+ -+/* -+ * bcm_mpm_stats() - Return stats for all pools -+ * -+ * Parameters: -+ * mgr: INPUT The handle to the pools manager -+ * stats: OUTPUT Array of pool statistics. -+ * nentries: MOD Max elements in 'stats' array on INPUT. Actual number -+ * of array elements copied to 'stats' on OUTPUT. -+ * -+ * Returns: -+ * BCME_OK Ok -+ * other Error getting stats. -+ * -+ */ -+int bcm_mpm_stats(bcm_mpm_mgr_h mgr, bcm_mp_stats_t *stats, int *nentries); -+ -+ -+/* -+ * bcm_mpm_dump() - Display statistics on all pools -+ * -+ * Parameters: -+ * mgr: INPUT The handle to the pools manager -+ * b: OUTPUT Output buffer. -+ * -+ * Returns: -+ * BCME_OK Ok -+ * other Error during dump. -+ * -+ */ -+int bcm_mpm_dump(bcm_mpm_mgr_h mgr, struct bcmstrbuf *b); -+ -+ -+/* -+ * bcm_mpm_get_obj_size() - The size of memory objects may need to be padded to -+ * compensate for alignment requirements of the objects. -+ * This function provides the padded object size. If clients -+ * pre-allocate a memory slab for a memory pool, the -+ * padded object size should be used by the client to allocate -+ * the memory slab (in order to provide sufficent space for -+ * the maximum number of objects). -+ * -+ * Parameters: -+ * mgr: INPUT The handle to the pools manager. -+ * obj_sz: INPUT Input object size. -+ * padded_obj_sz: OUTPUT Padded object size. -+ * -+ * Returns: -+ * BCME_OK Ok -+ * BCME_BADARG Bad arguments. -+ * -+ */ -+int bcm_mpm_get_obj_size(bcm_mpm_mgr_h mgr, unsigned int obj_sz, unsigned int *padded_obj_sz); -+ -+ -+/* -+*************************************************************************** -+* -+* API Routines on a specific pool. -+* -+*************************************************************************** -+*/ -+ -+ -+/* -+ * bcm_mp_alloc() - Allocate a memory pool object. -+ * -+ * Parameters: -+ * pool: INPUT The handle to the pool. -+ * -+ * Returns: -+ * A pointer to the new object. NULL on error. -+ * -+ */ -+void* bcm_mp_alloc(bcm_mp_pool_h pool); -+ -+/* -+ * bcm_mp_free() - Free a memory pool object. -+ * -+ * Parameters: -+ * pool: INPUT The handle to the pool. -+ * objp: INPUT A pointer to the object to free. -+ * -+ * Returns: -+ * BCME_OK Ok -+ * other Error during free. -+ * -+ */ -+int bcm_mp_free(bcm_mp_pool_h pool, void *objp); -+ -+/* -+ * bcm_mp_stats() - Return stats for this pool -+ * -+ * Parameters: -+ * pool: INPUT The handle to the pool -+ * stats: OUTPUT Pool statistics -+ * -+ * Returns: -+ * BCME_OK Ok -+ * other Error getting statistics. -+ * -+ */ -+int bcm_mp_stats(bcm_mp_pool_h pool, bcm_mp_stats_t *stats); -+ -+ -+/* -+ * bcm_mp_dump() - Dump a pool -+ * -+ * Parameters: -+ * pool: INPUT The handle to the pool -+ * b OUTPUT Output buffer -+ * -+ * Returns: -+ * BCME_OK Ok -+ * other Error during dump. -+ * -+ */ -+int bcm_mp_dump(bcm_mp_pool_h pool, struct bcmstrbuf *b); -+ -+ -+#endif /* _BCM_MPOOL_PUB_H */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmcdc.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmcdc.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmcdc.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmcdc.h 2017-11-09 17:53:43.917296000 +0800 -@@ -0,0 +1,122 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * CDC network driver ioctl/indication encoding -+ * Broadcom 802.11abg Networking Device Driver -+ * -+ * Definitions subject to change without notice. -+ * -+ * $Id: bcmcdc.h 291086 2011-10-21 01:17:24Z $ -+ */ -+#ifndef _bcmcdc_h_ -+#define _bcmcdc_h_ -+#include -+ -+typedef struct cdc_ioctl { -+ uint32 cmd; /* ioctl command value */ -+ uint32 len; /* lower 16: output buflen; upper 16: input buflen (excludes header) */ -+ uint32 flags; /* flag defns given below */ -+ uint32 status; /* status code returned from the device */ -+} cdc_ioctl_t; -+ -+/* Max valid buffer size that can be sent to the dongle */ -+#define CDC_MAX_MSG_SIZE ETHER_MAX_LEN -+ -+/* len field is divided into input and output buffer lengths */ -+#define CDCL_IOC_OUTLEN_MASK 0x0000FFFF /* maximum or expected response length, */ -+ /* excluding IOCTL header */ -+#define CDCL_IOC_OUTLEN_SHIFT 0 -+#define CDCL_IOC_INLEN_MASK 0xFFFF0000 /* input buffer length, excluding IOCTL header */ -+#define CDCL_IOC_INLEN_SHIFT 16 -+ -+/* CDC flag definitions */ -+#define CDCF_IOC_ERROR 0x01 /* 0=success, 1=ioctl cmd failed */ -+#define CDCF_IOC_SET 0x02 /* 0=get, 1=set cmd */ -+#define CDCF_IOC_OVL_IDX_MASK 0x3c /* overlay region index mask */ -+#define CDCF_IOC_OVL_RSV 0x40 /* 1=reserve this overlay region */ -+#define CDCF_IOC_OVL 0x80 /* 1=this ioctl corresponds to an overlay */ -+#define CDCF_IOC_ACTION_MASK 0xfe /* SET/GET, OVL_IDX, OVL_RSV, OVL mask */ -+#define CDCF_IOC_ACTION_SHIFT 1 /* SET/GET, OVL_IDX, OVL_RSV, OVL shift */ -+#define CDCF_IOC_IF_MASK 0xF000 /* I/F index */ -+#define CDCF_IOC_IF_SHIFT 12 -+#define CDCF_IOC_ID_MASK 0xFFFF0000 /* used to uniquely id an ioctl req/resp pairing */ -+#define CDCF_IOC_ID_SHIFT 16 /* # of bits of shift for ID Mask */ -+ -+#define CDC_IOC_IF_IDX(flags) (((flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT) -+#define CDC_IOC_ID(flags) (((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT) -+ -+#define CDC_GET_IF_IDX(hdr) \ -+ ((int)((((hdr)->flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT)) -+#define CDC_SET_IF_IDX(hdr, idx) \ -+ ((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | ((idx) << CDCF_IOC_IF_SHIFT))) -+ -+/* -+ * BDC header -+ * -+ * The BDC header is used on data packets to convey priority across USB. -+ */ -+ -+#define BDC_HEADER_LEN 4 -+ -+#define BDC_PROTO_VER_1 1 /* Old Protocol version */ -+#define BDC_PROTO_VER 2 /* Protocol version */ -+ -+#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */ -+#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */ -+ -+#define BDC_FLAG__UNUSED 0x03 /* Unassigned */ -+#define BDC_FLAG_SUM_GOOD 0x04 /* Dongle has verified good RX checksums */ -+#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */ -+ -+#define BDC_PRIORITY_MASK 0x7 -+ -+#define BDC_FLAG2_FC_FLAG 0x10 /* flag to indicate if pkt contains */ -+ /* FLOW CONTROL info only */ -+#define BDC_PRIORITY_FC_SHIFT 4 /* flow control info shift */ -+ -+#define BDC_FLAG2_IF_MASK 0x0f /* APSTA: interface on which the packet was received */ -+#define BDC_FLAG2_IF_SHIFT 0 -+#define BDC_FLAG2_PAD_MASK 0xf0 -+#define BDC_FLAG_PAD_MASK 0x03 -+#define BDC_FLAG2_PAD_SHIFT 2 -+#define BDC_FLAG_PAD_SHIFT 0 -+#define BDC_FLAG2_PAD_IDX 0x3c -+#define BDC_FLAG_PAD_IDX 0x03 -+#define BDC_GET_PAD_LEN(hdr) \ -+ ((int)(((((hdr)->flags2) & BDC_FLAG2_PAD_MASK) >> BDC_FLAG2_PAD_SHIFT) | \ -+ ((((hdr)->flags) & BDC_FLAG_PAD_MASK) >> BDC_FLAG_PAD_SHIFT))) -+#define BDC_SET_PAD_LEN(hdr, idx) \ -+ ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_PAD_MASK) | \ -+ (((idx) & BDC_FLAG2_PAD_IDX) << BDC_FLAG2_PAD_SHIFT))); \ -+ ((hdr)->flags = (((hdr)->flags & ~BDC_FLAG_PAD_MASK) | \ -+ (((idx) & BDC_FLAG_PAD_IDX) << BDC_FLAG_PAD_SHIFT))) -+ -+#define BDC_GET_IF_IDX(hdr) \ -+ ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) -+#define BDC_SET_IF_IDX(hdr, idx) \ -+ ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | ((idx) << BDC_FLAG2_IF_SHIFT))) -+ -+struct bdc_header { -+ uint8 flags; /* Flags */ -+ uint8 priority; /* 802.1d Priority 0:2 bits, 4:7 USB flow control info */ -+ uint8 flags2; -+ uint8 dataOffset; /* Offset from end of BDC header to packet data, in -+ * 4-byte words. Leaves room for optional headers. -+ */ -+}; -+ -+#define BDC_PROTO_VER_1 1 /* Old Protocol version */ -+ -+#endif /* _bcmcdc_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmdefs.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmdefs.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmdefs.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmdefs.h 2017-11-09 17:53:43.918300000 +0800 -@@ -0,0 +1,332 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Misc system wide definitions -+ * -+ * $Id: bcmdefs.h 316696 2012-02-23 03:29:35Z $ -+ */ -+ -+#ifndef _bcmdefs_h_ -+#define _bcmdefs_h_ -+ -+/* -+ * One doesn't need to include this file explicitly, gets included automatically if -+ * typedefs.h is included. -+ */ -+ -+/* Use BCM_REFERENCE to suppress warnings about intentionally-unused function -+ * arguments or local variables. -+ */ -+#define BCM_REFERENCE(data) ((void)(data)) -+ -+/* Compile-time assert can be used in place of ASSERT if the expression evaluates -+ * to a constant at compile time. -+ */ -+#define STATIC_ASSERT(expr) { \ -+ /* Make sure the expression is constant. */ \ -+ typedef enum { _STATIC_ASSERT_NOT_CONSTANT = (expr) } _static_assert_e; \ -+ /* Make sure the expression is true. */ \ -+ typedef char STATIC_ASSERT_FAIL[(expr) ? 1 : -1]; \ -+} -+ -+/* Reclaiming text and data : -+ * The following macros specify special linker sections that can be reclaimed -+ * after a system is considered 'up'. -+ * BCMATTACHFN is also used for detach functions (it's not worth having a BCMDETACHFN, -+ * as in most cases, the attach function calls the detach function to clean up on error). -+ */ -+#ifdef DONGLEBUILD -+ -+extern bool bcmreclaimed; -+extern bool attach_part_reclaimed; -+ -+#define BCMATTACHDATA(_data) __attribute__ ((__section__ (".dataini2." #_data))) _data -+#define BCMATTACHFN(_fn) __attribute__ ((__section__ (".textini2." #_fn), noinline)) _fn -+ -+#ifndef PREATTACH_NORECLAIM -+#define BCMPREATTACHDATA(_data) __attribute__ ((__section__ (".dataini3." #_data))) _data -+#define BCMPREATTACHFN(_fn) __attribute__ ((__section__ (".textini3." #_fn), noinline)) _fn -+#else -+#define BCMPREATTACHDATA(_data) __attribute__ ((__section__ (".dataini2." #_data))) _data -+#define BCMPREATTACHFN(_fn) __attribute__ ((__section__ (".textini2." #_fn), noinline)) _fn -+#endif -+ -+#if defined(BCMRECLAIM) -+#define BCMINITDATA(_data) __attribute__ ((__section__ (".dataini1." #_data))) _data -+#define BCMINITFN(_fn) __attribute__ ((__section__ (".textini1." #_fn), noinline)) _fn -+#define CONST -+#else -+#define BCMINITDATA(_data) _data -+#define BCMINITFN(_fn) _fn -+#define CONST const -+#endif -+ -+/* Non-manufacture or internal attach function/dat */ -+#if !defined(WLTEST) -+#define BCMNMIATTACHFN(_fn) BCMATTACHFN(_fn) -+#define BCMNMIATTACHDATA(_data) BCMATTACHDATA(_data) -+#else -+#define BCMNMIATTACHFN(_fn) _fn -+#define BCMNMIATTACHDATA(_data) _data -+#endif -+ -+#define BCMUNINITFN(_fn) _fn -+ -+#define BCMFASTPATH -+#else /* DONGLEBUILD */ -+ -+#define bcmreclaimed 0 -+#define BCMATTACHDATA(_data) _data -+#define BCMATTACHFN(_fn) _fn -+#define BCMPREATTACHDATA(_data) _data -+#define BCMPREATTACHFN(_fn) _fn -+#define BCMINITDATA(_data) _data -+#define BCMINITFN(_fn) _fn -+#define BCMUNINITFN(_fn) _fn -+#define BCMNMIATTACHFN(_fn) _fn -+#define BCMNMIATTACHDATA(_data) _data -+#define CONST const -+#if defined(__ARM_ARCH_7A__) -+#define BCM47XX_CA9 -+#else -+#undef BCM47XX_CA9 -+#endif -+#ifndef BCMFASTPATH -+#if defined(mips) || defined(BCM47XX_CA9) -+#define BCMFASTPATH __attribute__ ((__section__ (".text.fastpath"))) -+#define BCMFASTPATH_HOST __attribute__ ((__section__ (".text.fastpath_host"))) -+#else -+#define BCMFASTPATH -+#define BCMFASTPATH_HOST -+#endif -+#endif /* BCMFASTPATH */ -+ -+#endif /* DONGLEBUILD */ -+ -+#if defined(BCMROMBUILD) -+typedef struct { -+ uint16 esiz; -+ uint16 cnt; -+ void *addr; -+} bcmromdat_patch_t; -+#endif -+ -+/* Put some library data/code into ROM to reduce RAM requirements */ -+#if defined(BCMROMBUILD) && !defined(BCMROMSYMGEN_BUILD) && !defined(BCMJMPTBL_TCAM) -+#include -+#define STATIC static -+#else /* !BCMROMBUILD */ -+#define BCMROMDATA(_data) _data -+#define BCMROMDAT_NAME(_data) _data -+#define BCMROMFN(_fn) _fn -+#define BCMROMFN_NAME(_fn) _fn -+#define STATIC static -+#define BCMROMDAT_ARYSIZ(data) ARRAYSIZE(data) -+#define BCMROMDAT_SIZEOF(data) sizeof(data) -+#define BCMROMDAT_APATCH(data) -+#define BCMROMDAT_SPATCH(data) -+#endif /* !BCMROMBUILD */ -+ -+/* Bus types */ -+#define SI_BUS 0 /* SOC Interconnect */ -+#define PCI_BUS 1 /* PCI target */ -+#define PCMCIA_BUS 2 /* PCMCIA target */ -+#define SDIO_BUS 3 /* SDIO target */ -+#define JTAG_BUS 4 /* JTAG */ -+#define USB_BUS 5 /* USB (does not support R/W REG) */ -+#define SPI_BUS 6 /* gSPI target */ -+#define RPC_BUS 7 /* RPC target */ -+ -+/* Allows size optimization for single-bus image */ -+#ifdef BCMBUSTYPE -+#define BUSTYPE(bus) (BCMBUSTYPE) -+#else -+#define BUSTYPE(bus) (bus) -+#endif -+ -+/* Allows size optimization for single-backplane image */ -+#ifdef BCMCHIPTYPE -+#define CHIPTYPE(bus) (BCMCHIPTYPE) -+#else -+#define CHIPTYPE(bus) (bus) -+#endif -+ -+ -+/* Allows size optimization for SPROM support */ -+#if defined(BCMSPROMBUS) -+#define SPROMBUS (BCMSPROMBUS) -+#elif defined(SI_PCMCIA_SROM) -+#define SPROMBUS (PCMCIA_BUS) -+#else -+#define SPROMBUS (PCI_BUS) -+#endif -+ -+/* Allows size optimization for single-chip image */ -+#ifdef BCMCHIPID -+#define CHIPID(chip) (BCMCHIPID) -+#else -+#define CHIPID(chip) (chip) -+#endif -+ -+#ifdef BCMCHIPREV -+#define CHIPREV(rev) (BCMCHIPREV) -+#else -+#define CHIPREV(rev) (rev) -+#endif -+ -+/* Defines for DMA Address Width - Shared between OSL and HNDDMA */ -+#define DMADDR_MASK_32 0x0 /* Address mask for 32-bits */ -+#define DMADDR_MASK_30 0xc0000000 /* Address mask for 30-bits */ -+#define DMADDR_MASK_0 0xffffffff /* Address mask for 0-bits (hi-part) */ -+ -+#define DMADDRWIDTH_30 30 /* 30-bit addressing capability */ -+#define DMADDRWIDTH_32 32 /* 32-bit addressing capability */ -+#define DMADDRWIDTH_63 63 /* 64-bit addressing capability */ -+#define DMADDRWIDTH_64 64 /* 64-bit addressing capability */ -+ -+#ifdef BCMDMA64OSL -+typedef struct { -+ uint32 loaddr; -+ uint32 hiaddr; -+} dma64addr_t; -+ -+typedef dma64addr_t dmaaddr_t; -+#define PHYSADDRHI(_pa) ((_pa).hiaddr) -+#define PHYSADDRHISET(_pa, _val) \ -+ do { \ -+ (_pa).hiaddr = (_val); \ -+ } while (0) -+#define PHYSADDRLO(_pa) ((_pa).loaddr) -+#define PHYSADDRLOSET(_pa, _val) \ -+ do { \ -+ (_pa).loaddr = (_val); \ -+ } while (0) -+ -+#else -+typedef unsigned long dmaaddr_t; -+#define PHYSADDRHI(_pa) (0) -+#define PHYSADDRHISET(_pa, _val) -+#define PHYSADDRLO(_pa) ((_pa)) -+#define PHYSADDRLOSET(_pa, _val) \ -+ do { \ -+ (_pa) = (_val); \ -+ } while (0) -+#endif /* BCMDMA64OSL */ -+ -+/* One physical DMA segment */ -+typedef struct { -+ dmaaddr_t addr; -+ uint32 length; -+} hnddma_seg_t; -+ -+#if defined(MACOSX) -+/* In MacOS, the OS API may return large number of segments. Setting this number lower -+ * will result in failure of dma map -+ */ -+#define MAX_DMA_SEGS 8 -+#elif defined(__NetBSD__) -+/* In NetBSD we also want more segments because the lower level mbuf mapping api might -+ * allocate a large number of segments -+ */ -+#define MAX_DMA_SEGS 16 -+#else -+#define MAX_DMA_SEGS 4 -+#endif -+ -+ -+typedef struct { -+ void *oshdmah; /* Opaque handle for OSL to store its information */ -+ uint origsize; /* Size of the virtual packet */ -+ uint nsegs; -+ hnddma_seg_t segs[MAX_DMA_SEGS]; -+} hnddma_seg_map_t; -+ -+ -+/* packet headroom necessary to accommodate the largest header in the system, (i.e TXOFF). -+ * By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL. -+ * There is a compile time check in wlc.c which ensure that this value is at least as big -+ * as TXOFF. This value is used in dma_rxfill (hnddma.c). -+ */ -+ -+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RCP_TXNOCOPY) -+/* add 40 bytes to allow for extra RPC header and info */ -+#define BCMEXTRAHDROOM 260 -+#else /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY */ -+#define BCMEXTRAHDROOM 204 -+#endif /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY */ -+ -+/* Packet alignment for most efficient SDIO (can change based on platform) */ -+#ifndef SDALIGN -+#define SDALIGN 32 -+#endif -+ -+/* Headroom required for dongle-to-host communication. Packets allocated -+ * locally in the dongle (e.g. for CDC ioctls or RNDIS messages) should -+ * leave this much room in front for low-level message headers which may -+ * be needed to get across the dongle bus to the host. (These messages -+ * don't go over the network, so room for the full WL header above would -+ * be a waste.). -+*/ -+#define BCMDONGLEHDRSZ 12 -+#define BCMDONGLEPADSZ 16 -+ -+#define BCMDONGLEOVERHEAD (BCMDONGLEHDRSZ + BCMDONGLEPADSZ) -+ -+#ifdef BCMDBG -+ -+#ifndef BCMDBG_ERR -+#define BCMDBG_ERR -+#endif /* BCMDBG_ERR */ -+ -+#define BCMDBG_ASSERT -+ -+#endif /* BCMDBG */ -+ -+ -+/* Macros for doing definition and get/set of bitfields -+ * Usage example, e.g. a three-bit field (bits 4-6): -+ * #define _M BITFIELD_MASK(3) -+ * #define _S 4 -+ * ... -+ * regval = R_REG(osh, ®s->regfoo); -+ * field = GFIELD(regval, ); -+ * regval = SFIELD(regval, , 1); -+ * W_REG(osh, ®s->regfoo, regval); -+ */ -+#define BITFIELD_MASK(width) \ -+ (((unsigned)1 << (width)) - 1) -+#define GFIELD(val, field) \ -+ (((val) >> field ## _S) & field ## _M) -+#define SFIELD(val, field, bits) \ -+ (((val) & (~(field ## _M << field ## _S))) | \ -+ ((unsigned)(bits) << field ## _S)) -+ -+/* define BCMSMALL to remove misc features for memory-constrained environments */ -+#ifdef BCMSMALL -+#undef BCMSPACE -+#define bcmspace FALSE /* if (bcmspace) code is discarded */ -+#else -+#define BCMSPACE -+#define bcmspace TRUE /* if (bcmspace) code is retained */ -+#endif -+ -+/* Max. nvram variable table size */ -+#define MAXSZ_NVRAM_VARS 4096 -+ -+#ifdef EFI -+#define __attribute__(x) /* CSTYLED */ -+#endif -+ -+#endif /* _bcmdefs_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmdevs.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmdevs.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmdevs.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmdevs.h 2017-11-09 17:53:43.920291000 +0800 -@@ -0,0 +1,870 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom device-specific manifest constants. -+ * -+ * $Id: bcmdevs.h 328955 2012-04-23 09:06:12Z $ -+ */ -+ -+#ifndef _BCMDEVS_H -+#define _BCMDEVS_H -+ -+/* PCI vendor IDs */ -+#define VENDOR_EPIGRAM 0xfeda -+#define VENDOR_BROADCOM 0x14e4 -+#define VENDOR_3COM 0x10b7 -+#define VENDOR_NETGEAR 0x1385 -+#define VENDOR_DIAMOND 0x1092 -+#define VENDOR_INTEL 0x8086 -+#define VENDOR_DELL 0x1028 -+#define VENDOR_HP 0x103c -+#define VENDOR_HP_COMPAQ 0x0e11 -+#define VENDOR_APPLE 0x106b -+#define VENDOR_SI_IMAGE 0x1095 /* Silicon Image, used by Arasan SDIO Host */ -+#define VENDOR_BUFFALO 0x1154 /* Buffalo vendor id */ -+#define VENDOR_TI 0x104c /* Texas Instruments */ -+#define VENDOR_RICOH 0x1180 /* Ricoh */ -+#define VENDOR_JMICRON 0x197b -+ -+ -+/* PCMCIA vendor IDs */ -+#define VENDOR_BROADCOM_PCMCIA 0x02d0 -+ -+/* SDIO vendor IDs */ -+#define VENDOR_BROADCOM_SDIO 0x00BF -+ -+/* DONGLE VID/PIDs */ -+#define BCM_DNGL_VID 0x0a5c -+#define BCM_DNGL_BL_PID_4328 0xbd12 -+#define BCM_DNGL_BL_PID_4322 0xbd13 -+#define BCM_DNGL_BL_PID_4319 0xbd16 -+#define BCM_DNGL_BL_PID_43236 0xbd17 -+#define BCM_DNGL_BL_PID_4332 0xbd18 -+#define BCM_DNGL_BL_PID_4330 0xbd19 -+#define BCM_DNGL_BL_PID_4334 0xbd1a -+#define BCM_DNGL_BL_PID_43239 0xbd1b -+#define BCM_DNGL_BL_PID_4324 0xbd1c -+#define BCM_DNGL_BL_PID_4360 0xbd1d -+#define BCM_DNGL_BL_PID_4335 0xbd20 -+ -+#define BCM_DNGL_BDC_PID 0x0bdc -+#define BCM_DNGL_JTAG_PID 0x4a44 -+ -+/* HW USB BLOCK [CPULESS USB] PIDs */ -+#define BCM_HWUSB_PID_43239 43239 -+ -+/* PCI Device IDs */ -+#define BCM4210_DEVICE_ID 0x1072 /* never used */ -+#define BCM4230_DEVICE_ID 0x1086 /* never used */ -+#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */ -+#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */ -+#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */ -+#define BCM4211_DEVICE_ID 0x4211 -+#define BCM4231_DEVICE_ID 0x4231 -+#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */ -+#define BCM4311_D11G_ID 0x4311 /* 4311 802.11b/g id */ -+#define BCM4311_D11DUAL_ID 0x4312 /* 4311 802.11a/b/g id */ -+#define BCM4311_D11A_ID 0x4313 /* 4311 802.11a id */ -+#define BCM4328_D11DUAL_ID 0x4314 /* 4328/4312 802.11a/g id */ -+#define BCM4328_D11G_ID 0x4315 /* 4328/4312 802.11g id */ -+#define BCM4328_D11A_ID 0x4316 /* 4328/4312 802.11a id */ -+#define BCM4318_D11G_ID 0x4318 /* 4318 802.11b/g id */ -+#define BCM4318_D11DUAL_ID 0x4319 /* 4318 802.11a/b/g id */ -+#define BCM4318_D11A_ID 0x431a /* 4318 802.11a id */ -+#define BCM4325_D11DUAL_ID 0x431b /* 4325 802.11a/g id */ -+#define BCM4325_D11G_ID 0x431c /* 4325 802.11g id */ -+#define BCM4325_D11A_ID 0x431d /* 4325 802.11a id */ -+#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */ -+#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */ -+#define BCM4306_UART_ID 0x4322 /* 4306 uart */ -+#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */ -+#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */ -+#define BCM4306_D11G_ID2 0x4325 /* BCM4306_D11G_ID; INF w/loose binding war */ -+#define BCM4321_D11N_ID 0x4328 /* 4321 802.11n dualband id */ -+#define BCM4321_D11N2G_ID 0x4329 /* 4321 802.11n 2.4Ghz band id */ -+#define BCM4321_D11N5G_ID 0x432a /* 4321 802.11n 5Ghz band id */ -+#define BCM4322_D11N_ID 0x432b /* 4322 802.11n dualband device */ -+#define BCM4322_D11N2G_ID 0x432c /* 4322 802.11n 2.4GHz device */ -+#define BCM4322_D11N5G_ID 0x432d /* 4322 802.11n 5GHz device */ -+#define BCM4329_D11N_ID 0x432e /* 4329 802.11n dualband device */ -+#define BCM4329_D11N2G_ID 0x432f /* 4329 802.11n 2.4G device */ -+#define BCM4329_D11N5G_ID 0x4330 /* 4329 802.11n 5G device */ -+#define BCM4315_D11DUAL_ID 0x4334 /* 4315 802.11a/g id */ -+#define BCM4315_D11G_ID 0x4335 /* 4315 802.11g id */ -+#define BCM4315_D11A_ID 0x4336 /* 4315 802.11a id */ -+#define BCM4319_D11N_ID 0x4337 /* 4319 802.11n dualband device */ -+#define BCM4319_D11N2G_ID 0x4338 /* 4319 802.11n 2.4G device */ -+#define BCM4319_D11N5G_ID 0x4339 /* 4319 802.11n 5G device */ -+#define BCM43231_D11N2G_ID 0x4340 /* 43231 802.11n 2.4GHz device */ -+#define BCM43221_D11N2G_ID 0x4341 /* 43221 802.11n 2.4GHz device */ -+#define BCM43222_D11N_ID 0x4350 /* 43222 802.11n dualband device */ -+#define BCM43222_D11N2G_ID 0x4351 /* 43222 802.11n 2.4GHz device */ -+#define BCM43222_D11N5G_ID 0x4352 /* 43222 802.11n 5GHz device */ -+#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */ -+#define BCM43224_D11N_ID_VEN1 0x0576 /* Vendor specific 43224 802.11n db device */ -+#define BCM43226_D11N_ID 0x4354 /* 43226 802.11n dualband device */ -+#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */ -+#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */ -+#define BCM43236_D11N5G_ID 0x4348 /* 43236 802.11n 5GHz device */ -+#define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */ -+#define BCM43421_D11N_ID 0xA99D /* 43421 802.11n dualband device */ -+#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */ -+#define BCM4330_D11N_ID 0x4360 /* 4330 802.11n dualband device */ -+#define BCM4330_D11N2G_ID 0x4361 /* 4330 802.11n 2.4G device */ -+#define BCM4330_D11N5G_ID 0x4362 /* 4330 802.11n 5G device */ -+#define BCM4336_D11N_ID 0x4343 /* 4336 802.11n 2.4GHz device */ -+#define BCM6362_D11N_ID 0x435f /* 6362 802.11n dualband device */ -+#define BCM4331_D11N_ID 0x4331 /* 4331 802.11n dualband id */ -+#define BCM4331_D11N2G_ID 0x4332 /* 4331 802.11n 2.4Ghz band id */ -+#define BCM4331_D11N5G_ID 0x4333 /* 4331 802.11n 5Ghz band id */ -+#define BCM43237_D11N_ID 0x4355 /* 43237 802.11n dualband device */ -+#define BCM43237_D11N5G_ID 0x4356 /* 43237 802.11n 5GHz device */ -+#define BCM43227_D11N2G_ID 0x4358 /* 43228 802.11n 2.4GHz device */ -+#define BCM43228_D11N_ID 0x4359 /* 43228 802.11n DualBand device */ -+#define BCM43228_D11N5G_ID 0x435a /* 43228 802.11n 5GHz device */ -+#define BCM43362_D11N_ID 0x4363 /* 43362 802.11n 2.4GHz device */ -+#define BCM43239_D11N_ID 0x4370 /* 43239 802.11n dualband device */ -+#define BCM4324_D11N_ID 0x4374 /* 4324 802.11n dualband device */ -+#define BCM43217_D11N2G_ID 0x43a9 /* 43217 802.11n 2.4GHz device */ -+#define BCM43131_D11N2G_ID 0x43aa /* 43131 802.11n 2.4GHz device */ -+#define BCM4314_D11N2G_ID 0x4364 /* 4314 802.11n 2.4G device */ -+#define BCM43142_D11N2G_ID 0x4365 /* 43142 802.11n 2.4G device */ -+#define BCM4334_D11N_ID 0x4380 /* 4334 802.11n dualband device */ -+#define BCM4334_D11N2G_ID 0x4381 /* 4334 802.11n 2.4G device */ -+#define BCM4334_D11N5G_ID 0x4382 /* 4334 802.11n 5G device */ -+#define BCM4360_D11AC_ID 0x43a0 -+#define BCM4360_D11AC2G_ID 0x43a1 -+#define BCM4360_D11AC5G_ID 0x43a2 -+#define BCM4335_D11AC_ID 0x43ae -+#define BCM4335_D11AC2G_ID 0x43af -+#define BCM4335_D11AC5G_ID 0x43b0 -+#define BCM4352_D11AC_ID 0x43b1 /* 4352 802.11ac dualband device */ -+#define BCM4352_D11AC2G_ID 0x43b2 /* 4352 802.11ac 2.4G device */ -+#define BCM4352_D11AC5G_ID 0x43b3 /* 4352 802.11ac 5G device */ -+ -+/* PCI Subsystem ID */ -+#define BCM943228HMB_SSID_VEN1 0x0607 -+#define BCM94313HMGBL_SSID_VEN1 0x0608 -+#define BCM94313HMG_SSID_VEN1 0x0609 -+ -+ -+#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */ -+#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */ -+#define FPGA_JTAGM_ID 0x43f0 /* FPGA jtagm device id */ -+#define BCM_JTAGM_ID 0x43f1 /* BCM jtagm device id */ -+#define SDIOH_FPGA_ID 0x43f2 /* sdio host fpga */ -+#define BCM_SDIOH_ID 0x43f3 /* BCM sdio host id */ -+#define SDIOD_FPGA_ID 0x43f4 /* sdio device fpga */ -+#define SPIH_FPGA_ID 0x43f5 /* PCI SPI Host Controller FPGA */ -+#define BCM_SPIH_ID 0x43f6 /* Synopsis SPI Host Controller */ -+#define MIMO_FPGA_ID 0x43f8 /* FPGA mimo minimacphy device id */ -+#define BCM_JTAGM2_ID 0x43f9 /* BCM alternate jtagm device id */ -+#define SDHCI_FPGA_ID 0x43fa /* Standard SDIO Host Controller FPGA */ -+#define BCM4402_ENET_ID 0x4402 /* 4402 enet */ -+#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */ -+#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */ -+#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */ -+#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */ -+#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */ -+#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */ -+#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */ -+#define BCM47XX_AUDIO_ID 0x4711 /* 47xx audio codec */ -+#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */ -+#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */ -+#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */ -+#define BCM47XX_GMAC_ID 0x4715 /* 47xx Unimac based GbE */ -+#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */ -+#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */ -+#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */ -+#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */ -+#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */ -+#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */ -+#define BCM47XX_ATA100_ID 0x471d /* 47xx parallel ATA */ -+#define BCM47XX_SATAXOR_ID 0x471e /* 47xx serial ATA & XOR DMA */ -+#define BCM47XX_GIGETH_ID 0x471f /* 47xx GbE (5700) */ -+#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */ -+#define BCM4716_DEVICE_ID 0x4722 /* 4716 base devid */ -+#define BCM47XX_SMBUS_EMU_ID 0x47fe /* 47xx emulated SMBus device */ -+#define BCM47XX_XOR_EMU_ID 0x47ff /* 47xx emulated XOR engine */ -+#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */ -+#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */ -+#define JINVANI_SDIOH_ID 0x4743 /* Jinvani SDIO Gold Host */ -+#define BCM27XX_SDIOH_ID 0x2702 /* BCM27xx Standard SDIO Host */ -+#define PCIXX21_FLASHMEDIA_ID 0x803b /* TI PCI xx21 Standard Host Controller */ -+#define PCIXX21_SDIOH_ID 0x803c /* TI PCI xx21 Standard Host Controller */ -+#define R5C822_SDIOH_ID 0x0822 /* Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host */ -+#define JMICRON_SDIOH_ID 0x2381 /* JMicron Standard SDIO Host Controller */ -+ -+/* Chip IDs */ -+#define BCM4306_CHIP_ID 0x4306 /* 4306 chipcommon chipid */ -+#define BCM4311_CHIP_ID 0x4311 /* 4311 PCIe 802.11a/b/g */ -+#define BCM43111_CHIP_ID 43111 /* 43111 chipcommon chipid (OTP chipid) */ -+#define BCM43112_CHIP_ID 43112 /* 43112 chipcommon chipid (OTP chipid) */ -+#define BCM4312_CHIP_ID 0x4312 /* 4312 chipcommon chipid */ -+#define BCM4313_CHIP_ID 0x4313 /* 4313 chip id */ -+#define BCM43131_CHIP_ID 43131 /* 43131 chip id (OTP chipid) */ -+#define BCM4315_CHIP_ID 0x4315 /* 4315 chip id */ -+#define BCM4318_CHIP_ID 0x4318 /* 4318 chipcommon chipid */ -+#define BCM4319_CHIP_ID 0x4319 /* 4319 chip id */ -+#define BCM4320_CHIP_ID 0x4320 /* 4320 chipcommon chipid */ -+#define BCM4321_CHIP_ID 0x4321 /* 4321 chipcommon chipid */ -+#define BCM43217_CHIP_ID 43217 /* 43217 chip id (OTP chipid) */ -+#define BCM4322_CHIP_ID 0x4322 /* 4322 chipcommon chipid */ -+#define BCM43221_CHIP_ID 43221 /* 43221 chipcommon chipid (OTP chipid) */ -+#define BCM43222_CHIP_ID 43222 /* 43222 chipcommon chipid */ -+#define BCM43224_CHIP_ID 43224 /* 43224 chipcommon chipid */ -+#define BCM43225_CHIP_ID 43225 /* 43225 chipcommon chipid */ -+#define BCM43227_CHIP_ID 43227 /* 43227 chipcommon chipid */ -+#define BCM43228_CHIP_ID 43228 /* 43228 chipcommon chipid */ -+#define BCM43226_CHIP_ID 43226 /* 43226 chipcommon chipid */ -+#define BCM43231_CHIP_ID 43231 /* 43231 chipcommon chipid (OTP chipid) */ -+#define BCM43234_CHIP_ID 43234 /* 43234 chipcommon chipid */ -+#define BCM43235_CHIP_ID 43235 /* 43235 chipcommon chipid */ -+#define BCM43236_CHIP_ID 43236 /* 43236 chipcommon chipid */ -+#define BCM43237_CHIP_ID 43237 /* 43237 chipcommon chipid */ -+#define BCM43238_CHIP_ID 43238 /* 43238 chipcommon chipid */ -+#define BCM43239_CHIP_ID 43239 /* 43239 chipcommon chipid */ -+#define BCM43420_CHIP_ID 43420 /* 43222 chipcommon chipid (OTP, RBBU) */ -+#define BCM43421_CHIP_ID 43421 /* 43224 chipcommon chipid (OTP, RBBU) */ -+#define BCM43428_CHIP_ID 43428 /* 43228 chipcommon chipid (OTP, RBBU) */ -+#define BCM43431_CHIP_ID 43431 /* 4331 chipcommon chipid (OTP, RBBU) */ -+#define BCM43460_CHIP_ID 43460 /* 4360 chipcommon chipid (OTP, RBBU) */ -+#define BCM4325_CHIP_ID 0x4325 /* 4325 chip id */ -+#define BCM4328_CHIP_ID 0x4328 /* 4328 chip id */ -+#define BCM4329_CHIP_ID 0x4329 /* 4329 chipcommon chipid */ -+#define BCM4331_CHIP_ID 0x4331 /* 4331 chipcommon chipid */ -+#define BCM4336_CHIP_ID 0x4336 /* 4336 chipcommon chipid */ -+#define BCM43362_CHIP_ID 43362 /* 43362 chipcommon chipid */ -+#define BCM4330_CHIP_ID 0x4330 /* 4330 chipcommon chipid */ -+#define BCM6362_CHIP_ID 0x6362 /* 6362 chipcommon chipid */ -+#define BCM4314_CHIP_ID 0x4314 /* 4314 chipcommon chipid */ -+#define BCM43142_CHIP_ID 43142 /* 43142 chipcommon chipid */ -+#define BCM4324_CHIP_ID 0x4324 /* 4324 chipcommon chipid */ -+#define BCM43242_CHIP_ID 43242 /* 43242 chipcommon chipid */ -+#define BCM4334_CHIP_ID 0x4334 /* 4334 chipcommon chipid */ -+#define BCM4335_CHIP_ID 0x4335 -+#define BCM4360_CHIP_ID 0x4360 -+#define BCM43526_CHIP_ID 0xAA06 -+#define BCM4352_CHIP_ID 0x4352 -+ -+#define BCM4342_CHIP_ID 4342 /* 4342 chipcommon chipid (OTP, RBBU) */ -+#define BCM4402_CHIP_ID 0x4402 /* 4402 chipid */ -+#define BCM4704_CHIP_ID 0x4704 /* 4704 chipcommon chipid */ -+#define BCM4706_CHIP_ID 0x5300 /* 4706 chipcommon chipid */ -+#define BCM4710_CHIP_ID 0x4710 /* 4710 chipid */ -+#define BCM4712_CHIP_ID 0x4712 /* 4712 chipcommon chipid */ -+#define BCM4716_CHIP_ID 0x4716 /* 4716 chipcommon chipid */ -+#define BCM47162_CHIP_ID 47162 /* 47162 chipcommon chipid */ -+#define BCM4748_CHIP_ID 0x4748 /* 4716 chipcommon chipid (OTP, RBBU) */ -+#define BCM4749_CHIP_ID 0x4749 /* 5357 chipcommon chipid (OTP, RBBU) */ -+#define BCM4785_CHIP_ID 0x4785 /* 4785 chipcommon chipid */ -+#define BCM5350_CHIP_ID 0x5350 /* 5350 chipcommon chipid */ -+#define BCM5352_CHIP_ID 0x5352 /* 5352 chipcommon chipid */ -+#define BCM5354_CHIP_ID 0x5354 /* 5354 chipcommon chipid */ -+#define BCM5365_CHIP_ID 0x5365 /* 5365 chipcommon chipid */ -+#define BCM5356_CHIP_ID 0x5356 /* 5356 chipcommon chipid */ -+#define BCM5357_CHIP_ID 0x5357 /* 5357 chipcommon chipid */ -+#define BCM53572_CHIP_ID 53572 /* 53572 chipcommon chipid */ -+#define BCM53010_CHIP_ID 53010 /* NS chipcommon chipid */ -+#define BCM56150_CHIP_ID 56150 /* HR2 chipcommon chipid */ -+#define BCM56340_CHIP_ID 56340 /* HX4 chipcommon chipid */ -+#define BCM53020_CHIP_ID 53020 /* NSP chipcommon chipid */ -+#define BCM56450_CHIP_ID 56450 /* KT2 chipcommon chipid */ -+#define BCM54016_CHIP_ID 54016 /* CYGNUS chipcommon chipid */ -+#define BCM53400_CHIP_ID 0x8416 /* GH chipcommon chipid */ -+#define BCM56260_CHIP_ID 0xb260 /* SB2 chipcommon chipid */ -+#define BCM56160_CHIP_ID 0xb160 /* HR3 chipcommon chipid */ -+#define BCM56170_CHIP_ID 0xb170 /* GH2 chipcommon chipid */ -+#define BCM53540_CHIP_ID 0x8540 /* WF2 chipcommon chipid */ -+ -+#if defined(CONFIG_MACH_HX4) -+#define BCMIPROC_CHIP_ID BCM56340_CHIP_ID -+#elif defined(CONFIG_MACH_HR2) -+#define BCMIPROC_CHIP_ID BCM56150_CHIP_ID -+#elif defined(CONFIG_MACH_KT2) -+#define BCMIPROC_CHIP_ID BCM56450_CHIP_ID -+#elif defined(CONFIG_MACH_GH) -+#define BCMIPROC_CHIP_ID BCM53400_CHIP_ID -+#elif defined(CONFIG_MACH_SB2) -+#define BCMIPROC_CHIP_ID BCM56260_CHIP_ID -+#elif defined(CONFIG_MACH_HR3) -+ -+#if defined(CONFIG_MACH_WH2) -+#define BCMIPROC_CHIP_ID BCM53540_CHIP_ID -+#else -+#define BCMIPROC_CHIP_ID BCM56160_CHIP_ID -+#endif -+ -+#elif defined(CONFIG_MACH_GH2) -+#define BCMIPROC_CHIP_ID BCM56170_CHIP_ID -+#endif -+ -+/* Package IDs */ -+#define BCM4303_PKG_ID 2 /* 4303 package id */ -+#define BCM4309_PKG_ID 1 /* 4309 package id */ -+#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */ -+#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */ -+#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */ -+#define BCM4328USBD11G_PKG_ID 2 /* 4328 802.11g USB package id */ -+#define BCM4328USBDUAL_PKG_ID 3 /* 4328 802.11a/g USB package id */ -+#define BCM4328SDIOD11G_PKG_ID 4 /* 4328 802.11g SDIO package id */ -+#define BCM4328SDIODUAL_PKG_ID 5 /* 4328 802.11a/g SDIO package id */ -+#define BCM4329_289PIN_PKG_ID 0 /* 4329 289-pin package id */ -+#define BCM4329_182PIN_PKG_ID 1 /* 4329N 182-pin package id */ -+#define BCM5354E_PKG_ID 1 /* 5354E package id */ -+#define BCM4716_PKG_ID 8 /* 4716 package id */ -+#define BCM4717_PKG_ID 9 /* 4717 package id */ -+#define BCM4718_PKG_ID 10 /* 4718 package id */ -+#define BCM5356_PKG_NONMODE 1 /* 5356 package without nmode suppport */ -+#define BCM5358U_PKG_ID 8 /* 5358U package id */ -+#define BCM5358_PKG_ID 9 /* 5358 package id */ -+#define BCM47186_PKG_ID 10 /* 47186 package id */ -+#define BCM5357_PKG_ID 11 /* 5357 package id */ -+#define BCM5356U_PKG_ID 12 /* 5356U package id */ -+#define BCM53572_PKG_ID 8 /* 53572 package id */ -+#define BCM5357C0_PKG_ID 8 /* 5357c0 package id (the same as 53572) */ -+#define BCM47188_PKG_ID 9 /* 47188 package id */ -+#define BCM5358C0_PKG_ID 0xa /* 5358c0 package id */ -+#define BCM5356C0_PKG_ID 0xb /* 5356c0 package id */ -+#define BCM4331TT_PKG_ID 8 /* 4331 12x12 package id */ -+#define BCM4331TN_PKG_ID 9 /* 4331 12x9 package id */ -+#define BCM4331TNA0_PKG_ID 0xb /* 4331 12x9 package id */ -+#define BCM4706L_PKG_ID 1 /* 4706L package id */ -+ -+#define HDLSIM5350_PKG_ID 1 /* HDL simulator package id for a 5350 */ -+#define HDLSIM_PKG_ID 14 /* HDL simulator package id */ -+#define HWSIM_PKG_ID 15 /* Hardware simulator package id */ -+#define BCM43224_FAB_CSM 0x8 /* the chip is manufactured by CSM */ -+#define BCM43224_FAB_SMIC 0xa /* the chip is manufactured by SMIC */ -+#define BCM4336_WLBGA_PKG_ID 0x8 -+#define BCM4330_WLBGA_PKG_ID 0x0 -+#define BCM4314PCIE_ARM_PKG_ID (8 | 0) /* 4314 QFN PCI package id, bit 3 tie high */ -+#define BCM4314SDIO_PKG_ID (8 | 1) /* 4314 QFN SDIO package id */ -+#define BCM4314PCIE_PKG_ID (8 | 2) /* 4314 QFN PCI (ARM-less) package id */ -+#define BCM4314SDIO_ARM_PKG_ID (8 | 3) /* 4314 QFN SDIO (ARM-less) package id */ -+#define BCM4314SDIO_FPBGA_PKG_ID (8 | 4) /* 4314 FpBGA SDIO package id */ -+#define BCM4314DEV_PKG_ID (8 | 6) /* 4314 Developement package id */ -+ -+#define BCM4707_PKG_ID 1 /* 4707 package id */ -+#define BCM4708_PKG_ID 2 /* 4708 package id */ -+#define BCM4709_PKG_ID 0 /* 4709 package id */ -+ -+#define PCIXX21_FLASHMEDIA0_ID 0x8033 /* TI PCI xx21 Standard Host Controller */ -+#define PCIXX21_SDIOH0_ID 0x8034 /* TI PCI xx21 Standard Host Controller */ -+ -+#define BCM4335_WLCSP_PKG_ID (0x0) /* WLCSP Module/Mobile SDIO/HSIC. */ -+#define BCM4335_FCBGA_PKG_ID (0x1) /* FCBGA PC/Embeded/Media PCIE/SDIO */ -+#define BCM4335_WLBGA_PKG_ID (0x2) /* WLBGA COB/Mobile SDIO/HSIC. */ -+#define BCM4335_FCBGAD_PKG_ID (0x3) /* FCBGA Debug Debug/Dev All if's. */ -+#define BCM4335_PKG_MASK (0x3) -+ -+/* boardflags */ -+#define BFL_BTC2WIRE 0x00000001 /* old 2wire Bluetooth coexistence, OBSOLETE */ -+#define BFL_BTCOEX 0x00000001 /* Board supports BTCOEX */ -+#define BFL_PACTRL 0x00000002 /* Board has gpio 9 controlling the PA */ -+#define BFL_AIRLINEMODE 0x00000004 /* Board implements gpio 13 radio disable indication, UNUSED */ -+#define BFL_ADCDIV 0x00000008 /* Board has the rssi ADC divider */ -+#define BFL_ENETROBO 0x00000010 /* Board has robo switch or core */ -+#define BFL_NOPLLDOWN 0x00000020 /* Not ok to power down the chip pll and oscillator */ -+#define BFL_CCKHIPWR 0x00000040 /* Can do high-power CCK transmission */ -+#define BFL_ENETADM 0x00000080 /* Board has ADMtek switch */ -+#define BFL_ENETVLAN 0x00000100 /* Board has VLAN capability */ -+#define BFL_UNUSED 0x00000200 -+#define BFL_NOPCI 0x00000400 /* Board leaves PCI floating */ -+#define BFL_FEM 0x00000800 /* Board supports the Front End Module */ -+#define BFL_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */ -+#define BFL_HGPA 0x00002000 /* Board has a high gain PA */ -+#define BFL_BTC2WIRE_ALTGPIO 0x00004000 /* Board's BTC 2wire is in the alternate gpios */ -+#define BFL_ALTIQ 0x00008000 /* Alternate I/Q settings */ -+#define BFL_NOPA 0x00010000 /* Board has no PA */ -+#define BFL_RSSIINV 0x00020000 /* Board's RSSI uses positive slope(not TSSI) */ -+#define BFL_PAREF 0x00040000 /* Board uses the PARef LDO */ -+#define BFL_3TSWITCH 0x00080000 /* Board uses a triple throw switch shared with BT */ -+#define BFL_PHASESHIFT 0x00100000 /* Board can support phase shifter */ -+#define BFL_BUCKBOOST 0x00200000 /* Power topology uses BUCKBOOST */ -+#define BFL_FEM_BT 0x00400000 /* Board has FEM and switch to share antenna w/ BT */ -+#define BFL_NOCBUCK 0x00800000 /* Power topology doesn't use CBUCK */ -+#define BFL_CCKFAVOREVM 0x01000000 /* Favor CCK EVM over spectral mask */ -+#define BFL_PALDO 0x02000000 /* Power topology uses PALDO */ -+#define BFL_LNLDO2_2P5 0x04000000 /* Select 2.5V as LNLDO2 output voltage */ -+#define BFL_FASTPWR 0x08000000 -+#define BFL_UCPWRCTL_MININDX 0x08000000 /* Enforce min power index to avoid FEM damage */ -+#define BFL_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */ -+#define BFL_TRSW_1by2 0x20000000 /* Board has 2 TRSW's in 1by2 designs */ -+#define BFL_LO_TRSW_R_5GHz 0x40000000 /* In 5G do not throw TRSW to T for clipLO gain */ -+#define BFL_ELNA_GAINDEF 0x80000000 /* Backoff InitGain based on elna_2g/5g field -+ * when this flag is set -+ */ -+#define BFL_EXTLNA_TX 0x20000000 /* Temp boardflag to indicate to */ -+ -+/* boardflags2 */ -+#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* Board has an external rxbb regulator */ -+#define BFL2_APLL_WAR 0x00000002 /* Flag to implement alternative A-band PLL settings */ -+#define BFL2_TXPWRCTRL_EN 0x00000004 /* Board permits enabling TX Power Control */ -+#define BFL2_2X4_DIV 0x00000008 /* Board supports the 2X4 diversity switch */ -+#define BFL2_5G_PWRGAIN 0x00000010 /* Board supports 5G band power gain */ -+#define BFL2_PCIEWAR_OVR 0x00000020 /* Board overrides ASPM and Clkreq settings */ -+#define BFL2_CAESERS_BRD 0x00000040 /* Board is Caesers brd (unused by sw) */ -+#define BFL2_BTC3WIRE 0x00000080 /* Board support legacy 3 wire or 4 wire */ -+#define BFL2_BTCLEGACY 0x00000080 /* Board support legacy 3/4 wire, to replace -+ * BFL2_BTC3WIRE -+ */ -+#define BFL2_SKWRKFEM_BRD 0x00000100 /* 4321mcm93 board uses Skyworks FEM */ -+#define BFL2_SPUR_WAR 0x00000200 /* Board has a WAR for clock-harmonic spurs */ -+#define BFL2_GPLL_WAR 0x00000400 /* Flag to narrow G-band PLL loop b/w */ -+#define BFL2_TRISTATE_LED 0x00000800 /* Tri-state the LED */ -+#define BFL2_SINGLEANT_CCK 0x00001000 /* Tx CCK pkts on Ant 0 only */ -+#define BFL2_2G_SPUR_WAR 0x00002000 /* WAR to reduce and avoid clock-harmonic spurs in 2G */ -+#define BFL2_BPHY_ALL_TXCORES 0x00004000 /* Transmit bphy frames using all tx cores */ -+#define BFL2_FCC_BANDEDGE_WAR 0x00008000 /* Activates WAR to improve FCC bandedge performance */ -+#define BFL2_GPLL_WAR2 0x00010000 /* Flag to widen G-band PLL loop b/w */ -+#define BFL2_IPALVLSHIFT_3P3 0x00020000 -+#define BFL2_INTERNDET_TXIQCAL 0x00040000 /* Use internal envelope detector for TX IQCAL */ -+#define BFL2_XTALBUFOUTEN 0x00080000 /* Keep the buffered Xtal output from radio on */ -+ /* Most drivers will turn it off without this flag */ -+ /* to save power. */ -+ -+#define BFL2_ANAPACTRL_2G 0x00100000 /* 2G ext PAs are controlled by analog PA ctrl lines */ -+#define BFL2_ANAPACTRL_5G 0x00200000 /* 5G ext PAs are controlled by analog PA ctrl lines */ -+#define BFL2_ELNACTRL_TRSW_2G 0x00400000 /* AZW4329: 2G gmode_elna_gain controls TR Switch */ -+#define BFL2_BT_SHARE_ANT0 0x00800000 /* share core0 antenna with BT */ -+#define BFL2_TEMPSENSE_HIGHER 0x01000000 /* The tempsense threshold can sustain higher value -+ * than programmed. The exact delta is decided by -+ * driver per chip/boardtype. This can be used -+ * when tempsense qualification happens after shipment -+ */ -+#define BFL2_BTC3WIREONLY 0x02000000 /* standard 3 wire btc only. 4 wire not supported */ -+#define BFL2_PWR_NOMINAL 0x04000000 /* 0: power reduction on, 1: no power reduction */ -+#define BFL2_EXTLNA_PWRSAVE 0x08000000 /* boardflag to enable ucode to apply power save */ -+ /* ucode control of eLNA during Tx */ -+#define BFL2_4313_RADIOREG 0x10000000 -+ /* board rework */ -+#define BFL2_SDR_EN 0x20000000 /* SDR enabled or disabled */ -+ -+/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ -+#define BOARD_GPIO_BTC3W_IN 0x850 /* bit 4 is RF_ACTIVE, bit 6 is STATUS, bit 11 is PRI */ -+#define BOARD_GPIO_BTC3W_OUT 0x020 /* bit 5 is TX_CONF */ -+#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistence Input */ -+#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistence Out */ -+#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistence Input */ -+#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistence Out */ -+#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */ -+#define BOARD_GPIO_12 0x1000 /* gpio 12 */ -+#define BOARD_GPIO_13 0x2000 /* gpio 13 */ -+#define BOARD_GPIO_BTC4_IN 0x0800 /* gpio 11, coex4, in */ -+#define BOARD_GPIO_BTC4_BT 0x2000 /* gpio 12, coex4, bt active */ -+#define BOARD_GPIO_BTC4_STAT 0x4000 /* gpio 14, coex4, status */ -+#define BOARD_GPIO_BTC4_WLAN 0x8000 /* gpio 15, coex4, wlan active */ -+#define BOARD_GPIO_1_WLAN_PWR 0x02 /* throttle WLAN power on X21 board */ -+#define BOARD_GPIO_3_WLAN_PWR 0x08 /* throttle WLAN power on X28 board */ -+#define BOARD_GPIO_4_WLAN_PWR 0x10 /* throttle WLAN power on X19 board */ -+ -+#define GPIO_BTC4W_OUT_4312 0x010 /* bit 4 is BT_IODISABLE */ -+#define GPIO_BTC4W_OUT_43224 0x020 /* bit 5 is BT_IODISABLE */ -+#define GPIO_BTC4W_OUT_43224_SHARED 0x0e0 /* bit 5 is BT_IODISABLE */ -+#define GPIO_BTC4W_OUT_43225 0x0e0 /* bit 5 BT_IODISABLE, bit 6 SW_BT, bit 7 SW_WL */ -+#define GPIO_BTC4W_OUT_43421 0x020 /* bit 5 is BT_IODISABLE */ -+#define GPIO_BTC4W_OUT_4313 0x060 /* bit 5 SW_BT, bit 6 SW_WL */ -+#define GPIO_BTC4W_OUT_4331_SHARED 0x010 /* GPIO 4 */ -+ -+#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ -+#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */ -+#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal power-up */ -+#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL power-down */ -+ -+/* power control defines */ -+#define PLL_DELAY 150 /* us pll on delay */ -+#define FREF_DELAY 200 /* us fref change delay */ -+#define MIN_SLOW_CLK 32 /* us Slow clock period */ -+#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */ -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+/* Reference Board Types */ -+#define BU4710_BOARD 0x0400 -+#define VSIM4710_BOARD 0x0401 -+#define QT4710_BOARD 0x0402 -+ -+#define BU4309_BOARD 0x040a -+#define BCM94309CB_BOARD 0x040b -+#define BCM94309MP_BOARD 0x040c -+#define BCM4309AP_BOARD 0x040d -+ -+#define BCM94302MP_BOARD 0x040e -+ -+#define BU4306_BOARD 0x0416 -+#define BCM94306CB_BOARD 0x0417 -+#define BCM94306MP_BOARD 0x0418 -+ -+#define BCM94710D_BOARD 0x041a -+#define BCM94710R1_BOARD 0x041b -+#define BCM94710R4_BOARD 0x041c -+#define BCM94710AP_BOARD 0x041d -+ -+#define BU2050_BOARD 0x041f -+ -+#define BCM94306P50_BOARD 0x0420 -+ -+#define BCM94309G_BOARD 0x0421 -+ -+#define BU4704_BOARD 0x0423 -+#define BU4702_BOARD 0x0424 -+ -+#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */ -+ -+#define MPSG4306_BOARD 0x0427 -+ -+#define BCM94702MN_BOARD 0x0428 -+ -+/* BCM4702 1U CompactPCI Board */ -+#define BCM94702CPCI_BOARD 0x0429 -+ -+/* BCM4702 with BCM95380 VLAN Router */ -+#define BCM95380RR_BOARD 0x042a -+ -+/* cb4306 with SiGe PA */ -+#define BCM94306CBSG_BOARD 0x042b -+ -+/* cb4306 with SiGe PA */ -+#define PCSG94306_BOARD 0x042d -+ -+/* bu4704 with sdram */ -+#define BU4704SD_BOARD 0x042e -+ -+/* Dual 11a/11g Router */ -+#define BCM94704AGR_BOARD 0x042f -+ -+/* 11a-only minipci */ -+#define BCM94308MP_BOARD 0x0430 -+ -+/* 4306/gprs combo */ -+#define BCM94306GPRS_BOARD 0x0432 -+ -+/* BCM5365/BCM4704 FPGA Bringup Board */ -+#define BU5365_FPGA_BOARD 0x0433 -+ -+#define BU4712_BOARD 0x0444 -+#define BU4712SD_BOARD 0x045d -+#define BU4712L_BOARD 0x045f -+ -+/* BCM4712 boards */ -+#define BCM94712AP_BOARD 0x0445 -+#define BCM94712P_BOARD 0x0446 -+ -+/* BCM4318 boards */ -+#define BU4318_BOARD 0x0447 -+#define CB4318_BOARD 0x0448 -+#define MPG4318_BOARD 0x0449 -+#define MP4318_BOARD 0x044a -+#define SD4318_BOARD 0x044b -+ -+/* BCM4313 boards */ -+#define BCM94313BU_BOARD 0x050f -+#define BCM94313HM_BOARD 0x0510 -+#define BCM94313EPA_BOARD 0x0511 -+#define BCM94313HMG_BOARD 0x051C -+ -+/* BCM63XX boards */ -+#define BCM96338_BOARD 0x6338 -+#define BCM96348_BOARD 0x6348 -+#define BCM96358_BOARD 0x6358 -+#define BCM96368_BOARD 0x6368 -+ -+/* Another mp4306 with SiGe */ -+#define BCM94306P_BOARD 0x044c -+ -+/* mp4303 */ -+#define BCM94303MP_BOARD 0x044e -+ -+/* mpsgh4306 */ -+#define BCM94306MPSGH_BOARD 0x044f -+ -+/* BRCM 4306 w/ Front End Modules */ -+#define BCM94306MPM 0x0450 -+#define BCM94306MPL 0x0453 -+ -+/* 4712agr */ -+#define BCM94712AGR_BOARD 0x0451 -+ -+/* pcmcia 4303 */ -+#define PC4303_BOARD 0x0454 -+ -+/* 5350K */ -+#define BCM95350K_BOARD 0x0455 -+ -+/* 5350R */ -+#define BCM95350R_BOARD 0x0456 -+ -+/* 4306mplna */ -+#define BCM94306MPLNA_BOARD 0x0457 -+ -+/* 4320 boards */ -+#define BU4320_BOARD 0x0458 -+#define BU4320S_BOARD 0x0459 -+#define BCM94320PH_BOARD 0x045a -+ -+/* 4306mph */ -+#define BCM94306MPH_BOARD 0x045b -+ -+/* 4306pciv */ -+#define BCM94306PCIV_BOARD 0x045c -+ -+#define BU4712SD_BOARD 0x045d -+ -+#define BCM94320PFLSH_BOARD 0x045e -+ -+#define BU4712L_BOARD 0x045f -+#define BCM94712LGR_BOARD 0x0460 -+#define BCM94320R_BOARD 0x0461 -+ -+#define BU5352_BOARD 0x0462 -+ -+#define BCM94318MPGH_BOARD 0x0463 -+ -+#define BU4311_BOARD 0x0464 -+#define BCM94311MC_BOARD 0x0465 -+#define BCM94311MCAG_BOARD 0x0466 -+ -+#define BCM95352GR_BOARD 0x0467 -+ -+/* bcm95351agr */ -+#define BCM95351AGR_BOARD 0x0470 -+ -+/* bcm94704mpcb */ -+#define BCM94704MPCB_BOARD 0x0472 -+ -+/* 4785 boards */ -+#define BU4785_BOARD 0x0478 -+ -+/* 4321 boards */ -+#define BU4321_BOARD 0x046b -+#define BU4321E_BOARD 0x047c -+#define MP4321_BOARD 0x046c -+#define CB2_4321_BOARD 0x046d -+#define CB2_4321_AG_BOARD 0x0066 -+#define MC4321_BOARD 0x046e -+ -+/* 4328 boards */ -+#define BU4328_BOARD 0x0481 -+#define BCM4328SDG_BOARD 0x0482 -+#define BCM4328SDAG_BOARD 0x0483 -+#define BCM4328UG_BOARD 0x0484 -+#define BCM4328UAG_BOARD 0x0485 -+#define BCM4328PC_BOARD 0x0486 -+#define BCM4328CF_BOARD 0x0487 -+ -+/* 4325 boards */ -+#define BCM94325DEVBU_BOARD 0x0490 -+#define BCM94325BGABU_BOARD 0x0491 -+ -+#define BCM94325SDGWB_BOARD 0x0492 -+ -+#define BCM94325SDGMDL_BOARD 0x04aa -+#define BCM94325SDGMDL2_BOARD 0x04c6 -+#define BCM94325SDGMDL3_BOARD 0x04c9 -+ -+#define BCM94325SDABGWBA_BOARD 0x04e1 -+ -+/* 4322 boards */ -+#define BCM94322MC_SSID 0x04a4 -+#define BCM94322USB_SSID 0x04a8 /* dualband */ -+#define BCM94322HM_SSID 0x04b0 -+#define BCM94322USB2D_SSID 0x04bf /* single band discrete front end */ -+ -+/* 4312 boards */ -+#define BCM4312MCGSG_BOARD 0x04b5 -+ -+/* 4315 boards */ -+#define BCM94315DEVBU_SSID 0x04c2 -+#define BCM94315USBGP_SSID 0x04c7 -+#define BCM94315BGABU_SSID 0x04ca -+#define BCM94315USBGP41_SSID 0x04cb -+ -+/* 4319 boards */ -+#define BCM94319DEVBU_SSID 0X04e5 -+#define BCM94319USB_SSID 0X04e6 -+#define BCM94319SD_SSID 0X04e7 -+ -+/* 4716 boards */ -+#define BCM94716NR2_SSID 0x04cd -+ -+/* 4319 boards */ -+#define BCM94319DEVBU_SSID 0X04e5 -+#define BCM94319USBNP4L_SSID 0X04e6 -+#define BCM94319WLUSBN4L_SSID 0X04e7 -+#define BCM94319SDG_SSID 0X04ea -+#define BCM94319LCUSBSDN4L_SSID 0X04eb -+#define BCM94319USBB_SSID 0x04ee -+#define BCM94319LCSDN4L_SSID 0X0507 -+#define BCM94319LSUSBN4L_SSID 0X0508 -+#define BCM94319SDNA4L_SSID 0X0517 -+#define BCM94319SDELNA4L_SSID 0X0518 -+#define BCM94319SDELNA6L_SSID 0X0539 -+#define BCM94319ARCADYAN_SSID 0X0546 -+#define BCM94319WINDSOR_SSID 0x0561 -+#define BCM94319MLAP_SSID 0x0562 -+#define BCM94319SDNA_SSID 0x058b -+#define BCM94319BHEMU3_SSID 0x0563 -+#define BCM94319SDHMB_SSID 0x058c -+#define BCM94319SDBREF_SSID 0x05a1 -+#define BCM94319USBSDB_SSID 0x05a2 -+ -+ -+/* 4329 boards */ -+#define BCM94329AGB_SSID 0X04b9 -+#define BCM94329TDKMDL1_SSID 0X04ba -+#define BCM94329TDKMDL11_SSID 0X04fc -+#define BCM94329OLYMPICN18_SSID 0X04fd -+#define BCM94329OLYMPICN90_SSID 0X04fe -+#define BCM94329OLYMPICN90U_SSID 0X050c -+#define BCM94329OLYMPICN90M_SSID 0X050b -+#define BCM94329AGBF_SSID 0X04ff -+#define BCM94329OLYMPICX17_SSID 0X0504 -+#define BCM94329OLYMPICX17M_SSID 0X050a -+#define BCM94329OLYMPICX17U_SSID 0X0509 -+#define BCM94329OLYMPICUNO_SSID 0X0564 -+#define BCM94329MOTOROLA_SSID 0X0565 -+#define BCM94329OLYMPICLOCO_SSID 0X0568 -+/* 4336 SDIO board types */ -+#define BCM94336SD_WLBGABU_SSID 0x0511 -+#define BCM94336SD_WLBGAREF_SSID 0x0519 -+#define BCM94336SDGP_SSID 0x0538 -+#define BCM94336SDG_SSID 0x0519 -+#define BCM94336SDGN_SSID 0x0538 -+#define BCM94336SDGFC_SSID 0x056B -+ -+/* 4330 SDIO board types */ -+#define BCM94330SDG_SSID 0x0528 -+#define BCM94330SD_FCBGABU_SSID 0x052e -+#define BCM94330SD_WLBGABU_SSID 0x052f -+#define BCM94330SD_FCBGA_SSID 0x0530 -+#define BCM94330FCSDAGB_SSID 0x0532 -+#define BCM94330OLYMPICAMG_SSID 0x0549 -+#define BCM94330OLYMPICAMGEPA_SSID 0x054F -+#define BCM94330OLYMPICUNO3_SSID 0x0551 -+#define BCM94330WLSDAGB_SSID 0x0547 -+#define BCM94330CSPSDAGBB_SSID 0x054A -+ -+/* 43224 boards */ -+#define BCM943224X21 0x056e -+#define BCM943224X21_FCC 0x00d1 -+#define BCM943224X21B 0x00e9 -+#define BCM943224M93 0x008b -+#define BCM943224M93A 0x0090 -+#define BCM943224X16 0x0093 -+#define BCM94322X9 0x008d -+#define BCM94322M35e 0x008e -+ -+/* 43228 Boards */ -+#define BCM943228BU8_SSID 0x0540 -+#define BCM943228BU9_SSID 0x0541 -+#define BCM943228BU_SSID 0x0542 -+#define BCM943227HM4L_SSID 0x0543 -+#define BCM943227HMB_SSID 0x0544 -+#define BCM943228HM4L_SSID 0x0545 -+#define BCM943228SD_SSID 0x0573 -+ -+/* 43239 Boards */ -+#define BCM943239MOD_SSID 0x05ac -+#define BCM943239REF_SSID 0x05aa -+ -+/* 4331 boards */ -+#define BCM94331X19 0x00D6 /* X19B */ -+#define BCM94331X28 0x00E4 /* X28 */ -+#define BCM94331X28B 0x010E /* X28B */ -+#define BCM94331PCIEBT3Ax_SSID BCM94331X28 -+#define BCM94331X12_2G_SSID 0x00EC /* X12 2G */ -+#define BCM94331X12_5G_SSID 0x00ED /* X12 5G */ -+#define BCM94331X29B 0x00EF /* X29B */ -+#define BCM94331CSAX_SSID BCM94331X29B -+#define BCM94331X19C 0x00F5 /* X19C */ -+#define BCM94331X33 0x00F4 /* X33 */ -+#define BCM94331BU_SSID 0x0523 -+#define BCM94331S9BU_SSID 0x0524 -+#define BCM94331MC_SSID 0x0525 -+#define BCM94331MCI_SSID 0x0526 -+#define BCM94331PCIEBT4_SSID 0x0527 -+#define BCM94331HM_SSID 0x0574 -+#define BCM94331PCIEDUAL_SSID 0x059B -+#define BCM94331MCH5_SSID 0x05A9 -+#define BCM94331CS_SSID 0x05C6 -+#define BCM94331CD_SSID 0x05DA -+ -+/* 4314 Boards */ -+#define BCM94314BU_SSID 0x05b1 -+ -+/* 53572 Boards */ -+#define BCM953572BU_SSID 0x058D -+#define BCM953572NR2_SSID 0x058E -+#define BCM947188NR2_SSID 0x058F -+#define BCM953572SDRNR2_SSID 0x0590 -+ -+/* 43236 boards */ -+#define BCM943236OLYMPICSULLEY_SSID 0x594 -+#define BCM943236PREPROTOBLU2O3_SSID 0x5b9 -+#define BCM943236USBELNA_SSID 0x5f8 -+ -+/* 4314 Boards */ -+#define BCM94314BUSDIO_SSID 0x05c8 -+#define BCM94314BGABU_SSID 0x05c9 -+#define BCM94314HMEPA_SSID 0x05ca -+#define BCM94314HMEPABK_SSID 0x05cb -+#define BCM94314SUHMEPA_SSID 0x05cc -+#define BCM94314SUHM_SSID 0x05cd -+#define BCM94314HM_SSID 0x05d1 -+ -+/* 4334 Boards */ -+#define BCM94334FCAGBI_SSID 0x05df -+#define BCM94334WLAGBI_SSID 0x05dd -+ -+/* 43217 Boards */ -+#define BCM943217BU_SSID 0x05d5 -+#define BCM943217HM2L_SSID 0x05d6 -+#define BCM943217HMITR2L_SSID 0x05d7 -+ -+/* 43142 Boards */ -+#define BCM943142HM_SSID 0x05e0 -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+/* # of GPIO pins */ -+#define GPIO_NUMPINS 32 -+ -+/* These values are used by dhd host driver. */ -+#define RDL_RAM_BASE_4319 0x60000000 -+#define RDL_RAM_BASE_4329 0x60000000 -+#define RDL_RAM_SIZE_4319 0x48000 -+#define RDL_RAM_SIZE_4329 0x48000 -+#define RDL_RAM_SIZE_43236 0x70000 -+#define RDL_RAM_BASE_43236 0x60000000 -+#define RDL_RAM_SIZE_4328 0x60000 -+#define RDL_RAM_BASE_4328 0x80000000 -+#define RDL_RAM_SIZE_4322 0x60000 -+#define RDL_RAM_BASE_4322 0x60000000 -+#define RDL_RAM_SIZE_4360 0xE0000 -+#define RDL_RAM_BASE_4360 0x60000000 -+ -+/* generic defs for nvram "muxenab" bits -+* Note: these differ for 4335a0. refer bcmchipc.h for specific mux options. -+*/ -+#define MUXENAB_UART 0x00000001 -+#define MUXENAB_GPIO 0x00000002 -+#define MUXENAB_ERCX 0x00000004 -+#define MUXENAB_JTAG 0x00000008 -+#define MUXENAB_HOST_WAKE 0x00000010 -+ -+/* Boot flags */ -+#define FLASH_KERNEL_NFLASH 0x00000001 -+#define FLASH_BOOT_NFLASH 0x00000002 -+ -+#endif /* _BCMDEVS_H */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmendian.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmendian.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmendian.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmendian.h 2017-11-09 17:53:43.921293000 +0800 -@@ -0,0 +1,324 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Byte order utilities -+ * -+ * $Id: bcmendian.h 241182 2011-02-17 21:50:03Z $ -+ * -+ * This file by default provides proper behavior on little-endian architectures. -+ * On big-endian architectures, IL_BIGENDIAN should be defined. -+ */ -+ -+#ifndef _BCMENDIAN_H_ -+#define _BCMENDIAN_H_ -+ -+#include -+ -+/* Reverse the bytes in a 16-bit value */ -+#define BCMSWAP16(val) \ -+ ((uint16)((((uint16)(val) & (uint16)0x00ffU) << 8) | \ -+ (((uint16)(val) & (uint16)0xff00U) >> 8))) -+ -+/* Reverse the bytes in a 32-bit value */ -+#define BCMSWAP32(val) \ -+ ((uint32)((((uint32)(val) & (uint32)0x000000ffU) << 24) | \ -+ (((uint32)(val) & (uint32)0x0000ff00U) << 8) | \ -+ (((uint32)(val) & (uint32)0x00ff0000U) >> 8) | \ -+ (((uint32)(val) & (uint32)0xff000000U) >> 24))) -+ -+/* Reverse the two 16-bit halves of a 32-bit value */ -+#define BCMSWAP32BY16(val) \ -+ ((uint32)((((uint32)(val) & (uint32)0x0000ffffU) << 16) | \ -+ (((uint32)(val) & (uint32)0xffff0000U) >> 16))) -+ -+/* Byte swapping macros -+ * Host <=> Network (Big Endian) for 16- and 32-bit values -+ * Host <=> Little-Endian for 16- and 32-bit values -+ */ -+#ifndef hton16 -+#ifndef IL_BIGENDIAN -+#define HTON16(i) BCMSWAP16(i) -+#define hton16(i) bcmswap16(i) -+#define HTON32(i) BCMSWAP32(i) -+#define hton32(i) bcmswap32(i) -+#define NTOH16(i) BCMSWAP16(i) -+#define ntoh16(i) bcmswap16(i) -+#define NTOH32(i) BCMSWAP32(i) -+#define ntoh32(i) bcmswap32(i) -+#define LTOH16(i) (i) -+#define ltoh16(i) (i) -+#define LTOH32(i) (i) -+#define ltoh32(i) (i) -+#define HTOL16(i) (i) -+#define htol16(i) (i) -+#define HTOL32(i) (i) -+#define htol32(i) (i) -+#else /* IL_BIGENDIAN */ -+#define HTON16(i) (i) -+#define hton16(i) (i) -+#define HTON32(i) (i) -+#define hton32(i) (i) -+#define NTOH16(i) (i) -+#define ntoh16(i) (i) -+#define NTOH32(i) (i) -+#define ntoh32(i) (i) -+#define LTOH16(i) BCMSWAP16(i) -+#define ltoh16(i) bcmswap16(i) -+#define LTOH32(i) BCMSWAP32(i) -+#define ltoh32(i) bcmswap32(i) -+#define HTOL16(i) BCMSWAP16(i) -+#define htol16(i) bcmswap16(i) -+#define HTOL32(i) BCMSWAP32(i) -+#define htol32(i) bcmswap32(i) -+#endif /* IL_BIGENDIAN */ -+#endif /* hton16 */ -+ -+#ifndef IL_BIGENDIAN -+#define ltoh16_buf(buf, i) -+#define htol16_buf(buf, i) -+#else -+#define ltoh16_buf(buf, i) bcmswap16_buf((uint16 *)(buf), (i)) -+#define htol16_buf(buf, i) bcmswap16_buf((uint16 *)(buf), (i)) -+#endif /* IL_BIGENDIAN */ -+ -+/* Unaligned loads and stores in host byte order */ -+#ifndef IL_BIGENDIAN -+#define load32_ua(a) ltoh32_ua(a) -+#define store32_ua(a, v) htol32_ua_store(v, a) -+#define load16_ua(a) ltoh16_ua(a) -+#define store16_ua(a, v) htol16_ua_store(v, a) -+#else -+#define load32_ua(a) ntoh32_ua(a) -+#define store32_ua(a, v) hton32_ua_store(v, a) -+#define load16_ua(a) ntoh16_ua(a) -+#define store16_ua(a, v) hton16_ua_store(v, a) -+#endif /* IL_BIGENDIAN */ -+ -+#define _LTOH16_UA(cp) ((cp)[0] | ((cp)[1] << 8)) -+#define _LTOH32_UA(cp) ((cp)[0] | ((cp)[1] << 8) | ((cp)[2] << 16) | ((cp)[3] << 24)) -+#define _NTOH16_UA(cp) (((cp)[0] << 8) | (cp)[1]) -+#define _NTOH32_UA(cp) (((cp)[0] << 24) | ((cp)[1] << 16) | ((cp)[2] << 8) | (cp)[3]) -+ -+#define ltoh_ua(ptr) \ -+ (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \ -+ sizeof(*(ptr)) == sizeof(uint16) ? _LTOH16_UA((const uint8 *)(ptr)) : \ -+ sizeof(*(ptr)) == sizeof(uint32) ? _LTOH32_UA((const uint8 *)(ptr)) : \ -+ *(uint8 *)0) -+ -+#define ntoh_ua(ptr) \ -+ (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \ -+ sizeof(*(ptr)) == sizeof(uint16) ? _NTOH16_UA((const uint8 *)(ptr)) : \ -+ sizeof(*(ptr)) == sizeof(uint32) ? _NTOH32_UA((const uint8 *)(ptr)) : \ -+ *(uint8 *)0) -+ -+#ifdef __GNUC__ -+ -+/* GNU macro versions avoid referencing the argument multiple times, while also -+ * avoiding the -fno-inline used in ROM builds. -+ */ -+ -+#define bcmswap16(val) ({ \ -+ uint16 _val = (val); \ -+ BCMSWAP16(_val); \ -+}) -+ -+#define bcmswap32(val) ({ \ -+ uint32 _val = (val); \ -+ BCMSWAP32(_val); \ -+}) -+ -+#define bcmswap32by16(val) ({ \ -+ uint32 _val = (val); \ -+ BCMSWAP32BY16(_val); \ -+}) -+ -+#define bcmswap16_buf(buf, len) ({ \ -+ uint16 *_buf = (uint16 *)(buf); \ -+ uint _wds = (len) / 2; \ -+ while (_wds--) { \ -+ *_buf = bcmswap16(*_buf); \ -+ _buf++; \ -+ } \ -+}) -+ -+#define htol16_ua_store(val, bytes) ({ \ -+ uint16 _val = (val); \ -+ uint8 *_bytes = (uint8 *)(bytes); \ -+ _bytes[0] = _val & 0xff; \ -+ _bytes[1] = _val >> 8; \ -+}) -+ -+#define htol32_ua_store(val, bytes) ({ \ -+ uint32 _val = (val); \ -+ uint8 *_bytes = (uint8 *)(bytes); \ -+ _bytes[0] = _val & 0xff; \ -+ _bytes[1] = (_val >> 8) & 0xff; \ -+ _bytes[2] = (_val >> 16) & 0xff; \ -+ _bytes[3] = _val >> 24; \ -+}) -+ -+#define hton16_ua_store(val, bytes) ({ \ -+ uint16 _val = (val); \ -+ uint8 *_bytes = (uint8 *)(bytes); \ -+ _bytes[0] = _val >> 8; \ -+ _bytes[1] = _val & 0xff; \ -+}) -+ -+#define hton32_ua_store(val, bytes) ({ \ -+ uint32 _val = (val); \ -+ uint8 *_bytes = (uint8 *)(bytes); \ -+ _bytes[0] = _val >> 24; \ -+ _bytes[1] = (_val >> 16) & 0xff; \ -+ _bytes[2] = (_val >> 8) & 0xff; \ -+ _bytes[3] = _val & 0xff; \ -+}) -+ -+#define ltoh16_ua(bytes) ({ \ -+ const uint8 *_bytes = (const uint8 *)(bytes); \ -+ _LTOH16_UA(_bytes); \ -+}) -+ -+#define ltoh32_ua(bytes) ({ \ -+ const uint8 *_bytes = (const uint8 *)(bytes); \ -+ _LTOH32_UA(_bytes); \ -+}) -+ -+#define ntoh16_ua(bytes) ({ \ -+ const uint8 *_bytes = (const uint8 *)(bytes); \ -+ _NTOH16_UA(_bytes); \ -+}) -+ -+#define ntoh32_ua(bytes) ({ \ -+ const uint8 *_bytes = (const uint8 *)(bytes); \ -+ _NTOH32_UA(_bytes); \ -+}) -+ -+#else /* !__GNUC__ */ -+ -+/* Inline versions avoid referencing the argument multiple times */ -+static INLINE uint16 -+bcmswap16(uint16 val) -+{ -+ return BCMSWAP16(val); -+} -+ -+static INLINE uint32 -+bcmswap32(uint32 val) -+{ -+ return BCMSWAP32(val); -+} -+ -+static INLINE uint32 -+bcmswap32by16(uint32 val) -+{ -+ return BCMSWAP32BY16(val); -+} -+ -+/* Reverse pairs of bytes in a buffer (not for high-performance use) */ -+/* buf - start of buffer of shorts to swap */ -+/* len - byte length of buffer */ -+static INLINE void -+bcmswap16_buf(uint16 *buf, uint len) -+{ -+ len = len / 2; -+ -+ while (len--) { -+ *buf = bcmswap16(*buf); -+ buf++; -+ } -+} -+ -+/* -+ * Store 16-bit value to unaligned little-endian byte array. -+ */ -+static INLINE void -+htol16_ua_store(uint16 val, uint8 *bytes) -+{ -+ bytes[0] = val & 0xff; -+ bytes[1] = val >> 8; -+} -+ -+/* -+ * Store 32-bit value to unaligned little-endian byte array. -+ */ -+static INLINE void -+htol32_ua_store(uint32 val, uint8 *bytes) -+{ -+ bytes[0] = val & 0xff; -+ bytes[1] = (val >> 8) & 0xff; -+ bytes[2] = (val >> 16) & 0xff; -+ bytes[3] = val >> 24; -+} -+ -+/* -+ * Store 16-bit value to unaligned network-(big-)endian byte array. -+ */ -+static INLINE void -+hton16_ua_store(uint16 val, uint8 *bytes) -+{ -+ bytes[0] = val >> 8; -+ bytes[1] = val & 0xff; -+} -+ -+/* -+ * Store 32-bit value to unaligned network-(big-)endian byte array. -+ */ -+static INLINE void -+hton32_ua_store(uint32 val, uint8 *bytes) -+{ -+ bytes[0] = val >> 24; -+ bytes[1] = (val >> 16) & 0xff; -+ bytes[2] = (val >> 8) & 0xff; -+ bytes[3] = val & 0xff; -+} -+ -+/* -+ * Load 16-bit value from unaligned little-endian byte array. -+ */ -+static INLINE uint16 -+ltoh16_ua(const void *bytes) -+{ -+ return _LTOH16_UA((const uint8 *)bytes); -+} -+ -+/* -+ * Load 32-bit value from unaligned little-endian byte array. -+ */ -+static INLINE uint32 -+ltoh32_ua(const void *bytes) -+{ -+ return _LTOH32_UA((const uint8 *)bytes); -+} -+ -+/* -+ * Load 16-bit value from unaligned big-(network-)endian byte array. -+ */ -+static INLINE uint16 -+ntoh16_ua(const void *bytes) -+{ -+ return _NTOH16_UA((const uint8 *)bytes); -+} -+ -+/* -+ * Load 32-bit value from unaligned big-(network-)endian byte array. -+ */ -+static INLINE uint32 -+ntoh32_ua(const void *bytes) -+{ -+ return _NTOH32_UA((const uint8 *)bytes); -+} -+ -+#endif /* !__GNUC__ */ -+#endif /* !_BCMENDIAN_H_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetmib.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetmib.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetmib.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetmib.h 2017-11-09 17:53:43.922294000 +0800 -@@ -0,0 +1,88 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Hardware-specific MIB definition for -+ * Broadcom Home Networking Division -+ * BCM44XX and BCM47XX 10/100 Mbps Ethernet cores. -+ * -+ * $Id: bcmenetmib.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _bcmenetmib_h_ -+#define _bcmenetmib_h_ -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif /* PAD */ -+ -+/* -+ * EMAC MIB Registers -+ */ -+typedef volatile struct { -+ uint32 tx_good_octets; -+ uint32 tx_good_pkts; -+ uint32 tx_octets; -+ uint32 tx_pkts; -+ uint32 tx_broadcast_pkts; -+ uint32 tx_multicast_pkts; -+ uint32 tx_len_64; -+ uint32 tx_len_65_to_127; -+ uint32 tx_len_128_to_255; -+ uint32 tx_len_256_to_511; -+ uint32 tx_len_512_to_1023; -+ uint32 tx_len_1024_to_max; -+ uint32 tx_jabber_pkts; -+ uint32 tx_oversize_pkts; -+ uint32 tx_fragment_pkts; -+ uint32 tx_underruns; -+ uint32 tx_total_cols; -+ uint32 tx_single_cols; -+ uint32 tx_multiple_cols; -+ uint32 tx_excessive_cols; -+ uint32 tx_late_cols; -+ uint32 tx_defered; -+ uint32 tx_carrier_lost; -+ uint32 tx_pause_pkts; -+ uint32 PAD[8]; -+ -+ uint32 rx_good_octets; -+ uint32 rx_good_pkts; -+ uint32 rx_octets; -+ uint32 rx_pkts; -+ uint32 rx_broadcast_pkts; -+ uint32 rx_multicast_pkts; -+ uint32 rx_len_64; -+ uint32 rx_len_65_to_127; -+ uint32 rx_len_128_to_255; -+ uint32 rx_len_256_to_511; -+ uint32 rx_len_512_to_1023; -+ uint32 rx_len_1024_to_max; -+ uint32 rx_jabber_pkts; -+ uint32 rx_oversize_pkts; -+ uint32 rx_fragment_pkts; -+ uint32 rx_missed_pkts; -+ uint32 rx_crc_align_errs; -+ uint32 rx_undersize; -+ uint32 rx_crc_errs; -+ uint32 rx_align_errs; -+ uint32 rx_symbol_errs; -+ uint32 rx_pause_pkts; -+ uint32 rx_nonpause_pkts; -+} bcmenetmib_t; -+ -+#endif /* _bcmenetmib_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetphy.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetphy.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetphy.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetphy.h 2017-11-09 17:53:43.923292000 +0800 -@@ -0,0 +1,86 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Misc Broadcom BCM47XX MDC/MDIO enet phy definitions. -+ * -+ * $Id: bcmenetphy.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _bcmenetphy_h_ -+#define _bcmenetphy_h_ -+ -+/* phy address */ -+#define MAXEPHY 32 /* mdio phy addresses are 5bit quantities */ -+#define EPHY_MASK 0x1f /* phy mask */ -+#define EPHY_NONE 31 /* nvram: no phy present at all */ -+#define EPHY_NOREG 30 /* nvram: no local phy regs */ -+ -+#define MAXPHYREG 32 /* max 32 registers per phy */ -+ -+/* just a few phy registers */ -+#define CTL_RESET (1 << 15) /* reset */ -+#define CTL_LOOP (1 << 14) /* loopback */ -+#define CTL_SPEED (1 << 13) /* speed selection lsb 0=10, 1=100 */ -+#define CTL_ANENAB (1 << 12) /* autonegotiation enable */ -+#define CTL_RESTART (1 << 9) /* restart autonegotiation */ -+#define CTL_DUPLEX (1 << 8) /* duplex mode 0=half, 1=full */ -+#define CTL_SPEED_MSB (1 << 6) /* speed selection msb */ -+ -+#define CTL_SPEED_10 ((0 << 6) | (0 << 13)) /* speed selection CTL.6=0, CTL.13=0 */ -+#define CTL_SPEED_100 ((0 << 6) | (1 << 13)) /* speed selection CTL.6=0, CTL.13=1 */ -+#define CTL_SPEED_1000 ((1 << 6) | (0 << 13)) /* speed selection CTL.6=1, CTL.13=0 */ -+ -+#define ADV_10FULL (1 << 6) /* autonegotiate advertise 10full */ -+#define ADV_10HALF (1 << 5) /* autonegotiate advertise 10half */ -+#define ADV_100FULL (1 << 8) /* autonegotiate advertise 100full */ -+#define ADV_100HALF (1 << 7) /* autonegotiate advertise 100half */ -+#define ADV_PAUSE (1 << 10) /* autonegotiate advertise pause */ -+ -+/* link partner ability register */ -+#define LPA_SLCT 0x001f /* same as advertise selector */ -+#define LPA_10HALF 0x0020 /* can do 10mbps half-duplex */ -+#define LPA_10FULL 0x0040 /* can do 10mbps full-duplex */ -+#define LPA_100HALF 0x0080 /* can do 100mbps half-duplex */ -+#define LPA_100FULL 0x0100 /* can do 100mbps full-duplex */ -+#define LPA_100BASE4 0x0200 /* can do 100mbps 4k packets */ -+#define LPA_RFAULT 0x2000 /* link partner faulted */ -+#define LPA_LPACK 0x4000 /* link partner acked us */ -+#define LPA_NPAGE 0x8000 /* next page bit */ -+ -+#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL) -+#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4) -+ -+/* 1000BASE-T control register */ -+#define ADV_1000HALF 0x0100 /* advertise 1000BASE-T half duplex */ -+#define ADV_1000FULL 0x0200 /* advertise 1000BASE-T full duplex */ -+ -+/* 1000BASE-T status register */ -+#define LPA_1000HALF 0x0400 /* link partner 1000BASE-T half duplex */ -+#define LPA_1000FULL 0x0800 /* link partner 1000BASE-T full duplex */ -+ -+/* 1000BASE-T extended status register */ -+#define EST_1000THALF 0x1000 /* 1000BASE-T half duplex capable */ -+#define EST_1000TFULL 0x2000 /* 1000BASE-T full duplex capable */ -+#define EST_1000XHALF 0x4000 /* 1000BASE-X half duplex capable */ -+#define EST_1000XFULL 0x8000 /* 1000BASE-X full duplex capable */ -+ -+#define STAT_REMFAULT (1 << 4) /* remote fault */ -+#define STAT_LINK (1 << 2) /* link status */ -+#define STAT_JAB (1 << 1) /* jabber detected */ -+#define AUX_FORCED (1 << 2) /* forced 10/100 */ -+#define AUX_SPEED (1 << 1) /* speed 0=10mbps 1=100mbps */ -+#define AUX_DUPLEX (1 << 0) /* duplex 0=half 1=full */ -+ -+#endif /* _bcmenetphy_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetrxh.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetrxh.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetrxh.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmenetrxh.h 2017-11-09 17:53:43.927297000 +0800 -@@ -0,0 +1,50 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Hardware-specific Receive Data Header for the -+ * Broadcom Home Networking Division -+ * BCM44XX and BCM47XX 10/100 Mbps Ethernet cores. -+ * -+ * $Id: bcmenetrxh.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _bcmenetrxh_h_ -+#define _bcmenetrxh_h_ -+ -+/* -+ * The Ethernet MAC core returns an 8-byte Receive Frame Data Header -+ * with every frame consisting of -+ * 16bits of frame length, followed by -+ * 16bits of EMAC rx descriptor info, followed by 32bits of undefined. -+ */ -+typedef volatile struct { -+ uint16 len; -+ uint16 flags; -+ uint16 pad[12]; -+} bcmenetrxh_t; -+ -+#define RXHDR_LEN 28 /* Header length */ -+ -+#define RXF_L ((uint16)1 << 11) /* last buffer in a frame */ -+#define RXF_MISS ((uint16)1 << 7) /* received due to promisc mode */ -+#define RXF_BRDCAST ((uint16)1 << 6) /* dest is broadcast address */ -+#define RXF_MULT ((uint16)1 << 5) /* dest is multicast address */ -+#define RXF_LG ((uint16)1 << 4) /* frame length > rxmaxlength */ -+#define RXF_NO ((uint16)1 << 3) /* odd number of nibbles */ -+#define RXF_RXER ((uint16)1 << 2) /* receive symbol error */ -+#define RXF_CRC ((uint16)1 << 1) /* crc error */ -+#define RXF_OV ((uint16)1 << 0) /* fifo overflow */ -+ -+#endif /* _bcmenetrxh_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmgmacmib.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmgmacmib.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmgmacmib.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmgmacmib.h 2017-11-09 17:53:43.928296000 +0800 -@@ -0,0 +1,117 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Hardware-specific MIB definition for -+ * Broadcom Home Networking Division -+ * GbE Unimac core -+ * -+ * $Id: bcmgmacmib.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _bcmgmacmib_h_ -+#define _bcmgmacmib_h_ -+ -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif /* PAD */ -+ -+/* GMAC MIB structure */ -+ -+typedef struct _gmacmib { -+ uint32 tx_good_octets; /* 0x300 */ -+ uint32 tx_good_octets_high; /* 0x304 */ -+ uint32 tx_good_pkts; /* 0x308 */ -+ uint32 tx_octets; /* 0x30c */ -+ uint32 tx_octets_high; /* 0x310 */ -+ uint32 tx_pkts; /* 0x314 */ -+ uint32 tx_broadcast_pkts; /* 0x318 */ -+ uint32 tx_multicast_pkts; /* 0x31c */ -+ uint32 tx_len_64; /* 0x320 */ -+ uint32 tx_len_65_to_127; /* 0x324 */ -+ uint32 tx_len_128_to_255; /* 0x328 */ -+ uint32 tx_len_256_to_511; /* 0x32c */ -+ uint32 tx_len_512_to_1023; /* 0x330 */ -+ uint32 tx_len_1024_to_1522; /* 0x334 */ -+ uint32 tx_len_1523_to_2047; /* 0x338 */ -+ uint32 tx_len_2048_to_4095; /* 0x33c */ -+ uint32 tx_len_4095_to_8191; /* 0x340 */ -+ uint32 tx_len_8192_to_max; /* 0x344 */ -+ uint32 tx_jabber_pkts; /* 0x348 */ -+ uint32 tx_oversize_pkts; /* 0x34c */ -+ uint32 tx_fragment_pkts; /* 0x350 */ -+ uint32 tx_underruns; /* 0x354 */ -+ uint32 tx_total_cols; /* 0x358 */ -+ uint32 tx_single_cols; /* 0x35c */ -+ uint32 tx_multiple_cols; /* 0x360 */ -+ uint32 tx_excessive_cols; /* 0x364 */ -+ uint32 tx_late_cols; /* 0x368 */ -+ uint32 tx_defered; /* 0x36c */ -+ uint32 tx_carrier_lost; /* 0x370 */ -+ uint32 tx_pause_pkts; /* 0x374 */ -+ uint32 tx_uni_pkts; /* 0x378 */ -+ uint32 tx_q0_pkts; /* 0x37c */ -+ uint32 tx_q0_octets; /* 0x380 */ -+ uint32 tx_q0_octets_high; /* 0x384 */ -+ uint32 tx_q1_pkts; /* 0x388 */ -+ uint32 tx_q1_octets; /* 0x38c */ -+ uint32 tx_q1_octets_high; /* 0x390 */ -+ uint32 tx_q2_pkts; /* 0x394 */ -+ uint32 tx_q2_octets; /* 0x398 */ -+ uint32 tx_q2_octets_high; /* 0x39c */ -+ uint32 tx_q3_pkts; /* 0x3a0 */ -+ uint32 tx_q3_octets; /* 0x3a4 */ -+ uint32 tx_q3_octets_high; /* 0x3a8 */ -+ uint32 PAD; -+ uint32 rx_good_octets; /* 0x3b0 */ -+ uint32 rx_good_octets_high; /* 0x3b4 */ -+ uint32 rx_good_pkts; /* 0x3b8 */ -+ uint32 rx_octets; /* 0x3bc */ -+ uint32 rx_octets_high; /* 0x3c0 */ -+ uint32 rx_pkts; /* 0x3c4 */ -+ uint32 rx_broadcast_pkts; /* 0x3c8 */ -+ uint32 rx_multicast_pkts; /* 0x3cc */ -+ uint32 rx_len_64; /* 0x3d0 */ -+ uint32 rx_len_65_to_127; /* 0x3d4 */ -+ uint32 rx_len_128_to_255; /* 0x3d8 */ -+ uint32 rx_len_256_to_511; /* 0x3dc */ -+ uint32 rx_len_512_to_1023; /* 0x3e0 */ -+ uint32 rx_len_1024_to_1522; /* 0x3e4 */ -+ uint32 rx_len_1523_to_2047; /* 0x3e8 */ -+ uint32 rx_len_2048_to_4095; /* 0x3ec */ -+ uint32 rx_len_4095_to_8191; /* 0x3f0 */ -+ uint32 rx_len_8192_to_max; /* 0x3f4 */ -+ uint32 rx_jabber_pkts; /* 0x3f8 */ -+ uint32 rx_oversize_pkts; /* 0x3fc */ -+ uint32 rx_fragment_pkts; /* 0x400 */ -+ uint32 rx_missed_pkts; /* 0x404 */ -+ uint32 rx_crc_align_errs; /* 0x408 */ -+ uint32 rx_undersize; /* 0x40c */ -+ uint32 rx_crc_errs; /* 0x410 */ -+ uint32 rx_align_errs; /* 0x414 */ -+ uint32 rx_symbol_errs; /* 0x418 */ -+ uint32 rx_pause_pkts; /* 0x41c */ -+ uint32 rx_nonpause_pkts; /* 0x420 */ -+ uint32 rx_sachanges; /* 0x424 */ -+ uint32 rx_uni_pkts; /* 0x428 */ -+} gmacmib_t; -+ -+#define GM_MIB_BASE 0x300 -+#define GM_MIB_LIMIT 0x800 -+ -+#endif /* _bcmgmacmib_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmgmacrxh.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmgmacrxh.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmgmacrxh.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmgmacrxh.h 2017-11-09 17:53:43.929307000 +0800 -@@ -0,0 +1,53 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Hardware-specific Receive Data Header for the -+ * Broadcom Home Networking Division -+ * BCM47XX GbE cores. -+ * -+ * $Id: bcmgmacrxh.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _bcmgmacrxh_h_ -+#define _bcmgmacrxh_h_ -+ -+/* -+ * The Ethernet GMAC core returns an 8-byte Receive Frame Data Header -+ * with every frame consisting of -+ * 16 bits of frame length, followed by -+ * 16 bits of GMAC rx descriptor info, followed by 32bits of undefined. -+ */ -+typedef volatile struct { -+ uint16 len; -+ uint16 flags; -+ uint16 pad[12]; -+} bcmgmacrxh_t; -+ -+#define RXHDR_LEN 28 /* Header length */ -+ -+#define GRXF_DT_MASK ((uint16)0xf) /* data type */ -+#define GRXF_DT_SHIFT 12 -+#define GRXF_DC_MASK ((uint16)0xf) /* (num descr to xfer the frame) - 1 */ -+#define GRXF_DC_SHIFT 8 -+#define GRXF_OVF ((uint16)1 << 7) /* overflow error occured */ -+#define GRXF_CTFERR ((uint16)1 << 6) /* overflow error occured */ -+#define GRXF_OVERSIZE ((uint16)1 << 4) /* frame size > rxmaxlength */ -+#define GRXF_CRC ((uint16)1 << 3) /* crc error */ -+#define GRXF_VLAN ((uint16)1 << 2) /* vlan tag detected */ -+#define GRXF_PT_MASK ((uint16)3) /* packet type 0 - Unicast, -+ * 1 - Multicast, 2 - Broadcast -+ */ -+ -+#endif /* _bcmgmacrxh_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_egphy28.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_egphy28.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_egphy28.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_egphy28.h 2017-11-09 17:53:43.930299000 +0800 -@@ -0,0 +1,68 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * These routines provide access to the external phy -+ * -+ */ -+ -+#ifndef _EGPHY28_H_ -+#define _EGPHY28_H_ -+ -+#define EGPHY28_REG_RDB_ADDR 0x1e -+#define EGPHY28_REG_RDB_DATA 0x1f -+ -+#define EGPHY28_RDB_ACCESS_ADDR_1 0x17 -+#define EGPHY28_RDB_ACCESS_DATA_1 0x0f7e -+#define EGPHY28_RDB_ACCESS_ADDR_2 0x15 -+#define EGPHY28_RDB_ACCESS_DATA_2 0x0000 -+ -+/* Generic MII registers */ -+#define EGPHY28_COPPER_MII_CTRL 0x00 -+#define EGPHY28_PHY_ID_MSB 0x02 /* PHY ID MSB */ -+#define EGPHY28_PHY_ID_LSB 0x03 /* PHY ID LSB */ -+#define EGPHY28_MII_ADVERTISE 0x04 /* Advertisement control reg */ -+#define EGPHY28_MII_CTRL1000 0x09 /* 1000BASE-T control */ -+#define EGPGY28_MII_ECONTROL 0x10 /* Extended Control */ -+#define EGPHY28_COPPER_MISC_CTRL 0x2f /* COPPER MISC CONTROL */ -+ -+/* For EGPHY28_COPPER_MII_CTRL(0x00) */ -+#define BMCR_FULLDPLX 0x0100 /* Full duplex */ -+#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ -+#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ -+#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ -+#define BMCR_PDOWN 0x0800 /* Powerdown EGPHY28 */ -+#define BMCR_RESET 0x8000 /* Reset EGPHY28 */ -+ -+/* For EGPHY28_MII_ADVERTISE(0x04) */ -+#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */ -+#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ -+#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ -+#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ -+#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ -+#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ -+ -+/* For EGPHY28_MII_CTRL1000(0x09) */ -+#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ -+#define REPEATER_DTE 0x0400 /* Repeater/switch or DTE port type */ -+ -+/* For EGPHY28_COPPER_MISC_CTRL(0x2f) */ -+#define BMCR_FORCE_AUTO_MDIX 0x0200 -+ -+extern int egphy28_enable_set(u32 phy_addr, int enable); -+extern int egphy28_init(void __iomem *base, u32 phy_addr); -+extern int egphy28_enable_set(u32 phy_addr, int enable); -+extern int egphy28_force_auto_mdix(u32 phy_addr, int enable); -+ -+#endif -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy.h 2017-11-09 17:53:43.931300000 +0800 -@@ -0,0 +1,290 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * These routines provide access to the external phy -+ * -+ */ -+ -+#ifndef _bcm_iproc_phy_h_ -+#define _bcm_iproc_phy_h_ -+ -+ -+#define PHY_ADDR_MASK 0x00001F -+#define PHY_BUS_MASK 0x000020 -+#define PHY_BANK_MASK 0x001F00 -+#define PHY_FLAG_MASK 0xFF0000 -+#define PHY_ADDR(_flag, _bank, _bus, _addr) \ -+ (((_flag << 16) & PHY_FLAG_MASK) | ((_bank << 8) & PHY_BANK_MASK) | \ -+ ((_bus << 5) & PHY_BUS_MASK) | ((_addr << 0) & PHY_ADDR_MASK)) -+ -+#define PHY_REG_ADDR(_addr) ((_addr & PHY_ADDR_MASK) >> 0) -+#define PHY_REG_BUS(_addr) ((_addr & PHY_BUS_MASK) >> 5) -+#define PHY_REG_BANK(_addr) ((_addr & PHY_BANK_MASK) >> 8) -+#define PHY_REG_FLAGS(_addr) ((_addr & PHY_FLAG_MASK) >> 16) -+ -+/* Flags for phy register */ -+#define PHY_REG_FLAGS_NONE (0) -+#define PHY_REG_FLAGS_1000X (1 << 0) -+#define PHY_REG_FLAGS_PRI_SERDES (1 << 1) -+#define PHY_REG_FLAGS_RDB (1 << 2) -+#define PHY_REG_FLAGS_QSGMII (1 << 3) -+#define PHY_REG_FLAGS_FIBER (PHY_REG_FLAGS_1000X | \ -+ PHY_REG_FLAGS_PRI_SERDES) -+ -+typedef enum { -+ SOC_E_NONE = 0, -+ SOC_E_INTERNAL = -1, -+ SOC_E_MEMORY = -2, -+ SOC_E_UNIT = -3, -+ SOC_E_PARAM = -4, -+ SOC_E_EMPTY = -5, -+ SOC_E_FULL = -6, -+ SOC_E_NOT_FOUND = -7, -+ SOC_E_EXISTS = -8, -+ SOC_E_TIMEOUT = -9, -+ SOC_E_BUSY = -10, -+ SOC_E_FAIL = -11, -+ SOC_E_DISABLED = -12, -+ SOC_E_BADID = -13, -+ SOC_E_RESOURCE = -14, -+ SOC_E_CONFIG = -15, -+ SOC_E_UNAVAIL = -16, -+ SOC_E_INIT = -17, -+ SOC_E_PORT = -18, -+ -+ SOC_E_LIMIT = -19 /* Must come last */ -+} soc_error_t; -+ -+#define SOC_SUCCESS(rv) ((rv) >= 0) -+#define SOC_FAILURE(rv) ((rv) < 0) -+ -+typedef enum _soc_port_if_e { -+ SOC_PORT_IF_NOCXN, /* No physical connection */ -+ SOC_PORT_IF_NULL, /* Pass-through connection without PHY */ -+ SOC_PORT_IF_MII, -+ SOC_PORT_IF_GMII, -+ SOC_PORT_IF_SGMII, -+ SOC_PORT_IF_TBI, -+ SOC_PORT_IF_XGMII, -+ SOC_PORT_IF_RGMII, -+ SOC_PORT_IF_RvMII, -+ SOC_PORT_IF_SFI, -+ SOC_PORT_IF_XFI, -+ SOC_PORT_IF_KR, -+ SOC_PORT_IF_KR4, -+ SOC_PORT_IF_CR, -+ SOC_PORT_IF_CR4, -+ SOC_PORT_IF_XLAUI, -+ SOC_PORT_IF_SR, -+ SOC_PORT_IF_RXAUI, -+ SOC_PORT_IF_XAUI, -+ SOC_PORT_IF_SPAUI, -+ SOC_PORT_IF_QSGMII, -+ SOC_PORT_IF_ILKN, -+ SOC_PORT_IF_RCY, -+ SOC_PORT_IF_FAT_PIPE, -+ SOC_PORT_IF_CGMII, -+ SOC_PORT_IF_CAUI, -+ SOC_PORT_IF_LR, -+ SOC_PORT_IF_LR4, -+ SOC_PORT_IF_SR4, -+ SOC_PORT_IF_KX, -+ SOC_PORT_IF_CPU, -+ SOC_PORT_IF_OLP, -+ SOC_PORT_IF_OAMP, -+ SOC_PORT_IF_ERP, -+ SOC_PORT_IF_COUNT /* last, please */ -+} _soc_port_if_t; -+typedef _soc_port_if_t soc_port_if_t; -+ -+ -+/* 1000BASE-T/100BASE-TX/10BASE-T MII Control Register (Addr 00h) */ -+#define PHY_MII_CTRLr_FLAGS 0x00 -+#define PHY_MII_CTRLr_BANK 0x0000 -+#define PHY_MII_CTRLr_ADDR 0x00 -+/* 1000BASE-T/100BASE-TX/10BASE-T MII Status Register (ADDR 01h) */ -+#define PHY_MII_STATr_FLAGS 0x00 -+#define PHY_MII_STATr_BANK 0x0000 -+#define PHY_MII_STATr_ADDR 0x01 -+/* 1000BASE-T/100BASE-TX/10BASE-T PHY Identifier Register (ADDR 02h) */ -+#define PHY_MII_PHY_ID0r_FLAGS _SOC_PHY_REG_DIRECT -+#define PHY_MII_PHY_ID0r_BANK 0x0000 -+#define PHY_MII_PHY_ID0r_ADDR 0x02 -+/* 1000BASE-T/100BASE-TX/10BASE-T PHY Identifier Register (ADDR 03h) */ -+#define PHY_MII_PHY_ID1r_FLAGS _SOC_PHY_REG_DIRECT -+#define PHY_MII_PHY_ID1r_BANK 0x0000 -+#define PHY_MII_PHY_ID1r_ADDR 0x03 -+/* 1000BASE-T/100BASE-TX/10BASE-T Auto-neg Advertisment Register (ADDR 04h) */ -+#define PHY_MII_ANAr_FLAGS 0x00 -+#define PHY_MII_ANAr_BANK 0x0000 -+#define PHY_MII_ANAr_ADDR 0x04 -+/* 1000BASE-T/100BASE-TX/10BASE-T Auto-neg Link Partner Ability (ADDR 05h) */ -+#define PHY_MII_ANPr_FLAGS 0x00 -+#define PHY_MII_ANPr_BANK 0x0000 -+#define PHY_MII_ANPr_ADDR 0x05 -+/* 1000BASE-T Control Register (ADDR 09h) */ -+#define PHY_MII_GB_CTRLr_FLAGS 0x00 -+#define PHY_MII_GB_CTRLr_BANK 0x0000 -+#define PHY_MII_GB_CTRLr_ADDR 0x09 -+/* 1000BASE-T Status Register (ADDR 0ah) */ -+#define PHY_MII_GB_STATr_FLAGS 0x00 -+#define PHY_MII_GB_STATr_BANK 0x0000 -+#define PHY_MII_GB_STATr_ADDR 0x0a -+/* 1000BASE-T/100BASE-TX/10BASE-T IEEE Extended Status Register (ADDR 0fh) */ -+#define PHY_MII_ESRr_FLAGS 0x00 -+#define PHY_MII_ESRr_BANK 0x0000 -+#define PHY_MII_ESRr_ADDR 0x0f -+/* 1000BASE-T/100BASE-TX/10BASE-T PHY Extended Control Register (ADDR 10h) */ -+#define PHY_MII_ECRr_FLAGS 0x00 -+#define PHY_MII_ECRr_BANK 0x0000 -+#define PHY_MII_ECRr_ADDR 0x10 -+/* 1000BASE-T/100BASE-TX/10BASE-T Auxiliary Control Reg (ADDR 18h Shadow 000)*/ -+#define PHY_MII_AUX_CTRLr_FLAGS 0x00 -+#define PHY_MII_AUX_CTRLr_BANK 0x0000 -+#define PHY_MII_AUX_CTRLr_ADDR 0x18 -+/* 1000BASE-T/100BASE-TX/10BASE-T Power/MII Control Reg (ADDR 18h Shadow 010)*/ -+#define PHY_MII_POWER_CTRLr_FLAGS 0x00 -+#define PHY_MII_POWER_CTRLr_BANK 0x0002 -+#define PHY_MII_POWER_CTRLr_ADDR 0x18 -+/* 1000BASE-T/100BASE-TX/10BASE-T Misc Control Reg (ADDR 18h Shadow 111)*/ -+#define PHY_MII_MISC_CTRLr_FLAGS 0x00 -+#define PHY_MII_MISC_CTRLr_BANK 0x0007 -+#define PHY_MII_MISC_CTRLr_ADDR 0x18 -+/* Auxiliary 1000BASE-X Control Reg (ADDR 1ch shadow 11011) */ -+#define PHY_AUX_1000X_CTRLr_FLAGS 0x00 -+#define PHY_AUX_1000X_CTRLr_BANK 0x001B -+#define PHY_AUX_1000X_CTRLr_ADDRS 0x1c -+/* Mode Control Reg (ADDR 1ch shadow 11111) */ -+#define PHY_MODE_CTRLr_FLAGS 0x00 -+#define PHY_MODE_CTRLr_BANK 0x001F -+#define PHY_MODE_CTRLr_ADDR 0x1c -+ -+/* -+ * Primary SerDes Registers -+ */ -+/* 1000BASE-X MII Control Register (Addr 00h) */ -+#define PHY_1000X_MII_CTRLr_FLAGS SOC_PHY_REG_1000X -+#define PHY_1000X_MII_CTRLr_BANK 0x0000 -+#define PHY_1000X_MII_CTRLr_ADDR 0x00 -+ -+ -+/* MII Control Register: bit definitions */ -+#define MII_CTRL_FS_2500 (1 << 5) /* Force speed to 2500 Mbps */ -+#define MII_CTRL_SS_MSB (1 << 6) /* Speed select, MSb */ -+#define MII_CTRL_CST (1 << 7) /* Collision Signal test */ -+#define MII_CTRL_FD (1 << 8) /* Full Duplex */ -+#define MII_CTRL_RAN (1 << 9) /* Restart Autonegotiation */ -+#define MII_CTRL_IP (1 << 10) /* Isolate Phy */ -+#define MII_CTRL_PD (1 << 11) /* Power Down */ -+#define MII_CTRL_AE (1 << 12) /* Autonegotiation enable */ -+#define MII_CTRL_SS_LSB (1 << 13) /* Speed select, LSb */ -+#define MII_CTRL_LE (1 << 14) /* Loopback enable */ -+#define MII_CTRL_RESET (1 << 15) /* PHY reset */ -+ -+#define MII_CTRL_SS(_x) ((_x) & (MII_CTRL_SS_LSB|MII_CTRL_SS_MSB)) -+#define MII_CTRL_SS_10 0 -+#define MII_CTRL_SS_100 (MII_CTRL_SS_LSB) -+#define MII_CTRL_SS_1000 (MII_CTRL_SS_MSB) -+#define MII_CTRL_SS_INVALID (MII_CTRL_SS_LSB | MII_CTRL_SS_MSB) -+#define MII_CTRL_SS_MASK (MII_CTRL_SS_LSB | MII_CTRL_SS_MSB) -+ -+/* -+ * MII Status Register: See 802.3, 1998 pg 544 -+ */ -+#define MII_STAT_EXT (1 << 0) /* Extended Registers */ -+#define MII_STAT_JBBR (1 << 1) /* Jabber Detected */ -+#define MII_STAT_LA (1 << 2) /* Link Active */ -+#define MII_STAT_AN_CAP (1 << 3) /* Autoneg capable */ -+#define MII_STAT_RF (1 << 4) /* Remote Fault */ -+#define MII_STAT_AN_DONE (1 << 5) /* Autoneg complete */ -+#define MII_STAT_MF_PS (1 << 6) /* Preamble suppression */ -+#define MII_STAT_ES (1 << 8) /* Extended status (R15) */ -+#define MII_STAT_HD_100_T2 (1 << 9) /* Half duplex 100Mb/s supported */ -+#define MII_STAT_FD_100_T2 (1 << 10)/* Full duplex 100Mb/s supported */ -+#define MII_STAT_HD_10 (1 << 11)/* Half duplex 100Mb/s supported */ -+#define MII_STAT_FD_10 (1 << 12)/* Full duplex 100Mb/s supported */ -+#define MII_STAT_HD_100 (1 << 13)/* Half duplex 100Mb/s supported */ -+#define MII_STAT_FD_100 (1 << 14)/* Full duplex 100Mb/s supported */ -+#define MII_STAT_100_T4 (1 << 15)/* Full duplex 100Mb/s supported */ -+ -+/* -+ * MII Link Advertisment -+ */ -+#define MII_ANA_ASF (1 << 0)/* Advertise Selector Field */ -+#define MII_ANA_HD_10 (1 << 5)/* Half duplex 10Mb/s supported */ -+#define MII_ANA_FD_1000X (1 << 5)/* Full duplex for 1000BASE-X */ -+#define MII_ANA_FD_10 (1 << 6)/* Full duplex 10Mb/s supported */ -+#define MII_ANA_HD_1000X (1 << 6)/* Half duplex for 1000BASE-X */ -+#define MII_ANA_HD_100 (1 << 7)/* Half duplex 100Mb/s supported */ -+#define MII_ANA_1000X_PAUSE (1 << 7)/* Pause supported for 1000BASE-X */ -+#define MII_ANA_FD_100 (1 << 8)/* Full duplex 100Mb/s supported */ -+#define MII_ANA_1000X_ASYM_PAUSE (1 << 8)/* Asymmetric pause supported for 1000BASE-X */ -+#define MII_ANA_T4 (1 << 9)/* T4 */ -+#define MII_ANA_PAUSE (1 << 10)/* Pause supported */ -+#define MII_ANA_ASYM_PAUSE (1 << 11)/* Asymmetric pause supported */ -+#define MII_ANA_RF (1 << 13)/* Remote fault */ -+#define MII_ANA_NP (1 << 15)/* Next Page */ -+ -+#define MII_ANA_ASF_802_3 (1) /* 802.3 PHY */ -+ -+/* -+ * 1000Base-T Control Register -+ */ -+#define MII_GB_CTRL_MS_MAN (1 << 12) /* Manual Master/Slave mode */ -+#define MII_GB_CTRL_MS (1 << 11) /* Master/Slave negotiation mode */ -+#define MII_GB_CTRL_PT (1 << 10) /* Port type */ -+#define MII_GB_CTRL_ADV_1000FD (1 << 9) /* Advertise 1000Base-T FD */ -+#define MII_GB_CTRL_ADV_1000HD (1 << 8) /* Advertise 1000Base-T HD */ -+ -+/* -+ * 1000Base-T Status Register -+ */ -+#define MII_GB_STAT_MS_FAULT (1 << 15) /* Master/Slave Fault */ -+#define MII_GB_STAT_MS (1 << 14) /* Master/Slave, 1 == Master */ -+#define MII_GB_STAT_LRS (1 << 13) /* Local receiver status */ -+#define MII_GB_STAT_RRS (1 << 12) /* Remote receiver status */ -+#define MII_GB_STAT_LP_1000FD (1 << 11) /* Link partner 1000FD capable */ -+#define MII_GB_STAT_LP_1000HD (1 << 10) /* Link partner 1000HD capable */ -+#define MII_GB_STAT_IDE (0xff << 0) /* Idle error count */ -+ -+/* -+ * IEEE Extended Status Register -+ */ -+#define MII_ESR_1000_X_FD (1 << 15) /* 1000Base-T FD capable */ -+#define MII_ESR_1000_X_HD (1 << 14) /* 1000Base-T HD capable */ -+#define MII_ESR_1000_T_FD (1 << 13) /* 1000Base-T FD capable */ -+#define MII_ESR_1000_T_HD (1 << 12) /* 1000Base-T FD capable */ -+ -+/* MII Extended Control Register (BROADCOM) */ -+#define MII_ECR_FE (1 << 0) /* FIFO Elasticity */ -+#define MII_ECR_TLLM (1 << 1) /* Three link LED mode */ -+#define MII_ECR_ET_IPG (1 << 2) /* Extended XMIT IPG mode */ -+#define MII_ECR_FLED_OFF (1 << 3) /* Force LED off */ -+#define MII_ECR_FLED_ON (1 << 4) /* Force LED on */ -+#define MII_ECR_ELT (1 << 5) /* Enable LED traffic */ -+#define MII_ECR_RS (1 << 6) /* Reset Scrambler */ -+#define MII_ECR_BRSA (1 << 7) /* Bypass Receive Sym. align */ -+#define MII_ECR_BMLT3 (1 << 8) /* Bypass MLT3 Encoder/Decoder */ -+#define MII_ECR_BSD (1 << 9) /* Bypass Scramble/Descramble */ -+#define MII_ECR_B4B5B (1 << 10) /* Bypass 4B/5B Encode/Decode */ -+#define MII_ECR_FI (1 << 11) /* Force Interrupt */ -+#define MII_ECR_ID (1 << 12) /* Interrupt Disable */ -+#define MII_ECR_TD (1 << 13) /* XMIT Disable */ -+#define MII_ECR_DAMC (1 << 14) /* DIsable Auto-MDI Crossover */ -+#define MII_ECR_10B (1 << 15) /* 1 == 10B, 0 == GMII */ -+ -+/* MISC Control Register (Addr 18h, Shadow Value 111) */ -+#define MII_FORCED_AUTO_MDIX (1 << 9) /* 1 == AUTO-MDIX enabled when AN disabled */ -+#endif /* _bcm_iproc_phy_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5221.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5221.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5221.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5221.h 2017-11-09 17:53:43.932294000 +0800 -@@ -0,0 +1,45 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * These routines provide access to the external phy -+ * -+ */ -+ -+#ifndef _bcm_iproc_phy5221_h_ -+#define _bcm_iproc_phy5221_h_ -+ -+ -+/* ---- Include Files ---------------------------------------------------- */ -+#include -+ -+#define PHY_AUX_MULTIPLE_PHYr_BANK 0x0000 -+#define PHY_AUX_MULTIPLE_PHYr_ADDR 0x1e -+ -+#define PHY522X_SUPER_ISOLATE_MODE (1<<3) -+ -+/* ---- External Function Prototypes ------------------------------------- */ -+ -+extern int phy5221_wr_reg(uint eth_num, uint phyaddr, uint16 reg_bank, -+ uint8 reg_addr, uint16 *data); -+extern int phy5221_rd_reg(uint eth_num, uint phyaddr, uint16 reg_bank, -+ uint8 reg_addr, uint16 *data); -+extern int phy5221_mod_reg(uint eth_num, uint phyaddr, uint16 reg_bank, -+ uint8 reg_addr, uint16 data, uint16 mask); -+extern int phy5221_init(uint eth_num, uint phyaddr); -+extern int phy5221_link_get(uint eth_num, uint phyaddr, int *link); -+extern int phy5221_enable_set(uint eth_num, uint phyaddr, int enable); -+extern int phy5221_speed_get(uint eth_num, uint phyaddr, int *speed, int *duplex); -+ -+#endif /* _bcm_iproc_phy5221_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5461s.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5461s.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5461s.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5461s.h 2017-11-09 17:53:43.933291000 +0800 -@@ -0,0 +1,46 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * These routines provide access to the external phy -+ * -+ */ -+ -+#ifndef _bcm_iproc_phy5461s_h_ -+#define _bcm_iproc_phy5461s_h_ -+ -+ -+/* ---- Include Files ---------------------------------------------------- */ -+#include -+ -+/* Indirect PHY register address flags */ -+#define SOC_PHY_REG_RESERVE_ACCESS 0x20000000 -+#define SOC_PHY_REG_1000X 0x40000000 -+#define SOC_PHY_REG_INDIRECT 0x80000000 -+#define _SOC_PHY_REG_DIRECT ((SOC_PHY_REG_1000X << 1) | (SOC_PHY_REG_1000X >> 1)) -+ -+/* ---- External Function Prototypes ------------------------------------- */ -+ -+extern int phy5461_wr_reg(uint eth_num, uint phyaddr, uint32 flags, uint16 reg_bank, -+ uint8 reg_addr, uint16 *data); -+extern int phy5461_rd_reg(uint eth_num, uint phyaddr, uint32 flags, uint16 reg_bank, -+ uint8 reg_addr, uint16 *data); -+extern int phy5461_mod_reg(uint eth_num, uint phyaddr, uint32 flags, uint16 reg_bank, -+ uint8 reg_addr, uint16 data, uint16 mask); -+extern int phy5461_init(uint eth_num, uint phyaddr); -+extern int phy5461_link_get(uint eth_num, uint phyaddr, int *link); -+extern int phy5461_enable_set(uint eth_num, uint phyaddr, int enable); -+extern int phy5461_speed_get(uint eth_num, uint phyaddr, int *speed, int *duplex); -+ -+#endif /* _bcm_iproc_phy5461s_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5481.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5481.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5481.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_phy5481.h 2017-11-09 17:53:43.933313000 +0800 -@@ -0,0 +1,45 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * These routines provide access to the external phy -+ * -+ */ -+ -+#ifndef _bcm_iproc_phy5481_h_ -+#define _bcm_iproc_phy5481_h_ -+ -+ -+/* ---- Include Files ---------------------------------------------------- */ -+#include -+ -+// #define PHY_AUX_MULTIPLE_PHYr_BANK 0x0000 -+// #define PHY_AUX_MULTIPLE_PHYr_ADDR 0x1e -+ -+#define PHY5481_SUPER_ISOLATE_MODE (1U<<5) -+ -+/* ---- External Function Prototypes ------------------------------------- */ -+ -+extern int phy5481_wr_reg(uint eth_num, uint phyaddr, uint16 reg_bank, -+ uint8 reg_addr, uint16 *data); -+extern int phy5481_rd_reg(uint eth_num, uint phyaddr, uint16 reg_bank, -+ uint8 reg_addr, uint16 *data); -+extern int phy5481_mod_reg(uint eth_num, uint phyaddr, uint16 reg_bank, -+ uint8 reg_addr, uint16 data, uint16 mask); -+extern int phy5481_init(uint eth_num, uint phyaddr); -+extern int phy5481_link_get(uint eth_num, uint phyaddr, int *link); -+extern int phy5481_enable_set(uint eth_num, uint phyaddr, int enable); -+extern int phy5481_speed_get(uint eth_num, uint phyaddr, int *speed, int *duplex); -+ -+#endif /* _bcm_iproc_phy5481_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_serdes.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_serdes.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_serdes.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_serdes.h 2017-11-09 17:53:43.934297000 +0800 -@@ -0,0 +1,78 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * These routines provide access to the serdes -+ * -+ */ -+ -+#ifndef _bcm_iproc_serdes_h_ -+#define _bcm_iproc_serdes_h_ -+ -+ -+/* ---- Include Files ---------------------------------------------------- */ -+#include -+ -+#define PHY_REG_BLK_ADDR 0x001f /* GLOBAL BLOCK ADDRESS REGISTER */ -+ -+/* -+ * MII Link Advertisment (Clause 37) -+ */ -+#define MII_ANA_C37_NP (1 << 15) /* Next Page */ -+#define MII_ANA_C37_RF_OK (0 << 12) /* No error, link OK */ -+#define MII_ANA_C37_RF_LINK_FAIL (1 << 12) /* Offline */ -+#define MII_ANA_C37_RF_OFFLINE (2 << 12) /* Link failure */ -+#define MII_ANA_C37_RF_AN_ERR (3 << 12) /* Auto-Negotiation Error */ -+#define MII_ANA_C37_PAUSE (1 << 7) /* Symmetric Pause */ -+#define MII_ANA_C37_ASYM_PAUSE (1 << 8) /* Asymmetric Pause */ -+#define MII_ANA_C37_HD (1 << 6) /* Half duplex */ -+#define MII_ANA_C37_FD (1 << 5) /* Full duplex */ -+ -+/* MII Control Register: bit definitions */ -+ -+#define MII_CTRL_FS_2500 (1 << 5) /* Force speed to 2500 Mbps */ -+#define MII_CTRL_SS_MSB (1 << 6) /* Speed select, MSb */ -+#define MII_CTRL_CST (1 << 7) /* Collision Signal test */ -+#define MII_CTRL_FD (1 << 8) /* Full Duplex */ -+#define MII_CTRL_RAN (1 << 9) /* Restart Autonegotiation */ -+#define MII_CTRL_IP (1 << 10) /* Isolate Phy */ -+#define MII_CTRL_PD (1 << 11) /* Power Down */ -+#define MII_CTRL_AE (1 << 12) /* Autonegotiation enable */ -+#define MII_CTRL_SS_LSB (1 << 13) /* Speed select, LSb */ -+#define MII_CTRL_LE (1 << 14) /* Loopback enable */ -+#define MII_CTRL_RESET (1 << 15) /* PHY reset */ -+ -+#define MII_CTRL_SS(_x) ((_x) & (MII_CTRL_SS_LSB|MII_CTRL_SS_MSB)) -+#define MII_CTRL_SS_10 0 -+#define MII_CTRL_SS_100 (MII_CTRL_SS_LSB) -+#define MII_CTRL_SS_1000 (MII_CTRL_SS_MSB) -+#define MII_CTRL_SS_INVALID (MII_CTRL_SS_LSB | MII_CTRL_SS_MSB) -+#define MII_CTRL_SS_MASK (MII_CTRL_SS_LSB | MII_CTRL_SS_MSB) -+ -+/* ---- External Function Prototypes ------------------------------------- */ -+ -+extern void serdes_set_blk(uint eth_num, uint phyaddr, uint blk); -+extern void serdes_wr_reg(uint eth_num, uint phyaddr, uint reg, uint data); -+extern uint16 serdes_rd_reg(uint eth_num, uint phyaddr, uint reg); -+extern uint16 serdes_get_id(uint eth_num, uint phyaddr, uint off); -+extern void serdes_reset(uint eth_num, uint phyaddr); -+extern int serdes_reset_core(uint eth_num, uint phyaddr); -+extern int serdes_start_pll(uint eth_num, uint phyaddr); -+extern int serdes_init(uint eth_num, uint phyaddr); -+#if defined(CONFIG_SERDES_ASYMMETRIC_MODE) -+extern int serdes_speeddpx_set(uint eth_num, uint phyaddr, int speed, int fulldpx); -+extern int serdes_set_asym_mode(uint eth_num, uint phyaddr); -+#endif /* (defined(CONFIG_SERDES_ASYMMETRIC_MODE)) */ -+ -+#endif /* _bcm_iproc_serdes_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_serdes_def.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_serdes_def.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_serdes_def.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmiproc_serdes_def.h 2017-11-09 17:53:43.935301000 +0800 -@@ -0,0 +1,328 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * These are serdes defines -+ * -+ */ -+ -+#ifndef _PHY_XGXS16G_H_ -+#define _PHY_XGXS16G_H_ -+ -+/* macros */ -+ -+/* Macros ONLY used after initialization */ -+#define XGXS16G_2p5G_ID(id2) ((id2 & 0xff) == 0xf) -+ -+ -+/****************************************************************************/ -+/***** Starting below is auto-generated register macros from RDB files *****/ -+/****************************************************************************/ -+ -+/**************************************************************************** -+ * Core Enums. -+ ***************************************************************************/ -+ -+#define XGXS16G_IEEE0BLK_IEEECONTROL0r 0x00000000 -+#define XGXS16G_XGXSBLK0_XGXSCONTROLr 0x00008000 -+#define XGXS16G_XGXSBLK0_XGXSSTATUSr 0x00008001 -+#define XGXS16G_XGXSBLK0_MMDSELECTr 0x0000800d -+#define XGXS16G_XGXSBLK0_MISCCONTROL1r 0x0000800e -+#define XGXS16G_XGXSBLK1_LANECTRL0r 0x00008015 -+#define XGXS16G_XGXSBLK1_LANECTRL1r 0x00008016 -+#define XGXS16G_XGXSBLK1_LANECTRL3r 0x00008018 -+#define XGXS16G_TX0_TX_ACONTROL0r 0x00008061 -+#define XGXS16G_RX0_RX_CONTROLr 0x000080b1 -+#define XGXS16G_AN73_PDET_PARDET10GCONTROLr 0x00008131 -+#define XGXS16G_XGXSBLK7_EEECONTROLr 0x00008150 -+#define XGXS16G_TX_LN_SWAP1r 0x00008169 -+#define XGXS16G_SERDESDIGITAL_CONTROL1000X1r 0x00008300 -+#define XGXS16G_SERDESDIGITAL_CONTROL1000X2r 0x00008301 -+#define XGXS16G_SERDESDIGITAL_CONTROL1000X3r 0x00008302 -+#define XGXS16G_SERDESDIGITAL_STATUS1000X1r 0x00008304 -+#define XGXS16G_SERDESDIGITAL_MISC1r 0x00008308 -+#define XGXS16G_SERDESID_SERDESID0r 0x00008310 -+#define XGXS16G_SERDESID_SERDESID1r 0x00008311 -+#define XGXS16G_SERDESID_SERDESID2r 0x00008312 -+#define XGXS16G_SERDESID_SERDESID3r 0x00008313 -+#define XGXS16G_REMOTEPHY_MISC3r 0x0000833c -+#define XGXS16G_REMOTEPHY_MISC5r 0x0000833e -+#define XGXS16G_BAM_NEXTPAGE_MP5_NEXTPAGECTRLr 0x00008350 -+#define XGXS16G_BAM_NEXTPAGE_UD_FIELDr 0x00008357 -+#define XGXS16G_COMBO_IEEE0_MIICNTLr 0x0000ffe0 -+#define XGXS16G_COMBO_IEEE0_AUTONEGADVr 0x0000ffe4 -+ -+#define WC40_DIGITAL4_MISC3r 0x0000833c -+ -+/* Digital4 :: Misc3 :: laneDisable [06:06] */ -+#define DIGITAL4_MISC3_LANEDISABLE_MASK 0x0040 -+#define DIGITAL4_MISC3_LANEDISABLE_ALIGN 0 -+#define DIGITAL4_MISC3_LANEDISABLE_BITS 1 -+#define DIGITAL4_MISC3_LANEDISABLE_SHIFT 6 -+ -+ -+/**************************************************************************** -+ * XGXS16G_IEEE_ieee0Blk -+ ***************************************************************************/ -+/**************************************************************************** -+ * ieee0Blk :: ieeeControl0 -+ ***************************************************************************/ -+/* ieee0Blk :: ieeeControl0 :: rst_hw [15:15] */ -+#define IEEE0BLK_IEEECONTROL0_RST_HW_MASK 0x8000 -+#define IEEE0BLK_IEEECONTROL0_RST_HW_ALIGN 0 -+#define IEEE0BLK_IEEECONTROL0_RST_HW_BITS 1 -+#define IEEE0BLK_IEEECONTROL0_RST_HW_SHIFT 15 -+ -+/* ieee0Blk :: ieeeControl0 :: gloopback [14:14] */ -+#define IEEE0BLK_IEEECONTROL0_GLOOPBACK_MASK 0x4000 -+#define IEEE0BLK_IEEECONTROL0_GLOOPBACK_ALIGN 0 -+#define IEEE0BLK_IEEECONTROL0_GLOOPBACK_BITS 1 -+#define IEEE0BLK_IEEECONTROL0_GLOOPBACK_SHIFT 14 -+ -+ -+/**************************************************************************** -+ * XGXS16G_USER_XgxsBlk0 -+ ***************************************************************************/ -+/**************************************************************************** -+ * XgxsBlk0 :: xgxsControl -+ ***************************************************************************/ -+/* XgxsBlk0 :: xgxsControl :: start_sequencer [13:13] */ -+#define XGXSBLK0_XGXSCONTROL_START_SEQUENCER_MASK 0x2000 -+#define XGXSBLK0_XGXSCONTROL_START_SEQUENCER_ALIGN 0 -+#define XGXSBLK0_XGXSCONTROL_START_SEQUENCER_BITS 1 -+#define XGXSBLK0_XGXSCONTROL_START_SEQUENCER_SHIFT 13 -+ -+/* XgxsBlk0 :: xgxsControl :: mode_10g [11:08] */ -+#define XGXSBLK0_XGXSCONTROL_MODE_10G_MASK 0x0f00 -+#define XGXSBLK0_XGXSCONTROL_MODE_10G_ALIGN 0 -+#define XGXSBLK0_XGXSCONTROL_MODE_10G_BITS 4 -+#define XGXSBLK0_XGXSCONTROL_MODE_10G_SHIFT 8 -+#define XGXSBLK0_XGXSCONTROL_MODE_10G_XGXS 0 -+#define XGXSBLK0_XGXSCONTROL_MODE_10G_XGXS_noCC 1 -+#define XGXSBLK0_XGXSCONTROL_MODE_10G_IndLane 6 -+#define XGXSBLK0_XGXSCONTROL_MODE_10G_XGXS_noLss 8 -+#define XGXSBLK0_XGXSCONTROL_MODE_10G_XGXS_noLss_noCC 9 -+#define XGXSBLK0_XGXSCONTROL_MODE_10G_protBypass 10 -+#define XGXSBLK0_XGXSCONTROL_MODE_10G_protBypass_noDsk 11 -+#define XGXSBLK0_XGXSCONTROL_MODE_10G_ComboCoreMode 12 -+#define XGXSBLK0_XGXSCONTROL_MODE_10G_ClocksOff 15 -+ -+/* XgxsBlk0 :: xgxsControl :: hstl [05:05] */ -+#define XGXSBLK0_XGXSCONTROL_HSTL_MASK 0x0020 -+#define XGXSBLK0_XGXSCONTROL_HSTL_ALIGN 0 -+#define XGXSBLK0_XGXSCONTROL_HSTL_BITS 1 -+#define XGXSBLK0_XGXSCONTROL_HSTL_SHIFT 5 -+ -+/* XgxsBlk0 :: xgxsControl :: cdet_en [03:03] */ -+#define XGXSBLK0_XGXSCONTROL_CDET_EN_MASK 0x0008 -+#define XGXSBLK0_XGXSCONTROL_CDET_EN_ALIGN 0 -+#define XGXSBLK0_XGXSCONTROL_CDET_EN_BITS 1 -+#define XGXSBLK0_XGXSCONTROL_CDET_EN_SHIFT 3 -+ -+/* XgxsBlk0 :: xgxsControl :: eden [02:02] */ -+#define XGXSBLK0_XGXSCONTROL_EDEN_MASK 0x0004 -+#define XGXSBLK0_XGXSCONTROL_EDEN_ALIGN 0 -+#define XGXSBLK0_XGXSCONTROL_EDEN_BITS 1 -+#define XGXSBLK0_XGXSCONTROL_EDEN_SHIFT 2 -+ -+/* XgxsBlk0 :: xgxsControl :: afrst_en [01:01] */ -+#define XGXSBLK0_XGXSCONTROL_AFRST_EN_MASK 0x0002 -+#define XGXSBLK0_XGXSCONTROL_AFRST_EN_ALIGN 0 -+#define XGXSBLK0_XGXSCONTROL_AFRST_EN_BITS 1 -+#define XGXSBLK0_XGXSCONTROL_AFRST_EN_SHIFT 1 -+ -+/* XgxsBlk0 :: xgxsControl :: txcko_div [00:00] */ -+#define XGXSBLK0_XGXSCONTROL_TXCKO_DIV_MASK 0x0001 -+#define XGXSBLK0_XGXSCONTROL_TXCKO_DIV_ALIGN 0 -+#define XGXSBLK0_XGXSCONTROL_TXCKO_DIV_BITS 1 -+#define XGXSBLK0_XGXSCONTROL_TXCKO_DIV_SHIFT 0 -+ -+ -+/**************************************************************************** -+ * XgxsBlk0 :: xgxsStatus -+ ***************************************************************************/ -+/* XgxsBlk0 :: xgxsStatus :: txpll_lock [11:11] */ -+#define XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_MASK 0x0800 -+#define XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_ALIGN 0 -+#define XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_BITS 1 -+#define XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_SHIFT 11 -+ -+ -+/**************************************************************************** -+ * XgxsBlk0 :: miscControl1 -+ ***************************************************************************/ -+/* XgxsBlk0 :: miscControl1 :: PCS_dev_en_override [10:10] */ -+#define XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_MASK 0x0400 -+#define XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_ALIGN 0 -+#define XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_BITS 1 -+#define XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_SHIFT 10 -+ -+/* XgxsBlk0 :: miscControl1 :: PMD_dev_en_override [09:09] */ -+#define XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_MASK 0x0200 -+#define XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_ALIGN 0 -+#define XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_BITS 1 -+#define XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_SHIFT 9 -+ -+/* XgxsBlk0 :: miscControl1 :: ieee_blksel_autodet [01:01] */ -+#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_MASK 0x0002 -+#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_ALIGN 0 -+#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_BITS 1 -+#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_SHIFT 1 -+ -+/* XgxsBlk0 :: miscControl1 :: ieee_blksel_val [00:00] */ -+#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_MASK 0x0001 -+#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_ALIGN 0 -+#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_BITS 1 -+#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_SHIFT 0 -+ -+ -+/**************************************************************************** -+ * XGXS16G_USER_XgxsBlk1 -+ ***************************************************************************/ -+/**************************************************************************** -+ * XgxsBlk1 :: laneCtrl0 -+ ***************************************************************************/ -+/* XgxsBlk1 :: laneCtrl0 :: cl36_pcs_en_rx [07:04] */ -+#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_MASK 0x00f0 -+#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_ALIGN 0 -+#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_BITS 4 -+#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_SHIFT 4 -+ -+/* XgxsBlk1 :: laneCtrl0 :: cl36_pcs_en_tx [03:00] */ -+#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_MASK 0x000f -+#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_ALIGN 0 -+#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_BITS 4 -+#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_SHIFT 0 -+ -+ -+/**************************************************************************** -+ * XGXS16G_USER_TX0 -+ ***************************************************************************/ -+/**************************************************************************** -+ * TX0 :: Tx_AControl0 -+ ***************************************************************************/ -+/* TX0 :: Tx_AControl0 :: txpol_flip [05:05] */ -+#define TX0_TX_ACONTROL0_TXPOL_FLIP_MASK 0x0020 -+#define TX0_TX_ACONTROL0_TXPOL_FLIP_ALIGN 0 -+#define TX0_TX_ACONTROL0_TXPOL_FLIP_BITS 1 -+#define TX0_TX_ACONTROL0_TXPOL_FLIP_SHIFT 5 -+ -+ -+/**************************************************************************** -+ * XGXS16G_USER_dsc_2_0 -+ ***************************************************************************/ -+/**************************************************************************** -+ * dsc_2_0 :: dsc_ctrl0 -+ ***************************************************************************/ -+/* dsc_2_0 :: dsc_ctrl0 :: rxSeqStart [15:15] */ -+#define DSC_2_0_DSC_CTRL0_RXSEQSTART_MASK 0x8000 -+#define DSC_2_0_DSC_CTRL0_RXSEQSTART_ALIGN 0 -+#define DSC_2_0_DSC_CTRL0_RXSEQSTART_BITS 1 -+#define DSC_2_0_DSC_CTRL0_RXSEQSTART_SHIFT 15 -+ -+ -+/**************************************************************************** -+ * XGXS16G_USER_SerdesDigital -+ ***************************************************************************/ -+/**************************************************************************** -+ * SerdesDigital :: Control1000X1 -+ ***************************************************************************/ -+/* SerdesDigital :: Control1000X1 :: crc_checker_disable [07:07] */ -+#define SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_MASK 0x0080 -+#define SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_ALIGN 0 -+#define SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_BITS 1 -+#define SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_SHIFT 7 -+ -+/* SerdesDigital :: Control1000X1 :: disable_pll_pwrdwn [06:06] */ -+#define SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_MASK 0x0040 -+#define SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_ALIGN 0 -+#define SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_BITS 1 -+#define SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_SHIFT 6 -+ -+/* SerdesDigital :: Control1000X1 :: fiber_mode_1000X [00:00] */ -+#define SERDESDIGITAL_CONTROL1000X1_FIBER_MODE_1000X_MASK 0x0001 -+#define SERDESDIGITAL_CONTROL1000X1_FIBER_MODE_1000X_ALIGN 0 -+#define SERDESDIGITAL_CONTROL1000X1_FIBER_MODE_1000X_BITS 1 -+#define SERDESDIGITAL_CONTROL1000X1_FIBER_MODE_1000X_SHIFT 0 -+ -+/**************************************************************************** -+ * SerdesDigital :: Control1000X3 -+ ***************************************************************************/ -+/* SerdesDigital :: Control1000X3 :: fifo_elasicity_tx_rx [02:01] */ -+#define SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_MASK 0x0006 -+#define SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_ALIGN 0 -+#define SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_BITS 2 -+#define SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_SHIFT 1 -+ -+/* SerdesDigital :: Control1000X3 :: tx_fifo_rst [00:00] */ -+#define SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_MASK 0x0001 -+#define SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_ALIGN 0 -+#define SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_BITS 1 -+#define SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_SHIFT 0 -+ -+/**************************************************************************** -+ * SerdesDigital :: Status1000X1 -+ ***************************************************************************/ -+/* SerdesDigital :: Status1000X1 :: speed_status [04:03] */ -+#define SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_MASK 0x0018 -+#define SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_ALIGN 0 -+#define SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_BITS 2 -+#define SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_SHIFT 3 -+ -+/**************************************************************************** -+ * SerdesDigital :: Misc1 -+ ***************************************************************************/ -+/* SerdesDigital :: Misc1 :: refclk_sel [15:13] */ -+#define SERDESDIGITAL_MISC1_REFCLK_SEL_MASK 0xe000 -+#define SERDESDIGITAL_MISC1_REFCLK_SEL_ALIGN 0 -+#define SERDESDIGITAL_MISC1_REFCLK_SEL_BITS 3 -+#define SERDESDIGITAL_MISC1_REFCLK_SEL_SHIFT 13 -+#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_25MHz 0 -+#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_100MHz 1 -+#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_125MHz 2 -+#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_156p25MHz 3 -+#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_187p5MHz 4 -+#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_161p25Mhz 5 -+#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_50Mhz 6 -+#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_106p25Mhz 7 -+ -+/* SerdesDigital :: Misc1 :: force_speed_sel [04:04] */ -+#define SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_MASK 0x0010 -+#define SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_ALIGN 0 -+#define SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_BITS 1 -+#define SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_SHIFT 4 -+ -+/* SerdesDigital :: Misc1 :: force_speed [03:00] */ -+#define SERDESDIGITAL_MISC1_FORCE_SPEED_MASK 0x000f -+#define SERDESDIGITAL_MISC1_FORCE_SPEED_ALIGN 0 -+#define SERDESDIGITAL_MISC1_FORCE_SPEED_BITS 4 -+#define SERDESDIGITAL_MISC1_FORCE_SPEED_SHIFT 0 -+ -+ -+/**************************************************************************** -+ * CL73_UserB0 :: CL73_BAMCtrl1 -+ ***************************************************************************/ -+/* CL73_UserB0 :: CL73_BAMCtrl1 :: CL73_bamEn [15:15] */ -+#define CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_MASK 0x8000 -+#define CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_ALIGN 0 -+#define CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_BITS 1 -+#define CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_SHIFT 15 -+ -+ -+/**************************************************************************** -+ * Datatype Definitions. -+ ***************************************************************************/ -+#endif /* _PHY_XGXS16G_H_ */ -+ -+/* End of File */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmnvram.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmnvram.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmnvram.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmnvram.h 2017-11-09 17:53:43.936309000 +0800 -@@ -0,0 +1,290 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * NVRAM variable manipulation -+ * -+ * $Id: bcmnvram.h 325984 2012-04-05 08:51:37Z $ -+ */ -+ -+#ifndef _bcmnvram_h_ -+#define _bcmnvram_h_ -+ -+#ifndef _LANGUAGE_ASSEMBLY -+ -+#include -+#include -+#include -+ -+struct nvram_header { -+ uint32 magic; -+ uint32 len; -+ uint32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ -+ uint32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ -+ uint32 config_ncdl; /* ncdl values for memc */ -+}; -+ -+struct nvram_otphdr { -+ struct nvram_header nvh; -+ uint16 flags_swmacm_gpio_phya; /* otp flags, switch/gmac mode, gpio, phyaddr */ -+ struct ether_addr mac; -+ uint32 clkfreq; -+}; -+ -+struct nvram_tuple { -+ char *name; -+ char *value; -+ struct nvram_tuple *next; -+}; -+ -+/* -+ * Get default value for an NVRAM variable -+ */ -+extern char *nvram_default_get(const char *name); -+ -+/* -+ * Initialize NVRAM access. May be unnecessary or undefined on certain -+ * platforms. -+ */ -+extern int nvram_init(void *sih); -+ -+/* -+ * Append a chunk of nvram variables to the global list -+ */ -+extern int nvram_append(void *si, char *vars, uint varsz); -+ -+extern void nvram_get_global_vars(char **varlst, uint *varsz); -+ -+ -+/* -+ * Check for reset button press for restoring factory defaults. -+ */ -+extern int nvram_reset(void *sih); -+ -+/* -+ * Disable NVRAM access. May be unnecessary or undefined on certain -+ * platforms. -+ */ -+extern void nvram_exit(void *sih); -+ -+/* -+ * Get the value of an NVRAM variable. The pointer returned may be -+ * invalid after a set. -+ * @param name name of variable to get -+ * @return value of variable or NULL if undefined -+ */ -+extern char * nvram_get(const char *name); -+ -+/* -+ * Read the reset GPIO value from the nvram and set the GPIO -+ * as input -+ */ -+extern int BCMINITFN(nvram_resetgpio_init)(void *sih); -+ -+/* -+ * Get the value of an NVRAM variable. -+ * @param name name of variable to get -+ * @return value of variable or NUL if undefined -+ */ -+static INLINE char * -+nvram_safe_get(const char *name) -+{ -+ char *p = nvram_get(name); -+ return p ? p : ""; -+} -+ -+/* -+ * Match an NVRAM variable. -+ * @param name name of variable to match -+ * @param match value to compare against value of variable -+ * @return TRUE if variable is defined and its value is string equal -+ * to match or FALSE otherwise -+ */ -+static INLINE int -+nvram_match(char *name, char *match) -+{ -+ const char *value = nvram_get(name); -+ return (value && !strcmp(value, match)); -+} -+ -+/* -+ * Inversely match an NVRAM variable. -+ * @param name name of variable to match -+ * @param match value to compare against value of variable -+ * @return TRUE if variable is defined and its value is not string -+ * equal to invmatch or FALSE otherwise -+ */ -+static INLINE int -+nvram_invmatch(char *name, char *invmatch) -+{ -+ const char *value = nvram_get(name); -+ return (value && strcmp(value, invmatch)); -+} -+ -+/* -+ * Set the value of an NVRAM variable. The name and value strings are -+ * copied into private storage. Pointers to previously set values -+ * may become invalid. The new value may be immediately -+ * retrieved but will not be permanently stored until a commit. -+ * @param name name of variable to set -+ * @param value value of variable -+ * @return 0 on success and errno on failure -+ */ -+extern int nvram_set(const char *name, const char *value); -+ -+/* -+ * Unset an NVRAM variable. Pointers to previously set values -+ * remain valid until a set. -+ * @param name name of variable to unset -+ * @return 0 on success and errno on failure -+ * NOTE: use nvram_commit to commit this change to flash. -+ */ -+extern int nvram_unset(const char *name); -+ -+/* -+ * NVRAM is based of FLASH or OTP. -+ * @return From FLASH: TRUE -+ * From OTP: FALSE -+ */ -+extern bool nvram_inotp(void); -+ -+/* -+ * Commit NVRAM header to OTP. All pointers to values -+ * may be invalid after a commit. -+ * NVRAM values are undefined after a commit. -+ * @return 0 on success and errno on failure -+ */ -+extern int nvram_otpcommit(void *sih); -+ -+/* -+ * Commit NVRAM variables to permanent storage. All pointers to values -+ * may be invalid after a commit. -+ * NVRAM values are undefined after a commit. -+ * @return 0 on success and errno on failure -+ */ -+extern int nvram_commit(void); -+ -+/* -+ * Get all NVRAM variables (format name=value\0 ... \0\0). -+ * @param buf buffer to store variables -+ * @param count size of buffer in bytes -+ * @return 0 on success and errno on failure -+ */ -+extern int nvram_getall(char *nvram_buf, int count); -+ -+/* -+ * returns the crc value of the nvram -+ * @param nvh nvram header pointer -+ */ -+uint8 nvram_calc_crc(struct nvram_header * nvh); -+ -+#endif /* _LANGUAGE_ASSEMBLY */ -+ -+/* The NVRAM version number stored as an NVRAM variable */ -+#define NVRAM_SOFTWARE_VERSION "1" -+ -+#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ -+#define NVRAM_CLEAR_MAGIC 0x0 -+#define NVRAM_INVALID_MAGIC 0xFFFFFFFF -+#define NVRAM_VERSION 1 -+#define NVRAM_HEADER_SIZE 20 -+#define NVRAM_SPACE 0x8000 -+#define ENVRAM_SPACE 0x1000 -+ -+#define NVRAM_MAX_VALUE_LEN 255 -+#define NVRAM_MAX_PARAM_LEN 64 -+ -+#define NVRAM_CRC_START_POSITION 9 /* magic, len, crc8 to be skipped */ -+#define NVRAM_CRC_VER_MASK 0xffffff00 /* for crc_ver_init */ -+ -+/* Incase of nvram header(in OTP), we save 16bit after nvram header -+ * o 0:0 Switch Present -+ * o 1:4 Switch and gmac mode -+ * o 5:10 robo reset GPIO pin number -+ * o 11:15 phyaddr -+ */ -+#define OTPNVRAM_SWITCH_PRESENT 0x1 -+ -+#define OTPNVRAM_FLAGS_MASK 0x1 -+#define OTPNVRAM_SMACMODE_MASK 0x1e -+#define OTPNVRAM_GPIO_MASK 0x7e0 -+#define OTPNVRAM_PHYADDR_MASK 0xf800 -+ -+#define OTPNVRAM_SMACMODE_SHIFT 1 -+#define OTPNVRAM_GPIO_SHIFT 5 -+#define OTPNVRAM_PHYADDR_SHIFT 11 -+ -+/* clkfreq is saved in following format in OTP nvram data -+ * 9:0 pci clock -+ * 20:10 si clock -+ * 31:21 mips clock -+ */ -+ -+#define NVRAM_PCI_CLKMASK 0x3ff -+#define NVRAM_SI_CLKMASK 0x1ffc00 -+#define NVRAM_SI_CLKSHIFT 10 -+#define NVRAM_CPUCLK_SHIFT 21 -+ -+/* Offsets to embedded nvram area */ -+#define NVRAM_START_COMPRESSED 0x400 -+#define NVRAM_START 0x1000 -+ -+#define BCM_JUMBO_NVRAM_DELIMIT '\n' -+#define BCM_JUMBO_START "Broadcom Jumbo Nvram file" -+ -+#if (defined(FAILSAFE_UPGRADE) || defined(CONFIG_FAILSAFE_UPGRADE) || \ -+ defined(__CONFIG_FAILSAFE_UPGRADE_SUPPORT__)) -+#define IMAGE_SIZE "image_size" -+#define BOOTPARTITION "bootpartition" -+#define IMAGE_BOOT BOOTPARTITION -+#define PARTIALBOOTS "partialboots" -+#define MAXPARTIALBOOTS "maxpartialboots" -+#define IMAGE_1ST_FLASH_TRX "flash0.trx" -+#define IMAGE_1ST_FLASH_OS "flash0.os" -+#define IMAGE_2ND_FLASH_TRX "flash0.trx2" -+#define IMAGE_2ND_FLASH_OS "flash0.os2" -+#define IMAGE_FIRST_OFFSET "image_first_offset" -+#define IMAGE_SECOND_OFFSET "image_second_offset" -+#define LINUX_FIRST "linux" -+#define LINUX_SECOND "linux2" -+#endif -+ -+#if (defined(DUAL_IMAGE) || defined(CONFIG_DUAL_IMAGE) || \ -+ defined(__CONFIG_DUAL_IMAGE_FLASH_SUPPORT__)) -+/* Shared by all: CFE, Linux Kernel, and Ap */ -+#define IMAGE_BOOT "image_boot" -+#define BOOTPARTITION IMAGE_BOOT -+/* CFE variables */ -+#define IMAGE_1ST_FLASH_TRX "flash0.trx" -+#define IMAGE_1ST_FLASH_OS "flash0.os" -+#define IMAGE_2ND_FLASH_TRX "flash0.trx2" -+#define IMAGE_2ND_FLASH_OS "flash0.os2" -+#define IMAGE_SIZE "image_size" -+ -+/* CFE and Linux Kernel shared variables */ -+#define IMAGE_FIRST_OFFSET "image_first_offset" -+#define IMAGE_SECOND_OFFSET "image_second_offset" -+ -+/* Linux application variables */ -+#define LINUX_FIRST "linux" -+#define LINUX_SECOND "linux2" -+#define POLICY_TOGGLE "toggle" -+#define LINUX_PART_TO_FLASH "linux_to_flash" -+#define LINUX_FLASH_POLICY "linux_flash_policy" -+ -+#endif /* defined(DUAL_IMAGE||CONFIG_DUAL_IMAGE)||__CONFIG_DUAL_IMAGE_FLASH_SUPPORT__ */ -+ -+int nvram_env_gmac_name(int gmac, char *name); -+ -+#endif /* _bcmnvram_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmparams.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmparams.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmparams.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmparams.h 2017-11-09 17:53:43.937301000 +0800 -@@ -0,0 +1,32 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Misc system wide parameters. -+ * -+ * $Id: bcmparams.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _bcmparams_h_ -+#define _bcmparams_h_ -+ -+#define VLAN_MAXVID 15 /* Max. VLAN ID supported/allowed */ -+ -+#define VLAN_NUMPRIS 8 /* # of prio, start from 0 */ -+ -+#define DEV_NUMIFS 16 /* Max. # of devices/interfaces supported */ -+ -+#define WL_MAXBSSCFG 16 /* maximum number of BSS Configs we can configure */ -+ -+#endif -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmperf.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmperf.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmperf.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmperf.h 2017-11-09 17:53:43.938295000 +0800 -@@ -0,0 +1,40 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Performance counters software interface. -+ * -+ * $Id: bcmperf.h 241182 2011-02-17 21:50:03Z $ -+ */ -+/* essai */ -+#ifndef _BCMPERF_H_ -+#define _BCMPERF_H_ -+/* get cache hits and misses */ -+#if defined(BCMMIPS) && defined(BCMPERFSTATS) -+#include -+#define BCMPERF_ENABLE_INSTRCOUNT() hndmips_perf_instrcount_enable() -+#define BCMPERF_ENABLE_ICACHE_MISS() hndmips_perf_icache_miss_enable() -+#define BCMPERF_ENABLE_ICACHE_HIT() hndmips_perf_icache_hit_enable() -+#define BCMPERF_GETICACHE_MISS(x) ((x) = hndmips_perf_read_cache_miss()) -+#define BCMPERF_GETICACHE_HIT(x) ((x) = hndmips_perf_read_cache_hit()) -+#define BCMPERF_GETINSTRCOUNT(x) ((x) = hndmips_perf_read_instrcount()) -+#else -+#define BCMPERF_ENABLE_INSTRCOUNT() -+#define BCMPERF_ENABLE_ICACHE_MISS() -+#define BCMPERF_ENABLE_ICACHE_HIT() -+#define BCMPERF_GETICACHE_MISS(x) ((x) = 0) -+#define BCMPERF_GETICACHE_HIT(x) ((x) = 0) -+#define BCMPERF_GETINSTRCOUNT(x) ((x) = 0) -+#endif /* defined(mips) */ -+#endif /* _BCMPERF_H_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmsdpcm.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmsdpcm.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmsdpcm.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmsdpcm.h 2017-11-09 17:53:43.939297000 +0800 -@@ -0,0 +1,268 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom SDIO/PCMCIA -+ * Software-specific definitions shared between device and host side -+ * -+ * $Id: bcmsdpcm.h 314495 2012-02-12 07:56:39Z $ -+ */ -+ -+#ifndef _bcmsdpcm_h_ -+#define _bcmsdpcm_h_ -+ -+/* -+ * Software allocation of To SB Mailbox resources -+ */ -+ -+/* intstatus bits */ -+#define I_SMB_NAK I_SMB_SW0 /* To SB Mailbox Frame NAK */ -+#define I_SMB_INT_ACK I_SMB_SW1 /* To SB Mailbox Host Interrupt ACK */ -+#define I_SMB_USE_OOB I_SMB_SW2 /* To SB Mailbox Use OOB Wakeup */ -+#define I_SMB_DEV_INT I_SMB_SW3 /* To SB Mailbox Miscellaneous Interrupt */ -+ -+#define I_TOSBMAIL (I_SMB_NAK | I_SMB_INT_ACK | I_SMB_USE_OOB | I_SMB_DEV_INT) -+ -+/* tosbmailbox bits corresponding to intstatus bits */ -+#define SMB_NAK (1 << 0) /* To SB Mailbox Frame NAK */ -+#define SMB_INT_ACK (1 << 1) /* To SB Mailbox Host Interrupt ACK */ -+#define SMB_USE_OOB (1 << 2) /* To SB Mailbox Use OOB Wakeup */ -+#define SMB_DEV_INT (1 << 3) /* To SB Mailbox Miscellaneous Interrupt */ -+#define SMB_MASK 0x0000000f /* To SB Mailbox Mask */ -+ -+/* tosbmailboxdata */ -+#define SMB_DATA_VERSION_MASK 0x00ff0000 /* host protocol version (sent with F2 enable) */ -+#define SMB_DATA_VERSION_SHIFT 16 /* host protocol version (sent with F2 enable) */ -+ -+/* -+ * Software allocation of To Host Mailbox resources -+ */ -+ -+/* intstatus bits */ -+#define I_HMB_FC_STATE I_HMB_SW0 /* To Host Mailbox Flow Control State */ -+#define I_HMB_FC_CHANGE I_HMB_SW1 /* To Host Mailbox Flow Control State Changed */ -+#define I_HMB_FRAME_IND I_HMB_SW2 /* To Host Mailbox Frame Indication */ -+#define I_HMB_HOST_INT I_HMB_SW3 /* To Host Mailbox Miscellaneous Interrupt */ -+ -+#define I_TOHOSTMAIL (I_HMB_FC_CHANGE | I_HMB_FRAME_IND | I_HMB_HOST_INT) -+ -+/* tohostmailbox bits corresponding to intstatus bits */ -+#define HMB_FC_ON (1 << 0) /* To Host Mailbox Flow Control State */ -+#define HMB_FC_CHANGE (1 << 1) /* To Host Mailbox Flow Control State Changed */ -+#define HMB_FRAME_IND (1 << 2) /* To Host Mailbox Frame Indication */ -+#define HMB_HOST_INT (1 << 3) /* To Host Mailbox Miscellaneous Interrupt */ -+#define HMB_MASK 0x0000000f /* To Host Mailbox Mask */ -+ -+/* tohostmailboxdata */ -+#define HMB_DATA_NAKHANDLED 0x01 /* we're ready to retransmit NAK'd frame to host */ -+#define HMB_DATA_DEVREADY 0x02 /* we're ready to to talk to host after enable */ -+#define HMB_DATA_FC 0x04 /* per prio flowcontrol update flag to host */ -+#define HMB_DATA_FWREADY 0x08 /* firmware is ready for protocol activity */ -+#define HMB_DATA_FWHALT 0x10 /* firmware has halted operation */ -+ -+#define HMB_DATA_FCDATA_MASK 0xff000000 /* per prio flowcontrol data */ -+#define HMB_DATA_FCDATA_SHIFT 24 /* per prio flowcontrol data */ -+ -+#define HMB_DATA_VERSION_MASK 0x00ff0000 /* device protocol version (with devready) */ -+#define HMB_DATA_VERSION_SHIFT 16 /* device protocol version (with devready) */ -+ -+/* -+ * Software-defined protocol header -+ */ -+ -+/* Current protocol version */ -+#define SDPCM_PROT_VERSION 4 -+ -+/* SW frame header */ -+#define SDPCM_SEQUENCE_MASK 0x000000ff /* Sequence Number Mask */ -+#define SDPCM_PACKET_SEQUENCE(p) (((uint8 *)p)[0] & 0xff) /* p starts w/SW Header */ -+ -+#define SDPCM_CHANNEL_MASK 0x00000f00 /* Channel Number Mask */ -+#define SDPCM_CHANNEL_SHIFT 8 /* Channel Number Shift */ -+#define SDPCM_PACKET_CHANNEL(p) (((uint8 *)p)[1] & 0x0f) /* p starts w/SW Header */ -+ -+#define SDPCM_FLAGS_MASK 0x0000f000 /* Mask of flag bits */ -+#define SDPCM_FLAGS_SHIFT 12 /* Flag bits shift */ -+#define SDPCM_PACKET_FLAGS(p) ((((uint8 *)p)[1] & 0xf0) >> 4) /* p starts w/SW Header */ -+ -+/* Next Read Len: lookahead length of next frame, in 16-byte units (rounded up) */ -+#define SDPCM_NEXTLEN_MASK 0x00ff0000 /* Next Read Len Mask */ -+#define SDPCM_NEXTLEN_SHIFT 16 /* Next Read Len Shift */ -+#define SDPCM_NEXTLEN_VALUE(p) ((((uint8 *)p)[2] & 0xff) << 4) /* p starts w/SW Header */ -+#define SDPCM_NEXTLEN_OFFSET 2 -+ -+/* Data Offset from SOF (HW Tag, SW Tag, Pad) */ -+#define SDPCM_DOFFSET_OFFSET 3 /* Data Offset */ -+#define SDPCM_DOFFSET_VALUE(p) (((uint8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff) -+#define SDPCM_DOFFSET_MASK 0xff000000 -+#define SDPCM_DOFFSET_SHIFT 24 -+ -+#define SDPCM_FCMASK_OFFSET 4 /* Flow control */ -+#define SDPCM_FCMASK_VALUE(p) (((uint8 *)p)[SDPCM_FCMASK_OFFSET ] & 0xff) -+#define SDPCM_WINDOW_OFFSET 5 /* Credit based fc */ -+#define SDPCM_WINDOW_VALUE(p) (((uint8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff) -+#define SDPCM_VERSION_OFFSET 6 /* Version # */ -+#define SDPCM_VERSION_VALUE(p) (((uint8 *)p)[SDPCM_VERSION_OFFSET] & 0xff) -+#define SDPCM_UNUSED_OFFSET 7 /* Spare */ -+#define SDPCM_UNUSED_VALUE(p) (((uint8 *)p)[SDPCM_UNUSED_OFFSET] & 0xff) -+ -+#define SDPCM_SWHEADER_LEN 8 /* SW header is 64 bits */ -+ -+/* logical channel numbers */ -+#define SDPCM_CONTROL_CHANNEL 0 /* Control Request/Response Channel Id */ -+#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication Channel Id */ -+#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv Channel Id */ -+#define SDPCM_GLOM_CHANNEL 3 /* For coalesced packets (superframes) */ -+#define SDPCM_TEST_CHANNEL 15 /* Reserved for test/debug packets */ -+#define SDPCM_MAX_CHANNEL 15 -+ -+#define SDPCM_SEQUENCE_WRAP 256 /* wrap-around val for eight-bit frame seq number */ -+ -+#define SDPCM_FLAG_RESVD0 0x01 -+#define SDPCM_FLAG_RESVD1 0x02 -+#define SDPCM_FLAG_GSPI_TXENAB 0x04 -+#define SDPCM_FLAG_GLOMDESC 0x08 /* Superframe descriptor mask */ -+ -+/* For GLOM_CHANNEL frames, use a flag to indicate descriptor frame */ -+#define SDPCM_GLOMDESC_FLAG (SDPCM_FLAG_GLOMDESC << SDPCM_FLAGS_SHIFT) -+ -+#define SDPCM_GLOMDESC(p) (((uint8 *)p)[1] & 0x80) -+ -+/* For TEST_CHANNEL packets, define another 4-byte header */ -+#define SDPCM_TEST_HDRLEN 4 /* Generally: Cmd(1), Ext(1), Len(2); -+ * Semantics of Ext byte depend on command. -+ * Len is current or requested frame length, not -+ * including test header; sent little-endian. -+ */ -+#define SDPCM_TEST_DISCARD 0x01 /* Receiver discards. Ext is a pattern id. */ -+#define SDPCM_TEST_ECHOREQ 0x02 /* Echo request. Ext is a pattern id. */ -+#define SDPCM_TEST_ECHORSP 0x03 /* Echo response. Ext is a pattern id. */ -+#define SDPCM_TEST_BURST 0x04 /* Receiver to send a burst. Ext is a frame count */ -+#define SDPCM_TEST_SEND 0x05 /* Receiver sets send mode. Ext is boolean on/off */ -+ -+/* Handy macro for filling in datagen packets with a pattern */ -+#define SDPCM_TEST_FILL(byteno, id) ((uint8)(id + byteno)) -+ -+/* -+ * Software counters (first part matches hardware counters) -+ */ -+ -+typedef volatile struct { -+ uint32 cmd52rd; /* Cmd52RdCount, SDIO: cmd52 reads */ -+ uint32 cmd52wr; /* Cmd52WrCount, SDIO: cmd52 writes */ -+ uint32 cmd53rd; /* Cmd53RdCount, SDIO: cmd53 reads */ -+ uint32 cmd53wr; /* Cmd53WrCount, SDIO: cmd53 writes */ -+ uint32 abort; /* AbortCount, SDIO: aborts */ -+ uint32 datacrcerror; /* DataCrcErrorCount, SDIO: frames w/CRC error */ -+ uint32 rdoutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Rd Frm out of sync */ -+ uint32 wroutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Wr Frm out of sync */ -+ uint32 writebusy; /* WriteBusyCount, SDIO: device asserted "busy" */ -+ uint32 readwait; /* ReadWaitCount, SDIO: no data ready for a read cmd */ -+ uint32 readterm; /* ReadTermCount, SDIO: read frame termination cmds */ -+ uint32 writeterm; /* WriteTermCount, SDIO: write frames termination cmds */ -+ uint32 rxdescuflo; /* receive descriptor underflows */ -+ uint32 rxfifooflo; /* receive fifo overflows */ -+ uint32 txfifouflo; /* transmit fifo underflows */ -+ uint32 runt; /* runt (too short) frames recv'd from bus */ -+ uint32 badlen; /* frame's rxh len does not match its hw tag len */ -+ uint32 badcksum; /* frame's hw tag chksum doesn't agree with len value */ -+ uint32 seqbreak; /* break in sequence # space from one rx frame to the next */ -+ uint32 rxfcrc; /* frame rx header indicates crc error */ -+ uint32 rxfwoos; /* frame rx header indicates write out of sync */ -+ uint32 rxfwft; /* frame rx header indicates write frame termination */ -+ uint32 rxfabort; /* frame rx header indicates frame aborted */ -+ uint32 woosint; /* write out of sync interrupt */ -+ uint32 roosint; /* read out of sync interrupt */ -+ uint32 rftermint; /* read frame terminate interrupt */ -+ uint32 wftermint; /* write frame terminate interrupt */ -+} sdpcmd_cnt_t; -+ -+/* -+ * Register Access Macros -+ */ -+ -+#define SDIODREV_IS(var, val) ((var) == (val)) -+#define SDIODREV_GE(var, val) ((var) >= (val)) -+#define SDIODREV_GT(var, val) ((var) > (val)) -+#define SDIODREV_LT(var, val) ((var) < (val)) -+#define SDIODREV_LE(var, val) ((var) <= (val)) -+ -+#define SDIODDMAREG32(h, dir, chnl) \ -+ ((dir) == DMA_TX ? \ -+ (void *)(uintptr)&((h)->regs->dma.sdiod32.dma32regs[chnl].xmt) : \ -+ (void *)(uintptr)&((h)->regs->dma.sdiod32.dma32regs[chnl].rcv)) -+ -+#define SDIODDMAREG64(h, dir, chnl) \ -+ ((dir) == DMA_TX ? \ -+ (void *)(uintptr)&((h)->regs->dma.sdiod64.dma64regs[chnl].xmt) : \ -+ (void *)(uintptr)&((h)->regs->dma.sdiod64.dma64regs[chnl].rcv)) -+ -+#define SDIODDMAREG(h, dir, chnl) \ -+ (SDIODREV_LT((h)->corerev, 1) ? \ -+ SDIODDMAREG32((h), (dir), (chnl)) : \ -+ SDIODDMAREG64((h), (dir), (chnl))) -+ -+#define PCMDDMAREG(h, dir, chnl) \ -+ ((dir) == DMA_TX ? \ -+ (void *)(uintptr)&((h)->regs->dma.pcm32.dmaregs.xmt) : \ -+ (void *)(uintptr)&((h)->regs->dma.pcm32.dmaregs.rcv)) -+ -+#define SDPCMDMAREG(h, dir, chnl, coreid) \ -+ ((coreid) == SDIOD_CORE_ID ? \ -+ SDIODDMAREG(h, dir, chnl) : \ -+ PCMDDMAREG(h, dir, chnl)) -+ -+#define SDIODFIFOREG(h, corerev) \ -+ (SDIODREV_LT((corerev), 1) ? \ -+ ((dma32diag_t *)(uintptr)&((h)->regs->dma.sdiod32.dmafifo)) : \ -+ ((dma32diag_t *)(uintptr)&((h)->regs->dma.sdiod64.dmafifo))) -+ -+#define PCMDFIFOREG(h) \ -+ ((dma32diag_t *)(uintptr)&((h)->regs->dma.pcm32.dmafifo)) -+ -+#define SDPCMFIFOREG(h, coreid, corerev) \ -+ ((coreid) == SDIOD_CORE_ID ? \ -+ SDIODFIFOREG(h, corerev) : \ -+ PCMDFIFOREG(h)) -+ -+/* -+ * Shared structure between dongle and the host. -+ * The structure contains pointers to trap or assert information. -+ */ -+#define SDPCM_SHARED_VERSION 0x0001 -+#define SDPCM_SHARED_VERSION_MASK 0x00FF -+#define SDPCM_SHARED_ASSERT_BUILT 0x0100 -+#define SDPCM_SHARED_ASSERT 0x0200 -+#define SDPCM_SHARED_TRAP 0x0400 -+#define SDPCM_SHARED_IN_BRPT 0x0800 -+#define SDPCM_SHARED_SET_BRPT 0x1000 -+#define SDPCM_SHARED_PENDING_BRPT 0x2000 -+ -+typedef struct { -+ uint32 flags; -+ uint32 trap_addr; -+ uint32 assert_exp_addr; -+ uint32 assert_file_addr; -+ uint32 assert_line; -+ uint32 console_addr; /* Address of hndrte_cons_t */ -+ uint32 msgtrace_addr; -+ uint32 fwid; -+} sdpcm_shared_t; -+ -+extern sdpcm_shared_t sdpcm_shared; -+ -+/* Function can be used to notify host of FW halt */ -+extern void sdpcmd_fwhalt(void); -+ -+#endif /* _bcmsdpcm_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmstdlib.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmstdlib.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmstdlib.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmstdlib.h 2017-11-09 17:53:43.940291000 +0800 -@@ -0,0 +1,128 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * prototypes for functions defined in bcmstdlib.c -+ * -+ * $Id: bcmstdlib.h 289936 2011-10-14 21:06:33Z $: -+ */ -+ -+/* -+ * bcmstdlib.h file should be used only to construct an OSL or alone without any OSL -+ * It should not be used with any orbitarary OSL's as there could be a conflict -+ * with some of the routines defined here. -+*/ -+ -+#ifndef _BCMSTDLIB_H -+#define _BCMSTDLIB_H -+ -+#include -+#include -+#include -+ -+#ifndef INT_MAX -+#define INT_MAX 2147483647 /* from limits.h */ -+#endif -+ -+ -+/* For backwards compatibility, define "BWL_NO_INTERNAL_STDLIB_SUPPORT" to -+ * exclude support for the BRCM stdlib APIs. This should be cleaned-up such -+ * that platforms that require the BRCM stdlib API should simply define -+ * "BWL_INTERNAL_STDLIB_SUPPORT". This would eliminate the need for the -+ * following #ifndef check. -+ */ -+#ifndef BWL_NO_INTERNAL_STDLIB_SUPPORT -+#define BWL_INTERNAL_STDLIB_SUPPORT -+#endif -+ -+#ifdef BWL_INTERNAL_STDLIB_SUPPORT -+/* This should be cleaned-up such that platforms that require the BRCM stdlib -+ * API should simply define "BWL_INTERNAL_STDLIB_SUPPORT". This would eliminate -+ * the need for the following #ifdef check. -+ */ -+#if !defined(_WIN32) && !defined(_CFE_) && !defined(EFI) -+ -+typedef int FILE; -+#define stdout ((FILE *)1) -+#define stderr ((FILE *)2) -+ -+/* i/o functions */ -+extern int fputc(int c, FILE *stream); -+extern void putc(int c); -+/* extern int putc(int c, FILE *stream); */ -+#define putchar(c) putc(c) -+extern int fputs(const char *s, FILE *stream); -+extern int puts(const char *s); -+extern int getc(void); -+extern bool keypressed(void); -+ -+/* bcopy, bcmp, and bzero */ -+#define bcopy(src, dst, len) memcpy((dst), (src), (len)) -+#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) -+#define bzero(b, len) memset((b), '\0', (len)) -+ -+extern unsigned long rand(void); -+ -+#define atoi(s) ((int)(strtoul((s), NULL, 10))) -+ -+#endif -+ -+#if !defined(_WIN32) || defined(EFI) -+/* string functions */ -+#define PRINTF_BUFLEN 512 -+extern int printf(const char *fmt, ...) -+ __attribute__ ((format (__printf__, 1, 2))); -+extern int BCMROMFN(sprintf)(char *buf, const char *fmt, ...) -+ __attribute__ ((format (__printf__, 2, 3))); -+ -+extern int BCMROMFN(strcmp)(const char *s1, const char *s2); -+extern size_t BCMROMFN(strlen)(const char *s); -+extern char *BCMROMFN(strcpy)(char *dest, const char *src); -+extern char *BCMROMFN(strstr)(const char *s, const char *find); -+extern char *BCMROMFN(strncpy)(char *dest, const char *src, size_t n); -+extern char *BCMROMFN(strcat)(char *d, const char *s); -+ -+extern int BCMROMFN(strncmp)(const char *s1, const char *s2, size_t n); -+extern char *BCMROMFN(strchr)(const char *str, int c); -+extern char *BCMROMFN(strrchr)(const char *str, int c); -+extern size_t BCMROMFN(strspn)(const char *s1, const char *s2); -+extern size_t BCMROMFN(strcspn)(const char *s1, const char *s2); -+extern unsigned long BCMROMFN(strtoul)(const char *cp, char **endp, int base); -+#define strtol(nptr, endptr, base) ((long)strtoul((nptr), (endptr), (base))) -+ -+extern void *BCMROMFN(memmove)(void *dest, const void *src, size_t n); -+extern void *BCMROMFN(memchr)(const void *s, int c, size_t n); -+ -+extern int BCMROMFN(vsprintf)(char *buf, const char *fmt, va_list ap); -+/* mem functions */ -+/* For EFI, using EFIDriverLib versions */ -+/* Cannot use memmem in ROM because of character array initialization wiht "" in gcc */ -+extern void *memset(void *dest, int c, size_t n); -+/* Cannot use memcpy in ROM because of structure assignmnets in gcc */ -+extern void *memcpy(void *dest, const void *src, size_t n); -+extern int BCMROMFN(memcmp)(const void *s1, const void *s2, size_t n); -+ -+#endif /* !_WIN32 || EFI */ -+#endif /* BWL_INTERNAL_STDLIB_SUPPORT */ -+ -+#if !defined(_WIN32) || defined(EFI) -+extern int BCMROMFN(snprintf)(char *str, size_t n, char const *fmt, ...) -+ __attribute__ ((format (__printf__, 3, 4))); -+#else -+extern int BCMROMFN(snprintf)(char *str, size_t n, char const *fmt, ...); -+#endif -+ -+extern int BCMROMFN(vsnprintf)(char *buf, size_t size, const char *fmt, va_list ap); -+ -+#endif /* _BCMSTDLIB_H */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmutils.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmutils.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmutils.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmutils.h 2017-11-09 17:53:43.941299000 +0800 -@@ -0,0 +1,864 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Misc useful os-independent macros and functions. -+ * -+ * $Id: bcmutils.h 325951 2012-04-05 06:03:27Z $ -+ */ -+ -+#ifndef _bcmutils_h_ -+#define _bcmutils_h_ -+ -+#if defined(UNDER_CE) -+#include -+#else -+#define bcm_strcpy_s(dst, noOfElements, src) strcpy((dst), (src)) -+#define bcm_strncpy_s(dst, noOfElements, src, count) strncpy((dst), (src), (count)) -+#define bcm_strcat_s(dst, noOfElements, src) strcat((dst), (src)) -+#endif -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#ifdef PKTQ_LOG -+#include -+#endif -+ -+/* ctype replacement */ -+#define _BCM_U 0x01 /* upper */ -+#define _BCM_L 0x02 /* lower */ -+#define _BCM_D 0x04 /* digit */ -+#define _BCM_C 0x08 /* cntrl */ -+#define _BCM_P 0x10 /* punct */ -+#define _BCM_S 0x20 /* white space (space/lf/tab) */ -+#define _BCM_X 0x40 /* hex digit */ -+#define _BCM_SP 0x80 /* hard space (0x20) */ -+ -+#if defined(BCMROMBUILD) -+extern const unsigned char BCMROMDATA(bcm_ctype)[]; -+#else -+extern const unsigned char bcm_ctype[]; -+#endif -+#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)]) -+ -+#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0) -+#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0) -+#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0) -+#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0) -+#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0) -+#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0) -+#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0) -+#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0) -+#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0) -+#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0) -+#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0) -+#define bcm_tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c)) -+#define bcm_toupper(c) (bcm_islower((c)) ? ((c) + 'A' - 'a') : (c)) -+ -+/* Buffer structure for collecting string-formatted data -+* using bcm_bprintf() API. -+* Use bcm_binit() to initialize before use -+*/ -+ -+struct bcmstrbuf { -+ char *buf; /* pointer to current position in origbuf */ -+ unsigned int size; /* current (residual) size in bytes */ -+ char *origbuf; /* unmodified pointer to orignal buffer */ -+ unsigned int origsize; /* unmodified orignal buffer size in bytes */ -+}; -+ -+/* ** driver-only section ** */ -+#ifdef BCMDRIVER -+#ifdef EFI -+/* forward declare structyre type */ -+struct spktq; -+#endif -+#include -+ -+#define GPIO_PIN_NOTDEFINED 0x20 /* Pin not defined */ -+ -+/* -+ * Spin at most 'us' microseconds while 'exp' is true. -+ * Caller should explicitly test 'exp' when this completes -+ * and take appropriate error action if 'exp' is still true. -+ */ -+#define SPINWAIT(exp, us) { \ -+ uint countdown = (us) + 9; \ -+ while ((exp) && (countdown >= 10)) {\ -+ OSL_DELAY(10); \ -+ countdown -= 10; \ -+ } \ -+} -+ -+/* osl multi-precedence packet queue */ -+#ifndef PKTQ_LEN_DEFAULT -+#define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */ -+#endif -+#ifndef PKTQ_MAX_PREC -+#define PKTQ_MAX_PREC 16 /* Maximum precedence levels */ -+#endif -+ -+typedef struct pktq_prec { -+ void *head; /* first packet to dequeue */ -+ void *tail; /* last packet to dequeue */ -+ uint16 len; /* number of queued packets */ -+ uint16 max; /* maximum number of queued packets */ -+} pktq_prec_t; -+ -+#ifdef PKTQ_LOG -+typedef struct { -+ uint32 requested; /* packets requested to be stored */ -+ uint32 stored; /* packets stored */ -+ uint32 saved; /* packets saved, -+ because a lowest priority queue has given away one packet -+ */ -+ uint32 selfsaved; /* packets saved, -+ because an older packet from the same queue has been dropped -+ */ -+ uint32 full_dropped; /* packets dropped, -+ because pktq is full with higher precedence packets -+ */ -+ uint32 dropped; /* packets dropped because pktq per that precedence is full */ -+ uint32 sacrificed; /* packets dropped, -+ in order to save one from a queue of a highest priority -+ */ -+ uint32 busy; /* packets droped because of hardware/transmission error */ -+ uint32 retry; /* packets re-sent because they were not received */ -+ uint32 ps_retry; /* packets retried again prior to moving power save mode */ -+ uint32 retry_drop; /* packets finally dropped after retry limit */ -+ uint32 max_avail; /* the high-water mark of the queue capacity for packets - -+ goes to zero as queue fills -+ */ -+ uint32 max_used; /* the high-water mark of the queue utilisation for packets - -+ increases with use ('inverse' of max_avail) -+ */ -+ uint32 queue_capacity; /* the maximum capacity of the queue */ -+} pktq_counters_t; -+#endif /* PKTQ_LOG */ -+ -+ -+#define PKTQ_COMMON \ -+ uint16 num_prec; /* number of precedences in use */ \ -+ uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */ \ -+ uint16 max; /* total max packets */ \ -+ uint16 len; /* total number of packets */ -+ -+/* multi-priority pkt queue */ -+struct pktq { -+ PKTQ_COMMON -+ /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */ -+ struct pktq_prec q[PKTQ_MAX_PREC]; -+#ifdef PKTQ_LOG -+ pktq_counters_t _prec_cnt[PKTQ_MAX_PREC]; /* Counters per queue */ -+#endif -+}; -+ -+/* simple, non-priority pkt queue */ -+struct spktq { -+ PKTQ_COMMON -+ /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */ -+ struct pktq_prec q[1]; -+}; -+ -+#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--) -+ -+/* fn(pkt, arg). return true if pkt belongs to if */ -+typedef bool (*ifpkt_cb_t)(void*, int); -+ -+#ifdef BCMPKTPOOL -+#define POOL_ENAB(pool) ((pool) && (pool)->inited) -+#if defined(BCM4329C0) -+#define SHARED_POOL (pktpool_shared_ptr) -+#else -+#define SHARED_POOL (pktpool_shared) -+#endif /* BCM4329C0 */ -+#else /* BCMPKTPOOL */ -+#define POOL_ENAB(bus) 0 -+#define SHARED_POOL ((struct pktpool *)NULL) -+#endif /* BCMPKTPOOL */ -+ -+#ifndef PKTPOOL_LEN_MAX -+#define PKTPOOL_LEN_MAX 40 -+#endif /* PKTPOOL_LEN_MAX */ -+#define PKTPOOL_CB_MAX 3 -+ -+struct pktpool; -+typedef void (*pktpool_cb_t)(struct pktpool *pool, void *arg); -+typedef struct { -+ pktpool_cb_t cb; -+ void *arg; -+} pktpool_cbinfo_t; -+ -+#ifdef BCMDBG_POOL -+/* pkt pool debug states */ -+#define POOL_IDLE 0 -+#define POOL_RXFILL 1 -+#define POOL_RXDH 2 -+#define POOL_RXD11 3 -+#define POOL_TXDH 4 -+#define POOL_TXD11 5 -+#define POOL_AMPDU 6 -+#define POOL_TXENQ 7 -+ -+typedef struct { -+ void *p; -+ uint32 cycles; -+ uint32 dur; -+} pktpool_dbg_t; -+ -+typedef struct { -+ uint8 txdh; /* tx to host */ -+ uint8 txd11; /* tx to d11 */ -+ uint8 enq; /* waiting in q */ -+ uint8 rxdh; /* rx from host */ -+ uint8 rxd11; /* rx from d11 */ -+ uint8 rxfill; /* dma_rxfill */ -+ uint8 idle; /* avail in pool */ -+} pktpool_stats_t; -+#endif /* BCMDBG_POOL */ -+ -+typedef struct pktpool { -+ bool inited; -+ uint16 r; -+ uint16 w; -+ uint16 len; -+ uint16 maxlen; -+ uint16 plen; -+ bool istx; -+ bool empty; -+ uint8 cbtoggle; -+ uint8 cbcnt; -+ uint8 ecbcnt; -+ bool emptycb_disable; -+ pktpool_cbinfo_t *availcb_excl; -+ pktpool_cbinfo_t cbs[PKTPOOL_CB_MAX]; -+ pktpool_cbinfo_t ecbs[PKTPOOL_CB_MAX]; -+ void *q[PKTPOOL_LEN_MAX + 1]; -+ -+#ifdef BCMDBG_POOL -+ uint8 dbg_cbcnt; -+ pktpool_cbinfo_t dbg_cbs[PKTPOOL_CB_MAX]; -+ uint16 dbg_qlen; -+ pktpool_dbg_t dbg_q[PKTPOOL_LEN_MAX + 1]; -+#endif -+} pktpool_t; -+ -+#if defined(BCM4329C0) -+extern pktpool_t *pktpool_shared_ptr; -+#else -+extern pktpool_t *pktpool_shared; -+#endif /* BCM4329C0 */ -+ -+extern int pktpool_init(osl_t *osh, pktpool_t *pktp, int *pktplen, int plen, bool istx); -+extern int pktpool_deinit(osl_t *osh, pktpool_t *pktp); -+extern int pktpool_fill(osl_t *osh, pktpool_t *pktp, bool minimal); -+extern void* pktpool_get(pktpool_t *pktp); -+extern void pktpool_free(pktpool_t *pktp, void *p); -+extern int pktpool_add(pktpool_t *pktp, void *p); -+extern uint16 pktpool_avail(pktpool_t *pktp); -+extern int pktpool_avail_notify_normal(osl_t *osh, pktpool_t *pktp); -+extern int pktpool_avail_notify_exclusive(osl_t *osh, pktpool_t *pktp, pktpool_cb_t cb); -+extern int pktpool_avail_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); -+extern int pktpool_empty_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); -+extern int pktpool_setmaxlen(pktpool_t *pktp, uint16 maxlen); -+extern int pktpool_setmaxlen_strict(osl_t *osh, pktpool_t *pktp, uint16 maxlen); -+extern void pktpool_emptycb_disable(pktpool_t *pktp, bool disable); -+extern bool pktpool_emptycb_disabled(pktpool_t *pktp); -+ -+#define POOLPTR(pp) ((pktpool_t *)(pp)) -+#define pktpool_len(pp) (POOLPTR(pp)->len - 1) -+#define pktpool_plen(pp) (POOLPTR(pp)->plen) -+#define pktpool_maxlen(pp) (POOLPTR(pp)->maxlen) -+ -+#ifdef BCMDBG_POOL -+extern int pktpool_dbg_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg); -+extern int pktpool_start_trigger(pktpool_t *pktp, void *p); -+extern int pktpool_dbg_dump(pktpool_t *pktp); -+extern int pktpool_dbg_notify(pktpool_t *pktp); -+extern int pktpool_stats_dump(pktpool_t *pktp, pktpool_stats_t *stats); -+#endif /* BCMDBG_POOL */ -+ -+/* forward definition of ether_addr structure used by some function prototypes */ -+ -+struct ether_addr; -+ -+extern int ether_isbcast(const void *ea); -+extern int ether_isnulladdr(const void *ea); -+ -+/* operations on a specific precedence in packet queue */ -+ -+#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) -+#define pktq_pmax(pq, prec) ((pq)->q[prec].max) -+#define pktq_plen(pq, prec) ((pq)->q[prec].len) -+#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len) -+#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max) -+#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0) -+ -+#define pktq_ppeek(pq, prec) ((pq)->q[prec].head) -+#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) -+ -+extern void *pktq_penq(struct pktq *pq, int prec, void *p); -+extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); -+extern void *pktq_pdeq(struct pktq *pq, int prec); -+extern void *pktq_pdeq_prev(struct pktq *pq, int prec, void *prev_p); -+extern void *pktq_pdeq_tail(struct pktq *pq, int prec); -+/* Empty the queue at particular precedence level */ -+extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir, -+ ifpkt_cb_t fn, int arg); -+/* Remove a specified packet from its queue */ -+extern bool pktq_pdel(struct pktq *pq, void *p, int prec); -+ -+/* operations on a set of precedences in packet queue */ -+ -+extern int pktq_mlen(struct pktq *pq, uint prec_bmp); -+extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); -+extern void *pktq_mpeek(struct pktq *pq, uint prec_bmp, int *prec_out); -+ -+/* operations on packet queue as a whole */ -+ -+#define pktq_len(pq) ((int)(pq)->len) -+#define pktq_max(pq) ((int)(pq)->max) -+#define pktq_avail(pq) ((int)((pq)->max - (pq)->len)) -+#define pktq_full(pq) ((pq)->len >= (pq)->max) -+#define pktq_empty(pq) ((pq)->len == 0) -+ -+/* operations for single precedence queues */ -+#define pktenq(pq, p) pktq_penq(((struct pktq *)(void *)pq), 0, (p)) -+#define pktenq_head(pq, p) pktq_penq_head(((struct pktq *)(void *)pq), 0, (p)) -+#define pktdeq(pq) pktq_pdeq(((struct pktq *)(void *)pq), 0) -+#define pktdeq_tail(pq) pktq_pdeq_tail(((struct pktq *)(void *)pq), 0) -+#define pktqinit(pq, len) pktq_init(((struct pktq *)(void *)pq), 1, len) -+ -+extern void pktq_init(struct pktq *pq, int num_prec, int max_len); -+extern void pktq_set_max_plen(struct pktq *pq, int prec, int max_len); -+ -+/* prec_out may be NULL if caller is not interested in return value */ -+extern void *pktq_deq(struct pktq *pq, int *prec_out); -+extern void *pktq_deq_tail(struct pktq *pq, int *prec_out); -+extern void *pktq_peek(struct pktq *pq, int *prec_out); -+extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); -+extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg); -+ -+/* externs */ -+/* packet */ -+extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); -+extern uint pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf); -+extern uint pkttotlen(osl_t *osh, void *p); -+extern void *pktlast(osl_t *osh, void *p); -+extern uint pktsegcnt(osl_t *osh, void *p); -+extern uint pktsegcnt_war(osl_t *osh, void *p); -+extern uint8 *pktdataoffset(osl_t *osh, void *p, uint offset); -+extern void *pktoffset(osl_t *osh, void *p, uint offset); -+ -+/* Get priority from a packet and pass it back in scb (or equiv) */ -+#define PKTPRIO_VDSCP 0x100 /* DSCP prio found after VLAN tag */ -+#define PKTPRIO_VLAN 0x200 /* VLAN prio found */ -+#define PKTPRIO_UPD 0x400 /* DSCP used to update VLAN prio */ -+#define PKTPRIO_DSCP 0x800 /* DSCP prio found */ -+ -+extern uint pktsetprio(void *pkt, bool update_vtag); -+ -+/* string */ -+extern int BCMROMFN(bcm_atoi)(const char *s); -+extern ulong BCMROMFN(bcm_strtoul)(const char *cp, char **endp, uint base); -+extern char *BCMROMFN(bcmstrstr)(const char *haystack, const char *needle); -+extern char *BCMROMFN(bcmstrcat)(char *dest, const char *src); -+extern char *BCMROMFN(bcmstrncat)(char *dest, const char *src, uint size); -+extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen); -+char* bcmstrtok(char **string, const char *delimiters, char *tokdelim); -+int bcmstricmp(const char *s1, const char *s2); -+int bcmstrnicmp(const char* s1, const char* s2, int cnt); -+ -+ -+/* ethernet address */ -+extern char *bcm_ether_ntoa(const struct ether_addr *ea, char *buf); -+extern int BCMROMFN(bcm_ether_atoe)(const char *p, struct ether_addr *ea); -+ -+/* ip address */ -+struct ipv4_addr; -+extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf); -+ -+/* delay */ -+extern void bcm_mdelay(uint ms); -+/* variable access */ -+#if defined(DONGLEBUILD) && !defined(WLTEST) -+#ifdef BCMDBG -+#define NVRAM_RECLAIM_CHECK(name) \ -+ if (attach_part_reclaimed == TRUE) { \ -+ printf("%s: NVRAM already reclaimed, %s\n", __FUNCTION__, (name)); \ -+ *(char*) 0 = 0; /* TRAP */ \ -+ return NULL; \ -+ } -+#else /* BCMDBG */ -+#define NVRAM_RECLAIM_CHECK(name) \ -+ if (attach_part_reclaimed == TRUE) { \ -+ *(char*) 0 = 0; /* TRAP */ \ -+ return NULL; \ -+ } -+#endif /* BCMDBG */ -+#else /* DONGLEBUILD && !WLTEST && !BCMINTERNAL && !BCMDBG_DUMP */ -+#define NVRAM_RECLAIM_CHECK(name) -+#endif -+ -+extern char *getvar(char *vars, const char *name); -+extern int getintvar(char *vars, const char *name); -+extern int getintvararray(char *vars, const char *name, int index); -+extern int getintvararraysize(char *vars, const char *name); -+extern uint getgpiopin(char *vars, char *pin_name, uint def_pin); -+extern int getwanport(void); -+extern int getbrcmtag(void); -+#ifdef BCMDBG -+extern void prpkt(const char *msg, osl_t *osh, void *p0); -+#endif /* BCMDBG */ -+#ifdef BCMPERFSTATS -+extern void bcm_perf_enable(void); -+extern void bcmstats(char *fmt); -+extern void bcmlog(char *fmt, uint a1, uint a2); -+extern void bcmdumplog(char *buf, int size); -+extern int bcmdumplogent(char *buf, uint idx); -+#else -+#define bcm_perf_enable() -+#define bcmstats(fmt) -+#define bcmlog(fmt, a1, a2) -+#define bcmdumplog(buf, size) *buf = '\0' -+#define bcmdumplogent(buf, idx) -1 -+#endif /* BCMPERFSTATS */ -+ -+#if defined(BCMTSTAMPEDLOGS) -+#define TSF_TICKS_PER_MS 1024 -+/* Store a TSF timestamp and a log line in the log buffer */ -+extern void bcmtslog(uint32 tstamp, char *fmt, uint a1, uint a2); -+/* Print out the log buffer with timestamps */ -+extern void bcmprinttslogs(void); -+/* Print out a microsecond timestamp as "sec.ms.us " */ -+extern void bcmprinttstamp(uint32 us); -+/* Dump to buffer a microsecond timestamp as "sec.ms.us " */ -+extern void bcmdumptslog(char *buf, int size); -+#else -+#define bcmtslog(tstamp, fmt, a1, a2) -+#define bcmprinttslogs() -+#define bcmprinttstamp(us) -+#define bcmdumptslog(buf, size) -+#endif /* BCMTSTAMPEDLOGS */ -+ -+extern char *bcm_nvram_vars(uint *length); -+extern int bcm_nvram_cache(void *sih); -+ -+/* Support for sharing code across in-driver iovar implementations. -+ * The intent is that a driver use this structure to map iovar names -+ * to its (private) iovar identifiers, and the lookup function to -+ * find the entry. Macros are provided to map ids and get/set actions -+ * into a single number space for a switch statement. -+ */ -+ -+/* iovar structure */ -+typedef struct bcm_iovar { -+ const char *name; /* name for lookup and display */ -+ uint16 varid; /* id for switch */ -+ uint16 flags; /* driver-specific flag bits */ -+ uint16 type; /* base type of argument */ -+ uint16 minlen; /* min length for buffer vars */ -+} bcm_iovar_t; -+ -+/* varid definitions are per-driver, may use these get/set bits */ -+ -+/* IOVar action bits for id mapping */ -+#define IOV_GET 0 /* Get an iovar */ -+#define IOV_SET 1 /* Set an iovar */ -+ -+/* Varid to actionid mapping */ -+#define IOV_GVAL(id) ((id) * 2) -+#define IOV_SVAL(id) ((id) * 2 + IOV_SET) -+#define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET) -+#define IOV_ID(actionid) (actionid >> 1) -+ -+/* flags are per-driver based on driver attributes */ -+ -+extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name); -+extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg, int len, bool set); -+#if defined(WLTINYDUMP) || defined(BCMDBG) || defined(WLMSG_INFORM) || \ -+ defined(WLMSG_ASSOC) || defined(WLMSG_PRPKT) || defined(WLMSG_WSEC) -+extern int bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len); -+#endif /* WLTINYDUMP || BCMDBG || WLMSG_INFORM || WLMSG_ASSOC || WLMSG_PRPKT */ -+#endif /* BCMDRIVER */ -+ -+/* Base type definitions */ -+#define IOVT_VOID 0 /* no value (implictly set only) */ -+#define IOVT_BOOL 1 /* any value ok (zero/nonzero) */ -+#define IOVT_INT8 2 /* integer values are range-checked */ -+#define IOVT_UINT8 3 /* unsigned int 8 bits */ -+#define IOVT_INT16 4 /* int 16 bits */ -+#define IOVT_UINT16 5 /* unsigned int 16 bits */ -+#define IOVT_INT32 6 /* int 32 bits */ -+#define IOVT_UINT32 7 /* unsigned int 32 bits */ -+#define IOVT_BUFFER 8 /* buffer is size-checked as per minlen */ -+#define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER) -+ -+/* Initializer for IOV type strings */ -+#define BCM_IOV_TYPE_INIT { \ -+ "void", \ -+ "bool", \ -+ "int8", \ -+ "uint8", \ -+ "int16", \ -+ "uint16", \ -+ "int32", \ -+ "uint32", \ -+ "buffer", \ -+ "" } -+ -+#define BCM_IOVT_IS_INT(type) (\ -+ (type == IOVT_BOOL) || \ -+ (type == IOVT_INT8) || \ -+ (type == IOVT_UINT8) || \ -+ (type == IOVT_INT16) || \ -+ (type == IOVT_UINT16) || \ -+ (type == IOVT_INT32) || \ -+ (type == IOVT_UINT32)) -+ -+/* ** driver/apps-shared section ** */ -+ -+#define BCME_STRLEN 64 /* Max string length for BCM errors */ -+#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST)) -+ -+ -+/* -+ * error codes could be added but the defined ones shouldn't be changed/deleted -+ * these error codes are exposed to the user code -+ * when ever a new error code is added to this list -+ * please update errorstring table with the related error string and -+ * update osl files with os specific errorcode map -+*/ -+ -+#define BCME_OK 0 /* Success */ -+#define BCME_ERROR -1 /* Error generic */ -+#define BCME_BADARG -2 /* Bad Argument */ -+#define BCME_BADOPTION -3 /* Bad option */ -+#define BCME_NOTUP -4 /* Not up */ -+#define BCME_NOTDOWN -5 /* Not down */ -+#define BCME_NOTAP -6 /* Not AP */ -+#define BCME_NOTSTA -7 /* Not STA */ -+#define BCME_BADKEYIDX -8 /* BAD Key Index */ -+#define BCME_RADIOOFF -9 /* Radio Off */ -+#define BCME_NOTBANDLOCKED -10 /* Not band locked */ -+#define BCME_NOCLK -11 /* No Clock */ -+#define BCME_BADRATESET -12 /* BAD Rate valueset */ -+#define BCME_BADBAND -13 /* BAD Band */ -+#define BCME_BUFTOOSHORT -14 /* Buffer too short */ -+#define BCME_BUFTOOLONG -15 /* Buffer too long */ -+#define BCME_BUSY -16 /* Busy */ -+#define BCME_NOTASSOCIATED -17 /* Not Associated */ -+#define BCME_BADSSIDLEN -18 /* Bad SSID len */ -+#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel */ -+#define BCME_BADCHAN -20 /* Bad Channel */ -+#define BCME_BADADDR -21 /* Bad Address */ -+#define BCME_NORESOURCE -22 /* Not Enough Resources */ -+#define BCME_UNSUPPORTED -23 /* Unsupported */ -+#define BCME_BADLEN -24 /* Bad length */ -+#define BCME_NOTREADY -25 /* Not Ready */ -+#define BCME_EPERM -26 /* Not Permitted */ -+#define BCME_NOMEM -27 /* No Memory */ -+#define BCME_ASSOCIATED -28 /* Associated */ -+#define BCME_RANGE -29 /* Not In Range */ -+#define BCME_NOTFOUND -30 /* Not Found */ -+#define BCME_WME_NOT_ENABLED -31 /* WME Not Enabled */ -+#define BCME_TSPEC_NOTFOUND -32 /* TSPEC Not Found */ -+#define BCME_ACM_NOTSUPPORTED -33 /* ACM Not Supported */ -+#define BCME_NOT_WME_ASSOCIATION -34 /* Not WME Association */ -+#define BCME_SDIO_ERROR -35 /* SDIO Bus Error */ -+#define BCME_DONGLE_DOWN -36 /* Dongle Not Accessible */ -+#define BCME_VERSION -37 /* Incorrect version */ -+#define BCME_TXFAIL -38 /* TX failure */ -+#define BCME_RXFAIL -39 /* RX failure */ -+#define BCME_NODEVICE -40 /* Device not present */ -+#define BCME_NMODE_DISABLED -41 /* NMODE disabled */ -+#define BCME_NONRESIDENT -42 /* access to nonresident overlay */ -+#define BCME_LAST BCME_NONRESIDENT -+ -+/* These are collection of BCME Error strings */ -+#define BCMERRSTRINGTABLE { \ -+ "OK", \ -+ "Undefined error", \ -+ "Bad Argument", \ -+ "Bad Option", \ -+ "Not up", \ -+ "Not down", \ -+ "Not AP", \ -+ "Not STA", \ -+ "Bad Key Index", \ -+ "Radio Off", \ -+ "Not band locked", \ -+ "No clock", \ -+ "Bad Rate valueset", \ -+ "Bad Band", \ -+ "Buffer too short", \ -+ "Buffer too long", \ -+ "Busy", \ -+ "Not Associated", \ -+ "Bad SSID len", \ -+ "Out of Range Channel", \ -+ "Bad Channel", \ -+ "Bad Address", \ -+ "Not Enough Resources", \ -+ "Unsupported", \ -+ "Bad length", \ -+ "Not Ready", \ -+ "Not Permitted", \ -+ "No Memory", \ -+ "Associated", \ -+ "Not In Range", \ -+ "Not Found", \ -+ "WME Not Enabled", \ -+ "TSPEC Not Found", \ -+ "ACM Not Supported", \ -+ "Not WME Association", \ -+ "SDIO Bus Error", \ -+ "Dongle Not Accessible", \ -+ "Incorrect version", \ -+ "TX Failure", \ -+ "RX Failure", \ -+ "Device Not Present", \ -+ "NMODE Disabled", \ -+ "Nonresident overlay access", \ -+} -+ -+#ifndef ABS -+#define ABS(a) (((a) < 0) ? -(a) : (a)) -+#endif /* ABS */ -+ -+#ifndef MIN -+#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -+#endif /* MIN */ -+ -+#ifndef MAX -+#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -+#endif /* MAX */ -+ -+#define CEIL(x, y) (((x) + ((y) - 1)) / (y)) -+#define ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) -+#define ISALIGNED(a, x) (((uintptr)(a) & ((x) - 1)) == 0) -+#define ALIGN_ADDR(addr, boundary) (void *)(((uintptr)(addr) + (boundary) - 1) \ -+ & ~((boundary) - 1)) -+#define ALIGN_SIZE(size, boundary) (((size) + (boundary) - 1) \ -+ & ~((boundary) - 1)) -+#define ISPOWEROF2(x) ((((x) - 1) & (x)) == 0) -+#define VALID_MASK(mask) !((mask) & ((mask) + 1)) -+ -+#ifndef OFFSETOF -+#ifdef __ARMCC_VERSION -+/* -+ * The ARM RVCT compiler complains when using OFFSETOF where a constant -+ * expression is expected, such as an initializer for a static object. -+ * offsetof from the runtime library doesn't have that problem. -+ */ -+#include -+#define OFFSETOF(type, member) offsetof(type, member) -+#else -+#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member) -+#endif /* __ARMCC_VERSION */ -+#endif /* OFFSETOF */ -+ -+#ifndef ARRAYSIZE -+#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0])) -+#endif -+ -+/* Reference a function; used to prevent a static function from being optimized out */ -+extern void *_bcmutils_dummy_fn; -+#define REFERENCE_FUNCTION(f) (_bcmutils_dummy_fn = (void *)(f)) -+ -+/* bit map related macros */ -+#ifndef setbit -+#ifndef NBBY /* the BSD family defines NBBY */ -+#define NBBY 8 /* 8 bits per byte */ -+#endif /* #ifndef NBBY */ -+#define setbit(a, i) (((uint8 *)a)[(i) / NBBY] |= 1 << ((i) % NBBY)) -+#define clrbit(a, i) (((uint8 *)a)[(i) / NBBY] &= ~(1 << ((i) % NBBY))) -+#define isset(a, i) (((const uint8 *)a)[(i) / NBBY] & (1 << ((i) % NBBY))) -+#define isclr(a, i) ((((const uint8 *)a)[(i) / NBBY] & (1 << ((i) % NBBY))) == 0) -+#endif /* setbit */ -+ -+#define NBITS(type) (sizeof(type) * 8) -+#define NBITVAL(nbits) (1 << (nbits)) -+#define MAXBITVAL(nbits) ((1 << (nbits)) - 1) -+#define NBITMASK(nbits) MAXBITVAL(nbits) -+#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8) -+ -+/* basic mux operation - can be optimized on several architectures */ -+#define MUX(pred, true, false) ((pred) ? (true) : (false)) -+ -+/* modulo inc/dec - assumes x E [0, bound - 1] */ -+#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1) -+#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1) -+ -+/* modulo inc/dec, bound = 2^k */ -+#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1)) -+#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1)) -+ -+/* modulo add/sub - assumes x, y E [0, bound - 1] */ -+#define MODADD(x, y, bound) \ -+ MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y)) -+#define MODSUB(x, y, bound) \ -+ MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y)) -+ -+/* module add/sub, bound = 2^k */ -+#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1)) -+#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1)) -+ -+/* crc defines */ -+#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ -+#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ -+#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ -+#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ -+#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */ -+#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */ -+ -+/* use for direct output of MAC address in printf etc */ -+#define MACF "%02x:%02x:%02x:%02x:%02x:%02x" -+#define ETHERP_TO_MACF(ea) ((struct ether_addr *) (ea))->octet[0], \ -+ ((struct ether_addr *) (ea))->octet[1], \ -+ ((struct ether_addr *) (ea))->octet[2], \ -+ ((struct ether_addr *) (ea))->octet[3], \ -+ ((struct ether_addr *) (ea))->octet[4], \ -+ ((struct ether_addr *) (ea))->octet[5] -+ -+#define ETHER_TO_MACF(ea) (ea).octet[0], \ -+ (ea).octet[1], \ -+ (ea).octet[2], \ -+ (ea).octet[3], \ -+ (ea).octet[4], \ -+ (ea).octet[5] -+ -+/* bcm_format_flags() bit description structure */ -+typedef struct bcm_bit_desc { -+ uint32 bit; -+ const char* name; -+} bcm_bit_desc_t; -+ -+/* tag_ID/length/value_buffer tuple */ -+typedef struct bcm_tlv { -+ uint8 id; -+ uint8 len; -+ uint8 data[1]; -+} bcm_tlv_t; -+ -+/* Check that bcm_tlv_t fits into the given buflen */ -+#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len)) -+ -+/* buffer length for ethernet address from bcm_ether_ntoa() */ -+#define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */ -+ -+/* crypto utility function */ -+/* 128-bit xor: *dst = *src1 xor *src2. dst1, src1 and src2 may have any alignment */ -+static INLINE void -+xor_128bit_block(const uint8 *src1, const uint8 *src2, uint8 *dst) -+{ -+ if ( -+#ifdef __i386__ -+ 1 || -+#endif -+ (((uintptr)src1 | (uintptr)src2 | (uintptr)dst) & 3) == 0) { -+ /* ARM CM3 rel time: 1229 (727 if alignment check could be omitted) */ -+ /* x86 supports unaligned. This version runs 6x-9x faster on x86. */ -+ ((uint32 *)dst)[0] = ((const uint32 *)src1)[0] ^ ((const uint32 *)src2)[0]; -+ ((uint32 *)dst)[1] = ((const uint32 *)src1)[1] ^ ((const uint32 *)src2)[1]; -+ ((uint32 *)dst)[2] = ((const uint32 *)src1)[2] ^ ((const uint32 *)src2)[2]; -+ ((uint32 *)dst)[3] = ((const uint32 *)src1)[3] ^ ((const uint32 *)src2)[3]; -+ } else { -+ /* ARM CM3 rel time: 4668 (4191 if alignment check could be omitted) */ -+ int k; -+ for (k = 0; k < 16; k++) -+ dst[k] = src1[k] ^ src2[k]; -+ } -+} -+ -+/* externs */ -+/* crc */ -+extern uint8 BCMROMFN(hndcrc8)(uint8 *p, uint nbytes, uint8 crc); -+extern uint16 BCMROMFN(hndcrc16)(uint8 *p, uint nbytes, uint16 crc); -+extern uint32 BCMROMFN(hndcrc32)(uint8 *p, uint nbytes, uint32 crc); -+ -+/* format/print */ -+#if defined(BCMDBG) || defined(DHD_DEBUG) || defined(BCMDBG_ERR) || \ -+ defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || defined(WLMSG_ASSOC) -+extern int bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len); -+#endif -+ -+#if defined(BCMDBG) || defined(DHD_DEBUG) || defined(BCMDBG_ERR) || \ -+ defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || defined(WLMSG_ASSOC) || \ -+ defined(WLMEDIA_PEAKRATE) -+extern int bcm_format_hex(char *str, const void *bytes, int len); -+#endif -+ -+#ifdef BCMDBG -+extern void deadbeef(void *p, size_t len); -+#endif -+extern const char *bcm_crypto_algo_name(uint algo); -+extern char *bcm_chipname(uint chipid, char *buf, uint len); -+extern char *bcm_brev_str(uint32 brev, char *buf); -+extern void printbig(char *buf); -+extern void prhex(const char *msg, uchar *buf, uint len); -+ -+/* IE parsing */ -+extern bcm_tlv_t *BCMROMFN(bcm_next_tlv)(bcm_tlv_t *elt, int *buflen); -+extern bcm_tlv_t *BCMROMFN(bcm_parse_tlvs)(void *buf, int buflen, uint key); -+extern bcm_tlv_t *BCMROMFN(bcm_parse_ordered_tlvs)(void *buf, int buflen, uint key); -+ -+/* bcmerror */ -+extern const char *bcmerrorstr(int bcmerror); -+extern bcm_tlv_t *BCMROMFN(bcm_parse_tlvs)(void *buf, int buflen, uint key); -+ -+/* multi-bool data type: set of bools, mbool is true if any is set */ -+typedef uint32 mbool; -+#define mboolset(mb, bit) ((mb) |= (bit)) /* set one bool */ -+#define mboolclr(mb, bit) ((mb) &= ~(bit)) /* clear one bool */ -+#define mboolisset(mb, bit) (((mb) & (bit)) != 0) /* TRUE if one bool is set */ -+#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val))) -+ -+/* generic datastruct to help dump routines */ -+struct fielddesc { -+ const char *nameandfmt; -+ uint32 offset; -+ uint32 len; -+}; -+ -+extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size); -+extern void bcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, uint8 *buf, int len); -+ -+extern void bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount); -+extern int bcm_cmp_bytes(const uchar *arg1, const uchar *arg2, uint8 nbytes); -+extern void bcm_print_bytes(const char *name, const uchar *cdata, int len); -+ -+typedef uint32 (*bcmutl_rdreg_rtn)(void *arg0, uint arg1, uint32 offset); -+extern uint bcmdumpfields(bcmutl_rdreg_rtn func_ptr, void *arg0, uint arg1, struct fielddesc *str, -+ char *buf, uint32 bufsize); -+extern uint BCMROMFN(bcm_bitcount)(uint8 *bitmap, uint bytelength); -+ -+extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...); -+ -+/* power conversion */ -+extern uint16 BCMROMFN(bcm_qdbm_to_mw)(uint8 qdbm); -+extern uint8 BCMROMFN(bcm_mw_to_qdbm)(uint16 mw); -+ -+extern int32 exthdr_validate(char *ptr, uint size); -+extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); -+ -+unsigned int process_nvram_vars(char *varbuf, unsigned int len); -+ -+#ifdef __cplusplus -+ } -+#endif -+ -+#endif /* _bcmutils_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/bcmwifi.h b/drivers/net/ethernet/broadcom/gmac/src/include/bcmwifi.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/bcmwifi.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/bcmwifi.h 2017-11-09 17:53:43.942304000 +0800 -@@ -0,0 +1,456 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Misc utility routines for WL and Apps -+ * This header file housing the define and function prototype use by -+ * both the wl driver, tools & Apps. -+ * -+ * $Id: bcmwifi.h 293848 2011-11-03 12:31:04Z $ -+ */ -+ -+#ifndef _bcmwifi_h_ -+#define _bcmwifi_h_ -+ -+ -+/* A chanspec holds the channel number, band, bandwidth and control sideband */ -+typedef uint16 chanspec_t; -+ -+/* channel defines */ -+#define CH_UPPER_SB 0x01 -+#define CH_LOWER_SB 0x02 -+#define CH_EWA_VALID 0x04 -+#define CH_80MHZ_APART 16 -+#define CH_40MHZ_APART 8 -+#define CH_20MHZ_APART 4 -+#define CH_10MHZ_APART 2 -+#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */ -+#define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */ -+#define MAXCHANNEL 224 /* max # supported channels. The max channel no is 216, -+ * this is that + 1 rounded up to a multiple of NBBY (8). -+ * DO NOT MAKE it > 255: channels are uint8's all over -+ */ -+#define CHSPEC_CTLOVLP(sp1, sp2, sep) ABS(wf_chspec_ctlchan(sp1) - wf_chspec_ctlchan(sp2)) < (sep) -+ -+#ifndef D11AC_IOTYPES -+ -+#define WL_CHANSPEC_CHAN_MASK 0x00ff -+#define WL_CHANSPEC_CHAN_SHIFT 0 -+ -+#define WL_CHANSPEC_CTL_SB_MASK 0x0300 -+#define WL_CHANSPEC_CTL_SB_SHIFT 8 -+#define WL_CHANSPEC_CTL_SB_LOWER 0x0100 -+#define WL_CHANSPEC_CTL_SB_UPPER 0x0200 -+#define WL_CHANSPEC_CTL_SB_NONE 0x0300 -+ -+#define WL_CHANSPEC_BW_MASK 0x0C00 -+#define WL_CHANSPEC_BW_SHIFT 10 -+#define WL_CHANSPEC_BW_10 0x0400 -+#define WL_CHANSPEC_BW_20 0x0800 -+#define WL_CHANSPEC_BW_40 0x0C00 -+ -+#define WL_CHANSPEC_BAND_MASK 0xf000 -+#define WL_CHANSPEC_BAND_SHIFT 12 -+#define WL_CHANSPEC_BAND_5G 0x1000 -+#define WL_CHANSPEC_BAND_2G 0x2000 -+#define INVCHANSPEC 255 -+ -+/* channel defines */ -+#define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? ((channel) - CH_10MHZ_APART) : 0) -+#define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \ -+ ((channel) + CH_10MHZ_APART) : 0) -+#define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX) -+#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \ -+ WL_CHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \ -+ WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) -+#define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \ -+ ((channel) + CH_20MHZ_APART) : 0) -+#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ -+ ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \ -+ ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \ -+ WL_CHANSPEC_BAND_5G)) -+#define CHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK)) -+#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) -+ -+/* chanspec stores radio channel & flags to indicate control channel location, i.e. upper/lower */ -+#define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK) -+#define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK) -+ -+#ifdef WL11N_20MHZONLY -+ -+#define CHSPEC_IS10(chspec) 0 -+#define CHSPEC_IS20(chspec) 1 -+#ifndef CHSPEC_IS40 -+#define CHSPEC_IS40(chspec) 0 -+#endif -+ -+#else /* !WL11N_20MHZONLY */ -+ -+#define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10) -+#define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) -+#ifndef CHSPEC_IS40 -+#define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40) -+#endif -+ -+#endif /* !WL11N_20MHZONLY */ -+ -+#define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) -+#define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G) -+#define CHSPEC_SB_NONE(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE) -+#define CHSPEC_SB_UPPER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) -+#define CHSPEC_SB_LOWER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) -+#define CHSPEC_CTL_CHAN(chspec) ((CHSPEC_SB_LOWER(chspec)) ? \ -+ (LOWER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \ -+ (UPPER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK)))) -+#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G) -+ -+#define CHANSPEC_STR_LEN 8 -+ -+#else /* D11AC_IOTYPES */ -+ -+#define WL_CHANSPEC_CHAN_MASK 0x00ff -+#define WL_CHANSPEC_CHAN_SHIFT 0 -+#define WL_CHANSPEC_CHAN1_MASK 0x000f -+#define WL_CHANSPEC_CHAN1_SHIFT 0 -+#define WL_CHANSPEC_CHAN2_MASK 0x00f0 -+#define WL_CHANSPEC_CHAN2_SHIFT 4 -+ -+#define WL_CHANSPEC_CTL_SB_MASK 0x0700 -+#define WL_CHANSPEC_CTL_SB_SHIFT 8 -+#define WL_CHANSPEC_CTL_SB_LLL 0x0000 -+#define WL_CHANSPEC_CTL_SB_LLU 0x0100 -+#define WL_CHANSPEC_CTL_SB_LUL 0x0200 -+#define WL_CHANSPEC_CTL_SB_LUU 0x0300 -+#define WL_CHANSPEC_CTL_SB_ULL 0x0400 -+#define WL_CHANSPEC_CTL_SB_ULU 0x0500 -+#define WL_CHANSPEC_CTL_SB_UUL 0x0600 -+#define WL_CHANSPEC_CTL_SB_UUU 0x0700 -+#define WL_CHANSPEC_CTL_SB_LL WL_CHANSPEC_CTL_SB_LLL -+#define WL_CHANSPEC_CTL_SB_LU WL_CHANSPEC_CTL_SB_LLU -+#define WL_CHANSPEC_CTL_SB_UL WL_CHANSPEC_CTL_SB_LUL -+#define WL_CHANSPEC_CTL_SB_UU WL_CHANSPEC_CTL_SB_LUU -+#define WL_CHANSPEC_CTL_SB_L WL_CHANSPEC_CTL_SB_LLL -+#define WL_CHANSPEC_CTL_SB_U WL_CHANSPEC_CTL_SB_LLU -+#define WL_CHANSPEC_CTL_SB_LOWER WL_CHANSPEC_CTL_SB_LLL -+#define WL_CHANSPEC_CTL_SB_UPPER WL_CHANSPEC_CTL_SB_LLU -+ -+#define WL_CHANSPEC_BW_MASK 0x3800 -+#define WL_CHANSPEC_BW_SHIFT 11 -+#define WL_CHANSPEC_BW_5 0x0000 -+#define WL_CHANSPEC_BW_10 0x0800 -+#define WL_CHANSPEC_BW_20 0x1000 -+#define WL_CHANSPEC_BW_40 0x1800 -+#define WL_CHANSPEC_BW_80 0x2000 -+#define WL_CHANSPEC_BW_160 0x2800 -+#define WL_CHANSPEC_BW_8080 0x3000 -+ -+#define WL_CHANSPEC_BAND_MASK 0xc000 -+#define WL_CHANSPEC_BAND_SHIFT 14 -+#define WL_CHANSPEC_BAND_2G 0x0000 -+#define WL_CHANSPEC_BAND_3G 0x4000 -+#define WL_CHANSPEC_BAND_4G 0x8000 -+#define WL_CHANSPEC_BAND_5G 0xc000 -+#define INVCHANSPEC 255 -+ -+/* channel defines */ -+#define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? \ -+ ((channel) - CH_10MHZ_APART) : 0) -+#define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \ -+ ((channel) + CH_10MHZ_APART) : 0) -+#define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX) -+#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \ -+ (((channel) <= CH_MAX_2G_CHANNEL) ? \ -+ WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) -+#define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \ -+ ((channel) + CH_20MHZ_APART) : 0) -+#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ -+ ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \ -+ ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \ -+ WL_CHANSPEC_BAND_5G)) -+#define CH80MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ -+ ((channel) | (ctlsb) | WL_CHANSPEC_BW_80 | \ -+ ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \ -+ WL_CHANSPEC_BAND_5G)) -+#define CH160MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ -+ ((channel) | (ctlsb) | WL_CHANSPEC_BW_160 | \ -+ ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \ -+ WL_CHANSPEC_BAND_5G)) -+ -+/* simple MACROs to get different fields of chanspec */ -+#define CHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK)) -+#define CHSPEC_CHAN1(chspec) ((chspec) & WL_CHANSPEC_CHAN1_MASK) -+#define CHSPEC_CHAN2(chspec) ((chspec) & WL_CHANSPEC_CHAN2_MASK) -+#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) -+#define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK) -+#define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK) -+ -+#ifdef WL11N_20MHZONLY -+ -+#define CHSPEC_IS10(chspec) 0 -+#define CHSPEC_IS20(chspec) 1 -+#ifndef CHSPEC_IS40 -+#define CHSPEC_IS40(chspec) 0 -+#endif -+#ifndef CHSPEC_IS80 -+#define CHSPEC_IS160(chspec) 0 -+#endif -+#ifndef CHSPEC_IS160 -+#define CHSPEC_IS160(chspec) 0 -+#endif -+#ifndef CHSPEC_IS8080 -+#define CHSPEC_IS8080(chspec) 0 -+#endif -+ -+#else /* !WL11N_20MHZONLY */ -+ -+#define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10) -+#define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) -+#ifndef CHSPEC_IS40 -+#define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40) -+#endif -+#ifndef CHSPEC_IS80 -+#define CHSPEC_IS80(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_80) -+#endif -+#ifndef CHSPEC_IS160 -+#define CHSPEC_IS160(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_160) -+#endif -+#ifndef CHSPEC_IS8080 -+#define CHSPEC_IS8080(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_8080) -+#endif -+ -+#endif /* !WL11N_20MHZONLY */ -+ -+#define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) -+#define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G) -+#define CHSPEC_SB_UPPER(chspec) \ -+ ((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) && \ -+ (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)) -+#define CHSPEC_SB_LOWER(chspec) \ -+ ((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) && \ -+ (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)) -+#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G) -+ -+/** -+ * Number of chars needed for wf_chspec_ntoa() destination character buffer. -+ */ -+#define CHANSPEC_STR_LEN 20 -+ -+ -+/* Legacy Chanspec defines -+ * These are the defines for the previous format of the chanspec_t -+ */ -+#define WL_LCHANSPEC_CHAN_MASK 0x00ff -+#define WL_LCHANSPEC_CHAN_SHIFT 0 -+ -+#define WL_LCHANSPEC_CTL_SB_MASK 0x0300 -+#define WL_LCHANSPEC_CTL_SB_SHIFT 8 -+#define WL_LCHANSPEC_CTL_SB_LOWER 0x0100 -+#define WL_LCHANSPEC_CTL_SB_UPPER 0x0200 -+#define WL_LCHANSPEC_CTL_SB_NONE 0x0300 -+ -+#define WL_LCHANSPEC_BW_MASK 0x0C00 -+#define WL_LCHANSPEC_BW_SHIFT 10 -+#define WL_LCHANSPEC_BW_10 0x0400 -+#define WL_LCHANSPEC_BW_20 0x0800 -+#define WL_LCHANSPEC_BW_40 0x0C00 -+ -+#define WL_LCHANSPEC_BAND_MASK 0xf000 -+#define WL_LCHANSPEC_BAND_SHIFT 12 -+#define WL_LCHANSPEC_BAND_5G 0x1000 -+#define WL_LCHANSPEC_BAND_2G 0x2000 -+ -+#define LCHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_LCHANSPEC_CHAN_MASK)) -+#define LCHSPEC_BAND(chspec) ((chspec) & WL_LCHANSPEC_BAND_MASK) -+#define LCHSPEC_CTL_SB(chspec) ((chspec) & WL_LCHANSPEC_CTL_SB_MASK) -+#define LCHSPEC_BW(chspec) ((chspec) & WL_LCHANSPEC_BW_MASK) -+#define LCHSPEC_IS10(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_10) -+#define LCHSPEC_IS20(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_20) -+#define LCHSPEC_IS40(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40) -+#define LCHSPEC_IS5G(chspec) (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_5G) -+#define LCHSPEC_IS2G(chspec) (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_2G) -+ -+#define LCHSPEC_CREATE(chan, band, bw, sb) ((uint16)((chan) | (sb) | (bw) | (band))) -+ -+#endif /* D11AC_IOTYPES */ -+ -+/* -+ * WF_CHAN_FACTOR_* constants are used to calculate channel frequency -+ * given a channel number. -+ * chan_freq = chan_factor * 500Mhz + chan_number * 5 -+ */ -+ -+/** -+ * Channel Factor for the starting frequence of 2.4 GHz channels. -+ * The value corresponds to 2407 MHz. -+ */ -+#define WF_CHAN_FACTOR_2_4_G 4814 /* 2.4 GHz band, 2407 MHz */ -+ -+/** -+ * Channel Factor for the starting frequence of 5 GHz channels. -+ * The value corresponds to 5000 MHz. -+ */ -+#define WF_CHAN_FACTOR_5_G 10000 /* 5 GHz band, 5000 MHz */ -+ -+/** -+ * Channel Factor for the starting frequence of 4.9 GHz channels. -+ * The value corresponds to 4000 MHz. -+ */ -+#define WF_CHAN_FACTOR_4_G 8000 /* 4.9 GHz band for Japan */ -+ -+/* defined rate in 500kbps */ -+#define WLC_MAXRATE 108 /* in 500kbps units */ -+#define WLC_RATE_1M 2 /* in 500kbps units */ -+#define WLC_RATE_2M 4 /* in 500kbps units */ -+#define WLC_RATE_5M5 11 /* in 500kbps units */ -+#define WLC_RATE_11M 22 /* in 500kbps units */ -+#define WLC_RATE_6M 12 /* in 500kbps units */ -+#define WLC_RATE_9M 18 /* in 500kbps units */ -+#define WLC_RATE_12M 24 /* in 500kbps units */ -+#define WLC_RATE_18M 36 /* in 500kbps units */ -+#define WLC_RATE_24M 48 /* in 500kbps units */ -+#define WLC_RATE_36M 72 /* in 500kbps units */ -+#define WLC_RATE_48M 96 /* in 500kbps units */ -+#define WLC_RATE_54M 108 /* in 500kbps units */ -+ -+#define WLC_2G_25MHZ_OFFSET 5 /* 2.4GHz band channel offset */ -+ -+/** -+ * Convert chanspec to ascii string -+ * -+ * @param chspec chanspec format -+ * @param buf ascii string of chanspec -+ * -+ * @return pointer to buf with room for at least CHANSPEC_STR_LEN bytes -+ * -+ * @see CHANSPEC_STR_LEN -+ */ -+extern char * wf_chspec_ntoa(chanspec_t chspec, char *buf); -+ -+/** -+ * Convert ascii string to chanspec -+ * -+ * @param a pointer to input string -+ * -+ * @return >= 0 if successful or 0 otherwise -+ */ -+extern chanspec_t wf_chspec_aton(const char *a); -+ -+/** -+ * Verify the chanspec fields are valid. -+ * -+ * Verify the chanspec is using a legal set field values, i.e. that the chanspec -+ * specified a band, bw, ctl_sb and channel and that the combination could be -+ * legal given some set of circumstances. -+ * -+ * @param chanspec input chanspec to verify -+ * -+ * @return TRUE if the chanspec is malformed, FALSE if it looks good. -+ */ -+extern bool wf_chspec_malformed(chanspec_t chanspec); -+ -+/** -+ * Verify the chanspec specifies a valid channel according to 802.11. -+ * -+ * @param chanspec input chanspec to verify -+ * -+ * @return TRUE if the chanspec is a valid 802.11 channel -+ */ -+extern bool wf_chspec_valid(chanspec_t chanspec); -+ -+/** -+ * Return the primary (control) channel. -+ * -+ * This function returns the channel number of the primary 20MHz channel. For -+ * 20MHz channels this is just the channel number. For 40MHz or wider channels -+ * it is the primary 20MHz channel specified by the chanspec. -+ * -+ * @param chspec input chanspec -+ * -+ * @return Returns the channel number of the primary 20MHz channel -+ */ -+extern uint8 wf_chspec_ctlchan(chanspec_t chspec); -+ -+/** -+ * Return the primary (control) chanspec. -+ * -+ * This function returns the chanspec of the primary 20MHz channel. For 20MHz -+ * channels this is just the chanspec. For 40MHz or wider channels it is the -+ * chanspec of the primary 20MHZ channel specified by the chanspec. -+ * -+ * @param chspec input chanspec -+ * -+ * @return Returns the chanspec of the primary 20MHz channel -+ */ -+extern chanspec_t wf_chspec_ctlchspec(chanspec_t chspec); -+ -+/** -+ * Return a channel number corresponding to a frequency. -+ * -+ * Return the channel number for a given frequency and base frequency. -+ * The returned channel number is relative to the given base frequency. -+ * If the given base frequency is zero, a base frequency of 5 GHz is assumed for -+ * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz. -+ * -+ * Frequency is specified in MHz. -+ * The base frequency is specified as (start_factor * 500 kHz). -+ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for -+ * 2.4 GHz and 5 GHz bands. -+ * -+ * The returned channel will be in the range [1, 14] in the 2.4 GHz band -+ * and [0, 200] otherwise. -+ * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the -+ * frequency is not a 2.4 GHz channel, or if the frequency is not and even -+ * multiple of 5 MHz from the base frequency to the base plus 1 GHz. -+ * -+ * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2 -+ * -+ * @param freq frequency in MHz -+ * @param start_factor base frequency in 500 kHz units, e.g. 10000 for 5 GHz -+ * -+ * @return Returns a channel number -+ * -+ * @see WF_CHAN_FACTOR_2_4_G -+ * @see WF_CHAN_FACTOR_5_G -+ */ -+extern int wf_mhz2channel(uint freq, uint start_factor); -+ -+/** -+ * Return the center frequency in MHz of the given channel and base frequency. -+ * -+ * Return the center frequency in MHz of the given channel and base frequency. -+ * The channel number is interpreted relative to the given base frequency. -+ * -+ * The valid channel range is [1, 14] in the 2.4 GHz band and [0, 200] otherwise. -+ * The base frequency is specified as (start_factor * 500 kHz). -+ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for -+ * 2.4 GHz and 5 GHz bands. -+ * The channel range of [1, 14] is only checked for a start_factor of -+ * WF_CHAN_FACTOR_2_4_G (4814). -+ * Odd start_factors produce channels on .5 MHz boundaries, in which case -+ * the answer is rounded down to an integral MHz. -+ * -1 is returned for an out of range channel. -+ * -+ * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2 -+ * -+ * @param channel input channel number -+ * @param start_factor base frequency in 500 kHz units, e.g. 10000 for 5 GHz -+ * -+ * @return Returns a frequency in MHz -+ * -+ * @see WF_CHAN_FACTOR_2_4_G -+ * @see WF_CHAN_FACTOR_5_G -+ */ -+extern int wf_channel2mhz(uint channel, uint start_factor); -+ -+#endif /* _bcmwifi_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/compvers.sh b/drivers/net/ethernet/broadcom/gmac/src/include/compvers.sh ---- a/drivers/net/ethernet/broadcom/gmac/src/include/compvers.sh 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/compvers.sh 2017-11-09 17:53:43.943304000 +0800 -@@ -0,0 +1,133 @@ -+#!/bin/bash -+# -+# Given a list of components, generate _version.h -+# from version.h.in in 's directory -+# -+# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+# -+# 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. -+# -+# -+ -+# Optional argument -+ACTION=$1 -+[ -n "$VERBOSE" ] && export VERBOSE -+ -+SRCBASE=.. -+ -+# List of components -+# TODO: In the long term component versioning model, following list -+# TODO: or table of components will come from a central file -+COMPONENTS=( \ -+ upnp \ -+ phy \ -+ router \ -+ wps \ -+) -+ -+# Component dirs. Need one entry for each of above COMPONENTS -+COMPONENT_DIR_upnp=${SRCBASE}/router/libupnp/include -+COMPONENT_DIR_phy=${SRCBASE}/wl/phy -+COMPONENT_DIR_router=${SRCBASE}/router/shared -+COMPONENT_DIR_wps=${SRCBASE}/wps/common/include -+ -+# For a given component, query automerger for a different -+# path than COMPONENT_DIR_. -+# Force router component to be pointing to local branch or tag. -+COMPONENT_QUERY_router=src_force_local_component -+ -+ -+ -+# ===== DO NOT CHANGE ANYTHING BELOW THIS LINE ===== -+ -+NULL=/dev/null -+MKCOMPVER=${SRCBASE}/tools/release/mkversion.sh -+MERGERLOG=${SRCBASE}/../merger_sources.log -+ -+# TODO: Post svn transition, network paths will be taken away -+GETCOMPVER=getcompver.py -+GETCOMPVER_NET=/projects/hnd_software/gallery/src/tools/build/$GETCOMPVER -+GETCOMPVER_NET_WIN=Z:${GETCOMPVER_NET} -+ -+# -+# If there is a local copy GETCOMPVER use it ahead of network copy -+# -+if [ -s "$GETCOMPVER" ]; then -+ GETCOMPVER_PATH="$GETCOMPVER" -+elif [ -s "${SRCBASE}/../src/tools/build/$GETCOMPVER" ]; then -+ GETCOMPVER_PATH="${SRCBASE}/../src/tools/build/$GETCOMPVER" -+elif [ -s "$GETCOMPVER_NET" ]; then -+ GETCOMPVER_PATH="$GETCOMPVER_NET" -+elif [ -s "$GETCOMPVER_NET_WIN" ]; then -+ GETCOMPVER_PATH="$GETCOMPVER_NET_WIN" -+fi -+ -+# -+# If $GETCOMPVER isn't found, fetch it from SVN -+# (this is very rare) -+# -+if [ ! -s "$GETCOMPVER_PATH" ]; then -+ svn export -q \ -+ ^/proj/trunk/src/tools/build/${GETCOMPVER} \ -+ ${GETCOMPVER} 2> $NULL -+ GETCOMPVER_PATH=$GETCOMPVER -+fi -+ -+# -+# Now walk through each specified component to generate its -+# component_version.h file from version.h.in template -+# -+for component in ${COMPONENTS[*]} -+do -+ # Get relative path of component from current dir -+ tmp="COMPONENT_DIR_$component" -+ eval rel_path=\$$tmp -+ -+ # Get query path for component -+ tmp="COMPONENT_QUERY_$component" -+ eval query_path=\$$tmp -+ -+ if [ ! -d "$rel_path" ]; then -+ continue -+ fi -+ -+ if [ "$query_path" != "" ]; then -+ abs_path=$(echo $query_path | sed -e "s%\.\.%src%g") -+ else -+ abs_path=$(echo $rel_path | sed -e "s%\.\.%src%g") -+ fi -+ -+ [ -n "$VERBOSE" ] && \ -+ echo "DBG: python $GETCOMPVER_PATH $MERGERLOG $abs_path" -+ -+ tag=$(python $GETCOMPVER_PATH $MERGERLOG $abs_path 2> $NULL | sed -e 's/[[:space:]]*//g') -+ -+ template=$rel_path/version.h.in -+ verfile=$rel_path/${component}_version.h -+ -+ if [ "$ACTION" == "clean" ]; then -+ rm -fv $verfile -+ continue -+ fi -+ -+ # MKCOMPVER always has defaults if tag isn't set correctly -+ if [ ! -f "$verfile" -o "$FORCE" != "" ]; then -+ echo "" -+ echo ">>> Generate $abs_path/${component}_version.h from $tag" -+ -+ [ -n "$VERBOSE" ] && \ -+ echo "DBG: bash $MKCOMPVER $template $verfile $tag" -+ -+ bash $MKCOMPVER $template $verfile $tag -+ fi -+done -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/epivers.h b/drivers/net/ethernet/broadcom/gmac/src/include/epivers.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/epivers.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/epivers.h 2017-11-09 17:53:43.944299000 +0800 -@@ -0,0 +1,45 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * $Id: epivers.h.in,v 13.33 2010-09-08 22:08:53 $ -+*/ -+ -+#ifndef _epivers_h_ -+#define _epivers_h_ -+ -+#define EPI_MAJOR_VERSION 6 -+ -+#define EPI_MINOR_VERSION 30 -+ -+#define EPI_RC_NUMBER 40 -+ -+#define EPI_INCREMENTAL_NUMBER 0 -+ -+#define EPI_BUILD_NUMBER 2 -+ -+#define EPI_VERSION 6, 30, 40, 0 -+ -+#define EPI_VERSION_NUM 0x061e2800 -+ -+#define EPI_VERSION_DEV 6.30.40 -+ -+/* Driver Version String, ASCII, 32 chars max */ -+#ifdef WLTEST -+#define EPI_VERSION_STR "6.30.40 (TOB) (r WLTEST)" -+#else -+#define EPI_VERSION_STR "6.30.40 (TOB) (r)" -+#endif -+ -+#endif /* _epivers_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/epivers.h.in b/drivers/net/ethernet/broadcom/gmac/src/include/epivers.h.in ---- a/drivers/net/ethernet/broadcom/gmac/src/include/epivers.h.in 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/epivers.h.in 2017-11-09 17:53:43.945295000 +0800 -@@ -0,0 +1,46 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * $Id: epivers.h.in,v 13.33 2010-09-08 22:08:53 $ -+ * -+*/ -+ -+#ifndef _epivers_h_ -+#define _epivers_h_ -+ -+#define EPI_MAJOR_VERSION @EPI_MAJOR_VERSION@ -+ -+#define EPI_MINOR_VERSION @EPI_MINOR_VERSION@ -+ -+#define EPI_RC_NUMBER @EPI_RC_NUMBER@ -+ -+#define EPI_INCREMENTAL_NUMBER @EPI_INCREMENTAL_NUMBER@ -+ -+#define EPI_BUILD_NUMBER @EPI_BUILD_NUMBER@ -+ -+#define EPI_VERSION @EPI_VERSION@ -+ -+#define EPI_VERSION_NUM @EPI_VERSION_NUM@ -+ -+#define EPI_VERSION_DEV @EPI_VERSION_DEV@ -+ -+/* Driver Version String, ASCII, 32 chars max */ -+#ifdef WLTEST -+#define EPI_VERSION_STR "@EPI_VERSION_STR@@EPI_VERSION_TYPE@ (@VC_VERSION_NUM@ WLTEST)" -+#else -+#define EPI_VERSION_STR "@EPI_VERSION_STR@@EPI_VERSION_TYPE@ (@VC_VERSION_NUM@)" -+#endif -+ -+#endif /* _epivers_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/epivers.sh b/drivers/net/ethernet/broadcom/gmac/src/include/epivers.sh ---- a/drivers/net/ethernet/broadcom/gmac/src/include/epivers.sh 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/epivers.sh 2017-11-09 17:53:43.946291000 +0800 -@@ -0,0 +1,309 @@ -+#! /bin/bash -+# -+# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+# -+# 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. -+# -+# Create the epivers.h file from epivers.h.in -+# -+# Epivers.h generation mechanism supports svn based checkouts -+# -+# $Id: epivers.sh 299409 2011-11-30 00:52:43Z $ -+# -+# GetCompVer.py return value and action needed -+# i. trunk => use current date as version string -+# ii. local => use SVNURL expanded by HeadURL keyword -+# iii. => use it as as is -+# (some components can override and say give me native ver) -+# iv. empty => -+# a) If TAG is specified use it -+# a) If no TAG is specified use date -+# -+ -+# If the version header file already exists, increment its build number. -+# Otherwise, create a new file. -+if [ -f epivers.h ]; then -+ -+ # If REUSE_VERSION is set, epivers iteration is not incremented -+ # This can be used precommit and continuous integration projects -+ if [ -n "$REUSE_VERSION" ]; then -+ echo "Previous epivers.h exists. Skipping version increment" -+ exit 0 -+ fi -+ -+ build=`grep EPI_BUILD_NUMBER epivers.h | sed -e "s,.*BUILD_NUMBER[ ]*,,"` -+ build=`expr ${build} + 1` -+ echo build=${build} -+ sed -e "s,.*_BUILD_NUMBER.*,#define EPI_BUILD_NUMBER ${build}," \ -+ < epivers.h > epivers.h.new -+ mv epivers.h epivers.h.prev -+ mv epivers.h.new epivers.h -+ exit 0 -+ -+else # epivers.h doesn't exist -+ -+ NULL="/dev/null" -+ svncmd="svn --non-interactive" -+ -+ # Check for the in file, if not there we're in the wrong directory -+ if [ ! -f epivers.h.in ]; then -+ echo "ERROR: No epivers.h.in found" -+ exit 1 -+ fi -+ -+ # Following SVNURL should be expanded on checkout -+ SVNURL='$HeadURL: http://svn.sj.broadcom.com/svn/wlansvn/users/kenlo/northstar/AARDVARK_TWIG_6_30_40/src/include/epivers.sh $' -+ -+ # If SVNURL isn't expanded, extract it from svn info -+ if echo "$SVNURL" | grep -vq '$.*HeadURL.*epivers.sh.*$'; then -+ [ -n "$VERBOSE" ] && \ -+ echo "DBG: SVN URL wasn't expanded. Getting it from svn info" -+ SVNURL=$($svncmd info epivers.sh 2> $NULL | egrep "^URL:") -+ fi -+ -+ if echo "${TAG}" | grep -q "_BRANCH_\|_TWIG_"; then -+ branchtag=$TAG -+ else -+ branchtag="" -+ fi -+ -+ # If this is a tagged build, use the tag to supply the numbers -+ # Tag should be in the form -+ # _REL__ -+ # or -+ # _REL___RC -+ # or -+ # _REL___RC_ -+ -+ SRCBASE=.. -+ MERGERLOG=${SRCBASE}/../merger_sources.log -+ GETCOMPVER=getcompver.py -+ GETCOMPVER_NET=/projects/hnd_software/gallery/src/tools/build/$GETCOMPVER -+ GETCOMPVER_NET_WIN=Z:${GETCOMPVER_NET} -+ -+ # -+ # If there is a local copy GETCOMPVER use it ahead of network copy -+ # -+ if [ -s "$GETCOMPVER" ]; then -+ GETCOMPVER_PATH="$GETCOMPVER" -+ elif [ -s "${SRCBASE}/../src/tools/build/$GETCOMPVER" ]; then -+ GETCOMPVER_PATH="${SRCBASE}/../src/tools/build/$GETCOMPVER" -+ elif [ -s "$GETCOMPVER_NET" ]; then -+ GETCOMPVER_PATH="$GETCOMPVER_NET" -+ elif [ -s "$GETCOMPVER_NET_WIN" ]; then -+ GETCOMPVER_PATH="$GETCOMPVER_NET_WIN" -+ fi -+ -+ # -+ # If $GETCOMPVER isn't found, fetch it from SVN -+ # (this should be very rare) -+ # -+ if [ ! -s "$GETCOMPVER_PATH" ]; then -+ [ -n "$VERBOSE" ] && \ -+ echo "DBG: Fetching $GETCOMPVER from trunk" -+ -+ $svncmd export -q \ -+ ^/proj/trunk/src/tools/build/${GETCOMPVER} \ -+ ${GETCOMPVER} 2> $NULL -+ -+ GETCOMPVER_PATH=$GETCOMPVER -+ fi -+ -+ # Now get tag for src/include from automerger log -+ [ -n "$VERBOSE" ] && \ -+ echo "DBG: python $GETCOMPVER_PATH $MERGERLOG src/include" -+ -+ COMPTAG=$(python $GETCOMPVER_PATH $MERGERLOG src/include 2> $NULL | sed -e 's/[[:space:]]*//g') -+ -+ echo "DBG: Component Tag String Derived = $COMPTAG" -+ -+ # Process COMPTAG values -+ # Rule: -+ # If trunk is returned, use date as component tag -+ # If LOCAL_COMPONENT is returned, use SVN URL to get native tag -+ # If component is returned or empty, assign it to SVNTAG -+ # GetCompVer.py return value and action needed -+ # i. trunk => use current date as version string -+ # ii. local => use SVNURL expanded by HeadURL keyword -+ # iii. => use it as as is -+ # iv. empty => -+ # a) If TAG is specified use it -+ # a) If no TAG is specified use SVNURL from HeadURL -+ -+ SVNURL_VER=false -+ -+ if [ "$COMPTAG" == "" ]; then -+ SVNURL_VER=true -+ elif [ "$COMPTAG" == "LOCAL_COMPONENT" ]; then -+ SVNURL_VER=true -+ elif [ "$COMPTAG" == "trunk" ]; then -+ SVNTAG=$(date '+TRUNKCOMP_REL_%Y_%m_%d') -+ else -+ SVNTAG=$COMPTAG -+ fi -+ -+ # Given SVNURL path conventions or naming conventions, derive SVNTAG -+ # TO-DO: SVNTAG derivation logic can move to a central common API -+ # TO-DO: ${SRCBASE}/tools/build/svnurl2tag.sh -+ if [ "$SVNURL_VER" == "true" ]; then -+ case "${SVNURL}" in -+ */branches/*) -+ SVNTAG=$(echo $SVNURL | sed -e 's%.*/branches/\(.*\)/src.*%\1%g' | xargs printf "%s") -+ ;; -+ *_BRANCH_*) -+ SVNTAG=$(echo $SVNURL | sed -e 's%/%\n%g' | egrep _BRANCH_ | xargs printf "%s") -+ ;; -+ *_TWIG_*) -+ SVNTAG=$(echo $SVNURL | sed -e 's%/%\n%g' | egrep _TWIG_ | xargs printf "%s") -+ ;; -+ */tags/*) -+ SVNTAG=$(echo $SVNURL | sed -e 's%.*/tags/.*/\(.*\)/src.*%\1%g' | xargs printf "%s") -+ ;; -+ *_REL_*) -+ SVNTAG=$(echo $SVNURL | sed -e 's%/%\n%g' | egrep _REL_ | xargs printf "%s") -+ ;; -+ */trunk/*) -+ SVNTAG=$(date '+TRUNKURL_REL_%Y_%m_%d') -+ ;; -+ *) -+ SVNTAG=$(date '+OTHER_REL_%Y_%m_%d') -+ ;; -+ esac -+ echo "DBG: Native Tag String Derived from URL: $SVNTAG" -+ else -+ echo "DBG: Native Tag String Derived: $SVNTAG" -+ fi -+ -+ TAG=${SVNTAG} -+ -+ # Normalize the branch name portion to "D11" in case it has underscores in it -+ branch_name=`expr match "$TAG" '\(.*\)_\(BRANCH\|TWIG\|REL\)_.*'` -+ TAG=`echo $TAG | sed -e "s%^$branch_name%D11%"` -+ -+ # Split the tag into an array on underbar or whitespace boundaries. -+ IFS="_ " tag=(${TAG}) -+ unset IFS -+ -+ tagged=1 -+ if [ ${#tag[*]} -eq 0 ]; then -+ tag=(`date '+TOT REL %Y %m %d 0 %y'`); -+ # reconstruct a TAG from the date -+ TAG=${tag[0]}_${tag[1]}_${tag[2]}_${tag[3]}_${tag[4]}_${tag[5]} -+ tagged=0 -+ fi -+ -+ # Allow environment variable to override values. -+ # Missing values default to 0 -+ # -+ maj=${EPI_MAJOR_VERSION:-${tag[2]:-0}} -+ min=${EPI_MINOR_VERSION:-${tag[3]:-0}} -+ rcnum=${EPI_RC_NUMBER:-${tag[4]:-0}} -+ -+ # If increment field is 0, set it to date suffix if on TOB -+ if [ -n "$branchtag" ]; then -+ [ "${tag[5]:-0}" -eq 0 ] && echo "Using date suffix for incr" -+ today=`date '+%Y%m%d'` -+ incremental=${EPI_INCREMENTAL_NUMBER:-${tag[5]:-${today:-0}}} -+ else -+ incremental=${EPI_INCREMENTAL_NUMBER:-${tag[5]:-0}} -+ fi -+ origincr=${EPI_INCREMENTAL_NUMBER:-${tag[5]:-0}} -+ build=${EPI_BUILD_NUMBER:-0} -+ -+ # Strip 'RC' from front of rcnum if present -+ rcnum=${rcnum/#RC/} -+ -+ # strip leading zero off the number (otherwise they look like octal) -+ maj=${maj/#0/} -+ min=${min/#0/} -+ rcnum=${rcnum/#0/} -+ incremental=${incremental/#0/} -+ origincr=${origincr/#0/} -+ build=${build/#0/} -+ -+ # some numbers may now be null. replace with with zero. -+ maj=${maj:-0} -+ min=${min:-0} -+ -+ rcnum=${rcnum:-0} -+ incremental=${incremental:-0} -+ origincr=${origincr:-0} -+ build=${build:-0} -+ -+ if [ ${tagged} -eq 1 ]; then -+ # vernum is 32chars max -+ vernum=`printf "0x%02x%02x%02x%02x" ${maj} ${min} ${rcnum} ${origincr}` -+ else -+ vernum=`printf "0x00%02x%02x%02x" ${tag[7]} ${min} ${rcnum}` -+ fi -+ -+ # make sure the size of vernum is under 32 bits. -+ # Otherwise, truncate. The string will keep full information. -+ vernum=${vernum:0:10} -+ -+ # build the string directly from the tag, irrespective of its length -+ # remove the name , the tag type, then replace all _ by . -+ tag_ver_str=${TAG/${tag[0]}_} -+ tag_ver_str=${tag_ver_str/${tag[1]}_} -+ tag_ver_str=${tag_ver_str//_/.} -+ -+ # record tag type -+ tagtype= -+ -+ if [ "${tag[1]}" = "BRANCH" -o "${tag[1]}" = "TWIG" ]; then -+ tagtype=" (TOB)" -+ echo "tag type: $tagtype" -+ fi -+ -+ echo "Effective version string: $tag_ver_str" -+ -+ if [ "$(uname -s)" == "Darwin" ]; then -+ # Mac does not like 2-digit numbers so convert the number to single -+ # digit. 5.100 becomes 5.1 -+ if [ $min -gt 99 ]; then -+ minmac=`expr $min / 100` -+ else -+ minmac=$min -+ fi -+ epi_ver_dev="${maj}.${minmac}.0" -+ else -+ epi_ver_dev="${maj}.${min}.${rcnum}" -+ fi -+ -+ # Finally get version control revision number of (if any) -+ vc_version_num=$($svncmd info ${SRCBASE} 2> $NULL | awk -F': ' '/^Revision: /{printf "%s", $2}') -+ -+ # OK, go do it -+ echo "maj=${maj}, min=${min}, rc=${rcnum}, inc=${incremental}, build=${build}" -+ -+ sed \ -+ -e "s;@EPI_MAJOR_VERSION@;${maj};" \ -+ -e "s;@EPI_MINOR_VERSION@;${min};" \ -+ -e "s;@EPI_RC_NUMBER@;${rcnum};" \ -+ -e "s;@EPI_INCREMENTAL_NUMBER@;${incremental};" \ -+ -e "s;@EPI_BUILD_NUMBER@;${build};" \ -+ -e "s;@EPI_VERSION@;${maj}, ${min}, ${rcnum}, ${incremental};" \ -+ -e "s;@EPI_VERSION_STR@;${tag_ver_str};" \ -+ -e "s;@EPI_VERSION_TYPE@;${tagtype};" \ -+ -e "s;@VERSION_TYPE@;${tagtype};" \ -+ -e "s;@EPI_VERSION_NUM@;${vernum};" \ -+ -e "s;@EPI_VERSION_DEV@;${epi_ver_dev};" \ -+ -e "s;@VC_VERSION_NUM@;r${vc_version_num};" \ -+ < epivers.h.in > epivers.h -+ -+ # In shared workspaces across different platforms, ensure that -+ # windows generated file is made platform neutral without CRLF -+ if uname -s | egrep -i -q "cygwin"; then -+ dos2unix epivers.h > $NULL 2>&1 -+ fi -+fi # epivers.h -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/etioctl.h b/drivers/net/ethernet/broadcom/gmac/src/include/etioctl.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/etioctl.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/etioctl.h 2017-11-09 17:53:43.951293000 +0800 -@@ -0,0 +1,158 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * BCM44XX Ethernet Windows device driver custom OID definitions. -+ * -+ * $Id: etioctl.h 322208 2012-03-20 01:53:23Z $ -+ */ -+ -+#ifndef _etioctl_h_ -+#define _etioctl_h_ -+ -+/* -+ * Minor kludge alert: -+ * Duplicate a few definitions that irelay requires from epiioctl.h here -+ * so caller doesn't have to include this file and epiioctl.h . -+ * If this grows any more, it would be time to move these irelay-specific -+ * definitions out of the epiioctl.h and into a separate driver common file. -+ */ -+#ifndef EPICTRL_COOKIE -+#define EPICTRL_COOKIE 0xABADCEDE -+#endif -+ -+/* common ioctl definitions */ -+#define ETCUP 0 -+#define ETCDOWN 1 -+#define ETCLOOP 2 -+#define ETCDUMP 3 -+#define ETCSETMSGLEVEL 4 -+#define ETCPROMISC 5 -+#define ETCVAR 6 -+#define ETCSPEED 7 -+#define ETCPHYRD 9 -+#define ETCPHYWR 10 -+#define ETCQOS 11 -+#define ETCPHYRD2 12 -+#define ETCPHYWR2 13 -+#define ETCROBORD 14 -+#define ETCROBOWR 15 -+ -+/* -+ * A set of iovars defined for ET set/get -+ */ -+#define IOV_ET_POWER_SAVE_MODE 1 -+#define IOV_ET_CLEAR_DUMP 2 -+#define IOV_ET_ROBO_DEVID 3 -+#define IOV_PKTC 4 -+#define IOV_PKTCBND 5 -+#define IOV_COUNTERS 6 -+#define IOV_DUMP_CTF 7 -+ -+#if defined(linux) || defined(__ECOS) -+#define SIOCSETCUP (SIOCDEVPRIVATE + ETCUP) -+#define SIOCSETCDOWN (SIOCDEVPRIVATE + ETCDOWN) -+#define SIOCSETCLOOP (SIOCDEVPRIVATE + ETCLOOP) -+#define SIOCGETCDUMP (SIOCDEVPRIVATE + ETCDUMP) -+#define SIOCSETCSETMSGLEVEL (SIOCDEVPRIVATE + ETCSETMSGLEVEL) -+#define SIOCSETCPROMISC (SIOCDEVPRIVATE + ETCPROMISC) -+#define SIOCSETGETVAR (SIOCDEVPRIVATE + ETCVAR) -+#define SIOCSETCSPEED (SIOCDEVPRIVATE + ETCSPEED) -+#define SIOCTXGEN (SIOCDEVPRIVATE + 8) -+#define SIOCGETCPHYRD (SIOCDEVPRIVATE + ETCPHYRD) -+#define SIOCSETCPHYWR (SIOCDEVPRIVATE + ETCPHYWR) -+#define SIOCSETCQOS (SIOCDEVPRIVATE + ETCQOS) -+#define SIOCGETCPHYRD2 (SIOCDEVPRIVATE + ETCPHYRD2) -+#define SIOCSETCPHYWR2 (SIOCDEVPRIVATE + ETCPHYWR2) -+#define SIOCGETCROBORD (SIOCDEVPRIVATE + ETCROBORD) -+#define SIOCSETCROBOWR (SIOCDEVPRIVATE + ETCROBOWR) -+ -+/* structure to send a generic var set/get */ -+typedef struct et_var_s { -+ uint cmd; -+ uint set; -+ void *buf; -+ uint len; -+} et_var_t; -+ -+/* arg to SIOCTXGEN */ -+struct txg { -+ uint32 num; /* number of frames to send */ -+ uint32 delay; /* delay in microseconds between sending each */ -+ uint32 size; /* size of ether frame to send */ -+ uchar buf[1514]; /* starting ether frame data */ -+}; -+#endif /* linux */ -+ -+ -+#if defined(__NetBSD__) -+#define SIOCSETCUP _IOW('e', 0, struct ifreq) -+#define SIOCSETCDOWN _IOW('e', 1, struct ifreq) -+#define SIOCSETCLOOP _IOW('e', 2, struct ifreq) -+#define SIOCGETCDUMP _IOWR('e', 3, struct ifreq) -+#define SIOCSETCSETMSGLEVEL _IOW('e', 4, struct ifreq) -+#define SIOCSETCPROMISC _IOW('e', 5, struct ifreq) -+#define SIOCSETCTXDOWN _IOW('e', 6, struct ifreq) /* obsolete */ -+#define SIOCSETCSPEED _IOW('e', 7, struct ifreq) -+#define SIOCTXGEN _IOW('e', 8, struct ifreq) -+#define SIOCGETCPHYRD _IOWR('e', 9, struct ifreq) -+#define SIOCSETCPHYWR _IOW('e', 10, struct ifreq) -+#define SIOCSETCQOS _IOW('e', 11, struct ifreq) -+#define SIOCGETCPHYRD2 _IOWR('e', 12, struct ifreq) -+#define SIOCSETCPHYWR2 _IOW('e', 13, struct ifreq) -+#define SIOCGETCROBORD _IOWR('e', 14, struct ifreq) -+#define SIOCSETCROBOWR _IOW('e', 15, struct ifreq) -+ -+/* arg to SIOCTXGEN */ -+struct txg { -+ uint32 num; /* number of frames to send */ -+ uint32 delay; /* delay in microseconds between sending each */ -+ uint32 size; /* size of ether frame to send */ -+ uchar buf[1514]; /* starting ether frame data */ -+}; -+#endif /* __NetBSD__ */ -+ -+/* -+ * custom OID support -+ * -+ * 0xFF - implementation specific OID -+ * 0xE4 - first byte of Broadcom PCI vendor ID -+ * 0x14 - second byte of Broadcom PCI vendor ID -+ * 0xXX - the custom OID number -+ */ -+#define ET_OID_BASE 0xFFE41400 /* OID Base for ET */ -+ -+#define OID_ET_UP (ET_OID_BASE + ETCUP) -+#define OID_ET_DOWN (ET_OID_BASE + ETCDOWN) -+#define OID_ET_LOOP (ET_OID_BASE + ETCLOOP) -+#define OID_ET_DUMP (ET_OID_BASE + ETCDUMP) -+#define OID_ET_SETMSGLEVEL (ET_OID_BASE + ETCSETMSGLEVEL) -+#define OID_ET_PROMISC (ET_OID_BASE + ETCPROMISC) -+#define OID_ET_TXDOWN (ET_OID_BASE + 6) -+#define OID_ET_SPEED (ET_OID_BASE + ETCSPEED) -+#define OID_ET_GETINSTANCE (ET_OID_BASE + 8) -+#define OID_ET_SETCALLBACK (ET_OID_BASE + 9) -+#define OID_ET_UNSETCALLBACK (ET_OID_BASE + 10) -+ -+#define IS_ET_OID(oid) (((oid) & 0xFFFFFF00) == 0xFFE41400) -+ -+#define ET_ISQUERYOID(oid) ((oid == OID_ET_DUMP) || (oid == OID_ET_GETINSTANCE)) -+ -+/* OID_ET_SETCALLBACK data type */ -+typedef struct et_cb { -+ void (*fn)(void *, int); /* Callback function */ -+ void *context; /* Passed to callback function */ -+} et_cb_t; -+ -+#endif /* _etioctl_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/gmac_common.h b/drivers/net/ethernet/broadcom/gmac/src/include/gmac_common.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/gmac_common.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/gmac_common.h 2017-11-09 17:53:43.959311000 +0800 -@@ -0,0 +1,560 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * gmacdefs - Broadcom gmac (Unimac) specific definitions -+ * -+ * $Id: gmac_common.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _gmac_common_core_h_ -+#define _gmac_common_core_h_ -+ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD XSTR(__LINE__) -+#endif -+ -+typedef volatile struct _gmac_commonregs { -+ uint32 stag0; -+ uint32 stag1; -+ uint32 stag2; -+ uint32 stag3; -+ uint32 PAD[4]; -+ uint32 parsercontrol; -+ uint32 mib_max_len; -+ uint32 PAD[54]; -+ uint32 phyaccess; -+ uint32 phycontrol; -+ uint32 PAD[2]; -+ uint32 gmac0_rgmii_cntl; -+ uint32 PAD[59]; -+ uint32 cfp_access; -+ uint32 PAD[3]; -+ uint32 cfp_tcam_data0; -+ uint32 cfp_tcam_data1; -+ uint32 cfp_tcam_data2; -+ uint32 cfp_tcam_data3; -+ uint32 cfp_tcam_data4; -+ uint32 cfp_tcam_data5; -+ uint32 cfp_tcam_data6; -+ uint32 cfp_tcam_data7; -+ uint32 cfp_tcam_mask0; -+ uint32 cfp_tcam_mask1; -+ uint32 cfp_tcam_mask2; -+ uint32 cfp_tcam_mask3; -+ uint32 cfp_tcam_mask4; -+ uint32 cfp_tcam_mask5; -+ uint32 cfp_tcam_mask6; -+ uint32 cfp_tcam_mask7; -+ uint32 cfp_action_data; -+ uint32 PAD[19]; -+ uint32 tcam_bist_cntl; -+ uint32 tcam_bist_status; -+ uint32 tcam_cmp_status; -+ uint32 tcam_disable; -+ uint32 PAD[16]; -+ uint32 tcam_test_cntl; -+ uint32 PAD[3]; -+ uint32 udf_0_a3_a0; -+ uint32 udf_0_a7_a4; -+ uint32 udf_0_a8; -+ uint32 PAD[1]; -+ uint32 udf_1_a3_a0; -+ uint32 udf_1_a7_a4; -+ uint32 udf_1_a8; -+ uint32 PAD[1]; -+ uint32 udf_2_a3_a0; -+ uint32 udf_2_a7_a4; -+ uint32 udf_2_a8; -+ uint32 PAD[1]; -+ uint32 udf_0_b3_b0; -+ uint32 udf_0_b7_b4; -+ uint32 udf_0_b8; -+ uint32 PAD[1]; -+ uint32 udf_1_b3_b0; -+ uint32 udf_1_b7_b4; -+ uint32 udf_1_b8; -+ uint32 PAD[1]; -+ uint32 udf_2_b3_b0; -+ uint32 udf_2_b7_b4; -+ uint32 udf_2_b8; -+ uint32 PAD[1]; -+ uint32 udf_0_c3_c0; -+ uint32 udf_0_c7_c4; -+ uint32 udf_0_c8; -+ uint32 PAD[1]; -+ uint32 udf_1_c3_c0; -+ uint32 udf_1_c7_c4; -+ uint32 udf_1_c8; -+ uint32 PAD[1]; -+ uint32 udf_2_c3_c0; -+ uint32 udf_2_c7_c4; -+ uint32 udf_2_c8; -+ uint32 PAD[1]; -+ uint32 udf_0_d3_d0; -+ uint32 udf_0_d7_d4; -+ uint32 udf_0_d11_d8; -+} gmac_commonregs_t; -+ -+/* stag0 offset0x0 */ -+#define STAG0_TPID_SHIFT 0 -+#define STAG0_TPID_MASK 0xffff -+ -+/* stag1 offset0x4 */ -+#define STAG1_TPID_SHIFT 0 -+#define STAG1_TPID_MASK 0xffff -+ -+/* stag2 offset0x8 */ -+#define STAG2_TPID_SHIFT 0 -+#define STAG2_TPID_MASK 0xffff -+ -+/* stag3 offset0xc */ -+#define STAG3_TPID_SHIFT 0 -+#define STAG3_TPID_MASK 0xffff -+ -+/* parsercontrol offset0x20 */ -+#define PARSERCONTROL_MAX_PARSER_LEN_TH_SHIFT 0 -+#define PARSERCONTROL_MAX_PARSER_LEN_TH_MASK 0x3fff -+ -+/* mib_max_len offset0x24 */ -+#define MIB_MAX_LEN_MIB_MAX_LEN_SHIFT 0 -+#define MIB_MAX_LEN_MIB_MAX_LEN_MASK 0x3fff -+ -+/* phyaccess offset0x100 */ -+#define PHYACCESS_TRIGGER_SHIFT 30 -+#define PHYACCESS_TRIGGER_MASK 0x40000000 -+#define PHYACCESS_WR_CMD_SHIFT 29 -+#define PHYACCESS_WR_CMD_MASK 0x20000000 -+#define PHYACCESS_CPU_REG_ADDR_SHIFT 24 -+#define PHYACCESS_CPU_REG_ADDR_MASK 0x1f000000 -+#define PHYACCESS_CPU_PHY_ADDR_SHIFT 16 -+#define PHYACCESS_CPU_PHY_ADDR_MASK 0x1f0000 -+#define PHYACCESS_ACC_DATA_SHIFT 0 -+#define PHYACCESS_ACC_DATA_MASK 0xffff -+ -+/* phycontrol offset0x104 */ -+#define PHYCONTROL_SD_ACCESS_EN_SHIFT 25 -+#define PHYCONTROL_SD_ACCESS_EN_MASK 0x2000000 -+#define PHYCONTROL_NWAY_AUTO_POLLING_EN_SHIFT 24 -+#define PHYCONTROL_NWAY_AUTO_POLLING_EN_MASK 0x1000000 -+#define PHYCONTROL_MDC_TRANSITION_EN_SHIFT 23 -+#define PHYCONTROL_MDC_TRANSITION_EN_MASK 0x800000 -+#define PHYCONTROL_MDC_CYCLE_TH_SHIFT 16 -+#define PHYCONTROL_MDC_CYCLE_TH_MASK 0x7f0000 -+#define PHYCONTROL_EXT_PHY_ADDR_SHIFT 0 -+#define PHYCONTROL_EXT_PHY_ADDR_MASK 0x1f -+ -+/* gmac0_rgmii_cntl offset0x110 */ -+#define GMAC0_RGMII_CNTL_TIMING_SEL_SHIFT 0 -+#define GMAC0_RGMII_CNTL_TIMING_SEL_MASK 0x1 -+#define GMAC0_RGMII_CNTL_RGMII_DLL_RXC_BYPASS_SHIFT 1 -+#define GMAC0_RGMII_CNTL_RGMII_DLL_RXC_BYPASS_MASK 0x2 -+#define GMAC0_RGMII_CNTL_BYPASS_2NS_DEL_SHIFT 2 -+#define GMAC0_RGMII_CNTL_BYPASS_2NS_DEL_MASK 0x4 -+#define GMAC0_RGMII_CNTL_DEL_STRB_SHIFT 3 -+#define GMAC0_RGMII_CNTL_DEL_STRB_MASK 0x8 -+#define GMAC0_RGMII_CNTL_DEL_VALUE_SHIFT 4 -+#define GMAC0_RGMII_CNTL_DEL_VALUE_MASK 0x70 -+#define GMAC0_RGMII_CNTL_DEL_ADDR_SHIFT 7 -+#define GMAC0_RGMII_CNTL_DEL_ADDR_MASK 0x780 -+ -+/* cfp_access offset0x200 */ -+#define CFP_ACCESS_OP_START_DONE_SHIFT 0 -+#define CFP_ACCESS_OP_START_DONE_MASK 0x1 -+#define CFP_ACCESS_OP_SEL_SHIFT 1 -+#define CFP_ACCESS_OP_SEL_MASK 0xe -+#define CFP_ACCESS_CFP_RAM_CLEAR_SHIFT 4 -+#define CFP_ACCESS_CFP_RAM_CLEAR_MASK 0x10 -+#define CFP_ACCESS_RESERVED1_SHIFT 5 -+#define CFP_ACCESS_RESERVED1_MASK 0x3e0 -+#define CFP_ACCESS_RAM_SEL_SHIFT 10 -+#define CFP_ACCESS_RAM_SEL_MASK 0x7c00 -+#define CFP_ACCESS_TCAM_RESET_SHIFT 15 -+#define CFP_ACCESS_TCAM_RESET_MASK 0x8000 -+#define CFP_ACCESS_XCESS_ADDR_SHIFT 16 -+#define CFP_ACCESS_XCESS_ADDR_MASK 0x1ff0000 -+#define CFP_ACCESS_RESERVED0_SHIFT 25 -+#define CFP_ACCESS_RESERVED0_MASK 0xe000000 -+#define CFP_ACCESS_RD_STATUS_SHIFT 28 -+#define CFP_ACCESS_RD_STATUS_MASK 0xf0000000 -+ -+/* cfp_tcam_data0 offset0x210 */ -+#define CFP_TCAM_DATA0_DATA_SHIFT 0 -+#define CFP_TCAM_DATA0_DATA_MASK 0xffffffff -+ -+/* cfp_tcam_data1 offset0x214 */ -+#define CFP_TCAM_DATA1_DATA_SHIFT 0 -+#define CFP_TCAM_DATA1_DATA_MASK 0xffffffff -+ -+/* cfp_tcam_data2 offset0x218 */ -+#define CFP_TCAM_DATA2_DATA_SHIFT 0 -+#define CFP_TCAM_DATA2_DATA_MASK 0xffffffff -+ -+/* cfp_tcam_data3 offset0x21c */ -+#define CFP_TCAM_DATA3_DATA_SHIFT 0 -+#define CFP_TCAM_DATA3_DATA_MASK 0xffffffff -+ -+/* cfp_tcam_data4 offset0x220 */ -+#define CFP_TCAM_DATA4_DATA_SHIFT 0 -+#define CFP_TCAM_DATA4_DATA_MASK 0xffffffff -+ -+/* cfp_tcam_data5 offset0x224 */ -+#define CFP_TCAM_DATA5_DATA_SHIFT 0 -+#define CFP_TCAM_DATA5_DATA_MASK 0xffffffff -+ -+/* cfp_tcam_data6 offset0x228 */ -+#define CFP_TCAM_DATA6_DATA_SHIFT 0 -+#define CFP_TCAM_DATA6_DATA_MASK 0xffffffff -+ -+/* cfp_tcam_data7 offset0x22c */ -+#define CFP_TCAM_DATA7_DATA_SHIFT 0 -+#define CFP_TCAM_DATA7_DATA_MASK 0xffffffff -+ -+/* cfp_tcam_mask0 offset0x230 */ -+#define CFP_TCAM_MASK0_DATA_SHIFT 0 -+#define CFP_TCAM_MASK0_DATA_MASK 0xffffffff -+ -+/* cfp_tcam_mask1 offset0x234 */ -+#define CFP_TCAM_MASK1_DATA_SHIFT 0 -+#define CFP_TCAM_MASK1_DATA_MASK 0xffffffff -+ -+/* cfp_tcam_mask2 offset0x238 */ -+#define CFP_TCAM_MASK2_DATA_SHIFT 0 -+#define CFP_TCAM_MASK2_DATA_MASK 0xffffffff -+ -+/* cfp_tcam_mask3 offset0x23c */ -+#define CFP_TCAM_MASK3_DATA_SHIFT 0 -+#define CFP_TCAM_MASK3_DATA_MASK 0xffffffff -+ -+/* cfp_tcam_mask4 offset0x240 */ -+#define CFP_TCAM_MASK4_DATA_SHIFT 0 -+#define CFP_TCAM_MASK4_DATA_MASK 0xffffffff -+ -+/* cfp_tcam_mask5 offset0x244 */ -+#define CFP_TCAM_MASK5_DATA_SHIFT 0 -+#define CFP_TCAM_MASK5_DATA_MASK 0xffffffff -+ -+/* cfp_tcam_mask6 offset0x248 */ -+#define CFP_TCAM_MASK6_DATA_SHIFT 0 -+#define CFP_TCAM_MASK6_DATA_MASK 0xffffffff -+ -+/* cfp_tcam_mask7 offset0x24c */ -+#define CFP_TCAM_MASK7_DATA_SHIFT 0 -+#define CFP_TCAM_MASK7_DATA_MASK 0xffffffff -+ -+/* cfp_action_data offset0x250 */ -+#define CFP_ACTION_DATA_CHAINID_SHIFT 0 -+#define CFP_ACTION_DATA_CHAINID_MASK 0xff -+#define CFP_ACTION_DATA_CHANNELID_SHIFT 8 -+#define CFP_ACTION_DATA_CHANNELID_MASK 0xf00 -+#define CFP_ACTION_DATA_DROP_SHIFT 12 -+#define CFP_ACTION_DATA_DROP_MASK 0x1000 -+#define CFP_ACTION_DATA_RESERVED_SHIFT 13 -+#define CFP_ACTION_DATA_RESERVED_MASK 0xffffe000 -+ -+/* tcam_bist_cntl offset0x2a0 */ -+#define TCAM_BIST_CNTL_TCAM_BIST_EN_SHIFT 0 -+#define TCAM_BIST_CNTL_TCAM_BIST_EN_MASK 0x1 -+#define TCAM_BIST_CNTL_TCAM_BIST_TCAM_SEL_SHIFT 1 -+#define TCAM_BIST_CNTL_TCAM_BIST_TCAM_SEL_MASK 0x6 -+#define TCAM_BIST_CNTL_RESERVED1_SHIFT 3 -+#define TCAM_BIST_CNTL_RESERVED1_MASK 0x8 -+#define TCAM_BIST_CNTL_TCAM_BIST_STATUS_SEL_SHIFT 4 -+#define TCAM_BIST_CNTL_TCAM_BIST_STATUS_SEL_MASK 0xf0 -+#define TCAM_BIST_CNTL_TCAM_BIST_SKIP_ERR_CNT_SHIFT 8 -+#define TCAM_BIST_CNTL_TCAM_BIST_SKIP_ERR_CNT_MASK 0xff00 -+#define TCAM_BIST_CNTL_TCAM_TEST_COMPARE_SHIFT 16 -+#define TCAM_BIST_CNTL_TCAM_TEST_COMPARE_MASK 0x10000 -+#define TCAM_BIST_CNTL_RESERVED_SHIFT 17 -+#define TCAM_BIST_CNTL_RESERVED_MASK 0x7ffe0000 -+#define TCAM_BIST_CNTL_TCAM_BIST_DONE_SHIFT 31 -+#define TCAM_BIST_CNTL_TCAM_BIST_DONE_MASK 0x80000000 -+ -+/* tcam_bist_status offset0x2a4 */ -+#define TCAM_BIST_STATUS_TCAM_BIST_STATUS_SHIFT 0 -+#define TCAM_BIST_STATUS_TCAM_BIST_STATUS_MASK 0xffff -+#define TCAM_BIST_STATUS_RESERVED_SHIFT 16 -+#define TCAM_BIST_STATUS_RESERVED_MASK 0xffff0000 -+ -+/* tcam_cmp_status offset0x2a8 */ -+#define TCAM_CMP_STATUS_TCAM_HIT_ADDR_SHIFT 0 -+#define TCAM_CMP_STATUS_TCAM_HIT_ADDR_MASK 0x1ff -+#define TCAM_CMP_STATUS_RESERVED2_SHIFT 9 -+#define TCAM_CMP_STATUS_RESERVED2_MASK 0x7e00 -+#define TCAM_CMP_STATUS_TCAM_HIT_SHIFT 15 -+#define TCAM_CMP_STATUS_TCAM_HIT_MASK 0x8000 -+#define TCAM_CMP_STATUS_RESERVED1_SHIFT 16 -+#define TCAM_CMP_STATUS_RESERVED1_MASK 0xffff0000 -+ -+/* tcam_disable offset0x2ac */ -+#define TCAM_DISABLE_TCAM_DISABLE_SHIFT 0 -+#define TCAM_DISABLE_TCAM_DISABLE_MASK 0xf -+#define TCAM_DISABLE_RESERVED_SHIFT 4 -+#define TCAM_DISABLE_RESERVED_MASK 0xfffffff0 -+ -+/* tcam_test_cntl offset0x2f0 */ -+#define TCAM_TEST_CNTL_TCAM_TEST_CNTL_SHIFT 0 -+#define TCAM_TEST_CNTL_TCAM_TEST_CNTL_MASK 0x7ff -+#define TCAM_TEST_CNTL_RESERVED_SHIFT 11 -+#define TCAM_TEST_CNTL_RESERVED_MASK 0xfffff800 -+ -+/* udf_0_a3_a0 offset0x300 */ -+#define UDF_0_A3_A0_CFG_UDF_0_A0_SHIFT 0 -+#define UDF_0_A3_A0_CFG_UDF_0_A0_MASK 0xff -+#define UDF_0_A3_A0_CFG_UDF_0_A1_SHIFT 8 -+#define UDF_0_A3_A0_CFG_UDF_0_A1_MASK 0xff00 -+#define UDF_0_A3_A0_CFG_UDF_0_A2_SHIFT 16 -+#define UDF_0_A3_A0_CFG_UDF_0_A2_MASK 0xff0000 -+#define UDF_0_A3_A0_CFG_UDF_0_A3_SHIFT 24 -+#define UDF_0_A3_A0_CFG_UDF_0_A3_MASK 0xff000000 -+ -+/* udf_0_a7_a4 offset0x304 */ -+#define UDF_0_A7_A4_CFG_UDF_0_A4_SHIFT 0 -+#define UDF_0_A7_A4_CFG_UDF_0_A4_MASK 0xff -+#define UDF_0_A7_A4_CFG_UDF_0_A5_SHIFT 8 -+#define UDF_0_A7_A4_CFG_UDF_0_A5_MASK 0xff00 -+#define UDF_0_A7_A4_CFG_UDF_0_A6_SHIFT 16 -+#define UDF_0_A7_A4_CFG_UDF_0_A6_MASK 0xff0000 -+#define UDF_0_A7_A4_CFG_UDF_0_A7_SHIFT 24 -+#define UDF_0_A7_A4_CFG_UDF_0_A7_MASK 0xff000000 -+ -+/* udf_0_a8 offset0x308 */ -+#define UDF_0_A8_CFG_UDF_0_A8_SHIFT 0 -+#define UDF_0_A8_CFG_UDF_0_A8_MASK 0xff -+ -+/* udf_1_a3_a0 offset0x310 */ -+#define UDF_1_A3_A0_CFG_UDF_1_A0_SHIFT 0 -+#define UDF_1_A3_A0_CFG_UDF_1_A0_MASK 0xff -+#define UDF_1_A3_A0_CFG_UDF_1_A1_SHIFT 8 -+#define UDF_1_A3_A0_CFG_UDF_1_A1_MASK 0xff00 -+#define UDF_1_A3_A0_CFG_UDF_1_A2_SHIFT 16 -+#define UDF_1_A3_A0_CFG_UDF_1_A2_MASK 0xff0000 -+#define UDF_1_A3_A0_CFG_UDF_1_A3_SHIFT 24 -+#define UDF_1_A3_A0_CFG_UDF_1_A3_MASK 0xff000000 -+ -+/* udf_1_a7_a4 offset0x314 */ -+#define UDF_1_A7_A4_CFG_UDF_1_A4_SHIFT 0 -+#define UDF_1_A7_A4_CFG_UDF_1_A4_MASK 0xff -+#define UDF_1_A7_A4_CFG_UDF_1_A5_SHIFT 8 -+#define UDF_1_A7_A4_CFG_UDF_1_A5_MASK 0xff00 -+#define UDF_1_A7_A4_CFG_UDF_1_A6_SHIFT 16 -+#define UDF_1_A7_A4_CFG_UDF_1_A6_MASK 0xff0000 -+#define UDF_1_A7_A4_CFG_UDF_1_A7_SHIFT 24 -+#define UDF_1_A7_A4_CFG_UDF_1_A7_MASK 0xff000000 -+ -+/* udf_1_a8 offset0x318 */ -+#define UDF_1_A8_CFG_UDF_1_A8_SHIFT 0 -+#define UDF_1_A8_CFG_UDF_1_A8_MASK 0xff -+ -+/* udf_2_a3_a0 offset0x320 */ -+#define UDF_2_A3_A0_CFG_UDF_2_A0_SHIFT 0 -+#define UDF_2_A3_A0_CFG_UDF_2_A0_MASK 0xff -+#define UDF_2_A3_A0_CFG_UDF_2_A1_SHIFT 8 -+#define UDF_2_A3_A0_CFG_UDF_2_A1_MASK 0xff00 -+#define UDF_2_A3_A0_CFG_UDF_2_A2_SHIFT 16 -+#define UDF_2_A3_A0_CFG_UDF_2_A2_MASK 0xff0000 -+#define UDF_2_A3_A0_CFG_UDF_2_A3_SHIFT 24 -+#define UDF_2_A3_A0_CFG_UDF_2_A3_MASK 0xff000000 -+ -+/* udf_2_a7_a4 offset0x324 */ -+#define UDF_2_A7_A4_CFG_UDF_2_A4_SHIFT 0 -+#define UDF_2_A7_A4_CFG_UDF_2_A4_MASK 0xff -+#define UDF_2_A7_A4_CFG_UDF_2_A5_SHIFT 8 -+#define UDF_2_A7_A4_CFG_UDF_2_A5_MASK 0xff00 -+#define UDF_2_A7_A4_CFG_UDF_2_A6_SHIFT 16 -+#define UDF_2_A7_A4_CFG_UDF_2_A6_MASK 0xff0000 -+#define UDF_2_A7_A4_CFG_UDF_2_A7_SHIFT 24 -+#define UDF_2_A7_A4_CFG_UDF_2_A7_MASK 0xff000000 -+ -+/* udf_2_a8 offset0x328 */ -+#define UDF_2_A8_CFG_UDF_2_A8_SHIFT 0 -+#define UDF_2_A8_CFG_UDF_2_A8_MASK 0xff -+ -+/* udf_0_b3_b0 offset0x330 */ -+#define UDF_0_B3_B0_CFG_UDF_0_B0_SHIFT 0 -+#define UDF_0_B3_B0_CFG_UDF_0_B0_MASK 0xff -+#define UDF_0_B3_B0_CFG_UDF_0_B1_SHIFT 8 -+#define UDF_0_B3_B0_CFG_UDF_0_B1_MASK 0xff00 -+#define UDF_0_B3_B0_CFG_UDF_0_B2_SHIFT 16 -+#define UDF_0_B3_B0_CFG_UDF_0_B2_MASK 0xff0000 -+#define UDF_0_B3_B0_CFG_UDF_0_B3_SHIFT 24 -+#define UDF_0_B3_B0_CFG_UDF_0_B3_MASK 0xff000000 -+ -+/* udf_0_b7_b4 offset0x334 */ -+#define UDF_0_B7_B4_CFG_UDF_0_B4_SHIFT 0 -+#define UDF_0_B7_B4_CFG_UDF_0_B4_MASK 0xff -+#define UDF_0_B7_B4_CFG_UDF_0_B5_SHIFT 8 -+#define UDF_0_B7_B4_CFG_UDF_0_B5_MASK 0xff00 -+#define UDF_0_B7_B4_CFG_UDF_0_B6_SHIFT 16 -+#define UDF_0_B7_B4_CFG_UDF_0_B6_MASK 0xff0000 -+#define UDF_0_B7_B4_CFG_UDF_0_B7_SHIFT 24 -+#define UDF_0_B7_B4_CFG_UDF_0_B7_MASK 0xff000000 -+ -+/* udf_0_b8 offset0x338 */ -+#define UDF_0_B8_CFG_UDF_0_B8_SHIFT 0 -+#define UDF_0_B8_CFG_UDF_0_B8_MASK 0xff -+ -+/* udf_1_b3_b0 offset0x340 */ -+#define UDF_1_B3_B0_CFG_UDF_1_B0_SHIFT 0 -+#define UDF_1_B3_B0_CFG_UDF_1_B0_MASK 0xff -+#define UDF_1_B3_B0_CFG_UDF_1_B1_SHIFT 8 -+#define UDF_1_B3_B0_CFG_UDF_1_B1_MASK 0xff00 -+#define UDF_1_B3_B0_CFG_UDF_1_B2_SHIFT 16 -+#define UDF_1_B3_B0_CFG_UDF_1_B2_MASK 0xff0000 -+#define UDF_1_B3_B0_CFG_UDF_1_B3_SHIFT 24 -+#define UDF_1_B3_B0_CFG_UDF_1_B3_MASK 0xff000000 -+ -+/* udf_1_b7_b4 offset0x344 */ -+#define UDF_1_B7_B4_CFG_UDF_1_B4_SHIFT 0 -+#define UDF_1_B7_B4_CFG_UDF_1_B4_MASK 0xff -+#define UDF_1_B7_B4_CFG_UDF_1_B5_SHIFT 8 -+#define UDF_1_B7_B4_CFG_UDF_1_B5_MASK 0xff00 -+#define UDF_1_B7_B4_CFG_UDF_1_B6_SHIFT 16 -+#define UDF_1_B7_B4_CFG_UDF_1_B6_MASK 0xff0000 -+#define UDF_1_B7_B4_CFG_UDF_1_B7_SHIFT 24 -+#define UDF_1_B7_B4_CFG_UDF_1_B7_MASK 0xff000000 -+ -+/* udf_1_b8 offset0x348 */ -+#define UDF_1_B8_CFG_UDF_1_B8_SHIFT 0 -+#define UDF_1_B8_CFG_UDF_1_B8_MASK 0xff -+ -+/* udf_2_b3_b0 offset0x350 */ -+#define UDF_2_B3_B0_CFG_UDF_2_B0_SHIFT 0 -+#define UDF_2_B3_B0_CFG_UDF_2_B0_MASK 0xff -+#define UDF_2_B3_B0_CFG_UDF_2_B1_SHIFT 8 -+#define UDF_2_B3_B0_CFG_UDF_2_B1_MASK 0xff00 -+#define UDF_2_B3_B0_CFG_UDF_2_B2_SHIFT 16 -+#define UDF_2_B3_B0_CFG_UDF_2_B2_MASK 0xff0000 -+#define UDF_2_B3_B0_CFG_UDF_2_B3_SHIFT 24 -+#define UDF_2_B3_B0_CFG_UDF_2_B3_MASK 0xff000000 -+ -+/* udf_2_b7_b4 offset0x354 */ -+#define UDF_2_B7_B4_CFG_UDF_2_B4_SHIFT 0 -+#define UDF_2_B7_B4_CFG_UDF_2_B4_MASK 0xff -+#define UDF_2_B7_B4_CFG_UDF_2_B5_SHIFT 8 -+#define UDF_2_B7_B4_CFG_UDF_2_B5_MASK 0xff00 -+#define UDF_2_B7_B4_CFG_UDF_2_B6_SHIFT 16 -+#define UDF_2_B7_B4_CFG_UDF_2_B6_MASK 0xff0000 -+#define UDF_2_B7_B4_CFG_UDF_2_B7_SHIFT 24 -+#define UDF_2_B7_B4_CFG_UDF_2_B7_MASK 0xff000000 -+ -+/* udf_2_b8 offset0x358 */ -+#define UDF_2_B8_CFG_UDF_2_B8_SHIFT 0 -+#define UDF_2_B8_CFG_UDF_2_B8_MASK 0xff -+ -+/* udf_0_c3_c0 offset0x360 */ -+#define UDF_0_C3_C0_CFG_UDF_0_C0_SHIFT 0 -+#define UDF_0_C3_C0_CFG_UDF_0_C0_MASK 0xff -+#define UDF_0_C3_C0_CFG_UDF_0_C1_SHIFT 8 -+#define UDF_0_C3_C0_CFG_UDF_0_C1_MASK 0xff00 -+#define UDF_0_C3_C0_CFG_UDF_0_C2_SHIFT 16 -+#define UDF_0_C3_C0_CFG_UDF_0_C2_MASK 0xff0000 -+#define UDF_0_C3_C0_CFG_UDF_0_C3_SHIFT 24 -+#define UDF_0_C3_C0_CFG_UDF_0_C3_MASK 0xff000000 -+ -+/* udf_0_c7_c4 offset0x364 */ -+#define UDF_0_C7_C4_CFG_UDF_0_C4_SHIFT 0 -+#define UDF_0_C7_C4_CFG_UDF_0_C4_MASK 0xff -+#define UDF_0_C7_C4_CFG_UDF_0_C5_SHIFT 8 -+#define UDF_0_C7_C4_CFG_UDF_0_C5_MASK 0xff00 -+#define UDF_0_C7_C4_CFG_UDF_0_C6_SHIFT 16 -+#define UDF_0_C7_C4_CFG_UDF_0_C6_MASK 0xff0000 -+#define UDF_0_C7_C4_CFG_UDF_0_C7_SHIFT 24 -+#define UDF_0_C7_C4_CFG_UDF_0_C7_MASK 0xff000000 -+ -+/* udf_0_c8 offset0x368 */ -+#define UDF_0_C8_CFG_UDF_0_C8_SHIFT 0 -+#define UDF_0_C8_CFG_UDF_0_C8_MASK 0xff -+ -+/* udf_1_c3_c0 offset0x370 */ -+#define UDF_1_C3_C0_CFG_UDF_1_C0_SHIFT 0 -+#define UDF_1_C3_C0_CFG_UDF_1_C0_MASK 0xff -+#define UDF_1_C3_C0_CFG_UDF_1_C1_SHIFT 8 -+#define UDF_1_C3_C0_CFG_UDF_1_C1_MASK 0xff00 -+#define UDF_1_C3_C0_CFG_UDF_1_C2_SHIFT 16 -+#define UDF_1_C3_C0_CFG_UDF_1_C2_MASK 0xff0000 -+#define UDF_1_C3_C0_CFG_UDF_1_C3_SHIFT 24 -+#define UDF_1_C3_C0_CFG_UDF_1_C3_MASK 0xff000000 -+ -+/* udf_1_c7_c4 offset0x374 */ -+#define UDF_1_C7_C4_CFG_UDF_1_C4_SHIFT 0 -+#define UDF_1_C7_C4_CFG_UDF_1_C4_MASK 0xff -+#define UDF_1_C7_C4_CFG_UDF_1_C5_SHIFT 8 -+#define UDF_1_C7_C4_CFG_UDF_1_C5_MASK 0xff00 -+#define UDF_1_C7_C4_CFG_UDF_1_C6_SHIFT 16 -+#define UDF_1_C7_C4_CFG_UDF_1_C6_MASK 0xff0000 -+#define UDF_1_C7_C4_CFG_UDF_1_C7_SHIFT 24 -+#define UDF_1_C7_C4_CFG_UDF_1_C7_MASK 0xff000000 -+ -+/* udf_1_c8 offset0x378 */ -+#define UDF_1_C8_CFG_UDF_1_C8_SHIFT 0 -+#define UDF_1_C8_CFG_UDF_1_C8_MASK 0xff -+ -+/* udf_2_c3_c0 offset0x380 */ -+#define UDF_2_C3_C0_CFG_UDF_2_C0_SHIFT 0 -+#define UDF_2_C3_C0_CFG_UDF_2_C0_MASK 0xff -+#define UDF_2_C3_C0_CFG_UDF_2_C1_SHIFT 8 -+#define UDF_2_C3_C0_CFG_UDF_2_C1_MASK 0xff00 -+#define UDF_2_C3_C0_CFG_UDF_2_C2_SHIFT 16 -+#define UDF_2_C3_C0_CFG_UDF_2_C2_MASK 0xff0000 -+#define UDF_2_C3_C0_CFG_UDF_2_C3_SHIFT 24 -+#define UDF_2_C3_C0_CFG_UDF_2_C3_MASK 0xff000000 -+ -+/* udf_2_c7_c4 offset0x384 */ -+#define UDF_2_C7_C4_CFG_UDF_2_C4_SHIFT 0 -+#define UDF_2_C7_C4_CFG_UDF_2_C4_MASK 0xff -+#define UDF_2_C7_C4_CFG_UDF_2_C5_SHIFT 8 -+#define UDF_2_C7_C4_CFG_UDF_2_C5_MASK 0xff00 -+#define UDF_2_C7_C4_CFG_UDF_2_C6_SHIFT 16 -+#define UDF_2_C7_C4_CFG_UDF_2_C6_MASK 0xff0000 -+#define UDF_2_C7_C4_CFG_UDF_2_C7_SHIFT 24 -+#define UDF_2_C7_C4_CFG_UDF_2_C7_MASK 0xff000000 -+ -+/* udf_2_c8 offset0x388 */ -+#define UDF_2_C8_CFG_UDF_2_C8_SHIFT 0 -+#define UDF_2_C8_CFG_UDF_2_C8_MASK 0xff -+ -+/* udf_0_d3_d0 offset0x390 */ -+#define UDF_0_D3_D0_CFG_UDF_0_D0_SHIFT 0 -+#define UDF_0_D3_D0_CFG_UDF_0_D0_MASK 0xff -+#define UDF_0_D3_D0_CFG_UDF_0_D1_SHIFT 8 -+#define UDF_0_D3_D0_CFG_UDF_0_D1_MASK 0xff00 -+#define UDF_0_D3_D0_CFG_UDF_0_D2_SHIFT 16 -+#define UDF_0_D3_D0_CFG_UDF_0_D2_MASK 0xff0000 -+#define UDF_0_D3_D0_CFG_UDF_0_D3_SHIFT 24 -+#define UDF_0_D3_D0_CFG_UDF_0_D3_MASK 0xff000000 -+ -+/* udf_0_d7_d4 offset0x394 */ -+#define UDF_0_D7_D4_CFG_UDF_0_D4_SHIFT 0 -+#define UDF_0_D7_D4_CFG_UDF_0_D4_MASK 0xff -+#define UDF_0_D7_D4_CFG_UDF_0_D5_SHIFT 8 -+#define UDF_0_D7_D4_CFG_UDF_0_D5_MASK 0xff00 -+#define UDF_0_D7_D4_CFG_UDF_0_D6_SHIFT 16 -+#define UDF_0_D7_D4_CFG_UDF_0_D6_MASK 0xff0000 -+#define UDF_0_D7_D4_CFG_UDF_0_D7_SHIFT 24 -+#define UDF_0_D7_D4_CFG_UDF_0_D7_MASK 0xff000000 -+ -+/* udf_0_d11_d8 offset0x398 */ -+#define UDF_0_D11_D8_CFG_UDF_0_D8_SHIFT 0 -+#define UDF_0_D11_D8_CFG_UDF_0_D8_MASK 0xff -+#define UDF_0_D11_D8_CFG_UDF_0_D9_SHIFT 8 -+#define UDF_0_D11_D8_CFG_UDF_0_D9_MASK 0xff00 -+#define UDF_0_D11_D8_CFG_UDF_0_D10_SHIFT 16 -+#define UDF_0_D11_D8_CFG_UDF_0_D10_MASK 0xff0000 -+#define UDF_0_D11_D8_CFG_UDF_0_D11_SHIFT 24 -+#define UDF_0_D11_D8_CFG_UDF_0_D11_MASK 0xff000000 -+ -+#endif /* _gmac_common_core_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/gmac_core.h b/drivers/net/ethernet/broadcom/gmac/src/include/gmac_core.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/gmac_core.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/gmac_core.h 2017-11-09 17:53:43.960313000 +0800 -@@ -0,0 +1,304 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * gmacdefs - Broadcom gmac (Unimac) specific definitions -+ * -+ * $Id: gmac_core.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _gmac_core_h_ -+#define _gmac_core_h_ -+ -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif /* PAD */ -+ -+/* We have 4 DMA TX channels */ -+#define GMAC_NUM_DMA_TX 4 -+ -+typedef volatile struct { -+ dma64regs_t dmaxmt; /* dma tx */ -+ uint32 PAD[2]; -+ dma64regs_t dmarcv; /* dma rx */ -+ uint32 PAD[2]; -+} dma64_t; -+ -+/* -+ * Host Interface Registers -+ */ -+typedef volatile struct _gmacregs { -+ uint32 devcontrol; /* 0x000 */ -+ uint32 devstatus; /* 0x004 */ -+ uint32 PAD; -+ uint32 biststatus; /* 0x00c */ -+ uint32 PAD[4]; -+ uint32 intstatus; /* 0x020 */ -+ uint32 intmask; /* 0x024 */ -+ uint32 gptimer; /* 0x028 */ -+ uint32 PAD[53]; -+ uint32 intrecvlazy; /* 0x100 */ -+ uint32 flowctlthresh; /* 0x104 */ -+ uint32 wrrthresh; /* 0x108 */ -+ uint32 gmac_idle_cnt_thresh; /* 0x10c */ -+ uint32 PAD[28]; -+ uint32 phyaccess; /* 0x180 */ -+ uint32 PAD; -+ uint32 phycontrol; /* 0x188 */ -+ uint32 txqctl; /* 0x18c */ -+ uint32 rxqctl; /* 0x190 */ -+ uint32 gpioselect; /* 0x194 */ -+ uint32 gpio_output_en; /* 0x198 */ -+ uint32 PAD; /* 0x19c */ -+ uint32 txq_rxq_mem_ctl; /* 0x1a0 */ -+ uint32 memory_ecc_status; /* 0x1a4 */ -+ uint32 serdes_ctl; /* 0x1a8 */ -+ uint32 serdes_status0; /* 0x1ac */ -+ uint32 serdes_status1; /* 0x1b0 */ -+ uint32 PAD[11]; /* 0x1b4-1dc */ -+ uint32 clk_ctl_st; /* 0x1e0 */ -+ uint32 hw_war; /* 0x1e4 */ -+ uint32 pwrctl; /* 0x1e8 */ -+ uint32 PAD[5]; -+ -+ dma64_t dmaregs[GMAC_NUM_DMA_TX]; -+ -+ /* GAMC MIB counters */ -+ gmacmib_t mib; -+ uint32 PAD[245]; -+ -+ uint32 unimacversion; /* 0x800 */ -+ uint32 hdbkpctl; /* 0x804 */ -+ uint32 cmdcfg; /* 0x808 */ -+ uint32 macaddrhigh; /* 0x80c */ -+ uint32 macaddrlow; /* 0x810 */ -+ uint32 rxmaxlength; /* 0x814 */ -+ uint32 pausequanta; /* 0x818 */ -+ uint32 PAD[10]; -+ uint32 macmode; /* 0x844 */ -+ uint32 outertag; /* 0x848 */ -+ uint32 innertag; /* 0x84c */ -+ uint32 PAD[3]; -+ uint32 txipg; /* 0x85c */ -+ uint32 PAD[180]; -+ uint32 pausectl; /* 0xb30 */ -+ uint32 txflush; /* 0xb34 */ -+ uint32 rxstatus; /* 0xb38 */ -+ uint32 txstatus; /* 0xb3c */ -+} gmacregs_t; -+ -+#define GM_MIB_BASE 0x300 -+#define GM_MIB_LIMIT 0x800 -+ -+/* -+ * register-specific flag definitions -+ */ -+ -+/* device control */ -+#define DC_TSM 0x00000002 -+#define DC_CFCO 0x00000004 -+#define DC_RLSS 0x00000008 -+#define DC_MROR 0x00000010 -+#define DC_FCM_MASK 0x00000060 -+#define DC_FCM_SHIFT 5 -+#define DC_NAE 0x00000080 -+#define DC_TF 0x00000100 -+#define DC_RDS_MASK 0x00030000 -+#define DC_RDS_SHIFT 16 -+#define DC_TDS_MASK 0x000c0000 -+#define DC_TDS_SHIFT 18 -+ -+/* device status */ -+#define DS_RBF 0x00000001 -+#define DS_RDF 0x00000002 -+#define DS_RIF 0x00000004 -+#define DS_TBF 0x00000008 -+#define DS_TDF 0x00000010 -+#define DS_TIF 0x00000020 -+#define DS_PO 0x00000040 -+#define DS_MM_MASK 0x00000300 -+#define DS_MM_SHIFT 8 -+ -+/* bist status */ -+#define BS_MTF 0x00000001 -+#define BS_MRF 0x00000002 -+#define BS_TDB 0x00000004 -+#define BS_TIB 0x00000008 -+#define BS_TBF 0x00000010 -+#define BS_RDB 0x00000020 -+#define BS_RIB 0x00000040 -+#define BS_RBF 0x00000080 -+#define BS_URTF 0x00000100 -+#define BS_UTF 0x00000200 -+#define BS_URF 0x00000400 -+ -+/* interrupt status and mask registers */ -+#define I_MRO 0x00000001 -+#define I_MTO 0x00000002 -+#define I_TFD 0x00000004 -+#define I_LS 0x00000008 -+#define I_MDIO 0x00000010 -+#define I_MR 0x00000020 -+#define I_MT 0x00000040 -+#define I_TO 0x00000080 -+#define I_PDEE 0x00000400 -+#define I_PDE 0x00000800 -+#define I_DE 0x00001000 -+#define I_RDU 0x00002000 -+#define I_RFO 0x00004000 -+#define I_XFU 0x00008000 -+#define I_RI 0x00010000 -+#define I_XI0 0x01000000 -+#define I_XI1 0x02000000 -+#define I_XI2 0x04000000 -+#define I_XI3 0x08000000 -+#define I_INTMASK 0x0f01fcff -+#define I_ERRMASK 0x0000fc00 -+ -+/* interrupt receive lazy */ -+#define IRL_TO_MASK 0x00ffffff -+#define IRL_FC_MASK 0xff000000 -+#define IRL_FC_SHIFT 24 -+ -+/* flow control thresholds */ -+#define FCT_TT_MASK 0x00000fff -+#define FCT_RT_MASK 0x0fff0000 -+#define FCT_RT_SHIFT 16 -+ -+/* txq aribter wrr thresholds */ -+#define WRRT_Q0T_MASK 0x000000ff -+#define WRRT_Q1T_MASK 0x0000ff00 -+#define WRRT_Q1T_SHIFT 8 -+#define WRRT_Q2T_MASK 0x00ff0000 -+#define WRRT_Q2T_SHIFT 16 -+#define WRRT_Q3T_MASK 0xff000000 -+#define WRRT_Q3T_SHIFT 24 -+ -+/* phy access */ -+#define PA_DATA_MASK 0x0000ffff -+#define PA_ADDR_MASK 0x001f0000 -+#define PA_ADDR_SHIFT 16 -+#define PA_REG_MASK 0x1f000000 -+#define PA_REG_SHIFT 24 -+#define PA_WRITE 0x20000000 -+#define PA_START 0x40000000 -+ -+/* phy control */ -+#define PC_EPA_MASK 0x0000001f -+#define PC_MCT_MASK 0x007f0000 -+#define PC_MCT_SHIFT 16 -+#define PC_MTE 0x00800000 -+ -+/* rxq control */ -+#define RC_DBT_MASK 0x00000fff -+#define RC_DBT_SHIFT 0 -+#define RC_PTE 0x00001000 -+#define RC_MDP_MASK 0x3f000000 -+#define RC_MDP_SHIFT 24 -+ -+#define RC_MAC_DATA_PERIOD 9 -+ -+/* txq control */ -+#define TC_DBT_MASK 0x00000fff -+#define TC_DBT_SHIFT 0 -+ -+/* gpio select */ -+#define GS_GSC_MASK 0x0000000f -+#define GS_GSC_SHIFT 0 -+ -+/* gpio output enable */ -+#define GS_GOE_MASK 0x0000ffff -+#define GS_GOE_SHIFT 0 -+ -+/* gpio output enable */ -+#define SC_TX1G_FIFO_RST_MASK 0x00f00000 -+#define SC_TX1G_FIFO_RST_VAL 0x00f00000 -+#define SC_FORCE_SPD_STRAP_MASK 0x00060000 -+#define SC_FORCE_SPD_STRAP_VAL 0x00040000 -+#define SC_FORCE_SPD_100M_VAL 0x00020000 -+#define SC_FORCE_SPD_1G_VAL 0x00040000 -+#define SC_REF_TERM_SEL_MASK 0x00001000 -+#define SC_REFSEL_MASK 0x00000c00 -+#define SC_REFSEL_VAL 0x00000400 -+#define SC_REFDIV_MASK 0x00000300 -+#define SC_REFDIV_VAL 0x00000000 -+#define SC_LCREF_EN_MASK 0x00000040 -+#define SC_RSTB_PLL_MASK 0x00000010 -+#define SC_RSTB_MDIOREGS_MASK 0x00000008 -+#define SC_RSTB_HW_MASK 0x00000004 -+#define SC_IDDQ_MASK 0x00000002 -+#define SC_PWR_DOWN_MASK 0x00000001 -+ -+/* clk control status */ -+#define CS_FA 0x00000001 -+#define CS_FH 0x00000002 -+#define CS_FI 0x00000004 -+#define CS_AQ 0x00000008 -+#define CS_HQ 0x00000010 -+#define CS_FC 0x00000020 -+#define CS_ER 0x00000100 -+#define CS_AA 0x00010000 -+#define CS_HA 0x00020000 -+#define CS_BA 0x00040000 -+#define CS_BH 0x00080000 -+#define CS_ES 0x01000000 -+ -+/* command config */ -+#define CC_TE 0x00000001 -+#define CC_RE 0x00000002 -+#define CC_ES_MASK 0x0000000c -+#define CC_ES_SHIFT 2 -+#define CC_PROM 0x00000010 -+#define CC_PAD_EN 0x00000020 -+#define CC_CF 0x00000040 -+#define CC_PF 0x00000080 -+#define CC_RPI 0x00000100 -+#define CC_TAI 0x00000200 -+#define CC_HD 0x00000400 -+#define CC_HD_SHIFT 10 -+#define CC_SR 0x00002000 -+#define CC_ML 0x00008000 -+#define CC_OT 0x00020000 -+#define CC_OR 0x00040000 -+#define CC_AE 0x00400000 -+#define CC_CFE 0x00800000 -+#define CC_NLC 0x01000000 -+#define CC_RL 0x02000000 -+#define CC_RED 0x04000000 -+#define CC_PE 0x08000000 -+#define CC_TPI 0x10000000 -+#define CC_AT 0x20000000 -+ -+/* mac addr high */ -+#define MH_HI_MASK 0xffff -+#define MH_HI_SHIFT 16 -+#define MH_MID_MASK 0xffff -+#define MH_MID_SHIFT 0 -+ -+/* mac addr low */ -+#define ML_LO_MASK 0xffff -+#define ML_LO_SHIFT 0 -+ -+/* Core specific control flags */ -+#define SICF_SWCLKE 0x0004 -+#define SICF_SWRST 0x0008 -+ -+/* Core specific status flags */ -+#define SISF_SW_ATTACHED 0x0800 -+ -+#endif /* _gmac_core_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/hndarm.h b/drivers/net/ethernet/broadcom/gmac/src/include/hndarm.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/hndarm.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/hndarm.h 2017-11-09 17:53:43.961300000 +0800 -@@ -0,0 +1,96 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * HND SiliconBackplane ARM core software interface. -+ * -+ * $Id: hndarm.h 325951 2012-04-05 06:03:27Z $ -+ */ -+ -+#ifndef _hndarm_h_ -+#define _hndarm_h_ -+ -+#include -+ -+extern void *hndarm_armr; -+extern uint32 hndarm_rev; -+ -+ -+extern void si_arm_init(si_t *sih); -+ -+#ifdef __ARM_ARCH_7A__ -+extern uint32 si_memc_get_ncdl(si_t *sih); -+#endif -+ -+extern void enable_arm_ints(uint32 which); -+extern void disable_arm_ints(uint32 which); -+ -+extern uint32 get_arm_cyclecount(void); -+extern void set_arm_cyclecount(uint32 ticks); -+ -+#ifdef __ARM_ARCH_7R__ -+extern uint32 get_arm_perfcount_enable(void); -+extern void set_arm_perfcount_enable(uint32 which); -+extern uint32 set_arm_perfcount_disable(void); -+ -+extern uint32 get_arm_perfcount_sel(void); -+extern void set_arm_perfcount_sel(uint32 which); -+ -+extern uint32 get_arm_perfcount_event(void); -+extern void set_arm_perfcount_event(uint32 which); -+ -+extern uint32 get_arm_perfcount(void); -+extern void set_arm_perfcount(uint32 which); -+ -+extern void enable_arm_cyclecount(void); -+extern void disable_arm_cyclecount(void); -+#endif /* __ARM_ARCH_7R__ */ -+ -+extern uint32 get_arm_inttimer(void); -+extern void set_arm_inttimer(uint32 ticks); -+ -+extern uint32 get_arm_intmask(void); -+extern void set_arm_intmask(uint32 ticks); -+ -+extern uint32 get_arm_intstatus(void); -+extern void set_arm_intstatus(uint32 ticks); -+ -+extern uint32 get_arm_firqmask(void); -+extern void set_arm_firqmask(uint32 ticks); -+ -+extern uint32 get_arm_firqstatus(void); -+extern void set_arm_firqstatus(uint32 ticks); -+ -+extern void arm_wfi(si_t *sih); -+extern void arm_jumpto(void *addr); -+ -+extern void traptest(void); -+ -+#ifdef BCMOVLHW -+#define BCMOVLHW_ENAB(sih) TRUE -+ -+extern int si_arm_ovl_remap(si_t *sih, void *virt, void *phys, uint size); -+extern int si_arm_ovl_reset(si_t *sih); -+extern bool si_arm_ovl_vaildaddr(si_t *sih, void *virt); -+extern bool si_arm_ovl_isenab(si_t *sih); -+extern bool si_arm_ovl_int(si_t *sih, uint32 pc); -+#else -+#define BCMOVLHW_ENAB(sih) FALSE -+ -+#define si_arm_ovl_remap(a, b, c, d) do {} while (0) -+#define si_arm_ovl_reset(a) do {} while (0) -+#define si_arm_ovl_int(a, b) FALSE -+#endif -+ -+#endif /* _hndarm_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/hndchipc.h b/drivers/net/ethernet/broadcom/gmac/src/include/hndchipc.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/hndchipc.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/hndchipc.h 2017-11-09 17:53:43.962303000 +0800 -@@ -0,0 +1,38 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * HND SiliconBackplane chipcommon support. -+ * -+ * $Id: hndchipc.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _hndchipc_h_ -+#define _hndchipc_h_ -+ -+typedef void (*si_serial_init_fn)(void *regs, uint irq, uint baud_base, uint reg_shift); -+ -+extern void si_serial_init(si_t *sih, si_serial_init_fn add); -+ -+extern void *hnd_jtagm_init(si_t *sih, uint clkd, bool exttap); -+extern void hnd_jtagm_disable(si_t *sih, void *h); -+extern uint32 jtag_scan(si_t *sih, void *h, uint irsz, uint32 ir0, uint32 ir1, -+ uint drsz, uint32 dr0, uint32 *dr1, bool rti); -+ -+typedef void (*cc_isr_fn)(void* cbdata, uint32 ccintst); -+ -+extern bool si_cc_register_isr(si_t *sih, cc_isr_fn isr, uint32 ccintmask, void *cbdata); -+extern void si_cc_isr(si_t *sih, chipcregs_t *regs); -+ -+#endif /* _hndchipc_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/hndcpu.h b/drivers/net/ethernet/broadcom/gmac/src/include/hndcpu.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/hndcpu.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/hndcpu.h 2017-11-09 17:53:43.963297000 +0800 -@@ -0,0 +1,40 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * HND SiliconBackplane MIPS/ARM cores software interface. -+ * -+ * $Id: hndcpu.h 258983 2011-05-11 09:59:25Z $ -+ */ -+ -+#ifndef _hndcpu_h_ -+#define _hndcpu_h_ -+ -+#if defined(mips) -+#include -+#elif defined(__arm__) || defined(__thumb__) || defined(__thumb2__) -+#include -+#endif -+ -+extern uint si_irq(si_t *sih); -+extern uint32 si_cpu_clock(si_t *sih); -+extern uint32 si_mem_clock(si_t *sih); -+extern void hnd_cpu_wait(si_t *sih); -+extern void hnd_cpu_jumpto(void *addr); -+extern void hnd_cpu_reset(si_t *sih); -+extern void hnd_cpu_deadman_timer(si_t *sih, uint32 val); -+extern void si_router_coma(si_t *sih, int reset, int delay); -+extern void si_dmc_phyctl(si_t *sih, uint32 phyctl_val); -+ -+#endif /* _hndcpu_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/hnddma.h b/drivers/net/ethernet/broadcom/gmac/src/include/hnddma.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/hnddma.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/hnddma.h 2017-11-09 17:53:43.964295000 +0800 -@@ -0,0 +1,317 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface -+ * This supports the following chips: BCM42xx, 44xx, 47xx . -+ * -+ * $Id: hnddma.h 321146 2012-03-14 08:27:23Z $ -+ */ -+ -+#ifndef _hnddma_h_ -+#define _hnddma_h_ -+ -+#ifndef _hnddma_pub_ -+#define _hnddma_pub_ -+typedef const struct hnddma_pub hnddma_t; -+#endif /* _hnddma_pub_ */ -+ -+/* range param for dma_getnexttxp() and dma_txreclaim */ -+typedef enum txd_range { -+ HNDDMA_RANGE_ALL = 1, -+ HNDDMA_RANGE_TRANSMITTED, -+ HNDDMA_RANGE_TRANSFERED -+} txd_range_t; -+ -+/* dma parameters id */ -+enum dma_param_id { -+ HNDDMA_PID_TX_MULTI_OUTSTD_RD = 0, -+ HNDDMA_PID_TX_PREFETCH_CTL, -+ HNDDMA_PID_TX_PREFETCH_THRESH, -+ HNDDMA_PID_TX_BURSTLEN, -+ -+ HNDDMA_PID_RX_PREFETCH_CTL = 0x100, -+ HNDDMA_PID_RX_PREFETCH_THRESH, -+ HNDDMA_PID_RX_BURSTLEN -+}; -+ -+/* dma function type */ -+typedef void (*di_detach_t)(hnddma_t *dmah); -+typedef bool (*di_txreset_t)(hnddma_t *dmah); -+typedef bool (*di_rxreset_t)(hnddma_t *dmah); -+typedef bool (*di_rxidle_t)(hnddma_t *dmah); -+typedef void (*di_txinit_t)(hnddma_t *dmah); -+typedef bool (*di_txenabled_t)(hnddma_t *dmah); -+typedef void (*di_rxinit_t)(hnddma_t *dmah); -+typedef void (*di_txsuspend_t)(hnddma_t *dmah); -+typedef void (*di_txresume_t)(hnddma_t *dmah); -+typedef bool (*di_txsuspended_t)(hnddma_t *dmah); -+typedef bool (*di_txsuspendedidle_t)(hnddma_t *dmah); -+#ifdef WL_MULTIQUEUE -+typedef void (*di_txflush_t)(hnddma_t *dmah); -+typedef void (*di_txflush_clear_t)(hnddma_t *dmah); -+#endif /* WL_MULTIQUEUE */ -+typedef int (*di_txfast_t)(hnddma_t *dmah, void *p, bool commit); -+typedef int (*di_txunframed_t)(hnddma_t *dmah, void *p, uint len, bool commit); -+typedef int (*di_rxunframed_t)(hnddma_t *dmah, void *p, uint len, bool commit); -+typedef void* (*di_getpos_t)(hnddma_t *di, bool direction); -+typedef void (*di_fifoloopbackenable_t)(hnddma_t *dmah); -+typedef bool (*di_txstopped_t)(hnddma_t *dmah); -+typedef bool (*di_rxstopped_t)(hnddma_t *dmah); -+typedef bool (*di_rxenable_t)(hnddma_t *dmah); -+typedef bool (*di_rxenabled_t)(hnddma_t *dmah); -+typedef void* (*di_rx_t)(hnddma_t *dmah); -+typedef bool (*di_rxfill_t)(hnddma_t *dmah); -+typedef void (*di_txreclaim_t)(hnddma_t *dmah, txd_range_t range); -+typedef void (*di_rxreclaim_t)(hnddma_t *dmah); -+typedef uintptr (*di_getvar_t)(hnddma_t *dmah, const char *name); -+typedef void* (*di_getnexttxp_t)(hnddma_t *dmah, txd_range_t range); -+typedef void* (*di_getnextrxp_t)(hnddma_t *dmah, bool forceall); -+typedef void* (*di_peeknexttxp_t)(hnddma_t *dmah); -+typedef void* (*di_peekntxp_t)(hnddma_t *dmah, int *len, void *txps[], txd_range_t range); -+typedef void* (*di_peeknextrxp_t)(hnddma_t *dmah); -+typedef void (*di_rxparam_get_t)(hnddma_t *dmah, uint16 *rxoffset, uint16 *rxbufsize); -+typedef void (*di_txblock_t)(hnddma_t *dmah); -+typedef void (*di_txunblock_t)(hnddma_t *dmah); -+typedef uint (*di_txactive_t)(hnddma_t *dmah); -+typedef void (*di_txrotate_t)(hnddma_t *dmah); -+typedef void (*di_counterreset_t)(hnddma_t *dmah); -+typedef uint (*di_ctrlflags_t)(hnddma_t *dmah, uint mask, uint flags); -+typedef char* (*di_dump_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); -+typedef char* (*di_dumptx_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); -+typedef char* (*di_dumprx_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); -+typedef uint (*di_rxactive_t)(hnddma_t *dmah); -+typedef uint (*di_txpending_t)(hnddma_t *dmah); -+typedef uint (*di_txcommitted_t)(hnddma_t *dmah); -+typedef int (*di_pktpool_set_t)(hnddma_t *dmah, pktpool_t *pool); -+typedef bool (*di_rxtxerror_t)(hnddma_t *dmah, bool istx); -+typedef void (*di_burstlen_set_t)(hnddma_t *dmah, uint8 rxburstlen, uint8 txburstlen); -+typedef uint (*di_avoidancecnt_t)(hnddma_t *dmah); -+typedef void (*di_param_set_t)(hnddma_t *dmah, uint16 paramid, uint16 paramval); -+typedef bool (*dma_glom_enable_t) (hnddma_t *dmah, uint32 val); -+typedef uint (*dma_active_rxbuf_t) (hnddma_t *dmah); -+/* dma opsvec */ -+typedef struct di_fcn_s { -+ di_detach_t detach; -+ di_txinit_t txinit; -+ di_txreset_t txreset; -+ di_txenabled_t txenabled; -+ di_txsuspend_t txsuspend; -+ di_txresume_t txresume; -+ di_txsuspended_t txsuspended; -+ di_txsuspendedidle_t txsuspendedidle; -+#ifdef WL_MULTIQUEUE -+ di_txflush_t txflush; -+ di_txflush_clear_t txflush_clear; -+#endif /* WL_MULTIQUEUE */ -+ di_txfast_t txfast; -+ di_txunframed_t txunframed; -+ di_getpos_t getpos; -+ di_txstopped_t txstopped; -+ di_txreclaim_t txreclaim; -+ di_getnexttxp_t getnexttxp; -+ di_peeknexttxp_t peeknexttxp; -+ di_peekntxp_t peekntxp; -+ di_txblock_t txblock; -+ di_txunblock_t txunblock; -+ di_txactive_t txactive; -+ di_txrotate_t txrotate; -+ -+ di_rxinit_t rxinit; -+ di_rxreset_t rxreset; -+ di_rxidle_t rxidle; -+ di_rxstopped_t rxstopped; -+ di_rxenable_t rxenable; -+ di_rxenabled_t rxenabled; -+ di_rx_t rx; -+ di_rxfill_t rxfill; -+ di_rxreclaim_t rxreclaim; -+ di_getnextrxp_t getnextrxp; -+ di_peeknextrxp_t peeknextrxp; -+ di_rxparam_get_t rxparam_get; -+ -+ di_fifoloopbackenable_t fifoloopbackenable; -+ di_getvar_t d_getvar; -+ di_counterreset_t counterreset; -+ di_ctrlflags_t ctrlflags; -+ di_dump_t dump; -+ di_dumptx_t dumptx; -+ di_dumprx_t dumprx; -+ di_rxactive_t rxactive; -+ di_txpending_t txpending; -+ di_txcommitted_t txcommitted; -+ di_pktpool_set_t pktpool_set; -+ di_rxtxerror_t rxtxerror; -+ di_burstlen_set_t burstlen_set; -+ di_avoidancecnt_t avoidancecnt; -+ di_param_set_t param_set; -+ dma_glom_enable_t glom_enab; -+ di_rxunframed_t rxunframed; -+ dma_active_rxbuf_t dma_activerxbuf; -+ uint endnum; -+} di_fcn_t; -+ -+/* -+ * Exported data structure (read-only) -+ */ -+/* export structure */ -+struct hnddma_pub { -+ const di_fcn_t *di_fn; /* DMA function pointers */ -+ uint txavail; /* # free tx descriptors */ -+ uint dmactrlflags; /* dma control flags */ -+ -+ /* rx error counters */ -+ uint rxgiants; /* rx giant frames */ -+ uint rxnobuf; /* rx out of dma descriptors */ -+ /* tx error counters */ -+ uint txnobuf; /* tx out of dma descriptors */ -+ uint txnodesc; /* tx out of dma descriptors running count */ -+}; -+ -+ -+extern hnddma_t * dma_attach(osl_t *osh, const char *name, si_t *sih, -+ volatile void *dmaregstx, volatile void *dmaregsrx, -+ uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, uint nrxpost, -+ uint rxoffset, uint *msg_level); -+#ifdef BCMDMA32 -+ -+#define dma_detach(di) ((di)->di_fn->detach(di)) -+#define dma_txreset(di) ((di)->di_fn->txreset(di)) -+#define dma_rxreset(di) ((di)->di_fn->rxreset(di)) -+#define dma_rxidle(di) ((di)->di_fn->rxidle(di)) -+#define dma_txinit(di) ((di)->di_fn->txinit(di)) -+#define dma_txenabled(di) ((di)->di_fn->txenabled(di)) -+#define dma_rxinit(di) ((di)->di_fn->rxinit(di)) -+#define dma_txsuspend(di) ((di)->di_fn->txsuspend(di)) -+#define dma_txresume(di) ((di)->di_fn->txresume(di)) -+#define dma_txsuspended(di) ((di)->di_fn->txsuspended(di)) -+#define dma_txsuspendedidle(di) ((di)->di_fn->txsuspendedidle(di)) -+#ifdef WL_MULTIQUEUE -+#define dma_txflush(di) ((di)->di_fn->txflush(di)) -+#define dma_txflush_clear(di) ((di)->di_fn->txflush_clear(di)) -+#endif /* WL_MULTIQUEUE */ -+#define dma_txfast(di, p, commit) ((di)->di_fn->txfast(di, p, commit)) -+#define dma_fifoloopbackenable(di) ((di)->di_fn->fifoloopbackenable(di)) -+#define dma_txstopped(di) ((di)->di_fn->txstopped(di)) -+#define dma_rxstopped(di) ((di)->di_fn->rxstopped(di)) -+#define dma_rxenable(di) ((di)->di_fn->rxenable(di)) -+#define dma_rxenabled(di) ((di)->di_fn->rxenabled(di)) -+#define dma_rx(di) ((di)->di_fn->rx(di)) -+#define dma_rxfill(di) ((di)->di_fn->rxfill(di)) -+#define dma_txreclaim(di, range) ((di)->di_fn->txreclaim(di, range)) -+#define dma_rxreclaim(di) ((di)->di_fn->rxreclaim(di)) -+#define dma_getvar(di, name) ((di)->di_fn->d_getvar(di, name)) -+#define dma_getnexttxp(di, range) ((di)->di_fn->getnexttxp(di, range)) -+#define dma_getnextrxp(di, forceall) ((di)->di_fn->getnextrxp(di, forceall)) -+#define dma_peeknexttxp(di) ((di)->di_fn->peeknexttxp(di)) -+#define dma_peekntxp(di, l, t, r) ((di)->di_fn->peekntxp(di, l, t, r)) -+#define dma_peeknextrxp(di) ((di)->di_fn->peeknextrxp(di)) -+#define dma_rxparam_get(di, off, bufs) ((di)->di_fn->rxparam_get(di, off, bufs)) -+ -+#define dma_txblock(di) ((di)->di_fn->txblock(di)) -+#define dma_txunblock(di) ((di)->di_fn->txunblock(di)) -+#define dma_txactive(di) ((di)->di_fn->txactive(di)) -+#define dma_rxactive(di) ((di)->di_fn->rxactive(di)) -+#define dma_txrotate(di) ((di)->di_fn->txrotate(di)) -+#define dma_counterreset(di) ((di)->di_fn->counterreset(di)) -+#define dma_ctrlflags(di, mask, flags) ((di)->di_fn->ctrlflags((di), (mask), (flags))) -+#define dma_txpending(di) ((di)->di_fn->txpending(di)) -+#define dma_txcommitted(di) ((di)->di_fn->txcommitted(di)) -+#define dma_pktpool_set(di, pool) ((di)->di_fn->pktpool_set((di), (pool))) -+#if defined(BCMDBG) -+#define dma_dump(di, buf, dumpring) ((di)->di_fn->dump(di, buf, dumpring)) -+#define dma_dumptx(di, buf, dumpring) ((di)->di_fn->dumptx(di, buf, dumpring)) -+#define dma_dumprx(di, buf, dumpring) ((di)->di_fn->dumprx(di, buf, dumpring)) -+#endif -+#define dma_rxtxerror(di, istx) ((di)->di_fn->rxtxerror(di, istx)) -+#define dma_burstlen_set(di, rxlen, txlen) ((di)->di_fn->burstlen_set(di, rxlen, txlen)) -+#define dma_avoidance_cnt(di) ((di)->di_fn->avoidancecnt(di)) -+#define dma_param_set(di, paramid, paramval) ((di)->di_fn->param_set(di, paramid, paramval)) -+#define dma_activerxbuf(di) ((di)->di_fn->dma_activerxbuf(di)) -+ -+#else /* BCMDMA32 */ -+extern const di_fcn_t dma64proc; -+ -+#define dma_detach(di) (dma64proc.detach(di)) -+#define dma_txreset(di) (dma64proc.txreset(di)) -+#define dma_rxreset(di) (dma64proc.rxreset(di)) -+#define dma_rxidle(di) (dma64proc.rxidle(di)) -+#define dma_txinit(di) (dma64proc.txinit(di)) -+#define dma_txenabled(di) (dma64proc.txenabled(di)) -+#define dma_rxinit(di) (dma64proc.rxinit(di)) -+#define dma_txsuspend(di) (dma64proc.txsuspend(di)) -+#define dma_txresume(di) (dma64proc.txresume(di)) -+#define dma_txsuspended(di) (dma64proc.txsuspended(di)) -+#define dma_txsuspendedidle(di) (dma64proc.txsuspendedidle(di)) -+#ifdef WL_MULTIQUEUE -+#define dma_txflush(di) (dma64proc.txflush(di)) -+#define dma_txflush_clear(di) (dma64proc.txflush_clear(di)) -+#endif /* WL_MULTIQUEUE */ -+#define dma_txfast(di, p, commit) (dma64proc.txfast(di, p, commit)) -+#define dma_txunframed(di, p, l, commit)(dma64proc.txunframed(di, p, l, commit)) -+#define dma_getpos(di, dir) (dma64proc.getpos(di, dir)) -+#define dma_fifoloopbackenable(di) (dma64proc.fifoloopbackenable(di)) -+#define dma_txstopped(di) (dma64proc.txstopped(di)) -+#define dma_rxstopped(di) (dma64proc.rxstopped(di)) -+#define dma_rxenable(di) (dma64proc.rxenable(di)) -+#define dma_rxenabled(di) (dma64proc.rxenabled(di)) -+#define dma_rx(di) (dma64proc.rx(di)) -+#define dma_rxfill(di) (dma64proc.rxfill(di)) -+#define dma_txreclaim(di, range) (dma64proc.txreclaim(di, range)) -+#define dma_rxreclaim(di) (dma64proc.rxreclaim(di)) -+#define dma_getvar(di, name) (dma64proc.d_getvar(di, name)) -+#define dma_getnexttxp(di, range) (dma64proc.getnexttxp(di, range)) -+#define dma_getnextrxp(di, forceall) (dma64proc.getnextrxp(di, forceall)) -+#define dma_peeknexttxp(di) (dma64proc.peeknexttxp(di)) -+#define dma_peekntxp(di, l, t, r) (dma64proc.peekntxp(di, l, t, r)) -+#define dma_peeknextrxp(di) (dma64proc.peeknextrxp(di)) -+#define dma_rxparam_get(di, off, bufs) (dma64proc.rxparam_get(di, off, bufs)) -+ -+#define dma_txblock(di) (dma64proc.txblock(di)) -+#define dma_txunblock(di) (dma64proc.txunblock(di)) -+#define dma_txactive(di) (dma64proc.txactive(di)) -+#define dma_rxactive(di) (dma64proc.rxactive(di)) -+#define dma_txrotate(di) (dma64proc.txrotate(di)) -+#define dma_counterreset(di) (dma64proc.counterreset(di)) -+#define dma_ctrlflags(di, mask, flags) (dma64proc.ctrlflags((di), (mask), (flags))) -+#define dma_txpending(di) (dma64proc.txpending(di)) -+#define dma_txcommitted(di) (dma64proc.txcommitted(di)) -+#define dma_pktpool_set(di, pool) (dma64proc.pktpool_set((di), (pool))) -+#define dma_rxunframed(di, p, l, commit)(dma64proc.rxunframed(di, p, l, commit)) -+#if defined(BCMDBG) -+#define dma_dump(di, buf, dumpring) (dma64proc.dump(di, buf, dumpring)) -+#define dma_dumptx(di, buf, dumpring) (dma64proc.dumptx(di, buf, dumpring)) -+#define dma_dumprx(di, buf, dumpring) (dma64proc.dumprx(di, buf, dumpring)) -+#endif -+#define dma_rxtxerror(di, istx) (dma64proc.rxtxerror(di, istx)) -+#define dma_burstlen_set(di, rxlen, txlen) (dma64proc.burstlen_set(di, rxlen, txlen)) -+#define dma_avoidance_cnt(di) (dma64proc.avoidancecnt(di)) -+#define dma_param_set(di, paramid, paramval) (dma64proc.param_set(di, paramid, paramval)) -+ -+#define dma_glom_enable(di, val) (dma64proc.glom_enab(di, val)) -+#define dma_activerxbuf(di) (dma64proc.dma_activerxbuf(di)) -+ -+#endif /* BCMDMA32 */ -+ -+/* return addresswidth allowed -+ * This needs to be done after SB attach but before dma attach. -+ * SB attach provides ability to probe backplane and dma core capabilities -+ * This info is needed by DMA_ALLOC_CONSISTENT in dma attach -+ */ -+extern uint dma_addrwidth(si_t *sih, void *dmaregs); -+ -+/* pio helpers */ -+extern void dma_txpioloopback(osl_t *osh, dma32regs_t *); -+ -+#endif /* _hnddma_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/hndsoc.h b/drivers/net/ethernet/broadcom/gmac/src/include/hndsoc.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/hndsoc.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/hndsoc.h 2017-11-09 17:53:43.965312000 +0800 -@@ -0,0 +1,259 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom HND chip & on-chip-interconnect-related definitions. -+ * -+ * $Id: hndsoc.h 325951 2012-04-05 06:03:27Z $ -+ */ -+ -+#ifndef _HNDSOC_H -+#define _HNDSOC_H -+ -+/* Include the soci specific files */ -+#include -+#include -+ -+/* -+ * SOC Interconnect Address Map. -+ * All regions may not exist on all chips. -+ */ -+#define SI_SDRAM_BASE 0x00000000 /* Physical SDRAM */ -+#define SI_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */ -+#define SI_PCI_MEM_SZ (64 * 1024 * 1024) -+#define SI_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */ -+#define SI_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ -+#define SI_SDRAM_R2 0x80000000 /* Region 2 for sdram (512 MB) */ -+#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */ -+#define SI_WRAP_BASE 0x18100000 /* Wrapper space base */ -+#define SI_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */ -+#define SI_MAXCORES 20 /* Max cores (this is arbitrary, for software -+ * convenience and could be changed if we -+ * make any larger chips -+ */ -+ -+#define SI_FASTRAM 0x19000000 /* On-chip RAM on chips that also have DDR */ -+#define SI_FASTRAM_SWAPPED 0x19800000 -+ -+#define SI_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */ -+#define SI_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */ -+#define SI_ARMCM3_ROM 0x1e000000 /* ARM Cortex-M3 ROM */ -+#define SI_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */ -+#define SI_FLASH1_SZ 0x00400000 /* MIPS Size of Flash Region 1 */ -+ -+#define SI_NS_NANDFLASH 0x1c000000 /* NorthStar NAND flash base */ -+#define SI_NS_NORFLASH 0x1e000000 /* NorthStar NOR flash base */ -+#define SI_NS_NORFLASH_SZ 0x02000000 /* Size of NorthStar NOR flash region */ -+#define SI_NS_ROM 0xfffd0000 /* NorthStar ROM */ -+ -+#define SI_ARM7S_ROM 0x20000000 /* ARM7TDMI-S ROM */ -+#define SI_ARMCR4_ROM 0x000f0000 /* ARM Cortex-R4 ROM */ -+#define SI_ARMCM3_SRAM2 0x60000000 /* ARM Cortex-M3 SRAM Region 2 */ -+#define SI_ARM7S_SRAM2 0x80000000 /* ARM7TDMI-S SRAM Region 2 */ -+#define SI_ARM_FLASH1 0xffff0000 /* ARM Flash Region 1 */ -+#define SI_ARM_FLASH1_SZ 0x00010000 /* ARM Size of Flash Region 1 */ -+ -+#define SI_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */ -+#define SI_PCI_DMA2 0x80000000 /* Client Mode sb2pcitranslation2 (1 GB) */ -+#define SI_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */ -+#define SI_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2 -+ * (2 ZettaBytes), low 32 bits -+ */ -+#define SI_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2 -+ * (2 ZettaBytes), high 32 bits -+ */ -+#define SI_NS_CUR 0x1800B000 /* NorthStar CUR base */ -+ -+#define SI_NS_CHIPCB_SRAB 0x18036000 /* NorthStar+ Chip Common B SRAB base */ -+ -+/* core codes */ -+#define NODEV_CORE_ID 0x700 /* Invalid coreid */ -+#define CC_CORE_ID 0x800 /* chipcommon core */ -+#define ILINE20_CORE_ID 0x801 /* iline20 core */ -+#define SRAM_CORE_ID 0x802 /* sram core */ -+#define SDRAM_CORE_ID 0x803 /* sdram core */ -+#define PCI_CORE_ID 0x804 /* pci core */ -+#define MIPS_CORE_ID 0x805 /* mips core */ -+#define ENET_CORE_ID 0x806 /* enet mac core */ -+#define CODEC_CORE_ID 0x807 /* v90 codec core */ -+#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */ -+#define ADSL_CORE_ID 0x809 /* ADSL core */ -+#define ILINE100_CORE_ID 0x80a /* iline100 core */ -+#define IPSEC_CORE_ID 0x80b /* ipsec core */ -+#define UTOPIA_CORE_ID 0x80c /* utopia core */ -+#define PCMCIA_CORE_ID 0x80d /* pcmcia core */ -+#define SOCRAM_CORE_ID 0x80e /* internal memory core */ -+#define MEMC_CORE_ID 0x80f /* memc sdram core */ -+#define OFDM_CORE_ID 0x810 /* OFDM phy core */ -+#define EXTIF_CORE_ID 0x811 /* external interface core */ -+#define D11_CORE_ID 0x812 /* 802.11 MAC core */ -+#define APHY_CORE_ID 0x813 /* 802.11a phy core */ -+#define BPHY_CORE_ID 0x814 /* 802.11b phy core */ -+#define GPHY_CORE_ID 0x815 /* 802.11g phy core */ -+#define MIPS33_CORE_ID 0x816 /* mips3302 core */ -+#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */ -+#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */ -+#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */ -+#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */ -+#define SDIOH_CORE_ID 0x81b /* sdio host core */ -+#define ROBO_CORE_ID 0x81c /* roboswitch core */ -+#define ATA100_CORE_ID 0x81d /* parallel ATA core */ -+#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */ -+#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */ -+#define PCIE_CORE_ID 0x820 /* pci express core */ -+#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */ -+#define SRAMC_CORE_ID 0x822 /* SRAM controller core */ -+#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */ -+#define ARM11_CORE_ID 0x824 /* ARM 1176 core */ -+#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */ -+#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */ -+#define PMU_CORE_ID 0x827 /* PMU core */ -+#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */ -+#define SDIOD_CORE_ID 0x829 /* SDIO device core */ -+#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */ -+#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */ -+#define MIPS74K_CORE_ID 0x82c /* mips 74k core */ -+#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ -+#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */ -+#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */ -+#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */ -+#define SC_CORE_ID 0x831 /* shared common core */ -+#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */ -+#define SPIH_CORE_ID 0x833 /* SPI host core */ -+#define I2S_CORE_ID 0x834 /* I2S core */ -+#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ -+#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ -+ -+#define ACPHY_CORE_ID 0x83b /* Dot11 ACPHY */ -+#define PCIE2_CORE_ID 0x83c /* pci express Gen2 core */ -+#define USB30D_CORE_ID 0x83d /* usb 3.0 device core */ -+#define ARMCR4_CORE_ID 0x83e /* ARM CR4 CPU */ -+#define APB_BRIDGE_CORE_ID 0x135 /* APB bridge core ID */ -+#define AXI_CORE_ID 0x301 /* AXI/GPV core ID */ -+#define EROM_CORE_ID 0x366 /* EROM core ID */ -+#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ -+#define DEF_AI_COMP 0xfff /* Default component, in ai chips it maps all -+ * unused address ranges -+ */ -+ -+#define CC_4706_CORE_ID 0x500 /* chipcommon core */ -+#define NS_PCIEG2_CORE_ID 0x501 /* PCIE Gen 2 core */ -+#define NS_DMA_CORE_ID 0x502 /* DMA core */ -+#define NS_SDIO3_CORE_ID 0x503 /* SDIO3 core */ -+#define NS_USB20_CORE_ID 0x504 /* USB2.0 core */ -+#define NS_USB30_CORE_ID 0x505 /* USB3.0 core */ -+#define NS_A9JTAG_CORE_ID 0x506 /* ARM Cortex A9 JTAG core */ -+#define NS_DDR23_CORE_ID 0x507 /* Denali DDR2/DDR3 memory controller */ -+#define NS_ROM_CORE_ID 0x508 /* ROM core */ -+#define NS_NAND_CORE_ID 0x509 /* NAND flash controller core */ -+#define NS_QSPI_CORE_ID 0x50a /* SPI flash controller core */ -+#define NS_CCB_CORE_ID 0x50b /* ChipcommonB core */ -+#define SOCRAM_4706_CORE_ID 0x50e /* internal memory core */ -+#define NS_SOCRAM_CORE_ID SOCRAM_4706_CORE_ID -+#define ARMCA9_CORE_ID 0x510 /* ARM Cortex A9 core (ihost) */ -+#define NS_IHOST_CORE_ID ARMCA9_CORE_ID /* ARM Cortex A9 core (ihost) */ -+#define GMAC_COMMON_4706_CORE_ID 0x5dc /* Gigabit MAC core */ -+#define GMAC_4706_CORE_ID 0x52d /* Gigabit MAC core */ -+#define AMEMC_CORE_ID 0x52e /* DDR1/2 memory controller core */ -+#define ALTA_CORE_ID 0x534 /* I2S core */ -+#define DDR23_PHY_CORE_ID 0x5dd -+ -+#define SI_PCI1_MEM 0x40000000 /* Host Mode sb2pcitranslation0 (64 MB) */ -+#define SI_PCI1_CFG 0x44000000 /* Host Mode sb2pcitranslation1 (64 MB) */ -+#define SI_PCIE1_DMA_H32 0xc0000000 /* PCIE Client Mode sb2pcitranslation2 -+ * (2 ZettaBytes), high 32 bits -+ */ -+#define CC_4706B0_CORE_REV 0x8000001f /* chipcommon core */ -+#define SOCRAM_4706B0_CORE_REV 0x80000005 /* internal memory core */ -+#define GMAC_4706B0_CORE_REV 0x80000000 /* Gigabit MAC core */ -+ -+/* There are TWO constants on all HND chips: SI_ENUM_BASE above, -+ * and chipcommon being the first core: -+ */ -+#define SI_CC_IDX 0 -+ -+/* SOC Interconnect types (aka chip types) */ -+#define SOCI_SB 0 -+#define SOCI_AI 1 -+#define SOCI_UBUS 2 -+#define SOCI_NS 3 -+ -+/* Common core control flags */ -+#define SICF_BIST_EN 0x8000 -+#define SICF_PME_EN 0x4000 -+#define SICF_CORE_BITS 0x3ffc -+#define SICF_FGC 0x0002 -+#define SICF_CLOCK_EN 0x0001 -+ -+/* Common core status flags */ -+#define SISF_BIST_DONE 0x8000 -+#define SISF_BIST_ERROR 0x4000 -+#define SISF_GATED_CLK 0x2000 -+#define SISF_DMA64 0x1000 -+#define SISF_CORE_BITS 0x0fff -+ -+/* Norstar core status flags */ -+#define SISF_NS_BOOTDEV_MASK 0x0003 /* ROM core */ -+#define SISF_NS_BOOTDEV_NOR 0x0000 /* ROM core */ -+#define SISF_NS_BOOTDEV_NAND 0x0001 /* ROM core */ -+#define SISF_NS_BOOTDEV_ROM 0x0002 /* ROM core */ -+#define SISF_NS_BOOTDEV_OFFLOAD 0x0003 /* ROM core */ -+#define SISF_NS_SKUVEC_MASK 0x000c /* ROM core */ -+ -+/* A register that is common to all cores to -+ * communicate w/PMU regarding clock control. -+ */ -+#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */ -+ -+/* clk_ctl_st register */ -+#define CCS_FORCEALP 0x00000001 /* force ALP request */ -+#define CCS_FORCEHT 0x00000002 /* force HT request */ -+#define CCS_FORCEILP 0x00000004 /* force ILP request */ -+#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */ -+#define CCS_HTAREQ 0x00000010 /* HT Avail Request */ -+#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */ -+#define CCS_HQCLKREQ 0x00000040 /* HQ Clock Required */ -+#define CCS_USBCLKREQ 0x00000100 /* USB Clock Req */ -+#define CCS_ERSRC_REQ_MASK 0x00000700 /* external resource requests */ -+#define CCS_ERSRC_REQ_SHIFT 8 -+#define CCS_ALPAVAIL 0x00010000 /* ALP is available */ -+#define CCS_HTAVAIL 0x00020000 /* HT is available */ -+#define CCS_BP_ON_APL 0x00040000 /* RO: Backplane is running on ALP clock */ -+#define CCS_BP_ON_HT 0x00080000 /* RO: Backplane is running on HT clock */ -+#define CCS_ERSRC_STS_MASK 0x07000000 /* external resource status */ -+#define CCS_ERSRC_STS_SHIFT 24 -+ -+#define CCS0_HTAVAIL 0x00010000 /* HT avail in chipc and pcmcia on 4328a0 */ -+#define CCS0_ALPAVAIL 0x00020000 /* ALP avail in chipc and pcmcia on 4328a0 */ -+ -+/* Not really related to SOC Interconnect, but a couple of software -+ * conventions for the use the flash space: -+ */ -+ -+/* Minumum amount of flash we support */ -+#define FLASH_MIN 0x00020000 /* Minimum flash size */ -+ -+/* A boot/binary may have an embedded block that describes its size */ -+#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */ -+#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */ -+#define BISZ_MAGIC_IDX 0 /* Word 0: magic */ -+#define BISZ_TXTST_IDX 1 /* 1: text start */ -+#define BISZ_TXTEND_IDX 2 /* 2: text end */ -+#define BISZ_DATAST_IDX 3 /* 3: data start */ -+#define BISZ_DATAEND_IDX 4 /* 4: data end */ -+#define BISZ_BSSST_IDX 5 /* 5: bss start */ -+#define BISZ_BSSEND_IDX 6 /* 6: bss end */ -+#define BISZ_SIZE 7 /* descriptor size in 32-bit integers */ -+ -+#endif /* _HNDSOC_H */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/hndtcam.h b/drivers/net/ethernet/broadcom/gmac/src/include/hndtcam.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/hndtcam.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/hndtcam.h 2017-11-09 17:53:43.966304000 +0800 -@@ -0,0 +1,95 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * HND SOCRAM TCAM software interface. -+ * -+ * $Id: hndtcam.h 317281 2012-02-27 11:23:27Z $ -+ */ -+#ifndef _hndtcam_h_ -+#define _hndtcam_h_ -+ -+/* -+ * 0 - 1 -+ * 1 - 2 Consecutive locations are patched -+ * 2 - 4 Consecutive locations are patched -+ * 3 - 8 Consecutive locations are patched -+ * 4 - 16 Consecutive locations are patched -+ * Define default to patch 2 locations -+ */ -+ -+#ifdef PATCHCOUNT -+#define SRPC_PATCHCOUNT PATCHCOUNT -+#else -+#define PATCHCOUNT 0 -+#define SRPC_PATCHCOUNT PATCHCOUNT -+#endif -+ -+#if defined(__ARM_ARCH_7R__) -+#ifndef PATCHCOUNT -+#define PATCHCOUNT 1 -+#endif -+#define ARMCR4_TCAMPATCHCOUNT PATCHCOUNT -+#define ARMCR4_TCAMADDR_MASK (~((1 << (ARMCR4_TCAMPATCHCOUNT + 2))-1)) -+#define ARMCR4_PATCHNLOC (1 << ARMCR4_TCAMPATCHCOUNT) -+#endif /* defined(__ARM_ARCH_7R__) */ -+ -+/* N Consecutive location to patch */ -+#define SRPC_PATCHNLOC (1 << (SRPC_PATCHCOUNT)) -+ -+#define PATCHHDR(_p) __attribute__ ((__section__ (".patchhdr."#_p))) _p -+#define PATCHENTRY(_p) __attribute__ ((__section__ (".patchentry."#_p))) _p -+ -+#if defined(__ARM_ARCH_7R__) -+typedef struct { -+ uint32 data[ARMCR4_PATCHNLOC]; -+} patch_entry_t; -+#else -+typedef struct { -+ uint32 data[SRPC_PATCHNLOC]; -+} patch_entry_t; -+#endif -+ -+typedef struct { -+ void *addr; /* patch address */ -+ uint32 len; /* bytes to patch in entry */ -+ patch_entry_t *entry; /* patch entry data */ -+} patch_hdr_t; -+ -+/* patch values and address structure */ -+typedef struct patchaddrvalue { -+ uint32 addr; -+ uint32 value; -+} patchaddrvalue_t; -+ -+extern void *socram_regs; -+extern uint32 socram_rev; -+ -+extern void *arm_regs; -+ -+extern void hnd_patch_init(void *srp); -+extern void hnd_tcam_write(void *srp, uint16 idx, uint32 data); -+extern void hnd_tcam_read(void *srp, uint16 idx, uint32 *content); -+void * hnd_tcam_init(void *srp, int no_addrs); -+extern void hnd_tcam_disablepatch(void *srp); -+extern void hnd_tcam_enablepatch(void *srp); -+#ifdef CONFIG_XIP -+extern void hnd_tcam_bootloader_load(void *srp, char *pvars); -+#else -+extern void hnd_tcam_load(void *srp, const patchaddrvalue_t *patchtbl); -+#endif /* CONFIG_XIP */ -+extern void BCMATTACHFN(hnd_tcam_load_default)(void); -+extern void hnd_tcam_reclaim(void); -+ -+#endif /* _hndtcam_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/linux_osl.h b/drivers/net/ethernet/broadcom/gmac/src/include/linux_osl.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/linux_osl.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/linux_osl.h 2017-11-09 17:53:43.968293000 +0800 -@@ -0,0 +1,737 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Linux OS Independent Layer -+ * -+ * $Id: linux_osl.h 329351 2012-04-25 01:48:39Z $ -+ */ -+ -+#ifndef _linux_osl_h_ -+#define _linux_osl_h_ -+ -+#include -+ -+/* Linux Kernel: File Operations: start */ -+extern void * osl_os_open_image(char * filename); -+extern int osl_os_get_image_block(char * buf, int len, void * image); -+extern void osl_os_close_image(void * image); -+extern int osl_os_image_size(void *image); -+/* Linux Kernel: File Operations: end */ -+ -+#ifdef BCMDRIVER -+ -+/* OSL initialization */ -+extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag); -+extern void osl_detach(osl_t *osh); -+ -+/* Global ASSERT type */ -+extern uint32 g_assert_type; -+ -+/* ASSERT */ -+ #ifdef __GNUC__ -+ #define GCC_VERSION \ -+ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -+ #if GCC_VERSION > 30100 -+ #define ASSERT(exp) do {} while (0) -+ #else -+ /* ASSERT could cause segmentation fault on GCC3.1, use empty instead */ -+ #define ASSERT(exp) -+ #endif /* GCC_VERSION > 30100 */ -+ #endif /* __GNUC__ */ -+ -+/* microsecond delay */ -+#define OSL_DELAY(usec) osl_delay(usec) -+extern void osl_delay(uint usec); -+ -+#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ -+ osl_pcmcia_read_attr((osh), (offset), (buf), (size)) -+#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ -+ osl_pcmcia_write_attr((osh), (offset), (buf), (size)) -+extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size); -+extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size); -+ -+/* PCI configuration space access macros */ -+#define OSL_PCI_READ_CONFIG(osh, offset, size) \ -+ osl_pci_read_config((osh), (offset), (size)) -+#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ -+ osl_pci_write_config((osh), (offset), (size), (val)) -+extern uint32 osl_pci_read_config(osl_t *osh, uint offset, uint size); -+extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); -+ -+/* PCI device bus # and slot # */ -+#define OSL_PCI_BUS(osh) osl_pci_bus(osh) -+#define OSL_PCI_SLOT(osh) osl_pci_slot(osh) -+extern uint osl_pci_bus(osl_t *osh); -+extern uint osl_pci_slot(osl_t *osh); -+extern struct pci_dev *osl_pci_device(osl_t *osh); -+ -+/* Pkttag flag should be part of public information */ -+typedef struct { -+ bool pkttag; -+ bool mmbus; /* Bus supports memory-mapped register accesses */ -+ pktfree_cb_fn_t tx_fn; /* Callback function for PKTFREE */ -+ void *tx_ctx; /* Context to the callback function */ -+#ifdef OSLREGOPS -+ osl_rreg_fn_t rreg_fn; /* Read Register function */ -+ osl_wreg_fn_t wreg_fn; /* Write Register function */ -+ void *reg_ctx; /* Context to the reg callback functions */ -+#else -+ void *unused[3]; -+#endif -+} osl_pubinfo_t; -+ -+#define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \ -+ do { \ -+ ((osl_pubinfo_t*)osh)->tx_fn = _tx_fn; \ -+ ((osl_pubinfo_t*)osh)->tx_ctx = _tx_ctx; \ -+ } while (0) -+ -+#ifdef OSLREGOPS -+#define REGOPSSET(osh, rreg, wreg, ctx) \ -+ do { \ -+ ((osl_pubinfo_t*)osh)->rreg_fn = rreg; \ -+ ((osl_pubinfo_t*)osh)->wreg_fn = wreg; \ -+ ((osl_pubinfo_t*)osh)->reg_ctx = ctx; \ -+ } while (0) -+#endif /* OSLREGOPS */ -+ -+/* host/bus architecture-specific byte swap */ -+// #define BUS_SWAP32(v) (v) /* JIRA:LINUXDEV-16 */ -+#ifdef IL_BIGENDIAN -+#define BUS_SWAP32(v) bcmswap32(v) -+#else -+#define BUS_SWAP32(v) (v) -+#endif /* IL_BIGENDIAN */ -+ -+ #define MALLOC(osh, size) osl_malloc((osh), (size)) -+ #define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size)) -+ #define MALLOCED(osh) osl_malloced((osh)) -+ extern void *osl_malloc(osl_t *osh, uint size); -+ extern void osl_mfree(osl_t *osh, void *addr, uint size); -+ extern uint osl_malloced(osl_t *osh); -+ -+#define NATIVE_MALLOC(osh, size) kmalloc(size, GFP_ATOMIC) -+#define NATIVE_MFREE(osh, addr, size) kfree(addr) -+#ifdef USBAP -+#include -+#define VMALLOC(osh, size) vmalloc(size) -+#define VFREE(osh, addr, size) vfree(addr) -+#endif /* USBAP */ -+ -+#define MALLOC_FAILED(osh) osl_malloc_failed((osh)) -+extern uint osl_malloc_failed(osl_t *osh); -+ -+/* allocate/free shared (dma-able) consistent memory */ -+#define DMA_CONSISTENT_ALIGN osl_dma_consistent_align() -+#define DMA_ALLOC_CONSISTENT(osh, size, align, tot, pap, dmah) \ -+ osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap)) -+#define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \ -+ osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) -+extern uint osl_dma_consistent_align(void); -+extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align, uint *tot, ulong *pap); -+extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa); -+ -+/* map/unmap direction */ -+#define DMA_TX 1 /* TX direction for DMA */ -+#define DMA_RX 2 /* RX direction for DMA */ -+ -+/* map/unmap shared (dma-able) memory */ -+#define DMA_UNMAP(osh, pa, size, direction, p, dmah) \ -+ osl_dma_unmap((osh), (pa), (size), (direction)) -+extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction, void *p, hnddma_seg_map_t *dmah); -+extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); -+ -+/* API for DMA addressing capability */ -+#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0) -+ -+#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) mmap_op -+#define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op -+ -+#define OSL_ERROR(bcmerror) osl_error(bcmerror) -+extern int osl_error(int bcmerror); -+ -+/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ -+#define PKTBUFSZ 2048 /* largest reasonable packet buffer, driver uses for ethernet MTU */ -+ -+/* -+ * BINOSL selects the slightly slower function-call-based binary compatible osl. -+ * Macros expand to calls to functions defined in linux_osl.c . -+ */ -+#ifndef BINOSL -+#include /* use current 2.4.x calling conventions */ -+#include /* for vsn/printf's */ -+#include /* for mem*, str* */ -+ -+#define OSL_SYSUPTIME() ((uint32)jiffies * (1000 / HZ)) -+#define printf(fmt, args...) printk(fmt , ## args) -+#include /* for vsn/printf's */ -+#include /* for mem*, str* */ -+/* bcopy's: Linux kernel doesn't provide these (anymore) */ -+#define bcopy(src, dst, len) memcpy((dst), (src), (len)) -+#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) -+#define bzero(b, len) memset((b), '\0', (len)) -+ -+/* register access macros */ -+#if defined(OSLREGOPS) -+#define R_REG(osh, r) (\ -+ sizeof(*(r)) == sizeof(uint8) ? osl_readb((osh), (volatile uint8*)(r)) : \ -+ sizeof(*(r)) == sizeof(uint16) ? osl_readw((osh), (volatile uint16*)(r)) : \ -+ osl_readl((osh), (volatile uint32*)(r)) \ -+) -+#define W_REG(osh, r, v) do { \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): osl_writeb((osh), (volatile uint8*)(r), (uint8)(v)); break; \ -+ case sizeof(uint16): osl_writew((osh), (volatile uint16*)(r), (uint16)(v)); break; \ -+ case sizeof(uint32): osl_writel((osh), (volatile uint32*)(r), (uint32)(v)); break; \ -+ } \ -+} while (0) -+ -+extern uint8 osl_readb(osl_t *osh, volatile uint8 *r); -+extern uint16 osl_readw(osl_t *osh, volatile uint16 *r); -+extern uint32 osl_readl(osl_t *osh, volatile uint32 *r); -+extern void osl_writeb(osl_t *osh, volatile uint8 *r, uint8 v); -+extern void osl_writew(osl_t *osh, volatile uint16 *r, uint16 v); -+extern void osl_writel(osl_t *osh, volatile uint32 *r, uint32 v); -+#else /* OSLREGOPS */ -+ -+#ifndef IL_BIGENDIAN -+#ifndef __mips__ -+#define R_REG(osh, r) (\ -+ SELECT_BUS_READ(osh, \ -+ ({ \ -+ __typeof(*(r)) __osl_v; \ -+ BCM_REFERENCE(osh); \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): __osl_v = \ -+ readb((volatile uint8*)(r)); break; \ -+ case sizeof(uint16): __osl_v = \ -+ readw((volatile uint16*)(r)); break; \ -+ case sizeof(uint32): __osl_v = \ -+ readl((volatile uint32*)(r)); break; \ -+ } \ -+ __osl_v; \ -+ }), \ -+ OSL_READ_REG(osh, r)) \ -+) -+#else /* __mips__ */ -+#define R_REG(osh, r) (\ -+ SELECT_BUS_READ(osh, \ -+ ({ \ -+ __typeof(*(r)) __osl_v; \ -+ BCM_REFERENCE(osh); \ -+ __asm__ __volatile__("sync"); \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): __osl_v = \ -+ readb((volatile uint8*)(r)); break; \ -+ case sizeof(uint16): __osl_v = \ -+ readw((volatile uint16*)(r)); break; \ -+ case sizeof(uint32): __osl_v = \ -+ readl((volatile uint32*)(r)); break; \ -+ } \ -+ __asm__ __volatile__("sync"); \ -+ __osl_v; \ -+ }), \ -+ ({ \ -+ __typeof(*(r)) __osl_v; \ -+ __asm__ __volatile__("sync"); \ -+ __osl_v = OSL_READ_REG(osh, r); \ -+ __asm__ __volatile__("sync"); \ -+ __osl_v; \ -+ })) \ -+) -+#endif /* __mips__ */ -+ -+#define W_REG(osh, r, v) do { \ -+ BCM_REFERENCE(osh); \ -+ SELECT_BUS_WRITE(osh, \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ -+ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ -+ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ -+ }, \ -+ (OSL_WRITE_REG(osh, r, v))); \ -+ } while (0) -+#else /* IL_BIGENDIAN */ -+#define R_REG(osh, r) (\ -+ SELECT_BUS_READ(osh, \ -+ ({ \ -+ __typeof(*(r)) __osl_v; \ -+ BCM_REFERENCE(osh); \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): __osl_v = \ -+ readb((volatile uint8*)((uintptr)(r)^3)); break; \ -+ case sizeof(uint16): __osl_v = \ -+ readw((volatile uint16*)((uintptr)(r)^2)); break; \ -+ case sizeof(uint32): __osl_v = \ -+ readl((volatile uint32*)(r)); break; \ -+ } \ -+ __osl_v; \ -+ }), \ -+ OSL_READ_REG(osh, r)) \ -+) -+#define W_REG(osh, r, v) do { \ -+ BCM_REFERENCE(osh); \ -+ SELECT_BUS_WRITE(osh, \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): writeb((uint8)(v), \ -+ (volatile uint8*)((uintptr)(r)^3)); break; \ -+ case sizeof(uint16): writew((uint16)(v), \ -+ (volatile uint16*)((uintptr)(r)^2)); break; \ -+ case sizeof(uint32): writel((uint32)(v), \ -+ (volatile uint32*)(r)); break; \ -+ }, \ -+ (OSL_WRITE_REG(osh, r, v))); \ -+ } while (0) -+#endif /* IL_BIGENDIAN */ -+#endif /* OSLREGOPS */ -+ -+#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) -+#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) -+ -+/* bcopy, bcmp, and bzero functions */ -+#define bcopy(src, dst, len) memcpy((dst), (src), (len)) -+#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) -+#define bzero(b, len) memset((b), '\0', (len)) -+ -+/* uncached/cached virtual address */ -+#ifdef __mips__ -+#include -+#define OSL_UNCACHED(va) ((void *)KSEG1ADDR((va))) -+#define OSL_CACHED(va) ((void *)KSEG0ADDR((va))) -+#else -+#define OSL_UNCACHED(va) ((void *)va) -+#define OSL_CACHED(va) ((void *)va) -+ -+/* ARM NorthStar */ -+#define OSL_CACHE_FLUSH(va, len) -+ -+#endif /* mips */ -+ -+#ifdef __mips__ -+#define OSL_PREF_RANGE_LD(va, sz) prefetch_range_PREF_LOAD_RETAINED(va, sz) -+#define OSL_PREF_RANGE_ST(va, sz) prefetch_range_PREF_STORE_RETAINED(va, sz) -+#else /* __mips__ */ -+#define OSL_PREF_RANGE_LD(va, sz) -+#define OSL_PREF_RANGE_ST(va, sz) -+#endif /* __mips__ */ -+ -+/* get processor cycle count */ -+#if defined(mips) -+#define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2) -+#elif defined(__i386__) -+#define OSL_GETCYCLES(x) rdtscl((x)) -+#else -+#define OSL_GETCYCLES(x) ((x) = 0) -+#endif /* defined(mips) */ -+ -+/* dereference an address that may cause a bus exception */ -+#ifdef mips -+#if defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17)) -+#define BUSPROBE(val, addr) panic("get_dbe() will not fixup a bus exception when compiled into"\ -+ " a module") -+#else -+#define BUSPROBE(val, addr) get_dbe((val), (addr)) -+#include -+#endif /* defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17)) */ -+#else -+#define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; }) -+#endif /* mips */ -+ -+/* map/unmap physical to virtual I/O */ -+#if !defined(CONFIG_MMC_MSM7X00A) -+#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) -+#else -+#define REG_MAP(pa, size) (void *)(0) -+#endif /* !defined(CONFIG_MMC_MSM7X00A */ -+#define REG_UNMAP(va) iounmap((va)) -+ -+/* shared (dma-able) memory access macros */ -+#define R_SM(r) *(r) -+#define W_SM(r, v) (*(r) = (v)) -+#define BZERO_SM(r, len) memset((r), '\0', (len)) -+ -+/* Because the non BINOSL implemenation of the PKT OSL routines are macros (for -+ * performance reasons), we need the Linux headers. -+ */ -+#include /* use current 2.4.x calling conventions */ -+ -+/* packet primitives */ -+#define PKTGET(osh, len, send) osl_pktget((osh), (len)) -+#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) -+#define PKTLIST_DUMP(osh, buf) -+#define PKTDBG_TRACE(osh, pkt, bit) -+#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) -+#ifdef DHD_USE_STATIC_BUF -+#define PKTGET_STATIC(osh, len, send) osl_pktget_static((osh), (len)) -+#define PKTFREE_STATIC(osh, skb, send) osl_pktfree_static((osh), (skb), (send)) -+#endif /* DHD_USE_STATIC_BUF */ -+#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data) -+#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len) -+#define PKTHEADROOM(osh, skb) (PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head)) -+#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) -+#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next) -+#define PKTSETNEXT(osh, skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) -+#define PKTSETLEN(osh, skb, len) __pskb_trim((struct sk_buff*)(skb), (len)) -+#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) -+#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) -+#define PKTTAG(skb) ((void*)(((struct sk_buff*)(skb))->cb)) -+#define PKTSETPOOL(osh, skb, x, y) do {} while (0) -+#define PKTPOOL(osh, skb) FALSE -+#define PKTSHRINK(osh, m) (m) -+ -+#define FASTBUF (1 << 16) -+#define CTFBUF (1 << 17) -+#define PKTSETFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) |= FASTBUF) -+#define PKTCLRFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) &= (~FASTBUF)) -+#define PKTSETCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) |= CTFBUF) -+#define PKTCLRCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) &= (~CTFBUF)) -+#define PKTISFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) & FASTBUF) -+#define PKTISCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) & CTFBUF) -+#define PKTFAST(osh, skb) (((struct sk_buff*)(skb))->mac_len) -+ -+#define PKTSETSKIPCT(osh, skb) -+#define PKTCLRSKIPCT(osh, skb) -+#define PKTSKIPCT(osh, skb) -+#define PKTCLRCHAINED(osh, skb) -+#define PKTSETCHAINED(osh, skb) -+#define CTF_MARK(m) 0 -+ -+#ifdef BCMFA -+#ifdef BCMFA_HW_HASH -+#define PKTSETFAHIDX(skb, idx) (((struct sk_buff*)(skb))->napt_idx = idx) -+#else -+#define PKTSETFAHIDX(skb, idx) -+#endif /* BCMFA_SW_HASH */ -+#define PKTGETFAHIDX(skb) (((struct sk_buff*)(skb))->napt_idx) -+#define PKTSETFADEV(skb, imp) (((struct sk_buff*)(skb))->dev = imp) -+#define PKTSETRXDEV(skb) (((struct sk_buff*)(skb))->rxdev = ((struct sk_buff*)(skb))->dev) -+ -+#define AUX_TCP_FIN_RST (1 << 0) -+#define AUX_FREED (1 << 1) -+#define PKTSETFAAUX(skb) (((struct sk_buff*)(skb))->napt_flags |= AUX_TCP_FIN_RST) -+#define PKTCLRFAAUX(skb) (((struct sk_buff*)(skb))->napt_flags &= (~AUX_TCP_FIN_RST)) -+#define PKTISFAAUX(skb) (((struct sk_buff*)(skb))->napt_flags & AUX_TCP_FIN_RST) -+#define PKTSETFAFREED(skb) (((struct sk_buff*)(skb))->napt_flags |= AUX_FREED) -+#define PKTCLRFAFREED(skb) (((struct sk_buff*)(skb))->napt_flags &= (~AUX_FREED)) -+#define PKTISFAFREED(skb) (((struct sk_buff*)(skb))->napt_flags & AUX_FREED) -+#define PKTISFABRIDGED(skb) PKTISFAAUX(skb) -+#else -+#define PKTISFAAUX(skb) (FALSE) -+#define PKTISFABRIDGED(skb) (FALSE) -+#define PKTISFAFREED(skb) (FALSE) -+ -+#define PKTCLRFAAUX(skb) -+#define PKTSETFAFREED(skb) -+#define PKTCLRFAFREED(skb) -+#endif /* BCMFA */ -+ -+extern void osl_pktfree(osl_t *osh, void *skb, bool send); -+extern void *osl_pktget_static(osl_t *osh, uint len); -+extern void osl_pktfree_static(osl_t *osh, void *skb, bool send); -+ -+extern void *osl_pkt_frmnative(osl_t *osh, void *skb); -+extern void *osl_pktget(osl_t *osh, uint len); -+extern void *osl_pktdup(osl_t *osh, void *skb); -+extern struct sk_buff *osl_pkt_tonative(osl_t *osh, void *pkt); -+#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_t *)osh), (struct sk_buff*)(skb)) -+#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osl_t *)(osh), (pkt)) -+ -+#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) -+#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) -+#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority) -+#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x)) -+#define PKTSUMNEEDED(skb) (((struct sk_buff*)(skb))->ip_summed == CHECKSUM_HW) -+#define PKTSETSUMGOOD(skb, x) (((struct sk_buff*)(skb))->ip_summed = \ -+ ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE)) -+/* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because skb->ip_summed is overloaded */ -+#define PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned) -+ -+#ifdef CONFIG_NF_CONNTRACK_MARK -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -+#define PKTMARK(p) (((struct sk_buff *)(p))->mark) -+#define PKTSETMARK(p, m) ((struct sk_buff *)(p))->mark = (m) -+#else /* !2.6.0 */ -+#define PKTMARK(p) (((struct sk_buff *)(p))->nfmark) -+#define PKTSETMARK(p, m) ((struct sk_buff *)(p))->nfmark = (m) -+#endif /* 2.6.0 */ -+#else /* CONFIG_NF_CONNTRACK_MARK */ -+#define PKTMARK(p) 0 -+#define PKTSETMARK(p, m) -+#endif /* CONFIG_NF_CONNTRACK_MARK */ -+ -+#else /* BINOSL */ -+ -+/* Where to get the declarations for mem, str, printf, bcopy's? Two basic approaches. -+ * -+ * First, use the Linux header files and the C standard library replacmenent versions -+ * built-in to the kernel. Use this approach when compiling non hybrid code or compling -+ * the OS port files. The second approach is to use our own defines/prototypes and -+ * functions we have provided in the Linux OSL, i.e. linux_osl.c. Use this approach when -+ * compiling the files that make up the hybrid binary. We are ensuring we -+ * don't directly link to the kernel replacement routines from the hybrid binary. -+ * -+ * NOTE: The issue we are trying to avoid is any questioning of whether the -+ * hybrid binary is derived from Linux. The wireless common code (wlc) is designed -+ * to be OS independent through the use of the OSL API and thus the hybrid binary doesn't -+ * derive from the Linux kernel at all. But since we defined our OSL API to include -+ * a small collection of standard C library routines and these routines are provided in -+ * the kernel we want to avoid even the appearance of deriving at all even though clearly -+ * usage of a C standard library API doesn't represent a derivation from Linux. Lastly -+ * note at the time of this checkin 4 references to memcpy/memset could not be eliminated -+ * from the binary because they are created internally by GCC as part of things like -+ * structure assignment. I don't think the compiler should be doing this but there is -+ * no options to disable it on Intel architectures (there is for MIPS so somebody must -+ * agree with me). I may be able to even remove these references eventually with -+ * a GNU binutil such as objcopy via a symbol rename (i.e. memcpy to osl_memcpy). -+ */ -+#if !defined(LINUX_HYBRID) || defined(LINUX_PORT) -+ #define printf(fmt, args...) printk(fmt , ## args) -+ #include /* for vsn/printf's */ -+ #include /* for mem*, str* */ -+ /* bcopy's: Linux kernel doesn't provide these (anymore) */ -+ #define bcopy(src, dst, len) memcpy((dst), (src), (len)) -+ #define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) -+ #define bzero(b, len) memset((b), '\0', (len)) -+ -+ /* These are provided only because when compiling linux_osl.c there -+ * must be an explicit prototype (separate from the definition) because -+ * we are compiling with GCC option -Wstrict-prototypes. Conversely -+ * these could be placed directly in linux_osl.c. -+ */ -+ extern int osl_printf(const char *format, ...); -+ extern int osl_sprintf(char *buf, const char *format, ...); -+ extern int osl_snprintf(char *buf, size_t n, const char *format, ...); -+ extern int osl_vsprintf(char *buf, const char *format, va_list ap); -+ extern int osl_vsnprintf(char *buf, size_t n, const char *format, va_list ap); -+ extern int osl_strcmp(const char *s1, const char *s2); -+ extern int osl_strncmp(const char *s1, const char *s2, uint n); -+ extern int osl_strlen(const char *s); -+ extern char* osl_strcpy(char *d, const char *s); -+ extern char* osl_strncpy(char *d, const char *s, uint n); -+ extern char* osl_strchr(const char *s, int c); -+ extern char* osl_strrchr(const char *s, int c); -+ extern void *osl_memset(void *d, int c, size_t n); -+ extern void *osl_memcpy(void *d, const void *s, size_t n); -+ extern void *osl_memmove(void *d, const void *s, size_t n); -+ extern int osl_memcmp(const void *s1, const void *s2, size_t n); -+#else -+ -+ /* In the below defines we undefine the macro first in case it is -+ * defined. This shouldn't happen because we are not using Linux -+ * header files but because our Linux 2.4 make includes modversions.h -+ * through a GCC -include compile option, they get defined to point -+ * at the appropriate versioned symbol name. Note this doesn't -+ * happen with our Linux 2.6 makes. -+ */ -+ -+ /* *printf functions */ -+ #include /* va_list needed for v*printf */ -+ #include /* size_t needed for *nprintf */ -+ #undef printf -+ #undef sprintf -+ #undef snprintf -+ #undef vsprintf -+ #undef vsnprintf -+ #define printf(fmt, args...) osl_printf((fmt) , ## args) -+ #define sprintf(buf, fmt, args...) osl_sprintf((buf), (fmt) , ## args) -+ #define snprintf(buf, n, fmt, args...) osl_snprintf((buf), (n), (fmt) , ## args) -+ #define vsprintf(buf, fmt, ap) osl_vsprintf((buf), (fmt), (ap)) -+ #define vsnprintf(buf, n, fmt, ap) osl_vsnprintf((buf), (n), (fmt), (ap)) -+ extern int osl_printf(const char *format, ...); -+ extern int osl_sprintf(char *buf, const char *format, ...); -+ extern int osl_snprintf(char *buf, size_t n, const char *format, ...); -+ extern int osl_vsprintf(char *buf, const char *format, va_list ap); -+ extern int osl_vsnprintf(char *buf, size_t n, const char *format, va_list ap); -+ -+ /* str* functions */ -+ #undef strcmp -+ #undef strncmp -+ #undef strlen -+ #undef strcpy -+ #undef strncpy -+ #undef strchr -+ #undef strrchr -+ #define strcmp(s1, s2) osl_strcmp((s1), (s2)) -+ #define strncmp(s1, s2, n) osl_strncmp((s1), (s2), (n)) -+ #define strlen(s) osl_strlen((s)) -+ #define strcpy(d, s) osl_strcpy((d), (s)) -+ #define strncpy(d, s, n) osl_strncpy((d), (s), (n)) -+ #define strchr(s, c) osl_strchr((s), (c)) -+ #define strrchr(s, c) osl_strrchr((s), (c)) -+ extern int osl_strcmp(const char *s1, const char *s2); -+ extern int osl_strncmp(const char *s1, const char *s2, uint n); -+ extern int osl_strlen(const char *s); -+ extern char* osl_strcpy(char *d, const char *s); -+ extern char* osl_strncpy(char *d, const char *s, uint n); -+ extern char* osl_strchr(const char *s, int c); -+ extern char* osl_strrchr(const char *s, int c); -+ -+ /* mem* functions */ -+ #undef memset -+ #undef memcpy -+ #undef memcmp -+ #define memset(d, c, n) osl_memset((d), (c), (n)) -+ #define memcpy(d, s, n) osl_memcpy((d), (s), (n)) -+ #define memmove(d, s, n) osl_memmove((d), (s), (n)) -+ #define memcmp(s1, s2, n) osl_memcmp((s1), (s2), (n)) -+ extern void *osl_memset(void *d, int c, size_t n); -+ extern void *osl_memcpy(void *d, const void *s, size_t n); -+ extern void *osl_memmove(void *d, const void *s, size_t n); -+ extern int osl_memcmp(const void *s1, const void *s2, size_t n); -+ -+ /* bcopy, bcmp, and bzero functions */ -+ #undef bcopy -+ #undef bcmp -+ #undef bzero -+ #define bcopy(src, dst, len) osl_memcpy((dst), (src), (len)) -+ #define bcmp(b1, b2, len) osl_memcmp((b1), (b2), (len)) -+ #define bzero(b, len) osl_memset((b), '\0', (len)) -+#endif /* !defined(LINUX_HYBRID) || defined(LINUX_PORT) */ -+ -+/* register access macros */ -+#define R_REG(osh, r) (\ -+ sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \ -+ sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \ -+ osl_readl((volatile uint32*)(r)) \ -+) -+#define W_REG(osh, r, v) do { \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \ -+ case sizeof(uint16): osl_writew((uint16)(v), (volatile uint16*)(r)); break; \ -+ case sizeof(uint32): osl_writel((uint32)(v), (volatile uint32*)(r)); break; \ -+ } \ -+} while (0) -+ -+#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) -+#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) -+extern uint8 osl_readb(volatile uint8 *r); -+extern uint16 osl_readw(volatile uint16 *r); -+extern uint32 osl_readl(volatile uint32 *r); -+extern void osl_writeb(uint8 v, volatile uint8 *r); -+extern void osl_writew(uint16 v, volatile uint16 *r); -+extern void osl_writel(uint32 v, volatile uint32 *r); -+ -+/* system up time in ms */ -+#define OSL_SYSUPTIME() osl_sysuptime() -+extern uint32 osl_sysuptime(void); -+ -+/* uncached/cached virtual address */ -+#define OSL_UNCACHED(va) osl_uncached((va)) -+extern void *osl_uncached(void *va); -+#define OSL_CACHED(va) osl_cached((va)) -+extern void *osl_cached(void *va); -+ -+#define OSL_PREF_RANGE_LD(va, sz) -+#define OSL_PREF_RANGE_ST(va, sz) -+ -+/* get processor cycle count */ -+#define OSL_GETCYCLES(x) ((x) = osl_getcycles()) -+extern uint osl_getcycles(void); -+ -+/* dereference an address that may target abort */ -+#define BUSPROBE(val, addr) osl_busprobe(&(val), (addr)) -+extern int osl_busprobe(uint32 *val, uint32 addr); -+ -+/* map/unmap physical to virtual */ -+#define REG_MAP(pa, size) osl_reg_map((pa), (size)) -+#define REG_UNMAP(va) osl_reg_unmap((va)) -+extern void *osl_reg_map(uint32 pa, uint size); -+extern void osl_reg_unmap(void *va); -+ -+/* shared (dma-able) memory access macros */ -+#define R_SM(r) *(r) -+#define W_SM(r, v) (*(r) = (v)) -+#define BZERO_SM(r, len) bzero((r), (len)) -+ -+/* packet primitives */ -+#define PKTGET(osh, len, send) osl_pktget((osh), (len)) -+#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) -+#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative((osh), (skb)) -+#define PKTLIST_DUMP(osh, buf) -+#define PKTDBG_TRACE(osh, pkt, bit) -+#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) -+#define PKTDATA(osh, skb) osl_pktdata((osh), (skb)) -+#define PKTLEN(osh, skb) osl_pktlen((osh), (skb)) -+#define PKTHEADROOM(osh, skb) osl_pktheadroom((osh), (skb)) -+#define PKTTAILROOM(osh, skb) osl_pkttailroom((osh), (skb)) -+#define PKTNEXT(osh, skb) osl_pktnext((osh), (skb)) -+#define PKTSETNEXT(osh, skb, x) osl_pktsetnext((skb), (x)) -+#define PKTSETLEN(osh, skb, len) osl_pktsetlen((osh), (skb), (len)) -+#define PKTPUSH(osh, skb, bytes) osl_pktpush((osh), (skb), (bytes)) -+#define PKTPULL(osh, skb, bytes) osl_pktpull((osh), (skb), (bytes)) -+#define PKTTAG(skb) osl_pkttag((skb)) -+#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osh), (pkt)) -+#define PKTLINK(skb) osl_pktlink((skb)) -+#define PKTSETLINK(skb, x) osl_pktsetlink((skb), (x)) -+#define PKTPRIO(skb) osl_pktprio((skb)) -+#define PKTSETPRIO(skb, x) osl_pktsetprio((skb), (x)) -+#define PKTSHARED(skb) osl_pktshared((skb)) -+#define PKTSETPOOL(osh, skb, x, y) do {} while (0) -+#define PKTPOOL(osh, skb) FALSE -+ -+extern void *osl_pktget(osl_t *osh, uint len); -+extern void *osl_pktdup(osl_t *osh, void *skb); -+extern void *osl_pkt_frmnative(osl_t *osh, void *skb); -+extern void osl_pktfree(osl_t *osh, void *skb, bool send); -+extern uchar *osl_pktdata(osl_t *osh, void *skb); -+extern uint osl_pktlen(osl_t *osh, void *skb); -+extern uint osl_pktheadroom(osl_t *osh, void *skb); -+extern uint osl_pkttailroom(osl_t *osh, void *skb); -+extern void *osl_pktnext(osl_t *osh, void *skb); -+extern void osl_pktsetnext(void *skb, void *x); -+extern void osl_pktsetlen(osl_t *osh, void *skb, uint len); -+extern uchar *osl_pktpush(osl_t *osh, void *skb, int bytes); -+extern uchar *osl_pktpull(osl_t *osh, void *skb, int bytes); -+extern void *osl_pkttag(void *skb); -+extern void *osl_pktlink(void *skb); -+extern void osl_pktsetlink(void *skb, void *x); -+extern uint osl_pktprio(void *skb); -+extern void osl_pktsetprio(void *skb, uint x); -+extern struct sk_buff *osl_pkt_tonative(osl_t *osh, void *pkt); -+extern bool osl_pktshared(void *skb); -+ -+ -+#endif /* BINOSL */ -+ -+#define PKTALLOCED(osh) osl_pktalloced(osh) -+extern uint osl_pktalloced(osl_t *osh); -+ -+#define DMA_MAP(osh, va, size, direction, p, dmah) \ -+ osl_dma_map((osh), (va), (size), (direction), (p), (dmah)) -+ -+#else /* ! BCMDRIVER */ -+ -+ -+/* ASSERT */ -+ #define ASSERT(exp) do {} while (0) -+ -+/* MALLOC and MFREE */ -+#define MALLOC(o, l) malloc(l) -+#define MFREE(o, p, l) free(p) -+#include -+ -+/* str* and mem* functions */ -+#include -+ -+/* *printf functions */ -+#include -+ -+/* bcopy, bcmp, and bzero */ -+extern void bcopy(const void *src, void *dst, size_t len); -+extern int bcmp(const void *b1, const void *b2, size_t len); -+extern void bzero(void *b, size_t len); -+#endif /* ! BCMDRIVER */ -+ -+#endif /* _linux_osl_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/linuxver.h b/drivers/net/ethernet/broadcom/gmac/src/include/linuxver.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/linuxver.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/linuxver.h 2017-11-09 17:53:43.969290000 +0800 -@@ -0,0 +1,662 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Linux-specific abstractions to gain some independence from linux kernel versions. -+ * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences. -+ * -+ * $Id: linuxver.h 312774 2012-02-03 22:20:14Z $ -+ */ -+ -+#ifndef _linuxver_h_ -+#define _linuxver_h_ -+ -+#include -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -+#include -+#else -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) -+#include -+#else -+#include -+#endif -+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) */ -+#include -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)) -+/* __NO_VERSION__ must be defined for all linkables except one in 2.2 */ -+#ifdef __UNDEF_NO_VERSION__ -+#undef __NO_VERSION__ -+#else -+#define __NO_VERSION__ -+#endif -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0) */ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) -+#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i") -+#define module_param_string(_name_, _string_, _size_, _perm_) \ -+ MODULE_PARM(_string_, "c" __MODULE_STRING(_size_)) -+#endif -+ -+/* linux/malloc.h is deprecated, use linux/slab.h instead. */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 9)) -+#include -+#else -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) -+#include -+#else -+#include -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) -+#undef IP_TOS -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) */ -+#include -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41)) -+#include -+#else -+#include -+#ifndef work_struct -+#define work_struct tq_struct -+#endif -+#ifndef INIT_WORK -+#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data)) -+#endif -+#ifndef schedule_work -+#define schedule_work(_work) schedule_task((_work)) -+#endif -+#ifndef flush_scheduled_work -+#define flush_scheduled_work() flush_scheduled_tasks() -+#endif -+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41) */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) -+#define MY_INIT_WORK(_work, _func) INIT_WORK(_work, _func) -+#else -+#define MY_INIT_WORK(_work, _func) INIT_WORK(_work, _func, _work) -+typedef void (*work_func_t)(void *work); -+#endif /* >= 2.6.20 */ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -+/* Some distributions have their own 2.6.x compatibility layers */ -+#ifndef IRQ_NONE -+typedef void irqreturn_t; -+#define IRQ_NONE -+#define IRQ_HANDLED -+#define IRQ_RETVAL(x) -+#endif -+#else -+typedef irqreturn_t(*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs); -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) */ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) -+#define IRQF_SHARED SA_SHIRQ -+#endif /* < 2.6.18 */ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17) -+#ifdef CONFIG_NET_RADIO -+#define CONFIG_WIRELESS_EXT -+#endif -+#endif /* < 2.6.17 */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 67) -+#define MOD_INC_USE_COUNT -+#define MOD_DEC_USE_COUNT -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 67) */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) -+#include -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) -+#include -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) -+#include -+#else -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) -+#include -+#endif -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) */ -+ -+#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) -+#include -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) */ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) -+#include -+#include -+#endif -+#include -+#include -+#include -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 69)) -+/* In 2.5 (as of 2.5.69 at least) there is a cs_error exported which -+ * does this, but it's not in 2.4 so we do our own for now. -+ */ -+static inline void -+cs_error(client_handle_t handle, int func, int ret) -+{ -+ error_info_t err = { func, ret }; -+ CardServices(ReportError, handle, &err); -+} -+#endif -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 16)) -+ -+typedef struct pcmcia_device dev_link_t; -+ -+#endif -+ -+#endif /* CONFIG_PCMCIA */ -+ -+#ifndef __exit -+#define __exit -+#endif -+#ifndef __devexit -+#define __devexit -+#endif -+#ifndef __devinit -+#define __devinit __init -+#endif -+#ifndef __devinitdata -+#define __devinitdata -+#endif -+#ifndef __devexit_p -+#define __devexit_p(x) x -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)) -+ -+#define pci_get_drvdata(dev) (dev)->sysdata -+#define pci_set_drvdata(dev, value) (dev)->sysdata = (value) -+ -+/* -+ * New-style (2.4.x) PCI/hot-pluggable PCI/CardBus registration -+ */ -+ -+struct pci_device_id { -+ unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */ -+ unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */ -+ unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */ -+ unsigned long driver_data; /* Data private to the driver */ -+}; -+ -+struct pci_driver { -+ struct list_head node; -+ char *name; -+ const struct pci_device_id *id_table; /* NULL if wants all devices */ -+ int (*probe)(struct pci_dev *dev, -+ const struct pci_device_id *id); /* New device inserted */ -+ void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug -+ * capable driver) -+ */ -+ void (*suspend)(struct pci_dev *dev); /* Device suspended */ -+ void (*resume)(struct pci_dev *dev); /* Device woken up */ -+}; -+ -+#define MODULE_DEVICE_TABLE(type, name) -+#define PCI_ANY_ID (~0) -+ -+/* compatpci.c */ -+#define pci_module_init pci_register_driver -+extern int pci_register_driver(struct pci_driver *drv); -+extern void pci_unregister_driver(struct pci_driver *drv); -+ -+#endif /* PCI registration */ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)) -+#define pci_module_init pci_register_driver -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)) -+#ifdef MODULE -+#define module_init(x) int init_module(void) { return x(); } -+#define module_exit(x) void cleanup_module(void) { x(); } -+#else -+#define module_init(x) __initcall(x); -+#define module_exit(x) __exitcall(x); -+#endif -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) -+#define WL_USE_NETDEV_OPS -+#else -+#undef WL_USE_NETDEV_OPS -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) && defined(CONFIG_RFKILL) -+#define WL_CONFIG_RFKILL -+#else -+#undef WL_CONFIG_RFKILL -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 48)) -+#define list_for_each(pos, head) \ -+ for (pos = (head)->next; pos != (head); pos = pos->next) -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 13)) -+#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)]) -+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 44)) -+#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 23)) -+#define pci_enable_device(dev) do { } while (0) -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 14)) -+#define net_device device -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 42)) -+ -+/* -+ * DMA mapping -+ * -+ * See linux/Documentation/DMA-mapping.txt -+ */ -+ -+#ifndef PCI_DMA_TODEVICE -+#define PCI_DMA_TODEVICE 1 -+#define PCI_DMA_FROMDEVICE 2 -+#endif -+ -+typedef u32 dma_addr_t; -+ -+/* Pure 2^n version of get_order */ -+static inline int get_order(unsigned long size) -+{ -+ int order; -+ -+ size = (size-1) >> (PAGE_SHIFT-1); -+ order = -1; -+ do { -+ size >>= 1; -+ order++; -+ } while (size); -+ return order; -+} -+ -+static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, -+ dma_addr_t *dma_handle) -+{ -+ void *ret; -+ int gfp = GFP_ATOMIC | GFP_DMA; -+ -+ ret = (void *)__get_free_pages(gfp, get_order(size)); -+ -+ if (ret != NULL) { -+ memset(ret, 0, size); -+ *dma_handle = virt_to_bus(ret); -+ } -+ return ret; -+} -+static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size, -+ void *vaddr, dma_addr_t dma_handle) -+{ -+ free_pages((unsigned long)vaddr, get_order(size)); -+} -+#ifdef ILSIM -+extern uint pci_map_single(void *dev, void *va, uint size, int direction); -+extern void pci_unmap_single(void *dev, uint pa, uint size, int direction); -+#else -+#define pci_map_single(cookie, address, size, dir) virt_to_bus(address) -+#define pci_unmap_single(cookie, address, size, dir) -+#endif -+ -+#endif /* DMA mapping */ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43)) -+ -+#define dev_kfree_skb_any(a) dev_kfree_skb(a) -+#define netif_down(dev) do { (dev)->start = 0; } while (0) -+ -+/* pcmcia-cs provides its own netdevice compatibility layer */ -+#ifndef _COMPAT_NETDEVICE_H -+ -+/* -+ * SoftNet -+ * -+ * For pre-softnet kernels we need to tell the upper layer not to -+ * re-enter start_xmit() while we are in there. However softnet -+ * guarantees not to enter while we are in there so there is no need -+ * to do the netif_stop_queue() dance unless the transmit queue really -+ * gets stuck. This should also improve performance according to tests -+ * done by Aman Singla. -+ */ -+ -+#define dev_kfree_skb_irq(a) dev_kfree_skb(a) -+#define netif_wake_queue(dev) \ -+ do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while (0) -+#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy) -+ -+static inline void netif_start_queue(struct net_device *dev) -+{ -+ dev->tbusy = 0; -+ dev->interrupt = 0; -+ dev->start = 1; -+} -+ -+#define netif_queue_stopped(dev) (dev)->tbusy -+#define netif_running(dev) (dev)->start -+ -+#endif /* _COMPAT_NETDEVICE_H */ -+ -+#define netif_device_attach(dev) netif_start_queue(dev) -+#define netif_device_detach(dev) netif_stop_queue(dev) -+ -+/* 2.4.x renamed bottom halves to tasklets */ -+#define tasklet_struct tq_struct -+static inline void tasklet_schedule(struct tasklet_struct *tasklet) -+{ -+ queue_task(tasklet, &tq_immediate); -+ mark_bh(IMMEDIATE_BH); -+} -+ -+static inline void tasklet_init(struct tasklet_struct *tasklet, -+ void (*func)(unsigned long), -+ unsigned long data) -+{ -+ tasklet->next = NULL; -+ tasklet->sync = 0; -+ tasklet->routine = (void (*)(void *))func; -+ tasklet->data = (void *)data; -+} -+#define tasklet_kill(tasklet) { do {} while (0); } -+ -+/* 2.4.x introduced del_timer_sync() */ -+#define del_timer_sync(timer) del_timer(timer) -+ -+#else -+ -+#define netif_down(dev) -+ -+#endif /* SoftNet */ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3)) -+ -+/* -+ * Emit code to initialise a tq_struct's routine and data pointers -+ */ -+#define PREPARE_TQUEUE(_tq, _routine, _data) \ -+ do { \ -+ (_tq)->routine = _routine; \ -+ (_tq)->data = _data; \ -+ } while (0) -+ -+/* -+ * Emit code to initialise all of a tq_struct -+ */ -+#define INIT_TQUEUE(_tq, _routine, _data) \ -+ do { \ -+ INIT_LIST_HEAD(&(_tq)->list); \ -+ (_tq)->sync = 0; \ -+ PREPARE_TQUEUE((_tq), (_routine), (_data)); \ -+ } while (0) -+ -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3) */ -+ -+/* Power management related macro & routines */ -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 9) -+#define PCI_SAVE_STATE(a, b) pci_save_state(a) -+#define PCI_RESTORE_STATE(a, b) pci_restore_state(a) -+#else -+#define PCI_SAVE_STATE(a, b) pci_save_state(a, b) -+#define PCI_RESTORE_STATE(a, b) pci_restore_state(a, b) -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 6)) -+static inline int -+pci_save_state(struct pci_dev *dev, u32 *buffer) -+{ -+ int i; -+ if (buffer) { -+ for (i = 0; i < 16; i++) -+ pci_read_config_dword(dev, i * 4, &buffer[i]); -+ } -+ return 0; -+} -+ -+static inline int -+pci_restore_state(struct pci_dev *dev, u32 *buffer) -+{ -+ int i; -+ -+ if (buffer) { -+ for (i = 0; i < 16; i++) -+ pci_write_config_dword(dev, i * 4, buffer[i]); -+ } -+ /* -+ * otherwise, write the context information we know from bootup. -+ * This works around a problem where warm-booting from Windows -+ * combined with a D3(hot)->D0 transition causes PCI config -+ * header data to be forgotten. -+ */ -+ else { -+ for (i = 0; i < 6; i ++) -+ pci_write_config_dword(dev, -+ PCI_BASE_ADDRESS_0 + (i * 4), -+ pci_resource_start(dev, i)); -+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); -+ } -+ return 0; -+} -+#endif /* PCI power management */ -+ -+/* Old cp0 access macros deprecated in 2.4.19 */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 19)) -+#define read_c0_count() read_32bit_cp0_register(CP0_COUNT) -+#endif -+ -+/* Module refcount handled internally in 2.6.x */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)) -+#ifndef SET_MODULE_OWNER -+#define SET_MODULE_OWNER(dev) do {} while (0) -+#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT -+#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT -+#else -+#define OLD_MOD_INC_USE_COUNT do {} while (0) -+#define OLD_MOD_DEC_USE_COUNT do {} while (0) -+#endif -+#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) */ -+#ifndef SET_MODULE_OWNER -+#define SET_MODULE_OWNER(dev) do {} while (0) -+#endif -+#ifndef MOD_INC_USE_COUNT -+#define MOD_INC_USE_COUNT do {} while (0) -+#endif -+#ifndef MOD_DEC_USE_COUNT -+#define MOD_DEC_USE_COUNT do {} while (0) -+#endif -+#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT -+#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) */ -+ -+#ifndef SET_NETDEV_DEV -+#define SET_NETDEV_DEV(net, pdev) do {} while (0) -+#endif -+ -+#ifndef HAVE_FREE_NETDEV -+#define free_netdev(dev) kfree(dev) -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -+/* struct packet_type redefined in 2.6.x */ -+#define af_packet_priv data -+#endif -+ -+/* suspend args */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) -+#define DRV_SUSPEND_STATE_TYPE pm_message_t -+#else -+#define DRV_SUSPEND_STATE_TYPE uint32 -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) -+#define CHECKSUM_HW CHECKSUM_PARTIAL -+#endif -+ -+typedef struct { -+ void *parent; /* some external entity that the thread supposed to work for */ -+ struct task_struct *p_task; -+ long thr_pid; -+ int prio; /* priority */ -+ struct semaphore sema; -+ int terminated; -+ struct completion completed; -+} tsk_ctl_t; -+ -+ -+/* requires tsk_ctl_t tsk argument, the caller's priv data is passed in owner ptr */ -+/* note this macro assumes there may be only one context waiting on thread's completion */ -+#ifdef DHD_DEBUG -+#define DBG_THR(x) printk x -+#else -+#define DBG_THR(x) -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -+#define SMP_RD_BARRIER_DEPENDS(x) smp_read_barrier_depends(x) -+#else -+#define SMP_RD_BARRIER_DEPENDS(x) smp_rmb(x) -+#endif -+ -+ -+#define PROC_START(thread_func, owner, tsk_ctl, flags) \ -+{ \ -+ sema_init(&((tsk_ctl)->sema), 0); \ -+ init_completion(&((tsk_ctl)->completed)); \ -+ (tsk_ctl)->parent = owner; \ -+ (tsk_ctl)->terminated = FALSE; \ -+ (tsk_ctl)->thr_pid = kernel_thread(thread_func, tsk_ctl, flags); \ -+ if ((tsk_ctl)->thr_pid > 0) \ -+ wait_for_completion(&((tsk_ctl)->completed)); \ -+ DBG_THR(("%s thr:%lx started\n", __FUNCTION__, (tsk_ctl)->thr_pid)); \ -+} -+ -+#define PROC_STOP(tsk_ctl) \ -+{ \ -+ (tsk_ctl)->terminated = TRUE; \ -+ smp_wmb(); \ -+ up(&((tsk_ctl)->sema)); \ -+ wait_for_completion(&((tsk_ctl)->completed)); \ -+ DBG_THR(("%s thr:%lx terminated OK\n", __FUNCTION__, (tsk_ctl)->thr_pid)); \ -+ (tsk_ctl)->thr_pid = -1; \ -+} -+ -+/* ----------------------- */ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) -+#define KILL_PROC(nr, sig) \ -+{ \ -+struct task_struct *tsk; \ -+struct pid *pid; \ -+pid = find_get_pid((pid_t)nr); \ -+tsk = pid_task(pid, PIDTYPE_PID); \ -+if (tsk) send_sig(sig, tsk, 1); \ -+} -+#else -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (LINUX_VERSION_CODE <= \ -+ KERNEL_VERSION(2, 6, 30)) -+#define KILL_PROC(pid, sig) \ -+{ \ -+ struct task_struct *tsk; \ -+ tsk = find_task_by_vpid(pid); \ -+ if (tsk) send_sig(sig, tsk, 1); \ -+} -+#else -+#define KILL_PROC(pid, sig) \ -+{ \ -+ kill_proc(pid, sig, 1); \ -+} -+#endif -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) */ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) -+#include -+#include -+#else -+#include -+ -+#define __wait_event_interruptible_timeout(wq, condition, ret) \ -+do { \ -+ wait_queue_t __wait; \ -+ init_waitqueue_entry(&__wait, current); \ -+ \ -+ add_wait_queue(&wq, &__wait); \ -+ for (;;) { \ -+ set_current_state(TASK_INTERRUPTIBLE); \ -+ if (condition) \ -+ break; \ -+ if (!signal_pending(current)) { \ -+ ret = schedule_timeout(ret); \ -+ if (!ret) \ -+ break; \ -+ continue; \ -+ } \ -+ ret = -ERESTARTSYS; \ -+ break; \ -+ } \ -+ current->state = TASK_RUNNING; \ -+ remove_wait_queue(&wq, &__wait); \ -+} while (0) -+ -+#define wait_event_interruptible_timeout(wq, condition, timeout) \ -+({ \ -+ long __ret = timeout; \ -+ if (!(condition)) \ -+ __wait_event_interruptible_timeout(wq, condition, __ret); \ -+ __ret; \ -+}) -+ -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) */ -+ -+/* -+For < 2.6.24, wl creates its own netdev but doesn't -+align the priv area like the genuine alloc_netdev(). -+Since netdev_priv() always gives us the aligned address, it will -+not match our unaligned address for < 2.6.24 -+*/ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)) -+#define DEV_PRIV(dev) (dev->priv) -+#else -+#define DEV_PRIV(dev) netdev_priv(dev) -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) -+#define WL_ISR(i, d, p) wl_isr((i), (d)) -+#else -+#define WL_ISR(i, d, p) wl_isr((i), (d), (p)) -+#endif /* < 2.6.20 */ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) -+#define netdev_priv(dev) dev->priv -+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) */ -+ -+#endif /* _linuxver_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/osl.h b/drivers/net/ethernet/broadcom/gmac/src/include/osl.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/osl.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/osl.h 2017-11-09 17:53:43.969308000 +0800 -@@ -0,0 +1,143 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * OS Abstraction Layer -+ * -+ * $Id: osl.h 321101 2012-03-14 02:53:01Z $ -+ */ -+ -+#ifndef _osl_h_ -+#define _osl_h_ -+ -+/* osl handle type forward declaration */ -+typedef struct osl_info osl_t; -+typedef struct osl_dmainfo osldma_t; -+ -+#define OSL_PKTTAG_SZ 32 /* Size of PktTag */ -+ -+/* Drivers use PKTFREESETCB to register a callback function when a packet is freed by OSL */ -+typedef void (*pktfree_cb_fn_t)(void *ctx, void *pkt, unsigned int status); -+ -+/* Drivers use REGOPSSET() to register register read/write funcitons */ -+typedef unsigned int (*osl_rreg_fn_t)(void *ctx, volatile void *reg, unsigned int size); -+typedef void (*osl_wreg_fn_t)(void *ctx, volatile void *reg, unsigned int val, unsigned int size); -+ -+#ifdef __mips__ -+#define PREF_LOAD 0 -+#define PREF_STORE 1 -+#define PREF_LOAD_STREAMED 4 -+#define PREF_STORE_STREAMED 5 -+#define PREF_LOAD_RETAINED 6 -+#define PREF_STORE_RETAINED 7 -+#define PREF_WBACK_INV 25 -+#define PREF_PREPARE4STORE 30 -+ -+ -+#define MAKE_PREFETCH_FN(hint) \ -+static inline void prefetch_##hint(const void *addr) \ -+{ \ -+ __asm__ __volatile__(\ -+ " .set mips4 \n" \ -+ " pref %0, (%1) \n" \ -+ " .set mips0 \n" \ -+ : \ -+ : "i" (hint), "r" (addr)); \ -+} -+ -+#define MAKE_PREFETCH_RANGE_FN(hint) \ -+static inline void prefetch_range_##hint(const void *addr, int len) \ -+{ \ -+ int size = len; \ -+ while (size > 0) { \ -+ prefetch_##hint(addr); \ -+ size -= 32; \ -+ } \ -+} -+ -+MAKE_PREFETCH_FN(PREF_LOAD) -+MAKE_PREFETCH_RANGE_FN(PREF_LOAD) -+MAKE_PREFETCH_FN(PREF_STORE) -+MAKE_PREFETCH_RANGE_FN(PREF_STORE) -+MAKE_PREFETCH_FN(PREF_LOAD_STREAMED) -+MAKE_PREFETCH_RANGE_FN(PREF_LOAD_STREAMED) -+MAKE_PREFETCH_FN(PREF_STORE_STREAMED) -+MAKE_PREFETCH_RANGE_FN(PREF_STORE_STREAMED) -+MAKE_PREFETCH_FN(PREF_LOAD_RETAINED) -+MAKE_PREFETCH_RANGE_FN(PREF_LOAD_RETAINED) -+MAKE_PREFETCH_FN(PREF_STORE_RETAINED) -+MAKE_PREFETCH_RANGE_FN(PREF_STORE_RETAINED) -+#endif /* __mips__ */ -+ -+#if defined(linux) -+#include -+#else -+#error "Unsupported OSL requested" -+#endif -+ -+#ifndef PKTDBG_TRACE -+#define PKTDBG_TRACE(osh, pkt, bit) -+#endif -+ -+#ifndef PKTCTFMAP -+#define PKTCTFMAP(osh, p) -+#endif /* PKTCTFMAP */ -+ -+/* -------------------------------------------------------------------------- -+** Register manipulation macros. -+*/ -+ -+#define SET_REG(osh, r, mask, val) W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val))) -+ -+#ifndef AND_REG -+#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) -+#endif /* !AND_REG */ -+ -+#ifndef OR_REG -+#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) -+#endif /* !OR_REG */ -+ -+#if !defined(OSL_SYSUPTIME) -+#define OSL_SYSUPTIME() (0) -+#define OSL_SYSUPTIME_SUPPORT FALSE -+#else -+#define OSL_SYSUPTIME_SUPPORT TRUE -+#endif /* OSL_SYSUPTIME */ -+ -+#define PKTCGETATTR(s) (0) -+#define PKTCSETATTR(skb, f, p, b) -+#define PKTCCLRATTR(skb) -+#define PKTCCNT(skb) (1) -+#define PKTCLEN(skb) PKTLEN(NULL, skb) -+#define PKTCGETFLAGS(skb) (0) -+#define PKTCSETFLAGS(skb, f) -+#define PKTCCLRFLAGS(skb) -+#define PKTCFLAGS(skb) (0) -+#define PKTCSETCNT(skb, c) -+#define PKTCINCRCNT(skb) -+#define PKTCADDCNT(skb, c) -+#define PKTCSETLEN(skb, l) -+#define PKTCADDLEN(skb, l) -+#define PKTCSETFLAG(skb, fb) -+#define PKTCCLRFLAG(skb, fb) -+#define PKTCLINK(skb) NULL -+#define PKTSETCLINK(skb, x) -+#undef PKTISCHAINED -+#define PKTISCHAINED(skb) FALSE -+#define FOREACH_CHAINED_PKT(skb, nskb) \ -+ for ((nskb) = NULL; (skb) != NULL; (skb) = (nskb)) -+#define PKTCFREE PKTFREE -+ -+ -+#endif /* _osl_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/packed_section_end.h b/drivers/net/ethernet/broadcom/gmac/src/include/packed_section_end.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/packed_section_end.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/packed_section_end.h 2017-11-09 17:53:43.970305000 +0800 -@@ -0,0 +1,71 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Declare directives for structure packing. No padding will be provided -+ * between the members of packed structures, and therefore, there is no -+ * guarantee that structure members will be aligned. -+ * -+ * Declaring packed structures is compiler specific. In order to handle all -+ * cases, packed structures should be delared as: -+ * -+ * #include -+ * -+ * typedef BWL_PRE_PACKED_STRUCT struct foobar_t { -+ * some_struct_members; -+ * } BWL_POST_PACKED_STRUCT foobar_t; -+ * -+ * #include -+ * -+ * -+ * $Id: packed_section_end.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+ -+/* Error check - BWL_PACKED_SECTION is defined in packed_section_start.h -+ * and undefined in packed_section_end.h. If it is NOT defined at this -+ * point, then there is a missing include of packed_section_start.h. -+ */ -+#ifdef BWL_PACKED_SECTION -+ #undef BWL_PACKED_SECTION -+#else -+ #error "BWL_PACKED_SECTION is NOT defined!" -+#endif -+ -+ -+#if defined(_MSC_VER) -+ /* Disable compiler warning about pragma pack changing alignment. */ -+ #pragma warning(disable:4103) -+ -+ /* The Microsoft compiler uses pragmas for structure packing. Other -+ * compilers use structure attribute modifiers. Refer to -+ * BWL_PRE_PACKED_STRUCT and BWL_POST_PACKED_STRUCT defined in -+ * typedefs.h -+ */ -+ #if defined(BWL_DEFAULT_PACKING) -+ /* require default structure packing */ -+ #pragma pack(pop) -+ #undef BWL_DEFAULT_PACKING -+ #else /* BWL_PACKED_SECTION */ -+ #pragma pack() -+ #endif /* BWL_PACKED_SECTION */ -+#endif /* _MSC_VER */ -+ -+ -+/* Compiler-specific directives for structure packing are declared in -+ * packed_section_start.h. This marks the end of the structure packing section, -+ * so, undef them here. -+ */ -+#undef BWL_PRE_PACKED_STRUCT -+#undef BWL_POST_PACKED_STRUCT -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/packed_section_start.h b/drivers/net/ethernet/broadcom/gmac/src/include/packed_section_start.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/packed_section_start.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/packed_section_start.h 2017-11-09 17:53:43.971302000 +0800 -@@ -0,0 +1,76 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Declare directives for structure packing. No padding will be provided -+ * between the members of packed structures, and therefore, there is no -+ * guarantee that structure members will be aligned. -+ * -+ * Declaring packed structures is compiler specific. In order to handle all -+ * cases, packed structures should be delared as: -+ * -+ * #include -+ * -+ * typedef BWL_PRE_PACKED_STRUCT struct foobar_t { -+ * some_struct_members; -+ * } BWL_POST_PACKED_STRUCT foobar_t; -+ * -+ * #include -+ * -+ * -+ * $Id: packed_section_start.h 286783 2011-09-29 06:18:57Z $ -+ */ -+ -+ -+/* Error check - BWL_PACKED_SECTION is defined in packed_section_start.h -+ * and undefined in packed_section_end.h. If it is already defined at this -+ * point, then there is a missing include of packed_section_end.h. -+ */ -+#ifdef BWL_PACKED_SECTION -+ #error "BWL_PACKED_SECTION is already defined!" -+#else -+ #define BWL_PACKED_SECTION -+#endif -+ -+ -+#if defined(_MSC_VER) -+ /* Disable compiler warning about pragma pack changing alignment. */ -+ #pragma warning(disable:4103) -+ -+ /* The Microsoft compiler uses pragmas for structure packing. Other -+ * compilers use structure attribute modifiers. Refer to -+ * BWL_PRE_PACKED_STRUCT and BWL_POST_PACKED_STRUCT defined below. -+ */ -+ #if defined(BWL_DEFAULT_PACKING) -+ /* Default structure packing */ -+ #pragma pack(push, 8) -+ #else /* BWL_PACKED_SECTION */ -+ #pragma pack(1) -+ #endif /* BWL_PACKED_SECTION */ -+#endif /* _MSC_VER */ -+ -+ -+/* Declare compiler-specific directives for structure packing. */ -+#if defined(_MSC_VER) -+ #define BWL_PRE_PACKED_STRUCT -+ #define BWL_POST_PACKED_STRUCT -+#elif defined(__GNUC__) || defined(__lint) -+ #define BWL_PRE_PACKED_STRUCT -+ #define BWL_POST_PACKED_STRUCT __attribute__ ((packed)) -+#elif defined(__CC_ARM) -+ #define BWL_PRE_PACKED_STRUCT __packed -+ #define BWL_POST_PACKED_STRUCT -+#else -+ #error "Unknown compiler!" -+#endif -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/pcicfg.h b/drivers/net/ethernet/broadcom/gmac/src/include/pcicfg.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/pcicfg.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/pcicfg.h 2017-11-09 17:53:43.972306000 +0800 -@@ -0,0 +1,569 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * pcicfg.h: PCI configuration constants and structures. -+ * -+ * $Id: pcicfg.h 316716 2012-02-23 04:39:13Z $ -+ */ -+ -+#ifndef _h_pcicfg_ -+#define _h_pcicfg_ -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+/* The following inside ifndef's so we don't collide with NTDDK.H */ -+#ifndef PCI_MAX_BUS -+#define PCI_MAX_BUS 0x100 -+#endif -+#ifndef PCI_MAX_DEVICES -+#define PCI_MAX_DEVICES 0x20 -+#endif -+#ifndef PCI_MAX_FUNCTION -+#define PCI_MAX_FUNCTION 0x8 -+#endif -+ -+#ifndef PCI_INVALID_VENDORID -+#define PCI_INVALID_VENDORID 0xffff -+#endif -+#ifndef PCI_INVALID_DEVICEID -+#define PCI_INVALID_DEVICEID 0xffff -+#endif -+ -+ -+/* Convert between bus-slot-function-register and config addresses */ -+ -+#define PCICFG_BUS_SHIFT 16 /* Bus shift */ -+#define PCICFG_SLOT_SHIFT 11 /* Slot shift */ -+#define PCICFG_FUN_SHIFT 8 /* Function shift */ -+#define PCICFG_OFF_SHIFT 0 /* Register shift */ -+ -+#define PCICFG_BUS_MASK 0xff /* Bus mask */ -+#define PCICFG_SLOT_MASK 0x1f /* Slot mask */ -+#define PCICFG_FUN_MASK 7 /* Function mask */ -+#define PCICFG_OFF_MASK 0xff /* Bus mask */ -+ -+#define PCI_CONFIG_ADDR(b, s, f, o) \ -+ ((((b) & PCICFG_BUS_MASK) << PCICFG_BUS_SHIFT) \ -+ | (((s) & PCICFG_SLOT_MASK) << PCICFG_SLOT_SHIFT) \ -+ | (((f) & PCICFG_FUN_MASK) << PCICFG_FUN_SHIFT) \ -+ | (((o) & PCICFG_OFF_MASK) << PCICFG_OFF_SHIFT)) -+ -+#define PCI_CONFIG_BUS(a) (((a) >> PCICFG_BUS_SHIFT) & PCICFG_BUS_MASK) -+#define PCI_CONFIG_SLOT(a) (((a) >> PCICFG_SLOT_SHIFT) & PCICFG_SLOT_MASK) -+#define PCI_CONFIG_FUN(a) (((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK) -+#define PCI_CONFIG_OFF(a) (((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK) -+ -+/* PCIE Config space accessing MACROS */ -+ -+#define PCIECFG_BUS_SHIFT 24 /* Bus shift */ -+#define PCIECFG_SLOT_SHIFT 19 /* Slot/Device shift */ -+#define PCIECFG_FUN_SHIFT 16 /* Function shift */ -+#define PCIECFG_OFF_SHIFT 0 /* Register shift */ -+ -+#define PCIECFG_BUS_MASK 0xff /* Bus mask */ -+#define PCIECFG_SLOT_MASK 0x1f /* Slot/Device mask */ -+#define PCIECFG_FUN_MASK 7 /* Function mask */ -+#define PCIECFG_OFF_MASK 0xfff /* Register mask */ -+ -+#define PCIE_CONFIG_ADDR(b, s, f, o) \ -+ ((((b) & PCIECFG_BUS_MASK) << PCIECFG_BUS_SHIFT) \ -+ | (((s) & PCIECFG_SLOT_MASK) << PCIECFG_SLOT_SHIFT) \ -+ | (((f) & PCIECFG_FUN_MASK) << PCIECFG_FUN_SHIFT) \ -+ | (((o) & PCIECFG_OFF_MASK) << PCIECFG_OFF_SHIFT)) -+ -+#define PCIE_CONFIG_BUS(a) (((a) >> PCIECFG_BUS_SHIFT) & PCIECFG_BUS_MASK) -+#define PCIE_CONFIG_SLOT(a) (((a) >> PCIECFG_SLOT_SHIFT) & PCIECFG_SLOT_MASK) -+#define PCIE_CONFIG_FUN(a) (((a) >> PCIECFG_FUN_SHIFT) & PCIECFG_FUN_MASK) -+#define PCIE_CONFIG_OFF(a) (((a) >> PCIECFG_OFF_SHIFT) & PCIECFG_OFF_MASK) -+ -+/* The actual config space */ -+ -+#define PCI_BAR_MAX 6 -+ -+#define PCI_ROM_BAR 8 -+ -+#define PCR_RSVDA_MAX 2 -+ -+/* Bits in PCI bars' flags */ -+ -+#define PCIBAR_FLAGS 0xf -+#define PCIBAR_IO 0x1 -+#define PCIBAR_MEM1M 0x2 -+#define PCIBAR_MEM64 0x4 -+#define PCIBAR_PREFETCH 0x8 -+#define PCIBAR_MEM32_MASK 0xFFFFFF80 -+ -+/* pci config status reg has a bit to indicate that capability ptr is present */ -+ -+#define PCI_CAPPTR_PRESENT 0x0010 -+ -+typedef struct _pci_config_regs { -+ uint16 vendor; -+ uint16 device; -+ uint16 command; -+ uint16 status; -+ uint8 rev_id; -+ uint8 prog_if; -+ uint8 sub_class; -+ uint8 base_class; -+ uint8 cache_line_size; -+ uint8 latency_timer; -+ uint8 header_type; -+ uint8 bist; -+ uint32 base[PCI_BAR_MAX]; -+ uint32 cardbus_cis; -+ uint16 subsys_vendor; -+ uint16 subsys_id; -+ uint32 baserom; -+ uint32 rsvd_a[PCR_RSVDA_MAX]; -+ uint8 int_line; -+ uint8 int_pin; -+ uint8 min_gnt; -+ uint8 max_lat; -+ uint8 dev_dep[192]; -+} pci_config_regs; -+ -+#define SZPCR (sizeof (pci_config_regs)) -+#define MINSZPCR 64 /* offsetof (dev_dep[0] */ -+ -+#endif /* !LINUX_POSTMOGRIFY_REMOVAL */ -+/* A structure for the config registers is nice, but in most -+ * systems the config space is not memory mapped, so we need -+ * field offsetts. :-( -+ */ -+#define PCI_CFG_VID 0 -+#define PCI_CFG_DID 2 -+#define PCI_CFG_CMD 4 -+#define PCI_CFG_STAT 6 -+#define PCI_CFG_REV 8 -+#define PCI_CFG_PROGIF 9 -+#define PCI_CFG_SUBCL 0xa -+#define PCI_CFG_BASECL 0xb -+#define PCI_CFG_CLSZ 0xc -+#define PCI_CFG_LATTIM 0xd -+#define PCI_CFG_HDR 0xe -+#define PCI_CFG_BIST 0xf -+#define PCI_CFG_BAR0 0x10 -+#define PCI_CFG_BAR1 0x14 -+#define PCI_CFG_BAR2 0x18 -+#define PCI_CFG_BAR3 0x1c -+#define PCI_CFG_BAR4 0x20 -+#define PCI_CFG_BAR5 0x24 -+#define PCI_CFG_CIS 0x28 -+#define PCI_CFG_SVID 0x2c -+#define PCI_CFG_SSID 0x2e -+#define PCI_CFG_ROMBAR 0x30 -+#define PCI_CFG_CAPPTR 0x34 -+#define PCI_CFG_INT 0x3c -+#define PCI_CFG_PIN 0x3d -+#define PCI_CFG_MINGNT 0x3e -+#define PCI_CFG_MAXLAT 0x3f -+#define PCI_CFG_DEVCTRL 0xd8 -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+ -+#ifdef __NetBSD__ -+#undef PCI_CLASS_DISPLAY -+#undef PCI_CLASS_MEMORY -+#undef PCI_CLASS_BRIDGE -+#undef PCI_CLASS_INPUT -+#undef PCI_CLASS_DOCK -+#endif /* __NetBSD__ */ -+ -+#ifdef EFI -+#undef PCI_CLASS_BRIDGE -+#undef PCI_CLASS_OLD -+#undef PCI_CLASS_DISPLAY -+#undef PCI_CLASS_SERIAL -+#undef PCI_CLASS_SATELLITE -+#endif /* EFI */ -+ -+/* Classes and subclasses */ -+ -+typedef enum { -+ PCI_CLASS_OLD = 0, -+ PCI_CLASS_DASDI, -+ PCI_CLASS_NET, -+ PCI_CLASS_DISPLAY, -+ PCI_CLASS_MMEDIA, -+ PCI_CLASS_MEMORY, -+ PCI_CLASS_BRIDGE, -+ PCI_CLASS_COMM, -+ PCI_CLASS_BASE, -+ PCI_CLASS_INPUT, -+ PCI_CLASS_DOCK, -+ PCI_CLASS_CPU, -+ PCI_CLASS_SERIAL, -+ PCI_CLASS_INTELLIGENT = 0xe, -+ PCI_CLASS_SATELLITE, -+ PCI_CLASS_CRYPT, -+ PCI_CLASS_DSP, -+ PCI_CLASS_XOR = 0xfe -+} pci_classes; -+ -+typedef enum { -+ PCI_DASDI_SCSI, -+ PCI_DASDI_IDE, -+ PCI_DASDI_FLOPPY, -+ PCI_DASDI_IPI, -+ PCI_DASDI_RAID, -+ PCI_DASDI_OTHER = 0x80 -+} pci_dasdi_subclasses; -+ -+typedef enum { -+ PCI_NET_ETHER, -+ PCI_NET_TOKEN, -+ PCI_NET_FDDI, -+ PCI_NET_ATM, -+ PCI_NET_OTHER = 0x80 -+} pci_net_subclasses; -+ -+typedef enum { -+ PCI_DISPLAY_VGA, -+ PCI_DISPLAY_XGA, -+ PCI_DISPLAY_3D, -+ PCI_DISPLAY_OTHER = 0x80 -+} pci_display_subclasses; -+ -+typedef enum { -+ PCI_MMEDIA_VIDEO, -+ PCI_MMEDIA_AUDIO, -+ PCI_MMEDIA_PHONE, -+ PCI_MEDIA_OTHER = 0x80 -+} pci_mmedia_subclasses; -+ -+typedef enum { -+ PCI_MEMORY_RAM, -+ PCI_MEMORY_FLASH, -+ PCI_MEMORY_OTHER = 0x80 -+} pci_memory_subclasses; -+ -+typedef enum { -+ PCI_BRIDGE_HOST, -+ PCI_BRIDGE_ISA, -+ PCI_BRIDGE_EISA, -+ PCI_BRIDGE_MC, -+ PCI_BRIDGE_PCI, -+ PCI_BRIDGE_PCMCIA, -+ PCI_BRIDGE_NUBUS, -+ PCI_BRIDGE_CARDBUS, -+ PCI_BRIDGE_RACEWAY, -+ PCI_BRIDGE_OTHER = 0x80 -+} pci_bridge_subclasses; -+ -+typedef enum { -+ PCI_COMM_UART, -+ PCI_COMM_PARALLEL, -+ PCI_COMM_MULTIUART, -+ PCI_COMM_MODEM, -+ PCI_COMM_OTHER = 0x80 -+} pci_comm_subclasses; -+ -+typedef enum { -+ PCI_BASE_PIC, -+ PCI_BASE_DMA, -+ PCI_BASE_TIMER, -+ PCI_BASE_RTC, -+ PCI_BASE_PCI_HOTPLUG, -+ PCI_BASE_OTHER = 0x80 -+} pci_base_subclasses; -+ -+typedef enum { -+ PCI_INPUT_KBD, -+ PCI_INPUT_PEN, -+ PCI_INPUT_MOUSE, -+ PCI_INPUT_SCANNER, -+ PCI_INPUT_GAMEPORT, -+ PCI_INPUT_OTHER = 0x80 -+} pci_input_subclasses; -+ -+typedef enum { -+ PCI_DOCK_GENERIC, -+ PCI_DOCK_OTHER = 0x80 -+} pci_dock_subclasses; -+ -+typedef enum { -+ PCI_CPU_386, -+ PCI_CPU_486, -+ PCI_CPU_PENTIUM, -+ PCI_CPU_ALPHA = 0x10, -+ PCI_CPU_POWERPC = 0x20, -+ PCI_CPU_MIPS = 0x30, -+ PCI_CPU_COPROC = 0x40, -+ PCI_CPU_OTHER = 0x80 -+} pci_cpu_subclasses; -+ -+typedef enum { -+ PCI_SERIAL_IEEE1394, -+ PCI_SERIAL_ACCESS, -+ PCI_SERIAL_SSA, -+ PCI_SERIAL_USB, -+ PCI_SERIAL_FIBER, -+ PCI_SERIAL_SMBUS, -+ PCI_SERIAL_OTHER = 0x80 -+} pci_serial_subclasses; -+ -+typedef enum { -+ PCI_INTELLIGENT_I2O -+} pci_intelligent_subclasses; -+ -+typedef enum { -+ PCI_SATELLITE_TV, -+ PCI_SATELLITE_AUDIO, -+ PCI_SATELLITE_VOICE, -+ PCI_SATELLITE_DATA, -+ PCI_SATELLITE_OTHER = 0x80 -+} pci_satellite_subclasses; -+ -+typedef enum { -+ PCI_CRYPT_NETWORK, -+ PCI_CRYPT_ENTERTAINMENT, -+ PCI_CRYPT_OTHER = 0x80 -+} pci_crypt_subclasses; -+ -+typedef enum { -+ PCI_DSP_DPIO, -+ PCI_DSP_OTHER = 0x80 -+} pci_dsp_subclasses; -+ -+typedef enum { -+ PCI_XOR_QDMA, -+ PCI_XOR_OTHER = 0x80 -+} pci_xor_subclasses; -+ -+/* Header types */ -+#define PCI_HEADER_MULTI 0x80 -+#define PCI_HEADER_MASK 0x7f -+typedef enum { -+ PCI_HEADER_NORMAL, -+ PCI_HEADER_BRIDGE, -+ PCI_HEADER_CARDBUS -+} pci_header_types; -+ -+ -+/* Overlay for a PCI-to-PCI bridge */ -+ -+#define PPB_RSVDA_MAX 2 -+#define PPB_RSVDD_MAX 8 -+ -+typedef struct _ppb_config_regs { -+ uint16 vendor; -+ uint16 device; -+ uint16 command; -+ uint16 status; -+ uint8 rev_id; -+ uint8 prog_if; -+ uint8 sub_class; -+ uint8 base_class; -+ uint8 cache_line_size; -+ uint8 latency_timer; -+ uint8 header_type; -+ uint8 bist; -+ uint32 rsvd_a[PPB_RSVDA_MAX]; -+ uint8 prim_bus; -+ uint8 sec_bus; -+ uint8 sub_bus; -+ uint8 sec_lat; -+ uint8 io_base; -+ uint8 io_lim; -+ uint16 sec_status; -+ uint16 mem_base; -+ uint16 mem_lim; -+ uint16 pf_mem_base; -+ uint16 pf_mem_lim; -+ uint32 pf_mem_base_hi; -+ uint32 pf_mem_lim_hi; -+ uint16 io_base_hi; -+ uint16 io_lim_hi; -+ uint16 subsys_vendor; -+ uint16 subsys_id; -+ uint32 rsvd_b; -+ uint8 rsvd_c; -+ uint8 int_pin; -+ uint16 bridge_ctrl; -+ uint8 chip_ctrl; -+ uint8 diag_ctrl; -+ uint16 arb_ctrl; -+ uint32 rsvd_d[PPB_RSVDD_MAX]; -+ uint8 dev_dep[192]; -+} ppb_config_regs; -+ -+ -+/* PCI CAPABILITY DEFINES */ -+#define PCI_CAP_POWERMGMTCAP_ID 0x01 -+#define PCI_CAP_MSICAP_ID 0x05 -+#define PCI_CAP_VENDSPEC_ID 0x09 -+#define PCI_CAP_PCIECAP_ID 0x10 -+ -+/* Data structure to define the Message Signalled Interrupt facility -+ * Valid for PCI and PCIE configurations -+ */ -+typedef struct _pciconfig_cap_msi { -+ uint8 capID; -+ uint8 nextptr; -+ uint16 msgctrl; -+ uint32 msgaddr; -+} pciconfig_cap_msi; -+ -+/* Data structure to define the Power managment facility -+ * Valid for PCI and PCIE configurations -+ */ -+typedef struct _pciconfig_cap_pwrmgmt { -+ uint8 capID; -+ uint8 nextptr; -+ uint16 pme_cap; -+ uint16 pme_sts_ctrl; -+ uint8 pme_bridge_ext; -+ uint8 data; -+} pciconfig_cap_pwrmgmt; -+ -+#define PME_CAP_PM_STATES (0x1f << 27) /* Bits 31:27 states that can generate PME */ -+#define PME_CSR_OFFSET 0x4 /* 4-bytes offset */ -+#define PME_CSR_PME_EN (1 << 8) /* Bit 8 Enable generating of PME */ -+#define PME_CSR_PME_STAT (1 << 15) /* Bit 15 PME got asserted */ -+ -+/* Data structure to define the PCIE capability */ -+typedef struct _pciconfig_cap_pcie { -+ uint8 capID; -+ uint8 nextptr; -+ uint16 pcie_cap; -+ uint32 dev_cap; -+ uint16 dev_ctrl; -+ uint16 dev_status; -+ uint32 link_cap; -+ uint16 link_ctrl; -+ uint16 link_status; -+ uint32 slot_cap; -+ uint16 slot_ctrl; -+ uint16 slot_status; -+ uint16 root_ctrl; -+ uint16 root_cap; -+ uint32 root_status; -+} pciconfig_cap_pcie; -+ -+/* PCIE Enhanced CAPABILITY DEFINES */ -+#define PCIE_EXTCFG_OFFSET 0x100 -+#define PCIE_ADVERRREP_CAPID 0x0001 -+#define PCIE_VC_CAPID 0x0002 -+#define PCIE_DEVSNUM_CAPID 0x0003 -+#define PCIE_PWRBUDGET_CAPID 0x0004 -+ -+/* PCIE Extended configuration */ -+#define PCIE_ADV_CORR_ERR_MASK 0x114 -+#define CORR_ERR_RE (1 << 0) /* Receiver */ -+#define CORR_ERR_BT (1 << 6) /* Bad TLP */ -+#define CORR_ERR_BD (1 << 7) /* Bad DLLP */ -+#define CORR_ERR_RR (1 << 8) /* REPLAY_NUM rollover */ -+#define CORR_ERR_RT (1 << 12) /* Reply timer timeout */ -+#define ALL_CORR_ERRORS (CORR_ERR_RE | CORR_ERR_BT | CORR_ERR_BD | \ -+ CORR_ERR_RR | CORR_ERR_RT) -+ -+/* PCIE Root Control Register bits (Host mode only) */ -+#define PCIE_RC_CORR_SERR_EN 0x0001 -+#define PCIE_RC_NONFATAL_SERR_EN 0x0002 -+#define PCIE_RC_FATAL_SERR_EN 0x0004 -+#define PCIE_RC_PME_INT_EN 0x0008 -+#define PCIE_RC_CRS_EN 0x0010 -+ -+/* PCIE Root Capability Register bits (Host mode only) */ -+#define PCIE_RC_CRS_VISIBILITY 0x0001 -+ -+/* Header to define the PCIE specific capabilities in the extended config space */ -+typedef struct _pcie_enhanced_caphdr { -+ uint16 capID; -+ uint16 cap_ver : 4; -+ uint16 next_ptr : 12; -+} pcie_enhanced_caphdr; -+ -+ -+/* Everything below is BRCM HND proprietary */ -+ -+ -+/* Brcm PCI configuration registers */ -+#define cap_list rsvd_a[0] -+#define bar0_window dev_dep[0x80 - 0x40] -+#define bar1_window dev_dep[0x84 - 0x40] -+#define sprom_control dev_dep[0x88 - 0x40] -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+#define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */ -+#define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */ -+#define PCI_SPROM_CONTROL 0x88 /* sprom property control */ -+#define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */ -+#define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */ -+#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */ -+#define PCI_TO_SB_MB 0x98 /* signal backplane interrupts */ -+#define PCI_BACKPLANE_ADDR 0xa0 /* address an arbitrary location on the system backplane */ -+#define PCI_BACKPLANE_DATA 0xa4 /* data at the location specified by above address */ -+#define PCI_CLK_CTL_ST 0xa8 /* pci config space clock control/status (>=rev14) */ -+#define PCI_BAR0_WIN2 0xac /* backplane addres space accessed by second 4KB of BAR0 */ -+#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */ -+#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */ -+#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */ -+ -+#define PCI_BAR0_SHADOW_OFFSET (2 * 1024) /* bar0 + 2K accesses sprom shadow (in pci core) */ -+#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */ -+#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */ -+#define PCI_BAR0_PCISBR_OFFSET (4 * 1024) /* pci core SB registers are at the end of the -+ * 8KB window, so their address is the "regular" -+ * address plus 4K -+ */ -+/* -+ * PCIE GEN2 changed some of the above locations for -+ * Bar0WrapperBase, SecondaryBAR0Window and SecondaryBAR0WrapperBase -+ * BAR0 maps 32K of register space -+*/ -+#define PCIE2_BAR0_WIN2 0x70 /* backplane addres space accessed by second 4KB of BAR0 */ -+#define PCIE2_BAR0_CORE2_WIN 0x74 /* backplane addres space accessed by second 4KB of BAR0 */ -+#define PCIE2_BAR0_CORE2_WIN2 0x78 /* backplane addres space accessed by second 4KB of BAR0 */ -+ -+#define PCI_BAR0_WINSZ (16 * 1024) /* bar0 window size Match with corerev 13 */ -+/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */ -+#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) /* bar0 + 8K accesses pci/pcie core registers */ -+#define PCI_16KB0_CCREGS_OFFSET (12 * 1024) /* bar0 + 12K accesses chipc core registers */ -+#define PCI_16KBB0_WINSZ (16 * 1024) /* bar0 window size */ -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+/* On AI chips we have a second window to map DMP regs are mapped: */ -+#define PCI_16KB0_WIN2_OFFSET (4 * 1024) /* bar0 + 4K is "Window 2" */ -+ -+/* PCI_INT_STATUS */ -+#define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */ -+ -+/* PCI_INT_MASK */ -+#define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */ -+#define PCI_SBIM_MASK 0xff00 /* backplane core interrupt mask */ -+#define PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */ -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+/* PCI_SPROM_CONTROL */ -+#define SPROM_SZ_MSK 0x02 /* SPROM Size Mask */ -+#define SPROM_LOCKED 0x08 /* SPROM Locked */ -+#define SPROM_BLANK 0x04 /* indicating a blank SPROM */ -+#define SPROM_WRITEEN 0x10 /* SPROM write enable */ -+#define SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */ -+#define SPROM_BACKPLANE_EN 0x40 /* Enable indirect backplane access */ -+#define SPROM_OTPIN_USE 0x80 /* device OTP In use */ -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+/* Bits in PCI command and status regs */ -+#define PCI_CMD_IO 0x00000001 /* I/O enable */ -+#define PCI_CMD_MEMORY 0x00000002 /* Memory enable */ -+#define PCI_CMD_MASTER 0x00000004 /* Master enable */ -+#define PCI_CMD_SPECIAL 0x00000008 /* Special cycles enable */ -+#define PCI_CMD_INVALIDATE 0x00000010 /* Invalidate? */ -+#define PCI_CMD_VGA_PAL 0x00000040 /* VGA Palate */ -+#define PCI_STAT_TA 0x08000000 /* target abort status */ -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+#define PCI_CONFIG_SPACE_SIZE 256 -+#endif /* _h_pcicfg_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/phy542xx.h b/drivers/net/ethernet/broadcom/gmac/src/include/phy542xx.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/phy542xx.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/phy542xx.h 2017-11-09 17:53:43.973296000 +0800 -@@ -0,0 +1,98 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * These routines provide access to the external phy -+ * -+ */ -+ -+#ifndef _PHY542XX_H_ -+#define _PHY542XX_H_ -+ -+#include -+ -+/* Broadcom BCM542xx */ -+#define phy542xx_rd_reg phy542xx_reg_read -+#define phy542xx_wr_reg phy542xx_reg_write -+ -+#define BCM542XX_REG_EXP_SEL 0x17 -+#define BCM542XX_REG_EXP_SELECT_7E 0x0F7E -+#define BCM542XX_REG_EXP_DATA 0x15 -+#define BCM542XX_REG_EXP_RDB_EN 0x0000 -+ -+#define BCM542XX_REG_RDB_ADDR 0x1e -+#define BCM542XX_REG_RDB_DATA 0x1f -+ -+#define MIIM_BCM542xx_RDB_AUXSTATUS 0x09 -+#define MIIM_BCM542xx_AUXSTATUS_LINKMODE_MASK 0x0700 -+#define MIIM_BCM542xx_AUXSTATUS_LINKMODE_SHIFT 8 -+ -+#define BCM542XX_REG_RDB_MII_MISC_CTRL 0x02f -+ -+#define BCM542XX_REG_RDB_EXT_SERDES_CTRL 0x234 -+#define BCM542XX_REG_EXT_SERDES_AUTO_FX (1 << 6) -+#define BCM542XX_REG_EXT_SERDES_FX_FD (1 << 5) -+#define BCM542XX_REG_EXT_SERDES_FX (1 << 4) -+#define BCM542XX_REG_EXT_SERDES_LED (1 << 3) -+#define BCM542XX_REG_EXT_SEL_SYNC_ST (1 << 2) -+#define BCM542XX_REG_EXT_SELECT_SD (1 << 1) -+#define BCM542XX_REG_EXT_SERDES_SEL (1 << 0) -+#define BCM542XX_REG_EXT_SERDES_FX_MASK (BCM542XX_REG_EXT_SERDES_FX | \ -+ BCM542XX_REG_EXT_SERDES_AUTO_FX) -+ -+#define BCM542XX_REG_RDB_SGMII_SLAVE 0x235 -+#define BCM542XX_REG_SGMII_SLAVE_AUTO (1 << 0) -+ -+#define MIIM_BCM542xx_RDB_AUTO_DETECT_MEDIUM 0x23e -+#define BCM542XX_REG_MII_AUTO_DET_MED_2ND_SERDES (1 << 9) -+#define BCM542XX_REG_MII_INV_FIBER_SD (1 << 8) -+#define BCM542XX_REG_MII_FIBER_IN_USE_LED (1 << 7) -+#define BCM542XX_REG_MII_FIBER_LED (1 << 6) -+#define BCM542XX_REG_MII_FIBER_SD_SYNC (1 << 5) -+#define BCM542XX_REG_MII_FIBER_AUTO_PWRDN (1 << 4) -+#define BCM542XX_REG_MII_SD_en_ov (1 << 3) -+#define BCM542XX_REG_MII_AUTO_DET_MED_DEFAULT (1 << 2) -+#define BCM542XX_REG_MII_AUTO_DET_MED_PRI (1 << 1) -+#define BCM542XX_REG_MII_AUTO_DET_MED_EN (1 << 0) -+#define BCM542XX_REG_MII_AUTO_DET_MASK 0x033f -+ -+#define BCM542XX_REG_RDB_MODE_CTRL 0x021 -+#define BCM542XX_REG_MODE_CTRL_COPPER_LINK (1 << 7) -+#define BCM542XX_REG_MODE_CTRL_SERDES_LINK (1 << 6) -+#define BCM542XX_REG_MODE_CTRL_COPPER_ENERGY_DET (1 << 5) -+#define BCM542XX_REG_MODE_CNTL_MODE_SEL_2 (1 << 2) -+#define BCM542XX_REG_MODE_CNTL_MODE_SEL_1 (1 << 1) -+#define BCM542XX_REG_MODE_CTRL_1000X_EN (1 << 0) -+ -+#define BCM542XX_REG_RDB_COPPER_MISC_CTRL 0x02f -+#define BCM542XX_REG_MISC_CTRL_FORCE_AUTO_MDIX (1 << 9) -+ -+#define BCM542XX_REG_MODE_SEL_COPPER_2_SGMII (0x0) -+#define BCM542XX_REG_MODE_SEL_FIBER_2_SGMII (BCM542XX_REG_MODE_CNTL_MODE_SEL_1) -+#define BCM542XX_REG_MODE_SEL_SGMII_2_COPPER (BCM542XX_REG_MODE_CNTL_MODE_SEL_2) -+#define BCM542XX_REG_MODE_SEL_GBIC (BCM542XX_REG_MODE_CNTL_MODE_SEL_1 | \ -+ BCM542XX_REG_MODE_CNTL_MODE_SEL_2) -+ -+#define BCM542XX_REG_RDB_2ND_SERDES_BASE 0xb00 -+#define BCM542XX_REG_RDB_2ND_SERDES_MISC_1000X 0xb17 -+ -+ -+extern int phy542xx_reg_read(u32 phy_addr, u32 flags, int reg_addr, u16 *data); -+extern int phy542xx_reg_write(u32 phy_addr, u32 flags, int reg_addr, u16 data); -+extern int phy542xx_reset_setup(u32 phy_addr); -+extern int phy542xx_init(u32 phy_addr); -+extern int phy542xx_enable_set(u32 phy_addr, int enable); -+extern int phy542xx_force_auto_mdix(u32 phy_addr, int enable); -+ -+#endif /* _PHY542XX_H_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/802.11.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/802.11.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/802.11.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/802.11.h 2017-11-09 17:53:43.976303000 +0800 -@@ -0,0 +1,2356 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Fundamental types and constants relating to 802.11 -+ * -+ * $Id: 802.11.h 308961 2012-01-18 03:01:00Z $ -+ */ -+ -+#ifndef _802_11_H_ -+#define _802_11_H_ -+ -+#ifndef _TYPEDEFS_H_ -+#include -+#endif -+ -+#ifndef _NET_ETHERNET_H_ -+#include -+#endif -+ -+#include -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+ -+#define DOT11_TU_TO_US 1024 /* 802.11 Time Unit is 1024 microseconds */ -+ -+/* Generic 802.11 frame constants */ -+#define DOT11_A3_HDR_LEN 24 /* d11 header length with A3 */ -+#define DOT11_A4_HDR_LEN 30 /* d11 header length with A4 */ -+#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN /* MAC header length */ -+#define DOT11_FCS_LEN 4 /* d11 FCS length */ -+#define DOT11_ICV_LEN 4 /* d11 ICV length */ -+#define DOT11_ICV_AES_LEN 8 /* d11 ICV/AES length */ -+#define DOT11_QOS_LEN 2 /* d11 QoS length */ -+#define DOT11_HTC_LEN 4 /* d11 HT Control field length */ -+ -+#define DOT11_KEY_INDEX_SHIFT 6 /* d11 key index shift */ -+#define DOT11_IV_LEN 4 /* d11 IV length */ -+#define DOT11_IV_TKIP_LEN 8 /* d11 IV TKIP length */ -+#define DOT11_IV_AES_OCB_LEN 4 /* d11 IV/AES/OCB length */ -+#define DOT11_IV_AES_CCM_LEN 8 /* d11 IV/AES/CCM length */ -+#define DOT11_IV_MAX_LEN 8 /* maximum iv len for any encryption */ -+ -+/* Includes MIC */ -+#define DOT11_MAX_MPDU_BODY_LEN 2304 /* max MPDU body length */ -+/* A4 header + QoS + CCMP + PDU + ICV + FCS = 2352 */ -+#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \ -+ DOT11_QOS_LEN + \ -+ DOT11_IV_AES_CCM_LEN + \ -+ DOT11_MAX_MPDU_BODY_LEN + \ -+ DOT11_ICV_LEN + \ -+ DOT11_FCS_LEN) /* d11 max MPDU length */ -+ -+#define DOT11_MAX_SSID_LEN 32 /* d11 max ssid length */ -+ -+/* dot11RTSThreshold */ -+#define DOT11_DEFAULT_RTS_LEN 2347 /* d11 default RTS length */ -+#define DOT11_MAX_RTS_LEN 2347 /* d11 max RTS length */ -+ -+/* dot11FragmentationThreshold */ -+#define DOT11_MIN_FRAG_LEN 256 /* d11 min fragmentation length */ -+#define DOT11_MAX_FRAG_LEN 2346 /* Max frag is also limited by aMPDUMaxLength -+ * of the attached PHY -+ */ -+#define DOT11_DEFAULT_FRAG_LEN 2346 /* d11 default fragmentation length */ -+ -+/* dot11BeaconPeriod */ -+#define DOT11_MIN_BEACON_PERIOD 1 /* d11 min beacon period */ -+#define DOT11_MAX_BEACON_PERIOD 0xFFFF /* d11 max beacon period */ -+ -+/* dot11DTIMPeriod */ -+#define DOT11_MIN_DTIM_PERIOD 1 /* d11 min DTIM period */ -+#define DOT11_MAX_DTIM_PERIOD 0xFF /* d11 max DTIM period */ -+ -+/* 802.2 LLC/SNAP header used by 802.11 per 802.1H */ -+#define DOT11_LLC_SNAP_HDR_LEN 8 /* d11 LLC/SNAP header length */ -+#define DOT11_OUI_LEN 3 /* d11 OUI length */ -+BWL_PRE_PACKED_STRUCT struct dot11_llc_snap_header { -+ uint8 dsap; /* always 0xAA */ -+ uint8 ssap; /* always 0xAA */ -+ uint8 ctl; /* always 0x03 */ -+ uint8 oui[DOT11_OUI_LEN]; /* RFC1042: 0x00 0x00 0x00 -+ * Bridge-Tunnel: 0x00 0x00 0xF8 -+ */ -+ uint16 type; /* ethertype */ -+} BWL_POST_PACKED_STRUCT; -+ -+/* RFC1042 header used by 802.11 per 802.1H */ -+#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN) /* RCF1042 header length */ -+ -+/* Generic 802.11 MAC header */ -+/* -+ * N.B.: This struct reflects the full 4 address 802.11 MAC header. -+ * The fields are defined such that the shorter 1, 2, and 3 -+ * address headers just use the first k fields. -+ */ -+BWL_PRE_PACKED_STRUCT struct dot11_header { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr a1; /* address 1 */ -+ struct ether_addr a2; /* address 2 */ -+ struct ether_addr a3; /* address 3 */ -+ uint16 seq; /* sequence control */ -+ struct ether_addr a4; /* address 4 */ -+} BWL_POST_PACKED_STRUCT; -+ -+/* Control frames */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_rts_frame { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr ra; /* receiver address */ -+ struct ether_addr ta; /* transmitter address */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_RTS_LEN 16 /* d11 RTS frame length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_cts_frame { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr ra; /* receiver address */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_CTS_LEN 10 /* d11 CTS frame length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_ack_frame { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr ra; /* receiver address */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_ACK_LEN 10 /* d11 ACK frame length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_ps_poll_frame { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* AID */ -+ struct ether_addr bssid; /* receiver address, STA in AP */ -+ struct ether_addr ta; /* transmitter address */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_PS_POLL_LEN 16 /* d11 PS poll frame length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_cf_end_frame { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr ra; /* receiver address */ -+ struct ether_addr bssid; /* transmitter address, STA in AP */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_CS_END_LEN 16 /* d11 CF-END frame length */ -+ -+/* RWL wifi protocol: The Vendor Specific Action frame is defined for vendor-specific signaling -+* category+OUI+vendor specific content ( this can be variable) -+*/ -+BWL_PRE_PACKED_STRUCT struct dot11_action_wifi_vendor_specific { -+ uint8 category; -+ uint8 OUI[3]; -+ uint8 type; -+ uint8 subtype; -+ uint8 data[1040]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_action_wifi_vendor_specific dot11_action_wifi_vendor_specific_t; -+ -+/* generic vender specific action frame with variable length */ -+BWL_PRE_PACKED_STRUCT struct dot11_action_vs_frmhdr { -+ uint8 category; -+ uint8 OUI[3]; -+ uint8 type; -+ uint8 subtype; -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_action_vs_frmhdr dot11_action_vs_frmhdr_t; -+#define DOT11_ACTION_VS_HDR_LEN 6 -+ -+#define BCM_ACTION_OUI_BYTE0 0x00 -+#define BCM_ACTION_OUI_BYTE1 0x90 -+#define BCM_ACTION_OUI_BYTE2 0x4c -+ -+/* BA/BAR Control parameters */ -+#define DOT11_BA_CTL_POLICY_NORMAL 0x0000 /* normal ack */ -+#define DOT11_BA_CTL_POLICY_NOACK 0x0001 /* no ack */ -+#define DOT11_BA_CTL_POLICY_MASK 0x0001 /* ack policy mask */ -+ -+#define DOT11_BA_CTL_MTID 0x0002 /* multi tid BA */ -+#define DOT11_BA_CTL_COMPRESSED 0x0004 /* compressed bitmap */ -+ -+#define DOT11_BA_CTL_NUMMSDU_MASK 0x0FC0 /* num msdu in bitmap mask */ -+#define DOT11_BA_CTL_NUMMSDU_SHIFT 6 /* num msdu in bitmap shift */ -+ -+#define DOT11_BA_CTL_TID_MASK 0xF000 /* tid mask */ -+#define DOT11_BA_CTL_TID_SHIFT 12 /* tid shift */ -+ -+/* control frame header (BA/BAR) */ -+BWL_PRE_PACKED_STRUCT struct dot11_ctl_header { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr ra; /* receiver address */ -+ struct ether_addr ta; /* transmitter address */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_CTL_HDR_LEN 16 /* control frame hdr len */ -+ -+/* BAR frame payload */ -+BWL_PRE_PACKED_STRUCT struct dot11_bar { -+ uint16 bar_control; /* BAR Control */ -+ uint16 seqnum; /* Starting Sequence control */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_BAR_LEN 4 /* BAR frame payload length */ -+ -+#define DOT11_BA_BITMAP_LEN 128 /* bitmap length */ -+#define DOT11_BA_CMP_BITMAP_LEN 8 /* compressed bitmap length */ -+/* BA frame payload */ -+BWL_PRE_PACKED_STRUCT struct dot11_ba { -+ uint16 ba_control; /* BA Control */ -+ uint16 seqnum; /* Starting Sequence control */ -+ uint8 bitmap[DOT11_BA_BITMAP_LEN]; /* Block Ack Bitmap */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_BA_LEN 4 /* BA frame payload len (wo bitmap) */ -+ -+/* Management frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_management_header { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr da; /* receiver address */ -+ struct ether_addr sa; /* transmitter address */ -+ struct ether_addr bssid; /* BSS ID */ -+ uint16 seq; /* sequence control */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_MGMT_HDR_LEN 24 /* d11 management header length */ -+ -+/* Management frame payloads */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_bcn_prb { -+ uint32 timestamp[2]; -+ uint16 beacon_interval; -+ uint16 capability; -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_BCN_PRB_LEN 12 /* 802.11 beacon/probe frame fixed length */ -+#define DOT11_BCN_PRB_FIXED_LEN 12 /* 802.11 beacon/probe frame fixed length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_auth { -+ uint16 alg; /* algorithm */ -+ uint16 seq; /* sequence control */ -+ uint16 status; /* status code */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_AUTH_FIXED_LEN 6 /* length of auth frame without challenge IE */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_assoc_req { -+ uint16 capability; /* capability information */ -+ uint16 listen; /* listen interval */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_ASSOC_REQ_FIXED_LEN 4 /* length of assoc frame without info elts */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_reassoc_req { -+ uint16 capability; /* capability information */ -+ uint16 listen; /* listen interval */ -+ struct ether_addr ap; /* Current AP address */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_REASSOC_REQ_FIXED_LEN 10 /* length of assoc frame without info elts */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_assoc_resp { -+ uint16 capability; /* capability information */ -+ uint16 status; /* status code */ -+ uint16 aid; /* association ID */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_ASSOC_RESP_FIXED_LEN 6 /* length of assoc resp frame without info elts */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_action_measure { -+ uint8 category; -+ uint8 action; -+ uint8 token; -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_ACTION_MEASURE_LEN 3 /* d11 action measurement header length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_action_ht_ch_width { -+ uint8 category; -+ uint8 action; -+ uint8 ch_width; -+} BWL_POST_PACKED_STRUCT; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_action_ht_mimops { -+ uint8 category; -+ uint8 action; -+ uint8 control; -+} BWL_POST_PACKED_STRUCT; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_action_sa_query { -+ uint8 category; -+ uint8 action; -+ uint16 id; -+} BWL_POST_PACKED_STRUCT; -+ -+#define SM_PWRSAVE_ENABLE 1 -+#define SM_PWRSAVE_MODE 2 -+ -+/* ************* 802.11h related definitions. ************* */ -+BWL_PRE_PACKED_STRUCT struct dot11_power_cnst { -+ uint8 id; -+ uint8 len; -+ uint8 power; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_power_cnst dot11_power_cnst_t; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_power_cap { -+ uint8 min; -+ uint8 max; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_power_cap dot11_power_cap_t; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_tpc_rep { -+ uint8 id; -+ uint8 len; -+ uint8 tx_pwr; -+ uint8 margin; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_tpc_rep dot11_tpc_rep_t; -+#define DOT11_MNG_IE_TPC_REPORT_LEN 2 /* length of IE data, not including 2 byte header */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_supp_channels { -+ uint8 id; -+ uint8 len; -+ uint8 first_channel; -+ uint8 num_channels; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_supp_channels dot11_supp_channels_t; -+ -+/* Extension Channel Offset IE: 802.11n-D1.0 spec. added sideband -+ * offset for 40MHz operation. The possible 3 values are: -+ * 1 = above control channel -+ * 3 = below control channel -+ * 0 = no extension channel -+ */ -+BWL_PRE_PACKED_STRUCT struct dot11_extch { -+ uint8 id; /* IE ID, 62, DOT11_MNG_EXT_CHANNEL_OFFSET */ -+ uint8 len; /* IE length */ -+ uint8 extch; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_extch dot11_extch_ie_t; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_brcm_extch { -+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ -+ uint8 len; /* IE length */ -+ uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ -+ uint8 type; /* type inidicates what follows */ -+ uint8 extch; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_brcm_extch dot11_brcm_extch_ie_t; -+ -+#define BRCM_EXTCH_IE_LEN 5 -+#define BRCM_EXTCH_IE_TYPE 53 /* 802.11n ID not yet assigned */ -+#define DOT11_EXTCH_IE_LEN 1 -+#define DOT11_EXT_CH_MASK 0x03 /* extension channel mask */ -+#define DOT11_EXT_CH_UPPER 0x01 /* ext. ch. on upper sb */ -+#define DOT11_EXT_CH_LOWER 0x03 /* ext. ch. on lower sb */ -+#define DOT11_EXT_CH_NONE 0x00 /* no extension ch. */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_action_frmhdr { -+ uint8 category; -+ uint8 action; -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_ACTION_FRMHDR_LEN 2 -+ -+/* CSA IE data structure */ -+BWL_PRE_PACKED_STRUCT struct dot11_channel_switch { -+ uint8 id; /* id DOT11_MNG_CHANNEL_SWITCH_ID */ -+ uint8 len; /* length of IE */ -+ uint8 mode; /* mode 0 or 1 */ -+ uint8 channel; /* channel switch to */ -+ uint8 count; /* number of beacons before switching */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_channel_switch dot11_chan_switch_ie_t; -+ -+#define DOT11_SWITCH_IE_LEN 3 /* length of IE data, not including 2 byte header */ -+/* CSA mode - 802.11h-2003 $7.3.2.20 */ -+#define DOT11_CSA_MODE_ADVISORY 0 /* no DOT11_CSA_MODE_NO_TX restriction imposed */ -+#define DOT11_CSA_MODE_NO_TX 1 /* no transmission upon receiving CSA frame. */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_action_switch_channel { -+ uint8 category; -+ uint8 action; -+ dot11_chan_switch_ie_t chan_switch_ie; /* for switch IE */ -+ dot11_brcm_extch_ie_t extch_ie; /* extension channel offset */ -+} BWL_POST_PACKED_STRUCT; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_csa_body { -+ uint8 mode; /* mode 0 or 1 */ -+ uint8 reg; /* regulatory class */ -+ uint8 channel; /* channel switch to */ -+ uint8 count; /* number of beacons before switching */ -+} BWL_POST_PACKED_STRUCT; -+ -+/* 11n Extended Channel Switch IE data structure */ -+BWL_PRE_PACKED_STRUCT struct dot11_ext_csa { -+ uint8 id; /* id DOT11_MNG_EXT_CHANNEL_SWITCH_ID */ -+ uint8 len; /* length of IE */ -+ struct dot11_csa_body b; /* body of the ie */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_ext_csa dot11_ext_csa_ie_t; -+#define DOT11_EXT_CSA_IE_LEN 4 /* length of extended channel switch IE body */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_action_ext_csa { -+ uint8 category; -+ uint8 action; -+ dot11_ext_csa_ie_t chan_switch_ie; /* for switch IE */ -+} BWL_POST_PACKED_STRUCT; -+ -+BWL_PRE_PACKED_STRUCT struct dot11y_action_ext_csa { -+ uint8 category; -+ uint8 action; -+ struct dot11_csa_body b; /* body of the ie */ -+} BWL_POST_PACKED_STRUCT; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_obss_coex { -+ uint8 id; -+ uint8 len; -+ uint8 info; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_obss_coex dot11_obss_coex_t; -+#define DOT11_OBSS_COEXINFO_LEN 1 /* length of OBSS Coexistence INFO IE */ -+ -+#define DOT11_OBSS_COEX_INFO_REQ 0x01 -+#define DOT11_OBSS_COEX_40MHZ_INTOLERANT 0x02 -+#define DOT11_OBSS_COEX_20MHZ_WIDTH_REQ 0x04 -+ -+BWL_PRE_PACKED_STRUCT struct dot11_obss_chanlist { -+ uint8 id; -+ uint8 len; -+ uint8 regclass; -+ uint8 chanlist[1]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_obss_chanlist dot11_obss_chanlist_t; -+#define DOT11_OBSS_CHANLIST_FIXED_LEN 1 /* fixed length of regclass */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_extcap_ie { -+ uint8 id; -+ uint8 len; -+ uint8 cap[1]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_extcap_ie dot11_extcap_ie_t; -+ -+#define DOT11_EXTCAP_LEN_MAX 7 -+#define DOT11_EXTCAP_LEN_COEX 1 -+#define DOT11_EXTCAP_LEN_BT 3 -+#define DOT11_EXTCAP_LEN_IW 4 -+#define DOT11_EXTCAP_LEN_SI 6 -+ -+#define DOT11_EXTCAP_LEN_TDLS 5 -+BWL_PRE_PACKED_STRUCT struct dot11_extcap { -+ uint8 extcap[DOT11_EXTCAP_LEN_TDLS]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_extcap dot11_extcap_t; -+ -+/* TDLS Capabilities */ -+#define TDLS_CAP_TDLS 37 /* TDLS support */ -+#define TDLS_CAP_PU_BUFFER_STA 28 /* TDLS Peer U-APSD buffer STA support */ -+#define TDLS_CAP_PEER_PSM 20 /* TDLS Peer PSM support */ -+#define TDLS_CAP_CH_SW 30 /* TDLS Channel switch */ -+#define TDLS_CAP_PROH 38 /* TDLS prohibited */ -+#define TDLS_CAP_CH_SW_PROH 39 /* TDLS Channel switch prohibited */ -+ -+#define TDLS_CAP_MAX_BIT 39 /* TDLS max bit defined in ext cap */ -+ -+/* 802.11h/802.11k Measurement Request/Report IEs */ -+/* Measurement Type field */ -+#define DOT11_MEASURE_TYPE_BASIC 0 /* d11 measurement basic type */ -+#define DOT11_MEASURE_TYPE_CCA 1 /* d11 measurement CCA type */ -+#define DOT11_MEASURE_TYPE_RPI 2 /* d11 measurement RPI type */ -+#define DOT11_MEASURE_TYPE_CHLOAD 3 /* d11 measurement Channel Load type */ -+#define DOT11_MEASURE_TYPE_NOISE 4 /* d11 measurement Noise Histogram type */ -+#define DOT11_MEASURE_TYPE_BEACON 5 /* d11 measurement Beacon type */ -+#define DOT11_MEASURE_TYPE_FRAME 6 /* d11 measurement Frame type */ -+#define DOT11_MEASURE_TYPE_STATS 7 /* d11 measurement STA Statistics type */ -+#define DOT11_MEASURE_TYPE_LCI 8 /* d11 measurement LCI type */ -+#define DOT11_MEASURE_TYPE_TXSTREAM 9 /* d11 measurement TX Stream type */ -+#define DOT11_MEASURE_TYPE_PAUSE 255 /* d11 measurement pause type */ -+ -+/* Measurement Request Modes */ -+#define DOT11_MEASURE_MODE_PARALLEL (1<<0) /* d11 measurement parallel */ -+#define DOT11_MEASURE_MODE_ENABLE (1<<1) /* d11 measurement enable */ -+#define DOT11_MEASURE_MODE_REQUEST (1<<2) /* d11 measurement request */ -+#define DOT11_MEASURE_MODE_REPORT (1<<3) /* d11 measurement report */ -+#define DOT11_MEASURE_MODE_DUR (1<<4) /* d11 measurement dur mandatory */ -+/* Measurement Report Modes */ -+#define DOT11_MEASURE_MODE_LATE (1<<0) /* d11 measurement late */ -+#define DOT11_MEASURE_MODE_INCAPABLE (1<<1) /* d11 measurement incapable */ -+#define DOT11_MEASURE_MODE_REFUSED (1<<2) /* d11 measurement refuse */ -+/* Basic Measurement Map bits */ -+#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0)) /* d11 measurement basic map BSS */ -+#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1)) /* d11 measurement map OFDM */ -+#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2)) /* d11 measurement map unknown */ -+#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3)) /* d11 measurement map radar */ -+#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4)) /* d11 measurement map unmeasuremnt */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_meas_req { -+ uint8 id; -+ uint8 len; -+ uint8 token; -+ uint8 mode; -+ uint8 type; -+ uint8 channel; -+ uint8 start_time[8]; -+ uint16 duration; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_meas_req dot11_meas_req_t; -+#define DOT11_MNG_IE_MREQ_LEN 14 /* d11 measurement request IE length */ -+/* length of Measure Request IE data not including variable len */ -+#define DOT11_MNG_IE_MREQ_FIXED_LEN 3 /* d11 measurement request IE fixed length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_meas_rep { -+ uint8 id; -+ uint8 len; -+ uint8 token; -+ uint8 mode; -+ uint8 type; -+ BWL_PRE_PACKED_STRUCT union -+ { -+ BWL_PRE_PACKED_STRUCT struct { -+ uint8 channel; -+ uint8 start_time[8]; -+ uint16 duration; -+ uint8 map; -+ } BWL_POST_PACKED_STRUCT basic; -+ uint8 data[1]; -+ } BWL_POST_PACKED_STRUCT rep; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_meas_rep dot11_meas_rep_t; -+ -+/* length of Measure Report IE data not including variable len */ -+#define DOT11_MNG_IE_MREP_FIXED_LEN 3 /* d11 measurement response IE fixed length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_meas_rep_basic { -+ uint8 channel; -+ uint8 start_time[8]; -+ uint16 duration; -+ uint8 map; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t; -+#define DOT11_MEASURE_BASIC_REP_LEN 12 /* d11 measurement basic report length */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_quiet { -+ uint8 id; -+ uint8 len; -+ uint8 count; /* TBTTs until beacon interval in quiet starts */ -+ uint8 period; /* Beacon intervals between periodic quiet periods ? */ -+ uint16 duration; /* Length of quiet period, in TU's */ -+ uint16 offset; /* TU's offset from TBTT in Count field */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_quiet dot11_quiet_t; -+ -+BWL_PRE_PACKED_STRUCT struct chan_map_tuple { -+ uint8 channel; -+ uint8 map; -+} BWL_POST_PACKED_STRUCT; -+typedef struct chan_map_tuple chan_map_tuple_t; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_ibss_dfs { -+ uint8 id; -+ uint8 len; -+ uint8 eaddr[ETHER_ADDR_LEN]; -+ uint8 interval; -+ chan_map_tuple_t map[1]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_ibss_dfs dot11_ibss_dfs_t; -+ -+/* WME Elements */ -+#define WME_OUI "\x00\x50\xf2" /* WME OUI */ -+#define WME_OUI_LEN 3 -+#define WME_OUI_TYPE 2 /* WME type */ -+#define WME_TYPE 2 /* WME type, deprecated */ -+#define WME_SUBTYPE_IE 0 /* Information Element */ -+#define WME_SUBTYPE_PARAM_IE 1 /* Parameter Element */ -+#define WME_SUBTYPE_TSPEC 2 /* Traffic Specification */ -+#define WME_VER 1 /* WME version */ -+ -+/* WME Access Category Indices (ACIs) */ -+#define AC_BE 0 /* Best Effort */ -+#define AC_BK 1 /* Background */ -+#define AC_VI 2 /* Video */ -+#define AC_VO 3 /* Voice */ -+#define AC_COUNT 4 /* number of ACs */ -+ -+typedef uint8 ac_bitmap_t; /* AC bitmap of (1 << AC_xx) */ -+ -+#define AC_BITMAP_NONE 0x0 /* No ACs */ -+#define AC_BITMAP_ALL 0xf /* All ACs */ -+#define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0) -+#define AC_BITMAP_SET(ab, ac) (((ab) |= (1 << (ac)))) -+#define AC_BITMAP_RESET(ab, ac) (((ab) &= ~(1 << (ac)))) -+ -+/* WME Information Element (IE) */ -+BWL_PRE_PACKED_STRUCT struct wme_ie { -+ uint8 oui[3]; -+ uint8 type; -+ uint8 subtype; -+ uint8 version; -+ uint8 qosinfo; -+} BWL_POST_PACKED_STRUCT; -+typedef struct wme_ie wme_ie_t; -+#define WME_IE_LEN 7 /* WME IE length */ -+ -+BWL_PRE_PACKED_STRUCT struct edcf_acparam { -+ uint8 ACI; -+ uint8 ECW; -+ uint16 TXOP; /* stored in network order (ls octet first) */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct edcf_acparam edcf_acparam_t; -+ -+/* WME Parameter Element (PE) */ -+BWL_PRE_PACKED_STRUCT struct wme_param_ie { -+ uint8 oui[3]; -+ uint8 type; -+ uint8 subtype; -+ uint8 version; -+ uint8 qosinfo; -+ uint8 rsvd; -+ edcf_acparam_t acparam[AC_COUNT]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct wme_param_ie wme_param_ie_t; -+#define WME_PARAM_IE_LEN 24 /* WME Parameter IE length */ -+ -+/* QoS Info field for IE as sent from AP */ -+#define WME_QI_AP_APSD_MASK 0x80 /* U-APSD Supported mask */ -+#define WME_QI_AP_APSD_SHIFT 7 /* U-APSD Supported shift */ -+#define WME_QI_AP_COUNT_MASK 0x0f /* Parameter set count mask */ -+#define WME_QI_AP_COUNT_SHIFT 0 /* Parameter set count shift */ -+ -+/* QoS Info field for IE as sent from STA */ -+#define WME_QI_STA_MAXSPLEN_MASK 0x60 /* Max Service Period Length mask */ -+#define WME_QI_STA_MAXSPLEN_SHIFT 5 /* Max Service Period Length shift */ -+#define WME_QI_STA_APSD_ALL_MASK 0xf /* APSD all AC bits mask */ -+#define WME_QI_STA_APSD_ALL_SHIFT 0 /* APSD all AC bits shift */ -+#define WME_QI_STA_APSD_BE_MASK 0x8 /* APSD AC_BE mask */ -+#define WME_QI_STA_APSD_BE_SHIFT 3 /* APSD AC_BE shift */ -+#define WME_QI_STA_APSD_BK_MASK 0x4 /* APSD AC_BK mask */ -+#define WME_QI_STA_APSD_BK_SHIFT 2 /* APSD AC_BK shift */ -+#define WME_QI_STA_APSD_VI_MASK 0x2 /* APSD AC_VI mask */ -+#define WME_QI_STA_APSD_VI_SHIFT 1 /* APSD AC_VI shift */ -+#define WME_QI_STA_APSD_VO_MASK 0x1 /* APSD AC_VO mask */ -+#define WME_QI_STA_APSD_VO_SHIFT 0 /* APSD AC_VO shift */ -+ -+/* ACI */ -+#define EDCF_AIFSN_MIN 1 /* AIFSN minimum value */ -+#define EDCF_AIFSN_MAX 15 /* AIFSN maximum value */ -+#define EDCF_AIFSN_MASK 0x0f /* AIFSN mask */ -+#define EDCF_ACM_MASK 0x10 /* ACM mask */ -+#define EDCF_ACI_MASK 0x60 /* ACI mask */ -+#define EDCF_ACI_SHIFT 5 /* ACI shift */ -+#define EDCF_AIFSN_SHIFT 12 /* 4 MSB(0xFFF) in ifs_ctl for AC idx */ -+ -+/* ECW */ -+#define EDCF_ECW_MIN 0 /* cwmin/cwmax exponent minimum value */ -+#define EDCF_ECW_MAX 15 /* cwmin/cwmax exponent maximum value */ -+#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) -+#define EDCF_ECWMIN_MASK 0x0f /* cwmin exponent form mask */ -+#define EDCF_ECWMAX_MASK 0xf0 /* cwmax exponent form mask */ -+#define EDCF_ECWMAX_SHIFT 4 /* cwmax exponent form shift */ -+ -+/* TXOP */ -+#define EDCF_TXOP_MIN 0 /* TXOP minimum value */ -+#define EDCF_TXOP_MAX 65535 /* TXOP maximum value */ -+#define EDCF_TXOP2USEC(txop) ((txop) << 5) -+ -+/* Default BE ACI value for non-WME connection STA */ -+#define NON_EDCF_AC_BE_ACI_STA 0x02 -+ -+/* Default EDCF parameters that AP advertises for STA to use; WMM draft Table 12 */ -+#define EDCF_AC_BE_ACI_STA 0x03 /* STA ACI value for best effort AC */ -+#define EDCF_AC_BE_ECW_STA 0xA4 /* STA ECW value for best effort AC */ -+#define EDCF_AC_BE_TXOP_STA 0x0000 /* STA TXOP value for best effort AC */ -+#define EDCF_AC_BK_ACI_STA 0x27 /* STA ACI value for background AC */ -+#define EDCF_AC_BK_ECW_STA 0xA4 /* STA ECW value for background AC */ -+#define EDCF_AC_BK_TXOP_STA 0x0000 /* STA TXOP value for background AC */ -+#define EDCF_AC_VI_ACI_STA 0x42 /* STA ACI value for video AC */ -+#define EDCF_AC_VI_ECW_STA 0x43 /* STA ECW value for video AC */ -+#define EDCF_AC_VI_TXOP_STA 0x005e /* STA TXOP value for video AC */ -+#define EDCF_AC_VO_ACI_STA 0x62 /* STA ACI value for audio AC */ -+#define EDCF_AC_VO_ECW_STA 0x32 /* STA ECW value for audio AC */ -+#define EDCF_AC_VO_TXOP_STA 0x002f /* STA TXOP value for audio AC */ -+ -+/* Default EDCF parameters that AP uses; WMM draft Table 14 */ -+#define EDCF_AC_BE_ACI_AP 0x03 /* AP ACI value for best effort AC */ -+#define EDCF_AC_BE_ECW_AP 0x64 /* AP ECW value for best effort AC */ -+#define EDCF_AC_BE_TXOP_AP 0x0000 /* AP TXOP value for best effort AC */ -+#define EDCF_AC_BK_ACI_AP 0x27 /* AP ACI value for background AC */ -+#define EDCF_AC_BK_ECW_AP 0xA4 /* AP ECW value for background AC */ -+#define EDCF_AC_BK_TXOP_AP 0x0000 /* AP TXOP value for background AC */ -+#define EDCF_AC_VI_ACI_AP 0x41 /* AP ACI value for video AC */ -+#define EDCF_AC_VI_ECW_AP 0x43 /* AP ECW value for video AC */ -+#define EDCF_AC_VI_TXOP_AP 0x005e /* AP TXOP value for video AC */ -+#define EDCF_AC_VO_ACI_AP 0x61 /* AP ACI value for audio AC */ -+#define EDCF_AC_VO_ECW_AP 0x32 /* AP ECW value for audio AC */ -+#define EDCF_AC_VO_TXOP_AP 0x002f /* AP TXOP value for audio AC */ -+ -+/* EDCA Parameter IE */ -+BWL_PRE_PACKED_STRUCT struct edca_param_ie { -+ uint8 qosinfo; -+ uint8 rsvd; -+ edcf_acparam_t acparam[AC_COUNT]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct edca_param_ie edca_param_ie_t; -+#define EDCA_PARAM_IE_LEN 18 /* EDCA Parameter IE length */ -+ -+/* QoS Capability IE */ -+BWL_PRE_PACKED_STRUCT struct qos_cap_ie { -+ uint8 qosinfo; -+} BWL_POST_PACKED_STRUCT; -+typedef struct qos_cap_ie qos_cap_ie_t; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_qbss_load_ie { -+ uint8 id; /* 11, DOT11_MNG_QBSS_LOAD_ID */ -+ uint8 length; -+ uint16 station_count; /* total number of STAs associated */ -+ uint8 channel_utilization; /* % of time, normalized to 255, QAP sensed medium busy */ -+ uint16 aac; /* available admission capacity */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_qbss_load_ie dot11_qbss_load_ie_t; -+#define BSS_LOAD_IE_SIZE 7 /* BSS load IE size */ -+ -+/* nom_msdu_size */ -+#define FIXED_MSDU_SIZE 0x8000 /* MSDU size is fixed */ -+#define MSDU_SIZE_MASK 0x7fff /* (Nominal or fixed) MSDU size */ -+ -+/* surplus_bandwidth */ -+/* Represented as 3 bits of integer, binary point, 13 bits fraction */ -+#define INTEGER_SHIFT 13 /* integer shift */ -+#define FRACTION_MASK 0x1FFF /* fraction mask */ -+ -+/* Management Notification Frame */ -+BWL_PRE_PACKED_STRUCT struct dot11_management_notification { -+ uint8 category; /* DOT11_ACTION_NOTIFICATION */ -+ uint8 action; -+ uint8 token; -+ uint8 status; -+ uint8 data[1]; /* Elements */ -+} BWL_POST_PACKED_STRUCT; -+#define DOT11_MGMT_NOTIFICATION_LEN 4 /* Fixed length */ -+ -+/* Timeout Interval IE */ -+BWL_PRE_PACKED_STRUCT struct ti_ie { -+ uint8 ti_type; -+ uint32 ti_val; -+} BWL_POST_PACKED_STRUCT; -+typedef struct ti_ie ti_ie_t; -+#define TI_TYPE_REASSOC_DEADLINE 1 -+#define TI_TYPE_KEY_LIFETIME 2 -+ -+/* WME Action Codes */ -+#define WME_ADDTS_REQUEST 0 /* WME ADDTS request */ -+#define WME_ADDTS_RESPONSE 1 /* WME ADDTS response */ -+#define WME_DELTS_REQUEST 2 /* WME DELTS request */ -+ -+/* WME Setup Response Status Codes */ -+#define WME_ADMISSION_ACCEPTED 0 /* WME admission accepted */ -+#define WME_INVALID_PARAMETERS 1 /* WME invalide parameters */ -+#define WME_ADMISSION_REFUSED 3 /* WME admission refused */ -+ -+/* Macro to take a pointer to a beacon or probe response -+ * body and return the char* pointer to the SSID info element -+ */ -+#define BCN_PRB_SSID(body) ((char*)(body) + DOT11_BCN_PRB_LEN) -+ -+/* Authentication frame payload constants */ -+#define DOT11_OPEN_SYSTEM 0 /* d11 open authentication */ -+#define DOT11_SHARED_KEY 1 /* d11 shared authentication */ -+#define DOT11_FAST_BSS 2 /* d11 fast bss authentication */ -+#define DOT11_CHALLENGE_LEN 128 /* d11 challenge text length */ -+ -+/* Frame control macros */ -+#define FC_PVER_MASK 0x3 /* PVER mask */ -+#define FC_PVER_SHIFT 0 /* PVER shift */ -+#define FC_TYPE_MASK 0xC /* type mask */ -+#define FC_TYPE_SHIFT 2 /* type shift */ -+#define FC_SUBTYPE_MASK 0xF0 /* subtype mask */ -+#define FC_SUBTYPE_SHIFT 4 /* subtype shift */ -+#define FC_TODS 0x100 /* to DS */ -+#define FC_TODS_SHIFT 8 /* to DS shift */ -+#define FC_FROMDS 0x200 /* from DS */ -+#define FC_FROMDS_SHIFT 9 /* from DS shift */ -+#define FC_MOREFRAG 0x400 /* more frag. */ -+#define FC_MOREFRAG_SHIFT 10 /* more frag. shift */ -+#define FC_RETRY 0x800 /* retry */ -+#define FC_RETRY_SHIFT 11 /* retry shift */ -+#define FC_PM 0x1000 /* PM */ -+#define FC_PM_SHIFT 12 /* PM shift */ -+#define FC_MOREDATA 0x2000 /* more data */ -+#define FC_MOREDATA_SHIFT 13 /* more data shift */ -+#define FC_WEP 0x4000 /* WEP */ -+#define FC_WEP_SHIFT 14 /* WEP shift */ -+#define FC_ORDER 0x8000 /* order */ -+#define FC_ORDER_SHIFT 15 /* order shift */ -+ -+/* sequence control macros */ -+#define SEQNUM_SHIFT 4 /* seq. number shift */ -+#define SEQNUM_MAX 0x1000 /* max seqnum + 1 */ -+#define FRAGNUM_MASK 0xF /* frag. number mask */ -+ -+/* Frame Control type/subtype defs */ -+ -+/* FC Types */ -+#define FC_TYPE_MNG 0 /* management type */ -+#define FC_TYPE_CTL 1 /* control type */ -+#define FC_TYPE_DATA 2 /* data type */ -+ -+/* Management Subtypes */ -+#define FC_SUBTYPE_ASSOC_REQ 0 /* assoc. request */ -+#define FC_SUBTYPE_ASSOC_RESP 1 /* assoc. response */ -+#define FC_SUBTYPE_REASSOC_REQ 2 /* reassoc. request */ -+#define FC_SUBTYPE_REASSOC_RESP 3 /* reassoc. response */ -+#define FC_SUBTYPE_PROBE_REQ 4 /* probe request */ -+#define FC_SUBTYPE_PROBE_RESP 5 /* probe response */ -+#define FC_SUBTYPE_BEACON 8 /* beacon */ -+#define FC_SUBTYPE_ATIM 9 /* ATIM */ -+#define FC_SUBTYPE_DISASSOC 10 /* disassoc. */ -+#define FC_SUBTYPE_AUTH 11 /* authentication */ -+#define FC_SUBTYPE_DEAUTH 12 /* de-authentication */ -+#define FC_SUBTYPE_ACTION 13 /* action */ -+#define FC_SUBTYPE_ACTION_NOACK 14 /* action no-ack */ -+ -+/* Control Subtypes */ -+#define FC_SUBTYPE_CTL_WRAPPER 7 /* Control Wrapper */ -+#define FC_SUBTYPE_BLOCKACK_REQ 8 /* Block Ack Req */ -+#define FC_SUBTYPE_BLOCKACK 9 /* Block Ack */ -+#define FC_SUBTYPE_PS_POLL 10 /* PS poll */ -+#define FC_SUBTYPE_RTS 11 /* RTS */ -+#define FC_SUBTYPE_CTS 12 /* CTS */ -+#define FC_SUBTYPE_ACK 13 /* ACK */ -+#define FC_SUBTYPE_CF_END 14 /* CF-END */ -+#define FC_SUBTYPE_CF_END_ACK 15 /* CF-END ACK */ -+ -+/* Data Subtypes */ -+#define FC_SUBTYPE_DATA 0 /* Data */ -+#define FC_SUBTYPE_DATA_CF_ACK 1 /* Data + CF-ACK */ -+#define FC_SUBTYPE_DATA_CF_POLL 2 /* Data + CF-Poll */ -+#define FC_SUBTYPE_DATA_CF_ACK_POLL 3 /* Data + CF-Ack + CF-Poll */ -+#define FC_SUBTYPE_NULL 4 /* Null */ -+#define FC_SUBTYPE_CF_ACK 5 /* CF-Ack */ -+#define FC_SUBTYPE_CF_POLL 6 /* CF-Poll */ -+#define FC_SUBTYPE_CF_ACK_POLL 7 /* CF-Ack + CF-Poll */ -+#define FC_SUBTYPE_QOS_DATA 8 /* QoS Data */ -+#define FC_SUBTYPE_QOS_DATA_CF_ACK 9 /* QoS Data + CF-Ack */ -+#define FC_SUBTYPE_QOS_DATA_CF_POLL 10 /* QoS Data + CF-Poll */ -+#define FC_SUBTYPE_QOS_DATA_CF_ACK_POLL 11 /* QoS Data + CF-Ack + CF-Poll */ -+#define FC_SUBTYPE_QOS_NULL 12 /* QoS Null */ -+#define FC_SUBTYPE_QOS_CF_POLL 14 /* QoS CF-Poll */ -+#define FC_SUBTYPE_QOS_CF_ACK_POLL 15 /* QoS CF-Ack + CF-Poll */ -+ -+/* Data Subtype Groups */ -+#define FC_SUBTYPE_ANY_QOS(s) (((s) & 8) != 0) -+#define FC_SUBTYPE_ANY_NULL(s) (((s) & 4) != 0) -+#define FC_SUBTYPE_ANY_CF_POLL(s) (((s) & 2) != 0) -+#define FC_SUBTYPE_ANY_CF_ACK(s) (((s) & 1) != 0) -+ -+/* Type/Subtype Combos */ -+#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) /* FC kind mask */ -+ -+#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) /* FC kind */ -+ -+#define FC_SUBTYPE(fc) (((fc) & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT) /* Subtype from FC */ -+#define FC_TYPE(fc) (((fc) & FC_TYPE_MASK) >> FC_TYPE_SHIFT) /* Type from FC */ -+ -+#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ) /* assoc. request */ -+#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP) /* assoc. response */ -+#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ) /* reassoc. request */ -+#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP) /* reassoc. response */ -+#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) /* probe request */ -+#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) /* probe response */ -+#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) /* beacon */ -+#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC) /* disassoc */ -+#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH) /* authentication */ -+#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH) /* deauthentication */ -+#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION) /* action */ -+#define FC_ACTION_NOACK FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION_NOACK) /* action no-ack */ -+ -+#define FC_CTL_WRAPPER FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTL_WRAPPER) /* Control Wrapper */ -+#define FC_BLOCKACK_REQ FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK_REQ) /* Block Ack Req */ -+#define FC_BLOCKACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK) /* Block Ack */ -+#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) /* PS poll */ -+#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) /* RTS */ -+#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) /* CTS */ -+#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK) /* ACK */ -+#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END) /* CF-END */ -+#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK) /* CF-END ACK */ -+ -+#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA) /* data */ -+#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL) /* null data */ -+#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK) /* data CF ACK */ -+#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA) /* QoS data */ -+#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL) /* QoS null */ -+ -+/* QoS Control Field */ -+ -+/* 802.1D Priority */ -+#define QOS_PRIO_SHIFT 0 /* QoS priority shift */ -+#define QOS_PRIO_MASK 0x0007 /* QoS priority mask */ -+#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT) /* QoS priority */ -+ -+/* Traffic Identifier */ -+#define QOS_TID_SHIFT 0 /* QoS TID shift */ -+#define QOS_TID_MASK 0x000f /* QoS TID mask */ -+#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT) /* QoS TID */ -+ -+/* End of Service Period (U-APSD) */ -+#define QOS_EOSP_SHIFT 4 /* QoS End of Service Period shift */ -+#define QOS_EOSP_MASK 0x0010 /* QoS End of Service Period mask */ -+#define QOS_EOSP(qos) (((qos) & QOS_EOSP_MASK) >> QOS_EOSP_SHIFT) /* Qos EOSP */ -+ -+/* Ack Policy */ -+#define QOS_ACK_NORMAL_ACK 0 /* Normal Ack */ -+#define QOS_ACK_NO_ACK 1 /* No Ack (eg mcast) */ -+#define QOS_ACK_NO_EXP_ACK 2 /* No Explicit Ack */ -+#define QOS_ACK_BLOCK_ACK 3 /* Block Ack */ -+#define QOS_ACK_SHIFT 5 /* QoS ACK shift */ -+#define QOS_ACK_MASK 0x0060 /* QoS ACK mask */ -+#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT) /* QoS ACK */ -+ -+/* A-MSDU flag */ -+#define QOS_AMSDU_SHIFT 7 /* AMSDU shift */ -+#define QOS_AMSDU_MASK 0x0080 /* AMSDU mask */ -+ -+/* Management Frames */ -+ -+/* Management Frame Constants */ -+ -+/* Fixed fields */ -+#define DOT11_MNG_AUTH_ALGO_LEN 2 /* d11 management auth. algo. length */ -+#define DOT11_MNG_AUTH_SEQ_LEN 2 /* d11 management auth. seq. length */ -+#define DOT11_MNG_BEACON_INT_LEN 2 /* d11 management beacon interval length */ -+#define DOT11_MNG_CAP_LEN 2 /* d11 management cap. length */ -+#define DOT11_MNG_AP_ADDR_LEN 6 /* d11 management AP address length */ -+#define DOT11_MNG_LISTEN_INT_LEN 2 /* d11 management listen interval length */ -+#define DOT11_MNG_REASON_LEN 2 /* d11 management reason length */ -+#define DOT11_MNG_AID_LEN 2 /* d11 management AID length */ -+#define DOT11_MNG_STATUS_LEN 2 /* d11 management status length */ -+#define DOT11_MNG_TIMESTAMP_LEN 8 /* d11 management timestamp length */ -+ -+/* DUR/ID field in assoc resp is 0xc000 | AID */ -+#define DOT11_AID_MASK 0x3fff /* d11 AID mask */ -+ -+/* Reason Codes */ -+#define DOT11_RC_RESERVED 0 /* d11 RC reserved */ -+#define DOT11_RC_UNSPECIFIED 1 /* Unspecified reason */ -+#define DOT11_RC_AUTH_INVAL 2 /* Previous authentication no longer valid */ -+#define DOT11_RC_DEAUTH_LEAVING 3 /* Deauthenticated because sending station -+ * is leaving (or has left) IBSS or ESS -+ */ -+#define DOT11_RC_INACTIVITY 4 /* Disassociated due to inactivity */ -+#define DOT11_RC_BUSY 5 /* Disassociated because AP is unable to handle -+ * all currently associated stations -+ */ -+#define DOT11_RC_INVAL_CLASS_2 6 /* Class 2 frame received from -+ * nonauthenticated station -+ */ -+#define DOT11_RC_INVAL_CLASS_3 7 /* Class 3 frame received from -+ * nonassociated station -+ */ -+#define DOT11_RC_DISASSOC_LEAVING 8 /* Disassociated because sending station is -+ * leaving (or has left) BSS -+ */ -+#define DOT11_RC_NOT_AUTH 9 /* Station requesting (re)association is not -+ * authenticated with responding station -+ */ -+#define DOT11_RC_BAD_PC 10 /* Unacceptable power capability element */ -+#define DOT11_RC_BAD_CHANNELS 11 /* Unacceptable supported channels element */ -+/* 12 is unused */ -+ -+/* 32-39 are QSTA specific reasons added in 11e */ -+#define DOT11_RC_UNSPECIFIED_QOS 32 /* unspecified QoS-related reason */ -+#define DOT11_RC_INSUFFCIENT_BW 33 /* QAP lacks sufficient bandwidth */ -+#define DOT11_RC_EXCESSIVE_FRAMES 34 /* excessive number of frames need ack */ -+#define DOT11_RC_TX_OUTSIDE_TXOP 35 /* transmitting outside the limits of txop */ -+#define DOT11_RC_LEAVING_QBSS 36 /* QSTA is leaving the QBSS (or restting) */ -+#define DOT11_RC_BAD_MECHANISM 37 /* does not want to use the mechanism */ -+#define DOT11_RC_SETUP_NEEDED 38 /* mechanism needs a setup */ -+#define DOT11_RC_TIMEOUT 39 /* timeout */ -+ -+#define DOT11_RC_MAX 23 /* Reason codes > 23 are reserved */ -+ -+#define DOT11_RC_TDLS_PEER_UNREACH 25 -+#define DOT11_RC_TDLS_DOWN_UNSPECIFIED 26 -+ -+/* Status Codes */ -+#define DOT11_SC_SUCCESS 0 /* Successful */ -+#define DOT11_SC_FAILURE 1 /* Unspecified failure */ -+#define DOT11_SC_TDLS_WAKEUP_SCH_ALT 2 /* TDLS wakeup schedule rejected but alternative */ -+ /* schedule provided */ -+#define DOT11_SC_TDLS_WAKEUP_SCH_REJ 3 /* TDLS wakeup schedule rejected */ -+#define DOT11_SC_TDLS_SEC_DISABLED 5 /* TDLS Security disabled */ -+#define DOT11_SC_LIFETIME_REJ 6 /* Unacceptable lifetime */ -+#define DOT11_SC_NOT_SAME_BSS 7 /* Not in same BSS */ -+#define DOT11_SC_CAP_MISMATCH 10 /* Cannot support all requested -+ * capabilities in the Capability -+ * Information field -+ */ -+#define DOT11_SC_REASSOC_FAIL 11 /* Reassociation denied due to inability -+ * to confirm that association exists -+ */ -+#define DOT11_SC_ASSOC_FAIL 12 /* Association denied due to reason -+ * outside the scope of this standard -+ */ -+#define DOT11_SC_AUTH_MISMATCH 13 /* Responding station does not support -+ * the specified authentication -+ * algorithm -+ */ -+#define DOT11_SC_AUTH_SEQ 14 /* Received an Authentication frame -+ * with authentication transaction -+ * sequence number out of expected -+ * sequence -+ */ -+#define DOT11_SC_AUTH_CHALLENGE_FAIL 15 /* Authentication rejected because of -+ * challenge failure -+ */ -+#define DOT11_SC_AUTH_TIMEOUT 16 /* Authentication rejected due to timeout -+ * waiting for next frame in sequence -+ */ -+#define DOT11_SC_ASSOC_BUSY_FAIL 17 /* Association denied because AP is -+ * unable to handle additional -+ * associated stations -+ */ -+#define DOT11_SC_ASSOC_RATE_MISMATCH 18 /* Association denied due to requesting -+ * station not supporting all of the -+ * data rates in the BSSBasicRateSet -+ * parameter -+ */ -+#define DOT11_SC_ASSOC_SHORT_REQUIRED 19 /* Association denied due to requesting -+ * station not supporting the Short -+ * Preamble option -+ */ -+#define DOT11_SC_ASSOC_PBCC_REQUIRED 20 /* Association denied due to requesting -+ * station not supporting the PBCC -+ * Modulation option -+ */ -+#define DOT11_SC_ASSOC_AGILITY_REQUIRED 21 /* Association denied due to requesting -+ * station not supporting the Channel -+ * Agility option -+ */ -+#define DOT11_SC_ASSOC_SPECTRUM_REQUIRED 22 /* Association denied because Spectrum -+ * Management capability is required. -+ */ -+#define DOT11_SC_ASSOC_BAD_POWER_CAP 23 /* Association denied because the info -+ * in the Power Cap element is -+ * unacceptable. -+ */ -+#define DOT11_SC_ASSOC_BAD_SUP_CHANNELS 24 /* Association denied because the info -+ * in the Supported Channel element is -+ * unacceptable -+ */ -+#define DOT11_SC_ASSOC_SHORTSLOT_REQUIRED 25 /* Association denied due to requesting -+ * station not supporting the Short Slot -+ * Time option -+ */ -+#define DOT11_SC_ASSOC_ERPBCC_REQUIRED 26 /* Association denied due to requesting -+ * station not supporting the ER-PBCC -+ * Modulation option -+ */ -+#define DOT11_SC_ASSOC_DSSOFDM_REQUIRED 27 /* Association denied due to requesting -+ * station not supporting the DSS-OFDM -+ * option -+ */ -+#define DOT11_SC_ASSOC_R0KH_UNREACHABLE 28 /* Association denied due to AP -+ * being unable to reach the R0 Key Holder -+ */ -+#define DOT11_SC_ASSOC_TRY_LATER 30 /* Association denied temporarily, try again later -+ */ -+#define DOT11_SC_ASSOC_MFP_VIOLATION 31 /* Association denied due to Robust Management -+ * frame policy violation -+ */ -+ -+#define DOT11_SC_DECLINED 37 /* request declined */ -+#define DOT11_SC_INVALID_PARAMS 38 /* One or more params have invalid values */ -+#define DOT11_SC_INVALID_PAIRWISE_CIPHER 42 /* invalid pairwise cipher */ -+#define DOT11_SC_INVALID_AKMP 43 /* Association denied due to invalid AKMP */ -+#define DOT11_SC_INVALID_RSNIE_CAP 45 /* invalid RSN IE capabilities */ -+#define DOT11_SC_DLS_NOT_ALLOWED 48 /* DLS is not allowed in the BSS by policy */ -+#define DOT11_SC_INVALID_PMKID 53 /* Association denied due to invalid PMKID */ -+#define DOT11_SC_INVALID_MDID 54 /* Association denied due to invalid MDID */ -+#define DOT11_SC_INVALID_FTIE 55 /* Association denied due to invalid FTIE */ -+ -+#define DOT11_SC_UNEXP_MSG 70 /* Unexpected message */ -+#define DOT11_SC_INVALID_SNONCE 71 /* Invalid SNonce */ -+#define DOT11_SC_INVALID_RSNIE 72 /* Invalid contents of RSNIE */ -+ -+/* Info Elts, length of INFORMATION portion of Info Elts */ -+#define DOT11_MNG_DS_PARAM_LEN 1 /* d11 management DS parameter length */ -+#define DOT11_MNG_IBSS_PARAM_LEN 2 /* d11 management IBSS parameter length */ -+ -+/* TIM Info element has 3 bytes fixed info in INFORMATION field, -+ * followed by 1 to 251 bytes of Partial Virtual Bitmap -+ */ -+#define DOT11_MNG_TIM_FIXED_LEN 3 /* d11 management TIM fixed length */ -+#define DOT11_MNG_TIM_DTIM_COUNT 0 /* d11 management DTIM count */ -+#define DOT11_MNG_TIM_DTIM_PERIOD 1 /* d11 management DTIM period */ -+#define DOT11_MNG_TIM_BITMAP_CTL 2 /* d11 management TIM BITMAP control */ -+#define DOT11_MNG_TIM_PVB 3 /* d11 management TIM PVB */ -+ -+/* TLV defines */ -+#define TLV_TAG_OFF 0 /* tag offset */ -+#define TLV_LEN_OFF 1 /* length offset */ -+#define TLV_HDR_LEN 2 /* header length */ -+#define TLV_BODY_OFF 2 /* body offset */ -+ -+/* Management Frame Information Element IDs */ -+#define DOT11_MNG_SSID_ID 0 /* d11 management SSID id */ -+#define DOT11_MNG_RATES_ID 1 /* d11 management rates id */ -+#define DOT11_MNG_FH_PARMS_ID 2 /* d11 management FH parameter id */ -+#define DOT11_MNG_DS_PARMS_ID 3 /* d11 management DS parameter id */ -+#define DOT11_MNG_CF_PARMS_ID 4 /* d11 management CF parameter id */ -+#define DOT11_MNG_TIM_ID 5 /* d11 management TIM id */ -+#define DOT11_MNG_IBSS_PARMS_ID 6 /* d11 management IBSS parameter id */ -+#define DOT11_MNG_COUNTRY_ID 7 /* d11 management country id */ -+#define DOT11_MNG_HOPPING_PARMS_ID 8 /* d11 management hopping parameter id */ -+#define DOT11_MNG_HOPPING_TABLE_ID 9 /* d11 management hopping table id */ -+#define DOT11_MNG_REQUEST_ID 10 /* d11 management request id */ -+#define DOT11_MNG_QBSS_LOAD_ID 11 /* d11 management QBSS Load id */ -+#define DOT11_MNG_EDCA_PARAM_ID 12 /* 11E EDCA Parameter id */ -+#define DOT11_MNG_CHALLENGE_ID 16 /* d11 management chanllenge id */ -+#define DOT11_MNG_PWR_CONSTRAINT_ID 32 /* 11H PowerConstraint */ -+#define DOT11_MNG_PWR_CAP_ID 33 /* 11H PowerCapability */ -+#define DOT11_MNG_TPC_REQUEST_ID 34 /* 11H TPC Request */ -+#define DOT11_MNG_TPC_REPORT_ID 35 /* 11H TPC Report */ -+#define DOT11_MNG_SUPP_CHANNELS_ID 36 /* 11H Supported Channels */ -+#define DOT11_MNG_CHANNEL_SWITCH_ID 37 /* 11H ChannelSwitch Announcement */ -+#define DOT11_MNG_MEASURE_REQUEST_ID 38 /* 11H MeasurementRequest */ -+#define DOT11_MNG_MEASURE_REPORT_ID 39 /* 11H MeasurementReport */ -+#define DOT11_MNG_QUIET_ID 40 /* 11H Quiet */ -+#define DOT11_MNG_IBSS_DFS_ID 41 /* 11H IBSS_DFS */ -+#define DOT11_MNG_ERP_ID 42 /* d11 management ERP id */ -+#define DOT11_MNG_TS_DELAY_ID 43 /* d11 management TS Delay id */ -+#define DOT11_MNG_HT_CAP 45 /* d11 mgmt HT cap id */ -+#define DOT11_MNG_QOS_CAP_ID 46 /* 11E QoS Capability id */ -+#define DOT11_MNG_NONERP_ID 47 /* d11 management NON-ERP id */ -+#define DOT11_MNG_RSN_ID 48 /* d11 management RSN id */ -+#define DOT11_MNG_EXT_RATES_ID 50 /* d11 management ext. rates id */ -+#define DOT11_MNG_AP_CHREP_ID 51 /* 11k AP Channel report id */ -+#define DOT11_MNG_NBR_REP_ID 52 /* 11k Neighbor report id */ -+#define DOT11_MNG_MDIE_ID 54 /* 11r Mobility domain id */ -+#define DOT11_MNG_FTIE_ID 55 /* 11r Fast Bss Transition id */ -+#define DOT11_MNG_FT_TI_ID 56 /* 11r Timeout Interval id */ -+#define DOT11_MNG_REGCLASS_ID 59 /* d11 management regulatory class id */ -+#define DOT11_MNG_EXT_CSA_ID 60 /* d11 Extended CSA */ -+#define DOT11_MNG_HT_ADD 61 /* d11 mgmt additional HT info */ -+#define DOT11_MNG_EXT_CHANNEL_OFFSET 62 /* d11 mgmt ext channel offset */ -+#define DOT11_MNG_WAPI_ID 68 /* d11 management WAPI id */ -+#define DOT11_MNG_TIME_ADVERTISE_ID 69 /* 11p time advertisement */ -+#define DOT11_MNG_RRM_CAP_ID 70 /* 11k radio measurement capability */ -+#define DOT11_MNG_HT_BSS_COEXINFO_ID 72 /* d11 mgmt OBSS Coexistence INFO */ -+#define DOT11_MNG_HT_BSS_CHANNEL_REPORT_ID 73 /* d11 mgmt OBSS Intolerant Channel list */ -+#define DOT11_MNG_HT_OBSS_ID 74 /* d11 mgmt OBSS HT info */ -+#define DOT11_MNG_CHANNEL_USAGE 97 /* 11v channel usage */ -+#define DOT11_MNG_TIME_ZONE_ID 98 /* 11v time zone */ -+#define DOT11_MNG_LINK_IDENTIFIER_ID 101 /* 11z TDLS Link Identifier IE */ -+#define DOT11_MNG_WAKEUP_SCHEDULE_ID 102 /* 11z TDLS Wakeup Schedule IE */ -+#define DOT11_MNG_CHANNEL_SWITCH_TIMING_ID 104 /* 11z TDLS Channel Switch Timing IE */ -+#define DOT11_MNG_PTI_CONTROL_ID 105 /* 11z TDLS PTI Control IE */ -+#define DOT11_MNG_PU_BUFFER_STATUS_ID 106 /* 11z TDLS PU Buffer Status IE */ -+#define DOT11_MNG_INTERWORKING_ID 107 /* 11u interworking */ -+#define DOT11_MNG_ADVERTISEMENT_ID 108 /* 11u advertisement protocol */ -+#define DOT11_MNG_EXP_BW_REQ_ID 109 /* 11u expedited bandwith request */ -+#define DOT11_MNG_QOS_MAP_ID 110 /* 11u QoS map set */ -+#define DOT11_MNG_ROAM_CONSORT_ID 111 /* 11u roaming consortium */ -+#define DOT11_MNG_EMERGCY_ALERT_ID 112 /* 11u emergency alert identifier */ -+#define DOT11_MNG_EXT_CAP_ID 127 /* d11 mgmt ext capability */ -+#define DOT11_MNG_VHT_CAP_ID 191 /* d11 mgmt VHT cap id */ -+#define DOT11_MNG_VHT_OPERATION_ID 192 /* d11 mgmt VHT op id */ -+ -+#define DOT11_MNG_WPA_ID 221 /* d11 management WPA id */ -+#define DOT11_MNG_PROPR_ID 221 /* d11 management proprietary id */ -+/* should start using this one instead of above two */ -+#define DOT11_MNG_VS_ID 221 /* d11 management Vendor Specific IE */ -+ -+/* Rate element Basic flag and rate mask */ -+#define DOT11_RATE_BASIC 0x80 /* flag for a Basic Rate */ -+#define DOT11_RATE_MASK 0x7F /* mask for numeric part of rate */ -+ -+/* ERP info element bit values */ -+#define DOT11_MNG_ERP_LEN 1 /* ERP is currently 1 byte long */ -+#define DOT11_MNG_NONERP_PRESENT 0x01 /* NonERP (802.11b) STAs are present -+ *in the BSS -+ */ -+#define DOT11_MNG_USE_PROTECTION 0x02 /* Use protection mechanisms for -+ *ERP-OFDM frames -+ */ -+#define DOT11_MNG_BARKER_PREAMBLE 0x04 /* Short Preambles: 0 == allowed, -+ * 1 == not allowed -+ */ -+/* TS Delay element offset & size */ -+#define DOT11_MGN_TS_DELAY_LEN 4 /* length of TS DELAY IE */ -+#define TS_DELAY_FIELD_SIZE 4 /* TS DELAY field size */ -+ -+/* Capability Information Field */ -+#define DOT11_CAP_ESS 0x0001 /* d11 cap. ESS */ -+#define DOT11_CAP_IBSS 0x0002 /* d11 cap. IBSS */ -+#define DOT11_CAP_POLLABLE 0x0004 /* d11 cap. pollable */ -+#define DOT11_CAP_POLL_RQ 0x0008 /* d11 cap. poll request */ -+#define DOT11_CAP_PRIVACY 0x0010 /* d11 cap. privacy */ -+#define DOT11_CAP_SHORT 0x0020 /* d11 cap. short */ -+#define DOT11_CAP_PBCC 0x0040 /* d11 cap. PBCC */ -+#define DOT11_CAP_AGILITY 0x0080 /* d11 cap. agility */ -+#define DOT11_CAP_SPECTRUM 0x0100 /* d11 cap. spectrum */ -+#define DOT11_CAP_SHORTSLOT 0x0400 /* d11 cap. shortslot */ -+#define DOT11_CAP_RRM 0x1000 /* d11 cap. 11k radio measurement */ -+#define DOT11_CAP_CCK_OFDM 0x2000 /* d11 cap. CCK/OFDM */ -+ -+/* Extended capabilities IE bitfields */ -+/* 20/40 BSS Coexistence Management support bit position */ -+#define DOT11_EXT_CAP_OBSS_COEX_MGMT 0 -+/* scheduled PSMP support bit position */ -+#define DOT11_EXT_CAP_SPSMP 6 -+/* BSS Transition Management support bit position */ -+#define DOT11_EXT_CAP_BSS_TRANSITION_MGMT 19 -+/* Interworking support bit position */ -+#define DOT11_EXT_CAP_IW 31 -+/* service Interval granularity bit position and mask */ -+#define DOT11_EXT_CAP_SI 41 -+#define DOT11_EXT_CAP_SI_MASK 0x0E -+ -+/* -+ * Action Frame Constants -+ */ -+#define DOT11_ACTION_HDR_LEN 2 /* action frame category + action field */ -+#define DOT11_ACTION_CAT_OFF 0 /* category offset */ -+#define DOT11_ACTION_ACT_OFF 1 /* action offset */ -+ -+/* Action Category field (sec 7.3.1.11) */ -+#define DOT11_ACTION_CAT_ERR_MASK 0x80 /* category error mask */ -+#define DOT11_ACTION_CAT_MASK 0x7F /* category mask */ -+#define DOT11_ACTION_CAT_SPECT_MNG 0 /* category spectrum management */ -+#define DOT11_ACTION_CAT_QOS 1 /* category QoS */ -+#define DOT11_ACTION_CAT_DLS 2 /* category DLS */ -+#define DOT11_ACTION_CAT_BLOCKACK 3 /* category block ack */ -+#define DOT11_ACTION_CAT_PUBLIC 4 /* category public */ -+#define DOT11_ACTION_CAT_RRM 5 /* category radio measurements */ -+#define DOT11_ACTION_CAT_FBT 6 /* category fast bss transition */ -+#define DOT11_ACTION_CAT_HT 7 /* category for HT */ -+#define DOT11_ACTION_CAT_SA_QUERY 8 /* security association query */ -+#define DOT11_ACTION_CAT_PDPA 9 /* protected dual of public action */ -+#define DOT11_ACTION_CAT_BSSMGMT 10 /* category for BSS transition management */ -+#define DOT11_ACTION_NOTIFICATION 17 -+#define DOT11_ACTION_CAT_VSP 126 /* protected vendor specific */ -+#define DOT11_ACTION_CAT_VS 127 /* category Vendor Specific */ -+ -+/* Spectrum Management Action IDs (sec 7.4.1) */ -+#define DOT11_SM_ACTION_M_REQ 0 /* d11 action measurement request */ -+#define DOT11_SM_ACTION_M_REP 1 /* d11 action measurement response */ -+#define DOT11_SM_ACTION_TPC_REQ 2 /* d11 action TPC request */ -+#define DOT11_SM_ACTION_TPC_REP 3 /* d11 action TPC response */ -+#define DOT11_SM_ACTION_CHANNEL_SWITCH 4 /* d11 action channel switch */ -+#define DOT11_SM_ACTION_EXT_CSA 5 /* d11 extened CSA for 11n */ -+ -+/* HT action ids */ -+#define DOT11_ACTION_ID_HT_CH_WIDTH 0 /* notify channel width action id */ -+#define DOT11_ACTION_ID_HT_MIMO_PS 1 /* mimo ps action id */ -+ -+/* Public action ids */ -+#define DOT11_PUB_ACTION_BSS_COEX_MNG 0 /* 20/40 Coexistence Management action id */ -+#define DOT11_PUB_ACTION_CHANNEL_SWITCH 4 /* d11 action channel switch */ -+ -+/* Block Ack action types */ -+#define DOT11_BA_ACTION_ADDBA_REQ 0 /* ADDBA Req action frame type */ -+#define DOT11_BA_ACTION_ADDBA_RESP 1 /* ADDBA Resp action frame type */ -+#define DOT11_BA_ACTION_DELBA 2 /* DELBA action frame type */ -+ -+/* ADDBA action parameters */ -+#define DOT11_ADDBA_PARAM_AMSDU_SUP 0x0001 /* AMSDU supported under BA */ -+#define DOT11_ADDBA_PARAM_POLICY_MASK 0x0002 /* policy mask(ack vs delayed) */ -+#define DOT11_ADDBA_PARAM_POLICY_SHIFT 1 /* policy shift */ -+#define DOT11_ADDBA_PARAM_TID_MASK 0x003c /* tid mask */ -+#define DOT11_ADDBA_PARAM_TID_SHIFT 2 /* tid shift */ -+#define DOT11_ADDBA_PARAM_BSIZE_MASK 0xffc0 /* buffer size mask */ -+#define DOT11_ADDBA_PARAM_BSIZE_SHIFT 6 /* buffer size shift */ -+ -+#define DOT11_ADDBA_POLICY_DELAYED 0 /* delayed BA policy */ -+#define DOT11_ADDBA_POLICY_IMMEDIATE 1 /* immediate BA policy */ -+ -+/* Fast Transition action types */ -+#define DOT11_FT_ACTION_FT_RESERVED 0 -+#define DOT11_FT_ACTION_FT_REQ 1 /* FBT request - for over-the-DS FBT */ -+#define DOT11_FT_ACTION_FT_RES 2 /* FBT response - for over-the-DS FBT */ -+#define DOT11_FT_ACTION_FT_CON 3 /* FBT confirm - for OTDS with RRP */ -+#define DOT11_FT_ACTION_FT_ACK 4 /* FBT ack */ -+ -+/* DLS action types */ -+#define DOT11_DLS_ACTION_REQ 0 /* DLS Request */ -+#define DOT11_DLS_ACTION_RESP 1 /* DLS Response */ -+#define DOT11_DLS_ACTION_TD 2 /* DLS Teardown */ -+ -+/* Wireless Network Management (WNM) action types */ -+#define DOT11_WNM_ACTION_EVENT_REQ 0 -+#define DOT11_WNM_ACTION_EVENT_REP 1 -+#define DOT11_WNM_ACTION_DIAG_REQ 2 -+#define DOT11_WNM_ACTION_DIAG_REP 3 -+#define DOT11_WNM_ACTION_LOC_CFG_REQ 4 -+#define DOT11_WNM_ACTION_LOC_RFG_RESP 5 -+#define DOT11_WNM_ACTION_BSS_TRANS_QURY 6 -+#define DOT11_WNM_ACTION_BSS_TRANS_REQ 7 -+#define DOT11_WNM_ACTION_BSS_TRANS_RESP 8 -+#define DOT11_WNM_ACTION_FMS_REQ 9 -+#define DOT11_WNM_ACTION_FMS_RESP 10 -+#define DOT11_WNM_ACTION_COL_INTRFRNCE_REQ 11 -+#define DOT11_WNM_ACTION_COL_INTRFRNCE_REP 12 -+#define DOT11_WNM_ACTION_TFS_REQ 13 -+#define DOT11_WNM_ACTION_TFS_RESP 14 -+#define DOT11_WNM_ACTION_TFS_NOTIFY 15 -+#define DOT11_WNM_ACTION_WNM_SLEEP_REQ 16 -+#define DOT11_WNM_ACTION_WNM_SLEEP_RESP 17 -+#define DOT11_WNM_ACTION_TIM_BCAST_REQ 18 -+#define DOT11_WNM_ACTION_TIM_BCAST_RESP 19 -+#define DOT11_WNM_ACTION_QOS_TRFC_CAP_UPD 20 -+#define DOT11_WNM_ACTION_CHAN_USAGE_REQ 21 -+#define DOT11_WNM_ACTION_CHAN_USAGE_RESP 22 -+#define DOT11_WNM_ACTION_DMS_REQ 23 -+#define DOT11_WNM_ACTION_DMS_RESP 24 -+#define DOT11_WNM_ACTION_TMNG_MEASUR_REQ 25 -+#define DOT11_WNM_ACTION_NOTFCTN_REQ 26 -+#define DOT11_WNM_ACTION_NOTFCTN_RES 27 -+ -+#define DOT11_MNG_COUNTRY_ID_LEN 3 -+ -+/* DLS Request frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_dls_req { -+ uint8 category; /* category of action frame (2) */ -+ uint8 action; /* DLS action: req (0) */ -+ struct ether_addr da; /* destination address */ -+ struct ether_addr sa; /* source address */ -+ uint16 cap; /* capability */ -+ uint16 timeout; /* timeout value */ -+ uint8 data[1]; /* IE:support rate, extend support rate, HT cap */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_dls_req dot11_dls_req_t; -+#define DOT11_DLS_REQ_LEN 18 /* Fixed length */ -+ -+/* DLS response frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_dls_resp { -+ uint8 category; /* category of action frame (2) */ -+ uint8 action; /* DLS action: req (0) */ -+ uint16 status; /* status code field */ -+ struct ether_addr da; /* destination address */ -+ struct ether_addr sa; /* source address */ -+ uint8 data[1]; /* optional: capability, rate ... */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_dls_resp dot11_dls_resp_t; -+#define DOT11_DLS_RESP_LEN 16 /* Fixed length */ -+ -+ -+/* BSS Management Transition Query frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_query { -+ uint8 category; /* category of action frame (10) */ -+ uint8 action; /* WNM action: trans_query (6) */ -+ uint8 token; /* dialog token */ -+ uint8 reason; /* transition query reason */ -+ uint8 data[1]; /* Elements */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_bss_trans_query dot11_bss_trans_query_t; -+#define DOT11_BSS_TRANS_QUERY_LEN 4 /* Fixed length */ -+ -+/* BSS Management Transition Request frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_req { -+ uint8 category; /* category of action frame (10) */ -+ uint8 action; /* WNM action: trans_req (7) */ -+ uint8 token; /* dialog token */ -+ uint8 reqmode; /* transition request mode */ -+ uint16 disassoc_tmr; /* disassociation timer */ -+ uint8 validity_intrvl; /* validity interval */ -+ uint8 data[1]; /* optional: BSS term duration, ... */ -+ /* ...session info URL, list */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_bss_trans_req dot11_bss_trans_req_t; -+#define DOT11_BSS_TRANS_REQ_LEN 7 /* Fixed length */ -+ -+#define DOT11_BSS_TERM_DUR_LEN 12 /* Fixed length if present */ -+ -+ -+/* BSS Mgmt Transition Request Mode Field - 802.11v */ -+#define DOT11_BSS_TRNS_REQMODE_PREF_LIST_INCL 0x01 -+#define DOT11_BSS_TRNS_REQMODE_ABRIDGED 0x02 -+#define DOT11_BSS_TRNS_REQMODE_DISASSOC_IMMINENT 0x04 -+#define DOT11_BSS_TRNS_REQMODE_BSS_TERM_INCL 0x08 -+#define DOT11_BSS_TRNS_REQMODE_ESS_DISASSOC_IMNT 0x10 -+ -+ -+/* BSS Management transition response frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_res { -+ uint8 category; /* category of action frame (10) */ -+ uint8 action; /* WNM action: trans_res (8) */ -+ uint8 token; /* dialog token */ -+ uint8 status; /* transition status */ -+ uint8 term_delay; /* validity interval */ -+ uint8 data[1]; /* optional: BSS term duration, ... */ -+ /* ...session info URL, list */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_bss_trans_res dot11_bss_trans_res_t; -+#define DOT11_BSS_TRANS_RES_LEN 5 /* Fixed length */ -+ -+/* BSS Mgmt Transition Response Status Field */ -+#define DOT11_BSS_TRNS_RES_STATUS_ACCEPT 0 -+#define DOT11_BSS_TRNS_RES_STATUS_REJECT 1 -+#define DOT11_BSS_TRNS_RES_STATUS_REJ_INSUFF_BCN 2 -+#define DOT11_BSS_TRNS_RES_STATUS_REJ_INSUFF_CAP 3 -+#define DOT11_BSS_TRNS_RES_STATUS_REJ_TERM_UNDESIRED 4 -+#define DOT11_BSS_TRNS_RES_STATUS_REJ_TERM_DELAY_REQ 5 -+#define DOT11_BSS_TRNS_RES_STATUS_REJ_BSS_LIST_PROVIDED 6 -+#define DOT11_BSS_TRNS_RES_STATUS_REJ_NO_SUITABLE_BSS 7 -+#define DOT11_BSS_TRNS_RES_STATUS_REJ_LEAVING_ESS 8 -+ -+ -+/* Neighbor Report BSSID Information Field */ -+#define DOT11_NBR_RPRT_BSSID_INFO_REACHABILTY 0x0003 -+#define DOT11_NBR_RPRT_BSSID_INFO_SEC 0x0004 -+#define DOT11_NBR_RPRT_BSSID_INFO_KEY_SCOPE 0x0008 -+#define DOT11_NBR_RPRT_BSSID_INFO_CAP 0x03f0 -+ -+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_SPEC_MGMT 0x0010 -+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_QOS 0x0020 -+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_APSD 0x0040 -+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_RDIO_MSMT 0x0080 -+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_DEL_BA 0x0100 -+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_IMM_BA 0x0200 -+ -+/* Neighbor Report Subelements */ -+#define DOT11_NBR_RPRT_SUBELEM_BSS_CANDDT_PREF_ID 3 -+ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_addba_req { -+ uint8 category; /* category of action frame (3) */ -+ uint8 action; /* action: addba req */ -+ uint8 token; /* identifier */ -+ uint16 addba_param_set; /* parameter set */ -+ uint16 timeout; /* timeout in seconds */ -+ uint16 start_seqnum; /* starting sequence number */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_addba_req dot11_addba_req_t; -+#define DOT11_ADDBA_REQ_LEN 9 /* length of addba req frame */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_addba_resp { -+ uint8 category; /* category of action frame (3) */ -+ uint8 action; /* action: addba resp */ -+ uint8 token; /* identifier */ -+ uint16 status; /* status of add request */ -+ uint16 addba_param_set; /* negotiated parameter set */ -+ uint16 timeout; /* negotiated timeout in seconds */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_addba_resp dot11_addba_resp_t; -+#define DOT11_ADDBA_RESP_LEN 9 /* length of addba resp frame */ -+ -+/* DELBA action parameters */ -+#define DOT11_DELBA_PARAM_INIT_MASK 0x0800 /* initiator mask */ -+#define DOT11_DELBA_PARAM_INIT_SHIFT 11 /* initiator shift */ -+#define DOT11_DELBA_PARAM_TID_MASK 0xf000 /* tid mask */ -+#define DOT11_DELBA_PARAM_TID_SHIFT 12 /* tid shift */ -+ -+BWL_PRE_PACKED_STRUCT struct dot11_delba { -+ uint8 category; /* category of action frame (3) */ -+ uint8 action; /* action: addba req */ -+ uint16 delba_param_set; /* paarmeter set */ -+ uint16 reason; /* reason for dellba */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_delba dot11_delba_t; -+#define DOT11_DELBA_LEN 6 /* length of delba frame */ -+ -+/* SA Query action field value */ -+#define SA_QUERY_REQUEST 0 -+#define SA_QUERY_RESPONSE 1 -+ -+/* ************* 802.11r related definitions. ************* */ -+ -+/* Over-the-DS Fast Transition Request frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_ft_req { -+ uint8 category; /* category of action frame (6) */ -+ uint8 action; /* action: ft req */ -+ uint8 sta_addr[ETHER_ADDR_LEN]; -+ uint8 tgt_ap_addr[ETHER_ADDR_LEN]; -+ uint8 data[1]; /* Elements */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_ft_req dot11_ft_req_t; -+#define DOT11_FT_REQ_FIXED_LEN 14 -+ -+/* Over-the-DS Fast Transition Response frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_ft_res { -+ uint8 category; /* category of action frame (6) */ -+ uint8 action; /* action: ft resp */ -+ uint8 sta_addr[ETHER_ADDR_LEN]; -+ uint8 tgt_ap_addr[ETHER_ADDR_LEN]; -+ uint16 status; /* status code */ -+ uint8 data[1]; /* Elements */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_ft_res dot11_ft_res_t; -+#define DOT11_FT_RES_FIXED_LEN 16 -+ -+ -+/* ************* 802.11k related definitions. ************* */ -+ -+/* Radio measurements enabled capability ie */ -+ -+#define DOT11_RRM_CAP_LEN 5 /* length of rrm cap bitmap */ -+BWL_PRE_PACKED_STRUCT struct dot11_rrm_cap_ie { -+ uint8 cap[DOT11_RRM_CAP_LEN]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_rrm_cap_ie dot11_rrm_cap_ie_t; -+ -+/* Bitmap definitions for cap ie */ -+#define DOT11_RRM_CAP_LINK 0 -+#define DOT11_RRM_CAP_NEIGHBOR_REPORT 1 -+#define DOT11_RRM_CAP_PARALLEL 2 -+#define DOT11_RRM_CAP_REPEATED 3 -+#define DOT11_RRM_CAP_BCN_PASSIVE 4 -+#define DOT11_RRM_CAP_BCN_ACTIVE 5 -+#define DOT11_RRM_CAP_BCN_TABLE 6 -+#define DOT11_RRM_CAP_BCN_REP_COND 7 -+#define DOT11_RRM_CAP_AP_CHANREP 16 -+ -+ -+/* Operating Class (formerly "Regulatory Class") definitions */ -+#define DOT11_OP_CLASS_NONE 255 -+ -+ -+/* Radio Measurements action ids */ -+#define DOT11_RM_ACTION_RM_REQ 0 /* Radio measurement request */ -+#define DOT11_RM_ACTION_RM_REP 1 /* Radio measurement report */ -+#define DOT11_RM_ACTION_LM_REQ 2 /* Link measurement request */ -+#define DOT11_RM_ACTION_LM_REP 3 /* Link measurement report */ -+#define DOT11_RM_ACTION_NR_REQ 4 /* Neighbor report request */ -+#define DOT11_RM_ACTION_NR_REP 5 /* Neighbor report response */ -+ -+/* Generic radio measurement action frame header */ -+BWL_PRE_PACKED_STRUCT struct dot11_rm_action { -+ uint8 category; /* category of action frame (5) */ -+ uint8 action; /* radio measurement action */ -+ uint8 token; /* dialog token */ -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_rm_action dot11_rm_action_t; -+#define DOT11_RM_ACTION_LEN 3 -+ -+BWL_PRE_PACKED_STRUCT struct dot11_rmreq { -+ uint8 category; /* category of action frame (5) */ -+ uint8 action; /* radio measurement action */ -+ uint8 token; /* dialog token */ -+ uint16 reps; /* no. of repetitions */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_rmreq dot11_rmreq_t; -+#define DOT11_RMREQ_LEN 5 -+ -+BWL_PRE_PACKED_STRUCT struct dot11_rm_ie { -+ uint8 id; -+ uint8 len; -+ uint8 token; -+ uint8 mode; -+ uint8 type; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_rm_ie dot11_rm_ie_t; -+#define DOT11_RM_IE_LEN 5 -+ -+/* Definitions for "mode" bits in rm req */ -+#define DOT11_RMREQ_MODE_PARALLEL 1 -+#define DOT11_RMREQ_MODE_ENABLE 2 -+#define DOT11_RMREQ_MODE_REQUEST 4 -+#define DOT11_RMREQ_MODE_REPORT 8 -+#define DOT11_RMREQ_MODE_DURMAND 0x10 /* Duration Mandatory */ -+ -+/* Definitions for "mode" bits in rm rep */ -+#define DOT11_RMREP_MODE_LATE 1 -+#define DOT11_RMREP_MODE_INCAPABLE 2 -+#define DOT11_RMREP_MODE_REFUSED 4 -+ -+BWL_PRE_PACKED_STRUCT struct dot11_rmreq_bcn { -+ uint8 id; -+ uint8 len; -+ uint8 token; -+ uint8 mode; -+ uint8 type; -+ uint8 reg; -+ uint8 channel; -+ uint16 interval; -+ uint16 duration; -+ uint8 bcn_mode; -+ struct ether_addr bssid; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_rmreq_bcn dot11_rmreq_bcn_t; -+#define DOT11_RMREQ_BCN_LEN 18 -+ -+BWL_PRE_PACKED_STRUCT struct dot11_rmrep_bcn { -+ uint8 reg; -+ uint8 channel; -+ uint32 starttime[2]; -+ uint16 duration; -+ uint8 frame_info; -+ uint8 rcpi; -+ uint8 rsni; -+ struct ether_addr bssid; -+ uint8 antenna_id; -+ uint32 parent_tsf; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_rmrep_bcn dot11_rmrep_bcn_t; -+#define DOT11_RMREP_BCN_LEN 26 -+ -+/* Beacon request measurement mode */ -+#define DOT11_RMREQ_BCN_PASSIVE 0 -+#define DOT11_RMREQ_BCN_ACTIVE 1 -+#define DOT11_RMREQ_BCN_TABLE 2 -+ -+/* Sub-element IDs for Beacon Request */ -+#define DOT11_RMREQ_BCN_SSID_ID 0 -+#define DOT11_RMREQ_BCN_REPINFO_ID 1 -+#define DOT11_RMREQ_BCN_REPDET_ID 2 -+#define DOT11_RMREQ_BCN_REQUEST_ID 10 -+#define DOT11_RMREQ_BCN_APCHREP_ID 51 -+ -+/* Reporting Detail element definition */ -+#define DOT11_RMREQ_BCN_REPDET_FIXED 0 /* Fixed length fields only */ -+#define DOT11_RMREQ_BCN_REPDET_REQUEST 1 /* + requested information elems */ -+#define DOT11_RMREQ_BCN_REPDET_ALL 2 /* All fields */ -+ -+/* Sub-element IDs for Beacon Report */ -+#define DOT11_RMREP_BCN_FRM_BODY 1 -+ -+/* Neighbor measurement report */ -+BWL_PRE_PACKED_STRUCT struct dot11_rmrep_nbr { -+ struct ether_addr bssid; -+ uint32 bssid_info; -+ uint8 reg; -+ uint8 channel; -+ uint8 phytype; -+ uchar sub_elements[1]; /* Variable size data */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_rmrep_nbr dot11_rmrep_nbr_t; -+#define DOT11_RMREP_NBR_LEN 13 -+ -+/* MLME Enumerations */ -+#define DOT11_BSSTYPE_INFRASTRUCTURE 0 /* d11 infrastructure */ -+#define DOT11_BSSTYPE_INDEPENDENT 1 /* d11 independent */ -+#define DOT11_BSSTYPE_ANY 2 /* d11 any BSS type */ -+#define DOT11_SCANTYPE_ACTIVE 0 /* d11 scan active */ -+#define DOT11_SCANTYPE_PASSIVE 1 /* d11 scan passive */ -+ -+/* Link Measurement */ -+BWL_PRE_PACKED_STRUCT struct dot11_lmreq { -+ uint8 category; /* category of action frame (5) */ -+ uint8 action; /* radio measurement action */ -+ uint8 token; /* dialog token */ -+ uint8 txpwr; /* Transmit Power Used */ -+ uint8 maxtxpwr; /* Max Transmit Power */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_lmreq dot11_lmreq_t; -+#define DOT11_LMREQ_LEN 5 -+ -+BWL_PRE_PACKED_STRUCT struct dot11_lmrep { -+ uint8 category; /* category of action frame (5) */ -+ uint8 action; /* radio measurement action */ -+ uint8 token; /* dialog token */ -+ dot11_tpc_rep_t tpc; /* TPC element */ -+ uint8 rxant; /* Receive Antenna ID */ -+ uint8 txant; /* Transmit Antenna ID */ -+ uint8 rcpi; /* RCPI */ -+ uint8 rsni; /* RSNI */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_lmrep dot11_lmrep_t; -+#define DOT11_LMREP_LEN 11 -+ -+/* 802.11 BRCM "Compromise" Pre N constants */ -+#define PREN_PREAMBLE 24 /* green field preamble time */ -+#define PREN_MM_EXT 12 /* extra mixed mode preamble time */ -+#define PREN_PREAMBLE_EXT 4 /* extra preamble (multiply by unique_streams-1) */ -+ -+/* 802.11N PHY constants */ -+#define RIFS_11N_TIME 2 /* NPHY RIFS time */ -+ -+/* 802.11 HT PLCP format 802.11n-2009, sec 20.3.9.4.3 -+ * HT-SIG is composed of two 24 bit parts, HT-SIG1 and HT-SIG2 -+ */ -+/* HT-SIG1 */ -+#define HT_SIG1_MCS_MASK 0x00007F -+#define HT_SIG1_CBW 0x000080 -+#define HT_SIG1_HT_LENGTH 0xFFFF00 -+ -+/* HT-SIG2 */ -+#define HT_SIG2_SMOOTHING 0x000001 -+#define HT_SIG2_NOT_SOUNDING 0x000002 -+#define HT_SIG2_RESERVED 0x000004 -+#define HT_SIG2_AGGREGATION 0x000008 -+#define HT_SIG2_STBC_MASK 0x000030 -+#define HT_SIG2_STBC_SHIFT 4 -+#define HT_SIG2_FEC_CODING 0x000040 -+#define HT_SIG2_SHORT_GI 0x000080 -+#define HT_SIG2_ESS_MASK 0x000300 -+#define HT_SIG2_ESS_SHIFT 8 -+#define HT_SIG2_CRC 0x03FC00 -+#define HT_SIG2_TAIL 0x1C0000 -+ -+/* 802.11 A PHY constants */ -+#define APHY_SLOT_TIME 9 /* APHY slot time */ -+#define APHY_SIFS_TIME 16 /* APHY SIFS time */ -+#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME)) /* APHY DIFS time */ -+#define APHY_PREAMBLE_TIME 16 /* APHY preamble time */ -+#define APHY_SIGNAL_TIME 4 /* APHY signal time */ -+#define APHY_SYMBOL_TIME 4 /* APHY symbol time */ -+#define APHY_SERVICE_NBITS 16 /* APHY service nbits */ -+#define APHY_TAIL_NBITS 6 /* APHY tail nbits */ -+#define APHY_CWMIN 15 /* APHY cwmin */ -+ -+/* 802.11 B PHY constants */ -+#define BPHY_SLOT_TIME 20 /* BPHY slot time */ -+#define BPHY_SIFS_TIME 10 /* BPHY SIFS time */ -+#define BPHY_DIFS_TIME 50 /* BPHY DIFS time */ -+#define BPHY_PLCP_TIME 192 /* BPHY PLCP time */ -+#define BPHY_PLCP_SHORT_TIME 96 /* BPHY PLCP short time */ -+#define BPHY_CWMIN 31 /* BPHY cwmin */ -+ -+/* 802.11 G constants */ -+#define DOT11_OFDM_SIGNAL_EXTENSION 6 /* d11 OFDM signal extension */ -+ -+#define PHY_CWMAX 1023 /* PHY cwmax */ -+ -+#define DOT11_MAXNUMFRAGS 16 /* max # fragments per MSDU */ -+ -+/* 802.11 AC (VHT) constants */ -+ -+typedef int vht_group_id_t; -+ -+/* for VHT-A1 */ -+/* SIG-A1 reserved bits */ -+#define VHT_SIGA1_CONST_MASK 0x800004 -+ -+#define VHT_SIGA1_20MHZ_VAL 0x000000 -+#define VHT_SIGA1_40MHZ_VAL 0x000001 -+#define VHT_SIGA1_80MHZ_VAL 0x000002 -+#define VHT_SIGA1_160MHZ_VAL 0x000003 -+ -+#define VHT_SIGA1_STBC 0x000008 -+ -+#define VHT_SIGA1_GID_MAX_GID 0x3f -+#define VHT_SIGA1_GID_SHIFT 4 -+#define VHT_SIGA1_GID_TO_AP 0x00 -+#define VHT_SIGA1_GID_NOT_TO_AP 0x3f -+ -+#define VHT_SIGA1_NSTS_SHIFT 10 -+#define VHT_SIGA1_NSTS_SHIFT_MASK_USER0 0x001C00 -+ -+#define VHT_SIGA1_PARTIAL_AID_SHIFT 13 -+ -+/* for VHT-A2 */ -+#define VHT_SIGA2_GI_NONE 0x000000 -+#define VHT_SIGA2_GI_SHORT 0x000001 -+#define VHT_SIGA2_GI_W_MOD10 0x000002 -+#define VHT_SIGA2_CODING_LDPC 0x000004 -+#define VHT_SIGA2_BEAMFORM_ENABLE 0x000100 -+#define VHT_SIGA2_MCS_SHIFT 4 -+ -+#define VHT_SIGA2_B9_RESERVED 0x000200 -+#define VHT_SIGA2_TAIL_MASK 0xfc0000 -+#define VHT_SIGA2_TAIL_VALUE 0x000000 -+ -+#define VHT_SIGA2_SVC_BITS 16 -+#define VHT_SIGA2_TAIL_BITS 6 -+ -+ -+/* dot11Counters Table - 802.11 spec., Annex D */ -+typedef struct d11cnt { -+ uint32 txfrag; /* dot11TransmittedFragmentCount */ -+ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ -+ uint32 txfail; /* dot11FailedCount */ -+ uint32 txretry; /* dot11RetryCount */ -+ uint32 txretrie; /* dot11MultipleRetryCount */ -+ uint32 rxdup; /* dot11FrameduplicateCount */ -+ uint32 txrts; /* dot11RTSSuccessCount */ -+ uint32 txnocts; /* dot11RTSFailureCount */ -+ uint32 txnoack; /* dot11ACKFailureCount */ -+ uint32 rxfrag; /* dot11ReceivedFragmentCount */ -+ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ -+ uint32 rxcrc; /* dot11FCSErrorCount */ -+ uint32 txfrmsnt; /* dot11TransmittedFrameCount */ -+ uint32 rxundec; /* dot11WEPUndecryptableCount */ -+} d11cnt_t; -+ -+/* OUI for BRCM proprietary IE */ -+#define BRCM_PROP_OUI "\x00\x90\x4C" /* Broadcom proprietary OUI */ -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+/* The following BRCM_PROP_OUI types are currently in use (defined in -+ * relevant subsections). Each of them will be in a separate proprietary(221) IE -+ * #define SES_VNDR_IE_TYPE 1 (defined in src/ses/shared/ses.h) -+ * #define DPT_IE_TYPE 2 -+ * #define HT_CAP_IE_TYPE 51 -+ * #define HT_ADD_IE_TYPE 52 -+ * #define BRCM_EXTCH_IE_TYPE 53 -+ */ -+ -+/* Following is the generic structure for brcm_prop_ie (uses BRCM_PROP_OUI). -+ * DPT uses this format with type set to DPT_IE_TYPE -+ */ -+BWL_PRE_PACKED_STRUCT struct brcm_prop_ie_s { -+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ -+ uint8 len; /* IE length */ -+ uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ -+ uint8 type; /* type of this IE */ -+ uint16 cap; /* DPT capabilities */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct brcm_prop_ie_s brcm_prop_ie_t; -+ -+#define BRCM_PROP_IE_LEN 6 /* len of fixed part of brcm_prop ie */ -+ -+#define DPT_IE_TYPE 2 -+#define WET_TUNNEL_IE_TYPE 3 -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+/* BRCM OUI: Used in the proprietary(221) IE in all broadcom devices */ -+#define BRCM_OUI "\x00\x10\x18" /* Broadcom OUI */ -+ -+/* BRCM info element */ -+BWL_PRE_PACKED_STRUCT struct brcm_ie { -+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ -+ uint8 len; /* IE length */ -+ uint8 oui[3]; /* Proprietary OUI, BRCM_OUI */ -+ uint8 ver; /* type/ver of this IE */ -+ uint8 assoc; /* # of assoc STAs */ -+ uint8 flags; /* misc flags */ -+ uint8 flags1; /* misc flags */ -+ uint16 amsdu_mtu_pref; /* preferred A-MSDU MTU */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct brcm_ie brcm_ie_t; -+#define BRCM_IE_LEN 11 /* BRCM IE length */ -+#define BRCM_IE_VER 2 /* BRCM IE version */ -+#define BRCM_IE_LEGACY_AES_VER 1 /* BRCM IE legacy AES version */ -+ -+/* brcm_ie flags */ -+#define BRF_LZWDS 0x4 /* lazy wds enabled */ -+#define BRF_BLOCKACK 0x8 /* BlockACK capable */ -+ -+/* brcm_ie flags1 */ -+#define BRF1_AMSDU 0x1 /* A-MSDU capable */ -+#define BRF1_WMEPS 0x4 /* AP is capable of handling WME + PS w/o APSD */ -+#define BRF1_PSOFIX 0x8 /* AP has fixed PS mode out-of-order packets */ -+#define BRF1_RX_LARGE_AGG 0x10 /* device can rx large aggregates */ -+#define BRF1_RFAWARE_DCS 0x20 /* RFAWARE dynamic channel selection (DCS) */ -+#define BRF1_SOFTAP 0x40 /* Configure as Broadcom SOFTAP */ -+ -+/* Vendor IE structure */ -+BWL_PRE_PACKED_STRUCT struct vndr_ie { -+ uchar id; -+ uchar len; -+ uchar oui [3]; -+ uchar data [1]; /* Variable size data */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct vndr_ie vndr_ie_t; -+ -+#define VNDR_IE_HDR_LEN 2 /* id + len field */ -+#define VNDR_IE_MIN_LEN 3 /* size of the oui field */ -+#define VNDR_IE_MAX_LEN 256 /* verdor IE max length */ -+ -+/* ************* HT definitions. ************* */ -+#define MCSSET_LEN 16 /* 16-bits per 8-bit set to give 128-bits bitmap of MCS Index */ -+#define MAX_MCS_NUM (128) /* max mcs number = 128 */ -+ -+BWL_PRE_PACKED_STRUCT struct ht_cap_ie { -+ uint16 cap; -+ uint8 params; -+ uint8 supp_mcs[MCSSET_LEN]; -+ uint16 ext_htcap; -+ uint32 txbf_cap; -+ uint8 as_cap; -+} BWL_POST_PACKED_STRUCT; -+typedef struct ht_cap_ie ht_cap_ie_t; -+ -+/* CAP IE: HT 1.0 spec. simply stole a 802.11 IE, we use our prop. IE until this is resolved */ -+/* the capability IE is primarily used to convey this nodes abilities */ -+BWL_PRE_PACKED_STRUCT struct ht_prop_cap_ie { -+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ -+ uint8 len; /* IE length */ -+ uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ -+ uint8 type; /* type inidicates what follows */ -+ ht_cap_ie_t cap_ie; -+} BWL_POST_PACKED_STRUCT; -+typedef struct ht_prop_cap_ie ht_prop_cap_ie_t; -+ -+#define HT_PROP_IE_OVERHEAD 4 /* overhead bytes for prop oui ie */ -+#define HT_CAP_IE_LEN 26 /* HT capability len (based on .11n d2.0) */ -+#define HT_CAP_IE_TYPE 51 -+ -+#define HT_CAP_LDPC_CODING 0x0001 /* Support for rx of LDPC coded pkts */ -+#define HT_CAP_40MHZ 0x0002 /* FALSE:20Mhz, TRUE:20/40MHZ supported */ -+#define HT_CAP_MIMO_PS_MASK 0x000C /* Mimo PS mask */ -+#define HT_CAP_MIMO_PS_SHIFT 0x0002 /* Mimo PS shift */ -+#define HT_CAP_MIMO_PS_OFF 0x0003 /* Mimo PS, no restriction */ -+#define HT_CAP_MIMO_PS_RTS 0x0001 /* Mimo PS, send RTS/CTS around MIMO frames */ -+#define HT_CAP_MIMO_PS_ON 0x0000 /* Mimo PS, MIMO disallowed */ -+#define HT_CAP_GF 0x0010 /* Greenfield preamble support */ -+#define HT_CAP_SHORT_GI_20 0x0020 /* 20MHZ short guard interval support */ -+#define HT_CAP_SHORT_GI_40 0x0040 /* 40Mhz short guard interval support */ -+#define HT_CAP_TX_STBC 0x0080 /* Tx STBC support */ -+#define HT_CAP_RX_STBC_MASK 0x0300 /* Rx STBC mask */ -+#define HT_CAP_RX_STBC_SHIFT 8 /* Rx STBC shift */ -+#define HT_CAP_DELAYED_BA 0x0400 /* delayed BA support */ -+#define HT_CAP_MAX_AMSDU 0x0800 /* Max AMSDU size in bytes , 0=3839, 1=7935 */ -+ -+#define HT_CAP_DSSS_CCK 0x1000 /* DSSS/CCK supported by the BSS */ -+#define HT_CAP_PSMP 0x2000 /* Power Save Multi Poll support */ -+#define HT_CAP_40MHZ_INTOLERANT 0x4000 /* 40MHz Intolerant */ -+#define HT_CAP_LSIG_TXOP 0x8000 /* L-SIG TXOP protection support */ -+ -+#define HT_CAP_RX_STBC_NO 0x0 /* no rx STBC support */ -+#define HT_CAP_RX_STBC_ONE_STREAM 0x1 /* rx STBC support of 1 spatial stream */ -+#define HT_CAP_RX_STBC_TWO_STREAM 0x2 /* rx STBC support of 1-2 spatial streams */ -+#define HT_CAP_RX_STBC_THREE_STREAM 0x3 /* rx STBC support of 1-3 spatial streams */ -+ -+#define VHT_MAX_MPDU 11454 /* max mpdu size for now (bytes) */ -+#define VHT_MPDU_MSDU_DELTA 56 /* Difference in spec - vht mpdu, amsdu len */ -+/* Max AMSDU len - per spec */ -+#define VHT_MAX_AMSDU (VHT_MAX_MPDU - VHT_MPDU_MSDU_DELTA) -+ -+#define HT_MAX_AMSDU 7935 /* max amsdu size (bytes) per the HT spec */ -+#define HT_MIN_AMSDU 3835 /* min amsdu size (bytes) per the HT spec */ -+ -+#define HT_PARAMS_RX_FACTOR_MASK 0x03 /* ampdu rcv factor mask */ -+#define HT_PARAMS_DENSITY_MASK 0x1C /* ampdu density mask */ -+#define HT_PARAMS_DENSITY_SHIFT 2 /* ampdu density shift */ -+ -+/* HT/AMPDU specific define */ -+#define AMPDU_MAX_MPDU_DENSITY 7 /* max mpdu density; in 1/8 usec units */ -+#define AMPDU_RX_FACTOR_8K 0 /* max rcv ampdu len (8kb) */ -+#define AMPDU_RX_FACTOR_16K 1 /* max rcv ampdu len (16kb) */ -+#define AMPDU_RX_FACTOR_32K 2 /* max rcv ampdu len (32kb) */ -+#define AMPDU_RX_FACTOR_64K 3 /* max rcv ampdu len (64kb) */ -+#define AMPDU_RX_FACTOR_BASE 8*1024 /* ampdu factor base for rx len */ -+ -+#define AMPDU_DELIMITER_LEN 4 /* length of ampdu delimiter */ -+#define AMPDU_DELIMITER_LEN_MAX 63 /* max length of ampdu delimiter(enforced in HW) */ -+ -+#define HT_CAP_EXT_PCO 0x0001 -+#define HT_CAP_EXT_PCO_TTIME_MASK 0x0006 -+#define HT_CAP_EXT_PCO_TTIME_SHIFT 1 -+#define HT_CAP_EXT_MCS_FEEDBACK_MASK 0x0300 -+#define HT_CAP_EXT_MCS_FEEDBACK_SHIFT 8 -+#define HT_CAP_EXT_HTC 0x0400 -+#define HT_CAP_EXT_RD_RESP 0x0800 -+ -+BWL_PRE_PACKED_STRUCT struct ht_add_ie { -+ uint8 ctl_ch; /* control channel number */ -+ uint8 byte1; /* ext ch,rec. ch. width, RIFS support */ -+ uint16 opmode; /* operation mode */ -+ uint16 misc_bits; /* misc bits */ -+ uint8 basic_mcs[MCSSET_LEN]; /* required MCS set */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct ht_add_ie ht_add_ie_t; -+ -+/* ADD IE: HT 1.0 spec. simply stole a 802.11 IE, we use our prop. IE until this is resolved */ -+/* the additional IE is primarily used to convey the current BSS configuration */ -+BWL_PRE_PACKED_STRUCT struct ht_prop_add_ie { -+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ -+ uint8 len; /* IE length */ -+ uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ -+ uint8 type; /* indicates what follows */ -+ ht_add_ie_t add_ie; -+} BWL_POST_PACKED_STRUCT; -+typedef struct ht_prop_add_ie ht_prop_add_ie_t; -+ -+#define HT_ADD_IE_LEN 22 -+#define HT_ADD_IE_TYPE 52 -+ -+/* byte1 defn's */ -+#define HT_BW_ANY 0x04 /* set, STA can use 20 or 40MHz */ -+#define HT_RIFS_PERMITTED 0x08 /* RIFS allowed */ -+ -+/* opmode defn's */ -+#define HT_OPMODE_MASK 0x0003 /* protection mode mask */ -+#define HT_OPMODE_SHIFT 0 /* protection mode shift */ -+#define HT_OPMODE_PURE 0x0000 /* protection mode PURE */ -+#define HT_OPMODE_OPTIONAL 0x0001 /* protection mode optional */ -+#define HT_OPMODE_HT20IN40 0x0002 /* protection mode 20MHz HT in 40MHz BSS */ -+#define HT_OPMODE_MIXED 0x0003 /* protection mode Mixed Mode */ -+#define HT_OPMODE_NONGF 0x0004 /* protection mode non-GF */ -+#define DOT11N_TXBURST 0x0008 /* Tx burst limit */ -+#define DOT11N_OBSS_NONHT 0x0010 /* OBSS Non-HT STA present */ -+ -+/* misc_bites defn's */ -+#define HT_BASIC_STBC_MCS 0x007f /* basic STBC MCS */ -+#define HT_DUAL_STBC_PROT 0x0080 /* Dual STBC Protection */ -+#define HT_SECOND_BCN 0x0100 /* Secondary beacon support */ -+#define HT_LSIG_TXOP 0x0200 /* L-SIG TXOP Protection full support */ -+#define HT_PCO_ACTIVE 0x0400 /* PCO active */ -+#define HT_PCO_PHASE 0x0800 /* PCO phase */ -+#define HT_DUALCTS_PROTECTION 0x0080 /* DUAL CTS protection needed */ -+ -+/* Tx Burst Limits */ -+#define DOT11N_2G_TXBURST_LIMIT 6160 /* 2G band Tx burst limit per 802.11n Draft 1.10 (usec) */ -+#define DOT11N_5G_TXBURST_LIMIT 3080 /* 5G band Tx burst limit per 802.11n Draft 1.10 (usec) */ -+ -+/* Macros for opmode */ -+#define GET_HT_OPMODE(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ -+ >> HT_OPMODE_SHIFT) -+#define HT_MIXEDMODE_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ -+ == HT_OPMODE_MIXED) /* mixed mode present */ -+#define HT_HT20_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ -+ == HT_OPMODE_HT20IN40) /* 20MHz HT present */ -+#define HT_OPTIONAL_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \ -+ == HT_OPMODE_OPTIONAL) /* Optional protection present */ -+#define HT_USE_PROTECTION(add_ie) (HT_HT20_PRESENT((add_ie)) || \ -+ HT_MIXEDMODE_PRESENT((add_ie))) /* use protection */ -+#define HT_NONGF_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_NONGF) \ -+ == HT_OPMODE_NONGF) /* non-GF present */ -+#define DOT11N_TXBURST_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_TXBURST) \ -+ == DOT11N_TXBURST) /* Tx Burst present */ -+#define DOT11N_OBSS_NONHT_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_OBSS_NONHT) \ -+ == DOT11N_OBSS_NONHT) /* OBSS Non-HT present */ -+ -+BWL_PRE_PACKED_STRUCT struct obss_params { -+ uint16 passive_dwell; -+ uint16 active_dwell; -+ uint16 bss_widthscan_interval; -+ uint16 passive_total; -+ uint16 active_total; -+ uint16 chanwidth_transition_dly; -+ uint16 activity_threshold; -+} BWL_POST_PACKED_STRUCT; -+typedef struct obss_params obss_params_t; -+ -+BWL_PRE_PACKED_STRUCT struct dot11_obss_ie { -+ uint8 id; -+ uint8 len; -+ obss_params_t obss_params; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_obss_ie dot11_obss_ie_t; -+#define DOT11_OBSS_SCAN_IE_LEN sizeof(obss_params_t) /* HT OBSS len (based on 802.11n d3.0) */ -+ -+/* HT control field */ -+#define HT_CTRL_LA_TRQ 0x00000002 /* sounding request */ -+#define HT_CTRL_LA_MAI 0x0000003C /* MCS request or antenna selection indication */ -+#define HT_CTRL_LA_MAI_SHIFT 2 -+#define HT_CTRL_LA_MAI_MRQ 0x00000004 /* MCS request */ -+#define HT_CTRL_LA_MAI_MSI 0x00000038 /* MCS request sequence identifier */ -+#define HT_CTRL_LA_MFSI 0x000001C0 /* MFB sequence identifier */ -+#define HT_CTRL_LA_MFSI_SHIFT 6 -+#define HT_CTRL_LA_MFB_ASELC 0x0000FE00 /* MCS feedback, antenna selection command/data */ -+#define HT_CTRL_LA_MFB_ASELC_SH 9 -+#define HT_CTRL_LA_ASELC_CMD 0x00000C00 /* ASEL command */ -+#define HT_CTRL_LA_ASELC_DATA 0x0000F000 /* ASEL data */ -+#define HT_CTRL_CAL_POS 0x00030000 /* Calibration position */ -+#define HT_CTRL_CAL_SEQ 0x000C0000 /* Calibration sequence */ -+#define HT_CTRL_CSI_STEERING 0x00C00000 /* CSI/Steering */ -+#define HT_CTRL_CSI_STEER_SHIFT 22 -+#define HT_CTRL_CSI_STEER_NFB 0 /* no fedback required */ -+#define HT_CTRL_CSI_STEER_CSI 1 /* CSI, H matrix */ -+#define HT_CTRL_CSI_STEER_NCOM 2 /* non-compressed beamforming */ -+#define HT_CTRL_CSI_STEER_COM 3 /* compressed beamforming */ -+#define HT_CTRL_NDP_ANNOUNCE 0x01000000 /* NDP announcement */ -+#define HT_CTRL_AC_CONSTRAINT 0x40000000 /* AC Constraint */ -+#define HT_CTRL_RDG_MOREPPDU 0x80000000 /* RDG/More PPDU */ -+ -+#define HT_OPMODE_OPTIONAL 0x0001 /* protection mode optional */ -+#define HT_OPMODE_HT20IN40 0x0002 /* protection mode 20MHz HT in 40MHz BSS */ -+#define HT_OPMODE_MIXED 0x0003 /* protection mode Mixed Mode */ -+#define HT_OPMODE_NONGF 0x0004 /* protection mode non-GF */ -+#define DOT11N_TXBURST 0x0008 /* Tx burst limit */ -+#define DOT11N_OBSS_NONHT 0x0010 /* OBSS Non-HT STA present */ -+ -+/* ************* VHT definitions. ************* */ -+ -+BWL_PRE_PACKED_STRUCT struct vht_cap_ie { -+ uint32 vht_cap_info; -+ /* supported MCS set - 64 bit field */ -+ uint16 rx_mcs_map; -+ uint16 rx_max_rate; -+ uint16 tx_mcs_map; -+ uint16 tx_max_rate; -+} BWL_POST_PACKED_STRUCT; -+typedef struct vht_cap_ie vht_cap_ie_t; -+/* 4B cap_info + 8B supp_mcs */ -+#define VHT_CAP_IE_LEN 12 -+/* 32bit - cap info */ -+#define VHT_CAP_INFO_MAX_MPDU_LEN_MASK 0x00000003 -+#define VHT_CAP_INFO_SUPP_CHAN_WIDTH_MASK 0x0000000c -+#define VHT_CAP_INFO_LDPC 0x00000010 -+#define VHT_CAP_INFO_SGI_80MHZ 0x00000020 -+#define VHT_CAP_INFO_SGI_160MHZ 0x00000040 -+#define VHT_CAP_INFO_TX_STBC 0x00000080 -+#define VHT_CAP_INFO_RX_STBC 0x00000700 -+ -+#define VHT_CAP_INFO_RX_STBC_MASK 0x00000700 -+#define VHT_CAP_INFO_RX_STBC_SHIFT 8 -+#define VHT_CAP_INFO_SU_BEAMFMR 0x00000800 -+#define VHT_CAP_INFO_SU_BEAMFMEE 0x00001000 -+#define VHT_CAP_INFO_NUM_BMFMR_ANT_MASK 0x0000e000 -+#define VHT_CAP_INFO_NUM_BMFMR_ANT_SHIFT 13 -+ -+#define VHT_CAP_INFO_NUM_SOUNDING_DIM_MASK 0x00070000 -+#define VHT_CAP_INFO_NUM_SOUNDING_DIM_SHIFT 16 -+#define VHT_CAP_INFO_MU_BEAMFMR 0x00080000 -+#define VHT_CAP_INFO_MU_BEAMFMEE 0x00100000 -+#define VHT_CAP_INFO_TXOPPS 0x00200000 -+#define VHT_CAP_INFO_HTCVHT 0x00400000 -+#define VHT_CAP_INFO_AMPDU_MAXLEN_EXP_MASK 0x03800000 -+#define VHT_CAP_INFO_AMPDU_MAXLEN_EXP_SHIFT 23 -+ -+#define VHT_CAP_INFO_LINK_ADAPT_CAP_MASK 0x0c000000 -+#define VHT_CAP_INFO_LINK_ADAPT_CAP_SHIFT 26 -+ -+/* 64-bit Supp MCS. */ -+#define VHT_CAP_SUPP_MCS_RX_HIGHEST_RATE_MASK 0x1fff -+#define VHT_CAP_SUPP_MCS_RX_HIGHEST_RATE_SHIFT 0 -+ -+#define VHT_CAP_SUPP_MCS_TX_HIGHEST_RATE_MASK 0x1fff -+#define VHT_CAP_SUPP_MCS_TX_HIGHEST_RATE_SHIFT 0 -+ -+#define VHT_CAP_MCS_MAP_0_7 0 -+#define VHT_CAP_MCS_MAP_0_8 1 -+#define VHT_CAP_MCS_MAP_0_9 2 -+#define VHT_CAP_MCS_MAP_NONE 3 -+ -+#define VHT_CAP_MCS_MAP_NSS_MAX 8 -+ -+/* VHT Capabilities Supported Channel Width */ -+typedef enum vht_cap_chan_width { -+ VHT_CAP_CHAN_WIDTH_20_40 = 0x00, -+ VHT_CAP_CHAN_WIDTH_80 = 0x04, -+ VHT_CAP_CHAN_WIDTH_160 = 0x08 -+} vht_cap_chan_width_t; -+ -+/* VHT Capabilities Supported max MPDU LEN */ -+typedef enum vht_cap_max_mpdu_len { -+ VHT_CAP_MPDU_MAX_4K = 0x00, -+ VHT_CAP_MPDU_MAX_8K = 0x01, -+ VHT_CAP_MPDU_MAX_11K = 0x02 -+} vht_cap_max_mpdu_len_t; -+ -+/* VHT Operation Element */ -+BWL_PRE_PACKED_STRUCT struct vht_op_ie { -+ uint8 chan_width; -+ uint8 chan1; -+ uint8 chan2; -+ uint16 supp_mcs; /* same def as above in vht cap */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct vht_op_ie vht_op_ie_t; -+/* 3B VHT Op info + 2B Basic MCS */ -+#define VHT_OP_IE_LEN 5 -+ -+typedef enum vht_op_chan_width { -+ VHT_OP_CHAN_WIDTH_20_40 = 0, -+ VHT_OP_CHAN_WIDTH_80 = 1, -+ VHT_OP_CHAN_WIDTH_160 = 2, -+ VHT_OP_CHAN_WIDTH_80_80 = 3 -+} vht_op_chan_width_t; -+ -+/* Def for rx & tx basic mcs maps - ea ss num has 2 bits of info */ -+#define VHT_MCS_MAP_GET_SS_IDX(nss) (((nss)-1)*2) -+#define VHT_MCS_MAP_GET_MCS_PER_SS(nss, mcsMap) \ -+ (((mcsMap) >> VHT_MCS_MAP_GET_SS_IDX(nss)) & 0x3) -+#define VHT_MCS_MAP_SET_MCS_PER_SS(nss, numMcs, mcsMap) \ -+ ((mcsMap) |= (((numMcs) & 0x3) << VHT_MCS_MAP_GET_SS_IDX(nss))) -+ -+/* ************* WPA definitions. ************* */ -+#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ -+#define WPA_OUI_LEN 3 /* WPA OUI length */ -+#define WPA_OUI_TYPE 1 -+#define WPA_VERSION 1 /* WPA version */ -+#define WPA2_OUI "\x00\x0F\xAC" /* WPA2 OUI */ -+#define WPA2_OUI_LEN 3 /* WPA2 OUI length */ -+#define WPA2_VERSION 1 /* WPA2 version */ -+#define WPA2_VERSION_LEN 2 /* WAP2 version length */ -+ -+/* ************* WPS definitions. ************* */ -+#define WPS_OUI "\x00\x50\xF2" /* WPS OUI */ -+#define WPS_OUI_LEN 3 /* WPS OUI length */ -+#define WPS_OUI_TYPE 4 -+ -+/* ************* WFA definitions. ************* */ -+#if defined(MACOSX) -+#define MAC_OUI "\x00\x17\xF2" /* MACOSX OUI */ -+#define MAC_OUI_TYPE_P2P 5 -+#endif /* MACOSX */ -+ -+#if defined(MACOSX) && !defined(WLP2P_NEW_WFA_OUI) -+#define WFA_OUI WPS_OUI /* WFA OUI */ -+#else -+#ifdef P2P_IE_OVRD -+#define WFA_OUI MAC_OUI -+#else -+#define WFA_OUI "\x50\x6F\x9A" /* WFA OUI */ -+#endif /* P2P_IE_OVRD */ -+#endif /* MACOSX && !WLP2P_NEW_WFA_OUI */ -+#define WFA_OUI_LEN 3 /* WFA OUI length */ -+#ifdef P2P_IE_OVRD -+#define WFA_OUI_TYPE_P2P MAC_OUI_TYPE_P2P -+#else -+#define WFA_OUI_TYPE_P2P 9 -+#endif -+ -+#define WFA_OUI_TYPE_TPC 8 -+ -+/* RSN authenticated key managment suite */ -+#define RSN_AKM_NONE 0 /* None (IBSS) */ -+#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */ -+#define RSN_AKM_PSK 2 /* Pre-shared Key */ -+#define RSN_AKM_FBT_1X 3 /* Fast Bss transition using 802.1X */ -+#define RSN_AKM_FBT_PSK 4 /* Fast Bss transition using Pre-shared Key */ -+#define RSN_AKM_MFP_1X 5 /* SHA256 key derivation, using 802.1X */ -+#define RSN_AKM_MFP_PSK 6 /* SHA256 key derivation, using Pre-shared Key */ -+#define RSN_AKM_TPK 7 /* TPK(TDLS Peer Key) handshake */ -+ -+/* Key related defines */ -+#define DOT11_MAX_DEFAULT_KEYS 4 /* number of default keys */ -+#define DOT11_MAX_KEY_SIZE 32 /* max size of any key */ -+#define DOT11_MAX_IV_SIZE 16 /* max size of any IV */ -+#define DOT11_EXT_IV_FLAG (1<<5) /* flag to indicate IV is > 4 bytes */ -+#define DOT11_WPA_KEY_RSC_LEN 8 /* WPA RSC key len */ -+ -+#define WEP1_KEY_SIZE 5 /* max size of any WEP key */ -+#define WEP1_KEY_HEX_SIZE 10 /* size of WEP key in hex. */ -+#define WEP128_KEY_SIZE 13 /* max size of any WEP key */ -+#define WEP128_KEY_HEX_SIZE 26 /* size of WEP key in hex. */ -+#define TKIP_MIC_SIZE 8 /* size of TKIP MIC */ -+#define TKIP_EOM_SIZE 7 /* max size of TKIP EOM */ -+#define TKIP_EOM_FLAG 0x5a /* TKIP EOM flag byte */ -+#define TKIP_KEY_SIZE 32 /* size of any TKIP key */ -+#define TKIP_MIC_AUTH_TX 16 /* offset to Authenticator MIC TX key */ -+#define TKIP_MIC_AUTH_RX 24 /* offset to Authenticator MIC RX key */ -+#define TKIP_MIC_SUP_RX TKIP_MIC_AUTH_TX /* offset to Supplicant MIC RX key */ -+#define TKIP_MIC_SUP_TX TKIP_MIC_AUTH_RX /* offset to Supplicant MIC TX key */ -+#define AES_KEY_SIZE 16 /* size of AES key */ -+#define AES_MIC_SIZE 8 /* size of AES MIC */ -+#define BIP_KEY_SIZE 16 /* size of BIP key */ -+ -+/* WCN */ -+#define WCN_OUI "\x00\x50\xf2" /* WCN OUI */ -+#define WCN_TYPE 4 /* WCN type */ -+ -+ -+/* 802.11r protocol definitions */ -+ -+/* Mobility Domain IE */ -+BWL_PRE_PACKED_STRUCT struct dot11_mdid_ie { -+ uint8 id; -+ uint8 len; -+ uint16 mdid; /* Mobility Domain Id */ -+ uint8 cap; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_mdid_ie dot11_mdid_ie_t; -+ -+#define FBT_MDID_CAP_OVERDS 0x01 /* Fast Bss transition over the DS support */ -+#define FBT_MDID_CAP_RRP 0x02 /* Resource request protocol support */ -+ -+/* Fast Bss Transition IE */ -+BWL_PRE_PACKED_STRUCT struct dot11_ft_ie { -+ uint8 id; -+ uint8 len; -+ uint16 mic_control; /* Mic Control */ -+ uint8 mic[16]; -+ uint8 anonce[32]; -+ uint8 snonce[32]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_ft_ie dot11_ft_ie_t; -+ -+#define TIE_TYPE_RESERVED 0 -+#define TIE_TYPE_REASSOC_DEADLINE 1 -+#define TIE_TYPE_KEY_LIEFTIME 2 -+#define TIE_TYPE_ASSOC_COMEBACK 3 -+BWL_PRE_PACKED_STRUCT struct dot11_timeout_ie { -+ uint8 id; -+ uint8 len; -+ uint8 type; /* timeout interval type */ -+ uint32 value; /* timeout interval value */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_timeout_ie dot11_timeout_ie_t; -+ -+/* GTK ie */ -+BWL_PRE_PACKED_STRUCT struct dot11_gtk_ie { -+ uint8 id; -+ uint8 len; -+ uint16 key_info; -+ uint8 key_len; -+ uint8 rsc[8]; -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT; -+typedef struct dot11_gtk_ie dot11_gtk_ie_t; -+ -+#define BSSID_INVALID "\x00\x00\x00\x00\x00\x00" -+#define BSSID_BROADCAST "\xFF\xFF\xFF\xFF\xFF\xFF" -+ -+ -+/* ************* WMM Parameter definitions. ************* */ -+#define WMM_OUI "\x00\x50\xF2" /* WNN OUI */ -+#define WMM_OUI_LEN 3 /* WMM OUI length */ -+#define WMM_OUI_TYPE 2 /* WMM OUT type */ -+#define WMM_VERSION 1 -+#define WMM_VERSION_LEN 1 -+ -+/* WMM OUI subtype */ -+#define WMM_OUI_SUBTYPE_PARAMETER 1 -+#define WMM_PARAMETER_IE_LEN 24 -+ -+/* Link Identifier Element */ -+BWL_PRE_PACKED_STRUCT struct link_id_ie { -+ uint8 id; -+ uint8 len; -+ struct ether_addr bssid; -+ struct ether_addr tdls_init_mac; -+ struct ether_addr tdls_resp_mac; -+} BWL_POST_PACKED_STRUCT; -+typedef struct link_id_ie link_id_ie_t; -+#define TDLS_LINK_ID_IE_LEN 18 -+ -+/* Link Wakeup Schedule Element */ -+BWL_PRE_PACKED_STRUCT struct wakeup_sch_ie { -+ uint8 id; -+ uint8 len; -+ uint32 offset; /* in ms between TSF0 and start of 1st Awake Window */ -+ uint32 interval; /* in ms bwtween the start of 2 Awake Windows */ -+ uint32 awake_win_slots; /* in backof slots, duration of Awake Window */ -+ uint32 max_wake_win; /* in ms, max duration of Awake Window */ -+ uint16 idle_cnt; /* number of consecutive Awake Windows */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct wakeup_sch_ie wakeup_sch_ie_t; -+#define TDLS_WAKEUP_SCH_IE_LEN 18 -+ -+/* Channel Switch Timing Element */ -+BWL_PRE_PACKED_STRUCT struct channel_switch_timing_ie { -+ uint8 id; -+ uint8 len; -+ uint16 switch_time; /* in ms, time to switch channels */ -+ uint16 switch_timeout; /* in ms */ -+} BWL_POST_PACKED_STRUCT; -+typedef struct channel_switch_timing_ie channel_switch_timing_ie_t; -+#define TDLS_CHANNEL_SWITCH_TIMING_IE_LEN 4 -+ -+/* PTI Control Element */ -+BWL_PRE_PACKED_STRUCT struct pti_control_ie { -+ uint8 id; -+ uint8 len; -+ uint8 tid; -+ uint16 seq_control; -+} BWL_POST_PACKED_STRUCT; -+typedef struct pti_control_ie pti_control_ie_t; -+#define TDLS_PTI_CONTROL_IE_LEN 3 -+ -+/* PU Buffer Status Element */ -+BWL_PRE_PACKED_STRUCT struct pu_buffer_status_ie { -+ uint8 id; -+ uint8 len; -+ uint8 status; -+} BWL_POST_PACKED_STRUCT; -+typedef struct pu_buffer_status_ie pu_buffer_status_ie_t; -+#define TDLS_PU_BUFFER_STATUS_IE_LEN 1 -+#define TDLS_PU_BUFFER_STATUS_AC_BK 1 -+#define TDLS_PU_BUFFER_STATUS_AC_BE 2 -+#define TDLS_PU_BUFFER_STATUS_AC_VI 4 -+#define TDLS_PU_BUFFER_STATUS_AC_VO 8 -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _802_11_H_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/802.1d.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/802.1d.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/802.1d.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/802.1d.h 2017-11-09 17:53:43.977301000 +0800 -@@ -0,0 +1,44 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Fundamental types and constants relating to 802.1D -+ * -+ * $Id: 802.1d.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _802_1_D_ -+#define _802_1_D_ -+ -+/* 802.1D priority defines */ -+#define PRIO_8021D_NONE 2 /* None = - */ -+#define PRIO_8021D_BK 1 /* BK - Background */ -+#define PRIO_8021D_BE 0 /* BE - Best-effort */ -+#define PRIO_8021D_EE 3 /* EE - Excellent-effort */ -+#define PRIO_8021D_CL 4 /* CL - Controlled Load */ -+#define PRIO_8021D_VI 5 /* Vi - Video */ -+#define PRIO_8021D_VO 6 /* Vo - Voice */ -+#define PRIO_8021D_NC 7 /* NC - Network Control */ -+#define MAXPRIO 7 /* 0-7 */ -+#define NUMPRIO (MAXPRIO + 1) -+ -+#define ALLPRIO -1 /* All prioirty */ -+ -+/* Converts prio to precedence since the numerical value of -+ * PRIO_8021D_BE and PRIO_8021D_NONE are swapped. -+ */ -+#define PRIO2PREC(prio) \ -+ (((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? ((prio^2)) : (prio)) -+ -+#endif /* _802_1_D__ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/BOM b/drivers/net/ethernet/broadcom/gmac/src/include/proto/BOM ---- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/BOM 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/BOM 2017-11-09 17:53:43.978294000 +0800 -@@ -0,0 +1,4 @@ -+# Created by mkbom -+# $Id: BOM,v 9.0 1998-07-30 23:19:02 $ -+ -+File 1.46 vip.h -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/Makefile b/drivers/net/ethernet/broadcom/gmac/src/include/proto/Makefile ---- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/Makefile 2017-11-09 17:53:43.979288000 +0800 -@@ -0,0 +1,21 @@ -+# -+# include/proto/Makefile -+# -+# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+# -+# 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. -+# -+# $Id: Makefile 241182 2011-02-17 21:50:03Z $ -+# -+ -+# build etags -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmeth.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmeth.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmeth.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmeth.h 2017-11-09 17:53:43.979307000 +0800 -@@ -0,0 +1,106 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom Ethernettype protocol definitions -+ * -+ * $Id: bcmeth.h 294352 2011-11-06 19:23:00Z $ -+ */ -+ -+/* -+ * Broadcom Ethernet protocol defines -+ */ -+ -+#ifndef _BCMETH_H_ -+#define _BCMETH_H_ -+ -+#ifndef _TYPEDEFS_H_ -+#include -+#endif -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+/* ETHER_TYPE_BRCM is defined in ethernet.h */ -+ -+/* -+ * Following the 2byte BRCM ether_type is a 16bit BRCM subtype field -+ * in one of two formats: (only subtypes 32768-65535 are in use now) -+ * -+ * subtypes 0-32767: -+ * 8 bit subtype (0-127) -+ * 8 bit length in bytes (0-255) -+ * -+ * subtypes 32768-65535: -+ * 16 bit big-endian subtype -+ * 16 bit big-endian length in bytes (0-65535) -+ * -+ * length is the number of additional bytes beyond the 4 or 6 byte header -+ * -+ * Reserved values: -+ * 0 reserved -+ * 5-15 reserved for iLine protocol assignments -+ * 17-126 reserved, assignable -+ * 127 reserved -+ * 32768 reserved -+ * 32769-65534 reserved, assignable -+ * 65535 reserved -+ */ -+ -+/* -+ * While adding the subtypes and their specific processing code make sure -+ * bcmeth_bcm_hdr_t is the first data structure in the user specific data structure definition -+ */ -+ -+#define BCMILCP_SUBTYPE_RATE 1 -+#define BCMILCP_SUBTYPE_LINK 2 -+#define BCMILCP_SUBTYPE_CSA 3 -+#define BCMILCP_SUBTYPE_LARQ 4 -+#define BCMILCP_SUBTYPE_VENDOR 5 -+#define BCMILCP_SUBTYPE_FLH 17 -+ -+#define BCMILCP_SUBTYPE_VENDOR_LONG 32769 -+#define BCMILCP_SUBTYPE_CERT 32770 -+#define BCMILCP_SUBTYPE_SES 32771 -+ -+ -+#define BCMILCP_BCM_SUBTYPE_RESERVED 0 -+#define BCMILCP_BCM_SUBTYPE_EVENT 1 -+#define BCMILCP_BCM_SUBTYPE_SES 2 -+/* -+ * The EAPOL type is not used anymore. Instead EAPOL messages are now embedded -+ * within BCMILCP_BCM_SUBTYPE_EVENT type messages -+ */ -+/* #define BCMILCP_BCM_SUBTYPE_EAPOL 3 */ -+#define BCMILCP_BCM_SUBTYPE_DPT 4 -+ -+#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH 8 -+#define BCMILCP_BCM_SUBTYPEHDR_VERSION 0 -+ -+/* These fields are stored in network order */ -+typedef BWL_PRE_PACKED_STRUCT struct bcmeth_hdr -+{ -+ uint16 subtype; /* Vendor specific..32769 */ -+ uint16 length; -+ uint8 version; /* Version is 0 */ -+ uint8 oui[3]; /* Broadcom OUI */ -+ /* user specific Data */ -+ uint16 usr_subtype; -+} BWL_POST_PACKED_STRUCT bcmeth_hdr_t; -+ -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _BCMETH_H_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmevent.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmevent.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmevent.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmevent.h 2017-11-09 17:53:43.988295000 +0800 -@@ -0,0 +1,313 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom Event protocol definitions -+ * -+ * Dependencies: proto/bcmeth.h -+ * -+ * $Id: bcmevent.h 315348 2012-02-16 07:32:51Z $ -+ * -+ */ -+ -+/* -+ * Broadcom Ethernet Events protocol defines -+ * -+ */ -+ -+#ifndef _BCMEVENT_H_ -+#define _BCMEVENT_H_ -+ -+#ifndef _TYPEDEFS_H_ -+#include -+#endif -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+#define BCM_EVENT_MSG_VERSION 2 /* wl_event_msg_t struct version */ -+#define BCM_MSG_IFNAME_MAX 16 /* max length of interface name */ -+ -+/* flags */ -+#define WLC_EVENT_MSG_LINK 0x01 /* link is up */ -+#define WLC_EVENT_MSG_FLUSHTXQ 0x02 /* flush tx queue on MIC error */ -+#define WLC_EVENT_MSG_GROUP 0x04 /* group MIC error */ -+#define WLC_EVENT_MSG_UNKBSS 0x08 /* unknown source bsscfg */ -+#define WLC_EVENT_MSG_UNKIF 0x10 /* unknown source OS i/f */ -+ -+/* these fields are stored in network order */ -+ -+/* version 1 */ -+typedef BWL_PRE_PACKED_STRUCT struct -+{ -+ uint16 version; -+ uint16 flags; /* see flags below */ -+ uint32 event_type; /* Message (see below) */ -+ uint32 status; /* Status code (see below) */ -+ uint32 reason; /* Reason code (if applicable) */ -+ uint32 auth_type; /* WLC_E_AUTH */ -+ uint32 datalen; /* data buf */ -+ struct ether_addr addr; /* Station address (if applicable) */ -+ char ifname[BCM_MSG_IFNAME_MAX]; /* name of the packet incoming interface */ -+} BWL_POST_PACKED_STRUCT wl_event_msg_v1_t; -+ -+/* the current version */ -+typedef BWL_PRE_PACKED_STRUCT struct -+{ -+ uint16 version; -+ uint16 flags; /* see flags below */ -+ uint32 event_type; /* Message (see below) */ -+ uint32 status; /* Status code (see below) */ -+ uint32 reason; /* Reason code (if applicable) */ -+ uint32 auth_type; /* WLC_E_AUTH */ -+ uint32 datalen; /* data buf */ -+ struct ether_addr addr; /* Station address (if applicable) */ -+ char ifname[BCM_MSG_IFNAME_MAX]; /* name of the packet incoming interface */ -+ uint8 ifidx; /* destination OS i/f index */ -+ uint8 bsscfgidx; /* source bsscfg index */ -+} BWL_POST_PACKED_STRUCT wl_event_msg_t; -+ -+/* used by driver msgs */ -+typedef BWL_PRE_PACKED_STRUCT struct bcm_event { -+ struct ether_header eth; -+ bcmeth_hdr_t bcm_hdr; -+ wl_event_msg_t event; -+ /* data portion follows */ -+} BWL_POST_PACKED_STRUCT bcm_event_t; -+ -+#define BCM_MSG_LEN (sizeof(bcm_event_t) - sizeof(bcmeth_hdr_t) - sizeof(struct ether_header)) -+ -+/* Event messages */ -+#define WLC_E_SET_SSID 0 /* indicates status of set SSID */ -+#define WLC_E_JOIN 1 /* differentiates join IBSS from found (WLC_E_START) IBSS */ -+#define WLC_E_START 2 /* STA founded an IBSS or AP started a BSS */ -+#define WLC_E_AUTH 3 /* 802.11 AUTH request */ -+#define WLC_E_AUTH_IND 4 /* 802.11 AUTH indication */ -+#define WLC_E_DEAUTH 5 /* 802.11 DEAUTH request */ -+#define WLC_E_DEAUTH_IND 6 /* 802.11 DEAUTH indication */ -+#define WLC_E_ASSOC 7 /* 802.11 ASSOC request */ -+#define WLC_E_ASSOC_IND 8 /* 802.11 ASSOC indication */ -+#define WLC_E_REASSOC 9 /* 802.11 REASSOC request */ -+#define WLC_E_REASSOC_IND 10 /* 802.11 REASSOC indication */ -+#define WLC_E_DISASSOC 11 /* 802.11 DISASSOC request */ -+#define WLC_E_DISASSOC_IND 12 /* 802.11 DISASSOC indication */ -+#define WLC_E_QUIET_START 13 /* 802.11h Quiet period started */ -+#define WLC_E_QUIET_END 14 /* 802.11h Quiet period ended */ -+#define WLC_E_BEACON_RX 15 /* BEACONS received/lost indication */ -+#define WLC_E_LINK 16 /* generic link indication */ -+#define WLC_E_MIC_ERROR 17 /* TKIP MIC error occurred */ -+#define WLC_E_NDIS_LINK 18 /* NDIS style link indication */ -+#define WLC_E_ROAM 19 /* roam attempt occurred: indicate status & reason */ -+#define WLC_E_TXFAIL 20 /* change in dot11FailedCount (txfail) */ -+#define WLC_E_PMKID_CACHE 21 /* WPA2 pmkid cache indication */ -+#define WLC_E_RETROGRADE_TSF 22 /* current AP's TSF value went backward */ -+#define WLC_E_PRUNE 23 /* AP was pruned from join list for reason */ -+#define WLC_E_AUTOAUTH 24 /* report AutoAuth table entry match for join attempt */ -+#define WLC_E_EAPOL_MSG 25 /* Event encapsulating an EAPOL message */ -+#define WLC_E_SCAN_COMPLETE 26 /* Scan results are ready or scan was aborted */ -+#define WLC_E_ADDTS_IND 27 /* indicate to host addts fail/success */ -+#define WLC_E_DELTS_IND 28 /* indicate to host delts fail/success */ -+#define WLC_E_BCNSENT_IND 29 /* indicate to host of beacon transmit */ -+#define WLC_E_BCNRX_MSG 30 /* Send the received beacon up to the host */ -+#define WLC_E_BCNLOST_MSG 31 /* indicate to host loss of beacon */ -+#define WLC_E_ROAM_PREP 32 /* before attempting to roam */ -+#define WLC_E_PFN_NET_FOUND 33 /* PFN network found event */ -+#define WLC_E_PFN_NET_LOST 34 /* PFN network lost event */ -+#define WLC_E_RESET_COMPLETE 35 -+#define WLC_E_JOIN_START 36 -+#define WLC_E_ROAM_START 37 -+#define WLC_E_ASSOC_START 38 -+#define WLC_E_IBSS_ASSOC 39 -+#define WLC_E_RADIO 40 -+#define WLC_E_PSM_WATCHDOG 41 /* PSM microcode watchdog fired */ -+#define WLC_E_PROBREQ_MSG 44 /* probe request received */ -+#define WLC_E_SCAN_CONFIRM_IND 45 -+#define WLC_E_PSK_SUP 46 /* WPA Handshake fail */ -+#define WLC_E_COUNTRY_CODE_CHANGED 47 -+#define WLC_E_EXCEEDED_MEDIUM_TIME 48 /* WMMAC excedded medium time */ -+#define WLC_E_ICV_ERROR 49 /* WEP ICV error occurred */ -+#define WLC_E_UNICAST_DECODE_ERROR 50 /* Unsupported unicast encrypted frame */ -+#define WLC_E_MULTICAST_DECODE_ERROR 51 /* Unsupported multicast encrypted frame */ -+#define WLC_E_TRACE 52 -+#define WLC_E_IF 54 /* I/F change (for dongle host notification) */ -+#define WLC_E_P2P_DISC_LISTEN_COMPLETE 55 /* listen state expires */ -+#define WLC_E_RSSI 56 /* indicate RSSI change based on configured levels */ -+#define WLC_E_PFN_SCAN_COMPLETE 57 /* PFN completed scan of network list */ -+#define WLC_E_EXTLOG_MSG 58 -+#define WLC_E_ACTION_FRAME 59 /* Action frame Rx */ -+#define WLC_E_ACTION_FRAME_COMPLETE 60 /* Action frame Tx complete */ -+#define WLC_E_PRE_ASSOC_IND 61 /* assoc request received */ -+#define WLC_E_PRE_REASSOC_IND 62 /* re-assoc request received */ -+#define WLC_E_CHANNEL_ADOPTED 63 -+#define WLC_E_AP_STARTED 64 /* AP started */ -+#define WLC_E_DFS_AP_STOP 65 /* AP stopped due to DFS */ -+#define WLC_E_DFS_AP_RESUME 66 /* AP resumed due to DFS */ -+#define WLC_E_WAI_STA_EVENT 67 /* WAI stations event */ -+#define WLC_E_WAI_MSG 68 /* event encapsulating an WAI message */ -+#define WLC_E_ESCAN_RESULT 69 /* escan result event */ -+#define WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70 /* action frame off channel complete */ -+#define WLC_E_PROBRESP_MSG 71 /* probe response received */ -+#define WLC_E_P2P_PROBREQ_MSG 72 /* P2P Probe request received */ -+#define WLC_E_DCS_REQUEST 73 -+ -+#define WLC_E_FIFO_CREDIT_MAP 74 /* credits for D11 FIFOs. [AC0,AC1,AC2,AC3,BC_MC,ATIM] */ -+ -+#define WLC_E_ACTION_FRAME_RX 75 /* Received action frame event WITH -+ * wl_event_rx_frame_data_t header -+ */ -+#define WLC_E_WAKE_EVENT 76 /* Wake Event timer fired, used for wake WLAN test mode */ -+#define WLC_E_RM_COMPLETE 77 /* Radio measurement complete */ -+#define WLC_E_HTSFSYNC 78 /* Synchronize TSF with the host */ -+#define WLC_E_OVERLAY_REQ 79 /* request an overlay IOCTL/iovar from the host */ -+#define WLC_E_CSA_COMPLETE_IND 80 /* 802.11 CHANNEL SWITCH ACTION completed */ -+#define WLC_E_EXCESS_PM_WAKE_EVENT 81 /* excess PM Wake Event to inform host */ -+#define WLC_E_PFN_SCAN_NONE 82 /* no PFN networks around */ -+#define WLC_E_PFN_SCAN_ALLGONE 83 /* last found PFN network gets lost */ -+#define WLC_E_GTK_PLUMBED 84 -+#define WLC_E_ASSOC_IND_NDIS 85 /* 802.11 ASSOC indication for NDIS only */ -+#define WLC_E_REASSOC_IND_NDIS 86 /* 802.11 REASSOC indication for NDIS only */ -+#define WLC_E_ASSOC_REQ_IE 87 -+#define WLC_E_ASSOC_RESP_IE 88 -+ -+#define WLC_E_LAST 89 /* highest val + 1 for range checking */ -+ -+/* Table of event name strings for UIs and debugging dumps */ -+typedef struct { -+ uint event; -+ const char *name; -+} bcmevent_name_t; -+ -+extern const bcmevent_name_t bcmevent_names[]; -+extern const int bcmevent_names_size; -+ -+/* Event status codes */ -+#define WLC_E_STATUS_SUCCESS 0 /* operation was successful */ -+#define WLC_E_STATUS_FAIL 1 /* operation failed */ -+#define WLC_E_STATUS_TIMEOUT 2 /* operation timed out */ -+#define WLC_E_STATUS_NO_NETWORKS 3 /* failed due to no matching network found */ -+#define WLC_E_STATUS_ABORT 4 /* operation was aborted */ -+#define WLC_E_STATUS_NO_ACK 5 /* protocol failure: packet not ack'd */ -+#define WLC_E_STATUS_UNSOLICITED 6 /* AUTH or ASSOC packet was unsolicited */ -+#define WLC_E_STATUS_ATTEMPT 7 /* attempt to assoc to an auto auth configuration */ -+#define WLC_E_STATUS_PARTIAL 8 /* scan results are incomplete */ -+#define WLC_E_STATUS_NEWSCAN 9 /* scan aborted by another scan */ -+#define WLC_E_STATUS_NEWASSOC 10 /* scan aborted due to assoc in progress */ -+#define WLC_E_STATUS_11HQUIET 11 /* 802.11h quiet period started */ -+#define WLC_E_STATUS_SUPPRESS 12 /* user disabled scanning (WLC_SET_SCANSUPPRESS) */ -+#define WLC_E_STATUS_NOCHANS 13 /* no allowable channels to scan */ -+#define WLC_E_STATUS_CS_ABORT 15 /* abort channel select */ -+#define WLC_E_STATUS_ERROR 16 /* request failed due to error */ -+ -+/* roam reason codes */ -+#define WLC_E_REASON_INITIAL_ASSOC 0 /* initial assoc */ -+#define WLC_E_REASON_LOW_RSSI 1 /* roamed due to low RSSI */ -+#define WLC_E_REASON_DEAUTH 2 /* roamed due to DEAUTH indication */ -+#define WLC_E_REASON_DISASSOC 3 /* roamed due to DISASSOC indication */ -+#define WLC_E_REASON_BCNS_LOST 4 /* roamed due to lost beacons */ -+#define WLC_E_REASON_MINTXRATE 9 /* roamed because at mintxrate for too long */ -+#define WLC_E_REASON_TXFAIL 10 /* We can hear AP, but AP can't hear us */ -+ -+/* Roam codes used primarily by CCX */ -+#define WLC_E_REASON_FAST_ROAM_FAILED 5 /* roamed due to fast roam failure */ -+#define WLC_E_REASON_DIRECTED_ROAM 6 /* roamed due to request by AP */ -+#define WLC_E_REASON_TSPEC_REJECTED 7 /* roamed due to TSPEC rejection */ -+#define WLC_E_REASON_BETTER_AP 8 /* roamed due to finding better AP */ -+ -+#define WLC_E_REASON_REQUESTED_ROAM 11 /* roamed due to BSS Mgmt Transition request by AP */ -+ -+/* prune reason codes */ -+#define WLC_E_PRUNE_ENCR_MISMATCH 1 /* encryption mismatch */ -+#define WLC_E_PRUNE_BCAST_BSSID 2 /* AP uses a broadcast BSSID */ -+#define WLC_E_PRUNE_MAC_DENY 3 /* STA's MAC addr is in AP's MAC deny list */ -+#define WLC_E_PRUNE_MAC_NA 4 /* STA's MAC addr is not in AP's MAC allow list */ -+#define WLC_E_PRUNE_REG_PASSV 5 /* AP not allowed due to regulatory restriction */ -+#define WLC_E_PRUNE_SPCT_MGMT 6 /* AP does not support STA locale spectrum mgmt */ -+#define WLC_E_PRUNE_RADAR 7 /* AP is on a radar channel of STA locale */ -+#define WLC_E_RSN_MISMATCH 8 /* STA does not support AP's RSN */ -+#define WLC_E_PRUNE_NO_COMMON_RATES 9 /* No rates in common with AP */ -+#define WLC_E_PRUNE_BASIC_RATES 10 /* STA does not support all basic rates of BSS */ -+#define WLC_E_PRUNE_CIPHER_NA 12 /* BSS's cipher not supported */ -+#define WLC_E_PRUNE_KNOWN_STA 13 /* AP is already known to us as a STA */ -+#define WLC_E_PRUNE_WDS_PEER 15 /* AP is already known to us as a WDS peer */ -+#define WLC_E_PRUNE_QBSS_LOAD 16 /* QBSS LOAD - AAC is too low */ -+#define WLC_E_PRUNE_HOME_AP 17 /* prune home AP */ -+ -+/* WPA failure reason codes carried in the WLC_E_PSK_SUP event */ -+#define WLC_E_SUP_OTHER 0 /* Other reason */ -+#define WLC_E_SUP_DECRYPT_KEY_DATA 1 /* Decryption of key data failed */ -+#define WLC_E_SUP_BAD_UCAST_WEP128 2 /* Illegal use of ucast WEP128 */ -+#define WLC_E_SUP_BAD_UCAST_WEP40 3 /* Illegal use of ucast WEP40 */ -+#define WLC_E_SUP_UNSUP_KEY_LEN 4 /* Unsupported key length */ -+#define WLC_E_SUP_PW_KEY_CIPHER 5 /* Unicast cipher mismatch in pairwise key */ -+#define WLC_E_SUP_MSG3_TOO_MANY_IE 6 /* WPA IE contains > 1 RSN IE in key msg 3 */ -+#define WLC_E_SUP_MSG3_IE_MISMATCH 7 /* WPA IE mismatch in key message 3 */ -+#define WLC_E_SUP_NO_INSTALL_FLAG 8 /* INSTALL flag unset in 4-way msg */ -+#define WLC_E_SUP_MSG3_NO_GTK 9 /* encapsulated GTK missing from msg 3 */ -+#define WLC_E_SUP_GRP_KEY_CIPHER 10 /* Multicast cipher mismatch in group key */ -+#define WLC_E_SUP_GRP_MSG1_NO_GTK 11 /* encapsulated GTK missing from group msg 1 */ -+#define WLC_E_SUP_GTK_DECRYPT_FAIL 12 /* GTK decrypt failure */ -+#define WLC_E_SUP_SEND_FAIL 13 /* message send failure */ -+#define WLC_E_SUP_DEAUTH 14 /* received FC_DEAUTH */ -+#define WLC_E_SUP_WPA_PSK_TMO 15 /* WPA PSK 4-way handshake timeout */ -+ -+/* Event data for events that include frames received over the air */ -+/* WLC_E_PROBRESP_MSG -+ * WLC_E_P2P_PROBREQ_MSG -+ * WLC_E_ACTION_FRAME_RX -+ */ -+typedef BWL_PRE_PACKED_STRUCT struct wl_event_rx_frame_data { -+ uint16 version; -+ uint16 channel; /* Matches chanspec_t format from bcmwifi_channels.h */ -+ int32 rssi; -+ uint32 mactime; -+ uint32 rate; -+} BWL_POST_PACKED_STRUCT wl_event_rx_frame_data_t; -+ -+#define BCM_RX_FRAME_DATA_VERSION 1 -+ -+/* WLC_E_IF event data */ -+typedef struct wl_event_data_if { -+ uint8 ifidx; /* RTE virtual device index (for dongle) */ -+ uint8 opcode; /* see I/F opcode */ -+ uint8 reserved; -+ uint8 bssidx; /* bsscfg index */ -+ uint8 role; /* see I/F role */ -+} wl_event_data_if_t; -+ -+/* opcode in WLC_E_IF event */ -+#define WLC_E_IF_ADD 1 /* bsscfg add */ -+#define WLC_E_IF_DEL 2 /* bsscfg delete */ -+#define WLC_E_IF_CHANGE 3 /* bsscfg role change */ -+ -+/* I/F role code in WLC_E_IF event */ -+#define WLC_E_IF_ROLE_STA 0 /* Infra STA */ -+#define WLC_E_IF_ROLE_AP 1 /* Access Point */ -+#define WLC_E_IF_ROLE_WDS 2 /* WDS link */ -+#define WLC_E_IF_ROLE_P2P_GO 3 /* P2P Group Owner */ -+#define WLC_E_IF_ROLE_P2P_CLIENT 4 /* P2P Client */ -+ -+/* Reason codes for LINK */ -+#define WLC_E_LINK_BCN_LOSS 1 /* Link down because of beacon loss */ -+#define WLC_E_LINK_DISASSOC 2 /* Link down because of disassoc */ -+#define WLC_E_LINK_ASSOC_REC 3 /* Link down because assoc recreate failed */ -+#define WLC_E_LINK_BSSCFG_DIS 4 /* Link down due to bsscfg down */ -+ -+/* reason codes for WLC_E_OVERLAY_REQ event */ -+#define WLC_E_OVL_DOWNLOAD 0 /* overlay download request */ -+#define WLC_E_OVL_UPDATE_IND 1 /* device indication of host overlay update */ -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _BCMEVENT_H_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmip.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmip.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmip.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmip.h 2017-11-09 17:53:43.989292000 +0800 -@@ -0,0 +1,205 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Fundamental constants relating to IP Protocol -+ * -+ * $Id: bcmip.h 324300 2012-03-28 20:29:37Z $ -+ */ -+ -+#ifndef _bcmip_h_ -+#define _bcmip_h_ -+ -+#ifndef _TYPEDEFS_H_ -+#include -+#endif -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+ -+/* IPV4 and IPV6 common */ -+#define IP_VER_OFFSET 0x0 /* offset to version field */ -+#define IP_VER_MASK 0xf0 /* version mask */ -+#define IP_VER_SHIFT 4 /* version shift */ -+#define IP_VER_4 4 /* version number for IPV4 */ -+#define IP_VER_6 6 /* version number for IPV6 */ -+ -+#define IP_VER(ip_body) \ -+ ((((uint8 *)(ip_body))[IP_VER_OFFSET] & IP_VER_MASK) >> IP_VER_SHIFT) -+ -+#define IP_PROT_ICMP 0x1 /* ICMP protocol */ -+#define IP_PROT_IGMP 0x2 /* IGMP protocol */ -+#define IP_PROT_TCP 0x6 /* TCP protocol */ -+#define IP_PROT_UDP 0x11 /* UDP protocol type */ -+#define IP_PROT_ICMP6 0x3a /* ICMPv6 protocol type */ -+ -+/* IPV4 field offsets */ -+#define IPV4_VER_HL_OFFSET 0 /* version and ihl byte offset */ -+#define IPV4_TOS_OFFSET 1 /* type of service offset */ -+#define IPV4_PKTLEN_OFFSET 2 /* packet length offset */ -+#define IPV4_PKTFLAG_OFFSET 6 /* more-frag,dont-frag flag offset */ -+#define IPV4_PROT_OFFSET 9 /* protocol type offset */ -+#define IPV4_CHKSUM_OFFSET 10 /* IP header checksum offset */ -+#define IPV4_SRC_IP_OFFSET 12 /* src IP addr offset */ -+#define IPV4_DEST_IP_OFFSET 16 /* dest IP addr offset */ -+#define IPV4_OPTIONS_OFFSET 20 /* IP options offset */ -+#define IPV4_MIN_HEADER_LEN 20 /* Minimum size for an IP header (no options) */ -+ -+/* IPV4 field decodes */ -+#define IPV4_VER_MASK 0xf0 /* IPV4 version mask */ -+#define IPV4_VER_SHIFT 4 /* IPV4 version shift */ -+ -+#define IPV4_HLEN_MASK 0x0f /* IPV4 header length mask */ -+#define IPV4_HLEN(ipv4_body) (4 * (((uint8 *)(ipv4_body))[IPV4_VER_HL_OFFSET] & IPV4_HLEN_MASK)) -+ -+#define IPV4_ADDR_LEN 4 /* IPV4 address length */ -+ -+#define IPV4_ADDR_NULL(a) ((((uint8 *)(a))[0] | ((uint8 *)(a))[1] | \ -+ ((uint8 *)(a))[2] | ((uint8 *)(a))[3]) == 0) -+ -+#define IPV4_ADDR_BCAST(a) ((((uint8 *)(a))[0] & ((uint8 *)(a))[1] & \ -+ ((uint8 *)(a))[2] & ((uint8 *)(a))[3]) == 0xff) -+ -+#define IPV4_TOS_DSCP_MASK 0xfc /* DiffServ codepoint mask */ -+#define IPV4_TOS_DSCP_SHIFT 2 /* DiffServ codepoint shift */ -+ -+#define IPV4_TOS(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_TOS_OFFSET]) -+ -+#define IPV4_TOS_PREC_MASK 0xe0 /* Historical precedence mask */ -+#define IPV4_TOS_PREC_SHIFT 5 /* Historical precedence shift */ -+ -+#define IPV4_TOS_LOWDELAY 0x10 /* Lowest delay requested */ -+#define IPV4_TOS_THROUGHPUT 0x8 /* Best throughput requested */ -+#define IPV4_TOS_RELIABILITY 0x4 /* Most reliable delivery requested */ -+ -+#define IPV4_PROT(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_PROT_OFFSET]) -+ -+#define IPV4_FRAG_RESV 0x8000 /* Reserved */ -+#define IPV4_FRAG_DONT 0x4000 /* Don't fragment */ -+#define IPV4_FRAG_MORE 0x2000 /* More fragments */ -+#define IPV4_FRAG_OFFSET_MASK 0x1fff /* Fragment offset */ -+ -+#define IPV4_ADDR_STR_LEN 16 /* Max IP address length in string format */ -+ -+/* IPV4 packet formats */ -+BWL_PRE_PACKED_STRUCT struct ipv4_addr { -+ uint8 addr[IPV4_ADDR_LEN]; -+} BWL_POST_PACKED_STRUCT; -+ -+BWL_PRE_PACKED_STRUCT struct ipv4_hdr { -+ uint8 version_ihl; /* Version and Internet Header Length */ -+ uint8 tos; /* Type Of Service */ -+ uint16 tot_len; /* Number of bytes in packet (max 65535) */ -+ uint16 id; -+ uint16 frag; /* 3 flag bits and fragment offset */ -+ uint8 ttl; /* Time To Live */ -+ uint8 prot; /* Protocol */ -+ uint16 hdr_chksum; /* IP header checksum */ -+ uint8 src_ip[IPV4_ADDR_LEN]; /* Source IP Address */ -+ uint8 dst_ip[IPV4_ADDR_LEN]; /* Destination IP Address */ -+} BWL_POST_PACKED_STRUCT; -+ -+/* IPV6 field offsets */ -+#define IPV6_PAYLOAD_LEN_OFFSET 4 /* payload length offset */ -+#define IPV6_NEXT_HDR_OFFSET 6 /* next header/protocol offset */ -+#define IPV6_HOP_LIMIT_OFFSET 7 /* hop limit offset */ -+#define IPV6_SRC_IP_OFFSET 8 /* src IP addr offset */ -+#define IPV6_DEST_IP_OFFSET 24 /* dst IP addr offset */ -+ -+/* IPV6 field decodes */ -+#define IPV6_TRAFFIC_CLASS(ipv6_body) \ -+ (((((uint8 *)(ipv6_body))[0] & 0x0f) << 4) | \ -+ ((((uint8 *)(ipv6_body))[1] & 0xf0) >> 4)) -+ -+#define IPV6_FLOW_LABEL(ipv6_body) \ -+ (((((uint8 *)(ipv6_body))[1] & 0x0f) << 16) | \ -+ (((uint8 *)(ipv6_body))[2] << 8) | \ -+ (((uint8 *)(ipv6_body))[3])) -+ -+#define IPV6_PAYLOAD_LEN(ipv6_body) \ -+ ((((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 0] << 8) | \ -+ ((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 1]) -+ -+#define IPV6_NEXT_HDR(ipv6_body) \ -+ (((uint8 *)(ipv6_body))[IPV6_NEXT_HDR_OFFSET]) -+ -+#define IPV6_PROT(ipv6_body) IPV6_NEXT_HDR(ipv6_body) -+ -+#define IPV6_ADDR_LEN 16 /* IPV6 address length */ -+ -+/* IPV4 TOS or IPV6 Traffic Classifier or 0 */ -+#define IP_TOS46(ip_body) \ -+ (IP_VER(ip_body) == IP_VER_4 ? IPV4_TOS(ip_body) : \ -+ IP_VER(ip_body) == IP_VER_6 ? IPV6_TRAFFIC_CLASS(ip_body) : 0) -+ -+/* IPV6 extension headers (options) */ -+#define IPV6_EXTHDR_HOP 0 -+#define IPV6_EXTHDR_ROUTING 43 -+#define IPV6_EXTHDR_FRAGMENT 44 -+#define IPV6_EXTHDR_AUTH 51 -+#define IPV6_EXTHDR_NONE 59 -+#define IPV6_EXTHDR_DEST 60 -+ -+#define IPV6_EXTHDR(prot) (((prot) == IPV6_EXTHDR_HOP) || \ -+ ((prot) == IPV6_EXTHDR_ROUTING) || \ -+ ((prot) == IPV6_EXTHDR_FRAGMENT) || \ -+ ((prot) == IPV6_EXTHDR_AUTH) || \ -+ ((prot) == IPV6_EXTHDR_NONE) || \ -+ ((prot) == IPV6_EXTHDR_DEST)) -+ -+#define IPV6_MIN_HLEN 40 -+ -+#define IPV6_EXTHDR_LEN(eh) ((((struct ipv6_exthdr *)(eh))->hdrlen + 1) << 3) -+ -+BWL_PRE_PACKED_STRUCT struct ipv6_exthdr { -+ uint8 nexthdr; -+ uint8 hdrlen; -+} BWL_POST_PACKED_STRUCT; -+ -+BWL_PRE_PACKED_STRUCT struct ipv6_exthdr_frag { -+ uint8 nexthdr; -+ uint8 rsvd; -+ uint16 frag_off; -+ uint32 ident; -+} BWL_POST_PACKED_STRUCT; -+ -+static INLINE int32 -+ipv6_exthdr_len(uint8 *h, uint8 *proto) -+{ -+ uint16 len = 0, hlen; -+ struct ipv6_exthdr *eh = (struct ipv6_exthdr *)h; -+ -+ while (IPV6_EXTHDR(eh->nexthdr)) { -+ if (eh->nexthdr == IPV6_EXTHDR_NONE) -+ return -1; -+ else if (eh->nexthdr == IPV6_EXTHDR_FRAGMENT) -+ hlen = 8; -+ else if (eh->nexthdr == IPV6_EXTHDR_AUTH) -+ hlen = (eh->hdrlen + 2) << 2; -+ else -+ hlen = IPV6_EXTHDR_LEN(eh); -+ -+ len += hlen; -+ eh = (struct ipv6_exthdr *)(h + len); -+ } -+ -+ *proto = eh->nexthdr; -+ return len; -+} -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _bcmip_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmipv6.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmipv6.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmipv6.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/bcmipv6.h 2017-11-09 17:53:43.990289000 +0800 -@@ -0,0 +1,101 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Fundamental constants relating to Neighbor Discovery Protocol -+ * -+ * $Id: bcmipv6.h 305568 2011-12-29 20:21:17Z $ -+ */ -+ -+#ifndef _bcmipv6_h_ -+#define _bcmipv6_h_ -+ -+#ifndef _TYPEDEFS_H_ -+#include -+#endif -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+#define ICMPV6_HEADER_TYPE 0x3A -+#define ICMPV6_PKT_TYPE_NS 135 -+#define ICMPV6_PKT_TYPE_NA 136 -+ -+#define ICMPV6_ND_OPT_TYPE_TARGET_MAC 2 -+#define ICMPV6_ND_OPT_TYPE_SRC_MAC 1 -+ -+#define IPV6_VERSION 6 -+#define IPV6_HOP_LIMIT 255 -+ -+#define IPV6_ADDR_NULL(a) ((a[0] | a[1] | a[2] | a[3] | a[4] | \ -+ a[5] | a[6] | a[7] | a[8] | a[9] | \ -+ a[10] | a[11] | a[12] | a[13] | \ -+ a[14] | a[15]) == 0) -+ -+/* IPV6 address */ -+BWL_PRE_PACKED_STRUCT struct ipv6_addr { -+ uint8 addr[16]; -+} BWL_POST_PACKED_STRUCT; -+ -+#ifndef IL_BIGENDIAN -+ -+/* ICMPV6 Header */ -+BWL_PRE_PACKED_STRUCT struct icmp6_hdr { -+ uint8 icmp6_type; -+ uint8 icmp6_code; -+ uint16 icmp6_cksum; -+ BWL_PRE_PACKED_STRUCT union { -+ uint32 reserved; -+ BWL_PRE_PACKED_STRUCT struct nd_advt { -+ uint32 reserved1:5, -+ override:1, -+ solicited:1, -+ router:1, -+ reserved2:24; -+ } BWL_POST_PACKED_STRUCT nd_advt; -+ } BWL_POST_PACKED_STRUCT opt; -+} BWL_POST_PACKED_STRUCT; -+ -+/* Ipv6 Header Format */ -+BWL_PRE_PACKED_STRUCT struct ipv6_hdr { -+ uint8 priority:4, -+ version:4; -+ uint8 flow_lbl[3]; -+ uint16 payload_len; -+ uint8 nexthdr; -+ uint8 hop_limit; -+ struct ipv6_addr saddr; -+ struct ipv6_addr daddr; -+} BWL_POST_PACKED_STRUCT; -+ -+/* Neighbor Advertisement/Solicitation Packet Structure */ -+BWL_PRE_PACKED_STRUCT struct nd_msg { -+ struct icmp6_hdr icmph; -+ struct ipv6_addr target; -+} BWL_POST_PACKED_STRUCT; -+ -+ -+/* Neighibor Solicitation/Advertisement Optional Structure */ -+BWL_PRE_PACKED_STRUCT struct nd_msg_opt { -+ uint8 type; -+ uint8 len; -+ uint8 mac_addr[ETHER_ADDR_LEN]; -+} BWL_POST_PACKED_STRUCT; -+ -+#endif /* IL_BIGENDIAN */ -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* !defined(_bcmipv6_h_) */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/ethernet.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/ethernet.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/ethernet.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/ethernet.h 2017-11-09 17:53:43.991291000 +0800 -@@ -0,0 +1,202 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * From FreeBSD 2.2.7: Fundamental constants relating to ethernet. -+ * -+ * $Id: ethernet.h 316696 2012-02-23 03:29:35Z $ -+ */ -+ -+#ifndef _NET_ETHERNET_H_ /* use native BSD ethernet.h when available */ -+#define _NET_ETHERNET_H_ -+ -+#ifndef _TYPEDEFS_H_ -+#include "typedefs.h" -+#endif -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+ -+/* -+ * The number of bytes in an ethernet (MAC) address. -+ */ -+#define ETHER_ADDR_LEN 6 -+ -+/* -+ * The number of bytes in the type field. -+ */ -+#define ETHER_TYPE_LEN 2 -+ -+/* -+ * The number of bytes in the trailing CRC field. -+ */ -+#define ETHER_CRC_LEN 4 -+ -+/* -+ * The length of the combined header. -+ */ -+#define ETHER_HDR_LEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN) -+ -+/* -+ * The minimum packet length. -+ */ -+#define ETHER_MIN_LEN 64 -+ -+/* -+ * The minimum packet user data length. -+ */ -+#define ETHER_MIN_DATA 46 -+ -+/* -+ * The maximum packet length. -+ */ -+#define ETHER_MAX_LEN 1518 -+ -+/* -+ * The maximum packet user data length. -+ */ -+#define ETHER_MAX_DATA 1500 -+ -+/* ether types */ -+#define ETHER_TYPE_MIN 0x0600 /* Anything less than MIN is a length */ -+#define ETHER_TYPE_IP 0x0800 /* IP */ -+#define ETHER_TYPE_ARP 0x0806 /* ARP */ -+#define ETHER_TYPE_8021Q 0x8100 /* 802.1Q */ -+#define ETHER_TYPE_IPV6 0x86dd /* IPv6 */ -+#define ETHER_TYPE_BRCM 0x886c /* Broadcom Corp. */ -+#define ETHER_TYPE_802_1X 0x888e /* 802.1x */ -+#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 /* 802.1x preauthentication */ -+#define ETHER_TYPE_WAI 0x88b4 /* WAI */ -+#define ETHER_TYPE_89_0D 0x890d /* 89-0d frame for TDLS */ -+ -+#define ETHER_TYPE_PPP_SES 0x8864 /* PPPoE Session */ -+ -+/* Broadcom subtype follows ethertype; First 2 bytes are reserved; Next 2 are subtype; */ -+#define ETHER_BRCM_SUBTYPE_LEN 4 /* Broadcom 4 byte subtype */ -+ -+/* ether header */ -+#define ETHER_DEST_OFFSET (0 * ETHER_ADDR_LEN) /* dest address offset */ -+#define ETHER_SRC_OFFSET (1 * ETHER_ADDR_LEN) /* src address offset */ -+#define ETHER_TYPE_OFFSET (2 * ETHER_ADDR_LEN) /* ether type offset */ -+ -+/* -+ * A macro to validate a length with -+ */ -+#define ETHER_IS_VALID_LEN(foo) \ -+ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) -+ -+#define ETHER_FILL_MCAST_ADDR_FROM_IP(ea, mgrp_ip) { \ -+ ((uint8 *)ea)[0] = 0x01; \ -+ ((uint8 *)ea)[1] = 0x00; \ -+ ((uint8 *)ea)[2] = 0x5e; \ -+ ((uint8 *)ea)[3] = ((mgrp_ip) >> 16) & 0x7f; \ -+ ((uint8 *)ea)[4] = ((mgrp_ip) >> 8) & 0xff; \ -+ ((uint8 *)ea)[5] = ((mgrp_ip) >> 0) & 0xff; \ -+} -+ -+#ifndef __INCif_etherh /* Quick and ugly hack for VxWorks */ -+/* -+ * Structure of a 10Mb/s Ethernet header. -+ */ -+BWL_PRE_PACKED_STRUCT struct ether_header { -+ uint8 ether_dhost[ETHER_ADDR_LEN]; -+ uint8 ether_shost[ETHER_ADDR_LEN]; -+ uint16 ether_type; -+} BWL_POST_PACKED_STRUCT; -+ -+/* -+ * Structure of a 48-bit Ethernet address. -+ */ -+BWL_PRE_PACKED_STRUCT struct ether_addr { -+ uint8 octet[ETHER_ADDR_LEN]; -+} BWL_POST_PACKED_STRUCT; -+#endif /* !__INCif_etherh Quick and ugly hack for VxWorks */ -+ -+/* -+ * Takes a pointer, set, test, clear, toggle locally admininistered -+ * address bit in the 48-bit Ethernet address. -+ */ -+#define ETHER_SET_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] | 2)) -+#define ETHER_IS_LOCALADDR(ea) (((uint8 *)(ea))[0] & 2) -+#define ETHER_CLR_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & 0xfd)) -+#define ETHER_TOGGLE_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] ^ 2)) -+ -+/* Takes a pointer, marks unicast address bit in the MAC address */ -+#define ETHER_SET_UNICAST(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & ~1)) -+ -+/* -+ * Takes a pointer, returns true if a 48-bit multicast address -+ * (including broadcast, since it is all ones) -+ */ -+#define ETHER_ISMULTI(ea) (((const uint8 *)(ea))[0] & 1) -+ -+/* Copy an ethernet address in reverse order */ -+#define ether_rcopy(s, d) \ -+do { \ -+ ((uint16 *)(d))[2] = ((uint16 *)(s))[2]; \ -+ ((uint16 *)(d))[1] = ((uint16 *)(s))[1]; \ -+ ((uint16 *)(d))[0] = ((uint16 *)(s))[0]; \ -+} while (0) -+ -+/* compare two ethernet addresses - assumes the pointers can be referenced as shorts */ -+#define eacmp(a, b) ((((uint16 *)(a))[0] ^ ((uint16 *)(b))[0]) | \ -+ (((uint16 *)(a))[1] ^ ((uint16 *)(b))[1]) | \ -+ (((uint16 *)(a))[2] ^ ((uint16 *)(b))[2])) -+ -+#define ether_cmp(a, b) eacmp(a, b) -+ -+/* copy an ethernet address - assumes the pointers can be referenced as shorts */ -+#define eacopy(s, d) \ -+do { \ -+ ((uint16 *)(d))[0] = ((const uint16 *)(s))[0]; \ -+ ((uint16 *)(d))[1] = ((const uint16 *)(s))[1]; \ -+ ((uint16 *)(d))[2] = ((const uint16 *)(s))[2]; \ -+} while (0) -+ -+#define ether_copy(s, d) eacopy(s, d) -+ -+ -+static const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}}; -+static const struct ether_addr ether_null = {{0, 0, 0, 0, 0, 0}}; -+ -+#define ETHER_ISBCAST(ea) ((((const uint8 *)(ea))[0] & \ -+ ((const uint8 *)(ea))[1] & \ -+ ((const uint8 *)(ea))[2] & \ -+ ((const uint8 *)(ea))[3] & \ -+ ((const uint8 *)(ea))[4] & \ -+ ((const uint8 *)(ea))[5]) == 0xff) -+#define ETHER_ISNULLADDR(ea) ((((const uint8 *)(ea))[0] | \ -+ ((const uint8 *)(ea))[1] | \ -+ ((const uint8 *)(ea))[2] | \ -+ ((const uint8 *)(ea))[3] | \ -+ ((const uint8 *)(ea))[4] | \ -+ ((const uint8 *)(ea))[5]) == 0) -+ -+#define ETHER_ISNULLDEST(da) ((((const uint16 *)(da))[0] | \ -+ ((const uint16 *)(da))[1] | \ -+ ((const uint16 *)(da))[2]) == 0) -+ -+ -+#define ETHER_MOVE_HDR(d, s) \ -+do { \ -+ struct ether_header t; \ -+ t = *(struct ether_header *)(s); \ -+ *(struct ether_header *)(d) = t; \ -+} while (0) -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _NET_ETHERNET_H_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/vlan.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/vlan.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/vlan.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/vlan.h 2017-11-09 17:53:43.991302000 +0800 -@@ -0,0 +1,67 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * 802.1Q VLAN protocol definitions -+ * -+ * $Id: vlan.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _vlan_h_ -+#define _vlan_h_ -+ -+#ifndef _TYPEDEFS_H_ -+#include -+#endif -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+#ifndef VLAN_VID_MASK -+#define VLAN_VID_MASK 0xfff /* low 12 bits are vlan id */ -+#endif -+#define VLAN_CFI_SHIFT 12 /* canonical format indicator bit */ -+#define VLAN_PRI_SHIFT 13 /* user priority */ -+ -+#define VLAN_PRI_MASK 7 /* 3 bits of priority */ -+ -+#define VLAN_TCI_OFFSET 14 /* offset of tag ctrl info field */ -+ -+#define VLAN_TAG_LEN 4 -+#define VLAN_TAG_OFFSET (2 * ETHER_ADDR_LEN) /* offset in Ethernet II packet only */ -+ -+#define VLAN_TPID 0x8100 /* VLAN ethertype/Tag Protocol ID */ -+ -+struct ethervlan_header { -+ uint8 ether_dhost[ETHER_ADDR_LEN]; -+ uint8 ether_shost[ETHER_ADDR_LEN]; -+ uint16 vlan_type; /* 0x8100 */ -+ uint16 vlan_tag; /* priority, cfi and vid */ -+ uint16 ether_type; -+}; -+ -+#define ETHERVLAN_HDR_LEN (ETHER_HDR_LEN + VLAN_TAG_LEN) -+ -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#define ETHERVLAN_MOVE_HDR(d, s) \ -+do { \ -+ struct ethervlan_header t; \ -+ t = *(struct ethervlan_header *)(s); \ -+ *(struct ethervlan_header *)(d) = t; \ -+} while (0) -+ -+#endif /* _vlan_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/proto/wpa.h b/drivers/net/ethernet/broadcom/gmac/src/include/proto/wpa.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/proto/wpa.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/proto/wpa.h 2017-11-09 17:53:43.992308000 +0800 -@@ -0,0 +1,169 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Fundamental types and constants relating to WPA -+ * -+ * $Id: wpa.h 261155 2011-05-23 23:51:32Z $ -+ */ -+ -+#ifndef _proto_wpa_h_ -+#define _proto_wpa_h_ -+ -+#include -+#include -+ -+ -+/* This marks the start of a packed structure section. */ -+#include -+ -+/* Reason Codes */ -+ -+/* 13 through 23 taken from IEEE Std 802.11i-2004 */ -+#define DOT11_RC_INVALID_WPA_IE 13 /* Invalid info. element */ -+#define DOT11_RC_MIC_FAILURE 14 /* Michael failure */ -+#define DOT11_RC_4WH_TIMEOUT 15 /* 4-way handshake timeout */ -+#define DOT11_RC_GTK_UPDATE_TIMEOUT 16 /* Group key update timeout */ -+#define DOT11_RC_WPA_IE_MISMATCH 17 /* WPA IE in 4-way handshake differs from -+ * (re-)assoc. request/probe response -+ */ -+#define DOT11_RC_INVALID_MC_CIPHER 18 /* Invalid multicast cipher */ -+#define DOT11_RC_INVALID_UC_CIPHER 19 /* Invalid unicast cipher */ -+#define DOT11_RC_INVALID_AKMP 20 /* Invalid authenticated key management protocol */ -+#define DOT11_RC_BAD_WPA_VERSION 21 /* Unsupported WPA version */ -+#define DOT11_RC_INVALID_WPA_CAP 22 /* Invalid WPA IE capabilities */ -+#define DOT11_RC_8021X_AUTH_FAIL 23 /* 802.1X authentication failure */ -+ -+#define WPA2_PMKID_LEN 16 -+ -+/* WPA IE fixed portion */ -+typedef BWL_PRE_PACKED_STRUCT struct -+{ -+ uint8 tag; /* TAG */ -+ uint8 length; /* TAG length */ -+ uint8 oui[3]; /* IE OUI */ -+ uint8 oui_type; /* OUI type */ -+ BWL_PRE_PACKED_STRUCT struct { -+ uint8 low; -+ uint8 high; -+ } BWL_POST_PACKED_STRUCT version; /* IE version */ -+} BWL_POST_PACKED_STRUCT wpa_ie_fixed_t; -+#define WPA_IE_OUITYPE_LEN 4 -+#define WPA_IE_FIXED_LEN 8 -+#define WPA_IE_TAG_FIXED_LEN 6 -+ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ uint8 tag; /* TAG */ -+ uint8 length; /* TAG length */ -+ BWL_PRE_PACKED_STRUCT struct { -+ uint8 low; -+ uint8 high; -+ } BWL_POST_PACKED_STRUCT version; /* IE version */ -+} BWL_POST_PACKED_STRUCT wpa_rsn_ie_fixed_t; -+#define WPA_RSN_IE_FIXED_LEN 4 -+#define WPA_RSN_IE_TAG_FIXED_LEN 2 -+typedef uint8 wpa_pmkid_t[WPA2_PMKID_LEN]; -+ -+/* WPA suite/multicast suite */ -+typedef BWL_PRE_PACKED_STRUCT struct -+{ -+ uint8 oui[3]; -+ uint8 type; -+} BWL_POST_PACKED_STRUCT wpa_suite_t, wpa_suite_mcast_t; -+#define WPA_SUITE_LEN 4 -+ -+/* WPA unicast suite list/key management suite list */ -+typedef BWL_PRE_PACKED_STRUCT struct -+{ -+ BWL_PRE_PACKED_STRUCT struct { -+ uint8 low; -+ uint8 high; -+ } BWL_POST_PACKED_STRUCT count; -+ wpa_suite_t list[1]; -+} BWL_POST_PACKED_STRUCT wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t; -+#define WPA_IE_SUITE_COUNT_LEN 2 -+typedef BWL_PRE_PACKED_STRUCT struct -+{ -+ BWL_PRE_PACKED_STRUCT struct { -+ uint8 low; -+ uint8 high; -+ } BWL_POST_PACKED_STRUCT count; -+ wpa_pmkid_t list[1]; -+} BWL_POST_PACKED_STRUCT wpa_pmkid_list_t; -+ -+/* WPA cipher suites */ -+#define WPA_CIPHER_NONE 0 /* None */ -+#define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */ -+#define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */ -+#define WPA_CIPHER_AES_OCB 3 /* AES (OCB) */ -+#define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */ -+#define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */ -+#define WPA_CIPHER_BIP 6 /* WEP (104-bit) */ -+#define WPA_CIPHER_TPK 7 /* Group addressed traffic not allowed */ -+ -+ -+#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \ -+ (cipher) == WPA_CIPHER_WEP_40 || \ -+ (cipher) == WPA_CIPHER_WEP_104 || \ -+ (cipher) == WPA_CIPHER_TKIP || \ -+ (cipher) == WPA_CIPHER_AES_OCB || \ -+ (cipher) == WPA_CIPHER_AES_CCM || \ -+ (cipher) == WPA_CIPHER_TPK) -+ -+ -+/* WPA TKIP countermeasures parameters */ -+#define WPA_TKIP_CM_DETECT 60 /* multiple MIC failure window (seconds) */ -+#define WPA_TKIP_CM_BLOCK 60 /* countermeasures active window (seconds) */ -+ -+/* RSN IE defines */ -+#define RSN_CAP_LEN 2 /* Length of RSN capabilities field (2 octets) */ -+ -+/* RSN Capabilities defined in 802.11i */ -+#define RSN_CAP_PREAUTH 0x0001 -+#define RSN_CAP_NOPAIRWISE 0x0002 -+#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C -+#define RSN_CAP_PTK_REPLAY_CNTR_SHIFT 2 -+#define RSN_CAP_GTK_REPLAY_CNTR_MASK 0x0030 -+#define RSN_CAP_GTK_REPLAY_CNTR_SHIFT 4 -+#define RSN_CAP_1_REPLAY_CNTR 0 -+#define RSN_CAP_2_REPLAY_CNTRS 1 -+#define RSN_CAP_4_REPLAY_CNTRS 2 -+#define RSN_CAP_16_REPLAY_CNTRS 3 -+#ifdef MFP -+#define RSN_CAP_MFPR 0x0040 -+#define RSN_CAP_MFPC 0x0080 -+#endif -+ -+/* WPA capabilities defined in 802.11i */ -+#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS -+#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS -+#define WPA_CAP_REPLAY_CNTR_SHIFT RSN_CAP_PTK_REPLAY_CNTR_SHIFT -+#define WPA_CAP_REPLAY_CNTR_MASK RSN_CAP_PTK_REPLAY_CNTR_MASK -+ -+/* WPA capabilities defined in 802.11zD9.0 */ -+#define WPA_CAP_PEER_KEY_ENABLE (0x1 << 1) /* bit 9 */ -+ -+/* WPA Specific defines */ -+#define WPA_CAP_LEN RSN_CAP_LEN /* Length of RSN capabilities in RSN IE (2 octets) */ -+#define WPA_PMKID_CNT_LEN 2 /* Length of RSN PMKID count (2 octests) */ -+ -+#define WPA_CAP_WPA2_PREAUTH RSN_CAP_PREAUTH -+ -+#define WPA2_PMKID_COUNT_LEN 2 -+ -+ -+/* This marks the end of a packed structure section. */ -+#include -+ -+#endif /* _proto_wpa_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/sbchipc.h b/drivers/net/ethernet/broadcom/gmac/src/include/sbchipc.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/sbchipc.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/sbchipc.h 2017-11-09 17:53:44.004291000 +0800 -@@ -0,0 +1,2515 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * SiliconBackplane Chipcommon core hardware definitions. -+ * -+ * The chipcommon core provides chip identification, SB control, -+ * JTAG, 0/1/2 UARTs, clock frequency control, a watchdog interrupt timer, -+ * GPIO interface, extbus, and support for serial and parallel flashes. -+ * -+ * $Id: sbchipc.h 328955 2012-04-23 09:06:12Z $ -+ */ -+ -+#ifndef _SBCHIPC_H -+#define _SBCHIPC_H -+ -+#ifndef _LANGUAGE_ASSEMBLY -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif /* PAD */ -+ -+typedef struct eci_prerev35 { -+ uint32 eci_output; -+ uint32 eci_control; -+ uint32 eci_inputlo; -+ uint32 eci_inputmi; -+ uint32 eci_inputhi; -+ uint32 eci_inputintpolaritylo; -+ uint32 eci_inputintpolaritymi; -+ uint32 eci_inputintpolarityhi; -+ uint32 eci_intmasklo; -+ uint32 eci_intmaskmi; -+ uint32 eci_intmaskhi; -+ uint32 eci_eventlo; -+ uint32 eci_eventmi; -+ uint32 eci_eventhi; -+ uint32 eci_eventmasklo; -+ uint32 eci_eventmaskmi; -+ uint32 eci_eventmaskhi; -+ uint32 PAD[3]; -+} eci_prerev35_t; -+ -+typedef struct eci_rev35 { -+ uint32 eci_outputlo; -+ uint32 eci_outputhi; -+ uint32 eci_controllo; -+ uint32 eci_controlhi; -+ uint32 eci_inputlo; -+ uint32 eci_inputhi; -+ uint32 eci_inputintpolaritylo; -+ uint32 eci_inputintpolarityhi; -+ uint32 eci_intmasklo; -+ uint32 eci_intmaskhi; -+ uint32 eci_eventlo; -+ uint32 eci_eventhi; -+ uint32 eci_eventmasklo; -+ uint32 eci_eventmaskhi; -+ uint32 eci_auxtx; -+ uint32 eci_auxrx; -+ uint32 eci_datatag; -+ uint32 eci_uartescvalue; -+ uint32 eci_autobaudctr; -+ uint32 eci_uartfifolevel; -+} eci_rev35_t; -+ -+typedef struct flash_config { -+ uint32 PAD[19]; -+ /* Flash struct configuration registers (0x18c) for BCM4706 (corerev = 31) */ -+ uint32 flashstrconfig; -+} flash_config_t; -+ -+typedef volatile struct { -+ uint32 chipid; /* 0x0 */ -+ uint32 capabilities; -+ uint32 corecontrol; /* corerev >= 1 */ -+ uint32 bist; -+ -+ /* OTP */ -+ uint32 otpstatus; /* 0x10, corerev >= 10 */ -+ uint32 otpcontrol; -+ uint32 otpprog; -+ uint32 otplayout; /* corerev >= 23 */ -+ -+ /* Interrupt control */ -+ uint32 intstatus; /* 0x20 */ -+ uint32 intmask; -+ -+ /* Chip specific regs */ -+ uint32 chipcontrol; /* 0x28, rev >= 11 */ -+ uint32 chipstatus; /* 0x2c, rev >= 11 */ -+ -+ /* Jtag Master */ -+ uint32 jtagcmd; /* 0x30, rev >= 10 */ -+ uint32 jtagir; -+ uint32 jtagdr; -+ uint32 jtagctrl; -+ -+ /* serial flash interface registers */ -+ uint32 flashcontrol; /* 0x40 */ -+ uint32 flashaddress; -+ uint32 flashdata; -+ uint32 otplayoutextension; /* rev >= 35 */ -+ -+ /* Silicon backplane configuration broadcast control */ -+ uint32 broadcastaddress; /* 0x50 */ -+ uint32 broadcastdata; -+ -+ /* gpio - cleared only by power-on-reset */ -+ uint32 gpiopullup; /* 0x58, corerev >= 20 */ -+ uint32 gpiopulldown; /* 0x5c, corerev >= 20 */ -+ uint32 gpioin; /* 0x60 */ -+ uint32 gpioout; /* 0x64 */ -+ uint32 gpioouten; /* 0x68 */ -+ uint32 gpiocontrol; /* 0x6C */ -+ uint32 gpiointpolarity; /* 0x70 */ -+ uint32 gpiointmask; /* 0x74 */ -+ -+ /* GPIO events corerev >= 11 */ -+ uint32 gpioevent; -+ uint32 gpioeventintmask; -+ -+ /* Watchdog timer */ -+ uint32 watchdog; /* 0x80 */ -+ -+ /* GPIO events corerev >= 11 */ -+ uint32 gpioeventintpolarity; -+ -+ /* GPIO based LED powersave registers corerev >= 16 */ -+ uint32 gpiotimerval; /* 0x88 */ -+ uint32 gpiotimeroutmask; -+ -+ /* clock control */ -+ uint32 clockcontrol_n; /* 0x90 */ -+ uint32 clockcontrol_sb; /* aka m0 */ -+ uint32 clockcontrol_pci; /* aka m1 */ -+ uint32 clockcontrol_m2; /* mii/uart/mipsref */ -+ uint32 clockcontrol_m3; /* cpu */ -+ uint32 clkdiv; /* corerev >= 3 */ -+ uint32 gpiodebugsel; /* corerev >= 28 */ -+ uint32 capabilities_ext; /* 0xac */ -+ -+ /* pll delay registers (corerev >= 4) */ -+ uint32 pll_on_delay; /* 0xb0 */ -+ uint32 fref_sel_delay; -+ uint32 slow_clk_ctl; /* 5 < corerev < 10 */ -+ uint32 PAD; -+ -+ /* Instaclock registers (corerev >= 10) */ -+ uint32 system_clk_ctl; /* 0xc0 */ -+ uint32 clkstatestretch; -+ uint32 PAD[2]; -+ -+ /* Indirect backplane access (corerev >= 22) */ -+ uint32 bp_addrlow; /* 0xd0 */ -+ uint32 bp_addrhigh; -+ uint32 bp_data; -+ uint32 PAD; -+ uint32 bp_indaccess; -+ /* SPI registers, corerev >= 37 */ -+ uint32 gsioctrl; -+ uint32 gsioaddress; -+ uint32 gsiodata; -+ -+ /* More clock dividers (corerev >= 32) */ -+ uint32 clkdiv2; -+ /* FAB ID (corerev >= 40) */ -+ uint32 otpcontrol1; -+ uint32 fabid; /* 0xf8 */ -+ -+ /* In AI chips, pointer to erom */ -+ uint32 eromptr; /* 0xfc */ -+ -+ /* ExtBus control registers (corerev >= 3) */ -+ uint32 pcmcia_config; /* 0x100 */ -+ uint32 pcmcia_memwait; -+ uint32 pcmcia_attrwait; -+ uint32 pcmcia_iowait; -+ uint32 ide_config; -+ uint32 ide_memwait; -+ uint32 ide_attrwait; -+ uint32 ide_iowait; -+ uint32 prog_config; -+ uint32 prog_waitcount; -+ uint32 flash_config; -+ uint32 flash_waitcount; -+ uint32 SECI_config; /* 0x130 SECI configuration */ -+ uint32 SECI_status; -+ uint32 SECI_statusmask; -+ uint32 SECI_rxnibchanged; -+ -+ union { /* 0x140 */ -+ /* Enhanced Coexistence Interface (ECI) registers (corerev >= 21) */ -+ struct eci_prerev35 lt35; -+ struct eci_rev35 ge35; -+ /* Other interfaces */ -+ struct flash_config flashconf; -+ uint32 PAD[20]; -+ } eci; -+ -+ /* SROM interface (corerev >= 32) */ -+ uint32 sromcontrol; /* 0x190 */ -+ uint32 sromaddress; -+ uint32 sromdata; -+ uint32 PAD[1]; /* 0x19C */ -+ /* NAND flash registers for BCM4706 (corerev = 31) */ -+ uint32 nflashctrl; /* 0x1a0 */ -+ uint32 nflashconf; -+ uint32 nflashcoladdr; -+ uint32 nflashrowaddr; -+ uint32 nflashdata; -+ uint32 nflashwaitcnt0; /* 0x1b4 */ -+ uint32 PAD[2]; -+ -+ uint32 seci_uart_data; /* 0x1C0 */ -+ uint32 seci_uart_bauddiv; -+ uint32 seci_uart_fcr; -+ uint32 seci_uart_lcr; -+ uint32 seci_uart_mcr; -+ uint32 seci_uart_lsr; -+ uint32 seci_uart_msr; -+ uint32 seci_uart_baudadj; -+ /* Clock control and hardware workarounds (corerev >= 20) */ -+ uint32 clk_ctl_st; /* 0x1e0 */ -+ uint32 hw_war; -+ uint32 PAD[70]; -+ -+ /* UARTs */ -+ uint8 uart0data; /* 0x300 */ -+ uint8 uart0imr; -+ uint8 uart0fcr; -+ uint8 uart0lcr; -+ uint8 uart0mcr; -+ uint8 uart0lsr; -+ uint8 uart0msr; -+ uint8 uart0scratch; -+ uint8 PAD[248]; /* corerev >= 1 */ -+ -+ uint8 uart1data; /* 0x400 */ -+ uint8 uart1imr; -+ uint8 uart1fcr; -+ uint8 uart1lcr; -+ uint8 uart1mcr; -+ uint8 uart1lsr; -+ uint8 uart1msr; -+ uint8 uart1scratch; -+ uint32 PAD[126]; -+ -+ /* PMU registers (corerev >= 20) */ -+ /* Note: all timers driven by ILP clock are updated asynchronously to HT/ALP. -+ * The CPU must read them twice, compare, and retry if different. -+ */ -+ uint32 pmucontrol; /* 0x600 */ -+ uint32 pmucapabilities; -+ uint32 pmustatus; -+ uint32 res_state; -+ uint32 res_pending; -+ uint32 pmutimer; -+ uint32 min_res_mask; -+ uint32 max_res_mask; -+ uint32 res_table_sel; -+ uint32 res_dep_mask; -+ uint32 res_updn_timer; -+ uint32 res_timer; -+ uint32 clkstretch; -+ uint32 pmuwatchdog; -+ uint32 gpiosel; /* 0x638, rev >= 1 */ -+ uint32 gpioenable; /* 0x63c, rev >= 1 */ -+ uint32 res_req_timer_sel; -+ uint32 res_req_timer; -+ uint32 res_req_mask; -+ uint32 PAD; -+ uint32 chipcontrol_addr; /* 0x650 */ -+ uint32 chipcontrol_data; /* 0x654 */ -+ uint32 regcontrol_addr; -+ uint32 regcontrol_data; -+ uint32 pllcontrol_addr; -+ uint32 pllcontrol_data; -+ uint32 pmustrapopt; /* 0x668, corerev >= 28 */ -+ uint32 pmu_xtalfreq; /* 0x66C, pmurev >= 10 */ -+ uint32 PAD[100]; -+ uint16 sromotp[512]; /* 0x800 */ -+#ifdef NFLASH_SUPPORT -+ /* Nand flash MLC controller registers (corerev >= 38) */ -+ uint32 nand_revision; /* 0xC00 */ -+ uint32 nand_cmd_start; -+ uint32 nand_cmd_addr_x; -+ uint32 nand_cmd_addr; -+ uint32 nand_cmd_end_addr; -+ uint32 nand_cs_nand_select; -+ uint32 nand_cs_nand_xor; -+ uint32 PAD; -+ uint32 nand_spare_rd0; -+ uint32 nand_spare_rd4; -+ uint32 nand_spare_rd8; -+ uint32 nand_spare_rd12; -+ uint32 nand_spare_wr0; -+ uint32 nand_spare_wr4; -+ uint32 nand_spare_wr8; -+ uint32 nand_spare_wr12; -+ uint32 nand_acc_control; -+ uint32 PAD; -+ uint32 nand_config; -+ uint32 PAD; -+ uint32 nand_timing_1; -+ uint32 nand_timing_2; -+ uint32 nand_semaphore; -+ uint32 PAD; -+ uint32 nand_devid; -+ uint32 nand_devid_x; -+ uint32 nand_block_lock_status; -+ uint32 nand_intfc_status; -+ uint32 nand_ecc_corr_addr_x; -+ uint32 nand_ecc_corr_addr; -+ uint32 nand_ecc_unc_addr_x; -+ uint32 nand_ecc_unc_addr; -+ uint32 nand_read_error_count; -+ uint32 nand_corr_stat_threshold; -+ uint32 PAD[2]; -+ uint32 nand_read_addr_x; -+ uint32 nand_read_addr; -+ uint32 nand_page_program_addr_x; -+ uint32 nand_page_program_addr; -+ uint32 nand_copy_back_addr_x; -+ uint32 nand_copy_back_addr; -+ uint32 nand_block_erase_addr_x; -+ uint32 nand_block_erase_addr; -+ uint32 nand_inv_read_addr_x; -+ uint32 nand_inv_read_addr; -+ uint32 PAD[2]; -+ uint32 nand_blk_wr_protect; -+ uint32 PAD[3]; -+ uint32 nand_acc_control_cs1; -+ uint32 nand_config_cs1; -+ uint32 nand_timing_1_cs1; -+ uint32 nand_timing_2_cs1; -+ uint32 PAD[20]; -+ uint32 nand_spare_rd16; -+ uint32 nand_spare_rd20; -+ uint32 nand_spare_rd24; -+ uint32 nand_spare_rd28; -+ uint32 nand_cache_addr; -+ uint32 nand_cache_data; -+ uint32 nand_ctrl_config; -+ uint32 nand_ctrl_status; -+#endif /* NFLASH_SUPPORT */ -+ uint32 gci_corecaps0; /* GCI starting at 0xC00 */ -+ uint32 gci_corecaps1; -+ uint32 gci_corecaps2; -+ uint32 gci_corectrl; -+ uint32 gci_corestat; /* 0xC10 */ -+ uint32 PAD[11]; -+ uint32 gci_indirect_addr; /* 0xC40 */ -+ uint32 PAD[111]; -+ uint32 gci_chipctrl; /* 0xE00 */ -+} chipcregs_t; -+ -+#endif /* _LANGUAGE_ASSEMBLY */ -+ -+#if defined(IL_BIGENDIAN) && defined(BCMHND74K) -+/* Selective swapped defines for those registers we need in -+ * big-endian code. -+ */ -+#define CC_CHIPID 4 -+#define CC_CAPABILITIES 0 -+#define CC_CHIPST 0x28 -+#define CC_EROMPTR 0xf8 -+ -+#else /* !IL_BIGENDIAN || !BCMHND74K */ -+ -+#define CC_CHIPID 0 -+#define CC_CAPABILITIES 4 -+#define CC_CHIPST 0x2c -+#define CC_EROMPTR 0xfc -+ -+#endif /* IL_BIGENDIAN && BCMHND74K */ -+ -+#define CC_OTPST 0x10 -+#define CC_JTAGCMD 0x30 -+#define CC_JTAGIR 0x34 -+#define CC_JTAGDR 0x38 -+#define CC_JTAGCTRL 0x3c -+#define CC_GPIOPU 0x58 -+#define CC_GPIOPD 0x5c -+#define CC_GPIOIN 0x60 -+#define CC_GPIOOUT 0x64 -+#define CC_GPIOOUTEN 0x68 -+#define CC_GPIOCTRL 0x6c -+#define CC_GPIOPOL 0x70 -+#define CC_GPIOINTM 0x74 -+#define CC_WATCHDOG 0x80 -+#define CC_CLKC_N 0x90 -+#define CC_CLKC_M0 0x94 -+#define CC_CLKC_M1 0x98 -+#define CC_CLKC_M2 0x9c -+#define CC_CLKC_M3 0xa0 -+#define CC_CLKDIV 0xa4 -+#define CC_SYS_CLK_CTL 0xc0 -+#define CC_CLK_CTL_ST SI_CLK_CTL_ST -+#define PMU_CTL 0x600 -+#define PMU_CAP 0x604 -+#define PMU_ST 0x608 -+#define PMU_RES_STATE 0x60c -+#define PMU_TIMER 0x614 -+#define PMU_MIN_RES_MASK 0x618 -+#define PMU_MAX_RES_MASK 0x61c -+#define CC_CHIPCTL_ADDR 0x650 -+#define CC_CHIPCTL_DATA 0x654 -+#define PMU_REG_CONTROL_ADDR 0x658 -+#define PMU_REG_CONTROL_DATA 0x65C -+#define PMU_PLL_CONTROL_ADDR 0x660 -+#define PMU_PLL_CONTROL_DATA 0x664 -+#define CC_SROM_CTRL 0x190 -+#define CC_SROM_OTP 0x800 /* SROM/OTP address space */ -+#define CC_GCI_INDIRECT_ADDR_REG 0xC40 -+#define CC_GCI_CHIP_CTRL_REG 0xE00 -+#define CC_GCI_CC_OFFSET_2 2 -+#define CC_GCI_CC_OFFSET_5 5 -+ -+#ifdef NFLASH_SUPPORT -+/* NAND flash support */ -+#define CC_NAND_REVISION 0xC00 -+#define CC_NAND_CMD_START 0xC04 -+#define CC_NAND_CMD_ADDR 0xC0C -+#define CC_NAND_SPARE_RD_0 0xC20 -+#define CC_NAND_SPARE_RD_4 0xC24 -+#define CC_NAND_SPARE_RD_8 0xC28 -+#define CC_NAND_SPARE_RD_C 0xC2C -+#define CC_NAND_CONFIG 0xC48 -+#define CC_NAND_DEVID 0xC60 -+#define CC_NAND_DEVID_EXT 0xC64 -+#define CC_NAND_INTFC_STATUS 0xC6C -+#endif /* NFLASH_SUPPORT */ -+ -+/* chipid */ -+#define CID_ID_MASK 0x0000ffff /* Chip Id mask */ -+#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */ -+#define CID_REV_SHIFT 16 /* Chip Revision shift */ -+#define CID_PKG_MASK 0x00f00000 /* Package Option mask */ -+#define CID_PKG_SHIFT 20 /* Package Option shift */ -+#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */ -+#define CID_CC_SHIFT 24 -+#define CID_TYPE_MASK 0xf0000000 /* Chip Type */ -+#define CID_TYPE_SHIFT 28 -+ -+/* capabilities */ -+#define CC_CAP_UARTS_MASK 0x00000003 /* Number of UARTs */ -+#define CC_CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */ -+#define CC_CAP_UCLKSEL 0x00000018 /* UARTs clock select */ -+#define CC_CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */ -+#define CC_CAP_UARTGPIO 0x00000020 /* UARTs own GPIOs 15:12 */ -+#define CC_CAP_EXTBUS_MASK 0x000000c0 /* External bus mask */ -+#define CC_CAP_EXTBUS_NONE 0x00000000 /* No ExtBus present */ -+#define CC_CAP_EXTBUS_FULL 0x00000040 /* ExtBus: PCMCIA, IDE & Prog */ -+#define CC_CAP_EXTBUS_PROG 0x00000080 /* ExtBus: ProgIf only */ -+#define CC_CAP_FLASH_MASK 0x00000700 /* Type of flash */ -+#define CC_CAP_PLL_MASK 0x00038000 /* Type of PLL */ -+#define CC_CAP_PWR_CTL 0x00040000 /* Power control */ -+#define CC_CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */ -+#define CC_CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */ -+#define CC_CAP_OTPSIZE_BASE 5 /* OTP Size base */ -+#define CC_CAP_JTAGP 0x00400000 /* JTAG Master Present */ -+#define CC_CAP_ROM 0x00800000 /* Internal boot rom active */ -+#define CC_CAP_BKPLN64 0x08000000 /* 64-bit backplane */ -+#define CC_CAP_PMU 0x10000000 /* PMU Present, rev >= 20 */ -+#define CC_CAP_ECI 0x20000000 /* ECI Present, rev >= 21 */ -+#define CC_CAP_SROM 0x40000000 /* Srom Present, rev >= 32 */ -+#define CC_CAP_NFLASH 0x80000000 /* Nand flash present, rev >= 35 */ -+ -+#define CC_CAP2_SECI 0x00000001 /* SECI Present, rev >= 36 */ -+#define CC_CAP2_GSIO 0x00000002 /* GSIO (spi/i2c) present, rev >= 37 */ -+ -+/* capabilities extension */ -+#define CC_CAP_EXT_SECI_PRESENT 0x00000001 /* SECI present */ -+ -+/* PLL type */ -+#define PLL_NONE 0x00000000 -+#define PLL_TYPE1 0x00010000 /* 48MHz base, 3 dividers */ -+#define PLL_TYPE2 0x00020000 /* 48MHz, 4 dividers */ -+#define PLL_TYPE3 0x00030000 /* 25MHz, 2 dividers */ -+#define PLL_TYPE4 0x00008000 /* 48MHz, 4 dividers */ -+#define PLL_TYPE5 0x00018000 /* 25MHz, 4 dividers */ -+#define PLL_TYPE6 0x00028000 /* 100/200 or 120/240 only */ -+#define PLL_TYPE7 0x00038000 /* 25MHz, 4 dividers */ -+ -+/* ILP clock */ -+#define ILP_CLOCK 32000 -+ -+/* ALP clock on pre-PMU chips */ -+#define ALP_CLOCK 20000000 -+#define NS_ALP_CLOCK 125000000 -+#define NS_SLOW_ALP_CLOCK 100000000 -+#define NS_CPU_CLOCK 1000000000 -+#define NS_SLOW_CPU_CLOCK 800000000 -+#define NS_SI_CLOCK 250000000 -+#define NS_SLOW_SI_CLOCK 200000000 -+#define NS_FAST_MEM_CLOCK 800000000 -+#define NS_MEM_CLOCK 533000000 -+#define NS_SLOW_MEM_CLOCK 400000000 -+ -+/* HT clock */ -+#define HT_CLOCK 80000000 -+ -+/* corecontrol */ -+#define CC_UARTCLKO 0x00000001 /* Drive UART with internal clock */ -+#define CC_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ -+#define CC_ASYNCGPIO 0x00000004 /* 1=generate GPIO interrupt without backplane clock */ -+#define CC_UARTCLKEN 0x00000008 /* enable UART Clock (corerev > = 21 */ -+ -+/* 4321 chipcontrol */ -+#define CHIPCTRL_4321A0_DEFAULT 0x3a4 -+#define CHIPCTRL_4321A1_DEFAULT 0x0a4 -+#define CHIPCTRL_4321_PLL_DOWN 0x800000 /* serdes PLL down override */ -+ -+/* Fields in the otpstatus register in rev >= 21 */ -+#define OTPS_OL_MASK 0x000000ff -+#define OTPS_OL_MFG 0x00000001 /* manuf row is locked */ -+#define OTPS_OL_OR1 0x00000002 /* otp redundancy row 1 is locked */ -+#define OTPS_OL_OR2 0x00000004 /* otp redundancy row 2 is locked */ -+#define OTPS_OL_GU 0x00000008 /* general use region is locked */ -+#define OTPS_GUP_MASK 0x00000f00 -+#define OTPS_GUP_SHIFT 8 -+#define OTPS_GUP_HW 0x00000100 /* h/w subregion is programmed */ -+#define OTPS_GUP_SW 0x00000200 /* s/w subregion is programmed */ -+#define OTPS_GUP_CI 0x00000400 /* chipid/pkgopt subregion is programmed */ -+#define OTPS_GUP_FUSE 0x00000800 /* fuse subregion is programmed */ -+#define OTPS_READY 0x00001000 -+#define OTPS_RV(x) (1 << (16 + (x))) /* redundancy entry valid */ -+#define OTPS_RV_MASK 0x0fff0000 -+#define OTPS_PROGOK 0x40000000 -+ -+/* Fields in the otpcontrol register in rev >= 21 */ -+#define OTPC_PROGSEL 0x00000001 -+#define OTPC_PCOUNT_MASK 0x0000000e -+#define OTPC_PCOUNT_SHIFT 1 -+#define OTPC_VSEL_MASK 0x000000f0 -+#define OTPC_VSEL_SHIFT 4 -+#define OTPC_TMM_MASK 0x00000700 -+#define OTPC_TMM_SHIFT 8 -+#define OTPC_ODM 0x00000800 -+#define OTPC_PROGEN 0x80000000 -+ -+/* Fields in the 40nm otpcontrol register in rev >= 40 */ -+#define OTPC_40NM_PROGSEL_SHIFT 0 -+#define OTPC_40NM_PCOUNT_SHIFT 1 -+#define OTPC_40NM_PCOUNT_WR 0xA -+#define OTPC_40NM_PCOUNT_V1X 0xB -+#define OTPC_40NM_REGCSEL_SHIFT 5 -+#define OTPC_40NM_REGCSEL_DEF 0x4 -+#define OTPC_40NM_PROGIN_SHIFT 8 -+#define OTPC_40NM_R2X_SHIFT 10 -+#define OTPC_40NM_ODM_SHIFT 11 -+#define OTPC_40NM_DF_SHIFT 15 -+#define OTPC_40NM_VSEL_SHIFT 16 -+#define OTPC_40NM_VSEL_WR 0xA -+#define OTPC_40NM_VSEL_V1X 0xA -+#define OTPC_40NM_VSEL_R1X 0x5 -+#define OTPC_40NM_COFAIL_SHIFT 30 -+ -+#define OTPC1_CPCSEL_SHIFT 0 -+#define OTPC1_CPCSEL_DEF 6 -+#define OTPC1_TM_SHIFT 8 -+#define OTPC1_TM_WR 0x84 -+#define OTPC1_TM_V1X 0x84 -+#define OTPC1_TM_R1X 0x4 -+ -+/* Fields in otpprog in rev >= 21 and HND OTP */ -+#define OTPP_COL_MASK 0x000000ff -+#define OTPP_COL_SHIFT 0 -+#define OTPP_ROW_MASK 0x0000ff00 -+#define OTPP_ROW_SHIFT 8 -+#define OTPP_OC_MASK 0x0f000000 -+#define OTPP_OC_SHIFT 24 -+#define OTPP_READERR 0x10000000 -+#define OTPP_VALUE_MASK 0x20000000 -+#define OTPP_VALUE_SHIFT 29 -+#define OTPP_START_BUSY 0x80000000 -+#define OTPP_READ 0x40000000 /* HND OTP */ -+ -+/* Fields in otplayout register */ -+#define OTPL_HWRGN_OFF_MASK 0x00000FFF -+#define OTPL_HWRGN_OFF_SHIFT 0 -+#define OTPL_WRAP_REVID_MASK 0x00F80000 -+#define OTPL_WRAP_REVID_SHIFT 19 -+#define OTPL_WRAP_TYPE_MASK 0x00070000 -+#define OTPL_WRAP_TYPE_SHIFT 16 -+#define OTPL_WRAP_TYPE_65NM 0 -+#define OTPL_WRAP_TYPE_40NM 1 -+ -+/* otplayout reg corerev >= 36 */ -+#define OTP_CISFORMAT_NEW 0x80000000 -+ -+/* Opcodes for OTPP_OC field */ -+#define OTPPOC_READ 0 -+#define OTPPOC_BIT_PROG 1 -+#define OTPPOC_VERIFY 3 -+#define OTPPOC_INIT 4 -+#define OTPPOC_SET 5 -+#define OTPPOC_RESET 6 -+#define OTPPOC_OCST 7 -+#define OTPPOC_ROW_LOCK 8 -+#define OTPPOC_PRESCN_TEST 9 -+ -+/* Opcodes for OTPP_OC field (40NM) */ -+#define OTPPOC_READ_40NM 0 -+#define OTPPOC_PROG_ENABLE_40NM 1 -+#define OTPPOC_PROG_DISABLE_40NM 2 -+#define OTPPOC_VERIFY_40NM 3 -+#define OTPPOC_WORD_VERIFY_1_40NM 4 -+#define OTPPOC_ROW_LOCK_40NM 5 -+#define OTPPOC_STBY_40NM 6 -+#define OTPPOC_WAKEUP_40NM 7 -+#define OTPPOC_WORD_VERIFY_0_40NM 8 -+#define OTPPOC_PRESCN_TEST_40NM 9 -+#define OTPPOC_BIT_PROG_40NM 10 -+#define OTPPOC_WORDPROG_40NM 11 -+#define OTPPOC_BURNIN_40NM 12 -+#define OTPPOC_AUTORELOAD_40NM 13 -+#define OTPPOC_OVST_READ_40NM 14 -+#define OTPPOC_OVST_PROG_40NM 15 -+ -+/* Fields in otplayoutextension */ -+#define OTPLAYOUTEXT_FUSE_MASK 0x3FF -+ -+ -+/* Jtagm characteristics that appeared at a given corerev */ -+#define JTAGM_CREV_OLD 10 /* Old command set, 16bit max IR */ -+#define JTAGM_CREV_IRP 22 /* Able to do pause-ir */ -+#define JTAGM_CREV_RTI 28 /* Able to do return-to-idle */ -+ -+/* jtagcmd */ -+#define JCMD_START 0x80000000 -+#define JCMD_BUSY 0x80000000 -+#define JCMD_STATE_MASK 0x60000000 -+#define JCMD_STATE_TLR 0x00000000 /* Test-logic-reset */ -+#define JCMD_STATE_PIR 0x20000000 /* Pause IR */ -+#define JCMD_STATE_PDR 0x40000000 /* Pause DR */ -+#define JCMD_STATE_RTI 0x60000000 /* Run-test-idle */ -+#define JCMD0_ACC_MASK 0x0000f000 -+#define JCMD0_ACC_IRDR 0x00000000 -+#define JCMD0_ACC_DR 0x00001000 -+#define JCMD0_ACC_IR 0x00002000 -+#define JCMD0_ACC_RESET 0x00003000 -+#define JCMD0_ACC_IRPDR 0x00004000 -+#define JCMD0_ACC_PDR 0x00005000 -+#define JCMD0_IRW_MASK 0x00000f00 -+#define JCMD_ACC_MASK 0x000f0000 /* Changes for corerev 11 */ -+#define JCMD_ACC_IRDR 0x00000000 -+#define JCMD_ACC_DR 0x00010000 -+#define JCMD_ACC_IR 0x00020000 -+#define JCMD_ACC_RESET 0x00030000 -+#define JCMD_ACC_IRPDR 0x00040000 -+#define JCMD_ACC_PDR 0x00050000 -+#define JCMD_ACC_PIR 0x00060000 -+#define JCMD_ACC_IRDR_I 0x00070000 /* rev 28: return to run-test-idle */ -+#define JCMD_ACC_DR_I 0x00080000 /* rev 28: return to run-test-idle */ -+#define JCMD_IRW_MASK 0x00001f00 -+#define JCMD_IRW_SHIFT 8 -+#define JCMD_DRW_MASK 0x0000003f -+ -+/* jtagctrl */ -+#define JCTRL_FORCE_CLK 4 /* Force clock */ -+#define JCTRL_EXT_EN 2 /* Enable external targets */ -+#define JCTRL_EN 1 /* Enable Jtag master */ -+ -+/* Fields in clkdiv */ -+#define CLKD_SFLASH 0x0f000000 -+#define CLKD_SFLASH_SHIFT 24 -+#define CLKD_OTP 0x000f0000 -+#define CLKD_OTP_SHIFT 16 -+#define CLKD_JTAG 0x00000f00 -+#define CLKD_JTAG_SHIFT 8 -+#define CLKD_UART 0x000000ff -+ -+#define CLKD2_SROM 0x00000003 -+ -+/* intstatus/intmask */ -+#define CI_GPIO 0x00000001 /* gpio intr */ -+#define CI_EI 0x00000002 /* extif intr (corerev >= 3) */ -+#define CI_TEMP 0x00000004 /* temp. ctrl intr (corerev >= 15) */ -+#define CI_SIRQ 0x00000008 /* serial IRQ intr (corerev >= 15) */ -+#define CI_ECI 0x00000010 /* eci intr (corerev >= 21) */ -+#define CI_PMU 0x00000020 /* pmu intr (corerev >= 21) */ -+#define CI_UART 0x00000040 /* uart intr (corerev >= 21) */ -+#define CI_WDRESET 0x80000000 /* watchdog reset occurred */ -+ -+/* slow_clk_ctl */ -+#define SCC_SS_MASK 0x00000007 /* slow clock source mask */ -+#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */ -+#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */ -+#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */ -+#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ -+#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled, -+ * 0: LPO is enabled -+ */ -+#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, -+ * 0: power logic control -+ */ -+#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors -+ * PLL clock disable requests from core -+ */ -+#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't -+ * disable crystal when appropriate -+ */ -+#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */ -+#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */ -+#define SCC_CD_SHIFT 16 -+ -+/* system_clk_ctl */ -+#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */ -+#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */ -+#define SYCC_FP 0x00000004 /* ForcePLLOn */ -+#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */ -+#define SYCC_HR 0x00000010 /* Force HT */ -+#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */ -+#define SYCC_CD_SHIFT 16 -+ -+/* Indirect backplane access */ -+#define BPIA_BYTEEN 0x0000000f -+#define BPIA_SZ1 0x00000001 -+#define BPIA_SZ2 0x00000003 -+#define BPIA_SZ4 0x00000007 -+#define BPIA_SZ8 0x0000000f -+#define BPIA_WRITE 0x00000100 -+#define BPIA_START 0x00000200 -+#define BPIA_BUSY 0x00000200 -+#define BPIA_ERROR 0x00000400 -+ -+/* pcmcia/prog/flash_config */ -+#define CF_EN 0x00000001 /* enable */ -+#define CF_EM_MASK 0x0000000e /* mode */ -+#define CF_EM_SHIFT 1 -+#define CF_EM_FLASH 0 /* flash/asynchronous mode */ -+#define CF_EM_SYNC 2 /* synchronous mode */ -+#define CF_EM_PCMCIA 4 /* pcmcia mode */ -+#define CF_DS 0x00000010 /* destsize: 0=8bit, 1=16bit */ -+#define CF_BS 0x00000020 /* byteswap */ -+#define CF_CD_MASK 0x000000c0 /* clock divider */ -+#define CF_CD_SHIFT 6 -+#define CF_CD_DIV2 0x00000000 /* backplane/2 */ -+#define CF_CD_DIV3 0x00000040 /* backplane/3 */ -+#define CF_CD_DIV4 0x00000080 /* backplane/4 */ -+#define CF_CE 0x00000100 /* clock enable */ -+#define CF_SB 0x00000200 /* size/bytestrobe (synch only) */ -+ -+/* pcmcia_memwait */ -+#define PM_W0_MASK 0x0000003f /* waitcount0 */ -+#define PM_W1_MASK 0x00001f00 /* waitcount1 */ -+#define PM_W1_SHIFT 8 -+#define PM_W2_MASK 0x001f0000 /* waitcount2 */ -+#define PM_W2_SHIFT 16 -+#define PM_W3_MASK 0x1f000000 /* waitcount3 */ -+#define PM_W3_SHIFT 24 -+ -+/* pcmcia_attrwait */ -+#define PA_W0_MASK 0x0000003f /* waitcount0 */ -+#define PA_W1_MASK 0x00001f00 /* waitcount1 */ -+#define PA_W1_SHIFT 8 -+#define PA_W2_MASK 0x001f0000 /* waitcount2 */ -+#define PA_W2_SHIFT 16 -+#define PA_W3_MASK 0x1f000000 /* waitcount3 */ -+#define PA_W3_SHIFT 24 -+ -+/* pcmcia_iowait */ -+#define PI_W0_MASK 0x0000003f /* waitcount0 */ -+#define PI_W1_MASK 0x00001f00 /* waitcount1 */ -+#define PI_W1_SHIFT 8 -+#define PI_W2_MASK 0x001f0000 /* waitcount2 */ -+#define PI_W2_SHIFT 16 -+#define PI_W3_MASK 0x1f000000 /* waitcount3 */ -+#define PI_W3_SHIFT 24 -+ -+/* prog_waitcount */ -+#define PW_W0_MASK 0x0000001f /* waitcount0 */ -+#define PW_W1_MASK 0x00001f00 /* waitcount1 */ -+#define PW_W1_SHIFT 8 -+#define PW_W2_MASK 0x001f0000 /* waitcount2 */ -+#define PW_W2_SHIFT 16 -+#define PW_W3_MASK 0x1f000000 /* waitcount3 */ -+#define PW_W3_SHIFT 24 -+ -+#define PW_W0 0x0000000c -+#define PW_W1 0x00000a00 -+#define PW_W2 0x00020000 -+#define PW_W3 0x01000000 -+ -+/* flash_waitcount */ -+#define FW_W0_MASK 0x0000003f /* waitcount0 */ -+#define FW_W1_MASK 0x00001f00 /* waitcount1 */ -+#define FW_W1_SHIFT 8 -+#define FW_W2_MASK 0x001f0000 /* waitcount2 */ -+#define FW_W2_SHIFT 16 -+#define FW_W3_MASK 0x1f000000 /* waitcount3 */ -+#define FW_W3_SHIFT 24 -+ -+/* When Srom support present, fields in sromcontrol */ -+#define SRC_START 0x80000000 -+#define SRC_BUSY 0x80000000 -+#define SRC_OPCODE 0x60000000 -+#define SRC_OP_READ 0x00000000 -+#define SRC_OP_WRITE 0x20000000 -+#define SRC_OP_WRDIS 0x40000000 -+#define SRC_OP_WREN 0x60000000 -+#define SRC_OTPSEL 0x00000010 -+#define SRC_LOCK 0x00000008 -+#define SRC_SIZE_MASK 0x00000006 -+#define SRC_SIZE_1K 0x00000000 -+#define SRC_SIZE_4K 0x00000002 -+#define SRC_SIZE_16K 0x00000004 -+#define SRC_SIZE_SHIFT 1 -+#define SRC_PRESENT 0x00000001 -+ -+/* Fields in pmucontrol */ -+#define PCTL_ILP_DIV_MASK 0xffff0000 -+#define PCTL_ILP_DIV_SHIFT 16 -+#define PCTL_PLL_PLLCTL_UPD 0x00000400 /* rev 2 */ -+#define PCTL_NOILP_ON_WAIT 0x00000200 /* rev 1 */ -+#define PCTL_HT_REQ_EN 0x00000100 -+#define PCTL_ALP_REQ_EN 0x00000080 -+#define PCTL_XTALFREQ_MASK 0x0000007c -+#define PCTL_XTALFREQ_SHIFT 2 -+#define PCTL_ILP_DIV_EN 0x00000002 -+#define PCTL_LPO_SEL 0x00000001 -+ -+/* Fields in clkstretch */ -+#define CSTRETCH_HT 0xffff0000 -+#define CSTRETCH_ALP 0x0000ffff -+ -+/* gpiotimerval */ -+#define GPIO_ONTIME_SHIFT 16 -+ -+/* clockcontrol_n */ -+#define CN_N1_MASK 0x3f /* n1 control */ -+#define CN_N2_MASK 0x3f00 /* n2 control */ -+#define CN_N2_SHIFT 8 -+#define CN_PLLC_MASK 0xf0000 /* pll control */ -+#define CN_PLLC_SHIFT 16 -+ -+/* clockcontrol_sb/pci/uart */ -+#define CC_M1_MASK 0x3f /* m1 control */ -+#define CC_M2_MASK 0x3f00 /* m2 control */ -+#define CC_M2_SHIFT 8 -+#define CC_M3_MASK 0x3f0000 /* m3 control */ -+#define CC_M3_SHIFT 16 -+#define CC_MC_MASK 0x1f000000 /* mux control */ -+#define CC_MC_SHIFT 24 -+ -+/* N3M Clock control magic field values */ -+#define CC_F6_2 0x02 /* A factor of 2 in */ -+#define CC_F6_3 0x03 /* 6-bit fields like */ -+#define CC_F6_4 0x05 /* N1, M1 or M3 */ -+#define CC_F6_5 0x09 -+#define CC_F6_6 0x11 -+#define CC_F6_7 0x21 -+ -+#define CC_F5_BIAS 5 /* 5-bit fields get this added */ -+ -+#define CC_MC_BYPASS 0x08 -+#define CC_MC_M1 0x04 -+#define CC_MC_M1M2 0x02 -+#define CC_MC_M1M2M3 0x01 -+#define CC_MC_M1M3 0x11 -+ -+/* Type 2 Clock control magic field values */ -+#define CC_T2_BIAS 2 /* n1, n2, m1 & m3 bias */ -+#define CC_T2M2_BIAS 3 /* m2 bias */ -+ -+#define CC_T2MC_M1BYP 1 -+#define CC_T2MC_M2BYP 2 -+#define CC_T2MC_M3BYP 4 -+ -+/* Type 6 Clock control magic field values */ -+#define CC_T6_MMASK 1 /* bits of interest in m */ -+#define CC_T6_M0 120000000 /* sb clock for m = 0 */ -+#define CC_T6_M1 100000000 /* sb clock for m = 1 */ -+#define SB2MIPS_T6(sb) (2 * (sb)) -+ -+/* Common clock base */ -+#define CC_CLOCK_BASE1 24000000 /* Half the clock freq */ -+#define CC_CLOCK_BASE2 12500000 /* Alternate crystal on some PLLs */ -+ -+/* Clock control values for 200MHz in 5350 */ -+#define CLKC_5350_N 0x0311 -+#define CLKC_5350_M 0x04020009 -+ -+/* Flash types in the chipcommon capabilities register */ -+#define FLASH_NONE 0x000 /* No flash */ -+#define SFLASH_ST 0x100 /* ST serial flash */ -+#define SFLASH_AT 0x200 /* Atmel serial flash */ -+#define NFLASH 0x300 -+#define PFLASH 0x700 /* Parallel flash */ -+#define QSPIFLASH_ST 0x800 -+#define QSPIFLASH_AT 0x900 -+ -+/* Bits in the ExtBus config registers */ -+#define CC_CFG_EN 0x0001 /* Enable */ -+#define CC_CFG_EM_MASK 0x000e /* Extif Mode */ -+#define CC_CFG_EM_ASYNC 0x0000 /* Async/Parallel flash */ -+#define CC_CFG_EM_SYNC 0x0002 /* Synchronous */ -+#define CC_CFG_EM_PCMCIA 0x0004 /* PCMCIA */ -+#define CC_CFG_EM_IDE 0x0006 /* IDE */ -+#define CC_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */ -+#define CC_CFG_CD_MASK 0x00e0 /* Sync: Clock divisor, rev >= 20 */ -+#define CC_CFG_CE 0x0100 /* Sync: Clock enable, rev >= 20 */ -+#define CC_CFG_SB 0x0200 /* Sync: Size/Bytestrobe, rev >= 20 */ -+#define CC_CFG_IS 0x0400 /* Extif Sync Clk Select, rev >= 20 */ -+ -+/* ExtBus address space */ -+#define CC_EB_BASE 0x1a000000 /* Chipc ExtBus base address */ -+#define CC_EB_PCMCIA_MEM 0x1a000000 /* PCMCIA 0 memory base address */ -+#define CC_EB_PCMCIA_IO 0x1a200000 /* PCMCIA 0 I/O base address */ -+#define CC_EB_PCMCIA_CFG 0x1a400000 /* PCMCIA 0 config base address */ -+#define CC_EB_IDE 0x1a800000 /* IDE memory base */ -+#define CC_EB_PCMCIA1_MEM 0x1a800000 /* PCMCIA 1 memory base address */ -+#define CC_EB_PCMCIA1_IO 0x1aa00000 /* PCMCIA 1 I/O base address */ -+#define CC_EB_PCMCIA1_CFG 0x1ac00000 /* PCMCIA 1 config base address */ -+#define CC_EB_PROGIF 0x1b000000 /* ProgIF Async/Sync base address */ -+ -+ -+/* Start/busy bit in flashcontrol */ -+#define SFLASH_OPCODE 0x000000ff -+#define SFLASH_ACTION 0x00000700 -+#define SFLASH_CS_ACTIVE 0x00001000 /* Chip Select Active, rev >= 20 */ -+#define SFLASH_START 0x80000000 -+#define SFLASH_BUSY SFLASH_START -+ -+/* flashcontrol action codes */ -+#define SFLASH_ACT_OPONLY 0x0000 /* Issue opcode only */ -+#define SFLASH_ACT_OP1D 0x0100 /* opcode + 1 data byte */ -+#define SFLASH_ACT_OP3A 0x0200 /* opcode + 3 addr bytes */ -+#define SFLASH_ACT_OP3A1D 0x0300 /* opcode + 3 addr & 1 data bytes */ -+#define SFLASH_ACT_OP3A4D 0x0400 /* opcode + 3 addr & 4 data bytes */ -+#define SFLASH_ACT_OP3A4X4D 0x0500 /* opcode + 3 addr, 4 don't care & 4 data bytes */ -+#define SFLASH_ACT_OP3A1X4D 0x0700 /* opcode + 3 addr, 1 don't care & 4 data bytes */ -+ -+/* flashcontrol action+opcodes for ST flashes */ -+#define SFLASH_ST_WREN 0x0006 /* Write Enable */ -+#define SFLASH_ST_WRDIS 0x0004 /* Write Disable */ -+#define SFLASH_ST_RDSR 0x0105 /* Read Status Register */ -+#define SFLASH_ST_WRSR 0x0101 /* Write Status Register */ -+#define SFLASH_ST_READ 0x0303 /* Read Data Bytes */ -+#define SFLASH_ST_PP 0x0302 /* Page Program */ -+#define SFLASH_ST_SE 0x02d8 /* Sector Erase */ -+#define SFLASH_ST_BE 0x00c7 /* Bulk Erase */ -+#define SFLASH_ST_DP 0x00b9 /* Deep Power-down */ -+#define SFLASH_ST_RES 0x03ab /* Read Electronic Signature */ -+#define SFLASH_ST_CSA 0x1000 /* Keep chip select asserted */ -+#define SFLASH_ST_SSE 0x0220 /* Sub-sector Erase */ -+ -+#define SFLASH_MXIC_RDID 0x0390 /* Read Manufacture ID */ -+#define SFLASH_MXIC_MFID 0xc2 /* MXIC Manufacture ID */ -+ -+/* Status register bits for ST flashes */ -+#define SFLASH_ST_WIP 0x01 /* Write In Progress */ -+#define SFLASH_ST_WEL 0x02 /* Write Enable Latch */ -+#define SFLASH_ST_BP_MASK 0x1c /* Block Protect */ -+#define SFLASH_ST_BP_SHIFT 2 -+#define SFLASH_ST_SRWD 0x80 /* Status Register Write Disable */ -+ -+/* flashcontrol action+opcodes for Atmel flashes */ -+#define SFLASH_AT_READ 0x07e8 -+#define SFLASH_AT_PAGE_READ 0x07d2 -+#define SFLASH_AT_BUF1_READ -+#define SFLASH_AT_BUF2_READ -+#define SFLASH_AT_STATUS 0x01d7 -+#define SFLASH_AT_BUF1_WRITE 0x0384 -+#define SFLASH_AT_BUF2_WRITE 0x0387 -+#define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283 -+#define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286 -+#define SFLASH_AT_BUF1_PROGRAM 0x0288 -+#define SFLASH_AT_BUF2_PROGRAM 0x0289 -+#define SFLASH_AT_PAGE_ERASE 0x0281 -+#define SFLASH_AT_BLOCK_ERASE 0x0250 -+#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382 -+#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385 -+#define SFLASH_AT_BUF1_LOAD 0x0253 -+#define SFLASH_AT_BUF2_LOAD 0x0255 -+#define SFLASH_AT_BUF1_COMPARE 0x0260 -+#define SFLASH_AT_BUF2_COMPARE 0x0261 -+#define SFLASH_AT_BUF1_REPROGRAM 0x0258 -+#define SFLASH_AT_BUF2_REPROGRAM 0x0259 -+ -+/* Status register bits for Atmel flashes */ -+#define SFLASH_AT_READY 0x80 -+#define SFLASH_AT_MISMATCH 0x40 -+#define SFLASH_AT_ID_MASK 0x38 -+#define SFLASH_AT_ID_SHIFT 3 -+ -+/* SPI register bits, corerev >= 37 */ -+#define GSIO_START 0x80000000 -+#define GSIO_BUSY GSIO_START -+ -+/* -+ * These are the UART port assignments, expressed as offsets from the base -+ * register. These assignments should hold for any serial port based on -+ * a 8250, 16450, or 16550(A). -+ */ -+ -+#define UART_RX 0 /* In: Receive buffer (DLAB=0) */ -+#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */ -+#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */ -+#define UART_IER 1 /* In/Out: Interrupt Enable Register (DLAB=0) */ -+#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */ -+#define UART_IIR 2 /* In: Interrupt Identity Register */ -+#define UART_FCR 2 /* Out: FIFO Control Register */ -+#define UART_LCR 3 /* Out: Line Control Register */ -+#define UART_MCR 4 /* Out: Modem Control Register */ -+#define UART_LSR 5 /* In: Line Status Register */ -+#define UART_MSR 6 /* In: Modem Status Register */ -+#define UART_SCR 7 /* I/O: Scratch Register */ -+#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ -+#define UART_LCR_WLEN8 0x03 /* Word length: 8 bits */ -+#define UART_MCR_OUT2 0x08 /* MCR GPIO out 2 */ -+#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ -+#define UART_LSR_RX_FIFO 0x80 /* Receive FIFO error */ -+#define UART_LSR_TDHR 0x40 /* Data-hold-register empty */ -+#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ -+#define UART_LSR_BREAK 0x10 /* Break interrupt */ -+#define UART_LSR_FRAMING 0x08 /* Framing error */ -+#define UART_LSR_PARITY 0x04 /* Parity error */ -+#define UART_LSR_OVERRUN 0x02 /* Overrun error */ -+#define UART_LSR_RXRDY 0x01 /* Receiver ready */ -+#define UART_FCR_FIFO_ENABLE 1 /* FIFO control register bit controlling FIFO enable/disable */ -+ -+/* Interrupt Identity Register (IIR) bits */ -+#define UART_IIR_FIFO_MASK 0xc0 /* IIR FIFO disable/enabled mask */ -+#define UART_IIR_INT_MASK 0xf /* IIR interrupt ID source */ -+#define UART_IIR_MDM_CHG 0x0 /* Modem status changed */ -+#define UART_IIR_NOINT 0x1 /* No interrupt pending */ -+#define UART_IIR_THRE 0x2 /* THR empty */ -+#define UART_IIR_RCVD_DATA 0x4 /* Received data available */ -+#define UART_IIR_RCVR_STATUS 0x6 /* Receiver status */ -+#define UART_IIR_CHAR_TIME 0xc /* Character time */ -+ -+/* Interrupt Enable Register (IER) bits */ -+#define UART_IER_EDSSI 8 /* enable modem status interrupt */ -+#define UART_IER_ELSI 4 /* enable receiver line status interrupt */ -+#define UART_IER_ETBEI 2 /* enable transmitter holding register empty interrupt */ -+#define UART_IER_ERBFI 1 /* enable data available interrupt */ -+ -+/* pmustatus */ -+#define PST_EXTLPOAVAIL 0x0100 -+#define PST_WDRESET 0x0080 -+#define PST_INTPEND 0x0040 -+#define PST_SBCLKST 0x0030 -+#define PST_SBCLKST_ILP 0x0010 -+#define PST_SBCLKST_ALP 0x0020 -+#define PST_SBCLKST_HT 0x0030 -+#define PST_ALPAVAIL 0x0008 -+#define PST_HTAVAIL 0x0004 -+#define PST_RESINIT 0x0003 -+ -+/* pmucapabilities */ -+#define PCAP_REV_MASK 0x000000ff -+#define PCAP_RC_MASK 0x00001f00 -+#define PCAP_RC_SHIFT 8 -+#define PCAP_TC_MASK 0x0001e000 -+#define PCAP_TC_SHIFT 13 -+#define PCAP_PC_MASK 0x001e0000 -+#define PCAP_PC_SHIFT 17 -+#define PCAP_VC_MASK 0x01e00000 -+#define PCAP_VC_SHIFT 21 -+#define PCAP_CC_MASK 0x1e000000 -+#define PCAP_CC_SHIFT 25 -+#define PCAP5_PC_MASK 0x003e0000 /* PMU corerev >= 5 */ -+#define PCAP5_PC_SHIFT 17 -+#define PCAP5_VC_MASK 0x07c00000 -+#define PCAP5_VC_SHIFT 22 -+#define PCAP5_CC_MASK 0xf8000000 -+#define PCAP5_CC_SHIFT 27 -+ -+/* PMU Resource Request Timer registers */ -+/* This is based on PmuRev0 */ -+#define PRRT_TIME_MASK 0x03ff -+#define PRRT_INTEN 0x0400 -+#define PRRT_REQ_ACTIVE 0x0800 -+#define PRRT_ALP_REQ 0x1000 -+#define PRRT_HT_REQ 0x2000 -+#define PRRT_HQ_REQ 0x4000 -+ -+/* PMU resource bit position */ -+#define PMURES_BIT(bit) (1 << (bit)) -+ -+/* PMU resource number limit */ -+#define PMURES_MAX_RESNUM 30 -+ -+/* PMU chip control0 register */ -+#define PMU_CHIPCTL0 0 -+ -+/* clock req types */ -+#define PMU_CC1_CLKREQ_TYPE_SHIFT 19 -+#define PMU_CC1_CLKREQ_TYPE_MASK (1 << PMU_CC1_CLKREQ_TYPE_SHIFT) -+ -+#define CLKREQ_TYPE_CONFIG_OPENDRAIN 0 -+#define CLKREQ_TYPE_CONFIG_PUSHPULL 1 -+ -+/* PMU chip control1 register */ -+#define PMU_CHIPCTL1 1 -+#define PMU_CC1_RXC_DLL_BYPASS 0x00010000 -+ -+#define PMU_CC1_IF_TYPE_MASK 0x00000030 -+#define PMU_CC1_IF_TYPE_RMII 0x00000000 -+#define PMU_CC1_IF_TYPE_MII 0x00000010 -+#define PMU_CC1_IF_TYPE_RGMII 0x00000020 -+ -+#define PMU_CC1_SW_TYPE_MASK 0x000000c0 -+#define PMU_CC1_SW_TYPE_EPHY 0x00000000 -+#define PMU_CC1_SW_TYPE_EPHYMII 0x00000040 -+#define PMU_CC1_SW_TYPE_EPHYRMII 0x00000080 -+#define PMU_CC1_SW_TYPE_RGMII 0x000000c0 -+ -+/* PMU chip control2 register */ -+#define PMU_CHIPCTL2 2 -+ -+/* PMU chip control3 register */ -+#define PMU_CHIPCTL3 3 -+ -+#define PMU_CC3_ENABLE_SDIO_WAKEUP_SHIFT 19 -+#define PMU_CC3_ENABLE_RF_SHIFT 22 -+#define PMU_CC3_RF_DISABLE_IVALUE_SHIFT 23 -+ -+ -+/* PMU corerev and chip specific PLL controls. -+ * PMU_PLL_XX where is PMU corerev and is an arbitrary number -+ * to differentiate different PLLs controlled by the same PMU rev. -+ */ -+/* pllcontrol registers */ -+/* PDIV, div_phy, div_arm, div_adc, dith_sel, ioff, kpd_scale, lsb_sel, mash_sel, lf_c & lf_r */ -+#define PMU0_PLL0_PLLCTL0 0 -+#define PMU0_PLL0_PC0_PDIV_MASK 1 -+#define PMU0_PLL0_PC0_PDIV_FREQ 25000 -+#define PMU0_PLL0_PC0_DIV_ARM_MASK 0x00000038 -+#define PMU0_PLL0_PC0_DIV_ARM_SHIFT 3 -+#define PMU0_PLL0_PC0_DIV_ARM_BASE 8 -+ -+/* PC0_DIV_ARM for PLLOUT_ARM */ -+#define PMU0_PLL0_PC0_DIV_ARM_110MHZ 0 -+#define PMU0_PLL0_PC0_DIV_ARM_97_7MHZ 1 -+#define PMU0_PLL0_PC0_DIV_ARM_88MHZ 2 -+#define PMU0_PLL0_PC0_DIV_ARM_80MHZ 3 /* Default */ -+#define PMU0_PLL0_PC0_DIV_ARM_73_3MHZ 4 -+#define PMU0_PLL0_PC0_DIV_ARM_67_7MHZ 5 -+#define PMU0_PLL0_PC0_DIV_ARM_62_9MHZ 6 -+#define PMU0_PLL0_PC0_DIV_ARM_58_6MHZ 7 -+ -+/* Wildcard base, stop_mod, en_lf_tp, en_cal & lf_r2 */ -+#define PMU0_PLL0_PLLCTL1 1 -+#define PMU0_PLL0_PC1_WILD_INT_MASK 0xf0000000 -+#define PMU0_PLL0_PC1_WILD_INT_SHIFT 28 -+#define PMU0_PLL0_PC1_WILD_FRAC_MASK 0x0fffff00 -+#define PMU0_PLL0_PC1_WILD_FRAC_SHIFT 8 -+#define PMU0_PLL0_PC1_STOP_MOD 0x00000040 -+ -+/* Wildcard base, vco_calvar, vco_swc, vco_var_selref, vso_ical & vco_sel_avdd */ -+#define PMU0_PLL0_PLLCTL2 2 -+#define PMU0_PLL0_PC2_WILD_INT_MASK 0xf -+#define PMU0_PLL0_PC2_WILD_INT_SHIFT 4 -+ -+/* pllcontrol registers */ -+/* ndiv_pwrdn, pwrdn_ch, refcomp_pwrdn, dly_ch, p1div, p2div, _bypass_sdmod */ -+#define PMU1_PLL0_PLLCTL0 0 -+#define PMU1_PLL0_PC0_P1DIV_MASK 0x00f00000 -+#define PMU1_PLL0_PC0_P1DIV_SHIFT 20 -+#define PMU1_PLL0_PC0_P2DIV_MASK 0x0f000000 -+#define PMU1_PLL0_PC0_P2DIV_SHIFT 24 -+ -+/* mdiv */ -+#define PMU1_PLL0_PLLCTL1 1 -+#define PMU1_PLL0_PC1_M1DIV_MASK 0x000000ff -+#define PMU1_PLL0_PC1_M1DIV_SHIFT 0 -+#define PMU1_PLL0_PC1_M2DIV_MASK 0x0000ff00 -+#define PMU1_PLL0_PC1_M2DIV_SHIFT 8 -+#define PMU1_PLL0_PC1_M3DIV_MASK 0x00ff0000 -+#define PMU1_PLL0_PC1_M3DIV_SHIFT 16 -+#define PMU1_PLL0_PC1_M4DIV_MASK 0xff000000 -+#define PMU1_PLL0_PC1_M4DIV_SHIFT 24 -+#define PMU1_PLL0_PC1_M4DIV_BY_9 9 -+#define PMU1_PLL0_PC1_M4DIV_BY_18 0x12 -+#define PMU1_PLL0_PC1_M4DIV_BY_36 0x24 -+ -+#define DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT 8 -+#define DOT11MAC_880MHZ_CLK_DIVISOR_MASK (0xFF << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT) -+#define DOT11MAC_880MHZ_CLK_DIVISOR_VAL (0xE << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT) -+ -+/* mdiv, ndiv_dither_mfb, ndiv_mode, ndiv_int */ -+#define PMU1_PLL0_PLLCTL2 2 -+#define PMU1_PLL0_PC2_M5DIV_MASK 0x000000ff -+#define PMU1_PLL0_PC2_M5DIV_SHIFT 0 -+#define PMU1_PLL0_PC2_M5DIV_BY_12 0xc -+#define PMU1_PLL0_PC2_M5DIV_BY_18 0x12 -+#define PMU1_PLL0_PC2_M5DIV_BY_36 0x24 -+#define PMU1_PLL0_PC2_M6DIV_MASK 0x0000ff00 -+#define PMU1_PLL0_PC2_M6DIV_SHIFT 8 -+#define PMU1_PLL0_PC2_M6DIV_BY_18 0x12 -+#define PMU1_PLL0_PC2_M6DIV_BY_36 0x24 -+#define PMU1_PLL0_PC2_NDIV_MODE_MASK 0x000e0000 -+#define PMU1_PLL0_PC2_NDIV_MODE_SHIFT 17 -+#define PMU1_PLL0_PC2_NDIV_MODE_MASH 1 -+#define PMU1_PLL0_PC2_NDIV_MODE_MFB 2 /* recommended for 4319 */ -+#define PMU1_PLL0_PC2_NDIV_INT_MASK 0x1ff00000 -+#define PMU1_PLL0_PC2_NDIV_INT_SHIFT 20 -+ -+/* ndiv_frac */ -+#define PMU1_PLL0_PLLCTL3 3 -+#define PMU1_PLL0_PC3_NDIV_FRAC_MASK 0x00ffffff -+#define PMU1_PLL0_PC3_NDIV_FRAC_SHIFT 0 -+ -+/* pll_ctrl */ -+#define PMU1_PLL0_PLLCTL4 4 -+ -+/* pll_ctrl, vco_rng, clkdrive_ch */ -+#define PMU1_PLL0_PLLCTL5 5 -+#define PMU1_PLL0_PC5_CLK_DRV_MASK 0xffffff00 -+#define PMU1_PLL0_PC5_CLK_DRV_SHIFT 8 -+ -+/* PMU rev 2 control words */ -+#define PMU2_PHY_PLL_PLLCTL 4 -+#define PMU2_SI_PLL_PLLCTL 10 -+ -+/* PMU rev 2 */ -+/* pllcontrol registers */ -+/* ndiv_pwrdn, pwrdn_ch, refcomp_pwrdn, dly_ch, p1div, p2div, _bypass_sdmod */ -+#define PMU2_PLL_PLLCTL0 0 -+#define PMU2_PLL_PC0_P1DIV_MASK 0x00f00000 -+#define PMU2_PLL_PC0_P1DIV_SHIFT 20 -+#define PMU2_PLL_PC0_P2DIV_MASK 0x0f000000 -+#define PMU2_PLL_PC0_P2DIV_SHIFT 24 -+ -+/* mdiv */ -+#define PMU2_PLL_PLLCTL1 1 -+#define PMU2_PLL_PC1_M1DIV_MASK 0x000000ff -+#define PMU2_PLL_PC1_M1DIV_SHIFT 0 -+#define PMU2_PLL_PC1_M2DIV_MASK 0x0000ff00 -+#define PMU2_PLL_PC1_M2DIV_SHIFT 8 -+#define PMU2_PLL_PC1_M3DIV_MASK 0x00ff0000 -+#define PMU2_PLL_PC1_M3DIV_SHIFT 16 -+#define PMU2_PLL_PC1_M4DIV_MASK 0xff000000 -+#define PMU2_PLL_PC1_M4DIV_SHIFT 24 -+ -+/* mdiv, ndiv_dither_mfb, ndiv_mode, ndiv_int */ -+#define PMU2_PLL_PLLCTL2 2 -+#define PMU2_PLL_PC2_M5DIV_MASK 0x000000ff -+#define PMU2_PLL_PC2_M5DIV_SHIFT 0 -+#define PMU2_PLL_PC2_M6DIV_MASK 0x0000ff00 -+#define PMU2_PLL_PC2_M6DIV_SHIFT 8 -+#define PMU2_PLL_PC2_NDIV_MODE_MASK 0x000e0000 -+#define PMU2_PLL_PC2_NDIV_MODE_SHIFT 17 -+#define PMU2_PLL_PC2_NDIV_INT_MASK 0x1ff00000 -+#define PMU2_PLL_PC2_NDIV_INT_SHIFT 20 -+ -+/* ndiv_frac */ -+#define PMU2_PLL_PLLCTL3 3 -+#define PMU2_PLL_PC3_NDIV_FRAC_MASK 0x00ffffff -+#define PMU2_PLL_PC3_NDIV_FRAC_SHIFT 0 -+ -+/* pll_ctrl */ -+#define PMU2_PLL_PLLCTL4 4 -+ -+/* pll_ctrl, vco_rng, clkdrive_ch */ -+#define PMU2_PLL_PLLCTL5 5 -+#define PMU2_PLL_PC5_CLKDRIVE_CH1_MASK 0x00000f00 -+#define PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT 8 -+#define PMU2_PLL_PC5_CLKDRIVE_CH2_MASK 0x0000f000 -+#define PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT 12 -+#define PMU2_PLL_PC5_CLKDRIVE_CH3_MASK 0x000f0000 -+#define PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT 16 -+#define PMU2_PLL_PC5_CLKDRIVE_CH4_MASK 0x00f00000 -+#define PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT 20 -+#define PMU2_PLL_PC5_CLKDRIVE_CH5_MASK 0x0f000000 -+#define PMU2_PLL_PC5_CLKDRIVE_CH5_SHIFT 24 -+#define PMU2_PLL_PC5_CLKDRIVE_CH6_MASK 0xf0000000 -+#define PMU2_PLL_PC5_CLKDRIVE_CH6_SHIFT 28 -+ -+/* PMU rev 5 (& 6) */ -+#define PMU5_PLL_P1P2_OFF 0 -+#define PMU5_PLL_P1_MASK 0x0f000000 -+#define PMU5_PLL_P1_SHIFT 24 -+#define PMU5_PLL_P2_MASK 0x00f00000 -+#define PMU5_PLL_P2_SHIFT 20 -+#define PMU5_PLL_M14_OFF 1 -+#define PMU5_PLL_MDIV_MASK 0x000000ff -+#define PMU5_PLL_MDIV_WIDTH 8 -+#define PMU5_PLL_NM5_OFF 2 -+#define PMU5_PLL_NDIV_MASK 0xfff00000 -+#define PMU5_PLL_NDIV_SHIFT 20 -+#define PMU5_PLL_NDIV_MODE_MASK 0x000e0000 -+#define PMU5_PLL_NDIV_MODE_SHIFT 17 -+#define PMU5_PLL_FMAB_OFF 3 -+#define PMU5_PLL_MRAT_MASK 0xf0000000 -+#define PMU5_PLL_MRAT_SHIFT 28 -+#define PMU5_PLL_ABRAT_MASK 0x08000000 -+#define PMU5_PLL_ABRAT_SHIFT 27 -+#define PMU5_PLL_FDIV_MASK 0x07ffffff -+#define PMU5_PLL_PLLCTL_OFF 4 -+#define PMU5_PLL_PCHI_OFF 5 -+#define PMU5_PLL_PCHI_MASK 0x0000003f -+ -+/* pmu XtalFreqRatio */ -+#define PMU_XTALFREQ_REG_ILPCTR_MASK 0x00001FFF -+#define PMU_XTALFREQ_REG_MEASURE_MASK 0x80000000 -+#define PMU_XTALFREQ_REG_MEASURE_SHIFT 31 -+ -+/* Divider allocation in 4716/47162/5356/5357 */ -+#define PMU5_MAINPLL_CPU 1 -+#define PMU5_MAINPLL_MEM 2 -+#define PMU5_MAINPLL_SI 3 -+ -+/* 4706 PMU */ -+#define PMU4706_MAINPLL_PLL0 0 -+#define PMU6_4706_PROCPLL_OFF 4 /* The CPU PLL */ -+#define PMU6_4706_PROC_P2DIV_MASK 0x000f0000 -+#define PMU6_4706_PROC_P2DIV_SHIFT 16 -+#define PMU6_4706_PROC_P1DIV_MASK 0x0000f000 -+#define PMU6_4706_PROC_P1DIV_SHIFT 12 -+#define PMU6_4706_PROC_NDIV_INT_MASK 0x00000ff8 -+#define PMU6_4706_PROC_NDIV_INT_SHIFT 3 -+#define PMU6_4706_PROC_NDIV_MODE_MASK 0x00000007 -+#define PMU6_4706_PROC_NDIV_MODE_SHIFT 0 -+ -+#define PMU7_PLL_PLLCTL7 7 -+#define PMU7_PLL_CTL7_M4DIV_MASK 0xff000000 -+#define PMU7_PLL_CTL7_M4DIV_SHIFT 24 -+#define PMU7_PLL_CTL7_M4DIV_BY_6 6 -+#define PMU7_PLL_CTL7_M4DIV_BY_12 0xc -+#define PMU7_PLL_CTL7_M4DIV_BY_24 0x18 -+#define PMU7_PLL_PLLCTL8 8 -+#define PMU7_PLL_CTL8_M5DIV_MASK 0x000000ff -+#define PMU7_PLL_CTL8_M5DIV_SHIFT 0 -+#define PMU7_PLL_CTL8_M5DIV_BY_8 8 -+#define PMU7_PLL_CTL8_M5DIV_BY_12 0xc -+#define PMU7_PLL_CTL8_M5DIV_BY_24 0x18 -+#define PMU7_PLL_CTL8_M6DIV_MASK 0x0000ff00 -+#define PMU7_PLL_CTL8_M6DIV_SHIFT 8 -+#define PMU7_PLL_CTL8_M6DIV_BY_12 0xc -+#define PMU7_PLL_CTL8_M6DIV_BY_24 0x18 -+#define PMU7_PLL_PLLCTL11 11 -+#define PMU7_PLL_PLLCTL11_MASK 0xffffff00 -+#define PMU7_PLL_PLLCTL11_VAL 0x22222200 -+ -+/* PMU rev 15 */ -+#define PMU15_PLL_PLLCTL0 0 -+#define PMU15_PLL_PC0_CLKSEL_MASK 0x00000003 -+#define PMU15_PLL_PC0_CLKSEL_SHIFT 0 -+#define PMU15_PLL_PC0_FREQTGT_MASK 0x003FFFFC -+#define PMU15_PLL_PC0_FREQTGT_SHIFT 2 -+#define PMU15_PLL_PC0_PRESCALE_MASK 0x00C00000 -+#define PMU15_PLL_PC0_PRESCALE_SHIFT 22 -+#define PMU15_PLL_PC0_KPCTRL_MASK 0x07000000 -+#define PMU15_PLL_PC0_KPCTRL_SHIFT 24 -+#define PMU15_PLL_PC0_FCNTCTRL_MASK 0x38000000 -+#define PMU15_PLL_PC0_FCNTCTRL_SHIFT 27 -+#define PMU15_PLL_PC0_FDCMODE_MASK 0x40000000 -+#define PMU15_PLL_PC0_FDCMODE_SHIFT 30 -+#define PMU15_PLL_PC0_CTRLBIAS_MASK 0x80000000 -+#define PMU15_PLL_PC0_CTRLBIAS_SHIFT 31 -+ -+#define PMU15_PLL_PLLCTL1 1 -+#define PMU15_PLL_PC1_BIAS_CTLM_MASK 0x00000060 -+#define PMU15_PLL_PC1_BIAS_CTLM_SHIFT 5 -+#define PMU15_PLL_PC1_BIAS_CTLM_RST_MASK 0x00000040 -+#define PMU15_PLL_PC1_BIAS_CTLM_RST_SHIFT 6 -+#define PMU15_PLL_PC1_BIAS_SS_DIVR_MASK 0x0001FF80 -+#define PMU15_PLL_PC1_BIAS_SS_DIVR_SHIFT 7 -+#define PMU15_PLL_PC1_BIAS_SS_RSTVAL_MASK 0x03FE0000 -+#define PMU15_PLL_PC1_BIAS_SS_RSTVAL_SHIFT 17 -+#define PMU15_PLL_PC1_BIAS_INTG_BW_MASK 0x0C000000 -+#define PMU15_PLL_PC1_BIAS_INTG_BW_SHIFT 26 -+#define PMU15_PLL_PC1_BIAS_INTG_BYP_MASK 0x10000000 -+#define PMU15_PLL_PC1_BIAS_INTG_BYP_SHIFT 28 -+#define PMU15_PLL_PC1_OPENLP_EN_MASK 0x40000000 -+#define PMU15_PLL_PC1_OPENLP_EN_SHIFT 30 -+ -+#define PMU15_PLL_PLLCTL2 2 -+#define PMU15_PLL_PC2_CTEN_MASK 0x00000001 -+#define PMU15_PLL_PC2_CTEN_SHIFT 0 -+ -+#define PMU15_PLL_PLLCTL3 3 -+#define PMU15_PLL_PC3_DITHER_EN_MASK 0x00000001 -+#define PMU15_PLL_PC3_DITHER_EN_SHIFT 0 -+#define PMU15_PLL_PC3_DCOCTLSP_MASK 0xFE000000 -+#define PMU15_PLL_PC3_DCOCTLSP_SHIFT 25 -+#define PMU15_PLL_PC3_DCOCTLSP_DIV2EN_MASK 0x01 -+#define PMU15_PLL_PC3_DCOCTLSP_DIV2EN_SHIFT 0 -+#define PMU15_PLL_PC3_DCOCTLSP_CH0EN_MASK 0x02 -+#define PMU15_PLL_PC3_DCOCTLSP_CH0EN_SHIFT 1 -+#define PMU15_PLL_PC3_DCOCTLSP_CH1EN_MASK 0x04 -+#define PMU15_PLL_PC3_DCOCTLSP_CH1EN_SHIFT 2 -+#define PMU15_PLL_PC3_DCOCTLSP_CH0SEL_MASK 0x18 -+#define PMU15_PLL_PC3_DCOCTLSP_CH0SEL_SHIFT 3 -+#define PMU15_PLL_PC3_DCOCTLSP_CH1SEL_MASK 0x60 -+#define PMU15_PLL_PC3_DCOCTLSP_CH1SEL_SHIFT 5 -+#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV1 0 -+#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV2 1 -+#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV3 2 -+#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV5 3 -+ -+#define PMU15_PLL_PLLCTL4 4 -+#define PMU15_PLL_PC4_FLLCLK1_DIV_MASK 0x00000007 -+#define PMU15_PLL_PC4_FLLCLK1_DIV_SHIFT 0 -+#define PMU15_PLL_PC4_FLLCLK2_DIV_MASK 0x00000038 -+#define PMU15_PLL_PC4_FLLCLK2_DIV_SHIFT 3 -+#define PMU15_PLL_PC4_FLLCLK3_DIV_MASK 0x000001C0 -+#define PMU15_PLL_PC4_FLLCLK3_DIV_SHIFT 6 -+#define PMU15_PLL_PC4_DBGMODE_MASK 0x00000E00 -+#define PMU15_PLL_PC4_DBGMODE_SHIFT 9 -+#define PMU15_PLL_PC4_FLL480_CTLSP_LK_MASK 0x00001000 -+#define PMU15_PLL_PC4_FLL480_CTLSP_LK_SHIFT 12 -+#define PMU15_PLL_PC4_FLL480_CTLSP_MASK 0x000FE000 -+#define PMU15_PLL_PC4_FLL480_CTLSP_SHIFT 13 -+#define PMU15_PLL_PC4_DINPOL_MASK 0x00100000 -+#define PMU15_PLL_PC4_DINPOL_SHIFT 20 -+#define PMU15_PLL_PC4_CLKOUT_PD_MASK 0x00200000 -+#define PMU15_PLL_PC4_CLKOUT_PD_SHIFT 21 -+#define PMU15_PLL_PC4_CLKDIV2_PD_MASK 0x00400000 -+#define PMU15_PLL_PC4_CLKDIV2_PD_SHIFT 22 -+#define PMU15_PLL_PC4_CLKDIV4_PD_MASK 0x00800000 -+#define PMU15_PLL_PC4_CLKDIV4_PD_SHIFT 23 -+#define PMU15_PLL_PC4_CLKDIV8_PD_MASK 0x01000000 -+#define PMU15_PLL_PC4_CLKDIV8_PD_SHIFT 24 -+#define PMU15_PLL_PC4_CLKDIV16_PD_MASK 0x02000000 -+#define PMU15_PLL_PC4_CLKDIV16_PD_SHIFT 25 -+#define PMU15_PLL_PC4_TEST_EN_MASK 0x04000000 -+#define PMU15_PLL_PC4_TEST_EN_SHIFT 26 -+ -+#define PMU15_PLL_PLLCTL5 5 -+#define PMU15_PLL_PC5_FREQTGT_MASK 0x000FFFFF -+#define PMU15_PLL_PC5_FREQTGT_SHIFT 0 -+#define PMU15_PLL_PC5_DCOCTLSP_MASK 0x07F00000 -+#define PMU15_PLL_PC5_DCOCTLSP_SHIFT 20 -+#define PMU15_PLL_PC5_PRESCALE_MASK 0x18000000 -+#define PMU15_PLL_PC5_PRESCALE_SHIFT 27 -+ -+#define PMU15_PLL_PLLCTL6 6 -+#define PMU15_PLL_PC6_FREQTGT_MASK 0x000FFFFF -+#define PMU15_PLL_PC6_FREQTGT_SHIFT 0 -+#define PMU15_PLL_PC6_DCOCTLSP_MASK 0x07F00000 -+#define PMU15_PLL_PC6_DCOCTLSP_SHIFT 20 -+#define PMU15_PLL_PC6_PRESCALE_MASK 0x18000000 -+#define PMU15_PLL_PC6_PRESCALE_SHIFT 27 -+ -+#define PMU15_FREQTGT_480_DEFAULT 0x19AB1 -+#define PMU15_FREQTGT_492_DEFAULT 0x1A4F5 -+#define PMU15_ARM_96MHZ 96000000 /* 96 Mhz */ -+#define PMU15_ARM_98MHZ 98400000 /* 98.4 Mhz */ -+#define PMU15_ARM_97MHZ 97000000 /* 97 Mhz */ -+ -+ -+#define PMU17_PLLCTL2_NDIVTYPE_MASK 0x00000070 -+#define PMU17_PLLCTL2_NDIVTYPE_SHIFT 4 -+ -+#define PMU17_PLLCTL2_NDIV_MODE_INT 0 -+#define PMU17_PLLCTL2_NDIV_MODE_INT1B8 1 -+#define PMU17_PLLCTL2_NDIV_MODE_MASH111 2 -+#define PMU17_PLLCTL2_NDIV_MODE_MASH111B8 3 -+ -+#define PMU17_PLLCTL0_BBPLL_PWRDWN 0 -+#define PMU17_PLLCTL0_BBPLL_DRST 3 -+#define PMU17_PLLCTL0_BBPLL_DISBL_CLK 8 -+ -+/* PLL usage in 4716/47162 */ -+#define PMU4716_MAINPLL_PLL0 12 -+ -+/* PLL usage in 5356/5357 */ -+#define PMU5356_MAINPLL_PLL0 0 -+#define PMU5357_MAINPLL_PLL0 0 -+ -+/* 4716/47162 resources */ -+#define RES4716_PROC_PLL_ON 0x00000040 -+#define RES4716_PROC_HT_AVAIL 0x00000080 -+ -+/* 4716/4717/4718 Chip specific ChipControl register bits */ -+#define CCTRL_471X_I2S_PINS_ENABLE 0x0080 /* I2S pins off by default, shared w/ pflash */ -+ -+/* 5357 Chip specific ChipControl register bits */ -+/* 2nd - 32-bit reg */ -+#define CCTRL_5357_I2S_PINS_ENABLE 0x00040000 /* I2S pins enable */ -+#define CCTRL_5357_I2CSPI_PINS_ENABLE 0x00080000 /* I2C/SPI pins enable */ -+ -+/* 5354 resources */ -+#define RES5354_EXT_SWITCHER_PWM 0 /* 0x00001 */ -+#define RES5354_BB_SWITCHER_PWM 1 /* 0x00002 */ -+#define RES5354_BB_SWITCHER_BURST 2 /* 0x00004 */ -+#define RES5354_BB_EXT_SWITCHER_BURST 3 /* 0x00008 */ -+#define RES5354_ILP_REQUEST 4 /* 0x00010 */ -+#define RES5354_RADIO_SWITCHER_PWM 5 /* 0x00020 */ -+#define RES5354_RADIO_SWITCHER_BURST 6 /* 0x00040 */ -+#define RES5354_ROM_SWITCH 7 /* 0x00080 */ -+#define RES5354_PA_REF_LDO 8 /* 0x00100 */ -+#define RES5354_RADIO_LDO 9 /* 0x00200 */ -+#define RES5354_AFE_LDO 10 /* 0x00400 */ -+#define RES5354_PLL_LDO 11 /* 0x00800 */ -+#define RES5354_BG_FILTBYP 12 /* 0x01000 */ -+#define RES5354_TX_FILTBYP 13 /* 0x02000 */ -+#define RES5354_RX_FILTBYP 14 /* 0x04000 */ -+#define RES5354_XTAL_PU 15 /* 0x08000 */ -+#define RES5354_XTAL_EN 16 /* 0x10000 */ -+#define RES5354_BB_PLL_FILTBYP 17 /* 0x20000 */ -+#define RES5354_RF_PLL_FILTBYP 18 /* 0x40000 */ -+#define RES5354_BB_PLL_PU 19 /* 0x80000 */ -+ -+/* 5357 Chip specific ChipControl register bits */ -+#define CCTRL5357_EXTPA (1<<14) /* extPA in ChipControl 1, bit 14 */ -+#define CCTRL5357_ANT_MUX_2o3 (1<<15) /* 2o3 in ChipControl 1, bit 15 */ -+#define CCTRL5357_NFLASH (1<<16) /* Nandflash in ChipControl 1, bit 16 */ -+ -+/* 4328 resources */ -+#define RES4328_EXT_SWITCHER_PWM 0 /* 0x00001 */ -+#define RES4328_BB_SWITCHER_PWM 1 /* 0x00002 */ -+#define RES4328_BB_SWITCHER_BURST 2 /* 0x00004 */ -+#define RES4328_BB_EXT_SWITCHER_BURST 3 /* 0x00008 */ -+#define RES4328_ILP_REQUEST 4 /* 0x00010 */ -+#define RES4328_RADIO_SWITCHER_PWM 5 /* 0x00020 */ -+#define RES4328_RADIO_SWITCHER_BURST 6 /* 0x00040 */ -+#define RES4328_ROM_SWITCH 7 /* 0x00080 */ -+#define RES4328_PA_REF_LDO 8 /* 0x00100 */ -+#define RES4328_RADIO_LDO 9 /* 0x00200 */ -+#define RES4328_AFE_LDO 10 /* 0x00400 */ -+#define RES4328_PLL_LDO 11 /* 0x00800 */ -+#define RES4328_BG_FILTBYP 12 /* 0x01000 */ -+#define RES4328_TX_FILTBYP 13 /* 0x02000 */ -+#define RES4328_RX_FILTBYP 14 /* 0x04000 */ -+#define RES4328_XTAL_PU 15 /* 0x08000 */ -+#define RES4328_XTAL_EN 16 /* 0x10000 */ -+#define RES4328_BB_PLL_FILTBYP 17 /* 0x20000 */ -+#define RES4328_RF_PLL_FILTBYP 18 /* 0x40000 */ -+#define RES4328_BB_PLL_PU 19 /* 0x80000 */ -+ -+/* 4325 A0/A1 resources */ -+#define RES4325_BUCK_BOOST_BURST 0 /* 0x00000001 */ -+#define RES4325_CBUCK_BURST 1 /* 0x00000002 */ -+#define RES4325_CBUCK_PWM 2 /* 0x00000004 */ -+#define RES4325_CLDO_CBUCK_BURST 3 /* 0x00000008 */ -+#define RES4325_CLDO_CBUCK_PWM 4 /* 0x00000010 */ -+#define RES4325_BUCK_BOOST_PWM 5 /* 0x00000020 */ -+#define RES4325_ILP_REQUEST 6 /* 0x00000040 */ -+#define RES4325_ABUCK_BURST 7 /* 0x00000080 */ -+#define RES4325_ABUCK_PWM 8 /* 0x00000100 */ -+#define RES4325_LNLDO1_PU 9 /* 0x00000200 */ -+#define RES4325_OTP_PU 10 /* 0x00000400 */ -+#define RES4325_LNLDO3_PU 11 /* 0x00000800 */ -+#define RES4325_LNLDO4_PU 12 /* 0x00001000 */ -+#define RES4325_XTAL_PU 13 /* 0x00002000 */ -+#define RES4325_ALP_AVAIL 14 /* 0x00004000 */ -+#define RES4325_RX_PWRSW_PU 15 /* 0x00008000 */ -+#define RES4325_TX_PWRSW_PU 16 /* 0x00010000 */ -+#define RES4325_RFPLL_PWRSW_PU 17 /* 0x00020000 */ -+#define RES4325_LOGEN_PWRSW_PU 18 /* 0x00040000 */ -+#define RES4325_AFE_PWRSW_PU 19 /* 0x00080000 */ -+#define RES4325_BBPLL_PWRSW_PU 20 /* 0x00100000 */ -+#define RES4325_HT_AVAIL 21 /* 0x00200000 */ -+ -+/* 4325 B0/C0 resources */ -+#define RES4325B0_CBUCK_LPOM 1 /* 0x00000002 */ -+#define RES4325B0_CBUCK_BURST 2 /* 0x00000004 */ -+#define RES4325B0_CBUCK_PWM 3 /* 0x00000008 */ -+#define RES4325B0_CLDO_PU 4 /* 0x00000010 */ -+ -+/* 4325 C1 resources */ -+#define RES4325C1_LNLDO2_PU 12 /* 0x00001000 */ -+ -+/* 4325 chip-specific ChipStatus register bits */ -+#define CST4325_SPROM_OTP_SEL_MASK 0x00000003 -+#define CST4325_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ -+#define CST4325_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ -+#define CST4325_OTP_SEL 2 /* OTP is powered up, no SPROM */ -+#define CST4325_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */ -+#define CST4325_SDIO_USB_MODE_MASK 0x00000004 -+#define CST4325_SDIO_USB_MODE_SHIFT 2 -+#define CST4325_RCAL_VALID_MASK 0x00000008 -+#define CST4325_RCAL_VALID_SHIFT 3 -+#define CST4325_RCAL_VALUE_MASK 0x000001f0 -+#define CST4325_RCAL_VALUE_SHIFT 4 -+#define CST4325_PMUTOP_2B_MASK 0x00000200 /* 1 for 2b, 0 for to 2a */ -+#define CST4325_PMUTOP_2B_SHIFT 9 -+ -+#define RES4329_RESERVED0 0 /* 0x00000001 */ -+#define RES4329_CBUCK_LPOM 1 /* 0x00000002 */ -+#define RES4329_CBUCK_BURST 2 /* 0x00000004 */ -+#define RES4329_CBUCK_PWM 3 /* 0x00000008 */ -+#define RES4329_CLDO_PU 4 /* 0x00000010 */ -+#define RES4329_PALDO_PU 5 /* 0x00000020 */ -+#define RES4329_ILP_REQUEST 6 /* 0x00000040 */ -+#define RES4329_RESERVED7 7 /* 0x00000080 */ -+#define RES4329_RESERVED8 8 /* 0x00000100 */ -+#define RES4329_LNLDO1_PU 9 /* 0x00000200 */ -+#define RES4329_OTP_PU 10 /* 0x00000400 */ -+#define RES4329_RESERVED11 11 /* 0x00000800 */ -+#define RES4329_LNLDO2_PU 12 /* 0x00001000 */ -+#define RES4329_XTAL_PU 13 /* 0x00002000 */ -+#define RES4329_ALP_AVAIL 14 /* 0x00004000 */ -+#define RES4329_RX_PWRSW_PU 15 /* 0x00008000 */ -+#define RES4329_TX_PWRSW_PU 16 /* 0x00010000 */ -+#define RES4329_RFPLL_PWRSW_PU 17 /* 0x00020000 */ -+#define RES4329_LOGEN_PWRSW_PU 18 /* 0x00040000 */ -+#define RES4329_AFE_PWRSW_PU 19 /* 0x00080000 */ -+#define RES4329_BBPLL_PWRSW_PU 20 /* 0x00100000 */ -+#define RES4329_HT_AVAIL 21 /* 0x00200000 */ -+ -+#define CST4329_SPROM_OTP_SEL_MASK 0x00000003 -+#define CST4329_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ -+#define CST4329_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ -+#define CST4329_OTP_SEL 2 /* OTP is powered up, no SPROM */ -+#define CST4329_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */ -+#define CST4329_SPI_SDIO_MODE_MASK 0x00000004 -+#define CST4329_SPI_SDIO_MODE_SHIFT 2 -+ -+/* 4312 chip-specific ChipStatus register bits */ -+#define CST4312_SPROM_OTP_SEL_MASK 0x00000003 -+#define CST4312_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ -+#define CST4312_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ -+#define CST4312_OTP_SEL 2 /* OTP is powered up, no SPROM */ -+#define CST4312_OTP_BAD 3 /* OTP is broken, SPROM is present */ -+ -+/* 4312 resources (all PMU chips with little memory constraint) */ -+#define RES4312_SWITCHER_BURST 0 /* 0x00000001 */ -+#define RES4312_SWITCHER_PWM 1 /* 0x00000002 */ -+#define RES4312_PA_REF_LDO 2 /* 0x00000004 */ -+#define RES4312_CORE_LDO_BURST 3 /* 0x00000008 */ -+#define RES4312_CORE_LDO_PWM 4 /* 0x00000010 */ -+#define RES4312_RADIO_LDO 5 /* 0x00000020 */ -+#define RES4312_ILP_REQUEST 6 /* 0x00000040 */ -+#define RES4312_BG_FILTBYP 7 /* 0x00000080 */ -+#define RES4312_TX_FILTBYP 8 /* 0x00000100 */ -+#define RES4312_RX_FILTBYP 9 /* 0x00000200 */ -+#define RES4312_XTAL_PU 10 /* 0x00000400 */ -+#define RES4312_ALP_AVAIL 11 /* 0x00000800 */ -+#define RES4312_BB_PLL_FILTBYP 12 /* 0x00001000 */ -+#define RES4312_RF_PLL_FILTBYP 13 /* 0x00002000 */ -+#define RES4312_HT_AVAIL 14 /* 0x00004000 */ -+ -+/* 4322 resources */ -+#define RES4322_RF_LDO 0 -+#define RES4322_ILP_REQUEST 1 -+#define RES4322_XTAL_PU 2 -+#define RES4322_ALP_AVAIL 3 -+#define RES4322_SI_PLL_ON 4 -+#define RES4322_HT_SI_AVAIL 5 -+#define RES4322_PHY_PLL_ON 6 -+#define RES4322_HT_PHY_AVAIL 7 -+#define RES4322_OTP_PU 8 -+ -+/* 4322 chip-specific ChipStatus register bits */ -+#define CST4322_XTAL_FREQ_20_40MHZ 0x00000020 -+#define CST4322_SPROM_OTP_SEL_MASK 0x000000c0 -+#define CST4322_SPROM_OTP_SEL_SHIFT 6 -+#define CST4322_NO_SPROM_OTP 0 /* no OTP, no SPROM */ -+#define CST4322_SPROM_PRESENT 1 /* SPROM is present */ -+#define CST4322_OTP_PRESENT 2 /* OTP is present */ -+#define CST4322_PCI_OR_USB 0x00000100 -+#define CST4322_BOOT_MASK 0x00000600 -+#define CST4322_BOOT_SHIFT 9 -+#define CST4322_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ -+#define CST4322_BOOT_FROM_ROM 1 /* boot from ROM */ -+#define CST4322_BOOT_FROM_FLASH 2 /* boot from FLASH */ -+#define CST4322_BOOT_FROM_INVALID 3 -+#define CST4322_ILP_DIV_EN 0x00000800 -+#define CST4322_FLASH_TYPE_MASK 0x00001000 -+#define CST4322_FLASH_TYPE_SHIFT 12 -+#define CST4322_FLASH_TYPE_SHIFT_ST 0 /* ST serial FLASH */ -+#define CST4322_FLASH_TYPE_SHIFT_ATMEL 1 /* ATMEL flash */ -+#define CST4322_ARM_TAP_SEL 0x00002000 -+#define CST4322_RES_INIT_MODE_MASK 0x0000c000 -+#define CST4322_RES_INIT_MODE_SHIFT 14 -+#define CST4322_RES_INIT_MODE_ILPAVAIL 0 /* resinitmode: ILP available */ -+#define CST4322_RES_INIT_MODE_ILPREQ 1 /* resinitmode: ILP request */ -+#define CST4322_RES_INIT_MODE_ALPAVAIL 2 /* resinitmode: ALP available */ -+#define CST4322_RES_INIT_MODE_HTAVAIL 3 /* resinitmode: HT available */ -+#define CST4322_PCIPLLCLK_GATING 0x00010000 -+#define CST4322_CLK_SWITCH_PCI_TO_ALP 0x00020000 -+#define CST4322_PCI_CARDBUS_MODE 0x00040000 -+ -+/* 43224 chip-specific ChipControl register bits */ -+#define CCTRL43224_GPIO_TOGGLE 0x8000 /* gpio[3:0] pins as btcoex or s/w gpio */ -+#define CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0 /* 12 mA drive strength */ -+#define CCTRL_43224B0_12MA_LED_DRIVE 0xF0 /* 12 mA drive strength for later 43224s */ -+ -+/* 43236 resources */ -+#define RES43236_REGULATOR 0 -+#define RES43236_ILP_REQUEST 1 -+#define RES43236_XTAL_PU 2 -+#define RES43236_ALP_AVAIL 3 -+#define RES43236_SI_PLL_ON 4 -+#define RES43236_HT_SI_AVAIL 5 -+ -+/* 43236 chip-specific ChipControl register bits */ -+#define CCTRL43236_BT_COEXIST (1<<0) /* 0 disable */ -+#define CCTRL43236_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */ -+#define CCTRL43236_EXT_LNA (1<<2) /* 0 disable */ -+#define CCTRL43236_ANT_MUX_2o3 (1<<3) /* 2o3 mux, chipcontrol bit 3 */ -+#define CCTRL43236_GSIO (1<<4) /* 0 disable */ -+ -+/* 43236 Chip specific ChipStatus register bits */ -+#define CST43236_SFLASH_MASK 0x00000040 -+#define CST43236_OTP_SEL_MASK 0x00000080 -+#define CST43236_OTP_SEL_SHIFT 7 -+#define CST43236_HSIC_MASK 0x00000100 /* USB/HSIC */ -+#define CST43236_BP_CLK 0x00000200 /* 120/96Mbps */ -+#define CST43236_BOOT_MASK 0x00001800 -+#define CST43236_BOOT_SHIFT 11 -+#define CST43236_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ -+#define CST43236_BOOT_FROM_ROM 1 /* boot from ROM */ -+#define CST43236_BOOT_FROM_FLASH 2 /* boot from FLASH */ -+#define CST43236_BOOT_FROM_INVALID 3 -+ -+/* 43237 resources */ -+#define RES43237_REGULATOR 0 -+#define RES43237_ILP_REQUEST 1 -+#define RES43237_XTAL_PU 2 -+#define RES43237_ALP_AVAIL 3 -+#define RES43237_SI_PLL_ON 4 -+#define RES43237_HT_SI_AVAIL 5 -+ -+/* 43237 chip-specific ChipControl register bits */ -+#define CCTRL43237_BT_COEXIST (1<<0) /* 0 disable */ -+#define CCTRL43237_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */ -+#define CCTRL43237_EXT_LNA (1<<2) /* 0 disable */ -+#define CCTRL43237_ANT_MUX_2o3 (1<<3) /* 2o3 mux, chipcontrol bit 3 */ -+#define CCTRL43237_GSIO (1<<4) /* 0 disable */ -+ -+/* 43237 Chip specific ChipStatus register bits */ -+#define CST43237_SFLASH_MASK 0x00000040 -+#define CST43237_OTP_SEL_MASK 0x00000080 -+#define CST43237_OTP_SEL_SHIFT 7 -+#define CST43237_HSIC_MASK 0x00000100 /* USB/HSIC */ -+#define CST43237_BP_CLK 0x00000200 /* 120/96Mbps */ -+#define CST43237_BOOT_MASK 0x00001800 -+#define CST43237_BOOT_SHIFT 11 -+#define CST43237_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ -+#define CST43237_BOOT_FROM_ROM 1 /* boot from ROM */ -+#define CST43237_BOOT_FROM_FLASH 2 /* boot from FLASH */ -+#define CST43237_BOOT_FROM_INVALID 3 -+ -+/* 43239 resources */ -+#define RES43239_OTP_PU 9 -+#define RES43239_MACPHY_CLKAVAIL 23 -+#define RES43239_HT_AVAIL 24 -+ -+/* 43239 Chip specific ChipStatus register bits */ -+#define CST43239_SPROM_MASK 0x00000002 -+#define CST43239_SFLASH_MASK 0x00000004 -+#define CST43239_RES_INIT_MODE_SHIFT 7 -+#define CST43239_RES_INIT_MODE_MASK 0x000001f0 -+#define CST43239_CHIPMODE_SDIOD(cs) ((cs) & (1 << 15)) /* SDIO || gSPI */ -+#define CST43239_CHIPMODE_USB20D(cs) (~(cs) & (1 << 15)) /* USB || USBDA */ -+#define CST43239_CHIPMODE_SDIO(cs) (((cs) & (1 << 0)) == 0) /* SDIO */ -+#define CST43239_CHIPMODE_GSPI(cs) (((cs) & (1 << 0)) == (1 << 0)) /* gSPI */ -+ -+/* 4324 resources */ -+#define RES4324_OTP_PU 10 -+#define RES4324_HT_AVAIL 29 -+#define RES4324_MACPHY_CLKAVAIL 30 -+ -+/* 4324 Chip specific ChipStatus register bits */ -+#define CST4324_SPROM_MASK 0x00000080 -+#define CST4324_SFLASH_MASK 0x00400000 -+#define CST4324_RES_INIT_MODE_SHIFT 10 -+#define CST4324_RES_INIT_MODE_MASK 0x00000c00 -+#define CST4324_CHIPMODE_MASK 0x7 -+#define CST4324_CHIPMODE_SDIOD(cs) ((~(cs)) & (1 << 2)) /* SDIO || gSPI */ -+#define CST4324_CHIPMODE_USB20D(cs) (((cs) & CST4324_CHIPMODE_MASK) == 0x6) /* USB || USBDA */ -+ -+/* 4331 resources */ -+#define RES4331_REGULATOR 0 -+#define RES4331_ILP_REQUEST 1 -+#define RES4331_XTAL_PU 2 -+#define RES4331_ALP_AVAIL 3 -+#define RES4331_SI_PLL_ON 4 -+#define RES4331_HT_SI_AVAIL 5 -+ -+/* 4331 chip-specific ChipControl register bits */ -+#define CCTRL4331_BT_COEXIST (1<<0) /* 0 disable */ -+#define CCTRL4331_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */ -+#define CCTRL4331_EXT_LNA_G (1<<2) /* 0 disable */ -+#define CCTRL4331_SPROM_GPIO13_15 (1<<3) /* sprom/gpio13-15 mux */ -+#define CCTRL4331_EXTPA_EN (1<<4) /* 0 ext pa disable, 1 ext pa enabled */ -+#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5) /* set drive out GPIO_CLK on sprom_cs pin */ -+#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6) /* use sprom_cs pin as PCIE mdio interface */ -+#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7) /* aband extpa will be at gpio2/5 and sprom_dout */ -+#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8) /* override core control on pipe_AuxClkEnable */ -+#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) /* override core control on pipe_AuxPowerDown */ -+#define CCTRL4331_PCIE_AUXCLKEN (1<<10) /* pcie_auxclkenable */ -+#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) /* pcie_pipe_pllpowerdown */ -+#define CCTRL4331_EXTPA_EN2 (1<<12) /* 0 ext pa disable, 1 ext pa enabled */ -+#define CCTRL4331_EXT_LNA_A (1<<13) /* 0 disable */ -+#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) /* enable bt_shd0 at gpio4 */ -+#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) /* enable bt_shd1 at gpio5 */ -+#define CCTRL4331_EXTPA_ANA_EN (1<<24) /* 0 ext pa disable, 1 ext pa enabled */ -+ -+/* 4331 Chip specific ChipStatus register bits */ -+#define CST4331_XTAL_FREQ 0x00000001 /* crystal frequency 20/40Mhz */ -+#define CST4331_SPROM_OTP_SEL_MASK 0x00000006 -+#define CST4331_SPROM_OTP_SEL_SHIFT 1 -+#define CST4331_SPROM_PRESENT 0x00000002 -+#define CST4331_OTP_PRESENT 0x00000004 -+#define CST4331_LDO_RF 0x00000008 -+#define CST4331_LDO_PAR 0x00000010 -+ -+/* 4315 resource */ -+#define RES4315_CBUCK_LPOM 1 /* 0x00000002 */ -+#define RES4315_CBUCK_BURST 2 /* 0x00000004 */ -+#define RES4315_CBUCK_PWM 3 /* 0x00000008 */ -+#define RES4315_CLDO_PU 4 /* 0x00000010 */ -+#define RES4315_PALDO_PU 5 /* 0x00000020 */ -+#define RES4315_ILP_REQUEST 6 /* 0x00000040 */ -+#define RES4315_LNLDO1_PU 9 /* 0x00000200 */ -+#define RES4315_OTP_PU 10 /* 0x00000400 */ -+#define RES4315_LNLDO2_PU 12 /* 0x00001000 */ -+#define RES4315_XTAL_PU 13 /* 0x00002000 */ -+#define RES4315_ALP_AVAIL 14 /* 0x00004000 */ -+#define RES4315_RX_PWRSW_PU 15 /* 0x00008000 */ -+#define RES4315_TX_PWRSW_PU 16 /* 0x00010000 */ -+#define RES4315_RFPLL_PWRSW_PU 17 /* 0x00020000 */ -+#define RES4315_LOGEN_PWRSW_PU 18 /* 0x00040000 */ -+#define RES4315_AFE_PWRSW_PU 19 /* 0x00080000 */ -+#define RES4315_BBPLL_PWRSW_PU 20 /* 0x00100000 */ -+#define RES4315_HT_AVAIL 21 /* 0x00200000 */ -+ -+/* 4315 chip-specific ChipStatus register bits */ -+#define CST4315_SPROM_OTP_SEL_MASK 0x00000003 /* gpio [7:6], SDIO CIS selection */ -+#define CST4315_DEFCIS_SEL 0x00000000 /* use default CIS, OTP is powered up */ -+#define CST4315_SPROM_SEL 0x00000001 /* use SPROM, OTP is powered up */ -+#define CST4315_OTP_SEL 0x00000002 /* use OTP, OTP is powered up */ -+#define CST4315_OTP_PWRDN 0x00000003 /* use SPROM, OTP is powered down */ -+#define CST4315_SDIO_MODE 0x00000004 /* gpio [8], sdio/usb mode */ -+#define CST4315_RCAL_VALID 0x00000008 -+#define CST4315_RCAL_VALUE_MASK 0x000001f0 -+#define CST4315_RCAL_VALUE_SHIFT 4 -+#define CST4315_PALDO_EXTPNP 0x00000200 /* PALDO is configured with external PNP */ -+#define CST4315_CBUCK_MODE_MASK 0x00000c00 -+#define CST4315_CBUCK_MODE_BURST 0x00000400 -+#define CST4315_CBUCK_MODE_LPBURST 0x00000c00 -+ -+/* 4319 resources */ -+#define RES4319_CBUCK_LPOM 1 /* 0x00000002 */ -+#define RES4319_CBUCK_BURST 2 /* 0x00000004 */ -+#define RES4319_CBUCK_PWM 3 /* 0x00000008 */ -+#define RES4319_CLDO_PU 4 /* 0x00000010 */ -+#define RES4319_PALDO_PU 5 /* 0x00000020 */ -+#define RES4319_ILP_REQUEST 6 /* 0x00000040 */ -+#define RES4319_LNLDO1_PU 9 /* 0x00000200 */ -+#define RES4319_OTP_PU 10 /* 0x00000400 */ -+#define RES4319_LNLDO2_PU 12 /* 0x00001000 */ -+#define RES4319_XTAL_PU 13 /* 0x00002000 */ -+#define RES4319_ALP_AVAIL 14 /* 0x00004000 */ -+#define RES4319_RX_PWRSW_PU 15 /* 0x00008000 */ -+#define RES4319_TX_PWRSW_PU 16 /* 0x00010000 */ -+#define RES4319_RFPLL_PWRSW_PU 17 /* 0x00020000 */ -+#define RES4319_LOGEN_PWRSW_PU 18 /* 0x00040000 */ -+#define RES4319_AFE_PWRSW_PU 19 /* 0x00080000 */ -+#define RES4319_BBPLL_PWRSW_PU 20 /* 0x00100000 */ -+#define RES4319_HT_AVAIL 21 /* 0x00200000 */ -+ -+/* 4319 chip-specific ChipStatus register bits */ -+#define CST4319_SPI_CPULESSUSB 0x00000001 -+#define CST4319_SPI_CLK_POL 0x00000002 -+#define CST4319_SPI_CLK_PH 0x00000008 -+#define CST4319_SPROM_OTP_SEL_MASK 0x000000c0 /* gpio [7:6], SDIO CIS selection */ -+#define CST4319_SPROM_OTP_SEL_SHIFT 6 -+#define CST4319_DEFCIS_SEL 0x00000000 /* use default CIS, OTP is powered up */ -+#define CST4319_SPROM_SEL 0x00000040 /* use SPROM, OTP is powered up */ -+#define CST4319_OTP_SEL 0x00000080 /* use OTP, OTP is powered up */ -+#define CST4319_OTP_PWRDN 0x000000c0 /* use SPROM, OTP is powered down */ -+#define CST4319_SDIO_USB_MODE 0x00000100 /* gpio [8], sdio/usb mode */ -+#define CST4319_REMAP_SEL_MASK 0x00000600 -+#define CST4319_ILPDIV_EN 0x00000800 -+#define CST4319_XTAL_PD_POL 0x00001000 -+#define CST4319_LPO_SEL 0x00002000 -+#define CST4319_RES_INIT_MODE 0x0000c000 -+#define CST4319_PALDO_EXTPNP 0x00010000 /* PALDO is configured with external PNP */ -+#define CST4319_CBUCK_MODE_MASK 0x00060000 -+#define CST4319_CBUCK_MODE_BURST 0x00020000 -+#define CST4319_CBUCK_MODE_LPBURST 0x00060000 -+#define CST4319_RCAL_VALID 0x01000000 -+#define CST4319_RCAL_VALUE_MASK 0x3e000000 -+#define CST4319_RCAL_VALUE_SHIFT 25 -+ -+#define PMU1_PLL0_CHIPCTL0 0 -+#define PMU1_PLL0_CHIPCTL1 1 -+#define PMU1_PLL0_CHIPCTL2 2 -+#define CCTL_4319USB_XTAL_SEL_MASK 0x00180000 -+#define CCTL_4319USB_XTAL_SEL_SHIFT 19 -+#define CCTL_4319USB_48MHZ_PLL_SEL 1 -+#define CCTL_4319USB_24MHZ_PLL_SEL 2 -+ -+/* PMU resources for 4336 */ -+#define RES4336_CBUCK_LPOM 0 -+#define RES4336_CBUCK_BURST 1 -+#define RES4336_CBUCK_LP_PWM 2 -+#define RES4336_CBUCK_PWM 3 -+#define RES4336_CLDO_PU 4 -+#define RES4336_DIS_INT_RESET_PD 5 -+#define RES4336_ILP_REQUEST 6 -+#define RES4336_LNLDO_PU 7 -+#define RES4336_LDO3P3_PU 8 -+#define RES4336_OTP_PU 9 -+#define RES4336_XTAL_PU 10 -+#define RES4336_ALP_AVAIL 11 -+#define RES4336_RADIO_PU 12 -+#define RES4336_BG_PU 13 -+#define RES4336_VREG1p4_PU_PU 14 -+#define RES4336_AFE_PWRSW_PU 15 -+#define RES4336_RX_PWRSW_PU 16 -+#define RES4336_TX_PWRSW_PU 17 -+#define RES4336_BB_PWRSW_PU 18 -+#define RES4336_SYNTH_PWRSW_PU 19 -+#define RES4336_MISC_PWRSW_PU 20 -+#define RES4336_LOGEN_PWRSW_PU 21 -+#define RES4336_BBPLL_PWRSW_PU 22 -+#define RES4336_MACPHY_CLKAVAIL 23 -+#define RES4336_HT_AVAIL 24 -+#define RES4336_RSVD 25 -+ -+/* 4336 chip-specific ChipStatus register bits */ -+#define CST4336_SPI_MODE_MASK 0x00000001 -+#define CST4336_SPROM_PRESENT 0x00000002 -+#define CST4336_OTP_PRESENT 0x00000004 -+#define CST4336_ARMREMAP_0 0x00000008 -+#define CST4336_ILPDIV_EN_MASK 0x00000010 -+#define CST4336_ILPDIV_EN_SHIFT 4 -+#define CST4336_XTAL_PD_POL_MASK 0x00000020 -+#define CST4336_XTAL_PD_POL_SHIFT 5 -+#define CST4336_LPO_SEL_MASK 0x00000040 -+#define CST4336_LPO_SEL_SHIFT 6 -+#define CST4336_RES_INIT_MODE_MASK 0x00000180 -+#define CST4336_RES_INIT_MODE_SHIFT 7 -+#define CST4336_CBUCK_MODE_MASK 0x00000600 -+#define CST4336_CBUCK_MODE_SHIFT 9 -+ -+/* 4336 Chip specific PMU ChipControl register bits */ -+#define PCTL_4336_SERIAL_ENAB (1 << 24) -+ -+/* 4330 resources */ -+#define RES4330_CBUCK_LPOM 0 -+#define RES4330_CBUCK_BURST 1 -+#define RES4330_CBUCK_LP_PWM 2 -+#define RES4330_CBUCK_PWM 3 -+#define RES4330_CLDO_PU 4 -+#define RES4330_DIS_INT_RESET_PD 5 -+#define RES4330_ILP_REQUEST 6 -+#define RES4330_LNLDO_PU 7 -+#define RES4330_LDO3P3_PU 8 -+#define RES4330_OTP_PU 9 -+#define RES4330_XTAL_PU 10 -+#define RES4330_ALP_AVAIL 11 -+#define RES4330_RADIO_PU 12 -+#define RES4330_BG_PU 13 -+#define RES4330_VREG1p4_PU_PU 14 -+#define RES4330_AFE_PWRSW_PU 15 -+#define RES4330_RX_PWRSW_PU 16 -+#define RES4330_TX_PWRSW_PU 17 -+#define RES4330_BB_PWRSW_PU 18 -+#define RES4330_SYNTH_PWRSW_PU 19 -+#define RES4330_MISC_PWRSW_PU 20 -+#define RES4330_LOGEN_PWRSW_PU 21 -+#define RES4330_BBPLL_PWRSW_PU 22 -+#define RES4330_MACPHY_CLKAVAIL 23 -+#define RES4330_HT_AVAIL 24 -+#define RES4330_5gRX_PWRSW_PU 25 -+#define RES4330_5gTX_PWRSW_PU 26 -+#define RES4330_5g_LOGEN_PWRSW_PU 27 -+ -+/* 4330 chip-specific ChipStatus register bits */ -+#define CST4330_CHIPMODE_SDIOD(cs) (((cs) & 0x7) < 6) /* SDIO || gSPI */ -+#define CST4330_CHIPMODE_USB20D(cs) (((cs) & 0x7) >= 6) /* USB || USBDA */ -+#define CST4330_CHIPMODE_SDIO(cs) (((cs) & 0x4) == 0) /* SDIO */ -+#define CST4330_CHIPMODE_GSPI(cs) (((cs) & 0x6) == 4) /* gSPI */ -+#define CST4330_CHIPMODE_USB(cs) (((cs) & 0x7) == 6) /* USB packet-oriented */ -+#define CST4330_CHIPMODE_USBDA(cs) (((cs) & 0x7) == 7) /* USB Direct Access */ -+#define CST4330_OTP_PRESENT 0x00000010 -+#define CST4330_LPO_AUTODET_EN 0x00000020 -+#define CST4330_ARMREMAP_0 0x00000040 -+#define CST4330_SPROM_PRESENT 0x00000080 /* takes priority over OTP if both set */ -+#define CST4330_ILPDIV_EN 0x00000100 -+#define CST4330_LPO_SEL 0x00000200 -+#define CST4330_RES_INIT_MODE_SHIFT 10 -+#define CST4330_RES_INIT_MODE_MASK 0x00000c00 -+#define CST4330_CBUCK_MODE_SHIFT 12 -+#define CST4330_CBUCK_MODE_MASK 0x00003000 -+#define CST4330_CBUCK_POWER_OK 0x00004000 -+#define CST4330_BB_PLL_LOCKED 0x00008000 -+#define SOCDEVRAM_BP_ADDR 0x1E000000 -+#define SOCDEVRAM_ARM_ADDR 0x00800000 -+ -+/* 4330 Chip specific PMU ChipControl register bits */ -+#define PCTL_4330_SERIAL_ENAB (1 << 24) -+ -+/* 4330 Chip specific ChipControl register bits */ -+#define CCTRL_4330_GPIO_SEL 0x00000001 /* 1=select GPIOs to be muxed out */ -+#define CCTRL_4330_ERCX_SEL 0x00000002 /* 1=select ERCX BT coex to be muxed out */ -+#define CCTRL_4330_SDIO_HOST_WAKE 0x00000004 /* SDIO: 1=configure GPIO0 for host wake */ -+#define CCTRL_4330_JTAG_DISABLE 0x00000008 /* 1=disable JTAG interface on mux'd pins */ -+ -+/* 4334 resources */ -+#define RES4334_LPLDO_PU 0 -+#define RES4334_RESET_PULLDN_DIS 1 -+#define RES4334_PMU_BG_PU 2 -+#define RES4334_HSIC_LDO_PU 3 -+#define RES4334_CBUCK_LPOM_PU 4 -+#define RES4334_CBUCK_PFM_PU 5 -+#define RES4334_CLDO_PU 6 -+#define RES4334_LPLDO2_LVM 7 -+#define RES4334_LNLDO_PU 8 -+#define RES4334_LDO3P3_PU 9 -+#define RES4334_OTP_PU 10 -+#define RES4334_XTAL_PU 11 -+#define RES4334_WL_PWRSW_PU 12 -+#define RES4334_LQ_AVAIL 13 -+#define RES4334_LOGIC_RET 14 -+#define RES4334_MEM_SLEEP 15 -+#define RES4334_MACPHY_RET 16 -+#define RES4334_WL_CORE_READY 17 -+#define RES4334_ILP_REQ 18 -+#define RES4334_ALP_AVAIL 19 -+#define RES4334_MISC_PWRSW_PU 20 -+#define RES4334_SYNTH_PWRSW_PU 21 -+#define RES4334_RX_PWRSW_PU 22 -+#define RES4334_RADIO_PU 23 -+#define RES4334_WL_PMU_PU 24 -+#define RES4334_VCO_LDO_PU 25 -+#define RES4334_AFE_LDO_PU 26 -+#define RES4334_RX_LDO_PU 27 -+#define RES4334_TX_LDO_PU 28 -+#define RES4334_HT_AVAIL 29 -+#define RES4334_MACPHY_CLK_AVAIL 30 -+ -+/* 4334 chip-specific ChipStatus register bits */ -+#define CST4334_CHIPMODE_MASK 7 -+#define CST4334_SDIO_MODE 0x00000000 -+#define CST4334_SPI_MODE 0x00000004 -+#define CST4334_HSIC_MODE 0x00000006 -+#define CST4334_BLUSB_MODE 0x00000007 -+#define CST4334_CHIPMODE_HSIC(cs) (((cs) & CST4334_CHIPMODE_MASK) == CST4334_HSIC_MODE) -+#define CST4334_OTP_PRESENT 0x00000010 -+#define CST4334_LPO_AUTODET_EN 0x00000020 -+#define CST4334_ARMREMAP_0 0x00000040 -+#define CST4334_SPROM_PRESENT 0x00000080 -+#define CST4334_ILPDIV_EN_MASK 0x00000100 -+#define CST4334_ILPDIV_EN_SHIFT 8 -+#define CST4334_LPO_SEL_MASK 0x00000200 -+#define CST4334_LPO_SEL_SHIFT 9 -+#define CST4334_RES_INIT_MODE_MASK 0x00000C00 -+#define CST4334_RES_INIT_MODE_SHIFT 10 -+ -+/* 4334 Chip specific PMU ChipControl register bits */ -+#define PCTL_4334_GPIO3_ENAB (1 << 3) -+ -+/* 4334 Chip control */ -+#define CCTRL4334_HSIC_LDO_PU (1 << 23) -+ -+/* 4324 Chip specific ChipControl1 register bits */ -+#define CCTRL1_4324_GPIO_SEL (1 << 0) /* 1=select GPIOs to be muxed out */ -+#define CCTRL1_4324_SDIO_HOST_WAKE (1 << 2) /* SDIO: 1=configure GPIO0 for host wake */ -+ -+ -+/* 4313 resources */ -+#define RES4313_BB_PU_RSRC 0 -+#define RES4313_ILP_REQ_RSRC 1 -+#define RES4313_XTAL_PU_RSRC 2 -+#define RES4313_ALP_AVAIL_RSRC 3 -+#define RES4313_RADIO_PU_RSRC 4 -+#define RES4313_BG_PU_RSRC 5 -+#define RES4313_VREG1P4_PU_RSRC 6 -+#define RES4313_AFE_PWRSW_RSRC 7 -+#define RES4313_RX_PWRSW_RSRC 8 -+#define RES4313_TX_PWRSW_RSRC 9 -+#define RES4313_BB_PWRSW_RSRC 10 -+#define RES4313_SYNTH_PWRSW_RSRC 11 -+#define RES4313_MISC_PWRSW_RSRC 12 -+#define RES4313_BB_PLL_PWRSW_RSRC 13 -+#define RES4313_HT_AVAIL_RSRC 14 -+#define RES4313_MACPHY_CLK_AVAIL_RSRC 15 -+ -+/* 4313 chip-specific ChipStatus register bits */ -+#define CST4313_SPROM_PRESENT 1 -+#define CST4313_OTP_PRESENT 2 -+#define CST4313_SPROM_OTP_SEL_MASK 0x00000002 -+#define CST4313_SPROM_OTP_SEL_SHIFT 0 -+ -+/* 4313 Chip specific ChipControl register bits */ -+#define CCTRL_4313_12MA_LED_DRIVE 0x00000007 /* 12 mA drive strengh for later 4313 */ -+ -+/* PMU respources for 4314 */ -+#define RES4314_LPLDO_PU 0 -+#define RES4314_PMU_SLEEP_DIS 1 -+#define RES4314_PMU_BG_PU 2 -+#define RES4314_CBUCK_LPOM_PU 3 -+#define RES4314_CBUCK_PFM_PU 4 -+#define RES4314_CLDO_PU 5 -+#define RES4314_LPLDO2_LVM 6 -+#define RES4314_WL_PMU_PU 7 -+#define RES4314_LNLDO_PU 8 -+#define RES4314_LDO3P3_PU 9 -+#define RES4314_OTP_PU 10 -+#define RES4314_XTAL_PU 11 -+#define RES4314_WL_PWRSW_PU 12 -+#define RES4314_LQ_AVAIL 13 -+#define RES4314_LOGIC_RET 14 -+#define RES4314_MEM_SLEEP 15 -+#define RES4314_MACPHY_RET 16 -+#define RES4314_WL_CORE_READY 17 -+#define RES4314_ILP_REQ 18 -+#define RES4314_ALP_AVAIL 19 -+#define RES4314_MISC_PWRSW_PU 20 -+#define RES4314_SYNTH_PWRSW_PU 21 -+#define RES4314_RX_PWRSW_PU 22 -+#define RES4314_RADIO_PU 23 -+#define RES4314_VCO_LDO_PU 24 -+#define RES4314_AFE_LDO_PU 25 -+#define RES4314_RX_LDO_PU 26 -+#define RES4314_TX_LDO_PU 27 -+#define RES4314_HT_AVAIL 28 -+#define RES4314_MACPHY_CLK_AVAIL 29 -+ -+/* 4314 chip-specific ChipStatus register bits */ -+#define CST4314_OTP_ENABLED 0x00200000 -+ -+/* 43228 resources */ -+#define RES43228_NOT_USED 0 -+#define RES43228_ILP_REQUEST 1 -+#define RES43228_XTAL_PU 2 -+#define RES43228_ALP_AVAIL 3 -+#define RES43228_PLL_EN 4 -+#define RES43228_HT_PHY_AVAIL 5 -+ -+/* 43228 chipstatus reg bits */ -+#define CST43228_ILP_DIV_EN 0x1 -+#define CST43228_OTP_PRESENT 0x2 -+#define CST43228_SERDES_REFCLK_PADSEL 0x4 -+#define CST43228_SDIO_MODE 0x8 -+#define CST43228_SDIO_OTP_PRESENT 0x10 -+#define CST43228_SDIO_RESET 0x20 -+ -+/* 4706 chipstatus reg bits */ -+#define CST4706_PKG_OPTION (1<<0) /* 0: full-featured package 1: low-cost package */ -+#define CST4706_SFLASH_PRESENT (1<<1) /* 0: parallel, 1: serial flash is present */ -+#define CST4706_SFLASH_TYPE (1<<2) /* 0: 8b-p/ST-s flash, 1: 16b-p/Atmal-s flash */ -+#define CST4706_MIPS_BENDIAN (1<<3) /* 0: little, 1: big endian */ -+#define CST4706_PCIE1_DISABLE (1<<5) /* PCIE1 enable strap pin */ -+ -+/* 4706 flashstrconfig reg bits */ -+#define FLSTRCF4706_MASK 0x000000ff -+#define FLSTRCF4706_SF1 0x00000001 /* 2nd serial flash present */ -+#define FLSTRCF4706_PF1 0x00000002 /* 2nd parallel flash present */ -+#define FLSTRCF4706_SF1_TYPE 0x00000004 /* 2nd serial flash type : 0 : ST, 1 : Atmel */ -+#define FLSTRCF4706_NF1 0x00000008 /* 2nd NAND flash present */ -+#define FLSTRCF4706_1ST_MADDR_SEG_MASK 0x000000f0 /* Valid value mask */ -+#define FLSTRCF4706_1ST_MADDR_SEG_4MB 0x00000010 /* 4MB */ -+#define FLSTRCF4706_1ST_MADDR_SEG_8MB 0x00000020 /* 8MB */ -+#define FLSTRCF4706_1ST_MADDR_SEG_16MB 0x00000030 /* 16MB */ -+#define FLSTRCF4706_1ST_MADDR_SEG_32MB 0x00000040 /* 32MB */ -+#define FLSTRCF4706_1ST_MADDR_SEG_64MB 0x00000050 /* 64MB */ -+#define FLSTRCF4706_1ST_MADDR_SEG_128MB 0x00000060 /* 128MB */ -+#define FLSTRCF4706_1ST_MADDR_SEG_256MB 0x00000070 /* 256MB */ -+ -+/* 4360 Chip specific ChipControl register bits */ -+#define CCTRL4360_SECI_MODE (1 << 2) -+#define CCTRL4360_BTSWCTRL_MODE (1 << 3) -+#define CCTRL4360_EXTRA_FEMCTRL_MODE (1 << 8) -+#define CCTRL4360_BT_LGCY_MODE (1 << 9) -+#define CCTRL4360_CORE2FEMCTRL4_ON (1 << 21) -+ -+/* 4360 PMU resources and chip status bits */ -+#define RES4360_REGULATOR 0 -+#define RES4360_ILP_AVAIL 1 -+#define RES4360_ILP_REQ 2 -+#define RES4360_XTAL_PU 3 -+#define RES4360_ALP_AVAIL 4 -+#define RES4360_BBPLLPWRSW_PU 5 -+#define RES4360_HT_AVAIL 6 -+#define RES4360_OTP_PU 7 -+#define RES4360_USBLDO_PU 8 -+#define RES4360_USBPLL_PWRSW_PU 9 -+#define RES4360_LQ_AVAIL 10 -+ -+#define CST4360_XTAL_40MZ 0x00000001 -+#define CST4360_SFLASH 0x00000002 -+#define CST4360_SPROM_PRESENT 0x00000004 -+#define CST4360_SFLASH_TYPE 0x00000004 -+#define CST4360_OTP_ENABLED 0x00000008 -+#define CST4360_REMAP_ROM 0x00000010 -+#define CST4360_RSRC_INIT_MODE_MASK 0x00000060 -+#define CST4360_RSRC_INIT_MODE_SHIFT 5 -+#define CST4360_ILP_DIVEN 0x00000080 -+#define CST4360_MODE_USB 0x00000100 -+#define CST4360_SPROM_SIZE_MASK 0x00000600 -+#define CST4360_SPROM_SIZE_SHIFT 9 -+#define CST4360_BBPLL_LOCK 0x00000800 -+#define CST4360_AVBBPLL_LOCK 0x00001000 -+#define CST4360_USBBBPLL_LOCK 0x00002000 -+ -+#define CCTL_4360_UART_SEL 2 -+ -+/* 4335 resources */ -+#define RES4335_LPLDO_PO 0 -+#define RES4335_PMU_BG_PU 1 -+#define RES4335_PMU_SLEEP 2 -+#define RES4335_RSVD_3 3 -+#define RES4335_CBUCK_LPOM_PU 4 -+#define RES4335_CBUCK_PFM_PU 5 -+#define RES4335_RSVD_6 6 -+#define RES4335_RSVD_7 7 -+#define RES4335_LNLDO_PU 8 -+#define RES4335_XTALLDO_PU 9 -+#define RES4335_LDO3P3_PU 10 -+#define RES4335_OTP_PU 11 -+#define RES4335_XTAL_PU 12 -+#define RES4335_SR_CLK_START 13 -+#define RES4335_LQ_AVAIL 14 -+#define RES4335_LQ_START 15 -+#define RES4335_RSVD_16 16 -+#define RES4335_WL_CORE_RDY 17 -+#define RES4335_ILP_REQ 18 -+#define RES4335_ALP_AVAIL 19 -+#define RES4335_MINI_PMU 20 -+#define RES4335_RADIO_PU 21 -+#define RES4335_SR_CLK_STABLE 22 -+#define RES4335_SR_SAVE_RESTORE 23 -+#define RES4335_SR_PHY_PWRSW 24 -+#define RES4335_SR_VDDM_PWRSW 25 -+#define RES4335_SR_SUBCORE_PWRSW 26 -+#define RES4335_SR_SLEEP 27 -+#define RES4335_HT_START 28 -+#define RES4335_HT_AVAIL 29 -+#define RES4335_MACPHY_CLKAVAIL 30 -+ -+/* 4335 Chip specific ChipStatus register bits */ -+#define CST4335_SPROM_MASK 0x00000020 -+#define CST4335_SFLASH_MASK 0x00000040 -+#define CST4335_RES_INIT_MODE_SHIFT 7 -+#define CST4335_RES_INIT_MODE_MASK 0x00000180 -+#define CST4335_CHIPMODE_MASK 0xF -+#define CST4335_CHIPMODE_SDIOD(cs) (((cs) & (1 << 0)) != 0) /* SDIO */ -+#define CST4335_CHIPMODE_GSPI(cs) (((cs) & (1 << 1)) != 0) /* gSPI */ -+#define CST4335_CHIPMODE_USB20D(cs) (((cs) & (1 << 2)) != 0) /* USB || USBDA */ -+#define CST4335_CHIPMODE_PCIE(cs) (((cs) & (1 << 3)) != 0) /* PCIE */ -+ -+/* 4335 Chip specific ChipControl1 register bits */ -+#define CCTRL1_4335_GPIO_SEL (1 << 0) /* 1=select GPIOs to be muxed out */ -+#define CCTRL1_4335_SDIO_HOST_WAKE (1 << 2) /* SDIO: 1=configure GPIO0 for host wake */ -+ -+ -+#define CR4_RAM_BASE (0x180000) -+#define PATCHTBL_SIZE (0x800) -+ -+ -+/* 4335 resources--END */ -+ -+/* GCI chipcontrol register indices */ -+#define CC_GCI_CHIPCTRL_00 (0) -+#define CC_GCI_CHIPCTRL_01 (1) -+#define CC_GCI_CHIPCTRL_02 (2) -+#define CC_GCI_CHIPCTRL_03 (3) -+#define CC_GCI_CHIPCTRL_04 (4) -+#define CC_GCI_CHIPCTRL_05 (5) -+#define CC_GCI_CHIPCTRL_06 (6) -+#define CC_GCI_CHIPCTRL_07 (7) -+#define CC_GCI_CHIPCTRL_08 (8) -+ -+#define CC_GCI_NUMCHIPCTRLREGS(cap1) ((cap1 & 0xF00) >> 8) -+ -+/* 4335 pins -+* note: only the values set as default/used are added here. -+*/ -+#define CC4335_PIN_GPIO_00 (0) -+#define CC4335_PIN_GPIO_01 (1) -+#define CC4335_PIN_GPIO_02 (2) -+#define CC4335_PIN_GPIO_03 (3) -+#define CC4335_PIN_GPIO_04 (4) -+#define CC4335_PIN_GPIO_05 (5) -+#define CC4335_PIN_GPIO_06 (6) -+#define CC4335_PIN_GPIO_07 (7) -+#define CC4335_PIN_GPIO_08 (8) -+#define CC4335_PIN_GPIO_09 (9) -+#define CC4335_PIN_GPIO_10 (10) -+#define CC4335_PIN_GPIO_11 (11) -+#define CC4335_PIN_GPIO_12 (12) -+#define CC4335_PIN_GPIO_13 (13) -+#define CC4335_PIN_GPIO_14 (14) -+#define CC4335_PIN_GPIO_15 (15) -+#define CC4335_PIN_SDIO_CLK (16) -+#define CC4335_PIN_SDIO_CMD (17) -+#define CC4335_PIN_SDIO_DATA0 (18) -+#define CC4335_PIN_SDIO_DATA1 (19) -+#define CC4335_PIN_SDIO_DATA2 (20) -+#define CC4335_PIN_SDIO_DATA3 (21) -+#define CC4335_PIN_RF_SW_CTRL_0 (22) -+#define CC4335_PIN_RF_SW_CTRL_1 (23) -+#define CC4335_PIN_RF_SW_CTRL_2 (24) -+#define CC4335_PIN_RF_SW_CTRL_3 (25) -+#define CC4335_PIN_RF_SW_CTRL_4 (26) -+#define CC4335_PIN_RF_SW_CTRL_5 (27) -+#define CC4335_PIN_RF_SW_CTRL_6 (28) -+#define CC4335_PIN_RF_SW_CTRL_7 (29) -+#define CC4335_PIN_RF_SW_CTRL_8 (30) -+#define CC4335_PIN_RF_SW_CTRL_9 (31) -+ -+/* 4335 GCI function sel values -+*/ -+#define CC4335_FNSEL_HWDEF (0) -+#define CC4335_FNSEL_SAMEASPIN (1) -+#define CC4335_FNSEL_GPIO0 (2) -+#define CC4335_FNSEL_GPIO1 (3) -+#define CC4335_FNSEL_GCI0 (4) -+#define CC4335_FNSEL_GCI1 (5) -+#define CC4335_FNSEL_UART (6) -+#define CC4335_FNSEL_SFLASH (7) -+#define CC4335_FNSEL_SPROM (8) -+#define CC4335_FNSEL_MISC0 (9) -+#define CC4335_FNSEL_MISC1 (10) -+#define CC4335_FNSEL_MISC2 (11) -+#define CC4335_FNSEL_IND (12) -+#define CC4335_FNSEL_PDN (13) -+#define CC4335_FNSEL_PUP (14) -+#define CC4335_FNSEL_TRI (15) -+ -+/* find the 4 bit mask given the bit position */ -+#define GCIMASK(pos) (((uint32)0xF) << pos) -+ -+/* get the value which can be used to directly OR with chipcontrol reg */ -+#define GCIPOSVAL(val, pos) ((((uint32)val) << pos) & GCIMASK(pos)) -+ -+/* 4335 MUX options. each nibble belongs to a setting. Non-zero value specifies a logic -+* for now only UART for bootloader. -+*/ -+#define MUXENAB4335_UART_MASK (0x0000000f) -+ -+ -+/* defines to detect active host interface in use */ -+#define CHIP_HOSTIF_USB(sih) (si_chip_hostif(sih) & CST4360_MODE_USB) -+ -+/* -+* Maximum delay for the PMU state transition in us. -+* This is an upper bound intended for spinwaits etc. -+*/ -+#define PMU_MAX_TRANSITION_DLY 20000 -+ -+/* PMU resource up transition time in ILP cycles */ -+#define PMURES_UP_TRANSITION 2 -+ -+/* -+* Information from BT to WLAN over eci_inputlo, eci_inputmi & -+* eci_inputhi register. Rev >=21 -+*/ -+/* Fields in eci_inputlo register - [0:31] */ -+#define ECI_INLO_TASKTYPE_MASK 0x0000000f /* [3:0] - 4 bits */ -+#define ECI_INLO_TASKTYPE_SHIFT 0 -+#define ECI_INLO_PKTDUR_MASK 0x000000f0 /* [7:4] - 4 bits */ -+#define ECI_INLO_PKTDUR_SHIFT 4 -+#define ECI_INLO_ROLE_MASK 0x00000100 /* [8] - 1 bits */ -+#define ECI_INLO_ROLE_SHIFT 8 -+#define ECI_INLO_MLP_MASK 0x00000e00 /* [11:9] - 3 bits */ -+#define ECI_INLO_MLP_SHIFT 9 -+#define ECI_INLO_TXPWR_MASK 0x000ff000 /* [19:12] - 8 bits */ -+#define ECI_INLO_TXPWR_SHIFT 12 -+#define ECI_INLO_RSSI_MASK 0x0ff00000 /* [27:20] - 8 bits */ -+#define ECI_INLO_RSSI_SHIFT 20 -+#define ECI_INLO_VAD_MASK 0x10000000 /* [28] - 1 bits */ -+#define ECI_INLO_VAD_SHIFT 28 -+ -+/* -+* Register eci_inputlo bitfield values. -+* - BT packet type information bits [7:0] -+*/ -+/* [3:0] - Task (link) type */ -+#define BT_ACL 0x00 -+#define BT_SCO 0x01 -+#define BT_eSCO 0x02 -+#define BT_A2DP 0x03 -+#define BT_SNIFF 0x04 -+#define BT_PAGE_SCAN 0x05 -+#define BT_INQUIRY_SCAN 0x06 -+#define BT_PAGE 0x07 -+#define BT_INQUIRY 0x08 -+#define BT_MSS 0x09 -+#define BT_PARK 0x0a -+#define BT_RSSISCAN 0x0b -+#define BT_MD_ACL 0x0c -+#define BT_MD_eSCO 0x0d -+#define BT_SCAN_WITH_SCO_LINK 0x0e -+#define BT_SCAN_WITHOUT_SCO_LINK 0x0f -+/* [7:4] = packet duration code */ -+/* [8] - Master / Slave */ -+#define BT_MASTER 0 -+#define BT_SLAVE 1 -+/* [11:9] - multi-level priority */ -+#define BT_LOWEST_PRIO 0x0 -+#define BT_HIGHEST_PRIO 0x3 -+/* [19:12] - BT transmit power */ -+/* [27:20] - BT RSSI */ -+/* [28] - VAD silence */ -+/* [31:29] - Undefined */ -+/* Register eci_inputmi values - [32:63] - none defined */ -+/* [63:32] - Undefined */ -+ -+/* Information from WLAN to BT over eci_output register. */ -+/* Fields in eci_output register - [0:31] */ -+#define ECI48_OUT_MASKMAGIC_HIWORD 0x55550000 -+#define ECI_OUT_CHANNEL_MASK(ccrev) ((ccrev) < 35 ? 0xf : (ECI48_OUT_MASKMAGIC_HIWORD | 0xf000)) -+#define ECI_OUT_CHANNEL_SHIFT(ccrev) ((ccrev) < 35 ? 0 : 12) -+#define ECI_OUT_BW_MASK(ccrev) ((ccrev) < 35 ? 0x70 : (ECI48_OUT_MASKMAGIC_HIWORD | 0xe00)) -+#define ECI_OUT_BW_SHIFT(ccrev) ((ccrev) < 35 ? 4 : 9) -+#define ECI_OUT_ANTENNA_MASK(ccrev) ((ccrev) < 35 ? 0x80 : (ECI48_OUT_MASKMAGIC_HIWORD | 0x100)) -+#define ECI_OUT_ANTENNA_SHIFT(ccrev) ((ccrev) < 35 ? 7 : 8) -+#define ECI_OUT_SIMUL_TXRX_MASK(ccrev) \ -+ ((ccrev) < 35 ? 0x10000 : (ECI48_OUT_MASKMAGIC_HIWORD | 0x80)) -+#define ECI_OUT_SIMUL_TXRX_SHIFT(ccrev) ((ccrev) < 35 ? 16 : 7) -+#define ECI_OUT_FM_DISABLE_MASK(ccrev) \ -+ ((ccrev) < 35 ? 0x40000 : (ECI48_OUT_MASKMAGIC_HIWORD | 0x40)) -+#define ECI_OUT_FM_DISABLE_SHIFT(ccrev) ((ccrev) < 35 ? 18 : 6) -+ -+/* Indicate control of ECI bits between s/w and dot11mac. -+ * 0 => FW control, 1=> MAC/ucode control -+ -+ * Current assignment (ccrev >= 35): -+ * 0 - TxConf (ucode) -+ * 38 - FM disable (wl) -+ * 39 - Allow sim rx (ucode) -+ * 40 - Num antennas (wl) -+ * 43:41 - WLAN channel exclusion BW (wl) -+ * 47:44 - WLAN channel (wl) -+ * -+ * (ccrev < 35) -+ * 15:0 - wl -+ * 16 - -+ * 18 - FM disable -+ * 30 - wl interrupt -+ * 31 - ucode interrupt -+ * others - unassigned (presumed to be with dot11mac/ucode) -+ */ -+#define ECI_MACCTRL_BITS 0xbffb0000 -+#define ECI_MACCTRLLO_BITS 0x1 -+#define ECI_MACCTRLHI_BITS 0xFF -+ -+/* SECI configuration */ -+#define SECI_MODE_UART 0x0 -+#define SECI_MODE_SECI 0x1 -+#define SECI_MODE_LEGACY_3WIRE_BT 0x2 -+#define SECI_MODE_LEGACY_3WIRE_WLAN 0x3 -+#define SECI_MODE_HALF_SECI 0x4 -+ -+#define SECI_RESET (1 << 0) -+#define SECI_RESET_BAR_UART (1 << 1) -+#define SECI_ENAB_SECI_ECI (1 << 2) -+#define SECI_ENAB_SECIOUT_DIS (1 << 3) -+#define SECI_MODE_MASK 0x7 -+#define SECI_MODE_SHIFT 4 /* (bits 5, 6, 7) */ -+#define SECI_UPD_SECI (1 << 7) -+ -+#define SECI_SIGNOFF_0 0xDB -+#define SECI_SIGNOFF_1 0 -+ -+/* seci clk_ctl_st bits */ -+#define CLKCTL_STS_SECI_CLK_REQ (1 << 8) -+#define CLKCTL_STS_SECI_CLK_AVAIL (1 << 24) -+ -+#define SECI_UART_MSR_CTS_STATE (1 << 0) -+#define SECI_UART_MSR_RTS_STATE (1 << 1) -+#define SECI_UART_SECI_IN_STATE (1 << 2) -+#define SECI_UART_SECI_IN2_STATE (1 << 3) -+ -+/* SECI UART LCR/MCR register bits */ -+#define SECI_UART_LCR_STOP_BITS (1 << 0) /* 0 - 1bit, 1 - 2bits */ -+#define SECI_UART_LCR_PARITY_EN (1 << 1) -+#define SECI_UART_LCR_PARITY (1 << 2) /* 0 - odd, 1 - even */ -+#define SECI_UART_LCR_RX_EN (1 << 3) -+#define SECI_UART_LCR_LBRK_CTRL (1 << 4) /* 1 => SECI_OUT held low */ -+#define SECI_UART_LCR_TXO_EN (1 << 5) -+#define SECI_UART_LCR_RTSO_EN (1 << 6) -+#define SECI_UART_LCR_SLIPMODE_EN (1 << 7) -+#define SECI_UART_LCR_RXCRC_CHK (1 << 8) -+#define SECI_UART_LCR_TXCRC_INV (1 << 9) -+#define SECI_UART_LCR_TXCRC_LSBF (1 << 10) -+#define SECI_UART_LCR_TXCRC_EN (1 << 11) -+ -+#define SECI_UART_MCR_TX_EN (1 << 0) -+#define SECI_UART_MCR_PRTS (1 << 1) -+#define SECI_UART_MCR_SWFLCTRL_EN (1 << 2) -+#define SECI_UART_MCR_HIGHRATE_EN (1 << 3) -+#define SECI_UART_MCR_LOOPBK_EN (1 << 4) -+#define SECI_UART_MCR_AUTO_RTS (1 << 5) -+#define SECI_UART_MCR_AUTO_TX_DIS (1 << 6) -+#define SECI_UART_MCR_BAUD_ADJ_EN (1 << 7) -+#define SECI_UART_MCR_XONOFF_RPT (1 << 9) -+ -+/* WLAN channel numbers - used from wifi.h */ -+ -+/* WLAN BW */ -+#define ECI_BW_20 0x0 -+#define ECI_BW_25 0x1 -+#define ECI_BW_30 0x2 -+#define ECI_BW_35 0x3 -+#define ECI_BW_40 0x4 -+#define ECI_BW_45 0x5 -+#define ECI_BW_50 0x6 -+#define ECI_BW_ALL 0x7 -+ -+/* WLAN - number of antenna */ -+#define WLAN_NUM_ANT1 TXANT_0 -+#define WLAN_NUM_ANT2 TXANT_1 -+ -+#endif /* _SBCHIPC_H */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/sbconfig.h b/drivers/net/ethernet/broadcom/gmac/src/include/sbconfig.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/sbconfig.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/sbconfig.h 2017-11-09 17:53:44.005292000 +0800 -@@ -0,0 +1,276 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom SiliconBackplane hardware register definitions. -+ * -+ * $Id: sbconfig.h 241182 2011-02-17 21:50:03Z $ -+ */ -+ -+#ifndef _SBCONFIG_H -+#define _SBCONFIG_H -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif -+ -+/* enumeration in SB is based on the premise that cores are contiguos in the -+ * enumeration space. -+ */ -+#define SB_BUS_SIZE 0x10000 /* Each bus gets 64Kbytes for cores */ -+#define SB_BUS_BASE(b) (SI_ENUM_BASE + (b) * SB_BUS_SIZE) -+#define SB_BUS_MAXCORES (SB_BUS_SIZE / SI_CORE_SIZE) /* Max cores per bus */ -+ -+/* -+ * Sonics Configuration Space Registers. -+ */ -+#define SBCONFIGOFF 0xf00 /* core sbconfig regs are top 256bytes of regs */ -+#define SBCONFIGSIZE 256 /* sizeof (sbconfig_t) */ -+ -+#define SBIPSFLAG 0x08 -+#define SBTPSFLAG 0x18 -+#define SBTMERRLOGA 0x48 /* sonics >= 2.3 */ -+#define SBTMERRLOG 0x50 /* sonics >= 2.3 */ -+#define SBADMATCH3 0x60 -+#define SBADMATCH2 0x68 -+#define SBADMATCH1 0x70 -+#define SBIMSTATE 0x90 -+#define SBINTVEC 0x94 -+#define SBTMSTATELOW 0x98 -+#define SBTMSTATEHIGH 0x9c -+#define SBBWA0 0xa0 -+#define SBIMCONFIGLOW 0xa8 -+#define SBIMCONFIGHIGH 0xac -+#define SBADMATCH0 0xb0 -+#define SBTMCONFIGLOW 0xb8 -+#define SBTMCONFIGHIGH 0xbc -+#define SBBCONFIG 0xc0 -+#define SBBSTATE 0xc8 -+#define SBACTCNFG 0xd8 -+#define SBFLAGST 0xe8 -+#define SBIDLOW 0xf8 -+#define SBIDHIGH 0xfc -+ -+/* All the previous registers are above SBCONFIGOFF, but with Sonics 2.3, we have -+ * a few registers *below* that line. I think it would be very confusing to try -+ * and change the value of SBCONFIGOFF, so I'm definig them as absolute offsets here, -+ */ -+ -+#define SBIMERRLOGA 0xea8 -+#define SBIMERRLOG 0xeb0 -+#define SBTMPORTCONNID0 0xed8 -+#define SBTMPORTLOCK0 0xef8 -+ -+#ifndef _LANGUAGE_ASSEMBLY -+ -+typedef volatile struct _sbconfig { -+ uint32 PAD[2]; -+ uint32 sbipsflag; /* initiator port ocp slave flag */ -+ uint32 PAD[3]; -+ uint32 sbtpsflag; /* target port ocp slave flag */ -+ uint32 PAD[11]; -+ uint32 sbtmerrloga; /* (sonics >= 2.3) */ -+ uint32 PAD; -+ uint32 sbtmerrlog; /* (sonics >= 2.3) */ -+ uint32 PAD[3]; -+ uint32 sbadmatch3; /* address match3 */ -+ uint32 PAD; -+ uint32 sbadmatch2; /* address match2 */ -+ uint32 PAD; -+ uint32 sbadmatch1; /* address match1 */ -+ uint32 PAD[7]; -+ uint32 sbimstate; /* initiator agent state */ -+ uint32 sbintvec; /* interrupt mask */ -+ uint32 sbtmstatelow; /* target state */ -+ uint32 sbtmstatehigh; /* target state */ -+ uint32 sbbwa0; /* bandwidth allocation table0 */ -+ uint32 PAD; -+ uint32 sbimconfiglow; /* initiator configuration */ -+ uint32 sbimconfighigh; /* initiator configuration */ -+ uint32 sbadmatch0; /* address match0 */ -+ uint32 PAD; -+ uint32 sbtmconfiglow; /* target configuration */ -+ uint32 sbtmconfighigh; /* target configuration */ -+ uint32 sbbconfig; /* broadcast configuration */ -+ uint32 PAD; -+ uint32 sbbstate; /* broadcast state */ -+ uint32 PAD[3]; -+ uint32 sbactcnfg; /* activate configuration */ -+ uint32 PAD[3]; -+ uint32 sbflagst; /* current sbflags */ -+ uint32 PAD[3]; -+ uint32 sbidlow; /* identification */ -+ uint32 sbidhigh; /* identification */ -+} sbconfig_t; -+ -+#endif /* _LANGUAGE_ASSEMBLY */ -+ -+/* sbipsflag */ -+#define SBIPS_INT1_MASK 0x3f /* which sbflags get routed to mips interrupt 1 */ -+#define SBIPS_INT1_SHIFT 0 -+#define SBIPS_INT2_MASK 0x3f00 /* which sbflags get routed to mips interrupt 2 */ -+#define SBIPS_INT2_SHIFT 8 -+#define SBIPS_INT3_MASK 0x3f0000 /* which sbflags get routed to mips interrupt 3 */ -+#define SBIPS_INT3_SHIFT 16 -+#define SBIPS_INT4_MASK 0x3f000000 /* which sbflags get routed to mips interrupt 4 */ -+#define SBIPS_INT4_SHIFT 24 -+ -+/* sbtpsflag */ -+#define SBTPS_NUM0_MASK 0x3f /* interrupt sbFlag # generated by this core */ -+#define SBTPS_F0EN0 0x40 /* interrupt is always sent on the backplane */ -+ -+/* sbtmerrlog */ -+#define SBTMEL_CM 0x00000007 /* command */ -+#define SBTMEL_CI 0x0000ff00 /* connection id */ -+#define SBTMEL_EC 0x0f000000 /* error code */ -+#define SBTMEL_ME 0x80000000 /* multiple error */ -+ -+/* sbimstate */ -+#define SBIM_PC 0xf /* pipecount */ -+#define SBIM_AP_MASK 0x30 /* arbitration policy */ -+#define SBIM_AP_BOTH 0x00 /* use both timeslaces and token */ -+#define SBIM_AP_TS 0x10 /* use timesliaces only */ -+#define SBIM_AP_TK 0x20 /* use token only */ -+#define SBIM_AP_RSV 0x30 /* reserved */ -+#define SBIM_IBE 0x20000 /* inbanderror */ -+#define SBIM_TO 0x40000 /* timeout */ -+#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */ -+#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */ -+ -+/* sbtmstatelow */ -+#define SBTML_RESET 0x0001 /* reset */ -+#define SBTML_REJ_MASK 0x0006 /* reject field */ -+#define SBTML_REJ 0x0002 /* reject */ -+#define SBTML_TMPREJ 0x0004 /* temporary reject, for error recovery */ -+ -+#define SBTML_SICF_SHIFT 16 /* Shift to locate the SI control flags in sbtml */ -+ -+/* sbtmstatehigh */ -+#define SBTMH_SERR 0x0001 /* serror */ -+#define SBTMH_INT 0x0002 /* interrupt */ -+#define SBTMH_BUSY 0x0004 /* busy */ -+#define SBTMH_TO 0x0020 /* timeout (sonics >= 2.3) */ -+ -+#define SBTMH_SISF_SHIFT 16 /* Shift to locate the SI status flags in sbtmh */ -+ -+/* sbbwa0 */ -+#define SBBWA_TAB0_MASK 0xffff /* lookup table 0 */ -+#define SBBWA_TAB1_MASK 0xffff /* lookup table 1 */ -+#define SBBWA_TAB1_SHIFT 16 -+ -+/* sbimconfiglow */ -+#define SBIMCL_STO_MASK 0x7 /* service timeout */ -+#define SBIMCL_RTO_MASK 0x70 /* request timeout */ -+#define SBIMCL_RTO_SHIFT 4 -+#define SBIMCL_CID_MASK 0xff0000 /* connection id */ -+#define SBIMCL_CID_SHIFT 16 -+ -+/* sbimconfighigh */ -+#define SBIMCH_IEM_MASK 0xc /* inband error mode */ -+#define SBIMCH_TEM_MASK 0x30 /* timeout error mode */ -+#define SBIMCH_TEM_SHIFT 4 -+#define SBIMCH_BEM_MASK 0xc0 /* bus error mode */ -+#define SBIMCH_BEM_SHIFT 6 -+ -+/* sbadmatch0 */ -+#define SBAM_TYPE_MASK 0x3 /* address type */ -+#define SBAM_AD64 0x4 /* reserved */ -+#define SBAM_ADINT0_MASK 0xf8 /* type0 size */ -+#define SBAM_ADINT0_SHIFT 3 -+#define SBAM_ADINT1_MASK 0x1f8 /* type1 size */ -+#define SBAM_ADINT1_SHIFT 3 -+#define SBAM_ADINT2_MASK 0x1f8 /* type2 size */ -+#define SBAM_ADINT2_SHIFT 3 -+#define SBAM_ADEN 0x400 /* enable */ -+#define SBAM_ADNEG 0x800 /* negative decode */ -+#define SBAM_BASE0_MASK 0xffffff00 /* type0 base address */ -+#define SBAM_BASE0_SHIFT 8 -+#define SBAM_BASE1_MASK 0xfffff000 /* type1 base address for the core */ -+#define SBAM_BASE1_SHIFT 12 -+#define SBAM_BASE2_MASK 0xffff0000 /* type2 base address for the core */ -+#define SBAM_BASE2_SHIFT 16 -+ -+/* sbtmconfiglow */ -+#define SBTMCL_CD_MASK 0xff /* clock divide */ -+#define SBTMCL_CO_MASK 0xf800 /* clock offset */ -+#define SBTMCL_CO_SHIFT 11 -+#define SBTMCL_IF_MASK 0xfc0000 /* interrupt flags */ -+#define SBTMCL_IF_SHIFT 18 -+#define SBTMCL_IM_MASK 0x3000000 /* interrupt mode */ -+#define SBTMCL_IM_SHIFT 24 -+ -+/* sbtmconfighigh */ -+#define SBTMCH_BM_MASK 0x3 /* busy mode */ -+#define SBTMCH_RM_MASK 0x3 /* retry mode */ -+#define SBTMCH_RM_SHIFT 2 -+#define SBTMCH_SM_MASK 0x30 /* stop mode */ -+#define SBTMCH_SM_SHIFT 4 -+#define SBTMCH_EM_MASK 0x300 /* sb error mode */ -+#define SBTMCH_EM_SHIFT 8 -+#define SBTMCH_IM_MASK 0xc00 /* int mode */ -+#define SBTMCH_IM_SHIFT 10 -+ -+/* sbbconfig */ -+#define SBBC_LAT_MASK 0x3 /* sb latency */ -+#define SBBC_MAX0_MASK 0xf0000 /* maxccntr0 */ -+#define SBBC_MAX0_SHIFT 16 -+#define SBBC_MAX1_MASK 0xf00000 /* maxccntr1 */ -+#define SBBC_MAX1_SHIFT 20 -+ -+/* sbbstate */ -+#define SBBS_SRD 0x1 /* st reg disable */ -+#define SBBS_HRD 0x2 /* hold reg disable */ -+ -+/* sbidlow */ -+#define SBIDL_CS_MASK 0x3 /* config space */ -+#define SBIDL_AR_MASK 0x38 /* # address ranges supported */ -+#define SBIDL_AR_SHIFT 3 -+#define SBIDL_SYNCH 0x40 /* sync */ -+#define SBIDL_INIT 0x80 /* initiator */ -+#define SBIDL_MINLAT_MASK 0xf00 /* minimum backplane latency */ -+#define SBIDL_MINLAT_SHIFT 8 -+#define SBIDL_MAXLAT 0xf000 /* maximum backplane latency */ -+#define SBIDL_MAXLAT_SHIFT 12 -+#define SBIDL_FIRST 0x10000 /* this initiator is first */ -+#define SBIDL_CW_MASK 0xc0000 /* cycle counter width */ -+#define SBIDL_CW_SHIFT 18 -+#define SBIDL_TP_MASK 0xf00000 /* target ports */ -+#define SBIDL_TP_SHIFT 20 -+#define SBIDL_IP_MASK 0xf000000 /* initiator ports */ -+#define SBIDL_IP_SHIFT 24 -+#define SBIDL_RV_MASK 0xf0000000 /* sonics backplane revision code */ -+#define SBIDL_RV_SHIFT 28 -+#define SBIDL_RV_2_2 0x00000000 /* version 2.2 or earlier */ -+#define SBIDL_RV_2_3 0x10000000 /* version 2.3 */ -+ -+/* sbidhigh */ -+#define SBIDH_RC_MASK 0x000f /* revision code */ -+#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */ -+#define SBIDH_RCE_SHIFT 8 -+#define SBCOREREV(sbidh) \ -+ ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK)) -+#define SBIDH_CC_MASK 0x8ff0 /* core code */ -+#define SBIDH_CC_SHIFT 4 -+#define SBIDH_VC_MASK 0xffff0000 /* vendor code */ -+#define SBIDH_VC_SHIFT 16 -+ -+#define SB_COMMIT 0xfd8 /* update buffered registers value */ -+ -+/* vendor codes */ -+#define SB_VEND_BCM 0x4243 /* Broadcom's SB vendor code */ -+ -+#endif /* _SBCONFIG_H */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/sbhndarm.h b/drivers/net/ethernet/broadcom/gmac/src/include/sbhndarm.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/sbhndarm.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/sbhndarm.h 2017-11-09 17:53:44.005307000 +0800 -@@ -0,0 +1,293 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom SiliconBackplane ARM definitions -+ * -+ * $Id: sbhndarm.h 325951 2012-04-05 06:03:27Z $ -+ */ -+ -+#ifndef _sbhndarm_h_ -+#define _sbhndarm_h_ -+ -+#include -+#include -+ -+/* register offsets */ -+#define ARM7_CORECTL 0 -+ -+/* bits in corecontrol */ -+#define ACC_FORCED_RST 0x1 -+#define ACC_SERRINT 0x2 -+#define ACC_NOTSLEEPINGCLKREQ_SHIFT 24 -+ -+/* arm resetlog */ -+#define SBRESETLOG 0x1 -+#define SERRORLOG 0x2 -+ -+/* arm core-specific control flags */ -+#define SICF_REMAP_MSK 0x001c -+#define SICF_REMAP_NONE 0 -+#define SICF_REMAP_ROM 0x0004 -+#define SIFC_REMAP_FLASH 0x0008 -+ -+/* misc core-specific defines */ -+#if defined(__ARM_ARCH_4T__) -+/* arm7tdmi-s */ -+/* backplane related stuff */ -+#define ARM_CORE_ID ARM7S_CORE_ID /* arm coreid */ -+#define SI_ARM_ROM SI_ARM7S_ROM /* ROM backplane/system address */ -+#define SI_ARM_SRAM2 SI_ARM7S_SRAM2 /* RAM backplane address when remap is 1 or 2 */ -+#elif defined(__ARM_ARCH_7M__) -+/* cortex-m3 */ -+/* backplane related stuff */ -+#define ARM_CORE_ID ARMCM3_CORE_ID /* arm coreid */ -+#define SI_ARM_ROM SI_ARMCM3_ROM /* ROM backplane/system address */ -+#define SI_ARM_SRAM2 SI_ARMCM3_SRAM2 /* RAM backplane address when remap is 1 or 2 */ -+/* core registers offsets */ -+#define ARMCM3_CYCLECNT 0x90 /* Cortex-M3 core registers offsets */ -+#define ARMCM3_INTTIMER 0x94 -+#define ARMCM3_INTMASK 0x98 -+#define ARMCM3_INTSTATUS 0x9c -+/* interrupt/exception */ -+#define ARMCM3_NUMINTS 16 /* # of external interrupts */ -+#define ARMCM3_INTALL ((1 << ARMCM3_NUMINTS) - 1) /* Interrupt mask */ -+#define ARMCM3_FAULTMASK 0x40000000 /* Master fault enable/disable */ -+#define ARMCM3_PRIMASK 0x80000000 /* Master interrupt enable/disable */ -+#define ARMCM3_SHARED_INT 0 /* Interrupt shared by multiple cores */ -+#define ARMCM3_INT(i) (1 << (i)) /* Individual interrupt enable/disable */ -+/* compatible with arm7tdmi-s */ -+#define PS_I ARMCM3_PRIMASK -+#define PS_F ARMCM3_FAULTMASK -+/* intmask/intstatus bits */ -+#define ARMCM3_INTMASK_TIMER 0x1 -+#define ARMCM3_INTMASK_SYSRESET 0x4 -+#define ARMCM3_INTMASK_LOCKUP 0x8 -+ -+/* -+ * Overlay Support in Rev 5 -+ */ -+#define ARMCM3_OVL_VALID_SHIFT 0 -+#define ARMCM3_OVL_VALID 1 -+#define ARMCM3_OVL_SZ_SHIFT 1 -+#define ARMCM3_OVL_SZ_MASK 0x0000000e -+#define ARMCM3_OVL_SZ_512B 0 /* 512B */ -+#define ARMCM3_OVL_SZ_1KB 1 /* 1KB */ -+#define ARMCM3_OVL_SZ_2KB 2 /* 2KB */ -+#define ARMCM3_OVL_SZ_4KB 3 /* 4KB */ -+#define ARMCM3_OVL_SZ_8KB 4 /* 8KB */ -+#define ARMCM3_OVL_SZ_16KB 5 /* 16KB */ -+#define ARMCM3_OVL_SZ_32KB 6 /* 32KB */ -+#define ARMCM3_OVL_SZ_64KB 7 /* 64KB */ -+#define ARMCM3_OVL_ADDR_SHIFT 9 -+#define ARMCM3_OVL_ADDR_MASK 0x003FFE00 -+#define ARMCM3_OVL_MAX 16 -+ -+#elif defined(__ARM_ARCH_7R__) -+/* cortex-r4 */ -+/* backplane related stuff */ -+#define ARM_CORE_ID ARMCR4_CORE_ID /* arm coreid */ -+#define SI_ARM_ROM SI_ARMCR4_ROM /* ROM backplane/system address */ -+#define SI_ARM_SRAM2 0x0 /* In the cr4 the RAM is just not available -+ * when remap is 1 -+ */ -+ -+/* core registers offsets */ -+#define ARMCR4_CORECTL 0 -+#define ARMCR4_CORECAP 4 -+#define ARMCR4_COREST 8 -+ -+#define ARMCR4_FIQRSTATUS 0x10 -+#define ARMCR4_FIQMASK 0x14 -+#define ARMCR4_IRQMASK 0x18 -+ -+#define ARMCR4_INTSTATUS 0x20 -+#define ARMCR4_INTMASK 0x24 -+#define ARMCR4_CYCLECNT 0x28 -+#define ARMCR4_INTTIMER 0x2c -+ -+#define ARMCR4_GPIOSEL 0x30 -+#define ARMCR4_GPIOEN 0x34 -+ -+#define ARMCR4_BANKIDX 0x40 -+#define ARMCR4_BANKINFO 0x44 -+#define ARMCR4_BANKSTBY 0x48 -+#define ARMCR4_BANKPDA 0x4c -+ -+#define ARMCR4_TCAMPATCHCTRL 0x68 -+#define ARMCR4_TCAMPATCHTBLBASEADDR 0x6C -+#define ARMCR4_TCAMCMDREG 0x70 -+#define ARMCR4_TCAMDATAREG 0x74 -+#define ARMCR4_TCAMBANKXMASKREG 0x78 -+ -+#define ARMCR4_ROMNB_MASK 0xf00 -+#define ARMCR4_ROMNB_SHIFT 8 -+#define ARMCR4_TCBBNB_MASK 0xf0 -+#define ARMCR4_TCBBNB_SHIFT 4 -+#define ARMCR4_TCBANB_MASK 0xf -+#define ARMCR4_TCBANB_SHIFT 0 -+ -+#define ARMCR4_MT_MASK 0x300 -+#define ARMCR4_MT_SHIFT 8 -+#define ARMCR4_MT_ROM 0x100 -+#define ARMCR4_MT_RAM 0 -+ -+#define ARMCR4_BSZ_MASK 0x3f -+#define ARMCR4_BSZ_MULT 8192 -+ -+#define ARMCR4_TCAM_ENABLE (1 << 31) -+#define ARMCR4_TCAM_CLKENAB (1 << 30) -+#define ARMCR4_TCAM_PATCHCNT_MASK 0xf -+ -+#define ARMCR4_TCAM_CMD_DONE (1 << 31) -+#define ARMCR4_TCAM_MATCH (1 << 24) -+#define ARMCR4_TCAM_OPCODE_MASK (3 << 16) -+#define ARMCR4_TCAM_OPCODE_SHIFT 16 -+#define ARMCR4_TCAM_ADDR_MASK 0xffff -+#define ARMCR4_TCAM_NONE (0 << ARMCR4_TCAM_OPCODE_SHIFT) -+#define ARMCR4_TCAM_READ (1 << ARMCR4_TCAM_OPCODE_SHIFT) -+#define ARMCR4_TCAM_WRITE (2 << ARMCR4_TCAM_OPCODE_SHIFT) -+#define ARMCR4_TCAM_COMPARE (3 << ARMCR4_TCAM_OPCODE_SHIFT) -+#define ARMCR4_TCAM_CMD_DONE_DLY 1000 -+ -+#define ARMCR4_DATA_MASK (~0x7) -+#define ARMCR4_DATA_VALID (1 << 0) -+ -+ -+/* arm core-specific conrol flags */ -+#define SICF_CPUHALT 0x0020 -+#define SICF_UPDATEFW 0x0040 -+ -+/* arm core-specific status flags */ -+#define SISF_SDRENABLE 0x0001 -+#define SISF_TCMPROT 0x0002 -+ -+#define CHIP_SDRENABLE(sih) (sih->boardflags2 & BFL2_SDR_EN) -+#define CHIP_TCMPROTENAB(sih) (si_arm_sflags(sih) & SISF_TCMPROT) -+ -+#elif defined(__ARM_ARCH_7A__) -+/* backplane related stuff */ -+#define ARM_CORE_ID ARMCA9_CORE_ID /* arm coreid */ -+ -+#else /* !__ARM_ARCH_4T__ && !__ARM_ARCH_7M__ && !__ARM_ARCH_7R__ */ -+#error Unrecognized ARM Architecture -+#endif /* !__ARM_ARCH_4T__ && !__ARM_ARCH_7M__ && !__ARM_ARCH_7R__ */ -+ -+#ifndef _LANGUAGE_ASSEMBLY -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif /* PAD */ -+ -+#if defined(__ARM_ARCH_4T__) -+/* arm7tdmi-s */ -+typedef volatile struct { -+ uint32 corecontrol; /* 0 */ -+ uint32 sleepcontrol; /* 4 */ -+ uint32 PAD; -+ uint32 biststatus; /* 0xc */ -+ uint32 firqstatus; /* 0x10 */ -+ uint32 fiqmask; /* 0x14 */ -+ uint32 irqmask; /* 0x18 */ -+ uint32 PAD; -+ uint32 resetlog; /* 0x20 */ -+ uint32 gpioselect; /* 0x24 */ -+ uint32 gpioenable; /* 0x28 */ -+ uint32 PAD; -+ uint32 bpaddrlo; /* 0x30 */ -+ uint32 bpaddrhi; /* 0x34 */ -+ uint32 bpdata; /* 0x38 */ -+ uint32 bpindaccess; /* 0x3c */ -+ uint32 PAD[104]; -+ uint32 clk_ctl_st; /* 0x1e0 */ -+ uint32 hw_war; /* 0x1e4 */ -+} armregs_t; -+#define ARMREG(regs, reg) (&((armregs_t *)regs)->reg) -+#endif /* __ARM_ARCH_4T__ */ -+ -+#if defined(__ARM_ARCH_7M__) -+/* cortex-m3 */ -+typedef volatile struct { -+ uint32 corecontrol; /* 0x0 */ -+ uint32 corestatus; /* 0x4 */ -+ uint32 PAD[1]; -+ uint32 biststatus; /* 0xc */ -+ uint32 nmiisrst; /* 0x10 */ -+ uint32 nmimask; /* 0x14 */ -+ uint32 isrmask; /* 0x18 */ -+ uint32 PAD[1]; -+ uint32 resetlog; /* 0x20 */ -+ uint32 gpioselect; /* 0x24 */ -+ uint32 gpioenable; /* 0x28 */ -+ uint32 PAD[1]; -+ uint32 bpaddrlo; /* 0x30 */ -+ uint32 bpaddrhi; /* 0x34 */ -+ uint32 bpdata; /* 0x38 */ -+ uint32 bpindaccess; /* 0x3c */ -+ uint32 ovlidx; /* 0x40 */ -+ uint32 ovlmatch; /* 0x44 */ -+ uint32 ovladdr; /* 0x48 */ -+ uint32 PAD[13]; -+ uint32 bwalloc; /* 0x80 */ -+ uint32 PAD[3]; -+ uint32 cyclecnt; /* 0x90 */ -+ uint32 inttimer; /* 0x94 */ -+ uint32 intmask; /* 0x98 */ -+ uint32 intstatus; /* 0x9c */ -+ uint32 PAD[80]; -+ uint32 clk_ctl_st; /* 0x1e0 */ -+} cm3regs_t; -+#define ARMREG(regs, reg) (&((cm3regs_t *)regs)->reg) -+#endif /* __ARM_ARCH_7M__ */ -+ -+#if defined(__ARM_ARCH_7R__) -+/* cortex-R4 */ -+typedef volatile struct { -+ uint32 corecontrol; /* 0x0 */ -+ uint32 corecapabilities; /* 0x4 */ -+ uint32 corestatus; /* 0x8 */ -+ uint32 biststatus; /* 0xc */ -+ uint32 nmiisrst; /* 0x10 */ -+ uint32 nmimask; /* 0x14 */ -+ uint32 isrmask; /* 0x18 */ -+ uint32 PAD[1]; -+ uint32 intstatus; /* 0x20 */ -+ uint32 intmask; /* 0x24 */ -+ uint32 cyclecnt; /* 0x28 */ -+ uint32 inttimer; /* 0x2c */ -+ uint32 gpioselect; /* 0x30 */ -+ uint32 gpioenable; /* 0x34 */ -+ uint32 PAD[2]; -+ uint32 bankidx; /* 0x40 */ -+ uint32 bankinfo; /* 0x44 */ -+ uint32 bankstbyctl; /* 0x48 */ -+ uint32 bankpda; /* 0x4c */ -+ uint32 PAD[6]; -+ uint32 tcampatchctrl; /* 0x68 */ -+ uint32 tcampatchtblbaseaddr; /* 0x6c */ -+ uint32 tcamcmdreg; /* 0x70 */ -+ uint32 tcamdatareg; /* 0x74 */ -+ uint32 tcambankxmaskreg; /* 0x78 */ -+ uint32 PAD[89]; -+ uint32 clk_ctl_st; /* 0x1e0 */ -+} cr4regs_t; -+#define ARMREG(regs, reg) (&((cr4regs_t *)regs)->reg) -+#endif /* __ARM_ARCH_7R__ */ -+ -+#endif /* _LANGUAGE_ASSEMBLY */ -+ -+#endif /* _sbhndarm_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/sbhnddma.h b/drivers/net/ethernet/broadcom/gmac/src/include/sbhnddma.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/sbhnddma.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/sbhnddma.h 2017-11-09 17:53:44.006300000 +0800 -@@ -0,0 +1,403 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface -+ * This supports the following chips: BCM42xx, 44xx, 47xx . -+ * -+ * $Id: sbhnddma.h 321146 2012-03-14 08:27:23Z $ -+ */ -+ -+#ifndef _sbhnddma_h_ -+#define _sbhnddma_h_ -+ -+/* DMA structure: -+ * support two DMA engines: 32 bits address or 64 bit addressing -+ * basic DMA register set is per channel(transmit or receive) -+ * a pair of channels is defined for convenience -+ */ -+ -+ -+/* 32 bits addressing */ -+ -+/* dma registers per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint32 control; /* enable, et al */ -+ uint32 addr; /* descriptor ring base address (4K aligned) */ -+ uint32 ptr; /* last descriptor posted to chip */ -+ uint32 status; /* current active descriptor, et al */ -+} dma32regs_t; -+ -+typedef volatile struct { -+ dma32regs_t xmt; /* dma tx channel */ -+ dma32regs_t rcv; /* dma rx channel */ -+} dma32regp_t; -+ -+typedef volatile struct { /* diag access */ -+ uint32 fifoaddr; /* diag address */ -+ uint32 fifodatalow; /* low 32bits of data */ -+ uint32 fifodatahigh; /* high 32bits of data */ -+ uint32 pad; /* reserved */ -+} dma32diag_t; -+ -+/* -+ * DMA Descriptor -+ * Descriptors are only read by the hardware, never written back. -+ */ -+typedef volatile struct { -+ uint32 ctrl; /* misc control bits & bufcount */ -+ uint32 addr; /* data buffer address */ -+} dma32dd_t; -+ -+/* -+ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page. -+ */ -+#define D32RINGALIGN_BITS 12 -+#define D32MAXRINGSZ (1 << D32RINGALIGN_BITS) -+#define D32RINGALIGN (1 << D32RINGALIGN_BITS) -+ -+#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) -+ -+/* transmit channel control */ -+#define XC_XE ((uint32)1 << 0) /* transmit enable */ -+#define XC_SE ((uint32)1 << 1) /* transmit suspend request */ -+#define XC_LE ((uint32)1 << 2) /* loopback enable */ -+#define XC_FL ((uint32)1 << 4) /* flush request */ -+#define XC_MR_MASK 0x000000C0 /* Multiple outstanding reads */ -+#define XC_MR_SHIFT 6 -+#define XC_PD ((uint32)1 << 11) /* parity check disable */ -+#define XC_AE ((uint32)3 << 16) /* address extension bits */ -+#define XC_AE_SHIFT 16 -+#define XC_BL_MASK 0x001C0000 /* BurstLen bits */ -+#define XC_BL_SHIFT 18 -+#define XC_PC_MASK 0x00E00000 /* Prefetch control */ -+#define XC_PC_SHIFT 21 -+#define XC_PT_MASK 0x03000000 /* Prefetch threshold */ -+#define XC_PT_SHIFT 24 -+ -+/* Multiple outstanding reads */ -+#define DMA_MR_1 0 -+#define DMA_MR_2 1 -+/* 2, 3: reserved */ -+ -+/* DMA Burst Length in bytes */ -+#define DMA_BL_16 0 -+#define DMA_BL_32 1 -+#define DMA_BL_64 2 -+#define DMA_BL_128 3 -+#define DMA_BL_256 4 -+#define DMA_BL_512 5 -+#define DMA_BL_1024 6 -+ -+/* Prefetch control */ -+#define DMA_PC_0 0 -+#define DMA_PC_4 1 -+#define DMA_PC_8 2 -+#define DMA_PC_16 3 -+/* others: reserved */ -+ -+/* Prefetch threshold */ -+#define DMA_PT_1 0 -+#define DMA_PT_2 1 -+#define DMA_PT_4 2 -+#define DMA_PT_8 3 -+ -+/* transmit descriptor table pointer */ -+#define XP_LD_MASK 0xfff /* last valid descriptor */ -+ -+/* transmit channel status */ -+#define XS_CD_MASK 0x0fff /* current descriptor pointer */ -+#define XS_XS_MASK 0xf000 /* transmit state */ -+#define XS_XS_SHIFT 12 -+#define XS_XS_DISABLED 0x0000 /* disabled */ -+#define XS_XS_ACTIVE 0x1000 /* active */ -+#define XS_XS_IDLE 0x2000 /* idle wait */ -+#define XS_XS_STOPPED 0x3000 /* stopped */ -+#define XS_XS_SUSP 0x4000 /* suspend pending */ -+#define XS_XE_MASK 0xf0000 /* transmit errors */ -+#define XS_XE_SHIFT 16 -+#define XS_XE_NOERR 0x00000 /* no error */ -+#define XS_XE_DPE 0x10000 /* descriptor protocol error */ -+#define XS_XE_DFU 0x20000 /* data fifo underrun */ -+#define XS_XE_BEBR 0x30000 /* bus error on buffer read */ -+#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */ -+#define XS_AD_MASK 0xfff00000 /* active descriptor */ -+#define XS_AD_SHIFT 20 -+ -+/* receive channel control */ -+#define RC_RE ((uint32)1 << 0) /* receive enable */ -+#define RC_RO_MASK 0xfe /* receive frame offset */ -+#define RC_RO_SHIFT 1 -+#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */ -+#define RC_SH ((uint32)1 << 9) /* separate rx header descriptor enable */ -+#define RC_OC ((uint32)1 << 10) /* overflow continue */ -+#define RC_PD ((uint32)1 << 11) /* parity check disable */ -+#define RC_AE ((uint32)3 << 16) /* address extension bits */ -+#define RC_AE_SHIFT 16 -+#define RC_BL_MASK 0x001C0000 /* BurstLen bits */ -+#define RC_BL_SHIFT 18 -+#define RC_PC_MASK 0x00E00000 /* Prefetch control */ -+#define RC_PC_SHIFT 21 -+#define RC_PT_MASK 0x03000000 /* Prefetch threshold */ -+#define RC_PT_SHIFT 24 -+ -+/* receive descriptor table pointer */ -+#define RP_LD_MASK 0xfff /* last valid descriptor */ -+ -+/* receive channel status */ -+#define RS_CD_MASK 0x0fff /* current descriptor pointer */ -+#define RS_RS_MASK 0xf000 /* receive state */ -+#define RS_RS_SHIFT 12 -+#define RS_RS_DISABLED 0x0000 /* disabled */ -+#define RS_RS_ACTIVE 0x1000 /* active */ -+#define RS_RS_IDLE 0x2000 /* idle wait */ -+#define RS_RS_STOPPED 0x3000 /* reserved */ -+#define RS_RE_MASK 0xf0000 /* receive errors */ -+#define RS_RE_SHIFT 16 -+#define RS_RE_NOERR 0x00000 /* no error */ -+#define RS_RE_DPE 0x10000 /* descriptor protocol error */ -+#define RS_RE_DFO 0x20000 /* data fifo overflow */ -+#define RS_RE_BEBW 0x30000 /* bus error on buffer write */ -+#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */ -+#define RS_AD_MASK 0xfff00000 /* active descriptor */ -+#define RS_AD_SHIFT 20 -+ -+/* fifoaddr */ -+#define FA_OFF_MASK 0xffff /* offset */ -+#define FA_SEL_MASK 0xf0000 /* select */ -+#define FA_SEL_SHIFT 16 -+#define FA_SEL_XDD 0x00000 /* transmit dma data */ -+#define FA_SEL_XDP 0x10000 /* transmit dma pointers */ -+#define FA_SEL_RDD 0x40000 /* receive dma data */ -+#define FA_SEL_RDP 0x50000 /* receive dma pointers */ -+#define FA_SEL_XFD 0x80000 /* transmit fifo data */ -+#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */ -+#define FA_SEL_RFD 0xc0000 /* receive fifo data */ -+#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */ -+#define FA_SEL_RSD 0xe0000 /* receive frame status data */ -+#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */ -+ -+/* descriptor control flags */ -+#define CTRL_BC_MASK 0x00001fff /* buffer byte count, real data len must <= 4KB */ -+#define CTRL_AE ((uint32)3 << 16) /* address extension bits */ -+#define CTRL_AE_SHIFT 16 -+#define CTRL_PARITY ((uint32)3 << 18) /* parity bit */ -+#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */ -+#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */ -+#define CTRL_EOF ((uint32)1 << 30) /* end of frame */ -+#define CTRL_SOF ((uint32)1 << 31) /* start of frame */ -+ -+/* control flags in the range [27:20] are core-specific and not defined here */ -+#define CTRL_CORE_MASK 0x0ff00000 -+ -+/* 64 bits addressing */ -+ -+/* dma registers per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint32 control; /* enable, et al */ -+ uint32 ptr; /* last descriptor posted to chip */ -+ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */ -+ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */ -+ uint32 status0; /* current descriptor, xmt state */ -+ uint32 status1; /* active descriptor, xmt error */ -+} dma64regs_t; -+ -+typedef volatile struct { -+ dma64regs_t tx; /* dma64 tx channel */ -+ dma64regs_t rx; /* dma64 rx channel */ -+} dma64regp_t; -+ -+typedef volatile struct { /* diag access */ -+ uint32 fifoaddr; /* diag address */ -+ uint32 fifodatalow; /* low 32bits of data */ -+ uint32 fifodatahigh; /* high 32bits of data */ -+ uint32 pad; /* reserved */ -+} dma64diag_t; -+ -+/* -+ * DMA Descriptor -+ * Descriptors are only read by the hardware, never written back. -+ */ -+typedef volatile struct { -+ uint32 ctrl1; /* misc control bits */ -+ uint32 ctrl2; /* buffer count and address extension */ -+ uint32 addrlow; /* memory address of the date buffer, bits 31:0 */ -+ uint32 addrhigh; /* memory address of the date buffer, bits 63:32 */ -+} dma64dd_t; -+ -+/* -+ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss. -+ */ -+#define D64RINGALIGN_BITS 13 -+#define D64MAXRINGSZ (1 << D64RINGALIGN_BITS) -+#define D64RINGBOUNDARY (1 << D64RINGALIGN_BITS) -+ -+#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) -+ -+/* for cores with large descriptor ring support, descriptor ring size can be up to 4096 */ -+#define D64MAXDD_LARGE ((1 << 16) / sizeof (dma64dd_t)) -+ -+/* for cores with large descriptor ring support (4k descriptors), descriptor ring cannot cross -+ * 64K boundary -+ */ -+#define D64RINGBOUNDARY_LARGE (1 << 16) -+ -+/* -+ * Default DMA Burstlen values for USBRev >= 12 and SDIORev >= 11. -+ * When this field contains the value N, the burst length is 2**(N + 4) bytes. -+ */ -+#define D64_DEF_USBBURSTLEN 2 -+#define D64_DEF_SDIOBURSTLEN 1 -+ -+ -+#ifndef D64_USBBURSTLEN -+#define D64_USBBURSTLEN DMA_BL_64 -+#endif -+#ifndef D64_SDIOBURSTLEN -+#define D64_SDIOBURSTLEN DMA_BL_32 -+#endif -+ -+/* transmit channel control */ -+#define D64_XC_XE 0x00000001 /* transmit enable */ -+#define D64_XC_SE 0x00000002 /* transmit suspend request */ -+#define D64_XC_LE 0x00000004 /* loopback enable */ -+#define D64_XC_FL 0x00000010 /* flush request */ -+#define D64_XC_MR_MASK 0x000000C0 /* Multiple outstanding reads */ -+#define D64_XC_MR_SHIFT 6 -+#define D64_XC_PD 0x00000800 /* parity check disable */ -+#define D64_XC_AE 0x00030000 /* address extension bits */ -+#define D64_XC_AE_SHIFT 16 -+#define D64_XC_BL_MASK 0x001C0000 /* BurstLen bits */ -+#define D64_XC_BL_SHIFT 18 -+#define D64_XC_PC_MASK 0x00E00000 /* Prefetch control */ -+#define D64_XC_PC_SHIFT 21 -+#define D64_XC_PT_MASK 0x03000000 /* Prefetch threshold */ -+#define D64_XC_PT_SHIFT 24 -+ -+/* transmit descriptor table pointer */ -+#define D64_XP_LD_MASK 0x00001fff /* last valid descriptor */ -+ -+/* transmit channel status */ -+#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ -+#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ -+#define D64_XS0_XS_SHIFT 28 -+#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ -+#define D64_XS0_XS_ACTIVE 0x10000000 /* active */ -+#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */ -+#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ -+#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ -+ -+#define D64_XS1_AD_MASK 0x00001fff /* active descriptor */ -+#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ -+#define D64_XS1_XE_SHIFT 28 -+#define D64_XS1_XE_NOERR 0x00000000 /* no error */ -+#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */ -+#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */ -+#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */ -+#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */ -+#define D64_XS1_XE_COREE 0x50000000 /* core error */ -+ -+/* receive channel control */ -+#define D64_RC_RE 0x00000001 /* receive enable */ -+#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ -+#define D64_RC_RO_SHIFT 1 -+#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ -+#define D64_RC_SH 0x00000200 /* separate rx header descriptor enable */ -+#define D64_RC_OC 0x00000400 /* overflow continue */ -+#define D64_RC_PD 0x00000800 /* parity check disable */ -+#define D64_RC_GE 0x00004000 /* Glom enable */ -+#define D64_RC_AE 0x00030000 /* address extension bits */ -+#define D64_RC_AE_SHIFT 16 -+#define D64_RC_BL_MASK 0x001C0000 /* BurstLen bits */ -+#define D64_RC_BL_SHIFT 18 -+#define D64_RC_PC_MASK 0x00E00000 /* Prefetch control */ -+#define D64_RC_PC_SHIFT 21 -+#define D64_RC_PT_MASK 0x03000000 /* Prefetch threshold */ -+#define D64_RC_PT_SHIFT 24 -+ -+/* flags for dma controller */ -+#define DMA_CTRL_PEN (1 << 0) /* partity enable */ -+#define DMA_CTRL_ROC (1 << 1) /* rx overflow continue */ -+#define DMA_CTRL_RXMULTI (1 << 2) /* allow rx scatter to multiple descriptors */ -+#define DMA_CTRL_UNFRAMED (1 << 3) /* Unframed Rx/Tx data */ -+#define DMA_CTRL_USB_BOUNDRY4KB_WAR (1 << 4) -+#define DMA_CTRL_DMA_AVOIDANCE_WAR (1 << 5) /* DMA avoidance WAR for 4331 */ -+#define DMA_CTRL_RXSINGLE (1 << 6) /* always single buffer */ -+ -+/* receive descriptor table pointer */ -+#define D64_RP_LD_MASK 0x00001fff /* last valid descriptor */ -+ -+/* receive channel status */ -+#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ -+#define D64_RS0_RS_MASK 0xf0000000 /* receive state */ -+#define D64_RS0_RS_SHIFT 28 -+#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ -+#define D64_RS0_RS_ACTIVE 0x10000000 /* active */ -+#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */ -+#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */ -+#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */ -+ -+#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */ -+#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */ -+#define D64_RS1_RE_SHIFT 28 -+#define D64_RS1_RE_NOERR 0x00000000 /* no error */ -+#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */ -+#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */ -+#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */ -+#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */ -+#define D64_RS1_RE_COREE 0x50000000 /* core error */ -+ -+/* fifoaddr */ -+#define D64_FA_OFF_MASK 0xffff /* offset */ -+#define D64_FA_SEL_MASK 0xf0000 /* select */ -+#define D64_FA_SEL_SHIFT 16 -+#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */ -+#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */ -+#define D64_FA_SEL_RDD 0x40000 /* receive dma data */ -+#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */ -+#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */ -+#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */ -+#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */ -+#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */ -+#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */ -+#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */ -+ -+/* descriptor control flags 1 */ -+#define D64_CTRL_COREFLAGS 0x0ff00000 /* core specific flags */ -+#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */ -+#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */ -+#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */ -+#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */ -+ -+/* descriptor control flags 2 */ -+#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count. real data len must <= 16KB */ -+#define D64_CTRL2_AE 0x00030000 /* address extension bits */ -+#define D64_CTRL2_AE_SHIFT 16 -+#define D64_CTRL2_PARITY 0x00040000 /* parity bit */ -+ -+/* control flags in the range [27:20] are core-specific and not defined here */ -+#define D64_CTRL_CORE_MASK 0x0ff00000 -+ -+#define D64_RX_FRM_STS_LEN 0x0000ffff /* frame length mask */ -+#define D64_RX_FRM_STS_OVFL 0x00800000 /* RxOverFlow */ -+#define D64_RX_FRM_STS_DSCRCNT 0x0f000000 /* no. of descriptors used - 1, d11corerev >= 22 */ -+#define D64_RX_FRM_STS_DATATYPE 0xf0000000 /* core-dependent data type */ -+ -+/* receive frame status */ -+typedef volatile struct { -+ uint16 len; -+ uint16 flags; -+} dma_rxh_t; -+ -+#endif /* _sbhnddma_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/sbsocram.h b/drivers/net/ethernet/broadcom/gmac/src/include/sbsocram.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/sbsocram.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/sbsocram.h 2017-11-09 17:53:44.007303000 +0800 -@@ -0,0 +1,193 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * BCM47XX Sonics SiliconBackplane embedded ram core -+ * -+ * $Id: sbsocram.h 271781 2011-07-13 20:00:06Z $ -+ */ -+ -+#ifndef _SBSOCRAM_H -+#define _SBSOCRAM_H -+ -+#ifndef _LANGUAGE_ASSEMBLY -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif /* PAD */ -+ -+/* Memcsocram core registers */ -+typedef volatile struct sbsocramregs { -+ uint32 coreinfo; -+ uint32 bwalloc; -+ uint32 extracoreinfo; -+ uint32 biststat; -+ uint32 bankidx; -+ uint32 standbyctrl; -+ -+ uint32 errlogstatus; /* rev 6 */ -+ uint32 errlogaddr; /* rev 6 */ -+ /* used for patching rev 3 & 5 */ -+ uint32 cambankidx; -+ uint32 cambankstandbyctrl; -+ uint32 cambankpatchctrl; -+ uint32 cambankpatchtblbaseaddr; -+ uint32 cambankcmdreg; -+ uint32 cambankdatareg; -+ uint32 cambankmaskreg; -+ uint32 PAD[1]; -+ uint32 bankinfo; /* corev 8 */ -+ uint32 PAD[15]; -+ uint32 extmemconfig; -+ uint32 extmemparitycsr; -+ uint32 extmemparityerrdata; -+ uint32 extmemparityerrcnt; -+ uint32 extmemwrctrlandsize; -+ uint32 PAD[84]; -+ uint32 workaround; -+ uint32 pwrctl; /* corerev >= 2 */ -+ uint32 PAD[133]; -+ uint32 sr_control; /* corerev >= 15 */ -+ uint32 sr_status; /* corerev >= 15 */ -+ uint32 sr_address; /* corerev >= 15 */ -+ uint32 sr_data; /* corerev >= 15 */ -+} sbsocramregs_t; -+ -+#endif /* _LANGUAGE_ASSEMBLY */ -+ -+/* Register offsets */ -+#define SR_COREINFO 0x00 -+#define SR_BWALLOC 0x04 -+#define SR_BISTSTAT 0x0c -+#define SR_BANKINDEX 0x10 -+#define SR_BANKSTBYCTL 0x14 -+#define SR_PWRCTL 0x1e8 -+ -+/* Coreinfo register */ -+#define SRCI_PT_MASK 0x00070000 /* corerev >= 6; port type[18:16] */ -+#define SRCI_PT_SHIFT 16 -+/* port types : SRCI_PT__ */ -+#define SRCI_PT_OCP_OCP 0 -+#define SRCI_PT_AXI_OCP 1 -+#define SRCI_PT_ARM7AHB_OCP 2 -+#define SRCI_PT_CM3AHB_OCP 3 -+#define SRCI_PT_AXI_AXI 4 -+#define SRCI_PT_AHB_AXI 5 -+/* corerev >= 3 */ -+#define SRCI_LSS_MASK 0x00f00000 -+#define SRCI_LSS_SHIFT 20 -+#define SRCI_LRS_MASK 0x0f000000 -+#define SRCI_LRS_SHIFT 24 -+ -+/* In corerev 0, the memory size is 2 to the power of the -+ * base plus 16 plus to the contents of the memsize field plus 1. -+ */ -+#define SRCI_MS0_MASK 0xf -+#define SR_MS0_BASE 16 -+ -+/* -+ * In corerev 1 the bank size is 2 ^ the bank size field plus 14, -+ * the memory size is number of banks times bank size. -+ * The same applies to rom size. -+ */ -+#define SRCI_ROMNB_MASK 0xf000 -+#define SRCI_ROMNB_SHIFT 12 -+#define SRCI_ROMBSZ_MASK 0xf00 -+#define SRCI_ROMBSZ_SHIFT 8 -+#define SRCI_SRNB_MASK 0xf0 -+#define SRCI_SRNB_SHIFT 4 -+#define SRCI_SRBSZ_MASK 0xf -+#define SRCI_SRBSZ_SHIFT 0 -+ -+#define SR_BSZ_BASE 14 -+ -+/* Standby control register */ -+#define SRSC_SBYOVR_MASK 0x80000000 -+#define SRSC_SBYOVR_SHIFT 31 -+#define SRSC_SBYOVRVAL_MASK 0x60000000 -+#define SRSC_SBYOVRVAL_SHIFT 29 -+#define SRSC_SBYEN_MASK 0x01000000 /* rev >= 3 */ -+#define SRSC_SBYEN_SHIFT 24 -+ -+/* Power control register */ -+#define SRPC_PMU_STBYDIS_MASK 0x00000010 /* rev >= 3 */ -+#define SRPC_PMU_STBYDIS_SHIFT 4 -+#define SRPC_STBYOVRVAL_MASK 0x00000008 -+#define SRPC_STBYOVRVAL_SHIFT 3 -+#define SRPC_STBYOVR_MASK 0x00000007 -+#define SRPC_STBYOVR_SHIFT 0 -+ -+/* Extra core capability register */ -+#define SRECC_NUM_BANKS_MASK 0x000000F0 -+#define SRECC_NUM_BANKS_SHIFT 4 -+#define SRECC_BANKSIZE_MASK 0x0000000F -+#define SRECC_BANKSIZE_SHIFT 0 -+ -+#define SRECC_BANKSIZE(value) (1 << (value)) -+ -+/* CAM bank patch control */ -+#define SRCBPC_PATCHENABLE 0x80000000 -+ -+#define SRP_ADDRESS 0x0001FFFC -+#define SRP_VALID 0x8000 -+ -+/* CAM bank command reg */ -+#define SRCMD_WRITE 0x00020000 -+#define SRCMD_READ 0x00010000 -+#define SRCMD_DONE 0x80000000 -+ -+#define SRCMD_DONE_DLY 1000 -+ -+/* bankidx and bankinfo reg defines corerev >= 8 */ -+#define SOCRAM_BANKINFO_SZMASK 0x7f -+#define SOCRAM_BANKIDX_ROM_MASK 0x100 -+ -+#define SOCRAM_BANKIDX_MEMTYPE_SHIFT 8 -+/* socram bankinfo memtype */ -+#define SOCRAM_MEMTYPE_RAM 0 -+#define SOCRAM_MEMTYPE_R0M 1 -+#define SOCRAM_MEMTYPE_DEVRAM 2 -+ -+#define SOCRAM_BANKINFO_REG 0x40 -+#define SOCRAM_BANKIDX_REG 0x10 -+#define SOCRAM_BANKINFO_STDBY_MASK 0x400 -+#define SOCRAM_BANKINFO_STDBY_TIMER 0x800 -+ -+/* bankinfo rev >= 10 */ -+#define SOCRAM_BANKINFO_DEVRAMSEL_SHIFT 13 -+#define SOCRAM_BANKINFO_DEVRAMSEL_MASK 0x2000 -+#define SOCRAM_BANKINFO_DEVRAMPRO_SHIFT 14 -+#define SOCRAM_BANKINFO_DEVRAMPRO_MASK 0x4000 -+#define SOCRAM_BANKINFO_SLPSUPP_SHIFT 15 -+#define SOCRAM_BANKINFO_SLPSUPP_MASK 0x8000 -+#define SOCRAM_BANKINFO_RETNTRAM_SHIFT 16 -+#define SOCRAM_BANKINFO_RETNTRAM_MASK 0x00010000 -+#define SOCRAM_BANKINFO_PDASZ_SHIFT 17 -+#define SOCRAM_BANKINFO_PDASZ_MASK 0x003E0000 -+#define SOCRAM_BANKINFO_DEVRAMREMAP_SHIFT 24 -+#define SOCRAM_BANKINFO_DEVRAMREMAP_MASK 0x01000000 -+ -+/* extracoreinfo register */ -+#define SOCRAM_DEVRAMBANK_MASK 0xF000 -+#define SOCRAM_DEVRAMBANK_SHIFT 12 -+ -+/* bank info to calculate bank size */ -+#define SOCRAM_BANKINFO_SZBASE 8192 -+#define SOCRAM_BANKSIZE_SHIFT 13 /* SOCRAM_BANKINFO_SZBASE */ -+ -+ -+#endif /* _SBSOCRAM_H */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/sgmiiplus2_serdes.h b/drivers/net/ethernet/broadcom/gmac/src/include/sgmiiplus2_serdes.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/sgmiiplus2_serdes.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/sgmiiplus2_serdes.h 2017-11-09 17:53:44.008297000 +0800 -@@ -0,0 +1,28 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * These routines provide access to the serdes -+ * -+ */ -+ -+#ifndef _SGMIIPLUS2_SERDES_H_ -+#define _SGMIIPLUS2_SERDES_H_ -+ -+#include -+ -+extern void sgmiiplus2_serdes_reset(uint eth_num, uint phyaddr); -+extern int sgmiiplus2_serdes_init(uint eth_num, uint phyaddr); -+ -+#endif /* _SGMIIPLUS2_SERDES_H_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/siutils.h b/drivers/net/ethernet/broadcom/gmac/src/include/siutils.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/siutils.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/siutils.h 2017-11-09 17:53:44.009295000 +0800 -@@ -0,0 +1,243 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Misc utility routines for accessing the SOC Interconnects -+ * of Broadcom HNBU chips. -+ * -+ * $Id: siutils.h 323456 2012-03-24 07:17:39Z $ -+ */ -+ -+#ifndef _siutils_h_ -+#define _siutils_h_ -+ -+#if defined(WLC_HIGH) && !defined(WLC_LOW) -+#include "bcm_rpc.h" -+#endif -+/* -+ * Data structure to export all chip specific common variables -+ * public (read-only) portion of siutils handle returned by si_attach() -+ */ -+struct si_pub { -+ uint socitype; /* SOCI_SB, SOCI_AI */ -+ -+ uint bustype; /* SI_BUS, PCI_BUS */ -+ uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */ -+ uint buscorerev; /* buscore rev */ -+ uint buscoreidx; /* buscore index */ -+ int ccrev; /* chip common core rev */ -+ uint32 cccaps; /* chip common capabilities */ -+ uint32 cccaps_ext; /* chip common capabilities extension */ -+ int pmurev; /* pmu core rev */ -+ uint32 pmucaps; /* pmu capabilities */ -+ uint boardtype; /* board type */ -+ uint boardrev; /* board rev */ -+ uint boardvendor; /* board vendor */ -+ uint boardflags; /* board flags */ -+ uint boardflags2; /* board flags2 */ -+ uint chip; /* chip number */ -+ uint chiprev; /* chip revision */ -+ uint chippkg; /* chip package option */ -+ uint32 chipst; /* chip status */ -+ bool issim; /* chip is in simulation or emulation */ -+ uint socirev; /* SOC interconnect rev */ -+ bool pci_pr32414; -+ spinlock_t sih_lock; -+ -+#if defined(WLC_HIGH) && !defined(WLC_LOW) -+ rpc_info_t *rpc; -+#endif -+}; -+ -+/* for HIGH_ONLY driver, the si_t must be writable to allow states sync from BMAC to HIGH driver -+ * for monolithic driver, it is readonly to prevent accident change -+ */ -+#if defined(WLC_HIGH) && !defined(WLC_LOW) -+typedef struct si_pub si_t; -+#else -+typedef const struct si_pub si_t; -+#endif -+ -+#ifdef ATE_BUILD -+typedef struct _ate_params { -+ void* wl; -+ uint8 gpio_input; -+ uint8 gpio_output; -+ bool cmd_proceed; -+ uint16 cmd_idx; -+ bool ate_cmd_done; -+} ate_params_t; -+#endif /* ATE_BUILD */ -+ -+/* -+ * Many of the routines below take an 'sih' handle as their first arg. -+ * Allocate this by calling si_attach(). Free it by calling si_detach(). -+ * At any one time, the sih is logically focused on one particular si core -+ * (the "current core"). -+ * Use si_setcore() or si_setcoreidx() to change the association to another core. -+ */ -+#define BADIDX (SI_MAXCORES + 1) -+ -+/* clkctl xtal what flags */ -+#define XTAL 0x1 /* primary crystal oscillator (2050) */ -+#define PLL 0x2 /* main chip pll */ -+ -+/* clkctl clk mode */ -+#define CLK_FAST 0 /* force fast (pll) clock */ -+#define CLK_DYNAMIC 2 /* enable dynamic clock control */ -+ -+/* GPIO usage priorities */ -+#define GPIO_DRV_PRIORITY 0 /* Driver */ -+#define GPIO_APP_PRIORITY 1 /* Application */ -+#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO reservation */ -+ -+/* GPIO pull up/down */ -+#define GPIO_PULLUP 0 -+#define GPIO_PULLDN 1 -+ -+/* GPIO event regtype */ -+#define GPIO_REGEVT 0 /* GPIO register event */ -+#define GPIO_REGEVT_INTMSK 1 /* GPIO register event int mask */ -+#define GPIO_REGEVT_INTPOL 2 /* GPIO register event int polarity */ -+ -+/* device path */ -+#define SI_DEVPATH_BUFSZ 16 /* min buffer size in bytes */ -+ -+/* SI routine enumeration: to be used by update function with multiple hooks */ -+#define SI_DOATTACH 1 -+#define SI_PCIDOWN 2 -+#define SI_PCIUP 3 -+ -+#if defined(BCMQT) -+#define ISSIM_ENAB(sih) ((sih)->issim) -+#else -+#define ISSIM_ENAB(sih) 0 -+#endif -+ -+/* PMU clock/power control */ -+#if defined(BCMPMUCTL) -+#define PMUCTL_ENAB(sih) (BCMPMUCTL) -+#else -+#define PMUCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PMU) -+#endif -+ -+/* chipcommon clock/power control (exclusive with PMU's) */ -+#if defined(BCMPMUCTL) && BCMPMUCTL -+#define CCCTL_ENAB(sih) (0) -+#define CCPLL_ENAB(sih) (0) -+#else -+#define CCCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PWR_CTL) -+#define CCPLL_ENAB(sih) ((sih)->cccaps & CC_CAP_PLL_MASK) -+#endif -+ -+typedef void (*gpio_handler_t)(uint32 stat, void *arg); -+/* External BT Coex enable mask */ -+#define CC_BTCOEX_EN_MASK 0x01 -+/* External PA enable mask */ -+#define GPIO_CTRL_EPA_EN_MASK 0x40 -+/* WL/BT control enable mask */ -+#define GPIO_CTRL_5_6_EN_MASK 0x60 -+#define GPIO_CTRL_7_6_EN_MASK 0xC0 -+#define GPIO_OUT_7_EN_MASK 0x80 -+ -+ -+/* === exported functions === */ -+extern si_t *si_attach(uint pcidev, osl_t *osh, void *regs, uint bustype, -+ void *sdh, char **vars, uint *varsz); -+extern void si_detach(si_t *sih); -+ -+extern uint si_corelist(si_t *sih, uint coreid[]); -+extern uint si_coreid(si_t *sih); -+extern uint si_flag(si_t *sih); -+extern uint si_intflag(si_t *sih); -+extern uint si_coreidx(si_t *sih); -+extern uint si_coreunit(si_t *sih); -+extern uint si_corevendor(si_t *sih); -+extern uint si_corerev(si_t *sih); -+extern void *si_osh(si_t *sih); -+extern void si_setosh(si_t *sih, osl_t *osh); -+extern uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); -+extern void *si_coreregs(si_t *sih); -+extern uint si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val); -+extern uint32 si_core_cflags(si_t *sih, uint32 mask, uint32 val); -+extern void si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); -+extern uint32 si_core_sflags(si_t *sih, uint32 mask, uint32 val); -+#ifdef WLC_HIGH_ONLY -+extern bool wlc_bmac_iscoreup(si_t *sih); -+#define si_iscoreup(sih) wlc_bmac_iscoreup(sih) -+#else -+extern bool si_iscoreup(si_t *sih); -+#endif /* __CONFIG_USBAP__ */ -+extern uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit); -+extern void *si_setcoreidx(si_t *sih, uint coreidx); -+extern void *si_setcore(si_t *sih, uint coreid, uint coreunit); -+extern void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val); -+extern void si_restore_core(si_t *sih, uint coreid, uint intr_val); -+extern int si_numaddrspaces(si_t *sih); -+extern uint32 si_addrspace(si_t *sih, uint asidx); -+extern uint32 si_addrspacesize(si_t *sih, uint asidx); -+extern void si_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size); -+extern int si_corebist(si_t *sih); -+extern void si_core_reset(si_t *sih, uint32 bits, uint32 resetbits); -+extern void si_core_disable(si_t *sih, uint32 bits); -+extern uint32 si_clock_rate(uint32 pll_type, uint32 n, uint32 m); -+extern uint32 si_clock(si_t *sih); -+extern void si_setint(si_t *sih, int siflag); -+extern bool si_backplane64(si_t *sih); -+extern void si_clkctl_init(si_t *sih); -+extern bool si_clkctl_cc(si_t *sih, uint mode); -+extern int si_clkctl_xtal(si_t *sih, uint what, bool on); -+ -+extern uint32 si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority); -+extern uint32 si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority); -+ -+/* Wake-on-wireless-LAN (WOWL) */ -+extern bool si_pci_pmecap(si_t *sih); -+struct osl_info; -+extern bool si_pci_fastpmecap(struct osl_info *osh); -+ -+/* Fab-id information */ -+#define DEFAULT_FAB 0x0 /* Original/first fab used for this chip */ -+#define CSM_FAB7 0x1 /* CSM Fab7 chip */ -+#define TSMC_FAB12 0x2 /* TSMC Fab12/Fab14 chip */ -+#define SMIC_FAB4 0x3 /* SMIC Fab4 chip */ -+ -+/* -+ * Build device path. Path size must be >= SI_DEVPATH_BUFSZ. -+ * The returned path is NULL terminated and has trailing '/'. -+ * Return 0 on success, nonzero otherwise. -+ */ -+extern int si_devpath(si_t *sih, char *path, int size); -+/* Read variable with prepending the devpath to the name */ -+extern int si_getdevpathintvar(si_t *sih, const char *name); -+extern char *si_coded_devpathvar(si_t *sih, char *varname, int var_len, const char *name); -+ -+ -+extern void si_war42780_clkreq(si_t *sih, bool clkreq); -+extern void si_pcie_extendL1timer(si_t *sih, bool extend); -+ -+/* === debug routines === */ -+ -+#ifdef BCMDBG -+extern void si_view(si_t *sih, bool verbose); -+extern void si_viewall(si_t *sih, bool verbose); -+#endif -+ -+#if defined(BCMDBG) -+struct bcmstrbuf; -+extern void si_dumpregs(si_t *sih, struct bcmstrbuf *b); -+#endif -+ -+ -+#endif /* _siutils_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/trxhdr.h b/drivers/net/ethernet/broadcom/gmac/src/include/trxhdr.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/trxhdr.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/trxhdr.h 2017-11-09 17:53:44.010293000 +0800 -@@ -0,0 +1,86 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * TRX image file header format. -+ * -+ * $Id: trxhdr.h 314841 2012-02-14 18:28:33Z $ -+ */ -+ -+#ifndef _TRX_HDR_H -+#define _TRX_HDR_H -+ -+#include -+ -+#define TRX_MAGIC 0x30524448 /* "HDR0" */ -+#define TRX_MAX_LEN 0x3B0000 /* Max length */ -+#define TRX_NO_HEADER 1 /* Do not write TRX header */ -+#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */ -+#define TRX_EMBED_UCODE 0x8 /* Trx contains embedded ucode image */ -+#define TRX_ROMSIM_IMAGE 0x10 /* Trx contains ROM simulation image */ -+#define TRX_UNCOMP_IMAGE 0x20 /* Trx contains uncompressed rtecdc.bin image */ -+#define TRX_BOOTLOADER 0x40 /* the image is a bootloader */ -+ -+#define TRX_V1 1 -+#define TRX_V1_MAX_OFFSETS 3 /* V1: Max number of individual files */ -+ -+#ifndef BCMTRXV2 -+#define TRX_VERSION TRX_V1 /* Version 1 */ -+#define TRX_MAX_OFFSET TRX_V1_MAX_OFFSETS -+#endif -+ -+/* BMAC Host driver/application like bcmdl need to support both Ver 1 as well as -+ * Ver 2 of trx header. To make it generic, trx_header is structure is modified -+ * as below where size of "offsets" field will vary as per the TRX version. -+ * Currently, BMAC host driver and bcmdl are modified to support TRXV2 as well. -+ * To make sure, other applications like "dhdl" which are yet to be enhanced to support -+ * TRXV2 are not broken, new macro and structure defintion take effect only when BCMTRXV2 -+ * is defined. -+ */ -+struct trx_header { -+ uint32 magic; /* "HDR0" */ -+ uint32 len; /* Length of file including header */ -+ uint32 crc32; /* 32-bit CRC from flag_version to end of file */ -+ uint32 flag_version; /* 0:15 flags, 16:31 version */ -+#ifndef BCMTRXV2 -+ uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ -+#else -+ uint32 offsets[1]; /* Offsets of partitions from start of header */ -+#endif -+}; -+ -+#ifdef BCMTRXV2 -+#define TRX_VERSION TRX_V2 /* Version 2 */ -+#define TRX_MAX_OFFSET TRX_V2_MAX_OFFSETS -+ -+#define TRX_V2 2 -+/* V2: Max number of individual files -+ * To support SDR signature + Config data region -+ */ -+#define TRX_V2_MAX_OFFSETS 5 -+#define SIZEOF_TRXHDR_V1 (sizeof(struct trx_header)+(TRX_V1_MAX_OFFSETS-1)*sizeof(uint32)) -+#define SIZEOF_TRXHDR_V2 (sizeof(struct trx_header)+(TRX_V2_MAX_OFFSETS-1)*sizeof(uint32)) -+#define TRX_VER(trx) (trx->flag_version>>16) -+#define ISTRX_V1(trx) (TRX_VER(trx) == TRX_V1) -+#define ISTRX_V2(trx) (TRX_VER(trx) == TRX_V2) -+/* For V2, return size of V2 size: others, return V1 size */ -+#define SIZEOF_TRX(trx) (ISTRX_V2(trx) ? SIZEOF_TRXHDR_V2: SIZEOF_TRXHDR_V1) -+#else -+#define SIZEOF_TRX(trx) (sizeof(struct trx_header)) -+#endif /* BCMTRXV2 */ -+ -+/* Compatibility */ -+typedef struct trx_header TRXHDR, *PTRXHDR; -+ -+#endif /* _TRX_HDR_H */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/typedefs.h b/drivers/net/ethernet/broadcom/gmac/src/include/typedefs.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/typedefs.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/typedefs.h 2017-11-09 17:53:44.011290000 +0800 -@@ -0,0 +1,447 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * $Id: typedefs.h 286783 2011-09-29 06:18:57Z $ -+ */ -+ -+#ifndef _TYPEDEFS_H_ -+#define _TYPEDEFS_H_ -+ -+#ifdef SITE_TYPEDEFS -+ -+/* -+ * Define SITE_TYPEDEFS in the compile to include a site-specific -+ * typedef file "site_typedefs.h". -+ * -+ * If SITE_TYPEDEFS is not defined, then the code section below makes -+ * inferences about the compile environment based on defined symbols and -+ * possibly compiler pragmas. -+ * -+ * Following these two sections is the Default Typedefs section. -+ * This section is only processed if USE_TYPEDEF_DEFAULTS is -+ * defined. This section has a default set of typedefs and a few -+ * preprocessor symbols (TRUE, FALSE, NULL, ...). -+ */ -+ -+#include "site_typedefs.h" -+ -+#else -+ -+/* -+ * Infer the compile environment based on preprocessor symbols and pragmas. -+ * Override type definitions as needed, and include configuration-dependent -+ * header files to define types. -+ */ -+ -+#ifdef __cplusplus -+ -+#define TYPEDEF_BOOL -+#ifndef FALSE -+#define FALSE false -+#endif -+#ifndef TRUE -+#define TRUE true -+#endif -+ -+#else /* ! __cplusplus */ -+ -+#if defined(_WIN32) -+ -+#define TYPEDEF_BOOL -+typedef unsigned char bool; /* consistent w/BOOL */ -+ -+#endif /* _WIN32 */ -+ -+#endif /* ! __cplusplus */ -+ -+#if defined(_WIN64) && !defined(EFI) -+/* use the Windows ULONG_PTR type when compiling for 64 bit */ -+#include -+#define TYPEDEF_UINTPTR -+typedef ULONG_PTR uintptr; -+#elif defined(__x86_64__) -+#define TYPEDEF_UINTPTR -+typedef unsigned long long int uintptr; -+#endif -+ -+ -+#if defined(_MINOSL_) -+#define _NEED_SIZE_T_ -+#endif -+ -+#if defined(EFI) && !defined(_WIN64) -+#define _NEED_SIZE_T_ -+#endif -+ -+#if defined(TARGETOS_nucleus) -+/* for 'size_t' type */ -+#include -+ -+/* float_t types conflict with the same typedefs from the standard ANSI-C -+** math.h header file. Don't re-typedef them here. -+*/ -+#define TYPEDEF_FLOAT_T -+#endif /* TARGETOS_nucleus */ -+ -+#if defined(_NEED_SIZE_T_) -+typedef long unsigned int size_t; -+#endif -+ -+#ifdef _MSC_VER /* Microsoft C */ -+#define TYPEDEF_INT64 -+#define TYPEDEF_UINT64 -+typedef signed __int64 int64; -+typedef unsigned __int64 uint64; -+#endif -+ -+#if defined(MACOSX) -+#define TYPEDEF_BOOL -+#endif -+ -+#if defined(__NetBSD__) -+#define TYPEDEF_BOOL -+#ifndef _KERNEL -+#include -+#endif -+#define TYPEDEF_UINT -+#define TYPEDEF_USHORT -+#define TYPEDEF_ULONG -+#endif /* defined(__NetBSD__) */ -+ -+#if defined(__sparc__) -+#define TYPEDEF_ULONG -+#endif -+ -+ -+#ifdef linux -+/* -+ * If this is either a Linux hybrid build or the per-port code of a hybrid build -+ * then use the Linux header files to get some of the typedefs. Otherwise, define -+ * them entirely in this file. We can't always define the types because we get -+ * a duplicate typedef error; there is no way to "undefine" a typedef. -+ * We know when it's per-port code because each file defines LINUX_PORT at the top. -+ */ -+#if !defined(LINUX_HYBRID) || defined(LINUX_PORT) -+#define TYPEDEF_UINT -+#ifndef TARGETENV_android -+#define TYPEDEF_USHORT -+#define TYPEDEF_ULONG -+#endif /* TARGETENV_android */ -+#ifdef __KERNEL__ -+#include -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)) -+#define TYPEDEF_BOOL -+#endif /* >= 2.6.19 */ -+/* special detection for 2.6.18-128.7.1.0.1.el5 */ -+#if (LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18)) -+#include -+#ifdef noinline_for_stack -+#define TYPEDEF_BOOL -+#endif -+#endif /* == 2.6.18 */ -+#endif /* __KERNEL__ */ -+#endif /* !defined(LINUX_HYBRID) || defined(LINUX_PORT) */ -+#endif /* linux */ -+ -+#if defined(__ECOS) -+#define TYPEDEF_UCHAR -+#define TYPEDEF_UINT -+#define TYPEDEF_USHORT -+#define TYPEDEF_ULONG -+#define TYPEDEF_BOOL -+#endif -+ -+#if !defined(linux) && !defined(_WIN32) && !defined(_CFE_) && !defined(_MINOSL_) && \ -+ !defined(__DJGPP__) && !defined(__ECOS) && !defined(__BOB__) && \ -+ !defined(TARGETOS_nucleus) && !defined(EFI) && !defined(__FreeBSD__) -+#define TYPEDEF_UINT -+#define TYPEDEF_USHORT -+#endif -+ -+ -+/* Do not support the (u)int64 types with strict ansi for GNU C */ -+#if defined(__GNUC__) && defined(__STRICT_ANSI__) -+#define TYPEDEF_INT64 -+#define TYPEDEF_UINT64 -+#endif -+ -+/* ICL accepts unsigned 64 bit type only, and complains in ANSI mode -+ * for signed or unsigned -+ */ -+#if defined(__ICL) -+ -+#define TYPEDEF_INT64 -+ -+#if defined(__STDC__) -+#define TYPEDEF_UINT64 -+#endif -+ -+#endif /* __ICL */ -+ -+#if !defined(_WIN32) && !defined(_CFE_) && !defined(_MINOSL_) && !defined(__DJGPP__) && \ -+ !defined(__BOB__) && !defined(TARGETOS_nucleus) && !defined(EFI) -+ -+/* pick up ushort & uint from standard types.h */ -+#if defined(linux) && defined(__KERNEL__) -+ -+/* See note above */ -+#if !defined(LINUX_HYBRID) || defined(LINUX_PORT) -+#ifdef USER_MODE -+#include -+#else -+#include /* sys/types.h and linux/types.h are oil and water */ -+#endif /* USER_MODE */ -+#endif /* !defined(LINUX_HYBRID) || defined(LINUX_PORT) */ -+ -+#else -+ -+#if defined(__ECOS) -+#include -+#include -+#include -+#endif -+ -+#include -+ -+#endif /* linux && __KERNEL__ */ -+ -+#endif -+ -+#ifdef CONFIG_CPU_BIG_ENDIAN -+#define IL_BIGENDIAN -+#else -+#ifdef IL_BIGENDIAN -+#error "IL_BIGENDIAN was defined for a little-endian compile" -+#endif -+#endif /* CONFIG_CPU_BIG_ENDIAN */ -+ -+#if defined(MACOSX) -+ -+#ifdef __BIG_ENDIAN__ -+#define IL_BIGENDIAN -+#else -+#ifdef IL_BIGENDIAN -+#error "IL_BIGENDIAN was defined for a little-endian compile" -+#endif -+#endif /* __BIG_ENDIAN__ */ -+ -+#if !defined(__cplusplus) -+ -+#if defined(__i386__) -+typedef unsigned char bool; -+#else -+typedef unsigned int bool; -+#endif -+#define TYPE_BOOL 1 -+enum { -+ false = 0, -+ true = 1 -+}; -+ -+#if defined(KERNEL) -+#include -+#endif /* KERNEL */ -+ -+#endif /* __cplusplus */ -+ -+#endif /* MACOSX */ -+ -+ -+/* use the default typedefs in the next section of this file */ -+#define USE_TYPEDEF_DEFAULTS -+ -+#endif /* SITE_TYPEDEFS */ -+ -+ -+/* -+ * Default Typedefs -+ */ -+ -+#ifdef USE_TYPEDEF_DEFAULTS -+#undef USE_TYPEDEF_DEFAULTS -+ -+#ifndef TYPEDEF_BOOL -+typedef /* @abstract@ */ unsigned char bool; -+#endif -+ -+/* define uchar, ushort, uint, ulong */ -+ -+#ifndef TYPEDEF_UCHAR -+typedef unsigned char uchar; -+#endif -+ -+#ifndef TYPEDEF_USHORT -+typedef unsigned short ushort; -+#endif -+ -+#ifndef TYPEDEF_UINT -+typedef unsigned int uint; -+#endif -+ -+#ifndef TYPEDEF_ULONG -+typedef unsigned long ulong; -+#endif -+ -+/* define [u]int8/16/32/64, uintptr */ -+ -+#ifndef TYPEDEF_UINT8 -+typedef unsigned char uint8; -+#endif -+ -+#ifndef TYPEDEF_UINT16 -+typedef unsigned short uint16; -+#endif -+ -+#ifndef TYPEDEF_UINT32 -+typedef unsigned int uint32; -+#endif -+ -+#ifndef TYPEDEF_UINT64 -+typedef unsigned long long uint64; -+#endif -+ -+#ifndef TYPEDEF_UINTPTR -+typedef unsigned int uintptr; -+#endif -+ -+#ifndef TYPEDEF_INT8 -+typedef signed char int8; -+#endif -+ -+#ifndef TYPEDEF_INT16 -+typedef signed short int16; -+#endif -+ -+#ifndef TYPEDEF_INT32 -+typedef signed int int32; -+#endif -+ -+#ifndef TYPEDEF_INT64 -+typedef signed long long int64; -+#endif -+ -+/* define float32/64, float_t */ -+ -+#ifndef TYPEDEF_FLOAT32 -+typedef float float32; -+#endif -+ -+#ifndef TYPEDEF_FLOAT64 -+typedef double float64; -+#endif -+ -+/* -+ * abstracted floating point type allows for compile time selection of -+ * single or double precision arithmetic. Compiling with -DFLOAT32 -+ * selects single precision; the default is double precision. -+ */ -+ -+#ifndef TYPEDEF_FLOAT_T -+ -+#if defined(FLOAT32) -+typedef float32 float_t; -+#else /* default to double precision floating point */ -+typedef float64 float_t; -+#endif -+ -+#endif /* TYPEDEF_FLOAT_T */ -+ -+/* define macro values */ -+ -+#ifndef FALSE -+#define FALSE 0 -+#endif -+ -+#ifndef TRUE -+#define TRUE 1 /* TRUE */ -+#endif -+ -+#ifndef NULL -+#define NULL 0 -+#endif -+ -+#ifndef OFF -+#define OFF 0 -+#endif -+ -+#ifndef ON -+#define ON 1 /* ON = 1 */ -+#endif -+ -+#define AUTO (-1) /* Auto = -1 */ -+ -+/* define PTRSZ, INLINE */ -+ -+#ifndef PTRSZ -+#define PTRSZ sizeof(char*) -+#endif -+ -+ -+/* Detect compiler type. */ -+#ifdef _MSC_VER -+ #define BWL_COMPILER_MICROSOFT -+#elif defined(__GNUC__) || defined(__lint) -+ #define BWL_COMPILER_GNU -+#elif defined(__CC_ARM) && __CC_ARM -+ #define BWL_COMPILER_ARMCC -+#else -+ #error "Unknown compiler!" -+#endif /* _MSC_VER */ -+ -+ -+#ifndef INLINE -+ #if defined(BWL_COMPILER_MICROSOFT) -+ #define INLINE __inline -+ #elif defined(BWL_COMPILER_GNU) -+ #define INLINE __inline__ -+ #elif defined(BWL_COMPILER_ARMCC) -+ #define INLINE __inline -+ #else -+ #define INLINE -+ #endif /* _MSC_VER */ -+#endif /* INLINE */ -+ -+#undef TYPEDEF_BOOL -+#undef TYPEDEF_UCHAR -+#undef TYPEDEF_USHORT -+#undef TYPEDEF_UINT -+#undef TYPEDEF_ULONG -+#undef TYPEDEF_UINT8 -+#undef TYPEDEF_UINT16 -+#undef TYPEDEF_UINT32 -+#undef TYPEDEF_UINT64 -+#undef TYPEDEF_UINTPTR -+#undef TYPEDEF_INT8 -+#undef TYPEDEF_INT16 -+#undef TYPEDEF_INT32 -+#undef TYPEDEF_INT64 -+#undef TYPEDEF_FLOAT32 -+#undef TYPEDEF_FLOAT64 -+#undef TYPEDEF_FLOAT_T -+ -+#endif /* USE_TYPEDEF_DEFAULTS */ -+ -+/* Suppress unused parameter warning */ -+#define UNUSED_PARAMETER(x) (void)(x) -+ -+/* Avoid warning for discarded const or volatile qualifier in special cases (-Wcast-qual) */ -+#define DISCARD_QUAL(ptr, type) ((type *)(uintptr)(ptr)) -+ -+/* -+ * Including the bcmdefs.h here, to make sure everyone including typedefs.h -+ * gets this automatically -+*/ -+#include -+#endif /* _TYPEDEFS_H_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/include/wlioctl.h b/drivers/net/ethernet/broadcom/gmac/src/include/wlioctl.h ---- a/drivers/net/ethernet/broadcom/gmac/src/include/wlioctl.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/include/wlioctl.h 2017-11-09 17:53:44.016288000 +0800 -@@ -0,0 +1,4877 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Custom OID/ioctl definitions for -+ * Broadcom 802.11abg Networking Device Driver -+ * -+ * Definitions subject to change without notice. -+ * -+ * $Id: wlioctl.h 324203 2012-03-28 09:55:17Z $ -+ */ -+ -+#ifndef _wlioctl_h_ -+#define _wlioctl_h_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#ifdef __NetBSD__ -+/* NetBSD 2.0 does not have SIOCDEVPRIVATE. */ -+#define SIOCDEVPRIVATE _IOWR('i', 139, struct ifreq) -+#endif -+ -+#ifndef INTF_NAME_SIZ -+#define INTF_NAME_SIZ 16 -+#endif -+ -+/* Used to send ioctls over the transport pipe */ -+typedef struct remote_ioctl { -+ cdc_ioctl_t msg; -+ uint data_len; -+#ifndef OLYMPIC_RWL -+ char intf_name[INTF_NAME_SIZ]; -+#endif -+} rem_ioctl_t; -+#define REMOTE_SIZE sizeof(rem_ioctl_t) -+#ifdef EFI -+#define BCMWL_IOCTL_GUID \ -+ {0xB4910A35, 0x88C5, 0x4328, { 0x90, 0x08, 0x9F, 0xB2, 0x00, 0x00, 0x0, 0x0 } } -+#endif /* EFI */ -+ -+#define ACTION_FRAME_SIZE 1800 -+ -+typedef struct wl_action_frame { -+ struct ether_addr da; -+ uint16 len; -+ uint32 packetId; -+ uint8 data[ACTION_FRAME_SIZE]; -+} wl_action_frame_t; -+ -+#define WL_WIFI_ACTION_FRAME_SIZE sizeof(struct wl_action_frame) -+ -+typedef struct ssid_info -+{ -+ uint8 ssid_len; /* the length of SSID */ -+ uint8 ssid[32]; /* SSID string */ -+} ssid_info_t; -+ -+typedef struct wl_af_params { -+ uint32 channel; -+ int32 dwell_time; -+ struct ether_addr BSSID; -+ wl_action_frame_t action_frame; -+} wl_af_params_t; -+ -+#define WL_WIFI_AF_PARAMS_SIZE sizeof(struct wl_af_params) -+ -+#define MFP_TEST_FLAG_NORMAL 0 -+#define MFP_TEST_FLAG_ANY_KEY 1 -+typedef struct wl_sa_query { -+ uint32 flag; -+ uint8 action; -+ uint16 id; -+ struct ether_addr da; -+} wl_sa_query_t; -+ -+ -+/* require default structure packing */ -+#define BWL_DEFAULT_PACKING -+#include -+ -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+/* Legacy structure to help keep backward compatible wl tool and tray app */ -+ -+#define LEGACY_WL_BSS_INFO_VERSION 107 /* older version of wl_bss_info struct */ -+ -+typedef struct wl_bss_info_107 { -+ uint32 version; /* version field */ -+ uint32 length; /* byte length of data in this record, -+ * starting at version and including IEs -+ */ -+ struct ether_addr BSSID; -+ uint16 beacon_period; /* units are Kusec */ -+ uint16 capability; /* Capability information */ -+ uint8 SSID_len; -+ uint8 SSID[32]; -+ struct { -+ uint count; /* # rates in this set */ -+ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ -+ } rateset; /* supported rates */ -+ uint8 channel; /* Channel no. */ -+ uint16 atim_window; /* units are Kusec */ -+ uint8 dtim_period; /* DTIM period */ -+ int16 RSSI; /* receive signal strength (in dBm) */ -+ int8 phy_noise; /* noise (in dBm) */ -+ uint32 ie_length; /* byte length of Information Elements */ -+ /* variable length Information Elements */ -+} wl_bss_info_107_t; -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+/* -+ * Per-BSS information structure. -+ */ -+ -+#define LEGACY2_WL_BSS_INFO_VERSION 108 /* old version of wl_bss_info struct */ -+ -+/* BSS info structure -+ * Applications MUST CHECK ie_offset field and length field to access IEs and -+ * next bss_info structure in a vector (in wl_scan_results_t) -+ */ -+typedef struct wl_bss_info_108 { -+ uint32 version; /* version field */ -+ uint32 length; /* byte length of data in this record, -+ * starting at version and including IEs -+ */ -+ struct ether_addr BSSID; -+ uint16 beacon_period; /* units are Kusec */ -+ uint16 capability; /* Capability information */ -+ uint8 SSID_len; -+ uint8 SSID[32]; -+ struct { -+ uint count; /* # rates in this set */ -+ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ -+ } rateset; /* supported rates */ -+ chanspec_t chanspec; /* chanspec for bss */ -+ uint16 atim_window; /* units are Kusec */ -+ uint8 dtim_period; /* DTIM period */ -+ int16 RSSI; /* receive signal strength (in dBm) */ -+ int8 phy_noise; /* noise (in dBm) */ -+ -+ uint8 n_cap; /* BSS is 802.11N Capable */ -+ uint32 nbss_cap; /* 802.11N BSS Capabilities (based on HT_CAP_*) */ -+ uint8 ctl_ch; /* 802.11N BSS control channel number */ -+ uint32 reserved32[1]; /* Reserved for expansion of BSS properties */ -+ uint8 flags; /* flags */ -+ uint8 reserved[3]; /* Reserved for expansion of BSS properties */ -+ uint8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ -+ -+ uint16 ie_offset; /* offset at which IEs start, from beginning */ -+ uint32 ie_length; /* byte length of Information Elements */ -+ /* Add new fields here */ -+ /* variable length Information Elements */ -+} wl_bss_info_108_t; -+ -+#define WL_BSS_INFO_VERSION 109 /* current version of wl_bss_info struct */ -+ -+/* BSS info structure -+ * Applications MUST CHECK ie_offset field and length field to access IEs and -+ * next bss_info structure in a vector (in wl_scan_results_t) -+ */ -+typedef struct wl_bss_info { -+ uint32 version; /* version field */ -+ uint32 length; /* byte length of data in this record, -+ * starting at version and including IEs -+ */ -+ struct ether_addr BSSID; -+ uint16 beacon_period; /* units are Kusec */ -+ uint16 capability; /* Capability information */ -+ uint8 SSID_len; -+ uint8 SSID[32]; -+ struct { -+ uint count; /* # rates in this set */ -+ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ -+ } rateset; /* supported rates */ -+ chanspec_t chanspec; /* chanspec for bss */ -+ uint16 atim_window; /* units are Kusec */ -+ uint8 dtim_period; /* DTIM period */ -+ int16 RSSI; /* receive signal strength (in dBm) */ -+ int8 phy_noise; /* noise (in dBm) */ -+ -+ uint8 n_cap; /* BSS is 802.11N Capable */ -+ uint32 nbss_cap; /* 802.11N BSS Capabilities (based on HT_CAP_*) */ -+ uint8 ctl_ch; /* 802.11N BSS control channel number */ -+ uint16 vht_rxmcsmap; /* VHT rx mcs map */ -+ uint16 vht_txmcsmap; /* VHT tx mcs map */ -+ uint8 flags; /* flags */ -+ uint8 vht_cap; /* BSS is vht capable */ -+ uint8 reserved[2]; /* Reserved for expansion of BSS properties */ -+ uint8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ -+ -+ uint16 ie_offset; /* offset at which IEs start, from beginning */ -+ uint32 ie_length; /* byte length of Information Elements */ -+ int16 SNR; /* average SNR of during frame reception */ -+ /* Add new fields here */ -+ /* variable length Information Elements */ -+} wl_bss_info_t; -+ -+typedef struct wl_bsscfg { -+ uint32 wsec; -+ uint32 WPA_auth; -+ uint32 wsec_index; -+ uint32 associated; -+ uint32 BSS; -+ uint32 phytest_on; -+ struct ether_addr prev_BSSID; -+ struct ether_addr BSSID; -+} wl_bsscfg_t; -+ -+typedef struct wl_bss_config { -+ uint32 atim_window; -+ uint32 beacon_period; -+ uint32 chanspec; -+} wl_bss_config_t; -+ -+#define DLOAD_HANDLER_VER 1 /* Downloader version */ -+#define DLOAD_FLAG_VER_MASK 0xf000 /* Downloader version mask */ -+#define DLOAD_FLAG_VER_SHIFT 12 /* Downloader version shift */ -+ -+#define DL_CRC_NOT_INUSE 0x0001 -+ -+/* generic download types & flags */ -+enum { -+ DL_TYPE_UCODE = 1, -+ DL_TYPE_CLM = 2 -+}; -+ -+/* ucode type values */ -+enum { -+ UCODE_FW, -+ INIT_VALS, -+ BS_INIT_VALS -+}; -+ -+struct wl_dload_data { -+ uint16 flag; -+ uint16 dload_type; -+ uint32 len; -+ uint32 crc; -+ uint8 data[1]; -+}; -+typedef struct wl_dload_data wl_dload_data_t; -+ -+struct wl_ucode_info { -+ uint32 ucode_type; -+ uint32 num_chunks; -+ uint32 chunk_len; -+ uint32 chunk_num; -+ uint8 data_chunk[1]; -+}; -+typedef struct wl_ucode_info wl_ucode_info_t; -+ -+struct wl_clm_dload_info { -+ uint32 ds_id; -+ uint32 clm_total_len; -+ uint32 num_chunks; -+ uint32 chunk_len; -+ uint32 chunk_offset; -+ uint8 data_chunk[1]; -+}; -+typedef struct wl_clm_dload_info wl_clm_dload_info_t; -+ -+typedef struct wlc_ssid { -+ uint32 SSID_len; -+ uchar SSID[32]; -+} wlc_ssid_t; -+ -+#define MAX_PREFERRED_AP_NUM 5 -+typedef struct wlc_fastssidinfo { -+ uint32 SSID_channel[MAX_PREFERRED_AP_NUM]; -+ wlc_ssid_t SSID_info[MAX_PREFERRED_AP_NUM]; -+} wlc_fastssidinfo_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct wnm_url { -+ uint8 len; -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT wnm_url_t; -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+typedef struct chan_scandata { -+ uint8 txpower; -+ uint8 pad; -+ chanspec_t channel; /* Channel num, bw, ctrl_sb and band */ -+ uint32 channel_mintime; -+ uint32 channel_maxtime; -+} chan_scandata_t; -+ -+typedef enum wl_scan_type { -+ EXTDSCAN_FOREGROUND_SCAN, -+ EXTDSCAN_BACKGROUND_SCAN, -+ EXTDSCAN_FORCEDBACKGROUND_SCAN -+} wl_scan_type_t; -+ -+#define WLC_EXTDSCAN_MAX_SSID 5 -+ -+#define WL_BSS_FLAGS_FROM_BEACON 0x01 /* bss_info derived from beacon */ -+#define WL_BSS_FLAGS_FROM_CACHE 0x02 /* bss_info collected from cache */ -+#define WL_BSS_FLAGS_RSSI_ONCHANNEL 0x04 /* rssi info was received on channel (vs offchannel) */ -+ -+typedef struct wl_extdscan_params { -+ int8 nprobes; /* 0, passive, otherwise active */ -+ int8 split_scan; /* split scan */ -+ int8 band; /* band */ -+ int8 pad; -+ wlc_ssid_t ssid[WLC_EXTDSCAN_MAX_SSID]; /* ssid list */ -+ uint32 tx_rate; /* in 500ksec units */ -+ wl_scan_type_t scan_type; /* enum */ -+ int32 channel_num; -+ chan_scandata_t channel_list[1]; /* list of chandata structs */ -+} wl_extdscan_params_t; -+ -+#define WL_EXTDSCAN_PARAMS_FIXED_SIZE (sizeof(wl_extdscan_params_t) - sizeof(chan_scandata_t)) -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+#define WL_BSSTYPE_INFRA 1 -+#define WL_BSSTYPE_INDEP 0 -+#define WL_BSSTYPE_ANY 2 -+ -+/* Bitmask for scan_type */ -+#define WL_SCANFLAGS_PASSIVE 0x01 /* force passive scan */ -+#define WL_SCANFLAGS_RESERVED 0x02 /* Reserved */ -+#define WL_SCANFLAGS_PROHIBITED 0x04 /* allow scanning prohibited channels */ -+ -+#define WL_SCAN_PARAMS_SSID_MAX 10 -+ -+typedef struct wl_scan_params { -+ wlc_ssid_t ssid; /* default: {0, ""} */ -+ struct ether_addr bssid; /* default: bcast */ -+ int8 bss_type; /* default: any, -+ * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT -+ */ -+ uint8 scan_type; /* flags, 0 use default */ -+ int32 nprobes; /* -1 use default, number of probes per channel */ -+ int32 active_time; /* -1 use default, dwell time per channel for -+ * active scanning -+ */ -+ int32 passive_time; /* -1 use default, dwell time per channel -+ * for passive scanning -+ */ -+ int32 home_time; /* -1 use default, dwell time for the home channel -+ * between channel scans -+ */ -+ int32 channel_num; /* count of channels and ssids that follow -+ * -+ * low half is count of channels in channel_list, 0 -+ * means default (use all available channels) -+ * -+ * high half is entries in wlc_ssid_t array that -+ * follows channel_list, aligned for int32 (4 bytes) -+ * meaning an odd channel count implies a 2-byte pad -+ * between end of channel_list and first ssid -+ * -+ * if ssid count is zero, single ssid in the fixed -+ * parameter portion is assumed, otherwise ssid in -+ * the fixed portion is ignored -+ */ -+ uint16 channel_list[1]; /* list of chanspecs */ -+} wl_scan_params_t; -+ -+/* size of wl_scan_params not including variable length array */ -+#define WL_SCAN_PARAMS_FIXED_SIZE 64 -+ -+/* masks for channel and ssid count */ -+#define WL_SCAN_PARAMS_COUNT_MASK 0x0000ffff -+#define WL_SCAN_PARAMS_NSSID_SHIFT 16 -+ -+#define WL_SCAN_ACTION_START 1 -+#define WL_SCAN_ACTION_CONTINUE 2 -+#define WL_SCAN_ACTION_ABORT 3 -+ -+#define ISCAN_REQ_VERSION 1 -+ -+/* incremental scan struct */ -+typedef struct wl_iscan_params { -+ uint32 version; -+ uint16 action; -+ uint16 scan_duration; -+ wl_scan_params_t params; -+} wl_iscan_params_t; -+ -+/* 3 fields + size of wl_scan_params, not including variable length array */ -+#define WL_ISCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_iscan_params_t, params) + sizeof(wlc_ssid_t)) -+ -+typedef struct wl_scan_results { -+ uint32 buflen; -+ uint32 version; -+ uint32 count; -+ wl_bss_info_t bss_info[1]; -+} wl_scan_results_t; -+ -+/* size of wl_scan_results not including variable length array */ -+#define WL_SCAN_RESULTS_FIXED_SIZE (sizeof(wl_scan_results_t) - sizeof(wl_bss_info_t)) -+ -+/* wl_iscan_results status values */ -+#define WL_SCAN_RESULTS_SUCCESS 0 -+#define WL_SCAN_RESULTS_PARTIAL 1 -+#define WL_SCAN_RESULTS_PENDING 2 -+#define WL_SCAN_RESULTS_ABORTED 3 -+#define WL_SCAN_RESULTS_NO_MEM 4 -+ -+/* Used in EXT_STA */ -+#define DNGL_RXCTXT_SIZE 45 -+ -+#if defined(SIMPLE_ISCAN) -+#define ISCAN_RETRY_CNT 5 -+#define ISCAN_STATE_IDLE 0 -+#define ISCAN_STATE_SCANING 1 -+#define ISCAN_STATE_PENDING 2 -+ -+/* the buf lengh can be WLC_IOCTL_MAXLEN (8K) to reduce iteration */ -+#define WLC_IW_ISCAN_MAXLEN 2048 -+typedef struct iscan_buf { -+ struct iscan_buf * next; -+ char iscan_buf[WLC_IW_ISCAN_MAXLEN]; -+} iscan_buf_t; -+#endif /* SIMPLE_ISCAN */ -+ -+#define ESCAN_REQ_VERSION 1 -+ -+typedef struct wl_escan_params { -+ uint32 version; -+ uint16 action; -+ uint16 sync_id; -+ wl_scan_params_t params; -+} wl_escan_params_t; -+ -+#define WL_ESCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_escan_params_t, params) + sizeof(wlc_ssid_t)) -+ -+typedef struct wl_escan_result { -+ uint32 buflen; -+ uint32 version; -+ uint16 sync_id; -+ uint16 bss_count; -+ wl_bss_info_t bss_info[1]; -+} wl_escan_result_t; -+ -+#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(wl_escan_result_t) - sizeof(wl_bss_info_t)) -+ -+/* incremental scan results struct */ -+typedef struct wl_iscan_results { -+ uint32 status; -+ wl_scan_results_t results; -+} wl_iscan_results_t; -+ -+/* size of wl_iscan_results not including variable length array */ -+#define WL_ISCAN_RESULTS_FIXED_SIZE \ -+ (WL_SCAN_RESULTS_FIXED_SIZE + OFFSETOF(wl_iscan_results_t, results)) -+ -+typedef struct wl_probe_params { -+ wlc_ssid_t ssid; -+ struct ether_addr bssid; -+ struct ether_addr mac; -+} wl_probe_params_t; -+ -+#define WL_MAXRATES_IN_SET 16 /* max # of rates in a rateset */ -+typedef struct wl_rateset { -+ uint32 count; /* # rates in this set */ -+ uint8 rates[WL_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */ -+} wl_rateset_t; -+ -+typedef struct wl_rateset_args { -+ uint32 count; /* # rates in this set */ -+ uint8 rates[WL_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */ -+ uint8 mcs[MCSSET_LEN]; /* supported mcs index bit map */ -+} wl_rateset_args_t; -+ -+/* uint32 list */ -+typedef struct wl_uint32_list { -+ /* in - # of elements, out - # of entries */ -+ uint32 count; -+ /* variable length uint32 list */ -+ uint32 element[1]; -+} wl_uint32_list_t; -+ -+/* used for association with a specific BSSID and chanspec list */ -+typedef struct wl_assoc_params { -+ struct ether_addr bssid; /* 00:00:00:00:00:00: broadcast scan */ -+ int32 chanspec_num; /* 0: all available channels, -+ * otherwise count of chanspecs in chanspec_list -+ */ -+ chanspec_t chanspec_list[1]; /* list of chanspecs */ -+} wl_assoc_params_t; -+#define WL_ASSOC_PARAMS_FIXED_SIZE OFFSETOF(wl_assoc_params_t, chanspec_list) -+ -+/* used for reassociation/roam to a specific BSSID and channel */ -+typedef wl_assoc_params_t wl_reassoc_params_t; -+#define WL_REASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE -+ -+/* used for association to a specific BSSID and channel */ -+typedef wl_assoc_params_t wl_join_assoc_params_t; -+#define WL_JOIN_ASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE -+ -+/* used for join with or without a specific bssid and channel list */ -+typedef struct wl_join_params { -+ wlc_ssid_t ssid; -+ wl_assoc_params_t params; /* optional field, but it must include the fixed portion -+ * of the wl_assoc_params_t struct when it does present. -+ */ -+} wl_join_params_t; -+#define WL_JOIN_PARAMS_FIXED_SIZE (OFFSETOF(wl_join_params_t, params) + \ -+ WL_ASSOC_PARAMS_FIXED_SIZE) -+/* scan params for extended join */ -+typedef struct wl_join_scan_params { -+ uint8 scan_type; /* 0 use default, active or passive scan */ -+ int32 nprobes; /* -1 use default, number of probes per channel */ -+ int32 active_time; /* -1 use default, dwell time per channel for -+ * active scanning -+ */ -+ int32 passive_time; /* -1 use default, dwell time per channel -+ * for passive scanning -+ */ -+ int32 home_time; /* -1 use default, dwell time for the home channel -+ * between channel scans -+ */ -+} wl_join_scan_params_t; -+ -+/* extended join params */ -+typedef struct wl_extjoin_params { -+ wlc_ssid_t ssid; /* {0, ""}: wildcard scan */ -+ wl_join_scan_params_t scan; -+ wl_join_assoc_params_t assoc; /* optional field, but it must include the fixed portion -+ * of the wl_join_assoc_params_t struct when it does -+ * present. -+ */ -+} wl_extjoin_params_t; -+#define WL_EXTJOIN_PARAMS_FIXED_SIZE (OFFSETOF(wl_extjoin_params_t, assoc) + \ -+ WL_JOIN_ASSOC_PARAMS_FIXED_SIZE) -+ -+/* All builds use the new 11ac ratespec/chanspec */ -+#undef D11AC_IOTYPES -+#define D11AC_IOTYPES -+ -+#ifndef D11AC_IOTYPES -+ -+/* defines used by the nrate iovar */ -+#define NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */ -+#define NRATE_RATE_MASK 0x0000007f /* rate/mcs value */ -+#define NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */ -+#define NRATE_STF_SHIFT 8 /* stf mode shift */ -+#define NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ -+#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */ -+#define NRATE_SGI_MASK 0x00800000 /* sgi mode */ -+#define NRATE_SGI_SHIFT 23 /* sgi mode */ -+#define NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */ -+#define NRATE_LDPC_SHIFT 22 /* ldpc shift */ -+ -+#define NRATE_STF_SISO 0 /* stf mode SISO */ -+#define NRATE_STF_CDD 1 /* stf mode CDD */ -+#define NRATE_STF_STBC 2 /* stf mode STBC */ -+#define NRATE_STF_SDM 3 /* stf mode SDM */ -+ -+#else /* D11AC_IOTYPES */ -+ -+/* WL_RSPEC defines for rate information */ -+#define WL_RSPEC_RATE_MASK 0x000000FF /* rate or HT MCS value */ -+#define WL_RSPEC_VHT_MCS_MASK 0x0000000F /* VHT MCS value */ -+#define WL_RSPEC_VHT_NSS_MASK 0x000000F0 /* VHT Nss value */ -+#define WL_RSPEC_VHT_NSS_SHIFT 4 /* VHT Nss value shift */ -+#define WL_RSPEC_TXEXP_MASK 0x00000300 -+#define WL_RSPEC_TXEXP_SHIFT 8 -+#define WL_RSPEC_BW_MASK 0x00070000 /* bandwidth mask */ -+#define WL_RSPEC_BW_SHIFT 16 /* bandwidth shift */ -+#define WL_RSPEC_STBC 0x00100000 /* STBC encoding, Nsts = 2 x Nss */ -+#define WL_RSPEC_LDPC 0x00400000 /* bit indicates adv coding in use */ -+#define WL_RSPEC_SGI 0x00800000 /* Short GI mode */ -+#define WL_RSPEC_ENCODING_MASK 0x03000000 /* Encoding of Rate/MCS field */ -+#define WL_RSPEC_OVERRIDE_RATE 0x40000000 /* bit indicate to override mcs only */ -+#define WL_RSPEC_OVERRIDE_MODE 0x80000000 /* bit indicates override both rate & mode */ -+ -+/* WL_RSPEC_ENCODING field defs */ -+#define WL_RSPEC_ENCODE_RATE 0x00000000 /* Legacy rate is stored in RSPEC_RATE_MASK */ -+#define WL_RSPEC_ENCODE_HT 0x01000000 /* HT MCS is stored in RSPEC_RATE_MASK */ -+#define WL_RSPEC_ENCODE_VHT 0x02000000 /* VHT MCS and Nss is stored in RSPEC_RATE_MASK */ -+ -+/* WL_RSPEC_BW field defs */ -+#define WL_RSPEC_BW_UNSPECIFIED 0 -+#define WL_RSPEC_BW_20MHZ 0x00010000 -+#define WL_RSPEC_BW_40MHZ 0x00020000 -+#define WL_RSPEC_BW_80MHZ 0x00030000 -+#define WL_RSPEC_BW_160MHZ 0x00040000 -+ -+/* Legacy defines for the nrate iovar */ -+#define OLD_NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */ -+#define OLD_NRATE_RATE_MASK 0x0000007f /* rate/mcs value */ -+#define OLD_NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */ -+#define OLD_NRATE_STF_SHIFT 8 /* stf mode shift */ -+#define OLD_NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ -+#define OLD_NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */ -+#define OLD_NRATE_SGI 0x00800000 /* sgi mode */ -+#define OLD_NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */ -+ -+#define OLD_NRATE_STF_SISO 0 /* stf mode SISO */ -+#define OLD_NRATE_STF_CDD 1 /* stf mode CDD */ -+#define OLD_NRATE_STF_STBC 2 /* stf mode STBC */ -+#define OLD_NRATE_STF_SDM 3 /* stf mode SDM */ -+ -+#endif /* D11AC_IOTYPES */ -+ -+#define ANTENNA_NUM_1 1 /* total number of antennas to be used */ -+#define ANTENNA_NUM_2 2 -+#define ANTENNA_NUM_3 3 -+#define ANTENNA_NUM_4 4 -+ -+#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */ -+#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */ -+#define ANT_SELCFG_MAX 4 /* max number of antenna configurations */ -+#define ANT_SELCFG_TX_UNICAST 0 /* unicast tx antenna configuration */ -+#define ANT_SELCFG_RX_UNICAST 1 /* unicast rx antenna configuration */ -+#define ANT_SELCFG_TX_DEF 2 /* default tx antenna configuration */ -+#define ANT_SELCFG_RX_DEF 3 /* default rx antenna configuration */ -+ -+#define MAX_STREAMS_SUPPORTED 4 /* max number of streams supported */ -+ -+typedef struct { -+ uint8 ant_config[ANT_SELCFG_MAX]; /* antenna configuration */ -+ uint8 num_antcfg; /* number of available antenna configurations */ -+} wlc_antselcfg_t; -+ -+#define HIGHEST_SINGLE_STREAM_MCS 7 /* MCS values greater than this enable multiple streams */ -+ -+#define MAX_CCA_CHANNELS 38 /* Max number of 20 Mhz wide channels */ -+#define MAX_CCA_SECS 60 /* CCA keeps this many seconds history */ -+ -+#define IBSS_MED 15 /* Mediom in-bss congestion percentage */ -+#define IBSS_HI 25 /* Hi in-bss congestion percentage */ -+#define OBSS_MED 12 -+#define OBSS_HI 25 -+#define INTERFER_MED 5 -+#define INTERFER_HI 10 -+ -+#define CCA_FLAG_2G_ONLY 0x01 /* Return a channel from 2.4 Ghz band */ -+#define CCA_FLAG_5G_ONLY 0x02 /* Return a channel from 2.4 Ghz band */ -+#define CCA_FLAG_IGNORE_DURATION 0x04 /* Ignore dwell time for each channel */ -+#define CCA_FLAGS_PREFER_1_6_11 0x10 -+#define CCA_FLAG_IGNORE_INTERFER 0x20 /* do not exlude channel based on interfer level */ -+ -+#define CCA_ERRNO_BAND 1 /* After filtering for band pref, no choices left */ -+#define CCA_ERRNO_DURATION 2 /* After filtering for duration, no choices left */ -+#define CCA_ERRNO_PREF_CHAN 3 /* After filtering for chan pref, no choices left */ -+#define CCA_ERRNO_INTERFER 4 /* After filtering for interference, no choices left */ -+#define CCA_ERRNO_TOO_FEW 5 /* Only 1 channel was input */ -+ -+typedef struct { -+ uint32 duration; /* millisecs spent sampling this channel */ -+ uint32 congest_ibss; /* millisecs in our bss (presumably this traffic will */ -+ /* move if cur bss moves channels) */ -+ uint32 congest_obss; /* traffic not in our bss */ -+ uint32 interference; /* millisecs detecting a non 802.11 interferer. */ -+ uint32 timestamp; /* second timestamp */ -+} cca_congest_t; -+ -+typedef struct { -+ chanspec_t chanspec; /* Which channel? */ -+ uint8 num_secs; /* How many secs worth of data */ -+ cca_congest_t secs[1]; /* Data */ -+} cca_congest_channel_req_t; -+ -+/* interference source detection and identification mode */ -+#define ITFR_MODE_DISABLE 0 /* disable feature */ -+#define ITFR_MODE_MANUAL_ENABLE 1 /* enable manual detection */ -+#define ITFR_MODE_AUTO_ENABLE 2 /* enable auto detection */ -+ -+/* interference sources */ -+enum interference_source { -+ ITFR_NONE = 0, /* interference */ -+ ITFR_PHONE, /* wireless phone */ -+ ITFR_VIDEO_CAMERA, /* wireless video camera */ -+ ITFR_MICROWAVE_OVEN, /* microwave oven */ -+ ITFR_BABY_MONITOR, /* wireless baby monitor */ -+ ITFR_BLUETOOTH, /* bluetooth */ -+ ITFR_VIDEO_CAMERA_OR_BABY_MONITOR, /* wireless camera or baby monitor */ -+ ITFR_BLUETOOTH_OR_BABY_MONITOR, /* bluetooth or baby monitor */ -+ ITFR_VIDEO_CAMERA_OR_PHONE, /* video camera or phone */ -+ ITFR_UNIDENTIFIED /* interference from unidentified source */ -+}; -+ -+/* structure for interference source report */ -+typedef struct { -+ uint32 flags; /* flags. bit definitions below */ -+ uint32 source; /* last detected interference source */ -+ uint32 timestamp; /* second timestamp on interferenced flag change */ -+} interference_source_rep_t; -+ -+/* bit definitions for flags in interference source report */ -+#define ITFR_INTERFERENCED 1 /* interference detected */ -+#define ITFR_HOME_CHANNEL 2 /* home channel has interference */ -+#define ITFR_NOISY_ENVIRONMENT 4 /* noisy environemnt so feature stopped */ -+ -+#define WLC_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NUL */ -+ -+typedef struct wl_country { -+ char country_abbrev[WLC_CNTRY_BUF_SZ]; /* nul-terminated country code used in -+ * the Country IE -+ */ -+ int32 rev; /* revision specifier for ccode -+ * on set, -1 indicates unspecified. -+ * on get, rev >= 0 -+ */ -+ char ccode[WLC_CNTRY_BUF_SZ]; /* nul-terminated built-in country code. -+ * variable length, but fixed size in -+ * struct allows simple allocation for -+ * expected country strings <= 3 chars. -+ */ -+} wl_country_t; -+ -+typedef struct wl_channels_in_country { -+ uint32 buflen; -+ uint32 band; -+ char country_abbrev[WLC_CNTRY_BUF_SZ]; -+ uint32 count; -+ uint32 channel[1]; -+} wl_channels_in_country_t; -+ -+typedef struct wl_country_list { -+ uint32 buflen; -+ uint32 band_set; -+ uint32 band; -+ uint32 count; -+ char country_abbrev[1]; -+} wl_country_list_t; -+ -+#define WL_NUM_RPI_BINS 8 -+#define WL_RM_TYPE_BASIC 1 -+#define WL_RM_TYPE_CCA 2 -+#define WL_RM_TYPE_RPI 3 -+ -+#define WL_RM_FLAG_PARALLEL (1<<0) -+ -+#define WL_RM_FLAG_LATE (1<<1) -+#define WL_RM_FLAG_INCAPABLE (1<<2) -+#define WL_RM_FLAG_REFUSED (1<<3) -+ -+typedef struct wl_rm_req_elt { -+ int8 type; -+ int8 flags; -+ chanspec_t chanspec; -+ uint32 token; /* token for this measurement */ -+ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ -+ uint32 tsf_l; /* TSF low 32-bits */ -+ uint32 dur; /* TUs */ -+} wl_rm_req_elt_t; -+ -+typedef struct wl_rm_req { -+ uint32 token; /* overall measurement set token */ -+ uint32 count; /* number of measurement requests */ -+ void *cb; /* completion callback function: may be NULL */ -+ void *cb_arg; /* arg to completion callback function */ -+ wl_rm_req_elt_t req[1]; /* variable length block of requests */ -+} wl_rm_req_t; -+#define WL_RM_REQ_FIXED_LEN OFFSETOF(wl_rm_req_t, req) -+ -+typedef struct wl_rm_rep_elt { -+ int8 type; -+ int8 flags; -+ chanspec_t chanspec; -+ uint32 token; /* token for this measurement */ -+ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ -+ uint32 tsf_l; /* TSF low 32-bits */ -+ uint32 dur; /* TUs */ -+ uint32 len; /* byte length of data block */ -+ uint8 data[1]; /* variable length data block */ -+} wl_rm_rep_elt_t; -+#define WL_RM_REP_ELT_FIXED_LEN 24 /* length excluding data block */ -+ -+#define WL_RPI_REP_BIN_NUM 8 -+typedef struct wl_rm_rpi_rep { -+ uint8 rpi[WL_RPI_REP_BIN_NUM]; -+ int8 rpi_max[WL_RPI_REP_BIN_NUM]; -+} wl_rm_rpi_rep_t; -+ -+typedef struct wl_rm_rep { -+ uint32 token; /* overall measurement set token */ -+ uint32 len; /* length of measurement report block */ -+ wl_rm_rep_elt_t rep[1]; /* variable length block of reports */ -+} wl_rm_rep_t; -+#define WL_RM_REP_FIXED_LEN 8 -+ -+ -+#if defined(BCMSUP_PSK) -+typedef enum sup_auth_status { -+ /* Basic supplicant authentication states */ -+ WLC_SUP_DISCONNECTED = 0, -+ WLC_SUP_CONNECTING, -+ WLC_SUP_IDREQUIRED, -+ WLC_SUP_AUTHENTICATING, -+ WLC_SUP_AUTHENTICATED, -+ WLC_SUP_KEYXCHANGE, -+ WLC_SUP_KEYED, -+ WLC_SUP_TIMEOUT, -+ WLC_SUP_LAST_BASIC_STATE, -+ -+ /* Extended supplicant authentication states */ -+ /* Waiting to receive handshake msg M1 */ -+ WLC_SUP_KEYXCHANGE_WAIT_M1 = WLC_SUP_AUTHENTICATED, -+ /* Preparing to send handshake msg M2 */ -+ WLC_SUP_KEYXCHANGE_PREP_M2 = WLC_SUP_KEYXCHANGE, -+ /* Waiting to receive handshake msg M3 */ -+ WLC_SUP_KEYXCHANGE_WAIT_M3 = WLC_SUP_LAST_BASIC_STATE, -+ WLC_SUP_KEYXCHANGE_PREP_M4, /* Preparing to send handshake msg M4 */ -+ WLC_SUP_KEYXCHANGE_WAIT_G1, /* Waiting to receive handshake msg G1 */ -+ WLC_SUP_KEYXCHANGE_PREP_G2 /* Preparing to send handshake msg G2 */ -+} sup_auth_status_t; -+#endif -+ -+/* Enumerate crypto algorithms */ -+#define CRYPTO_ALGO_OFF 0 -+#define CRYPTO_ALGO_WEP1 1 -+#define CRYPTO_ALGO_TKIP 2 -+#define CRYPTO_ALGO_WEP128 3 -+#define CRYPTO_ALGO_AES_CCM 4 -+#define CRYPTO_ALGO_AES_OCB_MSDU 5 -+#define CRYPTO_ALGO_AES_OCB_MPDU 6 -+#define CRYPTO_ALGO_NALG 7 -+#define CRYPTO_ALGO_PMK 12 /* for 802.1x supp to set PMK before 4-way */ -+ -+#define WSEC_GEN_MIC_ERROR 0x0001 -+#define WSEC_GEN_REPLAY 0x0002 -+#define WSEC_GEN_ICV_ERROR 0x0004 -+#define WSEC_GEN_MFP_ACT_ERROR 0x0008 -+#define WSEC_GEN_MFP_DISASSOC_ERROR 0x0010 -+#define WSEC_GEN_MFP_DEAUTH_ERROR 0x0020 -+ -+#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */ -+#define WL_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ -+#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */ -+#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */ -+#define WL_IBSS_PEER_GROUP_KEY (1 << 6) /* Indicates a group key for a IBSS PEER */ -+ -+typedef struct wl_wsec_key { -+ uint32 index; /* key index */ -+ uint32 len; /* key length */ -+ uint8 data[DOT11_MAX_KEY_SIZE]; /* key data */ -+ uint32 pad_1[18]; -+ uint32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ -+ uint32 flags; /* misc flags */ -+ uint32 pad_2[2]; -+ int pad_3; -+ int iv_initialized; /* has IV been initialized already? */ -+ int pad_4; -+ /* Rx IV */ -+ struct { -+ uint32 hi; /* upper 32 bits of IV */ -+ uint16 lo; /* lower 16 bits of IV */ -+ } rxiv; -+ uint32 pad_5[2]; -+ struct ether_addr ea; /* per station */ -+} wl_wsec_key_t; -+ -+#define WSEC_MIN_PSK_LEN 8 -+#define WSEC_MAX_PSK_LEN 64 -+ -+/* Flag for key material needing passhash'ing */ -+#define WSEC_PASSPHRASE (1<<0) -+ -+/* receptacle for WLC_SET_WSEC_PMK parameter */ -+typedef struct { -+ ushort key_len; /* octets in key material */ -+ ushort flags; /* key handling qualification */ -+ uint8 key[WSEC_MAX_PSK_LEN]; /* PMK material */ -+} wsec_pmk_t; -+ -+/* wireless security bitvec */ -+#define WEP_ENABLED 0x0001 -+#define TKIP_ENABLED 0x0002 -+#define AES_ENABLED 0x0004 -+#define WSEC_SWFLAG 0x0008 -+#define SES_OW_ENABLED 0x0040 /* to go into transition mode without setting wep */ -+ -+/* wsec macros for operating on the above definitions */ -+#define WSEC_WEP_ENABLED(wsec) ((wsec) & WEP_ENABLED) -+#define WSEC_TKIP_ENABLED(wsec) ((wsec) & TKIP_ENABLED) -+#define WSEC_AES_ENABLED(wsec) ((wsec) & AES_ENABLED) -+ -+#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) -+#define WSEC_SES_OW_ENABLED(wsec) ((wsec) & SES_OW_ENABLED) -+ -+#ifdef MFP -+#define MFP_CAPABLE 0x0200 -+#define MFP_REQUIRED 0x0400 -+#define MFP_SHA256 0x0800 /* a special configuration for STA for WIFI test tool */ -+#endif /* MFP */ -+ -+/* WPA authentication mode bitvec */ -+#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */ -+#define WPA_AUTH_NONE 0x0001 /* none (IBSS) */ -+#define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */ -+#define WPA_AUTH_PSK 0x0004 /* Pre-shared key */ -+/* #define WPA_AUTH_8021X 0x0020 */ /* 802.1x, reserved */ -+#define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */ -+#define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */ -+#define BRCM_AUTH_PSK 0x0100 /* BRCM specific PSK */ -+#define BRCM_AUTH_DPT 0x0200 /* DPT PSK without group keys */ -+#define WPA2_AUTH_MFP 0x1000 /* MFP (11w) in contrast to CCX */ -+#define WPA2_AUTH_TPK 0x2000 /* TDLS Peer Key */ -+#define WPA2_AUTH_FT 0x4000 /* Fast Transition. */ -+#define WPA_AUTH_PFN_ANY 0xffffffff /* for PFN, match only ssid */ -+ -+/* pmkid */ -+#define MAXPMKID 16 -+ -+typedef struct _pmkid { -+ struct ether_addr BSSID; -+ uint8 PMKID[WPA2_PMKID_LEN]; -+} pmkid_t; -+ -+typedef struct _pmkid_list { -+ uint32 npmkid; -+ pmkid_t pmkid[1]; -+} pmkid_list_t; -+ -+typedef struct _pmkid_cand { -+ struct ether_addr BSSID; -+ uint8 preauth; -+} pmkid_cand_t; -+ -+typedef struct _pmkid_cand_list { -+ uint32 npmkid_cand; -+ pmkid_cand_t pmkid_cand[1]; -+} pmkid_cand_list_t; -+ -+typedef struct wl_assoc_info { -+ uint32 req_len; -+ uint32 resp_len; -+ uint32 flags; -+ struct dot11_assoc_req req; -+ struct ether_addr reassoc_bssid; /* used in reassoc's */ -+ struct dot11_assoc_resp resp; -+} wl_assoc_info_t; -+ -+/* flags */ -+#define WLC_ASSOC_REQ_IS_REASSOC 0x01 /* assoc req was actually a reassoc */ -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+typedef struct wl_led_info { -+ uint32 index; /* led index */ -+ uint32 behavior; -+ uint8 activehi; -+} wl_led_info_t; -+ -+ -+/* srom read/write struct passed through ioctl */ -+typedef struct { -+ uint byteoff; /* byte offset */ -+ uint nbytes; /* number of bytes */ -+ uint16 buf[1]; -+} srom_rw_t; -+ -+/* similar cis (srom or otp) struct [iovar: may not be aligned] */ -+typedef struct { -+ uint32 source; /* cis source */ -+ uint32 byteoff; /* byte offset */ -+ uint32 nbytes; /* number of bytes */ -+ /* data follows here */ -+} cis_rw_t; -+ -+#define WLC_CIS_DEFAULT 0 /* built-in default */ -+#define WLC_CIS_SROM 1 /* source is sprom */ -+#define WLC_CIS_OTP 2 /* source is otp */ -+ -+/* R_REG and W_REG struct passed through ioctl */ -+typedef struct { -+ uint32 byteoff; /* byte offset of the field in d11regs_t */ -+ uint32 val; /* read/write value of the field */ -+ uint32 size; /* sizeof the field */ -+ uint band; /* band (optional) */ -+} rw_reg_t; -+ -+/* Structure used by GET/SET_ATTEN ioctls - it controls power in b/g-band */ -+/* PCL - Power Control Loop */ -+/* current gain setting is replaced by user input */ -+#define WL_ATTEN_APP_INPUT_PCL_OFF 0 /* turn off PCL, apply supplied input */ -+#define WL_ATTEN_PCL_ON 1 /* turn on PCL */ -+/* current gain setting is maintained */ -+#define WL_ATTEN_PCL_OFF 2 /* turn off PCL. */ -+ -+typedef struct { -+ uint16 auto_ctrl; /* WL_ATTEN_XX */ -+ uint16 bb; /* Baseband attenuation */ -+ uint16 radio; /* Radio attenuation */ -+ uint16 txctl1; /* Radio TX_CTL1 value */ -+} atten_t; -+ -+/* Per-AC retry parameters */ -+struct wme_tx_params_s { -+ uint8 short_retry; -+ uint8 short_fallback; -+ uint8 long_retry; -+ uint8 long_fallback; -+ uint16 max_rate; /* In units of 512 Kbps */ -+}; -+ -+typedef struct wme_tx_params_s wme_tx_params_t; -+ -+#define WL_WME_TX_PARAMS_IO_BYTES (sizeof(wme_tx_params_t) * AC_COUNT) -+ -+/* defines used by poweridx iovar - it controls power in a-band */ -+/* current gain setting is maintained */ -+#define WL_PWRIDX_PCL_OFF -2 /* turn off PCL. */ -+#define WL_PWRIDX_PCL_ON -1 /* turn on PCL */ -+#define WL_PWRIDX_LOWER_LIMIT -2 /* lower limit */ -+#define WL_PWRIDX_UPPER_LIMIT 63 /* upper limit */ -+/* value >= 0 causes -+ * - input to be set to that value -+ * - PCL to be off -+ */ -+ -+/* Used to get specific link/ac parameters */ -+typedef struct { -+ int ac; -+ uint8 val; -+ struct ether_addr ea; -+} link_val_t; -+ -+#define BCM_MAC_STATUS_INDICATION (0x40010200L) -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+typedef struct { -+ uint16 ver; /* version of this struct */ -+ uint16 len; /* length in bytes of this structure */ -+ uint16 cap; /* sta's advertised capabilities */ -+ uint32 flags; /* flags defined below */ -+ uint32 idle; /* time since data pkt rx'd from sta */ -+ struct ether_addr ea; /* Station address */ -+ wl_rateset_t rateset; /* rateset in use */ -+ uint32 in; /* seconds elapsed since associated */ -+ uint32 listen_interval_inms; /* Min Listen interval in ms for this STA */ -+ uint32 tx_pkts; /* # of packets transmitted */ -+ uint32 tx_failures; /* # of packets failed */ -+ uint32 rx_ucast_pkts; /* # of unicast packets received */ -+ uint32 rx_mcast_pkts; /* # of multicast packets received */ -+ uint32 tx_rate; /* Rate of last successful tx frame */ -+ uint32 rx_rate; /* Rate of last successful rx frame */ -+ uint32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ -+ uint32 rx_decrypt_failures; /* # of packet decrypted unsuccessfully */ -+} sta_info_t; -+ -+#define WL_OLD_STAINFO_SIZE OFFSETOF(sta_info_t, tx_pkts) -+ -+#define WL_STA_VER 3 -+ -+/* Flags for sta_info_t indicating properties of STA */ -+#define WL_STA_BRCM 0x1 /* Running a Broadcom driver */ -+#define WL_STA_WME 0x2 /* WMM association */ -+#define WL_STA_UNUSED 0x4 -+#define WL_STA_AUTHE 0x8 /* Authenticated */ -+#define WL_STA_ASSOC 0x10 /* Associated */ -+#define WL_STA_AUTHO 0x20 /* Authorized */ -+#define WL_STA_WDS 0x40 /* Wireless Distribution System */ -+#define WL_STA_WDS_LINKUP 0x80 /* WDS traffic/probes flowing properly */ -+#define WL_STA_PS 0x100 /* STA is in power save mode from AP's viewpoint */ -+#define WL_STA_APSD_BE 0x200 /* APSD delv/trigger for AC_BE is default enabled */ -+#define WL_STA_APSD_BK 0x400 /* APSD delv/trigger for AC_BK is default enabled */ -+#define WL_STA_APSD_VI 0x800 /* APSD delv/trigger for AC_VI is default enabled */ -+#define WL_STA_APSD_VO 0x1000 /* APSD delv/trigger for AC_VO is default enabled */ -+#define WL_STA_N_CAP 0x2000 /* STA 802.11n capable */ -+#define WL_STA_SCBSTATS 0x4000 /* Per STA debug stats */ -+ -+#define WL_WDS_LINKUP WL_STA_WDS_LINKUP /* deprecated */ -+ -+/* Values for TX Filter override mode */ -+#define WLC_TXFILTER_OVERRIDE_DISABLED 0 -+#define WLC_TXFILTER_OVERRIDE_ENABLED 1 -+ -+/* Used to get specific STA parameters */ -+typedef struct { -+ uint32 val; -+ struct ether_addr ea; -+} scb_val_t; -+ -+/* Used by iovar versions of some ioctls, i.e. WLC_SCB_AUTHORIZE et al */ -+typedef struct { -+ uint32 code; -+ scb_val_t ioctl_args; -+} authops_t; -+ -+/* channel encoding */ -+typedef struct channel_info { -+ int hw_channel; -+ int target_channel; -+ int scan_channel; -+} channel_info_t; -+ -+/* For ioctls that take a list of MAC addresses */ -+struct maclist { -+ uint count; /* number of MAC addresses */ -+ struct ether_addr ea[1]; /* variable length array of MAC addresses */ -+}; -+ -+/* get pkt count struct passed through ioctl */ -+typedef struct get_pktcnt { -+ uint rx_good_pkt; -+ uint rx_bad_pkt; -+ uint tx_good_pkt; -+ uint tx_bad_pkt; -+ uint rx_ocast_good_pkt; /* unicast packets destined for others */ -+} get_pktcnt_t; -+ -+/* NINTENDO2 */ -+#define LQ_IDX_MIN 0 -+#define LQ_IDX_MAX 1 -+#define LQ_IDX_AVG 2 -+#define LQ_IDX_SUM 2 -+#define LQ_IDX_LAST 3 -+#define LQ_STOP_MONITOR 0 -+#define LQ_START_MONITOR 1 -+ -+/* Get averages RSSI, Rx PHY rate and SNR values */ -+typedef struct { -+ int rssi[LQ_IDX_LAST]; /* Array to keep min, max, avg rssi */ -+ int snr[LQ_IDX_LAST]; /* Array to keep min, max, avg snr */ -+ int isvalid; /* Flag indicating whether above data is valid */ -+} wl_lq_t; /* Link Quality */ -+ -+typedef enum wl_wakeup_reason_type { -+ LCD_ON = 1, -+ LCD_OFF, -+ DRC1_WAKE, -+ DRC2_WAKE, -+ REASON_LAST -+} wl_wr_type_t; -+ -+typedef struct { -+/* Unique filter id */ -+ uint32 id; -+ -+/* stores the reason for the last wake up */ -+ uint8 reason; -+} wl_wr_t; -+ -+/* Get MAC specific rate histogram command */ -+typedef struct { -+ struct ether_addr ea; /* MAC Address */ -+ uint8 ac_cat; /* Access Category */ -+ uint8 num_pkts; /* Number of packet entries to be averaged */ -+} wl_mac_ratehisto_cmd_t; /* MAC Specific Rate Histogram command */ -+ -+/* Get MAC rate histogram response */ -+typedef struct { -+ uint32 rate[WLC_MAXRATE + 1]; /* Rates */ -+ uint32 mcs[WL_RATESET_SZ_HT_MCS * WL_TX_CHAINS_MAX]; /* MCS counts */ -+ uint32 vht[WL_RATESET_SZ_VHT_MCS][WL_TX_CHAINS_MAX]; /* VHT counts */ -+ uint32 tsf_timer[2][2]; /* Start and End time for 8bytes value */ -+} wl_mac_ratehisto_res_t; /* MAC Specific Rate Histogram Response */ -+ -+/* Values for TX Filter override mode */ -+#define WLC_TXFILTER_OVERRIDE_DISABLED 0 -+#define WLC_TXFILTER_OVERRIDE_ENABLED 1 -+ -+#define WL_IOCTL_ACTION_GET 0x0 -+#define WL_IOCTL_ACTION_SET 0x1 -+#define WL_IOCTL_ACTION_OVL_IDX_MASK 0x1e -+#define WL_IOCTL_ACTION_OVL_RSV 0x20 -+#define WL_IOCTL_ACTION_OVL 0x40 -+#define WL_IOCTL_ACTION_MASK 0x7e -+#define WL_IOCTL_ACTION_OVL_SHIFT 1 -+ -+/* Linux network driver ioctl encoding */ -+typedef struct wl_ioctl { -+ uint cmd; /* common ioctl definition */ -+ void *buf; /* pointer to user buffer */ -+ uint len; /* length of user buffer */ -+ uint8 set; /* 1=set IOCTL; 0=query IOCTL */ -+ uint used; /* bytes read or written (optional) */ -+ uint needed; /* bytes needed (optional) */ -+} wl_ioctl_t; -+ -+/* reference to wl_ioctl_t struct used by usermode driver */ -+#define ioctl_subtype set /* subtype param */ -+#define ioctl_pid used /* pid param */ -+#define ioctl_status needed /* status param */ -+ -+/* -+ * Structure for passing hardware and software -+ * revision info up from the driver. -+ */ -+typedef struct wlc_rev_info { -+ uint vendorid; /* PCI vendor id */ -+ uint deviceid; /* device id of chip */ -+ uint radiorev; /* radio revision */ -+ uint chiprev; /* chip revision */ -+ uint corerev; /* core revision */ -+ uint boardid; /* board identifier (usu. PCI sub-device id) */ -+ uint boardvendor; /* board vendor (usu. PCI sub-vendor id) */ -+ uint boardrev; /* board revision */ -+ uint driverrev; /* driver version */ -+ uint ucoderev; /* microcode version */ -+ uint bus; /* bus type */ -+ uint chipnum; /* chip number */ -+ uint phytype; /* phy type */ -+ uint phyrev; /* phy revision */ -+ uint anarev; /* anacore rev */ -+ uint chippkg; /* chip package info */ -+} wlc_rev_info_t; -+ -+#define WL_REV_INFO_LEGACY_LENGTH 48 -+ -+#define WL_BRAND_MAX 10 -+typedef struct wl_instance_info { -+ uint instance; -+ char brand[WL_BRAND_MAX]; -+} wl_instance_info_t; -+ -+/* structure to change size of tx fifo */ -+typedef struct wl_txfifo_sz { -+ uint16 magic; -+ uint16 fifo; -+ uint16 size; -+} wl_txfifo_sz_t; -+/* magic pattern used for mismatch driver and wl */ -+#define WL_TXFIFO_SZ_MAGIC 0xa5a5 -+ -+/* Transfer info about an IOVar from the driver */ -+/* Max supported IOV name size in bytes, + 1 for nul termination */ -+#define WLC_IOV_NAME_LEN 30 -+typedef struct wlc_iov_trx_s { -+ uint8 module; -+ uint8 type; -+ char name[WLC_IOV_NAME_LEN]; -+} wlc_iov_trx_t; -+ -+/* check this magic number */ -+#define WLC_IOCTL_MAGIC 0x14e46c77 -+ -+/* bump this number if you change the ioctl interface */ -+#ifdef D11AC_IOTYPES -+#define WLC_IOCTL_VERSION 2 -+#define WLC_IOCTL_VERSION_LEGACY_IOTYPES 1 -+#else -+#define WLC_IOCTL_VERSION 1 -+#endif /* D11AC_IOTYPES */ -+ -+#define WLC_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ -+#define WLC_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ -+#define WLC_IOCTL_MEDLEN 1536 /* "med" length ioctl buffer required */ -+#ifdef WLC_HIGH_ONLY -+#define WLC_SAMPLECOLLECT_MAXLEN 1024 /* limit sample size for bmac */ -+#else -+#if defined(LCNCONF) || defined(LCN40CONF) -+#define WLC_SAMPLECOLLECT_MAXLEN 8192 /* Max Sample Collect buffer */ -+#else -+#define WLC_SAMPLECOLLECT_MAXLEN 10240 /* Max Sample Collect buffer for two cores */ -+#endif -+#endif /* WLC_HIGH_ONLY */ -+ -+/* common ioctl definitions */ -+#define WLC_GET_MAGIC 0 -+#define WLC_GET_VERSION 1 -+#define WLC_UP 2 -+#define WLC_DOWN 3 -+#define WLC_GET_LOOP 4 -+#define WLC_SET_LOOP 5 -+#define WLC_DUMP 6 -+#define WLC_GET_MSGLEVEL 7 -+#define WLC_SET_MSGLEVEL 8 -+#define WLC_GET_PROMISC 9 -+#define WLC_SET_PROMISC 10 -+/* #define WLC_OVERLAY_IOCTL 11 */ /* not supported */ -+#define WLC_GET_RATE 12 -+#define WLC_GET_MAX_RATE 13 -+#define WLC_GET_INSTANCE 14 -+/* #define WLC_GET_FRAG 15 */ /* no longer supported */ -+/* #define WLC_SET_FRAG 16 */ /* no longer supported */ -+/* #define WLC_GET_RTS 17 */ /* no longer supported */ -+/* #define WLC_SET_RTS 18 */ /* no longer supported */ -+#define WLC_GET_INFRA 19 -+#define WLC_SET_INFRA 20 -+#define WLC_GET_AUTH 21 -+#define WLC_SET_AUTH 22 -+#define WLC_GET_BSSID 23 -+#define WLC_SET_BSSID 24 -+#define WLC_GET_SSID 25 -+#define WLC_SET_SSID 26 -+#define WLC_RESTART 27 -+#define WLC_TERMINATED 28 -+/* #define WLC_DUMP_SCB 28 */ /* no longer supported */ -+#define WLC_GET_CHANNEL 29 -+#define WLC_SET_CHANNEL 30 -+#define WLC_GET_SRL 31 -+#define WLC_SET_SRL 32 -+#define WLC_GET_LRL 33 -+#define WLC_SET_LRL 34 -+#define WLC_GET_PLCPHDR 35 -+#define WLC_SET_PLCPHDR 36 -+#define WLC_GET_RADIO 37 -+#define WLC_SET_RADIO 38 -+#define WLC_GET_PHYTYPE 39 -+#define WLC_DUMP_RATE 40 -+#define WLC_SET_RATE_PARAMS 41 -+#define WLC_GET_FIXRATE 42 -+#define WLC_SET_FIXRATE 43 -+/* #define WLC_GET_WEP 42 */ /* no longer supported */ -+/* #define WLC_SET_WEP 43 */ /* no longer supported */ -+#define WLC_GET_KEY 44 -+#define WLC_SET_KEY 45 -+#define WLC_GET_REGULATORY 46 -+#define WLC_SET_REGULATORY 47 -+#define WLC_GET_PASSIVE_SCAN 48 -+#define WLC_SET_PASSIVE_SCAN 49 -+#define WLC_SCAN 50 -+#define WLC_SCAN_RESULTS 51 -+#define WLC_DISASSOC 52 -+#define WLC_REASSOC 53 -+#define WLC_GET_ROAM_TRIGGER 54 -+#define WLC_SET_ROAM_TRIGGER 55 -+#define WLC_GET_ROAM_DELTA 56 -+#define WLC_SET_ROAM_DELTA 57 -+#define WLC_GET_ROAM_SCAN_PERIOD 58 -+#define WLC_SET_ROAM_SCAN_PERIOD 59 -+#define WLC_EVM 60 /* diag */ -+#define WLC_GET_TXANT 61 -+#define WLC_SET_TXANT 62 -+#define WLC_GET_ANTDIV 63 -+#define WLC_SET_ANTDIV 64 -+/* #define WLC_GET_TXPWR 65 */ /* no longer supported */ -+/* #define WLC_SET_TXPWR 66 */ /* no longer supported */ -+#define WLC_GET_CLOSED 67 -+#define WLC_SET_CLOSED 68 -+#define WLC_GET_MACLIST 69 -+#define WLC_SET_MACLIST 70 -+#define WLC_GET_RATESET 71 -+#define WLC_SET_RATESET 72 -+/* #define WLC_GET_LOCALE 73 */ /* no longer supported */ -+#define WLC_LONGTRAIN 74 -+#define WLC_GET_BCNPRD 75 -+#define WLC_SET_BCNPRD 76 -+#define WLC_GET_DTIMPRD 77 -+#define WLC_SET_DTIMPRD 78 -+#define WLC_GET_SROM 79 -+#define WLC_SET_SROM 80 -+#define WLC_GET_WEP_RESTRICT 81 -+#define WLC_SET_WEP_RESTRICT 82 -+#define WLC_GET_COUNTRY 83 -+#define WLC_SET_COUNTRY 84 -+#define WLC_GET_PM 85 -+#define WLC_SET_PM 86 -+#define WLC_GET_WAKE 87 -+#define WLC_SET_WAKE 88 -+/* #define WLC_GET_D11CNTS 89 */ /* -> "counters" iovar */ -+#define WLC_GET_FORCELINK 90 /* ndis only */ -+#define WLC_SET_FORCELINK 91 /* ndis only */ -+#define WLC_FREQ_ACCURACY 92 /* diag */ -+#define WLC_CARRIER_SUPPRESS 93 /* diag */ -+#define WLC_GET_PHYREG 94 -+#define WLC_SET_PHYREG 95 -+#define WLC_GET_RADIOREG 96 -+#define WLC_SET_RADIOREG 97 -+#define WLC_GET_REVINFO 98 -+#define WLC_GET_UCANTDIV 99 -+#define WLC_SET_UCANTDIV 100 -+#define WLC_R_REG 101 -+#define WLC_W_REG 102 -+/* #define WLC_DIAG_LOOPBACK 103 old tray diag */ -+/* #define WLC_RESET_D11CNTS 104 */ /* -> "reset_d11cnts" iovar */ -+#define WLC_GET_MACMODE 105 -+#define WLC_SET_MACMODE 106 -+#define WLC_GET_MONITOR 107 -+#define WLC_SET_MONITOR 108 -+#define WLC_GET_GMODE 109 -+#define WLC_SET_GMODE 110 -+#define WLC_GET_LEGACY_ERP 111 -+#define WLC_SET_LEGACY_ERP 112 -+#define WLC_GET_RX_ANT 113 -+#define WLC_GET_CURR_RATESET 114 /* current rateset */ -+#define WLC_GET_SCANSUPPRESS 115 -+#define WLC_SET_SCANSUPPRESS 116 -+#define WLC_GET_AP 117 -+#define WLC_SET_AP 118 -+#define WLC_GET_EAP_RESTRICT 119 -+#define WLC_SET_EAP_RESTRICT 120 -+#define WLC_SCB_AUTHORIZE 121 -+#define WLC_SCB_DEAUTHORIZE 122 -+#define WLC_GET_WDSLIST 123 -+#define WLC_SET_WDSLIST 124 -+#define WLC_GET_ATIM 125 -+#define WLC_SET_ATIM 126 -+#define WLC_GET_RSSI 127 -+#define WLC_GET_PHYANTDIV 128 -+#define WLC_SET_PHYANTDIV 129 -+#define WLC_AP_RX_ONLY 130 -+#define WLC_GET_TX_PATH_PWR 131 -+#define WLC_SET_TX_PATH_PWR 132 -+#define WLC_GET_WSEC 133 -+#define WLC_SET_WSEC 134 -+#define WLC_GET_PHY_NOISE 135 -+#define WLC_GET_BSS_INFO 136 -+#define WLC_GET_PKTCNTS 137 -+#define WLC_GET_LAZYWDS 138 -+#define WLC_SET_LAZYWDS 139 -+#define WLC_GET_BANDLIST 140 -+#define WLC_GET_BAND 141 -+#define WLC_SET_BAND 142 -+#define WLC_SCB_DEAUTHENTICATE 143 -+#define WLC_GET_SHORTSLOT 144 -+#define WLC_GET_SHORTSLOT_OVERRIDE 145 -+#define WLC_SET_SHORTSLOT_OVERRIDE 146 -+#define WLC_GET_SHORTSLOT_RESTRICT 147 -+#define WLC_SET_SHORTSLOT_RESTRICT 148 -+#define WLC_GET_GMODE_PROTECTION 149 -+#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150 -+#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151 -+#define WLC_UPGRADE 152 -+/* #define WLC_GET_MRATE 153 */ /* no longer supported */ -+/* #define WLC_SET_MRATE 154 */ /* no longer supported */ -+#define WLC_GET_IGNORE_BCNS 155 -+#define WLC_SET_IGNORE_BCNS 156 -+#define WLC_GET_SCB_TIMEOUT 157 -+#define WLC_SET_SCB_TIMEOUT 158 -+#define WLC_GET_ASSOCLIST 159 -+#define WLC_GET_CLK 160 -+#define WLC_SET_CLK 161 -+#define WLC_GET_UP 162 -+#define WLC_OUT 163 -+#define WLC_GET_WPA_AUTH 164 -+#define WLC_SET_WPA_AUTH 165 -+#define WLC_GET_UCFLAGS 166 -+#define WLC_SET_UCFLAGS 167 -+#define WLC_GET_PWRIDX 168 -+#define WLC_SET_PWRIDX 169 -+#define WLC_GET_TSSI 170 -+#define WLC_GET_SUP_RATESET_OVERRIDE 171 -+#define WLC_SET_SUP_RATESET_OVERRIDE 172 -+/* #define WLC_SET_FAST_TIMER 173 */ /* no longer supported */ -+/* #define WLC_GET_FAST_TIMER 174 */ /* no longer supported */ -+/* #define WLC_SET_SLOW_TIMER 175 */ /* no longer supported */ -+/* #define WLC_GET_SLOW_TIMER 176 */ /* no longer supported */ -+/* #define WLC_DUMP_PHYREGS 177 */ /* no longer supported */ -+#define WLC_GET_PROTECTION_CONTROL 178 -+#define WLC_SET_PROTECTION_CONTROL 179 -+#define WLC_GET_PHYLIST 180 -+#define WLC_ENCRYPT_STRENGTH 181 /* ndis only */ -+#define WLC_DECRYPT_STATUS 182 /* ndis only */ -+#define WLC_GET_KEY_SEQ 183 -+#define WLC_GET_SCAN_CHANNEL_TIME 184 -+#define WLC_SET_SCAN_CHANNEL_TIME 185 -+#define WLC_GET_SCAN_UNASSOC_TIME 186 -+#define WLC_SET_SCAN_UNASSOC_TIME 187 -+#define WLC_GET_SCAN_HOME_TIME 188 -+#define WLC_SET_SCAN_HOME_TIME 189 -+#define WLC_GET_SCAN_NPROBES 190 -+#define WLC_SET_SCAN_NPROBES 191 -+#define WLC_GET_PRB_RESP_TIMEOUT 192 -+#define WLC_SET_PRB_RESP_TIMEOUT 193 -+#define WLC_GET_ATTEN 194 -+#define WLC_SET_ATTEN 195 -+#define WLC_GET_SHMEM 196 /* diag */ -+#define WLC_SET_SHMEM 197 /* diag */ -+/* #define WLC_GET_GMODE_PROTECTION_CTS 198 */ /* no longer supported */ -+/* #define WLC_SET_GMODE_PROTECTION_CTS 199 */ /* no longer supported */ -+#define WLC_SET_WSEC_TEST 200 -+#define WLC_SCB_DEAUTHENTICATE_FOR_REASON 201 -+#define WLC_TKIP_COUNTERMEASURES 202 -+#define WLC_GET_PIOMODE 203 -+#define WLC_SET_PIOMODE 204 -+#define WLC_SET_ASSOC_PREFER 205 -+#define WLC_GET_ASSOC_PREFER 206 -+#define WLC_SET_ROAM_PREFER 207 -+#define WLC_GET_ROAM_PREFER 208 -+#define WLC_SET_LED 209 -+#define WLC_GET_LED 210 -+#define WLC_GET_INTERFERENCE_MODE 211 -+#define WLC_SET_INTERFERENCE_MODE 212 -+#define WLC_GET_CHANNEL_QA 213 -+#define WLC_START_CHANNEL_QA 214 -+#define WLC_GET_CHANNEL_SEL 215 -+#define WLC_START_CHANNEL_SEL 216 -+#define WLC_GET_VALID_CHANNELS 217 -+#define WLC_GET_FAKEFRAG 218 -+#define WLC_SET_FAKEFRAG 219 -+#define WLC_GET_PWROUT_PERCENTAGE 220 -+#define WLC_SET_PWROUT_PERCENTAGE 221 -+#define WLC_SET_BAD_FRAME_PREEMPT 222 -+#define WLC_GET_BAD_FRAME_PREEMPT 223 -+#define WLC_SET_LEAP_LIST 224 -+#define WLC_GET_LEAP_LIST 225 -+#define WLC_GET_CWMIN 226 -+#define WLC_SET_CWMIN 227 -+#define WLC_GET_CWMAX 228 -+#define WLC_SET_CWMAX 229 -+#define WLC_GET_WET 230 -+#define WLC_SET_WET 231 -+#define WLC_GET_PUB 232 -+/* #define WLC_SET_GLACIAL_TIMER 233 */ /* no longer supported */ -+/* #define WLC_GET_GLACIAL_TIMER 234 */ /* no longer supported */ -+#define WLC_GET_KEY_PRIMARY 235 -+#define WLC_SET_KEY_PRIMARY 236 -+/* #define WLC_DUMP_RADIOREGS 237 */ /* no longer supported */ -+#define WLC_GET_ACI_ARGS 238 -+#define WLC_SET_ACI_ARGS 239 -+#define WLC_UNSET_CALLBACK 240 -+#define WLC_SET_CALLBACK 241 -+#define WLC_GET_RADAR 242 -+#define WLC_SET_RADAR 243 -+#define WLC_SET_SPECT_MANAGMENT 244 -+#define WLC_GET_SPECT_MANAGMENT 245 -+#define WLC_WDS_GET_REMOTE_HWADDR 246 /* handled in wl_linux.c/wl_vx.c */ -+#define WLC_WDS_GET_WPA_SUP 247 -+#define WLC_SET_CS_SCAN_TIMER 248 -+#define WLC_GET_CS_SCAN_TIMER 249 -+#define WLC_MEASURE_REQUEST 250 -+#define WLC_INIT 251 -+#define WLC_SEND_QUIET 252 -+#define WLC_KEEPALIVE 253 -+#define WLC_SEND_PWR_CONSTRAINT 254 -+#define WLC_UPGRADE_STATUS 255 -+#define WLC_CURRENT_PWR 256 -+#define WLC_GET_SCAN_PASSIVE_TIME 257 -+#define WLC_SET_SCAN_PASSIVE_TIME 258 -+#define WLC_LEGACY_LINK_BEHAVIOR 259 -+#define WLC_GET_CHANNELS_IN_COUNTRY 260 -+#define WLC_GET_COUNTRY_LIST 261 -+#define WLC_GET_VAR 262 /* get value of named variable */ -+#define WLC_SET_VAR 263 /* set named variable to value */ -+#define WLC_NVRAM_GET 264 /* deprecated */ -+#define WLC_NVRAM_SET 265 -+#define WLC_NVRAM_DUMP 266 -+#define WLC_REBOOT 267 -+#define WLC_SET_WSEC_PMK 268 -+#define WLC_GET_AUTH_MODE 269 -+#define WLC_SET_AUTH_MODE 270 -+#define WLC_GET_WAKEENTRY 271 -+#define WLC_SET_WAKEENTRY 272 -+#define WLC_NDCONFIG_ITEM 273 /* currently handled in wl_oid.c */ -+#define WLC_NVOTPW 274 -+#define WLC_OTPW 275 -+#define WLC_IOV_BLOCK_GET 276 -+#define WLC_IOV_MODULES_GET 277 -+#define WLC_SOFT_RESET 278 -+#define WLC_GET_ALLOW_MODE 279 -+#define WLC_SET_ALLOW_MODE 280 -+#define WLC_GET_DESIRED_BSSID 281 -+#define WLC_SET_DESIRED_BSSID 282 -+#define WLC_DISASSOC_MYAP 283 -+#define WLC_GET_NBANDS 284 /* for Dongle EXT_STA support */ -+#define WLC_GET_BANDSTATES 285 /* for Dongle EXT_STA support */ -+#define WLC_GET_WLC_BSS_INFO 286 /* for Dongle EXT_STA support */ -+#define WLC_GET_ASSOC_INFO 287 /* for Dongle EXT_STA support */ -+#define WLC_GET_OID_PHY 288 /* for Dongle EXT_STA support */ -+#define WLC_SET_OID_PHY 289 /* for Dongle EXT_STA support */ -+#define WLC_SET_ASSOC_TIME 290 /* for Dongle EXT_STA support */ -+#define WLC_GET_DESIRED_SSID 291 /* for Dongle EXT_STA support */ -+#define WLC_GET_CHANSPEC 292 /* for Dongle EXT_STA support */ -+#define WLC_GET_ASSOC_STATE 293 /* for Dongle EXT_STA support */ -+#define WLC_SET_PHY_STATE 294 /* for Dongle EXT_STA support */ -+#define WLC_GET_SCAN_PENDING 295 /* for Dongle EXT_STA support */ -+#define WLC_GET_SCANREQ_PENDING 296 /* for Dongle EXT_STA support */ -+#define WLC_GET_PREV_ROAM_REASON 297 /* for Dongle EXT_STA support */ -+#define WLC_SET_PREV_ROAM_REASON 298 /* for Dongle EXT_STA support */ -+#define WLC_GET_BANDSTATES_PI 299 /* for Dongle EXT_STA support */ -+#define WLC_GET_PHY_STATE 300 /* for Dongle EXT_STA support */ -+#define WLC_GET_BSS_WPA_RSN 301 /* for Dongle EXT_STA support */ -+#define WLC_GET_BSS_WPA2_RSN 302 /* for Dongle EXT_STA support */ -+#define WLC_GET_BSS_BCN_TS 303 /* for Dongle EXT_STA support */ -+#define WLC_GET_INT_DISASSOC 304 /* for Dongle EXT_STA support */ -+#define WLC_SET_NUM_PEERS 305 /* for Dongle EXT_STA support */ -+#define WLC_GET_NUM_BSS 306 /* for Dongle EXT_STA support */ -+#define WLC_PHY_SAMPLE_COLLECT 307 /* phy sample collect mode */ -+/* #define WLC_UM_PRIV 308 */ /* Deprecated: usermode driver */ -+#define WLC_GET_CMD 309 -+/* #define WLC_LAST 310 */ /* Never used - can be reused */ -+#define WLC_SET_INTERFERENCE_OVERRIDE_MODE 311 /* set inter mode override */ -+#define WLC_GET_INTERFERENCE_OVERRIDE_MODE 312 /* get inter mode override */ -+/* #define WLC_GET_WAI_RESTRICT 313 */ /* for WAPI, deprecated use iovar instead */ -+/* #define WLC_SET_WAI_RESTRICT 314 */ /* for WAPI, deprecated use iovar instead */ -+/* #define WLC_SET_WAI_REKEY 315 */ /* for WAPI, deprecated use iovar instead */ -+#define WLC_SET_NAT_CONFIG 316 /* for configuring NAT filter driver */ -+#define WLC_GET_NAT_STATE 317 -+#define WLC_LAST 318 -+ -+#ifndef EPICTRL_COOKIE -+#define EPICTRL_COOKIE 0xABADCEDE -+#endif -+ -+/* vx wlc ioctl's offset */ -+#define CMN_IOCTL_OFF 0x180 -+ -+/* -+ * custom OID support -+ * -+ * 0xFF - implementation specific OID -+ * 0xE4 - first byte of Broadcom PCI vendor ID -+ * 0x14 - second byte of Broadcom PCI vendor ID -+ * 0xXX - the custom OID number -+ */ -+ -+/* begin 0x1f values beyond the start of the ET driver range. */ -+#define WL_OID_BASE 0xFFE41420 -+ -+/* NDIS overrides */ -+#define OID_WL_GETINSTANCE (WL_OID_BASE + WLC_GET_INSTANCE) -+#define OID_WL_GET_FORCELINK (WL_OID_BASE + WLC_GET_FORCELINK) -+#define OID_WL_SET_FORCELINK (WL_OID_BASE + WLC_SET_FORCELINK) -+#define OID_WL_ENCRYPT_STRENGTH (WL_OID_BASE + WLC_ENCRYPT_STRENGTH) -+#define OID_WL_DECRYPT_STATUS (WL_OID_BASE + WLC_DECRYPT_STATUS) -+#define OID_LEGACY_LINK_BEHAVIOR (WL_OID_BASE + WLC_LEGACY_LINK_BEHAVIOR) -+#define OID_WL_NDCONFIG_ITEM (WL_OID_BASE + WLC_NDCONFIG_ITEM) -+ -+/* EXT_STA Dongle suuport */ -+#define OID_STA_CHANSPEC (WL_OID_BASE + WLC_GET_CHANSPEC) -+#define OID_STA_NBANDS (WL_OID_BASE + WLC_GET_NBANDS) -+#define OID_STA_GET_PHY (WL_OID_BASE + WLC_GET_OID_PHY) -+#define OID_STA_SET_PHY (WL_OID_BASE + WLC_SET_OID_PHY) -+#define OID_STA_ASSOC_TIME (WL_OID_BASE + WLC_SET_ASSOC_TIME) -+#define OID_STA_DESIRED_SSID (WL_OID_BASE + WLC_GET_DESIRED_SSID) -+#define OID_STA_SET_PHY_STATE (WL_OID_BASE + WLC_SET_PHY_STATE) -+#define OID_STA_SCAN_PENDING (WL_OID_BASE + WLC_GET_SCAN_PENDING) -+#define OID_STA_SCANREQ_PENDING (WL_OID_BASE + WLC_GET_SCANREQ_PENDING) -+#define OID_STA_GET_ROAM_REASON (WL_OID_BASE + WLC_GET_PREV_ROAM_REASON) -+#define OID_STA_SET_ROAM_REASON (WL_OID_BASE + WLC_SET_PREV_ROAM_REASON) -+#define OID_STA_GET_PHY_STATE (WL_OID_BASE + WLC_GET_PHY_STATE) -+#define OID_STA_INT_DISASSOC (WL_OID_BASE + WLC_GET_INT_DISASSOC) -+#define OID_STA_SET_NUM_PEERS (WL_OID_BASE + WLC_SET_NUM_PEERS) -+#define OID_STA_GET_NUM_BSS (WL_OID_BASE + WLC_GET_NUM_BSS) -+ -+/* NAT filter driver support */ -+#define OID_NAT_SET_CONFIG (WL_OID_BASE + WLC_SET_NAT_CONFIG) -+#define OID_NAT_GET_STATE (WL_OID_BASE + WLC_GET_NAT_STATE) -+ -+#define WL_DECRYPT_STATUS_SUCCESS 1 -+#define WL_DECRYPT_STATUS_FAILURE 2 -+#define WL_DECRYPT_STATUS_UNKNOWN 3 -+ -+/* allows user-mode app to poll the status of USB image upgrade */ -+#define WLC_UPGRADE_SUCCESS 0 -+#define WLC_UPGRADE_PENDING 1 -+ -+#ifdef CONFIG_USBRNDIS_RETAIL -+/* struct passed in for WLC_NDCONFIG_ITEM */ -+typedef struct { -+ char *name; -+ void *param; -+} ndconfig_item_t; -+#endif -+ -+ -+/* WLC_GET_AUTH, WLC_SET_AUTH values */ -+#define WL_AUTH_OPEN_SYSTEM 0 /* d11 open authentication */ -+#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */ -+#define WL_AUTH_OPEN_SHARED 2 /* try open, then shared if open failed w/rc 13 */ -+ -+/* Bit masks for radio disabled status - returned by WL_GET_RADIO */ -+#define WL_RADIO_SW_DISABLE (1<<0) -+#define WL_RADIO_HW_DISABLE (1<<1) -+#define WL_RADIO_MPC_DISABLE (1<<2) -+#define WL_RADIO_COUNTRY_DISABLE (1<<3) /* some countries don't support any channel */ -+ -+#define WL_SPURAVOID_OFF 0 -+#define WL_SPURAVOID_ON1 1 -+#define WL_SPURAVOID_ON2 2 -+ -+/* Override bit for WLC_SET_TXPWR. if set, ignore other level limits */ -+#define WL_TXPWR_OVERRIDE (1U<<31) -+#define WL_TXPWR_NEG (1U<<30) -+ -+#define WL_PHY_PAVARS_LEN 32 /* Phy type, Band range, chain, a1[0], b0[0], b1[0] ... */ -+ -+#define WL_PHY_PAVARS2_NUM 3 /* a1, b0, b1 */ -+#define WL_PHY_PAVAR_VER 1 /* pavars version */ -+typedef struct wl_pavars2 { -+ uint16 ver; /* version of this struct */ -+ uint16 len; /* len of this structure */ -+ uint16 inuse; /* driver return 1 for a1,b0,b1 in current band range */ -+ uint16 phy_type; /* phy type */ -+ uint16 bandrange; -+ uint16 chain; -+ uint16 inpa[WL_PHY_PAVARS2_NUM]; /* phy pavars for one band range */ -+} wl_pavars2_t; -+ -+typedef struct wl_po { -+ uint16 phy_type; /* Phy type */ -+ uint16 band; -+ uint16 cckpo; -+ uint32 ofdmpo; -+ uint16 mcspo[8]; -+} wl_po_t; -+ -+/* a large TX Power as an init value to factor out of MIN() calculations, -+ * keep low enough to fit in an int8, units are .25 dBm -+ */ -+#define WLC_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */ -+ -+/* "diag" iovar argument and error code */ -+#define WL_DIAG_INTERRUPT 1 /* d11 loopback interrupt test */ -+#define WL_DIAG_LOOPBACK 2 /* d11 loopback data test */ -+#define WL_DIAG_MEMORY 3 /* d11 memory test */ -+#define WL_DIAG_LED 4 /* LED test */ -+#define WL_DIAG_REG 5 /* d11/phy register test */ -+#define WL_DIAG_SROM 6 /* srom read/crc test */ -+#define WL_DIAG_DMA 7 /* DMA test */ -+#define WL_DIAG_LOOPBACK_EXT 8 /* enhenced d11 loopback data test */ -+ -+#define WL_DIAGERR_SUCCESS 0 -+#define WL_DIAGERR_FAIL_TO_RUN 1 /* unable to run requested diag */ -+#define WL_DIAGERR_NOT_SUPPORTED 2 /* diag requested is not supported */ -+#define WL_DIAGERR_INTERRUPT_FAIL 3 /* loopback interrupt test failed */ -+#define WL_DIAGERR_LOOPBACK_FAIL 4 /* loopback data test failed */ -+#define WL_DIAGERR_SROM_FAIL 5 /* srom read failed */ -+#define WL_DIAGERR_SROM_BADCRC 6 /* srom crc failed */ -+#define WL_DIAGERR_REG_FAIL 7 /* d11/phy register test failed */ -+#define WL_DIAGERR_MEMORY_FAIL 8 /* d11 memory test failed */ -+#define WL_DIAGERR_NOMEM 9 /* diag test failed due to no memory */ -+#define WL_DIAGERR_DMA_FAIL 10 /* DMA test failed */ -+ -+#define WL_DIAGERR_MEMORY_TIMEOUT 11 /* d11 memory test didn't finish in time */ -+#define WL_DIAGERR_MEMORY_BADPATTERN 12 /* d11 memory test result in bad pattern */ -+ -+/* band types */ -+#define WLC_BAND_AUTO 0 /* auto-select */ -+#define WLC_BAND_5G 1 /* 5 Ghz */ -+#define WLC_BAND_2G 2 /* 2.4 Ghz */ -+#define WLC_BAND_ALL 3 /* all bands */ -+ -+/* band range returned by band_range iovar */ -+#define WL_CHAN_FREQ_RANGE_2G 0 -+#define WL_CHAN_FREQ_RANGE_5GL 1 -+#define WL_CHAN_FREQ_RANGE_5GM 2 -+#define WL_CHAN_FREQ_RANGE_5GH 3 -+ -+#define WL_CHAN_FREQ_RANGE_5GLL_5BAND 4 -+#define WL_CHAN_FREQ_RANGE_5GLH_5BAND 5 -+#define WL_CHAN_FREQ_RANGE_5GML_5BAND 6 -+#define WL_CHAN_FREQ_RANGE_5GMH_5BAND 7 -+#define WL_CHAN_FREQ_RANGE_5GH_5BAND 8 -+ -+#define WL_CHAN_FREQ_RANGE_5G_BAND0 1 -+#define WL_CHAN_FREQ_RANGE_5G_BAND1 2 -+#define WL_CHAN_FREQ_RANGE_5G_BAND2 3 -+#define WL_CHAN_FREQ_RANGE_5G_BAND3 4 -+ -+#define WL_CHAN_FREQ_RANGE_5G_4BAND 5 -+ -+/* phy types (returned by WLC_GET_PHYTPE) */ -+#define WLC_PHY_TYPE_A 0 -+#define WLC_PHY_TYPE_B 1 -+#define WLC_PHY_TYPE_G 2 -+#define WLC_PHY_TYPE_N 4 -+#define WLC_PHY_TYPE_LP 5 -+#define WLC_PHY_TYPE_SSN 6 -+#define WLC_PHY_TYPE_HT 7 -+#define WLC_PHY_TYPE_LCN 8 -+#define WLC_PHY_TYPE_LCN40 10 -+#define WLC_PHY_TYPE_AC 11 -+#define WLC_PHY_TYPE_NULL 0xf -+ -+/* MAC list modes */ -+#define WLC_MACMODE_DISABLED 0 /* MAC list disabled */ -+#define WLC_MACMODE_DENY 1 /* Deny specified (i.e. allow unspecified) */ -+#define WLC_MACMODE_ALLOW 2 /* Allow specified (i.e. deny unspecified) */ -+ -+/* -+ * 54g modes (basic bits may still be overridden) -+ * -+ * GMODE_LEGACY_B Rateset: 1b, 2b, 5.5, 11 -+ * Preamble: Long -+ * Shortslot: Off -+ * GMODE_AUTO Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 -+ * Extended Rateset: 6, 9, 12, 48 -+ * Preamble: Long -+ * Shortslot: Auto -+ * GMODE_ONLY Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54 -+ * Extended Rateset: 6b, 9, 12b, 48 -+ * Preamble: Short required -+ * Shortslot: Auto -+ * GMODE_B_DEFERRED Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 -+ * Extended Rateset: 6, 9, 12, 48 -+ * Preamble: Long -+ * Shortslot: On -+ * GMODE_PERFORMANCE Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54 -+ * Preamble: Short required -+ * Shortslot: On and required -+ * GMODE_LRS Rateset: 1b, 2b, 5.5b, 11b -+ * Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54 -+ * Preamble: Long -+ * Shortslot: Auto -+ */ -+#define GMODE_LEGACY_B 0 -+#define GMODE_AUTO 1 -+#define GMODE_ONLY 2 -+#define GMODE_B_DEFERRED 3 -+#define GMODE_PERFORMANCE 4 -+#define GMODE_LRS 5 -+#define GMODE_MAX 6 -+ -+/* values for PLCPHdr_override */ -+#define WLC_PLCP_AUTO -1 -+#define WLC_PLCP_SHORT 0 -+#define WLC_PLCP_LONG 1 -+ -+/* values for g_protection_override and n_protection_override */ -+#define WLC_PROTECTION_AUTO -1 -+#define WLC_PROTECTION_OFF 0 -+#define WLC_PROTECTION_ON 1 -+#define WLC_PROTECTION_MMHDR_ONLY 2 -+#define WLC_PROTECTION_CTS_ONLY 3 -+ -+/* values for g_protection_control and n_protection_control */ -+#define WLC_PROTECTION_CTL_OFF 0 -+#define WLC_PROTECTION_CTL_LOCAL 1 -+#define WLC_PROTECTION_CTL_OVERLAP 2 -+ -+/* values for n_protection */ -+#define WLC_N_PROTECTION_OFF 0 -+#define WLC_N_PROTECTION_OPTIONAL 1 -+#define WLC_N_PROTECTION_20IN40 2 -+#define WLC_N_PROTECTION_MIXEDMODE 3 -+ -+/* values for n_preamble_type */ -+#define WLC_N_PREAMBLE_MIXEDMODE 0 -+#define WLC_N_PREAMBLE_GF 1 -+#define WLC_N_PREAMBLE_GF_BRCM 2 -+ -+/* values for band specific 40MHz capabilities (deprecated) */ -+#define WLC_N_BW_20ALL 0 -+#define WLC_N_BW_40ALL 1 -+#define WLC_N_BW_20IN2G_40IN5G 2 -+ -+#define WLC_BW_20MHZ_BIT (1<<0) -+#define WLC_BW_40MHZ_BIT (1<<1) -+#define WLC_BW_80MHZ_BIT (1<<2) -+ -+/* Bandwidth capabilities */ -+#define WLC_BW_CAP_20MHZ (WLC_BW_20MHZ_BIT) -+#define WLC_BW_CAP_40MHZ (WLC_BW_40MHZ_BIT|WLC_BW_20MHZ_BIT) -+#define WLC_BW_CAP_80MHZ (WLC_BW_80MHZ_BIT|WLC_BW_40MHZ_BIT|WLC_BW_20MHZ_BIT) -+#define WLC_BW_CAP_UNRESTRICTED 0xFF -+ -+#define WL_BW_CAP_20MHZ(bw_cap) (((bw_cap) & WLC_BW_20MHZ_BIT) ? TRUE : FALSE) -+#define WL_BW_CAP_40MHZ(bw_cap) (((bw_cap) & WLC_BW_40MHZ_BIT) ? TRUE : FALSE) -+#define WL_BW_CAP_80MHZ(bw_cap) (((bw_cap) & WLC_BW_80MHZ_BIT) ? TRUE : FALSE) -+ -+/* values to force tx/rx chain */ -+#define WLC_N_TXRX_CHAIN0 0 -+#define WLC_N_TXRX_CHAIN1 1 -+ -+/* bitflags for SGI support (sgi_rx iovar) */ -+#define WLC_N_SGI_20 0x01 -+#define WLC_N_SGI_40 0x02 -+ -+/* when sgi_tx==WLC_SGI_ALL, bypass rate selection, enable sgi for all mcs */ -+#define WLC_SGI_ALL 0x02 -+ -+/* Values for PM */ -+#define PM_OFF 0 -+#define PM_MAX 1 -+#define PM_FAST 2 -+#define PM_FORCE_OFF 3 /* use this bit to force PM off even bt is active */ -+ -+#define LISTEN_INTERVAL 10 -+/* interference mitigation options */ -+#define INTERFERE_OVRRIDE_OFF -1 /* interference override off */ -+#define INTERFERE_NONE 0 /* off */ -+#define NON_WLAN 1 /* foreign/non 802.11 interference, no auto detect */ -+#define WLAN_MANUAL 2 /* ACI: no auto detection */ -+#define WLAN_AUTO 3 /* ACI: auto detect */ -+#define WLAN_AUTO_W_NOISE 4 /* ACI: auto - detect and non 802.11 interference */ -+#define AUTO_ACTIVE (1 << 7) /* Auto is currently active */ -+ -+typedef struct wl_aci_args { -+ int enter_aci_thresh; /* Trigger level to start detecting ACI */ -+ int exit_aci_thresh; /* Trigger level to exit ACI mode */ -+ int usec_spin; /* microsecs to delay between rssi samples */ -+ int glitch_delay; /* interval between ACI scans when glitch count is consistently high */ -+ uint16 nphy_adcpwr_enter_thresh; /* ADC power to enter ACI mitigation mode */ -+ uint16 nphy_adcpwr_exit_thresh; /* ADC power to exit ACI mitigation mode */ -+ uint16 nphy_repeat_ctr; /* Number of tries per channel to compute power */ -+ uint16 nphy_num_samples; /* Number of samples to compute power on one channel */ -+ uint16 nphy_undetect_window_sz; /* num of undetects to exit ACI Mitigation mode */ -+ uint16 nphy_b_energy_lo_aci; /* low ACI power energy threshold for bphy */ -+ uint16 nphy_b_energy_md_aci; /* mid ACI power energy threshold for bphy */ -+ uint16 nphy_b_energy_hi_aci; /* high ACI power energy threshold for bphy */ -+ uint16 nphy_noise_noassoc_glitch_th_up; /* wl interference 4 */ -+ uint16 nphy_noise_noassoc_glitch_th_dn; -+ uint16 nphy_noise_assoc_glitch_th_up; -+ uint16 nphy_noise_assoc_glitch_th_dn; -+ uint16 nphy_noise_assoc_aci_glitch_th_up; -+ uint16 nphy_noise_assoc_aci_glitch_th_dn; -+ uint16 nphy_noise_assoc_enter_th; -+ uint16 nphy_noise_noassoc_enter_th; -+ uint16 nphy_noise_assoc_rx_glitch_badplcp_enter_th; -+ uint16 nphy_noise_noassoc_crsidx_incr; -+ uint16 nphy_noise_assoc_crsidx_incr; -+ uint16 nphy_noise_crsidx_decr; -+} wl_aci_args_t; -+ -+#define TRIGGER_NOW 0 -+#define TRIGGER_CRS 0x01 -+#define TRIGGER_CRSDEASSERT 0x02 -+#define TRIGGER_GOODFCS 0x04 -+#define TRIGGER_BADFCS 0x08 -+#define TRIGGER_BADPLCP 0x10 -+#define TRIGGER_CRSGLITCH 0x20 -+#define WL_ACI_ARGS_LEGACY_LENGTH 16 /* bytes of pre NPHY aci args */ -+#define WL_SAMPLECOLLECT_T_VERSION 2 /* version of wl_samplecollect_args_t struct */ -+typedef struct wl_samplecollect_args { -+ /* version 0 fields */ -+ uint8 coll_us; -+ int cores; -+ /* add'l version 1 fields */ -+ uint16 version; /* see definition of WL_SAMPLECOLLECT_T_VERSION */ -+ uint16 length; /* length of entire structure */ -+ int8 trigger; -+ uint16 timeout; -+ uint16 mode; -+ uint32 pre_dur; -+ uint32 post_dur; -+ uint8 gpio_sel; -+ bool downsamp; -+ bool be_deaf; -+ bool agc; /* loop from init gain and going down */ -+ bool filter; /* override high pass corners to lowest */ -+ /* add'l version 2 fields */ -+ uint8 trigger_state; -+ uint8 module_sel1; -+ uint8 module_sel2; -+ uint16 nsamps; -+} wl_samplecollect_args_t; -+ -+#define WL_SAMPLEDATA_HEADER_TYPE 1 -+#define WL_SAMPLEDATA_HEADER_SIZE 80 /* sample collect header size (bytes) */ -+#define WL_SAMPLEDATA_TYPE 2 -+#define WL_SAMPLEDATA_SEQ 0xff /* sequence # */ -+#define WL_SAMPLEDATA_MORE_DATA 0x100 /* more data mask */ -+#define WL_SAMPLEDATA_T_VERSION 1 /* version of wl_samplecollect_args_t struct */ -+/* version for unpacked sample data, int16 {(I,Q),Core(0..N)} */ -+#define WL_SAMPLEDATA_T_VERSION_SPEC_AN 2 -+ -+typedef struct wl_sampledata { -+ uint16 version; /* structure version */ -+ uint16 size; /* size of structure */ -+ uint16 tag; /* Header/Data */ -+ uint16 length; /* data length */ -+ uint32 flag; /* bit def */ -+} wl_sampledata_t; -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+/* wl_radar_args_t */ -+typedef struct { -+ int npulses; /* required number of pulses at n * t_int */ -+ int ncontig; /* required number of pulses at t_int */ -+ int min_pw; /* minimum pulse width (20 MHz clocks) */ -+ int max_pw; /* maximum pulse width (20 MHz clocks) */ -+ uint16 thresh0; /* Radar detection, thresh 0 */ -+ uint16 thresh1; /* Radar detection, thresh 1 */ -+ uint16 blank; /* Radar detection, blank control */ -+ uint16 fmdemodcfg; /* Radar detection, fmdemod config */ -+ int npulses_lp; /* Radar detection, minimum long pulses */ -+ int min_pw_lp; /* Minimum pulsewidth for long pulses */ -+ int max_pw_lp; /* Maximum pulsewidth for long pulses */ -+ int min_fm_lp; /* Minimum fm for long pulses */ -+ int max_span_lp; /* Maximum deltat for long pulses */ -+ int min_deltat; /* Minimum spacing between pulses */ -+ int max_deltat; /* Maximum spacing between pulses */ -+ uint16 autocorr; /* Radar detection, autocorr on or off */ -+ uint16 st_level_time; /* Radar detection, start_timing level */ -+ uint16 t2_min; /* minimum clocks needed to remain in state 2 */ -+ uint32 version; /* version */ -+ uint32 fra_pulse_err; /* sample error margin for detecting French radar pulsed */ -+ int npulses_fra; /* Radar detection, minimum French pulses set */ -+ int npulses_stg2; /* Radar detection, minimum staggered-2 pulses set */ -+ int npulses_stg3; /* Radar detection, minimum staggered-3 pulses set */ -+ uint16 percal_mask; /* defines which period cal is masked from radar detection */ -+ int quant; /* quantization resolution to pulse positions */ -+ uint32 min_burst_intv_lp; /* minimum burst to burst interval for bin3 radar */ -+ uint32 max_burst_intv_lp; /* maximum burst to burst interval for bin3 radar */ -+ int nskip_rst_lp; /* number of skipped pulses before resetting lp buffer */ -+ int max_pw_tol; /* maximum tollerance allowed in detected pulse width for radar detection */ -+ uint16 feature_mask; /* 16-bit mask to specify enabled features */ -+} wl_radar_args_t; -+ -+#define WL_RADAR_ARGS_VERSION 2 -+ -+typedef struct { -+ uint32 version; /* version */ -+ uint16 thresh0_20_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 20MHz */ -+ uint16 thresh1_20_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 20MHz */ -+ uint16 thresh0_40_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 40MHz */ -+ uint16 thresh1_40_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 40MHz */ -+ uint16 thresh0_80_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 80MHz */ -+ uint16 thresh1_80_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 80MHz */ -+ uint16 thresh0_160_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 160MHz */ -+ uint16 thresh1_160_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 160MHz */ -+ uint16 thresh0_20_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 20MHz */ -+ uint16 thresh1_20_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 20MHz */ -+ uint16 thresh0_40_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 40MHz */ -+ uint16 thresh1_40_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 40MHz */ -+ uint16 thresh0_80_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 80MHz */ -+ uint16 thresh1_80_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 80MHz */ -+ uint16 thresh0_160_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 160MHz */ -+ uint16 thresh1_160_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 160MHz */ -+} wl_radar_thr_t; -+ -+#define WL_RADAR_THR_VERSION 2 -+#define WL_THRESHOLD_LO_BAND 70 /* range from 5250MHz - 5350MHz */ -+ -+/* radar iovar SET defines */ -+#define WL_RADAR_DETECTOR_OFF 0 /* radar detector off */ -+#define WL_RADAR_DETECTOR_ON 1 /* radar detector on */ -+#define WL_RADAR_SIMULATED 2 /* force radar detector to declare -+ * detection once -+ */ -+#define WL_RSSI_ANT_VERSION 1 /* current version of wl_rssi_ant_t */ -+#define WL_ANT_RX_MAX 2 /* max 2 receive antennas */ -+#define WL_ANT_HT_RX_MAX 3 /* max 3 receive antennas/cores */ -+#define WL_ANT_IDX_1 0 /* antenna index 1 */ -+#define WL_ANT_IDX_2 1 /* antenna index 2 */ -+ -+#ifndef WL_RSSI_ANT_MAX -+#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */ -+#elif WL_RSSI_ANT_MAX != 4 -+#error "WL_RSSI_ANT_MAX does not match" -+#endif -+ -+/* RSSI per antenna */ -+typedef struct { -+ uint32 version; /* version field */ -+ uint32 count; /* number of valid antenna rssi */ -+ int8 rssi_ant[WL_RSSI_ANT_MAX]; /* rssi per antenna */ -+} wl_rssi_ant_t; -+ -+/* dfs_status iovar-related defines */ -+ -+/* cac - channel availability check, -+ * ism - in-service monitoring -+ * csa - channel switching announcement -+ */ -+ -+/* cac state values */ -+#define WL_DFS_CACSTATE_IDLE 0 /* state for operating in non-radar channel */ -+#define WL_DFS_CACSTATE_PREISM_CAC 1 /* CAC in progress */ -+#define WL_DFS_CACSTATE_ISM 2 /* ISM in progress */ -+#define WL_DFS_CACSTATE_CSA 3 /* csa */ -+#define WL_DFS_CACSTATE_POSTISM_CAC 4 /* ISM CAC */ -+#define WL_DFS_CACSTATE_PREISM_OOC 5 /* PREISM OOC */ -+#define WL_DFS_CACSTATE_POSTISM_OOC 6 /* POSTISM OOC */ -+#define WL_DFS_CACSTATES 7 /* this many states exist */ -+ -+/* data structure used in 'dfs_status' wl interface, which is used to query dfs status */ -+typedef struct { -+ uint state; /* noted by WL_DFS_CACSTATE_XX. */ -+ uint duration; /* time spent in ms in state. */ -+ /* as dfs enters ISM state, it removes the operational channel from quiet channel -+ * list and notes the channel in channel_cleared. set to 0 if no channel is cleared -+ */ -+ chanspec_t chanspec_cleared; -+ /* chanspec cleared used to be a uint, add another to uint16 to maintain size */ -+ uint16 pad; -+} wl_dfs_status_t; -+ -+#define NUM_PWRCTRL_RATES 12 -+ -+typedef struct { -+ uint8 txpwr_band_max[NUM_PWRCTRL_RATES]; /* User set target */ -+ uint8 txpwr_limit[NUM_PWRCTRL_RATES]; /* reg and local power limit */ -+ uint8 txpwr_local_max; /* local max according to the AP */ -+ uint8 txpwr_local_constraint; /* local constraint according to the AP */ -+ uint8 txpwr_chan_reg_max; /* Regulatory max for this channel */ -+ uint8 txpwr_target[2][NUM_PWRCTRL_RATES]; /* Latest target for 2.4 and 5 Ghz */ -+ uint8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */ -+ uint8 txpwr_opo[NUM_PWRCTRL_RATES]; /* On G phy, OFDM power offset */ -+ uint8 txpwr_bphy_cck_max[NUM_PWRCTRL_RATES]; /* Max CCK power for this band (SROM) */ -+ uint8 txpwr_bphy_ofdm_max; /* Max OFDM power for this band (SROM) */ -+ uint8 txpwr_aphy_max[NUM_PWRCTRL_RATES]; /* Max power for A band (SROM) */ -+ int8 txpwr_antgain[2]; /* Ant gain for each band - from SROM */ -+ uint8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */ -+} tx_power_legacy_t; -+ -+#define WL_TX_POWER_RATES_LEGACY 45 -+#define WL_TX_POWER_MCS20_FIRST 12 -+#define WL_TX_POWER_MCS20_NUM 16 -+#define WL_TX_POWER_MCS40_FIRST 28 -+#define WL_TX_POWER_MCS40_NUM 17 -+ -+typedef struct { -+ uint32 flags; -+ chanspec_t chanspec; /* txpwr report for this channel */ -+ chanspec_t local_chanspec; /* channel on which we are associated */ -+ uint8 local_max; /* local max according to the AP */ -+ uint8 local_constraint; /* local constraint according to the AP */ -+ int8 antgain[2]; /* Ant gain for each band - from SROM */ -+ uint8 rf_cores; /* count of RF Cores being reported */ -+ uint8 est_Pout[4]; /* Latest tx power out estimate per RF -+ * chain without adjustment -+ */ -+ uint8 est_Pout_cck; /* Latest CCK tx power out estimate */ -+ uint8 user_limit[WL_TX_POWER_RATES_LEGACY]; /* User limit */ -+ uint8 reg_limit[WL_TX_POWER_RATES_LEGACY]; /* Regulatory power limit */ -+ uint8 board_limit[WL_TX_POWER_RATES_LEGACY]; /* Max power board can support (SROM) */ -+ uint8 target[WL_TX_POWER_RATES_LEGACY]; /* Latest target power */ -+} tx_power_legacy2_t; -+ -+/* TX Power index defines */ -+#define WL_NUM_RATES_CCK 4 /* 1, 2, 5.5, 11 Mbps */ -+#define WL_NUM_RATES_OFDM 8 /* 6, 9, 12, 18, 24, 36, 48, 54 Mbps SISO/CDD */ -+#define WL_NUM_RATES_MCS_1STREAM 8 /* MCS 0-7 1-stream rates - SISO/CDD/STBC/MCS */ -+#define WL_NUM_RATES_EXTRA_VHT 2 /* Additional VHT 11AC rates */ -+#define WL_NUM_RATES_VHT 10 -+#define WL_NUM_RATES_MCS32 1 -+ -+#define WLC_NUM_RATES_CCK WL_NUM_RATES_CCK -+#define WLC_NUM_RATES_OFDM WL_NUM_RATES_OFDM -+#define WLC_NUM_RATES_MCS_1_STREAM WL_NUM_RATES_MCS_1STREAM -+#define WLC_NUM_RATES_MCS_2_STREAM WL_NUM_RATES_MCS_1STREAM -+#define WLC_NUM_RATES_MCS32 WL_NUM_RATES_MCS32 -+#define WL_TX_POWER_CCK_NUM WL_NUM_RATES_CCK -+#define WL_TX_POWER_OFDM_NUM WL_NUM_RATES_OFDM -+#define WL_TX_POWER_MCS_1_STREAM_NUM WL_NUM_RATES_MCS_1STREAM -+#define WL_TX_POWER_MCS_2_STREAM_NUM WL_NUM_RATES_MCS_1STREAM -+#define WL_TX_POWER_MCS_32_NUM WL_NUM_RATES_MCS32 -+ -+#define WL_NUM_2x2_ELEMENTS 4 -+#define WL_NUM_3x3_ELEMENTS 6 -+ -+typedef struct txppr { -+ /* start of 20MHz tx power limits */ -+ uint8 b20_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ -+ uint8 b20_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ -+ -+ uint8 b20_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b20_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ -+ uint8 b20_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b20_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ -+ -+ uint8 b20_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b20_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ -+ uint8 b20_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b20_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ -+ uint8 b20_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ -+ -+ uint8 b20_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ -+ uint8 b20_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ -+ uint8 b20_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ -+ uint8 b20_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ -+ uint8 b20_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ -+ uint8 b20_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ -+ uint8 b20_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ -+ uint8 b20_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ -+ -+ /* start of 40MHz tx power limits */ -+ uint8 b40_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b40_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ -+ uint8 b40_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ -+ -+ uint8 b40_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b40_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b40_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ -+ uint8 b40_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b40_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ -+ -+ uint8 b40_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b40_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b40_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ -+ uint8 b40_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b40_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ -+ uint8 b40_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ -+ -+ uint8 b40_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ -+ uint8 b40_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ -+ uint8 b40_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ -+ uint8 b40_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ -+ uint8 b40_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ -+ uint8 b40_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ -+ uint8 b40_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ -+ uint8 b40_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ -+ -+ /* start of 20in40MHz tx power limits */ -+ uint8 b20in40_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20in40_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ -+ uint8 b20in40_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ -+ -+ uint8 b20in40_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20in40_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b20in40_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ -+ uint8 b20in40_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b20in40_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ -+ -+ uint8 b20in40_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20in40_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* 20 in 40 MHz Legacy OFDM CDD */ -+ uint8 b20in40_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ -+ uint8 b20in40_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b20in40_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ -+ uint8 b20in40_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ -+ -+ uint8 b20in40_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ -+ uint8 b20in40_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ -+ uint8 b20in40_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ -+ uint8 b20in40_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ -+ uint8 b20in40_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ -+ uint8 b20in40_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ -+ uint8 b20in40_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ -+ uint8 b20in40_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ -+ -+ /* start of 80MHz tx power limits */ -+ uint8 b80_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ -+ uint8 b80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ -+ -+ uint8 b80_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ -+ uint8 b80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ -+ -+ uint8 b80_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ -+ uint8 b80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ -+ uint8 b80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ -+ -+ uint8 b80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ -+ uint8 b80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ -+ uint8 b80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ -+ uint8 b80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ -+ uint8 b80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ -+ uint8 b80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ -+ uint8 b80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ -+ uint8 b80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ -+ -+ /* start of 20in80MHz tx power limits */ -+ uint8 b20in80_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20in80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ -+ uint8 b20in80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ -+ -+ uint8 b20in80_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20in80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b20in80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ -+ uint8 b20in80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b20in80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ -+ -+ uint8 b20in80_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b20in80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b20in80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ -+ uint8 b20in80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b20in80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ -+ uint8 b20in80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ -+ -+ uint8 b20in80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ -+ uint8 b20in80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ -+ uint8 b20in80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ -+ uint8 b20in80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ -+ uint8 b20in80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ -+ uint8 b20in80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ -+ uint8 b20in80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ -+ uint8 b20in80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ -+ -+ /* start of 40in80MHz tx power limits */ -+ uint8 b40in80_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b40in80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */ -+ uint8 b40in80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */ -+ -+ uint8 b40in80_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b40in80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */ -+ uint8 b40in80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */ -+ uint8 b40in80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b40in80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */ -+ -+ uint8 b40in80_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */ -+ uint8 b40in80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* MHz Legacy OFDM CDD */ -+ uint8 b40in80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */ -+ uint8 b40in80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */ -+ uint8 b40in80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */ -+ uint8 b40in80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */ -+ -+ uint8 b40in80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */ -+ uint8 b40in80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */ -+ uint8 b40in80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */ -+ uint8 b40in80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */ -+ uint8 b40in80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */ -+ uint8 b40in80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */ -+ uint8 b40in80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */ -+ uint8 b40in80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */ -+ -+ uint8 mcs32; /* C_CHECK - THIS NEEDS TO BE REMOVED THROUGHOUT THE CODE */ -+} txppr_t; -+ -+/* 20MHz */ -+#define WL_TX_POWER_CCK_FIRST OFFSETOF(txppr_t, b20_1x1dsss) -+#define WL_TX_POWER_OFDM20_FIRST OFFSETOF(txppr_t, b20_1x1ofdm) -+#define WL_TX_POWER_MCS20_SISO_FIRST OFFSETOF(txppr_t, b20_1x1mcs0) -+#define WL_TX_POWER_20_S1x1_FIRST OFFSETOF(txppr_t, b20_1x1mcs0) -+ -+#define WL_TX_POWER_CCK_CDD_S1x2_FIRST OFFSETOF(txppr_t, b20_1x2dsss) -+#define WL_TX_POWER_OFDM20_CDD_FIRST OFFSETOF(txppr_t, b20_1x2cdd_ofdm) -+#define WL_TX_POWER_MCS20_CDD_FIRST OFFSETOF(txppr_t, b20_1x2cdd_mcs0) -+#define WL_TX_POWER_20_S1x2_FIRST OFFSETOF(txppr_t, b20_1x2cdd_mcs0) -+#define WL_TX_POWER_MCS20_STBC_FIRST OFFSETOF(txppr_t, b20_2x2stbc_mcs0) -+#define WL_TX_POWER_MCS20_SDM_FIRST OFFSETOF(txppr_t, b20_2x2sdm_mcs8) -+#define WL_TX_POWER_20_S2x2_FIRST OFFSETOF(txppr_t, b20_2x2sdm_mcs8) -+ -+#define WL_TX_POWER_CCK_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20_1x3dsss) -+#define WL_TX_POWER_OFDM20_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20_1x3cdd_ofdm) -+#define WL_TX_POWER_20_S1x3_FIRST OFFSETOF(txppr_t, b20_1x3cdd_mcs0) -+#define WL_TX_POWER_20_STBC_S2x3_FIRST OFFSETOF(txppr_t, b20_2x3stbc_mcs0) -+#define WL_TX_POWER_20_S2x3_FIRST OFFSETOF(txppr_t, b20_2x3sdm_mcs8) -+#define WL_TX_POWER_20_S3x3_FIRST OFFSETOF(txppr_t, b20_3x3sdm_mcs16) -+ -+#define WL_TX_POWER_20_S1X1_VHT OFFSETOF(txppr_t, b20_1x1vht) -+#define WL_TX_POWER_20_S1X2_CDD_VHT OFFSETOF(txppr_t, b20_1x2cdd_vht) -+#define WL_TX_POWER_20_S2X2_STBC_VHT OFFSETOF(txppr_t, b20_2x2stbc_vht) -+#define WL_TX_POWER_20_S2X2_VHT OFFSETOF(txppr_t, b20_2x2sdm_vht) -+#define WL_TX_POWER_20_S1X3_CDD_VHT OFFSETOF(txppr_t, b20_1x3cdd_vht) -+#define WL_TX_POWER_20_S2X3_STBC_VHT OFFSETOF(txppr_t, b20_2x3stbc_vht) -+#define WL_TX_POWER_20_S2X3_VHT OFFSETOF(txppr_t, b20_2x3sdm_vht) -+#define WL_TX_POWER_20_S3X3_VHT OFFSETOF(txppr_t, b20_3x3sdm_vht) -+ -+/* 40MHz */ -+#define WL_TX_POWER_40_DUMMY_CCK_FIRST OFFSETOF(txppr_t, b40_dummy1x1dsss) -+#define WL_TX_POWER_OFDM40_FIRST OFFSETOF(txppr_t, b40_1x1ofdm) -+#define WL_TX_POWER_MCS40_SISO_FIRST OFFSETOF(txppr_t, b40_1x1mcs0) -+#define WL_TX_POWER_40_S1x1_FIRST OFFSETOF(txppr_t, b40_1x1mcs0) -+ -+#define WL_TX_POWER_40_DUMMY_CCK_CDD_S1x2_FIRST OFFSETOF(txppr_t, b40_dummy1x2dsss) -+#define WL_TX_POWER_OFDM40_CDD_FIRST OFFSETOF(txppr_t, b40_1x2cdd_ofdm) -+#define WL_TX_POWER_MCS40_CDD_FIRST OFFSETOF(txppr_t, b40_1x2cdd_mcs0) -+#define WL_TX_POWER_40_S1x2_FIRST OFFSETOF(txppr_t, b40_1x2cdd_mcs0) -+#define WL_TX_POWER_MCS40_STBC_FIRST OFFSETOF(txppr_t, b40_2x2stbc_mcs0) -+#define WL_TX_POWER_MCS40_SDM_FIRST OFFSETOF(txppr_t, b40_2x2sdm_mcs8) -+#define WL_TX_POWER_40_S2x2_FIRST OFFSETOF(txppr_t, b40_2x2sdm_mcs8) -+ -+#define WL_TX_POWER_40_DUMMY_CCK_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40_dummy1x3dsss) -+#define WL_TX_POWER_OFDM40_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40_1x3cdd_ofdm) -+#define WL_TX_POWER_40_S1x3_FIRST OFFSETOF(txppr_t, b40_1x3cdd_mcs0) -+#define WL_TX_POWER_40_STBC_S2x3_FIRST OFFSETOF(txppr_t, b40_2x3stbc_mcs0) -+#define WL_TX_POWER_40_S2x3_FIRST OFFSETOF(txppr_t, b40_2x3sdm_mcs8) -+#define WL_TX_POWER_40_S3x3_FIRST OFFSETOF(txppr_t, b40_3x3sdm_mcs16) -+ -+#define WL_TX_POWER_40_S1X1_VHT OFFSETOF(txppr_t, b40_1x1vht) -+#define WL_TX_POWER_40_S1X2_CDD_VHT OFFSETOF(txppr_t, b40_1x2cdd_vht) -+#define WL_TX_POWER_40_S2X2_STBC_VHT OFFSETOF(txppr_t, b40_2x2stbc_vht) -+#define WL_TX_POWER_40_S2X2_VHT OFFSETOF(txppr_t, b40_2x2sdm_vht) -+#define WL_TX_POWER_40_S1X3_CDD_VHT OFFSETOF(txppr_t, b40_1x3cdd_vht) -+#define WL_TX_POWER_40_S2X3_STBC_VHT OFFSETOF(txppr_t, b40_2x3stbc_vht) -+#define WL_TX_POWER_40_S2X3_VHT OFFSETOF(txppr_t, b40_2x3sdm_vht) -+#define WL_TX_POWER_40_S3X3_VHT OFFSETOF(txppr_t, b40_3x3sdm_vht) -+ -+/* 20 in 40MHz */ -+#define WL_TX_POWER_20UL_CCK_FIRST OFFSETOF(txppr_t, b20in40_1x1dsss) -+#define WL_TX_POWER_20UL_OFDM_FIRST OFFSETOF(txppr_t, b20in40_1x1ofdm) -+#define WL_TX_POWER_20UL_S1x1_FIRST OFFSETOF(txppr_t, b20in40_1x1mcs0) -+ -+#define WL_TX_POWER_CCK_20U_CDD_S1x2_FIRST OFFSETOF(txppr_t, b20in40_1x2dsss) -+#define WL_TX_POWER_20UL_OFDM_CDD_FIRST OFFSETOF(txppr_t, b20in40_1x2cdd_ofdm) -+#define WL_TX_POWER_20UL_S1x2_FIRST OFFSETOF(txppr_t, b20in40_1x2cdd_mcs0) -+#define WL_TX_POWER_20UL_STBC_S2x2_FIRST OFFSETOF(txppr_t, b20in40_2x2stbc_mcs0) -+#define WL_TX_POWER_20UL_S2x2_FIRST OFFSETOF(txppr_t, b20in40_2x2sdm_mcs8) -+ -+#define WL_TX_POWER_CCK_20U_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in40_1x3dsss) -+#define WL_TX_POWER_20UL_OFDM_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in40_1x3cdd_ofdm) -+#define WL_TX_POWER_20UL_S1x3_FIRST OFFSETOF(txppr_t, b20in40_1x3cdd_mcs0) -+#define WL_TX_POWER_20UL_STBC_S2x3_FIRST OFFSETOF(txppr_t, b20in40_2x3stbc_mcs0) -+#define WL_TX_POWER_20UL_S2x3_FIRST OFFSETOF(txppr_t, b20in40_2x3sdm_mcs8) -+#define WL_TX_POWER_20UL_S3x3_FIRST OFFSETOF(txppr_t, b20in40_3x3sdm_mcs16) -+ -+#define WL_TX_POWER_20UL_S1X1_VHT OFFSETOF(txppr_t, b20in40_1x1vht) -+#define WL_TX_POWER_20UL_S1X2_CDD_VHT OFFSETOF(txppr_t, b20in40_1x2cdd_vht) -+#define WL_TX_POWER_20UL_S2X2_STBC_VHT OFFSETOF(txppr_t, b20in40_2x2stbc_vht) -+#define WL_TX_POWER_20UL_S2X2_VHT OFFSETOF(txppr_t, b20in40_2x2sdm_vht) -+#define WL_TX_POWER_20UL_S1X3_CDD_VHT OFFSETOF(txppr_t, b20in40_1x3cdd_vht) -+#define WL_TX_POWER_20UL_S2X3_STBC_VHT OFFSETOF(txppr_t, b20in40_2x3stbc_vht) -+#define WL_TX_POWER_20UL_S2X3_VHT OFFSETOF(txppr_t, b20in40_2x3sdm_vht) -+#define WL_TX_POWER_20UL_S3X3_VHT OFFSETOF(txppr_t, b20in40_3x3sdm_vht) -+ -+/* 80MHz */ -+#define WL_TX_POWER_80_DUMMY_CCK_FIRST OFFSETOF(txppr_t, b80_dummy1x1dsss) -+#define WL_TX_POWER_OFDM80_FIRST OFFSETOF(txppr_t, b80_1x1ofdm) -+#define WL_TX_POWER_MCS80_SISO_FIRST OFFSETOF(txppr_t, b80_1x1mcs0) -+#define WL_TX_POWER_80_S1x1_FIRST OFFSETOF(txppr_t, b80_1x1mcs0) -+ -+#define WL_TX_POWER_80_DUMMY_CCK_CDD_S1x2_FIRST OFFSETOF(txppr_t, b80_dummy1x2dsss) -+#define WL_TX_POWER_OFDM80_CDD_FIRST OFFSETOF(txppr_t, b80_1x2cdd_ofdm) -+#define WL_TX_POWER_MCS80_CDD_FIRST OFFSETOF(txppr_t, b80_1x2cdd_mcs0) -+#define WL_TX_POWER_80_S1x2_FIRST OFFSETOF(txppr_t, b80_1x2cdd_mcs0) -+#define WL_TX_POWER_MCS80_STBC_FIRST OFFSETOF(txppr_t, b80_2x2stbc_mcs0) -+#define WL_TX_POWER_MCS80_SDM_FIRST OFFSETOF(txppr_t, b80_2x2sdm_mcs8) -+#define WL_TX_POWER_80_S2x2_FIRST OFFSETOF(txppr_t, b80_2x2sdm_mcs8) -+ -+#define WL_TX_POWER_80_DUMMY_CCK_CDD_S1x3_FIRST OFFSETOF(txppr_t, b80_dummy1x3dsss) -+#define WL_TX_POWER_OFDM80_CDD_S1x3_FIRST OFFSETOF(txppr_t, b80_1x3cdd_ofdm) -+#define WL_TX_POWER_80_S1x3_FIRST OFFSETOF(txppr_t, b80_1x3cdd_mcs0) -+#define WL_TX_POWER_80_STBC_S2x3_FIRST OFFSETOF(txppr_t, b80_2x3stbc_mcs0) -+#define WL_TX_POWER_80_S2x3_FIRST OFFSETOF(txppr_t, b80_2x3sdm_mcs8) -+#define WL_TX_POWER_80_S3x3_FIRST OFFSETOF(txppr_t, b80_3x3sdm_mcs16) -+ -+#define WL_TX_POWER_80_S1X1_VHT OFFSETOF(txppr_t, b80_1x1vht) -+#define WL_TX_POWER_80_S1X2_CDD_VHT OFFSETOF(txppr_t, b80_1x2cdd_vht) -+#define WL_TX_POWER_80_S2X2_STBC_VHT OFFSETOF(txppr_t, b80_2x2stbc_vht) -+#define WL_TX_POWER_80_S2X2_VHT OFFSETOF(txppr_t, b80_2x2sdm_vht) -+#define WL_TX_POWER_80_S1X3_CDD_VHT OFFSETOF(txppr_t, b80_1x3cdd_vht) -+#define WL_TX_POWER_80_S2X3_STBC_VHT OFFSETOF(txppr_t, b80_2x3stbc_vht) -+#define WL_TX_POWER_80_S2X3_VHT OFFSETOF(txppr_t, b80_2x3sdm_vht) -+#define WL_TX_POWER_80_S3X3_VHT OFFSETOF(txppr_t, b80_3x3sdm_vht) -+ -+/* 20 in 80MHz */ -+#define WL_TX_POWER_20UUL_CCK_FIRST OFFSETOF(txppr_t, b20in80_1x1dsss) -+#define WL_TX_POWER_20UUL_OFDM_FIRST OFFSETOF(txppr_t, b20in80_1x1ofdm) -+#define WL_TX_POWER_20UUL_S1x1_FIRST OFFSETOF(txppr_t, b20in80_1x1mcs0) -+ -+#define WL_TX_POWER_CCK_20UU_CDD_S1x2_FIRST OFFSETOF(txppr_t, b20in80_1x2dsss) -+#define WL_TX_POWER_20UUL_OFDM_CDD_FIRST OFFSETOF(txppr_t, b20in80_1x2cdd_ofdm) -+#define WL_TX_POWER_20UUL_S1x2_FIRST OFFSETOF(txppr_t, b20in80_1x2cdd_mcs0) -+#define WL_TX_POWER_20UUL_STBC_S2x2_FIRST OFFSETOF(txppr_t, b20in80_2x2stbc_mcs0) -+#define WL_TX_POWER_20UUL_S2x2_FIRST OFFSETOF(txppr_t, b20in80_2x2sdm_mcs8) -+ -+#define WL_TX_POWER_CCK_20UU_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in80_1x3dsss) -+#define WL_TX_POWER_20UUL_OFDM_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in80_1x3cdd_ofdm) -+#define WL_TX_POWER_20UUL_S1x3_FIRST OFFSETOF(txppr_t, b20in80_1x3cdd_mcs0) -+#define WL_TX_POWER_20UUL_STBC_S2x3_FIRST OFFSETOF(txppr_t, b20in80_2x3stbc_mcs0) -+#define WL_TX_POWER_20UUL_S2x3_FIRST OFFSETOF(txppr_t, b20in80_2x3sdm_mcs8) -+#define WL_TX_POWER_20UUL_S3x3_FIRST OFFSETOF(txppr_t, b20in80_3x3sdm_mcs16) -+ -+#define WL_TX_POWER_20UUL_S1X1_VHT OFFSETOF(txppr_t, b20in80_1x1vht) -+#define WL_TX_POWER_20UUL_S1X2_CDD_VHT OFFSETOF(txppr_t, b20in80_1x2cdd_vht) -+#define WL_TX_POWER_20UUL_S2X2_STBC_VHT OFFSETOF(txppr_t, b20in80_2x2stbc_vht) -+#define WL_TX_POWER_20UUL_S2X2_VHT OFFSETOF(txppr_t, b20in80_2x2sdm_vht) -+#define WL_TX_POWER_20UUL_S1X3_CDD_VHT OFFSETOF(txppr_t, b20in80_1x3cdd_vht) -+#define WL_TX_POWER_20UUL_S2X3_STBC_VHT OFFSETOF(txppr_t, b20in80_2x3stbc_vht) -+#define WL_TX_POWER_20UUL_S2X3_VHT OFFSETOF(txppr_t, b20in80_2x3sdm_vht) -+#define WL_TX_POWER_20UUL_S3X3_VHT OFFSETOF(txppr_t, b20in80_3x3sdm_vht) -+ -+/* 40 in 80MHz */ -+#define WL_TX_POWER_40UUL_DUMMY_CCK_FIRST OFFSETOF(txppr_t, b40in80_dummy1x1dsss) -+#define WL_TX_POWER_40UUL_OFDM_FIRST OFFSETOF(txppr_t, b40in80_1x1ofdm) -+#define WL_TX_POWER_40UUL_S1x1_FIRST OFFSETOF(txppr_t, b40in80_1x1mcs0) -+ -+#define WL_TX_POWER_CCK_40UU_DUMMY_CDD_S1x2_FIRST OFFSETOF(txppr_t, b40in80_dummy1x2dsss) -+#define WL_TX_POWER_40UUL_OFDM_CDD_FIRST OFFSETOF(txppr_t, b40in80_1x2cdd_ofdm) -+#define WL_TX_POWER_40UUL_S1x2_FIRST OFFSETOF(txppr_t, b40in80_1x2cdd_mcs0) -+#define WL_TX_POWER_40UUL_STBC_S2x2_FIRST OFFSETOF(txppr_t, b40in80_2x2stbc_mcs0) -+#define WL_TX_POWER_40UUL_S2x2_FIRST OFFSETOF(txppr_t, b40in80_2x2sdm_mcs8) -+ -+#define WL_TX_POWER_CCK_40UU_DUMMY_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40in80_dummy1x3dsss) -+#define WL_TX_POWER_40UUL_OFDM_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40in80_1x3cdd_ofdm) -+#define WL_TX_POWER_40UUL_S1x3_FIRST OFFSETOF(txppr_t, b40in80_1x3cdd_mcs0) -+#define WL_TX_POWER_40UUL_STBC_S2x3_FIRST OFFSETOF(txppr_t, b40in80_2x3stbc_mcs0) -+#define WL_TX_POWER_40UUL_S2x3_FIRST OFFSETOF(txppr_t, b40in80_2x3sdm_mcs8) -+#define WL_TX_POWER_40UUL_S3x3_FIRST OFFSETOF(txppr_t, b40in80_3x3sdm_mcs16) -+ -+#define WL_TX_POWER_40UUL_S1X1_VHT OFFSETOF(txppr_t, b40in80_1x1vht) -+#define WL_TX_POWER_40UUL_S1X2_CDD_VHT OFFSETOF(txppr_t, b40in80_1x2cdd_vht) -+#define WL_TX_POWER_40UUL_S2X2_STBC_VHT OFFSETOF(txppr_t, b40in80_2x2stbc_vht) -+#define WL_TX_POWER_40UUL_S2X2_VHT OFFSETOF(txppr_t, b40in80_2x2sdm_vht) -+#define WL_TX_POWER_40UUL_S1X3_CDD_VHT OFFSETOF(txppr_t, b40in80_1x3cdd_vht) -+#define WL_TX_POWER_40UUL_S2X3_STBC_VHT OFFSETOF(txppr_t, b40in80_2x3stbc_vht) -+#define WL_TX_POWER_40UUL_S2X3_VHT OFFSETOF(txppr_t, b40in80_2x3sdm_vht) -+#define WL_TX_POWER_40UUL_S3X3_VHT OFFSETOF(txppr_t, b40in80_3x3sdm_vht) -+ -+#define WL_TX_POWER_MCS_32 OFFSETOF(txppr_t, mcs32) /* C_CHECK remove later */ -+ -+#define WL_TX_POWER_RATES sizeof(struct txppr) -+ -+/* sslpnphy specifics */ -+#define WL_TX_POWER_MCS20_SISO_FIRST_SSN WL_TX_POWER_MCS20_SISO_FIRST -+#define WL_TX_POWER_MCS40_SISO_FIRST_SSN WL_TX_POWER_MCS40_SISO_FIRST -+ -+typedef struct { -+ uint16 ver; /* version of this struct */ -+ uint16 len; /* length in bytes of this structure */ -+ uint32 flags; -+ chanspec_t chanspec; /* txpwr report for this channel */ -+ chanspec_t local_chanspec; /* channel on which we are associated */ -+ uint8 ppr[WL_TX_POWER_RATES]; /* Latest target power */ -+} wl_txppr_t; -+ -+#define WL_TXPPR_VERSION 0 -+#define WL_TXPPR_LENGTH (sizeof(wl_txppr_t)) -+#define TX_POWER_T_VERSION 43 -+ -+/* Defines used with channel_bandwidth for curpower */ -+#define WL_BW_20MHZ 0 -+#define WL_BW_40MHZ 1 -+#define WL_BW_80MHZ 2 -+ -+/* tx_power_t.flags bits */ -+#ifdef PPR_API -+#define WL_TX_POWER2_F_ENABLED 1 -+#define WL_TX_POWER2_F_HW 2 -+#define WL_TX_POWER2_F_MIMO 4 -+#define WL_TX_POWER2_F_SISO 8 -+#define WL_TX_POWER2_F_HT 0x10 -+#else -+#define WL_TX_POWER_F_ENABLED 1 -+#define WL_TX_POWER_F_HW 2 -+#define WL_TX_POWER_F_MIMO 4 -+#define WL_TX_POWER_F_SISO 8 -+#define WL_TX_POWER_F_HT 0x10 -+#endif -+ -+typedef struct { -+ uint32 flags; -+ chanspec_t chanspec; /* txpwr report for this channel */ -+ chanspec_t local_chanspec; /* channel on which we are associated */ -+ uint8 local_max; /* local max according to the AP */ -+ uint8 local_constraint; /* local constraint according to the AP */ -+ int8 antgain[2]; /* Ant gain for each band - from SROM */ -+ uint8 rf_cores; /* count of RF Cores being reported */ -+ uint8 est_Pout[4]; /* Latest tx power out estimate per RF chain */ -+ uint8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain w/o adjustment */ -+ uint8 est_Pout_cck; /* Latest CCK tx power out estimate */ -+ uint8 tx_power_max[4]; /* Maximum target power among all rates */ -+ uint tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */ -+ uint8 user_limit[WL_TX_POWER_RATES]; /* User limit */ -+ int8 board_limit[WL_TX_POWER_RATES]; /* Max power board can support (SROM) */ -+ int8 target[WL_TX_POWER_RATES]; /* Latest target power */ -+ int8 clm_limits[WL_NUMRATES]; /* regulatory limits - 20, 40 or 80MHz */ -+ int8 clm_limits_subchan1[WL_NUMRATES]; /* regulatory limits - 20in40 or 40in80 */ -+ int8 clm_limits_subchan2[WL_NUMRATES]; /* regulatory limits - 20in80MHz */ -+ int8 sar; /* SAR limit for display by wl executable */ -+ int8 channel_bandwidth; /* 20, 40 or 80 MHz bandwidth? */ -+ uint8 version; /* Version of the data format wlu <--> driver */ -+ uint8 display_core; /* Displayed curpower core */ -+#ifdef PPR_API -+} tx_power_new_t; -+#else -+} tx_power_t; -+#endif -+ -+typedef struct tx_inst_power { -+ uint8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */ -+ uint8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */ -+} tx_inst_power_t; -+ -+ -+typedef struct { -+ uint32 flags; -+ chanspec_t chanspec; /* txpwr report for this channel */ -+ chanspec_t local_chanspec; /* channel on which we are associated */ -+ uint8 local_max; /* local max according to the AP */ -+ uint8 local_constraint; /* local constraint according to the AP */ -+ int8 antgain[2]; /* Ant gain for each band - from SROM */ -+ uint8 rf_cores; /* count of RF Cores being reported */ -+ uint8 est_Pout[4]; /* Latest tx power out estimate per RF chain */ -+ uint8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain -+ * without adjustment -+ */ -+ uint8 est_Pout_cck; /* Latest CCK tx power out estimate */ -+ uint8 tx_power_max[4]; /* Maximum target power among all rates */ -+ uint tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */ -+ txppr_t user_limit; /* User limit */ -+ txppr_t reg_limit; /* Regulatory power limit */ -+ txppr_t board_limit; /* Max power board can support (SROM) */ -+ txppr_t target; /* Latest target power */ -+} wl_txpwr_t; -+ -+#define WL_NUM_TXCHAIN_MAX 4 -+typedef struct wl_txchain_pwr_offsets { -+ int8 offset[WL_NUM_TXCHAIN_MAX]; /* quarter dBm signed offset for each chain */ -+} wl_txchain_pwr_offsets_t; -+ -+/* 802.11h measurement types */ -+#define WLC_MEASURE_TPC 1 -+#define WLC_MEASURE_CHANNEL_BASIC 2 -+#define WLC_MEASURE_CHANNEL_CCA 3 -+#define WLC_MEASURE_CHANNEL_RPI 4 -+ -+/* regulatory enforcement levels */ -+#define SPECT_MNGMT_OFF 0 /* both 11h and 11d disabled */ -+#define SPECT_MNGMT_LOOSE_11H 1 /* allow non-11h APs in scan lists */ -+#define SPECT_MNGMT_STRICT_11H 2 /* prune out non-11h APs from scan list */ -+#define SPECT_MNGMT_STRICT_11D 3 /* switch to 802.11D mode */ -+/* SPECT_MNGMT_LOOSE_11H_D - same as SPECT_MNGMT_LOOSE with the exception that Country IE -+ * adoption is done regardless of capability spectrum_management -+ */ -+#define SPECT_MNGMT_LOOSE_11H_D 4 /* operation defined above */ -+ -+#define WL_CHAN_VALID_HW (1 << 0) /* valid with current HW */ -+#define WL_CHAN_VALID_SW (1 << 1) /* valid with current country setting */ -+#define WL_CHAN_BAND_5G (1 << 2) /* 5GHz-band channel */ -+#define WL_CHAN_RADAR (1 << 3) /* radar sensitive channel */ -+#define WL_CHAN_INACTIVE (1 << 4) /* temporarily inactive due to radar */ -+#define WL_CHAN_PASSIVE (1 << 5) /* channel is in passive mode */ -+#define WL_CHAN_RESTRICTED (1 << 6) /* restricted use channel */ -+ -+/* BTC mode used by "btc_mode" iovar */ -+#define WL_BTC_DISABLE 0 /* disable BT coexistence */ -+#define WL_BTC_FULLTDM 1 /* full TDM COEX */ -+#define WL_BTC_ENABLE 1 /* full TDM COEX to maintain backward compatiblity */ -+#define WL_BTC_PREMPT 2 /* full TDM COEX with preemption */ -+#define WL_BTC_LITE 3 /* light weight coex for large isolation platform */ -+#define WL_BTC_PARALLEL 4 /* BT and WLAN run in parallel with separate antenna */ -+#define WL_BTC_HYBRID 5 /* hybrid coex, only ack is allowed to transmit in BT slot */ -+#define WL_BTC_DEFAULT 8 /* set the default mode for the device */ -+#define WL_INF_BTC_DISABLE 0 -+#define WL_INF_BTC_ENABLE 1 -+#define WL_INF_BTC_AUTO 3 -+ -+/* BTC wire used by "btc_wire" iovar */ -+#define WL_BTC_DEFWIRE 0 /* use default wire setting */ -+#define WL_BTC_2WIRE 2 /* use 2-wire BTC */ -+#define WL_BTC_3WIRE 3 /* use 3-wire BTC */ -+#define WL_BTC_4WIRE 4 /* use 4-wire BTC */ -+ -+/* BTC flags: BTC configuration that can be set by host */ -+#define WL_BTC_FLAG_PREMPT (1 << 0) -+#define WL_BTC_FLAG_BT_DEF (1 << 1) -+#define WL_BTC_FLAG_ACTIVE_PROT (1 << 2) -+#define WL_BTC_FLAG_SIM_RSP (1 << 3) -+#define WL_BTC_FLAG_PS_PROTECT (1 << 4) -+#define WL_BTC_FLAG_SIM_TX_LP (1 << 5) -+#define WL_BTC_FLAG_ECI (1 << 6) -+#define WL_BTC_FLAG_LIGHT (1 << 7) -+#define WL_BTC_FLAG_PARALLEL (1 << 8) -+#endif /* !defined(LINUX_POSTMOGRIFY_REMOVAL) */ -+ -+/* Message levels */ -+#define WL_ERROR_VAL 0x00000001 -+#define WL_TRACE_VAL 0x00000002 -+#define WL_PRHDRS_VAL 0x00000004 -+#define WL_PRPKT_VAL 0x00000008 -+#define WL_INFORM_VAL 0x00000010 -+#define WL_TMP_VAL 0x00000020 -+#define WL_OID_VAL 0x00000040 -+#define WL_RATE_VAL 0x00000080 -+#define WL_ASSOC_VAL 0x00000100 -+#define WL_PRUSR_VAL 0x00000200 -+#define WL_PS_VAL 0x00000400 -+#define WL_TXPWR_VAL 0x00000800 /* retired in TOT on 6/10/2009 */ -+#define WL_PORT_VAL 0x00001000 -+#define WL_DUAL_VAL 0x00002000 -+#define WL_WSEC_VAL 0x00004000 -+#define WL_WSEC_DUMP_VAL 0x00008000 -+#define WL_LOG_VAL 0x00010000 -+#define WL_NRSSI_VAL 0x00020000 /* retired in TOT on 6/10/2009 */ -+#define WL_LOFT_VAL 0x00040000 /* retired in TOT on 6/10/2009 */ -+#define WL_REGULATORY_VAL 0x00080000 -+#define WL_PHYCAL_VAL 0x00100000 /* retired in TOT on 6/10/2009 */ -+#define WL_RADAR_VAL 0x00200000 /* retired in TOT on 6/10/2009 */ -+#define WL_MPC_VAL 0x00400000 -+#define WL_APSTA_VAL 0x00800000 -+#define WL_DFS_VAL 0x01000000 -+#define WL_BA_VAL 0x02000000 /* retired in TOT on 6/14/2010 */ -+#define WL_ACI_VAL 0x04000000 -+#define WL_MBSS_VAL 0x04000000 -+#define WL_CAC_VAL 0x08000000 -+#define WL_AMSDU_VAL 0x10000000 -+#define WL_AMPDU_VAL 0x20000000 -+#define WL_FFPLD_VAL 0x40000000 -+ -+/* wl_msg_level is full. For new bits take the next one and AND with -+ * wl_msg_level2 in wl_dbg.h -+ */ -+#define WL_DPT_VAL 0x00000001 -+#define WL_SCAN_VAL 0x00000002 -+#define WL_WOWL_VAL 0x00000004 -+#define WL_COEX_VAL 0x00000008 -+#define WL_RTDC_VAL 0x00000010 -+#define WL_PROTO_VAL 0x00000020 -+#define WL_BTA_VAL 0x00000040 -+#define WL_CHANINT_VAL 0x00000080 -+#define WL_THERMAL_VAL 0x00000100 /* retired in TOT on 6/10/2009 */ -+#define WL_P2P_VAL 0x00000200 -+#define WL_ITFR_VAL 0x00000400 -+#define WL_MCHAN_VAL 0x00000800 -+#define WL_TDLS_VAL 0x00001000 -+#define WL_MCNX_VAL 0x00002000 -+#define WL_PROT_VAL 0x00004000 -+#define WL_PSTA_VAL 0x00008000 -+#define WL_TSO_VAL 0x00010000 -+/* use top-bit for WL_TIME_STAMP_VAL because this is a modifier -+ * rather than a message-type of its own -+ */ -+#define WL_TIMESTAMP_VAL 0x80000000 -+ -+/* max # of leds supported by GPIO (gpio pin# == led index#) */ -+#define WL_LED_NUMGPIO 32 /* gpio 0-31 */ -+ -+/* led per-pin behaviors */ -+#define WL_LED_OFF 0 /* always off */ -+#define WL_LED_ON 1 /* always on */ -+#define WL_LED_ACTIVITY 2 /* activity */ -+#define WL_LED_RADIO 3 /* radio enabled */ -+#define WL_LED_ARADIO 4 /* 5 Ghz radio enabled */ -+#define WL_LED_BRADIO 5 /* 2.4Ghz radio enabled */ -+#define WL_LED_BGMODE 6 /* on if gmode, off if bmode */ -+#define WL_LED_WI1 7 -+#define WL_LED_WI2 8 -+#define WL_LED_WI3 9 -+#define WL_LED_ASSOC 10 /* associated state indicator */ -+#define WL_LED_INACTIVE 11 /* null behavior (clears default behavior) */ -+#define WL_LED_ASSOCACT 12 /* on when associated; blink fast for activity */ -+#define WL_LED_WI4 13 -+#define WL_LED_WI5 14 -+#define WL_LED_BLINKSLOW 15 /* blink slow */ -+#define WL_LED_BLINKMED 16 /* blink med */ -+#define WL_LED_BLINKFAST 17 /* blink fast */ -+#define WL_LED_BLINKCUSTOM 18 /* blink custom */ -+#define WL_LED_BLINKPERIODIC 19 /* blink periodic (custom 1000ms / off 400ms) */ -+#define WL_LED_ASSOC_WITH_SEC 20 /* when connected with security */ -+ /* keep on for 300 sec */ -+#define WL_LED_START_OFF 21 /* off upon boot, could be turned on later */ -+#define WL_LED_NUMBEHAVIOR 22 -+ -+/* led behavior numeric value format */ -+#define WL_LED_BEH_MASK 0x7f /* behavior mask */ -+#define WL_LED_AL_MASK 0x80 /* activelow (polarity) bit */ -+ -+/* maximum channels returned by the get valid channels iovar */ -+#define WL_NUMCHANNELS 64 -+ -+/* max number of chanspecs (used by the iovar to calc. buf space) */ -+#define WL_NUMCHANSPECS 110 -+ -+/* WDS link local endpoint WPA role */ -+#define WL_WDS_WPA_ROLE_AUTH 0 /* authenticator */ -+#define WL_WDS_WPA_ROLE_SUP 1 /* supplicant */ -+#define WL_WDS_WPA_ROLE_AUTO 255 /* auto, based on mac addr value */ -+ -+/* number of bytes needed to define a 128-bit mask for MAC event reporting */ -+#define WL_EVENTING_MASK_LEN 16 -+ -+/* -+ * Join preference iovar value is an array of tuples. Each tuple has a one-byte type, -+ * a one-byte length, and a variable length value. RSSI type tuple must be present -+ * in the array. -+ * -+ * Types are defined in "join preference types" section. -+ * -+ * Length is the value size in octets. It is reserved for WL_JOIN_PREF_WPA type tuple -+ * and must be set to zero. -+ * -+ * Values are defined below. -+ * -+ * 1. RSSI - 2 octets -+ * offset 0: reserved -+ * offset 1: reserved -+ * -+ * 2. WPA - 2 + 12 * n octets (n is # tuples defined below) -+ * offset 0: reserved -+ * offset 1: # of tuples -+ * offset 2: tuple 1 -+ * offset 14: tuple 2 -+ * ... -+ * offset 2 + 12 * (n - 1) octets: tuple n -+ * -+ * struct wpa_cfg_tuple { -+ * uint8 akm[DOT11_OUI_LEN+1]; akm suite -+ * uint8 ucipher[DOT11_OUI_LEN+1]; unicast cipher suite -+ * uint8 mcipher[DOT11_OUI_LEN+1]; multicast cipher suite -+ * }; -+ * -+ * multicast cipher suite can be specified as a specific cipher suite or WL_WPA_ACP_MCS_ANY. -+ * -+ * 3. BAND - 2 octets -+ * offset 0: reserved -+ * offset 1: see "band preference" and "band types" -+ * -+ * 4. BAND RSSI - 2 octets -+ * offset 0: band types -+ * offset 1: +ve RSSI boost balue in dB -+ */ -+ -+/* join preference types */ -+#define WL_JOIN_PREF_RSSI 1 /* by RSSI */ -+#define WL_JOIN_PREF_WPA 2 /* by akm and ciphers */ -+#define WL_JOIN_PREF_BAND 3 /* by 802.11 band */ -+#define WL_JOIN_PREF_RSSI_DELTA 4 /* by 802.11 band only if RSSI delta condition matches */ -+#define WL_JOIN_PREF_TRANS_PREF 5 /* defined by requesting AP */ -+ -+/* band preference */ -+#define WLJP_BAND_ASSOC_PREF 255 /* use what WLC_SET_ASSOC_PREFER ioctl specifies */ -+ -+/* any multicast cipher suite */ -+#define WL_WPA_ACP_MCS_ANY "\x00\x00\x00\x00" -+ -+struct tsinfo_arg { -+ uint8 octets[3]; -+}; -+ -+#define NFIFO 6 /* # tx/rx fifopairs */ -+ -+#define WL_CNT_T_VERSION 8 /* current version of wl_cnt_t struct */ -+ -+typedef struct { -+ uint16 version; /* see definition of WL_CNT_T_VERSION */ -+ uint16 length; /* length of entire structure */ -+ -+ /* transmit stat counters */ -+ uint32 txframe; /* tx data frames */ -+ uint32 txbyte; /* tx data bytes */ -+ uint32 txretrans; /* tx mac retransmits */ -+ uint32 txerror; /* tx data errors (derived: sum of others) */ -+ uint32 txctl; /* tx management frames */ -+ uint32 txprshort; /* tx short preamble frames */ -+ uint32 txserr; /* tx status errors */ -+ uint32 txnobuf; /* tx out of buffers errors */ -+ uint32 txnoassoc; /* tx discard because we're not associated */ -+ uint32 txrunt; /* tx runt frames */ -+ uint32 txchit; /* tx header cache hit (fastpath) */ -+ uint32 txcmiss; /* tx header cache miss (slowpath) */ -+ -+ /* transmit chip error counters */ -+ uint32 txuflo; /* tx fifo underflows */ -+ uint32 txphyerr; /* tx phy errors (indicated in tx status) */ -+ uint32 txphycrs; -+ -+ /* receive stat counters */ -+ uint32 rxframe; /* rx data frames */ -+ uint32 rxbyte; /* rx data bytes */ -+ uint32 rxerror; /* rx data errors (derived: sum of others) */ -+ uint32 rxctl; /* rx management frames */ -+ uint32 rxnobuf; /* rx out of buffers errors */ -+ uint32 rxnondata; /* rx non data frames in the data channel errors */ -+ uint32 rxbadds; /* rx bad DS errors */ -+ uint32 rxbadcm; /* rx bad control or management frames */ -+ uint32 rxfragerr; /* rx fragmentation errors */ -+ uint32 rxrunt; /* rx runt frames */ -+ uint32 rxgiant; /* rx giant frames */ -+ uint32 rxnoscb; /* rx no scb error */ -+ uint32 rxbadproto; /* rx invalid frames */ -+ uint32 rxbadsrcmac; /* rx frames with Invalid Src Mac */ -+ uint32 rxbadda; /* rx frames tossed for invalid da */ -+ uint32 rxfilter; /* rx frames filtered out */ -+ -+ /* receive chip error counters */ -+ uint32 rxoflo; /* rx fifo overflow errors */ -+ uint32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ -+ -+ uint32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ -+ uint32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ -+ uint32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ -+ -+ /* misc counters */ -+ uint32 dmade; /* tx/rx dma descriptor errors */ -+ uint32 dmada; /* tx/rx dma data errors */ -+ uint32 dmape; /* tx/rx dma descriptor protocol errors */ -+ uint32 reset; /* reset count */ -+ uint32 tbtt; /* cnts the TBTT int's */ -+ uint32 txdmawar; -+ uint32 pkt_callback_reg_fail; /* callbacks register failure */ -+ -+ /* MAC counters: 32-bit version of d11.h's macstat_t */ -+ uint32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, -+ * Control Management (includes retransmissions) -+ */ -+ uint32 txrtsfrm; /* number of RTS sent out by the MAC */ -+ uint32 txctsfrm; /* number of CTS sent out by the MAC */ -+ uint32 txackfrm; /* number of ACK frames sent out */ -+ uint32 txdnlfrm; /* Not used */ -+ uint32 txbcnfrm; /* beacons transmitted */ -+ uint32 txfunfl[8]; /* per-fifo tx underflows */ -+ uint32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS -+ * or BCN) -+ */ -+ uint32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for -+ * driver enqueued frames -+ */ -+ uint32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ -+ uint32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ -+ uint32 rxinvmachdr; /* Either the protocol version != 0 or frame type not -+ * data/control/management -+ */ -+ uint32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ -+ uint32 rxbadplcp; /* parity check of the PLCP header failed */ -+ uint32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ -+ uint32 rxstrt; /* Number of received frames with a good PLCP -+ * (i.e. passing parity check) -+ */ -+ uint32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ -+ uint32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ -+ uint32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ -+ uint32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ -+ uint32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ -+ uint32 rxackucast; /* number of ucast ACKS received (good FCS) */ -+ uint32 rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ -+ uint32 rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ -+ uint32 rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ -+ uint32 rxrtsocast; /* number of received RTS not addressed to the MAC */ -+ uint32 rxctsocast; /* number of received CTS not addressed to the MAC */ -+ uint32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ -+ uint32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ -+ uint32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC -+ * (unlikely to see these) -+ */ -+ uint32 rxbeaconmbss; /* beacons received from member of BSS */ -+ uint32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from -+ * other BSS (WDS FRAME) -+ */ -+ uint32 rxbeaconobss; /* beacons received from other BSS */ -+ uint32 rxrsptmout; /* Number of response timeouts for transmitted frames -+ * expecting a response -+ */ -+ uint32 bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ -+ uint32 rxf0ovfl; /* Number of receive fifo 0 overflows */ -+ uint32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ -+ uint32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ -+ uint32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ -+ uint32 pmqovfl; /* Number of PMQ overflows */ -+ uint32 rxcgprqfrm; /* Number of received Probe requests that made it into -+ * the PRQ fifo -+ */ -+ uint32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ -+ uint32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did -+ * not get ACK -+ */ -+ uint32 txcgprssuc; /* Tx Probe Response Success (ACK was received) */ -+ uint32 prs_timeout; /* Number of probe requests that were dropped from the PRQ -+ * fifo because a probe response could not be sent out within -+ * the time limit defined in M_PRS_MAXTIME -+ */ -+ uint32 rxnack; /* obsolete */ -+ uint32 frmscons; /* obsolete */ -+ uint32 txnack; /* obsolete */ -+ uint32 txglitch_nack; /* obsolete */ -+ uint32 txburst; /* obsolete */ -+ -+ /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ -+ uint32 txfrag; /* dot11TransmittedFragmentCount */ -+ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ -+ uint32 txfail; /* dot11FailedCount */ -+ uint32 txretry; /* dot11RetryCount */ -+ uint32 txretrie; /* dot11MultipleRetryCount */ -+ uint32 rxdup; /* dot11FrameduplicateCount */ -+ uint32 txrts; /* dot11RTSSuccessCount */ -+ uint32 txnocts; /* dot11RTSFailureCount */ -+ uint32 txnoack; /* dot11ACKFailureCount */ -+ uint32 rxfrag; /* dot11ReceivedFragmentCount */ -+ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ -+ uint32 rxcrc; /* dot11FCSErrorCount */ -+ uint32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ -+ uint32 rxundec; /* dot11WEPUndecryptableCount */ -+ -+ /* WPA2 counters (see rxundec for DecryptFailureCount) */ -+ uint32 tkipmicfaill; /* TKIPLocalMICFailures */ -+ uint32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ -+ uint32 tkipreplay; /* TKIPReplays */ -+ uint32 ccmpfmterr; /* CCMPFormatErrors */ -+ uint32 ccmpreplay; /* CCMPReplays */ -+ uint32 ccmpundec; /* CCMPDecryptErrors */ -+ uint32 fourwayfail; /* FourWayHandshakeFailures */ -+ uint32 wepundec; /* dot11WEPUndecryptableCount */ -+ uint32 wepicverr; /* dot11WEPICVErrorCount */ -+ uint32 decsuccess; /* DecryptSuccessCount */ -+ uint32 tkipicverr; /* TKIPICVErrorCount */ -+ uint32 wepexcluded; /* dot11WEPExcludedCount */ -+ -+ uint32 txchanrej; /* Tx frames suppressed due to channel rejection */ -+ uint32 psmwds; /* Count PSM watchdogs */ -+ uint32 phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ -+ -+ /* MBSS counters, AP only */ -+ uint32 prq_entries_handled; /* PRQ entries read in */ -+ uint32 prq_undirected_entries; /* which were bcast bss & ssid */ -+ uint32 prq_bad_entries; /* which could not be translated to info */ -+ uint32 atim_suppress_count; /* TX suppressions on ATIM fifo */ -+ uint32 bcn_template_not_ready; /* Template marked in use on send bcn ... */ -+ uint32 bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ -+ uint32 late_tbtt_dpc; /* TBTT DPC did not happen in time */ -+ -+ /* per-rate receive stat counters */ -+ uint32 rx1mbps; /* packets rx at 1Mbps */ -+ uint32 rx2mbps; /* packets rx at 2Mbps */ -+ uint32 rx5mbps5; /* packets rx at 5.5Mbps */ -+ uint32 rx6mbps; /* packets rx at 6Mbps */ -+ uint32 rx9mbps; /* packets rx at 9Mbps */ -+ uint32 rx11mbps; /* packets rx at 11Mbps */ -+ uint32 rx12mbps; /* packets rx at 12Mbps */ -+ uint32 rx18mbps; /* packets rx at 18Mbps */ -+ uint32 rx24mbps; /* packets rx at 24Mbps */ -+ uint32 rx36mbps; /* packets rx at 36Mbps */ -+ uint32 rx48mbps; /* packets rx at 48Mbps */ -+ uint32 rx54mbps; /* packets rx at 54Mbps */ -+ uint32 rx108mbps; /* packets rx at 108mbps */ -+ uint32 rx162mbps; /* packets rx at 162mbps */ -+ uint32 rx216mbps; /* packets rx at 216 mbps */ -+ uint32 rx270mbps; /* packets rx at 270 mbps */ -+ uint32 rx324mbps; /* packets rx at 324 mbps */ -+ uint32 rx378mbps; /* packets rx at 378 mbps */ -+ uint32 rx432mbps; /* packets rx at 432 mbps */ -+ uint32 rx486mbps; /* packets rx at 486 mbps */ -+ uint32 rx540mbps; /* packets rx at 540 mbps */ -+ -+ /* pkteng rx frame stats */ -+ uint32 pktengrxducast; /* unicast frames rxed by the pkteng code */ -+ uint32 pktengrxdmcast; /* multicast frames rxed by the pkteng code */ -+ -+ uint32 rfdisable; /* count of radio disables */ -+ uint32 bphy_rxcrsglitch; /* PHY count of bphy glitches */ -+ -+ uint32 txexptime; /* Tx frames suppressed due to timer expiration */ -+ -+ uint32 txmpdu_sgi; /* count for sgi transmit */ -+ uint32 rxmpdu_sgi; /* count for sgi received */ -+ uint32 txmpdu_stbc; /* count for stbc transmit */ -+ uint32 rxmpdu_stbc; /* count for stbc received */ -+ -+ uint32 rxundec_mcst; /* dot11WEPUndecryptableCount */ -+ -+ /* WPA2 counters (see rxundec for DecryptFailureCount) */ -+ uint32 tkipmicfaill_mcst; /* TKIPLocalMICFailures */ -+ uint32 tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ -+ uint32 tkipreplay_mcst; /* TKIPReplays */ -+ uint32 ccmpfmterr_mcst; /* CCMPFormatErrors */ -+ uint32 ccmpreplay_mcst; /* CCMPReplays */ -+ uint32 ccmpundec_mcst; /* CCMPDecryptErrors */ -+ uint32 fourwayfail_mcst; /* FourWayHandshakeFailures */ -+ uint32 wepundec_mcst; /* dot11WEPUndecryptableCount */ -+ uint32 wepicverr_mcst; /* dot11WEPICVErrorCount */ -+ uint32 decsuccess_mcst; /* DecryptSuccessCount */ -+ uint32 tkipicverr_mcst; /* TKIPICVErrorCount */ -+ uint32 wepexcluded_mcst; /* dot11WEPExcludedCount */ -+ -+ uint32 dma_hang; /* count for dma hang */ -+ uint32 reinit; /* count for reinit */ -+ -+ uint32 pstatxucast; /* count of ucast frames xmitted on all psta assoc */ -+ uint32 pstatxnoassoc; /* count of txnoassoc frames xmitted on all psta assoc */ -+ uint32 pstarxucast; /* count of ucast frames received on all psta assoc */ -+ uint32 pstarxbcmc; /* count of bcmc frames received on all psta */ -+ uint32 pstatxbcmc; /* count of bcmc frames transmitted on all psta */ -+ -+ uint32 cso_passthrough; /* hw cso required but passthrough */ -+ uint32 cso_normal; /* hw cso hdr for normal process */ -+ uint32 chained; /* number of frames chained */ -+ uint32 chainedsz1; /* number of chain size 1 frames */ -+ uint32 unchained; /* number of frames not chained */ -+ uint32 maxchainsz; /* max chain size so far */ -+ uint32 currchainsz; /* current chain size */ -+} wl_cnt_t; -+ -+typedef struct { -+ uint16 version; /* see definition of WL_CNT_T_VERSION */ -+ uint16 length; /* length of entire structure */ -+ -+ /* transmit stat counters */ -+ uint32 txframe; /* tx data frames */ -+ uint32 txbyte; /* tx data bytes */ -+ uint32 txretrans; /* tx mac retransmits */ -+ uint32 txerror; /* tx data errors (derived: sum of others) */ -+ uint32 txctl; /* tx management frames */ -+ uint32 txprshort; /* tx short preamble frames */ -+ uint32 txserr; /* tx status errors */ -+ uint32 txnobuf; /* tx out of buffers errors */ -+ uint32 txnoassoc; /* tx discard because we're not associated */ -+ uint32 txrunt; /* tx runt frames */ -+ uint32 txchit; /* tx header cache hit (fastpath) */ -+ uint32 txcmiss; /* tx header cache miss (slowpath) */ -+ -+ /* transmit chip error counters */ -+ uint32 txuflo; /* tx fifo underflows */ -+ uint32 txphyerr; /* tx phy errors (indicated in tx status) */ -+ uint32 txphycrs; -+ -+ /* receive stat counters */ -+ uint32 rxframe; /* rx data frames */ -+ uint32 rxbyte; /* rx data bytes */ -+ uint32 rxerror; /* rx data errors (derived: sum of others) */ -+ uint32 rxctl; /* rx management frames */ -+ uint32 rxnobuf; /* rx out of buffers errors */ -+ uint32 rxnondata; /* rx non data frames in the data channel errors */ -+ uint32 rxbadds; /* rx bad DS errors */ -+ uint32 rxbadcm; /* rx bad control or management frames */ -+ uint32 rxfragerr; /* rx fragmentation errors */ -+ uint32 rxrunt; /* rx runt frames */ -+ uint32 rxgiant; /* rx giant frames */ -+ uint32 rxnoscb; /* rx no scb error */ -+ uint32 rxbadproto; /* rx invalid frames */ -+ uint32 rxbadsrcmac; /* rx frames with Invalid Src Mac */ -+ uint32 rxbadda; /* rx frames tossed for invalid da */ -+ uint32 rxfilter; /* rx frames filtered out */ -+ -+ /* receive chip error counters */ -+ uint32 rxoflo; /* rx fifo overflow errors */ -+ uint32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ -+ -+ uint32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ -+ uint32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ -+ uint32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ -+ -+ /* misc counters */ -+ uint32 dmade; /* tx/rx dma descriptor errors */ -+ uint32 dmada; /* tx/rx dma data errors */ -+ uint32 dmape; /* tx/rx dma descriptor protocol errors */ -+ uint32 reset; /* reset count */ -+ uint32 tbtt; /* cnts the TBTT int's */ -+ uint32 txdmawar; -+ uint32 pkt_callback_reg_fail; /* callbacks register failure */ -+ -+ /* MAC counters: 32-bit version of d11.h's macstat_t */ -+ uint32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, -+ * Control Management (includes retransmissions) -+ */ -+ uint32 txrtsfrm; /* number of RTS sent out by the MAC */ -+ uint32 txctsfrm; /* number of CTS sent out by the MAC */ -+ uint32 txackfrm; /* number of ACK frames sent out */ -+ uint32 txdnlfrm; /* Not used */ -+ uint32 txbcnfrm; /* beacons transmitted */ -+ uint32 txfunfl[8]; /* per-fifo tx underflows */ -+ uint32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS -+ * or BCN) -+ */ -+ uint32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for -+ * driver enqueued frames -+ */ -+ uint32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ -+ uint32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ -+ uint32 rxinvmachdr; /* Either the protocol version != 0 or frame type not -+ * data/control/management -+ */ -+ uint32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ -+ uint32 rxbadplcp; /* parity check of the PLCP header failed */ -+ uint32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ -+ uint32 rxstrt; /* Number of received frames with a good PLCP -+ * (i.e. passing parity check) -+ */ -+ uint32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ -+ uint32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ -+ uint32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ -+ uint32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ -+ uint32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ -+ uint32 rxackucast; /* number of ucast ACKS received (good FCS) */ -+ uint32 rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ -+ uint32 rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ -+ uint32 rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ -+ uint32 rxrtsocast; /* number of received RTS not addressed to the MAC */ -+ uint32 rxctsocast; /* number of received CTS not addressed to the MAC */ -+ uint32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ -+ uint32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ -+ uint32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC -+ * (unlikely to see these) -+ */ -+ uint32 rxbeaconmbss; /* beacons received from member of BSS */ -+ uint32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from -+ * other BSS (WDS FRAME) -+ */ -+ uint32 rxbeaconobss; /* beacons received from other BSS */ -+ uint32 rxrsptmout; /* Number of response timeouts for transmitted frames -+ * expecting a response -+ */ -+ uint32 bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ -+ uint32 rxf0ovfl; /* Number of receive fifo 0 overflows */ -+ uint32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ -+ uint32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ -+ uint32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ -+ uint32 pmqovfl; /* Number of PMQ overflows */ -+ uint32 rxcgprqfrm; /* Number of received Probe requests that made it into -+ * the PRQ fifo -+ */ -+ uint32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ -+ uint32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did -+ * not get ACK -+ */ -+ uint32 txcgprssuc; /* Tx Probe Response Success (ACK was received) */ -+ uint32 prs_timeout; /* Number of probe requests that were dropped from the PRQ -+ * fifo because a probe response could not be sent out within -+ * the time limit defined in M_PRS_MAXTIME -+ */ -+ uint32 rxnack; -+ uint32 frmscons; -+ uint32 txnack; -+ uint32 txglitch_nack; /* obsolete */ -+ uint32 txburst; /* obsolete */ -+ -+ /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ -+ uint32 txfrag; /* dot11TransmittedFragmentCount */ -+ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ -+ uint32 txfail; /* dot11FailedCount */ -+ uint32 txretry; /* dot11RetryCount */ -+ uint32 txretrie; /* dot11MultipleRetryCount */ -+ uint32 rxdup; /* dot11FrameduplicateCount */ -+ uint32 txrts; /* dot11RTSSuccessCount */ -+ uint32 txnocts; /* dot11RTSFailureCount */ -+ uint32 txnoack; /* dot11ACKFailureCount */ -+ uint32 rxfrag; /* dot11ReceivedFragmentCount */ -+ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ -+ uint32 rxcrc; /* dot11FCSErrorCount */ -+ uint32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ -+ uint32 rxundec; /* dot11WEPUndecryptableCount */ -+ -+ /* WPA2 counters (see rxundec for DecryptFailureCount) */ -+ uint32 tkipmicfaill; /* TKIPLocalMICFailures */ -+ uint32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ -+ uint32 tkipreplay; /* TKIPReplays */ -+ uint32 ccmpfmterr; /* CCMPFormatErrors */ -+ uint32 ccmpreplay; /* CCMPReplays */ -+ uint32 ccmpundec; /* CCMPDecryptErrors */ -+ uint32 fourwayfail; /* FourWayHandshakeFailures */ -+ uint32 wepundec; /* dot11WEPUndecryptableCount */ -+ uint32 wepicverr; /* dot11WEPICVErrorCount */ -+ uint32 decsuccess; /* DecryptSuccessCount */ -+ uint32 tkipicverr; /* TKIPICVErrorCount */ -+ uint32 wepexcluded; /* dot11WEPExcludedCount */ -+ -+ uint32 rxundec_mcst; /* dot11WEPUndecryptableCount */ -+ -+ /* WPA2 counters (see rxundec for DecryptFailureCount) */ -+ uint32 tkipmicfaill_mcst; /* TKIPLocalMICFailures */ -+ uint32 tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ -+ uint32 tkipreplay_mcst; /* TKIPReplays */ -+ uint32 ccmpfmterr_mcst; /* CCMPFormatErrors */ -+ uint32 ccmpreplay_mcst; /* CCMPReplays */ -+ uint32 ccmpundec_mcst; /* CCMPDecryptErrors */ -+ uint32 fourwayfail_mcst; /* FourWayHandshakeFailures */ -+ uint32 wepundec_mcst; /* dot11WEPUndecryptableCount */ -+ uint32 wepicverr_mcst; /* dot11WEPICVErrorCount */ -+ uint32 decsuccess_mcst; /* DecryptSuccessCount */ -+ uint32 tkipicverr_mcst; /* TKIPICVErrorCount */ -+ uint32 wepexcluded_mcst; /* dot11WEPExcludedCount */ -+ -+ uint32 txchanrej; /* Tx frames suppressed due to channel rejection */ -+ uint32 txexptime; /* Tx frames suppressed due to timer expiration */ -+ uint32 psmwds; /* Count PSM watchdogs */ -+ uint32 phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ -+ -+ /* MBSS counters, AP only */ -+ uint32 prq_entries_handled; /* PRQ entries read in */ -+ uint32 prq_undirected_entries; /* which were bcast bss & ssid */ -+ uint32 prq_bad_entries; /* which could not be translated to info */ -+ uint32 atim_suppress_count; /* TX suppressions on ATIM fifo */ -+ uint32 bcn_template_not_ready; /* Template marked in use on send bcn ... */ -+ uint32 bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ -+ uint32 late_tbtt_dpc; /* TBTT DPC did not happen in time */ -+ -+ /* per-rate receive stat counters */ -+ uint32 rx1mbps; /* packets rx at 1Mbps */ -+ uint32 rx2mbps; /* packets rx at 2Mbps */ -+ uint32 rx5mbps5; /* packets rx at 5.5Mbps */ -+ uint32 rx6mbps; /* packets rx at 6Mbps */ -+ uint32 rx9mbps; /* packets rx at 9Mbps */ -+ uint32 rx11mbps; /* packets rx at 11Mbps */ -+ uint32 rx12mbps; /* packets rx at 12Mbps */ -+ uint32 rx18mbps; /* packets rx at 18Mbps */ -+ uint32 rx24mbps; /* packets rx at 24Mbps */ -+ uint32 rx36mbps; /* packets rx at 36Mbps */ -+ uint32 rx48mbps; /* packets rx at 48Mbps */ -+ uint32 rx54mbps; /* packets rx at 54Mbps */ -+ uint32 rx108mbps; /* packets rx at 108mbps */ -+ uint32 rx162mbps; /* packets rx at 162mbps */ -+ uint32 rx216mbps; /* packets rx at 216 mbps */ -+ uint32 rx270mbps; /* packets rx at 270 mbps */ -+ uint32 rx324mbps; /* packets rx at 324 mbps */ -+ uint32 rx378mbps; /* packets rx at 378 mbps */ -+ uint32 rx432mbps; /* packets rx at 432 mbps */ -+ uint32 rx486mbps; /* packets rx at 486 mbps */ -+ uint32 rx540mbps; /* packets rx at 540 mbps */ -+ -+ /* pkteng rx frame stats */ -+ uint32 pktengrxducast; /* unicast frames rxed by the pkteng code */ -+ uint32 pktengrxdmcast; /* multicast frames rxed by the pkteng code */ -+ -+ uint32 rfdisable; /* count of radio disables */ -+ uint32 bphy_rxcrsglitch; /* PHY count of bphy glitches */ -+ -+ uint32 txmpdu_sgi; /* count for sgi transmit */ -+ uint32 rxmpdu_sgi; /* count for sgi received */ -+ uint32 txmpdu_stbc; /* count for stbc transmit */ -+ uint32 rxmpdu_stbc; /* count for stbc received */ -+} wl_cnt_ver_six_t; -+ -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+#define WL_DELTA_STATS_T_VERSION 1 /* current version of wl_delta_stats_t struct */ -+ -+typedef struct { -+ uint16 version; /* see definition of WL_DELTA_STATS_T_VERSION */ -+ uint16 length; /* length of entire structure */ -+ -+ /* transmit stat counters */ -+ uint32 txframe; /* tx data frames */ -+ uint32 txbyte; /* tx data bytes */ -+ uint32 txretrans; /* tx mac retransmits */ -+ uint32 txfail; /* tx failures */ -+ -+ /* receive stat counters */ -+ uint32 rxframe; /* rx data frames */ -+ uint32 rxbyte; /* rx data bytes */ -+ -+ /* per-rate receive stat counters */ -+ uint32 rx1mbps; /* packets rx at 1Mbps */ -+ uint32 rx2mbps; /* packets rx at 2Mbps */ -+ uint32 rx5mbps5; /* packets rx at 5.5Mbps */ -+ uint32 rx6mbps; /* packets rx at 6Mbps */ -+ uint32 rx9mbps; /* packets rx at 9Mbps */ -+ uint32 rx11mbps; /* packets rx at 11Mbps */ -+ uint32 rx12mbps; /* packets rx at 12Mbps */ -+ uint32 rx18mbps; /* packets rx at 18Mbps */ -+ uint32 rx24mbps; /* packets rx at 24Mbps */ -+ uint32 rx36mbps; /* packets rx at 36Mbps */ -+ uint32 rx48mbps; /* packets rx at 48Mbps */ -+ uint32 rx54mbps; /* packets rx at 54Mbps */ -+ uint32 rx108mbps; /* packets rx at 108mbps */ -+ uint32 rx162mbps; /* packets rx at 162mbps */ -+ uint32 rx216mbps; /* packets rx at 216 mbps */ -+ uint32 rx270mbps; /* packets rx at 270 mbps */ -+ uint32 rx324mbps; /* packets rx at 324 mbps */ -+ uint32 rx378mbps; /* packets rx at 378 mbps */ -+ uint32 rx432mbps; /* packets rx at 432 mbps */ -+ uint32 rx486mbps; /* packets rx at 486 mbps */ -+ uint32 rx540mbps; /* packets rx at 540 mbps */ -+} wl_delta_stats_t; -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+#define WL_WME_CNT_VERSION 1 /* current version of wl_wme_cnt_t */ -+ -+typedef struct { -+ uint32 packets; -+ uint32 bytes; -+} wl_traffic_stats_t; -+ -+typedef struct { -+ uint16 version; /* see definition of WL_WME_CNT_VERSION */ -+ uint16 length; /* length of entire structure */ -+ -+ wl_traffic_stats_t tx[AC_COUNT]; /* Packets transmitted */ -+ wl_traffic_stats_t tx_failed[AC_COUNT]; /* Packets dropped or failed to transmit */ -+ wl_traffic_stats_t rx[AC_COUNT]; /* Packets received */ -+ wl_traffic_stats_t rx_failed[AC_COUNT]; /* Packets failed to receive */ -+ -+ wl_traffic_stats_t forward[AC_COUNT]; /* Packets forwarded by AP */ -+ -+ wl_traffic_stats_t tx_expired[AC_COUNT]; /* packets dropped due to lifetime expiry */ -+ -+} wl_wme_cnt_t; -+ -+struct wl_msglevel2 { -+ uint32 low; -+ uint32 high; -+}; -+ -+typedef struct wl_mkeep_alive_pkt { -+ uint16 version; /* Version for mkeep_alive */ -+ uint16 length; /* length of fixed parameters in the structure */ -+ uint32 period_msec; -+ uint16 len_bytes; -+ uint8 keep_alive_id; /* 0 - 3 for N = 4 */ -+ uint8 data[1]; -+} wl_mkeep_alive_pkt_t; -+ -+#define WL_MKEEP_ALIVE_VERSION 1 -+#define WL_MKEEP_ALIVE_FIXED_LEN OFFSETOF(wl_mkeep_alive_pkt_t, data) -+#define WL_MKEEP_ALIVE_PRECISION 500 -+ -+#ifndef LINUX_POSTMOGRIFY_REMOVAL -+#ifdef WLBA -+ -+#define WLC_BA_CNT_VERSION 1 /* current version of wlc_ba_cnt_t */ -+ -+/* block ack related stats */ -+typedef struct wlc_ba_cnt { -+ uint16 version; /* WLC_BA_CNT_VERSION */ -+ uint16 length; /* length of entire structure */ -+ -+ /* transmit stat counters */ -+ uint32 txpdu; /* pdus sent */ -+ uint32 txsdu; /* sdus sent */ -+ uint32 txfc; /* tx side flow controlled packets */ -+ uint32 txfci; /* tx side flow control initiated */ -+ uint32 txretrans; /* retransmitted pdus */ -+ uint32 txbatimer; /* ba resend due to timer */ -+ uint32 txdrop; /* dropped packets */ -+ uint32 txaddbareq; /* addba req sent */ -+ uint32 txaddbaresp; /* addba resp sent */ -+ uint32 txdelba; /* delba sent */ -+ uint32 txba; /* ba sent */ -+ uint32 txbar; /* bar sent */ -+ uint32 txpad[4]; /* future */ -+ -+ /* receive side counters */ -+ uint32 rxpdu; /* pdus recd */ -+ uint32 rxqed; /* pdus buffered before sending up */ -+ uint32 rxdup; /* duplicate pdus */ -+ uint32 rxnobuf; /* pdus discarded due to no buf */ -+ uint32 rxaddbareq; /* addba req recd */ -+ uint32 rxaddbaresp; /* addba resp recd */ -+ uint32 rxdelba; /* delba recd */ -+ uint32 rxba; /* ba recd */ -+ uint32 rxbar; /* bar recd */ -+ uint32 rxinvba; /* invalid ba recd */ -+ uint32 rxbaholes; /* ba recd with holes */ -+ uint32 rxunexp; /* unexpected packets */ -+ uint32 rxpad[4]; /* future */ -+} wlc_ba_cnt_t; -+#endif /* WLBA */ -+ -+/* structure for per-tid ampdu control */ -+struct ampdu_tid_control { -+ uint8 tid; /* tid */ -+ uint8 enable; /* enable/disable */ -+}; -+ -+/* structure for identifying ea/tid for sending addba/delba */ -+struct ampdu_ea_tid { -+ struct ether_addr ea; /* Station address */ -+ uint8 tid; /* tid */ -+}; -+/* structure for identifying retry/tid for retry_limit_tid/rr_retry_limit_tid */ -+struct ampdu_retry_tid { -+ uint8 tid; /* tid */ -+ uint8 retry; /* retry value */ -+}; -+ -+/* Different discovery modes for dpt */ -+#define DPT_DISCOVERY_MANUAL 0x01 /* manual discovery mode */ -+#define DPT_DISCOVERY_AUTO 0x02 /* auto discovery mode */ -+#define DPT_DISCOVERY_SCAN 0x04 /* scan-based discovery mode */ -+ -+/* different path selection values */ -+#define DPT_PATHSEL_AUTO 0 /* auto mode for path selection */ -+#define DPT_PATHSEL_DIRECT 1 /* always use direct DPT path */ -+#define DPT_PATHSEL_APPATH 2 /* always use AP path */ -+ -+/* different ops for deny list */ -+#define DPT_DENY_LIST_ADD 1 /* add to dpt deny list */ -+#define DPT_DENY_LIST_REMOVE 2 /* remove from dpt deny list */ -+ -+/* different ops for manual end point */ -+#define DPT_MANUAL_EP_CREATE 1 /* create manual dpt endpoint */ -+#define DPT_MANUAL_EP_MODIFY 2 /* modify manual dpt endpoint */ -+#define DPT_MANUAL_EP_DELETE 3 /* delete manual dpt endpoint */ -+ -+/* structure for dpt iovars */ -+typedef struct dpt_iovar { -+ struct ether_addr ea; /* Station address */ -+ uint8 mode; /* mode: depends on iovar */ -+ uint32 pad; /* future */ -+} dpt_iovar_t; -+ -+/* flags to indicate DPT status */ -+#define DPT_STATUS_ACTIVE 0x01 /* link active (though may be suspended) */ -+#define DPT_STATUS_AES 0x02 /* link secured through AES encryption */ -+#define DPT_STATUS_FAILED 0x04 /* DPT link failed */ -+ -+#define DPT_FNAME_LEN 48 /* Max length of friendly name */ -+ -+typedef struct dpt_status { -+ uint8 status; /* flags to indicate status */ -+ uint8 fnlen; /* length of friendly name */ -+ uchar name[DPT_FNAME_LEN]; /* friendly name */ -+ uint32 rssi; /* RSSI of the link */ -+ sta_info_t sta; /* sta info */ -+} dpt_status_t; -+ -+/* structure for dpt list */ -+typedef struct dpt_list { -+ uint32 num; /* number of entries in struct */ -+ dpt_status_t status[1]; /* per station info */ -+} dpt_list_t; -+ -+/* structure for dpt friendly name */ -+typedef struct dpt_fname { -+ uint8 len; /* length of friendly name */ -+ uchar name[DPT_FNAME_LEN]; /* friendly name */ -+} dpt_fname_t; -+ -+#define BDD_FNAME_LEN 32 /* Max length of friendly name */ -+typedef struct bdd_fname { -+ uint8 len; /* length of friendly name */ -+ uchar name[BDD_FNAME_LEN]; /* friendly name */ -+} bdd_fname_t; -+ -+/* structure for addts arguments */ -+/* For ioctls that take a list of TSPEC */ -+struct tslist { -+ int count; /* number of tspecs */ -+ struct tsinfo_arg tsinfo[1]; /* variable length array of tsinfo */ -+}; -+ -+#ifdef WLTDLS -+/* different ops for manual end point */ -+#define TDLS_MANUAL_EP_CREATE 1 /* create manual dpt endpoint */ -+#define TDLS_MANUAL_EP_MODIFY 2 /* modify manual dpt endpoint */ -+#define TDLS_MANUAL_EP_DELETE 3 /* delete manual dpt endpoint */ -+#define TDLS_MANUAL_EP_PM 4 /* put dpt endpoint in PM mode */ -+#define TDLS_MANUAL_EP_WAKE 5 /* wake up dpt endpoint from PM */ -+#define TDLS_MANUAL_EP_DISCOVERY 6 /* discover if endpoint is TDLS capable */ -+#define TDLS_MANUAL_EP_CHSW 7 /* channel switch */ -+ -+/* structure for tdls iovars */ -+typedef struct tdls_iovar { -+ struct ether_addr ea; /* Station address */ -+ uint8 mode; /* mode: depends on iovar */ -+ chanspec_t chanspec; -+ uint32 pad; /* future */ -+} tdls_iovar_t; -+#endif /* WLTDLS */ -+ -+/* structure for addts/delts arguments */ -+typedef struct tspec_arg { -+ uint16 version; /* see definition of TSPEC_ARG_VERSION */ -+ uint16 length; /* length of entire structure */ -+ uint flag; /* bit field */ -+ /* TSPEC Arguments */ -+ struct tsinfo_arg tsinfo; /* TS Info bit field */ -+ uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */ -+ uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */ -+ uint min_srv_interval; /* Minimum Service Interval (us) */ -+ uint max_srv_interval; /* Maximum Service Interval (us) */ -+ uint inactivity_interval; /* Inactivity Interval (us) */ -+ uint suspension_interval; /* Suspension Interval (us) */ -+ uint srv_start_time; /* Service Start Time (us) */ -+ uint min_data_rate; /* Minimum Data Rate (bps) */ -+ uint mean_data_rate; /* Mean Data Rate (bps) */ -+ uint peak_data_rate; /* Peak Data Rate (bps) */ -+ uint max_burst_size; /* Maximum Burst Size (bytes) */ -+ uint delay_bound; /* Delay Bound (us) */ -+ uint min_phy_rate; /* Minimum PHY Rate (bps) */ -+ uint16 surplus_bw; /* Surplus Bandwidth Allowance (range 1.0 to 8.0) */ -+ uint16 medium_time; /* Medium Time (32 us/s periods) */ -+ uint8 dialog_token; /* dialog token */ -+} tspec_arg_t; -+ -+/* tspec arg for desired station */ -+typedef struct tspec_per_sta_arg { -+ struct ether_addr ea; -+ struct tspec_arg ts; -+} tspec_per_sta_arg_t; -+ -+/* structure for max bandwidth for each access category */ -+typedef struct wme_max_bandwidth { -+ uint32 ac[AC_COUNT]; /* max bandwidth for each access category */ -+} wme_max_bandwidth_t; -+ -+#define WL_WME_MBW_PARAMS_IO_BYTES (sizeof(wme_max_bandwidth_t)) -+ -+/* current version of wl_tspec_arg_t struct */ -+#define TSPEC_ARG_VERSION 2 /* current version of wl_tspec_arg_t struct */ -+#define TSPEC_ARG_LENGTH 55 /* argument length from tsinfo to medium_time */ -+#define TSPEC_DEFAULT_DIALOG_TOKEN 42 /* default dialog token */ -+#define TSPEC_DEFAULT_SBW_FACTOR 0x3000 /* default surplus bw */ -+ -+ -+#define WL_WOWL_KEEPALIVE_MAX_PACKET_SIZE 80 -+#define WLC_WOWL_MAX_KEEPALIVE 2 -+ -+/* define for flag */ -+#define TSPEC_PENDING 0 /* TSPEC pending */ -+#define TSPEC_ACCEPTED 1 /* TSPEC accepted */ -+#define TSPEC_REJECTED 2 /* TSPEC rejected */ -+#define TSPEC_UNKNOWN 3 /* TSPEC unknown */ -+#define TSPEC_STATUS_MASK 7 /* TSPEC status mask */ -+ -+ -+/* Software feature flag defines used by wlfeatureflag */ -+#ifdef WLAFTERBURNER -+#define WL_SWFL_ABBFL 0x0001 /* Allow Afterburner on systems w/o hardware BFL */ -+#define WL_SWFL_ABENCORE 0x0002 /* Allow AB on non-4318E chips */ -+#endif /* WLAFTERBURNER */ -+#define WL_SWFL_NOHWRADIO 0x0004 -+#define WL_SWFL_FLOWCONTROL 0x0008 /* Enable backpressure to OS stack */ -+#define WL_SWFL_WLBSSSORT 0x0010 /* Per-port supports sorting of BSS */ -+ -+#define WL_LIFETIME_MAX 0xFFFF /* Max value in ms */ -+ -+/* Packet lifetime configuration per ac */ -+typedef struct wl_lifetime { -+ uint32 ac; /* access class */ -+ uint32 lifetime; /* Packet lifetime value in ms */ -+} wl_lifetime_t; -+ -+/* Channel Switch Announcement param */ -+typedef struct wl_chan_switch { -+ uint8 mode; /* value 0 or 1 */ -+ uint8 count; /* count # of beacons before switching */ -+ chanspec_t chspec; /* chanspec */ -+ uint8 reg; /* regulatory class */ -+} wl_chan_switch_t; -+#endif /* LINUX_POSTMOGRIFY_REMOVAL */ -+ -+/* Roaming trigger definitions for WLC_SET_ROAM_TRIGGER. -+ * -+ * (-100 < value < 0) value is used directly as a roaming trigger in dBm -+ * (0 <= value) value specifies a logical roaming trigger level from -+ * the list below -+ * -+ * WLC_GET_ROAM_TRIGGER always returns roaming trigger value in dBm, never -+ * the logical roam trigger value. -+ */ -+#define WLC_ROAM_TRIGGER_DEFAULT 0 /* default roaming trigger */ -+#define WLC_ROAM_TRIGGER_BANDWIDTH 1 /* optimize for bandwidth roaming trigger */ -+#define WLC_ROAM_TRIGGER_DISTANCE 2 /* optimize for distance roaming trigger */ -+#define WLC_ROAM_TRIGGER_AUTO 3 /* auto-detect environment */ -+#define WLC_ROAM_TRIGGER_MAX_VALUE 3 /* max. valid value */ -+ -+#define WLC_ROAM_NEVER_ROAM_TRIGGER (-100) /* Avoid Roaming by setting a large value */ -+ -+/* Preferred Network Offload (PNO, formerly PFN) defines */ -+#define WPA_AUTH_PFN_ANY 0xffffffff /* for PFN, match only ssid */ -+ -+enum { -+ PFN_LIST_ORDER, -+ PFN_RSSI -+}; -+ -+enum { -+ DISABLE, -+ ENABLE -+}; -+ -+enum { -+ OFF_ADAPT, -+ SMART_ADAPT, -+ STRICT_ADAPT, -+ SLOW_ADAPT -+}; -+ -+#define SORT_CRITERIA_BIT 0 -+#define AUTO_NET_SWITCH_BIT 1 -+#define ENABLE_BKGRD_SCAN_BIT 2 -+#define IMMEDIATE_SCAN_BIT 3 -+#define AUTO_CONNECT_BIT 4 -+#define ENABLE_BD_SCAN_BIT 5 -+#define ENABLE_ADAPTSCAN_BIT 6 -+#define IMMEDIATE_EVENT_BIT 8 -+ -+#define SORT_CRITERIA_MASK 0x0001 -+#define AUTO_NET_SWITCH_MASK 0x0002 -+#define ENABLE_BKGRD_SCAN_MASK 0x0004 -+#define IMMEDIATE_SCAN_MASK 0x0008 -+#define AUTO_CONNECT_MASK 0x0010 -+ -+#define ENABLE_BD_SCAN_MASK 0x0020 -+#define ENABLE_ADAPTSCAN_MASK 0x00c0 -+#define IMMEDIATE_EVENT_MASK 0x0100 -+ -+#define PFN_VERSION 2 -+#define PFN_SCANRESULT_VERSION 1 -+#define MAX_PFN_LIST_COUNT 16 -+ -+#define PFN_COMPLETE 1 -+#define PFN_INCOMPLETE 0 -+ -+#define DEFAULT_BESTN 2 -+#define DEFAULT_MSCAN 0 -+#define DEFAULT_REPEAT 10 -+#define DEFAULT_EXP 2 -+ -+/* PFN network info structure */ -+typedef struct wl_pfn_subnet_info { -+ struct ether_addr BSSID; -+ uint8 channel; /* channel number only */ -+ uint8 SSID_len; -+ uint8 SSID[32]; -+} wl_pfn_subnet_info_t; -+ -+typedef struct wl_pfn_net_info { -+ wl_pfn_subnet_info_t pfnsubnet; -+ int16 RSSI; /* receive signal strength (in dBm) */ -+ uint16 timestamp; /* age in seconds */ -+} wl_pfn_net_info_t; -+ -+typedef struct wl_pfn_scanresults { -+ uint32 version; -+ uint32 status; -+ uint32 count; -+ wl_pfn_net_info_t netinfo[1]; -+} wl_pfn_scanresults_t; -+ -+/* PFN data structure */ -+typedef struct wl_pfn_param { -+ int32 version; /* PNO parameters version */ -+ int32 scan_freq; /* Scan frequency */ -+ int32 lost_network_timeout; /* Timeout in sec. to declare -+ * discovered network as lost -+ */ -+ int16 flags; /* Bit field to control features -+ * of PFN such as sort criteria auto -+ * enable switch and background scan -+ */ -+ int16 rssi_margin; /* Margin to avoid jitter for choosing a -+ * PFN based on RSSI sort criteria -+ */ -+ uint8 bestn; /* number of best networks in each scan */ -+ uint8 mscan; /* number of scans recorded */ -+ uint8 repeat; /* Minimum number of scan intervals -+ *before scan frequency changes in adaptive scan -+ */ -+ uint8 exp; /* Exponent of 2 for maximum scan interval */ -+#if !defined(WLC_PATCH) || !defined(BCM43362A2) -+ int32 slow_freq; /* slow scan period */ -+#endif /* !WLC_PATCH || !BCM43362A2 */ -+} wl_pfn_param_t; -+ -+typedef struct wl_pfn { -+ wlc_ssid_t ssid; /* ssid name and its length */ -+ int32 bss_type; /* IBSS or infrastructure */ -+ int32 infra; /* BSS Vs IBSS */ -+ int32 auth; /* Open Vs Closed */ -+ int32 wpa_auth; /* WPA type */ -+ int32 wsec; /* wsec value */ -+} wl_pfn_t; -+#define WL_PFN_HIDDEN_BIT 2 -+#define PNO_SCAN_MAX_FW 508*1000 /* max time scan time in msec */ -+#define PNO_SCAN_MAX_FW_SEC PNO_SCAN_MAX_FW/1000 /* max time scan time in SEC */ -+#define PNO_SCAN_MIN_FW_SEC 10 /* min time scan time in SEC */ -+#define WL_PFN_HIDDEN_MASK 0x4 -+ -+/* TCP Checksum Offload defines */ -+#define TOE_TX_CSUM_OL 0x00000001 -+#define TOE_RX_CSUM_OL 0x00000002 -+ -+/* TCP Checksum Offload error injection for testing */ -+#define TOE_ERRTEST_TX_CSUM 0x00000001 -+#define TOE_ERRTEST_RX_CSUM 0x00000002 -+#define TOE_ERRTEST_RX_CSUM2 0x00000004 -+ -+struct toe_ol_stats_t { -+ /* Num of tx packets that don't need to be checksummed */ -+ uint32 tx_summed; -+ -+ /* Num of tx packets where checksum is filled by offload engine */ -+ uint32 tx_iph_fill; -+ uint32 tx_tcp_fill; -+ uint32 tx_udp_fill; -+ uint32 tx_icmp_fill; -+ -+ /* Num of rx packets where toe finds out if checksum is good or bad */ -+ uint32 rx_iph_good; -+ uint32 rx_iph_bad; -+ uint32 rx_tcp_good; -+ uint32 rx_tcp_bad; -+ uint32 rx_udp_good; -+ uint32 rx_udp_bad; -+ uint32 rx_icmp_good; -+ uint32 rx_icmp_bad; -+ -+ /* Num of tx packets in which csum error is injected */ -+ uint32 tx_tcp_errinj; -+ uint32 tx_udp_errinj; -+ uint32 tx_icmp_errinj; -+ -+ /* Num of rx packets in which csum error is injected */ -+ uint32 rx_tcp_errinj; -+ uint32 rx_udp_errinj; -+ uint32 rx_icmp_errinj; -+}; -+ -+/* ARP Offload feature flags for arp_ol iovar */ -+#define ARP_OL_AGENT 0x00000001 -+#define ARP_OL_SNOOP 0x00000002 -+#define ARP_OL_HOST_AUTO_REPLY 0x00000004 -+#define ARP_OL_PEER_AUTO_REPLY 0x00000008 -+ -+/* ARP Offload error injection */ -+#define ARP_ERRTEST_REPLY_PEER 0x1 -+#define ARP_ERRTEST_REPLY_HOST 0x2 -+ -+#define ARP_MULTIHOMING_MAX 8 /* Maximum local host IP addresses */ -+#define ND_MULTIHOMING_MAX 8 /* Maximum local host IP addresses */ -+ -+/* Arp offload statistic counts */ -+struct arp_ol_stats_t { -+ uint32 host_ip_entries; /* Host IP table addresses (more than one if multihomed) */ -+ uint32 host_ip_overflow; /* Host IP table additions skipped due to overflow */ -+ -+ uint32 arp_table_entries; /* ARP table entries */ -+ uint32 arp_table_overflow; /* ARP table additions skipped due to overflow */ -+ -+ uint32 host_request; /* ARP requests from host */ -+ uint32 host_reply; /* ARP replies from host */ -+ uint32 host_service; /* ARP requests from host serviced by ARP Agent */ -+ -+ uint32 peer_request; /* ARP requests received from network */ -+ uint32 peer_request_drop; /* ARP requests from network that were dropped */ -+ uint32 peer_reply; /* ARP replies received from network */ -+ uint32 peer_reply_drop; /* ARP replies from network that were dropped */ -+ uint32 peer_service; /* ARP request from host serviced by ARP Agent */ -+}; -+ -+/* NS offload statistic counts */ -+struct nd_ol_stats_t { -+ uint32 host_ip_entries; /* Host IP table addresses (more than one if multihomed) */ -+ uint32 host_ip_overflow; /* Host IP table additions skipped due to overflow */ -+ uint32 peer_request; /* NS requests received from network */ -+ uint32 peer_request_drop; /* NS requests from network that were dropped */ -+ uint32 peer_reply_drop; /* NA replies from network that were dropped */ -+ uint32 peer_service; /* NS request from host serviced by firmware */ -+}; -+ -+/* -+ * Keep-alive packet offloading. -+ */ -+ -+/* NAT keep-alive packets format: specifies the re-transmission period, the packet -+ * length, and packet contents. -+ */ -+typedef struct wl_keep_alive_pkt { -+ uint32 period_msec; /* Retransmission period (0 to disable packet re-transmits) */ -+ uint16 len_bytes; /* Size of packet to transmit (0 to disable packet re-transmits) */ -+ uint8 data[1]; /* Variable length packet to transmit. Contents should include -+ * entire ethernet packet (enet header, IP header, UDP header, -+ * and UDP payload) in network byte order. -+ */ -+} wl_keep_alive_pkt_t; -+ -+#define WL_KEEP_ALIVE_FIXED_LEN OFFSETOF(wl_keep_alive_pkt_t, data) -+ -+/* -+ * Dongle pattern matching filter. -+ */ -+ -+/* Packet filter types. Currently, only pattern matching is supported. */ -+typedef enum wl_pkt_filter_type { -+ WL_PKT_FILTER_TYPE_PATTERN_MATCH /* Pattern matching filter */ -+} wl_pkt_filter_type_t; -+ -+#define WL_PKT_FILTER_TYPE wl_pkt_filter_type_t -+ -+/* Pattern matching filter. Specifies an offset within received packets to -+ * start matching, the pattern to match, the size of the pattern, and a bitmask -+ * that indicates which bits within the pattern should be matched. -+ */ -+typedef struct wl_pkt_filter_pattern { -+ uint32 offset; /* Offset within received packet to start pattern matching. -+ * Offset '0' is the first byte of the ethernet header. -+ */ -+ uint32 size_bytes; /* Size of the pattern. Bitmask must be the same size. */ -+ uint8 mask_and_pattern[1]; /* Variable length mask and pattern data. mask starts -+ * at offset 0. Pattern immediately follows mask. -+ */ -+} wl_pkt_filter_pattern_t; -+ -+/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */ -+typedef struct wl_pkt_filter { -+ uint32 id; /* Unique filter id, specified by app. */ -+ uint32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */ -+ uint32 negate_match; /* Negate the result of filter matches */ -+ union { /* Filter definitions */ -+ wl_pkt_filter_pattern_t pattern; /* Pattern matching filter */ -+ } u; -+} wl_pkt_filter_t; -+ -+#define WL_PKT_FILTER_FIXED_LEN OFFSETOF(wl_pkt_filter_t, u) -+#define WL_PKT_FILTER_PATTERN_FIXED_LEN OFFSETOF(wl_pkt_filter_pattern_t, mask_and_pattern) -+ -+/* IOVAR "pkt_filter_enable" parameter. */ -+typedef struct wl_pkt_filter_enable { -+ uint32 id; /* Unique filter id */ -+ uint32 enable; /* Enable/disable bool */ -+} wl_pkt_filter_enable_t; -+ -+/* IOVAR "pkt_filter_list" parameter. Used to retrieve a list of installed filters. */ -+typedef struct wl_pkt_filter_list { -+ uint32 num; /* Number of installed packet filters */ -+ wl_pkt_filter_t filter[1]; /* Variable array of packet filters. */ -+} wl_pkt_filter_list_t; -+ -+#define WL_PKT_FILTER_LIST_FIXED_LEN OFFSETOF(wl_pkt_filter_list_t, filter) -+ -+/* IOVAR "pkt_filter_stats" parameter. Used to retrieve debug statistics. */ -+typedef struct wl_pkt_filter_stats { -+ uint32 num_pkts_matched; /* # filter matches for specified filter id */ -+ uint32 num_pkts_forwarded; /* # packets fwded from dongle to host for all filters */ -+ uint32 num_pkts_discarded; /* # packets discarded by dongle for all filters */ -+} wl_pkt_filter_stats_t; -+ -+/* Sequential Commands ioctl */ -+typedef struct wl_seq_cmd_ioctl { -+ uint32 cmd; /* common ioctl definition */ -+ uint32 len; /* length of user buffer */ -+} wl_seq_cmd_ioctl_t; -+ -+#define WL_SEQ_CMD_ALIGN_BYTES 4 -+ -+/* These are the set of get IOCTLs that should be allowed when using -+ * IOCTL sequence commands. These are issued implicitly by wl.exe each time -+ * it is invoked. We never want to buffer these, or else wl.exe will stop working. -+ */ -+#define WL_SEQ_CMDS_GET_IOCTL_FILTER(cmd) \ -+ (((cmd) == WLC_GET_MAGIC) || \ -+ ((cmd) == WLC_GET_VERSION) || \ -+ ((cmd) == WLC_GET_AP) || \ -+ ((cmd) == WLC_GET_INSTANCE)) -+ -+/* -+ * Packet engine interface -+ */ -+ -+#define WL_PKTENG_PER_TX_START 0x01 -+#define WL_PKTENG_PER_TX_STOP 0x02 -+#define WL_PKTENG_PER_RX_START 0x04 -+#define WL_PKTENG_PER_RX_WITH_ACK_START 0x05 -+#define WL_PKTENG_PER_TX_WITH_ACK_START 0x06 -+#define WL_PKTENG_PER_RX_STOP 0x08 -+#define WL_PKTENG_PER_MASK 0xff -+ -+#define WL_PKTENG_SYNCHRONOUS 0x100 /* synchronous flag */ -+ -+typedef struct wl_pkteng { -+ uint32 flags; -+ uint32 delay; /* Inter-packet delay */ -+ uint32 nframes; /* Number of frames */ -+ uint32 length; /* Packet length */ -+ uint8 seqno; /* Enable/disable sequence no. */ -+ struct ether_addr dest; /* Destination address */ -+ struct ether_addr src; /* Source address */ -+} wl_pkteng_t; -+ -+#define NUM_80211b_RATES 4 -+#define NUM_80211ag_RATES 8 -+#define NUM_80211n_RATES 32 -+#define NUM_80211_RATES (NUM_80211b_RATES+NUM_80211ag_RATES+NUM_80211n_RATES) -+typedef struct wl_pkteng_stats { -+ uint32 lostfrmcnt; /* RX PER test: no of frames lost (skip seqno) */ -+ int32 rssi; /* RSSI */ -+ int32 snr; /* signal to noise ratio */ -+ uint16 rxpktcnt[NUM_80211_RATES+1]; -+} wl_pkteng_stats_t; -+ -+typedef struct wl_sslpnphy_papd_debug_data { -+ uint8 psat_pwr; -+ uint8 psat_indx; -+ uint8 final_idx; -+ uint8 start_idx; -+ int32 min_phase; -+ int32 voltage; -+ int8 temperature; -+} wl_sslpnphy_papd_debug_data_t; -+typedef struct wl_sslpnphy_debug_data { -+ int16 papdcompRe [64]; -+ int16 papdcompIm [64]; -+} wl_sslpnphy_debug_data_t; -+typedef struct wl_sslpnphy_spbdump_data { -+ uint16 tbl_length; -+ int16 spbreal[256]; -+ int16 spbimg[256]; -+} wl_sslpnphy_spbdump_data_t; -+typedef struct wl_sslpnphy_percal_debug_data { -+ uint cur_idx; -+ uint tx_drift; -+ uint8 prev_cal_idx; -+ uint percal_ctr; -+ int nxt_cal_idx; -+ uint force_1idxcal; -+ uint onedxacl_req; -+ int32 last_cal_volt; -+ int8 last_cal_temp; -+ uint vbat_ripple; -+ uint exit_route; -+ int32 volt_winner; -+} wl_sslpnphy_percal_debug_data_t; -+ -+#define WL_WOWL_MAGIC (1 << 0) /* Wakeup on Magic packet */ -+#define WL_WOWL_NET (1 << 1) /* Wakeup on Netpattern */ -+#define WL_WOWL_DIS (1 << 2) /* Wakeup on loss-of-link due to Disassoc/Deauth */ -+#define WL_WOWL_RETR (1 << 3) /* Wakeup on retrograde TSF */ -+#define WL_WOWL_BCN (1 << 4) /* Wakeup on loss of beacon */ -+#define WL_WOWL_TST (1 << 5) /* Wakeup after test */ -+#define WL_WOWL_M1 (1 << 6) /* Wakeup after PTK refresh */ -+#define WL_WOWL_EAPID (1 << 7) /* Wakeup after receipt of EAP-Identity Req */ -+#define WL_WOWL_PME_GPIO (1 << 8) /* Wakeind via PME(0) or GPIO(1) */ -+#define WL_WOWL_NEEDTKIP1 (1 << 9) /* need tkip phase 1 key to be updated by the driver */ -+#define WL_WOWL_GTK_FAILURE (1 << 10) /* enable wakeup if GTK fails */ -+#define WL_WOWL_EXTMAGPAT (1 << 11) /* support extended magic packets */ -+#define WL_WOWL_ARPOFFLOAD (1 << 12) /* support ARP/NS/keepalive offloading */ -+#define WL_WOWL_WPA2 (1 << 13) /* read protocol version for EAPOL frames */ -+#define WL_WOWL_KEYROT (1 << 14) /* If the bit is set, use key rotaton */ -+#define WL_WOWL_BCAST (1 << 15) /* If the bit is set, frm received was bcast frame */ -+ -+#define MAGIC_PKT_MINLEN 102 /* Magic pkt min length is 6 * 0xFF + 16 * ETHER_ADDR_LEN */ -+ -+#define WOWL_PATTEN_TYPE_ARP (1 << 0) /* ARP offload Pattern */ -+#define WOWL_PATTEN_TYPE_NA (1 << 1) /* NA offload Pattern */ -+ -+typedef struct { -+ uint32 masksize; /* Size of the mask in #of bytes */ -+ uint32 offset; /* Offset to start looking for the packet in # of bytes */ -+ uint32 patternoffset; /* Offset of start of pattern in the structure */ -+ uint32 patternsize; /* Size of the pattern itself in #of bytes */ -+ uint32 id; /* id */ -+ uint32 reasonsize; /* Size of the wakeup reason code */ -+ uint32 flags; /* Flags to tell the pattern type and other properties */ -+ /* Mask follows the structure above */ -+ /* Pattern follows the mask is at 'patternoffset' from the start */ -+} wl_wowl_pattern_t; -+ -+typedef struct { -+ uint count; -+ wl_wowl_pattern_t pattern[1]; -+} wl_wowl_pattern_list_t; -+ -+typedef struct { -+ uint8 pci_wakeind; /* Whether PCI PMECSR PMEStatus bit was set */ -+ uint16 ucode_wakeind; /* What wakeup-event indication was set by ucode */ -+} wl_wowl_wakeind_t; -+ -+ -+/* per AC rate control related data structure */ -+typedef struct wl_txrate_class { -+ uint8 init_rate; -+ uint8 min_rate; -+ uint8 max_rate; -+} wl_txrate_class_t; -+ -+ -+/* Overlap BSS Scan parameters default, minimum, maximum */ -+#define WLC_OBSS_SCAN_PASSIVE_DWELL_DEFAULT 20 /* unit TU */ -+#define WLC_OBSS_SCAN_PASSIVE_DWELL_MIN 5 /* unit TU */ -+#define WLC_OBSS_SCAN_PASSIVE_DWELL_MAX 1000 /* unit TU */ -+#define WLC_OBSS_SCAN_ACTIVE_DWELL_DEFAULT 10 /* unit TU */ -+#define WLC_OBSS_SCAN_ACTIVE_DWELL_MIN 10 /* unit TU */ -+#define WLC_OBSS_SCAN_ACTIVE_DWELL_MAX 1000 /* unit TU */ -+#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_DEFAULT 300 /* unit Sec */ -+#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MIN 10 /* unit Sec */ -+#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MAX 900 /* unit Sec */ -+#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_DEFAULT 5 -+#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MIN 5 -+#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MAX 100 -+#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_DEFAULT 200 /* unit TU */ -+#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MIN 200 /* unit TU */ -+#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MAX 10000 /* unit TU */ -+#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_DEFAULT 20 /* unit TU */ -+#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MIN 20 /* unit TU */ -+#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MAX 10000 /* unit TU */ -+#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_DEFAULT 25 /* unit percent */ -+#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MIN 0 /* unit percent */ -+#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MAX 100 /* unit percent */ -+ -+/* structure for Overlap BSS scan arguments */ -+typedef struct wl_obss_scan_arg { -+ int16 passive_dwell; -+ int16 active_dwell; -+ int16 bss_widthscan_interval; -+ int16 passive_total; -+ int16 active_total; -+ int16 chanwidth_transition_delay; -+ int16 activity_threshold; -+} wl_obss_scan_arg_t; -+ -+#define WL_OBSS_SCAN_PARAM_LEN sizeof(wl_obss_scan_arg_t) -+#define WL_MIN_NUM_OBSS_SCAN_ARG 7 /* minimum number of arguments required for OBSS Scan */ -+ -+#define WL_COEX_INFO_MASK 0x07 -+#define WL_COEX_INFO_REQ 0x01 -+#define WL_COEX_40MHZ_INTOLERANT 0x02 -+#define WL_COEX_WIDTH20 0x04 -+ -+#define WLC_RSSI_INVALID 0 /* invalid RSSI value */ -+ -+#define MAX_RSSI_LEVELS 8 -+ -+/* RSSI event notification configuration. */ -+typedef struct wl_rssi_event { -+ uint32 rate_limit_msec; /* # of events posted to application will be limited to -+ * one per specified period (0 to disable rate limit). -+ */ -+ uint8 num_rssi_levels; /* Number of entries in rssi_levels[] below */ -+ int8 rssi_levels[MAX_RSSI_LEVELS]; /* Variable number of RSSI levels. An event -+ * will be posted each time the RSSI of received -+ * beacons/packets crosses a level. -+ */ -+} wl_rssi_event_t; -+ -+typedef struct wl_action_obss_coex_req { -+ uint8 info; -+ uint8 num; -+ uint8 ch_list[1]; -+} wl_action_obss_coex_req_t; -+ -+ -+/* IOVar parameter block for small MAC address array with type indicator */ -+#define WL_IOV_MAC_PARAM_LEN 4 -+ -+#define WL_IOV_PKTQ_LOG_PRECS 16 -+ -+typedef struct { -+ uint32 num_addrs; -+ char addr_type[WL_IOV_MAC_PARAM_LEN]; -+ struct ether_addr ea[WL_IOV_MAC_PARAM_LEN]; -+} wl_iov_mac_params_t; -+ -+ -+/* Parameter block for PKTQ_LOG statistics */ -+typedef struct { -+ uint32 requested; /* packets requested to be stored */ -+ uint32 stored; /* packets stored */ -+ uint32 saved; /* packets saved, -+ because a lowest priority queue has given away one packet -+ */ -+ uint32 selfsaved; /* packets saved, -+ because an older packet from the same queue has been dropped -+ */ -+ uint32 full_dropped; /* packets dropped, -+ because pktq is full with higher precedence packets -+ */ -+ uint32 dropped; /* packets dropped because pktq per that precedence is full */ -+ uint32 sacrificed; /* packets dropped, -+ in order to save one from a queue of a highest priority -+ */ -+ uint32 busy; /* packets droped because of hardware/transmission error */ -+ uint32 retry; /* packets re-sent because they were not received */ -+ uint32 ps_retry; /* packets retried again prior to moving power save mode */ -+ uint32 retry_drop; /* packets finally dropped after retry limit */ -+ uint32 max_avail; /* the high-water mark of the queue capacity for packets - -+ goes to zero as queue fills -+ */ -+ uint32 max_used; /* the high-water mark of the queue utilisation for packets - -+ increases with use ('inverse' of max_avail) -+ */ -+ uint32 queue_capacity; /* the maximum capacity of the queue */ -+} pktq_log_counters_v01_t; -+ -+#define sacrified sacrificed -+ -+typedef struct { -+ uint8 num_prec[WL_IOV_MAC_PARAM_LEN]; -+ pktq_log_counters_v01_t counters[WL_IOV_MAC_PARAM_LEN][WL_IOV_PKTQ_LOG_PRECS]; -+ char headings[1]; -+} pktq_log_format_v01_t; -+ -+ -+typedef struct { -+ uint32 version; -+ wl_iov_mac_params_t params; -+ union { -+ pktq_log_format_v01_t v01; -+ } pktq_log; -+} wl_iov_pktq_log_t; -+ -+ -+/* **** EXTLOG **** */ -+#define EXTLOG_CUR_VER 0x0100 -+ -+#define MAX_ARGSTR_LEN 18 /* At least big enough for storing ETHER_ADDR_STR_LEN */ -+ -+/* log modules (bitmap) */ -+#define LOG_MODULE_COMMON 0x0001 -+#define LOG_MODULE_ASSOC 0x0002 -+#define LOG_MODULE_EVENT 0x0004 -+#define LOG_MODULE_MAX 3 /* Update when adding module */ -+ -+/* log levels */ -+#define WL_LOG_LEVEL_DISABLE 0 -+#define WL_LOG_LEVEL_ERR 1 -+#define WL_LOG_LEVEL_WARN 2 -+#define WL_LOG_LEVEL_INFO 3 -+#define WL_LOG_LEVEL_MAX WL_LOG_LEVEL_INFO /* Update when adding level */ -+ -+/* flag */ -+#define LOG_FLAG_EVENT 1 -+ -+/* log arg_type */ -+#define LOG_ARGTYPE_NULL 0 -+#define LOG_ARGTYPE_STR 1 /* %s */ -+#define LOG_ARGTYPE_INT 2 /* %d */ -+#define LOG_ARGTYPE_INT_STR 3 /* %d...%s */ -+#define LOG_ARGTYPE_STR_INT 4 /* %s...%d */ -+ -+typedef struct wlc_extlog_cfg { -+ int max_number; -+ uint16 module; /* bitmap */ -+ uint8 level; -+ uint8 flag; -+ uint16 version; -+} wlc_extlog_cfg_t; -+ -+typedef struct log_record { -+ uint32 time; -+ uint16 module; -+ uint16 id; -+ uint8 level; -+ uint8 sub_unit; -+ uint8 seq_num; -+ int32 arg; -+ char str[MAX_ARGSTR_LEN]; -+} log_record_t; -+ -+typedef struct wlc_extlog_req { -+ uint32 from_last; -+ uint32 num; -+} wlc_extlog_req_t; -+ -+typedef struct wlc_extlog_results { -+ uint16 version; -+ uint16 record_len; -+ uint32 num; -+ log_record_t logs[1]; -+} wlc_extlog_results_t; -+ -+typedef struct log_idstr { -+ uint16 id; -+ uint16 flag; -+ uint8 arg_type; -+ const char *fmt_str; -+} log_idstr_t; -+ -+#define FMTSTRF_USER 1 -+ -+/* flat ID definitions -+ * New definitions HAVE TO BE ADDED at the end of the table. Otherwise, it will -+ * affect backward compatibility with pre-existing apps -+ */ -+typedef enum { -+ FMTSTR_DRIVER_UP_ID = 0, -+ FMTSTR_DRIVER_DOWN_ID = 1, -+ FMTSTR_SUSPEND_MAC_FAIL_ID = 2, -+ FMTSTR_NO_PROGRESS_ID = 3, -+ FMTSTR_RFDISABLE_ID = 4, -+ FMTSTR_REG_PRINT_ID = 5, -+ FMTSTR_EXPTIME_ID = 6, -+ FMTSTR_JOIN_START_ID = 7, -+ FMTSTR_JOIN_COMPLETE_ID = 8, -+ FMTSTR_NO_NETWORKS_ID = 9, -+ FMTSTR_SECURITY_MISMATCH_ID = 10, -+ FMTSTR_RATE_MISMATCH_ID = 11, -+ FMTSTR_AP_PRUNED_ID = 12, -+ FMTSTR_KEY_INSERTED_ID = 13, -+ FMTSTR_DEAUTH_ID = 14, -+ FMTSTR_DISASSOC_ID = 15, -+ FMTSTR_LINK_UP_ID = 16, -+ FMTSTR_LINK_DOWN_ID = 17, -+ FMTSTR_RADIO_HW_OFF_ID = 18, -+ FMTSTR_RADIO_HW_ON_ID = 19, -+ FMTSTR_EVENT_DESC_ID = 20, -+ FMTSTR_PNP_SET_POWER_ID = 21, -+ FMTSTR_RADIO_SW_OFF_ID = 22, -+ FMTSTR_RADIO_SW_ON_ID = 23, -+ FMTSTR_PWD_MISMATCH_ID = 24, -+ FMTSTR_FATAL_ERROR_ID = 25, -+ FMTSTR_AUTH_FAIL_ID = 26, -+ FMTSTR_ASSOC_FAIL_ID = 27, -+ FMTSTR_IBSS_FAIL_ID = 28, -+ FMTSTR_EXTAP_FAIL_ID = 29, -+ FMTSTR_MAX_ID -+} log_fmtstr_id_t; -+ -+#ifdef DONGLEOVERLAYS -+typedef struct { -+ uint32 flags_idx; /* lower 8 bits: overlay index; upper 24 bits: flags */ -+ uint32 offset; /* offset into overlay region to write code */ -+ uint32 len; /* overlay code len */ -+ /* overlay code follows this struct */ -+} wl_ioctl_overlay_t; -+ -+#define OVERLAY_IDX_MASK 0x000000ff -+#define OVERLAY_IDX_SHIFT 0 -+#define OVERLAY_FLAGS_MASK 0xffffff00 -+#define OVERLAY_FLAGS_SHIFT 8 -+/* overlay written to device memory immediately after loading the base image */ -+#define OVERLAY_FLAG_POSTLOAD 0x100 -+/* defer overlay download until the device responds w/WLC_E_OVL_DOWNLOAD event */ -+#define OVERLAY_FLAG_DEFER_DL 0x200 -+/* overlay downloaded prior to the host going to sleep */ -+#define OVERLAY_FLAG_PRESLEEP 0x400 -+ -+#define OVERLAY_DOWNLOAD_CHUNKSIZE 1024 -+#endif /* DONGLEOVERLAYS */ -+ -+/* no default structure packing */ -+#include -+ -+/* require strict packing */ -+#include -+/* Structures and constants used for "vndr_ie" IOVar interface */ -+#define VNDR_IE_CMD_LEN 4 /* length of the set command string: -+ * "add", "del" (+ NUL) -+ */ -+ -+/* 802.11 Mgmt Packet flags */ -+#define VNDR_IE_BEACON_FLAG 0x1 -+#define VNDR_IE_PRBRSP_FLAG 0x2 -+#define VNDR_IE_ASSOCRSP_FLAG 0x4 -+#define VNDR_IE_AUTHRSP_FLAG 0x8 -+#define VNDR_IE_PRBREQ_FLAG 0x10 -+#define VNDR_IE_ASSOCREQ_FLAG 0x20 -+#define VNDR_IE_IWAPID_FLAG 0x40 /* vendor IE in IW advertisement protocol ID field */ -+#define VNDR_IE_CUSTOM_FLAG 0x100 /* allow custom IE id */ -+ -+#define VNDR_IE_INFO_HDR_LEN (sizeof(uint32)) -+ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ -+ vndr_ie_t vndr_ie_data; /* vendor IE data */ -+} BWL_POST_PACKED_STRUCT vndr_ie_info_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ int iecount; /* number of entries in the vndr_ie_list[] array */ -+ vndr_ie_info_t vndr_ie_list[1]; /* variable size list of vndr_ie_info_t structs */ -+} BWL_POST_PACKED_STRUCT vndr_ie_buf_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ char cmd[VNDR_IE_CMD_LEN]; /* vndr_ie IOVar set command : "add", "del" + NUL */ -+ vndr_ie_buf_t vndr_ie_buffer; /* buffer containing Vendor IE list information */ -+} BWL_POST_PACKED_STRUCT vndr_ie_setbuf_t; -+ -+/* tag_ID/length/value_buffer tuple */ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ uint8 id; -+ uint8 len; -+ uint8 data[1]; -+} BWL_POST_PACKED_STRUCT tlv_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ -+ tlv_t ie_data; /* IE data */ -+} BWL_POST_PACKED_STRUCT ie_info_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ int iecount; /* number of entries in the ie_list[] array */ -+ ie_info_t ie_list[1]; /* variable size list of ie_info_t structs */ -+} BWL_POST_PACKED_STRUCT ie_buf_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ char cmd[VNDR_IE_CMD_LEN]; /* ie IOVar set command : "add" + NUL */ -+ ie_buf_t ie_buffer; /* buffer containing IE list information */ -+} BWL_POST_PACKED_STRUCT ie_setbuf_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct { -+ uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ -+ uint8 id; /* IE type */ -+} BWL_POST_PACKED_STRUCT ie_getbuf_t; -+ -+/* structures used to define format of wps ie data from probe requests */ -+/* passed up to applications via iovar "prbreq_wpsie" */ -+typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_hdr { -+ struct ether_addr staAddr; -+ uint16 ieLen; -+} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_hdr_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_data { -+ sta_prbreq_wps_ie_hdr_t hdr; -+ uint8 ieData[1]; -+} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_data_t; -+ -+typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_list { -+ uint32 totLen; -+ uint8 ieDataList[1]; -+} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_list_t; -+ -+ -+#ifdef WLMEDIA_TXFAILEVENT -+typedef BWL_PRE_PACKED_STRUCT struct { -+ char dest[ETHER_ADDR_LEN]; /* destination MAC */ -+ uint8 prio; /* Packet Priority */ -+ uint8 flags; /* Flags */ -+ uint32 tsf_l; /* TSF timer low */ -+ uint32 tsf_h; /* TSF timer high */ -+ uint16 rates; /* Main Rates */ -+ uint16 txstatus; /* TX Status */ -+} BWL_POST_PACKED_STRUCT txfailinfo_t; -+#endif /* WLMEDIA_TXFAILEVENT */ -+ -+/* no strict structure packing */ -+#include -+ -+/* Global ASSERT Logging */ -+#define ASSERTLOG_CUR_VER 0x0100 -+#define MAX_ASSRTSTR_LEN 64 -+ -+typedef struct assert_record { -+ uint32 time; -+ uint8 seq_num; -+ char str[MAX_ASSRTSTR_LEN]; -+} assert_record_t; -+ -+typedef struct assertlog_results { -+ uint16 version; -+ uint16 record_len; -+ uint32 num; -+ assert_record_t logs[1]; -+} assertlog_results_t; -+ -+#define LOGRRC_FIX_LEN 8 -+#define IOBUF_ALLOWED_NUM_OF_LOGREC(type, len) ((len - LOGRRC_FIX_LEN)/sizeof(type)) -+ -+ -+/* channel interference measurement (chanim) related defines */ -+ -+/* chanim mode */ -+#define CHANIM_DISABLE 0 /* disabled */ -+#define CHANIM_DETECT 1 /* detection only */ -+#define CHANIM_EXT 2 /* external state machine */ -+#define CHANIM_ACT 3 /* full internal state machine, detect + act */ -+#define CHANIM_MODE_MAX 4 -+ -+/* define for apcs reason code */ -+#define APCS_INIT 0 -+#define APCS_IOCTL 1 -+#define APCS_CHANIM 2 -+#define APCS_CSTIMER 3 -+#define APCS_BTA 4 -+ -+/* number of ACS record entries */ -+#define CHANIM_ACS_RECORD 10 -+ -+/* CHANIM */ -+#define CCASTATS_TXDUR 0 -+#define CCASTATS_INBSS 1 -+#define CCASTATS_OBSS 2 -+#define CCASTATS_NOCTG 3 -+#define CCASTATS_NOPKT 4 -+#define CCASTATS_DOZE 5 -+#define CCASTATS_TXOP 6 -+#define CCASTATS_GDTXDUR 7 -+#define CCASTATS_BDTXDUR 8 -+#define CCASTATS_MAX 9 -+ -+/* chanim acs record */ -+typedef struct { -+ bool valid; -+ uint8 trigger; -+ chanspec_t selected_chspc; -+ int8 bgnoise; -+ uint32 glitch_cnt; -+ uint8 ccastats; -+ uint timestamp; -+} chanim_acs_record_t; -+ -+typedef struct { -+ chanim_acs_record_t acs_record[CHANIM_ACS_RECORD]; -+ uint8 count; -+ uint timestamp; -+} wl_acs_record_t; -+ -+typedef struct chanim_stats { -+ uint32 glitchcnt; /* normalized as per second count */ -+ uint32 badplcp; /* normalized as per second count */ -+ uint8 ccastats[CCASTATS_MAX]; /* normalized as 0-255 */ -+ int8 bgnoise; /* background noise level (in dBm) */ -+ chanspec_t chanspec; -+ uint32 timestamp; -+} chanim_stats_t; -+ -+#define WL_CHANIM_STATS_VERSION 1 -+#define WL_CHANIM_COUNT_ALL 0xff -+#define WL_CHANIM_COUNT_ONE 0x1 -+ -+typedef struct { -+ uint32 buflen; -+ uint32 version; -+ uint32 count; -+ chanim_stats_t stats[1]; -+} wl_chanim_stats_t; -+ -+#define WL_CHANIM_STATS_FIXED_LEN OFFSETOF(wl_chanim_stats_t, stats) -+ -+/* Noise measurement metrics. */ -+#define NOISE_MEASURE_KNOISE 0x1 -+ -+/* scb probe parameter */ -+typedef struct { -+ uint32 scb_timeout; -+ uint32 scb_activity_time; -+ uint32 scb_max_probe; -+} wl_scb_probe_t; -+ -+/* ap tpc modes */ -+#define AP_TPC_OFF 0 -+#define AP_TPC_BSS_PWR 1 /* BSS power control */ -+#define AP_TPC_AP_PWR 2 /* AP power control */ -+#define AP_TPC_AP_BSS_PWR 3 /* Both AP and BSS power control */ -+#define AP_TPC_MAX_LINK_MARGIN 127 -+ -+/* structure/defines for selective mgmt frame (smf) stats support */ -+ -+#define SMFS_VERSION 1 -+/* selected mgmt frame (smf) stats element */ -+typedef struct wl_smfs_elem { -+ uint32 count; -+ uint16 code; /* SC or RC code */ -+} wl_smfs_elem_t; -+ -+typedef struct wl_smf_stats { -+ uint32 version; -+ uint16 length; /* reserved for future usage */ -+ uint8 type; -+ uint8 codetype; -+ uint32 ignored_cnt; -+ uint32 malformed_cnt; -+ uint32 count_total; /* count included the interested group */ -+ wl_smfs_elem_t elem[1]; -+} wl_smf_stats_t; -+ -+#define WL_SMFSTATS_FIXED_LEN OFFSETOF(wl_smf_stats_t, elem); -+ -+enum { -+ SMFS_CODETYPE_SC, -+ SMFS_CODETYPE_RC -+}; -+ -+/* reuse two number in the sc/rc space */ -+#define SMFS_CODE_MALFORMED 0xFFFE -+#define SMFS_CODE_IGNORED 0xFFFD -+ -+typedef enum smfs_type { -+ SMFS_TYPE_AUTH, -+ SMFS_TYPE_ASSOC, -+ SMFS_TYPE_REASSOC, -+ SMFS_TYPE_DISASSOC_TX, -+ SMFS_TYPE_DISASSOC_RX, -+ SMFS_TYPE_DEAUTH_TX, -+ SMFS_TYPE_DEAUTH_RX, -+ SMFS_TYPE_MAX -+} smfs_type_t; -+ -+#ifdef PHYMON -+ -+#define PHYMON_VERSION 1 -+ -+typedef struct wl_phycal_core_state { -+ /* Tx IQ/LO calibration coeffs */ -+ int16 tx_iqlocal_a; -+ int16 tx_iqlocal_b; -+ int8 tx_iqlocal_ci; -+ int8 tx_iqlocal_cq; -+ int8 tx_iqlocal_di; -+ int8 tx_iqlocal_dq; -+ int8 tx_iqlocal_ei; -+ int8 tx_iqlocal_eq; -+ int8 tx_iqlocal_fi; -+ int8 tx_iqlocal_fq; -+ -+ /* Rx IQ calibration coeffs */ -+ int16 rx_iqcal_a; -+ int16 rx_iqcal_b; -+ -+ uint8 tx_iqlocal_pwridx; /* Tx Power Index for Tx IQ/LO calibration */ -+ uint32 papd_epsilon_table[64]; /* PAPD epsilon table */ -+ int16 papd_epsilon_offset; /* PAPD epsilon offset */ -+ uint8 curr_tx_pwrindex; /* Tx power index */ -+ int8 idle_tssi; /* Idle TSSI */ -+ int8 est_tx_pwr; /* Estimated Tx Power (dB) */ -+ int8 est_rx_pwr; /* Estimated Rx Power (dB) from RSSI */ -+ uint16 rx_gaininfo; /* Rx gain applied on last Rx pkt */ -+ uint16 init_gaincode; /* initgain required for ACI */ -+ int8 estirr_tx; -+ int8 estirr_rx; -+ -+} wl_phycal_core_state_t; -+ -+typedef struct wl_phycal_state { -+ int version; -+ int8 num_phy_cores; /* number of cores */ -+ int8 curr_temperature; /* on-chip temperature sensor reading */ -+ chanspec_t chspec; /* channspec for this state */ -+ bool aci_state; /* ACI state: ON/OFF */ -+ uint16 crsminpower; /* crsminpower required for ACI */ -+ uint16 crsminpowerl; /* crsminpowerl required for ACI */ -+ uint16 crsminpoweru; /* crsminpoweru required for ACI */ -+ wl_phycal_core_state_t phycal_core[1]; -+} wl_phycal_state_t; -+ -+#define WL_PHYCAL_STAT_FIXED_LEN OFFSETOF(wl_phycal_state_t, phycal_core) -+#endif /* PHYMON */ -+ -+/* discovery state */ -+typedef struct wl_p2p_disc_st { -+ uint8 state; /* see state */ -+ chanspec_t chspec; /* valid in listen state */ -+ uint16 dwell; /* valid in listen state, in ms */ -+} wl_p2p_disc_st_t; -+ -+/* state */ -+#define WL_P2P_DISC_ST_SCAN 0 -+#define WL_P2P_DISC_ST_LISTEN 1 -+#define WL_P2P_DISC_ST_SEARCH 2 -+ -+/* scan request */ -+typedef struct wl_p2p_scan { -+ uint8 type; /* 'S' for WLC_SCAN, 'E' for "escan" */ -+ uint8 reserved[3]; -+ /* scan or escan parms... */ -+} wl_p2p_scan_t; -+ -+/* i/f request */ -+typedef struct wl_p2p_if { -+ struct ether_addr addr; -+ uint8 type; /* see i/f type */ -+ chanspec_t chspec; /* for p2p_ifadd GO */ -+} wl_p2p_if_t; -+ -+/* i/f type */ -+#define WL_P2P_IF_CLIENT 0 -+#define WL_P2P_IF_GO 1 -+#define WL_P2P_IF_DYNBCN_GO 2 -+#define WL_P2P_IF_DEV 3 -+ -+/* i/f query */ -+typedef struct wl_p2p_ifq { -+ uint bsscfgidx; -+ char ifname[BCM_MSG_IFNAME_MAX]; -+} wl_p2p_ifq_t; -+ -+/* OppPS & CTWindow */ -+typedef struct wl_p2p_ops { -+ uint8 ops; /* 0: disable 1: enable */ -+ uint8 ctw; /* >= 10 */ -+} wl_p2p_ops_t; -+ -+/* absence and presence request */ -+typedef struct wl_p2p_sched_desc { -+ uint32 start; -+ uint32 interval; -+ uint32 duration; -+ uint32 count; /* see count */ -+} wl_p2p_sched_desc_t; -+ -+/* count */ -+#define WL_P2P_SCHED_RSVD 0 -+#define WL_P2P_SCHED_REPEAT 255 /* anything > 255 will be treated as 255 */ -+ -+typedef struct wl_p2p_sched { -+ uint8 type; /* see schedule type */ -+ uint8 action; /* see schedule action */ -+ uint8 option; /* see schedule option */ -+ wl_p2p_sched_desc_t desc[1]; -+} wl_p2p_sched_t; -+#define WL_P2P_SCHED_FIXED_LEN 3 -+ -+/* schedule type */ -+#define WL_P2P_SCHED_TYPE_ABS 0 /* Scheduled Absence */ -+#define WL_P2P_SCHED_TYPE_REQ_ABS 1 /* Requested Absence */ -+ -+/* schedule action during absence periods (for WL_P2P_SCHED_ABS type) */ -+#define WL_P2P_SCHED_ACTION_NONE 0 /* no action */ -+#define WL_P2P_SCHED_ACTION_DOZE 1 /* doze */ -+/* schedule option - WL_P2P_SCHED_TYPE_REQ_ABS */ -+#define WL_P2P_SCHED_ACTION_GOOFF 2 /* turn off GO beacon/prbrsp functions */ -+/* schedule option - WL_P2P_SCHED_TYPE_XXX */ -+#define WL_P2P_SCHED_ACTION_RESET 255 /* reset */ -+ -+/* schedule option - WL_P2P_SCHED_TYPE_ABS */ -+#define WL_P2P_SCHED_OPTION_NORMAL 0 /* normal start/interval/duration/count */ -+#define WL_P2P_SCHED_OPTION_BCNPCT 1 /* percentage of beacon interval */ -+/* schedule option - WL_P2P_SCHED_TYPE_REQ_ABS */ -+#define WL_P2P_SCHED_OPTION_TSFOFS 2 /* normal start/internal/duration/count with -+ * start being an offset of the 'current' TSF -+ */ -+ -+/* feature flags */ -+#define WL_P2P_FEAT_GO_CSA (1 << 0) /* GO moves with the STA using CSA method */ -+#define WL_P2P_FEAT_GO_NOLEGACY (1 << 1) /* GO does not probe respond to non-p2p probe -+ * requests -+ */ -+#define WL_P2P_FEAT_RESTRICT_DEV_RESP (1 << 2) /* Restrict p2p dev interface from responding */ -+ -+/* RFAWARE def */ -+#define BCM_ACTION_RFAWARE 0x77 -+#define BCM_ACTION_RFAWARE_DCS 0x01 -+ -+/* DCS reason code define */ -+#define BCM_DCS_IOVAR 0x1 -+#define BCM_DCS_UNKNOWN 0xFF -+ -+typedef struct wl_bcmdcs_data { -+ uint reason; -+ chanspec_t chspec; -+} wl_bcmdcs_data_t; -+ -+/* n-mode support capability */ -+/* 2x2 includes both 1x1 & 2x2 devices -+ * reserved #define 2 for future when we want to separate 1x1 & 2x2 and -+ * control it independently -+ */ -+#define WL_11N_2x2 1 -+#define WL_11N_3x3 3 -+#define WL_11N_4x4 4 -+ -+/* define 11n feature disable flags */ -+#define WLFEATURE_DISABLE_11N 0x00000001 -+#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002 -+#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004 -+#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008 -+#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010 -+#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020 -+#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040 -+#define WLFEATURE_DISABLE_11N_GF 0x00000080 -+ -+/* Proxy STA modes */ -+#define PSTA_MODE_DISABLED 0 -+#define PSTA_MODE_PROXY 1 -+#define PSTA_MODE_REPEATER 2 -+ -+ -+/* NAT configuration */ -+typedef struct { -+ uint32 ipaddr; /* interface ip address */ -+ uint32 ipaddr_mask; /* interface ip address mask */ -+ uint32 ipaddr_gateway; /* gateway ip address */ -+ uint8 mac_gateway[6]; /* gateway mac address */ -+ uint32 ipaddr_dns; /* DNS server ip address, valid only for public if */ -+ uint8 mac_dns[6]; /* DNS server mac address, valid only for public if */ -+ uint8 GUID[38]; /* interface GUID */ -+} nat_if_info_t; -+ -+typedef struct { -+ uint op; /* operation code */ -+ bool pub_if; /* set for public if, clear for private if */ -+ nat_if_info_t if_info; /* interface info */ -+} nat_cfg_t; -+ -+/* op code in nat_cfg */ -+#define NAT_OP_ENABLE 1 /* enable NAT on given interface */ -+#define NAT_OP_DISABLE 2 /* disable NAT on given interface */ -+#define NAT_OP_DISABLE_ALL 3 /* disable NAT on all interfaces */ -+ -+/* NAT state */ -+#define NAT_STATE_ENABLED 1 /* NAT is enabled */ -+#define NAT_STATE_DISABLED 2 /* NAT is disabled */ -+ -+typedef struct { -+ int state; /* NAT state returned */ -+} nat_state_t; -+ -+#ifdef PROP_TXSTATUS -+/* Bit definitions for tlv iovar */ -+/* -+ * enable RSSI signals: -+ * WLFC_CTL_TYPE_RSSI -+ */ -+#define WLFC_FLAGS_RSSI_SIGNALS 1 -+ -+/* enable (if/mac_open, if/mac_close,, mac_add, mac_del) signals: -+ * -+ * WLFC_CTL_TYPE_MAC_OPEN -+ * WLFC_CTL_TYPE_MAC_CLOSE -+ * -+ * WLFC_CTL_TYPE_INTERFACE_OPEN -+ * WLFC_CTL_TYPE_INTERFACE_CLOSE -+ * -+ * WLFC_CTL_TYPE_MACDESC_ADD -+ * WLFC_CTL_TYPE_MACDESC_DEL -+ * -+ */ -+#define WLFC_FLAGS_XONXOFF_SIGNALS 2 -+ -+/* enable (status, fifo_credit, mac_credit) signals -+ * WLFC_CTL_TYPE_MAC_REQUEST_CREDIT -+ * WLFC_CTL_TYPE_TXSTATUS -+ * WLFC_CTL_TYPE_FIFO_CREDITBACK -+ */ -+#define WLFC_FLAGS_CREDIT_STATUS_SIGNALS 4 -+ -+#define WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE 8 -+#define WLFC_FLAGS_PSQ_GENERATIONFSM_ENABLE 16 -+#define WLFC_FLAGS_PSQ_ZERO_BUFFER_ENABLE 32 -+#endif /* PROP_TXSTATUS */ -+ -+#define BTA_STATE_LOG_SZ 64 -+ -+/* BTAMP Statemachine states */ -+enum { -+ HCIReset = 1, -+ HCIReadLocalAMPInfo, -+ HCIReadLocalAMPASSOC, -+ HCIWriteRemoteAMPASSOC, -+ HCICreatePhysicalLink, -+ HCIAcceptPhysicalLinkRequest, -+ HCIDisconnectPhysicalLink, -+ HCICreateLogicalLink, -+ HCIAcceptLogicalLink, -+ HCIDisconnectLogicalLink, -+ HCILogicalLinkCancel, -+ HCIAmpStateChange, -+ HCIWriteLogicalLinkAcceptTimeout -+}; -+ -+typedef struct flush_txfifo { -+ uint32 txfifobmp; -+ uint32 hwtxfifoflush; -+ struct ether_addr ea; -+} flush_txfifo_t; -+ -+#define CHANNEL_5G_LOW_START 36 /* 5G low (36..48) CDD enable/disable bit mask */ -+#define CHANNEL_5G_MID_START 52 /* 5G mid (52..64) CDD enable/disable bit mask */ -+#define CHANNEL_5G_HIGH_START 100 /* 5G high (100..140) CDD enable/disable bit mask */ -+#define CHANNEL_5G_UPPER_START 149 /* 5G upper (149..161) CDD enable/disable bit mask */ -+ -+enum { -+ SPATIAL_MODE_2G_IDX = 0, -+ SPATIAL_MODE_5G_LOW_IDX, -+ SPATIAL_MODE_5G_MID_IDX, -+ SPATIAL_MODE_5G_HIGH_IDX, -+ SPATIAL_MODE_5G_UPPER_IDX, -+ SPATIAL_MODE_MAX_IDX -+}; -+ -+/* IOVAR "mempool" parameter. Used to retrieve a list of memory pool statistics. */ -+typedef struct wl_mempool_stats { -+ int num; /* Number of memory pools */ -+ bcm_mp_stats_t s[1]; /* Variable array of memory pool stats. */ -+} wl_mempool_stats_t; -+ -+/* Network Offload Engine */ -+#define NWOE_OL_ENABLE 0x00000001 -+ -+typedef struct { -+ uint32 ipaddr; -+ uint32 ipaddr_netmask; -+ uint32 ipaddr_gateway; -+} nwoe_ifconfig_t; -+ -+/* -+ * Traffic management structures/defines. -+ */ -+ -+/* Traffic management bandwidth parameters */ -+#define TRF_MGMT_MAX_PRIORITIES 3 -+ -+#define TRF_MGMT_FLAG_ADD_DSCP 0x0001 /* Add DSCP to IP TOS field */ -+#define TRF_MGMT_FLAG_DISABLE_SHAPING 0x0002 /* Only support traffic clasification */ -+ -+ -+/* Traffic management priority classes */ -+typedef enum trf_mgmt_priority_class { -+ trf_mgmt_priority_low = 0, /* Maps to 802.1p BK */ -+ trf_mgmt_priority_medium = 1, /* Maps to 802.1p BE */ -+ trf_mgmt_priority_high = 2, /* Maps to 802.1p VI */ -+ trf_mgmt_priority_invalid = (trf_mgmt_priority_high + 1) -+} trf_mgmt_priority_class_t; -+ -+/* Traffic management configuration parameters */ -+typedef struct trf_mgmt_config { -+ uint32 trf_mgmt_enabled; /* 0 - disabled, 1 - enabled */ -+ uint32 flags; /* See TRF_MGMT_FLAG_xxx defines */ -+ uint32 host_ip_addr; -+ uint32 host_subnet_mask; -+ uint32 downlink_bandwidth; /* In units of kbps */ -+ uint32 uplink_bandwidth; /* In units of kbps */ -+ uint32 min_tx_bandwidth[TRF_MGMT_MAX_PRIORITIES]; -+ uint32 min_rx_bandwidth[TRF_MGMT_MAX_PRIORITIES]; -+} trf_mgmt_config_t; -+ -+/* Traffic management filter */ -+typedef struct trf_mgmt_filter { -+ uint32 dst_ip_addr; /* His IP address */ -+ uint16 dst_port; /* His L4 port */ -+ uint16 src_port; /* My L4 port */ -+ uint16 prot; /* L4 protocol (only TCP or UDP protocols) */ -+ uint16 flags; /* TBD. For now, this must be zero. */ -+ trf_mgmt_priority_class_t priority; /* 802.1p priority for filtered packets */ -+} trf_mgmt_filter_t; -+ -+/* Traffic management filter list (variable length) */ -+typedef struct trf_mgmt_filter_list { -+ uint32 num_filters; -+ trf_mgmt_filter_t filter[1]; -+} trf_mgmt_filter_list_t; -+ -+/* Traffic management shaping info */ -+typedef struct trf_mgmt_shaping_info { -+ uint32 max_bps; /* Max bytes consumed or produced per second */ -+ uint32 max_bytes_per_sampling_period; /* Max bytes consumed or produced per sample */ -+ uint32 shaping_delay_threshold; /* Theshold for starting traffic delays */ -+ uint32 num_bytes_produced_per_sec; /* Bytes produced over the sampling period */ -+ uint32 num_bytes_consumed_per_sec; /* Bytes consumed over the sampling period */ -+} trf_mgmt_shaping_info_t; -+ -+/* Traffic management shaping info array */ -+typedef struct trf_mgmt_shaping_info_array { -+ trf_mgmt_shaping_info_t tx_queue_shaping_info[TRF_MGMT_MAX_PRIORITIES]; -+ trf_mgmt_shaping_info_t rx_queue_shaping_info[TRF_MGMT_MAX_PRIORITIES]; -+} trf_mgmt_shaping_info_array_t; -+ -+ -+/* Traffic management statistical counters */ -+typedef struct trf_mgmt_stats { -+ uint32 num_processed_packets; /* Number of packets processed */ -+ uint32 num_processed_bytes; /* Number of bytes processed */ -+ uint32 num_queued_packets; /* Number of packets in queue */ -+ uint32 num_queued_bytes; /* Number of bytes in queue */ -+ uint32 num_discarded_packets; /* Number of packets discarded from queue */ -+} trf_mgmt_stats_t; -+ -+/* Traffic management statisics array */ -+typedef struct trf_mgmt_stats_array { -+ trf_mgmt_stats_t tx_queue_stats[TRF_MGMT_MAX_PRIORITIES]; -+ trf_mgmt_stats_t rx_queue_stats[TRF_MGMT_MAX_PRIORITIES]; -+} trf_mgmt_stats_array_t; -+ -+#endif /* _wlioctl_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/aiutils.c b/drivers/net/ethernet/broadcom/gmac/src/shared/aiutils.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/aiutils.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/aiutils.c 2017-11-09 17:53:44.023292000 +0800 -@@ -0,0 +1,1028 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * Misc utility routines for accessing chip-specific features -+ * of the SiliconBackplane-based Broadcom chips. -+ * -+ * $Id: aiutils.c 327582 2012-04-14 05:02:37Z kenlo $ -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "siutils_priv.h" -+#if defined(CONFIG_MACH_HX4) -+#include "hx4_erom.h" -+#elif defined(CONFIG_MACH_HR2) -+#include "hr2_erom.h" -+#elif defined(CONFIG_MACH_KT2) -+#include "kt2_erom.h" -+#elif defined(CONFIG_MACH_GH) -+#include "gh_erom.h" -+#elif defined(CONFIG_MACH_SB2) -+#include "sb2_erom.h" -+#elif defined(CONFIG_MACH_HR3) -+#include "hr3_erom.h" -+#elif defined(CONFIG_MACH_GH2) -+#include "gh2_erom.h" -+#endif -+ -+/* EROM parsing */ -+static uint32 -+get_erom_ent(si_t *sih, uint32 **eromptr, uint32 mask, uint32 match) -+{ -+ uint32 ent; -+ uint inv = 0, nom = 0; -+ -+ while (TRUE) { -+ ent = **eromptr; -+ -+ (*eromptr)++; -+ -+ if (mask == 0) { -+ break; -+ } -+ -+ if ((ent & ER_VALID) == 0) { -+ inv++; -+ continue; -+ } -+ -+ if (ent == (ER_END | ER_VALID)) { -+ break; -+ } -+ -+ if ((ent & mask) == match) { -+ break; -+ } -+ -+ nom++; -+ } -+ -+ SI_VMSG(("%s: Returning ent 0x%08x\n", __FUNCTION__, ent)); -+ if (inv + nom) { -+ SI_VMSG((" after %d invalid and %d non-matching entries\n", inv, nom)); -+ } -+ return ent; -+} -+ -+static uint32 -+get_asd(si_t *sih, uint32 **eromptr, uint sp, uint ad, uint st, uint32 *addrl, uint32 *addrh, -+ uint32 *sizel, uint32 *sizeh) -+{ -+ uint32 asd, sz, szd; -+ -+ asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID); -+ if (((asd & ER_TAG1) != ER_ADD) || -+ (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) || -+ ((asd & AD_ST_MASK) != st)) { -+ /* This is not what we want, "push" it back */ -+ (*eromptr)--; -+ return 0; -+ } -+ *addrl = asd & AD_ADDR_MASK; -+ if (asd & AD_AG32) { -+ *addrh = get_erom_ent(sih, eromptr, 0, 0); -+ } else { -+ *addrh = 0; -+ } -+ *sizeh = 0; -+ sz = asd & AD_SZ_MASK; -+ if (sz == AD_SZ_SZD) { -+ szd = get_erom_ent(sih, eromptr, 0, 0); -+ *sizel = szd & SD_SZ_MASK; -+ if (szd & SD_SG32) { -+ *sizeh = get_erom_ent(sih, eromptr, 0, 0); -+ } -+ } else { -+ *sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT); -+ } -+ -+ SI_VMSG((" SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n", -+ sp, ad, st, *sizeh, *sizel, *addrh, *addrl)); -+ -+ return asd; -+} -+ -+/* parse the enumeration rom to identify all cores */ -+void -+BCMATTACHFN(ai_scan)(si_t *sih, void *regs, uint devid) -+{ -+ si_info_t *sii = SI_INFO(sih); -+ chipcregs_t *cc = (chipcregs_t *)regs; -+ uint32 erombase, *eromptr, *eromlim; -+ -+ erombase = R_REG(sii->osh, &cc->eromptr); -+ -+ switch (BUSTYPE(sih->bustype)) { -+ case SI_BUS: -+#if defined(CONFIG_MACH_HX4) -+ eromptr = hx4_erom; -+#elif defined(CONFIG_MACH_HR2) -+ eromptr = hr2_erom; -+#elif defined(CONFIG_MACH_KT2) -+ eromptr = kt2_erom; -+#elif defined(CONFIG_MACH_GH) -+ eromptr = gh_erom; -+#elif defined(CONFIG_MACH_SB2) -+ eromptr = sb2_erom; -+#elif defined(CONFIG_MACH_HR3) -+ eromptr = hr3_erom; -+#elif defined(CONFIG_MACH_GH2) -+ eromptr = gh2_erom; -+#endif -+ break; -+ -+ case PCI_BUS: -+ /* Set wrappers address */ -+ sii->curwrap = (void *)((uintptr)regs + SI_CORE_SIZE); -+ -+ /* Now point the window at the erom */ -+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, erombase); -+ eromptr = regs; -+ break; -+ -+ case PCMCIA_BUS: -+ default: -+ SI_ERROR(("Don't know how to do AXI enumertion on bus %d\n", sih->bustype)); -+ ASSERT(0); -+ return; -+ } -+ eromlim = eromptr + (ER_REMAPCONTROL / sizeof(uint32)); -+ -+ SI_VMSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n", -+ regs, erombase, eromptr, eromlim)); -+ while (eromptr < eromlim) { -+ uint32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp; -+ uint32 mpd, asd, addrl, addrh, sizel, sizeh; -+ uint i, j, idx; -+ bool br; -+ -+ br = FALSE; -+ -+ /* Grok a component */ -+ cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI); -+ if (cia == (ER_END | ER_VALID)) { -+ SI_VMSG(("Found END of erom after %d cores\n", sii->numcores)); -+ return; -+ } -+ -+ cib = get_erom_ent(sih, &eromptr, 0, 0); -+ -+ if ((cib & ER_TAG) != ER_CI) { -+ SI_ERROR(("CIA not followed by CIB\n")); -+ goto error; -+ } -+ -+ cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT; -+ mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT; -+ crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT; -+ nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT; -+ nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT; -+ nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT; -+ nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT; -+ -+#ifdef BCMDBG_SI -+ SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, " -+ "nsw = %d, nmp = %d & nsp = %d\n", -+ mfg, cid, crev, eromptr - 1, nmw, nsw, nmp, nsp)); -+#else -+ BCM_REFERENCE(crev); -+#endif -+ -+ if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0)) { -+ continue; -+ } -+ -+ if ((nmw + nsw == 0)) { -+ /* A component which is not a core */ -+ /* XXX: Should record some info */ -+ if (cid == OOB_ROUTER_CORE_ID) { -+ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, -+ &addrl, &addrh, &sizel, &sizeh); -+ if (asd != 0) { -+ sii->oob_router = addrl; -+ } -+ } -+ if (cid != GMAC_COMMON_4706_CORE_ID) { -+ continue; -+ } -+ } -+ -+ idx = sii->numcores; -+ -+ sii->cia[idx] = cia; -+ sii->cib[idx] = cib; -+ sii->coreid[idx] = cid; -+ -+ for (i = 0; i < nmp; i++) { -+ mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID); -+ if ((mpd & ER_TAG) != ER_MP) { -+ SI_ERROR(("Not enough MP entries for component 0x%x\n", cid)); -+ goto error; -+ } -+ /* XXX: Record something? */ -+ SI_VMSG((" Master port %d, mp: %d id: %d\n", i, -+ (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT, -+ (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT)); -+ } -+ -+ /* First Slave Address Descriptor should be port 0: -+ * the main register space for the core -+ */ -+ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, &sizel, &sizeh); -+ if (asd == 0) { -+ do { -+ /* Try again to see if it is a bridge */ -+ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, &addrh, -+ &sizel, &sizeh); -+ if (asd != 0) { -+ br = TRUE; -+ } else { -+ if (br == TRUE) { -+ break; -+ } else if ((addrh != 0) || (sizeh != 0) || -+ (sizel != SI_CORE_SIZE)) { -+ /* XXX: Could we have sizel != 4KB? */ -+ SI_ERROR(("addrh = 0x%x\t sizeh = 0x%x\t size1 =" -+ "0x%x\n", addrh, sizeh, sizel)); -+ SI_ERROR(("First Slave ASD for" -+ "core 0x%04x malformed " -+ "(0x%08x)\n", cid, asd)); -+ goto error; -+ } -+ } -+ } while (1); -+ } -+ sii->coresba[idx] = addrl; -+ sii->coresba_size[idx] = sizel; -+ /* Get any more ASDs in port 0 */ -+ j = 1; -+ do { -+ asd = get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, &addrh, -+ &sizel, &sizeh); -+ if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) { -+ sii->coresba2[idx] = addrl; -+ sii->coresba2_size[idx] = sizel; -+ } -+ j++; -+ } while (asd != 0); -+ -+ /* Go through the ASDs for other slave ports */ -+ for (i = 1; i < nsp; i++) { -+ j = 0; -+ do { -+ asd = get_asd(sih, &eromptr, i, j, AD_ST_SLAVE, &addrl, &addrh, -+ &sizel, &sizeh); -+ /* XXX: Should record them so we can do error recovery later */ -+ -+ if (asd == 0) -+ break; -+ j++; -+ } while (1); -+ if (j == 0) { -+ SI_ERROR((" SP %d has no address descriptors\n", i)); -+ goto error; -+ } -+ } -+ -+ /* Now get master wrappers */ -+ for (i = 0; i < nmw; i++) { -+ asd = get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl, &addrh, -+ &sizel, &sizeh); -+ if (asd == 0) { -+ SI_ERROR(("Missing descriptor for MW %d\n", i)); -+ goto error; -+ } -+ if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { -+ SI_ERROR(("Master wrapper %d is not 4KB\n", i)); -+ goto error; -+ } -+ if (i == 0) { -+ sii->wrapba[idx] = addrl; -+ } -+ } -+ -+ /* And finally slave wrappers */ -+ for (i = 0; i < nsw; i++) { -+ uint fwp = (nsp == 1) ? 0 : 1; -+ asd = get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP, &addrl, &addrh, -+ &sizel, &sizeh); -+ if (asd == 0) { -+ SI_ERROR(("Missing descriptor for SW %d\n", i)); -+ goto error; -+ } -+ if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { -+ SI_ERROR(("Slave wrapper %d is not 4KB\n", i)); -+ goto error; -+ } -+ if ((nmw == 0) && (i == 0)) { -+ sii->wrapba[idx] = addrl; -+ } -+ } -+ -+ /* Don't record bridges */ -+ if (br) { -+ continue; -+ } -+ -+ /* Done with core */ -+ sii->numcores++; -+ } -+ -+ SI_ERROR(("Reached end of erom without finding END")); -+ -+error: -+ sii->numcores = 0; -+ return; -+} -+ -+/* This function changes the logical "focus" to the indicated core. -+ * Return the current core's virtual address. -+ */ -+void * -+ai_setcoreidx(si_t *sih, uint coreidx) -+{ -+ si_info_t *sii = SI_INFO(sih); -+ uint32 addr, wrap; -+ void *regs; -+ -+ if (coreidx >= MIN(sii->numcores, SI_MAXCORES)) { -+ return (NULL); -+ } -+ -+ addr = sii->coresba[coreidx]; -+ wrap = sii->wrapba[coreidx]; -+ -+ /* -+ * If the user has provided an interrupt mask enabled function, -+ * then assert interrupts are disabled before switching the core. -+ */ -+ ASSERT((sii->intrsenabled_fn == NULL) || !(*(sii)->intrsenabled_fn)((sii)->intr_arg)); -+ -+ switch (BUSTYPE(sih->bustype)) { -+ case SI_BUS: -+ /* map new one */ -+ if (!sii->regs[coreidx]) { -+ sii->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE); -+ ASSERT(GOODREGS(sii->regs[coreidx])); -+ } -+ sii->curmap = regs = sii->regs[coreidx]; -+ if (!sii->wrappers[coreidx]) { -+ sii->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE); -+ ASSERT(GOODREGS(sii->wrappers[coreidx])); -+ } -+ sii->curwrap = sii->wrappers[coreidx]; -+ break; -+ -+ case PCI_BUS: -+ /* point bar0 window */ -+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, addr); -+ regs = sii->curmap; -+ /* point bar0 2nd 4KB window to the primary wrapper */ -+ if (PCIE_GEN2(sii)) { -+ OSL_PCI_WRITE_CONFIG(sii->osh, PCIE2_BAR0_WIN2, 4, wrap); -+ } else { -+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN2, 4, wrap); -+ } -+ break; -+ -+ case PCMCIA_BUS: -+ default: -+ ASSERT(0); -+ regs = NULL; -+ break; -+ } -+ -+ sii->curmap = regs; -+ sii->curidx = coreidx; -+ -+ return regs; -+} -+ -+void -+ai_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size) -+{ -+ si_info_t *sii = SI_INFO(sih); -+ chipcregs_t *cc = NULL; -+ uint32 erombase, *eromptr, *eromlim; -+ uint i, j, cidx; -+ uint32 cia, cib, nmp, nsp; -+ uint32 asd, addrl, addrh, sizel, sizeh; -+ -+ for (i = 0; i < sii->numcores; i++) { -+ if (sii->coreid[i] == CC_CORE_ID) { -+ cc = (chipcregs_t *)sii->regs[i]; -+ break; -+ } -+ } -+ if (cc == NULL) { -+ goto error; -+ } -+ -+ erombase = R_REG(sii->osh, &cc->eromptr); -+ eromptr = (uint32 *)REG_MAP(erombase, SI_CORE_SIZE); -+ eromlim = eromptr + (ER_REMAPCONTROL / sizeof(uint32)); -+ -+ cidx = sii->curidx; -+ cia = sii->cia[cidx]; -+ cib = sii->cib[cidx]; -+ -+ nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT; -+ nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT; -+ -+ /* scan for cores */ -+ while (eromptr < eromlim) { -+ if ((get_erom_ent(sih, &eromptr, ER_TAG, ER_CI) == cia) && -+ (get_erom_ent(sih, &eromptr, 0, 0) == cib)) { -+ break; -+ } -+ } -+ -+ /* skip master ports */ -+ for (i = 0; i < nmp; i++) { -+ get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID); -+ } -+ -+ /* Skip ASDs in port 0 */ -+ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, &sizel, &sizeh); -+ if (asd == 0) { -+ /* Try again to see if it is a bridge */ -+ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, &addrh, -+ &sizel, &sizeh); -+ } -+ -+ j = 1; -+ do { -+ asd = get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, &addrh, -+ &sizel, &sizeh); -+ j++; -+ } while (asd != 0); -+ -+ /* Go through the ASDs for other slave ports */ -+ for (i = 1; i < nsp; i++) { -+ j = 0; -+ do { -+ asd = get_asd(sih, &eromptr, i, j, AD_ST_SLAVE, &addrl, &addrh, -+ &sizel, &sizeh); -+ if (asd == 0) { -+ break; -+ } -+ -+ if (!asidx--) { -+ *addr = addrl; -+ *size = sizel; -+ return; -+ } -+ j++; -+ } while (1); -+ -+ if (j == 0) { -+ SI_ERROR((" SP %d has no address descriptors\n", i)); -+ break; -+ } -+ } -+ -+error: -+ *size = 0; -+ return; -+} -+ -+/* Return the number of address spaces in current core */ -+int -+ai_numaddrspaces(si_t *sih) -+{ -+ /* XXX: Either save ot or parse the EROM on demand */ -+ return 2; -+} -+ -+/* Return the address of the nth address space in the current core */ -+uint32 -+ai_addrspace(si_t *sih, uint asidx) -+{ -+ si_info_t *sii; -+ uint cidx; -+ -+ sii = SI_INFO(sih); -+ cidx = sii->curidx; -+ -+ if (asidx == 0) { -+ return sii->coresba[cidx]; -+ } else if (asidx == 1) { -+ return sii->coresba2[cidx]; -+ } else { -+ SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", -+ __FUNCTION__, asidx)); -+ return 0; -+ } -+} -+ -+/* Return the size of the nth address space in the current core */ -+uint32 -+ai_addrspacesize(si_t *sih, uint asidx) -+{ -+ si_info_t *sii; -+ uint cidx; -+ -+ sii = SI_INFO(sih); -+ cidx = sii->curidx; -+ -+ if (asidx == 0) { -+ return sii->coresba_size[cidx]; -+ } else if (asidx == 1) { -+ return sii->coresba2_size[cidx]; -+ } else { -+ SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", -+ __FUNCTION__, asidx)); -+ return 0; -+ } -+} -+ -+uint -+ai_flag(si_t *sih) -+{ -+ si_info_t *sii; -+ aidmp_t *ai; -+ -+ sii = SI_INFO(sih); -+ ai = sii->curwrap; -+ return (R_REG(sii->osh, &ai->oobselouta30) & 0x1f); -+} -+ -+void -+ai_setint(si_t *sih, int siflag) -+{ -+ /* XXX: Figure out OOB stuff */ -+} -+ -+uint -+ai_wrap_reg(si_t *sih, uint32 offset, uint32 mask, uint32 val) -+{ -+ si_info_t *sii = SI_INFO(sih); -+ uint32 *map = (uint32 *) sii->curwrap; -+ -+ if (mask || val) { -+ uint32 w = R_REG(sii->osh, map+(offset/4)); -+ w &= ~mask; -+ w |= val; -+ W_REG(sii->osh, map+(offset/4), val); -+ } -+ -+ return (R_REG(sii->osh, map+(offset/4))); -+} -+ -+uint -+ai_corevendor(si_t *sih) -+{ -+ si_info_t *sii; -+ uint32 cia; -+ -+ sii = SI_INFO(sih); -+ cia = sii->cia[sii->curidx]; -+ return ((cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT); -+} -+ -+uint -+ai_corerev(si_t *sih) -+{ -+ si_info_t *sii; -+ uint32 cib; -+ -+ sii = SI_INFO(sih); -+ cib = sii->cib[sii->curidx]; -+ return ((cib & CIB_REV_MASK) >> CIB_REV_SHIFT); -+} -+ -+bool -+ai_iscoreup(si_t *sih) -+{ -+ si_info_t *sii; -+ aidmp_t *ai; -+ -+ sii = SI_INFO(sih); -+ ai = sii->curwrap; -+ -+ return (((R_REG(sii->osh, &ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) == SICF_CLOCK_EN) && -+ ((R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) == 0)); -+} -+ -+/* -+ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, -+ * switch back to the original core, and return the new value. -+ * -+ * When using the silicon backplane, no fiddling with interrupts or core switches is needed. -+ * -+ * Also, when using pci/pcie, we can optimize away the core switching for pci registers -+ * and (on newer pci cores) chipcommon registers. -+ */ -+uint -+ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -+{ -+ uint origidx = 0; -+ uint32 *r = NULL; -+ uint w; -+ uint intr_val = 0; -+ bool fast = FALSE; -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ -+ ASSERT(GOODIDX(coreidx)); -+ ASSERT(regoff < SI_CORE_SIZE); -+ ASSERT((val & ~mask) == 0); -+ -+ if (coreidx >= SI_MAXCORES) { -+ return 0; -+ } -+ -+ if (BUSTYPE(sih->bustype) == SI_BUS) { -+ /* If internal bus, we can always get at everything */ -+ fast = TRUE; -+ /* map if does not exist */ -+ if (!sii->regs[coreidx]) { -+ sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx], -+ SI_CORE_SIZE); -+ ASSERT(GOODREGS(sii->regs[coreidx])); -+ } -+ r = (uint32 *)((uchar *)sii->regs[coreidx] + regoff); -+ } else if (BUSTYPE(sih->bustype) == PCI_BUS) { -+ /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */ -+ -+ if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) { -+ /* Chipc registers are mapped at 12KB */ -+ -+ fast = TRUE; -+ r = (uint32 *)((char *)sii->curmap + PCI_16KB0_CCREGS_OFFSET + regoff); -+ } else if (sii->pub.buscoreidx == coreidx) { -+ /* pci registers are at either in the last 2KB of an 8KB window -+ * or, in pcie and pci rev 13 at 8KB -+ */ -+ fast = TRUE; -+ if (SI_FAST(sii)) { -+ r = (uint32 *)((char *)sii->curmap + -+ PCI_16KB0_PCIREGS_OFFSET + regoff); -+ } else { -+ r = (uint32 *)((char *)sii->curmap + -+ ((regoff >= SBCONFIGOFF) ? -+ PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) + -+ regoff); -+ } -+ } -+ } -+ -+ if (!fast) { -+ INTR_OFF(sii, intr_val); -+ -+ /* save current core index */ -+ origidx = si_coreidx(&sii->pub); -+ -+ /* switch core */ -+ r = (uint32*) ((uchar*) ai_setcoreidx(&sii->pub, coreidx) + regoff); -+ } -+ ASSERT(r != NULL); -+ -+ /* mask and set */ -+ if (mask || val) { -+ w = (R_REG(sii->osh, r) & ~mask) | val; -+ W_REG(sii->osh, r, w); -+ } -+ -+ /* readback */ -+ w = R_REG(sii->osh, r); -+ -+ if (!fast) { -+ /* restore core index */ -+ if (origidx != coreidx) { -+ ai_setcoreidx(&sii->pub, origidx); -+ } -+ -+ INTR_RESTORE(sii, intr_val); -+ } -+ -+ return (w); -+} -+ -+void -+ai_core_disable(si_t *sih, uint32 bits) -+{ -+ si_info_t *sii; -+ volatile uint32 dummy; -+ uint32 status; -+ aidmp_t *ai; -+ -+ sii = SI_INFO(sih); -+ -+ ASSERT(GOODREGS(sii->curwrap)); -+ ai = sii->curwrap; -+ -+ /* if core is already in reset, just return */ -+ if (R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) { -+ return; -+ } -+ -+ /* ensure there are no pending backplane operations */ -+ SPINWAIT(((status = R_REG(sii->osh, &ai->resetstatus)) != 0), 300); -+ -+ /* if pending backplane ops still, try waiting longer */ -+ if (status != 0) { -+ /* 300usecs was sufficient to allow backplane ops to clear for big hammer */ -+ /* during driver load we may need more time */ -+ SPINWAIT(((status = R_REG(sii->osh, &ai->resetstatus)) != 0), 10000); -+ /* if still pending ops, continue on and try disable anyway */ -+ /* this is in big hammer path, so don't call wl_reinit in this case... */ -+#ifdef BCMDBG -+ if (status != 0) { -+ printf("%s: WARN: resetstatus=%0x on core disable\n", __FUNCTION__, status); -+ } -+#endif -+ } -+ -+ W_REG(sii->osh, &ai->ioctrl, bits); -+ dummy = R_REG(sii->osh, &ai->ioctrl); -+ BCM_REFERENCE(dummy); -+ OSL_DELAY(10); -+ -+ W_REG(sii->osh, &ai->resetctrl, AIRC_RESET); -+ dummy = R_REG(sii->osh, &ai->resetctrl); -+ BCM_REFERENCE(dummy); -+ OSL_DELAY(1); -+} -+ -+/* reset and re-enable a core -+ * inputs: -+ * bits - core specific bits that are set during and after reset sequence -+ * resetbits - core specific bits that are set only during reset sequence -+ */ -+void -+ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits) -+{ -+ si_info_t *sii; -+ aidmp_t *ai; -+ volatile uint32 dummy; -+ -+ sii = SI_INFO(sih); -+ ASSERT(GOODREGS(sii->curwrap)); -+ ai = sii->curwrap; -+ -+#ifdef CONFIG_BCM_IPROC_GMAC_ACP -+ bits = resetbits = R_REG(sii->osh, &ai->ioctrl) & 0xFFFFFFFC; -+#endif /* CONFIG_BCM_IPROC_GMAC_ACP */ -+ -+ /* -+ * Must do the disable sequence first to work for arbitrary current core state. -+ */ -+ ai_core_disable(sih, (bits | resetbits)); -+ -+ /* -+ * Now do the initialization sequence. -+ */ -+ W_REG(sii->osh, &ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN)); -+ dummy = R_REG(sii->osh, &ai->ioctrl); -+ BCM_REFERENCE(dummy); -+ -+ W_REG(sii->osh, &ai->resetctrl, 0); -+ dummy = R_REG(sii->osh, &ai->resetctrl); -+ BCM_REFERENCE(dummy); -+ OSL_DELAY(1); -+ -+ W_REG(sii->osh, &ai->ioctrl, (bits | SICF_CLOCK_EN)); -+ dummy = R_REG(sii->osh, &ai->ioctrl); -+ BCM_REFERENCE(dummy); -+ OSL_DELAY(1); -+} -+ -+void -+ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) -+{ -+ si_info_t *sii; -+ aidmp_t *ai; -+ uint32 w; -+ -+ sii = SI_INFO(sih); -+ -+ ASSERT(GOODREGS(sii->curwrap)); -+ ai = sii->curwrap; -+ -+ ASSERT((val & ~mask) == 0); -+ -+ if (mask || val) { -+ w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val); -+ W_REG(sii->osh, &ai->ioctrl, w); -+ } -+} -+ -+uint32 -+ai_core_cflags(si_t *sih, uint32 mask, uint32 val) -+{ -+ si_info_t *sii; -+ aidmp_t *ai; -+ uint32 w; -+ -+ sii = SI_INFO(sih); -+ -+ ASSERT(GOODREGS(sii->curwrap)); -+ ai = sii->curwrap; -+ -+ ASSERT((val & ~mask) == 0); -+ -+ if (mask || val) { -+ w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val); -+ W_REG(sii->osh, &ai->ioctrl, w); -+ } -+ -+ return R_REG(sii->osh, &ai->ioctrl); -+} -+ -+uint32 -+ai_core_sflags(si_t *sih, uint32 mask, uint32 val) -+{ -+ si_info_t *sii; -+ aidmp_t *ai; -+ uint32 w; -+ -+ sii = SI_INFO(sih); -+ -+ ASSERT(GOODREGS(sii->curwrap)); -+ ai = sii->curwrap; -+ -+ ASSERT((val & ~mask) == 0); -+ ASSERT((mask & ~SISF_CORE_BITS) == 0); -+ -+ if (mask || val) { -+ w = ((R_REG(sii->osh, &ai->iostatus) & ~mask) | val); -+ W_REG(sii->osh, &ai->iostatus, w); -+ } -+ -+ return R_REG(sii->osh, &ai->iostatus); -+} -+ -+#if defined(BCMDBG) || defined(BCMDBG_DUMP) -+/* print interesting aidmp registers */ -+void -+ai_dumpregs(si_t *sih, struct bcmstrbuf *b) -+{ -+ si_info_t *sii; -+ osl_t *osh; -+ aidmp_t *ai; -+ uint i; -+ -+ sii = SI_INFO(sih); -+ osh = sii->osh; -+ -+ for (i = 0; i < sii->numcores; i++) { -+ si_setcoreidx(&sii->pub, i); -+ ai = sii->curwrap; -+ -+ bcm_bprintf(b, "core 0x%x: \n", sii->coreid[i]); -+ bcm_bprintf(b, "ioctrlset 0x%x ioctrlclear 0x%x ioctrl 0x%x iostatus 0x%x" -+ "ioctrlwidth 0x%x iostatuswidth 0x%x\n" -+ "resetctrl 0x%x resetstatus 0x%x resetreadid 0x%x resetwriteid 0x%x\n" -+ "errlogctrl 0x%x errlogdone 0x%x errlogstatus 0x%x" -+ "errlogaddrlo 0x%x errlogaddrhi 0x%x\n" -+ "errlogid 0x%x errloguser 0x%x errlogflags 0x%x\n" -+ "intstatus 0x%x config 0x%x itcr 0x%x\n", -+ R_REG(osh, &ai->ioctrlset), -+ R_REG(osh, &ai->ioctrlclear), -+ R_REG(osh, &ai->ioctrl), -+ R_REG(osh, &ai->iostatus), -+ R_REG(osh, &ai->ioctrlwidth), -+ R_REG(osh, &ai->iostatuswidth), -+ R_REG(osh, &ai->resetctrl), -+ R_REG(osh, &ai->resetstatus), -+ R_REG(osh, &ai->resetreadid), -+ R_REG(osh, &ai->resetwriteid), -+ R_REG(osh, &ai->errlogctrl), -+ R_REG(osh, &ai->errlogdone), -+ R_REG(osh, &ai->errlogstatus), -+ R_REG(osh, &ai->errlogaddrlo), -+ R_REG(osh, &ai->errlogaddrhi), -+ R_REG(osh, &ai->errlogid), -+ R_REG(osh, &ai->errloguser), -+ R_REG(osh, &ai->errlogflags), -+ R_REG(osh, &ai->intstatus), -+ R_REG(osh, &ai->config), -+ R_REG(osh, &ai->itcr)); -+ } -+} -+#endif /* BCMDBG || BCMDBG_DUMP */ -+ -+#ifdef BCMDBG -+static void -+_ai_view(osl_t *osh, aidmp_t *ai, uint32 cid, uint32 addr, bool verbose) -+{ -+ uint32 config; -+ -+ config = R_REG(osh, &ai->config); -+ SI_ERROR(("\nCore ID: 0x%x, addr 0x%x, config 0x%x\n", cid, addr, config)); -+ -+ if (config & AICFG_RST) { -+ SI_ERROR(("resetctrl 0x%x, resetstatus 0x%x, resetreadid 0x%x, resetwriteid 0x%x\n", -+ R_REG(osh, &ai->resetctrl), R_REG(osh, &ai->resetstatus), -+ R_REG(osh, &ai->resetreadid), R_REG(osh, &ai->resetwriteid))); -+ } -+ -+ if (config & AICFG_IOC) { -+ SI_ERROR(("ioctrl 0x%x, width %d\n", R_REG(osh, &ai->ioctrl), -+ R_REG(osh, &ai->ioctrlwidth))); -+ } -+ -+ if (config & AICFG_IOS) { -+ SI_ERROR(("iostatus 0x%x, width %d\n", R_REG(osh, &ai->iostatus), -+ R_REG(osh, &ai->iostatuswidth))); -+ } -+ -+ if (config & AICFG_ERRL) { -+ SI_ERROR(("errlogctrl 0x%x, errlogdone 0x%x, errlogstatus 0x%x, intstatus 0x%x\n", -+ R_REG(osh, &ai->errlogctrl), R_REG(osh, &ai->errlogdone), -+ R_REG(osh, &ai->errlogstatus), R_REG(osh, &ai->intstatus))); -+ SI_ERROR(("errlogid 0x%x, errloguser 0x%x, errlogflags 0x%x, errlogaddr " -+ "0x%x/0x%x\n", -+ R_REG(osh, &ai->errlogid), R_REG(osh, &ai->errloguser), -+ R_REG(osh, &ai->errlogflags), R_REG(osh, &ai->errlogaddrhi), -+ R_REG(osh, &ai->errlogaddrlo))); -+ } -+ -+ if (verbose && (config & AICFG_OOB)) { -+ SI_ERROR(("oobselina30 0x%x, oobselina74 0x%x\n", -+ R_REG(osh, &ai->oobselina30), R_REG(osh, &ai->oobselina74))); -+ SI_ERROR(("oobselinb30 0x%x, oobselinb74 0x%x\n", -+ R_REG(osh, &ai->oobselinb30), R_REG(osh, &ai->oobselinb74))); -+ SI_ERROR(("oobselinc30 0x%x, oobselinc74 0x%x\n", -+ R_REG(osh, &ai->oobselinc30), R_REG(osh, &ai->oobselinc74))); -+ SI_ERROR(("oobselind30 0x%x, oobselind74 0x%x\n", -+ R_REG(osh, &ai->oobselind30), R_REG(osh, &ai->oobselind74))); -+ SI_ERROR(("oobselouta30 0x%x, oobselouta74 0x%x\n", -+ R_REG(osh, &ai->oobselouta30), R_REG(osh, &ai->oobselouta74))); -+ SI_ERROR(("oobseloutb30 0x%x, oobseloutb74 0x%x\n", -+ R_REG(osh, &ai->oobseloutb30), R_REG(osh, &ai->oobseloutb74))); -+ SI_ERROR(("oobseloutc30 0x%x, oobseloutc74 0x%x\n", -+ R_REG(osh, &ai->oobseloutc30), R_REG(osh, &ai->oobseloutc74))); -+ SI_ERROR(("oobseloutd30 0x%x, oobseloutd74 0x%x\n", -+ R_REG(osh, &ai->oobseloutd30), R_REG(osh, &ai->oobseloutd74))); -+ SI_ERROR(("oobsynca 0x%x, oobseloutaen 0x%x\n", -+ R_REG(osh, &ai->oobsynca), R_REG(osh, &ai->oobseloutaen))); -+ SI_ERROR(("oobsyncb 0x%x, oobseloutben 0x%x\n", -+ R_REG(osh, &ai->oobsyncb), R_REG(osh, &ai->oobseloutben))); -+ SI_ERROR(("oobsyncc 0x%x, oobseloutcen 0x%x\n", -+ R_REG(osh, &ai->oobsyncc), R_REG(osh, &ai->oobseloutcen))); -+ SI_ERROR(("oobsyncd 0x%x, oobseloutden 0x%x\n", -+ R_REG(osh, &ai->oobsyncd), R_REG(osh, &ai->oobseloutden))); -+ SI_ERROR(("oobaextwidth 0x%x, oobainwidth 0x%x, oobaoutwidth 0x%x\n", -+ R_REG(osh, &ai->oobaextwidth), R_REG(osh, &ai->oobainwidth), -+ R_REG(osh, &ai->oobaoutwidth))); -+ SI_ERROR(("oobbextwidth 0x%x, oobbinwidth 0x%x, oobboutwidth 0x%x\n", -+ R_REG(osh, &ai->oobbextwidth), R_REG(osh, &ai->oobbinwidth), -+ R_REG(osh, &ai->oobboutwidth))); -+ SI_ERROR(("oobcextwidth 0x%x, oobcinwidth 0x%x, oobcoutwidth 0x%x\n", -+ R_REG(osh, &ai->oobcextwidth), R_REG(osh, &ai->oobcinwidth), -+ R_REG(osh, &ai->oobcoutwidth))); -+ SI_ERROR(("oobdextwidth 0x%x, oobdinwidth 0x%x, oobdoutwidth 0x%x\n", -+ R_REG(osh, &ai->oobdextwidth), R_REG(osh, &ai->oobdinwidth), -+ R_REG(osh, &ai->oobdoutwidth))); -+ } -+} -+ -+void -+ai_view(si_t *sih, bool verbose) -+{ -+ si_info_t *sii; -+ osl_t *osh; -+ aidmp_t *ai; -+ uint32 cid, addr; -+ -+ sii = SI_INFO(sih); -+ ai = sii->curwrap; -+ osh = sii->osh; -+ -+ cid = sii->coreid[sii->curidx]; -+ addr = sii->wrapba[sii->curidx]; -+ _ai_view(osh, ai, cid, addr, verbose); -+} -+ -+void -+ai_viewall(si_t *sih, bool verbose) -+{ -+ si_info_t *sii; -+ osl_t *osh; -+ aidmp_t *ai; -+ uint32 cid, addr; -+ uint i; -+ -+ sii = SI_INFO(sih); -+ osh = sii->osh; -+ for (i = 0; i < sii->numcores; i++) { -+ si_setcoreidx(sih, i); -+ -+ ai = sii->curwrap; -+ cid = sii->coreid[sii->curidx]; -+ addr = sii->wrapba[sii->curidx]; -+ _ai_view(osh, ai, cid, addr, verbose); -+ } -+} -+#endif /* BCMDBG */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_egphy28.c b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_egphy28.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_egphy28.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_egphy28.c 2017-11-09 17:53:44.024296000 +0800 -@@ -0,0 +1,352 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * These routines provide access to the external phy -+ * -+ */ -+#include -+#include -+#include "../../../mdio/iproc_mdio.h" -+#include "bcmiproc_phy.h" -+#include "bcmiproc_egphy28.h" -+ -+/* debug/trace */ -+//#define BCMDBG -+//#define BCMDBG_ERR -+#ifdef BCMDBG -+#define NET_ERROR(args) printf args -+#define NET_TRACE(args) printf args -+#elif defined(BCMDBG_ERR) -+#define NET_ERROR(args) printf args -+#define NET_TRACE(args) -+#else -+#define NET_ERROR(args) -+#define NET_TRACE(args) -+#endif /* BCMDBG */ -+#define NET_REG_TRACE(args) -+ -+extern u32 cmicd_schan_write(void __iomem *base, u32 ctrl, u32 addr, u32 val); -+extern u32 cmicd_schan_read(void __iomem *base, u32 ctrl, u32 addr); -+ -+ -+static int -+egphy28_rdb_reg_read(u32 phy_addr, u32 reg_addr, u16 *data) -+{ -+ int rv = SOC_E_NONE; -+ -+ /* MDIO write the RDB reg. address to reg.0x1E = */ -+ iproc_mii_write(MII_DEV_LOCAL, phy_addr, EGPHY28_REG_RDB_ADDR, -+ (0xffff & reg_addr)); -+ -+ /* MDIO read from reg.0x1F to get the RDB register's value as */ -+ iproc_mii_read(MII_DEV_LOCAL, phy_addr, EGPHY28_REG_RDB_DATA, data); -+ -+ return rv; -+} -+ -+static int -+egphy28_rdb_reg_write(u32 phy_addr, u32 reg_addr, u16 data) -+{ -+ int rv = SOC_E_NONE; -+ -+ /* MDIO write the RDB reg. address to reg.0x1E = */ -+ iproc_mii_write(MII_DEV_LOCAL, phy_addr, EGPHY28_REG_RDB_ADDR, -+ (0xffff & reg_addr)); -+ -+ /* MDIO write to reg.0x1F to set the RDB resister's value as */ -+ iproc_mii_write(MII_DEV_LOCAL, phy_addr, EGPHY28_REG_RDB_DATA, data); -+ -+ return rv; -+} -+ -+static void -+egphy28_rdb_reg_modify(u32 phy_addr, int reg_addr, u16 data, u16 mask) -+{ -+ u16 ori_data; -+ -+ egphy28_rdb_reg_read(phy_addr, reg_addr, &ori_data); -+ ori_data &= ~mask; -+ ori_data |= (data & mask); -+ egphy28_rdb_reg_write(phy_addr, reg_addr, ori_data); -+} -+ -+int -+egphy28_reg_read(u32 phy_addr, int reg_addr, u16 *data) -+{ -+ int rv = SOC_E_NONE; -+ iproc_mii_read(MII_DEV_LOCAL, phy_addr, reg_addr, data); -+ -+ return rv; -+} -+ -+int -+egphy28_reg_write(u32 phy_addr, int reg_addr, u16 data) -+{ -+ int rv = SOC_E_NONE; -+ iproc_mii_write(MII_DEV_LOCAL, phy_addr, reg_addr, data); -+ -+ return rv; -+} -+ -+static void -+egphy28_reg_modify(u32 phy_addr, int reg_addr, u16 data, u16 mask) -+{ -+ u16 ori_data; -+ -+ egphy28_reg_read(phy_addr, reg_addr, &ori_data); -+ ori_data &= ~mask; -+ ori_data |= (data & mask); -+ egphy28_reg_write(phy_addr, reg_addr, ori_data); -+} -+ -+static int -+egphy28_ge_reset(u32 phy_addr) -+{ -+ int rv = SOC_E_NONE; -+ u16 val; -+ -+ NET_TRACE(("%s: phy_addr %d\n", __FUNCTION__, phy_addr)); -+ -+ /* Reset the PHY */ -+ egphy28_reg_read(phy_addr, EGPHY28_COPPER_MII_CTRL, &val); -+ val |= BMCR_RESET; -+ egphy28_reg_write(phy_addr, EGPHY28_COPPER_MII_CTRL, val); -+ -+ SPINWAIT((!egphy28_reg_read(phy_addr, EGPHY28_COPPER_MII_CTRL, &val) && -+ (val & BMCR_RESET)), 100000); -+ -+ /* Check if out of reset */ -+ egphy28_reg_read(phy_addr, EGPHY28_COPPER_MII_CTRL, &val); -+ if (val & BMCR_RESET) { -+ NET_ERROR(("%s reset not complete\n", __FUNCTION__)); -+ rv = SOC_E_TIMEOUT; -+ } else { -+ NET_TRACE(("%s reset complete\n", __FUNCTION__)); -+ } -+ -+ return rv; -+} -+ -+ -+#if 0 -+static void -+cmid_schan_modify(void __iomem *base, u32 ctrl, u32 addr, u32 val, u32 mask) -+{ -+ u32 ori_val; -+ -+ ori_val = cmicd_schan_read(base, ctrl, addr); -+ ori_val &= ~mask; -+ ori_val |= (val & mask); -+ cmicd_schan_write(base, ctrl, addr, ori_val); -+} -+#endif -+ -+ -+static int -+egphy28_ge_init(void __iomem *base, u32 phy_addr) -+{ -+ int rv = SOC_E_NONE; -+ /* ==== Power up PHY ==== */ -+#if 0 -+ /* Give initial value */ -+ /* TOP_QGPHY_CTRL_0.EXT_PWRDOWN[23:20] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033800, 0x0, 0x00F00000); -+ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = HIGH */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x40000, 0x040000); -+ /* TOP_QGPHY_CTRL_2.IDDQ_BIAS[5] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x20); -+ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x0, 0x200000); -+ -+ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x040000); -+ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = HIGH */ -+ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x200000, 0x200000); -+ -+ /* ==== Partial Power down other 3 PHYs ==== */ -+ -+ /* Give initial value */ -+ /* TOP_QGPHY_CTRL_0.EXT_PWRDOWN[22:20] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033800, 0x0, 0x00700000); -+ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = HIGH */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x40000, 0x040000); -+ /* TOP_QGPHY_CTRL_2.IDDQ_BIAS[5] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x20); -+ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x0, 0x200000); -+ -+ /* TOP_QGPHY_CTRL_0.EXT_PWRDOWN[22:20] = HIGH */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033800, 0x00700000, 0x00700000); -+ /* TOP_QGPHY_CTRL_2.IDDQ_BIAS[5] = HIGH */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x20, 0x20); -+ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = HIGH */ -+ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x200000, 0x200000); -+ -+ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x040000); -+ /* TOP_QGPHY_CTRL_2.IDDQ_BIAS[5] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x20); -+ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x0, 0x200000); -+ -+ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = HIGH */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x040000, 0x040000); -+ /* TOP_QGPHY_CTRL_2.IDDQ_BIAS[5] = HIGH */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x20, 0x20); -+ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = HIGH */ -+ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x200000, 0x200000); -+ -+ /* TOP_QGPHY_CTRL_0.EXT_PWRDOWN[23] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033800, 0x0, 0x00800000); -+ /* TOP_QGPHY_CTRL_2.GPHY_IDDQ_GLOBAL_PWR[18] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x040000); -+ /* TOP_QGPHY_CTRL_2.IDDQ_BIAS[5] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02033400, 0x0, 0x20); -+ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = LOW */ -+ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x0, 0x200000); -+ -+ /* TOP_SOFT_RESET_REG.TOP_QGPHY_RST_L[21] = HIGH */ -+ cmid_schan_modify(base, 0x2c800200, 0x02030400, 0x200000, 0x200000); -+ -+ /* Reset the PHY (Register[0x00], bit 15 = 1) */ -+ egphy28_reg_modify(phy_addr, EGPHY28_COPPER_MII_CTRL, BMCR_RESET, BMCR_RESET); -+ -+ /* -+ * Enable direct RDB addressing mode, write to Expansion register -+ * 0x7E = 0x0000 -+ * - MDIO write to reg 0x17 = 0x0F7E -+ * - MDIO write to reg 0x15 = 0x0000 -+ */ -+ egphy28_reg_write(phy_addr, EGPHY28_RDB_ACCESS_ADDR_1, EGPHY28_RDB_ACCESS_DATA_1); -+ egphy28_reg_write(phy_addr, EGPHY28_RDB_ACCESS_ADDR_2, EGPHY28_RDB_ACCESS_DATA_2); -+ -+ /* Clear Reset the PHY (Register[0x00], bit 15 = 0) */ -+ egphy28_reg_modify(phy_addr, EGPHY28_COPPER_MII_CTRL, 0x0, BMCR_RESET); -+ -+ /* Set MAC PHY interface to be GMII mode */ -+ egphy28_reg_modify(phy_addr, EGPGY28_MII_ECONTROL, 0x0, (1 << 15)); -+ -+ /* Set 1000BASE-T full-duplex and switch device port (Register[0x09], bit 9,10 = 1) */ -+ egphy28_reg_write(phy_addr, EGPHY28_MII_CTRL1000, ADVERTISE_1000FULL | REPEATER_DTE); -+ -+ /* Set Full-duplex, 1000BASE-T, Auto-Negoatiation, Restartr-AN -+ * (Register[0x00], bit 8, 6, 12, 9 = 1) -+ */ -+ egphy28_reg_write(phy_addr, EGPHY28_COPPER_MII_CTRL, (BMCR_FULLDPLX | BMCR_SPEED1000 | -+ BMCR_ANENABLE | BMCR_ANRESTART)); -+ -+ /* Disable super-isolate (RDB Register[0x02a], bit 5 = 0). in default */ -+ egphy28_rdb_reg_modify(phy_addr, 0x2a, 0x0, (1 << 5)); -+ -+ /* Remove power down (Register[0x00], bit 11 = 0). in default */ -+ egphy28_reg_modify(phy_addr, EGPHY28_COPPER_MII_CTRL, ~BMCR_PDOWN, BMCR_PDOWN); -+ -+ /* Enable LEDs to indicate traffic status (Register[0x10], bit 5 = 1) */ -+ egphy28_reg_modify(phy_addr, 0x10, (1 << 5), (1 << 5)); -+ -+ /* Enable extended packet length (4.5k through 25k) (RDB Register[0x28], bit 14 = 1) */ -+ egphy28_rdb_reg_modify(phy_addr, 0x28, (1 << 14), (1 << 14)); -+ -+ egphy28_rdb_reg_modify(phy_addr, 0x16, (1 << 0), (1 << 0)); -+ egphy28_rdb_reg_modify(phy_addr, 0x1b, (1 << 1), (1 << 1)); -+ -+ /* Configure LED selectors */ -+ /* Disable carrier extension */ -+ /* IEEE compliance setup */ -+ egphy28_rdb_reg_write(phy_addr, 0x1E4, 0x00C0); -+ egphy28_rdb_reg_write(phy_addr, 0x1E7, 0xB008); -+ egphy28_rdb_reg_write(phy_addr, 0x1E2, 0x02E3); -+ egphy28_rdb_reg_write(phy_addr, 0x1E0, 0x0D11); -+ egphy28_rdb_reg_write(phy_addr, 0x1E3, 0x7FC0); -+ egphy28_rdb_reg_write(phy_addr, 0x1EB, 0x6B40); -+ egphy28_rdb_reg_write(phy_addr, 0x1E8, 0x0213); -+ egphy28_rdb_reg_write(phy_addr, 0x1E9, 0x0020); -+ egphy28_rdb_reg_write(phy_addr, 0x28, 0x4C30); -+ egphy28_rdb_reg_write(phy_addr, 0x125, 0x211B); -+ egphy28_rdb_reg_write(phy_addr, 0xE, 0x0013); -+ egphy28_rdb_reg_write(phy_addr, 0xB0, 0x000C); -+ egphy28_rdb_reg_write(phy_addr, 0xB0, 0x0000); -+ -+ /* Set Full-duplex, 1000BASE-T, Auto-Negoatiation, Restartr-AN -+ * (Register[0x00], bit 8, 6, 12, 9 = 1) -+ */ -+ egphy28_reg_write(phy_addr, EGPHY28_COPPER_MII_CTRL, (BMCR_FULLDPLX | BMCR_SPEED1000 | -+ BMCR_ANENABLE | BMCR_ANRESTART)); -+ -+ /* Automatic Master/Slave configuration (Register[0x09], bit 12 = 0) in default */ -+ egphy28_reg_modify(phy_addr, EGPHY28_MII_CTRL1000, 0x0, (1 << 12)); -+ -+ /* Ability advert set : IEEE 802.3, 10HD, 100HD, 10FD, 100FD */ -+ /* (Register[0x04] bit 0, 5, 7, 6, 8 = 1 */ -+ egphy28_reg_modify(phy_addr, EGPHY28_MII_ADVERTISE, -+ (ADVERTISE_10HALF | ADVERTISE_100HALF | ADVERTISE_10FULL | ADVERTISE_100FULL | ADVERTISE_CSMA), -+ (ADVERTISE_10HALF | ADVERTISE_100HALF | ADVERTISE_10FULL | ADVERTISE_100FULL | ADVERTISE_CSMA)); -+ /* Ability advert set : switch device port, 1000BASE-T FD, non-1000BASE-T HD */ -+ /* (Register[0x09] bit 10, 9 = 1, bit 8 = 0 */ -+ egphy28_reg_modify(phy_addr, EGPHY28_MII_CTRL1000, -+ (REPEATER_DTE | ADVERTISE_1000FULL), (REPEATER_DTE | ADVERTISE_1000FULL | ADVERTISE_1000HALF)); -+ -+ /* Set Auto-Negoatiation, Restartr-AN (Register[0x00], bit 12, 9 = 1) */ -+ egphy28_reg_modify(phy_addr, EGPHY28_COPPER_MII_CTRL, (BMCR_ANENABLE | BMCR_ANRESTART), -+ (BMCR_ANENABLE | BMCR_ANRESTART)); -+ -+ /* Clear bit 14 for automatic MDI crossover (Register[RDB 0x00] bit 14 = 0) in default */ -+ egphy28_rdb_reg_modify(phy_addr, 0x00, 0x0, (1 << 14)); -+ -+ /* Clear bit 9 to disable forced auto MDI xover */ -+ egphy28_rdb_reg_modify(phy_addr, 0x2f, 0x0, (1 << 9)); -+#endif -+ -+ return rv; -+} -+ -+ -+int -+egphy28_reset_setup(void __iomem *base, u32 phy_addr) -+{ -+ int rv = SOC_E_NONE; -+ -+ NET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ rv = egphy28_ge_reset(phy_addr); -+ if (SOC_SUCCESS(rv)) { -+ rv = egphy28_ge_init(base, phy_addr); -+ } -+ -+ return rv; -+} -+ -+int -+egphy28_init(void __iomem *base, u32 phy_addr) -+{ -+ u16 phyid0, phyid1; -+ -+ NET_TRACE(("%s: phy_addr %d\n", __FUNCTION__, phy_addr)); -+ -+ egphy28_reg_read(phy_addr, EGPHY28_PHY_ID_MSB, &phyid0); -+ egphy28_reg_read(phy_addr, EGPHY28_PHY_ID_LSB, &phyid1); -+ -+ printf("%s Phy ChipID: 0x%04x:0x%04x\n", __FUNCTION__, phyid1, phyid0); -+ //egphy28_reset_setup(base, phy_addr); -+ -+ return 0; -+} -+ -+int -+egphy28_enable_set(u32 phy_addr, int enable) -+{ -+ u16 val; -+ -+ NET_TRACE(("%s: phy_addr %d\n", __FUNCTION__, phy_addr)); -+ -+ egphy28_reg_read(phy_addr, EGPHY28_COPPER_MII_CTRL, &val); -+ if (enable) { -+ val &= ~BMCR_PDOWN; -+ } else { -+ val |= BMCR_PDOWN; -+ } -+ egphy28_reg_write(phy_addr, EGPHY28_COPPER_MII_CTRL, val); -+ -+ return SOC_E_NONE; -+} -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5221.c b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5221.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5221.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5221.c 2017-11-09 17:53:44.025293000 +0800 -@@ -0,0 +1,657 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * These routines provide access to the external phy -+ * -+ */ -+ -+/* ---- Include Files ---------------------------------------------------- */ -+#include -+#include -+#include "../../../mdio/iproc_mdio.h" -+#include "bcmiproc_phy.h" -+#include "bcmiproc_phy5221.h" -+ -+/* ---- External Variable Declarations ----------------------------------- */ -+/* ---- External Function Prototypes ------------------------------------- */ -+/* ---- Public Variables ------------------------------------------------- */ -+/* ---- Private Constants and Types -------------------------------------- */ -+/* ---- Private Variables ------------------------------------------------ */ -+ -+/* debug/trace */ -+//#define BCMDBG -+//#define BCMDBG_ERR -+#ifdef BCMDBG -+#define NET_ERROR(args) printf args -+#define NET_TRACE(args) printf args -+#elif defined(BCMDBG_ERR) -+#define NET_ERROR(args) printf args -+#define NET_TRACE(args) -+#else -+#define NET_ERROR(args) -+#define NET_TRACE(args) -+#endif /* BCMDBG */ -+#define NET_REG_TRACE(args) -+ -+ -+#ifndef ASSERT -+#define ASSERT(exp) -+#endif -+ -+ -+/* ==== Public Functions ================================================= */ -+ -+int -+phy5221_wr_reg(uint eth_num, uint phyaddr, uint16 reg_bank, -+ uint8 reg_addr, uint16 *data) -+{ -+ uint16 wr_data=*data; -+ uint16 test_reg; -+ -+ NET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ NET_REG_TRACE(("%s going to write phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, wr_data)); -+ -+ if (reg_bank) { -+ iproc_mii_read(MII_DEV_EXT, phyaddr, 0x1f, &test_reg); -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1f, (test_reg | 0x0080)); -+ -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, wr_data); -+ -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1f, test_reg); -+ } else { -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, wr_data); -+ } -+ return SOC_E_NONE; -+} -+ -+ -+int -+phy5221_rd_reg(uint eth_num, uint phyaddr, uint16 reg_bank, -+ uint8 reg_addr, uint16 *data) -+{ -+ uint16 test_reg; -+ -+ NET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ NET_REG_TRACE(("%s going to read phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr)); -+ -+ if (reg_bank) { -+ iproc_mii_read(MII_DEV_EXT, phyaddr, 0x1f, &test_reg); -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1f, (test_reg | 0x0080)); -+ -+ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, data); -+ -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1f, test_reg); -+ } else { -+ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, data); -+ } -+ NET_REG_TRACE(("%s rd phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, *data)); -+ -+ return SOC_E_NONE; -+} -+ -+ -+int -+phy5221_mod_reg(uint eth_num, uint phyaddr, uint16 reg_bank, -+ uint8 reg_addr, uint16 data, uint16 mask) -+{ -+ uint16 test_reg; -+ uint16 org_data, rd_data; -+ -+ NET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ NET_REG_TRACE(("%s going to modify phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x) mask(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, data, mask)); -+ -+ if (reg_bank) { -+ iproc_mii_read(MII_DEV_EXT, phyaddr, 0x1f, &test_reg); -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1f, (test_reg | 0x0080)); -+ -+ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, &rd_data); -+ NET_REG_TRACE(("%s rd phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); -+ org_data = rd_data; -+ rd_data &= ~(mask); -+ rd_data |= data; -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, rd_data); -+ NET_REG_TRACE(("%s wrt phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); -+ -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1f, test_reg); -+ } else { -+ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, &rd_data); -+ NET_REG_TRACE(("%s rd phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); -+ org_data = rd_data; -+ rd_data &= ~(mask); -+ rd_data |= data; -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, rd_data); -+ NET_REG_TRACE(("%s wrt phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); -+ } -+ -+ return SOC_E_NONE; -+} -+ -+ -+void -+phy5221_fe_reset(uint eth_num, uint phyaddr) -+{ -+ uint16 ctrl; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ /* set reset flag */ -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); -+ ctrl |= MII_CTRL_RESET; -+ phy5221_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); -+ -+ SPINWAIT( (!phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl) -+ && (ctrl & MII_CTRL_RESET)), 100000); -+ /* check if out of reset */ -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); -+ if (ctrl & MII_CTRL_RESET) { -+ /* timeout */ -+ NET_ERROR(("et%d: %s reset not complete\n", eth_num, __FUNCTION__)); -+ } else { -+ NET_ERROR(("et%d: %s reset complete\n", eth_num, __FUNCTION__)); -+ } -+ -+ return; -+} -+ -+ -+/* -+ * Function: -+ * phy5221_fe_init -+ * Purpose: -+ * Initialize the PHY (MII mode) to a known good state. -+ * Parameters: -+ * unit - StrataSwitch unit #. -+ * port - StrataSwitch port #. -+ * Returns: -+ * SOC_E_XXX -+ -+ * Notes: -+ * No synchronization performed at this level. -+ */ -+int -+phy5221_fe_init(uint eth_num, uint phyaddr) -+{ -+ uint16 mii_ana, mii_ctrl; -+ -+ /* Reset PHY */ -+ phy5221_fe_reset(eth_num, phyaddr); -+ -+ mii_ana = MII_ANA_HD_10 | MII_ANA_FD_10 | MII_ANA_HD_100 | -+ MII_ANA_FD_100 | MII_ANA_ASF_802_3; -+ mii_ctrl = MII_CTRL_FD | MII_CTRL_SS_100 | MII_CTRL_AE | MII_CTRL_RAN; -+ -+ phy5221_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ phy5221_wr_reg(eth_num, phyaddr, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &mii_ana); -+ -+ return SOC_E_NONE; -+} -+ -+ -+#ifdef BCMINTERNAL -+/* -+ * Function: -+ * phy5221_fe_speed_set -+ * Purpose: -+ * Set the current operating speed (forced). -+ * Parameters: -+ * unit - StrataSwitch unit #. -+ * port - StrataSwitch port #. -+ * duplex - (OUT) Boolean, true indicates full duplex, false -+ * indicates half. -+ * Returns: -+ * SOC_E_XXX -+ * Notes: -+ * No synchronization performed at this level. Autonegotiation is -+ * not manipulated. -+ */ -+int -+phy5221_fe_speed_set(uint eth_num, uint phyaddr, int speed) -+{ -+ uint16 mii_ctrl; -+ -+ if (speed == 0) { -+ return SOC_E_NONE; -+ } -+ -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ -+ mii_ctrl &= ~(MII_CTRL_SS_LSB | MII_CTRL_SS_MSB); -+ switch(speed) { -+ case 10: -+ mii_ctrl |= MII_CTRL_SS_10; -+ break; -+ case 100: -+ mii_ctrl |= MII_CTRL_SS_100; -+ break; -+ case 1000: -+ mii_ctrl |= MII_CTRL_SS_1000; -+ break; -+ default: -+ return SOC_E_CONFIG; -+ } -+ -+ phy5221_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ -+ return SOC_E_NONE; -+} -+#endif /* BCMINTERNAL */ -+ -+ -+/* -+ * Function: -+ * phy5221_init -+ * Purpose: -+ * Initialize xgxs6 phys -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * Returns: -+ * 0 -+ */ -+int -+phy5221_init(uint eth_num, uint phyaddr) -+{ -+ uint16 phyid0, phyid1; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID0r_BANK, PHY_MII_PHY_ID0r_ADDR, &phyid0); -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID1r_BANK, PHY_MII_PHY_ID1r_ADDR, &phyid1); -+ -+ NET_TRACE(("%s phyaddr(0x%x) Phy ChipID: 0x%04x:0x%04x\n", __FUNCTION__, phyaddr, phyid1, phyid0)); -+ -+ phy5221_fe_init(eth_num, phyaddr); -+ -+ return 0; -+} -+ -+/* -+ * Function: -+ * phy5221_link_get -+ * Purpose: -+ * Determine the current link up/down status -+ * Parameters: -+ * unit - StrataSwitch unit #. -+ * port - StrataSwitch port #. -+ * link - (OUT) Boolean, true indicates link established. -+ * Returns: -+ * SOC_E_XXX -+ * Notes: -+ * No synchronization performed at this level. -+ */ -+int -+phy5221_link_get(uint eth_num, uint phyaddr, int *link) -+{ -+ uint16 mii_ctrl, mii_stat; -+ uint32 wait; -+ -+ *link = FALSE; /* Default */ -+ -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); -+ /* the first read of status register will not show link up, second read will show link up */ -+ if (!(mii_stat & MII_STAT_LA) ) { -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); -+ } -+ -+ if (!(mii_stat & MII_STAT_LA) || (mii_stat == 0xffff)) { -+ /* mii_stat == 0xffff check is to handle removable PHY daughter cards */ -+ return SOC_E_NONE; -+ } -+ -+ /* Link appears to be up; we are done if autoneg is off. */ -+ -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ -+ if (!(mii_ctrl & MII_CTRL_AE)) { -+ *link = TRUE; -+ return SOC_E_NONE; -+ } -+ -+ /* -+ * If link appears to be up but autonegotiation is still in -+ * progress, wait for it to complete. For BCM5228, autoneg can -+ * still be busy up to about 200 usec after link is indicated. Also -+ * continue to check link state in case it goes back down. -+ * wait 500ms (500000us/10us = 50000 ) -+ */ -+ for (wait=0; wait<50000; wait++) { -+ -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); -+ -+ if (!(mii_stat & MII_STAT_LA)) { -+ /* link is down */ -+ return SOC_E_NONE; -+ } -+ -+ if (mii_stat & MII_STAT_AN_DONE) { -+ /* AutoNegotiation done */ -+ break; -+ } -+ -+ OSL_DELAY(10); -+ } -+ if (wait>=50000) { -+ /* timeout */ -+ return SOC_E_BUSY; -+ } -+ -+ /* Return link state at end of polling */ -+ *link = ((mii_stat & MII_STAT_LA) != 0); -+ -+ return SOC_E_NONE; -+} -+ -+ -+/* -+ * Function: -+ * phy5221_enable_set -+ * Purpose: -+ * Enable/Disable phy -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * enable - on/off state to set -+ * Returns: -+ * 0 -+ */ -+int -+phy5221_enable_set(uint eth_num, uint phyaddr, int enable) -+{ -+ uint16 data; /* New value to write to PHY register */ -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ data = enable ? 0 : MII_ECR_TD; /* Transmitt enable/disable */ -+ phy5221_mod_reg(eth_num, phyaddr, PHY_MII_ECRr_BANK, PHY_MII_ECRr_ADDR, data, MII_ECR_TD); -+ -+ data = enable ? 0 : PHY522X_SUPER_ISOLATE_MODE; -+ /* Device needs to be put in super-isolate mode in order to disable -+ * the link in 10BaseT mode -+ */ -+ phy5221_mod_reg(eth_num, phyaddr, PHY_AUX_MULTIPLE_PHYr_BANK, PHY_AUX_MULTIPLE_PHYr_ADDR, -+ data, PHY522X_SUPER_ISOLATE_MODE); -+ -+ return SOC_E_NONE; -+} -+ -+ -+#ifdef BCMINTERNAL -+/* -+ * Function: -+ * phy5221_speed_set -+ * Purpose: -+ * Set PHY speed -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * speed - link speed in Mbps -+ * Returns: -+ * 0 -+ */ -+int -+phy5221_speed_set(uint eth_num, uint phyaddr, int speed) -+{ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ phy5221_fe_speed_set(eth_num, phyaddr, speed); -+ -+ return 0; -+} -+#endif /* BCMINTERNAL */ -+ -+ -+/* -+ * Function: -+ * phy5221_auto_negotiate_gcd (greatest common denominator). -+ * Purpose: -+ * Determine the current greatest common denominator between -+ * two ends of a link -+ * Parameters: -+ * unit - StrataSwitch unit #. -+ * port - StrataSwitch port #. -+ * speed - (OUT) greatest common speed. -+ * duplex - (OUT) greatest common duplex. -+ * link - (OUT) Boolean, true indicates link established. -+ * Returns: -+ * SOC_E_XXX -+ * Notes: -+ * No synchronization performed at this level. -+ */ -+static int -+phy5221_auto_negotiate_gcd(uint eth_num, uint phyaddr, int *speed, int *duplex) -+{ -+ int t_speed, t_duplex; -+ uint16 mii_ana, mii_anp, mii_stat; -+ uint16 mii_gb_stat, mii_esr, mii_gb_ctrl; -+ -+ mii_gb_stat = 0; /* Start off 0 */ -+ mii_gb_ctrl = 0; /* Start off 0 */ -+ -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &mii_ana); -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_ANPr_BANK, PHY_MII_ANPr_ADDR, &mii_anp); -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); -+ -+ if (mii_stat & MII_STAT_ES) { /* Supports extended status */ -+ /* -+ * If the PHY supports extended status, check if it is 1000MB -+ * capable. If it is, check the 1000Base status register to see -+ * if 1000MB negotiated. -+ */ -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_ESRr_BANK, PHY_MII_ESRr_ADDR, &mii_esr); -+ -+ if (mii_esr & (MII_ESR_1000_X_FD | MII_ESR_1000_X_HD | -+ MII_ESR_1000_T_FD | MII_ESR_1000_T_HD)) { -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_GB_STATr_BANK, PHY_MII_GB_STATr_ADDR, &mii_gb_stat); -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_GB_CTRLr_BANK, PHY_MII_GB_CTRLr_ADDR, &mii_gb_ctrl); -+ } -+ } -+ -+ /* -+ * At this point, if we did not see Gig status, one of mii_gb_stat or -+ * mii_gb_ctrl will be 0. This will cause the first 2 cases below to -+ * fail and fall into the default 10/100 cases. -+ */ -+ -+ mii_ana &= mii_anp; -+ -+ if ((mii_gb_ctrl & MII_GB_CTRL_ADV_1000FD) && -+ (mii_gb_stat & MII_GB_STAT_LP_1000FD)) { -+ t_speed = 1000; -+ t_duplex = 1; -+ } else if ((mii_gb_ctrl & MII_GB_CTRL_ADV_1000HD) && -+ (mii_gb_stat & MII_GB_STAT_LP_1000HD)) { -+ t_speed = 1000; -+ t_duplex = 0; -+ } else if (mii_ana & MII_ANA_FD_100) { /* [a] */ -+ t_speed = 100; -+ t_duplex = 1; -+ } else if (mii_ana & MII_ANA_T4) { /* [b] */ -+ t_speed = 100; -+ t_duplex = 0; -+ } else if (mii_ana & MII_ANA_HD_100) { /* [c] */ -+ t_speed = 100; -+ t_duplex = 0; -+ } else if (mii_ana & MII_ANA_FD_10) { /* [d] */ -+ t_speed = 10; -+ t_duplex = 1 ; -+ } else if (mii_ana & MII_ANA_HD_10) { /* [e] */ -+ t_speed = 10; -+ t_duplex = 0; -+ } else { -+ return(SOC_E_FAIL); -+ } -+ -+ if (speed) *speed = t_speed; -+ if (duplex) *duplex = t_duplex; -+ -+ return(SOC_E_NONE); -+} -+ -+ -+/* -+ * Function: -+ * phy5221_speed_get -+ * Purpose: -+ * Get PHY speed -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * speed - current link speed in Mbps -+ * Returns: -+ * 0 -+ */ -+int -+phy5221_speed_get(uint eth_num, uint phyaddr, int *speed, int *duplex) -+{ -+ int rv; -+ uint16 mii_ctrl, mii_stat; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); -+ -+ *speed = 0; -+ *duplex = 0; -+ if (mii_ctrl & MII_CTRL_AE) { /* Auto-negotiation enabled */ -+ if (!(mii_stat & MII_STAT_AN_DONE)) { /* Auto-neg NOT complete */ -+ rv = SOC_E_NONE; -+ } else { -+ rv = phy5221_auto_negotiate_gcd(eth_num, phyaddr, speed, duplex); -+ } -+ } else { /* Auto-negotiation disabled */ -+ /* -+ * Simply pick up the values we force in CTRL register. -+ */ -+ if (mii_ctrl & MII_CTRL_FD) -+ *duplex = 1; -+ -+ switch(MII_CTRL_SS(mii_ctrl)) { -+ case MII_CTRL_SS_10: -+ *speed = 10; -+ break; -+ case MII_CTRL_SS_100: -+ *speed = 100; -+ break; -+ case MII_CTRL_SS_1000: -+ *speed = 1000; -+ break; -+ default: /* Just pass error back */ -+ return(SOC_E_UNAVAIL); -+ } -+ rv = SOC_E_NONE; -+ } -+ -+ return(rv); -+} -+ -+ -+#ifdef BCMINTERNAL -+int -+phy5221_lb_set(uint eth_num, uint phyaddr, int enable) -+{ -+ uint16 mii_ctrl; -+ -+ /* set reset flag */ -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ mii_ctrl &= ~MII_CTRL_LE; -+ mii_ctrl |= enable ? MII_CTRL_LE : 0; -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ -+ return 0; -+} -+#endif /* BCMINTERNAL */ -+ -+ -+#ifdef BCMINTERNAL -+void -+phy5221_disp_status(uint eth_num, uint phyaddr) -+{ -+ uint16 tmp0, tmp1, tmp2; -+ int speed, duplex; -+ -+ printf("et%d: %s: phyaddr:%d\n", eth_num, __FUNCTION__, phyaddr); -+ -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &tmp0); -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &tmp1); -+ printf(" MII-Control: 0x%x; MII-Status: 0x%x\n", tmp0, tmp1); -+ -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID0r_BANK, PHY_MII_PHY_ID0r_ADDR, &tmp0); -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID1r_BANK, PHY_MII_PHY_ID1r_ADDR, &tmp1); -+ printf(" Phy ChipID: 0x%04x:0x%04x\n", tmp0, tmp1); -+ -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &tmp0); -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_ANPr_BANK, PHY_MII_ANPr_ADDR, &tmp1); -+ phy5221_speed_get(eth_num, phyaddr, &speed, &duplex); -+ printf(" AutoNeg Ad: 0x%x; AutoNeg Partner: 0x%x; speed:%d; duplex:%d\n", tmp0, tmp1, speed, duplex); -+ -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_ESRr_BANK, PHY_MII_ESRr_ADDR, &tmp0); -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_ECRr_BANK, PHY_MII_ECRr_ADDR, &tmp1); -+ phy5221_rd_reg(eth_num, phyaddr, 0x0000, 0x11, &tmp2); -+ printf(" Reg0x0f: 0x%x; 100Base-X AUX ctrl: 0x%x; 100Base-X AUX stat: 0x%x\n", tmp0, tmp1, tmp2); -+ -+ phy5221_rd_reg(eth_num, phyaddr, 0x0000, 0x12, &tmp0); -+ phy5221_rd_reg(eth_num, phyaddr, 0x0000, 0x13, &tmp1); -+ phy5221_rd_reg(eth_num, phyaddr, 0x0000, 0x14, &tmp2); -+ printf(" 100Base-X RCV ERR: 0x%x; 100Base-X FALSE CARRIER: 0x%x; 100Base-X DISCON: 0x%x\n", tmp0, tmp1, tmp2); -+} -+#endif /* BCMINTERNAL */ -+ -+ -+#ifdef BCMINTERNAL -+void -+phy5221_chk_err(uint eth_num, uint phyaddr) -+{ -+ uint16 tmp0; -+ -+ phy5221_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &tmp0); -+ if (!(tmp0 & MII_STAT_LA)) { -+ printf("ERROR: reg 0x01 (LINK down): 0x%x\n", tmp0); -+ } -+ if (tmp0 & (MII_STAT_JBBR|MII_STAT_RF)) { -+ printf("ERROR: reg 0x01: 0x%x\n", tmp0); -+ } -+ -+ phy5221_rd_reg(eth_num, phyaddr, 0, 0x11, &tmp0); -+ if (!(tmp0 & 0x100)) { -+ printf("ERROR: reg 0x11 (LINK down): 0x%x\n", tmp0); -+ } -+ if (tmp0 & 0x8bf) { -+ printf("ERROR: reg 0x11: 0x%x\n", tmp0); -+ } -+ -+ phy5221_rd_reg(eth_num, phyaddr, 0, 0x12, &tmp0); -+ if (tmp0) { -+ printf("ERROR: reg 0x12 (RCV ERR CNT): 0x%x\n", tmp0); -+ } -+ -+ phy5221_rd_reg(eth_num, phyaddr, 0, 0x13, &tmp0); -+ if (tmp0) { -+ printf("ERROR: reg 0x13 (FALSE CARRIER CNT): 0x%x\n", tmp0); -+ } -+ -+ phy5221_rd_reg(eth_num, phyaddr, 0, 0x14, &tmp0); -+ if (tmp0 & 0xc000) { -+ printf("ERROR: reg 0x14: 0x%x\n", tmp0); -+ } -+ -+ phy5221_rd_reg(eth_num, phyaddr, 0, 0x19, &tmp0); -+ if (!(tmp0 & 0x4)) { -+ printf("ERROR: reg 0x19 (LINK down): 0x%x\n", tmp0); -+ } -+ if (tmp0 & 0xc0) { -+ printf("ERROR: reg 0x19: 0x%x\n", tmp0); -+ } -+} -+#endif /* BCMINTERNAL */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5461s.c b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5461s.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5461s.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5461s.c 2017-11-09 17:53:44.027292000 +0800 -@@ -0,0 +1,896 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * These routines provide access to the external phy -+ * -+ */ -+ -+/* ---- Include Files ---------------------------------------------------- */ -+#include -+#include -+#include "../../../mdio/iproc_mdio.h" -+#include "bcmiproc_phy.h" -+#include "bcmiproc_phy5461s.h" -+ -+/* ---- External Variable Declarations ----------------------------------- */ -+/* ---- External Function Prototypes ------------------------------------- */ -+/* ---- Public Variables ------------------------------------------------- */ -+/* ---- Private Constants and Types -------------------------------------- */ -+/* ---- Private Variables ------------------------------------------------ */ -+ -+/* debug/trace */ -+//#define BCMDBG -+//#define BCMDBG_ERR -+#ifdef BCMDBG -+#define NET_ERROR(args) printf args -+#define NET_TRACE(args) printf args -+#elif defined(BCMDBG_ERR) -+#define NET_ERROR(args) printf args -+#define NET_TRACE(args) -+#else -+#define NET_ERROR(args) -+#define NET_TRACE(args) -+#endif /* BCMDBG */ -+#define NET_REG_TRACE(args) -+ -+ -+#ifndef ASSERT -+#define ASSERT(exp) -+#endif -+ -+ -+/* ==== Public Functions ================================================= */ -+ -+int -+phy5461_wr_reg(uint eth_num, uint phyaddr, uint32 flags, uint16 reg_bank, -+ uint8 reg_addr, uint16 *data) -+{ -+ int rv = SOC_E_NONE; -+ uint16 wr_data=*data; -+ -+ NET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ NET_REG_TRACE(("%s going to write phyaddr(0x%x) flags(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, flags, reg_bank, reg_addr, wr_data)); -+ //printf("%s phyaddr(0x%x) flags(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ // __FUNCTION__, phyaddr, flags, reg_bank, reg_addr, wr_data); -+ -+ if (flags & SOC_PHY_REG_1000X) { -+ if (reg_addr <= 0x000f) { -+ uint16 blk_sel; -+ -+ /* Map 1000X page */ -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, 0x7c00); -+ -+ iproc_mii_read(MII_DEV_EXT, phyaddr, 0x1c, &blk_sel); -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, blk_sel | 0x8001); -+ -+ /* write 1000X IEEE register */ -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, wr_data); -+ -+ /* Restore IEEE mapping */ -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, (blk_sel & 0xfffe) | 0x8000); -+ } else if (flags & _SOC_PHY_REG_DIRECT) { -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, wr_data); -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ } else { -+ switch(reg_addr) { -+ /* Map shadow registers */ -+#ifdef BCMINTERNAL -+ case 0x15: -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x17, reg_bank); -+ break; -+#endif /* BCMINTERNAL */ -+ case 0x18: -+ if (reg_bank <= 0x0007) { -+ if (reg_bank == 0x0007) { -+ wr_data |= 0x8000; -+ } -+ wr_data = (wr_data & ~(0x0007)) | reg_bank; -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ break; -+ case 0x1C: -+ if (reg_bank <= 0x001F) { -+ wr_data = 0x8000 | (reg_bank << 10) | (wr_data & 0x03FF); -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ break; -+#ifdef BCMINTERNAL -+ case 0x1D: -+ if (reg_bank == 0x0000) { -+ wr_data = wr_data & 0x07FFF; -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ break; -+#endif /* BCMINTERNAL */ -+ default: -+ if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) { -+ /* Must not write to reserved registers */ -+ if (reg_addr > 0x001e) { -+ rv = SOC_E_PARAM; -+ } -+ } -+ break; -+ } -+ if (SOC_SUCCESS(rv)) { -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, wr_data); -+ } -+ } -+ if (SOC_FAILURE(rv)) { -+ NET_ERROR(("%s ERROR phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) rv(%d)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, rv)); -+ } -+ return rv; -+} -+ -+ -+int -+phy5461_rd_reg(uint eth_num, uint phyaddr, uint32 flags, uint16 reg_bank, -+ uint8 reg_addr, uint16 *data) -+{ -+ int rv = SOC_E_NONE; -+ -+ NET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ NET_REG_TRACE(("%s going to read phyaddr(0x%x) flags(0x%x) reg_bank(0x%x) reg_addr(0x%x)\n", -+ __FUNCTION__, phyaddr, flags, reg_bank, reg_addr)); -+ if (flags & SOC_PHY_REG_1000X) { -+ if (reg_addr <= 0x000f) { -+ uint16 blk_sel; -+ -+ /* Map 1000X page */ -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, 0x7c00); -+ iproc_mii_read(MII_DEV_EXT, phyaddr, 0x1c, &blk_sel); -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, blk_sel | 0x8001); -+ -+ /* Read 1000X IEEE register */ -+ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, data); -+ NET_REG_TRACE(("%s rd phyaddr(0x%x) flags(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, flags, reg_bank, reg_addr, *data)); -+ -+ /* Restore IEEE mapping */ -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, (blk_sel & 0xfffe) | 0x8000); -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ } else { -+ switch(reg_addr) { -+ /* Map shadow registers */ -+#ifdef BCMINTERNAL -+ case 0x15: -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x17, reg_bank); -+ break; -+#endif /* BCMINTERNAL */ -+ case 0x18: -+ if (reg_bank <= 0x0007) { -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 12) | 0x7); -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ break; -+ case 0x1C: -+ if (reg_bank <= 0x001F) { -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 10)); -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ break; -+#ifdef BCMINTERNAL -+ case 0x1D: -+ if (reg_bank <= 0x0001) { -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 15)); -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ break; -+#endif /* BCMINTERNAL */ -+ default: -+ if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) { -+ /* Must not read from reserved registers */ -+ if (reg_addr > 0x001e) { -+ rv = SOC_E_PARAM; -+ } -+ } -+ break; -+ } -+ if (SOC_SUCCESS(rv)) { -+ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, data); -+ NET_REG_TRACE(("%s rd phyaddr(0x%x) flags(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, flags, reg_bank, reg_addr, *data)); -+ } -+ } -+ if (SOC_FAILURE(rv)) { -+ NET_ERROR(("%s ERROR phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) rv(%d)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, rv)); -+ } else { -+ //printf("%s phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ // __FUNCTION__, phyaddr, reg_bank, reg_addr, *data); -+ } -+ -+ return rv; -+} -+ -+ -+int -+phy5461_mod_reg(uint eth_num, uint phyaddr, uint32 flags, uint16 reg_bank, -+ uint8 reg_addr, uint16 data, uint16 mask) -+{ -+ int rv = SOC_E_NONE; -+ uint16 org_data, rd_data; -+ -+ NET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ NET_REG_TRACE(("%s going to modify phyaddr(0x%x) flags(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x) mask(0x%x)\n", -+ __FUNCTION__, phyaddr, flags, reg_bank, reg_addr, data, mask)); -+ -+ if (flags & SOC_PHY_REG_1000X) { -+ if (reg_addr <= 0x000f) { -+ uint16 blk_sel; -+ -+ /* Map 1000X page */ -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, 0x7c00); -+ iproc_mii_read(MII_DEV_EXT, phyaddr, 0x1c, &blk_sel); -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, blk_sel | 0x8001); -+ -+ /* Modify 1000X IEEE register */ -+ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, &rd_data); -+ NET_REG_TRACE(("%s rd phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); -+ org_data = rd_data; -+ rd_data &= ~(mask); -+ rd_data |= data; -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, rd_data); -+ NET_REG_TRACE(("%s wrt phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); -+ -+ /* Restore IEEE mapping */ -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x1c, (blk_sel & 0xfffe) | 0x8000); -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ } else { -+ switch(reg_addr) { -+ /* Map shadow registers */ -+#ifdef BCMINTERNAL -+ case 0x15: -+ iproc_mii_write(MII_DEV_EXT, phyaddr, 0x17, reg_bank); -+ break; -+#endif /* BCMINTERNAL */ -+ case 0x18: -+ if (reg_bank <= 0x0007) { -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 12) | 0x7); -+ -+ if (reg_bank == 0x0007) { -+ data |= 0x8000; -+ mask |= 0x8000; -+ } -+ mask &= ~(0x0007); -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ break; -+ case 0x1C: -+ if (reg_bank <= 0x001F) { -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 10)); -+ data |= 0x8000; -+ mask |= 0x8000; -+ mask &= ~(0x1F << 10); -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ break; -+#ifdef BCMINTERNAL -+ case 0x1D: -+ if (reg_bank == 0x0000) { -+ mask &= 0x07FFF; -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ break; -+#endif /* BCMINTERNAL */ -+ default: -+ if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) { -+ /* Must not write to reserved registers */ -+ if (reg_addr > 0x001e) { -+ rv = SOC_E_PARAM; -+ } -+ } -+ break; -+ } -+ if (SOC_SUCCESS(rv)) { -+ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, &rd_data); -+ NET_REG_TRACE(("%s rd phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); -+ org_data = rd_data; -+ rd_data &= ~(mask); -+ rd_data |= data; -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, rd_data); -+ NET_REG_TRACE(("%s wrt phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); -+ } -+ } -+ -+ if (SOC_FAILURE(rv)) { -+ NET_ERROR(("%s ERROR phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) rv(%d)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, rv)); -+ } else { -+ //printf("%s modified(0x%x to 0x%x at phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x)\n", -+ // __FUNCTION__, org_data, rd_data, phyaddr, reg_bank, reg_addr); -+ } -+ -+ return rv; -+} -+ -+ -+void -+phy5461_ge_reset(uint eth_num, uint phyaddr) -+{ -+ uint16 ctrl; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ /* set reset flag */ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); -+ ctrl |= MII_CTRL_RESET; -+ phy5461_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); -+ -+ SPINWAIT( (!phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl) -+ && (ctrl & MII_CTRL_RESET)), 100000); -+ /* check if out of reset */ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); -+ if (ctrl & MII_CTRL_RESET) { -+ /* timeout */ -+ NET_ERROR(("et%d: %s reset not complete\n", eth_num, __FUNCTION__)); -+ } else { -+ NET_TRACE(("et%d: %s reset complete\n", eth_num, __FUNCTION__)); -+ } -+} -+ -+ -+/* -+ * Function: -+ * phy5461_ge_interface_set -+ * Purpose: -+ * Set the current operating mode of the PHY. -+ * (Pertaining to the MAC/PHY interface, not the line interface). -+ * For example: TBI or MII/GMII. -+ * Parameters: -+ * unit - StrataSwitch unit #. -+ * port - StrataSwitch port #. -+ * pif - one of SOC_PORT_IF_* -+ * Returns: -+ * SOC_E_XXX -+ */ -+int -+phy5461_ge_interface_set(uint eth_num, uint phyaddr, soc_port_if_t pif) -+{ -+ uint16 mii_ecr; -+ int mii; /* MII if true, TBI otherwise */ -+ -+ switch (pif) { -+ case SOC_PORT_IF_MII: -+ case SOC_PORT_IF_GMII: -+ case SOC_PORT_IF_SGMII: -+ mii = TRUE; -+ break; -+ case SOC_PORT_IF_NOCXN: -+ return (SOC_E_NONE); -+ case SOC_PORT_IF_TBI: -+ mii = FALSE; -+ break; -+ default: -+ return SOC_E_UNAVAIL; -+ } -+ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ECRr_FLAGS, PHY_MII_ECRr_BANK, PHY_MII_ECRr_ADDR, &mii_ecr); -+ -+ if (mii) { -+ mii_ecr &= ~MII_ECR_10B; -+ } else { -+ mii_ecr |= MII_ECR_10B; -+ } -+ -+ phy5461_wr_reg(eth_num, phyaddr, PHY_MII_ECRr_FLAGS, PHY_MII_ECRr_BANK, PHY_MII_ECRr_ADDR, &mii_ecr); -+ -+ return(SOC_E_NONE); -+} -+ -+ -+/* -+ * Function: -+ * phy5461_ge_init -+ * Purpose: -+ * Initialize the PHY (MII mode) to a known good state. -+ * Parameters: -+ * unit - StrataSwitch unit #. -+ * port - StrataSwitch port #. -+ * Returns: -+ * SOC_E_XXX -+ -+ * Notes: -+ * No synchronization performed at this level. -+ */ -+int -+phy5461_ge_init(uint eth_num, uint phyaddr) -+{ -+ uint16 mii_ctrl, mii_gb_ctrl; -+ uint16 mii_ana; -+ soc_port_if_t pif; -+ -+ /* Reset PHY */ -+ phy5461_ge_reset(eth_num, phyaddr); -+ -+ /* set advertized bits */ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ANAr_FLAGS, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &mii_ana); -+ mii_ana |= MII_ANA_FD_100 | MII_ANA_FD_10; -+ mii_ana |= MII_ANA_HD_100 | MII_ANA_HD_10; -+ phy5461_wr_reg(eth_num, phyaddr, PHY_MII_ANAr_FLAGS, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &mii_ana); -+ -+ mii_ctrl = MII_CTRL_FD | MII_CTRL_SS_1000 | MII_CTRL_AE | MII_CTRL_RAN; -+ mii_gb_ctrl = MII_GB_CTRL_ADV_1000FD | MII_GB_CTRL_PT; -+ -+ pif = SOC_PORT_IF_GMII; -+ -+ phy5461_ge_interface_set(eth_num, phyaddr, pif); -+ -+ phy5461_wr_reg(eth_num, phyaddr, PHY_MII_GB_CTRLr_FLAGS, PHY_MII_GB_CTRLr_BANK, PHY_MII_GB_CTRLr_ADDR, &mii_gb_ctrl); -+ phy5461_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ -+ return(SOC_E_NONE); -+} -+ -+ -+#ifdef BCMINTERNAL -+/* -+ * Function: -+ * phy5461_ge_speed_set -+ * Purpose: -+ * Set the current operating speed (forced). -+ * Parameters: -+ * unit - StrataSwitch unit #. -+ * port - StrataSwitch port #. -+ * duplex - (OUT) Boolean, true indicates full duplex, false -+ * indicates half. -+ * Returns: -+ * SOC_E_XXX -+ * Notes: -+ * No synchronization performed at this level. Autonegotiation is -+ * not manipulated. -+ */ -+int -+phy5461_ge_speed_set(uint eth_num, uint phyaddr, int speed) -+{ -+ uint16 mii_ctrl; -+ -+ if (speed == 0) { -+ return SOC_E_NONE; -+ } -+ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ -+ mii_ctrl &= ~(MII_CTRL_SS_LSB | MII_CTRL_SS_MSB); -+ switch(speed) { -+ case 10: -+ mii_ctrl |= MII_CTRL_SS_10; -+ break; -+ case 100: -+ mii_ctrl |= MII_CTRL_SS_100; -+ break; -+ case 1000: -+ mii_ctrl |= MII_CTRL_SS_1000; -+ break; -+ default: -+ return SOC_E_CONFIG; -+ } -+ -+ phy5461_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ -+ return SOC_E_NONE; -+} -+#endif /* BCMINTERNAL */ -+ -+ -+void -+phy5461_reset_setup(uint eth_num, uint phyaddr) -+{ -+ uint16 tmp; -+ -+ NET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ phy5461_ge_init(eth_num, phyaddr); -+ -+ /* copper regs */ -+ /* remove power down */ -+ phy5461_mod_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, 0, MII_CTRL_PD); -+ /* Disable super-isolate */ -+ phy5461_mod_reg(eth_num, phyaddr, PHY_MII_POWER_CTRLr_FLAGS, PHY_MII_POWER_CTRLr_BANK, PHY_MII_POWER_CTRLr_ADDR, 0, 1U<<5); -+ /* Enable extended packet length */ -+ phy5461_mod_reg(eth_num, phyaddr, PHY_MII_AUX_CTRLr_FLAGS, PHY_MII_AUX_CTRLr_BANK, PHY_MII_AUX_CTRLr_ADDR, 0x4000, 0x4000); -+ -+ /* Configure interface to MAC */ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_1000X_MII_CTRLr_FLAGS, PHY_1000X_MII_CTRLr_BANK, PHY_1000X_MII_CTRLr_ADDR, &tmp); -+ /* phy5461_ge_init has reset the phy, powering down the unstrapped interface */ -+ /* make sure enabled interfaces are powered up */ -+ /* SGMII (passthrough fiber) or GMII fiber regs */ -+ tmp &= ~MII_CTRL_PD; /* remove power down */ -+ /* -+ * Enable SGMII autonegotiation on the switch side so that the -+ * link status changes are reflected in the switch. -+ * On Bradley devices, LAG failover feature depends on the SerDes -+ * link staus to activate failover recovery. -+ */ -+ tmp |= MII_CTRL_AE; -+ phy5461_wr_reg(eth_num, phyaddr, PHY_1000X_MII_CTRLr_FLAGS, PHY_1000X_MII_CTRLr_BANK, PHY_1000X_MII_CTRLr_ADDR, &tmp); -+ -+ return; -+} -+ -+ -+/* -+ * Function: -+ * phy5461_init -+ * Purpose: -+ * Initialize xgxs6 phys -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * Returns: -+ * 0 -+ */ -+int -+phy5461_init(uint eth_num, uint phyaddr) -+{ -+ uint16 phyid0, phyid1; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID0r_FLAGS, PHY_MII_PHY_ID0r_BANK, PHY_MII_PHY_ID0r_ADDR, &phyid0); -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID1r_FLAGS, PHY_MII_PHY_ID1r_BANK, PHY_MII_PHY_ID1r_ADDR, &phyid1); -+ -+ printf("%s Phy ChipID: 0x%04x:0x%04x\n", __FUNCTION__, phyid1, phyid0); -+ -+ phy5461_reset_setup(eth_num, phyaddr); -+ -+ return 0; -+} -+ -+ -+/* -+ * Function: -+ * phy5461_link_get -+ * Purpose: -+ * Determine the current link up/down status -+ * Parameters: -+ * unit - StrataSwitch unit #. -+ * port - StrataSwitch port #. -+ * link - (OUT) Boolean, true indicates link established. -+ * Returns: -+ * SOC_E_XXX -+ * Notes: -+ * No synchronization performed at this level. -+ */ -+int -+phy5461_link_get(uint eth_num, uint phyaddr, int *link) -+{ -+ uint16 mii_ctrl, mii_stat; -+ uint32 wait; -+ -+ *link = FALSE; /* Default */ -+ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_STATr_FLAGS, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); -+ /* the first read of status register will not show link up, second read will show link up */ -+ if (!(mii_stat & MII_STAT_LA) ) { -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_STATr_FLAGS, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); -+ } -+ -+ if (!(mii_stat & MII_STAT_LA) || (mii_stat == 0xffff)) { -+ /* mii_stat == 0xffff check is to handle removable PHY daughter cards */ -+ return SOC_E_NONE; -+ } -+ -+ /* Link appears to be up; we are done if autoneg is off. */ -+ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ -+ if (!(mii_ctrl & MII_CTRL_AE)) { -+ *link = TRUE; -+ return SOC_E_NONE; -+ } -+ -+ /* -+ * If link appears to be up but autonegotiation is still in -+ * progress, wait for it to complete. For BCM5228, autoneg can -+ * still be busy up to about 200 usec after link is indicated. Also -+ * continue to check link state in case it goes back down. -+ */ -+ for (wait=0; wait<50000; wait++) { -+ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_STATr_FLAGS, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); -+ -+ if (!(mii_stat & MII_STAT_LA)) { -+ /* link is down */ -+ return SOC_E_NONE; -+ } -+ -+ if (mii_stat & MII_STAT_AN_DONE) { -+ /* AutoNegotiation done */ -+ break; -+ } -+ -+ OSL_DELAY(10); -+ } -+ if (wait>=50000) { -+ /* timeout */ -+ return SOC_E_BUSY; -+ } -+ -+ /* Return link state at end of polling */ -+ *link = ((mii_stat & MII_STAT_LA) != 0); -+ -+ return SOC_E_NONE; -+} -+ -+ -+/* -+ * Function: -+ * phy5461_enable_set -+ * Purpose: -+ * Enable/Disable phy -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * enable - on/off state to set -+ * Returns: -+ * 0 -+ */ -+int -+phy5461_enable_set(uint eth_num, uint phyaddr, int enable) -+{ -+ uint16 power_down; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ power_down = (enable) ? 0 : MII_CTRL_PD; -+ -+ phy5461_mod_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, power_down, MII_CTRL_PD); -+ -+ return SOC_E_NONE; -+} -+ -+ -+#ifdef BCMINTERNAL -+/* -+ * Function: -+ * phy5461_speed_set -+ * Purpose: -+ * Set PHY speed -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * speed - link speed in Mbps -+ * Returns: -+ * 0 -+ */ -+int -+phy5461_speed_set(uint eth_num, uint phyaddr, int speed) -+{ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ phy5461_ge_speed_set(eth_num, phyaddr, speed); -+ -+ return 0; -+} -+#endif /* BCMINTERNAL */ -+ -+ -+/* -+ * Function: -+ * phy5461_auto_negotiate_gcd (greatest common denominator). -+ * Purpose: -+ * Determine the current greatest common denominator between -+ * two ends of a link -+ * Parameters: -+ * unit - StrataSwitch unit #. -+ * port - StrataSwitch port #. -+ * speed - (OUT) greatest common speed. -+ * duplex - (OUT) greatest common duplex. -+ * link - (OUT) Boolean, true indicates link established. -+ * Returns: -+ * SOC_E_XXX -+ * Notes: -+ * No synchronization performed at this level. -+ */ -+static int -+phy5461_auto_negotiate_gcd(uint eth_num, uint phyaddr, int *speed, int *duplex) -+{ -+ int t_speed, t_duplex; -+ uint16 mii_ana, mii_anp, mii_stat; -+ uint16 mii_gb_stat, mii_esr, mii_gb_ctrl; -+ -+ mii_gb_stat = 0; /* Start off 0 */ -+ mii_gb_ctrl = 0; /* Start off 0 */ -+ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ANAr_FLAGS, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &mii_ana); -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ANPr_FLAGS, PHY_MII_ANPr_BANK, PHY_MII_ANPr_ADDR, &mii_anp); -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_STATr_FLAGS, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); -+ -+ if (mii_stat & MII_STAT_ES) { /* Supports extended status */ -+ /* -+ * If the PHY supports extended status, check if it is 1000MB -+ * capable. If it is, check the 1000Base status register to see -+ * if 1000MB negotiated. -+ */ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ESRr_FLAGS, PHY_MII_ESRr_BANK, PHY_MII_ESRr_ADDR, &mii_esr); -+ -+ if (mii_esr & (MII_ESR_1000_X_FD | MII_ESR_1000_X_HD | -+ MII_ESR_1000_T_FD | MII_ESR_1000_T_HD)) { -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_GB_STATr_FLAGS, PHY_MII_GB_STATr_BANK, PHY_MII_GB_STATr_ADDR, &mii_gb_stat); -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_GB_CTRLr_FLAGS, PHY_MII_GB_CTRLr_BANK, PHY_MII_GB_CTRLr_ADDR, &mii_gb_ctrl); -+ } -+ } -+ -+ /* -+ * At this point, if we did not see Gig status, one of mii_gb_stat or -+ * mii_gb_ctrl will be 0. This will cause the first 2 cases below to -+ * fail and fall into the default 10/100 cases. -+ */ -+ -+ mii_ana &= mii_anp; -+ -+ if ((mii_gb_ctrl & MII_GB_CTRL_ADV_1000FD) && -+ (mii_gb_stat & MII_GB_STAT_LP_1000FD)) { -+ t_speed = 1000; -+ t_duplex = 1; -+ } else if ((mii_gb_ctrl & MII_GB_CTRL_ADV_1000HD) && -+ (mii_gb_stat & MII_GB_STAT_LP_1000HD)) { -+ t_speed = 1000; -+ t_duplex = 0; -+ } else if (mii_ana & MII_ANA_FD_100) { /* [a] */ -+ t_speed = 100; -+ t_duplex = 1; -+ } else if (mii_ana & MII_ANA_T4) { /* [b] */ -+ t_speed = 100; -+ t_duplex = 0; -+ } else if (mii_ana & MII_ANA_HD_100) { /* [c] */ -+ t_speed = 100; -+ t_duplex = 0; -+ } else if (mii_ana & MII_ANA_FD_10) { /* [d] */ -+ t_speed = 10; -+ t_duplex = 1 ; -+ } else if (mii_ana & MII_ANA_HD_10) { /* [e] */ -+ t_speed = 10; -+ t_duplex = 0; -+ } else { -+ return(SOC_E_FAIL); -+ } -+ -+ if (speed) *speed = t_speed; -+ if (duplex) *duplex = t_duplex; -+ -+ return(SOC_E_NONE); -+} -+ -+ -+/* -+ * Function: -+ * phy5461_speed_get -+ * Purpose: -+ * Get PHY speed -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * speed - current link speed in Mbps -+ * Returns: -+ * 0 -+ */ -+int -+phy5461_speed_get(uint eth_num, uint phyaddr, int *speed, int *duplex) -+{ -+ int rv; -+ uint16 mii_ctrl, mii_stat; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_STATr_FLAGS, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); -+ -+ *speed = 0; -+ *duplex = 0; -+ if (mii_ctrl & MII_CTRL_AE) { /* Auto-negotiation enabled */ -+ if (!(mii_stat & MII_STAT_AN_DONE)) { /* Auto-neg NOT complete */ -+ rv = SOC_E_NONE; -+ } else { -+ rv = phy5461_auto_negotiate_gcd(eth_num, phyaddr, speed, duplex); -+ } -+ } else { /* Auto-negotiation disabled */ -+ /* -+ * Simply pick up the values we force in CTRL register. -+ */ -+ if (mii_ctrl & MII_CTRL_FD) -+ *duplex = 1; -+ -+ switch(MII_CTRL_SS(mii_ctrl)) { -+ case MII_CTRL_SS_10: -+ *speed = 10; -+ break; -+ case MII_CTRL_SS_100: -+ *speed = 100; -+ break; -+ case MII_CTRL_SS_1000: -+ *speed = 1000; -+ break; -+ default: /* Just pass error back */ -+ return(SOC_E_UNAVAIL); -+ } -+ rv = SOC_E_NONE; -+ } -+ -+ return(rv); -+} -+ -+ -+#ifdef BCMINTERNAL -+int -+phy5461_lb_set(uint eth_num, uint phyaddr, int enable) -+{ -+ uint16 mii_ctrl; -+ -+ /* set reset flag */ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ mii_ctrl &= ~MII_CTRL_LE; -+ mii_ctrl |= enable ? MII_CTRL_LE : 0; -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ -+ return 0; -+} -+ -+ -+void -+phy5461_disp_status(uint eth_num, uint phyaddr) -+{ -+ uint16 tmp0, tmp1, tmp2; -+ int speed, duplex; -+ -+ printf("et%d: %s: phyaddr:%d\n", eth_num, __FUNCTION__, phyaddr); -+ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_FLAGS, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &tmp0); -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_STATr_FLAGS, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &tmp1); -+ printf(" MII-Control: 0x%x; MII-Status: 0x%x\n", tmp0, tmp1); -+ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID0r_FLAGS, PHY_MII_PHY_ID0r_BANK, PHY_MII_PHY_ID0r_ADDR, &tmp0); -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID1r_FLAGS, PHY_MII_PHY_ID1r_BANK, PHY_MII_PHY_ID1r_ADDR, &tmp1); -+ printf(" Phy ChipID: 0x%04x:0x%04x\n", tmp0, tmp1); -+ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ANAr_FLAGS, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &tmp0); -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ANPr_FLAGS, PHY_MII_ANPr_BANK, PHY_MII_ANPr_ADDR, &tmp1); -+ phy5461_speed_get(eth_num, phyaddr, &speed, &duplex); -+ printf(" AutoNeg Ad: 0x%x; AutoNeg Partner: 0x%x; speed:%d; duplex:%d\n", tmp0, tmp1, speed, duplex); -+ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_GB_CTRLr_FLAGS, PHY_MII_GB_CTRLr_BANK, PHY_MII_GB_CTRLr_ADDR, &tmp0); -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_GB_STATr_FLAGS, PHY_MII_GB_STATr_BANK, PHY_MII_GB_STATr_ADDR, &tmp1); -+ printf(" MII GB ctrl: 0x%x; MII GB stat: 0x%x\n", tmp0, tmp1); -+ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ESRr_FLAGS, PHY_MII_ESRr_BANK, PHY_MII_ESRr_ADDR, &tmp0); -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MII_ECRr_FLAGS, PHY_MII_ECRr_BANK, PHY_MII_ECRr_ADDR, &tmp1); -+ phy5461_rd_reg(eth_num, phyaddr, 0x00, 0x0000, 0x11, &tmp2); -+ printf(" IEEE Ext stat: 0x%x; PHY Ext ctrl: 0x%x; PHY Ext stat: 0x%x\n", tmp0, tmp1, tmp2); -+ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_MODE_CTRLr_FLAGS, PHY_MODE_CTRLr_BANK, PHY_MODE_CTRLr_ADDR, &tmp0); -+ printf(" Mode Control (Addr 1c shadow 1f): 0x%x\n", tmp0); -+ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_1000X_MII_CTRLr_FLAGS, PHY_1000X_MII_CTRLr_BANK, PHY_1000X_MII_CTRLr_ADDR, &tmp0); -+ phy5461_rd_reg(eth_num, phyaddr, PHY_1000X_MII_CTRLr_FLAGS, PHY_1000X_MII_CTRLr_BANK, 0x01, &tmp1); -+ printf(" 1000-x MII ctrl: 0x%x; 1000-x MII stat: 0x%x\n", tmp0, tmp1); -+ -+ phy5461_rd_reg(eth_num, phyaddr, PHY_1000X_MII_CTRLr_FLAGS, PHY_1000X_MII_CTRLr_BANK, 0x04, &tmp0); -+ phy5461_rd_reg(eth_num, phyaddr, PHY_1000X_MII_CTRLr_FLAGS, PHY_1000X_MII_CTRLr_BANK, 0x05, &tmp1); -+ printf(" 1000-x AutoNeg Ad: 0x%x; 1000-x AutoNeg Partner: 0x%x\n", tmp0, tmp1); -+ -+} -+#endif /* BCMINTERNAL */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5481.c b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5481.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5481.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_phy5481.c 2017-11-09 17:53:44.028289000 +0800 -@@ -0,0 +1,728 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * These routines provide access to the external phy -+ * -+ */ -+ -+/* ---- Include Files ---------------------------------------------------- */ -+#include -+#include -+#include "../../../mdio/iproc_mdio.h" -+#include "bcmiproc_phy.h" -+#include "bcmiproc_phy5481.h" -+ -+/* ---- External Variable Declarations ----------------------------------- */ -+/* ---- External Function Prototypes ------------------------------------- */ -+/* ---- Public Variables ------------------------------------------------- */ -+/* ---- Private Constants and Types -------------------------------------- */ -+/* ---- Private Variables ------------------------------------------------ */ -+ -+/* debug/trace */ -+//#define BCMDBG -+//#define BCMDBG_ERR -+#ifdef BCMDBG -+#define NET_ERROR(args) printf args -+#define NET_TRACE(args) printf args -+#elif defined(BCMDBG_ERR) -+#define NET_ERROR(args) printf args -+#define NET_TRACE(args) -+#else -+#define NET_ERROR(args) -+#define NET_TRACE(args) -+#endif /* BCMDBG */ -+#define NET_REG_TRACE(args) -+ -+ -+#ifndef ASSERT -+#define ASSERT(exp) -+#endif -+ -+ -+/* ==== Public Functions ================================================= */ -+ -+int -+phy5481_wr_reg(uint eth_num, uint phyaddr, uint16 reg_bank, -+ uint8 reg_addr, uint16 *data) -+{ -+ int rv = SOC_E_NONE; -+ uint16 wr_data=*data; -+ -+ NET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ NET_REG_TRACE(("%s going to write phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, wr_data)); -+ -+ switch(reg_addr) { -+ /* Map shadow registers */ -+ case 0x18: -+ if (reg_bank <= 0x0007) { -+ if (reg_bank == 0x0007) { -+ wr_data |= 0x8000; -+ } -+ wr_data = (wr_data & ~(0x0007)) | reg_bank; -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ break; -+ case 0x1C: -+ if (reg_bank <= 0x000F) { -+ wr_data = 0x8000 | (reg_bank << 10) | (wr_data & 0x03FF); -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ break; -+ default: -+ if (reg_addr > 0x001e) { -+ rv = SOC_E_PARAM; -+ } -+ break; -+ } -+ -+ if (SOC_SUCCESS(rv)) { -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, wr_data); -+ } -+ -+ return rv; -+} -+ -+ -+int -+phy5481_rd_reg(uint eth_num, uint phyaddr, uint16 reg_bank, -+ uint8 reg_addr, uint16 *data) -+{ -+ int rv = SOC_E_NONE; -+ -+ NET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ NET_REG_TRACE(("%s going to read phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr)); -+ -+ switch(reg_addr) { -+ /* Map shadow registers */ -+ case 0x18: -+ if (reg_bank <= 0x0007) { -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 12) | 0x7); -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ break; -+ case 0x1C: -+ if (reg_bank <= 0x00F) { -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 10)); -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ break; -+ default: -+ if (reg_addr > 0x001e) { -+ rv = SOC_E_PARAM; -+ } -+ break; -+ } -+ -+ if (SOC_SUCCESS(rv)) { -+ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, data); -+ NET_REG_TRACE(("%s rd phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, *data)); -+ } -+ -+ return rv; -+} -+ -+ -+int -+phy5481_mod_reg(uint eth_num, uint phyaddr, uint16 reg_bank, -+ uint8 reg_addr, uint16 data, uint16 mask) -+{ -+ int rv = SOC_E_NONE; -+ uint16 org_data, rd_data; -+ -+ NET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ NET_REG_TRACE(("%s going to modify phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x) mask(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, data, mask)); -+ -+ switch(reg_addr) { -+ /* Map shadow registers */ -+ case 0x18: -+ if (reg_bank <= 0x0007) { -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 12) | 0x7); -+ if (reg_bank == 0x0007) { -+ data |= 0x8000; -+ mask |= 0x8000; -+ } -+ mask &= ~(0x0007); -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ break; -+ case 0x1C: -+ if (reg_bank <= 0x001F) { -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, (reg_bank << 10)); -+ data |= 0x8000; -+ mask |= 0x8000; -+ mask &= ~(0x1F << 10); -+ } else { -+ rv = SOC_E_PARAM; -+ } -+ break; -+ default: -+ if (reg_addr > 0x001e) { -+ rv = SOC_E_PARAM; -+ } -+ break; -+ } -+ -+ if (SOC_SUCCESS(rv)) { -+ iproc_mii_read(MII_DEV_EXT, phyaddr, reg_addr, &rd_data); -+ NET_REG_TRACE(("%s rd phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); -+ org_data = rd_data; -+ rd_data &= ~(mask); -+ rd_data |= data; -+ iproc_mii_write(MII_DEV_EXT, phyaddr, reg_addr, rd_data); -+ NET_REG_TRACE(("%s wrt phyaddr(0x%x) reg_bank(0x%x) reg_addr(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, reg_bank, reg_addr, rd_data)); -+ } -+ -+ return rv; -+} -+ -+void -+phy5481_ge_reset(uint eth_num, uint phyaddr) -+{ -+ uint16 ctrl; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ /* set reset flag */ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); -+ ctrl |= MII_CTRL_RESET; -+ phy5481_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); -+ -+ SPINWAIT( (!phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl) -+ && (ctrl & MII_CTRL_RESET)), 100000); -+ /* check if out of reset */ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &ctrl); -+ if (ctrl & MII_CTRL_RESET) { -+ /* timeout */ -+ NET_ERROR(("et%d: %s reset not complete\n", eth_num, __FUNCTION__)); -+ } else { -+ NET_ERROR(("et%d: %s reset complete\n", eth_num, __FUNCTION__)); -+ } -+ -+ return; -+} -+ -+ -+/* -+ * Function: -+ * phy5481_ge_init -+ * Purpose: -+ * Initialize the PHY (MII mode) to a known good state. -+ * Parameters: -+ * unit - StrataSwitch unit #. -+ * port - StrataSwitch port #. -+ * Returns: -+ * SOC_E_XXX -+ -+ * Notes: -+ * No synchronization performed at this level. -+ */ -+int -+phy5481_ge_init(uint eth_num, uint phyaddr) -+{ -+ uint16 mii_ana, mii_ctrl, mii_gb_ctrl; -+ -+ /* Reset PHY */ -+ phy5481_ge_reset(eth_num, phyaddr); -+ -+ /* set advertized bits */ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &mii_ana); -+ mii_ana |= MII_ANA_FD_100 | MII_ANA_FD_10; -+ mii_ana |= MII_ANA_HD_100 | MII_ANA_HD_10; -+ phy5481_wr_reg(eth_num, phyaddr, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &mii_ana); -+ -+ -+ mii_ctrl = MII_CTRL_FD | MII_CTRL_SS_1000 | MII_CTRL_AE | MII_CTRL_RAN; -+ mii_gb_ctrl = MII_GB_CTRL_ADV_1000FD | MII_GB_CTRL_PT; -+ -+ phy5481_wr_reg(eth_num, phyaddr, PHY_MII_GB_CTRLr_BANK, PHY_MII_GB_CTRLr_ADDR, &mii_gb_ctrl); -+ phy5481_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ -+ -+ return SOC_E_NONE; -+} -+ -+ -+#ifdef BCMINTERNAL -+/* -+ * Function: -+ * phy5481_ge_speed_set -+ * Purpose: -+ * Set the current operating speed (forced). -+ * Parameters: -+ * unit - StrataSwitch unit #. -+ * port - StrataSwitch port #. -+ * duplex - (OUT) Boolean, true indicates full duplex, false -+ * indicates half. -+ * Returns: -+ * SOC_E_XXX -+ * Notes: -+ * No synchronization performed at this level. Autonegotiation is -+ * not manipulated. -+ */ -+int -+phy5481_ge_speed_set(uint eth_num, uint phyaddr, int speed) -+{ -+ uint16 mii_ctrl; -+ -+ if (speed == 0) { -+ return SOC_E_NONE; -+ } -+ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ -+ mii_ctrl &= ~(MII_CTRL_SS_LSB | MII_CTRL_SS_MSB); -+ switch(speed) { -+ case 10: -+ mii_ctrl |= MII_CTRL_SS_10; -+ break; -+ case 100: -+ mii_ctrl |= MII_CTRL_SS_100; -+ break; -+ case 1000: -+ mii_ctrl |= MII_CTRL_SS_1000; -+ break; -+ default: -+ return SOC_E_CONFIG; -+ } -+ -+ phy5481_wr_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ -+ return SOC_E_NONE; -+} -+#endif /* BCMINTERNAL */ -+ -+void -+phy5481_reset_setup(uint eth_num, uint phyaddr) -+{ -+ -+ NET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ phy5481_ge_init(eth_num, phyaddr); -+ -+ /* copper regs */ -+ /* remove power down */ -+ phy5481_mod_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, 0, MII_CTRL_PD); -+ /* Disable super-isolate */ -+ phy5481_mod_reg(eth_num, phyaddr, PHY_MII_POWER_CTRLr_BANK, PHY_MII_POWER_CTRLr_ADDR, 0, PHY5481_SUPER_ISOLATE_MODE); -+ /* Enable extended packet length */ -+ phy5481_mod_reg(eth_num, phyaddr, PHY_MII_AUX_CTRLr_BANK, PHY_MII_AUX_CTRLr_ADDR, 0x4000, 0x4000); -+ -+ return; -+} -+ -+ -+/* -+ * Function: -+ * phy5481_init -+ * Purpose: -+ * Initialize xgxs6 phys -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * Returns: -+ * 0 -+ */ -+int -+phy5481_init(uint eth_num, uint phyaddr) -+{ -+ uint16 phyid0, phyid1; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID0r_BANK, PHY_MII_PHY_ID0r_ADDR, &phyid0); -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID1r_BANK, PHY_MII_PHY_ID1r_ADDR, &phyid1); -+ -+ printf("%s phyaddr(0x%x) Phy ChipID: 0x%04x:0x%04x\n", __FUNCTION__, phyaddr, phyid1, phyid0); -+ -+ phy5481_reset_setup(eth_num, phyaddr); -+ -+ return 0; -+} -+ -+ -+/* -+ * Function: -+ * phy5481_link_get -+ * Purpose: -+ * Determine the current link up/down status -+ * Parameters: -+ * unit - StrataSwitch unit #. -+ * port - StrataSwitch port #. -+ * link - (OUT) Boolean, true indicates link established. -+ * Returns: -+ * SOC_E_XXX -+ * Notes: -+ * No synchronization performed at this level. -+ */ -+int -+phy5481_link_get(uint eth_num, uint phyaddr, int *link) -+{ -+ uint16 mii_ctrl, mii_stat; -+ uint32 wait; -+ -+ *link = FALSE; /* Default */ -+ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); -+ /* the first read of status register will not show link up, second read will show link up */ -+ if (!(mii_stat & MII_STAT_LA) ) { -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); -+ } -+ -+ if (!(mii_stat & MII_STAT_LA) || (mii_stat == 0xffff)) { -+ /* mii_stat == 0xffff check is to handle removable PHY daughter cards */ -+ return SOC_E_NONE; -+ } -+ -+ /* Link appears to be up; we are done if autoneg is off. */ -+ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ -+ if (!(mii_ctrl & MII_CTRL_AE)) { -+ *link = TRUE; -+ return SOC_E_NONE; -+ } -+ -+ /* -+ * If link appears to be up but autonegotiation is still in -+ * progress, wait for it to complete. For BCM5228, autoneg can -+ * still be busy up to about 200 usec after link is indicated. Also -+ * continue to check link state in case it goes back down. -+ * wait 500ms (500000us/10us = 50000 ) -+ */ -+ for (wait=0; wait<50000; wait++) { -+ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); -+ -+ if (!(mii_stat & MII_STAT_LA)) { -+ /* link is down */ -+ return SOC_E_NONE; -+ } -+ -+ if (mii_stat & MII_STAT_AN_DONE) { -+ /* AutoNegotiation done */ -+ break; -+ } -+ -+ OSL_DELAY(10); -+ } -+ if (wait>=50000) { -+ /* timeout */ -+ return SOC_E_BUSY; -+ } -+ -+ /* Return link state at end of polling */ -+ *link = ((mii_stat & MII_STAT_LA) != 0); -+ -+ return SOC_E_NONE; -+} -+ -+/* -+ * Function: -+ * phy5481_enable_set -+ * Purpose: -+ * Enable/Disable phy -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * enable - on/off state to set -+ * Returns: -+ * 0 -+ */ -+int -+phy5481_enable_set(uint eth_num, uint phyaddr, int enable) -+{ -+ uint16 power_down; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ power_down = (enable) ? 0 : MII_CTRL_PD; -+ -+ phy5481_mod_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, power_down, MII_CTRL_PD); -+ -+ return SOC_E_NONE; -+} -+ -+ -+#ifdef BCMINTERNAL -+ -+/* -+ * Function: -+ * phy5481_speed_set -+ * Purpose: -+ * Set PHY speed -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * speed - link speed in Mbps -+ * Returns: -+ * 0 -+ */ -+int -+phy5481_speed_set(uint eth_num, uint phyaddr, int speed) -+{ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ phy5481_ge_speed_set(eth_num, phyaddr, speed); -+ -+ return 0; -+} -+#endif /* BCMINTERNAL */ -+ -+ -+/* -+ * Function: -+ * phy5481_auto_negotiate_gcd (greatest common denominator). -+ * Purpose: -+ * Determine the current greatest common denominator between -+ * two ends of a link -+ * Parameters: -+ * unit - StrataSwitch unit #. -+ * port - StrataSwitch port #. -+ * speed - (OUT) greatest common speed. -+ * duplex - (OUT) greatest common duplex. -+ * link - (OUT) Boolean, true indicates link established. -+ * Returns: -+ * SOC_E_XXX -+ * Notes: -+ * No synchronization performed at this level. -+ */ -+static int -+phy5481_auto_negotiate_gcd(uint eth_num, uint phyaddr, int *speed, int *duplex) -+{ -+ int t_speed, t_duplex; -+ uint16 mii_ana, mii_anp, mii_stat; -+ uint16 mii_gb_stat, mii_esr, mii_gb_ctrl; -+ -+ mii_gb_stat = 0; /* Start off 0 */ -+ mii_gb_ctrl = 0; /* Start off 0 */ -+ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &mii_ana); -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_ANPr_BANK, PHY_MII_ANPr_ADDR, &mii_anp); -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); -+ -+ if (mii_stat & MII_STAT_ES) { /* Supports extended status */ -+ /* -+ * If the PHY supports extended status, check if it is 1000MB -+ * capable. If it is, check the 1000Base status register to see -+ * if 1000MB negotiated. -+ */ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_ESRr_BANK, PHY_MII_ESRr_ADDR, &mii_esr); -+ -+ if (mii_esr & (MII_ESR_1000_X_FD | MII_ESR_1000_X_HD | -+ MII_ESR_1000_T_FD | MII_ESR_1000_T_HD)) { -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_GB_STATr_BANK, PHY_MII_GB_STATr_ADDR, &mii_gb_stat); -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_GB_CTRLr_BANK, PHY_MII_GB_CTRLr_ADDR, &mii_gb_ctrl); -+ } -+ } -+ -+ /* -+ * At this point, if we did not see Gig status, one of mii_gb_stat or -+ * mii_gb_ctrl will be 0. This will cause the first 2 cases below to -+ * fail and fall into the default 10/100 cases. -+ */ -+ -+ mii_ana &= mii_anp; -+ -+ if ((mii_gb_ctrl & MII_GB_CTRL_ADV_1000FD) && -+ (mii_gb_stat & MII_GB_STAT_LP_1000FD)) { -+ t_speed = 1000; -+ t_duplex = 1; -+ } else if ((mii_gb_ctrl & MII_GB_CTRL_ADV_1000HD) && -+ (mii_gb_stat & MII_GB_STAT_LP_1000HD)) { -+ t_speed = 1000; -+ t_duplex = 0; -+ } else if (mii_ana & MII_ANA_FD_100) { /* [a] */ -+ t_speed = 100; -+ t_duplex = 1; -+ } else if (mii_ana & MII_ANA_T4) { /* [b] */ -+ t_speed = 100; -+ t_duplex = 0; -+ } else if (mii_ana & MII_ANA_HD_100) { /* [c] */ -+ t_speed = 100; -+ t_duplex = 0; -+ } else if (mii_ana & MII_ANA_FD_10) { /* [d] */ -+ t_speed = 10; -+ t_duplex = 1 ; -+ } else if (mii_ana & MII_ANA_HD_10) { /* [e] */ -+ t_speed = 10; -+ t_duplex = 0; -+ } else { -+ return(SOC_E_FAIL); -+ } -+ -+ if (speed) *speed = t_speed; -+ if (duplex) *duplex = t_duplex; -+ -+ return(SOC_E_NONE); -+} -+ -+ -+/* -+ * Function: -+ * phy5481_speed_get -+ * Purpose: -+ * Get PHY speed -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * speed - current link speed in Mbps -+ * Returns: -+ * 0 -+ */ -+int -+phy5481_speed_get(uint eth_num, uint phyaddr, int *speed, int *duplex) -+{ -+ int rv; -+ uint16 mii_ctrl, mii_stat; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &mii_stat); -+ -+ *speed = 0; -+ *duplex = 0; -+ if (mii_ctrl & MII_CTRL_AE) { /* Auto-negotiation enabled */ -+ if (!(mii_stat & MII_STAT_AN_DONE)) { /* Auto-neg NOT complete */ -+ rv = SOC_E_NONE; -+ } else { -+ rv = phy5481_auto_negotiate_gcd(eth_num, phyaddr, speed, duplex); -+ } -+ } else { /* Auto-negotiation disabled */ -+ /* -+ * Simply pick up the values we force in CTRL register. -+ */ -+ if (mii_ctrl & MII_CTRL_FD) -+ *duplex = 1; -+ -+ switch(MII_CTRL_SS(mii_ctrl)) { -+ case MII_CTRL_SS_10: -+ *speed = 10; -+ break; -+ case MII_CTRL_SS_100: -+ *speed = 100; -+ break; -+ case MII_CTRL_SS_1000: -+ *speed = 1000; -+ break; -+ default: /* Just pass error back */ -+ return(SOC_E_UNAVAIL); -+ } -+ rv = SOC_E_NONE; -+ } -+ -+ return(rv); -+} -+ -+ -+#ifdef BCMINTERNAL -+int -+phy5481_lb_set(uint eth_num, uint phyaddr, int enable) -+{ -+ uint16 mii_ctrl; -+ -+ /* set reset flag */ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ mii_ctrl &= ~MII_CTRL_LE; -+ mii_ctrl |= enable ? MII_CTRL_LE : 0; -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &mii_ctrl); -+ -+ return 0; -+} -+#endif /* BCMINTERNAL */ -+ -+ -+#ifdef BCMINTERNAL -+void -+phy5481_disp_status(uint eth_num, uint phyaddr) -+{ -+ uint16 tmp0, tmp1, tmp2; -+ int speed, duplex; -+ -+ printf("et%d: %s: phyaddr:%d\n", eth_num, __FUNCTION__, phyaddr); -+ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_CTRLr_BANK, PHY_MII_CTRLr_ADDR, &tmp0); -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &tmp1); -+ printf(" MII-Control: 0x%x; MII-Status: 0x%x\n", tmp0, tmp1); -+ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID0r_BANK, PHY_MII_PHY_ID0r_ADDR, &tmp0); -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_PHY_ID1r_BANK, PHY_MII_PHY_ID1r_ADDR, &tmp1); -+ printf(" Phy ChipID: 0x%04x:0x%04x\n", tmp0, tmp1); -+ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_ANAr_BANK, PHY_MII_ANAr_ADDR, &tmp0); -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_ANPr_BANK, PHY_MII_ANPr_ADDR, &tmp1); -+ phy5481_speed_get(eth_num, phyaddr, &speed, &duplex); -+ printf(" AutoNeg Ad: 0x%x; AutoNeg Partner: 0x%x; speed:%d; duplex:%d\n", tmp0, tmp1, speed, duplex); -+ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_ESRr_BANK, PHY_MII_ESRr_ADDR, &tmp0); -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_ECRr_BANK, PHY_MII_ECRr_ADDR, &tmp1); -+ phy5481_rd_reg(eth_num, phyaddr, 0x0000, 0x11, &tmp2); -+ printf(" Reg0x0f: 0x%x; 100Base-X AUX ctrl: 0x%x; 100Base-X AUX stat: 0x%x\n", tmp0, tmp1, tmp2); -+ -+ phy5481_rd_reg(eth_num, phyaddr, 0x0000, 0x12, &tmp0); -+ phy5481_rd_reg(eth_num, phyaddr, 0x0000, 0x13, &tmp1); -+ phy5481_rd_reg(eth_num, phyaddr, 0x0000, 0x14, &tmp2); -+ printf(" 100Base-X RCV ERR: 0x%x; 100Base-X FALSE CARRIER: 0x%x; 100Base-X DISCON: 0x%x\n", tmp0, tmp1, tmp2); -+} -+#endif /* BCMINTERNAL */ -+ -+ -+#ifdef BCMINTERNAL -+void -+phy5481_chk_err(uint eth_num, uint phyaddr) -+{ -+ uint16 tmp0; -+ -+ phy5481_rd_reg(eth_num, phyaddr, PHY_MII_STATr_BANK, PHY_MII_STATr_ADDR, &tmp0); -+ if (!(tmp0 & MII_STAT_LA)) -+ printf("ERROR: reg 0x01 (LINK down): 0x%x\n", tmp0); -+ if (tmp0 & (MII_STAT_JBBR|MII_STAT_RF)) { -+ printf("ERROR: reg 0x01: 0x%x\n", tmp0); -+ } -+ -+ phy5481_rd_reg(eth_num, phyaddr, 0, 0x11, &tmp0); -+ if (!(tmp0 & 0x100)) { -+ printf("ERROR: reg 0x11 (LINK down): 0x%x\n", tmp0); -+ } -+ if (tmp0 & 0x8bf) { -+ printf("ERROR: reg 0x11: 0x%x\n", tmp0); -+ } -+ -+ phy5481_rd_reg(eth_num, phyaddr, 0, 0x12, &tmp0); -+ if (tmp0) { -+ printf("ERROR: reg 0x12 (RCV ERR CNT): 0x%x\n", tmp0); -+ } -+ -+ phy5481_rd_reg(eth_num, phyaddr, 0, 0x13, &tmp0); -+ if (tmp0) { -+ printf("ERROR: reg 0x13 (FALSE CARRIER CNT): 0x%x\n", tmp0); -+ } -+ -+ phy5481_rd_reg(eth_num, phyaddr, 0, 0x14, &tmp0); -+ if (tmp0 & 0xc000) { -+ printf("ERROR: reg 0x14: 0x%x\n", tmp0); -+ } -+ -+ phy5481_rd_reg(eth_num, phyaddr, 0, 0x19, &tmp0); -+ if (!(tmp0 & 0x4)) { -+ printf("ERROR: reg 0x19 (LINK down): 0x%x\n", tmp0); -+ } -+ if (tmp0 & 0xc0) { -+ printf("ERROR: reg 0x19: 0x%x\n", tmp0); -+ } -+} -+#endif /* BCMINTERNAL */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_serdes.c b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_serdes.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_serdes.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmiproc_serdes.c 2017-11-09 17:53:44.029293000 +0800 -@@ -0,0 +1,879 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * These routines provide access to the serdes -+ * -+ */ -+ -+/* ---- Include Files ---------------------------------------------------- */ -+#include -+#include -+#include "bcmiproc_serdes.h" -+#include "bcmiproc_serdes_def.h" -+#include "../../../mdio/iproc_mdio.h" -+ -+/* ---- External Variable Declarations ----------------------------------- */ -+/* ---- External Function Prototypes ------------------------------------- */ -+/* ---- Public Variables ------------------------------------------------- */ -+/* ---- Private Constants and Types -------------------------------------- */ -+/* ---- Private Variables ------------------------------------------------ */ -+ -+/* debug/trace */ -+//#define BCMDBG -+//#define BCMDBG_ERR -+#ifdef BCMDBG -+#define NET_ERROR(args) printf args -+#define NET_TRACE(args) printf args -+#elif defined(BCMDBG_ERR) -+#define NET_ERROR(args) printf args -+#define NET_TRACE(args) -+#else -+#define NET_ERROR(args) -+#define NET_TRACE(args) -+#endif /* BCMDBG */ -+#define NET_REG_TRACE(args) -+ -+ -+#ifndef ASSERT -+#define ASSERT(exp) -+#endif -+ -+ -+#if defined(CONFIG_MACH_SB2) -+/* CL22 register access for VIPERCORE in Saber2 */ -+#define PHY_AER_REG_ADDR_AER(_addr) (((_addr) >> 16) & 0x0000FFFF) -+#define PHY_AER_REG_ADDR_BLK(_addr) (((_addr) & 0x0000FFF0)) -+#define PHY_AER_REG_ADDR_REGAD(_addr) ((((_addr) & 0x00008000) >> 11) | \ -+ ((_addr) & 0x0000000F)) -+#endif -+ -+/* ==== Public Functions ================================================= */ -+ -+void -+serdes_set_blk(uint eth_num, uint phyaddr, uint blk) -+{ -+ uint16 blkaddr; -+ uint16 destblk = (uint16)blk; -+ -+ NET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ NET_REG_TRACE(("%s phyaddr(0x%x) blk(0x%x)\n", -+ __FUNCTION__, phyaddr, blk)); -+ -+ /* check if need to update blk addr */ -+ iproc_mii_read(MII_DEV_LOCAL, phyaddr, PHY_REG_BLK_ADDR, &blkaddr); -+ if (blkaddr!=destblk) { -+ /* write block address */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, PHY_REG_BLK_ADDR, destblk); -+ } -+} -+ -+ -+void -+serdes_wr_reg(uint eth_num, uint phyaddr, uint reg, uint data) -+{ -+ uint16 tmpdata=(uint16)data; -+#if defined(CONFIG_MACH_SB2) -+ uint16 phy_reg_aer = 0, phy_reg_blk = 0, phy_reg_addr = 0; -+ -+ phy_reg_aer = PHY_AER_REG_ADDR_AER(reg); /* upper 16 bits */ -+ phy_reg_blk = PHY_AER_REG_ADDR_BLK(reg); /* 12 bits mask=0xfff0 */ -+ phy_reg_addr = PHY_AER_REG_ADDR_REGAD(reg); /* 5 bits {15,3,2,1,0} */ -+ -+ if (phy_reg_aer != 0) { -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0xffd0); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001e, phy_reg_aer); -+ } -+ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, phy_reg_blk); /* Map block */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, phy_reg_addr, tmpdata); /* write register */ -+ -+ if (phy_reg_aer != 0) { -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0xffd0); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001e, 0x0); -+ } -+#else -+ uint blk = reg&0x7ff0; -+ uint off = reg&0x000f; -+ -+ NET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ if (reg&0x8000) -+ off|=0x10; -+ -+ /* set block address */ -+ serdes_set_blk(eth_num, phyaddr, blk); -+ -+ NET_REG_TRACE(("%s wrt phyaddr(0x%x) reg(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, reg, tmpdata)); -+ //printf("%s wrt phyaddr(0x%x) reg(0x%x) data(0x%x)\n", -+ // __FUNCTION__, phyaddr, reg, tmpdata); -+ /* write register */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, off, tmpdata); -+#endif -+} -+ -+ -+uint16 -+serdes_rd_reg(uint eth_num, uint phyaddr, uint reg) -+{ -+ uint16 data; -+#if defined(CONFIG_MACH_SB2) -+ uint16 phy_reg_aer = 0, phy_reg_blk = 0, phy_reg_addr = 0; -+ -+ phy_reg_aer = PHY_AER_REG_ADDR_AER(reg); /* upper 16 bits */ -+ phy_reg_blk = PHY_AER_REG_ADDR_BLK(reg); /* 12 bits mask=0xfff0 */ -+ phy_reg_addr = PHY_AER_REG_ADDR_REGAD(reg); /* 5 bits {15,3,2,1,0} */ -+ -+ if (phy_reg_aer != 0) { -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0xffd0); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001e, phy_reg_aer); -+ } -+ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, phy_reg_blk); /* Map block */ -+ iproc_mii_read(MII_DEV_LOCAL, phyaddr, phy_reg_addr, &data); /* read register */ -+ -+ if (phy_reg_aer != 0) { -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0xffd0); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001e, 0x0); -+ } -+#else -+ uint blk = reg&0x7ff0; -+ uint off = reg&0x000f; -+ -+ NET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ if (reg&0x8000) -+ off|=0x10; -+ -+ /* set block address */ -+ serdes_set_blk(eth_num, phyaddr, blk); -+ -+ /* read register */ -+ iproc_mii_read(MII_DEV_LOCAL, phyaddr, off, &data); -+ NET_REG_TRACE(("%s rd phyaddr(0x%x) reg(0x%x) data(0x%x)\n", -+ __FUNCTION__, phyaddr, reg, data)); -+ //printf("%s rd phyaddr(0x%x) reg(0x%x) data(0x%x)\n", -+ // __FUNCTION__, phyaddr, reg, data); -+#endif -+ -+ return data; -+} -+ -+ -+uint16 -+serdes_get_id(uint eth_num, uint phyaddr, uint off) -+{ -+ -+ ASSERT(phyaddr < MAXEPHY); -+ -+ if (phyaddr == EPHY_NOREG) -+ return 0; -+ -+ /* read the id high */ -+ return serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESID_SERDESID0r+off); -+} -+ -+ -+void -+serdes_reset(uint eth_num, uint phyaddr) -+{ -+ uint16 ctrl; -+ -+ ASSERT(phyaddr < MAXEPHY); -+ -+ if (phyaddr == EPHY_NOREG) -+ return; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ /* set reset flag */ -+ ctrl = serdes_rd_reg(eth_num, phyaddr, XGXS16G_IEEE0BLK_IEEECONTROL0r); -+ ctrl |= IEEE0BLK_IEEECONTROL0_RST_HW_MASK; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_IEEE0BLK_IEEECONTROL0r, ctrl); -+ udelay(100); -+ /* check if out of reset */ -+ if (serdes_rd_reg(eth_num, phyaddr, XGXS16G_IEEE0BLK_IEEECONTROL0r) & IEEE0BLK_IEEECONTROL0_RST_HW_MASK) { -+ NET_ERROR(("et%d: %s reset not complete\n", eth_num, __FUNCTION__)); -+ } -+} -+ -+ -+int -+serdes_reset_core(uint eth_num, uint phyaddr) -+{ -+ uint16 data16; -+ uint16 serdes_id2; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ /* get serdes id */ -+ serdes_id2 = serdes_get_id(eth_num, phyaddr, 2); -+ printf("et%d %s pbyaddr(0x%x) id2(0x%x)\n", eth_num, __FUNCTION__, phyaddr, serdes_id2); -+ -+ /* unlock lane */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, WC40_DIGITAL4_MISC3r); -+ data16 &= ~(DIGITAL4_MISC3_LANEDISABLE_MASK); -+ serdes_wr_reg(eth_num, phyaddr, WC40_DIGITAL4_MISC3r, data16); -+ -+ if ( phyaddr == 1 ) { -+ /* Reset the core */ -+ /* Stop PLL Sequencer and configure the core into correct mode */ -+ data16 = (XGXSBLK0_XGXSCONTROL_MODE_10G_IndLane << -+ XGXSBLK0_XGXSCONTROL_MODE_10G_SHIFT) | -+ XGXSBLK0_XGXSCONTROL_HSTL_MASK | -+ XGXSBLK0_XGXSCONTROL_CDET_EN_MASK | -+ XGXSBLK0_XGXSCONTROL_EDEN_MASK | -+ XGXSBLK0_XGXSCONTROL_AFRST_EN_MASK | -+ XGXSBLK0_XGXSCONTROL_TXCKO_DIV_MASK; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_XGXSCONTROLr, data16); -+ -+ /* Disable IEEE block select auto-detect. -+ * The driver will select desired block as necessary. -+ * By default, the driver keeps the XAUI block in -+ * IEEE address space. -+ */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_MISCCONTROL1r); -+ if (XGXS16G_2p5G_ID(serdes_id2)) { -+ data16 &= ~( XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_MASK | -+ XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_MASK); -+ } else { -+ data16 &= ~( XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_MASK | -+ XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_MASK); -+#if (!defined(CONFIG_MACH_KT2)) -+ data16 |= XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_MASK; -+#endif /* (!defined(CONFIG_MACH_KT2)) */ -+ } -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_MISCCONTROL1r, data16); -+ -+ /* disable in-band MDIO. PHY-443 */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, 0x8111); -+ /* rx_inBandMdio_rst */ -+ data16 |= 1 << 3; -+ serdes_wr_reg(eth_num, phyaddr, 0x8111, data16); -+ } -+ return 0; -+} -+ -+ -+int -+serdes_start_pll(uint eth_num, uint phyaddr) -+{ -+ uint16 data16; -+ -+ if ( phyaddr == 1 ) { -+ uint32 count=250; -+ /* Start PLL Sequencer and wait for PLL to lock */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_XGXSCONTROLr); -+ data16 |= XGXSBLK0_XGXSCONTROL_START_SEQUENCER_MASK; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_XGXSCONTROLr, data16); -+ -+ /* wait for PLL to lock */ -+ while (count!=0) { -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_XGXSSTATUSr); -+ if ( data16 & XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_MASK ) { -+ break; -+ } -+ /* wait 1 usec then dec counter */ -+ udelay(10); -+ count--; -+ } -+ if (count == 0) { -+ NET_ERROR(("%s TXPLL did not lock\n", __FUNCTION__)); -+ } -+ } -+ return 0; -+} -+ -+ -+/* -+ * Function: -+ * serdes_init -+ * Purpose: -+ * Initialize xgxs6 phys -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * Returns: -+ * 0 -+ */ -+int -+serdes_init(uint eth_num, uint phyaddr) -+{ -+#if defined(CONFIG_MACH_SB2) -+ -+#if 0 -+ /* Speed = 10M */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0c2f); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8300); -+ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0120); /* Mode = AN */ -+ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0000); /* Mode = Force */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); -+ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0000, 0x1100); /* Mode = AN */ -+ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0000, 0x0100); /* Mode = Force */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x2c2f); -+#endif -+ -+#if 0 -+ /* Speed = 100M */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0c2f); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8300); -+ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0120); /* Mode = AN */ -+ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0000); /* Mode = Force */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); -+ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0000, 0x3100); /* Mode = AN */ -+ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0000, 0x2100); /* Mode = Force */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x2c2f); -+#endif -+ -+#if 0 -+ /* Speed = 1G SGMII */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0c2f); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8300); -+ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0120); /* Mode = AN */ -+ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0000); /* Mode = Force */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); -+ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0000, 0x1140); /* Mode = AN */ -+ // iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0000, 0x0140); /* Mode = Force */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x2c3f); -+#endif -+ -+#if 1 -+ /* Auto Negotiation 10M/100M/1G ¡V SGMII Slave */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0c2f); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8300); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0100); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0000, 0x1140); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x2c3f); -+#endif -+ -+#else -+ -+ uint16 data16; -+ uint16 serdes_id0, serdes_id1, serdes_id2; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ /* get serdes id */ -+ serdes_id0 = serdes_get_id(eth_num, phyaddr, 0); -+ serdes_id1 = serdes_get_id(eth_num, phyaddr, 1); -+ serdes_id2 = serdes_get_id(eth_num, phyaddr, 2); -+ printf("%s phyaddr(0x%x) id0(0x%x) id1(0x%x) id2(0x%x)\n", __FUNCTION__, phyaddr, serdes_id0, serdes_id1, serdes_id2); -+ -+ /* get more ids */ -+ serdes_id0 = serdes_rd_reg(eth_num, phyaddr, 2); -+ serdes_id1 = serdes_rd_reg(eth_num, phyaddr, 3); -+ //printf("%s phyaddr(0x%x) SERDES PhyID_MS(0x%x) PhyID_LS(0x%x)\n", __FUNCTION__, phyaddr, serdes_id0, serdes_id1); -+ -+ /* unlock lane */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, WC40_DIGITAL4_MISC3r); -+ data16 &= ~(DIGITAL4_MISC3_LANEDISABLE_MASK); -+ serdes_wr_reg(eth_num, phyaddr, WC40_DIGITAL4_MISC3r, data16); -+ -+ /* disable CL73 BAM */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, 0x8372); -+ data16 &= ~(CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_MASK); -+ serdes_wr_reg(eth_num, phyaddr, 0x8372, data16); -+ -+ /* Set Local Advertising Configuration */ -+ data16 = MII_ANA_C37_FD | MII_ANA_C37_PAUSE | MII_ANA_C37_ASYM_PAUSE; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_AUTONEGADVr, data16); -+ -+ /* Disable BAM in Independent Lane mode. Over1G AN not supported */ -+ data16 = 0; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_BAM_NEXTPAGE_MP5_NEXTPAGECTRLr, data16); -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_BAM_NEXTPAGE_UD_FIELDr, data16); -+ -+ data16 = SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_MASK | -+ SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_MASK; -+ /* -+ * Put the Serdes in SGMII mode -+ * bit0 = 0; in SGMII mode -+ */ -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X1r, data16); -+ -+ /* set autoneg */ -+ data16 = MII_CTRL_AE | MII_CTRL_RAN; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_MIICNTLr, data16); -+ -+ /* Disable 10G parallel detect */ -+ data16 = 0; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_AN73_PDET_PARDET10GCONTROLr, data16); -+ -+ /* Disable BAM mode and Teton mode */ -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_BAM_NEXTPAGE_MP5_NEXTPAGECTRLr, data16); -+ -+ /* Enable lanes */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK1_LANECTRL0r); -+ data16 |= XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_MASK | -+ XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_MASK; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_XGXSBLK1_LANECTRL0r, data16); -+ -+ /* set elasticity fifo size to 13.5k to support 12k jumbo pkt size*/ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r); -+ data16 &= SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_MASK; -+ data16 |= (1 << 2); -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r, data16); -+ -+ /* Enabble LPI passthru' for native mode EEE */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_REMOTEPHY_MISC5r); -+ data16 |= 0xc000; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_REMOTEPHY_MISC5r, data16); -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK7_EEECONTROLr); -+ data16 |= 0x0007; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_XGXSBLK7_EEECONTROLr, data16); -+#endif -+ -+ return 0; -+} -+ -+ -+#ifdef BCMINTERNAL -+/* -+ * Function: -+ * serdes_enable_set -+ * Purpose: -+ * Enable/Disable phy -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * enable - on/off state to set -+ * Returns: -+ * 0 -+ */ -+int -+serdes_enable_set(uint eth_num, uint phyaddr, int enable) -+{ -+ uint16 data16, mask16; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK1_LANECTRL3r); -+ mask16 = (1 << (phyaddr-1)); /* rx lane */ -+ mask16 |= (mask16 << 4); /* add tx lane */ -+ mask16 |= 0x800; -+ if (enable) { -+ data16 &= ~(mask16); -+ } else { -+ data16 &= ~(mask16); -+ data16 |= mask16; -+ } -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_XGXSBLK1_LANECTRL3r, data16); -+ -+ return 0; -+} -+ -+ -+/* -+ * Function: -+ * serdes_speed_set -+ * Purpose: -+ * Set PHY speed -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * speed - link speed in Mbps -+ * Returns: -+ * 0 -+ */ -+int -+serdes_speed_set(uint eth_num, uint phyaddr, int speed) -+{ -+ uint16 speed_val, mask; -+ uint16 data16; -+ uint16 speed_mii; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ if (speed > 1000) { -+ return -1; -+ } -+ -+ speed_val = 0; -+ speed_mii = 0; -+ mask = SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_MASK | -+ SERDESDIGITAL_MISC1_FORCE_SPEED_MASK; -+ -+ switch (speed) { -+ case 0: -+ /* Do not change speed */ -+ return 0; -+ case 10: -+ speed_mii = MII_CTRL_SS_10; -+ break; -+ case 100: -+ speed_mii = MII_CTRL_SS_100; -+ break; -+ case 1000: -+ speed_mii = MII_CTRL_SS_1000; -+ break; -+ default: -+ return -1; -+ } -+ -+ /* Hold rxSeqStart */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr); -+ data16 |= DSC_2_0_DSC_CTRL0_RXSEQSTART_MASK; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr, data16); -+ -+ /* hold TX FIFO in reset */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r); -+ data16 |= SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_MASK; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r, data16); -+ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_MISC1r); -+ data16 &= ~(mask); -+ data16 |= speed_val; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_MISC1r, data16); -+ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_MIICNTLr); -+ data16 &= ~(MII_CTRL_AE | MII_CTRL_SS_LSB | MII_CTRL_SS_MSB); -+ data16 |= speed_mii; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_MIICNTLr, data16); -+ -+ /* release rxSeqStart */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr); -+ data16 &= ~(DSC_2_0_DSC_CTRL0_RXSEQSTART_MASK); -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr, data16); -+ -+ /* release TX FIFO reset */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r); -+ data16 &= ~(SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_MASK); -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r, data16); -+ -+ return 0; -+} -+ -+ -+/* -+ * Function: -+ * serdes_speed_get -+ * Purpose: -+ * Get PHY speed -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * speed - current link speed in Mbps -+ * Returns: -+ * 0 -+ */ -+int -+serdes_speed_get(uint eth_num, uint phyaddr, int *speed) -+{ -+ uint16 data16; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_STATUS1000X1r); -+ -+ data16 &= SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_MASK; -+ data16 >>= SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_SHIFT; -+ -+ if (data16 == 3) { -+ *speed= 2500; -+ } else if (data16 == 2) { -+ *speed= 1000; -+ } else if (data16 == 1) { -+ *speed= 100; -+ } else { -+ *speed= 10; -+ } -+ -+ return 0; -+} -+ -+ -+/* -+ * Function: -+ * phy_xgxs16g1l_lb_set -+ * Purpose: -+ * Put XGXS6/FusionCore in PHY loopback -+ * Parameters: -+ * unit - StrataSwitch unit #. -+ * port - StrataSwitch port #. -+ * enable - binary value for on/off (1/0) -+ * Returns: -+ * 0 -+ */ -+int -+serdes_lb_set(uint eth_num, uint phyaddr, int enable) -+{ -+ uint16 misc_ctrl, data16; -+ uint16 lb_bit; -+ uint16 lb_mask; -+ -+ /* Configure Loopback in XAUI */ -+ misc_ctrl = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_MISCCONTROL1r); -+ if (misc_ctrl & XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_MASK) { -+ /* PCS */ -+ lb_bit = (enable) ? IEEE0BLK_IEEECONTROL0_GLOOPBACK_MASK : 0; -+ lb_mask = IEEE0BLK_IEEECONTROL0_GLOOPBACK_MASK; -+ } else if (misc_ctrl & XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_MASK) { -+ /* PMA/PMD */ -+ lb_bit = (enable) ? 1 : 0; -+ lb_mask = 1; -+ } else { -+ /* PHY XS, DTE XS */ -+ lb_bit = (enable) ? IEEE0BLK_IEEECONTROL0_GLOOPBACK_MASK : 0; -+ lb_mask = IEEE0BLK_IEEECONTROL0_GLOOPBACK_MASK; -+ } -+ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_IEEE0BLK_IEEECONTROL0r); -+ data16 &= ~(lb_mask); -+ data16 |= lb_bit; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_IEEE0BLK_IEEECONTROL0r, data16); -+ -+ /* Configure Loopback in SerDes */ -+ lb_bit = (enable) ? MII_CTRL_LE : 0; -+ lb_mask = MII_CTRL_LE; -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_MIICNTLr); -+ data16 &= ~(lb_mask); -+ data16 |= lb_bit; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_MIICNTLr, data16); -+ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_XGXSCONTROLr); -+ data16 |= 0x10; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_XGXSCONTROLr, data16); -+ -+ data16 = serdes_rd_reg(eth_num, phyaddr, 0x8017); -+ data16 = 0xff0f; -+ serdes_wr_reg(eth_num, phyaddr, 0x8017, data16); -+ -+ return 0; -+} -+ -+void -+serdes_disp_status(uint eth_num, uint phyaddr) -+{ -+ uint16 tmp0, tmp1, tmp2, tmp3; -+ -+ printf("et%d: %s: phyaddr:%d\n", eth_num, __FUNCTION__, phyaddr); -+ -+ tmp0 = serdes_get_id(eth_num, phyaddr, 0); -+ tmp1 = serdes_get_id(eth_num, phyaddr, 1); -+ tmp2 = serdes_get_id(eth_num, phyaddr, 2); -+ printf(" id0(0x%x) id1(0x%x) id2(0x%x)\n", tmp0, tmp1, tmp2); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_IEEE0BLK_IEEECONTROL0r); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_IEEE0BLK_IEEECONTROL0r+1); -+ printf(" MII-Control(0): 0x%x; MII-Status(1): 0x%x\n", tmp0, tmp1); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, 2); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, 3); -+ printf(" Phy ChipID(2:3): 0x%04x:0x%04x\n", tmp0, tmp1); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, 4); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, 5); -+ tmp2 = serdes_rd_reg(eth_num, phyaddr, 0xf); -+ printf(" AN AD(4): 0x%x; AN LNK PARTNER(5): 0x%x; EXT STAT(f): 0x%x\n", tmp0, tmp1, tmp2); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_XGXSCONTROLr); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_XGXSSTATUSr); -+ printf(" XGXS-Control(8000): 0x%x; XGXS-Status(8001): 0x%x\n", tmp0, tmp1); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_MMDSELECTr); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK0_MISCCONTROL1r); -+ printf(" XGXS BLK0 MMD Select(800d): 0x%x; XGXS BLK0 MISC CTRL(800e): 0x%x\n", tmp0, tmp1); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK1_LANECTRL0r); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK1_LANECTRL3r); -+ printf(" XGXS BLK1 LNCTRL0(8015): 0x%x; XGXS BLK1_LNCTRL3(8018): 0x%x\n", tmp0, tmp1); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_AN73_PDET_PARDET10GCONTROLr); -+ tmp2 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_XGXSBLK7_EEECONTROLr); -+ printf(" XGXS RX0 CTRL(80b1): 0x%x; XGXS AN73 PARDET CTRL(8131): 0x%x; XGXS BLK7 EEECTRL(8150): 0x%x\n", tmp0, tmp1, tmp2); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, 0x8111); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, 0x8372); -+ printf(" (8111): 0x%x; (8372): 0x%x\n", tmp0, tmp1); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X1r); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X2r); -+ tmp2 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r); -+ printf(" XGXS SERDES DIG CTRL 1000X1(8300): 0x%x; XGXS SERDES DIG CTRL 1000X2(8301): 0x%x; XGXS SERDES DIGITAL CTRL 1000X3r(8302): 0x%x\n", tmp0, tmp1, tmp2); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_STATUS1000X1r); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_MISC1r); -+ printf(" XGXS SERDES DIG STATUS 1000X1(8304): 0x%x; XGXS SERDES DIG MISC1(8308): 0x%x\n", tmp0, tmp1); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESID_SERDESID0r); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESID_SERDESID1r); -+ printf(" XGXS SERDESID0(8310): 0x%x; XGXS SERDESID1(8311): 0x%x\n", tmp0, tmp1); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESID_SERDESID2r); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESID_SERDESID3r); -+ printf(" XGXS SERDESID0(8312): 0x%x; XGXS SERDESID1(8313): 0x%x\n", tmp0, tmp1); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_REMOTEPHY_MISC3r); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_REMOTEPHY_MISC5r); -+ printf(" XGXS REMOTEPHY MISC3(833c): 0x%x; XGXS REMOTEPHY MISC5(833e): 0x%x\n", tmp0, tmp1); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_BAM_NEXTPAGE_MP5_NEXTPAGECTRLr); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_BAM_NEXTPAGE_UD_FIELDr); -+ printf(" XGXS BAM MP5_NEXTPAGECTRL(8350): 0x%x; XGXS BAM NP UD FIELDr(8357): 0x%x\n", tmp0, tmp1); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_MIICNTLr); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_AUTONEGADVr); -+ printf(" XGXS COMBO IEEE0 MIICNTL(ffe0): 0x%x; XGXS COMBO IEEE0 AUTONEGADVr(ffe4): 0x%x\n", tmp0, tmp1); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, 0x8050); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, 0x8122); -+ printf(" (8050): 0x%x; (8122): 0x%x\n", tmp0, tmp1); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, 0x80b0); -+ tmp1 = serdes_rd_reg(eth_num, phyaddr, 0x80c0); -+ tmp2 = serdes_rd_reg(eth_num, phyaddr, 0x80d0); -+ tmp3 = serdes_rd_reg(eth_num, phyaddr, 0x80e0); -+ printf(" (80b0): 0x%x; (80c0): 0x%x; (80d0): 0x%x, (80e0): 0x%x\n", tmp0, tmp1, tmp2, tmp3); -+ -+ tmp0 = serdes_rd_reg(eth_num, phyaddr, 0xffe1); -+ printf(" (ffe1): 0x%x\n", tmp0); -+ -+} -+#endif /* BCMINTERNAL */ -+ -+ -+#if (defined(CONFIG_SERDES_ASYMMETRIC_MODE)) -+/* -+ * Function: -+ * serdes_speeddpx_set -+ * Purpose: -+ * Set serdes speed dpx -+ * Parameters: -+ * eth_num - ethernet data -+ * phyaddr - physical address -+ * speed - link speed in Mbps -+ * fulldpx - link dpx -+ * Returns: -+ * 0 -+ */ -+int -+serdes_speeddpx_set(uint eth_num, uint phyaddr, int speed, int fulldpx) -+{ -+ uint16 speed_val, mask; -+ uint16 data16; -+ uint16 speed_mii; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ if (speed > 1000) { -+ return -1; -+ } -+ -+ speed_val = 0; -+ speed_mii = 0; -+ mask = SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_MASK | -+ SERDESDIGITAL_MISC1_FORCE_SPEED_MASK; -+ -+ switch (speed) { -+ case 0: -+ /* Do not change speed */ -+ return 0; -+ case 10: -+ speed_mii = MII_CTRL_SS_10; -+ break; -+ case 100: -+ speed_mii = MII_CTRL_SS_100; -+ break; -+ case 1000: -+ speed_mii = MII_CTRL_SS_1000; -+ break; -+ default: -+ return -1; -+ } -+ -+ if (fulldpx) -+ speed_mii |= MII_CTRL_FD; -+ -+ /* Hold rxSeqStart */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr); -+ data16 |= DSC_2_0_DSC_CTRL0_RXSEQSTART_MASK; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr, data16); -+ -+ /* hold TX FIFO in reset */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r); -+ data16 |= SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_MASK; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r, data16); -+ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_MISC1r); -+ data16 &= ~(mask); -+ data16 |= speed_val; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_MISC1r, data16); -+ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_MIICNTLr); -+ data16 &= ~(MII_CTRL_AE | MII_CTRL_RAN | MII_CTRL_SS_LSB | MII_CTRL_SS_MSB | MII_CTRL_FD); -+ data16 |= speed_mii; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_COMBO_IEEE0_MIICNTLr, data16); -+ -+ /* release rxSeqStart */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr); -+ data16 &= ~(DSC_2_0_DSC_CTRL0_RXSEQSTART_MASK); -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_RX0_RX_CONTROLr, data16); -+ -+ /* release TX FIFO reset */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r); -+ data16 &= ~(SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_MASK); -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_CONTROL1000X3r, data16); -+ -+ return 0; -+} -+ -+int -+serdes_set_asym_mode(uint eth_num, uint phyaddr) -+{ -+ uint16 data16; -+ uint32 txclkctrlreg[] = {0x0000, 0x8065, 0x8075, 0x8085}; -+ uint32 rxclkctrlreg[] = {0x0000, 0x80bc, 0x80cc, 0x80dc}; -+ uint32 spd[] = {0x0000, 0x7120, 0x7120, 0x7110}; -+ uint32 clkctrlmsk[] = {0x0000, 0x0040, 0x0040, 0x0040}; -+ uint32 clkctrlval[] = {0x0000, 0x0040, 0x0040, 0x0000}; -+ -+ NET_TRACE(("et%d: %s: phyaddr %d\n", eth_num, __FUNCTION__, phyaddr)); -+ -+ printk("et%d: %s: setting serdes asymmetrice mode\n", eth_num, __FUNCTION__); -+ -+ /* set speed */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_MISC1r); -+ //printk("et%d: %s: read 0x%x from 0x%x\n", eth_num, __FUNCTION__, data16, XGXS16G_SERDESDIGITAL_MISC1r); -+ data16 &= 0x0f00; -+ data16 |= spd[phyaddr]; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_SERDESDIGITAL_MISC1r, data16); -+ //printk("et%d: %s: write 0x%x to 0x%x\n", eth_num, __FUNCTION__, data16, XGXS16G_SERDESDIGITAL_MISC1r); -+ -+ /* Enable asymmetric mode */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, XGXS16G_TX_LN_SWAP1r); -+ //printk("et%d: %s: read 0x%x from 0x%x\n", eth_num, __FUNCTION__, data16, XGXS16G_TX_LN_SWAP1r); -+ data16 |= 0x0100; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_TX_LN_SWAP1r, data16); -+ //printk("et%d: %s: write 0x%x to 0x%x\n", eth_num, __FUNCTION__, data16, XGXS16G_TX_LN_SWAP1r); -+ -+ /* set tx clock control bit */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, txclkctrlreg[phyaddr]); -+ //printk("et%d: %s: read 0x%x from 0x%x\n", eth_num, __FUNCTION__, data16, txclkctrlreg[phyaddr]); -+ data16 &= ~(clkctrlmsk[phyaddr]); -+ data16 |= clkctrlval[phyaddr]; -+ serdes_wr_reg(eth_num, phyaddr, txclkctrlreg[phyaddr], data16); -+ //printk("et%d: %s: write 0x%x to 0x%x\n", eth_num, __FUNCTION__, data16, txclkctrlreg[phyaddr]); -+ -+ /* set rx clock control bit */ -+ data16 = serdes_rd_reg(eth_num, phyaddr, rxclkctrlreg[phyaddr]); -+ //printk("et%d: %s: read 0x%x from 0x%x\n", eth_num, __FUNCTION__, data16, rxclkctrlreg[phyaddr]); -+ data16 &= ~(clkctrlmsk[phyaddr]); -+ data16 |= clkctrlval[phyaddr]; -+ serdes_wr_reg(eth_num, phyaddr, rxclkctrlreg[phyaddr], data16); -+ //printk("et%d: %s: write 0x%x to 0x%x\n", eth_num, __FUNCTION__, data16, rxclkctrlreg[phyaddr]); -+ -+ data16 = 0xffff; -+ serdes_wr_reg(eth_num, phyaddr, XGXS16G_XGXSBLK1_LANECTRL1r, data16); -+ //printk("et%d: %s: write 0x%x to 0x%x\n", eth_num, __FUNCTION__, data16, XGXS16G_XGXSBLK1_LANECTRL1r); -+ -+ return 0; -+} -+ -+#endif /* (defined(CONFIG_SERDES_ASYMMETRIC_MODE)) */ -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmutils.c b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmutils.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/bcmutils.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/bcmutils.c 2017-11-09 17:53:44.032290000 +0800 -@@ -0,0 +1,3389 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Driver O/S-independent utility routines -+ * -+ * $Id: bcmutils.c 325951 2012-04-05 06:03:27Z $ -+ */ -+ -+#include -+#include -+#include -+#if defined(__FreeBSD__) || defined(__NetBSD__) -+#include -+#else -+#include -+#endif -+#ifdef BCMDRIVER -+ -+#include -+#include -+#include -+#include -+ -+#else /* !BCMDRIVER */ -+ -+#include -+#include -+#include -+ -+#if defined(BCMEXTSUP) -+#include -+#endif -+ -+#endif /* !BCMDRIVER */ -+ -+#if defined(_WIN32) || defined(NDIS) || defined(__vxworks) || defined(_CFE_) -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef BCMPERFSTATS -+#include -+#endif -+#include -+void *_bcmutils_dummy_fn = NULL; -+ -+#ifdef BCMDRIVER -+ -+#ifdef WLC_LOW -+/* nvram vars cache */ -+static char *nvram_vars = NULL; -+static int vars_len = -1; -+#endif /* WLC_LOW */ -+ -+int -+pktpool_init(osl_t *osh, pktpool_t *pktp, int *pplen, int plen, bool istx) -+{ -+ int i, err = BCME_OK; -+ void *p; -+ int pktplen; -+ -+ ASSERT(pktp != NULL); -+ ASSERT(osh != NULL); -+ ASSERT(pplen != NULL); -+ -+ pktplen = *pplen; -+ -+ bzero(pktp, sizeof(pktpool_t)); -+ pktp->inited = TRUE; -+ pktp->istx = istx ? TRUE : FALSE; -+ pktp->plen = (uint16)plen; -+ *pplen = 0; -+ -+ pktp->maxlen = PKTPOOL_LEN_MAX; -+ if (pktplen > pktp->maxlen) -+ pktplen = pktp->maxlen; -+ -+ for (i = 0; i < pktplen; i++) { -+ p = PKTGET(osh, plen, pktp->istx); -+ if (p == NULL) { -+ /* Not able to allocate all requested pkts -+ * so just return what was actually allocated -+ * We can add to the pool later -+ */ -+ if (pktp->w == 0) { -+ err = BCME_NOMEM; -+ } -+ -+ goto exit; -+ } -+ -+ PKTSETPOOL(osh, p, TRUE, pktp); -+ pktp->q[i] = p; -+ pktp->w++; -+ pktp->len++; -+#ifdef BCMDBG_POOL -+ pktp->dbg_q[pktp->dbg_qlen++].p = p; -+#endif -+ } -+ -+exit: -+ *pplen = pktp->w; -+ pktp->len++; /* Add one for end */ -+ return err; -+} -+ -+int -+pktpool_deinit(osl_t *osh, pktpool_t *pktp) -+{ -+ int i; -+ int cnt; -+ -+ ASSERT(osh != NULL); -+ ASSERT(pktp != NULL); -+ -+ cnt = pktp->len; -+ for (i = 0; i < cnt; i++) { -+ if (pktp->q[i] != NULL) { -+ PKTSETPOOL(osh, pktp->q[i], FALSE, NULL); -+ PKTFREE(osh, pktp->q[i], pktp->istx); -+ pktp->q[i] = NULL; -+ pktp->len--; -+ } -+#ifdef BCMDBG_POOL -+ if (pktp->dbg_q[i].p != NULL) { -+ pktp->dbg_q[i].p = NULL; -+ } -+#endif -+ } -+ pktp->inited = FALSE; -+ -+ /* Are there still pending pkts? */ -+ ASSERT(pktpool_len(pktp) == 0); -+ -+ return 0; -+} -+ -+int -+pktpool_fill(osl_t *osh, pktpool_t *pktp, bool minimal) -+{ -+ void *p; -+ int err = 0; -+ int len, psize, maxlen; -+ -+ ASSERT(pktpool_plen(pktp) != 0); -+ -+ maxlen = pktpool_maxlen(pktp); -+ psize = minimal ? (maxlen >> 2) : maxlen; -+ len = pktpool_len(pktp); -+ for (; len < psize; len++) { -+ p = PKTGET(osh, pktpool_plen(pktp), FALSE); -+ if (p == NULL) { -+ err = BCME_NOMEM; -+ break; -+ } -+ -+ if (pktpool_add(pktp, p) != BCME_OK) { -+ PKTFREE(osh, p, FALSE); -+ err = BCME_ERROR; -+ break; -+ } -+ } -+ -+ return err; -+} -+ -+uint16 -+pktpool_avail(pktpool_t *pktp) -+{ -+ if (pktp->w == pktp->r) { -+ return 0; -+ } -+ -+ return (pktp->w > pktp->r) ? (pktp->w - pktp->r) : ((pktp->len) - (pktp->r - pktp->w)); -+} -+ -+static void * -+pktpool_deq(pktpool_t *pktp) -+{ -+ void *p; -+ -+ if (pktp->r == pktp->w) { -+ return NULL; -+ } -+ -+ p = pktp->q[pktp->r]; -+ ASSERT(p != NULL); -+ -+ pktp->q[pktp->r++] = NULL; -+ pktp->r %= (pktp->len); -+ -+ return p; -+} -+ -+static void -+pktpool_enq(pktpool_t *pktp, void *p) -+{ -+ uint16 next; -+ -+ ASSERT(p != NULL); -+ -+ next = (pktp->w + 1) % (pktp->len); -+ if (next == pktp->r) { -+ /* Should not happen; otherwise pkt leak */ -+ ASSERT(0); -+ return; -+ } -+ -+ ASSERT(pktp->q[pktp->w] == NULL); -+ -+ pktp->q[pktp->w] = p; -+ pktp->w = next; -+} -+ -+int -+pktpool_avail_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg) -+{ -+ int i; -+ -+ ASSERT(cb != NULL); -+ -+ i = pktp->cbcnt; -+ if (i == PKTPOOL_CB_MAX) { -+ return BCME_ERROR; -+ } -+ -+ ASSERT(pktp->cbs[i].cb == NULL); -+ pktp->cbs[i].cb = cb; -+ pktp->cbs[i].arg = arg; -+ pktp->cbcnt++; -+ -+ return 0; -+} -+ -+int -+pktpool_empty_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg) -+{ -+ int i; -+ -+ ASSERT(cb != NULL); -+ -+ i = pktp->ecbcnt; -+ if (i == PKTPOOL_CB_MAX) { -+ return BCME_ERROR; -+ } -+ -+ ASSERT(pktp->ecbs[i].cb == NULL); -+ pktp->ecbs[i].cb = cb; -+ pktp->ecbs[i].arg = arg; -+ pktp->ecbcnt++; -+ -+ return 0; -+} -+ -+static int -+pktpool_empty_notify(pktpool_t *pktp) -+{ -+ int i; -+ -+ pktp->empty = TRUE; -+ for (i = 0; i < pktp->ecbcnt; i++) { -+ ASSERT(pktp->ecbs[i].cb != NULL); -+ pktp->ecbs[i].cb(pktp, pktp->ecbs[i].arg); -+ } -+ pktp->empty = FALSE; -+ -+ return 0; -+} -+ -+#ifdef BCMDBG_POOL -+int -+pktpool_dbg_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg) -+{ -+ int i; -+ -+ ASSERT(cb); -+ -+ i = pktp->dbg_cbcnt; -+ if (i == PKTPOOL_CB_MAX) -+ return BCME_ERROR; -+ -+ ASSERT(pktp->dbg_cbs[i].cb == NULL); -+ pktp->dbg_cbs[i].cb = cb; -+ pktp->dbg_cbs[i].arg = arg; -+ pktp->dbg_cbcnt++; -+ -+ return 0; -+} -+ -+int pktpool_dbg_notify(pktpool_t *pktp); -+ -+int -+pktpool_dbg_notify(pktpool_t *pktp) -+{ -+ int i; -+ -+ for (i = 0; i < pktp->dbg_cbcnt; i++) { -+ ASSERT(pktp->dbg_cbs[i].cb); -+ pktp->dbg_cbs[i].cb(pktp, pktp->dbg_cbs[i].arg); -+ } -+ -+ return 0; -+} -+ -+int -+pktpool_dbg_dump(pktpool_t *pktp) -+{ -+ int i; -+ -+ printf("pool len=%d maxlen=%d\n", pktp->dbg_qlen, pktp->maxlen); -+ for (i = 0; i < pktp->dbg_qlen; i++) { -+ ASSERT(pktp->dbg_q[i].p); -+ printf("%d, p: 0x%x dur:%lu us state:%d\n", i, -+ pktp->dbg_q[i].p, pktp->dbg_q[i].dur/100, PKTPOOLSTATE(pktp->dbg_q[i].p)); -+ } -+ -+ return 0; -+} -+ -+int -+pktpool_stats_dump(pktpool_t *pktp, pktpool_stats_t *stats) -+{ -+ int i; -+ int state; -+ -+ bzero(stats, sizeof(pktpool_stats_t)); -+ for (i = 0; i < pktp->dbg_qlen; i++) { -+ ASSERT(pktp->dbg_q[i].p != NULL); -+ -+ state = PKTPOOLSTATE(pktp->dbg_q[i].p); -+ switch (state) { -+ case POOL_TXENQ: -+ stats->enq++; break; -+ case POOL_TXDH: -+ stats->txdh++; break; -+ case POOL_TXD11: -+ stats->txd11++; break; -+ case POOL_RXDH: -+ stats->rxdh++; break; -+ case POOL_RXD11: -+ stats->rxd11++; break; -+ case POOL_RXFILL: -+ stats->rxfill++; break; -+ case POOL_IDLE: -+ stats->idle++; break; -+ } -+ } -+ -+ return 0; -+} -+ -+int -+pktpool_start_trigger(pktpool_t *pktp, void *p) -+{ -+ uint32 cycles, i; -+ -+ if (!PKTPOOL(NULL, p)) { -+ return 0; -+ } -+ -+ OSL_GETCYCLES(cycles); -+ -+ for (i = 0; i < pktp->dbg_qlen; i++) { -+ ASSERT(pktp->dbg_q[i].p != NULL); -+ -+ if (pktp->dbg_q[i].p == p) { -+ pktp->dbg_q[i].cycles = cycles; -+ break; -+ } -+ } -+ -+ return 0; -+} -+ -+int pktpool_stop_trigger(pktpool_t *pktp, void *p); -+int -+pktpool_stop_trigger(pktpool_t *pktp, void *p) -+{ -+ uint32 cycles, i; -+ -+ if (!PKTPOOL(NULL, p)) { -+ return 0; -+ } -+ -+ OSL_GETCYCLES(cycles); -+ -+ for (i = 0; i < pktp->dbg_qlen; i++) { -+ ASSERT(pktp->dbg_q[i].p != NULL); -+ -+ if (pktp->dbg_q[i].p == p) { -+ if (pktp->dbg_q[i].cycles == 0) -+ break; -+ -+ if (cycles >= pktp->dbg_q[i].cycles) -+ pktp->dbg_q[i].dur = cycles - pktp->dbg_q[i].cycles; -+ else -+ pktp->dbg_q[i].dur = -+ (((uint32)-1) - pktp->dbg_q[i].cycles) + cycles + 1; -+ -+ pktp->dbg_q[i].cycles = 0; -+ break; -+ } -+ } -+ -+ return 0; -+} -+#endif /* BCMDBG_POOL */ -+ -+int -+pktpool_avail_notify_normal(osl_t *osh, pktpool_t *pktp) -+{ -+ ASSERT(pktp); -+ pktp->availcb_excl = NULL; -+ return 0; -+} -+ -+int -+pktpool_avail_notify_exclusive(osl_t *osh, pktpool_t *pktp, pktpool_cb_t cb) -+{ -+ int i; -+ -+ ASSERT(pktp); -+ ASSERT(pktp->availcb_excl == NULL); -+ for (i = 0; i < pktp->cbcnt; i++) { -+ if (cb == pktp->cbs[i].cb) { -+ pktp->availcb_excl = &pktp->cbs[i]; -+ break; -+ } -+ } -+ -+ if (pktp->availcb_excl == NULL) { -+ return BCME_ERROR; -+ } else { -+ return 0; -+ } -+} -+ -+static int -+pktpool_avail_notify(pktpool_t *pktp) -+{ -+ int i, k, idx; -+ int avail; -+ -+ ASSERT(pktp); -+ if (pktp->availcb_excl != NULL) { -+ pktp->availcb_excl->cb(pktp, pktp->availcb_excl->arg); -+ return 0; -+ } -+ -+ k = pktp->cbcnt - 1; -+ for (i = 0; i < pktp->cbcnt; i++) { -+ avail = pktpool_avail(pktp); -+ -+ if (avail) { -+ if (pktp->cbtoggle) { -+ idx = i; -+ } else { -+ idx = k--; -+ } -+ -+ ASSERT(pktp->cbs[idx].cb != NULL); -+ pktp->cbs[idx].cb(pktp, pktp->cbs[idx].arg); -+ } -+ } -+ -+ /* Alternate between filling from head or tail -+ */ -+ pktp->cbtoggle ^= 1; -+ -+ return 0; -+} -+ -+void * -+pktpool_get(pktpool_t *pktp) -+{ -+ void *p; -+ -+ p = pktpool_deq(pktp); -+ -+ if (p == NULL) { -+ /* Notify and try to reclaim tx pkts */ -+ if (pktp->ecbcnt) { -+ pktpool_empty_notify(pktp); -+ } -+ -+ p = pktpool_deq(pktp); -+ } -+ -+ return p; -+} -+ -+void -+pktpool_free(pktpool_t *pktp, void *p) -+{ -+ ASSERT(p != NULL); -+ -+#ifdef BCMDBG_POOL -+ /* pktpool_stop_trigger(pktp, p); */ -+#endif -+ -+ pktpool_enq(pktp, p); -+ -+ if (pktp->emptycb_disable) { -+ return; -+ } -+ -+ if (pktp->cbcnt) { -+ if (pktp->empty == FALSE) { -+ pktpool_avail_notify(pktp); -+ } -+ } -+} -+ -+int -+pktpool_add(pktpool_t *pktp, void *p) -+{ -+ ASSERT(p != NULL); -+ -+ if (pktpool_len(pktp) == pktp->maxlen) { -+ return BCME_RANGE; -+ } -+ -+ ASSERT(pktpool_plen(pktp) == PKTLEN(NULL, p)); /* pkts in pool have same length */ -+ PKTSETPOOL(NULL, p, TRUE, pktp); -+ -+ pktp->len++; -+ if (pktp->r > pktp->w) { -+ /* Add to tail */ -+ ASSERT(pktp->q[pktp->len - 1] == NULL); -+ pktp->q[pktp->len - 1] = p; -+ } else { -+ pktpool_enq(pktp, p); -+ } -+ -+#ifdef BCMDBG_POOL -+ pktp->dbg_q[pktp->dbg_qlen++].p = p; -+#endif -+ -+ return 0; -+} -+ -+int -+pktpool_setmaxlen(pktpool_t *pktp, uint16 maxlen) -+{ -+ if (maxlen > PKTPOOL_LEN_MAX) -+ maxlen = PKTPOOL_LEN_MAX; -+ -+ /* if pool is already beyond maxlen, then just cap it -+ * since we currently do not reduce the pool len -+ * already allocated -+ */ -+ pktp->maxlen = (pktpool_len(pktp) > maxlen) ? pktpool_len(pktp) : maxlen; -+ -+ return pktp->maxlen; -+} -+ -+void -+pktpool_emptycb_disable(pktpool_t *pktp, bool disable) -+{ -+ ASSERT(pktp); -+ -+ pktp->emptycb_disable = disable; -+} -+ -+bool -+pktpool_emptycb_disabled(pktpool_t *pktp) -+{ -+ ASSERT(pktp); -+ return pktp->emptycb_disable; -+} -+ -+/* copy a pkt buffer chain into a buffer */ -+uint -+pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) -+{ -+ uint n, ret = 0; -+ -+ if (len < 0) { -+ len = 4096; /* "infinite" */ -+ } -+ -+ /* skip 'offset' bytes */ -+ for (; p && offset; p = PKTNEXT(osh, p)) { -+ if (offset < (uint)PKTLEN(osh, p)) { -+ break; -+ } -+ offset -= PKTLEN(osh, p); -+ } -+ -+ if (!p) { -+ return 0; -+ } -+ -+ /* copy the data */ -+ for (; p && len; p = PKTNEXT(osh, p)) { -+ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); -+ bcopy(PKTDATA(osh, p) + offset, buf, n); -+ buf += n; -+ len -= n; -+ ret += n; -+ offset = 0; -+ } -+ -+ return ret; -+} -+ -+/* copy a buffer into a pkt buffer chain */ -+uint -+pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf) -+{ -+ uint n, ret = 0; -+ -+ /* skip 'offset' bytes */ -+ for (; p && offset; p = PKTNEXT(osh, p)) { -+ if (offset < (uint)PKTLEN(osh, p)) { -+ break; -+ } -+ offset -= PKTLEN(osh, p); -+ } -+ -+ if (!p) { -+ return 0; -+ } -+ -+ /* copy the data */ -+ for (; p && len; p = PKTNEXT(osh, p)) { -+ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); -+ bcopy(buf, PKTDATA(osh, p) + offset, n); -+ buf += n; -+ len -= n; -+ ret += n; -+ offset = 0; -+ } -+ -+ return ret; -+} -+ -+#ifdef NOTYET -+/* copy data from one pkt buffer (chain) to another */ -+uint -+pkt2pktcopy(osl_t *osh, void *p1, uint offs1, void *p2, uint offs2, int maxlen) -+{ -+ uint8 *dp1, *dp2; -+ uint len1, len2, copylen, totallen; -+ -+ for (; p1 && offs; p1 = PKTNEXT(osh, p1)) { -+ if (offs1 < (uint)PKTLEN(osh, p1)) { -+ break; -+ } -+ offs1 -= PKTLEN(osh, p1); -+ } -+ for (; p2 && offs; p2 = PKTNEXT(osh, p2)) { -+ if (offs2 < (uint)PKTLEN(osh, p2)) { -+ break; -+ } -+ offs2 -= PKTLEN(osh, p2); -+ } -+ -+ /* Heck w/it, only need the above for now */ -+} -+#endif /* NOTYET */ -+ -+ -+/* return total length of buffer chain */ -+uint BCMFASTPATH -+pkttotlen(osl_t *osh, void *p) -+{ -+ uint total; -+ int len; -+ -+ total = 0; -+ for (; p; p = PKTNEXT(osh, p)) { -+ len = PKTLEN(osh, p); -+#ifdef MACOSX -+ if (len < 0) { -+ /* Bad packet length, just drop and exit */ -+ printf("wl: pkttotlen bad (%p,%d)\n", p, len); -+ break; -+ } -+#endif /* MACOSX */ -+ total += len; -+ } -+ -+ return (total); -+} -+ -+/* return the last buffer of chained pkt */ -+void * -+pktlast(osl_t *osh, void *p) -+{ -+ for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p)) { -+ ; -+ } -+ -+ return (p); -+} -+ -+/* count segments of a chained packet */ -+uint BCMFASTPATH -+pktsegcnt(osl_t *osh, void *p) -+{ -+ uint cnt; -+ -+ for (cnt = 0; p; p = PKTNEXT(osh, p)) { -+ cnt++; -+ } -+ -+ return cnt; -+} -+ -+ -+/* count segments of a chained packet */ -+uint BCMFASTPATH -+pktsegcnt_war(osl_t *osh, void *p) -+{ -+ uint cnt; -+ uint8 *pktdata; -+ uint len, remain, align64; -+ -+ for (cnt = 0; p; p = PKTNEXT(osh, p)) { -+ cnt++; -+ len = PKTLEN(osh, p); -+ if (len > 128) { -+ pktdata = (uint8 *)PKTDATA(osh, p); /* starting address of data */ -+ /* Check for page boundary straddle (2048B) */ -+ if (((uintptr)pktdata & ~0x7ff) != ((uintptr)(pktdata+len) & ~0x7ff)) { -+ cnt++; -+ } -+ -+ align64 = (uint)((uintptr)pktdata & 0x3f); /* aligned to 64B */ -+ align64 = (64 - align64) & 0x3f; -+ len -= align64; /* bytes from aligned 64B to end */ -+ /* if aligned to 128B, check for MOD 128 between 1 to 4B */ -+ remain = len % 128; -+ if (remain > 0 && remain <= 4) { -+ cnt++; /* add extra seg */ -+ } -+ } -+ } -+ -+ return cnt; -+} -+ -+uint8 * BCMFASTPATH -+pktdataoffset(osl_t *osh, void *p, uint offset) -+{ -+ uint total = pkttotlen(osh, p); -+ uint pkt_off = 0, len = 0; -+ uint8 *pdata = (uint8 *) PKTDATA(osh, p); -+ -+ if (offset > total) { -+ return NULL; -+ } -+ -+ for (; p; p = PKTNEXT(osh, p)) { -+ pdata = (uint8 *) PKTDATA(osh, p); -+ pkt_off = offset - len; -+ len += PKTLEN(osh, p); -+ if (len > offset) { -+ break; -+ } -+ } -+ return (uint8*) (pdata+pkt_off); -+} -+ -+ -+/* given a offset in pdata, find the pkt seg hdr */ -+void * -+pktoffset(osl_t *osh, void *p, uint offset) -+{ -+ uint total = pkttotlen(osh, p); -+ uint len = 0; -+ -+ if (offset > total) { -+ return NULL; -+ } -+ -+ for (; p; p = PKTNEXT(osh, p)) { -+ len += PKTLEN(osh, p); -+ if (len > offset) { -+ break; -+ } -+ } -+ return p; -+} -+ -+/* -+ * osl multiple-precedence packet queue -+ * hi_prec is always >= the number of the highest non-empty precedence -+ */ -+void * BCMFASTPATH -+pktq_penq(struct pktq *pq, int prec, void *p) -+{ -+ struct pktq_prec *q; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ -+ -+ ASSERT(!pktq_full(pq)); -+ ASSERT(!pktq_pfull(pq, prec)); -+ -+ q = &pq->q[prec]; -+ -+ if (q->head) { -+ PKTSETLINK(q->tail, p); -+ } else { -+ q->head = p; -+ } -+ -+ q->tail = p; -+ q->len++; -+ -+ pq->len++; -+ -+ if (pq->hi_prec < prec) { -+ pq->hi_prec = (uint8)prec; -+ } -+ -+ return p; -+} -+ -+void * BCMFASTPATH -+pktq_penq_head(struct pktq *pq, int prec, void *p) -+{ -+ struct pktq_prec *q; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ -+ -+ ASSERT(!pktq_full(pq)); -+ ASSERT(!pktq_pfull(pq, prec)); -+ -+ q = &pq->q[prec]; -+ -+ if (q->head == NULL) { -+ q->tail = p; -+ } -+ -+ PKTSETLINK(p, q->head); -+ q->head = p; -+ q->len++; -+ -+ pq->len++; -+ -+ if (pq->hi_prec < prec) { -+ pq->hi_prec = (uint8)prec; -+ } -+ -+ return p; -+} -+ -+void * BCMFASTPATH -+pktq_pdeq(struct pktq *pq, int prec) -+{ -+ struct pktq_prec *q; -+ void *p; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) { -+ return NULL; -+ } -+ -+ if ((q->head = PKTLINK(p)) == NULL) { -+ q->tail = NULL; -+ } -+ -+ q->len--; -+ -+ pq->len--; -+ -+ PKTSETLINK(p, NULL); -+ -+ return p; -+} -+ -+void * BCMFASTPATH -+pktq_pdeq_prev(struct pktq *pq, int prec, void *prev_p) -+{ -+ struct pktq_prec *q; -+ void *p; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ -+ q = &pq->q[prec]; -+ -+ if (prev_p == NULL) { -+ return NULL; -+ } -+ -+ if ((p = PKTLINK(prev_p)) == NULL) { -+ return NULL; -+ } -+ -+ q->len--; -+ -+ pq->len--; -+ -+ PKTSETLINK(prev_p, PKTLINK(p)); -+ PKTSETLINK(p, NULL); -+ -+ return p; -+} -+ -+void * BCMFASTPATH -+pktq_pdeq_tail(struct pktq *pq, int prec) -+{ -+ struct pktq_prec *q; -+ void *p, *prev; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) { -+ return NULL; -+ } -+ -+ for (prev = NULL; p != q->tail; p = PKTLINK(p)) { -+ prev = p; -+ } -+ -+ if (prev) { -+ PKTSETLINK(prev, NULL); -+ } else { -+ q->head = NULL; -+ } -+ -+ q->tail = prev; -+ q->len--; -+ -+ pq->len--; -+ -+ return p; -+} -+ -+void -+pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn, int arg) -+{ -+ struct pktq_prec *q; -+ void *p, *prev = NULL; -+ -+ q = &pq->q[prec]; -+ p = q->head; -+ while (p) { -+ if (fn == NULL || (*fn)(p, arg)) { -+ bool head = (p == q->head); -+ if (head) { -+ q->head = PKTLINK(p); -+ } else { -+ PKTSETLINK(prev, PKTLINK(p)); -+ } -+ PKTSETLINK(p, NULL); -+ PKTFREE(osh, p, dir); -+ q->len--; -+ pq->len--; -+ p = (head ? q->head : PKTLINK(prev)); -+ } else { -+ prev = p; -+ p = PKTLINK(p); -+ } -+ } -+ -+ if (q->head == NULL) { -+ ASSERT(q->len == 0); -+ q->tail = NULL; -+ } -+} -+ -+bool BCMFASTPATH -+pktq_pdel(struct pktq *pq, void *pktbuf, int prec) -+{ -+ struct pktq_prec *q; -+ void *p; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ -+ if (!pktbuf) { -+ return FALSE; -+ } -+ -+ q = &pq->q[prec]; -+ -+ if (q->head == pktbuf) { -+ if ((q->head = PKTLINK(pktbuf)) == NULL) { -+ q->tail = NULL; -+ } -+ } else { -+ for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p)) { -+ ; -+ } -+ if (p == NULL) { -+ return FALSE; -+ } -+ -+ PKTSETLINK(p, PKTLINK(pktbuf)); -+ if (q->tail == pktbuf) { -+ q->tail = p; -+ } -+ } -+ -+ q->len--; -+ pq->len--; -+ PKTSETLINK(pktbuf, NULL); -+ return TRUE; -+} -+ -+void -+pktq_init(struct pktq *pq, int num_prec, int max_len) -+{ -+ int prec; -+ -+ ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC); -+ -+ /* pq is variable size; only zero out what's requested */ -+ bzero(pq, OFFSETOF(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec)); -+ -+ pq->num_prec = (uint16)num_prec; -+ -+ pq->max = (uint16)max_len; -+ -+ for (prec = 0; prec < num_prec; prec++) { -+ pq->q[prec].max = pq->max; -+ } -+} -+ -+void -+pktq_set_max_plen(struct pktq *pq, int prec, int max_len) -+{ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ -+ if (prec < pq->num_prec) { -+ pq->q[prec].max = (uint16)max_len; -+ } -+} -+ -+void * BCMFASTPATH -+pktq_deq(struct pktq *pq, int *prec_out) -+{ -+ struct pktq_prec *q; -+ void *p; -+ int prec; -+ -+ if (pq->len == 0) { -+ return NULL; -+ } -+ -+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) { -+ pq->hi_prec--; -+ } -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) { -+ return NULL; -+ } -+ -+ if ((q->head = PKTLINK(p)) == NULL) { -+ q->tail = NULL; -+ } -+ -+ q->len--; -+ -+ pq->len--; -+ -+ if (prec_out) { -+ *prec_out = prec; -+ } -+ -+ PKTSETLINK(p, NULL); -+ -+ return p; -+} -+ -+void * BCMFASTPATH -+pktq_deq_tail(struct pktq *pq, int *prec_out) -+{ -+ struct pktq_prec *q; -+ void *p, *prev; -+ int prec; -+ -+ if (pq->len == 0) { -+ return NULL; -+ } -+ -+ for (prec = 0; prec < pq->hi_prec; prec++) { -+ if (pq->q[prec].head) { -+ break; -+ } -+ } -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) { -+ return NULL; -+ } -+ -+ for (prev = NULL; p != q->tail; p = PKTLINK(p)) { -+ prev = p; -+ } -+ -+ if (prev) { -+ PKTSETLINK(prev, NULL); -+ } else { -+ q->head = NULL; -+ } -+ -+ q->tail = prev; -+ q->len--; -+ -+ pq->len--; -+ -+ if (prec_out) { -+ *prec_out = prec; -+ } -+ -+ PKTSETLINK(p, NULL); -+ -+ return p; -+} -+ -+void * -+pktq_peek(struct pktq *pq, int *prec_out) -+{ -+ int prec; -+ -+ if (pq->len == 0) { -+ return NULL; -+ } -+ -+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) { -+ pq->hi_prec--; -+ } -+ -+ if (prec_out) { -+ *prec_out = prec; -+ } -+ -+ return (pq->q[prec].head); -+} -+ -+void * -+pktq_peek_tail(struct pktq *pq, int *prec_out) -+{ -+ int prec; -+ -+ if (pq->len == 0) { -+ return NULL; -+ } -+ -+ for (prec = 0; prec < pq->hi_prec; prec++) { -+ if (pq->q[prec].head) { -+ break; -+ } -+ } -+ -+ if (prec_out) { -+ *prec_out = prec; -+ } -+ -+ return (pq->q[prec].tail); -+} -+ -+void -+pktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg) -+{ -+ int prec; -+ -+ /* Optimize flush, if pktq len = 0, just return. -+ * pktq len of 0 means pktq's prec q's are all empty. -+ */ -+ if (pq->len == 0) { -+ return; -+ } -+ -+ for (prec = 0; prec < pq->num_prec; prec++) { -+ pktq_pflush(osh, pq, prec, dir, fn, arg); -+ } -+ if (fn == NULL) { -+ ASSERT(pq->len == 0); -+ } -+} -+ -+/* Return sum of lengths of a specific set of precedences */ -+int -+pktq_mlen(struct pktq *pq, uint prec_bmp) -+{ -+ int prec, len; -+ -+ len = 0; -+ -+ for (prec = 0; prec <= pq->hi_prec; prec++) { -+ if (prec_bmp & (1 << prec)) { -+ len += pq->q[prec].len; -+ } -+ } -+ -+ return len; -+} -+ -+/* Priority peek from a specific set of precedences */ -+void * BCMFASTPATH -+pktq_mpeek(struct pktq *pq, uint prec_bmp, int *prec_out) -+{ -+ struct pktq_prec *q; -+ void *p; -+ int prec; -+ -+ if (pq->len == 0) { -+ return NULL; -+ } -+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) { -+ pq->hi_prec--; -+ } -+ -+ while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) { -+ if (prec-- == 0) { -+ return NULL; -+ } -+ } -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) { -+ return NULL; -+ } -+ -+ if (prec_out) { -+ *prec_out = prec; -+ } -+ -+ return p; -+} -+/* Priority dequeue from a specific set of precedences */ -+void * BCMFASTPATH -+pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) -+{ -+ struct pktq_prec *q; -+ void *p; -+ int prec; -+ -+ if (pq->len == 0) { -+ return NULL; -+ } -+ -+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) { -+ pq->hi_prec--; -+ } -+ -+ while ((pq->q[prec].head == NULL) || ((prec_bmp & (1 << prec)) == 0)) { -+ if (prec-- == 0) { -+ return NULL; -+ } -+ } -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) { -+ return NULL; -+ } -+ -+ if ((q->head = PKTLINK(p)) == NULL) { -+ q->tail = NULL; -+ } -+ -+ q->len--; -+ -+ if (prec_out) { -+ *prec_out = prec; -+ } -+ -+ pq->len--; -+ -+ PKTSETLINK(p, NULL); -+ -+ return p; -+} -+ -+#endif /* BCMDRIVER */ -+ -+#if defined(BCMROMBUILD) -+const unsigned char BCMROMDATA(bcm_ctype)[] = { -+#else -+const unsigned char bcm_ctype[] = { -+#endif -+ -+ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ -+ _BCM_C, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C, -+ _BCM_C, /* 8-15 */ -+ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ -+ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ -+ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ -+ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ -+ _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ -+ _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ -+ _BCM_P, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, -+ _BCM_U|_BCM_X, _BCM_U, /* 64-71 */ -+ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ -+ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ -+ _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */ -+ _BCM_P, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, -+ _BCM_L|_BCM_X, _BCM_L, /* 96-103 */ -+ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */ -+ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */ -+ _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128-143 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144-159 */ -+ _BCM_S|_BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, -+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 160-175 */ -+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, -+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 176-191 */ -+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, -+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 192-207 */ -+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U, _BCM_U, _BCM_U, -+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L, /* 208-223 */ -+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, -+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 224-239 */ -+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L, _BCM_L, _BCM_L, -+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */ -+}; -+ -+ulong -+BCMROMFN(bcm_strtoul)(const char *cp, char **endp, uint base) -+{ -+ ulong result, last_result = 0, value; -+ bool minus; -+ -+ minus = FALSE; -+ -+ while (bcm_isspace(*cp)) { -+ cp++; -+ } -+ -+ if (cp[0] == '+') { -+ cp++; -+ } else if (cp[0] == '-') { -+ minus = TRUE; -+ cp++; -+ } -+ -+ if (base == 0) { -+ if (cp[0] == '0') { -+ if ((cp[1] == 'x') || (cp[1] == 'X')) { -+ base = 16; -+ cp = &cp[2]; -+ } else { -+ base = 8; -+ cp = &cp[1]; -+ } -+ } else { -+ base = 10; -+ } -+ } else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) { -+ cp = &cp[2]; -+ } -+ -+ result = 0; -+ -+ while (bcm_isxdigit(*cp) && -+ (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) { -+ result = result*base + value; -+ /* Detected overflow */ -+ if (result < last_result && !minus) { -+ return (ulong)-1; -+ } -+ last_result = result; -+ cp++; -+ } -+ -+ if (minus) { -+ result = (ulong)(-(long)result); -+ } -+ -+ if (endp) { -+ *endp = DISCARD_QUAL(cp, char); -+ } -+ -+ return (result); -+} -+ -+int -+BCMROMFN(bcm_atoi)(const char *s) -+{ -+ return (int)bcm_strtoul(s, NULL, 10); -+} -+ -+/* return pointer to location of substring 'needle' in 'haystack' */ -+char * -+BCMROMFN(bcmstrstr)(const char *haystack, const char *needle) -+{ -+ int len, nlen; -+ int i; -+ -+ if ((haystack == NULL) || (needle == NULL)) { -+ return DISCARD_QUAL(haystack, char); -+ } -+ -+ nlen = strlen(needle); -+ len = strlen(haystack) - nlen + 1; -+ -+ for (i = 0; i < len; i++) { -+ if (memcmp(needle, &haystack[i], nlen) == 0) { -+ return DISCARD_QUAL(&haystack[i], char); -+ } -+ } -+ return (NULL); -+} -+ -+char * -+BCMROMFN(bcmstrcat)(char *dest, const char *src) -+{ -+ char *p; -+ -+ p = dest + strlen(dest); -+ -+ while ((*p++ = *src++) != '\0') { -+ ; -+ } -+ -+ return (dest); -+} -+ -+char * -+BCMROMFN(bcmstrncat)(char *dest, const char *src, uint size) -+{ -+ char *endp; -+ char *p; -+ -+ p = dest + strlen(dest); -+ endp = p + size; -+ -+ while (p != endp && (*p++ = *src++) != '\0') { -+ ; -+ } -+ -+ return (dest); -+} -+ -+ -+/**************************************************************************** -+* Function: bcmstrtok -+* -+* Purpose: -+* Tokenizes a string. This function is conceptually similiar to ANSI C strtok(), -+* but allows strToken() to be used by different strings or callers at the same -+* time. Each call modifies '*string' by substituting a NULL character for the -+* first delimiter that is encountered, and updates 'string' to point to the char -+* after the delimiter. Leading delimiters are skipped. -+* -+* Parameters: -+* string (mod) Ptr to string ptr, updated by token. -+* delimiters (in) Set of delimiter characters. -+* tokdelim (out) Character that delimits the returned token. (May -+* be set to NULL if token delimiter is not required). -+* -+* Returns: Pointer to the next token found. NULL when no more tokens are found. -+***************************************************************************** -+*/ -+char * -+bcmstrtok(char **string, const char *delimiters, char *tokdelim) -+{ -+ unsigned char *str; -+ unsigned long map[8]; -+ int count; -+ char *nextoken; -+ -+ if (tokdelim != NULL) { -+ /* Prime the token delimiter */ -+ *tokdelim = '\0'; -+ } -+ -+ /* Clear control map */ -+ for (count = 0; count < 8; count++) { -+ map[count] = 0; -+ } -+ -+ /* Set bits in delimiter table */ -+ do { -+ map[*delimiters >> 5] |= (1 << (*delimiters & 31)); -+ } -+ while (*delimiters++); -+ -+ str = (unsigned char*)*string; -+ -+ /* Find beginning of token (skip over leading delimiters). Note that -+ * there is no token iff this loop sets str to point to the terminal -+ * null (*str == '\0') -+ */ -+ while (((map[*str >> 5] & (1 << (*str & 31))) && *str) || (*str == ' ')) { -+ str++; -+ } -+ -+ nextoken = (char*)str; -+ -+ /* Find the end of the token. If it is not the end of the string, -+ * put a null there. -+ */ -+ for (; *str; str++) { -+ if (map[*str >> 5] & (1 << (*str & 31))) { -+ if (tokdelim != NULL) { -+ *tokdelim = *str; -+ } -+ -+ *str++ = '\0'; -+ break; -+ } -+ } -+ -+ *string = (char*)str; -+ -+ /* Determine if a token has been found. */ -+ if (nextoken == (char *) str) { -+ return NULL; -+ } -+ else { -+ return nextoken; -+ } -+} -+ -+ -+#define xToLower(C) \ -+ ((C >= 'A' && C <= 'Z') ? (char)((int)C - (int)'A' + (int)'a') : C) -+ -+ -+/**************************************************************************** -+* Function: bcmstricmp -+* -+* Purpose: Compare to strings case insensitively. -+* -+* Parameters: s1 (in) First string to compare. -+* s2 (in) Second string to compare. -+* -+* Returns: Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if -+* t1 > t2, when ignoring case sensitivity. -+***************************************************************************** -+*/ -+int -+bcmstricmp(const char *s1, const char *s2) -+{ -+ char dc, sc; -+ -+ while (*s2 && *s1) { -+ dc = xToLower(*s1); -+ sc = xToLower(*s2); -+ if (dc < sc) return -1; -+ if (dc > sc) return 1; -+ s1++; -+ s2++; -+ } -+ -+ if (*s1 && !*s2) return 1; -+ if (!*s1 && *s2) return -1; -+ return 0; -+} -+ -+ -+/**************************************************************************** -+* Function: bcmstrnicmp -+* -+* Purpose: Compare to strings case insensitively, upto a max of 'cnt' -+* characters. -+* -+* Parameters: s1 (in) First string to compare. -+* s2 (in) Second string to compare. -+* cnt (in) Max characters to compare. -+* -+* Returns: Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if -+* t1 > t2, when ignoring case sensitivity. -+***************************************************************************** -+*/ -+int -+bcmstrnicmp(const char* s1, const char* s2, int cnt) -+{ -+ char dc, sc; -+ -+ while (*s2 && *s1 && cnt) { -+ dc = xToLower(*s1); -+ sc = xToLower(*s2); -+ if (dc < sc) return -1; -+ if (dc > sc) return 1; -+ s1++; -+ s2++; -+ cnt--; -+ } -+ -+ if (!cnt) return 0; -+ if (*s1 && !*s2) return 1; -+ if (!*s1 && *s2) return -1; -+ return 0; -+} -+ -+/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ -+int -+BCMROMFN(bcm_ether_atoe)(const char *p, struct ether_addr *ea) -+{ -+ int i = 0; -+ char *ep; -+ -+ for (;;) { -+ ea->octet[i++] = (char) bcm_strtoul(p, &ep, 16); -+ p = ep; -+ if (!*p++ || i == 6) -+ break; -+ } -+ -+ return (i == 6); -+} -+ -+ -+#if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER) -+/* registry routine buffer preparation utility functions: -+ * parameter order is like strncpy, but returns count -+ * of bytes copied. Minimum bytes copied is null char(1)/wchar(2) -+ */ -+ulong -+wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen) -+{ -+ ulong copyct = 1; -+ ushort i; -+ -+ if (abuflen == 0) -+ return 0; -+ -+ /* wbuflen is in bytes */ -+ wbuflen /= sizeof(ushort); -+ -+ for (i = 0; i < wbuflen; ++i) { -+ if (--abuflen == 0) { -+ break; -+ } -+ *abuf++ = (char) *wbuf++; -+ ++copyct; -+ } -+ *abuf = '\0'; -+ -+ return copyct; -+} -+#endif /* CONFIG_USBRNDIS_RETAIL || NDIS_MINIPORT_DRIVER */ -+ -+char * -+bcm_ether_ntoa(const struct ether_addr *ea, char *buf) -+{ -+ static const char hex[] = -+ { -+ '0', '1', '2', '3', '4', '5', '6', '7', -+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' -+ }; -+ const uint8 *octet = ea->octet; -+ char *p = buf; -+ int i; -+ -+ for (i = 0; i < 6; i++, octet++) { -+ *p++ = hex[(*octet >> 4) & 0xf]; -+ *p++ = hex[*octet & 0xf]; -+ *p++ = ':'; -+ } -+ -+ *(p-1) = '\0'; -+ -+ return (buf); -+} -+ -+char * -+bcm_ip_ntoa(struct ipv4_addr *ia, char *buf) -+{ -+ snprintf(buf, 16, "%d.%d.%d.%d", -+ ia->addr[0], ia->addr[1], ia->addr[2], ia->addr[3]); -+ return (buf); -+} -+ -+#ifdef BCMDRIVER -+ -+void -+bcm_mdelay(uint ms) -+{ -+ uint i; -+ -+ for (i = 0; i < ms; i++) { -+ OSL_DELAY(1000); -+ } -+} -+ -+/* -+ * Search the name=value vars for a specific one and return its value. -+ * Returns NULL if not found. -+ */ -+char * -+getvar(char *vars, const char *name) -+{ -+#ifdef _MINOSL_ -+ return NULL; -+#else -+ char *s; -+ int len; -+ -+ if (!name) { -+ return NULL; -+ } -+ -+ len = strlen(name); -+ if (len == 0) { -+ return NULL; -+ } -+ -+ /* first look in vars[] */ -+ for (s = vars; s && *s;) { -+ if ((bcmp(s, name, len) == 0) && (s[len] == '=') && (strlen(s)==len)) { -+ return (&s[len+1]); -+ } -+ -+ while (*s++) { -+ ; -+ } -+ } -+ -+ /* then query nvram */ -+ return (nvram_get(name)); -+#endif /* defined(_MINOSL_) */ -+} -+ -+/* -+ * Search the vars for a specific one and return its value as -+ * an integer. Returns 0 if not found. -+ */ -+int -+getintvar(char *vars, const char *name) -+{ -+#ifdef _MINOSL_ -+ return 0; -+#else -+ char *val; -+ -+ if ((val = getvar(vars, name)) == NULL) { -+ return (0); -+ } -+ -+ return (bcm_strtoul(val, NULL, 0)); -+#endif /* _MINOSL_ */ -+} -+ -+int -+getintvararray(char *vars, const char *name, int index) -+{ -+#ifdef _MINOSL_ -+ return 0; -+#else -+ char *buf, *endp; -+ int i = 0; -+ int val = 0; -+ -+ if ((buf = getvar(vars, name)) == NULL) { -+ return (0); -+ } -+ -+ /* table values are always separated by "," or " " */ -+ while (*buf != '\0') { -+ val = bcm_strtoul(buf, &endp, 0); -+ if (i == index) { -+ return val; -+ } -+ buf = endp; -+ /* delimiter is ',' */ -+ if (*buf == ',') { -+ buf++; -+ } -+ i++; -+ } -+ return 0; -+#endif /* _MINOSL_ */ -+} -+ -+int -+getintvararraysize(char *vars, const char *name) -+{ -+#ifdef _MINOSL_ -+ return 0; -+#else -+ char *buf, *endp; -+ int count = 0; -+ int val = 0; -+ -+ if ((buf = getvar(vars, name)) == NULL) { -+ return (0); -+ } -+ -+ /* table values are always separated by "," or " " */ -+ while (*buf != '\0') { -+ val = bcm_strtoul(buf, &endp, 0); -+ buf = endp; -+ /* delimiter is ',' */ -+ if (*buf == ',') { -+ buf++; -+ } -+ count++; -+ } -+ BCM_REFERENCE(val); -+ return count; -+#endif /* _MINOSL_ */ -+} -+ -+/* Search for token in comma separated token-string */ -+static int -+findmatch(const char *string, const char *name) -+{ -+ uint len; -+ char *c; -+ -+ len = strlen(name); -+ while ((c = strchr(string, ',')) != NULL) { -+ if (len == (uint)(c - string) && !strncmp(string, name, len)) { -+ return 1; -+ } -+ string = c + 1; -+ } -+ -+ return (!strcmp(string, name)); -+} -+ -+/* Return gpio pin number assigned to the named pin -+ * -+ * Variable should be in format: -+ * -+ * gpio=pin_name,pin_name -+ * -+ * This format allows multiple features to share the gpio with mutual -+ * understanding. -+ * -+ * 'def_pin' is returned if a specific gpio is not defined for the requested functionality -+ * and if def_pin is not used by others. -+ */ -+uint -+getgpiopin(char *vars, char *pin_name, uint def_pin) -+{ -+ char name[] = "gpioXXXX"; -+ char *val; -+ uint pin; -+ -+ /* Go thru all possibilities till a match in pin name */ -+ for (pin = 0; pin < GPIO_NUMPINS; pin ++) { -+ snprintf(name, sizeof(name), "gpio%d", pin); -+ val = getvar(vars, name); -+ if (val && findmatch(val, pin_name)) { -+ return pin; -+ } -+ } -+ -+ if (def_pin != GPIO_PIN_NOTDEFINED) { -+ /* make sure the default pin is not used by someone else */ -+ snprintf(name, sizeof(name), "gpio%d", def_pin); -+ if (getvar(vars, name)) { -+ def_pin = GPIO_PIN_NOTDEFINED; -+ } -+ } -+ return def_pin; -+} -+ -+ -+/* Return the WAN port number -+ * -+ * 0 is returned if no wanport is configured. -+ */ -+int -+getwanport(void) -+{ -+ char name[] = "wanport"; -+ int retval; -+ -+ retval = getintvar(NULL, name); -+ return retval; -+} -+ -+ -+/* Return the brcmtag variable -+ * -+ * 0 is returned if no wanport is configured. -+ */ -+int -+getbrcmtag(void) -+{ -+ char name[] = "brcmtag"; -+ int retval; -+ -+ retval = getintvar(NULL, name); -+ return retval; -+} -+ -+#if defined(BCMPERFSTATS) || defined(BCMTSTAMPEDLOGS) -+#define LOGSIZE 256 /* should be power of 2 to avoid div below */ -+static struct { -+ uint cycles; -+ char *fmt; -+ uint a1; -+ uint a2; -+} logtab[LOGSIZE]; -+ -+/* last entry logged */ -+static uint logi = 0; -+/* next entry to read */ -+static uint readi = 0; -+#endif /* defined(BCMPERFSTATS) || defined(BCMTSTAMPEDLOGS) */ -+ -+#ifdef BCMPERFSTATS -+void -+bcm_perf_enable() -+{ -+ BCMPERF_ENABLE_INSTRCOUNT(); -+ BCMPERF_ENABLE_ICACHE_MISS(); -+ BCMPERF_ENABLE_ICACHE_HIT(); -+} -+ -+/* WARNING: This routine uses OSL_GETCYCLES(), which can give unexpected results on -+ * modern speed stepping CPUs. Use bcmtslog() instead in combination with TSF counter. -+ */ -+void -+bcmlog(char *fmt, uint a1, uint a2) -+{ -+ static uint last = 0; -+ uint cycles, i; -+ OSL_GETCYCLES(cycles); -+ -+ i = logi; -+ -+ logtab[i].cycles = cycles - last; -+ logtab[i].fmt = fmt; -+ logtab[i].a1 = a1; -+ logtab[i].a2 = a2; -+ -+ logi = (i + 1) % LOGSIZE; -+ last = cycles; -+} -+ -+ -+void -+bcmstats(char *fmt) -+{ -+ static uint last = 0; -+ static uint32 ic_miss = 0; -+ static uint32 instr_count = 0; -+ uint32 ic_miss_cur; -+ uint32 instr_count_cur; -+ uint cycles, i; -+ -+ OSL_GETCYCLES(cycles); -+ BCMPERF_GETICACHE_MISS(ic_miss_cur); -+ BCMPERF_GETINSTRCOUNT(instr_count_cur); -+ -+ i = logi; -+ -+ logtab[i].cycles = cycles - last; -+ logtab[i].a1 = ic_miss_cur - ic_miss; -+ logtab[i].a2 = instr_count_cur - instr_count; -+ logtab[i].fmt = fmt; -+ -+ logi = (i + 1) % LOGSIZE; -+ -+ last = cycles; -+ instr_count = instr_count_cur; -+ ic_miss = ic_miss_cur; -+} -+ -+ -+void -+bcmdumplog(char *buf, int size) -+{ -+ char *limit; -+ int j = 0; -+ int num; -+ -+ limit = buf + size - 80; -+ *buf = '\0'; -+ -+ num = logi - readi; -+ -+ if (num < 0) { -+ num += LOGSIZE; -+ } -+ -+ /* print in chronological order */ -+ -+ for (j = 0; j < num && (buf < limit); readi = (readi + 1) % LOGSIZE, j++) { -+ if (logtab[readi].fmt == NULL) { -+ continue; -+ } -+ buf += snprintf(buf, (limit - buf), "%d\t", logtab[readi].cycles); -+ buf += snprintf(buf, (limit - buf), logtab[readi].fmt, logtab[readi].a1, -+ logtab[readi].a2); -+ buf += snprintf(buf, (limit - buf), "\n"); -+ } -+ -+} -+ -+ -+/* -+ * Dump one log entry at a time. -+ * Return index of next entry or -1 when no more . -+ */ -+int -+bcmdumplogent(char *buf, uint i) -+{ -+ bool hit; -+ -+ /* -+ * If buf is NULL, return the starting index, -+ * interpreting i as the indicator of last 'i' entries to dump. -+ */ -+ if (buf == NULL) { -+ i = ((i > 0) && (i < (LOGSIZE - 1))) ? i : (LOGSIZE - 1); -+ return ((logi - i) % LOGSIZE); -+ } -+ -+ *buf = '\0'; -+ -+ ASSERT(i < LOGSIZE); -+ -+ if (i == logi) { -+ return (-1); -+ } -+ -+ hit = FALSE; -+ for (; (i != logi) && !hit; i = (i + 1) % LOGSIZE) { -+ if (logtab[i].fmt == NULL) { -+ continue; -+ } -+ buf += sprintf(buf, "%d: %d\t", i, logtab[i].cycles); -+ buf += sprintf(buf, logtab[i].fmt, logtab[i].a1, logtab[i].a2); -+ buf += sprintf(buf, "\n"); -+ hit = TRUE; -+ } -+ -+ return (i); -+} -+ -+#endif /* BCMPERFSTATS */ -+ -+#if defined(BCMTSTAMPEDLOGS) -+/* Store a TSF timestamp and a log line in the log buffer */ -+void -+bcmtslog(uint32 tstamp, char *fmt, uint a1, uint a2) -+{ -+ uint i = logi; -+ bool use_delta = FALSE; -+ static uint32 last = 0; /* used only when use_delta is true */ -+ -+ logtab[i].cycles = tstamp; -+ if (use_delta) { -+ logtab[i].cycles -= last; -+ } -+ -+ logtab[i].fmt = fmt; -+ logtab[i].a1 = a1; -+ logtab[i].a2 = a2; -+ -+ if (use_delta) { -+ last = tstamp; -+ } -+ logi = (i + 1) % LOGSIZE; -+} -+ -+/* Print out a microsecond timestamp as "sec.ms.us " */ -+void -+bcmprinttstamp(uint32 ticks) -+{ -+ uint us, ms, sec; -+ -+ us = (ticks % TSF_TICKS_PER_MS) * 1000 / TSF_TICKS_PER_MS; -+ ms = ticks / TSF_TICKS_PER_MS; -+ sec = ms / 1000; -+ ms -= sec * 1000; -+ printf("%04u.%03u.%03u ", sec, ms, us); -+} -+ -+/* Print out the log buffer with timestamps */ -+void -+bcmprinttslogs(void) -+{ -+ int j = 0; -+ int num; -+ -+ num = logi - readi; -+ if (num < 0) { -+ num += LOGSIZE; -+ } -+ -+ /* Format and print the log entries directly in chronological order */ -+ for (j = 0; j < num; readi = (readi + 1) % LOGSIZE, j++) { -+ if (logtab[readi].fmt == NULL) { -+ continue; -+ } -+ bcmprinttstamp(logtab[readi].cycles); -+ printf(logtab[readi].fmt, logtab[readi].a1, logtab[readi].a2); -+ printf("\n"); -+ } -+} -+ -+void -+bcmdumptslog(char *buf, int size) -+{ -+ char *limit; -+ int j = 0; -+ int num; -+ uint us, ms, sec; -+ -+ limit = buf + size - 80; -+ *buf = '\0'; -+ -+ num = logi - readi; -+ -+ if (num < 0) { -+ num += LOGSIZE; -+ } -+ -+ /* print in chronological order */ -+ for (j = 0; j < num && (buf < limit); readi = (readi + 1) % LOGSIZE, j++) { -+ if (logtab[readi].fmt == NULL) { -+ continue; -+ } -+ us = (logtab[readi].cycles % TSF_TICKS_PER_MS) * 1000 / TSF_TICKS_PER_MS; -+ ms = logtab[readi].cycles / TSF_TICKS_PER_MS; -+ sec = ms / 1000; -+ ms -= sec * 1000; -+ -+ buf += snprintf(buf, (limit - buf), "%04u.%03u.%03u ", sec, ms, us); -+ /* buf += snprintf(buf, (limit - buf), "%d\t", logtab[readi].cycles); */ -+ buf += snprintf(buf, (limit - buf), logtab[readi].fmt, logtab[readi].a1, -+ logtab[readi].a2); -+ buf += snprintf(buf, (limit - buf), "\n"); -+ } -+} -+#endif /* BCMTSTAMPEDLOGS */ -+ -+#if defined(BCMDBG) || defined(DHD_DEBUG) -+/* pretty hex print a pkt buffer chain */ -+void -+prpkt(const char *msg, osl_t *osh, void *p0) -+{ -+ void *p; -+ -+ if (msg && (msg[0] != '\0')) { -+ printf("%s:\n", msg); -+ } -+ -+ for (p = p0; p; p = PKTNEXT(osh, p)) { -+ prhex(NULL, PKTDATA(osh, p), PKTLEN(osh, p)); -+ } -+} -+#endif /* BCMDBG || DHD_DEBUG */ -+ -+/* Takes an Ethernet frame and sets out-of-bound PKTPRIO. -+ * Also updates the inplace vlan tag if requested. -+ * For debugging, it returns an indication of what it did. -+ */ -+uint BCMFASTPATH -+pktsetprio(void *pkt, bool update_vtag) -+{ -+ struct ether_header *eh; -+ struct ethervlan_header *evh; -+ uint8 *pktdata; -+ int priority = 0; -+ int rc = 0; -+ -+ pktdata = (uint8 *)PKTDATA(NULL, pkt); -+ ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16))); -+ -+ eh = (struct ether_header *) pktdata; -+ -+ if (eh->ether_type == hton16(ETHER_TYPE_8021Q)) { -+ uint16 vlan_tag; -+ int vlan_prio, dscp_prio = 0; -+ -+ evh = (struct ethervlan_header *)eh; -+ -+ vlan_tag = ntoh16(evh->vlan_tag); -+ vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK; -+ -+ if (evh->ether_type == hton16(ETHER_TYPE_IP)) { -+ uint8 *ip_body = pktdata + sizeof(struct ethervlan_header); -+ uint8 tos_tc = IP_TOS46(ip_body); -+ dscp_prio = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); -+ } -+ -+ /* DSCP priority gets precedence over 802.1P (vlan tag) */ -+ if (dscp_prio != 0) { -+ priority = dscp_prio; -+ rc |= PKTPRIO_VDSCP; -+ } else { -+ priority = vlan_prio; -+ rc |= PKTPRIO_VLAN; -+ } -+ /* -+ * If the DSCP priority is not the same as the VLAN priority, -+ * then overwrite the priority field in the vlan tag, with the -+ * DSCP priority value. This is required for Linux APs because -+ * the VLAN driver on Linux, overwrites the skb->priority field -+ * with the priority value in the vlan tag -+ */ -+ if (update_vtag && (priority != vlan_prio)) { -+ vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT); -+ vlan_tag |= (uint16)priority << VLAN_PRI_SHIFT; -+ evh->vlan_tag = hton16(vlan_tag); -+ rc |= PKTPRIO_UPD; -+ } -+ } else if (eh->ether_type == hton16(ETHER_TYPE_IP)) { -+ uint8 *ip_body = pktdata + sizeof(struct ether_header); -+ uint8 tos_tc = IP_TOS46(ip_body); -+ priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); -+ rc |= PKTPRIO_DSCP; -+ } -+ -+ ASSERT(priority >= 0 && priority <= MAXPRIO); -+ PKTSETPRIO(pkt, priority); -+ return (rc | priority); -+} -+ -+#ifndef BCM_BOOTLOADER -+ -+static char bcm_undeferrstr[32]; -+static const char *const bcmerrorstrtable[] = BCMERRSTRINGTABLE; -+ -+/* Convert the error codes into related error strings */ -+const char * -+bcmerrorstr(int bcmerror) -+{ -+ /* check if someone added a bcmerror code but forgot to add errorstring */ -+ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1)); -+ -+ if (bcmerror > 0 || bcmerror < BCME_LAST) { -+ snprintf(bcm_undeferrstr, sizeof(bcm_undeferrstr), "Undefined error %d", bcmerror); -+ return bcm_undeferrstr; -+ } -+ -+ ASSERT(strlen(bcmerrorstrtable[-bcmerror]) < BCME_STRLEN); -+ -+ return bcmerrorstrtable[-bcmerror]; -+} -+ -+#endif /* !BCM_BOOTLOADER */ -+ -+#ifdef WLC_LOW -+static void -+BCMINITFN(bcm_nvram_refresh)(char *flash) -+{ -+ int i; -+ int ret = 0; -+ -+ ASSERT(flash != NULL); -+ -+ /* default "empty" vars cache */ -+ bzero(flash, 2); -+ -+ if ((ret = nvram_getall(flash, NVRAM_SPACE))) { -+ return; -+ } -+ -+ /* determine nvram length */ -+ for (i = 0; i < NVRAM_SPACE; i++) { -+ if (flash[i] == '\0' && flash[i+1] == '\0') { -+ break; -+ } -+ } -+ -+ if (i > 1) { -+ vars_len = i + 2; -+ } else { -+ vars_len = 0; -+ } -+} -+ -+char * -+bcm_nvram_vars(uint *length) -+{ -+ /* cache may be stale if nvram is read/write */ -+ if (nvram_vars) { -+ ASSERT(!bcmreclaimed); -+ bcm_nvram_refresh(nvram_vars); -+ } -+ if (length) { -+ *length = vars_len; -+ } -+ return nvram_vars; -+} -+ -+/* copy nvram vars into locally-allocated multi-string array */ -+int -+BCMINITFN(bcm_nvram_cache)(void *sih) -+{ -+ int ret = 0; -+ void *osh; -+ char *flash = NULL; -+ -+ if (vars_len >= 0) { -+ bcm_nvram_refresh(nvram_vars); -+ return 0; -+ } -+ -+ osh = si_osh((si_t *)sih); -+ -+ /* allocate memory and read in flash */ -+ if (!(flash = MALLOC(osh, NVRAM_SPACE))) { -+ ret = BCME_NOMEM; -+ goto exit; -+ } -+ -+ bcm_nvram_refresh(flash); -+ -+ /* cache must be full size of nvram if read/write */ -+ nvram_vars = flash; -+ -+exit: -+ return ret; -+} -+#endif /* WLC_LOW */ -+ -+ -+int32 -+exthdr_validate(char *ptr, uint size) -+{ -+ char *exthdr, *trx_offset; -+ uint hdrsz; -+ int trxof = 0; -+ -+ if ((exthdr = nvram_get("ext_imghdr"))) { -+ char s[] = "XXX"; -+ uint i, j; -+ -+ hdrsz = strlen(exthdr); -+ -+ if (hdrsz > size) { -+ printf("Exthdr_size(%d) > Image_size(%d)\n", hdrsz, size); -+ trxof = -1; -+ goto done; -+ } -+ -+ if (hdrsz == 0) { -+ goto match; -+ } -+ -+ for (i = 0, j = 0; i < (hdrsz >> 1); i++) { -+ sprintf(s, "%02x", (ptr[i] & 0xff)); -+ if ((exthdr[j++] != s[0]) || (exthdr[j++] != s[1])) { -+ printf("Header mismatch\n"); -+ goto done; -+ } -+ } -+ } -+ -+match: -+ if ((trx_offset = nvram_get("trx_offset"))) -+ trxof = bcm_strtoul(trx_offset, NULL, 0); -+ -+done: -+ return trxof; -+} -+ -+/* iovar table lookup */ -+const bcm_iovar_t* -+bcm_iovar_lookup(const bcm_iovar_t *table, const char *name) -+{ -+ const bcm_iovar_t *vi; -+ const char *lookup_name; -+ -+ /* skip any ':' delimited option prefixes */ -+ lookup_name = strrchr(name, ':'); -+ if (lookup_name != NULL) { -+ lookup_name++; -+ } else { -+ lookup_name = name; -+ } -+ -+ ASSERT(table != NULL); -+ -+ for (vi = table; vi->name; vi++) { -+ if (!strcmp(vi->name, lookup_name)) { -+ return vi; -+ } -+ } -+ /* ran to end of table */ -+ -+ return NULL; /* var name not found */ -+} -+ -+int -+bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) -+{ -+ int bcmerror = 0; -+ -+ /* length check on io buf */ -+ switch (vi->type) { -+ case IOVT_BOOL: -+ case IOVT_INT8: -+ case IOVT_INT16: -+ case IOVT_INT32: -+ case IOVT_UINT8: -+ case IOVT_UINT16: -+ case IOVT_UINT32: -+ /* all integers are int32 sized args at the ioctl interface */ -+ if (len < (int)sizeof(int)) { -+ bcmerror = BCME_BUFTOOSHORT; -+ } -+ break; -+ -+ case IOVT_BUFFER: -+ /* buffer must meet minimum length requirement */ -+ if (len < vi->minlen) { -+ bcmerror = BCME_BUFTOOSHORT; -+ } -+ break; -+ -+ case IOVT_VOID: -+ if (!set) { -+ /* Cannot return nil... */ -+ bcmerror = BCME_UNSUPPORTED; -+ } else if (len) { -+ /* Set is an action w/o parameters */ -+ bcmerror = BCME_BUFTOOLONG; -+ } -+ break; -+ -+ default: -+ /* unknown type for length check in iovar info */ -+ ASSERT(0); -+ bcmerror = BCME_UNSUPPORTED; -+ } -+ -+ return bcmerror; -+} -+#endif /* BCMDRIVER */ -+ -+ -+/******************************************************************************* -+ * crc8 -+ * -+ * Computes a crc8 over the input data using the polynomial: -+ * -+ * x^8 + x^7 +x^6 + x^4 + x^2 + 1 -+ * -+ * The caller provides the initial value (either CRC8_INIT_VALUE -+ * or the previous returned value) to allow for processing of -+ * discontiguous blocks of data. When generating the CRC the -+ * caller is responsible for complementing the final return value -+ * and inserting it into the byte stream. When checking, a final -+ * return value of CRC8_GOOD_VALUE indicates a valid CRC. -+ * -+ * Reference: Dallas Semiconductor Application Note 27 -+ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", -+ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., -+ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt -+ * -+ * **************************************************************************** -+ */ -+ -+static const uint8 crc8_table[256] = { -+ 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, -+ 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, -+ 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, -+ 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, -+ 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, -+ 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, -+ 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, -+ 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, -+ 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, -+ 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, -+ 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, -+ 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, -+ 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, -+ 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, -+ 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, -+ 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, -+ 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, -+ 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, -+ 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, -+ 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, -+ 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, -+ 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, -+ 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, -+ 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, -+ 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, -+ 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, -+ 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, -+ 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, -+ 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, -+ 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, -+ 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, -+ 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F -+}; -+ -+#define CRC_INNER_LOOP(n, c, x) \ -+ (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] -+ -+uint8 -+BCMROMFN(hndcrc8)( -+ uint8 *pdata, /* pointer to array of data to process */ -+ uint nbytes, /* number of input data bytes to process */ -+ uint8 crc /* either CRC8_INIT_VALUE or previous return value */ -+) -+{ -+ /* hard code the crc loop instead of using CRC_INNER_LOOP macro -+ * to avoid the undefined and unnecessary (uint8 >> 8) operation. -+ */ -+ while (nbytes-- > 0) { -+ crc = crc8_table[(crc ^ *pdata++) & 0xff]; -+ } -+ -+ return crc; -+} -+ -+/******************************************************************************* -+ * crc16 -+ * -+ * Computes a crc16 over the input data using the polynomial: -+ * -+ * x^16 + x^12 +x^5 + 1 -+ * -+ * The caller provides the initial value (either CRC16_INIT_VALUE -+ * or the previous returned value) to allow for processing of -+ * discontiguous blocks of data. When generating the CRC the -+ * caller is responsible for complementing the final return value -+ * and inserting it into the byte stream. When checking, a final -+ * return value of CRC16_GOOD_VALUE indicates a valid CRC. -+ * -+ * Reference: Dallas Semiconductor Application Note 27 -+ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", -+ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., -+ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt -+ * -+ * **************************************************************************** -+ */ -+ -+static const uint16 crc16_table[256] = { -+ 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, -+ 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, -+ 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, -+ 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, -+ 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, -+ 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, -+ 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, -+ 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, -+ 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, -+ 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, -+ 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, -+ 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, -+ 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, -+ 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, -+ 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, -+ 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, -+ 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, -+ 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, -+ 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, -+ 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, -+ 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, -+ 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, -+ 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, -+ 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, -+ 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, -+ 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, -+ 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, -+ 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, -+ 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, -+ 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, -+ 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, -+ 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 -+}; -+ -+uint16 -+BCMROMFN(hndcrc16)( -+ uint8 *pdata, /* pointer to array of data to process */ -+ uint nbytes, /* number of input data bytes to process */ -+ uint16 crc /* either CRC16_INIT_VALUE or previous return value */ -+) -+{ -+ while (nbytes-- > 0) { -+ CRC_INNER_LOOP(16, crc, *pdata++); -+ } -+ return crc; -+} -+ -+static const uint32 crc32_table[256] = { -+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, -+ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, -+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, -+ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, -+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, -+ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, -+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, -+ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, -+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, -+ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, -+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, -+ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, -+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, -+ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, -+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, -+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, -+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, -+ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, -+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, -+ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, -+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, -+ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, -+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, -+ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, -+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, -+ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, -+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, -+ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, -+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, -+ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, -+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, -+ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, -+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, -+ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, -+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, -+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, -+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, -+ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, -+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, -+ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, -+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, -+ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, -+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, -+ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, -+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, -+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, -+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, -+ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, -+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, -+ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, -+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, -+ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, -+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, -+ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, -+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, -+ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, -+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, -+ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, -+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, -+ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, -+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, -+ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, -+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, -+ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -+}; -+ -+/* -+ * crc input is CRC32_INIT_VALUE for a fresh start, or previous return value if -+ * accumulating over multiple pieces. -+ */ -+uint32 -+BCMROMFN(hndcrc32)(uint8 *pdata, uint nbytes, uint32 crc) -+{ -+ uint8 *pend; -+#ifdef __mips__ -+ uint8 tmp[4]; -+ ulong *tptr = (ulong *)tmp; -+ -+ if (nbytes > 3) { -+ /* in case the beginning of the buffer isn't aligned */ -+ pend = (uint8 *)((uint)(pdata + 3) & ~0x3); -+ nbytes -= (pend - pdata); -+ while (pdata < pend) { -+ CRC_INNER_LOOP(32, crc, *pdata++); -+ } -+ } -+ -+ if (nbytes > 3) { -+ /* handle bulk of data as 32-bit words */ -+ pend = pdata + (nbytes & ~0x3); -+ while (pdata < pend) { -+ *tptr = *(ulong *)pdata; -+ pdata += sizeof(ulong *); -+ CRC_INNER_LOOP(32, crc, tmp[0]); -+ CRC_INNER_LOOP(32, crc, tmp[1]); -+ CRC_INNER_LOOP(32, crc, tmp[2]); -+ CRC_INNER_LOOP(32, crc, tmp[3]); -+ } -+ } -+ -+ /* 1-3 bytes at end of buffer */ -+ pend = pdata + (nbytes & 0x03); -+ while (pdata < pend) { -+ CRC_INNER_LOOP(32, crc, *pdata++); -+ } -+#else -+ pend = pdata + nbytes; -+ while (pdata < pend) { -+ CRC_INNER_LOOP(32, crc, *pdata++); -+ } -+#endif /* __mips__ */ -+ -+ return crc; -+} -+ -+#ifdef notdef -+#define CLEN 1499 /* CRC Length */ -+#define CBUFSIZ (CLEN+4) -+#define CNBUFS 5 /* # of bufs */ -+ -+void -+testcrc32(void) -+{ -+ uint j, k, l; -+ uint8 *buf; -+ uint len[CNBUFS]; -+ uint32 crcr; -+ uint32 crc32tv[CNBUFS] = -+ {0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110}; -+ -+ ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL); -+ -+ /* step through all possible alignments */ -+ for (l = 0; l <= 4; l++) { -+ for (j = 0; j < CNBUFS; j++) { -+ len[j] = CLEN; -+ for (k = 0; k < len[j]; k++) { -+ *(buf + j*CBUFSIZ + (k+l)) = (j+k) & 0xff; -+ } -+ } -+ -+ for (j = 0; j < CNBUFS; j++) { -+ crcr = crc32(buf + j*CBUFSIZ + l, len[j], CRC32_INIT_VALUE); -+ ASSERT(crcr == crc32tv[j]); -+ } -+ } -+ -+ MFREE(buf, CBUFSIZ*CNBUFS); -+ return; -+} -+#endif /* notdef */ -+ -+/* -+ * Advance from the current 1-byte tag/1-byte length/variable-length value -+ * triple, to the next, returning a pointer to the next. -+ * If the current or next TLV is invalid (does not fit in given buffer length), -+ * NULL is returned. -+ * *buflen is not modified if the TLV elt parameter is invalid, or is decremented -+ * by the TLV parameter's length if it is valid. -+ */ -+bcm_tlv_t * -+BCMROMFN(bcm_next_tlv)(bcm_tlv_t *elt, int *buflen) -+{ -+ int len; -+ -+ /* validate current elt */ -+ if (!bcm_valid_tlv(elt, *buflen)) { -+ return NULL; -+ } -+ -+ /* advance to next elt */ -+ len = elt->len; -+ elt = (bcm_tlv_t*)(elt->data + len); -+ *buflen -= (TLV_HDR_LEN + len); -+ -+ /* validate next elt */ -+ if (!bcm_valid_tlv(elt, *buflen)) { -+ return NULL; -+ } -+ -+ return elt; -+} -+ -+/* -+ * Traverse a string of 1-byte tag/1-byte length/variable-length value -+ * triples, returning a pointer to the substring whose first element -+ * matches tag -+ */ -+bcm_tlv_t * -+BCMROMFN(bcm_parse_tlvs)(void *buf, int buflen, uint key) -+{ -+ bcm_tlv_t *elt; -+ int totlen; -+ -+ elt = (bcm_tlv_t*)buf; -+ totlen = buflen; -+ -+ /* find tagged parameter */ -+ while (totlen >= TLV_HDR_LEN) { -+ int len = elt->len; -+ -+ /* validate remaining totlen */ -+ if ((elt->id == key) && -+ (totlen >= (len + TLV_HDR_LEN))) { -+ return (elt); -+ } -+ -+ elt = (bcm_tlv_t*)((uint8*)elt + (len + TLV_HDR_LEN)); -+ totlen -= (len + TLV_HDR_LEN); -+ } -+ -+ return NULL; -+} -+ -+/* -+ * Traverse a string of 1-byte tag/1-byte length/variable-length value -+ * triples, returning a pointer to the substring whose first element -+ * matches tag. Stop parsing when we see an element whose ID is greater -+ * than the target key. -+ */ -+bcm_tlv_t * -+BCMROMFN(bcm_parse_ordered_tlvs)(void *buf, int buflen, uint key) -+{ -+ bcm_tlv_t *elt; -+ int totlen; -+ -+ elt = (bcm_tlv_t*)buf; -+ totlen = buflen; -+ -+ /* find tagged parameter */ -+ while (totlen >= TLV_HDR_LEN) { -+ uint id = elt->id; -+ int len = elt->len; -+ -+ /* Punt if we start seeing IDs > than target key */ -+ if (id > key) { -+ return (NULL); -+ } -+ -+ /* validate remaining totlen */ -+ if ((id == key) && -+ (totlen >= (len + TLV_HDR_LEN))) { -+ return (elt); -+ } -+ -+ elt = (bcm_tlv_t*)((uint8*)elt + (len + TLV_HDR_LEN)); -+ totlen -= (len + TLV_HDR_LEN); -+ } -+ return NULL; -+} -+ -+#if defined(BCMDBG) || defined(BCMDBG_ERR) || defined(WLMSG_PRHDRS) || \ -+ defined(WLMSG_PRPKT) || defined(WLMSG_ASSOC) || defined(DHD_DEBUG) -+int -+bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len) -+{ -+ int i; -+ char* p = buf; -+ char hexstr[16]; -+ int slen = 0, nlen = 0; -+ uint32 bit; -+ const char* name; -+ -+ if (len < 2 || !buf) { -+ return 0; -+ } -+ -+ buf[0] = '\0'; -+ -+ for (i = 0; flags != 0; i++) { -+ bit = bd[i].bit; -+ name = bd[i].name; -+ if (bit == 0 && flags != 0) { -+ /* print any unnamed bits */ -+ snprintf(hexstr, 16, "0x%X", flags); -+ name = hexstr; -+ flags = 0; /* exit loop */ -+ } else if ((flags & bit) == 0) { -+ continue; -+ } -+ flags &= ~bit; -+ nlen = strlen(name); -+ slen += nlen; -+ /* count btwn flag space */ -+ if (flags != 0) { -+ slen += 1; -+ } -+ /* need NULL char as well */ -+ if (len <= slen) { -+ break; -+ } -+ /* copy NULL char but don't count it */ -+ strncpy(p, name, nlen + 1); -+ p += nlen; -+ /* copy btwn flag space and NULL char */ -+ if (flags != 0) { -+ p += snprintf(p, 2, " "); -+ } -+ } -+ -+ /* indicate the str was too short */ -+ if (flags != 0) { -+ if (len < 2) { -+ p -= 2 - len; /* overwrite last char */ -+ } -+ p += snprintf(p, 2, ">"); -+ } -+ -+ return (int)(p - buf); -+} -+ -+/* print bytes formatted as hex to a string. return the resulting string length */ -+int -+bcm_format_hex(char *str, const void *bytes, int len) -+{ -+ int i; -+ char *p = str; -+ const uint8 *src = (const uint8*)bytes; -+ -+ for (i = 0; i < len; i++) { -+ p += snprintf(p, 3, "%02X", *src); -+ src++; -+ } -+ return (int)(p - str); -+} -+#endif -+ -+/* pretty hex print a contiguous buffer */ -+void -+prhex(const char *msg, uchar *buf, uint nbytes) -+{ -+ char line[128], *p; -+ int len = sizeof(line); -+ int nchar; -+ uint i; -+ -+ if (msg && (msg[0] != '\0')) { -+ printf("%s:\n", msg); -+ } -+ -+ p = line; -+ for (i = 0; i < nbytes; i++) { -+ if (i % 16 == 0) { -+ nchar = snprintf(p, len, " %04d: ", i); /* line prefix */ -+ p += nchar; -+ len -= nchar; -+ } -+ if (len > 0) { -+ nchar = snprintf(p, len, "%02x ", buf[i]); -+ p += nchar; -+ len -= nchar; -+ } -+ -+ if (i % 16 == 15) { -+ printf("%s\n", line); /* flush line */ -+ p = line; -+ len = sizeof(line); -+ } -+ } -+ -+ /* flush last partial line */ -+ if (p != line) { -+ printf("%s\n", line); -+ } -+} -+ -+static const char *crypto_algo_names[] = { -+ "NONE", -+ "WEP1", -+ "TKIP", -+ "WEP128", -+ "AES_CCM", -+ "AES_OCB_MSDU", -+ "AES_OCB_MPDU", -+ "NALG" -+ "UNDEF", -+ "UNDEF", -+ "UNDEF", -+ "UNDEF" -+}; -+ -+const char * -+bcm_crypto_algo_name(uint algo) -+{ -+ return (algo < ARRAYSIZE(crypto_algo_names)) ? crypto_algo_names[algo] : "ERR"; -+} -+ -+#ifdef BCMDBG -+void -+deadbeef(void *p, size_t len) -+{ -+ static uint8 meat[] = { 0xde, 0xad, 0xbe, 0xef }; -+ -+ while (len-- > 0) { -+ *(uint8*)p = meat[((uintptr)p) & 3]; -+ p = (uint8*)p + 1; -+ } -+} -+#endif /* BCMDBG */ -+ -+char * -+bcm_chipname(uint chipid, char *buf, uint len) -+{ -+ const char *fmt; -+ -+ fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x"; -+ snprintf(buf, len, fmt, chipid); -+ return buf; -+} -+ -+/* Produce a human-readable string for boardrev */ -+char * -+bcm_brev_str(uint32 brev, char *buf) -+{ -+ if (brev < 0x100) { -+ snprintf(buf, 8, "%d.%d", (brev & 0xf0) >> 4, brev & 0xf); -+ } else { -+ snprintf(buf, 8, "%c%03x", ((brev & 0xf000) == 0x1000) ? 'P' : 'A', brev & 0xfff); -+ } -+ return (buf); -+} -+ -+#define BUFSIZE_TODUMP_ATONCE 512 /* Buffer size */ -+ -+/* dump large strings to console */ -+void -+printbig(char *buf) -+{ -+ uint len, max_len; -+ char c; -+ -+ len = strlen(buf); -+ -+ max_len = BUFSIZE_TODUMP_ATONCE; -+ -+ while (len > max_len) { -+ c = buf[max_len]; -+ buf[max_len] = '\0'; -+ printf("%s", buf); -+ buf[max_len] = c; -+ -+ buf += max_len; -+ len -= max_len; -+ } -+ /* print the remaining string */ -+ printf("%s\n", buf); -+ return; -+} -+ -+/* routine to dump fields in a fileddesc structure */ -+uint -+bcmdumpfields(bcmutl_rdreg_rtn read_rtn, void *arg0, uint arg1, struct fielddesc *fielddesc_array, -+ char *buf, uint32 bufsize) -+{ -+ uint filled_len; -+ int len; -+ struct fielddesc *cur_ptr; -+ -+ filled_len = 0; -+ cur_ptr = fielddesc_array; -+ -+ while (bufsize > 1) { -+ if (cur_ptr->nameandfmt == NULL) { -+ break; -+ } -+ len = snprintf(buf, bufsize, cur_ptr->nameandfmt, -+ read_rtn(arg0, arg1, cur_ptr->offset)); -+ /* check for snprintf overflow or error */ -+ if (len < 0 || (uint32)len >= bufsize) { -+ len = bufsize - 1; -+ } -+ buf += len; -+ bufsize -= len; -+ filled_len += len; -+ cur_ptr++; -+ } -+ return filled_len; -+} -+ -+uint -+bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) -+{ -+ uint len; -+ -+ len = strlen(name) + 1; -+ -+ if ((len + datalen) > buflen) { -+ return 0; -+ } -+ -+ strncpy(buf, name, buflen); -+ -+ /* append data onto the end of the name string */ -+ memcpy(&buf[len], data, datalen); -+ len += datalen; -+ -+ return len; -+} -+ -+/* Quarter dBm units to mW -+ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 -+ * Table is offset so the last entry is largest mW value that fits in -+ * a uint16. -+ */ -+ -+#define QDBM_OFFSET 153 /* Offset for first entry */ -+#define QDBM_TABLE_LEN 40 /* Table size */ -+ -+/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET. -+ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2 -+ */ -+#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */ -+ -+/* Largest mW value that will round down to the last table entry, -+ * QDBM_OFFSET + QDBM_TABLE_LEN-1. -+ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2. -+ */ -+#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */ -+ -+static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = { -+/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */ -+/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, -+/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849, -+/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, -+/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, -+/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096 -+}; -+ -+uint16 -+BCMROMFN(bcm_qdbm_to_mw)(uint8 qdbm) -+{ -+ uint factor = 1; -+ int idx = qdbm - QDBM_OFFSET; -+ -+ if (idx >= QDBM_TABLE_LEN) { -+ /* clamp to max uint16 mW value */ -+ return 0xFFFF; -+ } -+ -+ /* scale the qdBm index up to the range of the table 0-40 -+ * where an offset of 40 qdBm equals a factor of 10 mW. -+ */ -+ while (idx < 0) { -+ idx += 40; -+ factor *= 10; -+ } -+ -+ /* return the mW value scaled down to the correct factor of 10, -+ * adding in factor/2 to get proper rounding. -+ */ -+ return ((nqdBm_to_mW_map[idx] + factor/2) / factor); -+} -+ -+uint8 -+BCMROMFN(bcm_mw_to_qdbm)(uint16 mw) -+{ -+ uint8 qdbm; -+ int offset; -+ uint mw_uint = mw; -+ uint boundary; -+ -+ /* handle boundary case */ -+ if (mw_uint <= 1) { -+ return 0; -+ } -+ -+ offset = QDBM_OFFSET; -+ -+ /* move mw into the range of the table */ -+ while (mw_uint < QDBM_TABLE_LOW_BOUND) { -+ mw_uint *= 10; -+ offset -= 40; -+ } -+ -+ for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) { -+ boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] - -+ nqdBm_to_mW_map[qdbm])/2; -+ if (mw_uint < boundary) break; -+ } -+ -+ qdbm += (uint8)offset; -+ -+ return (qdbm); -+} -+ -+ -+uint -+BCMROMFN(bcm_bitcount)(uint8 *bitmap, uint length) -+{ -+ uint bitcount = 0, i; -+ uint8 tmp; -+ for (i = 0; i < length; i++) { -+ tmp = bitmap[i]; -+ while (tmp) { -+ bitcount++; -+ tmp &= (tmp - 1); -+ } -+ } -+ return bitcount; -+} -+ -+#ifdef BCMDRIVER -+ -+/* Initialization of bcmstrbuf structure */ -+void -+bcm_binit(struct bcmstrbuf *b, char *buf, uint size) -+{ -+ b->origsize = b->size = size; -+ b->origbuf = b->buf = buf; -+} -+ -+/* Buffer sprintf wrapper to guard against buffer overflow */ -+int -+bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) -+{ -+ va_list ap; -+ int r; -+ -+ va_start(ap, fmt); -+ -+ r = vsnprintf(b->buf, b->size, fmt, ap); -+ -+ /* Non Ansi C99 compliant returns -1, -+ * Ansi compliant return r >= b->size, -+ * bcmstdlib returns 0, handle all -+ */ -+ /* r == 0 is also the case when strlen(fmt) is zero. -+ * typically the case when "" is passed as argument. -+ */ -+ if ((r == -1) || (r >= (int)b->size)) { -+ b->size = 0; -+ } else { -+ b->size -= r; -+ b->buf += r; -+ } -+ -+ va_end(ap); -+ -+ return r; -+} -+ -+void -+bcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, uint8 *buf, int len) -+{ -+ int i; -+ -+ if (msg != NULL && msg[0] != '\0') { -+ bcm_bprintf(b, "%s", msg); -+ } -+ for (i = 0; i < len; i ++) { -+ bcm_bprintf(b, "%02X", buf[i]); -+ } -+ if (newline) { -+ bcm_bprintf(b, "\n"); -+ } -+} -+ -+void -+bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount) -+{ -+ int i; -+ -+ for (i = 0; i < num_bytes; i++) { -+ num[i] += amount; -+ if (num[i] >= amount) { -+ break; -+ } -+ amount = 1; -+ } -+} -+ -+int -+bcm_cmp_bytes(const uchar *arg1, const uchar *arg2, uint8 nbytes) -+{ -+ int i; -+ -+ for (i = nbytes - 1; i >= 0; i--) { -+ if (arg1[i] != arg2[i]) { -+ return (arg1[i] - arg2[i]); -+ } -+ } -+ return 0; -+} -+ -+void -+bcm_print_bytes(const char *name, const uchar *data, int len) -+{ -+ int i; -+ int per_line = 0; -+ -+ printf("%s: %d \n", name ? name : "", len); -+ for (i = 0; i < len; i++) { -+ printf("%02x ", *data++); -+ per_line++; -+ if (per_line == 16) { -+ per_line = 0; -+ printf("\n"); -+ } -+ } -+ printf("\n"); -+} -+#if defined(WLTINYDUMP) || defined(BCMDBG) || defined(WLMSG_INFORM) || \ -+ defined(WLMSG_ASSOC) || defined(WLMSG_PRPKT) || defined(WLMSG_WSEC) -+#define SSID_FMT_BUF_LEN ((4 * DOT11_MAX_SSID_LEN) + 1) -+ -+int -+bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len) -+{ -+ uint i, c; -+ char *p = buf; -+ char *endp = buf + SSID_FMT_BUF_LEN; -+ -+ if (ssid_len > DOT11_MAX_SSID_LEN) { -+ ssid_len = DOT11_MAX_SSID_LEN; -+ } -+ -+ for (i = 0; i < ssid_len; i++) { -+ c = (uint)ssid[i]; -+ if (c == '\\') { -+ *p++ = '\\'; -+ *p++ = '\\'; -+ } else if (bcm_isprint((uchar)c)) { -+ *p++ = (char)c; -+ } else { -+ p += snprintf(p, (endp - p), "\\x%02X", c); -+ } -+ } -+ *p = '\0'; -+ ASSERT(p < endp); -+ -+ return (int)(p - buf); -+} -+#endif /* WLTINYDUMP || BCMDBG || WLMSG_INFORM || WLMSG_ASSOC || WLMSG_PRPKT */ -+ -+#endif /* BCMDRIVER */ -+ -+/* -+ * ProcessVars:Takes a buffer of "=\n" lines read from a file and ending in a NUL. -+ * also accepts nvram files which are already in the format of =\0\=\0 -+ * Removes carriage returns, empty lines, comment lines, and converts newlines to NULs. -+ * Shortens buffer as needed and pads with NULs. End of buffer is marked by two NULs. -+*/ -+ -+unsigned int -+process_nvram_vars(char *varbuf, unsigned int len) -+{ -+ char *dp; -+ bool findNewline; -+ int column; -+ unsigned int buf_len, n; -+ unsigned int pad = 0; -+ -+ dp = varbuf; -+ -+ findNewline = FALSE; -+ column = 0; -+ -+ for (n = 0; n < len; n++) { -+ if (varbuf[n] == '\r') { -+ continue; -+ } -+ if (findNewline && varbuf[n] != '\n') { -+ continue; -+ } -+ findNewline = FALSE; -+ if (varbuf[n] == '#') { -+ findNewline = TRUE; -+ continue; -+ } -+ if (varbuf[n] == '\n') { -+ if (column == 0) { -+ continue; -+ } -+ *dp++ = 0; -+ column = 0; -+ continue; -+ } -+ *dp++ = varbuf[n]; -+ column++; -+ } -+ buf_len = (unsigned int)(dp - varbuf); -+ if (buf_len % 4) { -+ pad = 4 - buf_len % 4; -+ if (pad && (buf_len + pad <= len)) { -+ buf_len += pad; -+ } -+ } -+ -+ while (dp < varbuf + n) { -+ *dp++ = 0; -+ } -+ -+ return buf_len; -+} -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/gh2_erom.c b/drivers/net/ethernet/broadcom/gmac/src/shared/gh2_erom.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/gh2_erom.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/gh2_erom.c 2017-11-09 17:53:44.032304000 +0800 -@@ -0,0 +1,18 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet -+ * Greyhound2 sudo EROM -+ * -+ */ -+#include -+ -+uint32 gh2_erom[] = { -+ //#define CC_CORE_ID 0x800 /* chipcommon core */ -+ 0x4bf80001, 0x2a004201, 0x18000005, 0x181200c5, -+ //#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ -+ 0x4bf82d01, 0x04004211, 0x00000103, 0x18042005, 0x181100c5, -+ 0x4bf82d01, 0x04004211, 0x00000203, 0x1804a005, 0x181110c5, -+ 0x0000000f -+}; -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/gh2_erom.h b/drivers/net/ethernet/broadcom/gmac/src/shared/gh2_erom.h ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/gh2_erom.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/gh2_erom.h 2017-11-09 17:53:44.033296000 +0800 -@@ -0,0 +1,14 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet -+ * Greyhound2 sudo EROM -+ * -+ */ -+ -+#ifndef _gh2_erom_h_ -+#define _gh2_erom_h_ -+ -+extern uint32 gh2_erom[]; -+ -+#endif /* _gh2_erom_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/gh_erom.c b/drivers/net/ethernet/broadcom/gmac/src/shared/gh_erom.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/gh_erom.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/gh_erom.c 2017-11-09 17:53:44.034292000 +0800 -@@ -0,0 +1,28 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet -+ * Greyhound sudo EROM -+ * -+ */ -+#include -+ -+uint32 gh_erom[] = { -+ //#define CC_CORE_ID 0x800 /* chipcommon core */ -+ 0x4bf80001, 0x2a004201, 0x18000005, 0x181200c5, -+ //#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ -+ 0x4bf82d01, 0x04004211, 0x00000103, 0x18042005, 0x181100c5, -+ 0x0000000f -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/gh_erom.h b/drivers/net/ethernet/broadcom/gmac/src/shared/gh_erom.h ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/gh_erom.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/gh_erom.h 2017-11-09 17:53:44.035289000 +0800 -@@ -0,0 +1,26 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet -+ * Greyhound sudo EROM -+ * -+ */ -+ -+#ifndef _gh_erom_h_ -+#define _gh_erom_h_ -+ -+extern uint32 gh_erom[]; -+ -+#endif /* _gh_erom_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/hnddma.c b/drivers/net/ethernet/broadcom/gmac/src/shared/hnddma.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/hnddma.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/hnddma.c 2017-11-09 17:53:44.045302000 +0800 -@@ -0,0 +1,3701 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Generic Broadcom Home Networking Division (HND) DMA module. -+ * This supports the following chips: BCM42xx, 44xx, 47xx . -+ * -+ * $Id: hnddma.c 328477 2012-04-19 10:57:54Z $ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH -+#include -+#endif -+ -+#ifdef CONFIG_BCM_IPROC_GMAC_RWREG_OPT -+#ifdef R_REG -+#undef R_REG -+#define R_REG(osh, r) (\ -+ sizeof(*(r)) == sizeof(uint8) ? (*(volatile unsigned char __force *)(r)) : \ -+ sizeof(*(r)) == sizeof(uint16) ? (*(volatile unsigned short __force *)(r)) : \ -+ (*(volatile unsigned int __force *)(r)) \ -+) -+#endif /* R_REG */ -+ -+#ifdef W_REG -+#undef W_REG -+#define W_REG(osh, r, v) (\ -+ sizeof(*(r)) == sizeof(uint8) ? (*(volatile unsigned char __force *)(r) = (v)) : \ -+ sizeof(*(r)) == sizeof(uint16) ? (*(volatile unsigned short __force *)(r) = (v)) : \ -+ (*(volatile unsigned int __force *)(r) = (v)) \ -+) -+#endif /* W_REG */ -+#endif /* CONFIG_BCM_IPROC_GMAC_RWREG_OPT */ -+ -+/* debug/trace */ -+#ifdef BCMDBG -+#define DMA_ERROR(args) if (!(*di->msg_level & 1)); else printf args -+#define DMA_TRACE(args) if (!(*di->msg_level & 2)); else printf args -+#elif defined(BCMDBG_ERR) -+#define DMA_ERROR(args) if (!(*di->msg_level & 1)); else printf args -+#define DMA_TRACE(args) -+#else -+#define DMA_ERROR(args) -+#define DMA_TRACE(args) -+#endif /* BCMDBG */ -+ -+#define DMA_NONE(args) -+ -+ -+#define d32txregs dregs.d32_u.txregs_32 -+#define d32rxregs dregs.d32_u.rxregs_32 -+#define txd32 dregs.d32_u.txd_32 -+#define rxd32 dregs.d32_u.rxd_32 -+ -+#define d64txregs dregs.d64_u.txregs_64 -+#define d64rxregs dregs.d64_u.rxregs_64 -+#define txd64 dregs.d64_u.txd_64 -+#define rxd64 dregs.d64_u.rxd_64 -+ -+#define DBG(x...) printk(KERN_ERR x) -+ -+/* default dma message level (if input msg_level pointer is null in dma_attach()) */ -+#ifdef BCMDBG_ERR -+static uint dma_msg_level = 1; -+#else -+static uint dma_msg_level = 0; -+#endif /* BCMDBG_ERR */ -+ -+#define MAXNAMEL 8 /* 8 char names */ -+ -+#define DI_INFO(dmah) ((dma_info_t *)dmah) -+ -+/* dma engine software state */ -+typedef struct dma_info { -+ struct hnddma_pub hnddma; /* exported structure, don't use hnddma_t, -+ * which could be const -+ */ -+ uint *msg_level; /* message level pointer */ -+ char name[MAXNAMEL]; /* callers name for diag msgs */ -+ -+ void *osh; /* os handle */ -+ si_t *sih; /* sb handle */ -+ -+ bool dma64; /* this dma engine is operating in 64-bit mode */ -+ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ -+ -+ union { -+ struct { -+ dma32regs_t *txregs_32; /* 32-bit dma tx engine registers */ -+ dma32regs_t *rxregs_32; /* 32-bit dma rx engine registers */ -+ dma32dd_t *txd_32; /* pointer to dma32 tx descriptor ring */ -+ dma32dd_t *rxd_32; /* pointer to dma32 rx descriptor ring */ -+ } d32_u; -+ struct { -+ dma64regs_t *txregs_64; /* 64-bit dma tx engine registers */ -+ dma64regs_t *rxregs_64; /* 64-bit dma rx engine registers */ -+ dma64dd_t *txd_64; /* pointer to dma64 tx descriptor ring */ -+ dma64dd_t *rxd_64; /* pointer to dma64 rx descriptor ring */ -+ } d64_u; -+ } dregs; -+ -+ uint16 dmadesc_align; /* alignment requirement for dma descriptors */ -+ -+ uint16 ntxd; /* # tx descriptors tunable */ -+ uint16 txin; /* index of next descriptor to reclaim */ -+ uint16 txout; /* index of next descriptor to post */ -+ void **txp; /* pointer to parallel array of pointers to packets */ -+ osldma_t *tx_dmah; /* DMA TX descriptor ring handle */ -+ hnddma_seg_map_t *txp_dmah; /* DMA MAP meta-data handle */ -+ dmaaddr_t txdpa; /* Aligned physical address of descriptor ring */ -+ dmaaddr_t txdpaorig; /* Original physical address of descriptor ring */ -+ uint16 txdalign; /* #bytes added to alloc'd mem to align txd */ -+ uint32 txdalloc; /* #bytes allocated for the ring */ -+ uint32 xmtptrbase; /* When using unaligned descriptors, the ptr register -+ * is not just an index, it needs all 13 bits to be -+ * an offset from the addr register. -+ */ -+ -+ uint16 nrxd; /* # rx descriptors tunable */ -+ uint16 rxin; /* index of next descriptor to reclaim */ -+ uint16 rxout; /* index of next descriptor to post */ -+ void **rxp; /* pointer to parallel array of pointers to packets */ -+ osldma_t *rx_dmah; /* DMA RX descriptor ring handle */ -+ hnddma_seg_map_t *rxp_dmah; /* DMA MAP meta-data handle */ -+ dmaaddr_t rxdpa; /* Aligned physical address of descriptor ring */ -+ dmaaddr_t rxdpaorig; /* Original physical address of descriptor ring */ -+ uint16 rxdalign; /* #bytes added to alloc'd mem to align rxd */ -+ uint32 rxdalloc; /* #bytes allocated for the ring */ -+ uint32 rcvptrbase; /* Base for ptr reg when using unaligned descriptors */ -+ -+ /* tunables */ -+ uint16 rxbufsize; /* rx buffer size in bytes, -+ * not including the extra headroom -+ */ -+ uint rxextrahdrroom; /* extra rx headroom, reverseved to assist upper stack -+ * e.g. some rx pkt buffers will be bridged to tx side -+ * without byte copying. The extra headroom needs to be -+ * large enough to fit txheader needs. -+ * Some dongle driver may not need it. -+ */ -+ uint nrxpost; /* # rx buffers to keep posted */ -+ uint rxoffset; /* rxcontrol offset */ -+ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */ -+ uint ddoffsethigh; /* high 32 bits */ -+ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */ -+ uint dataoffsethigh; /* high 32 bits */ -+ bool aligndesc_4k; /* descriptor base need to be aligned or not */ -+ uint8 rxburstlen; /* burstlen field for rx (for cores supporting burstlen) */ -+ uint8 txburstlen; /* burstlen field for tx (for cores supporting burstlen) */ -+ uint8 txmultioutstdrd; /* tx multiple outstanding reads */ -+ uint8 txprefetchctl; /* prefetch control for tx */ -+ uint8 txprefetchthresh; /* prefetch threshold for tx */ -+ uint8 rxprefetchctl; /* prefetch control for rx */ -+ uint8 rxprefetchthresh; /* prefetch threshold for rx */ -+ pktpool_t *pktpool; /* pktpool */ -+ uint dma_avoidance_cnt; -+ -+ uint32 d64_xs0_cd_mask; /* tx current descriptor pointer mask */ -+ uint32 d64_xs1_ad_mask; /* tx active descriptor mask */ -+ uint32 d64_rs0_cd_mask; /* rx current descriptor pointer mask */ -+ uint16 rs0cd; /* cached value of rcvstatus0 currdescr */ -+ uint16 xs0cd; /* cached value of xmtstatus0 currdescr */ -+ uint16 xs0cd_snapshot; /* snapshot of xmtstatus0 currdescr */ -+ spinlock_t des_lock; -+} dma_info_t; -+ -+/* -+ * If BCMDMA32 is defined, hnddma will support both 32-bit and 64-bit DMA engines. -+ * Otherwise it will support only 64-bit. -+ * -+ * DMA32_ENAB indicates whether hnddma is compiled with support for 32-bit DMA engines. -+ * DMA64_ENAB indicates whether hnddma is compiled with support for 64-bit DMA engines. -+ * -+ * DMA64_MODE indicates whether the current DMA engine is running as 64-bit. -+ */ -+#ifdef BCMDMA32 -+#define DMA32_ENAB(di) 1 -+#define DMA64_ENAB(di) 1 -+#define DMA64_MODE(di) ((di)->dma64) -+#else /* !BCMDMA32 */ -+#define DMA32_ENAB(di) 0 -+#define DMA64_ENAB(di) 1 -+#define DMA64_MODE(di) 1 -+#endif /* !BCMDMA32 */ -+ -+/* DMA Scatter-gather list is supported. Note this is limited to TX direction only */ -+#ifdef BCMDMASGLISTOSL -+#define DMASGLIST_ENAB TRUE -+#else -+#define DMASGLIST_ENAB FALSE -+#endif /* BCMDMASGLISTOSL */ -+ -+/* descriptor bumping macros */ -+#define XXD(x, n) ((x) & ((n) - 1)) /* faster than %, but n must be power of 2 */ -+#define TXD(x) XXD((x), di->ntxd) -+#define RXD(x) XXD((x), di->nrxd) -+#define NEXTTXD(i) TXD((i) + 1) -+#define PREVTXD(i) TXD((i) - 1) -+#define NEXTRXD(i) RXD((i) + 1) -+#define PREVRXD(i) RXD((i) - 1) -+ -+#define NTXDACTIVE(h, t) TXD((t) - (h)) -+#define NRXDACTIVE(h, t) RXD((t) - (h)) -+ -+/* macros to convert between byte offsets and indexes */ -+#define B2I(bytes, type) ((uint16)((bytes) / sizeof(type))) -+#define I2B(index, type) ((index) * sizeof(type)) -+ -+#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */ -+#define PCI32ADDR_HIGH_SHIFT 30 /* address[31:30] */ -+ -+#define PCI64ADDR_HIGH 0x80000000 /* address[63] */ -+#define PCI64ADDR_HIGH_SHIFT 31 /* address[63] */ -+ -+ -+#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH -+#define SKB_PREFETCH_LEN (128) -+#endif -+ -+/* Common prototypes */ -+static bool _dma_isaddrext(dma_info_t *di); -+static bool _dma_descriptor_align(dma_info_t *di); -+static bool _dma_alloc(dma_info_t *di, uint direction); -+static void _dma_detach(dma_info_t *di); -+static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa); -+static void _dma_rxinit(dma_info_t *di); -+static void *_dma_rx(dma_info_t *di); -+static bool _dma_rxfill(dma_info_t *di); -+static void _dma_rxreclaim(dma_info_t *di); -+static void _dma_rxenable(dma_info_t *di); -+static void *_dma_getnextrxp(dma_info_t *di, bool forceall); -+static void _dma_rx_param_get(dma_info_t *di, uint16 *rxoffset, uint16 *rxbufsize); -+ -+static void _dma_txblock(dma_info_t *di); -+static void _dma_txunblock(dma_info_t *di); -+static uint _dma_txactive(dma_info_t *di); -+static uint _dma_rxactive(dma_info_t *di); -+static uint _dma_activerxbuf(dma_info_t *di); -+static uint _dma_txpending(dma_info_t *di); -+static uint _dma_txcommitted(dma_info_t *di); -+ -+static void *_dma_peeknexttxp(dma_info_t *di); -+static int _dma_peekntxp(dma_info_t *di, int *len, void *txps[], txd_range_t range); -+static void *_dma_peeknextrxp(dma_info_t *di); -+static uintptr _dma_getvar(dma_info_t *di, const char *name); -+static void _dma_counterreset(dma_info_t *di); -+static void _dma_fifoloopbackenable(dma_info_t *di); -+static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags); -+static uint8 dma_align_sizetobits(uint size); -+static void *dma_ringalloc(osl_t *osh, uint32 boundary, uint size, uint16 *alignbits, uint* alloced, -+ dmaaddr_t *descpa, osldma_t **dmah); -+static int _dma_pktpool_set(dma_info_t *di, pktpool_t *pool); -+static bool _dma_rxtx_error(dma_info_t *di, bool istx); -+static void _dma_burstlen_set(dma_info_t *di, uint8 rxburstlen, uint8 txburstlen); -+static uint _dma_avoidancecnt(dma_info_t *di); -+static void _dma_param_set(dma_info_t *di, uint16 paramid, uint16 paramval); -+static bool _dma_glom_enable(dma_info_t *di, uint32 val); -+ -+ -+/* Prototypes for 32-bit routines */ -+static bool dma32_alloc(dma_info_t *di, uint direction); -+static bool dma32_txreset(dma_info_t *di); -+static bool dma32_rxreset(dma_info_t *di); -+static bool dma32_txsuspendedidle(dma_info_t *di); -+static int dma32_txfast(dma_info_t *di, void *p0, bool commit); -+static void *dma32_getnexttxp(dma_info_t *di, txd_range_t range); -+static void *dma32_getnextrxp(dma_info_t *di, bool forceall); -+static void dma32_txrotate(dma_info_t *di); -+static bool dma32_rxidle(dma_info_t *di); -+static void dma32_txinit(dma_info_t *di); -+static bool dma32_txenabled(dma_info_t *di); -+static void dma32_txsuspend(dma_info_t *di); -+static void dma32_txresume(dma_info_t *di); -+static bool dma32_txsuspended(dma_info_t *di); -+#ifdef WL_MULTIQUEUE -+static void dma32_txflush(dma_info_t *di); -+static void dma32_txflush_clear(dma_info_t *di); -+#endif /* WL_MULTIQUEUE */ -+static void dma32_txreclaim(dma_info_t *di, txd_range_t range); -+static bool dma32_txstopped(dma_info_t *di); -+static bool dma32_rxstopped(dma_info_t *di); -+static bool dma32_rxenabled(dma_info_t *di); -+#if defined(BCMDBG) -+static void dma32_dumpring(dma_info_t *di, struct bcmstrbuf *b, dma32dd_t *ring, uint start, -+ uint end, uint max_num); -+static void dma32_dump(dma_info_t *di, struct bcmstrbuf *b, bool dumpring); -+static void dma32_dumptx(dma_info_t *di, struct bcmstrbuf *b, bool dumpring); -+static void dma32_dumprx(dma_info_t *di, struct bcmstrbuf *b, bool dumpring); -+#endif -+ -+static bool _dma32_addrext(osl_t *osh, dma32regs_t *dma32regs); -+ -+/* Prototypes for 64-bit routines */ -+static bool dma64_alloc(dma_info_t *di, uint direction); -+static bool dma64_txreset(dma_info_t *di); -+static bool dma64_rxreset(dma_info_t *di); -+static bool dma64_txsuspendedidle(dma_info_t *di); -+static int dma64_txfast(dma_info_t *di, void *p0, bool commit); -+static int dma64_txunframed(dma_info_t *di, void *p0, uint len, bool commit); -+static void *dma64_getpos(dma_info_t *di, bool direction); -+static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range); -+static void *dma64_getnextrxp(dma_info_t *di, bool forceall); -+static void dma64_txrotate(dma_info_t *di); -+ -+static bool dma64_rxidle(dma_info_t *di); -+static void dma64_txinit(dma_info_t *di); -+static bool dma64_txenabled(dma_info_t *di); -+static void dma64_txsuspend(dma_info_t *di); -+static void dma64_txresume(dma_info_t *di); -+static bool dma64_txsuspended(dma_info_t *di); -+#ifdef WL_MULTIQUEUE -+static void dma64_txflush(dma_info_t *di); -+static void dma64_txflush_clear(dma_info_t *di); -+#endif /* WL_MULTIQUEUE */ -+static void dma64_txreclaim(dma_info_t *di, txd_range_t range); -+static bool dma64_txstopped(dma_info_t *di); -+static bool dma64_rxstopped(dma_info_t *di); -+static bool dma64_rxenabled(dma_info_t *di); -+static bool _dma64_addrext(osl_t *osh, dma64regs_t *dma64regs); -+static int dma64_rxunframed(dma_info_t *di, void *p0, uint len, bool commit); -+ -+STATIC INLINE uint32 parity32(uint32 data); -+ -+#if defined(BCMDBG) -+static void dma64_dumpring(dma_info_t *di, struct bcmstrbuf *b, dma64dd_t *ring, uint start, -+ uint end, uint max_num); -+static void dma64_dump(dma_info_t *di, struct bcmstrbuf *b, bool dumpring); -+static void dma64_dumptx(dma_info_t *di, struct bcmstrbuf *b, bool dumpring); -+static void dma64_dumprx(dma_info_t *di, struct bcmstrbuf *b, bool dumpring); -+#endif -+ -+ -+const di_fcn_t dma64proc = { -+ (di_detach_t)_dma_detach, -+ (di_txinit_t)dma64_txinit, -+ (di_txreset_t)dma64_txreset, -+ (di_txenabled_t)dma64_txenabled, -+ (di_txsuspend_t)dma64_txsuspend, -+ (di_txresume_t)dma64_txresume, -+ (di_txsuspended_t)dma64_txsuspended, -+ (di_txsuspendedidle_t)dma64_txsuspendedidle, -+#ifdef WL_MULTIQUEUE -+ (di_txflush_t)dma64_txflush, -+ (di_txflush_clear_t)dma64_txflush_clear, -+#endif /* WL_MULTIQUEUE */ -+ (di_txfast_t)dma64_txfast, -+ (di_txunframed_t)dma64_txunframed, -+ (di_getpos_t)dma64_getpos, -+ (di_txstopped_t)dma64_txstopped, -+ (di_txreclaim_t)dma64_txreclaim, -+ (di_getnexttxp_t)dma64_getnexttxp, -+ (di_peeknexttxp_t)_dma_peeknexttxp, -+ (di_peekntxp_t)_dma_peekntxp, -+ (di_txblock_t)_dma_txblock, -+ (di_txunblock_t)_dma_txunblock, -+ (di_txactive_t)_dma_txactive, -+ (di_txrotate_t)dma64_txrotate, -+ -+ (di_rxinit_t)_dma_rxinit, -+ (di_rxreset_t)dma64_rxreset, -+ (di_rxidle_t)dma64_rxidle, -+ (di_rxstopped_t)dma64_rxstopped, -+ (di_rxenable_t)_dma_rxenable, -+ (di_rxenabled_t)dma64_rxenabled, -+ (di_rx_t)_dma_rx, -+ (di_rxfill_t)_dma_rxfill, -+ (di_rxreclaim_t)_dma_rxreclaim, -+ (di_getnextrxp_t)_dma_getnextrxp, -+ (di_peeknextrxp_t)_dma_peeknextrxp, -+ (di_rxparam_get_t)_dma_rx_param_get, -+ -+ (di_fifoloopbackenable_t)_dma_fifoloopbackenable, -+ (di_getvar_t)_dma_getvar, -+ (di_counterreset_t)_dma_counterreset, -+ (di_ctrlflags_t)_dma_ctrlflags, -+ -+#if defined(BCMDBG) -+ (di_dump_t)dma64_dump, -+ (di_dumptx_t)dma64_dumptx, -+ (di_dumprx_t)dma64_dumprx, -+#else -+ NULL, -+ NULL, -+ NULL, -+#endif -+ (di_rxactive_t)_dma_rxactive, -+ (di_txpending_t)_dma_txpending, -+ (di_txcommitted_t)_dma_txcommitted, -+ (di_pktpool_set_t)_dma_pktpool_set, -+ (di_rxtxerror_t)_dma_rxtx_error, -+ (di_burstlen_set_t)_dma_burstlen_set, -+ (di_avoidancecnt_t)_dma_avoidancecnt, -+ (di_param_set_t)_dma_param_set, -+ (dma_glom_enable_t)_dma_glom_enable, -+ (di_rxunframed_t)dma64_rxunframed, -+ (dma_active_rxbuf_t)_dma_activerxbuf, -+ 40 -+}; -+ -+static const di_fcn_t dma32proc = { -+ (di_detach_t)_dma_detach, -+ (di_txinit_t)dma32_txinit, -+ (di_txreset_t)dma32_txreset, -+ (di_txenabled_t)dma32_txenabled, -+ (di_txsuspend_t)dma32_txsuspend, -+ (di_txresume_t)dma32_txresume, -+ (di_txsuspended_t)dma32_txsuspended, -+ (di_txsuspendedidle_t)dma32_txsuspendedidle, -+#ifdef WL_MULTIQUEUE -+ (di_txflush_t)dma32_txflush, -+ (di_txflush_clear_t)dma32_txflush_clear, -+#endif /* WL_MULTIQUEUE */ -+ (di_txfast_t)dma32_txfast, -+ NULL, -+ NULL, -+ (di_txstopped_t)dma32_txstopped, -+ (di_txreclaim_t)dma32_txreclaim, -+ (di_getnexttxp_t)dma32_getnexttxp, -+ (di_peeknexttxp_t)_dma_peeknexttxp, -+ (di_peekntxp_t)_dma_peekntxp, -+ (di_txblock_t)_dma_txblock, -+ (di_txunblock_t)_dma_txunblock, -+ (di_txactive_t)_dma_txactive, -+ (di_txrotate_t)dma32_txrotate, -+ -+ (di_rxinit_t)_dma_rxinit, -+ (di_rxreset_t)dma32_rxreset, -+ (di_rxidle_t)dma32_rxidle, -+ (di_rxstopped_t)dma32_rxstopped, -+ (di_rxenable_t)_dma_rxenable, -+ (di_rxenabled_t)dma32_rxenabled, -+ (di_rx_t)_dma_rx, -+ (di_rxfill_t)_dma_rxfill, -+ (di_rxreclaim_t)_dma_rxreclaim, -+ (di_getnextrxp_t)_dma_getnextrxp, -+ (di_peeknextrxp_t)_dma_peeknextrxp, -+ (di_rxparam_get_t)_dma_rx_param_get, -+ -+ (di_fifoloopbackenable_t)_dma_fifoloopbackenable, -+ (di_getvar_t)_dma_getvar, -+ (di_counterreset_t)_dma_counterreset, -+ (di_ctrlflags_t)_dma_ctrlflags, -+ -+#if defined(BCMDBG) -+ (di_dump_t)dma32_dump, -+ (di_dumptx_t)dma32_dumptx, -+ (di_dumprx_t)dma32_dumprx, -+#else -+ NULL, -+ NULL, -+ NULL, -+#endif -+ (di_rxactive_t)_dma_rxactive, -+ (di_txpending_t)_dma_txpending, -+ (di_txcommitted_t)_dma_txcommitted, -+ (di_pktpool_set_t)_dma_pktpool_set, -+ (di_rxtxerror_t)_dma_rxtx_error, -+ (di_burstlen_set_t)_dma_burstlen_set, -+ (di_avoidancecnt_t)_dma_avoidancecnt, -+ (di_param_set_t)_dma_param_set, -+ NULL, -+ NULL, -+ NULL, -+ 40 -+}; -+ -+EXPORT_SYMBOL(dma_attach); -+EXPORT_SYMBOL(dma64proc); -+ -+hnddma_t * -+dma_attach(osl_t *osh, const char *name, si_t *sih, -+ volatile void *dmaregstx, volatile void *dmaregsrx, -+ uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, uint nrxpost, uint rxoffset, -+ uint *msg_level) -+{ -+ dma_info_t *di; -+ uint size; -+ uint32 mask; -+ -+ /* allocate private info structure */ -+ if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) { -+#ifdef BCMDBG -+ DMA_ERROR(("%s: out of memory, malloced %d bytes\n", __FUNCTION__, MALLOCED(osh))); -+#endif -+ return (NULL); -+ } -+ -+ bzero(di, sizeof(dma_info_t)); -+ -+ di->msg_level = msg_level ? msg_level : &dma_msg_level; -+ spin_lock_init(&di->des_lock); -+ -+ /* old chips w/o sb is no longer supported */ -+ ASSERT(sih != NULL); -+ -+ if (DMA64_ENAB(di)) { -+ di->dma64 = ((si_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64); -+ } else { -+ di->dma64 = 0; -+ } -+ -+ /* check arguments */ -+ ASSERT(ISPOWEROF2(ntxd)); -+ ASSERT(ISPOWEROF2(nrxd)); -+ -+ if (nrxd == 0) { -+ ASSERT(dmaregsrx == NULL); -+ } -+ if (ntxd == 0) { -+ ASSERT(dmaregstx == NULL); -+ } -+ -+ /* init dma reg pointer */ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ di->d64txregs = (dma64regs_t *)dmaregstx; -+ di->d64rxregs = (dma64regs_t *)dmaregsrx; -+ di->hnddma.di_fn = (const di_fcn_t *)&dma64proc; -+ } else if (DMA32_ENAB(di)) { -+ ASSERT(ntxd <= D32MAXDD); -+ ASSERT(nrxd <= D32MAXDD); -+ di->d32txregs = (dma32regs_t *)dmaregstx; -+ di->d32rxregs = (dma32regs_t *)dmaregsrx; -+ di->hnddma.di_fn = (const di_fcn_t *)&dma32proc; -+ } else { -+ DMA_ERROR(("%s: driver doesn't support 32-bit DMA\n", __FUNCTION__)); -+ ASSERT(0); -+ goto fail; -+ } -+ -+ /* Default flags (which can be changed by the driver calling dma_ctrlflags -+ * before enable): For backwards compatibility both Rx Overflow Continue -+ * and Parity are DISABLED. -+ * supports it. -+ */ -+ di->hnddma.di_fn->ctrlflags(&di->hnddma, DMA_CTRL_ROC | DMA_CTRL_PEN, 0); -+ -+ DMA_TRACE(("%s: %s: %s osh %p flags 0x%x ntxd %d nrxd %d rxbufsize %d " -+ "rxextheadroom %d nrxpost %d rxoffset %d dmaregstx %p dmaregsrx %p\n", -+ name, __FUNCTION__, (DMA64_MODE(di) ? "DMA64" : "DMA32"), -+ osh, di->hnddma.dmactrlflags, ntxd, nrxd, -+ rxbufsize, rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx)); -+ -+ /* make a private copy of our callers name */ -+ strncpy(di->name, name, MAXNAMEL); -+ di->name[MAXNAMEL-1] = '\0'; -+ -+ di->osh = osh; -+ di->sih = sih; -+ -+ /* save tunables */ -+ di->ntxd = (uint16)ntxd; -+ di->nrxd = (uint16)nrxd; -+ -+ /* the actual dma size doesn't include the extra headroom */ -+ di->rxextrahdrroom = (rxextheadroom == -1) ? BCMEXTRAHDROOM : rxextheadroom; -+ if (rxbufsize > BCMEXTRAHDROOM) { -+ di->rxbufsize = (uint16)(rxbufsize - di->rxextrahdrroom); -+ } else { -+ di->rxbufsize = (uint16)rxbufsize; -+ } -+ -+ di->nrxpost = (uint16)nrxpost; -+ di->rxoffset = (uint8)rxoffset; -+ -+ /* Get the default values (POR) of the burstlen. This can be overridden by the modules -+ * if this has to be different. Otherwise this value will be used to program the control -+ * register after the reset or during the init. -+ */ -+ if (dmaregsrx) { -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ /* detect the dma descriptor address mask, -+ * should be 0x1fff before 4360B0, 0xffff start from 4360B0 -+ */ -+ W_REG(di->osh, &di->d64rxregs->addrlow, 0xffffffff); -+ mask = R_REG(di->osh, &di->d64rxregs->addrlow); -+ -+ if (mask & 0xfff) { -+ mask = R_REG(di->osh, &di->d64rxregs->ptr) | 0xf; -+ } else { -+ mask = 0x1fff; -+ } -+ -+ DMA_TRACE(("%s: dma_rx_mask: %08x\n", di->name, mask)); -+ di->d64_rs0_cd_mask = mask; -+ -+ if (mask == 0x1fff) { -+ ASSERT(nrxd <= D64MAXDD); -+ } else { -+ ASSERT(nrxd <= D64MAXDD_LARGE); -+ } -+ -+ di->rxburstlen = (R_REG(di->osh, -+ &di->d64rxregs->control) & D64_RC_BL_MASK) >> D64_RC_BL_SHIFT; -+ di->rxprefetchctl = (R_REG(di->osh, -+ &di->d64rxregs->control) & D64_RC_PC_MASK) >> D64_RC_PC_SHIFT; -+ di->rxprefetchthresh = (R_REG(di->osh, -+ &di->d64rxregs->control) & D64_RC_PT_MASK) >> D64_RC_PT_SHIFT; -+ } else if (DMA32_ENAB(di)) { -+ di->rxburstlen = (R_REG(di->osh, -+ &di->d32rxregs->control) & RC_BL_MASK) >> RC_BL_SHIFT; -+ di->rxprefetchctl = (R_REG(di->osh, -+ &di->d32rxregs->control) & RC_PC_MASK) >> RC_PC_SHIFT; -+ di->rxprefetchthresh = (R_REG(di->osh, -+ &di->d32rxregs->control) & RC_PT_MASK) >> RC_PT_SHIFT; -+ } -+ } -+ if (dmaregstx) { -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ -+ /* detect the dma descriptor address mask, -+ * should be 0x1fff before 4360B0, 0xffff start from 4360B0 -+ */ -+ W_REG(di->osh, &di->d64txregs->addrlow, 0xffffffff); -+ mask = R_REG(di->osh, &di->d64txregs->addrlow); -+ -+ if (mask & 0xfff) { -+ mask = R_REG(di->osh, &di->d64txregs->ptr) | 0xf; -+ } else { -+ mask = 0x1fff; -+ } -+ -+ DMA_TRACE(("%s: dma_tx_mask: %08x\n", di->name, mask)); -+ di->d64_xs0_cd_mask = mask; -+ di->d64_xs1_ad_mask = mask; -+ -+ if (mask == 0x1fff) { -+ ASSERT(ntxd <= D64MAXDD); -+ } else { -+ ASSERT(ntxd <= D64MAXDD_LARGE); -+ } -+ -+ di->txburstlen = (R_REG(di->osh, -+ &di->d64txregs->control) & D64_XC_BL_MASK) >> D64_XC_BL_SHIFT; -+ di->txmultioutstdrd = (R_REG(di->osh, -+ &di->d64txregs->control) & D64_XC_MR_MASK) >> D64_XC_MR_SHIFT; -+ di->txprefetchctl = (R_REG(di->osh, -+ &di->d64txregs->control) & D64_XC_PC_MASK) >> D64_XC_PC_SHIFT; -+ di->txprefetchthresh = (R_REG(di->osh, -+ &di->d64txregs->control) & D64_XC_PT_MASK) >> D64_XC_PT_SHIFT; -+ } else if (DMA32_ENAB(di)) { -+ di->txburstlen = (R_REG(di->osh, -+ &di->d32txregs->control) & XC_BL_MASK) >> XC_BL_SHIFT; -+ di->txmultioutstdrd = (R_REG(di->osh, -+ &di->d32txregs->control) & XC_MR_MASK) >> XC_MR_SHIFT; -+ di->txprefetchctl = (R_REG(di->osh, -+ &di->d32txregs->control) & XC_PC_MASK) >> XC_PC_SHIFT; -+ di->txprefetchthresh = (R_REG(di->osh, -+ &di->d32txregs->control) & XC_PT_MASK) >> XC_PT_SHIFT; -+ } -+ } -+ -+ /* force burstlen to 3 */ -+ di->rxburstlen = 3; -+ di->txburstlen = 3; -+ /* -+ * figure out the DMA physical address offset for dd and data -+ * Other bus: use zero -+ */ -+ di->ddoffsetlow = 0; -+ di->dataoffsetlow = 0; -+ -+ /* set addr ext fields */ -+ di->addrext = _dma_isaddrext(di); -+ -+ /* does the descriptors need to be aligned and if yes, on 4K/8K or not */ -+ di->aligndesc_4k = _dma_descriptor_align(di); -+ if (di->aligndesc_4k) { -+ if (DMA64_MODE(di)) { -+ di->dmadesc_align = D64RINGALIGN_BITS; -+ if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) { -+ /* for smaller dd table, HW relax the alignment requirement */ -+ di->dmadesc_align = D64RINGALIGN_BITS - 1; -+ } -+ } else { -+ di->dmadesc_align = D32RINGALIGN_BITS; -+ } -+ } else { -+ /* The start address of descriptor table should be algined to cache line size, -+ * or other structure may share a cache line with it, which can lead to memory -+ * overlapping due to cache write-back operation. In the case of MIPS 74k, the -+ * cache line size is 32 bytes. -+ */ -+#ifdef __mips__ -+ di->dmadesc_align = 5; /* 32 byte alignment */ -+#else -+ di->dmadesc_align = 4; /* 16 byte alignment */ -+#endif -+ } -+ -+ DMA_NONE(("DMA descriptor align_needed %d, align %d\n", -+ di->aligndesc_4k, di->dmadesc_align)); -+ -+ /* allocate tx packet pointer vector */ -+ if (ntxd) { -+ size = ntxd * sizeof(void *); -+ if ((di->txp = MALLOC(osh, size)) == NULL) { -+ DMA_ERROR(("%s: %s: out of tx memory, malloced %d bytes\n", -+ di->name, __FUNCTION__, MALLOCED(osh))); -+ goto fail; -+ } -+ bzero(di->txp, size); -+ } -+ -+ /* allocate rx packet pointer vector */ -+ if (nrxd) { -+ size = nrxd * sizeof(void *); -+ if ((di->rxp = MALLOC(osh, size)) == NULL) { -+ DMA_ERROR(("%s: %s: out of rx memory, malloced %d bytes\n", -+ di->name, __FUNCTION__, MALLOCED(osh))); -+ goto fail; -+ } -+ bzero(di->rxp, size); -+ } -+ -+ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ -+ if (ntxd) { -+ if (!_dma_alloc(di, DMA_TX)) { -+ goto fail; -+ } -+ } -+ -+ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ -+ if (nrxd) { -+ if (!_dma_alloc(di, DMA_RX)) { -+ goto fail; -+ } -+ } -+ -+ if ((di->ddoffsetlow != 0) && !di->addrext) { -+ if (PHYSADDRLO(di->txdpa) > SI_PCI_DMA_SZ) { -+ DMA_ERROR(("%s: %s: txdpa 0x%x: addrext not supported\n", -+ di->name, __FUNCTION__, (uint32)PHYSADDRLO(di->txdpa))); -+ goto fail; -+ } -+ if (PHYSADDRLO(di->rxdpa) > SI_PCI_DMA_SZ) { -+ DMA_ERROR(("%s: %s: rxdpa 0x%x: addrext not supported\n", -+ di->name, __FUNCTION__, (uint32)PHYSADDRLO(di->rxdpa))); -+ goto fail; -+ } -+ } -+ -+ DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " -+ "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, -+ di->dataoffsethigh, di->addrext)); -+ -+ /* allocate DMA mapping vectors */ -+ if (DMASGLIST_ENAB) { -+ if (ntxd) { -+ size = ntxd * sizeof(hnddma_seg_map_t); -+ if ((di->txp_dmah = (hnddma_seg_map_t *)MALLOC(osh, size)) == NULL) { -+ goto fail; -+ } -+ bzero(di->txp_dmah, size); -+ } -+ -+ if (nrxd) { -+ size = nrxd * sizeof(hnddma_seg_map_t); -+ if ((di->rxp_dmah = (hnddma_seg_map_t *)MALLOC(osh, size)) == NULL) { -+ goto fail; -+ } -+ bzero(di->rxp_dmah, size); -+ } -+ } -+ -+ return ((hnddma_t *)di); -+ -+fail: -+ _dma_detach(di); -+ return (NULL); -+} -+ -+/* init the tx or rx descriptor */ -+static INLINE void -+dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, dmaaddr_t pa, uint outidx, uint32 *flags, -+ uint32 bufcount) -+{ -+ /* dma32 uses 32-bit control to fit both flags and bufcounter */ -+ *flags = *flags | (bufcount & CTRL_BC_MASK); -+ -+ if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { -+ W_SM(&ddring[outidx].addr, BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow)); -+ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags)); -+ } else { -+ /* address extension */ -+ uint32 ae; -+ ASSERT(di->addrext); -+ ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; -+ PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH; -+ -+ *flags |= (ae << CTRL_AE_SHIFT); -+ W_SM(&ddring[outidx].addr, BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow)); -+ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags)); -+ } -+} -+ -+/* Check for odd number of 1's */ -+STATIC INLINE uint32 parity32(uint32 data) -+{ -+ data ^= data >> 16; -+ data ^= data >> 8; -+ data ^= data >> 4; -+ data ^= data >> 2; -+ data ^= data >> 1; -+ -+ return (data & 1); -+} -+ -+#define DMA64_DD_PARITY(dd) parity32((dd)->addrlow ^ (dd)->addrhigh ^ (dd)->ctrl1 ^ (dd)->ctrl2) -+ -+static INLINE void -+dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx, uint32 *flags, -+ uint32 bufcount) -+{ -+ uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK; -+ -+ /* PCI bus with big(>1G) physical address, use address extension */ -+#if defined(__mips__) && defined(IL_BIGENDIAN) -+ if ((di->dataoffsetlow == SI_SDRAM_SWAPPED) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { -+#else -+ if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { -+#endif /* defined(__mips__) && defined(IL_BIGENDIAN) */ -+ ASSERT((PHYSADDRHI(pa) & PCI64ADDR_HIGH) == 0); -+ -+ W_SM(&ddring[outidx].addrlow, BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow)); -+ W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(PHYSADDRHI(pa) + di->dataoffsethigh)); -+ W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); -+ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); -+ } else { -+ /* address extension for 32-bit PCI */ -+ uint32 ae; -+ ASSERT(di->addrext); -+ -+ ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; -+ PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH; -+ ASSERT(PHYSADDRHI(pa) == 0); -+ -+ ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE; -+ W_SM(&ddring[outidx].addrlow, BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow)); -+ W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(0 + di->dataoffsethigh)); -+ W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); -+ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); -+ } -+ if (di->hnddma.dmactrlflags & DMA_CTRL_PEN) { -+ if (DMA64_DD_PARITY(&ddring[outidx])) { -+ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2 | D64_CTRL2_PARITY)); -+ } -+ } -+ -+#ifndef CONFIG_BCM_IPROC_GMAC_ACP -+/* Test */ -+#if defined(__arm__) -+ OSL_CACHE_FLUSH((uint)OSL_CACHED(&ddring[outidx]), sizeof(dma64dd_t)); -+#endif -+#endif /* ! CONFIG_BCM_IPROC_GMAC_ACP */ -+} -+ -+static bool -+_dma32_addrext(osl_t *osh, dma32regs_t *dma32regs) -+{ -+ uint32 w; -+ -+ OR_REG(osh, &dma32regs->control, XC_AE); -+ w = R_REG(osh, &dma32regs->control); -+ AND_REG(osh, &dma32regs->control, ~XC_AE); -+ return ((w & XC_AE) == XC_AE); -+} -+ -+static bool -+_dma_alloc(dma_info_t *di, uint direction) -+{ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ return dma64_alloc(di, direction); -+ } else if (DMA32_ENAB(di)) { -+ return dma32_alloc(di, direction); -+ } else { -+ ASSERT(0); -+ } -+} -+ -+/* !! may be called with core in reset */ -+static void -+_dma_detach(dma_info_t *di) -+{ -+ -+ DMA_TRACE(("%s: dma_detach\n", di->name)); -+ -+ /* shouldn't be here if descriptors are unreclaimed */ -+ ASSERT(di->txin == di->txout); -+ ASSERT(di->rxin == di->rxout); -+ -+ /* free dma descriptor rings */ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ if (di->txd64) { -+ DMA_FREE_CONSISTENT(di->osh, ((int8 *)(uintptr)di->txd64 - di->txdalign), -+ di->txdalloc, (di->txdpaorig), &di->tx_dmah); -+ } -+ if (di->rxd64) { -+ DMA_FREE_CONSISTENT(di->osh, ((int8 *)(uintptr)di->rxd64 - di->rxdalign), -+ di->rxdalloc, (di->rxdpaorig), &di->rx_dmah); -+ } -+ } else if (DMA32_ENAB(di)) { -+ if (di->txd32) { -+ DMA_FREE_CONSISTENT(di->osh, ((int8 *)(uintptr)di->txd32 - di->txdalign), -+ di->txdalloc, (di->txdpaorig), &di->tx_dmah); -+ } -+ if (di->rxd32) { -+ DMA_FREE_CONSISTENT(di->osh, ((int8 *)(uintptr)di->rxd32 - di->rxdalign), -+ di->rxdalloc, (di->rxdpaorig), &di->rx_dmah); -+ } -+ } else -+ ASSERT(0); -+ -+ /* free packet pointer vectors */ -+ if (di->txp) { -+ MFREE(di->osh, (void *)di->txp, (di->ntxd * sizeof(void *))); -+ } -+ if (di->rxp) { -+ MFREE(di->osh, (void *)di->rxp, (di->nrxd * sizeof(void *))); -+ } -+ -+ /* free tx packet DMA handles */ -+ if (di->txp_dmah) { -+ MFREE(di->osh, (void *)di->txp_dmah, di->ntxd * sizeof(hnddma_seg_map_t)); -+ } -+ -+ /* free rx packet DMA handles */ -+ if (di->rxp_dmah) { -+ MFREE(di->osh, (void *)di->rxp_dmah, di->nrxd * sizeof(hnddma_seg_map_t)); -+ } -+ -+ /* free our private info structure */ -+ MFREE(di->osh, (void *)di, sizeof(dma_info_t)); -+ -+} -+ -+static bool -+_dma_descriptor_align(dma_info_t *di) -+{ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ uint32 addrl; -+ -+ /* Check to see if the descriptors need to be aligned on 4K/8K or not */ -+ if (di->d64txregs != NULL) { -+ W_REG(di->osh, &di->d64txregs->addrlow, 0xff0); -+ addrl = R_REG(di->osh, &di->d64txregs->addrlow); -+ if (addrl != 0) { -+ return FALSE; -+ } -+ } else if (di->d64rxregs != NULL) { -+ W_REG(di->osh, &di->d64rxregs->addrlow, 0xff0); -+ addrl = R_REG(di->osh, &di->d64rxregs->addrlow); -+ if (addrl != 0) { -+ return FALSE; -+ } -+ } -+ } -+ return TRUE; -+} -+ -+/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */ -+static bool -+_dma_isaddrext(dma_info_t *di) -+{ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ /* DMA64 supports full 32- or 64-bit operation. AE is always valid */ -+ -+ /* not all tx or rx channel are available */ -+ if (di->d64txregs != NULL) { -+ if (!_dma64_addrext(di->osh, di->d64txregs)) { -+ DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have AE set\n", -+ di->name)); -+ ASSERT(0); -+ } -+ return TRUE; -+ } else if (di->d64rxregs != NULL) { -+ if (!_dma64_addrext(di->osh, di->d64rxregs)) { -+ DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have AE set\n", -+ di->name)); -+ ASSERT(0); -+ } -+ return TRUE; -+ } -+ return FALSE; -+ } else if (DMA32_ENAB(di)) { -+ if (di->d32txregs) { -+ return (_dma32_addrext(di->osh, di->d32txregs)); -+ } else if (di->d32rxregs) { -+ return (_dma32_addrext(di->osh, di->d32rxregs)); -+ } -+ } else { -+ ASSERT(0); -+ } -+ -+ return FALSE; -+} -+ -+/* initialize descriptor table base address */ -+static void -+_dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa) -+{ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ if (!di->aligndesc_4k) { -+ if (direction == DMA_TX) { -+ di->xmtptrbase = PHYSADDRLO(pa); -+ } else { -+ di->rcvptrbase = PHYSADDRLO(pa); -+ } -+ } -+ -+ if ((di->ddoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { -+ if (direction == DMA_TX) { -+ W_REG(di->osh, &di->d64txregs->addrlow, (PHYSADDRLO(pa) + -+ di->ddoffsetlow)); -+ W_REG(di->osh, &di->d64txregs->addrhigh, (PHYSADDRHI(pa) + -+ di->ddoffsethigh)); -+ } else { -+ W_REG(di->osh, &di->d64rxregs->addrlow, (PHYSADDRLO(pa) + -+ di->ddoffsetlow)); -+ W_REG(di->osh, &di->d64rxregs->addrhigh, (PHYSADDRHI(pa) + -+ di->ddoffsethigh)); -+ } -+ } else { -+ /* DMA64 32bits address extension */ -+ uint32 ae; -+ ASSERT(di->addrext); -+ ASSERT(PHYSADDRHI(pa) == 0); -+ -+ /* shift the high bit(s) from pa to ae */ -+ ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; -+ PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH; -+ -+ if (direction == DMA_TX) { -+ W_REG(di->osh, &di->d64txregs->addrlow, (PHYSADDRLO(pa) + -+ di->ddoffsetlow)); -+ W_REG(di->osh, &di->d64txregs->addrhigh, di->ddoffsethigh); -+ SET_REG(di->osh, &di->d64txregs->control, D64_XC_AE, -+ (ae << D64_XC_AE_SHIFT)); -+ } else { -+ W_REG(di->osh, &di->d64rxregs->addrlow, (PHYSADDRLO(pa) + -+ di->ddoffsetlow)); -+ W_REG(di->osh, &di->d64rxregs->addrhigh, di->ddoffsethigh); -+ SET_REG(di->osh, &di->d64rxregs->control, D64_RC_AE, -+ (ae << D64_RC_AE_SHIFT)); -+ } -+ } -+ -+ } else if (DMA32_ENAB(di)) { -+ ASSERT(PHYSADDRHI(pa) == 0); -+ if ((di->ddoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { -+ if (direction == DMA_TX) { -+ W_REG(di->osh, &di->d32txregs->addr, (PHYSADDRLO(pa) + -+ di->ddoffsetlow)); -+ } else { -+ W_REG(di->osh, &di->d32rxregs->addr, (PHYSADDRLO(pa) + -+ di->ddoffsetlow)); -+ } -+ } else { -+ /* dma32 address extension */ -+ uint32 ae; -+ ASSERT(di->addrext); -+ -+ /* shift the high bit(s) from pa to ae */ -+ ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; -+ PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH; -+ -+ if (direction == DMA_TX) { -+ W_REG(di->osh, &di->d32txregs->addr, (PHYSADDRLO(pa) + -+ di->ddoffsetlow)); -+ SET_REG(di->osh, &di->d32txregs->control, XC_AE, ae <osh, &di->d32rxregs->addr, (PHYSADDRLO(pa) + -+ di->ddoffsetlow)); -+ SET_REG(di->osh, &di->d32rxregs->control, RC_AE, ae <name)); -+ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ OR_REG(di->osh, &di->d64txregs->control, D64_XC_LE); -+ } else if (DMA32_ENAB(di)) { -+ OR_REG(di->osh, &di->d32txregs->control, XC_LE); -+ } else { -+ ASSERT(0); -+ } -+} -+ -+static void -+_dma_rxinit(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_rxinit\n", di->name)); -+ -+ if (di->nrxd == 0) { -+ return; -+ } -+ -+ /* During the reset procedure, the active rxd may not be zero if pktpool is -+ * enabled, we need to reclaim active rxd to avoid rxd being leaked. -+ */ -+ if ((POOL_ENAB(di->pktpool)) && (NRXDACTIVE(di->rxin, di->rxout))) { -+ _dma_rxreclaim(di); -+ } -+ -+ ASSERT(di->rxin == di->rxout); -+ di->rxin = di->rxout = di->rs0cd = 0; -+ -+ /* clear rx descriptor ring */ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ BZERO_SM((void *)(uintptr)di->rxd64, (di->nrxd * sizeof(dma64dd_t))); -+ -+ /* DMA engine with out alignment requirement requires table to be inited -+ * before enabling the engine -+ */ -+ if (!di->aligndesc_4k) { -+ _dma_ddtable_init(di, DMA_RX, di->rxdpa); -+ } -+ -+ _dma_rxenable(di); -+ -+ if (di->aligndesc_4k) { -+ _dma_ddtable_init(di, DMA_RX, di->rxdpa); -+ } -+ } else if (DMA32_ENAB(di)) { -+ BZERO_SM((void *)(uintptr)di->rxd32, (di->nrxd * sizeof(dma32dd_t))); -+ _dma_rxenable(di); -+ _dma_ddtable_init(di, DMA_RX, di->rxdpa); -+ } else { -+ ASSERT(0); -+ } -+} -+ -+static void -+_dma_rxenable(dma_info_t *di) -+{ -+ uint dmactrlflags = di->hnddma.dmactrlflags; -+ -+ DMA_TRACE(("%s: dma_rxenable\n", di->name)); -+ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ uint32 control = (R_REG(di->osh, &di->d64rxregs->control) & D64_RC_AE) | D64_RC_RE; -+ -+ if ((dmactrlflags & DMA_CTRL_PEN) == 0) { -+ control |= D64_RC_PD; -+ } -+ -+ if (dmactrlflags & DMA_CTRL_ROC) { -+ control |= D64_RC_OC; -+ } -+ -+ /* These bits 20:18 (burstLen) of control register can be written but will take -+ * effect only if these bits are valid. So this will not affect previous versions -+ * of the DMA. They will continue to have those bits set to 0. -+ */ -+ control &= ~D64_RC_BL_MASK; -+ control |= (di->rxburstlen << D64_RC_BL_SHIFT); -+ -+ control &= ~D64_RC_PC_MASK; -+ control |= (di->rxprefetchctl << D64_RC_PC_SHIFT); -+ -+ control &= ~D64_RC_PT_MASK; -+ control |= (di->rxprefetchthresh << D64_RC_PT_SHIFT); -+ -+ W_REG(di->osh, &di->d64rxregs->control, -+ ((di->rxoffset << D64_RC_RO_SHIFT) | control)); -+ } else if (DMA32_ENAB(di)) { -+ uint32 control = (R_REG(di->osh, &di->d32rxregs->control) & RC_AE) | RC_RE; -+ -+ if ((dmactrlflags & DMA_CTRL_PEN) == 0) { -+ control |= RC_PD; -+ } -+ -+ if (dmactrlflags & DMA_CTRL_ROC) { -+ control |= RC_OC; -+ } -+ -+ /* These bits 20:18 (burstLen) of control register can be written but will take -+ * effect only if these bits are valid. So this will not affect previous versions -+ * of the DMA. They will continue to have those bits set to 0. -+ */ -+ control &= ~RC_BL_MASK; -+ control |= (di->rxburstlen << RC_BL_SHIFT); -+ -+ control &= ~RC_PC_MASK; -+ control |= (di->rxprefetchctl << RC_PC_SHIFT); -+ -+ control &= ~RC_PT_MASK; -+ control |= (di->rxprefetchthresh << RC_PT_SHIFT); -+ -+ W_REG(di->osh, &di->d32rxregs->control, -+ ((di->rxoffset << RC_RO_SHIFT) | control)); -+ } else { -+ ASSERT(0); -+ } -+} -+ -+static void -+_dma_rx_param_get(dma_info_t *di, uint16 *rxoffset, uint16 *rxbufsize) -+{ -+ /* the normal values fit into 16 bits */ -+ *rxoffset = (uint16)di->rxoffset; -+ *rxbufsize = (uint16)di->rxbufsize; -+} -+ -+/* !! rx entry routine -+ * returns a pointer to the next frame received, or NULL if there are no more -+ * if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is supported -+ * with pkts chain -+ * otherwise, it's treated as giant pkt and will be tossed. -+ * The DMA scattering starts with normal DMA header, followed by first buffer data. -+ * After it reaches the max size of buffer, the data continues in next DMA descriptor -+ * buffer WITHOUT DMA header -+ */ -+static void * BCMFASTPATH -+_dma_rx(dma_info_t *di) -+{ -+ void *p, *head, *tail; -+ uint len; -+ uint pkt_len; -+ int resid = 0; -+#ifdef BCM4335 -+ dma64regs_t *dregs = di->d64rxregs; -+#endif -+ -+next_frame: -+ head = _dma_getnextrxp(di, FALSE); -+ if (head == NULL) { -+ return (NULL); -+ } -+ -+ len = ltoh16(*(uint16 *)(PKTDATA(di->osh, head))); -+ DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); -+ -+ /* set actual length */ -+ pkt_len = MIN((di->rxoffset + len), di->rxbufsize); -+ PKTSETLEN(di->osh, head, pkt_len); -+ resid = len - (di->rxbufsize - di->rxoffset); -+ -+ /* check for single or multi-buffer rx */ -+ if (resid <= 0) { -+ /* Single frame, all good */ -+ } else if (di->hnddma.dmactrlflags & DMA_CTRL_RXSINGLE) { -+ DMA_TRACE(("%s: dma_rx: corrupted length (%d)\n", di->name, len)); -+ PKTFREE(di->osh, head, FALSE); -+ di->hnddma.rxgiants++; -+ goto next_frame; -+ } else { -+ /* multi-buffer rx */ -+#ifdef BCMDBG -+ p = NULL; /* get rid of compiler warning */ -+#endif /* BCMDBG */ -+ tail = head; -+ while ((resid > 0) && (p = _dma_getnextrxp(di, FALSE))) { -+ PKTSETNEXT(di->osh, tail, p); -+ pkt_len = MIN(resid, (int)di->rxbufsize); -+ PKTSETLEN(di->osh, p, pkt_len); -+ -+ tail = p; -+ resid -= di->rxbufsize; -+ } -+ -+#ifdef BCMDBG -+ if (resid > 0) { -+ uint16 cur; -+ ASSERT(p == NULL); -+ cur = (DMA64_ENAB(di) && DMA64_MODE(di)) ? -+ B2I(((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) - -+ di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t) : -+ B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK, -+ dma32dd_t); -+ DMA_ERROR(("_dma_rx, rxin %d rxout %d, hw_curr %d\n", -+ di->rxin, di->rxout, cur)); -+ } -+#endif /* BCMDBG */ -+ -+ if ((di->hnddma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { -+ DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); -+ PKTFREE(di->osh, head, FALSE); -+ di->hnddma.rxgiants++; -+ goto next_frame; -+ } -+ } -+ -+ return (head); -+} -+ -+/* post receive buffers -+ * return FALSE is refill failed completely and ring is empty -+ * this will stall the rx dma and user might want to call rxfill again asap -+ * This unlikely happens on memory-rich NIC, but often on memory-constrained dongle -+ */ -+static bool BCMFASTPATH -+_dma_rxfill(dma_info_t *di) -+{ -+ void *p; -+ uint16 rxin, rxout; -+ uint32 flags = 0; -+ uint n; -+ uint i; -+ dmaaddr_t pa; -+ uint extra_offset = 0, extra_pad; -+ bool ring_empty; -+ uint alignment_req = (di->hnddma.dmactrlflags & DMA_CTRL_USB_BOUNDRY4KB_WAR) ? -+ 16 : 1; /* MUST BE POWER of 2 */ -+ -+ ring_empty = FALSE; -+ -+ /* -+ * Determine how many receive buffers we're lacking -+ * from the full complement, allocate, initialize, -+ * and post them, then update the chip rx lastdscr. -+ */ -+ -+ rxin = di->rxin; -+ rxout = di->rxout; -+ -+ n = di->nrxpost - NRXDACTIVE(rxin, rxout); -+ -+ if (di->rxbufsize > BCMEXTRAHDROOM) { -+ extra_offset = di->rxextrahdrroom; -+ } -+ -+ DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); -+ -+ for (i = 0; i < n; i++) { -+ /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the -+ size to be allocated -+ */ -+ if (POOL_ENAB(di->pktpool)) { -+ ASSERT(di->pktpool); -+ p = pktpool_get(di->pktpool); -+#ifdef BCMDBG_POOL -+ if (p) { -+ PKTPOOLSETSTATE(p, POOL_RXFILL); -+ } -+#endif /* BCMDBG_POOL */ -+ } -+ else { -+ p = PKTGET(di->osh, (di->rxbufsize + extra_offset + alignment_req - 1), FALSE); -+ } -+ if (p == NULL) { -+ DMA_TRACE(("%s: dma_rxfill: out of rxbufs\n", di->name)); -+ if (i == 0) { -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ if (dma64_rxidle(di)) { -+ DMA_TRACE(("%s: rxfill64: ring is empty !\n", di->name)); -+ ring_empty = TRUE; -+ } -+ } else if (DMA32_ENAB(di)) { -+ if (dma32_rxidle(di)) { -+ DMA_TRACE(("%s: rxfill32: ring is empty !\n", di->name)); -+ ring_empty = TRUE; -+ } -+ } else { -+ ASSERT(0); -+ } -+ } -+ di->hnddma.rxnobuf++; -+ break; -+ } -+ /* reserve an extra headroom, if applicable */ -+ if (di->hnddma.dmactrlflags & DMA_CTRL_USB_BOUNDRY4KB_WAR) { -+ extra_pad = ((alignment_req - (uint)(((unsigned long)PKTDATA(di->osh, p) - -+ (unsigned long)(uchar *)0))) & (alignment_req - 1)); -+ } else { -+ extra_pad = 0; -+ } -+ -+ if (extra_offset + extra_pad) { -+ PKTPULL(di->osh, p, extra_offset + extra_pad); -+ } -+ -+ /* Do a cached write instead of uncached write since DMA_MAP -+ * will flush the cache. -+ */ -+ *(uint16 *)(PKTDATA(di->osh, p)) = 0; -+ -+ if (DMASGLIST_ENAB) { -+ bzero(&di->rxp_dmah[rxout], sizeof(hnddma_seg_map_t)); -+ } -+ -+#if defined(CONFIG_BCM_IPROC_GMAC_ACP) && !defined(BCMDMASGLISTOSL) -+ pa = virt_to_phys(PKTDATA(di->osh, p)); -+#else -+ pa = DMA_MAP(di->osh, PKTDATA(di->osh, p), -+ di->rxbufsize, DMA_RX, p, -+ &di->rxp_dmah[rxout]); -+#endif /* defined(CONFIG_BCM_IPROC_GMAC_ACP) && !defined(BCMDMASGLISTOSL) */ -+ -+ ASSERT(ISALIGNED(PHYSADDRLO(pa), 4)); -+ -+ /* save the free packet pointer */ -+ ASSERT(di->rxp[rxout] == NULL); -+ di->rxp[rxout] = p; -+ -+ /* reset flags for each descriptor */ -+ flags = 0; -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ if (rxout == (di->nrxd - 1)) { -+ flags = D64_CTRL1_EOT; -+ } -+ -+ dma64_dd_upd(di, di->rxd64, pa, rxout, &flags, di->rxbufsize); -+ } else if (DMA32_ENAB(di)) { -+ if (rxout == (di->nrxd - 1)) { -+ flags = CTRL_EOT; -+ } -+ -+ ASSERT(PHYSADDRHI(pa) == 0); -+ dma32_dd_upd(di, di->rxd32, pa, rxout, &flags, di->rxbufsize); -+ } else { -+ ASSERT(0); -+ } -+ rxout = NEXTRXD(rxout); -+ } -+ -+ di->rxout = rxout; -+ -+ /* update the chip lastdscr pointer */ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ W_REG(di->osh, &di->d64rxregs->ptr, di->rcvptrbase + I2B(rxout, dma64dd_t)); -+ } else if (DMA32_ENAB(di)) { -+ W_REG(di->osh, &di->d32rxregs->ptr, I2B(rxout, dma32dd_t)); -+ } else { -+ ASSERT(0); -+ } -+ -+ return ring_empty; -+} -+ -+/* like getnexttxp but no reclaim */ -+static void * -+_dma_peeknexttxp(dma_info_t *di) -+{ -+ uint16 end, i; -+ -+ if (di->ntxd == 0) { -+ return (NULL); -+ } -+ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ end = (uint16)B2I(((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK) - -+ di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t); -+ di->xs0cd = end; -+ } else if (DMA32_ENAB(di)) { -+ end = (uint16)B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t); -+ di->xs0cd = end; -+ } else { -+ ASSERT(0); -+ } -+ -+ for (i = di->txin; i != end; i = NEXTTXD(i)) { -+ if (di->txp[i]) { -+ return (di->txp[i]); -+ } -+ } -+ -+ return (NULL); -+} -+ -+int -+_dma_peekntxp(dma_info_t *di, int *len, void *txps[], txd_range_t range) -+{ -+ uint16 start, end, i; -+ uint act; -+ void *txp = NULL; -+ int k, len_max; -+ -+ DMA_TRACE(("%s: dma_peekntxp\n", di->name)); -+ -+ ASSERT(len); -+ ASSERT(txps); -+ ASSERT(di); -+ if (di->ntxd == 0) { -+ *len = 0; -+ return BCME_ERROR; -+ } -+ -+ len_max = *len; -+ *len = 0; -+ -+ start = di->txin; -+ -+ if (range == HNDDMA_RANGE_ALL) { -+ end = di->txout; -+ } else { -+ if (DMA64_ENAB(di)) { -+ end = B2I(((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK) - -+ di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t); -+ -+ act = (uint)(R_REG(di->osh, &di->d64txregs->status1) & D64_XS1_AD_MASK); -+ act = (act - di->xmtptrbase) & D64_XS0_CD_MASK; -+ act = (uint)B2I(act, dma64dd_t); -+ } else { -+ end = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t); -+ -+ act = (uint)((R_REG(di->osh, &di->d32txregs->status) & XS_AD_MASK) >> -+ XS_AD_SHIFT); -+ act = (uint)B2I(act, dma32dd_t); -+ } -+ -+ di->xs0cd = end; -+ if (end != act) { -+ end = PREVTXD(act); -+ } -+ } -+ -+ if ((start == 0) && (end > di->txout)) { -+ return BCME_ERROR; -+ } -+ -+ k = 0; -+ for (i = start; i != end; i = NEXTTXD(i)) { -+ txp = di->txp[i]; -+ if (txp != NULL) { -+ if (k < len_max) { -+ txps[k++] = txp; -+ } else { -+ break; -+ } -+ } -+ } -+ *len = k; -+ -+ return BCME_OK; -+} -+ -+/* like getnextrxp but not take off the ring */ -+static void * -+_dma_peeknextrxp(dma_info_t *di) -+{ -+ uint16 end, i; -+ -+ if (di->nrxd == 0) { -+ return (NULL); -+ } -+ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ end = (uint16)B2I(((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) - -+ di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t); -+ di->rs0cd = end; -+ } else if (DMA32_ENAB(di)) { -+ end = (uint16)B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK, dma32dd_t); -+ di->rs0cd = end; -+ } else { -+ ASSERT(0); -+ } -+ -+ for (i = di->rxin; i != end; i = NEXTRXD(i)) { -+ if (di->rxp[i]) { -+ return (di->rxp[i]); -+ } -+ } -+ -+ return (NULL); -+} -+ -+static void -+_dma_rxreclaim(dma_info_t *di) -+{ -+ void *p; -+ bool origcb = TRUE; -+ -+#ifndef EFI -+ /* "unused local" warning suppression for OSLs that -+ * define PKTFREE() without using the di->osh arg -+ */ -+ di = di; -+#endif /* EFI */ -+ -+ DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); -+ -+ if (POOL_ENAB(di->pktpool) && -+ ((origcb = pktpool_emptycb_disabled(di->pktpool)) == FALSE)) { -+ pktpool_emptycb_disable(di->pktpool, TRUE); -+ } -+ -+ while ((p = _dma_getnextrxp(di, TRUE))) { -+ PKTFREE(di->osh, p, FALSE); -+ } -+ -+ if (origcb == FALSE) { -+ pktpool_emptycb_disable(di->pktpool, FALSE); -+ } -+} -+ -+static void * BCMFASTPATH -+_dma_getnextrxp(dma_info_t *di, bool forceall) -+{ -+ if (di->nrxd == 0) { -+ return (NULL); -+ } -+ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ return dma64_getnextrxp(di, forceall); -+ } else if (DMA32_ENAB(di)) { -+ return dma32_getnextrxp(di, forceall); -+ } else { -+ ASSERT(0); -+ } -+} -+ -+static void -+_dma_txblock(dma_info_t *di) -+{ -+ di->hnddma.txavail = 0; -+} -+ -+static void -+_dma_txunblock(dma_info_t *di) -+{ -+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+} -+ -+static uint -+_dma_txactive(dma_info_t *di) -+{ -+ return NTXDACTIVE(di->txin, di->txout); -+} -+ -+static uint -+_dma_txpending(dma_info_t *di) -+{ -+ uint16 curr; -+ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ curr = B2I(((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK) - -+ di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t); -+ di->xs0cd = curr; -+ } else if (DMA32_ENAB(di)) { -+ curr = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t); -+ di->xs0cd = curr; -+ } else { -+ ASSERT(0); -+ } -+ -+ return NTXDACTIVE(curr, di->txout); -+} -+ -+static uint -+_dma_txcommitted(dma_info_t *di) -+{ -+ uint16 ptr; -+ uint txin = di->txin; -+ -+ if (txin == di->txout) { -+ return 0; -+ } -+ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ ptr = B2I(R_REG(di->osh, &di->d64txregs->ptr), dma64dd_t); -+ } else if (DMA32_ENAB(di)) { -+ ptr = B2I(R_REG(di->osh, &di->d32txregs->ptr), dma32dd_t); -+ } else { -+ ASSERT(0); -+ } -+ -+ return NTXDACTIVE(di->txin, ptr); -+} -+ -+static uint -+_dma_rxactive(dma_info_t *di) -+{ -+ return NRXDACTIVE(di->rxin, di->rxout); -+} -+ -+static uint -+_dma_activerxbuf(dma_info_t *di) -+{ -+ uint16 curr, ptr; -+ curr = B2I(((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) - -+ di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t); -+ ptr = B2I(((R_REG(di->osh, &di->d64rxregs->ptr) & D64_RS0_CD_MASK) - -+ di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t); -+ return NRXDACTIVE(curr, ptr); -+} -+ -+ -+static void -+_dma_counterreset(dma_info_t *di) -+{ -+ /* reset all software counter */ -+ di->hnddma.rxgiants = 0; -+ di->hnddma.rxnobuf = 0; -+ di->hnddma.txnobuf = 0; -+} -+ -+static uint -+_dma_ctrlflags(dma_info_t *di, uint mask, uint flags) -+{ -+ uint dmactrlflags; -+ -+ if (!di) { -+ DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n")); -+ return (0); -+ } -+ -+ dmactrlflags = di->hnddma.dmactrlflags; -+ ASSERT((flags & ~mask) == 0); -+ -+ dmactrlflags &= ~mask; -+ dmactrlflags |= flags; -+ -+ /* If trying to enable parity, check if parity is actually supported */ -+ if (dmactrlflags & DMA_CTRL_PEN) { -+ uint32 control; -+ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ control = R_REG(di->osh, &di->d64txregs->control); -+ W_REG(di->osh, &di->d64txregs->control, control | D64_XC_PD); -+ if (R_REG(di->osh, &di->d64txregs->control) & D64_XC_PD) { -+ /* We *can* disable it so it is supported, -+ * restore control register -+ */ -+ W_REG(di->osh, &di->d64txregs->control, control); -+ } else { -+ /* Not supported, don't allow it to be enabled */ -+ dmactrlflags &= ~DMA_CTRL_PEN; -+ } -+ } else if (DMA32_ENAB(di)) { -+ control = R_REG(di->osh, &di->d32txregs->control); -+ W_REG(di->osh, &di->d32txregs->control, control | XC_PD); -+ if (R_REG(di->osh, &di->d32txregs->control) & XC_PD) { -+ W_REG(di->osh, &di->d32txregs->control, control); -+ } else { -+ /* Not supported, don't allow it to be enabled */ -+ dmactrlflags &= ~DMA_CTRL_PEN; -+ } -+ } else { -+ ASSERT(0); -+ } -+ } -+ -+ di->hnddma.dmactrlflags = dmactrlflags; -+ -+ return (dmactrlflags); -+} -+ -+/* get the address of the var in order to change later */ -+static uintptr -+_dma_getvar(dma_info_t *di, const char *name) -+{ -+ if (!strcmp(name, "&txavail")) { -+ return ((uintptr) &(di->hnddma.txavail)); -+ } else { -+ ASSERT(0); -+ } -+ return (0); -+} -+ -+static uint -+_dma_avoidancecnt(dma_info_t *di) -+{ -+ return (di->dma_avoidance_cnt); -+} -+ -+void -+dma_txpioloopback(osl_t *osh, dma32regs_t *regs) -+{ -+ OR_REG(osh, ®s->control, XC_LE); -+} -+ -+static -+uint8 dma_align_sizetobits(uint size) -+{ -+ uint8 bitpos = 0; -+ ASSERT(size); -+ ASSERT(!(size & (size-1))); -+ while (size >>= 1) { -+ bitpos ++; -+ } -+ return (bitpos); -+} -+ -+/* This function ensures that the DMA descriptor ring will not get allocated -+ * across Page boundary. If the allocation is done across the page boundary -+ * at the first time, then it is freed and the allocation is done at -+ * descriptor ring size aligned location. This will ensure that the ring will -+ * not cross page boundary -+ */ -+static void * -+dma_ringalloc(osl_t *osh, uint32 boundary, uint size, uint16 *alignbits, uint* alloced, -+ dmaaddr_t *descpa, osldma_t **dmah) -+{ -+ void * va; -+ uint32 desc_strtaddr; -+ uint32 alignbytes = 1 << *alignbits; -+ -+ if ((va = DMA_ALLOC_CONSISTENT(osh, size, *alignbits, alloced, descpa, dmah)) == NULL) { -+ return NULL; -+ } -+ -+ /* printk("%s va(0x%x)\n", __FUNCTION__, va); */ -+ desc_strtaddr = (uint32)ROUNDUP((uint)PHYSADDRLO(*descpa), alignbytes); -+ if (((desc_strtaddr + size - 1) & boundary) != -+ (desc_strtaddr & boundary)) { -+ *alignbits = dma_align_sizetobits(size); -+ DMA_FREE_CONSISTENT(osh, va, -+ size, *descpa, dmah); -+ va = DMA_ALLOC_CONSISTENT(osh, size, *alignbits, alloced, descpa, dmah); -+ } -+ return va; -+} -+ -+#if defined(BCMDBG) -+static void -+dma32_dumpring(dma_info_t *di, struct bcmstrbuf *b, dma32dd_t *ring, uint start, uint end, -+ uint max_num) -+{ -+ uint i; -+ -+ for (i = start; i != end; i = XXD((i + 1), max_num)) { -+ /* in the format of high->low 8 bytes */ -+ bcm_bprintf(b, "ring index %d: 0x%x %x\n", -+ i, R_SM(&ring[i].addr), R_SM(&ring[i].ctrl)); -+ } -+} -+ -+static void -+dma32_dumptx(dma_info_t *di, struct bcmstrbuf *b, bool dumpring) -+{ -+ if (di->ntxd == 0) { -+ return; -+ } -+ -+ bcm_bprintf(b, "DMA32: txd32 %p txdpa 0x%lx txp %p txin %d txout %d " -+ "txavail %d txnodesc %d\n", di->txd32, PHYSADDRLO(di->txdpa), di->txp, di->txin, -+ di->txout, di->hnddma.txavail, di->hnddma.txnodesc); -+ -+ bcm_bprintf(b, "xmtcontrol 0x%x xmtaddr 0x%x xmtptr 0x%x xmtstatus 0x%x\n", -+ R_REG(di->osh, &di->d32txregs->control), -+ R_REG(di->osh, &di->d32txregs->addr), -+ R_REG(di->osh, &di->d32txregs->ptr), -+ R_REG(di->osh, &di->d32txregs->status)); -+ -+ if (dumpring && di->txd32) { -+ dma32_dumpring(di, b, di->txd32, di->txin, di->txout, di->ntxd); -+ } -+} -+ -+static void -+dma32_dumprx(dma_info_t *di, struct bcmstrbuf *b, bool dumpring) -+{ -+ if (di->nrxd == 0) { -+ return; -+ } -+ -+ bcm_bprintf(b, "DMA32: rxd32 %p rxdpa 0x%lx rxp %p rxin %d rxout %d\n", -+ di->rxd32, PHYSADDRLO(di->rxdpa), di->rxp, di->rxin, di->rxout); -+ -+ bcm_bprintf(b, "rcvcontrol 0x%x rcvaddr 0x%x rcvptr 0x%x rcvstatus 0x%x\n", -+ R_REG(di->osh, &di->d32rxregs->control), -+ R_REG(di->osh, &di->d32rxregs->addr), -+ R_REG(di->osh, &di->d32rxregs->ptr), -+ R_REG(di->osh, &di->d32rxregs->status)); -+ if (di->rxd32 && dumpring) { -+ dma32_dumpring(di, b, di->rxd32, di->rxin, di->rxout, di->nrxd); -+ } -+} -+ -+static void -+dma32_dump(dma_info_t *di, struct bcmstrbuf *b, bool dumpring) -+{ -+ dma32_dumptx(di, b, dumpring); -+ dma32_dumprx(di, b, dumpring); -+} -+ -+static void -+dma64_dumpring(dma_info_t *di, struct bcmstrbuf *b, dma64dd_t *ring, uint start, uint end, -+ uint max_num) -+{ -+ uint i; -+ -+ for (i = start; i != end; i = XXD((i + 1), max_num)) { -+ /* in the format of high->low 16 bytes */ -+ bcm_bprintf(b, "ring index %d: 0x%x %x %x %x\n", -+ i, R_SM(&ring[i].addrhigh), R_SM(&ring[i].addrlow), -+ R_SM(&ring[i].ctrl2), R_SM(&ring[i].ctrl1)); -+ } -+} -+ -+static void -+dma64_dumptx(dma_info_t *di, struct bcmstrbuf *b, bool dumpring) -+{ -+ if (di->ntxd == 0) { -+ return; -+ } -+ -+ bcm_bprintf(b, "DMA64: txd64 %p txdpa 0x%lx txdpahi 0x%lx txp %p txin %d txout %d " -+ "txavail %d txnodesc %d\n", di->txd64, PHYSADDRLO(di->txdpa), -+ PHYSADDRHI(di->txdpaorig), di->txp, di->txin, di->txout, di->hnddma.txavail, -+ di->hnddma.txnodesc); -+ -+ bcm_bprintf(b, "xmtcontrol 0x%x xmtaddrlow 0x%x xmtaddrhigh 0x%x " -+ "xmtptr 0x%x xmtstatus0 0x%x xmtstatus1 0x%x\n", -+ R_REG(di->osh, &di->d64txregs->control), -+ R_REG(di->osh, &di->d64txregs->addrlow), -+ R_REG(di->osh, &di->d64txregs->addrhigh), -+ R_REG(di->osh, &di->d64txregs->ptr), -+ R_REG(di->osh, &di->d64txregs->status0), -+ R_REG(di->osh, &di->d64txregs->status1)); -+ -+ bcm_bprintf(b, "DMA64: DMA avoidance applied %d\n", di->dma_avoidance_cnt); -+ -+ if (dumpring && di->txd64) { -+ dma64_dumpring(di, b, di->txd64, di->txin, di->txout, di->ntxd); -+ } -+} -+ -+static void -+dma64_dumprx(dma_info_t *di, struct bcmstrbuf *b, bool dumpring) -+{ -+ if (di->nrxd == 0) { -+ return; -+ } -+ -+ bcm_bprintf(b, "DMA64: rxd64 %p rxdpa 0x%lx rxdpahi 0x%lx rxp %p rxin %d rxout %d\n", -+ di->rxd64, PHYSADDRLO(di->rxdpa), PHYSADDRHI(di->rxdpaorig), di->rxp, -+ di->rxin, di->rxout); -+ -+ bcm_bprintf(b, "rcvcontrol 0x%x rcvaddrlow 0x%x rcvaddrhigh 0x%x rcvptr " -+ "0x%x rcvstatus0 0x%x rcvstatus1 0x%x\n", -+ R_REG(di->osh, &di->d64rxregs->control), -+ R_REG(di->osh, &di->d64rxregs->addrlow), -+ R_REG(di->osh, &di->d64rxregs->addrhigh), -+ R_REG(di->osh, &di->d64rxregs->ptr), -+ R_REG(di->osh, &di->d64rxregs->status0), -+ R_REG(di->osh, &di->d64rxregs->status1)); -+ if (di->rxd64 && dumpring) { -+ dma64_dumpring(di, b, di->rxd64, di->rxin, di->rxout, di->nrxd); -+ } -+} -+ -+static void -+dma64_dump(dma_info_t *di, struct bcmstrbuf *b, bool dumpring) -+{ -+ dma64_dumptx(di, b, dumpring); -+ dma64_dumprx(di, b, dumpring); -+} -+#endif -+ -+ -+/* 32-bit DMA functions */ -+ -+static void -+dma32_txinit(dma_info_t *di) -+{ -+ uint32 control = XC_XE; -+ -+ DMA_TRACE(("%s: dma_txinit\n", di->name)); -+ -+ if (di->ntxd == 0) { -+ return; -+ } -+ -+ di->txin = di->txout = di->xs0cd = 0; -+ di->hnddma.txavail = di->ntxd - 1; -+ -+ /* clear tx descriptor ring */ -+ BZERO_SM(DISCARD_QUAL(di->txd32, void), (di->ntxd * sizeof(dma32dd_t))); -+ -+ /* These bits 20:18 (burstLen) of control register can be written but will take -+ * effect only if these bits are valid. So this will not affect previous versions -+ * of the DMA. They will continue to have those bits set to 0. -+ */ -+ control |= (di->txburstlen << XC_BL_SHIFT); -+ control |= (di->txmultioutstdrd << XC_MR_SHIFT); -+ control |= (di->txprefetchctl << XC_PC_SHIFT); -+ control |= (di->txprefetchthresh << XC_PT_SHIFT); -+ -+ if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0) { -+ control |= XC_PD; -+ } -+ W_REG(di->osh, &di->d32txregs->control, control); -+ _dma_ddtable_init(di, DMA_TX, di->txdpa); -+} -+ -+static bool -+dma32_txenabled(dma_info_t *di) -+{ -+ uint32 xc; -+ -+ /* If the chip is dead, it is not enabled :-) */ -+ xc = R_REG(di->osh, &di->d32txregs->control); -+ return ((xc != 0xffffffff) && (xc & XC_XE)); -+} -+ -+static void -+dma32_txsuspend(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txsuspend\n", di->name)); -+ -+ if (di->ntxd == 0) { -+ return; -+ } -+ -+ OR_REG(di->osh, &di->d32txregs->control, XC_SE); -+} -+ -+static void -+dma32_txresume(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txresume\n", di->name)); -+ -+ if (di->ntxd == 0) { -+ return; -+ } -+ -+ AND_REG(di->osh, &di->d32txregs->control, ~XC_SE); -+} -+ -+static bool -+dma32_txsuspended(dma_info_t *di) -+{ -+ return (di->ntxd == 0) || ((R_REG(di->osh, &di->d32txregs->control) & XC_SE) == XC_SE); -+} -+ -+#ifdef WL_MULTIQUEUE -+static void -+dma32_txflush(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txflush\n", di->name)); -+ -+ if (di->ntxd == 0) { -+ return; -+ } -+ -+ OR_REG(di->osh, &di->d32txregs->control, XC_SE | XC_FL); -+} -+ -+static void -+dma32_txflush_clear(dma_info_t *di) -+{ -+ uint32 status; -+ -+ DMA_TRACE(("%s: dma_txflush_clear\n", di->name)); -+ -+ if (di->ntxd == 0) { -+ return; -+ } -+ -+ SPINWAIT(((status = (R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK)) -+ != XS_XS_DISABLED) && -+ (status != XS_XS_IDLE) && -+ (status != XS_XS_STOPPED), -+ (10000)); -+ AND_REG(di->osh, &di->d32txregs->control, ~XC_FL); -+} -+#endif /* WL_MULTIQUEUE */ -+ -+static void -+dma32_txreclaim(dma_info_t *di, txd_range_t range) -+{ -+ void *p; -+ -+ DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, -+ (range == HNDDMA_RANGE_ALL) ? "all" : -+ ((range == HNDDMA_RANGE_TRANSMITTED) ? "transmitted" : "transfered"))); -+ -+ if (di->txin == di->txout) { -+ return; -+ } -+ -+ while ((p = dma32_getnexttxp(di, range))) { -+ PKTFREE(di->osh, p, TRUE); -+ } -+} -+ -+static bool -+dma32_txstopped(dma_info_t *di) -+{ -+ return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED); -+} -+ -+static bool -+dma32_rxstopped(dma_info_t *di) -+{ -+ return ((R_REG(di->osh, &di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED); -+} -+ -+static bool -+dma32_alloc(dma_info_t *di, uint direction) -+{ -+ uint size; -+ uint ddlen; -+ void *va; -+ uint alloced; -+ uint16 align; -+ uint16 align_bits; -+ -+ ddlen = sizeof(dma32dd_t); -+ -+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); -+ -+ alloced = 0; -+ align_bits = di->dmadesc_align; -+ align = (1 << align_bits); -+ -+ if (direction == DMA_TX) { -+ if ((va = dma_ringalloc(di->osh, D32RINGALIGN, size, &align_bits, &alloced, -+ &di->txdpaorig, &di->tx_dmah)) == NULL) { -+ DMA_ERROR(("%s: dma_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", -+ di->name)); -+ return FALSE; -+ } -+ -+ PHYSADDRHISET(di->txdpa, 0); -+ ASSERT(PHYSADDRHI(di->txdpaorig) == 0); -+ di->txd32 = (dma32dd_t *)ROUNDUP((uintptr)va, align); -+ di->txdalign = (uint)((int8 *)(uintptr)di->txd32 - (int8 *)va); -+ -+ PHYSADDRLOSET(di->txdpa, PHYSADDRLO(di->txdpaorig) + di->txdalign); -+ /* Make sure that alignment didn't overflow */ -+ ASSERT(PHYSADDRLO(di->txdpa) >= PHYSADDRLO(di->txdpaorig)); -+ -+ di->txdalloc = alloced; -+ ASSERT(ISALIGNED(di->txd32, align)); -+ } else { -+ if ((va = dma_ringalloc(di->osh, D32RINGALIGN, size, &align_bits, &alloced, -+ &di->rxdpaorig, &di->rx_dmah)) == NULL) { -+ DMA_ERROR(("%s: dma_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", -+ di->name)); -+ return FALSE; -+ } -+ -+ PHYSADDRHISET(di->rxdpa, 0); -+ ASSERT(PHYSADDRHI(di->rxdpaorig) == 0); -+ di->rxd32 = (dma32dd_t *)ROUNDUP((uintptr)va, align); -+ di->rxdalign = (uint)((int8 *)(uintptr)di->rxd32 - (int8 *)va); -+ -+ PHYSADDRLOSET(di->rxdpa, PHYSADDRLO(di->rxdpaorig) + di->rxdalign); -+ /* Make sure that alignment didn't overflow */ -+ ASSERT(PHYSADDRLO(di->rxdpa) >= PHYSADDRLO(di->rxdpaorig)); -+ di->rxdalloc = alloced; -+ ASSERT(ISALIGNED(di->rxd32, align)); -+ } -+ -+ return TRUE; -+} -+ -+static bool -+dma32_txreset(dma_info_t *di) -+{ -+ uint32 status; -+ -+ if (di->ntxd == 0) { -+ return TRUE; -+ } -+ -+ /* suspend tx DMA first */ -+ W_REG(di->osh, &di->d32txregs->control, XC_SE); -+ SPINWAIT(((status = (R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK)) -+ != XS_XS_DISABLED) && -+ (status != XS_XS_IDLE) && -+ (status != XS_XS_STOPPED), -+ (10000)); -+ -+ W_REG(di->osh, &di->d32txregs->control, 0); -+ SPINWAIT(((status = (R_REG(di->osh, -+ &di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED), -+ 10000); -+ -+ /* We should be disabled at this point */ -+ if (status != XS_XS_DISABLED) { -+ DMA_ERROR(("%s: status != D64_XS0_XS_DISABLED 0x%x\n", __FUNCTION__, status)); -+ ASSERT(status == XS_XS_DISABLED); -+ OSL_DELAY(300); -+ } -+ -+ return (status == XS_XS_DISABLED); -+} -+ -+static bool -+dma32_rxidle(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_rxidle\n", di->name)); -+ -+ if (di->nrxd == 0) { -+ return TRUE; -+ } -+ -+ return ((R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK) == -+ R_REG(di->osh, &di->d32rxregs->ptr)); -+} -+ -+static bool -+dma32_rxreset(dma_info_t *di) -+{ -+ uint32 status; -+ -+ if (di->nrxd == 0) { -+ return TRUE; -+ } -+ -+ W_REG(di->osh, &di->d32rxregs->control, 0); -+ SPINWAIT(((status = (R_REG(di->osh, -+ &di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED), -+ 10000); -+ -+ return (status == RS_RS_DISABLED); -+} -+ -+static bool -+dma32_rxenabled(dma_info_t *di) -+{ -+ uint32 rc; -+ -+ rc = R_REG(di->osh, &di->d32rxregs->control); -+ return ((rc != 0xffffffff) && (rc & RC_RE)); -+} -+ -+static bool -+dma32_txsuspendedidle(dma_info_t *di) -+{ -+ if (di->ntxd == 0) { -+ return TRUE; -+ } -+ -+ if (!(R_REG(di->osh, &di->d32txregs->control) & XC_SE)) { -+ return 0; -+ } -+ -+ if ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE) { -+ return 0; -+ } -+ -+ OSL_DELAY(2); -+ return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE); -+} -+ -+/* !! tx entry routine -+ * supports full 32bit dma engine buffer addressing so -+ * dma buffers can cross 4 Kbyte page boundaries. -+ * -+ * WARNING: call must check the return value for error. -+ * the error(toss frames) could be fatal and cause many subsequent hard to debug problems -+ */ -+static int -+dma32_txfast(dma_info_t *di, void *p0, bool commit) -+{ -+ void *p, *next; -+ uchar *data; -+ uint len; -+ uint16 txout; -+ uint32 flags = 0; -+ dmaaddr_t pa; -+ -+ DMA_TRACE(("%s: dma_txfast\n", di->name)); -+ -+ txout = di->txout; -+ -+ /* -+ * Walk the chain of packet buffers -+ * allocating and initializing transmit descriptor entries. -+ */ -+ for (p = p0; p; p = next) { -+ uint nsegs, j; -+ hnddma_seg_map_t *map; -+ -+ data = PKTDATA(di->osh, p); -+ len = PKTLEN(di->osh, p); -+#ifdef BCM_DMAPAD -+ len += PKTDMAPAD(di->osh, p); -+#endif -+ next = PKTNEXT(di->osh, p); -+ -+ /* return nonzero if out of tx descriptors */ -+ if (NEXTTXD(txout) == di->txin) { -+ goto outoftxd; -+ } -+ -+ if (len == 0) { -+ continue; -+ } -+ -+ if (DMASGLIST_ENAB) { -+ bzero(&di->txp_dmah[txout], sizeof(hnddma_seg_map_t)); -+ } -+ -+ /* get physical address of buffer start */ -+ pa = DMA_MAP(di->osh, data, len, DMA_TX, p, &di->txp_dmah[txout]); -+ -+ if (DMASGLIST_ENAB) { -+ map = &di->txp_dmah[txout]; -+ -+ /* See if all the segments can be accounted for */ -+ if (map->nsegs > (uint)(di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1)) { -+ goto outoftxd; -+ } -+ -+ nsegs = map->nsegs; -+ } else { -+ nsegs = 1; -+ } -+ -+ for (j = 1; j <= nsegs; j++) { -+ flags = 0; -+ if (p == p0 && j == 1) { -+ flags |= CTRL_SOF; -+ } -+ -+ /* With a DMA segment list, Descriptor table is filled -+ * using the segment list instead of looping over -+ * buffers in multi-chain DMA. Therefore, EOF for SGLIST is when -+ * end of segment list is reached. -+ */ -+ if ((!DMASGLIST_ENAB && next == NULL) || -+ (DMASGLIST_ENAB && j == nsegs)) { -+ flags |= (CTRL_IOC | CTRL_EOF); -+ } -+ if (txout == (di->ntxd - 1)) { -+ flags |= CTRL_EOT; -+ } -+ -+ if (DMASGLIST_ENAB) { -+ len = map->segs[j - 1].length; -+ pa = map->segs[j - 1].addr; -+ } -+ ASSERT(PHYSADDRHI(pa) == 0); -+ -+ dma32_dd_upd(di, di->txd32, pa, txout, &flags, len); -+ ASSERT(di->txp[txout] == NULL); -+ -+ txout = NEXTTXD(txout); -+ } -+ -+ /* See above. No need to loop over individual buffers */ -+ if (DMASGLIST_ENAB) { -+ break; -+ } -+ } -+ -+ /* if last txd eof not set, fix it */ -+ if (!(flags & CTRL_EOF)) { -+ W_SM(&di->txd32[PREVTXD(txout)].ctrl, BUS_SWAP32(flags | CTRL_IOC | CTRL_EOF)); -+ } -+ -+ /* save the packet */ -+ di->txp[PREVTXD(txout)] = p0; -+ -+ /* bump the tx descriptor index */ -+ di->txout = txout; -+ -+ /* kick the chip */ -+ if (commit) { -+ W_REG(di->osh, &di->d32txregs->ptr, I2B(txout, dma32dd_t)); -+ } -+ -+ /* tx flow control */ -+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ return (0); -+ -+outoftxd: -+ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); -+ PKTFREE(di->osh, p0, TRUE); -+ di->hnddma.txavail = 0; -+ di->hnddma.txnobuf++; -+ di->hnddma.txnodesc++; -+ return (-1); -+} -+ -+/* -+ * Reclaim next completed txd (txds if using chained buffers) in the range -+ * specified and return associated packet. -+ * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be -+ * transmitted as noted by the hardware "CurrDescr" pointer. -+ * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be -+ * transfered by the DMA as noted by the hardware "ActiveDescr" pointer. -+ * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and -+ * return associated packet regardless of the value of hardware pointers. -+ */ -+static void * -+dma32_getnexttxp(dma_info_t *di, txd_range_t range) -+{ -+ uint16 start, end, i; -+ uint16 active_desc; -+ void *txp; -+ -+ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, -+ (range == HNDDMA_RANGE_ALL) ? "all" : -+ ((range == HNDDMA_RANGE_TRANSMITTED) ? "transmitted" : "transfered"))); -+ -+ if (di->ntxd == 0) { -+ return (NULL); -+ } -+ -+ txp = NULL; -+ -+ start = di->txin; -+ if (range == HNDDMA_RANGE_ALL) { -+ end = di->txout; -+ } else { -+ dma32regs_t *dregs = di->d32txregs; -+ -+ if (di->txin == di->xs0cd) { -+ end = (uint16)B2I(R_REG(di->osh, &dregs->status) & XS_CD_MASK, dma32dd_t); -+ di->xs0cd = end; -+ } else { -+ end = di->xs0cd; -+ } -+ -+ if (range == HNDDMA_RANGE_TRANSFERED) { -+ active_desc = (uint16)((R_REG(di->osh, &dregs->status) & XS_AD_MASK) >> -+ XS_AD_SHIFT); -+ active_desc = (uint16)B2I(active_desc, dma32dd_t); -+ if (end != active_desc) { -+ end = PREVTXD(active_desc); -+ } -+ } -+ } -+ -+ if ((start == 0) && (end > di->txout)) { -+ goto bogus; -+ } -+ -+ for (i = start; i != end && !txp; i = NEXTTXD(i)) { -+ dmaaddr_t pa; -+ hnddma_seg_map_t *map = NULL; -+ uint size, j, nsegs; -+ -+ PHYSADDRLOSET(pa, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow)); -+ PHYSADDRHISET(pa, 0); -+ -+ if (DMASGLIST_ENAB) { -+ map = &di->txp_dmah[i]; -+ size = map->origsize; -+ nsegs = map->nsegs; -+ } else { -+ size = (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK); -+ nsegs = 1; -+ } -+ -+ for (j = nsegs; j > 0; j--) { -+ W_SM(&di->txd32[i].addr, 0xdeadbeef); -+ -+ txp = di->txp[i]; -+ di->txp[i] = NULL; -+ if (j > 1) { -+ i = NEXTTXD(i); -+ } -+ } -+ -+#ifndef CONFIG_BCM_IPROC_GMAC_ACP -+ DMA_UNMAP(di->osh, pa, size, DMA_TX, txp, map); -+#endif /* ! CONFIG_BCM_IPROC_GMAC_ACP */ -+ } -+ -+ di->txin = i; -+ -+ /* tx flow control */ -+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ return (txp); -+ -+bogus: -+ DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", -+ start, end, di->txout, forceall)); -+ return (NULL); -+} -+ -+static void * -+dma32_getnextrxp(dma_info_t *di, bool forceall) -+{ -+ uint16 i, curr; -+ void *rxp; -+ dmaaddr_t pa; -+ /* if forcing, dma engine must be disabled */ -+ ASSERT(!forceall || !dma32_rxenabled(di)); -+ -+ i = di->rxin; -+ -+ /* return if no packets posted */ -+ if (i == di->rxout) { -+ return (NULL); -+ } -+ -+ if (di->rxin == di->rs0cd) { -+ curr = (uint16)B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK, dma32dd_t); -+ di->rs0cd = curr; -+ } else { -+ curr = di->rs0cd; -+ } -+ -+ /* ignore curr if forceall */ -+ if (!forceall && (i == curr)) { -+ return (NULL); -+ } -+ -+ /* get the packet pointer that corresponds to the rx descriptor */ -+ rxp = di->rxp[i]; -+ ASSERT(rxp); -+ di->rxp[i] = NULL; -+ -+ PHYSADDRLOSET(pa, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow)); -+ PHYSADDRHISET(pa, 0); -+ -+ /* clear this packet from the descriptor ring */ -+#ifndef CONFIG_BCM_IPROC_GMAC_ACP -+ DMA_UNMAP(di->osh, pa, -+ di->rxbufsize, DMA_RX, rxp, &di->rxp_dmah[i]); -+#endif /* ! CONFIG_BCM_IPROC_GMAC_ACP */ -+ -+ W_SM(&di->rxd32[i].addr, 0xdeadbeef); -+ -+ di->rxin = NEXTRXD(i); -+ -+ return (rxp); -+} -+ -+/* -+ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). -+ */ -+static void -+dma32_txrotate(dma_info_t *di) -+{ -+ uint16 ad; -+ uint nactive; -+ uint rot; -+ uint16 old, new; -+ uint32 w; -+ uint16 first, last; -+ -+ ASSERT(dma32_txsuspendedidle(di)); -+ -+ nactive = _dma_txactive(di); -+ ad = B2I(((R_REG(di->osh, &di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t); -+ rot = TXD(ad - di->txin); -+ -+ ASSERT(rot < di->ntxd); -+ -+ /* full-ring case is a lot harder - don't worry about this */ -+ if (rot >= (di->ntxd - nactive)) { -+ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); -+ return; -+ } -+ -+ first = di->txin; -+ last = PREVTXD(di->txout); -+ -+ /* move entries starting at last and moving backwards to first */ -+ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { -+ new = TXD(old + rot); -+ -+ /* -+ * Move the tx dma descriptor. -+ * EOT is set only in the last entry in the ring. -+ */ -+ w = BUS_SWAP32(R_SM(&di->txd32[old].ctrl)) & ~CTRL_EOT; -+ if (new == (di->ntxd - 1)) { -+ w |= CTRL_EOT; -+ } -+ W_SM(&di->txd32[new].ctrl, BUS_SWAP32(w)); -+ W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr)); -+ -+ /* zap the old tx dma descriptor address field */ -+ W_SM(&di->txd32[old].addr, BUS_SWAP32(0xdeadbeef)); -+ -+ /* move the corresponding txp[] entry */ -+ ASSERT(di->txp[new] == NULL); -+ di->txp[new] = di->txp[old]; -+ -+ /* Move the segment map as well */ -+ if (DMASGLIST_ENAB) { -+ bcopy(&di->txp_dmah[old], &di->txp_dmah[new], sizeof(hnddma_seg_map_t)); -+ bzero(&di->txp_dmah[old], sizeof(hnddma_seg_map_t)); -+ } -+ -+ di->txp[old] = NULL; -+ } -+ -+ /* update txin and txout */ -+ di->txin = ad; -+ di->txout = TXD(di->txout + rot); -+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ /* kick the chip */ -+ W_REG(di->osh, &di->d32txregs->ptr, I2B(di->txout, dma32dd_t)); -+} -+ -+/* 64-bit DMA functions */ -+ -+static void -+dma64_txinit(dma_info_t *di) -+{ -+ uint32 control; -+ -+ DMA_TRACE(("%s: dma_txinit\n", di->name)); -+ -+ if (di->ntxd == 0) { -+ return; -+ } -+ -+ di->txin = di->txout = di->xs0cd = di->xs0cd_snapshot = 0; -+ di->hnddma.txavail = di->ntxd - 1; -+ -+ /* clear tx descriptor ring */ -+ BZERO_SM((void *)(uintptr)di->txd64, (di->ntxd * sizeof(dma64dd_t))); -+ -+ /* These bits 20:18 (burstLen) of control register can be written but will take -+ * effect only if these bits are valid. So this will not affect previous versions -+ * of the DMA. They will continue to have those bits set to 0. -+ */ -+ control = R_REG(di->osh, &di->d64txregs->control); -+ control = (control & ~D64_XC_BL_MASK) | (di->txburstlen << D64_XC_BL_SHIFT); -+ control = (control & ~D64_XC_MR_MASK) | (di->txmultioutstdrd << D64_XC_MR_SHIFT); -+ control = (control & ~D64_XC_PC_MASK) | (di->txprefetchctl << D64_XC_PC_SHIFT); -+ control = (control & ~D64_XC_PT_MASK) | (di->txprefetchthresh << D64_XC_PT_SHIFT); -+ W_REG(di->osh, &di->d64txregs->control, control); -+ -+ control = D64_XC_XE; -+ /* DMA engine with out alignment requirement requires table to be inited -+ * before enabling the engine -+ */ -+ if (!di->aligndesc_4k) { -+ _dma_ddtable_init(di, DMA_TX, di->txdpa); -+ } -+ -+ if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0) { -+ control |= D64_XC_PD; -+ } -+ OR_REG(di->osh, &di->d64txregs->control, control); -+ -+ /* DMA engine with alignment requirement requires table to be inited -+ * before enabling the engine -+ */ -+ if (di->aligndesc_4k) { -+ _dma_ddtable_init(di, DMA_TX, di->txdpa); -+ } -+} -+ -+static bool -+dma64_txenabled(dma_info_t *di) -+{ -+ uint32 xc; -+ -+ /* If the chip is dead, it is not enabled :-) */ -+ xc = R_REG(di->osh, &di->d64txregs->control); -+ return ((xc != 0xffffffff) && (xc & D64_XC_XE)); -+} -+ -+static void -+dma64_txsuspend(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txsuspend\n", di->name)); -+ -+ if (di->ntxd == 0) { -+ return; -+ } -+ -+ OR_REG(di->osh, &di->d64txregs->control, D64_XC_SE); -+} -+ -+static void -+dma64_txresume(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txresume\n", di->name)); -+ -+ if (di->ntxd == 0) { -+ return; -+ } -+ -+ AND_REG(di->osh, &di->d64txregs->control, ~D64_XC_SE); -+} -+ -+static bool -+dma64_txsuspended(dma_info_t *di) -+{ -+ return (di->ntxd == 0) || -+ ((R_REG(di->osh, &di->d64txregs->control) & D64_XC_SE) == D64_XC_SE); -+} -+ -+#ifdef WL_MULTIQUEUE -+static void -+dma64_txflush(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txflush\n", di->name)); -+ -+ if (di->ntxd == 0) { -+ return; -+ } -+ -+ OR_REG(di->osh, &di->d64txregs->control, D64_XC_SE | D64_XC_FL); -+} -+ -+static void -+dma64_txflush_clear(dma_info_t *di) -+{ -+ uint32 status; -+ -+ DMA_TRACE(("%s: dma_txflush_clear\n", di->name)); -+ -+ if (di->ntxd == 0) { -+ return; -+ } -+ -+ SPINWAIT(((status = (R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK)) != -+ D64_XS0_XS_DISABLED) && -+ (status != D64_XS0_XS_IDLE) && -+ (status != D64_XS0_XS_STOPPED), -+ 10000); -+ AND_REG(di->osh, &di->d64txregs->control, ~D64_XC_FL); -+} -+#endif /* WL_MULTIQUEUE */ -+ -+static void BCMFASTPATH -+dma64_txreclaim(dma_info_t *di, txd_range_t range) -+{ -+ void *p; -+ -+ DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, -+ (range == HNDDMA_RANGE_ALL) ? "all" : -+ ((range == HNDDMA_RANGE_TRANSMITTED) ? "transmitted" : "transfered"))); -+ -+ if (di->txin == di->txout) { -+ return; -+ } -+ -+ while ((p = dma64_getnexttxp(di, range))) { -+ /* For unframed data, we don't have any packets to free */ -+ if (!(di->hnddma.dmactrlflags & DMA_CTRL_UNFRAMED)) { -+ PKTFREE(di->osh, p, TRUE); -+ } -+ } -+} -+ -+static bool -+dma64_txstopped(dma_info_t *di) -+{ -+ return ((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED); -+} -+ -+static bool -+dma64_rxstopped(dma_info_t *di) -+{ -+ return ((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED); -+} -+ -+static bool -+dma64_alloc(dma_info_t *di, uint direction) -+{ -+ uint32 size; -+ uint ddlen; -+ void *va; -+ uint alloced = 0; -+ uint32 align; -+ uint16 align_bits; -+ -+ ddlen = sizeof(dma64dd_t); -+ -+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); -+ align_bits = di->dmadesc_align; -+ align = (1 << align_bits); -+ -+ if (direction == DMA_TX) { -+ if ((va = dma_ringalloc(di->osh, -+ (di->d64_xs0_cd_mask == 0x1fff) ? D64RINGBOUNDARY : D64RINGBOUNDARY_LARGE, -+ size, &align_bits, &alloced, -+ &di->txdpaorig, &di->tx_dmah)) == NULL) { -+ DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", -+ di->name)); -+ return FALSE; -+ } -+ align = (1 << align_bits); -+ -+ /* adjust the pa by rounding up to the alignment */ -+ PHYSADDRLOSET(di->txdpa, ROUNDUP(PHYSADDRLO(di->txdpaorig), align)); -+ PHYSADDRHISET(di->txdpa, PHYSADDRHI(di->txdpaorig)); -+ -+ /* Make sure that alignment didn't overflow */ -+ ASSERT(PHYSADDRLO(di->txdpa) >= PHYSADDRLO(di->txdpaorig)); -+ -+ /* find the alignment offset that was used */ -+ di->txdalign = (uint)(PHYSADDRLO(di->txdpa) - PHYSADDRLO(di->txdpaorig)); -+ -+ /* adjust the va by the same offset */ -+ di->txd64 = (dma64dd_t *)((uintptr)va + di->txdalign); -+ -+ /* printk("%s di->txd64(0x%x-0x%x) \n", __FUNCTION__, PHYSADDRHI(di->txd64), PHYSADDRLO(di->txd64)); */ -+ /* printk("%s di->txdpa(0x%x-0x%x) \n", __FUNCTION__, PHYSADDRHI(di->txdpa), PHYSADDRLO(di->txdpa)); */ -+ di->txdalloc = alloced; -+ ASSERT(ISALIGNED(PHYSADDRLO(di->txdpa), align)); -+ } else { -+ if ((va = dma_ringalloc(di->osh, -+ (di->d64_rs0_cd_mask == 0x1fff) ? D64RINGBOUNDARY : D64RINGBOUNDARY_LARGE, -+ size, &align_bits, &alloced, -+ &di->rxdpaorig, &di->rx_dmah)) == NULL) { -+ DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", -+ di->name)); -+ return FALSE; -+ } -+ align = (1 << align_bits); -+ -+ /* adjust the pa by rounding up to the alignment */ -+ PHYSADDRLOSET(di->rxdpa, ROUNDUP(PHYSADDRLO(di->rxdpaorig), align)); -+ PHYSADDRHISET(di->rxdpa, PHYSADDRHI(di->rxdpaorig)); -+ -+ /* Make sure that alignment didn't overflow */ -+ ASSERT(PHYSADDRLO(di->rxdpa) >= PHYSADDRLO(di->rxdpaorig)); -+ -+ /* find the alignment offset that was used */ -+ di->rxdalign = (uint)(PHYSADDRLO(di->rxdpa) - PHYSADDRLO(di->rxdpaorig)); -+ -+ /* adjust the va by the same offset */ -+ di->rxd64 = (dma64dd_t *)((uintptr)va + di->rxdalign); -+ -+ /* printk("%s di->rxd64(0x%x-0x%x) \n", __FUNCTION__, PHYSADDRHI(di->rxd64), PHYSADDRLO(di->rxd64)); */ -+ /* printk("%s di->rxdpa(0x%x-0x%x) \n", __FUNCTION__, PHYSADDRHI(di->rxdpa), PHYSADDRLO(di->rxdpa)); */ -+ di->rxdalloc = alloced; -+ ASSERT(ISALIGNED(PHYSADDRLO(di->rxdpa), align)); -+ } -+ -+ return TRUE; -+} -+ -+static bool -+dma64_txreset(dma_info_t *di) -+{ -+ uint32 status; -+ -+ if (di->ntxd == 0) { -+ return TRUE; -+ } -+ -+ /* suspend tx DMA first */ -+ W_REG(di->osh, &di->d64txregs->control, D64_XC_SE); -+ -+ SPINWAIT(((status = (R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK)) != -+ D64_XS0_XS_DISABLED) && -+ (status != D64_XS0_XS_IDLE) && -+ (status != D64_XS0_XS_STOPPED), -+ 10000); -+ -+ W_REG(di->osh, &di->d64txregs->control, 0); -+ -+ SPINWAIT(((status = (R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK)) != -+ D64_XS0_XS_DISABLED), -+ 10000); -+ -+ /* We should be disabled at this point */ -+ if (status != D64_XS0_XS_DISABLED) { -+ DMA_ERROR(("%s: status != D64_XS0_XS_DISABLED 0x%x\n", __FUNCTION__, status)); -+ ASSERT(status == D64_XS0_XS_DISABLED); -+ OSL_DELAY(300); -+ } -+ -+ return (status == D64_XS0_XS_DISABLED); -+} -+ -+static bool -+dma64_rxidle(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_rxidle\n", di->name)); -+ -+ if (di->nrxd == 0) { -+ return TRUE; -+ } -+ -+ return ((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) == -+ (R_REG(di->osh, &di->d64rxregs->ptr) & D64_RS0_CD_MASK)); -+} -+ -+static bool -+dma64_rxreset(dma_info_t *di) -+{ -+ uint32 status; -+ -+ if (di->nrxd == 0) { -+ return TRUE; -+ } -+ -+ W_REG(di->osh, &di->d64rxregs->control, 0); -+ -+ SPINWAIT(((status = (R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK)) != -+ D64_RS0_RS_DISABLED), 10000); -+ -+ return (status == D64_RS0_RS_DISABLED); -+} -+ -+static bool -+dma64_rxenabled(dma_info_t *di) -+{ -+ uint32 rc; -+ -+ rc = R_REG(di->osh, &di->d64rxregs->control); -+ return ((rc != 0xffffffff) && (rc & D64_RC_RE)); -+} -+ -+static bool -+dma64_txsuspendedidle(dma_info_t *di) -+{ -+ -+ if (di->ntxd == 0) { -+ return TRUE; -+ } -+ -+ if (!(R_REG(di->osh, &di->d64txregs->control) & D64_XC_SE)) { -+ return 0; -+ } -+ -+ if ((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_IDLE) { -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/* Useful when sending unframed data. This allows us to get a progress report from the DMA. -+ * We return a pointer to the beginning of the data buffer of the current descriptor. -+ * If DMA is idle, we return NULL. -+ */ -+static void* -+dma64_getpos(dma_info_t *di, bool direction) -+{ -+ void *va; -+ bool idle; -+ uint16 cur_idx; -+ -+ if (direction == DMA_TX) { -+ cur_idx = B2I(((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK) - -+ di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t); -+ idle = !NTXDACTIVE(di->txin, di->txout); -+ va = di->txp[cur_idx]; -+ } else { -+ cur_idx = B2I(((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) - -+ di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t); -+ idle = !NRXDACTIVE(di->rxin, di->rxout); -+ va = di->rxp[cur_idx]; -+ } -+ -+ /* If DMA is IDLE, return NULL */ -+ if (idle) { -+ DMA_TRACE(("%s: DMA idle, return NULL\n", __FUNCTION__)); -+ va = NULL; -+ } -+ -+ return va; -+} -+ -+/* TX of unframed data -+ * -+ * Adds a DMA ring descriptor for the data pointed to by "buf". -+ * This is for DMA of a buffer of data and is unlike other hnddma TX functions -+ * that take a pointer to a "packet" -+ * Each call to this is results in a single descriptor being added for "len" bytes of -+ * data starting at "buf", it doesn't handle chained buffers. -+ */ -+static int -+dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit) -+{ -+ uint16 txout; -+ uint32 flags = 0; -+ dmaaddr_t pa; /* phys addr */ -+ -+ txout = di->txout; -+ -+ /* return nonzero if out of tx descriptors */ -+ if (NEXTTXD(txout) == di->txin) { -+ goto outoftxd; -+ } -+ -+ if (len == 0) { -+ return 0; -+ } -+ -+#if defined(CONFIG_BCM_IPROC_GMAC_ACP) && !defined(BCMDMASGLISTOSL) -+ pa = virt_to_phys(buf); -+#else -+ pa = DMA_MAP(di->osh, buf, len, DMA_TX, NULL, &di->txp_dmah[txout]); -+#endif /* defined(CONFIG_BCM_IPROC_GMAC_ACP) && !defined(BCMDMASGLISTOSL) */ -+ -+ flags = (D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF); -+ -+ if (txout == (di->ntxd - 1)) { -+ flags |= D64_CTRL1_EOT; -+ } -+ -+ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len); -+ ASSERT(di->txp[txout] == NULL); -+ -+ /* save the buffer pointer - used by dma_getpos */ -+ di->txp[txout] = buf; -+ -+ txout = NEXTTXD(txout); -+ /* bump the tx descriptor index */ -+ di->txout = txout; -+ -+ /* kick the chip */ -+ if (commit) { -+ W_REG(di->osh, &di->d64txregs->ptr, di->xmtptrbase + I2B(txout, dma64dd_t)); -+ } -+ -+ /* tx flow control */ -+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ return (0); -+ -+outoftxd: -+ DMA_ERROR(("%s: %s: out of txds !!!\n", di->name, __FUNCTION__)); -+ di->hnddma.txavail = 0; -+ di->hnddma.txnobuf++; -+ return (-1); -+} -+ -+/* RX of unframed data -+ * -+ * Adds a DMA ring descriptor for the data pointed to by "buf". -+ * This is for DMA of a buffer of data and is unlike other hnddma TX functions -+ * that take a pointer to a "packet" -+ * Each call to this is results in a single descriptor being added for "len" bytes of -+ * data starting at "buf", it doesn't handle chained buffers. -+ */ -+static int -+dma64_rxunframed(dma_info_t *di, void *buf, uint len, bool commit) -+{ -+ uint16 rxout; -+ uint32 flags = 0; -+ dmaaddr_t pa; /* phys addr */ -+ -+ rxout = di->rxout; -+ -+ /* return nonzero if out of rx descriptors */ -+ if (NEXTRXD(rxout) == di->rxin) { -+ goto outofrxd; -+ } -+ -+ if (len == 0) { -+ return 0; -+ } -+ -+#if defined(CONFIG_BCM_IPROC_GMAC_ACP) && !defined(BCMDMASGLISTOSL) -+ pa = virt_to_phys(buf); -+#else -+ pa = DMA_MAP(di->osh, buf, len, DMA_RX, NULL, &di->rxp_dmah[rxout]); -+#endif /* defined(CONFIG_BCM_IPROC_GMAC_ACP) && !defined(BCMDMASGLISTOSL) */ -+ -+ flags = (D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF); -+ -+ if (rxout == (di->nrxd - 1)) { -+ flags |= D64_CTRL1_EOT; -+ } -+ -+ dma64_dd_upd(di, di->rxd64, pa, rxout, &flags, len); -+ ASSERT(di->rxp[rxout] == NULL); -+ -+ /* save the buffer pointer - used by dma_getpos */ -+ di->rxp[rxout] = buf; -+ -+ rxout = NEXTRXD(rxout); -+ /* bump the tx descriptor index */ -+ di->rxout = rxout; -+ -+ /* kick the chip */ -+ if (commit) { -+ W_REG(di->osh, &di->d64rxregs->ptr, di->rcvptrbase + I2B(rxout, dma64dd_t)); -+ //DBG("%s (Control Reg)W_REG: 0x%x Value: 0x%x\n", __FUNCTION__, &di->d64rxregs->ptr, di->rcvptrbase + I2B(rxout, dma64dd_t)); -+ } -+ -+ /* tx flow control */ -+ //di->hnddma.rxavail = di->nrxd - NRXDACTIVE(di->rxin, di->rxout) - 1; -+ -+ return (0); -+ -+outofrxd: -+ DMA_ERROR(("%s: %s: out of rxds !!!\n", di->name, __FUNCTION__)); -+ //di->hnddma.rxavail = 0; -+ di->hnddma.rxnobuf++; -+ return (-1); -+} -+ -+/* !! tx entry routine -+ * WARNING: call must check the return value for error. -+ * the error(toss frames) could be fatal and cause many subsequent hard to debug problems -+ */ -+static int BCMFASTPATH -+dma64_txfast(dma_info_t *di, void *p0, bool commit) -+{ -+ void *p, *next; -+ uchar *data; -+ uint len; -+ uint16 txout; -+ uint32 flags = 0; -+ dmaaddr_t pa; -+ bool war; -+ -+ DMA_TRACE(("%s: dma_txfast\n", di->name)); -+ -+ txout = di->txout; -+ war = (di->hnddma.dmactrlflags & DMA_CTRL_DMA_AVOIDANCE_WAR) ? TRUE : FALSE; -+ -+ /* -+ * Walk the chain of packet buffers -+ * allocating and initializing transmit descriptor entries. -+ */ -+ for (p = p0; p; p = next) { -+ uint nsegs, j, segsadd; -+ hnddma_seg_map_t *map = NULL; -+ -+ data = PKTDATA(di->osh, p); -+ len = PKTLEN(di->osh, p); -+#ifdef BCM_DMAPAD -+ len += PKTDMAPAD(di->osh, p); -+#endif /* BCM_DMAPAD */ -+ next = PKTNEXT(di->osh, p); -+ -+#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH -+ prefetch_range(next, SKB_PREFETCH_LEN); -+#endif -+ -+ /* return nonzero if out of tx descriptors */ -+ if (NEXTTXD(txout) == di->txin) { -+ goto outoftxd; -+ } -+ -+ if (len == 0) { -+ continue; -+ } -+ -+ /* get physical address of buffer start */ -+ if (DMASGLIST_ENAB) { -+ bzero(&di->txp_dmah[txout], sizeof(hnddma_seg_map_t)); -+ } -+ -+#if defined(CONFIG_BCM_IPROC_GMAC_ACP) && !defined(BCMDMASGLISTOSL) -+ pa = virt_to_phys(data); -+#else -+ pa = DMA_MAP(di->osh, data, len, DMA_TX, p, &di->txp_dmah[txout]); -+#endif /* defined(CONFIG_BCM_IPROC_GMAC_ACP) && !defined(BCMDMASGLISTOSL) */ -+ -+ -+ if (DMASGLIST_ENAB) { -+ map = &di->txp_dmah[txout]; -+ -+ /* See if all the segments can be accounted for */ -+ if (map->nsegs > (uint)(di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1)) { -+ goto outoftxd; -+ } -+ -+ nsegs = map->nsegs; -+ } else { -+ nsegs = 1; -+ } -+ -+ segsadd = 0; -+ for (j = 1; j <= nsegs; j++) { -+ flags = 0; -+ if (p == p0 && j == 1) { -+ flags |= D64_CTRL1_SOF; -+ } -+ -+ /* With a DMA segment list, Descriptor table is filled -+ * using the segment list instead of looping over -+ * buffers in multi-chain DMA. Therefore, EOF for SGLIST is when -+ * end of segment list is reached. -+ */ -+ if ((!DMASGLIST_ENAB && next == NULL) || -+ (DMASGLIST_ENAB && j == nsegs)) { -+ flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF); -+ } -+ if (txout == (di->ntxd - 1)) { -+ flags |= D64_CTRL1_EOT; -+ } -+ -+ if (DMASGLIST_ENAB) { -+ len = map->segs[j - 1].length; -+ pa = map->segs[j - 1].addr; -+ if (len > 128 && war) { -+ uint remain, new_len, align64; -+ /* check for 64B aligned of pa */ -+ align64 = (uint)(PHYSADDRLO(pa) & 0x3f); -+ align64 = (64 - align64) & 0x3f; -+ new_len = len - align64; -+ remain = new_len % 128; -+ if (remain > 0 && remain <= 4) { -+ uint32 buf_addr_lo; -+ uint32 tmp_flags = -+ flags & (~(D64_CTRL1_EOF | D64_CTRL1_IOC)); -+ flags &= ~(D64_CTRL1_SOF | D64_CTRL1_EOT); -+ remain += 64; -+ dma64_dd_upd(di, di->txd64, pa, txout, -+ &tmp_flags, len-remain); -+ ASSERT(di->txp[txout] == NULL); -+ txout = NEXTTXD(txout); -+ /* return nonzero if out of tx descriptors */ -+ if (txout == di->txin) { -+ DMA_ERROR(("%s: dma_txfast: Out-of-DMA" -+ " descriptors (txin %d txout %d" -+ " nsegs %d)\n", __FUNCTION__, -+ di->txin, di->txout, nsegs)); -+ goto outoftxd; -+ } -+ if (txout == (di->ntxd - 1)) { -+ flags |= D64_CTRL1_EOT; -+ } -+ buf_addr_lo = PHYSADDRLO(pa); -+ PHYSADDRLOSET(pa, (PHYSADDRLO(pa) + (len-remain))); -+ if (PHYSADDRLO(pa) < buf_addr_lo) { -+ PHYSADDRHISET(pa, (PHYSADDRHI(pa) + 1)); -+ } -+ len = remain; -+ segsadd++; -+ di->dma_avoidance_cnt++; -+ } -+ } -+ } -+ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len); -+ ASSERT(di->txp[txout] == NULL); -+ -+ txout = NEXTTXD(txout); -+ /* return nonzero if out of tx descriptors */ -+ if (txout == di->txin) { -+ DMA_ERROR(("%s: dma_txfast: Out-of-DMA descriptors" -+ " (txin %d txout %d nsegs %d)\n", __FUNCTION__, -+ di->txin, di->txout, nsegs)); -+ goto outoftxd; -+ } -+ } -+ if (segsadd && DMASGLIST_ENAB) { -+ map->nsegs += segsadd; -+ } -+ -+ /* See above. No need to loop over individual buffers */ -+ if (DMASGLIST_ENAB) { -+ break; -+ } -+ } -+ -+ /* if last txd eof not set, fix it */ -+ if (!(flags & D64_CTRL1_EOF)) { -+ W_SM(&di->txd64[PREVTXD(txout)].ctrl1, -+ BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF)); -+ } -+ -+ /* save the packet */ -+ di->txp[PREVTXD(txout)] = p0; -+ -+ /* bump the tx descriptor index */ -+ di->txout = txout; -+ -+ /* Spin lock to prevent TX discriptor protocol errors when using SG lists */ -+ spin_lock(&di->des_lock); -+ spin_unlock(&di->des_lock); -+ -+ /* kick the chip */ -+ if (commit) { -+ W_REG(di->osh, &di->d64txregs->ptr, di->xmtptrbase + I2B(txout, dma64dd_t)); -+ } -+ -+ /* tx flow control */ -+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ return (0); -+ -+outoftxd: -+ DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name)); -+ PKTFREE(di->osh, p0, TRUE); -+ di->hnddma.txavail = 0; -+ di->hnddma.txnobuf++; -+ return (-1); -+} -+ -+/* -+ * Reclaim next completed txd (txds if using chained buffers) in the range -+ * specified and return associated packet. -+ * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be -+ * transmitted as noted by the hardware "CurrDescr" pointer. -+ * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be -+ * transfered by the DMA as noted by the hardware "ActiveDescr" pointer. -+ * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and -+ * return associated packet regardless of the value of hardware pointers. -+ */ -+static void * BCMFASTPATH -+dma64_getnexttxp(dma_info_t *di, txd_range_t range) -+{ -+ uint16 start, end, i; -+ uint16 active_desc; -+ void *txp; -+ -+ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, -+ (range == HNDDMA_RANGE_ALL) ? "all" : -+ ((range == HNDDMA_RANGE_TRANSMITTED) ? "transmitted" : "transfered"))); -+ -+ if (di->ntxd == 0) { -+ return (NULL); -+ } -+ -+ txp = NULL; -+ -+ start = di->txin; -+ if (range == HNDDMA_RANGE_ALL) { -+ end = di->txout; -+ } else { -+ dma64regs_t *dregs = di->d64txregs; -+ -+ if (di->txin == di->xs0cd) { -+ end = (uint16)(B2I(((R_REG(di->osh, &dregs->status0) & D64_XS0_CD_MASK) - -+ di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t)); -+ di->xs0cd = end; -+ } else { -+ end = di->xs0cd; -+ } -+ -+ if (range == HNDDMA_RANGE_TRANSFERED) { -+ active_desc = (uint16)(R_REG(di->osh, &dregs->status1) & D64_XS1_AD_MASK); -+ active_desc = (active_desc - di->xmtptrbase) & D64_XS0_CD_MASK; -+ active_desc = B2I(active_desc, dma64dd_t); -+ if (end != active_desc) { -+ end = PREVTXD(active_desc); -+ } -+ } -+ } -+ -+ if ((start == 0) && (end > di->txout)) { -+ goto bogus; -+ } -+ -+ for (i = start; i != end && !txp; i = NEXTTXD(i)) { -+ dmaaddr_t pa; -+ hnddma_seg_map_t *map = NULL; -+ uint size, j, nsegs; -+ -+#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH -+ prefetch_range(di->txp[NEXTTXD(i)], SKB_PREFETCH_LEN); -+#endif -+ -+ PHYSADDRLOSET(pa, (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) - di->dataoffsetlow)); -+ PHYSADDRHISET(pa, (BUS_SWAP32(R_SM(&di->txd64[i].addrhigh)) - di->dataoffsethigh)); -+ -+ if (DMASGLIST_ENAB) { -+ map = &di->txp_dmah[i]; -+ size = map->origsize; -+ nsegs = map->nsegs; -+ if (nsegs > (uint)NTXDACTIVE(i, end)) { -+ di->xs0cd = i; -+ break; -+ } -+ } else { -+ size = (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) & D64_CTRL2_BC_MASK); -+ nsegs = 1; -+ } -+ -+ for (j = nsegs; j > 0; j--) { -+ W_SM(&di->txd64[i].addrlow, 0xdeadbeef); -+ W_SM(&di->txd64[i].addrhigh, 0xdeadbeef); -+ -+ txp = di->txp[i]; -+ di->txp[i] = NULL; -+ if (j > 1) { -+ i = NEXTTXD(i); -+ } -+ } -+#ifndef CONFIG_BCM_IPROC_GMAC_ACP -+ DMA_UNMAP(di->osh, pa, size, DMA_TX, txp, map); -+#endif /* ! CONFIG_BCM_IPROC_GMAC_ACP */ -+ } -+ -+ di->txin = i; -+ -+ /* tx flow control */ -+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ return (txp); -+ -+bogus: -+ DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", -+ start, end, di->txout, forceall)); -+ return (NULL); -+} -+ -+static void * BCMFASTPATH -+dma64_getnextrxp(dma_info_t *di, bool forceall) -+{ -+ uint16 i, curr; -+ void *rxp; -+ dmaaddr_t pa; -+ -+ /* if forcing, dma engine must be disabled */ -+ ASSERT(!forceall || !dma64_rxenabled(di)); -+ -+ i = di->rxin; -+ -+ /* return if no packets posted */ -+ if (i == di->rxout) { -+ return (NULL); -+ } -+ -+#ifdef CONFIG_BCM_IPROC_GMAC_PREFETCH -+ prefetch_range(di->rxp[NEXTRXD(i)], SKB_PREFETCH_LEN); -+#endif -+ -+ if (di->rxin == di->rs0cd) { -+ curr = (uint16)B2I(((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) - -+ di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t); -+ di->rs0cd = curr; -+ } else { -+ curr = di->rs0cd; -+ } -+ -+ /* ignore curr if forceall */ -+ if (!forceall && (i == curr)) { -+ return (NULL); -+ } -+ -+ /* get the packet pointer that corresponds to the rx descriptor */ -+ rxp = di->rxp[i]; -+ ASSERT(rxp); -+ di->rxp[i] = NULL; -+ -+ PHYSADDRLOSET(pa, (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) - di->dataoffsetlow)); -+ PHYSADDRHISET(pa, (BUS_SWAP32(R_SM(&di->rxd64[i].addrhigh)) - di->dataoffsethigh)); -+ -+ /* clear this packet from the descriptor ring */ -+#ifndef CONFIG_BCM_IPROC_GMAC_ACP -+ DMA_UNMAP(di->osh, pa, -+ di->rxbufsize, DMA_RX, rxp, &di->rxp_dmah[i]); -+#endif /* ! CONFIG_BCM_IPROC_GMAC_ACP */ -+ -+ W_SM(&di->rxd64[i].addrlow, 0xdeadbeef); -+ W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef); -+ -+ di->rxin = NEXTRXD(i); -+ -+ return (rxp); -+} -+ -+static bool -+_dma64_addrext(osl_t *osh, dma64regs_t *dma64regs) -+{ -+ uint32 w; -+ OR_REG(osh, &dma64regs->control, D64_XC_AE); -+ w = R_REG(osh, &dma64regs->control); -+ AND_REG(osh, &dma64regs->control, ~D64_XC_AE); -+ return ((w & D64_XC_AE) == D64_XC_AE); -+} -+ -+/* -+ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). -+ */ -+static void -+dma64_txrotate(dma_info_t *di) -+{ -+ uint16 ad; -+ uint nactive; -+ uint rot; -+ uint16 old, new; -+ uint32 w; -+ uint16 first, last; -+ -+ ASSERT(dma64_txsuspendedidle(di)); -+ -+ nactive = _dma_txactive(di); -+ ad = B2I((((R_REG(di->osh, &di->d64txregs->status1) & D64_XS1_AD_MASK) -+ - di->xmtptrbase) & D64_XS1_AD_MASK), dma64dd_t); -+ rot = TXD(ad - di->txin); -+ -+ ASSERT(rot < di->ntxd); -+ -+ /* full-ring case is a lot harder - don't worry about this */ -+ if (rot >= (di->ntxd - nactive)) { -+ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); -+ return; -+ } -+ -+ first = di->txin; -+ last = PREVTXD(di->txout); -+ -+ /* move entries starting at last and moving backwards to first */ -+ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { -+ new = TXD(old + rot); -+ -+ /* -+ * Move the tx dma descriptor. -+ * EOT is set only in the last entry in the ring. -+ */ -+ w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl1)) & ~D64_CTRL1_EOT; -+ if (new == (di->ntxd - 1)) { -+ w |= D64_CTRL1_EOT; -+ } -+ W_SM(&di->txd64[new].ctrl1, BUS_SWAP32(w)); -+ -+ w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl2)); -+ W_SM(&di->txd64[new].ctrl2, BUS_SWAP32(w)); -+ -+ W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow)); -+ W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh)); -+ -+ /* zap the old tx dma descriptor address field */ -+ W_SM(&di->txd64[old].addrlow, BUS_SWAP32(0xdeadbeef)); -+ W_SM(&di->txd64[old].addrhigh, BUS_SWAP32(0xdeadbeef)); -+ -+ /* move the corresponding txp[] entry */ -+ ASSERT(di->txp[new] == NULL); -+ di->txp[new] = di->txp[old]; -+ -+ /* Move the map */ -+ if (DMASGLIST_ENAB) { -+ bcopy(&di->txp_dmah[old], &di->txp_dmah[new], sizeof(hnddma_seg_map_t)); -+ bzero(&di->txp_dmah[old], sizeof(hnddma_seg_map_t)); -+ } -+ -+ di->txp[old] = NULL; -+ } -+ -+ /* update txin and txout */ -+ di->txin = ad; -+ di->txout = TXD(di->txout + rot); -+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ /* kick the chip */ -+ W_REG(di->osh, &di->d64txregs->ptr, di->xmtptrbase + I2B(di->txout, dma64dd_t)); -+} -+ -+uint -+BCMATTACHFN(dma_addrwidth)(si_t *sih, void *dmaregs) -+{ -+ dma32regs_t *dma32regs; -+ osl_t *osh; -+ -+ osh = si_osh(sih); -+ -+ /* Perform 64-bit checks only if we want to advertise 64-bit (> 32bit) capability) */ -+ /* DMA engine is 64-bit capable */ -+ if ((si_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64) { -+ /* backplane are 64-bit capable */ -+ if (si_backplane64(sih)) { -+ /* If bus is System Backplane or PCIE then we can access 64-bits */ -+ if ((BUSTYPE(sih->bustype) == SI_BUS) || -+ ((BUSTYPE(sih->bustype) == PCI_BUS) && -+ ((sih->buscoretype == PCIE_CORE_ID) || -+ (sih->buscoretype == PCIE2_CORE_ID)))) { -+ return (DMADDRWIDTH_64); -+ } -+ } -+ -+ /* DMA64 is always 32-bit capable, AE is always TRUE */ -+ ASSERT(_dma64_addrext(osh, (dma64regs_t *)dmaregs)); -+ -+ return (DMADDRWIDTH_32); -+ } -+ -+ /* Start checking for 32-bit / 30-bit addressing */ -+ dma32regs = (dma32regs_t *)dmaregs; -+ -+ /* For System Backplane, PCIE bus or addrext feature, 32-bits ok */ -+ if ((BUSTYPE(sih->bustype) == SI_BUS) || -+ ((BUSTYPE(sih->bustype) == PCI_BUS) && -+ ((sih->buscoretype == PCIE_CORE_ID) || -+ (sih->buscoretype == PCIE2_CORE_ID))) || -+ (_dma32_addrext(osh, dma32regs))) { -+ return (DMADDRWIDTH_32); -+ } -+ -+ /* Fallthru */ -+ return (DMADDRWIDTH_30); -+} -+ -+static int -+_dma_pktpool_set(dma_info_t *di, pktpool_t *pool) -+{ -+ ASSERT(di); -+ ASSERT(di->pktpool == NULL); -+ di->pktpool = pool; -+ return 0; -+} -+ -+static bool -+_dma_rxtx_error(dma_info_t *di, bool istx) -+{ -+ uint32 status1 = 0; -+ uint16 curr; -+ -+ if (DMA64_ENAB(di) && DMA64_MODE(di)) { -+ if (istx) { -+ status1 = R_REG(di->osh, &di->d64txregs->status1); -+ -+ if ((status1 & D64_XS1_XE_MASK) != D64_XS1_XE_NOERR) { -+ return TRUE; -+ } else if (si_coreid(di->sih) == GMAC_CORE_ID && si_corerev(di->sih) >= 4) { -+ curr = (uint16)(B2I(((R_REG(di->osh, &di->d64txregs->status0) & -+ D64_XS0_CD_MASK) - di->xmtptrbase) & -+ D64_XS0_CD_MASK, dma64dd_t)); -+ -+ if (NTXDACTIVE(di->txin, di->txout) != 0 && -+ curr == di->xs0cd_snapshot) { -+ -+ /* suspicious */ -+ return TRUE; -+ } -+ di->xs0cd_snapshot = di->xs0cd = curr; -+ -+ return FALSE; -+ } else { -+ return FALSE; -+ } -+ } -+ else { -+ -+ status1 = R_REG(di->osh, &di->d64rxregs->status1); -+ -+ if ((status1 & D64_RS1_RE_MASK) != D64_RS1_RE_NOERR) { -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+ } -+ } else if (DMA32_ENAB(di)) { -+ return FALSE; -+ } else { -+ ASSERT(0); -+ return FALSE; -+ } -+ -+} -+ -+void -+_dma_burstlen_set(dma_info_t *di, uint8 rxburstlen, uint8 txburstlen) -+{ -+ di->rxburstlen = rxburstlen; -+ di->txburstlen = txburstlen; -+} -+ -+void -+_dma_param_set(dma_info_t *di, uint16 paramid, uint16 paramval) -+{ -+ switch (paramid) { -+ case HNDDMA_PID_TX_MULTI_OUTSTD_RD: -+ di->txmultioutstdrd = (uint8)paramval; -+ break; -+ -+ case HNDDMA_PID_TX_PREFETCH_CTL: -+ di->txprefetchctl = (uint8)paramval; -+ break; -+ -+ case HNDDMA_PID_TX_PREFETCH_THRESH: -+ di->txprefetchthresh = (uint8)paramval; -+ break; -+ -+ case HNDDMA_PID_TX_BURSTLEN: -+ di->txburstlen = (uint8)paramval; -+ break; -+ -+ case HNDDMA_PID_RX_PREFETCH_CTL: -+ di->rxprefetchctl = (uint8)paramval; -+ break; -+ -+ case HNDDMA_PID_RX_PREFETCH_THRESH: -+ di->rxprefetchthresh = (uint8)paramval; -+ break; -+ -+ case HNDDMA_PID_RX_BURSTLEN: -+ di->rxburstlen = (uint8)paramval; -+ break; -+ -+ default: -+ break; -+ } -+} -+ -+static bool -+_dma_glom_enable(dma_info_t *di, uint32 val) -+{ -+ dma64regs_t *dregs = di->d64rxregs; -+ bool ret = TRUE; -+ if (val) { -+ OR_REG(di->osh, &dregs->control, D64_RC_GE); -+ if (!(R_REG(di->osh, &dregs->control) & D64_RC_GE)) -+ ret = FALSE; -+ } else { -+ AND_REG(di->osh, &dregs->control, ~D64_RC_GE); -+ } -+ return ret; -+} -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/hr2_erom.c b/drivers/net/ethernet/broadcom/gmac/src/shared/hr2_erom.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/hr2_erom.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/hr2_erom.c 2017-11-09 17:53:44.051300000 +0800 -@@ -0,0 +1,64 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet -+ * Helix4 sudo EROM -+ * -+ */ -+#include -+ -+uint32 hr2_erom[] = { -+ //#define CC_CORE_ID 0x800 /* chipcommon core */ -+ 0x4bf80001, 0x2a004201, 0x18000005, 0x181200c5, -+ //#define NS_CCB_CORE_ID 0x50b /* ChipcommonB core */ -+ 0x4bf50b01, 0x01000201, 0x18001005, 0x18002005, 0x18003005, 0x18004005, 0x18005005, 0x18006005, 0x18007005, 0x18008005, 0x18009005, -+ //#define NS_DMA_CORE_ID 0x502 /* DMA core */ -+ 0x4bf50201, 0x01004211, 0x00000003, 0x1802c005, 0x181140c5, -+ //#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ -+ 0x4bf82d01, 0x04004211, 0x00000103, 0x18022005, 0x181100c5, -+ //#define NS_PCIEG2_CORE_ID 0x501 /* PCIE Gen 2 core */ -+ 0x4bf50101, 0x01084411, 0x00000503, 0x18012005, 0x08000135, 0x08000000, 0x181010c5, 0x1810a185, -+ 0x4bf50101, 0x01084411, 0x00000603, 0x18013005, 0x40000135, 0x08000000, 0x181020c5, 0x1810b185, -+ 0x4bf50101, 0x01084411, 0x00000703, 0x18014005, 0x48000135, 0x08000000, 0x181030c5, 0x1810c185, -+ //#define ARMCA9_CORE_ID 0x510 /* ARM Cortex A9 core (ihost) */ -+ 0x4bf51001, 0x01104611, 0x00000803, 0x1800b005, 0x1800c005, 0x19000135, 0x00020000, 0x19020235, 0x00003000, 0x181000c5, 0x18106185, 0x18107285, -+ //#define NS_USB20_CORE_ID 0x504 /* USB2.0 core */ -+ 0x4bf50401, 0x01004211, 0x00000903, 0x18021005, 0x18022005, 0x181150c5, -+ //#define NS_USB30_CORE_ID 0x505 /* USB3.0 core */ -+ 0x4bf50501, 0x01004211, 0x00000a03, 0x18023005, 0x181050c5, -+ //#define NS_SDIO3_CORE_ID 0x503 /* SDIO3 core */ -+ 0x4bf50301, 0x01004211, 0x00000b03, 0x18020005, 0x181160c5, -+ //#define I2S_CORE_ID 0x834 /* I2S core */ -+ 0x4bf83401, 0x03004211, 0x00000c03, 0x1802a005, 0x181170c5, -+ //#define NS_A9JTAG_CORE_ID 0x506 /* ARM Cortex A9 JTAG core */ -+ 0x4bf50601, 0x01084211, 0x00000d03, 0x18210035, 0x00010000, 0x181180c5, 0x1811c085, -+ //#define NS_DDR23_CORE_ID 0x507 /* Denali DDR2/DDR3 memory controller */ -+ 0x4bf50701, 0x01100601, 0x18010005, 0x00000135, 0x08000000, 0x80000135, 0x30000000, 0xb0000235, 0x10000000, 0x18108185, 0x18109285, -+ //#define NS_ROM_CORE_ID 0x508 /* ROM core */ -+ 0x4bf50801, 0x01080201, 0xfffd0035, 0x00030000, 0x1810d085, -+ //#define NS_NAND_CORE_ID 0x509 /* NAND flash controller core */ -+ 0x4bf50901, 0x01080401, 0x18028005, 0x1c000135, 0x02000000, 0x1811a185, -+ //#define NS_QSPI_CORE_ID 0x50a /* SPI flash controller core */ -+ 0x4bf50a01, 0x01080401, 0x18029005, 0x1e000135, 0x02000000, 0x1811b185, -+ //#define EROM_CORE_ID 0x366 /* EROM core ID */ -+ 0x43b36601, 0x00000201, 0x18130005, -+ 0x43b13501, 0x00080201, 0x18000075, 0x00010000, 0x18121085, -+ 0x43b30101, 0x01000201, 0x1a000035, 0x00100000, -+ 0x43bfff01, 0x00280a01, 0x10000035, 0x08000000, 0x18011005, 0x18015035, 0x0000b000, 0x1802b105, 0x1802d135, 0x000d3000, 0x18104105, 0x1810e215, -+ 0x18119205, 0x1811d235, 0x00003000, 0x18122335, 0x0000e000, 0x18131305, 0x18137335, 0x000d9000, 0x18220335, 0x000de000, 0x19023335, -+ 0x00fdd000, 0x1a100335, 0x01f00000, 0x20000435, 0x20000000, 0x50000435, 0x30000000, 0xc0000435, 0x3ffd0000, 0x18132085, 0x18133185, -+ 0x18134285, 0x18135385, 0x18136485, -+ 0x0000000f -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/hr2_erom.h b/drivers/net/ethernet/broadcom/gmac/src/shared/hr2_erom.h ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/hr2_erom.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/hr2_erom.h 2017-11-09 17:53:44.052298000 +0800 -@@ -0,0 +1,26 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet -+ * Helix4 sudo EROM -+ * -+ */ -+ -+#ifndef _hr2_erom_h_ -+#define _hr2_erom_h_ -+ -+extern uint32 hr2_erom[]; -+ -+#endif //_hr2_erom_h_ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/hr3_erom.c b/drivers/net/ethernet/broadcom/gmac/src/shared/hr3_erom.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/hr3_erom.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/hr3_erom.c 2017-11-09 17:53:44.053293000 +0800 -@@ -0,0 +1,28 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet -+ * Hurricane3 sudo EROM -+ * -+ */ -+#include -+ -+uint32 hr3_erom[] = { -+ //#define CC_CORE_ID 0x800 /* chipcommon core */ -+ 0x4bf80001, 0x2a004201, 0x18000005, 0x181200c5, -+ //#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ -+ 0x4bf82d01, 0x04004211, 0x00000103, 0x18042005, 0x181100c5, -+ 0x0000000f -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/hr3_erom.h b/drivers/net/ethernet/broadcom/gmac/src/shared/hr3_erom.h ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/hr3_erom.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/hr3_erom.h 2017-11-09 17:53:44.054288000 +0800 -@@ -0,0 +1,26 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet -+ * Hurricane3 sudo EROM -+ * -+ */ -+ -+#ifndef _hr3_erom_h_ -+#define _hr3_erom_h_ -+ -+extern uint32 hr3_erom[]; -+ -+#endif /* _hr3_erom_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/hx4_erom.c b/drivers/net/ethernet/broadcom/gmac/src/shared/hx4_erom.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/hx4_erom.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/hx4_erom.c 2017-11-09 17:53:44.054324000 +0800 -@@ -0,0 +1,65 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet -+ * Helix4 sudo EROM -+ * -+ */ -+#include -+ -+uint32 hx4_erom[] = { -+ //#define CC_CORE_ID 0x800 /* chipcommon core */ -+ 0x4bf80001, 0x2a004201, 0x18000005, 0x181200c5, -+ //#define NS_CCB_CORE_ID 0x50b /* ChipcommonB core */ -+ 0x4bf50b01, 0x01000201, 0x18001005, 0x18002005, 0x18003005, 0x18004005, 0x18005005, 0x18006005, 0x18007005, 0x18008005, 0x18009005, -+ //#define NS_DMA_CORE_ID 0x502 /* DMA core */ -+ 0x4bf50201, 0x01004211, 0x00000003, 0x1802c005, 0x181140c5, -+ //#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ -+ 0x4bf82d01, 0x04004211, 0x00000103, 0x18022005, 0x181100c5, -+ 0x4bf82d01, 0x04004211, 0x00000203, 0x18023005, 0x181110c5, -+ //#define NS_PCIEG2_CORE_ID 0x501 /* PCIE Gen 2 core */ -+ 0x4bf50101, 0x01084411, 0x00000503, 0x18012005, 0x08000135, 0x08000000, 0x181010c5, 0x1810a185, -+ 0x4bf50101, 0x01084411, 0x00000603, 0x18013005, 0x40000135, 0x08000000, 0x181020c5, 0x1810b185, -+ 0x4bf50101, 0x01084411, 0x00000703, 0x18014005, 0x48000135, 0x08000000, 0x181030c5, 0x1810c185, -+ //#define ARMCA9_CORE_ID 0x510 /* ARM Cortex A9 core (ihost) */ -+ 0x4bf51001, 0x01104611, 0x00000803, 0x1800b005, 0x1800c005, 0x19000135, 0x00020000, 0x19020235, 0x00003000, 0x181000c5, 0x18106185, 0x18107285, -+ //#define NS_USB20_CORE_ID 0x504 /* USB2.0 core */ -+ 0x4bf50401, 0x01004211, 0x00000903, 0x18021005, 0x18022005, 0x181150c5, -+ //#define NS_USB30_CORE_ID 0x505 /* USB3.0 core */ -+ 0x4bf50501, 0x01004211, 0x00000a03, 0x18023005, 0x181050c5, -+ //#define NS_SDIO3_CORE_ID 0x503 /* SDIO3 core */ -+ 0x4bf50301, 0x01004211, 0x00000b03, 0x18020005, 0x181160c5, -+ //#define I2S_CORE_ID 0x834 /* I2S core */ -+ 0x4bf83401, 0x03004211, 0x00000c03, 0x1802a005, 0x181170c5, -+ //#define NS_A9JTAG_CORE_ID 0x506 /* ARM Cortex A9 JTAG core */ -+ 0x4bf50601, 0x01084211, 0x00000d03, 0x18210035, 0x00010000, 0x181180c5, 0x1811c085, -+ //#define NS_DDR23_CORE_ID 0x507 /* Denali DDR2/DDR3 memory controller */ -+ 0x4bf50701, 0x01100601, 0x18010005, 0x00000135, 0x08000000, 0x80000135, 0x30000000, 0xb0000235, 0x10000000, 0x18108185, 0x18109285, -+ //#define NS_ROM_CORE_ID 0x508 /* ROM core */ -+ 0x4bf50801, 0x01080201, 0xfffd0035, 0x00030000, 0x1810d085, -+ //#define NS_NAND_CORE_ID 0x509 /* NAND flash controller core */ -+ 0x4bf50901, 0x01080401, 0x18028005, 0x1c000135, 0x02000000, 0x1811a185, -+ //#define NS_QSPI_CORE_ID 0x50a /* SPI flash controller core */ -+ 0x4bf50a01, 0x01080401, 0x18029005, 0x1e000135, 0x02000000, 0x1811b185, -+ //#define EROM_CORE_ID 0x366 /* EROM core ID */ -+ 0x43b36601, 0x00000201, 0x18130005, -+ 0x43b13501, 0x00080201, 0x18000075, 0x00010000, 0x18121085, -+ 0x43b30101, 0x01000201, 0x1a000035, 0x00100000, -+ 0x43bfff01, 0x00280a01, 0x10000035, 0x08000000, 0x18011005, 0x18015035, 0x0000b000, 0x1802b105, 0x1802d135, 0x000d3000, 0x18104105, 0x1810e215, -+ 0x18119205, 0x1811d235, 0x00003000, 0x18122335, 0x0000e000, 0x18131305, 0x18137335, 0x000d9000, 0x18220335, 0x000de000, 0x19023335, -+ 0x00fdd000, 0x1a100335, 0x01f00000, 0x20000435, 0x20000000, 0x50000435, 0x30000000, 0xc0000435, 0x3ffd0000, 0x18132085, 0x18133185, -+ 0x18134285, 0x18135385, 0x18136485, -+ 0x0000000f -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/hx4_erom.h b/drivers/net/ethernet/broadcom/gmac/src/shared/hx4_erom.h ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/hx4_erom.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/hx4_erom.h 2017-11-09 17:53:44.055299000 +0800 -@@ -0,0 +1,26 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet -+ * Helix4 sudo EROM -+ * -+ */ -+ -+#ifndef _hx4_erom_h_ -+#define _hx4_erom_h_ -+ -+extern uint32 hx4_erom[]; -+ -+#endif //_hx4_erom_h_ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/kt2_erom.c b/drivers/net/ethernet/broadcom/gmac/src/shared/kt2_erom.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/kt2_erom.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/kt2_erom.c 2017-11-09 17:53:44.056295000 +0800 -@@ -0,0 +1,65 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet -+ * Helix4 sudo EROM -+ * -+ */ -+#include -+ -+uint32 kt2_erom[] = { -+ //#define CC_CORE_ID 0x800 /* chipcommon core */ -+ 0x4bf80001, 0x2a004201, 0x18000005, 0x181200c5, -+ //#define NS_CCB_CORE_ID 0x50b /* ChipcommonB core */ -+ 0x4bf50b01, 0x01000201, 0x18001005, 0x18002005, 0x18003005, 0x18004005, 0x18005005, 0x18006005, 0x18007005, 0x18008005, 0x18009005, -+ //#define NS_DMA_CORE_ID 0x502 /* DMA core */ -+ 0x4bf50201, 0x01004211, 0x00000003, 0x1802c005, 0x181140c5, -+ //#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ -+ 0x4bf82d01, 0x04004211, 0x00000103, 0x18022005, 0x181100c5, -+ 0x4bf82d01, 0x04004211, 0x00000203, 0x18023005, 0x181110c5, -+ //#define NS_PCIEG2_CORE_ID 0x501 /* PCIE Gen 2 core */ -+ 0x4bf50101, 0x01084411, 0x00000503, 0x18012005, 0x08000135, 0x08000000, 0x181010c5, 0x1810a185, -+ 0x4bf50101, 0x01084411, 0x00000603, 0x18013005, 0x40000135, 0x08000000, 0x181020c5, 0x1810b185, -+ 0x4bf50101, 0x01084411, 0x00000703, 0x18014005, 0x48000135, 0x08000000, 0x181030c5, 0x1810c185, -+ //#define ARMCA9_CORE_ID 0x510 /* ARM Cortex A9 core (ihost) */ -+ 0x4bf51001, 0x01104611, 0x00000803, 0x1800b005, 0x1800c005, 0x19000135, 0x00020000, 0x19020235, 0x00003000, 0x181000c5, 0x18106185, 0x18107285, -+ //#define NS_USB20_CORE_ID 0x504 /* USB2.0 core */ -+ 0x4bf50401, 0x01004211, 0x00000903, 0x18021005, 0x18022005, 0x181150c5, -+ //#define NS_USB30_CORE_ID 0x505 /* USB3.0 core */ -+ 0x4bf50501, 0x01004211, 0x00000a03, 0x18023005, 0x181050c5, -+ //#define NS_SDIO3_CORE_ID 0x503 /* SDIO3 core */ -+ 0x4bf50301, 0x01004211, 0x00000b03, 0x18020005, 0x181160c5, -+ //#define I2S_CORE_ID 0x834 /* I2S core */ -+ 0x4bf83401, 0x03004211, 0x00000c03, 0x1802a005, 0x181170c5, -+ //#define NS_A9JTAG_CORE_ID 0x506 /* ARM Cortex A9 JTAG core */ -+ 0x4bf50601, 0x01084211, 0x00000d03, 0x18210035, 0x00010000, 0x181180c5, 0x1811c085, -+ //#define NS_DDR23_CORE_ID 0x507 /* Denali DDR2/DDR3 memory controller */ -+ 0x4bf50701, 0x01100601, 0x18010005, 0x00000135, 0x08000000, 0x80000135, 0x30000000, 0xb0000235, 0x10000000, 0x18108185, 0x18109285, -+ //#define NS_ROM_CORE_ID 0x508 /* ROM core */ -+ 0x4bf50801, 0x01080201, 0xfffd0035, 0x00030000, 0x1810d085, -+ //#define NS_NAND_CORE_ID 0x509 /* NAND flash controller core */ -+ 0x4bf50901, 0x01080401, 0x18028005, 0x1c000135, 0x02000000, 0x1811a185, -+ //#define NS_QSPI_CORE_ID 0x50a /* SPI flash controller core */ -+ 0x4bf50a01, 0x01080401, 0x18029005, 0x1e000135, 0x02000000, 0x1811b185, -+ //#define EROM_CORE_ID 0x366 /* EROM core ID */ -+ 0x43b36601, 0x00000201, 0x18130005, -+ 0x43b13501, 0x00080201, 0x18000075, 0x00010000, 0x18121085, -+ 0x43b30101, 0x01000201, 0x1a000035, 0x00100000, -+ 0x43bfff01, 0x00280a01, 0x10000035, 0x08000000, 0x18011005, 0x18015035, 0x0000b000, 0x1802b105, 0x1802d135, 0x000d3000, 0x18104105, 0x1810e215, -+ 0x18119205, 0x1811d235, 0x00003000, 0x18122335, 0x0000e000, 0x18131305, 0x18137335, 0x000d9000, 0x18220335, 0x000de000, 0x19023335, -+ 0x00fdd000, 0x1a100335, 0x01f00000, 0x20000435, 0x20000000, 0x50000435, 0x30000000, 0xc0000435, 0x3ffd0000, 0x18132085, 0x18133185, -+ 0x18134285, 0x18135385, 0x18136485, -+ 0x0000000f -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/kt2_erom.h b/drivers/net/ethernet/broadcom/gmac/src/shared/kt2_erom.h ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/kt2_erom.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/kt2_erom.h 2017-11-09 17:53:44.057293000 +0800 -@@ -0,0 +1,26 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet -+ * Helix4 sudo EROM -+ * -+ */ -+ -+#ifndef _kt2_erom_h_ -+#define _kt2_erom_h_ -+ -+extern uint32 kt2_erom[]; -+ -+#endif //_kt2_erom_h_ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/linux_osl.c b/drivers/net/ethernet/broadcom/gmac/src/shared/linux_osl.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/linux_osl.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/linux_osl.c 2017-11-09 17:53:44.058299000 +0800 -@@ -0,0 +1,1266 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Linux OS Independent Layer -+ * -+ * $Id: linux_osl.c 322208 2012-03-20 01:53:23Z $ -+ */ -+ -+#define LINUX_PORT -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef mips -+#include -+#endif /* mips */ -+#include -+ -+ -+#include -+#include -+ -+#define PCI_CFG_RETRY 10 -+ -+#define OS_HANDLE_MAGIC 0x1234abcd /* Magic # to recognize osh */ -+#define BCM_MEM_FILENAME_LEN 24 /* Mem. filename length */ -+ -+#ifdef DHD_USE_STATIC_BUF -+#define STATIC_BUF_MAX_NUM 16 -+#define STATIC_BUF_SIZE (PAGE_SIZE*2) -+#define STATIC_BUF_TOTAL_LEN (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE) -+ -+typedef struct bcm_static_buf { -+ struct semaphore static_sem; -+ unsigned char *buf_ptr; -+ unsigned char buf_use[STATIC_BUF_MAX_NUM]; -+} bcm_static_buf_t; -+ -+static bcm_static_buf_t *bcm_static_buf = 0; -+ -+#define STATIC_PKT_MAX_NUM 8 -+ -+typedef struct bcm_static_pkt { -+ struct sk_buff *skb_4k[STATIC_PKT_MAX_NUM]; -+ struct sk_buff *skb_8k[STATIC_PKT_MAX_NUM]; -+ struct semaphore osl_pkt_sem; -+ unsigned char pkt_use[STATIC_PKT_MAX_NUM * 2]; -+} bcm_static_pkt_t; -+ -+static bcm_static_pkt_t *bcm_static_skb = 0; -+#endif /* DHD_USE_STATIC_BUF */ -+ -+typedef struct bcm_mem_link { -+ struct bcm_mem_link *prev; -+ struct bcm_mem_link *next; -+ uint size; -+ int line; -+ void *osh; -+ char file[BCM_MEM_FILENAME_LEN]; -+} bcm_mem_link_t; -+ -+struct osl_info { -+ osl_pubinfo_t pub; -+ uint magic; -+ void *pdev; -+ atomic_t malloced; -+ atomic_t pktalloced; /* Number of allocated packet buffers */ -+ uint failed; -+ uint bustype; -+ bcm_mem_link_t *dbgmem_list; -+ spinlock_t dbgmem_lock; -+ spinlock_t pktalloc_lock; -+}; -+ -+#define OSL_PKTTAG_CLEAR(p) \ -+do { \ -+ struct sk_buff *s = (struct sk_buff *)(p); \ -+ ASSERT(OSL_PKTTAG_SZ == 32); \ -+ *(uint32 *)(&s->cb[0]) = 0; *(uint32 *)(&s->cb[4]) = 0; \ -+ *(uint32 *)(&s->cb[8]) = 0; *(uint32 *)(&s->cb[12]) = 0; \ -+ *(uint32 *)(&s->cb[16]) = 0; *(uint32 *)(&s->cb[20]) = 0; \ -+ *(uint32 *)(&s->cb[24]) = 0; *(uint32 *)(&s->cb[28]) = 0; \ -+} while (0) -+ -+/* PCMCIA attribute space access macros */ -+#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) -+struct pcmcia_dev { -+ dev_link_t link; /* PCMCIA device pointer */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) -+ dev_node_t node; /* PCMCIA node structure */ -+#endif -+ void *base; /* Mapped attribute memory window */ -+ size_t size; /* Size of window */ -+ void *drv; /* Driver data */ -+}; -+#endif /* defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) */ -+ -+/* Global ASSERT type flag */ -+uint32 g_assert_type = FALSE; -+ -+static int16 linuxbcmerrormap[] = -+{ 0, /* 0 */ -+ -EINVAL, /* BCME_ERROR */ -+ -EINVAL, /* BCME_BADARG */ -+ -EINVAL, /* BCME_BADOPTION */ -+ -EINVAL, /* BCME_NOTUP */ -+ -EINVAL, /* BCME_NOTDOWN */ -+ -EINVAL, /* BCME_NOTAP */ -+ -EINVAL, /* BCME_NOTSTA */ -+ -EINVAL, /* BCME_BADKEYIDX */ -+ -EINVAL, /* BCME_RADIOOFF */ -+ -EINVAL, /* BCME_NOTBANDLOCKED */ -+ -EINVAL, /* BCME_NOCLK */ -+ -EINVAL, /* BCME_BADRATESET */ -+ -EINVAL, /* BCME_BADBAND */ -+ -E2BIG, /* BCME_BUFTOOSHORT */ -+ -E2BIG, /* BCME_BUFTOOLONG */ -+ -EBUSY, /* BCME_BUSY */ -+ -EINVAL, /* BCME_NOTASSOCIATED */ -+ -EINVAL, /* BCME_BADSSIDLEN */ -+ -EINVAL, /* BCME_OUTOFRANGECHAN */ -+ -EINVAL, /* BCME_BADCHAN */ -+ -EFAULT, /* BCME_BADADDR */ -+ -ENOMEM, /* BCME_NORESOURCE */ -+ -EOPNOTSUPP, /* BCME_UNSUPPORTED */ -+ -EMSGSIZE, /* BCME_BADLENGTH */ -+ -EINVAL, /* BCME_NOTREADY */ -+ -EPERM, /* BCME_EPERM */ -+ -ENOMEM, /* BCME_NOMEM */ -+ -EINVAL, /* BCME_ASSOCIATED */ -+ -ERANGE, /* BCME_RANGE */ -+ -EINVAL, /* BCME_NOTFOUND */ -+ -EINVAL, /* BCME_WME_NOT_ENABLED */ -+ -EINVAL, /* BCME_TSPEC_NOTFOUND */ -+ -EINVAL, /* BCME_ACM_NOTSUPPORTED */ -+ -EINVAL, /* BCME_NOT_WME_ASSOCIATION */ -+ -EIO, /* BCME_SDIO_ERROR */ -+ -ENODEV, /* BCME_DONGLE_DOWN */ -+ -EINVAL, /* BCME_VERSION */ -+ -EIO, /* BCME_TXFAIL */ -+ -EIO, /* BCME_RXFAIL */ -+ -ENODEV, /* BCME_NODEVICE */ -+ -EINVAL, /* BCME_NMODE_DISABLED */ -+ -ENODATA, /* BCME_NONRESIDENT */ -+ -+/* When an new error code is added to bcmutils.h, add os -+ * specific error translation here as well -+ */ -+/* check if BCME_LAST changed since the last time this function was updated */ -+#if BCME_LAST != -42 -+#error "You need to add a OS error translation in the linuxbcmerrormap \ -+ for new error code defined in bcmutils.h" -+#endif -+}; -+ -+/* translate bcmerrors into linux errors */ -+int -+osl_error(int bcmerror) -+{ -+ if (bcmerror > 0) -+ bcmerror = 0; -+ else if (bcmerror < BCME_LAST) -+ bcmerror = BCME_ERROR; -+ -+ /* Array bounds covered by ASSERT in osl_attach */ -+ return linuxbcmerrormap[-bcmerror]; -+} -+ -+extern uint8* dhd_os_prealloc(void *osh, int section, int size); -+ -+EXPORT_SYMBOL(osl_attach); -+osl_t * -+osl_attach(void *pdev, uint bustype, bool pkttag) -+{ -+ osl_t *osh; -+ -+ osh = kmalloc(sizeof(osl_t), GFP_ATOMIC); -+ ASSERT(osh); -+ -+ bzero(osh, sizeof(osl_t)); -+ -+ /* Check that error map has the right number of entries in it */ -+ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); -+ -+ osh->magic = OS_HANDLE_MAGIC; -+ atomic_set(&osh->malloced, 0); -+ osh->failed = 0; -+ osh->dbgmem_list = NULL; -+ spin_lock_init(&(osh->dbgmem_lock)); -+ osh->pdev = pdev; -+ osh->pub.pkttag = pkttag; -+ osh->bustype = bustype; -+ -+ switch (bustype) { -+ case PCI_BUS: -+ case SI_BUS: -+ case PCMCIA_BUS: -+ osh->pub.mmbus = TRUE; -+ break; -+ case JTAG_BUS: -+ case SDIO_BUS: -+ case USB_BUS: -+ case SPI_BUS: -+ case RPC_BUS: -+ osh->pub.mmbus = FALSE; -+ break; -+ default: -+ ASSERT(FALSE); -+ break; -+ } -+ -+#if defined(DHD_USE_STATIC_BUF) -+ if (!bcm_static_buf) { -+ if (!(bcm_static_buf = (bcm_static_buf_t *)dhd_os_prealloc(osh, 3, STATIC_BUF_SIZE+ -+ STATIC_BUF_TOTAL_LEN))) { -+ printk("can not alloc static buf!\n"); -+ } -+ else -+ printk("alloc static buf at %x!\n", (unsigned int)bcm_static_buf); -+ -+ -+ sema_init(&bcm_static_buf->static_sem, 1); -+ -+ bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE; -+ } -+ -+ if (!bcm_static_skb) { -+ int i; -+ void *skb_buff_ptr = 0; -+ bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048); -+ skb_buff_ptr = dhd_os_prealloc(osh, 4, 0); -+ -+ bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *)*16); -+ for (i = 0; i < STATIC_PKT_MAX_NUM * 2; i++) -+ bcm_static_skb->pkt_use[i] = 0; -+ -+ sema_init(&bcm_static_skb->osl_pkt_sem, 1); -+ } -+#endif /* DHD_USE_STATIC_BUF */ -+ -+ spin_lock_init(&(osh->pktalloc_lock)); -+ -+#ifdef BCMDBG -+ if (pkttag) { -+ struct sk_buff *skb; -+ ASSERT(OSL_PKTTAG_SZ <= sizeof(skb->cb)); -+ } -+#endif -+ return osh; -+} -+ -+void -+osl_detach(osl_t *osh) -+{ -+ if (osh == NULL) -+ return; -+ -+#ifdef DHD_USE_STATIC_BUF -+ if (bcm_static_buf) { -+ bcm_static_buf = 0; -+ } -+ if (bcm_static_skb) { -+ bcm_static_skb = 0; -+ } -+#endif -+ -+ ASSERT(osh->magic == OS_HANDLE_MAGIC); -+ kfree(osh); -+} -+ -+static struct sk_buff *osl_alloc_skb(unsigned int len) -+{ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) -+ gfp_t flags = GFP_ATOMIC; -+ -+ return __dev_alloc_skb(len, flags); -+#else -+ return dev_alloc_skb(len); -+#endif -+} -+ -+/* Convert a driver packet to native(OS) packet -+ * In the process, packettag is zeroed out before sending up -+ * IP code depends on skb->cb to be setup correctly with various options -+ * In our case, that means it should be 0 -+ */ -+struct sk_buff * BCMFASTPATH -+osl_pkt_tonative(osl_t *osh, void *pkt) -+{ -+ struct sk_buff *nskb; -+ -+ if (osh->pub.pkttag) -+ OSL_PKTTAG_CLEAR(pkt); -+ -+ /* Decrement the packet counter */ -+ for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { -+ atomic_sub(PKTISCHAINED(nskb) ? PKTCCNT(nskb) : 1, &osh->pktalloced); -+ } -+ return (struct sk_buff *)pkt; -+} -+ -+/* Convert a native(OS) packet to driver packet. -+ * In the process, native packet is destroyed, there is no copying -+ * Also, a packettag is zeroed out -+ */ -+void * BCMFASTPATH -+osl_pkt_frmnative(osl_t *osh, void *pkt) -+{ -+ struct sk_buff *nskb; -+ -+ if (osh->pub.pkttag) -+ OSL_PKTTAG_CLEAR(pkt); -+ -+ /* Increment the packet counter */ -+ for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { -+ atomic_add(PKTISCHAINED(nskb) ? PKTCCNT(nskb) : 1, &osh->pktalloced); -+ } -+ return (void *)pkt; -+} -+ -+/* Return a new packet. zero out pkttag */ -+void * BCMFASTPATH -+osl_pktget(osl_t *osh, uint len) -+{ -+ struct sk_buff *skb; -+ -+ if ((skb = osl_alloc_skb(len))) { -+ skb_put(skb, len); -+ skb->priority = 0; -+ -+ atomic_inc(&osh->pktalloced); -+ } -+ -+ PKTSETCLINK(skb, NULL); -+ -+ return ((void*) skb); -+} -+ -+/* Free the driver packet. Free the tag if present */ -+void BCMFASTPATH -+osl_pktfree(osl_t *osh, void *p, bool send) -+{ -+ struct sk_buff *skb, *nskb; -+ -+ skb = (struct sk_buff*) p; -+ -+ if (send && osh->pub.tx_fn) -+ osh->pub.tx_fn(osh->pub.tx_ctx, p, 0); -+ -+ PKTDBG_TRACE(osh, (void *) skb, PKTLIST_PKTFREE); -+ -+ /* perversion: we use skb->next to chain multi-skb packets */ -+ while (skb) { -+ nskb = skb->next; -+ skb->next = NULL; -+ -+ -+ { -+ if (skb->destructor) -+ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if -+ * destructor exists -+ */ -+ dev_kfree_skb_any(skb); -+ else -+ /* can free immediately (even in_irq()) if destructor -+ * does not exist -+ */ -+ dev_kfree_skb(skb); -+ } -+ atomic_dec(&osh->pktalloced); -+ skb = nskb; -+ } -+} -+ -+#ifdef DHD_USE_STATIC_BUF -+void* -+osl_pktget_static(osl_t *osh, uint len) -+{ -+ int i = 0; -+ struct sk_buff *skb; -+ -+ if (len > (PAGE_SIZE*2)) { -+ printk("%s: attempt to allocate huge packet (0x%x)\n", __FUNCTION__, len); -+ return osl_pktget(osh, len); -+ } -+ -+ down(&bcm_static_skb->osl_pkt_sem); -+ -+ if (len <= PAGE_SIZE) { -+ for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { -+ if (bcm_static_skb->pkt_use[i] == 0) -+ break; -+ } -+ -+ if (i != STATIC_PKT_MAX_NUM) { -+ bcm_static_skb->pkt_use[i] = 1; -+ up(&bcm_static_skb->osl_pkt_sem); -+ skb = bcm_static_skb->skb_4k[i]; -+ skb->tail = skb->data + len; -+ skb->len = len; -+ return skb; -+ } -+ } -+ -+ -+ for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { -+ if (bcm_static_skb->pkt_use[i+STATIC_PKT_MAX_NUM] == 0) -+ break; -+ } -+ -+ if (i != STATIC_PKT_MAX_NUM) { -+ bcm_static_skb->pkt_use[i+STATIC_PKT_MAX_NUM] = 1; -+ up(&bcm_static_skb->osl_pkt_sem); -+ skb = bcm_static_skb->skb_8k[i]; -+ skb->tail = skb->data + len; -+ skb->len = len; -+ return skb; -+ } -+ -+ up(&bcm_static_skb->osl_pkt_sem); -+ printk("%s: all static pkt in use!\n", __FUNCTION__); -+ return osl_pktget(osh, len); -+} -+ -+void -+osl_pktfree_static(osl_t *osh, void *p, bool send) -+{ -+ int i; -+ -+ for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { -+ if (p == bcm_static_skb->skb_4k[i]) { -+ down(&bcm_static_skb->osl_pkt_sem); -+ bcm_static_skb->pkt_use[i] = 0; -+ up(&bcm_static_skb->osl_pkt_sem); -+ return; -+ } -+ } -+ -+ for (i = 0; i < STATIC_PKT_MAX_NUM; i++) { -+ if (p == bcm_static_skb->skb_8k[i]) { -+ down(&bcm_static_skb->osl_pkt_sem); -+ bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM] = 0; -+ up(&bcm_static_skb->osl_pkt_sem); -+ return; -+ } -+ } -+ -+ return osl_pktfree(osh, p, send); -+} -+#endif /* DHD_USE_STATIC_BUF */ -+ -+uint32 -+osl_pci_read_config(osl_t *osh, uint offset, uint size) -+{ -+ uint val = 0; -+ uint retry = PCI_CFG_RETRY; -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ -+ /* only 4byte access supported */ -+ ASSERT(size == 4); -+ -+ do { -+ pci_read_config_dword(osh->pdev, offset, &val); -+ if (val != 0xffffffff) -+ break; -+ } while (retry--); -+ -+#ifdef BCMDBG -+ if (retry < PCI_CFG_RETRY) -+ printk("PCI CONFIG READ access to %d required %d retries\n", offset, -+ (PCI_CFG_RETRY - retry)); -+#endif /* BCMDBG */ -+ -+ return (val); -+} -+ -+void -+osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) -+{ -+ uint retry = PCI_CFG_RETRY; -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ -+ /* only 4byte access supported */ -+ ASSERT(size == 4); -+ -+ do { -+ pci_write_config_dword(osh->pdev, offset, val); -+ if (offset != PCI_BAR0_WIN) -+ break; -+ if (osl_pci_read_config(osh, offset, size) == val) -+ break; -+ } while (retry--); -+ -+#ifdef BCMDBG -+ if (retry < PCI_CFG_RETRY) -+ printk("PCI CONFIG WRITE access to %d required %d retries\n", offset, -+ (PCI_CFG_RETRY - retry)); -+#endif /* BCMDBG */ -+} -+ -+/* return bus # for the pci device pointed by osh->pdev */ -+uint -+osl_pci_bus(osl_t *osh) -+{ -+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); -+ -+ return ((struct pci_dev *)osh->pdev)->bus->number; -+} -+ -+/* return slot # for the pci device pointed by osh->pdev */ -+uint -+osl_pci_slot(osl_t *osh) -+{ -+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); -+ -+ return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); -+} -+ -+/* return the pci device pointed by osh->pdev */ -+struct pci_dev * -+osl_pci_device(osl_t *osh) -+{ -+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); -+ -+ return osh->pdev; -+} -+ -+static void -+osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write) -+{ -+} -+ -+void -+osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size) -+{ -+ osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE); -+} -+ -+void -+osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size) -+{ -+ osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE); -+} -+ -+void * -+osl_malloc(osl_t *osh, uint size) -+{ -+ void *addr; -+ -+ /* only ASSERT if osh is defined */ -+ if (osh) -+ ASSERT(osh->magic == OS_HANDLE_MAGIC); -+ -+#ifdef DHD_USE_STATIC_BUF -+ if (bcm_static_buf) -+ { -+ int i = 0; -+ if ((size >= PAGE_SIZE)&&(size <= STATIC_BUF_SIZE)) -+ { -+ down(&bcm_static_buf->static_sem); -+ -+ for (i = 0; i < STATIC_BUF_MAX_NUM; i++) -+ { -+ if (bcm_static_buf->buf_use[i] == 0) -+ break; -+ } -+ -+ if (i == STATIC_BUF_MAX_NUM) -+ { -+ up(&bcm_static_buf->static_sem); -+ printk("all static buff in use!\n"); -+ goto original; -+ } -+ -+ bcm_static_buf->buf_use[i] = 1; -+ up(&bcm_static_buf->static_sem); -+ -+ bzero(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i, size); -+ if (osh) -+ atomic_add(size, &osh->malloced); -+ -+ return ((void *)(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i)); -+ } -+ } -+original: -+#endif /* DHD_USE_STATIC_BUF */ -+ -+ if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { -+ if (osh) -+ osh->failed++; -+ return (NULL); -+ } -+ if (osh) -+ atomic_add(size, &osh->malloced); -+ -+ return (addr); -+} -+ -+void -+osl_mfree(osl_t *osh, void *addr, uint size) -+{ -+#ifdef DHD_USE_STATIC_BUF -+ if (bcm_static_buf) -+ { -+ if ((addr > (void *)bcm_static_buf) && ((unsigned char *)addr -+ <= ((unsigned char *)bcm_static_buf + STATIC_BUF_TOTAL_LEN))) -+ { -+ int buf_idx = 0; -+ -+ buf_idx = ((unsigned char *)addr - bcm_static_buf->buf_ptr)/STATIC_BUF_SIZE; -+ -+ down(&bcm_static_buf->static_sem); -+ bcm_static_buf->buf_use[buf_idx] = 0; -+ up(&bcm_static_buf->static_sem); -+ -+ if (osh) { -+ ASSERT(osh->magic == OS_HANDLE_MAGIC); -+ atomic_sub(size, &osh->malloced); -+ } -+ return; -+ } -+ } -+#endif /* DHD_USE_STATIC_BUF */ -+ if (osh) { -+ ASSERT(osh->magic == OS_HANDLE_MAGIC); -+ atomic_sub(size, &osh->malloced); -+ } -+ kfree(addr); -+} -+ -+uint -+osl_malloced(osl_t *osh) -+{ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ return (atomic_read(&osh->malloced)); -+} -+ -+uint -+osl_malloc_failed(osl_t *osh) -+{ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ return (osh->failed); -+} -+ -+ -+uint -+osl_dma_consistent_align(void) -+{ -+ return (PAGE_SIZE); -+} -+ -+void* -+osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align_bits, uint *alloced, ulong *pap) -+{ -+#ifdef CONFIG_BCM_IPROC_GMAC_ACP -+ void *va; -+ uint16 align = (1 << align_bits); -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ -+ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, align)) -+ size += align; -+ *alloced = size; -+ -+ va = kmalloc(size, GFP_ATOMIC | __GFP_ZERO); -+ if (va) -+ *pap = (ulong)__virt_to_phys((ulong)va); -+ return va; -+ -+#else -+ void *ret; -+// int gfp = GFP_KERNEL; //GFP_ATOMIC | GFP_DMA; -+ /* platform device reference */ -+ struct platform_device *pdev; -+ -+ uint16 align = (1 << align_bits); -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ -+ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, align)) -+ size += align; -+ *alloced = size; -+ -+// ret = (void *)__get_free_pages(gfp, get_order(size)); -+// if (ret != NULL) { -+// memset(ret, 0, size); -+// *pap = virt_to_phys(ret); -+// } -+ pdev = (struct platform_device *)osh->pdev; -+ ret = dma_alloc_coherent(&pdev->dev, size, (dma_addr_t*)pap, GFP_KERNEL); -+ return ret; -+ -+#endif /* CONFIG_BCM_IPROC_GMAC_ACP */ -+} -+ -+void -+osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) -+{ -+#ifdef CONFIG_BCM_IPROC_GMAC_ACP -+ kfree(va); -+#else -+ /* platform device reference */ -+ struct platform_device *pdev; -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ -+// free_pages((unsigned long)va, get_order(size)); -+ pdev = (struct platform_device *)osh->pdev; -+ dma_free_coherent(&pdev->dev, size, va, (dma_addr_t)pa); -+#endif /* CONFIG_BCM_IPROC_GMAC_ACP */ -+} -+ -+uint BCMFASTPATH -+osl_dma_map(osl_t *osh, void *va, uint size, int direction, void *p, hnddma_seg_map_t *dmah) -+{ -+ int dir; -+ /* platform device reference */ -+ struct platform_device *pdev; -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ pdev = (struct platform_device *)osh->pdev; -+ dir = (direction == DMA_TX)? DMA_TO_DEVICE: DMA_FROM_DEVICE; -+ -+#if defined(BCMDMASGLISTOSL) -+ if (dmah != NULL) { -+ int32 nsegs, i, totsegs = 0, totlen = 0; -+ struct scatterlist *sg, _sg[MAX_DMA_SEGS * 2]; -+ struct sk_buff *skb; -+ for (skb = (struct sk_buff *)p; skb != NULL; skb = PKTNEXT(osh, skb)) { -+ sg = &_sg[totsegs]; -+ if (skb_is_nonlinear(skb)) { -+ nsegs = skb_to_sgvec(skb, sg, 0, PKTLEN(osh, skb)); -+ ASSERT((nsegs > 0) && (totsegs + nsegs <= MAX_DMA_SEGS)); -+ #ifndef CONFIG_BCM_IPROC_GMAC_ACP -+ dma_map_sg(&pdev->dev, sg, nsegs, dir); -+ #endif /* CONFIG_BCM_IPROC_GMAC_ACP */ -+ } else { -+ nsegs = 1; -+ ASSERT(totsegs + nsegs <= MAX_DMA_SEGS); -+ sg->page_link = 0; -+ sg_set_buf(sg, PKTDATA(osh, skb), PKTLEN(osh, skb)); -+ #ifndef CONFIG_BCM_IPROC_GMAC_ACP -+ dma_map_single(&pdev->dev, PKTDATA(osh, skb), PKTLEN(osh, skb), dir); -+ #endif /* CONFIG_BCM_IPROC_GMAC_ACP */ -+ } -+ totsegs += nsegs; -+ totlen += PKTLEN(osh, skb); -+ } -+ dmah->nsegs = totsegs; -+ dmah->origsize = totlen; -+ for (i = 0, sg = _sg; i < totsegs; i++, sg++) { -+ dmah->segs[i].addr = sg_phys(sg); -+ dmah->segs[i].length = sg->length; -+ } -+ #ifdef CONFIG_BCM_IPROC_GMAC_ACP -+ return virt_to_phys(va); -+ #else -+ return dmah->segs[0].addr; -+ #endif /* CONFIG_BCM_IPROC_GMAC_ACP */ -+ } -+#endif /* defined(BCMDMASGLISTOSL) */ -+ -+#ifdef CONFIG_BCM_IPROC_GMAC_ACP -+ return virt_to_phys(va); -+#else -+ return dma_map_single(&pdev->dev, va, size, dir); -+#endif /* CONFIG_BCM_IPROC_GMAC_ACP */ -+} -+ -+void BCMFASTPATH -+osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction) -+{ -+#ifndef CONFIG_BCM_IPROC_GMAC_ACP -+ int dir; -+ /* platform device reference */ -+ struct platform_device *pdev; -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ pdev = (struct platform_device *)osh->pdev; -+ dir = (direction == DMA_TX)? DMA_TO_DEVICE: DMA_FROM_DEVICE; -+ dma_unmap_single(&pdev->dev, (uint32)pa, size, dir); -+#endif /* ! CONFIG_BCM_IPROC_GMAC_ACP */ -+} -+ -+ -+void -+osl_delay(uint usec) -+{ -+ uint d; -+ -+ while (usec > 0) { -+ d = MIN(usec, 1000); -+ udelay(d); -+ usec -= d; -+ } -+} -+ -+/* Clone a packet. -+ * The pkttag contents are NOT cloned. -+ */ -+void * -+osl_pktdup(osl_t *osh, void *skb) -+{ -+ void * p; -+ -+ /* clear the CTFBUF flag if set and map the rest of the buffer -+ * before cloning. -+ */ -+ PKTCTFMAP(osh, skb); -+ -+ if ((p = skb_clone((struct sk_buff *)skb, GFP_ATOMIC)) == NULL) -+ return NULL; -+ -+ /* skb_clone copies skb->cb.. we don't want that */ -+ if (osh->pub.pkttag) -+ OSL_PKTTAG_CLEAR(p); -+ -+ /* Increment the packet counter */ -+ atomic_inc(&osh->pktalloced); -+ return (p); -+} -+ -+ -+/* -+ * OSLREGOPS specifies the use of osl_XXX routines to be used for register access -+ */ -+#ifdef OSLREGOPS -+uint8 -+osl_readb(osl_t *osh, volatile uint8 *r) -+{ -+ osl_rreg_fn_t rreg = ((osl_pubinfo_t*)osh)->rreg_fn; -+ void *ctx = ((osl_pubinfo_t*)osh)->reg_ctx; -+ -+ return (uint8)((rreg)(ctx, (void*)r, sizeof(uint8))); -+} -+ -+ -+uint16 -+osl_readw(osl_t *osh, volatile uint16 *r) -+{ -+ osl_rreg_fn_t rreg = ((osl_pubinfo_t*)osh)->rreg_fn; -+ void *ctx = ((osl_pubinfo_t*)osh)->reg_ctx; -+ -+ return (uint16)((rreg)(ctx, (void*)r, sizeof(uint16))); -+} -+ -+uint32 -+osl_readl(osl_t *osh, volatile uint32 *r) -+{ -+ osl_rreg_fn_t rreg = ((osl_pubinfo_t*)osh)->rreg_fn; -+ void *ctx = ((osl_pubinfo_t*)osh)->reg_ctx; -+ -+ return (uint32)((rreg)(ctx, (void*)r, sizeof(uint32))); -+} -+ -+void -+osl_writeb(osl_t *osh, volatile uint8 *r, uint8 v) -+{ -+ osl_wreg_fn_t wreg = ((osl_pubinfo_t*)osh)->wreg_fn; -+ void *ctx = ((osl_pubinfo_t*)osh)->reg_ctx; -+ -+ ((wreg)(ctx, (void*)r, v, sizeof(uint8))); -+} -+ -+ -+void -+osl_writew(osl_t *osh, volatile uint16 *r, uint16 v) -+{ -+ osl_wreg_fn_t wreg = ((osl_pubinfo_t*)osh)->wreg_fn; -+ void *ctx = ((osl_pubinfo_t*)osh)->reg_ctx; -+ -+ ((wreg)(ctx, (void*)r, v, sizeof(uint16))); -+} -+ -+void -+osl_writel(osl_t *osh, volatile uint32 *r, uint32 v) -+{ -+ osl_wreg_fn_t wreg = ((osl_pubinfo_t*)osh)->wreg_fn; -+ void *ctx = ((osl_pubinfo_t*)osh)->reg_ctx; -+ -+ ((wreg)(ctx, (void*)r, v, sizeof(uint32))); -+} -+#endif /* OSLREGOPS */ -+ -+/* -+ * BINOSL selects the slightly slower function-call-based binary compatible osl. -+ */ -+#ifdef BINOSL -+ -+uint32 -+osl_sysuptime(void) -+{ -+ return ((uint32)jiffies * (1000 / HZ)); -+} -+ -+int -+osl_printf(const char *format, ...) -+{ -+ va_list args; -+ static char printbuf[1024]; -+ int len; -+ -+ /* sprintf into a local buffer because there *is* no "vprintk()".. */ -+ va_start(args, format); -+ len = vsnprintf(printbuf, 1024, format, args); -+ va_end(args); -+ -+ if (len > sizeof(printbuf)) { -+ printk("osl_printf: buffer overrun\n"); -+ return (0); -+ } -+ -+ return (printk("%s", printbuf)); -+} -+ -+int -+osl_sprintf(char *buf, const char *format, ...) -+{ -+ va_list args; -+ int rc; -+ -+ va_start(args, format); -+ rc = vsprintf(buf, format, args); -+ va_end(args); -+ return (rc); -+} -+ -+int -+osl_snprintf(char *buf, size_t n, const char *format, ...) -+{ -+ va_list args; -+ int rc; -+ -+ va_start(args, format); -+ rc = vsnprintf(buf, n, format, args); -+ va_end(args); -+ return (rc); -+} -+ -+int -+osl_vsprintf(char *buf, const char *format, va_list ap) -+{ -+ return (vsprintf(buf, format, ap)); -+} -+ -+int -+osl_vsnprintf(char *buf, size_t n, const char *format, va_list ap) -+{ -+ return (vsnprintf(buf, n, format, ap)); -+} -+ -+int -+osl_strcmp(const char *s1, const char *s2) -+{ -+ return (strcmp(s1, s2)); -+} -+ -+int -+osl_strncmp(const char *s1, const char *s2, uint n) -+{ -+ return (strncmp(s1, s2, n)); -+} -+ -+int -+osl_strlen(const char *s) -+{ -+ return (strlen(s)); -+} -+ -+char* -+osl_strcpy(char *d, const char *s) -+{ -+ return (strcpy(d, s)); -+} -+ -+char* -+osl_strncpy(char *d, const char *s, uint n) -+{ -+ return (strncpy(d, s, n)); -+} -+ -+char* -+osl_strchr(const char *s, int c) -+{ -+ return (strchr(s, c)); -+} -+ -+char* -+osl_strrchr(const char *s, int c) -+{ -+ return (strrchr(s, c)); -+} -+ -+void* -+osl_memset(void *d, int c, size_t n) -+{ -+ return memset(d, c, n); -+} -+ -+void* -+osl_memcpy(void *d, const void *s, size_t n) -+{ -+ return memcpy(d, s, n); -+} -+ -+void* -+osl_memmove(void *d, const void *s, size_t n) -+{ -+ return memmove(d, s, n); -+} -+ -+int -+osl_memcmp(const void *s1, const void *s2, size_t n) -+{ -+ return memcmp(s1, s2, n); -+} -+ -+uint32 -+osl_readl(volatile uint32 *r) -+{ -+ return (readl(r)); -+} -+ -+uint16 -+osl_readw(volatile uint16 *r) -+{ -+ return (readw(r)); -+} -+ -+uint8 -+osl_readb(volatile uint8 *r) -+{ -+ return (readb(r)); -+} -+ -+void -+osl_writel(uint32 v, volatile uint32 *r) -+{ -+ writel(v, r); -+} -+ -+void -+osl_writew(uint16 v, volatile uint16 *r) -+{ -+ writew(v, r); -+} -+ -+void -+osl_writeb(uint8 v, volatile uint8 *r) -+{ -+ writeb(v, r); -+} -+ -+void * -+osl_uncached(void *va) -+{ -+#ifdef mips -+ return ((void*)KSEG1ADDR(va)); -+#else -+ return ((void*)va); -+#endif /* mips */ -+} -+ -+void * -+osl_cached(void *va) -+{ -+#ifdef mips -+ return ((void*)KSEG0ADDR(va)); -+#else -+ return ((void*)va); -+#endif /* mips */ -+} -+ -+uint -+osl_getcycles(void) -+{ -+ uint cycles; -+ -+#if defined(mips) -+ cycles = read_c0_count() * 2; -+#elif defined(__i386__) -+ rdtscl(cycles); -+#else -+ cycles = 0; -+#endif /* defined(mips) */ -+ return cycles; -+} -+ -+void * -+osl_reg_map(uint32 pa, uint size) -+{ -+ return (ioremap_nocache((unsigned long)pa, (unsigned long)size)); -+} -+ -+void -+osl_reg_unmap(void *va) -+{ -+ iounmap(va); -+} -+ -+int -+osl_busprobe(uint32 *val, uint32 addr) -+{ -+#ifdef mips -+ return get_dbe(*val, (uint32 *)addr); -+#else -+ *val = readl((uint32 *)(uintptr)addr); -+ return 0; -+#endif /* mips */ -+} -+ -+bool -+osl_pktshared(void *skb) -+{ -+ return (((struct sk_buff*)skb)->cloned); -+} -+ -+uchar* -+osl_pktdata(osl_t *osh, void *skb) -+{ -+ return (((struct sk_buff*)skb)->data); -+} -+ -+uint -+osl_pktlen(osl_t *osh, void *skb) -+{ -+ return (((struct sk_buff*)skb)->len); -+} -+ -+uint -+osl_pktheadroom(osl_t *osh, void *skb) -+{ -+ return (uint) skb_headroom((struct sk_buff *) skb); -+} -+ -+uint -+osl_pkttailroom(osl_t *osh, void *skb) -+{ -+ return (uint) skb_tailroom((struct sk_buff *) skb); -+} -+ -+void* -+osl_pktnext(osl_t *osh, void *skb) -+{ -+ return (((struct sk_buff*)skb)->next); -+} -+ -+void -+osl_pktsetnext(void *skb, void *x) -+{ -+ ((struct sk_buff*)skb)->next = (struct sk_buff*)x; -+} -+ -+void -+osl_pktsetlen(osl_t *osh, void *skb, uint len) -+{ -+ __pskb_trim((struct sk_buff*)skb, len); -+} -+ -+uchar* -+osl_pktpush(osl_t *osh, void *skb, int bytes) -+{ -+ return (skb_push((struct sk_buff*)skb, bytes)); -+} -+ -+uchar* -+osl_pktpull(osl_t *osh, void *skb, int bytes) -+{ -+ return (skb_pull((struct sk_buff*)skb, bytes)); -+} -+ -+void* -+osl_pkttag(void *skb) -+{ -+ return ((void*)(((struct sk_buff*)skb)->cb)); -+} -+ -+void* -+osl_pktlink(void *skb) -+{ -+ return (((struct sk_buff*)skb)->prev); -+} -+ -+void -+osl_pktsetlink(void *skb, void *x) -+{ -+ ((struct sk_buff*)skb)->prev = (struct sk_buff*)x; -+} -+ -+uint -+osl_pktprio(void *skb) -+{ -+ return (((struct sk_buff*)skb)->priority); -+} -+ -+void -+osl_pktsetprio(void *skb, uint x) -+{ -+ ((struct sk_buff*)skb)->priority = x; -+} -+#endif /* BINOSL */ -+ -+uint -+osl_pktalloced(osl_t *osh) -+{ -+ return (atomic_read(&osh->pktalloced)); -+} -+ -+/* Linux Kernel: File Operations: start */ -+void * -+osl_os_open_image(char *filename) -+{ -+ struct file *fp; -+ -+ fp = filp_open(filename, O_RDONLY, 0); -+ /* -+ * 2.6.11 (FC4) supports filp_open() but later revs don't? -+ * Alternative: -+ * fp = open_namei(AT_FDCWD, filename, O_RD, 0); -+ * ??? -+ */ -+ if (IS_ERR(fp)) -+ fp = NULL; -+ -+ return fp; -+} -+ -+int -+osl_os_get_image_block(char *buf, int len, void *image) -+{ -+ struct file *fp = (struct file *)image; -+ int rdlen; -+ -+ if (!image) -+ return 0; -+ -+ rdlen = kernel_read(fp, fp->f_pos, buf, len); -+ if (rdlen > 0) -+ fp->f_pos += rdlen; -+ -+ return rdlen; -+} -+ -+void -+osl_os_close_image(void *image) -+{ -+ if (image) -+ filp_close((struct file *)image, NULL); -+} -+/* Linux Kernel: File Operations: end */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/nvramstubs.c b/drivers/net/ethernet/broadcom/gmac/src/shared/nvramstubs.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/nvramstubs.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/nvramstubs.c 2017-11-09 17:53:44.059297000 +0800 -@@ -0,0 +1,341 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * Stubs for NVRAM functions for platforms without flash -+ * -+ * $Id: nvramstubs.c 325991 2012-04-05 10:16:42Z kenlo $ -+ */ -+ -+#include -+#include -+#include -+#undef strcmp -+#define strcmp(s1,s2) 0 /* always match */ -+#include -+ -+int -+nvram_init(void *sih) -+{ -+ return 0; -+} -+ -+int -+nvram_append(void *sb, char *vars, uint varsz) -+{ -+ return 0; -+} -+ -+void -+nvram_exit(void *sih) -+{ -+} -+ -+/* fake nvram tuples */ -+typedef struct { -+ char *name; -+ char *value; -+} nvram_t; -+ -+static nvram_t fake_nvram[] = { -+ {"boardtype", "0x058d"}, -+ {"boardnum", "0x010"}, -+ {"boardrev", "0x1100"}, -+ {"boardflags", "0x710"}, -+ {"boardflags2", "0"}, -+ {"sromrev", "8"}, -+ {"clkfreq", "133,133,133"}, -+ {"xtalfreq", "125000"}, -+ {"et_txq_thresh", "1024"}, -+ {"et_rx_rate_limit","1"}, -+ {"sdram_config", "0x103"}, -+ {"swgmacet", "et2"}, -+ {"brcmtag", "1"}, -+ //{"ethaddr", "00:90:4c:06:a5:72"}, -+#ifdef FOUR_PORT_CONFIG -+ {"vlan1hwname", "et2"}, -+ {"vlan1ports", "0 1 2 8*"}, -+ {"vlan2hwname", "et2"}, -+ {"vlan2ports", "3 8*"}, -+ {"wanport", "3"}, -+#else -+ {"vlan1hwname", "et2"}, -+ {"vlan1ports", "0 1 2 3 8*"}, -+ {"vlan2hwname", "et2"}, -+ {"vlan2ports", "4 8*"}, -+ {"wanport", "4"}, -+#endif -+ {"landevs", "vlan1"}, -+ {"wandevs", "et0"}, -+ {"lan_ipaddr", "192.168.1.1"}, -+ {"lan_netmask", "255.255.255.0"}, -+ {"boot_wait", "on"}, -+ {"wait_time", "3"}, -+ {"watchdog", "0"}, -+ {"et_msglevel", "0xFFFFFFFF"} -+}; -+#define fake_nvram_size sizeof(fake_nvram)/sizeof(fake_nvram[0]) -+ -+#ifndef FAKE_NVRAM -+ -+#if defined(CONFIG_MACH_IPROC_P7) -+#define CONFIG_SPI_BASE 0xf0000000 -+#else -+#define CONFIG_SPI_BASE 0x1e000000 -+#endif /* CONFIG_MACH_IPROC_P7 */ -+#define CONFIG_ENV_OFFSET 0xc0000 /* 30000-b0000 - use last 10000 for env */ -+#define CONFIG_ENV_SIZE 0x10000 /* 64K */ -+#define CONFIG_ENV_MAX_ENTRIES 512 -+ -+#define UBOOT_ENV_ADDR CONFIG_SPI_BASE+CONFIG_ENV_OFFSET -+#define UBOOT_ENV_SIZE CONFIG_ENV_SIZE -+#define UBOOT_ENV_MAX_NUM CONFIG_ENV_MAX_ENTRIES -+ -+static uint8 u_boot_env[UBOOT_ENV_SIZE]; -+static bool u_boot_env_loaded=false; -+static nvram_t env_list[UBOOT_ENV_MAX_NUM]; -+static int uboot_vars_start = UBOOT_ENV_ADDR; -+static int uboot_nvram_max = UBOOT_ENV_SIZE; -+ -+/* pass envaddr= in bootargs */ -+static int __init envaddr_setup(char *str) -+{ -+ int ret =0; -+ unsigned long ul=0; -+ -+ ret = kstrtoul(str, 16, &ul); -+ -+ if (!ret) { -+ uboot_vars_start = ul; -+ printk("NVRAM: assign 0x%08x\n", uboot_vars_start); -+ } -+ -+ return !ret; -+} -+__setup("envaddr=", envaddr_setup); -+ -+/* -+APIs for access into uboot env vars -+*/ -+ -+int -+nvram_env_init(void) -+{ -+ volatile void *envbuf; -+ char *dp, *sp, *name, *value, *dp_end; -+ char sep = '\0'; -+ int idx=0; -+ -+ -+ printk("NVRAM: map 0x%08x\n", uboot_vars_start); -+ -+ /* map uboot env */ -+ if ((envbuf = (uint8*)ioremap(uboot_vars_start, UBOOT_ENV_SIZE)) == NULL) { -+ printk("%s: ioremap() failed\n", __FUNCTION__); -+ return -ENOMEM; -+ } -+ -+ /* copy memory into buffer */ -+ memcpy((void*)u_boot_env, (void *) envbuf, uboot_nvram_max); -+ -+ /* clear fake entry set */ -+ memset(env_list, 0, sizeof(env_list)); -+ -+ /* load uboot fake nvram buffer */ -+ /* point to first data */ -+ dp = (char*)u_boot_env; -+ /* point to data buffer */ -+ dp += 4; -+ dp_end = (char*)((uint32)u_boot_env+UBOOT_ENV_SIZE); -+ -+ /* point to first data */ -+ do { -+ /* skip leading white space */ -+ while ((*dp == ' ') || (*dp == '\t')) { -+ ++dp; -+ } -+ -+ /* skip comment lines */ -+ if (*dp == '#') { -+ while (*dp && (*dp != sep)) { -+ ++dp; -+ } -+ ++dp; -+ continue; -+ } -+ -+ /* parse name */ -+ for (name = dp; *dp != '=' && *dp && *dp != sep; ++dp) { -+ ; -+ } -+ -+ *dp++ = '\0'; /* terminate name */ -+ -+ /* parse value; deal with escapes */ -+ for (value = sp = dp; *dp && (*dp != sep); ++dp) { -+ if ((*dp == '\\') && *(dp + 1)) { -+ ++dp; -+ } -+ *sp++ = *dp; -+ } -+ *sp++ = '\0'; /* terminate value */ -+ ++dp; -+ -+ /* enter into hash table */ -+ env_list[idx].name = name; -+ env_list[idx].value = value; -+ //printk("entry%d %s=%s\n", idx, name, value); -+ idx++; -+ -+ /* check if table is full */ -+ if (idx >= UBOOT_ENV_MAX_NUM ) { -+ printk("%s: WARNING - UBoot environment table is full\n", __FUNCTION__); -+ break; -+ } -+ /* check if end of table */ -+ } while ((dp < dp_end) && *dp); /* size check needed for text */ -+ -+ u_boot_env_loaded = true; -+ -+ /* unmap uboot env */ -+ iounmap(envbuf); -+ -+ return 0; -+} -+#endif -+ -+int -+nvram_env_gmac_name(int gmac, char *name) -+{ -+ int ret=0; -+ switch (gmac) -+ { -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_GH2)) -+ case 0: -+ strcpy(name, "ethaddr"); -+ break; -+ case 1: -+ sprintf(name, "eth1addr"); -+ break; -+#elif (defined(CONFIG_MACH_HR2) || defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3)) -+ case 0: -+ strcpy(name, "ethaddr"); -+ break; -+#endif -+ default: -+ strcpy(name, "unknown"); -+ ret = -1; -+ break; -+ } -+ return ret; -+ -+} -+ -+char * -+nvram_get(const char *name) -+{ -+ int i, len; -+ nvram_t *tuple; -+ int num_entries; -+ -+ if (!name) { -+ return (char *) 0; -+ } -+ -+ len = strlen(name); -+ if (len == 0) { -+ return (char *) 0; -+ } -+ -+#if defined(CONFIG_MACH_SB2) && defined(CONFIG_MACH_IPROC_EMULATION) -+ static char macAddr[17]; /* = "d4:ae:52:bc:a5:09" */ -+ -+ if (name[0] == 'e' && name[1] == 't' && name[2] == 'h' && name[3] == 'a' && -+ name[4] == 'd' && name[5] == 'd' && name[6] == 'r') -+ { -+ macAddr[0] = 'd'; macAddr[1] = '4'; macAddr[2] = ':'; -+ macAddr[3] = 'a'; macAddr[4] = 'e'; macAddr[5] = ':'; -+ macAddr[6] = '5'; macAddr[7] = '2'; macAddr[8] = ':'; -+ macAddr[9] = 'b'; macAddr[10] = 'c'; macAddr[11] = ':'; -+ macAddr[12] = 'a'; macAddr[13] = '5'; macAddr[14] = ':'; -+ macAddr[15] = '0'; macAddr[16] = '9'; -+ return((char *)macAddr); -+ } /* else if (name[0] == 'e' && name[1] == 't' && name[2] == 'h' && name[3] == '1' && -+ name[4] == 'a' && name[5] == 'd' && name[6] == 'd' && name[7] == 'r') -+ { -+ macAddr[0] = 'd'; macAddr[1] = '5'; macAddr[2] = ':'; -+ macAddr[3] = 'a'; macAddr[4] = 'e'; macAddr[5] = ':'; -+ macAddr[6] = '5'; macAddr[7] = '3'; macAddr[8] = ':'; -+ macAddr[9] = 'b'; macAddr[10] = 'c'; macAddr[11] = ':'; -+ macAddr[12] = 'a'; macAddr[13] = '6'; macAddr[14] = ':'; -+ macAddr[15] = '0'; macAddr[16] = 'a'; -+ return((char *)macAddr); -+ } */ -+#endif -+ -+#ifndef FAKE_NVRAM -+ tuple = &env_list[0]; -+ num_entries = sizeof(env_list)/sizeof(nvram_t); -+ -+ if (!u_boot_env_loaded) { -+ nvram_env_init(); -+ } -+ -+ /* first check the uboot NVRAM variables */ -+ for (i = 0; i < num_entries; i++) { -+ if (tuple->name && (bcmp(tuple->name, name, len) == 0) && (strlen(tuple->name)==len)) { -+ /*printf("%s (NVRAM) %s: %s\n", __FUNCTION__, name, tuple->value);*/ -+ return tuple->value; -+ } -+ tuple++; -+ } -+#endif -+ -+ /* if cant find then check fake table above */ -+ tuple = &fake_nvram[0]; -+ num_entries = fake_nvram_size; -+ for (i = 0; i < num_entries; i++) { -+ if (tuple->name && (bcmp(tuple->name, name, len) == 0) && (strlen(tuple->name)==len)) { -+ /*printf("%s (STUBS) %s: %s\n", __FUNCTION__, name, tuple->value);*/ -+ return tuple->value; -+ } -+ tuple++; -+ } -+ -+ return (char *) 0; -+} -+ -+int -+nvram_set(const char *name, const char *value) -+{ -+ return 0; -+} -+ -+int -+nvram_unset(const char *name) -+{ -+ return 0; -+} -+ -+int -+nvram_commit(void) -+{ -+ return 0; -+} -+ -+int -+nvram_getall(char *buf, int count) -+{ -+ /* add null string as terminator */ -+ if (count < 1) { -+ return BCME_BUFTOOSHORT; -+ } -+ *buf = '\0'; -+ return 0; -+} -+ -+static int __init iproc_nvram_init(void) -+{ -+ nvram_env_init(); -+ return 0; -+} -+subsys_initcall(iproc_nvram_init); -\ No newline at end of file -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/phy542xx.c b/drivers/net/ethernet/broadcom/gmac/src/shared/phy542xx.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/phy542xx.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/phy542xx.c 2017-11-09 17:53:44.061289000 +0800 -@@ -0,0 +1,336 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * These routines provide access to the external phy -+ * -+ */ -+#include -+#include -+#include "../../../mdio/iproc_mdio.h" -+#include "bcmiproc_phy.h" -+#include "phy542xx.h" -+ -+/* debug/trace */ -+//#define BCMDBG -+//#define BCMDBG_ERR -+#ifdef BCMDBG -+#define NET_ERROR(args) printf args -+#define NET_TRACE(args) printf args -+#elif defined(BCMDBG_ERR) -+#define NET_ERROR(args) printf args -+#define NET_TRACE(args) -+#else -+#define NET_ERROR(args) -+#define NET_TRACE(args) -+#endif /* BCMDBG */ -+#define NET_REG_TRACE(args) -+ -+ -+#ifndef ASSERT -+#define ASSERT(exp) -+#endif -+ -+#define PHY542XX_RDB_REG_RD phy542xx_rdb_reg_read -+#define PHY542XX_RDB_REG_WR phy542xx_rdb_reg_write -+#define PHY542XX_REG_RD phy542xx_reg_read -+#define PHY542XX_REG_WR phy542xx_reg_write -+ -+static int -+phy542xx_rdb_reg_read(u32 phy_addr, u32 reg_addr, u16 *data) -+{ -+ int rv = SOC_E_NONE; -+ -+ /* MDIO write the RDB reg. address to reg.0x1E = */ -+ iproc_mii_write(MII_DEV_EXT, phy_addr, BCM542XX_REG_RDB_ADDR, -+ (0xffff & reg_addr)); -+ -+ /* MDIO read from reg.0x1F to get the RDB register's value as */ -+ iproc_mii_read(MII_DEV_EXT, phy_addr, BCM542XX_REG_RDB_DATA, data); -+ -+ return rv; -+} -+ -+static int -+phy542xx_rdb_reg_write(u32 phy_addr, u32 reg_addr, u16 data) -+{ -+ int rv = SOC_E_NONE; -+ -+ /* MDIO write the RDB reg. address to reg.0x1E = */ -+ iproc_mii_write(MII_DEV_EXT, phy_addr, BCM542XX_REG_RDB_ADDR, -+ (0xffff & reg_addr)); -+ -+ /* MDIO write to reg.0x1F to set the RDB resister's value as */ -+ iproc_mii_write(MII_DEV_EXT, phy_addr, BCM542XX_REG_RDB_DATA, data); -+ -+ return rv; -+} -+ -+int -+phy542xx_reg_read(u32 phy_addr, u32 flags, int reg_addr, u16 *data) -+{ -+ int rv = SOC_E_NONE; -+ u16 val; -+ -+ if (flags & PHY_REG_FLAGS_FIBER) { /* fiber registers */ -+ if (reg_addr <= 0x0f) { -+ if (flags & PHY_REG_FLAGS_1000X) { -+ /* 54220 fiber is controlled by Secondary SerDes */ -+ PHY542XX_RDB_REG_RD(phy_addr, -+ (reg_addr | BCM542XX_REG_RDB_2ND_SERDES_BASE), data); -+ } else { -+ /* Map 1000X page */ -+ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, &val); -+ val |= BCM542XX_REG_MODE_CTRL_1000X_EN; -+ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, val); -+ -+ /* Read 1000X IEEE register */ -+ iproc_mii_read(MII_DEV_EXT, phy_addr, reg_addr, data); -+ -+ /* Restore IEEE mapping */ -+ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, &val); -+ val &= ~BCM542XX_REG_MODE_CTRL_1000X_EN; -+ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, val); -+ } -+ } -+ } else if (flags & PHY_REG_FLAGS_RDB) { -+ PHY542XX_RDB_REG_RD(phy_addr, reg_addr, data); -+ } else { -+ iproc_mii_read(MII_DEV_EXT, phy_addr, reg_addr, data); -+ } -+ -+ return rv; -+} -+ -+ -+int -+phy542xx_reg_write(u32 phy_addr, u32 flags, int reg_addr, u16 data) -+{ -+ int rv = SOC_E_NONE; -+ u16 val; -+ -+ if (flags & PHY_REG_FLAGS_FIBER) { /* fiber registers */ -+ if (reg_addr <= 0x0f) { -+ if (flags & PHY_REG_FLAGS_1000X) { -+ /* 54220 fiber is controlled by Secondary SerDes */ -+ PHY542XX_RDB_REG_WR(phy_addr, -+ (reg_addr | BCM542XX_REG_RDB_2ND_SERDES_BASE), data); -+ } else { -+ /* Map 1000X page */ -+ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, &val); -+ val |= BCM542XX_REG_MODE_CTRL_1000X_EN; -+ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, val); -+ -+ /* Write 1000X IEEE register */ -+ iproc_mii_write(MII_DEV_EXT, phy_addr, reg_addr, data); -+ -+ /* Restore IEEE mapping */ -+ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, &val); -+ val &= ~BCM542XX_REG_MODE_CTRL_1000X_EN; -+ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, val); -+ } -+ } -+ } else if (flags & PHY_REG_FLAGS_RDB) { -+ PHY542XX_RDB_REG_WR(phy_addr, reg_addr, data); -+ } else { -+ iproc_mii_write(MII_DEV_EXT, phy_addr, reg_addr, data); -+ } -+ -+ return rv; -+} -+ -+static int -+phy542xx_ge_reset(u32 phy_addr) -+{ -+ int rv = SOC_E_NONE; -+ u16 val; -+ -+ NET_TRACE(("%s: phy_addr %d\n", __FUNCTION__, phy_addr)); -+ -+ /* Reset the PHY */ -+ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_CTRLr_ADDR, &val); -+ val |= MII_CTRL_RESET; -+ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_CTRLr_ADDR, val); -+ -+ SPINWAIT((!PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_CTRLr_ADDR, &val) && -+ (val & MII_CTRL_RESET)), 100000); -+ -+ /* Check if out of reset */ -+ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_CTRLr_ADDR, &val); -+ if (val & MII_CTRL_RESET) { -+ NET_ERROR(("%s reset not complete\n", __FUNCTION__)); -+ rv = SOC_E_TIMEOUT; -+ } else { -+ NET_TRACE(("%s reset complete\n", __FUNCTION__)); -+ } -+ -+ return rv; -+} -+ -+static int -+phy542xx_ge_init(u32 phy_addr) -+{ -+ int rv = SOC_E_NONE; -+ u16 val; -+ -+ /* -+ * Enable direct RDB addressing mode, write to Expansion register -+ * 0x7E = 0x0000 -+ * - MDIO write to reg 0x17 = 0x0F7E -+ * - MDIO write to reg 0x15 = 0x0000 -+ */ -+ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_NONE, -+ BCM542XX_REG_EXP_SEL, BCM542XX_REG_EXP_SELECT_7E); -+ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_NONE, -+ BCM542XX_REG_EXP_DATA, BCM542XX_REG_EXP_RDB_EN); -+ -+ /* Configure auto-detect Medium */ -+ PHY542XX_RDB_REG_RD(phy_addr, MIIM_BCM542xx_RDB_AUTO_DETECT_MEDIUM, &val); -+ val &= ~BCM542XX_REG_MII_AUTO_DET_MASK; -+ /* Enable dual serdes auto-detect medium */ -+ val |= (BCM542XX_REG_MII_AUTO_DET_MED_2ND_SERDES | -+ BCM542XX_REG_MII_FIBER_IN_USE_LED | -+ BCM542XX_REG_MII_FIBER_LED | -+ BCM542XX_REG_MII_FIBER_SD_SYNC); -+ /* Enable auto-detect medium */ -+ val |= BCM542XX_REG_MII_AUTO_DET_MED_EN; -+ /* Fiber selected when both media are active */ -+ val |= (BCM542XX_REG_MII_AUTO_DET_MED_PRI | -+ BCM542XX_REG_MII_AUTO_DET_MED_DEFAULT); -+ PHY542XX_RDB_REG_WR(phy_addr, MIIM_BCM542xx_RDB_AUTO_DETECT_MEDIUM, val); -+ -+ /* Power up primary SerDes, Fiber MII_CONTROL Reg. bit[11]*/ -+ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_PRI_SERDES, PHY_MII_CTRLr_ADDR, &val); -+ val &= ~MII_CTRL_PD; -+ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_PRI_SERDES, PHY_MII_CTRLr_ADDR, val); -+ -+ /* MODE_CONTROL register, DIGX_SHD_1C_1F, RDB_0x21 */ -+ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, &val); -+ val &= ~(BCM542XX_REG_MODE_CNTL_MODE_SEL_1 | -+ BCM542XX_REG_MODE_CNTL_MODE_SEL_2); -+ val |= BCM542XX_REG_MODE_SEL_SGMII_2_COPPER; -+ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_MODE_CTRL, val); -+ -+ /* COPPER INTERFACE */ -+ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_CTRLr_ADDR, &val); -+ val &= ~MII_CTRL_PD; -+ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_CTRLr_ADDR, val); -+ -+ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_NONE, MII_CTRL1000, ADVERTISE_1000FULL); -+ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_CTRLr_ADDR, -+ (BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE | BMCR_ANRESTART)); -+ -+ /* Enable/disable auto-detection between SGMII-slave and 1000BASE-X */ -+ /* External Serdes Control Reg., DIGX_SHD_1C_14, RDB_0x234 */ -+ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_EXT_SERDES_CTRL, &val); -+ val &= ~(BCM542XX_REG_EXT_SERDES_FX_MASK); -+ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_EXT_SERDES_CTRL, val); -+ -+ /* SGMII Slave Control Register, DIGX_SHD_1C_15, RDB_0x235 */ -+ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_SGMII_SLAVE, &val); -+ val &= ~(BCM542XX_REG_SGMII_SLAVE_AUTO); -+ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_SGMII_SLAVE, val); -+ -+ /* FIBER INTERFACE */ -+ /* Remove power down of SerDes */ -+ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_1000X, PHY_MII_CTRLr_ADDR, &val); -+ val &= ~MII_CTRL_PD; -+ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_1000X, PHY_MII_CTRLr_ADDR, val); -+ -+ /* Set the advertisement of serdes */ -+ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_1000X, PHY_MII_ANAr_ADDR, &val); -+ val |= (MII_ANA_FD_1000X | MII_ANA_HD_1000X | -+ MII_ANA_1000X_PAUSE | MII_ANA_1000X_ASYM_PAUSE); -+ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_1000X, PHY_MII_ANAr_ADDR, val); -+ -+ /* Enable auto-detection between SGMII-slave and 1000BASE-X */ -+ /* External Serdes Control Reg., DIGX_SHD_1C_14, RDB_0x234 */ -+ val = (BCM542XX_REG_EXT_SERDES_LED | BCM542XX_REG_EXT_SEL_SYNC_ST | -+ BCM542XX_REG_EXT_SELECT_SD | BCM542XX_REG_EXT_SERDES_SEL); -+ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_EXT_SERDES_CTRL, val); -+ -+ /* SGMII Slave Control Register, DIGX_SHD_1C_15, RDB_0x235 */ -+ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_SGMII_SLAVE, &val); -+ val &= ~(BCM542XX_REG_SGMII_SLAVE_AUTO); -+ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_SGMII_SLAVE, val); -+ -+ /* Miscellanous Control Reg., CORE_SHD18_111, RDB_0x02f */ -+ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_MII_MISC_CTRL, 0x2007); -+ -+ /* Second SERDES 100-FX CONTROL Register, RDB_0xb17 */ -+ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_2ND_SERDES_MISC_1000X, 0x0); -+ -+ /* Default SerDes config & restart autonegotiation */ -+ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_1000X, PHY_MII_CTRLr_ADDR, -+ (BMCR_FULLDPLX | BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_ANRESTART)); -+ -+ return rv; -+} -+ -+int -+phy542xx_reset_setup(u32 phy_addr) -+{ -+ int rv = SOC_E_NONE; -+ -+ NET_TRACE(("%s enter\n", __FUNCTION__)); -+ -+ rv = phy542xx_ge_reset(phy_addr); -+ -+ if (SOC_SUCCESS(rv)) { -+ rv = phy542xx_ge_init(phy_addr); -+ } -+ -+ return rv; -+} -+ -+int -+phy542xx_init(u32 phy_addr) -+{ -+ u16 phyid0, phyid1; -+ -+ NET_TRACE(("%s: phy_addr %d\n", __FUNCTION__, phy_addr)); -+ -+ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_PHY_ID0r_ADDR, &phyid0); -+ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_NONE, PHY_MII_PHY_ID1r_ADDR, &phyid1); -+ -+ printf("%s Phy ChipID: 0x%04x:0x%04x\n", __FUNCTION__, phyid1, phyid0); -+ -+ phy542xx_reset_setup(phy_addr); -+ -+ return 0; -+} -+ -+int -+phy542xx_enable_set(u32 phy_addr, int enable) -+{ -+ u16 val; -+ -+ NET_TRACE(("%s: phy_addr %d\n", __FUNCTION__, phy_addr)); -+ -+ PHY542XX_REG_RD(phy_addr, PHY_REG_FLAGS_PRI_SERDES, PHY_MII_CTRLr_ADDR, &val); -+ if (enable) { -+ val &= ~MII_CTRL_PD; -+ } else { -+ val |= MII_CTRL_PD; -+ } -+ PHY542XX_REG_WR(phy_addr, PHY_REG_FLAGS_PRI_SERDES, PHY_MII_CTRLr_ADDR, val); -+ -+ return SOC_E_NONE; -+} -+ -+int -+phy542xx_force_auto_mdix(u32 phy_addr, int enable) -+{ -+ u16 val; -+ -+ NET_TRACE(("%s: phy_addr %d\n", __FUNCTION__, phy_addr)); -+ -+ PHY542XX_RDB_REG_RD(phy_addr, BCM542XX_REG_RDB_COPPER_MISC_CTRL, &val); -+ if (enable) { -+ val |= BCM542XX_REG_MISC_CTRL_FORCE_AUTO_MDIX; -+ } else { -+ val &= ~BCM542XX_REG_MISC_CTRL_FORCE_AUTO_MDIX; -+ } -+ PHY542XX_RDB_REG_WR(phy_addr, BCM542XX_REG_RDB_COPPER_MISC_CTRL, val); -+ -+ return SOC_E_NONE; -+} -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/sb2_erom.c b/drivers/net/ethernet/broadcom/gmac/src/shared/sb2_erom.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/sb2_erom.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/sb2_erom.c 2017-11-09 17:53:44.061307000 +0800 -@@ -0,0 +1,81 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet -+ * Saber2 sudo EROM -+ * -+ */ -+#include -+ -+uint32 sb2_erom[] = { -+ // LOOP 1 : #define MFGID_BRCM 0x4bf /* Manufacturer Ids (mfg) */ -+ // #define CC_CORE_ID 0x800 /* chipcommon core (cid) */ -+ 0x4bf80001, -+ // crev = 0x2a, nsw = 0x0 (mask = 0x0x00f80000), nmw = 0x1 (mask = 0x0007c000), nsp = 0x1 (mask = 0x00003e00), nmp = 0x0 (mask = 0x000001f0) -+ 0x2a004201, -+ // First Slave Address Descriptor should be port 0: the main register space for the core -+ // addr1 = 0x18000000 (mask = 0xfffff000), addrh = 0x0 (AD_AG32 = 0x00000008), sizeh = 0x0, -+ // sz = 0x0 (AD_SZ_MASK = 0x00000030), sizel = 0x00001000 (0x00001000 << (sz >> 4)) -+ 0x18000005, -+ // Now get master wrappers (i = 0) -+ // addr1 = 0x18120000 (AD_ADDR_MASK = 0xfffff000), addrh = 0x0 (AD_AG32 = 0x00000008), sizeh = 0x0, -+ // sz = 0x0 (AD_SZ_MASK = 0x00000030), sizel = 0x00001000 (0x00001000 << (sz >> 4)) -+ 0x181200c5, -+ -+ // LOOP 2 : #define MFGID_BRCM 0x4bf /* Manufacturer Ids (mfg) */ -+ // #define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ -+ // cia = 0x4bf82d01 -+ // cid = 0x82d (cia & CIA_CID_MASK(0x000fff00)) >> CIA_CID_SHIFT(8), mfg = 0x4bf (cia & CIA_MFG_MASK(0xfff00000)) >> CIA_MFG_SHIFT(20) -+ 0x4bf82d01, -+ // cib = 0x04004211 -+ // crev = 0x04 (cib & CIB_REV_MASK(0xff000000)) >> CIB_REV_SHIFT(24), nmw = 0x01 (cib & CIB_NMW_MASK(0x0007c000)) >> CIB_NMW_SHIFT(14) -+ // nsw = 0x0 (cib & CIB_NSW_MASK(0x00f80000)) >> CIB_NSW_SHIFT(19), nmp = 0x01 (cib & CIB_NMP_MASK(0x000001f0)) >> CIB_NMP_SHIFT(4) -+ // nsp = 0x01 (cib & CIB_NSP_MASK(0x00003e00)) >> CIB_NSP_SHIFT(9) -+ 0x04004211, -+ // mpd = 0x00000103 -+ 0x00000103, -+ // First Slave Address Descriptor should be port 0: the main register space for the core -+ // addr1 = 0x18042000 (AD_ADDR_MASK = 0xfffff000), addrh = 0x0 (AD_AG32 = 0x00000008), sizeh = 0x0, -+ // sz = 0x0 (AD_SZ_MASK = 0x00000030), sizel = 0x00001000 (0x00001000 << (sz >> 4)) -+ 0x18042005, -+ // Now get master wrappers (i = 0) -+ // addr1 = 0x18110000 (AD_ADDR_MASK = 0xfffff000), addrh = 0x0 (AD_AG32 = 0x00000008), sizeh = 0x0, -+ // sz = 0x0 (AD_SZ_MASK = 0x00000030), sizel = 0x00001000 (0x00001000 << (sz >> 4)) -+ 0x181100c5, -+ -+ // LOOP 3 : #define MFGID_BRCM 0x4bf /* Manufacturer Ids (mfg) */ -+ // #define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ -+ // cia = 0x4bf82d01 -+ // cid = 0x82d (cia & CIA_CID_MASK(0x000fff00)) >> CIA_CID_SHIFT(8), mfg = 0x4bf (cia & CIA_MFG_MASK(0xfff00000)) >> CIA_MFG_SHIFT(20) -+ 0x4bf82d01, -+ // cib = 0x04004211 -+ // crev = 0x04 (cib & CIB_REV_MASK(0xff000000)) >> CIB_REV_SHIFT(24), nmw = 0x01 (cib & CIB_NMW_MASK(0x0007c000)) >> CIB_NMW_SHIFT(14) -+ // nsw = 0x0 (cib & CIB_NSW_MASK(0x00f80000)) >> CIB_NSW_SHIFT(19), nmp = 0x01 (cib & CIB_NMP_MASK(0x000001f0)) >> CIB_NMP_SHIFT(4) -+ // nsp = 0x01 (cib & CIB_NSP_MASK(0x00003e00)) >> CIB_NSP_SHIFT(9) -+ 0x04004211, -+ // mpd = 0x00000203 -+ 0x00000203, -+ // First Slave Address Descriptor should be port 0: the main register space for the core -+ // addr1 = 0x1804a000 (AD_ADDR_MASK = 0xfffff000), addrh = 0x0 (AD_AG32 = 0x00000008), sizeh = 0x0, -+ // sz = 0x0 (AD_SZ_MASK = 0x00000030), sizel = 0x00001000 (0x00001000 << (sz >> 4)) -+ 0x1804a005, -+ // Now get master wrappers (i = 0) -+ // addr1 = 0x18110000 (AD_ADDR_MASK = 0xfffff000), addrh = 0x0 (AD_AG32 = 0x00000008), sizeh = 0x0, -+ // sz = 0x0 (AD_SZ_MASK = 0x00000030), sizel = 0x00001000 (0x00001000 << (sz >> 4)) -+ 0x181110c5, -+ -+ // END of parse loop 0x0f = (ER_END(0x0e) | ER_VALID(0x01)) -+ 0x0000000f -+}; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/sb2_erom.h b/drivers/net/ethernet/broadcom/gmac/src/shared/sb2_erom.h ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/sb2_erom.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/sb2_erom.h 2017-11-09 17:53:44.062302000 +0800 -@@ -0,0 +1,26 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Broadcom Home Networking Division 10/100 Mbit/s Ethernet -+ * Saber2 sudo EROM -+ * -+ */ -+ -+#ifndef _sb2_erom_h_ -+#define _sb2_erom_h_ -+ -+extern uint32 sb2_erom[]; -+ -+#endif /* _sb2_erom_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/sgmiiplus2_serdes.c b/drivers/net/ethernet/broadcom/gmac/src/shared/sgmiiplus2_serdes.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/sgmiiplus2_serdes.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/sgmiiplus2_serdes.c 2017-11-09 17:53:44.063293000 +0800 -@@ -0,0 +1,102 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ * These routines provide access to the serdes -+ * -+ */ -+ -+/* ---- Include Files ---------------------------------------------------- */ -+#include -+#include -+#include "bcmiproc_serdes.h" -+#include "bcmiproc_serdes_def.h" -+#include "../../../mdio/iproc_mdio.h" -+ -+/* ---- External Variable Declarations ----------------------------------- */ -+/* ---- External Function Prototypes ------------------------------------- */ -+/* ---- Public Variables ------------------------------------------------- */ -+/* ---- Private Constants and Types -------------------------------------- */ -+/* ---- Private Variables ------------------------------------------------ */ -+ -+/* debug/trace */ -+//#define BCMDBG -+//#define BCMDBG_ERR -+#ifdef BCMDBG -+#define NET_ERROR(args) printf args -+#define NET_TRACE(args) printf args -+#elif defined(BCMDBG_ERR) -+#define NET_ERROR(args) printf args -+#define NET_TRACE(args) -+#else -+#define NET_ERROR(args) -+#define NET_TRACE(args) -+#endif /* BCMDBG */ -+#define NET_REG_TRACE(args) -+ -+#ifndef ASSERT -+#define ASSERT(exp) -+#endif -+ -+void -+sgmiiplus2_serdes_reset(uint eth_num, uint phyaddr) -+{ -+ uint16 ctrl; -+ -+ ASSERT(phyaddr < MAXEPHY); -+ -+ if (phyaddr == EPHY_NOREG) -+ return; -+ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x1f, 0x0); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0, 0x8000); -+ -+ udelay(100); -+ -+ iproc_mii_read(MII_DEV_LOCAL, phyaddr, 0x0, &ctrl); -+ if (ctrl & 0x8000) -+ NET_ERROR(("et%d: %s serdes reset not complete\n", eth_num, __FUNCTION__)); -+ -+} -+ -+int -+sgmiiplus2_serdes_init(uint eth_num, uint phyaddr) -+{ -+ u16 id1, id2; -+ -+ iproc_mii_read(MII_DEV_LOCAL, phyaddr, 0x0002, &id1); -+ iproc_mii_read(MII_DEV_LOCAL, phyaddr, 0x0003, &id2); -+ printf("Internal phyaddr %d: Get PHY ID0:%.4x, ID1:%.4x\n", phyaddr, id1, id2); -+ -+ /* Disable PLL */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0xffd0); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001e, 0x0000); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x062f); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001e, 0x0000); -+ -+ /* Disable lmtcal (broadcast to all lanes) */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0xffd0); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001e, 0x001f); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8480); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0012, 0x83f8); -+ -+ /* Auto negotiation 10/100/1G - SGMII Slave (broadcast to all lanes) */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8300); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x0100); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8340); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001a, 0x0003); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x0000); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0000, 0x1140); -+ -+ /* Change PLL calibration threshold to 0xc */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0xffd0); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001e, 0x0000); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8180); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0011, 0x0600); -+ -+ /* Enable PLL */ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x001f, 0x8000); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x0010, 0x262f); -+ -+ return 0; -+} -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/siutils.c b/drivers/net/ethernet/broadcom/gmac/src/shared/siutils.c ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/siutils.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/siutils.c 2017-11-09 17:53:44.065294000 +0800 -@@ -0,0 +1,1409 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Misc utility routines for accessing chip-specific features -+ * of the SiliconBackplane-based Broadcom chips. -+ * -+ * $Id: siutils.c 328955 2012-04-23 09:06:12Z $ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "siutils_priv.h" -+ -+/* local prototypes */ -+static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs, -+ uint bustype, void *sdh, char **vars, uint *varsz); -+static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, -+ uint *origidx, void *regs); -+ -+static void si_nvram_process(si_info_t *sii, char *pvars); -+/* dev path concatenation util */ -+static char *si_devpathvar(si_t *sih, char *var, int len, const char *name); -+static bool _si_clkctl_cc(si_info_t *sii, uint mode); -+ -+/* global variable to indicate reservation/release of gpio's */ -+static uint32 si_gpioreservation = 0; -+ -+/* global flag to prevent shared resources from being initialized multiple times in si_attach() */ -+ -+/* -+ * Allocate a si handle. -+ * devid - pci device id (used to determine chip#) -+ * osh - opaque OS handle -+ * regs - virtual address of initial core registers -+ * bustype - pci/pcmcia/sb/sdio/etc -+ * vars - pointer to a pointer area for "environment" variables -+ * varsz - pointer to int to return the size of the vars -+ */ -+si_t * -+BCMATTACHFN(si_attach)(uint devid, osl_t *osh, void *regs, -+ uint bustype, void *sdh, char **vars, uint *varsz) -+{ -+ si_info_t *sii; -+ si_t *sih; -+ -+ /* alloc si_info_t */ -+ if ((sii = MALLOC(osh, sizeof (si_info_t))) == NULL) { -+ SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh))); -+ return (NULL); -+ } -+ -+ if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) { -+ MFREE(osh, sii, sizeof(si_info_t)); -+ SI_ERROR(("%s si_doattach() failed\n", __FUNCTION__)); -+ return (NULL); -+ } -+ sii->vars = vars ? *vars : NULL; -+ sii->varsz = varsz ? *varsz : 0; -+ -+ sih = (si_t*)sii; -+ printk("%s socitype(0x%x) chip(0x%x) chiprev(0x%x) chippkg(0x%x)\n", -+ __FUNCTION__, sih->socitype, sih->chip, sih->chiprev, sih->chippkg); -+ -+ return (si_t *)sii; -+} -+ -+static bool -+BCMATTACHFN(si_buscore_setup)(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, -+ uint *origidx, void *regs) -+{ -+ bool pci, pcie; -+ uint i; -+ uint pciidx, pcieidx, pcirev, pcierev; -+ -+ cc = si_setcoreidx(&sii->pub, SI_CC_IDX); -+ ASSERT((uintptr)cc); -+ -+ /* get chipcommon rev */ -+ sii->pub.ccrev = (int)si_corerev(&sii->pub); -+ -+ /* get chipcommon chipstatus */ -+ if (sii->pub.ccrev >= 11) { -+ sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus); -+ } -+ -+ /* get chipcommon capabilites */ -+ sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities); -+ /* get chipcommon extended capabilities */ -+ if (sii->pub.ccrev >= 35) { -+ sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext); -+ } -+ -+ /* get pmu rev and caps */ -+ if (sii->pub.cccaps & CC_CAP_PMU) { -+ sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities); -+ sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK; -+ } -+ -+ SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n", -+ sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev, -+ sii->pub.pmucaps)); -+ -+ /* figure out bus/orignal core idx */ -+ sii->pub.buscoretype = NODEV_CORE_ID; -+ sii->pub.buscorerev = (uint)NOREV; -+ sii->pub.buscoreidx = BADIDX; -+ -+ pci = pcie = FALSE; -+ pcirev = pcierev = (uint)NOREV; -+ pciidx = pcieidx = BADIDX; -+ -+ for (i = 0; i < sii->numcores; i++) { -+ uint cid, crev; -+ -+ si_setcoreidx(&sii->pub, i); -+ cid = si_coreid(&sii->pub); -+ crev = si_corerev(&sii->pub); -+ -+ /* Display cores found */ -+ SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n", -+ i, cid, crev, sii->coresba[i], sii->regs[i])); -+ -+ /* find the core idx before entering this func. */ -+ if ((savewin && (savewin == sii->coresba[i])) || -+ (regs == sii->regs[i])) { -+ *origidx = i; -+ } -+ } -+ -+ SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, sii->pub.buscoretype, -+ sii->pub.buscorerev)); -+ -+ /* return to the original core */ -+ si_setcoreidx(&sii->pub, *origidx); -+ -+ return TRUE; -+} -+ -+static void -+BCMATTACHFN(si_nvram_process)(si_info_t *sii, char *pvars) -+{ -+ /* get boardtype and boardrev */ -+ switch (BUSTYPE(sii->pub.bustype)) { -+ case SI_BUS: -+ sii->pub.boardvendor = VENDOR_BROADCOM; -+ if (pvars == NULL || ((sii->pub.boardtype = getintvar(pvars, "prodid")) == 0)) { -+ if ((sii->pub.boardtype = getintvar(NULL, "boardtype")) == 0) { -+ sii->pub.boardtype = 0xffff; -+ } -+ } -+ break; -+ } -+ -+ if (sii->pub.boardtype == 0) { -+ SI_ERROR(("si_doattach: unknown board type\n")); -+ ASSERT(sii->pub.boardtype); -+ } -+ -+ sii->pub.boardrev = getintvar(pvars, "boardrev"); -+ sii->pub.boardflags = getintvar(pvars, "boardflags"); -+} -+ -+static si_info_t * -+BCMATTACHFN(si_doattach)(si_info_t *sii, uint devid, osl_t *osh, void *regs, -+ uint bustype, void *sdh, char **vars, uint *varsz) -+{ -+ struct si_pub *sih = &sii->pub; -+ uint32 w, savewin; -+ chipcregs_t *cc; -+ char *pvars = NULL; -+ uint origidx; -+ ASSERT(GOODREGS(regs)); -+ -+ bzero((uchar*)sii, sizeof(si_info_t)); -+ -+ savewin = 0; -+ sih->buscoreidx = BADIDX; -+ sii->curmap = regs; -+ sii->sdh = sdh; -+ sii->osh = osh; -+ -+ /* find Chipcommon address */ -+ cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); -+ -+ sih->bustype = bustype; -+ if (bustype != BUSTYPE(bustype)) { -+ SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n", -+ bustype, BUSTYPE(bustype))); -+ return NULL; -+ } -+ -+ /* ChipID recognition. -+ * We assume we can read chipid at offset 0 from the regs arg. -+ * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon), -+ * some way of recognizing them needs to be added here. -+ */ -+ if (!cc) { -+ SI_ERROR(("%s: chipcommon register space is null \n", __FUNCTION__)); -+ return NULL; -+ } -+ w = R_REG(osh, &cc->chipid); -+ printk("%s chipid: 0x%x\n", __FUNCTION__, w); -+#if defined(CONFIG_MACH_IPROC_P7) -+ sih->socitype = SOCI_AI; -+ /* get chip id rev & pkg */ -+ sih->chip = w & 0xfffff; -+ sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT; -+ w = R_REG(osh, &cc->capabilities); -+ sih->chiprev = w & 0xff; -+#else -+ sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT; -+ /* Might as wll fill in chip id rev & pkg */ -+ sih->chip = w & CID_ID_MASK; -+ sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT; -+ sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT; -+ /* printk("%s chip: 0x%x; chiprev: 0x%x; chippkg: 0x%x\n", __FUNCTION__, sih->chip, sih->chiprev, sih->chippkg); */ -+#endif /* CONFIG_MACH_IPROC_P7 */ -+ -+ sih->issim = IS_SIM(sih->chippkg); -+ -+ /* scan for cores */ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ SI_MSG(("Found chip type SB (0x%08x)\n", w)); -+ sb_scan(sih, regs, devid); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ SI_MSG(("Found chip type %s (0x%08x)\n", (CHIPTYPE(sih->socitype) == SOCI_AI) ? "AI" : "NS", w)); -+ ai_scan(sih, (void *)(uintptr)cc, devid); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ SI_MSG(("Found chip type UBUS (0x%08x), chip id = 0x%4x\n", w, sih->chip)); -+ ub_scan(sih, (void *)(uintptr)cc, devid); -+ } else { -+ SI_ERROR(("Found chip of unknown type (0x%08x)\n", w)); -+ return NULL; -+ } -+ -+ /* no cores found, bail out */ -+ if (sii->numcores == 0) { -+ SI_ERROR(("si_doattach: could not find any cores\n")); -+ return NULL; -+ } -+ /* bus/core/clk setup */ -+ origidx = SI_CC_IDX; -+ if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) { -+ SI_ERROR(("si_doattach: si_buscore_setup failed\n")); -+ goto exit; -+ } -+ -+ spin_lock_init(&sih->sih_lock); -+ -+ /* Init nvram from flash if it exists */ -+ nvram_init((void *)sih); -+ -+ pvars = vars ? *vars : NULL; -+ si_nvram_process(sii, pvars); -+ -+ /* bootloader should retain default pulls */ -+#ifndef BCM_BOOTLOADER -+ if (sih->ccrev >= 20) { -+ uint32 gpiopullup = 0, gpiopulldown = 0; -+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); -+ ASSERT(cc != NULL); -+ -+ W_REG(osh, &cc->gpiopullup, gpiopullup); -+ W_REG(osh, &cc->gpiopulldown, gpiopulldown); -+ si_setcoreidx(sih, origidx); -+ } -+#endif /* !BCM_BOOTLOADER */ -+ -+ -+ /* setup the GPIO based LED powersave register */ -+ if (sih->ccrev >= 16) { -+ if ((w = getintvar(pvars, "leddc")) == 0) { -+ w = DEFAULT_GPIOTIMERVAL; -+ } -+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w); -+ } -+ -+#if !defined(_CFE_) || defined(CFG_WL) -+ /* enable GPIO interrupts when clocks are off */ -+ if (sih->ccrev >= 21) { -+ uint32 corecontrol; -+ corecontrol = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, corecontrol), -+ 0, 0); -+ corecontrol |= CC_ASYNCGPIO; -+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, corecontrol), -+ corecontrol, corecontrol); -+ } -+#endif /* !_CFE_ || CFG_WL */ -+ -+ return (sii); -+exit: -+ return NULL; -+} -+ -+/* may be called with core in reset */ -+void -+BCMATTACHFN(si_detach)(si_t *sih) -+{ -+ si_info_t *sii; -+ uint idx; -+ -+ sii = SI_INFO(sih); -+ if (sii == NULL) { -+ return; -+ } -+ -+ if (BUSTYPE(sih->bustype) == SI_BUS) { -+ for (idx = 0; idx < SI_MAXCORES; idx++) { -+ if (sii->regs[idx]) { -+ REG_UNMAP(sii->regs[idx]); -+ sii->regs[idx] = NULL; -+ } -+ } -+ } -+ -+ MFREE(sii->osh, sii, sizeof(si_info_t)); -+} -+ -+void * -+si_osh(si_t *sih) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ return sii->osh; -+} -+ -+void -+si_setosh(si_t *sih, osl_t *osh) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ if (sii->osh != NULL) { -+ SI_ERROR(("osh is already set....\n")); -+ ASSERT(!sii->osh); -+ } -+ sii->osh = osh; -+} -+ -+uint -+si_intflag(si_t *sih) -+{ -+ si_info_t *sii = SI_INFO(sih); -+ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ return sb_intflag(sih); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ return R_REG(sii->osh, ((uint32 *)(uintptr) -+ (sii->oob_router + OOB_STATUSA))); -+ } -+ -+ ASSERT(0); -+ return 0; -+} -+ -+uint -+si_flag(si_t *sih) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ return sb_flag(sih); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ return ai_flag(sih); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ return ub_flag(sih); -+ } -+ -+ ASSERT(0); -+ return 0; -+} -+ -+void -+si_setint(si_t *sih, int siflag) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ sb_setint(sih, siflag); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ ai_setint(sih, siflag); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ ub_setint(sih, siflag); -+ } else { -+ ASSERT(0); -+ } -+} -+ -+uint -+si_coreid(si_t *sih) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ return sii->coreid[sii->curidx]; -+} -+ -+uint -+si_coreidx(si_t *sih) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ return sii->curidx; -+} -+ -+/* return the core-type instantiation # of the current core */ -+uint -+si_coreunit(si_t *sih) -+{ -+ si_info_t *sii; -+ uint idx; -+ uint coreid; -+ uint coreunit; -+ uint i; -+ -+ sii = SI_INFO(sih); -+ coreunit = 0; -+ -+ idx = sii->curidx; -+ -+ ASSERT(GOODREGS(sii->curmap)); -+ coreid = si_coreid(sih); -+ -+ /* count the cores of our type */ -+ for (i = 0; i < idx; i++) { -+ if (sii->coreid[i] == coreid) { -+ coreunit++; -+ } -+ } -+ -+ return (coreunit); -+} -+ -+uint -+si_corevendor(si_t *sih) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ return sb_corevendor(sih); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ return ai_corevendor(sih); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ return ub_corevendor(sih); -+ } -+ -+ ASSERT(0); -+ return 0; -+} -+ -+bool -+si_backplane64(si_t *sih) -+{ -+ return ((sih->cccaps & CC_CAP_BKPLN64) != 0); -+} -+ -+uint -+si_corerev(si_t *sih) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ return sb_corerev(sih); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ return ai_corerev(sih); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ return ub_corerev(sih); -+ } -+ -+ ASSERT(0); -+ return 0; -+} -+ -+/* return index of coreid or BADIDX if not found */ -+uint -+si_findcoreidx(si_t *sih, uint coreid, uint coreunit) -+{ -+ si_info_t *sii; -+ uint found; -+ uint i; -+ -+ sii = SI_INFO(sih); -+ -+ found = 0; -+ -+ for (i = 0; i < sii->numcores; i++) { -+ if (sii->coreid[i] == coreid) { -+ if (found == coreunit) -+ return (i); -+ found++; -+ } -+ } -+ -+ return (BADIDX); -+} -+ -+/* return list of found cores */ -+uint -+si_corelist(si_t *sih, uint coreid[]) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ -+ bcopy((uchar*)sii->coreid, (uchar*)coreid, (sii->numcores * sizeof(uint))); -+ return (sii->numcores); -+} -+ -+/* return current register mapping */ -+void * -+si_coreregs(si_t *sih) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ ASSERT(GOODREGS(sii->curmap)); -+ -+ return (sii->curmap); -+} -+ -+/* -+ * This function changes logical "focus" to the indicated core; -+ * must be called with interrupts off. -+ * Moreover, callers should keep interrupts off during switching out of and back to d11 core -+ */ -+void * -+si_setcore(si_t *sih, uint coreid, uint coreunit) -+{ -+ uint idx; -+ -+ idx = si_findcoreidx(sih, coreid, coreunit); -+ if (!GOODIDX(idx)) { -+ return (NULL); -+ } -+ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ return sb_setcoreidx(sih, idx); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ return ai_setcoreidx(sih, idx); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ return ub_setcoreidx(sih, idx); -+ } -+ -+ ASSERT(0); -+ return NULL; -+} -+ -+void * -+si_setcoreidx(si_t *sih, uint coreidx) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ return sb_setcoreidx(sih, coreidx); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ return ai_setcoreidx(sih, coreidx); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ return ub_setcoreidx(sih, coreidx); -+ } -+ -+ ASSERT(0); -+ return 0; -+} -+ -+/* Turn off interrupt as required by sb_setcore, before switch core */ -+void * -+si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val) -+{ -+ void *cc; -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ -+ if (SI_FAST(sii)) { -+ /* Overloading the origidx variable to remember the coreid, -+ * this works because the core ids cannot be confused with -+ * core indices. -+ */ -+ *origidx = coreid; -+ if (coreid == CC_CORE_ID) { -+ return (void *)CCREGS_FAST(sii); -+ } else if (coreid == sih->buscoretype) { -+ return (void *)PCIEREGS(sii); -+ } -+ } -+ INTR_OFF(sii, *intr_val); -+ *origidx = sii->curidx; -+ cc = si_setcore(sih, coreid, 0); -+ ASSERT(cc != NULL); -+ -+ return cc; -+} -+ -+/* restore coreidx and restore interrupt */ -+void -+si_restore_core(si_t *sih, uint coreid, uint intr_val) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ if (SI_FAST(sii) && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype))) { -+ return; -+ } -+ -+ si_setcoreidx(sih, coreid); -+ INTR_RESTORE(sii, intr_val); -+} -+ -+int -+si_numaddrspaces(si_t *sih) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ return sb_numaddrspaces(sih); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ return ai_numaddrspaces(sih); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ return ub_numaddrspaces(sih); -+ } -+ -+ ASSERT(0); -+ return 0; -+} -+ -+uint32 -+si_addrspace(si_t *sih, uint asidx) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ return sb_addrspace(sih, asidx); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ return ai_addrspace(sih, asidx); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ return ub_addrspace(sih, asidx); -+ } -+ -+ ASSERT(0); -+ return 0; -+} -+ -+uint32 -+si_addrspacesize(si_t *sih, uint asidx) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ return sb_addrspacesize(sih, asidx); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ return ai_addrspacesize(sih, asidx); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ return ub_addrspacesize(sih, asidx); -+ } -+ -+ ASSERT(0); -+ return 0; -+} -+ -+void -+si_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size) -+{ -+ /* Only supported for SOCI_AI */ -+ if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ ai_coreaddrspaceX(sih, asidx, addr, size); -+ } else { -+ *size = 0; -+ } -+} -+ -+uint32 -+si_core_cflags(si_t *sih, uint32 mask, uint32 val) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ return sb_core_cflags(sih, mask, val); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ return ai_core_cflags(sih, mask, val); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ return ub_core_cflags(sih, mask, val); -+ } -+ -+ ASSERT(0); -+ return 0; -+} -+ -+void -+si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ sb_core_cflags_wo(sih, mask, val); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ ai_core_cflags_wo(sih, mask, val); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ ub_core_cflags_wo(sih, mask, val); -+ } else { -+ ASSERT(0); -+ } -+} -+ -+uint32 -+si_core_sflags(si_t *sih, uint32 mask, uint32 val) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ return sb_core_sflags(sih, mask, val); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ return ai_core_sflags(sih, mask, val); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ return ub_core_sflags(sih, mask, val); -+ } -+ -+ ASSERT(0); -+ return 0; -+} -+ -+bool -+si_iscoreup(si_t *sih) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ return sb_iscoreup(sih); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ return ai_iscoreup(sih); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ return ub_iscoreup(sih); -+ } -+ -+ ASSERT(0); -+ return FALSE; -+} -+ -+uint -+si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val) -+{ -+ /* only for AI back plane chips */ -+ if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ return (ai_wrap_reg(sih, offset, mask, val)); -+ } -+ return 0; -+} -+ -+uint -+si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ return sb_corereg(sih, coreidx, regoff, mask, val); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ return ai_corereg(sih, coreidx, regoff, mask, val); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ return ub_corereg(sih, coreidx, regoff, mask, val); -+ } -+ -+ ASSERT(0); -+ return 0; -+} -+ -+void -+si_core_disable(si_t *sih, uint32 bits) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ sb_core_disable(sih, bits); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ ai_core_disable(sih, bits); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ ub_core_disable(sih, bits); -+ } -+} -+ -+void -+si_core_reset(si_t *sih, uint32 bits, uint32 resetbits) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ sb_core_reset(sih, bits, resetbits); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ ai_core_reset(sih, bits, resetbits); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ ub_core_reset(sih, bits, resetbits); -+ } -+} -+ -+/* Run bist on current core. Caller needs to take care of core-specific bist hazards */ -+int -+si_corebist(si_t *sih) -+{ -+ uint32 cflags; -+ int result = 0; -+ -+ /* Read core control flags */ -+ cflags = si_core_cflags(sih, 0, 0); -+ -+ /* Set bist & fgc */ -+ si_core_cflags(sih, ~0, (SICF_BIST_EN | SICF_FGC)); -+ -+ /* Wait for bist done */ -+ SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 100000); -+ -+ if (si_core_sflags(sih, 0, 0) & SISF_BIST_ERROR) { -+ result = BCME_ERROR; -+ } -+ -+ /* Reset core control flags */ -+ si_core_cflags(sih, 0xffff, cflags); -+ -+ return result; -+} -+ -+static uint32 -+BCMINITFN(factor6)(uint32 x) -+{ -+ switch (x) { -+ case CC_F6_2: return 2; -+ case CC_F6_3: return 3; -+ case CC_F6_4: return 4; -+ case CC_F6_5: return 5; -+ case CC_F6_6: return 6; -+ case CC_F6_7: return 7; -+ default: return 0; -+ } -+} -+ -+/* calculate the speed the SI would run at given a set of clockcontrol values */ -+uint32 -+BCMINITFN(si_clock_rate)(uint32 pll_type, uint32 n, uint32 m) -+{ -+ uint32 n1, n2, clock, m1, m2, m3, mc; -+ -+ n1 = n & CN_N1_MASK; -+ n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; -+ -+ if (pll_type == PLL_TYPE6) { -+ if (m & CC_T6_MMASK) { -+ return CC_T6_M1; -+ } else { -+ return CC_T6_M0; -+ } -+ } else if ((pll_type == PLL_TYPE1) || -+ (pll_type == PLL_TYPE3) || -+ (pll_type == PLL_TYPE4) || -+ (pll_type == PLL_TYPE7)) { -+ n1 = factor6(n1); -+ n2 += CC_F5_BIAS; -+ } else if (pll_type == PLL_TYPE2) { -+ n1 += CC_T2_BIAS; -+ n2 += CC_T2_BIAS; -+ ASSERT((n1 >= 2) && (n1 <= 7)); -+ ASSERT((n2 >= 5) && (n2 <= 23)); -+ } else if (pll_type == PLL_TYPE5) { -+ return (100000000); -+ } else { -+ ASSERT(0); -+ } -+ -+ /* PLL types 3 and 7 use BASE2 (25Mhz) */ -+ if ((pll_type == PLL_TYPE3) || -+ (pll_type == PLL_TYPE7)) { -+ clock = CC_CLOCK_BASE2 * n1 * n2; -+ } else { -+ clock = CC_CLOCK_BASE1 * n1 * n2; -+ } -+ -+ if (clock == 0) { -+ return 0; -+ } -+ -+ m1 = m & CC_M1_MASK; -+ m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; -+ m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; -+ mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; -+ -+ if ((pll_type == PLL_TYPE1) || -+ (pll_type == PLL_TYPE3) || -+ (pll_type == PLL_TYPE4) || -+ (pll_type == PLL_TYPE7)) { -+ m1 = factor6(m1); -+ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3)) { -+ m2 += CC_F5_BIAS; -+ } else { -+ m2 = factor6(m2); -+ } -+ m3 = factor6(m3); -+ -+ switch (mc) { -+ case CC_MC_BYPASS: return (clock); -+ case CC_MC_M1: return (clock / m1); -+ case CC_MC_M1M2: return (clock / (m1 * m2)); -+ case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3)); -+ case CC_MC_M1M3: return (clock / (m1 * m3)); -+ default: return (0); -+ } -+ } else { -+ ASSERT(pll_type == PLL_TYPE2); -+ -+ m1 += CC_T2_BIAS; -+ m2 += CC_T2M2_BIAS; -+ m3 += CC_T2_BIAS; -+ ASSERT((m1 >= 2) && (m1 <= 7)); -+ ASSERT((m2 >= 3) && (m2 <= 10)); -+ ASSERT((m3 >= 2) && (m3 <= 7)); -+ -+ if ((mc & CC_T2MC_M1BYP) == 0) { -+ clock /= m1; -+ } -+ if ((mc & CC_T2MC_M2BYP) == 0) { -+ clock /= m2; -+ } -+ if ((mc & CC_T2MC_M3BYP) == 0) { -+ clock /= m3; -+ } -+ -+ return (clock); -+ } -+} -+ -+uint32 -+BCMINITFN(si_clock)(si_t *sih) -+{ -+ if (sih->chippkg == BCM4709_PKG_ID) { -+ return NS_SI_CLOCK; -+ } -+ return NS_SLOW_SI_CLOCK; -+} -+ -+#if defined(BCMDBG) -+/* print interesting sbconfig registers */ -+void -+si_dumpregs(si_t *sih, struct bcmstrbuf *b) -+{ -+ si_info_t *sii; -+ uint origidx, intr_val = 0; -+ -+ sii = SI_INFO(sih); -+ origidx = sii->curidx; -+ -+ INTR_OFF(sii, intr_val); -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ sb_dumpregs(sih, b); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ ai_dumpregs(sih, b); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ ub_dumpregs(sih, b); -+ } else { -+ ASSERT(0); -+ } -+ -+ si_setcoreidx(sih, origidx); -+ INTR_RESTORE(sii, intr_val); -+} -+#endif -+ -+#ifdef BCMDBG -+void -+si_view(si_t *sih, bool verbose) -+{ -+ if (CHIPTYPE(sih->socitype) == SOCI_SB) { -+ sb_view(sih, verbose); -+ } else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ ai_view(sih, verbose); -+ } else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) { -+ ub_view(sih, verbose); -+ } else { -+ ASSERT(0); -+ } -+} -+ -+void -+si_viewall(si_t *sih, bool verbose) -+{ -+ si_info_t *sii; -+ uint curidx, i; -+ uint intr_val = 0; -+ -+ sii = SI_INFO(sih); -+ curidx = sii->curidx; -+ -+ INTR_OFF(sii, intr_val); -+ if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NS)) { -+ ai_viewall(sih, verbose); -+ } else { -+ SI_ERROR(("si_viewall: num_cores %d\n", sii->numcores)); -+ for (i = 0; i < sii->numcores; i++) { -+ si_setcoreidx(sih, i); -+ si_view(sih, verbose); -+ } -+ } -+ si_setcoreidx(sih, curidx); -+ INTR_RESTORE(sii, intr_val); -+} -+#endif /* BCMDBG */ -+ -+/* return the slow clock source - LPO, XTAL, or PCI */ -+static uint -+si_slowclk_src(si_info_t *sii) -+{ -+ chipcregs_t *cc; -+ -+ ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); -+ -+ if (sii->pub.ccrev < 6) { -+ return (SCC_SS_XTAL); -+ } else if (sii->pub.ccrev < 10) { -+ cc = (chipcregs_t *)si_setcoreidx(&sii->pub, sii->curidx); -+ return (R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK); -+ } else { /* Insta-clock */ -+ return (SCC_SS_XTAL); -+ } -+} -+ -+/* return the ILP (slowclock) min or max frequency */ -+static uint -+si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc) -+{ -+ uint32 slowclk; -+ uint div; -+ -+ ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); -+ -+ /* shouldn't be here unless we've established the chip has dynamic clk control */ -+ ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL); -+ -+ slowclk = si_slowclk_src(sii); -+ if (sii->pub.ccrev < 6) { -+ if (slowclk == SCC_SS_PCI) { -+ return (max_freq ? (PCIMAXFREQ / 64) : (PCIMINFREQ / 64)); -+ } else { -+ return (max_freq ? (XTALMAXFREQ / 32) : (XTALMINFREQ / 32)); -+ } -+ } else if (sii->pub.ccrev < 10) { -+ div = 4 * -+ (((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); -+ if (slowclk == SCC_SS_LPO) { -+ return (max_freq ? LPOMAXFREQ : LPOMINFREQ); -+ } else if (slowclk == SCC_SS_XTAL) { -+ return (max_freq ? (XTALMAXFREQ / div) : (XTALMINFREQ / div)); -+ } else if (slowclk == SCC_SS_PCI) { -+ return (max_freq ? (PCIMAXFREQ / div) : (PCIMINFREQ / div)); -+ } else { -+ ASSERT(0); -+ } -+ } else { -+ /* Chipc rev 10 is InstaClock */ -+ div = R_REG(sii->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT; -+ div = 4 * (div + 1); -+ return (max_freq ? XTALMAXFREQ : (XTALMINFREQ / div)); -+ } -+ return (0); -+} -+ -+static void -+BCMINITFN(si_clkctl_setdelay)(si_info_t *sii, void *chipcregs) -+{ -+ chipcregs_t *cc = (chipcregs_t *)chipcregs; -+ uint slowmaxfreq, pll_delay, slowclk; -+ uint pll_on_delay, fref_sel_delay; -+ -+ pll_delay = PLL_DELAY; -+ -+ /* If the slow clock is not sourced by the xtal then add the xtal_on_delay -+ * since the xtal will also be powered down by dynamic clk control logic. -+ */ -+ -+ slowclk = si_slowclk_src(sii); -+ if (slowclk != SCC_SS_XTAL) { -+ pll_delay += XTAL_ON_DELAY; -+ } -+ -+ /* Starting with 4318 it is ILP that is used for the delays */ -+ slowmaxfreq = si_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? FALSE : TRUE, cc); -+ -+ pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; -+ fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; -+ -+ W_REG(sii->osh, &cc->pll_on_delay, pll_on_delay); -+ W_REG(sii->osh, &cc->fref_sel_delay, fref_sel_delay); -+} -+ -+/* initialize power control delay registers */ -+void -+BCMINITFN(si_clkctl_init)(si_t *sih) -+{ -+ si_info_t *sii; -+ uint origidx = 0; -+ chipcregs_t *cc; -+ bool fast; -+ -+ if (!CCCTL_ENAB(sih)) { -+ return; -+ } -+ -+ sii = SI_INFO(sih); -+ fast = SI_FAST(sii); -+ if (!fast) { -+ origidx = sii->curidx; -+ if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) { -+ return; -+ } -+ } else if ((cc = (chipcregs_t *)CCREGS_FAST(sii)) == NULL) { -+ return; -+ } -+ ASSERT(cc != NULL); -+ -+ /* set all Instaclk chip ILP to 1 MHz */ -+ if (sih->ccrev >= 10) { -+ SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK, -+ (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); -+ } -+ -+ si_clkctl_setdelay(sii, (void *)(uintptr)cc); -+ -+ if (!fast) { -+ si_setcoreidx(sih, origidx); -+ } -+} -+ -+/* turn primary xtal and/or pll off/on */ -+int -+si_clkctl_xtal(si_t *sih, uint what, bool on) -+{ -+ switch (BUSTYPE(sih->bustype)) { -+ -+ default: -+ return (-1); -+ } -+ -+} -+ -+/* -+ * clock control policy function throught chipcommon -+ * -+ * set dynamic clk control mode (forceslow, forcefast, dynamic) -+ * returns true if we are forcing fast clock -+ * this is a wrapper over the next internal function -+ * to allow flexible policy settings for outside caller -+ */ -+bool -+si_clkctl_cc(si_t *sih, uint mode) -+{ -+ si_info_t *sii; -+ -+ sii = SI_INFO(sih); -+ -+ /* chipcommon cores prior to rev6 don't support dynamic clock control */ -+ if (sih->ccrev < 6) { -+ return FALSE; -+ } -+ -+ return _si_clkctl_cc(sii, mode); -+} -+ -+/* clk control mechanism through chipcommon, no policy checking */ -+static bool -+_si_clkctl_cc(si_info_t *sii, uint mode) -+{ -+ uint origidx = 0; -+ chipcregs_t *cc; -+ uint32 scc; -+ uint intr_val = 0; -+ bool fast = SI_FAST(sii); -+ -+ /* chipcommon cores prior to rev6 don't support dynamic clock control */ -+ if (sii->pub.ccrev < 6) { -+ return (FALSE); -+ } -+ -+ /* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */ -+ ASSERT(sii->pub.ccrev != 10); -+ -+ if (!fast) { -+ INTR_OFF(sii, intr_val); -+ origidx = sii->curidx; -+ -+ if ((BUSTYPE(sii->pub.bustype) == SI_BUS) && -+ si_setcore(&sii->pub, MIPS33_CORE_ID, 0) && -+ (si_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10)) { -+ goto done; -+ } -+ -+ cc = (chipcregs_t *) si_setcore(&sii->pub, CC_CORE_ID, 0); -+ } else if ((cc = (chipcregs_t *) CCREGS_FAST(sii)) == NULL) { -+ goto done; -+ } -+ -+ ASSERT(cc != NULL); -+ -+ if (!CCCTL_ENAB(&sii->pub) && (sii->pub.ccrev < 20)) { -+ goto done; -+ } -+ -+ switch (mode) { -+ case CLK_FAST: /* FORCEHT, fast (pll) clock */ -+ if (sii->pub.ccrev < 10) { -+ /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */ -+ si_clkctl_xtal(&sii->pub, XTAL, ON); -+ SET_REG(sii->osh, &cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP); -+ } else if (sii->pub.ccrev < 20) { -+ OR_REG(sii->osh, &cc->system_clk_ctl, SYCC_HR); -+ } else { -+ OR_REG(sii->osh, &cc->clk_ctl_st, CCS_FORCEHT); -+ } -+ -+ /* wait for the PLL */ -+ if (PMUCTL_ENAB(&sii->pub)) { -+ uint32 htavail = CCS_HTAVAIL; -+ -+ SPINWAIT(((R_REG(sii->osh, &cc->clk_ctl_st) & htavail) == 0), -+ PMU_MAX_TRANSITION_DLY); -+ ASSERT(R_REG(sii->osh, &cc->clk_ctl_st) & htavail); -+ } else { -+ OSL_DELAY(PLL_DELAY); -+ } -+ break; -+ -+ case CLK_DYNAMIC: /* enable dynamic clock control */ -+ if (sii->pub.ccrev < 10) { -+ scc = R_REG(sii->osh, &cc->slow_clk_ctl); -+ scc &= ~(SCC_FS | SCC_IP | SCC_XC); -+ if ((scc & SCC_SS_MASK) != SCC_SS_XTAL) { -+ scc |= SCC_XC; -+ } -+ W_REG(sii->osh, &cc->slow_clk_ctl, scc); -+ -+ /* for dynamic control, we have to release our xtal_pu "force on" */ -+ if (scc & SCC_XC) { -+ si_clkctl_xtal(&sii->pub, XTAL, OFF); -+ } -+ } else if (sii->pub.ccrev < 20) { -+ /* Instaclock */ -+ AND_REG(sii->osh, &cc->system_clk_ctl, ~SYCC_HR); -+ } else { -+ AND_REG(sii->osh, &cc->clk_ctl_st, ~CCS_FORCEHT); -+ } -+ break; -+ -+ default: -+ ASSERT(0); -+ } -+ -+done: -+ if (!fast) { -+ si_setcoreidx(&sii->pub, origidx); -+ INTR_RESTORE(sii, intr_val); -+ } -+ return (mode == CLK_FAST); -+} -+ -+/* Build device path. Support SI, PCI, and JTAG for now. */ -+int -+BCMNMIATTACHFN(si_devpath)(si_t *sih, char *path, int size) -+{ -+ int slen; -+ -+ ASSERT(path != NULL); -+ ASSERT(size >= SI_DEVPATH_BUFSZ); -+ -+ if (!path || size <= 0) -+ return -1; -+ -+ switch (BUSTYPE(sih->bustype)) { -+ case SI_BUS: -+ slen = snprintf(path, (size_t)size, "sb/%u/", si_coreidx(sih)); -+ break; -+ default: -+ slen = -1; -+ ASSERT(0); -+ break; -+ } -+ -+ if (slen < 0 || slen >= size) { -+ path[0] = '\0'; -+ return -1; -+ } -+ -+ return 0; -+} -+ -+char * -+BCMATTACHFN(si_coded_devpathvar)(si_t *sih, char *varname, int var_len, const char *name) -+{ -+ char pathname[SI_DEVPATH_BUFSZ + 32]; -+ char devpath[SI_DEVPATH_BUFSZ + 32]; -+ char *p; -+ int idx; -+ int len; -+ -+ /* try to get compact devpath if it exist */ -+ if (si_devpath(sih, devpath, SI_DEVPATH_BUFSZ) == 0) { -+ len = strlen(devpath); -+ devpath[len - 1] = '\0'; -+ for (idx = 0; idx < SI_MAXCORES; idx++) { -+ snprintf(pathname, SI_DEVPATH_BUFSZ, "devpath%d", idx); -+ if ((p = getvar(NULL, pathname)) == NULL) { -+ continue; -+ } -+ -+ if (strncmp(p, devpath, len) == 0) { -+ snprintf(varname, var_len, "%d:%s", idx, name); -+ return varname; -+ } -+ } -+ } -+ -+ return NULL; -+} -+ -+/* Get a variable, but only if it has a devpath prefix */ -+int -+BCMATTACHFN(si_getdevpathintvar)(si_t *sih, const char *name) -+{ -+#if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS) -+ return (getintvar(NULL, name)); -+#else -+ char varname[SI_DEVPATH_BUFSZ + 32]; -+ int val; -+ -+ si_devpathvar(sih, varname, sizeof(varname), name); -+ -+ if ((val = getintvar(NULL, varname)) != 0) { -+ return val; -+ } -+ -+ /* try to get compact devpath if it exist */ -+ if (si_coded_devpathvar(sih, varname, sizeof(varname), name) == NULL) { -+ return 0; -+ } -+ -+ return (getintvar(NULL, varname)); -+#endif /* BCMBUSTYPE && BCMBUSTYPE == SI_BUS */ -+} -+ -+/* Concatenate the dev path with a varname into the given 'var' buffer -+ * and return the 'var' pointer. -+ * Nothing is done to the arguments if len == 0 or var is NULL, var is still returned. -+ * On overflow, the first char will be set to '\0'. -+ */ -+static char * -+BCMATTACHFN(si_devpathvar)(si_t *sih, char *var, int len, const char *name) -+{ -+ uint path_len; -+ -+ if (!var || len <= 0) { -+ return var; -+ } -+ -+ if (si_devpath(sih, var, len) == 0) { -+ path_len = strlen(var); -+ -+ if (strlen(name) + 1 > (uint)(len - path_len)) { -+ var[0] = '\0'; -+ } else { -+ strncpy(var + path_len, name, len - path_len - 1); -+ } -+ } -+ -+ return var; -+} -+ -+ -+#if defined(BCMDBG) -+#endif -+ -+/* mask&set gpio output enable bits */ -+uint32 -+si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority) -+{ -+ uint regoff; -+ -+ regoff = 0; -+ -+ /* gpios could be shared on router platforms -+ * ignore reservation if it's high priority (e.g., test apps) -+ */ -+ if ((priority != GPIO_HI_PRIORITY) && -+ (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { -+ mask = priority ? (si_gpioreservation & mask) : -+ ((si_gpioreservation | mask) & ~(si_gpioreservation)); -+ val &= mask; -+ } -+ -+ regoff = OFFSETOF(chipcregs_t, gpioouten); -+ return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -+} -+ -+/* mask&set gpio output bits */ -+uint32 -+si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority) -+{ -+ uint regoff; -+ -+ regoff = 0; -+ -+ /* gpios could be shared on router platforms -+ * ignore reservation if it's high priority (e.g., test apps) -+ */ -+ if ((priority != GPIO_HI_PRIORITY) && -+ (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { -+ mask = priority ? (si_gpioreservation & mask) : -+ ((si_gpioreservation | mask) & ~(si_gpioreservation)); -+ val &= mask; -+ } -+ -+ regoff = OFFSETOF(chipcregs_t, gpioout); -+ return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); -+} -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/gmac/src/shared/siutils_priv.h b/drivers/net/ethernet/broadcom/gmac/src/shared/siutils_priv.h ---- a/drivers/net/ethernet/broadcom/gmac/src/shared/siutils_priv.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/gmac/src/shared/siutils_priv.h 2017-11-09 17:53:44.066299000 +0800 -@@ -0,0 +1,236 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ * -+ * Include file private to the SOC Interconnect support files. -+ * -+ * $Id: siutils_priv.h 302333 2011-12-11 01:47:49Z $ -+ */ -+ -+#ifndef _siutils_priv_h_ -+#define _siutils_priv_h_ -+ -+#ifdef BCMDBG_ERR -+#define SI_ERROR(args) printf args -+#else -+#define SI_ERROR(args) -+#endif /* BCMDBG_ERR */ -+ -+#ifdef BCMDBG -+#define SI_MSG(args) printf args -+#else -+#define SI_MSG(args) -+#endif /* BCMDBG */ -+ -+#ifdef BCMDBG_SI -+#define SI_VMSG(args) printf args -+#else -+#define SI_VMSG(args) -+#endif -+ -+#define IS_SIM(chippkg) ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) -+ -+typedef uint32 (*si_intrsoff_t)(void *intr_arg); -+typedef void (*si_intrsrestore_t)(void *intr_arg, uint32 arg); -+typedef bool (*si_intrsenabled_t)(void *intr_arg); -+ -+typedef struct gpioh_item { -+ void *arg; -+ bool level; -+ gpio_handler_t handler; -+ uint32 event; -+ struct gpioh_item *next; -+} gpioh_item_t; -+ -+/* misc si info needed by some of the routines */ -+typedef struct si_info { -+ struct si_pub pub; /* back plane public state (must be first field) */ -+ -+ void *osh; /* osl os handle */ -+ void *sdh; /* bcmsdh handle */ -+ -+ uint dev_coreid; /* the core provides driver functions */ -+ void *intr_arg; /* interrupt callback function arg */ -+ si_intrsoff_t intrsoff_fn; /* turns chip interrupts off */ -+ si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */ -+ si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */ -+ -+ void *pch; /* PCI/E core handle */ -+ gpioh_item_t *gpioh_head; /* GPIO event handlers list */ -+ bool memseg; /* flag to toggle MEM_SEG register */ -+ char *vars; -+ uint varsz; -+ -+ void *curmap; /* current regs va */ -+ void *regs[SI_MAXCORES]; /* other regs va */ -+ -+ uint curidx; /* current core index */ -+ uint numcores; /* # discovered cores */ -+ uint coreid[SI_MAXCORES]; /* id of each core */ -+ uint32 coresba[SI_MAXCORES]; /* backplane address of each core */ -+ void *regs2[SI_MAXCORES]; /* va of each core second register set (usbh20) */ -+ uint32 coresba2[SI_MAXCORES]; /* address of each core second register set (usbh20) */ -+ uint32 coresba_size[SI_MAXCORES]; /* backplane address space size */ -+ uint32 coresba2_size[SI_MAXCORES]; /* second address space size */ -+ -+ void *curwrap; /* current wrapper va */ -+ void *wrappers[SI_MAXCORES]; /* other cores wrapper va */ -+ uint32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */ -+ -+ uint32 cia[SI_MAXCORES]; /* erom cia entry for each core */ -+ uint32 cib[SI_MAXCORES]; /* erom cia entry for each core */ -+ uint32 oob_router; /* oob router registers for axi */ -+} si_info_t; -+ -+#define SI_INFO(sih) (si_info_t *)(uintptr)sih -+ -+#define GOODCOREADDR(x, b) (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ -+ ISALIGNED((x), SI_CORE_SIZE)) -+#define GOODREGS(regs) ((regs) != NULL && ISALIGNED((uintptr)(regs), SI_CORE_SIZE)) -+#define BADCOREADDR 0 -+#define GOODIDX(idx) (((uint)idx) < SI_MAXCORES) -+#define NOREV -1 /* Invalid rev */ -+ -+#define PCI(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ -+ ((si)->pub.buscoretype == PCI_CORE_ID)) -+ -+#define PCIE_GEN1(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ -+ ((si)->pub.buscoretype == PCIE_CORE_ID)) -+ -+#define PCIE_GEN2(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ -+ ((si)->pub.buscoretype == PCIE2_CORE_ID)) -+ -+#define PCIE(si) (PCIE_GEN1(si) || PCIE_GEN2(si)) -+ -+#define PCMCIA(si) ((BUSTYPE((si)->pub.bustype) == PCMCIA_BUS) && ((si)->memseg == TRUE)) -+ -+/* Newer chips can access PCI/PCIE and CC core without requiring to change -+ * PCI BAR0 WIN -+ */ -+#define SI_FAST(si) (PCIE(si) || (PCI(si) && ((si)->pub.buscorerev >= 13))) -+ -+#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET)) -+#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET)) -+ -+/* -+ * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/ -+ * after core switching to avoid invalid register accesss inside ISR. -+ */ -+#define INTR_OFF(si, intr_val) \ -+ if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ -+ intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } -+#define INTR_RESTORE(si, intr_val) \ -+ if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ -+ (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } -+ -+/* dynamic clock control defines */ -+#define LPOMINFREQ 25000 /* low power oscillator min */ -+#define LPOMAXFREQ 43000 /* low power oscillator max */ -+#define XTALMINFREQ 19800000 /* 20 MHz - 1% */ -+#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ -+#define PCIMINFREQ 25000000 /* 25 MHz */ -+#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ -+ -+#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ -+#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ -+ -+/* GPIO Based LED powersave defines */ -+#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */ -+#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */ -+#ifndef DEFAULT_GPIOTIMERVAL -+#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) -+#endif -+ -+#define sb_scan(a, b, c) do {} while (0) -+#define sb_coreid(a) (0) -+#define sb_intflag(a) (0) -+#define sb_flag(a) (0) -+#define sb_setint(a, b) do {} while (0) -+#define sb_corevendor(a) (0) -+#define sb_corerev(a) (0) -+#define sb_corereg(a, b, c, d, e) (0) -+#define sb_iscoreup(a) (false) -+#define sb_setcoreidx(a, b) (0) -+#define sb_core_cflags(a, b, c) (0) -+#define sb_core_cflags_wo(a, b, c) do {} while (0) -+#define sb_core_sflags(a, b, c) (0) -+#define sb_commit(a) do {} while (0) -+#define sb_base(a) (0) -+#define sb_size(a) (0) -+#define sb_core_reset(a, b, c) do {} while (0) -+#define sb_core_disable(a, b) do {} while (0) -+#define sb_addrspace(a, b) (0) -+#define sb_addrspacesize(a, b) (0) -+#define sb_numaddrspaces(a) (0) -+#define sb_set_initiator_to(a, b, c) (0) -+#define sb_taclear(a, b) (false) -+#define sb_view(a, b) do {} while (0) -+#define sb_viewall(a, b) do {} while (0) -+#define sb_dump(a, b) do {} while (0) -+#define sb_dumpregs(a, b) do {} while (0) -+ -+ -+/* AMBA Interconnect exported externs */ -+extern si_t *ai_attach(uint pcidev, osl_t *osh, void *regs, uint bustype, -+ void *sdh, char **vars, uint *varsz); -+extern si_t *ai_kattach(osl_t *osh); -+extern void ai_scan(si_t *sih, void *regs, uint devid); -+extern uint ai_flag(si_t *sih); -+extern void ai_setint(si_t *sih, int siflag); -+extern uint ai_coreidx(si_t *sih); -+extern uint ai_corevendor(si_t *sih); -+extern uint ai_corerev(si_t *sih); -+extern bool ai_iscoreup(si_t *sih); -+extern void *ai_setcoreidx(si_t *sih, uint coreidx); -+extern uint32 ai_core_cflags(si_t *sih, uint32 mask, uint32 val); -+extern void ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val); -+extern uint32 ai_core_sflags(si_t *sih, uint32 mask, uint32 val); -+extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); -+extern void ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits); -+extern void ai_core_disable(si_t *sih, uint32 bits); -+extern int ai_numaddrspaces(si_t *sih); -+extern uint32 ai_addrspace(si_t *sih, uint asidx); -+extern uint32 ai_addrspacesize(si_t *sih, uint asidx); -+extern void ai_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size); -+extern uint ai_wrap_reg(si_t *sih, uint32 offset, uint32 mask, uint32 val); -+#ifdef BCMDBG -+extern void ai_view(si_t *sih, bool verbose); -+extern void ai_viewall(si_t *sih, bool verbose); -+#endif /* BCMDBG */ -+#if defined(BCMDBG) -+extern void ai_dumpregs(si_t *sih, struct bcmstrbuf *b); -+#endif -+ -+ -+#define ub_scan(a, b, c) do {} while (0) -+#define ub_flag(a) (0) -+#define ub_setint(a, b) do {} while (0) -+#define ub_coreidx(a) (0) -+#define ub_corevendor(a) (0) -+#define ub_corerev(a) (0) -+#define ub_iscoreup(a) (0) -+#define ub_setcoreidx(a, b) (0) -+#define ub_core_cflags(a, b, c) (0) -+#define ub_core_cflags_wo(a, b, c) do {} while (0) -+#define ub_core_sflags(a, b, c) (0) -+#define ub_corereg(a, b, c, d, e) (0) -+#define ub_core_reset(a, b, c) do {} while (0) -+#define ub_core_disable(a, b) do {} while (0) -+#define ub_numaddrspaces(a) (0) -+#define ub_addrspace(a, b) (0) -+#define ub_addrspacesize(a, b) (0) -+#define ub_view(a, b) do {} while (0) -+#define ub_dumpregs(a, b) do {} while (0) -+ -+#endif /* _siutils_priv_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/mdio/Kconfig b/drivers/net/ethernet/broadcom/mdio/Kconfig ---- a/drivers/net/ethernet/broadcom/mdio/Kconfig 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/mdio/Kconfig 2017-11-09 17:53:44.076300000 +0800 -@@ -0,0 +1,23 @@ -+# -+# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+# -+# 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 MDIO_XGS_IPROC -+ tristate "BRCM XGS iProc MDIO support" -+ depends on ARCH_XGS_IPROC -+ default n -+ help -+ MDIO support -+ -+ If unsure, say N. -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/mdio/Makefile b/drivers/net/ethernet/broadcom/mdio/Makefile ---- a/drivers/net/ethernet/broadcom/mdio/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/mdio/Makefile 2017-11-09 17:53:44.077310000 +0800 -@@ -0,0 +1,17 @@ -+# -+# Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+# -+# 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. -+# -+obj-$(CONFIG_MDIO_XGS_IPROC) := iproc_mii.o -+iproc_mii-objs := ccb_mdio.o cmicd_mdio.o ccg_mdio.o iproc_mdio.o -\ No newline at end of file -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/mdio/ccb_mdio.c b/drivers/net/ethernet/broadcom/mdio/ccb_mdio.c ---- a/drivers/net/ethernet/broadcom/mdio/ccb_mdio.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/mdio/ccb_mdio.c 2017-11-09 17:53:44.079291000 +0800 -@@ -0,0 +1,873 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ */ -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+ -+#include "iproc_mdio.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "iproc_mdio_dev.h" -+ -+#ifdef CONFIG_OF_MDIO -+#include -+#include -+#include -+static struct iproc_mdiobus_data iproc_mdiobus_data; -+#define __devinit /* */ -+#define __devexit /* */ -+#endif /* CONFIG_OF_MDIO */ -+ -+#ifndef CONFIG_OF_MDIO -+#define CCB_MDIO_BASE_ADDRESS IPROC_MII_MGMT_CTL -+#endif -+ -+#define R_REG(reg) ioread32(ccb_mdio->base + (reg&0x0fff)) -+#define W_REG(reg, val) iowrite32(val, ccb_mdio->base + (reg&0x0fff)) -+ -+#define MII_ERR_VAL 0x0001 -+#define MII_MSG_VAL 0x0002 -+#define MII_DBG_VAL 0x0004 -+//static u32 mii_msg_level = MII_ERR_VAL; -+ -+#if defined(BCMDBG) || defined(BCMDBG_ERR) -+#define MII_ERR(args) do {if (mii_msg_level & MII_ERR_VAL) printk args;} while (0) -+#else -+#define MII_ERR(args) -+#endif -+ -+#ifdef BCMDBG -+#define MII_MSG(args) do {if (mii_msg_level & MII_MSG_VAL) printk args;} while (0) -+#define MII_DBG(args) do {if (mii_msg_level & MII_DBG_VAL) printk args;} while (0) -+#else -+#define MII_MSG(args) -+#define MII_DBG(args) -+#endif -+ -+#define MII_EN_CHK \ -+ {\ -+ if (!ccb_mdio->base) { \ -+ return MII_ERR_INIT; \ -+ } \ -+ if (!(R_REG(MII_MGMT) & 0x7f)) { \ -+ return MII_ERR_INTERNAL; \ -+ } \ -+ } -+ -+#define MII_TRIES 100000 -+#define MII_POLL_USEC 20 -+ -+struct mdio_device_data { -+ mdio_info_t *mdio; -+ int init; -+}; -+ -+static struct mdio_device_data mdio_devices={0}; -+static uint32_t ccb_mdio_clk_rate; -+ -+#define DRIVER_VERSION "0.01" -+#define DRIVER_NAME "iproc mdio" -+ -+static int mdio_major; -+static struct cdev mdio_cdev; -+ -+#define MDIO_IOC_OP_EXTERNAL_READ 0 -+#define MDIO_IOC_OP_EXTERNAL_WRITE 1 -+#define MDIO_IOC_OP_LOCAL_READ 2 -+#define MDIO_IOC_OP_LOCAL_WRITE 3 -+ -+ -+struct ccb_mdio_ctrl { -+ void __iomem *base; -+ int ref_cnt; -+}; -+ -+struct ccb_mdiobus_private { -+ /* iproc_mdiobus_data field have to be placed at the beginning of -+ * mdiobus private data */ -+ struct iproc_mdiobus_data bus_data; -+ struct ccb_mdio_ctrl *hw_ctrl; -+}; -+ -+static struct ccb_mdio_ctrl *ccb_mdio = NULL; -+ -+#ifndef CONFIG_OF_MDIO -+static struct resource ccb_mdio_mem = { -+ .name = "ccb_mdio", -+ .start = CCB_MDIO_BASE_ADDRESS, -+ .end = CCB_MDIO_BASE_ADDRESS + 0x1000 - 1, -+ .flags = IORESOURCE_MEM, -+}; -+#endif -+ -+/* Function : ccb_mii_read -+ * - Read operation. -+ * Return : -+ * Note : -+ */ -+int -+ccb_mii_read(int dev_type, int phy_addr, int reg_off, uint16_t *data) -+{ -+ int i; -+ uint32_t ctrl = 0; -+ unsigned long flags; -+ mdio_info_t *mdio = NULL; -+ -+ MII_EN_CHK; -+ -+ mdio = mdio_devices.mdio; -+ -+ spin_lock_irqsave(&mdio->lock, flags); -+ -+ ctrl = R_REG(MII_MGMT); -+ if (dev_type == MII_DEV_LOCAL) { -+ ctrl &= ~MII_MGMT_EXP_MASK; -+ } else { -+ ctrl |= MII_MGMT_EXP_MASK; -+ } -+ W_REG(MII_MGMT, ctrl); -+ MII_DBG(("MII READ: write(0x%x)=0x%x\n",MII_MGMT, ctrl)); -+ -+ for (i = 0; i < MII_TRIES; i++) { -+ ctrl = R_REG(MII_MGMT); -+ if (!(ctrl & MII_MGMT_BSY_MASK)) { -+ break; -+ } -+ udelay(MII_POLL_USEC); -+ } -+ if (i >= MII_TRIES) { -+ MII_ERR(("\n%s: BUSY stuck: ctrl=0x%x, count=%d\n", __FUNCTION__, ctrl, i)); -+ spin_unlock_irqrestore(&mdio->lock, flags); -+ return -1; -+ } -+ -+ ctrl = (((1 << MII_CMD_DATA_SB_SHIFT) & MII_CMD_DATA_SB_MASK) | -+ ((2 << MII_CMD_DATA_OP_SHIFT) & MII_CMD_DATA_OP_MASK) | -+ ((phy_addr << MII_CMD_DATA_PA_SHIFT) & MII_CMD_DATA_PA_MASK) | -+ ((reg_off << MII_CMD_DATA_RA_SHIFT) & MII_CMD_DATA_RA_MASK) | -+ ((2 << MII_CMD_DATA_TA_SHIFT) & MII_CMD_DATA_TA_MASK)); -+ W_REG(MII_CMD_DATA, ctrl); -+ MII_DBG(("MII READ: write(0x%x)=0x%x\n",MII_CMD_DATA, ctrl)); -+ -+ for (i = 0; i < MII_TRIES; i++) { -+ ctrl = R_REG(MII_MGMT); -+ if (!(ctrl & MII_MGMT_BSY_MASK)) { -+ break; -+ } -+ udelay(MII_POLL_USEC); -+ } -+ if (i >= MII_TRIES) { -+ MII_ERR(("\n%s: BUSY stuck: ctrl=0x%x, count=%d\n", __FUNCTION__, ctrl, i)); -+ spin_unlock_irqrestore(&mdio->lock, flags); -+ return -1; -+ } -+ -+ ctrl = R_REG(MII_CMD_DATA); -+ -+ MII_DBG(("MDIO READ: addr=%x off=%x value=%x\n", phy_addr, reg_off, ctrl)); -+ -+ spin_unlock_irqrestore(&mdio->lock, flags); -+ -+ *data = (ctrl & 0xffff); -+ return 0; -+} -+ -+/* Function : ccb_mii_write -+ * - Write operation. -+ * Return : -+ * Note : -+ */ -+int -+ccb_mii_write(int dev_type, int phy_addr, int reg_off, uint16_t data) -+{ -+ int i; -+ uint32_t ctrl = 0; -+ unsigned long flags; -+ mdio_info_t *mdio = NULL; -+ -+ MII_DBG(("MDIO WRITE: addr=%x off=%x\n", phy_addr, reg_off)); -+ -+ MII_EN_CHK; -+ -+ mdio = mdio_devices.mdio; -+ -+ spin_lock_irqsave(&mdio->lock, flags); -+ -+ ctrl = R_REG(MII_MGMT); -+ if (dev_type == MII_DEV_LOCAL) { -+ ctrl &= ~MII_MGMT_EXP_MASK; -+ } else { -+ ctrl |= MII_MGMT_EXP_MASK; -+ } -+ W_REG(MII_MGMT, ctrl); -+ MII_DBG(("MII WRITE: write(0x%x)=0x%x\n",MII_MGMT, ctrl)); -+ -+ for (i = 0; i < MII_TRIES; i++) { -+ ctrl = R_REG(MII_MGMT); -+ if (!(ctrl & MII_MGMT_BSY_MASK)) { -+ break; -+ } -+ udelay(MII_POLL_USEC); -+ } -+ if (i >= MII_TRIES) { -+ MII_ERR(("\n%s: BUSY stuck: ctrl=0x%x, count=%d\n", __FUNCTION__, ctrl, i)); -+ spin_unlock_irqrestore(&mdio->lock, flags); -+ return -1; -+ } -+ -+ ctrl = (((1 << MII_CMD_DATA_SB_SHIFT) & MII_CMD_DATA_SB_MASK) | -+ ((1 << MII_CMD_DATA_OP_SHIFT) & MII_CMD_DATA_OP_MASK) | -+ ((phy_addr << MII_CMD_DATA_PA_SHIFT) & MII_CMD_DATA_PA_MASK) | -+ ((reg_off << MII_CMD_DATA_RA_SHIFT) & MII_CMD_DATA_RA_MASK) | -+ ((2 << MII_CMD_DATA_TA_SHIFT) & MII_CMD_DATA_TA_MASK) | -+ ((data << MII_CMD_DATA_DATA_SHIFT) & MII_CMD_DATA_DATA_MASK)); -+ W_REG(MII_CMD_DATA, ctrl); -+ MII_DBG(("MII WRITE: write(0x%x)=0x%x\n",MII_CMD_DATA, ctrl)); -+ -+ -+ for (i = 0; i < MII_TRIES; i++) { -+ ctrl = R_REG(MII_MGMT); -+ if (!(ctrl & MII_MGMT_BSY_MASK)) { -+ break; -+ } -+ udelay(MII_POLL_USEC); -+ } -+ if (i >= MII_TRIES) { -+ MII_ERR(("\n%s: BUSY stuck: ctrl=0x%x, count=%d\n", __FUNCTION__, ctrl, i)); -+ spin_unlock_irqrestore(&mdio->lock, flags); -+ return -1; -+ } -+ -+ spin_unlock_irqrestore(&mdio->lock, flags); -+ -+ return MII_ERR_NONE; -+} -+ -+/* Function : ccb_mii_freq_set -+ * - Set MII management interface frequency. -+ * Return : -+ * Note : -+ * -+ */ -+int -+ccb_mii_freq_set(int speed_khz) -+{ -+ int rv = MII_ERR_NONE; -+ uint32_t divider = 0; -+ uint32_t mgmt = 0; -+ -+ MII_DBG(("MDIO FREQ SET: %d KHz\n", speed_khz)); -+ -+ /* host clock 66MHz device value the MDCDIV field */ -+ /* resultant MDIO clock should not exceed 2.5MHz */ -+ -+ if (speed_khz > 2500) { -+ MII_ERR(("\n%s: Maximum MDIO frequency is 2.5MHz\n", __FUNCTION__)); -+ return MII_ERR_PARAM; -+ } -+ -+ divider = ccb_mdio_clk_rate / (1000*speed_khz); -+ divider = (divider & MII_MGMT_MDCDIV_MASK); -+ if (divider > 0x7f) { -+ /* make sure the minimum configurable frequency */ -+ divider = 0x7f; -+ } -+ mgmt = R_REG(MII_MGMT); -+ mgmt &= ~MII_MGMT_MDCDIV_MASK; -+ mgmt |= divider; -+ -+ W_REG(MII_MGMT, mgmt); -+ MII_DBG(("MII FREQ(%d KHz): write(0x%x)=0x%x\n",speed_khz, MII_MGMT, mgmt)); -+ -+ return rv; -+} -+ -+static int -+mdio_open(struct inode *inode, struct file *filp) -+{ -+ filp->private_data = mdio_devices.mdio; -+ return 0; -+} -+ -+static int -+mdio_release(struct inode *inode, struct file *filp) -+{ -+ return 0; -+} -+ -+static int mdio_message(mdio_info_t *mdio, -+ struct mdio_ioc_transfer *u_xfers, unsigned n_xfers, int op) -+{ -+ -+ uint8_t pa, ra; -+ uint16_t regval; -+ -+ pa = u_xfers->pa; -+ ra = u_xfers->ra; -+ -+ MII_DBG(("mdio_message: op = %d\n", op)); -+ -+ if (op == MDIO_IOC_OP_LOCAL_READ) { -+ iproc_mii_read(MII_DEV_LOCAL, pa, ra, ®val); -+ u_xfers->rx_buf = regval; -+ } -+ -+ if (op == MDIO_IOC_OP_LOCAL_WRITE) { -+ iproc_mii_write(MII_DEV_LOCAL, pa, ra, u_xfers->tx_buf); -+ } -+ -+ if (op == MDIO_IOC_OP_EXTERNAL_READ) { -+ iproc_mii_read(MII_DEV_EXT, pa, ra, ®val); -+ u_xfers->rx_buf = regval; -+ } -+ -+ if (op == MDIO_IOC_OP_EXTERNAL_WRITE) { -+ iproc_mii_write(MII_DEV_EXT, pa, ra, u_xfers->tx_buf); -+ } -+ return 0; -+} -+ -+static long -+mdio_ioctl(struct file *filp, -+ unsigned int cmd, unsigned long arg) -+{ -+ int err = 0; -+ int retval = 0; -+ int ioc_op = 0; -+ uint32_t tmp; -+ unsigned n_ioc; -+ struct mdio_ioc_transfer *ioc, *uf; -+ mdio_info_t *mdio; -+ -+ MII_DBG(("mdio_ioctl: cmd = %d\n", cmd)); -+ -+ /* Check type and command number */ -+ if (_IOC_TYPE(cmd) != MDIO_IOC_MAGIC){ -+ return -ENOTTY; -+ } -+ -+ /* Check access direction once here; don't repeat below. -+ * IOC_DIR is from the user perspective, while access_ok is -+ * from the kernel perspective; so they look reversed. -+ */ -+ if (_IOC_DIR(cmd) & _IOC_READ) { -+ err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); -+ } -+ if (err == 0 && _IOC_DIR(cmd) & _IOC_WRITE) { -+ err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); -+ } -+ if (err) { -+ return -EFAULT; -+ } -+ -+ mdio = (mdio_info_t *)filp->private_data; -+ -+ switch (cmd) { -+ case MDIO_IOC_EXTERNAL_R_REG: -+ ioc_op = MDIO_IOC_OP_EXTERNAL_READ; -+ break; -+ case MDIO_IOC_EXTERNAL_W_REG: -+ ioc_op = MDIO_IOC_OP_EXTERNAL_WRITE; -+ break; -+ case MDIO_IOC_LOCAL_R_REG: -+ ioc_op = MDIO_IOC_OP_LOCAL_READ; -+ break; -+ case MDIO_IOC_LOCAL_W_REG: -+ ioc_op = MDIO_IOC_OP_LOCAL_WRITE; -+ break; -+ } -+ -+ tmp = _IOC_SIZE(cmd); -+ if ((tmp % sizeof(struct mdio_ioc_transfer)) != 0) { -+ retval = -EINVAL; -+ return retval; -+ } -+ n_ioc = tmp / sizeof(struct mdio_ioc_transfer); -+ if (n_ioc == 0) { -+ return 0; -+ } -+ -+ /* copy into scratch area */ -+ ioc = kmalloc(tmp, GFP_KERNEL); -+ if (!ioc) { -+ retval = -ENOMEM; -+ return retval; -+ } -+ if (__copy_from_user(ioc, (void __user *)arg, tmp)) { -+ kfree(ioc); -+ retval = -EFAULT; -+ return retval; -+ } -+ /* translate to mdio_message, execute */ -+ retval = mdio_message(mdio, ioc, n_ioc, ioc_op); -+ -+ if ((ioc_op == MDIO_IOC_OP_EXTERNAL_READ) || (ioc_op == MDIO_IOC_OP_LOCAL_READ)) { -+ uf = (struct mdio_ioc_transfer *)arg; -+ if (__copy_to_user((u8 __user *)&uf->rx_buf, (uint8_t *)&ioc->rx_buf, 2)) { -+ kfree(ioc); -+ retval = -EFAULT; -+ return retval; -+ } -+ } -+ kfree(ioc); -+ -+ return 0; -+} -+ -+static const struct file_operations mdio_fops = { -+ .open = mdio_open, -+ .release = mdio_release, -+ .unlocked_ioctl = mdio_ioctl, -+ .owner = THIS_MODULE, -+}; -+ -+static int _mdio_handler_init(void) -+{ -+ mdio_info_t *mdio = NULL; -+ -+ mdio = kmalloc(sizeof(mdio_info_t), GFP_KERNEL); -+ if (mdio == NULL) { -+ MII_ERR(("mdio_init: out of memory\n")); -+ return -ENOMEM; -+ } -+ memset(mdio, 0, sizeof(mdio_info_t)); -+ -+ /* Initialize lock */ -+ spin_lock_init(&mdio->lock); -+ -+ mdio_devices.mdio = mdio; -+ mdio_devices.init = 1; -+ -+ return 0; -+} -+ -+ -+static int ccb_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum) -+{ -+ struct ccb_mdiobus_private *bus_priv = bus->priv; -+ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; -+ uint16_t data; -+ int dev_type = 0; -+ int err; -+ -+ if (IPROC_MDIOBUS_TYPE_INTERNAL == bus_data->phybus_type) { -+ dev_type = MII_DEV_LOCAL; -+ } else if (IPROC_MDIOBUS_TYPE_EXTERNAL == bus_data->phybus_type) { -+ dev_type = MII_DEV_EXT; -+ } else { -+ return -EINVAL; -+ } -+ err = ccb_mii_read(dev_type, phy_id, regnum, &data); -+ if (err < 0) { -+ return err; -+ } else { -+ return data; -+ } -+} -+ -+static int ccb_mdiobus_write(struct mii_bus *bus, int phy_id, -+ int regnum, u16 val) -+{ -+ struct ccb_mdiobus_private *bus_priv = bus->priv; -+ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; -+ int dev_type = 0; -+ -+ if (IPROC_MDIOBUS_TYPE_INTERNAL == bus_data->phybus_type) { -+ dev_type = MII_DEV_LOCAL; -+ } else if (IPROC_MDIOBUS_TYPE_EXTERNAL == bus_data->phybus_type) { -+ dev_type = MII_DEV_EXT; -+ } else { -+ return -EINVAL; -+ } -+ -+ return ccb_mii_write(dev_type, phy_id, regnum, val); -+} -+ -+static void __maybe_unused ccb_mdiobus_test(struct mii_bus *mii_bus) -+{ -+ int i, nRet1, nRet2; -+ u16 data1 = 0, data2 = 0; -+ struct phy_device *phy_dev; -+ struct ccb_mdiobus_private *bus_priv = mii_bus->priv; -+ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; -+ -+ dev_info(mii_bus->parent, "%s : %s phy bus num[%d], type[%d]\n", -+ __func__, mii_bus->id, bus_data->phybus_num, bus_data->phybus_type); -+ -+ /* Check if mdiobus_read works fine */ -+ for (i = 0; i < PHY_MAX_ADDR; i++) { -+ phy_dev = mii_bus->phy_map[i]; -+ if (phy_dev) { -+ dev_info(mii_bus->parent, "phy[%d] id=0x%08x, addr = %d\n", -+ i, phy_dev->phy_id, phy_dev->addr); -+ nRet1 = phy_read(phy_dev, 2); -+ nRet2 = phy_read(phy_dev, 3); -+ if ((nRet1 < 0) || (nRet2 < 0)) { -+ dev_info(mii_bus->parent, -+ "phy_read failed!, %s, nRet1 = %d, nRet2 = %d\n", -+ dev_name(&phy_dev->dev), nRet1, nRet2); -+ } else { -+ dev_info(mii_bus->parent, -+ "%s: reg2 = 0x%x, reg3 = 0x%x\n", -+ dev_name(&phy_dev->dev), nRet1, nRet2); -+ } -+ } -+ } -+ -+ /* Check if general interface function for mdiobus read works fine */ -+ for (i = 0; i < PHY_MAX_ADDR; i++) { -+ data1 = mii_bus->read(mii_bus, i, 2); -+ data2 = mii_bus->read(mii_bus, i, 3); -+ if ((data1 < 0) || (data2 < 0)) { -+ dev_info(mii_bus->parent, -+ "iproc_mdiobus_read failed!, %s phy bus num[%d], type[%d], phyaddr = %d, nRet1 = %d, nRet2 = %d\n", -+ mii_bus->id, bus_data->phybus_num, bus_data->phybus_type, i, data1, data2); -+ } else { -+ dev_info(mii_bus->parent, -+ "read %s phy bus num[%d] type[%d] phyaddr[%d], reg2 = 0x%x, reg3 = 0x%x\n", -+ mii_bus->id, bus_data->phybus_num, bus_data->phybus_type, i, data1, data2); -+ } -+ } -+} -+ -+static struct ccb_mdio_ctrl *ccb_mdio_res_alloc(void) -+{ -+ if (!ccb_mdio) { -+ ccb_mdio = kzalloc(sizeof(*ccb_mdio), GFP_KERNEL); -+ if (!ccb_mdio) { -+ return NULL; -+ } -+ ccb_mdio->ref_cnt = 1; -+ } else { -+ ccb_mdio->ref_cnt++; -+ } -+ -+ return ccb_mdio; -+} -+ -+static void ccb_mdio_res_free(struct ccb_mdio_ctrl *ctrl) -+{ -+ if (ctrl) { -+ ctrl->ref_cnt --; -+ if (ctrl->ref_cnt == 0) { -+ iounmap(ctrl->base); -+ kfree(ctrl); -+ ccb_mdio = NULL; -+ } -+ } -+} -+ -+void -+ccb_mii_init(struct ccb_mdio_ctrl *ccb_mii) -+{ -+ if (ccb_mii->ref_cnt == 1) { -+ /* Set preamble */ -+ W_REG(MII_MGMT, MII_MGMT_PRE_MASK); -+ -+ /* Set the MII default clock 1MHz */ -+ ccb_mii_freq_set(1000); /* KHZ */ -+ } -+} -+ -+#ifdef CONFIG_OF_MDIO -+static int __devinit ccb_mii_probe(struct platform_device *pdev) -+{ -+ int ret = -ENODEV; -+ struct device_node *dn = pdev->dev.of_node; -+ struct mii_bus *mii_bus; -+ struct ccb_mdiobus_private *bus_priv; -+ struct iproc_mdiobus_data *bus_data; -+ u32 mdio_bus_id; -+ const char *mdio_bus_type; -+ struct ccb_mdio_ctrl *ccb_ctrl; -+ struct clk *clk=NULL; -+ -+ if (!of_device_is_available(dn)) -+ return -ENODEV; -+ -+ ccb_ctrl = ccb_mdio_res_alloc(); -+ if (!ccb_ctrl) { -+ printk(KERN_ERR "ccb mdio res alloc failed\n"); -+ return -ENOMEM; -+ -+ } -+ -+ /* Get register base address */ -+ ccb_ctrl->base = (void *)of_iomap(dn, 0); -+ MII_DBG(("MDIO INIT: Base Addr %x\n", ccb_ctrl->base)); -+ -+ clk = of_clk_get (dn, 0); -+ if (clk) -+ ccb_mdio_clk_rate = clk_get_rate(clk)/2; /* used by ccb_mii_freq_set() */ -+ else { -+ printk("No CCB MDIO Clock available from DT, use default clock rate: 62.5MHz\n"); -+ ccb_mdio_clk_rate = 62500000; -+ } -+ -+ ccb_mii_init(ccb_ctrl); -+ -+ if (of_property_read_u32(dn, "#bus-id", &mdio_bus_id)) { -+ mdio_bus_id = 0; /* no property available, use default: 0 */ -+ } -+ if (of_property_read_string(dn, "bus-type", &mdio_bus_type)) { -+ mdio_bus_type = "internal"; /* no property available, use default: "internal" */ -+ } -+ iproc_mdiobus_data.phybus_num = (u8) mdio_bus_id; -+ if (!strcmp(mdio_bus_type, "internal")) -+ iproc_mdiobus_data.phybus_type = IPROC_MDIOBUS_TYPE_INTERNAL; -+ else -+ iproc_mdiobus_data.phybus_type = IPROC_MDIOBUS_TYPE_EXTERNAL; -+ /* Note: this applies to CCB/CCG MDIO, but not for CMICD MDIO */ -+ iproc_mdiobus_data.logbus_num = iproc_mdiobus_data.phybus_num; -+ iproc_mdiobus_data.logbus_type = iproc_mdiobus_data.phybus_type; -+ -+ bus_data = &iproc_mdiobus_data; -+ -+ mii_bus = mdiobus_alloc_size(sizeof(*bus_priv)); -+ if (!mii_bus) -+ return -ENOMEM; -+ -+ mii_bus->name = "iproc_ccb_mdiobus"; -+ snprintf(mii_bus->id, MII_BUS_ID_SIZE, IPROC_MDIO_ID_FMT, -+ bus_data->logbus_num, bus_data->logbus_type); -+ mii_bus->parent = &pdev->dev; -+ mii_bus->read = ccb_mdiobus_read; -+ mii_bus->write = ccb_mdiobus_write; -+ -+ bus_priv = mii_bus->priv; -+ memcpy(&bus_priv->bus_data, bus_data, sizeof(struct iproc_mdiobus_data)); -+ bus_priv->hw_ctrl = ccb_ctrl; -+ -+ ret = mdiobus_register(mii_bus); -+ if (ret) { -+ dev_err(&pdev->dev, "mdiobus_register failed\n"); -+ goto err_exit; -+ } -+ -+ platform_set_drvdata(pdev, mii_bus); -+ -+ /* ccb_mdiobus_test(mii_bus); */ -+ -+ return 0; -+ -+err_exit: -+ kfree(mii_bus); -+ return ret; -+} -+ -+int ccb_mii_remove(struct platform_device *pdev) -+{ -+ struct mii_bus *mii_bus = platform_get_drvdata(pdev); -+ struct ccb_mdiobus_private *bus_priv; -+ -+ if (mii_bus) { -+ bus_priv = mii_bus->priv; -+ -+ mdiobus_unregister(mii_bus); -+ if (bus_priv) { -+ ccb_mdio_res_free(bus_priv->hw_ctrl); -+ } -+ mdiobus_free(mii_bus); -+ } -+ -+ return 0; -+} -+ -+ -+static const struct of_device_id bcm_iproc_dt_ids[] = { -+ { .compatible = "brcm,iproc-ccb-mdio"}, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, bcm_iproc_dt_ids); -+ -+static struct platform_driver iproc_ccb_mdiobus_driver = { -+ .probe = ccb_mii_probe, -+ .remove = ccb_mii_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(bcm_iproc_dt_ids), -+ }, -+}; -+/*module_platform_driver(iproc_ccb_mdiobus_driver);*/ -+ -+#else /* CONFIG_OF_MDIO */ -+ -+static int __devinit ccb_mdiobus_probe(struct platform_device *pdev) -+{ -+ struct mii_bus *mii_bus; -+ struct ccb_mdiobus_private *bus_priv; -+ struct iproc_mdiobus_data *bus_data = pdev->dev.platform_data; -+ struct ccb_mdio_ctrl *ccb_ctrl; -+ int ret; -+ -+ /* Get register base address */ -+ ccb_ctrl = ccb_mdio_res_alloc(); -+ if (!ccb_ctrl) { -+ printk(KERN_ERR "ccb mdio res alloc failed\n"); -+ ret = -ENOMEM; -+ goto error_exit; -+ } -+ -+ ccb_mii_init(ccb_ctrl); -+ -+ mii_bus = mdiobus_alloc_size(sizeof(*bus_priv)); -+ if (!mii_bus) { -+ dev_err(&pdev->dev, "mdiobus alloc filed\n"); -+ ret = -ENOMEM; -+ goto error_free_ctrl; -+ } -+ -+ mii_bus->name = "iproc_ccb_mdiobus"; -+ snprintf(mii_bus->id, MII_BUS_ID_SIZE, IPROC_MDIO_ID_FMT, -+ bus_data->logbus_num, bus_data->logbus_type); -+ mii_bus->parent = &pdev->dev; -+ mii_bus->read = ccb_mdiobus_read; -+ mii_bus->write = ccb_mdiobus_write; -+ -+ bus_priv = mii_bus->priv; -+ memcpy(&bus_priv->bus_data, bus_data, sizeof(struct iproc_mdiobus_data)); -+ bus_priv->hw_ctrl = ccb_ctrl; -+ -+ ret = mdiobus_register(mii_bus); -+ if (ret) { -+ dev_err(&pdev->dev, "mdiobus_register failed\n"); -+ goto error_free_bus; -+ } -+ -+ platform_set_drvdata(pdev, mii_bus); -+ -+ return 0; -+ -+error_free_bus: -+ kfree(mii_bus); -+error_free_ctrl: -+ ccb_mdio_res_free(ccb_ctrl); -+error_exit: -+ return ret; -+} -+ -+static int __devexit ccb_mdiobus_remove(struct platform_device *pdev) -+{ -+ struct mii_bus *mii_bus = platform_get_drvdata(pdev); -+ struct ccb_mdiobus_private *bus_priv; -+ -+ if (mii_bus) { -+ bus_priv = mii_bus->priv; -+ -+ mdiobus_unregister(mii_bus); -+ if (bus_priv) { -+ ccb_mdio_res_free(bus_priv->hw_ctrl); -+ } -+ mdiobus_free(mii_bus); -+ } -+ -+ return 0; -+} -+ -+static struct platform_driver iproc_ccb_mdiobus_driver = -+{ -+ .driver = { -+ .name = "iproc_ccb_mdio", -+ .owner = THIS_MODULE, -+ }, -+ .probe = ccb_mdiobus_probe, -+ .remove = ccb_mdiobus_remove, -+}; -+#endif /* CONFIG_OF_MDIO */ -+ -+int -+ccb_mdio_init(void) -+{ -+ int ret = -ENODEV; -+ dev_t mdio_dev; -+ mdio_info_t *mdio = NULL; -+ -+ ret = _mdio_handler_init(); -+ if(ret != 0) { -+ ret = -ENOMEM; -+ goto error_exit; -+ } -+ -+ mdio = mdio_devices.mdio; -+ -+ if (mdio_major) { -+ mdio_dev = MKDEV(mdio_major, 0); -+ ret = register_chrdev_region(mdio_dev, 1, "mdio"); -+ } else { -+ ret = alloc_chrdev_region(&mdio_dev, 0, 1, "mdio"); -+ mdio_major = MAJOR(mdio_dev); -+ } -+ if (ret) { -+ goto error_exit; -+ } -+ -+ cdev_init(&mdio_cdev, &mdio_fops); -+ ret = cdev_add(&mdio_cdev, mdio_dev, 1); -+ if (ret) { -+ printk(KERN_ERR "Fail to add mdio char dev!\n"); -+ goto error_region; -+ } -+ -+ platform_driver_register(&iproc_ccb_mdiobus_driver); -+ -+ return 0; -+ -+error_region: -+ unregister_chrdev_region(mdio_dev, 1); -+error_exit: -+ kfree(mdio); -+ return ret; -+} -+ -+void -+ccb_mdio_exit(void) -+{ -+ mdio_info_t *mdio = NULL; -+ -+ mdio = mdio_devices.mdio; -+ kfree(mdio); -+ -+ mdio_devices.mdio = NULL; -+ mdio_devices.init = 0; -+ unregister_chrdev_region(MKDEV(mdio_major, 0), 1); -+ -+ platform_driver_unregister(&iproc_ccb_mdiobus_driver); -+} -+ -+ -+//module_init(ccb_mdio_init); -+subsys_initcall(ccb_mdio_init); -+module_exit(ccb_mdio_exit); -+ -+ -+EXPORT_SYMBOL(ccb_mii_init); -+EXPORT_SYMBOL(ccb_mii_freq_set); -+EXPORT_SYMBOL(ccb_mii_read); -+EXPORT_SYMBOL(ccb_mii_write); -+ -+MODULE_AUTHOR("Broadcom"); -+MODULE_DESCRIPTION("BCM5301X MDIO Device Driver"); -+MODULE_LICENSE("GPL"); -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/mdio/ccg_mdio.c b/drivers/net/ethernet/broadcom/mdio/ccg_mdio.c ---- a/drivers/net/ethernet/broadcom/mdio/ccg_mdio.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/mdio/ccg_mdio.c 2017-11-09 17:53:44.080295000 +0800 -@@ -0,0 +1,488 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ */ -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "iproc_mdio.h" -+ -+#include -+#include -+#include -+#include -+ -+static struct iproc_mdiobus_data iproc_mdiobus_data; -+/*#define CCG_MDIO_BASE_ADDRESS IPROC_MII_MGMT_CTL*/ -+ -+#define MGMT_CTL_REG 0x000 -+#define MGMT_CTL__BYP_SHIFT 10 -+#define MGMT_CTL__BYP_WIDTH 1 -+#define MGMT_CTL__BYP_MASK ((1 << MGMT_CTL__BYP_WIDTH) - 1) -+#define MGMT_CTL__EXT_SHIFT 9 -+#define MGMT_CTL__EXT_WIDTH 1 -+#define MGMT_CTL__EXT_MASK ((1 << MGMT_CTL__EXT_WIDTH) - 1) -+#define MGMT_CTL__BSY_SHIFT 8 -+#define MGMT_CTL__BSY_WIDTH 1 -+#define MGMT_CTL__BSY_MASK ((1 << MGMT_CTL__BSY_WIDTH) - 1) -+#define MGMT_CTL__PRE_SHIFT 7 -+#define MGMT_CTL__PRE_WIDTH 1 -+#define MGMT_CTL__PRE_MASK ((1 << MGMT_CTL__BSY_WIDTH) - 1) -+#define MGMT_CTL__MDCDIV_SHIFT 0 -+#define MGMT_CTL__MDCDIV_WIDTH 7 -+#define MGMT_CTL__MDCDIV_MASK ((1 << MGMT_CTL__MDCDIV_WIDTH) - 1) -+ -+#define MGMT_CMD_DATA_REG 0x004 -+#define MGMT_CMD_DATA__SB_SHIFT 30 -+#define MGMT_CMD_DATA__SB_WIDTH 2 -+#define MGMT_CMD_DATA__SB_MASK ((1 << MGMT_CMD_DATA__SB_WIDTH) - 1) -+#define MGMT_CMD_DATA__OP_SHIFT 28 -+#define MGMT_CMD_DATA__OP_WIDTH 2 -+#define MGMT_CMD_DATA__OP_MASK ((1 << MGMT_CMD_DATA__OP_WIDTH) - 1) -+#define MGMT_CMD_DATA__PA_SHIFT 23 -+#define MGMT_CMD_DATA__PA_WIDTH 5 -+#define MGMT_CMD_DATA__PA_MASK ((1 << MGMT_CMD_DATA__PA_WIDTH) - 1) -+#define MGMT_CMD_DATA__RA_SHIFT 18 -+#define MGMT_CMD_DATA__RA_WIDTH 5 -+#define MGMT_CMD_DATA__RA_MASK ((1 << MGMT_CMD_DATA__RA_WIDTH) - 1) -+#define MGMT_CMD_DATA__TA_SHIFT 16 -+#define MGMT_CMD_DATA__TA_WIDTH 2 -+#define MGMT_CMD_DATA__TA_MASK ((1 << MGMT_CMD_DATA__TA_WIDTH) - 1) -+#define MGMT_CMD_DATA__DATA_SHIFT 0 -+#define MGMT_CMD_DATA__DATA_WIDTH 16 -+#define MGMT_CMD_DATA__DATA_MASK ((1 << MGMT_CMD_DATA__DATA_WIDTH) - 1) -+ -+ -+#define SET_REG_FIELD(reg_value, fshift, fmask, fvalue) \ -+ (reg_value) = ((reg_value) & ~((fmask) << (fshift))) | \ -+ (((fvalue) & (fmask)) << (fshift)) -+#define ISET_REG_FIELD(reg_value, fshift, fmask, fvalue) \ -+ (reg_value) = (reg_value) | (((fvalue) & (fmask)) << (fshift)) -+#define GET_REG_FIELD(reg_value, fshift, fmask) \ -+ (((reg_value) & ((fmask) << (fshift))) >> (fshift)) -+ -+#define MII_OP_MAX_HALT_USEC 500 -+#define MII_OP_HALT_USEC 10 -+ -+enum { -+ MII_OP_MODE_READ, -+ MII_OP_MODE_WRITE, -+ MII_OP_MODE_MAX -+}; -+ -+/** -+ * struct cmicd_mdio: cmicd mdio structure -+ * @resource: resource of cmicd cmc2 -+ * @base: base address of cmicd cmc2 -+ * @lock: spin lock protecting io access -+ */ -+struct ccg_mdio_ctrl { -+ void __iomem *base; -+ /* Use spinlock to co-operate that the caller might be in interrupt context */ -+ /* struct mutex lock; */ -+ spinlock_t lock; -+ int ref_cnt; -+}; -+ -+struct ccg_mdiobus_private { -+ /* iproc_mdiobus_data field have to be placed at the beginning of -+ * mdiobus private data */ -+ struct iproc_mdiobus_data bus_data; -+ struct ccg_mdio_ctrl *hw_ctrl; -+}; -+ -+struct ccg_mii_cmd { -+ int bus_id; -+ int ext_sel; -+ int phy_id; -+ int regnum; -+ u16 op_mode; -+ u16 val; -+}; -+ -+static struct ccg_mdio_ctrl *ccg_mdio = NULL; -+static uint32_t ccg_mdio_clk_rate; -+ -+ -+static void __maybe_unused ccg_mdiobus_test(struct mii_bus *mii_bus) -+{ -+ int i; -+ u16 data1 = 0, data2 = 0; -+ struct phy_device *phy_dev; -+ struct ccg_mdiobus_private *bus_priv = mii_bus->priv; -+ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; -+ -+ dev_info(mii_bus->parent, "%s : %s phy bus num[%d], type[%d]\n", -+ __func__, mii_bus->id, bus_data->phybus_num, bus_data->phybus_type); -+ -+ /* Check if mdiobus_read works fine */ -+ for (i = 0; i < PHY_MAX_ADDR; i++) { -+ phy_dev = mii_bus->phy_map[i]; -+ if (phy_dev) -+ dev_info(mii_bus->parent, "phy[%d] id=0x%08x, addr = %d\n", -+ i, phy_dev->phy_id, phy_dev->addr); -+ } -+ -+ /* Check if general interface function for mdiobus read works fine */ -+ for (i = 0; i < PHY_MAX_ADDR; i++) { -+ data1 = mii_bus->read(mii_bus, i, 2); -+ data2 = mii_bus->read(mii_bus, i, 3); -+ if ((data1 < 0) || (data2 < 0)) { -+ dev_info(mii_bus->parent, -+ "iproc_mdiobus_read failed!, %s phy bus num[%d], type[%d], phyaddr = %d, nRet1 = %d, nRet2 = %d\n", -+ mii_bus->id, bus_data->phybus_num, bus_data->phybus_type, i, data1, data2); -+ } else { -+ dev_info(mii_bus->parent, -+ "read %s phy bus num[%d] type[%d] phyaddr[%d], reg2 = 0x%x, reg3 = 0x%x\n", -+ mii_bus->id, bus_data->phybus_num, bus_data->phybus_type, i, data1, data2); -+ } -+ } -+ -+} -+ -+static inline u32 ccg_mii_reg_read(struct ccg_mdio_ctrl *ccg_mii, u32 reg) -+{ -+ return readl(ccg_mii->base + reg); -+} -+ -+static inline void ccg_mii_reg_write(struct ccg_mdio_ctrl *ccg_mii, u32 reg, u32 data) -+{ -+ writel(data, ccg_mii->base + reg); -+} -+ -+static inline int ccg_mii_busy(struct ccg_mdio_ctrl *ccg_mii, int to_usec) -+{ -+ do { -+ if(!GET_REG_FIELD(ccg_mii_reg_read(ccg_mii, MGMT_CTL_REG), -+ MGMT_CTL__BSY_SHIFT, MGMT_CTL__BSY_MASK)) -+ return 0; -+ udelay(MII_OP_HALT_USEC); -+ to_usec -= MII_OP_HALT_USEC; -+ } while (to_usec > 0); -+ -+ return 1; -+} -+ -+static int do_ccg_mii_op(struct ccg_mdio_ctrl *ccg_mii, struct ccg_mii_cmd *cmd) -+{ -+ u32 cmd_data = 0, mgt_ctrl; -+ unsigned long flags; -+ int ret = 0; -+ -+ if (MII_OP_MODE_WRITE == cmd->op_mode) { -+ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__OP_SHIFT, -+ MGMT_CMD_DATA__OP_MASK, 1); -+ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__DATA_SHIFT, -+ MGMT_CMD_DATA__DATA_MASK, cmd->val); -+ } -+ else if (MII_OP_MODE_READ == cmd->op_mode) { -+ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__OP_SHIFT, -+ MGMT_CMD_DATA__OP_MASK, 2); -+ } -+ else { -+ printk(KERN_ERR "%s : invald operation %d\n", __func__, cmd->op_mode); -+ return -EINVAL; -+ } -+ -+ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__PA_SHIFT, -+ MGMT_CMD_DATA__PA_MASK, cmd->phy_id); -+ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__RA_SHIFT, -+ MGMT_CMD_DATA__RA_MASK, cmd->regnum); -+ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__TA_SHIFT, -+ MGMT_CMD_DATA__TA_MASK, 2); -+ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__SB_SHIFT, -+ MGMT_CMD_DATA__SB_MASK, 1); -+ -+ /* mutex_lock(&ccg_mii->lock); */ -+ spin_lock_irqsave(&ccg_mii->lock, flags); -+ -+ if (ccg_mii_busy(ccg_mii, MII_OP_MAX_HALT_USEC)) { -+ ret = -EBUSY; -+ printk(KERN_ERR "%s : bus busy (1)\n", __func__); -+ goto err_exit_unlock; -+ } -+ -+ mgt_ctrl = ccg_mii_reg_read(ccg_mii, MGMT_CTL_REG); -+ if (cmd->ext_sel != GET_REG_FIELD(mgt_ctrl, MGMT_CTL__EXT_SHIFT, -+ MGMT_CTL__EXT_MASK)) { -+ SET_REG_FIELD(mgt_ctrl, MGMT_CTL__EXT_SHIFT, MGMT_CTL__EXT_MASK, cmd->ext_sel); -+ ccg_mii_reg_write(ccg_mii, MGMT_CTL_REG, mgt_ctrl); -+ } -+ -+ ccg_mii_reg_write(ccg_mii, MGMT_CMD_DATA_REG, cmd_data); -+ -+ if (ccg_mii_busy(ccg_mii, MII_OP_MAX_HALT_USEC)) { -+ ret = -EBUSY; -+ printk(KERN_ERR "%s : bus busy (2)\n", __func__); -+ goto err_exit_unlock; -+ } -+ -+ if (MII_OP_MODE_READ == cmd->op_mode) { -+ ret = GET_REG_FIELD(ccg_mii_reg_read(ccg_mii, MGMT_CMD_DATA_REG), -+ MGMT_CMD_DATA__DATA_SHIFT, MGMT_CMD_DATA__DATA_MASK); -+ } -+ -+ /* mutex_unlock(&ccg_mii->lock); */ -+ spin_unlock_irqrestore(&ccg_mii->lock, flags); -+ -+ return ret; -+ -+err_exit_unlock: -+ /* mutex_unlock(&ccg_mii->lock); */ -+ spin_unlock_irqrestore(&ccg_mii->lock, flags); -+ return ret; -+} -+ -+static int ccg_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum) -+{ -+ struct ccg_mdiobus_private *bus_priv = bus->priv; -+ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; -+ struct ccg_mii_cmd cmd = {0}; -+ -+ cmd.bus_id = bus_data->phybus_num; -+ if (IPROC_MDIOBUS_TYPE_EXTERNAL == bus_data->phybus_type) -+ cmd.ext_sel = 1; -+ cmd.phy_id = phy_id; -+ cmd.regnum = regnum; -+ cmd.op_mode = MII_OP_MODE_READ; -+ -+ return do_ccg_mii_op(bus_priv->hw_ctrl, &cmd); -+} -+ -+static int ccg_mdiobus_write(struct mii_bus *bus, int phy_id, -+ int regnum, u16 val) -+{ -+ struct ccg_mdiobus_private *bus_priv = bus->priv; -+ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; -+ struct ccg_mii_cmd cmd = {0}; -+ -+ cmd.bus_id = bus_data->phybus_num; -+ if (IPROC_MDIOBUS_TYPE_EXTERNAL == bus_data->phybus_type) -+ cmd.ext_sel = 1; -+ cmd.phy_id = phy_id; -+ cmd.regnum = regnum; -+ cmd.op_mode = MII_OP_MODE_WRITE; -+ cmd.val = val; -+ -+ return do_ccg_mii_op(bus_priv->hw_ctrl, &cmd); -+} -+ -+static struct ccg_mdio_ctrl * ccg_mdio_res_alloc(void) -+{ -+ if (!ccg_mdio) { -+ ccg_mdio = kzalloc(sizeof(*ccg_mdio), GFP_KERNEL); -+ if (!ccg_mdio) -+ return NULL; -+ -+ /* mutex_init(&ccg_mdio->lock); */ -+ spin_lock_init(&ccg_mdio->lock); -+ ccg_mdio->ref_cnt = 1; -+ } -+ else -+ ccg_mdio->ref_cnt ++; -+ -+ return ccg_mdio; -+} -+ -+static void ccg_mdio_res_free(struct ccg_mdio_ctrl *ctrl) -+{ -+ if (ctrl) { -+ ctrl->ref_cnt --; -+ if (ctrl->ref_cnt == 0) { -+ iounmap(ctrl->base); -+ kfree(ctrl); -+ ccg_mdio = NULL; -+ } -+ } -+} -+ -+static void ccg_mii_init(struct ccg_mdio_ctrl *ccg_mii) -+{ -+ u32 clk_rate, val = 0; -+ -+ if(ccg_mii->ref_cnt == 1) { -+ /* Set preamble enabled */ -+ ISET_REG_FIELD(val, MGMT_CTL__PRE_SHIFT, MGMT_CTL__PRE_MASK, 1); -+ -+ clk_rate = ccg_mdio_clk_rate; -+ -+ /* -+ * MII Mgt Clock (MDC) Divisor. 0x0: Disable output of the MDC -+ * Non-zero: Output the MDC with a frequency that is -+ * PCLK/(2* the value of this field). -+ */ -+ ISET_REG_FIELD(val, MGMT_CTL__MDCDIV_SHIFT, MGMT_CTL__MDCDIV_MASK, -+ clk_rate/(1000000)); /* Set the MII default clock to 1MHz: */ -+ -+ ccg_mii_reg_write(ccg_mii, MGMT_CTL_REG, val); -+ } -+} -+ -+static int ccg_mdiobus_probe(struct platform_device *pdev) -+{ -+ struct mii_bus *mii_bus; -+ struct device_node *dn = pdev->dev.of_node; -+ struct ccg_mdiobus_private *bus_priv; -+ struct iproc_mdiobus_data *bus_data; -+ struct ccg_mdio_ctrl *ccg_ctrl; -+ u32 mdio_bus_id; -+ const char *mdio_bus_type; -+ struct clk *clk=NULL; -+ int ret; -+ -+ if (!of_device_is_available(dn)) -+ return -ENODEV; -+ -+ ccg_ctrl = ccg_mdio_res_alloc(); -+ if (!ccg_ctrl) { -+ dev_err(&pdev->dev, "ccg mdio res alloc failed\n"); -+ ret = -ENOMEM; -+ goto err_exit; -+ } -+ -+ /* Get register base address */ -+ ccg_ctrl->base = (void *)of_iomap(dn, 0); -+ -+ clk = of_clk_get (dn, 0); -+ if (clk) -+ ccg_mdio_clk_rate = clk_get_rate(clk)/2; /* used by ccg_mii_init */ -+ else { -+ printk("No CCG MDIO Clock available from DT, use default clock rate: 50MHz\n"); -+ ccg_mdio_clk_rate = 50000000; -+ } -+ -+ ccg_mii_init(ccg_ctrl); -+ -+ if (of_property_read_u32(dn, "#bus-id", &mdio_bus_id)) -+ mdio_bus_id = 0; /* default: 0 */ -+ -+ if (of_property_read_string(dn, "bus-type", &mdio_bus_type)) -+ mdio_bus_type = "internal"; /* default: "internal" */ -+ -+ iproc_mdiobus_data.phybus_num = (u8) mdio_bus_id; -+ if (!strcmp(mdio_bus_type, "internal")) -+ iproc_mdiobus_data.phybus_type = IPROC_MDIOBUS_TYPE_INTERNAL; -+ else -+ iproc_mdiobus_data.phybus_type = IPROC_MDIOBUS_TYPE_EXTERNAL; -+ -+ /* Note: this applies to CCB/CCG MDIO, but not for CMICD MDIO */ -+ iproc_mdiobus_data.logbus_num = iproc_mdiobus_data.phybus_num; -+ iproc_mdiobus_data.logbus_type = iproc_mdiobus_data.phybus_type; -+ -+ bus_data = &iproc_mdiobus_data; -+ -+ mii_bus = mdiobus_alloc_size(sizeof(*bus_priv)); -+ if (!mii_bus) { -+ dev_err(&pdev->dev, "mdiobus alloc filed\n"); -+ ret = -ENOMEM; -+ goto err_free_ctrl; -+ } -+ -+ mii_bus->name = "iproc_ccg_mdiobus"; -+ snprintf(mii_bus->id, MII_BUS_ID_SIZE, IPROC_MDIO_ID_FMT, -+ bus_data->logbus_num, bus_data->logbus_type); -+ mii_bus->parent = &pdev->dev; -+ mii_bus->read = ccg_mdiobus_read; -+ mii_bus->write = ccg_mdiobus_write; -+ -+ bus_priv = mii_bus->priv; -+ memcpy(&bus_priv->bus_data, bus_data, sizeof(struct iproc_mdiobus_data)); -+ bus_priv->hw_ctrl = ccg_ctrl; -+ -+ if (IS_ENABLED(CONFIG_MACH_GH2) || IS_ENABLED(CONFIG_MACH_WH2)) -+ ret = of_mdiobus_register(mii_bus, dn); -+ else -+ ret = mdiobus_register(mii_bus); -+ -+ if (ret) { -+ dev_err(&pdev->dev, "mdiobus_register failed\n"); -+ goto err_free_bus; -+ } -+ -+ platform_set_drvdata(pdev, mii_bus); -+ -+#if 0 -+ ccg_mdiobus_test(mii_bus); -+#endif -+ -+ return 0; -+ -+err_free_bus: -+ kfree(mii_bus); -+err_free_ctrl: -+ ccg_mdio_res_free(ccg_ctrl); -+err_exit: -+ return ret; -+} -+ -+static int ccg_mdiobus_remove(struct platform_device *pdev) -+{ -+ struct mii_bus *mii_bus = platform_get_drvdata(pdev); -+ struct ccg_mdiobus_private *bus_priv; -+ -+ if (mii_bus) { -+ bus_priv = mii_bus->priv; -+ -+ mdiobus_unregister(mii_bus); -+ if (bus_priv) -+ ccg_mdio_res_free(bus_priv->hw_ctrl); -+ mdiobus_free(mii_bus); -+ } -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm_iproc_dt_ids[] = { -+ { .compatible = "brcm,iproc-ccg-mdio"}, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, bcm_iproc_dt_ids); -+ -+ -+static struct platform_driver iproc_ccg_mdiobus_driver = -+{ -+ .driver = { -+ .name = "iproc_ccg_mdio", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(bcm_iproc_dt_ids), -+ }, -+ .probe = ccg_mdiobus_probe, -+ .remove = ccg_mdiobus_remove, -+}; -+ -+static int __init ccg_mdio_init(void) -+{ -+ return platform_driver_register(&iproc_ccg_mdiobus_driver); -+} -+ -+static void __exit ccg_mdio_exit(void) -+{ -+ platform_driver_unregister(&iproc_ccg_mdiobus_driver); -+} -+ -+//module_init(ccg_mdio_init); -+subsys_initcall(ccg_mdio_init); -+module_exit(ccg_mdio_exit); -+ -+MODULE_AUTHOR("Broadcom Corporation"); -+MODULE_DESCRIPTION("iProc CCG mdio driver"); -+MODULE_LICENSE("GPL"); -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/mdio/cmicd_mdio.c b/drivers/net/ethernet/broadcom/mdio/cmicd_mdio.c ---- a/drivers/net/ethernet/broadcom/mdio/cmicd_mdio.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/mdio/cmicd_mdio.c 2017-11-09 17:53:44.081297000 +0800 -@@ -0,0 +1,606 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "iproc_mdio.h" -+ -+#include -+#include -+#include -+#include -+ -+static struct iproc_mdiobus_data iproc_mdiobus_data; -+ -+/* CMICD MDIO */ -+#define CMIC_COMMON_MIIM_PARAM_OFFSET 0x080 -+#define CMIC_COMMON_MIIM_PARAM__MIIM_CYCLE_L 31 -+#define CMIC_COMMON_MIIM_PARAM__MIIM_CYCLE_R 29 -+#define CMIC_COMMON_MIIM_PARAM__MIIM_CYCLE_WIDTH 3 -+#define CMIC_COMMON_MIIM_PARAM__MIIM_CYCLE_RESETVALUE 0x0 -+#define CMIC_COMMON_MIIM_PARAM__INTERNAL_SEL 25 -+#define CMIC_COMMON_MIIM_PARAM__INTERNAL_SEL_WIDTH 1 -+#define CMIC_COMMON_MIIM_PARAM__INTERNAL_SEL_RESETVALUE 0x0 -+#define CMIC_COMMON_MIIM_PARAM__BUS_ID_L 24 -+#define CMIC_COMMON_MIIM_PARAM__BUS_ID_R 22 -+#define CMIC_COMMON_MIIM_PARAM__BUS_ID_WIDTH 3 -+#define CMIC_COMMON_MIIM_PARAM__BUS_ID_RESETVALUE 0x0 -+#define CMIC_COMMON_MIIM_PARAM__C45_SEL 21 -+#define CMIC_COMMON_MIIM_PARAM__C45_SEL_WIDTH 1 -+#define CMIC_COMMON_MIIM_PARAM__C45_SEL_RESETVALUE 0x0 -+#define CMIC_COMMON_MIIM_PARAM__PHY_ID_L 20 -+#define CMIC_COMMON_MIIM_PARAM__PHY_ID_R 16 -+#define CMIC_COMMON_MIIM_PARAM__PHY_ID_WIDTH 5 -+#define CMIC_COMMON_MIIM_PARAM__PHY_ID_RESETVALUE 0x0 -+#define CMIC_COMMON_MIIM_PARAM__PHY_DATA_L 15 -+#define CMIC_COMMON_MIIM_PARAM__PHY_DATA_R 0 -+#define CMIC_COMMON_MIIM_PARAM__PHY_DATA_WIDTH 16 -+#define CMIC_COMMON_MIIM_PARAM__PHY_DATA_RESETVALUE 0x0000 -+#define CMIC_COMMON_MIIM_PARAM__RESERVED_L 28 -+#define CMIC_COMMON_MIIM_PARAM__RESERVED_R 26 -+#define CMIC_COMMON_MIIM_PARAM_WIDTH 32 -+#define CMIC_COMMON_MIIM_PARAM__WIDTH 32 -+#define CMIC_COMMON_MIIM_PARAM_ALL_L 31 -+#define CMIC_COMMON_MIIM_PARAM_ALL_R 0 -+#define CMIC_COMMON_MIIM_PARAM__ALL_L 31 -+#define CMIC_COMMON_MIIM_PARAM__ALL_R 0 -+#define CMIC_COMMON_MIIM_PARAM_DATAMASK 0xe3ffffff -+#define CMIC_COMMON_MIIM_PARAM_RDWRMASK 0x1c000000 -+#define CMIC_COMMON_MIIM_PARAM_RESETVALUE 0x0 -+ -+#define CMIC_COMMON_MIIM_READ_DATA_OFFSET 0x084 -+#define CMIC_COMMON_MIIM_READ_DATA__DATA_L 15 -+#define CMIC_COMMON_MIIM_READ_DATA__DATA_R 0 -+#define CMIC_COMMON_MIIM_READ_DATA__DATA_WIDTH 16 -+#define CMIC_COMMON_MIIM_READ_DATA__DATA_RESETVALUE 0x0000 -+#define CMIC_COMMON_MIIM_READ_DATA__RESERVED_L 31 -+#define CMIC_COMMON_MIIM_READ_DATA__RESERVED_R 16 -+#define CMIC_COMMON_MIIM_READ_DATA_WIDTH 16 -+#define CMIC_COMMON_MIIM_READ_DATA__WIDTH 16 -+#define CMIC_COMMON_MIIM_READ_DATA_ALL_L 15 -+#define CMIC_COMMON_MIIM_READ_DATA_ALL_R 0 -+#define CMIC_COMMON_MIIM_READ_DATA__ALL_L 15 -+#define CMIC_COMMON_MIIM_READ_DATA__ALL_R 0 -+#define CMIC_COMMON_MIIM_READ_DATA_DATAMASK 0x0000ffff -+#define CMIC_COMMON_MIIM_READ_DATA_RDWRMASK 0xffff0000 -+#define CMIC_COMMON_MIIM_READ_DATA_RESETVALUE 0x0 -+ -+#define CMIC_COMMON_MIIM_ADDRESS_OFFSET 0x088 -+#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_DTYPE_L 20 -+#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_DTYPE_R 16 -+#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_DTYPE_WIDTH 5 -+#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_DTYPE_RESETVALUE 0x0 -+#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_REGADR_L 15 -+#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_REGADR_R 0 -+#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_REGADR_WIDTH 16 -+#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_REGADR_RESETVALUE 0x0000 -+#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_22_REGADR_L 4 -+#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_22_REGADR_R 0 -+#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_22_REGADR_WIDTH 5 -+#define CMIC_COMMON_MIIM_ADDRESS__CLAUSE_22_REGADR_RESETVALUE 0x0 -+#define CMIC_COMMON_MIIM_ADDRESS__RESERVED_L 31 -+#define CMIC_COMMON_MIIM_ADDRESS__RESERVED_R 21 -+#define CMIC_COMMON_MIIM_ADDRESS_WIDTH 21 -+#define CMIC_COMMON_MIIM_ADDRESS__WIDTH 21 -+#define CMIC_COMMON_MIIM_ADDRESS_ALL_L 20 -+#define CMIC_COMMON_MIIM_ADDRESS_ALL_R 0 -+#define CMIC_COMMON_MIIM_ADDRESS__ALL_L 20 -+#define CMIC_COMMON_MIIM_ADDRESS__ALL_R 0 -+#define CMIC_COMMON_MIIM_ADDRESS_DATAMASK 0x001fffff -+#define CMIC_COMMON_MIIM_ADDRESS_RDWRMASK 0xffe00000 -+#define CMIC_COMMON_MIIM_ADDRESS_RESETVALUE 0x0 -+ -+#define CMIC_COMMON_MIIM_CTRL_OFFSET 0x08c -+#define CMIC_COMMON_MIIM_CTRL__MIIM_RD_START 1 -+#define CMIC_COMMON_MIIM_CTRL__MIIM_RD_START_WIDTH 1 -+#define CMIC_COMMON_MIIM_CTRL__MIIM_RD_START_RESETVALUE 0x0 -+#define CMIC_COMMON_MIIM_CTRL__MIIM_WR_START 0 -+#define CMIC_COMMON_MIIM_CTRL__MIIM_WR_START_WIDTH 1 -+#define CMIC_COMMON_MIIM_CTRL__MIIM_WR_START_RESETVALUE 0x0 -+#define CMIC_COMMON_MIIM_CTRL__RESERVED_L 31 -+#define CMIC_COMMON_MIIM_CTRL__RESERVED_R 2 -+#define CMIC_COMMON_MIIM_CTRL_WIDTH 2 -+#define CMIC_COMMON_MIIM_CTRL__WIDTH 2 -+#define CMIC_COMMON_MIIM_CTRL_ALL_L 1 -+#define CMIC_COMMON_MIIM_CTRL_ALL_R 0 -+#define CMIC_COMMON_MIIM_CTRL__ALL_L 1 -+#define CMIC_COMMON_MIIM_CTRL__ALL_R 0 -+#define CMIC_COMMON_MIIM_CTRL_DATAMASK 0x00000003 -+#define CMIC_COMMON_MIIM_CTRL_RDWRMASK 0xfffffffc -+#define CMIC_COMMON_MIIM_CTRL_RESETVALUE 0x0 -+ -+#define CMIC_COMMON_MIIM_STAT_OFFSET 0x090 -+#define CMIC_COMMON_MIIM_STAT__MIIM_OPN_DONE 0 -+#define CMIC_COMMON_MIIM_STAT__MIIM_OPN_DONE_WIDTH 1 -+#define CMIC_COMMON_MIIM_STAT__MIIM_OPN_DONE_RESETVALUE 0x0 -+#define CMIC_COMMON_MIIM_STAT__RESERVED_L 31 -+#define CMIC_COMMON_MIIM_STAT__RESERVED_R 1 -+#define CMIC_COMMON_MIIM_STAT_WIDTH 1 -+#define CMIC_COMMON_MIIM_STAT__WIDTH 1 -+#define CMIC_COMMON_MIIM_STAT_ALL_L 0 -+#define CMIC_COMMON_MIIM_STAT_ALL_R 0 -+#define CMIC_COMMON_MIIM_STAT__ALL_L 0 -+#define CMIC_COMMON_MIIM_STAT__ALL_R 0 -+#define CMIC_COMMON_MIIM_STAT_DATAMASK 0x00000001 -+#define CMIC_COMMON_MIIM_STAT_RDWRMASK 0xfffffffe -+#define CMIC_COMMON_MIIM_STAT_RESETVALUE 0x0 -+ -+#define CMIC_COMMON_UC0_PIO_ENDIANESS 0x1F0 -+ -+#define MIIM_PARAM_REG CMIC_COMMON_MIIM_PARAM_OFFSET -+#define MIIM_PARAM__MIIM_CYCLE_SHIFT CMIC_COMMON_MIIM_PARAM__MIIM_CYCLE_R -+#define MIIM_PARAM__MIIM_CYCLE_MASK ((1 << CMIC_COMMON_MIIM_PARAM__MIIM_CYCLE_WIDTH) - 1) -+#define MIIM_PARAM__INTERNAL_SEL_SHIFT CMIC_COMMON_MIIM_PARAM__INTERNAL_SEL -+#define MIIM_PARAM__INTERNAL_SEL_MASK ((1 << CMIC_COMMON_MIIM_PARAM__INTERNAL_SEL_WIDTH) - 1) -+#define MIIM_PARAM__BUS_ID_SHIFT CMIC_COMMON_MIIM_PARAM__BUS_ID_R -+#define MIIM_PARAM__BUS_ID_MASK ((1 << CMIC_COMMON_MIIM_PARAM__BUS_ID_WIDTH) - 1) -+#define MIIM_PARAM__C45_SEL_SHIFT CMIC_COMMON_MIIM_PARAM__C45_SEL -+#define MIIM_PARAM__C45_SEL_MASK ((1 << CMIC_COMMON_MIIM_PARAM__C45_SEL_WIDTH) - 1) -+#define MIIM_PARAM__PHY_ID_SHIFT CMIC_COMMON_MIIM_PARAM__PHY_ID_R -+#define MIIM_PARAM__PHY_ID_MASK ((1 << CMIC_COMMON_MIIM_PARAM__PHY_ID_WIDTH) - 1) -+#define MIIM_PARAM__PHY_DATA_SHIFT CMIC_COMMON_MIIM_PARAM__PHY_DATA_R -+#define MIIM_PARAM__PHY_DATA_MASK ((1 << CMIC_COMMON_MIIM_PARAM__PHY_DATA_WIDTH) - 1) -+ -+#define MIIM_READ_DATA_REG CMIC_COMMON_MIIM_READ_DATA_OFFSET -+#define MIIM_READ_DATA__DATA_SHIFT CMIC_COMMON_MIIM_READ_DATA__DATA_R -+#define MIIM_READ_DATA__DATA_MASK ((1 << CMIC_COMMON_MIIM_READ_DATA__DATA_WIDTH) - 1) -+ -+#define MIIM_ADDRESS_REG CMIC_COMMON_MIIM_ADDRESS_OFFSET -+#define MIIM_ADDRESS__CLAUSE_45_DTYPE_SHIFT CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_DTYPE_R -+#define MIIM_ADDRESS__CLAUSE_45_DTYPE_MASK ((1 << CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_DTYPE_WIDTH) - 1) -+#define MIIM_ADDRESS__CLAUSE_45_REGADR_SHIFT CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_REGADR_R -+#define MIIM_ADDRESS__CLAUSE_45_REGADR_MASK ((1 << CMIC_COMMON_MIIM_ADDRESS__CLAUSE_45_REGADR_WIDTH) - 1) -+#define MIIM_ADDRESS__CLAUSE_22_REGADR_SHIFT CMIC_COMMON_MIIM_ADDRESS__CLAUSE_22_REGADR_R -+#define MIIM_ADDRESS__CLAUSE_22_REGADR_MASK ((1 << CMIC_COMMON_MIIM_ADDRESS__CLAUSE_22_REGADR_WIDTH) - 1) -+ -+#define MIIM_CTRL_REG CMIC_COMMON_MIIM_CTRL_OFFSET -+#define MIIM_CTRL__MIIM_RD_START_SHIFT CMIC_COMMON_MIIM_CTRL__MIIM_RD_START -+#define MIIM_CTRL__MIIM_RD_START_MASK ((1 << CMIC_COMMON_MIIM_CTRL__MIIM_RD_START_WIDTH) - 1) -+#define MIIM_CTRL__MIIM_WR_START_SHIFT CMIC_COMMON_MIIM_CTRL__MIIM_WR_START -+#define MIIM_CTRL__MIIM_WR_START_MASK ((1 << CMIC_COMMON_MIIM_CTRL__MIIM_WR_START_WIDTH) - 1) -+ -+#define MIIM_STAT_REG CMIC_COMMON_MIIM_STAT_OFFSET -+#define MIIM_STAT__MIIM_OPN_DONE_SHIFT CMIC_COMMON_MIIM_STAT__MIIM_OPN_DONE -+#define MIIM_STAT__MIIM_OPN_DONE_MASK ((1 << CMIC_COMMON_MIIM_STAT__MIIM_OPN_DONE_WIDTH) - 1) -+ -+#define SET_REG_FIELD(reg_value, fshift, fmask, fvalue) \ -+ (reg_value) = ((reg_value) & ~((fmask) << (fshift))) | \ -+ (((fvalue) & (fmask)) << (fshift)) -+#define ISET_REG_FIELD(reg_value, fshift, fmask, fvalue) \ -+ (reg_value) = (reg_value) | (((fvalue) & (fmask)) << (fshift)) -+#define GET_REG_FIELD(reg_value, fshift, fmask) \ -+ (((reg_value) & ((fmask) << (fshift))) >> (fshift)) -+ -+#define MIIM_OP_MAX_HALT_USEC 500 -+ -+enum { -+ MIIM_OP_MODE_READ, -+ MIIM_OP_MODE_WRITE, -+ MIIM_OP_MODE_MAX -+}; -+ -+/** -+ * struct cmicd_mdio: cmicd mdio structure -+ * @base: base address of cmic_common -+ * @lock: spin lock protecting io access -+ */ -+struct cmicd_mdio_ctrl { -+ void __iomem *base; -+ /* Use spinlock to co-operate that the caller might be in interrupt context */ -+ /* struct mutex lock; */ -+ spinlock_t lock; -+ int ref_cnt; -+}; -+ -+struct cmicd_mdiobus_private { -+ /* iproc_mdiobus_data field have to be placed at the beginning of -+ * mdiobus private data */ -+ struct iproc_mdiobus_data bus_data; -+ struct cmicd_mdio_ctrl *hw_ctrl; -+}; -+ -+struct cmicd_miim_cmd { -+ int bus_id; -+ int int_sel; -+ int phy_id; -+ int regnum; -+ int c45_sel; -+ u16 op_mode; -+ u16 val; -+}; -+ -+static struct cmicd_mdio_ctrl *cmic_common = NULL; -+ -+ -+static void __maybe_unused cmicd_mdiobus_test(struct mii_bus *mii_bus) -+{ -+ int i; -+ u16 data1 = 0, data2 = 0; -+ struct phy_device *phy_dev; -+ struct cmicd_mdiobus_private *bus_priv = mii_bus->priv; -+ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; -+ -+ dev_info(mii_bus->parent, "%s : %s phy bus num[%d], type[%d]\n", -+ __func__, mii_bus->id, bus_data->phybus_num, bus_data->phybus_type); -+ -+ /* Check if mdiobus_read works fine */ -+ for (i = 0; i < PHY_MAX_ADDR; i++) { -+ phy_dev = mii_bus->phy_map[i]; -+ if (phy_dev) -+ dev_info(mii_bus->parent, "phy[%d] id=0x%08x, addr = %d\n", -+ i, phy_dev->phy_id, phy_dev->addr); -+ } -+ -+ /* Check if general interface function for mdiobus read works fine */ -+ for (i = 0; i < PHY_MAX_ADDR; i++) { -+ data1 = mii_bus->read(mii_bus, i, 2); -+ data2 = mii_bus->read(mii_bus, i, 3); -+ if ((data1 < 0) || (data2 < 0)) { -+ dev_info(mii_bus->parent, -+ "iproc_mdiobus_read failed!, %s phy bus num[%d], type[%d], phyaddr = %d, nRet1 = %d, nRet2 = %d\n", -+ mii_bus->id, bus_data->phybus_num, bus_data->phybus_type, i, data1, data2); -+ } else { -+ dev_info(mii_bus->parent, -+ "read %s phy bus num[%d] type[%d] phyaddr[%d], reg2 = 0x%x, reg3 = 0x%x\n", -+ mii_bus->id, bus_data->phybus_num, bus_data->phybus_type, i, data1, data2); -+ } -+ } -+} -+ -+static inline u32 cmicd_miim_reg_read(struct cmicd_mdio_ctrl *cmic_mdio, u32 reg) -+{ -+ u32 value = readl(cmic_mdio->base + reg); -+#ifdef __BIG_ENDIAN -+ if (readl(cmic_mdio->base + CMIC_COMMON_UC0_PIO_ENDIANESS) != 0) -+ { -+ /* CMICD is in big-endian mode */ -+ value = swab32(value); -+ } -+#endif -+ return value; -+} -+ -+static inline void cmicd_miim_reg_write(struct cmicd_mdio_ctrl *cmic_mdio, u32 reg, u32 data) -+{ -+#ifdef __BIG_ENDIAN -+ if (readl(cmic_mdio->base + CMIC_COMMON_UC0_PIO_ENDIANESS) != 0) -+ { -+ /* CMICD is in big-endian mode */ -+ writel(swab32(data), cmic_mdio->base + reg); -+ return; -+ } -+#endif -+ writel(data, cmic_mdio->base + reg); -+} -+ -+static inline void cmicd_miim_set_op_read(u32 *data, u32 set) -+{ -+ SET_REG_FIELD(*data, MIIM_CTRL__MIIM_RD_START_SHIFT, -+ MIIM_CTRL__MIIM_RD_START_MASK, set); -+} -+ -+static inline void cmicd_miim_set_op_write(u32 *data, u32 set) -+{ -+ SET_REG_FIELD(*data, MIIM_CTRL__MIIM_WR_START_SHIFT, -+ MIIM_CTRL__MIIM_WR_START_MASK, set); -+} -+ -+static inline int do_cmicd_miim_op(struct cmicd_mdio_ctrl *cmic_mdio, u32 op, u32 param, u32 addr) -+{ -+ u32 val, op_done; -+ unsigned long flags; -+ int ret = 0; -+ int usec = MIIM_OP_MAX_HALT_USEC; -+ -+ if (op >= MIIM_OP_MODE_MAX) { -+ printk(KERN_ERR "%s : invalid op code %d\n", __func__, op); -+ return -EINVAL; -+ } -+ -+ /* mutex_lock(&cmic_mdio->lock); */ -+ spin_lock_irqsave(&cmic_mdio->lock, flags); -+ -+ cmicd_miim_reg_write(cmic_mdio, MIIM_PARAM_REG, param); -+ cmicd_miim_reg_write(cmic_mdio, MIIM_ADDRESS_REG, addr); -+ val = cmicd_miim_reg_read(cmic_mdio, MIIM_CTRL_REG); -+ if(op == MIIM_OP_MODE_READ) -+ cmicd_miim_set_op_read(&val, 1); -+ else -+ cmicd_miim_set_op_write(&val, 1); -+ cmicd_miim_reg_write(cmic_mdio, MIIM_CTRL_REG, val); -+ -+ do { -+ op_done = GET_REG_FIELD(cmicd_miim_reg_read(cmic_mdio, MIIM_STAT_REG), -+ MIIM_STAT__MIIM_OPN_DONE_SHIFT, MIIM_STAT__MIIM_OPN_DONE_MASK); -+ if (op_done) -+ break; -+ -+ udelay(1); -+ usec--; -+ } while (usec > 0); -+ -+ if (op_done) { -+ if(op == MIIM_OP_MODE_READ) -+ ret = cmicd_miim_reg_read(cmic_mdio, MIIM_READ_DATA_REG); -+ } -+ else -+ ret = -ETIME; -+ -+ val = cmicd_miim_reg_read(cmic_mdio, MIIM_CTRL_REG); -+ if(op == MIIM_OP_MODE_READ) -+ cmicd_miim_set_op_read(&val, 0); -+ else -+ cmicd_miim_set_op_write(&val, 0); -+ cmicd_miim_reg_write(cmic_mdio, MIIM_CTRL_REG, val); -+ -+ /* mutex_unlock(&cmic_mdio->lock); */ -+ spin_unlock_irqrestore(&cmic_mdio->lock, flags); -+ -+ return ret; -+} -+ -+ -+static int cmicd_miim_op(struct cmicd_mdio_ctrl *cmic_mdio, struct cmicd_miim_cmd *cmd) -+{ -+ u32 miim_param =0, miim_addr = 0; -+ -+ ISET_REG_FIELD(miim_param, MIIM_PARAM__BUS_ID_SHIFT, -+ MIIM_PARAM__BUS_ID_MASK, cmd->bus_id); -+ -+ if (cmd->int_sel) -+ ISET_REG_FIELD(miim_param, MIIM_PARAM__INTERNAL_SEL_SHIFT, -+ MIIM_PARAM__INTERNAL_SEL_MASK, 1); -+ -+ ISET_REG_FIELD(miim_param, MIIM_PARAM__PHY_ID_SHIFT, -+ MIIM_PARAM__PHY_ID_MASK, cmd->phy_id); -+ -+ if (cmd->op_mode == MIIM_OP_MODE_WRITE) -+ ISET_REG_FIELD(miim_param, MIIM_PARAM__PHY_DATA_SHIFT, -+ MIIM_PARAM__PHY_DATA_MASK, cmd->val); -+ -+ if (cmd->c45_sel) { -+ ISET_REG_FIELD(miim_param, MIIM_PARAM__C45_SEL_SHIFT, -+ MIIM_PARAM__C45_SEL_MASK, 1); -+ -+ ISET_REG_FIELD(miim_addr, MIIM_ADDRESS__CLAUSE_45_REGADR_SHIFT, -+ MIIM_ADDRESS__CLAUSE_45_REGADR_MASK, cmd->regnum); -+ ISET_REG_FIELD(miim_addr, MIIM_ADDRESS__CLAUSE_45_DTYPE_SHIFT, -+ MIIM_ADDRESS__CLAUSE_45_REGADR_MASK, cmd->regnum >> 16); -+ } -+ else { -+ ISET_REG_FIELD(miim_addr, MIIM_ADDRESS__CLAUSE_22_REGADR_SHIFT, -+ MIIM_ADDRESS__CLAUSE_22_REGADR_MASK, cmd->regnum); -+ } -+ -+ return do_cmicd_miim_op(cmic_mdio, cmd->op_mode, miim_param, miim_addr); -+} -+ -+ -+static int cmicd_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum) -+{ -+ struct cmicd_mdiobus_private *bus_priv = bus->priv; -+ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; -+ struct cmicd_miim_cmd cmd = {0}; -+ -+ cmd.bus_id = bus_data->phybus_num; -+ if (IPROC_MDIOBUS_TYPE_INTERNAL == bus_data->phybus_type) -+ cmd.int_sel = 1; -+ -+ cmd.phy_id = phy_id; -+ cmd.regnum = regnum; -+ -+ if (regnum & MII_ADDR_C45) -+ cmd.c45_sel = 1; -+ -+ cmd.op_mode = MIIM_OP_MODE_READ; -+ -+ return cmicd_miim_op(bus_priv->hw_ctrl, &cmd); -+} -+ -+static int cmicd_mdiobus_write(struct mii_bus *bus, int phy_id, -+ int regnum, u16 val) -+{ -+ struct cmicd_mdiobus_private *bus_priv = bus->priv; -+ struct iproc_mdiobus_data *bus_data = &bus_priv->bus_data; -+ struct cmicd_miim_cmd cmd = {0}; -+ -+ cmd.bus_id = bus_data->phybus_num; -+ if (IPROC_MDIOBUS_TYPE_INTERNAL == bus_data->phybus_type) -+ cmd.int_sel = 1; -+ -+ cmd.phy_id = phy_id; -+ cmd.regnum = regnum; -+ cmd.val = val; -+ -+ if (regnum & MII_ADDR_C45) -+ cmd.c45_sel = 1; -+ -+ cmd.op_mode = MIIM_OP_MODE_WRITE; -+ -+ return cmicd_miim_op(bus_priv->hw_ctrl, &cmd); -+} -+ -+static struct cmicd_mdio_ctrl * cmicd_mdio_res_alloc(void) -+{ -+ if (!cmic_common) { -+ cmic_common = kzalloc(sizeof(*cmic_common), GFP_KERNEL); -+ if (!cmic_common) -+ return NULL; -+ /* mutex_init(&cmic_common->lock); */ -+ spin_lock_init(&cmic_common->lock); -+ cmic_common->ref_cnt = 1; -+ } -+ else -+ cmic_common->ref_cnt ++; -+ -+ return cmic_common; -+} -+ -+static void cmicd_mdio_res_free(struct cmicd_mdio_ctrl *ctrl) -+{ -+ if (ctrl) { -+ ctrl->ref_cnt --; -+ if (ctrl->ref_cnt == 0) { -+ iounmap(ctrl->base); -+ kfree(ctrl); -+ cmic_common = NULL; -+ } -+ } -+} -+ -+static int cmicd_mdiobus_probe(struct platform_device *pdev) -+{ -+ struct mii_bus *mii_bus; -+ struct device_node *dn = pdev->dev.of_node; -+ struct cmicd_mdiobus_private *bus_priv; -+ struct iproc_mdiobus_data *bus_data; -+ struct cmicd_mdio_ctrl *cmicd_ctrl; -+ u32 mdio_bus_id; -+ u32 logical_mdio_bus_id; -+ const char *mdio_bus_type; -+ int ret; -+ -+ if (!of_device_is_available(dn)) -+ return -ENODEV; -+ -+ cmicd_ctrl = cmicd_mdio_res_alloc(); -+ if (!cmicd_ctrl) { -+ dev_err(&pdev->dev, "cmicd mdio rese alloc failed\n"); -+ ret = -ENOMEM; -+ goto err_exit; -+ } -+ -+ /* Get register base address */ -+ cmicd_ctrl->base = (void *)of_iomap(dn, 0); /*cmic_common: 0x03210000*/ -+ -+ if (of_property_read_u32(dn, "#bus-id", &mdio_bus_id)) { -+ mdio_bus_id = 2; /* no property available, use default: 2 */ -+ } -+ if (of_property_read_u32(dn, "#logical-bus-id", &logical_mdio_bus_id)) { -+ logical_mdio_bus_id = 0; /*use default:0 */ -+ } -+ if (of_property_read_string(dn, "bus-type", &mdio_bus_type)) { -+ mdio_bus_type = "external"; /* use default: "external" */ -+ } -+ -+ iproc_mdiobus_data.phybus_num = (u8) mdio_bus_id; -+ iproc_mdiobus_data.logbus_num = (u8) logical_mdio_bus_id; -+ if (!strcmp(mdio_bus_type, "internal")) -+ iproc_mdiobus_data.phybus_type = IPROC_MDIOBUS_TYPE_INTERNAL; -+ else -+ iproc_mdiobus_data.phybus_type = IPROC_MDIOBUS_TYPE_EXTERNAL; -+ iproc_mdiobus_data.logbus_type = iproc_mdiobus_data.phybus_type; -+ bus_data = &iproc_mdiobus_data; -+ -+ mii_bus = mdiobus_alloc_size(sizeof(*bus_priv)); -+ if (!mii_bus) { -+ dev_err(&pdev->dev, "mdiobus_alloc failed\n"); -+ ret = -ENOMEM; -+ goto err_ctrl_free; -+ } -+ -+ mii_bus->name = "iproc_cmicd_mdiobus"; -+ snprintf(mii_bus->id, MII_BUS_ID_SIZE, IPROC_MDIO_ID_FMT, -+ bus_data->logbus_num, bus_data->logbus_type); -+ mii_bus->parent = &pdev->dev; -+ mii_bus->read = cmicd_mdiobus_read; -+ mii_bus->write = cmicd_mdiobus_write; -+ -+ bus_priv = mii_bus->priv; -+ memcpy(&bus_priv->bus_data, bus_data, sizeof(struct iproc_mdiobus_data)); -+ bus_priv->hw_ctrl = cmicd_ctrl; -+ -+ if (IS_ENABLED(CONFIG_MACH_GH2) || IS_ENABLED(CONFIG_MACH_WH2)) -+ ret = of_mdiobus_register(mii_bus, dn); -+ else -+ ret = mdiobus_register(mii_bus); -+ if (ret) { -+ dev_err(&pdev->dev, "mdiobus_register failed\n"); -+ goto err_bus_free; -+ } -+ -+ platform_set_drvdata(pdev, mii_bus); -+ -+#if 0 -+ cmicd_mdiobus_test(mii_bus); -+#endif -+ -+ return 0; -+ -+err_bus_free: -+ kfree(mii_bus); -+err_ctrl_free: -+ cmicd_mdio_res_free(cmicd_ctrl); -+err_exit: -+ return ret; -+} -+ -+static int cmicd_mdiobus_remove(struct platform_device *pdev) -+{ -+ struct mii_bus *mii_bus = platform_get_drvdata(pdev); -+ struct cmicd_mdiobus_private *bus_priv; -+ -+ if (mii_bus) { -+ bus_priv = mii_bus->priv; -+ -+ mdiobus_unregister(mii_bus); -+ if (bus_priv) -+ cmicd_mdio_res_free(bus_priv->hw_ctrl); -+ mdiobus_free(mii_bus); -+ } -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm_iproc_dt_ids[] = { -+ { .compatible = "brcm,iproc-cmicd-mdio"}, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, bcm_iproc_dt_ids); -+ -+static struct platform_driver iproc_cmicd_mdiobus_driver = -+{ -+ .driver = { -+ .name = "iproc_cmicd_mdio", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(bcm_iproc_dt_ids), -+ }, -+ .probe = cmicd_mdiobus_probe, -+ .remove = cmicd_mdiobus_remove, -+}; -+ -+static int __init cmicd_mdio_init(void) -+{ -+ return platform_driver_register(&iproc_cmicd_mdiobus_driver); -+} -+ -+static void __exit cmicd_mdio_exit(void) -+{ -+ platform_driver_unregister(&iproc_cmicd_mdiobus_driver); -+} -+ -+//module_init(cmicd_mdio_init); -+subsys_initcall(cmicd_mdio_init); -+module_exit(cmicd_mdio_exit); -+ -+MODULE_AUTHOR("Broadcom Corporation"); -+MODULE_DESCRIPTION("iProc CMICd mdio driver"); -+MODULE_LICENSE("GPL"); -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/mdio/iproc_mdio.c b/drivers/net/ethernet/broadcom/mdio/iproc_mdio.c ---- a/drivers/net/ethernet/broadcom/mdio/iproc_mdio.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/mdio/iproc_mdio.c 2017-11-09 17:53:44.082291000 +0800 -@@ -0,0 +1,141 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "iproc_mdio.h" -+ -+/* Only one MDIO bus has been supported for each type */ -+static struct mii_bus *iproc_mdiobus[IPROC_MDIOBUS_TYPE_MAX] = {0}; -+ -+static struct mii_bus* -+get_iproc_mdiobus(int bustype, int phy_addr) -+{ -+ struct device *d; -+ char bus_id[MII_BUS_ID_SIZE]; -+ char phy_id[20]; -+ struct phy_device *phy_dev; -+ int idx; -+ -+ if (bustype < 0 || bustype >= IPROC_MDIOBUS_TYPE_MAX) { -+ return NULL; -+ } -+ -+ /* -+ * To support more than one bus for internal bus type on GH2, the following -+ * "if (NULL == iproc_mdiobus[bustype])" should be commented out. -+ * Note: The multi-bus support is based on the assumption that the phy_dev -+ * addresses are different for the internal bus_type bus. -+ */ -+#if !(defined(CONFIG_MACH_GH2) || (defined(CONFIG_MACH_HR3) && defined(CONFIG_MACH_WH2))) -+ if (NULL == iproc_mdiobus[bustype]) { -+#endif -+ for (idx = 0; idx < IPROC_MDIOBUS_NUM_MAX; idx++) { -+ snprintf(bus_id, MII_BUS_ID_SIZE, IPROC_MDIO_ID_FMT, idx, bustype); -+ snprintf(phy_id, 20, PHY_ID_FMT, bus_id, phy_addr); -+ d = bus_find_device_by_name(&mdio_bus_type, NULL, phy_id); -+ if (d) { -+ phy_dev = to_phy_device(d); -+ iproc_mdiobus[bustype] = phy_dev->bus; -+ idx = IPROC_MDIOBUS_NUM_MAX; -+ } -+ } -+#if !(defined(CONFIG_MACH_GH2) || (defined(CONFIG_MACH_HR3) && defined(CONFIG_MACH_WH2))) -+ } -+#endif -+ return iproc_mdiobus[bustype]; -+} -+ -+ -+/** -+ * iproc_mii_read - General iProc interface function for reading a given PHY register -+ if not registered PHY interface by phy_driver_register -+ * @busnum: currently we're using busnum value 0 -+ * @bustype: the mdio bus type, coud be IPROC_MDIOBUS_TYPE_INTERNAL or IPROC_MDIOBUS_TYPE_EXTERNAL -+ * @phy_addr: the phy address -+ * @regnum: register number to read, if MII_ADDR_C45 == (@regnum & MII_ADDR_C45), means a C45 request -+ * @val: the address to store read value if the read operation is successful -+ * -+ * Returns 0 on success, or a negative value on error. -+ */ -+int iproc_mii_read(int dev_type, int phy_addr, u32 reg_off, u16 *data) -+{ -+ struct mii_bus *mii_bus; -+ int bustype; -+ int err = -1; -+ -+ if (MII_DEV_LOCAL == dev_type) { -+ bustype = IPROC_MDIOBUS_TYPE_INTERNAL; -+ } else if (MII_DEV_EXT == dev_type) { -+ bustype = IPROC_MDIOBUS_TYPE_EXTERNAL; -+ } else { -+ return -EINVAL; -+ } -+ -+ mii_bus = get_iproc_mdiobus(bustype, phy_addr); -+ if (mii_bus) { -+ err = mii_bus->read(mii_bus, phy_addr, reg_off); -+ if (err >= 0) { -+ *data = err; -+ } -+ } else { -+ pr_err("%s : mdiobus:%d:%d is invalid!\n", __func__, 0, bustype); -+ } -+ -+ return err; -+} -+EXPORT_SYMBOL(iproc_mii_read); -+ -+/** -+ * iproc_mii_write - General iProc interface function for writing a given PHY register -+ if not registered PHY interface by phy_driver_register -+ * @busnum: currently we're using busnum value 0 -+ * @bustype: the mdio bus type, coud be IPROC_MDIOBUS_TYPE_INTERNAL or IPROC_MDIOBUS_TYPE_EXTERNAL -+ * @phy_addr: the phy address -+ * @regnum: register number to write, if MII_ADDR_C45 == (@regnum & MII_ADDR_C45), means a C45 request -+ * @val: value to write to @regnum -+ * -+ * Returns 0 on success, or a negative value on error. -+ */ -+int iproc_mii_write(int dev_type, int phy_addr, u32 reg_off, u16 data) -+{ -+ struct mii_bus *mii_bus; -+ int bustype; -+ int err = -1; -+ -+ if (MII_DEV_LOCAL == dev_type) { -+ bustype = IPROC_MDIOBUS_TYPE_INTERNAL; -+ } else if (MII_DEV_EXT == dev_type) { -+ bustype = IPROC_MDIOBUS_TYPE_EXTERNAL; -+ } else { -+ return -EINVAL; -+ } -+ -+ mii_bus = get_iproc_mdiobus(bustype, phy_addr); -+ if (mii_bus) { -+ err = mii_bus->write(mii_bus, phy_addr, reg_off, data); -+ } else { -+ pr_err("%s : mdiobus:%d:%d is invalid!\n", __func__, 0, bustype); -+ } -+ -+ return err; -+} -+EXPORT_SYMBOL(iproc_mii_write); -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/mdio/iproc_mdio.h b/drivers/net/ethernet/broadcom/mdio/iproc_mdio.h ---- a/drivers/net/ethernet/broadcom/mdio/iproc_mdio.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/mdio/iproc_mdio.h 2017-11-09 17:53:44.082312000 +0800 -@@ -0,0 +1,97 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ */ -+ -+ -+#ifndef _bcm5301x_ccb_mii_h_ -+#define _bcm5301x_ccb_mii_h_ -+ -+#include -+ -+typedef struct _mdio_info_s { -+ void *h; /* dev handle */ -+ spinlock_t lock; -+} mdio_info_t; -+ -+/* reutrn value for MII driver */ -+#define MII_ERR_NONE 0 -+#define MII_ERR_TIMEOUT -1 -+#define MII_ERR_INTERNAL -2 -+#define MII_ERR_PARAM -3 -+#define MII_ERR_UNAVAIL -4 -+#define MII_ERR_UNKNOW -5 -+#define MII_ERR_INIT -6 -+ -+/* device type */ -+#define MII_DEV_LOCAL 0 -+#define MII_DEV_EXT 1 -+ -+/* MII register definition */ -+#define MII_MGMT 0x18003000 -+#define MII_MGMT_BASE 0x000 -+#define MII_MGMT_DATAMASK 0x000007ff -+#define MII_CMD_DATA 0x18003004 -+#define MII_CMD_DATA_BASE 0x004 -+#define MII_CMD_DATA_DATAMASK 0xffffffff -+ -+/* fields in MII_MGMT */ -+#define MII_MGMT_BYP_MASK 0x00000400 -+#define MII_MGMT_BYP_SHIFT 10 -+#define MII_MGMT_EXP_MASK 0x00000200 -+#define MII_MGMT_EXP_SHIFT 9 -+#define MII_MGMT_BSY_MASK 0x00000100 -+#define MII_MGMT_BSY_SHIFT 8 -+#define MII_MGMT_PRE_MASK 0x00000080 -+#define MII_MGMT_PRE_SHIFT 7 -+#define MII_MGMT_MDCDIV_MASK 0x0000007f -+#define MII_MGMT_MDCDIV_SHIFT 0 -+/* fields in MII_CMD_DATA */ -+#define MII_CMD_DATA_SB_MASK 0xc0000000 -+#define MII_CMD_DATA_SB_SHIFT 30 -+#define MII_CMD_DATA_OP_MASK 0x30000000 -+#define MII_CMD_DATA_OP_SHIFT 28 -+#define MII_CMD_DATA_PA_MASK 0x0f800000 -+#define MII_CMD_DATA_PA_SHIFT 23 -+#define MII_CMD_DATA_RA_MASK 0x007c0000 -+#define MII_CMD_DATA_RA_SHIFT 18 -+#define MII_CMD_DATA_TA_MASK 0x00030000 -+#define MII_CMD_DATA_TA_SHIFT 16 -+#define MII_CMD_DATA_DATA_MASK 0x0000ffff -+#define MII_CMD_DATA_DATA_SHIFT 0 -+ -+ -+/****** iProc General Interface for mdio bus support ******/ -+struct iproc_mdiobus_data { -+ /* the mdio bus num and type from chip view */ -+ u8 logbus_num; -+ u8 logbus_type; -+ /* the actual bus num and type that mdio bus comes from */ -+ u8 phybus_num; -+ u8 phybus_type; -+ /* Note : -+ * Usually the logbus_num and logbus_type are the same as phybus_num and -+ * phybus_type, but they may be different on some special cases. For example, -+ * we may use cmicd mdio external bus 2 for the iProc mdio external bus 0, -+ * this configuration could be described as phybus_num=2, phybus_type=external, -+ * logbus_num=0, logbus_type=external. From iProc's view, the Phy devices -+ * for iProc AMAC should use mdiobus by logbus_num and logbus_type. But internally -+ * we'll configure the mdio core by phybus_num and phybus_type. -+ */ -+}; -+ -+#define IPROC_MDIOBUS_TYPE_INTERNAL 0 -+#define IPROC_MDIOBUS_TYPE_EXTERNAL 1 -+ -+#define IPROC_MDIOBUS_NUM_MAX 8 -+#define IPROC_MDIOBUS_TYPE_MAX 2 -+ -+/* iproc_mii:[bus_num]:[bus_type] */ -+#define IPROC_MDIO_ID_FMT "iproc_mii:%01x:%01x" -+ -+ -+/* General interface for iProc mdio bus read/write function */ -+extern int iproc_mii_read(int dev_type, int phy_addr, u32 reg_off, u16 *data); -+extern int iproc_mii_write(int dev_type, int phy_addr, u32 reg_off, u16 data); -+/****** iProc General Interface for mdio bus support ******/ -+ -+#endif /* _bcm5301x_ccb_mii_h_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/mdio/iproc_mdio_dev.h b/drivers/net/ethernet/broadcom/mdio/iproc_mdio_dev.h ---- a/drivers/net/ethernet/broadcom/mdio/iproc_mdio_dev.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/net/ethernet/broadcom/mdio/iproc_mdio_dev.h 2017-11-09 17:53:44.083307000 +0800 -@@ -0,0 +1,32 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ */ -+ -+ -+#ifndef _IPROC_MDIO_DEV_H -+#define _IPROC_MDIO_DEV_H -+ -+/* IOCTL commands */ -+ -+#define MDIO_IOC_MAGIC 'm' -+ -+struct mdio_ioc_transfer { -+ uint8_t pa; /* phy address */ -+ uint8_t ra; /* register address */ -+ uint16_t tx_buf; -+ uint16_t rx_buf; -+}; -+ -+#define MDIO_MSGSIZE(N) \ -+ ((((N)*(sizeof (struct mdio_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \ -+ ? ((N)*(sizeof (struct mdio_ioc_transfer))) : 0) -+ -+#define MDIO_IOC_MESSAGE(N) _IOW(MDIO_IOC_MAGIC, 0, char[MDIO_MSGSIZE(N)]) -+ -+#define MDIO_IOC_EXTERNAL_R_REG _IOWR(MDIO_IOC_MAGIC, 0, char[MDIO_MSGSIZE(1)]) -+#define MDIO_IOC_EXTERNAL_W_REG _IOW(MDIO_IOC_MAGIC, 1, char[MDIO_MSGSIZE(1)]) -+#define MDIO_IOC_LOCAL_R_REG _IOWR(MDIO_IOC_MAGIC, 2, char[MDIO_MSGSIZE(1)]) -+#define MDIO_IOC_LOCAL_W_REG _IOW(MDIO_IOC_MAGIC, 3, char[MDIO_MSGSIZE(1)]) -+ -+ -+#endif -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig ---- a/drivers/pci/host/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/pci/host/Kconfig 2017-11-09 17:53:50.841348000 +0800 -@@ -118,6 +118,15 @@ config PCI_VERSATILE - bool "ARM Versatile PB PCI controller" - depends on ARCH_VERSATILE - -+config PCIE_XGS_IPROC -+ tristate "Broadcom XGS iProc PCIe controller" -+ select PCI_DOMAINS -+ depends on ARCH_XGS_IPROC -+ default n -+ help -+ This enables the XGS iProc PCIe core controller support for Broadcom's -+ iProc family of SoCs. -+ - config PCIE_IPROC - tristate "Broadcom iProc PCIe controller" - depends on OF && (ARM || ARM64) -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile ---- a/drivers/pci/host/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/pci/host/Makefile 2017-11-09 17:53:50.842362000 +0800 -@@ -16,6 +16,7 @@ obj-$(CONFIG_PCI_LAYERSCAPE) += pci-laye - obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o - obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o - obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o -+obj-$(CONFIG_PCIE_XGS_IPROC) += pcie-xgs-iproc.o - obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o - obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o - obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/pci/host/pcie-xgs-iproc.c b/drivers/pci/host/pcie-xgs-iproc.c ---- a/drivers/pci/host/pcie-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/pci/host/pcie-xgs-iproc.c 2017-11-09 17:53:50.893339000 +0800 -@@ -0,0 +1,469 @@ -+/* -+ * Copyright (C) 2014 Hauke Mehrtens -+ * Copyright (C) 2015 Broadcom Corporation -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define CLK_CONTROL_OFFSET 0x000 -+ -+#define CFG_IND_ADDR_OFFSET 0x120 -+#define CFG_IND_ADDR_MASK 0x00001ffc -+#define CFG_IND_DATA_OFFSET 0x124 -+ -+#define CFG_ADDR_OFFSET 0x1f8 -+#define CFG_ADDR_BUS_NUM_SHIFT 20 -+#define CFG_ADDR_BUS_NUM_MASK 0x0ff00000 -+#define CFG_ADDR_DEV_NUM_SHIFT 15 -+#define CFG_ADDR_DEV_NUM_MASK 0x000f8000 -+#define CFG_ADDR_FUNC_NUM_SHIFT 12 -+#define CFG_ADDR_FUNC_NUM_MASK 0x00007000 -+#define CFG_ADDR_REG_NUM_SHIFT 2 -+#define CFG_ADDR_REG_NUM_MASK 0x00000ffc -+#define CFG_ADDR_CFG_TYPE_SHIFT 0 -+#define CFG_ADDR_CFG_TYPE_MASK 0x00000003 -+ -+#define CFG_DATA_OFFSET 0x1fc -+ -+#define SYS_RC_INTX_EN 0x330 -+#define SYS_RC_INTX_MASK 0xf -+ -+#define IPROC_PCIE_MAX_NUM_IRQS 6 -+ -+/** -+ * iProc PCIe device -+ * @dev: pointer to device data structure -+ * @base: PCIe host controller I/O register base -+ * @resources: linked list of all PCI resources -+ * @sysdata: Per PCI controller data (ARM-specific) -+ * @root_bus: pointer to root bus -+ * @phy: optional PHY device that controls the Serdes -+ * @irqs: interrupt IDs -+ */ -+struct iproc_pcie { -+ struct device *dev; -+ void __iomem *base; -+#ifdef CONFIG_ARM -+ struct pci_sys_data sysdata; -+#endif -+ struct pci_bus *root_bus; -+ struct phy *phy; -+ int irqs[IPROC_PCIE_MAX_NUM_IRQS]; -+ int (*map_irq)(const struct pci_dev *, u8, u8); -+}; -+ -+#if (defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3) \ -+ || defined(CONFIG_MACH_GH2)) -+#define PCI_PERST_SWR (1) -+#define PCI_CONFIG_SWR (1) -+#else -+#define PCI_PERST_SWR (0) -+#define PCI_CONFIG_SWR (0) -+#endif /* defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3) || defined(CONFIG_MACH_GH2)*/ -+ -+#if PCI_CONFIG_SWR -+extern char * nvram_get(const char *name); -+#endif /* PCI_CONFIG_SWR */ -+ -+#define MII_DEV_LOCAL 0 -+extern int iproc_mii_write(int dev_type, int phy_addr, u32 reg_off, u16 data); -+ -+static inline struct iproc_pcie *iproc_pcie_data(struct pci_bus *bus) -+{ -+ struct iproc_pcie *pcie; -+#ifdef CONFIG_ARM -+ struct pci_sys_data *sys = bus->sysdata; -+ -+ pcie = sys->private_data; -+#else -+ pcie = bus->sysdata; -+#endif -+ return pcie; -+} -+ -+/** -+ * Note access to the configuration registers are protected at the higher layer -+ * by 'pci_lock' in drivers/pci/access.c -+ */ -+static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus, -+ unsigned int devfn, -+ int where) -+{ -+ struct iproc_pcie *pcie = iproc_pcie_data(bus); -+ unsigned slot = PCI_SLOT(devfn); -+ unsigned fn = PCI_FUNC(devfn); -+ unsigned busno = bus->number; -+ u32 val; -+ -+ /* root complex access */ -+ if (busno == 0) { -+ if (slot >= 1) -+ return NULL; -+ writel(where & CFG_IND_ADDR_MASK, -+ pcie->base + CFG_IND_ADDR_OFFSET); -+ return (pcie->base + CFG_IND_DATA_OFFSET); -+ } -+ -+ if (fn > 1) -+ return NULL; -+ -+ /* EP device access */ -+ val = (busno << CFG_ADDR_BUS_NUM_SHIFT) | -+ (slot << CFG_ADDR_DEV_NUM_SHIFT) | -+ (fn << CFG_ADDR_FUNC_NUM_SHIFT) | -+ (where & CFG_ADDR_REG_NUM_MASK) | -+ (1 & CFG_ADDR_CFG_TYPE_MASK); -+ writel(val, pcie->base + CFG_ADDR_OFFSET); -+ -+ return (pcie->base + CFG_DATA_OFFSET); -+} -+ -+static struct pci_ops iproc_pcie_ops = { -+ .map_bus = iproc_pcie_map_cfg_bus, -+ .read = pci_generic_config_read32, -+ .write = pci_generic_config_write32, -+}; -+ -+static void iproc_pcie_reset(struct iproc_pcie *pcie) -+{ -+ /* Configure the PCIe controller as root complex and send a downstream reset */ -+ writel(0, pcie->base + CLK_CONTROL_OFFSET); -+ mdelay(1); -+ writel(1, pcie->base + CLK_CONTROL_OFFSET); -+ mdelay(100); -+} -+ -+#if (defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_HR3) || defined(CONFIG_MACH_GH2)) -+static int pcie_serdes_reg_write(int phyaddr, int reg, u16 val) -+{ -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, 0x1f, reg & 0xfff0); -+ iproc_mii_write(MII_DEV_LOCAL, phyaddr, reg & 0xf, val); -+ -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+static int pcie_rc_war(struct iproc_pcie * pcie) -+{ -+ /* Setting for PCIe Serdes PLL output */ -+ pcie_serdes_reg_write(2, 0x2103, 0x2b1c); -+ pcie_serdes_reg_write(2, 0x1300, 0x000b); -+ mdelay(100); -+ -+#if PCI_PERST_SWR -+ iproc_pcie_reset(pcie); -+#endif /* PCI_PERST_SWR */ -+ -+ return PCIBIOS_SUCCESSFUL; -+} -+#endif /* CONFIG_MACH_GH || CONFIG_MACH_SB2) || CONFIG_MACH_HR3 || defined(CONFIG_MACH_GH2) */ -+ -+static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus) -+{ -+ u8 hdr_type; -+ u32 link_ctrl; -+ u16 pos, link_status; -+ bool link_is_active = false; -+ u32 class; -+#if PCI_CONFIG_SWR -+ u32 tmp32, devfn = 0; -+ char *pcie_configs = NULL; -+#endif /* PCI_CONFIG_SWR */ -+ -+ -+ /* make sure we are not in EP mode */ -+ pci_bus_read_config_byte(bus, 0, PCI_HEADER_TYPE, &hdr_type); -+ if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) { -+ dev_err(pcie->dev, "in EP mode, hdr=%#02x\n", hdr_type); -+ return -EFAULT; -+ } -+ -+#if (defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_SB2) || defined(CONFIG_MACH_HR3) || defined(CONFIG_MACH_GH2)) -+ pcie_rc_war(pcie); -+#endif -+ -+#if PCI_CONFIG_SWR -+ pcie_configs = nvram_get("pcie_configs"); -+ if (pcie_configs) { -+ if (!strcmp(pcie_configs, "tx-de-emp")) { -+ pci_bus_read_config_dword(bus, devfn, 0xdc, &tmp32); -+ tmp32 |= (0x1 << 6); -+ pci_bus_write_config_dword(bus, devfn, 0xdc, tmp32); -+ pci_bus_read_config_dword(bus, devfn, 0xdc, &tmp32); -+ } -+ } -+#endif /* PCI_CONFIG_SWR */ -+ -+ /* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */ -+ /* -+ * After this modification, the CLASS code in configuration space would be -+ * read as PCI_CLASS_BRIDGE_PCI(0x0604) instead of network interface(0x0200) -+ */ -+#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c -+#define PCI_CLASS_BRIDGE_MASK 0xffff00 -+#define PCI_CLASS_BRIDGE_SHIFT 8 -+ pci_bus_read_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, &class); -+ class &= ~PCI_CLASS_BRIDGE_MASK; -+ class |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT); -+ pci_bus_write_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, class); -+ -+ /* check link status to see if link is active */ -+ pos = pci_bus_find_capability(bus, 0, PCI_CAP_ID_EXP); -+ pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA, &link_status); -+ if (link_status & PCI_EXP_LNKSTA_NLW) -+ link_is_active = true; -+ -+ if (!link_is_active) { -+ /* try GEN 1 link speed */ -+#define PCI_LINK_STATUS_CTRL_2_OFFSET 0x0dc -+#define PCI_TARGET_LINK_SPEED_MASK 0xf -+#define PCI_TARGET_LINK_SPEED_GEN2 0x2 -+#define PCI_TARGET_LINK_SPEED_GEN1 0x1 -+ pci_bus_read_config_dword(bus, 0, -+ PCI_LINK_STATUS_CTRL_2_OFFSET, -+ &link_ctrl); -+ if ((link_ctrl & PCI_TARGET_LINK_SPEED_MASK) == -+ PCI_TARGET_LINK_SPEED_GEN2) { -+ link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK; -+ link_ctrl |= PCI_TARGET_LINK_SPEED_GEN1; -+ pci_bus_write_config_dword(bus, 0, -+ PCI_LINK_STATUS_CTRL_2_OFFSET, -+ link_ctrl); -+ msleep(100); -+ -+ pos = pci_bus_find_capability(bus, 0, PCI_CAP_ID_EXP); -+ pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA, -+ &link_status); -+ if (link_status & PCI_EXP_LNKSTA_NLW) -+ link_is_active = true; -+ } -+ } -+ -+ dev_info(pcie->dev, "link: %s\n", link_is_active ? "UP" : "DOWN"); -+ -+ return link_is_active ? 0 : -ENODEV; -+} -+ -+static void iproc_pcie_enable(struct iproc_pcie *pcie) -+{ -+ writel(SYS_RC_INTX_MASK, pcie->base + SYS_RC_INTX_EN); -+} -+ -+int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) -+{ -+ int ret; -+ void *sysdata; -+ struct pci_bus *bus; -+ -+ if (!pcie || !pcie->dev || !pcie->base) -+ return -EINVAL; -+ -+ ret = phy_init(pcie->phy); -+ if (ret) { -+ dev_err(pcie->dev, "unable to initialize PCIe PHY\n"); -+ return ret; -+ } -+ -+ ret = phy_power_on(pcie->phy); -+ if (ret) { -+ dev_err(pcie->dev, "unable to power on PCIe PHY\n"); -+ goto err_exit_phy; -+ } -+ -+ iproc_pcie_reset(pcie); -+ -+#ifdef CONFIG_ARM -+ pcie->sysdata.private_data = pcie; -+ sysdata = &pcie->sysdata; -+#else -+ sysdata = pcie; -+#endif -+ -+ bus = pci_create_root_bus(pcie->dev, 0, &iproc_pcie_ops, sysdata, res); -+ if (!bus) { -+ dev_err(pcie->dev, "unable to create PCI root bus\n"); -+ ret = -ENOMEM; -+ goto err_power_off_phy; -+ } -+ pcie->root_bus = bus; -+ -+ ret = iproc_pcie_check_link(pcie, bus); -+ if (ret) { -+ dev_err(pcie->dev, "no PCIe EP device detected\n"); -+ goto err_rm_root_bus; -+ } -+ -+ iproc_pcie_enable(pcie); -+ -+ pci_scan_child_bus(bus); -+ pci_assign_unassigned_bus_resources(bus); -+#ifdef CONFIG_ARM -+ pci_fixup_irqs(pci_common_swizzle, pcie->map_irq); -+#endif -+ pci_bus_add_devices(bus); -+ -+ return 0; -+ -+err_rm_root_bus: -+ pci_stop_root_bus(bus); -+ pci_remove_root_bus(bus); -+ -+err_power_off_phy: -+ phy_power_off(pcie->phy); -+err_exit_phy: -+ phy_exit(pcie->phy); -+ return ret; -+} -+EXPORT_SYMBOL(iproc_pcie_setup); -+ -+ -+#if ( defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_HR2) ) -+static void WrongPCIGen2TemplateWAR(int port, u32 reg, u16 val) -+{ -+ /* port = phy addr */ -+ iproc_mii_write(MII_DEV_LOCAL, port, 0x1f, 0x8630); -+ iproc_mii_write(MII_DEV_LOCAL, port, reg, val); -+} -+#endif /* defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_SKT2) || defined(CONFIG_MACH_HR2) */ -+ -+ -+int iproc_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin) -+{ -+ struct iproc_pcie *pcie = iproc_pcie_data(pdev->bus); -+ int irq = pcie->irqs[4]; -+ -+ return irq; -+} -+ -+static int iproc_pcie_probe(struct platform_device *pdev) -+{ -+ struct iproc_pcie *pcie; -+ struct device_node *np = pdev->dev.of_node; -+ struct resource reg; -+ resource_size_t iobase = 0; -+ LIST_HEAD(res); -+ int ret; -+ //u32 irqs_total; -+ int i; -+ -+ pcie = devm_kzalloc(&pdev->dev, sizeof(struct iproc_pcie), GFP_KERNEL); -+ if (!pcie) -+ return -ENOMEM; -+ -+ pcie->dev = &pdev->dev; -+ platform_set_drvdata(pdev, pcie); -+ -+ ret = of_address_to_resource(np, 0, ®); -+ if (ret < 0) { -+ dev_err(pcie->dev, "unable to obtain controller resources\n"); -+ return ret; -+ } -+ -+ pcie->base = devm_ioremap_resource(pcie->dev, ®); -+ if (IS_ERR(pcie->base)) -+ return PTR_ERR(pcie->base); -+ -+ /* PHY use is optional */ -+ pcie->phy = devm_phy_get(&pdev->dev, "pcie-phy"); -+ if (IS_ERR(pcie->phy)) { -+ if (PTR_ERR(pcie->phy) == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ pcie->phy = NULL; -+ } -+ -+ ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &iobase); -+ if (ret) { -+ dev_err(pcie->dev, -+ "unable to get PCI host bridge resources\n"); -+ return ret; -+ } -+ -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || defined(CONFIG_MACH_HR2)) -+// if (of_device_is_compatible(np, "iproc-p2") || of_device_is_compatible(np, "iproc-p6")) { -+ WrongPCIGen2TemplateWAR(of_get_pci_domain_nr(np) + 7, 0x13, 0x190); -+ WrongPCIGen2TemplateWAR(of_get_pci_domain_nr(np) + 7, 0x19, 0x191); -+// } -+#endif -+ -+ /*Parse IRQ*/ -+ /* of_irq_count is not exported for module to call */ -+#if 0 -+ irqs_total = of_irq_count(np); -+ if ( !irqs_total || (irqs_total > IPROC_PCIE_MAX_NUM_IRQS) ) -+ return -EINVAL; -+#endif -+ -+ for (i = 0; i < IPROC_PCIE_MAX_NUM_IRQS; i++) { -+ pcie->irqs[i] = irq_of_parse_and_map(np, i); -+ if (!pcie->irqs[i]) { -+ dev_err(&pdev->dev, "unable to parse or map irq index:%d\n", i); -+ return -EINVAL; -+ } -+ } -+ -+ //pcie->map_irq = of_irq_parse_and_map_pci; -+ pcie->map_irq = iproc_pcie_map_irq; -+ -+ ret = iproc_pcie_setup(pcie, &res); -+ if (ret) -+ dev_err(pcie->dev, "PCIe controller setup failed\n"); -+ -+ pci_free_resource_list(&res); -+ -+ return ret; -+} -+ -+static int iproc_pcie_remove(struct platform_device *pdev) -+{ -+ struct iproc_pcie *pcie = platform_get_drvdata(pdev); -+ -+ pci_stop_root_bus(pcie->root_bus); -+ pci_remove_root_bus(pcie->root_bus); -+ -+ phy_power_off(pcie->phy); -+ phy_exit(pcie->phy); -+ -+ return 0; -+} -+ -+static const struct of_device_id iproc_pcie_of_match_table[] = { -+ { .compatible = "brcm,iproc-pcie", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, iproc_pcie_of_match_table); -+ -+static struct platform_driver iproc_pcie_pltfm_driver = { -+ .driver = { -+ .name = "iproc-pcie", -+ .of_match_table = of_match_ptr(iproc_pcie_of_match_table), -+ }, -+ .probe = iproc_pcie_probe, -+ .remove = iproc_pcie_remove, -+}; -+ -+module_platform_driver(iproc_pcie_pltfm_driver); -+ -+MODULE_DESCRIPTION("Broadcom XGS iProc PCIe driver"); -+MODULE_LICENSE("GPL v2"); -\ No newline at end of file -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/soc/Kconfig b/drivers/soc/Kconfig ---- a/drivers/soc/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/soc/Kconfig 2017-11-09 17:53:55.652386000 +0800 -@@ -1,6 +1,7 @@ - menu "SOC (System On Chip) specific Drivers" - - source "drivers/soc/brcmstb/Kconfig" -+source "drivers/soc/bcm/Kconfig" - source "drivers/soc/mediatek/Kconfig" - source "drivers/soc/qcom/Kconfig" - source "drivers/soc/rockchip/Kconfig" -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/soc/Makefile b/drivers/soc/Makefile ---- a/drivers/soc/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/soc/Makefile 2017-11-09 17:53:55.653381000 +0800 -@@ -2,6 +2,7 @@ - # Makefile for the Linux Kernel SOC specific device drivers. - # - -+obj-$(CONFIG_SOC_XGS_IPROC) += bcm/ - obj-$(CONFIG_SOC_BRCMSTB) += brcmstb/ - obj-$(CONFIG_MACH_DOVE) += dove/ - obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/Kconfig b/drivers/soc/bcm/Kconfig ---- a/drivers/soc/bcm/Kconfig 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/soc/bcm/Kconfig 2017-11-09 17:53:55.664395000 +0800 -@@ -0,0 +1,8 @@ -+menuconfig SOC_XGS_IPROC -+ bool "Broadcom XGS iProc IDM/DMU/PMU drivers" -+ depends on ARCH_XGS_IPROC -+ default ARCH_XGS_IPROC -+ help -+ This option enables XGS iProc IDM/DMU/PMU related drivers. -+ -+ If unsure, say Y. -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/Makefile b/drivers/soc/bcm/Makefile ---- a/drivers/soc/bcm/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/soc/bcm/Makefile 2017-11-09 17:53:55.665375000 +0800 -@@ -0,0 +1 @@ -+obj-$(CONFIG_SOC_XGS_IPROC) += xgs-iproc-wrap-idm-dmu.o xgs-iproc-idm.o -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/xgs-iproc-idm.c b/drivers/soc/bcm/xgs-iproc-idm.c ---- a/drivers/soc/bcm/xgs-iproc-idm.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/soc/bcm/xgs-iproc-idm.c 2017-11-09 17:53:55.666387000 +0800 -@@ -0,0 +1,842 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+extern void __iomem *get_iproc_idm_base(int); -+extern void __iomem *get_iproc_idm_base_phys(int); -+ -+#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ -+ defined(CONFIG_MACH_HR2) -+#define IHOST_S1_IDM_ERROR_LOG_CONTROL 0x18107900 -+#define IHOST_S1_IDM_ERROR_LOG_COMPLETE 0x18107904 -+#define IHOST_S1_IDM_ERROR_LOG_STATUS 0x18107908 -+#define IHOST_S1_IDM_ERROR_LOG_ADDR_LSB 0x1810790c -+#define IHOST_S1_IDM_ERROR_LOG_ID 0x18107914 -+#define IHOST_S1_IDM_ERROR_LOG_FLAGS 0x1810791c -+#define IHOST_S1_IDM_INTERRUPT_STATUS 0x18107a00 -+#define IHOST_S0_IDM_ERROR_LOG_CONTROL 0x18108900 -+#define IHOST_S0_IDM_ERROR_LOG_COMPLETE 0x18108904 -+#define IHOST_S0_IDM_ERROR_LOG_STATUS 0x18108908 -+#define IHOST_S0_IDM_ERROR_LOG_ADDR_LSB 0x1810890c -+#define IHOST_S0_IDM_ERROR_LOG_ID 0x18108914 -+#define IHOST_S0_IDM_ERROR_LOG_FLAGS 0x1810891c -+#define IHOST_S0_IDM_INTERRUPT_STATUS 0x18108a00 -+#define DDR_S1_IDM_ERROR_LOG_CONTROL 0x18109900 -+#define DDR_S1_IDM_ERROR_LOG_COMPLETE 0x18109904 -+#define DDR_S1_IDM_ERROR_LOG_STATUS 0x18109908 -+#define DDR_S1_IDM_ERROR_LOG_ADDR_LSB 0x1810990c -+#define DDR_S1_IDM_ERROR_LOG_ID 0x18109914 -+#define DDR_S1_IDM_ERROR_LOG_FLAGS 0x1810991c -+#define DDR_S1_IDM_INTERRUPT_STATUS 0x18109a00 -+#define DDR_S2_IDM_ERROR_LOG_CONTROL 0x1810a900 -+#define DDR_S2_IDM_ERROR_LOG_COMPLETE 0x1810a904 -+#define DDR_S2_IDM_ERROR_LOG_STATUS 0x1810a908 -+#define DDR_S2_IDM_ERROR_LOG_ADDR_LSB 0x1810a90c -+#define DDR_S2_IDM_ERROR_LOG_ID 0x1810a914 -+#define DDR_S2_IDM_ERROR_LOG_FLAGS 0x1810a91c -+#define DDR_S2_IDM_INTERRUPT_STATUS 0x1810aa00 -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_CONTROL 0x1810b900 -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x1810b904 -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_STATUS 0x1810b908 -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1810b90c -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ID 0x1810b914 -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1810b91c -+#define AXI_PCIE_S0_IDM_IDM_INTERRUPT_STATUS 0x1810ba00 -+#define CMICD_S0_IDM_IDM_ERROR_LOG_CONTROL 0x1810d900 -+#define CMICD_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x1810d904 -+#define CMICD_S0_IDM_IDM_ERROR_LOG_STATUS 0x1810d908 -+#define CMICD_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1810d90c -+#define CMICD_S0_IDM_IDM_ERROR_LOG_ID 0x1810d914 -+#define CMICD_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1810d91c -+#define CMICD_S0_IDM_IDM_INTERRUPT_STATUS 0x1810da00 -+#define APBY_S0_IDM_IDM_ERROR_LOG_CONTROL 0x1810f900 -+#define APBY_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x1810f904 -+#define APBY_S0_IDM_IDM_ERROR_LOG_STATUS 0x1810f908 -+#define APBY_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1810f90c -+#define APBY_S0_IDM_IDM_ERROR_LOG_ID 0x1810f914 -+#define APBY_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1810f91c -+#define APBY_S0_IDM_IDM_INTERRUPT_STATUS 0x1810fa00 -+#define ROM_S0_IDM_ERROR_LOG_CONTROL 0x1811a900 -+#define ROM_S0_IDM_ERROR_LOG_COMPLETE 0x1811a904 -+#define ROM_S0_IDM_ERROR_LOG_STATUS 0x1811a908 -+#define ROM_S0_IDM_ERROR_LOG_ADDR_LSB 0x1811a90c -+#define ROM_S0_IDM_ERROR_LOG_ID 0x1811a914 -+#define ROM_S0_IDM_ERROR_LOG_FLAGS 0x1811a91c -+#define ROM_S0_IDM_INTERRUPT_STATUS 0x1811aa00 -+#define NAND_IDM_IDM_ERROR_LOG_CONTROL 0x1811b900 -+#define NAND_IDM_IDM_ERROR_LOG_COMPLETE 0x1811b904 -+#define NAND_IDM_IDM_ERROR_LOG_STATUS 0x1811b908 -+#define NAND_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1811b90c -+#define NAND_IDM_IDM_ERROR_LOG_ID 0x1811b914 -+#define NAND_IDM_IDM_ERROR_LOG_FLAGS 0x1811b91c -+#define NAND_IDM_IDM_INTERRUPT_STATUS 0x1811ba00 -+#define QSPI_IDM_IDM_ERROR_LOG_CONTROL 0x1811c900 -+#define QSPI_IDM_IDM_ERROR_LOG_COMPLETE 0x1811c904 -+#define QSPI_IDM_IDM_ERROR_LOG_STATUS 0x1811c908 -+#define QSPI_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1811c90c -+#define QSPI_IDM_IDM_ERROR_LOG_ID 0x1811c914 -+#define QSPI_IDM_IDM_ERROR_LOG_FLAGS 0x1811c91c -+#define QSPI_IDM_IDM_INTERRUPT_STATUS 0x1811ca00 -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_CONTROL 0x1811d900 -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x1811d904 -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_STATUS 0x1811d908 -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1811d90c -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_ID 0x1811d914 -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1811d91c -+#define A9JTAG_S0_IDM_IDM_INTERRUPT_STATUS 0x1811da00 -+#define SRAM_S0_IDM_ERROR_LOG_CONTROL 0x18120900 -+#define SRAM_S0_IDM_ERROR_LOG_COMPLETE 0x18120904 -+#define SRAM_S0_IDM_ERROR_LOG_STATUS 0x18120908 -+#define SRAM_S0_IDM_ERROR_LOG_ADDR_LSB 0x1812090c -+#define SRAM_S0_IDM_ERROR_LOG_ID 0x18120914 -+#define SRAM_S0_IDM_ERROR_LOG_FLAGS 0x1812091c -+#define SRAM_S0_IDM_INTERRUPT_STATUS 0x18120a00 -+#define APBZ_S0_IDM_IDM_ERROR_LOG_CONTROL 0x18121900 -+#define APBZ_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x18121904 -+#define APBZ_S0_IDM_IDM_ERROR_LOG_STATUS 0x18121908 -+#define APBZ_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1812190c -+#define APBZ_S0_IDM_IDM_ERROR_LOG_ID 0x18121914 -+#define APBZ_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1812191c -+#define APBZ_S0_IDM_IDM_INTERRUPT_STATUS 0x18121a00 -+#define AXIIC_DS_3_IDM_ERROR_LOG_CONTROL 0x18123900 -+#define AXIIC_DS_3_IDM_ERROR_LOG_COMPLETE 0x18123904 -+#define AXIIC_DS_3_IDM_ERROR_LOG_STATUS 0x18123908 -+#define AXIIC_DS_3_IDM_ERROR_LOG_ADDR_LSB 0x1812390c -+#define AXIIC_DS_3_IDM_ERROR_LOG_ID 0x18123914 -+#define AXIIC_DS_3_IDM_ERROR_LOG_FLAGS 0x1812391c -+#define AXIIC_DS_3_IDM_INTERRUPT_STATUS 0x18123a00 -+#define APBW_IDM_IDM_ERROR_LOG_CONTROL 0x18131900 -+#define APBW_IDM_IDM_ERROR_LOG_COMPLETE 0x18131904 -+#define APBW_IDM_IDM_ERROR_LOG_STATUS 0x18131908 -+#define APBW_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1813190c -+#define APBW_IDM_IDM_ERROR_LOG_ID 0x18131914 -+#define APBW_IDM_IDM_ERROR_LOG_FLAGS 0x1813191c -+#define APBW_IDM_IDM_INTERRUPT_STATUS 0x18131a00 -+#define APBX_IDM_IDM_ERROR_LOG_CONTROL 0x18132900 -+#define APBX_IDM_IDM_ERROR_LOG_COMPLETE 0x18132904 -+#define APBX_IDM_IDM_ERROR_LOG_STATUS 0x18132908 -+#define APBX_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1813290c -+#define APBX_IDM_IDM_ERROR_LOG_ID 0x18132914 -+#define APBX_IDM_IDM_ERROR_LOG_FLAGS 0x1813291c -+#define APBX_IDM_IDM_INTERRUPT_STATUS 0x18132a00 -+#define AXIIC_DS_0_IDM_ERROR_LOG_CONTROL 0x18141900 -+#define AXIIC_DS_0_IDM_ERROR_LOG_COMPLETE 0x18141904 -+#define AXIIC_DS_0_IDM_ERROR_LOG_STATUS 0x18141908 -+#define AXIIC_DS_0_IDM_ERROR_LOG_ADDR_LSB 0x1814190c -+#define AXIIC_DS_0_IDM_ERROR_LOG_ID 0x18141914 -+#define AXIIC_DS_0_IDM_ERROR_LOG_FLAGS 0x1814191c -+#define AXIIC_DS_0_IDM_INTERRUPT_STATUS 0x18141a00 -+ -+#elif defined(CONFIG_MACH_HR3) -+ -+#define IHOST_S0_IDM_ERROR_LOG_CONTROL 0x18107900 -+#define IHOST_S0_IDM_ERROR_LOG_COMPLETE 0x18107904 -+#define IHOST_S0_IDM_ERROR_LOG_STATUS 0x18107908 -+#define IHOST_S0_IDM_ERROR_LOG_ADDR_LSB 0x1810790c -+#define IHOST_S0_IDM_ERROR_LOG_ID 0x18107914 -+#define IHOST_S0_IDM_ERROR_LOG_FLAGS 0x1810791c -+#define IHOST_S0_IDM_INTERRUPT_STATUS 0x18107a00 -+#define IHOST_S1_IDM_ERROR_LOG_CONTROL 0x18106900 -+#define IHOST_S1_IDM_ERROR_LOG_COMPLETE 0x18106904 -+#define IHOST_S1_IDM_ERROR_LOG_STATUS 0x18106908 -+#define IHOST_S1_IDM_ERROR_LOG_ADDR_LSB 0x1810690c -+#define IHOST_S1_IDM_ERROR_LOG_ID 0x18106914 -+#define IHOST_S1_IDM_ERROR_LOG_FLAGS 0x1810691c -+#define IHOST_S1_IDM_INTERRUPT_STATUS 0x18106a00 -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_CONTROL 0x18108900 -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x18108904 -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_STATUS 0x18108908 -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1810890c -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ID 0x18108914 -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1810891c -+#define AXI_PCIE_S0_IDM_IDM_INTERRUPT_STATUS 0x18108a00 -+#define CMICD_S0_IDM_IDM_ERROR_LOG_CONTROL 0x1810a900 -+#define CMICD_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x1810a904 -+#define CMICD_S0_IDM_IDM_ERROR_LOG_STATUS 0x1810a908 -+#define CMICD_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1810a90c -+#define CMICD_S0_IDM_IDM_ERROR_LOG_ID 0x1810a914 -+#define CMICD_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1810a91c -+#define CMICD_S0_IDM_IDM_INTERRUPT_STATUS 0x1810aa00 -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_CONTROL 0x18119900 -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x18119904 -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_STATUS 0x18119908 -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1811990c -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_ID 0x18119914 -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1811991c -+#define A9JTAG_S0_IDM_IDM_INTERRUPT_STATUS 0x18119a00 -+#define APBX_IDM_IDM_ERROR_LOG_CONTROL 0x18130900 -+#define APBX_IDM_IDM_ERROR_LOG_COMPLETE 0x18130904 -+#define APBX_IDM_IDM_ERROR_LOG_STATUS 0x18130908 -+#define APBX_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1813090c -+#define APBX_IDM_IDM_ERROR_LOG_ID 0x18130914 -+#define APBX_IDM_IDM_ERROR_LOG_FLAGS 0x1813091c -+#define APBX_IDM_IDM_INTERRUPT_STATUS 0x18130a00 -+#define DDR_S1_IDM_ERROR_LOG_CONTROL 0x18104900 -+#define DDR_S1_IDM_ERROR_LOG_COMPLETE 0x18104904 -+#define DDR_S1_IDM_ERROR_LOG_STATUS 0x18104908 -+#define DDR_S1_IDM_ERROR_LOG_ADDR_LSB 0x1810490c -+#define DDR_S1_IDM_ERROR_LOG_ID 0x18104914 -+#define DDR_S1_IDM_ERROR_LOG_FLAGS 0x1810491c -+#define DDR_S1_IDM_INTERRUPT_STATUS 0x18104a00 -+#define DDR_S2_IDM_ERROR_LOG_CONTROL 0x18105900 -+#define DDR_S2_IDM_ERROR_LOG_COMPLETE 0x18105904 -+#define DDR_S2_IDM_ERROR_LOG_STATUS 0x18105908 -+#define DDR_S2_IDM_ERROR_LOG_ADDR_LSB 0x1810590c -+#define DDR_S2_IDM_ERROR_LOG_ID 0x18105914 -+#define DDR_S2_IDM_ERROR_LOG_FLAGS 0x1810591c -+#define DDR_S2_IDM_INTERRUPT_STATUS 0x18105a00 -+#define ROM_S0_IDM_ERROR_LOG_CONTROL 0x1811a900 -+#define ROM_S0_IDM_ERROR_LOG_COMPLETE 0x1811a904 -+#define ROM_S0_IDM_ERROR_LOG_STATUS 0x1811a908 -+#define ROM_S0_IDM_ERROR_LOG_ADDR_LSB 0x1811a90c -+#define ROM_S0_IDM_ERROR_LOG_ID 0x1811a914 -+#define ROM_S0_IDM_ERROR_LOG_FLAGS 0x1811a91c -+#define ROM_S0_IDM_INTERRUPT_STATUS 0x1811aa00 -+#define NAND_IDM_IDM_ERROR_LOG_CONTROL 0x1811d900 -+#define NAND_IDM_IDM_ERROR_LOG_COMPLETE 0x1811d904 -+#define NAND_IDM_IDM_ERROR_LOG_STATUS 0x1811d908 -+#define NAND_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1811d90c -+#define NAND_IDM_IDM_ERROR_LOG_ID 0x1811d914 -+#define NAND_IDM_IDM_ERROR_LOG_FLAGS 0x1811d91c -+#define NAND_IDM_IDM_INTERRUPT_STATUS 0x1811da00 -+#define QSPI_IDM_IDM_ERROR_LOG_CONTROL 0x1811f900 -+#define QSPI_IDM_IDM_ERROR_LOG_COMPLETE 0x1811f904 -+#define QSPI_IDM_IDM_ERROR_LOG_STATUS 0x1811f908 -+#define QSPI_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1811f90c -+#define QSPI_IDM_IDM_ERROR_LOG_ID 0x1811f914 -+#define QSPI_IDM_IDM_ERROR_LOG_FLAGS 0x1811f91c -+#define QSPI_IDM_IDM_INTERRUPT_STATUS 0x1811fa00 -+#define AXIIC_DS_0_IDM_ERROR_LOG_CONTROL 0x18120900 -+#define AXIIC_DS_0_IDM_ERROR_LOG_COMPLETE 0x18120904 -+#define AXIIC_DS_0_IDM_ERROR_LOG_STATUS 0x18120908 -+#define AXIIC_DS_0_IDM_ERROR_LOG_ADDR_LSB 0x1812090c -+#define AXIIC_DS_0_IDM_ERROR_LOG_ID 0x18120914 -+#define AXIIC_DS_0_IDM_ERROR_LOG_FLAGS 0x1812091c -+#define AXIIC_DS_0_IDM_INTERRUPT_STATUS 0x18120a00 -+ -+#elif defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_SB2) || \ -+ defined(CONFIG_MACH_GH2) -+ -+#define IHOST_S0_IDM_ERROR_LOG_CONTROL 0x18107900 -+#define IHOST_S0_IDM_ERROR_LOG_COMPLETE 0x18107904 -+#define IHOST_S0_IDM_ERROR_LOG_STATUS 0x18107908 -+#define IHOST_S0_IDM_ERROR_LOG_ADDR_LSB 0x1810790c -+#define IHOST_S0_IDM_ERROR_LOG_ID 0x18107914 -+#define IHOST_S0_IDM_ERROR_LOG_FLAGS 0x1810791c -+#define IHOST_S0_IDM_INTERRUPT_STATUS 0x18107a00 -+#define IHOST_S1_IDM_ERROR_LOG_CONTROL 0x18106900 -+#define IHOST_S1_IDM_ERROR_LOG_COMPLETE 0x18106904 -+#define IHOST_S1_IDM_ERROR_LOG_STATUS 0x18106908 -+#define IHOST_S1_IDM_ERROR_LOG_ADDR_LSB 0x1810690c -+#define IHOST_S1_IDM_ERROR_LOG_ID 0x18106914 -+#define IHOST_S1_IDM_ERROR_LOG_FLAGS 0x1810691c -+#define IHOST_S1_IDM_INTERRUPT_STATUS 0x18106a00 -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_CONTROL 0x18108900 -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x18108904 -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_STATUS 0x18108908 -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1810890c -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ID 0x18108914 -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1810891c -+#define AXI_PCIE_S0_IDM_IDM_INTERRUPT_STATUS 0x18108a00 -+#define CMICD_S0_IDM_IDM_ERROR_LOG_CONTROL 0x1810a900 -+#define CMICD_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x1810a904 -+#define CMICD_S0_IDM_IDM_ERROR_LOG_STATUS 0x1810a908 -+#define CMICD_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1810a90c -+#define CMICD_S0_IDM_IDM_ERROR_LOG_ID 0x1810a914 -+#define CMICD_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1810a91c -+#define CMICD_S0_IDM_IDM_INTERRUPT_STATUS 0x1810aa00 -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_CONTROL 0x18119900 -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_COMPLETE 0x18119904 -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_STATUS 0x18119908 -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1811990c -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_ID 0x18119914 -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_FLAGS 0x1811991c -+#define A9JTAG_S0_IDM_IDM_INTERRUPT_STATUS 0x18119a00 -+#define SRAM_S0_IDM_ERROR_LOG_CONTROL 0x1811b900 -+#define SRAM_S0_IDM_ERROR_LOG_COMPLETE 0x1811b904 -+#define SRAM_S0_IDM_ERROR_LOG_STATUS 0x1811b908 -+#define SRAM_S0_IDM_ERROR_LOG_ADDR_LSB 0x1811b90c -+#define SRAM_S0_IDM_ERROR_LOG_ID 0x1811b914 -+#define SRAM_S0_IDM_ERROR_LOG_FLAGS 0x1811b91c -+#define SRAM_S0_IDM_INTERRUPT_STATUS 0x1811ba00 -+#define APBX_IDM_IDM_ERROR_LOG_CONTROL 0x18130900 -+#define APBX_IDM_IDM_ERROR_LOG_COMPLETE 0x18130904 -+#define APBX_IDM_IDM_ERROR_LOG_STATUS 0x18130908 -+#define APBX_IDM_IDM_ERROR_LOG_ADDR_LSB 0x1813090c -+#define APBX_IDM_IDM_ERROR_LOG_ID 0x18130914 -+#define APBX_IDM_IDM_ERROR_LOG_FLAGS 0x1813091c -+#define APBX_IDM_IDM_INTERRUPT_STATUS 0x18130a00 -+#define DDR_S1_IDM_ERROR_LOG_CONTROL 0xf8102900 -+#define DDR_S1_IDM_ERROR_LOG_COMPLETE 0xf8102904 -+#define DDR_S1_IDM_ERROR_LOG_STATUS 0xf8102908 -+#define DDR_S1_IDM_ERROR_LOG_ADDR_LSB 0xf810290c -+#define DDR_S1_IDM_ERROR_LOG_ID 0xf8102914 -+#define DDR_S1_IDM_ERROR_LOG_FLAGS 0xf810291c -+#define DDR_S1_IDM_INTERRUPT_STATUS 0xf8102a00 -+#define DDR_S2_IDM_ERROR_LOG_CONTROL 0xf8103900 -+#define DDR_S2_IDM_ERROR_LOG_COMPLETE 0xf8103904 -+#define DDR_S2_IDM_ERROR_LOG_STATUS 0xf8103908 -+#define DDR_S2_IDM_ERROR_LOG_ADDR_LSB 0xf810390c -+#define DDR_S2_IDM_ERROR_LOG_ID 0xf8103914 -+#define DDR_S2_IDM_ERROR_LOG_FLAGS 0xf810391c -+#define DDR_S2_IDM_INTERRUPT_STATUS 0xf8103a00 -+#define ROM_S0_IDM_ERROR_LOG_CONTROL 0xf8104900 -+#define ROM_S0_IDM_ERROR_LOG_COMPLETE 0xf8104904 -+#define ROM_S0_IDM_ERROR_LOG_STATUS 0xf8104908 -+#define ROM_S0_IDM_ERROR_LOG_ADDR_LSB 0xf810490c -+#define ROM_S0_IDM_ERROR_LOG_ID 0xf8104914 -+#define ROM_S0_IDM_ERROR_LOG_FLAGS 0xf810491c -+#define ROM_S0_IDM_INTERRUPT_STATUS 0xf8104a00 -+#define NAND_IDM_IDM_ERROR_LOG_CONTROL 0xf8105900 -+#define NAND_IDM_IDM_ERROR_LOG_COMPLETE 0xf8105904 -+#define NAND_IDM_IDM_ERROR_LOG_STATUS 0xf8105908 -+#define NAND_IDM_IDM_ERROR_LOG_ADDR_LSB 0xf810590c -+#define NAND_IDM_IDM_ERROR_LOG_ID 0xf8105914 -+#define NAND_IDM_IDM_ERROR_LOG_FLAGS 0xf810591c -+#define NAND_IDM_IDM_INTERRUPT_STATUS 0xf8105a00 -+#define QSPI_IDM_IDM_ERROR_LOG_CONTROL 0xf8106900 -+#define QSPI_IDM_IDM_ERROR_LOG_COMPLETE 0xf8106904 -+#define QSPI_IDM_IDM_ERROR_LOG_STATUS 0xf8106908 -+#define QSPI_IDM_IDM_ERROR_LOG_ADDR_LSB 0xf810690c -+#define QSPI_IDM_IDM_ERROR_LOG_ID 0xf8106914 -+#define QSPI_IDM_IDM_ERROR_LOG_FLAGS 0xf810691c -+#define QSPI_IDM_IDM_INTERRUPT_STATUS 0xf8106a00 -+#define AXIIC_DS_0_IDM_ERROR_LOG_CONTROL 0x18120900 -+#define AXIIC_DS_0_IDM_ERROR_LOG_COMPLETE 0x18120904 -+#define AXIIC_DS_0_IDM_ERROR_LOG_STATUS 0x18120908 -+#define AXIIC_DS_0_IDM_ERROR_LOG_ADDR_LSB 0x1812090c -+#define AXIIC_DS_0_IDM_ERROR_LOG_ID 0x18120914 -+#define AXIIC_DS_0_IDM_ERROR_LOG_FLAGS 0x1812091c -+#define AXIIC_DS_0_IDM_INTERRUPT_STATUS 0x18120a00 -+#if !defined(CONFIG_MACH_GH2) -+#define AXIIC_DS_3_IDM_ERROR_LOG_CONTROL 0x1811e900 -+#define AXIIC_DS_3_IDM_ERROR_LOG_COMPLETE 0x1811e904 -+#define AXIIC_DS_3_IDM_ERROR_LOG_STATUS 0x1811e908 -+#define AXIIC_DS_3_IDM_ERROR_LOG_ADDR_LSB 0x1811e90c -+#define AXIIC_DS_3_IDM_ERROR_LOG_ID 0x1811e914 -+#define AXIIC_DS_3_IDM_ERROR_LOG_FLAGS 0x1811e91c -+#define AXIIC_DS_3_IDM_INTERRUPT_STATUS 0x1811ea00 -+#endif /* !defined(CONFIG_MACH_GH2) */ -+ -+#endif /* defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) || \ -+ defined(CONFIG_MACH_HR2) */ -+ -+#if defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_SB2) || \ -+ defined(CONFIG_MACH_GH2) -+#define IDM_IO_PHYS_TO_VIRT(x) (void __iomem *) \ -+ (((x & 0xFFF00000) == (int)get_iproc_idm_base_phys(0))? \ -+ get_iproc_idm_base(0) + x - get_iproc_idm_base_phys(0) : \ -+ get_iproc_idm_base(1) + x - get_iproc_idm_base_phys(1)) -+#else -+#define IDM_IO_PHYS_TO_VIRT(x) (void __iomem *) \ -+ (get_iproc_idm_base(0) + x - get_iproc_idm_base_phys(0)) -+#endif -+ -+ -+#define IHOST_S1_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(IHOST_S1_IDM_ERROR_LOG_CONTROL) -+#define IHOST_S1_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(IHOST_S1_IDM_ERROR_LOG_COMPLETE) -+#define IHOST_S1_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(IHOST_S1_IDM_ERROR_LOG_STATUS) -+#define IHOST_S1_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(IHOST_S1_IDM_ERROR_LOG_ADDR_LSB) -+#define IHOST_S1_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(IHOST_S1_IDM_ERROR_LOG_ID) -+#define IHOST_S1_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(IHOST_S1_IDM_ERROR_LOG_FLAGS) -+ -+#define IHOST_S0_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(IHOST_S0_IDM_ERROR_LOG_CONTROL) -+#define IHOST_S0_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(IHOST_S0_IDM_ERROR_LOG_COMPLETE) -+#define IHOST_S0_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(IHOST_S0_IDM_ERROR_LOG_STATUS) -+#define IHOST_S0_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(IHOST_S0_IDM_ERROR_LOG_ADDR_LSB) -+#define IHOST_S0_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(IHOST_S0_IDM_ERROR_LOG_ID) -+#define IHOST_S0_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(IHOST_S0_IDM_ERROR_LOG_FLAGS) -+ -+#define DDR_S1_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(DDR_S1_IDM_ERROR_LOG_CONTROL) -+#define DDR_S1_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(DDR_S1_IDM_ERROR_LOG_COMPLETE) -+#define DDR_S1_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(DDR_S1_IDM_ERROR_LOG_STATUS) -+#define DDR_S1_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(DDR_S1_IDM_ERROR_LOG_ADDR_LSB) -+#define DDR_S1_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(DDR_S1_IDM_ERROR_LOG_ID) -+#define DDR_S1_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(DDR_S1_IDM_ERROR_LOG_FLAGS) -+ -+#define DDR_S2_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(DDR_S2_IDM_ERROR_LOG_CONTROL) -+#define DDR_S2_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(DDR_S2_IDM_ERROR_LOG_COMPLETE) -+#define DDR_S2_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(DDR_S2_IDM_ERROR_LOG_STATUS) -+#define DDR_S2_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(DDR_S2_IDM_ERROR_LOG_ADDR_LSB) -+#define DDR_S2_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(DDR_S2_IDM_ERROR_LOG_ID) -+#define DDR_S2_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(DDR_S2_IDM_ERROR_LOG_FLAGS) -+ -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_CONTROL) -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_COMPLETE) -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_STATUS) -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ADDR_LSB) -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ID) -+#define AXI_PCIE_S0_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_FLAGS) -+ -+#define CMICD_S0_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(CMICD_S0_IDM_IDM_ERROR_LOG_CONTROL) -+#define CMICD_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(CMICD_S0_IDM_IDM_ERROR_LOG_COMPLETE) -+#define CMICD_S0_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(CMICD_S0_IDM_IDM_ERROR_LOG_STATUS) -+#define CMICD_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(CMICD_S0_IDM_IDM_ERROR_LOG_ADDR_LSB) -+#define CMICD_S0_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(CMICD_S0_IDM_IDM_ERROR_LOG_ID) -+#define CMICD_S0_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(CMICD_S0_IDM_IDM_ERROR_LOG_FLAGS) -+ -+#define APBY_S0_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(APBY_S0_IDM_IDM_ERROR_LOG_CONTROL) -+#define APBY_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(APBY_S0_IDM_IDM_ERROR_LOG_COMPLETE) -+#define APBY_S0_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(APBY_S0_IDM_IDM_ERROR_LOG_STATUS) -+#define APBY_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(APBY_S0_IDM_IDM_ERROR_LOG_ADDR_LSB) -+#define APBY_S0_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(APBY_S0_IDM_IDM_ERROR_LOG_ID) -+#define APBY_S0_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(APBY_S0_IDM_IDM_ERROR_LOG_FLAGS) -+ -+#define ROM_S0_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(ROM_S0_IDM_ERROR_LOG_CONTROL) -+#define ROM_S0_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(ROM_S0_IDM_ERROR_LOG_COMPLETE) -+#define ROM_S0_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(ROM_S0_IDM_ERROR_LOG_STATUS) -+#define ROM_S0_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(ROM_S0_IDM_ERROR_LOG_ADDR_LSB) -+#define ROM_S0_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(ROM_S0_IDM_ERROR_LOG_ID) -+#define ROM_S0_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(ROM_S0_IDM_ERROR_LOG_FLAGS) -+ -+#define NAND_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(NAND_IDM_IDM_ERROR_LOG_CONTROL) -+#define NAND_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(NAND_IDM_IDM_ERROR_LOG_COMPLETE) -+#define NAND_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(NAND_IDM_IDM_ERROR_LOG_STATUS) -+#define NAND_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(NAND_IDM_IDM_ERROR_LOG_ADDR_LSB) -+#define NAND_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(NAND_IDM_IDM_ERROR_LOG_ID) -+#define NAND_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(NAND_IDM_IDM_ERROR_LOG_FLAGS) -+ -+#define QSPI_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(QSPI_IDM_IDM_ERROR_LOG_CONTROL) -+#define QSPI_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(QSPI_IDM_IDM_ERROR_LOG_COMPLETE) -+#define QSPI_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(QSPI_IDM_IDM_ERROR_LOG_STATUS) -+#define QSPI_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(QSPI_IDM_IDM_ERROR_LOG_ADDR_LSB) -+#define QSPI_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(QSPI_IDM_IDM_ERROR_LOG_ID) -+#define QSPI_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(QSPI_IDM_IDM_ERROR_LOG_FLAGS) -+ -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(A9JTAG_S0_IDM_IDM_ERROR_LOG_CONTROL) -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(A9JTAG_S0_IDM_IDM_ERROR_LOG_COMPLETE) -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(A9JTAG_S0_IDM_IDM_ERROR_LOG_STATUS) -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(A9JTAG_S0_IDM_IDM_ERROR_LOG_ADDR_LSB) -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(A9JTAG_S0_IDM_IDM_ERROR_LOG_ID) -+#define A9JTAG_S0_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(A9JTAG_S0_IDM_IDM_ERROR_LOG_FLAGS) -+ -+#define SRAM_S0_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(SRAM_S0_IDM_ERROR_LOG_CONTROL) -+#define SRAM_S0_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(SRAM_S0_IDM_ERROR_LOG_COMPLETE) -+#define SRAM_S0_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(SRAM_S0_IDM_ERROR_LOG_STATUS) -+#define SRAM_S0_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(SRAM_S0_IDM_ERROR_LOG_ADDR_LSB) -+#define SRAM_S0_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(SRAM_S0_IDM_ERROR_LOG_ID) -+#define SRAM_S0_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(SRAM_S0_IDM_ERROR_LOG_FLAGS) -+ -+#define APBZ_S0_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(APBZ_S0_IDM_IDM_ERROR_LOG_CONTROL) -+#define APBZ_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(APBZ_S0_IDM_IDM_ERROR_LOG_COMPLETE) -+#define APBZ_S0_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(APBZ_S0_IDM_IDM_ERROR_LOG_STATUS) -+#define APBZ_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(APBZ_S0_IDM_IDM_ERROR_LOG_ADDR_LSB) -+#define APBZ_S0_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(APBZ_S0_IDM_IDM_ERROR_LOG_ID) -+#define APBZ_S0_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(APBZ_S0_IDM_IDM_ERROR_LOG_FLAGS) -+ -+#define AXIIC_DS_3_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_3_IDM_ERROR_LOG_CONTROL) -+#define AXIIC_DS_3_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_3_IDM_ERROR_LOG_COMPLETE) -+#define AXIIC_DS_3_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_3_IDM_ERROR_LOG_STATUS) -+#define AXIIC_DS_3_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_3_IDM_ERROR_LOG_ADDR_LSB) -+#define AXIIC_DS_3_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_3_IDM_ERROR_LOG_ID) -+#define AXIIC_DS_3_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_3_IDM_ERROR_LOG_FLAGS) -+ -+#define APBW_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(APBW_IDM_IDM_ERROR_LOG_CONTROL) -+#define APBW_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(APBW_IDM_IDM_ERROR_LOG_COMPLETE) -+#define APBW_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(APBW_IDM_IDM_ERROR_LOG_STATUS) -+#define APBW_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(APBW_IDM_IDM_ERROR_LOG_ADDR_LSB) -+#define APBW_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(APBW_IDM_IDM_ERROR_LOG_ID) -+#define APBW_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(APBW_IDM_IDM_ERROR_LOG_FLAGS) -+ -+#define APBX_IDM_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(APBX_IDM_IDM_ERROR_LOG_CONTROL) -+#define APBX_IDM_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(APBX_IDM_IDM_ERROR_LOG_COMPLETE) -+#define APBX_IDM_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(APBX_IDM_IDM_ERROR_LOG_STATUS) -+#define APBX_IDM_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(APBX_IDM_IDM_ERROR_LOG_ADDR_LSB) -+#define APBX_IDM_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(APBX_IDM_IDM_ERROR_LOG_ID) -+#define APBX_IDM_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(APBX_IDM_IDM_ERROR_LOG_FLAGS) -+ -+#define AXIIC_DS_0_IDM_ERROR_LOG_CONTROL_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_0_IDM_ERROR_LOG_CONTROL) -+#define AXIIC_DS_0_IDM_ERROR_LOG_COMPLETE_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_0_IDM_ERROR_LOG_COMPLETE) -+#define AXIIC_DS_0_IDM_ERROR_LOG_STATUS_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_0_IDM_ERROR_LOG_STATUS) -+#define AXIIC_DS_0_IDM_ERROR_LOG_ADDR_LSB_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_0_IDM_ERROR_LOG_ADDR_LSB) -+#define AXIIC_DS_0_IDM_ERROR_LOG_ID_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_0_IDM_ERROR_LOG_ID) -+#define AXIIC_DS_0_IDM_ERROR_LOG_FLAGS_VA IDM_IO_PHYS_TO_VIRT(AXIIC_DS_0_IDM_ERROR_LOG_FLAGS) -+ -+#define IDM_ERROR_LOG_ENABLE 0x33A -+#define IDM_ERROR_LOG_CLEAR 0x3 -+ -+#ifdef CONFIG_MACH_IPROC_P7 -+ -+#if defined(CONFIG_MACH_HR3) || defined(CONFIG_MACH_GH2) -+#define IHOST_S0_IDM_IRQ 52 -+#define DDR_S1_IDM_IRQ 53 -+#define DDR_S2_IDM_IRQ 54 -+#define AXI_PCIE_S0_IDM_IRQ 55 -+#define ROM_S0_IDM_IRQ 56 -+#define NAND_IDM_IRQ 57 -+#define QSPI_IDM_IRQ 58 -+#define PNOR_IDM_IRQ 59 -+#define SRAM_S0_IDM_IRQ 60 -+#define A9JTAG_S0_IDM_IRQ 61 -+#define APX_IDM_IRQ 64 -+#define CMICD_S0_IDM_IRQ 67 -+#define AXIIC_DS_0_IDM_IRQ 68 -+#define AXIIC_DS_1_IDM_IRQ 69 -+#define AXIIC_DS_2_IDM_IRQ 70 -+#else -+#define IHOST_S0_IDM_IRQ 52 -+#define DDR_S1_IDM_IRQ 54 -+#define DDR_S2_IDM_IRQ 55 -+#define AXI_PCIE_S0_IDM_IRQ 56 -+#define AXI_PCIE_S1_IDM_IRQ 57 -+#define ROM_S0_IDM_IRQ 58 -+#define NAND_IDM_IRQ 59 -+#define QSPI_IDM_IRQ 60 -+#define SRAM_S0_IDM_IRQ 62 -+#define A9JTAG_S0_IDM_IRQ 64 -+#define APX_IDM_IRQ 68 -+#define CMICD_S0_IDM_IRQ 71 -+#define AXIIC_DS_0_IDM_IRQ 78 -+#define AXIIC_DS_1_IDM_IRQ 79 -+#define AXIIC_DS_2_IDM_IRQ 80 -+#define AXIIC_DS_3_IDM_IRQ 81 -+#endif /* defined(CONFIG_MACH_HR3) || defined(CONFIG_MACH_GH2) */ -+ -+#else /* CONFIG_MACH_IPROC_P7 */ -+ -+#define IHOST_S1_IDM_IRQ 62 -+#define IHOST_S0_IDM_IRQ 63 -+#define DDR_S1_IDM_IRQ 64 -+#define DDR_S2_IDM_IRQ 65 -+#define AXI_PCIE_S0_IDM_IRQ 66 -+#define AXI_PCIE_S1_IDM_IRQ 67 -+#define CMICD_S0_IDM_IRQ 68 -+#define ROM_S0_IDM_IRQ 69 -+#define NAND_IDM_IRQ 70 -+#define QSPI_IDM_IRQ 71 -+#define A9JTAG_S0_IDM_IRQ 73 -+#define SRAM_S0_IDM_IRQ 74 -+#define APW_IDM_IRQ 75 -+#define APX_IDM_IRQ 76 -+#define APBY_S0_IDM_IRQ 77 -+#define APBZ_S0_IDM_IRQ 78 -+#define AXIIC_DS_0_IDM_IRQ 79 -+#define AXIIC_DS_1_IDM_IRQ 80 -+#define AXIIC_DS_2_IDM_IRQ 81 -+#define AXIIC_DS_3_IDM_IRQ 82 -+#define AXIIC_DS_4_IDM_IRQ 83 -+ -+#endif /* CONFIG_MACH_IPROC_P7 */ -+ -+static irqreturn_t idm_timeout_handler(int val, void *ptr) -+{ -+ u32 errval; -+ -+ printk(KERN_DEBUG "%s: %d, %d entry\n", __func__, __LINE__, val); -+ errval = readl(IHOST_S1_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(IHOST_S1_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(IHOST_S1_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(IHOST_S1_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, IHOST_S1_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(IHOST_S1_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+ errval = readl(IHOST_S0_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(IHOST_S0_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(IHOST_S0_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(IHOST_S0_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, IHOST_S0_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(IHOST_S0_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+ errval = readl(DDR_S1_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(DDR_S1_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(DDR_S1_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(DDR_S1_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, DDR_S1_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(DDR_S1_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+ errval = readl(DDR_S2_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(DDR_S2_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(DDR_S2_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(DDR_S2_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, DDR_S2_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(DDR_S2_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+ errval = readl(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, AXI_PCIE_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(AXI_PCIE_S0_IDM_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+ errval = readl(CMICD_S0_IDM_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(CMICD_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(CMICD_S0_IDM_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(CMICD_S0_IDM_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, CMICD_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(CMICD_S0_IDM_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+#if !defined(CONFIG_MACH_IPROC_P7) -+ errval = readl(APBY_S0_IDM_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(APBY_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(APBY_S0_IDM_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(APBY_S0_IDM_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, APBY_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(APBY_S0_IDM_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+#endif -+ errval = readl(ROM_S0_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(ROM_S0_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(ROM_S0_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(ROM_S0_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, ROM_S0_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(ROM_S0_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+ errval = readl(NAND_IDM_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(NAND_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(NAND_IDM_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(NAND_IDM_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, NAND_IDM_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(NAND_IDM_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+ errval = readl(QSPI_IDM_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(QSPI_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(QSPI_IDM_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(QSPI_IDM_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, QSPI_IDM_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(QSPI_IDM_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+ errval = readl(A9JTAG_S0_IDM_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(A9JTAG_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(A9JTAG_S0_IDM_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(A9JTAG_S0_IDM_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, A9JTAG_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(A9JTAG_S0_IDM_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+#if !defined(CONFIG_MACH_IPROC_P7) -+ errval = readl(SRAM_S0_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(SRAM_S0_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(SRAM_S0_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(SRAM_S0_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, SRAM_S0_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(SRAM_S0_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+ errval = readl(APBZ_S0_IDM_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(APBZ_S0_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(APBZ_S0_IDM_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(APBZ_S0_IDM_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, APBZ_S0_IDM_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(APBZ_S0_IDM_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+#endif -+ -+#if !defined(CONFIG_MACH_HR3) && !defined(CONFIG_MACH_GH2) -+ errval = readl(AXIIC_DS_3_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(AXIIC_DS_3_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(AXIIC_DS_3_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(AXIIC_DS_3_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, AXIIC_DS_3_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(AXIIC_DS_3_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+#endif /* !defined(CONFIG_MACH_HR3) && !defined(CONFIG_MACH_GH2)*/ -+ -+#if !defined(CONFIG_MACH_IPROC_P7) -+ errval = readl(APBW_IDM_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(APBW_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(APBW_IDM_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(APBW_IDM_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, APBW_IDM_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(APBW_IDM_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+#endif -+ errval = readl(APBX_IDM_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(APBX_IDM_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(APBX_IDM_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(APBX_IDM_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, APBX_IDM_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(APBX_IDM_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+ errval = readl(AXIIC_DS_0_IDM_ERROR_LOG_STATUS_VA); -+ if (errval > 0) -+ { -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ errval = readl(AXIIC_DS_0_IDM_ERROR_LOG_ADDR_LSB_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(AXIIC_DS_0_IDM_ERROR_LOG_ID_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ errval = readl(AXIIC_DS_0_IDM_ERROR_LOG_FLAGS_VA); -+ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, errval); -+ writel(IDM_ERROR_LOG_CLEAR, AXIIC_DS_0_IDM_ERROR_LOG_COMPLETE_VA); -+ errval = readl(AXIIC_DS_0_IDM_ERROR_LOG_STATUS_VA); -+ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, errval); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+void init_request_idm_timeout(void) -+{ -+ /* clear all pending idm interrupts */ -+ idm_timeout_handler(0, NULL); -+ -+ /* enable idm error log for all slaves */ -+ -+ writel(IDM_ERROR_LOG_ENABLE, IHOST_S1_IDM_ERROR_LOG_CONTROL_VA); -+ writel(IDM_ERROR_LOG_ENABLE, IHOST_S0_IDM_ERROR_LOG_COMPLETE_VA); -+ writel(IDM_ERROR_LOG_ENABLE, DDR_S1_IDM_ERROR_LOG_COMPLETE_VA); -+ writel(IDM_ERROR_LOG_ENABLE, DDR_S2_IDM_ERROR_LOG_COMPLETE_VA); -+ writel(IDM_ERROR_LOG_ENABLE, AXI_PCIE_S0_IDM_IDM_ERROR_LOG_CONTROL_VA); -+ writel(IDM_ERROR_LOG_ENABLE, CMICD_S0_IDM_IDM_ERROR_LOG_CONTROL_VA); -+ -+#if !defined(CONFIG_MACH_HR3) && !defined(CONFIG_MACH_GH2) -+ writel(IDM_ERROR_LOG_ENABLE, SRAM_S0_IDM_ERROR_LOG_CONTROL_VA); -+#endif /* !defined(CONFIG_MACH_HR3) && !defined(CONFIG_MACH_GH2)*/ -+ -+#ifndef CONFIG_MACH_IPROC_P7 -+ writel(IDM_ERROR_LOG_ENABLE, APBY_S0_IDM_IDM_ERROR_LOG_CONTROL_VA); -+ writel(IDM_ERROR_LOG_ENABLE, APBZ_S0_IDM_IDM_ERROR_LOG_CONTROL_VA); -+ writel(IDM_ERROR_LOG_ENABLE, APBW_IDM_IDM_ERROR_LOG_CONTROL_VA); -+#endif -+ -+ writel(IDM_ERROR_LOG_ENABLE, ROM_S0_IDM_ERROR_LOG_CONTROL_VA); -+ writel(IDM_ERROR_LOG_ENABLE, NAND_IDM_IDM_ERROR_LOG_CONTROL_VA); -+ writel(IDM_ERROR_LOG_ENABLE, QSPI_IDM_IDM_ERROR_LOG_CONTROL_VA); -+ writel(IDM_ERROR_LOG_ENABLE, A9JTAG_S0_IDM_IDM_ERROR_LOG_CONTROL_VA); -+#if !defined(CONFIG_MACH_HR3) && !defined(CONFIG_MACH_GH2) -+ writel(IDM_ERROR_LOG_ENABLE, AXIIC_DS_3_IDM_ERROR_LOG_COMPLETE_VA); -+#endif /* !defined(CONFIG_MACH_HR3) && !defined(CONFIG_MACH_GH2) */ -+ writel(IDM_ERROR_LOG_ENABLE, APBX_IDM_IDM_ERROR_LOG_CONTROL_VA); -+ writel(IDM_ERROR_LOG_ENABLE, AXIIC_DS_0_IDM_ERROR_LOG_CONTROL_VA); -+} -+ -+int request_idm_timeout_interrupts(struct device_node *np) -+{ -+ int i, ret, irq; -+ unsigned int irqs_total; -+ -+ init_request_idm_timeout(); -+ -+ irqs_total = of_irq_count(np); -+ if (!irqs_total) -+ return -EINVAL; -+ -+ for (i=0; i -+#include -+#include -+#include -+ -+#define IPROC_DMU_PCU_COMPATIBLE "brcm,iproc-dmu-pcu" -+#define IPROC_WRAP_CTRL_COMPATIBLE "brcm,iproc-wrap-ctrl" -+#define IPROC_IDM_COMPATIBLE "brcm,iproc-idm" -+#define MAX_IDM_NUM 2 -+ -+static void __iomem *iproc_dmu_pcu_base=NULL; -+static void __iomem *iproc_wrap_ctrl_base=NULL; -+static void __iomem *iproc_idm_base[MAX_IDM_NUM]={NULL}; -+static void __iomem *iproc_idm_base_phys[MAX_IDM_NUM]={NULL}; -+ -+ -+extern void request_idm_timeout_interrupts(struct device_node *); -+ -+void inline __iomem *get_iproc_dmu_pcu_base(void) { -+ return iproc_dmu_pcu_base; -+} -+ -+void inline __iomem *get_iproc_wrap_ctrl_base(void) { -+ return iproc_wrap_ctrl_base; -+} -+ -+void inline __iomem *get_iproc_idm_base(int index) { -+ return iproc_idm_base[index]; -+} -+ -+void inline __iomem *get_iproc_idm_base_phys(int index) { -+ return iproc_idm_base_phys[index]; -+} -+ -+int xgs_iproc_wrap_idm_dmu_base_reg_setup(void) -+{ -+ struct device_node *np; -+ -+ /* Get DMU/PCU base addr */ -+ np = of_find_compatible_node(NULL, NULL, IPROC_DMU_PCU_COMPATIBLE); -+ if (!np) { -+ pr_err("%s: No dmu/pcu node found\n", __func__); -+ return -ENODEV ; -+ } -+ iproc_dmu_pcu_base = of_iomap(np, 0); -+ if (!iproc_dmu_pcu_base) -+ return -ENOMEM; -+ -+ /* Get WRAP CTRL base addr */ -+ np = of_find_compatible_node(NULL, NULL, IPROC_WRAP_CTRL_COMPATIBLE); -+ if (!np) { -+ pr_err("%s: No wrap ctrl node found\n", __func__); -+ return -ENODEV; -+ } -+ iproc_wrap_ctrl_base = of_iomap(np, 0); -+ if (!iproc_wrap_ctrl_base) -+ return -ENOMEM; -+ -+ /* Get IDM base addr */ -+ np = of_find_compatible_node(NULL, NULL, IPROC_IDM_COMPATIBLE); -+ if (!np) { -+ pr_err("%s: No IDM node found\n", __func__); -+ return -ENODEV; -+ } -+ iproc_idm_base[0] = of_iomap(np, 0); -+ if (!iproc_idm_base[0]) -+ return -ENOMEM; -+ -+ /* Second IDM base addr required for GH/SB2/GH2 IDM timeout handling. -+ * For other devices, the second IDM base addr is not used. So, it is -+ * fine even the addr is NULL. -+ */ -+ iproc_idm_base[1] = of_iomap(np, 1); -+ -+ return 1; -+} -+ -+void xgs_iproc_idm_timeout_handler_setup(void) -+{ -+ struct device_node *np; -+ struct platform_device *pdev=NULL; -+ struct resource *res_mem; -+ -+ /* To get IDM phys addr */ -+ np = of_find_compatible_node(NULL, NULL, IPROC_IDM_COMPATIBLE); -+ if (!np) { -+ pr_warn("%s: No IDM node found\n", __func__); -+ return; -+ } -+ pdev = of_find_device_by_node(np); -+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res_mem) { -+ pr_warn("%s: No resource found\n", __func__); -+ return; -+ } -+ iproc_idm_base_phys[0] = (void __iomem *)res_mem->start; -+ -+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ /* Only GH/SB2/GH2 has second IDM base addr */ -+ if (res_mem) -+ iproc_idm_base_phys[1] = (void __iomem *)res_mem->start; -+ -+ /* register IDM timeout interrupt handler */ -+ request_idm_timeout_interrupts(np); -+} -\ No newline at end of file -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/spi/Kconfig b/drivers/spi/Kconfig ---- a/drivers/spi/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/spi/Kconfig 2017-11-09 17:53:55.798375000 +0800 -@@ -654,6 +654,74 @@ config SPI_NUC900 - help - SPI driver for Nuvoton NUC900 series ARM SoCs - -+config SPI_XGS_IPROC -+ tristate "BRCM XGS iProc QSPI support" -+ depends on ARCH_XGS_IPROC -+ default n -+ help -+ This selects a driver for the iProc QSPI Controller (for serial flash). -+ -+ If unsure, say N. -+ -+if SPI_XGS_IPROC -+ -+choice -+ prompt "Multi I/O SPI support" -+ default IPROC_QSPI_SINGLE_MODE -+ help -+ Number of (multi I/O) data lanes supported by the SPI flash. -+ -+config IPROC_QSPI_SINGLE_MODE -+ bool "Single lane" -+ help -+ Single lane. -+ -+config IPROC_QSPI_DUAL_MODE -+ bool "Dual mode" -+ help -+ Dual mode. -+ -+config IPROC_QSPI_QUAD_MODE -+ bool "Quad mode" -+ help -+ Quad mode. -+ -+endchoice -+ -+config IPROC_QSPI_MULTI_LANE_ADDR -+ bool "Use multi lanes also for address" -+ depends on IPROC_QSPI_DUAL_MODE || IPROC_QSPI_QUAD_MODE -+ default y -+ help -+ Use multi lanes also for address. -+ -+config IPROC_QSPI_READ_CMD -+ hex "Flash opcode for multi I/O read" -+ depends on IPROC_QSPI_DUAL_MODE || IPROC_QSPI_QUAD_MODE -+ range 0x00 0xff -+ default 0xbb if IPROC_QSPI_DUAL_MODE -+ default 0xeb -+ help -+ Flash opcode to send to flash for multip I/O read. -+ -+config IPROC_QSPI_READ_DUMMY_CYCLES -+ int "Dummy cycles for multi I/O read operation" -+ depends on IPROC_QSPI_DUAL_MODE || IPROC_QSPI_QUAD_MODE -+ range 0 255 -+ default 8 if IPROC_QSPI_DUAL_MODE -+ default 10 -+ help -+ Dummy cycles for flash read operation -+ -+config IPROC_QSPI_MAX_HZ -+ int "Maximal SPI clock in HZ" -+ range 1 1000000000 -+ default 62500000 -+ help -+ The maximal SPI clock (in Hz) supported by the flash. -+ -+endif # SPI_XGS_IPROC -+ - # - # Add new SPI master controllers in alphabetical order above this line - # -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/spi/Makefile b/drivers/spi/Makefile ---- a/drivers/spi/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/spi/Makefile 2017-11-09 17:53:55.799375000 +0800 -@@ -93,3 +93,5 @@ obj-$(CONFIG_SPI_XILINX) += spi-xilinx. - obj-$(CONFIG_SPI_XLP) += spi-xlp.o - obj-$(CONFIG_SPI_XTENSA_XTFPGA) += spi-xtensa-xtfpga.o - obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o -+obj-$(CONFIG_SPI_XGS_IPROC) += spi-xgs-iproc.o -+ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/spi/spi-xgs-iproc.c b/drivers/spi/spi-xgs-iproc.c ---- a/drivers/spi/spi-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/spi/spi-xgs-iproc.c 2017-11-09 17:53:55.932382000 +0800 -@@ -0,0 +1,1982 @@ -+/* -+ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_OF -+#include -+#include -+#include -+#include -+#endif -+ -+#define DBG(...) /* */ -+ -+/* -+ * Interrupts -+ */ -+ -+#define QSPI_INTR_COUNT (7) -+ -+#define QSPI_INTR_MSPI_HALTED_MASK (0x00000040) -+#define QSPI_INTR_MSPI_DONE_MASK (0x00000020) -+#define QSPI_INTR_BSPI_LR_OVERREAD_MASK (0x00000010) -+#define QSPI_INTR_BSPI_LR_SESSION_DONE_MASK (0x00000008) -+#define QSPI_INTR_BSPI_LR_IMPATIENT_MASK (0x00000004) -+#define QSPI_INTR_BSPI_LR_SESSION_ABORTED_MASK (0x00000002) -+#define QSPI_INTR_BSPI_LR_FULLNESS_REACHED_MASK (0x00000001) -+ -+#define BSPI_LR_INTERRUPTS_DATA \ -+ (QSPI_INTR_BSPI_LR_SESSION_DONE_MASK | \ -+ QSPI_INTR_BSPI_LR_FULLNESS_REACHED_MASK) -+ -+#define BSPI_LR_INTERRUPTS_ERROR \ -+ (QSPI_INTR_BSPI_LR_OVERREAD_MASK | \ -+ QSPI_INTR_BSPI_LR_IMPATIENT_MASK | \ -+ QSPI_INTR_BSPI_LR_SESSION_ABORTED_MASK) -+ -+#define BSPI_LR_INTERRUPTS_ALL \ -+ (BSPI_LR_INTERRUPTS_ERROR | \ -+ BSPI_LR_INTERRUPTS_DATA) -+ -+#define SPBR_MIN 8U -+#define SPBR_MAX 255U -+#define DEFAULT_SPEED_HZ 25000000UL -+#define MSPI_REFCLK_SOURCE "c_clk125" /* To be doubled */ -+#define MSPI_REFCLK_SOURCE_DEVID "iproc_slow" -+ -+/* -+ * Flash opcode and parameters -+ */ -+#define OPCODE_RDID 0x9f -+#define OPCODE_WREN 0x06 -+#define OPCODE_WRDI 0x04 -+#define OPCODE_WRR 0x01 -+#define OPCODE_RCR 0x35 -+#define OPCODE_READ 0x03 -+#define OPCODE_RDSR 0x05 -+#define OPCODE_WRSR 0x01 -+#define OPCODE_RDFSR 0x70 -+#define OPCODE_FAST_READ 0x0B -+#define OPCODE_FAST_READ_4B 0x0C -+#define OPCODE_EN4B 0xB7 -+#define OPCODE_EX4B 0xE9 -+#define OPCODE_BRWR 0x17 -+ -+#define BSPI_WIDTH_1BIT 1 -+#define BSPI_WIDTH_2BIT 2 -+#define BSPI_WIDTH_4BIT 4 -+ -+#define BSPI_ADDRLEN_3BYTES 3 -+#define BSPI_ADDRLEN_4BYTES 4 -+ -+#define BSPI_FLASH_TYPE_SPANSION 0 -+#define BSPI_FLASH_TYPE_MACRONIX 1 -+#define BSPI_FLASH_TYPE_NUMONYX 2 -+#define BSPI_FLASH_TYPE_SST 3 -+#define BSPI_FLASH_TYPE_UNKNOWN -1 -+ -+/* -+ * Register masks/fields/values -+ */ -+#define QSPI_BSPI_RAF_STATUS_FIFO_EMPTY_MASK (0x00000002) -+#define QSPI_BSPI_RAF_CONTROL_START_MASK (0x00000001) -+#define QSPI_BSPI_RAF_CONTROL_CLEAR_MASK (0x00000002) -+#define QSPI_BSPI_BPP_ADDR_BPP_SELECT_MASK (0x00010000) -+#define QSPI_BSPI_BPP_MODE_BPP_MASK (0x00000100) -+#define QSPI_BSPI_FLEX_MODE_ENABLE_MASK (0x00000001) -+ -+ -+/* -+ * Module parameters -+ */ -+ -+/* Mulit I/O for read: 0 - single, 1 - dual, 2 - quad */ -+#ifdef CONFIG_IPROC_QSPI_SINGLE_MODE -+static int io_mode = 0; -+#else /* !CONFIG_IPROC_QSPI_SINGLE_MODE */ -+#ifdef CONFIG_IPROC_QSPI_DUAL_MODE -+static int io_mode = 1; -+#else /* !CONFIG_IPROC_QSPI_DUAL_MODE */ -+static int io_mode = 2; -+#endif /* !CONFIG_IPROC_QSPI_DUAL_MODE */ -+#endif /* !CONFIG_IPROC_QSPI_SINGLE_MODE */ -+module_param(io_mode, int, 0444); -+ -+/* Multi I/O for address (only if not in single mode) */ -+#ifdef CONFIG_IPROC_QSPI_MULTI_LANE_ADDR -+static int addr_multi = 1; -+#else /* !CONFIG_IPROC_QSPI_MULTI_LANE_ADDR */ -+static int addr_multi = 0; -+#endif /* !CONFIG_IPROC_QSPI_MULTI_LANE_ADDR */ -+module_param(addr_multi, int, 0444); -+ -+/* Read opcode (only if not in single mode) */ -+#ifdef CONFIG_IPROC_QSPI_SINGLE_MODE -+static int read_opcode = OPCODE_FAST_READ; -+#else /* !CONFIG_IPROC_QSPI_SINGLE_MODE */ -+static int read_opcode = CONFIG_IPROC_QSPI_READ_CMD; -+#endif /* !CONFIG_IPROC_QSPI_SINGLE_MODE */ -+module_param(read_opcode, int, 0444); -+ -+/* Dummy cycles for read (only if not in single mode) */ -+#ifdef CONFIG_IPROC_QSPI_SINGLE_MODE -+static int dummy_cycles = 8; -+#else /* !CONFIG_IPROC_QSPI_SINGLE_MODE */ -+static int dummy_cycles = CONFIG_IPROC_QSPI_READ_DUMMY_CYCLES; -+#endif /* !CONFIG_IPROC_QSPI_SINGLE_MODE */ -+module_param(dummy_cycles, int, 0444); -+ -+/* Max SPI clock HZ */ -+static int max_hz = 0; -+module_param(max_hz, int, 0444); -+ -+/* Spansion high performance mode */ -+static int bspi_hp; -+module_param(bspi_hp, int, 0444); -+ -+struct brcmspi_platform_data { -+ int flash_cs; -+}; -+ -+struct bcmspi_parms { -+ u32 speed_hz; -+ u8 chip_select; -+ u8 mode; -+ u8 bits_per_word; -+}; -+ -+struct position { -+ struct spi_message *msg; -+ struct spi_transfer *trans; -+ int byte; -+ int mspi_16bit; -+}; -+ -+#define NUM_TXRAM 32 -+#define NUM_RXRAM 32 -+#define NUM_CDRAM 16 -+ -+struct bcm_mspi_hw { -+ u32 spcr0_lsb; /* 0x000 */ -+ u32 spcr0_msb; /* 0x004 */ -+ u32 spcr1_lsb; /* 0x008 */ -+ u32 spcr1_msb; /* 0x00c */ -+ u32 newqp; /* 0x010 */ -+ u32 endqp; /* 0x014 */ -+ u32 spcr2; /* 0x018 */ -+ u32 reserved0; /* 0x01c */ -+ u32 mspi_status; /* 0x020 */ -+ u32 cptqp; /* 0x024 */ -+ u32 reserved1[6]; /* 0x028 */ -+ u32 txram[NUM_TXRAM]; /* 0x040 */ -+ u32 rxram[NUM_RXRAM]; /* 0x0c0 */ -+ u32 cdram[NUM_CDRAM]; /* 0x140 */ -+ u32 write_lock; /* 0x180 */ -+ u32 disable_flush_gen; /* 0x184 */ -+}; -+ -+struct bcm_bspi_hw { -+ u32 revision_id; /* 0x000 */ -+ u32 scratch; /* 0x004 */ -+ u32 mast_n_boot_ctrl; /* 0x008 */ -+ u32 busy_status; /* 0x00c */ -+ u32 intr_status; /* 0x010 */ -+ u32 b0_status; /* 0x014 */ -+ u32 b0_ctrl; /* 0x018 */ -+ u32 b1_status; /* 0x01c */ -+ u32 b1_ctrl; /* 0x020 */ -+ u32 strap_override_ctrl; /* 0x024 */ -+ u32 flex_mode_enable; /* 0x028 */ -+ u32 bits_per_cycle; /* 0x02C */ -+ u32 bits_per_phase; /* 0x030 */ -+ u32 cmd_and_mode_byte; /* 0x034 */ -+ u32 flash_upper_addr_byte; /* 0x038 */ -+ u32 xor_value; /* 0x03C */ -+ u32 xor_enable; /* 0x040 */ -+ u32 pio_mode_enable; /* 0x044 */ -+ u32 pio_iodir; /* 0x048 */ -+ u32 pio_data; /* 0x04C */ -+}; -+ -+struct bcm_bspi_raf { -+ u32 start_address; /* 0x00 */ -+ u32 num_words; /* 0x04 */ -+ u32 ctrl; /* 0x08 */ -+ u32 fullness; /* 0x0C */ -+ u32 watermark; /* 0x10 */ -+ u32 status; /* 0x14 */ -+ u32 read_data; /* 0x18 */ -+ u32 word_cnt; /* 0x1C */ -+ u32 curr_addr; /* 0x20 */ -+}; -+ -+struct bcm_idm_qspi_ctrl { -+ u32 io_ctrl_direct; -+}; -+ -+struct bcm_cru_control { -+ u32 cru_control; -+}; -+ -+struct bcm_flex_mode { -+ int width; -+ int addrlen; -+ int hp; -+}; -+ -+#define STATE_IDLE 0 -+#define STATE_RUNNING 1 -+#define STATE_SHUTDOWN 2 -+ -+struct bcmspi_priv { -+ struct platform_device *pdev; -+ struct spi_master *master; -+ spinlock_t lock; -+ struct bcmspi_parms last_parms; -+ struct position pos; -+ struct list_head msg_queue; -+ int state; -+ int outstanding_bytes; -+ int next_udelay; -+ int cs_change; -+ unsigned int mspi_refclk; -+ unsigned int max_speed_hz; -+ volatile struct bcm_mspi_hw *mspi_hw; -+ int irq; -+ struct tasklet_struct tasklet; -+ int curr_cs; -+ -+ /* BSPI */ -+ volatile struct bcm_bspi_hw *bspi_hw; -+ volatile struct bcm_cru_control *cru_hw; -+ int bspi_enabled; -+ /* all chip selects controlled by BSPI */ -+ int bspi_chip_select; -+ -+ /* LR */ -+ volatile struct bcm_bspi_raf *bspi_hw_raf; -+ struct spi_transfer *cur_xfer; -+ u32 cur_xfer_idx; -+ u32 cur_xfer_len; -+ u32 xfer_status; -+ struct spi_message *cur_msg; -+ u32 actual_length; -+ u32 raf_next_addr; -+ u32 raf_next_len; -+ -+ /* Interrupts */ -+ volatile u32 *qspi_intr; -+ volatile struct bcm_idm_qspi_ctrl *idm_qspi; -+ -+ /* current flex mode settings */ -+ struct bcm_flex_mode flex_mode; -+}; -+ -+static void bcmspi_enable_interrupt(struct bcmspi_priv *priv, u32 mask) -+{ -+ priv->idm_qspi->io_ctrl_direct |= cpu_to_le32(mask << 2); -+} -+ -+static void bcmspi_disable_interrupt(struct bcmspi_priv *priv, u32 mask) -+{ -+ priv->idm_qspi->io_ctrl_direct &= cpu_to_le32(~(mask << 2)); -+} -+ -+static void bcmspi_clear_interrupt(struct bcmspi_priv *priv, u32 mask) -+{ -+ int i; -+ -+ for(i=0; iqspi_intr[i] = cpu_to_le32(1); -+ } -+ } -+} -+ -+static u32 bcmspi_read_interrupt(struct bcmspi_priv *priv) -+{ -+ int i; -+ u32 status = 0; -+ -+ for(i=0; iqspi_intr[i] & cpu_to_le32(1)) { -+ status |= 1UL << i; -+ } -+ } -+ -+ return status; -+} -+ -+static void bcmspi_flush_prefetch_buffers(struct bcmspi_priv *priv) -+{ -+ priv->bspi_hw->b0_ctrl = 0; -+ priv->bspi_hw->b1_ctrl = 0; -+ priv->bspi_hw->b0_ctrl = cpu_to_le32(1); -+ priv->bspi_hw->b1_ctrl = cpu_to_le32(1); -+} -+ -+static int bcmspi_lr_is_fifo_empty(struct bcmspi_priv *priv) -+{ -+ return priv->bspi_hw_raf->status & cpu_to_le32(QSPI_BSPI_RAF_STATUS_FIFO_EMPTY_MASK); -+} -+ -+static inline u32 bcmspi_lr_read_fifo(struct bcmspi_priv *priv) -+{ -+ /* for performance reasons return the raw data, rather than -+ * byte-swapped data. This works because the caller writes -+ * values 32-bits at a time to the destination buffer, giving -+ * an automatic byte-swap on big-endian machines. */ -+ -+ return priv->bspi_hw_raf->read_data; -+} -+ -+static inline void bcmspi_lr_start(struct bcmspi_priv *priv) -+{ -+ priv->bspi_hw_raf->ctrl = cpu_to_le32(QSPI_BSPI_RAF_CONTROL_START_MASK); -+} -+ -+static inline void bcmspi_lr_clear(struct bcmspi_priv *priv) -+{ -+ priv->bspi_hw_raf->ctrl = cpu_to_le32(QSPI_BSPI_RAF_CONTROL_CLEAR_MASK); -+ bcmspi_flush_prefetch_buffers(priv); -+} -+ -+static inline int bcmspi_is_4_byte_mode(struct bcmspi_priv *priv) -+{ -+ return priv->flex_mode.addrlen == BSPI_ADDRLEN_4BYTES; -+} -+ -+static int bcmbspi_flash_type(struct bcmspi_priv *priv); -+ -+static int bcmspi_set_flex_mode(struct bcmspi_priv *priv, -+ int width, int addrlen, int hp) -+{ -+ int bpc = 0, bpp = dummy_cycles, command = read_opcode; -+ int flex_mode = 1, error = 0; -+ -+ switch (width) { -+ case BSPI_WIDTH_1BIT: -+ if (addrlen == BSPI_ADDRLEN_3BYTES) { -+ /* default mode, does not need flex_cmd */ -+ flex_mode = 0; -+ } else { -+ bpp = 8; /* dummy cycles */ -+ //if (bcmbspi_flash_type(priv) == BSPI_FLASH_TYPE_SPANSION) -+ // command = OPCODE_FAST_READ_4B; -+ //else -+ command = OPCODE_FAST_READ; -+ } -+ break; -+ case BSPI_WIDTH_2BIT: -+ bpc = 0x00000001; /* only data is 2-bit */ -+ if (addr_multi) { -+ bpc |= 0x00010000; -+ } -+ if (hp) { -+ bpc |= 0x00010100; /* address and mode are 2-bit too */ -+ bpp |= QSPI_BSPI_BPP_MODE_BPP_MASK; -+ } -+ break; -+ case BSPI_WIDTH_4BIT: -+ bpc = 0x00000002; /* only data is 4-bit */ -+ if (addr_multi) { -+ bpc |= 0x00020000; -+ } -+ if (hp) { -+ bpc |= 0x00020200; /* address and mode are 4-bit too */ -+ bpp |= QSPI_BSPI_BPP_MODE_BPP_MASK; -+ } -+ break; -+ default: -+ error = 1; -+ break; -+ } -+ -+ if (addrlen == BSPI_ADDRLEN_4BYTES) { -+ bpp |= QSPI_BSPI_BPP_ADDR_BPP_SELECT_MASK; -+ } -+ -+ if (!error) { -+ priv->bspi_hw->flex_mode_enable = 0; -+ priv->bspi_hw->bits_per_cycle = cpu_to_le32(bpc); -+ priv->bspi_hw->bits_per_phase = cpu_to_le32(bpp); -+ priv->bspi_hw->cmd_and_mode_byte = cpu_to_le32(command); -+ priv->bspi_hw->flex_mode_enable = flex_mode ? -+ cpu_to_le32(QSPI_BSPI_FLEX_MODE_ENABLE_MASK) -+ : 0; -+ DBG("%s: width=%d addrlen=%d hp=%d\n", -+ __func__, width, addrlen, hp); -+ DBG("%s: fme=%08x bpc=%08x bpp=%08x cmd=%08x\n", __func__, -+ le32_to_cpu(priv->bspi_hw->flex_mode_enable), -+ le32_to_cpu(priv->bspi_hw->bits_per_cycle), -+ le32_to_cpu(priv->bspi_hw->bits_per_phase), -+ le32_to_cpu(priv->bspi_hw->cmd_and_mode_byte)); -+ } -+ -+ return error; -+} -+ -+static void bcmspi_set_mode(struct bcmspi_priv *priv, -+ int width, int addrlen, int hp) -+{ -+ int error = 0; -+ int show_info = 0; -+ -+ if ((width != -1 && width != priv->flex_mode.width) || -+ (hp != -1 && hp != priv->flex_mode.hp)) { -+ /* Don't print things if only for address mode change because it -+ * could be very frequent. */ -+ show_info = 1; -+ } -+ if (width == -1) -+ width = priv->flex_mode.width; -+ if (addrlen == -1) -+ addrlen = priv->flex_mode.addrlen; -+ if (hp == -1) -+ hp = priv->flex_mode.hp; -+ -+ error = bcmspi_set_flex_mode(priv, width, addrlen, hp); -+ -+ if (!error) { -+ priv->flex_mode.width = width; -+ priv->flex_mode.addrlen = addrlen; -+ priv->flex_mode.hp = hp; -+ if (show_info) { -+ dev_info(&priv->pdev->dev, -+ "%d-lane output, %d-byte address%s\n", -+ priv->flex_mode.width, -+ priv->flex_mode.addrlen, -+ priv->flex_mode.hp ? ", high-performance mode" : ""); -+ } -+ } else -+ dev_warn(&priv->pdev->dev, -+ "INVALID COMBINATION: width=%d addrlen=%d hp=%d\n", -+ width, addrlen, hp); -+} -+ -+static void bcmspi_set_chip_select(struct bcmspi_priv *priv, int cs) -+{ -+ if (priv->curr_cs != cs) { -+ DBG("Switching CS%1d => CS%1d\n", -+ priv->curr_cs, cs); -+ -+ /* We don't have multiple chip selects for now */ -+ } -+ priv->curr_cs = cs; -+ -+} -+ -+static inline int is_bspi_chip_select(struct bcmspi_priv *priv, u8 cs) -+{ -+ return priv->bspi_chip_select & (1 << cs); -+} -+ -+static void bcmspi_disable_bspi(struct bcmspi_priv *priv) -+{ -+ int i; -+ -+ if (!priv->bspi_hw || !priv->bspi_enabled) -+ return; -+ if ((priv->bspi_hw->mast_n_boot_ctrl & cpu_to_le32(1)) == 1) { -+ priv->bspi_enabled = 0; -+ return; -+ } -+ -+ DBG("disabling bspi\n"); -+ for (i = 0; i < 1000; i++) { -+ if ((priv->bspi_hw->busy_status & cpu_to_le32(1)) == 0) { -+ priv->bspi_hw->mast_n_boot_ctrl = cpu_to_le32(1); -+ priv->bspi_enabled = 0; -+ udelay(1); -+ return; -+ } -+ udelay(1); -+ } -+ dev_warn(&priv->pdev->dev, "timeout setting MSPI mode\n"); -+} -+ -+static void bcmspi_enable_bspi(struct bcmspi_priv *priv) -+{ -+ if (!priv->bspi_hw || priv->bspi_enabled) -+ return; -+ if ((priv->bspi_hw->mast_n_boot_ctrl & cpu_to_le32(1)) == 0) { -+ priv->bspi_enabled = 1; -+ return; -+ } -+ -+ DBG("enabling bspi\n"); -+ priv->bspi_hw->mast_n_boot_ctrl = 0; -+ priv->bspi_enabled = 1; -+} -+ -+static void bcmspi_hw_set_parms(struct bcmspi_priv *priv, -+ const struct bcmspi_parms *xp) -+{ -+ if (xp->speed_hz) { -+ unsigned int spbr = priv->mspi_refclk / (2 * xp->speed_hz); -+ -+ priv->mspi_hw->spcr0_lsb = cpu_to_le32(max(min(spbr, SPBR_MAX), SPBR_MIN)); -+ } else { -+ priv->mspi_hw->spcr0_lsb = cpu_to_le32(SPBR_MIN); -+ } -+ -+ if (priv->pos.msg == NULL || xp->bits_per_word > 8) { -+ /* Global hw init for 16bit spi_transfer */ -+ int bits = xp->bits_per_word; -+ bits = bits? (bits == 16? 0 : bits) : 8; -+ priv->mspi_hw->spcr0_msb = cpu_to_le32(0x80 | /* Master */ -+ (bits << 2) | -+ (xp->mode & 3)); -+ } else { -+ /* Configure for a new 8-bit spi_transfer */ -+ if (priv->pos.byte == 0) { -+ /* Use 16-bit MSPI transfer for performance if applicable */ -+ if (priv->pos.mspi_16bit ^ (!(priv->pos.trans->len & 1))) { -+ /* Update it only if needed */ -+ priv->pos.mspi_16bit = !priv->pos.mspi_16bit; -+ priv->mspi_hw->spcr0_msb = cpu_to_le32(0x80 | /* Master */ -+ ((priv->pos.mspi_16bit? 0 : 8) << 2) | -+ (xp->mode & 3)); -+ } -+ } -+ } -+ priv->last_parms = *xp; -+} -+ -+#define PARMS_NO_OVERRIDE 0 -+#define PARMS_OVERRIDE 1 -+ -+static int bcmspi_update_parms(struct bcmspi_priv *priv, -+ struct spi_device *spidev, struct spi_transfer *trans, int override) -+{ -+ struct bcmspi_parms xp; -+ -+ xp.speed_hz = min(trans->speed_hz ? trans->speed_hz : -+ (spidev->max_speed_hz ? spidev->max_speed_hz : DEFAULT_SPEED_HZ), -+ DEFAULT_SPEED_HZ); -+ xp.chip_select = spidev->chip_select; -+ xp.mode = spidev->mode; -+ xp.bits_per_word = trans->bits_per_word ? trans->bits_per_word : -+ (spidev->bits_per_word ? spidev->bits_per_word : 8); -+ -+ if ((override == PARMS_OVERRIDE) || -+ ((xp.speed_hz == priv->last_parms.speed_hz) && -+ (xp.chip_select == priv->last_parms.chip_select) && -+ (xp.mode == priv->last_parms.mode) && -+ (xp.bits_per_word == priv->last_parms.bits_per_word))) { -+ bcmspi_hw_set_parms(priv, &xp); -+ return 0; -+ } -+ /* no override, and parms do not match */ -+ return 1; -+} -+ -+ -+static int bcmspi_setup(struct spi_device *spi) -+{ -+ struct bcmspi_parms *xp; -+ struct bcmspi_priv *priv = spi_master_get_devdata(spi->master); -+ unsigned int speed_hz; -+ -+ DBG("%s\n", __func__); -+ -+ if (spi->bits_per_word > 16) -+ return -EINVAL; -+ -+ /* Module parameter override */ -+ if (max_hz != 0) { -+ speed_hz = max_hz; -+ } else { -+ speed_hz = spi->max_speed_hz; -+ } -+ -+ xp = spi_get_ctldata(spi); -+ if (!xp) { -+ xp = kzalloc(sizeof(struct bcmspi_parms), GFP_KERNEL); -+ if (!xp) -+ return -ENOMEM; -+ spi_set_ctldata(spi, xp); -+ } -+ if (speed_hz < priv->max_speed_hz) -+ xp->speed_hz = speed_hz; -+ else -+ xp->speed_hz = 0; -+ -+ priv->cru_hw->cru_control &= cpu_to_le32(~0x00000006); -+ (void)priv->cru_hw->cru_control; /* Need to read back */ -+ if (speed_hz >= 62500000) { -+ priv->cru_hw->cru_control |= cpu_to_le32(0x00000006); -+ } else if (speed_hz >= 50000000) { -+ priv->cru_hw->cru_control |= cpu_to_le32(0x00000002); -+ } else if (speed_hz >= 31250000) { -+ priv->cru_hw->cru_control |= cpu_to_le32(0x00000004); -+ } -+ (void)priv->cru_hw->cru_control; /* Need to read back */ -+ -+ xp->chip_select = spi->chip_select; -+ xp->mode = spi->mode; -+ xp->bits_per_word = spi->bits_per_word ? spi->bits_per_word : 8; -+ -+ return 0; -+} -+ -+/* stop at end of transfer, no other reason */ -+#define FNB_BREAK_NONE 0 -+/* stop at end of spi_message */ -+#define FNB_BREAK_EOM 1 -+/* stop at end of spi_transfer if delay */ -+#define FNB_BREAK_DELAY 2 -+/* stop at end of spi_transfer if cs_change */ -+#define FNB_BREAK_CS_CHANGE 4 -+/* stop if we run out of bytes */ -+#define FNB_BREAK_NO_BYTES 8 -+/* stop at end of spi_transfer */ -+#define FNB_BREAK_EOT 16 -+ -+/* events that make us stop filling TX slots */ -+#define FNB_BREAK_TX (FNB_BREAK_EOM | FNB_BREAK_DELAY | \ -+ FNB_BREAK_CS_CHANGE) -+ -+/* events that make us deassert CS */ -+#define FNB_BREAK_DESELECT (FNB_BREAK_EOM | FNB_BREAK_CS_CHANGE) -+ -+ -+static int find_next_byte(struct bcmspi_priv *priv, struct position *p, -+ struct list_head *completed, int flags) -+{ -+ int ret = FNB_BREAK_NONE; -+ -+ p->byte++; -+ -+ while (p->byte >= p->trans->len) { -+ /* we're at the end of the spi_transfer */ -+ -+ /* in TX mode, need to pause for a delay or CS change */ -+ if (p->trans->delay_usecs && (flags & FNB_BREAK_DELAY)) -+ ret |= FNB_BREAK_DELAY; -+ if (p->trans->cs_change && (flags & FNB_BREAK_CS_CHANGE)) -+ ret |= FNB_BREAK_CS_CHANGE; -+ if (ret) -+ return ret; -+ -+ /* advance to next spi_message? */ -+ if (list_is_last(&p->trans->transfer_list, -+ &p->msg->transfers)) { -+ struct spi_message *next_msg = NULL; -+ -+ /* TX breaks at the end of each message as well */ -+ if (!completed || (flags & FNB_BREAK_EOM)) { -+ DBG("find_next_byte: advance msg exit\n"); -+ return FNB_BREAK_EOM; -+ } -+ if (!list_is_last(&p->msg->queue, &priv->msg_queue)) { -+ next_msg = list_entry(p->msg->queue.next, -+ struct spi_message, queue); -+ } -+ /* delete from run queue, add to completion queue */ -+ list_del(&p->msg->queue); -+ list_add_tail(&p->msg->queue, completed); -+ -+ p->msg = next_msg; -+ p->byte = 0; -+ if (p->msg == NULL) { -+ p->trans = NULL; -+ ret = FNB_BREAK_NO_BYTES; -+ break; -+ } -+ -+ /* -+ * move on to the first spi_transfer of the new -+ * spi_message -+ */ -+ p->trans = list_entry(p->msg->transfers.next, -+ struct spi_transfer, transfer_list); -+ } else { -+ /* or just advance to the next spi_transfer */ -+ p->trans = list_entry(p->trans->transfer_list.next, -+ struct spi_transfer, transfer_list); -+ p->byte = 0; -+ -+ /* Separate spi_transfers into MSPI transfers */ -+ ret = FNB_BREAK_EOT; -+ } -+ } -+ DBG("find_next_byte: msg %p trans %p len %d byte %d ret %x\n", -+ p->msg, p->trans, p->trans ? p->trans->len : 0, p->byte, ret); -+ return ret; -+} -+ -+static void read_from_hw(struct bcmspi_priv *priv, struct list_head *completed) -+{ -+ struct position p; -+ int slot = 0, n = priv->outstanding_bytes; -+ -+ DBG("%s\n", __func__); -+ -+ p = priv->pos; -+ -+ while (n > 0) { -+ BUG_ON(p.msg == NULL); -+ -+ if (p.trans->bits_per_word <= 8) { -+ u8 *buf = p.trans->rx_buf; -+ -+ if (buf) { -+ -+ if (p.mspi_16bit) { -+ /* Using 16-bit SPI transfers for performance */ -+ buf[p.byte] = -+ le32_to_cpu(priv->mspi_hw->rxram[(slot << 1) + 0]) & 0xff; -+ DBG("RD %02x\n", buf ? buf[p.byte] : 0xff); -+ buf[p.byte + 1] = -+ le32_to_cpu(priv->mspi_hw->rxram[(slot << 1) + 1]) & 0xff; -+ DBG("RD %02x\n", buf ? buf[p.byte + 1] : 0xff); -+ } else { -+ buf[p.byte] = -+ le32_to_cpu(priv->mspi_hw->rxram[(slot << 1) + 1]) & 0xff; -+ DBG("RD %02x\n", buf ? buf[p.byte] : 0xff); -+ } -+ } -+ } else { -+ u16 *buf = p.trans->rx_buf; -+ -+ if (buf) { -+ buf[p.byte] = -+ ((le32_to_cpu(priv->mspi_hw->rxram[(slot << 1) + 1]) & 0xff) << 0) | -+ ((le32_to_cpu(priv->mspi_hw->rxram[(slot << 1) + 0] & 0xff)) << 8); -+ DBG("RD %04x\n", buf ? buf[p.byte] : 0xffff); -+ } -+ } -+ slot++; -+ n--; -+ p.msg->actual_length++; -+ if (p.mspi_16bit) { -+ p.byte++; -+ p.msg->actual_length++; -+ } -+ -+ find_next_byte(priv, &p, completed, FNB_BREAK_NONE); -+ } -+ -+ priv->pos = p; -+ priv->outstanding_bytes = 0; -+} -+ -+static void write_to_hw(struct bcmspi_priv *priv) -+{ -+ struct position p; -+ int slot = 0, fnb = 0; -+ struct spi_message *msg = NULL; -+ -+ DBG("%s\n", __func__); -+ -+ bcmspi_disable_bspi(priv); -+ -+ p = priv->pos; -+ -+ while (1) { -+ if (p.msg == NULL) -+ break; -+ if (!msg) { -+ msg = p.msg; -+ bcmspi_update_parms(priv, msg->spi, p.trans, -+ PARMS_OVERRIDE); -+ } else { -+ /* break if the speed, bits, etc. changed */ -+ if (bcmspi_update_parms(priv, msg->spi, p.trans, -+ PARMS_NO_OVERRIDE)) { -+ DBG("parms don't match, breaking\n"); -+ break; -+ } -+ } -+ if (p.trans->bits_per_word <= 8) { -+ const u8 *buf = p.trans->tx_buf; -+ -+ priv->mspi_hw->txram[slot << 1] = -+ cpu_to_le32(buf ? (buf[p.byte] & 0xff) : 0xff); -+ DBG("WR %02x\n", buf ? buf[p.byte] : 0xff); -+ -+ if (priv->pos.mspi_16bit) { -+ /* Using 16-bit SPI transfers for performance */ -+ p.byte++; -+ priv->mspi_hw->txram[(slot << 1) + 1] = -+ cpu_to_le32(buf ? (buf[p.byte] & 0xff) : 0xff); -+ DBG("WR %02x\n", buf ? buf[p.byte] : 0xff); -+ priv->mspi_hw->cdram[slot] = cpu_to_le32(0xce); -+ } else { -+ priv->mspi_hw->cdram[slot] = cpu_to_le32(0x8e); -+ } -+ -+ } else { -+ const u16 *buf = p.trans->tx_buf; -+ -+ priv->mspi_hw->txram[(slot << 1) + 0] = -+ cpu_to_le32(buf ? (buf[p.byte] >> 8) : 0xff); -+ priv->mspi_hw->txram[(slot << 1) + 1] = -+ cpu_to_le32(buf ? (buf[p.byte] & 0xff) : 0xff); -+ DBG("WR %04x\n", buf ? buf[p.byte] : 0xffff); -+ priv->mspi_hw->cdram[slot] = cpu_to_le32(0xce); -+ } -+ slot++; -+ -+ fnb = find_next_byte(priv, &p, NULL, FNB_BREAK_TX); -+ -+ if (fnb & FNB_BREAK_CS_CHANGE) -+ priv->cs_change = 1; -+ if (fnb & FNB_BREAK_DELAY) -+ priv->next_udelay = p.trans->delay_usecs; -+ if (fnb || (slot == NUM_CDRAM)) -+ break; -+ } -+ -+ if (slot) { -+ DBG("submitting %d slots\n", slot); -+ priv->mspi_hw->newqp = 0; -+ priv->mspi_hw->endqp = cpu_to_le32(slot - 1); -+ -+ /* deassert CS on the final byte */ -+ if (fnb & FNB_BREAK_DESELECT) -+ priv->mspi_hw->cdram[slot - 1] &= cpu_to_le32(~0x80); -+ -+ /* tell HIF_MSPI which CS to use */ -+ bcmspi_set_chip_select(priv, msg->spi->chip_select); -+ -+ priv->mspi_hw->write_lock = cpu_to_le32(1); -+ priv->mspi_hw->spcr2 = cpu_to_le32(0xe0); /* cont | spe | spifie */ -+ -+ priv->state = STATE_RUNNING; -+ priv->outstanding_bytes = slot; -+ } else { -+ priv->mspi_hw->write_lock = 0; -+ priv->state = STATE_IDLE; -+ } -+} -+ -+#define DWORD_ALIGNED(a) (!(((unsigned long)(a)) & 3)) -+#define ACROSS_16MB(a, l) (((a) ^ ((a) + (l) - 1)) & 0xFF000000) -+ -+static int bcmspi_emulate_flash_read(struct bcmspi_priv *priv, -+ struct spi_message *msg) -+{ -+ u32 addr, len; -+ int idx = 0; /* Also used for checking continuation */ -+ unsigned long flags = 0; -+ -+ /* Check if it's a continuation */ -+ if (priv->raf_next_len != 0) { -+ -+ /* Continuation (read across 16MB boundary) */ -+ addr = priv->raf_next_addr; -+ len = priv->raf_next_len; -+ -+ /* Update upper address byte */ -+ if (bcmspi_is_4_byte_mode(priv)) { -+ priv->bspi_hw->flash_upper_addr_byte = cpu_to_le32(addr & 0xFF000000); -+ /* Flush prefecth buffers since upper byte changed */ -+ bcmspi_flush_prefetch_buffers(priv); -+ } -+ -+ } else { -+ -+ /* It's the first session of this transfer */ -+ struct spi_transfer *trans; -+ u8 *buf; -+ -+ /* acquire lock when the MSPI is idle */ -+ while (1) { -+ spin_lock_irqsave(&priv->lock, flags); -+ if (priv->state == STATE_IDLE) -+ break; -+ spin_unlock_irqrestore(&priv->lock, flags); -+ if (priv->state == STATE_SHUTDOWN) -+ return -EIO; -+ udelay(1); -+ } -+ bcmspi_set_chip_select(priv, msg->spi->chip_select); -+ -+ /* first transfer - OPCODE_READ + 3-byte address */ -+ trans = list_entry(msg->transfers.next, struct spi_transfer, -+ transfer_list); -+ buf = (void *)trans->tx_buf; -+ -+ idx = 1; -+ -+ /* Check upper address byte for 4-byte mode */ -+ if (bcmspi_is_4_byte_mode(priv)) { -+ addr = buf[idx++] << 24; -+ } else { -+ addr = 0; -+ } -+ -+ /* -+ * addr coming into this function is a raw flash offset -+ * we need to convert it to the BSPI address -+ */ -+ addr |= (buf[idx] << 16) | (buf[idx+1] << 8) | buf[idx+2]; -+ -+ /* second transfer - read result into buffer */ -+ trans = list_entry(msg->transfers.next->next, struct spi_transfer, -+ transfer_list); -+ -+ buf = (void *)trans->rx_buf; -+ -+ len = trans->len; -+ -+ /* non-aligned and very short transfers are handled by MSPI */ -+ if (unlikely(!DWORD_ALIGNED(addr) || -+ !DWORD_ALIGNED(buf) || -+ len < sizeof(u32) || -+ !priv->bspi_hw_raf)) { -+ spin_unlock_irqrestore(&priv->lock, flags); -+ return -1; -+ } -+ -+ /* Flush prefetch buffers only if upper address byte changed */ -+ if ((addr & 0xFF000000) != le32_to_cpu(priv->bspi_hw->flash_upper_addr_byte)) { -+ bcmspi_flush_prefetch_buffers(priv); -+ /* Update upper address byte */ -+ priv->bspi_hw->flash_upper_addr_byte = cpu_to_le32(addr & 0xFF000000); -+ } -+ -+ /* Switching to BSPI */ -+ bcmspi_enable_bspi(priv); -+ -+ DBG("%s: dst %p src %p len %x addr BSPI %06x\n", -+ __func__, buf, addr, len, addr); -+ -+ /* initialize software parameters */ -+ priv->xfer_status = 0; -+ priv->cur_xfer = trans; -+ priv->cur_xfer_idx = 0; -+ priv->cur_msg = msg; -+ priv->actual_length = idx + 4 + trans->len; -+ } -+ -+ if (bcmspi_is_4_byte_mode(priv) && ACROSS_16MB(addr, len)) { -+ -+ /* Size for the first session */ -+ u32 bytes = 0x1000000 - (addr & 0x00FFFFFF); -+ -+ /* Address and size for remaining sessions */ -+ priv->raf_next_addr = addr + bytes; -+ priv->raf_next_len = len - bytes; -+ -+ len = bytes; -+ -+ } else { -+ priv->raf_next_len = 0; -+ } -+ -+ /* Length for this session */ -+ priv->cur_xfer_len = len; -+ -+ /* setup hardware */ -+ /* address must be 4-byte aligned */ -+ priv->bspi_hw_raf->start_address = cpu_to_le32(addr & 0x00FFFFFF); -+ priv->bspi_hw_raf->num_words = cpu_to_le32((len + 3) >> 2); -+ priv->bspi_hw_raf->watermark = 0; -+ -+ DBG("READ: %08x %08x (%08x)\n", addr, ((len + 3) >> 2), len); -+ -+ bcmspi_clear_interrupt(priv, 0xffffffff); -+ bcmspi_enable_interrupt(priv, BSPI_LR_INTERRUPTS_ALL); -+ bcmspi_lr_start(priv); -+ -+ if (idx) { -+ spin_unlock_irqrestore(&priv->lock, flags); -+ } -+ -+ return 0; -+} -+ -+/* -+ * m25p80_read() calls wait_till_ready() before each read to check -+ * the flash status register for pending writes. -+ * -+ * This can be safely skipped if our last transaction was just an -+ * emulated BSPI read. -+ */ -+static int bcmspi_emulate_flash_rdsr(struct bcmspi_priv *priv, -+ struct spi_message *msg) -+{ -+ u8 *buf; -+ struct spi_transfer *trans; -+ -+ if (priv->bspi_enabled == 0) -+ return 1; -+ -+ trans = list_entry(msg->transfers.next->next, struct spi_transfer, -+ transfer_list); -+ -+ buf = (void *)trans->rx_buf; -+ *buf = 0x00; -+ -+ msg->actual_length = 2; -+ msg->status = 0; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) -+ spi_finalize_current_message(priv->master); -+#else -+ msg->complete(msg->context); -+#endif -+ -+ return 0; -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) -+static int bcmspi_prepare_transfer(struct spi_master *master) -+{ -+ return 0; -+} -+ -+static int bcmspi_unprepare_transfer(struct spi_master *master) -+{ -+ return 0; -+} -+#endif -+ -+static int bcmspi_transfer_one(struct spi_master *master, struct spi_message *msg) -+{ -+ struct bcmspi_priv *priv = spi_master_get_devdata(master); -+ unsigned long flags; -+ -+ DBG("%s\n", __func__); -+ -+ if (is_bspi_chip_select(priv, msg->spi->chip_select)) { -+ struct spi_transfer *trans; -+ -+ trans = list_entry(msg->transfers.next, -+ struct spi_transfer, transfer_list); -+ if (trans && trans->len && trans->tx_buf) { -+ u8 command = ((u8 *)trans->tx_buf)[0]; -+ switch (command) { -+ case OPCODE_FAST_READ: -+ if (bcmspi_emulate_flash_read(priv, msg) == 0) -+ return 0; -+ break; -+ case OPCODE_RDSR: -+ if (bcmspi_emulate_flash_rdsr(priv, msg) == 0) -+ return 0; -+ break; -+ case OPCODE_EN4B: -+ DBG("ENABLE 4-BYTE MODE\n"); -+ bcmspi_set_mode(priv, -1, BSPI_ADDRLEN_4BYTES, -1); -+ break; -+ case OPCODE_EX4B: -+ DBG("DISABLE 4-BYTE MODE\n"); -+ bcmspi_set_mode(priv, -1, BSPI_ADDRLEN_3BYTES, -1); -+ break; -+ case OPCODE_BRWR: -+ { -+ u8 enable = ((u8 *)trans->tx_buf)[1]; -+ DBG("%s 4-BYTE MODE\n", enable ? "ENABLE" : "DISABLE"); -+ bcmspi_set_mode(priv, -1, -+ enable ? BSPI_ADDRLEN_4BYTES : -+ BSPI_ADDRLEN_3BYTES, -1); -+ } -+ break; -+ default: -+ break; -+ } -+ -+ /* Mark prefetch buffers dirty (by using upper byte) if needed */ -+ switch(command) { -+ case OPCODE_RDID: -+ case OPCODE_WREN: -+ case OPCODE_WRDI: -+ case OPCODE_RCR: -+ case OPCODE_READ: -+ case OPCODE_RDSR: -+ case OPCODE_WRSR: -+ case OPCODE_RDFSR: -+ case OPCODE_FAST_READ: -+ case OPCODE_FAST_READ_4B: -+ case OPCODE_EN4B: -+ case OPCODE_EX4B: -+ case OPCODE_BRWR: -+ /* These are known opcodes that are not writing/erasing */ -+ break; -+ default: -+ /* Could be writing/erasing; mark buffers dirty */ -+ priv->bspi_hw->flash_upper_addr_byte = cpu_to_le32(0xff000000); -+ break; -+ } -+ } -+ } -+ -+ spin_lock_irqsave(&priv->lock, flags); -+ -+ if (priv->state == STATE_SHUTDOWN) { -+ spin_unlock_irqrestore(&priv->lock, flags); -+ return -EIO; -+ } -+ -+ msg->actual_length = 0; -+ -+ list_add_tail(&msg->queue, &priv->msg_queue); -+ -+ if (priv->state == STATE_IDLE) { -+ BUG_ON(priv->pos.msg != NULL); -+ priv->pos.msg = msg; -+ priv->pos.trans = list_entry(msg->transfers.next, -+ struct spi_transfer, transfer_list); -+ priv->pos.byte = 0; -+ -+ write_to_hw(priv); -+ } -+ spin_unlock_irqrestore(&priv->lock, flags); -+ -+ return 0; -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) -+static int bcmspi_transfer(struct spi_device *spi, struct spi_message *msg) -+{ -+ return bcmspi_transfer_one(spi->master, msg); -+} -+#endif -+ -+static void bcmspi_cleanup(struct spi_device *spi) -+{ -+ struct bcmspi_parms *xp = spi_get_ctldata(spi); -+ -+ DBG("%s\n", __func__); -+ -+ kfree(xp); -+} -+ -+static irqreturn_t bcmspi_interrupt(int irq, void *dev_id) -+{ -+ struct bcmspi_priv *priv = dev_id; -+ -+ if (priv->bspi_enabled && priv->cur_xfer) { -+ int done = 0; -+ u32 status = bcmspi_read_interrupt(priv); -+ u32 *buf = (u32 *)priv->cur_xfer->rx_buf; -+ if (status & BSPI_LR_INTERRUPTS_DATA) { -+ while (!bcmspi_lr_is_fifo_empty(priv)) { -+ u32 data = bcmspi_lr_read_fifo(priv); -+ if (likely(priv->cur_xfer_len >= 4)) { -+ buf[priv->cur_xfer_idx++] = data; -+ priv->cur_xfer_len -= 4; -+ } else { -+ /* -+ * Read out remaining bytes, make sure -+ * we do not cross the buffer boundary -+ */ -+ u8 *cbuf = -+ (u8 *)&buf[priv->cur_xfer_idx]; -+ data = cpu_to_le32(data); -+ while (priv->cur_xfer_len) { -+ *cbuf++ = (u8)data; -+ data >>= 8; -+ priv->cur_xfer_len--; -+ } -+ } -+ } -+ } -+ if (status & BSPI_LR_INTERRUPTS_ERROR) { -+ dev_err(&priv->pdev->dev, "ERROR %02x\n", status); -+ priv->xfer_status = -EIO; -+ } else if ((status & QSPI_INTR_BSPI_LR_SESSION_DONE_MASK) && -+ priv->cur_xfer_len == 0) { -+ -+ if (priv->raf_next_len) { -+ -+ /* Continuation for reading across 16MB boundary */ -+ bcmspi_disable_interrupt(priv, BSPI_LR_INTERRUPTS_ALL); -+ bcmspi_emulate_flash_read(priv, NULL); -+ return IRQ_HANDLED; -+ -+ } else { -+ done = 1; -+ } -+ } -+ -+ if (done) { -+ priv->cur_xfer = NULL; -+ bcmspi_disable_interrupt(priv, BSPI_LR_INTERRUPTS_ALL); -+ -+ if (priv->xfer_status) { -+ bcmspi_lr_clear(priv); -+ } else { -+ if (priv->cur_msg) { -+ priv->cur_msg->actual_length = priv->actual_length; -+ priv->cur_msg->status = 0; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) -+ spi_finalize_current_message(priv->master); -+#else -+ priv->cur_msg->complete(priv->cur_msg->context); -+#endif -+ } -+ } -+ priv->cur_msg = NULL; -+ } -+ bcmspi_clear_interrupt(priv, status); -+ return IRQ_HANDLED; -+ } -+ -+ if (priv->mspi_hw->mspi_status & cpu_to_le32(1)) { -+ /* clear interrupt */ -+ priv->mspi_hw->mspi_status &= cpu_to_le32(~1); -+ bcmspi_clear_interrupt(priv, QSPI_INTR_MSPI_DONE_MASK); -+ -+ tasklet_schedule(&priv->tasklet); -+ return IRQ_HANDLED; -+ } else -+ return IRQ_NONE; -+} -+ -+static void bcmspi_complete(void *arg) -+{ -+ complete(arg); -+} -+ -+static void bcmspi_tasklet(unsigned long param) -+{ -+ struct bcmspi_priv *priv = (void *)param; -+ struct list_head completed; -+ struct spi_message *msg; -+ unsigned long flags; -+ -+ INIT_LIST_HEAD(&completed); -+ spin_lock_irqsave(&priv->lock, flags); -+ -+ if (priv->next_udelay) { -+ udelay(priv->next_udelay); -+ priv->next_udelay = 0; -+ } -+ -+ msg = priv->pos.msg; -+ -+ read_from_hw(priv, &completed); -+ if (priv->cs_change) { -+ udelay(10); -+ priv->cs_change = 0; -+ } -+ -+ write_to_hw(priv); -+ spin_unlock_irqrestore(&priv->lock, flags); -+ -+ while (!list_empty(&completed)) { -+ msg = list_first_entry(&completed, struct spi_message, queue); -+ list_del(&msg->queue); -+ msg->status = 0; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) -+ if (msg->complete == bcmspi_complete) -+ msg->complete(msg->context); -+ else -+ spi_finalize_current_message(priv->master); -+#else -+ if (msg->complete) -+ msg->complete(msg->context); -+#endif -+ -+ } -+} -+ -+static struct spi_master *default_master; -+ -+static int bcmspi_simple_transaction(struct bcmspi_parms *xp, -+ const void *tx_buf, int tx_len, void *rx_buf, int rx_len) -+{ -+ DECLARE_COMPLETION_ONSTACK(fini); -+ struct spi_message m; -+ struct spi_transfer t_tx, t_rx; -+ struct spi_device spi; -+ int ret; -+ -+ memset(&spi, 0, sizeof(spi)); -+ spi.max_speed_hz = xp->speed_hz; -+ spi.chip_select = xp->chip_select; -+ spi.mode = xp->mode; -+ spi.bits_per_word = xp->bits_per_word; -+ spi.master = default_master; -+ -+ spi_message_init(&m); -+ m.complete = bcmspi_complete; -+ m.context = &fini; -+ m.spi = &spi; -+ -+ memset(&t_tx, 0, sizeof(t_tx)); -+ memset(&t_rx, 0, sizeof(t_rx)); -+ t_tx.tx_buf = tx_buf; -+ t_tx.len = tx_len; -+ t_rx.rx_buf = rx_buf; -+ t_rx.len = rx_len; -+ -+ if (tx_len) -+ spi_message_add_tail(&t_tx, &m); -+ if (rx_len) -+ spi_message_add_tail(&t_rx, &m); -+ -+ ret = bcmspi_transfer_one(default_master, &m); -+ if (!ret) -+ wait_for_completion(&fini); -+ return ret; -+} -+ -+static void bcmspi_hw_init(struct bcmspi_priv *priv) -+{ -+ const struct bcmspi_parms bcmspi_default_parms_cs0 = { -+ .speed_hz = DEFAULT_SPEED_HZ, -+ .chip_select = 0, -+ .mode = SPI_MODE_3, -+ .bits_per_word = 8, -+ }; -+ -+ priv->mspi_hw->spcr1_lsb = 0; -+ priv->mspi_hw->spcr1_msb = 0; -+ priv->mspi_hw->newqp = 0; -+ priv->mspi_hw->endqp = 0; -+ priv->mspi_hw->spcr2 = cpu_to_le32(0x20); /* spifie */ -+ -+ bcmspi_hw_set_parms(priv, &bcmspi_default_parms_cs0); -+ -+ priv->bspi_enabled = 1; -+ bcmspi_disable_bspi(priv); -+} -+ -+static void bcmspi_hw_uninit(struct bcmspi_priv *priv) -+{ -+ priv->mspi_hw->spcr2 = 0x0; /* disable irq and enable bits */ -+ bcmspi_enable_bspi(priv); -+} -+ -+static int bcmbspi_flash_type(struct bcmspi_priv *priv) -+{ -+ char tx_buf[4]; -+ unsigned char jedec_id[5] = {0}; -+ int bspi_flash; -+ -+ /* Read ID */ -+ tx_buf[0] = OPCODE_RDID; -+ bcmspi_simple_transaction(&priv->last_parms, tx_buf, 1, &jedec_id, 5); -+ -+ switch (jedec_id[0]) { -+ case 0x01: /* Spansion */ -+ case 0xef: -+ bspi_flash = BSPI_FLASH_TYPE_SPANSION; -+ break; -+ case 0xc2: /* Macronix */ -+ bspi_flash = BSPI_FLASH_TYPE_MACRONIX; -+ break; -+ case 0xbf: /* SST */ -+ bspi_flash = BSPI_FLASH_TYPE_SST; -+ break; -+ case 0x89: /* Numonyx */ -+ bspi_flash = BSPI_FLASH_TYPE_NUMONYX; -+ break; -+ default: -+ bspi_flash = BSPI_FLASH_TYPE_UNKNOWN; -+ break; -+ } -+ return bspi_flash; -+} -+ -+static int bcmspi_set_quad_mode(struct bcmspi_priv *priv, int _enable) -+{ -+ char tx_buf[4]; -+ unsigned char cfg_reg, sts_reg; -+ -+ switch (bcmbspi_flash_type(priv)) { -+ case BSPI_FLASH_TYPE_SPANSION: -+ /* RCR */ -+ tx_buf[0] = OPCODE_RCR; -+ bcmspi_simple_transaction(&priv->last_parms, -+ tx_buf, 1, &cfg_reg, 1); -+ if (_enable) -+ cfg_reg |= 0x2; -+ else -+ cfg_reg &= ~0x2; -+ /* WREN */ -+ tx_buf[0] = OPCODE_WREN; -+ bcmspi_simple_transaction(&priv->last_parms, -+ tx_buf, 1, NULL, 0); -+ /* WRR */ -+ tx_buf[0] = OPCODE_WRR; -+ tx_buf[1] = 0; /* status register */ -+ tx_buf[2] = cfg_reg; /* configuration register */ -+ bcmspi_simple_transaction(&priv->last_parms, -+ tx_buf, 3, NULL, 0); -+ /* wait till ready */ -+ do { -+ tx_buf[0] = OPCODE_RDSR; -+ bcmspi_simple_transaction(&priv->last_parms, -+ tx_buf, 1, &sts_reg, 1); -+ udelay(1); -+ } while (sts_reg & 1); -+ break; -+ case BSPI_FLASH_TYPE_MACRONIX: -+ /* RDSR */ -+ tx_buf[0] = OPCODE_RDSR; -+ bcmspi_simple_transaction(&priv->last_parms, -+ tx_buf, 1, &cfg_reg, 1); -+ if (_enable) -+ cfg_reg |= 0x40; -+ else -+ cfg_reg &= ~0x40; -+ /* WREN */ -+ tx_buf[0] = OPCODE_WREN; -+ bcmspi_simple_transaction(&priv->last_parms, -+ tx_buf, 1, NULL, 0); -+ /* WRSR */ -+ tx_buf[0] = OPCODE_WRSR; -+ tx_buf[1] = cfg_reg; /* status register */ -+ bcmspi_simple_transaction(&priv->last_parms, -+ tx_buf, 2, NULL, 0); -+ /* wait till ready */ -+ do { -+ tx_buf[0] = OPCODE_RDSR; -+ bcmspi_simple_transaction(&priv->last_parms, -+ tx_buf, 1, &sts_reg, 1); -+ udelay(1); -+ } while (sts_reg & 1); -+ /* RDSR */ -+ tx_buf[0] = OPCODE_RDSR; -+ bcmspi_simple_transaction(&priv->last_parms, -+ tx_buf, 1, &cfg_reg, 1); -+ break; -+ case BSPI_FLASH_TYPE_SST: -+ case BSPI_FLASH_TYPE_NUMONYX: -+ /* TODO - send Quad mode control command */ -+ break; -+ default: -+ return _enable ? -1 : 0; -+ } -+ -+ return 0; -+} -+ -+static int bcmspi_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct brcmspi_platform_data *pdata; -+ struct bcmspi_priv *priv; -+ struct spi_master *master; -+ struct resource *res; -+ struct clk *clk; -+ int ret; -+ u32 irq; -+#ifdef CONFIG_OF -+ struct device_node *dn = pdev->dev.of_node; -+ u32 qspi_bus_id; -+ u32 qspi_cs; -+ int i, irqs_total; -+#endif -+ -+ DBG("bcmspi_probe\n"); -+ -+ pdata = (struct brcmspi_platform_data *)pdev->dev.platform_data; -+ -+ master = spi_alloc_master(dev, sizeof(struct bcmspi_priv)); -+ if (!master) { -+ dev_err(&pdev->dev, "error allocating spi_master\n"); -+ return -ENOMEM; -+ } -+ -+ priv = spi_master_get_devdata(master); -+ -+ priv->pdev = pdev; -+ priv->state = STATE_IDLE; -+ priv->pos.msg = NULL; -+ priv->pos.mspi_16bit = 0; -+ priv->master = master; -+ priv->raf_next_len = 0; -+ -+#ifndef CONFIG_OF -+ master->bus_num = pdev->id; -+#else -+ if (of_property_read_u32(dn, "#bus-id", &qspi_bus_id)) { -+ dev_warn(&pdev->dev, -+ "missing #bus-id property (default to 1)\n"); -+ qspi_bus_id = 1; -+ } -+ master->bus_num = qspi_bus_id; -+ pdev->id = qspi_bus_id; -+#endif -+ master->num_chipselect = 1; -+ master->mode_bits = SPI_MODE_3; -+ -+ master->setup = bcmspi_setup; -+ master->cleanup = bcmspi_cleanup; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) -+ master->prepare_transfer_hardware = bcmspi_prepare_transfer; -+ master->unprepare_transfer_hardware = bcmspi_unprepare_transfer; -+ master->transfer_one_message = bcmspi_transfer_one; -+ master->transfer = NULL; -+#else -+ master->transfer = bcmspi_transfer; -+#endif -+/* needed for supporting child SPI devices*/ -+#ifdef CONFIG_OF -+ master->dev.of_node = pdev->dev.of_node; -+#endif -+ -+ priv->mspi_hw = NULL; -+ priv->bspi_hw = NULL; -+ priv->bspi_hw_raf = NULL; -+ priv->qspi_intr = NULL; -+ priv->idm_qspi = NULL; -+ priv->irq = -1; -+ -+ /* Get MSPI reference clock and max speed hz */ -+#ifndef CONFIG_OF -+ clk = clk_get_sys(MSPI_REFCLK_SOURCE_DEVID, MSPI_REFCLK_SOURCE); -+#else -+ clk = of_clk_get (dn, 0); -+#endif /* CONFIG_OF */ -+ if (!clk) { -+ dev_err(&pdev->dev, "can't get reference clock frequency by %s\n", -+ MSPI_REFCLK_SOURCE); -+ ret = -EIO; -+ goto err2; -+ } -+ priv->mspi_refclk = (unsigned int)clk_get_rate(clk) * 2; -+ priv->max_speed_hz = priv->mspi_refclk / (2 * SPBR_MIN); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "can't get resource 0\n"); -+ ret = -EIO; -+ goto err2; -+ } -+ /* MSPI register range */ -+ priv->mspi_hw = (volatile void *)ioremap(res->start, -+ res->end - res->start); -+ if (!priv->mspi_hw) { -+ dev_err(&pdev->dev, "can't ioremap\n"); -+ ret = -EIO; -+ goto err2; -+ } -+ DBG("priv->mspi_hw=%p\n", priv->mspi_hw); -+ -+ /* BSPI register range */ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ if (res) { -+ priv->bspi_hw = (volatile void *)ioremap(res->start, -+ res->end - res->start); -+ if (!priv->bspi_hw) { -+ dev_err(&pdev->dev, "can't ioremap BSPI range\n"); -+ ret = -EIO; -+ goto err2; -+ } -+ } else -+ priv->bspi_hw = NULL; -+ DBG("priv->bspi_hw=%p\n", priv->bspi_hw); -+ -+ /* BSPI_RAF register range */ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); -+ if (res) { -+ priv->bspi_hw_raf = (volatile void *)ioremap(res->start, -+ res->end - res->start); -+ if (!priv->bspi_hw_raf) { -+ dev_err(&pdev->dev, "can't ioremap BSPI_RAF range\n"); -+ ret = -EIO; -+ goto err2; -+ } -+ } else -+ priv->bspi_hw_raf = NULL; -+ DBG("priv->bspi_hw_raf=%p\n", priv->bspi_hw_raf); -+ -+ /* QSPI interrupt register range */ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 3); -+ if (res) { -+ priv->qspi_intr = (volatile void *)ioremap(res->start, -+ res->end - res->start); -+ if (!priv->qspi_intr) { -+ dev_err(&pdev->dev, "can't ioremap QSPI interrupt range\n"); -+ ret = -EIO; -+ goto err2; -+ } -+ } else { -+ dev_err(&pdev->dev, "can't get resource 3\n"); -+ ret = -EIO; -+ goto err2; -+ } -+ DBG("priv->qspi_intr=%p\n", priv->qspi_intr); -+ -+ /* IDM QSPI io ctrl register range */ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 4); -+ if (res) { -+ priv->idm_qspi = (volatile void *)ioremap(res->start, -+ res->end - res->start); -+ if (!priv->idm_qspi) { -+ dev_err(&pdev->dev, "can't ioremap IDM QSPI range\n"); -+ ret = -EIO; -+ goto err2; -+ } -+ } else { -+ dev_err(&pdev->dev, "can't get resource 4\n"); -+ ret = -EIO; -+ goto err2; -+ } -+ DBG("priv->idm_qspi=%p\n", priv->idm_qspi); -+ -+ /* CRU control register */ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 5); -+ if (res) { -+ priv->cru_hw = (volatile void *)ioremap(res->start, -+ res->end - res->start); -+ if (!priv->cru_hw) { -+ dev_err(&pdev->dev, "can't ioremap CRU range\n"); -+ ret = -EIO; -+ goto err2; -+ } -+ } else { -+ dev_err(&pdev->dev, "can't get resource 4\n"); -+ ret = -EIO; -+ goto err2; -+ } -+ DBG("priv->cru_hw=%p\n", priv->cru_hw); -+ -+ /* IRQ */ -+#ifndef CONFIG_OF -+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "no IRQ defined\n"); -+ ret = -ENODEV; -+ goto err2; -+ } -+#else -+ irqs_total = of_irq_count(dn); -+#endif /*CONFIG_OF*/ -+ -+ /* Basic initialization (before enabling interrupts) */ -+ priv->bspi_hw->mast_n_boot_ctrl = cpu_to_le32(1); -+ bcmspi_disable_interrupt(priv, 0xffffffff); -+ bcmspi_clear_interrupt(priv, 0xffffffff); -+ bcmspi_enable_interrupt(priv, QSPI_INTR_MSPI_DONE_MASK); -+ -+ /* Request all IRQs */ -+#ifndef CONFIG_OF -+ for(irq=(u32)res->start; irq<=(u32)res->end; irq++) { -+#else -+ for (i=0; idev, "unable to allocate IRQ\n"); -+ goto err1; -+ } -+ } -+ -+ bcmspi_hw_init(priv); -+ priv->curr_cs = -1; -+ -+#ifdef CONFIG_OF -+ if (of_property_read_u32(dn, "#chip-select", &qspi_cs)) { -+ dev_warn(&pdev->dev, -+ "missing #chip-selects property (default to 0)\n"); -+ qspi_cs = 0; -+ } -+ priv->bspi_chip_select = (1 << qspi_cs); -+ if (pdata == 0) { -+ struct brcmspi_platform_data platformdata; -+ memset(&platformdata, 0, sizeof(platformdata)); -+ platformdata.flash_cs = qspi_cs; -+ platform_device_add_data(pdev, &platformdata, sizeof(platformdata)); -+ pdata = (struct brcmspi_platform_data *)pdev->dev.platform_data; -+ } -+#else -+ priv->bspi_chip_select = (priv->bspi_hw && pdata) ? (1 << pdata->flash_cs) : 0; -+#endif /* CONFIG_OF */ -+ -+ INIT_LIST_HEAD(&priv->msg_queue); -+ spin_lock_init(&priv->lock); -+ -+ platform_set_drvdata(pdev, priv); -+ -+ tasklet_init(&priv->tasklet, bcmspi_tasklet, (unsigned long)priv); -+ -+ if (!default_master) -+ default_master = master; -+ -+ -+ if (priv->bspi_chip_select) { -+ int bspi_width = BSPI_WIDTH_1BIT; -+ -+ /* Module parameter validation */ -+ if (io_mode != 0) { -+ if (read_opcode < 0 || read_opcode > 255) { -+ dev_err(&pdev->dev, "invalid read_opcode\n"); -+ io_mode = 0; -+ } else if (dummy_cycles < 0 || dummy_cycles > 255) { -+ dev_err(&pdev->dev, "invalid dummy_cycles\n"); -+ io_mode = 0; -+ } -+ } -+ if (io_mode == 2) { -+ bspi_width = BSPI_WIDTH_4BIT; -+ } else if (io_mode == 1) { -+ bspi_width = BSPI_WIDTH_2BIT; -+ } else if (io_mode != 0) { -+ dev_err(&pdev->dev, "invalid io_mode (0/1/2)\n"); -+ } -+ -+ if (io_mode == 2) -+ bcmspi_set_quad_mode(priv, 1); -+ -+ bcmspi_set_mode(priv, bspi_width, BSPI_ADDRLEN_3BYTES, bspi_hp); -+ } -+ -+ ret = spi_register_master(master); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "can't register master\n"); -+ goto err0; -+ } -+ -+ return 0; -+ -+err0: -+ bcmspi_hw_uninit(priv); -+err1: -+#ifdef CONFIG_OF -+ while ( i-- ) { -+ irq = irq_of_parse_and_map(dn, i-1); -+ free_irq(irq, priv); -+ } -+#endif -+err2: -+ if (priv->idm_qspi) { -+ iounmap(priv->idm_qspi); -+ } -+ if (priv->qspi_intr) { -+ iounmap(priv->qspi_intr); -+ } -+ if (priv->bspi_hw_raf) { -+ iounmap(priv->bspi_hw_raf); -+ } -+ if (priv->bspi_hw) { -+ iounmap(priv->bspi_hw); -+ } -+ if (priv->mspi_hw) { -+ iounmap(priv->mspi_hw); -+ } -+ spi_master_put(master); -+ return ret; -+} -+ -+static int bcmspi_remove(struct platform_device *pdev) -+{ -+ struct bcmspi_priv *priv = platform_get_drvdata(pdev); -+ unsigned long flags; -+ u32 irq; -+#ifdef CONFIG_OF -+ struct device_node *dn = pdev->dev.of_node; -+ u32 irq_start=0, irq_end=0; -+#else -+ struct resource *res; -+#endif /* CONFIG_OF */ -+ -+ /* acquire lock when the MSPI is idle */ -+ while (1) { -+ spin_lock_irqsave(&priv->lock, flags); -+ if (priv->state == STATE_IDLE) -+ break; -+ spin_unlock_irqrestore(&priv->lock, flags); -+ udelay(100); -+ } -+ priv->state = STATE_SHUTDOWN; -+ spin_unlock_irqrestore(&priv->lock, flags); -+ -+ tasklet_kill(&priv->tasklet); -+ platform_set_drvdata(pdev, NULL); -+ bcmspi_hw_uninit(priv); -+ if (priv->bspi_hw_raf) -+ iounmap(priv->bspi_hw_raf); -+ if (priv->bspi_hw) -+ iounmap((volatile void __iomem *)priv->bspi_hw); -+#ifdef CONFIG_OF -+ irq_start = irq_of_parse_and_map(dn, 0); -+ irq_end = irq_of_parse_and_map(dn, 1); -+ if (irq_start && irq_end) { -+ for(irq=irq_start; irq<=irq_end; irq++) -+ free_irq(irq, priv); -+ } -+#else -+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -+ if (res) { -+ for(irq=(u32)res->start; irq<=(u32)res->end; irq++) { -+ free_irq(irq, priv); -+ } -+ } -+#endif -+ -+ iounmap((volatile void __iomem *)priv->mspi_hw); -+ spi_unregister_master(priv->master); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int bcmspi_suspend(struct device *dev) -+{ -+ struct bcmspi_priv *priv = dev_get_drvdata(dev); -+ int ret; -+ -+ if (priv == NULL || priv->master == NULL) { -+ return -EINVAL; -+ } -+ -+ /* Do nothing if it's not yet initialized */ -+ if (!priv->bspi_hw) -+ return 0; -+ -+ /* Flush transactions and stop the queue */ -+ ret = spi_master_suspend(priv->master); -+ if (ret) { -+ dev_warn(dev, "cannot suspend master\n"); -+ return ret; -+ } -+ -+ /* Disable flex mode */ -+ priv->bspi_hw->flex_mode_enable = 0; -+ -+ /* Clear upper byte */ -+ priv->bspi_hw->flash_upper_addr_byte = 0; -+ -+ /* Ensure BSPI read is clean */ -+ bcmspi_flush_prefetch_buffers(priv); -+ -+ /* Switch to BSPI for waking up from boot code */ -+ if (!priv->bspi_enabled) -+ priv->bspi_hw->mast_n_boot_ctrl = 0; -+ -+ return 0; -+}; -+ -+static int bcmspi_resume(struct device *dev) -+{ -+ struct bcmspi_priv *priv = dev_get_drvdata(dev); -+ int ret; -+ -+ if (priv == NULL || priv->master == NULL) -+ return -EINVAL; -+ -+ /* Do nothing if it's not yet initialized */ -+ if (!priv->bspi_hw) -+ return 0; -+ -+ /* Restore MSPI/BSPI mode */ -+ priv->bspi_enabled = !priv->bspi_enabled; -+ if (priv->bspi_enabled) -+ bcmspi_disable_bspi(priv); -+ else -+ bcmspi_enable_bspi(priv); -+ -+ /* Restore controller configuration */ -+ bcmspi_hw_set_parms(priv, &priv->last_parms); -+ -+ /* Restore flex mode configuration */ -+ bcmspi_set_mode(priv, -+ priv->flex_mode.width, priv->flex_mode.addrlen, priv->flex_mode.hp); -+ -+ -+ /* Restore interrupts */ -+ bcmspi_disable_interrupt(priv, 0xffffffff); -+ bcmspi_clear_interrupt(priv, 0xffffffff); -+ bcmspi_enable_interrupt(priv, QSPI_INTR_MSPI_DONE_MASK); -+ -+ /* Ensure BSPI read is clean */ -+ bcmspi_flush_prefetch_buffers(priv); -+ -+ /* Start the queue running */ -+ ret = spi_master_resume(priv->master); -+ if (ret) -+ dev_err(dev, "problem starting queue (%d)\n", ret); -+ -+ return ret; -+} -+ -+static const struct dev_pm_ops bcmspi_pm_ops = { -+ .suspend = bcmspi_suspend, -+ .resume = bcmspi_resume, -+}; -+#endif /* CONFIG_PM */ -+ -+ -+#ifdef CONFIG_OF -+static const struct of_device_id qspi_iproc_dt_ids[] = { -+ {.compatible = "brcm,iproc-qspi"}, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(of, qspi_iproc_dt_ids); -+ -+ -+static struct platform_driver qspi_iproc_driver = { -+ .driver = { -+ .name = "iproc-qspi", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(qspi_iproc_dt_ids), -+#ifdef CONFIG_PM -+ .pm = &bcmspi_pm_ops, -+#endif -+ }, -+ .probe = bcmspi_probe, -+ .remove = bcmspi_remove, -+}; -+ -+module_platform_driver(qspi_iproc_driver); -+ -+#else /*CONFIG_OF*/ -+ -+static struct platform_driver driver = { -+ .driver = { -+ .name = "qspi_iproc", -+ .bus = &platform_bus_type, -+ .owner = THIS_MODULE, -+#ifdef CONFIG_PM -+ .pm = &bcmspi_pm_ops, -+#endif -+ }, -+ .probe = bcmspi_probe, -+ .remove = __devexit_p(bcmspi_remove), -+}; -+ -+static int __init bcmspi_spi_init(void) -+{ -+ platform_driver_register(&driver); -+ return 0; -+} -+ -+static void __exit bcmspi_spi_exit(void) -+{ -+ platform_driver_unregister(&driver); -+} -+ -+module_init(bcmspi_spi_init); -+module_exit(bcmspi_spi_exit); -+#endif /*CONFIG_OF*/ -+ -+MODULE_AUTHOR("Broadcom Corporation"); -+MODULE_DESCRIPTION("iProc QSPI driver"); -+MODULE_LICENSE("GPL"); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/legacy/serial.c b/drivers/usb/gadget/legacy/serial.c ---- a/drivers/usb/gadget/legacy/serial.c 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/usb/gadget/legacy/serial.c 2017-11-09 17:54:01.552429000 +0800 -@@ -250,7 +250,7 @@ static int __init init(void) - */ - if (use_acm) { - serial_config_driver.label = "CDC ACM config"; -- serial_config_driver.bConfigurationValue = 2; -+ serial_config_driver.bConfigurationValue = 1; - device_desc.bDeviceClass = USB_CLASS_COMM; - device_desc.idProduct = - cpu_to_le16(GS_CDC_PRODUCT_ID); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig ---- a/drivers/usb/gadget/udc/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/usb/gadget/udc/Kconfig 2017-11-09 17:54:01.588427000 +0800 -@@ -373,6 +373,17 @@ config USB_GADGET_XILINX - dynamically linked module called "udc-xilinx" and force all - gadget drivers to also be dynamically linked. - -+config USB_XGS_IPROC_UDC -+ tristate "Broadcom XGS IPROC USB Device driver" -+ depends on ARCH_XGS_IPROC && USB_GADGET -+ default n -+ help -+ USB peripheral controller driver for Broadcom XGS IPROC USB 2 device. -+ -+ Say "y" to link the driver statically, or "m" to build a dynamically -+ linked module called "xgs_iproc_udc" and force all gadget drivers to -+ also be dynamically linked. -+ - # - # LAST -- dummy/emulated controller - # -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile ---- a/drivers/usb/gadget/udc/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/usb/gadget/udc/Makefile 2017-11-09 17:54:01.589418000 +0800 -@@ -30,4 +30,5 @@ obj-$(CONFIG_USB_FOTG210_UDC) += fotg210 - obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o - obj-$(CONFIG_USB_GR_UDC) += gr_udc.o - obj-$(CONFIG_USB_GADGET_XILINX) += udc-xilinx.o -+obj-$(CONFIG_USB_XGS_IPROC_UDC) += xgs_iproc_udc.o - obj-$(CONFIG_USB_BDC_UDC) += bdc/ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/xgs_iproc_udc.c b/drivers/usb/gadget/udc/xgs_iproc_udc.c ---- a/drivers/usb/gadget/udc/xgs_iproc_udc.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/usb/gadget/udc/xgs_iproc_udc.c 2017-11-09 17:54:01.736429000 +0800 -@@ -0,0 +1,2114 @@ -+/***************************************************************************** -+* Copyright 2006 - 2010 Broadcom Corporation. All rights reserved. -+* -+* Unless you and Broadcom execute a separate written software license -+* agreement governing use of this software, this software is licensed to you -+* under the terms of the GNU General Public License version 2, available at -+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). -+* -+* Notwithstanding the above, under no circumstances may you combine this -+* software in any way with any other Broadcom software provided under a -+* license other than the GPL, without Broadcom's express prior written -+* consent. -+*****************************************************************************/ -+/****************************************************************************/ -+/** -+* @file bcm_dwc_udc.c -+* -+* @brief Broadcom Linux driver for DWC USB 2.0 Device Controller (UDC) -+* -+* This driver implements the Linux Gadget driver API as defined in usb_gadget.h -+* -+* @note -+* -+* This driver was written with the intent of being able to support any -+* variations on how this block is integrated into different Broadcom chips. -+* -+* There is a requirement on how the DWC UDC is configured. In particular, this -+* driver requires that the following options be defined and enabled in the -+* UDC core. -+* -+* UDC20AHB_CNAK_CLR_ENH_CC -+* UDC20AHB_STALL_SET_ENH_CC -+* UDC20AHB_SNAK_ENH_CC -+* -+* Some other UDC attributes can be supported by setting compile time options -+* or with some minor modifications to the source code. Ideally these would -+* be run-time info that is provided by the device instance to the driver. -+* These attributes include the following. -+* -+* IPROC_UDC_EP_CNT -+* IPROC_UDC_EP_MAX_PKG_SIZE -+* Type of each endpoint: Control, IN, OUT, or Bidirectional -+*/ -+/****************************************************************************/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "xgs_iproc_udc.h" -+ -+#define XGS_IPROC_UDC_NAME "iproc-udc" -+/* Would be nice if DMA_ADDR_INVALID or similar was defined in dma-mapping.h */ -+#define DMA_ADDR_INVALID (~(dma_addr_t)0) -+/* -+ * FRAME_NUM_INVALID is used for ISOC IN transfers for frame alignment. -+ * The device specifies the interval at which it wants to do transfers, -+ * but the host initiates all transfers. If the interval is some multiple -+ * number of frames, the device has no idea which frame in an interval -+ * window the host is going to start transfers. This could even be at a -+ * point many frames beyond the current window, as the starting point -+ * can be very application dependant and subject to an indeterminate -+ * amount of latency. -+ */ -+#define FRAME_NUM_INVALID (~(uint)0) -+/* Would be nice if ENOERROR or similar was defined in errno.h */ -+#define ENOERROR 0 -+ -+/* ---- Private Function Prototypes -------------------------------------- */ -+#ifdef IPROC_UDC_DEBUG -+static void iproc_dbg_dma_dump(struct iproc_udc *udc); -+static void iproc_dbg_dma_dump_desc(char *label, struct iproc_udc_dma_desc *virt, struct iproc_udc_dma_desc *phys); -+static void iproc_dbg_dma_dump_ep(struct iproc_ep *ep); -+#endif /* IPROC_UDC_DEBUG */ -+ -+static void iproc_ep_setup_init(struct iproc_ep *ep, int status); -+static void iproc_ep_setup_process(struct iproc_ep *ep, struct usb_ctrlrequest *setup); -+ -+static void iproc_dma_ep_init(struct iproc_ep *ep); -+static void iproc_dma_data_init(struct iproc_ep *ep); -+static void iproc_dma_data_finish(struct iproc_ep *ep); -+static void iproc_dma_data_add_ready(struct iproc_ep *ep); -+static void iproc_dma_data_rm_done(struct iproc_ep *ep); -+ -+static int iproc_platform_dma_alloc(struct platform_device *platformDevP, struct iproc_udc *udc); -+static void iproc_platform_dma_free(struct platform_device *platformDevP, struct iproc_udc *udc); -+ -+static void iproc_udc_req_queue_flush(struct iproc_ep *ep, int status); -+static void iproc_udc_req_xfer_error(struct iproc_ep *ep, int status); -+static void iproc_udc_req_xfer_done(struct iproc_ep *ep, struct iproc_ep_req *req, int status); -+static void iproc_udc_req_xfer_process(struct iproc_ep *ep); -+static void iproc_udc_req_xfer_add(struct iproc_ep *ep, struct iproc_ep_req *req); -+ -+static void iproc_udc_ops_finish(struct iproc_udc *udc); -+static void iproc_udc_ops_init(struct iproc_udc *udc); -+static void iproc_udc_ops_stop(struct iproc_udc *udc); -+static void iproc_udc_ops_start(struct iproc_udc *udc); -+static void iproc_udc_ops_disconnect(struct iproc_udc *udc); -+static void iproc_udc_ops_shutdown(struct iproc_udc *udc); -+ -+static int xgs_iproc_ep_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc); -+static int xgs_iproc_ep_disable(struct usb_ep *ep); -+static struct usb_request *xgs_iproc_ep_alloc_request(struct usb_ep *ep, uint gfp_flags); -+static void xgs_iproc_ep_free_request(struct usb_ep *ep, struct usb_request *req); -+static int xgs_iproc_ep_queue(struct usb_ep *ep, struct usb_request *req, uint gfp_flags); -+static int xgs_iproc_ep_dequeue(struct usb_ep *ep, struct usb_request *req); -+static int xgs_iproc_ep_set_halt(struct usb_ep *ep, int value); -+static int xgs_iproc_ep_fifo_status(struct usb_ep *ep); -+static void xgs_iproc_ep_fifo_flush(struct usb_ep *ep); -+ -+static int xgs_iproc_udc_start(struct usb_gadget *, struct usb_gadget_driver *); -+static int xgs_iproc_udc_stop(struct usb_gadget *); -+ -+static int xgs_iproc_udc_probe(struct platform_device *pdev); -+static int xgs_iproc_udc_remove(struct platform_device *pdev); -+ -+static void xgs_iproc_udc_proc_create(void); -+static void xgs_iproc_udc_proc_remove(void); -+ -+/* ---- Private Variables ------------------------------------------------ */ -+static const struct { -+ const char *name; -+ const int type; -+ const int msize; -+ const struct usb_ep_caps caps; -+} xgs_iproc_ep_info[] = { -+#define EP_INFO(_name, _type, _size, _caps) \ -+ { \ -+ .name = _name, \ -+ .type = _type, \ -+ .msize = _size, \ -+ .caps = _caps, \ -+ } -+ -+ EP_INFO("ep0", USB_ENDPOINT_XFER_CONTROL, IPROC_UDC_CTRL_MAX_PKG_SIZE, -+ USB_EP_CAPS(USB_EP_CAPS_TYPE_CONTROL, USB_EP_CAPS_DIR_ALL)), -+ EP_INFO("ep1in", USB_ENDPOINT_XFER_ISOC, IPROC_UDC_EP_MAX_PKG_SIZE, -+ USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_IN)), -+ EP_INFO("ep2out", USB_ENDPOINT_XFER_ISOC, IPROC_UDC_EP_MAX_PKG_SIZE, -+ USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_OUT)), -+ EP_INFO("ep3in", USB_ENDPOINT_XFER_BULK, IPROC_UDC_EP_MAX_PKG_SIZE, -+ USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)), -+ EP_INFO("ep4out", USB_ENDPOINT_XFER_BULK, IPROC_UDC_EP_MAX_PKG_SIZE, -+ USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)), -+ EP_INFO("ep5in", USB_ENDPOINT_XFER_INT, IPROC_UDC_EP_MAX_PKG_SIZE, -+ USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN)), -+ EP_INFO("ep6out", USB_ENDPOINT_XFER_INT, IPROC_UDC_EP_MAX_PKG_SIZE, -+ USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_OUT)), -+#undef EP_INFO -+}; -+ -+static struct usb_gadget_ops xgs_iproc_udc_ops = { -+ .udc_start = xgs_iproc_udc_start, -+ .udc_stop = xgs_iproc_udc_stop, -+}; -+ -+static struct usb_ep_ops xgs_iproc_udc_ep_ops = { -+ .enable = xgs_iproc_ep_enable, -+ .disable = xgs_iproc_ep_disable, -+ .alloc_request = xgs_iproc_ep_alloc_request, -+ .free_request = xgs_iproc_ep_free_request, -+ .queue = xgs_iproc_ep_queue, -+ .dequeue = xgs_iproc_ep_dequeue, -+ .set_halt = xgs_iproc_ep_set_halt, -+ .fifo_status = xgs_iproc_ep_fifo_status, -+ .fifo_flush = xgs_iproc_ep_fifo_flush, -+}; -+ -+/*********************************************************************** -+ * Convenience functions -+ ***********************************************************************/ -+static inline struct iproc_udc *gadget_to_udc(struct usb_gadget *g) -+{ -+ return container_of(g, struct iproc_udc, gadget); -+} -+ -+static inline struct iproc_ep *our_ep(struct usb_ep *ep) -+{ -+ return container_of(ep, struct iproc_ep, usb_ep); -+} -+ -+static inline struct iproc_ep_req *our_req(struct usb_request *req) -+{ -+ return container_of(req, struct iproc_ep_req, usb_req); -+} -+ -+/**************************************************************************** -+ * DMA descriptor chain routines. -+ * -+ * dma_desc_chain_reset - Initialize chain in preparation for transfer -+ * dma_desc_chain_full - Indicates if no descriptors in chain for available for use. -+ * dma_desc_chain_alloc - Get next free descriptor for use. Have to check if chain not full first. -+ * dma_desc_chain_empty - Indicates if no descriptors in the chain are being used. -+ * dma_desc_chain_head - Pointer to 1st entry in chain. Have to check if chain not empty first. -+ * dma_desc_chain_free - Frees up 1st entry for use. Only do this if DMA for this descriptor has completed. -+ * -+ ***************************************************************************/ -+static inline struct iproc_udc_dma_desc *dma_desc_chain_alloc(struct iproc_ep *ep) -+{ -+ uint idx; -+ -+ idx = ep->dma.add_idx++; -+ -+ return &ep->dma.vir_addr->desc[IPROC_EP_DMA_DESC_IDX(idx)]; -+} -+ -+static inline int dma_desc_chain_empty(struct iproc_ep *ep) -+{ -+ return ep->dma.add_idx == ep->dma.rm_idx; -+} -+ -+static inline void dma_desc_chain_free(struct iproc_ep *ep) -+{ -+ ep->dma.rm_idx++; -+} -+ -+static inline int dma_desc_chain_full(struct iproc_ep *ep) -+{ -+ return (!dma_desc_chain_empty(ep) && (IPROC_EP_DMA_DESC_IDX(ep->dma.add_idx) == IPROC_EP_DMA_DESC_IDX(ep->dma.rm_idx))); -+} -+ -+static inline struct iproc_udc_dma_desc *dma_desc_chain_head(struct iproc_ep *ep) -+{ -+ return (&ep->dma.vir_addr->desc[IPROC_EP_DMA_DESC_IDX(ep->dma.rm_idx)]); -+} -+ -+static inline void dma_desc_chain_reset(struct iproc_ep *ep) -+{ -+ ep->dma.add_idx = 0; -+ ep->dma.rm_idx = 0; -+} -+ -+ -+/**************************************************************************** -+ * APIs used by a Gadget driver to attach / detach from the UDC driver. -+ ***************************************************************************/ -+static int xgs_iproc_udc_start(struct usb_gadget *gadget, -+ struct usb_gadget_driver *gadget_driver) -+{ -+ struct iproc_udc *udc = gadget_to_udc(gadget); -+ ulong flags; -+ -+ if (!udc) { -+ dev_err(udc->dev, "UDC driver not initialized\n"); -+ return -ENODEV; -+ } -+ -+ if (!gadget_driver || !gadget_driver->setup || -+ gadget_driver->max_speed < USB_SPEED_FULL) { -+ dev_err(udc->dev, "invalid gadget driver\n" ); -+ return -EINVAL; -+ } -+ -+ spin_lock_irqsave(&udc->lock, flags); -+ -+ if (udc->gadget_driver) { -+ spin_unlock_irqrestore(&udc->lock, flags); -+ dev_err(udc->dev, "UDC driver busy\n"); -+ return -EBUSY; -+ } -+ -+ /* Hook up the gadget driver to the UDC controller driver */ -+ gadget_driver->driver.bus = NULL; -+ udc->gadget_driver = gadget_driver; -+ udc->gadget.dev.driver = &gadget_driver->driver; -+ udc->pullup_on = 1; -+ -+ iproc_udc_ops_start(udc); -+ /* un-stop the control endpoint */ -+ udc->ep[0].stopped = 0; -+ iproc_usbd_bus_conn(udc->usbd_regs); -+ -+ iproc_usbd_setup_done(udc->usbd_regs); -+ iproc_usbd_dma_en(udc->usbd_regs); -+ -+ spin_unlock_irqrestore(&udc->lock, flags); -+ -+ return ENOERROR; -+} -+ -+static int xgs_iproc_udc_stop(struct usb_gadget *gadget) -+{ -+ ulong flags; -+ struct iproc_udc *udc = gadget_to_udc(gadget); -+ -+ if (!udc) { -+ dev_err(udc->dev, "UDC driver not initialized\n"); -+ return -ENODEV; -+ } -+ -+ spin_lock_irqsave(&udc->lock, flags); -+ -+ udc->ep[0].stopped = 1; -+ iproc_udc_ops_stop(udc); -+ udelay(20); -+ udc->pullup_on = 0; -+ iproc_usbd_bus_disconn(udc->usbd_regs); -+ iproc_udc_ops_shutdown(udc); -+ spin_unlock_irqrestore(&udc->lock, flags); -+ -+ return ENOERROR; -+} -+ -+/**************************************************************************** -+ * -+ * Platform device level alloc / free of memory used for DMA descriptors. -+ * A single block of memory static in size is used for DMA descriptors. -+ * Each endpoint has a small number of descriptors for its exclusive use. -+ * These are chained in a loop. See bcm_udc_dwc.h and iproc_dma_ep_init() for more -+ * details. -+ * -+ ***************************************************************************/ -+static int iproc_platform_dma_alloc(struct platform_device *platformDevP, struct iproc_udc *udc) -+{ -+ udc->dma.vir_addr = dma_alloc_coherent(&platformDevP->dev, sizeof(struct iproc_udc_dma), -+ (dma_addr_t *)&udc->dma.phy_addr, GFP_KERNEL); -+ -+ if (!udc->dma.vir_addr) { -+ dev_err(udc->dev, "dma_alloc_coherent() failed\n"); -+ return -ENOMEM; -+ } -+ -+ return ENOERROR; -+} -+ -+static void iproc_platform_dma_free(struct platform_device *platformDevP, struct iproc_udc *udc) -+{ -+ int idx; -+ -+ dma_free_coherent(&platformDevP->dev, sizeof(struct iproc_udc_dma), udc->dma.vir_addr, -+ (dma_addr_t)udc->dma.phy_addr); -+ -+ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx ++) { -+ if (udc->ep[idx].dma.align_buff) { -+ dma_free_coherent(NULL, udc->ep[idx].dma.align_len, -+ udc->ep[idx].dma.align_buff, -+ udc->ep[idx].dma.align_addr); -+ udc->ep[idx].dma.align_buff = NULL; -+ } -+ } -+} -+ -+/**************************************************************************** -+ * Linux Gadget endpoint operations. See usb_ep_ops in usb_gadget.h. -+ ***************************************************************************/ -+static int xgs_iproc_ep_enable(struct usb_ep *usb_ep, const struct usb_endpoint_descriptor *desc) -+{ -+ struct iproc_ep *ep = our_ep(usb_ep); -+ struct iproc_udc *udc = ep->udc; -+ ulong flags; -+ uint xferType; -+ int ret = ENOERROR; -+ -+ if (!usb_ep || (ep->beq_addr != desc->bEndpointAddress)) { -+ dev_err(udc->dev, "invalid endpoint (%p)\n", usb_ep); -+ return -EINVAL; -+ } -+ -+ if (!desc || (desc->bDescriptorType != USB_DT_ENDPOINT)) { -+ dev_err(udc->dev, "ep%d: invalid descriptor=%p type=%d\n", ep->num, desc, desc ? desc->bDescriptorType : -1); -+ return -EINVAL; -+ } -+ -+ if (desc == ep->desc) { -+ dev_warn(udc->dev, "ep%d: already enabled with same descriptor\n", ep->num); -+ return -EEXIST; -+ } -+ -+ if (ep->desc) { -+ dev_warn(udc->dev, "ep%d: already enabled with another descriptor\n", ep->num); -+ return -EBUSY; -+ } -+ -+ if (!udc->gadget_driver || (udc->gadget.speed == USB_SPEED_UNKNOWN)) { -+ dev_warn(udc->dev, "%s: invalid device state\n", ep->usb_ep.name); -+ return -ESHUTDOWN; -+ } -+ -+ xferType = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; -+ if ((ep->dir == USB_DIR_IN) && (xferType == USB_ENDPOINT_XFER_ISOC)) { -+ if ((desc->bInterval < 1) || (desc->bInterval > 16)) { -+ dev_err(udc->dev, "%s: invalid ISOC bInterval=%u\n", ep->usb_ep.name, desc->bInterval); -+ return -ERANGE; -+ } -+ -+ /* -+ * We don't know when the host will send the first ISO IN request, so we need to set up -+ * to capture that event so we can align subsequent transfers to that particular frame -+ * number. Also set the frame number increment. The endpoint descriptor specifies this -+ * as a power of 2 (2**(n-1)). Translate this into a specific number of frames. -+ */ -+ ep->dma.frame_num = FRAME_NUM_INVALID; -+ ep->dma.frame_incr = 1 << (desc->bInterval - 1); -+ } -+ -+ spin_lock_irqsave(&udc->lock, flags); -+ -+ ep->desc = desc; -+ ep->stopped = 0; -+ -+ /** @todo Rework the UdcEpCfg() so it includes iproc_usbd_ep_cfg_set() ... */ -+ iproc_usbd_ep_cfg_set(udc->usbd_regs, ep->num, iproc_usbd_cfg_num(udc->usbd_regs)); -+ -+ spin_unlock_irqrestore(&udc->lock, flags); -+ -+ return ret; -+} -+ -+static int xgs_iproc_ep_disable(struct usb_ep *usb_ep) -+{ -+ struct iproc_ep *ep = our_ep(usb_ep); -+ struct iproc_udc *udc = ep->udc; -+ ulong flags; -+ int ret = ENOERROR; -+ -+ if (!usb_ep) { -+ dev_err(udc->dev, "invalid endpoint\n"); -+ return -EINVAL; -+ } -+ -+ if (!ep->desc) { -+ dev_warn(udc->dev, "%s: already disabled\n", ep->usb_ep.name); -+ return ENOERROR; -+ } -+ -+ spin_lock_irqsave(&udc->lock, flags); -+ -+ iproc_udc_req_queue_flush(ep, -ESHUTDOWN); -+ iproc_usbd_ep_irq_dis(udc->usbd_regs, ep->num, ep->dir); -+ ep->desc = NULL; -+ -+ spin_unlock_irqrestore(&udc->lock, flags); -+ -+ return ret; -+} -+ -+struct usb_request * xgs_iproc_ep_alloc_request(struct usb_ep *usb_ep, uint gfp_flags) -+{ -+ struct iproc_ep_req *req; -+ -+ if (!usb_ep) { -+ return NULL; -+ } -+ -+ if ((req = kzalloc(sizeof(*req), gfp_flags)) != NULL) { -+ /* -+ * Set the usb_req.dma to DMA_ADDR_INVALID so it can be determined if the usb_req.buf needs -+ * to be mapped when the request is subsequently queued. -+ */ -+ INIT_LIST_HEAD(&req->list_node); -+ req->usb_req.dma = DMA_ADDR_INVALID; -+ -+ return &req->usb_req; -+ } -+ -+ return NULL; -+} -+ -+static void xgs_iproc_ep_free_request(struct usb_ep *usb_ep, struct usb_request *usb_req) -+{ -+ struct iproc_ep_req *req = our_req(usb_req); -+ -+ if (usb_req) { -+ kfree(req); -+ } -+} -+ -+static int xgs_iproc_ep_queue(struct usb_ep *usb_ep, struct usb_request *usb_req, uint gfp_flags) -+{ -+ struct iproc_ep *ep = our_ep(usb_ep); -+ struct iproc_udc *udc = ep->udc; -+ struct iproc_ep_req *req = our_req(usb_req); -+ ulong flags; -+ int ret = ENOERROR; -+ -+ if (!usb_ep || !usb_req || !req->usb_req.complete || !req->usb_req.buf || !list_empty(&req->list_node)) { -+ dev_err(udc->dev, "invalid request\n"); -+ return -EINVAL; -+ } -+ -+ if (!ep->desc && (ep->num != 0)) { -+ dev_err(udc->dev, "%s: invalid EP state\n", ep->usb_ep.name); -+ return -EFAULT; -+ } -+ -+ if ((ep->type == USB_ENDPOINT_XFER_CONTROL) && !list_empty(&ep->list_queue)) { -+ dev_err(udc->dev, "%s: CTRL EP queue not empty\n", ep->usb_ep.name); -+ return -EPERM; -+ } -+ -+ if (usb_req->length > 16384 /* FSG_BUFLEN */) { -+ dev_err(udc->dev, "%s: request too big, length=%u\n", ep->usb_ep.name, usb_req->length); -+ return -E2BIG; -+ } -+ -+ /* -+ * Restrict ISOC IN requests to the max packet size. Assumption is that it does not make -+ * much sense to have more than one interval's (scheduled bandwidth's) worth of data. -+ */ -+ if ((ep->type == USB_ENDPOINT_XFER_ISOC) && (ep->dir == USB_DIR_IN) && (usb_req->length > ep->usb_ep.maxpacket)) { -+ dev_err(udc->dev, "%s: request > scheduled bandwidth, length=%u\n", ep->usb_ep.name, usb_req->length); -+ return -EFBIG; -+ } -+ -+ if (!udc->gadget_driver || (udc->gadget.speed == USB_SPEED_UNKNOWN)) { -+ dev_warn(udc->dev, "%s: invalid device state\n", ep->usb_ep.name); -+ return -ESHUTDOWN; -+ } -+ -+ if (((ulong)req->usb_req.buf) & 0x3UL) { -+ /* -+ * The DMA buffer does not have the alignment required by the hardware. We keep an endpoint level -+ * buffer available to handle this situation if it arises. If we don't currently have one available -+ * for this purpose, or if the current one is not large enough, then allocate a new one. Since -+ * we only have one buffer, we won't copy into the buffer until we are ready to do the DMA transfer. -+ * Mark the request as needing this alignment (copy). -+ */ -+ if ((ep->dma.align_buff != NULL) && (ep->dma.align_len < req->usb_req.length)) { -+ dma_free_coherent(NULL, ep->dma.align_len, ep->dma.align_buff, ep->dma.align_addr); -+ ep->dma.align_buff = NULL; -+ } -+ -+ if (ep->dma.align_buff == NULL) { -+ ep->dma.align_len = req->usb_req.length; -+ ep->dma.align_buff = dma_alloc_coherent(NULL, ep->dma.align_len, &(ep->dma.align_addr), GFP_KERNEL); -+ } -+ -+ if (ep->dma.align_buff == NULL) { -+ dev_err(udc->dev, "%s: dma_alloc_coherent() failed, length=%u\n", ep->usb_ep.name, usb_req->length); -+ return -ENOMEM; -+ } -+ -+ req->dma_aligned = 1; -+ } else if ((req->usb_req.dma == DMA_ADDR_INVALID) || (req->usb_req.dma == 0)) { -+ /* A physical address was not provided for the DMA buffer, so request it. */ -+ req->dma_mapped = 1; -+ req->usb_req.dma = dma_map_single(udc->gadget.dev.parent, -+ req->usb_req.buf, -+ req->usb_req.length, -+ (ep->dir == USB_DIR_IN ? DMA_TO_DEVICE : DMA_FROM_DEVICE)); -+ } -+ -+ spin_lock_irqsave(&udc->lock, flags); -+ -+ req->usb_req.status = -EINPROGRESS; -+ req->usb_req.actual = 0; -+ -+ if ((ep->type == USB_ENDPOINT_XFER_CONTROL) && (ep->dir == USB_DIR_OUT) && (req->usb_req.length == 0)) { -+ /* -+ * This might happen if gadget driver decides to send zero length packet (ZLP) during STATUS phase -+ * of a control transfer. This may happen for the cases where there is not a DATA phase. Just consider -+ * things complete. ZLP will be issued by hardware. See the handling of SETUP packets for more details -+ * on control transfer processing. -+ */ -+ iproc_udc_req_xfer_done(ep, req, ENOERROR); -+ } else { -+ if (req->usb_req.length == 0) { -+ req->usb_req.zero = 1; -+ } -+ iproc_udc_req_xfer_add(ep, req); -+ } -+ -+ spin_unlock_irqrestore(&udc->lock, flags); -+ -+ return ret; -+} -+ -+static int xgs_iproc_ep_dequeue(struct usb_ep *usb_ep, struct usb_request *usb_req) -+{ -+ struct iproc_ep *ep = our_ep(usb_ep); -+ struct iproc_udc *udc = ep->udc; -+ struct iproc_ep_req *req = our_req(usb_req); -+ ulong flags; -+ int ret = ENOERROR; -+ -+ if (!usb_ep || !usb_req) { -+ dev_err(udc->dev, "invalid request\n"); -+ return -EINVAL; -+ } -+ -+ spin_lock_irqsave(&udc->lock, flags); -+ -+ /* Make sure it's actually queued on this endpoint */ -+ list_for_each_entry(req, &ep->list_queue, list_node) { -+ if (&req->usb_req == usb_req) { -+ break; -+ } -+ } -+ -+ if (&req->usb_req != usb_req) { -+ spin_unlock_irqrestore(&udc->lock, flags); -+ dev_err(udc->dev, "%s: request not queued\n", ep->usb_ep.name); -+ return -ENOLINK; -+ } -+ -+ /** @todo Handle case where the request is in progress, or completed but not dequeued */ -+ -+ iproc_udc_req_xfer_done(ep, req, -ECONNRESET); -+ spin_unlock_irqrestore(&udc->lock, flags); -+ -+ return ret; -+} -+ -+static int xgs_iproc_ep_set_halt(struct usb_ep *usb_ep, int enable) -+{ -+ struct iproc_ep *ep = our_ep(usb_ep); -+ struct iproc_udc *udc = ep->udc; -+ ulong flags; -+ int ret = ENOERROR; -+ -+ if (!usb_ep) { -+ dev_err(udc->dev, "invalid request\n"); -+ return -EINVAL; -+ } -+ -+ if (ep->type == USB_ENDPOINT_XFER_ISOC) { -+ dev_warn(udc->dev, "%s: ISO HALT operations not supported\n", ep->usb_ep.name); -+ return -EOPNOTSUPP; -+ } -+ -+ if (enable && (ep->dir == USB_DIR_IN) && !list_empty(&ep->list_queue)) { -+ /* Only allow halt on an IN EP if its queue is empty */ -+ dev_err(udc->dev, "%s: IN queue not empty\n", ep->usb_ep.name); -+ return -EAGAIN; -+ } -+ -+ if (!enable && (ep->type == USB_ENDPOINT_XFER_CONTROL)) { -+ /* -+ * Halt clear for a control EP should only be handled as part of the subsequent SETUP -+ * exchange that occurs after the Halt was set. -+ */ -+ dev_warn(udc->dev, "%s: CTRL HALT clear\n", ep->usb_ep.name); -+ return -EPROTO; -+ } -+ -+ spin_lock_irqsave(&udc->lock, flags); -+ -+ if (!enable) { -+ iproc_usbd_ep_stall_dis(udc->usbd_regs, ep->num, ep->dir); -+ } else if (ep->type != USB_ENDPOINT_XFER_CONTROL) { -+ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, ep->dir); -+ } else { -+ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, USB_DIR_IN); -+ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, USB_DIR_OUT); -+ } -+ -+ spin_unlock_irqrestore(&udc->lock, flags); -+ mdelay(2); -+ -+ return ret; -+} -+ -+static int xgs_iproc_ep_fifo_status(struct usb_ep *usb_ep) -+{ -+ /* -+ * The DWC UDC core doesn't have a mechanism for determining the number of bytes -+ * currently in a FIFO. The best that can be done is determine whether or not a -+ * FIFO is empty. However, for the situation where a single Rx FIFO is being -+ * used for all endpoints, if cannot be determined which OUT and CTRL EP's are -+ * affected if the Rx FIFO is not empty. -+ */ -+ return -EOPNOTSUPP; -+} -+ -+static void xgs_iproc_ep_fifo_flush(struct usb_ep *usb_ep) -+{ -+ struct iproc_ep *ep = our_ep(usb_ep); -+ struct iproc_udc *udc = ep->udc; -+ ulong flags; -+ -+ if (!usb_ep) { -+ dev_err(udc->dev, "invalid request\n"); -+ return; -+ } -+ -+ /* -+ * FIFO flush for a control EP does not make any sense. The SETUP protocol -+ * should eliminate the need to flush. -+ */ -+ if (ep->type == USB_ENDPOINT_XFER_CONTROL) { -+ dev_warn(udc->dev, "%s: CTRL FIFO flush\n", ep->usb_ep.name); -+ return; -+ } -+ -+ if (iproc_usbd_ep_fifo_empty(udc->usbd_regs, ep->num, ep->dir)) { -+ dev_warn(udc->dev, "%s: FIFO empty\n", ep->usb_ep.name); -+ return; -+ } -+ -+ spin_lock_irqsave(&udc->lock, flags); -+ -+ iproc_usbd_ep_fifo_flush_en(udc->usbd_regs, ep->num, ep->dir); -+ -+ spin_unlock_irqrestore(&udc->lock, flags); -+} -+ -+/*************************************************************************** -+ * Routines for debug dump of DMA descriptors -+ **************************************************************************/ -+#ifdef IPROC_UDC_DEBUG -+static void iproc_dbg_dma_dump(struct iproc_udc *udc) -+{ -+ int idx; -+ -+ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { -+ iproc_dbg_dma_dump_ep(&udc->ep[idx]); -+ } -+} -+ -+static void iproc_dbg_dma_dump_desc(char *label, struct iproc_udc_dma_desc *virt, struct iproc_udc_dma_desc *phys) -+{ -+ printk("%s virt=0x%p phys=0x%p: 0x%08x 0x%08x 0x%08x", label, virt, phys, virt->status, virt->reserved, virt->buf_addr); -+} -+ -+static void iproc_dbg_dma_dump_ep(struct iproc_ep *ep) -+{ -+ int idx; -+ -+ printk("EP %d DMA\n", ep->num); -+ printk(" setup\n"); -+ iproc_dbg_dma_dump_desc(" ", (struct iproc_udc_dma_desc *)&ep->dma.vir_addr->setup, (struct iproc_udc_dma_desc *)&ep->dma.phy_addr->setup); -+ printk(" desc\n"); -+ -+ for (idx = 0; idx < IPROC_EP_DMA_DESC_CNT; idx++) { -+ iproc_dbg_dma_dump_desc(" ", &ep->dma.vir_addr->desc[idx], &ep->dma.phy_addr->desc[idx]); -+ -+ /* Don't bother displaying entries beyond the last. */ -+ if (IPROC_USBD_READ(ep->dma.vir_addr->desc[idx].status) & IPROC_USBD_REG_DMA_STAT_LAST_DESC) { -+ break; -+ } -+ } -+} -+#endif /* IPROC_UDC_DEBUG */ -+ -+/**************************************************************************** -+ * Initialization of DMA descriptors at the endpoint level. -+ ***************************************************************************/ -+static void iproc_dma_ep_init(struct iproc_ep *ep) -+{ -+ struct iproc_udc *udc = ep->udc; -+ int idx; -+ -+ /** @todo shorten names to virtAddr physAddr?? */ -+ ep->dma.vir_addr = &udc->dma.vir_addr->ep[ep->num]; -+ ep->dma.phy_addr = &udc->dma.phy_addr->ep[ep->num]; -+ -+ /* -+ * Control endpoints only do setup in the OUT direction, so only need to set the -+ * buffer address for that direction. The buffer is set, even if not a control -+ * endpoint, just to simplify things. There's no harm with this. -+ */ -+ ep->dma.vir_addr->setup.status = cpu_to_le32(IPROC_USBD_REG_DMA_STAT_BUF_HOST_BUSY); -+ wmb(); -+ iproc_usbd_ep_dma_buf_addr_set(udc->usbd_regs, ep->num, USB_DIR_OUT, &ep->dma.phy_addr->setup); -+ -+ /* -+ * Take ownership of the DMA descriptors, and chain them in a loop. This allows a small number -+ * descriptors to be used for requests. Need to have the DWC DMA Descriptor Update option enabled -+ * in the device control register in order to do this. When a transfer for a descriptor completes, -+ * the descriptor will get re-used if there's still data left in a request to transfer. See the -+ * iproc_dma_data_rm_done() and iproc_dma_data_add_ready() routines. -+ */ -+ /** @todo Put these in endpoint context?? */ -+ for (idx = 0; idx < IPROC_EP_DMA_DESC_CNT; idx++) { -+ ep->dma.vir_addr->desc[idx].status = cpu_to_le32(IPROC_USBD_REG_DMA_STAT_BUF_HOST_BUSY); -+ wmb(); -+ ep->dma.vir_addr->desc[idx].next_addr = cpu_to_le32((uint)&ep->dma.phy_addr->desc[idx+1]); -+ } -+ ep->dma.vir_addr->desc[(IPROC_EP_DMA_DESC_CNT - 1)].next_addr = cpu_to_le32((uint)&ep->dma.phy_addr->desc[0]); -+ -+ /* -+ * To simplify things, register the descriptor chain in both directions. Control endpoints are the -+ * only type that will be transferring in both directions, but they will only be transferring in one -+ * direction at a time, so should not be any issues with using the same descriptor set for both directions. -+ * For single direction endpoints, the other direction will not be used. -+ */ -+ -+ iproc_usbd_ep_dma_desc_addr_set(udc->usbd_regs, ep->num, USB_DIR_OUT, &ep->dma.phy_addr->desc[0]); -+ iproc_usbd_ep_dma_desc_addr_set(udc->usbd_regs, ep->num, USB_DIR_IN, &ep->dma.phy_addr->desc[0]); -+} -+ -+/**************************************************************************** -+ * DMA data routines. -+ * -+ * A gadget usb_request buf is used for the data. The entire buf contents may -+ * or may not fit into the descriptor chain at once. When the DMA transfer -+ * associated with a descriptor completes, the descriptor is re-used to add -+ * more segments of the usb_request to the chain as necessary. -+ * -+ * iproc_dma_data_init - Initialization in preparation for DMA of usb_request. -+ * iproc_dma_data_add_ready - Adds usb_request segments into DMA chain until full or no segments left -+ * iproc_dma_data_rm_done - Removes usb_request segments from DMA chain that have completed transfer -+ * iproc_dma_data_finish - Final stage of DMA of the usb_request -+ * -+ ***************************************************************************/ -+static void iproc_dma_data_init(struct iproc_ep *ep) -+{ -+ struct iproc_ep_req *req; -+ struct iproc_udc *udc = ep->udc; -+ -+ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); -+ -+ if (req->dma_aligned) { -+ /* -+ * This buffer needs to be aligned in order to DMA. We do this by copying into a special buffer we -+ * have for this purpose. Save the original DMA physical address so it can be restored later. -+ * This may not be used, but we'll do it anyways. Then set the DMA address to the aligned buffer -+ * address. Only the DMA physical address is used for the transfers, so the original buffer virtual -+ * address does not need to be changed. Then copy the data into the aligned buffer. -+ */ -+ /** @todo Really only need to do the memcpy for IN data */ -+ -+ req->orig_dma_addr = req->usb_req.dma; -+ req->usb_req.dma = ep->dma.align_addr; -+ memcpy(ep->dma.align_buff, req->usb_req.buf, req->usb_req.length); -+ } -+ -+ ep->dma.done = 0; -+ ep->dma.done_len = 0; -+ ep->dma.todo_len = ep->dma.usb_req->length; -+ ep->dma.buf_addr = ep->dma.usb_req->dma; -+ ep->dma.status = IPROC_USBD_REG_DMA_STAT_RX_SUCCESS; -+ -+ if ((ep->dir == USB_DIR_IN) && (ep->type != USB_ENDPOINT_XFER_ISOC)) { -+ /* -+ * For IN transfers, do not need to segment the buffer into max packet portions -+ * for the DMA descriptors. The hardware will automatically segment into max -+ * packet sizes as necessary. -+ */ -+ ep->dma.max_buf_len = ep->usb_ep.maxpacket; -+ -+ /* -+ * If the request is of zero length, then force the zero flag so iproc_dma_data_add_ready() -+ * will queue the request. Conversely, if the gadget has set the zero flag, leave -+ * it set only if it is needed (request length is a multiple of maxpacket) -+ */ -+ if (ep->dma.usb_req->length == 0) { -+ ep->dma.usb_req->zero = 1; -+ } else if (ep->dma.usb_req->zero) { -+ ep->dma.usb_req->zero = (ep->dma.usb_req->length % ep->usb_ep.maxpacket) ? 0 : 1; -+ } -+ } else { -+ ep->dma.max_buf_len = ep->usb_ep.maxpacket; -+ } -+ -+ dma_desc_chain_reset(ep); -+ -+ iproc_usbd_ep_irq_en(udc->usbd_regs, ep->num, ep->dir); -+} -+ -+static void iproc_dma_data_finish(struct iproc_ep *ep) -+{ -+ struct iproc_ep_req *req; -+ struct iproc_udc *udc = ep->udc; -+ -+ iproc_usbd_ep_irq_dis(udc->usbd_regs, ep->num, ep->dir); -+ iproc_usbd_ep_dma_dis(udc->usbd_regs, ep->num, ep->dir); -+ -+ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); -+ -+ if (req->dma_aligned) { -+ /* -+ * The original request buffer was not aligned properly, so a special buffer was used -+ * for the transfer. Copy the aligned buffer contents into the original. Also restore -+ * the original dma physical address. -+ */ -+ /** @todo Really only need to do the memcpy for OUT setup/data */ -+ memcpy(req->usb_req.buf, ep->dma.align_buff, req->usb_req.length); -+ req->usb_req.dma = req->orig_dma_addr; -+ } -+} -+ -+static void iproc_dma_data_add_ready(struct iproc_ep *ep) -+{ -+ struct iproc_udc *udc = ep->udc; -+ volatile struct iproc_udc_dma_desc *dma_desc = NULL; -+ uint status; -+ uint len; -+ int enable_dma = 0; -+ -+ /* -+ * DMA must be disabled while this loop is running, as multi-descriptor transfers -+ * will have the descriptor chain in an intermediate state until the last descriptor -+ * is written and the chain terminated. -+ */ -+ if (iproc_usbd_dma_status(udc->usbd_regs)) { -+ enable_dma = 1; -+ iproc_usbd_dma_dis(udc->usbd_regs); -+ } -+ -+ if (!ep->dma.todo_len) { -+ ep->dma.usb_req->zero = 1; -+ } -+ -+ /* -+ * Will only have one request in the chain at a time. Add request segments to the -+ * chain until all parts of the request have been put in the chain or the chain -+ * has no more room. -+ */ -+ while (!dma_desc_chain_full(ep) && (ep->dma.todo_len || ep->dma.usb_req->zero)) { -+ /* -+ * Get the next descriptor in the chain, and then fill the descriptor contents as needed. -+ * Do not set the descriptor buffer status to ready until last to ensure there's no -+ * contention with the hardware. -+ */ -+ dma_desc = dma_desc_chain_alloc(ep); -+ -+ len = ep->dma.todo_len < ep->dma.max_buf_len ? ep->dma.todo_len : ep->dma.max_buf_len; -+ ep->dma.todo_len -= len; -+ -+ status = 0; -+ -+ if (len < ep->dma.max_buf_len) { -+ /* -+ * If this segment is less than the max, then it is the last segment. There's no need to -+ * send a closing ZLP, although this segment might be a ZLP. Regardless, clear the ZLP flag -+ * to ensure that the processing of this request finishes. Also set the end of the descriptor -+ * chain. -+ */ -+ ep->dma.usb_req->zero = 0; -+ status |= IPROC_USBD_REG_DMA_STAT_LAST_DESC; -+ } else if ((ep->dma.todo_len == 0) && !ep->dma.usb_req->zero) { -+ /* -+ * Segment is of the max packet length. Since there's nothing left, it has to also be the last -+ * last segment. No closing ZLP segment requested, just set the end of the descriptor chain. -+ */ -+ status |= IPROC_USBD_REG_DMA_STAT_LAST_DESC; -+ } -+ -+ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC)) { -+ /* -+ * Increment the frame number for transmit, then use it for the next packet. The frame number -+ * may get larger than its 13-bit size, but the mask will handle the wrap-around so we don't -+ * need to add checks for this condition. E.g. 0x7ff + 1 = 0x800. 0x800 & 0x7ff = 0 which -+ * is the next number in the sequence. -+ */ -+ /** @todo Handle ISOC PIDs and frame numbers used with HS high bandwidth transfers */ -+ /** @todo Might not need to set the last descriptor status. Currently restricting -+ * IN ISOC transfers to the max packet size. -+ */ -+ status |= IPROC_USBD_REG_DMA_STAT_LAST_DESC; -+ -+ ep->dma.frame_num += ep->dma.frame_incr; -+ status |= ((ep->dma.frame_num << IPROC_USBD_REG_DMA_STAT_FRAME_NUM_SHIFT) & IPROC_USBD_REG_DMA_STAT_FRAME_NUM_MASK); -+ } -+ -+ IPROC_USBD_WRITE(dma_desc->buf_addr, ep->dma.buf_addr); -+ status |= (len << IPROC_USBD_REG_DMA_STAT_BYTE_CNT_SHIFT); -+ IPROC_USBD_WRITE(dma_desc->status, status | IPROC_USBD_REG_DMA_STAT_BUF_HOST_READY); -+ wmb(); -+ ep->dma.buf_addr += len; -+ -+ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC)) { -+ /* With ISOC transfers, only enable one DMA descriptors at a time. -+ */ -+ /** @todo Determine if FIFO will overflow. If it does not, then can remove this check. -+ * This may not even be an issue if the buffer size is restricted to the max packet size -+ * when a request is submitted to the endpoint. -+ */ -+ break; -+ } -+ } -+ /* Set LAST bit on last descriptor we've configured */ -+ if (dma_desc) { -+ IPROC_USBD_BITS_SET(dma_desc->status, IPROC_USBD_REG_DMA_STAT_LAST_DESC); -+ } -+ -+ if (enable_dma) { -+ iproc_usbd_dma_en(udc->usbd_regs); -+ } -+} -+ -+static void iproc_dma_data_rm_done(struct iproc_ep *ep) -+{ -+ struct iproc_udc *udc = ep->udc; -+ volatile struct iproc_udc_dma_desc *dma_desc; -+ uint status; -+ uint len; -+ -+ /* -+ * Will only have one request in the chain at a time. Remove any completed -+ * request segments from the chain so any segments awaiting transfer can -+ * be put in the chain. -+ */ -+ while (!dma_desc_chain_empty(ep)) { -+ /* -+ * Examine the first entry in the chain. If its status is not done, then there's -+ * nothing to remove. -+ */ -+ dma_desc = dma_desc_chain_head(ep); -+ -+ if ((IPROC_USBD_READ(dma_desc->status) & IPROC_USBD_REG_DMA_STAT_BUF_MASK) != IPROC_USBD_REG_DMA_STAT_BUF_DMA_DONE) { -+ break; -+ } -+ -+ /* -+ * The transfer of this request segment has completed. Save the status info and then -+ * take ownership of the descriptor. It is simpler to do this than modifying parts of -+ * the descriptor in order to take ownership. Don't put the descriptor back in the chain -+ * until all info affected by the status has been updated, just to be safe. -+ */ -+ status = IPROC_USBD_READ(dma_desc->status); -+ IPROC_USBD_WRITE(dma_desc->status, IPROC_USBD_REG_DMA_STAT_BUF_HOST_BUSY); -+ wmb(); -+ -+ len = (status & IPROC_USBD_REG_DMA_STAT_NON_ISO_BYTE_CNT_MASK) >> IPROC_USBD_REG_DMA_STAT_NON_ISO_BYTE_CNT_SHIFT; -+ -+ /* RX: For multiple descriptors, len is cumulative, not absolute. -+ * RX: So only adjust the dma fields when we get to the last descriptor -+ * TX: Each descriptor entry is absolute, count them all -+ */ -+ if ((ep->dir == USB_DIR_IN) || (status & IPROC_USBD_REG_DMA_STAT_LAST_DESC)) { -+ ep->dma.done_len += len; -+ ep->dma.usb_req->actual += len; -+ } -+ -+ if ((status & IPROC_USBD_REG_DMA_STAT_RX_MASK) != IPROC_USBD_REG_DMA_STAT_RX_SUCCESS) { -+ ep->dma.status = status & IPROC_USBD_REG_DMA_STAT_RX_MASK; -+ ep->dma.usb_req->status = -EIO; -+ dev_warn(udc->dev, "%s: DMA error: desc=0x%p status=0x%x len=%d add=0x%x remove=0x%x\n", -+ ep->usb_ep.name, dma_desc, status, len, ep->dma.add_idx, ep->dma.rm_idx); -+ } -+ -+ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC)){ -+ /** @todo Determine if this special processing needs to be done. May not to do this if the -+ * buffer size is restricted to the max packet size when a request is submitted to the endpoint. -+ */ -+ if (ep->dma.usb_req->actual == ep->dma.usb_req->length) { -+ ep->dma.usb_req->status = ENOERROR; -+ } -+ dma_desc_chain_reset(ep); -+ } else { -+ dma_desc_chain_free(ep); -+ } -+ } -+ -+ /* When last segment processed, update status if there has not been an error */ -+ if (!ep->dma.todo_len && (ep->dma.usb_req->status == -EINPROGRESS)) { -+ ep->dma.usb_req->status = ENOERROR; -+ } -+} -+ -+/*************************************************************************** -+ * UDC Operations routines. -+ * iproc_udc_ops_init - Initialization of the UDC in preparation for use by Gadget driver. -+ * iproc_udc_ops_start - Start UDC operations. Happens after a Gadget driver attaches. -+ * iproc_udc_ops_stop - Stop UDC operations. Happens after a Gadget driver detaches. -+ * iproc_udc_ops_finish - Finish / terminate all UDC operations -+ ***************************************************************************/ -+static void iproc_udc_ops_finish(struct iproc_udc *udc) -+{ -+ /* do nothing */ -+ return; -+} -+ -+static void iproc_udc_ops_init(struct iproc_udc *udc) -+{ -+ int idx; -+ struct iproc_ep *ep; -+ -+ iproc_usbd_ops_init(udc->usbd_regs); -+ -+ /* -+ * See usb/gadget/epautoconf.c for endpoint naming conventions. -+ * Control endpoints are bi-directional, but initial transfer (SETUP stage) is always OUT. -+ */ -+ /** @todo Really should make the non endpoint 0 init attributes configurable by the chip specific part -+ * of the driver, idx.e. the device instantiation. The settings below are for a chip specific DWG UDC -+ * core configuration. Also should incorporate the DWG UDC endpoint type attribute as part of this, -+ * which can be control, IN, OUT, or bidirectional. -+ */ -+ INIT_LIST_HEAD(&udc->gadget.ep_list); -+ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { -+ ep = &udc->ep[idx]; -+ -+ ep->udc = udc; -+ ep->num = idx; -+ -+ ep->dir = (xgs_iproc_ep_info[idx].caps.dir_in) ? USB_DIR_IN : USB_DIR_OUT;; -+ ep->beq_addr = idx | ep->dir; -+ ep->stopped = 0; -+ ep->type = xgs_iproc_ep_info[idx].type; -+ -+ ep->usb_ep.name = xgs_iproc_ep_info[idx].name; -+ ep->usb_ep.caps = xgs_iproc_ep_info[idx].caps; -+ ep->usb_ep.ops = &xgs_iproc_udc_ep_ops; -+ list_add_tail(&ep->usb_ep.ep_list, &udc->gadget.ep_list); -+ usb_ep_set_maxpacket_limit(&ep->usb_ep, xgs_iproc_ep_info[idx].msize); -+ ep->usb_ep.desc = NULL; -+ INIT_LIST_HEAD(&ep->list_queue); -+ -+ iproc_usbd_ep_ops_init(udc->usbd_regs, ep->num, ep->type, ep->dir, xgs_iproc_ep_info[idx].msize); -+ -+ iproc_dma_ep_init(ep); -+ } -+ -+ udc->gadget.ep0 = &udc->ep[0].usb_ep; -+ list_del(&udc->ep[0].usb_ep.ep_list); -+ -+ iproc_usbd_self_pwr_en(udc->usbd_regs); -+} -+ -+static void iproc_udc_ops_start(struct iproc_udc *udc) -+{ -+ int idx; -+ -+ /* -+ * Just enable interrupts for now. Endpoint 0 will get enabled once the speed enumeration -+ * has completed. The Device DMA enable is global in scope. There's endpoint specific -+ * DMA enables that will happen later. -+ */ -+ iproc_usbd_irq_en(udc->usbd_regs, (IPROC_USBD_IRQ_SPEED_ENUM_DONE | -+ IPROC_USBD_IRQ_BUS_SUSPEND | -+ IPROC_USBD_IRQ_BUS_IDLE | -+ IPROC_USBD_IRQ_BUS_RESET | -+ IPROC_USBD_IRQ_SET_INTF | -+ IPROC_USBD_IRQ_SET_CFG)); -+ iproc_usbd_dma_en(udc->usbd_regs); -+ -+ /* Enable interrupts for all configured endpoints */ -+ for (idx = 0; idx < IPROC_UDC_EP_CNT; ++idx) { -+ if (udc->ep[idx].usb_ep.name) { -+ iproc_usbd_ep_irq_en(udc->usbd_regs, udc->ep[idx].num, USB_DIR_OUT); -+ iproc_usbd_ep_irq_en(udc->usbd_regs, udc->ep[idx].num, USB_DIR_IN); -+ } -+ } -+ iproc_usbd_nak_response_dis(udc->usbd_regs); -+} -+ -+static void iproc_udc_ops_stop(struct iproc_udc *udc) -+{ -+ struct iproc_ep *ep; -+ -+ iproc_usbd_dma_dis(udc->usbd_regs); -+ iproc_usbd_irq_dis(udc->usbd_regs, IPROC_USBD_IRQ_ALL); -+ iproc_usbd_irq_clear(udc->usbd_regs, IPROC_USBD_IRQ_ALL); -+ -+ udc->gadget.speed = USB_SPEED_UNKNOWN; -+ -+ iproc_udc_req_queue_flush(&udc->ep[0], -ESHUTDOWN); -+ list_for_each_entry(ep, &udc->gadget.ep_list, usb_ep.ep_list) { -+ iproc_udc_req_queue_flush(ep, -ESHUTDOWN); -+ } -+} -+ -+static void iproc_udc_ops_disconnect(struct iproc_udc *udc) -+{ -+ struct iproc_ep *ep; -+ int idx; -+ -+ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { -+ ep = &udc->ep[idx]; -+ -+ if (ep->dma.usb_req) { -+ /* Flush DMA, reqeust still pending */ -+ iproc_usbd_ep_fifo_flush_en(udc->usbd_regs, 0, IPROC_USBD_EP_DIR_IN); -+ iproc_usbd_ep_fifo_flush_dis(udc->usbd_regs, 0, IPROC_USBD_EP_DIR_IN); -+ -+ iproc_udc_req_xfer_process(ep); -+ } -+ } -+} -+ -+static void iproc_udc_ops_shutdown(struct iproc_udc *udc) -+{ -+ struct iproc_ep *ep; -+ -+ udc->ep[0].desc = NULL; -+ list_for_each_entry(ep, &udc->gadget.ep_list, usb_ep.ep_list) { -+ ep->desc = NULL; -+ } -+ -+ udc->gadget.dev.driver = NULL; -+ udc->gadget_driver = NULL; -+} -+ -+ -+/**************************************************************************** -+ * Control Endpoint SETUP related routines. -+ * -+ * iproc_ep_setup_init - Prepares for next SETUP Rx. Status indicates if STALL req'd. -+ * iproc_ep_setup_process - Handle Rx of a SETUP. -+ ***************************************************************************/ -+static void iproc_ep_setup_init(struct iproc_ep *ep, int status) -+{ -+ struct iproc_udc *udc = ep->udc; -+ -+ /* Re-enable transfers to the SETUP buffer, clear IN and OUT NAKs, and re-enable OUT interrupts. */ -+ ep->dma.vir_addr->setup.status = cpu_to_le32(IPROC_USBD_REG_DMA_STAT_BUF_HOST_READY); -+ ep->dir = USB_DIR_OUT; -+ ep->stopped = 0; -+ -+ if (status == ENOERROR) { -+ /* Handling of previous SETUP was OK. Just clear any NAKs. */ -+ -+ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, USB_DIR_OUT); -+ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, USB_DIR_IN); -+ } else { -+ /* -+ * Handling of previous SETUP failed. Set the STALL. This will get cleared -+ * when the next SETUP is rx'd. -+ */ -+ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, USB_DIR_IN); -+ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, USB_DIR_OUT); -+ } -+ -+ iproc_usbd_ep_irq_en(udc->usbd_regs, ep->num, USB_DIR_OUT); -+ iproc_usbd_ep_dma_en(udc->usbd_regs, ep->num, USB_DIR_OUT); -+} -+ -+void iproc_ep_setup_process(struct iproc_ep *ep, struct usb_ctrlrequest *setup) -+{ -+ struct iproc_udc *udc = ep->udc; -+ uint value; -+ uint index; -+ uint length; -+ int status; -+ -+ value = le16_to_cpu(setup->wValue); -+ index = le16_to_cpu(setup->wIndex); -+ length = le16_to_cpu(setup->wLength); -+ -+ /* -+ * Any SETUP packets appearing here need to be handled by the gadget driver. Some SETUPs may have -+ * already been silently handled and acknowledged by the DWC UDC. The exceptions to this rule are the -+ * USB_REQ_SET_CONFIGURATION and USB_REQ_SET_INTERFACE, which have been only partially handled with -+ * the expectation that some additional software processing is required in order to complete these requests. -+ * Thus, they have not been acknowledged by the DWC UDC. There is no DATA stage for these requests. -+ */ -+ -+ /* -+ * Set the direction of the subsequent DATA stage of a control transfer. This is an -+ * optional stage. It may not exist for all control transfers. If there is a DATA -+ * stage, this info is used for DMA operations for any requests received from the -+ * Gadget driver. -+ */ -+ -+ ep->dir = setup->bRequestType & USB_ENDPOINT_DIR_MASK; -+ -+ if (ep->num != 0) { -+ /** @todo Make changes here if the Linux USB gadget ever supports a control endpoint other -+ * than endpoint 0. The DWC UDC supports multiple control endpoints, and this driver has -+ * been written with this in mind. To make things work, really need to change the Gadget -+ * setup() callback parameters to provide an endpoint context, or add something similar -+ * to the usb_ep structure, or possibly use a usb_request to hold a setup data packet. -+ */ -+ -+ dev_err(udc->dev, "%s: control transfer not supported\n", ep->usb_ep.name); -+ status = -EOPNOTSUPP; -+ } else { -+ /* -+ * Forward the SETUP to the gadget driver for processing. The appropriate directional -+ * interrupt and NAK clear will happen when the DATA stage request is queued. -+ */ -+ spin_unlock(&udc->lock); -+ status = udc->gadget_driver->setup(&udc->gadget, setup); -+ spin_lock(&udc->lock); -+ } -+ -+ if (status < 0) { -+ /* -+ * Error occurred during the processing of the SETUP, so enable STALL. This condition -+ * can only be cleared with the RX of another SETUP, so prepare for that event. -+ */ -+ dev_err(udc->dev, "%s: SETUP %02x.%02x STALL; status=%d\n", -+ ep->usb_ep.name, setup->bRequestType, setup->bRequest, status); -+ -+ iproc_ep_setup_init(ep, status); -+ } else if (length == 0) { -+ /* No DATA stage. Just need to prepare for the next SETUP. */ -+ iproc_ep_setup_init(ep, ENOERROR); -+ } else { -+ /* -+ * The SETUP stage processing has completed OK, and there may or may not be a request queued -+ * for the DATA stage. When the DATA stage completes, preparation for the RX of the next -+ * SETUP will be done. -+ */ -+ } -+} -+ -+ -+/**************************************************************************** -+ * IRQ routines. -+ * -+ * xgs_iproc_udc_isr - top level entry point. -+ * iproc_cfg_isr - device (endpoint 0) set config interrupt handler -+ * iproc_inf_isr - device (endpoint 0) set interface interrupt handler -+ * iproc_speed_isr - device speed enumeration done interrupt handler -+ * iproc_ep_in_isr - top level IN endpoint related interrupt handler -+ * iproc_ep_out_isr - top level OUT endpoint related interrupt handler -+ * iproc_ep_out_setup_isr - Control endpoint SETUP Rx handler. This may get -+ * called directly as the result of an endpoint OUT interrupt, or -+ * indirectly as the result of device SET_CFG or SET_INTF. -+ ***************************************************************************/ -+static void iproc_cfg_isr(struct iproc_udc *udc) -+{ -+ struct usb_ctrlrequest setup; -+ int idx; -+ u16 cfg; -+ -+ /* -+ * Device Configuration SETUP has been received. This is not placed in the SETUP -+ * DMA buffer. The packet has to be re-created here so it can be forwarded to the -+ * gadget driver to act upon. -+ */ -+ -+ cfg = (u16) iproc_usbd_cfg_num(udc->usbd_regs); -+ -+ setup.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE; -+ setup.bRequest = USB_REQ_SET_CONFIGURATION; -+ setup.wValue = cpu_to_le16(cfg); -+ setup.wIndex = 0; -+ setup.wLength = 0; -+ -+ /* -+ * Setting the configuration number before the gadget responds is a bit presumptious, but should -+ * not be fatal. -+ */ -+ /** @todo Do not set endpoint 0? Or is it a don't care? */ -+ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { -+ iproc_usbd_ep_cfg_set(udc->usbd_regs, idx, cfg); -+ } -+ -+ printk(KERN_INFO "SET CFG=%d\n", cfg); -+ -+ iproc_ep_setup_process(&udc->ep[0], &setup); -+ iproc_usbd_setup_done(udc->usbd_regs); -+} -+ -+static void iproc_inf_isr(struct iproc_udc *udc) -+{ -+ struct usb_ctrlrequest setup; -+ uint idx; -+ u16 intf; -+ u16 alt; -+ -+ /* -+ * Device Interface SETUP has been received. This is not placed in the SETUP -+ * DMA buffer. The packet has to be re-created here so it can be forwarded to the -+ * gadget driver to act upon. -+ */ -+ intf = (u16)iproc_usbd_intf_num(udc->usbd_regs); -+ alt = (u16)iproc_usbd_alt_num(udc->usbd_regs); -+ -+ setup.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_INTERFACE; -+ setup.bRequest = USB_REQ_SET_INTERFACE; -+ setup.wValue = cpu_to_le16(alt); -+ setup.wIndex = cpu_to_le16(intf); -+ setup.wLength = 0; -+ -+ /* -+ * Setting the interface numbers before the gadget responds is a bit presumptious, but should -+ * not be fatal. -+ */ -+ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { -+ iproc_usbd_ep_alt_set(udc->usbd_regs, idx, alt); -+ iproc_usbd_ep_intf_set(udc->usbd_regs, idx, intf); -+ } -+ -+ iproc_ep_setup_process(&udc->ep[0], &setup); -+ iproc_usbd_setup_done(udc->usbd_regs); -+} -+ -+static void iproc_speed_isr(struct iproc_udc *udc) -+{ -+ uint speed; -+ -+ speed = udc->gadget.speed; -+ -+ switch(iproc_usbd_speed_get(udc->usbd_regs)) { -+ case IPROC_USBD_SPEED_HIGH: -+ printk(KERN_INFO "HIGH SPEED\n"); -+ udc->gadget.speed = USB_SPEED_HIGH; -+ break; -+ case IPROC_USBD_SPEED_FULL: -+ printk(KERN_INFO "FULL SPEED\n"); -+ udc->gadget.speed = USB_SPEED_FULL; -+ break; -+ case IPROC_USBD_SPEED_LOW: -+ dev_warn(udc->dev, "low speed not supported\n"); -+ udc->gadget.speed = USB_SPEED_LOW; -+ break; -+ default: -+ dev_err(udc->dev, "unknown speed=0x%x\n", iproc_usbd_speed_get(udc->usbd_regs)); -+ break; -+ } -+ -+ if ((speed == USB_SPEED_UNKNOWN) && (udc->gadget.speed != USB_SPEED_UNKNOWN)) { -+ /* -+ * Speed has not been enumerated before, so now we can initialize transfers on endpoint 0. -+ * Also have to disable the NAKs at a global level, which has been in place while waiting -+ * for enumeration to complete. -+ */ -+ iproc_ep_setup_init(&udc->ep[0], ENOERROR); -+ iproc_usbd_nak_response_dis(udc->usbd_regs); -+ } -+} -+ -+static void iproc_ep_in_isr(struct iproc_ep *ep) -+{ -+ struct iproc_udc *udc = ep->udc; -+ uint status; -+ -+ status = iproc_usbd_ep_stat_active(udc->usbd_regs, ep->num, USB_DIR_IN); -+ iproc_usbd_ep_stat_clear(udc->usbd_regs, ep->num, USB_DIR_IN, status); -+ -+ if (!status) { -+ return; -+ } -+ -+ /** @todo check might only be for direction... */ -+ if ((ep->dir != USB_DIR_IN) && (ep->type != USB_ENDPOINT_XFER_CONTROL)) { -+ dev_err(udc->dev, "%s: unexpected IN interrupt\n", ep->usb_ep.name); -+ return; -+ } -+ -+ if (ep->dir != USB_DIR_IN) { -+ /* This probably should not be happening */ -+ dev_warn(udc->dev, "%s: CTRL dir OUT\n", ep->usb_ep.name); -+ } -+ -+ if ((ep->type == USB_ENDPOINT_XFER_ISOC) && -+ (status & (IPROC_USBD_EP_STAT_IN_XFER_DONE | IPROC_USBD_EP_STAT_DMA_BUF_UNAVAIL))) { -+ dev_warn(udc->dev, "%s: ISOC IN unexpected status=0x%x\n", ep->usb_ep.name, status); -+ } -+ -+ if (status & IPROC_USBD_EP_STAT_IN_TOKEN_RX) { -+ /* -+ * If there's any IN requests, the DMA should be setup and ready to go if -+ * the endpoint is not an ISOC. Nothing to do in this case. However, if -+ * this is an ISOC endpoint, then this interrupt implies there was no -+ * data available for this frame number. This will happen if the gadget -+ * does not have any data queued to send in this frame, or we have been -+ * waiting for this event to occur so we can get alignment with the host -+ * for the interval. This alignment is necessary when the interval is -+ * greater than one frame / uframe. E.g. for an audio stream sending -+ * samples @ 5ms intervals on a FS link, this corresponds to a period -+ * of 5 frames. Samples with be queued for every 5th frame number after -+ * the frame number in which this interrupt occurred. -+ */ -+ status &= ~IPROC_USBD_EP_STAT_IN_TOKEN_RX; -+ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, USB_DIR_IN); -+ -+ if ((ep->type == USB_ENDPOINT_XFER_ISOC)) { -+ /* Always align to the current frame number for subsequent transfers. */ -+ ep->dma.frame_num = iproc_usbd_last_rx_frame_num(udc->usbd_regs); -+ if (ep->dma.usb_req != NULL) { -+ /* -+ * Might have something queued when waiting for alignment. If something is queued, -+ * it is already too late for the current transfer point. It will also have been -+ * placed in the queue at some point before this interrupt, and it will be stale -+ * if we try to transmit at the next transfer point. -+ */ -+ ep->dma.usb_req->status = -EREMOTEIO; -+ iproc_udc_req_xfer_process(ep); -+ } -+ } -+ } -+ -+ if (status & IPROC_USBD_EP_STAT_IN_DMA_DONE) { -+ /* -+ * DMA has completed, but cannot start next transfer until IPROC_USBD_EP_STAT_IN_XFER_DONE. -+ * To avoid race conditions and other issues, do not release the current transfer until both -+ * interrupts have arrived. Normally this interrupt will arrive at or before the IN_XFER_DONE, -+ * but there have been situations when the system is under load that this interrupt might -+ * arrive after the IN_XFER_DONE, in which case we will need to do the processing now. -+ * The exception to this rule is for ISOC endpoints. They will only get this interrupt to -+ * indicate that DMA has completed. -+ */ -+ status &= ~IPROC_USBD_EP_STAT_IN_DMA_DONE; -+ -+ if ((ep->type == USB_ENDPOINT_XFER_ISOC)) { -+ iproc_udc_req_xfer_process(ep); -+ } else if (ep->dma.done & IPROC_USBD_EP_STAT_IN_XFER_DONE) { -+ /* -+ * Did not receive the IN_DMA_DONE interrupt for this request before or -+ * at the same time as the IN_XFER_DONE interrupt, so the request -+ * processing was postponed until the IN_DMA_DONE interrupt arrived. -+ * See handling of IN_XFER_DONE status below. -+ */ -+ iproc_udc_req_xfer_process(ep); -+ } else { -+ /* -+ * IN_DMA_DONE received. Save this info so request processing will be -+ * done when the IN_XFER_DONE interrupt is received. This may happen -+ * immediately, idx.e. both IN_DMA_DONE and IN_XFER_DONE status are -+ * set when the interrupt processing takes place. -+ */ -+ ep->dma.done = IPROC_USBD_EP_STAT_IN_DMA_DONE; -+ } -+ } -+ -+ if (status & IPROC_USBD_EP_STAT_IN_XFER_DONE) { -+ status &= ~(IPROC_USBD_EP_STAT_IN_XFER_DONE); -+ status &= ~(IPROC_USBD_EP_STAT_IN_FIFO_EMPTY); -+ -+ if (ep->dma.done & IPROC_USBD_EP_STAT_IN_DMA_DONE) { -+ /* -+ * Have received both the IN_DMA_DONE and IN_XFER_DONE interrupts -+ * for this request. OK to process the request (remove the request -+ * and start the next one). -+ */ -+ iproc_udc_req_xfer_process(ep); -+ } else { -+ /* -+ * Have not received the IN_DMA_DONE interrupt for this request. -+ * Need to postpone processing of the request until the IN_DMA_DONE -+ * interrupt occurs. See handling of IN_DMA_DONE status above. -+ */ -+ ep->dma.done = IPROC_USBD_EP_STAT_IN_XFER_DONE; -+ } -+ } -+ -+ /* Clear the FIFO EMPTY bit, not to print error message */ -+ status &= ~(IPROC_USBD_EP_STAT_IN_FIFO_EMPTY); -+ -+ if (status & IPROC_USBD_EP_STAT_DMA_BUF_UNAVAIL) { -+ dev_err(udc->dev, "%s: DMA BUF NOT AVAIL\n", ep->usb_ep.name); -+ status &= ~(IPROC_USBD_EP_STAT_DMA_BUF_UNAVAIL); -+ iproc_udc_req_xfer_process(ep); -+ } -+ -+ if (status & IPROC_USBD_EP_STAT_DMA_ERROR) { -+ status &= ~IPROC_USBD_EP_STAT_DMA_ERROR; -+ dev_err(udc->dev, "%s: DMA ERROR\n", ep->usb_ep.name); -+ iproc_udc_req_xfer_error(ep, -EIO); -+ } -+ -+ if (status) { -+ dev_err(udc->dev, "exit: %s %s: unknown status=0x%x\n", __func__, ep->usb_ep.name, status); -+ } -+} -+ -+static void iproc_ep_out_setup_isr(struct iproc_ep *ep) -+{ -+ struct iproc_udc *udc = ep->udc; -+ struct iproc_udc_dma_setup *dma; -+ -+ dma = &ep->dma.vir_addr->setup; -+ if ((IPROC_USBD_READ(dma->status) & IPROC_USBD_REG_DMA_STAT_BUF_MASK) != IPROC_USBD_REG_DMA_STAT_BUF_DMA_DONE) { -+ dev_err(udc->dev, "%s: unexpected DMA buf status=0x%x\n", ep->usb_ep.name, (IPROC_USBD_READ(dma->status) & IPROC_USBD_REG_DMA_STAT_BUF_MASK)); -+ iproc_ep_setup_init(ep, ENOERROR); -+ } else if ((IPROC_USBD_READ(dma->status) & IPROC_USBD_REG_DMA_STAT_RX_MASK) != IPROC_USBD_REG_DMA_STAT_RX_SUCCESS) { -+ dev_err(udc->dev, "%s: unexpected DMA rx status=0x%x\n", ep->usb_ep.name, (IPROC_USBD_READ(dma->status) & IPROC_USBD_REG_DMA_STAT_RX_MASK)); -+ iproc_ep_setup_init(ep, ENOERROR); -+ } else { -+ if (ep->num != 0) { -+ /** @todo Handle the cfg / intf / alt fields of the DMA status. This will only be any issue -+ * once the Linux Gadget driver framework supports control transfers on an endpoint other -+ * than 0. -+ */ -+ dev_warn(udc->dev, "%s: CTRL xfr support not complete\n", ep->usb_ep.name); -+ } -+ /* -+ * Take ownership of the descriptor while processing the request. Ownership will be released -+ * when ready to Rx SETUP again. -+ */ -+ IPROC_USBD_BITS_MODIFY(dma->status, IPROC_USBD_REG_DMA_STAT_BUF_MASK, IPROC_USBD_REG_DMA_STAT_BUF_HOST_BUSY); -+ iproc_ep_setup_process(ep, (struct usb_ctrlrequest *)&dma->data1); -+ } -+} -+ -+static void iproc_ep_out_isr(struct iproc_ep *ep) -+{ -+ struct iproc_udc *udc = ep->udc; -+ uint status; -+ -+ status = iproc_usbd_ep_stat_active(udc->usbd_regs, ep->num, USB_DIR_OUT); -+ iproc_usbd_ep_stat_clear(udc->usbd_regs, ep->num, USB_DIR_OUT, status); -+ -+ /* -+ * Remove the Rx packet size field from the status. The datasheet states this field is not used -+ * in DMA mode, but that is not true. -+ */ -+ status &= IPROC_USBD_EP_STAT_ALL; -+ -+ if (!status) { -+ return; -+ } -+ -+ if ((ep->dir != USB_DIR_OUT) && (ep->type != USB_ENDPOINT_XFER_CONTROL)) { -+ dev_err(udc->dev, "%s: unexpected OUT interrupt\n", ep->usb_ep.name); -+ return; -+ } -+ -+ if (ep->dir != USB_DIR_OUT) { -+ /* This probably should not be happening */ -+ dev_err(udc->dev, "%s: CTRL dir IN\n", ep->usb_ep.name); -+ } -+ -+ if (status & IPROC_USBD_EP_STAT_OUT_DMA_DATA_DONE) { -+ status &= ~IPROC_USBD_EP_STAT_OUT_DMA_DATA_DONE; -+ iproc_udc_req_xfer_process(ep); -+ } -+ -+ if (status & IPROC_USBD_EP_STAT_OUT_DMA_SETUP_DONE) { -+ status &= ~IPROC_USBD_EP_STAT_OUT_DMA_SETUP_DONE; -+ iproc_ep_out_setup_isr(ep); -+ } -+ -+ if (status & IPROC_USBD_EP_STAT_DMA_BUF_UNAVAIL) { -+ /** @todo Verify under what situations this can happen. Should be when chain has emptied but last desc not reached */ -+ /** @todo status for desc updates */ -+ -+ status &= ~IPROC_USBD_EP_STAT_DMA_BUF_UNAVAIL; -+ dev_err(udc->dev, "%s: DMA BUF NOT AVAIL\n", ep->usb_ep.name); -+ iproc_udc_req_xfer_process(ep); -+ } -+ -+ if (status & IPROC_USBD_EP_STAT_DMA_ERROR) { -+ status &= ~IPROC_USBD_EP_STAT_DMA_ERROR; -+ dev_err(udc->dev, "%s: DMA ERROR\n", ep->usb_ep.name); -+ /** @todo merge XferError and XferProcess?? */ -+ iproc_udc_req_xfer_error(ep, -EIO); -+ } -+ -+ if (status) { -+ dev_err(udc->dev, "%s: unknown status=0x%x\n", ep->usb_ep.name, status); -+ } -+} -+ -+irqreturn_t xgs_iproc_udc_isr(int irq, void *context) -+{ -+ struct iproc_udc *udc = NULL; -+ ulong flags; -+ uint stat, epin_stat, epout_stat; -+ int idx; -+ -+ udc = (struct iproc_udc *)context; -+ -+ spin_lock_irqsave(&udc->lock, flags); -+ -+ if (!udc || !udc->gadget_driver) { -+ dev_err(udc->dev, "Invalid context or no driver registered: irq dev=0x%x\n", iproc_usbd_irq_active(udc->usbd_regs)); -+ -+ iproc_usbd_irq_clear(udc->usbd_regs, IPROC_USBD_IRQ_ALL); -+ iproc_usbd_ep_irq_list_clear(udc->usbd_regs, USB_DIR_IN, ~0); -+ iproc_usbd_ep_irq_list_clear(udc->usbd_regs, USB_DIR_OUT, ~0); -+ -+ spin_unlock_irqrestore(&udc->lock, flags); -+ return IRQ_HANDLED; -+ } -+ -+ stat = iproc_usbd_irq_active(udc->usbd_regs); -+ epin_stat = iproc_usbd_ep_irq_list_active(udc->usbd_regs, USB_DIR_IN); -+ epout_stat = iproc_usbd_ep_irq_list_active(udc->usbd_regs, USB_DIR_OUT); -+ -+ if (!(stat || epin_stat || epout_stat)) { -+ return IRQ_NONE; -+ } -+ -+ iproc_usbd_irq_clear(udc->usbd_regs, stat); -+ iproc_usbd_ep_irq_list_clear(udc->usbd_regs, USB_DIR_IN, epin_stat); -+ iproc_usbd_ep_irq_list_clear(udc->usbd_regs, USB_DIR_OUT, epout_stat); -+ -+ /* -+ * Handle the SET_CFG and SET_INTF interrupts after the endpoint and other device interrupts. -+ * There can be some race conditions where we have an endpoint 0 interrupt pending for the -+ * completion of a previous endpoint 0 transfer (e.g. a GET config) when a SETUP arrives -+ * corresponding to the SET_CFG and SET_INTF. Need to complete the processing of the previous -+ * transfer before handling the next one, idx.e. the SET_CFG or SET_INTF. -+ */ -+ if (stat & IPROC_USBD_IRQ_BUS_RESET) { -+ printk(KERN_INFO "BUS reset\n"); -+ } -+ if (stat & IPROC_USBD_IRQ_BUS_SUSPEND) { -+ dev_dbg(udc->dev, "BUS suspend\n"); -+ } -+ if (stat & IPROC_USBD_IRQ_BUS_IDLE) { -+ dev_dbg(udc->dev, "BUS idle\n"); -+ iproc_udc_ops_disconnect(udc); -+ } -+ if (stat & IPROC_USBD_IRQ_SPEED_ENUM_DONE) { -+ dev_dbg(udc->dev, "BUS speed enum done\n"); -+ iproc_speed_isr(udc); -+ } -+ -+ /* endpoint interrupts handler */ -+ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { -+ if (epin_stat & (1 << idx)) { -+ iproc_ep_in_isr(&udc->ep[idx]); -+ } -+ if (epout_stat & (1 << idx)) { -+ iproc_ep_out_isr(&udc->ep[idx]); -+ } -+ } -+ -+ /* SET_CFG and SET_INTF interrupts handler */ -+ if (stat & IPROC_USBD_IRQ_SET_CFG) { -+ iproc_cfg_isr(udc); -+ } -+ if (stat & IPROC_USBD_IRQ_SET_INTF) { -+ iproc_inf_isr(udc); -+ } -+ -+ spin_unlock_irqrestore(&udc->lock, flags); -+ -+ return IRQ_HANDLED; -+} -+ -+/*************************************************************************** -+* Endpoint request operations -+***************************************************************************/ -+static void iproc_udc_req_queue_flush(struct iproc_ep *ep, int status) -+{ -+ struct iproc_udc *udc = ep->udc; -+ struct iproc_ep_req *req; -+ -+ ep->stopped = 1; -+ iproc_usbd_ep_ops_finish(udc->usbd_regs, ep->num); -+ -+ while (!list_empty(&ep->list_queue)) { -+ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); -+ iproc_udc_req_xfer_done(ep, req, status); -+ } -+ ep->dma.usb_req = NULL; -+} -+ -+ -+static void iproc_udc_req_xfer_add(struct iproc_ep *ep, struct iproc_ep_req *req) -+{ -+ struct iproc_udc *udc = ep->udc; -+ list_add_tail(&req->list_node, &ep->list_queue); -+ -+ /** @todo Is this necessary?? Stopped happens as a result of a halt, complete(), dequeue(), nuke(). -+ * nuke() is called when ep disabled, during setup processing, and by udc_queisce(). The latter is -+ * called during vbus state change (cable insert/remove), USB reset interrupt, and gadget deregister. -+ */ -+ if (ep->stopped) { -+ return; -+ } -+ -+ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC) && ep->dma.usb_req && (ep->dma.frame_num == FRAME_NUM_INVALID)) { -+ /* -+ * Gadget has a request already queued, but still have not received an IN token from the host -+ * and the interval window is not aligned. Queued packet is now very stale, so remove it. -+ */ -+ -+ iproc_dma_data_finish(ep); -+ /** @todo Move set of ep->dma.usb_req to iproc_dma_data_init() and iproc_dma_data_finish() routines. */ -+ ep->dma.usb_req = NULL; -+ iproc_udc_req_xfer_done(ep, list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node), -EREMOTEIO); -+ } -+ -+ /** @todo Current transfer is always the queue head. Do we need a separate pointer? Maybe just a pointer to usb_request -+ * need to know if the queue head has already been loaded. Maybe that's the point of the "stopped". -+ */ -+ if (!ep->dma.usb_req) { -+ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC) && -+ (ep->dma.frame_num == FRAME_NUM_INVALID)) { -+ /* -+ * Delay any ISOC IN DMA operations until it is known what frame number the host -+ * is going to start transfers with. Normally might just return requests until -+ * this event occurs. However, the zero gadget does not submit requests based on -+ * its own timer or similar, so if the request is returned right away things are -+ * going to thrash, as another request will be immediately submitted. -+ */ -+ ep->dma.usb_req = &(list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node))->usb_req; -+ iproc_dma_data_init(ep); -+ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, ep->dir); -+ iproc_usbd_ep_irq_en(udc->usbd_regs, ep->num, ep->dir); -+ } else { -+ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); -+ ep->dma.usb_req = &req->usb_req; -+ iproc_dma_data_init(ep); -+ iproc_dma_data_add_ready(ep); -+ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, ep->dir); -+ iproc_usbd_ep_dma_en(udc->usbd_regs, ep->num, ep->dir); -+ -+ /* needed for gadget commands to complete correctly - possible locking issue */ -+ mdelay(3); -+ } -+ } -+} -+ -+static void iproc_udc_req_xfer_done(struct iproc_ep *ep, struct iproc_ep_req *req, int status) -+{ -+ struct iproc_udc *udc = ep->udc; -+ uint stopped; -+ -+ list_del_init(&req->list_node); -+ -+ if (req->usb_req.status == -EINPROGRESS) { -+ req->usb_req.status = status; -+ } -+ -+ if (req->dma_aligned) { -+ req->dma_aligned = 0; -+ } else if (req->dma_mapped) { -+ /* -+ * A physical address was not provided for the DMA buffer. Release any resources -+ * that were requested by the driver. -+ */ -+ dma_unmap_single(udc->gadget.dev.parent, req->usb_req.dma, req->usb_req.length, -+ (ep->dir == USB_DIR_IN ? DMA_TO_DEVICE : DMA_FROM_DEVICE)); -+ -+ req->dma_mapped = 0; -+ req->usb_req.dma = DMA_ADDR_INVALID; -+ } -+ -+ /* -+ * Disable DMA operations during completion callback. The callback may cause requests to be -+ * added to the queue, but we don't want to change the state of the queue head. -+ */ -+ stopped = ep->stopped; -+ ep->stopped = 1; -+ spin_unlock(&udc->lock); -+ req->usb_req.complete(&ep->usb_ep, &req->usb_req); -+ spin_lock(&udc->lock); -+ ep->stopped = stopped; -+} -+ -+static void iproc_udc_req_xfer_error(struct iproc_ep *ep, int status) -+{ -+ struct iproc_udc *udc = ep->udc; -+ -+ if (!ep->dma.usb_req) { -+ dev_err(udc->dev, "%s: No request being transferred\n", ep->usb_ep.name); -+ return; -+ } -+ -+ /** @todo abort current DMA, start next transfer if there is one. */ -+ ep->dma.usb_req->status = status; -+ iproc_udc_req_xfer_process(ep); -+} -+ -+static void iproc_udc_req_xfer_process(struct iproc_ep *ep) -+{ -+ struct iproc_udc *udc = ep->udc; -+ struct iproc_ep_req *req; -+ -+ /** @todo Current transfer is always the queue head. Do we need a separate pointer? Maybe just a pointer to usb_request */ -+ if (!ep->dma.usb_req) { -+ dev_err(udc->dev, "%s: No request being transferred\n", ep->usb_ep.name); -+ return; -+ } -+ -+ iproc_usbd_ep_dma_dis(udc->usbd_regs, ep->num, ep->dir); -+ iproc_dma_data_rm_done(ep); -+ -+ if (ep->dma.usb_req->status != -EINPROGRESS) { -+ /* -+ * Current transfer stage has finished. This may or may not be with error. -+ * Complete the transfer as needed before starting the next one, if any. -+ */ -+ iproc_dma_data_finish(ep); -+ -+ if ((ep->type == USB_ENDPOINT_XFER_CONTROL) && (ep->dir == USB_DIR_IN) && (ep->dma.usb_req->status == ENOERROR)) { -+ /* -+ * For the status phase of control IN transfers, the hardware requires that an OUT DMA transfer -+ * actually takes place. This should be just an OUT ZLP, and we will re-use the IN buffer that -+ * just completed transfer for this purpose. There should be no harm in doing this, even if the -+ * OUT status is more than a ZLP. -+ */ -+ ep->dir = USB_DIR_OUT; -+ iproc_dma_data_init(ep); -+ } else { -+ /* -+ * All transfer stages have completed. Return the request to the gadget driver, and then -+ * setup for the next transfer. -+ */ -+ iproc_udc_req_xfer_done(ep, list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node), ENOERROR); -+ -+ if (ep->type == USB_ENDPOINT_XFER_CONTROL) { -+ iproc_ep_setup_init(ep, ENOERROR); -+ } -+ -+ if (list_empty(&ep->list_queue)) { -+ /** @todo Probably should more closely bind this to iproc_dma_data_finish. */ -+ ep->dma.usb_req = NULL; -+ } else { -+ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); -+ ep->dma.usb_req = &req->usb_req; -+ iproc_dma_data_init(ep); -+ } -+ } -+ } -+ -+ if (ep->dma.usb_req != NULL) { -+ iproc_dma_data_add_ready(ep); -+ iproc_usbd_ep_dma_en(udc->usbd_regs, ep->num, ep->dir); -+ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, ep->dir); -+ } -+} -+ -+ -+/*************************************************************************** -+ * Linux proc file system functions -+ ***************************************************************************/ -+#ifdef CONFIG_USB_GADGET_DEBUG_FILES -+#include -+ -+static const char udc_proc_file_name[] = "driver/" XGS_IPROC_UDC_NAME; -+ -+static int proc_file_show(struct seq_file *s, void *_) -+{ -+ return(0); -+} -+ -+static int proc_file_open(struct inode *inode, struct file *file) -+{ -+ return(single_open(file, proc_file_show, NULL)); -+} -+ -+static struct file_operations udc_proc_file_ops = -+{ -+ .open = proc_file_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+static void xgs_iproc_udc_proc_create(void) -+{ -+ struct proc_dir_entry *pde; -+ -+ pde = create_proc_entry (udc_proc_file_name, 0, NULL); -+ if (pde) { -+ pde->proc_fops = &udc_proc_file_ops; -+ } -+} -+ -+static void xgs_iproc_udc_proc_remove(void) -+{ -+ remove_proc_entry(udc_proc_file_name, NULL); -+} -+ -+#else -+ -+static void xgs_iproc_udc_proc_create(void) {} -+static void xgs_iproc_udc_proc_remove(void) {} -+ -+#endif -+ -+static const struct of_device_id xgs_iproc_udc_ids[] = { -+ { .compatible = "brcm,usbd,hx4", }, -+ { .compatible = "brcm,usbd,kt2", }, -+ { .compatible = "brcm,usbd,gh", }, -+ { .compatible = "brcm,usbd,sb2", }, -+ { .compatible = "brcm,usbd,hr3", }, -+ { .compatible = "brcm,usbd,gh2", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, xgs_iproc_udc_ids); -+ -+/**************************************************************************** -+ ***************************************************************************/ -+static int xgs_iproc_udc_probe(struct platform_device *pdev) -+{ -+ int ret = ENOERROR; -+ struct device *dev = &pdev->dev; -+ struct device_node *dn = dev->of_node; -+ const struct of_device_id *match; -+ struct iproc_udc *udc = NULL; -+ struct usb_phy *phy; -+ int irq; -+ -+ phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0); -+ if (IS_ERR(phy)) { -+ dev_err(dev, "unable to find transceiver\n"); -+ return PTR_ERR(phy); -+ } -+ -+ if (phy->flags != IPROC_USB_MODE_DEVICE) -+ return -ENODEV; -+ -+ match = of_match_device(xgs_iproc_udc_ids, dev); -+ if (!match) { -+ dev_err(dev, "failed to find USBD in DT\n"); -+ return -ENODEV; -+ } -+ -+ irq = (uint)irq_of_parse_and_map(dn, 0); -+ -+ udc = devm_kzalloc(dev, sizeof(*udc), GFP_KERNEL); -+ if (!udc) { -+ dev_err(dev, "devm_kzalloc() failed\n" ); -+ ret = -ENOMEM; -+ goto err1; -+ } -+ platform_set_drvdata(pdev, udc); -+ -+ udc->dev = dev; -+ spin_lock_init(&udc->lock); -+ -+ udc->usbd_regs = (struct iproc_usbd_regs *)of_iomap(dn, 0); -+ if (!udc->usbd_regs) { -+ dev_err(dev, "unable to iomap USB2D base address\n"); -+ ret = -ENXIO; -+ goto err1; -+ } -+ -+ ret = usb_phy_init(phy); -+ if (ret < 0) { -+ dev_err(dev, "initial usb transceiver failed.\n"); -+ goto err1; -+ } -+ -+ ret = iproc_platform_dma_alloc(pdev, udc); -+ if (ret < 0) { -+ dev_err(dev, "iproc_platform_dma_alloc() failed\n"); -+ goto err1; -+ } -+ -+ /* gadget init */ -+ udc->gadget.name = XGS_IPROC_UDC_NAME; -+ udc->gadget.speed = USB_SPEED_UNKNOWN; -+ udc->gadget.max_speed = USB_SPEED_HIGH; -+ udc->gadget.ops = &xgs_iproc_udc_ops; -+ -+ iproc_udc_ops_init(udc); -+ -+ iproc_usbd_irq_dis(udc->usbd_regs, IPROC_USBD_IRQ_ALL); -+ iproc_usbd_irq_clear(udc->usbd_regs, IPROC_USBD_IRQ_ALL); -+ -+ ret = devm_request_irq(dev, irq, xgs_iproc_udc_isr, 0, -+ XGS_IPROC_UDC_NAME, (void *)udc); -+ if (ret < 0) { -+ dev_err(dev, "error requesting IRQ #%d\n", irq); -+ goto err2; -+ } -+ -+ ret = usb_add_gadget_udc(dev, &udc->gadget); -+ if (ret < 0) { -+ dev_err(dev, "usb_add_gadget_udc() failed\n"); -+ goto err3; -+ } -+ -+ xgs_iproc_udc_proc_create(); -+ -+ return ENOERROR; -+ -+ -+err3: -+ devm_free_irq(dev, irq, udc); -+err2: -+ iproc_platform_dma_free(pdev, udc); -+err1: -+ if (udc->usbd_regs) { -+ iounmap(udc->usbd_regs); -+ udc->usbd_regs = NULL; -+ } -+ if (udc) { -+ kfree(udc); -+ } -+ -+ return ret; -+} -+ -+static int xgs_iproc_udc_remove(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct iproc_udc *udc = platform_get_drvdata(pdev); -+ struct device_node *dn = pdev->dev.of_node; -+ int irq = (uint)irq_of_parse_and_map(dn, 0); -+ -+ if (udc) { -+ xgs_iproc_udc_proc_remove(); -+ -+ usb_del_gadget_udc(&udc->gadget); -+ iproc_udc_ops_finish(udc); -+ -+ platform_set_drvdata(pdev, NULL); -+ iproc_platform_dma_free(pdev, udc); -+ devm_free_irq(dev, irq, udc); -+ -+ if (udc->usbd_regs) { -+ iounmap(udc->usbd_regs); -+ udc->usbd_regs = NULL; -+ } -+ -+ kfree(udc); -+ } -+ -+ return ENOERROR; -+} -+ -+/* -+ * Generic platform device driver definition. -+ */ -+static struct platform_driver xgs_iproc_udc_driver = -+{ -+ .probe = xgs_iproc_udc_probe, -+ .remove = xgs_iproc_udc_remove, -+ .driver = { -+ .name = XGS_IPROC_UDC_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(xgs_iproc_udc_ids), -+ }, -+}; -+ -+module_platform_driver(xgs_iproc_udc_driver); -+ -+MODULE_DESCRIPTION("Broadcom USB Device Controller(UDC) driver"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION("1.0.0"); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/xgs_iproc_udc.h b/drivers/usb/gadget/udc/xgs_iproc_udc.h ---- a/drivers/usb/gadget/udc/xgs_iproc_udc.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/usb/gadget/udc/xgs_iproc_udc.h 2017-11-09 17:54:01.737429000 +0800 -@@ -0,0 +1,158 @@ -+/***************************************************************************** -+* Copyright 2006 - 2010 Broadcom Corporation. All rights reserved. -+* -+* Unless you and Broadcom execute a separate written software license -+* agreement governing use of this software, this software is licensed to you -+* under the terms of the GNU General Public License version 2, available at -+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). -+* -+* Notwithstanding the above, under no circumstances may you combine this -+* software in any way with any other Broadcom software provided under a -+* license other than the GPL, without Broadcom's express prior written -+* consent. -+*****************************************************************************/ -+#ifndef _XGS_IPROC_UDC_H_ -+#define _XGS_IPROC_UDC_H_ -+ -+#include -+#include "xgs_usbd_regs.h" -+ -+#define IPROC_UDC_EP_CNT 7 -+#define IPROC_UDC_CTRL_MAX_PKG_SIZE 64 -+#define IPROC_UDC_EP_MAX_PKG_SIZE 512 -+ -+/* -+ * Some unsigned number trickery for indexing into DMA descriptor chain. If the -+ * decriptor count is some power of 2, then we can use the mask to extract -+ * an index and not worry about wrap around as the unsigned variables are -+ * incremented. E.g. in following, IDX(0), IDX(4), IDX(8), ..., IDX(0xffffc) -+ * all produce the same result, i.e. 0. -+ */ -+#define IPROC_EP_DMA_DESC_CNT 1 -+#define IPROC_EP_DMA_DESC_IDX_MASK (IPROC_EP_DMA_DESC_CNT - 1) -+#define IPROC_EP_DMA_DESC_IDX(_idx) ((_idx) & IPROC_EP_DMA_DESC_IDX_MASK) -+ -+/* Some DWC UDC DMA descriptor layout definitions. See datasheet for details. */ -+ -+struct iproc_udc_dma_setup { -+ unsigned int status; -+ unsigned int reserved; -+ unsigned int data1; -+ unsigned int data2; -+}; -+ -+struct iproc_udc_dma_desc { -+ unsigned int status; -+ unsigned int reserved; -+ unsigned int buf_addr; -+ unsigned int next_addr; -+}; -+ -+/* -+ * Common DMA descriptor layout used for all endpoints. Only control endpoints -+ * need the setup descriptor, but in order to simply things it is defined for -+ * all. It may be possible to omit this altogether, and just use one of data -+ * descriptors for setup instead. The control transfer protocol should allow -+ * this to be done. -+ */ -+struct iproc_ep_dma { -+ struct iproc_udc_dma_setup setup; -+ struct iproc_udc_dma_desc desc[IPROC_EP_DMA_DESC_CNT]; -+}; -+ -+/* Structure used for DMA descriptor allocation. Not really necessary but convenient. */ -+ -+struct iproc_udc_dma { -+ struct iproc_ep_dma ep[IPROC_UDC_EP_CNT]; -+}; -+ -+/* -+ * Structure used to hold endpoint specific information. There's one of these for -+ * each endpoint. -+ * -+ * The Rx/Tx FIFO sizes are used for RAM allocation purposes. Each transfer -+ * direction has its own RAM that is used for all the FIFOs in that direction. -+ * The RAM gets segmented (allocated) as each endpoint gets enabled. This dynamic -+ * allocation FIFO sizes gives flexibility, and does not require that an -+ * endpoint's size be fixed at run-time or during compilation. If there's not -+ * enough FIFO RAM as required by a gadget's endpoint definitions, then an -+ * error will occur for the enabling of any endpoints after the FIFO RAM has -+ * become exhausted. -+ * -+ * The DMA virtual address is used for all descriptor operations. The DMA -+ * physical address is for convenience (setting hardware registers, obtaining -+ * addresses for descriptor chaining, etc.). The DMA descriptors are not -+ * allocated on a per-endpoint basis. These are just pointers into the -+ * large block that was allocated for all endpoints. -+ */ -+struct iproc_ep { -+ struct usb_ep usb_ep; /* usb_gadget.h */ -+ const struct usb_endpoint_descriptor *desc; /* usb/ch9.h */ -+ struct list_head list_queue; /* active BCM_UDC_EP_REQ's for the endpoint */ -+ struct iproc_udc *udc; /* endpoint owner (UDC controller) */ -+ unsigned int num; -+ unsigned int dir; /* USB_DIR_xxx (direction) */ -+ unsigned int type; /* USB_ENDPOINT_XFER_xxx */ -+ unsigned int beq_addr; /* dirn | type */ -+ unsigned int stopped : 1; -+ struct { -+ struct iproc_ep_dma *vir_addr; -+ struct iproc_ep_dma *phy_addr; -+ struct usb_request *usb_req; /* Current request being DMA'd */ -+ -+ /** @todo Some of the below are duplicates of usb_request elements. Use usb_request instead. */ -+ unsigned int max_buf_len; /* Max buffer length to use with a descriptor */ -+ unsigned int done_len; /* Length of request DMA'd so far */ -+ unsigned int todo_len; /* Length of request left to DMA */ -+ unsigned int add_idx; /* descriptor chain index */ -+ unsigned int rm_idx; /* descriptor chain index */ -+ unsigned int buf_addr; /* Location in request to DMA */ -+ unsigned int frame_num; /* Frame number for ISOC transfers */ -+ unsigned int frame_incr; /* Frame number increment (period) */ -+ unsigned int status; -+ unsigned int done; /* DMA and USB transfer completion indication (IN_DMA_DONE and IN_XFER_DONE) */ -+ void *align_buff; /* Aligned buffer. Only used if usb_req buffer not aligned properly. */ -+ dma_addr_t align_addr; /* Aligned buffer physical address */ -+ unsigned int align_len; /* Aligned buffer length */ -+ } dma; -+}; -+ -+/* -+ * Structure used to hold controller information. There should be one of these -+ * for each controller. Most likely there's only one. -+ * -+ * The Rx/Tx FIFO space are used for RAM allocation purposes. These track how -+ * much RAM is available for use as a FIFO. When an endpoint is enabled, these -+ * are check to see if there's enough RAM for a FIFO of the desired length as -+ * implied by the max packet size. -+ */ -+struct iproc_udc { -+ struct usb_gadget gadget; /* usb_gadget.h */ -+ struct usb_gadget_driver *gadget_driver; /* usb_gadget.h */ -+ struct completion *dev_release; /* Used for coordination during device removal */ -+ spinlock_t lock; -+ struct device *dev; -+ unsigned int irq_num; -+ struct iproc_ep ep[IPROC_UDC_EP_CNT]; -+ struct iproc_usbd_regs *usbd_regs; -+ struct { -+ struct iproc_udc_dma *vir_addr; -+ struct iproc_udc_dma *phy_addr; -+ } dma; -+ unsigned int vbus_active : 1; /* Indicates if VBUS is present */ -+ unsigned int pullup_on : 1; /* Indicates if pull up is on */ -+}; -+ -+/* -+ * Structure used to hold an endpoint transfer request. Can be any number of -+ * these for an endpoint. -+ */ -+struct iproc_ep_req { -+ struct usb_request usb_req; /* usb_gadget.h */ -+ struct list_head list_node; /* For linking in the BCM_UDC_EP request queue */ -+ dma_addr_t orig_dma_addr; /* Original buffer DMA address (physical). */ -+ unsigned dma_mapped : 1; /* Indicates if address mapping req'd. See usb_gadget.h */ -+ unsigned dma_aligned : 1; /* Indicates if buffer duplication done for alignment. */ -+}; -+ -+#endif /* _XGS_IPROC_UDC_H_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/xgs_usbd_regs.h b/drivers/usb/gadget/udc/xgs_usbd_regs.h ---- a/drivers/usb/gadget/udc/xgs_usbd_regs.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/usb/gadget/udc/xgs_usbd_regs.h 2017-11-09 17:54:01.738446000 +0800 -@@ -0,0 +1,995 @@ -+/***************************************************************************** -+* Copyright 2003 - 2009 Broadcom Corporation. All rights reserved. -+* -+* Unless you and Broadcom execute a separate written software license -+* agreement governing use of this software, this software is licensed to you -+* under the terms of the GNU General Public License version 2, available at -+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). -+* -+* Notwithstanding the above, under no circumstances may you combine this -+* software in any way with any other Broadcom software provided under a -+* license other than the GPL, without Broadcom's express prior written -+* consent. -+*****************************************************************************/ -+#ifndef _USBD_REGS_H_ -+#define _USBD_REGS_H_ -+ -+#include -+ -+#define IPROC_USBD_MULTI_RX_FIFO 0 -+ -+#define IPROC_USBD_EP_CFG_CNT 10 -+#define IPROC_USBD_REG_EP_CNT 16 -+ -+#define IPROC_USBD_SPEED_UNKNOWN 0 -+#define IPROC_USBD_SPEED_LOW 1 -+#define IPROC_USBD_SPEED_FULL 2 -+#define IPROC_USBD_SPEED_HIGH 3 -+ -+#define IPROC_USBD_EP_DIR_IN 0x80 -+#define IPROC_USBD_EP_DIR_OUT 0x00 -+ -+#define IPROC_USBD_EP_TYPE_CTRL 0 -+#define IPROC_USBD_EP_TYPE_ISOC 1 -+#define IPROC_USBD_EP_TYPE_BULK 2 -+#define IPROC_USBD_EP_TYPE_INTR 3 -+ -+#define IPROC_USBD_IRQ_REMOTEWAKEUP_DELTA IPROC_USBD_REG_INTR_REMOTE_WAKEUP_DELTA -+#define IPROC_USBD_IRQ_SPEED_ENUM_DONE IPROC_USBD_REG_INTR_SPD_ENUM_DONE -+#define IPROC_USBD_IRQ_SOF_DETECTED IPROC_USBD_REG_INTR_SOF_RX -+#define IPROC_USBD_IRQ_BUS_SUSPEND IPROC_USBD_REG_INTR_BUS_SUSPEND -+#define IPROC_USBD_IRQ_BUS_RESET IPROC_USBD_REG_INTR_BUS_RESET -+#define IPROC_USBD_IRQ_BUS_IDLE IPROC_USBD_REG_INTR_BUS_IDLE -+#define IPROC_USBD_IRQ_SET_INTF IPROC_USBD_REG_INTR_SET_INTF_RX -+#define IPROC_USBD_IRQ_SET_CFG IPROC_USBD_REG_INTR_SET_CFG_RX -+#define IPROC_USBD_IRQ_ALL (IPROC_USBD_IRQ_REMOTEWAKEUP_DELTA | \ -+ IPROC_USBD_IRQ_SPEED_ENUM_DONE | \ -+ IPROC_USBD_IRQ_SOF_DETECTED | \ -+ IPROC_USBD_IRQ_BUS_SUSPEND | \ -+ IPROC_USBD_IRQ_BUS_RESET | \ -+ IPROC_USBD_IRQ_BUS_IDLE | \ -+ IPROC_USBD_IRQ_SET_INTF | \ -+ IPROC_USBD_IRQ_SET_CFG) -+ -+#define IPROC_USBD_EP_STAT_DMA_ERROR IPROC_USBD_REG_EP_FIFO_STATUS_AHB_BUS_ERROR -+#define IPROC_USBD_EP_STAT_DMA_BUF_UNAVAIL IPROC_USBD_REG_EP_FIFO_STATUS_DMA_BUF_NOT_AVAIL -+#define IPROC_USBD_EP_STAT_IN_TOKEN_RX IPROC_USBD_REG_EP_FIFO_STATUS_IN_TOKEN_RX -+#define IPROC_USBD_EP_STAT_IN_DMA_DONE IPROC_USBD_REG_EP_FIFO_STATUS_IN_DMA_DONE -+#define IPROC_USBD_EP_STAT_IN_FIFO_EMPTY IPROC_USBD_REG_EP_FIFO_STATUS_IN_FIFO_EMPTY -+#define IPROC_USBD_EP_STAT_IN_XFER_DONE IPROC_USBD_REG_EP_FIFO_STATUS_IN_XFER_DONE -+#define IPROC_USBD_EP_STAT_OUT_DMA_DATA_DONE IPROC_USBD_REG_EP_FIFO_STATUS_OUT_DMA_DATA_DONE -+#define IPROC_USBD_EP_STAT_OUT_DMA_SETUP_DONE IPROC_USBD_REG_EP_FIFO_STATUS_OUT_DMA_SETUP_DONE -+#define IPROC_USBD_EP_STAT_ALL (IPROC_USBD_EP_STAT_DMA_ERROR | \ -+ IPROC_USBD_EP_STAT_DMA_BUF_UNAVAIL | \ -+ IPROC_USBD_EP_STAT_IN_TOKEN_RX | \ -+ IPROC_USBD_EP_STAT_IN_DMA_DONE | \ -+ IPROC_USBD_EP_STAT_IN_XFER_DONE | \ -+ IPROC_USBD_EP_STAT_OUT_DMA_DATA_DONE | \ -+ IPROC_USBD_EP_STAT_OUT_DMA_SETUP_DONE) -+ -+ -+#define REG8_RSVD(start, end) uint8_t rsvd_##start[(end - start) / sizeof(uint8_t)] -+#define REG16_RSVD(start, end) uint16_t rsvd_##start[(end - start) / sizeof(uint16_t)] -+#define REG32_RSVD(start, end) uint rsvd_##start[(end - start) / sizeof(uint)] -+ -+struct iproc_usbd_ep_fifo_regs { -+ uint ctrl; -+ uint status; -+ uint size1; -+ uint size2; /* Buf Size OUT/Max PKT SIZE */ -+ uint buf_addr; -+ uint desc_addr; -+ REG32_RSVD(0x18, 0x20); -+}; -+ -+struct iproc_usbd_regs { -+ struct iproc_usbd_ep_fifo_regs ep_fifo_in[IPROC_USBD_REG_EP_CNT]; -+ struct iproc_usbd_ep_fifo_regs ep_fifo_out[IPROC_USBD_REG_EP_CNT]; -+ uint dev_cfg; -+ uint dev_ctrl; -+ uint dev_status; -+ uint dev_irq_status; -+ uint dev_irq_mask; -+ uint ep_irq_status; -+ uint ep_irq_mask; -+ uint test_mode; -+ uint rel_num; -+ REG32_RSVD(0x424, 0x500); -+ REG32_RSVD(0x500, 0x504); -+ uint ep_cfg[IPROC_USBD_REG_EP_CNT]; -+ REG32_RSVD(0x544, 0x800); -+ uint rx_fifo[256]; -+ uint tx_fifo[256]; -+ uint strap; -+}; -+ -+ -+struct iproc_usbd_idm_regs { -+ REG32_RSVD(0x000, 0x408); -+ uint io_ctrl; -+ REG32_RSVD(0x40C, 0x500); -+ uint io_status; -+ REG32_RSVD(0x504, 0x800); -+ uint reset_ctrl; -+ uint reset_status; -+ REG32_RSVD(0x808, 0xA00); -+ uint irq_status; -+}; -+ -+/* -+ * The endpoint type field in the FIFO control register has the same enumeration -+ * as the USB protocol. Not going to define it here. -+ */ -+#define IPROC_USBD_REG_EP_FIFO_CTRL_OUT_FLUSH_ENABLE (1 << 12) -+#define IPROC_USBD_REG_EP_FIFO_CTRL_OUT_CLOSE_DESC (1 << 11) -+#define IPROC_USBD_REG_EP_FIFO_CTRL_IN_SEND_NULL (1 << 10) -+#define IPROC_USBD_REG_EP_FIFO_CTRL_OUT_DMA_ENABLE (1 << 9) -+#define IPROC_USBD_REG_EP_FIFO_CTRL_NAK_CLEAR (1 << 8) -+#define IPROC_USBD_REG_EP_FIFO_CTRL_NAK_SET (1 << 7) -+#define IPROC_USBD_REG_EP_FIFO_CTRL_NAK_IN_PROGRESS (1 << 6) -+#define IPROC_USBD_REG_EP_FIFO_CTRL_TYPE_SHIFT 4 -+#define IPROC_USBD_REG_EP_FIFO_CTRL_TYPE_MASK (3 << IPROC_USBD_REG_EP_FIFO_CTRL_TYPE_SHIFT) -+#define IPROC_USBD_REG_EP_FIFO_CTRL_IN_DMA_ENABLE (1 << 3) -+#define IPROC_USBD_REG_EP_FIFO_CTRL_SNOOP_ENABLE (1 << 2) -+#define IPROC_USBD_REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE (1 << 1) -+#define IPROC_USBD_REG_EP_FIFO_CTRL_STALL_ENABLE (1 << 0) -+ -+#define IPROC_USBD_REG_EP_FIFO_STATUS_CLOSE_DESC_CLEAR (1 << 28) -+#define IPROC_USBD_REG_EP_FIFO_STATUS_IN_XFER_DONE (1 << 27) -+#define IPROC_USBD_REG_EP_FIFO_STATUS_STALL_SET_RX (1 << 26) -+#define IPROC_USBD_REG_EP_FIFO_STATUS_STALL_CLEAR_RX (1 << 25) -+#define IPROC_USBD_REG_EP_FIFO_STATUS_IN_FIFO_EMPTY (1 << 24) -+#define IPROC_USBD_REG_EP_FIFO_STATUS_IN_DMA_DONE (1 << 10) -+#define IPROC_USBD_REG_EP_FIFO_STATUS_AHB_BUS_ERROR (1 << 9) -+#define IPROC_USBD_REG_EP_FIFO_STATUS_OUT_FIFO_EMPTY (1 << 8) -+#define IPROC_USBD_REG_EP_FIFO_STATUS_DMA_BUF_NOT_AVAIL (1 << 7) -+#define IPROC_USBD_REG_EP_FIFO_STATUS_IN_TOKEN_RX (1 << 6) -+#define IPROC_USBD_REG_EP_FIFO_STATUS_OUT_DMA_SETUP_DONE (1 << 5) -+#define IPROC_USBD_REG_EP_FIFO_STATUS_OUT_DMA_DATA_DONE (1 << 4) -+ -+#define IPROC_USBD_REG_EP_FIFO_SIZE1_OUT_ISOC_PID_SHIFT 16 -+#define IPROC_USBD_REG_EP_FIFO_SIZE1_OUT_ISOC_PID_MASK (3 << IPROC_USBD_REG_EP_FIFO_SIZE1_OUT_ISOC_PID_SHIFT) -+#define IPROC_USBD_REG_EP_FIFO_SIZE1_IN_DEPTH_SHIFT 0 -+#define IPROC_USBD_REG_EP_FIFO_SIZE1_IN_DEPTH_MASK (0xffff << IPROC_USBD_REG_EP_FIFO_SIZE1_IN_DEPTH_SHIFT) -+#define IPROC_USBD_REG_EP_FIFO_SIZE1_OUT_FRAME_NUM_SHIFT IPROC_USBD_REG_EP_FIFO_SIZE1_IN_DEPTH_SHIFT -+#define IPROC_USBD_REG_EP_FIFO_SIZE1_OUT_FRAME_NUM_MASK IPROC_USBD_REG_EP_FIFO_SIZE1_IN_DEPTH_MASK -+ -+#define IPROC_USBD_REG_EP_FIFO_SIZE2_OUT_DEPTH_SHIFT 16 -+#define IPROC_USBD_REG_EP_FIFO_SIZE2_OUT_DEPTH_MASK (0xffff << IPROC_USBD_REG_EP_FIFO_SIZE2_OUT_DEPTH_SHIFT) -+#define IPROC_USBD_REG_EP_FIFO_SIZE2_PKT_MAX_SHIFT 0 -+#define IPROC_USBD_REG_EP_FIFO_SIZE2_PKT_MAX_MASK (0xffff << IPROC_USBD_REG_EP_FIFO_SIZE2_PKT_MAX_SHIFT) -+ -+/* -+ * The endpoint type field in the config register has the same enumeration -+ * as the USB protocol. Not going to define it here. -+ */ -+#define IPROC_USBD_REG_EP_CFG_PKT_MAX_SHIFT 19 -+#define IPROC_USBD_REG_EP_CFG_PKT_MAX_MASK (0x7ff << IPROC_USBD_REG_EP_CFG_PKT_MAX_SHIFT) -+#define IPROC_USBD_REG_EP_CFG_ALT_NUM_SHIFT 15 -+#define IPROC_USBD_REG_EP_CFG_ALT_NUM_MASK (0xf << IPROC_USBD_REG_EP_CFG_ALT_NUM_SHIFT) -+#define IPROC_USBD_REG_EP_CFG_INTF_NUM_SHIFT 11 -+#define IPROC_USBD_REG_EP_CFG_INTF_NUM_MASK (0xf << IPROC_USBD_REG_EP_CFG_INTF_NUM_SHIFT) -+#define IPROC_USBD_REG_EP_CFG_CFG_NUM_SHIFT 7 -+#define IPROC_USBD_REG_EP_CFG_CFG_NUM_MASK (0xf << IPROC_USBD_REG_EP_CFG_CFG_NUM_SHIFT) -+#define IPROC_USBD_REG_EP_CFG_TYPE_SHIFT 5 -+#define IPROC_USBD_REG_EP_CFG_TYPE_MASK (0x3 << IPROC_USBD_REG_EP_CFG_TYPE_SHIFT) -+#define IPROC_USBD_REG_EP_CFG_DIRN_IN (1 << 4) -+#define IPROC_USBD_REG_EP_CFG_DIRN_OUT 0 -+#define IPROC_USBD_REG_EP_CFG_FIFO_NUM_SHIFT 0 -+#define IPROC_USBD_REG_EP_CFG_FIFO_NUM_MASK (0xf << IPROC_USBD_REG_EP_CFG_FIFO_NUM_SHIFT) -+ -+/* Endpoint Interrupt register definitions */ -+#define IPROC_USBD_REG_EP_INTR_OUT_SHIFT 16 -+#define IPROC_USBD_REG_EP_INTR_OUT_MASK (0xffff << IPROC_USBD_REG_EP_INTR_OUT_SHIFT) -+#define IPROC_USBD_REG_EP_INTR_IN_SHIFT 0 -+#define IPROC_USBD_REG_EP_INTR_IN_MASK (0xffff << IPROC_USBD_REG_EP_INTR_IN_SHIFT) -+ -+/* Device Controller register definitions */ -+#define IPROC_USBD_REG_CFG_ULPI_DDR_ENABLE (1 << 19) -+#define IPROC_USBD_REG_CFG_SET_DESCRIPTOR_ENABLE (1 << 18) -+#define IPROC_USBD_REG_CFG_CSR_PROGRAM_ENABLE (1 << 17) -+#define IPROC_USBD_REG_CFG_HALT_STALL_ENABLE (1 << 16) -+#define IPROC_USBD_REG_CFG_HS_TIMEOUT_CALIB_SHIFT 13 -+#define IPROC_USBD_REG_CFG_HS_TIMEOUT_CALIB_MASK (7 << IPROC_USBD_REG_CFG_HS_TIMEOUT_CALIB_SHIFT) -+#define IPROC_USBD_REG_CFG_FS_TIMEOUT_CALIB_SHIFT 10 -+#define IPROC_USBD_REG_CFG_FS_TIMEOUT_CALIB_MASK (7 << IPROC_USBD_REG_CFG_FS_TIMEOUT_CALIB_SHIFT) -+#define IPROC_USBD_REG_CFG_STATUS_1_ENABLE (1 << 8) -+#define IPROC_USBD_REG_CFG_STATUS_ENABLE (1 << 7) -+#define IPROC_USBD_REG_CFG_UTMI_BI_DIRN_ENABLE (1 << 6) -+#define IPROC_USBD_REG_CFG_UTMI_8BIT_ENABLE (1 << 5) -+#define IPROC_USBD_REG_CFG_SYNC_FRAME_ENABLE (1 << 4) -+#define IPROC_USBD_REG_CFG_SELF_PWR_ENABLE (1 << 3) -+#define IPROC_USBD_REG_CFG_REMOTE_WAKEUP_ENABLE (1 << 2) -+#define IPROC_USBD_REG_CFG_SPD_SHIFT 0 -+#define IPROC_USBD_REG_CFG_SPD_MASK (3 << IPROC_USBD_REG_CFG_SPD_SHIFT) -+#define IPROC_USBD_REG_CFG_SPD_HS (0 << IPROC_USBD_REG_CFG_SPD_SHIFT) -+#define IPROC_USBD_REG_CFG_SPD_FS (1 << IPROC_USBD_REG_CFG_SPD_SHIFT) -+#define IPROC_USBD_REG_CFG_SPD_LS (2 << IPROC_USBD_REG_CFG_SPD_SHIFT) -+#define IPROC_USBD_REG_CFG_SPD_FS_48MHZ (3 << IPROC_USBD_REG_CFG_SPD_SHIFT) -+ -+#define IPROC_USBD_REG_CTRL_DMA_OUT_THRESHOLD_LEN_SHIFT 24 -+#define IPROC_USBD_REG_CTRL_DMA_OUT_THRESHOLD_LEN_MASK (0xff << IPROC_USBD_REG_CTRL_DMA_OUT_THRESHOLD_LEN_SHIFT) -+#define IPROC_USBD_REG_CTRL_DMA_BURST_LEN_SHIFT 16 -+#define IPROC_USBD_REG_CTRL_DMA_BURST_LEN_MASK (0xff << IPROC_USBD_REG_CTRL_DMA_BURST_LEN_SHIFT) -+#define IPROC_USBD_REG_CTRL_OUT_FIFO_FLUSH_ENABLE (1 << 14) -+#define IPROC_USBD_REG_CTRL_CSR_DONE (1 << 13) -+#define IPROC_USBD_REG_CTRL_OUT_NAK_ALL_ENABLE (1 << 12) -+#define IPROC_USBD_REG_CTRL_DISCONNECT_ENABLE (1 << 10) -+#define IPROC_USBD_REG_CTRL_DMA_MODE_ENABLE (1 << 9) -+#define IPROC_USBD_REG_CTRL_DMA_BURST_ENABLE (1 << 8) -+#define IPROC_USBD_REG_CTRL_DMA_OUT_THRESHOLD_ENABLE (1 << 7) -+#define IPROC_USBD_REG_CTRL_DMA_BUFF_FILL_MODE_ENABLE (1 << 6) -+#define IPROC_USBD_REG_CTRL_ENDIAN_BIG_ENABLE (1 << 5) -+#define IPROC_USBD_REG_CTRL_DMA_DESC_UPDATE_ENABLE (1 << 4) -+#define IPROC_USBD_REG_CTRL_DMA_IN_ENABLE (1 << 3) /*TX DMA Enable */ -+#define IPROC_USBD_REG_CTRL_DMA_OUT_ENABLE (1 << 2) /*RX DMA Enable */ -+#define IPROC_USBD_REG_CTRL_RESUME_SIGNAL_ENABLE (1 << 0) -+#define IPROC_USBD_REG_CTRL_LE_ENABLE 0 /*^BCM5892 */ -+ -+#define IPROC_USBD_REG_STAT_SOF_FRAME_NUM_SHIFT 18 -+#define IPROC_USBD_REG_STAT_SOF_FRAME_NUM_MASK (0x3ffff << IPROC_USBD_REG_STAT_SOF_FRAME_NUM_SHIFT) -+#define IPROC_USBD_REG_STAT_REMOTE_WAKEUP_ALLOWED (1 << 17) -+#define IPROC_USBD_REG_STAT_PHY_ERROR (1 << 16) -+#define IPROC_USBD_REG_STAT_OUT_FIFO_EMPTY (1 << 15) -+#define IPROC_USBD_REG_STAT_SPD_SHIFT 13 -+#define IPROC_USBD_REG_STAT_SPD_MASK (3 << IPROC_USBD_REG_STAT_SPD_SHIFT) -+#define IPROC_USBD_REG_STAT_SPD_HS (0 << IPROC_USBD_REG_STAT_SPD_SHIFT) -+#define IPROC_USBD_REG_STAT_SPD_FS (1 << IPROC_USBD_REG_STAT_SPD_SHIFT) -+#define IPROC_USBD_REG_STAT_SPD_LS (2 << IPROC_USBD_REG_STAT_SPD_SHIFT) -+#define IPROC_USBD_REG_STAT_SPD_FS_48MHZ (3 << IPROC_USBD_REG_STAT_SPD_SHIFT) -+#define IPROC_USBD_REG_STAT_BUS_SUSPENDED (1 << 12) -+#define IPROC_USBD_REG_STAT_ALT_NUM_SHIFT 8 -+#define IPROC_USBD_REG_STAT_ALT_NUM_MASK (0xf << IPROC_USBD_REG_STAT_ALT_NUM_SHIFT) -+#define IPROC_USBD_REG_STAT_INTF_NUM_SHIFT 4 -+#define IPROC_USBD_REG_STAT_INTF_NUM_MASK (0xf << IPROC_USBD_REG_STAT_INTF_NUM_SHIFT) -+#define IPROC_USBD_REG_STAT_CFG_NUM_SHIFT 0 -+#define IPROC_USBD_REG_STAT_CFG_NUM_MASK (0xf << IPROC_USBD_REG_STAT_CFG_NUM_SHIFT) -+ -+#define IPROC_USBD_REG_INTR_REMOTE_WAKEUP_DELTA (1 << 7) /*Remote Wakeup Delta*/ -+#define IPROC_USBD_REG_INTR_SPD_ENUM_DONE (1 << 6) /*ENUM Speed Completed*/ -+#define IPROC_USBD_REG_INTR_SOF_RX (1 << 5) /*SOF Token Detected */ -+#define IPROC_USBD_REG_INTR_BUS_SUSPEND (1 << 4) /*SUSPEND State Detected*/ -+#define IPROC_USBD_REG_INTR_BUS_RESET (1 << 3) /*RESET State Detected */ -+#define IPROC_USBD_REG_INTR_BUS_IDLE (1 << 2) /*IDLE State Detected*/ -+#define IPROC_USBD_REG_INTR_SET_INTF_RX (1 << 1) /*Received SET_INTERFACE CMD*/ -+#define IPROC_USBD_REG_INTR_SET_CFG_RX (1 << 0) /*Received SET_CONFIG CMD*/ -+ -+/* DMA Descriptor definitions */ -+#define IPROC_USBD_REG_DMA_STAT_BUF_SHIFT 30 -+#define IPROC_USBD_REG_DMA_STAT_BUF_HOST_READY (0 << IPROC_USBD_REG_DMA_STAT_BUF_SHIFT) -+#define IPROC_USBD_REG_DMA_STAT_BUF_DMA_BUSY (1 << IPROC_USBD_REG_DMA_STAT_BUF_SHIFT) -+#define IPROC_USBD_REG_DMA_STAT_BUF_DMA_DONE (2 << IPROC_USBD_REG_DMA_STAT_BUF_SHIFT) -+#define IPROC_USBD_REG_DMA_STAT_BUF_HOST_BUSY (3 << IPROC_USBD_REG_DMA_STAT_BUF_SHIFT) -+#define IPROC_USBD_REG_DMA_STAT_BUF_MASK (3 << IPROC_USBD_REG_DMA_STAT_BUF_SHIFT) -+#define IPROC_USBD_REG_DMA_STAT_RX_SHIFT 28 -+#define IPROC_USBD_REG_DMA_STAT_RX_SUCCESS (0 << IPROC_USBD_REG_DMA_STAT_RX_SHIFT) -+#define IPROC_USBD_REG_DMA_STAT_RX_ERR_DESC (1 << IPROC_USBD_REG_DMA_STAT_RX_SHIFT) -+#define IPROC_USBD_REG_DMA_STAT_RX_ERR_BUF (3 << IPROC_USBD_REG_DMA_STAT_RX_SHIFT) -+#define IPROC_USBD_REG_DMA_STAT_RX_MASK (3 << IPROC_USBD_REG_DMA_STAT_RX_SHIFT) -+#define IPROC_USBD_REG_DMA_STAT_CFG_NUM_SHIFT 24 -+#define IPROC_USBD_REG_DMA_STAT_CFG_NUM_MASK (0xf << IPROC_USBD_REG_DMA_STAT_CFG_NUM_SHIFT) -+#define IPROC_USBD_REG_DMA_STAT_INTF_NUM_SHIFT 20 -+#define IPROC_USBD_REG_DMA_STAT_INTF_NUM_MASK (0xf << IPROC_USBD_REG_DMA_STAT_INTF_NUM_SHIFT) -+#define IPROC_USBD_REG_DMA_STAT_ALT_NUM_SHIFT 16 -+#define IPROC_USBD_REG_DMA_STAT_ALT_NUM_MASK (0xf << IPROC_USBD_REG_DMA_STAT_ALT_NUM_SHIFT) -+#define IPROC_USBD_REG_DMA_STAT_LAST_DESC (1 << 27) -+#define IPROC_USBD_REG_DMA_STAT_FRAME_NUM_SHIFT 16 -+#define IPROC_USBD_REG_DMA_STAT_FRAME_NUM_MASK (0x7ff << IPROC_USBD_REG_DMA_STAT_FRAME_NUM_SHIFT) -+#define IPROC_USBD_REG_DMA_STAT_BYTE_CNT_SHIFT 0 -+#define IPROC_USBD_REG_DMA_STAT_ISO_PID_SHIFT 14 -+#define IPROC_USBD_REG_DMA_STAT_ISO_PID_MASK (0x3 << IPROC_USBD_REG_DMA_STAT_ISO_PID_SHIFT) -+#define IPROC_USBD_REG_DMA_STAT_ISO_BYTE_CNT_SHIFT IPROC_USBD_REG_DMA_STAT_BYTE_CNT_SHIFT -+#define IPROC_USBD_REG_DMA_STAT_ISO_BYTE_CNT_MASK (0x3fff << IPROC_USBD_REG_DMA_STAT_ISO_BYTE_CNT_SHIFT) -+#define IPROC_USBD_REG_DMA_STAT_NON_ISO_BYTE_CNT_SHIFT IPROC_USBD_REG_DMA_STAT_BYTE_CNT_SHIFT -+#define IPROC_USBD_REG_DMA_STAT_NON_ISO_BYTE_CNT_MASK (0xffff << IPROC_USBD_REG_DMA_STAT_NON_ISO_BYTE_CNT_SHIFT) -+ -+/* USB2D IDM definitions */ -+#define IPROC_USB2D_IDM_REG_IO_CTRL_DIRECT_CLK_ENABLE (1 << 0) -+#define IPROC_USB2D_IDM_REG_RESET_CTRL_RESET (1 << 0) -+ -+/* Inline Function Definitions */ -+static inline uint -+usbd_reg32_read(volatile uint *reg) -+{ -+ return (le32_to_cpu(*reg)); -+} -+ -+static inline void -+usbd_reg32_write(volatile uint *reg, uint value) -+{ -+ *reg = cpu_to_le32(value); -+} -+ -+static inline void -+usbd_reg32_bits_set(volatile uint *reg, uint bits) -+{ -+ uint tmp; -+ tmp = usbd_reg32_read(reg); -+ tmp |= bits; -+ usbd_reg32_write(reg, tmp); -+} -+ -+static inline void -+usbd_reg32_bits_clear(volatile uint *reg, uint bits) -+{ -+ uint tmp; -+ tmp = usbd_reg32_read(reg); -+ tmp &= ~bits; -+ usbd_reg32_write(reg, tmp); -+} -+ -+static inline void -+usbd_reg32_bits_modify(volatile uint *reg, uint mask, uint value) -+{ -+ uint tmp; -+ tmp = usbd_reg32_read(reg); -+ tmp &= ~mask; -+ tmp |= value; -+ usbd_reg32_write(reg, tmp); -+} -+ -+#define IPROC_USBD_READ(_r) usbd_reg32_read(&_r) -+#define IPROC_USBD_WRITE(_r, _v) usbd_reg32_write(&_r, _v) -+#define IPROC_USBD_BITS_SET(_r, _b) usbd_reg32_bits_set(&_r, _b) -+#define IPROC_USBD_BITS_CLEAR(_r, _b) usbd_reg32_bits_clear(&_r, _b) -+#define IPROC_USBD_BITS_MODIFY(_r, _m, _v) usbd_reg32_bits_modify(&_r, _m, _v) -+ -+/***************************************************************************** -+* @brief Connect / Disconnect to USB BUS -+*****************************************************************************/ -+static inline void iproc_usbd_bus_conn(struct iproc_usbd_regs *base) -+{ -+ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, IPROC_USBD_REG_CTRL_DISCONNECT_ENABLE); -+} -+ -+static inline void iproc_usbd_bus_disconn(struct iproc_usbd_regs *base) -+{ -+ IPROC_USBD_BITS_SET(base->dev_ctrl, IPROC_USBD_REG_CTRL_DISCONNECT_ENABLE); -+} -+ -+/***************************************************************************** -+* @brief USB BUS suspend status -+* @return -+* true : BUS is in suspend state -+* false : BUS is not in suspend state -+*****************************************************************************/ -+static inline bool iproc_usbd_bus_suspend(struct iproc_usbd_regs *base) -+{ -+ return (IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_BUS_SUSPENDED) ? true : false; -+} -+ -+/***************************************************************************** -+* @brief Retrieve setting numbers from last Rx'd SET_CONFIGURATION or -+* SET_INTERFACE request -+* @return -+* Setting Number -+*****************************************************************************/ -+static inline uint iproc_usbd_alt_num(struct iproc_usbd_regs *base) -+{ -+ return ((IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_ALT_NUM_MASK) >> IPROC_USBD_REG_STAT_ALT_NUM_SHIFT); -+} -+ -+static inline uint iproc_usbd_cfg_num(struct iproc_usbd_regs *base) -+{ -+ return ((IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_CFG_NUM_MASK) >> IPROC_USBD_REG_STAT_CFG_NUM_SHIFT); -+} -+ -+static inline uint iproc_usbd_intf_num(struct iproc_usbd_regs *base) -+{ -+ return ((IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_INTF_NUM_MASK) >> IPROC_USBD_REG_STAT_INTF_NUM_SHIFT); -+} -+ -+ -+/***************************************************************************** -+* @brief Disable / Enable DMA operations at the device level (all endpoints) -+*****************************************************************************/ -+static inline void iproc_usbd_dma_dis(struct iproc_usbd_regs *base) -+{ -+ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, (IPROC_USBD_REG_CTRL_DMA_IN_ENABLE | IPROC_USBD_REG_CTRL_DMA_OUT_ENABLE)); -+} -+ -+static inline void iproc_usbd_dma_en(struct iproc_usbd_regs *base) -+{ -+ IPROC_USBD_BITS_SET(base->dev_ctrl, (IPROC_USBD_REG_CTRL_DMA_IN_ENABLE | IPROC_USBD_REG_CTRL_DMA_OUT_ENABLE)); -+} -+ -+static inline bool iproc_usbd_dma_status(struct iproc_usbd_regs *base) -+{ -+ return (IPROC_USBD_READ(base->dev_ctrl) & IPROC_USBD_REG_CTRL_DMA_OUT_ENABLE ? true : false); -+} -+ -+/***************************************************************************** -+* @brief Retrieve Frame number contained in last Rx'd SOF packet -+* @return -+* Frame Number in the following format. -+* bits[13:3] milli-second frame number -+* bits[2:0] micro-frame number -+* @note -+* For full and low speed connections, the microframe number will be zero. -+*****************************************************************************/ -+static inline uint iproc_usbd_last_rx_frame_num(struct iproc_usbd_regs *base) -+{ -+ return((IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_SOF_FRAME_NUM_MASK) >> IPROC_USBD_REG_STAT_SOF_FRAME_NUM_SHIFT); -+} -+ -+/***************************************************************************** -+* @brief Device level interrupt operations -+* @note -+* Use the IPROC_USBD_IRQ_xxx definitions with these routines. These -+* definitions are bit-wise, and allow operations on multiple interrupts -+* by OR'ing the definitions together. -+* DeviceIrqClear(), DeviceIrqDisable(), DeviceIrqEnable() use their mask -+* parameter to operate only on the interrupts set in the mask. E.g. -+* DeviceIrqEnable( DEVICE_IRQ_SET_INTF ); -+* DeviceIrqEnable( DEVICE_IRQ_SET_CFG ); -+* and -+* DeviceIrqEnable( DEVICE_IRQ_SET_INTF | DEVICE_IRQ_SET_CFG ); -+* are equivalent. -+* DeviceIrqMask() returns a mask of all the interrupts that are enabled. -+* DeviceIrqStatus() returns a mask of all the interrupts that have an active status. -+*****************************************************************************/ -+static inline uint iproc_usbd_irq_active(struct iproc_usbd_regs *base) -+{ -+ return(IPROC_USBD_READ(base->dev_irq_status)); -+} -+ -+static inline void iproc_usbd_irq_clear(struct iproc_usbd_regs *base, uint mask) -+{ -+ IPROC_USBD_WRITE(base->dev_irq_status, mask); -+} -+ -+static inline void iproc_usbd_irq_dis(struct iproc_usbd_regs *base, uint mask) -+{ -+ IPROC_USBD_BITS_SET(base->dev_irq_mask, mask); -+} -+ -+static inline void iproc_usbd_irq_en(struct iproc_usbd_regs *base, uint mask) -+{ -+ IPROC_USBD_BITS_CLEAR(base->dev_irq_mask, mask); -+} -+static inline uint iproc_usbd_irq_mask(struct iproc_usbd_regs *base) -+{ -+ return((~IPROC_USBD_READ(base->dev_irq_mask)) & IPROC_USBD_IRQ_ALL); -+} -+ -+/***************************************************************************** -+* @brief Disable / Enable NAK responses for all OUT endpoints. -+*****************************************************************************/ -+static inline void iproc_usbd_nak_response_dis(struct iproc_usbd_regs *base) -+{ -+ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, IPROC_USBD_REG_CTRL_OUT_NAK_ALL_ENABLE); -+} -+ -+static inline void iproc_usbd_nak_response_en(struct iproc_usbd_regs *base) -+{ -+ IPROC_USBD_BITS_SET(base->dev_ctrl, IPROC_USBD_REG_CTRL_OUT_NAK_ALL_ENABLE); -+} -+ -+/***************************************************************************** -+* @brief PHY error detected -+*****************************************************************************/ -+static inline bool iproc_usbd_phy_err_detect(struct iproc_usbd_regs *base) -+{ -+ return(IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_PHY_ERROR ? true : false); -+} -+ -+/***************************************************************************** -+* @brief Remote Wakeup operations. -+* DeviceRemoteWakeupEnable() and DeviceRemoteWakeupDisable() are used to -+* specify device if is going to attempt this. -+* DeviceRemoteWakeupAllowed() indicates if host has enabled this feature. -+* The associated DEVICE_IRQ_REMOTEWAKEUP_DELTA can be used to determine -+* changes to the status of this feature. -+* DeviceRemoteWakeupStart(); delayMsec(1); DeviceRemoteWakeupStop(); is -+* used for controlling the wakeup signalling. -+*****************************************************************************/ -+static inline bool iproc_usbd_wakeup_allow(struct iproc_usbd_regs *base) -+{ -+ return(IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_REMOTE_WAKEUP_ALLOWED ? true : false); -+} -+ -+static inline void iproc_usbd_wakeup_dis(struct iproc_usbd_regs *base) -+{ -+ IPROC_USBD_BITS_CLEAR(base->dev_cfg, IPROC_USBD_REG_CFG_REMOTE_WAKEUP_ENABLE); -+} -+ -+static inline void iproc_usbd_wakeup_en(struct iproc_usbd_regs *base) -+{ -+ IPROC_USBD_BITS_SET(base->dev_cfg, IPROC_USBD_REG_CFG_REMOTE_WAKEUP_ENABLE); -+} -+ -+static inline void iproc_usbd_wakeup_start(struct iproc_usbd_regs *base) -+{ -+ IPROC_USBD_BITS_SET(base->dev_ctrl, IPROC_USBD_REG_CTRL_RESUME_SIGNAL_ENABLE); -+} -+ -+static inline void iproc_usbd_wakeup_stop(struct iproc_usbd_regs *base) -+{ -+ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, IPROC_USBD_REG_CTRL_RESUME_SIGNAL_ENABLE); -+} -+ -+/***************************************************************************** -+* @brief Control whether or not device advertises itself as self-powered. -+*****************************************************************************/ -+static inline void iproc_usbd_self_pwr_dis(struct iproc_usbd_regs *base) -+{ -+ IPROC_USBD_BITS_CLEAR(base->dev_cfg, IPROC_USBD_REG_CFG_SELF_PWR_ENABLE); -+} -+ -+static inline void iproc_usbd_self_pwr_en(struct iproc_usbd_regs *base) -+{ -+ IPROC_USBD_BITS_SET(base->dev_cfg, IPROC_USBD_REG_CFG_SELF_PWR_ENABLE); -+} -+ -+/***************************************************************************** -+* @brief Control whether or not device SET DESCRIPTOR support is enabled. -+* If disabled, STALL will be issued upon receipt of a SET DESCRIPTOR request. -+*****************************************************************************/ -+static inline void iproc_usbd_set_desc_dis(struct iproc_usbd_regs *base) -+{ -+ IPROC_USBD_BITS_CLEAR(base->dev_cfg, IPROC_USBD_REG_CFG_SET_DESCRIPTOR_ENABLE); -+} -+ -+static inline void iproc_usbd_set_desc_en(struct iproc_usbd_regs *base) -+{ -+ IPROC_USBD_BITS_SET(base->dev_cfg, IPROC_USBD_REG_CFG_SET_DESCRIPTOR_ENABLE); -+} -+ -+/***************************************************************************** -+* @brief Device SET configuration or SET interface has completed. -+* If disabled, STALL will be issued upon receipt of a SET DESCRIPTOR request. -+*****************************************************************************/ -+static inline void iproc_usbd_setup_done(struct iproc_usbd_regs *base) -+{ -+ IPROC_USBD_BITS_SET(base->dev_ctrl, IPROC_USBD_REG_CTRL_CSR_DONE); -+} -+ -+/***************************************************************************** -+* @brief Link speed routines. -+* Use the usbDevHw_DEVICE_SPEED_xxx definitions with these routines. These -+* DeviceSpeedRequested() indicates the desired link speed. -+* DeviceSpeedEnumerated() returns the speed negotiated with the host. -+* The associated DEVICE_IRQ_SPEED_ENUM_DONE can be used to determine -+* when speed negotiation has completed. -+*****************************************************************************/ -+static inline uint iproc_usbd_speed_get(struct iproc_usbd_regs *base) -+{ -+ switch(IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_SPD_MASK) { -+ case IPROC_USBD_REG_STAT_SPD_LS: -+ return(IPROC_USBD_SPEED_LOW); -+ -+ case IPROC_USBD_REG_STAT_SPD_HS: -+ return(IPROC_USBD_SPEED_HIGH); -+ -+ case IPROC_USBD_REG_STAT_SPD_FS: -+ case IPROC_USBD_REG_STAT_SPD_FS_48MHZ: -+ return(IPROC_USBD_SPEED_FULL); -+ } -+ -+ return IPROC_USBD_SPEED_FULL; -+} -+ -+static inline void iproc_usbd_speed_req(struct iproc_usbd_regs *base, uint speed) -+{ -+ IPROC_USBD_BITS_CLEAR(base->dev_cfg, IPROC_USBD_REG_CFG_SPD_MASK); -+ -+ switch(speed) { -+ case IPROC_USBD_SPEED_LOW: -+ IPROC_USBD_BITS_SET(base->dev_cfg, IPROC_USBD_REG_CFG_SPD_LS); -+ break; -+ -+ case IPROC_USBD_SPEED_HIGH: -+ IPROC_USBD_BITS_SET(base->dev_cfg, IPROC_USBD_REG_CFG_SPD_HS); -+ break; -+ -+ case IPROC_USBD_SPEED_FULL: -+ default: -+ IPROC_USBD_BITS_SET(base->dev_cfg, IPROC_USBD_REG_CFG_SPD_FS); -+ break; -+ } -+} -+ -+/***************************************************************************** -+* @brief Finalize (terminate) / Initialize Endpoint operations -+* @param num - Endpoint number -+* @param dirn - Endpoint direction. See ENDPT_DIRN_xxx definitions -+* @param dirn - Endpoint type. See ENDPT_TYPE_xxx definitions -+* @param dirn - Endpoint max packet size. -+*****************************************************************************/ -+static inline void iproc_usbd_ep_ops_finish(struct iproc_usbd_regs *base, uint num) -+{ -+} -+ -+static inline void iproc_usbd_ep_ops_init(struct iproc_usbd_regs *base, uint num, uint type, uint dirn, uint maxPktSize) -+{ -+ if ((type == IPROC_USBD_EP_TYPE_CTRL) || (dirn == IPROC_USBD_EP_DIR_OUT)) { -+ IPROC_USBD_WRITE(base->ep_fifo_out[num].ctrl, (type << IPROC_USBD_REG_EP_FIFO_CTRL_TYPE_SHIFT)); -+ IPROC_USBD_WRITE(base->ep_fifo_out[num].status, IPROC_USBD_READ(base->ep_fifo_out[num].status)); -+ IPROC_USBD_WRITE(base->ep_fifo_out[num].size1, 0); -+ IPROC_USBD_WRITE(base->ep_fifo_out[num].size2, ((maxPktSize >> 2) << 16) | maxPktSize); -+#if IPROC_USBD_MULTI_RX_FIFO -+ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].size2, ((maxPktSize + 3) >> 2) << IPROC_USBD_REG_EP_FIFO_SIZE2_OUT_DEPTH_SHIFT)); -+#endif -+ } -+ if ((type == IPROC_USBD_EP_TYPE_CTRL) || (dirn == IPROC_USBD_EP_DIR_IN)) { -+ IPROC_USBD_WRITE(base->ep_fifo_in[num].ctrl, (type << IPROC_USBD_REG_EP_FIFO_CTRL_TYPE_SHIFT)); -+ IPROC_USBD_WRITE(base->ep_fifo_in[num].size2, (maxPktSize << IPROC_USBD_REG_EP_FIFO_SIZE2_PKT_MAX_SHIFT)); -+ IPROC_USBD_WRITE(base->ep_fifo_in[num].size1, (maxPktSize >> 2)); -+ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE); -+ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, (IPROC_USBD_REG_EP_FIFO_CTRL_NAK_SET | IPROC_USBD_REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE)); -+ } -+ IPROC_USBD_WRITE(base->ep_cfg[num], (num << IPROC_USBD_REG_EP_CFG_FIFO_NUM_SHIFT) | -+ (type << IPROC_USBD_REG_EP_CFG_TYPE_SHIFT) | -+ (maxPktSize << IPROC_USBD_REG_EP_CFG_PKT_MAX_SHIFT) | -+ (dirn == IPROC_USBD_EP_DIR_OUT ? IPROC_USBD_REG_EP_CFG_DIRN_OUT : IPROC_USBD_REG_EP_CFG_DIRN_IN)); -+} -+ -+/***************************************************************************** -+* @brief Endpoint Configuration / Interface / Alternate number operations -+* @param num - Endpoint number -+* @param cfg - Configuration number -+* @param intf - Interface number -+* @param alt - Alternate number -+*****************************************************************************/ -+static inline void iproc_usbd_ep_alt_set(struct iproc_usbd_regs *base, uint num, uint alt) -+{ -+ IPROC_USBD_BITS_MODIFY(base->ep_cfg[num], IPROC_USBD_REG_EP_CFG_ALT_NUM_MASK, (alt << IPROC_USBD_REG_EP_CFG_ALT_NUM_SHIFT)); -+} -+ -+static inline void iproc_usbd_ep_cfg_set(struct iproc_usbd_regs *base, uint num, uint cfg) -+{ -+ IPROC_USBD_BITS_MODIFY(base->ep_cfg[num], IPROC_USBD_REG_EP_CFG_CFG_NUM_MASK, (cfg << IPROC_USBD_REG_EP_CFG_CFG_NUM_SHIFT)); -+} -+ -+static inline void iproc_usbd_ep_intf_set(struct iproc_usbd_regs *base, uint num, uint intf) -+{ -+ IPROC_USBD_BITS_MODIFY(base->ep_cfg[num], IPROC_USBD_REG_EP_CFG_INTF_NUM_MASK, (intf << IPROC_USBD_REG_EP_CFG_INTF_NUM_SHIFT)); -+} -+ -+ -+/***************************************************************************** -+* @brief Endpoint DMA routines -+* @param num - Endpoint number -+* @param addr - physical address of buffer or descriptor -+*****************************************************************************/ -+static inline void iproc_usbd_ep_dma_dis(struct iproc_usbd_regs *base, uint num, uint dirn) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+#if IPROC_USBD_MULTI_RX_FIFO -+ IPROC_USBD_BITS_CLEAR(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_OUT_DMA_ENABLE); -+#else -+ /* -+ * With a single RX FIFO, do not want to do anything, as there might be another OUT capable -+ * endpoint still active and wanting DMA enabled. If theory this should be OK, as long as -+ * the DMA descriptor buffer status fields are the last thing updated before being set to -+ * HOST ready, or the first thing updated when being set to HOST busy. Hopefully no -+ * situations arise such that there's contention with the hardware with doing this. -+ */ -+#endif -+ } else { -+ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_IN_DMA_ENABLE); -+ } -+} -+ -+static inline void iproc_usbd_ep_dma_en(struct iproc_usbd_regs *base, uint num, uint dirn) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+#if IPROC_USBD_MULTI_RX_FIFO -+ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_OUT_DMA_ENABLE); -+#else -+ IPROC_USBD_BITS_SET(base->dev_ctrl, IPROC_USBD_REG_CTRL_DMA_OUT_ENABLE); -+#endif -+ } else { -+ /* Set the Poll bit in the control register */ -+ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_IN_DMA_ENABLE); -+ } -+} -+ -+static inline void iproc_usbd_ep_dma_buf_addr_set(struct iproc_usbd_regs *base, uint num, uint dirn, void *addr) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+ IPROC_USBD_WRITE(base->ep_fifo_out[num].buf_addr, (uint)addr); -+ } -+} -+ -+static inline void iproc_usbd_ep_dma_desc_addr_set(struct iproc_usbd_regs *base, uint num, uint dirn, void *addr) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+ IPROC_USBD_WRITE(base->ep_fifo_out[num].desc_addr, (uint)addr); -+ } -+ else { -+ IPROC_USBD_WRITE(base->ep_fifo_in[num].desc_addr, (uint)addr); -+ } -+} -+ -+/***************************************************************************** -+* @brief Endpoint FIFO routines -+* @param num - Endpoint number -+* @note The flush operation is a state. Once enabled, FIFO contents are discared -+* until disabled. Usually enable upon endpoint termination or error, and -+* then disable once operations are to resume normally. -+*****************************************************************************/ -+static inline bool iproc_usbd_ep_fifo_empty(struct iproc_usbd_regs *base, uint num, uint dirn) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+#if IPROC_USBD_MULTI_RX_FIFO -+ return(base->ep_fifo_out[num].status & IPROC_USBD_REG_EP_FIFO_STATUS_OUT_FIFO_EMPTY ? true : false); -+#else -+ return(base->dev_status & IPROC_USBD_REG_STAT_OUT_FIFO_EMPTY ? true : false); -+#endif -+ } -+ return(base->ep_fifo_in[num].status & IPROC_USBD_REG_EP_FIFO_STATUS_IN_FIFO_EMPTY ? true : false); -+} -+ -+static inline void iproc_usbd_ep_fifo_flush_dis(struct iproc_usbd_regs *base, uint num, uint dirn) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+#if IPROC_USBD_MULTI_RX_FIFO -+ IPROC_USBD_BITS_CLEAR(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_OUT_FLUSH_ENABLE); -+#else -+ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, IPROC_USBD_REG_CTRL_OUT_FIFO_FLUSH_ENABLE); -+#endif -+ } -+ else { -+ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE); -+ } -+} -+ -+static inline void iproc_usbd_ep_fifo_flush_en(struct iproc_usbd_regs *base, uint num, uint dirn) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+#if IPROC_USBD_MULTI_RX_FIFO -+ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_OUT_FLUSH_ENABLE); -+#else -+ IPROC_USBD_BITS_SET(base->dev_ctrl, IPROC_USBD_REG_CTRL_OUT_FIFO_FLUSH_ENABLE); -+#endif -+ } else { -+ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE); -+ } -+} -+ -+/***************************************************************************** -+* @brief Endpoint Frame Number routines -+* @param num - Endpoint number -+* @return Frame number of last packet received on the endpoint, and in the following format. -+* bits[13:3] milli-second frame number -+* bits[2:0] micro-frame number -+* @note Really only applicable to OUT endpoints. IN will always return 0. -+*****************************************************************************/ -+static inline uint iproc_usbd_ep_frame_num(struct iproc_usbd_regs *base, uint num, uint dirn) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+ return((IPROC_USBD_READ(base->ep_fifo_out[num].size1) & IPROC_USBD_REG_EP_FIFO_SIZE1_OUT_FRAME_NUM_MASK) >> IPROC_USBD_REG_EP_FIFO_SIZE1_OUT_FRAME_NUM_SHIFT); -+ } -+ return(0); -+} -+ -+/***************************************************************************** -+* @brief Endpoint IRQ / status routines -+* @param num - Endpoint number -+* @note -+* Cannot set specific status for Endpoint interrupts. Can only do operations -+* in a global sense. Once an interrupt occurs for an endpoint, the endpoint -+* status has to be checked for the particular type of interrupt that occurred. -+* -+* The iproc_usbd_ep_irq_en() and iproc_usbd_ep_irq_dis() are used for -+* operations on a specific endpoint. These routines may or may not be used in -+* the context of interrupt processing. -+* -+* Use the usbDevHw_EndptIrqListXxx() routines for operations using a bit-wise -+* list of endpoints (bit 0 for endpoint 0, etc.). Typical use would be for -+* interrupt processing. -+* -+* Use the IPROC_USBD_EP_STAT_xxx definitions with the status routines. These -+* definitions are bit-wise, and allow operations on multiple conditions -+* by OR'ing the definitions together. -+*****************************************************************************/ -+static inline void iproc_usbd_ep_irq_clear(struct iproc_usbd_regs *base, uint num, uint dirn) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+ IPROC_USBD_WRITE(base->ep_irq_status, (1 << num) << IPROC_USBD_REG_EP_INTR_OUT_SHIFT); -+ } else { -+ IPROC_USBD_WRITE(base->ep_irq_status, (1 << num) << IPROC_USBD_REG_EP_INTR_IN_SHIFT); -+ } -+} -+ -+static inline void iproc_usbd_ep_irq_dis(struct iproc_usbd_regs *base, uint num, uint dirn) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+ IPROC_USBD_BITS_SET(base->ep_irq_mask, ((1 << num) << IPROC_USBD_REG_EP_INTR_OUT_SHIFT)); -+ } else { -+ IPROC_USBD_BITS_SET(base->ep_irq_mask, ((1 << num) << IPROC_USBD_REG_EP_INTR_IN_SHIFT)); -+ } -+} -+ -+static inline void iproc_usbd_ep_irq_en(struct iproc_usbd_regs *base, uint num, uint dirn) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+ IPROC_USBD_BITS_CLEAR(base->ep_irq_mask, ((1 << num) << IPROC_USBD_REG_EP_INTR_OUT_SHIFT)); -+ } else { -+ IPROC_USBD_BITS_CLEAR(base->ep_irq_mask, ((1 << num) << IPROC_USBD_REG_EP_INTR_IN_SHIFT)); -+ } -+} -+ -+static inline uint iproc_usbd_ep_irq_list_active(struct iproc_usbd_regs *base, uint dirn) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+ return((IPROC_USBD_READ(base->ep_irq_status) & IPROC_USBD_REG_EP_INTR_OUT_MASK) >> IPROC_USBD_REG_EP_INTR_OUT_SHIFT); -+ } -+ return((IPROC_USBD_READ(base->ep_irq_status) & IPROC_USBD_REG_EP_INTR_IN_MASK) >> IPROC_USBD_REG_EP_INTR_IN_SHIFT); -+} -+ -+static inline void iproc_usbd_ep_irq_list_clear(struct iproc_usbd_regs *base, uint dirn, uint mask) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+ IPROC_USBD_WRITE(base->ep_irq_status, (mask << IPROC_USBD_REG_EP_INTR_OUT_SHIFT)); /*strat from bit 16 */ -+ } else { -+ IPROC_USBD_WRITE(base->ep_irq_status, (mask << IPROC_USBD_REG_EP_INTR_IN_SHIFT)); /* start from bit 0 */ -+ } -+} -+ -+static inline uint iproc_usbd_ep_stat_active(struct iproc_usbd_regs *base, uint num, uint dirn) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+ return(IPROC_USBD_READ(base->ep_fifo_out[num].status)); /* End Point Status register */ -+ } -+ return(IPROC_USBD_READ(base->ep_fifo_in[num].status)); -+} -+ -+static inline void iproc_usbd_ep_stat_clear(struct iproc_usbd_regs *base, uint num, uint dirn, uint mask) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+ IPROC_USBD_WRITE(base->ep_fifo_out[num].status, mask); -+ } else { -+ IPROC_USBD_WRITE(base->ep_fifo_in[num].status, mask); -+ } -+} -+ -+/***************************************************************************** -+* @brief Endpoint NAK routines -+* @param num - Endpoint number -+* @note A NAK response can be enabled by the application by the EndptNakEnable(). -+* The EndptNakInProgress() is used to determine if the controller is -+* currently actively sending NAKs. This may have been a result of the -+* EndptNakEnable() or automatically by the controller under certain -+* conditions. The EndptNakClear() must be used to terminate the NAKs. -+*****************************************************************************/ -+static inline void iproc_usbd_ep_nak_clear(struct iproc_usbd_regs *base, uint num, uint dirn) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_NAK_CLEAR); -+ } else { -+ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_NAK_CLEAR); -+ } -+} -+ -+static inline void iproc_usbd_ep_nak_en(struct iproc_usbd_regs *base, uint num, uint dirn) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_NAK_SET); -+ } else { -+ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_NAK_SET); -+ } -+} -+ -+static inline void iproc_usbd_ep_nak_dis(struct iproc_usbd_regs *base, uint num, uint dirn) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+ IPROC_USBD_BITS_CLEAR(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_NAK_SET); -+ } else { -+ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_NAK_SET); -+ } -+} -+ -+static inline bool iproc_usbd_ep_nak_progress(struct iproc_usbd_regs *base, uint num, uint dirn) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+ return (IPROC_USBD_READ(base->ep_fifo_out[num].ctrl) & IPROC_USBD_REG_EP_FIFO_CTRL_NAK_IN_PROGRESS) ? true : false; -+ } -+ return (IPROC_USBD_READ(base->ep_fifo_in[num].ctrl) & IPROC_USBD_REG_EP_FIFO_CTRL_NAK_IN_PROGRESS) ? true : false; -+} -+ -+/***************************************************************************** -+* @brief Endpoint Stall routines -+* Disable / Enable STALL responses (halt feature) on a given endpoint. -+* @param num - Endpoint number -+*****************************************************************************/ -+static inline void iproc_usbd_ep_stall_dis(struct iproc_usbd_regs *base, uint num, uint dirn) -+{ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+ IPROC_USBD_BITS_CLEAR(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_STALL_ENABLE); -+ } else { -+ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_STALL_ENABLE); -+ } -+} -+ -+static inline void iproc_usbd_ep_stall_en(struct iproc_usbd_regs *base, uint num, uint dirn) -+{ -+#if IPROC_USBD_MULTI_RX_FIFO -+ if (!(IPROC_USBD_READ(base->ep_fifo_out[num].status) & IPROC_USBD_REG_EP_FIFO_STATUS_OUT_FIFO_EMPTY)) -+#else -+ if (!(IPROC_USBD_READ(base->dev_status) & IPROC_USBD_REG_STAT_OUT_FIFO_EMPTY)) -+#endif -+ return; -+ -+ if (dirn == IPROC_USBD_EP_DIR_OUT) { -+ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_STALL_ENABLE); -+ } else { -+ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, IPROC_USBD_REG_EP_FIFO_CTRL_STALL_ENABLE); -+ } -+} -+ -+ -+/***************************************************************************** -+* @brief Initialize device controller operations -+*****************************************************************************/ -+static inline void iproc_usbd_ops_init(struct iproc_usbd_regs *base) -+{ -+ int idx; -+ -+ iproc_usbd_dma_dis(base); -+ iproc_usbd_irq_dis(base, IPROC_USBD_IRQ_ALL); -+ iproc_usbd_irq_clear(base, IPROC_USBD_IRQ_ALL); -+ -+ /* @todo Create and use usbDevHw_EndptIrqListDisable?? */ -+ for (idx = 0; idx < IPROC_USBD_EP_CFG_CNT; idx++) { -+ iproc_usbd_ep_irq_dis(base, idx, IPROC_USBD_EP_DIR_IN); -+ iproc_usbd_ep_irq_clear(base, idx, IPROC_USBD_EP_DIR_IN); -+ iproc_usbd_ep_stat_clear(base, idx, IPROC_USBD_EP_DIR_IN, iproc_usbd_ep_stat_active(base, idx, IPROC_USBD_EP_DIR_IN)); -+ -+ iproc_usbd_ep_irq_dis(base, idx, IPROC_USBD_EP_DIR_OUT); -+ iproc_usbd_ep_irq_clear(base, idx, IPROC_USBD_EP_DIR_OUT); -+ iproc_usbd_ep_stat_clear(base, idx, IPROC_USBD_EP_DIR_OUT, iproc_usbd_ep_stat_active(base, idx, IPROC_USBD_EP_DIR_OUT)); -+ } -+ -+ IPROC_USBD_WRITE(base->dev_cfg, (IPROC_USBD_REG_CFG_SET_DESCRIPTOR_ENABLE | -+ IPROC_USBD_REG_CFG_UTMI_8BIT_ENABLE | -+ IPROC_USBD_REG_CFG_CSR_PROGRAM_ENABLE | -+ IPROC_USBD_REG_CFG_SPD_HS)); -+ -+ IPROC_USBD_WRITE(base->dev_ctrl, (IPROC_USBD_REG_CTRL_LE_ENABLE | -+ IPROC_USBD_REG_CTRL_DISCONNECT_ENABLE | -+ IPROC_USBD_REG_CTRL_DMA_MODE_ENABLE | -+ IPROC_USBD_REG_CTRL_DMA_IN_ENABLE | -+ IPROC_USBD_REG_CTRL_DMA_OUT_ENABLE | -+ IPROC_USBD_REG_CTRL_DMA_DESC_UPDATE_ENABLE | -+ IPROC_USBD_REG_CTRL_OUT_NAK_ALL_ENABLE | -+ IPROC_USBD_REG_CTRL_DMA_OUT_THRESHOLD_LEN_MASK | -+ IPROC_USBD_REG_CTRL_DMA_BURST_LEN_MASK | -+#if !IPROC_USBD_MULTI_RX_FIFO -+ IPROC_USBD_REG_CTRL_OUT_FIFO_FLUSH_ENABLE | -+#endif -+ IPROC_USBD_REG_CTRL_DMA_BURST_ENABLE)); -+ -+ IPROC_USBD_WRITE(base->dev_irq_mask, (IPROC_USBD_REG_INTR_BUS_IDLE | -+ IPROC_USBD_REG_INTR_SOF_RX)); -+ IPROC_USBD_WRITE(base->ep_irq_mask,0); -+} -+ -+/***************************************************************************** -+* @brief Disable / Enable USB device -+*****************************************************************************/ -+static inline void iproc_usbd_dis(struct iproc_usbd_idm_regs *idm_base) -+{ -+ /* reset usb device */ -+ IPROC_USBD_BITS_SET(idm_base->reset_ctrl, IPROC_USB2D_IDM_REG_RESET_CTRL_RESET); -+ -+ /* disable usb device clock */ -+ IPROC_USBD_BITS_CLEAR(idm_base->io_ctrl, IPROC_USB2D_IDM_REG_IO_CTRL_DIRECT_CLK_ENABLE); -+ mdelay(10); -+} -+ -+static inline void iproc_usbd_en(struct iproc_usbd_idm_regs *idm_base) -+{ -+ /* enable usb device clock */ -+ IPROC_USBD_BITS_SET(idm_base->io_ctrl, IPROC_USB2D_IDM_REG_IO_CTRL_DIRECT_CLK_ENABLE); -+ mdelay(10); -+ -+ /* get usb device out of reset */ -+ IPROC_USBD_BITS_CLEAR(idm_base->reset_ctrl, IPROC_USB2D_IDM_REG_RESET_CTRL_RESET); -+ mdelay(100); -+} -+ -+ -+ -+#endif /* _USBD_REGS_H_ */ -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig ---- a/drivers/usb/host/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/usb/host/Kconfig 2017-11-09 17:54:01.760430000 +0800 -@@ -298,6 +298,13 @@ config USB_EHCI_HCD_PLATFORM - - If unsure, say N. - -+config USB_EHCI_XGS_IPROC -+ bool "BRCM XGS iProc EHCI patch" -+ depends on (ARCH_XGS_IPROC && USB_EHCI_HCD_PLATFORM) -+ default n -+ ---help--- -+ This option is for BRCM XGS iProc EHCI patch -+ - config USB_OCTEON_EHCI - bool "Octeon on-chip EHCI support (DEPRECATED)" - depends on CAVIUM_OCTEON_SOC -@@ -561,6 +568,13 @@ config USB_OHCI_HCD_PLATFORM - - If unsure, say N. - -+config USB_OHCI_XGS_IPROC -+ bool "BRCM XGS iProc OHCI patch" -+ depends on (ARCH_XGS_IPROC && USB_OHCI_HCD_PLATFORM) -+ default n -+ ---help--- -+ This option is for BRCM XGS iProc OHCI patch -+ - config USB_OCTEON_OHCI - bool "Octeon on-chip OHCI support (DEPRECATED)" - depends on CAVIUM_OCTEON_SOC -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c ---- a/drivers/usb/host/ehci-platform.c 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/usb/host/ehci-platform.c 2017-11-09 17:54:01.791421000 +0800 -@@ -41,6 +41,14 @@ - #define EHCI_MAX_CLKS 3 - #define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv) - -+ -+#ifdef CONFIG_USB_EHCI_XGS_IPROC -+#include -+#include -+ -+#define BCM_USB_FIFO_THRESHOLD 0x00800040 -+#endif /* CONFIG_USB_EHCI_XGS_IPROC */ -+ - struct ehci_platform_priv { - struct clk *clks[EHCI_MAX_CLKS]; - struct reset_control *rst; -@@ -150,10 +158,24 @@ static int ehci_platform_probe(struct pl - struct ehci_platform_priv *priv; - struct ehci_hcd *ehci; - int err, irq, phy_num, clk = 0; -+#ifdef CONFIG_USB_EHCI_XGS_IPROC -+ struct usb_phy *phy; -+#endif /* CONFIG_USB_EHCI_XGS_IPROC */ - - if (usb_disabled()) - return -ENODEV; - -+#ifdef CONFIG_USB_EHCI_XGS_IPROC -+ phy = devm_usb_get_phy_by_phandle(&dev->dev, "usb-phy", 0); -+ if (IS_ERR(phy)) { -+ dev_err(&dev->dev, "unable to find transceiver\n"); -+ return PTR_ERR(phy); -+ } -+ -+ if (phy->flags != IPROC_USB_MODE_HOST) -+ return -ENODEV; -+#endif -+ - /* - * Use reasonable defaults so platforms don't have to provide these - * with DT probing on ARM. -@@ -292,6 +314,9 @@ static int ehci_platform_probe(struct pl - goto err_power; - - device_wakeup_enable(hcd->self.controller); -+#ifdef CONFIG_USB_EHCI_XGS_IPROC -+ ehci_writel(ehci, BCM_USB_FIFO_THRESHOLD, &ehci->regs->reserved4[6]); -+#endif - platform_set_drvdata(dev, hcd); - - return err; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c ---- a/drivers/usb/host/ohci-platform.c 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/usb/host/ohci-platform.c 2017-11-09 17:54:01.874447000 +0800 -@@ -35,6 +35,14 @@ - #define OHCI_MAX_CLKS 3 - #define hcd_to_ohci_priv(h) ((struct ohci_platform_priv *)hcd_to_ohci(h)->priv) - -+#ifdef CONFIG_USB_OHCI_XGS_IPROC -+#include -+#include -+ -+#define UHCRHDA_REG_OFFSET 0x48 -+#define UHCRHDA_OCPM (1 << 11) -+#endif -+ - struct ohci_platform_priv { - struct clk *clks[OHCI_MAX_CLKS]; - struct reset_control *rst; -@@ -118,10 +126,24 @@ static int ohci_platform_probe(struct pl - struct ohci_platform_priv *priv; - struct ohci_hcd *ohci; - int err, irq, phy_num, clk = 0; -+#ifdef CONFIG_USB_OHCI_XGS_IPROC -+ struct usb_phy *phy; -+#endif /* CONFIG_USB_OHCI_XGS_IPROC */ - - if (usb_disabled()) - return -ENODEV; - -+#ifdef CONFIG_USB_OHCI_XGS_IPROC -+ phy = devm_usb_get_phy_by_phandle(&dev->dev, "usb-phy", 0); -+ if (IS_ERR(phy)) { -+ dev_err(&dev->dev, "unable to find transceiver\n"); -+ return PTR_ERR(phy); -+ } -+ -+ if (phy->flags != IPROC_USB_MODE_HOST) -+ return -ENODEV; -+#endif /* CONFIG_USB_OHCI_XGS_IPROC */ -+ - /* - * Use reasonable defaults so platforms don't have to provide these - * with DT probing on ARM. -@@ -251,6 +273,12 @@ static int ohci_platform_probe(struct pl - hcd->rsrc_start = res_mem->start; - hcd->rsrc_len = resource_size(res_mem); - -+#ifdef CONFIG_USB_OHCI_XGS_IPROC -+#if defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3) || defined(CONFIG_MACH_GH2) -+ writel(readl(hcd->regs + UHCRHDA_REG_OFFSET) | UHCRHDA_OCPM, hcd->regs + UHCRHDA_REG_OFFSET); -+#endif -+#endif -+ - err = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (err) - goto err_power; -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig ---- a/drivers/usb/phy/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/usb/phy/Kconfig 2017-11-09 17:54:02.191425000 +0800 -@@ -213,4 +213,11 @@ config USB_ULPI_VIEWPORT - Provides read/write operations to the ULPI phy register set for - controllers with a viewport register (e.g. Chipidea/ARC controllers). - -+config USBPHY_XGS_IPROC -+ tristate "BRCM iProc USB PHY" -+ depends on ARCH_XGS_IPROC -+ select USB_PHY -+ help -+ BRCM iProc USB PHY driver -+ - endmenu -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile ---- a/drivers/usb/phy/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/usb/phy/Makefile 2017-11-09 17:54:02.191443000 +0800 -@@ -27,3 +27,4 @@ obj-$(CONFIG_USB_RCAR_PHY) += phy-rcar- - obj-$(CONFIG_USB_ULPI) += phy-ulpi.o - obj-$(CONFIG_USB_ULPI_VIEWPORT) += phy-ulpi-viewport.o - obj-$(CONFIG_KEYSTONE_USB_PHY) += phy-keystone.o -+obj-$(CONFIG_USBPHY_XGS_IPROC) += phy-xgs-iproc.o -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/usb/phy/phy-xgs-iproc.c b/drivers/usb/phy/phy-xgs-iproc.c ---- a/drivers/usb/phy/phy-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/usb/phy/phy-xgs-iproc.c 2017-11-09 17:54:02.236439000 +0800 -@@ -0,0 +1,745 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+#define USB2D_IDM_IDM_IO_CONTROL_DIRECT_ADDR(base) (base + 0x408) -+#define USB2D_IDM_IDM_RESET_CONTROL_ADDR(base) (base + 0x800) -+#define IPROC_WRAP_MISC_STATUS__USBPHY_PLL_LOCK 1 -+#define USB2D_IDM_IDM_RESET_CONTROL__RESET 0 -+#define USB2D_IDM_IDM_IO_CONTROL_DIRECT__clk_enable 0 -+ -+#if defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) -+ -+#define IPROC_CCB_MDIO_MII_CTRL_ADDR(base) (base + 0x0) -+#define IPROC_CCB_MDIO_MII_DATA_ADDR(base) (base + 0x4) -+#define IPROC_CCB_MDIO_COMPATIBLE "brcm,iproc-ccb-mdio" -+ -+#if defined(CONFIG_MACH_HX4) -+#define IPROC_WRAP_IPROC_XGPLL_CTRL_0_ADDR(base) (base + 0x1c) -+#define IPROC_WRAP_IPROC_XGPLL_CTRL_4_ADDR(base) (base + 0x2c) -+#define IPROC_WRAP_USBPHY_CTRL_ADDR(base) (base + 0x34) -+#define IPROC_WRAP_MISC_STATUS_ADDR(base) (base + 0x38) -+#define IPROC_CLK_NDIV_40 0x80 -+#define IPROC_CLK_NDIV_20 0x8C -+#define USB_CLK_NDIV_MASK 0xFE7FFE00 -+#define USB_CLK_PLL_RESET_MASK 0xFF7FFE00 -+#define USB_CLK_PHY_RESET_MASK 0xFFFFFE00 -+#define USB_CLK_NDIV_40 0x30 -+#define USB_CLK_NDIV_20 0x60 -+#define IPROC_WRAP_IPROC_XGPLL_CTRL_4__NDIV_INT_R 0 -+#define IPROC_WRAP_IPROC_XGPLL_CTRL_4__NDIV_INT_WIDTH 8 -+#define IPROC_WRAP_IPROC_XGPLL_CTRL_0__CH3_MDIV_R 8 -+#define IPROC_WRAP_IPROC_XGPLL_CTRL_0__CH3_MDIV_WIDTH 8 -+#else -+#define IPROC_DDR_PLL_CTRL_REGISTER_3_ADDR(base) (base + 0x0c) -+#define IPROC_DDR_PLL_CTRL_REGISTER_5_ADDR(base) (base + 0x14) -+#define IPROC_WRAP_USBPHY_CTRL_ADDR(base) (base + 0x20) -+#define IPROC_WRAP_MISC_STATUS_ADDR(base) (base + 0x28) -+#define IPROC_DDR_PLL_CTRL_REGISTER_3__NDIV_INT_R 0 -+#define IPROC_DDR_PLL_CTRL_REGISTER_3__NDIV_INT_WIDTH 10 -+#define IPROC_DDR_PLL_CTRL_REGISTER_5__CH1_MDIV_R 0 -+#define IPROC_DDR_PLL_CTRL_REGISTER_5__CH1_MDIV_WIDTH 8 -+#endif /* defined(CONFIG_MACH_HX4) */ -+ -+#else /* defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) */ -+ -+#define IPROC_WRAP_USBPHY_CTRL_0__PHY_IDDQ 26 -+#define IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB 25 -+#define IPROC_WRAP_USBPHY_CTRL_0__RESETB 24 -+#define IPROC_WRAP_USBPHY_CTRL_2__PHY_ISO 17 -+#define IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B0 0 -+#define IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B11 11 -+ -+#if defined(CONFIG_MACH_SB2) -+#define IPROC_WRAP_USBPHY_CTRL_0_ADDR(base) (base + 0x28) -+#define IPROC_WRAP_USBPHY_CTRL_2_ADDR(base) (base + 0x30) -+#define IPROC_WRAP_MISC_STATUS_ADDR(base) (base + 0x44) -+#define IPROC_WRAP_TOP_STRAP_CTRL_ADDR(base) (base + 0x70) -+#define IPROC_WRAP_TOP_STRAP_CTRL__USB_DEVICE 10 -+ -+#elif defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3) || \ -+ defined(CONFIG_MACH_GH2) -+#define IPROC_WRAP_USBPHY_CTRL_0_ADDR(base) (base + 0x44) -+#define IPROC_WRAP_USBPHY_CTRL_2_ADDR(base) (base + 0x4c) -+#define IPROC_WRAP_MISC_STATUS_ADDR(base) (base + 0x58) -+#define IPROC_WRAP_TOP_STRAP_STATUS_ADDR(base) (base + 0xa4) -+#define IPROC_WRAP_TOP_STRAP_STATUS__USB2_SEL 17 -+#if defined(CONFIG_MACH_GH2) -+#define USBH_Utmi_p0Ctl(base) (base + 0x10) -+static void __iomem *USBH_Utmi_base = NULL; -+#endif /* defined(CONFIG_MACH_GH2) */ -+#endif -+ -+#endif /* defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2) */ -+ -+struct iproc_usb_priv { -+ struct usb_phy phy; -+ struct device *dev; -+ struct device_node *dn; -+ void __iomem *wrap_base; -+ void __iomem *idm_base; -+ uint usb_mode; -+}; -+ -+extern void __iomem *get_iproc_wrap_ctrl_base(void); -+ -+/*************************************************************************** -+**************************************************************************** -+***************************************************************************/ -+static const struct of_device_id xgs_iproc_usb_phy_dt_ids[] = { -+ { .compatible = "brcm,usb-phy,hx4", }, -+ { .compatible = "brcm,usb-phy,kt2", }, -+ { .compatible = "brcm,usb-phy,gh", }, -+ { .compatible = "brcm,usb-phy,sb2", }, -+ { .compatible = "brcm,usb-phy,hr3", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, xgs_iproc_usb_phy_dt_ids); -+ -+ -+static int xgs_iproc_usb_phy_mode(struct iproc_usb_priv *iproc_usb_data) -+{ -+ void __iomem *wrap_base = iproc_usb_data->wrap_base; -+ struct device *dev = iproc_usb_data->dev; -+ int usb_mode = IPROC_USB_MODE_HOST; -+ ulong val; -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) -+ int gpio_pin, ret; -+#endif /* (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) */ -+ -+ if (!wrap_base) { -+ return -EINVAL; -+ } -+ -+#if (defined(CONFIG_MACH_HX4) || defined(CONFIG_MACH_KT2)) -+ /* gpio pin 4 to control host/device mode */ -+ gpio_pin = of_get_named_gpio(dev->of_node, "usbdev-gpio", 0); -+ -+ if (gpio_pin < 0) { -+ dev_warn(dev, "No gpio pin set for USB device detection(default to 4)\n"); -+ gpio_pin = 4; -+ } -+ -+ ret = gpio_request(gpio_pin, "usbdev-gpio"); -+ if (ret != 0) { -+ dev_err(dev, "request gpio #%d error.\n", gpio_pin); -+ return ret; -+ } -+ -+ val = __gpio_get_value(gpio_pin); -+ -+ gpio_free(gpio_pin); -+ -+ if (val & 1) { -+ usb_mode = IPROC_USB_MODE_DEVICE; -+ } -+#elif defined(CONFIG_MACH_SB2) -+ /* u-boot enable this bit to indicate usb in host mode */ -+ val = readl_relaxed(IPROC_WRAP_TOP_STRAP_CTRL_ADDR(wrap_base)); -+ if (!(val & (1 << IPROC_WRAP_TOP_STRAP_CTRL__USB_DEVICE))) { -+ usb_mode = IPROC_USB_MODE_DEVICE; -+ } -+#else -+ /* u-boot enable this bit to indicate usb in host mode */ -+ val = readl_relaxed(IPROC_WRAP_TOP_STRAP_STATUS_ADDR(wrap_base)); -+ if (!(val & (1 << IPROC_WRAP_TOP_STRAP_STATUS__USB2_SEL))) { -+ usb_mode = IPROC_USB_MODE_DEVICE; -+ } -+#endif -+ -+ dev_info(dev, "usb mode: %s\n", (usb_mode == IPROC_USB_MODE_DEVICE) ? "DEVICE" : "HOST"); -+ -+ return usb_mode; -+} -+ -+#if (defined (CONFIG_MACH_HX4) || defined (CONFIG_MACH_KT2)) -+/* Returns USB PHY PLL ref clock in MHz */ -+static uint _get_usb_clk(void __iomem *wrap_base) -+{ -+ uint ndiv, mdiv, refclk; -+ ulong val; -+ -+#if defined(CONFIG_MACH_HX4) -+ val = readl_relaxed(IPROC_WRAP_IPROC_XGPLL_CTRL_4_ADDR(wrap_base)); -+ ndiv = ((val >> IPROC_WRAP_IPROC_XGPLL_CTRL_4__NDIV_INT_R) & -+ ~(0xFFFFFFFF << IPROC_WRAP_IPROC_XGPLL_CTRL_4__NDIV_INT_WIDTH)); -+ -+ val = readl_relaxed(IPROC_WRAP_IPROC_XGPLL_CTRL_0_ADDR(wrap_base)); -+ mdiv = ((val >> IPROC_WRAP_IPROC_XGPLL_CTRL_0__CH3_MDIV_R) & -+ ~(0xFFFFFFFF << IPROC_WRAP_IPROC_XGPLL_CTRL_0__CH3_MDIV_WIDTH)); -+#else -+ val = readl_relaxed(IPROC_DDR_PLL_CTRL_REGISTER_3_ADDR(wrap_base)); -+ ndiv = ((val >> IPROC_DDR_PLL_CTRL_REGISTER_3__NDIV_INT_R) & -+ ~(0xFFFFFFFF << IPROC_DDR_PLL_CTRL_REGISTER_3__NDIV_INT_WIDTH)); -+ -+ /* read channel 1 mdiv */ -+ val = readl_relaxed(IPROC_DDR_PLL_CTRL_REGISTER_5_ADDR(wrap_base)); -+ mdiv = ((val >> IPROC_DDR_PLL_CTRL_REGISTER_5__CH1_MDIV_R) & -+ ~(0xFFFFFFFF << IPROC_DDR_PLL_CTRL_REGISTER_5__CH1_MDIV_WIDTH)); -+#endif -+ -+ refclk = (25 * ndiv) / mdiv; -+ -+ return refclk; -+} -+#endif /* (defined (CONFIG_MACH_HX4) || defined (CONFIG_MACH_KT2)) */ -+ -+static int iproc_usb_phy_hx4_config(struct iproc_usb_priv *iproc_usb_data) -+{ -+#if (defined (CONFIG_MACH_HX4) || defined (CONFIG_MACH_KT2)) -+ void __iomem *wrap_base = iproc_usb_data->wrap_base; -+ void __iomem *ccb_mdio_base = NULL; -+ struct device_node *np; -+ ulong ndiv, precmd, miicmd, miidata; -+ ulong val, mask; -+ uint count = 0; -+ -+ if (!wrap_base) -+ return -EINVAL; -+ -+ if (iproc_usb_data->usb_mode == IPROC_USB_MODE_DEVICE) { -+ np = of_find_compatible_node(NULL, NULL, IPROC_CCB_MDIO_COMPATIBLE); -+ if (!np) { -+ printk(KERN_ERR "Failed to find CCB MDIO defined in DT\n"); -+ return -ENODEV; -+ } -+ -+ ccb_mdio_base = of_iomap(np, 0); -+ if (!ccb_mdio_base) { -+ printk(KERN_ERR "Unable to iomap CCB MDIO base address\n"); -+ return -ENXIO; -+ } -+ -+ ndiv = 1920 / _get_usb_clk(wrap_base); -+ -+ /* Construct precmd with Start Bit, PHY address and turnaround time */ -+ /* SB | PA | TA */ -+ precmd = 1 << 30 | 6 << 23 | 2 << 16; -+ -+ /* Connect MDIO interface to onchip PHY */ -+ writel_relaxed(0x9A, IPROC_CCB_MDIO_MII_CTRL_ADDR(ccb_mdio_base)); -+ mdelay(10); -+ -+ /* Program NDIV and PDIV into 0x1C register */ -+ miicmd = precmd | (0x1 << 28) | (0x1C << 18); -+ miidata = 1 << 12 | ndiv; -+ /* 0x53721040 */ -+ writel_relaxed(miicmd | miidata, IPROC_CCB_MDIO_MII_DATA_ADDR(ccb_mdio_base)); -+ mdelay(10); -+ -+ /* Program other PLL parameters into 0x1D register, disable suspend and put PHY into reset */ -+ miicmd = precmd | (0x1 << 28) | (0x1D << 18); -+ miidata = 1 << 13 | 3 << 8 | 3 << 4 | 0xa; -+ /* 0x5376233a */ -+ writel_relaxed(miicmd | miidata, IPROC_CCB_MDIO_MII_DATA_ADDR(ccb_mdio_base)); -+ mdelay(10); -+ -+ /* Program register 0x15, USB device mode set and get PHY out of reset */ -+ miicmd = precmd | (0x1 << 28) | (0x15 << 18); -+ miidata = 1 << 2 | 1 << 1; -+ /* 0x53560006 */ -+ writel_relaxed(miicmd | miidata, IPROC_CCB_MDIO_MII_DATA_ADDR(ccb_mdio_base)); -+ mdelay(10); -+ -+ /* Program register 0x19, set mdio mode */ -+ miicmd = precmd | (0x1 << 28) | (0x19 << 18); -+ miidata = 1 << 7; -+ /* 0x53660080 */ -+ writel_relaxed(miicmd | miidata, IPROC_CCB_MDIO_MII_DATA_ADDR(ccb_mdio_base)); -+ mdelay(10); -+ -+ /* get the PLL out of reset */ -+ miicmd = precmd | (0x2 << 28) | (0x1D << 18); -+ miidata = 0; -+ writel_relaxed(miicmd | miidata, IPROC_CCB_MDIO_MII_DATA_ADDR(ccb_mdio_base)); -+ mdelay(10); -+ miidata = readl_relaxed(IPROC_CCB_MDIO_MII_DATA_ADDR(ccb_mdio_base)); -+ miicmd = precmd | (0x1 << 28) | (0x1D << 18); -+ miidata |= (1 << 12); -+ /* 0x5376333a */ -+ writel_relaxed(miicmd | miidata, IPROC_CCB_MDIO_MII_DATA_ADDR(ccb_mdio_base)); -+ mdelay(10); -+ -+ if (ccb_mdio_base) { -+ iounmap(ccb_mdio_base); -+ ccb_mdio_base = NULL; -+ } -+ } else { -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); -+ val |= 0x01000000; /* 24:PLL_RESETB = 1 */ -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); -+ -+ mdelay(20); -+ -+ /* check pll_lock */ -+ mask = (1 << IPROC_WRAP_MISC_STATUS__USBPHY_PLL_LOCK); -+ do { -+ val = readl_relaxed(IPROC_WRAP_MISC_STATUS_ADDR(wrap_base)); -+ if ((val & mask) == mask) { -+ break; -+ } else { -+ udelay(10); -+ count ++; -+ } -+ } while(count <= 10); -+ if (count > 10) { -+ printk(KERN_WARNING "%s : PLL not lock! IPROC_WRAP_MISC_STATUS = 0x%08lx\n", -+ __FUNCTION__, val); -+ } -+ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); -+ val &= ~0x00800000; /* 23:RESETB = 0 */ -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); -+ mdelay(100); -+ -+#if defined(CONFIG_MACH_HX4) -+ val = readl_relaxed(IPROC_WRAP_IPROC_XGPLL_CTRL_4_ADDR(wrap_base)); -+ ndiv = ((val >> IPROC_WRAP_IPROC_XGPLL_CTRL_4__NDIV_INT_R) & -+ ~(0xFFFFFFFF << IPROC_WRAP_IPROC_XGPLL_CTRL_4__NDIV_INT_WIDTH)); -+ if (ndiv == IPROC_CLK_NDIV_40) { -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); -+ val = (val & USB_CLK_NDIV_MASK) | USB_CLK_NDIV_40; -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); -+ udelay(10); -+ val = (val & USB_CLK_PLL_RESET_MASK) | USB_CLK_NDIV_40; -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); -+ udelay(10); -+ val = (val & USB_CLK_PHY_RESET_MASK) | USB_CLK_NDIV_40; -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); -+ udelay(10); -+ } else if (ndiv == IPROC_CLK_NDIV_20) { -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); -+ val = (val & USB_CLK_NDIV_MASK) | USB_CLK_NDIV_20; -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); -+ udelay(10); -+ val = (val & USB_CLK_PLL_RESET_MASK) | USB_CLK_NDIV_20; -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); -+ udelay(10); -+ val = (val & USB_CLK_PHY_RESET_MASK) | USB_CLK_NDIV_20; -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); -+ udelay(10); -+ } -+#endif /* CONFIG_MACH_HX4 */ -+ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); -+ val |= 0x00800000; /* 23:RESETB = 1 */ -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_ADDR(wrap_base)); -+ udelay(100); -+ } -+#endif /* (defined (CONFIG_MACH_HX4) || defined (CONFIG_MACH_KT2)) */ -+ -+ return 0; -+} -+ -+static int iproc_usb_phy_sb2_config(struct iproc_usb_priv *iproc_usb_data) -+{ -+#if defined(CONFIG_MACH_SB2) -+ void __iomem *wrap_base = iproc_usb_data->wrap_base; -+ ulong val, mask, count = 0; -+ -+ if (!wrap_base) { -+ return -EINVAL; -+ } -+ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ val |= 0x0c000000; /* 27:PHY_ISO & 26:PLL_SUSPEND_EN = 1 */ -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ val &= ~0x03000000; /* 25:PLL_RESETB & 24:RESETB = 0 */ -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+ val &= ~0x03000000; /* 25:AFE_BG_PWRDWNB & 24:AFE_LDO_PWRDWNB = 0 */ -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+ udelay(10); -+ val |= 0x02000000; /* 25:AFE_BG_PWRDWNB = 1 */ -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+ udelay(150); -+ val |= 0x01000000; /* 24:AFE_LDO_PWRDWNB = 1 */ -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+ udelay(160); -+ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ val &= ~0x08000000; /* 27:PHY_ISO = 0 */ -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ udelay(20); -+ val |= 0x02000000; /* 25:PLL_RESETB = 1 */ -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ -+ mdelay(20); -+ -+ /* check pll_lock */ -+ mask = (1 << IPROC_WRAP_MISC_STATUS__USBPHY_PLL_LOCK); -+ do { -+ val = readl_relaxed(IPROC_WRAP_MISC_STATUS_ADDR(wrap_base)); -+ if ((val & mask) == mask) { -+ break; -+ } else { -+ udelay(10); -+ count ++; -+ } -+ } while(count <= 10); -+ -+ if (count > 10) -+ printk(KERN_WARNING "%s : PLL not lock! IPROC_WRAP_MISC_STATUS = 0x%08lx\n", -+ __FUNCTION__, val); -+ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ val |= 0x01000000; /* 24:RESETB = 1 */ -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ udelay(2); -+#endif /* defined(CONFIG_MACH_SB2) */ -+ -+ return 0; -+} -+ -+static int iproc_usb_phy_gh_config(struct iproc_usb_priv *iproc_usb_data) -+{ -+#if defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3) || \ -+ defined (CONFIG_MACH_GH2) -+ void __iomem *wrap_base = iproc_usb_data->wrap_base; -+ ulong val, mask, count = 0; -+ -+ if (!wrap_base) -+ return -EINVAL; -+ -+#if !defined(CONFIG_MACH_GH2) -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+ val |= (1 << IPROC_WRAP_USBPHY_CTRL_2__PHY_ISO); -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ val |= (1 << IPROC_WRAP_USBPHY_CTRL_0__PHY_IDDQ); -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+ val |= (1 << IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B0); -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+ -+ /* set phy_resetb to 0, pll_resetb to 0 */ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_0__RESETB); -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB); -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ -+ /* set p1ctl[11] to 0 */ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B11); -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+ -+ /* set phy_iso to 0 */ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_2__PHY_ISO); -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+ -+ /* set phy_iddq to 0 */ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_0__PHY_IDDQ); -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ -+ mdelay(1); -+ -+ /* set pll_resetb to 1, phy_resetb to 1 */ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ val |= (1 << IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB); -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+ val |= (1 << IPROC_WRAP_USBPHY_CTRL_0__RESETB); -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); -+#else /* !defined(CONFIG_MACH_GH2) */ -+ /* This value is from the designer to set Internal Power Sequence Mode */ -+ val = readl_relaxed(IPROC_WRAP_TOP_STRAP_STATUS_ADDR(wrap_base)); -+ if (!(val & (1 << IPROC_WRAP_TOP_STRAP_STATUS__USB2_SEL))) { -+ /* device mode */ -+ writel_relaxed(0x0806, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+ } else { -+ /* host mode */ -+ writel_relaxed(0x0802, USBH_Utmi_p0Ctl(USBH_Utmi_base)); -+ } -+#endif /* !defined(CONFIG_MACH_GH2) */ -+ mdelay(20); -+ -+ /* check pll_lock */ -+ mask = (1 << IPROC_WRAP_MISC_STATUS__USBPHY_PLL_LOCK); -+ do { -+ val = readl_relaxed(IPROC_WRAP_MISC_STATUS_ADDR(wrap_base)); -+ if ((val & mask) == mask) { -+ break; -+ } else { -+ udelay(10); -+ count ++; -+ } -+ } while(count <= 10); -+ -+ if (count > 10) { -+ printk(KERN_WARNING "%s : PLL not lock! IPROC_WRAP_MISC_STATUS = 0x%08lx\n", -+ __FUNCTION__, val); -+ } -+ -+#if !defined(CONFIG_MACH_GH2) -+ /* set non_drving to 0 */ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B0); -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+ -+ /* set p1ctl[11] to 1 */ -+ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+ val |= (1 << IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B11); -+ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); -+#endif /* !defined(CONFIG_MACH_GH2) */ -+#endif /* defined(CONFIG_MACH_GH) || defined(CONFIG_MACH_HR3) || defined (CONFI -+G_MACH_GH2) */ -+ -+ return 0; -+} -+ -+static int iproc_usb_phy_init(struct usb_phy *phy) -+{ -+ struct iproc_usb_priv *iproc_usb_data = container_of(phy, struct iproc_usb_priv, phy); -+ struct device *dev = iproc_usb_data->dev; -+ const struct of_device_id *match; -+ int ret = 0; -+ uint val; -+ -+ if (!iproc_usb_data->wrap_base || !iproc_usb_data->idm_base) { -+ return -EINVAL; -+ } -+ -+ match = of_match_device(xgs_iproc_usb_phy_dt_ids, dev); -+ if (!match) { -+ dev_err(dev, "failed to find USB PHY in DT\n"); -+ return -ENODEV; -+ } -+ -+ /* Put USBD controller into reset state and disable clock via IDM registers */ -+ val = readl_relaxed(USB2D_IDM_IDM_RESET_CONTROL_ADDR(iproc_usb_data->idm_base)); -+ val |= (1 << USB2D_IDM_IDM_RESET_CONTROL__RESET); -+ writel_relaxed(val, USB2D_IDM_IDM_RESET_CONTROL_ADDR(iproc_usb_data->idm_base)); -+ -+ val = readl_relaxed(USB2D_IDM_IDM_IO_CONTROL_DIRECT_ADDR(iproc_usb_data->idm_base)); -+ val &= ~(1 << USB2D_IDM_IDM_IO_CONTROL_DIRECT__clk_enable); -+ writel_relaxed(val, USB2D_IDM_IDM_IO_CONTROL_DIRECT_ADDR(iproc_usb_data->idm_base)); -+ -+ if (strstr(match->compatible, "hx4") || -+ strstr(match->compatible, "kt2")) -+ ret = iproc_usb_phy_hx4_config(iproc_usb_data); -+ else if (strstr(match->compatible, "sb2")) -+ ret = iproc_usb_phy_sb2_config(iproc_usb_data); -+#if !defined(CONFIG_MACH_GH2) -+ else -+ ret = iproc_usb_phy_gh_config(iproc_usb_data); -+#endif -+ -+ /* Enable clock to USBD and get the USBD out of reset */ -+ val = readl_relaxed(USB2D_IDM_IDM_IO_CONTROL_DIRECT_ADDR(iproc_usb_data->idm_base)); -+ val |= (1 << USB2D_IDM_IDM_IO_CONTROL_DIRECT__clk_enable); -+ writel_relaxed(val, USB2D_IDM_IDM_IO_CONTROL_DIRECT_ADDR(iproc_usb_data->idm_base)); -+ -+ mdelay(10); -+ val = readl_relaxed(USB2D_IDM_IDM_RESET_CONTROL_ADDR(iproc_usb_data->idm_base)); -+ val &= ~(1 << USB2D_IDM_IDM_RESET_CONTROL__RESET); -+ writel_relaxed(val, USB2D_IDM_IDM_RESET_CONTROL_ADDR(iproc_usb_data->idm_base)); -+ -+#if defined(CONFIG_MACH_GH2) -+ /* In GH2, it must init PHY after RESET */ -+ mdelay(100); -+ ret = iproc_usb_phy_gh_config(iproc_usb_data); -+#endif -+ -+ return ret; -+} -+ -+static int xgs_iproc_usb_phy_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *dn = pdev->dev.of_node; -+ struct iproc_usb_priv *iproc_usb_data; -+ int gpio_pin; -+ enum of_gpio_flags flags; -+ u32 gpio_active_low; -+ u32 __maybe_unused val; -+ int ret, usb_mode; -+ -+ if (!of_device_is_available(dn)) -+ return -ENODEV; -+ -+ iproc_usb_data = devm_kzalloc(dev, sizeof(*iproc_usb_data), GFP_KERNEL); -+ if (!iproc_usb_data) { -+ dev_err(dev, "devm_kzalloc() failed\n" ); -+ return -ENOMEM; -+ } -+ memset(iproc_usb_data, 0, sizeof(*iproc_usb_data)); -+ platform_set_drvdata(pdev, iproc_usb_data); -+ -+ iproc_usb_data->dev = dev; -+ iproc_usb_data->dn = dn; -+ -+ iproc_usb_data->wrap_base = get_iproc_wrap_ctrl_base(); -+ if (!iproc_usb_data->wrap_base) { -+ dev_err(&pdev->dev, "can't iomap usb phy base address\n"); -+ ret = -ENOMEM; -+ goto err1; -+ } -+ -+ gpio_pin = of_get_named_gpio_flags(dn, "vbus-gpio", 0, &flags); -+ -+ if (gpio_pin < 0) { -+ dev_err(&pdev->dev, "Error: no gpio pin set for USB power\n"); -+ return gpio_pin; -+ } -+ -+ gpio_active_low = flags & OF_GPIO_ACTIVE_LOW; -+ -+ ret = gpio_request(gpio_pin, "usbphy-vbus"); -+ if (ret != 0) { -+ dev_err(dev, "request gpio #%d error.\n", gpio_pin); -+ goto err1; -+ } -+ -+ usb_mode = xgs_iproc_usb_phy_mode(iproc_usb_data); -+ -+ iproc_usb_data->usb_mode = usb_mode; -+ iproc_usb_data->phy.dev = dev; -+ iproc_usb_data->phy.flags = usb_mode; -+ iproc_usb_data->phy.init = iproc_usb_phy_init; -+ iproc_usb_data->phy.type = USB_PHY_TYPE_USB2; -+ -+ if (usb_mode == IPROC_USB_MODE_DEVICE) { -+ iproc_usb_data->idm_base = (void *)of_iomap(dn, 1); -+ if (!iproc_usb_data->idm_base) { -+ dev_err(&pdev->dev, "can't iomap usb2d idm base address 1\n"); -+ ret = -ENOMEM; -+ goto err2; -+ } -+ -+ gpio_direction_input(gpio_pin); -+ } else { -+ -+#if defined(CONFIG_MACH_GH2) -+ USBH_Utmi_base = (void *)of_iomap(dn, 2); -+ if (!USBH_Utmi_base) { -+ dev_err(&pdev->dev, "can't iomap usb2h idm base address 2\n"); -+ ret = -ENOMEM; -+ goto err2; -+ } -+#endif -+ iproc_usb_data->idm_base = (void *)of_iomap(dn, 0); -+ if (!iproc_usb_data->idm_base) { -+ dev_err(&pdev->dev, "can't iomap usb2h idm base address 0\n"); -+ ret = -ENOMEM; -+ goto err2; -+ } -+ -+ gpio_direction_output(gpio_pin, 1); -+ -+ /*turn off the power: if active low for power, then set 1 to turn off*/ -+ if (gpio_active_low) -+ __gpio_set_value(gpio_pin, 1); -+ else -+ __gpio_set_value(gpio_pin, 0); -+ -+ /* -+ Initial usb phy for usb host mode. For the device mode, -+ the iproc_usb_phy_init will be called when usb udc start. -+ */ -+ ret = iproc_usb_phy_init(&iproc_usb_data->phy); -+ if (ret < 0) -+ goto err2; -+ } -+ -+ ret = usb_add_phy_dev(&iproc_usb_data->phy); -+ if (ret) -+ goto err2; -+ -+ /* supply power for USB device connected to the host */ -+ if (usb_mode != IPROC_USB_MODE_DEVICE) { -+ if (gpio_active_low) -+ __gpio_set_value(gpio_pin, 0); -+ else -+ __gpio_set_value(gpio_pin, 1); -+ } -+ gpio_free(gpio_pin); -+ -+ return 0; -+ -+err2: -+ gpio_free(gpio_pin); -+err1: -+ if (iproc_usb_data->idm_base) { -+ iounmap(iproc_usb_data->idm_base); -+ } -+ if (iproc_usb_data) { -+ iounmap(iproc_usb_data); -+ } -+#if defined(CONFIG_MACH_GH2) -+ if (USBH_Utmi_base) { -+ iounmap(USBH_Utmi_base); -+ USBH_Utmi_base = NULL; -+ } -+#endif -+ return ret; -+} -+ -+static int xgs_iproc_usb_phy_remove(struct platform_device *pdev) -+{ -+ struct iproc_usb_priv *iproc_usb_data = platform_get_drvdata(pdev); -+ -+ platform_set_drvdata(pdev, NULL); -+ if (iproc_usb_data->idm_base) { -+ iounmap(iproc_usb_data->idm_base); -+ usb_remove_phy(&iproc_usb_data->phy); -+ } -+ -+ if (iproc_usb_data) -+ iounmap(iproc_usb_data); -+ -+#if defined(CONFIG_MACH_GH2) -+ if (USBH_Utmi_base) { -+ iounmap(USBH_Utmi_base); -+ USBH_Utmi_base = NULL; -+ } -+#endif -+ -+ return 0; -+} -+ -+static struct platform_driver xgs_iproc_usb_phy_driver = -+{ -+ .driver = { -+ .name = "usb-phy", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(xgs_iproc_usb_phy_dt_ids), -+ }, -+ .probe = xgs_iproc_usb_phy_probe, -+ .remove = xgs_iproc_usb_phy_remove, -+}; -+ -+module_platform_driver(xgs_iproc_usb_phy_driver); -+ -+MODULE_AUTHOR("Broadcom"); -+MODULE_DESCRIPTION("Broadcom USB phy driver"); -+MODULE_LICENSE("GPL"); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig ---- a/drivers/watchdog/Kconfig 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/watchdog/Kconfig 2017-11-09 17:54:04.039439000 +0800 -@@ -578,6 +578,14 @@ config LPC18XX_WATCHDOG - To compile this driver as a module, choose M here: the - module will be called lpc18xx_wdt. - -+config XGS_IPROC_SP805_WDT -+ tristate "BRCM XGS iProc watchdog based on SP805" -+ depends on (ARCH_XGS_IPROC || COMPILE_TEST) -+ select WATCHDOG_CORE -+ help -+ Say Y here to include support for the watchdog timer -+ embedded in BRCM XGS iProc SoCs. -+ - # AVR32 Architecture - - config AT32AP700X_WDT -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile ---- a/drivers/watchdog/Makefile 2016-12-16 00:49:34.000000000 +0800 -+++ b/drivers/watchdog/Makefile 2017-11-09 17:54:04.040435000 +0800 -@@ -69,6 +69,7 @@ obj-$(CONFIG_MEDIATEK_WATCHDOG) += mtk_w - obj-$(CONFIG_DIGICOLOR_WATCHDOG) += digicolor_wdt.o - obj-$(CONFIG_LPC18XX_WATCHDOG) += lpc18xx_wdt.o - obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o -+obj-$(CONFIG_XGS_IPROC_SP805_WDT) += xgs_iproc_sp805_wdt.o - - # AVR32 Architecture - obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/drivers/watchdog/xgs_iproc_sp805_wdt.c b/drivers/watchdog/xgs_iproc_sp805_wdt.c ---- a/drivers/watchdog/xgs_iproc_sp805_wdt.c 1970-01-01 08:00:00.000000000 +0800 -+++ b/drivers/watchdog/xgs_iproc_sp805_wdt.c 2017-11-09 17:54:04.252451000 +0800 -@@ -0,0 +1,381 @@ -+/* -+ * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved. -+ * -+ * 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. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* default timeout in seconds */ -+#define DEFAULT_TIMEOUT 60 -+ -+#define MODULE_NAME "iproc-sp805-wdt" -+ -+/* watchdog register offsets and masks */ -+#define WDTLOAD 0x000 -+ #define LOAD_MIN 0x00000001 -+ #define LOAD_MAX 0xFFFFFFFF -+#define WDTVALUE 0x004 -+#define WDTCONTROL 0x008 -+ /* control register masks */ -+ #define INT_ENABLE (1 << 0) -+ #define RESET_ENABLE (1 << 1) -+#define WDTINTCLR 0x00C -+#define WDTRIS 0x010 -+#define WDTMIS 0x014 -+ #define INT_MASK (1 << 0) -+#define WDTLOCK 0xC00 -+ #define UNLOCK 0x1ACCE551 -+ #define LOCK 0x00000001 -+ -+/** -+ * struct sp805_wdt: sp805 wdt device structure -+ * @wdd: instance of struct watchdog_device -+ * @lock: spin lock protecting dev structure and io access -+ * @base: base address of wdt -+ * @clk: clock structure of wdt -+ * @adev: amba device structure of wdt -+ * @load_val: load value to be set for current timeout -+ */ -+struct sp805_wdt { -+ struct watchdog_device wdd; -+ spinlock_t lock; -+ void __iomem *base; -+ struct clk *clk; -+ struct amba_device *adev; -+ unsigned int load_val; -+}; -+ -+static bool nowayout = WATCHDOG_NOWAYOUT; -+module_param(nowayout, bool, 0); -+MODULE_PARM_DESC(nowayout, -+ "Set to 1 to keep watchdog running after device release"); -+ -+/* This routine get boot status to indicate if the last boot is from WDT */ -+static unsigned int wdt_get_clear_bootstatus( -+ void __iomem *wdt_bootstatus, -+ unsigned int wdt_bootstatus_bit) -+{ -+ unsigned int reg; -+ unsigned int bootstatus = 0; -+ -+ reg = readl_relaxed(wdt_bootstatus); -+ bootstatus = reg & (1 << wdt_bootstatus_bit); -+ -+ if (bootstatus) -+ /* write 1 to clear boot status bit */ -+ writel_relaxed(reg, wdt_bootstatus); -+ -+ return bootstatus; -+} -+ -+/* This routine finds load value that will reset system in required timout */ -+static int wdt_setload(struct watchdog_device *wdd, unsigned int timeout) -+{ -+ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd); -+ u64 load, rate; -+ -+ rate = clk_get_rate(wdt->clk); -+ -+ /* -+ * sp805 runs counter with given value twice, after the end of first -+ * counter it gives an interrupt and then starts counter again. If -+ * interrupt already occurred then it resets the system. This is why -+ * load is half of what should be required. -+ */ -+ load = div_u64(rate, 2) * timeout - 1; -+ -+ load = (load > LOAD_MAX) ? LOAD_MAX : load; -+ load = (load < LOAD_MIN) ? LOAD_MIN : load; -+ -+ spin_lock(&wdt->lock); -+ wdt->load_val = load; -+ /* roundup timeout to closest positive integer value */ -+ wdd->timeout = div_u64((load + 1) * 2 + (rate / 2), rate); -+ spin_unlock(&wdt->lock); -+ -+ return 0; -+} -+ -+/* returns number of seconds left for reset to occur */ -+static unsigned int wdt_timeleft(struct watchdog_device *wdd) -+{ -+ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd); -+ u64 load, rate; -+ -+ rate = clk_get_rate(wdt->clk); -+ -+ spin_lock(&wdt->lock); -+ load = readl_relaxed(wdt->base + WDTVALUE); -+ -+ /* If the interrupt is inactive then time left is WDTValue + WDTLoad. */ -+ if (!(readl_relaxed(wdt->base + WDTRIS) & INT_MASK)) -+ load += wdt->load_val + 1; -+ spin_unlock(&wdt->lock); -+ -+ return div_u64(load, rate); -+} -+ -+static int wdt_config(struct watchdog_device *wdd, bool ping) -+{ -+ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd); -+ int ret; -+ -+ if (!ping) { -+ ret = clk_prepare(wdt->clk); -+ if (ret) { -+ dev_err(&wdt->adev->dev, "clock prepare fail"); -+ return ret; -+ } -+ -+ ret = clk_enable(wdt->clk); -+ if (ret) { -+ dev_err(&wdt->adev->dev, "clock enable fail"); -+ clk_unprepare(wdt->clk); -+ return ret; -+ } -+ } -+ -+ spin_lock(&wdt->lock); -+ -+ writel_relaxed(UNLOCK, wdt->base + WDTLOCK); -+ writel_relaxed(wdt->load_val, wdt->base + WDTLOAD); -+ writel_relaxed(INT_MASK, wdt->base + WDTINTCLR); -+ -+ if (!ping) -+ writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base + -+ WDTCONTROL); -+ -+ writel_relaxed(LOCK, wdt->base + WDTLOCK); -+ -+ /* Flush posted writes. */ -+ readl_relaxed(wdt->base + WDTLOCK); -+ spin_unlock(&wdt->lock); -+ -+ return 0; -+} -+ -+static int wdt_ping(struct watchdog_device *wdd) -+{ -+ return wdt_config(wdd, true); -+} -+ -+/* enables watchdog timers reset */ -+static int wdt_enable(struct watchdog_device *wdd) -+{ -+ return wdt_config(wdd, false); -+} -+ -+/* disables watchdog timers reset */ -+static int wdt_disable(struct watchdog_device *wdd) -+{ -+ struct sp805_wdt *wdt = watchdog_get_drvdata(wdd); -+ -+ spin_lock(&wdt->lock); -+ -+ writel_relaxed(UNLOCK, wdt->base + WDTLOCK); -+ writel_relaxed(0, wdt->base + WDTCONTROL); -+ writel_relaxed(LOCK, wdt->base + WDTLOCK); -+ -+ /* Flush posted writes. */ -+ readl_relaxed(wdt->base + WDTLOCK); -+ spin_unlock(&wdt->lock); -+ -+ clk_disable(wdt->clk); -+ clk_unprepare(wdt->clk); -+ -+ return 0; -+} -+ -+static const struct watchdog_info wdt_info = { -+ .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, -+ .identity = MODULE_NAME, -+}; -+ -+static const struct watchdog_ops wdt_ops = { -+ .owner = THIS_MODULE, -+ .start = wdt_enable, -+ .stop = wdt_disable, -+ .ping = wdt_ping, -+ .set_timeout = wdt_setload, -+ .get_timeleft = wdt_timeleft, -+}; -+ -+static int sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id) -+{ -+ struct sp805_wdt *wdt; -+ int ret; -+ struct device_node *dnode = adev->dev.of_node; -+ void __iomem *wdt_bootstatus = NULL; -+ unsigned int bootstatus_bit = 0; -+ -+ wdt = devm_kzalloc(&adev->dev, sizeof(*wdt), GFP_KERNEL); -+ if (!wdt) { -+ dev_err(&adev->dev, "Kzalloc failed\n"); -+ ret = -ENOMEM; -+ goto error1; -+ } -+ -+ wdt->base = of_iomap(dnode, 0); -+ if (!wdt->base) { -+ ret = -ENOMEM; -+ dev_err(&adev->dev, "of_iomap failed\n"); -+ goto error2; -+ } -+ -+ wdt_bootstatus = of_iomap(dnode, 1); -+ if (!wdt_bootstatus) { -+ ret = -ENOMEM; -+ dev_err(&adev->dev, "of_iomap failed\n"); -+ goto error2; -+ } -+ -+ wdt->clk = of_clk_get(dnode, 0); -+ if (IS_ERR(wdt->clk)) { -+ dev_err(&adev->dev, "Clock not found\n"); -+ ret = PTR_ERR(wdt->clk); -+ goto error2; -+ } -+ -+ wdt->adev = adev; -+ wdt->wdd.info = &wdt_info; -+ wdt->wdd.ops = &wdt_ops; -+ -+ spin_lock_init(&wdt->lock); -+ watchdog_set_nowayout(&wdt->wdd, nowayout); -+ watchdog_set_drvdata(&wdt->wdd, wdt); -+ wdt_setload(&wdt->wdd, DEFAULT_TIMEOUT); -+ -+ ret = watchdog_register_device(&wdt->wdd); -+ if (ret) { -+ dev_err(&adev->dev, "watchdog_register_device() failed: %d\n", -+ ret); -+ goto error3; -+ } -+ -+ amba_set_drvdata(adev, wdt); -+ -+ ret = of_property_read_u32(dnode, "wdt_boot_status_bit", -+ &bootstatus_bit); -+ if (ret) { -+ dev_err(&adev->dev, "failed getting DT bootstatus bit\n"); -+ goto error3; -+ } -+ -+ wdt->wdd.bootstatus = wdt_get_clear_bootstatus( -+ wdt_bootstatus, -+ bootstatus_bit); -+ -+ dev_info(&adev->dev, "registration successful\n"); -+ dev_info(&adev->dev, "timeout=%d sec, nowayout=%d\n", -+ DEFAULT_TIMEOUT, nowayout); -+ -+ return 0; -+ -+error3: -+ clk_put(wdt->clk); -+ -+error2: -+ if (wdt->base) -+ iounmap(wdt->base); -+ if (wdt_bootstatus) -+ iounmap(wdt_bootstatus); -+ kfree(wdt); -+ -+error1: -+ dev_err(&adev->dev, "Probe Failed!!!\n"); -+ -+ return ret; -+} -+ -+static int sp805_wdt_remove(struct amba_device *adev) -+{ -+ struct sp805_wdt *wdt = amba_get_drvdata(adev); -+ -+ watchdog_unregister_device(&wdt->wdd); -+ amba_set_drvdata(adev, NULL); -+ watchdog_set_drvdata(&wdt->wdd, NULL); -+ clk_put(wdt->clk); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int sp805_wdt_suspend(struct device *dev) -+{ -+ struct sp805_wdt *wdt = dev_get_drvdata(dev); -+ -+ if (watchdog_active(&wdt->wdd)) -+ return wdt_disable(&wdt->wdd); -+ -+ return 0; -+} -+ -+static int sp805_wdt_resume(struct device *dev) -+{ -+ struct sp805_wdt *wdt = dev_get_drvdata(dev); -+ -+ if (watchdog_active(&wdt->wdd)) -+ return wdt_enable(&wdt->wdd); -+ -+ return 0; -+} -+#endif /* CONFIG_PM */ -+ -+static SIMPLE_DEV_PM_OPS(sp805_wdt_dev_pm_ops, sp805_wdt_suspend, -+ sp805_wdt_resume); -+ -+static struct amba_id sp805_wdt_ids[] = { -+ { -+ .id = 0x00141805, -+ .mask = 0x00ffffff, -+ }, -+ { 0, 0 }, -+}; -+MODULE_DEVICE_TABLE(amba, sp805_wdt_ids); -+ -+static struct amba_driver sp805_wdt_driver = { -+ .drv = { -+ .name = MODULE_NAME, -+ .pm = &sp805_wdt_dev_pm_ops, -+ }, -+ .id_table = sp805_wdt_ids, -+ .probe = sp805_wdt_probe, -+ .remove = sp805_wdt_remove, -+}; -+ -+module_amba_driver(sp805_wdt_driver); -+ -+MODULE_AUTHOR("Viresh Kumar "); -+MODULE_DESCRIPTION("ARM SP805 Watchdog Driver"); -+MODULE_LICENSE("GPL"); -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h ---- a/include/linux/mtd/spi-nor.h 2016-12-16 00:49:34.000000000 +0800 -+++ b/include/linux/mtd/spi-nor.h 2017-11-09 17:54:11.415490000 +0800 -@@ -183,6 +183,9 @@ struct spi_nor { - int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len); - - void *priv; -+#ifdef CONFIG_M25PXX_STAY_IN_3BYTE_MODE -+ void *priv1; -+#endif - }; - - /** -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/include/linux/soc/bcm/xgs-iproc-wrap-idm-dmu.h b/include/linux/soc/bcm/xgs-iproc-wrap-idm-dmu.h ---- a/include/linux/soc/bcm/xgs-iproc-wrap-idm-dmu.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/include/linux/soc/bcm/xgs-iproc-wrap-idm-dmu.h 2017-11-09 17:54:12.456502000 +0800 -@@ -0,0 +1,15 @@ -+/* -+ * $Copyright Open Broadcom Corporation$ -+ */ -+ -+#ifndef XGS_IPROC_WRAP_IDM_DMU_H -+#define XGS_IPROC_WRAP_IDM_DMU_H -+ -+extern int xgs_iproc_wrap_idm_dmu_base_reg_setup(void); -+extern void xgs_iproc_idm_timeout_handler_setup(void); -+extern void __iomem *get_iproc_wrap_ctrl_base(void); -+extern void __iomem *get_iproc_dmu_pcu_base(void); -+extern void __iomem *get_iproc_idm_base(int index); -+extern void __iomem *get_iproc_idm_base_phys(int index); -+ -+#endif -diff -uprN -EbwB --no-dereference -X /projects/ntsw-sw7/home/chena/TEMP/XLDK_releasebuild12/INTERNAL/release/tools/dontdiff a/include/linux/usb/iproc_usb.h b/include/linux/usb/iproc_usb.h ---- a/include/linux/usb/iproc_usb.h 1970-01-01 08:00:00.000000000 +0800 -+++ b/include/linux/usb/iproc_usb.h 2017-11-09 17:54:12.826524000 +0800 -@@ -0,0 +1,20 @@ -+/* -+ * iproc_usb.h -- USB defines for XGS IPROC USB drivers -+ * -+ * Copyright (C) 2015 Broadcom Limited. -+ * -+ * This software is distributed under the terms of the GNU General -+ * Public License ("GPL") as published by the Free Software Foundation, -+ * version 2 of that License. -+ */ -+ -+#ifndef __LINUX_USB_IPROC_USB_H -+#define __LINUX_USB_IPROC_USB_H -+ -+/* USB Flags */ -+ -+#define IPROC_USB_MODE_HOST (0) -+#define IPROC_USB_MODE_DEVICE (1) -+ -+#endif /* __LINUX_USB_IPROC_USB_H */ -+ diff --git a/packages/base/any/kernels/4.4-lts/patches/series b/packages/base/any/kernels/4.4-lts/patches/series deleted file mode 100644 index db86ea76..00000000 --- a/packages/base/any/kernels/4.4-lts/patches/series +++ /dev/null @@ -1 +0,0 @@ -kernel-4.4-brcm-iproc.patch diff --git a/packages/base/any/kernels/modules/ym2651y.c b/packages/base/any/kernels/modules/ym2651y.c index 4b3b8a09..8e8cc540 100644 --- a/packages/base/any/kernels/modules/ym2651y.c +++ b/packages/base/any/kernels/modules/ym2651y.c @@ -33,724 +33,716 @@ #include #include -#define MAX_FAN_DUTY_CYCLE 100 -#define I2C_RW_RETRY_COUNT 10 -#define I2C_RW_RETRY_INTERVAL 60 /* ms */ +#define MAX_FAN_DUTY_CYCLE 100 +#define I2C_RW_RETRY_COUNT 10 +#define I2C_RW_RETRY_INTERVAL 60 /* ms */ + +static int support_i2c_block = 1; // 1: support I2C_FUNC_SMBUS_I2C_BLOCK 0: not support /* Addresses scanned */ static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; enum chips { - YM2651, - YM2401, - YM2851, + YM2651, + YM2401, + YM2851, + YM1921, }; /* Each client has this additional data */ struct ym2651y_data { - struct device *hwmon_dev; - struct mutex update_lock; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - u8 chip; /* chip id */ - u8 capability; /* Register value */ - u16 status_word; /* Register value */ - u8 fan_fault; /* Register value */ - u8 over_temp; /* Register value */ - u16 v_out; /* Register value */ - u16 i_out; /* Register value */ - u16 p_out; /* Register value */ - u8 vout_mode; /* Register value */ - u16 temp; /* Register value */ - u16 fan_speed; /* Register value */ - u16 fan_duty_cycle[2]; /* Register value */ - u8 fan_dir[5]; /* Register value */ - u8 pmbus_revision; /* Register value */ - u8 mfr_id[10]; /* Register value */ - u8 mfr_model[16]; /* Register value */ - u8 mfr_revsion[3]; /* Register value */ - u8 mfr_serial[20]; /* Register value */ - u16 mfr_vin_min; /* Register value */ - u16 mfr_vin_max; /* Register value */ - u16 mfr_iin_max; /* Register value */ - u16 mfr_iout_max; /* Register value */ - u16 mfr_pin_max; /* Register value */ - u16 mfr_pout_max; /* Register value */ - u16 mfr_vout_min; /* Register value */ - u16 mfr_vout_max; /* Register value */ + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 chip; /* chip id */ + u8 capability; /* Register value */ + u16 status_word; /* Register value */ + u8 fan_fault; /* Register value */ + u8 over_temp; /* Register value */ + u16 v_out; /* Register value */ + u16 i_out; /* Register value */ + u16 p_out; /* Register value */ + u8 vout_mode; /* Register value */ + u16 temp; /* Register value */ + u16 fan_speed; /* Register value */ + u16 fan_duty_cycle[2]; /* Register value */ + u8 fan_dir[5]; /* Register value */ + u8 pmbus_revision; /* Register value */ + u8 mfr_id[10]; /* Register value */ + u8 mfr_model[16]; /* Register value */ + u8 mfr_revsion[3]; /* Register value */ + u8 mfr_serial[20]; /* Register value */ + u16 mfr_vin_min; /* Register value */ + u16 mfr_vin_max; /* Register value */ + u16 mfr_iin_max; /* Register value */ + u16 mfr_iout_max; /* Register value */ + u16 mfr_pin_max; /* Register value */ + u16 mfr_pout_max; /* Register value */ + u16 mfr_vout_min; /* Register value */ + u16 mfr_vout_max; /* Register value */ }; static ssize_t show_byte(struct device *dev, struct device_attribute *da, - char *buf); + char *buf); static ssize_t show_word(struct device *dev, struct device_attribute *da, - char *buf); + char *buf); static ssize_t show_linear(struct device *dev, struct device_attribute *da, - char *buf); + char *buf); static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf); static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, - char *buf); + char *buf); static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, - char *buf); + char *buf); static ssize_t show_ascii(struct device *dev, struct device_attribute *da, - char *buf); + char *buf); static struct ym2651y_data *ym2651y_update_device(struct device *dev); static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, - const char *buf, size_t count); + const char *buf, size_t count); static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value); enum ym2651y_sysfs_attributes { - PSU_POWER_ON = 0, - PSU_TEMP_FAULT, - PSU_POWER_GOOD, - PSU_FAN1_FAULT, - PSU_FAN_DIRECTION, - PSU_OVER_TEMP, - PSU_V_OUT, - PSU_I_OUT, - PSU_P_OUT, - PSU_P_OUT_UV, /*In Unit of microVolt, instead of mini.*/ - PSU_TEMP1_INPUT, - PSU_FAN1_SPEED, - PSU_FAN1_DUTY_CYCLE, - PSU_PMBUS_REVISION, - PSU_MFR_ID, - PSU_MFR_MODEL, - PSU_MFR_REVISION, - PSU_MFR_SERIAL, - PSU_MFR_VIN_MIN, - PSU_MFR_VIN_MAX, - PSU_MFR_VOUT_MIN, - PSU_MFR_VOUT_MAX, - PSU_MFR_IIN_MAX, - PSU_MFR_IOUT_MAX, - PSU_MFR_PIN_MAX, - PSU_MFR_POUT_MAX + PSU_POWER_ON = 0, + PSU_TEMP_FAULT, + PSU_POWER_GOOD, + PSU_FAN1_FAULT, + PSU_FAN_DIRECTION, + PSU_OVER_TEMP, + PSU_V_OUT, + PSU_I_OUT, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_FAN1_SPEED, + PSU_FAN1_DUTY_CYCLE, + PSU_PMBUS_REVISION, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_REVISION, + PSU_MFR_SERIAL, + PSU_MFR_VIN_MIN, + PSU_MFR_VIN_MAX, + PSU_MFR_VOUT_MIN, + PSU_MFR_VOUT_MAX, + PSU_MFR_IIN_MAX, + PSU_MFR_IOUT_MAX, + PSU_MFR_PIN_MAX, + PSU_MFR_POUT_MAX }; /* sysfs attributes for hwmon */ -static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON); -static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); -static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD); -static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); -static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP); -static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout, NULL, PSU_V_OUT); -static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); -static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); -static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_power_on, S_IRUGO, show_word, NULL, PSU_POWER_ON); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_word, NULL, PSU_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, show_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_over_temp, S_IRUGO, show_over_temp, NULL, PSU_OVER_TEMP); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, show_linear, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, show_linear, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); -static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION); +static SENSOR_DEVICE_ATTR(psu_fan_dir, S_IRUGO, show_ascii, NULL, PSU_FAN_DIRECTION); static SENSOR_DEVICE_ATTR(psu_pmbus_revision,S_IRUGO, show_byte, NULL, PSU_PMBUS_REVISION); -static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID); -static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL); -static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION); -static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, show_ascii, NULL, PSU_MFR_SERIAL); -static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN); -static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN); -static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX); -static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX); - -/*Duplicate nodes for lm-sensors.*/ -static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_linear, NULL, PSU_V_OUT); -static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_linear, NULL, PSU_I_OUT); -static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_linear, NULL, PSU_P_OUT_UV); -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_linear, NULL, PSU_TEMP1_INPUT); -static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); -static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_word, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, show_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_revision, S_IRUGO, show_ascii, NULL, PSU_MFR_REVISION); +static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, show_ascii, NULL, PSU_MFR_SERIAL); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_min, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vin_max, S_IRUGO, show_linear, NULL, PSU_MFR_VIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_min, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MIN); +static SENSOR_DEVICE_ATTR(psu_mfr_vout_max, S_IRUGO, show_linear, NULL, PSU_MFR_VOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iin_max, S_IRUGO, show_linear, NULL, PSU_MFR_IIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_iout_max, S_IRUGO, show_linear, NULL, PSU_MFR_IOUT_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pin_max, S_IRUGO, show_linear, NULL, PSU_MFR_PIN_MAX); +static SENSOR_DEVICE_ATTR(psu_mfr_pout_max, S_IRUGO, show_linear, NULL, PSU_MFR_POUT_MAX); static struct attribute *ym2651y_attributes[] = { - &sensor_dev_attr_psu_power_on.dev_attr.attr, - &sensor_dev_attr_psu_temp_fault.dev_attr.attr, - &sensor_dev_attr_psu_power_good.dev_attr.attr, - &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, - &sensor_dev_attr_psu_over_temp.dev_attr.attr, - &sensor_dev_attr_psu_v_out.dev_attr.attr, - &sensor_dev_attr_psu_i_out.dev_attr.attr, - &sensor_dev_attr_psu_p_out.dev_attr.attr, - &sensor_dev_attr_psu_temp1_input.dev_attr.attr, - &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, - &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, - &sensor_dev_attr_psu_fan_dir.dev_attr.attr, - &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr, - &sensor_dev_attr_psu_mfr_id.dev_attr.attr, - &sensor_dev_attr_psu_mfr_model.dev_attr.attr, - &sensor_dev_attr_psu_mfr_revision.dev_attr.attr, - &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr, - &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr, - &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr, - /*Duplicate nodes for lm-sensors.*/ - &sensor_dev_attr_curr2_input.dev_attr.attr, - &sensor_dev_attr_in2_input.dev_attr.attr, - &sensor_dev_attr_power2_input.dev_attr.attr, - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_fan1_input.dev_attr.attr, - &sensor_dev_attr_temp1_fault.dev_attr.attr, - NULL + &sensor_dev_attr_psu_power_on.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_over_temp.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan_dir.dev_attr.attr, + &sensor_dev_attr_psu_pmbus_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_revision.dev_attr.attr, + &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_pin_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_min.dev_attr.attr, + &sensor_dev_attr_psu_mfr_vout_max.dev_attr.attr, + &sensor_dev_attr_psu_mfr_iout_max.dev_attr.attr, + NULL }; static ssize_t show_byte(struct device *dev, struct device_attribute *da, - char *buf) + char *buf) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - - if (!data->valid) { - return 0; - } + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + + if (!data->valid) { + return 0; + } - return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) : - sprintf(buf, "0\n"); + return (attr->index == PSU_PMBUS_REVISION) ? sprintf(buf, "%d\n", data->pmbus_revision) : + sprintf(buf, "0\n"); } static ssize_t show_word(struct device *dev, struct device_attribute *da, - char *buf) + char *buf) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - u16 status = 0; - - if (!data->valid) { - return 0; - } + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u16 status = 0; + + if (!data->valid) { + return 0; + } - switch (attr->index) { - case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */ - status = (data->status_word & 0x40) ? 0 : 1; - break; - case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */ - status = (data->status_word & 0x4) >> 2; - break; - case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */ - status = (data->status_word & 0x800) ? 0 : 1; - break; - } + switch (attr->index) { + case PSU_POWER_ON: /* psu_power_on, low byte bit 6 of status_word, 0=>ON, 1=>OFF */ + status = (data->status_word & 0x40) ? 0 : 1; + break; + case PSU_TEMP_FAULT: /* psu_temp_fault, low byte bit 2 of status_word, 0=>Normal, 1=>temp fault */ + status = (data->status_word & 0x4) >> 2; + break; + case PSU_POWER_GOOD: /* psu_power_good, high byte bit 3 of status_word, 0=>OK, 1=>FAIL */ + status = (data->status_word & 0x800) ? 0 : 1; + break; + } - return sprintf(buf, "%d\n", status); + return sprintf(buf, "%d\n", status); } static int two_complement_to_int(u16 data, u8 valid_bit, int mask) { - u16 valid_data = data & mask; - bool is_negative = valid_data >> (valid_bit - 1); + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); - return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; } static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) + const char *buf, size_t count) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); - int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; - long speed; - int error; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; - error = kstrtol(buf, 10, &speed); - if (error) - return error; + error = kstrtol(buf, 10, &speed); + if (error) + return error; - if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) - return -EINVAL; + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; - mutex_lock(&data->update_lock); - data->fan_duty_cycle[nr] = speed; - ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); - mutex_unlock(&data->update_lock); + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + ym2651y_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); - return count; + return count; } static ssize_t show_linear(struct device *dev, struct device_attribute *da, - char *buf) + char *buf) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); - u16 value = 0; - int exponent, mantissa; - int multiplier = 1000; + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; - if (!data->valid) { - return 0; - } - - switch (attr->index) { - case PSU_V_OUT: - value = data->v_out; - break; - case PSU_I_OUT: - value = data->i_out; - break; - case PSU_P_OUT_UV: - multiplier = 1000000; /*For lm-sensors, unit is micro-Volt.*/ - /*Passing through*/ - case PSU_P_OUT: - value = data->p_out; - break; - case PSU_TEMP1_INPUT: - value = data->temp; - break; - case PSU_FAN1_SPEED: - value = data->fan_speed; - multiplier = 1; - break; - case PSU_FAN1_DUTY_CYCLE: - value = data->fan_duty_cycle[0]; - multiplier = 1; - break; - case PSU_MFR_VIN_MIN: - value = data->mfr_vin_min; - break; - case PSU_MFR_VIN_MAX: - value = data->mfr_vin_max; - break; - case PSU_MFR_VOUT_MIN: - value = data->mfr_vout_min; - break; - case PSU_MFR_VOUT_MAX: - value = data->mfr_vout_max; - break; - case PSU_MFR_PIN_MAX: - value = data->mfr_pin_max; - break; - case PSU_MFR_POUT_MAX: - value = data->mfr_pout_max; - break; - case PSU_MFR_IOUT_MAX: - value = data->mfr_iout_max; - break; - case PSU_MFR_IIN_MAX: - value = data->mfr_iin_max; - break; - } + if (!data->valid) { + return 0; + } + + switch (attr->index) { + case PSU_V_OUT: + value = data->v_out; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp; + break; + case PSU_FAN1_SPEED: + value = data->fan_speed; + multiplier = 1; + break; + case PSU_FAN1_DUTY_CYCLE: + value = data->fan_duty_cycle[0]; + multiplier = 1; + break; + case PSU_MFR_VIN_MIN: + value = data->mfr_vin_min; + break; + case PSU_MFR_VIN_MAX: + value = data->mfr_vin_max; + break; + case PSU_MFR_VOUT_MIN: + value = data->mfr_vout_min; + break; + case PSU_MFR_VOUT_MAX: + value = data->mfr_vout_max; + break; + case PSU_MFR_PIN_MAX: + value = data->mfr_pin_max; + break; + case PSU_MFR_POUT_MAX: + value = data->mfr_pout_max; + break; + case PSU_MFR_IOUT_MAX: + value = data->mfr_iout_max; + break; + case PSU_MFR_IIN_MAX: + value = data->mfr_iin_max; + break; + } - exponent = two_complement_to_int(value >> 11, 5, 0x1f); - mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); - return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); } static ssize_t show_fan_fault(struct device *dev, struct device_attribute *da, - char *buf) + char *buf) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - u8 shift; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u8 shift; - if (!data->valid) { - return 0; - } - - shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + if (!data->valid) { + return 0; + } + + shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; - return sprintf(buf, "%d\n", data->fan_fault >> shift); + return sprintf(buf, "%d\n", data->fan_fault >> shift); } static ssize_t show_over_temp(struct device *dev, struct device_attribute *da, - char *buf) + char *buf) { - struct ym2651y_data *data = ym2651y_update_device(dev); + struct ym2651y_data *data = ym2651y_update_device(dev); - if (!data->valid) { - return 0; - } - - return sprintf(buf, "%d\n", data->over_temp >> 7); + if (!data->valid) { + return 0; + } + + return sprintf(buf, "%d\n", data->over_temp >> 7); } static ssize_t show_ascii(struct device *dev, struct device_attribute *da, - char *buf) + char *buf) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct ym2651y_data *data = ym2651y_update_device(dev); - u8 *ptr = NULL; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ym2651y_data *data = ym2651y_update_device(dev); + u8 *ptr = NULL; - if (!data->valid) { - return 0; - } - - switch (attr->index) { - case PSU_FAN_DIRECTION: /* psu_fan_dir */ - ptr = data->fan_dir + 1; /* Skip the first byte since it is the length of string. */ - break; - case PSU_MFR_ID: /* psu_mfr_id */ - ptr = data->mfr_id + 1; /* The first byte is the count byte of string. */; - break; - case PSU_MFR_MODEL: /* psu_mfr_model */ - ptr = data->mfr_model + 1; /* The first byte is the count byte of string. */ - break; - case PSU_MFR_REVISION: /* psu_mfr_revision */ - ptr = data->mfr_revsion + 1; /* The first byte is the count byte of string. */ - break; - case PSU_MFR_SERIAL: /* psu_mfr_serial */ - ptr = data->mfr_serial + 1; /* The first byte is the count byte of string. */ - break; - default: - return 0; - } + if (!data->valid) { + return 0; + } + + switch (attr->index) { + case PSU_FAN_DIRECTION: /* psu_fan_dir */ + ptr = data->fan_dir + 1; /* Skip the first byte since it is the length of string. */ + break; + case PSU_MFR_ID: /* psu_mfr_id */ + ptr = data->mfr_id + 1; /* The first byte is the count byte of string. */; + break; + case PSU_MFR_MODEL: /* psu_mfr_model */ + ptr = data->mfr_model + 1; /* The first byte is the count byte of string. */ + break; + case PSU_MFR_REVISION: /* psu_mfr_revision */ + ptr = data->mfr_revsion + 1; /* The first byte is the count byte of string. */ + break; + case PSU_MFR_SERIAL: /* psu_mfr_serial */ + ptr = data->mfr_serial + 1; /* The first byte is the count byte of string. */ + break; + default: + return 0; + } - return sprintf(buf, "%s\n", ptr); + return sprintf(buf, "%s\n", ptr); } static ssize_t show_vout_by_mode(struct device *dev, struct device_attribute *da, char *buf) { - struct ym2651y_data *data = ym2651y_update_device(dev); - int exponent, mantissa; - int multiplier = 1000; + struct ym2651y_data *data = ym2651y_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; - if (!data->valid) { - return 0; - } + if (!data->valid) { + return 0; + } - exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); - mantissa = data->v_out; + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; - return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); + return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); } static ssize_t show_vout(struct device *dev, struct device_attribute *da, char *buf) { - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); - if (data->chip == YM2401) { - return show_vout_by_mode(dev, da, buf); - } + if (data->chip == YM2401) { + return show_vout_by_mode(dev, da, buf); + } - return show_linear(dev, da, buf); + return show_linear(dev, da, buf); } static const struct attribute_group ym2651y_group = { - .attrs = ym2651y_attributes, + .attrs = ym2651y_attributes, }; static int ym2651y_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) + const struct i2c_device_id *dev_id) { - struct ym2651y_data *data; - int status; + struct ym2651y_data *data; + int status; - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_I2C_BLOCK)) { - status = -EIO; - goto exit; - } + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA )) { + status = -EIO; + goto exit; + } + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_I2C_BLOCK)) { + support_i2c_block = 0; + } + + data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } - data = kzalloc(sizeof(struct ym2651y_data), GFP_KERNEL); - if (!data) { - status = -ENOMEM; - goto exit; - } + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->chip = dev_id->driver_data; + dev_info(&client->dev, "chip found\n"); - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - data->chip = dev_id->driver_data; - dev_info(&client->dev, "chip found\n"); + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &ym2651y_group); + if (status) { + goto exit_free; + } - /* Register sysfs hooks */ - status = sysfs_create_group(&client->dev.kobj, &ym2651y_group); - if (status) { - goto exit_free; - } + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - status = PTR_ERR(data->hwmon_dev); - goto exit_remove; - } + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); - dev_info(&client->dev, "%s: psu '%s'\n", - dev_name(data->hwmon_dev), client->name); - - return 0; + return 0; exit_remove: - sysfs_remove_group(&client->dev.kobj, &ym2651y_group); + sysfs_remove_group(&client->dev.kobj, &ym2651y_group); exit_free: - kfree(data); + kfree(data); exit: - return status; + return status; } static int ym2651y_remove(struct i2c_client *client) { - struct ym2651y_data *data = i2c_get_clientdata(client); + struct ym2651y_data *data = i2c_get_clientdata(client); - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &ym2651y_group); - kfree(data); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &ym2651y_group); + kfree(data); - return 0; + return 0; } static const struct i2c_device_id ym2651y_id[] = { - { "ym2651", YM2651 }, - { "ym2401", YM2401 }, - { "ym2851", YM2851 }, - {} + { "ym2651", YM2651 }, + { "ym2401", YM2401 }, + { "ym2851", YM2851 }, + { "ym1921", YM1921 }, + {} }; MODULE_DEVICE_TABLE(i2c, ym2651y_id); static struct i2c_driver ym2651y_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "ym2651", - }, - .probe = ym2651y_probe, - .remove = ym2651y_remove, - .id_table = ym2651y_id, - .address_list = normal_i2c, + .class = I2C_CLASS_HWMON, + .driver = { + .name = "ym2651", + }, + .probe = ym2651y_probe, + .remove = ym2651y_remove, + .id_table = ym2651y_id, + .address_list = normal_i2c, }; static int ym2651y_read_byte(struct i2c_client *client, u8 reg) { - int status = 0, retry = I2C_RW_RETRY_COUNT; + int status = 0, retry = I2C_RW_RETRY_COUNT; - while (retry) { - status = i2c_smbus_read_byte_data(client, reg); - if (unlikely(status < 0)) { - msleep(I2C_RW_RETRY_INTERVAL); - retry--; - continue; - } + while (retry) { + status = i2c_smbus_read_byte_data(client, reg); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } - break; - } + break; + } return status; } static int ym2651y_read_word(struct i2c_client *client, u8 reg) { - int status = 0, retry = I2C_RW_RETRY_COUNT; + int status = 0, retry = I2C_RW_RETRY_COUNT; - while (retry) { - status = i2c_smbus_read_word_data(client, reg); - if (unlikely(status < 0)) { - msleep(I2C_RW_RETRY_INTERVAL); - retry--; - continue; - } + while (retry) { + status = i2c_smbus_read_word_data(client, reg); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } - break; - } + break; + } return status; } static int ym2651y_write_word(struct i2c_client *client, u8 reg, u16 value) { - int status = 0, retry = I2C_RW_RETRY_COUNT; + int status = 0, retry = I2C_RW_RETRY_COUNT; - while (retry) { - status = i2c_smbus_write_word_data(client, reg, value); - if (unlikely(status < 0)) { - msleep(I2C_RW_RETRY_INTERVAL); - retry--; - continue; - } + while (retry) { + status = i2c_smbus_write_word_data(client, reg, value); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } - break; - } + break; + } return status; } static int ym2651y_read_block(struct i2c_client *client, u8 command, u8 *data, - int data_len) + int data_len) { - int status = 0, retry = I2C_RW_RETRY_COUNT; + int status = 0, retry = I2C_RW_RETRY_COUNT; - while (retry) { - status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); - if (unlikely(status < 0)) { - msleep(I2C_RW_RETRY_INTERVAL); - retry--; - continue; - } + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } - break; - } + break; + } return status; } struct reg_data_byte { - u8 reg; - u8 *value; + u8 reg; + u8 *value; }; struct reg_data_word { - u8 reg; - u16 *value; + u8 reg; + u16 *value; }; static struct ym2651y_data *ym2651y_update_device(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct ym2651y_data *data = i2c_get_clientdata(client); + struct i2c_client *client = to_i2c_client(dev); + struct ym2651y_data *data = i2c_get_clientdata(client); - mutex_lock(&data->update_lock); + mutex_lock(&data->update_lock); - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { - int i, status, length; - u8 command, buf; - struct reg_data_byte regs_byte[] = { {0x19, &data->capability}, - {0x20, &data->vout_mode}, - {0x7d, &data->over_temp}, - {0x81, &data->fan_fault}, - {0x98, &data->pmbus_revision}}; - struct reg_data_word regs_word[] = { {0x79, &data->status_word}, - {0x8b, &data->v_out}, - {0x8c, &data->i_out}, - {0x96, &data->p_out}, - {0x8d, &data->temp}, - {0x3b, &(data->fan_duty_cycle[0])}, - {0x3c, &(data->fan_duty_cycle[1])}, - {0x90, &data->fan_speed}, - {0xa0, &data->mfr_vin_min}, - {0xa1, &data->mfr_vin_max}, - {0xa2, &data->mfr_iin_max}, - {0xa3, &data->mfr_pin_max}, - {0xa4, &data->mfr_vout_min}, - {0xa5, &data->mfr_vout_max}, - {0xa6, &data->mfr_iout_max}, - {0xa7, &data->mfr_pout_max}}; + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int i, status, length; + u8 command, buf; + struct reg_data_byte regs_byte[] = { {0x19, &data->capability}, + {0x20, &data->vout_mode}, + {0x7d, &data->over_temp}, + {0x81, &data->fan_fault}, + {0x98, &data->pmbus_revision}}; + struct reg_data_word regs_word[] = { {0x79, &data->status_word}, + {0x8b, &data->v_out}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x8d, &data->temp}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x3c, &(data->fan_duty_cycle[1])}, + {0x90, &data->fan_speed}, + {0xa0, &data->mfr_vin_min}, + {0xa1, &data->mfr_vin_max}, + {0xa2, &data->mfr_iin_max}, + {0xa3, &data->mfr_pin_max}, + {0xa4, &data->mfr_vout_min}, + {0xa5, &data->mfr_vout_max}, + {0xa6, &data->mfr_iout_max}, + {0xa7, &data->mfr_pout_max}}; - dev_dbg(&client->dev, "Starting ym2651 update\n"); - data->valid = 0; + dev_dbg(&client->dev, "Starting ym2651 update\n"); + data->valid = 0; - /* Read byte data */ - for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { - status = ym2651y_read_byte(client, regs_byte[i].reg); + /* Read byte data */ + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = ym2651y_read_byte(client, regs_byte[i].reg); - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_byte[i].reg, status); - goto exit; - } - else { - *(regs_byte[i].value) = status; - } - } + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + goto exit; + } + else { + *(regs_byte[i].value) = status; + } + } - /* Read word data */ - for (i = 0; i < ARRAY_SIZE(regs_word); i++) { - status = ym2651y_read_word(client, regs_word[i].reg); + /* Read word data */ + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = ym2651y_read_word(client, regs_word[i].reg); - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_word[i].reg, status); - goto exit; - } - else { - *(regs_word[i].value) = status; - } - } + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + goto exit; + } + else { + *(regs_word[i].value) = status; + } + } - /* Read fan_direction */ - command = 0xC3; - status = ym2651y_read_block(client, command, data->fan_dir, - ARRAY_SIZE(data->fan_dir)-1); - data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0'; + if (support_i2c_block) { + + /* Read fan_direction */ + command = 0xC3; + status = ym2651y_read_block(client, command, data->fan_dir, + ARRAY_SIZE(data->fan_dir)-1); + data->fan_dir[ARRAY_SIZE(data->fan_dir)-1] = '\0'; - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } - /* Read mfr_id */ - command = 0x99; - status = ym2651y_read_block(client, command, data->mfr_id, - ARRAY_SIZE(data->mfr_id)-1); - data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0'; - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - - /* Read mfr_model */ - command = 0x9a; - length = 1; - - /* Read first byte to determine the length of data */ - status = ym2651y_read_block(client, command, &buf, length); - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - - status = ym2651y_read_block(client, command, data->mfr_model, buf+1); - data->mfr_model[buf+1] = '\0'; - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - - /* Read mfr_revsion */ - command = 0x9b; - status = ym2651y_read_block(client, command, data->mfr_revsion, - ARRAY_SIZE(data->mfr_revsion)-1); - data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0'; - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - - /* Read mfr_serial */ - command = 0x9e; - status = ym2651y_read_block(client, command, data->mfr_serial, - ARRAY_SIZE(data->mfr_serial)-1); - data->mfr_serial[ARRAY_SIZE(data->mfr_serial)-1] = '\0'; - - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - goto exit; - } - - data->last_updated = jiffies; - data->valid = 1; - } + /* Read mfr_id */ + command = 0x99; + status = ym2651y_read_block(client, command, data->mfr_id, + ARRAY_SIZE(data->mfr_id)-1); + data->mfr_id[ARRAY_SIZE(data->mfr_id)-1] = '\0'; + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + /* Read mfr_model */ + command = 0x9a; + length = 1; + + /* Read first byte to determine the length of data */ + status = ym2651y_read_block(client, command, &buf, length); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + status = ym2651y_read_block(client, command, data->mfr_model, buf+1); + data->mfr_model[buf+1] = '\0'; + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + /* Read mfr_revsion */ + command = 0x9b; + status = ym2651y_read_block(client, command, data->mfr_revsion, + ARRAY_SIZE(data->mfr_revsion)-1); + data->mfr_revsion[ARRAY_SIZE(data->mfr_revsion)-1] = '\0'; + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + + /* Read mfr_serial */ + command = 0x9e; + status = ym2651y_read_block(client, command, data->mfr_serial, + ARRAY_SIZE(data->mfr_serial)-1); + data->mfr_serial[ARRAY_SIZE(data->mfr_serial)-1] = '\0'; + + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + goto exit; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } exit: - mutex_unlock(&data->update_lock); + mutex_unlock(&data->update_lock); - return data; + return data; } static int __init ym2651y_init(void) { - return i2c_add_driver(&ym2651y_driver); + return i2c_add_driver(&ym2651y_driver); } static void __exit ym2651y_exit(void) { - i2c_del_driver(&ym2651y_driver); + i2c_del_driver(&ym2651y_driver); } MODULE_AUTHOR("Brandon Chuang "); diff --git a/packages/base/any/templates/platform-config-platform.yml b/packages/base/any/templates/platform-config-platform.yml index a053373f..ece4c088 100644 --- a/packages/base/any/templates/platform-config-platform.yml +++ b/packages/base/any/templates/platform-config-platform.yml @@ -18,6 +18,7 @@ common: maintainer: support@bigswitch.com support: opennetworklinux@googlegroups.com changelog: None + dists: $DISTS packages: - name: onl-platform-config-$PLATFORM diff --git a/packages/base/armel/kernels/kernel-3.2-lts-arm-iproc-all/PKG.yml b/packages/base/armel/kernels/kernel-3.2-lts-arm-iproc-all/PKG.yml index 45503a7f..ab016a9f 100644 --- a/packages/base/armel/kernels/kernel-3.2-lts-arm-iproc-all/PKG.yml +++ b/packages/base/armel/kernels/kernel-3.2-lts-arm-iproc-all/PKG.yml @@ -5,6 +5,7 @@ common: copyright: Copyright 2013, 2014, 2015 Big Switch Networks maintainer: support@bigswitch.com support: opennetworklinux@googlegroups.com + dists: jessie packages: - name: onl-kernel-3.2-lts-arm-iproc-all diff --git a/packages/base/armel/kernels/kernel-4.4-lts-arm-iproc-all/Makefile b/packages/base/armel/kernels/kernel-4.14-lts-armel-iproc-all/Makefile similarity index 100% rename from packages/base/armel/kernels/kernel-4.4-lts-arm-iproc-all/Makefile rename to packages/base/armel/kernels/kernel-4.14-lts-armel-iproc-all/Makefile diff --git a/packages/base/armel/kernels/kernel-4.14-lts-armel-iproc-all/PKG.yml b/packages/base/armel/kernels/kernel-4.14-lts-armel-iproc-all/PKG.yml new file mode 100644 index 00000000..4ff5b41f --- /dev/null +++ b/packages/base/armel/kernels/kernel-4.14-lts-armel-iproc-all/PKG.yml @@ -0,0 +1 @@ +!include $ONL/packages/base/any/kernels/lts/APKG.yml VERSION=4.14 ARCH=armel CONFIG=armel-iproc-all diff --git a/packages/base/armel/kernels/kernel-4.4-lts-arm-iproc-all/builds/.gitignore b/packages/base/armel/kernels/kernel-4.14-lts-armel-iproc-all/builds/.gitignore similarity index 100% rename from packages/base/armel/kernels/kernel-4.4-lts-arm-iproc-all/builds/.gitignore rename to packages/base/armel/kernels/kernel-4.14-lts-armel-iproc-all/builds/.gitignore diff --git a/packages/base/armel/kernels/kernel-4.14-lts-armel-iproc-all/builds/Makefile b/packages/base/armel/kernels/kernel-4.14-lts-armel-iproc-all/builds/Makefile new file mode 100644 index 00000000..023ecdb6 --- /dev/null +++ b/packages/base/armel/kernels/kernel-4.14-lts-armel-iproc-all/builds/Makefile @@ -0,0 +1,5 @@ +KERNEL_BUILD_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) +KERNEL_ARCH := arm +KERNEL_LTS_VERSION := 4.14 +KERNEL_CONFIG := armel-iproc-all +include $(ONL)/packages/base/any/kernels/lts/builds/Makefile diff --git a/packages/base/armel/kernels/kernel-4.4-lts-arm-iproc-all/PKG.yml b/packages/base/armel/kernels/kernel-4.4-lts-arm-iproc-all/PKG.yml deleted file mode 100644 index 1d1f5758..00000000 --- a/packages/base/armel/kernels/kernel-4.4-lts-arm-iproc-all/PKG.yml +++ /dev/null @@ -1,18 +0,0 @@ - -common: - arch: armel - version: 1.0.0 - copyright: Copyright 2013, 2014, 2015 Big Switch Networks - maintainer: support@bigswitch.com - support: opennetworklinux@googlegroups.com - -packages: - - name: onl-kernel-4.4-lts-arm-iproc-all - version: 1.0.0 - summary: Open Network Linux Kernel 4.4-LTS for ARM Integrated Processor Platforms. - - files: - builds/kernel-4.4-lts-arm-iproc-all.bin.gz : $$PKG_INSTALL/ - builds/linux-4.4.*-mbuild : $$PKG_INSTALL/mbuilds - - changelog: Change changes changes., diff --git a/packages/base/armel/kernels/kernel-4.4-lts-arm-iproc-all/builds/Makefile b/packages/base/armel/kernels/kernel-4.4-lts-arm-iproc-all/builds/Makefile deleted file mode 100644 index 642762a8..00000000 --- a/packages/base/armel/kernels/kernel-4.4-lts-arm-iproc-all/builds/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# -*- Makefile -*- -############################################################ -# -# -# Copyright 2013, 2014 BigSwitch Networks, Inc. -# -# -# -# -############################################################ -THIS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) - -include $(ONL)/make/config.mk - -#export MODSYNCLIST_EXTRA := arch/arm/plat-iproc/include - -kernel: - $(MAKE) -C $(ONL)/packages/base/any/kernels/4.4-lts/configs/arm-iproc-all K_TARGET_DIR=$(THIS_DIR) $(ONL_MAKE_PARALLEL) - -clean: - rm -rf kernel-* linux-4.4.* diff --git a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/modules/PKG.yml b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/modules/PKG.yml index c2f59267..44a0e946 100644 --- a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/modules/PKG.yml +++ b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/modules/PKG.yml @@ -1 +1 @@ -!include $ONL_TEMPLATES/no-platform-modules.yml ARCH=armel VENDOR=accton BASENAME=arm-accton-as4610-30 +!include $ONL_TEMPLATES/platform-modules.yml ARCH=armel VENDOR=accton BASENAME=arm-accton-as4610-30 KERNELS="onl-kernel-4.14-lts-armel-iproc-all:armel" diff --git a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/modules/builds/.gitignore b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/modules/builds/.gitignore new file mode 100644 index 00000000..a65b4177 --- /dev/null +++ b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/modules/builds/.gitignore @@ -0,0 +1 @@ +lib diff --git a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/modules/builds/Makefile b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/modules/builds/Makefile new file mode 100644 index 00000000..440a0ff3 --- /dev/null +++ b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/modules/builds/Makefile @@ -0,0 +1,7 @@ +KERNELS := onl-kernel-4.14-lts-armel-iproc-all:armel +KMODULES := $(wildcard $(ONL)/packages/platforms/accton/armel/arm-accton-as4610/src/modules/*.c) +KINCLUDES := $(wildcard $(ONL)/packages/platforms/accton/armel/arm-accton-as4610/src/modules/*.h) +VENDOR := accton +BASENAME := arm-accton-as4610-30 +ARCH := arm +include $(ONL)/make/kmodule.mk diff --git a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/builds/dtb/.gitignore b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/builds/dtb/.gitignore index 7ac7a04f..f9450b8b 100644 --- a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/builds/dtb/.gitignore +++ b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/builds/dtb/.gitignore @@ -1,2 +1,3 @@ *.dtb dts +include diff --git a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/builds/dtb/Makefile b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/builds/dtb/Makefile index 2956bc6e..d3118ad6 100644 --- a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/builds/dtb/Makefile +++ b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/builds/dtb/Makefile @@ -1,10 +1,15 @@ +INCLUDES=include . +KERNEL := onl-kernel-4.14-lts-armel-iproc-all:armel +DTS_LIST := arm-accton-as4610.dts +VPATH := ../../../../../src include $(ONL)/make/dtbs.mk # # The 4610 DTS relies on the common arm devices tree includes. These are linked here from the kernel package. # setup:: - onlpm --link-dir onl-kernel-3.2-lts-arm-iproc-all:armel /usr/share/onl/packages/armel/onl-kernel-3.2-lts-arm-iproc-all/mbuilds/arch/arm/boot/dts dts + onlpm --link-dir onl-kernel-4.14-lts-armel-iproc-all:armel /usr/share/onl/packages/armel/onl-kernel-4.14-lts-armel-iproc-all/mbuilds/arch/arm/boot/dts dts + onlpm --link-dir onl-kernel-4.14-lts-armel-iproc-all:armel /usr/share/onl/packages/armel/onl-kernel-4.14-lts-armel-iproc-all/mbuilds/include include -clean:: - rm -rf fsl +setup-clean:: + rm -f dts include diff --git a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/builds/dtb/arm-accton-as4610-54-r0.dts b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/builds/dtb/arm-accton-as4610-54-r0.dts index 3226b312..0e7a33c0 100644 --- a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/builds/dtb/arm-accton-as4610-54-r0.dts +++ b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/builds/dtb/arm-accton-as4610-54-r0.dts @@ -139,8 +139,8 @@ #address-cells = <1>; #size-cells = <0>; reg = <0>; - optoe@50 { - compatible = "optoe2"; + sfp_eeprom@50 { + compatible = "at,as4610_sfp1"; reg = <0x50>; label = "port49"; }; @@ -151,8 +151,8 @@ #address-cells = <1>; #size-cells = <0>; reg = <1>; - optoe@50 { - compatible = "optoe2"; + sfp_eeprom@50 { + compatible = "accton,as4610_sfp2"; reg = <0x50>; label = "port50"; }; @@ -163,8 +163,8 @@ #address-cells = <1>; #size-cells = <0>; reg = <2>; - optoe@50 { - compatible = "optoe2"; + sfp_eeprom@50 { + compatible = "accton,as4610_sfp3"; reg = <0x50>; label = "port51"; }; @@ -175,8 +175,8 @@ #address-cells = <1>; #size-cells = <0>; reg = <3>; - optoe@50 { - compatible = "optoe2"; + sfp_eeprom@50 { + compatible = "accton,as4610_sfp4"; reg = <0x50>; label = "port52"; }; @@ -187,10 +187,9 @@ #address-cells = <1>; #size-cells = <0>; reg = <4>; - optoe@50 { - compatible = "optoe1"; + sfp_eeprom@50 { + compatible = "accton,as4610_sfp5"; reg = <0x50>; - label = "port53"; }; }; @@ -199,10 +198,9 @@ #address-cells = <1>; #size-cells = <0>; reg = <5>; - optoe@50 { - compatible = "optoe1"; + sfp_eeprom@50 { + compatible = "accton,as4610_sfp6"; reg = <0x50>; - label = "port54"; }; }; diff --git a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/src/lib/arm-accton-as4610-30-r0.yml b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/src/lib/arm-accton-as4610-30-r0.yml index 937774e8..013f2867 100644 --- a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/src/lib/arm-accton-as4610-30-r0.yml +++ b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/src/lib/arm-accton-as4610-30-r0.yml @@ -9,9 +9,9 @@ arm-accton-as4610-30-r0: flat_image_tree: kernel: - <<: *arm-iproc-kernel + <<: *armel-iproc-4-14-kernel dtb: - =: arm-accton-as4610-54-r0.dtb + =: arm-accton-as4610.dtb package: onl-platform-build-arm-accton-as4610-30-r0:armel itb: diff --git a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/src/python/arm_accton_as4610_30_r0/__init__.py b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/src/python/arm_accton_as4610_30_r0/__init__.py index e43c847e..f4aa5bab 100644 --- a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/src/python/arm_accton_as4610_30_r0/__init__.py +++ b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-30/platform-config/r0/src/python/arm_accton_as4610_30_r0/__init__.py @@ -6,3 +6,13 @@ class OnlPlatform_arm_accton_as4610_30_r0(OnlPlatformAccton, PLATFORM='arm-accton-as4610-30-r0' MODEL="AS4610-30" SYS_OBJECT_ID=".4610.30" + + def baseconfig(self): + self.insmod("accton_i2c_cpld") + self.new_i2c_device("as4610_30_cpld", 0x30, 0) + self.insmod("accton_as4610_sfp") + self.insmod("accton_as4610_psu") + self.insmod("accton_as4610_fan") + self.insmod("accton_as4610_leds") + self.insmod("ym2651y") + return True diff --git a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/modules/PKG.yml b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/modules/PKG.yml index 0ddb1ebe..edaa8ee6 100644 --- a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/modules/PKG.yml +++ b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/modules/PKG.yml @@ -1 +1 @@ -!include $ONL_TEMPLATES/no-platform-modules.yml ARCH=armel VENDOR=accton BASENAME=arm-accton-as4610-54 +!include $ONL_TEMPLATES/platform-modules.yml ARCH=armel VENDOR=accton BASENAME=arm-accton-as4610-54 KERNELS="onl-kernel-4.14-lts-armel-iproc-all:armel" diff --git a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/modules/builds/.gitignore b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/modules/builds/.gitignore new file mode 100644 index 00000000..a65b4177 --- /dev/null +++ b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/modules/builds/.gitignore @@ -0,0 +1 @@ +lib diff --git a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/modules/builds/Makefile b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/modules/builds/Makefile new file mode 100644 index 00000000..9acef27d --- /dev/null +++ b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/modules/builds/Makefile @@ -0,0 +1,7 @@ +KERNELS := onl-kernel-4.14-lts-armel-iproc-all:armel +KMODULES := $(wildcard $(ONL)/packages/platforms/accton/armel/arm-accton-as4610/src/modules/*.c) +KINCLUDES := $(wildcard $(ONL)/packages/platforms/accton/armel/arm-accton-as4610/src/modules/*.h) +VENDOR := accton +BASENAME := arm-accton-as4610-54 +ARCH := arm +include $(ONL)/make/kmodule.mk diff --git a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/builds/dtb/.gitignore b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/builds/dtb/.gitignore index 7ac7a04f..f9450b8b 100644 --- a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/builds/dtb/.gitignore +++ b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/builds/dtb/.gitignore @@ -1,2 +1,3 @@ *.dtb dts +include diff --git a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/builds/dtb/Makefile b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/builds/dtb/Makefile index 2956bc6e..d3118ad6 100644 --- a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/builds/dtb/Makefile +++ b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/builds/dtb/Makefile @@ -1,10 +1,15 @@ +INCLUDES=include . +KERNEL := onl-kernel-4.14-lts-armel-iproc-all:armel +DTS_LIST := arm-accton-as4610.dts +VPATH := ../../../../../src include $(ONL)/make/dtbs.mk # # The 4610 DTS relies on the common arm devices tree includes. These are linked here from the kernel package. # setup:: - onlpm --link-dir onl-kernel-3.2-lts-arm-iproc-all:armel /usr/share/onl/packages/armel/onl-kernel-3.2-lts-arm-iproc-all/mbuilds/arch/arm/boot/dts dts + onlpm --link-dir onl-kernel-4.14-lts-armel-iproc-all:armel /usr/share/onl/packages/armel/onl-kernel-4.14-lts-armel-iproc-all/mbuilds/arch/arm/boot/dts dts + onlpm --link-dir onl-kernel-4.14-lts-armel-iproc-all:armel /usr/share/onl/packages/armel/onl-kernel-4.14-lts-armel-iproc-all/mbuilds/include include -clean:: - rm -rf fsl +setup-clean:: + rm -f dts include diff --git a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/builds/dtb/arm-accton-as4610-54-r0.dts b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/builds/dtb/arm-accton-as4610-54-r0.dts index 3226b312..0e7a33c0 100644 --- a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/builds/dtb/arm-accton-as4610-54-r0.dts +++ b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/builds/dtb/arm-accton-as4610-54-r0.dts @@ -139,8 +139,8 @@ #address-cells = <1>; #size-cells = <0>; reg = <0>; - optoe@50 { - compatible = "optoe2"; + sfp_eeprom@50 { + compatible = "at,as4610_sfp1"; reg = <0x50>; label = "port49"; }; @@ -151,8 +151,8 @@ #address-cells = <1>; #size-cells = <0>; reg = <1>; - optoe@50 { - compatible = "optoe2"; + sfp_eeprom@50 { + compatible = "accton,as4610_sfp2"; reg = <0x50>; label = "port50"; }; @@ -163,8 +163,8 @@ #address-cells = <1>; #size-cells = <0>; reg = <2>; - optoe@50 { - compatible = "optoe2"; + sfp_eeprom@50 { + compatible = "accton,as4610_sfp3"; reg = <0x50>; label = "port51"; }; @@ -175,8 +175,8 @@ #address-cells = <1>; #size-cells = <0>; reg = <3>; - optoe@50 { - compatible = "optoe2"; + sfp_eeprom@50 { + compatible = "accton,as4610_sfp4"; reg = <0x50>; label = "port52"; }; @@ -187,10 +187,9 @@ #address-cells = <1>; #size-cells = <0>; reg = <4>; - optoe@50 { - compatible = "optoe1"; + sfp_eeprom@50 { + compatible = "accton,as4610_sfp5"; reg = <0x50>; - label = "port53"; }; }; @@ -199,10 +198,9 @@ #address-cells = <1>; #size-cells = <0>; reg = <5>; - optoe@50 { - compatible = "optoe1"; + sfp_eeprom@50 { + compatible = "accton,as4610_sfp6"; reg = <0x50>; - label = "port54"; }; }; diff --git a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/src/lib/arm-accton-as4610-54-r0.yml b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/src/lib/arm-accton-as4610-54-r0.yml index 542fac0c..077a149a 100644 --- a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/src/lib/arm-accton-as4610-54-r0.yml +++ b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/src/lib/arm-accton-as4610-54-r0.yml @@ -2,16 +2,16 @@ ###################################################################### # -# platform-config for AS4610 +# platform-config for AS4610-54 # ###################################################################### arm-accton-as4610-54-r0: flat_image_tree: kernel: - <<: *arm-iproc-kernel + <<: *armel-iproc-4-14-kernel dtb: - =: arm-accton-as4610-54-r0.dtb + =: arm-accton-as4610.dtb package: onl-platform-build-arm-accton-as4610-54-r0:armel itb: diff --git a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/src/python/arm_accton_as4610_54_r0/__init__.py b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/src/python/arm_accton_as4610_54_r0/__init__.py index a4cf2289..87383d76 100644 --- a/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/src/python/arm_accton_as4610_54_r0/__init__.py +++ b/packages/platforms/accton/armel/arm-accton-as4610/arm-accton-as4610-54/platform-config/r0/src/python/arm_accton_as4610_54_r0/__init__.py @@ -6,3 +6,31 @@ class OnlPlatform_arm_accton_as4610_54_r0(OnlPlatformAccton, PLATFORM='arm-accton-as4610-54-r0' MODEL="AS4610-54" SYS_OBJECT_ID=".4610.54" + + def baseconfig(self): + self.insmod("accton_i2c_cpld") + self.new_i2c_device("as4610_54_cpld", 0x30, 0) + self.insmod("accton_as4610_sfp") + self.insmod("accton_as4610_psu") + self.insmod("accton_as4610_fan") + self.insmod("accton_as4610_leds") + self.insmod("ym2651y") +# self.new_i2c_devices( +# [ +# ("pca9548", 0x70, 1), +# ("as4610_sfp1", 0x50, 2), +# ("as4610_sfp2", 0x50, 3), +# ("as4610_sfp3", 0x50, 4), +# ("as4610_sfp4", 0x50, 5), +# ("as4610_sfp5", 0x50, 6), +# ("as4610_sfp6", 0x50, 7), +# ("as4610_psu1", 0x50, 8), +# ("as4610_psu2", 0x51, 8), +# ("ym1921", 0x58, 8), +# ("ym1921", 0x59, 8), +# ("lm77", 0x48, 9), +# ("ds1307", 0x68, 9), +# ("24c04", 0x50, 9), +# ] +# ) + return True diff --git a/packages/platforms/accton/armel/arm-accton-as4610/src/arm-accton-as4610.dts b/packages/platforms/accton/armel/arm-accton-as4610/src/arm-accton-as4610.dts new file mode 100644 index 00000000..61eb953d --- /dev/null +++ b/packages/platforms/accton/armel/arm-accton-as4610/src/arm-accton-as4610.dts @@ -0,0 +1,286 @@ +/* + * Accton AS4610 54 Device Tree Source + * + * Copyright 2015, Cumulus Networks, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +/dts-v1/; +#include "dts/bcm-helix4.dtsi" + +/ { + model = "accton,as4610_54"; + compatible = "accton,as4610_54","brcm,helix4"; + + aliases { + serial0 = &uart1; + serial1 = &uart2; + ethernet0 = &gmac0; + i2c-controller0 = &i2c0; + i2c-controller1 = &i2c1; + }; +/* + chosen { + bootargs = "console=ttyS0,115200n8 maxcpus=2 mem=2000M"; + }; +*/ + memory { + reg = <0x61000000 0x7f000000>; + }; + + localbus@1c000000 { + #address-cells = <0x2>; + #size-cells = <0x1>; + /* NAND Flash */ + ranges = < + 0x0 0x0 0x0 0x1c000000 0x00120000 + 0x1 0x0 0x0 0x1c120000 0x00040000 + >; + + flash@0,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0x0 0x0 0x02000000>; + byteswap; + + partition@0 { + /* uboot */ + reg = <0x00000000 0x00100000>; + label = "uboot"; + }; + partition@1 { + /* uboot-env */ + reg = <0x00100000 0x00100000>; + label = "uboot-env"; + env_size = <0x2000>; + }; + partition@2 { + /* board_eeprom */ + reg = <0x00200000 0x00100000>; + label = "board_eeprom"; + }; + partition@3 { + /* shmoo */ + reg = <0x00300000 0x00100000>; + label = "shmoo"; + }; + partition@4 { + /* onie */ + reg = <0x00400000 0x00800000>; + label = "onie"; + }; + partition@5 { + /* open */ + reg = <0x00c00000 0x03c00000>; + label = "open"; + }; + partition@6 { + /* open2 */ + reg = <0x04800000 0x7d000000>; + label = "open2"; + }; + partition@7 { + /* diag */ + reg = <0xfec00000 0x01000000>; + label = "diag"; + }; + }; + }; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&gmac0 { + status = "okay"; + phy-mode = "sgmii"; /* "gmii-id", "gmii-rxid", "sgmii" */ +}; + +&usbphy0 { + status = "okay"; + usb-phy-mode = "host"; /* "host", "device" */ +/* mdio-phy-handle = <&usb_phy>; +*/ +}; + +&ehci0 { + status = "okay"; +}; + +&gpio_cca { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + cpld@30 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "accton,as4610_54_cpld"; + label = "cpld"; + reg = <0x30>; + }; +}; + +&i2c1 { + status = "okay"; + mux@70 { + compatible = "ti,pca9548"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + deselect-on-exit; + + // SFP+ 1 + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + sfp_eeprom@50 { + compatible = "accton,as4610_sfp1"; + reg = <0x50>; + label = "port49"; + }; + }; + + // SFP+ 2 + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + sfp_eeprom@50 { + compatible = "accton,as4610_sfp2"; + reg = <0x50>; + label = "port50"; + }; + }; + + // SFP+ 3 + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + sfp_eeprom@50 { + compatible = "accton,as4610_sfp3"; + reg = <0x50>; + label = "port51"; + }; + }; + + // SFP+ 4 + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + sfp_eeprom@50 { + compatible = "accton,as4610_sfp4"; + reg = <0x50>; + label = "port52"; + }; + }; + + // QSFP+ STK1 + i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + sfp_eeprom@50 { + compatible = "accton,as4610_sfp5"; + reg = <0x50>; + }; + }; + + // QSFP+ STK2 + i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + sfp_eeprom@50 { + compatible = "accton,as4610_sfp6"; + reg = <0x50>; + }; + }; + + // PSU EEPROM + i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + psu1_eeprom@50 { + compatible = "accton,as4610_psu1"; + reg = <0x50>; + }; + psu1_pmbus@58 { + compatible = "3y-power,ym1921"; + reg = <0x58>; + }; + psu2_eeprom@51 { + compatible = "accton,as4610_psu2"; + reg = <0x51>; + }; + psu2_pmbus@59 { + compatible = "3y-power,ym1921"; + reg = <0x59>; + }; + }; + + i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + + temp@48 { + compatible = "nxp,lm77"; + reg = <0x48>; + }; + + rtc@68 { + /* Actually M41T11 */ + compatible = "dallas,ds1307"; + reg = <0x68>; + }; + + board_eeprom@50 { + compatible = "at,24c04"; + reg = <0x50>; + label = "board_eeprom"; + }; + }; + }; +}; + +/* +&mdio_int { + status = "okay"; + usb_phy: usb_phy@0 { + reg = <6>; + }; +}; +*/ + +&hwrng { + status = "okay"; +}; + +&iproc_wdt { + status = "okay"; +}; + +&dmac0 { + status = "okay"; +}; + +&iproc_cmicd { + status = "okay"; +}; diff --git a/packages/platforms/accton/armel/arm-accton-as4610/src/arm_accton_as4610/module/src/platform_lib.h b/packages/platforms/accton/armel/arm-accton-as4610/src/arm_accton_as4610/module/src/platform_lib.h index 873e74ad..c40b0aaf 100644 --- a/packages/platforms/accton/armel/arm-accton-as4610/src/arm_accton_as4610/module/src/platform_lib.h +++ b/packages/platforms/accton/armel/arm-accton-as4610/src/arm_accton_as4610/module/src/platform_lib.h @@ -28,8 +28,8 @@ #include "arm_accton_as4610_log.h" -#define CHASSIS_THERMAL_COUNT 1 -#define CHASSIS_PSU_COUNT 2 +#define CHASSIS_THERMAL_COUNT 1 +#define CHASSIS_PSU_COUNT 2 #define PSU1_ID 1 #define PSU2_ID 2 @@ -46,7 +46,7 @@ #define PSU1_AC_EEPROM_NODE(node) PSU1_AC_EEPROM_PREFIX#node #define PSU2_AC_EEPROM_NODE(node) PSU2_AC_EEPROM_PREFIX#node -#define IDPROM_PATH "/sys/devices/1803b000.i2c/i2c-1/i2c-9/9-0050/eeprom" +#define IDPROM_PATH "/sys/devices/platform/axi/1803b000.i2c/i2c-1/i2c-9/9-0050/eeprom" int deviceNodeWriteInt(char *filename, int value, int data_len); int deviceNodeReadBinary(char *filename, char *buffer, int buf_size, int data_len); @@ -97,4 +97,3 @@ typedef enum platform_id_e { extern platform_id_t platform_id; #endif /* __PLATFORM_LIB_H__ */ - diff --git a/packages/platforms/accton/armel/arm-accton-as4610/src/arm_accton_as4610/module/src/sfpi.c b/packages/platforms/accton/armel/arm-accton-as4610/src/arm_accton_as4610/module/src/sfpi.c index 41379f73..7199a31a 100644 --- a/packages/platforms/accton/armel/arm-accton-as4610/src/arm_accton_as4610/module/src/sfpi.c +++ b/packages/platforms/accton/armel/arm-accton-as4610/src/arm_accton_as4610/module/src/sfpi.c @@ -24,31 +24,50 @@ * ***********************************************************/ #include -#include #include "platform_lib.h" #include #include "arm_accton_as4610_log.h" -#define PORT_EEPROM_FORMAT "/sys/bus/i2c/devices/%d-0050/eeprom" -#define MODULE_PRESENT_FORMAT "/sys/bus/i2c/devices/0-0030/module_present_%d" -#define MODULE_RXLOS_FORMAT "/sys/bus/i2c/devices/0-0030/module_rx_los_%d" -#define MODULE_TXFAULT_FORMAT "/sys/bus/i2c/devices/0-0030/module_tx_fault_%d" -#define MODULE_PRESENT_ALL_ATTR_CPLD "/sys/bus/i2c/devices/0-0030/module_present_all" -#define MODULE_RXLOS_ALL_ATTR_CPLD "/sys/bus/i2c/devices/0-0030/module_rx_los_all" +#define MAX_SFP_PATH 64 +static char sfp_node_path[MAX_SFP_PATH] = {0}; +#define FRONT_PORT_MUX_INDEX(port) (port-46) -static int front_port_bus_index(int port) +static int +sfp_node_read_int(char *node_path, int *value, int data_len) { - return (platform_id == PLATFORM_ID_POWERPC_ACCTON_AS4610_30_R0) ? - (port - 22) : /* PLATFORM_ID_POWERPC_ACCTON_AS4610_30_R0 */ - (port - 46) ; /* PLATFORM_ID_POWERPC_ACCTON_AS4610_54_R0 */ + int ret = 0; + char buf[8]; + *value = 0; + + ret = deviceNodeReadString(node_path, buf, sizeof(buf), data_len); + + if (ret == 0) { + *value = atoi(buf); + } + + return ret; } -static int front_port_to_cpld_port(int port) +static char* +sfp_get_port_path_addr(int port, int addr, char *node_name) { - return (platform_id == PLATFORM_ID_POWERPC_ACCTON_AS4610_30_R0) ? - (port - 23) : /* PLATFORM_ID_POWERPC_ACCTON_AS4610_30_R0 */ - (port - 47) ; /* PLATFORM_ID_POWERPC_ACCTON_AS4610_54_R0 */ + int front_port_mux_id; + + if(platform_id == PLATFORM_ID_POWERPC_ACCTON_AS4610_30_R0) + front_port_mux_id = port - 22; + else /*PLATFORM_ID_POWERPC_ACCTON_AS4610_54_R0*/ + front_port_mux_id = port - 46; + + sprintf(sfp_node_path, "/sys/bus/i2c/devices/%d-00%d/%s", + front_port_mux_id, addr, node_name); + return sfp_node_path; +} + +static char* +sfp_get_port_path(int port, char *node_name) +{ + return sfp_get_port_path_addr(port, 50, node_name); } /************************************************************ @@ -96,9 +115,9 @@ onlp_sfpi_is_present(int port) * Return < 0 if error. */ int present; - int cpld_port = front_port_to_cpld_port(port); - - if (onlp_file_read_int(&present, MODULE_PRESENT_FORMAT, cpld_port) < 0) { + char* path = sfp_get_port_path(port, "sfp_is_present"); + + if (sfp_node_read_int(path, &present, 0) != 0) { AIM_LOG_ERROR("Unable to read present status from port(%d)\r\n", port); return ONLP_STATUS_E_INTERNAL; } @@ -110,6 +129,7 @@ int onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst) { uint32_t byte; + char* path; FILE* fp; int port; @@ -120,18 +140,18 @@ onlp_sfpi_presence_bitmap_get(onlp_sfp_bitmap_t* dst) else /*PLATFORM_ID_POWERPC_ACCTON_AS4610_54_R0*/ port = 48; - /* Read present status of each port */ - fp = fopen(MODULE_PRESENT_ALL_ATTR_CPLD, "r"); + path = sfp_get_port_path(port, "sfp_is_present_all"); + fp = fopen(path, "r"); + if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the module_present_all device file of CPLD."); + AIM_LOG_ERROR("Unable to open the sfp_is_present_all device file."); return ONLP_STATUS_E_INTERNAL; } - int count = fscanf(fp, "%x", &byte); fclose(fp); if(count != 1) { /* Likely a CPLD read timeout. */ - AIM_LOG_ERROR("Unable to read all fields the module_present_all device file of CPLD."); + AIM_LOG_ERROR("Unable to read all fields from the sfp_is_present_all device file."); return ONLP_STATUS_E_INTERNAL; } @@ -153,6 +173,7 @@ int onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) { uint32_t byte; + char* path; FILE* fp; int port; @@ -161,18 +182,16 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) else /*PLATFORM_ID_POWERPC_ACCTON_AS4610_54_R0*/ port = 48; - /* Read present status of each port */ - fp = fopen(MODULE_RXLOS_ALL_ATTR_CPLD, "r"); + path = sfp_get_port_path(port, "sfp_rx_los_all"); + fp = fopen(path, "r"); if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the module_rx_los_all device file of CPLD."); + AIM_LOG_ERROR("Unable to open the sfp_rx_los_all device file."); return ONLP_STATUS_E_INTERNAL; } - int count = fscanf(fp, "%x", &byte); fclose(fp); if(count != 1) { - /* Likely a CPLD read timeout. */ - AIM_LOG_ERROR("Unable to read all fields the module_rx_los_all device file of CPLD."); + AIM_LOG_ERROR("Unable to read all fields from the sfp_rx_los_all device file."); return ONLP_STATUS_E_INTERNAL; } @@ -193,51 +212,32 @@ onlp_sfpi_rx_los_bitmap_get(onlp_sfp_bitmap_t* dst) int onlp_sfpi_eeprom_read(int port, uint8_t data[256]) { + char* path = sfp_get_port_path(port, "sfp_eeprom"); + /* * Read the SFP eeprom into data[] * * Return MISSING if SFP is missing. * Return OK if eeprom is read */ - int size = 0; memset(data, 0, 256); - if(onlp_file_read(data, 256, &size, PORT_EEPROM_FORMAT, front_port_bus_index(port)) != ONLP_STATUS_OK) { + if (deviceNodeReadBinary(path, (char*)data, 256, 256) != 0) { AIM_LOG_ERROR("Unable to read eeprom from port(%d)\r\n", port); return ONLP_STATUS_E_INTERNAL; } - if (size != 256) { - AIM_LOG_ERROR("Unable to read eeprom from port(%d), size is different!\r\n", port); - return ONLP_STATUS_E_INTERNAL; - } - return ONLP_STATUS_OK; } int onlp_sfpi_dom_read(int port, uint8_t data[256]) { - FILE* fp; - char file[64] = {0}; - - sprintf(file, PORT_EEPROM_FORMAT, front_port_bus_index(port)); - fp = fopen(file, "r"); - if(fp == NULL) { - AIM_LOG_ERROR("Unable to open the eeprom device file of port(%d)", port); - return ONLP_STATUS_E_INTERNAL; - } + char* path = sfp_get_port_path_addr(port, 51, "sfp_eeprom"); + memset(data, 0, 256); - if (fseek(fp, 256, SEEK_CUR) != 0) { - fclose(fp); - AIM_LOG_ERROR("Unable to set the file position indicator of port(%d)", port); - return ONLP_STATUS_E_INTERNAL; - } - - int ret = fread(data, 1, 256, fp); - fclose(fp); - if (ret != 256) { - AIM_LOG_ERROR("Unable to read the module_eeprom device file of port(%d)", port); + if (deviceNodeReadBinary(path, (char*)data, 256, 256) != 0) { + AIM_LOG_INFO("Unable to read eeprom from port(%d)\r\n", port); return ONLP_STATUS_E_INTERNAL; } @@ -247,24 +247,45 @@ onlp_sfpi_dom_read(int port, uint8_t data[256]) int onlp_sfpi_control_set(int port, onlp_sfp_control_t control, int value) { - return ONLP_STATUS_E_UNSUPPORTED; + int rv; + + switch(control) + { + case ONLP_SFP_CONTROL_TX_DISABLE: + { + char* path = sfp_get_port_path(port, "sfp_tx_disable"); + + if (deviceNodeWriteInt(path, value, 0) != 0) { + AIM_LOG_ERROR("Unable to set tx_disable status to port(%d)\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + rv = ONLP_STATUS_OK; + } + break; + } + + default: + rv = ONLP_STATUS_E_UNSUPPORTED; + break; + } + + return rv; } int onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) { int rv; - int cpld_port = front_port_to_cpld_port(port); - - if (cpld_port > 4) { - return ONLP_STATUS_E_UNSUPPORTED; - } + char* path = NULL; switch(control) { case ONLP_SFP_CONTROL_RX_LOS: { - if (onlp_file_read_int(value, MODULE_RXLOS_FORMAT, cpld_port) < 0) { + path = sfp_get_port_path(port, "sfp_rx_los"); + + if (sfp_node_read_int(path, value, 0) != 0) { AIM_LOG_ERROR("Unable to read rx_los status from port(%d)\r\n", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -276,7 +297,9 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) case ONLP_SFP_CONTROL_TX_FAULT: { - if (onlp_file_read_int(value, MODULE_TXFAULT_FORMAT, cpld_port) < 0) { + path = sfp_get_port_path(port, "sfp_tx_fault"); + + if (sfp_node_read_int(path, value, 0) != 0) { AIM_LOG_ERROR("Unable to read tx_fault status from port(%d)\r\n", port); rv = ONLP_STATUS_E_INTERNAL; } @@ -286,6 +309,20 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) break; } + case ONLP_SFP_CONTROL_TX_DISABLE: + { + path = sfp_get_port_path(port, "sfp_tx_disable"); + + if (sfp_node_read_int(path, value, 0) != 0) { + AIM_LOG_ERROR("Unable to read tx_disabled status from port(%d)\r\n", port); + rv = ONLP_STATUS_E_INTERNAL; + } + else { + rv = ONLP_STATUS_OK; + } + break; + } + default: rv = ONLP_STATUS_E_UNSUPPORTED; } @@ -293,9 +330,9 @@ onlp_sfpi_control_get(int port, onlp_sfp_control_t control, int* value) return rv; } + int onlp_sfpi_denit(void) { return ONLP_STATUS_OK; } - diff --git a/packages/platforms/accton/armel/arm-accton-as4610/src/arm_accton_as4610/module/src/thermali.c b/packages/platforms/accton/armel/arm-accton-as4610/src/arm_accton_as4610/module/src/thermali.c index d9beebec..ddfbce3f 100644 --- a/packages/platforms/accton/armel/arm-accton-as4610/src/arm_accton_as4610/module/src/thermali.c +++ b/packages/platforms/accton/armel/arm-accton-as4610/src/arm_accton_as4610/module/src/thermali.c @@ -63,11 +63,11 @@ enum onlp_thermal_id static char* last_path[] = /* must map with onlp_thermal_id */ { "reserved", - "9-0048/temp1_input", - "8-0058/psu_temp1_input", - "8-0059/psu_temp1_input", + "9-0048*temp1_input", + "8-0058*psu_temp1_input", + "8-0059*psu_temp1_input", }; - + /* Static values */ static onlp_thermal_info_t linfo[] = { { }, /* Not used */ @@ -107,9 +107,7 @@ onlp_thermali_init(void) int onlp_thermali_info_get(onlp_oid_t id, onlp_thermal_info_t* info) { - int fd, len, nbytes = 10, temp_base=1, local_id; - char r_data[10] = {0}; - char fullpath[50] = {0}; + int local_id; VALIDATE(id); local_id = ONLP_OID_ID_GET(id); @@ -119,12 +117,12 @@ onlp_thermali_info_get(onlp_oid_t id, onlp_thermal_info_t* info) *info = linfo[local_id]; /* get fullpath */ - sprintf(fullpath, "%s%s", prefix_path, last_path[local_id]); - - OPEN_READ_FILE(fd, fullpath, r_data, nbytes, len); - info->mcelsius = atoi(r_data) / temp_base; + onlp_file_read_int(&info->mcelsius, "%s%s", prefix_path, last_path[local_id]); + //sprintf(fullpath, "%s%s", prefix_path, last_path[local_id]); + //AIM_LOG_MSG("%s", fullpath); + //OPEN_READ_FILE(fd, fullpath, r_data, nbytes, len); + //info->mcelsius = atoi(r_data) / temp_base; DEBUG_PRINT("\n[Debug][%s][%d][save data: %d]\n", __FUNCTION__, __LINE__, info->mcelsius); return ONLP_STATUS_OK; } - diff --git a/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_as4610_fan.c b/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_as4610_fan.c new file mode 100644 index 00000000..e84bbaf5 --- /dev/null +++ b/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_as4610_fan.c @@ -0,0 +1,344 @@ +/* + * A hwmon driver for the Accton as4610 fan + * + * Copyright (C) 2016 Accton Technology Corporation. + * Brandon Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "accton_i2c_cpld.h" + +#define DRVNAME "as4610_fan" + + +static struct as4610_fan_data *as4610_fan_update_device(struct device *dev); +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + +/* fan related data, the index should match sysfs_fan_attributes + */ +static const u8 fan_reg[] = { + 0x2B, /* fan PWM(for all fan) */ + 0x2D, /* fan 1 speed(rpm) */ + 0x2C, /* fan 2 speed(rpm) */ + 0x11, /* fan1-2 operating status */ +}; + +static struct as4610_fan_data *fan_data = NULL; + +/* Each client has this additional data */ +struct as4610_fan_data { + struct platform_device *pdev; + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */ +}; + +enum fan_id { + FAN1_ID, + FAN2_ID +}; + +enum sysfs_fan_attributes { + FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ + FAN1_SPEED_RPM, + FAN2_SPEED_RPM, + FAN_FAULT, + FAN1_FAULT, + FAN2_FAULT +}; + +/* Define attributes + */ +#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT) +#define DECLARE_FAN_FAULT_ATTR(index) &sensor_dev_attr_fan##index##_fault.dev_attr.attr + +#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN##index##_DUTY_CYCLE_PERCENTAGE) +#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan##index##_duty_cycle_percentage.dev_attr.attr + +#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_SPEED_RPM) +#define DECLARE_FAN_SPEED_RPM_ATTR(index) &sensor_dev_attr_fan##index##_speed_rpm.dev_attr.attr + +/* fan fault attributes in this platform */ +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2); +/* fan speed(rpm) attributes in this platform */ +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2); +/* 1 fan duty cycle attribute in this platform */ +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(); + +static struct attribute *as4610_fan_attributes[] = { + /* fan related attributes */ + DECLARE_FAN_FAULT_ATTR(1), + DECLARE_FAN_FAULT_ATTR(2), + DECLARE_FAN_SPEED_RPM_ATTR(1), + DECLARE_FAN_SPEED_RPM_ATTR(2), + DECLARE_FAN_DUTY_CYCLE_ATTR(), + NULL +}; + +#define FAN_DUTY_CYCLE_REG_MASK 0xF +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100 + +static int as4610_fan_read_value(u8 reg) +{ + return accton_i2c_cpld_read(AS4610_CPLD_SLAVE_ADDR, reg); +} + +static int as4610_fan_write_value(u8 reg, u8 value) +{ + return accton_i2c_cpld_write(AS4610_CPLD_SLAVE_ADDR, reg, value); +} + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ + reg_val &= FAN_DUTY_CYCLE_REG_MASK; + return (u32)((reg_val * 125 + 5)/10); +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ + return ((u32)duty_cycle * 10 / 125); +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ + /* Count Frequency is 1.515KHz= 0.66ms + * Count Period = 400 cycle = 400*0.66ms = 264ms + * R.P.M value = read value x3.79*60/2 + * 3.79 = 1000ms/264ms + * 60 = 1min =60s + * 2 = 1 rotation of fan has two pulses. + */ + return (u32)reg_val * 379 * 60 / 2 / 100; +} + +static u8 is_fan_fault(struct as4610_fan_data *data, enum fan_id id) +{ + u8 mask = (id == FAN1_ID) ? 0x20 : 0x10; + + return !(data->reg_val[FAN_FAULT] & mask); +} + +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < 0 || value > FAN_MAX_DUTY_CYCLE) + return -EINVAL; + + as4610_fan_write_value(fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); + return count; +} + +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as4610_fan_data *data = as4610_fan_update_device(dev); + ssize_t ret = 0; + + if (data->valid) { + switch (attr->index) { + case FAN_DUTY_CYCLE_PERCENTAGE: + { + u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[attr->index]); + ret = sprintf(buf, "%u\n", duty_cycle); + break; + } + case FAN1_SPEED_RPM: + case FAN2_SPEED_RPM: + ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index])); + break; + case FAN1_FAULT: + case FAN2_FAULT: + ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); + break; + default: + break; + } + } + + return ret; +} + +static const struct attribute_group as4610_fan_group = { + .attrs = as4610_fan_attributes, +}; + +static struct as4610_fan_data *as4610_fan_update_device(struct device *dev) +{ + mutex_lock(&fan_data->update_lock); + + if (time_after(jiffies, fan_data->last_updated + HZ + HZ / 2) || + !fan_data->valid) { + int i; + + dev_dbg(fan_data->hwmon_dev, "Starting as4610_fan update\n"); + fan_data->valid = 0; + + /* Update fan data + */ + for (i = 0; i < ARRAY_SIZE(fan_data->reg_val); i++) { + int status = as4610_fan_read_value(fan_reg[i]); + + if (status < 0) { + fan_data->valid = 0; + mutex_unlock(&fan_data->update_lock); + dev_dbg(fan_data->hwmon_dev, "reg %d, err %d\n", fan_reg[i], status); + return fan_data; + } + else { + fan_data->reg_val[i] = status; + } + } + + fan_data->last_updated = jiffies; + fan_data->valid = 1; + } + + mutex_unlock(&fan_data->update_lock); + + return fan_data; +} + +static int as4610_fan_probe(struct platform_device *pdev) +{ + int status = -1; + + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &as4610_fan_group); + if (status) { + goto exit; + + } + + fan_data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(fan_data->hwmon_dev)) { + status = PTR_ERR(fan_data->hwmon_dev); + goto exit_remove; + } + + dev_info(&pdev->dev, "accton_as4610_fan\n"); + + return 0; + +exit_remove: + sysfs_remove_group(&pdev->dev.kobj, &as4610_fan_group); +exit: + return status; +} + +static int as4610_fan_remove(struct platform_device *pdev) +{ + hwmon_device_unregister(fan_data->hwmon_dev); + sysfs_remove_group(&pdev->dev.kobj, &as4610_fan_group); + + return 0; +} + +static const struct i2c_device_id as4610_fan_id[] = { + { "as4610_fan", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as4610_fan_id); + +static struct platform_driver as4610_fan_driver = { + .probe = as4610_fan_probe, + .remove = as4610_fan_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init as4610_fan_init(void) +{ + int ret; + + if (as4610_number_of_system_fan() == 0) { + return -ENODEV; + } + + ret = platform_driver_register(&as4610_fan_driver); + if (ret < 0) { + goto exit; + } + + fan_data = kzalloc(sizeof(struct as4610_fan_data), GFP_KERNEL); + if (!fan_data) { + ret = -ENOMEM; + platform_driver_unregister(&as4610_fan_driver); + goto exit; + } + + mutex_init(&fan_data->update_lock); + fan_data->valid = 0; + + fan_data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(fan_data->pdev)) { + ret = PTR_ERR(fan_data->pdev); + platform_driver_unregister(&as4610_fan_driver); + kfree(fan_data); + goto exit; + } + +exit: + return ret; +} + +static void __exit as4610_fan_exit(void) +{ + if (!fan_data) { + return; + } + + platform_device_unregister(fan_data->pdev); + platform_driver_unregister(&as4610_fan_driver); + kfree(fan_data); +} + +late_initcall(as4610_fan_init); +module_exit(as4610_fan_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as4610_fan driver"); +MODULE_LICENSE("GPL"); diff --git a/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_as4610_leds.c b/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_as4610_leds.c new file mode 100644 index 00000000..cdc80779 --- /dev/null +++ b/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_as4610_leds.c @@ -0,0 +1,674 @@ +/* + * A LED driver for the accton_as4610_led + * + * Copyright (C) 2016 Accton Technology Corporation. + * Brandon Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*#define DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "accton_i2c_cpld.h" + +//extern void led_classdev_unregister(struct led_classdev *led_cdev); +//extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); + +#define DRVNAME "as4610_led" + +struct as4610_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + int led_map; + u8 reg_val[5]; /* Register value, 0 = (0x1A) Blinking function + 1 = (0x30) 7-seg 2 + 2 = (0x31) 7-seg 1 + 3 = (0x32) SYS/PRI/PSU1-2 LED + 4 = (0x33) STK1-2/Fan/PoE/Alarm LED */ +}; + +static struct as4610_led_data *ledctl = NULL; + +/* LED related data + */ +#define LED_7SEG_REG_MASK 0x0F +#define LED_7SEG_POINT_REG_MASK 0x10 + +#define LED_NORMAL_MASK 0x03 +#define LED_NORMAL_GREEN_VALUE 0x02 +#define LED_NORMAL_AMBER_VALUE 0x01 +#define LED_NORMAL_OFF_VALUE 0x00 + +#define LED_TYPE_SYS_REG_MASK 0xC0 +#define LED_MODE_SYS_BLINK_MASK 0x80 + +#define LED_TYPE_PRI_REG_MASK 0x30 +#define LED_MODE_PRI_BLINK_MASK 0x40 + +#define LED_TYPE_PSU1_REG_MASK 0x0C +#define LED_MODE_PSU1_BLINK_MASK 0x20 + +#define LED_TYPE_PSU2_REG_MASK 0x03 +#define LED_MODE_PSU2_BLINK_MASK 0x10 + +#define LED_TYPE_STK1_REG_MASK 0xC0 +#define LED_MODE_STK1_BLINK_MASK 0x08 + +#define LED_TYPE_STK2_REG_MASK 0x30 +#define LED_MODE_STK2_BLINK_MASK 0x04 + +#define LED_TYPE_FAN_REG_MASK 0x0C +#define LED_MODE_FAN_BLINK_MASK 0x02 + +#define LED_TYPE_POE_ALARM_REG_MASK 0x03 +#define LED_MODE_POE_ALARM_BLINK_MASK 0x01 + +static const u8 led_reg[] = { + 0x1A, /* Blinking function */ + 0x30, /* 7-seg 1 */ + 0x31, /* 7-seg 2 */ + 0x32, /* SYS/PRI/PSU1-2 LED */ + 0x33, /* STK1-2/Fan/PoE/Alarm LED */ +}; + +enum led_type { + LED_TYPE_SYS, + LED_TYPE_PRI, + LED_TYPE_PSU1, + LED_TYPE_PSU2, + LED_TYPE_STK1, + LED_TYPE_STK2, + LED_TYPE_7SEG_TENS, + LED_TYPE_7SEG_TENS_POINT, + LED_TYPE_7SEG_DIGITS, + LED_TYPE_7SEG_DIGITS_POINT, + LED_TYPE_FAN, + LED_TYPE_POE, + LED_TYPE_ALARM, + NUM_OF_LED +}; + +#define AS4610_COMMON_LED_MAP (BIT(LED_TYPE_SYS) | BIT(LED_TYPE_PRI) | BIT(LED_TYPE_PSU1) | \ + BIT(LED_TYPE_PSU2)| BIT(LED_TYPE_STK1)| BIT(LED_TYPE_STK2)) +#define AS4610_NPOE_LED_MAP (AS4610_COMMON_LED_MAP | BIT(LED_TYPE_7SEG_TENS) | \ + BIT(LED_TYPE_7SEG_TENS_POINT) | BIT(LED_TYPE_7SEG_DIGITS) | \ + BIT(LED_TYPE_7SEG_DIGITS_POINT)) +#define AS4610_POE_LED_MAP (AS4610_NPOE_LED_MAP | BIT(LED_TYPE_FAN) | BIT(LED_TYPE_POE)) +#define AS4610_54T_B_LED_MAP (AS4610_COMMON_LED_MAP | BIT(LED_TYPE_FAN) | BIT(LED_TYPE_ALARM)) + +static int as4610_ledmaps[] = { + [PID_AS4610_30T] = AS4610_NPOE_LED_MAP, + [PID_AS4610_30P] = AS4610_POE_LED_MAP, + [PID_AS4610_54T] = AS4610_NPOE_LED_MAP, + [PID_AS4610_54P] = AS4610_POE_LED_MAP, + [PID_AS4610_54T_B] = AS4610_54T_B_LED_MAP, + [PID_RESERVED] = 0, +}; + +enum led_light_mode { + LED_MODE_OFF = 0, + LED_MODE_GREEN, + LED_MODE_GREEN_BLINK, + LED_MODE_AMBER, + LED_MODE_AMBER_BLINK, + LED_MODE_RED, + LED_MODE_RED_BLINK, + LED_MODE_BLUE, + LED_MODE_BLUE_BLINK, + LED_MODE_AUTO, + LED_MODE_AUTO_BLINKING, + LED_MODE_UNKNOWN, + LED_MODE_SEVEN_SEGMENT_MAX = 9, +}; + +static int as4610_led_read_value(u8 reg) +{ + return accton_i2c_cpld_read(0x30, reg); +} + +static int as4610_led_write_value(u8 reg, u8 value) +{ + return accton_i2c_cpld_write(0x30, reg, value); +} + +static void as4610_led_update(void) +{ + mutex_lock(&ledctl->update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting as4610_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + int status = as4610_led_read_value(led_reg[i]); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg[i], status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static enum led_brightness seven_segment_get(struct led_classdev *cdev, u8 reg_id) +{ + as4610_led_update(); + return (ledctl->reg_val[reg_id] & LED_7SEG_REG_MASK); +} + +static void seven_segment_set(struct led_classdev *cdev, enum led_brightness mode, u8 reg_id) +{ + if (mode > cdev->max_brightness) { + return; + } + + ledctl->reg_val[reg_id] &= 0xF0; + ledctl->reg_val[reg_id] |= mode; + as4610_led_write_value(led_reg[reg_id], ledctl->reg_val[reg_id]); +} + +static enum led_brightness seven_segment_digits_get(struct led_classdev *cdev) +{ + return seven_segment_get(cdev, 1); +} + +static void seven_segment_digits_set(struct led_classdev *cdev, enum led_brightness mode) +{ + seven_segment_set(cdev, mode, 1); +} + +static enum led_brightness seven_segment_tens_get(struct led_classdev *cdev) +{ + return seven_segment_get(cdev, 2); +} + +static void seven_segment_tens_set(struct led_classdev *cdev, enum led_brightness mode) +{ + seven_segment_set(cdev, mode, 2); +} + +static enum led_brightness seven_segment_point_get(struct led_classdev *cdev, u8 reg_id) +{ + as4610_led_update(); + return (ledctl->reg_val[reg_id] & LED_7SEG_POINT_REG_MASK) ? LED_MODE_GREEN : LED_MODE_OFF; +} + +static void seven_segment_point_set(struct led_classdev *cdev, + enum led_brightness mode, u8 reg_id) +{ + /* Validate brightness */ + if ((int)mode < LED_MODE_OFF || mode > cdev->max_brightness) { + return; + } + + if ((int)mode == (int)LED_MODE_OFF) { + ledctl->reg_val[reg_id] &= ~LED_7SEG_POINT_REG_MASK; + } + else { /* LED_MODE_GREEN */ + ledctl->reg_val[reg_id] |= LED_7SEG_POINT_REG_MASK; + } + + as4610_led_write_value(led_reg[reg_id], ledctl->reg_val[reg_id]); +} + +static enum led_brightness seven_segment_tens_point_get(struct led_classdev *cdev) +{ + return seven_segment_point_get(cdev, 2); +} + +static void seven_segment_tens_point_set(struct led_classdev *cdev, + enum led_brightness mode) +{ + seven_segment_point_set(cdev, mode, 2); +} + +static enum led_brightness seven_segment_digits_point_get(struct led_classdev *cdev) +{ + return seven_segment_point_get(cdev, 1); +} + +static void seven_segment_digits_point_set(struct led_classdev *cdev, + enum led_brightness mode) +{ + seven_segment_point_set(cdev, mode, 1); +} + +static u8 led_is_blinking_mode(enum led_brightness mode) +{ + return ((int)mode == (int)LED_MODE_GREEN_BLINK || + (int)mode == (int)LED_MODE_AMBER_BLINK || + (int)mode == (int)LED_MODE_AUTO_BLINKING); +} + +static enum led_brightness as4610_led_auto_get(u8 blink_mask) +{ + as4610_led_update(); + return (ledctl->reg_val[0] & blink_mask) ? LED_MODE_AUTO_BLINKING : LED_MODE_AUTO; +} + +static void as4610_led_auto_set(struct led_classdev *cdev, + enum led_brightness mode, u8 blink_mask) +{ + /* Validate brightness */ + if ((int)mode < (int)LED_MODE_AUTO || mode > cdev->max_brightness) { + return; + } + + /* Set blinking */ + if (led_is_blinking_mode(mode)) { + ledctl->reg_val[0] |= blink_mask; + } + else { + ledctl->reg_val[0] &= ~blink_mask; + } + as4610_led_write_value(led_reg[0], ledctl->reg_val[0]); +} + +static enum led_brightness as4610_led_psu1_get(struct led_classdev *cdev) +{ + return as4610_led_auto_get(LED_MODE_PSU1_BLINK_MASK); +} + +static void as4610_led_psu1_set(struct led_classdev *cdev, + enum led_brightness mode) +{ + as4610_led_auto_set(cdev, mode, LED_MODE_PSU1_BLINK_MASK); +} + +static enum led_brightness as4610_led_psu2_get(struct led_classdev *cdev) +{ + return as4610_led_auto_get(LED_MODE_PSU2_BLINK_MASK); +} + +static void as4610_led_psu2_set(struct led_classdev *led_cdev, + enum led_brightness mode) +{ + as4610_led_auto_set(led_cdev, mode, LED_MODE_PSU2_BLINK_MASK); +} + +static enum led_brightness as4610_led_fan_get(struct led_classdev *cdev) +{ + return as4610_led_auto_get(LED_MODE_FAN_BLINK_MASK); +} + +static void as4610_led_fan_set(struct led_classdev *cdev, + enum led_brightness mode) +{ + as4610_led_auto_set(cdev, mode, LED_MODE_FAN_BLINK_MASK); +} + +static u8 led_normal_light_mode_to_reg_val(enum led_brightness mode) +{ + if (led_is_blinking_mode(mode)) { + mode -= 1; /* convert blinking mode to non-blinking mode */ + } + + if ((int)mode == (int)LED_MODE_GREEN) { + return LED_NORMAL_GREEN_VALUE; + } + else if ((int)mode == (int)LED_MODE_AMBER) { + return LED_NORMAL_AMBER_VALUE; + } + + return LED_NORMAL_OFF_VALUE; +} + +static enum led_brightness led_normal_reg_val_to_light_mode(u8 reg_val) +{ + reg_val &= LED_NORMAL_MASK; + + if (reg_val & LED_NORMAL_GREEN_VALUE) { + return LED_MODE_GREEN; + } + else if (reg_val & LED_NORMAL_AMBER_VALUE) { + return LED_MODE_AMBER; + } + + return LED_MODE_OFF; +} + +static void as4610_led_normal_set(struct led_classdev *cdev, + enum led_brightness mode, u8 blink_mask, u8 reg_id, u8 reg_mask, u8 shift) +{ + /* Validate brightness */ + if (mode > cdev->max_brightness) { + return; + } + + /* Set blinking */ + if (led_is_blinking_mode(mode)) { + ledctl->reg_val[0] |= blink_mask; + } + else { + ledctl->reg_val[0] &= ~blink_mask; + } + as4610_led_write_value(led_reg[0], ledctl->reg_val[0]); + + /* Set color */ + ledctl->reg_val[reg_id] &= ~reg_mask; + ledctl->reg_val[reg_id] |= (led_normal_light_mode_to_reg_val(mode) << shift); + as4610_led_write_value(led_reg[reg_id], ledctl->reg_val[reg_id]); +} + +static enum led_brightness as4610_led_normal_get(u8 reg_id, u8 blink_mask, u8 shift) +{ + u8 blinking = 0; + enum led_brightness mode; + + as4610_led_update(); + + mode = led_normal_reg_val_to_light_mode(ledctl->reg_val[reg_id] >> shift); + if ((int)mode == (int)LED_MODE_OFF) { + return mode; + } + + /* Checking blinking */ + if (ledctl->reg_val[0] & blink_mask) { + blinking = 1; + } + + return blinking ? (mode+1) : mode; +} + +static void as4610_led_sys_set(struct led_classdev *cdev, + enum led_brightness mode) +{ + as4610_led_normal_set(cdev, mode, LED_MODE_SYS_BLINK_MASK, + 3, LED_TYPE_SYS_REG_MASK, 6); +} + +static enum led_brightness as4610_led_sys_get(struct led_classdev *cdev) +{ + return as4610_led_normal_get(3, LED_MODE_SYS_BLINK_MASK, 6); +} + +static void as4610_led_pri_set(struct led_classdev *cdev, + enum led_brightness mode) +{ + as4610_led_normal_set(cdev, mode, LED_MODE_PRI_BLINK_MASK, + 3, LED_TYPE_PRI_REG_MASK, 4); +} + +static enum led_brightness as4610_led_pri_get(struct led_classdev *cdev) +{ + return as4610_led_normal_get(3, LED_MODE_PRI_BLINK_MASK, 4); +} + +static void as4610_led_poe_alarm_set(struct led_classdev *cdev, + enum led_brightness mode) +{ + as4610_led_normal_set(cdev, mode, LED_MODE_POE_ALARM_BLINK_MASK, + 4, LED_TYPE_POE_ALARM_REG_MASK, 0); +} + +static enum led_brightness as4610_led_poe_alarm_get(struct led_classdev *cdev) +{ + return as4610_led_normal_get(4, LED_MODE_POE_ALARM_BLINK_MASK, 0); +} + +static void as4610_led_stk1_set(struct led_classdev *cdev, + enum led_brightness mode) +{ + as4610_led_normal_set(cdev, mode, LED_MODE_STK1_BLINK_MASK, + 4, LED_TYPE_STK1_REG_MASK, 6); +} + +static enum led_brightness as4610_led_stk1_get(struct led_classdev *cdev) +{ + return as4610_led_normal_get(4, LED_MODE_STK1_BLINK_MASK, 6); +} + +static void as4610_led_stk2_set(struct led_classdev *cdev, + enum led_brightness mode) +{ + as4610_led_normal_set(cdev, mode, LED_MODE_STK2_BLINK_MASK, + 4, LED_TYPE_STK2_REG_MASK, 4); +} + +static enum led_brightness as4610_led_stk2_get(struct led_classdev *cdev) +{ + return as4610_led_normal_get(4, LED_MODE_STK2_BLINK_MASK, 4); +} + +static struct led_classdev as4610_leds[] = { + [LED_TYPE_SYS] = { + .name = "as4610::sys", + .default_trigger = "unused", + .brightness_set = as4610_led_sys_set, + .brightness_get = as4610_led_sys_get, + .max_brightness = LED_MODE_AMBER_BLINK, + }, + [LED_TYPE_PRI] = { + .name = "as4610::pri", + .default_trigger = "unused", + .brightness_set = as4610_led_pri_set, + .brightness_get = as4610_led_pri_get, + .max_brightness = LED_MODE_AMBER_BLINK, + }, + [LED_TYPE_PSU1] = { + .name = "as4610::psu1", + .default_trigger = "unused", + .brightness_set = as4610_led_psu1_set, + .brightness_get = as4610_led_psu1_get, + .max_brightness = LED_MODE_AUTO_BLINKING, + }, + [LED_TYPE_PSU2] = { + .name = "as4610::psu2", + .default_trigger = "unused", + .brightness_set = as4610_led_psu2_set, + .brightness_get = as4610_led_psu2_get, + .max_brightness = LED_MODE_AUTO_BLINKING, + }, + [LED_TYPE_STK1] = { + .name = "as4610::stk1", + .default_trigger = "unused", + .brightness_set = as4610_led_stk1_set, + .brightness_get = as4610_led_stk1_get, + .max_brightness = LED_MODE_AMBER_BLINK, + }, + [LED_TYPE_STK2] = { + .name = "as4610::stk2", + .default_trigger = "unused", + .brightness_set = as4610_led_stk2_set, + .brightness_get = as4610_led_stk2_get, + .max_brightness = LED_MODE_AMBER_BLINK, + }, + [LED_TYPE_7SEG_TENS] = { + .name = "as4610::7seg_tens", + .default_trigger = "unused", + .brightness_set = seven_segment_tens_set, + .brightness_get = seven_segment_tens_get, + .max_brightness = LED_MODE_SEVEN_SEGMENT_MAX, + }, + [LED_TYPE_7SEG_TENS_POINT] = { + .name = "as4610::7seg_tens_point", + .default_trigger = "unused", + .brightness_set = seven_segment_tens_point_set, + .brightness_get = seven_segment_tens_point_get, + .max_brightness = LED_MODE_GREEN, + }, + [LED_TYPE_7SEG_DIGITS] = { + .name = "as4610::7seg_digits", + .default_trigger = "unused", + .brightness_set = seven_segment_digits_set, + .brightness_get = seven_segment_digits_get, + .max_brightness = LED_MODE_SEVEN_SEGMENT_MAX, + }, + [LED_TYPE_7SEG_DIGITS_POINT] = { + .name = "as4610::7seg_digits_point", + .default_trigger = "unused", + .brightness_set = seven_segment_digits_point_set, + .brightness_get = seven_segment_digits_point_get, + .max_brightness = LED_MODE_GREEN, + }, + [LED_TYPE_FAN] = { + .name = "as4610::fan", + .default_trigger = "unused", + .brightness_set = as4610_led_fan_set, + .brightness_get = as4610_led_fan_get, + .max_brightness = LED_MODE_AUTO_BLINKING, + }, + [LED_TYPE_POE] = { + .name = "as4610::poe", + .default_trigger = "unused", + .brightness_set = as4610_led_poe_alarm_set, + .brightness_get = as4610_led_poe_alarm_get, + .max_brightness = LED_MODE_AMBER_BLINK, + }, + [LED_TYPE_ALARM] = { + .name = "as4610::alarm", + .default_trigger = "unused", + .brightness_set = as4610_led_poe_alarm_set, + .brightness_get = as4610_led_poe_alarm_get, + .max_brightness = LED_MODE_AMBER_BLINK, + }, +}; + +static int as4610_led_probe(struct platform_device *pdev) +{ + int ret = 0, i; + + for (i = 0; i < NUM_OF_LED; i++) { + if (!(ledctl->led_map & BIT(i))) { + continue; + } + + ret = led_classdev_register(&pdev->dev, &as4610_leds[i]); + if (ret < 0) { + goto error; + } + } + + return 0; + +error: + for (i = i-1; i >= 0; i--) { + /* only unregister the LEDs that were successfully registered */ + if (!(ledctl->led_map & BIT(i))) { + continue; + } + + led_classdev_unregister(&as4610_leds[i]); + } + + return ret; +} + +static int as4610_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < NUM_OF_LED; i++) { + if (!(ledctl->led_map & BIT(i))) { + continue; + } + + led_classdev_unregister(&as4610_leds[i]); + } + + return 0; +} + +static struct platform_driver as4610_led_driver = { + .probe = as4610_led_probe, + .remove = as4610_led_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init as4610_led_init(void) +{ + int ret, pid; + + if (as4610_product_id() == PID_UNKNOWN) { + return -ENODEV; + } + + ret = platform_driver_register(&as4610_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct as4610_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&as4610_led_driver); + goto exit; + } + + pid = as4610_product_id(); + if (pid == PID_UNKNOWN) { + return -ENODEV; + } + + ledctl->led_map = as4610_ledmaps[pid]; + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&as4610_led_driver); + kfree(ledctl); + goto exit; + } + +exit: + return ret; +} + +static void __exit as4610_led_exit(void) +{ + if (!ledctl) { + return; + } + + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&as4610_led_driver); + kfree(ledctl); +} + +late_initcall(as4610_led_init); +module_exit(as4610_led_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as4610_led driver"); +MODULE_LICENSE("GPL"); diff --git a/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_as4610_psu.c b/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_as4610_psu.c new file mode 100644 index 00000000..1f0d79dc --- /dev/null +++ b/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_as4610_psu.c @@ -0,0 +1,286 @@ +/* + * An hwmon driver for accton as4610 Power Module + * + * Copyright (C) 2016 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_model_name(struct device *dev, struct device_attribute *da, char *buf); +static int as4610_psu_read_data(struct i2c_client *client, u8 command, u8 *data,int data_len); +extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { 0x50, 0x53, I2C_CLIENT_END }; + +/* Each client has this additional data + */ +struct as4610_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 index; /* PSU index */ + u8 status; /* Status(present/power_good) register read from CPLD */ + char model_name[9]; /* Model name, read from eeprom */ +}; + +static struct as4610_psu_data *as4610_psu_update_device(struct device *dev); + +enum as4610_psu_sysfs_attributes { + PSU_PRESENT, + PSU_MODEL_NAME, + PSU_POWER_GOOD +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, show_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_model_name,NULL, PSU_MODEL_NAME); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, show_status, NULL, PSU_POWER_GOOD); + +static struct attribute *as4610_psu_attributes[] = { + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_model_name.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + NULL +}; + +static ssize_t show_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct as4610_psu_data *data = as4610_psu_update_device(dev); + u8 status = 0; + + if (attr->index == PSU_PRESENT) { + status = (data->status >> (data->index*2) & 0x1); + } + else { /* PSU_POWER_GOOD */ + status = (data->status >> (data->index*2 + 1) & 0x1); + } + + return sprintf(buf, "%d\n", status); +} + +static ssize_t show_model_name(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct as4610_psu_data *data = as4610_psu_update_device(dev); + + return sprintf(buf, "%s\n", data->model_name); +} + +static const struct attribute_group as4610_psu_group = { + .attrs = as4610_psu_attributes, +}; + +static int as4610_psu_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct as4610_psu_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct as4610_psu_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + data->index = dev_id->driver_data; + mutex_init(&data->update_lock); + + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &as4610_psu_group); + if (status) { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &as4610_psu_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int as4610_psu_remove(struct i2c_client *client) +{ + struct as4610_psu_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &as4610_psu_group); + kfree(data); + + return 0; +} + +enum psu_index +{ + as4610_psu1, + as4610_psu2 +}; + +static const struct i2c_device_id as4610_psu_id[] = { + { "as4610_psu1", as4610_psu1 }, + { "as4610_psu2", as4610_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, as4610_psu_id); + +static struct i2c_driver as4610_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "as4610_psu", + }, + .probe = as4610_psu_probe, + .remove = as4610_psu_remove, + .id_table = as4610_psu_id, + .address_list = normal_i2c, +}; + +static int as4610_psu_read_data(struct i2c_client *client, u8 command, u8 *data, + int count) +{ + int status = 0; + + while (count) { + status = i2c_smbus_read_byte_data(client, command); + if (unlikely(status < 0)) { + break; + } + + *data = (u8)status; + data += 1; + command += 1; + count -= 1; + } + + return status; +} + +static struct as4610_psu_data *as4610_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct as4610_psu_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + int status; + int present = 0; + + data->valid = 0; + data->status = 0; + dev_dbg(&client->dev, "Starting as4610 update\n"); + + /* Read psu status */ + status = accton_i2c_cpld_read(0x30, 0x11); + + if (status < 0) { + dev_dbg(&client->dev, "cpld reg 0x30 err %d\n", status); + goto exit; + } + else { + data->status = status; + } + + /* Read model name */ + memset(data->model_name, 0, sizeof(data->model_name)); + present = (data->status >> (data->index*2) & 0x1); + + if (present) { + int len = ARRAY_SIZE(data->model_name)-1; + + status = as4610_psu_read_data(client, 0x20, data->model_name, + ARRAY_SIZE(data->model_name)-1); + + if (status < 0) { + data->model_name[0] = '\0'; + dev_dbg(&client->dev, "unable to read model name from (0x%x)\n", client->addr); + goto exit; + } + else { + data->model_name[ARRAY_SIZE(data->model_name)-1] = '\0'; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + +exit: + mutex_unlock(&data->update_lock); + + return data; +} + +static int __init as4610_psu_init(void) +{ + return i2c_add_driver(&as4610_psu_driver); +} + +static void __exit as4610_psu_exit(void) +{ + i2c_del_driver(&as4610_psu_driver); +} + +module_init(as4610_psu_init); +module_exit(as4610_psu_exit); + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("as4610_psu driver"); +MODULE_LICENSE("GPL"); + diff --git a/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_as4610_sfp.c b/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_as4610_sfp.c new file mode 100644 index 00000000..39c17ecf --- /dev/null +++ b/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_as4610_sfp.c @@ -0,0 +1,1269 @@ +/* + * SFP driver for accton as4610 sfp + * + * Copyright (C) Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "as4610_sfp" /* Platform dependent */ + +#define DEBUG_MODE 0 + +#if (DEBUG_MODE == 1) + #define DEBUG_PRINT(fmt, args...) \ + printk (KERN_INFO "%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define NUM_OF_SFP_PORT 32 +#define EEPROM_NAME "sfp_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ +#define BIT_INDEX(i) (1ULL << (i)) +#define USE_I2C_BLOCK_READ 0 /* Platform dependent */ +#define I2C_RW_RETRY_COUNT 3 +#define I2C_RW_RETRY_INTERVAL 100 /* ms */ + +#define SFP_EEPROM_A0_I2C_ADDR (0xA0 >> 1) +#define SFP_EEPROM_A2_I2C_ADDR (0xA2 >> 1) + +#define SFF8024_PHYSICAL_DEVICE_ID_ADDR 0x0 +#define SFF8024_DEVICE_ID_SFP 0x3 +#define SFF8024_DEVICE_ID_QSFP 0xC +#define SFF8024_DEVICE_ID_QSFP_PLUS 0xD +#define SFF8024_DEVICE_ID_QSFP28 0x11 + +#define SFF8472_DIAG_MON_TYPE_ADDR 92 +#define SFF8472_DIAG_MON_TYPE_DDM_MASK 0x40 +#define SFF8472_10G_ETH_COMPLIANCE_ADDR 0x3 +#define SFF8472_10G_BASE_MASK 0xF0 + +#define SFF8436_RX_LOS_ADDR 3 +#define SFF8436_TX_FAULT_ADDR 4 +#define SFF8436_TX_DISABLE_ADDR 86 + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_present(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count);; +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_eeprom_read(struct i2c_client *, u8, u8 *,int); +static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); +extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +enum sfp_sysfs_attributes { + PRESENT, + PRESENT_ALL, + PORT_NUMBER, + PORT_TYPE, + DDM_IMPLEMENTED, + TX_FAULT, + TX_FAULT1, + TX_FAULT2, + TX_FAULT3, + TX_FAULT4, + TX_DISABLE, + TX_DISABLE1, + TX_DISABLE2, + TX_DISABLE3, + TX_DISABLE4, + RX_LOS, + RX_LOS1, + RX_LOS2, + RX_LOS3, + RX_LOS4, + RX_LOS_ALL +}; + +/* SFP/QSFP common attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_port_type, S_IRUGO, show_port_type, NULL, PORT_TYPE); +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_present, NULL, PRESENT); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_present, NULL, PRESENT_ALL); +static SENSOR_DEVICE_ATTR(sfp_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, TX_FAULT); + +/* QSFP attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_rx_los1, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS1); +static SENSOR_DEVICE_ATTR(sfp_rx_los2, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS2); +static SENSOR_DEVICE_ATTR(sfp_rx_los3, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS3); +static SENSOR_DEVICE_ATTR(sfp_rx_los4, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS4); +static SENSOR_DEVICE_ATTR(sfp_tx_disable1, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE1); +static SENSOR_DEVICE_ATTR(sfp_tx_disable2, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE2); +static SENSOR_DEVICE_ATTR(sfp_tx_disable3, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE3); +static SENSOR_DEVICE_ATTR(sfp_tx_disable4, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE4); +static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT1); +static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2); +static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3); +static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4); +static struct attribute *qsfp_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los1.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los2.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los3.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault4.dev_attr.attr, + NULL +}; + +/* SFP msa attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_ddm_implemented, S_IRUGO, sfp_show_ddm_implemented, NULL, DDM_IMPLEMENTED); +static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS_ALL); +static struct attribute *sfp_msa_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_ddm_implemented.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los_all.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + NULL +}; + +/* SFP ddm attributes for sysfs */ +static struct attribute *sfp_ddm_attributes[] = { + NULL +}; + +/* Platform dependent +++ */ +enum port_numbers { +as4610_sfp1, /* Port 25 for as4610_30, Port 49 for as4610_54 */ +as4610_sfp2, /* Port 26 for as4610_30, Port 50 for as4610_54 */ +as4610_sfp3, /* Port 27 for as4610_30, Port 51 for as4610_54 */ +as4610_sfp4, /* Port 28 for as4610_30, Port 52 for as4610_54 */ +as4610_sfp5, /* Port 29 for as4610_30, Port 53 for as4610_54 */ +as4610_sfp6, /* Port 30 for as4610_30, Port 54 for as4610_54 */ +}; + +static const struct i2c_device_id sfp_device_id[] = { +{"as4610_sfp1", as4610_sfp1}, +{"as4610_sfp2", as4610_sfp2}, +{"as4610_sfp3", as4610_sfp3}, +{"as4610_sfp4", as4610_sfp4}, +{"as4610_sfp5", as4610_sfp5}, +{"as4610_sfp6", as4610_sfp6}, +{ /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, sfp_device_id); +/* Platform dependent --- */ + +/* + * list of valid port types + * note OOM_PORT_TYPE_NOT_PRESENT to indicate no + * module is present in this port + */ +typedef enum oom_driver_port_type_e { + OOM_DRIVER_PORT_TYPE_INVALID, + OOM_DRIVER_PORT_TYPE_NOT_PRESENT, + OOM_DRIVER_PORT_TYPE_SFP, + OOM_DRIVER_PORT_TYPE_SFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP, + OOM_DRIVER_PORT_TYPE_QSFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP28 +} oom_driver_port_type_t; + +enum driver_type_e { + DRIVER_TYPE_SFP_MSA, + DRIVER_TYPE_SFP_DDM, + DRIVER_TYPE_QSFP +}; + +/* Each client has this additional data + */ +struct eeprom_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + struct bin_attribute bin; /* eeprom data */ +}; + +struct sfp_msa_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 status[6]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss + 3 => device id + 4 => 10G Ethernet Compliance Codes + to distinguish SFP or SFP+ + 5 => DIAGNOSTIC MONITORING TYPE */ + struct eeprom_data eeprom; +}; + +struct sfp_ddm_data { + struct eeprom_data eeprom; +}; + +struct qsfp_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss */ + + u8 device_id; + struct eeprom_data eeprom; +}; + +struct sfp_port_data { + struct mutex update_lock; + enum driver_type_e driver_type; + int port; /* CPLD port index */ + oom_driver_port_type_t port_type; + u64 present; /* present status, bit0:port0, bit1:port1 and so on */ + + struct sfp_msa_data *msa; + struct sfp_ddm_data *ddm; + struct qsfp_data *qsfp; + + struct i2c_client *client; +}; + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "sfp %d\n", data->port); +} + +/* Platform dependent +++ */ +static struct sfp_port_data *sfp_update_present(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0; + int status = -1; + u8 regs[] = {0x2, 0x3, 0x21}; + + DEBUG_PRINT("Starting sfp present status update"); + mutex_lock(&data->update_lock); + + /* Read present status of port 49~54 */ + data->present = 0; + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = accton_i2c_cpld_read(0x30, regs[i]); + + if (status < 0) { + DEBUG_PRINT("cpld(0x30) reg(0x%x) err %d", regs[i], status); + goto exit; + } + + DEBUG_PRINT("Present status = 0x%lx", data->present); + switch (i) { + case 0: + data->present |= (status & BIT_INDEX(6)) >> 6; /* port 25/49 */ + data->present |= (status & BIT_INDEX(2)) >> 1; /* port 26/50 */ + break; + case 1: + data->present |= (status & BIT_INDEX(6)) >> 4; /* port 27/51 */ + data->present |= (status & BIT_INDEX(2)) << 1; /* port 28/52 */ + break; + case 2: + data->present |= (status & BIT_INDEX(0)) << 4; /* port 29/53 */ + data->present |= (status & BIT_INDEX(4)) << 1; /* port 30/54 */ + break; + default: + break; + } + } + + DEBUG_PRINT("Present status = 0x%lx", data->present); +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0; + int status = -1; + u8 regs[] = {0x2, 0x3, 0x21}; + + if (time_before(jiffies, data->msa->last_updated + HZ + HZ / 2) && data->msa->valid) { + return data; + } + + DEBUG_PRINT("Starting as4610 sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->msa->valid = 0; + memset(data->msa->status, 0, sizeof(data->msa->status)); + + /* Read status of port 49~52(SFP port) */ + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = accton_i2c_cpld_read(0x30, regs[i]); + + if (status < 0) { + DEBUG_PRINT("cpld(0x30) reg(0x%x) err %d", regs[i], status); + goto exit; + } + + DEBUG_PRINT("TX_FAULT = 0x%lx, TX_DISABLE = 0x%lx, TX_FAULT = 0x%lx", + data->msa->status[0], data->msa->status[1], data->msa->status[2]); + switch (i) { + case 0: + /* port 25/49 */ + data->msa->status[0] |= (status & BIT_INDEX(5)) >> 5; /* tx_fail */ + data->msa->status[2] |= (status & BIT_INDEX(4)) >> 4; /* rx_los */ + /* port 26/50 */ + data->msa->status[0] |= (status & BIT_INDEX(1)) << 0; /* tx_fail */ + data->msa->status[2] |= (status & BIT_INDEX(0)) << 1; /* rx_los */ + break; + case 1: + /* port 27/51 */ + data->msa->status[0] |= (status & BIT_INDEX(5)) >> 3; /* tx_fail */ + data->msa->status[2] |= (status & BIT_INDEX(4)) >> 2; /* rx_los */ + /* port 28/52 */ + data->msa->status[0] |= (status & BIT_INDEX(1)) << 1; /* tx_fail */ + data->msa->status[2] |= (status & BIT_INDEX(0)) << 2; /* rx_los */ + break; + default: + break; + } + } + + DEBUG_PRINT("TX_FAULT = 0x%lx, TX_DISABLE = 0x%lx, TX_FAULT = 0x%lx", + data->msa->status[0], data->msa->status[1], data->msa->status[2]); + data->msa->valid = 1; + data->msa->last_updated = jiffies; + +exit: + mutex_unlock(&data->update_lock); + return data; +} +/* Platform dependent --- */ + +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + if (data->driver_type == DRIVER_TYPE_QSFP) { + return qsfp_set_tx_disable(dev, da, buf, count); + } + + return 0; +} + +static int sfp_is_port_present(struct i2c_client *client, int port) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + data = sfp_update_present(client); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + return (data->present & BIT_INDEX(data->port)) ? 1 : 0; /* Platform dependent */ +} + +/* Platform dependent +++ */ +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + + if (PRESENT_ALL == attr->index) { + struct sfp_port_data *data = sfp_update_present(client); + + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + /* Return values 25/49 -> 30/54 in order */ + return sprintf(buf, "%.2x\n", (u8)(data->present)); + } + else { + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + /* PRESENT */ + return sprintf(buf, "%d\n", present); + } +} +/* Platform dependent --- */ + +static struct sfp_port_data *sfp_update_port_type(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 buf = 0; + int status; + + mutex_lock(&data->update_lock); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + { + status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + if (buf != SFF8024_DEVICE_ID_SFP) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + status = sfp_eeprom_read(client, SFF8472_10G_ETH_COMPLIANCE_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("sfp port type (0x3) data = (0x%x)", buf); + data->port_type = buf & SFF8472_10G_BASE_MASK ? OOM_DRIVER_PORT_TYPE_SFP_PLUS : OOM_DRIVER_PORT_TYPE_SFP; + break; + } + case DRIVER_TYPE_QSFP: + { + status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("qsfp port type (0x0) buf = (0x%x)", buf); + switch (buf) { + case SFF8024_DEVICE_ID_QSFP: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP; + break; + case SFF8024_DEVICE_ID_QSFP_PLUS: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + case SFF8024_DEVICE_ID_QSFP28: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + default: + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + break; + } + default: + break; + } + + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + if (!present) { + return sprintf(buf, "%d\n", OOM_DRIVER_PORT_TYPE_NOT_PRESENT); + } + + sfp_update_port_type(dev); + return sprintf(buf, "%d\n", data->port_type); +} + +static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i, status = -1; + u8 buf = 0; + u8 reg[] = {SFF8436_TX_FAULT_ADDR, SFF8436_TX_DISABLE_ADDR, SFF8436_RX_LOS_ADDR}; + + if (time_before(jiffies, data->qsfp->last_updated + HZ + HZ / 2) && data->qsfp->valid) { + return data; + } + + DEBUG_PRINT("Starting sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->qsfp->valid = 0; + memset(data->qsfp->status, 0, sizeof(data->qsfp->status)); + + /* Notify device to update tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + goto exit; + } + } + msleep(200); + + /* Read actual tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + goto exit; + } + + DEBUG_PRINT("qsfp reg(0x%x) status = (0x%x)", reg[i], data->qsfp->status[i]); + data->qsfp->status[i] = (buf & 0xF); + } + + data->qsfp->valid = 1; + data->qsfp->last_updated = jiffies; + +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + int present; + u8 val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENXIO; + } + + data = qsfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + switch (attr->index) { + case TX_FAULT: + val = !!(data->qsfp->status[2] & 0xF); + break; + case TX_FAULT1: + case TX_FAULT2: + case TX_FAULT3: + case TX_FAULT4: + val = !!(data->qsfp->status[2] & BIT_INDEX(attr->index - TX_FAULT1)); + break; + case TX_DISABLE: + val = data->qsfp->status[1] & 0xF; + break; + case TX_DISABLE1: + case TX_DISABLE2: + case TX_DISABLE3: + case TX_DISABLE4: + val = !!(data->qsfp->status[1] & BIT_INDEX(attr->index - TX_DISABLE1)); + break; + case RX_LOS: + val = !!(data->qsfp->status[0] & 0xF); + break; + case RX_LOS1: + case RX_LOS2: + case RX_LOS3: + case RX_LOS4: + val = !!(data->qsfp->status[0] & BIT_INDEX(attr->index - RX_LOS1)); + break; + default: + break; + } + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long disable; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (!status) { + /* port is not present */ + return -ENXIO; + } + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + + data = qsfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + mutex_lock(&data->update_lock); + + if (attr->index == TX_DISABLE) { + data->qsfp->status[1] = disable & 0xF; + } + else {/* TX_DISABLE1 ~ TX_DISABLE4*/ + if (disable) { + data->qsfp->status[1] |= (1 << (attr->index - TX_DISABLE1)); + } + else { + data->qsfp->status[1] &= ~(1 << (attr->index - TX_DISABLE1)); + } + } + + DEBUG_PRINT("index = (%d), status = (0x%x)", attr->index, data->qsfp->status[1]); + status = sfp_eeprom_write(data->client, SFF8436_TX_DISABLE_ADDR, &data->qsfp->status[1], sizeof(data->qsfp->status[1])); + if (unlikely(status < 0)) { + count = status; + } + + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + char ddm; + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (status == 0) { + /* port is not present */ + return -ENODEV; + } + + status = sfp_eeprom_read(client, SFF8472_DIAG_MON_TYPE_ADDR, &ddm, sizeof(ddm)); + if (unlikely(status < 0)) { + return status; + } + + return sprintf(buf, "%d\n", !!(ddm & SFF8472_DIAG_MON_TYPE_DDM_MASK)); +} + +/* Platform dependent +++ */ +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 val = 0, index = 0; + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (data->driver_type == DRIVER_TYPE_QSFP) { + return qsfp_show_tx_rx_status(dev, da, buf); + } + + data = sfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + if(attr->index == RX_LOS_ALL) { + /** Return values 25/49 -> 28/52 in order */ + return sprintf(buf, "%.2x\n", (u8)(data->msa->status[2])); + } + + switch (attr->index) { + case TX_FAULT: + index = 0; + break; + case TX_DISABLE: + index = 1; + break; + case RX_LOS: + index = 2; + break; + default: + return 0; + } + + val = (data->msa->status[index] & BIT_INDEX(data->port)) ? 1 : 0; + return sprintf(buf, "%d\n", val); +} +/* Platform dependent --- */ +static ssize_t sfp_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, command, *data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return 1; +#endif + + +} + +static ssize_t sfp_port_write(struct sfp_port_data *data, + const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_write(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t sfp_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("%s(%d) offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + return sfp_port_write(data, buf, off, count); +} + +static ssize_t sfp_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + + //result = data_len; + +abort: + return status; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, command); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, status); + goto abort; + } + + *data = (u8)status; + status = 1; + +abort: + return status; +#endif +} + +static ssize_t sfp_port_read(struct sfp_port_data *data, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + DEBUG_PRINT("Count = 0, return"); + return count; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_read(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; + +} + +static ssize_t sfp_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + return sfp_port_read(data, buf, off, count); +} + +static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = sfp_bin_read; + eeprom->write = sfp_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + +static int sfp_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + +static const struct attribute_group sfp_msa_group = { + .attrs = sfp_msa_attributes, +}; + +static int sfp_i2c_check_functionality(struct i2c_client *client) +{ +#if USE_I2C_BLOCK_READ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK); +#else + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA); +#endif +} + +static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_msa_data **data) +{ + int status; + struct sfp_msa_data *msa; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + msa = kzalloc(sizeof(struct sfp_msa_data), GFP_KERNEL); + if (!msa) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_msa_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &msa->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = msa; + dev_info(&client->dev, "sfp msa '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); +exit_free: + kfree(msa); +exit: + + return status; +} + +static const struct attribute_group sfp_ddm_group = { + .attrs = sfp_ddm_attributes, +}; + +static int sfp_ddm_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_ddm_data **data) +{ + int status; + struct sfp_ddm_data *ddm; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + ddm = kzalloc(sizeof(struct sfp_ddm_data), GFP_KERNEL); + if (!ddm) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_ddm_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &ddm->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = ddm; + dev_info(&client->dev, "sfp ddm '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); +exit_free: + kfree(ddm); +exit: + + return status; +} + +static const struct attribute_group qsfp_group = { + .attrs = qsfp_attributes, +}; + +static int qsfp_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct qsfp_data **data) +{ + int status; + struct qsfp_data *qsfp; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + qsfp = kzalloc(sizeof(struct qsfp_data), GFP_KERNEL); + if (!qsfp) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &qsfp_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = qsfp; + dev_info(&client->dev, "qsfp '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &qsfp_group); +exit_free: + kfree(qsfp); +exit: + + return status; +} + +/* Platform dependent +++ */ +static int sfp_device_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct sfp_port_data *data = NULL; + + data = kzalloc(sizeof(struct sfp_port_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + data->client = client; + + if (client->addr != SFP_EEPROM_A0_I2C_ADDR && + client->addr != SFP_EEPROM_A2_I2C_ADDR ) { + return -ENODEV; + } + + if (dev_id->driver_data >= as4610_sfp1 && dev_id->driver_data <= as4610_sfp4) { + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_SFP_MSA; + return sfp_msa_probe(client, dev_id, &data->msa); + } + else if (client->addr == SFP_EEPROM_A2_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_SFP_DDM; + return sfp_ddm_probe(client, dev_id, &data->ddm); + } + } + else if (dev_id->driver_data >= as4610_sfp5 && dev_id->driver_data <= as4610_sfp6) { + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_QSFP; + return qsfp_probe(client, dev_id, &data->qsfp); + } + } + + return -ENODEV; +} +/* Platform dependent --- */ + +static int sfp_msa_remove(struct i2c_client *client, struct sfp_msa_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); + kfree(data); + return 0; +} + +static int sfp_ddm_remove(struct i2c_client *client, struct sfp_ddm_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); + kfree(data); + return 0; +} + +static int qfp_remove(struct i2c_client *client, struct qsfp_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &qsfp_group); + kfree(data); + return 0; +} + +static int sfp_device_remove(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + return sfp_msa_remove(client, data->msa); + case DRIVER_TYPE_SFP_DDM: + return sfp_ddm_remove(client, data->ddm); + case DRIVER_TYPE_QSFP: + return qfp_remove(client, data->qsfp); + } + + return 0; +} + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static struct i2c_driver sfp_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = sfp_device_probe, + .remove = sfp_device_remove, + .id_table = sfp_device_id, + .address_list = normal_i2c, +}; + +static int __init sfp_init(void) +{ + return i2c_add_driver(&sfp_driver); +} + +static void __exit sfp_exit(void) +{ + i2c_del_driver(&sfp_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton as4610_sfp driver"); +MODULE_LICENSE("GPL"); + +late_initcall(sfp_init); +module_exit(sfp_exit); + diff --git a/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_i2c_cpld.c b/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_i2c_cpld.c new file mode 100644 index 00000000..a7140def --- /dev/null +++ b/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_i2c_cpld.c @@ -0,0 +1,284 @@ +/* + * A hwmon driver for the accton_i2c_cpld + * + * Copyright (C) 2013 Accton Technology Corporation. + * Brandon Chuang + * + * Based on ad7414.c + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include "accton_i2c_cpld.h" + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +enum cpld_device_id { + as4610_30_cpld, + as4610_54_cpld +}; + +struct cpld_data { + enum cpld_device_id id; +}; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +/* Addresses scanned for accton_i2c_cpld + */ +static const unsigned short normal_i2c[] = { 0x31, 0x35, 0x60, 0x61, 0x62, I2C_CLIENT_END }; + +static u8 cpld_product_id_offset(enum cpld_device_id id) +{ + switch (id) { + case as4610_30_cpld: + case as4610_54_cpld: + return 0x1; + } + + return 0; +} + +static int cpld_has_product_id(const struct i2c_device_id *dev_id) +{ + return (dev_id->driver_data == as4610_30_cpld) || + (dev_id->driver_data == as4610_54_cpld); +} + +static ssize_t show_cpld_product_id(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0; + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + + val = i2c_smbus_read_byte_data(client, cpld_product_id_offset(data->id)); + if (val < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", client->addr, cpld_product_id_offset(data->id), val); + } + + return sprintf(buf, "%d\n", (val & 0xF)); +} + +static u8 cpld_version_offset(enum cpld_device_id id) +{ + switch (id) { + case as4610_30_cpld: + case as4610_54_cpld: + return 0xB; + } + + return 0; +} + +static ssize_t show_cpld_version(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0; + struct i2c_client *client = to_i2c_client(dev); + struct cpld_data *data = i2c_get_clientdata(client); + + val = i2c_smbus_read_byte_data(client, cpld_version_offset(data->id)); + if (val < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0xB) err %d\n", client->addr, val); + } + + return sprintf(buf, "%d\n", val); +} + +static void accton_i2c_cpld_add_client(struct i2c_client *client, enum cpld_device_id id) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + struct cpld_data *data = kzalloc(sizeof(struct cpld_data), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + if (!data) { + dev_dbg(&client->dev, "Can't allocate cpld_client_data (0x%x)\n", client->addr); + return; + } + + data->id = id; + i2c_set_clientdata(client, data); + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void accton_i2c_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static struct device_attribute ver = __ATTR(version, 0600, show_cpld_version, NULL); +static struct device_attribute pid = __ATTR(product_id, 0600, show_cpld_product_id, NULL); + +static int accton_i2c_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + } + + status = sysfs_create_file(&client->dev.kobj, &ver.attr); + if (status) { + goto exit; + } + + if (cpld_has_product_id(dev_id)) { + status = sysfs_create_file(&client->dev.kobj, &pid.attr); + if (status) { + goto exit; + } + } + + dev_info(&client->dev, "chip found\n"); + accton_i2c_cpld_add_client(client, (enum cpld_device_id)dev_id->driver_data); + + return 0; + + exit: + return status; +} + +static int accton_i2c_cpld_remove(struct i2c_client *client) +{ + sysfs_remove_file(&client->dev.kobj, &ver.attr); + accton_i2c_cpld_remove_client(client); + + return 0; +} + +static const struct i2c_device_id accton_i2c_cpld_id[] = { + { "as4610_30_cpld", as4610_30_cpld }, + { "as4610_54_cpld", as4610_54_cpld }, + { /* LIST END */} +}; +MODULE_DEVICE_TABLE(i2c, accton_i2c_cpld_id); + +static struct i2c_driver accton_i2c_cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "accton_i2c_cpld", + }, + .probe = accton_i2c_cpld_probe, + .remove = accton_i2c_cpld_remove, + .id_table = accton_i2c_cpld_id, + .address_list = normal_i2c, +}; + +int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_read_byte_data(cpld_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(accton_i2c_cpld_read); + +int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client->addr == cpld_addr) { + ret = i2c_smbus_write_byte_data(cpld_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(accton_i2c_cpld_write); + +static int __init accton_i2c_cpld_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&accton_i2c_cpld_driver); +} + +static void __exit accton_i2c_cpld_exit(void) +{ + i2c_del_driver(&accton_i2c_cpld_driver); +} + +MODULE_AUTHOR("Brandon Chuang "); +MODULE_DESCRIPTION("accton_i2c_cpld driver"); +MODULE_LICENSE("GPL"); + +module_init(accton_i2c_cpld_init); +module_exit(accton_i2c_cpld_exit); diff --git a/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_i2c_cpld.h b/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_i2c_cpld.h new file mode 100644 index 00000000..9b75abd9 --- /dev/null +++ b/packages/platforms/accton/armel/arm-accton-as4610/src/modules/accton_i2c_cpld.h @@ -0,0 +1,76 @@ +/* + * A hwmon driver for the accton_i2c_cpld + * + * Copyright (C) 2016 Accton Technology Corporation. + * Brandon Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +#define AS4610_CPLD_SLAVE_ADDR 0x30 +#define AS4610_CPLD_PID_OFFSET 0x01 /* Product ID offset */ + +enum as4610_product_id_e { + PID_AS4610_30T, + PID_AS4610_30P, + PID_AS4610_54T, + PID_AS4610_54P, + PID_RESERVED, + PID_AS4610_54T_B, + PID_UNKNOWN +}; + +static inline int as4610_product_id(void) +{ + int pid = accton_i2c_cpld_read(AS4610_CPLD_SLAVE_ADDR, AS4610_CPLD_PID_OFFSET); + pid &= 0xF; + + if (pid < PID_AS4610_30T || pid > PID_AS4610_54T_B || pid == PID_RESERVED) { + return PID_UNKNOWN; + } + + return pid; +} + +static inline int as4610_is_poe_system(void) +{ + int pid = as4610_product_id(); + return (pid == PID_AS4610_30P || pid == PID_AS4610_54P); +} + +static inline int as4610_number_of_system_fan(void) +{ + int nFan = 0; + int pid = as4610_product_id(); + + switch (pid) { + case PID_AS4610_30P: + case PID_AS4610_54P: + nFan = 1; + break; + case PID_AS4610_54T_B: + nFan = 2; + break; + default: + nFan = 0; + break; + } + + return nFan; +} + diff --git a/packages/platforms/delta/armel/arm-delta-ag6248c/arm-delta-ag6248c-poe/platform-config/r0/PKG.yml b/packages/platforms/delta/armel/arm-delta-ag6248c/arm-delta-ag6248c-poe/platform-config/r0/PKG.yml index d8c6ed4a..fb67b75a 100755 --- a/packages/platforms/delta/armel/arm-delta-ag6248c/arm-delta-ag6248c-poe/platform-config/r0/PKG.yml +++ b/packages/platforms/delta/armel/arm-delta-ag6248c/arm-delta-ag6248c-poe/platform-config/r0/PKG.yml @@ -1 +1 @@ -!include $ONL_TEMPLATES/platform-config-platform.yml ARCH=armel VENDOR=delta BASENAME=arm-delta-ag6248c-poe REVISION=r0 +!include $ONL_TEMPLATES/platform-config-platform.yml ARCH=armel VENDOR=delta BASENAME=arm-delta-ag6248c-poe REVISION=r0 DISTS=jessie diff --git a/packages/platforms/delta/armel/arm-delta-ag6248c/arm-delta-ag6248c/platform-config/r0/PKG.yml b/packages/platforms/delta/armel/arm-delta-ag6248c/arm-delta-ag6248c/platform-config/r0/PKG.yml index 16ff5c28..2c2717a8 100644 --- a/packages/platforms/delta/armel/arm-delta-ag6248c/arm-delta-ag6248c/platform-config/r0/PKG.yml +++ b/packages/platforms/delta/armel/arm-delta-ag6248c/arm-delta-ag6248c/platform-config/r0/PKG.yml @@ -1 +1 @@ -!include $ONL_TEMPLATES/platform-config-platform.yml ARCH=armel VENDOR=delta BASENAME=arm-delta-ag6248c REVISION=r0 +!include $ONL_TEMPLATES/platform-config-platform.yml ARCH=armel VENDOR=delta BASENAME=arm-delta-ag6248c REVISION=r0 DISTS=jessie diff --git a/packages/platforms/qemu/arm/arm-qemu-armv7a/platform-config/r0/PKG.yml b/packages/platforms/qemu/arm/arm-qemu-armv7a/platform-config/r0/PKG.yml index d6ef2795..66afda3b 100644 --- a/packages/platforms/qemu/arm/arm-qemu-armv7a/platform-config/r0/PKG.yml +++ b/packages/platforms/qemu/arm/arm-qemu-armv7a/platform-config/r0/PKG.yml @@ -1 +1 @@ -!include $ONL_TEMPLATES/platform-config-platform.yml ARCH=armel VENDOR=qemu BASENAME=arm-qemu-armv7a REVISION=r0 +!include $ONL_TEMPLATES/platform-config-platform.yml ARCH=armel VENDOR=qemu BASENAME=arm-qemu-armv7a REVISION=r0 DISTS=jessie diff --git a/tools/flat-image-tree.py b/tools/flat-image-tree.py index 19ad7f9c..c4290daf 100755 --- a/tools/flat-image-tree.py +++ b/tools/flat-image-tree.py @@ -66,7 +66,7 @@ class Image(object): self.wl(""" description = "%s";""" % self.description) self.wl(""" type = "%s";""" % self.type) self.wl(""" data = /incbin/("%s");""" % self.data) - self.wl(""" arch = "%s";""" % ("arm" if ops.arch == 'armel' else ops.arch)) + self.wl(""" arch = "%s";""" % ("arm" if ops.arch in [ 'armel', 'armhf' ] else ops.arch)) self.wl(""" compression = "%s";""" % self.compression) if self.os: self.wl(""" os = %s;""" % self.os) @@ -95,7 +95,7 @@ class KernelImage(Image): if arch == 'powerpc': self.load = "<0x0>" self.entry = "<0x0>" - elif arch == 'armel': + elif arch in [ 'armel', 'armhf' ]: self.load = "<0x61008000>" self.entry = "<0x61008000>" elif arch == 'arm64': @@ -117,7 +117,7 @@ class InitrdImage(Image): if arch == 'powerpc': self.load = "<0x1000000>" self.entry ="<0x1000000>" - elif arch == 'armel': + elif arch in [ 'armel', 'armhf' ]: self.load = "<0x0000000>" self.entry ="<0x0000000>" elif arch == 'arm64': @@ -306,7 +306,7 @@ if __name__ == '__main__': ap.add_argument("--desc", nargs=1, help="Flat Image Tree description", default="ONL Flat Image Tree.") ap.add_argument("--itb", metavar='itb-file', help="Compile result to an image tree blob file.") ap.add_argument("--its", metavar='its-file', help="Write result to an image tree source file.") - ap.add_argument("--arch", choices=['powerpc', 'armel', 'arm64'], required=True) + ap.add_argument("--arch", choices=['powerpc', 'armel', 'armhf', 'arm64'], required=True) ops=ap.parse_args() fit = FlatImageTree(ops.desc) diff --git a/tools/mkinstaller.py b/tools/mkinstaller.py index 9ca57909..6989c02a 100755 --- a/tools/mkinstaller.py +++ b/tools/mkinstaller.py @@ -175,7 +175,7 @@ if __name__ == '__main__': ap = argparse.ArgumentParser(NAME) ap.add_argument("--arch", help="Installer Architecture.", required=True, - choices = ['amd64', 'powerpc', 'armel', 'arm64']) + choices = ['amd64', 'powerpc', 'armel', 'armhf', 'arm64']) ap.add_argument("--initrd", nargs=2, help="The system initrd.") ap.add_argument("--fit", nargs=2, help="The system FIT image.") ap.add_argument("--boot-config", help="The boot-config source.") diff --git a/tools/onlpm.py b/tools/onlpm.py index 4701daed..3b1cf745 100755 --- a/tools/onlpm.py +++ b/tools/onlpm.py @@ -136,8 +136,10 @@ class OnlPackage(object): 'BUILD_DIR' : 'BUILD/%s' % g_dist_codename, # Default Templates Location - 'ONL_TEMPLATES' : "%s/packages/base/any/templates" % os.getenv("ONL") + 'ONL_TEMPLATES' : "%s/packages/base/any/templates" % os.getenv("ONL"), + # Default Distribution + 'DISTS' : g_dist_codename, } ############################################################ @@ -503,6 +505,13 @@ class OnlPackageGroup(object): return False return True + def distcheck(self): + for p in self.packages: + if p.pkg.get("dists", None): + if g_dist_codename not in p.pkg['dists'].split(','): + return False + return True + def prerequisite_packages(self): rv = [] for e in list(onlu.sflatten(self._pkgs.get('prerequisites', {}).get('packages', []))): @@ -863,7 +872,8 @@ class OnlPackageManager(object): pg.filtered = True if not pg.archcheck(arches): pg.filtered = True - + if not pg.distcheck(): + pg.filtered = True def load(self, basedir, usecache=True, rebuildcache=False): pkgspec = [ 'PKG.yml', 'pkg.yml' ] @@ -1089,6 +1099,8 @@ class OnlPackageManager(object): def list_platforms(self, arch): platforms = [] for pg in self.package_groups: + if not pg.distcheck(): + continue for p in pg.packages: (name, pkgArch) = OnlPackage.idparse(p.id()) m = re.match(r'onl-platform-config-(?P.*)', name) @@ -1103,7 +1115,7 @@ def defaultPm(): packagedirs = os.environ['ONLPM_OPTION_PACKAGEDIRS'].split(':') repoPackageDir = os.environ.get('ONLPM_OPTION_REPO_PACKAGE_DIR', 'packages') subdir = os.getcwd() - arches = ['amd64', 'powerpc', 'armel', 'arm64', 'all',] + arches = ['amd64', 'powerpc', 'armel', 'armhf', 'arm64', 'all',] if envJson: for j in envJson.split(':'): @@ -1139,7 +1151,7 @@ if __name__ == '__main__': ap.add_argument("--csv", action='store_true') ap.add_argument("--show-group", action='store_true') ap.add_argument("--arch") - ap.add_argument("--arches", nargs='+', default=['amd64', 'powerpc', 'armel', 'arm64', 'all']), + ap.add_argument("--arches", nargs='+', default=['amd64', 'powerpc', 'armel', 'armhf', 'arm64', 'all']), ap.add_argument("--pmake", action='store_true') ap.add_argument("--prereq-packages", action='store_true') ap.add_argument("--lookup", metavar='PACKAGE') diff --git a/tools/onlrfs.py b/tools/onlrfs.py index 46749d3b..85c51b28 100755 --- a/tools/onlrfs.py +++ b/tools/onlrfs.py @@ -334,7 +334,7 @@ class OnlRfsBuilder(object): if not os.path.exists(self.QEMU_PPC): raise OnlRfsError("%s is missing." % self.QEMU_PPC) - if self.arch == 'armel': + if self.arch in [ 'armel', 'armhf' ]: if not os.path.exists(self.QEMU_ARM): raise OnlRfsError("%s is missing." % self.QEMU_ARM) @@ -378,7 +378,7 @@ class OnlRfsBuilder(object): def dpkg_configure(self, dir_): if self.arch == 'powerpc': onlu.execute('sudo cp %s %s' % (self.QEMU_PPC, os.path.join(dir_, 'usr/bin'))) - if self.arch == 'armel': + if self.arch in [ 'armel', 'armhf' ]: onlu.execute('sudo cp %s %s' % (self.QEMU_ARM, os.path.join(dir_, 'usr/bin'))) if self.arch == 'arm64': onlu.execute('sudo cp %s %s' % (self.QEMU_ARM64, os.path.join(dir_, 'usr/bin'))) diff --git a/tools/scripts/kmodbuild.sh b/tools/scripts/kmodbuild.sh index 94f258d8..d5586b70 100755 --- a/tools/scripts/kmodbuild.sh +++ b/tools/scripts/kmodbuild.sh @@ -38,6 +38,9 @@ function build_source { BUILD_DIR=`mktemp -d` cp $2 $BUILD_DIR + if [ -n "$4" ]; then + cp $4 $BUILD_DIR + fi src=$(basename $2) obj=${src%.c}.o echo "obj-m := $obj" >> $BUILD_DIR/Kbuild @@ -49,7 +52,7 @@ for kernel in $1; do if [ -d $module ]; then build_directory $kernel $module $3 else - build_source $kernel $module $3 + build_source $kernel $module $3 $4 fi done done