From f9c0dcfaad64da3aca1dde32f6b477176c375c9d Mon Sep 17 00:00:00 2001 From: coolsnowwolf Date: Sun, 26 Nov 2017 14:09:36 +0800 Subject: [PATCH] update kernel 4.9 to 4.9.63 --- include/kernel-version.mk | 4 +- target/linux/ar7/config-3.18 | 1 - target/linux/ar7/{config-4.1 => config-4.9} | 44 +- .../linux/ar7/files/drivers/char/ar7_gpio.c | 158 - ...re-the-port-type-s-FCR-value-is-used.patch | 48 + .../ar7/patches-3.18/120-gpio_chrdev.patch | 28 - .../ar7/patches-3.18/500-serial_kludge.patch | 28 - .../ar7/patches-3.18/950-cpmac_titan.patch | 10 +- .../patches-4.1/001-mips-ar7-fix-serial.patch | 23 - .../ar7/patches-4.1/120-gpio_chrdev.patch | 28 - .../ar7/patches-4.1/500-serial_kludge.patch | 28 - ...re-the-port-type-s-FCR-value-is-used.patch | 48 + .../100-fix-highmem-offset.patch | 0 ...R7-allow-NULL-clock-for-clk_get_rate.patch | 0 .../110-flash.patch | 2 +- .../160-vlynq_try_remote_first.patch | 0 .../200-free-mem-below-kernel-offset.patch | 0 .../300-add-ac49x-platform.patch | 6 +- .../310-ac49x-prom-support.patch | 0 .../320-ac49x-mtd-partitions.patch | 4 +- .../920-ar7part.patch | 10 +- .../925-actiontec_leds.patch | 6 +- .../950-cpmac_titan.patch | 14 +- ...50-gpio-nxp-74hc153-gpio-chip-driver.patch | 2 +- .../452-gpio-add-gpio-latch-driver.patch | 2 +- .../950-0031-Add-dwc_otg-driver.patch | 2 +- ...tsq-add-shortcut-in-tcp_tasklet_func.patch | 2 +- ...-a-shortcut-in-tcp_small_queue_check.patch | 2 +- ...ove-tsq_flags-close-to-sk_wmem_alloc.patch | 6 +- ...tcp-allow-drivers-to-tweak-TSQ-logic.patch | 85 + ...90-net-generalize-napi_complete_done.patch | 6 +- .../hack-4.9/214-spidev_h_portability.patch | 2 +- .../661-use_fq_codel_by_default.patch | 2 +- .../702-phy_add_aneg_done_function.patch | 2 +- ...710-phy-add-mdio_register_board_info.patch | 2 +- ...ort-limiting-4K-sectors-support-base.patch | 56 + .../616-net_optimize_xfrm_calls.patch | 2 +- .../pending-4.9/630-packet_socket_type.patch | 16 +- .../pending-4.9/701-phy_extension.patch | 2 +- ...detach-callback-to-struct-phy_driver.patch | 2 +- ...-cpu-operating-points-for-cpufreq-su.patch | 6 +- ...018-qcom-ipq4019-turn-on-DMA-for-i2c.patch | 2 +- ...4019-use-correct-clock-for-i2c-bus-0.patch | 2 +- ...0020-qcom-ipq4019-enable-DMA-for-spi.patch | 2 +- .../0022-dts-ipq4019-support-ARMv7-PMU.patch | 2 +- .../0065-arm-override-compiler-flags.patch | 2 +- .../0069-arm-boot-add-dts-files.patch | 7 +- ...pq4019-add-remaining-pin-definitions.patch | 516 - ...-support-to-configure-ipq40xx-GPIO_P.patch | 149 - .../140-qcom-ipq4019-fix-i2c_0-node.patch | 28 - .../141-qcom-ipq4019-add-second-i2c.patch | 46 - ...use-v2-of-the-kpss-bringup-mechanism.patch | 10 +- ...-USB-nodes-to-ipq4019-SoC-device-tre.patch | 2 +- ...-both-IPQ4019-wifi-block-definitions.patch | 170 +- ...9-add-pseudo-random-number-generator.patch | 2 +- ...11-dts-ARM-qcom-ipq4019-add-scm-node.patch | 25 - .../312-firmware-qcom-scm-fuse-access.patch | 98 - .../701-dts-ipq4019-add-mdio-node.patch | 2 +- ...702-dts-ipq4019-add-PHY-switch-nodes.patch | 2 +- ...ts-ipq4019-add-ethernet-essedma-node.patch | 6 +- ...712-net-essedma-disable-default-vlan.patch | 69 - ...19-Add-IPQ4019-USB-HS-SS-PHY-drivers.patch | 71 +- ...ctrl-Updated-various-Pin-definitions.patch | 1328 ++ ...support-to-configure-ipq40xx-GPIO_PU.patch | 236 + ...q4019-add-nand-and-qpic-bam-dma-node.patch | 70 +- ...-2-dts-ipq4019-Fix-pinctrl-node-name.patch | 44 + ...-Move-xo-and-timer-nodes-to-SoC-dtsi.patch | 78 + ...pq4019-ap-dk04-fix-pinctrl-node-name.patch | 11 + ...19-ap-dk04-remove-xo-and-timer-nodes.patch | 27 + ...4019-ap-dk01-add-tcsr-config-to-dtsi.patch | 42 + ...19-ap-dk01-add-network-nodes-to-dtsi.patch | 32 + ...-dk01-remove-spi-chip-node-from-dtsi.patch | 17 + ...864-06-dts-ipq4019-fix-max-cpu-speed.patch | 13 + ...9-ap-dk01.1-c1-add-spi-and-ram-nodes.patch | 115 + ...9-ap-dk01.1-c1-add-compatible-string.patch | 10 + .../0026-NET-multi-phy-support.patch | 2 +- target/linux/layerscape/README | 151 + target/linux/layerscape/armv8_32b/config-4.9 | 98 +- .../armv8_32b/profiles/00-default.mk | 18 - target/linux/layerscape/armv8_64b/config-4.9 | 88 +- .../armv8_64b/profiles/00-default.mk | 18 - .../linux/layerscape/base-files/etc/rc.local | 4 - target/linux/layerscape/image/Makefile | 90 +- target/linux/layerscape/modules.mk | 5 +- .../201-config-support-layerscape.patch | 15 +- .../202-core-linux-support-layerscape.patch | 508 + .../301-arch-support-layerscape.patch | 10 +- .../302-dts-support-layercape.patch | 254 +- ...elect-ARCH_DMA_ADDR_T_64BIT-for-LPAE.patch | 23 + .../401-mtd-spi-nor-support-layerscape.patch | 110 +- .../601-net-support-layerscape.patch | 2365 ---- .../701-sdk_dpaa-support-layerscape.patch | 334 +- .../702-pci-support-layerscape.patch | 20 +- .../703-phy-support-layerscape.patch | 2 +- .../704-fsl-mc-layerscape-support.patch | 37 +- ...706-fsl-dpaa-use-4-9-ndo-get-stats64.patch | 112 + .../706-fsl_ppfe-support-layercape.patch | 10548 ++++++++++++++++ .../804-crypto-support-layerscape.patch | 151 +- .../805-dma-support-layerscape.patch | 608 +- .../806-flextimer-support-layerscape.patch | 99 +- .../810-iommu-support-layerscape.patch | 365 +- .../817-usb-support-layerscape.patch | 20 +- ...t-dsa-add-Mediatek-tag-RX-TX-handler.patch | 2 +- .../120-net-mvneta-add-BQL-support.patch | 16 +- .../300-mvneta-tx-queue-workaround.patch | 4 +- ...-a-hook-for-link-up-link-down-events.patch | 2 +- ...move-phy-MMD-accessors-to-phy-core.c.patch | 4 +- ..._-read-write-_mmd-generic-MMD-access.patch | 2 +- ...dd-802.3-clause-45-support-to-phylib.patch | 4 +- ...t-PHY-speed-and-duplex-string-genera.patch | 2 +- ..._lookup_setting-and-guts-of-phy_supp.patch | 2 +- ...5-phylink-add-phylink-infrastructure.patch | 4 +- .../419-net-mvneta-convert-to-phylink.patch | 52 +- ...le-MVNETA_CAUSE_PSC_SYNC_CHANGE-inte.patch | 8 +- ...22-net-mvneta-add-nway_reset-support.patch | 4 +- ...add-flow-control-support-via-phylink.patch | 10 +- ...ble-flow-control-for-PHY-connections.patch | 2 +- ...e-flow-control-for-fixed-connections.patch | 4 +- .../427-phylink-add-EEE-support.patch | 2 +- .../428-net-mvneta-add-EEE-support.patch | 22 +- ...ta-add-module-EEPROM-reading-support.patch | 4 +- .../ramips/base-files/etc/board.d/01_leds | 31 +- .../ramips/base-files/etc/board.d/02_network | 13 +- target/linux/ramips/base-files/etc/diag.sh | 15 +- .../lib/preinit/07_set_preinit_iface_ramips | 9 +- target/linux/ramips/base-files/lib/ramips.sh | 22 +- .../ramips/base-files/lib/upgrade/platform.sh | 7 + target/linux/ramips/dts/ArcherC20.dts | 187 + target/linux/ramips/dts/ArcherC50.dts | 7 +- target/linux/ramips/dts/D240.dts | 17 +- target/linux/ramips/dts/DCH-M225.dts | 18 +- target/linux/ramips/dts/DIR-615-H1.dts | 12 +- target/linux/ramips/dts/DIR-620-D1.dts | 12 +- target/linux/ramips/dts/DUZUN-DM06.dts | 16 +- target/linux/ramips/dts/EW1200.dts | 2 +- target/linux/ramips/dts/HC5X61.dtsi | 7 +- target/linux/ramips/dts/K2P.dts | 2 +- target/linux/ramips/dts/MIR3G.dts | 74 +- target/linux/ramips/dts/MIWIFI-MINI.dts | 7 +- target/linux/ramips/dts/PSG1218A.dts | 10 +- .../ramips/dts/RT5350F-OLINUXINO-EVB.dts | 71 +- target/linux/ramips/dts/RT5350F-OLINUXINO.dts | 71 +- .../linux/ramips/dts/RT5350F-OLINUXINO.dtsi | 94 + target/linux/ramips/dts/TL-WR840NV5.dts | 111 + target/linux/ramips/dts/U25AWF-H1.dts | 106 + target/linux/ramips/dts/U7621-06-256M-16M.dts | 86 + target/linux/ramips/dts/U7621-06.dtsi | 117 + target/linux/ramips/dts/U7628-01-128M-16M.dts | 83 + target/linux/ramips/dts/U7628-01.dtsi | 132 + target/linux/ramips/dts/VOCORE2.dtsi | 2 +- target/linux/ramips/dts/WE1026-5G-16M.dts | 76 + target/linux/ramips/dts/WE1026-5G.dtsi | 124 + target/linux/ramips/dts/WHR-300HP2.dts | 7 +- target/linux/ramips/dts/WIZFI630A.dts | 35 +- target/linux/ramips/dts/WL-351.dts | 6 +- target/linux/ramips/dts/WT3020-8M.dts | 8 + target/linux/ramips/dts/WT3020.dtsi | 9 - target/linux/ramips/dts/Y1.dtsi | 7 +- target/linux/ramips/dts/YOUKU-YK1.dts | 3 +- target/linux/ramips/dts/ZBT-APE522II.dts | 7 +- target/linux/ramips/dts/ZBT-WE3526.dts | 117 + target/linux/ramips/dts/ZBT-WG2626.dts | 2 +- target/linux/ramips/dts/ZBT-WG3526.dtsi | 2 +- target/linux/ramips/dts/ZBT-WR8305RT.dts | 7 +- target/linux/ramips/dts/mt7620a.dtsi | 14 + target/linux/ramips/dts/mt7620n.dtsi | 7 + target/linux/ramips/dts/mt7621.dtsi | 2 +- target/linux/ramips/dts/mt7628an.dtsi | 20 +- target/linux/ramips/dts/rt3050.dtsi | 7 + target/linux/ramips/dts/rt3352.dtsi | 14 + .../drivers/net/ethernet/mtk/mt7530.c | 8 +- .../drivers/net/ethernet/mtk/mtk_eth_soc.c | 4 +- target/linux/ramips/image/mt7620.mk | 70 +- target/linux/ramips/image/mt7621.mk | 21 +- target/linux/ramips/image/mt76x8.mk | 42 +- target/linux/ramips/mt7620/config-4.9 | 3 +- target/linux/ramips/mt7621/config-4.9 | 6 +- .../0034-NET-multi-phy-support.patch | 2 +- .../0039-mtd-add-mt7621-nand-support.patch | 5 +- .../ramips/patches-4.9/0040-nand-hack.patch | 2 +- ...d-spi-nor-add-w25q256-3b-mode-switch.patch | 214 + ...54-mtd-add-chunked-read-io-to-m25p80.patch | 19 +- ..._CMDEFTGT_MEM-according-to-datasheet.patch | 12 - .../0102-MIPS-ralink-Fix-MT7628-pinmux.patch | 33 + ...-ralink-Fix-typo-in-mt7628-pinmux-function | 31 + target/linux/ramips/rt305x/config-4.9 | 1 + target/linux/ramips/rt3883/config-4.9 | 1 + .../patches-4.9/0052-stmmac-form-4-12.patch | 464 +- target/linux/uml/Makefile | 2 +- ...-setjmp-symbol-clashes-with-libpthre.patch | 130 + ...-building-and-running-on-older-hosts.patch | 99 + ...-check-for-PTRACE_GETRESET-SETREGSET.patch | 29 + ...ix-check-for-_xstate-for-older-hosts.patch | 46 + .../uml/patches-4.9/101-mconsole-exec.patch | 211 + .../patches-4.9/102-pseudo-random-mac.patch | 131 + .../patches-4.9/100-fix_cs5535_clockevt.patch | 2 +- 196 files changed, 18501 insertions(+), 5032 deletions(-) rename target/linux/ar7/{config-4.1 => config-4.9} (83%) delete mode 100644 target/linux/ar7/files/drivers/char/ar7_gpio.c create mode 100644 target/linux/ar7/patches-3.18/002-MIPS-AR7-ensure-the-port-type-s-FCR-value-is-used.patch delete mode 100644 target/linux/ar7/patches-3.18/120-gpio_chrdev.patch delete mode 100644 target/linux/ar7/patches-3.18/500-serial_kludge.patch delete mode 100644 target/linux/ar7/patches-4.1/001-mips-ar7-fix-serial.patch delete mode 100644 target/linux/ar7/patches-4.1/120-gpio_chrdev.patch delete mode 100644 target/linux/ar7/patches-4.1/500-serial_kludge.patch create mode 100644 target/linux/ar7/patches-4.9/002-MIPS-AR7-ensure-the-port-type-s-FCR-value-is-used.patch rename target/linux/ar7/{patches-4.1 => patches-4.9}/100-fix-highmem-offset.patch (100%) rename target/linux/ar7/{patches-4.1 => patches-4.9}/101-MIPS-AR7-allow-NULL-clock-for-clk_get_rate.patch (100%) rename target/linux/ar7/{patches-4.1 => patches-4.9}/110-flash.patch (92%) rename target/linux/ar7/{patches-4.1 => patches-4.9}/160-vlynq_try_remote_first.patch (100%) rename target/linux/ar7/{patches-4.1 => patches-4.9}/200-free-mem-below-kernel-offset.patch (100%) rename target/linux/ar7/{patches-4.1 => patches-4.9}/300-add-ac49x-platform.patch (93%) rename target/linux/ar7/{patches-4.1 => patches-4.9}/310-ac49x-prom-support.patch (100%) rename target/linux/ar7/{patches-4.1 => patches-4.9}/320-ac49x-mtd-partitions.patch (91%) rename target/linux/ar7/{patches-4.1 => patches-4.9}/920-ar7part.patch (93%) rename target/linux/ar7/{patches-4.1 => patches-4.9}/925-actiontec_leds.patch (90%) rename target/linux/ar7/{patches-4.1 => patches-4.9}/950-cpmac_titan.patch (80%) create mode 100644 target/linux/generic/backport-4.9/025-tcp-allow-drivers-to-tweak-TSQ-logic.patch create mode 100644 target/linux/generic/pending-4.9/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch delete mode 100644 target/linux/ipq806x/patches-4.9/131-pinctrl-qcom-ipq4019-add-remaining-pin-definitions.patch delete mode 100644 target/linux/ipq806x/patches-4.9/132-pinctrl-qcom-add-support-to-configure-ipq40xx-GPIO_P.patch delete mode 100644 target/linux/ipq806x/patches-4.9/140-qcom-ipq4019-fix-i2c_0-node.patch delete mode 100644 target/linux/ipq806x/patches-4.9/141-qcom-ipq4019-add-second-i2c.patch delete mode 100644 target/linux/ipq806x/patches-4.9/311-dts-ARM-qcom-ipq4019-add-scm-node.patch delete mode 100644 target/linux/ipq806x/patches-4.9/312-firmware-qcom-scm-fuse-access.patch delete mode 100644 target/linux/ipq806x/patches-4.9/712-net-essedma-disable-default-vlan.patch create mode 100644 target/linux/ipq806x/patches-4.9/852-ipq4019-pinctrl-Updated-various-Pin-definitions.patch create mode 100644 target/linux/ipq806x/patches-4.9/859-msm-pinctrl-Add-support-to-configure-ipq40xx-GPIO_PU.patch create mode 100644 target/linux/ipq806x/patches-4.9/864-00-v3-1-2-dts-ipq4019-Fix-pinctrl-node-name.patch create mode 100644 target/linux/ipq806x/patches-4.9/864-00-v3-2-2-dts-ipq4019-Move-xo-and-timer-nodes-to-SoC-dtsi.patch create mode 100644 target/linux/ipq806x/patches-4.9/864-01-dts-ipq4019-ap-dk04-fix-pinctrl-node-name.patch create mode 100644 target/linux/ipq806x/patches-4.9/864-02-dts-ipq4019-ap-dk04-remove-xo-and-timer-nodes.patch create mode 100644 target/linux/ipq806x/patches-4.9/864-03-dts-ipq4019-ap-dk01-add-tcsr-config-to-dtsi.patch create mode 100644 target/linux/ipq806x/patches-4.9/864-04-dts-ipq4019-ap-dk01-add-network-nodes-to-dtsi.patch create mode 100644 target/linux/ipq806x/patches-4.9/864-05-dts-ipq4019-ap-dk01-remove-spi-chip-node-from-dtsi.patch create mode 100644 target/linux/ipq806x/patches-4.9/864-06-dts-ipq4019-fix-max-cpu-speed.patch create mode 100644 target/linux/ipq806x/patches-4.9/864-07-dts-ipq4019-ap-dk01.1-c1-add-spi-and-ram-nodes.patch create mode 100644 target/linux/ipq806x/patches-4.9/864-08-dts-ipq4019-ap-dk01.1-c1-add-compatible-string.patch create mode 100644 target/linux/layerscape/README delete mode 100644 target/linux/layerscape/armv8_32b/profiles/00-default.mk delete mode 100644 target/linux/layerscape/armv8_64b/profiles/00-default.mk delete mode 100644 target/linux/layerscape/base-files/etc/rc.local create mode 100644 target/linux/layerscape/patches-4.9/202-core-linux-support-layerscape.patch create mode 100644 target/linux/layerscape/patches-4.9/303-arm-imx-select-ARCH_DMA_ADDR_T_64BIT-for-LPAE.patch delete mode 100644 target/linux/layerscape/patches-4.9/601-net-support-layerscape.patch create mode 100644 target/linux/layerscape/patches-4.9/706-fsl-dpaa-use-4-9-ndo-get-stats64.patch create mode 100644 target/linux/layerscape/patches-4.9/706-fsl_ppfe-support-layercape.patch create mode 100644 target/linux/ramips/dts/ArcherC20.dts create mode 100644 target/linux/ramips/dts/RT5350F-OLINUXINO.dtsi create mode 100644 target/linux/ramips/dts/TL-WR840NV5.dts create mode 100644 target/linux/ramips/dts/U25AWF-H1.dts create mode 100644 target/linux/ramips/dts/U7621-06-256M-16M.dts create mode 100644 target/linux/ramips/dts/U7621-06.dtsi create mode 100644 target/linux/ramips/dts/U7628-01-128M-16M.dts create mode 100644 target/linux/ramips/dts/U7628-01.dtsi create mode 100644 target/linux/ramips/dts/WE1026-5G-16M.dts create mode 100644 target/linux/ramips/dts/WE1026-5G.dtsi create mode 100644 target/linux/ramips/dts/ZBT-WE3526.dts create mode 100644 target/linux/ramips/patches-4.9/0053-mtd-spi-nor-add-w25q256-3b-mode-switch.patch delete mode 100644 target/linux/ramips/patches-4.9/0063-set-CM_GCR_BASE_CMDEFTGT_MEM-according-to-datasheet.patch create mode 100644 target/linux/ramips/patches-4.9/0102-MIPS-ralink-Fix-MT7628-pinmux.patch create mode 100644 target/linux/ramips/patches-4.9/0103-MIPS-ralink-Fix-typo-in-mt7628-pinmux-function create mode 100644 target/linux/uml/patches-4.9/000-um-Avoid-longjmp-setjmp-symbol-clashes-with-libpthre.patch create mode 100644 target/linux/uml/patches-4.9/001-um-Allow-building-and-running-on-older-hosts.patch create mode 100644 target/linux/uml/patches-4.9/002-um-Correctly-check-for-PTRACE_GETRESET-SETREGSET.patch create mode 100644 target/linux/uml/patches-4.9/003-um-Fix-check-for-_xstate-for-older-hosts.patch create mode 100644 target/linux/uml/patches-4.9/101-mconsole-exec.patch create mode 100644 target/linux/uml/patches-4.9/102-pseudo-random-mac.patch diff --git a/include/kernel-version.mk b/include/kernel-version.mk index fdf4ac775..8848439c9 100644 --- a/include/kernel-version.mk +++ b/include/kernel-version.mk @@ -4,11 +4,11 @@ LINUX_RELEASE?=1 LINUX_VERSION-3.18 = .71 LINUX_VERSION-4.4 = .93 -LINUX_VERSION-4.9 = .61 +LINUX_VERSION-4.9 = .63 LINUX_KERNEL_HASH-3.18.71 = 5abc9778ad44ce02ed6c8ab52ece8a21c6d20d21f6ed8a19287b4a38a50c1240 LINUX_KERNEL_HASH-4.4.93 = ed349314f16e78a6571b5f8884f6452782aef6c26b81bcc7ccdac44ecd917c36 -LINUX_KERNEL_HASH-4.9.61 = e0239675728ef0c3697d4b651a1d1a1dd7b2920ed2c5f05a23a23d4aa726d19e +LINUX_KERNEL_HASH-4.9.63 = 21c9386f33fd3453ca67f7478b4c1ba34067645ef6d391871029cbd7f5df2ea3 ifdef KERNEL_PATCHVER LINUX_VERSION:=$(KERNEL_PATCHVER)$(strip $(LINUX_VERSION-$(KERNEL_PATCHVER))) diff --git a/target/linux/ar7/config-3.18 b/target/linux/ar7/config-3.18 index 21c86db65..a91d45e8d 100644 --- a/target/linux/ar7/config-3.18 +++ b/target/linux/ar7/config-3.18 @@ -1,6 +1,5 @@ CONFIG_ADM6996_PHY=y CONFIG_AR7=y -CONFIG_AR7_GPIO=y CONFIG_AR7_TI=y # CONFIG_AR7_TYPE_AC49X is not set CONFIG_AR7_TYPE_TI=y diff --git a/target/linux/ar7/config-4.1 b/target/linux/ar7/config-4.9 similarity index 83% rename from target/linux/ar7/config-4.1 rename to target/linux/ar7/config-4.9 index 7463d5b75..95a5375ba 100644 --- a/target/linux/ar7/config-4.1 +++ b/target/linux/ar7/config-4.9 @@ -1,22 +1,21 @@ CONFIG_ADM6996_PHY=y CONFIG_AR7=y -CONFIG_AR7_GPIO=y CONFIG_AR7_TI=y # CONFIG_AR7_TYPE_AC49X is not set CONFIG_AR7_TYPE_TI=y CONFIG_AR7_WDT=y CONFIG_ARCH_BINFMT_ELF_STATE=y +CONFIG_ARCH_CLOCKSOURCE_DATA=y CONFIG_ARCH_DISCARD_MEMBLOCK=y -CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y CONFIG_ARCH_HAS_ELF_RANDOMIZE=y # CONFIG_ARCH_HAS_GCOV_PROFILE_ALL is not set # CONFIG_ARCH_HAS_SG_CHAIN is not set -CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y -CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_ARCH_SUPPORTS_UPROBES=y CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y CONFIG_BOOT_ELF32=y CONFIG_CEVT_R4K=y @@ -37,6 +36,8 @@ CONFIG_CPU_R4K_CACHE_TLB=y CONFIG_CPU_R4K_FPU=y CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_WORKQUEUE=y CONFIG_CSRC_R4K=y CONFIG_DMA_NONCOHERENT=y CONFIG_EARLY_PRINTK=y @@ -46,12 +47,14 @@ CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_GENERIC_IO=y +CONFIG_GENERIC_IRQ_CHIP=y CONFIG_GENERIC_IRQ_SHOW=y CONFIG_GENERIC_PCI_IOMAP=y CONFIG_GENERIC_SCHED_CLOCK=y CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GPIOLIB=y -CONFIG_GPIO_DEVRES=y +CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_HARDWARE_WATCHPOINTS=y CONFIG_HAS_DMA=y CONFIG_HAS_IOMEM=y @@ -63,7 +66,7 @@ CONFIG_HAVE_ARCH_KGDB=y CONFIG_HAVE_ARCH_SECCOMP_FILTER=y CONFIG_HAVE_ARCH_TRACEHOOK=y # CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -CONFIG_HAVE_BPF_JIT=y +CONFIG_HAVE_CBPF_JIT=y CONFIG_HAVE_CC_STACKPROTECTOR=y CONFIG_HAVE_CLK=y CONFIG_HAVE_CONTEXT_TRACKING=y @@ -71,7 +74,6 @@ CONFIG_HAVE_C_RECORDMCOUNT=y CONFIG_HAVE_DEBUG_KMEMLEAK=y CONFIG_HAVE_DEBUG_STACKOVERFLOW=y CONFIG_HAVE_DMA_API_DEBUG=y -CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_DMA_CONTIGUOUS=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y @@ -79,36 +81,36 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_HAVE_IDE=y +CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_KERNEL_BZIP2=y -CONFIG_HAVE_KERNEL_GZIP=y -CONFIG_HAVE_KERNEL_LZ4=y -CONFIG_HAVE_KERNEL_LZMA=y -CONFIG_HAVE_KERNEL_LZO=y -CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_HAVE_MEMBLOCK=y CONFIG_HAVE_MEMBLOCK_NODE_MAP=y CONFIG_HAVE_MOD_ARCH_SPECIFIC=y CONFIG_HAVE_NET_DSA=y CONFIG_HAVE_OPROFILE=y CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HW_RANDOM=y CONFIG_HZ_PERIODIC=y CONFIG_INITRAMFS_SOURCE="" CONFIG_IP17XX_PHY=y -CONFIG_IRQ_CPU=y CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_MIPS_CPU=y CONFIG_IRQ_WORK=y CONFIG_KALLSYMS=y CONFIG_LEDS_GPIO=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y -# CONFIG_LZ4_COMPRESS is not set -# CONFIG_LZ4_DECOMPRESS is not set CONFIG_MDIO_BOARDINFO=y CONFIG_MIPS=y +CONFIG_MIPS_ASID_BITS=8 +CONFIG_MIPS_ASID_SHIFT=0 +CONFIG_MIPS_CLOCK_VSYSCALL=y +# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set +CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y # CONFIG_MIPS_HUGE_TLB_SUPPORT is not set CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_MIPS_MACHINE is not set @@ -120,18 +122,21 @@ CONFIG_MVSWITCH_PHY=y CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEED_PER_CPU_KM=y CONFIG_NO_EXCEPT_FILL=y +CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y # CONFIG_NO_IOPORT_MAP is not set -CONFIG_PAGEFLAGS_EXTENDED=y +# CONFIG_OF is not set +CONFIG_PCI_DRIVERS_LEGACY=y CONFIG_PERF_USE_VMALLOC=y CONFIG_PGTABLE_LEVELS=2 CONFIG_PHYLIB=y -# CONFIG_RCU_EXPEDITE_BOOT is not set # CONFIG_RCU_STALL_COMMON is not set -CONFIG_SCHED_HRTICK=y +# CONFIG_SCHED_INFO is not set # CONFIG_SCSI_DMA is not set +# CONFIG_SERIAL_8250_FSL is not set CONFIG_SRCU=y CONFIG_SWAP_IO_SPACE=y CONFIG_SWCONFIG=y +CONFIG_SWPHY=y CONFIG_SYSCTL_EXCEPTION_TRACE=y CONFIG_SYS_HAS_CPU_MIPS32_R1=y CONFIG_SYS_HAS_EARLY_PRINTK=y @@ -144,4 +149,3 @@ CONFIG_SYS_SUPPORTS_ZBOOT_UART16550=y CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_VLYNQ=y # CONFIG_VLYNQ_DEBUG is not set -CONFIG_ZONE_DMA_FLAG=0 diff --git a/target/linux/ar7/files/drivers/char/ar7_gpio.c b/target/linux/ar7/files/drivers/char/ar7_gpio.c deleted file mode 100644 index 71310fa75..000000000 --- a/target/linux/ar7/files/drivers/char/ar7_gpio.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2007 Nicolas Thill - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRVNAME "ar7_gpio" -#define LONGNAME "TI AR7 GPIOs Driver" - -MODULE_AUTHOR("Nicolas Thill "); -MODULE_DESCRIPTION(LONGNAME); -MODULE_LICENSE("GPL"); - -static int ar7_gpio_major; - -static ssize_t ar7_gpio_write(struct file *file, const char __user *buf, - size_t len, loff_t *ppos) -{ - int pin = iminor(file->f_path.dentry->d_inode); - size_t i; - - for (i = 0; i < len; ++i) { - char c; - if (get_user(c, buf + i)) - return -EFAULT; - switch (c) { - case '0': - gpio_set_value(pin, 0); - break; - case '1': - gpio_set_value(pin, 1); - break; - case 'd': - case 'D': - ar7_gpio_disable(pin); - break; - case 'e': - case 'E': - ar7_gpio_enable(pin); - break; - case 'i': - case 'I': - case '<': - gpio_direction_input(pin); - break; - case 'o': - case 'O': - case '>': - gpio_direction_output(pin, 0); - break; - default: - return -EINVAL; - } - } - - return len; -} - -static ssize_t ar7_gpio_read(struct file *file, char __user *buf, - size_t len, loff_t *ppos) -{ - int pin = iminor(file->f_path.dentry->d_inode); - int value; - - value = gpio_get_value(pin); - if (put_user(value ? '1' : '0', buf)) - return -EFAULT; - - return 1; -} - -static int ar7_gpio_open(struct inode *inode, struct file *file) -{ - int m = iminor(inode); - - if (m >= (ar7_is_titan() ? TITAN_GPIO_MAX : AR7_GPIO_MAX)) - return -EINVAL; - - return nonseekable_open(inode, file); -} - -static int ar7_gpio_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static const struct file_operations ar7_gpio_fops = { - .owner = THIS_MODULE, - .write = ar7_gpio_write, - .read = ar7_gpio_read, - .open = ar7_gpio_open, - .release = ar7_gpio_release, - .llseek = no_llseek, -}; - -static struct platform_device *ar7_gpio_device; - -static int __init ar7_gpio_char_init(void) -{ - int rc; - - ar7_gpio_device = platform_device_alloc(DRVNAME, -1); - if (!ar7_gpio_device) - return -ENOMEM; - - rc = platform_device_add(ar7_gpio_device); - if (rc < 0) - goto out_put; - - rc = register_chrdev(ar7_gpio_major, DRVNAME, &ar7_gpio_fops); - if (rc < 0) - goto out_put; - - ar7_gpio_major = rc; - - rc = 0; - - goto out; - -out_put: - platform_device_put(ar7_gpio_device); -out: - return rc; -} - -static void __exit ar7_gpio_char_exit(void) -{ - unregister_chrdev(ar7_gpio_major, DRVNAME); - platform_device_unregister(ar7_gpio_device); -} - -module_init(ar7_gpio_char_init); -module_exit(ar7_gpio_char_exit); diff --git a/target/linux/ar7/patches-3.18/002-MIPS-AR7-ensure-the-port-type-s-FCR-value-is-used.patch b/target/linux/ar7/patches-3.18/002-MIPS-AR7-ensure-the-port-type-s-FCR-value-is-used.patch new file mode 100644 index 000000000..f6a875486 --- /dev/null +++ b/target/linux/ar7/patches-3.18/002-MIPS-AR7-ensure-the-port-type-s-FCR-value-is-used.patch @@ -0,0 +1,48 @@ +From ee6c9d41de084b2cefd90e5e0c9f30a35f6d3967 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Sun, 29 Oct 2017 15:50:42 +0100 +Subject: [PATCH RFC 3/3] MIPS: AR7: ensure the port type's FCR value is used + +Since commit aef9a7bd9b67 ("serial/uart/8250: Add tunable RX interrupt +trigger I/F of FIFO buffers"), the port's default FCR value isn't used +in serial8250_do_set_termios anymore, but copied over once in +serial8250_config_port and then modified as needed. + +Unfortunately, serial8250_config_port will never be called if the port +is shared between kernel and userspace, and the port's flag doesn't have +UPF_BOOT_AUTOCONF, which would trigger a serial8250_config_port as well. + +This causes garbled output from userspace: + +[ 5.220000] random: procd urandom read with 49 bits of entropy available +ers + [kee + +Fix this by forcing it to be configured on boot, resulting in the +expected output: + +[ 5.250000] random: procd urandom read with 50 bits of entropy available +Press the [f] key and hit [enter] to enter failsafe mode +Press the [1], [2], [3] or [4] key and hit [enter] to select the debug level + +Fixes: aef9a7bd9b67 ("serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers") +Signed-off-by: Jonas Gorski +--- +I'm not sure if this is just AR7's issue, or if this points to a general +issue for UARTs used as kernel console and login console with the "fixed" +commit. + + arch/mips/ar7/platform.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/mips/ar7/platform.c ++++ b/arch/mips/ar7/platform.c +@@ -581,7 +581,7 @@ static int __init ar7_register_uarts(voi + uart_port.type = PORT_AR7; + uart_port.uartclk = clk_get_rate(bus_clk) / 2; + uart_port.iotype = UPIO_MEM32; +- uart_port.flags = UPF_FIXED_TYPE; ++ uart_port.flags = UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF; + uart_port.regshift = 2; + + uart_port.line = 0; diff --git a/target/linux/ar7/patches-3.18/120-gpio_chrdev.patch b/target/linux/ar7/patches-3.18/120-gpio_chrdev.patch deleted file mode 100644 index beb0052ca..000000000 --- a/target/linux/ar7/patches-3.18/120-gpio_chrdev.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- a/drivers/char/Kconfig -+++ b/drivers/char/Kconfig -@@ -452,6 +452,15 @@ config MWAVE - To compile this driver as a module, choose M here: the - module will be called mwave. - -+config AR7_GPIO -+ tristate "TI AR7 GPIO Support" -+ depends on AR7 -+ help -+ Give userspace access to the GPIO pins on the Texas Instruments AR7 -+ processors. -+ -+ If compiled as a module, it will be called ar7_gpio. -+ - config SCx200_GPIO - tristate "NatSemi SCx200 GPIO Support" - depends on SCx200 ---- a/drivers/char/Makefile -+++ b/drivers/char/Makefile -@@ -42,6 +42,7 @@ obj-$(CONFIG_HW_RANDOM) += hw_random/ - obj-$(CONFIG_PPDEV) += ppdev.o - obj-$(CONFIG_NWBUTTON) += nwbutton.o - obj-$(CONFIG_NWFLASH) += nwflash.o -+obj-$(CONFIG_AR7_GPIO) += ar7_gpio.o - obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o - obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o - obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o diff --git a/target/linux/ar7/patches-3.18/500-serial_kludge.patch b/target/linux/ar7/patches-3.18/500-serial_kludge.patch deleted file mode 100644 index fc725309a..000000000 --- a/target/linux/ar7/patches-3.18/500-serial_kludge.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- a/drivers/tty/serial/8250/8250_core.c -+++ b/drivers/tty/serial/8250/8250_core.c -@@ -329,6 +329,13 @@ static const struct serial8250_config ua - .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, - .flags = UART_CAP_FIFO | UART_CAP_AFE, - }, -+ [PORT_AR7] = { -+ .name = "TI-AR7", -+ .fifo_size = 16, -+ .tx_loadsz = 16, -+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, -+ .flags = UART_CAP_FIFO | UART_CAP_AFE, -+ }, - }; - - /* Uart divisor latch read */ -@@ -3168,7 +3175,11 @@ static void serial8250_console_putchar(s - { - struct uart_8250_port *up = up_to_u8250p(port); - -+#ifdef CONFIG_AR7 -+ wait_for_xmitr(up, BOTH_EMPTY); -+#else - wait_for_xmitr(up, UART_LSR_THRE); -+#endif - serial_port_out(port, UART_TX, ch); - } - diff --git a/target/linux/ar7/patches-3.18/950-cpmac_titan.patch b/target/linux/ar7/patches-3.18/950-cpmac_titan.patch index f1d432cc4..3cabae067 100644 --- a/target/linux/ar7/patches-3.18/950-cpmac_titan.patch +++ b/target/linux/ar7/patches-3.18/950-cpmac_titan.patch @@ -1,6 +1,6 @@ --- a/drivers/net/ethernet/ti/cpmac.c +++ b/drivers/net/ethernet/ti/cpmac.c -@@ -1146,6 +1146,8 @@ static int cpmac_probe(struct platform_d +@@ -1147,6 +1147,8 @@ static int cpmac_probe(struct platform_d goto out; } @@ -9,7 +9,7 @@ dev->irq = platform_get_irq_byname(pdev, "irq"); dev->netdev_ops = &cpmac_netdev_ops; -@@ -1227,7 +1229,7 @@ int cpmac_init(void) +@@ -1228,7 +1230,7 @@ int cpmac_init(void) cpmac_mii->reset = cpmac_mdio_reset; cpmac_mii->irq = mii_irqs; @@ -18,8 +18,8 @@ if (!cpmac_mii->priv) { pr_err("Can't ioremap mdio registers\n"); -@@ -1238,10 +1240,16 @@ int cpmac_init(void) - #warning FIXME: unhardcode gpio&reset bits +@@ -1239,10 +1241,16 @@ int cpmac_init(void) + /* FIXME: unhardcode gpio&reset bits */ ar7_gpio_disable(26); ar7_gpio_disable(27); - ar7_device_reset(AR7_RESET_BIT_CPMAC_LO); @@ -37,7 +37,7 @@ cpmac_mii->reset(cpmac_mii); for (i = 0; i < 300; i++) { -@@ -1258,7 +1266,11 @@ int cpmac_init(void) +@@ -1259,7 +1267,11 @@ int cpmac_init(void) mask = 0; } diff --git a/target/linux/ar7/patches-4.1/001-mips-ar7-fix-serial.patch b/target/linux/ar7/patches-4.1/001-mips-ar7-fix-serial.patch deleted file mode 100644 index 1aded9246..000000000 --- a/target/linux/ar7/patches-4.1/001-mips-ar7-fix-serial.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 443ab715a40881d6c9ba11b027ba154bac904cb0 Mon Sep 17 00:00:00 2001 -From: Oswald Buddenhagen -Date: Sat, 10 May 2014 23:19:08 +0200 -Subject: [PATCH] MIPS/AR7: ensure that serial ports are properly set up - -without UPF_FIXED_TYPE, the data from the PORT_AR7 uart_config entry is -never copied, resulting in a dead port. - -Signed-off-by: Oswald Buddenhagen ---- - arch/mips/ar7/platform.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/mips/ar7/platform.c -+++ b/arch/mips/ar7/platform.c -@@ -577,6 +577,7 @@ static int __init ar7_register_uarts(voi - uart_port.type = PORT_AR7; - uart_port.uartclk = clk_get_rate(bus_clk) / 2; - uart_port.iotype = UPIO_MEM32; -+ uart_port.flags = UPF_FIXED_TYPE; - uart_port.regshift = 2; - - uart_port.line = 0; diff --git a/target/linux/ar7/patches-4.1/120-gpio_chrdev.patch b/target/linux/ar7/patches-4.1/120-gpio_chrdev.patch deleted file mode 100644 index 1468ca321..000000000 --- a/target/linux/ar7/patches-4.1/120-gpio_chrdev.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- a/drivers/char/Kconfig -+++ b/drivers/char/Kconfig -@@ -461,6 +461,15 @@ config MWAVE - To compile this driver as a module, choose M here: the - module will be called mwave. - -+config AR7_GPIO -+ tristate "TI AR7 GPIO Support" -+ depends on AR7 -+ help -+ Give userspace access to the GPIO pins on the Texas Instruments AR7 -+ processors. -+ -+ If compiled as a module, it will be called ar7_gpio. -+ - config SCx200_GPIO - tristate "NatSemi SCx200 GPIO Support" - depends on SCx200 ---- a/drivers/char/Makefile -+++ b/drivers/char/Makefile -@@ -42,6 +42,7 @@ obj-$(CONFIG_HW_RANDOM) += hw_random/ - obj-$(CONFIG_PPDEV) += ppdev.o - obj-$(CONFIG_NWBUTTON) += nwbutton.o - obj-$(CONFIG_NWFLASH) += nwflash.o -+obj-$(CONFIG_AR7_GPIO) += ar7_gpio.o - obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o - obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o - obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o diff --git a/target/linux/ar7/patches-4.1/500-serial_kludge.patch b/target/linux/ar7/patches-4.1/500-serial_kludge.patch deleted file mode 100644 index c7bb29707..000000000 --- a/target/linux/ar7/patches-4.1/500-serial_kludge.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- a/drivers/tty/serial/8250/8250_core.c -+++ b/drivers/tty/serial/8250/8250_core.c -@@ -347,6 +347,13 @@ configured less than Maximum supported f - .rxtrig_bytes = {1, 4, 8, 14}, - .flags = UART_CAP_FIFO, - }, -+ [PORT_AR7] = { -+ .name = "TI-AR7", -+ .fifo_size = 16, -+ .tx_loadsz = 16, -+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, -+ .flags = UART_CAP_FIFO | UART_CAP_AFE, -+ }, - }; - - /* Uart divisor latch read */ -@@ -3342,7 +3349,11 @@ static void serial8250_console_putchar(s - { - struct uart_8250_port *up = up_to_u8250p(port); - -+#ifdef CONFIG_AR7 -+ wait_for_xmitr(up, BOTH_EMPTY); -+#else - wait_for_xmitr(up, UART_LSR_THRE); -+#endif - serial_port_out(port, UART_TX, ch); - } - diff --git a/target/linux/ar7/patches-4.9/002-MIPS-AR7-ensure-the-port-type-s-FCR-value-is-used.patch b/target/linux/ar7/patches-4.9/002-MIPS-AR7-ensure-the-port-type-s-FCR-value-is-used.patch new file mode 100644 index 000000000..cc1a541a3 --- /dev/null +++ b/target/linux/ar7/patches-4.9/002-MIPS-AR7-ensure-the-port-type-s-FCR-value-is-used.patch @@ -0,0 +1,48 @@ +From ee6c9d41de084b2cefd90e5e0c9f30a35f6d3967 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski +Date: Sun, 29 Oct 2017 15:50:42 +0100 +Subject: [PATCH RFC 3/3] MIPS: AR7: ensure the port type's FCR value is used + +Since commit aef9a7bd9b67 ("serial/uart/8250: Add tunable RX interrupt +trigger I/F of FIFO buffers"), the port's default FCR value isn't used +in serial8250_do_set_termios anymore, but copied over once in +serial8250_config_port and then modified as needed. + +Unfortunately, serial8250_config_port will never be called if the port +is shared between kernel and userspace, and the port's flag doesn't have +UPF_BOOT_AUTOCONF, which would trigger a serial8250_config_port as well. + +This causes garbled output from userspace: + +[ 5.220000] random: procd urandom read with 49 bits of entropy available +ers + [kee + +Fix this by forcing it to be configured on boot, resulting in the +expected output: + +[ 5.250000] random: procd urandom read with 50 bits of entropy available +Press the [f] key and hit [enter] to enter failsafe mode +Press the [1], [2], [3] or [4] key and hit [enter] to select the debug level + +Fixes: aef9a7bd9b67 ("serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers") +Signed-off-by: Jonas Gorski +--- +I'm not sure if this is just AR7's issue, or if this points to a general +issue for UARTs used as kernel console and login console with the "fixed" +commit. + + arch/mips/ar7/platform.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/mips/ar7/platform.c ++++ b/arch/mips/ar7/platform.c +@@ -576,7 +576,7 @@ static int __init ar7_register_uarts(voi + uart_port.type = PORT_AR7; + uart_port.uartclk = clk_get_rate(bus_clk) / 2; + uart_port.iotype = UPIO_MEM32; +- uart_port.flags = UPF_FIXED_TYPE; ++ uart_port.flags = UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF; + uart_port.regshift = 2; + + uart_port.line = 0; diff --git a/target/linux/ar7/patches-4.1/100-fix-highmem-offset.patch b/target/linux/ar7/patches-4.9/100-fix-highmem-offset.patch similarity index 100% rename from target/linux/ar7/patches-4.1/100-fix-highmem-offset.patch rename to target/linux/ar7/patches-4.9/100-fix-highmem-offset.patch diff --git a/target/linux/ar7/patches-4.1/101-MIPS-AR7-allow-NULL-clock-for-clk_get_rate.patch b/target/linux/ar7/patches-4.9/101-MIPS-AR7-allow-NULL-clock-for-clk_get_rate.patch similarity index 100% rename from target/linux/ar7/patches-4.1/101-MIPS-AR7-allow-NULL-clock-for-clk_get_rate.patch rename to target/linux/ar7/patches-4.9/101-MIPS-AR7-allow-NULL-clock-for-clk_get_rate.patch diff --git a/target/linux/ar7/patches-4.1/110-flash.patch b/target/linux/ar7/patches-4.9/110-flash.patch similarity index 92% rename from target/linux/ar7/patches-4.1/110-flash.patch rename to target/linux/ar7/patches-4.9/110-flash.patch index e4aeffd3e..f5713bd03 100644 --- a/target/linux/ar7/patches-4.1/110-flash.patch +++ b/target/linux/ar7/patches-4.9/110-flash.patch @@ -11,7 +11,7 @@ obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c -@@ -199,7 +199,7 @@ static struct resource physmap_flash_res +@@ -198,7 +198,7 @@ static struct resource physmap_flash_res .name = "mem", .flags = IORESOURCE_MEM, .start = 0x10000000, diff --git a/target/linux/ar7/patches-4.1/160-vlynq_try_remote_first.patch b/target/linux/ar7/patches-4.9/160-vlynq_try_remote_first.patch similarity index 100% rename from target/linux/ar7/patches-4.1/160-vlynq_try_remote_first.patch rename to target/linux/ar7/patches-4.9/160-vlynq_try_remote_first.patch diff --git a/target/linux/ar7/patches-4.1/200-free-mem-below-kernel-offset.patch b/target/linux/ar7/patches-4.9/200-free-mem-below-kernel-offset.patch similarity index 100% rename from target/linux/ar7/patches-4.1/200-free-mem-below-kernel-offset.patch rename to target/linux/ar7/patches-4.9/200-free-mem-below-kernel-offset.patch diff --git a/target/linux/ar7/patches-4.1/300-add-ac49x-platform.patch b/target/linux/ar7/patches-4.9/300-add-ac49x-platform.patch similarity index 93% rename from target/linux/ar7/patches-4.1/300-add-ac49x-platform.patch rename to target/linux/ar7/patches-4.9/300-add-ac49x-platform.patch index 2e5528e72..c17ae69aa 100644 --- a/target/linux/ar7/patches-4.1/300-add-ac49x-platform.patch +++ b/target/linux/ar7/patches-4.9/300-add-ac49x-platform.patch @@ -13,7 +13,7 @@ +load-$(CONFIG_AR7_AC49X) += 0xffffffff945ca000 --- a/arch/mips/ar7/setup.c +++ b/arch/mips/ar7/setup.c -@@ -69,6 +69,10 @@ const char *get_system_type(void) +@@ -68,6 +68,10 @@ const char *get_system_type(void) return "TI AR7 (TNETV1056)"; case TITAN_CHIP_1060: return "TI AR7 (TNETV1060)"; @@ -37,7 +37,7 @@ #define AR7_IRQ_UART0 15 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig -@@ -99,7 +99,7 @@ config AR7 +@@ -160,7 +160,7 @@ config AR7 select HAVE_CLK help Support for the Texas Instruments AR7 System-on-a-Chip @@ -46,7 +46,7 @@ config ATH25 bool "Atheros AR231x/AR531x SoC support" -@@ -925,6 +925,7 @@ config MIPS_PARAVIRT +@@ -1002,6 +1002,7 @@ config MIPS_PARAVIRT endchoice source "arch/mips/alchemy/Kconfig" diff --git a/target/linux/ar7/patches-4.1/310-ac49x-prom-support.patch b/target/linux/ar7/patches-4.9/310-ac49x-prom-support.patch similarity index 100% rename from target/linux/ar7/patches-4.1/310-ac49x-prom-support.patch rename to target/linux/ar7/patches-4.9/310-ac49x-prom-support.patch diff --git a/target/linux/ar7/patches-4.1/320-ac49x-mtd-partitions.patch b/target/linux/ar7/patches-4.9/320-ac49x-mtd-partitions.patch similarity index 91% rename from target/linux/ar7/patches-4.1/320-ac49x-mtd-partitions.patch rename to target/linux/ar7/patches-4.9/320-ac49x-mtd-partitions.patch index 23304931e..fafa8c77e 100644 --- a/target/linux/ar7/patches-4.1/320-ac49x-mtd-partitions.patch +++ b/target/linux/ar7/patches-4.9/320-ac49x-mtd-partitions.patch @@ -1,6 +1,6 @@ --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig -@@ -159,6 +159,11 @@ config MTD_OF_PARTS +@@ -154,6 +154,11 @@ config MTD_OF_PARTS the partition map from the children of the flash node, as described in Documentation/devicetree/bindings/mtd/partition.txt. @@ -24,7 +24,7 @@ obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c -@@ -202,7 +202,7 @@ static struct resource physmap_flash_res +@@ -201,7 +201,7 @@ static struct resource physmap_flash_res .end = 0x11ffffff, }; diff --git a/target/linux/ar7/patches-4.1/920-ar7part.patch b/target/linux/ar7/patches-4.9/920-ar7part.patch similarity index 93% rename from target/linux/ar7/patches-4.1/920-ar7part.patch rename to target/linux/ar7/patches-4.9/920-ar7part.patch index 9948858d0..e520af208 100644 --- a/target/linux/ar7/patches-4.1/920-ar7part.patch +++ b/target/linux/ar7/patches-4.9/920-ar7part.patch @@ -20,11 +20,11 @@ }; +int create_titan_partitions(struct mtd_info *master, -+ struct mtd_partition **pparts, ++ const struct mtd_partition **pparts, + struct mtd_part_parser_data *data); + static int create_mtd_partitions(struct mtd_info *master, - struct mtd_partition **pparts, + const struct mtd_partition **pparts, struct mtd_part_parser_data *data) { struct ar7_bin_rec header; @@ -107,11 +107,13 @@ root_offset += master->erasesize - 1; --- a/drivers/mtd/titanpart.c +++ b/drivers/mtd/titanpart.c -@@ -149,7 +149,7 @@ static void titan_add_partition(char * e +@@ -148,8 +148,8 @@ static void titan_add_partition(char * e + } int create_titan_partitions(struct mtd_info *master, - struct mtd_partition **pparts, +- struct mtd_partition **pparts, - unsigned long origin) ++ const struct mtd_partition **pparts, + struct mtd_part_parser_data *data) { struct nsp_img_hdr_head hdr; diff --git a/target/linux/ar7/patches-4.1/925-actiontec_leds.patch b/target/linux/ar7/patches-4.9/925-actiontec_leds.patch similarity index 90% rename from target/linux/ar7/patches-4.1/925-actiontec_leds.patch rename to target/linux/ar7/patches-4.9/925-actiontec_leds.patch index 1346a210f..804dbf5c3 100644 --- a/target/linux/ar7/patches-4.1/925-actiontec_leds.patch +++ b/target/linux/ar7/patches-4.9/925-actiontec_leds.patch @@ -1,6 +1,6 @@ --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c -@@ -461,31 +461,22 @@ static struct gpio_led fb_fon_leds[] = { +@@ -460,31 +460,22 @@ static struct gpio_led fb_fon_leds[] = { }, }; @@ -35,7 +35,7 @@ .default_trigger = "default-on", }, { -@@ -493,6 +484,44 @@ static struct gpio_led gt701_leds[] = { +@@ -492,6 +483,44 @@ static struct gpio_led gt701_leds[] = { .gpio = 10, .active_low = 1, }, @@ -80,7 +80,7 @@ }; static struct gpio_led_platform_data ar7_led_data; -@@ -536,9 +565,9 @@ static void __init detect_leds(void) +@@ -535,9 +564,9 @@ static void __init detect_leds(void) } else if (strstr(prid, "CYWM") || strstr(prid, "CYWL")) { ar7_led_data.num_leds = ARRAY_SIZE(titan_leds); ar7_led_data.leds = titan_leds; diff --git a/target/linux/ar7/patches-4.1/950-cpmac_titan.patch b/target/linux/ar7/patches-4.9/950-cpmac_titan.patch similarity index 80% rename from target/linux/ar7/patches-4.1/950-cpmac_titan.patch rename to target/linux/ar7/patches-4.9/950-cpmac_titan.patch index f1d432cc4..158b689c9 100644 --- a/target/linux/ar7/patches-4.1/950-cpmac_titan.patch +++ b/target/linux/ar7/patches-4.9/950-cpmac_titan.patch @@ -1,7 +1,7 @@ --- a/drivers/net/ethernet/ti/cpmac.c +++ b/drivers/net/ethernet/ti/cpmac.c -@@ -1146,6 +1146,8 @@ static int cpmac_probe(struct platform_d - goto out; +@@ -1124,6 +1124,8 @@ static int cpmac_probe(struct platform_d + goto fail; } + ar7_device_reset(pdata->reset_bit); @@ -9,17 +9,17 @@ dev->irq = platform_get_irq_byname(pdev, "irq"); dev->netdev_ops = &cpmac_netdev_ops; -@@ -1227,7 +1229,7 @@ int cpmac_init(void) +@@ -1203,7 +1205,7 @@ int cpmac_init(void) + cpmac_mii->write = cpmac_mdio_write; cpmac_mii->reset = cpmac_mdio_reset; - cpmac_mii->irq = mii_irqs; - cpmac_mii->priv = ioremap(AR7_REGS_MDIO, 256); + cpmac_mii->priv = ioremap(ar7_is_titan() ? TITAN_REGS_MDIO : AR7_REGS_MDIO, 256); if (!cpmac_mii->priv) { pr_err("Can't ioremap mdio registers\n"); -@@ -1238,10 +1240,16 @@ int cpmac_init(void) - #warning FIXME: unhardcode gpio&reset bits +@@ -1214,10 +1216,16 @@ int cpmac_init(void) + /* FIXME: unhardcode gpio&reset bits */ ar7_gpio_disable(26); ar7_gpio_disable(27); - ar7_device_reset(AR7_RESET_BIT_CPMAC_LO); @@ -37,7 +37,7 @@ cpmac_mii->reset(cpmac_mii); for (i = 0; i < 300; i++) { -@@ -1258,7 +1266,11 @@ int cpmac_init(void) +@@ -1234,7 +1242,11 @@ int cpmac_init(void) mask = 0; } diff --git a/target/linux/ar71xx/patches-4.9/450-gpio-nxp-74hc153-gpio-chip-driver.patch b/target/linux/ar71xx/patches-4.9/450-gpio-nxp-74hc153-gpio-chip-driver.patch index 41cf75a55..7ffdc769e 100644 --- a/target/linux/ar71xx/patches-4.9/450-gpio-nxp-74hc153-gpio-chip-driver.patch +++ b/target/linux/ar71xx/patches-4.9/450-gpio-nxp-74hc153-gpio-chip-driver.patch @@ -1,6 +1,6 @@ --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig -@@ -1211,4 +1211,12 @@ config GPIO_VIPERBOARD +@@ -1213,4 +1213,12 @@ config GPIO_VIPERBOARD endmenu diff --git a/target/linux/ar71xx/patches-4.9/452-gpio-add-gpio-latch-driver.patch b/target/linux/ar71xx/patches-4.9/452-gpio-add-gpio-latch-driver.patch index 5ddf6de92..a56226f09 100644 --- a/target/linux/ar71xx/patches-4.9/452-gpio-add-gpio-latch-driver.patch +++ b/target/linux/ar71xx/patches-4.9/452-gpio-add-gpio-latch-driver.patch @@ -1,6 +1,6 @@ --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig -@@ -1218,4 +1218,9 @@ config GPIO_NXP_74HC153 +@@ -1220,4 +1220,9 @@ config GPIO_NXP_74HC153 Platform driver for NXP 74HC153 Dual 4-input Multiplexer. This provides a GPIO interface supporting input mode only. diff --git a/target/linux/brcm2708/patches-4.9/950-0031-Add-dwc_otg-driver.patch b/target/linux/brcm2708/patches-4.9/950-0031-Add-dwc_otg-driver.patch index 1932e3024..c3862fc07 100644 --- a/target/linux/brcm2708/patches-4.9/950-0031-Add-dwc_otg-driver.patch +++ b/target/linux/brcm2708/patches-4.9/950-0031-Add-dwc_otg-driver.patch @@ -696,7 +696,7 @@ Signed-off-by: Noralf Trønnes } --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c -@@ -5042,7 +5042,7 @@ static void port_event(struct usb_hub *h +@@ -5045,7 +5045,7 @@ static void port_event(struct usb_hub *h if (portchange & USB_PORT_STAT_C_OVERCURRENT) { u16 status = 0, unused; diff --git a/target/linux/generic/backport-4.9/024-3-tcp-tsq-add-shortcut-in-tcp_tasklet_func.patch b/target/linux/generic/backport-4.9/024-3-tcp-tsq-add-shortcut-in-tcp_tasklet_func.patch index d3db74252..249a2ce27 100644 --- a/target/linux/generic/backport-4.9/024-3-tcp-tsq-add-shortcut-in-tcp_tasklet_func.patch +++ b/target/linux/generic/backport-4.9/024-3-tcp-tsq-add-shortcut-in-tcp_tasklet_func.patch @@ -60,7 +60,7 @@ Signed-off-by: David S. Miller nval = cmpxchg(&tp->tsq_flags, oval, nval); if (nval != oval) continue; -@@ -2182,6 +2182,8 @@ static bool tcp_write_xmit(struct sock * +@@ -2183,6 +2183,8 @@ static bool tcp_write_xmit(struct sock * unlikely(tso_fragment(sk, skb, limit, mss_now, gfp))) break; diff --git a/target/linux/generic/backport-4.9/024-5-tcp-tsq-add-a-shortcut-in-tcp_small_queue_check.patch b/target/linux/generic/backport-4.9/024-5-tcp-tsq-add-a-shortcut-in-tcp_small_queue_check.patch index 925d2dcea..463b95534 100644 --- a/target/linux/generic/backport-4.9/024-5-tcp-tsq-add-a-shortcut-in-tcp_small_queue_check.patch +++ b/target/linux/generic/backport-4.9/024-5-tcp-tsq-add-a-shortcut-in-tcp_small_queue_check.patch @@ -19,7 +19,7 @@ Signed-off-by: David S. Miller --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c -@@ -2087,6 +2087,15 @@ static bool tcp_small_queue_check(struct +@@ -2088,6 +2088,15 @@ static bool tcp_small_queue_check(struct limit <<= factor; if (atomic_read(&sk->sk_wmem_alloc) > limit) { diff --git a/target/linux/generic/backport-4.9/024-8-tcp-tsq-move-tsq_flags-close-to-sk_wmem_alloc.patch b/target/linux/generic/backport-4.9/024-8-tcp-tsq-move-tsq_flags-close-to-sk_wmem_alloc.patch index 6604a20fc..8f4c5b2a0 100644 --- a/target/linux/generic/backport-4.9/024-8-tcp-tsq-move-tsq_flags-close-to-sk_wmem_alloc.patch +++ b/target/linux/generic/backport-4.9/024-8-tcp-tsq-move-tsq_flags-close-to-sk_wmem_alloc.patch @@ -114,7 +114,7 @@ Signed-off-by: David S. Miller if (nval != oval) continue; -@@ -2096,7 +2096,7 @@ static bool tcp_small_queue_check(struct +@@ -2097,7 +2097,7 @@ static bool tcp_small_queue_check(struct skb->prev == sk->sk_write_queue.next) return false; @@ -123,7 +123,7 @@ Signed-off-by: David S. Miller /* It is possible TX completion already happened * before we set TSQ_THROTTLED, so we must * test again the condition. -@@ -2194,8 +2194,8 @@ static bool tcp_write_xmit(struct sock * +@@ -2195,8 +2195,8 @@ static bool tcp_write_xmit(struct sock * unlikely(tso_fragment(sk, skb, limit, mss_now, gfp))) break; @@ -134,7 +134,7 @@ Signed-off-by: David S. Miller if (tcp_small_queue_check(sk, skb, 0)) break; -@@ -3508,8 +3508,6 @@ void tcp_send_ack(struct sock *sk) +@@ -3509,8 +3509,6 @@ void tcp_send_ack(struct sock *sk) /* We do not want pure acks influencing TCP Small Queues or fq/pacing * too much. * SKB_TRUESIZE(max(1 .. 66, MAX_TCP_HEADER)) is unfortunately ~784 diff --git a/target/linux/generic/backport-4.9/025-tcp-allow-drivers-to-tweak-TSQ-logic.patch b/target/linux/generic/backport-4.9/025-tcp-allow-drivers-to-tweak-TSQ-logic.patch new file mode 100644 index 000000000..d92ce0747 --- /dev/null +++ b/target/linux/generic/backport-4.9/025-tcp-allow-drivers-to-tweak-TSQ-logic.patch @@ -0,0 +1,85 @@ +From: Eric Dumazet +Date: Sat, 11 Nov 2017 15:54:12 -0800 +Subject: [PATCH] tcp: allow drivers to tweak TSQ logic +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +I had many reports that TSQ logic breaks wifi aggregation. + +Current logic is to allow up to 1 ms of bytes to be queued into qdisc +and drivers queues. + +But Wifi aggregation needs a bigger budget to allow bigger rates to +be discovered by various TCP Congestion Controls algorithms. + +This patch adds an extra socket field, allowing wifi drivers to select +another log scale to derive TCP Small Queue credit from current pacing +rate. + +Initial value is 10, meaning that this patch does not change current +behavior. + +We expect wifi drivers to set this field to smaller values (tests have +been done with values from 6 to 9) + +They would have to use following template : + +if (skb->sk && skb->sk->sk_pacing_shift != MY_PACING_SHIFT) + skb->sk->sk_pacing_shift = MY_PACING_SHIFT; + +Ref: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1670041 +Signed-off-by: Eric Dumazet +Cc: Johannes Berg +Cc: Toke Høiland-Jørgensen +Cc: Kir Kolyshkin +--- +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -260,6 +260,7 @@ struct sock_common { + * @sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4) + * @sk_gso_max_size: Maximum GSO segment size to build + * @sk_gso_max_segs: Maximum number of GSO segments ++ * @sk_pacing_shift: scaling factor for TCP Small Queues + * @sk_lingertime: %SO_LINGER l_linger setting + * @sk_backlog: always used with the per-socket spinlock held + * @sk_callback_lock: used with the callbacks in the end of this struct +@@ -421,6 +422,8 @@ struct sock { + kmemcheck_bitfield_end(flags); + + u16 sk_gso_max_segs; ++#define sk_pacing_shift sk_pacing_shift /* for backport checks */ ++ u8 sk_pacing_shift; + unsigned long sk_lingertime; + struct proto *sk_prot_creator; + rwlock_t sk_callback_lock; +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -2475,6 +2475,7 @@ void sock_init_data(struct socket *sock, + + sk->sk_max_pacing_rate = ~0U; + sk->sk_pacing_rate = ~0U; ++ sk->sk_pacing_shift = 10; + sk->sk_incoming_cpu = -1; + /* + * Before updating sk_refcnt, we must commit prior changes to memory +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -1581,7 +1581,7 @@ u32 tcp_tso_autosize(const struct sock * + { + u32 bytes, segs; + +- bytes = min(sk->sk_pacing_rate >> 10, ++ bytes = min(sk->sk_pacing_rate >> sk->sk_pacing_shift, + sk->sk_gso_max_size - 1 - MAX_TCP_HEADER); + + /* Goal is to send at least one packet per ms, +@@ -2084,7 +2084,7 @@ static bool tcp_small_queue_check(struct + { + unsigned int limit; + +- limit = max(2 * skb->truesize, sk->sk_pacing_rate >> 10); ++ limit = max(2 * skb->truesize, sk->sk_pacing_rate >> sk->sk_pacing_shift); + limit = min_t(u32, limit, sysctl_tcp_limit_output_bytes); + limit <<= factor; + diff --git a/target/linux/generic/backport-4.9/090-net-generalize-napi_complete_done.patch b/target/linux/generic/backport-4.9/090-net-generalize-napi_complete_done.patch index d7b7b4897..d234651fd 100644 --- a/target/linux/generic/backport-4.9/090-net-generalize-napi_complete_done.patch +++ b/target/linux/generic/backport-4.9/090-net-generalize-napi_complete_done.patch @@ -399,7 +399,7 @@ Signed-off-by: David S. Miller /* bnx2x_has_rx_work() reads the status block, --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c -@@ -1768,7 +1768,7 @@ static int bnxt_poll_nitroa0(struct napi +@@ -1774,7 +1774,7 @@ static int bnxt_poll_nitroa0(struct napi } if (!bnxt_has_work(bp, cpr) && rx_pkts < budget) { @@ -803,7 +803,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -2696,11 +2696,9 @@ static int mvneta_poll(struct napi_struc +@@ -2697,11 +2697,9 @@ static int mvneta_poll(struct napi_struc rx_done = mvneta_rx_swbm(pp, budget, &pp->rxqs[rx_queue]); } @@ -1346,7 +1346,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c -@@ -2800,7 +2800,7 @@ static int ath10k_pci_napi_poll(struct n +@@ -2804,7 +2804,7 @@ static int ath10k_pci_napi_poll(struct n done = ath10k_htt_txrx_compl_task(ar, budget); if (done < budget) { diff --git a/target/linux/generic/hack-4.9/214-spidev_h_portability.patch b/target/linux/generic/hack-4.9/214-spidev_h_portability.patch index 23914d633..ad4706c82 100644 --- a/target/linux/generic/hack-4.9/214-spidev_h_portability.patch +++ b/target/linux/generic/hack-4.9/214-spidev_h_portability.patch @@ -13,7 +13,7 @@ Signed-off-by: Felix Fietkau --- a/include/uapi/linux/spi/spidev.h +++ b/include/uapi/linux/spi/spidev.h -@@ -111,7 +111,7 @@ struct spi_ioc_transfer { +@@ -112,7 +112,7 @@ struct spi_ioc_transfer { /* not all platforms use or _IOC_TYPECHECK() ... */ #define SPI_MSGSIZE(N) \ diff --git a/target/linux/generic/hack-4.9/661-use_fq_codel_by_default.patch b/target/linux/generic/hack-4.9/661-use_fq_codel_by_default.patch index 4e7b4ad1d..18a98b3aa 100644 --- a/target/linux/generic/hack-4.9/661-use_fq_codel_by_default.patch +++ b/target/linux/generic/hack-4.9/661-use_fq_codel_by_default.patch @@ -44,7 +44,7 @@ Signed-off-by: Felix Fietkau device, it has to decide which ones to send first, which ones to --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c -@@ -1976,7 +1976,7 @@ static int __init pktsched_init(void) +@@ -1978,7 +1978,7 @@ static int __init pktsched_init(void) return err; } diff --git a/target/linux/generic/hack-4.9/702-phy_add_aneg_done_function.patch b/target/linux/generic/hack-4.9/702-phy_add_aneg_done_function.patch index cf798bc20..8a2b51a4f 100644 --- a/target/linux/generic/hack-4.9/702-phy_add_aneg_done_function.patch +++ b/target/linux/generic/hack-4.9/702-phy_add_aneg_done_function.patch @@ -1,6 +1,6 @@ --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -499,6 +499,12 @@ struct phy_driver { +@@ -495,6 +495,12 @@ struct phy_driver { /* Determines the negotiated speed and duplex */ int (*read_status)(struct phy_device *phydev); diff --git a/target/linux/generic/hack-4.9/710-phy-add-mdio_register_board_info.patch b/target/linux/generic/hack-4.9/710-phy-add-mdio_register_board_info.patch index 838c73789..55607bc6e 100644 --- a/target/linux/generic/hack-4.9/710-phy-add-mdio_register_board_info.patch +++ b/target/linux/generic/hack-4.9/710-phy-add-mdio_register_board_info.patch @@ -50,7 +50,7 @@ phy_device_free(phydev); --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -863,6 +863,23 @@ void mdio_bus_exit(void); +@@ -859,6 +859,23 @@ void mdio_bus_exit(void); extern struct bus_type mdio_bus_type; diff --git a/target/linux/generic/pending-4.9/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch b/target/linux/generic/pending-4.9/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch new file mode 100644 index 000000000..1c5b9c3b2 --- /dev/null +++ b/target/linux/generic/pending-4.9/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch @@ -0,0 +1,56 @@ +From: Felix Fietkau +Date: Sat, 4 Nov 2017 07:40:23 +0100 +Subject: [PATCH] mtd: spi-nor: support limiting 4K sectors support based on + flash size + +Some devices need 4K sectors to be able to deal with small flash chips. +For instance, w25x05 is 64 KiB in size, and without 4K sectors, the +entire chip is just one erase block. +On bigger flash chip sizes, using 4K sectors can significantly slow down +many operations, including using a writable filesystem. There are several +platforms where it makes sense to use a single kernel on both kinds of +devices. + +To support this properly, allow configuring an upper flash chip size +limit for 4K sectors support. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/mtd/spi-nor/Kconfig ++++ b/drivers/mtd/spi-nor/Kconfig +@@ -29,6 +29,17 @@ config MTD_SPI_NOR_USE_4K_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). + ++config MTD_SPI_NOR_USE_4K_SECTORS_LIMIT ++ int "Maximum flash chip size to use 4K sectors on (in KiB)" ++ depends on MTD_SPI_NOR_USE_4K_SECTORS ++ default "4096" ++ help ++ There are many flash chips that support 4K sectors, but are so large ++ that using them significantly slows down writing large amounts of ++ data or using a writable filesystem. ++ Any flash chip larger than the size specified in this option will ++ not use 4K sectors. ++ + config SPI_ATMEL_QUADSPI + tristate "Atmel Quad SPI Controller" + depends on ARCH_AT91 || (ARM && COMPILE_TEST) +--- a/drivers/mtd/spi-nor/spi-nor.c ++++ b/drivers/mtd/spi-nor/spi-nor.c +@@ -1640,10 +1640,12 @@ int spi_nor_scan(struct spi_nor *nor, co + + #ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS + /* prefer "small sector" erase if possible */ +- if (info->flags & SECT_4K) { ++ if ((info->flags & SECT_4K) && (mtd->size <= ++ CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT * 1024)) { + nor->erase_opcode = SPINOR_OP_BE_4K; + mtd->erasesize = 4096; +- } else if (info->flags & SECT_4K_PMC) { ++ } else if ((info->flags & SECT_4K_PMC) && (mtd->size <= ++ CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT * 1024)) { + nor->erase_opcode = SPINOR_OP_BE_4K_PMC; + mtd->erasesize = 4096; + } else diff --git a/target/linux/generic/pending-4.9/616-net_optimize_xfrm_calls.patch b/target/linux/generic/pending-4.9/616-net_optimize_xfrm_calls.patch index e627fa0ca..a147f5f94 100644 --- a/target/linux/generic/pending-4.9/616-net_optimize_xfrm_calls.patch +++ b/target/linux/generic/pending-4.9/616-net_optimize_xfrm_calls.patch @@ -8,7 +8,7 @@ Signed-off-by: Felix Fietkau --- a/net/netfilter/nf_nat_core.c +++ b/net/netfilter/nf_nat_core.c -@@ -95,6 +95,9 @@ int nf_xfrm_me_harder(struct net *net, s +@@ -93,6 +93,9 @@ int nf_xfrm_me_harder(struct net *net, s struct dst_entry *dst; int err; diff --git a/target/linux/generic/pending-4.9/630-packet_socket_type.patch b/target/linux/generic/pending-4.9/630-packet_socket_type.patch index dea2e2ce7..e943a47a8 100644 --- a/target/linux/generic/pending-4.9/630-packet_socket_type.patch +++ b/target/linux/generic/pending-4.9/630-packet_socket_type.patch @@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau #define PACKET_FANOUT_LB 1 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c -@@ -1778,6 +1778,7 @@ static int packet_rcv_spkt(struct sk_buf +@@ -1780,6 +1780,7 @@ static int packet_rcv_spkt(struct sk_buf { struct sock *sk; struct sockaddr_pkt *spkt; @@ -38,7 +38,7 @@ Signed-off-by: Felix Fietkau /* * When we registered the protocol we saved the socket in the data -@@ -1785,6 +1786,7 @@ static int packet_rcv_spkt(struct sk_buf +@@ -1787,6 +1788,7 @@ static int packet_rcv_spkt(struct sk_buf */ sk = pt->af_packet_priv; @@ -46,7 +46,7 @@ Signed-off-by: Felix Fietkau /* * Yank back the headers [hope the device set this -@@ -1797,7 +1799,7 @@ static int packet_rcv_spkt(struct sk_buf +@@ -1799,7 +1801,7 @@ static int packet_rcv_spkt(struct sk_buf * so that this procedure is noop. */ @@ -55,7 +55,7 @@ Signed-off-by: Felix Fietkau goto out; if (!net_eq(dev_net(dev), sock_net(sk))) -@@ -2035,12 +2037,12 @@ static int packet_rcv(struct sk_buff *sk +@@ -2037,12 +2039,12 @@ static int packet_rcv(struct sk_buff *sk unsigned int snaplen, res; bool is_drop_n_account = false; @@ -71,7 +71,7 @@ Signed-off-by: Felix Fietkau if (!net_eq(dev_net(dev), sock_net(sk))) goto drop; -@@ -2166,12 +2168,12 @@ static int tpacket_rcv(struct sk_buff *s +@@ -2168,12 +2170,12 @@ static int tpacket_rcv(struct sk_buff *s BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32); BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48); @@ -87,7 +87,7 @@ Signed-off-by: Felix Fietkau if (!net_eq(dev_net(dev), sock_net(sk))) goto drop; -@@ -3250,6 +3252,7 @@ static int packet_create(struct net *net +@@ -3252,6 +3254,7 @@ static int packet_create(struct net *net mutex_init(&po->pg_vec_lock); po->rollover = NULL; po->prot_hook.func = packet_rcv; @@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau if (sock->type == SOCK_PACKET) po->prot_hook.func = packet_rcv_spkt; -@@ -3836,6 +3839,16 @@ packet_setsockopt(struct socket *sock, i +@@ -3838,6 +3841,16 @@ packet_setsockopt(struct socket *sock, i po->xmit = val ? packet_direct_xmit : dev_queue_xmit; return 0; } @@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau default: return -ENOPROTOOPT; } -@@ -3888,6 +3901,13 @@ static int packet_getsockopt(struct sock +@@ -3891,6 +3904,13 @@ static int packet_getsockopt(struct sock case PACKET_VNET_HDR: val = po->has_vnet_hdr; break; diff --git a/target/linux/generic/pending-4.9/701-phy_extension.patch b/target/linux/generic/pending-4.9/701-phy_extension.patch index 2b9e42405..b480b1d78 100644 --- a/target/linux/generic/pending-4.9/701-phy_extension.patch +++ b/target/linux/generic/pending-4.9/701-phy_extension.patch @@ -62,7 +62,7 @@ Signed-off-by: John Crispin * @phydev: the phy_device struct --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -820,6 +820,7 @@ int phy_ethtool_ksettings_get(struct phy +@@ -816,6 +816,7 @@ int phy_ethtool_ksettings_get(struct phy struct ethtool_link_ksettings *cmd); int phy_ethtool_ksettings_set(struct phy_device *phydev, const struct ethtool_link_ksettings *cmd); diff --git a/target/linux/generic/pending-4.9/703-phy-add-detach-callback-to-struct-phy_driver.patch b/target/linux/generic/pending-4.9/703-phy-add-detach-callback-to-struct-phy_driver.patch index c64c3bea3..7cc39dcb8 100644 --- a/target/linux/generic/pending-4.9/703-phy-add-detach-callback-to-struct-phy_driver.patch +++ b/target/linux/generic/pending-4.9/703-phy-add-detach-callback-to-struct-phy_driver.patch @@ -23,7 +23,7 @@ Signed-off-by: Gabor Juhos phy_suspend(phydev); --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -511,6 +511,12 @@ struct phy_driver { +@@ -507,6 +507,12 @@ struct phy_driver { */ int (*did_interrupt)(struct phy_device *phydev); diff --git a/target/linux/ipq806x/patches-4.9/0017-qcom-ipq4019-add-cpu-operating-points-for-cpufreq-su.patch b/target/linux/ipq806x/patches-4.9/0017-qcom-ipq4019-add-cpu-operating-points-for-cpufreq-su.patch index 5aeb93cdc..7cbd6a455 100644 --- a/target/linux/ipq806x/patches-4.9/0017-qcom-ipq4019-add-cpu-operating-points-for-cpufreq-su.patch +++ b/target/linux/ipq806x/patches-4.9/0017-qcom-ipq4019-add-cpu-operating-points-for-cpufreq-su.patch @@ -45,7 +45,7 @@ Signed-off-by: Matthew McClintock }; cpu@3 { -@@ -81,6 +76,33 @@ +@@ -81,6 +76,29 @@ reg = <0x3>; clocks = <&gcc GCC_APPS_CLK_SRC>; clock-frequency = <0>; @@ -71,10 +71,6 @@ Signed-off-by: Matthew McClintock + }; + opp@666000000 { + opp-hz = /bits/ 64 <666000000>; -+ clock-latency-ns = <256000>; -+ }; -+ opp@717000000 { -+ opp-hz = /bits/ 64 <717000000>; + clock-latency-ns = <256000>; }; }; diff --git a/target/linux/ipq806x/patches-4.9/0018-qcom-ipq4019-turn-on-DMA-for-i2c.patch b/target/linux/ipq806x/patches-4.9/0018-qcom-ipq4019-turn-on-DMA-for-i2c.patch index a580610b2..42bb4a6e3 100644 --- a/target/linux/ipq806x/patches-4.9/0018-qcom-ipq4019-turn-on-DMA-for-i2c.patch +++ b/target/linux/ipq806x/patches-4.9/0018-qcom-ipq4019-turn-on-DMA-for-i2c.patch @@ -12,7 +12,7 @@ Signed-off-by: Matthew McClintock --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -183,6 +183,8 @@ +@@ -179,6 +179,8 @@ clock-names = "iface", "core"; #address-cells = <1>; #size-cells = <0>; diff --git a/target/linux/ipq806x/patches-4.9/0019-qcom-ipq4019-use-correct-clock-for-i2c-bus-0.patch b/target/linux/ipq806x/patches-4.9/0019-qcom-ipq4019-use-correct-clock-for-i2c-bus-0.patch index 64878e2c0..54ee571cb 100644 --- a/target/linux/ipq806x/patches-4.9/0019-qcom-ipq4019-use-correct-clock-for-i2c-bus-0.patch +++ b/target/linux/ipq806x/patches-4.9/0019-qcom-ipq4019-use-correct-clock-for-i2c-bus-0.patch @@ -17,7 +17,7 @@ Signed-off-by: Matthew McClintock --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -179,7 +179,7 @@ +@@ -175,7 +175,7 @@ reg = <0x78b7000 0x6000>; interrupts = ; clocks = <&gcc GCC_BLSP1_AHB_CLK>, diff --git a/target/linux/ipq806x/patches-4.9/0020-qcom-ipq4019-enable-DMA-for-spi.patch b/target/linux/ipq806x/patches-4.9/0020-qcom-ipq4019-enable-DMA-for-spi.patch index b5a533502..c1fa5c729 100644 --- a/target/linux/ipq806x/patches-4.9/0020-qcom-ipq4019-enable-DMA-for-spi.patch +++ b/target/linux/ipq806x/patches-4.9/0020-qcom-ipq4019-enable-DMA-for-spi.patch @@ -12,7 +12,7 @@ Signed-off-by: Matthew McClintock --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -171,6 +171,8 @@ +@@ -167,6 +167,8 @@ clock-names = "core", "iface"; #address-cells = <1>; #size-cells = <0>; diff --git a/target/linux/ipq806x/patches-4.9/0022-dts-ipq4019-support-ARMv7-PMU.patch b/target/linux/ipq806x/patches-4.9/0022-dts-ipq4019-support-ARMv7-PMU.patch index 2acfdcf29..c427d66ef 100644 --- a/target/linux/ipq806x/patches-4.9/0022-dts-ipq4019-support-ARMv7-PMU.patch +++ b/target/linux/ipq806x/patches-4.9/0022-dts-ipq4019-support-ARMv7-PMU.patch @@ -13,7 +13,7 @@ Signed-off-by: Matthew McClintock --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -112,6 +112,12 @@ +@@ -108,6 +108,12 @@ IRQ_TYPE_LEVEL_HIGH)>; }; diff --git a/target/linux/ipq806x/patches-4.9/0065-arm-override-compiler-flags.patch b/target/linux/ipq806x/patches-4.9/0065-arm-override-compiler-flags.patch index dd40f1371..e5af7ffa2 100644 --- a/target/linux/ipq806x/patches-4.9/0065-arm-override-compiler-flags.patch +++ b/target/linux/ipq806x/patches-4.9/0065-arm-override-compiler-flags.patch @@ -15,7 +15,7 @@ Signed-off-by: John Crispin # testing for a specific architecture or later rather impossible. arch-$(CONFIG_CPU_32v7M) =-D__LINUX_ARM_ARCH__=7 -march=armv7-m -Wa,-march=armv7-m -arch-$(CONFIG_CPU_32v7) =-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a) -+arch-$(CONFIG_CPU_32v7) =-D__LINUX_ARM_ARCH__=7 -mcpu=cortex-a15 -mtune=cortex-a15 ++arch-$(CONFIG_CPU_32v7) =-D__LINUX_ARM_ARCH__=7 -mcpu=cortex-a15 arch-$(CONFIG_CPU_32v6) =-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) # Only override the compiler option if ARMv6. The ARMv6K extensions are # always available in ARMv7 diff --git a/target/linux/ipq806x/patches-4.9/0069-arm-boot-add-dts-files.patch b/target/linux/ipq806x/patches-4.9/0069-arm-boot-add-dts-files.patch index ea9e67278..bab280878 100644 --- a/target/linux/ipq806x/patches-4.9/0069-arm-boot-add-dts-files.patch +++ b/target/linux/ipq806x/patches-4.9/0069-arm-boot-add-dts-files.patch @@ -5,19 +5,18 @@ Subject: [PATCH 69/69] arm: boot: add dts files Signed-off-by: John Crispin --- - arch/arm/boot/dts/Makefile | 9 ++++++++ - 1 file changed, 9 insertions(+) + arch/arm/boot/dts/Makefile | 8 ++++++++ + 1 file changed, 8 insertions(+) --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile -@@ -618,7 +618,19 @@ dtb-$(CONFIG_ARCH_QCOM) += \ +@@ -618,7 +618,18 @@ dtb-$(CONFIG_ARCH_QCOM) += \ qcom-apq8084-mtp.dtb \ qcom-ipq4019-ap.dk01.1-c1.dtb \ qcom-ipq4019-ap.dk04.1-c1.dtb \ + qcom-ipq4019-fritz4040.dtb \ + qcom-ipq4019-nbg6617.dtb \ + qcom-ipq4019-rt-ac58u.dtb \ -+ qcom-ipq4019-rt-acrh17.dtb \ qcom-ipq8064-ap148.dtb \ + qcom-ipq8064-c2600.dtb \ + qcom-ipq8064-d7800.dtb \ diff --git a/target/linux/ipq806x/patches-4.9/131-pinctrl-qcom-ipq4019-add-remaining-pin-definitions.patch b/target/linux/ipq806x/patches-4.9/131-pinctrl-qcom-ipq4019-add-remaining-pin-definitions.patch deleted file mode 100644 index f3ffc2e2c..000000000 --- a/target/linux/ipq806x/patches-4.9/131-pinctrl-qcom-ipq4019-add-remaining-pin-definitions.patch +++ /dev/null @@ -1,516 +0,0 @@ -From 941e3869bdeddb2bebcc52ebfd57efe014887bc6 Mon Sep 17 00:00:00 2001 -Message-Id: <941e3869bdeddb2bebcc52ebfd57efe014887bc6.1500038134.git.chunkeey@googlemail.com> -In-Reply-To: -References: -From: Ram Chandra Jangir -Date: Wed, 10 May 2017 12:51:51 +0200 -Subject: [PATCH v3 2/3] pinctrl: qcom: ipq4019: add most remaining pin - definitions -To: linux-gpio@vger.kernel.org, - devicetree@vger.kernel.org -Cc: Linus Walleij , - Rob Herring , - Mark Rutland - -This patch adds multiple pinctrl functions and mappings -for SDIO, NAND, I2S, WIFI, PCIE, LEDs, etc... that have -been missing from the current minimal version. - -This patch has been updated from the original version -that was posted by Ram Chandra Jangir on the LEDE-DEV ML: -. A short -summary of the changes are documented in the device-tree -patch of this series: -"dt-bindings: pinctrl: add most other IPQ4019 pin functions and groups" - -Cc: Bjorn Andersson -Cc: John Crispin -Signed-off-by: Ram Chandra Jangir -Signed-off-by: Christian Lamparter ---- - drivers/pinctrl/qcom/pinctrl-ipq4019.c | 431 ++++++++++++++++++++++++++------- - 1 file changed, 346 insertions(+), 85 deletions(-) - -diff --git a/drivers/pinctrl/qcom/pinctrl-ipq4019.c b/drivers/pinctrl/qcom/pinctrl-ipq4019.c -index 743d1f458205..9e7f23d29cda 100644 ---- a/drivers/pinctrl/qcom/pinctrl-ipq4019.c -+++ b/drivers/pinctrl/qcom/pinctrl-ipq4019.c -@@ -277,12 +277,49 @@ DECLARE_QCA_GPIO_PINS(99); - - enum ipq4019_functions { - qca_mux_gpio, -- qca_mux_blsp_uart1, -+ qca_mux_aud_pin, -+ qca_mux_audio_pwm, - qca_mux_blsp_i2c0, - qca_mux_blsp_i2c1, -- qca_mux_blsp_uart0, -- qca_mux_blsp_spi1, - qca_mux_blsp_spi0, -+ qca_mux_blsp_spi1, -+ qca_mux_blsp_uart0, -+ qca_mux_blsp_uart1, -+ qca_mux_chip_rst, -+ qca_mux_i2s_rx, -+ qca_mux_i2s_spdif_in, -+ qca_mux_i2s_spdif_out, -+ qca_mux_i2s_td, -+ qca_mux_i2s_tx, -+ qca_mux_jtag, -+ qca_mux_led0, -+ qca_mux_led1, -+ qca_mux_led2, -+ qca_mux_led3, -+ qca_mux_led4, -+ qca_mux_led5, -+ qca_mux_led6, -+ qca_mux_led7, -+ qca_mux_led8, -+ qca_mux_led9, -+ qca_mux_led10, -+ qca_mux_led11, -+ qca_mux_mdc, -+ qca_mux_mdio, -+ qca_mux_pcie, -+ qca_mux_pmu, -+ qca_mux_prng_rosc, -+ qca_mux_qpic, -+ qca_mux_rgmii, -+ qca_mux_rmii, -+ qca_mux_sdio, -+ qca_mux_smart0, -+ qca_mux_smart1, -+ qca_mux_smart2, -+ qca_mux_smart3, -+ qca_mux_tm, -+ qca_mux_wifi0, -+ qca_mux_wifi1, - qca_mux_NA, - }; - -@@ -303,108 +340,331 @@ static const char * const gpio_groups[] = { - "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98", - "gpio99", - }; -- --static const char * const blsp_uart1_groups[] = { -- "gpio8", "gpio9", "gpio10", "gpio11", -+static const char * const aud_pin_groups[] = { -+ "gpio48", "gpio49", "gpio50", "gpio51", -+}; -+static const char * const audio_pwm_groups[] = { -+ "gpio30", "gpio31", "gpio32", "gpio33", "gpio64", "gpio65", "gpio66", -+ "gpio67", - }; - static const char * const blsp_i2c0_groups[] = { - "gpio10", "gpio11", "gpio20", "gpio21", "gpio58", "gpio59", - }; --static const char * const blsp_spi0_groups[] = { -- "gpio12", "gpio13", "gpio14", "gpio15", "gpio45", -- "gpio54", "gpio55", "gpio56", "gpio57", --}; - static const char * const blsp_i2c1_groups[] = { - "gpio12", "gpio13", "gpio34", "gpio35", - }; --static const char * const blsp_uart0_groups[] = { -- "gpio16", "gpio17", "gpio60", "gpio61", -+static const char * const blsp_spi0_groups[] = { -+ "gpio12", "gpio13", "gpio14", "gpio15", "gpio45", "gpio54", "gpio55", -+ "gpio56", "gpio57", - }; - static const char * const blsp_spi1_groups[] = { - "gpio44", "gpio45", "gpio46", "gpio47", - }; -+static const char * const blsp_uart0_groups[] = { -+ "gpio16", "gpio17", "gpio60", "gpio61", -+}; -+static const char * const blsp_uart1_groups[] = { -+ "gpio8", "gpio9", "gpio10", "gpio11", -+}; -+static const char * const chip_rst_groups[] = { -+ "gpio62", -+}; -+static const char * const i2s_rx_groups[] = { -+ "gpio0", "gpio1", "gpio2", "gpio20", "gpio21", "gpio22", "gpio23", -+ "gpio58", "gpio60", "gpio61", "gpio63", -+}; -+static const char * const i2s_spdif_in_groups[] = { -+ "gpio34", "gpio59", "gpio63", -+}; -+static const char * const i2s_spdif_out_groups[] = { -+ "gpio35", "gpio62", "gpio63", -+}; -+static const char * const i2s_td_groups[] = { -+ "gpio27", "gpio28", "gpio29", "gpio54", "gpio55", "gpio56", "gpio63", -+}; -+static const char * const i2s_tx_groups[] = { -+ "gpio24", "gpio25", "gpio26", "gpio52", "gpio53", "gpio57", "gpio60", -+ "gpio61", -+}; -+static const char * const jtag_groups[] = { -+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", -+}; -+static const char * const led0_groups[] = { -+ "gpio16", "gpio36", "gpio60", -+}; -+static const char * const led1_groups[] = { -+ "gpio17", "gpio37", "gpio61", -+}; -+static const char * const led2_groups[] = { -+ "gpio36", "gpio38", "gpio58", -+}; -+static const char * const led3_groups[] = { -+ "gpio39", -+}; -+static const char * const led4_groups[] = { -+ "gpio40", -+}; -+static const char * const led5_groups[] = { -+ "gpio44", -+}; -+static const char * const led6_groups[] = { -+ "gpio45", -+}; -+static const char * const led7_groups[] = { -+ "gpio46", -+}; -+static const char * const led8_groups[] = { -+ "gpio47", -+}; -+static const char * const led9_groups[] = { -+ "gpio48", -+}; -+static const char * const led10_groups[] = { -+ "gpio49", -+}; -+static const char * const led11_groups[] = { -+ "gpio50", -+}; -+static const char * const mdc_groups[] = { -+ "gpio7", "gpio52", -+}; -+static const char * const mdio_groups[] = { -+ "gpio6", "gpio53", -+}; -+static const char * const pcie_groups[] = { -+ "gpio39", "gpio52", -+}; -+static const char * const pmu_groups[] = { -+ "gpio54", "gpio55", -+}; -+static const char * const prng_rosc_groups[] = { -+ "gpio53", -+}; -+static const char * const qpic_groups[] = { -+ "gpio52", "gpio53", "gpio54", "gpio55", "gpio56", "gpio57", "gpio58", -+ "gpio59", "gpio60", "gpio61", "gpio62", "gpio63", "gpio64", "gpio65", -+ "gpio66", "gpio67", "gpio68", "gpio69", -+}; -+static const char * const rgmii_groups[] = { -+ "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", -+ "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", -+}; -+static const char * const rmii_groups[] = { -+ "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", -+ "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49", -+ "gpio50", "gpio51", -+}; -+static const char * const sdio_groups[] = { -+ "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29", -+ "gpio30", "gpio31", "gpio32", -+}; -+static const char * const smart0_groups[] = { -+ "gpio0", "gpio1", "gpio2", "gpio5", "gpio44", "gpio45", "gpio46", -+ "gpio47", -+}; -+static const char * const smart1_groups[] = { -+ "gpio8", "gpio9", "gpio16", "gpio17", "gpio58", "gpio59", "gpio60", -+ "gpio61", -+}; -+static const char * const smart2_groups[] = { -+ "gpio40", "gpio41", "gpio48", "gpio49", -+}; -+static const char * const smart3_groups[] = { -+ "gpio58", "gpio59", "gpio60", "gpio61", -+}; -+static const char * const tm_groups[] = { -+ "gpio52", "gpio53", "gpio54", "gpio55", "gpio56", "gpio57", "gpio58", -+ "gpio59", "gpio60", "gpio61", "gpio62", "gpio63", -+}; -+static const char * const wifi0_groups[] = { -+ "gpio37", "gpio40", "gpio41", "gpio42", "gpio50", "gpio51", "gpio52", -+ "gpio53", "gpio56", "gpio57", "gpio58", "gpio98", -+}; -+static const char * const wifi1_groups[] = { -+ "gpio37", "gpio40", "gpio41", "gpio43", "gpio50", "gpio51", "gpio52", -+ "gpio53", "gpio56", "gpio57", "gpio58", "gpio98", -+}; - - static const struct msm_function ipq4019_functions[] = { -- FUNCTION(gpio), -- FUNCTION(blsp_uart1), -+ FUNCTION(aud_pin), -+ FUNCTION(audio_pwm), - FUNCTION(blsp_i2c0), - FUNCTION(blsp_i2c1), -- FUNCTION(blsp_uart0), -- FUNCTION(blsp_spi1), - FUNCTION(blsp_spi0), -+ FUNCTION(blsp_spi1), -+ FUNCTION(blsp_uart0), -+ FUNCTION(blsp_uart1), -+ FUNCTION(chip_rst), -+ FUNCTION(gpio), -+ FUNCTION(i2s_rx), -+ FUNCTION(i2s_spdif_in), -+ FUNCTION(i2s_spdif_out), -+ FUNCTION(i2s_td), -+ FUNCTION(i2s_tx), -+ FUNCTION(jtag), -+ FUNCTION(led0), -+ FUNCTION(led1), -+ FUNCTION(led2), -+ FUNCTION(led3), -+ FUNCTION(led4), -+ FUNCTION(led5), -+ FUNCTION(led6), -+ FUNCTION(led7), -+ FUNCTION(led8), -+ FUNCTION(led9), -+ FUNCTION(led10), -+ FUNCTION(led11), -+ FUNCTION(mdc), -+ FUNCTION(mdio), -+ FUNCTION(pcie), -+ FUNCTION(pmu), -+ FUNCTION(prng_rosc), -+ FUNCTION(qpic), -+ FUNCTION(rgmii), -+ FUNCTION(rmii), -+ FUNCTION(sdio), -+ FUNCTION(smart0), -+ FUNCTION(smart1), -+ FUNCTION(smart2), -+ FUNCTION(smart3), -+ FUNCTION(tm), -+ FUNCTION(wifi0), -+ FUNCTION(wifi1), - }; - - static const struct msm_pingroup ipq4019_groups[] = { -- PINGROUP(0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(5, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(6, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(7, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(8, blsp_uart1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(9, blsp_uart1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(10, blsp_uart1, NA, NA, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(11, blsp_uart1, NA, NA, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(12, blsp_spi0, blsp_i2c1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(13, blsp_spi0, blsp_i2c1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(14, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(15, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(16, blsp_uart0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(17, blsp_uart0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -+ PINGROUP(0, jtag, smart0, i2s_rx, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(1, jtag, smart0, i2s_rx, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(2, jtag, smart0, i2s_rx, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(3, jtag, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -+ PINGROUP(4, jtag, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -+ PINGROUP(5, jtag, smart0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA), -+ PINGROUP(6, mdio, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -+ PINGROUP(7, mdc, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -+ PINGROUP(8, blsp_uart1, NA, NA, smart1, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(9, blsp_uart1, NA, NA, smart1, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(10, blsp_uart1, NA, NA, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(11, blsp_uart1, NA, NA, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(12, blsp_spi0, blsp_i2c1, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(13, blsp_spi0, blsp_i2c1, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(14, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA), -+ PINGROUP(15, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA), -+ PINGROUP(16, blsp_uart0, led0, smart1, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(17, blsp_uart0, led1, smart1, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), - PINGROUP(18, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), - PINGROUP(19, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(20, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(21, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(22, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(23, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(24, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(25, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(26, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(27, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(28, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(29, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(30, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(31, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(32, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(33, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(34, blsp_i2c1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(35, blsp_i2c1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(36, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(37, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(38, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(39, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(40, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(41, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(42, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(43, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(44, NA, blsp_spi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(45, NA, blsp_spi1, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(46, NA, blsp_spi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(47, NA, blsp_spi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(48, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(49, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(50, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(51, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(52, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(53, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(54, NA, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(55, NA, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(56, NA, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(57, NA, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(58, NA, NA, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(59, NA, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(60, NA, blsp_uart0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(61, NA, blsp_uart0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(62, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(63, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(64, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(65, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(66, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(67, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(68, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(69, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -+ PINGROUP(20, blsp_i2c0, i2s_rx, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(21, blsp_i2c0, i2s_rx, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(22, rgmii, i2s_rx, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA), -+ PINGROUP(23, sdio, rgmii, i2s_rx, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(24, sdio, rgmii, i2s_tx, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(25, sdio, rgmii, i2s_tx, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(26, sdio, rgmii, i2s_tx, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(27, sdio, rgmii, i2s_td, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(28, sdio, rgmii, i2s_td, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(29, sdio, rgmii, i2s_td, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(30, sdio, rgmii, audio_pwm, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(31, sdio, rgmii, audio_pwm, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(32, sdio, rgmii, audio_pwm, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(33, rgmii, audio_pwm, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(34, blsp_i2c1, i2s_spdif_in, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA, NA), -+ PINGROUP(35, blsp_i2c1, i2s_spdif_out, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA, NA), -+ PINGROUP(36, rmii, led2, led0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA), -+ PINGROUP(37, rmii, wifi0, wifi1, led1, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(38, rmii, led2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA), -+ PINGROUP(39, rmii, pcie, led3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA), -+ PINGROUP(40, rmii, wifi0, wifi1, smart2, led4, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(41, rmii, wifi0, wifi1, smart2, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(42, rmii, wifi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA), -+ PINGROUP(43, rmii, wifi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA), -+ PINGROUP(44, rmii, blsp_spi1, smart0, led5, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(45, rmii, blsp_spi1, blsp_spi0, smart0, led6, NA, NA, NA, NA, -+ NA, NA, NA, NA, NA), -+ PINGROUP(46, rmii, blsp_spi1, smart0, led7, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(47, rmii, blsp_spi1, smart0, led8, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(48, rmii, aud_pin, smart2, led9, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(49, rmii, aud_pin, smart2, led10, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(50, rmii, aud_pin, wifi0, wifi1, led11, NA, NA, NA, NA, NA, -+ NA, NA, NA, NA), -+ PINGROUP(51, rmii, aud_pin, wifi0, wifi1, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA, NA), -+ PINGROUP(52, qpic, mdc, pcie, i2s_tx, NA, NA, NA, tm, wifi0, wifi1, NA, -+ NA, NA, NA), -+ PINGROUP(53, qpic, mdio, i2s_tx, prng_rosc, NA, tm, wifi0, wifi1, NA, -+ NA, NA, NA, NA, NA), -+ PINGROUP(54, qpic, blsp_spi0, i2s_td, NA, pmu, NA, NA, NA, tm, NA, NA, -+ NA, NA, NA), -+ PINGROUP(55, qpic, blsp_spi0, i2s_td, NA, pmu, NA, NA, NA, tm, NA, NA, -+ NA, NA, NA), -+ PINGROUP(56, qpic, blsp_spi0, i2s_td, NA, NA, tm, wifi0, wifi1, NA, NA, -+ NA, NA, NA, NA), -+ PINGROUP(57, qpic, blsp_spi0, i2s_tx, NA, NA, tm, wifi0, wifi1, NA, NA, -+ NA, NA, NA, NA), -+ PINGROUP(58, qpic, led2, blsp_i2c0, smart3, smart1, i2s_rx, NA, NA, tm, -+ wifi0, wifi1, NA, NA, NA), -+ PINGROUP(59, qpic, blsp_i2c0, smart3, smart1, i2s_spdif_in, NA, NA, NA, -+ NA, NA, tm, NA, NA, NA), -+ PINGROUP(60, qpic, blsp_uart0, smart1, smart3, led0, i2s_tx, i2s_rx, -+ NA, NA, NA, NA, NA, tm, NA), -+ PINGROUP(61, qpic, blsp_uart0, smart1, smart3, led1, i2s_tx, i2s_rx, -+ NA, NA, NA, NA, NA, tm, NA), -+ PINGROUP(62, qpic, chip_rst, NA, NA, i2s_spdif_out, NA, NA, NA, NA, NA, -+ tm, NA, NA, NA), -+ PINGROUP(63, qpic, NA, NA, NA, i2s_td, i2s_rx, i2s_spdif_out, -+ i2s_spdif_in, NA, NA, NA, NA, tm, NA), -+ PINGROUP(64, qpic, audio_pwm, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(65, qpic, audio_pwm, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(66, qpic, audio_pwm, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(67, qpic, audio_pwm, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA, NA), -+ PINGROUP(68, qpic, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -+ PINGROUP(69, qpic, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), - PINGROUP(70, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), - PINGROUP(71, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), - PINGROUP(72, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -@@ -433,7 +693,8 @@ static const struct msm_pingroup ipq4019_groups[] = { - PINGROUP(95, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), - PINGROUP(96, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), - PINGROUP(97, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -- PINGROUP(98, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), -+ PINGROUP(98, wifi0, wifi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, -+ NA), - PINGROUP(99, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), - }; - --- -2.13.2 - diff --git a/target/linux/ipq806x/patches-4.9/132-pinctrl-qcom-add-support-to-configure-ipq40xx-GPIO_P.patch b/target/linux/ipq806x/patches-4.9/132-pinctrl-qcom-add-support-to-configure-ipq40xx-GPIO_P.patch deleted file mode 100644 index f05ea750b..000000000 --- a/target/linux/ipq806x/patches-4.9/132-pinctrl-qcom-add-support-to-configure-ipq40xx-GPIO_P.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 895bbe5061fe2a6825503f57263a4eff9bb78a3c Mon Sep 17 00:00:00 2001 -Message-Id: <895bbe5061fe2a6825503f57263a4eff9bb78a3c.1500038134.git.chunkeey@googlemail.com> -In-Reply-To: <941e3869bdeddb2bebcc52ebfd57efe014887bc6.1500038134.git.chunkeey@googlemail.com> -References: - <941e3869bdeddb2bebcc52ebfd57efe014887bc6.1500038134.git.chunkeey@googlemail.com> -From: Ram Chandra Jangir -Date: Sun, 4 Jun 2017 21:38:21 +0200 -Subject: [PATCH v3 3/3] pinctrl: msm: add support to configure ipq40xx - GPIO_PULL bits -To: linux-gpio@vger.kernel.org, - devicetree@vger.kernel.org -Cc: Linus Walleij , - Rob Herring , - Mark Rutland - -GPIO_PULL bits configurations in TLMM_GPIO_CFG register -differs for IPQ40xx from rest of the other qcom SoCs. -As it does not support the keeper state and therefore can't -support bias-bus-hold property. - -This patch adds a pull_no_keeper setting which configures the -msm_gpio_pull bits for ipq40xx. This is required to fix the -proper configurations of gpio-pull bits for nand pins mux. - -IPQ40xx SoC: -2'b10: Internal pull up enable. -2'b11: Unsupport - -For other SoC's: -2'b10: Keeper -2'b11: Pull-Up - -Note: Due to pull_no_keeper length, all kerneldoc entries -in the msm_pinctrl_soc_data struct had to be realigned. - -Reviewed-by: Bjorn Andersson -Signed-off-by: Ram Chandra Jangir -Signed-off-by: Christian Lamparter ---- - drivers/pinctrl/qcom/pinctrl-ipq4019.c | 1 + - drivers/pinctrl/qcom/pinctrl-msm.c | 25 +++++++++++++++++++------ - drivers/pinctrl/qcom/pinctrl-msm.h | 16 +++++++++------- - 3 files changed, 29 insertions(+), 13 deletions(-) - -diff --git a/drivers/pinctrl/qcom/pinctrl-ipq4019.c b/drivers/pinctrl/qcom/pinctrl-ipq4019.c -index 9e7f23d29cda..1979b14b6fc3 100644 ---- a/drivers/pinctrl/qcom/pinctrl-ipq4019.c -+++ b/drivers/pinctrl/qcom/pinctrl-ipq4019.c -@@ -706,6 +706,7 @@ static const struct msm_pinctrl_soc_data ipq4019_pinctrl = { - .groups = ipq4019_groups, - .ngroups = ARRAY_SIZE(ipq4019_groups), - .ngpios = 100, -+ .pull_no_keeper = true, - }; - - static int ipq4019_pinctrl_probe(struct platform_device *pdev) -diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c -index 273badd92561..e5e27d79f5ef 100644 ---- a/drivers/pinctrl/qcom/pinctrl-msm.c -+++ b/drivers/pinctrl/qcom/pinctrl-msm.c -@@ -202,10 +202,11 @@ static int msm_config_reg(struct msm_pinctrl *pctrl, - return 0; - } - --#define MSM_NO_PULL 0 --#define MSM_PULL_DOWN 1 --#define MSM_KEEPER 2 --#define MSM_PULL_UP 3 -+#define MSM_NO_PULL 0 -+#define MSM_PULL_DOWN 1 -+#define MSM_KEEPER 2 -+#define MSM_PULL_UP_NO_KEEPER 2 -+#define MSM_PULL_UP 3 - - static unsigned msm_regval_to_drive(u32 val) - { -@@ -243,10 +244,16 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev, - arg = arg == MSM_PULL_DOWN; - break; - case PIN_CONFIG_BIAS_BUS_HOLD: -+ if (pctrl->soc->pull_no_keeper) -+ return -ENOTSUPP; -+ - arg = arg == MSM_KEEPER; - break; - case PIN_CONFIG_BIAS_PULL_UP: -- arg = arg == MSM_PULL_UP; -+ if (pctrl->soc->pull_no_keeper) -+ arg = arg == MSM_PULL_UP_NO_KEEPER; -+ else -+ arg = arg == MSM_PULL_UP; - break; - case PIN_CONFIG_DRIVE_STRENGTH: - arg = msm_regval_to_drive(arg); -@@ -309,10 +316,16 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev, - arg = MSM_PULL_DOWN; - break; - case PIN_CONFIG_BIAS_BUS_HOLD: -+ if (pctrl->soc->pull_no_keeper) -+ return -ENOTSUPP; -+ - arg = MSM_KEEPER; - break; - case PIN_CONFIG_BIAS_PULL_UP: -- arg = MSM_PULL_UP; -+ if (pctrl->soc->pull_no_keeper) -+ arg = MSM_PULL_UP_NO_KEEPER; -+ else -+ arg = MSM_PULL_UP; - break; - case PIN_CONFIG_DRIVE_STRENGTH: - /* Check for invalid values */ -diff --git a/drivers/pinctrl/qcom/pinctrl-msm.h b/drivers/pinctrl/qcom/pinctrl-msm.h -index 54fdd04ce9d5..9b9feea540ff 100644 ---- a/drivers/pinctrl/qcom/pinctrl-msm.h -+++ b/drivers/pinctrl/qcom/pinctrl-msm.h -@@ -99,13 +99,14 @@ struct msm_pingroup { - - /** - * struct msm_pinctrl_soc_data - Qualcomm pin controller driver configuration -- * @pins: An array describing all pins the pin controller affects. -- * @npins: The number of entries in @pins. -- * @functions: An array describing all mux functions the SoC supports. -- * @nfunctions: The number of entries in @functions. -- * @groups: An array describing all pin groups the pin SoC supports. -- * @ngroups: The numbmer of entries in @groups. -- * @ngpio: The number of pingroups the driver should expose as GPIOs. -+ * @pins: An array describing all pins the pin controller affects. -+ * @npins: The number of entries in @pins. -+ * @functions: An array describing all mux functions the SoC supports. -+ * @nfunctions: The number of entries in @functions. -+ * @groups: An array describing all pin groups the pin SoC supports. -+ * @ngroups: The numbmer of entries in @groups. -+ * @ngpio: The number of pingroups the driver should expose as GPIOs. -+ * @pull_no_keeper: The SoC does not support keeper bias. - */ - struct msm_pinctrl_soc_data { - const struct pinctrl_pin_desc *pins; -@@ -115,6 +116,7 @@ struct msm_pinctrl_soc_data { - const struct msm_pingroup *groups; - unsigned ngroups; - unsigned ngpios; -+ bool pull_no_keeper; - }; - - int msm_pinctrl_probe(struct platform_device *pdev, --- -2.13.2 - diff --git a/target/linux/ipq806x/patches-4.9/140-qcom-ipq4019-fix-i2c_0-node.patch b/target/linux/ipq806x/patches-4.9/140-qcom-ipq4019-fix-i2c_0-node.patch deleted file mode 100644 index 041d8961d..000000000 --- a/target/linux/ipq806x/patches-4.9/140-qcom-ipq4019-fix-i2c_0-node.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 830a63791185f4daaecb8d1102c4ee3c9210c03c Mon Sep 17 00:00:00 2001 -From: Christian Lamparter -Date: Mon, 1 May 2017 13:42:41 +0200 -Subject: [PATCH 1/2] qcom: ipq4019: fix i2c_0 node - -This patch fixes two typos in the i2c_0 node for the ipq4019. -The register size is just 0x600. The core clock is -GCC_BLSP1_QUP1_I2C_APPS_CLK. GCC_BLSP1_QUP2_I2C_APPS_CLK is -used by the second i2c. - -Fixes: e76b4284b520ba3 ("qcom: ipq4019: add i2c node to ipq4019 SoC and DK01 device tree") - -Signed-off-by: Christian Lamparter ---- - arch/arm/boot/dts/qcom-ipq4019.dtsi | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/arm/boot/dts/qcom-ipq4019.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -184,7 +184,7 @@ - - i2c_0: i2c@78b7000 { - compatible = "qcom,i2c-qup-v2.2.1"; -- reg = <0x78b7000 0x6000>; -+ reg = <0x78b7000 0x600>; - interrupts = ; - clocks = <&gcc GCC_BLSP1_AHB_CLK>, - <&gcc GCC_BLSP1_QUP1_I2C_APPS_CLK>; diff --git a/target/linux/ipq806x/patches-4.9/141-qcom-ipq4019-add-second-i2c.patch b/target/linux/ipq806x/patches-4.9/141-qcom-ipq4019-add-second-i2c.patch deleted file mode 100644 index 5f98cc909..000000000 --- a/target/linux/ipq806x/patches-4.9/141-qcom-ipq4019-add-second-i2c.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 5110346bcc17b037edd5b0193f31ad046e6242db Mon Sep 17 00:00:00 2001 -From: Christian Lamparter -Date: Mon, 1 May 2017 13:53:07 +0200 -Subject: [PATCH 2/2] qcom: ipq4019: add second i2c - -This patch adds the second i2c block to the IPQ4019 platform. -The second i2c has been successfully tested on the -Cisco Meraki MR33. - -Cc: Chris Blake -Cc: Matthew McClintock -Signed-off-by: Christian Lamparter ---- - arch/arm/boot/dts/qcom-ipq4019.dtsi | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - ---- a/arch/arm/boot/dts/qcom-ipq4019.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -26,6 +26,7 @@ - aliases { - spi0 = &spi_0; - i2c0 = &i2c_0; -+ i2c1 = &i2c_1; - }; - - cpus { -@@ -196,6 +197,19 @@ - status = "disabled"; - }; - -+ i2c_1: i2c@78b8000 { -+ compatible = "qcom,i2c-qup-v2.2.1"; -+ reg = <0x78b8000 0x600>; -+ interrupts = ; -+ clocks = <&gcc GCC_BLSP1_AHB_CLK>, -+ <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>; -+ clock-names = "iface", "core"; -+ dmas = <&blsp_dma 11>, <&blsp_dma 10>; -+ dma-names = "rx", "tx"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; - - cryptobam: dma@8e04000 { - compatible = "qcom,bam-v1.7.0"; diff --git a/target/linux/ipq806x/patches-4.9/305-qcom-ipq4019-use-v2-of-the-kpss-bringup-mechanism.patch b/target/linux/ipq806x/patches-4.9/305-qcom-ipq4019-use-v2-of-the-kpss-bringup-mechanism.patch index d34f5d1f9..560eee7d2 100644 --- a/target/linux/ipq806x/patches-4.9/305-qcom-ipq4019-use-v2-of-the-kpss-bringup-mechanism.patch +++ b/target/linux/ipq806x/patches-4.9/305-qcom-ipq4019-use-v2-of-the-kpss-bringup-mechanism.patch @@ -17,7 +17,7 @@ Changes: --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -35,19 +35,27 @@ +@@ -34,19 +34,27 @@ cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a7"; @@ -47,7 +47,7 @@ Changes: qcom,acc = <&acc1>; qcom,saw = <&saw1>; reg = <0x1>; -@@ -59,7 +67,8 @@ +@@ -58,7 +66,8 @@ cpu@2 { device_type = "cpu"; compatible = "arm,cortex-a7"; @@ -57,7 +57,7 @@ Changes: qcom,acc = <&acc2>; qcom,saw = <&saw2>; reg = <0x2>; -@@ -71,7 +80,8 @@ +@@ -70,7 +79,8 @@ cpu@3 { device_type = "cpu"; compatible = "arm,cortex-a7"; @@ -67,7 +67,7 @@ Changes: qcom,acc = <&acc3>; qcom,saw = <&saw3>; reg = <0x3>; -@@ -236,22 +246,22 @@ +@@ -218,22 +228,22 @@ }; acc0: clock-controller@b088000 { @@ -94,7 +94,7 @@ Changes: reg = <0x0b0b8000 0x1000>, <0xb008000 0x1000>; }; -@@ -279,6 +289,12 @@ +@@ -261,6 +271,12 @@ regulator; }; diff --git a/target/linux/ipq806x/patches-4.9/306-qcom-ipq4019-add-USB-nodes-to-ipq4019-SoC-device-tre.patch b/target/linux/ipq806x/patches-4.9/306-qcom-ipq4019-add-USB-nodes-to-ipq4019-SoC-device-tre.patch index 22ea75299..b780d7881 100644 --- a/target/linux/ipq806x/patches-4.9/306-qcom-ipq4019-add-USB-nodes-to-ipq4019-SoC-device-tre.patch +++ b/target/linux/ipq806x/patches-4.9/306-qcom-ipq4019-add-USB-nodes-to-ipq4019-SoC-device-tre.patch @@ -51,7 +51,7 @@ Changes: }; --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -331,5 +331,76 @@ +@@ -313,5 +313,76 @@ compatible = "qcom,pshold"; reg = <0x4ab000 0x4>; }; diff --git a/target/linux/ipq806x/patches-4.9/308-dts-ipq4019-add-both-IPQ4019-wifi-block-definitions.patch b/target/linux/ipq806x/patches-4.9/308-dts-ipq4019-add-both-IPQ4019-wifi-block-definitions.patch index 4b2f6c8dd..ad7ce1673 100644 --- a/target/linux/ipq806x/patches-4.9/308-dts-ipq4019-add-both-IPQ4019-wifi-block-definitions.patch +++ b/target/linux/ipq806x/patches-4.9/308-dts-ipq4019-add-both-IPQ4019-wifi-block-definitions.patch @@ -1,100 +1,57 @@ -From 45e183ad169db4e233ce8337cf8b735545151f0e Mon Sep 17 00:00:00 2001 +From 6091a49b0b06bf838fed80498c4f5f40d0fbd447 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 19 Nov 2016 01:22:46 +0100 -Subject: [PATCH] arm: dts: qcom: add both IPQ4019 wifi blocks +Subject: [PATCH] dts: ipq4019: add both IPQ4019 wifi block definitions -This patch adds and enables the device-tree definitions for -both qcom,ipq4019-wifi blocks for the IPQ4019. +The IPQ4019 has two ath10k blocks on the AHB. Both wifi's +are already supported by ath10k. -Support for these have been added into the ath10k driver since: -280e762e9c72 ("ath10k: enable ipq4019 device probe in ahb module") - -The binding documentation was added in commit: -a47aaa69de88 ("dt: bindings: add new dt entry for pre calibration in qcom, ath10k.txt") - -This has been tested on an ASUS RT-AC58U (IPQ4019), -an AVM Fritz!Box 4040 (IPQ4018), a Compex WPJ428(IPQ4028) -and a Meraki MR33 (IPQ4029). - -| a000000.wifi: qca4019 hw1.0 target 0x01000000 chip_id 0x003b00ff [...] -| a000000.wifi: kconfig debug 0 debugfs 1 tracing 0 dfs 1 testmode 1 -| a000000.wifi: firmware ver 10.4-3.4-00082 api 5 features no-p2p,mfp,[...] -| a000000.wifi: board_file api 2 bmi_id 0:16 crc32 5773b188 -| a000000.wifi: htt-ver 2.2 wmi-op 6 htt-op 4 cal pre-cal-file [...] -... -| a800000.wifi: qca4019 hw1.0 target 0x01000000 chip_id 0x003b00ff sub 0000:0000 -| a800000.wifi: kconfig debug 0 debugfs 1 tracing 0 dfs 1 testmode 1 -| a800000.wifi: firmware ver 10.4-3.4-00082 api 5 features no-p2p, [...] -| a800000.wifi: board_file api 2 bmi_id 0:17 crc32 5773b188 -| a800000.wifi: htt-ver 2.2 wmi-op 6 htt-op 4 cal pre-cal-file [...] - -Signed-off-by: Christian Lamparter +Signed-off-by: Christian Lamparter --- - arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi | 8 +++ - arch/arm/boot/dts/qcom-ipq4019.dtsi | 84 +++++++++++++++++++++++++++ - 2 files changed, 92 insertions(+) + arch/arm/boot/dts/qcom-ipq4019.dtsi | 84 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 84 insertions(+) -diff --git a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi -index c25d8f5c669d..cfa0c9970d5b 100644 ---- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi -@@ -112,5 +112,13 @@ - watchdog@b017000 { - status = "ok"; - }; -+ -+ wifi@a000000 { -+ status = "ok"; -+ }; -+ -+ wifi@a800000 { -+ status = "ok"; -+ }; - }; - }; -diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi -index d1a56331ce96..1ddcc96b510c 100644 --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -291,5 +291,89 @@ - compatible = "qcom,pshold"; - reg = <0x4ab000 0x4>; +@@ -384,5 +384,89 @@ + dr_mode = "host"; + }; }; + + wifi0: wifi@a000000 { + compatible = "qcom,ipq4019-wifi"; + reg = <0xa000000 0x200000>; -+ resets = <&gcc WIFI0_CPU_INIT_RESET>, -+ <&gcc WIFI0_RADIO_SRIF_RESET>, -+ <&gcc WIFI0_RADIO_WARM_RESET>, -+ <&gcc WIFI0_RADIO_COLD_RESET>, -+ <&gcc WIFI0_CORE_WARM_RESET>, -+ <&gcc WIFI0_CORE_COLD_RESET>; ++ resets = <&gcc WIFI0_CPU_INIT_RESET ++ &gcc WIFI0_RADIO_SRIF_RESET ++ &gcc WIFI0_RADIO_WARM_RESET ++ &gcc WIFI0_RADIO_COLD_RESET ++ &gcc WIFI0_CORE_WARM_RESET ++ &gcc WIFI0_CORE_COLD_RESET>; + reset-names = "wifi_cpu_init", "wifi_radio_srif", + "wifi_radio_warm", "wifi_radio_cold", + "wifi_core_warm", "wifi_core_cold"; -+ clocks = <&gcc GCC_WCSS2G_CLK>, -+ <&gcc GCC_WCSS2G_REF_CLK>, -+ <&gcc GCC_WCSS2G_RTC_CLK>; ++ clocks = <&gcc GCC_WCSS2G_CLK ++ &gcc GCC_WCSS2G_REF_CLK ++ &gcc GCC_WCSS2G_RTC_CLK>; + clock-names = "wifi_wcss_cmd", "wifi_wcss_ref", + "wifi_wcss_rtc"; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; ++ interrupts = <0 32 IRQ_TYPE_EDGE_RISING ++ 0 33 IRQ_TYPE_EDGE_RISING ++ 0 34 IRQ_TYPE_EDGE_RISING ++ 0 35 IRQ_TYPE_EDGE_RISING ++ 0 36 IRQ_TYPE_EDGE_RISING ++ 0 37 IRQ_TYPE_EDGE_RISING ++ 0 38 IRQ_TYPE_EDGE_RISING ++ 0 39 IRQ_TYPE_EDGE_RISING ++ 0 40 IRQ_TYPE_EDGE_RISING ++ 0 41 IRQ_TYPE_EDGE_RISING ++ 0 42 IRQ_TYPE_EDGE_RISING ++ 0 43 IRQ_TYPE_EDGE_RISING ++ 0 44 IRQ_TYPE_EDGE_RISING ++ 0 45 IRQ_TYPE_EDGE_RISING ++ 0 46 IRQ_TYPE_EDGE_RISING ++ 0 47 IRQ_TYPE_EDGE_RISING ++ 0 168 IRQ_TYPE_NONE>; + interrupt-names = "msi0", "msi1", "msi2", "msi3", + "msi4", "msi5", "msi6", "msi7", + "msi8", "msi9", "msi10", "msi11", @@ -106,37 +63,37 @@ index d1a56331ce96..1ddcc96b510c 100644 + wifi1: wifi@a800000 { + compatible = "qcom,ipq4019-wifi"; + reg = <0xa800000 0x200000>; -+ resets = <&gcc WIFI1_CPU_INIT_RESET>, -+ <&gcc WIFI1_RADIO_SRIF_RESET>, -+ <&gcc WIFI1_RADIO_WARM_RESET>, -+ <&gcc WIFI1_RADIO_COLD_RESET>, -+ <&gcc WIFI1_CORE_WARM_RESET>, -+ <&gcc WIFI1_CORE_COLD_RESET>; ++ resets = <&gcc WIFI1_CPU_INIT_RESET ++ &gcc WIFI1_RADIO_SRIF_RESET ++ &gcc WIFI1_RADIO_WARM_RESET ++ &gcc WIFI1_RADIO_COLD_RESET ++ &gcc WIFI1_CORE_WARM_RESET ++ &gcc WIFI1_CORE_COLD_RESET>; + reset-names = "wifi_cpu_init", "wifi_radio_srif", + "wifi_radio_warm", "wifi_radio_cold", + "wifi_core_warm", "wifi_core_cold"; -+ clocks = <&gcc GCC_WCSS5G_CLK>, -+ <&gcc GCC_WCSS5G_REF_CLK>, -+ <&gcc GCC_WCSS5G_RTC_CLK>; ++ clocks = <&gcc GCC_WCSS5G_CLK ++ &gcc GCC_WCSS5G_REF_CLK ++ &gcc GCC_WCSS5G_RTC_CLK>; + clock-names = "wifi_wcss_cmd", "wifi_wcss_ref", + "wifi_wcss_rtc"; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; ++ interrupts = <0 48 IRQ_TYPE_EDGE_RISING ++ 0 49 IRQ_TYPE_EDGE_RISING ++ 0 50 IRQ_TYPE_EDGE_RISING ++ 0 51 IRQ_TYPE_EDGE_RISING ++ 0 52 IRQ_TYPE_EDGE_RISING ++ 0 53 IRQ_TYPE_EDGE_RISING ++ 0 54 IRQ_TYPE_EDGE_RISING ++ 0 55 IRQ_TYPE_EDGE_RISING ++ 0 56 IRQ_TYPE_EDGE_RISING ++ 0 57 IRQ_TYPE_EDGE_RISING ++ 0 58 IRQ_TYPE_EDGE_RISING ++ 0 59 IRQ_TYPE_EDGE_RISING ++ 0 60 IRQ_TYPE_EDGE_RISING ++ 0 61 IRQ_TYPE_EDGE_RISING ++ 0 62 IRQ_TYPE_EDGE_RISING ++ 0 63 IRQ_TYPE_EDGE_RISING ++ 0 169 IRQ_TYPE_NONE>; + interrupt-names = "msi0", "msi1", "msi2", "msi3", + "msi4", "msi5", "msi6", "msi7", + "msi8", "msi9", "msi10", "msi11", @@ -146,6 +103,3 @@ index d1a56331ce96..1ddcc96b510c 100644 + }; }; }; --- -2.13.3 - diff --git a/target/linux/ipq806x/patches-4.9/309-dts-ipq4019-add-pseudo-random-number-generator.patch b/target/linux/ipq806x/patches-4.9/309-dts-ipq4019-add-pseudo-random-number-generator.patch index f53f78073..8323ff0fa 100644 --- a/target/linux/ipq806x/patches-4.9/309-dts-ipq4019-add-pseudo-random-number-generator.patch +++ b/target/linux/ipq806x/patches-4.9/309-dts-ipq4019-add-pseudo-random-number-generator.patch @@ -13,7 +13,7 @@ Signed-off-by: Christian Lamparter --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -295,6 +295,13 @@ +@@ -277,6 +277,13 @@ regulator; }; diff --git a/target/linux/ipq806x/patches-4.9/311-dts-ARM-qcom-ipq4019-add-scm-node.patch b/target/linux/ipq806x/patches-4.9/311-dts-ARM-qcom-ipq4019-add-scm-node.patch deleted file mode 100644 index 7ac157058..000000000 --- a/target/linux/ipq806x/patches-4.9/311-dts-ARM-qcom-ipq4019-add-scm-node.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Christian Lamparter -Date: Mon, 20 Mar 2017 18:08:03 +0100 -Subject: [PATCH] dts: ARM: qcom-ipq4019: add scm node - -This patch adds the device-tree node necessary for communicating -with Qualcomm's TrustZone/Secure Execution Environment -implementation. - -Signed-off-by: Christian Lamparter ---- ---- a/arch/arm/boot/dts/qcom-ipq4019.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -137,6 +137,12 @@ - }; - }; - -+ firmware { -+ scm { -+ compatible = "qcom,scm-ipq4019", "qcom,scm-ipq40xx"; -+ }; -+ }; -+ - soc { - #address-cells = <1>; - #size-cells = <1>; diff --git a/target/linux/ipq806x/patches-4.9/312-firmware-qcom-scm-fuse-access.patch b/target/linux/ipq806x/patches-4.9/312-firmware-qcom-scm-fuse-access.patch deleted file mode 100644 index df6ecfac7..000000000 --- a/target/linux/ipq806x/patches-4.9/312-firmware-qcom-scm-fuse-access.patch +++ /dev/null @@ -1,98 +0,0 @@ ---- a/drivers/firmware/qcom_scm-32.c -+++ b/drivers/firmware/qcom_scm-32.c -@@ -578,3 +578,33 @@ int __qcom_scm_pinmux_write(u32 svc_id, - - return ret; - } -+ -+int __qcom_scm_fuse(struct device *dev, u32 address, u32 *val) -+{ -+ __le32 *otp_value; -+ dma_addr_t in; -+ int ret; -+ -+ otp_value = kzalloc(PAGE_ALIGN(sizeof(*otp_value)), GFP_KERNEL); -+ if (!otp_value) -+ return -ENOMEM; -+ -+ in = dma_map_single(dev, otp_value, sizeof(in), DMA_FROM_DEVICE); -+ -+ ret = dma_mapping_error(dev, in); -+ if (ret != 0) { -+ kfree(otp_value); -+ pr_err("DMA Mapping Error %d\n", ret); -+ return ret; -+ } -+ -+ ret = qcom_scm_call(dev, QCOM_SCM_SVC_FUSE, address, -+ &in, sizeof(in), NULL, 0); -+ -+ dma_unmap_single(dev, in, sizeof(in), DMA_FROM_DEVICE); -+ -+ *val = le32_to_cpu(*otp_value); -+ kfree(otp_value); -+ -+ return ret; -+} ---- a/drivers/firmware/qcom_scm.c -+++ b/drivers/firmware/qcom_scm.c -@@ -165,6 +165,25 @@ int qcom_scm_hdcp_req(struct qcom_scm_hd - EXPORT_SYMBOL(qcom_scm_hdcp_req); - - /** -+ * qcom_scm_fuse() - Reads a value from the OTP -+ * @address: address -+ * -+ * Returns the value of the OTP at the specified address. -+ */ -+int qcom_scm_fuse(u32 address, u32 *val) -+{ -+ int ret = qcom_scm_clk_enable(); -+ -+ if (ret) -+ return ret; -+ -+ ret = __qcom_scm_fuse(__scm->dev, address, val); -+ qcom_scm_clk_disable(); -+ return ret; -+} -+EXPORT_SYMBOL(qcom_scm_fuse); -+ -+/** - * qcom_scm_pas_supported() - Check if the peripheral authentication service is - * available for the given peripherial - * @peripheral: peripheral id ---- a/drivers/firmware/qcom_scm.h -+++ b/drivers/firmware/qcom_scm.h -@@ -63,6 +63,9 @@ extern int __qcom_scm_pas_mss_reset(str - s32 __qcom_scm_pinmux_read(u32 svc_id, u32 cmd_id, u32 arg1); - s32 __qcom_scm_pinmux_write(u32 svc_id, u32 cmd_id, u32 arg1, u32 arg2); - -+#define QCOM_SCM_SVC_FUSE 0x8 -+extern int __qcom_scm_fuse(struct device *dev, u32 address, u32 *val); -+ - /* common error codes */ - #define QCOM_SCM_V2_EBUSY -12 - #define QCOM_SCM_ENOMEM -5 ---- a/include/linux/qcom_scm.h -+++ b/include/linux/qcom_scm.h -@@ -48,4 +48,7 @@ extern u32 qcom_scm_get_version(void); - - extern s32 qcom_scm_pinmux_read(u32 arg1); - extern s32 qcom_scm_pinmux_write(u32 arg1, u32 arg2); -+ -+extern int qcom_scm_fuse(u32 address, u32 *val); -+ - #endif ---- a/drivers/firmware/qcom_scm-64.c -+++ b/drivers/firmware/qcom_scm-64.c -@@ -374,3 +374,9 @@ int __qcom_scm_pinmux_write(u32 svc_id, - { - return -ENOTSUPP; - } -+ -+int __qcom_scm_fuse(struct device *dev, u32 address, u32 *val) -+{ -+ *val = -1; -+ return -ENOTSUPP; -+} diff --git a/target/linux/ipq806x/patches-4.9/701-dts-ipq4019-add-mdio-node.patch b/target/linux/ipq806x/patches-4.9/701-dts-ipq4019-add-mdio-node.patch index 546eb3769..d19be2716 100644 --- a/target/linux/ipq806x/patches-4.9/701-dts-ipq4019-add-mdio-node.patch +++ b/target/linux/ipq806x/patches-4.9/701-dts-ipq4019-add-mdio-node.patch @@ -15,7 +15,7 @@ so the info might change. --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -345,6 +345,34 @@ +@@ -321,6 +321,34 @@ reg = <0x4ab000 0x4>; }; diff --git a/target/linux/ipq806x/patches-4.9/702-dts-ipq4019-add-PHY-switch-nodes.patch b/target/linux/ipq806x/patches-4.9/702-dts-ipq4019-add-PHY-switch-nodes.patch index ee8f459e4..b1b18b46d 100644 --- a/target/linux/ipq806x/patches-4.9/702-dts-ipq4019-add-PHY-switch-nodes.patch +++ b/target/linux/ipq806x/patches-4.9/702-dts-ipq4019-add-PHY-switch-nodes.patch @@ -14,7 +14,7 @@ Signed-off-by: Christian Lamparter --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -373,6 +373,29 @@ +@@ -349,6 +349,29 @@ }; }; diff --git a/target/linux/ipq806x/patches-4.9/711-dts-ipq4019-add-ethernet-essedma-node.patch b/target/linux/ipq806x/patches-4.9/711-dts-ipq4019-add-ethernet-essedma-node.patch index afd680d64..ad3c9fc30 100644 --- a/target/linux/ipq806x/patches-4.9/711-dts-ipq4019-add-ethernet-essedma-node.patch +++ b/target/linux/ipq806x/patches-4.9/711-dts-ipq4019-add-ethernet-essedma-node.patch @@ -16,16 +16,16 @@ Signed-off-by: Christian Lamparter --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -27,6 +27,8 @@ +@@ -26,6 +26,8 @@ + aliases { spi0 = &spi_0; i2c0 = &i2c_0; - i2c1 = &i2c_1; + ethernet0 = &gmac0; + ethernet1 = &gmac1; }; cpus { -@@ -396,6 +398,64 @@ +@@ -372,6 +374,64 @@ status = "disabled"; }; diff --git a/target/linux/ipq806x/patches-4.9/712-net-essedma-disable-default-vlan.patch b/target/linux/ipq806x/patches-4.9/712-net-essedma-disable-default-vlan.patch deleted file mode 100644 index 2a1cade85..000000000 --- a/target/linux/ipq806x/patches-4.9/712-net-essedma-disable-default-vlan.patch +++ /dev/null @@ -1,69 +0,0 @@ -From: Christian Lamparter -Subject: [PATCH] net: essedma: disable default vlan tagging -Date: Tue, 21 Mar 13:59:02 CET 2017 +0100 - -The essedma driver has its own unique take on VLAN management -and its configuration. In the original SDK, each VLAN is -assigned one virtual ethernet netdev. - -However, this is non-standard. So, this patch does away -with the default_vlan_tag property the driver is using -and therefore forces the user to use the kernel's vlan -feature. - -This patch also removes the "qcom,poll_required = <1>;" from -the essedma node. - -Signed-off-by: Christian Lamparter ---- ---- a/drivers/net/ethernet/qualcomm/essedma/edma.c -+++ b/drivers/net/ethernet/qualcomm/essedma/edma.c -@@ -715,13 +715,11 @@ static void edma_rx_complete(struct edma - edma_receive_checksum(rd, skb); - - /* Process VLAN HW acceleration indication provided by HW */ -- if (unlikely(adapter->default_vlan_tag != rd->rrd4)) { -- vlan = rd->rrd4; -- if (likely(rd->rrd7 & EDMA_RRD_CVLAN)) -- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan); -- else if (rd->rrd1 & EDMA_RRD_SVLAN) -- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021AD), vlan); -- } -+ vlan = rd->rrd4; -+ if (likely(rd->rrd7 & EDMA_RRD_CVLAN)) -+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan); -+ else if (rd->rrd1 & EDMA_RRD_SVLAN) -+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021AD), vlan); - - /* Update rx statistics */ - adapter->stats.rx_packets++; -@@ -1390,8 +1388,6 @@ netdev_tx_t edma_xmit(struct sk_buff *sk - /* Check and mark VLAN tag offload */ - if (skb_vlan_tag_present(skb)) - flags_transmit |= EDMA_VLAN_TX_TAG_INSERT_FLAG; -- else if (adapter->default_vlan_tag) -- flags_transmit |= EDMA_VLAN_TX_TAG_INSERT_DEFAULT_FLAG; - - /* Check and mark checksum offload */ - if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) ---- a/arch/arm/boot/dts/qcom-ipq4019.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -404,8 +404,7 @@ - qcom,page-mode = <0>; - qcom,rx_head_buf_size = <1540>; - qcom,mdio_supported; -- qcom,poll_required = <1>; -- qcom,num_gmac = <2>; -+ qcom,num_gmac = <1>; - interrupts = <0 65 IRQ_TYPE_EDGE_RISING - 0 66 IRQ_TYPE_EDGE_RISING - 0 67 IRQ_TYPE_EDGE_RISING -@@ -443,7 +442,7 @@ - - gmac0: gmac0 { - local-mac-address = [00 00 00 00 00 00]; -- vlan_tag = <1 0x1f>; -+ vlan_tag = <1 0x3f>; - }; - - gmac1: gmac1 { diff --git a/target/linux/ipq806x/patches-4.9/820-qcom-ipq4019-Add-IPQ4019-USB-HS-SS-PHY-drivers.patch b/target/linux/ipq806x/patches-4.9/820-qcom-ipq4019-Add-IPQ4019-USB-HS-SS-PHY-drivers.patch index 2aa0448f8..3636c5ca0 100644 --- a/target/linux/ipq806x/patches-4.9/820-qcom-ipq4019-Add-IPQ4019-USB-HS-SS-PHY-drivers.patch +++ b/target/linux/ipq806x/patches-4.9/820-qcom-ipq4019-Add-IPQ4019-USB-HS-SS-PHY-drivers.patch @@ -291,7 +291,7 @@ Changed: +MODULE_DESCRIPTION("USB3 QCA BALDUR HSPHY driver"); --- /dev/null +++ b/drivers/usb/phy/phy-qca-uniphy.c -@@ -0,0 +1,202 @@ +@@ -0,0 +1,135 @@ +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any @@ -318,18 +318,6 @@ Changed: +#include +#include +#include -+#include -+ -+#define USB_CALIBRATION_CMD 0x10 -+#define USB3PHY_SPARE_1 0x7FC -+#define RX_LOS_1 0x7C8 -+#define MISC_SOURCE_REG 0x21c -+#define CDR_CONTROL_REG_1 0x80 -+#define PCS_INTERNAL_CONTROL14 0x364 -+#define MMD1_REG_REG_MASK (0x7F << 8) -+#define OTP_MASK (0x7F << 5) -+#define MMD1_REG_AUTOLOAD_MASK (0x1 << 7) -+#define SPARE_1_BIT14_MASK (0x1 << 14) + +struct qca_uni_ss_phy { + struct usb_phy phy; @@ -350,60 +338,6 @@ Changed: + reset_control_assert(phy->por_rst); +} + -+int qca_uni_ss_phy_usb_los_calibration(void __iomem *base) -+{ -+ int err; -+ uint32_t data, otp_val = 0; -+ -+ /* Get OTP value */ -+ err = qcom_scm_fuse(USB_CALIBRATION_CMD, &otp_val); -+ if (err < 0 || !(otp_val & OTP_MASK)) { -+ pr_err("USB Calibration Failed with error %d %d\n", err, otp_val); -+ return 0; -+ } -+ -+ pr_info("Raw USB3 Calibration value %x\n", otp_val); -+ -+ /* -+ * Read the USB3PHY_SPARE_1 register and -+ * set bit 14 to 0 -+ */ -+ data = readl_relaxed(base + USB3PHY_SPARE_1); -+ data = data & (~SPARE_1_BIT14_MASK); -+ writel(data, base + USB3PHY_SPARE_1); -+ udelay(100); -+ -+ /* -+ * Get bit 11:5 value, add with 0x14 and set to the -+ * register USB3PHY_RX_LOS_1 bit MMD1_REG_REG -+ */ -+ data = readl_relaxed(base + RX_LOS_1); -+ otp_val = ((otp_val & OTP_MASK) >> 5) + 0x14; -+ otp_val = otp_val << 8; -+ data = data & (~MMD1_REG_REG_MASK); -+ data = data | otp_val; -+ writel(data, base + RX_LOS_1); -+ udelay(100); -+ -+ /* -+ * Set bit MMD1_REG_AUTOLOAD_SEL_RX_LOS_THRES in -+ * USB3PHY_RX_LOS_1 to 1 -+ */ -+ data = readl_relaxed(base + RX_LOS_1); -+ data = data | MMD1_REG_AUTOLOAD_MASK; -+ writel(data, base + RX_LOS_1); -+ udelay(100); -+ -+ writel(0x4000, base + PCS_INTERNAL_CONTROL14); -+ udelay(100); -+ writel(0xaa0a, base + MISC_SOURCE_REG); -+ udelay(100); -+ writel(0x0202, base + CDR_CONTROL_REG_1); -+ udelay(100); -+ -+ return 0; -+} -+ +static int qca_uni_ss_phy_init(struct usb_phy *x) +{ + struct qca_uni_ss_phy *phy = phy_to_dw_phy(x); @@ -416,8 +350,7 @@ Changed: + /* deassert SS PHY POR reset */ + reset_control_deassert(phy->por_rst); + -+ /* USB LOS Calibration */ -+ return qca_uni_ss_phy_usb_los_calibration(phy->base); ++ return 0; +} + +static int qca_uni_ss_get_resources(struct platform_device *pdev, diff --git a/target/linux/ipq806x/patches-4.9/852-ipq4019-pinctrl-Updated-various-Pin-definitions.patch b/target/linux/ipq806x/patches-4.9/852-ipq4019-pinctrl-Updated-various-Pin-definitions.patch new file mode 100644 index 000000000..d0a6a26a5 --- /dev/null +++ b/target/linux/ipq806x/patches-4.9/852-ipq4019-pinctrl-Updated-various-Pin-definitions.patch @@ -0,0 +1,1328 @@ +From fc6cf61517b8b4ab4678659936fc7572f699d6e7 Mon Sep 17 00:00:00 2001 +From: Ram Chandra Jangir +Date: Tue, 28 Mar 2017 14:00:00 +0530 +Subject: [PATCH] ipq4019: pinctrl: Updated various Pin definitions + +Populate default values for various GPIO functions + +Signed-off-by: Ram Chandra Jangir +--- + drivers/pinctrl/qcom/pinctrl-ipq4019.c | 1189 +++++++++++++++++++++++++++++--- + 1 file changed, 1111 insertions(+), 78 deletions(-) + +--- a/drivers/pinctrl/qcom/pinctrl-ipq4019.c ++++ b/drivers/pinctrl/qcom/pinctrl-ipq4019.c +@@ -276,16 +276,531 @@ DECLARE_QCA_GPIO_PINS(99); + + + enum ipq4019_functions { ++ qca_mux_rmii0_refclk, ++ qca_mux_wifi0_rfsilient0, ++ qca_mux_wifi1_rfsilient0, ++ qca_mux_smart2, ++ qca_mux_led4, ++ qca_mux_wifi0_cal, ++ qca_mux_wifi1_cal, ++ qca_mux_wifi_wci0, ++ qca_mux_rmii0_dv, ++ qca_mux_wifi_wci1, ++ qca_mux_rmii1_refclk, ++ qca_mux_blsp_spi1, ++ qca_mux_led5, ++ qca_mux_rmii10, ++ qca_mux_led6, ++ qca_mux_rmii11, ++ qca_mux_led7, ++ qca_mux_rmii1_dv, ++ qca_mux_led8, ++ qca_mux_rmii1_tx, ++ qca_mux_aud_pin, ++ qca_mux_led9, ++ qca_mux_rmii1_rx, ++ qca_mux_led10, ++ qca_mux_wifi0_rfsilient1, ++ qca_mux_wifi1_rfsilient1, ++ qca_mux_led11, ++ qca_mux_boot7, ++ qca_mux_qpic_pad, ++ qca_mux_pcie_clk, ++ qca_mux_tm_clk0, ++ qca_mux_wifi00, ++ qca_mux_wifi10, ++ qca_mux_mdio1, ++ qca_mux_prng_rosc, ++ qca_mux_dbg_out, ++ qca_mux_tm0, ++ qca_mux_wifi01, ++ qca_mux_wifi11, ++ qca_mux_atest_char3, ++ qca_mux_pmu0, ++ qca_mux_boot8, ++ qca_mux_tm1, ++ qca_mux_atest_char2, ++ qca_mux_pmu1, ++ qca_mux_boot9, ++ qca_mux_tm2, ++ qca_mux_atest_char1, ++ qca_mux_tm_ack, ++ qca_mux_wifi03, ++ qca_mux_wifi13, ++ qca_mux_qpic_pad4, ++ qca_mux_atest_char0, ++ qca_mux_tm3, ++ qca_mux_wifi02, ++ qca_mux_wifi12, ++ qca_mux_qpic_pad5, ++ qca_mux_smart3, ++ qca_mux_wcss0_dbg14, ++ qca_mux_tm4, ++ qca_mux_wifi04, ++ qca_mux_wifi14, ++ qca_mux_qpic_pad6, ++ qca_mux_wcss0_dbg15, ++ qca_mux_qdss_tracectl_a, ++ qca_mux_boot18, ++ qca_mux_tm5, ++ qca_mux_qpic_pad7, ++ qca_mux_atest_char, ++ qca_mux_wcss0_dbg4, ++ qca_mux_qdss_traceclk_a, ++ qca_mux_boot19, ++ qca_mux_tm6, ++ qca_mux_wcss0_dbg5, ++ qca_mux_qdss_cti_trig_out_a0, ++ qca_mux_boot14, ++ qca_mux_tm7, ++ qca_mux_chip_rst, ++ qca_mux_wcss0_dbg6, ++ qca_mux_qdss_cti_trig_out_b0, ++ qca_mux_boot11, ++ qca_mux_tm8, ++ qca_mux_wcss0_dbg7, ++ qca_mux_wcss1_dbg7, ++ qca_mux_boot20, ++ qca_mux_tm9, ++ qca_mux_qpic_pad1, ++ qca_mux_wcss0_dbg8, ++ qca_mux_wcss1_dbg8, ++ qca_mux_qpic_pad2, ++ qca_mux_wcss0_dbg9, ++ qca_mux_wcss1_dbg9, ++ qca_mux_qpic_pad3, ++ qca_mux_wcss0_dbg10, ++ qca_mux_wcss1_dbg10, ++ qca_mux_qpic_pad0, ++ qca_mux_wcss0_dbg11, ++ qca_mux_wcss1_dbg11, ++ qca_mux_qpic_pad8, ++ qca_mux_wcss0_dbg12, ++ qca_mux_wcss1_dbg12, ++ qca_mux_wifi034, ++ qca_mux_wifi134, ++ qca_mux_jtag_tdi, + qca_mux_gpio, ++ qca_mux_i2s_rx_bclk, ++ qca_mux_jtag_tck, ++ qca_mux_i2s_rx_fsync, ++ qca_mux_jtag_tms, ++ qca_mux_i2s_rxd, ++ qca_mux_smart0, ++ qca_mux_jtag_tdo, ++ qca_mux_jtag_rst, ++ qca_mux_jtag_trst, ++ qca_mux_mdio0, ++ qca_mux_wcss0_dbg18, ++ qca_mux_wcss1_dbg18, ++ qca_mux_qdss_tracedata_a, ++ qca_mux_mdc, ++ qca_mux_wcss0_dbg19, ++ qca_mux_wcss1_dbg19, + qca_mux_blsp_uart1, ++ qca_mux_wifi0_uart, ++ qca_mux_wifi1_uart, ++ qca_mux_smart1, ++ qca_mux_wcss0_dbg20, ++ qca_mux_wcss1_dbg20, ++ qca_mux_wifi0_uart0, ++ qca_mux_wifi1_uart0, ++ qca_mux_wcss0_dbg21, ++ qca_mux_wcss1_dbg21, + qca_mux_blsp_i2c0, ++ qca_mux_wcss0_dbg22, ++ qca_mux_wcss1_dbg22, ++ qca_mux_wcss0_dbg23, ++ qca_mux_wcss1_dbg23, ++ qca_mux_blsp_spi0, + qca_mux_blsp_i2c1, ++ qca_mux_wcss0_dbg24, ++ qca_mux_wcss1_dbg24, ++ qca_mux_wcss0_dbg25, ++ qca_mux_wcss1_dbg25, ++ qca_mux_wcss0_dbg26, ++ qca_mux_wcss1_dbg26, ++ qca_mux_wcss0_dbg, ++ qca_mux_wcss1_dbg, + qca_mux_blsp_uart0, +- qca_mux_blsp_spi1, +- qca_mux_blsp_spi0, ++ qca_mux_led0, ++ qca_mux_wcss0_dbg28, ++ qca_mux_wcss1_dbg28, ++ qca_mux_led1, ++ qca_mux_wcss0_dbg29, ++ qca_mux_wcss1_dbg29, ++ qca_mux_wifi0_uart1, ++ qca_mux_wifi1_uart1, ++ qca_mux_wcss0_dbg30, ++ qca_mux_wcss1_dbg30, ++ qca_mux_wcss0_dbg31, ++ qca_mux_wcss1_dbg31, ++ qca_mux_i2s_rx_mclk, ++ qca_mux_wcss0_dbg16, ++ qca_mux_wcss1_dbg16, ++ qca_mux_wcss0_dbg17, ++ qca_mux_wcss1_dbg17, ++ qca_mux_rgmii0, ++ qca_mux_sdio0, ++ qca_mux_rgmii1, ++ qca_mux_sdio1, ++ qca_mux_rgmii2, ++ qca_mux_i2s_tx_mclk, ++ qca_mux_sdio2, ++ qca_mux_rgmii3, ++ qca_mux_i2s_tx_bclk, ++ qca_mux_sdio3, ++ qca_mux_rgmii_rx, ++ qca_mux_i2s_tx_fsync, ++ qca_mux_sdio_clk, ++ qca_mux_rgmii_txc, ++ qca_mux_i2s_td1, ++ qca_mux_sdio_cmd, ++ qca_mux_i2s_td2, ++ qca_mux_sdio4, ++ qca_mux_i2s_td3, ++ qca_mux_sdio5, ++ qca_mux_audio_pwm0, ++ qca_mux_sdio6, ++ qca_mux_audio_pwm1, ++ qca_mux_wcss0_dbg27, ++ qca_mux_wcss1_dbg27, ++ qca_mux_sdio7, ++ qca_mux_rgmii_rxc, ++ qca_mux_audio_pwm2, ++ qca_mux_rgmii_tx, ++ qca_mux_audio_pwm3, ++ qca_mux_boot2, ++ qca_mux_i2s_spdif_in, ++ qca_mux_i2s_spdif_out, ++ qca_mux_rmii00, ++ qca_mux_led2, ++ qca_mux_rmii01, ++ qca_mux_wifi0_wci, ++ qca_mux_wifi1_wci, ++ qca_mux_boot4, ++ qca_mux_rmii0_tx, ++ qca_mux_boot5, ++ qca_mux_rmii0_rx, ++ qca_mux_pcie_clk1, ++ qca_mux_led3, ++ qca_mux_sdio_cd, + qca_mux_NA, + }; + ++static const char * const rmii0_refclk_groups[] = { ++ "gpio40", ++}; ++static const char * const wifi0_rfsilient0_groups[] = { ++ "gpio40", ++}; ++static const char * const wifi1_rfsilient0_groups[] = { ++ "gpio40", ++}; ++static const char * const smart2_groups[] = { ++ "gpio40", "gpio41", "gpio48", "gpio49", ++}; ++static const char * const led4_groups[] = { ++ "gpio40", ++}; ++static const char * const wifi0_cal_groups[] = { ++ "gpio41", "gpio51", ++}; ++static const char * const wifi1_cal_groups[] = { ++ "gpio41", "gpio51", ++}; ++static const char * const wifi_wci0_groups[] = { ++ "gpio42", ++}; ++static const char * const rmii0_dv_groups[] = { ++ "gpio43", ++}; ++static const char * const wifi_wci1_groups[] = { ++ "gpio43", ++}; ++static const char * const rmii1_refclk_groups[] = { ++ "gpio44", ++}; ++static const char * const blsp_spi1_groups[] = { ++ "gpio44", "gpio45", "gpio46", "gpio47", ++}; ++static const char * const led5_groups[] = { ++ "gpio44", ++}; ++static const char * const rmii10_groups[] = { ++ "gpio45", "gpio50", ++}; ++static const char * const led6_groups[] = { ++ "gpio45", ++}; ++static const char * const rmii11_groups[] = { ++ "gpio46", "gpio51", ++}; ++static const char * const led7_groups[] = { ++ "gpio46", ++}; ++static const char * const rmii1_dv_groups[] = { ++ "gpio47", ++}; ++static const char * const led8_groups[] = { ++ "gpio47", ++}; ++static const char * const rmii1_tx_groups[] = { ++ "gpio48", ++}; ++static const char * const aud_pin_groups[] = { ++ "gpio48", "gpio49", "gpio50", "gpio51", ++}; ++static const char * const led9_groups[] = { ++ "gpio48", ++}; ++static const char * const rmii1_rx_groups[] = { ++ "gpio49", ++}; ++static const char * const led10_groups[] = { ++ "gpio49", ++}; ++static const char * const wifi0_rfsilient1_groups[] = { ++ "gpio50", ++}; ++static const char * const wifi1_rfsilient1_groups[] = { ++ "gpio50", ++}; ++static const char * const led11_groups[] = { ++ "gpio50", ++}; ++static const char * const boot7_groups[] = { ++ "gpio51", ++}; ++static const char * const qpic_pad_groups[] = { ++ "gpio52", "gpio53", "gpio54", "gpio55", "gpio56", "gpio61", "gpio62", ++ "gpio63", "gpio69", ++}; ++static const char * const pcie_clk_groups[] = { ++ "gpio52", ++}; ++static const char * const tm_clk0_groups[] = { ++ "gpio52", ++}; ++static const char * const wifi00_groups[] = { ++ "gpio52", ++}; ++static const char * const wifi10_groups[] = { ++ "gpio52", ++}; ++static const char * const mdio1_groups[] = { ++ "gpio53", ++}; ++static const char * const prng_rosc_groups[] = { ++ "gpio53", ++}; ++static const char * const dbg_out_groups[] = { ++ "gpio53", ++}; ++static const char * const tm0_groups[] = { ++ "gpio53", ++}; ++static const char * const wifi01_groups[] = { ++ "gpio53", ++}; ++static const char * const wifi11_groups[] = { ++ "gpio53", ++}; ++static const char * const atest_char3_groups[] = { ++ "gpio54", ++}; ++static const char * const pmu0_groups[] = { ++ "gpio54", ++}; ++static const char * const boot8_groups[] = { ++ "gpio54", ++}; ++static const char * const tm1_groups[] = { ++ "gpio54", ++}; ++static const char * const atest_char2_groups[] = { ++ "gpio55", ++}; ++static const char * const pmu1_groups[] = { ++ "gpio55", ++}; ++static const char * const boot9_groups[] = { ++ "gpio55", ++}; ++static const char * const tm2_groups[] = { ++ "gpio55", ++}; ++static const char * const atest_char1_groups[] = { ++ "gpio56", ++}; ++static const char * const tm_ack_groups[] = { ++ "gpio56", ++}; ++static const char * const wifi03_groups[] = { ++ "gpio56", ++}; ++static const char * const wifi13_groups[] = { ++ "gpio56", ++}; ++static const char * const qpic_pad4_groups[] = { ++ "gpio57", ++}; ++static const char * const atest_char0_groups[] = { ++ "gpio57", ++}; ++static const char * const tm3_groups[] = { ++ "gpio57", ++}; ++static const char * const wifi02_groups[] = { ++ "gpio57", ++}; ++static const char * const wifi12_groups[] = { ++ "gpio57", ++}; ++static const char * const qpic_pad5_groups[] = { ++ "gpio58", ++}; ++static const char * const smart3_groups[] = { ++ "gpio58", "gpio59", "gpio60", "gpio61", ++}; ++static const char * const wcss0_dbg14_groups[] = { ++ "gpio58", ++}; ++static const char * const tm4_groups[] = { ++ "gpio58", ++}; ++static const char * const wifi04_groups[] = { ++ "gpio58", ++}; ++static const char * const wifi14_groups[] = { ++ "gpio58", ++}; ++static const char * const qpic_pad6_groups[] = { ++ "gpio59", ++}; ++static const char * const wcss0_dbg15_groups[] = { ++ "gpio59", ++}; ++static const char * const qdss_tracectl_a_groups[] = { ++ "gpio59", ++}; ++static const char * const boot18_groups[] = { ++ "gpio59", ++}; ++static const char * const tm5_groups[] = { ++ "gpio59", ++}; ++static const char * const qpic_pad7_groups[] = { ++ "gpio60", ++}; ++static const char * const atest_char_groups[] = { ++ "gpio60", ++}; ++static const char * const wcss0_dbg4_groups[] = { ++ "gpio60", ++}; ++static const char * const qdss_traceclk_a_groups[] = { ++ "gpio60", ++}; ++static const char * const boot19_groups[] = { ++ "gpio60", ++}; ++static const char * const tm6_groups[] = { ++ "gpio60", ++}; ++static const char * const wcss0_dbg5_groups[] = { ++ "gpio61", ++}; ++static const char * const qdss_cti_trig_out_a0_groups[] = { ++ "gpio61", ++}; ++static const char * const boot14_groups[] = { ++ "gpio61", ++}; ++static const char * const tm7_groups[] = { ++ "gpio61", ++}; ++static const char * const chip_rst_groups[] = { ++ "gpio62", ++}; ++static const char * const wcss0_dbg6_groups[] = { ++ "gpio62", ++}; ++static const char * const qdss_cti_trig_out_b0_groups[] = { ++ "gpio62", ++}; ++static const char * const boot11_groups[] = { ++ "gpio62", ++}; ++static const char * const tm8_groups[] = { ++ "gpio62", ++}; ++static const char * const wcss0_dbg7_groups[] = { ++ "gpio63", ++}; ++static const char * const wcss1_dbg7_groups[] = { ++ "gpio63", ++}; ++static const char * const boot20_groups[] = { ++ "gpio63", ++}; ++static const char * const tm9_groups[] = { ++ "gpio63", ++}; ++static const char * const qpic_pad1_groups[] = { ++ "gpio64", ++}; ++static const char * const wcss0_dbg8_groups[] = { ++ "gpio64", ++}; ++static const char * const wcss1_dbg8_groups[] = { ++ "gpio64", ++}; ++static const char * const qpic_pad2_groups[] = { ++ "gpio65", ++}; ++static const char * const wcss0_dbg9_groups[] = { ++ "gpio65", ++}; ++static const char * const wcss1_dbg9_groups[] = { ++ "gpio65", ++}; ++static const char * const qpic_pad3_groups[] = { ++ "gpio66", ++}; ++static const char * const wcss0_dbg10_groups[] = { ++ "gpio66", ++}; ++static const char * const wcss1_dbg10_groups[] = { ++ "gpio66", ++}; ++static const char * const qpic_pad0_groups[] = { ++ "gpio67", ++}; ++static const char * const wcss0_dbg11_groups[] = { ++ "gpio67", ++}; ++static const char * const wcss1_dbg11_groups[] = { ++ "gpio67", ++}; ++static const char * const qpic_pad8_groups[] = { ++ "gpio68", ++}; ++static const char * const wcss0_dbg12_groups[] = { ++ "gpio68", ++}; ++static const char * const wcss1_dbg12_groups[] = { ++ "gpio68", ++}; ++static const char * const wifi034_groups[] = { ++ "gpio98", ++}; ++static const char * const wifi134_groups[] = { ++ "gpio98", ++}; ++static const char * const jtag_tdi_groups[] = { ++ "gpio0", ++}; + static const char * const gpio_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", + "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", +@@ -303,13 +818,103 @@ static const char * const gpio_groups[] + "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98", + "gpio99", + }; +- ++static const char * const i2s_rx_bclk_groups[] = { ++ "gpio0", "gpio21", "gpio60", ++}; ++static const char * const jtag_tck_groups[] = { ++ "gpio1", ++}; ++static const char * const i2s_rx_fsync_groups[] = { ++ "gpio1", "gpio22", "gpio61", ++}; ++static const char * const jtag_tms_groups[] = { ++ "gpio2", ++}; ++static const char * const i2s_rxd_groups[] = { ++ "gpio2", "gpio23", "gpio63", ++}; ++static const char * const smart0_groups[] = { ++ "gpio0", "gpio1", "gpio2", "gpio5", "gpio44", "gpio45", "gpio46", ++ "gpio47", ++}; ++static const char * const jtag_tdo_groups[] = { ++ "gpio3", ++}; ++static const char * const jtag_rst_groups[] = { ++ "gpio4", ++}; ++static const char * const jtag_trst_groups[] = { ++ "gpio5", ++}; ++static const char * const mdio0_groups[] = { ++ "gpio6", ++}; ++static const char * const wcss0_dbg18_groups[] = { ++ "gpio6", "gpio22", "gpio39", ++}; ++static const char * const wcss1_dbg18_groups[] = { ++ "gpio6", "gpio22", "gpio39", ++}; ++static const char * const qdss_tracedata_a_groups[] = { ++ "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11", "gpio16", ++ "gpio17", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", ++ "gpio43", ++}; ++static const char * const mdc_groups[] = { ++ "gpio7", "gpio52", ++}; ++static const char * const wcss0_dbg19_groups[] = { ++ "gpio7", "gpio23", "gpio40", ++}; ++static const char * const wcss1_dbg19_groups[] = { ++ "gpio7", "gpio23", "gpio40", ++}; + static const char * const blsp_uart1_groups[] = { + "gpio8", "gpio9", "gpio10", "gpio11", + }; ++static const char * const wifi0_uart_groups[] = { ++ "gpio8", "gpio9", "gpio11", "gpio19", "gpio62", ++}; ++static const char * const wifi1_uart_groups[] = { ++ "gpio8", "gpio11", "gpio19", "gpio62", "gpio63", ++}; ++static const char * const smart1_groups[] = { ++ "gpio8", "gpio9", "gpio16", "gpio17", "gpio58", "gpio59", "gpio60", ++ "gpio61", ++}; ++static const char * const wcss0_dbg20_groups[] = { ++ "gpio8", "gpio24", "gpio41", ++}; ++static const char * const wcss1_dbg20_groups[] = { ++ "gpio8", "gpio24", "gpio41", ++}; ++static const char * const wifi0_uart0_groups[] = { ++ "gpio9", "gpio10", ++}; ++static const char * const wifi1_uart0_groups[] = { ++ "gpio9", "gpio10", ++}; ++static const char * const wcss0_dbg21_groups[] = { ++ "gpio9", "gpio25", "gpio42", ++}; ++static const char * const wcss1_dbg21_groups[] = { ++ "gpio9", "gpio25", "gpio42", ++}; + static const char * const blsp_i2c0_groups[] = { + "gpio10", "gpio11", "gpio20", "gpio21", "gpio58", "gpio59", + }; ++static const char * const wcss0_dbg22_groups[] = { ++ "gpio10", "gpio26", "gpio43", ++}; ++static const char * const wcss1_dbg22_groups[] = { ++ "gpio10", "gpio26", "gpio43", ++}; ++static const char * const wcss0_dbg23_groups[] = { ++ "gpio11", "gpio27", "gpio44", ++}; ++static const char * const wcss1_dbg23_groups[] = { ++ "gpio11", "gpio27", "gpio44", ++}; + static const char * const blsp_spi0_groups[] = { + "gpio12", "gpio13", "gpio14", "gpio15", "gpio45", + "gpio54", "gpio55", "gpio56", "gpio57", +@@ -317,94 +922,582 @@ static const char * const blsp_spi0_grou + static const char * const blsp_i2c1_groups[] = { + "gpio12", "gpio13", "gpio34", "gpio35", + }; ++static const char * const wcss0_dbg24_groups[] = { ++ "gpio12", "gpio28", "gpio45", ++}; ++static const char * const wcss1_dbg24_groups[] = { ++ "gpio12", "gpio28", "gpio45", ++}; ++static const char * const wcss0_dbg25_groups[] = { ++ "gpio13", "gpio29", "gpio46", ++}; ++static const char * const wcss1_dbg25_groups[] = { ++ "gpio13", "gpio29", "gpio46", ++}; ++static const char * const wcss0_dbg26_groups[] = { ++ "gpio14", "gpio30", "gpio47", ++}; ++static const char * const wcss1_dbg26_groups[] = { ++ "gpio14", "gpio30", "gpio47", ++}; ++static const char * const wcss0_dbg_groups[] = { ++ "gpio15", "gpio69", ++}; ++static const char * const wcss1_dbg_groups[] = { ++ "gpio15", ++}; + static const char * const blsp_uart0_groups[] = { + "gpio16", "gpio17", "gpio60", "gpio61", + }; +-static const char * const blsp_spi1_groups[] = { +- "gpio44", "gpio45", "gpio46", "gpio47", ++static const char * const led0_groups[] = { ++ "gpio16", "gpio36", "gpio60", ++}; ++static const char * const wcss0_dbg28_groups[] = { ++ "gpio16", "gpio32", "gpio49", ++}; ++static const char * const wcss1_dbg28_groups[] = { ++ "gpio16", "gpio32", "gpio49", ++}; ++static const char * const led1_groups[] = { ++ "gpio17", "gpio37", "gpio61", ++}; ++static const char * const wcss0_dbg29_groups[] = { ++ "gpio17", "gpio33", "gpio50", ++}; ++static const char * const wcss1_dbg29_groups[] = { ++ "gpio17", "gpio33", "gpio50", ++}; ++static const char * const wifi0_uart1_groups[] = { ++ "gpio18", "gpio63", ++}; ++static const char * const wifi1_uart1_groups[] = { ++ "gpio18", "gpio63", ++}; ++static const char * const wcss0_dbg30_groups[] = { ++ "gpio18", "gpio34", "gpio51", ++}; ++static const char * const wcss1_dbg30_groups[] = { ++ "gpio18", "gpio34", "gpio51", ++}; ++static const char * const wcss0_dbg31_groups[] = { ++ "gpio19", "gpio35", "gpio52", ++}; ++static const char * const wcss1_dbg31_groups[] = { ++ "gpio19", "gpio35", ++}; ++static const char * const i2s_rx_mclk_groups[] = { ++ "gpio20", "gpio58", ++}; ++static const char * const wcss0_dbg16_groups[] = { ++ "gpio20", "gpio37", ++}; ++static const char * const wcss1_dbg16_groups[] = { ++ "gpio20", "gpio37", ++}; ++static const char * const wcss0_dbg17_groups[] = { ++ "gpio21", "gpio38", ++}; ++static const char * const wcss1_dbg17_groups[] = { ++ "gpio21", "gpio38", ++}; ++static const char * const rgmii0_groups[] = { ++ "gpio22", "gpio28", ++}; ++static const char * const sdio0_groups[] = { ++ "gpio23", ++}; ++static const char * const rgmii1_groups[] = { ++ "gpio23", "gpio29", ++}; ++static const char * const sdio1_groups[] = { ++ "gpio24", ++}; ++static const char * const rgmii2_groups[] = { ++ "gpio24", "gpio30", ++}; ++static const char * const i2s_tx_mclk_groups[] = { ++ "gpio24", "gpio52", ++}; ++static const char * const sdio2_groups[] = { ++ "gpio25", ++}; ++static const char * const rgmii3_groups[] = { ++ "gpio25", "gpio31", ++}; ++static const char * const i2s_tx_bclk_groups[] = { ++ "gpio25", "gpio53", "gpio60", ++}; ++static const char * const sdio3_groups[] = { ++ "gpio26", ++}; ++static const char * const rgmii_rx_groups[] = { ++ "gpio26", ++}; ++static const char * const i2s_tx_fsync_groups[] = { ++ "gpio26", "gpio57", "gpio61", ++}; ++static const char * const sdio_clk_groups[] = { ++ "gpio27", ++}; ++static const char * const rgmii_txc_groups[] = { ++ "gpio27", ++}; ++static const char * const i2s_td1_groups[] = { ++ "gpio27", "gpio54", "gpio63", ++}; ++static const char * const sdio_cmd_groups[] = { ++ "gpio28", ++}; ++static const char * const i2s_td2_groups[] = { ++ "gpio28", "gpio55", ++}; ++static const char * const sdio4_groups[] = { ++ "gpio29", ++}; ++static const char * const i2s_td3_groups[] = { ++ "gpio29", "gpio56", ++}; ++static const char * const sdio5_groups[] = { ++ "gpio30", ++}; ++static const char * const audio_pwm0_groups[] = { ++ "gpio30", "gpio64", ++}; ++static const char * const sdio6_groups[] = { ++ "gpio31", ++}; ++static const char * const audio_pwm1_groups[] = { ++ "gpio31", "gpio65", ++}; ++static const char * const wcss0_dbg27_groups[] = { ++ "gpio31", "gpio48", ++}; ++static const char * const wcss1_dbg27_groups[] = { ++ "gpio31", "gpio48", ++}; ++static const char * const sdio7_groups[] = { ++ "gpio32", ++}; ++static const char * const rgmii_rxc_groups[] = { ++ "gpio32", ++}; ++static const char * const audio_pwm2_groups[] = { ++ "gpio32", "gpio66", ++}; ++static const char * const rgmii_tx_groups[] = { ++ "gpio33", ++}; ++static const char * const audio_pwm3_groups[] = { ++ "gpio33", "gpio67", ++}; ++static const char * const boot2_groups[] = { ++ "gpio33", ++}; ++static const char * const i2s_spdif_in_groups[] = { ++ "gpio34", "gpio59", "gpio63", ++}; ++static const char * const i2s_spdif_out_groups[] = { ++ "gpio35", "gpio62", "gpio63", ++}; ++static const char * const rmii00_groups[] = { ++ "gpio36", "gpio41", ++}; ++static const char * const led2_groups[] = { ++ "gpio36", "gpio38", "gpio58", ++}; ++static const char * const rmii01_groups[] = { ++ "gpio37", "gpio42", ++}; ++static const char * const wifi0_wci_groups[] = { ++ "gpio37", ++}; ++static const char * const wifi1_wci_groups[] = { ++ "gpio37", ++}; ++static const char * const boot4_groups[] = { ++ "gpio37", ++}; ++static const char * const rmii0_tx_groups[] = { ++ "gpio38", ++}; ++static const char * const boot5_groups[] = { ++ "gpio38", ++}; ++static const char * const rmii0_rx_groups[] = { ++ "gpio39", ++}; ++static const char * const pcie_clk1_groups[] = { ++ "gpio39", ++}; ++static const char * const led3_groups[] = { ++ "gpio39", ++}; ++static const char * const sdio_cd_groups[] = { ++ "gpio22", + }; + + static const struct msm_function ipq4019_functions[] = { ++ FUNCTION(rmii0_refclk), ++ FUNCTION(wifi0_rfsilient0), ++ FUNCTION(wifi1_rfsilient0), ++ FUNCTION(smart2), ++ FUNCTION(led4), ++ FUNCTION(wifi0_cal), ++ FUNCTION(wifi1_cal), ++ FUNCTION(wifi_wci0), ++ FUNCTION(rmii0_dv), ++ FUNCTION(wifi_wci1), ++ FUNCTION(rmii1_refclk), ++ FUNCTION(blsp_spi1), ++ FUNCTION(led5), ++ FUNCTION(rmii10), ++ FUNCTION(led6), ++ FUNCTION(rmii11), ++ FUNCTION(led7), ++ FUNCTION(rmii1_dv), ++ FUNCTION(led8), ++ FUNCTION(rmii1_tx), ++ FUNCTION(aud_pin), ++ FUNCTION(led9), ++ FUNCTION(rmii1_rx), ++ FUNCTION(led10), ++ FUNCTION(wifi0_rfsilient1), ++ FUNCTION(wifi1_rfsilient1), ++ FUNCTION(led11), ++ FUNCTION(boot7), ++ FUNCTION(qpic_pad), ++ FUNCTION(pcie_clk), ++ FUNCTION(tm_clk0), ++ FUNCTION(wifi00), ++ FUNCTION(wifi10), ++ FUNCTION(mdio1), ++ FUNCTION(prng_rosc), ++ FUNCTION(dbg_out), ++ FUNCTION(tm0), ++ FUNCTION(wifi01), ++ FUNCTION(wifi11), ++ FUNCTION(atest_char3), ++ FUNCTION(pmu0), ++ FUNCTION(boot8), ++ FUNCTION(tm1), ++ FUNCTION(atest_char2), ++ FUNCTION(pmu1), ++ FUNCTION(boot9), ++ FUNCTION(tm2), ++ FUNCTION(atest_char1), ++ FUNCTION(tm_ack), ++ FUNCTION(wifi03), ++ FUNCTION(wifi13), ++ FUNCTION(qpic_pad4), ++ FUNCTION(atest_char0), ++ FUNCTION(tm3), ++ FUNCTION(wifi02), ++ FUNCTION(wifi12), ++ FUNCTION(qpic_pad5), ++ FUNCTION(smart3), ++ FUNCTION(wcss0_dbg14), ++ FUNCTION(tm4), ++ FUNCTION(wifi04), ++ FUNCTION(wifi14), ++ FUNCTION(qpic_pad6), ++ FUNCTION(wcss0_dbg15), ++ FUNCTION(qdss_tracectl_a), ++ FUNCTION(boot18), ++ FUNCTION(tm5), ++ FUNCTION(qpic_pad7), ++ FUNCTION(atest_char), ++ FUNCTION(wcss0_dbg4), ++ FUNCTION(qdss_traceclk_a), ++ FUNCTION(boot19), ++ FUNCTION(tm6), ++ FUNCTION(wcss0_dbg5), ++ FUNCTION(qdss_cti_trig_out_a0), ++ FUNCTION(boot14), ++ FUNCTION(tm7), ++ FUNCTION(chip_rst), ++ FUNCTION(wcss0_dbg6), ++ FUNCTION(qdss_cti_trig_out_b0), ++ FUNCTION(boot11), ++ FUNCTION(tm8), ++ FUNCTION(wcss0_dbg7), ++ FUNCTION(wcss1_dbg7), ++ FUNCTION(boot20), ++ FUNCTION(tm9), ++ FUNCTION(qpic_pad1), ++ FUNCTION(wcss0_dbg8), ++ FUNCTION(wcss1_dbg8), ++ FUNCTION(qpic_pad2), ++ FUNCTION(wcss0_dbg9), ++ FUNCTION(wcss1_dbg9), ++ FUNCTION(qpic_pad3), ++ FUNCTION(wcss0_dbg10), ++ FUNCTION(wcss1_dbg10), ++ FUNCTION(qpic_pad0), ++ FUNCTION(wcss0_dbg11), ++ FUNCTION(wcss1_dbg11), ++ FUNCTION(qpic_pad8), ++ FUNCTION(wcss0_dbg12), ++ FUNCTION(wcss1_dbg12), ++ FUNCTION(wifi034), ++ FUNCTION(wifi134), ++ FUNCTION(jtag_tdi), + FUNCTION(gpio), ++ FUNCTION(i2s_rx_bclk), ++ FUNCTION(jtag_tck), ++ FUNCTION(i2s_rx_fsync), ++ FUNCTION(jtag_tms), ++ FUNCTION(i2s_rxd), ++ FUNCTION(smart0), ++ FUNCTION(jtag_tdo), ++ FUNCTION(jtag_rst), ++ FUNCTION(jtag_trst), ++ FUNCTION(mdio0), ++ FUNCTION(wcss0_dbg18), ++ FUNCTION(wcss1_dbg18), ++ FUNCTION(qdss_tracedata_a), ++ FUNCTION(mdc), ++ FUNCTION(wcss0_dbg19), ++ FUNCTION(wcss1_dbg19), + FUNCTION(blsp_uart1), ++ FUNCTION(wifi0_uart), ++ FUNCTION(wifi1_uart), ++ FUNCTION(smart1), ++ FUNCTION(wcss0_dbg20), ++ FUNCTION(wcss1_dbg20), ++ FUNCTION(wifi0_uart0), ++ FUNCTION(wifi1_uart0), ++ FUNCTION(wcss0_dbg21), ++ FUNCTION(wcss1_dbg21), + FUNCTION(blsp_i2c0), ++ FUNCTION(wcss0_dbg22), ++ FUNCTION(wcss1_dbg22), ++ FUNCTION(wcss0_dbg23), ++ FUNCTION(wcss1_dbg23), ++ FUNCTION(blsp_spi0), + FUNCTION(blsp_i2c1), ++ FUNCTION(wcss0_dbg24), ++ FUNCTION(wcss1_dbg24), ++ FUNCTION(wcss0_dbg25), ++ FUNCTION(wcss1_dbg25), ++ FUNCTION(wcss0_dbg26), ++ FUNCTION(wcss1_dbg26), ++ FUNCTION(wcss0_dbg), ++ FUNCTION(wcss1_dbg), + FUNCTION(blsp_uart0), +- FUNCTION(blsp_spi1), +- FUNCTION(blsp_spi0), ++ FUNCTION(led0), ++ FUNCTION(wcss0_dbg28), ++ FUNCTION(wcss1_dbg28), ++ FUNCTION(led1), ++ FUNCTION(wcss0_dbg29), ++ FUNCTION(wcss1_dbg29), ++ FUNCTION(wifi0_uart1), ++ FUNCTION(wifi1_uart1), ++ FUNCTION(wcss0_dbg30), ++ FUNCTION(wcss1_dbg30), ++ FUNCTION(wcss0_dbg31), ++ FUNCTION(wcss1_dbg31), ++ FUNCTION(i2s_rx_mclk), ++ FUNCTION(wcss0_dbg16), ++ FUNCTION(wcss1_dbg16), ++ FUNCTION(wcss0_dbg17), ++ FUNCTION(wcss1_dbg17), ++ FUNCTION(rgmii0), ++ FUNCTION(sdio0), ++ FUNCTION(rgmii1), ++ FUNCTION(sdio1), ++ FUNCTION(rgmii2), ++ FUNCTION(i2s_tx_mclk), ++ FUNCTION(sdio2), ++ FUNCTION(rgmii3), ++ FUNCTION(i2s_tx_bclk), ++ FUNCTION(sdio3), ++ FUNCTION(rgmii_rx), ++ FUNCTION(i2s_tx_fsync), ++ FUNCTION(sdio_clk), ++ FUNCTION(rgmii_txc), ++ FUNCTION(i2s_td1), ++ FUNCTION(sdio_cmd), ++ FUNCTION(i2s_td2), ++ FUNCTION(sdio4), ++ FUNCTION(i2s_td3), ++ FUNCTION(sdio5), ++ FUNCTION(audio_pwm0), ++ FUNCTION(sdio6), ++ FUNCTION(audio_pwm1), ++ FUNCTION(wcss0_dbg27), ++ FUNCTION(wcss1_dbg27), ++ FUNCTION(sdio7), ++ FUNCTION(rgmii_rxc), ++ FUNCTION(audio_pwm2), ++ FUNCTION(rgmii_tx), ++ FUNCTION(audio_pwm3), ++ FUNCTION(boot2), ++ FUNCTION(i2s_spdif_in), ++ FUNCTION(i2s_spdif_out), ++ FUNCTION(rmii00), ++ FUNCTION(led2), ++ FUNCTION(rmii01), ++ FUNCTION(wifi0_wci), ++ FUNCTION(wifi1_wci), ++ FUNCTION(boot4), ++ FUNCTION(rmii0_tx), ++ FUNCTION(boot5), ++ FUNCTION(rmii0_rx), ++ FUNCTION(pcie_clk1), ++ FUNCTION(led3), ++ FUNCTION(sdio_cd), + }; + + static const struct msm_pingroup ipq4019_groups[] = { +- PINGROUP(0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(5, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(6, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(7, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(8, blsp_uart1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(9, blsp_uart1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(10, blsp_uart1, NA, NA, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(11, blsp_uart1, NA, NA, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(12, blsp_spi0, blsp_i2c1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(13, blsp_spi0, blsp_i2c1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(14, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(15, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(16, blsp_uart0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(17, blsp_uart0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(18, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(19, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(20, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(21, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(22, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(23, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(24, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(25, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(26, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(27, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(28, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(29, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(30, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(31, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(32, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(33, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(34, blsp_i2c1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(35, blsp_i2c1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(36, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(37, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(38, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(39, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(40, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(41, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(42, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(43, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(44, NA, blsp_spi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(45, NA, blsp_spi1, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(46, NA, blsp_spi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(47, NA, blsp_spi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(48, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(49, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(50, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(51, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(52, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(53, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(54, NA, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(55, NA, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(56, NA, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(57, NA, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(58, NA, NA, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(59, NA, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(60, NA, blsp_uart0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(61, NA, blsp_uart0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(62, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(63, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(64, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(65, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(66, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(67, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(68, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(69, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(0, jtag_tdi, smart0, i2s_rx_bclk, NA, NA, NA, NA, NA, NA, NA, ++ NA, NA, NA, NA), ++ PINGROUP(1, jtag_tck, smart0, i2s_rx_fsync, NA, NA, NA, NA, NA, NA, NA, ++ NA, NA, NA, NA), ++ PINGROUP(2, jtag_tms, smart0, i2s_rxd, NA, NA, NA, NA, NA, NA, NA, NA, ++ NA, NA, NA), ++ PINGROUP(3, jtag_tdo, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ++ NA), ++ PINGROUP(4, jtag_rst, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ++ NA), ++ PINGROUP(5, jtag_trst, smart0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ++ NA, NA), ++ PINGROUP(6, mdio0, NA, wcss0_dbg18, wcss1_dbg18, NA, qdss_tracedata_a, ++ NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(7, mdc, NA, wcss0_dbg19, wcss1_dbg19, NA, qdss_tracedata_a, ++ NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(8, blsp_uart1, wifi0_uart, wifi1_uart, smart1, NA, ++ wcss0_dbg20, wcss1_dbg20, NA, qdss_tracedata_a, NA, NA, NA, ++ NA, NA), ++ PINGROUP(9, blsp_uart1, wifi0_uart0, wifi1_uart0, smart1, wifi0_uart, ++ NA, wcss0_dbg21, wcss1_dbg21, NA, qdss_tracedata_a, NA, NA, ++ NA, NA), ++ PINGROUP(10, blsp_uart1, wifi0_uart0, wifi1_uart0, blsp_i2c0, NA, ++ wcss0_dbg22, wcss1_dbg22, NA, qdss_tracedata_a, NA, NA, NA, ++ NA, NA), ++ PINGROUP(11, blsp_uart1, wifi0_uart, wifi1_uart, blsp_i2c0, NA, ++ wcss0_dbg23, wcss1_dbg23, NA, qdss_tracedata_a, NA, NA, NA, ++ NA, NA), ++ PINGROUP(12, blsp_spi0, blsp_i2c1, NA, wcss0_dbg24, wcss1_dbg24, NA, ++ NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(13, blsp_spi0, blsp_i2c1, NA, wcss0_dbg25, wcss1_dbg25, NA, ++ NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(14, blsp_spi0, NA, wcss0_dbg26, wcss1_dbg26, NA, NA, NA, NA, ++ NA, NA, NA, NA, NA, NA), ++ PINGROUP(15, blsp_spi0, NA, wcss0_dbg, wcss1_dbg, NA, NA, NA, NA, NA, ++ NA, NA, NA, NA, NA), ++ PINGROUP(16, blsp_uart0, led0, smart1, NA, wcss0_dbg28, wcss1_dbg28, ++ NA, qdss_tracedata_a, NA, NA, NA, NA, NA, NA), ++ PINGROUP(17, blsp_uart0, led1, smart1, NA, wcss0_dbg29, wcss1_dbg29, ++ NA, qdss_tracedata_a, NA, NA, NA, NA, NA, NA), ++ PINGROUP(18, wifi0_uart1, wifi1_uart1, NA, wcss0_dbg30, wcss1_dbg30, ++ NA, NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(19, wifi0_uart, wifi1_uart, NA, wcss0_dbg31, wcss1_dbg31, NA, ++ NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(20, blsp_i2c0, i2s_rx_mclk, NA, wcss0_dbg16, wcss1_dbg16, NA, ++ NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(21, blsp_i2c0, i2s_rx_bclk, NA, wcss0_dbg17, wcss1_dbg17, NA, ++ NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(22, rgmii0, i2s_rx_fsync, NA, wcss0_dbg18, wcss1_dbg18, NA, ++ NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(23, sdio0, rgmii1, i2s_rxd, NA, wcss0_dbg19, wcss1_dbg19, NA, ++ NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(24, sdio1, rgmii2, i2s_tx_mclk, NA, wcss0_dbg20, wcss1_dbg20, ++ NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(25, sdio2, rgmii3, i2s_tx_bclk, NA, wcss0_dbg21, wcss1_dbg21, ++ NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(26, sdio3, rgmii_rx, i2s_tx_fsync, NA, wcss0_dbg22, ++ wcss1_dbg22, NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(27, sdio_clk, rgmii_txc, i2s_td1, NA, wcss0_dbg23, ++ wcss1_dbg23, NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(28, sdio_cmd, rgmii0, i2s_td2, NA, wcss0_dbg24, wcss1_dbg24, ++ NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(29, sdio4, rgmii1, i2s_td3, NA, wcss0_dbg25, wcss1_dbg25, NA, ++ NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(30, sdio5, rgmii2, audio_pwm0, NA, wcss0_dbg26, wcss1_dbg26, ++ NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(31, sdio6, rgmii3, audio_pwm1, NA, wcss0_dbg27, wcss1_dbg27, ++ NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(32, sdio7, rgmii_rxc, audio_pwm2, NA, wcss0_dbg28, ++ wcss1_dbg28, NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(33, rgmii_tx, audio_pwm3, NA, wcss0_dbg29, wcss1_dbg29, NA, ++ boot2, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(34, blsp_i2c1, i2s_spdif_in, NA, wcss0_dbg30, wcss1_dbg30, NA, ++ NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(35, blsp_i2c1, i2s_spdif_out, NA, wcss0_dbg31, wcss1_dbg31, ++ NA, NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(36, rmii00, led2, led0, NA, NA, NA, NA, NA, NA, NA, NA, NA, ++ NA, NA), ++ PINGROUP(37, rmii01, wifi0_wci, wifi1_wci, led1, NA, NA, wcss0_dbg16, ++ wcss1_dbg16, NA, qdss_tracedata_a, boot4, NA, NA, NA), ++ PINGROUP(38, rmii0_tx, led2, NA, NA, wcss0_dbg17, wcss1_dbg17, NA, ++ qdss_tracedata_a, boot5, NA, NA, NA, NA, NA), ++ PINGROUP(39, rmii0_rx, pcie_clk1, led3, NA, NA, wcss0_dbg18, ++ wcss1_dbg18, NA, NA, qdss_tracedata_a, NA, NA, NA, NA), ++ PINGROUP(40, rmii0_refclk, wifi0_rfsilient0, wifi1_rfsilient0, smart2, ++ led4, NA, NA, wcss0_dbg19, wcss1_dbg19, NA, NA, ++ qdss_tracedata_a, NA, NA), ++ PINGROUP(41, rmii00, wifi0_cal, wifi1_cal, smart2, NA, NA, wcss0_dbg20, ++ wcss1_dbg20, NA, NA, qdss_tracedata_a, NA, NA, NA), ++ PINGROUP(42, rmii01, wifi_wci0, NA, NA, wcss0_dbg21, wcss1_dbg21, NA, ++ NA, qdss_tracedata_a, NA, NA, NA, NA, NA), ++ PINGROUP(43, rmii0_dv, wifi_wci1, NA, NA, wcss0_dbg22, wcss1_dbg22, NA, ++ NA, qdss_tracedata_a, NA, NA, NA, NA, NA), ++ PINGROUP(44, rmii1_refclk, blsp_spi1, smart0, led5, NA, NA, ++ wcss0_dbg23, wcss1_dbg23, NA, NA, NA, NA, NA, NA), ++ PINGROUP(45, rmii10, blsp_spi1, blsp_spi0, smart0, led6, NA, NA, ++ wcss0_dbg24, wcss1_dbg24, NA, NA, NA, NA, NA), ++ PINGROUP(46, rmii11, blsp_spi1, smart0, led7, NA, NA, wcss0_dbg25, ++ wcss1_dbg25, NA, NA, NA, NA, NA, NA), ++ PINGROUP(47, rmii1_dv, blsp_spi1, smart0, led8, NA, NA, wcss0_dbg26, ++ wcss1_dbg26, NA, NA, NA, NA, NA, NA), ++ PINGROUP(48, rmii1_tx, aud_pin, smart2, led9, NA, NA, wcss0_dbg27, ++ wcss1_dbg27, NA, NA, NA, NA, NA, NA), ++ PINGROUP(49, rmii1_rx, aud_pin, smart2, led10, NA, NA, wcss0_dbg28, ++ wcss1_dbg28, NA, NA, NA, NA, NA, NA), ++ PINGROUP(50, rmii10, aud_pin, wifi0_rfsilient1, wifi1_rfsilient1, ++ led11, NA, NA, wcss0_dbg29, wcss1_dbg29, NA, NA, NA, NA, NA), ++ PINGROUP(51, rmii11, aud_pin, wifi0_cal, wifi1_cal, NA, NA, ++ wcss0_dbg30, wcss1_dbg30, NA, boot7, NA, NA, NA, NA), ++ PINGROUP(52, qpic_pad, mdc, pcie_clk, i2s_tx_mclk, NA, NA, wcss0_dbg31, ++ tm_clk0, wifi00, wifi10, NA, NA, NA, NA), ++ PINGROUP(53, qpic_pad, mdio1, i2s_tx_bclk, prng_rosc, dbg_out, tm0, ++ wifi01, wifi11, NA, NA, NA, NA, NA, NA), ++ PINGROUP(54, qpic_pad, blsp_spi0, i2s_td1, atest_char3, pmu0, NA, NA, ++ boot8, tm1, NA, NA, NA, NA, NA), ++ PINGROUP(55, qpic_pad, blsp_spi0, i2s_td2, atest_char2, pmu1, NA, NA, ++ boot9, tm2, NA, NA, NA, NA, NA), ++ PINGROUP(56, qpic_pad, blsp_spi0, i2s_td3, atest_char1, NA, tm_ack, ++ wifi03, wifi13, NA, NA, NA, NA, NA, NA), ++ PINGROUP(57, qpic_pad4, blsp_spi0, i2s_tx_fsync, atest_char0, NA, tm3, ++ wifi02, wifi12, NA, NA, NA, NA, NA, NA), ++ PINGROUP(58, qpic_pad5, led2, blsp_i2c0, smart3, smart1, i2s_rx_mclk, ++ NA, wcss0_dbg14, tm4, wifi04, wifi14, NA, NA, NA), ++ PINGROUP(59, qpic_pad6, blsp_i2c0, smart3, smart1, i2s_spdif_in, NA, ++ NA, wcss0_dbg15, qdss_tracectl_a, boot18, tm5, NA, NA, NA), ++ PINGROUP(60, qpic_pad7, blsp_uart0, smart1, smart3, led0, i2s_tx_bclk, ++ i2s_rx_bclk, atest_char, NA, wcss0_dbg4, qdss_traceclk_a, ++ boot19, tm6, NA), ++ PINGROUP(61, qpic_pad, blsp_uart0, smart1, smart3, led1, i2s_tx_fsync, ++ i2s_rx_fsync, NA, NA, wcss0_dbg5, qdss_cti_trig_out_a0, ++ boot14, tm7, NA), ++ PINGROUP(62, qpic_pad, chip_rst, wifi0_uart, wifi1_uart, i2s_spdif_out, ++ NA, NA, wcss0_dbg6, qdss_cti_trig_out_b0, boot11, tm8, NA, NA, ++ NA), ++ PINGROUP(63, qpic_pad, wifi0_uart1, wifi1_uart1, wifi1_uart, i2s_td1, ++ i2s_rxd, i2s_spdif_out, i2s_spdif_in, NA, wcss0_dbg7, ++ wcss1_dbg7, boot20, tm9, NA), ++ PINGROUP(64, qpic_pad1, audio_pwm0, NA, wcss0_dbg8, wcss1_dbg8, NA, NA, ++ NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(65, qpic_pad2, audio_pwm1, NA, wcss0_dbg9, wcss1_dbg9, NA, NA, ++ NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(66, qpic_pad3, audio_pwm2, NA, wcss0_dbg10, wcss1_dbg10, NA, ++ NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(67, qpic_pad0, audio_pwm3, NA, wcss0_dbg11, wcss1_dbg11, NA, ++ NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(68, qpic_pad8, NA, wcss0_dbg12, wcss1_dbg12, NA, NA, NA, NA, ++ NA, NA, NA, NA, NA, NA), ++ PINGROUP(69, qpic_pad, NA, wcss0_dbg, NA, NA, NA, NA, NA, NA, NA, NA, ++ NA, NA, NA), + PINGROUP(70, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(71, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(72, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +@@ -433,7 +1526,8 @@ static const struct msm_pingroup ipq4019 + PINGROUP(95, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(96, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(97, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +- PINGROUP(98, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), ++ PINGROUP(98, wifi034, wifi134, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ++ NA, NA), + PINGROUP(99, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + }; + +@@ -460,6 +1554,7 @@ static const struct of_device_id ipq4019 + static struct platform_driver ipq4019_pinctrl_driver = { + .driver = { + .name = "ipq4019-pinctrl", ++ .owner = THIS_MODULE, + .of_match_table = ipq4019_pinctrl_of_match, + }, + .probe = ipq4019_pinctrl_probe, diff --git a/target/linux/ipq806x/patches-4.9/859-msm-pinctrl-Add-support-to-configure-ipq40xx-GPIO_PU.patch b/target/linux/ipq806x/patches-4.9/859-msm-pinctrl-Add-support-to-configure-ipq40xx-GPIO_PU.patch new file mode 100644 index 000000000..07cf01b26 --- /dev/null +++ b/target/linux/ipq806x/patches-4.9/859-msm-pinctrl-Add-support-to-configure-ipq40xx-GPIO_PU.patch @@ -0,0 +1,236 @@ +From e77af7de404eb464f7da9e0daeb8b362cc66a7ba Mon Sep 17 00:00:00 2001 +From: Ram Chandra Jangir +Date: Tue, 9 May 2017 11:45:00 +0530 +Subject: [PATCH] msm: pinctrl: Add support to configure ipq40xx GPIO_PULL bits + +GPIO_PULL bits configurations in TLMM_GPIO_CFG register +differs for IPQ40xx from rest of the other qcom SoC's. +This change add support to configure the msm_gpio_pull +bits for ipq40xx, It is required to fix the proper +configurations of gpio-pull bits for nand pins mux. + +IPQ40xx SoC: +2'b10: Internal pull up enable. +2'b11: Unsupport + +For other SoC's: +2'b10: Keeper +2'b11: Pull-Up + +Signed-off-by: Ram Chandra Jangir +--- + drivers/pinctrl/qcom/pinctrl-apq8064.c | 1 + + drivers/pinctrl/qcom/pinctrl-apq8084.c | 1 + + drivers/pinctrl/qcom/pinctrl-ipq4019.c | 8 ++++++++ + drivers/pinctrl/qcom/pinctrl-ipq8064.c | 1 + + drivers/pinctrl/qcom/pinctrl-mdm9615.c | 1 + + drivers/pinctrl/qcom/pinctrl-msm.c | 21 ++++++++------------- + drivers/pinctrl/qcom/pinctrl-msm.h | 19 +++++++++++++++++++ + drivers/pinctrl/qcom/pinctrl-msm8660.c | 1 + + drivers/pinctrl/qcom/pinctrl-msm8916.c | 1 + + drivers/pinctrl/qcom/pinctrl-msm8960.c | 1 + + drivers/pinctrl/qcom/pinctrl-msm8x74.c | 1 + + 11 files changed, 43 insertions(+), 13 deletions(-) + +--- a/drivers/pinctrl/qcom/pinctrl-apq8064.c ++++ b/drivers/pinctrl/qcom/pinctrl-apq8064.c +@@ -597,6 +597,7 @@ static const struct msm_pinctrl_soc_data + .groups = apq8064_groups, + .ngroups = ARRAY_SIZE(apq8064_groups), + .ngpios = NUM_GPIO_PINGROUPS, ++ .gpio_pull = &msm_gpio_pull, + }; + + static int apq8064_pinctrl_probe(struct platform_device *pdev) +--- a/drivers/pinctrl/qcom/pinctrl-apq8084.c ++++ b/drivers/pinctrl/qcom/pinctrl-apq8084.c +@@ -1206,6 +1206,7 @@ static const struct msm_pinctrl_soc_data + .groups = apq8084_groups, + .ngroups = ARRAY_SIZE(apq8084_groups), + .ngpios = NUM_GPIO_PINGROUPS, ++ .gpio_pull = &msm_gpio_pull, + }; + + static int apq8084_pinctrl_probe(struct platform_device *pdev) +--- a/drivers/pinctrl/qcom/pinctrl-ipq4019.c ++++ b/drivers/pinctrl/qcom/pinctrl-ipq4019.c +@@ -1531,6 +1531,13 @@ static const struct msm_pingroup ipq4019 + PINGROUP(99, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + }; + ++static const struct msm_pinctrl_gpio_pull ipq4019_gpio_pull = { ++ .no_pull = 0, ++ .pull_down = 1, ++ .keeper = 0, ++ .pull_up = 2, ++}; ++ + static const struct msm_pinctrl_soc_data ipq4019_pinctrl = { + .pins = ipq4019_pins, + .npins = ARRAY_SIZE(ipq4019_pins), +@@ -1539,6 +1546,7 @@ static const struct msm_pinctrl_soc_data + .groups = ipq4019_groups, + .ngroups = ARRAY_SIZE(ipq4019_groups), + .ngpios = 100, ++ .gpio_pull = &ipq4019_gpio_pull, + }; + + static int ipq4019_pinctrl_probe(struct platform_device *pdev) +--- a/drivers/pinctrl/qcom/pinctrl-ipq8064.c ++++ b/drivers/pinctrl/qcom/pinctrl-ipq8064.c +@@ -630,6 +630,7 @@ static const struct msm_pinctrl_soc_data + .groups = ipq8064_groups, + .ngroups = ARRAY_SIZE(ipq8064_groups), + .ngpios = NUM_GPIO_PINGROUPS, ++ .gpio_pull = &msm_gpio_pull, + }; + + static int ipq8064_pinctrl_probe(struct platform_device *pdev) +--- a/drivers/pinctrl/qcom/pinctrl-mdm9615.c ++++ b/drivers/pinctrl/qcom/pinctrl-mdm9615.c +@@ -444,6 +444,7 @@ static const struct msm_pinctrl_soc_data + .groups = mdm9615_groups, + .ngroups = ARRAY_SIZE(mdm9615_groups), + .ngpios = NUM_GPIO_PINGROUPS, ++ .gpio_pull = &msm_gpio_pull, + }; + + static int mdm9615_pinctrl_probe(struct platform_device *pdev) +--- a/drivers/pinctrl/qcom/pinctrl-msm.c ++++ b/drivers/pinctrl/qcom/pinctrl-msm.c +@@ -203,11 +203,6 @@ static int msm_config_reg(struct msm_pin + return 0; + } + +-#define MSM_NO_PULL 0 +-#define MSM_PULL_DOWN 1 +-#define MSM_KEEPER 2 +-#define MSM_PULL_UP 3 +- + static unsigned msm_regval_to_drive(u32 val) + { + return (val + 1) * 2; +@@ -238,16 +233,16 @@ static int msm_config_group_get(struct p + /* Convert register value to pinconf value */ + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: +- arg = arg == MSM_NO_PULL; ++ arg = arg == pctrl->soc->gpio_pull->no_pull; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: +- arg = arg == MSM_PULL_DOWN; ++ arg = arg == pctrl->soc->gpio_pull->pull_down; + break; + case PIN_CONFIG_BIAS_BUS_HOLD: +- arg = arg == MSM_KEEPER; ++ arg = arg == pctrl->soc->gpio_pull->keeper; + break; + case PIN_CONFIG_BIAS_PULL_UP: +- arg = arg == MSM_PULL_UP; ++ arg = arg == pctrl->soc->gpio_pull->pull_up; + break; + case PIN_CONFIG_DRIVE_STRENGTH: + arg = msm_regval_to_drive(arg); +@@ -304,16 +299,16 @@ static int msm_config_group_set(struct p + /* Convert pinconf values to register values */ + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: +- arg = MSM_NO_PULL; ++ arg = pctrl->soc->gpio_pull->no_pull; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: +- arg = MSM_PULL_DOWN; ++ arg = pctrl->soc->gpio_pull->pull_down; + break; + case PIN_CONFIG_BIAS_BUS_HOLD: +- arg = MSM_KEEPER; ++ arg = pctrl->soc->gpio_pull->keeper; + break; + case PIN_CONFIG_BIAS_PULL_UP: +- arg = MSM_PULL_UP; ++ arg = pctrl->soc->gpio_pull->pull_up; + break; + case PIN_CONFIG_DRIVE_STRENGTH: + /* Check for invalid values */ +--- a/drivers/pinctrl/qcom/pinctrl-msm.h ++++ b/drivers/pinctrl/qcom/pinctrl-msm.h +@@ -98,6 +98,16 @@ struct msm_pingroup { + }; + + /** ++ * struct msm_pinctrl_gpio_pull - pinctrl pull value bit field descriptor ++ */ ++struct msm_pinctrl_gpio_pull { ++ unsigned no_pull; ++ unsigned pull_down; ++ unsigned keeper; ++ unsigned pull_up; ++}; ++ ++/** + * struct msm_pinctrl_soc_data - Qualcomm pin controller driver configuration + * @pins: An array describing all pins the pin controller affects. + * @npins: The number of entries in @pins. +@@ -106,6 +116,7 @@ struct msm_pingroup { + * @groups: An array describing all pin groups the pin SoC supports. + * @ngroups: The numbmer of entries in @groups. + * @ngpio: The number of pingroups the driver should expose as GPIOs. ++ * @gpio_pull_val: The pull value bit field descriptor. + */ + struct msm_pinctrl_soc_data { + const struct pinctrl_pin_desc *pins; +@@ -115,6 +126,14 @@ struct msm_pinctrl_soc_data { + const struct msm_pingroup *groups; + unsigned ngroups; + unsigned ngpios; ++ const struct msm_pinctrl_gpio_pull *gpio_pull; ++}; ++ ++static const struct msm_pinctrl_gpio_pull msm_gpio_pull = { ++ .no_pull = 0, ++ .pull_down = 1, ++ .keeper = 2, ++ .pull_up = 3, + }; + + int msm_pinctrl_probe(struct platform_device *pdev, +--- a/drivers/pinctrl/qcom/pinctrl-msm8660.c ++++ b/drivers/pinctrl/qcom/pinctrl-msm8660.c +@@ -979,6 +979,7 @@ static const struct msm_pinctrl_soc_data + .groups = msm8660_groups, + .ngroups = ARRAY_SIZE(msm8660_groups), + .ngpios = NUM_GPIO_PINGROUPS, ++ .gpio_pull = &msm_gpio_pull, + }; + + static int msm8660_pinctrl_probe(struct platform_device *pdev) +--- a/drivers/pinctrl/qcom/pinctrl-msm8916.c ++++ b/drivers/pinctrl/qcom/pinctrl-msm8916.c +@@ -967,6 +967,7 @@ static const struct msm_pinctrl_soc_data + .groups = msm8916_groups, + .ngroups = ARRAY_SIZE(msm8916_groups), + .ngpios = NUM_GPIO_PINGROUPS, ++ .gpio_pull = &msm_gpio_pull, + }; + + static int msm8916_pinctrl_probe(struct platform_device *pdev) +--- a/drivers/pinctrl/qcom/pinctrl-msm8960.c ++++ b/drivers/pinctrl/qcom/pinctrl-msm8960.c +@@ -1244,6 +1244,7 @@ static const struct msm_pinctrl_soc_data + .groups = msm8960_groups, + .ngroups = ARRAY_SIZE(msm8960_groups), + .ngpios = NUM_GPIO_PINGROUPS, ++ .gpio_pull = &msm_gpio_pull, + }; + + static int msm8960_pinctrl_probe(struct platform_device *pdev) +--- a/drivers/pinctrl/qcom/pinctrl-msm8x74.c ++++ b/drivers/pinctrl/qcom/pinctrl-msm8x74.c +@@ -1069,6 +1069,7 @@ static const struct msm_pinctrl_soc_data + .groups = msm8x74_groups, + .ngroups = ARRAY_SIZE(msm8x74_groups), + .ngpios = NUM_GPIO_PINGROUPS, ++ .gpio_pull = &msm_gpio_pull, + }; + + static int msm8x74_pinctrl_probe(struct platform_device *pdev) diff --git a/target/linux/ipq806x/patches-4.9/863-dts-ipq4019-add-nand-and-qpic-bam-dma-node.patch b/target/linux/ipq806x/patches-4.9/863-dts-ipq4019-add-nand-and-qpic-bam-dma-node.patch index 9ea46c9d4..62153b3cd 100644 --- a/target/linux/ipq806x/patches-4.9/863-dts-ipq4019-add-nand-and-qpic-bam-dma-node.patch +++ b/target/linux/ipq806x/patches-4.9/863-dts-ipq4019-add-nand-and-qpic-bam-dma-node.patch @@ -15,17 +15,78 @@ Signed-off-by: Ram Chandra Jangir --- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi -@@ -88,6 +88,26 @@ +@@ -88,6 +88,86 @@ bias-disable; }; }; + + nand_pins: nand_pins { + ++ mux_1 { ++ pins = "gpio52", "gpio53", "gpio54", ++ "gpio55", "gpio56", "gpio61", ++ "gpio62", "gpio63", "gpio69"; ++ function = "qpic_pad"; ++ bias-disable; ++ }; ++ ++ mux_2 { ++ pins = "gpio67"; ++ function = "qpic_pad0"; ++ bias-disable; ++ }; ++ ++ mux_3 { ++ pins = "gpio64"; ++ function = "qpic_pad1"; ++ bias-disable; ++ }; ++ ++ mux_4 { ++ pins = "gpio65"; ++ function = "qpic_pad2"; ++ bias-disable; ++ }; ++ ++ mux_5 { ++ pins = "gpio66"; ++ function = "qpic_pad3"; ++ bias-disable; ++ }; ++ ++ mux_6 { ++ pins = "gpio57"; ++ function = "qpic_pad4"; ++ bias-disable; ++ }; ++ ++ mux_7 { ++ pins = "gpio58"; ++ function = "qpic_pad5"; ++ bias-disable; ++ }; ++ ++ mux_8 { ++ pins = "gpio59"; ++ function = "qpic_pad6"; ++ bias-disable; ++ }; ++ ++ mux_9 { ++ pins = "gpio60"; ++ function = "qpic_pad7"; ++ bias-disable; ++ }; ++ ++ mux_10 { ++ pins = "gpio68"; ++ function = "qpic_pad8"; ++ bias-disable; ++ }; ++ + pullups { + pins = "gpio52", "gpio53", "gpio58", + "gpio59"; -+ function = "qpic"; + bias-pull-up; + }; + @@ -35,14 +96,13 @@ Signed-off-by: Ram Chandra Jangir + "gpio62", "gpio63", "gpio64", + "gpio65", "gpio66", "gpio67", + "gpio68", "gpio69"; -+ function = "qpic"; + bias-pull-down; + }; + }; }; blsp_dma: dma@7884000 { -@@ -159,5 +179,15 @@ +@@ -159,5 +239,15 @@ watchdog@b017000 { status = "ok"; }; @@ -60,7 +120,7 @@ Signed-off-by: Ram Chandra Jangir }; --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -609,5 +609,43 @@ +@@ -586,5 +586,43 @@ "legacy"; status = "disabled"; }; diff --git a/target/linux/ipq806x/patches-4.9/864-00-v3-1-2-dts-ipq4019-Fix-pinctrl-node-name.patch b/target/linux/ipq806x/patches-4.9/864-00-v3-1-2-dts-ipq4019-Fix-pinctrl-node-name.patch new file mode 100644 index 000000000..220503bda --- /dev/null +++ b/target/linux/ipq806x/patches-4.9/864-00-v3-1-2-dts-ipq4019-Fix-pinctrl-node-name.patch @@ -0,0 +1,44 @@ +From patchwork Mon Jul 3 07:47:12 2017 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v3,1/2] dts: ipq4019: Fix pinctrl node name +From: Varadarajan Narayanan +X-Patchwork-Id: 9822099 +Message-Id: <1499068033-24000-2-git-send-email-varada@codeaurora.org> +To: andy.gross@linaro.org, david.brown@linaro.org, robh+dt@kernel.org, + mark.rutland@arm.com, linux@armlinux.org.uk, + linux-arm-msm@vger.kernel.org, + linux-soc@vger.kernel.org, devicetree@vger.kernel.org, + linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org +Cc: Varadarajan Narayanan +Date: Mon, 3 Jul 2017 13:17:12 +0530 + +Signed-off-by: Varadarajan Narayanan +--- + arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi | 2 +- + arch/arm/boot/dts/qcom-ipq4019.dtsi | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi +@@ -40,7 +40,7 @@ + clock-frequency = <48000000>; + }; + +- pinctrl@0x01000000 { ++ pinctrl@1000000 { + serial_pins: serial_pinmux { + mux { + pins = "gpio60", "gpio61"; +--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi +@@ -155,7 +155,7 @@ + reg = <0x1800000 0x60000>; + }; + +- tlmm: pinctrl@0x01000000 { ++ tlmm: pinctrl@1000000 { + compatible = "qcom,ipq4019-pinctrl"; + reg = <0x01000000 0x300000>; + gpio-controller; diff --git a/target/linux/ipq806x/patches-4.9/864-00-v3-2-2-dts-ipq4019-Move-xo-and-timer-nodes-to-SoC-dtsi.patch b/target/linux/ipq806x/patches-4.9/864-00-v3-2-2-dts-ipq4019-Move-xo-and-timer-nodes-to-SoC-dtsi.patch new file mode 100644 index 000000000..da3b2c694 --- /dev/null +++ b/target/linux/ipq806x/patches-4.9/864-00-v3-2-2-dts-ipq4019-Move-xo-and-timer-nodes-to-SoC-dtsi.patch @@ -0,0 +1,78 @@ +From patchwork Mon Jul 3 07:47:13 2017 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v3,2/2] dts: ipq4019: Move xo and timer nodes to SoC dtsi +From: Varadarajan Narayanan +X-Patchwork-Id: 9822107 +Message-Id: <1499068033-24000-3-git-send-email-varada@codeaurora.org> +To: andy.gross@linaro.org, david.brown@linaro.org, robh+dt@kernel.org, + mark.rutland@arm.com, linux@armlinux.org.uk, + linux-arm-msm@vger.kernel.org, + linux-soc@vger.kernel.org, devicetree@vger.kernel.org, + linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org +Cc: Varadarajan Narayanan +Date: Mon, 3 Jul 2017 13:17:13 +0530 + +The node for xo and timer belong to the SoC DTS file. +Else, new board DT files may not inherit these nodes. + +Signed-off-by: Varadarajan Narayanan +--- + arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi | 19 ------------------- + arch/arm/boot/dts/qcom-ipq4019.dtsi | 15 +++++++++++++++ + 2 files changed, 15 insertions(+), 19 deletions(-) + +--- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi +@@ -20,26 +20,7 @@ + model = "Qualcomm Technologies, Inc. IPQ4019/AP-DK01.1"; + compatible = "qcom,ipq4019"; + +- clocks { +- xo: xo { +- compatible = "fixed-clock"; +- clock-frequency = <48000000>; +- #clock-cells = <0>; +- }; +- }; +- + soc { +- +- +- timer { +- compatible = "arm,armv7-timer"; +- interrupts = <1 2 0xf08>, +- <1 3 0xf08>, +- <1 4 0xf08>, +- <1 1 0xf08>; +- clock-frequency = <48000000>; +- }; +- + pinctrl@1000000 { + serial_pins: serial_pinmux { + mux { +--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi +@@ -132,6 +132,21 @@ + clock-frequency = <32768>; + #clock-cells = <0>; + }; ++ ++ xo: xo { ++ compatible = "fixed-clock"; ++ clock-frequency = <48000000>; ++ #clock-cells = <0>; ++ }; ++ }; ++ ++ timer { ++ compatible = "arm,armv7-timer"; ++ interrupts = <1 2 0xf08>, ++ <1 3 0xf08>, ++ <1 4 0xf08>, ++ <1 1 0xf08>; ++ clock-frequency = <48000000>; + }; + + soc { diff --git a/target/linux/ipq806x/patches-4.9/864-01-dts-ipq4019-ap-dk04-fix-pinctrl-node-name.patch b/target/linux/ipq806x/patches-4.9/864-01-dts-ipq4019-ap-dk04-fix-pinctrl-node-name.patch new file mode 100644 index 000000000..f2de6d618 --- /dev/null +++ b/target/linux/ipq806x/patches-4.9/864-01-dts-ipq4019-ap-dk04-fix-pinctrl-node-name.patch @@ -0,0 +1,11 @@ +--- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi +@@ -38,7 +38,7 @@ + clock-frequency = <48000000>; + }; + +- pinctrl@0x01000000 { ++ pinctrl@1000000 { + serial_0_pins: serial_pinmux { + mux { + pins = "gpio16", "gpio17"; diff --git a/target/linux/ipq806x/patches-4.9/864-02-dts-ipq4019-ap-dk04-remove-xo-and-timer-nodes.patch b/target/linux/ipq806x/patches-4.9/864-02-dts-ipq4019-ap-dk04-remove-xo-and-timer-nodes.patch new file mode 100644 index 000000000..dcbdb8d77 --- /dev/null +++ b/target/linux/ipq806x/patches-4.9/864-02-dts-ipq4019-ap-dk04-remove-xo-and-timer-nodes.patch @@ -0,0 +1,27 @@ +--- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk04.1.dtsi +@@ -20,24 +20,7 @@ + model = "Qualcomm Technologies, Inc. IPQ4019/AP-DK04.1"; + compatible = "qcom,ipq4019"; + +- clocks { +- xo: xo { +- compatible = "fixed-clock"; +- clock-frequency = <48000000>; +- #clock-cells = <0>; +- }; +- }; +- + soc { +- timer { +- compatible = "arm,armv7-timer"; +- interrupts = <1 2 0xf08>, +- <1 3 0xf08>, +- <1 4 0xf08>, +- <1 1 0xf08>; +- clock-frequency = <48000000>; +- }; +- + pinctrl@1000000 { + serial_0_pins: serial_pinmux { + mux { diff --git a/target/linux/ipq806x/patches-4.9/864-03-dts-ipq4019-ap-dk01-add-tcsr-config-to-dtsi.patch b/target/linux/ipq806x/patches-4.9/864-03-dts-ipq4019-ap-dk01-add-tcsr-config-to-dtsi.patch new file mode 100644 index 000000000..9d11dc022 --- /dev/null +++ b/target/linux/ipq806x/patches-4.9/864-03-dts-ipq4019-ap-dk01-add-tcsr-config-to-dtsi.patch @@ -0,0 +1,42 @@ +--- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi +@@ -15,12 +15,39 @@ + */ + + #include "qcom-ipq4019.dtsi" ++#include + + / { + model = "Qualcomm Technologies, Inc. IPQ4019/AP-DK01.1"; + compatible = "qcom,ipq4019"; + + soc { ++ tcsr@194b000 { ++ /* select hostmode */ ++ compatible = "qcom,tcsr"; ++ reg = <0x194b000 0x100>; ++ qcom,usb-hsphy-mode-select = ; ++ status = "ok"; ++ }; ++ ++ ess_tcsr@1953000 { ++ compatible = "qcom,tcsr"; ++ reg = <0x1953000 0x1000>; ++ qcom,ess-interface-select = ; ++ }; ++ ++ tcsr@1949000 { ++ compatible = "qcom,tcsr"; ++ reg = <0x1949000 0x100>; ++ qcom,wifi_glb_cfg = ; ++ }; ++ ++ tcsr@1957000 { ++ compatible = "qcom,tcsr"; ++ reg = <0x1957000 0x100>; ++ qcom,wifi_noc_memtype_m0_m2 = ; ++ }; ++ + pinctrl@1000000 { + serial_pins: serial_pinmux { + mux { diff --git a/target/linux/ipq806x/patches-4.9/864-04-dts-ipq4019-ap-dk01-add-network-nodes-to-dtsi.patch b/target/linux/ipq806x/patches-4.9/864-04-dts-ipq4019-ap-dk01-add-network-nodes-to-dtsi.patch new file mode 100644 index 000000000..02a102e37 --- /dev/null +++ b/target/linux/ipq806x/patches-4.9/864-04-dts-ipq4019-ap-dk01-add-network-nodes-to-dtsi.patch @@ -0,0 +1,32 @@ +--- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi +@@ -136,5 +136,29 @@ + usb2: usb2@60f8800 { + status = "ok"; + }; ++ ++ mdio@90000 { ++ status = "okay"; ++ }; ++ ++ ess-switch@c000000 { ++ status = "okay"; ++ }; ++ ++ ess-psgmii@98000 { ++ status = "okay"; ++ }; ++ ++ edma@c080000 { ++ status = "okay"; ++ }; ++ ++ wifi@a000000 { ++ status = "okay"; ++ }; ++ ++ wifi@a800000 { ++ status = "okay"; ++ }; + }; + }; diff --git a/target/linux/ipq806x/patches-4.9/864-05-dts-ipq4019-ap-dk01-remove-spi-chip-node-from-dtsi.patch b/target/linux/ipq806x/patches-4.9/864-05-dts-ipq4019-ap-dk01-remove-spi-chip-node-from-dtsi.patch new file mode 100644 index 000000000..0d4b80b30 --- /dev/null +++ b/target/linux/ipq806x/patches-4.9/864-05-dts-ipq4019-ap-dk01-remove-spi-chip-node-from-dtsi.patch @@ -0,0 +1,17 @@ +--- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi +@@ -89,14 +89,6 @@ + pinctrl-names = "default"; + status = "ok"; + cs-gpios = <&tlmm 54 0>; +- +- mx25l25635e@0 { +- #address-cells = <1>; +- #size-cells = <1>; +- reg = <0>; +- compatible = "mx25l25635e"; +- spi-max-frequency = <24000000>; +- }; + }; + + serial@78af000 { diff --git a/target/linux/ipq806x/patches-4.9/864-06-dts-ipq4019-fix-max-cpu-speed.patch b/target/linux/ipq806x/patches-4.9/864-06-dts-ipq4019-fix-max-cpu-speed.patch new file mode 100644 index 000000000..33f7f04f3 --- /dev/null +++ b/target/linux/ipq806x/patches-4.9/864-06-dts-ipq4019-fix-max-cpu-speed.patch @@ -0,0 +1,13 @@ +--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi +@@ -108,8 +108,8 @@ + opp-hz = /bits/ 64 <500000000>; + clock-latency-ns = <256000>; + }; +- opp@666000000 { +- opp-hz = /bits/ 64 <666000000>; ++ opp@716800000 { ++ opp-hz = /bits/ 64 <716800000>; + clock-latency-ns = <256000>; + }; + }; diff --git a/target/linux/ipq806x/patches-4.9/864-07-dts-ipq4019-ap-dk01.1-c1-add-spi-and-ram-nodes.patch b/target/linux/ipq806x/patches-4.9/864-07-dts-ipq4019-ap-dk01.1-c1-add-spi-and-ram-nodes.patch new file mode 100644 index 000000000..e9d262069 --- /dev/null +++ b/target/linux/ipq806x/patches-4.9/864-07-dts-ipq4019-ap-dk01.1-c1-add-spi-and-ram-nodes.patch @@ -0,0 +1,115 @@ +--- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1-c1.dts ++++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1-c1.dts +@@ -19,4 +19,112 @@ + / { + model = "Qualcomm Technologies, Inc. IPQ40xx/AP-DK01.1-C1"; + ++ memory { ++ device_type = "memory"; ++ reg = <0x80000000 0x10000000>; ++ }; ++ ++ reserved-memory { ++ #address-cells = <0x1>; ++ #size-cells = <0x1>; ++ ranges; ++ ++ apps_bl@87000000 { ++ reg = <0x87000000 0x400000>; ++ no-map; ++ }; ++ ++ sbl@87400000 { ++ reg = <0x87400000 0x100000>; ++ no-map; ++ }; ++ ++ cnss_debug@87500000 { ++ reg = <0x87500000 0x600000>; ++ no-map; ++ }; ++ ++ cpu_context_dump@87b00000 { ++ reg = <0x87b00000 0x080000>; ++ no-map; ++ }; ++ ++ tz_apps@87b80000 { ++ reg = <0x87b80000 0x280000>; ++ no-map; ++ }; ++ ++ smem@87e00000 { ++ reg = <0x87e00000 0x080000>; ++ no-map; ++ }; ++ ++ tz@87e80000 { ++ reg = <0x87e80000 0x180000>; ++ no-map; ++ }; ++ }; ++}; ++ ++&spi_0 { ++ mx25l25635f@0 { ++ compatible = "mx25l25635f", "jedec,spi-nor"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0>; ++ spi-max-frequency = <24000000>; ++ ++ SBL1@0 { ++ label = "SBL1"; ++ reg = <0x0 0x40000>; ++ read-only; ++ }; ++ MIBIB@40000 { ++ label = "MIBIB"; ++ reg = <0x40000 0x20000>; ++ read-only; ++ }; ++ QSEE@60000 { ++ label = "QSEE"; ++ reg = <0x60000 0x60000>; ++ read-only; ++ }; ++ CDT@c0000 { ++ label = "CDT"; ++ reg = <0xc0000 0x10000>; ++ read-only; ++ }; ++ DDRPARAMS@d0000 { ++ label = "DDRPARAMS"; ++ reg = <0xd0000 0x10000>; ++ read-only; ++ }; ++ APPSBLENV@e0000 { ++ label = "APPSBLENV"; ++ reg = <0xe0000 0x10000>; ++ read-only; ++ }; ++ APPSBL@f0000 { ++ label = "APPSBL"; ++ reg = <0xf0000 0x80000>; ++ read-only; ++ }; ++ ART@170000 { ++ label = "ART"; ++ reg = <0x170000 0x10000>; ++ read-only; ++ }; ++ kernel@180000 { ++ label = "kernel"; ++ reg = <0x180000 0x400000>; ++ }; ++ rootfs@580000 { ++ label = "rootfs"; ++ reg = <0x580000 0x1600000>; ++ }; ++ firmware@180000 { ++ label = "firmware"; ++ reg = <0x180000 0x1a00000>; ++ }; ++ }; + }; diff --git a/target/linux/ipq806x/patches-4.9/864-08-dts-ipq4019-ap-dk01.1-c1-add-compatible-string.patch b/target/linux/ipq806x/patches-4.9/864-08-dts-ipq4019-ap-dk01.1-c1-add-compatible-string.patch new file mode 100644 index 000000000..2d4ff3104 --- /dev/null +++ b/target/linux/ipq806x/patches-4.9/864-08-dts-ipq4019-ap-dk01.1-c1-add-compatible-string.patch @@ -0,0 +1,10 @@ +--- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1-c1.dts ++++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1-c1.dts +@@ -18,6 +18,7 @@ + + / { + model = "Qualcomm Technologies, Inc. IPQ40xx/AP-DK01.1-C1"; ++ compatible = "qcom,ap-dk01.1-c1", "qcom,ap-dk01.2-c1", "qcom,ipq4019"; + + memory { + device_type = "memory"; diff --git a/target/linux/lantiq/patches-4.9/0026-NET-multi-phy-support.patch b/target/linux/lantiq/patches-4.9/0026-NET-multi-phy-support.patch index 9e71051d3..6046d6cde 100644 --- a/target/linux/lantiq/patches-4.9/0026-NET-multi-phy-support.patch +++ b/target/linux/lantiq/patches-4.9/0026-NET-multi-phy-support.patch @@ -43,7 +43,7 @@ Signed-off-by: John Crispin } --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -373,6 +373,7 @@ struct phy_device { +@@ -369,6 +369,7 @@ struct phy_device { bool is_pseudo_fixed_link; bool has_fixups; bool suspended; diff --git a/target/linux/layerscape/README b/target/linux/layerscape/README new file mode 100644 index 000000000..eaeee32e8 --- /dev/null +++ b/target/linux/layerscape/README @@ -0,0 +1,151 @@ + +Layerscape Quick Start + +1. Layerscape target support +---------------------------- +* ARMv8 64-bit + LS1012ARDB LS1012AFRDM LS1043ARDB LS1046ARDB LS1088ARDB LS2088ARDB + +* ARMv8 32-bit + LS1012ARDB LS1012AFRDM LS1043ARDB LS1046ARDB + + +2. Build +-------- + +2.1 make menuconfig +------------------- +* For single device + + Target System: "NXP Layerscape". + Subtarget: "ARMv8 64-bit based boards" or "ARMv8 32-bit based boards" + Target Profile: (select device you want to build) + + For example, build firmware for 64-bit ls1043ardb. + +---------------------------------------------+ + | Target System (NXP Layerscape) ---> | + |---------------------------------------------| + | Subtarget (ARMv8 64-bit based boards) ---> | + |---------------------------------------------| + | Target Profile (ls1043ardb-armv8_64b) ---> | + +---------------------------------------------+ + +* For multiple devices + + Target System: "NXP Layerscape". + Subtarget: "ARMv8 64-bit based boards" or "ARMv8 32-bit based boards" + Target Profile: "Multiple devices" + Target Devices: (select devices you want to build) + + For example, build firmware for all 64-bit devices. + Target Devices ---> + +-----------------------------------------------------------------+ + | [*] Enable all profiles by default | + |-----------------------------------------------------------------| + | [ ] Use a per-device root filesystem that adds profile packages | + |-----------------------------------------------------------------| + | [*] ls1012afrdm-armv8_64b ---- | + |-----------------------------------------------------------------| + | [*] ls1012ardb-armv8_64b ---- | + |-----------------------------------------------------------------| + | [*] ls1043ardb-armv8_64b ---- | + |-----------------------------------------------------------------| + | [*] ls1046ardb-armv8_64b ---- | + |-----------------------------------------------------------------| + | [*] ls1088ardb-armv8_64b ---- | + |-----------------------------------------------------------------| + | [*] ls2088ardb-armv8_64b ---- | + +-----------------------------------------------------------------+ + + Note: per-device root filesystem hasn't been supported for now. + +2.2 make (or make -j) +------------------------ + +2.3 Final firmware +------------------ +Final firmware would be in bin/targets/layerscape//, and +named as lede-layerscape---squashfs-firmware.bin. + + +3. Program firmware to NOR/QSPI flash +------------------------------------- +* LS1043ARDB (NOR flash) + + Start up from bank0, and program firmware to bank4 with below commands. + Switch to bank4 to start up LEDE. + + => tftp a0000000 lede-layerscape---squashfs-firmware.bin + => protect off all + => erase 64000000 +$filesize + => cp.b a0000000 64000000 $filesize + => cpld reset altbank + +* LS2088ARDB (NOR flash) + + Start up from bank0, and program firmware to bank4 with below commands. + Switch to bank4 to start up LEDE. + + => tftp a0000000 lede-layerscape---squashfs-firmware.bin + => protect off all + => erase 584000000 +$filesize + => cp.b a0000000 584000000 $filesize + => qix altbank + +* LS1012ARDB (QSPI flash) + + Start up from bank1, and program firmware to bank2 with below commands. + Switch to bank2 to start up LEDE. + + => tftp a0000000 lede-layerscape---squashfs-firmware.bin + => i2c mw 0x24 0x7 0xfc;i2c mw 0x24 0x3 0xf5 + => sf probe 0:0 + => sf erase 0 +$filesize + => sf write a0000000 0 $filesize + => reset + +* LS1012AFRDM (QSPI flash) + + LS1012AFRDM board only has one bank. Start up board, and program firmware + with below commands. Reset to start up LEDE. + + => tftp 96000000 lede-layerscape---squashfs-firmware.bin + => sf probe 0:0 + => sf erase 0 +$filesize + => sf write 96000000 0 $filesize + => reset + +* LS1046ARDB (QSPI flash) + + Start up from bank1, and program firmware to bank2 with below commands. + Switch to bank2 to start up LEDE. + + => tftp a0000000 lede-layerscape---squashfs-firmware.bin + => sf probe 0:1 + => sf erase 0 +$filesize + => sf write a0000000 0 $filesize + => cpld reset altbank + +* LS1088ARDB (QSPI flash) + + Start up from bank0, and program firmware to bank1 with below commands. + Switch to bank1 to start up LEDE. + + => tftp a0000000 lede-layerscape---squashfs-firmware.bin + => sf probe 0:1 + => sf erase 0 +$filesize + => sf write a0000000 0 $filesize + => qix altbank + + Note: old version u-boot of ls1088ardb may use below commands to switch to + bank1 instead of 'qix altbank'. + => i2c mw 66 50 20;i2c mw 66 10 20;i2c mw 66 10 21 + + +4. Other references and sources +------------------------------- +- NXP LSDK site: https://lsdk.github.io/ + +- NXP LSDK github: https://github.com/qoriq-open-source + +- LEDE documentation: https://lede-project.org/docs/start diff --git a/target/linux/layerscape/armv8_32b/config-4.9 b/target/linux/layerscape/armv8_32b/config-4.9 index f0687f380..9e5b33b88 100644 --- a/target/linux/layerscape/armv8_32b/config-4.9 +++ b/target/linux/layerscape/armv8_32b/config-4.9 @@ -2,7 +2,6 @@ CONFIG_ABX500_CORE=y CONFIG_AD525X_DPOT=y CONFIG_AD525X_DPOT_I2C=y # CONFIG_AD525X_DPOT_SPI is not set -CONFIG_ADVISE_SYSCALLS=y CONFIG_AHCI_IMX=y CONFIG_AHCI_QORIQ=y CONFIG_AK8975=y @@ -11,6 +10,7 @@ CONFIG_APDS9802ALS=y CONFIG_AQUANTIA_PHY=y # CONFIG_ARCH_AXXIA is not set CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y CONFIG_ARCH_HAS_BANDGAP=y CONFIG_ARCH_HAS_ELF_RANDOMIZE=y CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y @@ -254,7 +254,6 @@ CONFIG_CROSS_MEMORY_ATTACH=y CONFIG_CRYPTO_AEAD=y CONFIG_CRYPTO_AEAD2=y # CONFIG_CRYPTO_AES_ARM_CE is not set -# CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_AUTHENC=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_CRC32C=y @@ -304,7 +303,6 @@ CONFIG_DEBUG_RODATA=y # CONFIG_DEBUG_USER is not set CONFIG_DECOMPRESS_BZIP2=y CONFIG_DECOMPRESS_GZIP=y -CONFIG_DECOMPRESS_LZ4=y CONFIG_DECOMPRESS_LZMA=y CONFIG_DECOMPRESS_LZO=y CONFIG_DECOMPRESS_XZ=y @@ -450,6 +448,9 @@ CONFIG_FSL_EDMA=y CONFIG_FSL_FM_MAX_FRAME_SIZE=1522 CONFIG_FSL_FM_RX_EXTRA_HEADROOM=64 CONFIG_FSL_GUTS=y +CONFIG_FSL_IFC=y +CONFIG_FSL_PPFE=y +CONFIG_FSL_PPFE_UTIL_DISABLED=y CONFIG_FSL_PQ_MDIO=y # CONFIG_FSL_QDMA is not set CONFIG_FSL_QMAN_CI_SCHED_CFG_BMAN_W=2 @@ -524,7 +525,6 @@ CONFIG_GPIO_TPS6586X=y CONFIG_GPIO_TPS65910=y CONFIG_GPIO_TWL4030=y CONFIG_GPIO_XILINX=y -CONFIG_GRACE_PERIOD=y CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_HAS_DMA=y @@ -669,11 +669,6 @@ CONFIG_IOMMU_HELPER=y # CONFIG_IOMMU_IO_PGTABLE_LPAE is not set CONFIG_IOMMU_SUPPORT=y CONFIG_IOSCHED_CFQ=y -CONFIG_IP6_NF_FILTER=y -CONFIG_IP6_NF_IPTABLES=y -CONFIG_IP6_NF_NAT=y -CONFIG_IP6_NF_TARGET_MASQUERADE=y -# CONFIG_IP6_NF_TARGET_NPT is not set CONFIG_IPC_NS=y CONFIG_IPV6=y CONFIG_IPV6_MULTIPLE_TABLES=y @@ -683,39 +678,10 @@ CONFIG_IPV6_SIT=y # CONFIG_IPV6_SUBTREES is not set # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_MROUTE is not set -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MANGLE=y -CONFIG_IP_NF_NAT=y -CONFIG_IP_NF_TARGET_MASQUERADE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_RARP=y -CONFIG_IP_VS=y -# CONFIG_IP_VS_DEBUG is not set -# CONFIG_IP_VS_DH is not set -# CONFIG_IP_VS_FO is not set -# CONFIG_IP_VS_IPV6 is not set -# CONFIG_IP_VS_LBLC is not set -# CONFIG_IP_VS_LBLCR is not set -# CONFIG_IP_VS_LC is not set -# CONFIG_IP_VS_NFCT is not set -# CONFIG_IP_VS_NQ is not set -# CONFIG_IP_VS_OVF is not set -# CONFIG_IP_VS_PROTO_AH is not set -# CONFIG_IP_VS_PROTO_AH_ESP is not set -# CONFIG_IP_VS_PROTO_ESP is not set -# CONFIG_IP_VS_PROTO_SCTP is not set -# CONFIG_IP_VS_PROTO_TCP is not set -# CONFIG_IP_VS_PROTO_UDP is not set -# CONFIG_IP_VS_RR is not set -# CONFIG_IP_VS_SED is not set -# CONFIG_IP_VS_SH is not set -CONFIG_IP_VS_SH_TAB_BITS=8 -CONFIG_IP_VS_TAB_BITS=12 -# CONFIG_IP_VS_WLC is not set -# CONFIG_IP_VS_WRR is not set CONFIG_IRQCHIP=y CONFIG_IRQ_CROSSBAR=y CONFIG_IRQ_DOMAIN=y @@ -726,7 +692,6 @@ CONFIG_IRQ_WORK=y # CONFIG_ISDN is not set CONFIG_ISL29003=y CONFIG_JBD2=y -# CONFIG_JFFS2_FS is not set CONFIG_KALLSYMS=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_XZ is not set @@ -759,14 +724,14 @@ CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 CONFIG_LIBFDT=y CONFIG_LOCALVERSION_AUTO=y -CONFIG_LOCKD=y CONFIG_LOCKUP_DETECTOR=y CONFIG_LOCK_SPIN_ON_OWNER=y CONFIG_LOGO=y CONFIG_LOGO_LINUX_CLUT224=y CONFIG_LOGO_LINUX_MONO=y CONFIG_LOGO_LINUX_VGA16=y -CONFIG_LZ4_DECOMPRESS=y +CONFIG_LS_SCFG_MSI=y +# CONFIG_LS_SOC_DRIVERS is not set CONFIG_LZO_COMPRESS=y CONFIG_LZO_DECOMPRESS=y CONFIG_MACB=y @@ -878,8 +843,10 @@ CONFIG_MTD_NAND_BRCMNAND=y CONFIG_MTD_NAND_DENALI=y CONFIG_MTD_NAND_DENALI_DT=y CONFIG_MTD_NAND_ECC=y +CONFIG_MTD_NAND_FSL_IFC=y CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384 CONFIG_MTD_SST25L=y CONFIG_MTD_UBI=y CONFIG_MTD_UBI_BEB_LIMIT=20 @@ -896,49 +863,11 @@ CONFIG_NAMESPACES=y CONFIG_NATIONAL_PHY=y CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEON=y -CONFIG_NETFILTER=y -CONFIG_NETFILTER_ADVANCED=y -CONFIG_NETFILTER_INGRESS=y -CONFIG_NETFILTER_XTABLES=y -CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y -CONFIG_NETFILTER_XT_MATCH_COMMENT=y -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y -CONFIG_NETFILTER_XT_MATCH_IPVS=y -CONFIG_NETFILTER_XT_NAT=y -CONFIG_NETFILTER_XT_TARGET_CHECKSUM=y -CONFIG_NETLINK_DIAG=y # CONFIG_NET_CLS_CGROUP is not set CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_INGRESS=y CONFIG_NET_IP_TUNNEL=y -CONFIG_NET_KEY=y CONFIG_NET_NS=y -CONFIG_NET_PACKET_ENGINE=y CONFIG_NET_PTP_CLASSIFY=y -CONFIG_NET_SWITCHDEV=y -# CONFIG_NET_VENDOR_AURORA is not set -CONFIG_NFS_ACL_SUPPORT=y -CONFIG_NFS_FS=y -CONFIG_NFS_USE_KERNEL_DNS=y -# CONFIG_NFS_USE_LEGACY_DNS is not set -CONFIG_NFS_V2=y -CONFIG_NFS_V3_ACL=y -CONFIG_NFS_V4=y -CONFIG_NF_CONNTRACK=y -CONFIG_NF_CONNTRACK_IPV4=y -CONFIG_NF_CONNTRACK_IPV6=y -CONFIG_NF_CONNTRACK_MARK=y -# CONFIG_NF_CONNTRACK_RTCACHE is not set -CONFIG_NF_DEFRAG_IPV4=y -CONFIG_NF_DEFRAG_IPV6=y -# CONFIG_NF_LOG_IPV6 is not set -CONFIG_NF_NAT=y -CONFIG_NF_NAT_IPV4=y -CONFIG_NF_NAT_IPV6=y -CONFIG_NF_NAT_MASQUERADE_IPV4=y -CONFIG_NF_NAT_MASQUERADE_IPV6=y -CONFIG_NF_NAT_NEEDED=y -# CONFIG_NF_NAT_REDIRECT is not set CONFIG_NLS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y @@ -964,7 +893,6 @@ CONFIG_OF_NET=y CONFIG_OF_PCI=y CONFIG_OF_PCI_IRQ=y CONFIG_OF_RESERVED_MEM=y -CONFIG_OID_REGISTRY=y CONFIG_OLD_SIGACTION=y CONFIG_OLD_SIGSUSPEND3=y # CONFIG_OMAP2PLUS_MBOX is not set @@ -994,7 +922,6 @@ CONFIG_OUTER_CACHE_SYNC=y CONFIG_PACKET_DIAG=y CONFIG_PAGE_COUNTER=y CONFIG_PAGE_OFFSET=0xC0000000 -# CONFIG_PALMAS_GPADC is not set # CONFIG_PANIC_ON_OOPS is not set CONFIG_PANIC_ON_OOPS_VALUE=0 CONFIG_PANIC_TIMEOUT=0 @@ -1009,6 +936,7 @@ CONFIG_PCIEASPM_DEFAULT=y CONFIG_PCIEPORTBUS=y CONFIG_PCIE_DW=y CONFIG_PCIE_PME=y +CONFIG_PCI_BUS_ADDR_T_64BIT=y CONFIG_PCI_DOMAINS=y CONFIG_PCI_DOMAINS_GENERIC=y # CONFIG_PCI_DRA7XX is not set @@ -1094,7 +1022,6 @@ CONFIG_RCU_CPU_STALL_TIMEOUT=21 CONFIG_RCU_STALL_COMMON=y CONFIG_RD_BZIP2=y CONFIG_RD_GZIP=y -CONFIG_RD_LZ4=y CONFIG_RD_LZMA=y CONFIG_RD_LZO=y CONFIG_RD_XZ=y @@ -1147,7 +1074,6 @@ CONFIG_REGULATOR_TWL4030=y CONFIG_REGULATOR_VEXPRESS=y CONFIG_RESET_CONTROLLER=y CONFIG_RFS_ACCEL=y -CONFIG_ROOT_NFS=y CONFIG_RPS=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_AS3722=y @@ -1245,7 +1171,7 @@ CONFIG_SOC_HAS_REALTIME_COUNTER=y # CONFIG_SOC_IMX6SX is not set # CONFIG_SOC_IMX6UL is not set # CONFIG_SOC_IMX7D is not set -# CONFIG_SOC_LS1021A is not set +CONFIG_SOC_LS1021A=y CONFIG_SOC_OMAP3430=y CONFIG_SOC_OMAP5=y CONFIG_SOC_TI81XX=y @@ -1254,7 +1180,6 @@ CONFIG_SPARSE_IRQ=y CONFIG_SPI=y CONFIG_SPI_BITBANG=y CONFIG_SPI_CADENCE=y -# CONFIG_SPI_CADENCE_QUADSPI is not set CONFIG_SPI_FSL_QUADSPI=y # CONFIG_SPI_IMX is not set CONFIG_SPI_MASTER=y @@ -1278,8 +1203,6 @@ CONFIG_STMPE_I2C=y # CONFIG_STMPE_SPI is not set CONFIG_STMP_DEVICE=y # CONFIG_STRIP_ASM_SYMS is not set -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y CONFIG_SWIOTLB=y @@ -1347,7 +1270,6 @@ CONFIG_USB_DWC3_DUAL_ROLE=y CONFIG_USB_DWC3_OF_SIMPLE=y CONFIG_USB_DWC3_OMAP=y CONFIG_USB_DWC3_PCI=y -# CONFIG_USB_EHCI_FSL is not set CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD_PLATFORM=y # CONFIG_USB_EHCI_MXC is not set diff --git a/target/linux/layerscape/armv8_32b/profiles/00-default.mk b/target/linux/layerscape/armv8_32b/profiles/00-default.mk deleted file mode 100644 index fc1231dc7..000000000 --- a/target/linux/layerscape/armv8_32b/profiles/00-default.mk +++ /dev/null @@ -1,18 +0,0 @@ -define Profile/Default - NAME:=Default Profile - PRIORITY:=1 -endef - -define Profile/Default/Description - Default package set compatible with most boards. -endef - -DEFAULT_PACKAGES+= \ - rcw-layerscape-ls1043ardb uboot-layerscape-$(SUBTARGET)-ls1043ardb \ - fman-layerscape-ls1043ardb \ - rcw-layerscape-ls1046ardb uboot-layerscape-$(SUBTARGET)-ls1046ardb \ - fman-layerscape-ls1046ardb \ - rcw-layerscape-ls1012ardb uboot-layerscape-$(SUBTARGET)-ls1012ardb \ - kmod-ppfe ppfe-ls1012ardb - -$(eval $(call Profile,Default)) diff --git a/target/linux/layerscape/armv8_64b/config-4.9 b/target/linux/layerscape/armv8_64b/config-4.9 index 91a89a25b..9e0c8e032 100644 --- a/target/linux/layerscape/armv8_64b/config-4.9 +++ b/target/linux/layerscape/armv8_64b/config-4.9 @@ -23,7 +23,6 @@ CONFIG_ACPI_REDUCED_HARDWARE_ONLY=y CONFIG_ACPI_SPCR_TABLE=y CONFIG_ACPI_TABLE_UPGRADE=y CONFIG_ACPI_THERMAL=y -CONFIG_ADVISE_SYSCALLS=y CONFIG_AHCI_CEVA=y CONFIG_AHCI_QORIQ=y CONFIG_AHCI_XGENE=y @@ -107,6 +106,7 @@ CONFIG_ARM_SP805_WATCHDOG=y CONFIG_ARM_TIMER_SP804=y CONFIG_ASN1=y CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_ASYNC_CORE=y CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y CONFIG_ATA=y CONFIG_ATA_ACPI=y @@ -145,11 +145,6 @@ CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 CONFIG_BOUNCE=y CONFIG_BPF_JIT=y # CONFIG_BPF_SYSCALL is not set -CONFIG_BRIDGE_EBT_DNAT=y -CONFIG_BRIDGE_EBT_SNAT=y -CONFIG_BRIDGE_EBT_T_NAT=y -CONFIG_BRIDGE_NETFILTER=y -CONFIG_BRIDGE_NF_EBTABLES=y CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y @@ -259,7 +254,6 @@ CONFIG_CRYPTO_AES_ARM64_CE_CCM=y CONFIG_CRYPTO_AKCIPHER=y CONFIG_CRYPTO_AKCIPHER2=y CONFIG_CRYPTO_ANSI_CPRNG=y -# CONFIG_CRYPTO_ARC4 is not set CONFIG_CRYPTO_AUTHENC=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_CRC32C=y @@ -274,12 +268,13 @@ CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC=y CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI=y # CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG is not set +CONFIG_CRYPTO_DEV_FSL_CAAM_DMA=y # CONFIG_CRYPTO_DEV_FSL_CAAM_INTC is not set CONFIG_CRYPTO_DEV_FSL_CAAM_JR=y CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API=y CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9 CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y -# CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM is not set +CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM=y CONFIG_CRYPTO_DRBG=y CONFIG_CRYPTO_DRBG_HMAC=y CONFIG_CRYPTO_DRBG_MENU=y @@ -318,7 +313,6 @@ CONFIG_DEBUG_RODATA=y CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_DECOMPRESS_BZIP2=y CONFIG_DECOMPRESS_GZIP=y -CONFIG_DECOMPRESS_LZ4=y CONFIG_DECOMPRESS_LZMA=y CONFIG_DECOMPRESS_LZO=y CONFIG_DECOMPRESS_XZ=y @@ -461,6 +455,8 @@ CONFIG_FSL_LS2_CONSOLE=y CONFIG_FSL_MC_BUS=y CONFIG_FSL_MC_DPIO=y CONFIG_FSL_MC_RESTOOL=y +CONFIG_FSL_PPFE=y +CONFIG_FSL_PPFE_UTIL_DISABLED=y # CONFIG_FSL_QBMAN_DEBUG is not set # CONFIG_FSL_QDMA is not set CONFIG_FSL_QMAN_CI_SCHED_CFG_BMAN_W=2 @@ -691,11 +687,6 @@ CONFIG_IPV6=y CONFIG_IPV6_SIT=y # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_MROUTE is not set -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MANGLE=y -CONFIG_IP_NF_NAT=y -CONFIG_IP_NF_TARGET_MASQUERADE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_DHCP=y @@ -708,7 +699,6 @@ CONFIG_IRQ_FORCED_THREADING=y CONFIG_IRQ_WORK=y # CONFIG_ISDN is not set CONFIG_JBD2=y -# CONFIG_JFFS2_FS is not set CONFIG_JUMP_LABEL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y @@ -748,7 +738,6 @@ CONFIG_LOGO_LINUX_CLUT224=y # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_LS_SCFG_MSI=y CONFIG_LS_SOC_DRIVERS=y -CONFIG_LZ4_DECOMPRESS=y CONFIG_LZO_COMPRESS=y CONFIG_LZO_DECOMPRESS=y CONFIG_MACB=y @@ -837,6 +826,7 @@ CONFIG_MTD_NAND_ECC=y CONFIG_MTD_NAND_FSL_IFC=y CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384 CONFIG_MTD_SST25L=y CONFIG_MUTEX_SPIN_ON_OWNER=y CONFIG_MV_XOR_V2=y @@ -845,76 +835,12 @@ CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEED_MULTIPLE_NODES=y CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_NETFILTER=y -CONFIG_NETFILTER_ADVANCED=y -CONFIG_NETFILTER_INGRESS=y -CONFIG_NETFILTER_NETLINK=y -CONFIG_NETFILTER_XTABLES=y -CONFIG_NETFILTER_XT_CONNMARK=y -CONFIG_NETFILTER_XT_MATCH_COMMENT=y -CONFIG_NETFILTER_XT_NAT=y -CONFIG_NETFILTER_XT_TARGET_CONNMARK=y # CONFIG_NETLABEL is not set -CONFIG_NETLINK_DIAG=y -# CONFIG_NETWORK_FILESYSTEMS is not set -CONFIG_NET_9P=y -# CONFIG_NET_9P_DEBUG is not set -CONFIG_NET_9P_VIRTIO=y # CONFIG_NET_CLS_CGROUP is not set CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_INGRESS=y CONFIG_NET_IP_TUNNEL=y -CONFIG_NET_KEY=y CONFIG_NET_NS=y -CONFIG_NET_PACKET_ENGINE=y CONFIG_NET_PTP_CLASSIFY=y -# CONFIG_NET_VENDOR_AURORA is not set -# CONFIG_NET_VENDOR_STMICRO is not set -# CONFIG_NFT_CHAIN_NAT_IPV4 is not set -# CONFIG_NFT_CHAIN_ROUTE_IPV4 is not set -CONFIG_NFT_COMPAT=y -# CONFIG_NFT_COUNTER is not set -CONFIG_NFT_CT=y -# CONFIG_NFT_EXTHDR is not set -# CONFIG_NFT_HASH is not set -# CONFIG_NFT_LIMIT is not set -# CONFIG_NFT_LOG is not set -CONFIG_NFT_MASQ=y -# CONFIG_NFT_MASQ_IPV4 is not set -# CONFIG_NFT_META is not set -CONFIG_NFT_NAT=y -# CONFIG_NFT_NUMGEN is not set -# CONFIG_NFT_QUOTA is not set -# CONFIG_NFT_REDIR is not set -# CONFIG_NFT_REJECT is not set -# CONFIG_NFT_REJECT_IPV4 is not set -# CONFIG_NFT_SET_HASH is not set -# CONFIG_NFT_SET_RBTREE is not set -CONFIG_NF_CONNTRACK=y -CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CONNTRACK_IPV4=y -CONFIG_NF_CONNTRACK_IPV6=y -CONFIG_NF_CONNTRACK_MARK=y -# CONFIG_NF_CONNTRACK_RTCACHE is not set -CONFIG_NF_DEFRAG_IPV4=y -CONFIG_NF_DEFRAG_IPV6=y -# CONFIG_NF_LOG_BRIDGE is not set -CONFIG_NF_LOG_COMMON=y -CONFIG_NF_LOG_IPV6=y -CONFIG_NF_NAT=y -CONFIG_NF_NAT_IPV4=y -CONFIG_NF_NAT_IPV6=y -CONFIG_NF_NAT_MASQUERADE_IPV4=y -CONFIG_NF_NAT_MASQUERADE_IPV6=y -CONFIG_NF_NAT_NEEDED=y -# CONFIG_NF_NAT_REDIRECT is not set -CONFIG_NF_REJECT_IPV6=y -CONFIG_NF_TABLES=y -# CONFIG_NF_TABLES_ARP is not set -CONFIG_NF_TABLES_BRIDGE=y -# CONFIG_NF_TABLES_INET is not set -CONFIG_NF_TABLES_IPV4=y -# CONFIG_NF_TABLES_IPV6 is not set CONFIG_NLS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y @@ -1046,7 +972,6 @@ CONFIG_RCU_CPU_STALL_TIMEOUT=21 CONFIG_RCU_STALL_COMMON=y CONFIG_RD_BZIP2=y CONFIG_RD_GZIP=y -CONFIG_RD_LZ4=y CONFIG_RD_LZMA=y CONFIG_RD_LZO=y CONFIG_RD_XZ=y @@ -1240,7 +1165,6 @@ CONFIG_USB_DWC3_DUAL_ROLE=y # CONFIG_USB_DWC3_HOST is not set CONFIG_USB_DWC3_OF_SIMPLE=y CONFIG_USB_DWC3_PCI=y -# CONFIG_USB_EHCI_FSL is not set CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_EHCI_PCI=y diff --git a/target/linux/layerscape/armv8_64b/profiles/00-default.mk b/target/linux/layerscape/armv8_64b/profiles/00-default.mk deleted file mode 100644 index fc1231dc7..000000000 --- a/target/linux/layerscape/armv8_64b/profiles/00-default.mk +++ /dev/null @@ -1,18 +0,0 @@ -define Profile/Default - NAME:=Default Profile - PRIORITY:=1 -endef - -define Profile/Default/Description - Default package set compatible with most boards. -endef - -DEFAULT_PACKAGES+= \ - rcw-layerscape-ls1043ardb uboot-layerscape-$(SUBTARGET)-ls1043ardb \ - fman-layerscape-ls1043ardb \ - rcw-layerscape-ls1046ardb uboot-layerscape-$(SUBTARGET)-ls1046ardb \ - fman-layerscape-ls1046ardb \ - rcw-layerscape-ls1012ardb uboot-layerscape-$(SUBTARGET)-ls1012ardb \ - kmod-ppfe ppfe-ls1012ardb - -$(eval $(call Profile,Default)) diff --git a/target/linux/layerscape/base-files/etc/rc.local b/target/linux/layerscape/base-files/etc/rc.local deleted file mode 100644 index 297c3a83d..000000000 --- a/target/linux/layerscape/base-files/etc/rc.local +++ /dev/null @@ -1,4 +0,0 @@ -# Put your custom commands here that should be executed once -# the system init finished. By default this file does nothing. -modprobe pfe.ko -exit 0 diff --git a/target/linux/layerscape/image/Makefile b/target/linux/layerscape/image/Makefile index 5577b1623..88bf8d7b4 100644 --- a/target/linux/layerscape/image/Makefile +++ b/target/linux/layerscape/image/Makefile @@ -16,10 +16,30 @@ define Build/append-ls-uboot dd if=$(STAGING_DIR_IMAGE)/$(1)-$(SUBTARGET)-uboot.bin >> $@ endef +define Build/append-ls-ppa + dd if=$(STAGING_DIR_IMAGE)/$(1)-ppa.itb >> $@ +endef + define Build/append-ls-fman dd if=$(STAGING_DIR_IMAGE)/$(1)-fman.bin >> $@ endef +define Build/append-ls-mc + dd if=$(STAGING_DIR_IMAGE)/$(1)-mc.itb >> $@ +endef + +define Build/append-ls-ppfe + dd if=$(STAGING_DIR_IMAGE)/pfe.itb >> $@ +endef + +define Build/append-ls-dpl + dd if=$(STAGING_DIR_IMAGE)/$(1)-dpl.dtb >> $@ +endef + +define Build/append-ls-dpc + dd if=$(STAGING_DIR_IMAGE)/$(1)-dpc.dtb >> $@ +endef + define Build/append-ls-dtb $(call Image/BuildDTB,$(DTS_DIR)/$(1).dts,$(DTS_DIR)/$(1).dtb) dd if=$(DTS_DIR)/$(1).dtb >> $@ @@ -51,10 +71,12 @@ endef define Device/ls1043ardb DEVICE_TITLE := ls1043ardb-$(SUBTARGET) - DEVICE_PACKAGES += rcw-layerscape-ls1043ardb uboot-layerscape-$(SUBTARGET)-ls1043ardb fman-layerscape-ls1043ardb + DEVICE_PACKAGES += rcw-layerscape-ls1043ardb uboot-layerscape-$(SUBTARGET)-ls1043ardb \ + fman-layerscape-ls1043ardb layerscape-ppa-ls1043ardb DEVICE_DTS = ../../../arm64/boot/dts/freescale/fsl-ls1043a-rdb-sdk IMAGE/firmware.bin = append-ls-rcw $(1) | pad-to 1M | \ - append-ls-uboot $(1) | pad-to 9M | \ + append-ls-uboot $(1) | pad-to 4M | \ + append-ls-ppa $(1) | pad-to 9M | \ append-ls-fman $(1) | pad-to 15M | \ append-ls-dtb $$(DEVICE_DTS) | pad-to 16M | \ append-kernel | pad-to 32M | \ @@ -64,47 +86,83 @@ TARGET_DEVICES += ls1043ardb define Device/ls1046ardb DEVICE_TITLE := ls1046ardb-$(SUBTARGET) - DEVICE_PACKAGES += rcw-layerscape-ls1046ardb uboot-layerscape-$(SUBTARGET)-ls1046ardb fman-layerscape-ls1046ardb + DEVICE_PACKAGES += rcw-layerscape-ls1046ardb uboot-layerscape-$(SUBTARGET)-ls1046ardb \ + fman-layerscape-ls1046ardb layerscape-ppa-ls1046ardb DEVICE_DTS = ../../../arm64/boot/dts/freescale/fsl-ls1046a-rdb-sdk IMAGE/firmware.bin = append-ls-rcw $(1) | pad-to 1M | \ - append-ls-uboot $(1) | pad-to 9M | \ + append-ls-uboot $(1) | pad-to 4M | \ + append-ls-ppa $(1) | pad-to 9M | \ append-ls-fman $(1) | pad-to 15M | \ append-ls-dtb $$(DEVICE_DTS) | pad-to 16M | \ append-kernel | pad-to 32M | \ - append-ls-rootfs-ext4 $(1) 22M | check-size 67108865 + append-ls-rootfs-ext4 $(1) 30M | check-size 67108865 endef TARGET_DEVICES += ls1046ardb define Device/ls1012ardb DEVICE_TITLE := ls1012ardb-$(SUBTARGET) - DEVICE_PACKAGES += rcw-layerscape-ls1012ardb uboot-layerscape-$(SUBTARGET)-ls1012ardb kmod-ppfe ppfe-ls1012ardb + DEVICE_PACKAGES += rcw-layerscape-ls1012ardb uboot-layerscape-$(SUBTARGET)-ls1012ardb \ + kmod-ppfe layerscape-ppfe layerscape-ppa-ls1012ardb DEVICE_DTS = ../../../arm64/boot/dts/freescale/fsl-ls1012a-rdb IMAGE/firmware.bin = append-ls-rcw $(1) | pad-to 1M | \ - append-ls-uboot $(1) | pad-to 15M | \ + append-ls-uboot $(1) | pad-to 4M | \ + append-ls-ppa $(1) | pad-to 10M | \ + append-ls-ppfe | pad-to 15M | \ append-ls-dtb $$(DEVICE_DTS) | pad-to 16M | \ append-kernel | pad-to 32M | \ - append-ls-rootfs-ext4 $(1) 23M | check-size 67108865 + append-ls-rootfs-ext4 $(1) 30M | check-size 67108865 endef TARGET_DEVICES += ls1012ardb +define Device/ls1012afrdm + DEVICE_TITLE := ls1012afrdm-$(SUBTARGET) + DEVICE_PACKAGES += rcw-layerscape-ls1012afrdm uboot-layerscape-$(SUBTARGET)-ls1012afrdm \ + kmod-ppfe layerscape-ppfe layerscape-ppa-ls1012afrdm + DEVICE_DTS = ../../../arm64/boot/dts/freescale/fsl-ls1012a-frdm + IMAGE/firmware.bin = append-ls-rcw $(1) | pad-to 1M | \ + append-ls-uboot $(1) | pad-to 4M | \ + append-ls-ppa $(1) | pad-to 10M | \ + append-ls-ppfe | pad-to 15M | \ + append-ls-dtb $$(DEVICE_DTS) | pad-to 16M | \ + append-kernel | pad-to 32M | \ + append-ls-rootfs-ext4 $(1) 30M | check-size 67108865 +endef +TARGET_DEVICES += ls1012afrdm + ifeq ($(SUBTARGET),armv8_64b) define Device/ls1088ardb DEVICE_TITLE := ls1088ardb-$(SUBTARGET) - DEVICE_PACKAGES += rcw-layerscape-ls1088ardb uboot-layerscape-$(SUBTARGET)-ls1088ardb mc-binary-ls1088ardb + DEVICE_PACKAGES += rcw-layerscape-ls1088ardb uboot-layerscape-$(SUBTARGET)-ls1088ardb \ + layerscape-mc-ls1088ardb layerscape-dpl-ls1088ardb restool \ + layerscape-ppa-ls1088ardb DEVICE_DTS = ../../../arm64/boot/dts/freescale/fsl-ls1088a-rdb - IMAGE/firmware.bin = append-ls-dtb $$(DEVICE_DTS) | pad-to 1M | \ - append-kernel | pad-to 17M | \ - append-ls-rootfs-ext4 $(1) 17M | check-size 51380225 + IMAGE/firmware.bin = append-ls-rcw $(1) | pad-to 1M | \ + append-ls-uboot $(1) | pad-to 4M | \ + append-ls-ppa $(1) | pad-to 10M | \ + append-ls-mc $(1) | pad-to 13M | \ + append-ls-dpl $(1) | pad-to 14M | \ + append-ls-dpc $(1) | pad-to 15M | \ + append-ls-dtb $$(DEVICE_DTS) | pad-to 16M | \ + append-kernel | pad-to 32M | \ + append-ls-rootfs-ext4 $(1) 30M | check-size 67108865 endef TARGET_DEVICES += ls1088ardb define Device/ls2088ardb DEVICE_TITLE := ls2088ardb-$(SUBTARGET) - DEVICE_PACKAGES += rcw-layerscape-ls2088ardb uboot-layerscape-$(SUBTARGET)-ls2088ardb mc-binary-ls2088ardb + DEVICE_PACKAGES += rcw-layerscape-ls2088ardb uboot-layerscape-$(SUBTARGET)-ls2088ardb \ + layerscape-mc-ls2088ardb layerscape-dpl-ls2088ardb restool \ + layerscape-ppa-ls2088ardb DEVICE_DTS = ../../../arm64/boot/dts/freescale/fsl-ls2088a-rdb - IMAGE/firmware.bin = append-ls-dtb $$(DEVICE_DTS) | pad-to 1M | \ - append-kernel | pad-to 17M | \ - append-rootfs | pad-rootfs | check-size 51380225 + IMAGE/firmware.bin = append-ls-rcw $(1) | pad-to 1M | \ + append-ls-uboot $(1) | pad-to 4M | \ + append-ls-ppa $(1) | pad-to 10M | \ + append-ls-mc $(1) | pad-to 13M | \ + append-ls-dpl $(1) | pad-to 14M | \ + append-ls-dpc $(1) | pad-to 15M | \ + append-ls-dtb $$(DEVICE_DTS) | pad-to 16M | \ + append-kernel | pad-to 32M | \ + append-rootfs | pad-rootfs | check-size 67108865 endef TARGET_DEVICES += ls2088ardb endif diff --git a/target/linux/layerscape/modules.mk b/target/linux/layerscape/modules.mk index 0b34f96b3..7a368a0d2 100644 --- a/target/linux/layerscape/modules.mk +++ b/target/linux/layerscape/modules.mk @@ -8,9 +8,10 @@ define KernelPackage/ppfe SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Freescale PPFE Driver support - KCONFIG:=CONFIG_FSL_PPFE + DEPENDS:=@TARGET_layerscape + KCONFIG:=CONFIG_FSL_PPFE CONFIG_FSL_PPFE_UTIL_DISABLED FILES:=$(LINUX_DIR)/drivers/staging/fsl_ppfe/pfe.ko - AUTOLOAD:=$(call AutoLoad,35,ppfe) + AUTOLOAD:=$(call AutoLoad,35,pfe) endef define KernelPackage/ppfe/description diff --git a/target/linux/layerscape/patches-4.9/201-config-support-layerscape.patch b/target/linux/layerscape/patches-4.9/201-config-support-layerscape.patch index 939880fd1..333a9d121 100644 --- a/target/linux/layerscape/patches-4.9/201-config-support-layerscape.patch +++ b/target/linux/layerscape/patches-4.9/201-config-support-layerscape.patch @@ -1,4 +1,4 @@ -From 11edf9c88acea13d1a02901289060263b4027a77 Mon Sep 17 00:00:00 2001 +From 7992b4384d94c5e1bad998ca3a9a5781caac8e62 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Mon, 25 Sep 2017 09:52:26 +0800 Subject: [PATCH] config: support layerscape @@ -30,11 +30,11 @@ Signed-off-by: Yangbo Lu drivers/soc/fsl/layerscape/Kconfig | 10 +++ drivers/soc/fsl/layerscape/Makefile | 1 + drivers/soc/fsl/rcpm.c | 154 ++++++++++++++++++++++++++++++++ - drivers/staging/Kconfig | 4 + - drivers/staging/Makefile | 2 + + drivers/staging/Kconfig | 6 ++ + drivers/staging/Makefile | 3 + drivers/staging/fsl-dpaa2/Kconfig | 41 +++++++++ drivers/staging/fsl-dpaa2/Makefile | 9 ++ - 18 files changed, 309 insertions(+), 4 deletions(-) + 18 files changed, 312 insertions(+), 4 deletions(-) create mode 100644 drivers/soc/fsl/Kconfig create mode 100644 drivers/soc/fsl/Kconfig.arm create mode 100644 drivers/soc/fsl/layerscape/Kconfig @@ -407,16 +407,18 @@ Signed-off-by: Yangbo Lu source "drivers/staging/wilc1000/Kconfig" source "drivers/staging/most/Kconfig" -@@ -106,4 +108,6 @@ source "drivers/staging/greybus/Kconfig" +@@ -106,4 +108,8 @@ source "drivers/staging/greybus/Kconfig" source "drivers/staging/vc04_services/Kconfig" +source "drivers/staging/fsl_qbman/Kconfig" ++ ++source "drivers/staging/fsl_ppfe/Kconfig" + endif # STAGING --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile -@@ -36,9 +36,11 @@ obj-$(CONFIG_UNISYSSPAR) += unisys/ +@@ -36,9 +36,12 @@ obj-$(CONFIG_UNISYSSPAR) += unisys/ obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/ obj-$(CONFIG_FB_TFT) += fbtft/ obj-$(CONFIG_FSL_MC_BUS) += fsl-mc/ @@ -428,6 +430,7 @@ Signed-off-by: Yangbo Lu obj-$(CONFIG_GREYBUS) += greybus/ obj-$(CONFIG_BCM2708_VCHIQ) += vc04_services/ +obj-$(CONFIG_FSL_SDK_DPA) += fsl_qbman/ ++obj-$(CONFIG_FSL_PPFE) += fsl_ppfe/ --- /dev/null +++ b/drivers/staging/fsl-dpaa2/Kconfig @@ -0,0 +1,41 @@ diff --git a/target/linux/layerscape/patches-4.9/202-core-linux-support-layerscape.patch b/target/linux/layerscape/patches-4.9/202-core-linux-support-layerscape.patch new file mode 100644 index 000000000..45b3c7ae6 --- /dev/null +++ b/target/linux/layerscape/patches-4.9/202-core-linux-support-layerscape.patch @@ -0,0 +1,508 @@ +From c37953457a7ebeb0d97ae8574b3d41274fcd9119 Mon Sep 17 00:00:00 2001 +From: Yangbo Lu +Date: Wed, 1 Nov 2017 16:22:33 +0800 +Subject: [PATCH] core-linux: support layerscape + +This is a integrated patch for layerscape core-linux support. + +Signed-off-by: Madalin Bucur +Signed-off-by: Zhao Qiang +Signed-off-by: Camelia Groza +Signed-off-by: Madalin Bucur +Signed-off-by: Zhang Ying-22455 +Signed-off-by: Ramneek Mehresh +Signed-off-by: Jarod Wilson +Signed-off-by: Nikhil Badola +Signed-off-by: stephen hemminger +Signed-off-by: Arnd Bergmann +Signed-off-by: Yangbo Lu +--- + drivers/base/devres.c | 66 ++++++++++++++++++++++++++++ + drivers/base/soc.c | 66 ++++++++++++++++++++++++++++ + include/linux/device.h | 19 ++++++++ + include/linux/fsl/svr.h | 97 +++++++++++++++++++++++++++++++++++++++++ + include/linux/fsl_devices.h | 3 ++ + include/linux/netdev_features.h | 2 + + include/linux/netdevice.h | 4 ++ + include/linux/skbuff.h | 2 + + include/linux/sys_soc.h | 3 ++ + include/uapi/linux/if_ether.h | 1 + + net/core/dev.c | 13 +++++- + net/core/skbuff.c | 29 +++++++++++- + net/sched/sch_generic.c | 7 +++ + 13 files changed, 309 insertions(+), 3 deletions(-) + create mode 100644 include/linux/fsl/svr.h + +--- a/drivers/base/devres.c ++++ b/drivers/base/devres.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #include "base.h" + +@@ -985,3 +986,68 @@ void devm_free_pages(struct device *dev, + &devres)); + } + EXPORT_SYMBOL_GPL(devm_free_pages); ++ ++static void devm_percpu_release(struct device *dev, void *pdata) ++{ ++ void __percpu *p; ++ ++ p = *(void __percpu **)pdata; ++ free_percpu(p); ++} ++ ++static int devm_percpu_match(struct device *dev, void *data, void *p) ++{ ++ struct devres *devr = container_of(data, struct devres, data); ++ ++ return *(void **)devr->data == p; ++} ++ ++/** ++ * __devm_alloc_percpu - Resource-managed alloc_percpu ++ * @dev: Device to allocate per-cpu memory for ++ * @size: Size of per-cpu memory to allocate ++ * @align: Alignment of per-cpu memory to allocate ++ * ++ * Managed alloc_percpu. Per-cpu memory allocated with this function is ++ * automatically freed on driver detach. ++ * ++ * RETURNS: ++ * Pointer to allocated memory on success, NULL on failure. ++ */ ++void __percpu *__devm_alloc_percpu(struct device *dev, size_t size, ++ size_t align) ++{ ++ void *p; ++ void __percpu *pcpu; ++ ++ pcpu = __alloc_percpu(size, align); ++ if (!pcpu) ++ return NULL; ++ ++ p = devres_alloc(devm_percpu_release, sizeof(void *), GFP_KERNEL); ++ if (!p) { ++ free_percpu(pcpu); ++ return NULL; ++ } ++ ++ *(void __percpu **)p = pcpu; ++ ++ devres_add(dev, p); ++ ++ return pcpu; ++} ++EXPORT_SYMBOL_GPL(__devm_alloc_percpu); ++ ++/** ++ * devm_free_percpu - Resource-managed free_percpu ++ * @dev: Device this memory belongs to ++ * @pdata: Per-cpu memory to free ++ * ++ * Free memory allocated with devm_alloc_percpu(). ++ */ ++void devm_free_percpu(struct device *dev, void __percpu *pdata) ++{ ++ WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match, ++ (void *)pdata)); ++} ++EXPORT_SYMBOL_GPL(devm_free_percpu); +--- a/drivers/base/soc.c ++++ b/drivers/base/soc.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + + static DEFINE_IDA(soc_ida); + +@@ -159,3 +160,68 @@ static int __init soc_bus_register(void) + return bus_register(&soc_bus_type); + } + core_initcall(soc_bus_register); ++ ++static int soc_device_match_one(struct device *dev, void *arg) ++{ ++ struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); ++ const struct soc_device_attribute *match = arg; ++ ++ if (match->machine && ++ !glob_match(match->machine, soc_dev->attr->machine)) ++ return 0; ++ ++ if (match->family && ++ !glob_match(match->family, soc_dev->attr->family)) ++ return 0; ++ ++ if (match->revision && ++ !glob_match(match->revision, soc_dev->attr->revision)) ++ return 0; ++ ++ if (match->soc_id && ++ !glob_match(match->soc_id, soc_dev->attr->soc_id)) ++ return 0; ++ ++ return 1; ++} ++ ++/* ++ * soc_device_match - identify the SoC in the machine ++ * @matches: zero-terminated array of possible matches ++ * ++ * returns the first matching entry of the argument array, or NULL ++ * if none of them match. ++ * ++ * This function is meant as a helper in place of of_match_node() ++ * in cases where either no device tree is available or the information ++ * in a device node is insufficient to identify a particular variant ++ * by its compatible strings or other properties. For new devices, ++ * the DT binding should always provide unique compatible strings ++ * that allow the use of of_match_node() instead. ++ * ++ * The calling function can use the .data entry of the ++ * soc_device_attribute to pass a structure or function pointer for ++ * each entry. ++ */ ++const struct soc_device_attribute *soc_device_match( ++ const struct soc_device_attribute *matches) ++{ ++ int ret = 0; ++ ++ if (!matches) ++ return NULL; ++ ++ while (!ret) { ++ if (!(matches->machine || matches->family || ++ matches->revision || matches->soc_id)) ++ break; ++ ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches, ++ soc_device_match_one); ++ if (!ret) ++ matches++; ++ else ++ return matches; ++ } ++ return NULL; ++} ++EXPORT_SYMBOL_GPL(soc_device_match); +--- a/include/linux/device.h ++++ b/include/linux/device.h +@@ -688,6 +688,25 @@ void __iomem *devm_ioremap_resource(stru + int devm_add_action(struct device *dev, void (*action)(void *), void *data); + void devm_remove_action(struct device *dev, void (*action)(void *), void *data); + ++/** ++ * devm_alloc_percpu - Resource-managed alloc_percpu ++ * @dev: Device to allocate per-cpu memory for ++ * @type: Type to allocate per-cpu memory for ++ * ++ * Managed alloc_percpu. Per-cpu memory allocated with this function is ++ * automatically freed on driver detach. ++ * ++ * RETURNS: ++ * Pointer to allocated memory on success, NULL on failure. ++ */ ++#define devm_alloc_percpu(dev, type) \ ++ ((typeof(type) __percpu *)__devm_alloc_percpu((dev), sizeof(type), \ ++ __alignof__(type))) ++ ++void __percpu *__devm_alloc_percpu(struct device *dev, size_t size, ++ size_t align); ++void devm_free_percpu(struct device *dev, void __percpu *pdata); ++ + static inline int devm_add_action_or_reset(struct device *dev, + void (*action)(void *), void *data) + { +--- /dev/null ++++ b/include/linux/fsl/svr.h +@@ -0,0 +1,97 @@ ++/* ++ * MPC85xx cpu type detection ++ * ++ * Copyright 2011-2012 Freescale Semiconductor, Inc. ++ * ++ * This 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. ++ */ ++ ++#ifndef FSL_SVR_H ++#define FSL_SVR_H ++ ++#define SVR_REV(svr) ((svr) & 0xFF) /* SOC design resision */ ++#define SVR_MAJ(svr) (((svr) >> 4) & 0xF) /* Major revision field*/ ++#define SVR_MIN(svr) (((svr) >> 0) & 0xF) /* Minor revision field*/ ++ ++/* Some parts define SVR[0:23] as the SOC version */ ++#define SVR_SOC_VER(svr) (((svr) >> 8) & 0xFFF7FF) /* SOC Version fields */ ++ ++#define SVR_8533 0x803400 ++#define SVR_8535 0x803701 ++#define SVR_8536 0x803700 ++#define SVR_8540 0x803000 ++#define SVR_8541 0x807200 ++#define SVR_8543 0x803200 ++#define SVR_8544 0x803401 ++#define SVR_8545 0x803102 ++#define SVR_8547 0x803101 ++#define SVR_8548 0x803100 ++#define SVR_8555 0x807100 ++#define SVR_8560 0x807000 ++#define SVR_8567 0x807501 ++#define SVR_8568 0x807500 ++#define SVR_8569 0x808000 ++#define SVR_8572 0x80E000 ++#define SVR_P1010 0x80F100 ++#define SVR_P1011 0x80E500 ++#define SVR_P1012 0x80E501 ++#define SVR_P1013 0x80E700 ++#define SVR_P1014 0x80F101 ++#define SVR_P1017 0x80F700 ++#define SVR_P1020 0x80E400 ++#define SVR_P1021 0x80E401 ++#define SVR_P1022 0x80E600 ++#define SVR_P1023 0x80F600 ++#define SVR_P1024 0x80E402 ++#define SVR_P1025 0x80E403 ++#define SVR_P2010 0x80E300 ++#define SVR_P2020 0x80E200 ++#define SVR_P2040 0x821000 ++#define SVR_P2041 0x821001 ++#define SVR_P3041 0x821103 ++#define SVR_P4040 0x820100 ++#define SVR_P4080 0x820000 ++#define SVR_P5010 0x822100 ++#define SVR_P5020 0x822000 ++#define SVR_P5021 0X820500 ++#define SVR_P5040 0x820400 ++#define SVR_T4240 0x824000 ++#define SVR_T4120 0x824001 ++#define SVR_T4160 0x824100 ++#define SVR_T4080 0x824102 ++#define SVR_C291 0x850000 ++#define SVR_C292 0x850020 ++#define SVR_C293 0x850030 ++#define SVR_B4860 0X868000 ++#define SVR_G4860 0x868001 ++#define SVR_G4060 0x868003 ++#define SVR_B4440 0x868100 ++#define SVR_G4440 0x868101 ++#define SVR_B4420 0x868102 ++#define SVR_B4220 0x868103 ++#define SVR_T1040 0x852000 ++#define SVR_T1041 0x852001 ++#define SVR_T1042 0x852002 ++#define SVR_T1020 0x852100 ++#define SVR_T1021 0x852101 ++#define SVR_T1022 0x852102 ++#define SVR_T1023 0x854100 ++#define SVR_T1024 0x854000 ++#define SVR_T2080 0x853000 ++#define SVR_T2081 0x853100 ++ ++#define SVR_8610 0x80A000 ++#define SVR_8641 0x809000 ++#define SVR_8641D 0x809001 ++ ++#define SVR_9130 0x860001 ++#define SVR_9131 0x860000 ++#define SVR_9132 0x861000 ++#define SVR_9232 0x861400 ++ ++#define SVR_Unknown 0xFFFFFF ++ ++#endif +--- a/include/linux/fsl_devices.h ++++ b/include/linux/fsl_devices.h +@@ -99,7 +99,10 @@ struct fsl_usb2_platform_data { + unsigned suspended:1; + unsigned already_suspended:1; + unsigned has_fsl_erratum_a007792:1; ++ unsigned has_fsl_erratum_14:1; + unsigned has_fsl_erratum_a005275:1; ++ unsigned has_fsl_erratum_a006918:1; ++ unsigned has_fsl_erratum_a005697:1; + unsigned check_phy_clk_valid:1; + + /* register save area for suspend/resume */ +--- a/include/linux/netdev_features.h ++++ b/include/linux/netdev_features.h +@@ -74,6 +74,7 @@ enum { + NETIF_F_BUSY_POLL_BIT, /* Busy poll */ + + NETIF_F_HW_TC_BIT, /* Offload TC infrastructure */ ++ NETIF_F_HW_ACCEL_MQ_BIT, /* Hardware-accelerated multiqueue */ + + /* + * Add your fresh new feature above and remember to update +@@ -136,6 +137,7 @@ enum { + #define NETIF_F_HW_L2FW_DOFFLOAD __NETIF_F(HW_L2FW_DOFFLOAD) + #define NETIF_F_BUSY_POLL __NETIF_F(BUSY_POLL) + #define NETIF_F_HW_TC __NETIF_F(HW_TC) ++#define NETIF_F_HW_ACCEL_MQ __NETIF_F(HW_ACCEL_MQ) + + #define for_each_netdev_feature(mask_addr, bit) \ + for_each_set_bit(bit, (unsigned long *)mask_addr, NETDEV_FEATURE_COUNT) +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1509,6 +1509,8 @@ enum netdev_priv_flags { + * @if_port: Selectable AUI, TP, ... + * @dma: DMA channel + * @mtu: Interface MTU value ++ * @min_mtu: Interface Minimum MTU value ++ * @max_mtu: Interface Maximum MTU value + * @type: Interface hardware type + * @hard_header_len: Maximum hardware header length. + * @min_header_len: Minimum hardware header length +@@ -1735,6 +1737,8 @@ struct net_device { + unsigned char dma; + + unsigned int mtu; ++ unsigned int min_mtu; ++ unsigned int max_mtu; + unsigned short type; + unsigned short hard_header_len; + unsigned short min_header_len; +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -903,6 +903,7 @@ void kfree_skb(struct sk_buff *skb); + void kfree_skb_list(struct sk_buff *segs); + void skb_tx_error(struct sk_buff *skb); + void consume_skb(struct sk_buff *skb); ++void skb_recycle(struct sk_buff *skb); + void __kfree_skb(struct sk_buff *skb); + extern struct kmem_cache *skbuff_head_cache; + +@@ -3057,6 +3058,7 @@ static inline void skb_free_datagram_loc + } + int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags); + int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len); ++void copy_skb_header(struct sk_buff *new, const struct sk_buff *old); + int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len); + __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, u8 *to, + int len, __wsum csum); +--- a/include/linux/sys_soc.h ++++ b/include/linux/sys_soc.h +@@ -13,6 +13,7 @@ struct soc_device_attribute { + const char *family; + const char *revision; + const char *soc_id; ++ const void *data; + }; + + /** +@@ -34,4 +35,6 @@ void soc_device_unregister(struct soc_de + */ + struct device *soc_device_to_device(struct soc_device *soc); + ++const struct soc_device_attribute *soc_device_match( ++ const struct soc_device_attribute *matches); + #endif /* __SOC_BUS_H */ +--- a/include/uapi/linux/if_ether.h ++++ b/include/uapi/linux/if_ether.h +@@ -35,6 +35,7 @@ + #define ETH_DATA_LEN 1500 /* Max. octets in payload */ + #define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ + #define ETH_FCS_LEN 4 /* Octets in the FCS */ ++#define ETH_MIN_MTU 68 /* Min IPv4 MTU per RFC791 */ + + /* + * These are the defined Ethernet Protocol ID's. +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -6603,9 +6603,18 @@ int dev_set_mtu(struct net_device *dev, + if (new_mtu == dev->mtu) + return 0; + +- /* MTU must be positive. */ +- if (new_mtu < 0) ++ /* MTU must be positive, and in range */ ++ if (new_mtu < 0 || new_mtu < dev->min_mtu) { ++ net_err_ratelimited("%s: Invalid MTU %d requested, hw min %d\n", ++ dev->name, new_mtu, dev->min_mtu); + return -EINVAL; ++ } ++ ++ if (dev->max_mtu > 0 && new_mtu > dev->max_mtu) { ++ net_err_ratelimited("%s: Invalid MTU %d requested, hw max %d\n", ++ dev->name, new_mtu, dev->min_mtu); ++ return -EINVAL; ++ } + + if (!netif_device_present(dev)) + return -ENODEV; +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -842,6 +842,32 @@ void napi_consume_skb(struct sk_buff *sk + } + EXPORT_SYMBOL(napi_consume_skb); + ++/** ++ * skb_recycle - clean up an skb for reuse ++ * @skb: buffer ++ * ++ * Recycles the skb to be reused as a receive buffer. This ++ * function does any necessary reference count dropping, and ++ * cleans up the skbuff as if it just came from __alloc_skb(). ++ */ ++void skb_recycle(struct sk_buff *skb) ++{ ++ struct skb_shared_info *shinfo; ++ u8 head_frag = skb->head_frag; ++ ++ skb_release_head_state(skb); ++ ++ shinfo = skb_shinfo(skb); ++ memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); ++ atomic_set(&shinfo->dataref, 1); ++ ++ memset(skb, 0, offsetof(struct sk_buff, tail)); ++ skb->data = skb->head + NET_SKB_PAD; ++ skb->head_frag = head_frag; ++ skb_reset_tail_pointer(skb); ++} ++EXPORT_SYMBOL(skb_recycle); ++ + /* Make sure a field is enclosed inside headers_start/headers_end section */ + #define CHECK_SKB_FIELD(field) \ + BUILD_BUG_ON(offsetof(struct sk_buff, field) < \ +@@ -1073,7 +1099,7 @@ static void skb_headers_offset_update(st + skb->inner_mac_header += off; + } + +-static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) ++void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) + { + __copy_skb_header(new, old); + +@@ -1081,6 +1107,7 @@ static void copy_skb_header(struct sk_bu + skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; + skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type; + } ++EXPORT_SYMBOL(copy_skb_header); + + static inline int skb_alloc_rx_flag(const struct sk_buff *skb) + { +--- a/net/sched/sch_generic.c ++++ b/net/sched/sch_generic.c +@@ -309,6 +309,13 @@ static void dev_watchdog(unsigned long a + txq->trans_timeout++; + break; + } ++ ++ /* Devices with HW_ACCEL_MQ have multiple txqs ++ * but update only the first one's transmission ++ * timestamp so avoid checking the rest. ++ */ ++ if (dev->features & NETIF_F_HW_ACCEL_MQ) ++ break; + } + + if (some_queue_timedout) { diff --git a/target/linux/layerscape/patches-4.9/301-arch-support-layerscape.patch b/target/linux/layerscape/patches-4.9/301-arch-support-layerscape.patch index 3a2e9c64b..66860a0bb 100644 --- a/target/linux/layerscape/patches-4.9/301-arch-support-layerscape.patch +++ b/target/linux/layerscape/patches-4.9/301-arch-support-layerscape.patch @@ -1,4 +1,4 @@ -From 7edaf7ed8fbd5fb50950a4fc8067a9c14557d010 Mon Sep 17 00:00:00 2001 +From 739029f49bd9181b821298f9d27b29ce2d292967 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Mon, 25 Sep 2017 10:03:52 +0800 Subject: [PATCH] arch: support layerscape @@ -34,8 +34,8 @@ Signed-off-by: Yangbo Lu arch/arm64/include/asm/pgtable-prot.h | 1 + arch/arm64/include/asm/pgtable.h | 5 +++ arch/arm64/kernel/pci.c | 62 +++++++++++++++++++++++++++++++++++ - arch/arm64/mm/dma-mapping.c | 6 ++++ - 15 files changed, 197 insertions(+), 3 deletions(-) + arch/arm64/mm/dma-mapping.c | 23 ++++++++++--- + 15 files changed, 209 insertions(+), 8 deletions(-) --- a/arch/arm/include/asm/delay.h +++ b/arch/arm/include/asm/delay.h @@ -410,7 +410,7 @@ Signed-off-by: Yangbo Lu static int swiotlb __ro_after_init; -@@ -918,6 +919,10 @@ static int __init __iommu_dma_init(void) +@@ -925,6 +926,10 @@ static int __init __iommu_dma_init(void) if (!ret) ret = register_iommu_dma_ops_notifier(&pci_bus_type); #endif @@ -421,7 +421,7 @@ Signed-off-by: Yangbo Lu return ret; } arch_initcall(__iommu_dma_init); -@@ -971,3 +976,4 @@ void arch_setup_dma_ops(struct device *d +@@ -978,3 +983,4 @@ void arch_setup_dma_ops(struct device *d dev->archdata.dma_coherent = coherent; __iommu_setup_dma_ops(dev, dma_base, size, iommu); } diff --git a/target/linux/layerscape/patches-4.9/302-dts-support-layercape.patch b/target/linux/layerscape/patches-4.9/302-dts-support-layercape.patch index a7a3a48e6..7dae7d6ac 100644 --- a/target/linux/layerscape/patches-4.9/302-dts-support-layercape.patch +++ b/target/linux/layerscape/patches-4.9/302-dts-support-layercape.patch @@ -1,4 +1,4 @@ -From 2b2e3b9a0d2abf276b40843f75d97b623e4ee109 Mon Sep 17 00:00:00 2001 +From bfa4a794f91162cfeccfa4d59121cde9a84e32a3 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Mon, 25 Sep 2017 10:02:10 +0800 Subject: [PATCH] dts: support layercape @@ -45,10 +45,10 @@ Signed-off-by: Yangbo Lu arch/arm/boot/dts/sun8i-a23-a33.dtsi | 2 +- arch/arm/boot/dts/sun9i-a80.dtsi | 2 +- arch/arm64/boot/dts/freescale/Makefile | 16 + - arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts | 134 +++ - arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts | 155 ++++ - arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts | 91 +++ - arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 517 ++++++++++++ + arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts | 177 ++++ + arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts | 198 +++++ + arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts | 134 +++ + arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 594 ++++++++++++++ arch/arm64/boot/dts/freescale/fsl-ls1043-post.dtsi | 45 + .../boot/dts/freescale/fsl-ls1043a-qds-sdk.dts | 69 ++ arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts | 171 +++- @@ -65,7 +65,7 @@ Signed-off-by: Yangbo Lu arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 793 ++++++++++++++++++ arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts | 173 ++++ arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts | 236 ++++++ - arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 816 ++++++++++++++++++ + arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 818 ++++++++++++++++++ arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts | 191 ++--- arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts | 169 ++-- arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts | 9 +- @@ -76,7 +76,7 @@ Signed-off-by: Yangbo Lu arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi | 195 +++++ arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi | 198 +++++ arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi | 161 ++++ - arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 910 +++++++++++++++++++++ + arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 912 +++++++++++++++++++++ .../boot/dts/freescale/qoriq-bman1-portals.dtsi | 81 ++ arch/arm64/boot/dts/freescale/qoriq-dpaa-eth.dtsi | 66 ++ .../boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi | 43 + @@ -93,7 +93,7 @@ Signed-off-by: Yangbo Lu arch/powerpc/boot/dts/fsl/qoriq-bman1-portals.dtsi | 10 + arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi | 4 +- arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi | 4 +- - 66 files changed, 7778 insertions(+), 1021 deletions(-) + 66 files changed, 7988 insertions(+), 1021 deletions(-) create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts @@ -484,7 +484,7 @@ Signed-off-by: Yangbo Lu }; + ftm0: ftm0@29d0000 { -+ compatible = "fsl,ftm-alarm"; ++ compatible = "fsl,ls1021a-ftm"; + reg = <0x0 0x29d0000 0x0 0x10000>, + <0x0 0x1ee2140 0x0 0x4>; + reg-names = "ftm", "FlexTimer1"; @@ -740,7 +740,7 @@ Signed-off-by: Yangbo Lu subdir-y := $(dts-dirs) --- /dev/null +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts -@@ -0,0 +1,134 @@ +@@ -0,0 +1,177 @@ +/* + * Device Tree file for Freescale LS1012A Freedom Board. + * @@ -792,6 +792,11 @@ Signed-off-by: Yangbo Lu + model = "LS1012A Freedom Board"; + compatible = "fsl,ls1012a-frdm", "fsl,ls1012a"; + ++ aliases { ++ ethernet0 = &pfe_mac0; ++ ethernet1 = &pfe_mac1; ++ }; ++ + sys_mclk: clock-mclk { + compatible = "fixed-clock"; + #clock-cells = <0>; @@ -868,6 +873,44 @@ Signed-off-by: Yangbo Lu + }; +}; + ++&pfe { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ethernet@0 { ++ compatible = "fsl,pfe-gemac-port"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0x0>; /* GEM_ID */ ++ fsl,gemac-bus-id = <0x0>; /* BUS_ID */ ++ fsl,gemac-phy-id = <0x2>; /* PHY_ID */ ++ fsl,mdio-mux-val = <0x0>; ++ phy-mode = "sgmii"; ++ fsl,pfe-phy-if-flags = <0x0>; ++ ++ mdio@0 { ++ reg = <0x1>; /* enabled/disabled */ ++ }; ++ }; ++ ++ ethernet@1 { ++ compatible = "fsl,pfe-gemac-port"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0x1>; /* GEM_ID */ ++ fsl,gemac-bus-id = <0x1>; /* BUS_ID */ ++ fsl,gemac-phy-id = <0x1>; /* PHY_ID */ ++ fsl,mdio-mux-val = <0x0>; ++ phy-mode = "sgmii"; ++ fsl,pfe-phy-if-flags = <0x0>; ++ ++ mdio@0 { ++ reg = <0x0>; /* enabled/disabled */ ++ }; ++ }; ++}; ++ +&sai2 { + status = "okay"; +}; @@ -877,7 +920,7 @@ Signed-off-by: Yangbo Lu +}; --- /dev/null +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts -@@ -0,0 +1,155 @@ +@@ -0,0 +1,198 @@ +/* + * Device Tree file for Freescale LS1012A QDS Board. + * @@ -929,6 +972,11 @@ Signed-off-by: Yangbo Lu + model = "LS1012A QDS Board"; + compatible = "fsl,ls1012a-qds", "fsl,ls1012a"; + ++ aliases { ++ ethernet0 = &pfe_mac0; ++ ethernet1 = &pfe_mac1; ++ }; ++ + sys_mclk: clock-mclk { + compatible = "fixed-clock"; + #clock-cells = <0>; @@ -1018,6 +1066,44 @@ Signed-off-by: Yangbo Lu + }; +}; + ++&pfe { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ethernet@0 { ++ compatible = "fsl,pfe-gemac-port"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0x0>; /* GEM_ID */ ++ fsl,gemac-bus-id = <0x0>; /* BUS_ID */ ++ fsl,gemac-phy-id = <0x1>; /* PHY_ID */ ++ fsl,mdio-mux-val = <0x2>; ++ phy-mode = "sgmii-2500"; ++ fsl,pfe-phy-if-flags = <0x0>; ++ ++ mdio@0 { ++ reg = <0x1>; /* enabled/disabled */ ++ }; ++ }; ++ ++ ethernet@1 { ++ compatible = "fsl,pfe-gemac-port"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0x1>; /* GEM_ID */ ++ fsl,gemac-bus-id = <0x1>; /* BUS_ID */ ++ fsl,gemac-phy-id = <0x2>; /* PHY_ID */ ++ fsl,mdio-mux-val = <0x3>; ++ phy-mode = "sgmii-2500"; ++ fsl,pfe-phy-if-flags = <0x0>; ++ ++ mdio@0 { ++ reg = <0x0>; /* enabled/disabled */ ++ }; ++ }; ++}; ++ +&sai2 { + status = "okay"; +}; @@ -1035,7 +1121,7 @@ Signed-off-by: Yangbo Lu +}; --- /dev/null +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts -@@ -0,0 +1,91 @@ +@@ -0,0 +1,134 @@ +/* + * Device Tree file for Freescale LS1012A RDB Board. + * @@ -1086,6 +1172,11 @@ Signed-off-by: Yangbo Lu +/ { + model = "LS1012A RDB Board"; + compatible = "fsl,ls1012a-rdb", "fsl,ls1012a"; ++ ++ aliases { ++ ethernet0 = &pfe_mac0; ++ ethernet1 = &pfe_mac1; ++ }; +}; + +&duart0 { @@ -1127,9 +1218,47 @@ Signed-off-by: Yangbo Lu + mmc-hs200-1_8v; + status = "okay"; +}; ++ ++&pfe { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ethernet@0 { ++ compatible = "fsl,pfe-gemac-port"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0x0>; /* GEM_ID */ ++ fsl,gemac-bus-id = <0x0>; /* BUS_ID */ ++ fsl,gemac-phy-id = <0x2>; /* PHY_ID */ ++ fsl,mdio-mux-val = <0x0>; ++ phy-mode = "sgmii"; ++ fsl,pfe-phy-if-flags = <0x0>; ++ ++ mdio@0 { ++ reg = <0x1>; /* enabled/disabled */ ++ }; ++ }; ++ ++ ethernet@1 { ++ compatible = "fsl,pfe-gemac-port"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0x1>; /* GEM_ID */ ++ fsl,gemac-bus-id = < 0x1 >; /* BUS_ID */ ++ fsl,gemac-phy-id = < 0x1 >; /* PHY_ID */ ++ fsl,mdio-mux-val = <0x0>; ++ phy-mode = "rgmii-txid"; ++ fsl,pfe-phy-if-flags = <0x0>; ++ ++ mdio@0 { ++ reg = <0x0>; /* enabled/disabled */ ++ }; ++ }; ++}; --- /dev/null +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -@@ -0,0 +1,517 @@ +@@ -0,0 +1,594 @@ +/* + * Device Tree Include file for Freescale Layerscape-1012A family SoC. + * @@ -1322,6 +1451,12 @@ Signed-off-by: Yangbo Lu + interrupts = ; + }; + ++ caam-dma { ++ compatible = "fsl,sec-v5.4-dma", ++ "fsl,sec-v5.0-dma", ++ "fsl,sec-v4.0-dma"; ++ }; ++ + rtic@60000 { + compatible = "fsl,sec-v5.4-rtic", + "fsl,sec-v5.0-rtic", @@ -1485,8 +1620,14 @@ Signed-off-by: Yangbo Lu + status = "disabled"; + }; + ++ rcpm: rcpm@1ee2000 { ++ compatible = "fsl,ls1012a-rcpm", "fsl,qoriq-rcpm-2.1"; ++ reg = <0x0 0x1ee2000 0x0 0x1000>; ++ fsl,#rcpm-wakeup-cells = <1>; ++ }; ++ + ftm0: ftm0@29d0000 { -+ compatible = "fsl,ftm-alarm"; ++ compatible = "fsl,ls1012a-ftm"; + reg = <0x0 0x29d0000 0x0 0x10000>, + <0x0 0x1ee2140 0x0 0x4>; + reg-names = "ftm", "FlexTimer1"; @@ -1645,6 +1786,71 @@ Signed-off-by: Yangbo Lu + dma-coherent; + status = "disabled"; + }; ++ ++ msi: msi-controller1@1572000 { ++ compatible = "fsl,ls1012a-msi"; ++ reg = <0x0 0x1572000 0x0 0x8>; ++ msi-controller; ++ interrupts = <0 126 IRQ_TYPE_LEVEL_HIGH>; ++ }; ++ ++ pcie@3400000 { ++ compatible = "fsl,ls1012a-pcie", "snps,dw-pcie"; ++ reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ ++ 0x40 0x00000000 0x0 0x00002000>; /* configuration space */ ++ reg-names = "regs", "config"; ++ interrupts = <0 118 0x4>, /* AER interrupt */ ++ <0 117 0x4>; /* PME interrupt */ ++ interrupt-names = "aer", "pme"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ num-lanes = <4>; ++ bus-range = <0x0 0xff>; ++ ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ ++ 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ ++ msi-parent = <&msi>; ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 7>; ++ interrupt-map = <0000 0 0 1 &gic 0 110 IRQ_TYPE_LEVEL_HIGH>, ++ <0000 0 0 2 &gic 0 111 IRQ_TYPE_LEVEL_HIGH>, ++ <0000 0 0 3 &gic 0 112 IRQ_TYPE_LEVEL_HIGH>, ++ <0000 0 0 4 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>; ++ }; ++ }; ++ ++ reserved-memory { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ pfe_reserved: packetbuffer@83400000 { ++ reg = <0 0x83400000 0 0xc00000>; ++ }; ++ }; ++ ++ pfe: pfe@04000000 { ++ compatible = "fsl,pfe"; ++ reg = <0x0 0x04000000 0x0 0xc00000>, /* AXI 16M */ ++ <0x0 0x83400000 0x0 0xc00000>; /* PFE DDR 12M */ ++ reg-names = "pfe", "pfe-ddr"; ++ fsl,pfe-num-interfaces = <0x2>; ++ interrupts = <0 172 0x4>, /* HIF interrupt */ ++ <0 173 0x4>, /*HIF_NOCPY interrupt */ ++ <0 174 0x4>; /* WoL interrupt */ ++ interrupt-names = "pfe_hif", "pfe_hif_nocpy", "pfe_wol"; ++ memory-region = <&pfe_reserved>; ++ fsl,pfe-scfg = <&scfg 0>; ++ fsl,rcpm-wakeup = <&rcpm 0xf0000020>; ++ clocks = <&clockgen 4 0>; ++ clock-names = "pfe"; ++ ++ status = "okay"; ++ pfe_mac0: ethernet@0 { ++ }; ++ ++ pfe_mac1: ethernet@1 { ++ }; + }; +}; --- /dev/null @@ -2646,7 +2852,7 @@ Signed-off-by: Yangbo Lu }; + ftm0: ftm0@29d0000 { -+ compatible = "fsl,ftm-alarm"; ++ compatible = "fsl,ls1043a-ftm"; + reg = <0x0 0x29d0000 0x0 0x10000>, + <0x0 0x1ee2140 0x0 0x4>; + reg-names = "ftm", "FlexTimer1"; @@ -4326,7 +4532,7 @@ Signed-off-by: Yangbo Lu + }; + + ftm0: ftm0@29d0000 { -+ compatible = "fsl,ftm-alarm"; ++ compatible = "fsl,ls1046a-ftm"; + reg = <0x0 0x29d0000 0x0 0x10000>, + <0x0 0x1ee2140 0x0 0x4>; + reg-names = "ftm", "FlexTimer1"; @@ -4962,7 +5168,7 @@ Signed-off-by: Yangbo Lu +}; --- /dev/null +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -@@ -0,0 +1,816 @@ +@@ -0,0 +1,818 @@ +/* + * Device Tree Include file for NXP Layerscape-1088A family SoC. + * @@ -5475,9 +5681,11 @@ Signed-off-by: Yangbo Lu + }; + + ftm0: ftm0@2800000 { -+ compatible = "fsl,ftm-alarm"; -+ reg = <0x0 0x2800000 0x0 0x10000>; ++ compatible = "fsl,ls1088a-ftm"; ++ reg = <0x0 0x2800000 0x0 0x10000>, ++ <0x0 0x1e34050 0x0 0x4>; + interrupts = <0 44 4>; ++ reg-names = "ftm", "FlexTimer1"; + }; + + i2c0: i2c@2000000 { @@ -8124,7 +8332,7 @@ Signed-off-by: Yangbo Lu +}; --- /dev/null +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -@@ -0,0 +1,910 @@ +@@ -0,0 +1,912 @@ +/* + * Device Tree Include file for Freescale Layerscape-2080A family SoC. + * @@ -9015,9 +9223,11 @@ Signed-off-by: Yangbo Lu + }; + + ftm0: ftm0@2800000 { -+ compatible = "fsl,ftm-alarm"; -+ reg = <0x0 0x2800000 0x0 0x10000>; ++ compatible = "fsl,ls208xa-ftm"; ++ reg = <0x0 0x2800000 0x0 0x10000>, ++ <0x0 0x1e34050 0x0 0x4>; + interrupts = <0 44 4>; ++ reg-names = "ftm", "FlexTimer1"; + }; + }; + diff --git a/target/linux/layerscape/patches-4.9/303-arm-imx-select-ARCH_DMA_ADDR_T_64BIT-for-LPAE.patch b/target/linux/layerscape/patches-4.9/303-arm-imx-select-ARCH_DMA_ADDR_T_64BIT-for-LPAE.patch new file mode 100644 index 000000000..097c4320f --- /dev/null +++ b/target/linux/layerscape/patches-4.9/303-arm-imx-select-ARCH_DMA_ADDR_T_64BIT-for-LPAE.patch @@ -0,0 +1,23 @@ +From c079739fa1101dcf7a1e40a195e019065e327d15 Mon Sep 17 00:00:00 2001 +From: Yangbo Lu +Date: Fri, 20 Oct 2017 16:45:17 +0800 +Subject: [PATCH] arm: imx: select ARCH_DMA_ADDR_T_64BIT for LPAE + +Selected ARCH_DMA_ADDR_T_64BIT for LPAE since +hardware could support it. + +Signed-off-by: Yangbo Lu +--- + arch/arm/mach-imx/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm/mach-imx/Kconfig ++++ b/arch/arm/mach-imx/Kconfig +@@ -1,6 +1,7 @@ + menuconfig ARCH_MXC + bool "Freescale i.MX family" + depends on ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 || ARM_SINGLE_ARMV7M ++ select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE + select ARCH_SUPPORTS_BIG_ENDIAN + select CLKSRC_IMX_GPT + select GENERIC_IRQ_CHIP diff --git a/target/linux/layerscape/patches-4.9/401-mtd-spi-nor-support-layerscape.patch b/target/linux/layerscape/patches-4.9/401-mtd-spi-nor-support-layerscape.patch index 445a6fa02..362777317 100644 --- a/target/linux/layerscape/patches-4.9/401-mtd-spi-nor-support-layerscape.patch +++ b/target/linux/layerscape/patches-4.9/401-mtd-spi-nor-support-layerscape.patch @@ -1,4 +1,4 @@ -From 120fa458ffe2250ea58578ccfc85e674005463dc Mon Sep 17 00:00:00 2001 +From a3757157751a8a5302ee5e11faf828dc5db02018 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Mon, 25 Sep 2017 10:53:50 +0800 Subject: [PATCH] mtd: spi-nor: support layerscape @@ -18,10 +18,10 @@ Signed-off-by: Ash Benz Signed-off-by: Yangbo Lu --- drivers/mtd/mtdchar.c | 2 +- - drivers/mtd/spi-nor/fsl-quadspi.c | 356 +++++++++++++++++++++++++++++++------- - drivers/mtd/spi-nor/spi-nor.c | 136 +++++++++++++-- + drivers/mtd/spi-nor/fsl-quadspi.c | 327 +++++++++++++++++++++++++++++++------- + drivers/mtd/spi-nor/spi-nor.c | 136 ++++++++++++++-- include/linux/mtd/spi-nor.h | 14 +- - 4 files changed, 432 insertions(+), 76 deletions(-) + 4 files changed, 409 insertions(+), 70 deletions(-) --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -209,13 +209,15 @@ Signed-off-by: Yangbo Lu fsl_qspi_unlock_lut(q); -@@ -382,25 +449,51 @@ static void fsl_qspi_init_lut(struct fsl +@@ -382,24 +449,50 @@ static void fsl_qspi_init_lut(struct fsl for (i = 0; i < QUADSPI_LUT_NUM; i++) qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4); - /* Quad Read */ - lut_base = SEQID_QUAD_READ * 4; -- ++ /* Read */ ++ lut_base = SEQID_READ * 4; + - if (q->nor_size <= SZ_16M) { - cmd = SPINOR_OP_READ_1_1_4; - addrlen = ADDR24BIT; @@ -226,9 +228,7 @@ Signed-off-by: Yangbo Lu - addrlen = ADDR32BIT; - dummy = 8; - } -+ /* Read */ -+ lut_base = SEQID_READ * 4; - +- - qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen), + if (nor->flash_read == SPI_NOR_FAST) { + qspi_writel(q, LUT0(CMD, PAD1, read_op) | @@ -242,10 +242,11 @@ Signed-off-by: Yangbo Lu + read_op = 0xEC; + qspi_writel(q, + LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD4, addrlen), -+ base + QUADSPI_LUT(lut_base)); + base + QUADSPI_LUT(lut_base)); +- qspi_writel(q, LUT0(DUMMY, PAD1, dummy) | LUT1(FSL_READ, PAD4, rxfifo), + qspi_writel(q, + LUT0(MODE, PAD4, 0xff) | LUT1(DUMMY, PAD4, read_dm), -+ base + QUADSPI_LUT(lut_base + 1)); + base + QUADSPI_LUT(lut_base + 1)); + qspi_writel(q, + LUT0(FSL_READ, PAD4, rxfifo), + base + QUADSPI_LUT(lut_base + 2)); @@ -261,21 +262,19 @@ Signed-off-by: Yangbo Lu + /* read mode : 1-4-4, such as Spansion s25fl128s. */ + qspi_writel(q, LUT0(CMD, PAD1, read_op) + | LUT1(ADDR_DDR, PAD4, addrlen), - base + QUADSPI_LUT(lut_base)); -- qspi_writel(q, LUT0(DUMMY, PAD1, dummy) | LUT1(FSL_READ, PAD4, rxfifo), ++ base + QUADSPI_LUT(lut_base)); + + qspi_writel(q, LUT0(MODE_DDR, PAD4, 0xff) + | LUT1(DUMMY, PAD1, read_dm), - base + QUADSPI_LUT(lut_base + 1)); - ++ base + QUADSPI_LUT(lut_base + 1)); ++ + qspi_writel(q, LUT0(FSL_READ_DDR, PAD4, rxfifo) + | LUT1(JMP_ON_CS, PAD1, 0), + base + QUADSPI_LUT(lut_base + 2)); + } -+ + /* Write enable */ lut_base = SEQID_WREN * 4; - qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN), @@ -409,16 +502,8 @@ static void fsl_qspi_init_lut(struct fsl /* Page Program */ lut_base = SEQID_PP * 4; @@ -501,50 +500,7 @@ Signed-off-by: Yangbo Lu } /* -@@ -681,19 +860,36 @@ static void fsl_qspi_init_abh_read(struc - { - void __iomem *base = q->iobase; - int seqid; -+ const struct fsl_qspi_devtype_data *devtype_data = q->devtype_data; - - /* AHB configuration for access buffer 0/1/2 .*/ - qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR); - qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR); - qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR); -+ - /* -- * Set ADATSZ with the maximum AHB buffer size to improve the -- * read performance. -+ * Errata: A-009282: QuadSPI data prefetch may result in incorrect data -+ * Workaround: Keep the read data size to 64 bits (8 bytes). -+ * This disables the prefetch on the AHB buffer and -+ * prevents this issue from occurring. - */ -- qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK | -- ((q->devtype_data->ahb_buf_size / 8) -- << QUADSPI_BUF3CR_ADATSZ_SHIFT), -- base + QUADSPI_BUF3CR); -+ if (devtype_data->devtype == FSL_QUADSPI_LS2080A || -+ devtype_data->devtype == FSL_QUADSPI_LS1021A) { -+ -+ qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK | -+ (1 << QUADSPI_BUF3CR_ADATSZ_SHIFT), -+ base + QUADSPI_BUF3CR); -+ -+ } else { -+ /* -+ * Set ADATSZ with the maximum AHB buffer size to improve the -+ * read performance. -+ */ -+ qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK | -+ ((q->devtype_data->ahb_buf_size / 8) -+ << QUADSPI_BUF3CR_ADATSZ_SHIFT), -+ base + QUADSPI_BUF3CR); -+ } - - /* We only use the buffer3 */ - qspi_writel(q, 0, base + QUADSPI_BUF0IND); -@@ -704,6 +900,11 @@ static void fsl_qspi_init_abh_read(struc +@@ -704,6 +883,11 @@ static void fsl_qspi_init_abh_read(struc seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode); qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT, q->iobase + QUADSPI_BFGENCR); @@ -556,7 +512,7 @@ Signed-off-by: Yangbo Lu } /* This function was used to prepare and enable QSPI clock */ -@@ -822,6 +1023,7 @@ static const struct of_device_id fsl_qsp +@@ -822,6 +1006,7 @@ static const struct of_device_id fsl_qsp { .compatible = "fsl,imx7d-qspi", .data = (void *)&imx7d_data, }, { .compatible = "fsl,imx6ul-qspi", .data = (void *)&imx6ul_data, }, { .compatible = "fsl,ls1021a-qspi", .data = (void *)&ls1021a_data, }, @@ -564,21 +520,21 @@ Signed-off-by: Yangbo Lu { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids); -@@ -835,8 +1037,12 @@ static int fsl_qspi_read_reg(struct spi_ +@@ -835,8 +1020,12 @@ static int fsl_qspi_read_reg(struct spi_ { int ret; struct fsl_qspi *q = nor->priv; + u32 to = 0; -+ -+ if (opcode == SPINOR_OP_SPANSION_RDAR) -+ u8tou32(&to, nor->cmd_buf, 4); - ret = fsl_qspi_runcmd(q, opcode, 0, len); ++ if (opcode == SPINOR_OP_SPANSION_RDAR) ++ u8tou32(&to, nor->cmd_buf, 4); ++ + ret = fsl_qspi_runcmd(q, opcode, to, len); if (ret) return ret; -@@ -848,9 +1054,13 @@ static int fsl_qspi_write_reg(struct spi +@@ -848,9 +1037,13 @@ static int fsl_qspi_write_reg(struct spi { struct fsl_qspi *q = nor->priv; int ret; @@ -593,7 +549,7 @@ Signed-off-by: Yangbo Lu if (ret) return ret; -@@ -859,7 +1069,7 @@ static int fsl_qspi_write_reg(struct spi +@@ -859,7 +1052,7 @@ static int fsl_qspi_write_reg(struct spi } else if (len > 0) { ret = fsl_qspi_nor_write(q, nor, opcode, 0, @@ -602,7 +558,7 @@ Signed-off-by: Yangbo Lu if (ret > 0) return 0; } else { -@@ -875,7 +1085,7 @@ static ssize_t fsl_qspi_write(struct spi +@@ -875,7 +1068,7 @@ static ssize_t fsl_qspi_write(struct spi { struct fsl_qspi *q = nor->priv; ssize_t ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to, @@ -611,7 +567,7 @@ Signed-off-by: Yangbo Lu /* invalid the data in the AHB buffer. */ fsl_qspi_invalid(q); -@@ -922,7 +1132,7 @@ static ssize_t fsl_qspi_read(struct spi_ +@@ -922,7 +1115,7 @@ static ssize_t fsl_qspi_read(struct spi_ len); /* Read out the data directly from the AHB buffer.*/ @@ -620,7 +576,7 @@ Signed-off-by: Yangbo Lu len); return len; -@@ -980,6 +1190,8 @@ static int fsl_qspi_probe(struct platfor +@@ -980,6 +1173,8 @@ static int fsl_qspi_probe(struct platfor struct spi_nor *nor; struct mtd_info *mtd; int ret, i = 0; @@ -629,7 +585,7 @@ Signed-off-by: Yangbo Lu q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL); if (!q) -@@ -1027,6 +1239,12 @@ static int fsl_qspi_probe(struct platfor +@@ -1027,6 +1222,12 @@ static int fsl_qspi_probe(struct platfor goto clk_failed; } @@ -642,7 +598,7 @@ Signed-off-by: Yangbo Lu /* find the irq */ ret = platform_get_irq(pdev, 0); if (ret < 0) { -@@ -1050,6 +1268,7 @@ static int fsl_qspi_probe(struct platfor +@@ -1050,6 +1251,7 @@ static int fsl_qspi_probe(struct platfor mutex_init(&q->lock); @@ -650,7 +606,7 @@ Signed-off-by: Yangbo Lu /* iterate the subnodes. */ for_each_available_child_of_node(dev->of_node, np) { /* skip the holes */ -@@ -1076,18 +1295,25 @@ static int fsl_qspi_probe(struct platfor +@@ -1076,18 +1278,25 @@ static int fsl_qspi_probe(struct platfor ret = of_property_read_u32(np, "spi-max-frequency", &q->clk_rate); if (ret < 0) @@ -680,7 +636,7 @@ Signed-off-by: Yangbo Lu /* Set the correct NOR size now. */ if (q->nor_size == 0) { -@@ -1110,8 +1336,12 @@ static int fsl_qspi_probe(struct platfor +@@ -1110,8 +1319,12 @@ static int fsl_qspi_probe(struct platfor nor->page_size = q->devtype_data->txfifo; i++; @@ -935,7 +891,7 @@ Signed-off-by: Yangbo Lu #ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS /* prefer "small sector" erase if possible */ -@@ -1676,9 +1783,15 @@ int spi_nor_scan(struct spi_nor *nor, co +@@ -1678,9 +1785,15 @@ int spi_nor_scan(struct spi_nor *nor, co /* 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; @@ -954,7 +910,7 @@ Signed-off-by: Yangbo Lu ret = set_quad_mode(nor, info); if (ret) { dev_err(dev, "quad mode not supported\n"); -@@ -1691,6 +1804,9 @@ int spi_nor_scan(struct spi_nor *nor, co +@@ -1693,6 +1806,9 @@ int spi_nor_scan(struct spi_nor *nor, co /* Default commands */ switch (nor->flash_read) { diff --git a/target/linux/layerscape/patches-4.9/601-net-support-layerscape.patch b/target/linux/layerscape/patches-4.9/601-net-support-layerscape.patch deleted file mode 100644 index 9db40dc2f..000000000 --- a/target/linux/layerscape/patches-4.9/601-net-support-layerscape.patch +++ /dev/null @@ -1,2365 +0,0 @@ -From 2ed7bff3d1f2fa6c5f6eff0b2bd98deaa3dc18b0 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Mon, 25 Sep 2017 10:57:14 +0800 -Subject: [PATCH] net: support layerscape - -This is a integrated patch for layerscape net support. - -Signed-off-by: Madalin Bucur -Signed-off-by: Zhao Qiang -Signed-off-by: Camelia Groza -Signed-off-by: Madalin Bucur -Signed-off-by: Zhang Ying-22455 -Signed-off-by: Ramneek Mehresh -Signed-off-by: Jarod Wilson -Signed-off-by: Nikhil Badola -Signed-off-by: stephen hemminger -Signed-off-by: Arnd Bergmann -Signed-off-by: Yangbo Lu ---- - drivers/base/devres.c | 66 +++++++++++++++ - drivers/base/soc.c | 66 +++++++++++++++ - drivers/net/bonding/bond_main.c | 10 +-- - drivers/net/dummy.c | 5 +- - drivers/net/ethernet/amazon/ena/ena_netdev.c | 10 +-- - drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 6 +- - drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 4 +- - drivers/net/ethernet/atheros/alx/main.c | 6 +- - drivers/net/ethernet/broadcom/b44.c | 5 +- - drivers/net/ethernet/broadcom/bnx2.c | 5 +- - drivers/net/ethernet/broadcom/bnxt/bnxt.c | 6 +- - drivers/net/ethernet/broadcom/tg3.c | 8 +- - drivers/net/ethernet/brocade/bna/bnad.c | 6 +- - drivers/net/ethernet/calxeda/xgmac.c | 5 +- - drivers/net/ethernet/cavium/thunder/nicvf_main.c | 5 +- - drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 7 +- - drivers/net/ethernet/cisco/enic/enic_main.c | 8 +- - drivers/net/ethernet/ec_bhf.c | 4 +- - drivers/net/ethernet/emulex/benet/be_main.c | 5 +- - drivers/net/ethernet/hisilicon/hns/hns_enet.c | 6 +- - drivers/net/ethernet/ibm/ehea/ehea_main.c | 5 +- - drivers/net/ethernet/intel/e1000e/e1000.h | 4 +- - drivers/net/ethernet/intel/e1000e/netdev.c | 5 +- - drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 6 +- - drivers/net/ethernet/intel/i40e/i40e.h | 5 +- - drivers/net/ethernet/intel/i40e/i40e_main.c | 18 ++-- - drivers/net/ethernet/intel/igb/igb_main.c | 10 +-- - drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 7 +- - drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 6 +- - drivers/net/ethernet/marvell/mvneta.c | 4 +- - drivers/net/ethernet/marvell/mvpp2.c | 4 +- - drivers/net/ethernet/marvell/sky2.c | 6 +- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 +- - drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 4 +- - drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 3 +- - drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 4 +- - drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 3 +- - drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 9 +- - drivers/net/ethernet/neterion/vxge/vxge-main.c | 4 +- - .../net/ethernet/netronome/nfp/nfp_net_common.c | 6 +- - drivers/net/ethernet/nvidia/forcedeth.c | 4 +- - .../net/ethernet/qlogic/netxen/netxen_nic_main.c | 10 +-- - drivers/net/ethernet/qlogic/qede/qede_main.c | 7 +- - drivers/net/ethernet/qualcomm/emac/emac.c | 6 +- - drivers/net/ethernet/realtek/8139too.c | 9 +- - drivers/net/ethernet/realtek/r8169.c | 4 +- - drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 8 +- - drivers/net/ethernet/sfc/efx.c | 6 +- - drivers/net/ethernet/sun/niu.c | 6 +- - drivers/net/ethernet/synopsys/dwc_eth_qos.c | 4 +- - drivers/net/ethernet/tile/tilepro.c | 4 +- - drivers/net/ethernet/via/via-rhine.c | 8 +- - drivers/net/fjes/fjes_main.c | 7 +- - drivers/net/hyperv/netvsc_drv.c | 6 +- - drivers/net/ifb.c | 6 +- - drivers/net/ipvlan/ipvlan_main.c | 5 +- - drivers/net/loopback.c | 5 +- - drivers/net/macsec.c | 8 +- - drivers/net/macvlan.c | 5 +- - drivers/net/nlmon.c | 4 +- - drivers/net/ppp/ppp_generic.c | 4 +- - drivers/net/slip/slip.c | 3 +- - drivers/net/team/team.c | 3 +- - drivers/net/tun.c | 3 +- - drivers/net/veth.c | 6 +- - drivers/net/virtio_net.c | 6 +- - drivers/net/vmxnet3/vmxnet3_ethtool.c | 4 +- - drivers/net/vmxnet3/vmxnet3_int.h | 4 +- - drivers/net/vrf.c | 5 +- - drivers/net/xen-netfront.c | 6 +- - drivers/staging/netlogic/xlr_net.c | 10 +-- - include/linux/device.h | 19 +++++ - include/linux/fsl/svr.h | 97 ++++++++++++++++++++++ - include/linux/fsl_devices.h | 3 + - include/linux/netdev_features.h | 2 + - include/linux/netdevice.h | 12 ++- - include/linux/skbuff.h | 2 + - include/linux/sys_soc.h | 3 + - include/net/ip_tunnels.h | 4 +- - include/uapi/linux/if_ether.h | 1 + - net/8021q/vlan_dev.c | 5 +- - net/bridge/br_device.c | 6 +- - net/core/dev.c | 13 ++- - net/core/skbuff.c | 29 ++++++- - net/ipv4/ip_tunnel_core.c | 6 +- - net/l2tp/l2tp_eth.c | 6 +- - net/mac80211/iface.c | 4 +- - net/openvswitch/vport-internal_dev.c | 4 +- - net/sched/sch_generic.c | 7 ++ - net/sched/sch_teql.c | 5 +- - 90 files changed, 468 insertions(+), 298 deletions(-) - create mode 100644 include/linux/fsl/svr.h - ---- a/drivers/base/devres.c -+++ b/drivers/base/devres.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - #include "base.h" - -@@ -985,3 +986,68 @@ void devm_free_pages(struct device *dev, - &devres)); - } - EXPORT_SYMBOL_GPL(devm_free_pages); -+ -+static void devm_percpu_release(struct device *dev, void *pdata) -+{ -+ void __percpu *p; -+ -+ p = *(void __percpu **)pdata; -+ free_percpu(p); -+} -+ -+static int devm_percpu_match(struct device *dev, void *data, void *p) -+{ -+ struct devres *devr = container_of(data, struct devres, data); -+ -+ return *(void **)devr->data == p; -+} -+ -+/** -+ * __devm_alloc_percpu - Resource-managed alloc_percpu -+ * @dev: Device to allocate per-cpu memory for -+ * @size: Size of per-cpu memory to allocate -+ * @align: Alignment of per-cpu memory to allocate -+ * -+ * Managed alloc_percpu. Per-cpu memory allocated with this function is -+ * automatically freed on driver detach. -+ * -+ * RETURNS: -+ * Pointer to allocated memory on success, NULL on failure. -+ */ -+void __percpu *__devm_alloc_percpu(struct device *dev, size_t size, -+ size_t align) -+{ -+ void *p; -+ void __percpu *pcpu; -+ -+ pcpu = __alloc_percpu(size, align); -+ if (!pcpu) -+ return NULL; -+ -+ p = devres_alloc(devm_percpu_release, sizeof(void *), GFP_KERNEL); -+ if (!p) { -+ free_percpu(pcpu); -+ return NULL; -+ } -+ -+ *(void __percpu **)p = pcpu; -+ -+ devres_add(dev, p); -+ -+ return pcpu; -+} -+EXPORT_SYMBOL_GPL(__devm_alloc_percpu); -+ -+/** -+ * devm_free_percpu - Resource-managed free_percpu -+ * @dev: Device this memory belongs to -+ * @pdata: Per-cpu memory to free -+ * -+ * Free memory allocated with devm_alloc_percpu(). -+ */ -+void devm_free_percpu(struct device *dev, void __percpu *pdata) -+{ -+ WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match, -+ (void *)pdata)); -+} -+EXPORT_SYMBOL_GPL(devm_free_percpu); ---- a/drivers/base/soc.c -+++ b/drivers/base/soc.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - - static DEFINE_IDA(soc_ida); - -@@ -159,3 +160,68 @@ static int __init soc_bus_register(void) - return bus_register(&soc_bus_type); - } - core_initcall(soc_bus_register); -+ -+static int soc_device_match_one(struct device *dev, void *arg) -+{ -+ struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); -+ const struct soc_device_attribute *match = arg; -+ -+ if (match->machine && -+ !glob_match(match->machine, soc_dev->attr->machine)) -+ return 0; -+ -+ if (match->family && -+ !glob_match(match->family, soc_dev->attr->family)) -+ return 0; -+ -+ if (match->revision && -+ !glob_match(match->revision, soc_dev->attr->revision)) -+ return 0; -+ -+ if (match->soc_id && -+ !glob_match(match->soc_id, soc_dev->attr->soc_id)) -+ return 0; -+ -+ return 1; -+} -+ -+/* -+ * soc_device_match - identify the SoC in the machine -+ * @matches: zero-terminated array of possible matches -+ * -+ * returns the first matching entry of the argument array, or NULL -+ * if none of them match. -+ * -+ * This function is meant as a helper in place of of_match_node() -+ * in cases where either no device tree is available or the information -+ * in a device node is insufficient to identify a particular variant -+ * by its compatible strings or other properties. For new devices, -+ * the DT binding should always provide unique compatible strings -+ * that allow the use of of_match_node() instead. -+ * -+ * The calling function can use the .data entry of the -+ * soc_device_attribute to pass a structure or function pointer for -+ * each entry. -+ */ -+const struct soc_device_attribute *soc_device_match( -+ const struct soc_device_attribute *matches) -+{ -+ int ret = 0; -+ -+ if (!matches) -+ return NULL; -+ -+ while (!ret) { -+ if (!(matches->machine || matches->family || -+ matches->revision || matches->soc_id)) -+ break; -+ ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches, -+ soc_device_match_one); -+ if (!ret) -+ matches++; -+ else -+ return matches; -+ } -+ return NULL; -+} -+EXPORT_SYMBOL_GPL(soc_device_match); ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -211,8 +211,8 @@ static int lacp_fast; - - static int bond_init(struct net_device *bond_dev); - static void bond_uninit(struct net_device *bond_dev); --static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev, -- struct rtnl_link_stats64 *stats); -+static void bond_get_stats(struct net_device *bond_dev, -+ struct rtnl_link_stats64 *stats); - static void bond_slave_arr_handler(struct work_struct *work); - static bool bond_time_in_interval(struct bonding *bond, unsigned long last_act, - int mod); -@@ -3336,8 +3336,8 @@ static void bond_fold_stats(struct rtnl_ - } - } - --static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev, -- struct rtnl_link_stats64 *stats) -+static void bond_get_stats(struct net_device *bond_dev, -+ struct rtnl_link_stats64 *stats) - { - struct bonding *bond = netdev_priv(bond_dev); - struct rtnl_link_stats64 temp; -@@ -3361,8 +3361,6 @@ static struct rtnl_link_stats64 *bond_ge - - memcpy(&bond->bond_stats, stats, sizeof(*stats)); - spin_unlock(&bond->stats_lock); -- -- return stats; - } - - static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd) ---- a/drivers/net/dummy.c -+++ b/drivers/net/dummy.c -@@ -54,8 +54,8 @@ struct pcpu_dstats { - struct u64_stats_sync syncp; - }; - --static struct rtnl_link_stats64 *dummy_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void dummy_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - int i; - -@@ -73,7 +73,6 @@ static struct rtnl_link_stats64 *dummy_g - stats->tx_bytes += tbytes; - stats->tx_packets += tpackets; - } -- return stats; - } - - static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev) ---- a/drivers/net/ethernet/amazon/ena/ena_netdev.c -+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c -@@ -2172,19 +2172,19 @@ err: - ena_com_delete_debug_area(adapter->ena_dev); - } - --static struct rtnl_link_stats64 *ena_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+static void ena_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct ena_adapter *adapter = netdev_priv(netdev); - struct ena_admin_basic_stats ena_stats; - int rc; - - if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags)) -- return NULL; -+ return; - - rc = ena_com_get_dev_basic_stats(adapter->ena_dev, &ena_stats); - if (rc) -- return NULL; -+ return; - - stats->tx_bytes = ((u64)ena_stats.tx_bytes_high << 32) | - ena_stats.tx_bytes_low; -@@ -2211,8 +2211,6 @@ static struct rtnl_link_stats64 *ena_get - - stats->rx_errors = 0; - stats->tx_errors = 0; -- -- return stats; - } - - static const struct net_device_ops ena_netdev_ops = { ---- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c -+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c -@@ -1542,8 +1542,8 @@ static void xgbe_tx_timeout(struct net_d - schedule_work(&pdata->restart_work); - } - --static struct rtnl_link_stats64 *xgbe_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *s) -+static void xgbe_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *s) - { - struct xgbe_prv_data *pdata = netdev_priv(netdev); - struct xgbe_mmc_stats *pstats = &pdata->mmc_stats; -@@ -1569,8 +1569,6 @@ static struct rtnl_link_stats64 *xgbe_ge - s->tx_dropped = netdev->stats.tx_dropped; - - DBGPR("<--%s\n", __func__); -- -- return s; - } - - static int xgbe_vlan_rx_add_vid(struct net_device *netdev, __be16 proto, ---- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c -+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c -@@ -1199,7 +1199,7 @@ err: - return ret; - } - --static struct rtnl_link_stats64 *xgene_enet_get_stats64( -+static void xgene_enet_get_stats64( - struct net_device *ndev, - struct rtnl_link_stats64 *storage) - { -@@ -1230,8 +1230,6 @@ static struct rtnl_link_stats64 *xgene_e - } - } - memcpy(storage, stats, sizeof(struct rtnl_link_stats64)); -- -- return storage; - } - - static int xgene_enet_set_mac_address(struct net_device *ndev, void *addr) ---- a/drivers/net/ethernet/atheros/alx/main.c -+++ b/drivers/net/ethernet/atheros/alx/main.c -@@ -1424,8 +1424,8 @@ static void alx_poll_controller(struct n - } - #endif - --static struct rtnl_link_stats64 *alx_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *net_stats) -+static void alx_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *net_stats) - { - struct alx_priv *alx = netdev_priv(dev); - struct alx_hw_stats *hw_stats = &alx->hw.stats; -@@ -1469,8 +1469,6 @@ static struct rtnl_link_stats64 *alx_get - net_stats->rx_packets = hw_stats->rx_ok + net_stats->rx_errors; - - spin_unlock(&alx->stats_lock); -- -- return net_stats; - } - - static const struct net_device_ops alx_netdev_ops = { ---- a/drivers/net/ethernet/broadcom/b44.c -+++ b/drivers/net/ethernet/broadcom/b44.c -@@ -1677,8 +1677,8 @@ static int b44_close(struct net_device * - return 0; - } - --static struct rtnl_link_stats64 *b44_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *nstat) -+static void b44_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *nstat) - { - struct b44 *bp = netdev_priv(dev); - struct b44_hw_stats *hwstat = &bp->hw_stats; -@@ -1721,7 +1721,6 @@ static struct rtnl_link_stats64 *b44_get - #endif - } while (u64_stats_fetch_retry_irq(&hwstat->syncp, start)); - -- return nstat; - } - - static int __b44_load_mcast(struct b44 *bp, struct net_device *dev) ---- a/drivers/net/ethernet/broadcom/bnx2.c -+++ b/drivers/net/ethernet/broadcom/bnx2.c -@@ -6828,13 +6828,13 @@ bnx2_save_stats(struct bnx2 *bp) - (unsigned long) (bp->stats_blk->ctr + \ - bp->temp_stats_blk->ctr) - --static struct rtnl_link_stats64 * -+static void - bnx2_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats) - { - struct bnx2 *bp = netdev_priv(dev); - - if (bp->stats_blk == NULL) -- return net_stats; -+ return; - - net_stats->rx_packets = - GET_64BIT_NET_STATS(stat_IfHCInUcastPkts) + -@@ -6898,7 +6898,6 @@ bnx2_get_stats64(struct net_device *dev, - GET_32BIT_NET_STATS(stat_IfInMBUFDiscards) + - GET_32BIT_NET_STATS(stat_FwRxDrop); - -- return net_stats; - } - - /* All ethtool functions called with rtnl_lock */ ---- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c -+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c -@@ -5664,7 +5664,7 @@ static int bnxt_ioctl(struct net_device - return -EOPNOTSUPP; - } - --static struct rtnl_link_stats64 * -+static void - bnxt_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - u32 i; -@@ -5673,7 +5673,7 @@ bnxt_get_stats64(struct net_device *dev, - memset(stats, 0, sizeof(struct rtnl_link_stats64)); - - if (!bp->bnapi) -- return stats; -+ return; - - /* TODO check if we need to synchronize with bnxt_close path */ - for (i = 0; i < bp->cp_nr_rings; i++) { -@@ -5720,8 +5720,6 @@ bnxt_get_stats64(struct net_device *dev, - stats->tx_fifo_errors = le64_to_cpu(tx->tx_fifo_underruns); - stats->tx_errors = le64_to_cpu(tx->tx_err); - } -- -- return stats; - } - - static bool bnxt_mc_list_updated(struct bnxt *bp, u32 *rx_mask) ---- a/drivers/net/ethernet/broadcom/tg3.c -+++ b/drivers/net/ethernet/broadcom/tg3.c -@@ -14145,8 +14145,8 @@ static const struct ethtool_ops tg3_etht - .set_link_ksettings = tg3_set_link_ksettings, - }; - --static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void tg3_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct tg3 *tp = netdev_priv(dev); - -@@ -14154,13 +14154,11 @@ static struct rtnl_link_stats64 *tg3_get - if (!tp->hw_stats) { - *stats = tp->net_stats_prev; - spin_unlock_bh(&tp->lock); -- return stats; -+ return; - } - - tg3_get_nstats(tp, stats); - spin_unlock_bh(&tp->lock); -- -- return stats; - } - - static void tg3_set_rx_mode(struct net_device *dev) ---- a/drivers/net/ethernet/brocade/bna/bnad.c -+++ b/drivers/net/ethernet/brocade/bna/bnad.c -@@ -3111,7 +3111,7 @@ bnad_start_xmit(struct sk_buff *skb, str - * Used spin_lock to synchronize reading of stats structures, which - * is written by BNA under the same lock. - */ --static struct rtnl_link_stats64 * -+static void - bnad_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) - { - struct bnad *bnad = netdev_priv(netdev); -@@ -3123,8 +3123,6 @@ bnad_get_stats64(struct net_device *netd - bnad_netdev_hwstats_fill(bnad, stats); - - spin_unlock_irqrestore(&bnad->bna_lock, flags); -- -- return stats; - } - - static void -@@ -3430,7 +3428,7 @@ static const struct net_device_ops bnad_ - .ndo_open = bnad_open, - .ndo_stop = bnad_stop, - .ndo_start_xmit = bnad_start_xmit, -- .ndo_get_stats64 = bnad_get_stats64, -+ .ndo_get_stats64 = bnad_get_stats64, - .ndo_set_rx_mode = bnad_set_rx_mode, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = bnad_set_mac_address, ---- a/drivers/net/ethernet/calxeda/xgmac.c -+++ b/drivers/net/ethernet/calxeda/xgmac.c -@@ -1460,9 +1460,9 @@ static void xgmac_poll_controller(struct - } - #endif - --static struct rtnl_link_stats64 * -+static void - xgmac_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *storage) -+ struct rtnl_link_stats64 *storage) - { - struct xgmac_priv *priv = netdev_priv(dev); - void __iomem *base = priv->base; -@@ -1490,7 +1490,6 @@ xgmac_get_stats64(struct net_device *dev - - writel(0, base + XGMAC_MMC_CTRL); - spin_unlock_bh(&priv->stats_lock); -- return storage; - } - - static int xgmac_set_mac_address(struct net_device *dev, void *p) ---- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c -+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c -@@ -1423,8 +1423,8 @@ void nicvf_update_stats(struct nicvf *ni - nicvf_update_sq_stats(nic, qidx); - } - --static struct rtnl_link_stats64 *nicvf_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+static void nicvf_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct nicvf *nic = netdev_priv(netdev); - struct nicvf_hw_stats *hw_stats = &nic->hw_stats; -@@ -1440,7 +1440,6 @@ static struct rtnl_link_stats64 *nicvf_g - stats->tx_packets = hw_stats->tx_frames; - stats->tx_dropped = hw_stats->tx_drops; - -- return stats; - } - - static void nicvf_tx_timeout(struct net_device *dev) ---- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c -+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c -@@ -2383,8 +2383,8 @@ int cxgb4_remove_server_filter(const str - } - EXPORT_SYMBOL(cxgb4_remove_server_filter); - --static struct rtnl_link_stats64 *cxgb_get_stats(struct net_device *dev, -- struct rtnl_link_stats64 *ns) -+static void cxgb_get_stats(struct net_device *dev, -+ struct rtnl_link_stats64 *ns) - { - struct port_stats stats; - struct port_info *p = netdev_priv(dev); -@@ -2397,7 +2397,7 @@ static struct rtnl_link_stats64 *cxgb_ge - spin_lock(&adapter->stats_lock); - if (!netif_device_present(dev)) { - spin_unlock(&adapter->stats_lock); -- return ns; -+ return; - } - t4_get_port_stats_offset(adapter, p->tx_chan, &stats, - &p->stats_base); -@@ -2431,7 +2431,6 @@ static struct rtnl_link_stats64 *cxgb_ge - ns->tx_errors = stats.tx_error_frames; - ns->rx_errors = stats.rx_symbol_err + stats.rx_fcs_err + - ns->rx_length_errors + stats.rx_len_err + ns->rx_fifo_errors; -- return ns; - } - - static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd) ---- a/drivers/net/ethernet/cisco/enic/enic_main.c -+++ b/drivers/net/ethernet/cisco/enic/enic_main.c -@@ -680,8 +680,8 @@ static netdev_tx_t enic_hard_start_xmit( - } - - /* dev_base_lock rwlock held, nominally process context */ --static struct rtnl_link_stats64 *enic_get_stats(struct net_device *netdev, -- struct rtnl_link_stats64 *net_stats) -+static void enic_get_stats(struct net_device *netdev, -+ struct rtnl_link_stats64 *net_stats) - { - struct enic *enic = netdev_priv(netdev); - struct vnic_stats *stats; -@@ -693,7 +693,7 @@ static struct rtnl_link_stats64 *enic_ge - * recorded stats. - */ - if (err == -ENOMEM) -- return net_stats; -+ return; - - net_stats->tx_packets = stats->tx.tx_frames_ok; - net_stats->tx_bytes = stats->tx.tx_bytes_ok; -@@ -707,8 +707,6 @@ static struct rtnl_link_stats64 *enic_ge - net_stats->rx_over_errors = enic->rq_truncated_pkts; - net_stats->rx_crc_errors = enic->rq_bad_fcs; - net_stats->rx_dropped = stats->rx.rx_no_bufs + stats->rx.rx_drop; -- -- return net_stats; - } - - static int enic_mc_sync(struct net_device *netdev, const u8 *mc_addr) ---- a/drivers/net/ethernet/ec_bhf.c -+++ b/drivers/net/ethernet/ec_bhf.c -@@ -458,7 +458,7 @@ static int ec_bhf_stop(struct net_device - return 0; - } - --static struct rtnl_link_stats64 * -+static void - ec_bhf_get_stats(struct net_device *net_dev, - struct rtnl_link_stats64 *stats) - { -@@ -473,8 +473,6 @@ ec_bhf_get_stats(struct net_device *net_ - - stats->tx_bytes = priv->stat_tx_bytes; - stats->rx_bytes = priv->stat_rx_bytes; -- -- return stats; - } - - static const struct net_device_ops ec_bhf_netdev_ops = { ---- a/drivers/net/ethernet/emulex/benet/be_main.c -+++ b/drivers/net/ethernet/emulex/benet/be_main.c -@@ -646,8 +646,8 @@ void be_parse_stats(struct be_adapter *a - } - } - --static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+static void be_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct be_adapter *adapter = netdev_priv(netdev); - struct be_drv_stats *drvs = &adapter->drv_stats; -@@ -711,7 +711,6 @@ static struct rtnl_link_stats64 *be_get_ - stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop + - drvs->rx_input_fifo_overflow_drop + - drvs->rx_drops_no_pbuf; -- return stats; - } - - void be_link_status_update(struct be_adapter *adapter, u8 link_status) ---- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c -+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c -@@ -1536,8 +1536,8 @@ void hns_nic_set_rx_mode(struct net_devi - hns_set_multicast_list(ndev); - } - --struct rtnl_link_stats64 *hns_nic_get_stats64(struct net_device *ndev, -- struct rtnl_link_stats64 *stats) -+static void hns_nic_get_stats64(struct net_device *ndev, -+ struct rtnl_link_stats64 *stats) - { - int idx = 0; - u64 tx_bytes = 0; -@@ -1579,8 +1579,6 @@ struct rtnl_link_stats64 *hns_nic_get_st - stats->tx_window_errors = ndev->stats.tx_window_errors; - stats->rx_compressed = ndev->stats.rx_compressed; - stats->tx_compressed = ndev->stats.tx_compressed; -- -- return stats; - } - - static u16 ---- a/drivers/net/ethernet/ibm/ehea/ehea_main.c -+++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c -@@ -328,8 +328,8 @@ out: - spin_unlock_irqrestore(&ehea_bcmc_regs.lock, flags); - } - --static struct rtnl_link_stats64 *ehea_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void ehea_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct ehea_port *port = netdev_priv(dev); - u64 rx_packets = 0, tx_packets = 0, rx_bytes = 0, tx_bytes = 0; -@@ -352,7 +352,6 @@ static struct rtnl_link_stats64 *ehea_ge - - stats->multicast = port->stats.multicast; - stats->rx_errors = port->stats.rx_errors; -- return stats; - } - - static void ehea_update_stats(struct work_struct *work) ---- a/drivers/net/ethernet/intel/e1000e/e1000.h -+++ b/drivers/net/ethernet/intel/e1000e/e1000.h -@@ -493,8 +493,8 @@ int e1000e_setup_rx_resources(struct e10 - int e1000e_setup_tx_resources(struct e1000_ring *ring); - void e1000e_free_rx_resources(struct e1000_ring *ring); - void e1000e_free_tx_resources(struct e1000_ring *ring); --struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats); -+void e1000e_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats); - void e1000e_set_interrupt_capability(struct e1000_adapter *adapter); - void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); - void e1000e_get_hw_control(struct e1000_adapter *adapter); ---- a/drivers/net/ethernet/intel/e1000e/netdev.c -+++ b/drivers/net/ethernet/intel/e1000e/netdev.c -@@ -5939,8 +5939,8 @@ static void e1000_reset_task(struct work - * - * Returns the address of the device statistics structure. - **/ --struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+void e1000e_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct e1000_adapter *adapter = netdev_priv(netdev); - -@@ -5977,7 +5977,6 @@ struct rtnl_link_stats64 *e1000e_get_sta - /* Tx Dropped needs to be maintained elsewhere */ - - spin_unlock(&adapter->stats64_lock); -- return stats; - } - - /** ---- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c -+++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c -@@ -1128,8 +1128,8 @@ void fm10k_reset_rx_state(struct fm10k_i - * Returns 64bit statistics, for use in the ndo_get_stats64 callback. This - * function replaces fm10k_get_stats for kernels which support it. - */ --static struct rtnl_link_stats64 *fm10k_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+static void fm10k_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct fm10k_intfc *interface = netdev_priv(netdev); - struct fm10k_ring *ring; -@@ -1174,8 +1174,6 @@ static struct rtnl_link_stats64 *fm10k_g - - /* following stats updated by fm10k_service_task() */ - stats->rx_missed_errors = netdev->stats.rx_missed_errors; -- -- return stats; - } - - int fm10k_setup_tc(struct net_device *dev, u8 tc) ---- a/drivers/net/ethernet/intel/i40e/i40e.h -+++ b/drivers/net/ethernet/intel/i40e/i40e.h -@@ -797,9 +797,8 @@ static inline void i40e_irq_dynamic_enab - void i40e_irq_dynamic_disable_icr0(struct i40e_pf *pf); - void i40e_irq_dynamic_enable_icr0(struct i40e_pf *pf, bool clearpba); - #ifdef I40E_FCOE --struct rtnl_link_stats64 *i40e_get_netdev_stats_struct( -- struct net_device *netdev, -- struct rtnl_link_stats64 *storage); -+void i40e_get_netdev_stats_struct(struct net_device *netdev, -+ struct rtnl_link_stats64 *storage); - int i40e_set_mac(struct net_device *netdev, void *p); - void i40e_set_rx_mode(struct net_device *netdev); - #endif ---- a/drivers/net/ethernet/intel/i40e/i40e_main.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c -@@ -408,15 +408,11 @@ struct rtnl_link_stats64 *i40e_get_vsi_s - * Returns the address of the device statistics structure. - * The statistics are actually updated from the service task. - **/ --#ifdef I40E_FCOE --struct rtnl_link_stats64 *i40e_get_netdev_stats_struct( -- struct net_device *netdev, -- struct rtnl_link_stats64 *stats) --#else --static struct rtnl_link_stats64 *i40e_get_netdev_stats_struct( -- struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+#ifndef I40E_FCOE -+static - #endif -+void i40e_get_netdev_stats_struct(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct i40e_netdev_priv *np = netdev_priv(netdev); - struct i40e_ring *tx_ring, *rx_ring; -@@ -425,10 +421,10 @@ static struct rtnl_link_stats64 *i40e_ge - int i; - - if (test_bit(__I40E_DOWN, &vsi->state)) -- return stats; -+ return; - - if (!vsi->tx_rings) -- return stats; -+ return; - - rcu_read_lock(); - for (i = 0; i < vsi->num_queue_pairs; i++) { -@@ -468,8 +464,6 @@ static struct rtnl_link_stats64 *i40e_ge - stats->rx_dropped = vsi_stats->rx_dropped; - stats->rx_crc_errors = vsi_stats->rx_crc_errors; - stats->rx_length_errors = vsi_stats->rx_length_errors; -- -- return stats; - } - - /** ---- a/drivers/net/ethernet/intel/igb/igb_main.c -+++ b/drivers/net/ethernet/intel/igb/igb_main.c -@@ -137,8 +137,8 @@ static void igb_update_phy_info(unsigned - static void igb_watchdog(unsigned long); - static void igb_watchdog_task(struct work_struct *); - static netdev_tx_t igb_xmit_frame(struct sk_buff *skb, struct net_device *); --static struct rtnl_link_stats64 *igb_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats); -+static void igb_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats); - static int igb_change_mtu(struct net_device *, int); - static int igb_set_mac(struct net_device *, void *); - static void igb_set_uta(struct igb_adapter *adapter, bool set); -@@ -5386,8 +5386,8 @@ static void igb_reset_task(struct work_s - * @netdev: network interface device structure - * @stats: rtnl_link_stats64 pointer - **/ --static struct rtnl_link_stats64 *igb_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+static void igb_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct igb_adapter *adapter = netdev_priv(netdev); - -@@ -5395,8 +5395,6 @@ static struct rtnl_link_stats64 *igb_get - igb_update_stats(adapter, &adapter->stats64); - memcpy(stats, &adapter->stats64, sizeof(*stats)); - spin_unlock(&adapter->stats64_lock); -- -- return stats; - } - - /** ---- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c -+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c -@@ -8085,8 +8085,9 @@ static void ixgbe_netpoll(struct net_dev - } - - #endif --static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+ -+static void ixgbe_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct ixgbe_adapter *adapter = netdev_priv(netdev); - int i; -@@ -8124,13 +8125,13 @@ static struct rtnl_link_stats64 *ixgbe_g - } - } - rcu_read_unlock(); -+ - /* following stats updated by ixgbe_watchdog_task() */ - stats->multicast = netdev->stats.multicast; - stats->rx_errors = netdev->stats.rx_errors; - stats->rx_length_errors = netdev->stats.rx_length_errors; - stats->rx_crc_errors = netdev->stats.rx_crc_errors; - stats->rx_missed_errors = netdev->stats.rx_missed_errors; -- return stats; - } - - #ifdef CONFIG_IXGBE_DCB ---- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c -+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c -@@ -3880,8 +3880,8 @@ static void ixgbevf_shutdown(struct pci_ - ixgbevf_suspend(pdev, PMSG_SUSPEND); - } - --static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+static void ixgbevf_get_stats(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct ixgbevf_adapter *adapter = netdev_priv(netdev); - unsigned int start; -@@ -3914,8 +3914,6 @@ static struct rtnl_link_stats64 *ixgbevf - stats->tx_bytes += bytes; - stats->tx_packets += packets; - } -- -- return stats; - } - - #define IXGBEVF_MAX_MAC_HDR_LEN 127 ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -636,7 +636,7 @@ static void mvneta_mib_counters_clear(st - } - - /* Get System Network Statistics */ --static struct rtnl_link_stats64 * -+static void - mvneta_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *stats) - { -@@ -670,8 +670,6 @@ mvneta_get_stats64(struct net_device *de - stats->rx_dropped = dev->stats.rx_dropped; - - stats->tx_dropped = dev->stats.tx_dropped; -- -- return stats; - } - - /* Rx descriptors helper methods */ ---- a/drivers/net/ethernet/marvell/mvpp2.c -+++ b/drivers/net/ethernet/marvell/mvpp2.c -@@ -5761,7 +5761,7 @@ error: - return err; - } - --static struct rtnl_link_stats64 * -+static void - mvpp2_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - struct mvpp2_port *port = netdev_priv(dev); -@@ -5793,8 +5793,6 @@ mvpp2_get_stats64(struct net_device *dev - stats->rx_errors = dev->stats.rx_errors; - stats->rx_dropped = dev->stats.rx_dropped; - stats->tx_dropped = dev->stats.tx_dropped; -- -- return stats; - } - - static int mvpp2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ---- a/drivers/net/ethernet/marvell/sky2.c -+++ b/drivers/net/ethernet/marvell/sky2.c -@@ -3898,8 +3898,8 @@ static void sky2_set_multicast(struct ne - gma_write16(hw, port, GM_RX_CTRL, reg); - } - --static struct rtnl_link_stats64 *sky2_get_stats(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void sky2_get_stats(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct sky2_port *sky2 = netdev_priv(dev); - struct sky2_hw *hw = sky2->hw; -@@ -3939,8 +3939,6 @@ static struct rtnl_link_stats64 *sky2_ge - stats->rx_dropped = dev->stats.rx_dropped; - stats->rx_fifo_errors = dev->stats.rx_fifo_errors; - stats->tx_fifo_errors = dev->stats.tx_fifo_errors; -- -- return stats; - } - - /* Can have one global because blinking is controlled by ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -462,8 +462,8 @@ static void mtk_stats_update(struct mtk_ - } - } - --static struct rtnl_link_stats64 *mtk_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *storage) -+static void mtk_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *storage) - { - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_hw_stats *hw_stats = mac->hw_stats; -@@ -494,8 +494,6 @@ static struct rtnl_link_stats64 *mtk_get - storage->tx_errors = dev->stats.tx_errors; - storage->rx_dropped = dev->stats.rx_dropped; - storage->tx_dropped = dev->stats.tx_dropped; -- -- return storage; - } - - static inline int mtk_max_frag_size(int mtu) ---- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c -+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c -@@ -1316,7 +1316,7 @@ static void mlx4_en_tx_timeout(struct ne - } - - --static struct rtnl_link_stats64 * -+static void - mlx4_en_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - struct mlx4_en_priv *priv = netdev_priv(dev); -@@ -1324,8 +1324,6 @@ mlx4_en_get_stats64(struct net_device *d - spin_lock_bh(&priv->stats_lock); - netdev_stats_to_stats64(stats, &dev->stats); - spin_unlock_bh(&priv->stats_lock); -- -- return stats; - } - - static void mlx4_en_set_default_moderation(struct mlx4_en_priv *priv) ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c -@@ -2647,7 +2647,7 @@ mqprio: - return mlx5e_setup_tc(dev, tc->tc); - } - --struct rtnl_link_stats64 * -+static void - mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - struct mlx5e_priv *priv = netdev_priv(dev); -@@ -2681,7 +2681,6 @@ mlx5e_get_stats(struct net_device *dev, - stats->multicast = - VPORT_COUNTER_GET(vstats, received_eth_multicast.packets); - -- return stats; - } - - static void mlx5e_set_rx_mode(struct net_device *dev) ---- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c -+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c -@@ -949,15 +949,13 @@ out: - /* Return the stats from a cache that is updated periodically, - * as this function might get called in an atomic context. - */ --static struct rtnl_link_stats64 * -+static void - mlxsw_sp_port_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *stats) - { - struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); - - memcpy(stats, mlxsw_sp_port->hw_stats.cache, sizeof(*stats)); -- -- return stats; - } - - int mlxsw_sp_port_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid_begin, ---- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c -+++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c -@@ -351,7 +351,7 @@ static int mlxsw_sx_port_change_mtu(stru - return 0; - } - --static struct rtnl_link_stats64 * -+static void - mlxsw_sx_port_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *stats) - { -@@ -380,7 +380,6 @@ mlxsw_sx_port_get_stats64(struct net_dev - tx_dropped += p->tx_dropped; - } - stats->tx_dropped = tx_dropped; -- return stats; - } - - static const struct net_device_ops mlxsw_sx_port_netdev_ops = { ---- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c -+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c -@@ -378,8 +378,8 @@ static inline void put_be32(__be32 val, - __raw_writel((__force __u32) val, (__force void __iomem *)p); - } - --static struct rtnl_link_stats64 *myri10ge_get_stats(struct net_device *dev, -- struct rtnl_link_stats64 *stats); -+static void myri10ge_get_stats(struct net_device *dev, -+ struct rtnl_link_stats64 *stats); - - static void set_fw_name(struct myri10ge_priv *mgp, char *name, bool allocated) - { -@@ -3119,8 +3119,8 @@ drop: - return NETDEV_TX_OK; - } - --static struct rtnl_link_stats64 *myri10ge_get_stats(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void myri10ge_get_stats(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - const struct myri10ge_priv *mgp = netdev_priv(dev); - const struct myri10ge_slice_netstats *slice_stats; -@@ -3135,7 +3135,6 @@ static struct rtnl_link_stats64 *myri10g - stats->rx_dropped += slice_stats->rx_dropped; - stats->tx_dropped += slice_stats->tx_dropped; - } -- return stats; - } - - static void myri10ge_set_multicast_list(struct net_device *dev) ---- a/drivers/net/ethernet/neterion/vxge/vxge-main.c -+++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c -@@ -3116,7 +3116,7 @@ static int vxge_change_mtu(struct net_de - * @stats: pointer to struct rtnl_link_stats64 - * - */ --static struct rtnl_link_stats64 * -+static void - vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats) - { - struct vxgedev *vdev = netdev_priv(dev); -@@ -3155,8 +3155,6 @@ vxge_get_stats64(struct net_device *dev, - net_stats->tx_bytes += bytes; - net_stats->tx_errors += txstats->tx_errors; - } -- -- return net_stats; - } - - static enum vxge_hw_status vxge_timestamp_config(struct __vxge_hw_device *devh) ---- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c -+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c -@@ -2400,8 +2400,8 @@ int nfp_net_set_ring_size(struct nfp_net - return err; - } - --static struct rtnl_link_stats64 *nfp_net_stat64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+static void nfp_net_stat64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct nfp_net *nn = netdev_priv(netdev); - int r; -@@ -2431,8 +2431,6 @@ static struct rtnl_link_stats64 *nfp_net - stats->tx_bytes += data[1]; - stats->tx_errors += data[2]; - } -- -- return stats; - } - - static bool nfp_net_ebpf_capable(struct nfp_net *nn) ---- a/drivers/net/ethernet/nvidia/forcedeth.c -+++ b/drivers/net/ethernet/nvidia/forcedeth.c -@@ -1733,7 +1733,7 @@ static void nv_update_stats(struct net_d - * Called with read_lock(&dev_base_lock) held for read - - * only synchronized against unregister_netdevice. - */ --static struct rtnl_link_stats64* -+static void - nv_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *storage) - __acquires(&netdev_priv(dev)->hwstats_lock) - __releases(&netdev_priv(dev)->hwstats_lock) -@@ -1793,8 +1793,6 @@ nv_get_stats64(struct net_device *dev, s - - spin_unlock_bh(&np->hwstats_lock); - } -- -- return storage; - } - - /* ---- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c -+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c -@@ -90,8 +90,8 @@ static irqreturn_t netxen_msix_intr(int - - static void netxen_free_ip_list(struct netxen_adapter *, bool); - static void netxen_restore_indev_addr(struct net_device *dev, unsigned long); --static struct rtnl_link_stats64 *netxen_nic_get_stats(struct net_device *dev, -- struct rtnl_link_stats64 *stats); -+static void netxen_nic_get_stats(struct net_device *dev, -+ struct rtnl_link_stats64 *stats); - static int netxen_nic_set_mac(struct net_device *netdev, void *p); - - /* PCI Device ID Table */ -@@ -2295,8 +2295,8 @@ request_reset: - clear_bit(__NX_RESETTING, &adapter->state); - } - --static struct rtnl_link_stats64 *netxen_nic_get_stats(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+static void netxen_nic_get_stats(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct netxen_adapter *adapter = netdev_priv(netdev); - -@@ -2306,8 +2306,6 @@ static struct rtnl_link_stats64 *netxen_ - stats->tx_bytes = adapter->stats.txbytes; - stats->rx_dropped = adapter->stats.rxdropped; - stats->tx_dropped = adapter->stats.txdropped; -- -- return stats; - } - - static irqreturn_t netxen_intr(int irq, void *data) ---- a/drivers/net/ethernet/qlogic/qede/qede_main.c -+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c -@@ -1803,9 +1803,8 @@ void qede_fill_by_demand_stats(struct qe - edev->stats.tx_mac_ctrl_frames = stats.tx_mac_ctrl_frames; - } - --static --struct rtnl_link_stats64 *qede_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void qede_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct qede_dev *edev = netdev_priv(dev); - -@@ -1835,8 +1834,6 @@ struct rtnl_link_stats64 *qede_get_stats - stats->collisions = edev->stats.tx_total_collisions; - stats->rx_crc_errors = edev->stats.rx_crc_errors; - stats->rx_frame_errors = edev->stats.rx_align_errors; -- -- return stats; - } - - #ifdef CONFIG_QED_SRIOV ---- a/drivers/net/ethernet/qualcomm/emac/emac.c -+++ b/drivers/net/ethernet/qualcomm/emac/emac.c -@@ -319,8 +319,8 @@ static int emac_ioctl(struct net_device - } - - /* Provide network statistics info for the interface */ --static struct rtnl_link_stats64 *emac_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *net_stats) -+static void emac_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *net_stats) - { - struct emac_adapter *adpt = netdev_priv(netdev); - unsigned int addr = REG_MAC_RX_STATUS_BIN; -@@ -384,8 +384,6 @@ static struct rtnl_link_stats64 *emac_ge - net_stats->tx_window_errors = stats->tx_late_col; - - spin_unlock(&stats->lock); -- -- return net_stats; - } - - static const struct net_device_ops emac_netdev_ops = { ---- a/drivers/net/ethernet/realtek/8139too.c -+++ b/drivers/net/ethernet/realtek/8139too.c -@@ -653,9 +653,8 @@ static int rtl8139_poll(struct napi_stru - static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance); - static int rtl8139_close (struct net_device *dev); - static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); --static struct rtnl_link_stats64 *rtl8139_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 -- *stats); -+static void rtl8139_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats); - static void rtl8139_set_rx_mode (struct net_device *dev); - static void __set_rx_mode (struct net_device *dev); - static void rtl8139_hw_start (struct net_device *dev); -@@ -2521,7 +2520,7 @@ static int netdev_ioctl(struct net_devic - } - - --static struct rtnl_link_stats64 * -+static void - rtl8139_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - struct rtl8139_private *tp = netdev_priv(dev); -@@ -2549,8 +2548,6 @@ rtl8139_get_stats64(struct net_device *d - stats->tx_packets = tp->tx_stats.packets; - stats->tx_bytes = tp->tx_stats.bytes; - } while (u64_stats_fetch_retry_irq(&tp->tx_stats.syncp, start)); -- -- return stats; - } - - /* Set or clear the multicast filter for this adaptor. ---- a/drivers/net/ethernet/realtek/r8169.c -+++ b/drivers/net/ethernet/realtek/r8169.c -@@ -7751,7 +7751,7 @@ err_pm_runtime_put: - goto out; - } - --static struct rtnl_link_stats64 * -+static void - rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - struct rtl8169_private *tp = netdev_priv(dev); -@@ -7805,8 +7805,6 @@ rtl8169_get_stats64(struct net_device *d - le16_to_cpu(tp->tc_offset.tx_aborted); - - pm_runtime_put_noidle(&pdev->dev); -- -- return stats; - } - - static void rtl8169_net_suspend(struct net_device *dev) ---- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c -+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c -@@ -1721,11 +1721,9 @@ static inline u64 sxgbe_get_stat64(void - * This function is a driver entry point whenever ifconfig command gets - * executed to see device statistics. Statistics are number of - * bytes sent or received, errors occurred etc. -- * Return value: -- * This function returns various statistical information of device. - */ --static struct rtnl_link_stats64 *sxgbe_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void sxgbe_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct sxgbe_priv_data *priv = netdev_priv(dev); - void __iomem *ioaddr = priv->ioaddr; -@@ -1776,8 +1774,6 @@ static struct rtnl_link_stats64 *sxgbe_g - SXGBE_MMC_TXUFLWHI_GBCNT_REG); - writel(0, ioaddr + SXGBE_MMC_CTL_REG); - spin_unlock(&priv->stats_lock); -- -- return stats; - } - - /* sxgbe_set_features - entry point to set offload features of the device. ---- a/drivers/net/ethernet/sfc/efx.c -+++ b/drivers/net/ethernet/sfc/efx.c -@@ -2232,16 +2232,14 @@ int efx_net_stop(struct net_device *net_ - } - - /* Context: process, dev_base_lock or RTNL held, non-blocking. */ --static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, -- struct rtnl_link_stats64 *stats) -+static void efx_net_stats(struct net_device *net_dev, -+ struct rtnl_link_stats64 *stats) - { - struct efx_nic *efx = netdev_priv(net_dev); - - spin_lock_bh(&efx->stats_lock); - efx->type->update_stats(efx, NULL, stats); - spin_unlock_bh(&efx->stats_lock); -- -- return stats; - } - - /* Context: netif_tx_lock held, BHs disabled. */ ---- a/drivers/net/ethernet/sun/niu.c -+++ b/drivers/net/ethernet/sun/niu.c -@@ -6294,8 +6294,8 @@ no_rings: - stats->tx_errors = errors; - } - --static struct rtnl_link_stats64 *niu_get_stats(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void niu_get_stats(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct niu *np = netdev_priv(dev); - -@@ -6303,8 +6303,6 @@ static struct rtnl_link_stats64 *niu_get - niu_get_rx_stats(np, stats); - niu_get_tx_stats(np, stats); - } -- -- return stats; - } - - static void niu_load_hash_xmac(struct niu *np, u16 *hash) ---- a/drivers/net/ethernet/synopsys/dwc_eth_qos.c -+++ b/drivers/net/ethernet/synopsys/dwc_eth_qos.c -@@ -2490,7 +2490,7 @@ static void dwceqos_read_mmc_counters(st - dwceqos_read(lp, DWC_MMC_RXPACKETCOUNT_GB); - } - --static struct rtnl_link_stats64* -+static void - dwceqos_get_stats64(struct net_device *ndev, struct rtnl_link_stats64 *s) - { - unsigned long flags; -@@ -2522,8 +2522,6 @@ dwceqos_get_stats64(struct net_device *n - else - s->tx_errors = hwstats->txunderflowerror + - hwstats->txcarriererror; -- -- return s; - } - - static void ---- a/drivers/net/ethernet/tile/tilepro.c -+++ b/drivers/net/ethernet/tile/tilepro.c -@@ -2047,8 +2047,8 @@ static int tile_net_ioctl(struct net_dev - * - * Returns the address of the device statistics structure. - */ --static struct rtnl_link_stats64 *tile_net_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void tile_net_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct tile_net_priv *priv = netdev_priv(dev); - u64 rx_packets = 0, tx_packets = 0; ---- a/drivers/net/ethernet/via/via-rhine.c -+++ b/drivers/net/ethernet/via/via-rhine.c -@@ -513,8 +513,8 @@ static irqreturn_t rhine_interrupt(int i - static void rhine_tx(struct net_device *dev); - static int rhine_rx(struct net_device *dev, int limit); - static void rhine_set_rx_mode(struct net_device *dev); --static struct rtnl_link_stats64 *rhine_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats); -+static void rhine_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats); - static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); - static const struct ethtool_ops netdev_ethtool_ops; - static int rhine_close(struct net_device *dev); -@@ -2222,7 +2222,7 @@ out_unlock: - mutex_unlock(&rp->task_lock); - } - --static struct rtnl_link_stats64 * -+static void - rhine_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - struct rhine_private *rp = netdev_priv(dev); -@@ -2245,8 +2245,6 @@ rhine_get_stats64(struct net_device *dev - stats->tx_packets = rp->tx_stats.packets; - stats->tx_bytes = rp->tx_stats.bytes; - } while (u64_stats_fetch_retry_irq(&rp->tx_stats.syncp, start)); -- -- return stats; - } - - static void rhine_set_rx_mode(struct net_device *dev) ---- a/drivers/net/fjes/fjes_main.c -+++ b/drivers/net/fjes/fjes_main.c -@@ -56,8 +56,7 @@ static void fjes_raise_intr_rxdata_task( - static void fjes_tx_stall_task(struct work_struct *); - static void fjes_force_close_task(struct work_struct *); - static irqreturn_t fjes_intr(int, void*); --static struct rtnl_link_stats64 * --fjes_get_stats64(struct net_device *, struct rtnl_link_stats64 *); -+static void fjes_get_stats64(struct net_device *, struct rtnl_link_stats64 *); - static int fjes_change_mtu(struct net_device *, int); - static int fjes_vlan_rx_add_vid(struct net_device *, __be16 proto, u16); - static int fjes_vlan_rx_kill_vid(struct net_device *, __be16 proto, u16); -@@ -762,14 +761,12 @@ static void fjes_tx_retry(struct net_dev - netif_tx_wake_queue(queue); - } - --static struct rtnl_link_stats64 * -+static void - fjes_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) - { - struct fjes_adapter *adapter = netdev_priv(netdev); - - memcpy(stats, &adapter->stats64, sizeof(struct rtnl_link_stats64)); -- -- return stats; - } - - static int fjes_change_mtu(struct net_device *netdev, int new_mtu) ---- a/drivers/net/hyperv/netvsc_drv.c -+++ b/drivers/net/hyperv/netvsc_drv.c -@@ -918,8 +918,8 @@ out: - return ret; - } - --static struct rtnl_link_stats64 *netvsc_get_stats64(struct net_device *net, -- struct rtnl_link_stats64 *t) -+static void netvsc_get_stats64(struct net_device *net, -+ struct rtnl_link_stats64 *t) - { - struct net_device_context *ndev_ctx = netdev_priv(net); - int cpu; -@@ -957,8 +957,6 @@ static struct rtnl_link_stats64 *netvsc_ - - t->rx_dropped = net->stats.rx_dropped; - t->rx_errors = net->stats.rx_errors; -- -- return t; - } - - static int netvsc_set_mac_addr(struct net_device *ndev, void *p) ---- a/drivers/net/ifb.c -+++ b/drivers/net/ifb.c -@@ -129,8 +129,8 @@ resched: - - } - --static struct rtnl_link_stats64 *ifb_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void ifb_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct ifb_dev_private *dp = netdev_priv(dev); - struct ifb_q_private *txp = dp->tx_private; -@@ -157,8 +157,6 @@ static struct rtnl_link_stats64 *ifb_sta - } - stats->rx_dropped = dev->stats.rx_dropped; - stats->tx_dropped = dev->stats.tx_dropped; -- -- return stats; - } - - static int ifb_dev_init(struct net_device *dev) ---- a/drivers/net/ipvlan/ipvlan_main.c -+++ b/drivers/net/ipvlan/ipvlan_main.c -@@ -296,8 +296,8 @@ static void ipvlan_set_multicast_mac_fil - dev_mc_sync(ipvlan->phy_dev, dev); - } - --static struct rtnl_link_stats64 *ipvlan_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *s) -+static void ipvlan_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *s) - { - struct ipvl_dev *ipvlan = netdev_priv(dev); - -@@ -334,7 +334,6 @@ static struct rtnl_link_stats64 *ipvlan_ - s->rx_dropped = rx_errs; - s->tx_dropped = tx_drps; - } -- return s; - } - - static int ipvlan_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) ---- a/drivers/net/loopback.c -+++ b/drivers/net/loopback.c -@@ -97,8 +97,8 @@ static netdev_tx_t loopback_xmit(struct - return NETDEV_TX_OK; - } - --static struct rtnl_link_stats64 *loopback_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void loopback_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - u64 bytes = 0; - u64 packets = 0; -@@ -122,7 +122,6 @@ static struct rtnl_link_stats64 *loopbac - stats->tx_packets = packets; - stats->rx_bytes = bytes; - stats->tx_bytes = bytes; -- return stats; - } - - static u32 always_on(struct net_device *dev) ---- a/drivers/net/macsec.c -+++ b/drivers/net/macsec.c -@@ -2899,13 +2899,13 @@ static int macsec_change_mtu(struct net_ - return 0; - } - --static struct rtnl_link_stats64 *macsec_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *s) -+static void macsec_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *s) - { - int cpu; - - if (!dev->tstats) -- return s; -+ return; - - for_each_possible_cpu(cpu) { - struct pcpu_sw_netstats *stats; -@@ -2929,8 +2929,6 @@ static struct rtnl_link_stats64 *macsec_ - - s->rx_dropped = dev->stats.rx_dropped; - s->tx_dropped = dev->stats.tx_dropped; -- -- return s; - } - - static int macsec_get_iflink(const struct net_device *dev) ---- a/drivers/net/macvlan.c -+++ b/drivers/net/macvlan.c -@@ -857,8 +857,8 @@ static void macvlan_uninit(struct net_de - macvlan_port_destroy(port->dev); - } - --static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void macvlan_dev_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct macvlan_dev *vlan = netdev_priv(dev); - -@@ -895,7 +895,6 @@ static struct rtnl_link_stats64 *macvlan - stats->rx_dropped = rx_errors; - stats->tx_dropped = tx_dropped; - } -- return stats; - } - - static int macvlan_vlan_rx_add_vid(struct net_device *dev, ---- a/drivers/net/nlmon.c -+++ b/drivers/net/nlmon.c -@@ -76,7 +76,7 @@ static int nlmon_close(struct net_device - return netlink_remove_tap(&nlmon->nt); - } - --static struct rtnl_link_stats64 * -+static void - nlmon_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - int i; -@@ -104,8 +104,6 @@ nlmon_get_stats64(struct net_device *dev - - stats->rx_bytes = bytes; - stats->tx_bytes = 0; -- -- return stats; - } - - static u32 always_on(struct net_device *dev) ---- a/drivers/net/ppp/ppp_generic.c -+++ b/drivers/net/ppp/ppp_generic.c -@@ -1312,7 +1312,7 @@ ppp_net_ioctl(struct net_device *dev, st - return err; - } - --static struct rtnl_link_stats64* -+static void - ppp_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats64) - { - struct ppp *ppp = netdev_priv(dev); -@@ -1332,8 +1332,6 @@ ppp_get_stats64(struct net_device *dev, - stats64->rx_dropped = dev->stats.rx_dropped; - stats64->tx_dropped = dev->stats.tx_dropped; - stats64->rx_length_errors = dev->stats.rx_length_errors; -- -- return stats64; - } - - static int ppp_dev_init(struct net_device *dev) ---- a/drivers/net/slip/slip.c -+++ b/drivers/net/slip/slip.c -@@ -571,7 +571,7 @@ static int sl_change_mtu(struct net_devi - - /* Netdevice get statistics request */ - --static struct rtnl_link_stats64 * -+static void - sl_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - struct net_device_stats *devstats = &dev->stats; -@@ -602,7 +602,6 @@ sl_get_stats64(struct net_device *dev, s - stats->collisions += comp->sls_o_misses; - } - #endif -- return stats; - } - - /* Netdevice register callback */ ---- a/drivers/net/team/team.c -+++ b/drivers/net/team/team.c -@@ -1798,7 +1798,7 @@ unwind: - return err; - } - --static struct rtnl_link_stats64 * -+static void - team_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - struct team *team = netdev_priv(dev); -@@ -1835,7 +1835,6 @@ team_get_stats64(struct net_device *dev, - stats->rx_dropped = rx_dropped; - stats->tx_dropped = tx_dropped; - stats->rx_nohandler = rx_nohandler; -- return stats; - } - - static int team_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) ---- a/drivers/net/tun.c -+++ b/drivers/net/tun.c -@@ -983,7 +983,7 @@ static void tun_set_headroom(struct net_ - tun->align = new_hr; - } - --static struct rtnl_link_stats64 * -+static void - tun_net_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - u32 rx_dropped = 0, tx_dropped = 0, rx_frame_errors = 0; -@@ -1017,7 +1017,6 @@ tun_net_get_stats64(struct net_device *d - stats->rx_dropped = rx_dropped; - stats->rx_frame_errors = rx_frame_errors; - stats->tx_dropped = tx_dropped; -- return stats; - } - - static const struct net_device_ops tun_netdev_ops = { ---- a/drivers/net/veth.c -+++ b/drivers/net/veth.c -@@ -161,8 +161,8 @@ static u64 veth_stats_one(struct pcpu_vs - return atomic64_read(&priv->dropped); - } - --static struct rtnl_link_stats64 *veth_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *tot) -+static void veth_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *tot) - { - struct veth_priv *priv = netdev_priv(dev); - struct net_device *peer; -@@ -180,8 +180,6 @@ static struct rtnl_link_stats64 *veth_ge - tot->rx_packets = one.packets; - } - rcu_read_unlock(); -- -- return tot; - } - - /* fake multicast ability */ ---- a/drivers/net/virtio_net.c -+++ b/drivers/net/virtio_net.c -@@ -1017,8 +1017,8 @@ out: - return ret; - } - --static struct rtnl_link_stats64 *virtnet_stats(struct net_device *dev, -- struct rtnl_link_stats64 *tot) -+static void virtnet_stats(struct net_device *dev, -+ struct rtnl_link_stats64 *tot) - { - struct virtnet_info *vi = netdev_priv(dev); - int cpu; -@@ -1051,8 +1051,6 @@ static struct rtnl_link_stats64 *virtnet - tot->rx_dropped = dev->stats.rx_dropped; - tot->rx_length_errors = dev->stats.rx_length_errors; - tot->rx_frame_errors = dev->stats.rx_frame_errors; -- -- return tot; - } - - #ifdef CONFIG_NET_POLL_CONTROLLER ---- a/drivers/net/vmxnet3/vmxnet3_ethtool.c -+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c -@@ -113,7 +113,7 @@ vmxnet3_global_stats[] = { - }; - - --struct rtnl_link_stats64 * -+void - vmxnet3_get_stats64(struct net_device *netdev, - struct rtnl_link_stats64 *stats) - { -@@ -160,8 +160,6 @@ vmxnet3_get_stats64(struct net_device *n - stats->rx_dropped += drvRxStats->drop_total; - stats->multicast += devRxStats->mcastPktsRxOK; - } -- -- return stats; - } - - static int ---- a/drivers/net/vmxnet3/vmxnet3_int.h -+++ b/drivers/net/vmxnet3/vmxnet3_int.h -@@ -466,8 +466,8 @@ vmxnet3_create_queues(struct vmxnet3_ada - - void vmxnet3_set_ethtool_ops(struct net_device *netdev); - --struct rtnl_link_stats64 * --vmxnet3_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats); -+void vmxnet3_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats); - - extern char vmxnet3_driver_name[]; - #endif ---- a/drivers/net/vrf.c -+++ b/drivers/net/vrf.c -@@ -79,8 +79,8 @@ static void vrf_tx_error(struct net_devi - kfree_skb(skb); - } - --static struct rtnl_link_stats64 *vrf_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void vrf_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - int i; - -@@ -104,7 +104,6 @@ static struct rtnl_link_stats64 *vrf_get - stats->rx_bytes += rbytes; - stats->rx_packets += rpkts; - } -- return stats; - } - - /* Local traffic destined to local address. Reinsert the packet to rx ---- a/drivers/net/xen-netfront.c -+++ b/drivers/net/xen-netfront.c -@@ -1081,8 +1081,8 @@ static int xennet_change_mtu(struct net_ - return 0; - } - --static struct rtnl_link_stats64 *xennet_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *tot) -+static void xennet_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *tot) - { - struct netfront_info *np = netdev_priv(dev); - int cpu; -@@ -1113,8 +1113,6 @@ static struct rtnl_link_stats64 *xennet_ - - tot->rx_errors = dev->stats.rx_errors; - tot->tx_dropped = dev->stats.tx_dropped; -- -- return tot; - } - - static void xennet_release_tx_bufs(struct netfront_queue *queue) ---- a/drivers/staging/netlogic/xlr_net.c -+++ b/drivers/staging/netlogic/xlr_net.c -@@ -395,14 +395,6 @@ static void xlr_stats(struct net_device - TX_DROP_FRAME_COUNTER); - } - --static struct rtnl_link_stats64 *xlr_get_stats64(struct net_device *ndev, -- struct rtnl_link_stats64 *stats -- ) --{ -- xlr_stats(ndev, stats); -- return stats; --} -- - static const struct net_device_ops xlr_netdev_ops = { - .ndo_open = xlr_net_open, - .ndo_stop = xlr_net_stop, -@@ -410,7 +402,7 @@ static const struct net_device_ops xlr_n - .ndo_select_queue = xlr_net_select_queue, - .ndo_set_mac_address = xlr_net_set_mac_addr, - .ndo_set_rx_mode = xlr_set_rx_mode, -- .ndo_get_stats64 = xlr_get_stats64, -+ .ndo_get_stats64 = xlr_stats, - }; - - /* ---- a/include/linux/device.h -+++ b/include/linux/device.h -@@ -688,6 +688,25 @@ void __iomem *devm_ioremap_resource(stru - int devm_add_action(struct device *dev, void (*action)(void *), void *data); - void devm_remove_action(struct device *dev, void (*action)(void *), void *data); - -+/** -+ * devm_alloc_percpu - Resource-managed alloc_percpu -+ * @dev: Device to allocate per-cpu memory for -+ * @type: Type to allocate per-cpu memory for -+ * -+ * Managed alloc_percpu. Per-cpu memory allocated with this function is -+ * automatically freed on driver detach. -+ * -+ * RETURNS: -+ * Pointer to allocated memory on success, NULL on failure. -+ */ -+#define devm_alloc_percpu(dev, type) \ -+ ((typeof(type) __percpu *)__devm_alloc_percpu((dev), sizeof(type), \ -+ __alignof__(type))) -+ -+void __percpu *__devm_alloc_percpu(struct device *dev, size_t size, -+ size_t align); -+void devm_free_percpu(struct device *dev, void __percpu *pdata); -+ - static inline int devm_add_action_or_reset(struct device *dev, - void (*action)(void *), void *data) - { ---- /dev/null -+++ b/include/linux/fsl/svr.h -@@ -0,0 +1,97 @@ -+/* -+ * MPC85xx cpu type detection -+ * -+ * Copyright 2011-2012 Freescale Semiconductor, Inc. -+ * -+ * This 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. -+ */ -+ -+#ifndef FSL_SVR_H -+#define FSL_SVR_H -+ -+#define SVR_REV(svr) ((svr) & 0xFF) /* SOC design resision */ -+#define SVR_MAJ(svr) (((svr) >> 4) & 0xF) /* Major revision field*/ -+#define SVR_MIN(svr) (((svr) >> 0) & 0xF) /* Minor revision field*/ -+ -+/* Some parts define SVR[0:23] as the SOC version */ -+#define SVR_SOC_VER(svr) (((svr) >> 8) & 0xFFF7FF) /* SOC Version fields */ -+ -+#define SVR_8533 0x803400 -+#define SVR_8535 0x803701 -+#define SVR_8536 0x803700 -+#define SVR_8540 0x803000 -+#define SVR_8541 0x807200 -+#define SVR_8543 0x803200 -+#define SVR_8544 0x803401 -+#define SVR_8545 0x803102 -+#define SVR_8547 0x803101 -+#define SVR_8548 0x803100 -+#define SVR_8555 0x807100 -+#define SVR_8560 0x807000 -+#define SVR_8567 0x807501 -+#define SVR_8568 0x807500 -+#define SVR_8569 0x808000 -+#define SVR_8572 0x80E000 -+#define SVR_P1010 0x80F100 -+#define SVR_P1011 0x80E500 -+#define SVR_P1012 0x80E501 -+#define SVR_P1013 0x80E700 -+#define SVR_P1014 0x80F101 -+#define SVR_P1017 0x80F700 -+#define SVR_P1020 0x80E400 -+#define SVR_P1021 0x80E401 -+#define SVR_P1022 0x80E600 -+#define SVR_P1023 0x80F600 -+#define SVR_P1024 0x80E402 -+#define SVR_P1025 0x80E403 -+#define SVR_P2010 0x80E300 -+#define SVR_P2020 0x80E200 -+#define SVR_P2040 0x821000 -+#define SVR_P2041 0x821001 -+#define SVR_P3041 0x821103 -+#define SVR_P4040 0x820100 -+#define SVR_P4080 0x820000 -+#define SVR_P5010 0x822100 -+#define SVR_P5020 0x822000 -+#define SVR_P5021 0X820500 -+#define SVR_P5040 0x820400 -+#define SVR_T4240 0x824000 -+#define SVR_T4120 0x824001 -+#define SVR_T4160 0x824100 -+#define SVR_T4080 0x824102 -+#define SVR_C291 0x850000 -+#define SVR_C292 0x850020 -+#define SVR_C293 0x850030 -+#define SVR_B4860 0X868000 -+#define SVR_G4860 0x868001 -+#define SVR_G4060 0x868003 -+#define SVR_B4440 0x868100 -+#define SVR_G4440 0x868101 -+#define SVR_B4420 0x868102 -+#define SVR_B4220 0x868103 -+#define SVR_T1040 0x852000 -+#define SVR_T1041 0x852001 -+#define SVR_T1042 0x852002 -+#define SVR_T1020 0x852100 -+#define SVR_T1021 0x852101 -+#define SVR_T1022 0x852102 -+#define SVR_T1023 0x854100 -+#define SVR_T1024 0x854000 -+#define SVR_T2080 0x853000 -+#define SVR_T2081 0x853100 -+ -+#define SVR_8610 0x80A000 -+#define SVR_8641 0x809000 -+#define SVR_8641D 0x809001 -+ -+#define SVR_9130 0x860001 -+#define SVR_9131 0x860000 -+#define SVR_9132 0x861000 -+#define SVR_9232 0x861400 -+ -+#define SVR_Unknown 0xFFFFFF -+ -+#endif ---- a/include/linux/fsl_devices.h -+++ b/include/linux/fsl_devices.h -@@ -99,7 +99,10 @@ struct fsl_usb2_platform_data { - unsigned suspended:1; - unsigned already_suspended:1; - unsigned has_fsl_erratum_a007792:1; -+ unsigned has_fsl_erratum_14:1; - unsigned has_fsl_erratum_a005275:1; -+ unsigned has_fsl_erratum_a006918:1; -+ unsigned has_fsl_erratum_a005697:1; - unsigned check_phy_clk_valid:1; - - /* register save area for suspend/resume */ ---- a/include/linux/netdev_features.h -+++ b/include/linux/netdev_features.h -@@ -74,6 +74,7 @@ enum { - NETIF_F_BUSY_POLL_BIT, /* Busy poll */ - - NETIF_F_HW_TC_BIT, /* Offload TC infrastructure */ -+ NETIF_F_HW_ACCEL_MQ_BIT, /* Hardware-accelerated multiqueue */ - - /* - * Add your fresh new feature above and remember to update -@@ -136,6 +137,7 @@ enum { - #define NETIF_F_HW_L2FW_DOFFLOAD __NETIF_F(HW_L2FW_DOFFLOAD) - #define NETIF_F_BUSY_POLL __NETIF_F(BUSY_POLL) - #define NETIF_F_HW_TC __NETIF_F(HW_TC) -+#define NETIF_F_HW_ACCEL_MQ __NETIF_F(HW_ACCEL_MQ) - - #define for_each_netdev_feature(mask_addr, bit) \ - for_each_set_bit(bit, (unsigned long *)mask_addr, NETDEV_FEATURE_COUNT) ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -916,8 +916,8 @@ struct netdev_xdp { - * Callback used when the transmitter has not made any progress - * for dev->watchdog ticks. - * -- * struct rtnl_link_stats64* (*ndo_get_stats64)(struct net_device *dev, -- * struct rtnl_link_stats64 *storage); -+ * void (*ndo_get_stats64)(struct net_device *dev, -+ * struct rtnl_link_stats64 *storage); - * struct net_device_stats* (*ndo_get_stats)(struct net_device *dev); - * Called when a user wants to get the network device usage - * statistics. Drivers must do one of the following: -@@ -1165,8 +1165,8 @@ struct net_device_ops { - struct neigh_parms *); - void (*ndo_tx_timeout) (struct net_device *dev); - -- struct rtnl_link_stats64* (*ndo_get_stats64)(struct net_device *dev, -- struct rtnl_link_stats64 *storage); -+ void (*ndo_get_stats64)(struct net_device *dev, -+ struct rtnl_link_stats64 *storage); - bool (*ndo_has_offload_stats)(int attr_id); - int (*ndo_get_offload_stats)(int attr_id, - const struct net_device *dev, -@@ -1509,6 +1509,8 @@ enum netdev_priv_flags { - * @if_port: Selectable AUI, TP, ... - * @dma: DMA channel - * @mtu: Interface MTU value -+ * @min_mtu: Interface Minimum MTU value -+ * @max_mtu: Interface Maximum MTU value - * @type: Interface hardware type - * @hard_header_len: Maximum hardware header length. - * @min_header_len: Minimum hardware header length -@@ -1735,6 +1737,8 @@ struct net_device { - unsigned char dma; - - unsigned int mtu; -+ unsigned int min_mtu; -+ unsigned int max_mtu; - unsigned short type; - unsigned short hard_header_len; - unsigned short min_header_len; ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -903,6 +903,7 @@ void kfree_skb(struct sk_buff *skb); - void kfree_skb_list(struct sk_buff *segs); - void skb_tx_error(struct sk_buff *skb); - void consume_skb(struct sk_buff *skb); -+void skb_recycle(struct sk_buff *skb); - void __kfree_skb(struct sk_buff *skb); - extern struct kmem_cache *skbuff_head_cache; - -@@ -3057,6 +3058,7 @@ static inline void skb_free_datagram_loc - } - int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags); - int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len); -+void copy_skb_header(struct sk_buff *new, const struct sk_buff *old); - int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len); - __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, u8 *to, - int len, __wsum csum); ---- a/include/linux/sys_soc.h -+++ b/include/linux/sys_soc.h -@@ -13,6 +13,7 @@ struct soc_device_attribute { - const char *family; - const char *revision; - const char *soc_id; -+ const void *data; - }; - - /** -@@ -34,4 +35,6 @@ void soc_device_unregister(struct soc_de - */ - struct device *soc_device_to_device(struct soc_device *soc); - -+const struct soc_device_attribute *soc_device_match( -+ const struct soc_device_attribute *matches); - #endif /* __SOC_BUS_H */ ---- a/include/net/ip_tunnels.h -+++ b/include/net/ip_tunnels.h -@@ -261,8 +261,8 @@ int ip_tunnel_ioctl(struct net_device *d - int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict); - int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu); - --struct rtnl_link_stats64 *ip_tunnel_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *tot); -+void ip_tunnel_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *tot); - struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, - int link, __be16 flags, - __be32 remote, __be32 local, ---- a/include/uapi/linux/if_ether.h -+++ b/include/uapi/linux/if_ether.h -@@ -35,6 +35,7 @@ - #define ETH_DATA_LEN 1500 /* Max. octets in payload */ - #define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ - #define ETH_FCS_LEN 4 /* Octets in the FCS */ -+#define ETH_MIN_MTU 68 /* Min IPv4 MTU per RFC791 */ - - /* - * These are the defined Ethernet Protocol ID's. ---- a/net/8021q/vlan_dev.c -+++ b/net/8021q/vlan_dev.c -@@ -671,7 +671,8 @@ static int vlan_ethtool_get_ts_info(stru - return 0; - } - --static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) -+static void vlan_dev_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct vlan_pcpu_stats *p; - u32 rx_errors = 0, tx_dropped = 0; -@@ -702,8 +703,6 @@ static struct rtnl_link_stats64 *vlan_de - } - stats->rx_errors = rx_errors; - stats->tx_dropped = tx_dropped; -- -- return stats; - } - - #ifdef CONFIG_NET_POLL_CONTROLLER ---- a/net/bridge/br_device.c -+++ b/net/bridge/br_device.c -@@ -156,8 +156,8 @@ static int br_dev_stop(struct net_device - return 0; - } - --static struct rtnl_link_stats64 *br_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void br_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct net_bridge *br = netdev_priv(dev); - struct pcpu_sw_netstats tmp, sum = { 0 }; -@@ -181,8 +181,6 @@ static struct rtnl_link_stats64 *br_get_ - stats->tx_packets = sum.tx_packets; - stats->rx_bytes = sum.rx_bytes; - stats->rx_packets = sum.rx_packets; -- -- return stats; - } - - static int br_change_mtu(struct net_device *dev, int new_mtu) ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -6603,9 +6603,18 @@ int dev_set_mtu(struct net_device *dev, - if (new_mtu == dev->mtu) - return 0; - -- /* MTU must be positive. */ -- if (new_mtu < 0) -+ /* MTU must be positive, and in range */ -+ if (new_mtu < 0 || new_mtu < dev->min_mtu) { -+ net_err_ratelimited("%s: Invalid MTU %d requested, hw min %d\n", -+ dev->name, new_mtu, dev->min_mtu); - return -EINVAL; -+ } -+ -+ if (dev->max_mtu > 0 && new_mtu > dev->max_mtu) { -+ net_err_ratelimited("%s: Invalid MTU %d requested, hw max %d\n", -+ dev->name, new_mtu, dev->min_mtu); -+ return -EINVAL; -+ } - - if (!netif_device_present(dev)) - return -ENODEV; ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -842,6 +842,32 @@ void napi_consume_skb(struct sk_buff *sk - } - EXPORT_SYMBOL(napi_consume_skb); - -+/** -+ * skb_recycle - clean up an skb for reuse -+ * @skb: buffer -+ * -+ * Recycles the skb to be reused as a receive buffer. This -+ * function does any necessary reference count dropping, and -+ * cleans up the skbuff as if it just came from __alloc_skb(). -+ */ -+void skb_recycle(struct sk_buff *skb) -+{ -+ struct skb_shared_info *shinfo; -+ u8 head_frag = skb->head_frag; -+ -+ skb_release_head_state(skb); -+ -+ shinfo = skb_shinfo(skb); -+ memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); -+ atomic_set(&shinfo->dataref, 1); -+ -+ memset(skb, 0, offsetof(struct sk_buff, tail)); -+ skb->data = skb->head + NET_SKB_PAD; -+ skb->head_frag = head_frag; -+ skb_reset_tail_pointer(skb); -+} -+EXPORT_SYMBOL(skb_recycle); -+ - /* Make sure a field is enclosed inside headers_start/headers_end section */ - #define CHECK_SKB_FIELD(field) \ - BUILD_BUG_ON(offsetof(struct sk_buff, field) < \ -@@ -1073,7 +1099,7 @@ static void skb_headers_offset_update(st - skb->inner_mac_header += off; - } - --static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) -+void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) - { - __copy_skb_header(new, old); - -@@ -1081,6 +1107,7 @@ static void copy_skb_header(struct sk_bu - skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; - skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type; - } -+EXPORT_SYMBOL(copy_skb_header); - - static inline int skb_alloc_rx_flag(const struct sk_buff *skb) - { ---- a/net/ipv4/ip_tunnel_core.c -+++ b/net/ipv4/ip_tunnel_core.c -@@ -188,8 +188,8 @@ int iptunnel_handle_offloads(struct sk_b - EXPORT_SYMBOL_GPL(iptunnel_handle_offloads); - - /* Often modified stats are per cpu, other are shared (netdev->stats) */ --struct rtnl_link_stats64 *ip_tunnel_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *tot) -+void ip_tunnel_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *tot) - { - int i; - -@@ -214,8 +214,6 @@ struct rtnl_link_stats64 *ip_tunnel_get_ - tot->rx_bytes += rx_bytes; - tot->tx_bytes += tx_bytes; - } -- -- return tot; - } - EXPORT_SYMBOL_GPL(ip_tunnel_get_stats64); - ---- a/net/l2tp/l2tp_eth.c -+++ b/net/l2tp/l2tp_eth.c -@@ -106,8 +106,8 @@ static int l2tp_eth_dev_xmit(struct sk_b - return NETDEV_TX_OK; - } - --static struct rtnl_link_stats64 *l2tp_eth_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void l2tp_eth_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct l2tp_eth *priv = netdev_priv(dev); - -@@ -117,10 +117,8 @@ static struct rtnl_link_stats64 *l2tp_et - stats->rx_bytes = atomic_long_read(&priv->rx_bytes); - stats->rx_packets = atomic_long_read(&priv->rx_packets); - stats->rx_errors = atomic_long_read(&priv->rx_errors); -- return stats; - } - -- - static const struct net_device_ops l2tp_eth_netdev_ops = { - .ndo_init = l2tp_eth_dev_init, - .ndo_uninit = l2tp_eth_dev_uninit, ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -1146,7 +1146,7 @@ static u16 ieee80211_netdev_select_queue - return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); - } - --static struct rtnl_link_stats64 * -+static void - ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - int i; -@@ -1171,8 +1171,6 @@ ieee80211_get_stats64(struct net_device - stats->rx_bytes += rx_bytes; - stats->tx_bytes += tx_bytes; - } -- -- return stats; - } - - static const struct net_device_ops ieee80211_dataif_ops = { ---- a/net/openvswitch/vport-internal_dev.c -+++ b/net/openvswitch/vport-internal_dev.c -@@ -106,7 +106,7 @@ static void internal_dev_destructor(stru - free_netdev(dev); - } - --static struct rtnl_link_stats64 * -+static void - internal_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - int i; -@@ -134,8 +134,6 @@ internal_get_stats(struct net_device *de - stats->tx_bytes += local_stats.tx_bytes; - stats->tx_packets += local_stats.tx_packets; - } -- -- return stats; - } - - static void internal_set_rx_headroom(struct net_device *dev, int new_hr) ---- a/net/sched/sch_generic.c -+++ b/net/sched/sch_generic.c -@@ -309,6 +309,13 @@ static void dev_watchdog(unsigned long a - txq->trans_timeout++; - break; - } -+ -+ /* Devices with HW_ACCEL_MQ have multiple txqs -+ * but update only the first one's transmission -+ * timestamp so avoid checking the rest. -+ */ -+ if (dev->features & NETIF_F_HW_ACCEL_MQ) -+ break; - } - - if (some_queue_timedout) { ---- a/net/sched/sch_teql.c -+++ b/net/sched/sch_teql.c -@@ -401,8 +401,8 @@ static int teql_master_close(struct net_ - return 0; - } - --static struct rtnl_link_stats64 *teql_master_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void teql_master_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct teql_master *m = netdev_priv(dev); - -@@ -410,7 +410,6 @@ static struct rtnl_link_stats64 *teql_ma - stats->tx_bytes = m->tx_bytes; - stats->tx_errors = m->tx_errors; - stats->tx_dropped = m->tx_dropped; -- return stats; - } - - static int teql_master_mtu(struct net_device *dev, int new_mtu) diff --git a/target/linux/layerscape/patches-4.9/701-sdk_dpaa-support-layerscape.patch b/target/linux/layerscape/patches-4.9/701-sdk_dpaa-support-layerscape.patch index 56c07c5e6..4ebcdc73a 100644 --- a/target/linux/layerscape/patches-4.9/701-sdk_dpaa-support-layerscape.patch +++ b/target/linux/layerscape/patches-4.9/701-sdk_dpaa-support-layerscape.patch @@ -1,4 +1,4 @@ -From 6fe4518adbbbab0404958db4aa95673d60174881 Mon Sep 17 00:00:00 2001 +From 3cd36deb674720ab34eabb9783648ed743e52121 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Mon, 25 Sep 2017 11:58:03 +0800 Subject: [PATCH] sdk_dpaa: support layerscape @@ -18,15 +18,15 @@ Signed-off-by: Yangbo Lu .../net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c | 180 + .../net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h | 43 + drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 1213 ++++ - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 698 ++ + drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 687 ++ .../ethernet/freescale/sdk_dpaa/dpaa_eth_base.c | 205 + .../ethernet/freescale/sdk_dpaa/dpaa_eth_base.h | 49 + .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 1992 +++++ .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h | 237 + - .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 1811 +++++ + .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 1820 +++++ .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.h | 225 + .../ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c | 381 + - .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 1179 +++ + .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 1168 +++ .../ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c | 278 + .../ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h | 144 + .../net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c | 544 ++ @@ -41,24 +41,24 @@ Signed-off-by: Yangbo Lu .../freescale/sdk_fman/Peripherals/FM/HC/Makefile | 15 + .../freescale/sdk_fman/Peripherals/FM/HC/hc.c | 1232 ++++ .../freescale/sdk_fman/Peripherals/FM/MAC/Makefile | 28 + - .../freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c | 1464 ++++ + .../freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c | 1465 ++++ .../freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h | 228 + .../sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c | 97 + .../sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h | 42 + - .../freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c | 658 ++ - .../freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h | 225 + + .../freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c | 674 ++ + .../freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h | 226 + .../sdk_fman/Peripherals/FM/MAC/fman_crc32.c | 119 + .../sdk_fman/Peripherals/FM/MAC/fman_crc32.h | 43 + .../sdk_fman/Peripherals/FM/MAC/fman_dtsec.c | 845 +++ .../Peripherals/FM/MAC/fman_dtsec_mii_acc.c | 163 + - .../sdk_fman/Peripherals/FM/MAC/fman_memac.c | 511 ++ + .../sdk_fman/Peripherals/FM/MAC/fman_memac.c | 532 ++ .../Peripherals/FM/MAC/fman_memac_mii_acc.c | 213 + .../sdk_fman/Peripherals/FM/MAC/fman_tgec.c | 367 + - .../freescale/sdk_fman/Peripherals/FM/MAC/memac.c | 1096 +++ + .../freescale/sdk_fman/Peripherals/FM/MAC/memac.c | 1153 +++ .../freescale/sdk_fman/Peripherals/FM/MAC/memac.h | 110 + .../sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c | 78 + .../sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h | 73 + - .../freescale/sdk_fman/Peripherals/FM/MAC/tgec.c | 975 +++ + .../freescale/sdk_fman/Peripherals/FM/MAC/tgec.c | 1017 +++ .../freescale/sdk_fman/Peripherals/FM/MAC/tgec.h | 151 + .../sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c | 139 + .../sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h | 80 + @@ -124,7 +124,7 @@ Signed-off-by: Yangbo Lu .../sdk_fman/inc/Peripherals/crc_mac_addr_ext.h | 364 + .../freescale/sdk_fman/inc/Peripherals/dpaa_ext.h | 210 + .../freescale/sdk_fman/inc/Peripherals/fm_ext.h | 1731 +++++ - .../sdk_fman/inc/Peripherals/fm_mac_ext.h | 859 +++ + .../sdk_fman/inc/Peripherals/fm_mac_ext.h | 887 +++ .../sdk_fman/inc/Peripherals/fm_macsec_ext.h | 1271 ++++ .../sdk_fman/inc/Peripherals/fm_muram_ext.h | 170 + .../sdk_fman/inc/Peripherals/fm_pcd_ext.h | 3974 ++++++++++ @@ -154,7 +154,7 @@ Signed-off-by: Yangbo Lu .../freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h | 1096 +++ .../sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h | 107 + .../freescale/sdk_fman/inc/flib/fsl_fman_kg.h | 514 ++ - .../freescale/sdk_fman/inc/flib/fsl_fman_memac.h | 427 ++ + .../freescale/sdk_fman/inc/flib/fsl_fman_memac.h | 434 ++ .../sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h | 78 + .../freescale/sdk_fman/inc/flib/fsl_fman_port.h | 593 ++ .../freescale/sdk_fman/inc/flib/fsl_fman_prs.h | 102 + @@ -195,7 +195,7 @@ Signed-off-by: Yangbo Lu .../freescale/sdk_fman/src/inc/system/sys_io_ext.h | 46 + .../freescale/sdk_fman/src/inc/types_linux.h | 208 + .../sdk_fman/src/inc/wrapper/fsl_fman_test.h | 84 + - .../sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h | 128 + + .../sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h | 130 + .../sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h | 163 + .../sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h | 921 +++ .../ethernet/freescale/sdk_fman/src/inc/xx/xx.h | 50 + @@ -206,7 +206,7 @@ Signed-off-by: Yangbo Lu .../freescale/sdk_fman/src/wrapper/lnxwrp_fm.c | 2908 ++++++++ .../freescale/sdk_fman/src/wrapper/lnxwrp_fm.h | 294 + .../sdk_fman/src/wrapper/lnxwrp_fm_port.c | 1480 ++++ - .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c | 4813 +++++++++++++ + .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c | 4854 +++++++++++++ .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c | 1297 ++++ .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h | 755 ++ .../sdk_fman/src/wrapper/lnxwrp_resources.h | 121 + @@ -262,13 +262,13 @@ Signed-off-by: Yangbo Lu include/uapi/linux/fmd/Peripherals/Kbuild | 4 + include/uapi/linux/fmd/Peripherals/fm_ioctls.h | 628 ++ include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h | 3084 ++++++++ - .../uapi/linux/fmd/Peripherals/fm_port_ioctls.h | 948 +++ + .../uapi/linux/fmd/Peripherals/fm_port_ioctls.h | 973 +++ .../uapi/linux/fmd/Peripherals/fm_test_ioctls.h | 208 + include/uapi/linux/fmd/integrations/Kbuild | 1 + .../linux/fmd/integrations/integration_ioctls.h | 56 + include/uapi/linux/fmd/ioctls.h | 96 + include/uapi/linux/fmd/net_ioctls.h | 430 ++ - 257 files changed, 152931 insertions(+) + 257 files changed, 153159 insertions(+) create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/Kconfig create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/Makefile create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c @@ -2923,7 +2923,7 @@ Signed-off-by: Yangbo Lu +module_exit(dpa_unload); --- /dev/null +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -@@ -0,0 +1,698 @@ +@@ -0,0 +1,687 @@ +/* Copyright 2008-2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without @@ -3440,17 +3440,6 @@ Signed-off-by: Yangbo Lu + return fd->offset; +} + -+/* Verifies if the skb length is below the interface MTU */ -+static inline int dpa_check_rx_mtu(struct sk_buff *skb, int mtu) -+{ -+ if (unlikely(skb->len > mtu)) -+ if ((skb->protocol != htons(ETH_P_8021Q)) -+ || (skb->len > mtu + 4)) -+ return -1; -+ -+ return 0; -+} -+ +static inline uint16_t dpa_get_headroom(struct dpa_buffer_layout_s *bl) +{ + uint16_t headroom; @@ -6119,7 +6108,7 @@ Signed-off-by: Yangbo Lu +#endif --- /dev/null +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -@@ -0,0 +1,1811 @@ +@@ -0,0 +1,1820 @@ +/* Copyright 2008-2013 Freescale Semiconductor, Inc. + * + * Redistribution and use in source and binary forms, with or without @@ -6385,7 +6374,16 @@ Signed-off-by: Yangbo Lu + +int dpa_change_mtu(struct net_device *net_dev, int new_mtu) +{ -+ const int max_mtu = dpa_get_max_mtu(); ++ int max_mtu = dpa_get_max_mtu(); ++ ++#ifndef CONFIG_PPC ++ /* Due to the A010022 FMan errata, we can not use contig frames larger ++ * than 4K, nor S/G frames. We need to prevent the user from setting a ++ * large MTU. ++ */ ++ if (unlikely(dpaa_errata_a010022)) ++ max_mtu = DPA_BP_RAW_SIZE; ++#endif + + /* Make sure we don't exceed the Ethernet controller's MAXFRM */ + if (new_mtu < 68 || new_mtu > max_mtu) { @@ -8545,7 +8543,7 @@ Signed-off-by: Yangbo Lu +module_exit(dpa_proxy_unload); --- /dev/null +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -0,0 +1,1179 @@ +@@ -0,0 +1,1168 @@ +/* Copyright 2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without @@ -9164,13 +9162,6 @@ Signed-off-by: Yangbo Lu + (*count_ptr)--; + skb->protocol = eth_type_trans(skb, net_dev); + -+ /* IP Reassembled frames are allowed to be larger than MTU */ -+ if (unlikely(dpa_check_rx_mtu(skb, net_dev->mtu) && -+ !(fd_status & FM_FD_IPR))) { -+ percpu_stats->rx_dropped++; -+ goto drop_bad_frame; -+ } -+ + skb_len = skb->len; + +#ifdef CONFIG_FSL_DPAA_DBG_LOOP @@ -9203,10 +9194,6 @@ Signed-off-by: Yangbo Lu +packet_dropped: + return; + -+drop_bad_frame: -+ dev_kfree_skb(skb); -+ return; -+ +_release_frame: + dpa_fd_release(net_dev, fd); +} @@ -14903,7 +14890,7 @@ Signed-off-by: Yangbo Lu + --- /dev/null +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c -@@ -0,0 +1,1464 @@ +@@ -0,0 +1,1465 @@ +/* + * Copyright 2008-2013 Freescale Semiconductor Inc. + * @@ -16295,6 +16282,7 @@ Signed-off-by: Yangbo Lu + + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = DtsecResetCounters; + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = DtsecGetStatistics; ++ p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = NULL; + + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = DtsecModifyMacAddress; + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = DtsecAddHashMacAddress; @@ -16746,7 +16734,7 @@ Signed-off-by: Yangbo Lu +#endif /* __DTSEC_MII_ACC_H */ --- /dev/null +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c -@@ -0,0 +1,658 @@ +@@ -0,0 +1,674 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * @@ -17210,6 +17198,22 @@ Signed-off-by: Yangbo Lu + +/* ......................................................................... */ + ++t_Error FM_MAC_GetFrameSizeCounters(t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type) ++{ ++ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; ++ ++ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); ++ ++ memset(p_FrameSizeCounters, 0, sizeof(t_FmMacFrameSizeCounters)); ++ ++ if (p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters) ++ return p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters(h_FmMac, p_FrameSizeCounters, type); ++ ++ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); ++} ++ ++/* ......................................................................... */ ++ +t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr) +{ + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; @@ -17407,7 +17411,7 @@ Signed-off-by: Yangbo Lu +#endif /* (defined(DEBUG_ERRORS) && ... */ --- /dev/null +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h -@@ -0,0 +1,225 @@ +@@ -0,0 +1,226 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * @@ -17516,6 +17520,7 @@ Signed-off-by: Yangbo Lu + + t_Error (*f_FM_MAC_ResetCounters) (t_Handle h_FmMac); + t_Error (*f_FM_MAC_GetStatistics) (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics); ++ t_Error (*f_FM_MAC_GetFrameSizeCounters) (t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type); + + t_Error (*f_FM_MAC_ModifyMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); + t_Error (*f_FM_MAC_AddHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); @@ -18817,7 +18822,7 @@ Signed-off-by: Yangbo Lu + --- /dev/null +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c -@@ -0,0 +1,511 @@ +@@ -0,0 +1,532 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * @@ -19180,24 +19185,45 @@ Signed-off-by: Yangbo Lu + case E_MEMAC_COUNTER_R64: + ret_val = GET_MEMAC_CNTR_64(r64); + break; ++ case E_MEMAC_COUNTER_T64: ++ ret_val = GET_MEMAC_CNTR_64(t64); ++ break; + case E_MEMAC_COUNTER_R127: + ret_val = GET_MEMAC_CNTR_64(r127); + break; ++ case E_MEMAC_COUNTER_T127: ++ ret_val = GET_MEMAC_CNTR_64(t127); ++ break; + case E_MEMAC_COUNTER_R255: + ret_val = GET_MEMAC_CNTR_64(r255); + break; ++ case E_MEMAC_COUNTER_T255: ++ ret_val = GET_MEMAC_CNTR_64(t255); ++ break; + case E_MEMAC_COUNTER_R511: + ret_val = GET_MEMAC_CNTR_64(r511); + break; ++ case E_MEMAC_COUNTER_T511: ++ ret_val = GET_MEMAC_CNTR_64(t511); ++ break; + case E_MEMAC_COUNTER_R1023: + ret_val = GET_MEMAC_CNTR_64(r1023); + break; ++ case E_MEMAC_COUNTER_T1023: ++ ret_val = GET_MEMAC_CNTR_64(t1023); ++ break; + case E_MEMAC_COUNTER_R1518: + ret_val = GET_MEMAC_CNTR_64(r1518); + break; ++ case E_MEMAC_COUNTER_T1518: ++ ret_val = GET_MEMAC_CNTR_64(t1518); ++ break; + case E_MEMAC_COUNTER_R1519X: + ret_val = GET_MEMAC_CNTR_64(r1519x); + break; ++ case E_MEMAC_COUNTER_T1519X: ++ ret_val = GET_MEMAC_CNTR_64(t1519x); ++ break; + case E_MEMAC_COUNTER_RFRG: + ret_val = GET_MEMAC_CNTR_64(rfrg); + break; @@ -19917,7 +19943,7 @@ Signed-off-by: Yangbo Lu +} --- /dev/null +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c -@@ -0,0 +1,1096 @@ +@@ -0,0 +1,1153 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * @@ -20513,6 +20539,62 @@ Signed-off-by: Yangbo Lu + +/* ......................................................................... */ + ++static t_Error MemacGetFrameSizeCounters(t_Handle h_Memac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type) ++{ ++ t_Memac *p_Memac = (t_Memac *)h_Memac; ++ ++ SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER); ++ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); ++ SANITY_CHECK_RETURN_ERROR(p_FrameSizeCounters, E_NULL_POINTER); ++ ++ switch (type) ++ { ++ case e_COMM_MODE_NONE: ++ break; ++ ++ case e_COMM_MODE_RX: ++ p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64); ++ p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127); ++ p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255); ++ p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511); ++ p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023); ++ p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518); ++ p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X); ++ break; ++ ++ case e_COMM_MODE_TX: ++ p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T64); ++ p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T127); ++ p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T255); ++ p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T511); ++ p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1023); ++ p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1518); ++ p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1519X); ++ break; ++ ++ case e_COMM_MODE_RX_AND_TX: ++ p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64) ++ + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T64); ++ p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127) ++ + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T127); ++ p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255) ++ + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T255); ++ p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511) ++ + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T511); ++ p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023) ++ + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1023); ++ p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518) ++ + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1518); ++ p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X) ++ + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1519X); ++ break; ++ } ++ ++ return E_OK; ++} ++ ++/* ......................................................................... */ ++ +static t_Error MemacModifyMacAddress (t_Handle h_Memac, t_EnetAddr *p_EnetAddr) +{ + t_Memac *p_Memac = (t_Memac *)h_Memac; @@ -20945,6 +21027,7 @@ Signed-off-by: Yangbo Lu + + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = MemacResetCounters; + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = MemacGetStatistics; ++ p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = MemacGetFrameSizeCounters; + + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = MemacModifyMacAddress; + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = MemacAddHashMacAddress; @@ -21286,7 +21369,7 @@ Signed-off-by: Yangbo Lu +#endif /* __MEMAC_MII_ACC_H */ --- /dev/null +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c -@@ -0,0 +1,975 @@ +@@ -0,0 +1,1017 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * @@ -21727,6 +21810,47 @@ Signed-off-by: Yangbo Lu + +/* ......................................................................... */ + ++static t_Error TgecGetFrameSizeCounters(t_Handle h_Tgec, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type) ++{ ++ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; ++ struct tgec_regs *p_TgecMemMap; ++ ++ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER); ++ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); ++ SANITY_CHECK_RETURN_ERROR(p_FrameSizeCounters, E_NULL_POINTER); ++ ++ p_TgecMemMap = p_Tgec->p_MemMap; ++ ++ switch (type) ++ { ++ case e_COMM_MODE_NONE: ++ break; ++ ++ case e_COMM_MODE_RX: ++ p_FrameSizeCounters->count_pkts_64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64); ++ p_FrameSizeCounters->count_pkts_65_to_127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127); ++ p_FrameSizeCounters->count_pkts_128_to_255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255); ++ p_FrameSizeCounters->count_pkts_256_to_511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511); ++ p_FrameSizeCounters->count_pkts_512_to_1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023); ++ p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518); ++ p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X); ++ break; ++ ++ case e_COMM_MODE_TX: ++ //Tx counters not supported ++ break; ++ ++ case e_COMM_MODE_RX_AND_TX: ++ //Tx counters not supported ++ break; ++ } ++ ++ return E_OK; ++} ++ ++ ++/* ......................................................................... */ ++ +static t_Error TgecEnable1588TimeStamp(t_Handle h_Tgec) +{ + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; @@ -22194,6 +22318,7 @@ Signed-off-by: Yangbo Lu + + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = TgecResetCounters; + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = TgecGetStatistics; ++ p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = TgecGetFrameSizeCounters; + + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = TgecModifyMacAddress; + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = TgecAddHashMacAddress; @@ -77953,7 +78078,7 @@ Signed-off-by: Yangbo Lu +#endif /* __FM_EXT */ --- /dev/null +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h -@@ -0,0 +1,859 @@ +@@ -0,0 +1,887 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * @@ -78153,6 +78278,19 @@ Signed-off-by: Yangbo Lu + - Other */ +} t_FmMacStatistics; + ++/**************************************************************************//** ++ @Description FM MAC Frame Size Counters ++*//***************************************************************************/ ++typedef struct t_FmMacFrameSizeCounters { ++ ++ uint64_t count_pkts_64; /**< 64 byte frame counter */ ++ uint64_t count_pkts_65_to_127; /**< 65 to 127 byte frame counter */ ++ uint64_t count_pkts_128_to_255; /**< 128 to 255 byte frame counter */ ++ uint64_t count_pkts_256_to_511; /**< 256 to 511 byte frame counter */ ++ uint64_t count_pkts_512_to_1023; /**< 512 to 1023 byte frame counter */ ++ uint64_t count_pkts_1024_to_1518; /**< 1024 to 1518 byte frame counter */ ++ uint64_t count_pkts_1519_to_1522; /**< 1519 to 1522 byte good frame count */ ++} t_FmMacFrameSizeCounters; + +/**************************************************************************//** + @Group FM_mac_init_grp FM MAC Initialization Unit @@ -78610,6 +78748,21 @@ Signed-off-by: Yangbo Lu +t_Error FM_MAC_GetStatistics(t_Handle h_FmMac, t_FmMacStatistics *p_Statistics); + +/**************************************************************************//** ++ @Function FM_MAC_GetFrameSizeCounters ++ ++ @Description get MAC statistics counters for different frame size ++ ++ @Param[in] h_FmMac - A handle to a FM MAC Module. ++ @Param[in] p_FrameSizeCounters - Structure with counters ++ @Param[in] type - Type of counters to be read ++ ++ @Return E_OK on success; Error code otherwise. ++ ++ @Cautions Allowed only following FM_Init(). ++*//***************************************************************************/ ++t_Error FM_MAC_GetFrameSizeCounters(t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type); ++ ++/**************************************************************************//** + @Function FM_MAC_ModifyMacAddr + + @Description Replace the main MAC Address @@ -94578,7 +94731,7 @@ Signed-off-by: Yangbo Lu +#endif /* __FSL_FMAN_KG_H */ --- /dev/null +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h -@@ -0,0 +1,427 @@ +@@ -0,0 +1,434 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * @@ -94727,12 +94880,19 @@ Signed-off-by: Yangbo Lu + +enum memac_counters { + E_MEMAC_COUNTER_R64, ++ E_MEMAC_COUNTER_T64, + E_MEMAC_COUNTER_R127, ++ E_MEMAC_COUNTER_T127, + E_MEMAC_COUNTER_R255, ++ E_MEMAC_COUNTER_T255, + E_MEMAC_COUNTER_R511, ++ E_MEMAC_COUNTER_T511, + E_MEMAC_COUNTER_R1023, ++ E_MEMAC_COUNTER_T1023, + E_MEMAC_COUNTER_R1518, ++ E_MEMAC_COUNTER_T1518, + E_MEMAC_COUNTER_R1519X, ++ E_MEMAC_COUNTER_T1519X, + E_MEMAC_COUNTER_RFRG, + E_MEMAC_COUNTER_RJBR, + E_MEMAC_COUNTER_RDRP, @@ -103346,7 +103506,7 @@ Signed-off-by: Yangbo Lu +#endif /* __FSL_FMAN_TEST_H */ --- /dev/null +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h -@@ -0,0 +1,128 @@ +@@ -0,0 +1,130 @@ +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. + * All rights reserved. + * @@ -103472,6 +103632,8 @@ Signed-off-by: Yangbo Lu +/* FMAN MAC exported routines */ +EXPORT_SYMBOL(FM_MAC_GetStatistics); + ++EXPORT_SYMBOL(FM_MAC_GetFrameSizeCounters); ++ +EXPORT_SYMBOL(FM_GetSpecialOperationCoding); + +#endif /* __LNXWRP_EXP_SYM_H */ @@ -111188,7 +111350,7 @@ Signed-off-by: Yangbo Lu +module_exit(fm_port_unload); --- /dev/null +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c -@@ -0,0 +1,4813 @@ +@@ -0,0 +1,4854 @@ +/* + * Copyright 2008-2012 Freescale Semiconductor Inc. + * @@ -115799,6 +115961,47 @@ Signed-off-by: Yangbo Lu + break; + } + ++ case FM_PORT_IOC_GET_MAC_FRAME_SIZE_COUNTERS: ++ { ++ t_LnxWrpFmDev *p_LnxWrpFmDev = ++ (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev; ++ ioc_fm_port_mac_frame_size_counters_t param; ++ t_FmMacFrameSizeCounters frameSizeCounters; ++ int mac_id = p_LnxWrpFmPortDev->id; ++ ++ if (!p_LnxWrpFmDev) ++ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!")); ++ ++ if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev && ++ &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev) ++ mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */ ++ ++ if (!p_LnxWrpFmDev->macs[mac_id].h_Dev) ++ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!")); ++ ++ if (copy_from_user(¶m, (ioc_fm_port_mac_frame_size_counters_t *)arg, ++ sizeof(ioc_fm_port_mac_frame_size_counters_t))) ++ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); ++ ++ if (FM_MAC_GetFrameSizeCounters(p_LnxWrpFmDev->macs[mac_id].h_Dev, ++ &frameSizeCounters, param.type)) ++ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); ++ ++ param.count_pkts_64 = frameSizeCounters.count_pkts_64; ++ param.count_pkts_65_to_127 = frameSizeCounters.count_pkts_65_to_127; ++ param.count_pkts_128_to_255 = frameSizeCounters.count_pkts_128_to_255; ++ param.count_pkts_256_to_511 = frameSizeCounters.count_pkts_256_to_511; ++ param.count_pkts_512_to_1023 = frameSizeCounters.count_pkts_512_to_1023; ++ param.count_pkts_1024_to_1518 = frameSizeCounters.count_pkts_1024_to_1518; ++ param.count_pkts_1519_to_1522 = frameSizeCounters.count_pkts_1519_to_1522; ++ ++ if (copy_to_user((ioc_fm_port_mac_frame_size_counters_t *)arg, ¶m, ++ sizeof(ioc_fm_port_mac_frame_size_counters_t))) ++ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); ++ ++ break; ++ } ++ + case FM_PORT_IOC_GET_BMI_COUNTERS: + { + t_LnxWrpFmDev *p_LnxWrpFmDev = @@ -152474,7 +152677,7 @@ Signed-off-by: Yangbo Lu +/** @} */ /* end of lnx_ioctl_FM_grp group */ --- /dev/null +++ b/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h -@@ -0,0 +1,948 @@ +@@ -0,0 +1,973 @@ +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. + * All rights reserved. + * @@ -153416,6 +153619,31 @@ Signed-off-by: Yangbo Lu + +#define FM_PORT_IOC_GET_BMI_COUNTERS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(42), ioc_fm_port_bmi_stats_t) + ++typedef struct ioc_fm_port_mac_frame_size_counters_t { ++ ++ e_CommMode type; ++ uint64_t count_pkts_64; /**< 64 byte frame counter */ ++ uint64_t count_pkts_65_to_127; /**< 65 to 127 byte frame counter */ ++ uint64_t count_pkts_128_to_255; /**< 128 to 255 byte frame counter */ ++ uint64_t count_pkts_256_to_511; /**< 256 to 511 byte frame counter */ ++ uint64_t count_pkts_512_to_1023; /**< 512 to 1023 byte frame counter */ ++ uint64_t count_pkts_1024_to_1518; /**< 1024 to 1518 byte frame counter */ ++ uint64_t count_pkts_1519_to_1522; /**< 1519 to 1522 byte good frame count */ ++} ioc_fm_port_mac_frame_size_counters_t; ++ ++/**************************************************************************//** ++ @Function FM_MAC_GetFrameSizeCounters ++ ++ @Description get MAC statistics counters for different frame size ++ ++ @Param[out] ioc_fm_port_mac_frame_size_counters_t A structure holding the counters ++ ++ @Return E_OK on success; Error code otherwise. ++ ++ @Cautions Allowed only following FM_Init(). ++*//***************************************************************************/ ++#define FM_PORT_IOC_GET_MAC_FRAME_SIZE_COUNTERS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(43), ioc_fm_port_mac_frame_size_counters_t) ++ + +/** @} */ /* end of lnx_ioctl_FM_PORT_pcd_runtime_control_grp group */ +/** @} */ /* end of lnx_ioctl_FM_PORT_runtime_control_grp group */ diff --git a/target/linux/layerscape/patches-4.9/702-pci-support-layerscape.patch b/target/linux/layerscape/patches-4.9/702-pci-support-layerscape.patch index 4e3b139b4..65243518a 100644 --- a/target/linux/layerscape/patches-4.9/702-pci-support-layerscape.patch +++ b/target/linux/layerscape/patches-4.9/702-pci-support-layerscape.patch @@ -1,4 +1,4 @@ -From c4813da334b0c31e9c55eea015f1e898e84ff45b Mon Sep 17 00:00:00 2001 +From 9e6e0a53b29190dbd86a39304b59c3028f5b36c2 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Mon, 25 Sep 2017 11:04:10 +0800 Subject: [PATCH] pci: support layerscape @@ -15,17 +15,17 @@ Signed-off-by: Mingkai Hu Signed-off-by: Christoph Hellwig Signed-off-by: Yangbo Lu --- - drivers/irqchip/irq-ls-scfg-msi.c | 256 +++++++-- + drivers/irqchip/irq-ls-scfg-msi.c | 257 +++++++-- drivers/pci/host/Makefile | 2 +- drivers/pci/host/pci-layerscape-ep-debugfs.c | 758 +++++++++++++++++++++++++++ drivers/pci/host/pci-layerscape-ep.c | 309 +++++++++++ drivers/pci/host/pci-layerscape-ep.h | 115 ++++ - drivers/pci/host/pci-layerscape.c | 37 +- + drivers/pci/host/pci-layerscape.c | 38 +- drivers/pci/host/pcie-designware.c | 6 + drivers/pci/host/pcie-designware.h | 1 + drivers/pci/pcie/portdrv_core.c | 181 +++---- include/linux/pci.h | 1 + - 10 files changed, 1518 insertions(+), 148 deletions(-) + 10 files changed, 1520 insertions(+), 148 deletions(-) create mode 100644 drivers/pci/host/pci-layerscape-ep-debugfs.c create mode 100644 drivers/pci/host/pci-layerscape-ep.c create mode 100644 drivers/pci/host/pci-layerscape-ep.h @@ -198,7 +198,7 @@ Signed-off-by: Yangbo Lu &ls_scfg_msi_domain_ops, msi_data); if (!msi_data->parent) { -@@ -164,16 +230,117 @@ static int ls_scfg_msi_domains_init(stru +@@ -164,16 +230,118 @@ static int ls_scfg_msi_domains_init(stru return 0; } @@ -288,6 +288,7 @@ Signed-off-by: Yangbo Lu + { .compatible = "fsl,1s1021a-msi", .data = &ls1021_msi_cfg}, + { .compatible = "fsl,1s1043a-msi", .data = &ls1021_msi_cfg}, + ++ { .compatible = "fsl,ls1012a-msi", .data = &ls1021_msi_cfg }, + { .compatible = "fsl,ls1021a-msi", .data = &ls1021_msi_cfg }, + { .compatible = "fsl,ls1043a-msi", .data = &ls1021_msi_cfg }, + { .compatible = "fsl,ls1043a-v1.1-msi", .data = &ls1043_v1_1_msi_cfg }, @@ -317,7 +318,7 @@ Signed-off-by: Yangbo Lu res = platform_get_resource(pdev, IORESOURCE_MEM, 0); msi_data->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(msi_data->regs)) { -@@ -182,23 +349,48 @@ static int ls_scfg_msi_probe(struct plat +@@ -182,23 +350,48 @@ static int ls_scfg_msi_probe(struct plat } msi_data->msiir_addr = res->start; @@ -376,7 +377,7 @@ Signed-off-by: Yangbo Lu platform_set_drvdata(pdev, msi_data); return 0; -@@ -207,8 +399,10 @@ static int ls_scfg_msi_probe(struct plat +@@ -207,8 +400,10 @@ static int ls_scfg_msi_probe(struct plat static int ls_scfg_msi_remove(struct platform_device *pdev) { struct ls_scfg_msi *msi_data = platform_get_drvdata(pdev); @@ -388,7 +389,7 @@ Signed-off-by: Yangbo Lu irq_domain_remove(msi_data->msi_domain); irq_domain_remove(msi_data->parent); -@@ -218,12 +412,6 @@ static int ls_scfg_msi_remove(struct pla +@@ -218,12 +413,6 @@ static int ls_scfg_msi_remove(struct pla return 0; } @@ -1656,7 +1657,7 @@ Signed-off-by: Yangbo Lu } static int ls_pcie_msi_host_init(struct pcie_port *pp, -@@ -196,20 +209,38 @@ static struct ls_pcie_drvdata ls1021_drv +@@ -196,20 +209,39 @@ static struct ls_pcie_drvdata ls1021_drv static struct ls_pcie_drvdata ls1043_drvdata = { .lut_offset = 0x10000, .ltssm_shift = 24, @@ -1686,6 +1687,7 @@ Signed-off-by: Yangbo Lu }; static const struct of_device_id ls_pcie_of_match[] = { ++ { .compatible = "fsl,ls1012a-pcie", .data = &ls1046_drvdata }, { .compatible = "fsl,ls1021a-pcie", .data = &ls1021_drvdata }, { .compatible = "fsl,ls1043a-pcie", .data = &ls1043_drvdata }, + { .compatible = "fsl,ls1046a-pcie", .data = &ls1046_drvdata }, diff --git a/target/linux/layerscape/patches-4.9/703-phy-support-layerscape.patch b/target/linux/layerscape/patches-4.9/703-phy-support-layerscape.patch index 312faf2c5..81c473c4d 100644 --- a/target/linux/layerscape/patches-4.9/703-phy-support-layerscape.patch +++ b/target/linux/layerscape/patches-4.9/703-phy-support-layerscape.patch @@ -1741,7 +1741,7 @@ Signed-off-by: Yangbo Lu PHY_INTERFACE_MODE_MAX, } phy_interface_t; -@@ -784,6 +785,9 @@ int phy_stop_interrupts(struct phy_devic +@@ -780,6 +781,9 @@ int phy_stop_interrupts(struct phy_devic static inline int phy_read_status(struct phy_device *phydev) { diff --git a/target/linux/layerscape/patches-4.9/704-fsl-mc-layerscape-support.patch b/target/linux/layerscape/patches-4.9/704-fsl-mc-layerscape-support.patch index 2927c7e66..a35e59310 100644 --- a/target/linux/layerscape/patches-4.9/704-fsl-mc-layerscape-support.patch +++ b/target/linux/layerscape/patches-4.9/704-fsl-mc-layerscape-support.patch @@ -1,4 +1,4 @@ -From 464b4d9b8282e0f1e5040e4914505f91ce4d3750 Mon Sep 17 00:00:00 2001 +From afb7254de9f03c3efaf4e306dcf5f88e1873fc6b Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Mon, 25 Sep 2017 12:06:25 +0800 Subject: [PATCH] fsl-mc: layerscape support @@ -29,7 +29,7 @@ Signed-off-by: Yangbo Lu .../{include/dpcon-cmd.h => bus/dpio/dpio-cmd.h} | 73 +- drivers/staging/fsl-mc/bus/dpio/dpio-driver.c | 296 ++++++ drivers/staging/fsl-mc/bus/dpio/dpio-driver.txt | 135 +++ - drivers/staging/fsl-mc/bus/dpio/dpio-service.c | 689 +++++++++++++ + drivers/staging/fsl-mc/bus/dpio/dpio-service.c | 693 +++++++++++++ drivers/staging/fsl-mc/bus/dpio/dpio.c | 224 +++++ drivers/staging/fsl-mc/bus/dpio/dpio.h | 109 ++ drivers/staging/fsl-mc/bus/dpio/qbman-portal.c | 1049 ++++++++++++++++++++ @@ -68,7 +68,7 @@ Signed-off-by: Yangbo Lu drivers/staging/fsl-mc/include/mc-cmd.h | 44 +- drivers/staging/fsl-mc/include/mc-sys.h | 3 +- drivers/staging/fsl-mc/include/mc.h | 17 +- - 49 files changed, 7380 insertions(+), 2612 deletions(-) + 49 files changed, 7384 insertions(+), 2612 deletions(-) create mode 100644 drivers/staging/fsl-mc/bus/dpbp-cmd.h create mode 100644 drivers/staging/fsl-mc/bus/dpcon-cmd.h create mode 100644 drivers/staging/fsl-mc/bus/dpcon.c @@ -1772,7 +1772,7 @@ Signed-off-by: Yangbo Lu + Dequeue result struct and parsing APIs are defined in dpaa2-global.h. --- /dev/null +++ b/drivers/staging/fsl-mc/bus/dpio/dpio-service.c -@@ -0,0 +1,689 @@ +@@ -0,0 +1,693 @@ +/* + * Copyright 2014-2016 Freescale Semiconductor Inc. + * Copyright 2016 NXP @@ -1852,14 +1852,14 @@ Signed-off-by: Yangbo Lu + if (d) + return d; + -+ if (unlikely(cpu >= num_possible_cpus())) ++ if (unlikely(cpu >= (int)num_possible_cpus())) + return NULL; + + /* + * If cpu == -1, choose the current cpu, with no guarantees about + * potentially being migrated away. + */ -+ if (unlikely(cpu < 0)) ++ if (cpu < 0) + cpu = smp_processor_id(); + + /* If a specific cpu was requested, pick it up immediately */ @@ -1871,6 +1871,10 @@ Signed-off-by: Yangbo Lu + if (d) + return d; + ++ d = service_select_by_cpu(d, -1); ++ if (d) ++ return d; ++ + spin_lock(&dpio_list_lock); + d = list_entry(dpio_list.next, struct dpaa2_io, node); + list_del(&d->node); @@ -1897,7 +1901,7 @@ Signed-off-by: Yangbo Lu + return NULL; + + /* check if CPU is out of range (-1 means any cpu) */ -+ if (desc->cpu >= num_possible_cpus()) { ++ if (desc->cpu >= (int)num_possible_cpus()) { + kfree(obj); + return NULL; + } @@ -8354,14 +8358,6 @@ Signed-off-by: Yangbo Lu * Author: German Rivera * * This file is licensed under the terms of the GNU General Public -@@ -17,6 +17,7 @@ - #include - #include - #include "../include/mc-bus.h" -+#include "fsl-mc-private.h" - - /* - * Generate a unique ID identifying the interrupt (only used within the MSI --- a/drivers/staging/fsl-mc/bus/fsl-mc-private.h +++ b/drivers/staging/fsl-mc/bus/fsl-mc-private.h @@ -10,13 +10,15 @@ @@ -8393,11 +8389,8 @@ Signed-off-by: Yangbo Lu * Author: German Rivera * * This file is licensed under the terms of the GNU General Public -@@ -17,9 +17,10 @@ - #include - #include - #include "../include/mc-bus.h" -+#include "fsl-mc-private.h" +@@ -20,7 +20,7 @@ + #include "fsl-mc-private.h" static struct irq_chip its_msi_irq_chip = { - .name = "fsl-mc-bus-msi", @@ -8405,7 +8398,7 @@ Signed-off-by: Yangbo Lu .irq_mask = irq_chip_mask_parent, .irq_unmask = irq_chip_unmask_parent, .irq_eoi = irq_chip_eoi_parent, -@@ -51,7 +52,7 @@ static int its_fsl_mc_msi_prepare(struct +@@ -52,7 +52,7 @@ static int its_fsl_mc_msi_prepare(struct return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info); } @@ -8414,7 +8407,7 @@ Signed-off-by: Yangbo Lu .msi_prepare = its_fsl_mc_msi_prepare, }; -@@ -94,8 +95,8 @@ int __init its_fsl_mc_msi_init(void) +@@ -95,8 +95,8 @@ int __init its_fsl_mc_msi_init(void) continue; } diff --git a/target/linux/layerscape/patches-4.9/706-fsl-dpaa-use-4-9-ndo-get-stats64.patch b/target/linux/layerscape/patches-4.9/706-fsl-dpaa-use-4-9-ndo-get-stats64.patch new file mode 100644 index 000000000..4fa29b290 --- /dev/null +++ b/target/linux/layerscape/patches-4.9/706-fsl-dpaa-use-4-9-ndo-get-stats64.patch @@ -0,0 +1,112 @@ +From: Mathew McBride +Date: Tue, 24 Oct 2017 11:30:00 +1100 +Subject: [PATCH] dpaa: backport use of 4.9 ndo_get_stats64 + +This patch changes the declarations of ndo_get_stats64 handlers +to the previous struct rtnl_link_stats64 * return type instead of +the mainline void return. + +Suggested-by: Adrien Gallouët +Signed-off-by: Mathew McBride + +--- + drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 5 +++-- + drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h | 4 ++-- + drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 3 ++- + drivers/staging/fsl-dpaa2/ethsw/switch.c | 4 ++-- + drivers/staging/fsl-dpaa2/evb/evb.c | 4 ++-- + 5 files changed, 11 insertions(+), 9 deletions(-) + +--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c ++++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c +@@ -1296,7 +1296,7 @@ static int dpaa2_eth_set_addr(struct net + /** Fill in counters maintained by the GPP driver. These may be different from + * the hardware counters obtained by ethtool. + */ +-static void dpaa2_eth_get_stats(struct net_device *net_dev, ++static struct rtnl_link_stats64 *dpaa2_eth_get_stats(struct net_device *net_dev, + struct rtnl_link_stats64 *stats) + { + struct dpaa2_eth_priv *priv = netdev_priv(net_dev); +@@ -1312,6 +1312,7 @@ static void dpaa2_eth_get_stats(struct n + for (j = 0; j < num; j++) + netstats[j] += cpustats[j]; + } ++ return stats; + } + + static int dpaa2_eth_change_mtu(struct net_device *net_dev, int mtu) +--- a/drivers/staging/fsl-dpaa2/ethsw/switch.c ++++ b/drivers/staging/fsl-dpaa2/ethsw/switch.c +@@ -1094,7 +1094,7 @@ static int ethsw_port_fdb_del(struct ndm + return 0; + } + +-void ethsw_port_get_stats(struct net_device *netdev, ++struct rtnl_link_stats64 *ethsw_port_get_stats(struct net_device *netdev, + struct rtnl_link_stats64 *storage) + { + struct ethsw_port_priv *port_priv = netdev_priv(netdev); +@@ -1154,7 +1154,7 @@ void ethsw_port_get_stats(struct net_dev + if (err) + goto error; + +- return; ++ return storage; + + error: + netdev_err(netdev, "dpsw_if_get_counter err %d\n", err); +--- a/drivers/staging/fsl-dpaa2/evb/evb.c ++++ b/drivers/staging/fsl-dpaa2/evb/evb.c +@@ -765,7 +765,7 @@ static int evb_dellink(struct net_device + return 0; + } + +-void evb_port_get_stats(struct net_device *netdev, ++struct rtnl_link_stats64 *evb_port_get_stats(struct net_device *netdev, + struct rtnl_link_stats64 *storage) + { + struct evb_port_priv *port_priv = netdev_priv(netdev); +@@ -842,7 +842,7 @@ void evb_port_get_stats(struct net_devic + if (unlikely(err)) + goto error; + +- return; ++ return storage; + + error: + netdev_err(netdev, "dpdmux_if_get_counter err %d\n", err); +--- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c ++++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c +@@ -239,8 +239,8 @@ EXPORT_SYMBOL(dpa_timeout); + * Calculates the statistics for the given device by adding the statistics + * collected by each CPU. + */ +-void __cold +-dpa_get_stats64(struct net_device *net_dev, ++struct rtnl_link_stats64 __cold ++*dpa_get_stats64(struct net_device *net_dev, + struct rtnl_link_stats64 *stats) + { + struct dpa_priv_s *priv = netdev_priv(net_dev); +@@ -258,6 +258,7 @@ dpa_get_stats64(struct net_device *net_d + for (j = 0; j < numstats; j++) + netstats[j] += cpustats[j]; + } ++ return stats; + } + EXPORT_SYMBOL(dpa_get_stats64); + +--- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h ++++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h +@@ -140,8 +140,8 @@ int dpa_netdev_init(struct net_device *n + int __cold dpa_start(struct net_device *net_dev); + int __cold dpa_stop(struct net_device *net_dev); + void __cold dpa_timeout(struct net_device *net_dev); +-void __cold +-dpa_get_stats64(struct net_device *net_dev, ++struct rtnl_link_stats64 __cold ++*dpa_get_stats64(struct net_device *net_dev, + struct rtnl_link_stats64 *stats); + int dpa_change_mtu(struct net_device *net_dev, int new_mtu); + int dpa_ndo_init(struct net_device *net_dev); diff --git a/target/linux/layerscape/patches-4.9/706-fsl_ppfe-support-layercape.patch b/target/linux/layerscape/patches-4.9/706-fsl_ppfe-support-layercape.patch new file mode 100644 index 000000000..4104272ef --- /dev/null +++ b/target/linux/layerscape/patches-4.9/706-fsl_ppfe-support-layercape.patch @@ -0,0 +1,10548 @@ +From 8b7935a883d42187716fe486c83352f24d01ddcd Mon Sep 17 00:00:00 2001 +From: Yangbo Lu +Date: Thu, 19 Oct 2017 12:48:19 +0800 +Subject: [PATCH] fsl_ppfe: support layercape + +This is a integrated patch for layerscape pfe support. + +Calvin Johnson +Signed-off-by: Yangbo Lu +--- + drivers/staging/fsl_ppfe/Kconfig | 20 + + drivers/staging/fsl_ppfe/Makefile | 19 + + drivers/staging/fsl_ppfe/TODO | 2 + + drivers/staging/fsl_ppfe/include/pfe/cbus.h | 78 + + drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h | 55 + + .../staging/fsl_ppfe/include/pfe/cbus/class_csr.h | 289 +++ + .../staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h | 242 ++ + drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h | 86 + + drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h | 100 + + .../staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h | 50 + + .../staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h | 168 ++ + .../staging/fsl_ppfe/include/pfe/cbus/util_csr.h | 61 + + drivers/staging/fsl_ppfe/include/pfe/pfe.h | 372 +++ + drivers/staging/fsl_ppfe/pfe_ctrl.c | 238 ++ + drivers/staging/fsl_ppfe/pfe_ctrl.h | 112 + + drivers/staging/fsl_ppfe/pfe_debugfs.c | 111 + + drivers/staging/fsl_ppfe/pfe_debugfs.h | 25 + + drivers/staging/fsl_ppfe/pfe_eth.c | 2434 ++++++++++++++++++++ + drivers/staging/fsl_ppfe/pfe_eth.h | 184 ++ + drivers/staging/fsl_ppfe/pfe_firmware.c | 314 +++ + drivers/staging/fsl_ppfe/pfe_firmware.h | 32 + + drivers/staging/fsl_ppfe/pfe_hal.c | 1516 ++++++++++++ + drivers/staging/fsl_ppfe/pfe_hif.c | 1072 +++++++++ + drivers/staging/fsl_ppfe/pfe_hif.h | 211 ++ + drivers/staging/fsl_ppfe/pfe_hif_lib.c | 601 +++++ + drivers/staging/fsl_ppfe/pfe_hif_lib.h | 239 ++ + drivers/staging/fsl_ppfe/pfe_hw.c | 176 ++ + drivers/staging/fsl_ppfe/pfe_hw.h | 27 + + drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c | 394 ++++ + drivers/staging/fsl_ppfe/pfe_mod.c | 141 ++ + drivers/staging/fsl_ppfe/pfe_mod.h | 112 + + drivers/staging/fsl_ppfe/pfe_perfmon.h | 38 + + drivers/staging/fsl_ppfe/pfe_sysfs.c | 818 +++++++ + drivers/staging/fsl_ppfe/pfe_sysfs.h | 29 + + 34 files changed, 10366 insertions(+) + create mode 100644 drivers/staging/fsl_ppfe/Kconfig + create mode 100644 drivers/staging/fsl_ppfe/Makefile + create mode 100644 drivers/staging/fsl_ppfe/TODO + create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus.h + create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h + create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/class_csr.h + create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h + create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h + create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h + create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h + create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h + create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/util_csr.h + create mode 100644 drivers/staging/fsl_ppfe/include/pfe/pfe.h + create mode 100644 drivers/staging/fsl_ppfe/pfe_ctrl.c + create mode 100644 drivers/staging/fsl_ppfe/pfe_ctrl.h + create mode 100644 drivers/staging/fsl_ppfe/pfe_debugfs.c + create mode 100644 drivers/staging/fsl_ppfe/pfe_debugfs.h + create mode 100644 drivers/staging/fsl_ppfe/pfe_eth.c + create mode 100644 drivers/staging/fsl_ppfe/pfe_eth.h + create mode 100644 drivers/staging/fsl_ppfe/pfe_firmware.c + create mode 100644 drivers/staging/fsl_ppfe/pfe_firmware.h + create mode 100644 drivers/staging/fsl_ppfe/pfe_hal.c + create mode 100644 drivers/staging/fsl_ppfe/pfe_hif.c + create mode 100644 drivers/staging/fsl_ppfe/pfe_hif.h + create mode 100644 drivers/staging/fsl_ppfe/pfe_hif_lib.c + create mode 100644 drivers/staging/fsl_ppfe/pfe_hif_lib.h + create mode 100644 drivers/staging/fsl_ppfe/pfe_hw.c + create mode 100644 drivers/staging/fsl_ppfe/pfe_hw.h + create mode 100644 drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c + create mode 100644 drivers/staging/fsl_ppfe/pfe_mod.c + create mode 100644 drivers/staging/fsl_ppfe/pfe_mod.h + create mode 100644 drivers/staging/fsl_ppfe/pfe_perfmon.h + create mode 100644 drivers/staging/fsl_ppfe/pfe_sysfs.c + create mode 100644 drivers/staging/fsl_ppfe/pfe_sysfs.h + +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/Kconfig +@@ -0,0 +1,20 @@ ++# ++# Freescale Programmable Packet Forwarding Engine driver ++# ++config FSL_PPFE ++ bool "Freescale PPFE Driver" ++ default n ++ ---help--- ++ Freescale LS1012A SoC has a Programmable Packet Forwarding Engine. ++ It provides two high performance ethernet interfaces. ++ This driver initializes, programs and controls the PPFE. ++ Use this driver to enable network connectivity on LS1012A platforms. ++ ++if FSL_PPFE ++ ++config FSL_PPFE_UTIL_DISABLED ++ bool "Disable PPFE UTIL Processor Engine" ++ ---help--- ++ UTIL PE has to be enabled only if required. ++ ++endif # FSL_PPFE +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/Makefile +@@ -0,0 +1,19 @@ ++# ++# Makefile for Freesecale PPFE driver ++# ++ ++ccflags-y += -I$(src)/include -I$(src) ++ ++obj-m += pfe.o ++ ++pfe-y += pfe_mod.o \ ++ pfe_hw.o \ ++ pfe_firmware.o \ ++ pfe_ctrl.o \ ++ pfe_hif.o \ ++ pfe_hif_lib.o\ ++ pfe_eth.o \ ++ pfe_sysfs.o \ ++ pfe_debugfs.o \ ++ pfe_ls1012a_platform.o \ ++ pfe_hal.o +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/TODO +@@ -0,0 +1,2 @@ ++TODO: ++ - provide pfe pe monitoring support +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/include/pfe/cbus.h +@@ -0,0 +1,78 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _CBUS_H_ ++#define _CBUS_H_ ++ ++#define EMAC1_BASE_ADDR (CBUS_BASE_ADDR + 0x200000) ++#define EGPI1_BASE_ADDR (CBUS_BASE_ADDR + 0x210000) ++#define EMAC2_BASE_ADDR (CBUS_BASE_ADDR + 0x220000) ++#define EGPI2_BASE_ADDR (CBUS_BASE_ADDR + 0x230000) ++#define BMU1_BASE_ADDR (CBUS_BASE_ADDR + 0x240000) ++#define BMU2_BASE_ADDR (CBUS_BASE_ADDR + 0x250000) ++#define ARB_BASE_ADDR (CBUS_BASE_ADDR + 0x260000) ++#define DDR_CONFIG_BASE_ADDR (CBUS_BASE_ADDR + 0x270000) ++#define HIF_BASE_ADDR (CBUS_BASE_ADDR + 0x280000) ++#define HGPI_BASE_ADDR (CBUS_BASE_ADDR + 0x290000) ++#define LMEM_BASE_ADDR (CBUS_BASE_ADDR + 0x300000) ++#define LMEM_SIZE 0x10000 ++#define LMEM_END (LMEM_BASE_ADDR + LMEM_SIZE) ++#define TMU_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x310000) ++#define CLASS_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x320000) ++#define HIF_NOCPY_BASE_ADDR (CBUS_BASE_ADDR + 0x350000) ++#define UTIL_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x360000) ++#define CBUS_GPT_BASE_ADDR (CBUS_BASE_ADDR + 0x370000) ++ ++/* ++ * defgroup XXX_MEM_ACCESS_ADDR PE memory access through CSR ++ * XXX_MEM_ACCESS_ADDR register bit definitions. ++ */ ++#define PE_MEM_ACCESS_WRITE BIT(31) /* Internal Memory Write. */ ++#define PE_MEM_ACCESS_IMEM BIT(15) ++#define PE_MEM_ACCESS_DMEM BIT(16) ++ ++/* Byte Enables of the Internal memory access. These are interpred in BE */ ++#define PE_MEM_ACCESS_BYTE_ENABLE(offset, size) \ ++ ({ typeof(size) size_ = (size); \ ++ (((BIT(size_) - 1) << (4 - (offset) - (size_))) & 0xf) << 24; }) ++ ++#include "cbus/emac_mtip.h" ++#include "cbus/gpi.h" ++#include "cbus/bmu.h" ++#include "cbus/hif.h" ++#include "cbus/tmu_csr.h" ++#include "cbus/class_csr.h" ++#include "cbus/hif_nocpy.h" ++#include "cbus/util_csr.h" ++ ++/* PFE cores states */ ++#define CORE_DISABLE 0x00000000 ++#define CORE_ENABLE 0x00000001 ++#define CORE_SW_RESET 0x00000002 ++ ++/* LMEM defines */ ++#define LMEM_HDR_SIZE 0x0010 ++#define LMEM_BUF_SIZE_LN2 0x7 ++#define LMEM_BUF_SIZE BIT(LMEM_BUF_SIZE_LN2) ++ ++/* DDR defines */ ++#define DDR_HDR_SIZE 0x0100 ++#define DDR_BUF_SIZE_LN2 0xb ++#define DDR_BUF_SIZE BIT(DDR_BUF_SIZE_LN2) ++ ++#endif /* _CBUS_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _BMU_H_ ++#define _BMU_H_ ++ ++#define BMU_VERSION 0x000 ++#define BMU_CTRL 0x004 ++#define BMU_UCAST_CONFIG 0x008 ++#define BMU_UCAST_BASE_ADDR 0x00c ++#define BMU_BUF_SIZE 0x010 ++#define BMU_BUF_CNT 0x014 ++#define BMU_THRES 0x018 ++#define BMU_INT_SRC 0x020 ++#define BMU_INT_ENABLE 0x024 ++#define BMU_ALLOC_CTRL 0x030 ++#define BMU_FREE_CTRL 0x034 ++#define BMU_FREE_ERR_ADDR 0x038 ++#define BMU_CURR_BUF_CNT 0x03c ++#define BMU_MCAST_CNT 0x040 ++#define BMU_MCAST_ALLOC_CTRL 0x044 ++#define BMU_REM_BUF_CNT 0x048 ++#define BMU_LOW_WATERMARK 0x050 ++#define BMU_HIGH_WATERMARK 0x054 ++#define BMU_INT_MEM_ACCESS 0x100 ++ ++struct BMU_CFG { ++ unsigned long baseaddr; ++ u32 count; ++ u32 size; ++ u32 low_watermark; ++ u32 high_watermark; ++}; ++ ++#define BMU1_BUF_SIZE LMEM_BUF_SIZE_LN2 ++#define BMU2_BUF_SIZE DDR_BUF_SIZE_LN2 ++ ++#define BMU2_MCAST_ALLOC_CTRL (BMU2_BASE_ADDR + BMU_MCAST_ALLOC_CTRL) ++ ++#endif /* _BMU_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/class_csr.h +@@ -0,0 +1,289 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _CLASS_CSR_H_ ++#define _CLASS_CSR_H_ ++ ++/* @file class_csr.h. ++ * class_csr - block containing all the classifier control and status register. ++ * Mapped on CBUS and accessible from all PE's and ARM. ++ */ ++#define CLASS_VERSION (CLASS_CSR_BASE_ADDR + 0x000) ++#define CLASS_TX_CTRL (CLASS_CSR_BASE_ADDR + 0x004) ++#define CLASS_INQ_PKTPTR (CLASS_CSR_BASE_ADDR + 0x010) ++ ++/* (ddr_hdr_size[24:16], lmem_hdr_size[5:0]) */ ++#define CLASS_HDR_SIZE (CLASS_CSR_BASE_ADDR + 0x014) ++ ++/* LMEM header size for the Classifier block.\ Data in the LMEM ++ * is written from this offset. ++ */ ++#define CLASS_HDR_SIZE_LMEM(off) ((off) & 0x3f) ++ ++/* DDR header size for the Classifier block.\ Data in the DDR ++ * is written from this offset. ++ */ ++#define CLASS_HDR_SIZE_DDR(off) (((off) & 0x1ff) << 16) ++ ++#define CLASS_PE0_QB_DM_ADDR0 (CLASS_CSR_BASE_ADDR + 0x020) ++ ++/* DMEM address of first [15:0] and second [31:16] buffers on QB side. */ ++#define CLASS_PE0_QB_DM_ADDR1 (CLASS_CSR_BASE_ADDR + 0x024) ++ ++/* DMEM address of third [15:0] and fourth [31:16] buffers on QB side. */ ++#define CLASS_PE0_RO_DM_ADDR0 (CLASS_CSR_BASE_ADDR + 0x060) ++ ++/* DMEM address of first [15:0] and second [31:16] buffers on RO side. */ ++#define CLASS_PE0_RO_DM_ADDR1 (CLASS_CSR_BASE_ADDR + 0x064) ++ ++/* DMEM address of third [15:0] and fourth [31:16] buffers on RO side. */ ++ ++/* @name Class PE memory access. Allows external PE's and HOST to ++ * read/write PMEM/DMEM memory ranges for each classifier PE. ++ */ ++/* {sr_pe_mem_cmd[31], csr_pe_mem_wren[27:24], csr_pe_mem_addr[23:0]}, ++ * See \ref XXX_MEM_ACCESS_ADDR for details. ++ */ ++#define CLASS_MEM_ACCESS_ADDR (CLASS_CSR_BASE_ADDR + 0x100) ++ ++/* Internal Memory Access Write Data [31:0] */ ++#define CLASS_MEM_ACCESS_WDATA (CLASS_CSR_BASE_ADDR + 0x104) ++ ++/* Internal Memory Access Read Data [31:0] */ ++#define CLASS_MEM_ACCESS_RDATA (CLASS_CSR_BASE_ADDR + 0x108) ++#define CLASS_TM_INQ_ADDR (CLASS_CSR_BASE_ADDR + 0x114) ++#define CLASS_PE_STATUS (CLASS_CSR_BASE_ADDR + 0x118) ++ ++#define CLASS_PHY1_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x11c) ++#define CLASS_PHY1_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x120) ++#define CLASS_PHY1_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x124) ++#define CLASS_PHY1_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x128) ++#define CLASS_PHY1_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x12c) ++#define CLASS_PHY1_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x130) ++#define CLASS_PHY1_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x134) ++#define CLASS_PHY1_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x138) ++#define CLASS_PHY1_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x13c) ++#define CLASS_PHY1_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x140) ++#define CLASS_PHY2_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x144) ++#define CLASS_PHY2_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x148) ++#define CLASS_PHY2_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x14c) ++#define CLASS_PHY2_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x150) ++#define CLASS_PHY2_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x154) ++#define CLASS_PHY2_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x158) ++#define CLASS_PHY2_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x15c) ++#define CLASS_PHY2_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x160) ++#define CLASS_PHY2_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x164) ++#define CLASS_PHY2_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x168) ++#define CLASS_PHY3_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x16c) ++#define CLASS_PHY3_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x170) ++#define CLASS_PHY3_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x174) ++#define CLASS_PHY3_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x178) ++#define CLASS_PHY3_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x17c) ++#define CLASS_PHY3_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x180) ++#define CLASS_PHY3_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x184) ++#define CLASS_PHY3_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x188) ++#define CLASS_PHY3_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x18c) ++#define CLASS_PHY3_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x190) ++#define CLASS_PHY1_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x194) ++#define CLASS_PHY1_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x198) ++#define CLASS_PHY1_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x19c) ++#define CLASS_PHY1_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a0) ++#define CLASS_PHY2_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a4) ++#define CLASS_PHY2_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a8) ++#define CLASS_PHY2_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1ac) ++#define CLASS_PHY2_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b0) ++#define CLASS_PHY3_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b4) ++#define CLASS_PHY3_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b8) ++#define CLASS_PHY3_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1bc) ++#define CLASS_PHY3_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c0) ++#define CLASS_PHY4_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c4) ++#define CLASS_PHY4_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c8) ++#define CLASS_PHY4_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1cc) ++#define CLASS_PHY4_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1d0) ++#define CLASS_PHY4_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x1d4) ++#define CLASS_PHY4_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x1d8) ++#define CLASS_PHY4_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1dc) ++#define CLASS_PHY4_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1e0) ++#define CLASS_PHY4_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x1e4) ++#define CLASS_PHY4_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1e8) ++#define CLASS_PHY4_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x1ec) ++#define CLASS_PHY4_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x1f0) ++#define CLASS_PHY4_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x1f4) ++#define CLASS_PHY4_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x1f8) ++ ++#define CLASS_PE_SYS_CLK_RATIO (CLASS_CSR_BASE_ADDR + 0x200) ++#define CLASS_AFULL_THRES (CLASS_CSR_BASE_ADDR + 0x204) ++#define CLASS_GAP_BETWEEN_READS (CLASS_CSR_BASE_ADDR + 0x208) ++#define CLASS_MAX_BUF_CNT (CLASS_CSR_BASE_ADDR + 0x20c) ++#define CLASS_TSQ_FIFO_THRES (CLASS_CSR_BASE_ADDR + 0x210) ++#define CLASS_TSQ_MAX_CNT (CLASS_CSR_BASE_ADDR + 0x214) ++#define CLASS_IRAM_DATA_0 (CLASS_CSR_BASE_ADDR + 0x218) ++#define CLASS_IRAM_DATA_1 (CLASS_CSR_BASE_ADDR + 0x21c) ++#define CLASS_IRAM_DATA_2 (CLASS_CSR_BASE_ADDR + 0x220) ++#define CLASS_IRAM_DATA_3 (CLASS_CSR_BASE_ADDR + 0x224) ++ ++#define CLASS_BUS_ACCESS_ADDR (CLASS_CSR_BASE_ADDR + 0x228) ++ ++#define CLASS_BUS_ACCESS_WDATA (CLASS_CSR_BASE_ADDR + 0x22c) ++#define CLASS_BUS_ACCESS_RDATA (CLASS_CSR_BASE_ADDR + 0x230) ++ ++/* (route_entry_size[9:0], route_hash_size[23:16] ++ * (this is actually ln2(size))) ++ */ ++#define CLASS_ROUTE_HASH_ENTRY_SIZE (CLASS_CSR_BASE_ADDR + 0x234) ++ ++#define CLASS_ROUTE_ENTRY_SIZE(size) ((size) & 0x1ff) ++#define CLASS_ROUTE_HASH_SIZE(hash_bits) (((hash_bits) & 0xff) << 16) ++ ++#define CLASS_ROUTE_TABLE_BASE (CLASS_CSR_BASE_ADDR + 0x238) ++ ++#define CLASS_ROUTE_MULTI (CLASS_CSR_BASE_ADDR + 0x23c) ++#define CLASS_SMEM_OFFSET (CLASS_CSR_BASE_ADDR + 0x240) ++#define CLASS_LMEM_BUF_SIZE (CLASS_CSR_BASE_ADDR + 0x244) ++#define CLASS_VLAN_ID (CLASS_CSR_BASE_ADDR + 0x248) ++#define CLASS_BMU1_BUF_FREE (CLASS_CSR_BASE_ADDR + 0x24c) ++#define CLASS_USE_TMU_INQ (CLASS_CSR_BASE_ADDR + 0x250) ++#define CLASS_VLAN_ID1 (CLASS_CSR_BASE_ADDR + 0x254) ++ ++#define CLASS_BUS_ACCESS_BASE (CLASS_CSR_BASE_ADDR + 0x258) ++#define CLASS_BUS_ACCESS_BASE_MASK (0xFF000000) ++/* bit 31:24 of PE peripheral address are stored in CLASS_BUS_ACCESS_BASE */ ++ ++#define CLASS_HIF_PARSE (CLASS_CSR_BASE_ADDR + 0x25c) ++ ++#define CLASS_HOST_PE0_GP (CLASS_CSR_BASE_ADDR + 0x260) ++#define CLASS_PE0_GP (CLASS_CSR_BASE_ADDR + 0x264) ++#define CLASS_HOST_PE1_GP (CLASS_CSR_BASE_ADDR + 0x268) ++#define CLASS_PE1_GP (CLASS_CSR_BASE_ADDR + 0x26c) ++#define CLASS_HOST_PE2_GP (CLASS_CSR_BASE_ADDR + 0x270) ++#define CLASS_PE2_GP (CLASS_CSR_BASE_ADDR + 0x274) ++#define CLASS_HOST_PE3_GP (CLASS_CSR_BASE_ADDR + 0x278) ++#define CLASS_PE3_GP (CLASS_CSR_BASE_ADDR + 0x27c) ++#define CLASS_HOST_PE4_GP (CLASS_CSR_BASE_ADDR + 0x280) ++#define CLASS_PE4_GP (CLASS_CSR_BASE_ADDR + 0x284) ++#define CLASS_HOST_PE5_GP (CLASS_CSR_BASE_ADDR + 0x288) ++#define CLASS_PE5_GP (CLASS_CSR_BASE_ADDR + 0x28c) ++ ++#define CLASS_PE_INT_SRC (CLASS_CSR_BASE_ADDR + 0x290) ++#define CLASS_PE_INT_ENABLE (CLASS_CSR_BASE_ADDR + 0x294) ++ ++#define CLASS_TPID0_TPID1 (CLASS_CSR_BASE_ADDR + 0x298) ++#define CLASS_TPID2 (CLASS_CSR_BASE_ADDR + 0x29c) ++ ++#define CLASS_L4_CHKSUM_ADDR (CLASS_CSR_BASE_ADDR + 0x2a0) ++ ++#define CLASS_PE0_DEBUG (CLASS_CSR_BASE_ADDR + 0x2a4) ++#define CLASS_PE1_DEBUG (CLASS_CSR_BASE_ADDR + 0x2a8) ++#define CLASS_PE2_DEBUG (CLASS_CSR_BASE_ADDR + 0x2ac) ++#define CLASS_PE3_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b0) ++#define CLASS_PE4_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b4) ++#define CLASS_PE5_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b8) ++ ++#define CLASS_STATE (CLASS_CSR_BASE_ADDR + 0x2bc) ++ ++/* CLASS defines */ ++#define CLASS_PBUF_SIZE 0x100 /* Fixed by hardware */ ++#define CLASS_PBUF_HEADER_OFFSET 0x80 /* Can be configured */ ++ ++/* Can be configured */ ++#define CLASS_PBUF0_BASE_ADDR 0x000 ++/* Can be configured */ ++#define CLASS_PBUF1_BASE_ADDR (CLASS_PBUF0_BASE_ADDR + CLASS_PBUF_SIZE) ++/* Can be configured */ ++#define CLASS_PBUF2_BASE_ADDR (CLASS_PBUF1_BASE_ADDR + CLASS_PBUF_SIZE) ++/* Can be configured */ ++#define CLASS_PBUF3_BASE_ADDR (CLASS_PBUF2_BASE_ADDR + CLASS_PBUF_SIZE) ++ ++#define CLASS_PBUF0_HEADER_BASE_ADDR (CLASS_PBUF0_BASE_ADDR + \ ++ CLASS_PBUF_HEADER_OFFSET) ++#define CLASS_PBUF1_HEADER_BASE_ADDR (CLASS_PBUF1_BASE_ADDR + \ ++ CLASS_PBUF_HEADER_OFFSET) ++#define CLASS_PBUF2_HEADER_BASE_ADDR (CLASS_PBUF2_BASE_ADDR + \ ++ CLASS_PBUF_HEADER_OFFSET) ++#define CLASS_PBUF3_HEADER_BASE_ADDR (CLASS_PBUF3_BASE_ADDR + \ ++ CLASS_PBUF_HEADER_OFFSET) ++ ++#define CLASS_PE0_RO_DM_ADDR0_VAL ((CLASS_PBUF1_BASE_ADDR << 16) | \ ++ CLASS_PBUF0_BASE_ADDR) ++#define CLASS_PE0_RO_DM_ADDR1_VAL ((CLASS_PBUF3_BASE_ADDR << 16) | \ ++ CLASS_PBUF2_BASE_ADDR) ++ ++#define CLASS_PE0_QB_DM_ADDR0_VAL ((CLASS_PBUF1_HEADER_BASE_ADDR << 16) |\ ++ CLASS_PBUF0_HEADER_BASE_ADDR) ++#define CLASS_PE0_QB_DM_ADDR1_VAL ((CLASS_PBUF3_HEADER_BASE_ADDR << 16) |\ ++ CLASS_PBUF2_HEADER_BASE_ADDR) ++ ++#define CLASS_ROUTE_SIZE 128 ++#define CLASS_MAX_ROUTE_SIZE 256 ++#define CLASS_ROUTE_HASH_BITS 20 ++#define CLASS_ROUTE_HASH_MASK (BIT(CLASS_ROUTE_HASH_BITS) - 1) ++ ++/* Can be configured */ ++#define CLASS_ROUTE0_BASE_ADDR 0x400 ++/* Can be configured */ ++#define CLASS_ROUTE1_BASE_ADDR (CLASS_ROUTE0_BASE_ADDR + CLASS_ROUTE_SIZE) ++/* Can be configured */ ++#define CLASS_ROUTE2_BASE_ADDR (CLASS_ROUTE1_BASE_ADDR + CLASS_ROUTE_SIZE) ++/* Can be configured */ ++#define CLASS_ROUTE3_BASE_ADDR (CLASS_ROUTE2_BASE_ADDR + CLASS_ROUTE_SIZE) ++ ++#define CLASS_SA_SIZE 128 ++#define CLASS_IPSEC_SA0_BASE_ADDR 0x600 ++/* not used */ ++#define CLASS_IPSEC_SA1_BASE_ADDR (CLASS_IPSEC_SA0_BASE_ADDR + CLASS_SA_SIZE) ++/* not used */ ++#define CLASS_IPSEC_SA2_BASE_ADDR (CLASS_IPSEC_SA1_BASE_ADDR + CLASS_SA_SIZE) ++/* not used */ ++#define CLASS_IPSEC_SA3_BASE_ADDR (CLASS_IPSEC_SA2_BASE_ADDR + CLASS_SA_SIZE) ++ ++/* generic purpose free dmem buffer, last portion of 2K dmem pbuf */ ++#define CLASS_GP_DMEM_BUF_SIZE (2048 - (CLASS_PBUF_SIZE * 4) - \ ++ (CLASS_ROUTE_SIZE * 4) - (CLASS_SA_SIZE)) ++#define CLASS_GP_DMEM_BUF ((void *)(CLASS_IPSEC_SA0_BASE_ADDR + \ ++ CLASS_SA_SIZE)) ++ ++#define TWO_LEVEL_ROUTE BIT(0) ++#define PHYNO_IN_HASH BIT(1) ++#define HW_ROUTE_FETCH BIT(3) ++#define HW_BRIDGE_FETCH BIT(5) ++#define IP_ALIGNED BIT(6) ++#define ARC_HIT_CHECK_EN BIT(7) ++#define CLASS_TOE BIT(11) ++#define HASH_NORMAL (0 << 12) ++#define HASH_CRC_PORT BIT(12) ++#define HASH_CRC_IP (2 << 12) ++#define HASH_CRC_PORT_IP (3 << 12) ++#define QB2BUS_LE BIT(15) ++ ++#define TCP_CHKSUM_DROP BIT(0) ++#define UDP_CHKSUM_DROP BIT(1) ++#define IPV4_CHKSUM_DROP BIT(9) ++ ++/*CLASS_HIF_PARSE bits*/ ++#define HIF_PKT_CLASS_EN BIT(0) ++#define HIF_PKT_OFFSET(ofst) (((ofst) & 0xF) << 1) ++ ++struct class_cfg { ++ u32 toe_mode; ++ unsigned long route_table_baseaddr; ++ u32 route_table_hash_bits; ++ u32 pe_sys_clk_ratio; ++ u32 resume; ++}; ++ ++#endif /* _CLASS_CSR_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h +@@ -0,0 +1,242 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _EMAC_H_ ++#define _EMAC_H_ ++ ++#include ++ ++#define EMAC_IEVENT_REG 0x004 ++#define EMAC_IMASK_REG 0x008 ++#define EMAC_R_DES_ACTIVE_REG 0x010 ++#define EMAC_X_DES_ACTIVE_REG 0x014 ++#define EMAC_ECNTRL_REG 0x024 ++#define EMAC_MII_DATA_REG 0x040 ++#define EMAC_MII_CTRL_REG 0x044 ++#define EMAC_MIB_CTRL_STS_REG 0x064 ++#define EMAC_RCNTRL_REG 0x084 ++#define EMAC_TCNTRL_REG 0x0C4 ++#define EMAC_PHY_ADDR_LOW 0x0E4 ++#define EMAC_PHY_ADDR_HIGH 0x0E8 ++#define EMAC_GAUR 0x120 ++#define EMAC_GALR 0x124 ++#define EMAC_TFWR_STR_FWD 0x144 ++#define EMAC_RX_SECTION_FULL 0x190 ++#define EMAC_RX_SECTION_EMPTY 0x194 ++#define EMAC_TX_SECTION_EMPTY 0x1A0 ++#define EMAC_TRUNC_FL 0x1B0 ++ ++#define RMON_T_DROP 0x200 /* Count of frames not cntd correctly */ ++#define RMON_T_PACKETS 0x204 /* RMON TX packet count */ ++#define RMON_T_BC_PKT 0x208 /* RMON TX broadcast pkts */ ++#define RMON_T_MC_PKT 0x20c /* RMON TX multicast pkts */ ++#define RMON_T_CRC_ALIGN 0x210 /* RMON TX pkts with CRC align err */ ++#define RMON_T_UNDERSIZE 0x214 /* RMON TX pkts < 64 bytes, good CRC */ ++#define RMON_T_OVERSIZE 0x218 /* RMON TX pkts > MAX_FL bytes good CRC */ ++#define RMON_T_FRAG 0x21c /* RMON TX pkts < 64 bytes, bad CRC */ ++#define RMON_T_JAB 0x220 /* RMON TX pkts > MAX_FL bytes, bad CRC */ ++#define RMON_T_COL 0x224 /* RMON TX collision count */ ++#define RMON_T_P64 0x228 /* RMON TX 64 byte pkts */ ++#define RMON_T_P65TO127 0x22c /* RMON TX 65 to 127 byte pkts */ ++#define RMON_T_P128TO255 0x230 /* RMON TX 128 to 255 byte pkts */ ++#define RMON_T_P256TO511 0x234 /* RMON TX 256 to 511 byte pkts */ ++#define RMON_T_P512TO1023 0x238 /* RMON TX 512 to 1023 byte pkts */ ++#define RMON_T_P1024TO2047 0x23c /* RMON TX 1024 to 2047 byte pkts */ ++#define RMON_T_P_GTE2048 0x240 /* RMON TX pkts > 2048 bytes */ ++#define RMON_T_OCTETS 0x244 /* RMON TX octets */ ++#define IEEE_T_DROP 0x248 /* Count of frames not counted crtly */ ++#define IEEE_T_FRAME_OK 0x24c /* Frames tx'd OK */ ++#define IEEE_T_1COL 0x250 /* Frames tx'd with single collision */ ++#define IEEE_T_MCOL 0x254 /* Frames tx'd with multiple collision */ ++#define IEEE_T_DEF 0x258 /* Frames tx'd after deferral delay */ ++#define IEEE_T_LCOL 0x25c /* Frames tx'd with late collision */ ++#define IEEE_T_EXCOL 0x260 /* Frames tx'd with excesv collisions */ ++#define IEEE_T_MACERR 0x264 /* Frames tx'd with TX FIFO underrun */ ++#define IEEE_T_CSERR 0x268 /* Frames tx'd with carrier sense err */ ++#define IEEE_T_SQE 0x26c /* Frames tx'd with SQE err */ ++#define IEEE_T_FDXFC 0x270 /* Flow control pause frames tx'd */ ++#define IEEE_T_OCTETS_OK 0x274 /* Octet count for frames tx'd w/o err */ ++#define RMON_R_PACKETS 0x284 /* RMON RX packet count */ ++#define RMON_R_BC_PKT 0x288 /* RMON RX broadcast pkts */ ++#define RMON_R_MC_PKT 0x28c /* RMON RX multicast pkts */ ++#define RMON_R_CRC_ALIGN 0x290 /* RMON RX pkts with CRC alignment err */ ++#define RMON_R_UNDERSIZE 0x294 /* RMON RX pkts < 64 bytes, good CRC */ ++#define RMON_R_OVERSIZE 0x298 /* RMON RX pkts > MAX_FL bytes good CRC */ ++#define RMON_R_FRAG 0x29c /* RMON RX pkts < 64 bytes, bad CRC */ ++#define RMON_R_JAB 0x2a0 /* RMON RX pkts > MAX_FL bytes, bad CRC */ ++#define RMON_R_RESVD_O 0x2a4 /* Reserved */ ++#define RMON_R_P64 0x2a8 /* RMON RX 64 byte pkts */ ++#define RMON_R_P65TO127 0x2ac /* RMON RX 65 to 127 byte pkts */ ++#define RMON_R_P128TO255 0x2b0 /* RMON RX 128 to 255 byte pkts */ ++#define RMON_R_P256TO511 0x2b4 /* RMON RX 256 to 511 byte pkts */ ++#define RMON_R_P512TO1023 0x2b8 /* RMON RX 512 to 1023 byte pkts */ ++#define RMON_R_P1024TO2047 0x2bc /* RMON RX 1024 to 2047 byte pkts */ ++#define RMON_R_P_GTE2048 0x2c0 /* RMON RX pkts > 2048 bytes */ ++#define RMON_R_OCTETS 0x2c4 /* RMON RX octets */ ++#define IEEE_R_DROP 0x2c8 /* Count frames not counted correctly */ ++#define IEEE_R_FRAME_OK 0x2cc /* Frames rx'd OK */ ++#define IEEE_R_CRC 0x2d0 /* Frames rx'd with CRC err */ ++#define IEEE_R_ALIGN 0x2d4 /* Frames rx'd with alignment err */ ++#define IEEE_R_MACERR 0x2d8 /* Receive FIFO overflow count */ ++#define IEEE_R_FDXFC 0x2dc /* Flow control pause frames rx'd */ ++#define IEEE_R_OCTETS_OK 0x2e0 /* Octet cnt for frames rx'd w/o err */ ++ ++#define EMAC_SMAC_0_0 0x500 /*Supplemental MAC Address 0 (RW).*/ ++#define EMAC_SMAC_0_1 0x504 /*Supplemental MAC Address 0 (RW).*/ ++ ++/* GEMAC definitions and settings */ ++ ++#define EMAC_PORT_0 0 ++#define EMAC_PORT_1 1 ++ ++/* GEMAC Bit definitions */ ++#define EMAC_IEVENT_HBERR 0x80000000 ++#define EMAC_IEVENT_BABR 0x40000000 ++#define EMAC_IEVENT_BABT 0x20000000 ++#define EMAC_IEVENT_GRA 0x10000000 ++#define EMAC_IEVENT_TXF 0x08000000 ++#define EMAC_IEVENT_TXB 0x04000000 ++#define EMAC_IEVENT_RXF 0x02000000 ++#define EMAC_IEVENT_RXB 0x01000000 ++#define EMAC_IEVENT_MII 0x00800000 ++#define EMAC_IEVENT_EBERR 0x00400000 ++#define EMAC_IEVENT_LC 0x00200000 ++#define EMAC_IEVENT_RL 0x00100000 ++#define EMAC_IEVENT_UN 0x00080000 ++ ++#define EMAC_IMASK_HBERR 0x80000000 ++#define EMAC_IMASK_BABR 0x40000000 ++#define EMAC_IMASKT_BABT 0x20000000 ++#define EMAC_IMASK_GRA 0x10000000 ++#define EMAC_IMASKT_TXF 0x08000000 ++#define EMAC_IMASK_TXB 0x04000000 ++#define EMAC_IMASKT_RXF 0x02000000 ++#define EMAC_IMASK_RXB 0x01000000 ++#define EMAC_IMASK_MII 0x00800000 ++#define EMAC_IMASK_EBERR 0x00400000 ++#define EMAC_IMASK_LC 0x00200000 ++#define EMAC_IMASKT_RL 0x00100000 ++#define EMAC_IMASK_UN 0x00080000 ++ ++#define EMAC_RCNTRL_MAX_FL_SHIFT 16 ++#define EMAC_RCNTRL_LOOP 0x00000001 ++#define EMAC_RCNTRL_DRT 0x00000002 ++#define EMAC_RCNTRL_MII_MODE 0x00000004 ++#define EMAC_RCNTRL_PROM 0x00000008 ++#define EMAC_RCNTRL_BC_REJ 0x00000010 ++#define EMAC_RCNTRL_FCE 0x00000020 ++#define EMAC_RCNTRL_RGMII 0x00000040 ++#define EMAC_RCNTRL_SGMII 0x00000080 ++#define EMAC_RCNTRL_RMII 0x00000100 ++#define EMAC_RCNTRL_RMII_10T 0x00000200 ++#define EMAC_RCNTRL_CRC_FWD 0x00004000 ++ ++#define EMAC_TCNTRL_GTS 0x00000001 ++#define EMAC_TCNTRL_HBC 0x00000002 ++#define EMAC_TCNTRL_FDEN 0x00000004 ++#define EMAC_TCNTRL_TFC_PAUSE 0x00000008 ++#define EMAC_TCNTRL_RFC_PAUSE 0x00000010 ++ ++#define EMAC_ECNTRL_RESET 0x00000001 /* reset the EMAC */ ++#define EMAC_ECNTRL_ETHER_EN 0x00000002 /* enable the EMAC */ ++#define EMAC_ECNTRL_MAGIC_ENA 0x00000004 ++#define EMAC_ECNTRL_SLEEP 0x00000008 ++#define EMAC_ECNTRL_SPEED 0x00000020 ++#define EMAC_ECNTRL_DBSWAP 0x00000100 ++ ++#define EMAC_X_WMRK_STRFWD 0x00000100 ++ ++#define EMAC_X_DES_ACTIVE_TDAR 0x01000000 ++#define EMAC_R_DES_ACTIVE_RDAR 0x01000000 ++ ++#define EMAC_RX_SECTION_EMPTY_V 0x00010006 ++/* ++ * The possible operating speeds of the MAC, currently supporting 10, 100 and ++ * 1000Mb modes. ++ */ ++enum mac_speed {SPEED_10M, SPEED_100M, SPEED_1000M, SPEED_1000M_PCS}; ++ ++/* MII-related definitios */ ++#define EMAC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */ ++#define EMAC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */ ++#define EMAC_MII_DATA_OP_CL45_RD 0x30000000 /* Perform a read operation */ ++#define EMAC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */ ++#define EMAC_MII_DATA_OP_CL45_WR 0x10000000 /* Perform a write operation */ ++#define EMAC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */ ++#define EMAC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */ ++#define EMAC_MII_DATA_TA 0x00020000 /* Turnaround */ ++#define EMAC_MII_DATA_DATAMSK 0x0000ffff /* PHY data field */ ++ ++#define EMAC_MII_DATA_RA_SHIFT 18 /* MII Register address bits */ ++#define EMAC_MII_DATA_RA_MASK 0x1F /* MII Register address mask */ ++#define EMAC_MII_DATA_PA_SHIFT 23 /* MII PHY address bits */ ++#define EMAC_MII_DATA_PA_MASK 0x1F /* MII PHY address mask */ ++ ++#define EMAC_MII_DATA_RA(v) (((v) & EMAC_MII_DATA_RA_MASK) << \ ++ EMAC_MII_DATA_RA_SHIFT) ++#define EMAC_MII_DATA_PA(v) (((v) & EMAC_MII_DATA_RA_MASK) << \ ++ EMAC_MII_DATA_PA_SHIFT) ++#define EMAC_MII_DATA(v) ((v) & 0xffff) ++ ++#define EMAC_MII_SPEED_SHIFT 1 ++#define EMAC_HOLDTIME_SHIFT 8 ++#define EMAC_HOLDTIME_MASK 0x7 ++#define EMAC_HOLDTIME(v) (((v) & EMAC_HOLDTIME_MASK) << \ ++ EMAC_HOLDTIME_SHIFT) ++ ++/* ++ * The Address organisation for the MAC device. All addresses are split into ++ * two 32-bit register fields. The first one (bottom) is the lower 32-bits of ++ * the address and the other field are the high order bits - this may be 16-bits ++ * in the case of MAC addresses, or 32-bits for the hash address. ++ * In terms of memory storage, the first item (bottom) is assumed to be at a ++ * lower address location than 'top'. i.e. top should be at address location of ++ * 'bottom' + 4 bytes. ++ */ ++struct pfe_mac_addr { ++ u32 bottom; /* Lower 32-bits of address. */ ++ u32 top; /* Upper 32-bits of address. */ ++}; ++ ++/* ++ * The following is the organisation of the address filters section of the MAC ++ * registers. The Cadence MAC contains four possible specific address match ++ * addresses, if an incoming frame corresponds to any one of these four ++ * addresses then the frame will be copied to memory. ++ * It is not necessary for all four of the address match registers to be ++ * programmed, this is application dependent. ++ */ ++struct spec_addr { ++ struct pfe_mac_addr one; /* Specific address register 1. */ ++ struct pfe_mac_addr two; /* Specific address register 2. */ ++ struct pfe_mac_addr three; /* Specific address register 3. */ ++ struct pfe_mac_addr four; /* Specific address register 4. */ ++}; ++ ++struct gemac_cfg { ++ u32 mode; ++ u32 speed; ++ u32 duplex; ++}; ++ ++/* EMAC Hash size */ ++#define EMAC_HASH_REG_BITS 64 ++ ++#define EMAC_SPEC_ADDR_MAX 4 ++ ++#endif /* _EMAC_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h +@@ -0,0 +1,86 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _GPI_H_ ++#define _GPI_H_ ++ ++#define GPI_VERSION 0x00 ++#define GPI_CTRL 0x04 ++#define GPI_RX_CONFIG 0x08 ++#define GPI_HDR_SIZE 0x0c ++#define GPI_BUF_SIZE 0x10 ++#define GPI_LMEM_ALLOC_ADDR 0x14 ++#define GPI_LMEM_FREE_ADDR 0x18 ++#define GPI_DDR_ALLOC_ADDR 0x1c ++#define GPI_DDR_FREE_ADDR 0x20 ++#define GPI_CLASS_ADDR 0x24 ++#define GPI_DRX_FIFO 0x28 ++#define GPI_TRX_FIFO 0x2c ++#define GPI_INQ_PKTPTR 0x30 ++#define GPI_DDR_DATA_OFFSET 0x34 ++#define GPI_LMEM_DATA_OFFSET 0x38 ++#define GPI_TMLF_TX 0x4c ++#define GPI_DTX_ASEQ 0x50 ++#define GPI_FIFO_STATUS 0x54 ++#define GPI_FIFO_DEBUG 0x58 ++#define GPI_TX_PAUSE_TIME 0x5c ++#define GPI_LMEM_SEC_BUF_DATA_OFFSET 0x60 ++#define GPI_DDR_SEC_BUF_DATA_OFFSET 0x64 ++#define GPI_TOE_CHKSUM_EN 0x68 ++#define GPI_OVERRUN_DROPCNT 0x6c ++#define GPI_CSR_MTIP_PAUSE_REG 0x74 ++#define GPI_CSR_MTIP_PAUSE_QUANTUM 0x78 ++#define GPI_CSR_RX_CNT 0x7c ++#define GPI_CSR_TX_CNT 0x80 ++#define GPI_CSR_DEBUG1 0x84 ++#define GPI_CSR_DEBUG2 0x88 ++ ++struct gpi_cfg { ++ u32 lmem_rtry_cnt; ++ u32 tmlf_txthres; ++ u32 aseq_len; ++ u32 mtip_pause_reg; ++}; ++ ++/* GPI commons defines */ ++#define GPI_LMEM_BUF_EN 0x1 ++#define GPI_DDR_BUF_EN 0x1 ++ ++/* EGPI 1 defines */ ++#define EGPI1_LMEM_RTRY_CNT 0x40 ++#define EGPI1_TMLF_TXTHRES 0xBC ++#define EGPI1_ASEQ_LEN 0x50 ++ ++/* EGPI 2 defines */ ++#define EGPI2_LMEM_RTRY_CNT 0x40 ++#define EGPI2_TMLF_TXTHRES 0xBC ++#define EGPI2_ASEQ_LEN 0x40 ++ ++/* EGPI 3 defines */ ++#define EGPI3_LMEM_RTRY_CNT 0x40 ++#define EGPI3_TMLF_TXTHRES 0xBC ++#define EGPI3_ASEQ_LEN 0x40 ++ ++/* HGPI defines */ ++#define HGPI_LMEM_RTRY_CNT 0x40 ++#define HGPI_TMLF_TXTHRES 0xBC ++#define HGPI_ASEQ_LEN 0x40 ++ ++#define EGPI_PAUSE_TIME 0x000007D0 ++#define EGPI_PAUSE_ENABLE 0x40000000 ++#endif /* _GPI_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h +@@ -0,0 +1,100 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _HIF_H_ ++#define _HIF_H_ ++ ++/* @file hif.h. ++ * hif - PFE hif block control and status register. ++ * Mapped on CBUS and accessible from all PE's and ARM. ++ */ ++#define HIF_VERSION (HIF_BASE_ADDR + 0x00) ++#define HIF_TX_CTRL (HIF_BASE_ADDR + 0x04) ++#define HIF_TX_CURR_BD_ADDR (HIF_BASE_ADDR + 0x08) ++#define HIF_TX_ALLOC (HIF_BASE_ADDR + 0x0c) ++#define HIF_TX_BDP_ADDR (HIF_BASE_ADDR + 0x10) ++#define HIF_TX_STATUS (HIF_BASE_ADDR + 0x14) ++#define HIF_RX_CTRL (HIF_BASE_ADDR + 0x20) ++#define HIF_RX_BDP_ADDR (HIF_BASE_ADDR + 0x24) ++#define HIF_RX_STATUS (HIF_BASE_ADDR + 0x30) ++#define HIF_INT_SRC (HIF_BASE_ADDR + 0x34) ++#define HIF_INT_ENABLE (HIF_BASE_ADDR + 0x38) ++#define HIF_POLL_CTRL (HIF_BASE_ADDR + 0x3c) ++#define HIF_RX_CURR_BD_ADDR (HIF_BASE_ADDR + 0x40) ++#define HIF_RX_ALLOC (HIF_BASE_ADDR + 0x44) ++#define HIF_TX_DMA_STATUS (HIF_BASE_ADDR + 0x48) ++#define HIF_RX_DMA_STATUS (HIF_BASE_ADDR + 0x4c) ++#define HIF_INT_COAL (HIF_BASE_ADDR + 0x50) ++ ++/* HIF_INT_SRC/ HIF_INT_ENABLE control bits */ ++#define HIF_INT BIT(0) ++#define HIF_RXBD_INT BIT(1) ++#define HIF_RXPKT_INT BIT(2) ++#define HIF_TXBD_INT BIT(3) ++#define HIF_TXPKT_INT BIT(4) ++ ++/* HIF_TX_CTRL bits */ ++#define HIF_CTRL_DMA_EN BIT(0) ++#define HIF_CTRL_BDP_POLL_CTRL_EN BIT(1) ++#define HIF_CTRL_BDP_CH_START_WSTB BIT(2) ++ ++/* HIF_RX_STATUS bits */ ++#define BDP_CSR_RX_DMA_ACTV BIT(16) ++ ++/* HIF_INT_ENABLE bits */ ++#define HIF_INT_EN BIT(0) ++#define HIF_RXBD_INT_EN BIT(1) ++#define HIF_RXPKT_INT_EN BIT(2) ++#define HIF_TXBD_INT_EN BIT(3) ++#define HIF_TXPKT_INT_EN BIT(4) ++ ++/* HIF_POLL_CTRL bits*/ ++#define HIF_RX_POLL_CTRL_CYCLE 0x0400 ++#define HIF_TX_POLL_CTRL_CYCLE 0x0400 ++ ++/* HIF_INT_COAL bits*/ ++#define HIF_INT_COAL_ENABLE BIT(31) ++ ++/* Buffer descriptor control bits */ ++#define BD_CTRL_BUFLEN_MASK 0x3fff ++#define BD_BUF_LEN(x) ((x) & BD_CTRL_BUFLEN_MASK) ++#define BD_CTRL_CBD_INT_EN BIT(16) ++#define BD_CTRL_PKT_INT_EN BIT(17) ++#define BD_CTRL_LIFM BIT(18) ++#define BD_CTRL_LAST_BD BIT(19) ++#define BD_CTRL_DIR BIT(20) ++#define BD_CTRL_LMEM_CPY BIT(21) /* Valid only for HIF_NOCPY */ ++#define BD_CTRL_PKT_XFER BIT(24) ++#define BD_CTRL_DESC_EN BIT(31) ++#define BD_CTRL_PARSE_DISABLE BIT(25) ++#define BD_CTRL_BRFETCH_DISABLE BIT(26) ++#define BD_CTRL_RTFETCH_DISABLE BIT(27) ++ ++/* Buffer descriptor status bits*/ ++#define BD_STATUS_CONN_ID(x) ((x) & 0xffff) ++#define BD_STATUS_DIR_PROC_ID BIT(16) ++#define BD_STATUS_CONN_ID_EN BIT(17) ++#define BD_STATUS_PE2PROC_ID(x) (((x) & 7) << 18) ++#define BD_STATUS_LE_DATA BIT(21) ++#define BD_STATUS_CHKSUM_EN BIT(22) ++ ++/* HIF Buffer descriptor status bits */ ++#define DIR_PROC_ID BIT(16) ++#define PROC_ID(id) ((id) << 18) ++ ++#endif /* _HIF_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h +@@ -0,0 +1,50 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _HIF_NOCPY_H_ ++#define _HIF_NOCPY_H_ ++ ++#define HIF_NOCPY_VERSION (HIF_NOCPY_BASE_ADDR + 0x00) ++#define HIF_NOCPY_TX_CTRL (HIF_NOCPY_BASE_ADDR + 0x04) ++#define HIF_NOCPY_TX_CURR_BD_ADDR (HIF_NOCPY_BASE_ADDR + 0x08) ++#define HIF_NOCPY_TX_ALLOC (HIF_NOCPY_BASE_ADDR + 0x0c) ++#define HIF_NOCPY_TX_BDP_ADDR (HIF_NOCPY_BASE_ADDR + 0x10) ++#define HIF_NOCPY_TX_STATUS (HIF_NOCPY_BASE_ADDR + 0x14) ++#define HIF_NOCPY_RX_CTRL (HIF_NOCPY_BASE_ADDR + 0x20) ++#define HIF_NOCPY_RX_BDP_ADDR (HIF_NOCPY_BASE_ADDR + 0x24) ++#define HIF_NOCPY_RX_STATUS (HIF_NOCPY_BASE_ADDR + 0x30) ++#define HIF_NOCPY_INT_SRC (HIF_NOCPY_BASE_ADDR + 0x34) ++#define HIF_NOCPY_INT_ENABLE (HIF_NOCPY_BASE_ADDR + 0x38) ++#define HIF_NOCPY_POLL_CTRL (HIF_NOCPY_BASE_ADDR + 0x3c) ++#define HIF_NOCPY_RX_CURR_BD_ADDR (HIF_NOCPY_BASE_ADDR + 0x40) ++#define HIF_NOCPY_RX_ALLOC (HIF_NOCPY_BASE_ADDR + 0x44) ++#define HIF_NOCPY_TX_DMA_STATUS (HIF_NOCPY_BASE_ADDR + 0x48) ++#define HIF_NOCPY_RX_DMA_STATUS (HIF_NOCPY_BASE_ADDR + 0x4c) ++#define HIF_NOCPY_RX_INQ0_PKTPTR (HIF_NOCPY_BASE_ADDR + 0x50) ++#define HIF_NOCPY_RX_INQ1_PKTPTR (HIF_NOCPY_BASE_ADDR + 0x54) ++#define HIF_NOCPY_TX_PORT_NO (HIF_NOCPY_BASE_ADDR + 0x60) ++#define HIF_NOCPY_LMEM_ALLOC_ADDR (HIF_NOCPY_BASE_ADDR + 0x64) ++#define HIF_NOCPY_CLASS_ADDR (HIF_NOCPY_BASE_ADDR + 0x68) ++#define HIF_NOCPY_TMU_PORT0_ADDR (HIF_NOCPY_BASE_ADDR + 0x70) ++#define HIF_NOCPY_TMU_PORT1_ADDR (HIF_NOCPY_BASE_ADDR + 0x74) ++#define HIF_NOCPY_TMU_PORT2_ADDR (HIF_NOCPY_BASE_ADDR + 0x7c) ++#define HIF_NOCPY_TMU_PORT3_ADDR (HIF_NOCPY_BASE_ADDR + 0x80) ++#define HIF_NOCPY_TMU_PORT4_ADDR (HIF_NOCPY_BASE_ADDR + 0x84) ++#define HIF_NOCPY_INT_COAL (HIF_NOCPY_BASE_ADDR + 0x90) ++ ++#endif /* _HIF_NOCPY_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h +@@ -0,0 +1,168 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _TMU_CSR_H_ ++#define _TMU_CSR_H_ ++ ++#define TMU_VERSION (TMU_CSR_BASE_ADDR + 0x000) ++#define TMU_INQ_WATERMARK (TMU_CSR_BASE_ADDR + 0x004) ++#define TMU_PHY_INQ_PKTPTR (TMU_CSR_BASE_ADDR + 0x008) ++#define TMU_PHY_INQ_PKTINFO (TMU_CSR_BASE_ADDR + 0x00c) ++#define TMU_PHY_INQ_FIFO_CNT (TMU_CSR_BASE_ADDR + 0x010) ++#define TMU_SYS_GENERIC_CONTROL (TMU_CSR_BASE_ADDR + 0x014) ++#define TMU_SYS_GENERIC_STATUS (TMU_CSR_BASE_ADDR + 0x018) ++#define TMU_SYS_GEN_CON0 (TMU_CSR_BASE_ADDR + 0x01c) ++#define TMU_SYS_GEN_CON1 (TMU_CSR_BASE_ADDR + 0x020) ++#define TMU_SYS_GEN_CON2 (TMU_CSR_BASE_ADDR + 0x024) ++#define TMU_SYS_GEN_CON3 (TMU_CSR_BASE_ADDR + 0x028) ++#define TMU_SYS_GEN_CON4 (TMU_CSR_BASE_ADDR + 0x02c) ++#define TMU_TEQ_DISABLE_DROPCHK (TMU_CSR_BASE_ADDR + 0x030) ++#define TMU_TEQ_CTRL (TMU_CSR_BASE_ADDR + 0x034) ++#define TMU_TEQ_QCFG (TMU_CSR_BASE_ADDR + 0x038) ++#define TMU_TEQ_DROP_STAT (TMU_CSR_BASE_ADDR + 0x03c) ++#define TMU_TEQ_QAVG (TMU_CSR_BASE_ADDR + 0x040) ++#define TMU_TEQ_WREG_PROB (TMU_CSR_BASE_ADDR + 0x044) ++#define TMU_TEQ_TRANS_STAT (TMU_CSR_BASE_ADDR + 0x048) ++#define TMU_TEQ_HW_PROB_CFG0 (TMU_CSR_BASE_ADDR + 0x04c) ++#define TMU_TEQ_HW_PROB_CFG1 (TMU_CSR_BASE_ADDR + 0x050) ++#define TMU_TEQ_HW_PROB_CFG2 (TMU_CSR_BASE_ADDR + 0x054) ++#define TMU_TEQ_HW_PROB_CFG3 (TMU_CSR_BASE_ADDR + 0x058) ++#define TMU_TEQ_HW_PROB_CFG4 (TMU_CSR_BASE_ADDR + 0x05c) ++#define TMU_TEQ_HW_PROB_CFG5 (TMU_CSR_BASE_ADDR + 0x060) ++#define TMU_TEQ_HW_PROB_CFG6 (TMU_CSR_BASE_ADDR + 0x064) ++#define TMU_TEQ_HW_PROB_CFG7 (TMU_CSR_BASE_ADDR + 0x068) ++#define TMU_TEQ_HW_PROB_CFG8 (TMU_CSR_BASE_ADDR + 0x06c) ++#define TMU_TEQ_HW_PROB_CFG9 (TMU_CSR_BASE_ADDR + 0x070) ++#define TMU_TEQ_HW_PROB_CFG10 (TMU_CSR_BASE_ADDR + 0x074) ++#define TMU_TEQ_HW_PROB_CFG11 (TMU_CSR_BASE_ADDR + 0x078) ++#define TMU_TEQ_HW_PROB_CFG12 (TMU_CSR_BASE_ADDR + 0x07c) ++#define TMU_TEQ_HW_PROB_CFG13 (TMU_CSR_BASE_ADDR + 0x080) ++#define TMU_TEQ_HW_PROB_CFG14 (TMU_CSR_BASE_ADDR + 0x084) ++#define TMU_TEQ_HW_PROB_CFG15 (TMU_CSR_BASE_ADDR + 0x088) ++#define TMU_TEQ_HW_PROB_CFG16 (TMU_CSR_BASE_ADDR + 0x08c) ++#define TMU_TEQ_HW_PROB_CFG17 (TMU_CSR_BASE_ADDR + 0x090) ++#define TMU_TEQ_HW_PROB_CFG18 (TMU_CSR_BASE_ADDR + 0x094) ++#define TMU_TEQ_HW_PROB_CFG19 (TMU_CSR_BASE_ADDR + 0x098) ++#define TMU_TEQ_HW_PROB_CFG20 (TMU_CSR_BASE_ADDR + 0x09c) ++#define TMU_TEQ_HW_PROB_CFG21 (TMU_CSR_BASE_ADDR + 0x0a0) ++#define TMU_TEQ_HW_PROB_CFG22 (TMU_CSR_BASE_ADDR + 0x0a4) ++#define TMU_TEQ_HW_PROB_CFG23 (TMU_CSR_BASE_ADDR + 0x0a8) ++#define TMU_TEQ_HW_PROB_CFG24 (TMU_CSR_BASE_ADDR + 0x0ac) ++#define TMU_TEQ_HW_PROB_CFG25 (TMU_CSR_BASE_ADDR + 0x0b0) ++#define TMU_TDQ_IIFG_CFG (TMU_CSR_BASE_ADDR + 0x0b4) ++/* [9:0] Scheduler Enable for each of the scheduler in the TDQ. ++ * This is a global Enable for all schedulers in PHY0 ++ */ ++#define TMU_TDQ0_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x0b8) ++ ++#define TMU_LLM_CTRL (TMU_CSR_BASE_ADDR + 0x0bc) ++#define TMU_LLM_BASE_ADDR (TMU_CSR_BASE_ADDR + 0x0c0) ++#define TMU_LLM_QUE_LEN (TMU_CSR_BASE_ADDR + 0x0c4) ++#define TMU_LLM_QUE_HEADPTR (TMU_CSR_BASE_ADDR + 0x0c8) ++#define TMU_LLM_QUE_TAILPTR (TMU_CSR_BASE_ADDR + 0x0cc) ++#define TMU_LLM_QUE_DROPCNT (TMU_CSR_BASE_ADDR + 0x0d0) ++#define TMU_INT_EN (TMU_CSR_BASE_ADDR + 0x0d4) ++#define TMU_INT_SRC (TMU_CSR_BASE_ADDR + 0x0d8) ++#define TMU_INQ_STAT (TMU_CSR_BASE_ADDR + 0x0dc) ++#define TMU_CTRL (TMU_CSR_BASE_ADDR + 0x0e0) ++ ++/* [31] Mem Access Command. 0 = Internal Memory Read, 1 = Internal memory ++ * Write [27:24] Byte Enables of the Internal memory access [23:0] Address of ++ * the internal memory. This address is used to access both the PM and DM of ++ * all the PE's ++ */ ++#define TMU_MEM_ACCESS_ADDR (TMU_CSR_BASE_ADDR + 0x0e4) ++ ++/* Internal Memory Access Write Data */ ++#define TMU_MEM_ACCESS_WDATA (TMU_CSR_BASE_ADDR + 0x0e8) ++/* Internal Memory Access Read Data. The commands are blocked ++ * at the mem_access only ++ */ ++#define TMU_MEM_ACCESS_RDATA (TMU_CSR_BASE_ADDR + 0x0ec) ++ ++/* [31:0] PHY0 in queue address (must be initialized with one of the ++ * xxx_INQ_PKTPTR cbus addresses) ++ */ ++#define TMU_PHY0_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f0) ++/* [31:0] PHY1 in queue address (must be initialized with one of the ++ * xxx_INQ_PKTPTR cbus addresses) ++ */ ++#define TMU_PHY1_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f4) ++/* [31:0] PHY2 in queue address (must be initialized with one of the ++ * xxx_INQ_PKTPTR cbus addresses) ++ */ ++#define TMU_PHY2_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f8) ++/* [31:0] PHY3 in queue address (must be initialized with one of the ++ * xxx_INQ_PKTPTR cbus addresses) ++ */ ++#define TMU_PHY3_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0fc) ++#define TMU_BMU_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x100) ++#define TMU_TX_CTRL (TMU_CSR_BASE_ADDR + 0x104) ++ ++#define TMU_BUS_ACCESS_WDATA (TMU_CSR_BASE_ADDR + 0x108) ++#define TMU_BUS_ACCESS (TMU_CSR_BASE_ADDR + 0x10c) ++#define TMU_BUS_ACCESS_RDATA (TMU_CSR_BASE_ADDR + 0x110) ++ ++#define TMU_PE_SYS_CLK_RATIO (TMU_CSR_BASE_ADDR + 0x114) ++#define TMU_PE_STATUS (TMU_CSR_BASE_ADDR + 0x118) ++#define TMU_TEQ_MAX_THRESHOLD (TMU_CSR_BASE_ADDR + 0x11c) ++/* [31:0] PHY4 in queue address (must be initialized with one of the ++ * xxx_INQ_PKTPTR cbus addresses) ++ */ ++#define TMU_PHY4_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x134) ++/* [9:0] Scheduler Enable for each of the scheduler in the TDQ. ++ * This is a global Enable for all schedulers in PHY1 ++ */ ++#define TMU_TDQ1_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x138) ++/* [9:0] Scheduler Enable for each of the scheduler in the TDQ. ++ * This is a global Enable for all schedulers in PHY2 ++ */ ++#define TMU_TDQ2_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x13c) ++/* [9:0] Scheduler Enable for each of the scheduler in the TDQ. ++ * This is a global Enable for all schedulers in PHY3 ++ */ ++#define TMU_TDQ3_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x140) ++#define TMU_BMU_BUF_SIZE (TMU_CSR_BASE_ADDR + 0x144) ++/* [31:0] PHY5 in queue address (must be initialized with one of the ++ * xxx_INQ_PKTPTR cbus addresses) ++ */ ++#define TMU_PHY5_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x148) ++ ++#define SW_RESET BIT(0) /* Global software reset */ ++#define INQ_RESET BIT(2) ++#define TEQ_RESET BIT(3) ++#define TDQ_RESET BIT(4) ++#define PE_RESET BIT(5) ++#define MEM_INIT BIT(6) ++#define MEM_INIT_DONE BIT(7) ++#define LLM_INIT BIT(8) ++#define LLM_INIT_DONE BIT(9) ++#define ECC_MEM_INIT_DONE BIT(10) ++ ++struct tmu_cfg { ++ u32 pe_sys_clk_ratio; ++ unsigned long llm_base_addr; ++ u32 llm_queue_len; ++}; ++ ++/* Not HW related for pfe_ctrl / pfe common defines */ ++#define DEFAULT_MAX_QDEPTH 80 ++#define DEFAULT_Q0_QDEPTH 511 /*We keep one large queue for host tx qos */ ++#define DEFAULT_TMU3_QDEPTH 127 ++ ++#endif /* _TMU_CSR_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/util_csr.h +@@ -0,0 +1,61 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _UTIL_CSR_H_ ++#define _UTIL_CSR_H_ ++ ++#define UTIL_VERSION (UTIL_CSR_BASE_ADDR + 0x000) ++#define UTIL_TX_CTRL (UTIL_CSR_BASE_ADDR + 0x004) ++#define UTIL_INQ_PKTPTR (UTIL_CSR_BASE_ADDR + 0x010) ++ ++#define UTIL_HDR_SIZE (UTIL_CSR_BASE_ADDR + 0x014) ++ ++#define UTIL_PE0_QB_DM_ADDR0 (UTIL_CSR_BASE_ADDR + 0x020) ++#define UTIL_PE0_QB_DM_ADDR1 (UTIL_CSR_BASE_ADDR + 0x024) ++#define UTIL_PE0_RO_DM_ADDR0 (UTIL_CSR_BASE_ADDR + 0x060) ++#define UTIL_PE0_RO_DM_ADDR1 (UTIL_CSR_BASE_ADDR + 0x064) ++ ++#define UTIL_MEM_ACCESS_ADDR (UTIL_CSR_BASE_ADDR + 0x100) ++#define UTIL_MEM_ACCESS_WDATA (UTIL_CSR_BASE_ADDR + 0x104) ++#define UTIL_MEM_ACCESS_RDATA (UTIL_CSR_BASE_ADDR + 0x108) ++ ++#define UTIL_TM_INQ_ADDR (UTIL_CSR_BASE_ADDR + 0x114) ++#define UTIL_PE_STATUS (UTIL_CSR_BASE_ADDR + 0x118) ++ ++#define UTIL_PE_SYS_CLK_RATIO (UTIL_CSR_BASE_ADDR + 0x200) ++#define UTIL_AFULL_THRES (UTIL_CSR_BASE_ADDR + 0x204) ++#define UTIL_GAP_BETWEEN_READS (UTIL_CSR_BASE_ADDR + 0x208) ++#define UTIL_MAX_BUF_CNT (UTIL_CSR_BASE_ADDR + 0x20c) ++#define UTIL_TSQ_FIFO_THRES (UTIL_CSR_BASE_ADDR + 0x210) ++#define UTIL_TSQ_MAX_CNT (UTIL_CSR_BASE_ADDR + 0x214) ++#define UTIL_IRAM_DATA_0 (UTIL_CSR_BASE_ADDR + 0x218) ++#define UTIL_IRAM_DATA_1 (UTIL_CSR_BASE_ADDR + 0x21c) ++#define UTIL_IRAM_DATA_2 (UTIL_CSR_BASE_ADDR + 0x220) ++#define UTIL_IRAM_DATA_3 (UTIL_CSR_BASE_ADDR + 0x224) ++ ++#define UTIL_BUS_ACCESS_ADDR (UTIL_CSR_BASE_ADDR + 0x228) ++#define UTIL_BUS_ACCESS_WDATA (UTIL_CSR_BASE_ADDR + 0x22c) ++#define UTIL_BUS_ACCESS_RDATA (UTIL_CSR_BASE_ADDR + 0x230) ++ ++#define UTIL_INQ_AFULL_THRES (UTIL_CSR_BASE_ADDR + 0x234) ++ ++struct util_cfg { ++ u32 pe_sys_clk_ratio; ++}; ++ ++#endif /* _UTIL_CSR_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/include/pfe/pfe.h +@@ -0,0 +1,372 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _PFE_H_ ++#define _PFE_H_ ++ ++#include "cbus.h" ++ ++#define CLASS_DMEM_BASE_ADDR(i) (0x00000000 | ((i) << 20)) ++/* ++ * Only valid for mem access register interface ++ */ ++#define CLASS_IMEM_BASE_ADDR(i) (0x00000000 | ((i) << 20)) ++#define CLASS_DMEM_SIZE 0x00002000 ++#define CLASS_IMEM_SIZE 0x00008000 ++ ++#define TMU_DMEM_BASE_ADDR(i) (0x00000000 + ((i) << 20)) ++/* ++ * Only valid for mem access register interface ++ */ ++#define TMU_IMEM_BASE_ADDR(i) (0x00000000 + ((i) << 20)) ++#define TMU_DMEM_SIZE 0x00000800 ++#define TMU_IMEM_SIZE 0x00002000 ++ ++#define UTIL_DMEM_BASE_ADDR 0x00000000 ++#define UTIL_DMEM_SIZE 0x00002000 ++ ++#define PE_LMEM_BASE_ADDR 0xc3010000 ++#define PE_LMEM_SIZE 0x8000 ++#define PE_LMEM_END (PE_LMEM_BASE_ADDR + PE_LMEM_SIZE) ++ ++#define DMEM_BASE_ADDR 0x00000000 ++#define DMEM_SIZE 0x2000 /* TMU has less... */ ++#define DMEM_END (DMEM_BASE_ADDR + DMEM_SIZE) ++ ++#define PMEM_BASE_ADDR 0x00010000 ++#define PMEM_SIZE 0x8000 /* TMU has less... */ ++#define PMEM_END (PMEM_BASE_ADDR + PMEM_SIZE) ++ ++/* These check memory ranges from PE point of view/memory map */ ++#define IS_DMEM(addr, len) \ ++ ({ typeof(addr) addr_ = (addr); \ ++ ((unsigned long)(addr_) >= DMEM_BASE_ADDR) && \ ++ (((unsigned long)(addr_) + (len)) <= DMEM_END); }) ++ ++#define IS_PMEM(addr, len) \ ++ ({ typeof(addr) addr_ = (addr); \ ++ ((unsigned long)(addr_) >= PMEM_BASE_ADDR) && \ ++ (((unsigned long)(addr_) + (len)) <= PMEM_END); }) ++ ++#define IS_PE_LMEM(addr, len) \ ++ ({ typeof(addr) addr_ = (addr); \ ++ ((unsigned long)(addr_) >= \ ++ PE_LMEM_BASE_ADDR) && \ ++ (((unsigned long)(addr_) + \ ++ (len)) <= PE_LMEM_END); }) ++ ++#define IS_PFE_LMEM(addr, len) \ ++ ({ typeof(addr) addr_ = (addr); \ ++ ((unsigned long)(addr_) >= \ ++ CBUS_VIRT_TO_PFE(LMEM_BASE_ADDR)) && \ ++ (((unsigned long)(addr_) + (len)) <= \ ++ CBUS_VIRT_TO_PFE(LMEM_END)); }) ++ ++#define __IS_PHYS_DDR(addr, len) \ ++ ({ typeof(addr) addr_ = (addr); \ ++ ((unsigned long)(addr_) >= \ ++ DDR_PHYS_BASE_ADDR) && \ ++ (((unsigned long)(addr_) + (len)) <= \ ++ DDR_PHYS_END); }) ++ ++#define IS_PHYS_DDR(addr, len) __IS_PHYS_DDR(DDR_PFE_TO_PHYS(addr), len) ++ ++/* ++ * If using a run-time virtual address for the cbus base address use this code ++ */ ++extern void *cbus_base_addr; ++extern void *ddr_base_addr; ++extern unsigned long ddr_phys_base_addr; ++extern unsigned int ddr_size; ++ ++#define CBUS_BASE_ADDR cbus_base_addr ++#define DDR_PHYS_BASE_ADDR ddr_phys_base_addr ++#define DDR_BASE_ADDR ddr_base_addr ++#define DDR_SIZE ddr_size ++ ++#define DDR_PHYS_END (DDR_PHYS_BASE_ADDR + DDR_SIZE) ++ ++#define LS1012A_PFE_RESET_WA /* ++ * PFE doesn't have global reset and re-init ++ * should takecare few things to make PFE ++ * functional after reset ++ */ ++#define PFE_CBUS_PHYS_BASE_ADDR 0xc0000000 /* CBUS physical base address ++ * as seen by PE's. ++ */ ++/* CBUS physical base address as seen by PE's. */ ++#define PFE_CBUS_PHYS_BASE_ADDR_FROM_PFE 0xc0000000 ++ ++#define DDR_PHYS_TO_PFE(p) (((unsigned long int)(p)) & 0x7FFFFFFF) ++#define DDR_PFE_TO_PHYS(p) (((unsigned long int)(p)) | 0x80000000) ++#define CBUS_PHYS_TO_PFE(p) (((p) - PFE_CBUS_PHYS_BASE_ADDR) + \ ++ PFE_CBUS_PHYS_BASE_ADDR_FROM_PFE) ++/* Translates to PFE address map */ ++ ++#define DDR_PHYS_TO_VIRT(p) (((p) - DDR_PHYS_BASE_ADDR) + DDR_BASE_ADDR) ++#define DDR_VIRT_TO_PHYS(v) (((v) - DDR_BASE_ADDR) + DDR_PHYS_BASE_ADDR) ++#define DDR_VIRT_TO_PFE(p) (DDR_PHYS_TO_PFE(DDR_VIRT_TO_PHYS(p))) ++ ++#define CBUS_VIRT_TO_PFE(v) (((v) - CBUS_BASE_ADDR) + \ ++ PFE_CBUS_PHYS_BASE_ADDR) ++#define CBUS_PFE_TO_VIRT(p) (((unsigned long int)(p) - \ ++ PFE_CBUS_PHYS_BASE_ADDR) + CBUS_BASE_ADDR) ++ ++/* The below part of the code is used in QOS control driver from host */ ++#define TMU_APB_BASE_ADDR 0xc1000000 /* TMU base address seen by ++ * pe's ++ */ ++ ++enum { ++ CLASS0_ID = 0, ++ CLASS1_ID, ++ CLASS2_ID, ++ CLASS3_ID, ++ CLASS4_ID, ++ CLASS5_ID, ++ TMU0_ID, ++ TMU1_ID, ++ TMU2_ID, ++ TMU3_ID, ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ UTIL_ID, ++#endif ++ MAX_PE ++}; ++ ++#define CLASS_MASK (BIT(CLASS0_ID) | BIT(CLASS1_ID) |\ ++ BIT(CLASS2_ID) | BIT(CLASS3_ID) |\ ++ BIT(CLASS4_ID) | BIT(CLASS5_ID)) ++#define CLASS_MAX_ID CLASS5_ID ++ ++#define TMU_MASK (BIT(TMU0_ID) | BIT(TMU1_ID) |\ ++ BIT(TMU3_ID)) ++ ++#define TMU_MAX_ID TMU3_ID ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++#define UTIL_MASK BIT(UTIL_ID) ++#endif ++ ++struct pe_status { ++ u32 cpu_state; ++ u32 activity_counter; ++ u32 rx; ++ union { ++ u32 tx; ++ u32 tmu_qstatus; ++ }; ++ u32 drop; ++#if defined(CFG_PE_DEBUG) ++ u32 debug_indicator; ++ u32 debug[16]; ++#endif ++} __aligned(16); ++ ++struct pe_sync_mailbox { ++ u32 stop; ++ u32 stopped; ++}; ++ ++/* Drop counter definitions */ ++ ++#define CLASS_NUM_DROP_COUNTERS 13 ++#define UTIL_NUM_DROP_COUNTERS 8 ++ ++/* PE information. ++ * Structure containing PE's specific information. It is used to create ++ * generic C functions common to all PE's. ++ * Before using the library functions this structure needs to be initialized ++ * with the different registers virtual addresses ++ * (according to the ARM MMU mmaping). The default initialization supports a ++ * virtual == physical mapping. ++ */ ++struct pe_info { ++ u32 dmem_base_addr; /* PE's dmem base address */ ++ u32 pmem_base_addr; /* PE's pmem base address */ ++ u32 pmem_size; /* PE's pmem size */ ++ ++ void *mem_access_wdata; /* PE's _MEM_ACCESS_WDATA register ++ * address ++ */ ++ void *mem_access_addr; /* PE's _MEM_ACCESS_ADDR register ++ * address ++ */ ++ void *mem_access_rdata; /* PE's _MEM_ACCESS_RDATA register ++ * address ++ */ ++}; ++ ++void pe_lmem_read(u32 *dst, u32 len, u32 offset); ++void pe_lmem_write(u32 *src, u32 len, u32 offset); ++ ++void pe_dmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len); ++void pe_pmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len); ++ ++u32 pe_pmem_read(int id, u32 addr, u8 size); ++ ++void pe_dmem_write(int id, u32 val, u32 addr, u8 size); ++u32 pe_dmem_read(int id, u32 addr, u8 size); ++void class_pe_lmem_memcpy_to32(u32 dst, const void *src, unsigned int len); ++void class_pe_lmem_memset(u32 dst, int val, unsigned int len); ++void class_bus_write(u32 val, u32 addr, u8 size); ++u32 class_bus_read(u32 addr, u8 size); ++ ++#define class_bus_readl(addr) class_bus_read(addr, 4) ++#define class_bus_readw(addr) class_bus_read(addr, 2) ++#define class_bus_readb(addr) class_bus_read(addr, 1) ++ ++#define class_bus_writel(val, addr) class_bus_write(val, addr, 4) ++#define class_bus_writew(val, addr) class_bus_write(val, addr, 2) ++#define class_bus_writeb(val, addr) class_bus_write(val, addr, 1) ++ ++#define pe_dmem_readl(id, addr) pe_dmem_read(id, addr, 4) ++#define pe_dmem_readw(id, addr) pe_dmem_read(id, addr, 2) ++#define pe_dmem_readb(id, addr) pe_dmem_read(id, addr, 1) ++ ++#define pe_dmem_writel(id, val, addr) pe_dmem_write(id, val, addr, 4) ++#define pe_dmem_writew(id, val, addr) pe_dmem_write(id, val, addr, 2) ++#define pe_dmem_writeb(id, val, addr) pe_dmem_write(id, val, addr, 1) ++ ++/*int pe_load_elf_section(int id, const void *data, elf32_shdr *shdr); */ ++int pe_load_elf_section(int id, const void *data, struct elf32_shdr *shdr, ++ struct device *dev); ++ ++void pfe_lib_init(void *cbus_base, void *ddr_base, unsigned long ddr_phys_base, ++ unsigned int ddr_size); ++void bmu_init(void *base, struct BMU_CFG *cfg); ++void bmu_reset(void *base); ++void bmu_enable(void *base); ++void bmu_disable(void *base); ++void bmu_set_config(void *base, struct BMU_CFG *cfg); ++ ++/* ++ * An enumerated type for loopback values. This can be one of three values, no ++ * loopback -normal operation, local loopback with internal loopback module of ++ * MAC or PHY loopback which is through the external PHY. ++ */ ++#ifndef __MAC_LOOP_ENUM__ ++#define __MAC_LOOP_ENUM__ ++enum mac_loop {LB_NONE, LB_EXT, LB_LOCAL}; ++#endif ++ ++void gemac_init(void *base, void *config); ++void gemac_disable_rx_checksum_offload(void *base); ++void gemac_enable_rx_checksum_offload(void *base); ++void gemac_set_mdc_div(void *base, int mdc_div); ++void gemac_set_speed(void *base, enum mac_speed gem_speed); ++void gemac_set_duplex(void *base, int duplex); ++void gemac_set_mode(void *base, int mode); ++void gemac_enable(void *base); ++void gemac_tx_disable(void *base); ++void gemac_tx_enable(void *base); ++void gemac_disable(void *base); ++void gemac_reset(void *base); ++void gemac_set_address(void *base, struct spec_addr *addr); ++struct spec_addr gemac_get_address(void *base); ++void gemac_set_loop(void *base, enum mac_loop gem_loop); ++void gemac_set_laddr1(void *base, struct pfe_mac_addr *address); ++void gemac_set_laddr2(void *base, struct pfe_mac_addr *address); ++void gemac_set_laddr3(void *base, struct pfe_mac_addr *address); ++void gemac_set_laddr4(void *base, struct pfe_mac_addr *address); ++void gemac_set_laddrN(void *base, struct pfe_mac_addr *address, ++ unsigned int entry_index); ++void gemac_clear_laddr1(void *base); ++void gemac_clear_laddr2(void *base); ++void gemac_clear_laddr3(void *base); ++void gemac_clear_laddr4(void *base); ++void gemac_clear_laddrN(void *base, unsigned int entry_index); ++struct pfe_mac_addr gemac_get_hash(void *base); ++void gemac_set_hash(void *base, struct pfe_mac_addr *hash); ++struct pfe_mac_addr gem_get_laddr1(void *base); ++struct pfe_mac_addr gem_get_laddr2(void *base); ++struct pfe_mac_addr gem_get_laddr3(void *base); ++struct pfe_mac_addr gem_get_laddr4(void *base); ++struct pfe_mac_addr gem_get_laddrN(void *base, unsigned int entry_index); ++void gemac_set_config(void *base, struct gemac_cfg *cfg); ++void gemac_allow_broadcast(void *base); ++void gemac_no_broadcast(void *base); ++void gemac_enable_1536_rx(void *base); ++void gemac_disable_1536_rx(void *base); ++void gemac_enable_rx_jmb(void *base); ++void gemac_disable_rx_jmb(void *base); ++void gemac_enable_stacked_vlan(void *base); ++void gemac_disable_stacked_vlan(void *base); ++void gemac_enable_pause_rx(void *base); ++void gemac_disable_pause_rx(void *base); ++void gemac_enable_copy_all(void *base); ++void gemac_disable_copy_all(void *base); ++void gemac_set_bus_width(void *base, int width); ++void gemac_set_wol(void *base, u32 wol_conf); ++ ++void gpi_init(void *base, struct gpi_cfg *cfg); ++void gpi_reset(void *base); ++void gpi_enable(void *base); ++void gpi_disable(void *base); ++void gpi_set_config(void *base, struct gpi_cfg *cfg); ++ ++void class_init(struct class_cfg *cfg); ++void class_reset(void); ++void class_enable(void); ++void class_disable(void); ++void class_set_config(struct class_cfg *cfg); ++ ++void tmu_reset(void); ++void tmu_init(struct tmu_cfg *cfg); ++void tmu_enable(u32 pe_mask); ++void tmu_disable(u32 pe_mask); ++u32 tmu_qstatus(u32 if_id); ++u32 tmu_pkts_processed(u32 if_id); ++ ++void util_init(struct util_cfg *cfg); ++void util_reset(void); ++void util_enable(void); ++void util_disable(void); ++ ++void hif_init(void); ++void hif_tx_enable(void); ++void hif_tx_disable(void); ++void hif_rx_enable(void); ++void hif_rx_disable(void); ++ ++/* Get Chip Revision level ++ * ++ */ ++static inline unsigned int CHIP_REVISION(void) ++{ ++ /*For LS1012A return always 1 */ ++ return 1; ++} ++ ++/* Start HIF rx DMA ++ * ++ */ ++static inline void hif_rx_dma_start(void) ++{ ++ writel(HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB, HIF_RX_CTRL); ++} ++ ++/* Start HIF tx DMA ++ * ++ */ ++static inline void hif_tx_dma_start(void) ++{ ++ writel(HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB, HIF_TX_CTRL); ++} ++ ++#endif /* _PFE_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_ctrl.c +@@ -0,0 +1,238 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "pfe_mod.h" ++#include "pfe_ctrl.h" ++ ++#define TIMEOUT_MS 1000 ++ ++int relax(unsigned long end) ++{ ++ if (time_after(jiffies, end)) { ++ if (time_after(jiffies, end + (TIMEOUT_MS * HZ) / 1000)) ++ return -1; ++ ++ if (need_resched()) ++ schedule(); ++ } ++ ++ return 0; ++} ++ ++void pfe_ctrl_suspend(struct pfe_ctrl *ctrl) ++{ ++ int id; ++ ++ mutex_lock(&ctrl->mutex); ++ ++ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) ++ pe_dmem_write(id, cpu_to_be32(0x1), CLASS_DM_RESUME, 4); ++ ++ for (id = TMU0_ID; id <= TMU_MAX_ID; id++) { ++ if (id == TMU2_ID) ++ continue; ++ pe_dmem_write(id, cpu_to_be32(0x1), TMU_DM_RESUME, 4); ++ } ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ pe_dmem_write(UTIL_ID, cpu_to_be32(0x1), UTIL_DM_RESUME, 4); ++#endif ++ mutex_unlock(&ctrl->mutex); ++} ++ ++void pfe_ctrl_resume(struct pfe_ctrl *ctrl) ++{ ++ int pe_mask = CLASS_MASK | TMU_MASK; ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ pe_mask |= UTIL_MASK; ++#endif ++ mutex_lock(&ctrl->mutex); ++ pe_start(&pfe->ctrl, pe_mask); ++ mutex_unlock(&ctrl->mutex); ++} ++ ++/* PE sync stop. ++ * Stops packet processing for a list of PE's (specified using a bitmask). ++ * The caller must hold ctrl->mutex. ++ * ++ * @param ctrl Control context ++ * @param pe_mask Mask of PE id's to stop ++ * ++ */ ++int pe_sync_stop(struct pfe_ctrl *ctrl, int pe_mask) ++{ ++ struct pe_sync_mailbox *mbox; ++ int pe_stopped = 0; ++ unsigned long end = jiffies + 2; ++ int i; ++ ++ pe_mask &= 0x2FF; /*Exclude Util + TMU2 */ ++ ++ for (i = 0; i < MAX_PE; i++) ++ if (pe_mask & (1 << i)) { ++ mbox = (void *)ctrl->sync_mailbox_baseaddr[i]; ++ ++ pe_dmem_write(i, cpu_to_be32(0x1), (unsigned ++ long)&mbox->stop, 4); ++ } ++ ++ while (pe_stopped != pe_mask) { ++ for (i = 0; i < MAX_PE; i++) ++ if ((pe_mask & (1 << i)) && !(pe_stopped & (1 << i))) { ++ mbox = (void *)ctrl->sync_mailbox_baseaddr[i]; ++ ++ if (pe_dmem_read(i, (unsigned ++ long)&mbox->stopped, 4) & ++ cpu_to_be32(0x1)) ++ pe_stopped |= (1 << i); ++ } ++ ++ if (relax(end) < 0) ++ goto err; ++ } ++ ++ return 0; ++ ++err: ++ pr_err("%s: timeout, %x %x\n", __func__, pe_mask, pe_stopped); ++ ++ for (i = 0; i < MAX_PE; i++) ++ if (pe_mask & (1 << i)) { ++ mbox = (void *)ctrl->sync_mailbox_baseaddr[i]; ++ ++ pe_dmem_write(i, cpu_to_be32(0x0), (unsigned ++ long)&mbox->stop, 4); ++ } ++ ++ return -EIO; ++} ++ ++/* PE start. ++ * Starts packet processing for a list of PE's (specified using a bitmask). ++ * The caller must hold ctrl->mutex. ++ * ++ * @param ctrl Control context ++ * @param pe_mask Mask of PE id's to start ++ * ++ */ ++void pe_start(struct pfe_ctrl *ctrl, int pe_mask) ++{ ++ struct pe_sync_mailbox *mbox; ++ int i; ++ ++ for (i = 0; i < MAX_PE; i++) ++ if (pe_mask & (1 << i)) { ++ mbox = (void *)ctrl->sync_mailbox_baseaddr[i]; ++ ++ pe_dmem_write(i, cpu_to_be32(0x0), (unsigned ++ long)&mbox->stop, 4); ++ } ++} ++ ++/* This function will ensure all PEs are put in to idle state */ ++int pe_reset_all(struct pfe_ctrl *ctrl) ++{ ++ struct pe_sync_mailbox *mbox; ++ int pe_stopped = 0; ++ unsigned long end = jiffies + 2; ++ int i; ++ int pe_mask = CLASS_MASK | TMU_MASK; ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ pe_mask |= UTIL_MASK; ++#endif ++ ++ for (i = 0; i < MAX_PE; i++) ++ if (pe_mask & (1 << i)) { ++ mbox = (void *)ctrl->sync_mailbox_baseaddr[i]; ++ ++ pe_dmem_write(i, cpu_to_be32(0x2), (unsigned ++ long)&mbox->stop, 4); ++ } ++ ++ while (pe_stopped != pe_mask) { ++ for (i = 0; i < MAX_PE; i++) ++ if ((pe_mask & (1 << i)) && !(pe_stopped & (1 << i))) { ++ mbox = (void *)ctrl->sync_mailbox_baseaddr[i]; ++ ++ if (pe_dmem_read(i, (unsigned long) ++ &mbox->stopped, 4) & ++ cpu_to_be32(0x1)) ++ pe_stopped |= (1 << i); ++ } ++ ++ if (relax(end) < 0) ++ goto err; ++ } ++ ++ return 0; ++ ++err: ++ pr_err("%s: timeout, %x %x\n", __func__, pe_mask, pe_stopped); ++ return -EIO; ++} ++ ++int pfe_ctrl_init(struct pfe *pfe) ++{ ++ struct pfe_ctrl *ctrl = &pfe->ctrl; ++ int id; ++ ++ pr_info("%s\n", __func__); ++ ++ mutex_init(&ctrl->mutex); ++ spin_lock_init(&ctrl->lock); ++ ++ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) { ++ ctrl->sync_mailbox_baseaddr[id] = CLASS_DM_SYNC_MBOX; ++ ctrl->msg_mailbox_baseaddr[id] = CLASS_DM_MSG_MBOX; ++ } ++ ++ for (id = TMU0_ID; id <= TMU_MAX_ID; id++) { ++ if (id == TMU2_ID) ++ continue; ++ ctrl->sync_mailbox_baseaddr[id] = TMU_DM_SYNC_MBOX; ++ ctrl->msg_mailbox_baseaddr[id] = TMU_DM_MSG_MBOX; ++ } ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ ctrl->sync_mailbox_baseaddr[UTIL_ID] = UTIL_DM_SYNC_MBOX; ++ ctrl->msg_mailbox_baseaddr[UTIL_ID] = UTIL_DM_MSG_MBOX; ++#endif ++ ++ ctrl->hash_array_baseaddr = pfe->ddr_baseaddr + ROUTE_TABLE_BASEADDR; ++ ctrl->hash_array_phys_baseaddr = pfe->ddr_phys_baseaddr + ++ ROUTE_TABLE_BASEADDR; ++ ++ ctrl->dev = pfe->dev; ++ ++ pr_info("%s finished\n", __func__); ++ ++ return 0; ++} ++ ++void pfe_ctrl_exit(struct pfe *pfe) ++{ ++ pr_info("%s\n", __func__); ++} +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_ctrl.h +@@ -0,0 +1,112 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _PFE_CTRL_H_ ++#define _PFE_CTRL_H_ ++ ++#include ++ ++#include "pfe_mod.h" ++#include "pfe/pfe.h" ++ ++#define DMA_BUF_SIZE_128 0x80 /* enough for 1 conntracks */ ++#define DMA_BUF_SIZE_256 0x100 ++/* enough for 2 conntracks, 1 bridge entry or 1 multicast entry */ ++#define DMA_BUF_SIZE_512 0x200 ++/* 512bytes dma allocated buffers used by rtp relay feature */ ++#define DMA_BUF_MIN_ALIGNMENT 8 ++#define DMA_BUF_BOUNDARY (4 * 1024) ++/* bursts can not cross 4k boundary */ ++ ++#define CMD_TX_ENABLE 0x0501 ++#define CMD_TX_DISABLE 0x0502 ++ ++#define CMD_RX_LRO 0x0011 ++#define CMD_PKTCAP_ENABLE 0x0d01 ++#define CMD_QM_EXPT_RATE 0x020c ++ ++#define CLASS_DM_SH_STATIC (0x800) ++#define CLASS_DM_CPU_TICKS (CLASS_DM_SH_STATIC) ++#define CLASS_DM_SYNC_MBOX (0x808) ++#define CLASS_DM_MSG_MBOX (0x810) ++#define CLASS_DM_DROP_CNTR (0x820) ++#define CLASS_DM_RESUME (0x854) ++#define CLASS_DM_PESTATUS (0x860) ++ ++#define TMU_DM_SH_STATIC (0x80) ++#define TMU_DM_CPU_TICKS (TMU_DM_SH_STATIC) ++#define TMU_DM_SYNC_MBOX (0x88) ++#define TMU_DM_MSG_MBOX (0x90) ++#define TMU_DM_RESUME (0xA0) ++#define TMU_DM_PESTATUS (0xB0) ++#define TMU_DM_CONTEXT (0x300) ++#define TMU_DM_TX_TRANS (0x480) ++ ++#define UTIL_DM_SH_STATIC (0x0) ++#define UTIL_DM_CPU_TICKS (UTIL_DM_SH_STATIC) ++#define UTIL_DM_SYNC_MBOX (0x8) ++#define UTIL_DM_MSG_MBOX (0x10) ++#define UTIL_DM_DROP_CNTR (0x20) ++#define UTIL_DM_RESUME (0x40) ++#define UTIL_DM_PESTATUS (0x50) ++ ++struct pfe_ctrl { ++ struct mutex mutex; /* to serialize pfe control access */ ++ spinlock_t lock; ++ ++ void *dma_pool; ++ void *dma_pool_512; ++ void *dma_pool_128; ++ ++ struct device *dev; ++ ++ void *hash_array_baseaddr; /* ++ * Virtual base address of ++ * the conntrack hash array ++ */ ++ unsigned long hash_array_phys_baseaddr; /* ++ * Physical base address of ++ * the conntrack hash array ++ */ ++ ++ int (*event_cb)(u16, u16, u16*); ++ ++ unsigned long sync_mailbox_baseaddr[MAX_PE]; /* ++ * Sync mailbox PFE ++ * internal address, ++ * initialized ++ * when parsing elf images ++ */ ++ unsigned long msg_mailbox_baseaddr[MAX_PE]; /* ++ * Msg mailbox PFE internal ++ * address, initialized ++ * when parsing elf images ++ */ ++ unsigned int sys_clk; /* AXI clock value, in KHz */ ++}; ++ ++int pfe_ctrl_init(struct pfe *pfe); ++void pfe_ctrl_exit(struct pfe *pfe); ++int pe_sync_stop(struct pfe_ctrl *ctrl, int pe_mask); ++void pe_start(struct pfe_ctrl *ctrl, int pe_mask); ++int pe_reset_all(struct pfe_ctrl *ctrl); ++void pfe_ctrl_suspend(struct pfe_ctrl *ctrl); ++void pfe_ctrl_resume(struct pfe_ctrl *ctrl); ++int relax(unsigned long end); ++ ++#endif /* _PFE_CTRL_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_debugfs.c +@@ -0,0 +1,111 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#include ++#include ++#include ++ ++#include "pfe_mod.h" ++ ++static int dmem_show(struct seq_file *s, void *unused) ++{ ++ u32 dmem_addr, val; ++ int id = (long int)s->private; ++ int i; ++ ++ for (dmem_addr = 0; dmem_addr < CLASS_DMEM_SIZE; dmem_addr += 8 * 4) { ++ seq_printf(s, "%04x:", dmem_addr); ++ ++ for (i = 0; i < 8; i++) { ++ val = pe_dmem_read(id, dmem_addr + i * 4, 4); ++ seq_printf(s, " %02x %02x %02x %02x", val & 0xff, ++ (val >> 8) & 0xff, (val >> 16) & 0xff, ++ (val >> 24) & 0xff); ++ } ++ ++ seq_puts(s, "\n"); ++ } ++ ++ return 0; ++} ++ ++static int dmem_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, dmem_show, inode->i_private); ++} ++ ++static const struct file_operations dmem_fops = { ++ .open = dmem_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++int pfe_debugfs_init(struct pfe *pfe) ++{ ++ struct dentry *d; ++ ++ pr_info("%s\n", __func__); ++ ++ pfe->dentry = debugfs_create_dir("pfe", NULL); ++ if (IS_ERR_OR_NULL(pfe->dentry)) ++ goto err_dir; ++ ++ d = debugfs_create_file("pe0_dmem", 0444, pfe->dentry, (void *)0, ++ &dmem_fops); ++ if (IS_ERR_OR_NULL(d)) ++ goto err_pe; ++ ++ d = debugfs_create_file("pe1_dmem", 0444, pfe->dentry, (void *)1, ++ &dmem_fops); ++ if (IS_ERR_OR_NULL(d)) ++ goto err_pe; ++ ++ d = debugfs_create_file("pe2_dmem", 0444, pfe->dentry, (void *)2, ++ &dmem_fops); ++ if (IS_ERR_OR_NULL(d)) ++ goto err_pe; ++ ++ d = debugfs_create_file("pe3_dmem", 0444, pfe->dentry, (void *)3, ++ &dmem_fops); ++ if (IS_ERR_OR_NULL(d)) ++ goto err_pe; ++ ++ d = debugfs_create_file("pe4_dmem", 0444, pfe->dentry, (void *)4, ++ &dmem_fops); ++ if (IS_ERR_OR_NULL(d)) ++ goto err_pe; ++ ++ d = debugfs_create_file("pe5_dmem", 0444, pfe->dentry, (void *)5, ++ &dmem_fops); ++ if (IS_ERR_OR_NULL(d)) ++ goto err_pe; ++ ++ return 0; ++ ++err_pe: ++ debugfs_remove_recursive(pfe->dentry); ++ ++err_dir: ++ return -1; ++} ++ ++void pfe_debugfs_exit(struct pfe *pfe) ++{ ++ debugfs_remove_recursive(pfe->dentry); ++} +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_debugfs.h +@@ -0,0 +1,25 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _PFE_DEBUGFS_H_ ++#define _PFE_DEBUGFS_H_ ++ ++int pfe_debugfs_init(struct pfe *pfe); ++void pfe_debugfs_exit(struct pfe *pfe); ++ ++#endif /* _PFE_DEBUGFS_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_eth.c +@@ -0,0 +1,2434 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++/* @pfe_eth.c. ++ * Ethernet driver for to handle exception path for PFE. ++ * - uses HIF functions to send/receive packets. ++ * - uses ctrl function to start/stop interfaces. ++ * - uses direct register accesses to control phy operation. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#if defined(CONFIG_NF_CONNTRACK_MARK) ++#include ++#endif ++ ++#include "pfe_mod.h" ++#include "pfe_eth.h" ++ ++static void *cbus_emac_base[3]; ++static void *cbus_gpi_base[3]; ++ ++/* Forward Declaration */ ++static void pfe_eth_exit_one(struct pfe_eth_priv_s *priv); ++static void pfe_eth_flush_tx(struct pfe_eth_priv_s *priv); ++static void pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int ++ from_tx, int n_desc); ++ ++unsigned int gemac_regs[] = { ++ 0x0004, /* Interrupt event */ ++ 0x0008, /* Interrupt mask */ ++ 0x0024, /* Ethernet control */ ++ 0x0064, /* MIB Control/Status */ ++ 0x0084, /* Receive control/status */ ++ 0x00C4, /* Transmit control */ ++ 0x00E4, /* Physical address low */ ++ 0x00E8, /* Physical address high */ ++ 0x0144, /* Transmit FIFO Watermark and Store and Forward Control*/ ++ 0x0190, /* Receive FIFO Section Full Threshold */ ++ 0x01A0, /* Transmit FIFO Section Empty Threshold */ ++ 0x01B0, /* Frame Truncation Length */ ++}; ++ ++/********************************************************************/ ++/* SYSFS INTERFACE */ ++/********************************************************************/ ++ ++#ifdef PFE_ETH_NAPI_STATS ++/* ++ * pfe_eth_show_napi_stats ++ */ ++static ssize_t pfe_eth_show_napi_stats(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev)); ++ ssize_t len = 0; ++ ++ len += sprintf(buf + len, "sched: %u\n", ++ priv->napi_counters[NAPI_SCHED_COUNT]); ++ len += sprintf(buf + len, "poll: %u\n", ++ priv->napi_counters[NAPI_POLL_COUNT]); ++ len += sprintf(buf + len, "packet: %u\n", ++ priv->napi_counters[NAPI_PACKET_COUNT]); ++ len += sprintf(buf + len, "budget: %u\n", ++ priv->napi_counters[NAPI_FULL_BUDGET_COUNT]); ++ len += sprintf(buf + len, "desc: %u\n", ++ priv->napi_counters[NAPI_DESC_COUNT]); ++ ++ return len; ++} ++ ++/* ++ * pfe_eth_set_napi_stats ++ */ ++static ssize_t pfe_eth_set_napi_stats(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev)); ++ ++ memset(priv->napi_counters, 0, sizeof(priv->napi_counters)); ++ ++ return count; ++} ++#endif ++#ifdef PFE_ETH_TX_STATS ++/* pfe_eth_show_tx_stats ++ * ++ */ ++static ssize_t pfe_eth_show_tx_stats(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev)); ++ ssize_t len = 0; ++ int i; ++ ++ len += sprintf(buf + len, "TX queues stats:\n"); ++ ++ for (i = 0; i < emac_txq_cnt; i++) { ++ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev, ++ i); ++ ++ len += sprintf(buf + len, "\n"); ++ __netif_tx_lock_bh(tx_queue); ++ ++ hif_tx_lock(&pfe->hif); ++ len += sprintf(buf + len, ++ "Queue %2d : credits = %10d\n" ++ , i, hif_lib_tx_credit_avail(pfe, priv->id, i)); ++ len += sprintf(buf + len, ++ " tx packets = %10d\n" ++ , pfe->tmu_credit.tx_packets[priv->id][i]); ++ hif_tx_unlock(&pfe->hif); ++ ++ /* Don't output additionnal stats if queue never used */ ++ if (!pfe->tmu_credit.tx_packets[priv->id][i]) ++ goto skip; ++ ++ len += sprintf(buf + len, ++ " clean_fail = %10d\n" ++ , priv->clean_fail[i]); ++ len += sprintf(buf + len, ++ " stop_queue = %10d\n" ++ , priv->stop_queue_total[i]); ++ len += sprintf(buf + len, ++ " stop_queue_hif = %10d\n" ++ , priv->stop_queue_hif[i]); ++ len += sprintf(buf + len, ++ " stop_queue_hif_client = %10d\n" ++ , priv->stop_queue_hif_client[i]); ++ len += sprintf(buf + len, ++ " stop_queue_credit = %10d\n" ++ , priv->stop_queue_credit[i]); ++skip: ++ __netif_tx_unlock_bh(tx_queue); ++ } ++ return len; ++} ++ ++/* pfe_eth_set_tx_stats ++ * ++ */ ++static ssize_t pfe_eth_set_tx_stats(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev)); ++ int i; ++ ++ for (i = 0; i < emac_txq_cnt; i++) { ++ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev, ++ i); ++ ++ __netif_tx_lock_bh(tx_queue); ++ priv->clean_fail[i] = 0; ++ priv->stop_queue_total[i] = 0; ++ priv->stop_queue_hif[i] = 0; ++ priv->stop_queue_hif_client[i] = 0; ++ priv->stop_queue_credit[i] = 0; ++ __netif_tx_unlock_bh(tx_queue); ++ } ++ ++ return count; ++} ++#endif ++/* pfe_eth_show_txavail ++ * ++ */ ++static ssize_t pfe_eth_show_txavail(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev)); ++ ssize_t len = 0; ++ int i; ++ ++ for (i = 0; i < emac_txq_cnt; i++) { ++ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev, ++ i); ++ ++ __netif_tx_lock_bh(tx_queue); ++ ++ len += sprintf(buf + len, "%d", ++ hif_lib_tx_avail(&priv->client, i)); ++ ++ __netif_tx_unlock_bh(tx_queue); ++ ++ if (i == (emac_txq_cnt - 1)) ++ len += sprintf(buf + len, "\n"); ++ else ++ len += sprintf(buf + len, " "); ++ } ++ ++ return len; ++} ++ ++/* pfe_eth_show_default_priority ++ * ++ */ ++static ssize_t pfe_eth_show_default_priority(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev)); ++ unsigned long flags; ++ int rc; ++ ++ spin_lock_irqsave(&priv->lock, flags); ++ rc = sprintf(buf, "%d\n", priv->default_priority); ++ spin_unlock_irqrestore(&priv->lock, flags); ++ ++ return rc; ++} ++ ++/* pfe_eth_set_default_priority ++ * ++ */ ++ ++static ssize_t pfe_eth_set_default_priority(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev)); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&priv->lock, flags); ++ priv->default_priority = kstrtoul(buf, 0, 0); ++ spin_unlock_irqrestore(&priv->lock, flags); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(txavail, 0444, pfe_eth_show_txavail, NULL); ++static DEVICE_ATTR(default_priority, 0644, pfe_eth_show_default_priority, ++ pfe_eth_set_default_priority); ++ ++#ifdef PFE_ETH_NAPI_STATS ++static DEVICE_ATTR(napi_stats, 0644, pfe_eth_show_napi_stats, ++ pfe_eth_set_napi_stats); ++#endif ++ ++#ifdef PFE_ETH_TX_STATS ++static DEVICE_ATTR(tx_stats, 0644, pfe_eth_show_tx_stats, ++ pfe_eth_set_tx_stats); ++#endif ++ ++/* ++ * pfe_eth_sysfs_init ++ * ++ */ ++static int pfe_eth_sysfs_init(struct net_device *ndev) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ int err; ++ ++ /* Initialize the default values */ ++ ++ /* ++ * By default, packets without conntrack will use this default high ++ * priority queue ++ */ ++ priv->default_priority = 15; ++ ++ /* Create our sysfs files */ ++ err = device_create_file(&ndev->dev, &dev_attr_default_priority); ++ if (err) { ++ netdev_err(ndev, ++ "failed to create default_priority sysfs files\n"); ++ goto err_priority; ++ } ++ ++ err = device_create_file(&ndev->dev, &dev_attr_txavail); ++ if (err) { ++ netdev_err(ndev, ++ "failed to create default_priority sysfs files\n"); ++ goto err_txavail; ++ } ++ ++#ifdef PFE_ETH_NAPI_STATS ++ err = device_create_file(&ndev->dev, &dev_attr_napi_stats); ++ if (err) { ++ netdev_err(ndev, "failed to create napi stats sysfs files\n"); ++ goto err_napi; ++ } ++#endif ++ ++#ifdef PFE_ETH_TX_STATS ++ err = device_create_file(&ndev->dev, &dev_attr_tx_stats); ++ if (err) { ++ netdev_err(ndev, "failed to create tx stats sysfs files\n"); ++ goto err_tx; ++ } ++#endif ++ ++ return 0; ++ ++#ifdef PFE_ETH_TX_STATS ++err_tx: ++#endif ++#ifdef PFE_ETH_NAPI_STATS ++ device_remove_file(&ndev->dev, &dev_attr_napi_stats); ++ ++err_napi: ++#endif ++ device_remove_file(&ndev->dev, &dev_attr_txavail); ++ ++err_txavail: ++ device_remove_file(&ndev->dev, &dev_attr_default_priority); ++ ++err_priority: ++ return -1; ++} ++ ++/* pfe_eth_sysfs_exit ++ * ++ */ ++void pfe_eth_sysfs_exit(struct net_device *ndev) ++{ ++#ifdef PFE_ETH_TX_STATS ++ device_remove_file(&ndev->dev, &dev_attr_tx_stats); ++#endif ++ ++#ifdef PFE_ETH_NAPI_STATS ++ device_remove_file(&ndev->dev, &dev_attr_napi_stats); ++#endif ++ device_remove_file(&ndev->dev, &dev_attr_txavail); ++ device_remove_file(&ndev->dev, &dev_attr_default_priority); ++} ++ ++/*************************************************************************/ ++/* ETHTOOL INTERCAE */ ++/*************************************************************************/ ++ ++/*MTIP GEMAC */ ++static const struct fec_stat { ++ char name[ETH_GSTRING_LEN]; ++ u16 offset; ++} fec_stats[] = { ++ /* RMON TX */ ++ { "tx_dropped", RMON_T_DROP }, ++ { "tx_packets", RMON_T_PACKETS }, ++ { "tx_broadcast", RMON_T_BC_PKT }, ++ { "tx_multicast", RMON_T_MC_PKT }, ++ { "tx_crc_errors", RMON_T_CRC_ALIGN }, ++ { "tx_undersize", RMON_T_UNDERSIZE }, ++ { "tx_oversize", RMON_T_OVERSIZE }, ++ { "tx_fragment", RMON_T_FRAG }, ++ { "tx_jabber", RMON_T_JAB }, ++ { "tx_collision", RMON_T_COL }, ++ { "tx_64byte", RMON_T_P64 }, ++ { "tx_65to127byte", RMON_T_P65TO127 }, ++ { "tx_128to255byte", RMON_T_P128TO255 }, ++ { "tx_256to511byte", RMON_T_P256TO511 }, ++ { "tx_512to1023byte", RMON_T_P512TO1023 }, ++ { "tx_1024to2047byte", RMON_T_P1024TO2047 }, ++ { "tx_GTE2048byte", RMON_T_P_GTE2048 }, ++ { "tx_octets", RMON_T_OCTETS }, ++ ++ /* IEEE TX */ ++ { "IEEE_tx_drop", IEEE_T_DROP }, ++ { "IEEE_tx_frame_ok", IEEE_T_FRAME_OK }, ++ { "IEEE_tx_1col", IEEE_T_1COL }, ++ { "IEEE_tx_mcol", IEEE_T_MCOL }, ++ { "IEEE_tx_def", IEEE_T_DEF }, ++ { "IEEE_tx_lcol", IEEE_T_LCOL }, ++ { "IEEE_tx_excol", IEEE_T_EXCOL }, ++ { "IEEE_tx_macerr", IEEE_T_MACERR }, ++ { "IEEE_tx_cserr", IEEE_T_CSERR }, ++ { "IEEE_tx_sqe", IEEE_T_SQE }, ++ { "IEEE_tx_fdxfc", IEEE_T_FDXFC }, ++ { "IEEE_tx_octets_ok", IEEE_T_OCTETS_OK }, ++ ++ /* RMON RX */ ++ { "rx_packets", RMON_R_PACKETS }, ++ { "rx_broadcast", RMON_R_BC_PKT }, ++ { "rx_multicast", RMON_R_MC_PKT }, ++ { "rx_crc_errors", RMON_R_CRC_ALIGN }, ++ { "rx_undersize", RMON_R_UNDERSIZE }, ++ { "rx_oversize", RMON_R_OVERSIZE }, ++ { "rx_fragment", RMON_R_FRAG }, ++ { "rx_jabber", RMON_R_JAB }, ++ { "rx_64byte", RMON_R_P64 }, ++ { "rx_65to127byte", RMON_R_P65TO127 }, ++ { "rx_128to255byte", RMON_R_P128TO255 }, ++ { "rx_256to511byte", RMON_R_P256TO511 }, ++ { "rx_512to1023byte", RMON_R_P512TO1023 }, ++ { "rx_1024to2047byte", RMON_R_P1024TO2047 }, ++ { "rx_GTE2048byte", RMON_R_P_GTE2048 }, ++ { "rx_octets", RMON_R_OCTETS }, ++ ++ /* IEEE RX */ ++ { "IEEE_rx_drop", IEEE_R_DROP }, ++ { "IEEE_rx_frame_ok", IEEE_R_FRAME_OK }, ++ { "IEEE_rx_crc", IEEE_R_CRC }, ++ { "IEEE_rx_align", IEEE_R_ALIGN }, ++ { "IEEE_rx_macerr", IEEE_R_MACERR }, ++ { "IEEE_rx_fdxfc", IEEE_R_FDXFC }, ++ { "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK }, ++}; ++ ++static void pfe_eth_fill_stats(struct net_device *ndev, struct ethtool_stats ++ *stats, u64 *data) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(fec_stats); i++) ++ data[i] = readl(priv->EMAC_baseaddr + fec_stats[i].offset); ++} ++ ++static void pfe_eth_gstrings(struct net_device *netdev, ++ u32 stringset, u8 *data) ++{ ++ int i; ++ ++ switch (stringset) { ++ case ETH_SS_STATS: ++ for (i = 0; i < ARRAY_SIZE(fec_stats); i++) ++ memcpy(data + i * ETH_GSTRING_LEN, ++ fec_stats[i].name, ETH_GSTRING_LEN); ++ break; ++ } ++} ++ ++static int pfe_eth_stats_count(struct net_device *ndev, int sset) ++{ ++ switch (sset) { ++ case ETH_SS_STATS: ++ return ARRAY_SIZE(fec_stats); ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ ++/* ++ * pfe_eth_gemac_reglen - Return the length of the register structure. ++ * ++ */ ++static int pfe_eth_gemac_reglen(struct net_device *ndev) ++{ ++ pr_info("%s()\n", __func__); ++ return (sizeof(gemac_regs) / sizeof(u32)); ++} ++ ++/* ++ * pfe_eth_gemac_get_regs - Return the gemac register structure. ++ * ++ */ ++static void pfe_eth_gemac_get_regs(struct net_device *ndev, struct ethtool_regs ++ *regs, void *regbuf) ++{ ++ int i; ++ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ u32 *buf = (u32 *)regbuf; ++ ++ pr_info("%s()\n", __func__); ++ for (i = 0; i < sizeof(gemac_regs) / sizeof(u32); i++) ++ buf[i] = readl(priv->EMAC_baseaddr + gemac_regs[i]); ++} ++ ++/* ++ * pfe_eth_set_wol - Set the magic packet option, in WoL register. ++ * ++ */ ++static int pfe_eth_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ ++ if (wol->wolopts & ~WAKE_MAGIC) ++ return -EOPNOTSUPP; ++ ++ /* for MTIP we store wol->wolopts */ ++ priv->wol = wol->wolopts; ++ ++ device_set_wakeup_enable(&ndev->dev, wol->wolopts & WAKE_MAGIC); ++ ++ return 0; ++} ++ ++/* ++ * ++ * pfe_eth_get_wol - Get the WoL options. ++ * ++ */ ++static void pfe_eth_get_wol(struct net_device *ndev, struct ethtool_wolinfo ++ *wol) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ ++ wol->supported = WAKE_MAGIC; ++ wol->wolopts = 0; ++ ++ if (priv->wol & WAKE_MAGIC) ++ wol->wolopts = WAKE_MAGIC; ++ ++ memset(&wol->sopass, 0, sizeof(wol->sopass)); ++} ++ ++/* ++ * pfe_eth_get_drvinfo - Fills in the drvinfo structure with some basic info ++ * ++ */ ++static void pfe_eth_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo ++ *drvinfo) ++{ ++ strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); ++ strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); ++ strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); ++ strlcpy(drvinfo->bus_info, "N/A", sizeof(drvinfo->bus_info)); ++} ++ ++/* ++ * pfe_eth_set_settings - Used to send commands to PHY. ++ * ++ */ ++static int pfe_eth_set_settings(struct net_device *ndev, ++ const struct ethtool_link_ksettings *cmd) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ struct phy_device *phydev = priv->phydev; ++ ++ if (!phydev) ++ return -ENODEV; ++ ++ return phy_ethtool_ksettings_set(phydev, cmd); ++} ++ ++/* ++ * pfe_eth_getsettings - Return the current settings in the ethtool_cmd ++ * structure. ++ * ++ */ ++static int pfe_eth_get_settings(struct net_device *ndev, ++ struct ethtool_link_ksettings *cmd) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ struct phy_device *phydev = priv->phydev; ++ ++ if (!phydev) ++ return -ENODEV; ++ ++ return phy_ethtool_ksettings_get(phydev, cmd); ++} ++ ++/* ++ * pfe_eth_get_msglevel - Gets the debug message mask. ++ * ++ */ ++static uint32_t pfe_eth_get_msglevel(struct net_device *ndev) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ ++ return priv->msg_enable; ++} ++ ++/* ++ * pfe_eth_set_msglevel - Sets the debug message mask. ++ * ++ */ ++static void pfe_eth_set_msglevel(struct net_device *ndev, uint32_t data) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ ++ priv->msg_enable = data; ++} ++ ++#define HIF_RX_COAL_MAX_CLKS (~(1 << 31)) ++#define HIF_RX_COAL_CLKS_PER_USEC (pfe->ctrl.sys_clk / 1000) ++#define HIF_RX_COAL_MAX_USECS (HIF_RX_COAL_MAX_CLKS / \ ++ HIF_RX_COAL_CLKS_PER_USEC) ++ ++/* ++ * pfe_eth_set_coalesce - Sets rx interrupt coalescing timer. ++ * ++ */ ++static int pfe_eth_set_coalesce(struct net_device *ndev, ++ struct ethtool_coalesce *ec) ++{ ++ if (ec->rx_coalesce_usecs > HIF_RX_COAL_MAX_USECS) ++ return -EINVAL; ++ ++ if (!ec->rx_coalesce_usecs) { ++ writel(0, HIF_INT_COAL); ++ return 0; ++ } ++ ++ writel((ec->rx_coalesce_usecs * HIF_RX_COAL_CLKS_PER_USEC) | ++ HIF_INT_COAL_ENABLE, HIF_INT_COAL); ++ ++ return 0; ++} ++ ++/* ++ * pfe_eth_get_coalesce - Gets rx interrupt coalescing timer value. ++ * ++ */ ++static int pfe_eth_get_coalesce(struct net_device *ndev, ++ struct ethtool_coalesce *ec) ++{ ++ int reg_val = readl(HIF_INT_COAL); ++ ++ if (reg_val & HIF_INT_COAL_ENABLE) ++ ec->rx_coalesce_usecs = (reg_val & HIF_RX_COAL_MAX_CLKS) / ++ HIF_RX_COAL_CLKS_PER_USEC; ++ else ++ ec->rx_coalesce_usecs = 0; ++ ++ return 0; ++} ++ ++/* ++ * pfe_eth_set_pauseparam - Sets pause parameters ++ * ++ */ ++static int pfe_eth_set_pauseparam(struct net_device *ndev, ++ struct ethtool_pauseparam *epause) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ ++ if (epause->tx_pause != epause->rx_pause) { ++ netdev_info(ndev, ++ "hardware only support enable/disable both tx and rx\n"); ++ return -EINVAL; ++ } ++ ++ priv->pause_flag = 0; ++ priv->pause_flag |= epause->rx_pause ? PFE_PAUSE_FLAG_ENABLE : 0; ++ priv->pause_flag |= epause->autoneg ? PFE_PAUSE_FLAG_AUTONEG : 0; ++ ++ if (epause->rx_pause || epause->autoneg) { ++ gemac_enable_pause_rx(priv->EMAC_baseaddr); ++ writel((readl(priv->GPI_baseaddr + GPI_TX_PAUSE_TIME) | ++ EGPI_PAUSE_ENABLE), ++ priv->GPI_baseaddr + GPI_TX_PAUSE_TIME); ++ if (priv->phydev) { ++ priv->phydev->supported |= ADVERTISED_Pause | ++ ADVERTISED_Asym_Pause; ++ priv->phydev->advertising |= ADVERTISED_Pause | ++ ADVERTISED_Asym_Pause; ++ } ++ } else { ++ gemac_disable_pause_rx(priv->EMAC_baseaddr); ++ writel((readl(priv->GPI_baseaddr + GPI_TX_PAUSE_TIME) & ++ ~EGPI_PAUSE_ENABLE), ++ priv->GPI_baseaddr + GPI_TX_PAUSE_TIME); ++ if (priv->phydev) { ++ priv->phydev->supported &= ~(ADVERTISED_Pause | ++ ADVERTISED_Asym_Pause); ++ priv->phydev->advertising &= ~(ADVERTISED_Pause | ++ ADVERTISED_Asym_Pause); ++ } ++ } ++ ++ return 0; ++} ++ ++/* ++ * pfe_eth_get_pauseparam - Gets pause parameters ++ * ++ */ ++static void pfe_eth_get_pauseparam(struct net_device *ndev, ++ struct ethtool_pauseparam *epause) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ ++ epause->autoneg = (priv->pause_flag & PFE_PAUSE_FLAG_AUTONEG) != 0; ++ epause->tx_pause = (priv->pause_flag & PFE_PAUSE_FLAG_ENABLE) != 0; ++ epause->rx_pause = epause->tx_pause; ++} ++ ++/* ++ * pfe_eth_get_hash ++ */ ++#define PFE_HASH_BITS 6 /* #bits in hash */ ++#define CRC32_POLY 0xEDB88320 ++ ++static int pfe_eth_get_hash(u8 *addr) ++{ ++ unsigned int i, bit, data, crc, hash; ++ ++ /* calculate crc32 value of mac address */ ++ crc = 0xffffffff; ++ ++ for (i = 0; i < 6; i++) { ++ data = addr[i]; ++ for (bit = 0; bit < 8; bit++, data >>= 1) { ++ crc = (crc >> 1) ^ ++ (((crc ^ data) & 1) ? CRC32_POLY : 0); ++ } ++ } ++ ++ /* ++ * only upper 6 bits (PFE_HASH_BITS) are used ++ * which point to specific bit in the hash registers ++ */ ++ hash = (crc >> (32 - PFE_HASH_BITS)) & 0x3f; ++ ++ return hash; ++} ++ ++const struct ethtool_ops pfe_ethtool_ops = { ++ .get_drvinfo = pfe_eth_get_drvinfo, ++ .get_regs_len = pfe_eth_gemac_reglen, ++ .get_regs = pfe_eth_gemac_get_regs, ++ .get_link = ethtool_op_get_link, ++ .get_wol = pfe_eth_get_wol, ++ .set_wol = pfe_eth_set_wol, ++ .set_pauseparam = pfe_eth_set_pauseparam, ++ .get_pauseparam = pfe_eth_get_pauseparam, ++ .get_strings = pfe_eth_gstrings, ++ .get_sset_count = pfe_eth_stats_count, ++ .get_ethtool_stats = pfe_eth_fill_stats, ++ .get_msglevel = pfe_eth_get_msglevel, ++ .set_msglevel = pfe_eth_set_msglevel, ++ .set_coalesce = pfe_eth_set_coalesce, ++ .get_coalesce = pfe_eth_get_coalesce, ++ .get_link_ksettings = pfe_eth_get_settings, ++ .set_link_ksettings = pfe_eth_set_settings, ++}; ++ ++/* pfe_eth_mdio_reset ++ */ ++int pfe_eth_mdio_reset(struct mii_bus *bus) ++{ ++ struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv; ++ u32 phy_speed; ++ ++ netif_info(priv, hw, priv->ndev, "%s\n", __func__); ++ ++ mutex_lock(&bus->mdio_lock); ++ ++ /* ++ * Set MII speed to 2.5 MHz (= clk_get_rate() / 2 * phy_speed) ++ * ++ * The formula for FEC MDC is 'ref_freq / (MII_SPEED x 2)' while ++ * for ENET-MAC is 'ref_freq / ((MII_SPEED + 1) x 2)'. ++ */ ++ phy_speed = (DIV_ROUND_UP((pfe->ctrl.sys_clk * 1000), 4000000) ++ << EMAC_MII_SPEED_SHIFT); ++ phy_speed |= EMAC_HOLDTIME(0x5); ++ __raw_writel(phy_speed, priv->PHY_baseaddr + EMAC_MII_CTRL_REG); ++ ++ mutex_unlock(&bus->mdio_lock); ++ ++ return 0; ++} ++ ++/* pfe_eth_gemac_phy_timeout ++ * ++ */ ++static int pfe_eth_gemac_phy_timeout(struct pfe_eth_priv_s *priv, int timeout) ++{ ++ while (!(__raw_readl(priv->PHY_baseaddr + EMAC_IEVENT_REG) & ++ EMAC_IEVENT_MII)) { ++ if (timeout-- <= 0) ++ return -1; ++ usleep_range(10, 20); ++ } ++ __raw_writel(EMAC_IEVENT_MII, priv->PHY_baseaddr + EMAC_IEVENT_REG); ++ return 0; ++} ++ ++static int pfe_eth_mdio_mux(u8 muxval) ++{ ++ struct i2c_adapter *a; ++ struct i2c_msg msg; ++ unsigned char buf[2]; ++ int ret; ++ ++ a = i2c_get_adapter(0); ++ if (!a) ++ return -ENODEV; ++ ++ /* set bit 1 (the second bit) of chip at 0x09, register 0x13 */ ++ buf[0] = 0x54; /* reg number */ ++ buf[1] = (muxval << 6) | 0x3; /* data */ ++ msg.addr = 0x66; ++ msg.buf = buf; ++ msg.len = 2; ++ msg.flags = 0; ++ ret = i2c_transfer(a, &msg, 1); ++ i2c_put_adapter(a); ++ if (ret != 1) ++ return -ENODEV; ++ return 0; ++} ++ ++static int pfe_eth_mdio_write_addr(struct mii_bus *bus, int mii_id, ++ int dev_addr, int regnum) ++{ ++ struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv; ++ ++ __raw_writel(EMAC_MII_DATA_PA(mii_id) | ++ EMAC_MII_DATA_RA(dev_addr) | ++ EMAC_MII_DATA_TA | EMAC_MII_DATA(regnum), ++ priv->PHY_baseaddr + EMAC_MII_DATA_REG); ++ ++ if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) { ++ netdev_err(priv->ndev, "%s: phy MDIO address write timeout\n", ++ __func__); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int pfe_eth_mdio_write(struct mii_bus *bus, int mii_id, int regnum, ++ u16 value) ++{ ++ struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv; ++ ++ /*To access external PHYs on QDS board mux needs to be configured*/ ++ if ((mii_id) && (pfe->mdio_muxval[mii_id])) ++ pfe_eth_mdio_mux(pfe->mdio_muxval[mii_id]); ++ ++ if (regnum & MII_ADDR_C45) { ++ pfe_eth_mdio_write_addr(bus, mii_id, (regnum >> 16) & 0x1f, ++ regnum & 0xffff); ++ __raw_writel(EMAC_MII_DATA_OP_CL45_WR | ++ EMAC_MII_DATA_PA(mii_id) | ++ EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) | ++ EMAC_MII_DATA_TA | EMAC_MII_DATA(value), ++ priv->PHY_baseaddr + EMAC_MII_DATA_REG); ++ } else { ++ /* start a write op */ ++ __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_WR | ++ EMAC_MII_DATA_PA(mii_id) | ++ EMAC_MII_DATA_RA(regnum) | ++ EMAC_MII_DATA_TA | EMAC_MII_DATA(value), ++ priv->PHY_baseaddr + EMAC_MII_DATA_REG); ++ } ++ ++ if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) { ++ netdev_err(priv->ndev, "%s: phy MDIO write timeout\n", ++ __func__); ++ return -1; ++ } ++ netif_info(priv, hw, priv->ndev, "%s: phy %x reg %x val %x\n", __func__, ++ mii_id, regnum, value); ++ ++ return 0; ++} ++ ++static int pfe_eth_mdio_read(struct mii_bus *bus, int mii_id, int regnum) ++{ ++ struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv; ++ u16 value = 0; ++ ++ /*To access external PHYs on QDS board mux needs to be configured*/ ++ if ((mii_id) && (pfe->mdio_muxval[mii_id])) ++ pfe_eth_mdio_mux(pfe->mdio_muxval[mii_id]); ++ ++ if (regnum & MII_ADDR_C45) { ++ pfe_eth_mdio_write_addr(bus, mii_id, (regnum >> 16) & 0x1f, ++ regnum & 0xffff); ++ __raw_writel(EMAC_MII_DATA_OP_CL45_RD | ++ EMAC_MII_DATA_PA(mii_id) | ++ EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) | ++ EMAC_MII_DATA_TA, ++ priv->PHY_baseaddr + EMAC_MII_DATA_REG); ++ } else { ++ /* start a read op */ ++ __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_RD | ++ EMAC_MII_DATA_PA(mii_id) | ++ EMAC_MII_DATA_RA(regnum) | ++ EMAC_MII_DATA_TA, priv->PHY_baseaddr + ++ EMAC_MII_DATA_REG); ++ } ++ ++ if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) { ++ netdev_err(priv->ndev, "%s: phy MDIO read timeout\n", __func__); ++ return -1; ++ } ++ ++ value = EMAC_MII_DATA(__raw_readl(priv->PHY_baseaddr + ++ EMAC_MII_DATA_REG)); ++ netif_info(priv, hw, priv->ndev, "%s: phy %x reg %x val %x\n", __func__, ++ mii_id, regnum, value); ++ return value; ++} ++ ++static int pfe_eth_mdio_init(struct pfe_eth_priv_s *priv, ++ struct ls1012a_mdio_platform_data *minfo) ++{ ++ struct mii_bus *bus; ++ int rc; ++ ++ netif_info(priv, drv, priv->ndev, "%s\n", __func__); ++ pr_info("%s\n", __func__); ++ ++ bus = mdiobus_alloc(); ++ if (!bus) { ++ netdev_err(priv->ndev, "mdiobus_alloc() failed\n"); ++ rc = -ENOMEM; ++ goto err0; ++ } ++ ++ bus->name = "ls1012a MDIO Bus"; ++ bus->read = &pfe_eth_mdio_read; ++ bus->write = &pfe_eth_mdio_write; ++ bus->reset = &pfe_eth_mdio_reset; ++ snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", priv->id); ++ bus->priv = priv; ++ ++ bus->phy_mask = minfo->phy_mask; ++ priv->mdc_div = minfo->mdc_div; ++ ++ if (!priv->mdc_div) ++ priv->mdc_div = 64; ++ ++ bus->irq[0] = minfo->irq[0]; ++ ++ bus->parent = priv->pfe->dev; ++ ++ netif_info(priv, drv, priv->ndev, "%s: mdc_div: %d, phy_mask: %x\n", ++ __func__, priv->mdc_div, bus->phy_mask); ++ rc = mdiobus_register(bus); ++ if (rc) { ++ netdev_err(priv->ndev, "mdiobus_register(%s) failed\n", ++ bus->name); ++ goto err1; ++ } ++ ++ priv->mii_bus = bus; ++ pfe_eth_mdio_reset(bus); ++ ++ return 0; ++ ++err1: ++ mdiobus_free(bus); ++err0: ++ return rc; ++} ++ ++/* pfe_eth_mdio_exit ++ */ ++static void pfe_eth_mdio_exit(struct mii_bus *bus) ++{ ++ if (!bus) ++ return; ++ ++ netif_info((struct pfe_eth_priv_s *)bus->priv, drv, ((struct ++ pfe_eth_priv_s *)(bus->priv))->ndev, "%s\n", __func__); ++ ++ mdiobus_unregister(bus); ++ mdiobus_free(bus); ++} ++ ++/* pfe_get_phydev_speed ++ */ ++static int pfe_get_phydev_speed(struct phy_device *phydev) ++{ ++ switch (phydev->speed) { ++ case 10: ++ return SPEED_10M; ++ case 100: ++ return SPEED_100M; ++ case 1000: ++ default: ++ return SPEED_1000M; ++ } ++} ++ ++/* pfe_set_rgmii_speed ++ */ ++#define RGMIIPCR 0x434 ++/* RGMIIPCR bit definitions*/ ++#define SCFG_RGMIIPCR_EN_AUTO (0x00000008) ++#define SCFG_RGMIIPCR_SETSP_1000M (0x00000004) ++#define SCFG_RGMIIPCR_SETSP_100M (0x00000000) ++#define SCFG_RGMIIPCR_SETSP_10M (0x00000002) ++#define SCFG_RGMIIPCR_SETFD (0x00000001) ++ ++static void pfe_set_rgmii_speed(struct phy_device *phydev) ++{ ++ u32 rgmii_pcr; ++ ++ regmap_read(pfe->scfg, RGMIIPCR, &rgmii_pcr); ++ rgmii_pcr &= ~(SCFG_RGMIIPCR_SETSP_1000M | SCFG_RGMIIPCR_SETSP_10M); ++ ++ switch (phydev->speed) { ++ case 10: ++ rgmii_pcr |= SCFG_RGMIIPCR_SETSP_10M; ++ break; ++ case 1000: ++ rgmii_pcr |= SCFG_RGMIIPCR_SETSP_1000M; ++ break; ++ case 100: ++ default: ++ /* Default is 100M */ ++ break; ++ } ++ regmap_write(pfe->scfg, RGMIIPCR, rgmii_pcr); ++} ++ ++/* pfe_get_phydev_duplex ++ */ ++static int pfe_get_phydev_duplex(struct phy_device *phydev) ++{ ++ /*return (phydev->duplex == DUPLEX_HALF) ? DUP_HALF:DUP_FULL ; */ ++ return DUPLEX_FULL; ++} ++ ++/* pfe_eth_adjust_link ++ */ ++static void pfe_eth_adjust_link(struct net_device *ndev) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ unsigned long flags; ++ struct phy_device *phydev = priv->phydev; ++ int new_state = 0; ++ ++ netif_info(priv, drv, ndev, "%s\n", __func__); ++ ++ spin_lock_irqsave(&priv->lock, flags); ++ ++ if (phydev->link) { ++ /* ++ * Now we make sure that we can be in full duplex mode. ++ * If not, we operate in half-duplex mode. ++ */ ++ if (phydev->duplex != priv->oldduplex) { ++ new_state = 1; ++ gemac_set_duplex(priv->EMAC_baseaddr, ++ pfe_get_phydev_duplex(phydev)); ++ priv->oldduplex = phydev->duplex; ++ } ++ ++ if (phydev->speed != priv->oldspeed) { ++ new_state = 1; ++ gemac_set_speed(priv->EMAC_baseaddr, ++ pfe_get_phydev_speed(phydev)); ++ if (priv->einfo->mii_config == PHY_INTERFACE_MODE_RGMII_TXID) ++ pfe_set_rgmii_speed(phydev); ++ priv->oldspeed = phydev->speed; ++ } ++ ++ if (!priv->oldlink) { ++ new_state = 1; ++ priv->oldlink = 1; ++ } ++ ++ } else if (priv->oldlink) { ++ new_state = 1; ++ priv->oldlink = 0; ++ priv->oldspeed = 0; ++ priv->oldduplex = -1; ++ } ++ ++ if (new_state && netif_msg_link(priv)) ++ phy_print_status(phydev); ++ ++ spin_unlock_irqrestore(&priv->lock, flags); ++} ++ ++/* pfe_phy_exit ++ */ ++static void pfe_phy_exit(struct net_device *ndev) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ ++ netif_info(priv, drv, ndev, "%s\n", __func__); ++ ++ phy_disconnect(priv->phydev); ++ priv->phydev = NULL; ++} ++ ++/* pfe_eth_stop ++ */ ++static void pfe_eth_stop(struct net_device *ndev, int wake) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ ++ netif_info(priv, drv, ndev, "%s\n", __func__); ++ ++ if (wake) { ++ gemac_tx_disable(priv->EMAC_baseaddr); ++ } else { ++ gemac_disable(priv->EMAC_baseaddr); ++ gpi_disable(priv->GPI_baseaddr); ++ ++ if (priv->phydev) ++ phy_stop(priv->phydev); ++ } ++} ++ ++/* pfe_eth_start ++ */ ++static int pfe_eth_start(struct pfe_eth_priv_s *priv) ++{ ++ netif_info(priv, drv, priv->ndev, "%s\n", __func__); ++ ++ if (priv->phydev) ++ phy_start(priv->phydev); ++ ++ gpi_enable(priv->GPI_baseaddr); ++ gemac_enable(priv->EMAC_baseaddr); ++ ++ return 0; ++} ++ ++/* ++ * Configure on chip serdes through mdio ++ */ ++static void ls1012a_configure_serdes(struct net_device *ndev) ++{ ++ struct pfe_eth_priv_s *priv = pfe->eth.eth_priv[0]; ++ int sgmii_2500 = 0; ++ struct mii_bus *bus = priv->mii_bus; ++ ++ if (priv->einfo->mii_config == PHY_INTERFACE_MODE_SGMII_2500) ++ sgmii_2500 = 1; ++ ++ netif_info(priv, drv, ndev, "%s\n", __func__); ++ /* PCS configuration done with corresponding GEMAC */ ++ ++ pfe_eth_mdio_read(bus, 0, 0); ++ pfe_eth_mdio_read(bus, 0, 1); ++ ++ /*These settings taken from validtion team */ ++ pfe_eth_mdio_write(bus, 0, 0x0, 0x8000); ++ if (sgmii_2500) { ++ pfe_eth_mdio_write(bus, 0, 0x14, 0x9); ++ pfe_eth_mdio_write(bus, 0, 0x4, 0x4001); ++ pfe_eth_mdio_write(bus, 0, 0x12, 0xa120); ++ pfe_eth_mdio_write(bus, 0, 0x13, 0x7); ++ } else { ++ pfe_eth_mdio_write(bus, 0, 0x14, 0xb); ++ pfe_eth_mdio_write(bus, 0, 0x4, 0x1a1); ++ pfe_eth_mdio_write(bus, 0, 0x12, 0x400); ++ pfe_eth_mdio_write(bus, 0, 0x13, 0x0); ++ } ++ ++ pfe_eth_mdio_write(bus, 0, 0x0, 0x1140); ++} ++ ++/* ++ * pfe_phy_init ++ * ++ */ ++static int pfe_phy_init(struct net_device *ndev) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ struct phy_device *phydev; ++ char phy_id[MII_BUS_ID_SIZE + 3]; ++ char bus_id[MII_BUS_ID_SIZE]; ++ phy_interface_t interface; ++ ++ priv->oldlink = 0; ++ priv->oldspeed = 0; ++ priv->oldduplex = -1; ++ ++ snprintf(bus_id, MII_BUS_ID_SIZE, "ls1012a-%d", 0); ++ snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, ++ priv->einfo->phy_id); ++ ++ netif_info(priv, drv, ndev, "%s: %s\n", __func__, phy_id); ++ interface = priv->einfo->mii_config; ++ if ((interface == PHY_INTERFACE_MODE_SGMII) || ++ (interface == PHY_INTERFACE_MODE_SGMII_2500)) { ++ /*Configure SGMII PCS */ ++ if (pfe->scfg) { ++ /*Config MDIO from serdes */ ++ regmap_write(pfe->scfg, 0x484, 0x00000000); ++ } ++ ls1012a_configure_serdes(ndev); ++ } ++ ++ if (pfe->scfg) { ++ /*Config MDIO from PAD */ ++ regmap_write(pfe->scfg, 0x484, 0x80000000); ++ } ++ ++ priv->oldlink = 0; ++ priv->oldspeed = 0; ++ priv->oldduplex = -1; ++ pr_info("%s interface %x\n", __func__, interface); ++ phydev = phy_connect(ndev, phy_id, &pfe_eth_adjust_link, interface); ++ ++ if (IS_ERR(phydev)) { ++ netdev_err(ndev, "phy_connect() failed\n"); ++ return PTR_ERR(phydev); ++ } ++ ++ priv->phydev = phydev; ++ phydev->irq = PHY_POLL; ++ ++ return 0; ++} ++ ++/* pfe_gemac_init ++ */ ++static int pfe_gemac_init(struct pfe_eth_priv_s *priv) ++{ ++ struct gemac_cfg cfg; ++ ++ netif_info(priv, ifup, priv->ndev, "%s\n", __func__); ++ ++ cfg.speed = SPEED_1000M; ++ cfg.duplex = DUPLEX_FULL; ++ ++ gemac_set_config(priv->EMAC_baseaddr, &cfg); ++ gemac_allow_broadcast(priv->EMAC_baseaddr); ++ gemac_enable_1536_rx(priv->EMAC_baseaddr); ++ gemac_enable_rx_jmb(priv->EMAC_baseaddr); ++ gemac_enable_stacked_vlan(priv->EMAC_baseaddr); ++ gemac_enable_pause_rx(priv->EMAC_baseaddr); ++ gemac_set_bus_width(priv->EMAC_baseaddr, 64); ++ ++ /*GEM will perform checksum verifications*/ ++ if (priv->ndev->features & NETIF_F_RXCSUM) ++ gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr); ++ else ++ gemac_disable_rx_checksum_offload(priv->EMAC_baseaddr); ++ ++ return 0; ++} ++ ++/* pfe_eth_event_handler ++ */ ++static int pfe_eth_event_handler(void *data, int event, int qno) ++{ ++ struct pfe_eth_priv_s *priv = data; ++ ++ switch (event) { ++ case EVENT_RX_PKT_IND: ++ ++ if (qno == 0) { ++ if (napi_schedule_prep(&priv->high_napi)) { ++ netif_info(priv, intr, priv->ndev, ++ "%s: schedule high prio poll\n" ++ , __func__); ++ ++#ifdef PFE_ETH_NAPI_STATS ++ priv->napi_counters[NAPI_SCHED_COUNT]++; ++#endif ++ ++ __napi_schedule(&priv->high_napi); ++ } ++ } else if (qno == 1) { ++ if (napi_schedule_prep(&priv->low_napi)) { ++ netif_info(priv, intr, priv->ndev, ++ "%s: schedule low prio poll\n" ++ , __func__); ++ ++#ifdef PFE_ETH_NAPI_STATS ++ priv->napi_counters[NAPI_SCHED_COUNT]++; ++#endif ++ __napi_schedule(&priv->low_napi); ++ } ++ } else if (qno == 2) { ++ if (napi_schedule_prep(&priv->lro_napi)) { ++ netif_info(priv, intr, priv->ndev, ++ "%s: schedule lro prio poll\n" ++ , __func__); ++ ++#ifdef PFE_ETH_NAPI_STATS ++ priv->napi_counters[NAPI_SCHED_COUNT]++; ++#endif ++ __napi_schedule(&priv->lro_napi); ++ } ++ } ++ ++ break; ++ ++ case EVENT_TXDONE_IND: ++ pfe_eth_flush_tx(priv); ++ hif_lib_event_handler_start(&priv->client, EVENT_TXDONE_IND, 0); ++ break; ++ case EVENT_HIGH_RX_WM: ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++/* pfe_eth_open ++ */ ++static int pfe_eth_open(struct net_device *ndev) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ struct hif_client_s *client; ++ int rc; ++ ++ netif_info(priv, ifup, ndev, "%s\n", __func__); ++ ++ /* Register client driver with HIF */ ++ client = &priv->client; ++ memset(client, 0, sizeof(*client)); ++ client->id = PFE_CL_GEM0 + priv->id; ++ client->tx_qn = emac_txq_cnt; ++ client->rx_qn = EMAC_RXQ_CNT; ++ client->priv = priv; ++ client->pfe = priv->pfe; ++ client->event_handler = pfe_eth_event_handler; ++ ++ client->tx_qsize = EMAC_TXQ_DEPTH; ++ client->rx_qsize = EMAC_RXQ_DEPTH; ++ ++ rc = hif_lib_client_register(client); ++ if (rc) { ++ netdev_err(ndev, "%s: hif_lib_client_register(%d) failed\n", ++ __func__, client->id); ++ goto err0; ++ } ++ ++ netif_info(priv, drv, ndev, "%s: registered client: %p\n", __func__, ++ client); ++ ++ pfe_gemac_init(priv); ++ ++ if (!is_valid_ether_addr(ndev->dev_addr)) { ++ netdev_err(ndev, "%s: invalid MAC address\n", __func__); ++ rc = -EADDRNOTAVAIL; ++ goto err1; ++ } ++ ++ gemac_set_laddrN(priv->EMAC_baseaddr, ++ (struct pfe_mac_addr *)ndev->dev_addr, 1); ++ ++ napi_enable(&priv->high_napi); ++ napi_enable(&priv->low_napi); ++ napi_enable(&priv->lro_napi); ++ ++ rc = pfe_eth_start(priv); ++ ++ netif_tx_wake_all_queues(ndev); ++ ++ return rc; ++ ++err1: ++ hif_lib_client_unregister(&priv->client); ++ ++err0: ++ return rc; ++} ++ ++/* ++ * pfe_eth_shutdown ++ */ ++int pfe_eth_shutdown(struct net_device *ndev, int wake) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ int i, qstatus; ++ unsigned long next_poll = jiffies + 1, end = jiffies + ++ (TX_POLL_TIMEOUT_MS * HZ) / 1000; ++ int tx_pkts, prv_tx_pkts; ++ ++ netif_info(priv, ifdown, ndev, "%s\n", __func__); ++ ++ for (i = 0; i < emac_txq_cnt; i++) ++ hrtimer_cancel(&priv->fast_tx_timeout[i].timer); ++ ++ netif_tx_stop_all_queues(ndev); ++ ++ do { ++ tx_pkts = 0; ++ pfe_eth_flush_tx(priv); ++ ++ for (i = 0; i < emac_txq_cnt; i++) ++ tx_pkts += hif_lib_tx_pending(&priv->client, i); ++ ++ if (tx_pkts) { ++ /*Don't wait forever, break if we cross max timeout */ ++ if (time_after(jiffies, end)) { ++ pr_err( ++ "(%s)Tx is not complete after %dmsec\n", ++ ndev->name, TX_POLL_TIMEOUT_MS); ++ break; ++ } ++ ++ pr_info("%s : (%s) Waiting for tx packets to free. Pending tx pkts = %d.\n" ++ , __func__, ndev->name, tx_pkts); ++ if (need_resched()) ++ schedule(); ++ } ++ ++ } while (tx_pkts); ++ ++ end = jiffies + (TX_POLL_TIMEOUT_MS * HZ) / 1000; ++ ++ prv_tx_pkts = tmu_pkts_processed(priv->id); ++ /* ++ * Wait till TMU transmits all pending packets ++ * poll tmu_qstatus and pkts processed by TMU for every 10ms ++ * Consider TMU is busy, If we see TMU qeueu pending or any packets ++ * processed by TMU ++ */ ++ while (1) { ++ if (time_after(jiffies, next_poll)) { ++ tx_pkts = tmu_pkts_processed(priv->id); ++ qstatus = tmu_qstatus(priv->id) & 0x7ffff; ++ ++ if (!qstatus && (tx_pkts == prv_tx_pkts)) ++ break; ++ /* Don't wait forever, break if we cross max ++ * timeout(TX_POLL_TIMEOUT_MS) ++ */ ++ if (time_after(jiffies, end)) { ++ pr_err("TMU%d is busy after %dmsec\n", ++ priv->id, TX_POLL_TIMEOUT_MS); ++ break; ++ } ++ prv_tx_pkts = tx_pkts; ++ next_poll++; ++ } ++ if (need_resched()) ++ schedule(); ++ } ++ /* Wait for some more time to complete transmitting packet if any */ ++ next_poll = jiffies + 1; ++ while (1) { ++ if (time_after(jiffies, next_poll)) ++ break; ++ if (need_resched()) ++ schedule(); ++ } ++ ++ pfe_eth_stop(ndev, wake); ++ ++ napi_disable(&priv->lro_napi); ++ napi_disable(&priv->low_napi); ++ napi_disable(&priv->high_napi); ++ ++ hif_lib_client_unregister(&priv->client); ++ ++ return 0; ++} ++ ++/* pfe_eth_close ++ * ++ */ ++static int pfe_eth_close(struct net_device *ndev) ++{ ++ pfe_eth_shutdown(ndev, 0); ++ ++ return 0; ++} ++ ++/* pfe_eth_suspend ++ * ++ * return value : 1 if netdevice is configured to wakeup system ++ * 0 otherwise ++ */ ++int pfe_eth_suspend(struct net_device *ndev) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ int retval = 0; ++ ++ if (priv->wol) { ++ gemac_set_wol(priv->EMAC_baseaddr, priv->wol); ++ retval = 1; ++ } ++ pfe_eth_shutdown(ndev, priv->wol); ++ ++ return retval; ++} ++ ++/* pfe_eth_resume ++ * ++ */ ++int pfe_eth_resume(struct net_device *ndev) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ ++ if (priv->wol) ++ gemac_set_wol(priv->EMAC_baseaddr, 0); ++ gemac_tx_enable(priv->EMAC_baseaddr); ++ ++ return pfe_eth_open(ndev); ++} ++ ++/* pfe_eth_get_queuenum ++ */ ++static int pfe_eth_get_queuenum(struct pfe_eth_priv_s *priv, struct sk_buff ++ *skb) ++{ ++ int queuenum = 0; ++ unsigned long flags; ++ ++ /* Get the Fast Path queue number */ ++ /* ++ * Use conntrack mark (if conntrack exists), then packet mark (if any), ++ * then fallback to default ++ */ ++#if defined(CONFIG_IP_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_MARK) ++ if (skb->nfct) { ++ enum ip_conntrack_info cinfo; ++ struct nf_conn *ct; ++ ++ ct = nf_ct_get(skb, &cinfo); ++ ++ if (ct) { ++ u32 connmark; ++ ++ connmark = ct->mark; ++ ++ if ((connmark & 0x80000000) && priv->id != 0) ++ connmark >>= 16; ++ ++ queuenum = connmark & EMAC_QUEUENUM_MASK; ++ } ++ } else {/* continued after #endif ... */ ++#endif ++ if (skb->mark) { ++ queuenum = skb->mark & EMAC_QUEUENUM_MASK; ++ } else { ++ spin_lock_irqsave(&priv->lock, flags); ++ queuenum = priv->default_priority & EMAC_QUEUENUM_MASK; ++ spin_unlock_irqrestore(&priv->lock, flags); ++ } ++#if defined(CONFIG_IP_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_MARK) ++ } ++#endif ++ return queuenum; ++} ++ ++/* pfe_eth_might_stop_tx ++ * ++ */ ++static int pfe_eth_might_stop_tx(struct pfe_eth_priv_s *priv, int queuenum, ++ struct netdev_queue *tx_queue, ++ unsigned int n_desc, ++ unsigned int n_segs) ++{ ++ ktime_t kt; ++ ++ if (unlikely((__hif_tx_avail(&pfe->hif) < n_desc) || ++ (hif_lib_tx_avail(&priv->client, queuenum) < n_desc) || ++ (hif_lib_tx_credit_avail(pfe, priv->id, queuenum) < n_segs))) { ++#ifdef PFE_ETH_TX_STATS ++ if (__hif_tx_avail(&pfe->hif) < n_desc) { ++ priv->stop_queue_hif[queuenum]++; ++ } else if (hif_lib_tx_avail(&priv->client, queuenum) < n_desc) { ++ priv->stop_queue_hif_client[queuenum]++; ++ } else if (hif_lib_tx_credit_avail(pfe, priv->id, queuenum) < ++ n_segs) { ++ priv->stop_queue_credit[queuenum]++; ++ } ++ priv->stop_queue_total[queuenum]++; ++#endif ++ netif_tx_stop_queue(tx_queue); ++ ++ kt = ktime_set(0, LS1012A_TX_FAST_RECOVERY_TIMEOUT_MS * ++ NSEC_PER_MSEC); ++ hrtimer_start(&priv->fast_tx_timeout[queuenum].timer, kt, ++ HRTIMER_MODE_REL); ++ return -1; ++ } else { ++ return 0; ++ } ++} ++ ++#define SA_MAX_OP 2 ++/* pfe_hif_send_packet ++ * ++ * At this level if TX fails we drop the packet ++ */ ++static void pfe_hif_send_packet(struct sk_buff *skb, struct pfe_eth_priv_s ++ *priv, int queuenum) ++{ ++ struct skb_shared_info *sh = skb_shinfo(skb); ++ unsigned int nr_frags; ++ u32 ctrl = 0; ++ ++ netif_info(priv, tx_queued, priv->ndev, "%s\n", __func__); ++ ++ if (skb_is_gso(skb)) { ++ priv->stats.tx_dropped++; ++ return; ++ } ++ ++ if (skb->ip_summed == CHECKSUM_PARTIAL) ++ ctrl = HIF_CTRL_TX_CHECKSUM; ++ ++ nr_frags = sh->nr_frags; ++ ++ if (nr_frags) { ++ skb_frag_t *f; ++ int i; ++ ++ __hif_lib_xmit_pkt(&priv->client, queuenum, skb->data, ++ skb_headlen(skb), ctrl, HIF_FIRST_BUFFER, ++ skb); ++ ++ for (i = 0; i < nr_frags - 1; i++) { ++ f = &sh->frags[i]; ++ __hif_lib_xmit_pkt(&priv->client, queuenum, ++ skb_frag_address(f), ++ skb_frag_size(f), ++ 0x0, 0x0, skb); ++ } ++ ++ f = &sh->frags[i]; ++ ++ __hif_lib_xmit_pkt(&priv->client, queuenum, ++ skb_frag_address(f), skb_frag_size(f), ++ 0x0, HIF_LAST_BUFFER | HIF_DATA_VALID, ++ skb); ++ ++ netif_info(priv, tx_queued, priv->ndev, ++ "%s: pkt sent successfully skb:%p nr_frags:%d len:%d\n", ++ __func__, skb, nr_frags, skb->len); ++ } else { ++ __hif_lib_xmit_pkt(&priv->client, queuenum, skb->data, ++ skb->len, ctrl, HIF_FIRST_BUFFER | ++ HIF_LAST_BUFFER | HIF_DATA_VALID, ++ skb); ++ netif_info(priv, tx_queued, priv->ndev, ++ "%s: pkt sent successfully skb:%p len:%d\n", ++ __func__, skb, skb->len); ++ } ++ hif_tx_dma_start(); ++ priv->stats.tx_packets++; ++ priv->stats.tx_bytes += skb->len; ++ hif_lib_tx_credit_use(pfe, priv->id, queuenum, 1); ++} ++ ++/* pfe_eth_flush_txQ ++ */ ++static void pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int ++ from_tx, int n_desc) ++{ ++ struct sk_buff *skb; ++ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev, ++ tx_q_num); ++ unsigned int flags; ++ ++ netif_info(priv, tx_done, priv->ndev, "%s\n", __func__); ++ ++ if (!from_tx) ++ __netif_tx_lock_bh(tx_queue); ++ ++ /* Clean HIF and client queue */ ++ while ((skb = hif_lib_tx_get_next_complete(&priv->client, ++ tx_q_num, &flags, ++ HIF_TX_DESC_NT))) { ++ if (flags & HIF_DATA_VALID) ++ dev_kfree_skb_any(skb); ++ } ++ if (!from_tx) ++ __netif_tx_unlock_bh(tx_queue); ++} ++ ++/* pfe_eth_flush_tx ++ */ ++static void pfe_eth_flush_tx(struct pfe_eth_priv_s *priv) ++{ ++ int ii; ++ ++ netif_info(priv, tx_done, priv->ndev, "%s\n", __func__); ++ ++ for (ii = 0; ii < emac_txq_cnt; ii++) ++ pfe_eth_flush_txQ(priv, ii, 0, 0); ++} ++ ++void pfe_tx_get_req_desc(struct sk_buff *skb, unsigned int *n_desc, unsigned int ++ *n_segs) ++{ ++ struct skb_shared_info *sh = skb_shinfo(skb); ++ ++ /* Scattered data */ ++ if (sh->nr_frags) { ++ *n_desc = sh->nr_frags + 1; ++ *n_segs = 1; ++ /* Regular case */ ++ } else { ++ *n_desc = 1; ++ *n_segs = 1; ++ } ++} ++ ++/* pfe_eth_send_packet ++ */ ++static int pfe_eth_send_packet(struct sk_buff *skb, struct net_device *ndev) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ int tx_q_num = skb_get_queue_mapping(skb); ++ int n_desc, n_segs; ++ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev, ++ tx_q_num); ++ ++ netif_info(priv, tx_queued, ndev, "%s\n", __func__); ++ ++ if ((!skb_is_gso(skb)) && (skb_headroom(skb) < (PFE_PKT_HEADER_SZ + ++ sizeof(unsigned long)))) { ++ netif_warn(priv, tx_err, priv->ndev, "%s: copying skb\n", ++ __func__); ++ ++ if (pskb_expand_head(skb, (PFE_PKT_HEADER_SZ + sizeof(unsigned ++ long)), 0, GFP_ATOMIC)) { ++ /* No need to re-transmit, no way to recover*/ ++ kfree_skb(skb); ++ priv->stats.tx_dropped++; ++ return NETDEV_TX_OK; ++ } ++ } ++ ++ pfe_tx_get_req_desc(skb, &n_desc, &n_segs); ++ ++ hif_tx_lock(&pfe->hif); ++ if (unlikely(pfe_eth_might_stop_tx(priv, tx_q_num, tx_queue, n_desc, ++ n_segs))) { ++#ifdef PFE_ETH_TX_STATS ++ if (priv->was_stopped[tx_q_num]) { ++ priv->clean_fail[tx_q_num]++; ++ priv->was_stopped[tx_q_num] = 0; ++ } ++#endif ++ hif_tx_unlock(&pfe->hif); ++ return NETDEV_TX_BUSY; ++ } ++ ++ pfe_hif_send_packet(skb, priv, tx_q_num); ++ ++ hif_tx_unlock(&pfe->hif); ++ ++ tx_queue->trans_start = jiffies; ++ ++#ifdef PFE_ETH_TX_STATS ++ priv->was_stopped[tx_q_num] = 0; ++#endif ++ ++ return NETDEV_TX_OK; ++} ++ ++/* pfe_eth_select_queue ++ * ++ */ ++static u16 pfe_eth_select_queue(struct net_device *ndev, struct sk_buff *skb, ++ void *accel_priv, ++ select_queue_fallback_t fallback) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ ++ return pfe_eth_get_queuenum(priv, skb); ++} ++ ++/* pfe_eth_get_stats ++ */ ++static struct net_device_stats *pfe_eth_get_stats(struct net_device *ndev) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ ++ netif_info(priv, drv, ndev, "%s\n", __func__); ++ ++ return &priv->stats; ++} ++ ++/* pfe_eth_set_mac_address ++ */ ++static int pfe_eth_set_mac_address(struct net_device *ndev, void *addr) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ struct sockaddr *sa = addr; ++ ++ netif_info(priv, drv, ndev, "%s\n", __func__); ++ ++ if (!is_valid_ether_addr(sa->sa_data)) ++ return -EADDRNOTAVAIL; ++ ++ memcpy(ndev->dev_addr, sa->sa_data, ETH_ALEN); ++ ++ gemac_set_laddrN(priv->EMAC_baseaddr, ++ (struct pfe_mac_addr *)ndev->dev_addr, 1); ++ ++ return 0; ++} ++ ++/* pfe_eth_enet_addr_byte_mac ++ */ ++int pfe_eth_enet_addr_byte_mac(u8 *enet_byte_addr, ++ struct pfe_mac_addr *enet_addr) ++{ ++ if (!enet_byte_addr || !enet_addr) { ++ return -1; ++ ++ } else { ++ enet_addr->bottom = enet_byte_addr[0] | ++ (enet_byte_addr[1] << 8) | ++ (enet_byte_addr[2] << 16) | ++ (enet_byte_addr[3] << 24); ++ enet_addr->top = enet_byte_addr[4] | ++ (enet_byte_addr[5] << 8); ++ return 0; ++ } ++} ++ ++/* pfe_eth_set_multi ++ */ ++static void pfe_eth_set_multi(struct net_device *ndev) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ struct pfe_mac_addr hash_addr; /* hash register structure */ ++ /* specific mac address register structure */ ++ struct pfe_mac_addr spec_addr; ++ int result; /* index into hash register to set.. */ ++ int uc_count = 0; ++ struct netdev_hw_addr *ha; ++ ++ if (ndev->flags & IFF_PROMISC) { ++ netif_info(priv, drv, ndev, "entering promiscuous mode\n"); ++ ++ priv->promisc = 1; ++ gemac_enable_copy_all(priv->EMAC_baseaddr); ++ } else { ++ priv->promisc = 0; ++ gemac_disable_copy_all(priv->EMAC_baseaddr); ++ } ++ ++ /* Enable broadcast frame reception if required. */ ++ if (ndev->flags & IFF_BROADCAST) { ++ gemac_allow_broadcast(priv->EMAC_baseaddr); ++ } else { ++ netif_info(priv, drv, ndev, ++ "disabling broadcast frame reception\n"); ++ ++ gemac_no_broadcast(priv->EMAC_baseaddr); ++ } ++ ++ if (ndev->flags & IFF_ALLMULTI) { ++ /* Set the hash to rx all multicast frames */ ++ hash_addr.bottom = 0xFFFFFFFF; ++ hash_addr.top = 0xFFFFFFFF; ++ gemac_set_hash(priv->EMAC_baseaddr, &hash_addr); ++ netdev_for_each_uc_addr(ha, ndev) { ++ if (uc_count >= MAX_UC_SPEC_ADDR_REG) ++ break; ++ pfe_eth_enet_addr_byte_mac(ha->addr, &spec_addr); ++ gemac_set_laddrN(priv->EMAC_baseaddr, &spec_addr, ++ uc_count + 2); ++ uc_count++; ++ } ++ } else if ((netdev_mc_count(ndev) > 0) || (netdev_uc_count(ndev))) { ++ u8 *addr; ++ ++ hash_addr.bottom = 0; ++ hash_addr.top = 0; ++ ++ netdev_for_each_mc_addr(ha, ndev) { ++ addr = ha->addr; ++ ++ netif_info(priv, drv, ndev, ++ "adding multicast address %X:%X:%X:%X:%X:%X to gem filter\n", ++ addr[0], addr[1], addr[2], ++ addr[3], addr[4], addr[5]); ++ ++ result = pfe_eth_get_hash(addr); ++ ++ if (result < EMAC_HASH_REG_BITS) { ++ if (result < 32) ++ hash_addr.bottom |= (1 << result); ++ else ++ hash_addr.top |= (1 << (result - 32)); ++ } else { ++ break; ++ } ++ } ++ ++ uc_count = -1; ++ netdev_for_each_uc_addr(ha, ndev) { ++ addr = ha->addr; ++ ++ if (++uc_count < MAX_UC_SPEC_ADDR_REG) { ++ netdev_info(ndev, ++ "adding unicast address %02x:%02x:%02x:%02x:%02x:%02x to gem filter\n", ++ addr[0], addr[1], addr[2], ++ addr[3], addr[4], addr[5]); ++ pfe_eth_enet_addr_byte_mac(addr, &spec_addr); ++ gemac_set_laddrN(priv->EMAC_baseaddr, ++ &spec_addr, uc_count + 2); ++ } else { ++ netif_info(priv, drv, ndev, ++ "adding unicast address %02x:%02x:%02x:%02x:%02x:%02x to gem hash\n", ++ addr[0], addr[1], addr[2], ++ addr[3], addr[4], addr[5]); ++ ++ result = pfe_eth_get_hash(addr); ++ if (result >= EMAC_HASH_REG_BITS) { ++ break; ++ ++ } else { ++ if (result < 32) ++ hash_addr.bottom |= (1 << ++ result); ++ else ++ hash_addr.top |= (1 << ++ (result - 32)); ++ } ++ } ++ } ++ ++ gemac_set_hash(priv->EMAC_baseaddr, &hash_addr); ++ } ++ ++ if (!(netdev_uc_count(ndev) >= MAX_UC_SPEC_ADDR_REG)) { ++ /* ++ * Check if there are any specific address HW registers that ++ * need to be flushed ++ */ ++ for (uc_count = netdev_uc_count(ndev); uc_count < ++ MAX_UC_SPEC_ADDR_REG; uc_count++) ++ gemac_clear_laddrN(priv->EMAC_baseaddr, uc_count + 2); ++ } ++ ++ if (ndev->flags & IFF_LOOPBACK) ++ gemac_set_loop(priv->EMAC_baseaddr, LB_LOCAL); ++} ++ ++/* pfe_eth_set_features ++ */ ++static int pfe_eth_set_features(struct net_device *ndev, netdev_features_t ++ features) ++{ ++ struct pfe_eth_priv_s *priv = netdev_priv(ndev); ++ int rc = 0; ++ ++ if (features & NETIF_F_RXCSUM) ++ gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr); ++ else ++ gemac_disable_rx_checksum_offload(priv->EMAC_baseaddr); ++ return rc; ++} ++ ++/* pfe_eth_fast_tx_timeout ++ */ ++static enum hrtimer_restart pfe_eth_fast_tx_timeout(struct hrtimer *timer) ++{ ++ struct pfe_eth_fast_timer *fast_tx_timeout = container_of(timer, struct ++ pfe_eth_fast_timer, ++ timer); ++ struct pfe_eth_priv_s *priv = container_of(fast_tx_timeout->base, ++ struct pfe_eth_priv_s, ++ fast_tx_timeout); ++ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev, ++ fast_tx_timeout->queuenum); ++ ++ if (netif_tx_queue_stopped(tx_queue)) { ++#ifdef PFE_ETH_TX_STATS ++ priv->was_stopped[fast_tx_timeout->queuenum] = 1; ++#endif ++ netif_tx_wake_queue(tx_queue); ++ } ++ ++ return HRTIMER_NORESTART; ++} ++ ++/* pfe_eth_fast_tx_timeout_init ++ */ ++static void pfe_eth_fast_tx_timeout_init(struct pfe_eth_priv_s *priv) ++{ ++ int i; ++ ++ for (i = 0; i < emac_txq_cnt; i++) { ++ priv->fast_tx_timeout[i].queuenum = i; ++ hrtimer_init(&priv->fast_tx_timeout[i].timer, CLOCK_MONOTONIC, ++ HRTIMER_MODE_REL); ++ priv->fast_tx_timeout[i].timer.function = ++ pfe_eth_fast_tx_timeout; ++ priv->fast_tx_timeout[i].base = priv->fast_tx_timeout; ++ } ++} ++ ++static struct sk_buff *pfe_eth_rx_skb(struct net_device *ndev, ++ struct pfe_eth_priv_s *priv, ++ unsigned int qno) ++{ ++ void *buf_addr; ++ unsigned int rx_ctrl; ++ unsigned int desc_ctrl = 0; ++ struct hif_ipsec_hdr *ipsec_hdr = NULL; ++ struct sk_buff *skb; ++ struct sk_buff *skb_frag, *skb_frag_last = NULL; ++ int length = 0, offset; ++ ++ skb = priv->skb_inflight[qno]; ++ ++ if (skb) { ++ skb_frag_last = skb_shinfo(skb)->frag_list; ++ if (skb_frag_last) { ++ while (skb_frag_last->next) ++ skb_frag_last = skb_frag_last->next; ++ } ++ } ++ ++ while (!(desc_ctrl & CL_DESC_LAST)) { ++ buf_addr = hif_lib_receive_pkt(&priv->client, qno, &length, ++ &offset, &rx_ctrl, &desc_ctrl, ++ (void **)&ipsec_hdr); ++ if (!buf_addr) ++ goto incomplete; ++ ++#ifdef PFE_ETH_NAPI_STATS ++ priv->napi_counters[NAPI_DESC_COUNT]++; ++#endif ++ ++ /* First frag */ ++ if (desc_ctrl & CL_DESC_FIRST) { ++ skb = build_skb(buf_addr, 0); ++ if (unlikely(!skb)) ++ goto pkt_drop; ++ ++ skb_reserve(skb, offset); ++ skb_put(skb, length); ++ skb->dev = ndev; ++ ++ if ((ndev->features & NETIF_F_RXCSUM) && (rx_ctrl & ++ HIF_CTRL_RX_CHECKSUMMED)) ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ else ++ skb_checksum_none_assert(skb); ++ ++ } else { ++ /* Next frags */ ++ if (unlikely(!skb)) { ++ pr_err("%s: NULL skb_inflight\n", ++ __func__); ++ goto pkt_drop; ++ } ++ ++ skb_frag = build_skb(buf_addr, 0); ++ ++ if (unlikely(!skb_frag)) { ++ kfree(buf_addr); ++ goto pkt_drop; ++ } ++ ++ skb_reserve(skb_frag, offset); ++ skb_put(skb_frag, length); ++ ++ skb_frag->dev = ndev; ++ ++ if (skb_shinfo(skb)->frag_list) ++ skb_frag_last->next = skb_frag; ++ else ++ skb_shinfo(skb)->frag_list = skb_frag; ++ ++ skb->truesize += skb_frag->truesize; ++ skb->data_len += length; ++ skb->len += length; ++ skb_frag_last = skb_frag; ++ } ++ } ++ ++ priv->skb_inflight[qno] = NULL; ++ return skb; ++ ++incomplete: ++ priv->skb_inflight[qno] = skb; ++ return NULL; ++ ++pkt_drop: ++ priv->skb_inflight[qno] = NULL; ++ ++ if (skb) ++ kfree_skb(skb); ++ else ++ kfree(buf_addr); ++ ++ priv->stats.rx_errors++; ++ ++ return NULL; ++} ++ ++/* pfe_eth_poll ++ */ ++static int pfe_eth_poll(struct pfe_eth_priv_s *priv, struct napi_struct *napi, ++ unsigned int qno, int budget) ++{ ++ struct net_device *ndev = priv->ndev; ++ struct sk_buff *skb; ++ int work_done = 0; ++ unsigned int len; ++ ++ netif_info(priv, intr, priv->ndev, "%s\n", __func__); ++ ++#ifdef PFE_ETH_NAPI_STATS ++ priv->napi_counters[NAPI_POLL_COUNT]++; ++#endif ++ ++ do { ++ skb = pfe_eth_rx_skb(ndev, priv, qno); ++ ++ if (!skb) ++ break; ++ ++ len = skb->len; ++ ++ /* Packet will be processed */ ++ skb->protocol = eth_type_trans(skb, ndev); ++ ++ netif_receive_skb(skb); ++ ++ priv->stats.rx_packets++; ++ priv->stats.rx_bytes += len; ++ ++ work_done++; ++ ++#ifdef PFE_ETH_NAPI_STATS ++ priv->napi_counters[NAPI_PACKET_COUNT]++; ++#endif ++ ++ } while (work_done < budget); ++ ++ /* ++ * If no Rx receive nor cleanup work was done, exit polling mode. ++ * No more netif_running(dev) check is required here , as this is ++ * checked in net/core/dev.c (2.6.33.5 kernel specific). ++ */ ++ if (work_done < budget) { ++ napi_complete(napi); ++ ++ hif_lib_event_handler_start(&priv->client, EVENT_RX_PKT_IND, ++ qno); ++ } ++#ifdef PFE_ETH_NAPI_STATS ++ else ++ priv->napi_counters[NAPI_FULL_BUDGET_COUNT]++; ++#endif ++ ++ return work_done; ++} ++ ++/* ++ * pfe_eth_lro_poll ++ */ ++static int pfe_eth_lro_poll(struct napi_struct *napi, int budget) ++{ ++ struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s, ++ lro_napi); ++ ++ netif_info(priv, intr, priv->ndev, "%s\n", __func__); ++ ++ return pfe_eth_poll(priv, napi, 2, budget); ++} ++ ++/* pfe_eth_low_poll ++ */ ++static int pfe_eth_low_poll(struct napi_struct *napi, int budget) ++{ ++ struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s, ++ low_napi); ++ ++ netif_info(priv, intr, priv->ndev, "%s\n", __func__); ++ ++ return pfe_eth_poll(priv, napi, 1, budget); ++} ++ ++/* pfe_eth_high_poll ++ */ ++static int pfe_eth_high_poll(struct napi_struct *napi, int budget) ++{ ++ struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s, ++ high_napi); ++ ++ netif_info(priv, intr, priv->ndev, "%s\n", __func__); ++ ++ return pfe_eth_poll(priv, napi, 0, budget); ++} ++ ++static const struct net_device_ops pfe_netdev_ops = { ++ .ndo_open = pfe_eth_open, ++ .ndo_stop = pfe_eth_close, ++ .ndo_start_xmit = pfe_eth_send_packet, ++ .ndo_select_queue = pfe_eth_select_queue, ++ .ndo_get_stats = pfe_eth_get_stats, ++ .ndo_set_mac_address = pfe_eth_set_mac_address, ++ .ndo_set_rx_mode = pfe_eth_set_multi, ++ .ndo_set_features = pfe_eth_set_features, ++ .ndo_validate_addr = eth_validate_addr, ++}; ++ ++/* pfe_eth_init_one ++ */ ++static int pfe_eth_init_one(struct pfe *pfe, int id) ++{ ++ struct net_device *ndev = NULL; ++ struct pfe_eth_priv_s *priv = NULL; ++ struct ls1012a_eth_platform_data *einfo; ++ struct ls1012a_mdio_platform_data *minfo; ++ struct ls1012a_pfe_platform_data *pfe_info; ++ int err; ++ ++ /* Extract pltform data */ ++ pfe_info = (struct ls1012a_pfe_platform_data *) ++ pfe->dev->platform_data; ++ if (!pfe_info) { ++ pr_err( ++ "%s: pfe missing additional platform data\n" ++ , __func__); ++ err = -ENODEV; ++ goto err0; ++ } ++ ++ einfo = (struct ls1012a_eth_platform_data *) ++ pfe_info->ls1012a_eth_pdata; ++ ++ /* einfo never be NULL, but no harm in having this check */ ++ if (!einfo) { ++ pr_err( ++ "%s: pfe missing additional gemacs platform data\n" ++ , __func__); ++ err = -ENODEV; ++ goto err0; ++ } ++ ++ minfo = (struct ls1012a_mdio_platform_data *) ++ pfe_info->ls1012a_mdio_pdata; ++ ++ /* einfo never be NULL, but no harm in having this check */ ++ if (!minfo) { ++ pr_err( ++ "%s: pfe missing additional mdios platform data\n", ++ __func__); ++ err = -ENODEV; ++ goto err0; ++ } ++ ++ /* Create an ethernet device instance */ ++ ndev = alloc_etherdev_mq(sizeof(*priv), emac_txq_cnt); ++ ++ if (!ndev) { ++ pr_err("%s: gemac %d device allocation failed\n", ++ __func__, einfo[id].gem_id); ++ err = -ENOMEM; ++ goto err0; ++ } ++ ++ priv = netdev_priv(ndev); ++ priv->ndev = ndev; ++ priv->id = einfo[id].gem_id; ++ priv->pfe = pfe; ++ ++ SET_NETDEV_DEV(priv->ndev, priv->pfe->dev); ++ ++ pfe->eth.eth_priv[id] = priv; ++ ++ /* Set the info in the priv to the current info */ ++ priv->einfo = &einfo[id]; ++ priv->EMAC_baseaddr = cbus_emac_base[id]; ++ priv->PHY_baseaddr = cbus_emac_base[0]; ++ priv->GPI_baseaddr = cbus_gpi_base[id]; ++ ++#define HIF_GEMAC_TMUQ_BASE 6 ++ priv->low_tmu_q = HIF_GEMAC_TMUQ_BASE + (id * 2); ++ priv->high_tmu_q = priv->low_tmu_q + 1; ++ ++ spin_lock_init(&priv->lock); ++ ++ pfe_eth_fast_tx_timeout_init(priv); ++ ++ /* Copy the station address into the dev structure, */ ++ memcpy(ndev->dev_addr, einfo[id].mac_addr, ETH_ALEN); ++ ++ /* Initialize mdio */ ++ if (minfo[id].enabled) { ++ err = pfe_eth_mdio_init(priv, &minfo[id]); ++ if (err) { ++ netdev_err(ndev, "%s: pfe_eth_mdio_init() failed\n", ++ __func__); ++ goto err2; ++ } ++ } ++ ++ ndev->mtu = 1500; ++ ++ /* Set MTU limits */ ++ ndev->min_mtu = ETH_MIN_MTU; ++ ndev->max_mtu = JUMBO_FRAME_SIZE; ++ ++ /* supported features */ ++ ndev->hw_features = NETIF_F_SG; ++ ++ /*Enable after checksum offload is validated */ ++ ndev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | ++ NETIF_F_IPV6_CSUM | NETIF_F_SG; ++ ++ /* enabled by default */ ++ ndev->features = ndev->hw_features; ++ ++ priv->usr_features = ndev->features; ++ ++ ndev->netdev_ops = &pfe_netdev_ops; ++ ++ ndev->ethtool_ops = &pfe_ethtool_ops; ++ ++ /* Enable basic messages by default */ ++ priv->msg_enable = NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_LINK | ++ NETIF_MSG_PROBE; ++ ++ netif_napi_add(ndev, &priv->low_napi, pfe_eth_low_poll, ++ HIF_RX_POLL_WEIGHT - 16); ++ netif_napi_add(ndev, &priv->high_napi, pfe_eth_high_poll, ++ HIF_RX_POLL_WEIGHT - 16); ++ netif_napi_add(ndev, &priv->lro_napi, pfe_eth_lro_poll, ++ HIF_RX_POLL_WEIGHT - 16); ++ ++ err = register_netdev(ndev); ++ ++ if (err) { ++ netdev_err(ndev, "register_netdev() failed\n"); ++ goto err3; ++ } ++ device_init_wakeup(&ndev->dev, WAKE_MAGIC); ++ ++ if (!(priv->einfo->phy_flags & GEMAC_NO_PHY)) { ++ err = pfe_phy_init(ndev); ++ if (err) { ++ netdev_err(ndev, "%s: pfe_phy_init() failed\n", ++ __func__); ++ goto err4; ++ } ++ } ++ ++ netif_carrier_on(ndev); ++ ++ /* Create all the sysfs files */ ++ if (pfe_eth_sysfs_init(ndev)) ++ goto err4; ++ ++ netif_info(priv, probe, ndev, "%s: created interface, baseaddr: %p\n", ++ __func__, priv->EMAC_baseaddr); ++ ++ return 0; ++err4: ++ unregister_netdev(ndev); ++err3: ++ pfe_eth_mdio_exit(priv->mii_bus); ++err2: ++ free_netdev(priv->ndev); ++err0: ++ return err; ++} ++ ++/* pfe_eth_init ++ */ ++int pfe_eth_init(struct pfe *pfe) ++{ ++ int ii = 0; ++ int err; ++ ++ pr_info("%s\n", __func__); ++ ++ cbus_emac_base[0] = EMAC1_BASE_ADDR; ++ cbus_emac_base[1] = EMAC2_BASE_ADDR; ++ ++ cbus_gpi_base[0] = EGPI1_BASE_ADDR; ++ cbus_gpi_base[1] = EGPI2_BASE_ADDR; ++ ++ for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) { ++ err = pfe_eth_init_one(pfe, ii); ++ if (err) ++ goto err0; ++ } ++ ++ return 0; ++ ++err0: ++ while (ii--) ++ pfe_eth_exit_one(pfe->eth.eth_priv[ii]); ++ ++ /* Register three network devices in the kernel */ ++ return err; ++} ++ ++/* pfe_eth_exit_one ++ */ ++static void pfe_eth_exit_one(struct pfe_eth_priv_s *priv) ++{ ++ netif_info(priv, probe, priv->ndev, "%s\n", __func__); ++ ++ pfe_eth_sysfs_exit(priv->ndev); ++ ++ unregister_netdev(priv->ndev); ++ ++ if (!(priv->einfo->phy_flags & GEMAC_NO_PHY)) ++ pfe_phy_exit(priv->ndev); ++ ++ if (priv->mii_bus) ++ pfe_eth_mdio_exit(priv->mii_bus); ++ ++ free_netdev(priv->ndev); ++} ++ ++/* pfe_eth_exit ++ */ ++void pfe_eth_exit(struct pfe *pfe) ++{ ++ int ii; ++ ++ pr_info("%s\n", __func__); ++ ++ for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--) ++ pfe_eth_exit_one(pfe->eth.eth_priv[ii]); ++} +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_eth.h +@@ -0,0 +1,184 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _PFE_ETH_H_ ++#define _PFE_ETH_H_ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define PFE_ETH_NAPI_STATS ++#define PFE_ETH_TX_STATS ++ ++#define PFE_ETH_FRAGS_MAX (65536 / HIF_RX_PKT_MIN_SIZE) ++#define LRO_LEN_COUNT_MAX 32 ++#define LRO_NB_COUNT_MAX 32 ++ ++#define PFE_PAUSE_FLAG_ENABLE 1 ++#define PFE_PAUSE_FLAG_AUTONEG 2 ++ ++/* GEMAC configured by SW */ ++/* GEMAC configured by phy lines (not for MII/GMII) */ ++ ++#define GEMAC_SW_FULL_DUPLEX BIT(9) ++#define GEMAC_SW_SPEED_10M (0 << 12) ++#define GEMAC_SW_SPEED_100M BIT(12) ++#define GEMAC_SW_SPEED_1G (2 << 12) ++ ++#define GEMAC_NO_PHY BIT(0) ++ ++struct ls1012a_eth_platform_data { ++ /* device specific information */ ++ u32 device_flags; ++ char name[16]; ++ ++ /* board specific information */ ++ u32 mii_config; ++ u32 phy_flags; ++ u32 gem_id; ++ u32 bus_id; ++ u32 phy_id; ++ u32 mdio_muxval; ++ u8 mac_addr[ETH_ALEN]; ++}; ++ ++struct ls1012a_mdio_platform_data { ++ int enabled; ++ int irq[32]; ++ u32 phy_mask; ++ int mdc_div; ++}; ++ ++struct ls1012a_pfe_platform_data { ++ struct ls1012a_eth_platform_data ls1012a_eth_pdata[3]; ++ struct ls1012a_mdio_platform_data ls1012a_mdio_pdata[3]; ++}; ++ ++#define NUM_GEMAC_SUPPORT 2 ++#define DRV_NAME "pfe-eth" ++#define DRV_VERSION "1.0" ++ ++#define LS1012A_TX_FAST_RECOVERY_TIMEOUT_MS 3 ++#define TX_POLL_TIMEOUT_MS 1000 ++ ++#define EMAC_TXQ_CNT 16 ++#define EMAC_TXQ_DEPTH (HIF_TX_DESC_NT) ++ ++#define JUMBO_FRAME_SIZE 10258 ++/* ++ * Client Tx queue threshold, for txQ flush condition. ++ * It must be smaller than the queue size (in case we ever change it in the ++ * future). ++ */ ++#define HIF_CL_TX_FLUSH_MARK 32 ++ ++/* ++ * Max number of TX resources (HIF descriptors or skbs) that will be released ++ * in a single go during batch recycling. ++ * Should be lower than the flush mark so the SW can provide the HW with a ++ * continuous stream of packets instead of bursts. ++ */ ++#define TX_FREE_MAX_COUNT 16 ++#define EMAC_RXQ_CNT 3 ++#define EMAC_RXQ_DEPTH HIF_RX_DESC_NT ++/* make sure clients can receive a full burst of packets */ ++#define EMAC_RMON_TXBYTES_POS 0x00 ++#define EMAC_RMON_RXBYTES_POS 0x14 ++ ++#define EMAC_QUEUENUM_MASK (emac_txq_cnt - 1) ++#define EMAC_MDIO_TIMEOUT 1000 ++#define MAX_UC_SPEC_ADDR_REG 31 ++ ++struct pfe_eth_fast_timer { ++ int queuenum; ++ struct hrtimer timer; ++ void *base; ++}; ++ ++struct pfe_eth_priv_s { ++ struct pfe *pfe; ++ struct hif_client_s client; ++ struct napi_struct lro_napi; ++ struct napi_struct low_napi; ++ struct napi_struct high_napi; ++ int low_tmu_q; ++ int high_tmu_q; ++ struct net_device_stats stats; ++ struct net_device *ndev; ++ int id; ++ int promisc; ++ unsigned int msg_enable; ++ unsigned int usr_features; ++ ++ spinlock_t lock; /* protect member variables */ ++ unsigned int event_status; ++ int irq; ++ void *EMAC_baseaddr; ++ /* This points to the EMAC base from where we access PHY */ ++ void *PHY_baseaddr; ++ void *GPI_baseaddr; ++ /* PHY stuff */ ++ struct phy_device *phydev; ++ int oldspeed; ++ int oldduplex; ++ int oldlink; ++ /* mdio info */ ++ int mdc_div; ++ struct mii_bus *mii_bus; ++ struct clk *gemtx_clk; ++ int wol; ++ int pause_flag; ++ ++ int default_priority; ++ struct pfe_eth_fast_timer fast_tx_timeout[EMAC_TXQ_CNT]; ++ ++ struct ls1012a_eth_platform_data *einfo; ++ struct sk_buff *skb_inflight[EMAC_RXQ_CNT + 6]; ++ ++#ifdef PFE_ETH_TX_STATS ++ unsigned int stop_queue_total[EMAC_TXQ_CNT]; ++ unsigned int stop_queue_hif[EMAC_TXQ_CNT]; ++ unsigned int stop_queue_hif_client[EMAC_TXQ_CNT]; ++ unsigned int stop_queue_credit[EMAC_TXQ_CNT]; ++ unsigned int clean_fail[EMAC_TXQ_CNT]; ++ unsigned int was_stopped[EMAC_TXQ_CNT]; ++#endif ++ ++#ifdef PFE_ETH_NAPI_STATS ++ unsigned int napi_counters[NAPI_MAX_COUNT]; ++#endif ++ unsigned int frags_inflight[EMAC_RXQ_CNT + 6]; ++}; ++ ++struct pfe_eth { ++ struct pfe_eth_priv_s *eth_priv[3]; ++}; ++ ++int pfe_eth_init(struct pfe *pfe); ++void pfe_eth_exit(struct pfe *pfe); ++int pfe_eth_suspend(struct net_device *dev); ++int pfe_eth_resume(struct net_device *dev); ++int pfe_eth_mdio_reset(struct mii_bus *bus); ++ ++#endif /* _PFE_ETH_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_firmware.c +@@ -0,0 +1,314 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++/* ++ * @file ++ * Contains all the functions to handle parsing and loading of PE firmware ++ * files. ++ */ ++#include ++ ++#include "pfe_mod.h" ++#include "pfe_firmware.h" ++#include "pfe/pfe.h" ++ ++static struct elf32_shdr *get_elf_section_header(const struct firmware *fw, ++ const char *section) ++{ ++ struct elf32_hdr *elf_hdr = (struct elf32_hdr *)fw->data; ++ struct elf32_shdr *shdr; ++ struct elf32_shdr *shdr_shstr; ++ Elf32_Off e_shoff = be32_to_cpu(elf_hdr->e_shoff); ++ Elf32_Half e_shentsize = be16_to_cpu(elf_hdr->e_shentsize); ++ Elf32_Half e_shnum = be16_to_cpu(elf_hdr->e_shnum); ++ Elf32_Half e_shstrndx = be16_to_cpu(elf_hdr->e_shstrndx); ++ Elf32_Off shstr_offset; ++ Elf32_Word sh_name; ++ const char *name; ++ int i; ++ ++ /* Section header strings */ ++ shdr_shstr = (struct elf32_shdr *)(fw->data + e_shoff + e_shstrndx * ++ e_shentsize); ++ shstr_offset = be32_to_cpu(shdr_shstr->sh_offset); ++ ++ for (i = 0; i < e_shnum; i++) { ++ shdr = (struct elf32_shdr *)(fw->data + e_shoff ++ + i * e_shentsize); ++ ++ sh_name = be32_to_cpu(shdr->sh_name); ++ ++ name = (const char *)(fw->data + shstr_offset + sh_name); ++ ++ if (!strcmp(name, section)) ++ return shdr; ++ } ++ ++ pr_err("%s: didn't find section %s\n", __func__, section); ++ ++ return NULL; ++} ++ ++#if defined(CFG_DIAGS) ++static int pfe_get_diags_info(const struct firmware *fw, struct pfe_diags_info ++ *diags_info) ++{ ++ struct elf32_shdr *shdr; ++ unsigned long offset, size; ++ ++ shdr = get_elf_section_header(fw, ".pfe_diags_str"); ++ if (shdr) { ++ offset = be32_to_cpu(shdr->sh_offset); ++ size = be32_to_cpu(shdr->sh_size); ++ diags_info->diags_str_base = be32_to_cpu(shdr->sh_addr); ++ diags_info->diags_str_size = size; ++ diags_info->diags_str_array = kmalloc(size, GFP_KERNEL); ++ memcpy(diags_info->diags_str_array, fw->data + offset, size); ++ ++ return 0; ++ } else { ++ return -1; ++ } ++} ++#endif ++ ++static void pfe_check_version_info(const struct firmware *fw) ++{ ++ /*static char *version = NULL;*/ ++ static char *version; ++ ++ struct elf32_shdr *shdr = get_elf_section_header(fw, ".version"); ++ ++ if (shdr) { ++ if (!version) { ++ /* ++ * this is the first fw we load, use its version ++ * string as reference (whatever it is) ++ */ ++ version = (char *)(fw->data + ++ be32_to_cpu(shdr->sh_offset)); ++ ++ pr_info("PFE binary version: %s\n", version); ++ } else { ++ /* ++ * already have loaded at least one firmware, check ++ * sequence can start now ++ */ ++ if (strcmp(version, (char *)(fw->data + ++ be32_to_cpu(shdr->sh_offset)))) { ++ pr_info( ++ "WARNING: PFE firmware binaries from incompatible version\n"); ++ } ++ } ++ } else { ++ /* ++ * version cannot be verified, a potential issue that should ++ * be reported ++ */ ++ pr_info( ++ "WARNING: PFE firmware binaries from incompatible version\n"); ++ } ++} ++ ++/* PFE elf firmware loader. ++ * Loads an elf firmware image into a list of PE's (specified using a bitmask) ++ * ++ * @param pe_mask Mask of PE id's to load firmware to ++ * @param fw Pointer to the firmware image ++ * ++ * @return 0 on success, a negative value on error ++ * ++ */ ++int pfe_load_elf(int pe_mask, const struct firmware *fw, struct pfe *pfe) ++{ ++ struct elf32_hdr *elf_hdr = (struct elf32_hdr *)fw->data; ++ Elf32_Half sections = be16_to_cpu(elf_hdr->e_shnum); ++ struct elf32_shdr *shdr = (struct elf32_shdr *)(fw->data + ++ be32_to_cpu(elf_hdr->e_shoff)); ++ int id, section; ++ int rc; ++ ++ pr_info("%s\n", __func__); ++ ++ /* Some sanity checks */ ++ if (strncmp(&elf_hdr->e_ident[EI_MAG0], ELFMAG, SELFMAG)) { ++ pr_err("%s: incorrect elf magic number\n", __func__); ++ return -EINVAL; ++ } ++ ++ if (elf_hdr->e_ident[EI_CLASS] != ELFCLASS32) { ++ pr_err("%s: incorrect elf class(%x)\n", __func__, ++ elf_hdr->e_ident[EI_CLASS]); ++ return -EINVAL; ++ } ++ ++ if (elf_hdr->e_ident[EI_DATA] != ELFDATA2MSB) { ++ pr_err("%s: incorrect elf data(%x)\n", __func__, ++ elf_hdr->e_ident[EI_DATA]); ++ return -EINVAL; ++ } ++ ++ if (be16_to_cpu(elf_hdr->e_type) != ET_EXEC) { ++ pr_err("%s: incorrect elf file type(%x)\n", __func__, ++ be16_to_cpu(elf_hdr->e_type)); ++ return -EINVAL; ++ } ++ ++ for (section = 0; section < sections; section++, shdr++) { ++ if (!(be32_to_cpu(shdr->sh_flags) & (SHF_WRITE | SHF_ALLOC | ++ SHF_EXECINSTR))) ++ continue; ++ ++ for (id = 0; id < MAX_PE; id++) ++ if (pe_mask & (1 << id)) { ++ rc = pe_load_elf_section(id, fw->data, shdr, ++ pfe->dev); ++ if (rc < 0) ++ goto err; ++ } ++ } ++ ++ pfe_check_version_info(fw); ++ ++ return 0; ++ ++err: ++ return rc; ++} ++ ++/* PFE firmware initialization. ++ * Loads different firmware files from filesystem. ++ * Initializes PE IMEM/DMEM and UTIL-PE DDR ++ * Initializes control path symbol addresses (by looking them up in the elf ++ * firmware files ++ * Takes PE's out of reset ++ * ++ * @return 0 on success, a negative value on error ++ * ++ */ ++int pfe_firmware_init(struct pfe *pfe) ++{ ++ const struct firmware *class_fw, *tmu_fw; ++ int rc = 0; ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ const char *util_fw_name; ++ const struct firmware *util_fw; ++#endif ++ ++ pr_info("%s\n", __func__); ++ ++ if (request_firmware(&class_fw, CLASS_FIRMWARE_FILENAME, pfe->dev)) { ++ pr_err("%s: request firmware %s failed\n", __func__, ++ CLASS_FIRMWARE_FILENAME); ++ rc = -ETIMEDOUT; ++ goto err0; ++ } ++ ++ if (request_firmware(&tmu_fw, TMU_FIRMWARE_FILENAME, pfe->dev)) { ++ pr_err("%s: request firmware %s failed\n", __func__, ++ TMU_FIRMWARE_FILENAME); ++ rc = -ETIMEDOUT; ++ goto err1; ++} ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ util_fw_name = UTIL_FIRMWARE_FILENAME; ++ ++ if (request_firmware(&util_fw, util_fw_name, pfe->dev)) { ++ pr_err("%s: request firmware %s failed\n", __func__, ++ util_fw_name); ++ rc = -ETIMEDOUT; ++ goto err2; ++ } ++#endif ++ rc = pfe_load_elf(CLASS_MASK, class_fw, pfe); ++ if (rc < 0) { ++ pr_err("%s: class firmware load failed\n", __func__); ++ goto err3; ++ } ++ ++#if defined(CFG_DIAGS) ++ rc = pfe_get_diags_info(class_fw, &pfe->diags.class_diags_info); ++ if (rc < 0) { ++ pr_warn( ++ "PFE diags won't be available for class PEs\n"); ++ rc = 0; ++ } ++#endif ++ ++ rc = pfe_load_elf(TMU_MASK, tmu_fw, pfe); ++ if (rc < 0) { ++ pr_err("%s: tmu firmware load failed\n", __func__); ++ goto err3; ++ } ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ rc = pfe_load_elf(UTIL_MASK, util_fw, pfe); ++ if (rc < 0) { ++ pr_err("%s: util firmware load failed\n", __func__); ++ goto err3; ++ } ++ ++#if defined(CFG_DIAGS) ++ rc = pfe_get_diags_info(util_fw, &pfe->diags.util_diags_info); ++ if (rc < 0) { ++ pr_warn( ++ "PFE diags won't be available for util PE\n"); ++ rc = 0; ++ } ++#endif ++ ++ util_enable(); ++#endif ++ ++ tmu_enable(0xf); ++ class_enable(); ++ ++err3: ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ release_firmware(util_fw); ++ ++err2: ++#endif ++ release_firmware(tmu_fw); ++ ++err1: ++ release_firmware(class_fw); ++ ++err0: ++ return rc; ++} ++ ++/* PFE firmware cleanup ++ * Puts PE's in reset ++ * ++ * ++ */ ++void pfe_firmware_exit(struct pfe *pfe) ++{ ++ pr_info("%s\n", __func__); ++ ++ if (pe_reset_all(&pfe->ctrl) != 0) ++ pr_err("Error: Failed to stop PEs, PFE reload may not work correctly\n"); ++ ++ class_disable(); ++ tmu_disable(0xf); ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ util_disable(); ++#endif ++} +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_firmware.h +@@ -0,0 +1,32 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _PFE_FIRMWARE_H_ ++#define _PFE_FIRMWARE_H_ ++ ++#define CLASS_FIRMWARE_FILENAME "ppfe_class_ls1012a.elf" ++#define TMU_FIRMWARE_FILENAME "ppfe_tmu_ls1012a.elf" ++ ++#define PFE_FW_CHECK_PASS 0 ++#define PFE_FW_CHECK_FAIL 1 ++#define NUM_PFE_FW 3 ++ ++int pfe_firmware_init(struct pfe *pfe); ++void pfe_firmware_exit(struct pfe *pfe); ++ ++#endif /* _PFE_FIRMWARE_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_hal.c +@@ -0,0 +1,1516 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#include "pfe_mod.h" ++#include "pfe/pfe.h" ++ ++void *cbus_base_addr; ++void *ddr_base_addr; ++unsigned long ddr_phys_base_addr; ++unsigned int ddr_size; ++ ++static struct pe_info pe[MAX_PE]; ++ ++/* Initializes the PFE library. ++ * Must be called before using any of the library functions. ++ * ++ * @param[in] cbus_base CBUS virtual base address (as mapped in ++ * the host CPU address space) ++ * @param[in] ddr_base PFE DDR range virtual base address (as ++ * mapped in the host CPU address space) ++ * @param[in] ddr_phys_base PFE DDR range physical base address (as ++ * mapped in platform) ++ * @param[in] size PFE DDR range size (as defined by the host ++ * software) ++ */ ++void pfe_lib_init(void *cbus_base, void *ddr_base, unsigned long ddr_phys_base, ++ unsigned int size) ++{ ++ cbus_base_addr = cbus_base; ++ ddr_base_addr = ddr_base; ++ ddr_phys_base_addr = ddr_phys_base; ++ ddr_size = size; ++ ++ pe[CLASS0_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(0); ++ pe[CLASS0_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(0); ++ pe[CLASS0_ID].pmem_size = CLASS_IMEM_SIZE; ++ pe[CLASS0_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; ++ pe[CLASS0_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; ++ pe[CLASS0_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; ++ ++ pe[CLASS1_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(1); ++ pe[CLASS1_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(1); ++ pe[CLASS1_ID].pmem_size = CLASS_IMEM_SIZE; ++ pe[CLASS1_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; ++ pe[CLASS1_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; ++ pe[CLASS1_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; ++ ++ pe[CLASS2_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(2); ++ pe[CLASS2_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(2); ++ pe[CLASS2_ID].pmem_size = CLASS_IMEM_SIZE; ++ pe[CLASS2_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; ++ pe[CLASS2_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; ++ pe[CLASS2_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; ++ ++ pe[CLASS3_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(3); ++ pe[CLASS3_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(3); ++ pe[CLASS3_ID].pmem_size = CLASS_IMEM_SIZE; ++ pe[CLASS3_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; ++ pe[CLASS3_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; ++ pe[CLASS3_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; ++ ++ pe[CLASS4_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(4); ++ pe[CLASS4_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(4); ++ pe[CLASS4_ID].pmem_size = CLASS_IMEM_SIZE; ++ pe[CLASS4_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; ++ pe[CLASS4_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; ++ pe[CLASS4_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; ++ ++ pe[CLASS5_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(5); ++ pe[CLASS5_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(5); ++ pe[CLASS5_ID].pmem_size = CLASS_IMEM_SIZE; ++ pe[CLASS5_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; ++ pe[CLASS5_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; ++ pe[CLASS5_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; ++ ++ pe[TMU0_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(0); ++ pe[TMU0_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(0); ++ pe[TMU0_ID].pmem_size = TMU_IMEM_SIZE; ++ pe[TMU0_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA; ++ pe[TMU0_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR; ++ pe[TMU0_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA; ++ ++ pe[TMU1_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(1); ++ pe[TMU1_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(1); ++ pe[TMU1_ID].pmem_size = TMU_IMEM_SIZE; ++ pe[TMU1_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA; ++ pe[TMU1_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR; ++ pe[TMU1_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA; ++ ++ pe[TMU3_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(3); ++ pe[TMU3_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(3); ++ pe[TMU3_ID].pmem_size = TMU_IMEM_SIZE; ++ pe[TMU3_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA; ++ pe[TMU3_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR; ++ pe[TMU3_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA; ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ pe[UTIL_ID].dmem_base_addr = UTIL_DMEM_BASE_ADDR; ++ pe[UTIL_ID].mem_access_wdata = UTIL_MEM_ACCESS_WDATA; ++ pe[UTIL_ID].mem_access_addr = UTIL_MEM_ACCESS_ADDR; ++ pe[UTIL_ID].mem_access_rdata = UTIL_MEM_ACCESS_RDATA; ++#endif ++} ++ ++/* Writes a buffer to PE internal memory from the host ++ * through indirect access registers. ++ * ++ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ++ * ..., UTIL_ID) ++ * @param[in] src Buffer source address ++ * @param[in] mem_access_addr DMEM destination address (must be 32bit ++ * aligned) ++ * @param[in] len Number of bytes to copy ++ */ ++void pe_mem_memcpy_to32(int id, u32 mem_access_addr, const void *src, unsigned ++int len) ++{ ++ u32 offset = 0, val, addr; ++ unsigned int len32 = len >> 2; ++ int i; ++ ++ addr = mem_access_addr | PE_MEM_ACCESS_WRITE | ++ PE_MEM_ACCESS_BYTE_ENABLE(0, 4); ++ ++ for (i = 0; i < len32; i++, offset += 4, src += 4) { ++ val = *(u32 *)src; ++ writel(cpu_to_be32(val), pe[id].mem_access_wdata); ++ writel(addr + offset, pe[id].mem_access_addr); ++ } ++ ++ len = (len & 0x3); ++ if (len) { ++ val = 0; ++ ++ addr = (mem_access_addr | PE_MEM_ACCESS_WRITE | ++ PE_MEM_ACCESS_BYTE_ENABLE(0, len)) + offset; ++ ++ for (i = 0; i < len; i++, src++) ++ val |= (*(u8 *)src) << (8 * i); ++ ++ writel(cpu_to_be32(val), pe[id].mem_access_wdata); ++ writel(addr, pe[id].mem_access_addr); ++ } ++} ++ ++/* Writes a buffer to PE internal data memory (DMEM) from the host ++ * through indirect access registers. ++ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ++ * ..., UTIL_ID) ++ * @param[in] src Buffer source address ++ * @param[in] dst DMEM destination address (must be 32bit ++ * aligned) ++ * @param[in] len Number of bytes to copy ++ */ ++void pe_dmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len) ++{ ++ pe_mem_memcpy_to32(id, pe[id].dmem_base_addr | dst | ++ PE_MEM_ACCESS_DMEM, src, len); ++} ++ ++/* Writes a buffer to PE internal program memory (PMEM) from the host ++ * through indirect access registers. ++ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ++ * ..., TMU3_ID) ++ * @param[in] src Buffer source address ++ * @param[in] dst PMEM destination address (must be 32bit ++ * aligned) ++ * @param[in] len Number of bytes to copy ++ */ ++void pe_pmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len) ++{ ++ pe_mem_memcpy_to32(id, pe[id].pmem_base_addr | (dst & (pe[id].pmem_size ++ - 1)) | PE_MEM_ACCESS_IMEM, src, len); ++} ++ ++/* Reads PE internal program memory (IMEM) from the host ++ * through indirect access registers. ++ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ++ * ..., TMU3_ID) ++ * @param[in] addr PMEM read address (must be aligned on size) ++ * @param[in] size Number of bytes to read (maximum 4, must not ++ * cross 32bit boundaries) ++ * @return the data read (in PE endianness, i.e BE). ++ */ ++u32 pe_pmem_read(int id, u32 addr, u8 size) ++{ ++ u32 offset = addr & 0x3; ++ u32 mask = 0xffffffff >> ((4 - size) << 3); ++ u32 val; ++ ++ addr = pe[id].pmem_base_addr | ((addr & ~0x3) & (pe[id].pmem_size - 1)) ++ | PE_MEM_ACCESS_IMEM | PE_MEM_ACCESS_BYTE_ENABLE(offset, size); ++ ++ writel(addr, pe[id].mem_access_addr); ++ val = be32_to_cpu(readl(pe[id].mem_access_rdata)); ++ ++ return (val >> (offset << 3)) & mask; ++} ++ ++/* Writes PE internal data memory (DMEM) from the host ++ * through indirect access registers. ++ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ++ * ..., UTIL_ID) ++ * @param[in] addr DMEM write address (must be aligned on size) ++ * @param[in] val Value to write (in PE endianness, i.e BE) ++ * @param[in] size Number of bytes to write (maximum 4, must not ++ * cross 32bit boundaries) ++ */ ++void pe_dmem_write(int id, u32 val, u32 addr, u8 size) ++{ ++ u32 offset = addr & 0x3; ++ ++ addr = pe[id].dmem_base_addr | (addr & ~0x3) | PE_MEM_ACCESS_WRITE | ++ PE_MEM_ACCESS_DMEM | PE_MEM_ACCESS_BYTE_ENABLE(offset, size); ++ ++ /* Indirect access interface is byte swapping data being written */ ++ writel(cpu_to_be32(val << (offset << 3)), pe[id].mem_access_wdata); ++ writel(addr, pe[id].mem_access_addr); ++} ++ ++/* Reads PE internal data memory (DMEM) from the host ++ * through indirect access registers. ++ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ++ * ..., UTIL_ID) ++ * @param[in] addr DMEM read address (must be aligned on size) ++ * @param[in] size Number of bytes to read (maximum 4, must not ++ * cross 32bit boundaries) ++ * @return the data read (in PE endianness, i.e BE). ++ */ ++u32 pe_dmem_read(int id, u32 addr, u8 size) ++{ ++ u32 offset = addr & 0x3; ++ u32 mask = 0xffffffff >> ((4 - size) << 3); ++ u32 val; ++ ++ addr = pe[id].dmem_base_addr | (addr & ~0x3) | PE_MEM_ACCESS_DMEM | ++ PE_MEM_ACCESS_BYTE_ENABLE(offset, size); ++ ++ writel(addr, pe[id].mem_access_addr); ++ ++ /* Indirect access interface is byte swapping data being read */ ++ val = be32_to_cpu(readl(pe[id].mem_access_rdata)); ++ ++ return (val >> (offset << 3)) & mask; ++} ++ ++/* This function is used to write to CLASS internal bus peripherals (ccu, ++ * pe-lem) from the host ++ * through indirect access registers. ++ * @param[in] val value to write ++ * @param[in] addr Address to write to (must be aligned on size) ++ * @param[in] size Number of bytes to write (1, 2 or 4) ++ * ++ */ ++void class_bus_write(u32 val, u32 addr, u8 size) ++{ ++ u32 offset = addr & 0x3; ++ ++ writel((addr & CLASS_BUS_ACCESS_BASE_MASK), CLASS_BUS_ACCESS_BASE); ++ ++ addr = (addr & ~CLASS_BUS_ACCESS_BASE_MASK) | PE_MEM_ACCESS_WRITE | ++ (size << 24); ++ ++ writel(cpu_to_be32(val << (offset << 3)), CLASS_BUS_ACCESS_WDATA); ++ writel(addr, CLASS_BUS_ACCESS_ADDR); ++} ++ ++/* Reads from CLASS internal bus peripherals (ccu, pe-lem) from the host ++ * through indirect access registers. ++ * @param[in] addr Address to read from (must be aligned on size) ++ * @param[in] size Number of bytes to read (1, 2 or 4) ++ * @return the read data ++ * ++ */ ++u32 class_bus_read(u32 addr, u8 size) ++{ ++ u32 offset = addr & 0x3; ++ u32 mask = 0xffffffff >> ((4 - size) << 3); ++ u32 val; ++ ++ writel((addr & CLASS_BUS_ACCESS_BASE_MASK), CLASS_BUS_ACCESS_BASE); ++ ++ addr = (addr & ~CLASS_BUS_ACCESS_BASE_MASK) | (size << 24); ++ ++ writel(addr, CLASS_BUS_ACCESS_ADDR); ++ val = be32_to_cpu(readl(CLASS_BUS_ACCESS_RDATA)); ++ ++ return (val >> (offset << 3)) & mask; ++} ++ ++/* Writes data to the cluster memory (PE_LMEM) ++ * @param[in] dst PE LMEM destination address (must be 32bit aligned) ++ * @param[in] src Buffer source address ++ * @param[in] len Number of bytes to copy ++ */ ++void class_pe_lmem_memcpy_to32(u32 dst, const void *src, unsigned int len) ++{ ++ u32 len32 = len >> 2; ++ int i; ++ ++ for (i = 0; i < len32; i++, src += 4, dst += 4) ++ class_bus_write(*(u32 *)src, dst, 4); ++ ++ if (len & 0x2) { ++ class_bus_write(*(u16 *)src, dst, 2); ++ src += 2; ++ dst += 2; ++ } ++ ++ if (len & 0x1) { ++ class_bus_write(*(u8 *)src, dst, 1); ++ src++; ++ dst++; ++ } ++} ++ ++/* Writes value to the cluster memory (PE_LMEM) ++ * @param[in] dst PE LMEM destination address (must be 32bit aligned) ++ * @param[in] val Value to write ++ * @param[in] len Number of bytes to write ++ */ ++void class_pe_lmem_memset(u32 dst, int val, unsigned int len) ++{ ++ u32 len32 = len >> 2; ++ int i; ++ ++ val = val | (val << 8) | (val << 16) | (val << 24); ++ ++ for (i = 0; i < len32; i++, dst += 4) ++ class_bus_write(val, dst, 4); ++ ++ if (len & 0x2) { ++ class_bus_write(val, dst, 2); ++ dst += 2; ++ } ++ ++ if (len & 0x1) { ++ class_bus_write(val, dst, 1); ++ dst++; ++ } ++} ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ ++/* Writes UTIL program memory (DDR) from the host. ++ * ++ * @param[in] addr Address to write (virtual, must be aligned on size) ++ * @param[in] val Value to write (in PE endianness, i.e BE) ++ * @param[in] size Number of bytes to write (2 or 4) ++ */ ++static void util_pmem_write(u32 val, void *addr, u8 size) ++{ ++ void *addr64 = (void *)((unsigned long)addr & ~0x7); ++ unsigned long off = 8 - ((unsigned long)addr & 0x7) - size; ++ ++ /* ++ * IMEM should be loaded as a 64bit swapped value in a 64bit aligned ++ * location ++ */ ++ if (size == 4) ++ writel(be32_to_cpu(val), addr64 + off); ++ else ++ writew(be16_to_cpu((u16)val), addr64 + off); ++} ++ ++/* Writes a buffer to UTIL program memory (DDR) from the host. ++ * ++ * @param[in] dst Address to write (virtual, must be at least 16bit ++ * aligned) ++ * @param[in] src Buffer to write (in PE endianness, i.e BE, must have ++ * same alignment as dst) ++ * @param[in] len Number of bytes to write (must be at least 16bit ++ * aligned) ++ */ ++static void util_pmem_memcpy(void *dst, const void *src, unsigned int len) ++{ ++ unsigned int len32; ++ int i; ++ ++ if ((unsigned long)src & 0x2) { ++ util_pmem_write(*(u16 *)src, dst, 2); ++ src += 2; ++ dst += 2; ++ len -= 2; ++ } ++ ++ len32 = len >> 2; ++ ++ for (i = 0; i < len32; i++, dst += 4, src += 4) ++ util_pmem_write(*(u32 *)src, dst, 4); ++ ++ if (len & 0x2) ++ util_pmem_write(*(u16 *)src, dst, len & 0x2); ++} ++#endif ++ ++/* Loads an elf section into pmem ++ * Code needs to be at least 16bit aligned and only PROGBITS sections are ++ * supported ++ * ++ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ..., ++ * TMU3_ID) ++ * @param[in] data pointer to the elf firmware ++ * @param[in] shdr pointer to the elf section header ++ * ++ */ ++static int pe_load_pmem_section(int id, const void *data, ++ struct elf32_shdr *shdr) ++{ ++ u32 offset = be32_to_cpu(shdr->sh_offset); ++ u32 addr = be32_to_cpu(shdr->sh_addr); ++ u32 size = be32_to_cpu(shdr->sh_size); ++ u32 type = be32_to_cpu(shdr->sh_type); ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ if (id == UTIL_ID) { ++ pr_err("%s: unsupported pmem section for UTIL\n", ++ __func__); ++ return -EINVAL; ++ } ++#endif ++ ++ if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) { ++ pr_err( ++ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n" ++ , __func__, addr, (unsigned long)data + offset); ++ ++ return -EINVAL; ++ } ++ ++ if (addr & 0x1) { ++ pr_err("%s: load address(%x) is not 16bit aligned\n", ++ __func__, addr); ++ return -EINVAL; ++ } ++ ++ if (size & 0x1) { ++ pr_err("%s: load size(%x) is not 16bit aligned\n", ++ __func__, size); ++ return -EINVAL; ++ } ++ ++ switch (type) { ++ case SHT_PROGBITS: ++ pe_pmem_memcpy_to32(id, addr, data + offset, size); ++ ++ break; ++ ++ default: ++ pr_err("%s: unsupported section type(%x)\n", __func__, ++ type); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* Loads an elf section into dmem ++ * Data needs to be at least 32bit aligned, NOBITS sections are correctly ++ * initialized to 0 ++ * ++ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ++ * ..., UTIL_ID) ++ * @param[in] data pointer to the elf firmware ++ * @param[in] shdr pointer to the elf section header ++ * ++ */ ++static int pe_load_dmem_section(int id, const void *data, ++ struct elf32_shdr *shdr) ++{ ++ u32 offset = be32_to_cpu(shdr->sh_offset); ++ u32 addr = be32_to_cpu(shdr->sh_addr); ++ u32 size = be32_to_cpu(shdr->sh_size); ++ u32 type = be32_to_cpu(shdr->sh_type); ++ u32 size32 = size >> 2; ++ int i; ++ ++ if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) { ++ pr_err( ++ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n", ++ __func__, addr, (unsigned long)data + offset); ++ ++ return -EINVAL; ++ } ++ ++ if (addr & 0x3) { ++ pr_err("%s: load address(%x) is not 32bit aligned\n", ++ __func__, addr); ++ return -EINVAL; ++ } ++ ++ switch (type) { ++ case SHT_PROGBITS: ++ pe_dmem_memcpy_to32(id, addr, data + offset, size); ++ break; ++ ++ case SHT_NOBITS: ++ for (i = 0; i < size32; i++, addr += 4) ++ pe_dmem_write(id, 0, addr, 4); ++ ++ if (size & 0x3) ++ pe_dmem_write(id, 0, addr, size & 0x3); ++ ++ break; ++ ++ default: ++ pr_err("%s: unsupported section type(%x)\n", __func__, ++ type); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* Loads an elf section into DDR ++ * Data needs to be at least 32bit aligned, NOBITS sections are correctly ++ * initialized to 0 ++ * ++ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ++ * ..., UTIL_ID) ++ * @param[in] data pointer to the elf firmware ++ * @param[in] shdr pointer to the elf section header ++ * ++ */ ++static int pe_load_ddr_section(int id, const void *data, ++ struct elf32_shdr *shdr, ++ struct device *dev) { ++ u32 offset = be32_to_cpu(shdr->sh_offset); ++ u32 addr = be32_to_cpu(shdr->sh_addr); ++ u32 size = be32_to_cpu(shdr->sh_size); ++ u32 type = be32_to_cpu(shdr->sh_type); ++ u32 flags = be32_to_cpu(shdr->sh_flags); ++ ++ switch (type) { ++ case SHT_PROGBITS: ++ if (flags & SHF_EXECINSTR) { ++ if (id <= CLASS_MAX_ID) { ++ /* DO the loading only once in DDR */ ++ if (id == CLASS0_ID) { ++ pr_err( ++ "%s: load address(%x) and elf file address(%lx) rcvd\n", ++ __func__, addr, ++ (unsigned long)data + offset); ++ if (((unsigned long)(data + offset) ++ & 0x3) != (addr & 0x3)) { ++ pr_err( ++ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n" ++ , __func__, addr, ++ (unsigned long)data + offset); ++ ++ return -EINVAL; ++ } ++ ++ if (addr & 0x1) { ++ pr_err( ++ "%s: load address(%x) is not 16bit aligned\n" ++ , __func__, addr); ++ return -EINVAL; ++ } ++ ++ if (size & 0x1) { ++ pr_err( ++ "%s: load length(%x) is not 16bit aligned\n" ++ , __func__, size); ++ return -EINVAL; ++ } ++ memcpy(DDR_PHYS_TO_VIRT( ++ DDR_PFE_TO_PHYS(addr)), ++ data + offset, size); ++ } ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ } else if (id == UTIL_ID) { ++ if (((unsigned long)(data + offset) & 0x3) ++ != (addr & 0x3)) { ++ pr_err( ++ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n" ++ , __func__, addr, ++ (unsigned long)data + offset); ++ ++ return -EINVAL; ++ } ++ ++ if (addr & 0x1) { ++ pr_err( ++ "%s: load address(%x) is not 16bit aligned\n" ++ , __func__, addr); ++ return -EINVAL; ++ } ++ ++ if (size & 0x1) { ++ pr_err( ++ "%s: load length(%x) is not 16bit aligned\n" ++ , __func__, size); ++ return -EINVAL; ++ } ++ ++ util_pmem_memcpy(DDR_PHYS_TO_VIRT( ++ DDR_PFE_TO_PHYS(addr)), ++ data + offset, size); ++ } ++#endif ++ } else { ++ pr_err( ++ "%s: unsupported ddr section type(%x) for PE(%d)\n" ++ , __func__, type, id); ++ return -EINVAL; ++ } ++ ++ } else { ++ memcpy(DDR_PHYS_TO_VIRT(DDR_PFE_TO_PHYS(addr)), data ++ + offset, size); ++ } ++ ++ break; ++ ++ case SHT_NOBITS: ++ memset(DDR_PHYS_TO_VIRT(DDR_PFE_TO_PHYS(addr)), 0, size); ++ ++ break; ++ ++ default: ++ pr_err("%s: unsupported section type(%x)\n", __func__, ++ type); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* Loads an elf section into pe lmem ++ * Data needs to be at least 32bit aligned, NOBITS sections are correctly ++ * initialized to 0 ++ * ++ * @param[in] id PE identification (CLASS0_ID,..., CLASS5_ID) ++ * @param[in] data pointer to the elf firmware ++ * @param[in] shdr pointer to the elf section header ++ * ++ */ ++static int pe_load_pe_lmem_section(int id, const void *data, ++ struct elf32_shdr *shdr) ++{ ++ u32 offset = be32_to_cpu(shdr->sh_offset); ++ u32 addr = be32_to_cpu(shdr->sh_addr); ++ u32 size = be32_to_cpu(shdr->sh_size); ++ u32 type = be32_to_cpu(shdr->sh_type); ++ ++ if (id > CLASS_MAX_ID) { ++ pr_err( ++ "%s: unsupported pe-lmem section type(%x) for PE(%d)\n", ++ __func__, type, id); ++ return -EINVAL; ++ } ++ ++ if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) { ++ pr_err( ++ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n", ++ __func__, addr, (unsigned long)data + offset); ++ ++ return -EINVAL; ++ } ++ ++ if (addr & 0x3) { ++ pr_err("%s: load address(%x) is not 32bit aligned\n", ++ __func__, addr); ++ return -EINVAL; ++ } ++ ++ switch (type) { ++ case SHT_PROGBITS: ++ class_pe_lmem_memcpy_to32(addr, data + offset, size); ++ break; ++ ++ case SHT_NOBITS: ++ class_pe_lmem_memset(addr, 0, size); ++ break; ++ ++ default: ++ pr_err("%s: unsupported section type(%x)\n", __func__, ++ type); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* Loads an elf section into a PE ++ * For now only supports loading a section to dmem (all PE's), pmem (class and ++ * tmu PE's), ++ * DDDR (util PE code) ++ * ++ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ++ * ..., UTIL_ID) ++ * @param[in] data pointer to the elf firmware ++ * @param[in] shdr pointer to the elf section header ++ * ++ */ ++int pe_load_elf_section(int id, const void *data, struct elf32_shdr *shdr, ++ struct device *dev) { ++ u32 addr = be32_to_cpu(shdr->sh_addr); ++ u32 size = be32_to_cpu(shdr->sh_size); ++ ++ if (IS_DMEM(addr, size)) ++ return pe_load_dmem_section(id, data, shdr); ++ else if (IS_PMEM(addr, size)) ++ return pe_load_pmem_section(id, data, shdr); ++ else if (IS_PFE_LMEM(addr, size)) ++ return 0; ++ else if (IS_PHYS_DDR(addr, size)) ++ return pe_load_ddr_section(id, data, shdr, dev); ++ else if (IS_PE_LMEM(addr, size)) ++ return pe_load_pe_lmem_section(id, data, shdr); ++ ++ pr_err("%s: unsupported memory range(%x)\n", __func__, ++ addr); ++ return 0; ++} ++ ++/**************************** BMU ***************************/ ++ ++/* Initializes a BMU block. ++ * @param[in] base BMU block base address ++ * @param[in] cfg BMU configuration ++ */ ++void bmu_init(void *base, struct BMU_CFG *cfg) ++{ ++ bmu_disable(base); ++ ++ bmu_set_config(base, cfg); ++ ++ bmu_reset(base); ++} ++ ++/* Resets a BMU block. ++ * @param[in] base BMU block base address ++ */ ++void bmu_reset(void *base) ++{ ++ writel(CORE_SW_RESET, base + BMU_CTRL); ++ ++ /* Wait for self clear */ ++ while (readl(base + BMU_CTRL) & CORE_SW_RESET) ++ ; ++} ++ ++/* Enabled a BMU block. ++ * @param[in] base BMU block base address ++ */ ++void bmu_enable(void *base) ++{ ++ writel(CORE_ENABLE, base + BMU_CTRL); ++} ++ ++/* Disables a BMU block. ++ * @param[in] base BMU block base address ++ */ ++void bmu_disable(void *base) ++{ ++ writel(CORE_DISABLE, base + BMU_CTRL); ++} ++ ++/* Sets the configuration of a BMU block. ++ * @param[in] base BMU block base address ++ * @param[in] cfg BMU configuration ++ */ ++void bmu_set_config(void *base, struct BMU_CFG *cfg) ++{ ++ writel(cfg->baseaddr, base + BMU_UCAST_BASE_ADDR); ++ writel(cfg->count & 0xffff, base + BMU_UCAST_CONFIG); ++ writel(cfg->size & 0xffff, base + BMU_BUF_SIZE); ++ ++ /* Interrupts are never used */ ++ writel(cfg->low_watermark, base + BMU_LOW_WATERMARK); ++ writel(cfg->high_watermark, base + BMU_HIGH_WATERMARK); ++ writel(0x0, base + BMU_INT_ENABLE); ++} ++ ++/**************************** MTIP GEMAC ***************************/ ++ ++/* Enable Rx Checksum Engine. With this enabled, Frame with bad IP, ++ * TCP or UDP checksums are discarded ++ * ++ * @param[in] base GEMAC base address. ++ */ ++void gemac_enable_rx_checksum_offload(void *base) ++{ ++ /*Do not find configuration to do this */ ++} ++ ++/* Disable Rx Checksum Engine. ++ * ++ * @param[in] base GEMAC base address. ++ */ ++void gemac_disable_rx_checksum_offload(void *base) ++{ ++ /*Do not find configuration to do this */ ++} ++ ++/* GEMAC set speed. ++ * @param[in] base GEMAC base address ++ * @param[in] speed GEMAC speed (10, 100 or 1000 Mbps) ++ */ ++void gemac_set_speed(void *base, enum mac_speed gem_speed) ++{ ++ u32 ecr = readl(base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_SPEED; ++ u32 rcr = readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_RMII_10T; ++ ++ switch (gem_speed) { ++ case SPEED_10M: ++ rcr |= EMAC_RCNTRL_RMII_10T; ++ break; ++ ++ case SPEED_1000M: ++ ecr |= EMAC_ECNTRL_SPEED; ++ break; ++ ++ case SPEED_100M: ++ default: ++ /*It is in 100M mode */ ++ break; ++ } ++ writel(ecr, (base + EMAC_ECNTRL_REG)); ++ writel(rcr, (base + EMAC_RCNTRL_REG)); ++} ++ ++/* GEMAC set duplex. ++ * @param[in] base GEMAC base address ++ * @param[in] duplex GEMAC duplex mode (Full, Half) ++ */ ++void gemac_set_duplex(void *base, int duplex) ++{ ++ if (duplex == DUPLEX_HALF) { ++ writel(readl(base + EMAC_TCNTRL_REG) & ~EMAC_TCNTRL_FDEN, base ++ + EMAC_TCNTRL_REG); ++ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_DRT, (base ++ + EMAC_RCNTRL_REG)); ++ } else{ ++ writel(readl(base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_FDEN, base ++ + EMAC_TCNTRL_REG); ++ writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_DRT, (base ++ + EMAC_RCNTRL_REG)); ++ } ++} ++ ++/* GEMAC set mode. ++ * @param[in] base GEMAC base address ++ * @param[in] mode GEMAC operation mode (MII, RMII, RGMII, SGMII) ++ */ ++void gemac_set_mode(void *base, int mode) ++{ ++ u32 val = readl(base + EMAC_RCNTRL_REG); ++ ++ /*Remove loopbank*/ ++ val &= ~EMAC_RCNTRL_LOOP; ++ ++ /*Enable flow control and MII mode*/ ++ val |= (EMAC_RCNTRL_FCE | EMAC_RCNTRL_MII_MODE); ++ ++ writel(val, base + EMAC_RCNTRL_REG); ++} ++ ++/* GEMAC enable function. ++ * @param[in] base GEMAC base address ++ */ ++void gemac_enable(void *base) ++{ ++ writel(readl(base + EMAC_ECNTRL_REG) | EMAC_ECNTRL_ETHER_EN, base + ++ EMAC_ECNTRL_REG); ++} ++ ++/* GEMAC disable function. ++ * @param[in] base GEMAC base address ++ */ ++void gemac_disable(void *base) ++{ ++ writel(readl(base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_ETHER_EN, base + ++ EMAC_ECNTRL_REG); ++} ++ ++/* GEMAC TX disable function. ++ * @param[in] base GEMAC base address ++ */ ++void gemac_tx_disable(void *base) ++{ ++ writel(readl(base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_GTS, base + ++ EMAC_TCNTRL_REG); ++} ++ ++void gemac_tx_enable(void *base) ++{ ++ writel(readl(base + EMAC_TCNTRL_REG) & ~EMAC_TCNTRL_GTS, base + ++ EMAC_TCNTRL_REG); ++} ++ ++/* Sets the hash register of the MAC. ++ * This register is used for matching unicast and multicast frames. ++ * ++ * @param[in] base GEMAC base address. ++ * @param[in] hash 64-bit hash to be configured. ++ */ ++void gemac_set_hash(void *base, struct pfe_mac_addr *hash) ++{ ++ writel(hash->bottom, base + EMAC_GALR); ++ writel(hash->top, base + EMAC_GAUR); ++} ++ ++void gemac_set_laddrN(void *base, struct pfe_mac_addr *address, ++ unsigned int entry_index) ++{ ++ if ((entry_index < 1) || (entry_index > EMAC_SPEC_ADDR_MAX)) ++ return; ++ ++ entry_index = entry_index - 1; ++ if (entry_index < 1) { ++ writel(htonl(address->bottom), base + EMAC_PHY_ADDR_LOW); ++ writel((htonl(address->top) | 0x8808), base + ++ EMAC_PHY_ADDR_HIGH); ++ } else { ++ writel(htonl(address->bottom), base + ((entry_index - 1) * 8) ++ + EMAC_SMAC_0_0); ++ writel((htonl(address->top) | 0x8808), base + ((entry_index - ++ 1) * 8) + EMAC_SMAC_0_1); ++ } ++} ++ ++void gemac_clear_laddrN(void *base, unsigned int entry_index) ++{ ++ if ((entry_index < 1) || (entry_index > EMAC_SPEC_ADDR_MAX)) ++ return; ++ ++ entry_index = entry_index - 1; ++ if (entry_index < 1) { ++ writel(0, base + EMAC_PHY_ADDR_LOW); ++ writel(0, base + EMAC_PHY_ADDR_HIGH); ++ } else { ++ writel(0, base + ((entry_index - 1) * 8) + EMAC_SMAC_0_0); ++ writel(0, base + ((entry_index - 1) * 8) + EMAC_SMAC_0_1); ++ } ++} ++ ++/* Set the loopback mode of the MAC. This can be either no loopback for ++ * normal operation, local loopback through MAC internal loopback module or PHY ++ * loopback for external loopback through a PHY. This asserts the external ++ * loop pin. ++ * ++ * @param[in] base GEMAC base address. ++ * @param[in] gem_loop Loopback mode to be enabled. LB_LOCAL - MAC ++ * Loopback, ++ * LB_EXT - PHY Loopback. ++ */ ++void gemac_set_loop(void *base, enum mac_loop gem_loop) ++{ ++ pr_info("%s()\n", __func__); ++ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_LOOP, (base + ++ EMAC_RCNTRL_REG)); ++} ++ ++/* GEMAC allow frames ++ * @param[in] base GEMAC base address ++ */ ++void gemac_enable_copy_all(void *base) ++{ ++ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_PROM, (base + ++ EMAC_RCNTRL_REG)); ++} ++ ++/* GEMAC do not allow frames ++ * @param[in] base GEMAC base address ++ */ ++void gemac_disable_copy_all(void *base) ++{ ++ writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_PROM, (base + ++ EMAC_RCNTRL_REG)); ++} ++ ++/* GEMAC allow broadcast function. ++ * @param[in] base GEMAC base address ++ */ ++void gemac_allow_broadcast(void *base) ++{ ++ writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_BC_REJ, base + ++ EMAC_RCNTRL_REG); ++} ++ ++/* GEMAC no broadcast function. ++ * @param[in] base GEMAC base address ++ */ ++void gemac_no_broadcast(void *base) ++{ ++ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_BC_REJ, base + ++ EMAC_RCNTRL_REG); ++} ++ ++/* GEMAC enable 1536 rx function. ++ * @param[in] base GEMAC base address ++ */ ++void gemac_enable_1536_rx(void *base) ++{ ++ /* Set 1536 as Maximum frame length */ ++ writel(readl(base + EMAC_RCNTRL_REG) | (1536 << 16), base + ++ EMAC_RCNTRL_REG); ++} ++ ++/* GEMAC enable jumbo function. ++ * @param[in] base GEMAC base address ++ */ ++void gemac_enable_rx_jmb(void *base) ++{ ++ writel(readl(base + EMAC_RCNTRL_REG) | (JUMBO_FRAME_SIZE << 16), base ++ + EMAC_RCNTRL_REG); ++} ++ ++/* GEMAC enable stacked vlan function. ++ * @param[in] base GEMAC base address ++ */ ++void gemac_enable_stacked_vlan(void *base) ++{ ++ /* MTIP doesn't support stacked vlan */ ++} ++ ++/* GEMAC enable pause rx function. ++ * @param[in] base GEMAC base address ++ */ ++void gemac_enable_pause_rx(void *base) ++{ ++ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_FCE, ++ base + EMAC_RCNTRL_REG); ++} ++ ++/* GEMAC disable pause rx function. ++ * @param[in] base GEMAC base address ++ */ ++void gemac_disable_pause_rx(void *base) ++{ ++ writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_FCE, ++ base + EMAC_RCNTRL_REG); ++} ++ ++/* GEMAC enable pause tx function. ++ * @param[in] base GEMAC base address ++ */ ++void gemac_enable_pause_tx(void *base) ++{ ++ writel(EMAC_RX_SECTION_EMPTY_V, base + EMAC_RX_SECTION_EMPTY); ++} ++ ++/* GEMAC disable pause tx function. ++ * @param[in] base GEMAC base address ++ */ ++void gemac_disable_pause_tx(void *base) ++{ ++ writel(0x0, base + EMAC_RX_SECTION_EMPTY); ++} ++ ++/* GEMAC wol configuration ++ * @param[in] base GEMAC base address ++ * @param[in] wol_conf WoL register configuration ++ */ ++void gemac_set_wol(void *base, u32 wol_conf) ++{ ++ u32 val = readl(base + EMAC_ECNTRL_REG); ++ ++ if (wol_conf) ++ val |= (EMAC_ECNTRL_MAGIC_ENA | EMAC_ECNTRL_SLEEP); ++ else ++ val &= ~(EMAC_ECNTRL_MAGIC_ENA | EMAC_ECNTRL_SLEEP); ++ writel(val, base + EMAC_ECNTRL_REG); ++} ++ ++/* Sets Gemac bus width to 64bit ++ * @param[in] base GEMAC base address ++ * @param[in] width gemac bus width to be set possible values are 32/64/128 ++ */ ++void gemac_set_bus_width(void *base, int width) ++{ ++} ++ ++/* Sets Gemac configuration. ++ * @param[in] base GEMAC base address ++ * @param[in] cfg GEMAC configuration ++ */ ++void gemac_set_config(void *base, struct gemac_cfg *cfg) ++{ ++ /*GEMAC config taken from VLSI */ ++ writel(0x00000004, base + EMAC_TFWR_STR_FWD); ++ writel(0x00000005, base + EMAC_RX_SECTION_FULL); ++ writel(0x00003fff, base + EMAC_TRUNC_FL); ++ writel(0x00000030, base + EMAC_TX_SECTION_EMPTY); ++ writel(0x00000000, base + EMAC_MIB_CTRL_STS_REG); ++ ++ gemac_set_mode(base, cfg->mode); ++ ++ gemac_set_speed(base, cfg->speed); ++ ++ gemac_set_duplex(base, cfg->duplex); ++} ++ ++/**************************** GPI ***************************/ ++ ++/* Initializes a GPI block. ++ * @param[in] base GPI base address ++ * @param[in] cfg GPI configuration ++ */ ++void gpi_init(void *base, struct gpi_cfg *cfg) ++{ ++ gpi_reset(base); ++ ++ gpi_disable(base); ++ ++ gpi_set_config(base, cfg); ++} ++ ++/* Resets a GPI block. ++ * @param[in] base GPI base address ++ */ ++void gpi_reset(void *base) ++{ ++ writel(CORE_SW_RESET, base + GPI_CTRL); ++} ++ ++/* Enables a GPI block. ++ * @param[in] base GPI base address ++ */ ++void gpi_enable(void *base) ++{ ++ writel(CORE_ENABLE, base + GPI_CTRL); ++} ++ ++/* Disables a GPI block. ++ * @param[in] base GPI base address ++ */ ++void gpi_disable(void *base) ++{ ++ writel(CORE_DISABLE, base + GPI_CTRL); ++} ++ ++/* Sets the configuration of a GPI block. ++ * @param[in] base GPI base address ++ * @param[in] cfg GPI configuration ++ */ ++void gpi_set_config(void *base, struct gpi_cfg *cfg) ++{ ++ writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_ALLOC_CTRL), base ++ + GPI_LMEM_ALLOC_ADDR); ++ writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_FREE_CTRL), base ++ + GPI_LMEM_FREE_ADDR); ++ writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_ALLOC_CTRL), base ++ + GPI_DDR_ALLOC_ADDR); ++ writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_FREE_CTRL), base ++ + GPI_DDR_FREE_ADDR); ++ writel(CBUS_VIRT_TO_PFE(CLASS_INQ_PKTPTR), base + GPI_CLASS_ADDR); ++ writel(DDR_HDR_SIZE, base + GPI_DDR_DATA_OFFSET); ++ writel(LMEM_HDR_SIZE, base + GPI_LMEM_DATA_OFFSET); ++ writel(0, base + GPI_LMEM_SEC_BUF_DATA_OFFSET); ++ writel(0, base + GPI_DDR_SEC_BUF_DATA_OFFSET); ++ writel((DDR_HDR_SIZE << 16) | LMEM_HDR_SIZE, base + GPI_HDR_SIZE); ++ writel((DDR_BUF_SIZE << 16) | LMEM_BUF_SIZE, base + GPI_BUF_SIZE); ++ ++ writel(((cfg->lmem_rtry_cnt << 16) | (GPI_DDR_BUF_EN << 1) | ++ GPI_LMEM_BUF_EN), base + GPI_RX_CONFIG); ++ writel(cfg->tmlf_txthres, base + GPI_TMLF_TX); ++ writel(cfg->aseq_len, base + GPI_DTX_ASEQ); ++ writel(1, base + GPI_TOE_CHKSUM_EN); ++ ++ if (cfg->mtip_pause_reg) { ++ writel(cfg->mtip_pause_reg, base + GPI_CSR_MTIP_PAUSE_REG); ++ writel(EGPI_PAUSE_TIME, base + GPI_TX_PAUSE_TIME); ++ } ++} ++ ++/**************************** CLASSIFIER ***************************/ ++ ++/* Initializes CLASSIFIER block. ++ * @param[in] cfg CLASSIFIER configuration ++ */ ++void class_init(struct class_cfg *cfg) ++{ ++ class_reset(); ++ ++ class_disable(); ++ ++ class_set_config(cfg); ++} ++ ++/* Resets CLASSIFIER block. ++ * ++ */ ++void class_reset(void) ++{ ++ writel(CORE_SW_RESET, CLASS_TX_CTRL); ++} ++ ++/* Enables all CLASS-PE's cores. ++ * ++ */ ++void class_enable(void) ++{ ++ writel(CORE_ENABLE, CLASS_TX_CTRL); ++} ++ ++/* Disables all CLASS-PE's cores. ++ * ++ */ ++void class_disable(void) ++{ ++ writel(CORE_DISABLE, CLASS_TX_CTRL); ++} ++ ++/* ++ * Sets the configuration of the CLASSIFIER block. ++ * @param[in] cfg CLASSIFIER configuration ++ */ ++void class_set_config(struct class_cfg *cfg) ++{ ++ u32 val; ++ ++ /* Initialize route table */ ++ if (!cfg->resume) ++ memset(DDR_PHYS_TO_VIRT(cfg->route_table_baseaddr), 0, (1 << ++ cfg->route_table_hash_bits) * CLASS_ROUTE_SIZE); ++ ++#if !defined(LS1012A_PFE_RESET_WA) ++ writel(cfg->pe_sys_clk_ratio, CLASS_PE_SYS_CLK_RATIO); ++#endif ++ ++ writel((DDR_HDR_SIZE << 16) | LMEM_HDR_SIZE, CLASS_HDR_SIZE); ++ writel(LMEM_BUF_SIZE, CLASS_LMEM_BUF_SIZE); ++ writel(CLASS_ROUTE_ENTRY_SIZE(CLASS_ROUTE_SIZE) | ++ CLASS_ROUTE_HASH_SIZE(cfg->route_table_hash_bits), ++ CLASS_ROUTE_HASH_ENTRY_SIZE); ++ writel(HIF_PKT_CLASS_EN | HIF_PKT_OFFSET(sizeof(struct hif_hdr)), ++ CLASS_HIF_PARSE); ++ ++ val = HASH_CRC_PORT_IP | QB2BUS_LE; ++ ++#if defined(CONFIG_IP_ALIGNED) ++ val |= IP_ALIGNED; ++#endif ++ ++ /* ++ * Class PE packet steering will only work if TOE mode, bridge fetch or ++ * route fetch are enabled (see class/qb_fet.v). Route fetch would ++ * trigger additional memory copies (likely from DDR because of hash ++ * table size, which cannot be reduced because PE software still ++ * relies on hash value computed in HW), so when not in TOE mode we ++ * simply enable HW bridge fetch even though we don't use it. ++ */ ++ if (cfg->toe_mode) ++ val |= CLASS_TOE; ++ else ++ val |= HW_BRIDGE_FETCH; ++ ++ writel(val, CLASS_ROUTE_MULTI); ++ ++ writel(DDR_PHYS_TO_PFE(cfg->route_table_baseaddr), ++ CLASS_ROUTE_TABLE_BASE); ++ writel(CLASS_PE0_RO_DM_ADDR0_VAL, CLASS_PE0_RO_DM_ADDR0); ++ writel(CLASS_PE0_RO_DM_ADDR1_VAL, CLASS_PE0_RO_DM_ADDR1); ++ writel(CLASS_PE0_QB_DM_ADDR0_VAL, CLASS_PE0_QB_DM_ADDR0); ++ writel(CLASS_PE0_QB_DM_ADDR1_VAL, CLASS_PE0_QB_DM_ADDR1); ++ writel(CBUS_VIRT_TO_PFE(TMU_PHY_INQ_PKTPTR), CLASS_TM_INQ_ADDR); ++ ++ writel(23, CLASS_AFULL_THRES); ++ writel(23, CLASS_TSQ_FIFO_THRES); ++ ++ writel(24, CLASS_MAX_BUF_CNT); ++ writel(24, CLASS_TSQ_MAX_CNT); ++} ++ ++/**************************** TMU ***************************/ ++ ++void tmu_reset(void) ++{ ++ writel(SW_RESET, TMU_CTRL); ++} ++ ++/* Initializes TMU block. ++ * @param[in] cfg TMU configuration ++ */ ++void tmu_init(struct tmu_cfg *cfg) ++{ ++ int q, phyno; ++ ++ tmu_disable(0xF); ++ mdelay(10); ++ ++#if !defined(LS1012A_PFE_RESET_WA) ++ /* keep in soft reset */ ++ writel(SW_RESET, TMU_CTRL); ++#endif ++ writel(0x3, TMU_SYS_GENERIC_CONTROL); ++ writel(750, TMU_INQ_WATERMARK); ++ writel(CBUS_VIRT_TO_PFE(EGPI1_BASE_ADDR + ++ GPI_INQ_PKTPTR), TMU_PHY0_INQ_ADDR); ++ writel(CBUS_VIRT_TO_PFE(EGPI2_BASE_ADDR + ++ GPI_INQ_PKTPTR), TMU_PHY1_INQ_ADDR); ++ writel(CBUS_VIRT_TO_PFE(HGPI_BASE_ADDR + ++ GPI_INQ_PKTPTR), TMU_PHY3_INQ_ADDR); ++ writel(CBUS_VIRT_TO_PFE(HIF_NOCPY_RX_INQ0_PKTPTR), TMU_PHY4_INQ_ADDR); ++ writel(CBUS_VIRT_TO_PFE(UTIL_INQ_PKTPTR), TMU_PHY5_INQ_ADDR); ++ writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_FREE_CTRL), ++ TMU_BMU_INQ_ADDR); ++ ++ writel(0x3FF, TMU_TDQ0_SCH_CTRL); /* ++ * enabling all 10 ++ * schedulers [9:0] of each TDQ ++ */ ++ writel(0x3FF, TMU_TDQ1_SCH_CTRL); ++ writel(0x3FF, TMU_TDQ3_SCH_CTRL); ++ ++#if !defined(LS1012A_PFE_RESET_WA) ++ writel(cfg->pe_sys_clk_ratio, TMU_PE_SYS_CLK_RATIO); ++#endif ++ ++#if !defined(LS1012A_PFE_RESET_WA) ++ writel(DDR_PHYS_TO_PFE(cfg->llm_base_addr), TMU_LLM_BASE_ADDR); ++ /* Extra packet pointers will be stored from this address onwards */ ++ ++ writel(cfg->llm_queue_len, TMU_LLM_QUE_LEN); ++ writel(5, TMU_TDQ_IIFG_CFG); ++ writel(DDR_BUF_SIZE, TMU_BMU_BUF_SIZE); ++ ++ writel(0x0, TMU_CTRL); ++ ++ /* MEM init */ ++ pr_info("%s: mem init\n", __func__); ++ writel(MEM_INIT, TMU_CTRL); ++ ++ while (!(readl(TMU_CTRL) & MEM_INIT_DONE)) ++ ; ++ ++ /* LLM init */ ++ pr_info("%s: lmem init\n", __func__); ++ writel(LLM_INIT, TMU_CTRL); ++ ++ while (!(readl(TMU_CTRL) & LLM_INIT_DONE)) ++ ; ++#endif ++ /* set up each queue for tail drop */ ++ for (phyno = 0; phyno < 4; phyno++) { ++ if (phyno == 2) ++ continue; ++ for (q = 0; q < 16; q++) { ++ u32 qdepth; ++ ++ writel((phyno << 8) | q, TMU_TEQ_CTRL); ++ writel(1 << 22, TMU_TEQ_QCFG); /*Enable tail drop */ ++ ++ if (phyno == 3) ++ qdepth = DEFAULT_TMU3_QDEPTH; ++ else ++ qdepth = (q == 0) ? DEFAULT_Q0_QDEPTH : ++ DEFAULT_MAX_QDEPTH; ++ ++ /* LOG: 68855 */ ++ /* ++ * The following is a workaround for the reordered ++ * packet and BMU2 buffer leakage issue. ++ */ ++ if (CHIP_REVISION() == 0) ++ qdepth = 31; ++ ++ writel(qdepth << 18, TMU_TEQ_HW_PROB_CFG2); ++ writel(qdepth >> 14, TMU_TEQ_HW_PROB_CFG3); ++ } ++ } ++ ++#ifdef CFG_LRO ++ /* Set TMU-3 queue 5 (LRO) in no-drop mode */ ++ writel((3 << 8) | TMU_QUEUE_LRO, TMU_TEQ_CTRL); ++ writel(0, TMU_TEQ_QCFG); ++#endif ++ ++ writel(0x05, TMU_TEQ_DISABLE_DROPCHK); ++ ++ writel(0x0, TMU_CTRL); ++} ++ ++/* Enables TMU-PE cores. ++ * @param[in] pe_mask TMU PE mask ++ */ ++void tmu_enable(u32 pe_mask) ++{ ++ writel(readl(TMU_TX_CTRL) | (pe_mask & 0xF), TMU_TX_CTRL); ++} ++ ++/* Disables TMU cores. ++ * @param[in] pe_mask TMU PE mask ++ */ ++void tmu_disable(u32 pe_mask) ++{ ++ writel(readl(TMU_TX_CTRL) & ~(pe_mask & 0xF), TMU_TX_CTRL); ++} ++ ++/* This will return the tmu queue status ++ * @param[in] if_id gem interface id or TMU index ++ * @return returns the bit mask of busy queues, zero means all ++ * queues are empty ++ */ ++u32 tmu_qstatus(u32 if_id) ++{ ++ return cpu_to_be32(pe_dmem_read(TMU0_ID + if_id, TMU_DM_PESTATUS + ++ offsetof(struct pe_status, tmu_qstatus), 4)); ++} ++ ++u32 tmu_pkts_processed(u32 if_id) ++{ ++ return cpu_to_be32(pe_dmem_read(TMU0_ID + if_id, TMU_DM_PESTATUS + ++ offsetof(struct pe_status, rx), 4)); ++} ++ ++/**************************** UTIL ***************************/ ++ ++/* Resets UTIL block. ++ */ ++void util_reset(void) ++{ ++ writel(CORE_SW_RESET, UTIL_TX_CTRL); ++} ++ ++/* Initializes UTIL block. ++ * @param[in] cfg UTIL configuration ++ */ ++void util_init(struct util_cfg *cfg) ++{ ++ writel(cfg->pe_sys_clk_ratio, UTIL_PE_SYS_CLK_RATIO); ++} ++ ++/* Enables UTIL-PE core. ++ * ++ */ ++void util_enable(void) ++{ ++ writel(CORE_ENABLE, UTIL_TX_CTRL); ++} ++ ++/* Disables UTIL-PE core. ++ * ++ */ ++void util_disable(void) ++{ ++ writel(CORE_DISABLE, UTIL_TX_CTRL); ++} ++ ++/**************************** HIF ***************************/ ++/* Initializes HIF copy block. ++ * ++ */ ++void hif_init(void) ++{ ++ /*Initialize HIF registers*/ ++ writel((HIF_RX_POLL_CTRL_CYCLE << 16) | HIF_TX_POLL_CTRL_CYCLE, ++ HIF_POLL_CTRL); ++} ++ ++/* Enable hif tx DMA and interrupt ++ * ++ */ ++void hif_tx_enable(void) ++{ ++ writel(HIF_CTRL_DMA_EN, HIF_TX_CTRL); ++ writel((readl(HIF_INT_ENABLE) | HIF_INT_EN | HIF_TXPKT_INT_EN), ++ HIF_INT_ENABLE); ++} ++ ++/* Disable hif tx DMA and interrupt ++ * ++ */ ++void hif_tx_disable(void) ++{ ++ u32 hif_int; ++ ++ writel(0, HIF_TX_CTRL); ++ ++ hif_int = readl(HIF_INT_ENABLE); ++ hif_int &= HIF_TXPKT_INT_EN; ++ writel(hif_int, HIF_INT_ENABLE); ++} ++ ++/* Enable hif rx DMA and interrupt ++ * ++ */ ++void hif_rx_enable(void) ++{ ++ hif_rx_dma_start(); ++ writel((readl(HIF_INT_ENABLE) | HIF_INT_EN | HIF_RXPKT_INT_EN), ++ HIF_INT_ENABLE); ++} ++ ++/* Disable hif rx DMA and interrupt ++ * ++ */ ++void hif_rx_disable(void) ++{ ++ u32 hif_int; ++ ++ writel(0, HIF_RX_CTRL); ++ ++ hif_int = readl(HIF_INT_ENABLE); ++ hif_int &= HIF_RXPKT_INT_EN; ++ writel(hif_int, HIF_INT_ENABLE); ++} +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_hif.c +@@ -0,0 +1,1072 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "pfe_mod.h" ++ ++#define HIF_INT_MASK (HIF_INT | HIF_RXPKT_INT | HIF_TXPKT_INT) ++ ++unsigned char napi_first_batch; ++ ++static void pfe_tx_do_cleanup(unsigned long data); ++ ++static int pfe_hif_alloc_descr(struct pfe_hif *hif) ++{ ++ void *addr; ++ dma_addr_t dma_addr; ++ int err = 0; ++ ++ pr_info("%s\n", __func__); ++ addr = dma_alloc_coherent(pfe->dev, ++ HIF_RX_DESC_NT * sizeof(struct hif_desc) + ++ HIF_TX_DESC_NT * sizeof(struct hif_desc), ++ &dma_addr, GFP_KERNEL); ++ ++ if (!addr) { ++ pr_err("%s: Could not allocate buffer descriptors!\n" ++ , __func__); ++ err = -ENOMEM; ++ goto err0; ++ } ++ ++ hif->descr_baseaddr_p = dma_addr; ++ hif->descr_baseaddr_v = addr; ++ hif->rx_ring_size = HIF_RX_DESC_NT; ++ hif->tx_ring_size = HIF_TX_DESC_NT; ++ ++ return 0; ++ ++err0: ++ return err; ++} ++ ++#if defined(LS1012A_PFE_RESET_WA) ++static void pfe_hif_disable_rx_desc(struct pfe_hif *hif) ++{ ++ int ii; ++ struct hif_desc *desc = hif->rx_base; ++ ++ /*Mark all descriptors as LAST_BD */ ++ for (ii = 0; ii < hif->rx_ring_size; ii++) { ++ desc->ctrl |= BD_CTRL_LAST_BD; ++ desc++; ++ } ++} ++ ++struct class_rx_hdr_t { ++ u32 next_ptr; /* ptr to the start of the first DDR buffer */ ++ u16 length; /* total packet length */ ++ u16 phyno; /* input physical port number */ ++ u32 status; /* gemac status bits */ ++ u32 status2; /* reserved for software usage */ ++}; ++ ++/* STATUS_BAD_FRAME_ERR is set for all errors (including checksums if enabled) ++ * except overflow ++ */ ++#define STATUS_BAD_FRAME_ERR BIT(16) ++#define STATUS_LENGTH_ERR BIT(17) ++#define STATUS_CRC_ERR BIT(18) ++#define STATUS_TOO_SHORT_ERR BIT(19) ++#define STATUS_TOO_LONG_ERR BIT(20) ++#define STATUS_CODE_ERR BIT(21) ++#define STATUS_MC_HASH_MATCH BIT(22) ++#define STATUS_CUMULATIVE_ARC_HIT BIT(23) ++#define STATUS_UNICAST_HASH_MATCH BIT(24) ++#define STATUS_IP_CHECKSUM_CORRECT BIT(25) ++#define STATUS_TCP_CHECKSUM_CORRECT BIT(26) ++#define STATUS_UDP_CHECKSUM_CORRECT BIT(27) ++#define STATUS_OVERFLOW_ERR BIT(28) /* GPI error */ ++#define MIN_PKT_SIZE 64 ++ ++static inline void copy_to_lmem(u32 *dst, u32 *src, int len) ++{ ++ int i; ++ ++ for (i = 0; i < len; i += sizeof(u32)) { ++ *dst = htonl(*src); ++ dst++; src++; ++ } ++} ++ ++static void send_dummy_pkt_to_hif(void) ++{ ++ void *lmem_ptr, *ddr_ptr, *lmem_virt_addr; ++ u32 physaddr; ++ struct class_rx_hdr_t local_hdr; ++ static u32 dummy_pkt[] = { ++ 0x33221100, 0x2b785544, 0xd73093cb, 0x01000608, ++ 0x04060008, 0x2b780200, 0xd73093cb, 0x0a01a8c0, ++ 0x33221100, 0xa8c05544, 0x00000301, 0x00000000, ++ 0x00000000, 0x00000000, 0x00000000, 0xbe86c51f }; ++ ++ ddr_ptr = (void *)((u64)readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL)); ++ if (!ddr_ptr) ++ return; ++ ++ lmem_ptr = (void *)((u64)readl(BMU1_BASE_ADDR + BMU_ALLOC_CTRL)); ++ if (!lmem_ptr) ++ return; ++ ++ pr_info("Sending a dummy pkt to HIF %p %p\n", ddr_ptr, lmem_ptr); ++ physaddr = (u32)DDR_VIRT_TO_PFE(ddr_ptr); ++ ++ lmem_virt_addr = (void *)CBUS_PFE_TO_VIRT((unsigned long int)lmem_ptr); ++ ++ local_hdr.phyno = htons(0); /* RX_PHY_0 */ ++ local_hdr.length = htons(MIN_PKT_SIZE); ++ ++ local_hdr.next_ptr = htonl((u32)physaddr); ++ /*Mark checksum is correct */ ++ local_hdr.status = htonl((STATUS_IP_CHECKSUM_CORRECT | ++ STATUS_UDP_CHECKSUM_CORRECT | ++ STATUS_TCP_CHECKSUM_CORRECT | ++ STATUS_UNICAST_HASH_MATCH | ++ STATUS_CUMULATIVE_ARC_HIT)); ++ copy_to_lmem((u32 *)lmem_virt_addr, (u32 *)&local_hdr, ++ sizeof(local_hdr)); ++ ++ copy_to_lmem((u32 *)(lmem_virt_addr + LMEM_HDR_SIZE), (u32 *)dummy_pkt, ++ 0x40); ++ ++ writel((unsigned long int)lmem_ptr, CLASS_INQ_PKTPTR); ++} ++ ++void pfe_hif_rx_idle(struct pfe_hif *hif) ++{ ++ int hif_stop_loop = 10; ++ u32 rx_status; ++ ++ pfe_hif_disable_rx_desc(hif); ++ pr_info("Bringing hif to idle state..."); ++ writel(0, HIF_INT_ENABLE); ++ /*If HIF Rx BDP is busy send a dummy packet */ ++ do { ++ rx_status = readl(HIF_RX_STATUS); ++ if (rx_status & BDP_CSR_RX_DMA_ACTV) ++ send_dummy_pkt_to_hif(); ++ ++ usleep_range(100, 150); ++ } while (--hif_stop_loop); ++ ++ if (readl(HIF_RX_STATUS) & BDP_CSR_RX_DMA_ACTV) ++ pr_info("Failed\n"); ++ else ++ pr_info("Done\n"); ++} ++#endif ++ ++static void pfe_hif_free_descr(struct pfe_hif *hif) ++{ ++ pr_info("%s\n", __func__); ++ ++ dma_free_coherent(pfe->dev, ++ hif->rx_ring_size * sizeof(struct hif_desc) + ++ hif->tx_ring_size * sizeof(struct hif_desc), ++ hif->descr_baseaddr_v, hif->descr_baseaddr_p); ++} ++ ++void pfe_hif_desc_dump(struct pfe_hif *hif) ++{ ++ struct hif_desc *desc; ++ unsigned long desc_p; ++ int ii = 0; ++ ++ pr_info("%s\n", __func__); ++ ++ desc = hif->rx_base; ++ desc_p = (u32)((u64)desc - (u64)hif->descr_baseaddr_v + ++ hif->descr_baseaddr_p); ++ ++ pr_info("HIF Rx desc base %p physical %x\n", desc, (u32)desc_p); ++ for (ii = 0; ii < hif->rx_ring_size; ii++) { ++ pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n", ++ readl(&desc->status), readl(&desc->ctrl), ++ readl(&desc->data), readl(&desc->next)); ++ desc++; ++ } ++ ++ desc = hif->tx_base; ++ desc_p = ((u64)desc - (u64)hif->descr_baseaddr_v + ++ hif->descr_baseaddr_p); ++ ++ pr_info("HIF Tx desc base %p physical %x\n", desc, (u32)desc_p); ++ for (ii = 0; ii < hif->tx_ring_size; ii++) { ++ pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n", ++ readl(&desc->status), readl(&desc->ctrl), ++ readl(&desc->data), readl(&desc->next)); ++ desc++; ++ } ++} ++ ++/* pfe_hif_release_buffers */ ++static void pfe_hif_release_buffers(struct pfe_hif *hif) ++{ ++ struct hif_desc *desc; ++ int i = 0; ++ ++ hif->rx_base = hif->descr_baseaddr_v; ++ ++ pr_info("%s\n", __func__); ++ ++ /*Free Rx buffers */ ++ desc = hif->rx_base; ++ for (i = 0; i < hif->rx_ring_size; i++) { ++ if (readl(&desc->data)) { ++ if ((i < hif->shm->rx_buf_pool_cnt) && ++ (!hif->shm->rx_buf_pool[i])) { ++ /* ++ * dma_unmap_single(hif->dev, desc->data, ++ * hif->rx_buf_len[i], DMA_FROM_DEVICE); ++ */ ++ dma_unmap_single(hif->dev, ++ DDR_PFE_TO_PHYS( ++ readl(&desc->data)), ++ hif->rx_buf_len[i], ++ DMA_FROM_DEVICE); ++ hif->shm->rx_buf_pool[i] = hif->rx_buf_addr[i]; ++ } else { ++ pr_err("%s: buffer pool already full\n" ++ , __func__); ++ } ++ } ++ ++ writel(0, &desc->data); ++ writel(0, &desc->status); ++ writel(0, &desc->ctrl); ++ desc++; ++ } ++} ++ ++/* ++ * pfe_hif_init_buffers ++ * This function initializes the HIF Rx/Tx ring descriptors and ++ * initialize Rx queue with buffers. ++ */ ++static int pfe_hif_init_buffers(struct pfe_hif *hif) ++{ ++ struct hif_desc *desc, *first_desc_p; ++ u32 data; ++ int i = 0; ++ ++ pr_info("%s\n", __func__); ++ ++ /* Check enough Rx buffers available in the shared memory */ ++ if (hif->shm->rx_buf_pool_cnt < hif->rx_ring_size) ++ return -ENOMEM; ++ ++ hif->rx_base = hif->descr_baseaddr_v; ++ memset(hif->rx_base, 0, hif->rx_ring_size * sizeof(struct hif_desc)); ++ ++ /*Initialize Rx descriptors */ ++ desc = hif->rx_base; ++ first_desc_p = (struct hif_desc *)hif->descr_baseaddr_p; ++ ++ for (i = 0; i < hif->rx_ring_size; i++) { ++ /* Initialize Rx buffers from the shared memory */ ++ ++ data = (u32)dma_map_single(hif->dev, hif->shm->rx_buf_pool[i], ++ pfe_pkt_size, DMA_FROM_DEVICE); ++ hif->rx_buf_addr[i] = hif->shm->rx_buf_pool[i]; ++ hif->rx_buf_len[i] = pfe_pkt_size; ++ hif->shm->rx_buf_pool[i] = NULL; ++ ++ if (likely(dma_mapping_error(hif->dev, data) == 0)) { ++ writel(DDR_PHYS_TO_PFE(data), &desc->data); ++ } else { ++ pr_err("%s : low on mem\n", __func__); ++ ++ goto err; ++ } ++ ++ writel(0, &desc->status); ++ ++ /* ++ * Ensure everything else is written to DDR before ++ * writing bd->ctrl ++ */ ++ wmb(); ++ ++ writel((BD_CTRL_PKT_INT_EN | BD_CTRL_LIFM ++ | BD_CTRL_DIR | BD_CTRL_DESC_EN ++ | BD_BUF_LEN(pfe_pkt_size)), &desc->ctrl); ++ ++ /* Chain descriptors */ ++ writel((u32)DDR_PHYS_TO_PFE(first_desc_p + i + 1), &desc->next); ++ desc++; ++ } ++ ++ /* Overwrite last descriptor to chain it to first one*/ ++ desc--; ++ writel((u32)DDR_PHYS_TO_PFE(first_desc_p), &desc->next); ++ ++ hif->rxtoclean_index = 0; ++ ++ /*Initialize Rx buffer descriptor ring base address */ ++ writel(DDR_PHYS_TO_PFE(hif->descr_baseaddr_p), HIF_RX_BDP_ADDR); ++ ++ hif->tx_base = hif->rx_base + hif->rx_ring_size; ++ first_desc_p = (struct hif_desc *)hif->descr_baseaddr_p + ++ hif->rx_ring_size; ++ memset(hif->tx_base, 0, hif->tx_ring_size * sizeof(struct hif_desc)); ++ ++ /*Initialize tx descriptors */ ++ desc = hif->tx_base; ++ ++ for (i = 0; i < hif->tx_ring_size; i++) { ++ /* Chain descriptors */ ++ writel((u32)DDR_PHYS_TO_PFE(first_desc_p + i + 1), &desc->next); ++ writel(0, &desc->ctrl); ++ desc++; ++ } ++ ++ /* Overwrite last descriptor to chain it to first one */ ++ desc--; ++ writel((u32)DDR_PHYS_TO_PFE(first_desc_p), &desc->next); ++ hif->txavail = hif->tx_ring_size; ++ hif->txtosend = 0; ++ hif->txtoclean = 0; ++ hif->txtoflush = 0; ++ ++ /*Initialize Tx buffer descriptor ring base address */ ++ writel((u32)DDR_PHYS_TO_PFE(first_desc_p), HIF_TX_BDP_ADDR); ++ ++ return 0; ++ ++err: ++ pfe_hif_release_buffers(hif); ++ return -ENOMEM; ++} ++ ++/* ++ * pfe_hif_client_register ++ * ++ * This function used to register a client driver with the HIF driver. ++ * ++ * Return value: ++ * 0 - on Successful registration ++ */ ++static int pfe_hif_client_register(struct pfe_hif *hif, u32 client_id, ++ struct hif_client_shm *client_shm) ++{ ++ struct hif_client *client = &hif->client[client_id]; ++ u32 i, cnt; ++ struct rx_queue_desc *rx_qbase; ++ struct tx_queue_desc *tx_qbase; ++ struct hif_rx_queue *rx_queue; ++ struct hif_tx_queue *tx_queue; ++ int err = 0; ++ ++ pr_info("%s\n", __func__); ++ ++ spin_lock_bh(&hif->tx_lock); ++ ++ if (test_bit(client_id, &hif->shm->g_client_status[0])) { ++ pr_err("%s: client %d already registered\n", ++ __func__, client_id); ++ err = -1; ++ goto unlock; ++ } ++ ++ memset(client, 0, sizeof(struct hif_client)); ++ ++ /* Initialize client Rx queues baseaddr, size */ ++ ++ cnt = CLIENT_CTRL_RX_Q_CNT(client_shm->ctrl); ++ /* Check if client is requesting for more queues than supported */ ++ if (cnt > HIF_CLIENT_QUEUES_MAX) ++ cnt = HIF_CLIENT_QUEUES_MAX; ++ ++ client->rx_qn = cnt; ++ rx_qbase = (struct rx_queue_desc *)client_shm->rx_qbase; ++ for (i = 0; i < cnt; i++) { ++ rx_queue = &client->rx_q[i]; ++ rx_queue->base = rx_qbase + i * client_shm->rx_qsize; ++ rx_queue->size = client_shm->rx_qsize; ++ rx_queue->write_idx = 0; ++ } ++ ++ /* Initialize client Tx queues baseaddr, size */ ++ cnt = CLIENT_CTRL_TX_Q_CNT(client_shm->ctrl); ++ ++ /* Check if client is requesting for more queues than supported */ ++ if (cnt > HIF_CLIENT_QUEUES_MAX) ++ cnt = HIF_CLIENT_QUEUES_MAX; ++ ++ client->tx_qn = cnt; ++ tx_qbase = (struct tx_queue_desc *)client_shm->tx_qbase; ++ for (i = 0; i < cnt; i++) { ++ tx_queue = &client->tx_q[i]; ++ tx_queue->base = tx_qbase + i * client_shm->tx_qsize; ++ tx_queue->size = client_shm->tx_qsize; ++ tx_queue->ack_idx = 0; ++ } ++ ++ set_bit(client_id, &hif->shm->g_client_status[0]); ++ ++unlock: ++ spin_unlock_bh(&hif->tx_lock); ++ ++ return err; ++} ++ ++/* ++ * pfe_hif_client_unregister ++ * ++ * This function used to unregister a client from the HIF driver. ++ * ++ */ ++static void pfe_hif_client_unregister(struct pfe_hif *hif, u32 client_id) ++{ ++ pr_info("%s\n", __func__); ++ ++ /* ++ * Mark client as no longer available (which prevents further packet ++ * receive for this client) ++ */ ++ spin_lock_bh(&hif->tx_lock); ++ ++ if (!test_bit(client_id, &hif->shm->g_client_status[0])) { ++ pr_err("%s: client %d not registered\n", __func__, ++ client_id); ++ ++ spin_unlock_bh(&hif->tx_lock); ++ return; ++ } ++ ++ clear_bit(client_id, &hif->shm->g_client_status[0]); ++ ++ spin_unlock_bh(&hif->tx_lock); ++} ++ ++/* ++ * client_put_rxpacket- ++ * This functions puts the Rx pkt in the given client Rx queue. ++ * It actually swap the Rx pkt in the client Rx descriptor buffer ++ * and returns the free buffer from it. ++ * ++ * If the function returns NULL means client Rx queue is full and ++ * packet couldn't send to client queue. ++ */ ++static void *client_put_rxpacket(struct hif_rx_queue *queue, void *pkt, u32 len, ++ u32 flags, u32 client_ctrl, u32 *rem_len) ++{ ++ void *free_pkt = NULL; ++ struct rx_queue_desc *desc = queue->base + queue->write_idx; ++ ++ if (readl(&desc->ctrl) & CL_DESC_OWN) { ++ if (page_mode) { ++ int rem_page_size = PAGE_SIZE - ++ PRESENT_OFST_IN_PAGE(pkt); ++ int cur_pkt_size = ROUND_MIN_RX_SIZE(len + ++ pfe_pkt_headroom); ++ *rem_len = (rem_page_size - cur_pkt_size); ++ if (*rem_len) { ++ free_pkt = pkt + cur_pkt_size; ++ get_page(virt_to_page(free_pkt)); ++ } else { ++ free_pkt = (void ++ *)__get_free_page(GFP_ATOMIC | GFP_DMA_PFE); ++ *rem_len = pfe_pkt_size; ++ } ++ } else { ++ free_pkt = kmalloc(PFE_BUF_SIZE, GFP_ATOMIC | ++ GFP_DMA_PFE); ++ *rem_len = PFE_BUF_SIZE - pfe_pkt_headroom; ++ } ++ ++ if (free_pkt) { ++ desc->data = pkt; ++ desc->client_ctrl = client_ctrl; ++ /* ++ * Ensure everything else is written to DDR before ++ * writing bd->ctrl ++ */ ++ smp_wmb(); ++ writel(CL_DESC_BUF_LEN(len) | flags, &desc->ctrl); ++ queue->write_idx = (queue->write_idx + 1) ++ & (queue->size - 1); ++ ++ free_pkt += pfe_pkt_headroom; ++ } ++ } ++ ++ return free_pkt; ++} ++ ++/* ++ * pfe_hif_rx_process- ++ * This function does pfe hif rx queue processing. ++ * Dequeue packet from Rx queue and send it to corresponding client queue ++ */ ++static int pfe_hif_rx_process(struct pfe_hif *hif, int budget) ++{ ++ struct hif_desc *desc; ++ struct hif_hdr *pkt_hdr; ++ struct __hif_hdr hif_hdr; ++ void *free_buf; ++ int rtc, len, rx_processed = 0; ++ struct __hif_desc local_desc; ++ int flags; ++ unsigned int desc_p; ++ unsigned int buf_size = 0; ++ ++ spin_lock_bh(&hif->lock); ++ ++ rtc = hif->rxtoclean_index; ++ ++ while (rx_processed < budget) { ++ desc = hif->rx_base + rtc; ++ ++ __memcpy12(&local_desc, desc); ++ ++ /* ACK pending Rx interrupt */ ++ if (local_desc.ctrl & BD_CTRL_DESC_EN) { ++ writel(HIF_INT | HIF_RXPKT_INT, HIF_INT_SRC); ++ ++ if (rx_processed == 0) { ++ if (napi_first_batch == 1) { ++ desc_p = hif->descr_baseaddr_p + ++ ((unsigned long int)(desc) - ++ (unsigned long ++ int)hif->descr_baseaddr_v); ++ napi_first_batch = 0; ++ } ++ } ++ ++ __memcpy12(&local_desc, desc); ++ ++ if (local_desc.ctrl & BD_CTRL_DESC_EN) ++ break; ++ } ++ ++ napi_first_batch = 0; ++ ++#ifdef HIF_NAPI_STATS ++ hif->napi_counters[NAPI_DESC_COUNT]++; ++#endif ++ len = BD_BUF_LEN(local_desc.ctrl); ++ /* ++ * dma_unmap_single(hif->dev, DDR_PFE_TO_PHYS(local_desc.data), ++ * hif->rx_buf_len[rtc], DMA_FROM_DEVICE); ++ */ ++ dma_unmap_single(hif->dev, DDR_PFE_TO_PHYS(local_desc.data), ++ hif->rx_buf_len[rtc], DMA_FROM_DEVICE); ++ ++ pkt_hdr = (struct hif_hdr *)hif->rx_buf_addr[rtc]; ++ ++ /* Track last HIF header received */ ++ if (!hif->started) { ++ hif->started = 1; ++ ++ __memcpy8(&hif_hdr, pkt_hdr); ++ ++ hif->qno = hif_hdr.hdr.q_num; ++ hif->client_id = hif_hdr.hdr.client_id; ++ hif->client_ctrl = (hif_hdr.hdr.client_ctrl1 << 16) | ++ hif_hdr.hdr.client_ctrl; ++ flags = CL_DESC_FIRST; ++ ++ } else { ++ flags = 0; ++ } ++ ++ if (local_desc.ctrl & BD_CTRL_LIFM) ++ flags |= CL_DESC_LAST; ++ ++ /* Check for valid client id and still registered */ ++ if ((hif->client_id >= HIF_CLIENTS_MAX) || ++ !(test_bit(hif->client_id, ++ &hif->shm->g_client_status[0]))) { ++ printk_ratelimited("%s: packet with invalid client id %d q_num %d\n", ++ __func__, ++ hif->client_id, ++ hif->qno); ++ ++ free_buf = pkt_hdr; ++ ++ goto pkt_drop; ++ } ++ ++ /* Check to valid queue number */ ++ if (hif->client[hif->client_id].rx_qn <= hif->qno) { ++ pr_info("%s: packet with invalid queue: %d\n" ++ , __func__, hif->qno); ++ hif->qno = 0; ++ } ++ ++ free_buf = ++ client_put_rxpacket(&hif->client[hif->client_id].rx_q[hif->qno], ++ (void *)pkt_hdr, len, flags, ++ hif->client_ctrl, &buf_size); ++ ++ hif_lib_indicate_client(hif->client_id, EVENT_RX_PKT_IND, ++ hif->qno); ++ ++ if (unlikely(!free_buf)) { ++#ifdef HIF_NAPI_STATS ++ hif->napi_counters[NAPI_CLIENT_FULL_COUNT]++; ++#endif ++ /* ++ * If we want to keep in polling mode to retry later, ++ * we need to tell napi that we consumed ++ * the full budget or we will hit a livelock scenario. ++ * The core code keeps this napi instance ++ * at the head of the list and none of the other ++ * instances get to run ++ */ ++ rx_processed = budget; ++ ++ if (flags & CL_DESC_FIRST) ++ hif->started = 0; ++ ++ break; ++ } ++ ++pkt_drop: ++ /*Fill free buffer in the descriptor */ ++ hif->rx_buf_addr[rtc] = free_buf; ++ hif->rx_buf_len[rtc] = min(pfe_pkt_size, buf_size); ++ writel((DDR_PHYS_TO_PFE ++ ((u32)dma_map_single(hif->dev, ++ free_buf, hif->rx_buf_len[rtc], DMA_FROM_DEVICE))), ++ &desc->data); ++ /* ++ * Ensure everything else is written to DDR before ++ * writing bd->ctrl ++ */ ++ wmb(); ++ writel((BD_CTRL_PKT_INT_EN | BD_CTRL_LIFM | BD_CTRL_DIR | ++ BD_CTRL_DESC_EN | BD_BUF_LEN(hif->rx_buf_len[rtc])), ++ &desc->ctrl); ++ ++ rtc = (rtc + 1) & (hif->rx_ring_size - 1); ++ ++ if (local_desc.ctrl & BD_CTRL_LIFM) { ++ if (!(hif->client_ctrl & HIF_CTRL_RX_CONTINUED)) { ++ rx_processed++; ++ ++#ifdef HIF_NAPI_STATS ++ hif->napi_counters[NAPI_PACKET_COUNT]++; ++#endif ++ } ++ hif->started = 0; ++ } ++ } ++ ++ hif->rxtoclean_index = rtc; ++ spin_unlock_bh(&hif->lock); ++ ++ /* we made some progress, re-start rx dma in case it stopped */ ++ hif_rx_dma_start(); ++ ++ return rx_processed; ++} ++ ++/* ++ * client_ack_txpacket- ++ * This function ack the Tx packet in the give client Tx queue by resetting ++ * ownership bit in the descriptor. ++ */ ++static int client_ack_txpacket(struct pfe_hif *hif, unsigned int client_id, ++ unsigned int q_no) ++{ ++ struct hif_tx_queue *queue = &hif->client[client_id].tx_q[q_no]; ++ struct tx_queue_desc *desc = queue->base + queue->ack_idx; ++ ++ if (readl(&desc->ctrl) & CL_DESC_OWN) { ++ writel((readl(&desc->ctrl) & ~CL_DESC_OWN), &desc->ctrl); ++ queue->ack_idx = (queue->ack_idx + 1) & (queue->size - 1); ++ ++ return 0; ++ ++ } else { ++ /*This should not happen */ ++ pr_err("%s: %d %d %d %d %d %p %d\n", __func__, ++ hif->txtosend, hif->txtoclean, hif->txavail, ++ client_id, q_no, queue, queue->ack_idx); ++ WARN(1, "%s: doesn't own this descriptor", __func__); ++ return 1; ++ } ++} ++ ++void __hif_tx_done_process(struct pfe_hif *hif, int count) ++{ ++ struct hif_desc *desc; ++ struct hif_desc_sw *desc_sw; ++ int ttc, tx_avl; ++ int pkts_done[HIF_CLIENTS_MAX] = {0, 0}; ++ ++ ttc = hif->txtoclean; ++ tx_avl = hif->txavail; ++ ++ while ((tx_avl < hif->tx_ring_size) && count--) { ++ desc = hif->tx_base + ttc; ++ ++ if (readl(&desc->ctrl) & BD_CTRL_DESC_EN) ++ break; ++ ++ desc_sw = &hif->tx_sw_queue[ttc]; ++ ++ if (desc_sw->data) { ++ /* ++ * dmap_unmap_single(hif->dev, desc_sw->data, ++ * desc_sw->len, DMA_TO_DEVICE); ++ */ ++ dma_unmap_single(hif->dev, desc_sw->data, ++ desc_sw->len, DMA_TO_DEVICE); ++ } ++ ++ if (desc_sw->client_id > HIF_CLIENTS_MAX) ++ pr_err("Invalid cl id %d\n", desc_sw->client_id); ++ ++ pkts_done[desc_sw->client_id]++; ++ ++ client_ack_txpacket(hif, desc_sw->client_id, desc_sw->q_no); ++ ++ ttc = (ttc + 1) & (hif->tx_ring_size - 1); ++ tx_avl++; ++ } ++ ++ if (pkts_done[0]) ++ hif_lib_indicate_client(0, EVENT_TXDONE_IND, 0); ++ if (pkts_done[1]) ++ hif_lib_indicate_client(1, EVENT_TXDONE_IND, 0); ++ ++ hif->txtoclean = ttc; ++ hif->txavail = tx_avl; ++ ++ if (!count) { ++ tasklet_schedule(&hif->tx_cleanup_tasklet); ++ } else { ++ /*Enable Tx done interrupt */ ++ writel(readl_relaxed(HIF_INT_ENABLE) | HIF_TXPKT_INT, ++ HIF_INT_ENABLE); ++ } ++} ++ ++static void pfe_tx_do_cleanup(unsigned long data) ++{ ++ struct pfe_hif *hif = (struct pfe_hif *)data; ++ ++ writel(HIF_INT | HIF_TXPKT_INT, HIF_INT_SRC); ++ ++ hif_tx_done_process(hif, 64); ++} ++ ++/* ++ * __hif_xmit_pkt - ++ * This function puts one packet in the HIF Tx queue ++ */ ++void __hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int ++ q_no, void *data, u32 len, unsigned int flags) ++{ ++ struct hif_desc *desc; ++ struct hif_desc_sw *desc_sw; ++ ++ desc = hif->tx_base + hif->txtosend; ++ desc_sw = &hif->tx_sw_queue[hif->txtosend]; ++ ++ desc_sw->len = len; ++ desc_sw->client_id = client_id; ++ desc_sw->q_no = q_no; ++ desc_sw->flags = flags; ++ ++ if (flags & HIF_DONT_DMA_MAP) { ++ desc_sw->data = 0; ++ writel((u32)DDR_PHYS_TO_PFE(data), &desc->data); ++ } else { ++ desc_sw->data = dma_map_single(hif->dev, data, len, ++ DMA_TO_DEVICE); ++ writel((u32)DDR_PHYS_TO_PFE(desc_sw->data), &desc->data); ++ } ++ ++ hif->txtosend = (hif->txtosend + 1) & (hif->tx_ring_size - 1); ++ hif->txavail--; ++ ++ if ((!((flags & HIF_DATA_VALID) && (flags & ++ HIF_LAST_BUFFER)))) ++ goto skip_tx; ++ ++ /* ++ * Ensure everything else is written to DDR before ++ * writing bd->ctrl ++ */ ++ wmb(); ++ ++ do { ++ desc_sw = &hif->tx_sw_queue[hif->txtoflush]; ++ desc = hif->tx_base + hif->txtoflush; ++ ++ if (desc_sw->flags & HIF_LAST_BUFFER) { ++ writel((BD_CTRL_LIFM | ++ BD_CTRL_BRFETCH_DISABLE | BD_CTRL_RTFETCH_DISABLE ++ | BD_CTRL_PARSE_DISABLE | BD_CTRL_DESC_EN | ++ BD_CTRL_PKT_INT_EN | BD_BUF_LEN(desc_sw->len)), ++ &desc->ctrl); ++ } else { ++ writel((BD_CTRL_DESC_EN | ++ BD_BUF_LEN(desc_sw->len)), &desc->ctrl); ++ } ++ hif->txtoflush = (hif->txtoflush + 1) & (hif->tx_ring_size - 1); ++ } ++ while (hif->txtoflush != hif->txtosend) ++ ; ++ ++skip_tx: ++ return; ++} ++ ++static irqreturn_t wol_isr(int irq, void *dev_id) ++{ ++ pr_info("WoL\n"); ++ gemac_set_wol(EMAC1_BASE_ADDR, 0); ++ gemac_set_wol(EMAC2_BASE_ADDR, 0); ++ return IRQ_HANDLED; ++} ++ ++/* ++ * hif_isr- ++ * This ISR routine processes Rx/Tx done interrupts from the HIF hardware block ++ */ ++static irqreturn_t hif_isr(int irq, void *dev_id) ++{ ++ struct pfe_hif *hif = (struct pfe_hif *)dev_id; ++ int int_status; ++ int int_enable_mask; ++ ++ /*Read hif interrupt source register */ ++ int_status = readl_relaxed(HIF_INT_SRC); ++ int_enable_mask = readl_relaxed(HIF_INT_ENABLE); ++ ++ if ((int_status & HIF_INT) == 0) ++ return IRQ_NONE; ++ ++ int_status &= ~(HIF_INT); ++ ++ if (int_status & HIF_RXPKT_INT) { ++ int_status &= ~(HIF_RXPKT_INT); ++ int_enable_mask &= ~(HIF_RXPKT_INT); ++ ++ napi_first_batch = 1; ++ ++ if (napi_schedule_prep(&hif->napi)) { ++#ifdef HIF_NAPI_STATS ++ hif->napi_counters[NAPI_SCHED_COUNT]++; ++#endif ++ __napi_schedule(&hif->napi); ++ } ++ } ++ ++ if (int_status & HIF_TXPKT_INT) { ++ int_status &= ~(HIF_TXPKT_INT); ++ int_enable_mask &= ~(HIF_TXPKT_INT); ++ /*Schedule tx cleanup tassklet */ ++ tasklet_schedule(&hif->tx_cleanup_tasklet); ++ } ++ ++ /*Disable interrupts, they will be enabled after they are serviced */ ++ writel_relaxed(int_enable_mask, HIF_INT_ENABLE); ++ ++ if (int_status) { ++ pr_info("%s : Invalid interrupt : %d\n", __func__, ++ int_status); ++ writel(int_status, HIF_INT_SRC); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int data2) ++{ ++ unsigned int client_id = data1; ++ ++ if (client_id >= HIF_CLIENTS_MAX) { ++ pr_err("%s: client id %d out of bounds\n", __func__, ++ client_id); ++ return; ++ } ++ ++ switch (req) { ++ case REQUEST_CL_REGISTER: ++ /* Request for register a client */ ++ pr_info("%s: register client_id %d\n", ++ __func__, client_id); ++ pfe_hif_client_register(hif, client_id, (struct ++ hif_client_shm *)&hif->shm->client[client_id]); ++ break; ++ ++ case REQUEST_CL_UNREGISTER: ++ pr_info("%s: unregister client_id %d\n", ++ __func__, client_id); ++ ++ /* Request for unregister a client */ ++ pfe_hif_client_unregister(hif, client_id); ++ ++ break; ++ ++ default: ++ pr_err("%s: unsupported request %d\n", ++ __func__, req); ++ break; ++ } ++ ++ /* ++ * Process client Tx queues ++ * Currently we don't have checking for tx pending ++ */ ++} ++ ++/* ++ * pfe_hif_rx_poll ++ * This function is NAPI poll function to process HIF Rx queue. ++ */ ++static int pfe_hif_rx_poll(struct napi_struct *napi, int budget) ++{ ++ struct pfe_hif *hif = container_of(napi, struct pfe_hif, napi); ++ int work_done; ++ ++#ifdef HIF_NAPI_STATS ++ hif->napi_counters[NAPI_POLL_COUNT]++; ++#endif ++ ++ work_done = pfe_hif_rx_process(hif, budget); ++ ++ if (work_done < budget) { ++ napi_complete(napi); ++ writel(readl_relaxed(HIF_INT_ENABLE) | HIF_RXPKT_INT, ++ HIF_INT_ENABLE); ++ } ++#ifdef HIF_NAPI_STATS ++ else ++ hif->napi_counters[NAPI_FULL_BUDGET_COUNT]++; ++#endif ++ ++ return work_done; ++} ++ ++/* ++ * pfe_hif_init ++ * This function initializes the baseaddresses and irq, etc. ++ */ ++int pfe_hif_init(struct pfe *pfe) ++{ ++ struct pfe_hif *hif = &pfe->hif; ++ int err; ++ ++ pr_info("%s\n", __func__); ++ ++ hif->dev = pfe->dev; ++ hif->irq = pfe->hif_irq; ++ ++ err = pfe_hif_alloc_descr(hif); ++ if (err) ++ goto err0; ++ ++ if (pfe_hif_init_buffers(hif)) { ++ pr_err("%s: Could not initialize buffer descriptors\n" ++ , __func__); ++ err = -ENOMEM; ++ goto err1; ++ } ++ ++ /* Initialize NAPI for Rx processing */ ++ init_dummy_netdev(&hif->dummy_dev); ++ netif_napi_add(&hif->dummy_dev, &hif->napi, pfe_hif_rx_poll, ++ HIF_RX_POLL_WEIGHT); ++ napi_enable(&hif->napi); ++ ++ spin_lock_init(&hif->tx_lock); ++ spin_lock_init(&hif->lock); ++ ++ hif_init(); ++ hif_rx_enable(); ++ hif_tx_enable(); ++ ++ /* Disable tx done interrupt */ ++ writel(HIF_INT_MASK, HIF_INT_ENABLE); ++ ++ gpi_enable(HGPI_BASE_ADDR); ++ ++ err = request_irq(hif->irq, hif_isr, 0, "pfe_hif", hif); ++ if (err) { ++ pr_err("%s: failed to get the hif IRQ = %d\n", ++ __func__, hif->irq); ++ goto err1; ++ } ++ ++ err = request_irq(pfe->wol_irq, wol_isr, 0, "pfe_wol", pfe); ++ if (err) { ++ pr_err("%s: failed to get the wol IRQ = %d\n", ++ __func__, pfe->wol_irq); ++ goto err1; ++ } ++ ++ tasklet_init(&hif->tx_cleanup_tasklet, ++ (void(*)(unsigned long))pfe_tx_do_cleanup, ++ (unsigned long)hif); ++ ++ return 0; ++err1: ++ pfe_hif_free_descr(hif); ++err0: ++ return err; ++} ++ ++/* pfe_hif_exit- */ ++void pfe_hif_exit(struct pfe *pfe) ++{ ++ struct pfe_hif *hif = &pfe->hif; ++ ++ pr_info("%s\n", __func__); ++ ++ tasklet_kill(&hif->tx_cleanup_tasklet); ++ ++ spin_lock_bh(&hif->lock); ++ hif->shm->g_client_status[0] = 0; ++ /* Make sure all clients are disabled*/ ++ hif->shm->g_client_status[1] = 0; ++ ++ spin_unlock_bh(&hif->lock); ++ ++ /*Disable Rx/Tx */ ++ gpi_disable(HGPI_BASE_ADDR); ++ hif_rx_disable(); ++ hif_tx_disable(); ++ ++ napi_disable(&hif->napi); ++ netif_napi_del(&hif->napi); ++ ++ free_irq(pfe->wol_irq, pfe); ++ free_irq(hif->irq, hif); ++ ++ pfe_hif_release_buffers(hif); ++ pfe_hif_free_descr(hif); ++} +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_hif.h +@@ -0,0 +1,211 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _PFE_HIF_H_ ++#define _PFE_HIF_H_ ++ ++#include ++ ++#define HIF_NAPI_STATS ++ ++#define HIF_CLIENT_QUEUES_MAX 16 ++#define HIF_RX_POLL_WEIGHT 64 ++ ++#define HIF_RX_PKT_MIN_SIZE 0x800 /* 2KB */ ++#define HIF_RX_PKT_MIN_SIZE_MASK ~(HIF_RX_PKT_MIN_SIZE - 1) ++#define ROUND_MIN_RX_SIZE(_sz) (((_sz) + (HIF_RX_PKT_MIN_SIZE - 1)) \ ++ & HIF_RX_PKT_MIN_SIZE_MASK) ++#define PRESENT_OFST_IN_PAGE(_buf) (((unsigned long int)(_buf) & (PAGE_SIZE \ ++ - 1)) & HIF_RX_PKT_MIN_SIZE_MASK) ++ ++enum { ++ NAPI_SCHED_COUNT = 0, ++ NAPI_POLL_COUNT, ++ NAPI_PACKET_COUNT, ++ NAPI_DESC_COUNT, ++ NAPI_FULL_BUDGET_COUNT, ++ NAPI_CLIENT_FULL_COUNT, ++ NAPI_MAX_COUNT ++}; ++ ++/* ++ * HIF_TX_DESC_NT value should be always greter than 4, ++ * Otherwise HIF_TX_POLL_MARK will become zero. ++ */ ++#define HIF_RX_DESC_NT 256 ++#define HIF_TX_DESC_NT 2048 ++ ++#define HIF_FIRST_BUFFER BIT(0) ++#define HIF_LAST_BUFFER BIT(1) ++#define HIF_DONT_DMA_MAP BIT(2) ++#define HIF_DATA_VALID BIT(3) ++#define HIF_TSO BIT(4) ++ ++enum { ++ PFE_CL_GEM0 = 0, ++ PFE_CL_GEM1, ++ HIF_CLIENTS_MAX ++}; ++ ++/*structure to store client queue info */ ++struct hif_rx_queue { ++ struct rx_queue_desc *base; ++ u32 size; ++ u32 write_idx; ++}; ++ ++struct hif_tx_queue { ++ struct tx_queue_desc *base; ++ u32 size; ++ u32 ack_idx; ++}; ++ ++/*Structure to store the client info */ ++struct hif_client { ++ int rx_qn; ++ struct hif_rx_queue rx_q[HIF_CLIENT_QUEUES_MAX]; ++ int tx_qn; ++ struct hif_tx_queue tx_q[HIF_CLIENT_QUEUES_MAX]; ++}; ++ ++/*HIF hardware buffer descriptor */ ++struct hif_desc { ++ u32 ctrl; ++ u32 status; ++ u32 data; ++ u32 next; ++}; ++ ++struct __hif_desc { ++ u32 ctrl; ++ u32 status; ++ u32 data; ++}; ++ ++struct hif_desc_sw { ++ dma_addr_t data; ++ u16 len; ++ u8 client_id; ++ u8 q_no; ++ u16 flags; ++}; ++ ++struct hif_hdr { ++ u8 client_id; ++ u8 q_num; ++ u16 client_ctrl; ++ u16 client_ctrl1; ++}; ++ ++struct __hif_hdr { ++ union { ++ struct hif_hdr hdr; ++ u32 word[2]; ++ }; ++}; ++ ++struct hif_ipsec_hdr { ++ u16 sa_handle[2]; ++} __packed; ++ ++/* HIF_CTRL_TX... defines */ ++#define HIF_CTRL_TX_CHECKSUM BIT(2) ++ ++/* HIF_CTRL_RX... defines */ ++#define HIF_CTRL_RX_OFFSET_OFST (24) ++#define HIF_CTRL_RX_CHECKSUMMED BIT(2) ++#define HIF_CTRL_RX_CONTINUED BIT(1) ++ ++struct pfe_hif { ++ /* To store registered clients in hif layer */ ++ struct hif_client client[HIF_CLIENTS_MAX]; ++ struct hif_shm *shm; ++ int irq; ++ ++ void *descr_baseaddr_v; ++ unsigned long descr_baseaddr_p; ++ ++ struct hif_desc *rx_base; ++ u32 rx_ring_size; ++ u32 rxtoclean_index; ++ void *rx_buf_addr[HIF_RX_DESC_NT]; ++ int rx_buf_len[HIF_RX_DESC_NT]; ++ unsigned int qno; ++ unsigned int client_id; ++ unsigned int client_ctrl; ++ unsigned int started; ++ ++ struct hif_desc *tx_base; ++ u32 tx_ring_size; ++ u32 txtosend; ++ u32 txtoclean; ++ u32 txavail; ++ u32 txtoflush; ++ struct hif_desc_sw tx_sw_queue[HIF_TX_DESC_NT]; ++ ++/* tx_lock synchronizes hif packet tx as well as pfe_hif structure access */ ++ spinlock_t tx_lock; ++/* lock synchronizes hif rx queue processing */ ++ spinlock_t lock; ++ struct net_device dummy_dev; ++ struct napi_struct napi; ++ struct device *dev; ++ ++#ifdef HIF_NAPI_STATS ++ unsigned int napi_counters[NAPI_MAX_COUNT]; ++#endif ++ struct tasklet_struct tx_cleanup_tasklet; ++}; ++ ++void __hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int ++ q_no, void *data, u32 len, unsigned int flags); ++int hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no, ++ void *data, unsigned int len); ++void __hif_tx_done_process(struct pfe_hif *hif, int count); ++void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int ++ data2); ++int pfe_hif_init(struct pfe *pfe); ++void pfe_hif_exit(struct pfe *pfe); ++void pfe_hif_rx_idle(struct pfe_hif *hif); ++static inline void hif_tx_done_process(struct pfe_hif *hif, int count) ++{ ++ spin_lock_bh(&hif->tx_lock); ++ __hif_tx_done_process(hif, count); ++ spin_unlock_bh(&hif->tx_lock); ++} ++ ++static inline void hif_tx_lock(struct pfe_hif *hif) ++{ ++ spin_lock_bh(&hif->tx_lock); ++} ++ ++static inline void hif_tx_unlock(struct pfe_hif *hif) ++{ ++ spin_unlock_bh(&hif->tx_lock); ++} ++ ++static inline int __hif_tx_avail(struct pfe_hif *hif) ++{ ++ return hif->txavail; ++} ++ ++#define __memcpy8(dst, src) memcpy(dst, src, 8) ++#define __memcpy12(dst, src) memcpy(dst, src, 12) ++#define __memcpy(dst, src, len) memcpy(dst, src, len) ++ ++#endif /* _PFE_HIF_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.c +@@ -0,0 +1,601 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "pfe_mod.h" ++#include "pfe_hif.h" ++#include "pfe_hif_lib.h" ++ ++unsigned int lro_mode; ++unsigned int page_mode; ++unsigned int tx_qos; ++unsigned int pfe_pkt_size; ++unsigned int pfe_pkt_headroom; ++unsigned int emac_txq_cnt; ++ ++/* ++ * @pfe_hal_lib.c. ++ * Common functions used by HIF client drivers ++ */ ++ ++/*HIF shared memory Global variable */ ++struct hif_shm ghif_shm; ++ ++/* Cleanup the HIF shared memory, release HIF rx_buffer_pool. ++ * This function should be called after pfe_hif_exit ++ * ++ * @param[in] hif_shm Shared memory address location in DDR ++ */ ++static void pfe_hif_shm_clean(struct hif_shm *hif_shm) ++{ ++ int i; ++ void *pkt; ++ ++ for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) { ++ pkt = hif_shm->rx_buf_pool[i]; ++ if (pkt) { ++ hif_shm->rx_buf_pool[i] = NULL; ++ pkt -= pfe_pkt_headroom; ++ ++ if (page_mode) ++ put_page(virt_to_page(pkt)); ++ else ++ kfree(pkt); ++ } ++ } ++} ++ ++/* Initialize shared memory used between HIF driver and clients, ++ * allocate rx_buffer_pool required for HIF Rx descriptors. ++ * This function should be called before initializing HIF driver. ++ * ++ * @param[in] hif_shm Shared memory address location in DDR ++ * @rerurn 0 - on succes, <0 on fail to initialize ++ */ ++static int pfe_hif_shm_init(struct hif_shm *hif_shm) ++{ ++ int i; ++ void *pkt; ++ ++ memset(hif_shm, 0, sizeof(struct hif_shm)); ++ hif_shm->rx_buf_pool_cnt = HIF_RX_DESC_NT; ++ ++ for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) { ++ if (page_mode) { ++ pkt = (void *)__get_free_page(GFP_KERNEL | ++ GFP_DMA_PFE); ++ } else { ++ pkt = kmalloc(PFE_BUF_SIZE, GFP_KERNEL | GFP_DMA_PFE); ++ } ++ ++ if (pkt) ++ hif_shm->rx_buf_pool[i] = pkt + pfe_pkt_headroom; ++ else ++ goto err0; ++ } ++ ++ return 0; ++ ++err0: ++ pr_err("%s Low memory\n", __func__); ++ pfe_hif_shm_clean(hif_shm); ++ return -ENOMEM; ++} ++ ++/*This function sends indication to HIF driver ++ * ++ * @param[in] hif hif context ++ */ ++static void hif_lib_indicate_hif(struct pfe_hif *hif, int req, int data1, int ++ data2) ++{ ++ hif_process_client_req(hif, req, data1, data2); ++} ++ ++void hif_lib_indicate_client(int client_id, int event_type, int qno) ++{ ++ struct hif_client_s *client = pfe->hif_client[client_id]; ++ ++ if (!client || (event_type >= HIF_EVENT_MAX) || (qno >= ++ HIF_CLIENT_QUEUES_MAX)) ++ return; ++ ++ if (!test_and_set_bit(qno, &client->queue_mask[event_type])) ++ client->event_handler(client->priv, event_type, qno); ++} ++ ++/*This function releases Rx queue descriptors memory and pre-filled buffers ++ * ++ * @param[in] client hif_client context ++ */ ++static void hif_lib_client_release_rx_buffers(struct hif_client_s *client) ++{ ++ struct rx_queue_desc *desc; ++ int qno, ii; ++ void *buf; ++ ++ for (qno = 0; qno < client->rx_qn; qno++) { ++ desc = client->rx_q[qno].base; ++ ++ for (ii = 0; ii < client->rx_q[qno].size; ii++) { ++ buf = (void *)desc->data; ++ if (buf) { ++ buf -= pfe_pkt_headroom; ++ ++ if (page_mode) ++ free_page((unsigned long)buf); ++ else ++ kfree(buf); ++ ++ desc->ctrl = 0; ++ } ++ ++ desc++; ++ } ++ } ++ ++ kfree(client->rx_qbase); ++} ++ ++/*This function allocates memory for the rxq descriptors and pre-fill rx queues ++ * with buffers. ++ * @param[in] client client context ++ * @param[in] q_size size of the rxQ, all queues are of same size ++ */ ++static int hif_lib_client_init_rx_buffers(struct hif_client_s *client, int ++ q_size) ++{ ++ struct rx_queue_desc *desc; ++ struct hif_client_rx_queue *queue; ++ int ii, qno; ++ ++ /*Allocate memory for the client queues */ ++ client->rx_qbase = kzalloc(client->rx_qn * q_size * sizeof(struct ++ rx_queue_desc), GFP_KERNEL); ++ if (!client->rx_qbase) ++ goto err; ++ ++ for (qno = 0; qno < client->rx_qn; qno++) { ++ queue = &client->rx_q[qno]; ++ ++ queue->base = client->rx_qbase + qno * q_size * sizeof(struct ++ rx_queue_desc); ++ queue->size = q_size; ++ queue->read_idx = 0; ++ queue->write_idx = 0; ++ ++ pr_debug("rx queue: %d, base: %p, size: %d\n", qno, ++ queue->base, queue->size); ++ } ++ ++ for (qno = 0; qno < client->rx_qn; qno++) { ++ queue = &client->rx_q[qno]; ++ desc = queue->base; ++ ++ for (ii = 0; ii < queue->size; ii++) { ++ desc->ctrl = CL_DESC_BUF_LEN(pfe_pkt_size) | ++ CL_DESC_OWN; ++ desc++; ++ } ++ } ++ ++ return 0; ++ ++err: ++ return 1; ++} ++ ++ ++static void hif_lib_client_cleanup_tx_queue(struct hif_client_tx_queue *queue) ++{ ++ pr_debug("%s\n", __func__); ++ ++ /* ++ * Check if there are any pending packets. Client must flush the tx ++ * queues before unregistering, by calling by calling ++ * hif_lib_tx_get_next_complete() ++ * ++ * Hif no longer calls since we are no longer registered ++ */ ++ if (queue->tx_pending) ++ pr_err("%s: pending transmit packets\n", __func__); ++} ++ ++static void hif_lib_client_release_tx_buffers(struct hif_client_s *client) ++{ ++ int qno; ++ ++ pr_debug("%s\n", __func__); ++ ++ for (qno = 0; qno < client->tx_qn; qno++) ++ hif_lib_client_cleanup_tx_queue(&client->tx_q[qno]); ++ ++ kfree(client->tx_qbase); ++} ++ ++static int hif_lib_client_init_tx_buffers(struct hif_client_s *client, int ++ q_size) ++{ ++ struct hif_client_tx_queue *queue; ++ int qno; ++ ++ client->tx_qbase = kzalloc(client->tx_qn * q_size * sizeof(struct ++ tx_queue_desc), GFP_KERNEL); ++ if (!client->tx_qbase) ++ return 1; ++ ++ for (qno = 0; qno < client->tx_qn; qno++) { ++ queue = &client->tx_q[qno]; ++ ++ queue->base = client->tx_qbase + qno * q_size * sizeof(struct ++ tx_queue_desc); ++ queue->size = q_size; ++ queue->read_idx = 0; ++ queue->write_idx = 0; ++ queue->tx_pending = 0; ++ queue->nocpy_flag = 0; ++ queue->prev_tmu_tx_pkts = 0; ++ queue->done_tmu_tx_pkts = 0; ++ ++ pr_debug("tx queue: %d, base: %p, size: %d\n", qno, ++ queue->base, queue->size); ++ } ++ ++ return 0; ++} ++ ++static int hif_lib_event_dummy(void *priv, int event_type, int qno) ++{ ++ return 0; ++} ++ ++int hif_lib_client_register(struct hif_client_s *client) ++{ ++ struct hif_shm *hif_shm; ++ struct hif_client_shm *client_shm; ++ int err, i; ++ /* int loop_cnt = 0; */ ++ ++ pr_debug("%s\n", __func__); ++ ++ /*Allocate memory before spin_lock*/ ++ if (hif_lib_client_init_rx_buffers(client, client->rx_qsize)) { ++ err = -ENOMEM; ++ goto err_rx; ++ } ++ ++ if (hif_lib_client_init_tx_buffers(client, client->tx_qsize)) { ++ err = -ENOMEM; ++ goto err_tx; ++ } ++ ++ spin_lock_bh(&pfe->hif.lock); ++ if (!(client->pfe) || (client->id >= HIF_CLIENTS_MAX) || ++ (pfe->hif_client[client->id])) { ++ err = -EINVAL; ++ goto err; ++ } ++ ++ hif_shm = client->pfe->hif.shm; ++ ++ if (!client->event_handler) ++ client->event_handler = hif_lib_event_dummy; ++ ++ /*Initialize client specific shared memory */ ++ client_shm = (struct hif_client_shm *)&hif_shm->client[client->id]; ++ client_shm->rx_qbase = (unsigned long int)client->rx_qbase; ++ client_shm->rx_qsize = client->rx_qsize; ++ client_shm->tx_qbase = (unsigned long int)client->tx_qbase; ++ client_shm->tx_qsize = client->tx_qsize; ++ client_shm->ctrl = (client->tx_qn << CLIENT_CTRL_TX_Q_CNT_OFST) | ++ (client->rx_qn << CLIENT_CTRL_RX_Q_CNT_OFST); ++ /* spin_lock_init(&client->rx_lock); */ ++ ++ for (i = 0; i < HIF_EVENT_MAX; i++) { ++ client->queue_mask[i] = 0; /* ++ * By default all events are ++ * unmasked ++ */ ++ } ++ ++ /*Indicate to HIF driver*/ ++ hif_lib_indicate_hif(&pfe->hif, REQUEST_CL_REGISTER, client->id, 0); ++ ++ pr_debug("%s: client: %p, client_id: %d, tx_qsize: %d, rx_qsize: %d\n", ++ __func__, client, client->id, client->tx_qsize, ++ client->rx_qsize); ++ ++ client->cpu_id = -1; ++ ++ pfe->hif_client[client->id] = client; ++ spin_unlock_bh(&pfe->hif.lock); ++ ++ return 0; ++ ++err: ++ spin_unlock_bh(&pfe->hif.lock); ++ hif_lib_client_release_tx_buffers(client); ++ ++err_tx: ++ hif_lib_client_release_rx_buffers(client); ++ ++err_rx: ++ return err; ++} ++ ++int hif_lib_client_unregister(struct hif_client_s *client) ++{ ++ struct pfe *pfe = client->pfe; ++ u32 client_id = client->id; ++ ++ pr_info( ++ "%s : client: %p, client_id: %d, txQ_depth: %d, rxQ_depth: %d\n" ++ , __func__, client, client->id, client->tx_qsize, ++ client->rx_qsize); ++ ++ spin_lock_bh(&pfe->hif.lock); ++ hif_lib_indicate_hif(&pfe->hif, REQUEST_CL_UNREGISTER, client->id, 0); ++ ++ hif_lib_client_release_tx_buffers(client); ++ hif_lib_client_release_rx_buffers(client); ++ pfe->hif_client[client_id] = NULL; ++ spin_unlock_bh(&pfe->hif.lock); ++ ++ return 0; ++} ++ ++int hif_lib_event_handler_start(struct hif_client_s *client, int event, ++ int qno) ++{ ++ struct hif_client_rx_queue *queue = &client->rx_q[qno]; ++ struct rx_queue_desc *desc = queue->base + queue->read_idx; ++ ++ if ((event >= HIF_EVENT_MAX) || (qno >= HIF_CLIENT_QUEUES_MAX)) { ++ pr_debug("%s: Unsupported event : %d queue number : %d\n", ++ __func__, event, qno); ++ return -1; ++ } ++ ++ test_and_clear_bit(qno, &client->queue_mask[event]); ++ ++ switch (event) { ++ case EVENT_RX_PKT_IND: ++ if (!(desc->ctrl & CL_DESC_OWN)) ++ hif_lib_indicate_client(client->id, ++ EVENT_RX_PKT_IND, qno); ++ break; ++ ++ case EVENT_HIGH_RX_WM: ++ case EVENT_TXDONE_IND: ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++/* ++ * This function gets one packet from the specified client queue ++ * It also refill the rx buffer ++ */ ++void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int ++ *ofst, unsigned int *rx_ctrl, ++ unsigned int *desc_ctrl, void **priv_data) ++{ ++ struct hif_client_rx_queue *queue = &client->rx_q[qno]; ++ struct rx_queue_desc *desc; ++ void *pkt = NULL; ++ ++ /* ++ * Following lock is to protect rx queue access from, ++ * hif_lib_event_handler_start. ++ * In general below lock is not required, because hif_lib_xmit_pkt and ++ * hif_lib_event_handler_start are called from napi poll and which is ++ * not re-entrant. But if some client use in different way this lock is ++ * required. ++ */ ++ /*spin_lock_irqsave(&client->rx_lock, flags); */ ++ desc = queue->base + queue->read_idx; ++ if (!(desc->ctrl & CL_DESC_OWN)) { ++ pkt = desc->data - pfe_pkt_headroom; ++ ++ *rx_ctrl = desc->client_ctrl; ++ *desc_ctrl = desc->ctrl; ++ ++ if (desc->ctrl & CL_DESC_FIRST) { ++ u16 size = *rx_ctrl >> HIF_CTRL_RX_OFFSET_OFST; ++ ++ if (size) { ++ *len = CL_DESC_BUF_LEN(desc->ctrl) - ++ PFE_PKT_HEADER_SZ - size; ++ *ofst = pfe_pkt_headroom + PFE_PKT_HEADER_SZ ++ + size; ++ *priv_data = desc->data + PFE_PKT_HEADER_SZ; ++ } else { ++ *len = CL_DESC_BUF_LEN(desc->ctrl) - ++ PFE_PKT_HEADER_SZ; ++ *ofst = pfe_pkt_headroom + PFE_PKT_HEADER_SZ; ++ *priv_data = NULL; ++ } ++ ++ } else { ++ *len = CL_DESC_BUF_LEN(desc->ctrl); ++ *ofst = pfe_pkt_headroom; ++ } ++ ++ /* ++ * Needed so we don't free a buffer/page ++ * twice on module_exit ++ */ ++ desc->data = NULL; ++ ++ /* ++ * Ensure everything else is written to DDR before ++ * writing bd->ctrl ++ */ ++ smp_wmb(); ++ ++ desc->ctrl = CL_DESC_BUF_LEN(pfe_pkt_size) | CL_DESC_OWN; ++ queue->read_idx = (queue->read_idx + 1) & (queue->size - 1); ++ } ++ ++ /*spin_unlock_irqrestore(&client->rx_lock, flags); */ ++ return pkt; ++} ++ ++static inline void hif_hdr_write(struct hif_hdr *pkt_hdr, unsigned int ++ client_id, unsigned int qno, ++ u32 client_ctrl) ++{ ++ /* Optimize the write since the destinaton may be non-cacheable */ ++ if (!((unsigned long)pkt_hdr & 0x3)) { ++ ((u32 *)pkt_hdr)[0] = (client_ctrl << 16) | (qno << 8) | ++ client_id; ++ } else { ++ ((u16 *)pkt_hdr)[0] = (qno << 8) | (client_id & 0xFF); ++ ((u16 *)pkt_hdr)[1] = (client_ctrl & 0xFFFF); ++ } ++} ++ ++/*This function puts the given packet in the specific client queue */ ++void __hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void ++ *data, unsigned int len, u32 client_ctrl, ++ unsigned int flags, void *client_data) ++{ ++ struct hif_client_tx_queue *queue = &client->tx_q[qno]; ++ struct tx_queue_desc *desc = queue->base + queue->write_idx; ++ ++ /* First buffer */ ++ if (flags & HIF_FIRST_BUFFER) { ++ data -= sizeof(struct hif_hdr); ++ len += sizeof(struct hif_hdr); ++ ++ hif_hdr_write(data, client->id, qno, client_ctrl); ++ } ++ ++ desc->data = client_data; ++ desc->ctrl = CL_DESC_OWN | CL_DESC_FLAGS(flags); ++ ++ __hif_xmit_pkt(&pfe->hif, client->id, qno, data, len, flags); ++ ++ queue->write_idx = (queue->write_idx + 1) & (queue->size - 1); ++ queue->tx_pending++; ++ queue->jiffies_last_packet = jiffies; ++} ++ ++void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno, ++ unsigned int *flags, int count) ++{ ++ struct hif_client_tx_queue *queue = &client->tx_q[qno]; ++ struct tx_queue_desc *desc = queue->base + queue->read_idx; ++ ++ pr_debug("%s: qno : %d rd_indx: %d pending:%d\n", __func__, qno, ++ queue->read_idx, queue->tx_pending); ++ ++ if (!queue->tx_pending) ++ return NULL; ++ ++ if (queue->nocpy_flag && !queue->done_tmu_tx_pkts) { ++ u32 tmu_tx_pkts = be32_to_cpu(pe_dmem_read(TMU0_ID + ++ client->id, TMU_DM_TX_TRANS, 4)); ++ ++ if (queue->prev_tmu_tx_pkts > tmu_tx_pkts) ++ queue->done_tmu_tx_pkts = UINT_MAX - ++ queue->prev_tmu_tx_pkts + tmu_tx_pkts; ++ else ++ queue->done_tmu_tx_pkts = tmu_tx_pkts - ++ queue->prev_tmu_tx_pkts; ++ ++ queue->prev_tmu_tx_pkts = tmu_tx_pkts; ++ ++ if (!queue->done_tmu_tx_pkts) ++ return NULL; ++ } ++ ++ if (desc->ctrl & CL_DESC_OWN) ++ return NULL; ++ ++ queue->read_idx = (queue->read_idx + 1) & (queue->size - 1); ++ queue->tx_pending--; ++ ++ *flags = CL_DESC_GET_FLAGS(desc->ctrl); ++ ++ if (queue->done_tmu_tx_pkts && (*flags & HIF_LAST_BUFFER)) ++ queue->done_tmu_tx_pkts--; ++ ++ return desc->data; ++} ++ ++static void hif_lib_tmu_credit_init(struct pfe *pfe) ++{ ++ int i, q; ++ ++ for (i = 0; i < NUM_GEMAC_SUPPORT; i++) ++ for (q = 0; q < emac_txq_cnt; q++) { ++ pfe->tmu_credit.tx_credit_max[i][q] = (q == 0) ? ++ DEFAULT_Q0_QDEPTH : DEFAULT_MAX_QDEPTH; ++ pfe->tmu_credit.tx_credit[i][q] = ++ pfe->tmu_credit.tx_credit_max[i][q]; ++ } ++} ++ ++int pfe_hif_lib_init(struct pfe *pfe) ++{ ++ int rc; ++ ++ pr_info("%s\n", __func__); ++ ++ if (lro_mode) { ++ page_mode = 1; ++ pfe_pkt_size = min(PAGE_SIZE, MAX_PFE_PKT_SIZE); ++ pfe_pkt_headroom = 0; ++ } else { ++ page_mode = 0; ++ pfe_pkt_size = PFE_PKT_SIZE; ++ pfe_pkt_headroom = PFE_PKT_HEADROOM; ++ } ++ ++ if (tx_qos) ++ emac_txq_cnt = EMAC_TXQ_CNT / 2; ++ else ++ emac_txq_cnt = EMAC_TXQ_CNT; ++ ++ hif_lib_tmu_credit_init(pfe); ++ pfe->hif.shm = &ghif_shm; ++ rc = pfe_hif_shm_init(pfe->hif.shm); ++ ++ return rc; ++} ++ ++void pfe_hif_lib_exit(struct pfe *pfe) ++{ ++ pr_info("%s\n", __func__); ++ ++ pfe_hif_shm_clean(pfe->hif.shm); ++} +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.h +@@ -0,0 +1,239 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _PFE_HIF_LIB_H_ ++#define _PFE_HIF_LIB_H_ ++ ++#include "pfe_hif.h" ++ ++#define HIF_CL_REQ_TIMEOUT 10 ++#define GFP_DMA_PFE 0 ++ ++enum { ++ REQUEST_CL_REGISTER = 0, ++ REQUEST_CL_UNREGISTER, ++ HIF_REQUEST_MAX ++}; ++ ++enum { ++ /* Event to indicate that client rx queue is reached water mark level */ ++ EVENT_HIGH_RX_WM = 0, ++ /* Event to indicate that, packet received for client */ ++ EVENT_RX_PKT_IND, ++ /* Event to indicate that, packet tx done for client */ ++ EVENT_TXDONE_IND, ++ HIF_EVENT_MAX ++}; ++ ++/*structure to store client queue info */ ++ ++/*structure to store client queue info */ ++struct hif_client_rx_queue { ++ struct rx_queue_desc *base; ++ u32 size; ++ u32 read_idx; ++ u32 write_idx; ++}; ++ ++struct hif_client_tx_queue { ++ struct tx_queue_desc *base; ++ u32 size; ++ u32 read_idx; ++ u32 write_idx; ++ u32 tx_pending; ++ unsigned long jiffies_last_packet; ++ u32 nocpy_flag; ++ u32 prev_tmu_tx_pkts; ++ u32 done_tmu_tx_pkts; ++}; ++ ++struct hif_client_s { ++ int id; ++ int tx_qn; ++ int rx_qn; ++ void *rx_qbase; ++ void *tx_qbase; ++ int tx_qsize; ++ int rx_qsize; ++ int cpu_id; ++ struct hif_client_tx_queue tx_q[HIF_CLIENT_QUEUES_MAX]; ++ struct hif_client_rx_queue rx_q[HIF_CLIENT_QUEUES_MAX]; ++ int (*event_handler)(void *priv, int event, int data); ++ unsigned long queue_mask[HIF_EVENT_MAX]; ++ struct pfe *pfe; ++ void *priv; ++}; ++ ++/* ++ * Client specific shared memory ++ * It contains number of Rx/Tx queues, base addresses and queue sizes ++ */ ++struct hif_client_shm { ++ u32 ctrl; /*0-7: number of Rx queues, 8-15: number of tx queues */ ++ unsigned long rx_qbase; /*Rx queue base address */ ++ u32 rx_qsize; /*each Rx queue size, all Rx queues are of same size */ ++ unsigned long tx_qbase; /* Tx queue base address */ ++ u32 tx_qsize; /*each Tx queue size, all Tx queues are of same size */ ++}; ++ ++/*Client shared memory ctrl bit description */ ++#define CLIENT_CTRL_RX_Q_CNT_OFST 0 ++#define CLIENT_CTRL_TX_Q_CNT_OFST 8 ++#define CLIENT_CTRL_RX_Q_CNT(ctrl) (((ctrl) >> CLIENT_CTRL_RX_Q_CNT_OFST) \ ++ & 0xFF) ++#define CLIENT_CTRL_TX_Q_CNT(ctrl) (((ctrl) >> CLIENT_CTRL_TX_Q_CNT_OFST) \ ++ & 0xFF) ++ ++/* ++ * Shared memory used to communicate between HIF driver and host/client drivers ++ * Before starting the hif driver rx_buf_pool ans rx_buf_pool_cnt should be ++ * initialized with host buffers and buffers count in the pool. ++ * rx_buf_pool_cnt should be >= HIF_RX_DESC_NT. ++ * ++ */ ++struct hif_shm { ++ u32 rx_buf_pool_cnt; /*Number of rx buffers available*/ ++ /*Rx buffers required to initialize HIF rx descriptors */ ++ void *rx_buf_pool[HIF_RX_DESC_NT]; ++ unsigned long g_client_status[2]; /*Global client status bit mask */ ++ /* Client specific shared memory */ ++ struct hif_client_shm client[HIF_CLIENTS_MAX]; ++}; ++ ++#define CL_DESC_OWN BIT(31) ++/* This sets owner ship to HIF driver */ ++#define CL_DESC_LAST BIT(30) ++/* This indicates last packet for multi buffers handling */ ++#define CL_DESC_FIRST BIT(29) ++/* This indicates first packet for multi buffers handling */ ++ ++#define CL_DESC_BUF_LEN(x) ((x) & 0xFFFF) ++#define CL_DESC_FLAGS(x) (((x) & 0xF) << 16) ++#define CL_DESC_GET_FLAGS(x) (((x) >> 16) & 0xF) ++ ++struct rx_queue_desc { ++ void *data; ++ u32 ctrl; /*0-15bit len, 16-20bit flags, 31bit owner*/ ++ u32 client_ctrl; ++}; ++ ++struct tx_queue_desc { ++ void *data; ++ u32 ctrl; /*0-15bit len, 16-20bit flags, 31bit owner*/ ++}; ++ ++/* HIF Rx is not working properly for 2-byte aligned buffers and ++ * ip_header should be 4byte aligned for better iperformance. ++ * "ip_header = 64 + 6(hif_header) + 14 (MAC Header)" will be 4byte aligned. ++ */ ++#define PFE_PKT_HEADER_SZ sizeof(struct hif_hdr) ++/* must be big enough for headroom, pkt size and skb shared info */ ++#define PFE_BUF_SIZE 2048 ++#define PFE_PKT_HEADROOM 128 ++ ++#define SKB_SHARED_INFO_SIZE (sizeof(struct skb_shared_info)) ++#define PFE_PKT_SIZE (PFE_BUF_SIZE - PFE_PKT_HEADROOM \ ++ - SKB_SHARED_INFO_SIZE) ++#define MAX_L2_HDR_SIZE 14 /* Not correct for VLAN/PPPoE */ ++#define MAX_L3_HDR_SIZE 20 /* Not correct for IPv6 */ ++#define MAX_L4_HDR_SIZE 60 /* TCP with maximum options */ ++#define MAX_HDR_SIZE (MAX_L2_HDR_SIZE + MAX_L3_HDR_SIZE \ ++ + MAX_L4_HDR_SIZE) ++/* Used in page mode to clamp packet size to the maximum supported by the hif ++ *hw interface (<16KiB) ++ */ ++#define MAX_PFE_PKT_SIZE 16380UL ++ ++extern unsigned int pfe_pkt_size; ++extern unsigned int pfe_pkt_headroom; ++extern unsigned int page_mode; ++extern unsigned int lro_mode; ++extern unsigned int tx_qos; ++extern unsigned int emac_txq_cnt; ++ ++int pfe_hif_lib_init(struct pfe *pfe); ++void pfe_hif_lib_exit(struct pfe *pfe); ++int hif_lib_client_register(struct hif_client_s *client); ++int hif_lib_client_unregister(struct hif_client_s *client); ++void __hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void ++ *data, unsigned int len, u32 client_ctrl, ++ unsigned int flags, void *client_data); ++int hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void *data, ++ unsigned int len, u32 client_ctrl, void *client_data); ++void hif_lib_indicate_client(int cl_id, int event, int data); ++int hif_lib_event_handler_start(struct hif_client_s *client, int event, int ++ data); ++int hif_lib_tmu_queue_start(struct hif_client_s *client, int qno); ++int hif_lib_tmu_queue_stop(struct hif_client_s *client, int qno); ++void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno, ++ unsigned int *flags, int count); ++void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int ++ *ofst, unsigned int *rx_ctrl, ++ unsigned int *desc_ctrl, void **priv_data); ++void hif_lib_set_rx_cpu_affinity(struct hif_client_s *client, int cpu_id); ++void hif_lib_set_tx_queue_nocpy(struct hif_client_s *client, int qno, int ++ enable); ++static inline int hif_lib_tx_avail(struct hif_client_s *client, unsigned int ++ qno) ++{ ++ struct hif_client_tx_queue *queue = &client->tx_q[qno]; ++ ++ return (queue->size - queue->tx_pending); ++} ++ ++static inline int hif_lib_get_tx_wr_index(struct hif_client_s *client, unsigned ++ int qno) ++{ ++ struct hif_client_tx_queue *queue = &client->tx_q[qno]; ++ ++ return queue->write_idx; ++} ++ ++static inline int hif_lib_tx_pending(struct hif_client_s *client, unsigned int ++ qno) ++{ ++ struct hif_client_tx_queue *queue = &client->tx_q[qno]; ++ ++ return queue->tx_pending; ++} ++ ++#define hif_lib_tx_credit_avail(pfe, id, qno) \ ++ ((pfe)->tmu_credit.tx_credit[id][qno]) ++ ++#define hif_lib_tx_credit_max(pfe, id, qno) \ ++ ((pfe)->tmu_credit.tx_credit_max[id][qno]) ++ ++/* ++ * Test comment ++ */ ++#define hif_lib_tx_credit_use(pfe, id, qno, credit) \ ++ ({ typeof(pfe) pfe_ = pfe; \ ++ typeof(id) id_ = id; \ ++ typeof(qno) qno_ = qno_; \ ++ typeof(credit) credit_ = credit; \ ++ do { \ ++ if (tx_qos) { \ ++ (pfe_)->tmu_credit.tx_credit[id_][qno_]\ ++ -= credit_; \ ++ (pfe_)->tmu_credit.tx_packets[id_][qno_]\ ++ += credit_; \ ++ } \ ++ } while (0); \ ++ }) ++ ++#endif /* _PFE_HIF_LIB_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_hw.c +@@ -0,0 +1,176 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#include "pfe_mod.h" ++#include "pfe_hw.h" ++ ++/* Functions to handle most of pfe hw register initialization */ ++int pfe_hw_init(struct pfe *pfe, int resume) ++{ ++ struct class_cfg class_cfg = { ++ .pe_sys_clk_ratio = PE_SYS_CLK_RATIO, ++ .route_table_baseaddr = pfe->ddr_phys_baseaddr + ++ ROUTE_TABLE_BASEADDR, ++ .route_table_hash_bits = ROUTE_TABLE_HASH_BITS, ++ }; ++ ++ struct tmu_cfg tmu_cfg = { ++ .pe_sys_clk_ratio = PE_SYS_CLK_RATIO, ++ .llm_base_addr = pfe->ddr_phys_baseaddr + TMU_LLM_BASEADDR, ++ .llm_queue_len = TMU_LLM_QUEUE_LEN, ++ }; ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ struct util_cfg util_cfg = { ++ .pe_sys_clk_ratio = PE_SYS_CLK_RATIO, ++ }; ++#endif ++ ++ struct BMU_CFG bmu1_cfg = { ++ .baseaddr = CBUS_VIRT_TO_PFE(LMEM_BASE_ADDR + ++ BMU1_LMEM_BASEADDR), ++ .count = BMU1_BUF_COUNT, ++ .size = BMU1_BUF_SIZE, ++ .low_watermark = 10, ++ .high_watermark = 15, ++ }; ++ ++ struct BMU_CFG bmu2_cfg = { ++ .baseaddr = DDR_PHYS_TO_PFE(pfe->ddr_phys_baseaddr + ++ BMU2_DDR_BASEADDR), ++ .count = BMU2_BUF_COUNT, ++ .size = BMU2_BUF_SIZE, ++ .low_watermark = 250, ++ .high_watermark = 253, ++ }; ++ ++ struct gpi_cfg egpi1_cfg = { ++ .lmem_rtry_cnt = EGPI1_LMEM_RTRY_CNT, ++ .tmlf_txthres = EGPI1_TMLF_TXTHRES, ++ .aseq_len = EGPI1_ASEQ_LEN, ++ .mtip_pause_reg = CBUS_VIRT_TO_PFE(EMAC1_BASE_ADDR + ++ EMAC_TCNTRL_REG), ++ }; ++ ++ struct gpi_cfg egpi2_cfg = { ++ .lmem_rtry_cnt = EGPI2_LMEM_RTRY_CNT, ++ .tmlf_txthres = EGPI2_TMLF_TXTHRES, ++ .aseq_len = EGPI2_ASEQ_LEN, ++ .mtip_pause_reg = CBUS_VIRT_TO_PFE(EMAC2_BASE_ADDR + ++ EMAC_TCNTRL_REG), ++ }; ++ ++ struct gpi_cfg hgpi_cfg = { ++ .lmem_rtry_cnt = HGPI_LMEM_RTRY_CNT, ++ .tmlf_txthres = HGPI_TMLF_TXTHRES, ++ .aseq_len = HGPI_ASEQ_LEN, ++ .mtip_pause_reg = 0, ++ }; ++ ++ pr_info("%s\n", __func__); ++ ++#if !defined(LS1012A_PFE_RESET_WA) ++ /* LS1012A needs this to make PE work correctly */ ++ writel(0x3, CLASS_PE_SYS_CLK_RATIO); ++ writel(0x3, TMU_PE_SYS_CLK_RATIO); ++ writel(0x3, UTIL_PE_SYS_CLK_RATIO); ++ usleep_range(10, 20); ++#endif ++ ++ pr_info("CLASS version: %x\n", readl(CLASS_VERSION)); ++ pr_info("TMU version: %x\n", readl(TMU_VERSION)); ++ ++ pr_info("BMU1 version: %x\n", readl(BMU1_BASE_ADDR + ++ BMU_VERSION)); ++ pr_info("BMU2 version: %x\n", readl(BMU2_BASE_ADDR + ++ BMU_VERSION)); ++ ++ pr_info("EGPI1 version: %x\n", readl(EGPI1_BASE_ADDR + ++ GPI_VERSION)); ++ pr_info("EGPI2 version: %x\n", readl(EGPI2_BASE_ADDR + ++ GPI_VERSION)); ++ pr_info("HGPI version: %x\n", readl(HGPI_BASE_ADDR + ++ GPI_VERSION)); ++ ++ pr_info("HIF version: %x\n", readl(HIF_VERSION)); ++ pr_info("HIF NOPCY version: %x\n", readl(HIF_NOCPY_VERSION)); ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ pr_info("UTIL version: %x\n", readl(UTIL_VERSION)); ++#endif ++ while (!(readl(TMU_CTRL) & ECC_MEM_INIT_DONE)) ++ ; ++ ++ hif_rx_disable(); ++ hif_tx_disable(); ++ ++ bmu_init(BMU1_BASE_ADDR, &bmu1_cfg); ++ ++ pr_info("bmu_init(1) done\n"); ++ ++ bmu_init(BMU2_BASE_ADDR, &bmu2_cfg); ++ ++ pr_info("bmu_init(2) done\n"); ++ ++ class_cfg.resume = resume ? 1 : 0; ++ ++ class_init(&class_cfg); ++ ++ pr_info("class_init() done\n"); ++ ++ tmu_init(&tmu_cfg); ++ ++ pr_info("tmu_init() done\n"); ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ util_init(&util_cfg); ++ ++ pr_info("util_init() done\n"); ++#endif ++ gpi_init(EGPI1_BASE_ADDR, &egpi1_cfg); ++ ++ pr_info("gpi_init(1) done\n"); ++ ++ gpi_init(EGPI2_BASE_ADDR, &egpi2_cfg); ++ ++ pr_info("gpi_init(2) done\n"); ++ ++ gpi_init(HGPI_BASE_ADDR, &hgpi_cfg); ++ ++ pr_info("gpi_init(hif) done\n"); ++ ++ bmu_enable(BMU1_BASE_ADDR); ++ ++ pr_info("bmu_enable(1) done\n"); ++ ++ bmu_enable(BMU2_BASE_ADDR); ++ ++ pr_info("bmu_enable(2) done\n"); ++ ++ return 0; ++} ++ ++void pfe_hw_exit(struct pfe *pfe) ++{ ++ pr_info("%s\n", __func__); ++ ++ bmu_disable(BMU1_BASE_ADDR); ++ bmu_reset(BMU1_BASE_ADDR); ++ ++ bmu_disable(BMU2_BASE_ADDR); ++ bmu_reset(BMU2_BASE_ADDR); ++} +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_hw.h +@@ -0,0 +1,27 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _PFE_HW_H_ ++#define _PFE_HW_H_ ++ ++#define PE_SYS_CLK_RATIO 1 /* SYS/AXI = 250MHz, HFE = 500MHz */ ++ ++int pfe_hw_init(struct pfe *pfe, int resume); ++void pfe_hw_exit(struct pfe *pfe); ++ ++#endif /* _PFE_HW_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c +@@ -0,0 +1,394 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "pfe_mod.h" ++ ++struct ls1012a_pfe_platform_data pfe_platform_data; ++ ++static int pfe_get_gemac_if_proprties(struct device_node *parent, int port, int ++ if_cnt, ++ struct ls1012a_pfe_platform_data ++ *pdata) ++{ ++ struct device_node *gem = NULL, *phy = NULL; ++ int size; ++ int ii = 0, phy_id = 0; ++ const u32 *addr; ++ const void *mac_addr; ++ ++ for (ii = 0; ii < if_cnt; ii++) { ++ gem = of_get_next_child(parent, gem); ++ if (!gem) ++ goto err; ++ addr = of_get_property(gem, "reg", &size); ++ if (addr && (be32_to_cpup(addr) == port)) ++ break; ++ } ++ ++ if (ii >= if_cnt) { ++ pr_err("%s:%d Failed to find interface = %d\n", ++ __func__, __LINE__, if_cnt); ++ goto err; ++ } ++ ++ pdata->ls1012a_eth_pdata[port].gem_id = port; ++ ++ mac_addr = of_get_mac_address(gem); ++ ++ if (mac_addr) { ++ memcpy(pdata->ls1012a_eth_pdata[port].mac_addr, mac_addr, ++ ETH_ALEN); ++ } ++ ++ pdata->ls1012a_eth_pdata[port].mii_config = of_get_phy_mode(gem); ++ ++ if ((pdata->ls1012a_eth_pdata[port].mii_config) < 0) ++ pr_err("%s:%d Incorrect Phy mode....\n", __func__, ++ __LINE__); ++ ++ addr = of_get_property(gem, "fsl,gemac-bus-id", &size); ++ if (!addr) ++ pr_err("%s:%d Invalid gemac-bus-id....\n", __func__, ++ __LINE__); ++ else ++ pdata->ls1012a_eth_pdata[port].bus_id = be32_to_cpup(addr); ++ ++ addr = of_get_property(gem, "fsl,gemac-phy-id", &size); ++ if (!addr) { ++ pr_err("%s:%d Invalid gemac-phy-id....\n", __func__, ++ __LINE__); ++ } else { ++ phy_id = be32_to_cpup(addr); ++ pdata->ls1012a_eth_pdata[port].phy_id = phy_id; ++ pdata->ls1012a_mdio_pdata[0].phy_mask &= ~(1 << phy_id); ++ } ++ ++ addr = of_get_property(gem, "fsl,mdio-mux-val", &size); ++ if (!addr) ++ pr_err("%s: Invalid mdio-mux-val....\n", __func__); ++ else ++ phy_id = be32_to_cpup(addr); ++ pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id; ++ ++ if (pdata->ls1012a_eth_pdata[port].phy_id < 32) ++ pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] = ++ pdata->ls1012a_eth_pdata[port].mdio_muxval; ++ ++ addr = of_get_property(gem, "fsl,pfe-phy-if-flags", &size); ++ if (!addr) ++ pr_err("%s:%d Invalid pfe-phy-if-flags....\n", ++ __func__, __LINE__); ++ else ++ pdata->ls1012a_eth_pdata[port].phy_flags = be32_to_cpup(addr); ++ ++ /* If PHY is enabled, read mdio properties */ ++ if (pdata->ls1012a_eth_pdata[port].phy_flags & GEMAC_NO_PHY) ++ goto done; ++ ++ phy = of_get_next_child(gem, NULL); ++ ++ addr = of_get_property(phy, "reg", &size); ++ ++ if (!addr) ++ pr_err("%s:%d Invalid phy enable flag....\n", ++ __func__, __LINE__); ++ else ++ pdata->ls1012a_mdio_pdata[port].enabled = be32_to_cpup(addr); ++ ++ pdata->ls1012a_mdio_pdata[port].irq[0] = PHY_POLL; ++ ++done: ++ ++ return 0; ++ ++err: ++ return -1; ++} ++ ++/* ++ * ++ * pfe_platform_probe - ++ * ++ * ++ */ ++static int pfe_platform_probe(struct platform_device *pdev) ++{ ++ struct resource res; ++ int ii, rc, interface_count = 0, size = 0; ++ const u32 *prop; ++ struct device_node *np; ++ struct clk *pfe_clk; ++ ++ np = pdev->dev.of_node; ++ ++ if (!np) { ++ pr_err("Invalid device node\n"); ++ return -EINVAL; ++ } ++ ++ pfe = kzalloc(sizeof(*pfe), GFP_KERNEL); ++ if (!pfe) { ++ rc = -ENOMEM; ++ goto err_alloc; ++ } ++ ++ platform_set_drvdata(pdev, pfe); ++ ++ dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); ++ ++ if (of_address_to_resource(np, 1, &res)) { ++ rc = -ENOMEM; ++ pr_err("failed to get ddr resource\n"); ++ goto err_ddr; ++ } ++ ++ pfe->ddr_phys_baseaddr = res.start; ++ pfe->ddr_size = resource_size(&res); ++ ++ pfe->ddr_baseaddr = phys_to_virt(res.start); ++ if (!pfe->ddr_baseaddr) { ++ pr_err("ioremap() ddr failed\n"); ++ rc = -ENOMEM; ++ goto err_ddr; ++ } ++ ++ pfe->scfg = ++ syscon_regmap_lookup_by_phandle(pdev->dev.of_node, ++ "fsl,pfe-scfg"); ++ if (IS_ERR(pfe->scfg)) { ++ dev_err(&pdev->dev, "No syscfg phandle specified\n"); ++ return PTR_ERR(pfe->scfg); ++ } ++ ++ pfe->cbus_baseaddr = of_iomap(np, 0); ++ if (!pfe->cbus_baseaddr) { ++ rc = -ENOMEM; ++ pr_err("failed to get axi resource\n"); ++ goto err_axi; ++ } ++ ++ pfe->hif_irq = platform_get_irq(pdev, 0); ++ if (pfe->hif_irq < 0) { ++ pr_err("platform_get_irq for hif failed\n"); ++ rc = pfe->hif_irq; ++ goto err_hif_irq; ++ } ++ ++ pfe->wol_irq = platform_get_irq(pdev, 2); ++ if (pfe->wol_irq < 0) { ++ pr_err("platform_get_irq for WoL failed\n"); ++ rc = pfe->wol_irq; ++ goto err_hif_irq; ++ } ++ ++ /* Read interface count */ ++ prop = of_get_property(np, "fsl,pfe-num-interfaces", &size); ++ if (!prop) { ++ pr_err("Failed to read number of interfaces\n"); ++ rc = -ENXIO; ++ goto err_prop; ++ } ++ ++ interface_count = be32_to_cpup(prop); ++ if (interface_count <= 0) { ++ pr_err("No ethernet interface count : %d\n", ++ interface_count); ++ rc = -ENXIO; ++ goto err_prop; ++ } ++ ++ pfe_platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff; ++ ++ for (ii = 0; ii < interface_count; ii++) { ++ pfe_get_gemac_if_proprties(np, ii, interface_count, ++ &pfe_platform_data); ++ } ++ ++ pfe->dev = &pdev->dev; ++ ++ pfe->dev->platform_data = &pfe_platform_data; ++ ++ /* declare WoL capabilities */ ++ device_init_wakeup(&pdev->dev, true); ++ ++ /* find the clocks */ ++ pfe_clk = devm_clk_get(pfe->dev, "pfe"); ++ if (IS_ERR(pfe_clk)) ++ return PTR_ERR(pfe_clk); ++ ++ /* PFE clock is (platform clock / 2) */ ++ /* save sys_clk value as KHz */ ++ pfe->ctrl.sys_clk = clk_get_rate(pfe_clk) / (2 * 1000); ++ ++ rc = pfe_probe(pfe); ++ if (rc < 0) ++ goto err_probe; ++ ++ return 0; ++ ++err_probe: ++err_prop: ++err_hif_irq: ++ iounmap(pfe->cbus_baseaddr); ++ ++err_axi: ++ iounmap(pfe->ddr_baseaddr); ++ ++err_ddr: ++ platform_set_drvdata(pdev, NULL); ++ ++ kfree(pfe); ++ ++err_alloc: ++ return rc; ++} ++ ++/* ++ * pfe_platform_remove - ++ */ ++static int pfe_platform_remove(struct platform_device *pdev) ++{ ++ struct pfe *pfe = platform_get_drvdata(pdev); ++ int rc; ++ ++ pr_info("%s\n", __func__); ++ ++ rc = pfe_remove(pfe); ++ ++ iounmap(pfe->cbus_baseaddr); ++ iounmap(pfe->ddr_baseaddr); ++ ++ platform_set_drvdata(pdev, NULL); ++ ++ kfree(pfe); ++ ++ return rc; ++} ++ ++#ifdef CONFIG_PM ++#ifdef CONFIG_PM_SLEEP ++int pfe_platform_suspend(struct device *dev) ++{ ++ struct pfe *pfe = platform_get_drvdata(to_platform_device(dev)); ++ struct net_device *netdev; ++ int i; ++ ++ pfe->wake = 0; ++ ++ for (i = 0; i < (NUM_GEMAC_SUPPORT); i++) { ++ netdev = pfe->eth.eth_priv[i]->ndev; ++ ++ netif_device_detach(netdev); ++ ++ if (netif_running(netdev)) ++ if (pfe_eth_suspend(netdev)) ++ pfe->wake = 1; ++ } ++ ++ /* Shutdown PFE only if we're not waking up the system */ ++ if (!pfe->wake) { ++#if defined(LS1012A_PFE_RESET_WA) ++ pfe_hif_rx_idle(&pfe->hif); ++#endif ++ pfe_ctrl_suspend(&pfe->ctrl); ++ pfe_firmware_exit(pfe); ++ ++ pfe_hif_exit(pfe); ++ pfe_hif_lib_exit(pfe); ++ ++ pfe_hw_exit(pfe); ++ } ++ ++ return 0; ++} ++ ++static int pfe_platform_resume(struct device *dev) ++{ ++ struct pfe *pfe = platform_get_drvdata(to_platform_device(dev)); ++ struct net_device *netdev; ++ int i; ++ ++ if (!pfe->wake) { ++ pfe_hw_init(pfe, 1); ++ pfe_hif_lib_init(pfe); ++ pfe_hif_init(pfe); ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ util_enable(); ++#endif ++ tmu_enable(0xf); ++ class_enable(); ++ pfe_ctrl_resume(&pfe->ctrl); ++ } ++ ++ for (i = 0; i < (NUM_GEMAC_SUPPORT); i++) { ++ netdev = pfe->eth.eth_priv[i]->ndev; ++ ++ if (pfe->eth.eth_priv[i]->mii_bus) ++ pfe_eth_mdio_reset(pfe->eth.eth_priv[i]->mii_bus); ++ ++ if (netif_running(netdev)) ++ pfe_eth_resume(netdev); ++ ++ netif_device_attach(netdev); ++ } ++ return 0; ++} ++#else ++#define pfe_platform_suspend NULL ++#define pfe_platform_resume NULL ++#endif ++ ++static const struct dev_pm_ops pfe_platform_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(pfe_platform_suspend, pfe_platform_resume) ++}; ++#endif ++ ++static const struct of_device_id pfe_match[] = { ++ { ++ .compatible = "fsl,pfe", ++ }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, pfe_match); ++ ++static struct platform_driver pfe_platform_driver = { ++ .probe = pfe_platform_probe, ++ .remove = pfe_platform_remove, ++ .driver = { ++ .name = "pfe", ++ .of_match_table = pfe_match, ++#ifdef CONFIG_PM ++ .pm = &pfe_platform_pm_ops, ++#endif ++ }, ++}; ++ ++module_platform_driver(pfe_platform_driver); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("PFE Ethernet driver"); ++MODULE_AUTHOR("NXP DNCPE"); +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_mod.c +@@ -0,0 +1,141 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#include ++#include "pfe_mod.h" ++ ++struct pfe *pfe; ++ ++/* ++ * pfe_probe - ++ */ ++int pfe_probe(struct pfe *pfe) ++{ ++ int rc; ++ ++ if (pfe->ddr_size < DDR_MAX_SIZE) { ++ pr_err("%s: required DDR memory (%x) above platform ddr memory (%x)\n", ++ __func__, (unsigned int)DDR_MAX_SIZE, pfe->ddr_size); ++ rc = -ENOMEM; ++ goto err_hw; ++ } ++ ++ if (((int)(pfe->ddr_phys_baseaddr + BMU2_DDR_BASEADDR) & ++ (8 * SZ_1M - 1)) != 0) { ++ pr_err("%s: BMU2 base address (0x%x) must be aligned on 8MB boundary\n", ++ __func__, (int)pfe->ddr_phys_baseaddr + ++ BMU2_DDR_BASEADDR); ++ rc = -ENOMEM; ++ goto err_hw; ++ } ++ ++ pr_info("cbus_baseaddr: %lx, ddr_baseaddr: %lx, ddr_phys_baseaddr: %lx, ddr_size: %x\n", ++ (unsigned long)pfe->cbus_baseaddr, ++ (unsigned long)pfe->ddr_baseaddr, ++ pfe->ddr_phys_baseaddr, pfe->ddr_size); ++ ++ pfe_lib_init(pfe->cbus_baseaddr, pfe->ddr_baseaddr, ++ pfe->ddr_phys_baseaddr, pfe->ddr_size); ++ ++ rc = pfe_hw_init(pfe, 0); ++ if (rc < 0) ++ goto err_hw; ++ ++ rc = pfe_hif_lib_init(pfe); ++ if (rc < 0) ++ goto err_hif_lib; ++ ++ rc = pfe_hif_init(pfe); ++ if (rc < 0) ++ goto err_hif; ++ ++ rc = pfe_firmware_init(pfe); ++ if (rc < 0) ++ goto err_firmware; ++ ++ rc = pfe_ctrl_init(pfe); ++ if (rc < 0) ++ goto err_ctrl; ++ ++ rc = pfe_eth_init(pfe); ++ if (rc < 0) ++ goto err_eth; ++ ++ rc = pfe_sysfs_init(pfe); ++ if (rc < 0) ++ goto err_sysfs; ++ ++ rc = pfe_debugfs_init(pfe); ++ if (rc < 0) ++ goto err_debugfs; ++ ++ return 0; ++ ++err_debugfs: ++ pfe_sysfs_exit(pfe); ++ ++err_sysfs: ++ pfe_eth_exit(pfe); ++ ++err_eth: ++ pfe_ctrl_exit(pfe); ++ ++err_ctrl: ++ pfe_firmware_exit(pfe); ++ ++err_firmware: ++ pfe_hif_exit(pfe); ++ ++err_hif: ++ pfe_hif_lib_exit(pfe); ++ ++err_hif_lib: ++ pfe_hw_exit(pfe); ++ ++err_hw: ++ return rc; ++} ++ ++/* ++ * pfe_remove - ++ */ ++int pfe_remove(struct pfe *pfe) ++{ ++ pr_info("%s\n", __func__); ++ ++ pfe_debugfs_exit(pfe); ++ ++ pfe_sysfs_exit(pfe); ++ ++ pfe_eth_exit(pfe); ++ ++ pfe_ctrl_exit(pfe); ++ ++#if defined(LS1012A_PFE_RESET_WA) ++ pfe_hif_rx_idle(&pfe->hif); ++#endif ++ pfe_firmware_exit(pfe); ++ ++ pfe_hif_exit(pfe); ++ ++ pfe_hif_lib_exit(pfe); ++ ++ pfe_hw_exit(pfe); ++ ++ return 0; ++} +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_mod.h +@@ -0,0 +1,112 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _PFE_MOD_H_ ++#define _PFE_MOD_H_ ++ ++#include ++#include ++ ++struct pfe; ++ ++#include "pfe_hw.h" ++#include "pfe_firmware.h" ++#include "pfe_ctrl.h" ++#include "pfe_hif.h" ++#include "pfe_hif_lib.h" ++#include "pfe_eth.h" ++#include "pfe_sysfs.h" ++#include "pfe_perfmon.h" ++#include "pfe_debugfs.h" ++ ++#define PHYID_MAX_VAL 32 ++ ++struct pfe_tmu_credit { ++ /* Number of allowed TX packet in-flight, matches TMU queue size */ ++ unsigned int tx_credit[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT]; ++ unsigned int tx_credit_max[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT]; ++ unsigned int tx_packets[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT]; ++}; ++ ++struct pfe { ++ struct regmap *scfg; ++ unsigned long ddr_phys_baseaddr; ++ void *ddr_baseaddr; ++ unsigned int ddr_size; ++ void *cbus_baseaddr; ++ void *apb_baseaddr; ++ unsigned long iram_phys_baseaddr; ++ void *iram_baseaddr; ++ unsigned long ipsec_phys_baseaddr; ++ void *ipsec_baseaddr; ++ int hif_irq; ++ int wol_irq; ++ int hif_client_irq; ++ struct device *dev; ++ struct dentry *dentry; ++ struct pfe_ctrl ctrl; ++ struct pfe_hif hif; ++ struct pfe_eth eth; ++ struct hif_client_s *hif_client[HIF_CLIENTS_MAX]; ++#if defined(CFG_DIAGS) ++ struct pfe_diags diags; ++#endif ++ struct pfe_tmu_credit tmu_credit; ++ struct pfe_cpumon cpumon; ++ struct pfe_memmon memmon; ++ int wake; ++ int mdio_muxval[PHYID_MAX_VAL]; ++ struct clk *hfe_clock; ++}; ++ ++extern struct pfe *pfe; ++ ++int pfe_probe(struct pfe *pfe); ++int pfe_remove(struct pfe *pfe); ++ ++/* DDR Mapping in reserved memory*/ ++#define ROUTE_TABLE_BASEADDR 0 ++#define ROUTE_TABLE_HASH_BITS 15 /* 32K entries */ ++#define ROUTE_TABLE_SIZE ((1 << ROUTE_TABLE_HASH_BITS) \ ++ * CLASS_ROUTE_SIZE) ++#define BMU2_DDR_BASEADDR (ROUTE_TABLE_BASEADDR + ROUTE_TABLE_SIZE) ++#define BMU2_BUF_COUNT (4096 - 256) ++/* This is to get a total DDR size of 12MiB */ ++#define BMU2_DDR_SIZE (DDR_BUF_SIZE * BMU2_BUF_COUNT) ++#define UTIL_CODE_BASEADDR (BMU2_DDR_BASEADDR + BMU2_DDR_SIZE) ++#define UTIL_CODE_SIZE (128 * SZ_1K) ++#define UTIL_DDR_DATA_BASEADDR (UTIL_CODE_BASEADDR + UTIL_CODE_SIZE) ++#define UTIL_DDR_DATA_SIZE (64 * SZ_1K) ++#define CLASS_DDR_DATA_BASEADDR (UTIL_DDR_DATA_BASEADDR + UTIL_DDR_DATA_SIZE) ++#define CLASS_DDR_DATA_SIZE (32 * SZ_1K) ++#define TMU_DDR_DATA_BASEADDR (CLASS_DDR_DATA_BASEADDR + CLASS_DDR_DATA_SIZE) ++#define TMU_DDR_DATA_SIZE (32 * SZ_1K) ++#define TMU_LLM_BASEADDR (TMU_DDR_DATA_BASEADDR + TMU_DDR_DATA_SIZE) ++#define TMU_LLM_QUEUE_LEN (8 * 512) ++/* Must be power of two and at least 16 * 8 = 128 bytes */ ++#define TMU_LLM_SIZE (4 * 16 * TMU_LLM_QUEUE_LEN) ++/* (4 TMU's x 16 queues x queue_len) */ ++ ++#define DDR_MAX_SIZE (TMU_LLM_BASEADDR + TMU_LLM_SIZE) ++ ++/* LMEM Mapping */ ++#define BMU1_LMEM_BASEADDR 0 ++#define BMU1_BUF_COUNT 256 ++#define BMU1_LMEM_SIZE (LMEM_BUF_SIZE * BMU1_BUF_COUNT) ++ ++#endif /* _PFE_MOD_H */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_perfmon.h +@@ -0,0 +1,38 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _PFE_PERFMON_H_ ++#define _PFE_PERFMON_H_ ++ ++#include "pfe/pfe.h" ++ ++#define CT_CPUMON_INTERVAL (1 * TIMER_TICKS_PER_SEC) ++ ++struct pfe_cpumon { ++ u32 cpu_usage_pct[MAX_PE]; ++ u32 class_usage_pct; ++}; ++ ++struct pfe_memmon { ++ u32 kernel_memory_allocated; ++}; ++ ++int pfe_perfmon_init(struct pfe *pfe); ++void pfe_perfmon_exit(struct pfe *pfe); ++ ++#endif /* _PFE_PERFMON_H_ */ +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_sysfs.c +@@ -0,0 +1,818 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#include ++#include ++ ++#include "pfe_mod.h" ++ ++#define PE_EXCEPTION_DUMP_ADDRESS 0x1fa8 ++#define NUM_QUEUES 16 ++ ++static char register_name[20][5] = { ++ "EPC", "ECAS", "EID", "ED", ++ "r0", "r1", "r2", "r3", ++ "r4", "r5", "r6", "r7", ++ "r8", "r9", "r10", "r11", ++ "r12", "r13", "r14", "r15", ++}; ++ ++static char exception_name[14][20] = { ++ "Reset", ++ "HardwareFailure", ++ "NMI", ++ "InstBreakpoint", ++ "DataBreakpoint", ++ "Unsupported", ++ "PrivilegeViolation", ++ "InstBusError", ++ "DataBusError", ++ "AlignmentError", ++ "ArithmeticError", ++ "SystemCall", ++ "MemoryManagement", ++ "Interrupt", ++}; ++ ++static unsigned long class_do_clear; ++static unsigned long tmu_do_clear; ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++static unsigned long util_do_clear; ++#endif ++ ++static ssize_t display_pe_status(char *buf, int id, u32 dmem_addr, unsigned long ++ do_clear) ++{ ++ ssize_t len = 0; ++ u32 val; ++ char statebuf[5]; ++ struct pfe_cpumon *cpumon = &pfe->cpumon; ++ u32 debug_indicator; ++ u32 debug[20]; ++ ++ *(u32 *)statebuf = pe_dmem_read(id, dmem_addr, 4); ++ dmem_addr += 4; ++ ++ statebuf[4] = '\0'; ++ len += sprintf(buf + len, "state=%4s ", statebuf); ++ ++ val = pe_dmem_read(id, dmem_addr, 4); ++ dmem_addr += 4; ++ len += sprintf(buf + len, "ctr=%08x ", cpu_to_be32(val)); ++ ++ val = pe_dmem_read(id, dmem_addr, 4); ++ if (do_clear && val) ++ pe_dmem_write(id, 0, dmem_addr, 4); ++ dmem_addr += 4; ++ len += sprintf(buf + len, "rx=%u ", cpu_to_be32(val)); ++ ++ val = pe_dmem_read(id, dmem_addr, 4); ++ if (do_clear && val) ++ pe_dmem_write(id, 0, dmem_addr, 4); ++ dmem_addr += 4; ++ if (id >= TMU0_ID && id <= TMU_MAX_ID) ++ len += sprintf(buf + len, "qstatus=%x", cpu_to_be32(val)); ++ else ++ len += sprintf(buf + len, "tx=%u", cpu_to_be32(val)); ++ ++ val = pe_dmem_read(id, dmem_addr, 4); ++ if (do_clear && val) ++ pe_dmem_write(id, 0, dmem_addr, 4); ++ dmem_addr += 4; ++ if (val) ++ len += sprintf(buf + len, " drop=%u", cpu_to_be32(val)); ++ ++ len += sprintf(buf + len, " load=%d%%", cpumon->cpu_usage_pct[id]); ++ ++ len += sprintf(buf + len, "\n"); ++ ++ debug_indicator = pe_dmem_read(id, dmem_addr, 4); ++ dmem_addr += 4; ++ if (!strncmp((char *)&debug_indicator, "DBUG", 4)) { ++ int j, last = 0; ++ ++ for (j = 0; j < 16; j++) { ++ debug[j] = pe_dmem_read(id, dmem_addr, 4); ++ if (debug[j]) { ++ if (do_clear) ++ pe_dmem_write(id, 0, dmem_addr, 4); ++ last = j + 1; ++ } ++ dmem_addr += 4; ++ } ++ for (j = 0; j < last; j++) { ++ len += sprintf(buf + len, "%08x%s", ++ cpu_to_be32(debug[j]), ++ (j & 0x7) == 0x7 || j == last - 1 ? "\n" : " "); ++ } ++ } ++ ++ if (!strncmp(statebuf, "DEAD", 4)) { ++ u32 i, dump = PE_EXCEPTION_DUMP_ADDRESS; ++ ++ len += sprintf(buf + len, "Exception details:\n"); ++ for (i = 0; i < 20; i++) { ++ debug[i] = pe_dmem_read(id, dump, 4); ++ dump += 4; ++ if (i == 2) ++ len += sprintf(buf + len, "%4s = %08x (=%s) ", ++ register_name[i], cpu_to_be32(debug[i]), ++ exception_name[min((u32) ++ cpu_to_be32(debug[i]), (u32)13)]); ++ else ++ len += sprintf(buf + len, "%4s = %08x%s", ++ register_name[i], cpu_to_be32(debug[i]), ++ (i & 0x3) == 0x3 || i == 19 ? "\n" : " "); ++ } ++ } ++ ++ return len; ++} ++ ++static ssize_t class_phy_stats(char *buf, int phy) ++{ ++ ssize_t len = 0; ++ int off1 = phy * 0x28; ++ int off2 = phy * 0x10; ++ ++ if (phy == 3) ++ off1 = CLASS_PHY4_RX_PKTS - CLASS_PHY1_RX_PKTS; ++ ++ len += sprintf(buf + len, "phy: %d\n", phy); ++ len += sprintf(buf + len, ++ " rx: %10u, tx: %10u, intf: %10u, ipv4: %10u, ipv6: %10u\n", ++ readl(CLASS_PHY1_RX_PKTS + off1), ++ readl(CLASS_PHY1_TX_PKTS + off1), ++ readl(CLASS_PHY1_INTF_MATCH_PKTS + off1), ++ readl(CLASS_PHY1_V4_PKTS + off1), ++ readl(CLASS_PHY1_V6_PKTS + off1)); ++ ++ len += sprintf(buf + len, ++ " icmp: %10u, igmp: %10u, tcp: %10u, udp: %10u\n", ++ readl(CLASS_PHY1_ICMP_PKTS + off2), ++ readl(CLASS_PHY1_IGMP_PKTS + off2), ++ readl(CLASS_PHY1_TCP_PKTS + off2), ++ readl(CLASS_PHY1_UDP_PKTS + off2)); ++ ++ len += sprintf(buf + len, " err\n"); ++ len += sprintf(buf + len, ++ " lp: %10u, intf: %10u, l3: %10u, chcksum: %10u, ttl: %10u\n", ++ readl(CLASS_PHY1_LP_FAIL_PKTS + off1), ++ readl(CLASS_PHY1_INTF_FAIL_PKTS + off1), ++ readl(CLASS_PHY1_L3_FAIL_PKTS + off1), ++ readl(CLASS_PHY1_CHKSUM_ERR_PKTS + off1), ++ readl(CLASS_PHY1_TTL_ERR_PKTS + off1)); ++ ++ return len; ++} ++ ++/* qm_read_drop_stat ++ * This function is used to read the drop statistics from the TMU ++ * hw drop counter. Since the hw counter is always cleared afer ++ * reading, this function maintains the previous drop count, and ++ * adds the new value to it. That value can be retrieved by ++ * passing a pointer to it with the total_drops arg. ++ * ++ * @param tmu TMU number (0 - 3) ++ * @param queue queue number (0 - 15) ++ * @param total_drops pointer to location to store total drops (or NULL) ++ * @param do_reset if TRUE, clear total drops after updating ++ */ ++u32 qm_read_drop_stat(u32 tmu, u32 queue, u32 *total_drops, int do_reset) ++{ ++ static u32 qtotal[TMU_MAX_ID + 1][NUM_QUEUES]; ++ u32 val; ++ ++ writel((tmu << 8) | queue, TMU_TEQ_CTRL); ++ writel((tmu << 8) | queue, TMU_LLM_CTRL); ++ val = readl(TMU_TEQ_DROP_STAT); ++ qtotal[tmu][queue] += val; ++ if (total_drops) ++ *total_drops = qtotal[tmu][queue]; ++ if (do_reset) ++ qtotal[tmu][queue] = 0; ++ return val; ++} ++ ++static ssize_t tmu_queue_stats(char *buf, int tmu, int queue) ++{ ++ ssize_t len = 0; ++ u32 drops; ++ ++ len += sprintf(buf + len, "%d-%02d, ", tmu, queue); ++ ++ drops = qm_read_drop_stat(tmu, queue, NULL, 0); ++ ++ /* Select queue */ ++ writel((tmu << 8) | queue, TMU_TEQ_CTRL); ++ writel((tmu << 8) | queue, TMU_LLM_CTRL); ++ ++ len += sprintf(buf + len, ++ "(teq) drop: %10u, tx: %10u (llm) head: %08x, tail: %08x, drop: %10u\n", ++ drops, readl(TMU_TEQ_TRANS_STAT), ++ readl(TMU_LLM_QUE_HEADPTR), readl(TMU_LLM_QUE_TAILPTR), ++ readl(TMU_LLM_QUE_DROPCNT)); ++ ++ return len; ++} ++ ++static ssize_t tmu_queues(char *buf, int tmu) ++{ ++ ssize_t len = 0; ++ int queue; ++ ++ for (queue = 0; queue < 16; queue++) ++ len += tmu_queue_stats(buf + len, tmu, queue); ++ ++ return len; ++} ++ ++static ssize_t block_version(char *buf, void *addr) ++{ ++ ssize_t len = 0; ++ u32 val; ++ ++ val = readl(addr); ++ len += sprintf(buf + len, "revision: %x, version: %x, id: %x\n", ++ (val >> 24) & 0xff, (val >> 16) & 0xff, val & 0xffff); ++ ++ return len; ++} ++ ++static ssize_t bmu(char *buf, int id, void *base) ++{ ++ ssize_t len = 0; ++ ++ len += sprintf(buf + len, "%s: %d\n ", __func__, id); ++ ++ len += block_version(buf + len, base + BMU_VERSION); ++ ++ len += sprintf(buf + len, " buf size: %x\n", (1 << readl(base + ++ BMU_BUF_SIZE))); ++ len += sprintf(buf + len, " buf count: %x\n", readl(base + ++ BMU_BUF_CNT)); ++ len += sprintf(buf + len, " buf rem: %x\n", readl(base + ++ BMU_REM_BUF_CNT)); ++ len += sprintf(buf + len, " buf curr: %x\n", readl(base + ++ BMU_CURR_BUF_CNT)); ++ len += sprintf(buf + len, " free err: %x\n", readl(base + ++ BMU_FREE_ERR_ADDR)); ++ ++ return len; ++} ++ ++static ssize_t gpi(char *buf, int id, void *base) ++{ ++ ssize_t len = 0; ++ u32 val; ++ ++ len += sprintf(buf + len, "%s%d:\n ", __func__, id); ++ len += block_version(buf + len, base + GPI_VERSION); ++ ++ len += sprintf(buf + len, " tx under stick: %x\n", readl(base + ++ GPI_FIFO_STATUS)); ++ val = readl(base + GPI_FIFO_DEBUG); ++ len += sprintf(buf + len, " tx pkts: %x\n", (val >> 23) & ++ 0x3f); ++ len += sprintf(buf + len, " rx pkts: %x\n", (val >> 18) & ++ 0x3f); ++ len += sprintf(buf + len, " tx bytes: %x\n", (val >> 9) & ++ 0x1ff); ++ len += sprintf(buf + len, " rx bytes: %x\n", (val >> 0) & ++ 0x1ff); ++ len += sprintf(buf + len, " overrun: %x\n", readl(base + ++ GPI_OVERRUN_DROPCNT)); ++ ++ return len; ++} ++ ++static ssize_t pfe_set_class(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ class_do_clear = kstrtoul(buf, 0, 0); ++ return count; ++} ++ ++static ssize_t pfe_show_class(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ ssize_t len = 0; ++ int id; ++ u32 val; ++ struct pfe_cpumon *cpumon = &pfe->cpumon; ++ ++ len += block_version(buf + len, CLASS_VERSION); ++ ++ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) { ++ len += sprintf(buf + len, "%d: ", id - CLASS0_ID); ++ ++ val = readl(CLASS_PE0_DEBUG + id * 4); ++ len += sprintf(buf + len, "pc=1%04x ", val & 0xffff); ++ ++ len += display_pe_status(buf + len, id, CLASS_DM_PESTATUS, ++ class_do_clear); ++ } ++ len += sprintf(buf + len, "aggregate load=%d%%\n\n", ++ cpumon->class_usage_pct); ++ ++ len += sprintf(buf + len, "pe status: 0x%x\n", ++ readl(CLASS_PE_STATUS)); ++ len += sprintf(buf + len, "max buf cnt: 0x%x afull thres: 0x%x\n", ++ readl(CLASS_MAX_BUF_CNT), readl(CLASS_AFULL_THRES)); ++ len += sprintf(buf + len, "tsq max cnt: 0x%x tsq fifo thres: 0x%x\n", ++ readl(CLASS_TSQ_MAX_CNT), readl(CLASS_TSQ_FIFO_THRES)); ++ len += sprintf(buf + len, "state: 0x%x\n", readl(CLASS_STATE)); ++ ++ len += class_phy_stats(buf + len, 0); ++ len += class_phy_stats(buf + len, 1); ++ len += class_phy_stats(buf + len, 2); ++ len += class_phy_stats(buf + len, 3); ++ ++ return len; ++} ++ ++static ssize_t pfe_set_tmu(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ tmu_do_clear = kstrtoul(buf, 0, 0); ++ return count; ++} ++ ++static ssize_t pfe_show_tmu(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ ssize_t len = 0; ++ int id; ++ u32 val; ++ ++ len += block_version(buf + len, TMU_VERSION); ++ ++ for (id = TMU0_ID; id <= TMU_MAX_ID; id++) { ++ if (id == TMU2_ID) ++ continue; ++ len += sprintf(buf + len, "%d: ", id - TMU0_ID); ++ ++ len += display_pe_status(buf + len, id, TMU_DM_PESTATUS, ++ tmu_do_clear); ++ } ++ ++ len += sprintf(buf + len, "pe status: %x\n", readl(TMU_PE_STATUS)); ++ len += sprintf(buf + len, "inq fifo cnt: %x\n", ++ readl(TMU_PHY_INQ_FIFO_CNT)); ++ val = readl(TMU_INQ_STAT); ++ len += sprintf(buf + len, "inq wr ptr: %x\n", val & 0x3ff); ++ len += sprintf(buf + len, "inq rd ptr: %x\n", val >> 10); ++ ++ return len; ++} ++ ++static unsigned long drops_do_clear; ++static u32 class_drop_counter[CLASS_NUM_DROP_COUNTERS]; ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++static u32 util_drop_counter[UTIL_NUM_DROP_COUNTERS]; ++#endif ++ ++char *class_drop_description[CLASS_NUM_DROP_COUNTERS] = { ++ "ICC", ++ "Host Pkt Error", ++ "Rx Error", ++ "IPsec Outbound", ++ "IPsec Inbound", ++ "EXPT IPsec Error", ++ "Reassembly", ++ "Fragmenter", ++ "NAT-T", ++ "Socket", ++ "Multicast", ++ "NAT-PT", ++ "Tx Disabled", ++}; ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++char *util_drop_description[UTIL_NUM_DROP_COUNTERS] = { ++ "IPsec Outbound", ++ "IPsec Inbound", ++ "IPsec Rate Limiter", ++ "Fragmenter", ++ "Socket", ++ "Tx Disabled", ++ "Rx Error", ++}; ++#endif ++ ++static ssize_t pfe_set_drops(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ drops_do_clear = kstrtoul(buf, 0, 0); ++ return count; ++} ++ ++static u32 tmu_drops[4][16]; ++static ssize_t pfe_show_drops(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ ssize_t len = 0; ++ int id, dropnum; ++ int tmu, queue; ++ u32 val; ++ u32 dmem_addr; ++ int num_class_drops = 0, num_tmu_drops = 0, num_util_drops = 0; ++ struct pfe_ctrl *ctrl = &pfe->ctrl; ++ ++ memset(class_drop_counter, 0, sizeof(class_drop_counter)); ++ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) { ++ if (drops_do_clear) ++ pe_sync_stop(ctrl, (1 << id)); ++ for (dropnum = 0; dropnum < CLASS_NUM_DROP_COUNTERS; ++ dropnum++) { ++ dmem_addr = CLASS_DM_DROP_CNTR; ++ val = be32_to_cpu(pe_dmem_read(id, dmem_addr, 4)); ++ class_drop_counter[dropnum] += val; ++ num_class_drops += val; ++ if (drops_do_clear) ++ pe_dmem_write(id, 0, dmem_addr, 4); ++ } ++ if (drops_do_clear) ++ pe_start(ctrl, (1 << id)); ++ } ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ if (drops_do_clear) ++ pe_sync_stop(ctrl, (1 << UTIL_ID)); ++ for (dropnum = 0; dropnum < UTIL_NUM_DROP_COUNTERS; dropnum++) { ++ dmem_addr = UTIL_DM_DROP_CNTR; ++ val = be32_to_cpu(pe_dmem_read(UTIL_ID, dmem_addr, 4)); ++ util_drop_counter[dropnum] = val; ++ num_util_drops += val; ++ if (drops_do_clear) ++ pe_dmem_write(UTIL_ID, 0, dmem_addr, 4); ++ } ++ if (drops_do_clear) ++ pe_start(ctrl, (1 << UTIL_ID)); ++#endif ++ for (tmu = 0; tmu < 4; tmu++) { ++ for (queue = 0; queue < 16; queue++) { ++ qm_read_drop_stat(tmu, queue, &tmu_drops[tmu][queue], ++ drops_do_clear); ++ num_tmu_drops += tmu_drops[tmu][queue]; ++ } ++ } ++ ++ if (num_class_drops == 0 && num_util_drops == 0 && num_tmu_drops == 0) ++ len += sprintf(buf + len, "No PE drops\n\n"); ++ ++ if (num_class_drops > 0) { ++ len += sprintf(buf + len, "Class PE drops --\n"); ++ for (dropnum = 0; dropnum < CLASS_NUM_DROP_COUNTERS; ++ dropnum++) { ++ if (class_drop_counter[dropnum] > 0) ++ len += sprintf(buf + len, " %s: %d\n", ++ class_drop_description[dropnum], ++ class_drop_counter[dropnum]); ++ } ++ len += sprintf(buf + len, "\n"); ++ } ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ if (num_util_drops > 0) { ++ len += sprintf(buf + len, "Util PE drops --\n"); ++ for (dropnum = 0; dropnum < UTIL_NUM_DROP_COUNTERS; dropnum++) { ++ if (util_drop_counter[dropnum] > 0) ++ len += sprintf(buf + len, " %s: %d\n", ++ util_drop_description[dropnum], ++ util_drop_counter[dropnum]); ++ } ++ len += sprintf(buf + len, "\n"); ++ } ++#endif ++ if (num_tmu_drops > 0) { ++ len += sprintf(buf + len, "TMU drops --\n"); ++ for (tmu = 0; tmu < 4; tmu++) { ++ for (queue = 0; queue < 16; queue++) { ++ if (tmu_drops[tmu][queue] > 0) ++ len += sprintf(buf + len, ++ " TMU%d-Q%d: %d\n" ++ , tmu, queue, tmu_drops[tmu][queue]); ++ } ++ } ++ len += sprintf(buf + len, "\n"); ++ } ++ ++ return len; ++} ++ ++static ssize_t pfe_show_tmu0_queues(struct device *dev, struct device_attribute ++ *attr, char *buf) ++{ ++ return tmu_queues(buf, 0); ++} ++ ++static ssize_t pfe_show_tmu1_queues(struct device *dev, struct device_attribute ++ *attr, char *buf) ++{ ++ return tmu_queues(buf, 1); ++} ++ ++static ssize_t pfe_show_tmu2_queues(struct device *dev, struct device_attribute ++ *attr, char *buf) ++{ ++ return tmu_queues(buf, 2); ++} ++ ++static ssize_t pfe_show_tmu3_queues(struct device *dev, struct device_attribute ++ *attr, char *buf) ++{ ++ return tmu_queues(buf, 3); ++} ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++static ssize_t pfe_set_util(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ util_do_clear = kstrtoul(buf, NULL, 0); ++ return count; ++} ++ ++static ssize_t pfe_show_util(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ ssize_t len = 0; ++ struct pfe_ctrl *ctrl = &pfe->ctrl; ++ ++ len += block_version(buf + len, UTIL_VERSION); ++ ++ pe_sync_stop(ctrl, (1 << UTIL_ID)); ++ len += display_pe_status(buf + len, UTIL_ID, UTIL_DM_PESTATUS, ++ util_do_clear); ++ pe_start(ctrl, (1 << UTIL_ID)); ++ ++ len += sprintf(buf + len, "pe status: %x\n", readl(UTIL_PE_STATUS)); ++ len += sprintf(buf + len, "max buf cnt: %x\n", ++ readl(UTIL_MAX_BUF_CNT)); ++ len += sprintf(buf + len, "tsq max cnt: %x\n", ++ readl(UTIL_TSQ_MAX_CNT)); ++ ++ return len; ++} ++#endif ++ ++static ssize_t pfe_show_bmu(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ ssize_t len = 0; ++ ++ len += bmu(buf + len, 1, BMU1_BASE_ADDR); ++ len += bmu(buf + len, 2, BMU2_BASE_ADDR); ++ ++ return len; ++} ++ ++static ssize_t pfe_show_hif(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ ssize_t len = 0; ++ ++ len += sprintf(buf + len, "hif:\n "); ++ len += block_version(buf + len, HIF_VERSION); ++ ++ len += sprintf(buf + len, " tx curr bd: %x\n", ++ readl(HIF_TX_CURR_BD_ADDR)); ++ len += sprintf(buf + len, " tx status: %x\n", ++ readl(HIF_TX_STATUS)); ++ len += sprintf(buf + len, " tx dma status: %x\n", ++ readl(HIF_TX_DMA_STATUS)); ++ ++ len += sprintf(buf + len, " rx curr bd: %x\n", ++ readl(HIF_RX_CURR_BD_ADDR)); ++ len += sprintf(buf + len, " rx status: %x\n", ++ readl(HIF_RX_STATUS)); ++ len += sprintf(buf + len, " rx dma status: %x\n", ++ readl(HIF_RX_DMA_STATUS)); ++ ++ len += sprintf(buf + len, "hif nocopy:\n "); ++ len += block_version(buf + len, HIF_NOCPY_VERSION); ++ ++ len += sprintf(buf + len, " tx curr bd: %x\n", ++ readl(HIF_NOCPY_TX_CURR_BD_ADDR)); ++ len += sprintf(buf + len, " tx status: %x\n", ++ readl(HIF_NOCPY_TX_STATUS)); ++ len += sprintf(buf + len, " tx dma status: %x\n", ++ readl(HIF_NOCPY_TX_DMA_STATUS)); ++ ++ len += sprintf(buf + len, " rx curr bd: %x\n", ++ readl(HIF_NOCPY_RX_CURR_BD_ADDR)); ++ len += sprintf(buf + len, " rx status: %x\n", ++ readl(HIF_NOCPY_RX_STATUS)); ++ len += sprintf(buf + len, " rx dma status: %x\n", ++ readl(HIF_NOCPY_RX_DMA_STATUS)); ++ ++ return len; ++} ++ ++static ssize_t pfe_show_gpi(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ ssize_t len = 0; ++ ++ len += gpi(buf + len, 0, EGPI1_BASE_ADDR); ++ len += gpi(buf + len, 1, EGPI2_BASE_ADDR); ++ len += gpi(buf + len, 3, HGPI_BASE_ADDR); ++ ++ return len; ++} ++ ++static ssize_t pfe_show_pfemem(struct device *dev, struct device_attribute ++ *attr, char *buf) ++{ ++ ssize_t len = 0; ++ struct pfe_memmon *memmon = &pfe->memmon; ++ ++ len += sprintf(buf + len, "Kernel Memory: %d Bytes (%d KB)\n", ++ memmon->kernel_memory_allocated, ++ (memmon->kernel_memory_allocated + 1023) / 1024); ++ ++ return len; ++} ++ ++#ifdef HIF_NAPI_STATS ++static ssize_t pfe_show_hif_napi_stats(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct pfe *pfe = platform_get_drvdata(pdev); ++ ssize_t len = 0; ++ ++ len += sprintf(buf + len, "sched: %u\n", ++ pfe->hif.napi_counters[NAPI_SCHED_COUNT]); ++ len += sprintf(buf + len, "poll: %u\n", ++ pfe->hif.napi_counters[NAPI_POLL_COUNT]); ++ len += sprintf(buf + len, "packet: %u\n", ++ pfe->hif.napi_counters[NAPI_PACKET_COUNT]); ++ len += sprintf(buf + len, "budget: %u\n", ++ pfe->hif.napi_counters[NAPI_FULL_BUDGET_COUNT]); ++ len += sprintf(buf + len, "desc: %u\n", ++ pfe->hif.napi_counters[NAPI_DESC_COUNT]); ++ len += sprintf(buf + len, "full: %u\n", ++ pfe->hif.napi_counters[NAPI_CLIENT_FULL_COUNT]); ++ ++ return len; ++} ++ ++static ssize_t pfe_set_hif_napi_stats(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct pfe *pfe = platform_get_drvdata(pdev); ++ ++ memset(pfe->hif.napi_counters, 0, sizeof(pfe->hif.napi_counters)); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(hif_napi_stats, 0644, pfe_show_hif_napi_stats, ++ pfe_set_hif_napi_stats); ++#endif ++ ++static DEVICE_ATTR(class, 0644, pfe_show_class, pfe_set_class); ++static DEVICE_ATTR(tmu, 0644, pfe_show_tmu, pfe_set_tmu); ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++static DEVICE_ATTR(util, 0644, pfe_show_util, pfe_set_util); ++#endif ++static DEVICE_ATTR(bmu, 0444, pfe_show_bmu, NULL); ++static DEVICE_ATTR(hif, 0444, pfe_show_hif, NULL); ++static DEVICE_ATTR(gpi, 0444, pfe_show_gpi, NULL); ++static DEVICE_ATTR(drops, 0644, pfe_show_drops, pfe_set_drops); ++static DEVICE_ATTR(tmu0_queues, 0444, pfe_show_tmu0_queues, NULL); ++static DEVICE_ATTR(tmu1_queues, 0444, pfe_show_tmu1_queues, NULL); ++static DEVICE_ATTR(tmu2_queues, 0444, pfe_show_tmu2_queues, NULL); ++static DEVICE_ATTR(tmu3_queues, 0444, pfe_show_tmu3_queues, NULL); ++static DEVICE_ATTR(pfemem, 0444, pfe_show_pfemem, NULL); ++ ++int pfe_sysfs_init(struct pfe *pfe) ++{ ++ if (device_create_file(pfe->dev, &dev_attr_class)) ++ goto err_class; ++ ++ if (device_create_file(pfe->dev, &dev_attr_tmu)) ++ goto err_tmu; ++ ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ if (device_create_file(pfe->dev, &dev_attr_util)) ++ goto err_util; ++#endif ++ ++ if (device_create_file(pfe->dev, &dev_attr_bmu)) ++ goto err_bmu; ++ ++ if (device_create_file(pfe->dev, &dev_attr_hif)) ++ goto err_hif; ++ ++ if (device_create_file(pfe->dev, &dev_attr_gpi)) ++ goto err_gpi; ++ ++ if (device_create_file(pfe->dev, &dev_attr_drops)) ++ goto err_drops; ++ ++ if (device_create_file(pfe->dev, &dev_attr_tmu0_queues)) ++ goto err_tmu0_queues; ++ ++ if (device_create_file(pfe->dev, &dev_attr_tmu1_queues)) ++ goto err_tmu1_queues; ++ ++ if (device_create_file(pfe->dev, &dev_attr_tmu2_queues)) ++ goto err_tmu2_queues; ++ ++ if (device_create_file(pfe->dev, &dev_attr_tmu3_queues)) ++ goto err_tmu3_queues; ++ ++ if (device_create_file(pfe->dev, &dev_attr_pfemem)) ++ goto err_pfemem; ++ ++#ifdef HIF_NAPI_STATS ++ if (device_create_file(pfe->dev, &dev_attr_hif_napi_stats)) ++ goto err_hif_napi_stats; ++#endif ++ ++ return 0; ++ ++#ifdef HIF_NAPI_STATS ++err_hif_napi_stats: ++ device_remove_file(pfe->dev, &dev_attr_pfemem); ++#endif ++ ++err_pfemem: ++ device_remove_file(pfe->dev, &dev_attr_tmu3_queues); ++ ++err_tmu3_queues: ++ device_remove_file(pfe->dev, &dev_attr_tmu2_queues); ++ ++err_tmu2_queues: ++ device_remove_file(pfe->dev, &dev_attr_tmu1_queues); ++ ++err_tmu1_queues: ++ device_remove_file(pfe->dev, &dev_attr_tmu0_queues); ++ ++err_tmu0_queues: ++ device_remove_file(pfe->dev, &dev_attr_drops); ++ ++err_drops: ++ device_remove_file(pfe->dev, &dev_attr_gpi); ++ ++err_gpi: ++ device_remove_file(pfe->dev, &dev_attr_hif); ++ ++err_hif: ++ device_remove_file(pfe->dev, &dev_attr_bmu); ++ ++err_bmu: ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ device_remove_file(pfe->dev, &dev_attr_util); ++ ++err_util: ++#endif ++ device_remove_file(pfe->dev, &dev_attr_tmu); ++ ++err_tmu: ++ device_remove_file(pfe->dev, &dev_attr_class); ++ ++err_class: ++ return -1; ++} ++ ++void pfe_sysfs_exit(struct pfe *pfe) ++{ ++#ifdef HIF_NAPI_STATS ++ device_remove_file(pfe->dev, &dev_attr_hif_napi_stats); ++#endif ++ device_remove_file(pfe->dev, &dev_attr_pfemem); ++ device_remove_file(pfe->dev, &dev_attr_tmu3_queues); ++ device_remove_file(pfe->dev, &dev_attr_tmu2_queues); ++ device_remove_file(pfe->dev, &dev_attr_tmu1_queues); ++ device_remove_file(pfe->dev, &dev_attr_tmu0_queues); ++ device_remove_file(pfe->dev, &dev_attr_drops); ++ device_remove_file(pfe->dev, &dev_attr_gpi); ++ device_remove_file(pfe->dev, &dev_attr_hif); ++ device_remove_file(pfe->dev, &dev_attr_bmu); ++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) ++ device_remove_file(pfe->dev, &dev_attr_util); ++#endif ++ device_remove_file(pfe->dev, &dev_attr_tmu); ++ device_remove_file(pfe->dev, &dev_attr_class); ++} +--- /dev/null ++++ b/drivers/staging/fsl_ppfe/pfe_sysfs.h +@@ -0,0 +1,29 @@ ++/* ++ * Copyright 2015-2016 Freescale Semiconductor, Inc. ++ * Copyright 2017 NXP ++ * ++ * 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, see . ++ */ ++ ++#ifndef _PFE_SYSFS_H_ ++#define _PFE_SYSFS_H_ ++ ++#include ++ ++u32 qm_read_drop_stat(u32 tmu, u32 queue, u32 *total_drops, int do_reset); ++ ++int pfe_sysfs_init(struct pfe *pfe); ++void pfe_sysfs_exit(struct pfe *pfe); ++ ++#endif /* _PFE_SYSFS_H_ */ diff --git a/target/linux/layerscape/patches-4.9/804-crypto-support-layerscape.patch b/target/linux/layerscape/patches-4.9/804-crypto-support-layerscape.patch index 79103a273..f6a7bca7c 100644 --- a/target/linux/layerscape/patches-4.9/804-crypto-support-layerscape.patch +++ b/target/linux/layerscape/patches-4.9/804-crypto-support-layerscape.patch @@ -1,4 +1,4 @@ -From 0a5b97d1f524c1769b4059e3c7123b52755f7121 Mon Sep 17 00:00:00 2001 +From 9c9579d76ccd6e738ab98c9b4c73c168912cdb8a Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Wed, 27 Sep 2017 15:02:01 +0800 Subject: [PATCH] crypto: support layerscape @@ -54,7 +54,7 @@ Signed-off-by: Yangbo Lu drivers/crypto/caam/compat.h | 1 + drivers/crypto/caam/ctrl.c | 356 +- drivers/crypto/caam/ctrl.h | 2 + - drivers/crypto/caam/desc.h | 52 +- + drivers/crypto/caam/desc.h | 55 +- drivers/crypto/caam/desc_constr.h | 139 +- drivers/crypto/caam/dpseci.c | 859 ++++ drivers/crypto/caam/dpseci.h | 395 ++ @@ -62,7 +62,8 @@ Signed-off-by: Yangbo Lu drivers/crypto/caam/error.c | 127 +- drivers/crypto/caam/error.h | 10 +- drivers/crypto/caam/intern.h | 31 +- - drivers/crypto/caam/jr.c | 55 +- + drivers/crypto/caam/jr.c | 97 +- + drivers/crypto/caam/jr.h | 2 + drivers/crypto/caam/key_gen.c | 32 +- drivers/crypto/caam/key_gen.h | 36 +- drivers/crypto/caam/pdb.h | 62 + @@ -83,7 +84,7 @@ Signed-off-by: Yangbo Lu include/uapi/linux/cryptouser.h | 5 + scripts/spelling.txt | 3 + sound/soc/amd/acp-pcm-dma.c | 2 +- - 54 files changed, 17263 insertions(+), 3955 deletions(-) + 55 files changed, 17310 insertions(+), 3955 deletions(-) create mode 100644 crypto/acompress.c create mode 100644 crypto/scompress.c create mode 100644 crypto/tls.c @@ -15259,9 +15260,9 @@ Signed-off-by: Yangbo Lu +} + +/* -+ * qi_cache_alloc - Allocate buffers from CAAM-QI cache ++ * qi_cache_zalloc - Allocate buffers from CAAM-QI cache + * -+ * Allocate data on the hotpath. Instead of using kmalloc, one can use the ++ * Allocate data on the hotpath. Instead of using kzalloc, one can use the + * services of the CAAM QI memory cache (backed by kmem_cache). The buffers + * will have a size of CAAM_QI_MEMCACHE_SIZE, which should be sufficient for + * hosting 16 SG entries. @@ -15270,15 +15271,15 @@ Signed-off-by: Yangbo Lu + * + * Returns a pointer to a retrieved buffer on success or NULL on failure. + */ -+static inline void *qi_cache_alloc(gfp_t flags) ++static inline void *qi_cache_zalloc(gfp_t flags) +{ -+ return kmem_cache_alloc(qi_cache, flags); ++ return kmem_cache_zalloc(qi_cache, flags); +} + +/* + * qi_cache_free - Frees buffers allocated from CAAM-QI cache + * -+ * @obj - buffer previously allocated by qi_cache_alloc ++ * @obj - buffer previously allocated by qi_cache_zalloc + * + * No checking is being done, the call is a passthrough call to + * kmem_cache_free(...) @@ -15690,7 +15691,7 @@ Signed-off-by: Yangbo Lu + enum optype op_type = encrypt ? ENCRYPT : DECRYPT; + + /* allocate space for base edesc and link tables */ -+ edesc = qi_cache_alloc(GFP_DMA | flags); ++ edesc = qi_cache_zalloc(GFP_DMA | flags); + if (unlikely(!edesc)) { + dev_err(dev, "could not allocate extended descriptor\n"); + return ERR_PTR(-ENOMEM); @@ -15895,7 +15896,7 @@ Signed-off-by: Yangbo Lu + } + + /* allocate space for base edesc and link tables */ -+ edesc = qi_cache_alloc(GFP_DMA | flags); ++ edesc = qi_cache_zalloc(GFP_DMA | flags); + if (unlikely(!edesc)) { + dev_err(dev, "could not allocate extended descriptor\n"); + return ERR_PTR(-ENOMEM); @@ -16761,7 +16762,7 @@ Signed-off-by: Yangbo Lu + } + + /* allocate space for base edesc and link tables */ -+ edesc = qi_cache_alloc(GFP_DMA | flags); ++ edesc = qi_cache_zalloc(GFP_DMA | flags); + if (unlikely(!edesc)) { + dev_err(dev, "could not allocate extended descriptor\n"); + caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, @@ -16916,7 +16917,7 @@ Signed-off-by: Yangbo Lu + } + + /* allocate space for base edesc and link tables */ -+ edesc = qi_cache_alloc(GFP_DMA | flags); ++ edesc = qi_cache_zalloc(GFP_DMA | flags); + if (!edesc) { + dev_err(dev, "could not allocate extended descriptor\n"); + caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, @@ -22122,7 +22123,15 @@ Signed-off-by: Yangbo Lu #define LDST_SRCDST_WORD_ALTDS_CLASS1 (0x0f << LDST_SRCDST_SHIFT) #define LDST_SRCDST_WORD_PKHA_A_SZ (0x10 << LDST_SRCDST_SHIFT) #define LDST_SRCDST_WORD_PKHA_B_SZ (0x11 << LDST_SRCDST_SHIFT) -@@ -400,7 +395,7 @@ struct sec4_sg_entry { +@@ -360,6 +355,7 @@ struct sec4_sg_entry { + #define FIFOLD_TYPE_PK_N (0x08 << FIFOLD_TYPE_SHIFT) + #define FIFOLD_TYPE_PK_A (0x0c << FIFOLD_TYPE_SHIFT) + #define FIFOLD_TYPE_PK_B (0x0d << FIFOLD_TYPE_SHIFT) ++#define FIFOLD_TYPE_IFIFO (0x0f << FIFOLD_TYPE_SHIFT) + + /* Other types. Need to OR in last/flush bits as desired */ + #define FIFOLD_TYPE_MSG_MASK (0x38 << FIFOLD_TYPE_SHIFT) +@@ -400,7 +396,7 @@ struct sec4_sg_entry { #define FIFOST_TYPE_PKHA_N (0x08 << FIFOST_TYPE_SHIFT) #define FIFOST_TYPE_PKHA_A (0x0c << FIFOST_TYPE_SHIFT) #define FIFOST_TYPE_PKHA_B (0x0d << FIFOST_TYPE_SHIFT) @@ -22131,7 +22140,15 @@ Signed-off-by: Yangbo Lu #define FIFOST_TYPE_AF_SBOX_TKEK (0x21 << FIFOST_TYPE_SHIFT) #define FIFOST_TYPE_PKHA_E_JKEK (0x22 << FIFOST_TYPE_SHIFT) #define FIFOST_TYPE_PKHA_E_TKEK (0x23 << FIFOST_TYPE_SHIFT) -@@ -1107,8 +1102,8 @@ struct sec4_sg_entry { +@@ -413,6 +409,7 @@ struct sec4_sg_entry { + #define FIFOST_TYPE_MESSAGE_DATA (0x30 << FIFOST_TYPE_SHIFT) + #define FIFOST_TYPE_RNGSTORE (0x34 << FIFOST_TYPE_SHIFT) + #define FIFOST_TYPE_RNGFIFO (0x35 << FIFOST_TYPE_SHIFT) ++#define FIFOST_TYPE_METADATA (0x3e << FIFOST_TYPE_SHIFT) + #define FIFOST_TYPE_SKIP (0x3f << FIFOST_TYPE_SHIFT) + + /* +@@ -1107,8 +1104,8 @@ struct sec4_sg_entry { /* For non-protocol/alg-only op commands */ #define OP_ALG_TYPE_SHIFT 24 #define OP_ALG_TYPE_MASK (0x7 << OP_ALG_TYPE_SHIFT) @@ -22142,7 +22159,7 @@ Signed-off-by: Yangbo Lu #define OP_ALG_ALGSEL_SHIFT 16 #define OP_ALG_ALGSEL_MASK (0xff << OP_ALG_ALGSEL_SHIFT) -@@ -1249,7 +1244,7 @@ struct sec4_sg_entry { +@@ -1249,7 +1246,7 @@ struct sec4_sg_entry { #define OP_ALG_PKMODE_MOD_PRIMALITY 0x00f /* PKHA mode copy-memory functions */ @@ -22151,7 +22168,7 @@ Signed-off-by: Yangbo Lu #define OP_ALG_PKMODE_SRC_REG_MASK (7 << OP_ALG_PKMODE_SRC_REG_SHIFT) #define OP_ALG_PKMODE_DST_REG_SHIFT 10 #define OP_ALG_PKMODE_DST_REG_MASK (7 << OP_ALG_PKMODE_DST_REG_SHIFT) -@@ -1445,7 +1440,7 @@ struct sec4_sg_entry { +@@ -1445,10 +1442,11 @@ struct sec4_sg_entry { #define MATH_SRC1_REG2 (0x02 << MATH_SRC1_SHIFT) #define MATH_SRC1_REG3 (0x03 << MATH_SRC1_SHIFT) #define MATH_SRC1_IMM (0x04 << MATH_SRC1_SHIFT) @@ -22160,7 +22177,11 @@ Signed-off-by: Yangbo Lu #define MATH_SRC1_INFIFO (0x0a << MATH_SRC1_SHIFT) #define MATH_SRC1_OUTFIFO (0x0b << MATH_SRC1_SHIFT) #define MATH_SRC1_ONE (0x0c << MATH_SRC1_SHIFT) -@@ -1629,4 +1624,31 @@ struct sec4_sg_entry { ++#define MATH_SRC1_ZERO (0x0f << MATH_SRC1_SHIFT) + + /* Destination selectors */ + #define MATH_DEST_SHIFT 8 +@@ -1629,4 +1627,31 @@ struct sec4_sg_entry { /* Frame Descriptor Command for Replacement Job Descriptor */ #define FD_CMD_REPLACE_JOB_DESC 0x20000000 @@ -24327,7 +24348,22 @@ Signed-off-by: Yangbo Lu #include "regs.h" #include "jr.h" #include "desc.h" -@@ -73,6 +74,8 @@ static int caam_jr_shutdown(struct devic +@@ -22,6 +23,14 @@ struct jr_driver_data { + + static struct jr_driver_data driver_data; + ++static int jr_driver_probed; ++ ++int caam_jr_driver_probed(void) ++{ ++ return jr_driver_probed; ++} ++EXPORT_SYMBOL(caam_jr_driver_probed); ++ + static int caam_reset_hw_jr(struct device *dev) + { + struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); +@@ -73,6 +82,8 @@ static int caam_jr_shutdown(struct devic ret = caam_reset_hw_jr(dev); @@ -24336,7 +24372,16 @@ Signed-off-by: Yangbo Lu /* Release interrupt */ free_irq(jrp->irq, dev); -@@ -128,7 +131,7 @@ static irqreturn_t caam_jr_interrupt(int +@@ -116,6 +127,8 @@ static int caam_jr_remove(struct platfor + dev_err(jrdev, "Failed to shut down job ring\n"); + irq_dispose_mapping(jrpriv->irq); + ++ jr_driver_probed--; ++ + return ret; + } + +@@ -128,7 +141,7 @@ static irqreturn_t caam_jr_interrupt(int /* * Check the output ring for ready responses, kick @@ -24345,7 +24390,7 @@ Signed-off-by: Yangbo Lu */ irqstate = rd_reg32(&jrp->rregs->jrintstatus); if (!irqstate) -@@ -150,13 +153,18 @@ static irqreturn_t caam_jr_interrupt(int +@@ -150,13 +163,18 @@ static irqreturn_t caam_jr_interrupt(int /* Have valid interrupt at this point, just ACK and trigger */ wr_reg32(&jrp->rregs->jrintstatus, irqstate); @@ -24367,7 +24412,7 @@ Signed-off-by: Yangbo Lu struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); void (*usercall)(struct device *dev, u32 *desc, u32 status, void *arg); u32 *userdesc, userstatus; -@@ -230,8 +238,6 @@ static irqreturn_t caam_jr_threadirq(int +@@ -230,8 +248,6 @@ static irqreturn_t caam_jr_threadirq(int /* reenable / unmask IRQs */ clrsetbits_32(&jrp->rregs->rconfig_lo, JRCFG_IMSK, 0); @@ -24376,7 +24421,44 @@ Signed-off-by: Yangbo Lu } /** -@@ -389,10 +395,11 @@ static int caam_jr_init(struct device *d +@@ -275,6 +291,36 @@ struct device *caam_jr_alloc(void) + EXPORT_SYMBOL(caam_jr_alloc); + + /** ++ * caam_jridx_alloc() - Alloc a specific job ring based on its index. ++ * ++ * returns : pointer to the newly allocated physical ++ * JobR dev can be written to if successful. ++ **/ ++struct device *caam_jridx_alloc(int idx) ++{ ++ struct caam_drv_private_jr *jrpriv; ++ struct device *dev = ERR_PTR(-ENODEV); ++ ++ spin_lock(&driver_data.jr_alloc_lock); ++ ++ if (list_empty(&driver_data.jr_list)) ++ goto end; ++ ++ list_for_each_entry(jrpriv, &driver_data.jr_list, list_node) { ++ if (jrpriv->ridx == idx) { ++ atomic_inc(&jrpriv->tfm_count); ++ dev = jrpriv->dev; ++ break; ++ } ++ } ++ ++end: ++ spin_unlock(&driver_data.jr_alloc_lock); ++ return dev; ++} ++EXPORT_SYMBOL(caam_jridx_alloc); ++ ++/** + * caam_jr_free() - Free the Job Ring + * @rdev - points to the dev that identifies the Job ring to + * be released. +@@ -389,10 +435,11 @@ static int caam_jr_init(struct device *d jrp = dev_get_drvdata(dev); @@ -24391,7 +24473,7 @@ Signed-off-by: Yangbo Lu if (error) { dev_err(dev, "can't connect JobR %d interrupt (%d)\n", jrp->ridx, jrp->irq); -@@ -454,6 +461,7 @@ out_free_inpring: +@@ -454,6 +501,7 @@ out_free_inpring: out_free_irq: free_irq(jrp->irq, dev); out_kill_deq: @@ -24399,7 +24481,7 @@ Signed-off-by: Yangbo Lu return error; } -@@ -489,15 +497,28 @@ static int caam_jr_probe(struct platform +@@ -489,15 +537,28 @@ static int caam_jr_probe(struct platform return -ENOMEM; } @@ -24435,7 +24517,12 @@ Signed-off-by: Yangbo Lu /* Identify the interrupt */ jrpriv->irq = irq_of_parse_and_map(nprop, 0); -@@ -520,7 +541,7 @@ static int caam_jr_probe(struct platform +@@ -517,10 +578,12 @@ static int caam_jr_probe(struct platform + + atomic_set(&jrpriv->tfm_count, 0); + ++ jr_driver_probed++; ++ return 0; } @@ -24444,6 +24531,18 @@ Signed-off-by: Yangbo Lu { .compatible = "fsl,sec-v4.0-job-ring", }, +--- a/drivers/crypto/caam/jr.h ++++ b/drivers/crypto/caam/jr.h +@@ -8,7 +8,9 @@ + #define JR_H + + /* Prototypes for backend-level services exposed to APIs */ ++int caam_jr_driver_probed(void); + struct device *caam_jr_alloc(void); ++struct device *caam_jridx_alloc(int idx); + void caam_jr_free(struct device *rdev); + int caam_jr_enqueue(struct device *dev, u32 *desc, + void (*cbk)(struct device *dev, u32 *desc, u32 status, --- a/drivers/crypto/caam/key_gen.c +++ b/drivers/crypto/caam/key_gen.c @@ -41,15 +41,29 @@ Split key generation-------------------- diff --git a/target/linux/layerscape/patches-4.9/805-dma-support-layerscape.patch b/target/linux/layerscape/patches-4.9/805-dma-support-layerscape.patch index 703aeed3e..94f0a3444 100644 --- a/target/linux/layerscape/patches-4.9/805-dma-support-layerscape.patch +++ b/target/linux/layerscape/patches-4.9/805-dma-support-layerscape.patch @@ -1,4 +1,4 @@ -From 659603c5f6cbc3d39922d4374df25ae4627d0e88 Mon Sep 17 00:00:00 2001 +From 854c1f0e9574e9b25a55b439608c71e013b34a56 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Mon, 25 Sep 2017 12:12:20 +0800 Subject: [PATCH] dma: support layerscape @@ -8,8 +8,9 @@ This is a integrated patch for layerscape dma support. Signed-off-by: jiaheng.fan Signed-off-by: Yangbo Lu --- - drivers/dma/Kconfig | 14 + - drivers/dma/Makefile | 2 + + drivers/dma/Kconfig | 31 + + drivers/dma/Makefile | 3 + + drivers/dma/caam_dma.c | 563 +++++++++++++++ drivers/dma/dpaa2-qdma/Kconfig | 8 + drivers/dma/dpaa2-qdma/Makefile | 8 + drivers/dma/dpaa2-qdma/dpaa2-qdma.c | 986 +++++++++++++++++++++++++ @@ -18,7 +19,8 @@ Signed-off-by: Yangbo Lu drivers/dma/dpaa2-qdma/fsl_dpdmai.h | 521 ++++++++++++++ drivers/dma/dpaa2-qdma/fsl_dpdmai_cmd.h | 222 ++++++ drivers/dma/fsl-qdma.c | 1201 +++++++++++++++++++++++++++++++ - 10 files changed, 3678 insertions(+) + 11 files changed, 4259 insertions(+) + create mode 100644 drivers/dma/caam_dma.c create mode 100644 drivers/dma/dpaa2-qdma/Kconfig create mode 100644 drivers/dma/dpaa2-qdma/Makefile create mode 100644 drivers/dma/dpaa2-qdma/dpaa2-qdma.c @@ -51,6 +53,30 @@ Signed-off-by: Yangbo Lu config FSL_RAID tristate "Freescale RAID engine Support" depends on FSL_SOC && !ASYNC_TX_ENABLE_CHANNEL_SWITCH +@@ -564,6 +578,23 @@ config ZX_DMA + help + Support the DMA engine for ZTE ZX296702 platform devices. + ++config CRYPTO_DEV_FSL_CAAM_DMA ++ tristate "CAAM DMA engine support" ++ depends on CRYPTO_DEV_FSL_CAAM_JR ++ default y ++ select DMA_ENGINE ++ select ASYNC_CORE ++ select ASYNC_TX_ENABLE_CHANNEL_SWITCH ++ help ++ Selecting this will offload the DMA operations for users of ++ the scatter gather memcopy API to the CAAM via job rings. The ++ CAAM is a hardware module that provides hardware acceleration to ++ cryptographic operations. It has a built-in DMA controller that can ++ be programmed to read/write cryptographic data. This module defines ++ a DMA driver that uses the DMA capabilities of the CAAM. ++ ++ To compile this as a module, choose M here: the module ++ will be called caam_dma. + + # driver files + source "drivers/dma/bestcomm/Kconfig" --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -29,6 +29,8 @@ obj-$(CONFIG_DW_DMAC_CORE) += dw/ @@ -62,6 +88,580 @@ Signed-off-by: Yangbo Lu obj-$(CONFIG_FSL_RAID) += fsl_raid.o obj-$(CONFIG_HSU_DMA) += hsu/ obj-$(CONFIG_IMG_MDC_DMA) += img-mdc-dma.o +@@ -67,6 +69,7 @@ obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma- + obj-$(CONFIG_TI_EDMA) += edma.o + obj-$(CONFIG_XGENE_DMA) += xgene-dma.o + obj-$(CONFIG_ZX_DMA) += zx296702_dma.o ++obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_DMA) += caam_dma.o + + obj-y += qcom/ + obj-y += xilinx/ +--- /dev/null ++++ b/drivers/dma/caam_dma.c +@@ -0,0 +1,563 @@ ++/* ++ * caam support for SG DMA ++ * ++ * Copyright 2016 Freescale Semiconductor, Inc ++ * Copyright 2017 NXP ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "dmaengine.h" ++ ++#include "../crypto/caam/regs.h" ++#include "../crypto/caam/jr.h" ++#include "../crypto/caam/error.h" ++#include "../crypto/caam/intern.h" ++#include "../crypto/caam/desc_constr.h" ++#include "../crypto/caam/sg_sw_sec4.h" ++ ++#define DESC_DMA_MEMCPY_LEN ((CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN) / \ ++ CAAM_CMD_SZ) ++ ++/* This is max chunk size of a DMA transfer. If a buffer is larger than this ++ * value it is internally broken into chunks of max CAAM_DMA_CHUNK_SIZE bytes ++ * and for each chunk a DMA transfer request is issued. ++ * This value is the largest number on 16 bits that is a multiple of 256 bytes ++ * (the largest configurable CAAM DMA burst size). ++ */ ++#define CAAM_DMA_CHUNK_SIZE 65280 ++ ++struct caam_dma_sh_desc { ++ u32 desc[DESC_DMA_MEMCPY_LEN] ____cacheline_aligned; ++ dma_addr_t desc_dma; ++}; ++ ++/* caam dma extended descriptor */ ++struct caam_dma_edesc { ++ struct dma_async_tx_descriptor async_tx; ++ struct list_head node; ++ struct caam_dma_ctx *ctx; ++ dma_addr_t src_dma; ++ dma_addr_t dst_dma; ++ unsigned int src_len; ++ unsigned int dst_len; ++ struct sec4_sg_entry *sec4_sg; ++ u32 jd[] ____cacheline_aligned; ++}; ++ ++/* ++ * caam_dma_ctx - per jr/channel context ++ * @chan: dma channel used by async_tx API ++ * @node: list_head used to attach to the global dma_ctx_list ++ * @jrdev: Job Ring device ++ * @submit_q: queue of pending (submitted, but not enqueued) jobs ++ * @done_not_acked: jobs that have been completed by jr, but maybe not acked ++ * @edesc_lock: protects extended descriptor ++ */ ++struct caam_dma_ctx { ++ struct dma_chan chan; ++ struct list_head node; ++ struct device *jrdev; ++ struct list_head submit_q; ++ struct list_head done_not_acked; ++ spinlock_t edesc_lock; ++}; ++ ++static struct dma_device *dma_dev; ++static struct caam_dma_sh_desc *dma_sh_desc; ++static LIST_HEAD(dma_ctx_list); ++ ++static dma_cookie_t caam_dma_tx_submit(struct dma_async_tx_descriptor *tx) ++{ ++ struct caam_dma_edesc *edesc = NULL; ++ struct caam_dma_ctx *ctx = NULL; ++ dma_cookie_t cookie; ++ ++ edesc = container_of(tx, struct caam_dma_edesc, async_tx); ++ ctx = container_of(tx->chan, struct caam_dma_ctx, chan); ++ ++ spin_lock_bh(&ctx->edesc_lock); ++ ++ cookie = dma_cookie_assign(tx); ++ list_add_tail(&edesc->node, &ctx->submit_q); ++ ++ spin_unlock_bh(&ctx->edesc_lock); ++ ++ return cookie; ++} ++ ++static unsigned int caam_dma_sg_dma_len(struct scatterlist *sg, ++ unsigned int nents) ++{ ++ unsigned int len; ++ ++ for (len = 0; sg && nents; sg = sg_next(sg), nents--) ++ len += sg_dma_len(sg); ++ ++ return len; ++} ++ ++static struct caam_dma_edesc * ++caam_dma_sg_edesc_alloc(struct dma_chan *chan, ++ struct scatterlist *dst_sg, unsigned int dst_nents, ++ struct scatterlist *src_sg, unsigned int src_nents, ++ unsigned long flags) ++{ ++ struct caam_dma_ctx *ctx = container_of(chan, struct caam_dma_ctx, ++ chan); ++ struct device *jrdev = ctx->jrdev; ++ struct caam_dma_edesc *edesc; ++ struct sec4_sg_entry *sec4_sg; ++ dma_addr_t sec4_sg_dma_src; ++ unsigned int sec4_sg_bytes; ++ ++ if (!dst_sg || !src_sg || !dst_nents || !src_nents) ++ return NULL; ++ ++ sec4_sg_bytes = (src_nents + dst_nents) * sizeof(*sec4_sg); ++ ++ edesc = kzalloc(sizeof(*edesc) + DESC_JOB_IO_LEN + sec4_sg_bytes, ++ GFP_DMA | GFP_NOWAIT); ++ if (!edesc) ++ return ERR_PTR(-ENOMEM); ++ ++ edesc->src_len = caam_dma_sg_dma_len(src_sg, src_nents); ++ edesc->dst_len = caam_dma_sg_dma_len(dst_sg, dst_nents); ++ if (edesc->src_len != edesc->dst_len) { ++ dev_err(jrdev, "%s: src(%u) and dst(%u) len mismatch.\n", ++ __func__, edesc->src_len, edesc->dst_len); ++ kfree(edesc); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ dma_async_tx_descriptor_init(&edesc->async_tx, chan); ++ edesc->async_tx.tx_submit = caam_dma_tx_submit; ++ edesc->async_tx.flags = flags; ++ edesc->async_tx.cookie = -EBUSY; ++ ++ /* Prepare SEC SGs */ ++ edesc->sec4_sg = (void *)edesc + offsetof(struct caam_dma_edesc, jd) + ++ DESC_JOB_IO_LEN; ++ ++ sec4_sg = edesc->sec4_sg; ++ sg_to_sec4_sg_last(src_sg, src_nents, sec4_sg, 0); ++ ++ sec4_sg += src_nents; ++ sg_to_sec4_sg_last(dst_sg, dst_nents, sec4_sg, 0); ++ ++ sec4_sg_dma_src = dma_map_single(jrdev, edesc->sec4_sg, sec4_sg_bytes, ++ DMA_TO_DEVICE); ++ if (dma_mapping_error(jrdev, sec4_sg_dma_src)) { ++ dev_err(jrdev, "error mapping segments to device\n"); ++ kfree(edesc); ++ return ERR_PTR(-ENOMEM); ++ } ++ ++ edesc->src_dma = sec4_sg_dma_src; ++ edesc->dst_dma = sec4_sg_dma_src + src_nents * sizeof(*sec4_sg); ++ edesc->ctx = ctx; ++ ++ return edesc; ++} ++ ++static void caam_jr_chan_free_edesc(struct caam_dma_edesc *edesc) ++{ ++ struct caam_dma_ctx *ctx = edesc->ctx; ++ struct caam_dma_edesc *_edesc = NULL; ++ ++ spin_lock_bh(&ctx->edesc_lock); ++ ++ list_add_tail(&edesc->node, &ctx->done_not_acked); ++ list_for_each_entry_safe(edesc, _edesc, &ctx->done_not_acked, node) { ++ if (async_tx_test_ack(&edesc->async_tx)) { ++ list_del(&edesc->node); ++ kfree(edesc); ++ } ++ } ++ ++ spin_unlock_bh(&ctx->edesc_lock); ++} ++ ++static void caam_dma_done(struct device *dev, u32 *hwdesc, u32 err, ++ void *context) ++{ ++ struct caam_dma_edesc *edesc = context; ++ struct caam_dma_ctx *ctx = edesc->ctx; ++ dma_async_tx_callback callback; ++ void *callback_param; ++ ++ if (err) ++ caam_jr_strstatus(ctx->jrdev, err); ++ ++ dma_run_dependencies(&edesc->async_tx); ++ ++ spin_lock_bh(&ctx->edesc_lock); ++ dma_cookie_complete(&edesc->async_tx); ++ spin_unlock_bh(&ctx->edesc_lock); ++ ++ callback = edesc->async_tx.callback; ++ callback_param = edesc->async_tx.callback_param; ++ ++ dma_descriptor_unmap(&edesc->async_tx); ++ ++ caam_jr_chan_free_edesc(edesc); ++ ++ if (callback) ++ callback(callback_param); ++} ++ ++static void caam_dma_sg_init_job_desc(struct caam_dma_edesc *edesc) ++{ ++ u32 *jd = edesc->jd; ++ u32 *sh_desc = dma_sh_desc->desc; ++ dma_addr_t desc_dma = dma_sh_desc->desc_dma; ++ ++ /* init the job descriptor */ ++ init_job_desc_shared(jd, desc_dma, desc_len(sh_desc), HDR_REVERSE); ++ ++ /* set SEQIN PTR */ ++ append_seq_in_ptr(jd, edesc->src_dma, edesc->src_len, LDST_SGF); ++ ++ /* set SEQOUT PTR */ ++ append_seq_out_ptr(jd, edesc->dst_dma, edesc->dst_len, LDST_SGF); ++ ++#ifdef DEBUG ++ print_hex_dump(KERN_ERR, "caam dma desc@" __stringify(__LINE__) ": ", ++ DUMP_PREFIX_ADDRESS, 16, 4, jd, desc_bytes(jd), 1); ++#endif ++} ++ ++/* This function can be called from an interrupt context */ ++static struct dma_async_tx_descriptor * ++caam_dma_prep_sg(struct dma_chan *chan, struct scatterlist *dst_sg, ++ unsigned int dst_nents, struct scatterlist *src_sg, ++ unsigned int src_nents, unsigned long flags) ++{ ++ struct caam_dma_edesc *edesc; ++ ++ /* allocate extended descriptor */ ++ edesc = caam_dma_sg_edesc_alloc(chan, dst_sg, dst_nents, src_sg, ++ src_nents, flags); ++ if (IS_ERR_OR_NULL(edesc)) ++ return ERR_CAST(edesc); ++ ++ /* Initialize job descriptor */ ++ caam_dma_sg_init_job_desc(edesc); ++ ++ return &edesc->async_tx; ++} ++ ++static void caam_dma_memcpy_init_job_desc(struct caam_dma_edesc *edesc) ++{ ++ u32 *jd = edesc->jd; ++ u32 *sh_desc = dma_sh_desc->desc; ++ dma_addr_t desc_dma = dma_sh_desc->desc_dma; ++ ++ /* init the job descriptor */ ++ init_job_desc_shared(jd, desc_dma, desc_len(sh_desc), HDR_REVERSE); ++ ++ /* set SEQIN PTR */ ++ append_seq_in_ptr(jd, edesc->src_dma, edesc->src_len, 0); ++ ++ /* set SEQOUT PTR */ ++ append_seq_out_ptr(jd, edesc->dst_dma, edesc->dst_len, 0); ++ ++#ifdef DEBUG ++ print_hex_dump(KERN_ERR, "caam dma desc@" __stringify(__LINE__) ": ", ++ DUMP_PREFIX_ADDRESS, 16, 4, jd, desc_bytes(jd), 1); ++#endif ++} ++ ++static struct dma_async_tx_descriptor * ++caam_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, ++ size_t len, unsigned long flags) ++{ ++ struct caam_dma_edesc *edesc; ++ struct caam_dma_ctx *ctx = container_of(chan, struct caam_dma_ctx, ++ chan); ++ ++ edesc = kzalloc(sizeof(*edesc) + DESC_JOB_IO_LEN, GFP_DMA | GFP_NOWAIT); ++ if (!edesc) ++ return ERR_PTR(-ENOMEM); ++ ++ dma_async_tx_descriptor_init(&edesc->async_tx, chan); ++ edesc->async_tx.tx_submit = caam_dma_tx_submit; ++ edesc->async_tx.flags = flags; ++ edesc->async_tx.cookie = -EBUSY; ++ ++ edesc->src_dma = src; ++ edesc->src_len = len; ++ edesc->dst_dma = dst; ++ edesc->dst_len = len; ++ edesc->ctx = ctx; ++ ++ caam_dma_memcpy_init_job_desc(edesc); ++ ++ return &edesc->async_tx; ++} ++ ++/* This function can be called in an interrupt context */ ++static void caam_dma_issue_pending(struct dma_chan *chan) ++{ ++ struct caam_dma_ctx *ctx = container_of(chan, struct caam_dma_ctx, ++ chan); ++ struct caam_dma_edesc *edesc, *_edesc; ++ ++ spin_lock_bh(&ctx->edesc_lock); ++ list_for_each_entry_safe(edesc, _edesc, &ctx->submit_q, node) { ++ if (caam_jr_enqueue(ctx->jrdev, edesc->jd, ++ caam_dma_done, edesc) < 0) ++ break; ++ list_del(&edesc->node); ++ } ++ spin_unlock_bh(&ctx->edesc_lock); ++} ++ ++static void caam_dma_free_chan_resources(struct dma_chan *chan) ++{ ++ struct caam_dma_ctx *ctx = container_of(chan, struct caam_dma_ctx, ++ chan); ++ struct caam_dma_edesc *edesc, *_edesc; ++ ++ spin_lock_bh(&ctx->edesc_lock); ++ list_for_each_entry_safe(edesc, _edesc, &ctx->submit_q, node) { ++ list_del(&edesc->node); ++ kfree(edesc); ++ } ++ list_for_each_entry_safe(edesc, _edesc, &ctx->done_not_acked, node) { ++ list_del(&edesc->node); ++ kfree(edesc); ++ } ++ spin_unlock_bh(&ctx->edesc_lock); ++} ++ ++static int caam_dma_jr_chan_bind(void) ++{ ++ struct device *jrdev; ++ struct caam_dma_ctx *ctx; ++ int bonds = 0; ++ int i; ++ ++ for (i = 0; i < caam_jr_driver_probed(); i++) { ++ jrdev = caam_jridx_alloc(i); ++ if (IS_ERR(jrdev)) { ++ pr_err("job ring device %d allocation failed\n", i); ++ continue; ++ } ++ ++ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); ++ if (!ctx) { ++ caam_jr_free(jrdev); ++ continue; ++ } ++ ++ ctx->chan.device = dma_dev; ++ ctx->chan.private = ctx; ++ ++ ctx->jrdev = jrdev; ++ ++ INIT_LIST_HEAD(&ctx->submit_q); ++ INIT_LIST_HEAD(&ctx->done_not_acked); ++ INIT_LIST_HEAD(&ctx->node); ++ spin_lock_init(&ctx->edesc_lock); ++ ++ dma_cookie_init(&ctx->chan); ++ ++ /* add the context of this channel to the context list */ ++ list_add_tail(&ctx->node, &dma_ctx_list); ++ ++ /* add this channel to the device chan list */ ++ list_add_tail(&ctx->chan.device_node, &dma_dev->channels); ++ ++ bonds++; ++ } ++ ++ return bonds; ++} ++ ++static inline void caam_jr_dma_free(struct dma_chan *chan) ++{ ++ struct caam_dma_ctx *ctx = container_of(chan, struct caam_dma_ctx, ++ chan); ++ ++ list_del(&ctx->node); ++ list_del(&chan->device_node); ++ caam_jr_free(ctx->jrdev); ++ kfree(ctx); ++} ++ ++static void set_caam_dma_desc(u32 *desc) ++{ ++ u32 *jmp_cmd; ++ ++ /* dma shared descriptor */ ++ init_sh_desc(desc, HDR_SHARE_NEVER | (1 << HDR_START_IDX_SHIFT)); ++ ++ /* REG1 = CAAM_DMA_CHUNK_SIZE */ ++ append_math_add_imm_u32(desc, REG1, ZERO, IMM, CAAM_DMA_CHUNK_SIZE); ++ ++ /* REG0 = SEQINLEN - CAAM_DMA_CHUNK_SIZE */ ++ append_math_sub_imm_u32(desc, REG0, SEQINLEN, IMM, CAAM_DMA_CHUNK_SIZE); ++ ++ /* if (REG0 > 0) ++ * jmp to LABEL1 ++ */ ++ jmp_cmd = append_jump(desc, JUMP_TEST_INVALL | JUMP_COND_MATH_N | ++ JUMP_COND_MATH_Z); ++ ++ /* REG1 = SEQINLEN */ ++ append_math_sub(desc, REG1, SEQINLEN, ZERO, CAAM_CMD_SZ); ++ ++ /* LABEL1 */ ++ set_jump_tgt_here(desc, jmp_cmd); ++ ++ /* VARSEQINLEN = REG1 */ ++ append_math_add(desc, VARSEQINLEN, REG1, ZERO, CAAM_CMD_SZ); ++ ++ /* VARSEQOUTLEN = REG1 */ ++ append_math_add(desc, VARSEQOUTLEN, REG1, ZERO, CAAM_CMD_SZ); ++ ++ /* do FIFO STORE */ ++ append_seq_fifo_store(desc, 0, FIFOST_TYPE_METADATA | LDST_VLF); ++ ++ /* do FIFO LOAD */ ++ append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | ++ FIFOLD_TYPE_IFIFO | LDST_VLF); ++ ++ /* if (REG0 > 0) ++ * jmp 0xF8 (after shared desc header) ++ */ ++ append_jump(desc, JUMP_TEST_INVALL | JUMP_COND_MATH_N | ++ JUMP_COND_MATH_Z | 0xF8); ++ ++#ifdef DEBUG ++ print_hex_dump(KERN_ERR, "caam dma shdesc@" __stringify(__LINE__) ": ", ++ DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1); ++#endif ++} ++ ++static int __init caam_dma_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device *ctrldev = dev->parent; ++ struct dma_chan *chan, *_chan; ++ u32 *sh_desc; ++ int err = -ENOMEM; ++ int bonds; ++ ++ if (!caam_jr_driver_probed()) { ++ dev_info(dev, "Defer probing after JR driver probing\n"); ++ return -EPROBE_DEFER; ++ } ++ ++ dma_dev = kzalloc(sizeof(*dma_dev), GFP_KERNEL); ++ if (!dma_dev) ++ return -ENOMEM; ++ ++ dma_sh_desc = kzalloc(sizeof(*dma_sh_desc), GFP_KERNEL | GFP_DMA); ++ if (!dma_sh_desc) ++ goto desc_err; ++ ++ sh_desc = dma_sh_desc->desc; ++ set_caam_dma_desc(sh_desc); ++ dma_sh_desc->desc_dma = dma_map_single(ctrldev, sh_desc, ++ desc_bytes(sh_desc), ++ DMA_TO_DEVICE); ++ if (dma_mapping_error(ctrldev, dma_sh_desc->desc_dma)) { ++ dev_err(dev, "unable to map dma descriptor\n"); ++ goto map_err; ++ } ++ ++ INIT_LIST_HEAD(&dma_dev->channels); ++ ++ bonds = caam_dma_jr_chan_bind(); ++ if (!bonds) { ++ err = -ENODEV; ++ goto jr_bind_err; ++ } ++ ++ dma_dev->dev = dev; ++ dma_dev->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; ++ dma_cap_set(DMA_SG, dma_dev->cap_mask); ++ dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask); ++ dma_cap_set(DMA_PRIVATE, dma_dev->cap_mask); ++ dma_dev->device_tx_status = dma_cookie_status; ++ dma_dev->device_issue_pending = caam_dma_issue_pending; ++ dma_dev->device_prep_dma_sg = caam_dma_prep_sg; ++ dma_dev->device_prep_dma_memcpy = caam_dma_prep_memcpy; ++ dma_dev->device_free_chan_resources = caam_dma_free_chan_resources; ++ ++ err = dma_async_device_register(dma_dev); ++ if (err) { ++ dev_err(dev, "Failed to register CAAM DMA engine\n"); ++ goto jr_bind_err; ++ } ++ ++ dev_info(dev, "caam dma support with %d job rings\n", bonds); ++ ++ return err; ++ ++jr_bind_err: ++ list_for_each_entry_safe(chan, _chan, &dma_dev->channels, device_node) ++ caam_jr_dma_free(chan); ++ ++ dma_unmap_single(ctrldev, dma_sh_desc->desc_dma, desc_bytes(sh_desc), ++ DMA_TO_DEVICE); ++map_err: ++ kfree(dma_sh_desc); ++desc_err: ++ kfree(dma_dev); ++ return err; ++} ++ ++static int caam_dma_remove(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device *ctrldev = dev->parent; ++ struct caam_dma_ctx *ctx, *_ctx; ++ ++ dma_async_device_unregister(dma_dev); ++ ++ list_for_each_entry_safe(ctx, _ctx, &dma_ctx_list, node) { ++ list_del(&ctx->node); ++ caam_jr_free(ctx->jrdev); ++ kfree(ctx); ++ } ++ ++ dma_unmap_single(ctrldev, dma_sh_desc->desc_dma, ++ desc_bytes(dma_sh_desc->desc), DMA_TO_DEVICE); ++ ++ kfree(dma_sh_desc); ++ kfree(dma_dev); ++ ++ dev_info(dev, "caam dma support disabled\n"); ++ return 0; ++} ++ ++static const struct of_device_id caam_dma_match[] = { ++ { .compatible = "fsl,sec-v5.4-dma", }, ++ { .compatible = "fsl,sec-v5.0-dma", }, ++ { .compatible = "fsl,sec-v4.0-dma", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, caam_dma_match); ++ ++static struct platform_driver caam_dma_driver = { ++ .driver = { ++ .name = "caam-dma", ++ .of_match_table = caam_dma_match, ++ }, ++ .probe = caam_dma_probe, ++ .remove = caam_dma_remove, ++}; ++module_platform_driver(caam_dma_driver); ++ ++MODULE_LICENSE("Dual BSD/GPL"); ++MODULE_DESCRIPTION("NXP CAAM support for SG DMA"); ++MODULE_AUTHOR("NXP Semiconductors"); --- /dev/null +++ b/drivers/dma/dpaa2-qdma/Kconfig @@ -0,0 +1,8 @@ diff --git a/target/linux/layerscape/patches-4.9/806-flextimer-support-layerscape.patch b/target/linux/layerscape/patches-4.9/806-flextimer-support-layerscape.patch index 711fde77d..7ead7b6ec 100644 --- a/target/linux/layerscape/patches-4.9/806-flextimer-support-layerscape.patch +++ b/target/linux/layerscape/patches-4.9/806-flextimer-support-layerscape.patch @@ -1,4 +1,4 @@ -From a5b3155b532289af793c26251cb087b4a24d5c15 Mon Sep 17 00:00:00 2001 +From 76cd2ef6b69b67c09480a3248f7b910897f0bb2f Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Mon, 25 Sep 2017 12:13:12 +0800 Subject: [PATCH] flextimer: support layerscape @@ -10,8 +10,8 @@ Signed-off-by: Meng Yi Signed-off-by: Yangbo Lu --- drivers/clocksource/fsl_ftm_timer.c | 8 +- - drivers/soc/fsl/layerscape/ftm_alarm.c | 286 +++++++++++++++++++++++++++++++++ - 2 files changed, 290 insertions(+), 4 deletions(-) + drivers/soc/fsl/layerscape/ftm_alarm.c | 367 +++++++++++++++++++++++++++++++++ + 2 files changed, 371 insertions(+), 4 deletions(-) create mode 100644 drivers/soc/fsl/layerscape/ftm_alarm.c --- a/drivers/clocksource/fsl_ftm_timer.c @@ -34,7 +34,7 @@ Signed-off-by: Yangbo Lu static inline void ftm_irq_enable(void __iomem *base) --- /dev/null +++ b/drivers/soc/fsl/layerscape/ftm_alarm.c -@@ -0,0 +1,286 @@ +@@ -0,0 +1,367 @@ +/* + * Freescale FlexTimer Module (FTM) Alarm driver. + * @@ -53,6 +53,10 @@ Signed-off-by: Yangbo Lu +#include +#include +#include ++#include ++#include ++#include ++#include + +#define FTM_SC 0x00 +#define FTM_SC_CLK_SHIFT 3 @@ -77,6 +81,57 @@ Signed-off-by: Yangbo Lu +static u32 alarm_freq; +static bool big_endian; + ++enum pmu_endian_type { ++ BIG_ENDIAN, ++ LITTLE_ENDIAN, ++}; ++ ++struct rcpm_cfg { ++ enum pmu_endian_type big_endian; /* Big/Little endian of PMU module */ ++ u32 flextimer_set_bit; /* FlexTimer1 is not powerdown during device LPM20 */ ++}; ++ ++static struct rcpm_cfg ls1012a_rcpm_cfg = { ++ .big_endian = BIG_ENDIAN, ++ .flextimer_set_bit = 0x20000, ++}; ++ ++static struct rcpm_cfg ls1021a_rcpm_cfg = { ++ .big_endian = BIG_ENDIAN, ++ .flextimer_set_bit = 0x20000, ++}; ++ ++static struct rcpm_cfg ls1043a_rcpm_cfg = { ++ .big_endian = BIG_ENDIAN, ++ .flextimer_set_bit = 0x20000, ++}; ++ ++static struct rcpm_cfg ls1046a_rcpm_cfg = { ++ .big_endian = BIG_ENDIAN, ++ .flextimer_set_bit = 0x20000, ++}; ++ ++static struct rcpm_cfg ls1088a_rcpm_cfg = { ++ .big_endian = LITTLE_ENDIAN, ++ .flextimer_set_bit = 0x4000, ++}; ++ ++static struct rcpm_cfg ls208xa_rcpm_cfg = { ++ .big_endian = LITTLE_ENDIAN, ++ .flextimer_set_bit = 0x4000, ++}; ++ ++static const struct of_device_id ippdexpcr_of_match[] = { ++ { .compatible = "fsl,ls1012a-ftm", .data = &ls1012a_rcpm_cfg}, ++ { .compatible = "fsl,ls1021a-ftm", .data = &ls1021a_rcpm_cfg}, ++ { .compatible = "fsl,ls1043a-ftm", .data = &ls1043a_rcpm_cfg}, ++ { .compatible = "fsl,ls1046a-ftm", .data = &ls1046a_rcpm_cfg}, ++ { .compatible = "fsl,ls1088a-ftm", .data = &ls1088a_rcpm_cfg}, ++ { .compatible = "fsl,ls208xa-ftm", .data = &ls208xa_rcpm_cfg}, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, ippdexpcr_of_match); ++ +static inline u32 ftm_readl(void __iomem *addr) +{ + if (big_endian) @@ -251,7 +306,10 @@ Signed-off-by: Yangbo Lu + struct resource *r; + int irq; + int ret; -+ u32 ippdexpcr; ++ struct rcpm_cfg *rcpm_cfg; ++ u32 ippdexpcr, flextimer; ++ const struct of_device_id *of_id; ++ enum pmu_endian_type endian; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) @@ -261,14 +319,32 @@ Signed-off-by: Yangbo Lu + if (IS_ERR(ftm1_base)) + return PTR_ERR(ftm1_base); + ++ of_id = of_match_node(ippdexpcr_of_match, np); ++ if (!of_id) ++ return -ENODEV; ++ ++ rcpm_cfg = devm_kzalloc(&pdev->dev, sizeof(*rcpm_cfg), GFP_KERNEL); ++ if (!rcpm_cfg) ++ return -ENOMEM; ++ ++ rcpm_cfg = (struct rcpm_cfg*)of_id->data; ++ endian = rcpm_cfg->big_endian; ++ flextimer = rcpm_cfg->flextimer_set_bit; ++ + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "FlexTimer1"); + if (r) { + rcpm_ftm_addr = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(rcpm_ftm_addr)) + return PTR_ERR(rcpm_ftm_addr); -+ ippdexpcr = ioread32be(rcpm_ftm_addr); -+ ippdexpcr |= 0x20000; -+ iowrite32be(ippdexpcr, rcpm_ftm_addr); ++ if (endian == BIG_ENDIAN) ++ ippdexpcr = ioread32be(rcpm_ftm_addr); ++ else ++ ippdexpcr = ioread32(rcpm_ftm_addr); ++ ippdexpcr |= flextimer; ++ if (endian == BIG_ENDIAN) ++ iowrite32be(ippdexpcr, rcpm_ftm_addr); ++ else ++ iowrite32(ippdexpcr, rcpm_ftm_addr); + } + + irq = irq_of_parse_and_map(np, 0); @@ -302,7 +378,12 @@ Signed-off-by: Yangbo Lu +} + +static const struct of_device_id ftm_alarm_match[] = { -+ { .compatible = "fsl,ftm-alarm", }, ++ { .compatible = "fsl,ls1012a-ftm", }, ++ { .compatible = "fsl,ls1021a-ftm", }, ++ { .compatible = "fsl,ls1043a-ftm", }, ++ { .compatible = "fsl,ls1046a-ftm", }, ++ { .compatible = "fsl,ls1088a-ftm", }, ++ { .compatible = "fsl,ls208xa-ftm", }, + { .compatible = "fsl,ftm-timer", }, + { }, +}; diff --git a/target/linux/layerscape/patches-4.9/810-iommu-support-layerscape.patch b/target/linux/layerscape/patches-4.9/810-iommu-support-layerscape.patch index ec8917361..657a38fec 100644 --- a/target/linux/layerscape/patches-4.9/810-iommu-support-layerscape.patch +++ b/target/linux/layerscape/patches-4.9/810-iommu-support-layerscape.patch @@ -1,4 +1,4 @@ -From f1874c71c855bd8ca8478a622053276f2c61eeca Mon Sep 17 00:00:00 2001 +From 152f316e7829f6aeb3a36009e7e5ec0f1d97d770 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Wed, 27 Sep 2017 10:33:26 +0800 Subject: [PATCH] iommu: support layerscape @@ -12,16 +12,16 @@ Signed-off-by: Sunil Goutham Signed-off-by: Yangbo Lu --- drivers/iommu/amd_iommu.c | 56 ++++++---- - drivers/iommu/arm-smmu-v3.c | 35 ++++++- - drivers/iommu/arm-smmu.c | 74 ++++++++++--- + drivers/iommu/arm-smmu-v3.c | 117 ++++++++++++++------- + drivers/iommu/arm-smmu.c | 100 +++++++++++++++--- drivers/iommu/dma-iommu.c | 242 ++++++++++++++++++++++++++++++++++++------- drivers/iommu/intel-iommu.c | 92 ++++++++++++---- - drivers/iommu/iommu.c | 191 ++++++++++++++++++++++++++++++++-- + drivers/iommu/iommu.c | 219 ++++++++++++++++++++++++++++++++++++--- drivers/iommu/mtk_iommu.c | 2 + drivers/iommu/mtk_iommu_v1.c | 2 + include/linux/dma-iommu.h | 11 ++ include/linux/iommu.h | 55 +++++++--- - 10 files changed, 645 insertions(+), 115 deletions(-) + 10 files changed, 739 insertions(+), 157 deletions(-) --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -143,7 +143,78 @@ Signed-off-by: Yangbo Lu static bool disable_bypass; module_param_named(disable_bypass, disable_bypass, bool, S_IRUGO); MODULE_PARM_DESC(disable_bypass, -@@ -1370,8 +1373,6 @@ static bool arm_smmu_capable(enum iommu_ +@@ -552,9 +555,14 @@ struct arm_smmu_s2_cfg { + }; + + struct arm_smmu_strtab_ent { +- bool valid; +- +- bool bypass; /* Overrides s1/s2 config */ ++ /* ++ * An STE is "assigned" if the master emitting the corresponding SID ++ * is attached to a domain. The behaviour of an unassigned STE is ++ * determined by the disable_bypass parameter, whereas an assigned ++ * STE behaves according to s1_cfg/s2_cfg, which themselves are ++ * configured according to the domain type. ++ */ ++ bool assigned; + struct arm_smmu_s1_cfg *s1_cfg; + struct arm_smmu_s2_cfg *s2_cfg; + }; +@@ -627,6 +635,7 @@ enum arm_smmu_domain_stage { + ARM_SMMU_DOMAIN_S1 = 0, + ARM_SMMU_DOMAIN_S2, + ARM_SMMU_DOMAIN_NESTED, ++ ARM_SMMU_DOMAIN_BYPASS, + }; + + struct arm_smmu_domain { +@@ -1000,9 +1009,9 @@ static void arm_smmu_write_strtab_ent(st + * This is hideously complicated, but we only really care about + * three cases at the moment: + * +- * 1. Invalid (all zero) -> bypass (init) +- * 2. Bypass -> translation (attach) +- * 3. Translation -> bypass (detach) ++ * 1. Invalid (all zero) -> bypass/fault (init) ++ * 2. Bypass/fault -> translation/bypass (attach) ++ * 3. Translation/bypass -> bypass/fault (detach) + * + * Given that we can't update the STE atomically and the SMMU + * doesn't read the thing in a defined order, that leaves us +@@ -1041,11 +1050,15 @@ static void arm_smmu_write_strtab_ent(st + } + + /* Nuke the existing STE_0 value, as we're going to rewrite it */ +- val = ste->valid ? STRTAB_STE_0_V : 0; ++ val = STRTAB_STE_0_V; ++ ++ /* Bypass/fault */ ++ if (!ste->assigned || !(ste->s1_cfg || ste->s2_cfg)) { ++ if (!ste->assigned && disable_bypass) ++ val |= STRTAB_STE_0_CFG_ABORT; ++ else ++ val |= STRTAB_STE_0_CFG_BYPASS; + +- if (ste->bypass) { +- val |= disable_bypass ? STRTAB_STE_0_CFG_ABORT +- : STRTAB_STE_0_CFG_BYPASS; + dst[0] = cpu_to_le64(val); + dst[1] = cpu_to_le64(STRTAB_STE_1_SHCFG_INCOMING + << STRTAB_STE_1_SHCFG_SHIFT); +@@ -1108,10 +1121,7 @@ static void arm_smmu_write_strtab_ent(st + static void arm_smmu_init_bypass_stes(u64 *strtab, unsigned int nent) + { + unsigned int i; +- struct arm_smmu_strtab_ent ste = { +- .valid = true, +- .bypass = true, +- }; ++ struct arm_smmu_strtab_ent ste = { .assigned = false }; + + for (i = 0; i < nent; ++i) { + arm_smmu_write_strtab_ent(NULL, -1, strtab, &ste); +@@ -1364,8 +1374,6 @@ static bool arm_smmu_capable(enum iommu_ switch (cap) { case IOMMU_CAP_CACHE_COHERENCY: return true; @@ -152,7 +223,96 @@ Signed-off-by: Yangbo Lu case IOMMU_CAP_NOEXEC: return true; default: -@@ -1709,6 +1710,9 @@ arm_smmu_iova_to_phys(struct iommu_domai +@@ -1377,7 +1385,9 @@ static struct iommu_domain *arm_smmu_dom + { + struct arm_smmu_domain *smmu_domain; + +- if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA) ++ if (type != IOMMU_DOMAIN_UNMANAGED && ++ type != IOMMU_DOMAIN_DMA && ++ type != IOMMU_DOMAIN_IDENTITY) + return NULL; + + /* +@@ -1508,6 +1518,11 @@ static int arm_smmu_domain_finalise(stru + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); + struct arm_smmu_device *smmu = smmu_domain->smmu; + ++ if (domain->type == IOMMU_DOMAIN_IDENTITY) { ++ smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS; ++ return 0; ++ } ++ + /* Restrict the stage to what we can actually support */ + if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1)) + smmu_domain->stage = ARM_SMMU_DOMAIN_S2; +@@ -1578,7 +1593,7 @@ static __le64 *arm_smmu_get_step_for_sid + return step; + } + +-static int arm_smmu_install_ste_for_dev(struct iommu_fwspec *fwspec) ++static void arm_smmu_install_ste_for_dev(struct iommu_fwspec *fwspec) + { + int i; + struct arm_smmu_master_data *master = fwspec->iommu_priv; +@@ -1590,17 +1605,14 @@ static int arm_smmu_install_ste_for_dev( + + arm_smmu_write_strtab_ent(smmu, sid, step, &master->ste); + } +- +- return 0; + } + + static void arm_smmu_detach_dev(struct device *dev) + { + struct arm_smmu_master_data *master = dev->iommu_fwspec->iommu_priv; + +- master->ste.bypass = true; +- if (arm_smmu_install_ste_for_dev(dev->iommu_fwspec) < 0) +- dev_warn(dev, "failed to install bypass STE\n"); ++ master->ste.assigned = false; ++ arm_smmu_install_ste_for_dev(dev->iommu_fwspec); + } + + static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) +@@ -1619,7 +1631,7 @@ static int arm_smmu_attach_dev(struct io + ste = &master->ste; + + /* Already attached to a different domain? */ +- if (!ste->bypass) ++ if (ste->assigned) + arm_smmu_detach_dev(dev); + + mutex_lock(&smmu_domain->init_mutex); +@@ -1640,10 +1652,12 @@ static int arm_smmu_attach_dev(struct io + goto out_unlock; + } + +- ste->bypass = false; +- ste->valid = true; ++ ste->assigned = true; + +- if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) { ++ if (smmu_domain->stage == ARM_SMMU_DOMAIN_BYPASS) { ++ ste->s1_cfg = NULL; ++ ste->s2_cfg = NULL; ++ } else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) { + ste->s1_cfg = &smmu_domain->s1_cfg; + ste->s2_cfg = NULL; + arm_smmu_write_ctx_desc(smmu, ste->s1_cfg); +@@ -1652,10 +1666,7 @@ static int arm_smmu_attach_dev(struct io + ste->s2_cfg = &smmu_domain->s2_cfg; + } + +- ret = arm_smmu_install_ste_for_dev(dev->iommu_fwspec); +- if (ret < 0) +- ste->valid = false; +- ++ arm_smmu_install_ste_for_dev(dev->iommu_fwspec); + out_unlock: + mutex_unlock(&smmu_domain->init_mutex); + return ret; +@@ -1703,6 +1714,9 @@ arm_smmu_iova_to_phys(struct iommu_domai struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops; @@ -162,7 +322,36 @@ Signed-off-by: Yangbo Lu if (!ops) return 0; -@@ -1880,6 +1884,31 @@ static int arm_smmu_of_xlate(struct devi +@@ -1801,7 +1815,7 @@ static void arm_smmu_remove_device(struc + return; + + master = fwspec->iommu_priv; +- if (master && master->ste.valid) ++ if (master && master->ste.assigned) + arm_smmu_detach_dev(dev); + iommu_group_remove_device(dev); + kfree(master); +@@ -1830,6 +1844,9 @@ static int arm_smmu_domain_get_attr(stru + { + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); + ++ if (domain->type != IOMMU_DOMAIN_UNMANAGED) ++ return -EINVAL; ++ + switch (attr) { + case DOMAIN_ATTR_NESTING: + *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED); +@@ -1845,6 +1862,9 @@ static int arm_smmu_domain_set_attr(stru + int ret = 0; + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); + ++ if (domain->type != IOMMU_DOMAIN_UNMANAGED) ++ return -EINVAL; ++ + mutex_lock(&smmu_domain->init_mutex); + + switch (attr) { +@@ -1874,6 +1894,31 @@ static int arm_smmu_of_xlate(struct devi return iommu_fwspec_add_ids(dev, args->args, 1); } @@ -194,7 +383,7 @@ Signed-off-by: Yangbo Lu static struct iommu_ops arm_smmu_ops = { .capable = arm_smmu_capable, .domain_alloc = arm_smmu_domain_alloc, -@@ -1895,6 +1924,8 @@ static struct iommu_ops arm_smmu_ops = { +@@ -1889,6 +1934,8 @@ static struct iommu_ops arm_smmu_ops = { .domain_get_attr = arm_smmu_domain_get_attr, .domain_set_attr = arm_smmu_domain_set_attr, .of_xlate = arm_smmu_of_xlate, @@ -231,7 +420,65 @@ Signed-off-by: Yangbo Lu static int force_stage; module_param(force_stage, int, S_IRUGO); MODULE_PARM_DESC(force_stage, -@@ -1343,6 +1348,9 @@ static phys_addr_t arm_smmu_iova_to_phys +@@ -401,6 +406,7 @@ enum arm_smmu_domain_stage { + ARM_SMMU_DOMAIN_S1 = 0, + ARM_SMMU_DOMAIN_S2, + ARM_SMMU_DOMAIN_NESTED, ++ ARM_SMMU_DOMAIN_BYPASS, + }; + + struct arm_smmu_domain { +@@ -821,6 +827,12 @@ static int arm_smmu_init_domain_context( + if (smmu_domain->smmu) + goto out_unlock; + ++ if (domain->type == IOMMU_DOMAIN_IDENTITY) { ++ smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS; ++ smmu_domain->smmu = smmu; ++ goto out_unlock; ++ } ++ + /* + * Mapping the requested stage onto what we support is surprisingly + * complicated, mainly because the spec allows S1+S2 SMMUs without +@@ -981,7 +993,7 @@ static void arm_smmu_destroy_domain_cont + void __iomem *cb_base; + int irq; + +- if (!smmu) ++ if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY) + return; + + /* +@@ -1004,7 +1016,9 @@ static struct iommu_domain *arm_smmu_dom + { + struct arm_smmu_domain *smmu_domain; + +- if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA) ++ if (type != IOMMU_DOMAIN_UNMANAGED && ++ type != IOMMU_DOMAIN_DMA && ++ type != IOMMU_DOMAIN_IDENTITY) + return NULL; + /* + * Allocate the domain and initialise some of its data structures. +@@ -1202,10 +1216,15 @@ static int arm_smmu_domain_add_master(st + { + struct arm_smmu_device *smmu = smmu_domain->smmu; + struct arm_smmu_s2cr *s2cr = smmu->s2crs; +- enum arm_smmu_s2cr_type type = S2CR_TYPE_TRANS; + u8 cbndx = smmu_domain->cfg.cbndx; ++ enum arm_smmu_s2cr_type type; + int i, idx; + ++ if (smmu_domain->stage == ARM_SMMU_DOMAIN_BYPASS) ++ type = S2CR_TYPE_BYPASS; ++ else ++ type = S2CR_TYPE_TRANS; ++ + for_each_cfg_sme(fwspec, i, idx) { + if (type == s2cr[idx].type && cbndx == s2cr[idx].cbndx) + continue; +@@ -1343,6 +1362,9 @@ static phys_addr_t arm_smmu_iova_to_phys struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops; @@ -241,7 +488,7 @@ Signed-off-by: Yangbo Lu if (!ops) return 0; -@@ -1368,8 +1376,6 @@ static bool arm_smmu_capable(enum iommu_ +@@ -1368,8 +1390,6 @@ static bool arm_smmu_capable(enum iommu_ * requests. */ return true; @@ -250,7 +497,7 @@ Signed-off-by: Yangbo Lu case IOMMU_CAP_NOEXEC: return true; default: -@@ -1478,10 +1484,12 @@ static struct iommu_group *arm_smmu_devi +@@ -1478,10 +1498,12 @@ static struct iommu_group *arm_smmu_devi } if (group) @@ -264,7 +511,27 @@ Signed-off-by: Yangbo Lu else group = generic_device_group(dev); -@@ -1534,17 +1542,44 @@ out_unlock: +@@ -1493,6 +1515,9 @@ static int arm_smmu_domain_get_attr(stru + { + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); + ++ if (domain->type != IOMMU_DOMAIN_UNMANAGED) ++ return -EINVAL; ++ + switch (attr) { + case DOMAIN_ATTR_NESTING: + *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED); +@@ -1508,6 +1533,9 @@ static int arm_smmu_domain_set_attr(stru + int ret = 0; + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); + ++ if (domain->type != IOMMU_DOMAIN_UNMANAGED) ++ return -EINVAL; ++ + mutex_lock(&smmu_domain->init_mutex); + + switch (attr) { +@@ -1534,17 +1562,44 @@ out_unlock: static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args) { @@ -310,7 +577,7 @@ Signed-off-by: Yangbo Lu static struct iommu_ops arm_smmu_ops = { .capable = arm_smmu_capable, .domain_alloc = arm_smmu_domain_alloc, -@@ -1560,6 +1595,8 @@ static struct iommu_ops arm_smmu_ops = { +@@ -1560,6 +1615,8 @@ static struct iommu_ops arm_smmu_ops = { .domain_get_attr = arm_smmu_domain_get_attr, .domain_set_attr = arm_smmu_domain_set_attr, .of_xlate = arm_smmu_of_xlate, @@ -319,7 +586,7 @@ Signed-off-by: Yangbo Lu .pgsize_bitmap = -1UL, /* Restricted during device attach */ }; -@@ -1581,16 +1618,22 @@ static void arm_smmu_device_reset(struct +@@ -1581,16 +1638,22 @@ static void arm_smmu_device_reset(struct for (i = 0; i < smmu->num_mapping_groups; ++i) arm_smmu_write_sme(smmu, i); @@ -351,7 +618,7 @@ Signed-off-by: Yangbo Lu writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_sACR); } -@@ -2024,6 +2067,11 @@ static int arm_smmu_device_dt_probe(stru +@@ -2024,6 +2087,11 @@ static int arm_smmu_device_dt_probe(stru bus_set_iommu(&pci_bus_type, &arm_smmu_ops); } #endif @@ -865,7 +1132,15 @@ Signed-off-by: Yangbo Lu static void quirk_iommu_g4x_gfx(struct pci_dev *dev) --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c -@@ -68,6 +68,13 @@ struct iommu_group_attribute { +@@ -36,6 +36,7 @@ + + static struct kset *iommu_group_kset; + static DEFINE_IDA(iommu_group_ida); ++static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_DMA; + + struct iommu_callback_data { + const struct iommu_ops *ops; +@@ -68,6 +69,13 @@ struct iommu_group_attribute { const char *buf, size_t count); }; @@ -879,7 +1154,26 @@ Signed-off-by: Yangbo Lu #define IOMMU_GROUP_ATTR(_name, _mode, _show, _store) \ struct iommu_group_attribute iommu_group_attr_##_name = \ __ATTR(_name, _mode, _show, _store) -@@ -133,8 +140,131 @@ static ssize_t iommu_group_show_name(str +@@ -86,6 +94,18 @@ static int __iommu_attach_group(struct i + static void __iommu_detach_group(struct iommu_domain *domain, + struct iommu_group *group); + ++static int __init iommu_set_def_domain_type(char *str) ++{ ++ bool pt; ++ ++ if (!str || strtobool(str, &pt)) ++ return -EINVAL; ++ ++ iommu_def_domain_type = pt ? IOMMU_DOMAIN_IDENTITY : IOMMU_DOMAIN_DMA; ++ return 0; ++} ++early_param("iommu.passthrough", iommu_set_def_domain_type); ++ + static ssize_t iommu_group_attr_show(struct kobject *kobj, + struct attribute *__attr, char *buf) + { +@@ -133,8 +153,131 @@ static ssize_t iommu_group_show_name(str return sprintf(buf, "%s\n", group->name); } @@ -1011,7 +1305,7 @@ Signed-off-by: Yangbo Lu static void iommu_group_release(struct kobject *kobj) { struct iommu_group *group = to_iommu_group(kobj); -@@ -212,6 +342,11 @@ struct iommu_group *iommu_group_alloc(vo +@@ -212,6 +355,11 @@ struct iommu_group *iommu_group_alloc(vo */ kobject_put(&group->kobj); @@ -1023,7 +1317,7 @@ Signed-off-by: Yangbo Lu pr_debug("Allocated group %d\n", group->id); return group; -@@ -318,7 +453,7 @@ static int iommu_group_create_direct_map +@@ -318,7 +466,7 @@ static int iommu_group_create_direct_map struct device *dev) { struct iommu_domain *domain = group->default_domain; @@ -1032,7 +1326,7 @@ Signed-off-by: Yangbo Lu struct list_head mappings; unsigned long pg_size; int ret = 0; -@@ -331,18 +466,21 @@ static int iommu_group_create_direct_map +@@ -331,18 +479,21 @@ static int iommu_group_create_direct_map pg_size = 1UL << __ffs(domain->pgsize_bitmap); INIT_LIST_HEAD(&mappings); @@ -1057,7 +1351,7 @@ Signed-off-by: Yangbo Lu for (addr = start; addr < end; addr += pg_size) { phys_addr_t phys_addr; -@@ -358,7 +496,7 @@ static int iommu_group_create_direct_map +@@ -358,7 +509,7 @@ static int iommu_group_create_direct_map } out: @@ -1066,7 +1360,7 @@ Signed-off-by: Yangbo Lu return ret; } -@@ -563,6 +701,19 @@ struct iommu_group *iommu_group_get(stru +@@ -563,6 +714,19 @@ struct iommu_group *iommu_group_get(stru EXPORT_SYMBOL_GPL(iommu_group_get); /** @@ -1086,7 +1380,30 @@ Signed-off-by: Yangbo Lu * iommu_group_put - Decrement group reference * @group: the group to use * -@@ -1557,20 +1708,38 @@ int iommu_domain_set_attr(struct iommu_d +@@ -845,10 +1009,19 @@ struct iommu_group *iommu_group_get_for_ + * IOMMU driver. + */ + if (!group->default_domain) { +- group->default_domain = __iommu_domain_alloc(dev->bus, +- IOMMU_DOMAIN_DMA); ++ struct iommu_domain *dom; ++ ++ dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type); ++ if (!dom && iommu_def_domain_type != IOMMU_DOMAIN_DMA) { ++ dev_warn(dev, ++ "failed to allocate default IOMMU domain of type %u; falling back to IOMMU_DOMAIN_DMA", ++ iommu_def_domain_type); ++ dom = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_DMA); ++ } ++ ++ group->default_domain = dom; + if (!group->domain) +- group->domain = group->default_domain; ++ group->domain = dom; + } + + ret = iommu_group_add_device(group, dev); +@@ -1557,20 +1730,38 @@ int iommu_domain_set_attr(struct iommu_d } EXPORT_SYMBOL_GPL(iommu_domain_set_attr); diff --git a/target/linux/layerscape/patches-4.9/817-usb-support-layerscape.patch b/target/linux/layerscape/patches-4.9/817-usb-support-layerscape.patch index 147b03ae2..eccac7400 100644 --- a/target/linux/layerscape/patches-4.9/817-usb-support-layerscape.patch +++ b/target/linux/layerscape/patches-4.9/817-usb-support-layerscape.patch @@ -1,4 +1,4 @@ -From f8daa8e984213554008e73cd155530dceec5a109 Mon Sep 17 00:00:00 2001 +From b14460ee524a34d3b94b44032b52155c4cd708e5 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Wed, 27 Sep 2017 10:34:07 +0800 Subject: [PATCH] usb: support layerscape @@ -15,6 +15,7 @@ Signed-off-by: Suresh Gupta Signed-off-by: Zhao Chenhui Signed-off-by: Yangbo Lu --- + drivers/net/usb/r8152.c | 4 + drivers/usb/common/common.c | 50 ++++++ drivers/usb/core/hub.c | 8 + drivers/usb/dwc3/core.c | 235 ++++++++++++++++++++++++++- @@ -32,8 +33,21 @@ Signed-off-by: Yangbo Lu drivers/usb/phy/phy-fsl-usb.h | 8 + include/linux/usb.h | 1 + include/linux/usb/of.h | 2 + - 17 files changed, 726 insertions(+), 73 deletions(-) + 18 files changed, 730 insertions(+), 73 deletions(-) +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -1812,6 +1812,10 @@ static int rx_bottom(struct r8152 *tp, i + unsigned int pkt_len; + struct sk_buff *skb; + ++ /* limite the skb numbers for rx_queue */ ++ if (unlikely(skb_queue_len(&tp->rx_queue) >= 1000)) ++ break; ++ + pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK; + if (pkt_len < ETH_ZLEN) + break; --- a/drivers/usb/common/common.c +++ b/drivers/usb/common/common.c @@ -105,6 +105,56 @@ static const char *const usb_dr_modes[] @@ -95,7 +109,7 @@ Signed-off-by: Yangbo Lu int ret; --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c -@@ -4412,6 +4412,14 @@ hub_port_init(struct usb_hub *hub, struc +@@ -4415,6 +4415,14 @@ hub_port_init(struct usb_hub *hub, struc else speed = usb_speed_string(udev->speed); diff --git a/target/linux/mediatek/patches-4.9/0028-net-next-dsa-add-Mediatek-tag-RX-TX-handler.patch b/target/linux/mediatek/patches-4.9/0028-net-next-dsa-add-Mediatek-tag-RX-TX-handler.patch index 2ba1cb80d..ef545e3db 100644 --- a/target/linux/mediatek/patches-4.9/0028-net-next-dsa-add-Mediatek-tag-RX-TX-handler.patch +++ b/target/linux/mediatek/patches-4.9/0028-net-next-dsa-add-Mediatek-tag-RX-TX-handler.patch @@ -34,7 +34,7 @@ Reviewed-by: Florian Fainelli --- a/net/dsa/Kconfig +++ b/net/dsa/Kconfig -@@ -41,4 +41,6 @@ config NET_DSA_TAG_TRAILER +@@ -42,4 +42,6 @@ config NET_DSA_TAG_TRAILER config NET_DSA_TAG_QCA bool diff --git a/target/linux/mvebu/patches-4.9/120-net-mvneta-add-BQL-support.patch b/target/linux/mvebu/patches-4.9/120-net-mvneta-add-BQL-support.patch index 5fedc8e8a..dba8f27b3 100644 --- a/target/linux/mvebu/patches-4.9/120-net-mvneta-add-BQL-support.patch +++ b/target/linux/mvebu/patches-4.9/120-net-mvneta-add-BQL-support.patch @@ -1,6 +1,6 @@ --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -1719,8 +1719,10 @@ static struct mvneta_tx_queue *mvneta_tx +@@ -1720,8 +1720,10 @@ static struct mvneta_tx_queue *mvneta_tx /* Free tx queue skbuffs */ static void mvneta_txq_bufs_free(struct mvneta_port *pp, @@ -12,7 +12,7 @@ int i; for (i = 0; i < num; i++) { -@@ -1728,6 +1730,11 @@ static void mvneta_txq_bufs_free(struct +@@ -1729,6 +1731,11 @@ static void mvneta_txq_bufs_free(struct txq->txq_get_index; struct sk_buff *skb = txq->tx_skb[txq->txq_get_index]; @@ -24,7 +24,7 @@ mvneta_txq_inc_get(txq); if (!IS_TSO_HEADER(txq, tx_desc->buf_phys_addr)) -@@ -1738,6 +1745,8 @@ static void mvneta_txq_bufs_free(struct +@@ -1739,6 +1746,8 @@ static void mvneta_txq_bufs_free(struct continue; dev_kfree_skb_any(skb); } @@ -33,7 +33,7 @@ } /* Handle end of transmission */ -@@ -1751,7 +1760,7 @@ static void mvneta_txq_done(struct mvnet +@@ -1752,7 +1761,7 @@ static void mvneta_txq_done(struct mvnet if (!tx_done) return; @@ -42,7 +42,7 @@ txq->count -= tx_done; -@@ -2358,6 +2367,8 @@ out: +@@ -2359,6 +2368,8 @@ out: struct mvneta_pcpu_stats *stats = this_cpu_ptr(pp->stats); struct netdev_queue *nq = netdev_get_tx_queue(dev, txq_id); @@ -51,7 +51,7 @@ txq->count += frags; mvneta_txq_pend_desc_add(pp, txq, frags); -@@ -2382,9 +2393,10 @@ static void mvneta_txq_done_force(struct +@@ -2383,9 +2394,10 @@ static void mvneta_txq_done_force(struct struct mvneta_tx_queue *txq) { @@ -63,7 +63,7 @@ /* reset txq */ txq->count = 0; -@@ -2880,6 +2892,8 @@ static int mvneta_txq_init(struct mvneta +@@ -2881,6 +2893,8 @@ static int mvneta_txq_init(struct mvneta static void mvneta_txq_deinit(struct mvneta_port *pp, struct mvneta_tx_queue *txq) { @@ -72,7 +72,7 @@ kfree(txq->tx_skb); if (txq->tso_hdrs) -@@ -2891,6 +2905,8 @@ static void mvneta_txq_deinit(struct mvn +@@ -2892,6 +2906,8 @@ static void mvneta_txq_deinit(struct mvn txq->size * MVNETA_DESC_ALIGNED_SIZE, txq->descs, txq->descs_phys); diff --git a/target/linux/mvebu/patches-4.9/300-mvneta-tx-queue-workaround.patch b/target/linux/mvebu/patches-4.9/300-mvneta-tx-queue-workaround.patch index 2582a4199..2601d92fc 100644 --- a/target/linux/mvebu/patches-4.9/300-mvneta-tx-queue-workaround.patch +++ b/target/linux/mvebu/patches-4.9/300-mvneta-tx-queue-workaround.patch @@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau --- --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3833,6 +3833,16 @@ static int mvneta_ethtool_get_rxfh(struc +@@ -3834,6 +3834,16 @@ static int mvneta_ethtool_get_rxfh(struc return 0; } @@ -26,7 +26,7 @@ Signed-off-by: Felix Fietkau static const struct net_device_ops mvneta_netdev_ops = { .ndo_open = mvneta_open, .ndo_stop = mvneta_stop, -@@ -3843,6 +3853,7 @@ static const struct net_device_ops mvnet +@@ -3844,6 +3854,7 @@ static const struct net_device_ops mvnet .ndo_fix_features = mvneta_fix_features, .ndo_get_stats64 = mvneta_get_stats64, .ndo_do_ioctl = mvneta_ioctl, diff --git a/target/linux/mvebu/patches-4.9/400-phy-provide-a-hook-for-link-up-link-down-events.patch b/target/linux/mvebu/patches-4.9/400-phy-provide-a-hook-for-link-up-link-down-events.patch index da4d24b7d..cac2e6ea6 100644 --- a/target/linux/mvebu/patches-4.9/400-phy-provide-a-hook-for-link-up-link-down-events.patch +++ b/target/linux/mvebu/patches-4.9/400-phy-provide-a-hook-for-link-up-link-down-events.patch @@ -167,7 +167,7 @@ Signed-off-by: Russell King --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -429,6 +429,7 @@ struct phy_device { +@@ -425,6 +425,7 @@ struct phy_device { u8 mdix; diff --git a/target/linux/mvebu/patches-4.9/401-net-phy-move-phy-MMD-accessors-to-phy-core.c.patch b/target/linux/mvebu/patches-4.9/401-net-phy-move-phy-MMD-accessors-to-phy-core.c.patch index 360108fcc..20ed3119d 100644 --- a/target/linux/mvebu/patches-4.9/401-net-phy-move-phy-MMD-accessors-to-phy-core.c.patch +++ b/target/linux/mvebu/patches-4.9/401-net-phy-move-phy-MMD-accessors-to-phy-core.c.patch @@ -256,7 +256,7 @@ Signed-off-by: Russell King +EXPORT_SYMBOL(phy_write_mmd); --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -630,14 +630,7 @@ struct phy_fixup { +@@ -626,14 +626,7 @@ struct phy_fixup { * * Same rules as for phy_read(); */ @@ -272,7 +272,7 @@ Signed-off-by: Russell King /** * phy_read_mmd_indirect - reads data from the MMD registers -@@ -731,16 +724,7 @@ static inline bool phy_is_pseudo_fixed_l +@@ -727,16 +720,7 @@ static inline bool phy_is_pseudo_fixed_l * * Same rules as for phy_write(); */ diff --git a/target/linux/mvebu/patches-4.9/402-net-phy-make-phy_-read-write-_mmd-generic-MMD-access.patch b/target/linux/mvebu/patches-4.9/402-net-phy-make-phy_-read-write-_mmd-generic-MMD-access.patch index fcb274d55..33d467794 100644 --- a/target/linux/mvebu/patches-4.9/402-net-phy-make-phy_-read-write-_mmd-generic-MMD-access.patch +++ b/target/linux/mvebu/patches-4.9/402-net-phy-make-phy_-read-write-_mmd-generic-MMD-access.patch @@ -64,7 +64,7 @@ Signed-off-by: Russell King EXPORT_SYMBOL(phy_write_mmd); --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -573,6 +573,30 @@ struct phy_driver { +@@ -569,6 +569,30 @@ struct phy_driver { */ void (*link_change_notify)(struct phy_device *dev); diff --git a/target/linux/mvebu/patches-4.9/407-net-phy-add-802.3-clause-45-support-to-phylib.patch b/target/linux/mvebu/patches-4.9/407-net-phy-add-802.3-clause-45-support-to-phylib.patch index ae4bb846f..0715a6a8a 100644 --- a/target/linux/mvebu/patches-4.9/407-net-phy-add-802.3-clause-45-support-to-phylib.patch +++ b/target/linux/mvebu/patches-4.9/407-net-phy-add-802.3-clause-45-support-to-phylib.patch @@ -295,7 +295,7 @@ Signed-off-by: Russell King } --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -810,6 +810,8 @@ static inline const char *phydev_name(co +@@ -806,6 +806,8 @@ static inline const char *phydev_name(co void phy_attached_print(struct phy_device *phydev, const char *fmt, ...) __printf(2, 3); void phy_attached_info(struct phy_device *phydev); @@ -304,7 +304,7 @@ Signed-off-by: Russell King int genphy_config_init(struct phy_device *phydev); int genphy_setup_forced(struct phy_device *phydev); int genphy_restart_aneg(struct phy_device *phydev); -@@ -824,6 +826,16 @@ static inline int genphy_no_soft_reset(s +@@ -820,6 +822,16 @@ static inline int genphy_no_soft_reset(s { return 0; } diff --git a/target/linux/mvebu/patches-4.9/411-net-phy-split-out-PHY-speed-and-duplex-string-genera.patch b/target/linux/mvebu/patches-4.9/411-net-phy-split-out-PHY-speed-and-duplex-string-genera.patch index f4da7e92e..2f0039b11 100644 --- a/target/linux/mvebu/patches-4.9/411-net-phy-split-out-PHY-speed-and-duplex-string-genera.patch +++ b/target/linux/mvebu/patches-4.9/411-net-phy-split-out-PHY-speed-and-duplex-string-genera.patch @@ -91,7 +91,7 @@ Signed-off-by: Russell King { --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -645,6 +645,9 @@ struct phy_fixup { +@@ -641,6 +641,9 @@ struct phy_fixup { int (*run)(struct phy_device *phydev); }; diff --git a/target/linux/mvebu/patches-4.9/412-net-phy-move-phy_lookup_setting-and-guts-of-phy_supp.patch b/target/linux/mvebu/patches-4.9/412-net-phy-move-phy_lookup_setting-and-guts-of-phy_supp.patch index 051a9ed68..8ead41cd6 100644 --- a/target/linux/mvebu/patches-4.9/412-net-phy-move-phy_lookup_setting-and-guts-of-phy_supp.patch +++ b/target/linux/mvebu/patches-4.9/412-net-phy-move-phy_lookup_setting-and-guts-of-phy_supp.patch @@ -305,7 +305,7 @@ Signed-off-by: Russell King { --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -648,6 +648,21 @@ struct phy_fixup { +@@ -644,6 +644,21 @@ struct phy_fixup { const char *phy_speed_to_str(int speed); const char *phy_duplex_to_str(unsigned int duplex); diff --git a/target/linux/mvebu/patches-4.9/415-phylink-add-phylink-infrastructure.patch b/target/linux/mvebu/patches-4.9/415-phylink-add-phylink-infrastructure.patch index 59e8aa81b..cf9b2061c 100644 --- a/target/linux/mvebu/patches-4.9/415-phylink-add-phylink-infrastructure.patch +++ b/target/linux/mvebu/patches-4.9/415-phylink-add-phylink-infrastructure.patch @@ -999,7 +999,7 @@ Signed-off-by: Russell King +MODULE_LICENSE("GPL"); --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -153,6 +153,7 @@ static inline const char *phy_modes(phy_ +@@ -149,6 +149,7 @@ static inline const char *phy_modes(phy_ #define MII_ADDR_C45 (1<<30) struct device; @@ -1007,7 +1007,7 @@ Signed-off-by: Russell King struct sk_buff; /* -@@ -425,6 +426,7 @@ struct phy_device { +@@ -421,6 +422,7 @@ struct phy_device { struct mutex lock; diff --git a/target/linux/mvebu/patches-4.9/419-net-mvneta-convert-to-phylink.patch b/target/linux/mvebu/patches-4.9/419-net-mvneta-convert-to-phylink.patch index bc8d5fdac..8084a17af 100644 --- a/target/linux/mvebu/patches-4.9/419-net-mvneta-convert-to-phylink.patch +++ b/target/linux/mvebu/patches-4.9/419-net-mvneta-convert-to-phylink.patch @@ -21,15 +21,15 @@ Signed-off-by: Russell King Marvell ARMADA XP, ARMADA 370 and ARMADA 38x SoC family. --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -28,6 +28,7 @@ - #include +@@ -29,6 +29,7 @@ #include #include + #include +#include #include #include #include -@@ -188,6 +189,7 @@ +@@ -189,6 +190,7 @@ #define MVNETA_GMAC_CTRL_0 0x2c00 #define MVNETA_GMAC_MAX_RX_SIZE_SHIFT 2 #define MVNETA_GMAC_MAX_RX_SIZE_MASK 0x7ffc @@ -37,7 +37,7 @@ Signed-off-by: Russell King #define MVNETA_GMAC0_PORT_ENABLE BIT(0) #define MVNETA_GMAC_CTRL_2 0x2c08 #define MVNETA_GMAC2_INBAND_AN_ENABLE BIT(0) -@@ -203,13 +205,19 @@ +@@ -204,13 +206,19 @@ #define MVNETA_GMAC_TX_FLOW_CTRL_ENABLE BIT(5) #define MVNETA_GMAC_RX_FLOW_CTRL_ACTIVE BIT(6) #define MVNETA_GMAC_TX_FLOW_CTRL_ACTIVE BIT(7) @@ -57,7 +57,7 @@ Signed-off-by: Russell King #define MVNETA_GMAC_AN_FLOW_CTRL_EN BIT(11) #define MVNETA_GMAC_CONFIG_FULL_DUPLEX BIT(12) #define MVNETA_GMAC_AN_DUPLEX_EN BIT(13) -@@ -399,14 +407,9 @@ struct mvneta_port { +@@ -400,14 +408,9 @@ struct mvneta_port { u16 tx_ring_size; u16 rx_ring_size; @@ -74,7 +74,7 @@ Signed-off-by: Russell King struct mvneta_bm *bm_priv; struct mvneta_bm_pool *pool_long; -@@ -1240,44 +1243,6 @@ static void mvneta_set_other_mcast_table +@@ -1241,44 +1244,6 @@ static void mvneta_set_other_mcast_table mvreg_write(pp, MVNETA_DA_FILT_OTH_MCAST + offset, val); } @@ -119,7 +119,7 @@ Signed-off-by: Russell King static void mvneta_percpu_unmask_interrupt(void *arg) { struct mvneta_port *pp = arg; -@@ -1425,7 +1390,6 @@ static void mvneta_defaults_set(struct m +@@ -1426,7 +1391,6 @@ static void mvneta_defaults_set(struct m val &= ~MVNETA_PHY_POLLING_ENABLE; mvreg_write(pp, MVNETA_UNIT_CONTROL, val); @@ -127,7 +127,7 @@ Signed-off-by: Russell King mvneta_set_ucast_table(pp, -1); mvneta_set_special_mcast_table(pp, -1); mvneta_set_other_mcast_table(pp, -1); -@@ -2630,26 +2594,11 @@ static irqreturn_t mvneta_isr(int irq, v +@@ -2631,26 +2595,11 @@ static irqreturn_t mvneta_isr(int irq, v return IRQ_HANDLED; } @@ -156,7 +156,7 @@ Signed-off-by: Russell King } /* NAPI handler -@@ -2665,7 +2614,6 @@ static int mvneta_poll(struct napi_struc +@@ -2666,7 +2615,6 @@ static int mvneta_poll(struct napi_struc u32 cause_rx_tx; int rx_queue; struct mvneta_port *pp = netdev_priv(napi->dev); @@ -164,7 +164,7 @@ Signed-off-by: Russell King struct mvneta_pcpu_port *port = this_cpu_ptr(pp->ports); if (!netif_running(pp->dev)) { -@@ -2679,12 +2627,11 @@ static int mvneta_poll(struct napi_struc +@@ -2680,12 +2628,11 @@ static int mvneta_poll(struct napi_struc u32 cause_misc = mvreg_read(pp, MVNETA_INTR_MISC_CAUSE); mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0); @@ -182,7 +182,7 @@ Signed-off-by: Russell King } /* Release Tx descriptors */ -@@ -2980,7 +2927,6 @@ static int mvneta_setup_txqs(struct mvne +@@ -2981,7 +2928,6 @@ static int mvneta_setup_txqs(struct mvne static void mvneta_start_dev(struct mvneta_port *pp) { int cpu; @@ -190,7 +190,7 @@ Signed-off-by: Russell King mvneta_max_rx_size_set(pp, pp->pkt_size); mvneta_txq_max_tx_size_set(pp, pp->pkt_size); -@@ -3003,16 +2949,15 @@ static void mvneta_start_dev(struct mvne +@@ -3004,16 +2950,15 @@ static void mvneta_start_dev(struct mvne MVNETA_CAUSE_LINK_CHANGE | MVNETA_CAUSE_PSC_SYNC_CHANGE); @@ -209,7 +209,7 @@ Signed-off-by: Russell King for_each_online_cpu(cpu) { struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu); -@@ -3182,99 +3127,210 @@ static int mvneta_set_mac_addr(struct ne +@@ -3183,99 +3128,210 @@ static int mvneta_set_mac_addr(struct ne return 0; } @@ -490,7 +490,7 @@ Signed-off-by: Russell King } /* Electing a CPU must be done in an atomic way: it should be done -@@ -3532,10 +3588,9 @@ static int mvneta_stop(struct net_device +@@ -3533,10 +3589,9 @@ static int mvneta_stop(struct net_device static int mvneta_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { @@ -503,7 +503,7 @@ Signed-off-by: Russell King } /* Ethtool methods */ -@@ -3546,44 +3601,18 @@ mvneta_ethtool_set_link_ksettings(struct +@@ -3547,44 +3602,18 @@ mvneta_ethtool_set_link_ksettings(struct const struct ethtool_link_ksettings *cmd) { struct mvneta_port *pp = netdev_priv(ndev); @@ -557,7 +557,7 @@ Signed-off-by: Russell King } /* Set interrupt coalescing for ethtools */ -@@ -3691,26 +3720,28 @@ static void mvneta_ethtool_update_stats( +@@ -3692,26 +3721,28 @@ static void mvneta_ethtool_update_stats( { const struct mvneta_statistic *s; void __iomem *base = pp->base; @@ -591,7 +591,7 @@ Signed-off-by: Russell King } } -@@ -3870,7 +3901,7 @@ const struct ethtool_ops mvneta_eth_tool +@@ -3871,7 +3902,7 @@ const struct ethtool_ops mvneta_eth_tool .get_rxnfc = mvneta_ethtool_get_rxnfc, .get_rxfh = mvneta_ethtool_get_rxfh, .set_rxfh = mvneta_ethtool_set_rxfh, @@ -600,7 +600,7 @@ Signed-off-by: Russell King .set_link_ksettings = mvneta_ethtool_set_link_ksettings, }; -@@ -3997,14 +4028,13 @@ static int mvneta_probe(struct platform_ +@@ -3998,14 +4029,13 @@ static int mvneta_probe(struct platform_ const struct mbus_dram_target_info *dram_target_info; struct resource *res; struct device_node *dn = pdev->dev.of_node; @@ -616,7 +616,7 @@ Signed-off-by: Russell King int tx_csum_limit; int phy_mode; int err; -@@ -4020,31 +4050,11 @@ static int mvneta_probe(struct platform_ +@@ -4021,31 +4051,11 @@ static int mvneta_probe(struct platform_ goto err_free_netdev; } @@ -649,7 +649,7 @@ Signed-off-by: Russell King } dev->tx_queue_len = MVNETA_MAX_TXD; -@@ -4055,12 +4065,7 @@ static int mvneta_probe(struct platform_ +@@ -4056,12 +4066,7 @@ static int mvneta_probe(struct platform_ pp = netdev_priv(dev); spin_lock_init(&pp->lock); @@ -663,7 +663,7 @@ Signed-off-by: Russell King pp->rxq_def = rxq_def; -@@ -4071,7 +4076,7 @@ static int mvneta_probe(struct platform_ +@@ -4072,7 +4077,7 @@ static int mvneta_probe(struct platform_ pp->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(pp->clk)) { err = PTR_ERR(pp->clk); @@ -672,7 +672,7 @@ Signed-off-by: Russell King } clk_prepare_enable(pp->clk); -@@ -4179,6 +4184,14 @@ static int mvneta_probe(struct platform_ +@@ -4180,6 +4185,14 @@ static int mvneta_probe(struct platform_ dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; dev->gso_max_segs = MVNETA_MAX_TSO_SEGS; @@ -687,7 +687,7 @@ Signed-off-by: Russell King err = register_netdev(dev); if (err < 0) { dev_err(&pdev->dev, "failed to register\n"); -@@ -4190,14 +4203,6 @@ static int mvneta_probe(struct platform_ +@@ -4191,14 +4204,6 @@ static int mvneta_probe(struct platform_ platform_set_drvdata(pdev, pp->dev); @@ -702,7 +702,7 @@ Signed-off-by: Russell King return 0; err_netdev: -@@ -4208,16 +4213,14 @@ err_netdev: +@@ -4209,16 +4214,14 @@ err_netdev: 1 << pp->id); } err_free_stats: @@ -721,7 +721,7 @@ Signed-off-by: Russell King err_free_irq: irq_dispose_mapping(dev->irq); err_free_netdev: -@@ -4229,7 +4232,6 @@ err_free_netdev: +@@ -4230,7 +4233,6 @@ err_free_netdev: static int mvneta_remove(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); @@ -729,7 +729,7 @@ Signed-off-by: Russell King struct mvneta_port *pp = netdev_priv(dev); unregister_netdev(dev); -@@ -4237,10 +4239,8 @@ static int mvneta_remove(struct platform +@@ -4238,10 +4240,8 @@ static int mvneta_remove(struct platform clk_disable_unprepare(pp->clk); free_percpu(pp->ports); free_percpu(pp->stats); diff --git a/target/linux/mvebu/patches-4.9/420-net-mvneta-disable-MVNETA_CAUSE_PSC_SYNC_CHANGE-inte.patch b/target/linux/mvebu/patches-4.9/420-net-mvneta-disable-MVNETA_CAUSE_PSC_SYNC_CHANGE-inte.patch index 255872026..6d35b5005 100644 --- a/target/linux/mvebu/patches-4.9/420-net-mvneta-disable-MVNETA_CAUSE_PSC_SYNC_CHANGE-inte.patch +++ b/target/linux/mvebu/patches-4.9/420-net-mvneta-disable-MVNETA_CAUSE_PSC_SYNC_CHANGE-inte.patch @@ -12,7 +12,7 @@ Signed-off-by: Russell King --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -2629,9 +2629,11 @@ static int mvneta_poll(struct napi_struc +@@ -2630,9 +2630,11 @@ static int mvneta_poll(struct napi_struc mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0); if (cause_misc & (MVNETA_CAUSE_PHY_STATUS_CHANGE | @@ -26,7 +26,7 @@ Signed-off-by: Russell King } /* Release Tx descriptors */ -@@ -2946,8 +2948,7 @@ static void mvneta_start_dev(struct mvne +@@ -2947,8 +2949,7 @@ static void mvneta_start_dev(struct mvne mvreg_write(pp, MVNETA_INTR_MISC_MASK, MVNETA_CAUSE_PHY_STATUS_CHANGE | @@ -36,7 +36,7 @@ Signed-off-by: Russell King phylink_start(pp->phylink); netif_tx_start_all_queues(pp->dev); -@@ -3438,8 +3439,7 @@ static int mvneta_cpu_online(unsigned in +@@ -3439,8 +3440,7 @@ static int mvneta_cpu_online(unsigned in on_each_cpu(mvneta_percpu_unmask_interrupt, pp, true); mvreg_write(pp, MVNETA_INTR_MISC_MASK, MVNETA_CAUSE_PHY_STATUS_CHANGE | @@ -46,7 +46,7 @@ Signed-off-by: Russell King netif_tx_start_all_queues(pp->dev); spin_unlock(&pp->lock); return 0; -@@ -3480,8 +3480,7 @@ static int mvneta_cpu_dead(unsigned int +@@ -3481,8 +3481,7 @@ static int mvneta_cpu_dead(unsigned int on_each_cpu(mvneta_percpu_unmask_interrupt, pp, true); mvreg_write(pp, MVNETA_INTR_MISC_MASK, MVNETA_CAUSE_PHY_STATUS_CHANGE | diff --git a/target/linux/mvebu/patches-4.9/422-net-mvneta-add-nway_reset-support.patch b/target/linux/mvebu/patches-4.9/422-net-mvneta-add-nway_reset-support.patch index 9a604eb03..20c23ba2a 100644 --- a/target/linux/mvebu/patches-4.9/422-net-mvneta-add-nway_reset-support.patch +++ b/target/linux/mvebu/patches-4.9/422-net-mvneta-add-nway_reset-support.patch @@ -11,7 +11,7 @@ Signed-off-by: Russell King --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3614,6 +3614,13 @@ mvneta_ethtool_get_link_ksettings(struct +@@ -3615,6 +3615,13 @@ mvneta_ethtool_get_link_ksettings(struct return phylink_ethtool_ksettings_get(pp->phylink, cmd); } @@ -25,7 +25,7 @@ Signed-off-by: Russell King /* Set interrupt coalescing for ethtools */ static int mvneta_ethtool_set_coalesce(struct net_device *dev, struct ethtool_coalesce *c) -@@ -3887,6 +3894,7 @@ static const struct net_device_ops mvnet +@@ -3888,6 +3895,7 @@ static const struct net_device_ops mvnet }; const struct ethtool_ops mvneta_eth_tool_ops = { diff --git a/target/linux/mvebu/patches-4.9/424-net-mvneta-add-flow-control-support-via-phylink.patch b/target/linux/mvebu/patches-4.9/424-net-mvneta-add-flow-control-support-via-phylink.patch index f10b57c99..3f778953e 100644 --- a/target/linux/mvebu/patches-4.9/424-net-mvneta-add-flow-control-support-via-phylink.patch +++ b/target/linux/mvebu/patches-4.9/424-net-mvneta-add-flow-control-support-via-phylink.patch @@ -11,7 +11,7 @@ Signed-off-by: Russell King --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3178,6 +3178,12 @@ static int mvneta_mac_link_state(struct +@@ -3179,6 +3179,12 @@ static int mvneta_mac_link_state(struct state->link = !!(gmac_stat & MVNETA_GMAC_LINK_UP); state->duplex = !!(gmac_stat & MVNETA_GMAC_FULL_DUPLEX); @@ -24,7 +24,7 @@ Signed-off-by: Russell King return 1; } -@@ -3220,6 +3226,8 @@ static void mvneta_mac_config(struct net +@@ -3221,6 +3227,8 @@ static void mvneta_mac_config(struct net if (phylink_test(state->advertising, Pause)) new_an |= MVNETA_GMAC_ADVERT_SYM_FLOW_CTRL; @@ -33,7 +33,7 @@ Signed-off-by: Russell King switch (mode) { case MLO_AN_SGMII: -@@ -3244,7 +3252,7 @@ static void mvneta_mac_config(struct net +@@ -3245,7 +3253,7 @@ static void mvneta_mac_config(struct net /* The MAC only supports FD mode */ MVNETA_GMAC_CONFIG_FULL_DUPLEX; @@ -42,7 +42,7 @@ Signed-off-by: Russell King new_an |= MVNETA_GMAC_AN_FLOW_CTRL_EN; break; -@@ -3710,6 +3718,22 @@ static int mvneta_ethtool_set_ringparam( +@@ -3711,6 +3719,22 @@ static int mvneta_ethtool_set_ringparam( return 0; } @@ -65,7 +65,7 @@ Signed-off-by: Russell King static void mvneta_ethtool_get_strings(struct net_device *netdev, u32 sset, u8 *data) { -@@ -3901,6 +3925,8 @@ const struct ethtool_ops mvneta_eth_tool +@@ -3902,6 +3926,8 @@ const struct ethtool_ops mvneta_eth_tool .get_drvinfo = mvneta_ethtool_get_drvinfo, .get_ringparam = mvneta_ethtool_get_ringparam, .set_ringparam = mvneta_ethtool_set_ringparam, diff --git a/target/linux/mvebu/patches-4.9/425-net-mvneta-enable-flow-control-for-PHY-connections.patch b/target/linux/mvebu/patches-4.9/425-net-mvneta-enable-flow-control-for-PHY-connections.patch index 29d45f921..f2d14afda 100644 --- a/target/linux/mvebu/patches-4.9/425-net-mvneta-enable-flow-control-for-PHY-connections.patch +++ b/target/linux/mvebu/patches-4.9/425-net-mvneta-enable-flow-control-for-PHY-connections.patch @@ -12,7 +12,7 @@ Signed-off-by: Russell King --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3152,10 +3152,11 @@ static void mvneta_validate_support(stru +@@ -3153,10 +3153,11 @@ static void mvneta_validate_support(stru phylink_set(mask, 10baseT_Full); phylink_set(mask, 100baseT_Half); phylink_set(mask, 100baseT_Full); diff --git a/target/linux/mvebu/patches-4.9/426-net-mvneta-enable-flow-control-for-fixed-connections.patch b/target/linux/mvebu/patches-4.9/426-net-mvneta-enable-flow-control-for-fixed-connections.patch index 60f549cc8..bac74ca4e 100644 --- a/target/linux/mvebu/patches-4.9/426-net-mvneta-enable-flow-control-for-fixed-connections.patch +++ b/target/linux/mvebu/patches-4.9/426-net-mvneta-enable-flow-control-for-fixed-connections.patch @@ -11,7 +11,7 @@ Signed-off-by: Russell King --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3142,6 +3142,8 @@ static void mvneta_validate_support(stru +@@ -3143,6 +3143,8 @@ static void mvneta_validate_support(stru phylink_set(mask, BNC); phylink_set(mask, Backplane); @@ -20,7 +20,7 @@ Signed-off-by: Russell King /* Half-duplex at speeds higher than 100Mbit is unsupported */ phylink_set(mask, 1000baseT_Full); phylink_set(mask, 1000baseX_Full); -@@ -3154,9 +3156,6 @@ static void mvneta_validate_support(stru +@@ -3155,9 +3157,6 @@ static void mvneta_validate_support(stru phylink_set(mask, 100baseT_Full); } diff --git a/target/linux/mvebu/patches-4.9/427-phylink-add-EEE-support.patch b/target/linux/mvebu/patches-4.9/427-phylink-add-EEE-support.patch index 767830419..bc7e5eeeb 100644 --- a/target/linux/mvebu/patches-4.9/427-phylink-add-EEE-support.patch +++ b/target/linux/mvebu/patches-4.9/427-phylink-add-EEE-support.patch @@ -10,7 +10,7 @@ Signed-off-by: Russell King --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3304,7 +3304,8 @@ static void mvneta_mac_link_down(struct +@@ -3305,7 +3305,8 @@ static void mvneta_mac_link_down(struct } } diff --git a/target/linux/mvebu/patches-4.9/428-net-mvneta-add-EEE-support.patch b/target/linux/mvebu/patches-4.9/428-net-mvneta-add-EEE-support.patch index e1e11ee29..3a20a06be 100644 --- a/target/linux/mvebu/patches-4.9/428-net-mvneta-add-EEE-support.patch +++ b/target/linux/mvebu/patches-4.9/428-net-mvneta-add-EEE-support.patch @@ -13,7 +13,7 @@ Signed-off-by: Russell King --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -243,6 +243,12 @@ +@@ -244,6 +244,12 @@ #define MVNETA_TXQ_TOKEN_SIZE_REG(q) (0x3e40 + ((q) << 2)) #define MVNETA_TXQ_TOKEN_SIZE_MAX 0x7fffffff @@ -26,7 +26,7 @@ Signed-off-by: Russell King #define MVNETA_CAUSE_TXQ_SENT_DESC_ALL_MASK 0xff /* Descriptor ring Macros */ -@@ -316,6 +322,11 @@ +@@ -317,6 +323,11 @@ #define MVNETA_RX_GET_BM_POOL_ID(rxd) \ (((rxd)->status & MVNETA_RXD_BM_POOL_MASK) >> MVNETA_RXD_BM_POOL_SHIFT) @@ -38,7 +38,7 @@ Signed-off-by: Russell King struct mvneta_statistic { unsigned short offset; unsigned short type; -@@ -324,6 +335,7 @@ struct mvneta_statistic { +@@ -325,6 +336,7 @@ struct mvneta_statistic { #define T_REG_32 32 #define T_REG_64 64 @@ -46,7 +46,7 @@ Signed-off-by: Russell King static const struct mvneta_statistic mvneta_statistics[] = { { 0x3000, T_REG_64, "good_octets_received", }, -@@ -358,6 +370,7 @@ static const struct mvneta_statistic mvn +@@ -359,6 +371,7 @@ static const struct mvneta_statistic mvn { 0x304c, T_REG_32, "broadcast_frames_sent", }, { 0x3054, T_REG_32, "fc_sent", }, { 0x300c, T_REG_32, "internal_mac_transmit_err", }, @@ -54,7 +54,7 @@ Signed-off-by: Russell King }; struct mvneta_pcpu_stats { -@@ -416,6 +429,10 @@ struct mvneta_port { +@@ -417,6 +430,10 @@ struct mvneta_port { struct mvneta_bm_pool *pool_short; int bm_win_id; @@ -65,7 +65,7 @@ Signed-off-by: Russell King u64 ethtool_stats[ARRAY_SIZE(mvneta_statistics)]; u32 indir[MVNETA_RSS_LU_TABLE_SIZE]; -@@ -3289,6 +3306,18 @@ static void mvneta_mac_config(struct net +@@ -3290,6 +3307,18 @@ static void mvneta_mac_config(struct net mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, new_an); } @@ -84,7 +84,7 @@ Signed-off-by: Russell King static void mvneta_mac_link_down(struct net_device *ndev, unsigned int mode) { struct mvneta_port *pp = netdev_priv(ndev); -@@ -3302,6 +3331,9 @@ static void mvneta_mac_link_down(struct +@@ -3303,6 +3332,9 @@ static void mvneta_mac_link_down(struct val |= MVNETA_GMAC_FORCE_LINK_DOWN; mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val); } @@ -94,7 +94,7 @@ Signed-off-by: Russell King } static void mvneta_mac_link_up(struct net_device *ndev, unsigned int mode, -@@ -3318,6 +3350,11 @@ static void mvneta_mac_link_up(struct ne +@@ -3319,6 +3351,11 @@ static void mvneta_mac_link_up(struct ne } mvneta_port_up(pp); @@ -106,7 +106,7 @@ Signed-off-by: Russell King } static const struct phylink_mac_ops mvneta_phylink_ops = { -@@ -3770,6 +3807,13 @@ static void mvneta_ethtool_update_stats( +@@ -3771,6 +3808,13 @@ static void mvneta_ethtool_update_stats( high = readl_relaxed(base + s->offset + 4); val = (u64)high << 32 | low; break; @@ -120,7 +120,7 @@ Signed-off-by: Russell King } pp->ethtool_stats[i] += val; -@@ -3905,6 +3949,47 @@ static u16 mvneta_select_queue(struct ne +@@ -3906,6 +3950,47 @@ static u16 mvneta_select_queue(struct ne } @@ -168,7 +168,7 @@ Signed-off-by: Russell King static const struct net_device_ops mvneta_netdev_ops = { .ndo_open = mvneta_open, .ndo_stop = mvneta_stop, -@@ -3937,6 +4022,8 @@ const struct ethtool_ops mvneta_eth_tool +@@ -3938,6 +4023,8 @@ const struct ethtool_ops mvneta_eth_tool .set_rxfh = mvneta_ethtool_set_rxfh, .get_link_ksettings = mvneta_ethtool_get_link_ksettings, .set_link_ksettings = mvneta_ethtool_set_link_ksettings, diff --git a/target/linux/mvebu/patches-4.9/430-net-mvneta-add-module-EEPROM-reading-support.patch b/target/linux/mvebu/patches-4.9/430-net-mvneta-add-module-EEPROM-reading-support.patch index 1f35a18b9..834bbe9a3 100644 --- a/target/linux/mvebu/patches-4.9/430-net-mvneta-add-module-EEPROM-reading-support.patch +++ b/target/linux/mvebu/patches-4.9/430-net-mvneta-add-module-EEPROM-reading-support.patch @@ -7,7 +7,7 @@ Signed-off-by: Russell King --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3949,6 +3949,22 @@ static u16 mvneta_select_queue(struct ne +@@ -3950,6 +3950,22 @@ static u16 mvneta_select_queue(struct ne } @@ -30,7 +30,7 @@ Signed-off-by: Russell King static int mvneta_ethtool_get_eee(struct net_device *dev, struct ethtool_eee *eee) { -@@ -4022,6 +4038,8 @@ const struct ethtool_ops mvneta_eth_tool +@@ -4023,6 +4039,8 @@ const struct ethtool_ops mvneta_eth_tool .set_rxfh = mvneta_ethtool_set_rxfh, .get_link_ksettings = mvneta_ethtool_get_link_ksettings, .set_link_ksettings = mvneta_ethtool_set_link_ksettings, diff --git a/target/linux/ramips/base-files/etc/board.d/01_leds b/target/linux/ramips/base-files/etc/board.d/01_leds index 83e1a9400..74e405e42 100755 --- a/target/linux/ramips/base-files/etc/board.d/01_leds +++ b/target/linux/ramips/base-files/etc/board.d/01_leds @@ -86,6 +86,12 @@ c108) ucidef_set_led_netdev "lan" "lan" "$board:green:lan" "eth0" ucidef_set_led_netdev "modem" "modem" "$board:green:modem" "wwan0" ;; +c20) + ucidef_set_led_switch "lan" "lan" "$board:blue:lan" "switch0" "0x1e" + ucidef_set_led_switch "wan" "wan" "$board:blue:wan" "switch0" "0x01" + set_usb_led "$board:blue:usb" + ucidef_set_led_netdev "wlan2g" "wlan2g" "$board:blue:wlan2g" "wlan0" + ;; c20i) ucidef_set_led_switch "lan" "lan" "$board:blue:lan" "switch0" "0x1e" ucidef_set_led_switch "wan" "wan" "$board:blue:wan" "switch0" "0x01" @@ -247,8 +253,9 @@ miniembplug) set_usb_led "$board:green:mobile" ;; mir3g) - ucidef_set_led_netdev "eth" "Ethernet" "$board:red:wan" "eth0" - set_usb_led "$board:blue:usb" + ucidef_set_led_switch "wan-amber" "WAN (amber)" "$board:amber:wan" "switch0" "0x02" "0x08" + ucidef_set_led_switch "lan1-amber" "LAN1 (amber)" "$board:amber:lan1" "switch0" "0x08" "0x08" + ucidef_set_led_switch "lan2-amber" "LAN2 (amber)" "$board:amber:lan2" "switch0" "0x04" "0x08" ;; miwifi-mini) ucidef_set_led_default "power" "power" "$board:red:status" "1" @@ -361,6 +368,19 @@ tl-wr841n-v13) ucidef_set_led_switch "lan4" "lan4" "$board:green:lan4" "switch0" "0x10" ucidef_set_led_switch "wan" "wan" "$board:green:wan" "switch0" "0x01" ;; +u25awf-h1) + set_wifi_led "u25awf:red:wifi" + ucidef_set_led_netdev "eth" "eth" "u25awf:green:lan" "eth0" + ;; +u7628-01-128M-16M) + ucidef_set_led_switch "lan1" "lan1" "u7628-01:green:lan1" "switch0" "0x2" + ucidef_set_led_switch "lan2" "lan2" "u7628-01:green:lan2" "switch0" "0x4" + ucidef_set_led_switch "lan3" "lan3" "u7628-01:green:lan3" "switch0" "0x8" + ucidef_set_led_switch "lan4" "lan4" "u7628-01:green:lan4" "switch0" "0x10" + ucidef_set_led_switch "wan" "wan" "u7628-01:green:wan" "switch0" "0x01" + set_usb_led "u7628-01:green:usb" + set_wifi_led "u7628-01:green:wlan" + ;; vocore-8M|\ vocore-16M) ucidef_set_led_netdev "eth" "ETH" "vocore:orange:eth" "eth0" @@ -379,6 +399,11 @@ w502u) wcr-150gn) set_usb_led "$board:amber:user" ;; +we1026-5g-16m) + ucidef_set_led_netdev "lan" "LAN" "we1026-5g:green:lan" "eth0" + set_wifi_led "we1026-5g:green:wifi" + set_usb_led "we1026-5g:green:usb" "1-1.1" + ;; whr-1166d|\ whr-300hp2|\ whr-600d) @@ -445,9 +470,9 @@ zte-q7) set_wifi_led "$board:blue:status" ;; youku-yk1) - ucidef_set_led_default "power" "power" "$board:blue:power" "1" set_wifi_led "$board:blue:air" set_usb_led "$board:blue:usb" + ucidef_set_led_switch "wan" "wan" "$board:blue:wan" "switch0" "0x10" ;; esac diff --git a/target/linux/ramips/base-files/etc/board.d/02_network b/target/linux/ramips/base-files/etc/board.d/02_network index 9284b1812..6ad64e672 100755 --- a/target/linux/ramips/base-files/etc/board.d/02_network +++ b/target/linux/ramips/base-files/etc/board.d/02_network @@ -102,6 +102,7 @@ ramips_setup_interfaces() r6220|\ sap-g3200u3|\ sk-wb8|\ + u7621-06-256M-16M|\ vr500|\ wf-2881|\ witi|\ @@ -113,6 +114,7 @@ ramips_setup_interfaces() youku-yk1|\ zbt-ape522ii|\ zbt-we1326|\ + zbt-we3526|\ zbt-we826-16M|\ zbt-we826-32M|\ zbt-wg2626|\ @@ -124,7 +126,7 @@ ramips_setup_interfaces() ;; mir3g) ucidef_add_switch "switch0" \ - "1:wan" "2:lan:2" "3:lan:1" "6@eth0" + "2:lan:2" "3:lan:1" "1:wan" "6t@eth0" ;; psg1218b) ucidef_add_switch "switch0" \ @@ -171,7 +173,9 @@ ramips_setup_interfaces() rb750gr3|\ rt-n14u|\ tl-wr840n-v4|\ + tl-wr840n-v5|\ tl-wr841n-v13|\ + u7628-01-128M-16M|\ ubnt-erx|\ ubnt-erx-sfp|\ ur-326n4g|\ @@ -184,6 +188,7 @@ ramips_setup_interfaces() ucidef_add_switch "switch0" \ "1:lan" "2:lan" "3:lan" "4:lan" "0:wan" "6@eth0" ;; + c20|\ c50) ucidef_add_switch "switch0" \ "1:lan:3" "2:lan:4" "3:lan:1" "4:lan:2" "0:wan" "6@eth0" @@ -236,6 +241,7 @@ ramips_setup_interfaces() mzk-ex750np|\ na930|\ pbr-d1|\ + u25awf-h1|\ wli-tx4-ag300n|\ wmdr-143n|\ wmr-300|\ @@ -323,7 +329,8 @@ ramips_setup_interfaces() ucidef_add_switch "switch0" \ "3:lan" "4:wan" "6@eth0" ;; - wcr-150gn) + wcr-150gn|\ + we1026-5g-16m) ucidef_add_switch "switch0" \ "0:lan" "6t@eth0" ;; @@ -427,7 +434,7 @@ ramips_setup_macs() wan_mac=$(macaddr_add "$lan_mac" 1) ;; mir3g) - lan_mac=$(mtd_get_mac_binary Factory e006) + lan_mac=$(mtd_get_mac_binary Factory 0xe006) ;; miwifi-mini) wan_mac=$(cat /sys/class/net/eth0/address) diff --git a/target/linux/ramips/base-files/etc/diag.sh b/target/linux/ramips/base-files/etc/diag.sh index 75171673b..50cc44058 100644 --- a/target/linux/ramips/base-files/etc/diag.sh +++ b/target/linux/ramips/base-files/etc/diag.sh @@ -24,6 +24,7 @@ get_status_led() { ex2700|\ ex3700|\ fonera20n|\ + hg255d|\ kn|\ kn_rc|\ kn_rf|\ @@ -36,6 +37,7 @@ get_status_led() { pwh2004|\ r6220|\ tl-wr840n-v4|\ + tl-wr840n-v5|\ tl-wr841n-v13|\ vr500|\ wnce2001|\ @@ -118,6 +120,7 @@ get_status_led() { w502u) status_led="$board:blue:wps" ;; + c20|\ d240|\ dap-1350|\ na930|\ @@ -132,7 +135,8 @@ get_status_led() { wl-330n3g|\ wli-tx4-ag300n|\ y1|\ - y1s) + y1s|\ + youku-yk1) status_led="$board:blue:power" ;; db-wrt01|\ @@ -236,6 +240,15 @@ get_status_led() { sap-g3200u3) status_led="$board:green:usb" ;; + u25awf-h1) + status_led="u25awf:red:wifi" + ;; + u7621-06-256M-16M) + status_led="u7621-06:green:status" + ;; + u7628-01-128M-16M) + status_led="u7628-01:green:power" + ;; v22rw-2x2) status_led="$board:green:security" ;; diff --git a/target/linux/ramips/base-files/lib/preinit/07_set_preinit_iface_ramips b/target/linux/ramips/base-files/lib/preinit/07_set_preinit_iface_ramips index 452b1b203..5048dacb4 100644 --- a/target/linux/ramips/base-files/lib/preinit/07_set_preinit_iface_ramips +++ b/target/linux/ramips/base-files/lib/preinit/07_set_preinit_iface_ramips @@ -6,17 +6,22 @@ . /lib/ramips.sh ramips_set_preinit_iface() { - RT3X5X=`cat /proc/cpuinfo | egrep "(RT3.5|RT5350|MT7628|MT7688|MT7620)"` + RT3X5X=`cat /proc/cpuinfo | egrep "(RT3.5|RT5350|MT7628|MT7688|MT7620|MT7621)"` if [ -n "${RT3X5X}" ]; then # The ethernet switch driver enables VLAN by default, but # failsafe uses eth0, making the device unreachable: # https://dev.openwrt.org/ticket/18768 - ralink_switchdev=rt305x case "${RT3X5X}" in *MT7620*) ralink_switchdev=mt7620 ;; + *MT7621*) + ralink_switchdev=mt7530 + ;; + *) + ralink_switchdev=rt305x + ;; esac swconfig dev $ralink_switchdev set reset 1 swconfig dev $ralink_switchdev set enable_vlan 0 diff --git a/target/linux/ramips/base-files/lib/ramips.sh b/target/linux/ramips/base-files/lib/ramips.sh index 174e29e43..76ca3d130 100755 --- a/target/linux/ramips/base-files/lib/ramips.sh +++ b/target/linux/ramips/base-files/lib/ramips.sh @@ -88,6 +88,9 @@ ramips_board_detect() { *"C108") name="c108" ;; + *"C20") + name="c20" + ;; *"C20i") name="c20i" ;; @@ -499,9 +502,21 @@ ramips_board_detect() { *"TL-WR840N v4") name="tl-wr840n-v4" ;; + *"TL-WR840N v5") + name="tl-wr840n-v5" + ;; *"TL-WR841N v13") name="tl-wr841n-v13" ;; + *"U25AWF-H1") + name="u25awf-h1" + ;; + *"U7621-06 (256M RAM/16M flash)") + name="u7621-06-256M-16M" + ;; + *"U7628-01 (128M RAM/16M flash)") + name="u7628-01-128M-16M" + ;; *"UBNT-ERX") name="ubnt-erx" ;; @@ -553,6 +568,9 @@ ramips_board_detect() { *"WCR-150GN") name="wcr-150gn" ;; + *"WE1026-5G (16M)") + name="we1026-5g-16m" + ;; *"WF-2881") name="wf-2881" ;; @@ -719,7 +737,9 @@ ramips_board_detect() { name="youku-yk1" ;; *) - name="generic" + name="$(strings /proc/device-tree/compatible | head -1)" + name="${name##*,}" + name="${name:-generic}" ;; esac diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh index 5cfca52ab..0d5b6bb4f 100755 --- a/target/linux/ramips/base-files/lib/upgrade/platform.sh +++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh @@ -144,6 +144,9 @@ platform_check_image() { tew-714tru|\ timecloud|\ tiny-ac|\ + u25awf-h1|\ + u7621-06-256M-16M|\ + u7628-01-128M-16M|\ ur-326n4g|\ ur-336un|\ v22rw-2x2|\ @@ -193,11 +196,13 @@ platform_check_image() { x8|\ y1|\ y1s|\ + we1026-5g-16m|\ zbt-ape522ii|\ zbt-cpe102|\ zbt-wa05|\ zbt-we1326|\ zbt-we2026|\ + zbt-we3526|\ zbt-we826-16M|\ zbt-we826-32M|\ zbt-wg2626|\ @@ -229,10 +234,12 @@ platform_check_image() { } return 0 ;; + c20|\ c20i|\ c50|\ mr200|\ tl-wr840n-v4|\ + tl-wr840n-v5|\ tl-wr841n-v13) [ "$magic" != "03000000" ] && { echo "Invalid image type." diff --git a/target/linux/ramips/dts/ArcherC20.dts b/target/linux/ramips/dts/ArcherC20.dts new file mode 100644 index 000000000..f0281c37c --- /dev/null +++ b/target/linux/ramips/dts/ArcherC20.dts @@ -0,0 +1,187 @@ +/dts-v1/; + +#include "mt7620a.dtsi" + +#include +#include + +/ { + compatible = "tplink,c20", "ralink,mt7620a-soc"; + model = "TP-Link Archer C20"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + gpio-leds { + compatible = "gpio-leds"; + + lan { + label = "c20:blue:lan"; + gpios = <&gpio0 1 GPIO_ACTIVE_LOW>; + }; + + power { + label = "c20:blue:power"; + gpios = <&gpio0 7 GPIO_ACTIVE_LOW>; + default-state = "keep"; + }; + + usb { + label = "c20:blue:usb"; + gpios = <&gpio2 4 GPIO_ACTIVE_LOW>; + }; + + wan { + label = "c20:blue:wan"; + gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; + }; + + wan_orange { + label = "c20:orange:wan"; + gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; + }; + + wlan5g { + label = "c20:blue:wlan5g"; + gpios = <&gpio0 17 GPIO_ACTIVE_LOW>; + }; + + wlan2g { + label = "c20:blue:wlan2g"; + gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; + }; + + wps { + label = "c20:blue:wps"; + gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; + }; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + + reset { + label = "reset"; + gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + rfkill { + label = "rfkill"; + gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; + linux,code = ; + }; }; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <10000000>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x20000>; + read-only; + }; + + partition@20000 { + label = "firmware"; + reg = <0x20000 0x7a0000>; + }; + + partition@7c0000 { + label = "config"; + reg = <0x7c0000 0x10000>; + read-only; + }; + + rom: partition@7d0000 { + label = "rom"; + reg = <0x7d0000 0x10000>; + read-only; + }; + + partition@7e0000 { + label = "romfile"; + reg = <0x7e0000 0x10000>; + read-only; + }; + + radio: partition@7f0000 { + label = "radio"; + reg = <0x7f0000 0x10000>; + read-only; + }; + }; +}; + +&pinctrl { + state_default: pinctrl0 { + gpio { + ralink,group = "i2c", "uartf", "wled", "ephy", "spi refclk", "wdt"; + ralink,function = "gpio"; + }; + }; +}; + +ðernet { + pinctrl-names = "default"; + mtd-mac-address = <&rom 0xf100>; + mediatek,portmap = "wllll"; + }; + +&ehci { + status = "okay"; +}; + +&ohci { + status = "okay"; +}; + +&gsw { + mediatek,port4 = "ephy"; +}; + +&wmac { + ralink,mtd-eeprom = <&radio 0>; + mtd-mac-address = <&rom 0xf100>; + mtd-mac-address-increment = <(-2)>; + pinctrl-names = "default"; + pinctrl-0 = <&pa_pins>; +}; + +&pcie { + status = "okay"; + + pcie-bridge { + mt76@0,0 { + reg = <0x0000 0 0 0 0>; + device_type = "pci"; + mediatek,mtd-eeprom = <&radio 32768>; + ieee80211-freq-limit = <5000000 6000000>; + mtd-mac-address = <&rom 0xf100>; + mtd-mac-address-increment = <(-1)>; + }; + }; +}; diff --git a/target/linux/ramips/dts/ArcherC50.dts b/target/linux/ramips/dts/ArcherC50.dts index e8729232b..88bd3272d 100644 --- a/target/linux/ramips/dts/ArcherC50.dts +++ b/target/linux/ramips/dts/ArcherC50.dts @@ -142,11 +142,6 @@ ralink,group = "i2c", "uartf", "rgmii1", "rgmii2", "wled", "ephy", "spi refclk", "mdio", "wdt", "nd_sd"; ralink,function = "gpio"; }; - - pa { - ralink,group = "pa"; - ralink,function = "pa"; - }; }; }; @@ -172,6 +167,8 @@ ralink,mtd-eeprom = <&radio 0>; mtd-mac-address = <&rom 0xf100>; mtd-mac-address-increment = <(-2)>; + pinctrl-names = "default"; + pinctrl-0 = <&pa_pins>; }; &pcie { diff --git a/target/linux/ramips/dts/D240.dts b/target/linux/ramips/dts/D240.dts index 4f3da8d31..392e92d46 100644 --- a/target/linux/ramips/dts/D240.dts +++ b/target/linux/ramips/dts/D240.dts @@ -52,9 +52,16 @@ power_mpcie2 { gpio-export,name = "power_mpcie2"; - gpio-export,output = ; - gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; + gpio-export,output = <1>; + gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>; }; + + power_mpcie1 { + gpio-export,name = "power_mpcie1"; + gpio-export,output = <1>; + gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>; + }; + }; gpio-leds { @@ -94,6 +101,10 @@ status = "okay"; }; +&gpio2 { + status = "okay"; +}; + &gpio3 { status = "okay"; }; @@ -157,7 +168,7 @@ &pinctrl { state_default: pinctrl0 { default { - ralink,group = "i2c", "uartf", "wled", "spi refclk", "pa"; + ralink,group = "i2c", "uartf", "wled", "spi refclk", "pa", "nd_sd"; ralink,function = "gpio"; }; }; diff --git a/target/linux/ramips/dts/DCH-M225.dts b/target/linux/ramips/dts/DCH-M225.dts index 867335e95..1aea90805 100644 --- a/target/linux/ramips/dts/DCH-M225.dts +++ b/target/linux/ramips/dts/DCH-M225.dts @@ -90,7 +90,7 @@ #sound-dai-cells = <0>; status = "okay"; pinctrl-names = "default"; - pinctrl-0 = <&gpio_i2s_pins>, <&wm8960_mclk_pins>; + pinctrl-0 = <&mdio_refclk_pins>; }; &spi0 { @@ -158,16 +158,9 @@ ralink,function = "gpio"; }; - pa { - ralink,group = "pa"; - ralink,function = "pa"; - }; - - wm8960_mclk_pins: wm8960_mclk { - wm8960_mclk { - ralink,group = "mdio"; - ralink,function = "refclk"; - }; + gpio_i2s { + ralink,group = "uartf"; + ralink,function = "gpio i2s"; }; }; }; @@ -182,5 +175,6 @@ &wmac { ralink,mtd-eeprom = <&factory 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pa_pins>; }; - diff --git a/target/linux/ramips/dts/DIR-615-H1.dts b/target/linux/ramips/dts/DIR-615-H1.dts index 9e8b86ed7..7d410f1dd 100644 --- a/target/linux/ramips/dts/DIR-615-H1.dts +++ b/target/linux/ramips/dts/DIR-615-H1.dts @@ -99,21 +99,13 @@ ralink,group = "i2c", "jtag", "uartf"; ralink,function = "gpio"; }; - - rgmii { - ralink,group = "rgmii"; - ralink,function = "rgmii"; - }; - - mdio { - ralink,group = "mdio"; - ralink,function = "mdio"; - }; }; }; ðernet { mtd-mac-address = <&factory 0x28>; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins &mdio_pins>; }; &esw { diff --git a/target/linux/ramips/dts/DIR-620-D1.dts b/target/linux/ramips/dts/DIR-620-D1.dts index baf17e733..2def8aae4 100644 --- a/target/linux/ramips/dts/DIR-620-D1.dts +++ b/target/linux/ramips/dts/DIR-620-D1.dts @@ -78,21 +78,13 @@ ralink,group = "i2c", "jtag", "uartf"; ralink,function = "gpio"; }; - - rgmii { - ralink,group = "rgmii"; - ralink,function = "rgmii"; - }; - - mdio { - ralink,group = "mdio"; - ralink,function = "mdio"; - }; }; }; ðernet { mtd-mac-address = <&factory 0x4>; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins &mdio_pins>; }; &esw { diff --git a/target/linux/ramips/dts/DUZUN-DM06.dts b/target/linux/ramips/dts/DUZUN-DM06.dts index 97625d875..b8261a591 100644 --- a/target/linux/ramips/dts/DUZUN-DM06.dts +++ b/target/linux/ramips/dts/DUZUN-DM06.dts @@ -63,20 +63,6 @@ ralink,function = "gpio"; }; }; - - i2s_pins: i2s { - i2s { - ralink,group = "i2s"; - ralink,function = "i2s"; - }; - }; - - wm8960_mclk_pins: wm8960_mclk { - wm8960_mclk { - ralink,group = "refclk"; - ralink,function = "reclk"; - }; - }; }; &gpio1 { @@ -108,7 +94,7 @@ #sound-dai-cells = <0>; status = "okay"; pinctrl-names = "default"; - pinctrl-0 = <&i2s_pins>, <&wm8960_mclk_pins>; + pinctrl-0 = <&i2s_pins>, <&refclk_pins>; }; &sdhci { diff --git a/target/linux/ramips/dts/EW1200.dts b/target/linux/ramips/dts/EW1200.dts index e6b96fa2b..84c4f72cb 100644 --- a/target/linux/ramips/dts/EW1200.dts +++ b/target/linux/ramips/dts/EW1200.dts @@ -121,7 +121,7 @@ &pinctrl { state_default: pinctrl0 { gpio { - ralink,group = "wdt", "rgmii2", "wdt rst", "jtag", "mdio"; + ralink,group = "wdt", "rgmii2", "jtag", "mdio"; ralink,function = "gpio"; }; }; diff --git a/target/linux/ramips/dts/HC5X61.dtsi b/target/linux/ramips/dts/HC5X61.dtsi index 1a5927dfd..f0b59ecf1 100644 --- a/target/linux/ramips/dts/HC5X61.dtsi +++ b/target/linux/ramips/dts/HC5X61.dtsi @@ -122,6 +122,8 @@ &wmac { ralink,mtd-eeprom = <&factory 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pa_pins>; }; &pcie { @@ -134,10 +136,5 @@ ralink,group = "uartf", "wled", "nd_sd"; ralink,function = "gpio"; }; - - pa { - ralink,group = "pa"; - ralink,function = "pa"; - }; }; }; diff --git a/target/linux/ramips/dts/K2P.dts b/target/linux/ramips/dts/K2P.dts index 4089ce64f..db4dc2987 100644 --- a/target/linux/ramips/dts/K2P.dts +++ b/target/linux/ramips/dts/K2P.dts @@ -106,7 +106,7 @@ }; ðernet { - mtd-mac-address = <&factory 0xe000>; + mtd-mac-address = <&factory 0xe006>; }; &pinctrl { diff --git a/target/linux/ramips/dts/MIR3G.dts b/target/linux/ramips/dts/MIR3G.dts index 0cdb6d57f..efe98b0e1 100644 --- a/target/linux/ramips/dts/MIR3G.dts +++ b/target/linux/ramips/dts/MIR3G.dts @@ -21,20 +21,36 @@ gpio-leds { compatible = "gpio-leds"; - wan { - label = "mir3g:red:wan"; + status_red { + label = "mir3g:red:status"; gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; }; - usb { - label = "mir3g:blue:usb"; + status_blue { + label = "mir3g:blue:status"; gpios = <&gpio0 8 GPIO_ACTIVE_LOW>; }; - status { + status_yellow { label = "mir3g:yellow:status"; gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; }; + + wan_amber { + label = "mir3g:amber:wan"; + gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; + }; + + lan1_amber { + label = "mir3g:amber:lan1"; + gpios = <&gpio0 14 GPIO_ACTIVE_LOW>; + }; + + lan2_amber { + label = "mir3g:amber:lan2"; + gpios = <&gpio0 16 GPIO_ACTIVE_LOW>; + }; + }; gpio-keys-polled { @@ -45,10 +61,21 @@ reset { label = "reset"; - gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>; + gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; linux,code = ; }; }; + + gpio_export { + compatible = "gpio-export"; + #size-cells = <0>; + + usbpower { + gpio-export,name = "usbpower"; + gpio-export,output = <1>; + gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; + }; + }; }; &nand { @@ -63,7 +90,6 @@ partition@80000 { label = "Config"; reg = <0x80000 0x40000>; - read-only; }; partition@c0000 { @@ -81,13 +107,11 @@ partition@140000 { label = "crash"; reg = <0x140000 0x40000>; - read-only; }; partition@180000 { label = "crash_syslog"; reg = <0x180000 0x40000>; - read-only; }; partition@1c0000 { @@ -96,15 +120,22 @@ read-only; }; - /* - * kernel0 partition should be erased, so - * u-boot in failsafe routine switches - * to next one looking for kernel image. - * To remind about this fact rename kernel0 - * into kernel_erase. + /* uboot expects to find kernels at 0x200000 & 0x600000 + * referred to as system 1 & system 2 respectively. + * a kernel is considered suitable for handing control over + * if its linux magic number exists & uImage CRC are correct. + * If either of those conditions fail, a matching sys'n'_fail flag + * is set in uboot env & a restart performed in the hope that the + * alternate kernel is okay. + * if neither kernel checksums ok and both are marked failed, system 2 + * is booted anyway. + * + * Note uboot's tftp flash install writes the transferred + * image to both kernel partitions. */ + partition@200000 { - label = "kernel_erase"; + label = "kernel_stock"; reg = <0x200000 0x400000>; }; @@ -114,12 +145,13 @@ }; /* ubi partition is the result of squashing - * next consequent stock partitions: - * - rootfs0 (rootfs partition for stock kernel0), - * - rootfs1 (rootfs partition for stock failsafe kernel1), + * next consecutive stock partitions: + * - rootfs0 (rootfs partition for stock kernel0), + * - rootfs1 (rootfs partition for stock failsafe kernel1), * - overlay (used as ubi overlay in stock fw) * resulting 117,5MiB space for packages. */ + partition@a00000 { label = "ubi"; reg = <0xa00000 0x7580000>; @@ -136,7 +168,7 @@ mediatek,mtd-eeprom = <&factory 0x0000>; ieee80211-freq-limit = <2400000 2500000>; }; - }; + }; pcie1 { wifi@14c3,7662 { @@ -156,7 +188,7 @@ &pinctrl { state_default: pinctrl0 { gpio { - ralink,group = "jtag", "uart3", "wdt"; + ralink,group = "jtag", "uart2", "uart3", "wdt"; ralink,function = "gpio"; }; }; diff --git a/target/linux/ramips/dts/MIWIFI-MINI.dts b/target/linux/ramips/dts/MIWIFI-MINI.dts index 9da5673d4..3da39c529 100644 --- a/target/linux/ramips/dts/MIWIFI-MINI.dts +++ b/target/linux/ramips/dts/MIWIFI-MINI.dts @@ -125,6 +125,8 @@ &wmac { ralink,mtd-eeprom = <&factory 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pa_pins>; }; &pcie { @@ -146,10 +148,5 @@ ralink,group = "i2c", "rgmii1"; ralink,function = "gpio"; }; - - pa { - ralink,group = "pa"; - ralink,function = "pa"; - }; }; }; diff --git a/target/linux/ramips/dts/PSG1218A.dts b/target/linux/ramips/dts/PSG1218A.dts index c63af5803..d76abc39f 100644 --- a/target/linux/ramips/dts/PSG1218A.dts +++ b/target/linux/ramips/dts/PSG1218A.dts @@ -31,11 +31,6 @@ ralink,group = "i2c", "uartf", "rgmii1", "rgmii2", "wled", "nd_sd"; ralink,function = "gpio"; }; - - pa { - ralink,group = "pa"; - ralink,function = "pa"; - }; }; }; @@ -45,3 +40,8 @@ mtd-mac-address = <&factory 0x28>; mediatek,portmap = "llllw"; }; + +&wmac { + pinctrl-names = "default"; + pinctrl-0 = <&pa_pins>; +}; diff --git a/target/linux/ramips/dts/RT5350F-OLINUXINO-EVB.dts b/target/linux/ramips/dts/RT5350F-OLINUXINO-EVB.dts index 7811ee20d..5c7b3c7c4 100644 --- a/target/linux/ramips/dts/RT5350F-OLINUXINO-EVB.dts +++ b/target/linux/ramips/dts/RT5350F-OLINUXINO-EVB.dts @@ -1,6 +1,6 @@ /dts-v1/; -#include "rt5350.dtsi" +#include "RT5350F-OLINUXINO.dtsi" #include @@ -30,72 +30,3 @@ }; }; }; - -&spi0 { - status = "okay"; - - m25p80@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <10000000>; - - partition@0 { - label = "u-boot"; - reg = <0x0 0x30000>; - read-only; - }; - - partition@30000 { - label = "u-boot-env"; - reg = <0x30000 0x10000>; - read-only; - }; - - factory: partition@40000 { - label = "factory"; - reg = <0x40000 0x10000>; - read-only; - }; - - partition@50000 { - label = "firmware"; - reg = <0x50000 0x7b0000>; - }; - }; -}; - -&gpio1 { - status = "okay"; -}; - -&pinctrl { - state_default: pinctrl0 { - gpio { - ralink,group = "jtag", "rgmii", "mdio", "uartf"; - ralink,function = "gpio"; - }; - }; -}; - -ðernet { - mtd-mac-address = <&factory 0x4>; -}; - -&esw { - mediatek,portmap = <0x2f>; - mediatek,led_polarity = <0x17>; -}; - -&wmac { - ralink,mtd-eeprom = <&factory 0>; -}; - -&ehci { - status = "okay"; -}; - -&ohci { - status = "okay"; -}; diff --git a/target/linux/ramips/dts/RT5350F-OLINUXINO.dts b/target/linux/ramips/dts/RT5350F-OLINUXINO.dts index 6ee3daeaa..2e0dcb155 100644 --- a/target/linux/ramips/dts/RT5350F-OLINUXINO.dts +++ b/target/linux/ramips/dts/RT5350F-OLINUXINO.dts @@ -1,77 +1,8 @@ /dts-v1/; -#include "rt5350.dtsi" +#include "RT5350F-OLINUXINO.dtsi" / { compatible = "olimex,rt5350f-olinuxino", "ralink,rt5350-soc"; model = "Olimex RT5350F-OLinuXino"; }; - -&spi0 { - status = "okay"; - - m25p80@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <10000000>; - - partition@0 { - label = "u-boot"; - reg = <0x0 0x30000>; - read-only; - }; - - partition@30000 { - label = "u-boot-env"; - reg = <0x30000 0x10000>; - read-only; - }; - - factory: partition@40000 { - label = "factory"; - reg = <0x40000 0x10000>; - read-only; - }; - - partition@50000 { - label = "firmware"; - reg = <0x50000 0x7b0000>; - }; - }; -}; - -&gpio1 { - status = "okay"; -}; - -&pinctrl { - state_default: pinctrl0 { - gpio { - ralink,group = "jtag", "rgmii", "mdio", "uartf"; - ralink,function = "gpio"; - }; - }; -}; - -ðernet { - mtd-mac-address = <&factory 0x4>; -}; - -&esw { - mediatek,portmap = <0x2f>; - mediatek,led_polarity = <0x17>; -}; - -&wmac { - ralink,mtd-eeprom = <&factory 0>; -}; - -&ehci { - status = "okay"; -}; - -&ohci { - status = "okay"; -}; diff --git a/target/linux/ramips/dts/RT5350F-OLINUXINO.dtsi b/target/linux/ramips/dts/RT5350F-OLINUXINO.dtsi new file mode 100644 index 000000000..629dab893 --- /dev/null +++ b/target/linux/ramips/dts/RT5350F-OLINUXINO.dtsi @@ -0,0 +1,94 @@ +#include "rt5350.dtsi" + +/ { + compatible = "olimex,rt5350f-olinuxino", "ralink,rt5350-soc"; + + aliases { + serial0 = &uartlite; + serial1 = &uart; + }; +}; + + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <10000000>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "u-boot-env"; + reg = <0x30000 0x10000>; + read-only; + }; + + factory: partition@40000 { + label = "factory"; + reg = <0x40000 0x10000>; + read-only; + }; + + partition@50000 { + label = "firmware"; + reg = <0x50000 0x7b0000>; + }; + }; +}; + +&gpio1 { + status = "okay"; +}; + +&pinctrl { + state_default: pinctrl0 { + gpio { + ralink,group = "jtag", "rgmii", "mdio"; + ralink,function = "gpio"; + }; + uartf_gpio { + ralink,group = "uartf"; + ralink,function = "gpio uartf"; + }; + }; +}; + +ðernet { + mtd-mac-address = <&factory 0x4>; +}; + +&esw { + mediatek,portmap = <0x2f>; + mediatek,led_polarity = <0x17>; +}; + +&wmac { + ralink,mtd-eeprom = <&factory 0>; + ralink,led-polarity = <1>; +}; + +&ehci { + status = "okay"; +}; + +&ohci { + status = "okay"; +}; + +&i2c { + status = "okay"; +}; + +&uart { + status = "okay"; +}; + diff --git a/target/linux/ramips/dts/TL-WR840NV5.dts b/target/linux/ramips/dts/TL-WR840NV5.dts new file mode 100644 index 000000000..340f2bbd8 --- /dev/null +++ b/target/linux/ramips/dts/TL-WR840NV5.dts @@ -0,0 +1,111 @@ +/dts-v1/; + +#include "mt7628an.dtsi" + +#include +#include + +/ { + compatible = "tplink,tl-wr840n-v5", "mediatek,mt7628an-soc"; + model = "TP-Link TL-WR840N v5"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x4000000>; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + + reset { + label = "reset"; + gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + /* LED used is dual-color,dual lead LED */ + gpio-leds { + compatible = "gpio-leds"; + + power { + label = "tl-wr840n-v5:green:power"; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + }; + + orange { + label = "tl-wr840n-v5:orange:power"; + gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <10000000>; + m25p,chunked-io = <32>; + + partition@0 { + label = "boot"; + reg = <0x0 0x20000>; + read-only; + }; + + partition@20000 { + label = "firmware"; + reg = <0x20000 0x3c0000>; + }; + + partition@3e0000 { + label = "config"; + reg = <0x3e0000 0x10000>; + read-only; + }; + + factory: partition@3f0000 { + label = "factory"; + reg = <0x3f0000 0x10000>; + read-only; + }; + }; +}; + +&ehci { + status = "disabled"; +}; + +&ohci { + status = "disabled"; +}; + +&wmac { + status = "okay"; + mtd-mac-address = <&factory 0xf100>; + mediatek,mtd-eeprom = <&factory 0x10000>; +}; + +ðernet { + mtd-mac-address = <&factory 0xf100>; + mediatek,portmap = "wllll"; +}; + +&pinctrl { + state_default: pinctrl0 { + gpio { + ralink,group = "p0led_an", "p2led_an", "perst"; + ralink,function = "gpio"; + }; + }; +}; diff --git a/target/linux/ramips/dts/U25AWF-H1.dts b/target/linux/ramips/dts/U25AWF-H1.dts new file mode 100644 index 000000000..8021b0f79 --- /dev/null +++ b/target/linux/ramips/dts/U25AWF-H1.dts @@ -0,0 +1,106 @@ +/dts-v1/; + +#include "mt7620a.dtsi" + +#include +#include + +/{ + compatible = "kimax,u25awf-h1","ralink,mt7620a-soc"; + model = "Kimax U25AWF-H1"; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + + reset { + label = "reset"; + gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + wifi { + label = "u25awf:red:wifi"; + gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; + }; + + lan { + label = "u25awf:green:lan"; + gpios = <&gpio2 4 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <10000000>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "u-boot-env"; + reg = <0x30000 0x10000>; + read-only; + }; + + factory: partition@40000 { + label = "factory"; + reg = <0x40000 0x10000>; + read-only; + }; + + partition@50000 { + label = "firmware"; + reg = <0x50000 0xfb0000>; + }; + }; +}; + +&ehci { + status = "okay"; +}; + +&ohci { + status = "okay"; +}; + +ðernet { + mtd-mac-address = <&factory 0x4>; +}; + +&wmac { + ralink,mtd-eeprom = <&factory 0>; +}; + +&pinctrl { + state_default: pinctrl0 { + default { + ralink,group = "uartf", "ephy", "wled"; + ralink,function = "gpio"; + }; + }; +}; diff --git a/target/linux/ramips/dts/U7621-06-256M-16M.dts b/target/linux/ramips/dts/U7621-06-256M-16M.dts new file mode 100644 index 000000000..1bf03fdf5 --- /dev/null +++ b/target/linux/ramips/dts/U7621-06-256M-16M.dts @@ -0,0 +1,86 @@ +/* + * BSD LICENSE + * + * Copyright(c) 2017 Kristian Evensen . + * Copyright(c) 2017 Piotr Dymacz . + * 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 "U7621-06.dtsi" + +#include +#include + +/ { + compatible = "unielec,u7621-06-256m-16m", "unielec,u7621-06", "mediatek,mt7621-soc"; + model = "UniElec U7621-06 (256M RAM/16M flash)"; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x10000000>; + }; +}; + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <14000000>; + m25p,chunked-io = <32>; + + partition@0 { + label = "bootloader"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "config"; + reg = <0x30000 0x10000>; + read-only; + }; + + factory: partition@40000 { + label = "factory"; + reg = <0x40000 0x10000>; + read-only; + }; + + firmware: partition@50000 { + label = "firmware"; + reg = <0x50000 0xfb0000>; + }; + }; +}; diff --git a/target/linux/ramips/dts/U7621-06.dtsi b/target/linux/ramips/dts/U7621-06.dtsi new file mode 100644 index 000000000..0502904bd --- /dev/null +++ b/target/linux/ramips/dts/U7621-06.dtsi @@ -0,0 +1,117 @@ +/* + * BSD LICENSE + * + * Copyright(c) 2017 Kristian Evensen . + * Copyright(c) 2017 Piotr Dymacz . + * 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 "mt7621.dtsi" + +#include +#include + +/ { + compatible = "unielec,u7621-06", "mediatek,mt7621-soc"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + gpio-export { + compatible = "gpio-export"; + #size-cells = <0>; + + modem_reset { + gpio-export,name = "modem_reset"; + gpio-export,output = <1>; + gpios = <&gpio0 16 GPIO_ACTIVE_LOW>; + }; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + + reset { + label = "reset"; + gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + status { + label = "u7621-06:green:status"; + gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; + }; + + led4 { + label = "u7621-06:green:led4"; + gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; + }; + + led5 { + label = "u7621-06:green:led5"; + gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&sdhci { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&sdhci_pins>; +}; + +&pcie { + status = "okay"; +}; + +ðernet { + mtd-mac-address = <&factory 0xe000>; + mediatek,portmap = "llllw"; +}; + +&pinctrl { + state_default: pinctrl0 { + gpio { + ralink,group = "jtag", "uart2", "wdt"; + ralink,function = "gpio"; + }; + }; +}; diff --git a/target/linux/ramips/dts/U7628-01-128M-16M.dts b/target/linux/ramips/dts/U7628-01-128M-16M.dts new file mode 100644 index 000000000..4b3345da3 --- /dev/null +++ b/target/linux/ramips/dts/U7628-01-128M-16M.dts @@ -0,0 +1,83 @@ +/* + * BSD LICENSE + * + * Copyright(c) 2017 Kristian Evensen . + * Copyright(c) 2017 Piotr Dymacz . + * 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 "U7628-01.dtsi" + +/ { + compatible = "unielec,u7628-01-128m-16m", "unielec,u7628-01", "mediatek,mt7628an-soc"; + model = "UniElec U7628-01 (128M RAM/16M flash)"; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x8000000>; + }; +}; + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <12000000>; + m25p,chunked-io = <32>; + + partition@0 { + label = "bootloader"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "config"; + reg = <0x30000 0x10000>; + read-only; + }; + + factory: partition@40000 { + label = "factory"; + reg = <0x40000 0x10000>; + read-only; + }; + + partition@50000 { + label = "firmware"; + reg = <0x50000 0xfb0000>; + }; + }; +}; diff --git a/target/linux/ramips/dts/U7628-01.dtsi b/target/linux/ramips/dts/U7628-01.dtsi new file mode 100644 index 000000000..34226a4a4 --- /dev/null +++ b/target/linux/ramips/dts/U7628-01.dtsi @@ -0,0 +1,132 @@ +/* + * BSD LICENSE + * + * Copyright(c) 2017 Kristian Evensen . + * Copyright(c) 2017 Piotr Dymacz . + * 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 "mt7628an.dtsi" + +#include +#include + +/ { + compatible = "unielec,u7628-01", "mediatek,mt7628an-soc"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + reset { + label = "reset"; + gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + power { + label = "u7628-01:green:power"; + gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; + }; + + wlan { + label = "u7628-01:green:wlan"; + gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; + }; + + wan { + label = "u7628-01:green:wan"; + gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; + }; + + lan1 { + label = "u7628-01:green:lan1"; + gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; + }; + + lan2 { + label = "u7628-01:green:lan2"; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + }; + + lan3 { + label = "u7628-01:green:lan3"; + gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; + }; + + lan4 { + label = "u7628-01:green:lan4"; + gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; + }; + + usb { + label = "u7628-01:green:usb"; + gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&pcie { + status = "okay"; +}; + +ðernet { + mtd-mac-address = <&factory 0x28>; +}; + +&wmac { + status = "okay"; + ralink,mtd-eeprom = <&factory 0x0>; +}; + +&pinctrl { + state_default: pinctrl0 { + gpio { + ralink,group = "gpio", "p0led_an", "p1led_an", "p2led_an", "p3led_an", "p4led_an", "refclk", "wdt", "wled_an"; + ralink,function = "gpio"; + }; + }; +}; diff --git a/target/linux/ramips/dts/VOCORE2.dtsi b/target/linux/ramips/dts/VOCORE2.dtsi index dc1bd17b0..f7aec8e1f 100644 --- a/target/linux/ramips/dts/VOCORE2.dtsi +++ b/target/linux/ramips/dts/VOCORE2.dtsi @@ -12,7 +12,7 @@ &pinctrl { state_default: pinctrl0 { gpio { - ralink,group = "wled_an", "perst", "wdt"; + ralink,group = "wled_an", "refclk", "wdt"; ralink,function = "gpio"; }; }; diff --git a/target/linux/ramips/dts/WE1026-5G-16M.dts b/target/linux/ramips/dts/WE1026-5G-16M.dts new file mode 100644 index 000000000..e01e86423 --- /dev/null +++ b/target/linux/ramips/dts/WE1026-5G-16M.dts @@ -0,0 +1,76 @@ +/* + * BSD LICENSE + * + * Copyright(c) 2017 Kristian Evensen . + * 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 "WE1026-5G.dtsi" + +/ { + compatible = "zbtlink,we1026-5g-16m", "ralink,mt7620a-soc"; + model = "ZBT WE1026-5G (16M)"; +}; + +&spi0 { + status = "okay"; + + en25q128@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <10000000>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "u-boot-env"; + reg = <0x30000 0x10000>; + read-only; + }; + + factory: partition@40000 { + label = "factory"; + reg = <0x40000 0x10000>; + read-only; + }; + + firmware: partition@50000 { + label = "firmware"; + reg = <0x50000 0xfb0000>; + }; + }; +}; diff --git a/target/linux/ramips/dts/WE1026-5G.dtsi b/target/linux/ramips/dts/WE1026-5G.dtsi new file mode 100644 index 000000000..c357e1eee --- /dev/null +++ b/target/linux/ramips/dts/WE1026-5G.dtsi @@ -0,0 +1,124 @@ +/* + * BSD LICENSE + * + * Copyright(c) 2017 Kristian Evensen . + * 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 "mt7620a.dtsi" + +#include +#include + +/ { + compatible = "zbtlink,we1026-5g", "ralink,mt7620a-soc"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + gpio-leds { + compatible = "gpio-leds"; + lan { + label = "we1026-5g:green:lan"; + gpios = <&gpio2 0 GPIO_ACTIVE_LOW>; + }; + + usb { + label = "we1026-5g:green:usb"; + gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>; + }; + + wifi { + label = "we1026-5g:green:wifi"; + gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; + }; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + reset { + label = "reset"; + gpios = <&gpio0 1 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; + +&sdhci { + status = "okay"; +}; + +&ehci { + status = "okay"; +}; + +&ohci { + status = "okay"; +}; + +ðernet { + mtd-mac-address = <&factory 0x28>; +}; + +&wmac { + ralink,mtd-eeprom = <&factory 0>; +}; + +&pinctrl { + state_default: pinctrl0 { + default { + ralink,group = "i2c", "uartf", "spi refclk", "ephy", "wled"; + ralink,function = "gpio"; + }; + }; +}; + +&pcie { + status = "okay"; + pcie-bridge { + wifi@14c3,7662 { + compatible = "pci14c3,7662"; + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x8000>; + ieee80211-freq-limit = <5000000 6000000>; + }; + }; +}; diff --git a/target/linux/ramips/dts/WHR-300HP2.dts b/target/linux/ramips/dts/WHR-300HP2.dts index f74a0b84b..d405686d7 100644 --- a/target/linux/ramips/dts/WHR-300HP2.dts +++ b/target/linux/ramips/dts/WHR-300HP2.dts @@ -127,11 +127,6 @@ ralink,group = "i2c", "uartf", "rgmii1", "rgmii2", "wled", "nd_sd"; ralink,function = "gpio"; }; - - pa { - ralink,group = "pa"; - ralink,function = "pa"; - }; }; }; @@ -147,4 +142,6 @@ &wmac { ralink,mtd-eeprom = <&factory 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pa_pins>; }; diff --git a/target/linux/ramips/dts/WIZFI630A.dts b/target/linux/ramips/dts/WIZFI630A.dts index 882086bcc..86ed19730 100644 --- a/target/linux/ramips/dts/WIZFI630A.dts +++ b/target/linux/ramips/dts/WIZFI630A.dts @@ -118,28 +118,9 @@ }; &uart { - compatible = "ralink,mt7620a-uart", "ralink,rt2880-uart", "ns16550a"; - reg = <0x500 0x100>; - resets = <&rstctrl 12>; - reset-names = "uart"; - interrupt-parent = <&intc>; - interrupts = <5>; - reg-shift = <2>; + status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&uartf_pins>; - status = "okay"; -}; - -&uartlite { - compatible = "ralink,mt7620a-uart", "ralink,rt2880-uart", "ns16550a"; - reg = <0xc00 0x100>; - resets = <&rstctrl 19>; - reset-names = "uartl"; - interrupt-parent = <&intc>; - interrupts = <12>; - reg-shift = <2>; - pinctrl-names = "default"; - pinctrl-0 = <&uartlite_pins>; }; &pinctrl { @@ -149,20 +130,6 @@ ralink,function = "gpio"; }; }; - - uartf_gpio_pins: uartf_gpio { - uartf_gpio { - ralink,group = "uartf"; - ralink,function = "uartf"; - }; - }; - - uartlite_pins: uartlite { - uart { - ralink,group = "uartlite"; - ralink,function = "uartlite"; - }; - }; }; ðernet { diff --git a/target/linux/ramips/dts/WL-351.dts b/target/linux/ramips/dts/WL-351.dts index e620f10d8..0dd596cfe 100644 --- a/target/linux/ramips/dts/WL-351.dts +++ b/target/linux/ramips/dts/WL-351.dts @@ -92,15 +92,13 @@ ralink,group = "spi", "i2c", "jtag", "mdio", "uartf"; ralink,function = "gpio"; }; - rgmii { - ralink,group = "rgmii"; - ralink,function = "rgmii"; - }; }; }; ðernet { mtd-mac-address = <&factory 0x4>; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; }; &esw { diff --git a/target/linux/ramips/dts/WT3020-8M.dts b/target/linux/ramips/dts/WT3020-8M.dts index 05ade7c5a..b2397d2cd 100644 --- a/target/linux/ramips/dts/WT3020-8M.dts +++ b/target/linux/ramips/dts/WT3020-8M.dts @@ -7,6 +7,14 @@ model = "Nexx WT3020 (8M)"; }; +&ehci { + status = "okay"; +}; + +&ohci { + status = "okay"; +}; + &spi0 { status = "okay"; diff --git a/target/linux/ramips/dts/WT3020.dtsi b/target/linux/ramips/dts/WT3020.dtsi index 6bea6cc1f..91720e32c 100644 --- a/target/linux/ramips/dts/WT3020.dtsi +++ b/target/linux/ramips/dts/WT3020.dtsi @@ -37,15 +37,6 @@ status = "okay"; }; - -&ehci { - status = "okay"; -}; - -&ohci { - status = "okay"; -}; - ðernet { mtd-mac-address = <&factory 0x4>; mediatek,portmap = "wllll"; diff --git a/target/linux/ramips/dts/Y1.dtsi b/target/linux/ramips/dts/Y1.dtsi index 022b67949..cc126f04a 100644 --- a/target/linux/ramips/dts/Y1.dtsi +++ b/target/linux/ramips/dts/Y1.dtsi @@ -94,6 +94,8 @@ &wmac { ralink,mtd-eeprom = <&factory 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pa_pins>; }; &pinctrl { @@ -102,10 +104,5 @@ ralink,group = "uartf", "wled", "nd_sd"; ralink,function = "gpio"; }; - - pa { - ralink,group = "pa"; - ralink,function = "pa"; - }; }; }; diff --git a/target/linux/ramips/dts/YOUKU-YK1.dts b/target/linux/ramips/dts/YOUKU-YK1.dts index d4e3c905b..8a0e0819e 100644 --- a/target/linux/ramips/dts/YOUKU-YK1.dts +++ b/target/linux/ramips/dts/YOUKU-YK1.dts @@ -96,7 +96,7 @@ &pinctrl { state_default: pinctrl0 { default { - ralink,group = "i2c", "uartf", "rgmii1", "rgmii2", "ephy", "wled", "nd_sd"; + ralink,group = "i2c", "rgmii1", "ephy", "wled"; ralink,function = "gpio"; }; }; @@ -104,7 +104,6 @@ ðernet { pinctrl-names = "default"; - pinctrl-0 = <&ephy_pins>; mtd-mac-address = <&factory 0x4>; mediatek,portmap = "llllw"; }; diff --git a/target/linux/ramips/dts/ZBT-APE522II.dts b/target/linux/ramips/dts/ZBT-APE522II.dts index 45fef667c..05d053f22 100644 --- a/target/linux/ramips/dts/ZBT-APE522II.dts +++ b/target/linux/ramips/dts/ZBT-APE522II.dts @@ -115,6 +115,8 @@ &wmac { ralink,mtd-eeprom = <&factory 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pa_pins>; }; &pcie { @@ -136,10 +138,5 @@ ralink,group = "wled", "i2c", "uartf", "wdt"; ralink,function = "gpio"; }; - - pa { - ralink,group = "pa"; - ralink,function = "pa"; - }; }; }; diff --git a/target/linux/ramips/dts/ZBT-WE3526.dts b/target/linux/ramips/dts/ZBT-WE3526.dts new file mode 100644 index 000000000..dc7896f13 --- /dev/null +++ b/target/linux/ramips/dts/ZBT-WE3526.dts @@ -0,0 +1,117 @@ +/dts-v1/; + +#include "mt7621.dtsi" + +#include +#include + +/ { + compatible = "zbtlink,zbt-we3526", "mediatek,mt7621-soc"; + model = "ZBT-WE3526"; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x1c000000>, <0x20000000 0x4000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + palmbus: palmbus@1E000000 { + i2c@900 { + status = "okay"; + }; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + + reset { + label = "reset"; + gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; +}; + +&sdhci { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <10000000>; + m25p,chunked-io = <32>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "u-boot-env"; + reg = <0x30000 0x10000>; + read-only; + }; + + factory: partition@40000 { + label = "factory"; + reg = <0x40000 0x10000>; + read-only; + }; + + firmware: partition@50000 { + label = "firmware"; + reg = <0x50000 0xfb0000>; + }; + }; +}; + +&pcie { + status = "okay"; + + pcie0 { + wifi@14c3,7662 { + compatible = "pci14c3,7662"; + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x8000>; + ieee80211-freq-limit = <5000000 6000000>; + + led { + led-sources = <2>; + }; + }; + }; + + pcie1 { + wifi@14c3,7603 { + compatible = "pci14c3,7603"; + reg = <0x0000 0 0 0 0>; + mediatek,mtd-eeprom = <&factory 0x0000>; + }; + }; +}; + +ðernet { + mtd-mac-address = <&factory 0xe000>; +}; + +&pinctrl { + state_default: pinctrl0 { + gpio { + ralink,group = "wdt"; + ralink,function = "gpio"; + }; + }; +}; diff --git a/target/linux/ramips/dts/ZBT-WG2626.dts b/target/linux/ramips/dts/ZBT-WG2626.dts index a55fd09e6..79f2859bb 100644 --- a/target/linux/ramips/dts/ZBT-WG2626.dts +++ b/target/linux/ramips/dts/ZBT-WG2626.dts @@ -116,7 +116,7 @@ &pinctrl { state_default: pinctrl0 { gpio { - ralink,group = "wdt", "rgmii2", "wdt rst", "jtag", "mdio"; + ralink,group = "wdt", "rgmii2", "jtag", "mdio"; ralink,function = "gpio"; }; }; diff --git a/target/linux/ramips/dts/ZBT-WG3526.dtsi b/target/linux/ramips/dts/ZBT-WG3526.dtsi index ccd5ab1e0..104a51f8d 100644 --- a/target/linux/ramips/dts/ZBT-WG3526.dtsi +++ b/target/linux/ramips/dts/ZBT-WG3526.dtsi @@ -111,7 +111,7 @@ &pinctrl { state_default: pinctrl0 { gpio { - ralink,group = "wdt", "rgmii2", "wdt rst", "jtag", "mdio"; + ralink,group = "wdt", "rgmii2", "jtag", "mdio"; ralink,function = "gpio"; }; }; diff --git a/target/linux/ramips/dts/ZBT-WR8305RT.dts b/target/linux/ramips/dts/ZBT-WR8305RT.dts index 11911b9f0..52cac80a7 100644 --- a/target/linux/ramips/dts/ZBT-WR8305RT.dts +++ b/target/linux/ramips/dts/ZBT-WR8305RT.dts @@ -94,6 +94,8 @@ }; ðernet { + pinctrl-names = "default"; + pinctrl-0 = <&ephy_pins>; mtd-mac-address = <&factory 0x4>; mediatek,portmap = "llllw"; }; @@ -104,11 +106,6 @@ &pinctrl { state_default: pinctrl0 { - ephy { - ralink,group = "ephy"; - ralink,function = "ephy"; - }; - default { ralink,group = "i2c", "uartf", "spi refclk", "wled"; ralink,function = "gpio"; diff --git a/target/linux/ramips/dts/mt7620a.dtsi b/target/linux/ramips/dts/mt7620a.dtsi index 96966b464..882cf8810 100644 --- a/target/linux/ramips/dts/mt7620a.dtsi +++ b/target/linux/ramips/dts/mt7620a.dtsi @@ -365,6 +365,13 @@ }; }; + mdio_refclk_pins: mdio_refclk { + mdio_refclk { + ralink,group = "mdio"; + ralink,function = "refclk"; + }; + }; + ephy_pins: ephy { ephy { ralink,group = "ephy"; @@ -399,6 +406,13 @@ ralink,function = "pcie rst"; }; }; + + pa_pins: pa { + pa { + ralink,group = "pa"; + ralink,function = "pa"; + }; + }; }; rstctrl: rstctrl { diff --git a/target/linux/ramips/dts/mt7620n.dtsi b/target/linux/ramips/dts/mt7620n.dtsi index f1593acd9..5d3c1e3fa 100644 --- a/target/linux/ramips/dts/mt7620n.dtsi +++ b/target/linux/ramips/dts/mt7620n.dtsi @@ -228,6 +228,13 @@ state_default: pinctrl0 { }; + ephy_pins: ephy { + ephy { + ralink,group = "ephy"; + ralink,function = "ephy"; + }; + }; + spi_pins: spi { spi { ralink,group = "spi"; diff --git a/target/linux/ramips/dts/mt7621.dtsi b/target/linux/ramips/dts/mt7621.dtsi index 766251899..d68ddf3bc 100644 --- a/target/linux/ramips/dts/mt7621.dtsi +++ b/target/linux/ramips/dts/mt7621.dtsi @@ -58,7 +58,7 @@ }; wdt: wdt@100 { - compatible = "mtk,mt7621-wdt"; + compatible = "mediatek,mt7621-wdt"; reg = <0x100 0x100>; }; diff --git a/target/linux/ramips/dts/mt7628an.dtsi b/target/linux/ramips/dts/mt7628an.dtsi index b64a87a49..b572f2ae4 100644 --- a/target/linux/ramips/dts/mt7628an.dtsi +++ b/target/linux/ramips/dts/mt7628an.dtsi @@ -38,7 +38,7 @@ }; watchdog: watchdog@120 { - compatible = "ralink,mt7628an-wdt", "mtk,mt7621-wdt"; + compatible = "ralink,mt7628an-wdt", "mediatek,mt7621-wdt"; reg = <0x120 0x10>; resets = <&rstctrl 8>; @@ -298,6 +298,13 @@ }; }; + i2s_pins: i2s { + i2s { + ralink,group = "i2s"; + ralink,function = "i2s"; + }; + }; + uart0_pins: uartlite { uartlite { ralink,group = "uart0"; @@ -340,12 +347,19 @@ }; }; - pcm_i2s_pins: i2s { - i2s { + pcm_i2s_pins: pcm_i2s { + pcm_i2s { ralink,group = "i2s"; ralink,function = "pcm"; }; }; + + refclk_pins: refclk { + refclk { + ralink,group = "refclk"; + ralink,function = "refclk"; + }; + }; }; rstctrl: rstctrl { diff --git a/target/linux/ramips/dts/rt3050.dtsi b/target/linux/ramips/dts/rt3050.dtsi index 23da1c43e..5c69d282a 100644 --- a/target/linux/ramips/dts/rt3050.dtsi +++ b/target/linux/ramips/dts/rt3050.dtsi @@ -260,6 +260,13 @@ }; }; + rgmii_pins: rgmii { + rgmii { + ralink,group = "rgmii"; + ralink,function = "rgmii"; + }; + }; + uartlite_pins: uartlite { uart { ralink,group = "uartlite"; diff --git a/target/linux/ramips/dts/rt3352.dtsi b/target/linux/ramips/dts/rt3352.dtsi index a617281b7..5612458f1 100644 --- a/target/linux/ramips/dts/rt3352.dtsi +++ b/target/linux/ramips/dts/rt3352.dtsi @@ -262,6 +262,20 @@ }; }; + mdio_pins: mdio { + mdio { + ralink,group = "mdio"; + ralink,function = "mdio"; + }; + }; + + rgmii_pins: rgmii { + rgmii { + ralink,group = "rgmii"; + ralink,function = "rgmii"; + }; + }; + spi_pins: spi { spi { ralink,group = "spi"; diff --git a/target/linux/ramips/files-4.9/drivers/net/ethernet/mtk/mt7530.c b/target/linux/ramips/files-4.9/drivers/net/ethernet/mtk/mt7530.c index 74b4a7103..439d8c266 100644 --- a/target/linux/ramips/files-4.9/drivers/net/ethernet/mtk/mt7530.c +++ b/target/linux/ramips/files-4.9/drivers/net/ethernet/mtk/mt7530.c @@ -220,6 +220,12 @@ struct mt7530_mapping { .members = { 0, 0x7e, 0x41 }, .etags = { 0, 0x40, 0x40 }, .vids = { 0, 1, 2 }, + }, { + .name = "lwlll", + .pvids = { 1, 2, 1, 1, 1, 1, 1 }, + .members = { 0, 0x7d, 0x42 }, + .etags = { 0, 0x40, 0x40 }, + .vids = { 0, 1, 2 }, }, }; @@ -922,7 +928,7 @@ mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus, int vl /* magic vodoo */ if (!IS_ENABLED(CONFIG_SOC_MT7621) && bus && mt7530_r32(mt7530, REG_HWTRAP) != 0x1117edf) { - dev_info(dev, "fixing up MHWTRAP register - bootloader probably played with it\n"); + dev_info(dev, "fixing up MHWTRAP register - bootloader probably played with it\n"); mt7530_w32(mt7530, REG_HWTRAP, 0x1117edf); } dev_info(dev, "loaded %s driver\n", swdev->name); diff --git a/target/linux/ramips/files-4.9/drivers/net/ethernet/mtk/mtk_eth_soc.c b/target/linux/ramips/files-4.9/drivers/net/ethernet/mtk/mtk_eth_soc.c index 5f4afade0..a9d2f385a 100644 --- a/target/linux/ramips/files-4.9/drivers/net/ethernet/mtk/mtk_eth_soc.c +++ b/target/linux/ramips/files-4.9/drivers/net/ethernet/mtk/mtk_eth_soc.c @@ -1003,7 +1003,7 @@ static int fe_poll(struct napi_struct *napi, int budget) goto poll_again; } - napi_complete(napi); + napi_complete_done(napi, rx_done); fe_int_enable(tx_intr | rx_intr); } else { rx_done = budget; @@ -1536,7 +1536,7 @@ static int fe_probe(struct platform_device *pdev) priv->rx_ring.rx_ring_size = NUM_DMA_DESC; INIT_WORK(&priv->pending_work, fe_pending_work); - napi_weight = 32; + napi_weight = 16; if (priv->flags & FE_FLAG_NAPI_WEIGHT) { napi_weight *= 4; priv->tx_ring.tx_ring_size *= 4; diff --git a/target/linux/ramips/image/mt7620.mk b/target/linux/ramips/image/mt7620.mk index f201c9d40..7dd26fe27 100644 --- a/target/linux/ramips/image/mt7620.mk +++ b/target/linux/ramips/image/mt7620.mk @@ -2,7 +2,7 @@ # MT7620A Profiles # -DEVICE_VARS += TPLINK_BOARD_ID +DEVICE_VARS += TPLINK_FLASHLAYOUT TPLINK_HWID TPLINK_HWREV TPLINK_HWREVADD TPLINK_HVERSION define Build/elecom-header cp $@ $(KDIR)/v_0.0.0.bin @@ -10,7 +10,9 @@ define Build/elecom-header mkhash md5 $(KDIR)/v_0.0.0.bin && \ echo 458 \ ) | mkhash md5 > $(KDIR)/v_0.0.0.md5 - $(STAGING_DIR_HOST)/bin/tar -cf $@ -C $(KDIR) v_0.0.0.bin v_0.0.0.md5 + $(STAGING_DIR_HOST)/bin/tar -c \ + $(if $(SOURCE_DATE_EPOCH),--mtime=@$(SOURCE_DATE_EPOCH)) \ + -f $@ -C $(KDIR) v_0.0.0.bin v_0.0.0.md5 endef define Build/zyimage @@ -26,17 +28,35 @@ endef TARGET_DEVICES += ai-br100 define Device/Archer + TPLINK_HWREVADD := 0 + TPLINK_HVERSION := 3 KERNEL := $(KERNEL_DTB) - KERNEL_INITRAMFS := $(KERNEL_DTB) | tplink-v2-header - IMAGE/factory.bin := tplink-v2-image - IMAGE/sysupgrade.bin := tplink-v2-image -s | append-metadata + KERNEL_INITRAMFS := $(KERNEL_DTB) | tplink-v2-header -e + IMAGE/factory.bin := tplink-v2-image -e + IMAGE/sysupgrade.bin := tplink-v2-image -s -e | append-metadata endef +define Device/ArcherC20 + $(Device/Archer) + DTS := ArcherC20 + SUPPORTED_DEVICES := c20 + TPLINK_FLASHLAYOUT := 8Mmtk + TPLINK_HWID := 0xc2000001 + TPLINK_HWREV := 0x44 + TPLINK_HWREVADD := 0x1 + IMAGES += factory.bin + DEVICE_TITLE := TP-Link ArcherC20 + DEVICE_PACKAGES := kmod-usb-core kmod-usb2 kmod-usb-ledtrig-usbport +endef +TARGET_DEVICES += ArcherC20 + define Device/ArcherC20i $(Device/Archer) DTS := ArcherC20i SUPPORTED_DEVICES := c20i - TPLINK_BOARD_ID := ArcherC20i + TPLINK_FLASHLAYOUT := 8Mmtk + TPLINK_HWID := 0xc2000001 + TPLINK_HWREV := 58 IMAGES += factory.bin DEVICE_TITLE := TP-Link ArcherC20i endef @@ -46,10 +66,12 @@ define Device/ArcherC50v1 $(Device/Archer) DTS := ArcherC50 SUPPORTED_DEVICES := c50 - TPLINK_BOARD_ID := ArcherC50 + TPLINK_FLASHLAYOUT := 8Mmtk + TPLINK_HWID := 0xc7500001 + TPLINK_HWREV := 69 IMAGES += factory-us.bin factory-eu.bin - IMAGE/factory-us.bin := tplink-v2-image -w 0 - IMAGE/factory-eu.bin := tplink-v2-image -w 2 + IMAGE/factory-us.bin := tplink-v2-image -e -w 0 + IMAGE/factory-eu.bin := tplink-v2-image -e -w 2 DEVICE_TITLE := TP-Link ArcherC50v1 endef TARGET_DEVICES += ArcherC50v1 @@ -58,7 +80,9 @@ define Device/ArcherMR200 $(Device/Archer) DTS := ArcherMR200 SUPPORTED_DEVICES := mr200 - TPLINK_BOARD_ID := ArcherMR200 + TPLINK_FLASHLAYOUT := 8MLmtk + TPLINK_HWID := 0xd7500001 + TPLINK_HWREV := 0x4a DEVICE_PACKAGES := kmod-usb2 kmod-usb-net kmod-usb-net-rndis kmod-usb-serial kmod-usb-serial-option adb-enablemodem DEVICE_TITLE := TP-Link ArcherMR200 endef @@ -81,7 +105,9 @@ TARGET_DEVICES += cf-wr800n define Device/cs-qr10 DTS := CS-QR10 DEVICE_TITLE := Planex CS-QR10 - DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-i2c-core kmod-i2c-ralink kmod-sound-core kmod-sound-mtk kmod-sdhci-mt7620 + DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci \ + kmod-sound-core kmod-sound-mt7620 \ + kmod-i2c-ralink kmod-sdhci-mt7620 endef TARGET_DEVICES += cs-qr10 @@ -115,7 +141,7 @@ define Device/dch-m225 seama-seal -m "signature=wapn22_dlink.2013gui_dap1320b" | \ check-size $$$$(IMAGE_SIZE) DEVICE_TITLE := D-Link DCH-M225 - DEVICE_PACKAGES := kmod-mt76 + DEVICE_PACKAGES := kmod-mt76 kmod-sound-core kmod-sound-mt7620 kmod-i2c-ralink endef TARGET_DEVICES += dch-m225 @@ -171,6 +197,13 @@ define Device/gl-mt300a endef TARGET_DEVICES += gl-mt300a +define Device/u25awf-h1 + DTS := U25AWF-H1 + IMAGE_SIZE := 16064k + DEVICE_TITLE := Kimax U25AWF-H1 +endef +TARGET_DEVICES += u25awf-h1 + define Device/gl-mt300n DTS := GL-MT300N IMAGE_SIZE := $(ralink_default_fw_size_16M) @@ -456,6 +489,7 @@ define Device/wt3020-8M IMAGE/factory.bin := $$(sysupgrade_bin) | check-size $$$$(IMAGE_SIZE) | \ poray-header -B WT3020 -F 8M DEVICE_TITLE := Nexx WT3020 (8MB) + DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci endef TARGET_DEVICES += wt3020-8M @@ -475,11 +509,21 @@ TARGET_DEVICES += y1s define Device/youku-yk1 DTS := YOUKU-YK1 - IMAGE_SIZE := $(ralink_default_fw_size_16M) + IMAGE_SIZE := $(ralink_default_fw_size_32M) DEVICE_TITLE := YOUKU YK1 + DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620 kmod-usb-ledtrig-usbport endef TARGET_DEVICES += youku-yk1 +define Device/we1026-5g-16m + DTS := WE1026-5G-16M + IMAGE_SIZE := 16777216 + SUPPORTED_DEVICES += we1026-5g-16m + DEVICE_TITLE := Zbtlink ZBT-WE1026-5G (16M) + DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-mt76 kmod-sdhci-mt7620 +endef +TARGET_DEVICES += we1026-5g-16m + define Device/zbt-ape522ii DTS := ZBT-APE522II DEVICE_TITLE := Zbtlink ZBT-APE522II diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk index 779616292..82d0eeae6 100644 --- a/target/linux/ramips/image/mt7621.mk +++ b/target/linux/ramips/image/mt7621.mk @@ -121,7 +121,7 @@ define Device/mir3g SUPPORTED_DEVICES += R3G DEVICE_PACKAGES := \ kmod-mt7603 kmod-mt76x2 kmod-usb3 kmod-usb-ledtrig-usbport wpad-mini \ - kmod-softdog + uboot-envtools endef TARGET_DEVICES += mir3g @@ -225,6 +225,14 @@ define Device/timecloud endef TARGET_DEVICES += timecloud +define Device/u7621-06-256M-16M + DTS := U7621-06-256M-16M + IMAGE_SIZE := 16064k + DEVICE_TITLE := UniElec U7621-06 (256M RAM/16M flash) + DEVICE_PACKAGES := kmod-ata-core kmod-ata-ahci kmod-sdhci-mt7620 kmod-usb3 +endef +TARGET_DEVICES += u7621-06-256M-16M + define Device/ubnt-erx DTS := UBNT-ERX FILESYSTEMS := squashfs @@ -321,6 +329,17 @@ define Device/zbt-we1326 endef TARGET_DEVICES += zbt-we1326 +define Device/zbt-we3526 + DTS := ZBT-WE3526 + IMAGE_SIZE := $(ralink_default_fw_size_16M) + SUPPORTED_DEVICES += zbt-we3526 + DEVICE_TITLE := ZBT WE3526 + DEVICE_PACKAGES := \ + kmod-sdhci-mt7620 kmod-mt7603 kmod-mt76x2 \ + kmod-usb3 kmod-usb-ledtrig-usbport wpad-mini +endef +TARGET_DEVICES += zbt-we3526 + define Device/zbt-wg2626 DTS := ZBT-WG2626 IMAGE_SIZE := $(ralink_default_fw_size_16M) diff --git a/target/linux/ramips/image/mt76x8.mk b/target/linux/ramips/image/mt76x8.mk index f4b3171a0..0e9b8fc7e 100644 --- a/target/linux/ramips/image/mt76x8.mk +++ b/target/linux/ramips/image/mt76x8.mk @@ -2,7 +2,7 @@ # MT76x8 Profiles # -DEVICE_VARS += TPLINK_BOARD_ID +DEVICE_VARS += TPLINK_FLASHLAYOUT TPLINK_HWID TPLINK_HWREV TPLINK_HWREVADD TPLINK_HVERSION define Device/duzun-dm06 DTS := DUZUN-DM06 @@ -85,12 +85,32 @@ define Device/tl-wr840n-v4 DTS := TL-WR840NV4 IMAGE_SIZE := 7808k DEVICE_TITLE := TP-Link TL-WR840N v4 - TPLINK_BOARD_ID := TL-WR840NV4 + TPLINK_FLASHLAYOUT := 8Mmtk + TPLINK_HWID := 0x08400004 + TPLINK_HWREV := 0x1 + TPLINK_HWREVADD := 0x4 + TPLINK_HVERSION := 3 KERNEL := $(KERNEL_DTB) + KERNEL_INITRAMFS := $(KERNEL_DTB) | tplink-v2-header -e IMAGES += tftp-recovery.bin - IMAGE/factory.bin := tplink-v2-image + IMAGE/factory.bin := tplink-v2-image -e IMAGE/tftp-recovery.bin := pad-extra 128k | $$(IMAGE/factory.bin) - IMAGE/sysupgrade.bin := tplink-v2-image -s | append-metadata | \ + IMAGE/sysupgrade.bin := tplink-v2-image -s -e | append-metadata | \ + check-size $$$$(IMAGE_SIZE) +endef + +define Device/tl-wr840n-v5 + DTS := TL-WR840NV5 + IMAGE_SIZE := 3840k + DEVICE_TITLE := TP-Link TL-WR840N v5 + TPLINK_FLASHLAYOUT := 4Mmtk + TPLINK_HWID := 0x08400005 + TPLINK_HWREV := 0x1 + TPLINK_HWREVADD := 0x5 + TPLINK_HVERSION := 3 + KERNEL := $(KERNEL_DTB) + KERNEL_INITRAMFS := $(KERNEL_DTB) | tplink-v2-header -e + IMAGE/sysupgrade.bin := tplink-v2-image -s -e | append-metadata | \ check-size $$$$(IMAGE_SIZE) endef @@ -98,9 +118,19 @@ define Device/tl-wr841n-v13 $(Device/tl-wr840n-v4) DTS := TL-WR841NV13 DEVICE_TITLE := TP-Link TL-WR841N v13 - TPLINK_BOARD_ID := TL-WR841NV13 + TPLINK_HWID := 0x08410013 + TPLINK_HWREV := 0x268 + TPLINK_HWREVADD := 0x13 endef -TARGET_DEVICES += tl-wr840n-v4 tl-wr841n-v13 +TARGET_DEVICES += tl-wr840n-v4 tl-wr840n-v5 tl-wr841n-v13 + +define Device/u7628-01-128M-16M + DTS := U7628-01-128M-16M + IMAGE_SIZE := 16064k + DEVICE_TITLE := UniElec U7628-01 (128M RAM/16M flash) + DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport +endef +TARGET_DEVICES += u7628-01-128M-16M define Device/vocore2 DTS := VOCORE2 diff --git a/target/linux/ramips/mt7620/config-4.9 b/target/linux/ramips/mt7620/config-4.9 index 52c05185e..4f8c68629 100644 --- a/target/linux/ramips/mt7620/config-4.9 +++ b/target/linux/ramips/mt7620/config-4.9 @@ -126,7 +126,6 @@ CONFIG_MIPS_CLOCK_VSYSCALL=y # CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set CONFIG_MIPS_CMDLINE_FROM_DTB=y # CONFIG_MIPS_ELF_APPENDED_DTB is not set -CONFIG_MIPS_FPU_EMULATOR=y # CONFIG_MIPS_HUGE_TLB_SUPPORT is not set CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_MIPS_MACHINE is not set @@ -138,9 +137,11 @@ CONFIG_MODULES_USE_ELF_REL=y # CONFIG_MTD_CFI_INTELEXT is not set CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_M25P80=y +CONFIG_MTD_NAND_MT7620=y CONFIG_MTD_PHYSMAP=y CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384 CONFIG_MTD_SPLIT_FIRMWARE=y CONFIG_MTD_SPLIT_SEAMA_FW=y CONFIG_MTD_SPLIT_TPLINK_FW=y diff --git a/target/linux/ramips/mt7621/config-4.9 b/target/linux/ramips/mt7621/config-4.9 index ce8ba450c..f9765edaf 100644 --- a/target/linux/ramips/mt7621/config-4.9 +++ b/target/linux/ramips/mt7621/config-4.9 @@ -5,7 +5,6 @@ CONFIG_ARCH_HAS_ELF_RANDOMIZE=y # CONFIG_ARCH_HAS_GCOV_PROFILE_ALL is not set CONFIG_ARCH_HAS_RESET_CONTROLLER=y # CONFIG_ARCH_HAS_SG_CHAIN is not set -CONFIG_ARCH_HAS_TICK_BROADCAST=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y @@ -65,7 +64,6 @@ CONFIG_EARLY_PRINTK=y CONFIG_FIXED_PHY=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_GENERIC_IO=y CONFIG_GENERIC_IRQ_CHIP=y @@ -151,7 +149,6 @@ CONFIG_MIPS_CPS=y # CONFIG_MIPS_CPS_NS16550 is not set CONFIG_MIPS_CPU_SCACHE=y # CONFIG_MIPS_ELF_APPENDED_DTB is not set -CONFIG_MIPS_FPU_EMULATOR=y CONFIG_MIPS_GIC=y # CONFIG_MIPS_HUGE_TLB_SUPPORT is not set CONFIG_MIPS_L1_CACHE_SHIFT=5 @@ -255,8 +252,8 @@ CONFIG_SPI_MASTER=y CONFIG_SPI_MT7621=y # CONFIG_SPI_RT2880 is not set CONFIG_SRCU=y -CONFIG_SWCONFIG=y CONFIG_SWCONFIG_LEDS=y +CONFIG_SWCONFIG=y CONFIG_SWPHY=y CONFIG_SYNC_R4K=y CONFIG_SYSCTL_EXCEPTION_TRACE=y @@ -283,7 +280,6 @@ CONFIG_USB_SUPPORT=y CONFIG_USE_OF=y CONFIG_WATCHDOG_CORE=y CONFIG_WEAK_ORDERING=y -CONFIG_WEAK_REORDERING_BEYOND_LLSC=y CONFIG_XPS=y CONFIG_ZLIB_DEFLATE=y CONFIG_ZLIB_INFLATE=y diff --git a/target/linux/ramips/patches-4.9/0034-NET-multi-phy-support.patch b/target/linux/ramips/patches-4.9/0034-NET-multi-phy-support.patch index c19c3cd35..4d7f59028 100644 --- a/target/linux/ramips/patches-4.9/0034-NET-multi-phy-support.patch +++ b/target/linux/ramips/patches-4.9/0034-NET-multi-phy-support.patch @@ -43,7 +43,7 @@ Signed-off-by: John Crispin } --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -373,6 +373,7 @@ struct phy_device { +@@ -369,6 +369,7 @@ struct phy_device { bool is_pseudo_fixed_link; bool has_fixups; bool suspended; diff --git a/target/linux/ramips/patches-4.9/0039-mtd-add-mt7621-nand-support.patch b/target/linux/ramips/patches-4.9/0039-mtd-add-mt7621-nand-support.patch index f3fc9767a..f5b1d8234 100644 --- a/target/linux/ramips/patches-4.9/0039-mtd-add-mt7621-nand-support.patch +++ b/target/linux/ramips/patches-4.9/0039-mtd-add-mt7621-nand-support.patch @@ -3379,7 +3379,7 @@ Signed-off-by: John Crispin + data |= ((0x2<<18) |(0x2<<16)); + DRV_WriteReg32(RALINK_SYSCTL_BASE+0x60, data); + -+ hw = &mt7621_nand_hw, ++ hw = &mt7621_nand_hw; + BUG_ON(!hw); + /* Allocate memory for the device structure (and zero it) */ + host = kzalloc(sizeof(struct mtk_nand_host), GFP_KERNEL); @@ -4302,7 +4302,7 @@ Signed-off-by: John Crispin +#endif /* __NAND_DEF_H__ */ --- /dev/null +++ b/drivers/mtd/nand/nand_device_list.h -@@ -0,0 +1,55 @@ +@@ -0,0 +1,56 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are @@ -4345,6 +4345,7 @@ Signed-off-by: John Crispin + {0x20BC, 0x105554, 5, 16, 512, 128, 2048, 64, 0x1123, "EHD013151MA_5", 0}, + {0xECBC, 0x005554, 5, 16, 512, 128, 2048, 64, 0x1123, "K524G2GACB_A0", 0}, + {0x2CBC, 0x905556, 5, 16, 512, 128, 2048, 64, 0x21044333, "MT29C4G96MAZA", 0}, ++ {0x2CDA, 0x909506, 5, 8, 256, 128, 2048, 64, 0x30C77fff, "MT29F2G08ABAE", 0}, + {0xADBC, 0x905554, 5, 16, 512, 128, 2048, 64, 0x10801011, "H9DA4GH4JJAMC", 0}, + {0x01F1, 0x801D01, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "S34ML01G100TF", 0}, + {0x92F1, 0x8095FF, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "F59L1G81A", 0}, diff --git a/target/linux/ramips/patches-4.9/0040-nand-hack.patch b/target/linux/ramips/patches-4.9/0040-nand-hack.patch index 64a325300..fe2b12d2c 100644 --- a/target/linux/ramips/patches-4.9/0040-nand-hack.patch +++ b/target/linux/ramips/patches-4.9/0040-nand-hack.patch @@ -41,7 +41,7 @@ } --- a/drivers/mtd/nand/nand_device_list.h +++ b/drivers/mtd/nand/nand_device_list.h -@@ -43,6 +43,8 @@ static const flashdev_info gen_FlashTabl +@@ -44,6 +44,8 @@ static const flashdev_info gen_FlashTabl {0xADBC, 0x905554, 5, 16, 512, 128, 2048, 64, 0x10801011, "H9DA4GH4JJAMC", 0}, {0x01F1, 0x801D01, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "S34ML01G100TF", 0}, {0x92F1, 0x8095FF, 4, 8, 128, 128, 2048, 64, 0x30C77fff, "F59L1G81A", 0}, diff --git a/target/linux/ramips/patches-4.9/0053-mtd-spi-nor-add-w25q256-3b-mode-switch.patch b/target/linux/ramips/patches-4.9/0053-mtd-spi-nor-add-w25q256-3b-mode-switch.patch new file mode 100644 index 000000000..9d45ad010 --- /dev/null +++ b/target/linux/ramips/patches-4.9/0053-mtd-spi-nor-add-w25q256-3b-mode-switch.patch @@ -0,0 +1,214 @@ +mtd: spi-nor: add support for switching between 3-byte and 4-byte addressing on w25q256 flash + +On some devices the flash chip needs to be in 3-byte addressing mode during +reboot, otherwise the boot loader will fail to start. +This mode however does not allow regular reads/writes onto the upper 16M +half. W25Q256 has separate read commands for reading from >16M, however +it does not have any separate write commands. +This patch changes the code to leave the chip in 3-byte mode most of the +time and only switch during erase/write cycles that go to >16M +addresses. + +Signed-off-by: Felix Fietkau +--- +--- a/drivers/mtd/spi-nor/spi-nor.c ++++ b/drivers/mtd/spi-nor/spi-nor.c +@@ -85,6 +85,10 @@ struct flash_info { + * Use dedicated 4byte address op codes + * to support memory size above 128Mib. + */ ++#define SPI_NOR_4B_READ_OP BIT(12) /* ++ * Like SPI_NOR_4B_OPCODES, but for read ++ * op code only. ++ */ + }; + + #define JEDEC_MFR(info) ((info)->id[0]) +@@ -250,6 +254,15 @@ static inline u8 spi_nor_convert_3to4_er + ARRAY_SIZE(spi_nor_3to4_erase)); + } + ++static void spi_nor_set_4byte_read(struct spi_nor *nor, ++ const struct flash_info *info) ++{ ++ nor->addr_width = 3; ++ nor->ext_addr = 0; ++ nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode); ++ nor->flags |= SNOR_F_4B_EXT_ADDR; ++} ++ + static void spi_nor_set_4byte_opcodes(struct spi_nor *nor, + const struct flash_info *info) + { +@@ -467,6 +480,36 @@ static int spi_nor_erase_sector(struct s + return nor->write_reg(nor, nor->erase_opcode, buf, nor->addr_width); + } + ++static int spi_nor_check_ext_addr(struct spi_nor *nor, u32 addr) ++{ ++ bool ext_addr; ++ int ret; ++ u8 cmd; ++ ++ if (!(nor->flags & SNOR_F_4B_EXT_ADDR)) ++ return 0; ++ ++ ext_addr = !!(addr & 0xff000000); ++ if (nor->ext_addr == ext_addr) ++ return 0; ++ ++ cmd = ext_addr ? SPINOR_OP_EN4B : SPINOR_OP_EX4B; ++ write_enable(nor); ++ ret = nor->write_reg(nor, cmd, NULL, 0); ++ if (ret) ++ return ret; ++ ++ cmd = 0; ++ ret = nor->write_reg(nor, SPINOR_OP_WREAR, &cmd, 1); ++ if (ret) ++ return ret; ++ ++ nor->addr_width = 3 + ext_addr; ++ nor->ext_addr = ext_addr; ++ write_disable(nor); ++ return 0; ++} ++ + /* + * 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. +@@ -492,6 +535,10 @@ static int spi_nor_erase(struct mtd_info + if (ret) + return ret; + ++ ret = spi_nor_check_ext_addr(nor, addr + len); ++ if (ret) ++ return ret; ++ + /* whole-chip erase? */ + if (len == mtd->size && !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) { + unsigned long timeout; +@@ -542,6 +589,7 @@ static int spi_nor_erase(struct mtd_info + write_disable(nor); + + erase_err: ++ spi_nor_check_ext_addr(nor, 0); + spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE); + + instr->state = ret ? MTD_ERASE_FAILED : MTD_ERASE_DONE; +@@ -834,7 +882,9 @@ static int spi_nor_lock(struct mtd_info + if (ret) + return ret; + ++ spi_nor_check_ext_addr(nor, ofs + len); + ret = nor->flash_lock(nor, ofs, len); ++ spi_nor_check_ext_addr(nor, 0); + + spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK); + return ret; +@@ -849,7 +899,9 @@ static int spi_nor_unlock(struct mtd_inf + if (ret) + return ret; + ++ spi_nor_check_ext_addr(nor, ofs + len); + ret = nor->flash_unlock(nor, ofs, len); ++ spi_nor_check_ext_addr(nor, 0); + + spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK); + return ret; +@@ -1151,7 +1203,7 @@ static const struct flash_info spi_nor_i + { "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) }, ++ { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_READ_OP) }, + + /* Catalyst / On Semiconductor -- non-JEDEC */ + { "cat25c11", CAT25_INFO( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, +@@ -1205,6 +1257,9 @@ static int spi_nor_read(struct mtd_info + if (ret) + return ret; + ++ if (nor->flags & SNOR_F_4B_EXT_ADDR) ++ nor->addr_width = 4; ++ + while (len) { + loff_t addr = from; + +@@ -1229,6 +1284,18 @@ static int spi_nor_read(struct mtd_info + ret = 0; + + read_err: ++ if (nor->flags & SNOR_F_4B_EXT_ADDR) { ++ u8 val = 0; ++ ++ if ((from + len) & 0xff000000) { ++ write_enable(nor); ++ nor->write_reg(nor, SPINOR_OP_WREAR, &val, 1); ++ write_disable(nor); ++ } ++ ++ nor->addr_width = 3; ++ } ++ + spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ); + return ret; + } +@@ -1330,6 +1397,10 @@ static int spi_nor_write(struct mtd_info + if (ret) + return ret; + ++ ret = spi_nor_check_ext_addr(nor, to + len); ++ if (ret < 0) ++ return ret; ++ + for (i = 0; i < len; ) { + ssize_t written; + loff_t addr = to + i; +@@ -1377,6 +1448,7 @@ static int spi_nor_write(struct mtd_info + } + + write_err: ++ spi_nor_check_ext_addr(nor, 0); + spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE); + return ret; + } +@@ -1717,8 +1789,10 @@ int spi_nor_scan(struct spi_nor *nor, co + else if (mtd->size > 0x1000000) { + /* enable 4-byte addressing if the device exceeds 16MiB */ + nor->addr_width = 4; +- if (JEDEC_MFR(info) == SNOR_MFR_SPANSION || +- info->flags & SPI_NOR_4B_OPCODES) ++ if (info->flags & SPI_NOR_4B_READ_OP) ++ spi_nor_set_4byte_read(nor, info); ++ else if (JEDEC_MFR(info) == SNOR_MFR_SPANSION || ++ info->flags & SPI_NOR_4B_OPCODES) + spi_nor_set_4byte_opcodes(nor, info); + else + set_4byte(nor, info, 1); +--- a/include/linux/mtd/spi-nor.h ++++ b/include/linux/mtd/spi-nor.h +@@ -90,6 +90,7 @@ + /* Used for Macronix and Winbond flashes. */ + #define SPINOR_OP_EN4B 0xb7 /* Enter 4-byte mode */ + #define SPINOR_OP_EX4B 0xe9 /* Exit 4-byte mode */ ++#define SPINOR_OP_WREAR 0xc5 /* Write extended address register */ + + /* Used for Spansion flashes only. */ + #define SPINOR_OP_BRWR 0x17 /* Bank register write */ +@@ -141,6 +142,7 @@ enum spi_nor_option_flags { + SNOR_F_NO_OP_CHIP_ERASE = BIT(2), + SNOR_F_S3AN_ADDR_DEFAULT = BIT(3), + SNOR_F_READY_XSR_RDY = BIT(4), ++ SNOR_F_4B_EXT_ADDR = BIT(5), + }; + + /** +@@ -188,6 +190,7 @@ struct spi_nor { + enum read_mode flash_read; + bool sst_write_second; + u32 flags; ++ u8 ext_addr; + u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE]; + + int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops); diff --git a/target/linux/ramips/patches-4.9/0054-mtd-add-chunked-read-io-to-m25p80.patch b/target/linux/ramips/patches-4.9/0054-mtd-add-chunked-read-io-to-m25p80.patch index 40994fb8d..0a429d2bc 100644 --- a/target/linux/ramips/patches-4.9/0054-mtd-add-chunked-read-io-to-m25p80.patch +++ b/target/linux/ramips/patches-4.9/0054-mtd-add-chunked-read-io-to-m25p80.patch @@ -1,6 +1,6 @@ --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -1381,6 +1381,66 @@ write_err: +@@ -1453,6 +1453,67 @@ write_err: return ret; } @@ -8,6 +8,7 @@ + size_t *_retlen, const u_char *_buf) +{ + struct spi_nor *nor = mtd_to_spi_nor(mtd); ++ u32 addr_width = nor->addr_width + !!(nor->flags & SNOR_F_4B_EXT_ADDR); + int chunk_size; + int retlen = 0; + int ret; @@ -16,8 +17,8 @@ + if (!chunk_size) + chunk_size = _len; + -+ if (nor->addr_width > 3) -+ chunk_size -= nor->addr_width - 3; ++ if (addr_width > 3) ++ chunk_size -= addr_width - 3; + + while (retlen < _len) { + size_t len = min_t(int, chunk_size, _len - retlen); @@ -67,7 +68,7 @@ static int macronix_quad_enable(struct spi_nor *nor) { int ret, val; -@@ -1630,10 +1690,12 @@ int spi_nor_scan(struct spi_nor *nor, co +@@ -1702,10 +1763,12 @@ int spi_nor_scan(struct spi_nor *nor, co } /* sst nor chips use AAI word program */ @@ -82,7 +83,7 @@ if (info->flags & USE_FSR) nor->flags |= SNOR_F_USE_FSR; -@@ -1663,11 +1725,20 @@ int spi_nor_scan(struct spi_nor *nor, co +@@ -1737,11 +1800,20 @@ int spi_nor_scan(struct spi_nor *nor, co mtd->writebufsize = nor->page_size; if (np) { @@ -105,15 +106,15 @@ nor->flash_read = SPI_NOR_FAST; --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h -@@ -141,6 +141,7 @@ enum spi_nor_option_flags { - SNOR_F_NO_OP_CHIP_ERASE = BIT(2), +@@ -143,6 +143,7 @@ enum spi_nor_option_flags { SNOR_F_S3AN_ADDR_DEFAULT = BIT(3), SNOR_F_READY_XSR_RDY = BIT(4), -+ SNOR_F_SST = BIT(5), + SNOR_F_4B_EXT_ADDR = BIT(5), ++ SNOR_F_SST = BIT(6), }; /** -@@ -180,6 +181,7 @@ struct spi_nor { +@@ -182,6 +183,7 @@ struct spi_nor { struct mutex lock; struct device *dev; u32 page_size; diff --git a/target/linux/ramips/patches-4.9/0063-set-CM_GCR_BASE_CMDEFTGT_MEM-according-to-datasheet.patch b/target/linux/ramips/patches-4.9/0063-set-CM_GCR_BASE_CMDEFTGT_MEM-according-to-datasheet.patch deleted file mode 100644 index d950c4757..000000000 --- a/target/linux/ramips/patches-4.9/0063-set-CM_GCR_BASE_CMDEFTGT_MEM-according-to-datasheet.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/arch/mips/include/asm/mips-cm.h -+++ b/arch/mips/include/asm/mips-cm.h -@@ -239,8 +239,7 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80) - #define CM_GCR_BASE_GCRBASE_MSK (_ULCAST_(0x1ffff) << 15) - #define CM_GCR_BASE_CMDEFTGT_SHF 0 - #define CM_GCR_BASE_CMDEFTGT_MSK (_ULCAST_(0x3) << 0) --#define CM_GCR_BASE_CMDEFTGT_DISABLED 0 --#define CM_GCR_BASE_CMDEFTGT_MEM 1 -+#define CM_GCR_BASE_CMDEFTGT_MEM 0 - #define CM_GCR_BASE_CMDEFTGT_IOCU0 2 - #define CM_GCR_BASE_CMDEFTGT_IOCU1 3 - diff --git a/target/linux/ramips/patches-4.9/0102-MIPS-ralink-Fix-MT7628-pinmux.patch b/target/linux/ramips/patches-4.9/0102-MIPS-ralink-Fix-MT7628-pinmux.patch new file mode 100644 index 000000000..f2d1ab170 --- /dev/null +++ b/target/linux/ramips/patches-4.9/0102-MIPS-ralink-Fix-MT7628-pinmux.patch @@ -0,0 +1,33 @@ +From 8ef4b43cd3794d63052d85898e42424fd3b14d24 Mon Sep 17 00:00:00 2001 +From: Mathias Kresin +Date: Thu, 11 May 2017 08:11:14 +0200 +Subject: [PATCH 1/2] MIPS: ralink: Fix MT7628 pinmux + +According to the datasheet the REFCLK pin is shared with GPIO#37 and +the PERST pin is shared with GPIO#36. + +Fixes: 53263a1c6852 ("MIPS: ralink: add mt7628an support") +Signed-off-by: Mathias Kresin +Acked-by: John Crispin +Cc: Ralf Baechle +Cc: linux-mips@linux-mips.org +Cc: # 3.19+ +Patchwork: https://patchwork.linux-mips.org/patch/16046/ +Signed-off-by: James Hogan +--- + arch/mips/ralink/mt7620.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/mips/ralink/mt7620.c ++++ b/arch/mips/ralink/mt7620.c +@@ -141,8 +141,8 @@ static struct rt2880_pmx_func i2c_grp_mt + FUNC("i2c", 0, 4, 2), + }; + +-static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 36, 1) }; +-static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 37, 1) }; ++static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 37, 1) }; ++static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 36, 1) }; + static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 38, 1) }; + static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) }; + diff --git a/target/linux/ramips/patches-4.9/0103-MIPS-ralink-Fix-typo-in-mt7628-pinmux-function b/target/linux/ramips/patches-4.9/0103-MIPS-ralink-Fix-typo-in-mt7628-pinmux-function new file mode 100644 index 000000000..9c77840f2 --- /dev/null +++ b/target/linux/ramips/patches-4.9/0103-MIPS-ralink-Fix-typo-in-mt7628-pinmux-function @@ -0,0 +1,31 @@ +From 05a67cc258e75ac9758e6f13d26337b8be51162a Mon Sep 17 00:00:00 2001 +From: Mathias Kresin +Date: Thu, 11 May 2017 08:11:15 +0200 +Subject: [PATCH 2/2] MIPS: ralink: Fix typo in mt7628 pinmux function + +There is a typo inside the pinmux setup code. The function is called +refclk and not reclk. + +Fixes: 53263a1c6852 ("MIPS: ralink: add mt7628an support") +Signed-off-by: Mathias Kresin +Acked-by: John Crispin +Cc: Ralf Baechle +Cc: linux-mips@linux-mips.org +Cc: # 3.19+ +Patchwork: https://patchwork.linux-mips.org/patch/16047/ +Signed-off-by: James Hogan +--- + arch/mips/ralink/mt7620.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/mips/ralink/mt7620.c ++++ b/arch/mips/ralink/mt7620.c +@@ -141,7 +141,7 @@ static struct rt2880_pmx_func i2c_grp_mt + FUNC("i2c", 0, 4, 2), + }; + +-static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 37, 1) }; ++static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("refclk", 0, 37, 1) }; + static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 36, 1) }; + static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 38, 1) }; + static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) }; diff --git a/target/linux/ramips/rt305x/config-4.9 b/target/linux/ramips/rt305x/config-4.9 index d7b53038d..ae843f372 100644 --- a/target/linux/ramips/rt305x/config-4.9 +++ b/target/linux/ramips/rt305x/config-4.9 @@ -134,6 +134,7 @@ CONFIG_MTD_M25P80=y CONFIG_MTD_PHYSMAP=y CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384 CONFIG_MTD_SPLIT_FIRMWARE=y CONFIG_MTD_SPLIT_SEAMA_FW=y CONFIG_MTD_SPLIT_UIMAGE_FW=y diff --git a/target/linux/ramips/rt3883/config-4.9 b/target/linux/ramips/rt3883/config-4.9 index 3e6b73f80..3b116e560 100644 --- a/target/linux/ramips/rt3883/config-4.9 +++ b/target/linux/ramips/rt3883/config-4.9 @@ -134,6 +134,7 @@ CONFIG_MTD_M25P80=y CONFIG_MTD_PHYSMAP=y CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384 CONFIG_MTD_SPLIT_FIRMWARE=y CONFIG_MTD_SPLIT_SEAMA_FW=y CONFIG_MTD_SPLIT_UIMAGE_FW=y diff --git a/target/linux/sunxi/patches-4.9/0052-stmmac-form-4-12.patch b/target/linux/sunxi/patches-4.9/0052-stmmac-form-4-12.patch index 285e4d276..a5cdec552 100644 --- a/target/linux/sunxi/patches-4.9/0052-stmmac-form-4-12.patch +++ b/target/linux/sunxi/patches-4.9/0052-stmmac-form-4-12.patch @@ -2887,7 +2887,7 @@ + + /* Display RX ring */ + priv->hw->desc->display_ring(head_rx, DMA_RX_SIZE, true); - } ++ } +} + +static void stmmac_display_tx_rings(struct stmmac_priv *priv) @@ -2906,15 +2906,15 @@ + head_tx = (void *)tx_q->dma_etx; + else + head_tx = (void *)tx_q->dma_tx; ++ ++ priv->hw->desc->display_ring(head_tx, DMA_TX_SIZE, false); + } ++} - /* Display Rx ring */ - priv->hw->desc->display_ring(head_rx, DMA_RX_SIZE, true); - /* Display Tx ring */ - priv->hw->desc->display_ring(head_tx, DMA_TX_SIZE, false); -+ priv->hw->desc->display_ring(head_tx, DMA_TX_SIZE, false); -+ } -+} -+ +static void stmmac_display_rings(struct stmmac_priv *priv) +{ + /* Display RX ring */ @@ -3131,7 +3131,7 @@ if (priv->hw->mode->set_16kib_bfsize) bfsize = priv->hw->mode->set_16kib_bfsize(dev->mtu); -@@ -1018,235 +1228,409 @@ static int init_dma_desc_rings(struct ne +@@ -1018,257 +1228,516 @@ static int init_dma_desc_rings(struct ne priv->dma_buf_sz = bfsize; @@ -3163,7 +3163,10 @@ + p = &((rx_q->dma_erx + i)->basic); + else + p = rx_q->dma_rx + i; -+ + +- ret = stmmac_init_rx_buffers(priv, p, i, flags); +- if (ret) +- goto err_init_rx_buffers; + ret = stmmac_init_rx_buffers(priv, p, i, flags, + queue); + if (ret) @@ -3173,18 +3176,15 @@ + rx_q->rx_skbuff[i], rx_q->rx_skbuff[i]->data, + (unsigned int)rx_q->rx_skbuff_dma[i]); + } - -- ret = stmmac_init_rx_buffers(priv, p, i, flags); -- if (ret) -- goto err_init_rx_buffers; ++ + rx_q->cur_rx = 0; + rx_q->dirty_rx = (unsigned int)(i - DMA_RX_SIZE); ++ ++ stmmac_clear_rx_descriptors(priv, queue); - netif_dbg(priv, probe, priv->dev, "[%p]\t[%p]\t[%x]\n", - priv->rx_skbuff[i], priv->rx_skbuff[i]->data, - (unsigned int)priv->rx_skbuff_dma[i]); -+ stmmac_clear_rx_descriptors(priv, queue); -+ + /* Setup the chained descriptor addresses */ + if (priv->mode == STMMAC_CHAIN_MODE) { + if (priv->extend_desc) @@ -3277,8 +3277,13 @@ + priv->hw->mode->init(tx_q->dma_tx, + tx_q->dma_tx_phy, + DMA_TX_SIZE, 0); -+ } -+ + } + +- priv->tx_skbuff_dma[i].buf = 0; +- priv->tx_skbuff_dma[i].map_as_page = false; +- priv->tx_skbuff_dma[i].len = 0; +- priv->tx_skbuff_dma[i].last_segment = false; +- priv->tx_skbuff[i] = NULL; + for (i = 0; i < DMA_TX_SIZE; i++) { + struct dma_desc *p; + if (priv->extend_desc) @@ -3300,13 +3305,8 @@ + tx_q->tx_skbuff_dma[i].len = 0; + tx_q->tx_skbuff_dma[i].last_segment = false; + tx_q->tx_skbuff[i] = NULL; - } - -- priv->tx_skbuff_dma[i].buf = 0; -- priv->tx_skbuff_dma[i].map_as_page = false; -- priv->tx_skbuff_dma[i].len = 0; -- priv->tx_skbuff_dma[i].last_segment = false; -- priv->tx_skbuff[i] = NULL; ++ } ++ + tx_q->dirty_tx = 0; + tx_q->cur_tx = 0; + @@ -3387,17 +3387,10 @@ - priv->tx_skbuff_dma[i].buf, - priv->tx_skbuff_dma[i].len, - DMA_TO_DEVICE); -- } + for (i = 0; i < DMA_TX_SIZE; i++) + stmmac_free_tx_buffer(priv, queue, i); +} - -- if (priv->tx_skbuff[i]) { -- dev_kfree_skb_any(priv->tx_skbuff[i]); -- priv->tx_skbuff[i] = NULL; -- priv->tx_skbuff_dma[i].buf = 0; -- priv->tx_skbuff_dma[i].map_as_page = false; -- } ++ +/** + * free_dma_rx_desc_resources - free RX dma desc resources + * @priv: private structure @@ -3426,11 +3419,10 @@ + + kfree(rx_q->rx_skbuff_dma); + kfree(rx_q->rx_skbuff); - } - } - - /** -- * alloc_dma_desc_resources - alloc TX/RX resources. ++ } ++} ++ ++/** + * free_dma_tx_desc_resources - free TX dma desc resources + * @priv: private structure + */ @@ -3463,90 +3455,36 @@ + +/** + * alloc_dma_rx_desc_resources - alloc RX resources. - * @priv: private structure - * Description: according to which descriptor can be used (extend or basic) - * this function allocates the resources for TX and RX paths. In case of - * reception, for example, it pre-allocated the RX socket buffer in order to - * allow zero-copy mechanism. - */ --static int alloc_dma_desc_resources(struct stmmac_priv *priv) ++ * @priv: private structure ++ * Description: according to which descriptor can be used (extend or basic) ++ * this function allocates the resources for TX and RX paths. In case of ++ * reception, for example, it pre-allocated the RX socket buffer in order to ++ * allow zero-copy mechanism. ++ */ +static int alloc_dma_rx_desc_resources(struct stmmac_priv *priv) - { ++{ + u32 rx_count = priv->plat->rx_queues_to_use; - int ret = -ENOMEM; ++ int ret = -ENOMEM; + u32 queue; - -- priv->rx_skbuff_dma = kmalloc_array(DMA_RX_SIZE, sizeof(dma_addr_t), -- GFP_KERNEL); -- if (!priv->rx_skbuff_dma) -- return -ENOMEM; ++ + /* RX queues buffers and DMA */ + for (queue = 0; queue < rx_count; queue++) { + struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; - -- priv->rx_skbuff = kmalloc_array(DMA_RX_SIZE, sizeof(struct sk_buff *), -- GFP_KERNEL); -- if (!priv->rx_skbuff) -- goto err_rx_skbuff; -- -- priv->tx_skbuff_dma = kmalloc_array(DMA_TX_SIZE, -- sizeof(*priv->tx_skbuff_dma), -- GFP_KERNEL); -- if (!priv->tx_skbuff_dma) -- goto err_tx_skbuff_dma; -- -- priv->tx_skbuff = kmalloc_array(DMA_TX_SIZE, sizeof(struct sk_buff *), -- GFP_KERNEL); -- if (!priv->tx_skbuff) -- goto err_tx_skbuff; -- -- if (priv->extend_desc) { -- priv->dma_erx = dma_zalloc_coherent(priv->device, DMA_RX_SIZE * -- sizeof(struct -- dma_extended_desc), -- &priv->dma_rx_phy, -- GFP_KERNEL); -- if (!priv->dma_erx) -- goto err_dma; ++ + rx_q->queue_index = queue; + rx_q->priv_data = priv; - -- priv->dma_etx = dma_zalloc_coherent(priv->device, DMA_TX_SIZE * -- sizeof(struct -- dma_extended_desc), -- &priv->dma_tx_phy, ++ + rx_q->rx_skbuff_dma = kmalloc_array(DMA_RX_SIZE, + sizeof(dma_addr_t), - GFP_KERNEL); -- if (!priv->dma_etx) { -- dma_free_coherent(priv->device, DMA_RX_SIZE * -- sizeof(struct dma_extended_desc), -- priv->dma_erx, priv->dma_rx_phy); -- goto err_dma; -- } -- } else { -- priv->dma_rx = dma_zalloc_coherent(priv->device, DMA_RX_SIZE * -- sizeof(struct dma_desc), -- &priv->dma_rx_phy, -- GFP_KERNEL); -- if (!priv->dma_rx) -- goto err_dma; ++ GFP_KERNEL); + if (!rx_q->rx_skbuff_dma) + return -ENOMEM; - -- priv->dma_tx = dma_zalloc_coherent(priv->device, DMA_TX_SIZE * -- sizeof(struct dma_desc), -- &priv->dma_tx_phy, -- GFP_KERNEL); -- if (!priv->dma_tx) { -- dma_free_coherent(priv->device, DMA_RX_SIZE * -- sizeof(struct dma_desc), -- priv->dma_rx, priv->dma_rx_phy); ++ + rx_q->rx_skbuff = kmalloc_array(DMA_RX_SIZE, + sizeof(struct sk_buff *), + GFP_KERNEL); + if (!rx_q->rx_skbuff) - goto err_dma; ++ goto err_dma; + + if (priv->extend_desc) { + rx_q->dma_erx = dma_zalloc_coherent(priv->device, @@ -3567,19 +3505,12 @@ + GFP_KERNEL); + if (!rx_q->dma_rx) + goto err_dma; - } - } - - return 0; - - err_dma: -- kfree(priv->tx_skbuff); --err_tx_skbuff: -- kfree(priv->tx_skbuff_dma); --err_tx_skbuff_dma: -- kfree(priv->rx_skbuff); --err_rx_skbuff: -- kfree(priv->rx_skbuff_dma); ++ } ++ } ++ ++ return 0; ++ ++err_dma: + free_dma_rx_desc_resources(priv); + + return ret; @@ -3636,7 +3567,7 @@ + GFP_KERNEL); + if (!tx_q->dma_tx) + goto err_dma_buffers; -+ } + } + } + + return 0; @@ -3644,9 +3575,9 @@ +err_dma_buffers: + free_dma_tx_desc_resources(priv); + - return ret; - } - ++ return ret; ++} ++ +/** + * alloc_dma_desc_resources - alloc TX/RX resources. + * @priv: private structure @@ -3672,7 +3603,176 @@ + * free_dma_desc_resources - free dma desc resources + * @priv: private structure + */ - static void free_dma_desc_resources(struct stmmac_priv *priv) ++static void free_dma_desc_resources(struct stmmac_priv *priv) ++{ ++ /* Release the DMA RX socket buffers */ ++ free_dma_rx_desc_resources(priv); ++ ++ /* Release the DMA TX socket buffers */ ++ free_dma_tx_desc_resources(priv); ++} ++ ++/** ++ * stmmac_mac_enable_rx_queues - Enable MAC rx queues ++ * @priv: driver private structure ++ * Description: It is used for enabling the rx queues in the MAC ++ */ ++static void stmmac_mac_enable_rx_queues(struct stmmac_priv *priv) ++{ ++ u32 rx_queues_count = priv->plat->rx_queues_to_use; ++ int queue; ++ u8 mode; + +- if (priv->tx_skbuff[i]) { +- dev_kfree_skb_any(priv->tx_skbuff[i]); +- priv->tx_skbuff[i] = NULL; +- priv->tx_skbuff_dma[i].buf = 0; +- priv->tx_skbuff_dma[i].map_as_page = false; +- } ++ for (queue = 0; queue < rx_queues_count; queue++) { ++ mode = priv->plat->rx_queues_cfg[queue].mode_to_use; ++ priv->hw->mac->rx_queue_enable(priv->hw, mode, queue); + } + } + + /** +- * alloc_dma_desc_resources - alloc TX/RX resources. +- * @priv: private structure +- * Description: according to which descriptor can be used (extend or basic) +- * this function allocates the resources for TX and RX paths. In case of +- * reception, for example, it pre-allocated the RX socket buffer in order to +- * allow zero-copy mechanism. ++ * stmmac_start_rx_dma - start RX DMA channel ++ * @priv: driver private structure ++ * @chan: RX channel index ++ * Description: ++ * This starts a RX DMA channel + */ +-static int alloc_dma_desc_resources(struct stmmac_priv *priv) ++static void stmmac_start_rx_dma(struct stmmac_priv *priv, u32 chan) + { +- int ret = -ENOMEM; +- +- priv->rx_skbuff_dma = kmalloc_array(DMA_RX_SIZE, sizeof(dma_addr_t), +- GFP_KERNEL); +- if (!priv->rx_skbuff_dma) +- return -ENOMEM; +- +- priv->rx_skbuff = kmalloc_array(DMA_RX_SIZE, sizeof(struct sk_buff *), +- GFP_KERNEL); +- if (!priv->rx_skbuff) +- goto err_rx_skbuff; +- +- priv->tx_skbuff_dma = kmalloc_array(DMA_TX_SIZE, +- sizeof(*priv->tx_skbuff_dma), +- GFP_KERNEL); +- if (!priv->tx_skbuff_dma) +- goto err_tx_skbuff_dma; +- +- priv->tx_skbuff = kmalloc_array(DMA_TX_SIZE, sizeof(struct sk_buff *), +- GFP_KERNEL); +- if (!priv->tx_skbuff) +- goto err_tx_skbuff; +- +- if (priv->extend_desc) { +- priv->dma_erx = dma_zalloc_coherent(priv->device, DMA_RX_SIZE * +- sizeof(struct +- dma_extended_desc), +- &priv->dma_rx_phy, +- GFP_KERNEL); +- if (!priv->dma_erx) +- goto err_dma; +- +- priv->dma_etx = dma_zalloc_coherent(priv->device, DMA_TX_SIZE * +- sizeof(struct +- dma_extended_desc), +- &priv->dma_tx_phy, +- GFP_KERNEL); +- if (!priv->dma_etx) { +- dma_free_coherent(priv->device, DMA_RX_SIZE * +- sizeof(struct dma_extended_desc), +- priv->dma_erx, priv->dma_rx_phy); +- goto err_dma; +- } +- } else { +- priv->dma_rx = dma_zalloc_coherent(priv->device, DMA_RX_SIZE * +- sizeof(struct dma_desc), +- &priv->dma_rx_phy, +- GFP_KERNEL); +- if (!priv->dma_rx) +- goto err_dma; ++ netdev_dbg(priv->dev, "DMA RX processes started in channel %d\n", chan); ++ priv->hw->dma->start_rx(priv->ioaddr, chan); ++} + +- priv->dma_tx = dma_zalloc_coherent(priv->device, DMA_TX_SIZE * +- sizeof(struct dma_desc), +- &priv->dma_tx_phy, +- GFP_KERNEL); +- if (!priv->dma_tx) { +- dma_free_coherent(priv->device, DMA_RX_SIZE * +- sizeof(struct dma_desc), +- priv->dma_rx, priv->dma_rx_phy); +- goto err_dma; +- } +- } ++/** ++ * stmmac_start_tx_dma - start TX DMA channel ++ * @priv: driver private structure ++ * @chan: TX channel index ++ * Description: ++ * This starts a TX DMA channel ++ */ ++static void stmmac_start_tx_dma(struct stmmac_priv *priv, u32 chan) ++{ ++ netdev_dbg(priv->dev, "DMA TX processes started in channel %d\n", chan); ++ priv->hw->dma->start_tx(priv->ioaddr, chan); ++} + +- return 0; ++/** ++ * stmmac_stop_rx_dma - stop RX DMA channel ++ * @priv: driver private structure ++ * @chan: RX channel index ++ * Description: ++ * This stops a RX DMA channel ++ */ ++static void stmmac_stop_rx_dma(struct stmmac_priv *priv, u32 chan) ++{ ++ netdev_dbg(priv->dev, "DMA RX processes stopped in channel %d\n", chan); ++ priv->hw->dma->stop_rx(priv->ioaddr, chan); ++} + +-err_dma: +- kfree(priv->tx_skbuff); +-err_tx_skbuff: +- kfree(priv->tx_skbuff_dma); +-err_tx_skbuff_dma: +- kfree(priv->rx_skbuff); +-err_rx_skbuff: +- kfree(priv->rx_skbuff_dma); +- return ret; ++/** ++ * stmmac_stop_tx_dma - stop TX DMA channel ++ * @priv: driver private structure ++ * @chan: TX channel index ++ * Description: ++ * This stops a TX DMA channel ++ */ ++static void stmmac_stop_tx_dma(struct stmmac_priv *priv, u32 chan) ++{ ++ netdev_dbg(priv->dev, "DMA TX processes stopped in channel %d\n", chan); ++ priv->hw->dma->stop_tx(priv->ioaddr, chan); + } + +-static void free_dma_desc_resources(struct stmmac_priv *priv) ++/** ++ * stmmac_start_all_dma - start all RX and TX DMA channels ++ * @priv: driver private structure ++ * Description: ++ * This starts all the RX and TX DMA channels ++ */ ++static void stmmac_start_all_dma(struct stmmac_priv *priv) { - /* Release the DMA TX/RX socket buffers */ - dma_free_rx_skbufs(priv); @@ -3698,99 +3798,6 @@ - kfree(priv->rx_skbuff); - kfree(priv->tx_skbuff_dma); - kfree(priv->tx_skbuff); -+ /* Release the DMA RX socket buffers */ -+ free_dma_rx_desc_resources(priv); -+ -+ /* Release the DMA TX socket buffers */ -+ free_dma_tx_desc_resources(priv); - } - - /** -@@ -1256,19 +1640,104 @@ static void free_dma_desc_resources(stru - */ - static void stmmac_mac_enable_rx_queues(struct stmmac_priv *priv) - { -- int rx_count = priv->dma_cap.number_rx_queues; -- int queue = 0; -+ u32 rx_queues_count = priv->plat->rx_queues_to_use; -+ int queue; -+ u8 mode; - -- /* If GMAC does not have multiple queues, then this is not necessary*/ -- if (rx_count == 1) -- return; -+ for (queue = 0; queue < rx_queues_count; queue++) { -+ mode = priv->plat->rx_queues_cfg[queue].mode_to_use; -+ priv->hw->mac->rx_queue_enable(priv->hw, mode, queue); -+ } -+} - -- /** -- * If the core is synthesized with multiple rx queues / multiple -- * dma channels, then rx queues will be disabled by default. -- * For now only rx queue 0 is enabled. -- */ -- priv->hw->mac->rx_queue_enable(priv->hw, queue); -+/** -+ * stmmac_start_rx_dma - start RX DMA channel -+ * @priv: driver private structure -+ * @chan: RX channel index -+ * Description: -+ * This starts a RX DMA channel -+ */ -+static void stmmac_start_rx_dma(struct stmmac_priv *priv, u32 chan) -+{ -+ netdev_dbg(priv->dev, "DMA RX processes started in channel %d\n", chan); -+ priv->hw->dma->start_rx(priv->ioaddr, chan); -+} -+ -+/** -+ * stmmac_start_tx_dma - start TX DMA channel -+ * @priv: driver private structure -+ * @chan: TX channel index -+ * Description: -+ * This starts a TX DMA channel -+ */ -+static void stmmac_start_tx_dma(struct stmmac_priv *priv, u32 chan) -+{ -+ netdev_dbg(priv->dev, "DMA TX processes started in channel %d\n", chan); -+ priv->hw->dma->start_tx(priv->ioaddr, chan); -+} -+ -+/** -+ * stmmac_stop_rx_dma - stop RX DMA channel -+ * @priv: driver private structure -+ * @chan: RX channel index -+ * Description: -+ * This stops a RX DMA channel -+ */ -+static void stmmac_stop_rx_dma(struct stmmac_priv *priv, u32 chan) -+{ -+ netdev_dbg(priv->dev, "DMA RX processes stopped in channel %d\n", chan); -+ priv->hw->dma->stop_rx(priv->ioaddr, chan); -+} -+ -+/** -+ * stmmac_stop_tx_dma - stop TX DMA channel -+ * @priv: driver private structure -+ * @chan: TX channel index -+ * Description: -+ * This stops a TX DMA channel -+ */ -+static void stmmac_stop_tx_dma(struct stmmac_priv *priv, u32 chan) -+{ -+ netdev_dbg(priv->dev, "DMA TX processes stopped in channel %d\n", chan); -+ priv->hw->dma->stop_tx(priv->ioaddr, chan); -+} -+ -+/** -+ * stmmac_start_all_dma - start all RX and TX DMA channels -+ * @priv: driver private structure -+ * Description: -+ * This starts all the RX and TX DMA channels -+ */ -+static void stmmac_start_all_dma(struct stmmac_priv *priv) -+{ + u32 rx_channels_count = priv->plat->rx_queues_to_use; + u32 tx_channels_count = priv->plat->tx_queues_to_use; + u32 chan = 0; @@ -3800,23 +3807,38 @@ + + for (chan = 0; chan < tx_channels_count; chan++) + stmmac_start_tx_dma(priv, chan); -+} -+ -+/** + } + + /** +- * stmmac_mac_enable_rx_queues - Enable MAC rx queues +- * @priv: driver private structure +- * Description: It is used for enabling the rx queues in the MAC + * stmmac_stop_all_dma - stop all RX and TX DMA channels + * @priv: driver private structure + * Description: + * This stops the RX and TX DMA channels -+ */ + */ +-static void stmmac_mac_enable_rx_queues(struct stmmac_priv *priv) +static void stmmac_stop_all_dma(struct stmmac_priv *priv) -+{ + { +- int rx_count = priv->dma_cap.number_rx_queues; +- int queue = 0; + u32 rx_channels_count = priv->plat->rx_queues_to_use; + u32 tx_channels_count = priv->plat->tx_queues_to_use; + u32 chan = 0; -+ + +- /* If GMAC does not have multiple queues, then this is not necessary*/ +- if (rx_count == 1) +- return; + for (chan = 0; chan < rx_channels_count; chan++) + stmmac_stop_rx_dma(priv, chan); -+ + +- /** +- * If the core is synthesized with multiple rx queues / multiple +- * dma channels, then rx queues will be disabled by default. +- * For now only rx queue 0 is enabled. +- */ +- priv->hw->mac->rx_queue_enable(priv->hw, queue); + for (chan = 0; chan < tx_channels_count; chan++) + stmmac_stop_tx_dma(priv, chan); } diff --git a/target/linux/uml/Makefile b/target/linux/uml/Makefile index 6967e403c..0b4603292 100644 --- a/target/linux/uml/Makefile +++ b/target/linux/uml/Makefile @@ -22,7 +22,7 @@ BOARDNAME:=User Mode Linux FEATURES:=squashfs ext4 audio source-only MAINTAINER:=Florian Fainelli -KERNEL_PATCHVER:=4.4 +KERNEL_PATCHVER:=4.9 include $(INCLUDE_DIR)/target.mk diff --git a/target/linux/uml/patches-4.9/000-um-Avoid-longjmp-setjmp-symbol-clashes-with-libpthre.patch b/target/linux/uml/patches-4.9/000-um-Avoid-longjmp-setjmp-symbol-clashes-with-libpthre.patch new file mode 100644 index 000000000..02149eea7 --- /dev/null +++ b/target/linux/uml/patches-4.9/000-um-Avoid-longjmp-setjmp-symbol-clashes-with-libpthre.patch @@ -0,0 +1,130 @@ +From f44f1e7da7c8e3f4575d5d61c4df978496903fcc Mon Sep 17 00:00:00 2001 +From: Florian Fainelli +Date: Tue, 23 May 2017 17:32:31 -0700 +Subject: [PATCH] um: Avoid longjmp/setjmp symbol clashes with libpthread.a + +[ Upstream commit f44f1e7da7c8e3f4575d5d61c4df978496903fcc ] + +Building a statically linked UML kernel on a Centos 6.9 host resulted in +the following linking failure (GCC 4.4, glibc-2.12): + +/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/libpthread.a(libpthread.o): +In function `siglongjmp': +(.text+0x8490): multiple definition of `longjmp' +arch/x86/um/built-in.o:/local/users/fainelli/openwrt/trunk/build_dir/target-x86_64_musl/linux-uml/linux-4.4.69/arch/x86/um/setjmp_64.S:44: +first defined here +/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/libpthread.a(libpthread.o): +In function `sem_open': +(.text+0x77cd): warning: the use of `mktemp' is dangerous, better use +`mkstemp' +collect2: ld returned 1 exit status +make[4]: *** [vmlinux] Error 1 + +Adopt a solution similar to the one done for vmap where we define +longjmp/setjmp to be kernel_longjmp/setjmp. In the process, make sure we +do rename the functions in arch/x86/um/setjmp_*.S accordingly. + +Fixes: a7df4716d195 ("um: link with -lpthread") +Signed-off-by: Florian Fainelli +Signed-off-by: Richard Weinberger +--- + arch/um/Makefile | 4 ++++ + arch/x86/um/setjmp_32.S | 16 ++++++++-------- + arch/x86/um/setjmp_64.S | 16 ++++++++-------- + 3 files changed, 20 insertions(+), 16 deletions(-) + +--- a/arch/um/Makefile ++++ b/arch/um/Makefile +@@ -59,10 +59,14 @@ KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_D + # Same things for in6addr_loopback and mktime - found in libc. For these two we + # only get link-time error, luckily. + # ++# -Dlongjmp=kernel_longjmp prevents anything from referencing the libpthread.a ++# embedded copy of longjmp, same thing for setjmp. ++# + # These apply to USER_CFLAGS to. + + KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ \ + $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \ ++ -Dlongjmp=kernel_longjmp -Dsetjmp=kernel_setjmp \ + -Din6addr_loopback=kernel_in6addr_loopback \ + -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr + +--- a/arch/x86/um/setjmp_32.S ++++ b/arch/x86/um/setjmp_32.S +@@ -16,9 +16,9 @@ + + .text + .align 4 +- .globl setjmp +- .type setjmp, @function +-setjmp: ++ .globl kernel_setjmp ++ .type kernel_setjmp, @function ++kernel_setjmp: + #ifdef _REGPARM + movl %eax,%edx + #else +@@ -35,13 +35,13 @@ setjmp: + movl %ecx,20(%edx) # Return address + ret + +- .size setjmp,.-setjmp ++ .size kernel_setjmp,.-kernel_setjmp + + .text + .align 4 +- .globl longjmp +- .type longjmp, @function +-longjmp: ++ .globl kernel_longjmp ++ .type kernel_longjmp, @function ++kernel_longjmp: + #ifdef _REGPARM + xchgl %eax,%edx + #else +@@ -55,4 +55,4 @@ longjmp: + movl 16(%edx),%edi + jmp *20(%edx) + +- .size longjmp,.-longjmp ++ .size kernel_longjmp,.-kernel_longjmp +--- a/arch/x86/um/setjmp_64.S ++++ b/arch/x86/um/setjmp_64.S +@@ -18,9 +18,9 @@ + + .text + .align 4 +- .globl setjmp +- .type setjmp, @function +-setjmp: ++ .globl kernel_setjmp ++ .type kernel_setjmp, @function ++kernel_setjmp: + pop %rsi # Return address, and adjust the stack + xorl %eax,%eax # Return value + movq %rbx,(%rdi) +@@ -34,13 +34,13 @@ setjmp: + movq %rsi,56(%rdi) # Return address + ret + +- .size setjmp,.-setjmp ++ .size kernel_setjmp,.-kernel_setjmp + + .text + .align 4 +- .globl longjmp +- .type longjmp, @function +-longjmp: ++ .globl kernel_longjmp ++ .type kernel_longjmp, @function ++kernel_longjmp: + movl %esi,%eax # Return value (int) + movq (%rdi),%rbx + movq 8(%rdi),%rsp +@@ -51,4 +51,4 @@ longjmp: + movq 48(%rdi),%r15 + jmp *56(%rdi) + +- .size longjmp,.-longjmp ++ .size kernel_longjmp,.-kernel_longjmp diff --git a/target/linux/uml/patches-4.9/001-um-Allow-building-and-running-on-older-hosts.patch b/target/linux/uml/patches-4.9/001-um-Allow-building-and-running-on-older-hosts.patch new file mode 100644 index 000000000..501cca82f --- /dev/null +++ b/target/linux/uml/patches-4.9/001-um-Allow-building-and-running-on-older-hosts.patch @@ -0,0 +1,99 @@ +From 0a987645672ebde7844a9c0732a5a25f3d4bb6c6 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli +Date: Thu, 25 May 2017 11:36:26 -0700 +Subject: [PATCH] um: Allow building and running on older hosts + +[ Upstream commit 0a987645672ebde7844a9c0732a5a25f3d4bb6c6 ] + +Commit a78ff1112263 ("um: add extended processor state save/restore +support") and b6024b21fec8 ("um: extend fpstate to _xstate to support +YMM registers") forced the use of the x86 FP _xstate and +PTRACE_GETREGSET/SETREGSET. On older hosts, we would neither be able to +build UML nor run it anymore with these two commits applied because we +don't have definitions for struct _xstate nor these two ptrace requests. + +We can determine at build time which fp context structure to check +against, just like we can keep using the old i387 fp save/restore if +PTRACE_GETRESET/SETREGSET are not defined. + +Fixes: a78ff1112263 ("um: add extended processor state save/restore support") +Fixes: b6024b21fec8 ("um: extend fpstate to _xstate to support YMM registers") +Signed-off-by: Florian Fainelli +Signed-off-by: Richard Weinberger +--- + arch/x86/um/os-Linux/registers.c | 12 ++++++++---- + arch/x86/um/user-offsets.c | 4 ++++ + 2 files changed, 12 insertions(+), 4 deletions(-) + +--- a/arch/x86/um/os-Linux/registers.c ++++ b/arch/x86/um/os-Linux/registers.c +@@ -26,6 +26,7 @@ int save_i387_registers(int pid, unsigne + + int save_fp_registers(int pid, unsigned long *fp_regs) + { ++#ifdef PTRACE_GETREGSET + struct iovec iov; + + if (have_xstate_support) { +@@ -34,9 +35,9 @@ int save_fp_registers(int pid, unsigned + if (ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov) < 0) + return -errno; + return 0; +- } else { ++ } else ++#endif + return save_i387_registers(pid, fp_regs); +- } + } + + int restore_i387_registers(int pid, unsigned long *fp_regs) +@@ -48,6 +49,7 @@ int restore_i387_registers(int pid, unsi + + int restore_fp_registers(int pid, unsigned long *fp_regs) + { ++#ifdef PTRACE_SETREGSET + struct iovec iov; + + if (have_xstate_support) { +@@ -56,9 +58,9 @@ int restore_fp_registers(int pid, unsign + if (ptrace(PTRACE_SETREGSET, pid, NT_X86_XSTATE, &iov) < 0) + return -errno; + return 0; +- } else { ++ } else ++#endif + return restore_i387_registers(pid, fp_regs); +- } + } + + #ifdef __i386__ +@@ -122,6 +124,7 @@ int put_fp_registers(int pid, unsigned l + + void arch_init_registers(int pid) + { ++#ifdef PTRACE_GETREGSET + struct _xstate fp_regs; + struct iovec iov; + +@@ -129,6 +132,7 @@ void arch_init_registers(int pid) + iov.iov_len = sizeof(struct _xstate); + if (ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov) == 0) + have_xstate_support = 1; ++#endif + } + #endif + +--- a/arch/x86/um/user-offsets.c ++++ b/arch/x86/um/user-offsets.c +@@ -50,7 +50,11 @@ void foo(void) + DEFINE(HOST_GS, GS); + DEFINE(HOST_ORIG_AX, ORIG_EAX); + #else ++#if defined(PTRACE_GETREGSET) && defined(PTRACE_SETREGSET) + DEFINE(HOST_FP_SIZE, sizeof(struct _xstate) / sizeof(unsigned long)); ++#else ++ DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); ++#endif + DEFINE_LONGS(HOST_BX, RBX); + DEFINE_LONGS(HOST_CX, RCX); + DEFINE_LONGS(HOST_DI, RDI); diff --git a/target/linux/uml/patches-4.9/002-um-Correctly-check-for-PTRACE_GETRESET-SETREGSET.patch b/target/linux/uml/patches-4.9/002-um-Correctly-check-for-PTRACE_GETRESET-SETREGSET.patch new file mode 100644 index 000000000..79beb823c --- /dev/null +++ b/target/linux/uml/patches-4.9/002-um-Correctly-check-for-PTRACE_GETRESET-SETREGSET.patch @@ -0,0 +1,29 @@ +From 61e8d462457f202bf0c6393133425ad387825e22 Mon Sep 17 00:00:00 2001 +From: Richard Weinberger +Date: Thu, 6 Jul 2017 09:35:27 +0200 +Subject: [PATCH] um: Correctly check for PTRACE_GETRESET/SETREGSET + +[ Upstream commit 61e8d462457f202bf0c6393133425ad387825e22 ] + +When checking for PTRACE_GETRESET/SETREGSET, make sure that +the correct header file is included. We need linux/ptrace.h +which contains all ptrace UAPI related defines. +Otherwise #if defined(PTRACE_GETRESET) is always false. + +Cc: Florian Fainelli +Signed-off-by: Richard Weinberger +--- + arch/x86/um/user-offsets.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/um/user-offsets.c ++++ b/arch/x86/um/user-offsets.c +@@ -5,7 +5,7 @@ + #include + #include + #define __FRAME_OFFSETS +-#include ++#include + #include + + #ifdef __i386__ diff --git a/target/linux/uml/patches-4.9/003-um-Fix-check-for-_xstate-for-older-hosts.patch b/target/linux/uml/patches-4.9/003-um-Fix-check-for-_xstate-for-older-hosts.patch new file mode 100644 index 000000000..b31ca4191 --- /dev/null +++ b/target/linux/uml/patches-4.9/003-um-Fix-check-for-_xstate-for-older-hosts.patch @@ -0,0 +1,46 @@ +From 2fb44600fe784449404c6639de26af8361999ec7 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli +Date: Tue, 18 Jul 2017 16:43:47 -0700 +Subject: [PATCH] um: Fix check for _xstate for older hosts + +Commit 0a987645672e ("um: Allow building and running on older +hosts") attempted to check for PTRACE_{GET,SET}REGSET under the premise +that these ptrace(2) parameters were directly linked with the presence +of the _xstate structure. + +After Richard's commit 61e8d462457f ("um: Correctly check for +PTRACE_GETRESET/SETREGSET") which properly included linux/ptrace.h +instead of asm/ptrace.h, we could get into the original build failure +that I reported: + +arch/x86/um/user-offsets.c: In function 'foo': +arch/x86/um/user-offsets.c:54: error: invalid application of 'sizeof' to +incomplete type 'struct _xstate' + +On this particular host, we do have PTRACE_GETREGSET and +PTRACE_SETREGSET defined in linux/ptrace.h, but not the structure +_xstate that should be pulled from the following include chain: signal.h +-> bits/sigcontext.h. + +Correctly fix this by checking for FP_XSTATE_MAGIC1 which is the correct +way to see if struct _xstate is available or not on the host. + +Fixes: 61e8d462457f ("um: Correctly check for PTRACE_GETRESET/SETREGSET") +Fixes: 0a987645672e ("um: Allow building and running on older hosts") +Signed-off-by: Florian Fainelli +Signed-off-by: Richard Weinberger +--- + arch/x86/um/user-offsets.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/um/user-offsets.c ++++ b/arch/x86/um/user-offsets.c +@@ -50,7 +50,7 @@ void foo(void) + DEFINE(HOST_GS, GS); + DEFINE(HOST_ORIG_AX, ORIG_EAX); + #else +-#if defined(PTRACE_GETREGSET) && defined(PTRACE_SETREGSET) ++#ifdef FP_XSTATE_MAGIC1 + DEFINE(HOST_FP_SIZE, sizeof(struct _xstate) / sizeof(unsigned long)); + #else + DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); diff --git a/target/linux/uml/patches-4.9/101-mconsole-exec.patch b/target/linux/uml/patches-4.9/101-mconsole-exec.patch new file mode 100644 index 000000000..6682338f3 --- /dev/null +++ b/target/linux/uml/patches-4.9/101-mconsole-exec.patch @@ -0,0 +1,211 @@ +# +# Minimalist mconsole exec patch +# +# 3.10 version (with bit more synchronous behavior) by fingon at iki dot fi +# Adaptation to kernel 3.3.8 made by David Fernández (david at dit.upm.es) for +# Starting point: mconsole-exec-2.6.30.patch for kernel 2.6.30 +# Author of original patch: Paolo Giarrusso, aka Blaisorblade +# (http://www.user-mode-linux.org/~blaisorblade) +# +# Known misfeatures: +# +# - If output is too long, blocks (and breaks horribly) +# (this misfeature from 3.10 patches, when minimalizing the patch; +# workaround: redirect to a shared filesystem if long output is expected) +# +# - Nothing useful is done with stdin +# +--- a/arch/um/drivers/mconsole.h ++++ b/arch/um/drivers/mconsole.h +@@ -85,6 +85,7 @@ extern void mconsole_cad(struct mc_reque + extern void mconsole_stop(struct mc_request *req); + extern void mconsole_go(struct mc_request *req); + extern void mconsole_log(struct mc_request *req); ++extern void mconsole_exec(struct mc_request *req); + extern void mconsole_proc(struct mc_request *req); + extern void mconsole_stack(struct mc_request *req); + +--- a/arch/um/drivers/mconsole_kern.c ++++ b/arch/um/drivers/mconsole_kern.c +@@ -4,6 +4,7 @@ + * Licensed under the GPL + */ + ++#include "linux/kmod.h" + #include + #include + #include +@@ -24,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -121,6 +123,59 @@ void mconsole_log(struct mc_request *req + mconsole_reply(req, "", 0, 0); + } + ++void mconsole_exec(struct mc_request *req) ++{ ++ struct subprocess_info *sub_info; ++ int res, len; ++ struct file *out; ++ char buf[MCONSOLE_MAX_DATA]; ++ ++ char *envp[] = { ++ "HOME=/", "TERM=linux", ++ "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin", ++ NULL ++ }; ++ char *argv[] = { ++ "/bin/sh", "-c", ++ req->request.data + strlen("exec "), ++ NULL ++ }; ++ ++ sub_info = call_usermodehelper_setup("/bin/sh", argv, envp, GFP_ATOMIC, NULL, NULL, NULL); ++ if (sub_info == NULL) { ++ mconsole_reply(req, "call_usermodehelper_setup failed", 1, 0); ++ return; ++ } ++ res = call_usermodehelper_stdoutpipe(sub_info, &out); ++ if (res < 0) { ++ kfree(sub_info); ++ mconsole_reply(req, "call_usermodehelper_stdoutpipe failed", 1, 0); ++ return; ++ } ++ ++ res = call_usermodehelper_exec(sub_info, UMH_WAIT_PROC); ++ if (res < 0) { ++ kfree(sub_info); ++ mconsole_reply(req, "call_usermodehelper_exec failed", 1, 0); ++ return; ++ } ++ ++ for (;;) { ++ len = out->f_op->read(out, buf, sizeof(buf), &out->f_pos); ++ if (len < 0) { ++ mconsole_reply(req, "reading output failed", 1, 0); ++ break; ++ } ++ if (len == 0) ++ break; ++ mconsole_reply_len(req, buf, len, 0, 1); ++ } ++ fput(out); ++ ++ mconsole_reply_len(req, NULL, 0, 0, 0); ++} ++ ++ + void mconsole_proc(struct mc_request *req) + { + struct vfsmount *mnt = task_active_pid_ns(current)->proc_mnt; +@@ -187,6 +242,7 @@ void mconsole_proc(struct mc_request *re + stop - pause the UML; it will do nothing until it receives a 'go' \n\ + go - continue the UML after a 'stop' \n\ + log - make UML enter into the kernel log\n\ ++ exec - pass to /bin/sh -c synchronously\n\ + proc - returns the contents of the UML's /proc/\n\ + stack - returns the stack of the specified pid\n\ + " +--- a/arch/um/drivers/mconsole_user.c ++++ b/arch/um/drivers/mconsole_user.c +@@ -30,6 +30,7 @@ static struct mconsole_command commands[ + { "stop", mconsole_stop, MCONSOLE_PROC }, + { "go", mconsole_go, MCONSOLE_INTR }, + { "log", mconsole_log, MCONSOLE_INTR }, ++ { "exec", mconsole_exec, MCONSOLE_PROC }, + { "proc", mconsole_proc, MCONSOLE_PROC }, + { "stack", mconsole_stack, MCONSOLE_INTR }, + }; +--- a/arch/um/os-Linux/file.c ++++ b/arch/um/os-Linux/file.c +@@ -554,6 +554,8 @@ int os_create_unix_socket(const char *fi + + addr.sun_family = AF_UNIX; + ++ if (len > sizeof(addr.sun_path)) ++ len = sizeof(addr.sun_path); + snprintf(addr.sun_path, len, "%s", file); + + err = bind(sock, (struct sockaddr *) &addr, sizeof(addr)); +--- a/include/linux/kmod.h ++++ b/include/linux/kmod.h +@@ -62,6 +62,7 @@ struct subprocess_info { + int wait; + int retval; + int (*init)(struct subprocess_info *info, struct cred *new); ++ struct file *stdout; + void (*cleanup)(struct subprocess_info *info); + void *data; + }; +@@ -102,4 +103,6 @@ extern int usermodehelper_read_trylock(v + extern long usermodehelper_read_lock_wait(long timeout); + extern void usermodehelper_read_unlock(void); + ++int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info, struct file **filp); ++ + #endif /* __LINUX_KMOD_H__ */ +--- a/kernel/kmod.c ++++ b/kernel/kmod.c +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -222,6 +223,28 @@ static int call_usermodehelper_exec_asyn + flush_signal_handlers(current, 1); + spin_unlock_irq(¤t->sighand->siglock); + ++ /* Install output when needed */ ++ if (sub_info->stdout) { ++ struct files_struct *f = current->files; ++ struct fdtable *fdt; ++ ++ sys_close(1); ++ sys_close(2); ++ get_file(sub_info->stdout); ++ fd_install(1, sub_info->stdout); ++ fd_install(2, sub_info->stdout); ++ spin_lock(&f->file_lock); ++ fdt = files_fdtable(f); ++ __set_bit(1, fdt->open_fds); ++ __clear_bit(1, fdt->close_on_exec); ++ __set_bit(2, fdt->open_fds); ++ __clear_bit(2, fdt->close_on_exec); ++ spin_unlock(&f->file_lock); ++ ++ /* disallow core files */ ++ current->signal->rlim[RLIMIT_CORE] = (struct rlimit){0, 0}; ++ } ++ + /* + * Our parent (unbound workqueue) runs with elevated scheduling + * priority. Avoid propagating that into the userspace child. +@@ -540,6 +563,20 @@ struct subprocess_info *call_usermodehel + } + EXPORT_SYMBOL(call_usermodehelper_setup); + ++int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info, ++ struct file **filp) ++{ ++ struct file *f[2]; ++ ++ if (create_pipe_files(f, 0)<0) ++ return PTR_ERR(f); ++ sub_info->stdout = f[1]; ++ *filp = f[0]; ++ return 0; ++} ++EXPORT_SYMBOL(call_usermodehelper_stdoutpipe); ++ ++ + /** + * call_usermodehelper_exec - start a usermode application + * @sub_info: information about the subprocessa diff --git a/target/linux/uml/patches-4.9/102-pseudo-random-mac.patch b/target/linux/uml/patches-4.9/102-pseudo-random-mac.patch new file mode 100644 index 000000000..a31d75ff3 --- /dev/null +++ b/target/linux/uml/patches-4.9/102-pseudo-random-mac.patch @@ -0,0 +1,131 @@ +=============================================================================== + +This patch makes MAC addresses of network interfaces predictable. In +particular, it adds a small routine that computes MAC addresses of based on +a SHA1 hash of the virtual machine name and interface ID. + +TECHNICAL INFORMATION: + +Applies to vanilla kernel 3.9.4. + +=============================================================================== +--- a/arch/um/Kconfig.net ++++ b/arch/um/Kconfig.net +@@ -21,6 +21,19 @@ config UML_NET + enable at least one of the following transport options to actually + make use of UML networking. + ++config UML_NET_RANDOM_MAC ++ bool "Use random MAC addresses for network interfaces" ++ default n ++ depends on UML_NET ++ help ++ Virtual network devices inside a User-Mode Linux instance must be ++ assigned a MAC (Ethernet) address. If none is specified on the UML ++ command line, one must be automatically computed. If this option is ++ enabled, a randomly generated address is used. Otherwise, if this ++ option is disabled, the address is generated from a SHA1 hash of ++ the umid of the UML instance and the interface name. The latter choice ++ is useful to make MAC addresses predictable. ++ + config UML_NET_ETHERTAP + bool "Ethertap transport" + depends on UML_NET +--- a/arch/um/drivers/net_kern.c ++++ b/arch/um/drivers/net_kern.c +@@ -25,6 +25,14 @@ + #include + #include + ++#include ++#include ++#include ++#include ++#include ++#include ++#include "os.h" ++ + #define DRIVER_NAME "uml-netdev" + + static DEFINE_SPINLOCK(opened_lock); +@@ -295,11 +303,53 @@ static void uml_net_user_timer_expire(un + #endif + } + ++#ifndef CONFIG_UML_NET_RANDOM_MAC ++ ++/* Compute a SHA1 hash of the UML instance's id and ++ * * an interface name. */ ++static int compute_hash(const char *umid, const char *ifname, char *hash) ++{ ++ struct ahash_request *desc; ++ struct crypto_ahash *tfm; ++ struct scatterlist sg; ++ char vmif[1024]; ++ int ret; ++ ++ strcpy (vmif, umid); ++ strcat (vmif, ifname); ++ ++ tfm = crypto_alloc_ahash("sha1", 0, CRYPTO_ALG_ASYNC); ++ if (IS_ERR(tfm)) ++ return -ENOMEM; ++ ++ desc = ahash_request_alloc(tfm, GFP_KERNEL); ++ if (!desc) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ crypto_ahash_clear_flags(tfm, ~0); ++ ++ sg_init_table(&sg, 1); ++ sg_set_buf(&sg, vmif, strlen(vmif)); ++ ++ ahash_request_set_crypt(desc, &sg, hash, strlen(vmif)); ++ ++ ret = crypto_ahash_digest(desc); ++out: ++ crypto_free_ahash(tfm); ++ ++ return ret; ++} ++ ++#endif ++ + static void setup_etheraddr(struct net_device *dev, char *str) + { + unsigned char *addr = dev->dev_addr; + char *end; + int i; ++ u8 hash[SHA1_DIGEST_SIZE]; + + if (str == NULL) + goto random; +@@ -340,9 +390,26 @@ static void setup_etheraddr(struct net_d + return; + + random: ++#ifdef CONFIG_UML_NET_RANDOM_MAC + printk(KERN_INFO + "Choosing a random ethernet address for device %s\n", dev->name); + eth_hw_addr_random(dev); ++#else ++ printk(KERN_INFO ++ "Computing a digest to use as ethernet address for device %s\n", dev->name); ++ if (compute_hash(get_umid(), dev->name, hash) < 0) { ++ printk(KERN_WARNING ++ "Could not compute digest to use as ethernet address for device %s. " ++ "Using random address instead.\n", dev->name); ++ random_ether_addr(addr); ++ } ++ else { ++ for (i=0; i < 6; i++) ++ addr[i] = (hash[i] + hash[i+6]) % 0x100; ++ } ++ addr [0] &= 0xfe; /* clear multicast bit */ ++ addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ ++#endif + } + + static DEFINE_SPINLOCK(devices_lock); diff --git a/target/linux/x86/patches-4.9/100-fix_cs5535_clockevt.patch b/target/linux/x86/patches-4.9/100-fix_cs5535_clockevt.patch index c49ddca7d..c3a7fce9c 100644 --- a/target/linux/x86/patches-4.9/100-fix_cs5535_clockevt.patch +++ b/target/linux/x86/patches-4.9/100-fix_cs5535_clockevt.patch @@ -1,6 +1,6 @@ --- a/drivers/clocksource/cs5535-clockevt.c +++ b/drivers/clocksource/cs5535-clockevt.c -@@ -129,7 +129,8 @@ static irqreturn_t mfgpt_tick(int irq, v +@@ -130,7 +130,8 @@ static irqreturn_t mfgpt_tick(int irq, v cs5535_mfgpt_write(cs5535_event_clock, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2);