diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index 959377e41..79842a3b9 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - target: ['cig_wf188', 'cig_wf194c', 'cig_wf160d', 'edgecore_eap101', 'edgecore_eap102', 'edgecore_ecs4100-12ph', 'edgecore_ecw5211', 'edgecore_ecw5410', 'edgecore_oap100', 'edgecore_ssw2ac2600', 'edgecore_spw2ac1200', 'indio_um-305ac', 'linksys_e8450-ubi', 'linksys_ea8300', 'mikrotik_nand', 'tplink_cpe210_v3', 'tplink_cpe510_v3', 'tplink_eap225_outdoor_v1', 'tplink_ec420', 'tplink_ex227', 'tplink_ex228', 'tplink_ex447', 'wallys_dr40x9' ] + target: ['cig_wf188', 'cig_wf194c', 'cig_wf160d', 'edgecore_eap101', 'edgecore_eap102', 'edgecore_ecs4100-12ph', 'edgecore_ecw5211', 'edgecore_ecw5410', 'edgecore_oap100', 'edgecore_ssw2ac2600', 'edgecore_spw2ac1200', 'indio_um-305ac', 'linksys_e8450-ubi', 'linksys_ea8300', 'tplink_cpe210_v3', 'tplink_cpe510_v3', 'tplink_eap225_outdoor_v1', 'tplink_ec420', 'tplink_ex227', 'tplink_ex228', 'tplink_ex447', 'wallys_dr40x9' ] steps: - uses: actions/checkout@v2 diff --git a/backports/0010-ar71xx-forward-port-target-to-get-routerboard-suppor.patch b/backports/0010-ar71xx-forward-port-target-to-get-routerboard-suppor.patch deleted file mode 100644 index 3569495cc..000000000 --- a/backports/0010-ar71xx-forward-port-target-to-get-routerboard-suppor.patch +++ /dev/null @@ -1,137757 +0,0 @@ -From a5f4e99a365f392feca84f29b7011fb507771f0e Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Tue, 20 Apr 2021 11:13:20 +0200 -Subject: [PATCH 10/27] ar71xx: forward port target to get routerboard support - -This is only a 1 month interim until the new nand driver for ath79 is ready - -Signed-off-by: John Crispin ---- - config/Config-images.in | 1 + - package/kernel/linux/modules/usb.mk | 2 +- - package/kernel/mac80211/ath.mk | 9 +- - target/linux/ar71xx/Makefile | 24 + - .../ar71xx/base-files/etc/board.d/01_leds | 1130 ++++ - .../ar71xx/base-files/etc/board.d/02_network | 711 ++ - .../base-files/etc/board.d/03_gpio_switches | 42 + - target/linux/ar71xx/base-files/etc/diag.sh | 599 ++ - .../etc/hotplug.d/firmware/10-ath9k-eeprom | 178 + - .../etc/hotplug.d/firmware/11-ath10k-caldata | 195 + - .../etc/hotplug.d/ieee80211/10_fix_wifi_mac | 24 + - .../etc/hotplug.d/net/10-ar922x-led-fix | 52 + - target/linux/ar71xx/base-files/etc/inittab | 3 + - .../uci-defaults/03_network-switchX-migration | 108 + - .../uci-defaults/03_network-vlan-migration | 13 + - .../etc/uci-defaults/04_led_migration | 84 + - .../etc/uci-defaults/09_fix-checksum | 28 + - .../etc/uci-defaults/09_fix-seama-header | 17 + - target/linux/ar71xx/base-files/lib/ar71xx.sh | 1589 +++++ - .../lib/preinit/01_preinit_do_ar71xx.sh | 9 + - .../lib/preinit/05_set_iface_mac_ar71xx | 60 + - .../lib/preinit/05_set_preinit_iface_ar71xx | 57 + - .../base-files/lib/preinit/82_patch_ath10k | 50 + - .../ar71xx/base-files/lib/upgrade/allnet.sh | 155 + - .../ar71xx/base-files/lib/upgrade/dir825.sh | 165 + - .../base-files/lib/upgrade/merakinand.sh | 165 + - .../ar71xx/base-files/lib/upgrade/openmesh.sh | 232 + - .../ar71xx/base-files/lib/upgrade/platform.sh | 915 +++ - target/linux/ar71xx/config-4.14 | 477 ++ - .../files/arch/mips/ath79/Kconfig.openwrt | 2458 +++++++ - .../ar71xx/files/arch/mips/ath79/Makefile | 290 + - .../files/arch/mips/ath79/dev-ap9x-pci.c | 173 + - .../files/arch/mips/ath79/dev-ap9x-pci.h | 55 + - .../ar71xx/files/arch/mips/ath79/dev-dsa.c | 36 + - .../ar71xx/files/arch/mips/ath79/dev-dsa.h | 21 + - .../ar71xx/files/arch/mips/ath79/dev-eth.c | 1262 ++++ - .../ar71xx/files/arch/mips/ath79/dev-eth.h | 55 + - .../ar71xx/files/arch/mips/ath79/dev-m25p80.c | 101 + - .../ar71xx/files/arch/mips/ath79/dev-m25p80.h | 17 + - .../ar71xx/files/arch/mips/ath79/dev-nfc.c | 141 + - .../ar71xx/files/arch/mips/ath79/dev-nfc.h | 34 + - .../ar71xx/files/arch/mips/ath79/mach-a60.c | 181 + - .../files/arch/mips/ath79/mach-alfa-ap120c.c | 147 + - .../files/arch/mips/ath79/mach-alfa-ap96.c | 132 + - .../files/arch/mips/ath79/mach-alfa-nx.c | 113 + - .../files/arch/mips/ath79/mach-all0258n.c | 88 + - .../files/arch/mips/ath79/mach-all0315n.c | 85 + - .../files/arch/mips/ath79/mach-antminer-s1.c | 98 + - .../files/arch/mips/ath79/mach-antminer-s3.c | 103 + - .../files/arch/mips/ath79/mach-antrouter-r1.c | 98 + - .../files/arch/mips/ath79/mach-ap121f.c | 103 + - .../ar71xx/files/arch/mips/ath79/mach-ap132.c | 189 + - .../ar71xx/files/arch/mips/ath79/mach-ap143.c | 142 + - .../ar71xx/files/arch/mips/ath79/mach-ap147.c | 125 + - .../ar71xx/files/arch/mips/ath79/mach-ap152.c | 140 + - .../files/arch/mips/ath79/mach-ap531b0.c | 112 + - .../ar71xx/files/arch/mips/ath79/mach-ap90q.c | 201 + - .../files/arch/mips/ath79/mach-ap91-5g.c | 118 + - .../ar71xx/files/arch/mips/ath79/mach-ap96.c | 142 + - .../arch/mips/ath79/mach-archer-c25-v1.c | 227 + - .../arch/mips/ath79/mach-archer-c59-v1.c | 342 + - .../arch/mips/ath79/mach-archer-c60-v1.c | 225 + - .../files/arch/mips/ath79/mach-archer-c7-v4.c | 260 + - .../files/arch/mips/ath79/mach-archer-c7-v5.c | 207 + - .../files/arch/mips/ath79/mach-archer-c7.c | 349 + - .../files/arch/mips/ath79/mach-arduino-yun.c | 156 + - .../files/arch/mips/ath79/mach-aw-nr580.c | 107 + - .../files/arch/mips/ath79/mach-bhr-4grv2.c | 171 + - .../arch/mips/ath79/mach-bhu-bxu2000n2-a.c | 120 + - .../ar71xx/files/arch/mips/ath79/mach-bsb.c | 83 + - .../ar71xx/files/arch/mips/ath79/mach-c55.c | 132 + - .../ar71xx/files/arch/mips/ath79/mach-c60.c | 265 + - .../files/arch/mips/ath79/mach-cap324.c | 133 + - .../files/arch/mips/ath79/mach-cap4200ag.c | 131 + - .../files/arch/mips/ath79/mach-carambola2.c | 105 + - .../files/arch/mips/ath79/mach-cf-e316n-v2.c | 765 +++ - .../files/arch/mips/ath79/mach-cpe510.c | 281 + - .../files/arch/mips/ath79/mach-cpe870.c | 152 + - .../files/arch/mips/ath79/mach-cr3000.c | 168 + - .../files/arch/mips/ath79/mach-cr5000.c | 179 + - .../files/arch/mips/ath79/mach-dap-1330-a1.c | 146 + - .../files/arch/mips/ath79/mach-dap-2695-a1.c | 191 + - .../files/arch/mips/ath79/mach-dgl-5500-a1.c | 150 + - .../files/arch/mips/ath79/mach-dhp-1565-a1.c | 170 + - .../files/arch/mips/ath79/mach-dir-505-a1.c | 116 + - .../files/arch/mips/ath79/mach-dir-600-a1.c | 162 + - .../files/arch/mips/ath79/mach-dir-615-c1.c | 135 + - .../files/arch/mips/ath79/mach-dir-615-i1.c | 133 + - .../files/arch/mips/ath79/mach-dir-825-b1.c | 191 + - .../files/arch/mips/ath79/mach-dir-825-c1.c | 241 + - .../files/arch/mips/ath79/mach-dir-869-a1.c | 175 + - .../files/arch/mips/ath79/mach-dlan-hotspot.c | 117 + - .../arch/mips/ath79/mach-dlan-pro-1200-ac.c | 190 + - .../arch/mips/ath79/mach-dlan-pro-500-wp.c | 203 + - .../arch/mips/ath79/mach-domywifi-dw33d.c | 192 + - .../ar71xx/files/arch/mips/ath79/mach-dr344.c | 224 + - .../ar71xx/files/arch/mips/ath79/mach-dr531.c | 155 + - .../files/arch/mips/ath79/mach-dragino2.c | 136 + - .../files/arch/mips/ath79/mach-e1700ac-v2.c | 145 + - .../files/arch/mips/ath79/mach-e2100l.c | 126 + - .../files/arch/mips/ath79/mach-e558-v2.c | 170 + - .../files/arch/mips/ath79/mach-e600g-v2.c | 184 + - .../files/arch/mips/ath79/mach-e750a-v4.c | 122 + - .../files/arch/mips/ath79/mach-e750g-v8.c | 151 + - .../files/arch/mips/ath79/mach-eap120.c | 126 + - .../files/arch/mips/ath79/mach-eap300v2.c | 101 + - .../files/arch/mips/ath79/mach-eap7660d.c | 181 + - .../files/arch/mips/ath79/mach-el-m150.c | 112 + - .../files/arch/mips/ath79/mach-el-mini.c | 86 + - .../files/arch/mips/ath79/mach-ens202ext.c | 124 + - .../files/arch/mips/ath79/mach-epg5000.c | 177 + - .../files/arch/mips/ath79/mach-esr1750.c | 176 + - .../files/arch/mips/ath79/mach-esr900.c | 200 + - .../files/arch/mips/ath79/mach-ew-balin.c | 110 + - .../files/arch/mips/ath79/mach-ew-dorin.c | 138 + - .../files/arch/mips/ath79/mach-f9k1115v2.c | 189 + - .../files/arch/mips/ath79/mach-fritz300e.c | 132 + - .../files/arch/mips/ath79/mach-fritz4020.c | 242 + - .../files/arch/mips/ath79/mach-fritz450e.c | 179 + - .../files/arch/mips/ath79/mach-gl-ar150.c | 125 + - .../files/arch/mips/ath79/mach-gl-ar300.c | 103 + - .../files/arch/mips/ath79/mach-gl-ar300m.c | 158 + - .../files/arch/mips/ath79/mach-gl-ar750.c | 146 + - .../files/arch/mips/ath79/mach-gl-ar750s.c | 193 + - .../files/arch/mips/ath79/mach-gl-domino.c | 136 + - .../files/arch/mips/ath79/mach-gl-inet.c | 104 + - .../files/arch/mips/ath79/mach-gl-mifi.c | 114 + - .../files/arch/mips/ath79/mach-gl-usb150.c | 87 + - .../arch/mips/ath79/mach-gs-minibox-v32.c | 121 + - .../files/arch/mips/ath79/mach-gs-oolite-v1.c | 143 + - .../arch/mips/ath79/mach-gs-oolite-v5-2.c | 111 + - .../files/arch/mips/ath79/mach-hiveap-121.c | 153 + - .../arch/mips/ath79/mach-hiwifi-hc6361.c | 115 + - .../files/arch/mips/ath79/mach-hornet-ub.c | 142 + - .../files/arch/mips/ath79/mach-ja76pf.c | 190 + - .../files/arch/mips/ath79/mach-jwap003.c | 95 + - .../files/arch/mips/ath79/mach-jwap230.c | 158 + - .../ar71xx/files/arch/mips/ath79/mach-koala.c | 161 + - .../files/arch/mips/ath79/mach-lan-turtle.c | 178 + - .../ar71xx/files/arch/mips/ath79/mach-lima.c | 86 + - .../files/arch/mips/ath79/mach-mc-mac1200r.c | 155 + - .../ar71xx/files/arch/mips/ath79/mach-mr12.c | 114 + - .../ar71xx/files/arch/mips/ath79/mach-mr16.c | 118 + - .../files/arch/mips/ath79/mach-mr1750.c | 171 + - .../ar71xx/files/arch/mips/ath79/mach-mr18.c | 286 + - .../ar71xx/files/arch/mips/ath79/mach-mr600.c | 177 + - .../ar71xx/files/arch/mips/ath79/mach-mr900.c | 181 + - .../files/arch/mips/ath79/mach-mynet-n600.c | 202 + - .../files/arch/mips/ath79/mach-mynet-n750.c | 226 + - .../files/arch/mips/ath79/mach-mynet-rext.c | 208 + - .../files/arch/mips/ath79/mach-mzk-w04nu.c | 124 + - .../files/arch/mips/ath79/mach-mzk-w300nh.c | 115 + - .../ar71xx/files/arch/mips/ath79/mach-n5q.c | 132 + - .../files/arch/mips/ath79/mach-nbg460n.c | 220 + - .../files/arch/mips/ath79/mach-nbg6716.c | 385 ++ - .../ar71xx/files/arch/mips/ath79/mach-om2p.c | 320 + - .../ar71xx/files/arch/mips/ath79/mach-om5p.c | 218 + - .../files/arch/mips/ath79/mach-om5pac.c | 193 + - .../files/arch/mips/ath79/mach-om5pacv2.c | 215 + - .../files/arch/mips/ath79/mach-omy-g1.c | 123 + - .../files/arch/mips/ath79/mach-omy-x1.c | 106 + - .../files/arch/mips/ath79/mach-onion-omega.c | 84 + - .../ar71xx/files/arch/mips/ath79/mach-pb42.c | 83 + - .../files/arch/mips/ath79/mach-pqi-air-pen.c | 99 + - .../files/arch/mips/ath79/mach-qihoo-c301.c | 166 + - .../ar71xx/files/arch/mips/ath79/mach-r36a.c | 140 + - .../ar71xx/files/arch/mips/ath79/mach-r602n.c | 213 + - .../ar71xx/files/arch/mips/ath79/mach-r6100.c | 146 + - .../files/arch/mips/ath79/mach-rambutan.c | 92 + - .../files/arch/mips/ath79/mach-rb2011.c | 406 ++ - .../ar71xx/files/arch/mips/ath79/mach-rb4xx.c | 465 ++ - .../ar71xx/files/arch/mips/ath79/mach-rb750.c | 349 + - .../ar71xx/files/arch/mips/ath79/mach-rb91x.c | 348 + - .../ar71xx/files/arch/mips/ath79/mach-rb922.c | 361 + - .../ar71xx/files/arch/mips/ath79/mach-rb95x.c | 327 + - .../ar71xx/files/arch/mips/ath79/mach-rbspi.c | 1262 ++++ - .../files/arch/mips/ath79/mach-rbsxtlite.c | 302 + - .../ar71xx/files/arch/mips/ath79/mach-re450.c | 239 + - .../files/arch/mips/ath79/mach-rme-eg200.c | 99 + - .../files/arch/mips/ath79/mach-rut9xx.c | 191 + - .../files/arch/mips/ath79/mach-rw2458n.c | 91 + - .../files/arch/mips/ath79/mach-sc1750.c | 145 + - .../files/arch/mips/ath79/mach-sc300m.c | 132 + - .../ar71xx/files/arch/mips/ath79/mach-sc450.c | 149 + - .../files/arch/mips/ath79/mach-smart-300.c | 135 + - .../files/arch/mips/ath79/mach-som9331.c | 125 + - .../files/arch/mips/ath79/mach-sr3200.c | 187 + - .../ar71xx/files/arch/mips/ath79/mach-t830.c | 127 + - .../mips/ath79/mach-tellstick-znet-lite.c | 129 + - .../files/arch/mips/ath79/mach-tew-632brp.c | 111 + - .../files/arch/mips/ath79/mach-tew-673gru.c | 198 + - .../files/arch/mips/ath79/mach-tew-712br.c | 153 + - .../files/arch/mips/ath79/mach-tew-732br.c | 127 + - .../files/arch/mips/ath79/mach-tew-823dru.c | 181 + - .../files/arch/mips/ath79/mach-tl-mr11u.c | 183 + - .../files/arch/mips/ath79/mach-tl-mr13u.c | 107 + - .../files/arch/mips/ath79/mach-tl-mr3020.c | 126 + - .../files/arch/mips/ath79/mach-tl-mr3x20.c | 147 + - .../files/arch/mips/ath79/mach-tl-mr6400.c | 151 + - .../arch/mips/ath79/mach-tl-wa701nd-v2.c | 116 + - .../arch/mips/ath79/mach-tl-wa7210n-v2.c | 125 + - .../arch/mips/ath79/mach-tl-wa801nd-v3.c | 137 + - .../arch/mips/ath79/mach-tl-wa830re-v2.c | 132 + - .../arch/mips/ath79/mach-tl-wa901nd-v2.c | 104 + - .../arch/mips/ath79/mach-tl-wa901nd-v4.c | 115 + - .../files/arch/mips/ath79/mach-tl-wa901nd.c | 127 + - .../files/arch/mips/ath79/mach-tl-wax50re.c | 445 ++ - .../arch/mips/ath79/mach-tl-wdr3320-v2.c | 146 + - .../files/arch/mips/ath79/mach-tl-wdr3500.c | 169 + - .../files/arch/mips/ath79/mach-tl-wdr4300.c | 206 + - .../arch/mips/ath79/mach-tl-wdr6500-v2.c | 142 + - .../files/arch/mips/ath79/mach-tl-wpa8630.c | 172 + - .../arch/mips/ath79/mach-tl-wr1041n-v2.c | 157 + - .../arch/mips/ath79/mach-tl-wr1043nd-v2.c | 215 + - .../arch/mips/ath79/mach-tl-wr1043nd-v4.c | 283 + - .../files/arch/mips/ath79/mach-tl-wr1043nd.c | 141 + - .../files/arch/mips/ath79/mach-tl-wr2543n.c | 150 + - .../files/arch/mips/ath79/mach-tl-wr703n.c | 118 + - .../files/arch/mips/ath79/mach-tl-wr720n-v3.c | 108 + - .../arch/mips/ath79/mach-tl-wr741nd-v4.c | 187 + - .../files/arch/mips/ath79/mach-tl-wr741nd.c | 130 + - .../files/arch/mips/ath79/mach-tl-wr802n.c | 117 + - .../files/arch/mips/ath79/mach-tl-wr810n.c | 149 + - .../files/arch/mips/ath79/mach-tl-wr841n-v8.c | 286 + - .../files/arch/mips/ath79/mach-tl-wr841n-v9.c | 457 ++ - .../files/arch/mips/ath79/mach-tl-wr841n.c | 140 + - .../arch/mips/ath79/mach-tl-wr902ac-v1.c | 145 + - .../files/arch/mips/ath79/mach-tl-wr940n-v4.c | 184 + - .../arch/mips/ath79/mach-tl-wr941nd-v6.c | 149 + - .../files/arch/mips/ath79/mach-tl-wr941nd.c | 121 + - .../files/arch/mips/ath79/mach-tl-wr942n-v1.c | 279 + - .../files/arch/mips/ath79/mach-ts-d084.c | 86 + - .../files/arch/mips/ath79/mach-tube2h.c | 129 + - .../files/arch/mips/ath79/mach-ubnt-unifiac.c | 179 + - .../files/arch/mips/ath79/mach-ubnt-xm.c | 781 +++ - .../ar71xx/files/arch/mips/ath79/mach-ubnt.c | 205 + - .../files/arch/mips/ath79/mach-wam250.c | 122 + - .../ar71xx/files/arch/mips/ath79/mach-weio.c | 140 + - .../files/arch/mips/ath79/mach-whr-hp-g300n.c | 155 + - .../files/arch/mips/ath79/mach-wi2a-ac200i.c | 217 + - .../mips/ath79/mach-wifi-pineapple-nano.c | 107 + - .../files/arch/mips/ath79/mach-wlae-ag300n.c | 114 + - .../files/arch/mips/ath79/mach-wlr8100.c | 195 + - .../files/arch/mips/ath79/mach-wndap360.c | 105 + - .../files/arch/mips/ath79/mach-wndr3700.c | 172 + - .../files/arch/mips/ath79/mach-wndr4300.c | 215 + - .../files/arch/mips/ath79/mach-wnr2000-v3.c | 637 ++ - .../files/arch/mips/ath79/mach-wnr2000-v4.c | 214 + - .../files/arch/mips/ath79/mach-wnr2000.c | 102 + - .../files/arch/mips/ath79/mach-wnr2200.c | 246 + - .../ar71xx/files/arch/mips/ath79/mach-wp543.c | 109 + - .../ar71xx/files/arch/mips/ath79/mach-wpe72.c | 97 + - .../files/arch/mips/ath79/mach-wpj342.c | 178 + - .../files/arch/mips/ath79/mach-wpj344.c | 169 + - .../files/arch/mips/ath79/mach-wpj531.c | 143 + - .../files/arch/mips/ath79/mach-wpj558.c | 170 + - .../files/arch/mips/ath79/mach-wpj563.c | 150 + - .../files/arch/mips/ath79/mach-wrt160nl.c | 126 + - .../files/arch/mips/ath79/mach-wrt400n.c | 161 + - .../files/arch/mips/ath79/mach-wrtnode2q.c | 126 + - .../files/arch/mips/ath79/mach-wzr-450hp2.c | 221 + - .../arch/mips/ath79/mach-wzr-hp-ag300h.c | 202 + - .../arch/mips/ath79/mach-wzr-hp-g300nh.c | 279 + - .../arch/mips/ath79/mach-wzr-hp-g300nh2.c | 174 + - .../files/arch/mips/ath79/mach-wzr-hp-g450h.c | 169 + - .../ar71xx/files/arch/mips/ath79/mach-z1.c | 164 + - .../files/arch/mips/ath79/mach-zbt-we1526.c | 153 + - .../files/arch/mips/ath79/mach-zcn-1523h.c | 154 + - .../ar71xx/files/arch/mips/ath79/machtypes.h | 387 ++ - .../ar71xx/files/arch/mips/ath79/nvram.c | 85 + - .../ar71xx/files/arch/mips/ath79/nvram.h | 19 + - .../files/arch/mips/ath79/pci-ath9k-fixup.c | 126 + - .../files/arch/mips/ath79/pci-ath9k-fixup.h | 6 + - .../ar71xx/files/arch/mips/ath79/routerboot.c | 354 + - .../ar71xx/files/arch/mips/ath79/routerboot.h | 89 + - .../mips/include/asm/fw/myloader/myloader.h | 34 + - .../include/asm/mach-ath79/ag71xx_platform.h | 65 + - .../mips/include/asm/mach-ath79/mach-rb750.h | 84 + - .../mips/include/asm/mach-ath79/rb4xx_cpld.h | 43 + - .../ar71xx/files/drivers/gpio/gpio-latch.c | 220 + - .../files/drivers/gpio/gpio-nxp-74hc153.c | 243 + - .../ar71xx/files/drivers/leds/leds-nu801.c | 396 ++ - .../ar71xx/files/drivers/leds/leds-rb750.c | 144 + - .../files/drivers/leds/leds-wndr3700-usb.c | 76 + - .../ar71xx/files/drivers/mtd/cybertan_part.c | 206 + - .../files/drivers/mtd/nand/ar934x_nfc.c | 1591 +++++ - .../files/drivers/mtd/nand/rb4xx_nand.c | 396 ++ - .../files/drivers/mtd/nand/rb750_nand.c | 440 ++ - .../files/drivers/mtd/nand/rb91x_nand.c | 464 ++ - .../ar71xx/files/drivers/mtd/tplinkpart.c | 235 + - .../ar71xx/files/drivers/net/dsa/mv88e6063.c | 307 + - .../net/ethernet/atheros/ag71xx/Kconfig | 33 + - .../net/ethernet/atheros/ag71xx/Makefile | 15 + - .../net/ethernet/atheros/ag71xx/ag71xx.h | 508 ++ - .../ethernet/atheros/ag71xx/ag71xx_ar7240.c | 1386 ++++ - .../ethernet/atheros/ag71xx/ag71xx_ar8216.c | 44 + - .../ethernet/atheros/ag71xx/ag71xx_debugfs.c | 285 + - .../ethernet/atheros/ag71xx/ag71xx_ethtool.c | 120 + - .../net/ethernet/atheros/ag71xx/ag71xx_main.c | 1494 +++++ - .../net/ethernet/atheros/ag71xx/ag71xx_mdio.c | 320 + - .../net/ethernet/atheros/ag71xx/ag71xx_phy.c | 261 + - .../ar71xx/files/drivers/spi/spi-rb4xx-cpld.c | 347 + - .../ar71xx/files/drivers/spi/spi-rb4xx.c | 430 ++ - .../ar71xx/files/drivers/spi/spi-vsc7385.c | 621 ++ - .../ar71xx/files/include/linux/leds-nu801.h | 38 + - .../ar71xx/files/include/linux/nxp_74hc153.h | 24 + - .../files/include/linux/platform/ar934x_nfc.h | 39 + - .../include/linux/platform_data/gpio-latch.h | 14 + - .../include/linux/platform_data/rb91x_nand.h | 16 + - .../ar71xx/files/include/linux/spi/vsc7385.h | 19 + - target/linux/ar71xx/generic/config-default | 227 + - .../ar71xx/generic/profiles/00-default.mk | 18 + - target/linux/ar71xx/generic/target.mk | 10 + - target/linux/ar71xx/image/Makefile | 69 + - target/linux/ar71xx/image/common-tp-link.mk | 108 + - .../ar71xx/image/generic-legacy-devices.mk | 423 ++ - target/linux/ar71xx/image/generic-tp-link.mk | 544 ++ - target/linux/ar71xx/image/generic-ubnt.mk | 319 + - target/linux/ar71xx/image/generic.mk | 1352 ++++ - target/linux/ar71xx/image/legacy.mk | 1059 +++ - .../linux/ar71xx/image/lzma-loader/Makefile | 70 + - .../ar71xx/image/lzma-loader/src/LzmaDecode.c | 584 ++ - .../ar71xx/image/lzma-loader/src/LzmaDecode.h | 113 + - .../ar71xx/image/lzma-loader/src/LzmaTypes.h | 45 + - .../ar71xx/image/lzma-loader/src/Makefile | 108 + - .../image/lzma-loader/src/ar71xx_regs.h | 725 +++ - .../ar71xx/image/lzma-loader/src/board.c | 56 + - .../ar71xx/image/lzma-loader/src/cache.c | 43 + - .../ar71xx/image/lzma-loader/src/cache.h | 17 + - .../ar71xx/image/lzma-loader/src/cacheops.h | 85 + - .../ar71xx/image/lzma-loader/src/config.h | 31 + - .../ar71xx/image/lzma-loader/src/cp0regdef.h | 39 + - .../linux/ar71xx/image/lzma-loader/src/head.S | 134 + - .../ar71xx/image/lzma-loader/src/loader.c | 264 + - .../ar71xx/image/lzma-loader/src/loader.lds | 34 + - .../ar71xx/image/lzma-loader/src/loader2.lds | 10 + - .../image/lzma-loader/src/lzma-data.lds | 8 + - .../ar71xx/image/lzma-loader/src/printf.c | 350 + - .../ar71xx/image/lzma-loader/src/printf.h | 18 + - target/linux/ar71xx/image/mikrotik.mk | 61 + - target/linux/ar71xx/image/nand.mk | 137 + - .../linux/ar71xx/image/tiny-legacy-devices.mk | 161 + - target/linux/ar71xx/image/tiny-senao.mk | 28 + - target/linux/ar71xx/image/tiny-tp-link.mk | 695 ++ - target/linux/ar71xx/image/tiny.mk | 31 + - target/linux/ar71xx/image/ubinize-nbg6716.ini | 24 + - .../linux/ar71xx/image/ubinize-wndr4300.ini | 26 + - target/linux/ar71xx/mikrotik/config-default | 79 + - .../ar71xx/mikrotik/profiles/00-default.mk | 18 + - target/linux/ar71xx/mikrotik/target.mk | 11 + - target/linux/ar71xx/modules.mk | 69 + - target/linux/ar71xx/nand/config-default | 70 + - .../linux/ar71xx/nand/profiles/00-default.mk | 18 + - target/linux/ar71xx/nand/target.mk | 9 + - .../ar71xx/patches-4.14/001-spi-cs-gpio.patch | 20 + - .../002-add_back_gpio_function_select.patch | 92 + - .../004-register_gpio_driver_earlier.patch | 18 + - ...Avoid-using-unitialized-reg-variable.patch | 42 + - ...h79-do-AR724x-PCIe-root-complex-init.patch | 113 + - ...200-MIPS-ath79-fix-ar933x-wmac-reset.patch | 30 + - .../201-ar913x_wmac_external_reset.patch | 31 + - .../202-MIPS-ath79-ar934x-wmac-revision.patch | 11 + - .../220-add_cpu_feature_overrides.patch | 28 + - ...0-MIPS-add-MIPS_MACHINE_NONAME-macro.patch | 21 + - .../310-lib-add-rle-decompression.patch | 124 + - ...otentially-missed-IRQ-handling-durin.patch | 52 + - .../401-mtd-physmap-add-lock-unlock.patch | 94 + - .../402-mtd-SST39VF6401B-support.patch | 29 + - .../404-mtd-cybertan-trx-parser.patch | 25 + - .../405-mtd-tp-link-partition-parser.patch | 25 + - ...o-pass-probe-types-via-platform-data.patch | 34 + - .../408-mtd-redboot_partition_scan.patch | 44 + - .../409-mtd-rb4xx_nand_driver.patch | 21 + - .../410-mtd-rb750-nand-driver.patch | 21 + - ...mtd-cfi_cmdset_0002-force-word-write.patch | 61 + - .../413-mtd-ar934x-nand-driver.patch | 25 + - .../414-mtd-rb91x-nand-driver.patch | 23 + - .../420-net-ar71xx_mac_driver.patch | 28 + - .../423-dsa-add-88e6063-driver.patch | 27 + - .../430-drivers-link-spi-before-mtd.patch | 12 + - .../432-spi-rb4xx-spi-driver.patch | 25 + - .../433-spi-rb4xx-cpld-driver.patch | 26 + - .../patches-4.14/435-spi-vsc7385_driver.patch | 24 + - .../440-leds-wndr3700-usb-led-driver.patch | 26 + - .../441-leds-rb750-led-driver.patch | 23 + - ...to-use-OPEN_-DRAIN-SOURCE-flags-with.patch | 45 + - ...50-gpio-nxp-74hc153-gpio-chip-driver.patch | 25 + - ...x164-improve-platform-device-support.patch | 119 + - .../452-gpio-add-gpio-latch-driver.patch | 22 + - .../461-spi-ath79-add-fast-flash-read.patch | 60 + - ...ath79-swizzle-pci-address-for-ar71xx.patch | 111 + - ...490-usb-ehci-add-quirks-for-qca-socs.patch | 103 + - .../patches-4.14/500-MIPS-fw-myloader.patch | 22 + - ...-mac-argument-to-ath79_register_wmac.patch | 70 + - ...IPS-ath79-add-ath79_device_reset_get.patch | 42 + - ...ath79-add-ath79_gpio_function_select.patch | 39 + - ...6-MIPS-ath79-prom-parse-redboot-args.patch | 42 + - ...MIPS-ath79-prom-add-myloader-support.patch | 55 + - ...S-ath79-prom-image-command-line-hack.patch | 73 + - ...PS-ath79-process-board-kernel-option.patch | 11 + - ...S-ath79-init-gpio-pin-of-wmac-device.patch | 14 + - .../520-MIPS-ath79-enable-UART-function.patch | 18 + - ...S-ath79-enable-UART-for-early_serial.patch | 61 + - ...dd-ath79_wmac_register_simple-helper.patch | 21 + - .../523-MIPS-ath79-OTP-support.patch | 192 + - ...add-ath79_wmac_disable_25ghz-helpers.patch | 31 + - ...525-MIPS-ath79-enable-qca-usb-quirks.patch | 101 + - ...MIPS-ath79-add-more-register-defines.patch | 455 ++ - .../602-MIPS-ath79-add-openwrt-stuff.patch | 49 + - .../603-MIPS-ath79-ap121-fixes.patch | 149 + - .../patches-4.14/604-MIPS-ath79-no-of.patch | 70 + - .../605-MIPS-ath79-db120-fixes.patch | 204 + - .../606-MIPS-ath79-pb44-fixes.patch | 144 + - .../607-MIPS-ath79-ubnt-xm-fixes.patch | 14 + - ...8-MIPS-ath79-ubnt-xm-add-more-boards.patch | 20 + - .../609-MIPS-ath79-ap136-fixes.patch | 300 + - .../611-MIPS-ath79-wdt-timeout.patch | 25 + - .../612-MIPS-ath79-set-buffalo-txgain.patch | 24 + - ...ath79_wmac_setup_ext_lna_gpio-helper.patch | 76 + - ...PS-ath79-add-support-for-QCA953x-SoC.patch | 696 ++ - ...PS-ath79-add-support-for-QCA956x-SoC.patch | 717 ++ - ...ore-register-defines-for-QCA956x-SoC.patch | 38 + - ...0-MIPS-ath79-fix-chained-irq-disable.patch | 106 + - ...1-MIPS-ath79-wmac-enable-set-led-pin.patch | 24 + - ...MIPS-ath79-gpio-enable-set-direction.patch | 32 + - ...40-MIPS-ath79-add-QCA955x-wmac-reset.patch | 82 + - .../700-MIPS-ath79-add-openwrt-Kconfig.patch | 11 + - ...MIPS-ath79-add-routerboard-detection.patch | 35 + - ...h79-fixup-routerboot-board-parameter.patch | 43 + - ...d-gpio-func-register-for-QCA955x-SoC.patch | 38 + - ...0-MIPS-ath79-add-PCI-for-QCA953x-SoC.patch | 44 + - ...1-MIPS-ath79-add-PCI-for-QCA9556-SoC.patch | 12 + - .../818-MIPS-ath79-add-nu801-led-driver.patch | 26 + - ...-MIPS-ath79-add_gpio_function2_setup.patch | 67 + - ...support-for-boot-console-with-arbitr.patch | 54 + - .../900-mdio_bitbang_ignore_ta_value.patch | 32 + - ...-prevent-rescheduling-during-command.patch | 61 + - .../902-at803x-add-reset-gpio-pdata.patch | 68 + - ...at803x-add-sgmii-aneg-override-pdata.patch | 38 + - .../910-unaligned_access_hacks.patch | 942 +++ - ...usb-chipidea-AR933x-platform-support.patch | 124 + - ...ore-register-defines-for-QCA956x-SoC.patch | 194 + - .../patches-4.14/930-chipidea-pullup.patch | 72 + - .../940-qca955x-add-more-registers.patch | 42 + - .../950-add-boardinfo-platform-data.patch | 67 + - .../952-qca955x-enable-ddr-wb-flush.patch | 49 + - .../953-qca955x-pci-reset-fixes.patch | 120 + - ...x-fix-potential-missing-irq-dispatch.patch | 27 + - .../patches-4.14/999-backport-fixes.patch | 191 + - target/linux/ar71xx/tiny/config-default | 76 + - .../linux/ar71xx/tiny/profiles/00-default.mk | 11 + - target/linux/ar71xx/tiny/target.mk | 10 + - ...dcode-path-to-awk-in-scripts-ld-vers.patch | 30 + - .../011-kbuild-export-SUBARCH.patch | 23 + - ...-for-controlling-warnings-to-linux-c.patch | 142 + - ...te-alias-warning-for-SYSCALL_DEFINEx.patch | 88 + - .../020-backport_netfilter_rtcache.patch | 558 ++ - ...tcp-allow-drivers-to-tweak-TSQ-logic.patch | 85 + - ...ption-fix-dwm-158-3g-modem-interface.patch | 42 + - ...port-for-host-mode-external-vbus-sup.patch | 109 + - ...wc2_vbus_supply_init-fix-error-check.patch | 55 + - ...ding-master-MTD-out-of-mtd_add_devic.patch | 74 + - ...rid-of-the-mtd_add_device_partitions.patch | 93 + - ...dd-of_match_table-parser-matching-fo.patch | 200 + - ...t-parser-to-fixed-partitions-as-it-f.patch | 74 + - ...of_match_table-with-fixed-partitions.patch | 44 + - ...ding-registering-partitions-to-the-p.patch | 168 + - ...-improve-handling-TRX-partition-size.patch | 70 + - ...add-of_match_table-with-a-new-DT-bin.patch | 39 + - ...add-of_match_table-with-the-new-DT-b.patch | 37 + - ...se-DT-info-for-parsing-partitions-wi.patch | 102 + - ...inal-flags-for-every-struct-mtd_info.patch | 58 + - ...ulating-partition-boundaries-when-ch.patch | 55 + - ...ying-block-address-non-regular-inode.patch | 69 + - ...-master-mode-for-BCM54210E-and-B5021.patch | 50 + - ...-support-new-device-flag-for-setting.patch | 54 + - ...-direct-pointer-to-the-struct-device.patch | 199 + - ...002-bcma-use-dev_-printing-functions.patch | 36 + - ...le-working-over-slow-can_sleep-GPIOs.patch | 84 + - ...ridge-add-support-for-port-isolation.patch | 145 + - ...ddress-assignment-via-ifconfig-ioctl.patch | 79 + - ...s3xxx-use-actual-size-reads-for-PCIe.patch | 46 + - ...net-qmi_wwan-add-Wistron-Neweb-D19Q1.patch | 54 + - ...acket.h-include-its-headers-directly.patch | 36 + - ...dv-Remove-usage-of-BIT-x-in-packet.h.patch | 72 + - ...e-kernel-fixed-width-types-in-packet.patch | 386 ++ - ...-adv-Convert-packet.h-to-uapi-header.patch | 1665 +++++ - ...tor-Parse-batman-adv-unicast-headers.patch | 108 + - ...add-defines-for-arp-decnet-max-hooks.patch | 67 + - ...ake-nf_unregister_net_hooks-simple-w.patch | 91 + - ...emove-synchronize_net-call-if-nfqueu.patch | 116 + - ...filter-core-free-hooks-with-call_rcu.patch | 132 + - ...e-size-of-hook-entry-point-locations.patch | 200 + - ...e-hook-array-sizes-to-what-is-needed.patch | 95 + - ...allocate-space-for-decnet-hooks-unle.patch | 67 + - ...allocate-space-for-arp-bridge-hooks-.patch | 165 + - ...ass-hook-number-family-and-device-to.patch | 98 + - ...etfilter-core-add-nf_remove_net_hook.patch | 44 + - ...ass-family-as-parameter-to-nf_remove.patch | 51 + - ...upport-for-NFPROTO_INET-hook-registr.patch | 129 + - ...les-explicit-nft_set_pktinfo-call-fr.patch | 291 + - ...nly-allow-one-nat-hook-per-hook-poin.patch | 146 + - ...les_inet-don-t-use-multihook-infrast.patch | 161 + - ...les-remove-multihook-chains-and-fami.patch | 390 ++ - ...hecksum-indirection-to-struct-nf_ipv.patch | 171 + - ...hecksum_partial-indirection-to-struc.patch | 204 + - ...-saveroute-indirection-in-struct-nf_.patch | 232 + - ...oute-indirection-to-struct-nf_ipv6_o.patch | 349 + - ...eroute-indirection-to-struct-nf_ipv6.patch | 223 + - ...-route_key_size-field-in-struct-nf_a.patch | 94 + - ...-struct-nf_afinfo-and-its-helper-fun.patch | 173 + - ...f_tables_arp-don-t-set-forward-chain.patch | 20 + - ...les-remove-hooks-from-family-definit.patch | 233 + - ...-defensive-check-on-malformed-packet.patch | 302 + - ...v4.16-netfilter-meta-secpath-support.patch | 101 + - ...ack-move-nf_ct_netns_-get-put-to-cor.patch | 142 + - ...conntrack-add-IPS_OFFLOAD-status-bit.patch | 169 + - ...bles-add-flow-table-netlink-frontend.patch | 1079 +++ - ...dd-generic-flow-table-infrastructure.patch | 586 ++ - ...etfilter-flow-table-support-for-IPv4.patch | 334 + - ...etfilter-flow-table-support-for-IPv6.patch | 354 + - ...able-support-for-the-mixed-IPv4-IPv6.patch | 141 + - ...er-nf_tables-flow-offload-expression.patch | 332 + - ...les-remove-nhooks-field-from-struct-.patch | 113 + - ...les-fix-a-typo-in-nf_tables_getflowt.patch | 22 + - ...rove-flow-table-Kconfig-dependencies.patch | 106 + - ...les-remove-flag-field-from-struct-nf.patch | 59 + - ...les-no-need-for-struct-nft_af_info-t.patch | 80 + - ...les-remove-struct-nft_af_info-parame.patch | 60 + - ...les-fix-potential-NULL-ptr-deref-in-.patch | 30 + - ...les-add-single-table-list-for-all-fa.patch | 1450 +++++ - ...tfilter-exit_net-cleanup-check-added.patch | 100 + - ...nf_tables-get-rid-of-pernet-families.patch | 598 ++ - ...les-get-rid-of-struct-nft_af_info-ab.patch | 1204 ++++ - ...ow_offload-wait-for-garbage-collecto.patch | 47 + - ...ow_offload-no-need-to-flush-entries-.patch | 29 + - ...ow_offload-move-flowtable-cleanup-ro.patch | 97 + - ...tfilter-nf_tables-fix-flowtable-free.patch | 140 + - ...ow_offload-handle-netdevice-events-f.patch | 96 + - ...les-allocate-handle-and-delete-objec.patch | 468 ++ - ...w_offload-fix-use-after-free-and-a-r.patch | 95 + - ...ble-infrastructure-depends-on-NETFIL.patch | 73 + - ...-netfilter-remove-duplicated-include.patch | 29 + - ...w_table-use-IP_CT_DIR_-values-for-FL.patch | 35 + - ...ow_table-clean-up-flow_offload_alloc.patch | 118 + - ...ipv6-make-ip6_dst_mtu_forward-inline.patch | 80 + - ...w_table-cache-mtu-in-struct-flow_off.patch | 145 + - ...w_table-rename-nf_flow_table.c-to-nf.patch | 952 +++ - ...w_table-move-ipv4-offload-hook-code-.patch | 522 ++ - ...w_table-move-ip-header-check-out-of-.patch | 32 + - ...w_table-move-ipv6-offload-hook-code-.patch | 483 ++ - ...w_table-relax-mixed-ipv4-ipv6-flowta.patch | 23 + - ...w_table-move-init-code-to-nf_flow_ta.patch | 298 + - ...w_table-fix-priv-pointer-for-netdev-.patch | 22 + - ...w_table-track-flow-tables-in-nf_flow.patch | 114 + - ...w_table-make-flow_offload_dead-inlin.patch | 38 + - ...w_table-add-a-new-flow-state-for-tea.patch | 83 + - ...w_table-in-flow_offload_lookup-skip-.patch | 36 + - ...w_table-add-support-for-sending-flow.patch | 99 + - ...w_table-tear-down-TCP-flows-if-RST-o.patch | 81 + - ...w_table-fix-checksum-when-handling-D.patch | 19 + - ...low_offload-Fix-reverse-route-lookup.patch | 39 + - ...w_table-add-missing-condition-for-TC.patch | 48 + - ...w_table-fix-offloading-connections-w.patch | 23 + - ...ter-nf_flow_table-attach-dst-to-skbs.patch | 49 + - ...w_table-fix-offloaded-connection-tim.patch | 110 + - ...w_table-fix-up-ct-state-of-flows-aft.patch | 24 + - ...ow_offload-fix-interaction-with-vrf-.patch | 86 + - ...et-sched-Introduce-act_ctinfo-action.patch | 640 ++ - ...s-trigger-Introduce-a-NETDEV-trigger.patch | 588 ++ - ...dev-fix-refcnt-leak-on-interface-ren.patch | 69 + - ...dev-fix-handling-on-interface-rename.patch | 49 + - ...ix-calculating-partition-end-address.patch | 28 + - ...enable-CONFIG_MMC_SDHCI_IO_ACCESSORS.patch | 23 + - ...fault-compression-selection-in-ubifs.patch | 37 + - ...-dmi-Add-access-to-the-SKU-ID-string.patch | 57 + - ...y-serial-exar-generalize-rs485-setup.patch | 75 + - target/linux/generic/config-4.14 | 5793 +++++++++++++++++ - .../generic/hack-4.14/204-module_strip.patch | 208 + - .../hack-4.14/207-disable-modorder.patch | 44 + - .../210-darwin_scripts_include.patch | 3065 +++++++++ - .../211-host_tools_portability.patch | 40 + - .../hack-4.14/212-byteshift_portability.patch | 65 + - .../hack-4.14/214-spidev_h_portability.patch | 24 + - .../generic/hack-4.14/220-gc_sections.patch | 258 + - .../hack-4.14/221-module_exports.patch | 101 + - .../hack-4.14/230-openwrt_lzma_options.patch | 71 + - .../hack-4.14/250-netfilter_depends.patch | 27 + - .../generic/hack-4.14/251-sound_kconfig.patch | 197 + - .../hack-4.14/259-regmap_dynamic.patch | 105 + - .../260-crypto_test_dependencies.patch | 60 + - .../generic/hack-4.14/280-rfkill-stubs.patch | 84 + - ...cache-use-more-efficient-cache-blast.patch | 66 + - .../301-mips_image_cmdline_hack.patch | 38 + - .../321-powerpc_crtsavres_prereq.patch | 38 + - .../400-mt29f_spinand-fix-memleak.patch | 90 + - .../generic/hack-4.14/531-debloat_lzma.patch | 1040 +++ - .../640-bridge-only-accept-EAP-locally.patch | 82 + - ...lter-connmark-introduce-set-dscpmark.patch | 124 + - .../hack-4.14/647-netfilter-flow-acct.patch | 70 + - .../650-netfilter-add-xt_OFFLOAD-target.patch | 553 ++ - .../hack-4.14/651-wireless_mesh_header.patch | 24 + - .../hack-4.14/660-fq_codel_defaults.patch | 27 + - .../661-use_fq_codel_by_default.patch | 94 + - .../hack-4.14/662-remove_pfifo_fast.patch | 159 + - .../700-swconfig_switch_drivers.patch | 140 + - .../702-phy_add_aneg_done_function.patch | 27 + - .../generic/hack-4.14/721-phy_packets.patch | 176 + - .../hack-4.14/773-bgmac-add-srab-switch.patch | 98 + - .../hack-4.14/901-debloat_sock_diag.patch | 136 + - .../generic/hack-4.14/902-debloat_proc.patch | 405 ++ - .../hack-4.14/904-debloat_dma_buf.patch | 64 + - .../hack-4.14/910-kobject_uevent.patch | 32 + - .../911-kobject_add_broadcast_uevent.patch | 76 + - ...ays-create-console-node-in-initramfs.patch | 40 + - .../generic/hack-4.14/930-crashlog.patch | 338 + - ...problem-with-platfom-data-in-w1-gpio.patch | 38 + - ...s-negative-stack-offsets-on-stack-tr.patch | 57 + - ...f-ath79-Fix-perfcount-IRQ-assignment.patch | 110 + - .../pending-4.14/110-ehci_hcd_ignore_oc.patch | 79 + - ...e_mem_map-with-ARCH_PFN_OFFSET-calcu.patch | 82 + - ...0-add-linux-spidev-compatible-si3210.patch | 18 + - ..._value_cansleep-for-setting-chipsele.patch | 20 + - ...ame2-and-add-RENAME_WHITEOUT-support.patch | 62 + - ...41-jffs2-add-RENAME_EXCHANGE-support.patch | 73 + - ...ge_allow_receiption_on_disabled_port.patch | 47 + - ...-generic-parsing-of-linux-part-probe.patch | 172 + - ...nefficient-copy-of-unaligned-buffers.patch | 50 + - ...et-phy-at803x-add-support-for-AT8032.patch | 73 + - ...ng-comment-related-to-link-detection.patch | 43 + - .../pending-4.14/201-extra_optimization.patch | 28 + - .../203-kallsyms_uncompressed.patch | 119 + - .../205-backtrace_module_info.patch | 45 + - .../pending-4.14/220-optimize_inlining.patch | 165 + - ...e-filenames-from-deps_initramfs-list.patch | 46 + - ...able_wilink_platform_without_drivers.patch | 20 + - .../270-platform-mikrotik-build-bits.patch | 31 + - .../300-mips_expose_boot_raw.patch | 40 + - .../302-mips_no_branch_likely.patch | 22 + - .../pending-4.14/304-mips_disable_fpu.patch | 137 + - .../pending-4.14/305-mips_module_reloc.patch | 371 ++ - .../306-mips_mem_functions_performance.patch | 106 + - .../307-mips_highmem_offset.patch | 19 + - .../pending-4.14/308-mips32r2_tune.patch | 22 + - ...CPU-option-reporting-to-proc-cpuinfo.patch | 140 + - .../310-arm_module_unresolved_weak_sym.patch | 22 + - ...t-command-line-parameters-from-users.patch | 274 + - .../332-arc-add-OWRTDTB-section.patch | 84 + - ...able-unaligned-access-in-kernel-mode.patch | 24 + - ...IPS-mm-remove-mips_dma_mapping_error.patch | 32 + - ...ove-no-op-dma_map_ops-where-possible.patch | 140 + - ...ernel-XZ-compression-option-on-PPC_8.patch | 24 + - .../400-mtd-add-rootfs-split-support.patch | 108 + - ...for-different-partition-parser-types.patch | 142 + - ...arsers-for-rootfs-and-firmware-split.patch | 44 + - .../403-mtd-hook-mtdsplit-to-Kbuild.patch | 32 + - .../404-mtd-add-more-helper-functions.patch | 76 + - .../411-mtd-partial_eraseblock_write.patch | 153 + - .../412-mtd-partial_eraseblock_unlock.patch | 40 + - ...t-add-of_match_table-with-DT-binding.patch | 31 + - .../pending-4.14/420-mtd-redboot_space.patch | 41 + - ...30-mtd-add-myloader-partition-parser.patch | 229 + - ...check-for-bad-blocks-when-calculatin.patch | 68 + - ...bcm47xxpart-detect-T_Meter-partition.patch | 37 + - ...mtd-add-routerbootpart-parser-config.patch | 36 + - .../pending-4.14/440-block2mtd_init.patch | 116 + - .../pending-4.14/441-block2mtd_probe.patch | 47 + - ...-fallback-from-spi_flash_read-to-reg.patch | 36 + - ...w-NOR-driver-to-write-fewer-bytes-th.patch | 36 + - ...mtd-cfi_cmdset_0002-no-erase_suspend.patch | 25 + - ...et_0002-add-buffer-write-cmd-timeout.patch | 17 + - ...25p80-mx-disable-software-protection.patch | 18 + - ...or-fix-Spansion-regressions-aliased-.patch | 37 + - ...ort-limiting-4K-sectors-support-base.patch | 56 + - ...pi-nor-Add-Winbond-w25q128jv-support.patch | 34 + - .../476-mtd-spi-nor-add-eon-en25q128.patch | 18 + - .../477-mtd-add-spi-nor-add-mx25u3235f.patch | 18 + - ...support-for-XM25QH64A-and-XM25QH128A.patch | 30 + - .../479-mtd-spi-nor-add-eon-en25qh32.patch | 10 + - .../479-mtd-spi-nor-add-eon-en25qh64.patch | 10 + - .../479-mtd-spi-nor-add-xtx-xt25f128b.patch | 42 + - .../480-mtd-set-rootfs-to-be-root-dev.patch | 38 + - ...r-add-support-for-Gigadevice-GD25D05.patch | 24 + - ...mtd-device-named-ubi-or-data-on-boot.patch | 97 + - ...to-create-ubiblock-device-for-rootfs.patch | 66 + - ...ting-ubi0-rootfs-in-init-do_mounts.c.patch | 51 + - ...ROOT_DEV-to-ubiblock-rootfs-if-unset.patch | 34 + - .../494-mtd-ubi-add-EOF-marker-support.patch | 60 + - ...-mtd-core-add-get_mtd_device_by_node.patch | 75 + - ...-add-bindings-for-mtd-concat-devices.patch | 52 + - ...cat-add-dt-driver-for-concat-devices.patch | 216 + - .../530-jffs2_make_lzma_available.patch | 5180 +++++++++++++++ - .../pending-4.14/532-jffs2_eofdetect.patch | 65 + - .../600-netfilter_conntrack_flush.patch | 95 + - ...etfilter_match_bypass_default_checks.patch | 110 + - ...netfilter_match_bypass_default_table.patch | 111 + - ...netfilter_match_reduce_memory_access.patch | 22 + - ...-netfilter_optional_tcp_window_check.patch | 44 + - ...del-do-not-defer-queue-length-update.patch | 86 + - .../pending-4.14/630-packet_socket_type.patch | 138 + - ...w_table-add-hardware-offload-support.patch | 565 ++ - ...w_table-support-hw-offload-through-v.patch | 306 + - ...-support-hardware-flow-table-offload.patch | 60 + - ...-support-hardware-flow-table-offload.patch | 61 + - ...-support-hardware-flow-table-offload.patch | 125 + - ...w_table-rework-hardware-offload-time.patch | 37 + - ...low_table-rework-private-driver-data.patch | 25 + - .../pending-4.14/655-increase_skb_pad.patch | 20 + - ...Add-support-for-MAP-E-FMRs-mesh-mode.patch | 500 ++ - ...ng-with-source-address-failed-policy.patch | 255 + - ...nes-for-_POLICY_FAILED-until-all-cod.patch | 50 + - ...T-skip-GRO-for-foreign-MAC-addresses.patch | 152 + - .../681-NET-add-of_get_mac_address_mtd.patch | 133 + - ...dd-support-for-threaded-NAPI-polling.patch | 339 + - ...detach-callback-to-struct-phy_driver.patch | 38 + - ...-at803x-allow-to-configure-via-pdata.patch | 142 + - ...net-phy-at803x-fix-at8033-sgmii-mode.patch | 51 + - .../810-pci_disable_common_quirks.patch | 60 + - .../811-pci_disable_usb_common_quirks.patch | 115 + - .../pending-4.14/834-ledtrig-libata.patch | 149 + - .../pending-4.14/920-mangle_bootargs.patch | 71 + - tools/Makefile | 2 +- - 722 files changed, 131914 insertions(+), 6 deletions(-) - create mode 100644 target/linux/ar71xx/Makefile - create mode 100755 target/linux/ar71xx/base-files/etc/board.d/01_leds - create mode 100755 target/linux/ar71xx/base-files/etc/board.d/02_network - create mode 100755 target/linux/ar71xx/base-files/etc/board.d/03_gpio_switches - create mode 100644 target/linux/ar71xx/base-files/etc/diag.sh - create mode 100644 target/linux/ar71xx/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom - create mode 100644 target/linux/ar71xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata - create mode 100644 target/linux/ar71xx/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac - create mode 100644 target/linux/ar71xx/base-files/etc/hotplug.d/net/10-ar922x-led-fix - create mode 100644 target/linux/ar71xx/base-files/etc/inittab - create mode 100644 target/linux/ar71xx/base-files/etc/uci-defaults/03_network-switchX-migration - create mode 100644 target/linux/ar71xx/base-files/etc/uci-defaults/03_network-vlan-migration - create mode 100644 target/linux/ar71xx/base-files/etc/uci-defaults/04_led_migration - create mode 100644 target/linux/ar71xx/base-files/etc/uci-defaults/09_fix-checksum - create mode 100644 target/linux/ar71xx/base-files/etc/uci-defaults/09_fix-seama-header - create mode 100755 target/linux/ar71xx/base-files/lib/ar71xx.sh - create mode 100644 target/linux/ar71xx/base-files/lib/preinit/01_preinit_do_ar71xx.sh - create mode 100644 target/linux/ar71xx/base-files/lib/preinit/05_set_iface_mac_ar71xx - create mode 100644 target/linux/ar71xx/base-files/lib/preinit/05_set_preinit_iface_ar71xx - create mode 100644 target/linux/ar71xx/base-files/lib/preinit/82_patch_ath10k - create mode 100644 target/linux/ar71xx/base-files/lib/upgrade/allnet.sh - create mode 100644 target/linux/ar71xx/base-files/lib/upgrade/dir825.sh - create mode 100644 target/linux/ar71xx/base-files/lib/upgrade/merakinand.sh - create mode 100644 target/linux/ar71xx/base-files/lib/upgrade/openmesh.sh - create mode 100755 target/linux/ar71xx/base-files/lib/upgrade/platform.sh - create mode 100644 target/linux/ar71xx/config-4.14 - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/Kconfig.openwrt - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/Makefile - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.h - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-dsa.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-dsa.h - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-eth.h - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.h - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.h - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-a60.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-ap120c.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-ap96.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-nx.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-all0258n.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-all0315n.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-antminer-s1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-antminer-s3.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-antrouter-r1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ap121f.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ap132.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ap143.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ap147.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ap152.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ap531b0.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ap90q.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ap91-5g.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ap96.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c25-v1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c59-v1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c60-v1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c7-v4.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c7-v5.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c7.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-arduino-yun.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-aw-nr580.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-bhr-4grv2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-bhu-bxu2000n2-a.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-bsb.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-c55.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-c60.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-cap324.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-cap4200ag.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-carambola2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-cf-e316n-v2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-cpe510.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-cpe870.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-cr3000.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-cr5000.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dap-1330-a1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dap-2695-a1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dgl-5500-a1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dhp-1565-a1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dir-505-a1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dir-600-a1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dir-615-c1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dir-615-i1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dir-825-b1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dir-825-c1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dir-869-a1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dlan-hotspot.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dlan-pro-1200-ac.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dlan-pro-500-wp.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-domywifi-dw33d.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dr344.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dr531.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dragino2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-e1700ac-v2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-e2100l.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-e558-v2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-e600g-v2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-e750a-v4.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-e750g-v8.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-eap120.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-eap300v2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-eap7660d.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-el-m150.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-el-mini.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ens202ext.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-epg5000.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-esr1750.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-esr900.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ew-balin.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ew-dorin.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-f9k1115v2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-fritz300e.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-fritz4020.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-fritz450e.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar150.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar300.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar300m.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar750.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar750s.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-gl-domino.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-gl-inet.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-gl-mifi.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-gl-usb150.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-gs-minibox-v32.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-gs-oolite-v1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-gs-oolite-v5-2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-hiveap-121.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-hiwifi-hc6361.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-hornet-ub.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ja76pf.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-jwap003.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-jwap230.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-koala.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-lan-turtle.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-lima.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-mc-mac1200r.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-mr12.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-mr16.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-mr1750.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-mr600.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-mr900.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-mynet-n600.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-mynet-n750.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-mynet-rext.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-mzk-w04nu.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-mzk-w300nh.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-n5q.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-nbg460n.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-nbg6716.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-om2p.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-om5p.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-om5pac.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-om5pacv2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-omy-g1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-omy-x1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-onion-omega.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-pb42.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-pqi-air-pen.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-qihoo-c301.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-r36a.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-r602n.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-r6100.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-rambutan.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-rb2011.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-rb4xx.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-rb750.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-rb91x.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-rb922.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-rb95x.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-rbspi.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-rbsxtlite.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-re450.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-rme-eg200.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-rut9xx.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-rw2458n.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-sc1750.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-sc300m.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-sc450.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-smart-300.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-som9331.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-sr3200.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-t830.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tellstick-znet-lite.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tew-632brp.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tew-673gru.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tew-712br.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tew-732br.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tew-823dru.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr11u.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr13u.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3020.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr6400.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa701nd-v2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa7210n-v2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa801nd-v3.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa830re-v2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd-v2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd-v4.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wax50re.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr3320-v2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr3500.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr4300.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr6500-v2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wpa8630.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1041n-v2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1043nd-v2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1043nd-v4.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1043nd.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr2543n.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr703n.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr720n-v3.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr741nd-v4.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr741nd.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr802n.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr810n.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n-v8.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n-v9.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr902ac-v1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr940n-v4.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr941nd-v6.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr941nd.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr942n-v1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ts-d084.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tube2h.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ubnt-unifiac.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ubnt-xm.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ubnt.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wam250.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-weio.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-whr-hp-g300n.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wi2a-ac200i.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wifi-pineapple-nano.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wlae-ag300n.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wlr8100.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wndap360.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wndr3700.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wndr4300.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2000-v3.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2000-v4.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2000.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2200.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wp543.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wpe72.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wpj342.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wpj344.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wpj531.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wpj558.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wpj563.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wrt160nl.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wrt400n.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wrtnode2q.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-450hp2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-ag300h.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g300nh.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g300nh2.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g450h.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-z1.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-zbt-we1526.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-zcn-1523h.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/machtypes.h - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/nvram.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/nvram.h - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.h - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/routerboot.c - create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/routerboot.h - create mode 100644 target/linux/ar71xx/files/arch/mips/include/asm/fw/myloader/myloader.h - create mode 100644 target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h - create mode 100644 target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/mach-rb750.h - create mode 100644 target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/rb4xx_cpld.h - create mode 100644 target/linux/ar71xx/files/drivers/gpio/gpio-latch.c - create mode 100644 target/linux/ar71xx/files/drivers/gpio/gpio-nxp-74hc153.c - create mode 100644 target/linux/ar71xx/files/drivers/leds/leds-nu801.c - create mode 100644 target/linux/ar71xx/files/drivers/leds/leds-rb750.c - create mode 100644 target/linux/ar71xx/files/drivers/leds/leds-wndr3700-usb.c - create mode 100644 target/linux/ar71xx/files/drivers/mtd/cybertan_part.c - create mode 100644 target/linux/ar71xx/files/drivers/mtd/nand/ar934x_nfc.c - create mode 100644 target/linux/ar71xx/files/drivers/mtd/nand/rb4xx_nand.c - create mode 100644 target/linux/ar71xx/files/drivers/mtd/nand/rb750_nand.c - create mode 100644 target/linux/ar71xx/files/drivers/mtd/nand/rb91x_nand.c - create mode 100644 target/linux/ar71xx/files/drivers/mtd/tplinkpart.c - create mode 100644 target/linux/ar71xx/files/drivers/net/dsa/mv88e6063.c - create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Kconfig - create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Makefile - create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h - create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c - create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar8216.c - create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c - create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ethtool.c - create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c - create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c - create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_phy.c - create mode 100644 target/linux/ar71xx/files/drivers/spi/spi-rb4xx-cpld.c - create mode 100644 target/linux/ar71xx/files/drivers/spi/spi-rb4xx.c - create mode 100644 target/linux/ar71xx/files/drivers/spi/spi-vsc7385.c - create mode 100644 target/linux/ar71xx/files/include/linux/leds-nu801.h - create mode 100644 target/linux/ar71xx/files/include/linux/nxp_74hc153.h - create mode 100644 target/linux/ar71xx/files/include/linux/platform/ar934x_nfc.h - create mode 100644 target/linux/ar71xx/files/include/linux/platform_data/gpio-latch.h - create mode 100644 target/linux/ar71xx/files/include/linux/platform_data/rb91x_nand.h - create mode 100644 target/linux/ar71xx/files/include/linux/spi/vsc7385.h - create mode 100644 target/linux/ar71xx/generic/config-default - create mode 100644 target/linux/ar71xx/generic/profiles/00-default.mk - create mode 100644 target/linux/ar71xx/generic/target.mk - create mode 100644 target/linux/ar71xx/image/Makefile - create mode 100644 target/linux/ar71xx/image/common-tp-link.mk - create mode 100644 target/linux/ar71xx/image/generic-legacy-devices.mk - create mode 100644 target/linux/ar71xx/image/generic-tp-link.mk - create mode 100644 target/linux/ar71xx/image/generic-ubnt.mk - create mode 100644 target/linux/ar71xx/image/generic.mk - create mode 100644 target/linux/ar71xx/image/legacy.mk - create mode 100644 target/linux/ar71xx/image/lzma-loader/Makefile - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/LzmaDecode.c - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/LzmaDecode.h - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/LzmaTypes.h - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/Makefile - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/ar71xx_regs.h - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/board.c - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/cache.c - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/cache.h - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/cacheops.h - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/config.h - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/cp0regdef.h - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/head.S - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/loader.c - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/loader.lds - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/loader2.lds - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/lzma-data.lds - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/printf.c - create mode 100644 target/linux/ar71xx/image/lzma-loader/src/printf.h - create mode 100644 target/linux/ar71xx/image/mikrotik.mk - create mode 100644 target/linux/ar71xx/image/nand.mk - create mode 100644 target/linux/ar71xx/image/tiny-legacy-devices.mk - create mode 100644 target/linux/ar71xx/image/tiny-senao.mk - create mode 100644 target/linux/ar71xx/image/tiny-tp-link.mk - create mode 100644 target/linux/ar71xx/image/tiny.mk - create mode 100644 target/linux/ar71xx/image/ubinize-nbg6716.ini - create mode 100644 target/linux/ar71xx/image/ubinize-wndr4300.ini - create mode 100644 target/linux/ar71xx/mikrotik/config-default - create mode 100644 target/linux/ar71xx/mikrotik/profiles/00-default.mk - create mode 100644 target/linux/ar71xx/mikrotik/target.mk - create mode 100644 target/linux/ar71xx/modules.mk - create mode 100644 target/linux/ar71xx/nand/config-default - create mode 100644 target/linux/ar71xx/nand/profiles/00-default.mk - create mode 100644 target/linux/ar71xx/nand/target.mk - create mode 100644 target/linux/ar71xx/patches-4.14/001-spi-cs-gpio.patch - create mode 100644 target/linux/ar71xx/patches-4.14/002-add_back_gpio_function_select.patch - create mode 100644 target/linux/ar71xx/patches-4.14/004-register_gpio_driver_earlier.patch - create mode 100644 target/linux/ar71xx/patches-4.14/100-MIPS-ath79-Avoid-using-unitialized-reg-variable.patch - create mode 100644 target/linux/ar71xx/patches-4.14/106-02-MIPS-ath79-do-AR724x-PCIe-root-complex-init.patch - create mode 100644 target/linux/ar71xx/patches-4.14/200-MIPS-ath79-fix-ar933x-wmac-reset.patch - create mode 100644 target/linux/ar71xx/patches-4.14/201-ar913x_wmac_external_reset.patch - create mode 100644 target/linux/ar71xx/patches-4.14/202-MIPS-ath79-ar934x-wmac-revision.patch - create mode 100644 target/linux/ar71xx/patches-4.14/220-add_cpu_feature_overrides.patch - create mode 100644 target/linux/ar71xx/patches-4.14/300-MIPS-add-MIPS_MACHINE_NONAME-macro.patch - create mode 100644 target/linux/ar71xx/patches-4.14/310-lib-add-rle-decompression.patch - create mode 100644 target/linux/ar71xx/patches-4.14/343-MIPS-ath79-Fix-potentially-missed-IRQ-handling-durin.patch - create mode 100644 target/linux/ar71xx/patches-4.14/401-mtd-physmap-add-lock-unlock.patch - create mode 100644 target/linux/ar71xx/patches-4.14/402-mtd-SST39VF6401B-support.patch - create mode 100644 target/linux/ar71xx/patches-4.14/404-mtd-cybertan-trx-parser.patch - create mode 100644 target/linux/ar71xx/patches-4.14/405-mtd-tp-link-partition-parser.patch - create mode 100644 target/linux/ar71xx/patches-4.14/407-mtd-m25p80-allow-to-pass-probe-types-via-platform-data.patch - create mode 100644 target/linux/ar71xx/patches-4.14/408-mtd-redboot_partition_scan.patch - create mode 100644 target/linux/ar71xx/patches-4.14/409-mtd-rb4xx_nand_driver.patch - create mode 100644 target/linux/ar71xx/patches-4.14/410-mtd-rb750-nand-driver.patch - create mode 100644 target/linux/ar71xx/patches-4.14/411-mtd-cfi_cmdset_0002-force-word-write.patch - create mode 100644 target/linux/ar71xx/patches-4.14/413-mtd-ar934x-nand-driver.patch - create mode 100644 target/linux/ar71xx/patches-4.14/414-mtd-rb91x-nand-driver.patch - create mode 100644 target/linux/ar71xx/patches-4.14/420-net-ar71xx_mac_driver.patch - create mode 100644 target/linux/ar71xx/patches-4.14/423-dsa-add-88e6063-driver.patch - create mode 100644 target/linux/ar71xx/patches-4.14/430-drivers-link-spi-before-mtd.patch - create mode 100644 target/linux/ar71xx/patches-4.14/432-spi-rb4xx-spi-driver.patch - create mode 100644 target/linux/ar71xx/patches-4.14/433-spi-rb4xx-cpld-driver.patch - create mode 100644 target/linux/ar71xx/patches-4.14/435-spi-vsc7385_driver.patch - create mode 100644 target/linux/ar71xx/patches-4.14/440-leds-wndr3700-usb-led-driver.patch - create mode 100644 target/linux/ar71xx/patches-4.14/441-leds-rb750-led-driver.patch - create mode 100644 target/linux/ar71xx/patches-4.14/442-leds-gpio-allow-to-use-OPEN_-DRAIN-SOURCE-flags-with.patch - create mode 100644 target/linux/ar71xx/patches-4.14/450-gpio-nxp-74hc153-gpio-chip-driver.patch - create mode 100644 target/linux/ar71xx/patches-4.14/451-gpio-74x164-improve-platform-device-support.patch - create mode 100644 target/linux/ar71xx/patches-4.14/452-gpio-add-gpio-latch-driver.patch - create mode 100644 target/linux/ar71xx/patches-4.14/461-spi-ath79-add-fast-flash-read.patch - create mode 100644 target/linux/ar71xx/patches-4.14/470-MIPS-ath79-swizzle-pci-address-for-ar71xx.patch - create mode 100644 target/linux/ar71xx/patches-4.14/490-usb-ehci-add-quirks-for-qca-socs.patch - create mode 100644 target/linux/ar71xx/patches-4.14/500-MIPS-fw-myloader.patch - create mode 100644 target/linux/ar71xx/patches-4.14/501-MIPS-ath79-add-mac-argument-to-ath79_register_wmac.patch - create mode 100644 target/linux/ar71xx/patches-4.14/504-MIPS-ath79-add-ath79_device_reset_get.patch - create mode 100644 target/linux/ar71xx/patches-4.14/505-MIPS-ath79-add-ath79_gpio_function_select.patch - create mode 100644 target/linux/ar71xx/patches-4.14/506-MIPS-ath79-prom-parse-redboot-args.patch - create mode 100644 target/linux/ar71xx/patches-4.14/507-MIPS-ath79-prom-add-myloader-support.patch - create mode 100644 target/linux/ar71xx/patches-4.14/508-MIPS-ath79-prom-image-command-line-hack.patch - create mode 100644 target/linux/ar71xx/patches-4.14/509-MIPS-ath79-process-board-kernel-option.patch - create mode 100644 target/linux/ar71xx/patches-4.14/510-MIPS-ath79-init-gpio-pin-of-wmac-device.patch - create mode 100644 target/linux/ar71xx/patches-4.14/520-MIPS-ath79-enable-UART-function.patch - create mode 100644 target/linux/ar71xx/patches-4.14/521-MIPS-ath79-enable-UART-for-early_serial.patch - create mode 100644 target/linux/ar71xx/patches-4.14/522-MIPS-ath79-add-ath79_wmac_register_simple-helper.patch - create mode 100644 target/linux/ar71xx/patches-4.14/523-MIPS-ath79-OTP-support.patch - create mode 100644 target/linux/ar71xx/patches-4.14/524-MIPS-ath79-add-ath79_wmac_disable_25ghz-helpers.patch - create mode 100644 target/linux/ar71xx/patches-4.14/525-MIPS-ath79-enable-qca-usb-quirks.patch - create mode 100644 target/linux/ar71xx/patches-4.14/601-MIPS-ath79-add-more-register-defines.patch - create mode 100644 target/linux/ar71xx/patches-4.14/602-MIPS-ath79-add-openwrt-stuff.patch - create mode 100644 target/linux/ar71xx/patches-4.14/603-MIPS-ath79-ap121-fixes.patch - create mode 100644 target/linux/ar71xx/patches-4.14/604-MIPS-ath79-no-of.patch - create mode 100644 target/linux/ar71xx/patches-4.14/605-MIPS-ath79-db120-fixes.patch - create mode 100644 target/linux/ar71xx/patches-4.14/606-MIPS-ath79-pb44-fixes.patch - create mode 100644 target/linux/ar71xx/patches-4.14/607-MIPS-ath79-ubnt-xm-fixes.patch - create mode 100644 target/linux/ar71xx/patches-4.14/608-MIPS-ath79-ubnt-xm-add-more-boards.patch - create mode 100644 target/linux/ar71xx/patches-4.14/609-MIPS-ath79-ap136-fixes.patch - create mode 100644 target/linux/ar71xx/patches-4.14/611-MIPS-ath79-wdt-timeout.patch - create mode 100644 target/linux/ar71xx/patches-4.14/612-MIPS-ath79-set-buffalo-txgain.patch - create mode 100644 target/linux/ar71xx/patches-4.14/613-MIPS-ath79-add-ath79_wmac_setup_ext_lna_gpio-helper.patch - create mode 100644 target/linux/ar71xx/patches-4.14/620-MIPS-ath79-add-support-for-QCA953x-SoC.patch - create mode 100644 target/linux/ar71xx/patches-4.14/621-MIPS-ath79-add-support-for-QCA956x-SoC.patch - create mode 100644 target/linux/ar71xx/patches-4.14/622-MIPS-ath79-add-more-register-defines-for-QCA956x-SoC.patch - create mode 100644 target/linux/ar71xx/patches-4.14/630-MIPS-ath79-fix-chained-irq-disable.patch - create mode 100644 target/linux/ar71xx/patches-4.14/631-MIPS-ath79-wmac-enable-set-led-pin.patch - create mode 100644 target/linux/ar71xx/patches-4.14/632-MIPS-ath79-gpio-enable-set-direction.patch - create mode 100644 target/linux/ar71xx/patches-4.14/640-MIPS-ath79-add-QCA955x-wmac-reset.patch - create mode 100644 target/linux/ar71xx/patches-4.14/700-MIPS-ath79-add-openwrt-Kconfig.patch - create mode 100644 target/linux/ar71xx/patches-4.14/701-MIPS-ath79-add-routerboard-detection.patch - create mode 100644 target/linux/ar71xx/patches-4.14/702-MIPS-ath79-fixup-routerboot-board-parameter.patch - create mode 100644 target/linux/ar71xx/patches-4.14/739-MIPS-ath79-add-gpio-func-register-for-QCA955x-SoC.patch - create mode 100644 target/linux/ar71xx/patches-4.14/740-MIPS-ath79-add-PCI-for-QCA953x-SoC.patch - create mode 100644 target/linux/ar71xx/patches-4.14/741-MIPS-ath79-add-PCI-for-QCA9556-SoC.patch - create mode 100644 target/linux/ar71xx/patches-4.14/818-MIPS-ath79-add-nu801-led-driver.patch - create mode 100644 target/linux/ar71xx/patches-4.14/820-MIPS-ath79-add_gpio_function2_setup.patch - create mode 100644 target/linux/ar71xx/patches-4.14/821-serial-core-add-support-for-boot-console-with-arbitr.patch - create mode 100644 target/linux/ar71xx/patches-4.14/900-mdio_bitbang_ignore_ta_value.patch - create mode 100644 target/linux/ar71xx/patches-4.14/901-phy-mdio-bitbang-prevent-rescheduling-during-command.patch - create mode 100644 target/linux/ar71xx/patches-4.14/902-at803x-add-reset-gpio-pdata.patch - create mode 100644 target/linux/ar71xx/patches-4.14/903-at803x-add-sgmii-aneg-override-pdata.patch - create mode 100644 target/linux/ar71xx/patches-4.14/910-unaligned_access_hacks.patch - create mode 100644 target/linux/ar71xx/patches-4.14/920-usb-chipidea-AR933x-platform-support.patch - create mode 100644 target/linux/ar71xx/patches-4.14/921-MIPS-ath79-add-even-more-register-defines-for-QCA956x-SoC.patch - create mode 100644 target/linux/ar71xx/patches-4.14/930-chipidea-pullup.patch - create mode 100644 target/linux/ar71xx/patches-4.14/940-qca955x-add-more-registers.patch - create mode 100644 target/linux/ar71xx/patches-4.14/950-add-boardinfo-platform-data.patch - create mode 100644 target/linux/ar71xx/patches-4.14/952-qca955x-enable-ddr-wb-flush.patch - create mode 100644 target/linux/ar71xx/patches-4.14/953-qca955x-pci-reset-fixes.patch - create mode 100644 target/linux/ar71xx/patches-4.14/955-qca953x-fix-potential-missing-irq-dispatch.patch - create mode 100644 target/linux/ar71xx/patches-4.14/999-backport-fixes.patch - create mode 100644 target/linux/ar71xx/tiny/config-default - create mode 100644 target/linux/ar71xx/tiny/profiles/00-default.mk - create mode 100644 target/linux/ar71xx/tiny/target.mk - create mode 100644 target/linux/generic/backport-4.14/010-Kbuild-don-t-hardcode-path-to-awk-in-scripts-ld-vers.patch - create mode 100644 target/linux/generic/backport-4.14/011-kbuild-export-SUBARCH.patch - create mode 100644 target/linux/generic/backport-4.14/012-kbuild-add-macro-for-controlling-warnings-to-linux-c.patch - create mode 100644 target/linux/generic/backport-4.14/013-disable-Wattribute-alias-warning-for-SYSCALL_DEFINEx.patch - create mode 100644 target/linux/generic/backport-4.14/020-backport_netfilter_rtcache.patch - create mode 100644 target/linux/generic/backport-4.14/025-tcp-allow-drivers-to-tweak-TSQ-logic.patch - create mode 100644 target/linux/generic/backport-4.14/030-USB-serial-option-fix-dwm-158-3g-modem-interface.patch - create mode 100644 target/linux/generic/backport-4.14/030-v4.17-0001-usb-dwc2-add-support-for-host-mode-external-vbus-sup.patch - create mode 100644 target/linux/generic/backport-4.14/030-v4.17-0002-usb-dwc2-dwc2_vbus_supply_init-fix-error-check.patch - create mode 100644 target/linux/generic/backport-4.14/040-v4.17-0001-mtd-move-code-adding-master-MTD-out-of-mtd_add_devic.patch - create mode 100644 target/linux/generic/backport-4.14/040-v4.17-0002-mtd-get-rid-of-the-mtd_add_device_partitions.patch - create mode 100644 target/linux/generic/backport-4.14/041-v4.17-0001-mtd-partitions-add-of_match_table-parser-matching-fo.patch - create mode 100644 target/linux/generic/backport-4.14/041-v4.17-0002-mtd-rename-ofpart-parser-to-fixed-partitions-as-it-f.patch - create mode 100644 target/linux/generic/backport-4.14/041-v4.17-0003-mtd-ofpart-add-of_match_table-with-fixed-partitions.patch - create mode 100644 target/linux/generic/backport-4.14/042-v4.18-0001-mtd-move-code-adding-registering-partitions-to-the-p.patch - create mode 100644 target/linux/generic/backport-4.14/043-v4.18-mtd-bcm47xxpart-improve-handling-TRX-partition-size.patch - create mode 100644 target/linux/generic/backport-4.14/044-v4.18-mtd-bcm47xxpart-add-of_match_table-with-a-new-DT-bin.patch - create mode 100644 target/linux/generic/backport-4.14/045-v4.19-mtd-parsers-trx-add-of_match_table-with-the-new-DT-b.patch - create mode 100644 target/linux/generic/backport-4.14/046-v4.19-mtd-partitions-use-DT-info-for-parsing-partitions-wi.patch - create mode 100644 target/linux/generic/backport-4.14/047-v4.21-mtd-keep-original-flags-for-every-struct-mtd_info.patch - create mode 100644 target/linux/generic/backport-4.14/048-v4.21-mtd-improve-calculating-partition-boundaries-when-ch.patch - create mode 100644 target/linux/generic/backport-4.14/050-v4.19-f2fs-skip-verifying-block-address-non-regular-inode.patch - create mode 100644 target/linux/generic/backport-4.14/071-v4.15-0001-net-bgmac-enable-master-mode-for-BCM54210E-and-B5021.patch - create mode 100644 target/linux/generic/backport-4.14/076-v4.15-0001-net-phy-broadcom-support-new-device-flag-for-setting.patch - create mode 100644 target/linux/generic/backport-4.14/080-v5.1-0001-bcma-keep-a-direct-pointer-to-the-struct-device.patch - create mode 100644 target/linux/generic/backport-4.14/080-v5.1-0002-bcma-use-dev_-printing-functions.patch - create mode 100644 target/linux/generic/backport-4.14/085-v4.16-0001-i2c-gpio-Enable-working-over-slow-can_sleep-GPIOs.patch - create mode 100644 target/linux/generic/backport-4.14/090-net-bridge-add-support-for-port-isolation.patch - create mode 100644 target/linux/generic/backport-4.14/095-Allow-class-e-address-assignment-via-ifconfig-ioctl.patch - create mode 100644 target/linux/generic/backport-4.14/101-arm-cns3xxx-use-actual-size-reads-for-PCIe.patch - create mode 100644 target/linux/generic/backport-4.14/183-net-qmi_wwan-add-Wistron-Neweb-D19Q1.patch - create mode 100644 target/linux/generic/backport-4.14/270-batman-adv-Let-packet.h-include-its-headers-directly.patch - create mode 100644 target/linux/generic/backport-4.14/271-batman-adv-Remove-usage-of-BIT-x-in-packet.h.patch - create mode 100644 target/linux/generic/backport-4.14/272-batman-adv-Remove-kernel-fixed-width-types-in-packet.patch - create mode 100644 target/linux/generic/backport-4.14/273-batman-adv-Convert-packet.h-to-uapi-header.patch - create mode 100644 target/linux/generic/backport-4.14/274-flow_dissector-Parse-batman-adv-unicast-headers.patch - create mode 100644 target/linux/generic/backport-4.14/289-v4.16-netfilter-add-defines-for-arp-decnet-max-hooks.patch - create mode 100644 target/linux/generic/backport-4.14/290-v4.16-netfilter-core-make-nf_unregister_net_hooks-simple-w.patch - create mode 100644 target/linux/generic/backport-4.14/291-v4.16-netfilter-core-remove-synchronize_net-call-if-nfqueu.patch - create mode 100644 target/linux/generic/backport-4.14/292-v4.16-netfilter-core-free-hooks-with-call_rcu.patch - create mode 100644 target/linux/generic/backport-4.14/293-v4.16-netfilter-reduce-size-of-hook-entry-point-locations.patch - create mode 100644 target/linux/generic/backport-4.14/294-v4.16-netfilter-reduce-hook-array-sizes-to-what-is-needed.patch - create mode 100644 target/linux/generic/backport-4.14/295-v4.16-netfilter-don-t-allocate-space-for-decnet-hooks-unle.patch - create mode 100644 target/linux/generic/backport-4.14/296-v4.16-netfilter-don-t-allocate-space-for-arp-bridge-hooks-.patch - create mode 100644 target/linux/generic/backport-4.14/297-v4.16-netfilter-core-pass-hook-number-family-and-device-to.patch - create mode 100644 target/linux/generic/backport-4.14/298-v4.16-netfilter-core-add-nf_remove_net_hook.patch - create mode 100644 target/linux/generic/backport-4.14/298-v4.16-netfilter-core-pass-family-as-parameter-to-nf_remove.patch - create mode 100644 target/linux/generic/backport-4.14/299-v4.16-netfilter-core-support-for-NFPROTO_INET-hook-registr.patch - create mode 100644 target/linux/generic/backport-4.14/300-v4.16-netfilter-nf_tables-explicit-nft_set_pktinfo-call-fr.patch - create mode 100644 target/linux/generic/backport-4.14/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch - create mode 100644 target/linux/generic/backport-4.14/302-v4.16-netfilter-nf_tables_inet-don-t-use-multihook-infrast.patch - create mode 100644 target/linux/generic/backport-4.14/303-v4.16-netfilter-nf_tables-remove-multihook-chains-and-fami.patch - create mode 100644 target/linux/generic/backport-4.14/304-v4.16-netfilter-move-checksum-indirection-to-struct-nf_ipv.patch - create mode 100644 target/linux/generic/backport-4.14/305-v4.16-netfilter-move-checksum_partial-indirection-to-struc.patch - create mode 100644 target/linux/generic/backport-4.14/306-v4.16-netfilter-remove-saveroute-indirection-in-struct-nf_.patch - create mode 100644 target/linux/generic/backport-4.14/307-v4.16-netfilter-move-route-indirection-to-struct-nf_ipv6_o.patch - create mode 100644 target/linux/generic/backport-4.14/308-v4.16-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch - create mode 100644 target/linux/generic/backport-4.14/309-v4.16-netfilter-remove-route_key_size-field-in-struct-nf_a.patch - create mode 100644 target/linux/generic/backport-4.14/310-v4.16-netfilter-remove-struct-nf_afinfo-and-its-helper-fun.patch - create mode 100644 target/linux/generic/backport-4.14/311-v4.16-netfilter-nf_tables_arp-don-t-set-forward-chain.patch - create mode 100644 target/linux/generic/backport-4.14/312-v4.16-netfilter-nf_tables-remove-hooks-from-family-definit.patch - create mode 100644 target/linux/generic/backport-4.14/313-v4.16-netfilter-remove-defensive-check-on-malformed-packet.patch - create mode 100644 target/linux/generic/backport-4.14/314-v4.16-netfilter-meta-secpath-support.patch - create mode 100644 target/linux/generic/backport-4.14/315-v4.15-netfilter-conntrack-move-nf_ct_netns_-get-put-to-cor.patch - create mode 100644 target/linux/generic/backport-4.14/320-v4.16-netfilter-nf_conntrack-add-IPS_OFFLOAD-status-bit.patch - create mode 100644 target/linux/generic/backport-4.14/321-v4.16-netfilter-nf_tables-add-flow-table-netlink-frontend.patch - create mode 100644 target/linux/generic/backport-4.14/322-v4.16-netfilter-add-generic-flow-table-infrastructure.patch - create mode 100644 target/linux/generic/backport-4.14/323-v4.16-netfilter-flow-table-support-for-IPv4.patch - create mode 100644 target/linux/generic/backport-4.14/324-v4.16-netfilter-flow-table-support-for-IPv6.patch - create mode 100644 target/linux/generic/backport-4.14/325-v4.16-netfilter-flow-table-support-for-the-mixed-IPv4-IPv6.patch - create mode 100644 target/linux/generic/backport-4.14/326-v4.16-netfilter-nf_tables-flow-offload-expression.patch - create mode 100644 target/linux/generic/backport-4.14/327-v4.16-netfilter-nf_tables-remove-nhooks-field-from-struct-.patch - create mode 100644 target/linux/generic/backport-4.14/328-v4.16-netfilter-nf_tables-fix-a-typo-in-nf_tables_getflowt.patch - create mode 100644 target/linux/generic/backport-4.14/329-v4.16-netfilter-improve-flow-table-Kconfig-dependencies.patch - create mode 100644 target/linux/generic/backport-4.14/330-v4.16-netfilter-nf_tables-remove-flag-field-from-struct-nf.patch - create mode 100644 target/linux/generic/backport-4.14/331-v4.16-netfilter-nf_tables-no-need-for-struct-nft_af_info-t.patch - create mode 100644 target/linux/generic/backport-4.14/332-v4.16-netfilter-nf_tables-remove-struct-nft_af_info-parame.patch - create mode 100644 target/linux/generic/backport-4.14/334-v4.15-netfilter-nf_tables-fix-potential-NULL-ptr-deref-in-.patch - create mode 100644 target/linux/generic/backport-4.14/335-v4.16-netfilter-nf_tables-add-single-table-list-for-all-fa.patch - create mode 100644 target/linux/generic/backport-4.14/336-v4.15-netfilter-exit_net-cleanup-check-added.patch - create mode 100644 target/linux/generic/backport-4.14/337-v4.16-netfilter-nf_tables-get-rid-of-pernet-families.patch - create mode 100644 target/linux/generic/backport-4.14/338-v4.16-netfilter-nf_tables-get-rid-of-struct-nft_af_info-ab.patch - create mode 100644 target/linux/generic/backport-4.14/339-v4.16-netfilter-nft_flow_offload-wait-for-garbage-collecto.patch - create mode 100644 target/linux/generic/backport-4.14/340-v4.16-netfilter-nft_flow_offload-no-need-to-flush-entries-.patch - create mode 100644 target/linux/generic/backport-4.14/341-v4.16-netfilter-nft_flow_offload-move-flowtable-cleanup-ro.patch - create mode 100644 target/linux/generic/backport-4.14/342-v4.16-netfilter-nf_tables-fix-flowtable-free.patch - create mode 100644 target/linux/generic/backport-4.14/343-netfilter-nft_flow_offload-handle-netdevice-events-f.patch - create mode 100644 target/linux/generic/backport-4.14/344-v4.16-netfilter-nf_tables-allocate-handle-and-delete-objec.patch - create mode 100644 target/linux/generic/backport-4.14/345-v4.16-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch - create mode 100644 target/linux/generic/backport-4.14/346-v4.16-netfilter-flowtable-infrastructure-depends-on-NETFIL.patch - create mode 100644 target/linux/generic/backport-4.14/347-v4.16-netfilter-remove-duplicated-include.patch - create mode 100644 target/linux/generic/backport-4.14/348-v4.18-netfilter-nf_flow_table-use-IP_CT_DIR_-values-for-FL.patch - create mode 100644 target/linux/generic/backport-4.14/349-v4.18-netfilter-nf_flow_table-clean-up-flow_offload_alloc.patch - create mode 100644 target/linux/generic/backport-4.14/350-v4.18-ipv6-make-ip6_dst_mtu_forward-inline.patch - create mode 100644 target/linux/generic/backport-4.14/351-v4.18-netfilter-nf_flow_table-cache-mtu-in-struct-flow_off.patch - create mode 100644 target/linux/generic/backport-4.14/352-v4.18-netfilter-nf_flow_table-rename-nf_flow_table.c-to-nf.patch - create mode 100644 target/linux/generic/backport-4.14/353-v4.18-netfilter-nf_flow_table-move-ipv4-offload-hook-code-.patch - create mode 100644 target/linux/generic/backport-4.14/354-v4.18-netfilter-nf_flow_table-move-ip-header-check-out-of-.patch - create mode 100644 target/linux/generic/backport-4.14/355-v4.18-netfilter-nf_flow_table-move-ipv6-offload-hook-code-.patch - create mode 100644 target/linux/generic/backport-4.14/356-v4.18-netfilter-nf_flow_table-relax-mixed-ipv4-ipv6-flowta.patch - create mode 100644 target/linux/generic/backport-4.14/357-v4.18-netfilter-nf_flow_table-move-init-code-to-nf_flow_ta.patch - create mode 100644 target/linux/generic/backport-4.14/358-v4.18-netfilter-nf_flow_table-fix-priv-pointer-for-netdev-.patch - create mode 100644 target/linux/generic/backport-4.14/359-v4.18-netfilter-nf_flow_table-track-flow-tables-in-nf_flow.patch - create mode 100644 target/linux/generic/backport-4.14/360-v4.18-netfilter-nf_flow_table-make-flow_offload_dead-inlin.patch - create mode 100644 target/linux/generic/backport-4.14/361-v4.18-netfilter-nf_flow_table-add-a-new-flow-state-for-tea.patch - create mode 100644 target/linux/generic/backport-4.14/362-v4.18-netfilter-nf_flow_table-in-flow_offload_lookup-skip-.patch - create mode 100644 target/linux/generic/backport-4.14/363-v4.18-netfilter-nf_flow_table-add-support-for-sending-flow.patch - create mode 100644 target/linux/generic/backport-4.14/364-v4.18-netfilter-nf_flow_table-tear-down-TCP-flows-if-RST-o.patch - create mode 100644 target/linux/generic/backport-4.14/365-v4.16-netfilter-nf_flow_table-fix-checksum-when-handling-D.patch - create mode 100644 target/linux/generic/backport-4.14/366-netfilter-nft_flow_offload-Fix-reverse-route-lookup.patch - create mode 100644 target/linux/generic/backport-4.14/367-v4.18-netfilter-nf_flow_table-add-missing-condition-for-TC.patch - create mode 100644 target/linux/generic/backport-4.14/368-v4.18-netfilter-nf_flow_table-fix-offloading-connections-w.patch - create mode 100644 target/linux/generic/backport-4.14/369-v4.18-netfilter-nf_flow_table-attach-dst-to-skbs.patch - create mode 100644 target/linux/generic/backport-4.14/370-netfilter-nf_flow_table-fix-offloaded-connection-tim.patch - create mode 100644 target/linux/generic/backport-4.14/371-netfilter-nf_flow_table-fix-up-ct-state-of-flows-aft.patch - create mode 100644 target/linux/generic/backport-4.14/372-netfilter-nft_flow_offload-fix-interaction-with-vrf-.patch - create mode 100644 target/linux/generic/backport-4.14/380-v5.3-net-sched-Introduce-act_ctinfo-action.patch - create mode 100644 target/linux/generic/backport-4.14/400-v4.16-leds-trigger-Introduce-a-NETDEV-trigger.patch - create mode 100644 target/linux/generic/backport-4.14/401-v5.2-leds-trigger-netdev-fix-refcnt-leak-on-interface-ren.patch - create mode 100644 target/linux/generic/backport-4.14/402-leds-trigger-netdev-fix-handling-on-interface-rename.patch - create mode 100644 target/linux/generic/backport-4.14/410-mtd-fix-calculating-partition-end-address.patch - create mode 100644 target/linux/generic/backport-4.14/420-enable-CONFIG_MMC_SDHCI_IO_ACCESSORS.patch - create mode 100644 target/linux/generic/backport-4.14/500-v4.20-ubifs-Fix-default-compression-selection-in-ubifs.patch - create mode 100644 target/linux/generic/backport-4.14/900-v4.18-firmware-dmi-Add-access-to-the-SKU-ID-string.patch - create mode 100644 target/linux/generic/backport-4.14/950-tty-serial-exar-generalize-rs485-setup.patch - create mode 100644 target/linux/generic/config-4.14 - create mode 100644 target/linux/generic/hack-4.14/204-module_strip.patch - create mode 100644 target/linux/generic/hack-4.14/207-disable-modorder.patch - create mode 100644 target/linux/generic/hack-4.14/210-darwin_scripts_include.patch - create mode 100644 target/linux/generic/hack-4.14/211-host_tools_portability.patch - create mode 100644 target/linux/generic/hack-4.14/212-byteshift_portability.patch - create mode 100644 target/linux/generic/hack-4.14/214-spidev_h_portability.patch - create mode 100644 target/linux/generic/hack-4.14/220-gc_sections.patch - create mode 100644 target/linux/generic/hack-4.14/221-module_exports.patch - create mode 100644 target/linux/generic/hack-4.14/230-openwrt_lzma_options.patch - create mode 100644 target/linux/generic/hack-4.14/250-netfilter_depends.patch - create mode 100644 target/linux/generic/hack-4.14/251-sound_kconfig.patch - create mode 100644 target/linux/generic/hack-4.14/259-regmap_dynamic.patch - create mode 100644 target/linux/generic/hack-4.14/260-crypto_test_dependencies.patch - create mode 100644 target/linux/generic/hack-4.14/280-rfkill-stubs.patch - create mode 100644 target/linux/generic/hack-4.14/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch - create mode 100644 target/linux/generic/hack-4.14/301-mips_image_cmdline_hack.patch - create mode 100644 target/linux/generic/hack-4.14/321-powerpc_crtsavres_prereq.patch - create mode 100644 target/linux/generic/hack-4.14/400-mt29f_spinand-fix-memleak.patch - create mode 100644 target/linux/generic/hack-4.14/531-debloat_lzma.patch - create mode 100644 target/linux/generic/hack-4.14/640-bridge-only-accept-EAP-locally.patch - create mode 100644 target/linux/generic/hack-4.14/645-netfilter-connmark-introduce-set-dscpmark.patch - create mode 100644 target/linux/generic/hack-4.14/647-netfilter-flow-acct.patch - create mode 100644 target/linux/generic/hack-4.14/650-netfilter-add-xt_OFFLOAD-target.patch - create mode 100644 target/linux/generic/hack-4.14/651-wireless_mesh_header.patch - create mode 100644 target/linux/generic/hack-4.14/660-fq_codel_defaults.patch - create mode 100644 target/linux/generic/hack-4.14/661-use_fq_codel_by_default.patch - create mode 100644 target/linux/generic/hack-4.14/662-remove_pfifo_fast.patch - create mode 100644 target/linux/generic/hack-4.14/700-swconfig_switch_drivers.patch - create mode 100644 target/linux/generic/hack-4.14/702-phy_add_aneg_done_function.patch - create mode 100644 target/linux/generic/hack-4.14/721-phy_packets.patch - create mode 100644 target/linux/generic/hack-4.14/773-bgmac-add-srab-switch.patch - create mode 100644 target/linux/generic/hack-4.14/901-debloat_sock_diag.patch - create mode 100644 target/linux/generic/hack-4.14/902-debloat_proc.patch - create mode 100644 target/linux/generic/hack-4.14/904-debloat_dma_buf.patch - create mode 100644 target/linux/generic/hack-4.14/910-kobject_uevent.patch - create mode 100644 target/linux/generic/hack-4.14/911-kobject_add_broadcast_uevent.patch - create mode 100644 target/linux/generic/hack-4.14/921-always-create-console-node-in-initramfs.patch - create mode 100644 target/linux/generic/hack-4.14/930-crashlog.patch - create mode 100644 target/linux/generic/pending-4.14/0931-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch - create mode 100644 target/linux/generic/pending-4.14/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch - create mode 100644 target/linux/generic/pending-4.14/103-MIPS-perf-ath79-Fix-perfcount-IRQ-assignment.patch - create mode 100644 target/linux/generic/pending-4.14/110-ehci_hcd_ignore_oc.patch - create mode 100644 target/linux/generic/pending-4.14/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch - create mode 100644 target/linux/generic/pending-4.14/130-add-linux-spidev-compatible-si3210.patch - create mode 100644 target/linux/generic/pending-4.14/131-spi-use-gpio_set_value_cansleep-for-setting-chipsele.patch - create mode 100644 target/linux/generic/pending-4.14/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch - create mode 100644 target/linux/generic/pending-4.14/141-jffs2-add-RENAME_EXCHANGE-support.patch - create mode 100644 target/linux/generic/pending-4.14/150-bridge_allow_receiption_on_disabled_port.patch - create mode 100644 target/linux/generic/pending-4.14/161-mtd-part-add-generic-parsing-of-linux-part-probe.patch - create mode 100644 target/linux/generic/pending-4.14/171-usb-dwc2-Fix-inefficient-copy-of-unaligned-buffers.patch - create mode 100644 target/linux/generic/pending-4.14/180-net-phy-at803x-add-support-for-AT8032.patch - create mode 100644 target/linux/generic/pending-4.14/190-2-5-e1000e-Fix-wrong-comment-related-to-link-detection.patch - create mode 100644 target/linux/generic/pending-4.14/201-extra_optimization.patch - create mode 100644 target/linux/generic/pending-4.14/203-kallsyms_uncompressed.patch - create mode 100644 target/linux/generic/pending-4.14/205-backtrace_module_info.patch - create mode 100644 target/linux/generic/pending-4.14/220-optimize_inlining.patch - create mode 100644 target/linux/generic/pending-4.14/240-remove-unsane-filenames-from-deps_initramfs-list.patch - create mode 100644 target/linux/generic/pending-4.14/261-enable_wilink_platform_without_drivers.patch - create mode 100644 target/linux/generic/pending-4.14/270-platform-mikrotik-build-bits.patch - create mode 100644 target/linux/generic/pending-4.14/300-mips_expose_boot_raw.patch - create mode 100644 target/linux/generic/pending-4.14/302-mips_no_branch_likely.patch - create mode 100644 target/linux/generic/pending-4.14/304-mips_disable_fpu.patch - create mode 100644 target/linux/generic/pending-4.14/305-mips_module_reloc.patch - create mode 100644 target/linux/generic/pending-4.14/306-mips_mem_functions_performance.patch - create mode 100644 target/linux/generic/pending-4.14/307-mips_highmem_offset.patch - create mode 100644 target/linux/generic/pending-4.14/308-mips32r2_tune.patch - create mode 100644 target/linux/generic/pending-4.14/309-MIPS-Add-CPU-option-reporting-to-proc-cpuinfo.patch - create mode 100644 target/linux/generic/pending-4.14/310-arm_module_unresolved_weak_sym.patch - create mode 100644 target/linux/generic/pending-4.14/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch - create mode 100644 target/linux/generic/pending-4.14/332-arc-add-OWRTDTB-section.patch - create mode 100644 target/linux/generic/pending-4.14/333-arc-enable-unaligned-access-in-kernel-mode.patch - create mode 100644 target/linux/generic/pending-4.14/340-MIPS-mm-remove-mips_dma_mapping_error.patch - create mode 100644 target/linux/generic/pending-4.14/341-MIPS-mm-remove-no-op-dma_map_ops-where-possible.patch - create mode 100644 target/linux/generic/pending-4.14/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch - create mode 100644 target/linux/generic/pending-4.14/400-mtd-add-rootfs-split-support.patch - create mode 100644 target/linux/generic/pending-4.14/401-mtd-add-support-for-different-partition-parser-types.patch - create mode 100644 target/linux/generic/pending-4.14/402-mtd-use-typed-mtd-parsers-for-rootfs-and-firmware-split.patch - create mode 100644 target/linux/generic/pending-4.14/403-mtd-hook-mtdsplit-to-Kbuild.patch - create mode 100644 target/linux/generic/pending-4.14/404-mtd-add-more-helper-functions.patch - create mode 100644 target/linux/generic/pending-4.14/411-mtd-partial_eraseblock_write.patch - create mode 100644 target/linux/generic/pending-4.14/412-mtd-partial_eraseblock_unlock.patch - create mode 100644 target/linux/generic/pending-4.14/419-mtd-redboot-add-of_match_table-with-DT-binding.patch - create mode 100644 target/linux/generic/pending-4.14/420-mtd-redboot_space.patch - create mode 100644 target/linux/generic/pending-4.14/430-mtd-add-myloader-partition-parser.patch - create mode 100644 target/linux/generic/pending-4.14/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch - create mode 100644 target/linux/generic/pending-4.14/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch - create mode 100644 target/linux/generic/pending-4.14/435-mtd-add-routerbootpart-parser-config.patch - create mode 100644 target/linux/generic/pending-4.14/440-block2mtd_init.patch - create mode 100644 target/linux/generic/pending-4.14/441-block2mtd_probe.patch - create mode 100644 target/linux/generic/pending-4.14/450-mtd-m25p80-allow-fallback-from-spi_flash_read-to-reg.patch - create mode 100644 target/linux/generic/pending-4.14/450-mtd-spi-nor-allow-NOR-driver-to-write-fewer-bytes-th.patch - create mode 100644 target/linux/generic/pending-4.14/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch - create mode 100644 target/linux/generic/pending-4.14/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch - create mode 100644 target/linux/generic/pending-4.14/465-m25p80-mx-disable-software-protection.patch - create mode 100644 target/linux/generic/pending-4.14/466-Revert-mtd-spi-nor-fix-Spansion-regressions-aliased-.patch - create mode 100644 target/linux/generic/pending-4.14/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch - create mode 100644 target/linux/generic/pending-4.14/475-mtd-spi-nor-Add-Winbond-w25q128jv-support.patch - create mode 100644 target/linux/generic/pending-4.14/476-mtd-spi-nor-add-eon-en25q128.patch - create mode 100644 target/linux/generic/pending-4.14/477-mtd-add-spi-nor-add-mx25u3235f.patch - create mode 100644 target/linux/generic/pending-4.14/478-mtd-spi-nor-Add-support-for-XM25QH64A-and-XM25QH128A.patch - create mode 100644 target/linux/generic/pending-4.14/479-mtd-spi-nor-add-eon-en25qh32.patch - create mode 100644 target/linux/generic/pending-4.14/479-mtd-spi-nor-add-eon-en25qh64.patch - create mode 100644 target/linux/generic/pending-4.14/479-mtd-spi-nor-add-xtx-xt25f128b.patch - create mode 100644 target/linux/generic/pending-4.14/480-mtd-set-rootfs-to-be-root-dev.patch - create mode 100644 target/linux/generic/pending-4.14/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch - create mode 100644 target/linux/generic/pending-4.14/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch - create mode 100644 target/linux/generic/pending-4.14/491-ubi-auto-create-ubiblock-device-for-rootfs.patch - create mode 100644 target/linux/generic/pending-4.14/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch - create mode 100644 target/linux/generic/pending-4.14/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch - create mode 100644 target/linux/generic/pending-4.14/494-mtd-ubi-add-EOF-marker-support.patch - create mode 100644 target/linux/generic/pending-4.14/495-mtd-core-add-get_mtd_device_by_node.patch - create mode 100644 target/linux/generic/pending-4.14/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch - create mode 100644 target/linux/generic/pending-4.14/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch - create mode 100644 target/linux/generic/pending-4.14/530-jffs2_make_lzma_available.patch - create mode 100644 target/linux/generic/pending-4.14/532-jffs2_eofdetect.patch - create mode 100644 target/linux/generic/pending-4.14/600-netfilter_conntrack_flush.patch - create mode 100644 target/linux/generic/pending-4.14/610-netfilter_match_bypass_default_checks.patch - create mode 100644 target/linux/generic/pending-4.14/611-netfilter_match_bypass_default_table.patch - create mode 100644 target/linux/generic/pending-4.14/612-netfilter_match_reduce_memory_access.patch - create mode 100644 target/linux/generic/pending-4.14/613-netfilter_optional_tcp_window_check.patch - create mode 100644 target/linux/generic/pending-4.14/620-net_sched-codel-do-not-defer-queue-length-update.patch - create mode 100644 target/linux/generic/pending-4.14/630-packet_socket_type.patch - create mode 100644 target/linux/generic/pending-4.14/640-netfilter-nf_flow_table-add-hardware-offload-support.patch - create mode 100644 target/linux/generic/pending-4.14/641-netfilter-nf_flow_table-support-hw-offload-through-v.patch - create mode 100644 target/linux/generic/pending-4.14/642-net-8021q-support-hardware-flow-table-offload.patch - create mode 100644 target/linux/generic/pending-4.14/643-net-bridge-support-hardware-flow-table-offload.patch - create mode 100644 target/linux/generic/pending-4.14/644-net-pppoe-support-hardware-flow-table-offload.patch - create mode 100644 target/linux/generic/pending-4.14/645-netfilter-nf_flow_table-rework-hardware-offload-time.patch - create mode 100644 target/linux/generic/pending-4.14/646-netfilter-nf_flow_table-rework-private-driver-data.patch - create mode 100644 target/linux/generic/pending-4.14/655-increase_skb_pad.patch - create mode 100644 target/linux/generic/pending-4.14/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch - create mode 100644 target/linux/generic/pending-4.14/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch - create mode 100644 target/linux/generic/pending-4.14/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch - create mode 100644 target/linux/generic/pending-4.14/680-NET-skip-GRO-for-foreign-MAC-addresses.patch - create mode 100644 target/linux/generic/pending-4.14/681-NET-add-of_get_mac_address_mtd.patch - create mode 100644 target/linux/generic/pending-4.14/690-net-add-support-for-threaded-NAPI-polling.patch - create mode 100644 target/linux/generic/pending-4.14/703-phy-add-detach-callback-to-struct-phy_driver.patch - create mode 100644 target/linux/generic/pending-4.14/734-net-phy-at803x-allow-to-configure-via-pdata.patch - create mode 100644 target/linux/generic/pending-4.14/735-net-phy-at803x-fix-at8033-sgmii-mode.patch - create mode 100644 target/linux/generic/pending-4.14/810-pci_disable_common_quirks.patch - create mode 100644 target/linux/generic/pending-4.14/811-pci_disable_usb_common_quirks.patch - create mode 100644 target/linux/generic/pending-4.14/834-ledtrig-libata.patch - create mode 100644 target/linux/generic/pending-4.14/920-mangle_bootargs.patch - -diff --git a/config/Config-images.in b/config/Config-images.in -index 2921cd5bca..b869ccae70 100644 ---- a/config/Config-images.in -+++ b/config/Config-images.in -@@ -13,6 +13,7 @@ menu "Target Images" - choice - prompt "Compression" - default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_apm821xx -+ default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_ar71xx - default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_ath79_mikrotik - default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_lantiq - default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_mpc85xx -diff --git a/package/kernel/linux/modules/usb.mk b/package/kernel/linux/modules/usb.mk -index 4191590ba7..592affe494 100644 ---- a/package/kernel/linux/modules/usb.mk -+++ b/package/kernel/linux/modules/usb.mk -@@ -1590,7 +1590,7 @@ $(eval $(call KernelPackage,usbip-server)) - - define KernelPackage/usb-chipidea - TITLE:=Host and device support for Chipidea controllers -- DEPENDS:=+USB_GADGET_SUPPORT:kmod-usb-gadget @TARGET_ath79 +kmod-usb-ehci +kmod-usb-phy-nop -+ DEPENDS:=+USB_GADGET_SUPPORT:kmod-usb-gadget @TARGET_ar71xx||TARGET_ath79 +kmod-usb-ehci +kmod-usb-phy-nop - KCONFIG:= \ - CONFIG_EXTCON \ - CONFIG_USB_CHIPIDEA \ -diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk -index 24abb910ff..f209c95ba8 100644 ---- a/package/kernel/mac80211/ath.mk -+++ b/package/kernel/mac80211/ath.mk -@@ -42,6 +42,7 @@ config-$(CONFIG_PACKAGE_ATH_DYNACK) += ATH9K_DYNACK - config-$(call config_package,ath9k) += ATH9K - config-$(call config_package,ath9k-common) += ATH9K_COMMON - config-$(call config_package,owl-loader) += ATH9K_PCI_NO_EEPROM -+config-$(CONFIG_TARGET_ar71xx) += ATH9K_AHB - config-$(CONFIG_TARGET_ath79) += ATH9K_AHB - config-$(CONFIG_TARGET_ipq40xx) += ATH10K_AHB - config-$(CONFIG_PCI) += ATH9K_PCI -@@ -125,7 +126,7 @@ endef - define KernelPackage/ath - $(call KernelPackage/mac80211/Default) - TITLE:=Atheros common driver part -- DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ath79||TARGET_ath25 +kmod-mac80211 -+ DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ar71xx||TARGET_ath79||TARGET_ath25 +kmod-mac80211 - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath.ko - MENU:=1 - endef -@@ -190,7 +191,7 @@ define KernelPackage/ath9k-common - TITLE:=Atheros 802.11n wireless devices (common code for ath9k and ath9k_htc) - URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k - HIDDEN:=1 -- DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ath79 +kmod-ath +@DRIVER_11N_SUPPORT -+ DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ar71xx||TARGET_ath79 +kmod-ath +@DRIVER_11N_SUPPORT - FILES:= \ - $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_common.ko \ - $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_hw.ko -@@ -200,7 +201,7 @@ define KernelPackage/ath9k - $(call KernelPackage/mac80211/Default) - TITLE:=Atheros 802.11n PCI wireless cards support - URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k -- DEPENDS+= @PCI_SUPPORT||TARGET_ath79 +kmod-ath9k-common -+ DEPENDS+= @PCI_SUPPORT||TARGET_ar71xx||TARGET_ath79 +kmod-ath9k-common - FILES:= \ - $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k.ko - AUTOLOAD:=$(call AutoProbe,ath9k) -@@ -230,7 +231,7 @@ define KernelPackage/ath9k/config - - config ATH9K_UBNTHSR - bool "Support for Ubiquiti UniFi Outdoor+ access point" -- depends on PACKAGE_kmod-ath9k && TARGET_ath79 -+ depends on PACKAGE_kmod-ath9k && (TARGET_ar71xx_generic||TARGET_ath79) - default y - - endef -diff --git a/target/linux/ar71xx/Makefile b/target/linux/ar71xx/Makefile -new file mode 100644 -index 0000000000..aa53b49735 ---- /dev/null -+++ b/target/linux/ar71xx/Makefile -@@ -0,0 +1,24 @@ -+# -+# Copyright (C) 2008-2011 OpenWrt.org -+# -+# This is free software, licensed under the GNU General Public License v2. -+# See /LICENSE for more information. -+# -+include $(TOPDIR)/rules.mk -+ -+ARCH:=mips -+BOARD:=ar71xx -+BOARDNAME:=Atheros AR7xxx/AR9xxx -+FEATURES:=usbgadget source-only -+CPU_TYPE:=24kc -+SUBTARGETS:=generic tiny nand mikrotik -+ -+KERNEL_PATCHVER:=4.14 -+ -+include $(INCLUDE_DIR)/target.mk -+ -+DEFAULT_PACKAGES += \ -+ kmod-gpio-button-hotplug swconfig \ -+ kmod-ath9k uboot-envtools -+ -+$(eval $(call BuildTarget)) -diff --git a/target/linux/ar71xx/base-files/etc/board.d/01_leds b/target/linux/ar71xx/base-files/etc/board.d/01_leds -new file mode 100755 -index 0000000000..54727a6e52 ---- /dev/null -+++ b/target/linux/ar71xx/base-files/etc/board.d/01_leds -@@ -0,0 +1,1130 @@ -+#!/bin/sh -+# -+# Copyright (C) 2011 OpenWrt.org -+# -+ -+. /lib/functions/uci-defaults.sh -+ -+board_config_update -+ -+board=$(board_name) -+ -+case "$board" in -+a40) -+ ucidef_set_led_default "status-red" "Status (red)" "a40:red:status" "0" -+ ucidef_set_led_default "status-blue" "Status (blue)" "a40:blue:status" "0" -+ ;; -+a60) -+ ucidef_set_led_default "status-red" "Status (red)" "a60:red:status" "0" -+ ucidef_set_led_default "status-blue" "Status (blue)" "a60:blue:status" "0" -+ ;; -+airgateway|\ -+airgatewaypro) -+ ucidef_set_led_wlan "wlan" "WLAN" "ubnt:blue:wlan" "phy0tpt" -+ ;; -+alfa-nx) -+ ucidef_set_led_netdev "wan" "WAN" "alfa:green:led_2" "eth0" -+ ucidef_set_led_netdev "lan" "LAN" "alfa:green:led_3" "eth1" -+ ;; -+all0258n|\ -+all0315n) -+ ucidef_set_rssimon "wlan0" "200000" "1" -+ ucidef_set_led_rssi "rssilow" "RSSILOW" "$board:red:rssilow" "wlan0" "1" "40" "0" "6" -+ ucidef_set_led_rssi "rssimedium" "RSSIMEDIUM" "$board:yellow:rssimedium" "wlan0" "30" "80" "-29" "5" -+ ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "$board:green:rssihigh" "wlan0" "70" "100" "-69" "8" -+ ;; -+antminer-s1|\ -+antminer-s3) -+ ucidef_set_led_default "sys" "SYS" "$board:green:sys" "0" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan" "phy0tpt" -+ -+ case "$board" in -+ antminer-s3) -+ ucidef_set_led_default "lan" "LAN" "$board:yellow:lan" "0" -+ ;; -+ esac -+ ;; -+antrouter-r1) -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan" "phy0tpt" -+ ucidef_set_led_default "btc" "BTC" "$board:green:btc" "0" -+ ;; -+ap121f) -+ ucidef_set_led_netdev "lan" "LAN" "$board:green:lan" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan" "phy0tpt" -+ ;; -+ap147-010) -+ ucidef_set_led_netdev "wan" "WAN" "ap147:green:wan" "eth1" -+ ucidef_set_led_switch "lan1" "LAN1" "ap147:green:lan1" "switch0" "0x10" -+ ucidef_set_led_switch "lan2" "LAN2" "ap147:green:lan2" "switch0" "0x08" -+ ucidef_set_led_switch "lan3" "LAN3" "ap147:green:lan3" "switch0" "0x04" -+ ucidef_set_led_switch "lan4" "LAN4" "ap147:green:lan4" "switch0" "0x02" -+ ucidef_set_led_wlan "wlan2g" "WLAN 2.4 GHz" "ap147:green:wlan-2g" "phy0tpt" -+ ;; -+ap90q|\ -+cpe505n|\ -+cpe830|\ -+cpe870|\ -+dr531|\ -+e600g-v2|\ -+e600gac-v2|\ -+e750a-v4) -+ ucidef_set_led_netdev "lan" "LAN" "$board:green:lan" "eth0" -+ ucidef_set_led_netdev "wan" "WAN" "$board:green:wan" "eth1" -+ -+ case "$board" in -+ ap90q) -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan" "phy0tpt" -+ ;; -+ cpe505n) -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:blue:wlan" "phy0tpt" -+ ;; -+ cpe830|\ -+ cpe870) -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan" "phy0tpt" -+ ucidef_set_rssimon "wlan0" "200000" "1" -+ ucidef_set_led_rssi "rssilow" "RSSILOW" "$board:green:link1" "wlan0" "1" "100" "0" "13" -+ ucidef_set_led_rssi "rssimediumlow" "RSSIMEDIUMLOW" "$board:green:link2" "wlan0" "26" "100" "-25" "13" -+ ucidef_set_led_rssi "rssimediumhigh" "RSSIMEDIUMHIGH" "$board:green:link3" "wlan0" "51" "100" "-50" "13" -+ ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "$board:green:link4" "wlan0" "76" "100" "-75" "13" -+ ;; -+ esac -+ ;; -+ap531b0|\ -+gl-usb150|\ -+sc1750|\ -+sc450) -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan" "phy0tpt" -+ ;; -+ap91-5g|\ -+n5q) -+ ucidef_set_led_netdev "lan" "LAN" "$board:green:lan" "eth0" -+ ucidef_set_rssimon "wlan0" "200000" "1" -+ ucidef_set_led_rssi "signal1" "SIGNAL1" "$board:red:signal1" "wlan0" "1" "100" -+ ucidef_set_led_rssi "signal2" "SIGNAL2" "$board:orange:signal2" "wlan0" "25" "100" -+ ucidef_set_led_rssi "signal3" "SIGNAL3" "$board:green:signal3" "wlan0" "50" "100" -+ ucidef_set_led_rssi "signal4" "SIGNAL4" "$board:green:signal4" "wlan0" "75" "100" -+ -+ case "$board" in -+ n5q) -+ ucidef_set_led_netdev "wan" "WAN" "$board:green:wan" "eth1" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan" "phy0tpt" -+ ;; -+ esac -+ ;; -+archer-c25-v1) -+ ucidef_set_led_netdev "wan" "WAN" "$board:green:wan" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan2g" "phy1tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN5G" "$board:green:wlan5g" "phy0tpt" -+ ucidef_set_led_switch "lan1" "LAN1" "$board:green:lan1" "switch0" "0x10" -+ ucidef_set_led_switch "lan2" "LAN2" "$board:green:lan2" "switch0" "0x08" -+ ucidef_set_led_switch "lan3" "LAN3" "$board:green:lan3" "switch0" "0x04" -+ ucidef_set_led_switch "lan4" "LAN4" "$board:green:lan4" "switch0" "0x02" -+ ;; -+archer-c5|\ -+archer-c7) -+ ucidef_set_led_usbport "usb1" "USB1" "tp-link:green:usb1" "usb1-port1" -+ ucidef_set_led_usbport "usb2" "USB2" "tp-link:green:usb2" "usb2-port1" -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "tp-link:green:wlan2g" "phy1tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN5G" "tp-link:green:wlan5g" "phy0tpt" -+ ;; -+archer-c58-v1|\ -+archer-c59-v1|\ -+archer-c59-v2|\ -+archer-c60-v1|\ -+archer-c60-v2) -+ ucidef_set_led_switch "lan" "LAN" "$board:green:lan" "switch0" "0x1E" -+ ucidef_set_led_netdev "wan" "WAN" "$board:green:wan" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan2g" "phy1tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN5G" "$board:green:wlan5g" "phy0tpt" -+ -+ case "$board" in -+ archer-c59-v1|\ -+ archer-c59-v2) -+ ucidef_set_led_usbport "usb" "USB" "$board:green:usb" "usb1-port1" -+ ;; -+ esac -+ ;; -+archer-c7-v4|\ -+archer-c7-v5) -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan2g" "phy1tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN5G" "$board:green:wlan5g" "phy0tpt" -+ ucidef_set_led_switch "wan" "WAN" "$board:green:wan" "switch0" "0x02" -+ ucidef_set_led_switch "lan1" "LAN1" "$board:green:lan4" "switch0" "0x04" -+ ucidef_set_led_switch "lan2" "LAN2" "$board:green:lan3" "switch0" "0x08" -+ ucidef_set_led_switch "lan3" "LAN3" "$board:green:lan2" "switch0" "0x10" -+ ucidef_set_led_switch "lan4" "LAN4" "$board:green:lan1" "switch0" "0x20" -+ -+ case "$board" in -+ archer-c7-v4) -+ ucidef_set_led_usbport "usb1" "USB1" "$board:green:usb1" "usb1-port1" -+ ucidef_set_led_usbport "usb2" "USB2" "$board:green:usb2" "usb2-port1" -+ ;; -+ esac -+ -+ case "$board" in -+ archer-c7-v5) -+ ucidef_set_led_usbport "usb" "USB" "$board:green:usb" "usb1-port1" -+ ;; -+ esac -+ ;; -+arduino-yun) -+ ucidef_set_led_wlan "wlan" "WLAN" "arduino:blue:wlan" "phy0tpt" -+ ucidef_set_led_usbport "usb" "USB" "arduino:white:usb" "1-1-port1" -+ ;; -+bhr-4grv2) -+ ucidef_set_led_default "power" "POWER" "buffalo:green:power" "1" -+ ucidef_set_led_default "diag" "DIAG" "buffalo:red:diag" "0" -+ ;; -+bsb) -+ ucidef_set_led_default "sys" "SYS" "$board:red:sys" "1" -+ ;; -+bullet-m|\ -+bullet-m-xw|\ -+loco-m-xw|\ -+nanostation-m|\ -+nanostation-m-xw|\ -+rocket-m|\ -+rocket-m-xw) -+ ucidef_set_rssimon "wlan0" "200000" "1" -+ ucidef_set_led_rssi "rssilow" "RSSILOW" "ubnt:red:link1" "wlan0" "1" "100" -+ ucidef_set_led_rssi "rssimediumlow" "RSSIMEDIUMLOW" "ubnt:orange:link2" "wlan0" "26" "100" -+ ucidef_set_led_rssi "rssimediumhigh" "RSSIMEDIUMHIGH" "ubnt:green:link3" "wlan0" "51" "100" -+ ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "ubnt:green:link4" "wlan0" "76" "100" -+ ;; -+bxu2000n-2-a1) -+ ucidef_set_led_wlan "wlan" "WLAN" "bhu:green:wlan" "phy0tpt" -+ ;; -+cap324) -+ ucidef_set_led_netdev "lan" "LAN" "pcs:green:lan" "eth0" -+ ucidef_set_led_wlan "wlan_amber" "WLAN_AMBER" "pcs:amber:wlan" "phy0tpt" -+ ucidef_set_led_wlan "wlan_green" "WLAN_GREEN" "pcs:green:wlan" "phy1tpt" -+ ;; -+c-55) -+ ucidef_set_led_netdev "lan_green" "LAN_GREEN" "$board:green:lan" "eth0" -+ ucidef_set_led_wlan "wlan_amber" "WLAN_AMBER" "$board:amber:wlan" "phy0tpt" -+ ucidef_set_led_wlan "wlan_green" "WLAN_GREEN" "$board:green:wlan" "phy1tpt" -+ ;; -+c-60) -+ ucidef_set_led_wlan "wlan1_green" "WLAN1_GREEN" "$board:green:wlan1" "phy0tpt" -+ ucidef_set_led_wlan "wlan2_green" "WLAN2_GREEN" "$board:green:wlan2" "phy1tpt" -+ ;; -+cap4200ag) -+ ucidef_set_led_default "lan_green" "LAN_GREEN" "senao:green:lan" "1" -+ ucidef_set_led_wlan "wlan_amber" "WLAN_AMBER" "senao:amber:wlan" "phy0tpt" -+ ucidef_set_led_wlan "wlan_green" "WLAN_GREEN" "senao:green:wlan" "phy1tpt" -+ ;; -+carambola2) -+ ucidef_set_led_netdev "lan" "LAN" "$board:orange:eth0" "eth0" -+ ucidef_set_led_netdev "wan" "WAN" "$board:orange:eth1" "eth1" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan" "phy0tpt" -+ ;; -+cf-e316n-v2) -+ ucidef_set_led_netdev "lan" "LAN" "$board:blue:lan" "eth0" -+ ucidef_set_led_netdev "wan" "WAN" "$board:blue:wan" "eth1" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:blue:wlan" "phy0tpt" -+ ;; -+cf-e320n-v2) -+ ucidef_set_led_netdev "lan" "LAN" "$board:green:lan" "eth0" -+ ucidef_set_led_netdev "wan" "WAN" "$board:red:wan" "eth1" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:blue:wlan" "phy0tpt" -+ ;; -+cf-e355ac-v1|\ -+cf-e355ac-v2|\ -+cf-e375ac|\ -+cf-e380ac-v1|\ -+cf-e380ac-v2|\ -+cf-e385ac) -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "$board:blue:wlan2g" "phy1tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN5G" "$board:red:wlan5g" "phy0tpt" -+ -+ case "$board" in -+ cf-e375ac|\ -+ cf-e385ac) -+ ucidef_set_led_switch "lan" "LAN" "$board:green:lan" "switch0" "0x04" -+ ;; -+ *) -+ ucidef_set_led_netdev "lan" "LAN" "$board:green:lan" "eth0" -+ ;; -+ esac -+ ;; -+cf-e520n|\ -+cf-e530n) -+ ucidef_set_led_netdev "wan" "WAN" "$board:blue:wan" "eth1" -+ ;; -+cpe210|\ -+cpe210-v2|\ -+cpe210-v3|\ -+cpe510|\ -+cpe510-v2|\ -+wbs210|\ -+wbs510) -+ ucidef_set_rssimon "wlan0" "200000" "1" -+ ucidef_set_led_rssi "rssilow" "RSSILOW" "tp-link:green:link1" "wlan0" "1" "100" "0" "13" -+ ucidef_set_led_rssi "rssimediumlow" "RSSIMEDIUMLOW" "tp-link:green:link2" "wlan0" "26" "100" "-25" "13" -+ ucidef_set_led_rssi "rssimediumhigh" "RSSIMEDIUMHIGH" "tp-link:green:link3" "wlan0" "51" "100" "-50" "13" -+ ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "tp-link:green:link4" "wlan0" "76" "100" "-75" "13" -+ -+ case "$board" in -+ cpe210-v2|\ -+ cpe210-v3|\ -+ cpe510-v2) -+ ucidef_set_led_netdev "lan" "LAN" "tp-link:green:lan0" "eth0" -+ ;; -+ *) -+ ucidef_set_led_switch "lan0" "LAN0" "tp-link:green:lan0" "switch0" "0x20" -+ ucidef_set_led_switch "lan1" "LAN1" "tp-link:green:lan1" "switch0" "0x10" -+ ;; -+ esac -+ ;; -+cr3000) -+ ucidef_set_led_netdev "wan" "WAN" "pcs:blue:wan" "eth1" -+ ucidef_set_led_switch "lan1" "LAN1" "pcs:blue:lan1" "switch0" "0x04" -+ ucidef_set_led_switch "lan2" "LAN2" "pcs:blue:lan2" "switch0" "0x08" -+ ucidef_set_led_switch "lan3" "LAN3" "pcs:blue:lan3" "switch0" "0x10" -+ ucidef_set_led_switch "lan4" "LAN4" "pcs:blue:lan4" "switch0" "0x02" -+ ucidef_set_led_wlan "wlan" "WLAN" "pcs:blue:wlan" "phy0tpt" -+ ;; -+cr5000) -+ ucidef_set_led_wlan "wlan" "WLAN" "pcs:blue:wlan" "phy0tpt" -+ ucidef_set_led_usbport "usb" "USB" "pcs:white:wps" "usb1-port1" -+ ;; -+db120) -+ ucidef_set_led_usbport "usb" "USB" "$board:green:usb" "usb1-port1" -+ ;; -+dr344) -+ ucidef_set_led_netdev "lan" "LAN" "$board:green:lan" "eth1" -+ ;; -+dragino2) -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:red:wlan" "phy0tpt" -+ ucidef_set_led_netdev "lan" "LAN" "$board:red:lan" "eth0" -+ ucidef_set_led_netdev "wan" "WAN" "$board:red:wan" "eth1" -+ ;; -+dw33d) -+ ucidef_set_led_usbport "mmc" "MMC" "$board:blue:mmc" "usb1-port1" -+ ucidef_set_led_usbport "usb" "USB" "$board:blue:usb" "usb2-port1" -+ ucidef_set_led_netdev "internet" "INTERNET" "$board:blue:internet" "eth0" -+ ucidef_set_led_wlan "wlan2g" "WLAN-2.4G" "$board:blue:wlan-2g" "phy1tpt" -+ ;; -+eap300v2) -+ ucidef_set_led_netdev "lan" "LAN" "engenius:blue:lan" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "engenius:blue:wlan" "phy0tpt" -+ ;; -+ens202ext) -+ ucidef_set_rssimon "wlan0" "200000" "1" -+ ucidef_set_led_rssi "rssilow" "RSSILOW" "engenius:amber:wlan1" "wlan0" "1" "100" "0" "13" -+ ucidef_set_led_rssi "rssimedium" "RSSIMEDIUM" "engenius:red:wlan2" "wlan0" "25" "100" "-39" "13" -+ ucidef_set_led_rssi "rssimediumhigh" "RSSIMEDIUMHIGH" "engenius:amber:wlan3" "wlan0" "50" "100" "-59" "13" -+ ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "engenius:green:wlan4" "wlan0" "75" "100" "-79" "13" -+ ;; -+f9k1115v2) -+ ucidef_set_led_usbport "usb2" "USB2" "belkin:green:usb2" "usb1-port1" -+ ;; -+fritz300e) -+ ucidef_set_led_netdev "lan" "LAN" "$board:green:lan" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan" "phy0tpt" -+ ucidef_set_rssimon "wlan0" "200000" "1" -+ ucidef_set_led_rssi "rssilow" "RSSILOW" "$board:green:rssi0" "wlan0" "1" "100" -+ ucidef_set_led_rssi "rssimediumlow" "RSSIMEDIUMLOW" "$board:green:rssi1" "wlan0" "20" "100" -+ ucidef_set_led_rssi "rssimedium" "RSSIMEDIUM" "$board:green:rssi2" "wlan0" "40" "100" -+ ucidef_set_led_rssi "rssimediumhigh" "RSSIMEDIUMHIGH" "$board:green:rssi3" "wlan0" "60" "100" -+ ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "$board:green:rssi4" "wlan0" "80" "100" -+ ;; -+dap-1330-a1) -+ ucidef_set_rssimon "wlan0" "2000000" "2" -+ ucidef_set_led_rssi "wifi-low" "wifi-low" "d-link:red:wifi" "wlan0" "1" "29" -+ ucidef_set_led_rssi "wifi-medium" "wifi-medium" "d-link:green:wifi" "wlan0" "30" "100" -+ ucidef_set_led_rssi "wifi-high" "wifi-high" "d-link:green:signal1" "wlan0" "50" "100" -+ ucidef_set_led_rssi "wifi-max" "wifi-max" "d-link:green:signal2" "wlan0" "70" "100" -+ ;; -+dap-2695-a1) -+ ucidef_set_led_default "power" "POWER" "d-link:green:power" "1" -+ ucidef_set_led_default "diag" "DIAG" "d-link:red:power" "0" -+ ucidef_set_led_wlan "wlan2g" "WLAN 2.4 GHz" "d-link:green:wlan2g" "phy1tpt" -+ ;; -+dhp-1565-a1) -+ ucidef_set_led_switch "wan" "WAN" "d-link:green:planet" "switch0" "0x20" -+ ;; -+dir-600-a1|\ -+dir-615-e1|\ -+dir-615-e4|\ -+ebr-2310-c1) -+ ucidef_set_led_netdev "wan" "WAN" "d-link:green:wan" "eth1" -+ ucidef_set_led_switch "lan1" "LAN1" "d-link:green:lan1" "switch0" "0x02" -+ ucidef_set_led_switch "lan2" "LAN2" "d-link:green:lan2" "switch0" "0x04" -+ ucidef_set_led_switch "lan3" "LAN3" "d-link:green:lan3" "switch0" "0x08" -+ ucidef_set_led_switch "lan4" "LAN4" "d-link:green:lan4" "switch0" "0x10" -+ ;; -+dir-615-c1) -+ ucidef_set_led_netdev "wan" "WAN" "d-link:green:wan" "eth1" -+ ucidef_set_led_wlan "wlan" "WLAN" "d-link:green:wlan" "phy0tpt" -+ ;; -+dir-825-b1|\ -+dir-825-c1) -+ ucidef_set_led_usbport "usb" "USB" "d-link:blue:usb" "usb1-port1" -+ -+ case "$board" in -+ dir-825-c1) -+ ucidef_set_led_wlan "wlan2g" "WLAN 2.4 GHz" "d-link:blue:wlan2g" "phy0tpt" -+ ;; -+ esac -+ ;; -+dir-615-i1) -+ ucidef_set_led_default "power" "POWER" "d-link:green:power" "1" -+ ucidef_set_led_default "diag" "DIAG" "d-link:amber:power" "0" -+ ucidef_set_led_default "wps" "WPS" "d-link:blue:wps" "0" -+ ucidef_set_led_netdev "wan" "WAN" "d-link:green:wan" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "d-link:green:wlan" "phy0tpt" -+ ;; -+dlan-hotspot) -+ ucidef_set_led_wlan "wlan" "WLAN" "devolo:green:wifi" "phy0tpt" -+ ;; -+dlan-pro-500-wp) -+ ucidef_set_led_default "power" "System Power" "devolo:green:status" "1" -+ ucidef_set_led_netdev "lan" "Ethernet Activity" "devolo:green:eth" "br-lan" -+ ucidef_set_led_wlan "wlan2g" "WLAN 2.4 GHz" "devolo:green:wlan-2g" "phy0tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN 5 GHz" "devolo:blue:wlan-5g" "none" -+ ;; -+dlan-pro-1200-ac) -+ ucidef_set_led_wlan "wlan" "WLAN" "devolo:status:wlan" "phy0radio" -+ ucidef_set_led_gpio "plcw" "dLAN" "devolo:status:dlan" "17" "0" -+ ucidef_set_led_gpio "plcr" "dLAN" "devolo:error:dlan" "16" "0" -+ ;; -+e1700ac-v2) -+ ucidef_set_led_usbport "usb" "USB" "$board:green:usb" "usb1-port1" -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "$board:green:wlan2g" "phy1tpt" -+ ;; -+e558-v2|\ -+e750g-v8) -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan" "phy0tpt" -+ ;; -+esr900) -+ ucidef_set_led_wlan "wlan2g" "WLAN 2.4 GHz" "engenius:blue:wlan-2g" "phy0tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN 5 GHz" "engenius:blue:wlan-5g" "phy1tpt" -+ ;; -+esr1750|\ -+epg5000) -+ ucidef_set_led_wlan "wlan2g" "WLAN 2.4 GHz" "$board:blue:wlan-2g" "phy1tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN 5 GHz" "$board:blue:wlan-5g" "phy0tpt" -+ ;; -+fritz4020) -+ ucidef_set_led_netdev "lan" "LAN" "$board:green:lan" "eth1" -+ ucidef_set_led_netdev "wan" "WAN" "$board:green:wan" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan" "phy0tpt" -+ ;; -+fritz450e) -+ ucidef_set_led_netdev "lan" "LAN" "$board:green:lan" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan" "phy0tpt" -+ ;; -+gl-ar300m) -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:red:wlan" "phy0tpt" -+ ucidef_set_led_netdev "lan" "LAN" "$board:green:lan" "eth1" -+ ;; -+gl-ar750) -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "$board:white:wlan2g" "phy1tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN5G" "$board:white:wlan5g" "phy0tpt" -+ ;; -+gl-ar750s) -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "$board:green:wlan2g" "phy1tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN5G" "$board:green:wlan5g" "phy0tpt" -+ ;; -+gl-mifi) -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan" "phy0tpt" -+ ucidef_set_led_netdev "wan" "WAN" "$board:green:wan" "eth0" -+ ucidef_set_led_netdev "lan" "LAN" "$board:green:lan" "eth1" -+ ucidef_set_led_netdev "3gnet" "3GNET" "$board:green:net" "3g-wan" -+ ;; -+gl-ar150) -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:orange:wlan" "phy0tpt" -+ ucidef_set_led_netdev "wan" "WAN" "$board:green:wan" "eth0" -+ ucidef_set_led_netdev "lan" "LAN" "$board:green:lan" "eth1" -+ ;; -+gl-ar300) -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:wlan" "phy0tpt" -+ ;; -+gl-domino|\ -+sc300m|\ -+wrt160nl) -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:blue:wlan" "phy0tpt" -+ ;; -+gl-inet) -+ ucidef_set_led_netdev "lan" "LAN" "$board:green:lan" "eth1" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:red:wlan" "phy0tpt" -+ ;; -+hiwifi-hc6361) -+ ucidef_set_led_netdev "inet" "INET" "hiwifi:blue:internet" "eth1" -+ ucidef_set_led_wlan "wlan" "WLAN" "hiwifi:blue:wlan-2p4" "phy0tpt" -+ ;; -+hornet-ub|\ -+hornet-ub-x2) -+ ucidef_set_led_netdev "lan" "LAN" "alfa:blue:lan" "eth0" -+ ucidef_set_led_netdev "wan" "WAN" "alfa:blue:wan" "eth1" -+ ucidef_set_led_wlan "wlan" "WLAN" "alfa:blue:wlan" "phy0tpt" -+ ucidef_set_led_usbport "usb" "USB" "alfa:blue:usb" "usb1-port1" -+ ;; -+koala) -+ ucidef_set_led_default "power" "POWER" "$board:green:power" "1" -+ ucidef_set_led_wlan "wlan2g" "WLAN 2.4GHz" "$board:yellow:wlan2" "phy1tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN 5GHz" "$board:red:wlan58" "phy0tpt" -+ ;; -+lan-turtle) -+ ucidef_set_led_netdev "wan" "WAN" "$board:orange:system" "eth1" -+ ;; -+lbe-m5) -+ ucidef_set_led_netdev "lan" "LAN" "ubnt:green:lan" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "ubnt:green:wlan" "phy0tpt" -+ ;; -+mc-mac1200r) -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "mercury:green:wlan2g" "phy1tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN5G" "mercury:green:wlan5g" "phy0tpt" -+ ;; -+mr12|\ -+mr16) -+ ucidef_set_led_netdev "wan" "WAN" "$board:green:wan" "eth0" -+ ucidef_set_led_wlan "wlan1" "WLAN1" "$board:green:wifi1" "phy0assoc" -+ ucidef_set_led_wlan "wlan2" "WLAN2" "$board:green:wifi2" "phy0assoc" -+ ucidef_set_led_wlan "wlan3" "WLAN3" "$board:green:wifi3" "phy0assoc" -+ ucidef_set_led_wlan "wlan4" "WLAN4" "$board:green:wifi4" "phy0tpt" -+ ;; -+mr18) -+ ucidef_set_led_netdev "wlan0" "WLAN0" "$board:blue:tricolor0" "wlan0" -+ ;; -+mr600) -+ ucidef_set_led_wlan "wlan58" "WLAN58" "$board:green:wlan58" "phy0tpt" -+ ucidef_set_led_default "wps" "WPS" "mr600:blue:wps" "0" -+ ;; -+mr600v2) -+ ucidef_set_led_default "wlan24-red" "WLAN 2.4GHz (red)" "mr600:red:wlan24" "0" -+ ucidef_set_led_default "wlan24-yellow" "WLAN 2.4GHz (yellow)" "mr600:yellow:wlan24" "0" -+ ucidef_set_led_wlan "wlan24-green" "WLAN 4GHz (green)" "mr600:green:wlan24" "phy1tpt" -+ ucidef_set_led_default "wlan5-red" "WLAN 5GHz (red)" "mr600:red:wlan58" "0" -+ ucidef_set_led_default "wlan5-yellow" "WLAN 5GHz (yellow)" "mr600:yellow:wlan58" "0" -+ ucidef_set_led_wlan "wlan5-green" "WLAN 5GHz (green)" "mr600:green:wlan58" "phy0tpt" -+ ;; -+mr1750|\ -+mr1750v2) -+ ucidef_set_led_netdev "lan" "LAN" "mr1750:blue:wan" "eth0" -+ ucidef_set_led_wlan "wlan58" "WLAN58" "mr1750:blue:wlan58" "phy0tpt" -+ ucidef_set_led_wlan "wlan24" "WLAN24" "mr1750:blue:wlan24" "phy1tpt" -+ ucidef_set_led_default "status-red" "Status (red)" "mr1750:red:wifi" "0" -+ ucidef_set_led_default "status-green" "Status (green)" "mr1750:green:wifi" "0" -+ ;; -+mr900|\ -+mr900v2) -+ ucidef_set_led_netdev "lan" "LAN" "mr900:blue:wan" "eth0" -+ ucidef_set_led_wlan "wlan24" "WLAN24" "mr900:blue:wlan24" "phy0tpt" -+ ucidef_set_led_wlan "wlan58" "WLAN58" "mr900:blue:wlan58" "phy1tpt" -+ ucidef_set_led_default "status-red" "Status (red)" "mr900:red:wifi" "0" -+ ucidef_set_led_default "status-green" "Status (green)" "mr900:green:wifi" "0" -+ ;; -+mynet-n600) -+ ucidef_set_led_netdev "wan" "WAN" "wd:blue:internet" "eth1" -+ ucidef_set_led_switch "lan1" "LAN1" "wd:green:lan1" "switch0" "0x02" -+ ucidef_set_led_switch "lan2" "LAN2" "wd:green:lan2" "switch0" "0x10" -+ ucidef_set_led_switch "lan3" "LAN3" "wd:green:lan3" "switch0" "0x08" -+ ucidef_set_led_switch "lan4" "LAN4" "wd:green:lan4" "switch0" "0x04" -+ ;; -+mynet-rext) -+ ucidef_set_led_netdev "lan" "LAN" "wd:blue:ethernet" "eth0" -+ ucidef_set_rssimon "wlan0" "200000" "1" -+ ucidef_set_led_rssi "rssilow" "RSSILOW" "wd:blue:quality1" "wlan0" "1" "40" "0" "6" -+ ucidef_set_led_rssi "rssimedium" "RSSIMEDIUM" "wd:blue:quality2" "wlan0" "30" "80" "-29" "5" -+ ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "wd:blue:quality3" "wlan0" "70" "100" "-69" "8" -+ ucidef_set_led_wlan "wlan" "WLAN" "wd:blue:wireless" "phy0tpt" -+ ;; -+mzk-w04u) -+ ucidef_set_led_usbport "usb" "USB" "planex:green:usb" "usb1-port1" -+ ;; -+mzk-w300nh) -+ ucidef_set_led_wlan "wlan" "WLAN" "planex:green:wlan" "phy0tpt" -+ ;; -+nbg460n_550n_550nh) -+ ucidef_set_led_wlan "wlan" "WLAN" "nbg460n:green:wlan" "phy0tpt" -+ ;; -+nbg6616) -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wifi2g" "phy1tpt" -+ ucidef_set_led_wlan "wlan5" "WLAN5" "$board:green:wifi5g" "phy0tpt" -+ ucidef_set_led_usbport "usb1" "USB1" "$board:green:usb1" "usb1-port1" -+ ucidef_set_led_usbport "usb2" "USB2" "$board:green:usb2" "usb2-port1" -+ ;; -+nbg6716) -+ ucidef_set_led_netdev "wan" "WAN" "$board:white:internet" "eth1" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:white:wifi2g" "phy1tpt" -+ ucidef_set_led_wlan "wlan5" "WLAN5" "$board:white:wifi5g" "phy0tpt" -+ ucidef_set_led_usbport "usb1" "USB1" "$board:white:usb1" "usb1-port1" -+ ucidef_set_led_usbport "usb2" "USB2" "$board:white:usb2" "usb2-port1" -+ ;; -+om2p|\ -+om2p-hs|\ -+om2p-hsv2|\ -+om2p-hsv3|\ -+om2p-hsv4|\ -+om2p-lc|\ -+om2pv2|\ -+om2pv4) -+ ucidef_set_led_netdev "port1" "port1" "om2p:blue:wan" "eth0" -+ ucidef_set_led_netdev "port2" "port2" "om2p:blue:lan" "eth1" -+ ucidef_set_led_default "wlan-red" "WLAN (red)" "om2p:red:wifi" "0" -+ ucidef_set_led_default "wlan-yellow" "WLAN (yellow)" "om2p:yellow:wifi" "0" -+ ucidef_set_led_default "wlan-green" "WLAN (green)" "om2p:green:wifi" "0" -+ ;; -+om5p|\ -+om5p-an) -+ ucidef_set_led_netdev "port1" "port1" "om5p:blue:wan" "eth0" -+ ucidef_set_led_netdev "port2" "port2" "om5p:blue:lan" "eth1" -+ ucidef_set_led_default "wlan-red" "WLAN (red)" "om5p:red:wifi" "0" -+ ucidef_set_led_default "wlan-yellow" "WLAN (yellow)" "om5p:yellow:wifi" "0" -+ ucidef_set_led_default "wlan-green" "WLAN (green)" "om5p:green:wifi" "0" -+ ;; -+om5p-ac) -+ ucidef_set_led_netdev "port1" "port1" "om5pac:blue:lan" "eth0" -+ ucidef_set_led_netdev "port2" "port2" "om5pac:blue:wan" "eth1" -+ ucidef_set_led_default "wlan-red" "WLAN (red)" "om5pac:red:wifi" "0" -+ ucidef_set_led_default "wlan-yellow" "WLAN (yellow)" "om5pac:yellow:wifi" "0" -+ ucidef_set_led_default "wlan-green" "WLAN (green)" "om5pac:green:wifi" "0" -+ ;; -+om5p-acv2) -+ ucidef_set_led_default "wlan-red" "WLAN (red)" "om5pac:red:wifi" "0" -+ ucidef_set_led_default "wlan-yellow" "WLAN (yellow)" "om5pac:yellow:wifi" "0" -+ ucidef_set_led_default "wlan-green" "WLAN (green)" "om5pac:green:wifi" "0" -+ ;; -+omy-g1) -+ ucidef_set_led_wlan "wlan" "WLAN" "omy:green:wlan" "phy0tpt" -+ ucidef_set_led_netdev "wan" "WAN" "omy:green:wan" "eth0" -+ ucidef_set_led_netdev "lan" "LAN" "omy:green:lan" "eth1" -+ ;; -+omy-x1) -+ ucidef_set_led_default "power" "POWER" "omy:green:power" "1" -+ ucidef_set_led_default "wan" "WAN" "omy:green:wan" "eth0" -+ ;; -+pqi-air-pen) -+ ucidef_set_led_wlan "wlan" "WLAN" "pqi-air-pen:blue:wlan" "phy0tpt" -+ ucidef_set_led_default "wps" "WPS" "pqi-air-pen:blue:wps" "0" -+ ;; -+qihoo-c301) -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "qihoo:red:status" "phy1tpt" -+ ;; -+r36a) -+ ucidef_set_led_netdev "lan" "LAN" "$board:blue:lan" "eth0" -+ ucidef_set_led_usbport "usb" "USB" "$board:blue:usb" "usb1-port1" -+ ucidef_set_led_netdev "wan" "WAN" "$board:blue:wan" "eth1" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:blue:wlan" "phy0tpt" -+ ;; -+r602n|\ -+t830|\ -+zbt-we1526) -+ ucidef_set_led_netdev "wan" "WAN" "$board:green:wan" "eth1" -+ ucidef_set_led_switch "lan1" "LAN1" "$board:green:lan1" "switch0" "0x10" -+ ucidef_set_led_switch "lan2" "LAN2" "$board:green:lan2" "switch0" "0x08" -+ ucidef_set_led_switch "lan3" "LAN3" "$board:green:lan3" "switch0" "0x04" -+ ucidef_set_led_switch "lan4" "LAN4" "$board:green:lan4" "switch0" "0x02" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan" "phy0tpt" -+ -+ case "$board" in -+ t830) -+ ucidef_set_led_usbport "usb" "USB" "$board:green:usb" "usb1-port1" -+ ;; -+ esac -+ ;; -+r6100) -+ ucidef_set_led_netdev "wan" "WAN (green)" "netgear:green:wan" "eth0" -+ ucidef_set_led_usbport "usb" "USB" "netgear:blue:usb" "usb1-port1" -+ ucidef_set_led_wlan "wlan" "WLAN" "netgear:blue:wlan" "phy1tpt" -+ ;; -+rb-750) -+ ucidef_set_led_default "act" "act" "rb750:green:act" "1" -+ ucidef_set_led_netdev "port1" "port1" "rb750:green:port1" "eth1" -+ ucidef_set_led_switch "port2" "port2" "rb750:green:port2" "switch0" "0x10" -+ ucidef_set_led_switch "port3" "port3" "rb750:green:port3" "switch0" "0x08" -+ ucidef_set_led_switch "port4" "port4" "rb750:green:port4" "switch0" "0x04" -+ ucidef_set_led_switch "port5" "port5" "rb750:green:port5" "switch0" "0x02" -+ ;; -+rb-750-r2|\ -+rb-750p-pbr2|\ -+rb-750up-r2) -+ ucidef_set_led_timer "user" "USER" "rb:green:user" "1000" "1000" -+ ucidef_set_led_netdev "port1" "port1" "rb:green:port1" "eth0" -+ ucidef_set_led_switch "port2" "port2" "rb:green:port2" "switch0" "0x10" -+ ucidef_set_led_switch "port3" "port2" "rb:green:port3" "switch0" "0x08" -+ ucidef_set_led_switch "port4" "port3" "rb:green:port4" "switch0" "0x04" -+ ucidef_set_led_switch "port5" "port5" "rb:green:port5" "switch0" "0x02" -+ ;; -+rb-911-2hn|\ -+rb-911-5hn) -+ ucidef_set_led_netdev "eth" "ETH" "rb:green:eth" "eth0" -+ ;; -+rb-931-2nd|\ -+rb-941-2nd) -+ ucidef_set_led_timer "user" "USR/ACT" "rb:green:user" "1000" "1000" -+ ;; -+rb-951ui-2nd|\ -+rb-952ui-5ac2nd) -+ ucidef_set_led_timer "user" "USER" "rb:green:user" "1000" "1000" -+ ucidef_set_led_netdev "port1" "port1" "rb:green:port1" "eth0" -+ ucidef_set_led_switch "port2" "port2" "rb:green:port2" "switch0" "0x10" -+ ucidef_set_led_switch "port3" "port2" "rb:green:port3" "switch0" "0x08" -+ ucidef_set_led_switch "port4" "port3" "rb:green:port4" "switch0" "0x04" -+ ucidef_set_led_switch "port5" "port5" "rb:green:port5" "switch0" "0x02" -+ ucidef_set_led_wlan "wlan" "WLAN" "rb:blue:wlan" "phy0tpt" -+ ;; -+rb-962uigs-5hact2hnt) -+ ucidef_set_led_timer "user" "USER/SFP" "rb:green:user" "1000" "1000" -+ ;; -+rb-2011il|\ -+rb-2011ils|\ -+rb-2011l|\ -+rb-2011uas|\ -+rb-2011uas-2hnd|\ -+rb-2011uias|\ -+rb-2011uias-2hnd|\ -+rb-2011uias-2hnd-r2) -+ ucidef_set_led_switch "eth6" "ETH6" "rb:green:eth6" "switch1" "0x20" -+ ucidef_set_led_switch "eth7" "ETH7" "rb:green:eth7" "switch1" "0x10" -+ ucidef_set_led_switch "eth8" "ETH8" "rb:green:eth8" "switch1" "0x08" -+ ucidef_set_led_switch "eth9" "ETH9" "rb:green:eth9" "switch1" "0x04" -+ ucidef_set_led_switch "eth10" "ETH10" "rb:green:eth10" "switch1" "0x02" -+ ;; -+rb-lhg-5nd) -+ ucidef_set_led_netdev "lan" "LAN" "rb:green:eth" "eth0" -+ ucidef_set_rssimon "wlan0" "200000" "1" -+ ucidef_set_led_rssi "rssilow" "RSSILOW" "rb:green:rssi0" "wlan0" "1" "100" "0" "13" -+ ucidef_set_led_rssi "rssimediumlow" "RSSIMEDIUMLOW" "rb:green:rssi1" "wlan0" "20" "100" "-19" "13" -+ ucidef_set_led_rssi "rssimedium" "RSSIMEDIUM" "rb:green:rssi2" "wlan0" "40" "100" "-39" "13" -+ ucidef_set_led_rssi "rssimediumhigh" "RSSIMEDIUMHIGH" "rb:green:rssi3" "wlan0" "60" "100" "-59" "13" -+ ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "rb:green:rssi4" "wlan0" "80" "100" "-79" "13" -+ ;; -+rb-map-2nd) -+ ucidef_set_led_switch "eth1" "WAN" "rb:green:eth1" "switch0" "0x02" -+ ucidef_set_led_switch "eth2" "LAN" "rb:green:eth2" "switch0" "0x04" -+ ucidef_set_led_gpio "poe" "POE" "rb:red:poe_out" "14" "0" -+ ucidef_set_led_wlan "wlan" "WLAN" "rb:green:wlan" "phy0tpt" -+ ;; -+rb-mapl-2nd) -+ ucidef_set_led_default "power" "POWER" "rb:green:power" "1" -+ ucidef_set_led_netdev "lan" "LAN" "rb:green:eth" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "rb:green:wlan" "phy0tpt" -+ ;; -+rb-wap-2nd) -+ ucidef_set_led_timer "user" "USER" "rb:green:user" "1000" "1000" -+ ucidef_set_led_wlan "wlan" "WLAN" "rb:green:wlan" "phy0tpt" -+ ;; -+rb-wapr-2nd) -+ ucidef_set_led_wlan "wlan" "WLAN" "rb:green:user" "phy0tpt" -+ ;; -+re355|\ -+re450) -+ ucidef_set_led_netdev "lan_data" "LAN Data" "$board:green:lan_data" "eth0" "tx rx" -+ ucidef_set_led_netdev "lan_link" "LAN Link" "$board:green:lan_link" "eth0" "link" -+ ucidef_set_led_wlan "wlan2g" "WLAN 2.4 GHz" "$board:blue:wlan2g" "phy1tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN 5 GHz" "$board:blue:wlan5g" "phy0tpt" -+ ;; -+rme-eg200) -+ ucidef_set_led_netdev "wan" "WAN" "eg200:red:eth0" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "eg200:red:wlan" "phy0tpt" -+ ucidef_set_led_oneshot "modbus" "Modbus" "eg200:red:modbus" "100" "33" -+ ucidef_set_led_default "etactica" "etactica" "eg200:red:etactica" "ignore" -+ ;; -+rocket-m-ti) -+ ucidef_set_rssimon "wlan0" "200000" "1" -+ ucidef_set_led_rssi "rssiverylow" "RSSIVERYLOW" "ubnt:green:link1" "wlan0" "1" "100" -+ ucidef_set_led_rssi "rssilow" "RSSILOW" "ubnt:green:link2" "wlan0" "18" "100" -+ ucidef_set_led_rssi "rssimediumlow" "RSSIMEDIUMLOW" "ubnt:green:link3" "wlan0" "34" "100" -+ ucidef_set_led_rssi "rssimediumhigh" "RSSIMEDIUMHIGH" "ubnt:green:link4" "wlan0" "51" "100" -+ ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "ubnt:green:link5" "wlan0" "67" "100" -+ ucidef_set_led_rssi "rssiveryhigh" "RSSIVERYHIGH" "ubnt:green:link6" "wlan0" "84" "100" -+ ;; -+rut900) -+ ucidef_set_led_netdev "wan" "WAN" "$board:green:wan" "eth1" -+ ucidef_set_led_switch "lan1" "LAN1" "$board:green:lan1" "switch0" "0x10" -+ ucidef_set_led_switch "lan2" "LAN2" "$board:green:lan2" "switch0" "0x08" -+ ucidef_set_led_switch "lan3" "LAN3" "$board:green:lan3" "switch0" "0x04" -+ ;; -+smart-300) -+ ucidef_set_led_netdev "wan" "WAN" "nc-link:green:wan" "eth0" -+ ucidef_set_led_switch "lan1" "LAN1" "nc-link:green:lan1" "switch0" "0x04" -+ ucidef_set_led_switch "lan2" "LAN2" "nc-link:green:lan2" "switch0" "0x08" -+ ucidef_set_led_switch "lan3" "LAN3" "nc-link:green:lan3" "switch0" "0x10" -+ ucidef_set_led_switch "lan4" "LAN4" "nc-link:green:lan4" "switch0" "0x02" -+ ucidef_set_led_wlan "wlan" "WLAN" "nc-link:green:wlan" "phy0tpt" -+ ;; -+som9331) -+ ucidef_set_led_netdev "wan" "WAN" "$board:orange:wan" "eth1" -+ ucidef_set_led_switch "lan1" "LAN1" "$board:orange:lan1" "switch0" "0x08" -+ ucidef_set_led_switch "lan2" "LAN2" "$board:orange:lan2" "switch0" "0x02" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:red:wlan" "phy0tpt" -+ ucidef_set_led_usbport "usb" "USB" "$board:green:system" "usb1-port1" -+ ;; -+sr3200) -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "$board:green:wlan2g" "phy1tpt" -+ ;; -+tellstick-znet-lite) -+ ucidef_set_led_netdev "lan_act" "LANACT" "tellstick:green:lan" "eth0" "tx rx" -+ ucidef_set_led_netdev "lan_link" "LANLINK" "tellstick:orange:lan" "eth0" "link" -+ ;; -+tew-712br) -+ ucidef_set_led_netdev "wan" "WAN" "trendnet:green:wan" "eth1" -+ ucidef_set_led_switch "lan1" "LAN1" "trendnet:green:lan1" "switch0" "0x02" -+ ucidef_set_led_switch "lan2" "LAN2" "trendnet:green:lan2" "switch0" "0x04" -+ ucidef_set_led_switch "lan3" "LAN3" "trendnet:green:lan3" "switch0" "0x08" -+ ucidef_set_led_switch "lan4" "LAN4" "trendnet:green:lan4" "switch0" "0x10" -+ ucidef_set_led_wlan "wlan" "WLAN" "trendnet:green:wlan" "phy0tpt" -+ ;; -+tew-732br) -+ ucidef_set_led_netdev "wan" "WAN" "trendnet:green:wan" "eth1" -+ ;; -+tew-823dru) -+ ucidef_set_led_netdev "wan" "WAN" "trendnet:green:planet" "eth0" -+ ;; -+tl-mr11u|\ -+tl-mr3020|\ -+tl-mr3040|\ -+tl-mr3040-v2) -+ ucidef_set_led_usbport "usb" "USB" "tp-link:green:3g" "usb1-port1" -+ ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" -+ ucidef_set_led_netdev "lan" "LAN" "tp-link:green:lan" "eth0" -+ ;; -+tl-mr3220|\ -+tl-mr3420) -+ ucidef_set_led_usbport "usb" "USB" "tp-link:green:3g" "usb1-port1" -+ ;; -+tl-mr3220-v2|\ -+tl-wr741nd-v4) -+ ucidef_set_led_netdev "wan" "WAN" "tp-link:green:wan" "eth1" -+ ucidef_set_led_switch "lan1" "LAN1" "tp-link:green:lan1" "switch0" "0x04" -+ ucidef_set_led_switch "lan2" "LAN2" "tp-link:green:lan2" "switch0" "0x08" -+ ucidef_set_led_switch "lan3" "LAN3" "tp-link:green:lan3" "switch0" "0x10" -+ ucidef_set_led_switch "lan4" "LAN4" "tp-link:green:lan4" "switch0" "0x02" -+ ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" -+ -+ case "$board" in -+ tl-mr3220-v2) -+ ucidef_set_led_usbport "usb" "USB" "tp-link:green:3g" "usb1-port1" -+ ;; -+ esac -+ ;; -+tl-mr3420-v2|\ -+tl-wr841n-v8|\ -+tl-wr842n-v2|\ -+tl-wr941nd-v5) -+ ucidef_set_led_netdev "wan" "WAN" "tp-link:green:wan" "eth0" -+ ucidef_set_led_switch "lan1" "LAN1" "tp-link:green:lan1" "switch0" "0x04" -+ ucidef_set_led_switch "lan2" "LAN2" "tp-link:green:lan2" "switch0" "0x08" -+ ucidef_set_led_switch "lan3" "LAN3" "tp-link:green:lan3" "switch0" "0x10" -+ ucidef_set_led_switch "lan4" "LAN4" "tp-link:green:lan4" "switch0" "0x02" -+ ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" -+ -+ case "$board" in -+ tl-mr3420-v2|\ -+ tl-wr842n-v2) -+ ucidef_set_led_usbport "usb" "USB" "tp-link:green:3g" "usb1-port1" -+ ;; -+ esac -+ ;; -+tl-mr6400) -+ ucidef_set_led_netdev "lan" "LAN" "tp-link:white:lan" "eth0" -+ ucidef_set_led_netdev "wan" "WAN" "tp-link:white:wan" "eth1" -+ ucidef_set_led_netdev "4g" "4G" "tp-link:white:4g" "usb0" -+ ucidef_set_led_wlan "wlan" "WLAN" "tp-link:white:wlan" "phy0tpt" -+ ;; -+tl-wa7210n-v2) -+ ucidef_set_led_netdev "lan" "LAN" "tp-link:green:lan" "eth0" -+ ucidef_set_rssimon "wlan0" "200000" "1" -+ ucidef_set_led_rssi "rssilow" "RSSILOW" "tp-link:green:signal1" "wlan0" "1" "100" "0" "13" -+ ucidef_set_led_rssi "rssimediumlow" "RSSIMEDIUMLOW" "tp-link:green:signal2" "wlan0" "26" "100" "-25" "13" -+ ucidef_set_led_rssi "rssimediumhigh" "RSSIMEDIUMHIGH" "tp-link:green:signal3" "wlan0" "51" "100" "-50" "13" -+ ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "tp-link:green:signal4" "wlan0" "76" "100" "-75" "13" -+ ;; -+tl-wa750re) -+ ucidef_set_led_netdev "lan" "LAN" "tp-link:orange:lan" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "tp-link:orange:wlan" "phy0tpt" -+ ucidef_set_rssimon "wlan0" "200000" "1" -+ ucidef_set_led_rssi "rssilow" "RSSILOW" "tp-link:orange:signal1" "wlan0" "1" "100" "0" "13" -+ ucidef_set_led_rssi "rssimediumlow" "RSSIMEDIUMLOW" "tp-link:orange:signal2" "wlan0" "20" "100" "-19" "13" -+ ucidef_set_led_rssi "rssimedium" "RSSIMEDIUM" "tp-link:orange:signal3" "wlan0" "40" "100" "-39" "13" -+ ucidef_set_led_rssi "rssimediumhigh" "RSSIMEDIUMHIGH" "tp-link:orange:signal4" "wlan0" "60" "100" "-59" "13" -+ ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "tp-link:orange:signal5" "wlan0" "80" "100" "-79" "13" -+ ;; -+tl-wa801nd-v3) -+ ucidef_set_led_netdev "lan" "LAN" "tp-link:green:lan" "eth1" -+ ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" -+ ;; -+tl-wa850re|\ -+tl-wa850re-v2) -+ ucidef_set_led_netdev "lan" "LAN" "tp-link:blue:lan" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "tp-link:blue:wlan" "phy0tpt" -+ ucidef_set_rssimon "wlan0" "200000" "1" -+ ucidef_set_led_rssi "rssilow" "RSSILOW" "tp-link:blue:signal1" "wlan0" "1" "100" "0" "13" -+ ucidef_set_led_rssi "rssimediumlow" "RSSIMEDIUMLOW" "tp-link:blue:signal2" "wlan0" "20" "100" "-19" "13" -+ ucidef_set_led_rssi "rssimedium" "RSSIMEDIUM" "tp-link:blue:signal3" "wlan0" "40" "100" "-39" "13" -+ ucidef_set_led_rssi "rssimediumhigh" "RSSIMEDIUMHIGH" "tp-link:blue:signal4" "wlan0" "60" "100" "-59" "13" -+ ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "tp-link:blue:signal5" "wlan0" "80" "100" "-79" "13" -+ ;; -+tl-wa701nd-v2|\ -+tl-wa801nd-v2|\ -+tl-wa830re-v2|\ -+tl-wa860re|\ -+tl-wa901nd-v3|\ -+tl-wa901nd-v4|\ -+tl-wa901nd-v5) -+ ucidef_set_led_netdev "lan" "LAN" "tp-link:green:lan" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" -+ ;; -+tl-wa901nd) -+ ucidef_set_led_netdev "lan" "LAN" "tp-link:green:lan" "eth0" -+ ;; -+tl-wa901nd-v2|\ -+tl-wr941nd|\ -+tl-wr1041n-v2) -+ ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" -+ ;; -+tl-wdr3320-v2) -+ ucidef_set_led_wlan "wlan5g" "WLAN5G" "tp-link:green:wlan5g" "phy0tpt" -+ ;; -+tl-wdr3500) -+ ucidef_set_led_usbport "usb" "USB" "tp-link:green:usb" "usb1-port1" -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "tp-link:green:wlan2g" "phy0tpt" -+ ;; -+tl-wdr4300) -+ ucidef_set_led_usbport "usb1" "USB1" "tp-link:green:usb1" "1-1-port1" -+ ucidef_set_led_usbport "usb2" "USB2" "tp-link:green:usb2" "1-1-port2" -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "tp-link:blue:wlan2g" "phy0tpt" -+ ;; -+tl-wdr4900-v2) -+ ucidef_set_led_usbport "usb1" "USB1" "tp-link:green:usb1" "usb1-port1" -+ ucidef_set_led_usbport "usb2" "USB2" "tp-link:green:usb2" "usb2-port1" -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "tp-link:blue:wlan2g" "phy0tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN5G" "tp-link:blue:wlan5g" "phy1tpt" -+ ;; -+tl-wdr6500-v2|\ -+tl-wr741nd) -+ ucidef_set_led_netdev "wan" "WAN" "tp-link:green:wan" "eth1" -+ ucidef_set_led_switch "lan1" "LAN1" "tp-link:green:lan1" "switch0" "0x02" -+ ucidef_set_led_switch "lan2" "LAN2" "tp-link:green:lan2" "switch0" "0x04" -+ ucidef_set_led_switch "lan3" "LAN3" "tp-link:green:lan3" "switch0" "0x08" -+ ucidef_set_led_switch "lan4" "LAN4" "tp-link:green:lan4" "switch0" "0x10" -+ ;; -+tl-wpa8630) -+ ucidef_set_led_netdev "lan" "LAN" "$board:green:lan" "eth0" -+ ucidef_set_led_netdev "wlan" "WLAN" "$board:green:wlan" "wlan1" -+ ucidef_set_led_netdev "wlan5" "WLAN5" "$board:green:wlan5" "wlan0" -+ ;; -+tl-wr740n-v6|\ -+tl-wr841n-v9|\ -+tl-wr841n-v11|\ -+tl-wr842n-v3) -+ ucidef_set_led_netdev "wan" "WAN" "tp-link:green:wan" "eth1" -+ ucidef_set_led_switch "lan1" "LAN1" "tp-link:green:lan1" "switch0" "0x10" -+ ucidef_set_led_switch "lan2" "LAN2" "tp-link:green:lan2" "switch0" "0x08" -+ ucidef_set_led_switch "lan3" "LAN3" "tp-link:green:lan3" "switch0" "0x04" -+ ucidef_set_led_switch "lan4" "LAN4" "tp-link:green:lan4" "switch0" "0x02" -+ ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" -+ -+ case "$board" in -+ tl-wr842n-v3) -+ ucidef_set_led_usbport "usb" "USB" "tp-link:green:3g" "usb1-port1" -+ ;; -+ esac -+ ;; -+tl-wr802n-v1) -+ ucidef_set_led_wlan "wlan" "WLAN" "tp-link:blue:system" "phy0tpt" -+ ;; -+tl-wr802n-v2) -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:system" "phy0tpt" -+ ;; -+tl-wr902ac-v1) -+ ucidef_set_led_netdev "lan" "LAN" "$board:green:lan" "eth0" -+ ucidef_set_led_usbport "usb" "USB" "$board:green:usb" "usb1-port1" -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "$board:green:wlan2g" "phy1tpt" -+ ;; -+tl-wr940n-v4|\ -+tl-wr941nd-v6) -+ ucidef_set_led_netdev "wan" "WAN" "tp-link:blue:wan" "eth0" -+ ucidef_set_led_switch "lan1" "LAN1" "tp-link:blue:lan1" "switch0" "0x10" -+ ucidef_set_led_switch "lan2" "LAN2" "tp-link:blue:lan2" "switch0" "0x08" -+ ucidef_set_led_switch "lan3" "LAN3" "tp-link:blue:lan3" "switch0" "0x04" -+ ucidef_set_led_switch "lan4" "LAN4" "tp-link:blue:lan4" "switch0" "0x02" -+ ucidef_set_led_wlan "wlan" "WLAN" "tp-link:blue:wlan" "phy0tpt" -+ ;; -+tl-wr840n-v2|\ -+tl-wr840n-v3) -+ ucidef_set_led_netdev "wan" "WAN" "tp-link:green:wan" "eth1" -+ ucidef_set_led_switch "lan" "LAN" "tp-link:green:lan" "switch0" "0x1E" -+ ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" -+ ;; -+tl-wr940n-v6) -+ ucidef_set_led_netdev "wan" "WAN" "tp-link:blue:wan" "eth0" -+ ;; -+tl-wr942n-v1) -+ ucidef_set_led_switch "lan1" "LAN1" "$board:green:lan1" "switch0" "0x04" -+ ucidef_set_led_switch "lan2" "LAN2" "$board:green:lan2" "switch0" "0x08" -+ ucidef_set_led_switch "lan3" "LAN3" "$board:green:lan3" "switch0" "0x10" -+ ucidef_set_led_switch "lan4" "LAN4" "$board:green:lan4" "switch0" "0x02" -+ ucidef_set_led_netdev "wan" "WAN" "$board:green:wan" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:green:wlan" "phy0tpt" -+ ucidef_set_led_usbport "usb1" "USB1" "$board:green:usb1" "1-1-port2" -+ ucidef_set_led_usbport "usb2" "USB2" "$board:green:usb2" "1-1-port1" -+ ;; -+tl-wr1043nd|\ -+tl-wr1043nd-v2) -+ ucidef_set_led_usbport "usb" "USB" "tp-link:green:usb" "usb1-port1" -+ ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" -+ ;; -+tl-wr1043n-v5|\ -+tl-wr1043nd-v4) -+ ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" -+ ucidef_set_led_switch "wan" "WAN" "tp-link:green:wan" "switch0" "0x20" -+ ucidef_set_led_switch "lan1" "LAN1" "tp-link:green:lan1" "switch0" "0x10" -+ ucidef_set_led_switch "lan2" "LAN2" "tp-link:green:lan2" "switch0" "0x08" -+ ucidef_set_led_switch "lan3" "LAN3" "tp-link:green:lan3" "switch0" "0x04" -+ ucidef_set_led_switch "lan4" "LAN4" "tp-link:green:lan4" "switch0" "0x02" -+ -+ case "$board" in -+ tl-wr1043nd-v4) -+ ucidef_set_led_usbport "usb" "USB" "tp-link:green:usb" "usb1-port1" -+ ;; -+ esac -+ ;; -+tl-wr2543n) -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "tp-link:green:wlan2g" "phy0tpt" -+ ucidef_set_led_usbport "usb" "USB" "tp-link:green:usb" "usb1-port1" -+ ;; -+tube2h) -+ ucidef_set_led_netdev "lan" "LAN" "alfa:blue:lan" "eth0" -+ ucidef_set_rssimon "wlan0" "200000" "1" -+ ucidef_set_led_rssi "signal1" "SIGNAL1" "alfa:red:signal1" "wlan0" "1" "100" "0" "13" -+ ucidef_set_led_rssi "signal2" "SIGNAL2" "alfa:orange:signal2" "wlan0" "26" "100" "-25" "13" -+ ucidef_set_led_rssi "signal3" "SIGNAL3" "alfa:green:signal3" "wlan0" "51" "100" "-50" "13" -+ ucidef_set_led_rssi "signal4" "SIGNAL4" "alfa:green:signal4" "wlan0" "76" "100" "-75" "13" -+ ;; -+wam250) -+ ucidef_set_led_netdev "lan" "LAN" "$board:white:lan" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "$board:white:wlan" "phy0tpt" -+ ;; -+wndap360) -+ ucidef_set_led_power "power" "POWER GREEN" "netgear:green:power" "1" -+ ;; -+wndr3700) -+ ucidef_set_led_default "wan" "WAN LED (green)" "netgear:green:wan" "0" -+ ucidef_set_led_usbport "usb" "USB" "netgear:green:usb" "usb1-port1" -+ ;; -+wi2a-ac200i) -+ ucidef_set_led_default "power" "Power (green)" "nokia:green:power" "1" -+ ucidef_set_led_default "wan" "Ethernet LED (green)" "nokia:green:wan" "1" -+ ucidef_set_led_wlan "wlan5g" "WLAN" "nokia:green:wlan-5g" "phy0tpt" -+ ucidef_set_led_wlan "wlan2g" "WLAN" "nokia:green:wlan-2g" "phy1tpt" -+ ;; -+wndr3700v4|\ -+wndr4300) -+ ucidef_set_led_switch "wan-amber" "WAN (amber)" "netgear:amber:wan" "switch0" "0x20" -+ ucidef_set_led_usbport "usb" "USB" "netgear:green:usb" "usb1-port1" -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "netgear:green:wlan2g" "phy0tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN5G" "netgear:blue:wlan5g" "phy1tpt" -+ ;; -+whr-g301n|\ -+whr-hp-g300n|\ -+whr-hp-gn) -+ ucidef_set_led_netdev "wan" "WAN" "buffalo:green:wan" "eth1" -+ ucidef_set_led_switch "lan1" "LAN1" "buffalo:green:lan1" "switch0" "0x02" -+ ucidef_set_led_switch "lan2" "LAN2" "buffalo:green:lan2" "switch0" "0x04" -+ ucidef_set_led_switch "lan3" "LAN3" "buffalo:green:lan3" "switch0" "0x08" -+ ucidef_set_led_switch "lan4" "LAN4" "buffalo:green:lan4" "switch0" "0x10" -+ ;; -+wifi-pineapple-nano) -+ ucidef_set_led_wlan "wlan0" "WLAN0" "$board:blue:system" "phy0tpt" -+ ;; -+wlae-ag300n) -+ ucidef_set_led_netdev "wireless" "WIRELESS" "buffalo:green:wireless" "wlan0" -+ ;; -+wnr1000-v2|\ -+wnr2000-v3) -+ ucidef_set_led_netdev "wan-amber" "WAN (amber)" "netgear:amber:wan" "eth0" -+ ucidef_set_led_default "wan-green" "WAN (green)" "netgear:green:wan" "0" -+ ucidef_set_led_wlan "wlan" "WLAN" "netgear:blue:wlan" "phy0tpt" -+ ucidef_set_led_switch "lan1green" "LAN1 (green)" "netgear:green:lan1" "switch0" "0x02" "0x04" -+ ucidef_set_led_switch "lan2green" "LAN2 (green)" "netgear:green:lan2" "switch0" "0x04" "0x04" -+ ucidef_set_led_switch "lan3green" "LAN3 (green)" "netgear:green:lan3" "switch0" "0x08" "0x04" -+ ucidef_set_led_switch "lan4green" "LAN4 (green)" "netgear:green:lan4" "switch0" "0x10" "0x04" -+ ucidef_set_led_switch "lan1amber" "LAN1 (amber)" "netgear:amber:lan1" "switch0" "0x02" "0x02" -+ ucidef_set_led_switch "lan2amber" "LAN2 (amber)" "netgear:amber:lan2" "switch0" "0x04" "0x02" -+ ucidef_set_led_switch "lan3amber" "LAN3 (amber)" "netgear:amber:lan3" "switch0" "0x08" "0x02" -+ ucidef_set_led_switch "lan4amber" "LAN4 (amber)" "netgear:amber:lan4" "switch0" "0x10" "0x02" -+ ;; -+wnr2000-v4) -+ ucidef_set_led_netdev "wan" "WAN" "netgear:green:wan" "eth0" -+ ucidef_set_led_netdev "wlan" "WLAN" "netgear:blue:wlan" "wlan0" -+ ucidef_set_led_switch "lan1" "LAN1" "netgear:amber:lan1" "switch0" "0x02" -+ ucidef_set_led_switch "lan2" "LAN2" "netgear:amber:lan2" "switch0" "0x04" -+ ucidef_set_led_switch "lan3" "LAN3" "netgear:amber:lan3" "switch0" "0x08" -+ ucidef_set_led_switch "lan4" "LAN4" "netgear:amber:lan4" "switch0" "0x10" -+ ucidef_set_led_usbport "usb" "USB" "netgear:amber:status" "usb1-port1" -+ ;; -+wnr2200) -+ ucidef_set_led_netdev "wan-amber" "WAN (amber)" "netgear:amber:wan" "eth0" -+ ucidef_set_led_default "wan-green" "WAN (green)" "netgear:green:wan" "0" -+ ucidef_set_led_wlan "wlan" "WLAN" "netgear:blue:wlan" "phy0tpt" -+ ucidef_set_led_switch "lan1green" "LAN1 (green)" "netgear:green:lan1" "switch0" "0x02" "0x04" -+ ucidef_set_led_switch "lan2green" "LAN2 (green)" "netgear:green:lan2" "switch0" "0x04" "0x04" -+ ucidef_set_led_switch "lan3green" "LAN3 (green)" "netgear:green:lan3" "switch0" "0x08" "0x04" -+ ucidef_set_led_switch "lan4green" "LAN4 (green)" "netgear:green:lan4" "switch0" "0x10" "0x04" -+ ucidef_set_led_switch "lan1amber" "LAN1 (amber)" "netgear:amber:lan1" "switch0" "0x02" "0x02" -+ ucidef_set_led_switch "lan2amber" "LAN2 (amber)" "netgear:amber:lan2" "switch0" "0x04" "0x02" -+ ucidef_set_led_switch "lan3amber" "LAN3 (amber)" "netgear:amber:lan3" "switch0" "0x08" "0x02" -+ ucidef_set_led_switch "lan4amber" "LAN4 (amber)" "netgear:amber:lan4" "switch0" "0x10" "0x02" -+ ucidef_set_led_usbport "usb" "USB" "netgear:green:usb" "usb1-port1" -+ ;; -+wnr612-v2) -+ ucidef_set_led_netdev "wan" "WAN" "netgear:green:wan" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "netgear:green:wlan" "phy0tpt" -+ ucidef_set_led_switch "lan1" "LAN1" "netgear:green:lan1" "switch0" "0x02" "0x0f" -+ ucidef_set_led_switch "lan2" "LAN2" "netgear:green:lan2" "switch0" "0x04" "0x0f" -+ ;; -+wpn824n) -+ ucidef_set_led_netdev "wan-amber" "WAN (amber)" "netgear:amber:wan" "eth0" -+ ucidef_set_led_wlan "wlan" "WLAN" "netgear:blue:wlan" "phy0tpt" -+ ucidef_set_led_switch "lan1amber" "LAN1 (amber)" "netgear:amber:lan1" "switch0" "0x02" -+ ucidef_set_led_switch "lan2amber" "LAN2 (amber)" "netgear:amber:lan2" "switch0" "0x04" -+ ucidef_set_led_switch "lan3amber" "LAN3 (amber)" "netgear:amber:lan3" "switch0" "0x08" -+ ucidef_set_led_switch "lan4amber" "LAN4 (amber)" "netgear:amber:lan4" "switch0" "0x10" -+ ucidef_set_led_default "lan1green" "LAN1 (green)" "netgear:green:lan1" "0" -+ ucidef_set_led_default "lan2green" "LAN2 (green)" "netgear:green:lan2" "0" -+ ucidef_set_led_default "lan3green" "LAN3 (green)" "netgear:green:lan3" "0" -+ ucidef_set_led_default "lan4green" "LAN4 (green)" "netgear:green:lan4" "0" -+ ucidef_set_led_default "wan-green" "WAN (green)" "netgear:green:wan" "0" -+ ucidef_set_led_default "wps1" "WPS1" "netgear:blue:wps1" "0" -+ ucidef_set_led_default "wps2" "WPS2" "netgear:blue:wps2" "0" -+ ucidef_set_led_default "status" "STATUS" "netgear:amber:status" "0" -+ ucidef_set_led_default "test" "TEST" "netgear:amber:test" "0" -+ ;; -+wzr-hp-ag300h) -+ ucidef_set_led_default "diag" "DIAG" "buffalo:red:diag" "0" -+ ucidef_set_led_netdev "router" "ROUTER" "buffalo:green:router" "eth1" -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "buffalo:amber:band2g" "phy0tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN5G" "buffalo:amber:band5g" "phy1tpt" -+ ucidef_set_led_usbport "usb" "USB" "buffalo:green:usb" "usb1-port1" -+ ;; -+wzr-hp-g300nh) -+ ucidef_set_led_wlan "wlan" "Wireless" "buffalo:green:wireless" "phy0tpt" -+ ucidef_set_led_netdev "router" "Router" "buffalo:green:router" "eth1" -+ ucidef_set_led_usbport "usb" "USB" "buffalo:blue:usb" "usb1-port1" -+ ;; -+wzr-hp-g300nh2|\ -+wzr-hp-g450h) -+ ucidef_set_led_wlan "wlan" "Wireless" "buffalo:green:wireless" "phy0tpt" -+ ;; -+xd3200) -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "$board:blue:wlan2g" "phy1tpt" -+ ;; -+z1) -+ ucidef_set_led_netdev "wlan1" "WLAN1" "$board:blue:tricolor0" "wlan1" -+ ;; -+zcn-1523h-2) -+ ucidef_set_led_netdev "lan1" "lan1" "zcn-1523h:green:lan1" "eth0" -+ ;; -+zcn-1523h-5) -+ ucidef_set_led_netdev "lan1" "lan1" "zcn-1523h:green:lan1" "eth0" -+ ucidef_set_led_netdev "lan2" "lan2" "zcn-1523h:green:lan2" "eth1" -+ ;; -+esac -+ -+board_config_flush -+ -+exit 0 -diff --git a/target/linux/ar71xx/base-files/etc/board.d/02_network b/target/linux/ar71xx/base-files/etc/board.d/02_network -new file mode 100755 -index 0000000000..e38f06b88d ---- /dev/null -+++ b/target/linux/ar71xx/base-files/etc/board.d/02_network -@@ -0,0 +1,711 @@ -+#!/bin/sh -+# -+# Copyright (C) 2011-2015 OpenWrt.org -+# -+ -+. /lib/functions/system.sh -+. /lib/functions/uci-defaults.sh -+ -+ar71xx_setup_interfaces() -+{ -+ local board="$1" -+ -+ case "$board" in -+ airgatewaypro) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "4:lan" "5:wan" -+ ;; -+ airrouter|\ -+ ap121|\ -+ ap121-mini|\ -+ ap96|\ -+ dir-600-a1|\ -+ dir-615-c1|\ -+ dir-615-e1|\ -+ dir-615-e4|\ -+ hiwifi-hc6361|\ -+ ja76pf|\ -+ mc-mac1200r|\ -+ minibox-v1|\ -+ mynet-n600|\ -+ oolite-v1|\ -+ oolite-v5.2|\ -+ oolite-v5.2-dev|\ -+ qihoo-c301|\ -+ r602n|\ -+ rb-750|\ -+ rb-751|\ -+ som9331|\ -+ t830|\ -+ tew-632brp|\ -+ tew-712br|\ -+ tew-732br|\ -+ tl-mr3220|\ -+ tl-mr3420|\ -+ tl-wdr3320-v2|\ -+ tl-wdr3500|\ -+ tl-wr740n-v6|\ -+ tl-wr840n-v2|\ -+ tl-wr840n-v3|\ -+ tl-wr841n-v11|\ -+ tl-wr841n-v9|\ -+ tl-wr842n-v3|\ -+ whr-g301n|\ -+ whr-hp-g300n|\ -+ whr-hp-gn|\ -+ wzr-hp-ag300h|\ -+ zbt-we1526) -+ ucidef_set_interfaces_lan_wan "eth0.1" "eth1" -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1" -+ ;; -+ alfa-ap120c|\ -+ all0305|\ -+ antminer-s1|\ -+ antminer-s3|\ -+ antrouter-r1|\ -+ ap121f|\ -+ ap91-5g|\ -+ aw-nr580|\ -+ bullet-m|\ -+ bullet-m-xw|\ -+ c-55|\ -+ cap324|\ -+ cap4200ag|\ -+ cf-e380ac-v1|\ -+ cf-e380ac-v2|\ -+ cpe210-v2|\ -+ cpe210-v3|\ -+ cpe510-v2|\ -+ dr342|\ -+ eap120|\ -+ eap300v2|\ -+ eap7660d|\ -+ el-mini|\ -+ fritz300e|\ -+ fritz450e|\ -+ gl-usb150|\ -+ hiveap-121|\ -+ koala|\ -+ lbe-m5|\ -+ loco-m-xw|\ -+ mr12|\ -+ mr16|\ -+ mr1750|\ -+ mr1750v2|\ -+ mr18|\ -+ mr600|\ -+ mr600v2|\ -+ mr900|\ -+ mr900v2|\ -+ mynet-rext|\ -+ pqi-air-pen|\ -+ rb-411|\ -+ rb-411u|\ -+ rb-911-2hn|\ -+ rb-911-5hn|\ -+ rb-911g-2hpnd|\ -+ rb-911g-5hpacd|\ -+ rb-911g-5hpnd|\ -+ rb-912uag-2hpnd|\ -+ rb-912uag-5hpnd|\ -+ rb-921gs-5hpacd-r2|\ -+ rb-922uags-5hpacd|\ -+ rb-lhg-5nd|\ -+ rb-mapl-2nd|\ -+ rb-sxt2n|\ -+ rb-sxt-2nd-r3|\ -+ rb-sxt5n|\ -+ rb-wap-2nd|\ -+ rb-wapr-2nd|\ -+ rb-wapg-5hact2hnd|\ -+ re355|\ -+ re450|\ -+ rocket-m-xw|\ -+ sc300m |\ -+ tl-mr10u|\ -+ tl-mr11u|\ -+ tl-mr12u|\ -+ tl-mr13u|\ -+ tl-mr3020|\ -+ tl-mr3040|\ -+ tl-mr3040-v2|\ -+ tl-wa701nd-v2|\ -+ tl-wa7210n-v2|\ -+ tl-wa750re|\ -+ tl-wa801nd-v2|\ -+ tl-wa830re-v2|\ -+ tl-wa850re|\ -+ tl-wa850re-v2|\ -+ tl-wa855re-v1|\ -+ tl-wa901nd|\ -+ tl-wa901nd-v2|\ -+ tl-wa901nd-v3|\ -+ tl-wa901nd-v4|\ -+ tl-wa901nd-v5|\ -+ tl-wr703n|\ -+ tl-wr802n-v1|\ -+ tl-wr802n-v2|\ -+ tl-wr902ac-v1|\ -+ ts-d084|\ -+ tube2h|\ -+ unifi|\ -+ unifiac-lite|\ -+ wi2a-ac200i|\ -+ wifi-pineapple-nano|\ -+ wndap360|\ -+ wp543) -+ ucidef_set_interface_wan "eth0" -+ ;; -+ a40|\ -+ a60|\ -+ alfa-ap96|\ -+ alfa-nx|\ -+ dr344|\ -+ gl-ar150|\ -+ gl-ar300m|\ -+ gl-domino|\ -+ gl-inet|\ -+ gl-mifi|\ -+ jwap003|\ -+ om2p-hsv4|\ -+ om2pv4|\ -+ pb42|\ -+ pb44|\ -+ rb-951ui-2hnd|\ -+ routerstation|\ -+ tl-wr710n|\ -+ tl-wr720n-v3|\ -+ tl-wr810n|\ -+ tl-wr810n-v2|\ -+ wpe72|\ -+ wrtnode2q) -+ ucidef_set_interfaces_lan_wan "eth1" "eth0" -+ ;; -+ all0258n|\ -+ all0315n|\ -+ dlan-hotspot|\ -+ dlan-pro-500-wp|\ -+ ja76pf2|\ -+ rocket-m-ti|\ -+ ubnt-unifi-outdoor) -+ ucidef_set_interface_lan "eth0 eth1" -+ ;; -+ wzr-hp-g300nh2) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan:1" "3:lan:2" "4:lan:3" "5:lan:4" "2:wan" -+ ;; -+ ap132|\ -+ ap136|\ -+ ap152|\ -+ rb-750gl|\ -+ rb-751g|\ -+ rb-951g-2hnd|\ -+ rb-962uigs-5hact2hnt|\ -+ wlr8100|\ -+ wzr-hp-g450h) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "2:lan" "3:lan" "4:lan" "5:lan" "1:wan" -+ ;; -+ ap135-020|\ -+ ap136-020|\ -+ bhr-4grv2|\ -+ tew-823dru|\ -+ tl-wr1043nd-v2|\ -+ wzr-450hp2) -+ ucidef_set_interfaces_lan_wan "eth1.1" "eth0.2" -+ ucidef_add_switch "switch0" \ -+ "0@eth1" "1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1" "5:wan" "6@eth0" -+ ;; -+ ap136-010|\ -+ ap147-010|\ -+ nbg6616|\ -+ nbg6716) -+ ucidef_set_interfaces_lan_wan "eth0.1" "eth1.2" -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "6@eth1" -+ ;; -+ ap143|\ -+ rb-433|\ -+ rb-433u) -+ ucidef_set_interfaces_lan_wan "eth1.1" "eth0" -+ ucidef_add_switch "switch0" \ -+ "1:lan" "2:lan" "5@eth1" -+ ;; -+ archer-c5|\ -+ archer-c7|\ -+ tl-wdr4900-v2) -+ ucidef_set_interfaces_lan_wan "eth1.1" "eth0.2" -+ ucidef_add_switch "switch0" \ -+ "0@eth1" "2:lan" "3:lan" "4:lan" "5:lan" "6@eth0" "1:wan" -+ ;; -+ archer-c25-v1|\ -+ archer-c60-v1|\ -+ archer-c60-v2|\ -+ rb-750-r2|\ -+ rb-750p-pbr2|\ -+ rb-750up-r2|\ -+ rb-951ui-2nd|\ -+ rb-952ui-5ac2nd) -+ ucidef_set_interfaces_lan_wan "eth1.1" "eth0" -+ ucidef_add_switch "switch0" \ -+ "0@eth1" "1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1" -+ ;; -+ archer-c58-v1|\ -+ archer-c59-v1|\ -+ archer-c59-v2|\ -+ fritz4020|\ -+ rb-450g) -+ ucidef_set_interfaces_lan_wan "eth1.1" "eth0" -+ ucidef_add_switch "switch0" \ -+ "0@eth1" "1:lan:1" "2:lan:4" "3:lan:3" "4:lan:2" -+ ;; -+ arduino-yun|\ -+ dir-505-a1|\ -+ tl-wa801nd-v3) -+ ucidef_set_interface_lan "eth1" -+ ;; -+ bsb) -+ ucidef_set_interfaces_lan_wan "eth1.1" "eth0" -+ ucidef_add_switch "switch0" \ -+ "0@eth1" "1:lan" "3:lan" -+ ;; -+ c-60) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "3:wan" "4:lan" -+ ;; -+ rme-eg200) -+ ucidef_set_interface_lan "eth0" "dhcp" -+ ;; -+ cf-e375ac|\ -+ rb-map-2nd) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:wan" "2:lan" -+ ;; -+ cf-e385ac) -+ ucidef_set_interfaces_lan_wan "eth0.1" "eth1.2" -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "2:lan" "1:wan" "6@eth1" -+ ;; -+ cpe210|\ -+ cpe510|\ -+ wbs210|\ -+ wbs510) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "5:lan" "4:wan" -+ ;; -+ cr3000) -+ ucidef_set_interfaces_lan_wan "eth0.1" "eth1" -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan:1" "2:lan:4" "3:lan:3" "4:lan:2" -+ ;; -+ cr5000|\ -+ dgl-5500-a1|\ -+ dhp-1565-a1|\ -+ dir-825-c1|\ -+ dir-835-a1|\ -+ esr900|\ -+ mynet-n750|\ -+ sr3200) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan" -+ ;; -+ tl-wr1043n-v5) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1" "5:wan" -+ ;; -+ dap-2695-a1) -+ ucidef_add_switch "switch0" "0@eth0" "2:lan" "3:wan" "6@eth1" -+ ;; -+ rb-931-2nd) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan:3" "2:lan:2" "3:wan:1" -+ ;; -+ rb-941-2nd) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan:4" "2:lan:3" "3:lan:2" "4:wan:1" -+ ;; -+ db120|\ -+ rb-2011il|\ -+ rb-2011ils|\ -+ rb-2011l|\ -+ rb-2011uas|\ -+ rb-2011uas-2hnd|\ -+ rb-2011uias|\ -+ rb-2011uias-2hnd|\ -+ rb-2011uias-2hnd-r2) -+ case "$board" in -+ rb-2011ils|\ -+ rb-2011uas*|\ -+ rb-2011uias|\ -+ rb-2011uias-2hnd|\ -+ rb-2011uias-2hnd-r2) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "2:lan" "3:lan" "4:lan" "5:lan" "1:wan" "6:sfp" -+ ;; -+ *) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "2:lan" "3:lan" "4:lan" "5:lan" "1:wan" -+ ;; -+ esac -+ -+ ucidef_add_switch "switch1" \ -+ "0@eth1" "1:lan" "2:lan" "3:lan" "4:lan" "5:lan" -+ ;; -+ dir-615-i1|\ -+ omy-g1|\ -+ r6100|\ -+ smart-300|\ -+ tl-wdr6500-v2|\ -+ tl-wr940n-v4|\ -+ tl-wr940n-v6|\ -+ tl-wr941nd-v6|\ -+ wnr1000-v2|\ -+ wnr2000-v4|\ -+ wnr2200|\ -+ wnr612-v2|\ -+ wpn824n) -+ ucidef_set_interfaces_lan_wan "eth1.1" "eth0" -+ ucidef_add_switch "switch0" \ -+ "0@eth1" "1:lan:1" "2:lan:2" "3:lan:3" "4:lan:4" -+ ;; -+ tl-mr6400) -+ ucidef_set_interfaces_lan_wan "eth0.1 eth1" "usb0" -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan" "2:lan" "3:lan" -+ ;; -+ dir-825-b1|\ -+ nbg460n_550n_550nh|\ -+ tew-673gru|\ -+ wzr-hp-g300nh) -+ ucidef_set_interfaces_lan_wan "eth0.1" "eth1" -+ ucidef_add_switch "switch0" \ -+ "0:lan" "1:lan" "2:lan" "3:lan" "5@eth0" -+ ;; -+ dlan-pro-1200-ac) -+ ucidef_set_interface_lan "eth0" -+ ucidef_add_switch "switch0" \ -+ "0u@eth0" "2:lan" "3:lan" "4:lan" -+ ucidef_add_switch_attr "switch0" "enable" "false" -+ ;; -+ e1700ac-v2|\ -+ e750g-v8|\ -+ unifiac-pro|\ -+ xd3200) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "2:lan" "3:wan" -+ ;; -+ e558-v2) -+ ucidef_set_interfaces_lan_wan "eth1.1" "eth0.2" -+ ucidef_add_switch "switch0" \ -+ "0@eth1" "4:lan" "5:lan" "6@eth0" "3:wan" -+ ;; -+ ebr-2310-c1) -+ ucidef_set_interfaces_lan_wan "eth0.1" "eth1" -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan:1" "2:lan:2" "3:lan:3" "4:lan:4" -+ ;; -+ el-m150) -+ ucidef_set_interfaces_lan_wan "eth1.1" "eth0" -+ ucidef_add_switch "switch0" \ -+ "0:lan" "1:lan" "3@eth1" -+ ;; -+ dir-869-a1|\ -+ epg5000|\ -+ esr1750|\ -+ tl-wr1043nd-v4|\ -+ wndr3700v4|\ -+ wndr4300) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1" "5:wan" -+ ;; -+ ew-balin) -+ ucidef_set_interface "usb2" ifname "usb0" protocol "static" -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "5:lan:4" "4:lan:5" "3:wan" -+ ;; -+ ew-dorin) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan" "2:lan" "3:wan" -+ ;; -+ ew-dorin-router) -+ ucidef_set_interfaces_lan_wan "eth0.1" "eth1" -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "2:lan" "3:lan" -+ ;; -+ dw33d|\ -+ f9k1115v2) -+ ucidef_set_interfaces_lan_wan "eth1.1" "eth0.2" -+ ucidef_add_switch "switch0" \ -+ "2:lan" "3:lan" "4:lan" "5:lan" "6@eth1" "0@eth0" "1:wan" -+ ;; -+ gl-ar300|\ -+ wnr2000-v3) -+ ucidef_set_interfaces_lan_wan "eth1.1" "eth0" -+ ucidef_add_switch "switch0" \ -+ "0@eth1" "1:lan" "2:lan" "3:lan" "4:lan" -+ ;; -+ gl-ar750|\ -+ rb-435g) -+ ucidef_set_interfaces_lan_wan "eth1.1" "eth0" -+ ucidef_add_switch "switch0" \ -+ "0@eth1" "1:lan" "2:lan" -+ ;; -+ gl-ar750s) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "2:lan:2" "3:lan:1" "1:wan" -+ ;; -+ jwap230) -+ ucidef_set_interfaces_lan_wan "eth0.1" "eth1.2" -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan" "5:wan" "6@eth1" -+ ;; -+ nanostation-m-xw) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "5:lan" "1:wan" -+ ;; -+ onion-omega) -+ ucidef_set_interface_lan "wlan0" -+ ;; -+ rb-450) -+ ucidef_set_interfaces_lan_wan "eth1.1" "eth0" -+ ucidef_add_switch "switch0" \ -+ "0:lan:4" "1:lan:3" "2:lan:2" "3:lan:1" "5@eth1" -+ ;; -+ routerstation-pro) -+ ucidef_set_interfaces_lan_wan "eth1.1" "eth0" -+ ucidef_add_switch "switch0" \ -+ "0@eth1" "2:lan:3" "3:lan:2" "4:lan:1" -+ ;; -+ rb-493g) -+ ucidef_set_interfaces_lan_wan "eth0.1 eth1.1" "eth1.2" -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan:4" "2:lan:1" "3:lan:2" "4:lan:3" -+ ucidef_add_switch "switch1" \ -+ "0@eth1" "1:lan:4" "2:lan:1" "3:lan:3" "4:lan:2" "5:wan" -+ ;; -+ rut900) -+ ucidef_set_interfaces_lan_wan "eth0.1" "eth1" -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "2:lan:3" "3:lan:2" "4:lan:1" -+ ;; -+ tellstick-znet-lite) -+ ucidef_set_interface_wan "eth0" -+ ucidef_set_interface "wlan" ifname "wlan0" protocol "dhcp" -+ ;; -+ tl-mr3420-v2|\ -+ tl-wr841n-v8|\ -+ tl-wr842n-v2|\ -+ tl-wr941nd-v5|\ -+ tl-wr942n-v1) -+ ucidef_set_interfaces_lan_wan "eth1.1" "eth0" -+ ucidef_add_switch "switch0" \ -+ "0@eth1" "1:lan:4" "2:lan:1" "3:lan:2" "4:lan:3" -+ ;; -+ archer-c7-v4|\ -+ archer-c7-v5|\ -+ tl-wdr4300|\ -+ tl-wr1041n-v2) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "2:lan:1" "3:lan:2" "4:lan:3" "5:lan:4" "1:wan" -+ ;; -+ tl-wpa8630) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "2:lan:3" "3:lan:2" "4:lan:1" "5:lan:4" -+ ;; -+ tl-wr1043nd) -+ ucidef_add_switch "switch0" \ -+ "1:lan" "2:lan" "3:lan" "4:lan" "0:wan" "5@eth0" -+ ;; -+ tl-wr2543n) -+ ucidef_add_switch "switch0" \ -+ "1:lan" "2:lan" "3:lan" "4:lan" "0:wan" "9@eth0" -+ ;; -+ tl-mr3220-v2|\ -+ tl-wr741nd-v4) -+ ucidef_set_interfaces_lan_wan "eth0.1" "eth1" -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan:4" "2:lan:1" "3:lan:2" "4:lan:3" -+ ;; -+ tl-wr841n-v1|\ -+ tl-wr941nd) -+ ucidef_set_interface "eth" ifname "eth0" -+ ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "wan" -+ ;; -+ tl-wr741nd|\ -+ tl-wr841n-v7) -+ ucidef_set_interfaces_lan_wan "eth0.1" "eth1" -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan:1" "2:lan:2" "3:lan:3" "4:lan:4" -+ ;; -+ uap-pro|\ -+ wpj342) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan" "2:wan" -+ ;; -+ wndr3700|\ -+ wndr3700v2|\ -+ wndr3800|\ -+ wndr3800ch) -+ ucidef_set_interfaces_lan_wan "eth0.1" "eth1" -+ ucidef_add_switch "switch0" \ -+ "0:lan:4" "1:lan:3" "2:lan:2" "3:lan:1" "5@eth0" -+ -+ ucidef_add_switch_attr "switch0" "blinkrate" 2 -+ ucidef_add_switch_port_attr "switch0" 1 led 6 -+ ucidef_add_switch_port_attr "switch0" 2 led 9 -+ ucidef_add_switch_port_attr "switch0" 5 led 2 -+ ;; -+ wpj344) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "3:lan" "2:wan" -+ ;; -+ wpj558) -+ ucidef_add_switch "switch0" \ -+ "5:lan" "1:wan" "6@eth0" -+ ;; -+ wpj563) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "2:lan" "3:wan" -+ ;; -+ wrt160nl) -+ ucidef_set_interfaces_lan_wan "eth0.1" "eth1" -+ ucidef_add_switch "switch0" \ -+ "0:lan:4" "1:lan:3" "2:lan:2" "3:lan:1" "4@eth0" -+ ;; -+ wzr-hp-g450h) -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "2:lan:1 3:lan:2 4:lan:3 5:lan:4" "1:wan" -+ ;; -+ z1) -+ ucidef_set_interfaces_lan_wan "eth0.1" "eth1" -+ ucidef_add_switch "switch0" \ -+ "0@eth0" "1:lan:1" "2:lan:2" "3:lan:3" "4:lan:4" "5:wan" -+ ;; -+ ens202ext) -+ ucidef_set_interfaces_lan_wan "eth1.1" "eth1.2" -+ ucidef_add_switch "switch0" \ -+ "0@eth1" "2:lan:1" "3:lan:2" "4:lan:3" "5:lan:4" "1:wan" -+ ;; -+ *) -+ ucidef_set_interfaces_lan_wan "eth0" "eth1" -+ ;; -+ esac -+} -+ -+ar71xx_setup_macs() -+{ -+ local board="$1" -+ local lan_mac="" -+ local wan_mac="" -+ -+ case $board in -+ archer-c7-v4) -+ base_mac=$(mtd_get_mac_binary config 0x8) -+ wan_mac=$(macaddr_add "$base_mac" 1) -+ ;; -+ archer-c7-v5) -+ base_mac=$(mtd_get_mac_binary info 0x8) -+ wan_mac=$(macaddr_add "$base_mac" 1) -+ ;; -+ dgl-5500-a1|\ -+ dir-825-c1) -+ wan_mac=$(mtd_get_mac_ascii nvram "wan_mac") -+ ;; -+ dhp-1565-a1|\ -+ dir-835-a1|\ -+ wndr3700v4|\ -+ wndr4300) -+ lan_mac=$(mtd_get_mac_binary caldata 0x0) -+ wan_mac=$(mtd_get_mac_binary caldata 0x6) -+ ;; -+ dir-869-a1|\ -+ mynet-n750) -+ wan_mac=$(mtd_get_mac_ascii devdata "wanmac") -+ ;; -+ esr900) -+ wan_mac=$(mtd_get_mac_ascii u-boot-env "wanaddr") -+ ;; -+ fritz300e) -+ lan_mac=$(fritz_tffs -n maca -i $(find_mtd_part "tffs (1)")) -+ ;; -+ tl-wdr4300) -+ base_mac=$(mtd_get_mac_binary u-boot 0x1fc00) -+ wan_mac=$(macaddr_add "$base_mac" 1) -+ ;; -+ tl-wr1043n-v5|\ -+ tl-wr1043nd-v4) -+ lan_mac=$(mtd_get_mac_binary product-info 0x8) -+ wan_mac=$(macaddr_add "$lan_mac" 1) -+ ;; -+ wlr8100) -+ lan_mac=$(mtd_get_mac_ascii u-boot-env "ethaddr") -+ wan_mac=$(mtd_get_mac_ascii u-boot-env "wanaddr") -+ ;; -+ wpj344|\ -+ wpj558) -+ wan_mac=$(mtd_get_mac_binary u-boot 0x2e018) -+ ;; -+ esac -+ -+ [ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac -+ [ -n "$wan_mac" ] && ucidef_set_interface_macaddr "wan" $wan_mac -+} -+ -+ar71xx_setup_ar8xxx_switch() -+{ -+ local board="$1" -+ -+ case $board in -+ ap147-010|\ -+ archer-c25-v1|\ -+ archer-c58-v1|\ -+ archer-c59-v1|\ -+ archer-c59-v2|\ -+ archer-c60-v1|\ -+ archer-c60-v2|\ -+ archer-c7-v4|\ -+ archer-c7-v5|\ -+ cf-e375ac|\ -+ cf-e385ac|\ -+ cr3000|\ -+ dhp-1565-a1|\ -+ mynet-n600|\ -+ rb-2011il|\ -+ rb-2011ils|\ -+ rb-2011l|\ -+ rb-2011uas|\ -+ rb-2011uas-2hnd|\ -+ rb-2011uias|\ -+ rb-2011uias-2hnd|\ -+ rb-2011uias-2hnd-r2|\ -+ rb-750|\ -+ rb-750p-pbr2|\ -+ rb-750-r2|\ -+ rb-750up-r2|\ -+ rb-951ui-2nd|\ -+ rb-952ui-5ac2nd|\ -+ rb-map-2nd|\ -+ tl-wr1043nd-v4|\ -+ tl-wr1043n-v5|\ -+ wndr3700v4|\ -+ wndr3700v4|\ -+ wndr4300|\ -+ wnr1000-v2|\ -+ wnr2000-v3|\ -+ wnr2200|\ -+ wnr612-v2|\ -+ wpn824n) -+ ucidef_set_ar8xxx_switch_mib "switch0" 0 500 -+ ;; -+ esac -+} -+ -+board_config_update -+board=$(board_name) -+ar71xx_setup_interfaces $board -+ar71xx_setup_macs $board -+ar71xx_setup_ar8xxx_switch $board -+board_config_flush -+ -+exit 0 -diff --git a/target/linux/ar71xx/base-files/etc/board.d/03_gpio_switches b/target/linux/ar71xx/base-files/etc/board.d/03_gpio_switches -new file mode 100755 -index 0000000000..3bb2f635a3 ---- /dev/null -+++ b/target/linux/ar71xx/base-files/etc/board.d/03_gpio_switches -@@ -0,0 +1,42 @@ -+#!/bin/sh -+# -+# Copyright (C) 2015 OpenWrt.org -+# -+ -+. /lib/functions/uci-defaults.sh -+ -+board_config_update -+ -+board=$(board_name) -+ -+case "$board" in -+cpe210|\ -+cpe510|\ -+wbs210|\ -+wbs510) -+ ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "20" -+ ;; -+nanostation-m) -+ ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "8" -+ ;; -+nanostation-m-xw) -+ ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "2" -+ ;; -+rb-912uag-2hpnd|\ -+rb-912uag-5hpnd) -+ ucidef_add_gpio_switch "usb_power_switch" "USB Power Switch" "61" "1" -+ ;; -+rb-750up-r2|\ -+rb-951ui-2nd|\ -+rb-952ui-5ac2nd) -+ ucidef_add_gpio_switch "usb_power_switch" "USB Power Switch" "45" "1" -+ ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "14" -+ ;; -+rb-750p-pbr2) -+ ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "14" -+ ;; -+esac -+ -+board_config_flush -+ -+exit 0 -diff --git a/target/linux/ar71xx/base-files/etc/diag.sh b/target/linux/ar71xx/base-files/etc/diag.sh -new file mode 100644 -index 0000000000..1a92ad927d ---- /dev/null -+++ b/target/linux/ar71xx/base-files/etc/diag.sh -@@ -0,0 +1,599 @@ -+#!/bin/sh -+# Copyright (C) 2009-2013 OpenWrt.org -+ -+. /lib/functions.sh -+. /lib/functions/leds.sh -+ -+get_status_led() { -+ local board=$(board_name) -+ -+ case $board in -+ a40) -+ status_led="a40:green:status" -+ ;; -+ a60) -+ status_led="a60:green:status" -+ ;; -+ alfa-nx) -+ status_led="alfa:green:led_8" -+ ;; -+ all0305) -+ status_led="eap7660d:green:ds4" -+ ;; -+ antminer-s1|\ -+ antminer-s3|\ -+ antminer-r1|\ -+ e1700ac-v2|\ -+ e558-v2|\ -+ e600gac-v2|\ -+ e750a-v4|\ -+ e750g-v8|\ -+ eap120|\ -+ minibox-v1|\ -+ minibox-v3.2|\ -+ packet-squirrel|\ -+ som9331|\ -+ sr3200|\ -+ tl-wr802n-v2|\ -+ xd3200) -+ status_led="$board:green:system" -+ ;; -+ ap121f) -+ status_led="$board:green:vpn" -+ ;; -+ ap132|\ -+ ap531b0|\ -+ cpe505n|\ -+ db120|\ -+ dr342|\ -+ dr344|\ -+ rut900|\ -+ tew-632brp|\ -+ tl-wr942n-v1|\ -+ wpj344|\ -+ zbt-we1526) -+ status_led="$board:green:status" -+ ;; -+ ap136-010|\ -+ ap136-020) -+ status_led="ap136:green:status" -+ ;; -+ ap147-010) -+ status_led="ap147:green:status" -+ ;; -+ ap135-020) -+ status_led="ap135:green:status" -+ ;; -+ archer-c25-v1|\ -+ archer-c58-v1|\ -+ archer-c59-v1|\ -+ archer-c59-v2|\ -+ archer-c60-v1|\ -+ archer-c60-v2|\ -+ archer-c7-v4|\ -+ archer-c7-v5|\ -+ fritz300e|\ -+ fritz4020|\ -+ fritz450e|\ -+ gl-ar750s|\ -+ gl-usb150|\ -+ mr12|\ -+ mr16|\ -+ nbg6616|\ -+ sc1750|\ -+ sc450|\ -+ tl-wpa8630|\ -+ tl-wr902ac-v1) -+ status_led="$board:green:power" -+ ;; -+ tl-mr10u|\ -+ tl-mr12u|\ -+ tl-mr13u|\ -+ tl-wdr4300|\ -+ tl-wdr4900-v2|\ -+ tl-wr703n|\ -+ tl-wr710n|\ -+ tl-wr720n-v3|\ -+ tl-wr802n-v1|\ -+ tl-wr810n|\ -+ tl-wr810n-v2|\ -+ tl-wr940n-v4|\ -+ tl-wr941nd-v6) -+ status_led="tp-link:blue:system" -+ ;; -+ ap90q|\ -+ cpe830|\ -+ cpe870|\ -+ gl-ar300m|\ -+ gl-inet|\ -+ gl-mifi) -+ status_led="$board:green:lan" -+ ;; -+ ap91-5g|\ -+ n5q) -+ status_led="$board:green:signal4" -+ ;; -+ ap96) -+ status_led="$board:green:led2" -+ ;; -+ aw-nr580) -+ status_led="$board:green:ready" -+ ;; -+ bhr-4grv2|\ -+ wzr-hp-ag300h|\ -+ wzr-hp-g300nh2) -+ status_led="buffalo:red:diag" -+ ;; -+ bsb) -+ status_led="$board:red:sys" -+ ;; -+ bullet-m|\ -+ bullet-m-xw|\ -+ loco-m-xw|\ -+ nano-m|\ -+ nanostation-m|\ -+ nanostation-m-xw|\ -+ rocket-m|\ -+ rocket-m-xw) -+ status_led="ubnt:green:link4" -+ ;; -+ bxu2000n-2-a1) -+ status_led="bhu:green:status" -+ ;; -+ cap324) -+ status_led="pcs:green:power" -+ ;; -+ c-55|\ -+ c-60) -+ status_led="$board:green:pwr" -+ ;; -+ cap4200ag) -+ status_led="senao:green:pwr" -+ ;; -+ cf-e316n-v2|\ -+ cf-e520n|\ -+ cf-e530n) -+ status_led="$board:blue:wan" -+ ;; -+ cf-e320n-v2) -+ status_led="$board:blue:wlan" -+ ;; -+ cf-e375ac|\ -+ cf-e380ac-v1|\ -+ cf-e380ac-v2|\ -+ cf-e385ac) -+ status_led="$board:blue:wlan2g" -+ ;; -+ cpe510) -+ status_led="tp-link:green:link4" -+ ;; -+ cr3000|\ -+ cr5000) -+ status_led="pcs:amber:power" -+ ;; -+ dap-1330-a1|\ -+ dgl-5500-a1|\ -+ dhp-1565-a1|\ -+ dir-505-a1|\ -+ dir-600-a1|\ -+ dir-615-e1|\ -+ dir-615-i1|\ -+ dir-615-e4) -+ status_led="d-link:green:power" -+ ;; -+ dir-615-c1) -+ status_led="d-link:green:status" -+ ;; -+ dir-825-b1) -+ status_led="d-link:orange:power" -+ ;; -+ dir-825-c1|\ -+ dir-835-a1) -+ status_led="d-link:amber:power" -+ ;; -+ dir-869-a1) -+ status_led="d-link:white:status" -+ ;; -+ dlan-hotspot) -+ status_led="devolo:green:wifi" -+ ;; -+ dlan-pro-500-wp) -+ status_led="devolo:green:wlan-2g" -+ ;; -+ dlan-pro-1200-ac) -+ status_led="devolo:status:wlan" -+ ;; -+ dr531) -+ status_led="$board:green:sig4" -+ ;; -+ dragino2|\ -+ oolite-v1) -+ status_led="$board:red:system" -+ ;; -+ dw33d|\ -+ r36a) -+ status_led="$board:blue:status" -+ ;; -+ e600g-v2|\ -+ oolite-v5.2-dev|\ -+ ts-d084|\ -+ wifi-pineapple-nano) -+ status_led="$board:blue:system" -+ ;; -+ eap300v2) -+ status_led="engenius:blue:power" -+ ;; -+ ens202ext|\ -+ esr900) -+ status_led="engenius:amber:power" -+ ;; -+ eap7660d) -+ status_led="$board:green:ds4" -+ ;; -+ el-m150|\ -+ el-mini) -+ status_led="easylink:green:system" -+ ;; -+ ew-balin) -+ status_led="balin:green:status" -+ ;; -+ ew-dorin|\ -+ ew-dorin-router) -+ status_led="dorin:green:status" -+ ;; -+ f9k1115v2) -+ status_led="belkin:blue:status" -+ ;; -+ epg5000|\ -+ esr1750) -+ status_led="$board:amber:power" -+ ;; -+ gl-ar750|\ -+ hiveap-121|\ -+ nbg6716|\ -+ wam250) -+ status_led="$board:white:power" -+ ;; -+ hiwifi-hc6361) -+ status_led="hiwifi:blue:system" -+ ;; -+ hornet-ub|\ -+ hornet-ub-x2) -+ status_led="alfa:blue:wps" -+ ;; -+ ja76pf|\ -+ ja76pf2) -+ status_led="jjplus:green:led1" -+ ;; -+ jwap230) -+ status_led="$board:green:led1" -+ ;; -+ koala) -+ status_led="$board:blue:sys" -+ ;; -+ lan-turtle) -+ status_led="$board:orange:system" -+ ;; -+ lbe-m5) -+ status_led="ubnt:green:sys" -+ ;; -+ ls-sr71) -+ status_led="ubnt:green:d22" -+ ;; -+ mc-mac1200r) -+ status_led="mercury:green:system" -+ ;; -+ mr18|\ -+ z1) -+ status_led="$board:green:tricolor0" -+ ;; -+ mr600) -+ status_led="$board:orange:power" -+ ;; -+ mr600v2) -+ status_led="mr600:blue:power" -+ ;; -+ mr1750|\ -+ mr1750v2) -+ status_led="mr1750:blue:power" -+ ;; -+ mr900|\ -+ mr900v2) -+ status_led="mr900:blue:power" -+ ;; -+ mynet-n600|\ -+ mynet-n750|\ -+ mynet-rext) -+ status_led="wd:blue:power" -+ ;; -+ mzk-w04nu|\ -+ mzk-w300nh) -+ status_led="planex:green:status" -+ ;; -+ nbg460n_550n_550nh) -+ status_led="nbg460n:green:power" -+ ;; -+ om2p|\ -+ om2p-hs|\ -+ om2p-hsv2|\ -+ om2p-hsv3|\ -+ om2p-hsv4|\ -+ om2p-lc|\ -+ om2pv2|\ -+ om2pv4) -+ status_led="om2p:blue:power" -+ ;; -+ om5p|\ -+ om5p-an) -+ status_led="om5p:blue:power" -+ ;; -+ om5p-ac|\ -+ om5p-acv2) -+ status_led="om5pac:blue:power" -+ ;; -+ omy-g1) -+ status_led="omy:green:wlan" -+ ;; -+ omy-x1) -+ status_led="omy:green:power" -+ ;; -+ onion-omega) -+ status_led="onion:amber:system" -+ ;; -+ pb44) -+ status_led="$board:amber:jump1" -+ ;; -+ r602n) -+ status_led="$board:green:wan" -+ ;; -+ rb-2011il|\ -+ rb-2011ils|\ -+ rb-2011l|\ -+ rb-2011uas|\ -+ rb-2011uas-2hnd) -+ status_led="rb:green:usr" -+ ;; -+ rb-411|\ -+ rb-411u|\ -+ rb-433|\ -+ rb-433u|\ -+ rb-450|\ -+ rb-450g|\ -+ rb-493) -+ status_led="rb4xx:yellow:user" -+ ;; -+ rb-750) -+ status_led="rb750:green:act" -+ ;; -+ rb-750-r2|\ -+ rb-750p-pbr2|\ -+ rb-750up-r2|\ -+ rb-911-2hn|\ -+ rb-911-5hn|\ -+ rb-911g-2hpnd|\ -+ rb-911g-5hpacd|\ -+ rb-911g-5hpnd|\ -+ rb-931-2nd|\ -+ rb-941-2nd|\ -+ rb-951ui-2nd|\ -+ rb-952ui-5ac2nd|\ -+ rb-962uigs-5hact2hnt|\ -+ rb-lhg-5nd|\ -+ rb-map-2nd|\ -+ rb-mapl-2nd|\ -+ rb-sxt-2nd-r3|\ -+ rb-wap-2nd|\ -+ rb-wapr-2nd) -+ status_led="rb:green:user" -+ ;; -+ rb-951ui-2hnd) -+ status_led="rb:green:act" -+ ;; -+ rb-912uag-2hpnd|\ -+ rb-912uag-5hpnd|\ -+ rb-sxt2n|\ -+ rb-sxt5n|\ -+ rb-wapg-5hact2hnd) -+ status_led="rb:green:power" -+ ;; -+ re355|\ -+ re450|\ -+ sc300m) -+ status_led="$board:blue:power" -+ ;; -+ rocket-m-ti) -+ status_led="ubnt:green:link6" -+ ;; -+ routerstation|\ -+ routerstation-pro) -+ status_led="ubnt:green:rf" -+ ;; -+ rw2458n) -+ status_led="$board:green:d3" -+ ;; -+ smart-300) -+ status_led="nc-link:green:system" -+ ;; -+ qihoo-c301) -+ status_led="qihoo:green:status" -+ ;; -+ t830) -+ status_led="$board:green:usb" -+ ;; -+ tellstick-znet-lite) -+ status_led="tellstick:white:system" -+ ;; -+ tew-673gru) -+ status_led="trendnet:blue:wps" -+ ;; -+ tew-712br|\ -+ tew-732br|\ -+ tew-823dru) -+ status_led="trendnet:green:power" -+ ;; -+ tl-mr3020|\ -+ tl-wr2543n) -+ status_led="tp-link:green:wps" -+ ;; -+ tl-wa750re) -+ status_led="tp-link:orange:re" -+ ;; -+ tl-wa850re|\ -+ tl-wa850re-v2) -+ status_led="tp-link:blue:re" -+ ;; -+ tl-wa855re-v1|\ -+ tl-wa860re) -+ status_led="tp-link:green:power" -+ ;; -+ tl-mr6400) -+ status_led="tp-link:white:power" -+ ;; -+ archer-c5|\ -+ archer-c7|\ -+ tl-mr3220|\ -+ tl-mr3220-v2|\ -+ tl-mr3420|\ -+ tl-mr3420-v2|\ -+ tl-wa701nd-v2|\ -+ tl-wa801nd-v2|\ -+ tl-wa801nd-v3|\ -+ tl-wa830re-v2|\ -+ tl-wa901nd|\ -+ tl-wa901nd-v2|\ -+ tl-wa901nd-v3|\ -+ tl-wa901nd-v4|\ -+ tl-wa901nd-v5|\ -+ tl-wdr3320-v2|\ -+ tl-wdr3500|\ -+ tl-wr1041n-v2|\ -+ tl-wr1043n-v5|\ -+ tl-wr1043nd|\ -+ tl-wr1043nd-v2|\ -+ tl-wr1043nd-v4|\ -+ tl-wr740n-v6|\ -+ tl-wr741nd|\ -+ tl-wr741nd-v4|\ -+ tl-wr840n-v2|\ -+ tl-wr840n-v3|\ -+ tl-wr841n-v1|\ -+ tl-wr841n-v7|\ -+ tl-wr841n-v8|\ -+ tl-wr841n-v11|\ -+ tl-wr842n-v2|\ -+ tl-wr842n-v3|\ -+ tl-wr941nd|\ -+ tl-wr941nd-v5) -+ status_led="tp-link:green:system" -+ ;; -+ tl-wr841n-v9) -+ status_led="tp-link:green:qss" -+ ;; -+ tl-wr940n-v6) -+ status_led="tp-link:orange:diag" -+ ;; -+ tl-wdr6500-v2) -+ status_led="tp-link:white:system" -+ ;; -+ tube2h) -+ status_led="alfa:green:signal4" -+ ;; -+ unifi) -+ status_led="ubnt:green:dome" -+ ;; -+ uap-pro|\ -+ unifiac-lite|\ -+ unifiac-pro) -+ status_led="ubnt:white:dome" -+ ;; -+ unifi-outdoor-plus) -+ status_led="ubnt:white:front" -+ ;; -+ airgateway|\ -+ airgatewaypro) -+ status_led="ubnt:white:status" -+ ;; -+ wi2a-ac200i) -+ status_led="nokia:green:ctrl" -+ ;; -+ whr-g301n|\ -+ whr-hp-g300n|\ -+ whr-hp-gn|\ -+ wzr-hp-g300nh) -+ status_led="buffalo:green:router" -+ ;; -+ wlae-ag300n) -+ status_led="buffalo:green:status" -+ ;; -+ r6100|\ -+ wndap360|\ -+ wndr3700|\ -+ wndr3700v4|\ -+ wndr4300|\ -+ wnr2000|\ -+ wnr2000-v3|\ -+ wnr2200|\ -+ wnr612-v2|\ -+ wnr1000-v2|\ -+ wpn824n) -+ status_led="netgear:green:power" -+ ;; -+ wp543) -+ status_led="$board:green:diag" -+ ;; -+ wpj342|\ -+ wpj531|\ -+ wpj558) -+ status_led="$board:green:sig3" -+ ;; -+ wpj563) -+ status_led="$board:green:sig1" -+ ;; -+ wrt160nl|\ -+ wrt400n) -+ status_led="$board:blue:wps" -+ ;; -+ zcn-1523h-2|\ -+ zcn-1523h-5) -+ status_led="zcn-1523h:amber:init" -+ ;; -+ wlr8100) -+ status_led="sitecom:amber:status" -+ ;; -+ esac -+} -+ -+set_state() { -+ get_status_led -+ -+ case "$1" in -+ preinit) -+ status_led_blink_preinit -+ ;; -+ failsafe) -+ status_led_blink_failsafe -+ ;; -+ preinit_regular) -+ status_led_blink_preinit_regular -+ ;; -+ upgrade) -+ status_led_blink_preinit_regular -+ ;; -+ done) -+ status_led_on -+ case $(board_name) in -+ gl-ar300m|\ -+ gl-ar750) -+ fw_printenv lc >/dev/null 2>&1 && fw_setenv "bootcount" 0 -+ ;; -+ qihoo-c301) -+ local n=$(fw_printenv activeregion | cut -d = -f 2) -+ fw_setenv "image${n}trynum" 0 -+ ;; -+ wi2a-ac200i) -+ fw_setenv PKRstCnt 0 -+ ;; -+ esac -+ ;; -+ esac -+} -diff --git a/target/linux/ar71xx/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom b/target/linux/ar71xx/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom -new file mode 100644 -index 0000000000..8fe57c87cc ---- /dev/null -+++ b/target/linux/ar71xx/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom -@@ -0,0 +1,178 @@ -+#!/bin/sh -+ -+[ -e /lib/firmware/$FIRMWARE ] && exit 0 -+ -+. /lib/functions.sh -+. /lib/functions/system.sh -+ -+ath9k_eeprom_die() { -+ echo "ath9k eeprom: " "$*" -+ exit 1 -+} -+ -+ath9k_eeprom_extract() { -+ local part=$1 -+ local offset=$(($2)) -+ local count=$(($3)) -+ local mtd -+ -+ mtd=$(find_mtd_chardev $part) -+ [ -n "$mtd" ] || \ -+ ath9k_eeprom_die "no mtd device found for partition $part" -+ -+ dd if=$mtd of=/lib/firmware/$FIRMWARE iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null || \ -+ ath9k_eeprom_die "failed to extract from $mtd" -+} -+ -+ath9k_ubi_eeprom_extract() { -+ local part=$1 -+ local offset=$(($2)) -+ local count=$(($3)) -+ local ubidev=$(nand_find_ubi $CI_UBIPART) -+ local ubi -+ -+ ubi=$(nand_find_volume $ubidev $part) -+ [ -n "$ubi" ] || \ -+ ath9k_eeprom_die "no UBI volume found for $part" -+ -+ dd if=/dev/$ubi of=/lib/firmware/$FIRMWARE iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null || \ -+ ath9k_eeprom_die "failed to extract from $ubi" -+} -+ -+ath9k_eeprom_extract_reverse() { -+ local part=$1 -+ local offset=$2 -+ local count=$(($3)) -+ local mtd -+ local reversed -+ local caldata -+ -+ mtd=$(find_mtd_chardev "$part") -+ reversed=$(hexdump -v -s $offset -n $count -e '/1 "%02x "' $mtd) -+ -+ for byte in $reversed; do -+ caldata="\x${byte}${caldata}" -+ done -+ -+ printf "%b" "$caldata" > /lib/firmware/$FIRMWARE -+} -+ -+ath9k_patch_firmware_mac() { -+ local mac=$1 -+ -+ [ -z "$mac" ] && return -+ -+ macaddr_2bin $mac | dd of=/lib/firmware/$FIRMWARE conv=notrunc oflag=seek_bytes bs=6 seek=2 count=1 -+} -+ -+board=$(board_name) -+ -+case "$FIRMWARE" in -+"soc_wmac.eeprom") -+ case $board in -+ c-55|\ -+ c-60) -+ ath9k_eeprom_extract "art" 0x1000 0x800 -+ ath9k_patch_firmware_mac $(macaddr_add $(mtd_get_mac_binary art 0x0) +1) -+ ;; -+ fritz4020|\ -+ fritz450e) -+ ath9k_eeprom_extract_reverse "urlader" 0x1541 0x440 -+ ;; -+ mr18) -+ . /lib/upgrade/nand.sh -+ -+ if [ -n "$(nand_find_volume ubi0 caldata)" ]; then -+ ath9k_ubi_eeprom_extract "caldata" 0x1000 0x800 -+ else -+ ath9k_eeprom_extract "odm-caldata" 0x1000 0x800 -+ fi -+ ath9k_patch_firmware_mac $(macaddr_add $(mtd_get_mac_binary_ubi board-config 0x66) +1) -+ ;; -+ r6100 | \ -+ wndr3700v4 | \ -+ wndr4300) -+ ath9k_eeprom_extract "caldata" 0x1000 0x800 -+ ath9k_patch_firmware_mac $(mtd_get_mac_binary caldata 0x0) -+ ;; -+ rambutan) -+ ath9k_eeprom_extract "art" 0x1000 0x800 -+ ;; -+ wlr8100) -+ ath9k_eeprom_extract "art" 0x1000 0x800 -+ ath9k_patch_firmware_mac $(mtd_get_mac_ascii u-boot-env "ethaddr") -+ ;; -+ z1) -+ . /lib/upgrade/nand.sh -+ -+ if [ -n "$(nand_find_volume ubi0 caldata)" ]; then -+ ath9k_ubi_eeprom_extract "caldata" 0x1000 0x800 -+ else -+ ath9k_eeprom_extract "origcaldata" 0x1000 0x800 -+ fi -+ ath9k_patch_firmware_mac $(macaddr_add $(mtd_get_mac_binary_ubi board-config 0x66) +2) -+ ;; -+ *) -+ ath9k_eeprom_die "board $board is not supported yet" -+ ;; -+ esac -+ ;; -+ -+"pci_wmac0.eeprom") -+ case $board in -+ c-55) -+ ath9k_eeprom_extract "art" 0x5000 0x800 -+ ath9k_patch_firmware_mac $(macaddr_add $(mtd_get_mac_binary art 0x0) +2) -+ ;; -+ fritz300e) -+ ath9k_eeprom_extract_reverse "urloader" 0x1541 0x440 -+ ;; -+ mr18) -+ . /lib/upgrade/nand.sh -+ -+ if [ -n "$(nand_find_volume ubi0 caldata)" ]; then -+ ath9k_ubi_eeprom_extract "caldata" 0x5000 0x800 -+ else -+ ath9k_eeprom_extract "odm-caldata" 0x5000 0x800 -+ fi -+ ath9k_patch_firmware_mac $(macaddr_add $(mtd_get_mac_binary_ubi board-config 0x66) +2) -+ ;; -+ wndr3700v4 | \ -+ wndr4300) -+ ath9k_eeprom_extract "caldata" 0x5000 0x800 -+ ath9k_patch_firmware_mac $(mtd_get_mac_binary caldata 0xc) -+ ;; -+ z1) -+ . /lib/upgrade/nand.sh -+ -+ if [ -n "$(nand_find_volume ubi0 caldata)" ]; then -+ ath9k_ubi_eeprom_extract "caldata" 0x15000 0x1000 -+ else -+ ath9k_eeprom_extract "origcaldata" 0x15000 0x1000 -+ fi -+ ath9k_patch_firmware_mac $(macaddr_add $(mtd_get_mac_binary_ubi board-config 0x66) +3) -+ ;; -+ *) -+ ath9k_eeprom_die "board $board is not supported yet" -+ ;; -+ esac -+ ;; -+ -+"pci_wmac1.eeprom") -+ case $board in -+ mr18) -+ . /lib/upgrade/nand.sh -+ -+ if [ -n "$(nand_find_volume ubi0 caldata)" ]; then -+ ath9k_ubi_eeprom_extract "caldata" 0x9000 0x800 -+ else -+ ath9k_eeprom_extract "odm-caldata" 0x9000 0x800 -+ fi -+ ath9k_patch_firmware_mac $(macaddr_add $(mtd_get_mac_binary_ubi board-config 0x66) +3) -+ ;; -+ *) -+ ath9k_eeprom_die "board $board is not supported yet" -+ ;; -+ esac -+ ;; -+esac -diff --git a/target/linux/ar71xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ar71xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata -new file mode 100644 -index 0000000000..c0e8f17d94 ---- /dev/null -+++ b/target/linux/ar71xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata -@@ -0,0 +1,195 @@ -+#!/bin/sh -+ -+ath10kcal_die() { -+ echo "ath10cal: " "$*" -+ exit 1 -+} -+ -+ath10kcal_from_file() { -+ local source=$1 -+ local offset=$(($2)) -+ local count=$(($3)) -+ -+ dd if=$source of=/lib/firmware/$FIRMWARE iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null || \ -+ ath10kcal_die "failed to extract calibration data from $source" -+} -+ -+ath10kcal_extract() { -+ local part=$1 -+ local offset=$(($2)) -+ local count=$(($3)) -+ local mtd cal_size -+ -+ mtd=$(find_mtd_chardev $part) -+ [ -n "$mtd" ] || \ -+ ath10kcal_die "no mtd device found for partition $part" -+ -+ # Check that the calibration data size in header equals the desired size -+ cal_size=$(dd if=$mtd bs=2 count=1 skip=$(( $offset / 2 )) conv=swab 2>/dev/null | hexdump -ve '1/2 "%d"') -+ -+ [ "$count" = "$cal_size" ] || \ -+ ath10kcal_die "no calibration data found in $part" -+ -+ dd if=$mtd of=/lib/firmware/$FIRMWARE iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null || \ -+ ath10kcal_die "failed to extract calibration data from $mtd" -+} -+ -+ath10kcal_patch_mac() { -+ local mac=$1 -+ -+ [ -z "$mac" ] && return -+ -+ macaddr_2bin $mac | dd of=/lib/firmware/$FIRMWARE conv=notrunc oflag=seek_bytes bs=6 seek=6 count=1 -+} -+ -+[ -e /lib/firmware/$FIRMWARE ] && exit 0 -+ -+. /lib/functions.sh -+. /lib/functions/system.sh -+ -+board=$(board_name) -+ -+case "$FIRMWARE" in -+"ath10k/cal-pci-0000:00:00.0.bin") -+ case $board in -+ a40|\ -+ a60|\ -+ mr1750|\ -+ mr1750v2|\ -+ om5p-acv2) -+ ath10kcal_extract "ART" 0x5000 0x844 -+ ath10kcal_patch_mac $(macaddr_add $(cat /sys/class/net/eth0/address) +16) -+ ;; -+ archer-c25-v1|\ -+ tl-wdr6500-v2) -+ ath10kcal_extract "art" 0x5000 0x844 -+ ath10kcal_patch_mac $(macaddr_add $(cat /sys/class/net/eth1/address) -2) -+ ;; -+ archer-c7-v4|\ -+ archer-c7-v5) -+ ath10kcal_extract "art" 0x5000 0x844 -+ ath10kcal_patch_mac $(macaddr_add $(cat /sys/class/net/eth0/address) -1) -+ ;; -+ cf-e355ac-v1|\ -+ cf-e380ac-v1|\ -+ cf-e380ac-v2|\ -+ dlan-pro-1200-ac|\ -+ e1700ac-v2|\ -+ e600gac-v2|\ -+ minibox-v3.2|\ -+ oolite-v5.2|\ -+ oolite-v5.2-dev|\ -+ sr3200|\ -+ xd3200) -+ ath10kcal_extract "art" 0x5000 0x844 -+ ;; -+ dap-2695-a1) -+ ath10kcal_extract "radiocfg" 0x5000 0x844 -+ ath10kcal_patch_mac $(mtd_get_mac_ascii bdcfg wlanmac_a) -+ ;; -+ dir-869-a1|\ -+ qihoo-c301) -+ ath10kcal_extract "radiocfg" 0x5000 0x844 -+ ath10kcal_patch_mac $(mtd_get_mac_ascii devdata wlan5mac) -+ ;; -+ dw33d) -+ ath10kcal_extract "art" 0x5000 0x844 -+ ath10kcal_patch_mac $(mtd_get_mac_binary art 0x12) -+ ;; -+ epg5000|\ -+ esr1750) -+ ath10kcal_extract "caldata" 0x5000 0x844 -+ ath10kcal_patch_mac $(macaddr_add $(cat /sys/class/net/eth0/address) +1) -+ ;; -+ gl-ar750s|\ -+ gl-ar750|\ -+ tl-wpa8630) -+ ath10kcal_extract "art" 0x5000 0x844 -+ ath10kcal_patch_mac $(macaddr_add $(cat /sys/class/net/eth0/address) +1) -+ ;; -+ koala) -+ ath10kcal_extract "art" 0x5000 0x844 -+ ath10kcal_patch_mac $(macaddr_add $(mtd_get_mac_binary art 0xc) +0) -+ ;; -+ mc-mac1200r) -+ ath10kcal_extract "art" 0x5000 0x844 -+ ath10kcal_patch_mac $(macaddr_add $(cat /sys/class/net/eth1/address) -1) -+ ;; -+ r6100) -+ ath10kcal_extract "caldata" 0x5000 0x844 -+ ath10kcal_patch_mac $(macaddr_add $(cat /sys/class/net/eth1/address) +2) -+ ;; -+ rb-952ui-5ac2nd|\ -+ rb-wapg-5hact2hnd) -+ ath10kcal_from_file "/sys/firmware/mikrotik/hard_config/wlan_data" 0x5000 0x844 -+ ;; -+ re355|\ -+ re450|\ -+ tl-wr902ac-v1) -+ ath10kcal_extract "art" 0x5000 0x844 -+ ath10kcal_patch_mac $(macaddr_add $(cat /sys/class/net/eth0/address) -2) -+ ;; -+ unifiac-lite|\ -+ unifiac-pro) -+ ath10kcal_extract "EEPROM" 0x5000 0x844 -+ ;; -+ wi2a-ac200i) -+ ath10kcal_extract "ART" 0x5000 0x844 -+ ;; -+ esac -+ ;; -+"ath10k/cal-pci-0000:01:00.0.bin") -+ case $board in -+ archer-c5|\ -+ archer-c7) -+ ath10kcal_extract "art" 0x5000 0x844 -+ ath10kcal_patch_mac $(macaddr_add $(cat /sys/class/net/eth1/address) -1) -+ ;; -+ nbg6616|\ -+ nbg6716) -+ ath10kcal_extract "RFdata" 0x5000 0x844 -+ ath10kcal_patch_mac $(macaddr_add $(cat /sys/class/net/eth1/address) -2) -+ ;; -+ om5p-ac) -+ ath10kcal_extract "ART" 0x5000 0x844 -+ ath10kcal_patch_mac $(macaddr_add $(cat /sys/class/net/eth0/address) +16) -+ ;; -+ rb-911g-5hpacd|\ -+ rb-921gs-5hpacd-r2|\ -+ rb-922uags-5hpacd|\ -+ rb-962uigs-5hact2hnt) -+ ath10kcal_from_file "/sys/firmware/mikrotik/hard_config/wlan_data" 0x5000 0x844 -+ ;; -+ wlr8100) -+ ath10kcal_extract "art" 0x5000 0x844 -+ ath10kcal_patch_mac $(macaddr_add $(mtd_get_mac_ascii u-boot-env ethaddr) +1) -+ ;; -+ esac -+ ;; -+"ath10k/pre-cal-pci-0000:00:00.0.bin") -+ case $board in -+ archer-c58-v1|\ -+ archer-c59-v1|\ -+ archer-c59-v2|\ -+ archer-c60-v1|\ -+ cf-e355ac-v2|\ -+ cf-e375ac) -+ ath10kcal_extract "art" 0x5000 0x2f20 -+ ln -sf /lib/firmware/ath10k/pre-cal-pci-0000\:00\:00.0.bin \ -+ /lib/firmware/ath10k/QCA9888/hw2.0/board.bin -+ ;; -+ archer-c60-v2) -+ ath10kcal_extract "art" 0x5000 0x2f20 -+ ln -sf /lib/firmware/ath10k/pre-cal-pci-0000\:00\:00.0.bin \ -+ /lib/firmware/ath10k/QCA9888/hw2.0/board.bin -+ ath10kcal_patch_mac $(macaddr_add $(cat /sys/class/net/eth1/address) -1) -+ ;; -+ cf-e385ac) -+ ath10kcal_extract "art" 0x5000 0x2f20 -+ ;; -+ esac -+ ;; -+*) -+ exit 1 -+ ;; -+esac -diff --git a/target/linux/ar71xx/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac b/target/linux/ar71xx/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac -new file mode 100644 -index 0000000000..2a06b7d07b ---- /dev/null -+++ b/target/linux/ar71xx/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac -@@ -0,0 +1,24 @@ -+#!/bin/ash -+ -+[ "$ACTION" == "add" ] || exit 0 -+ -+PHYNBR=${DEVPATH##*/phy} -+ -+[ -n $PHYNBR ] || exit 0 -+ -+. /lib/functions.sh -+. /lib/functions/system.sh -+ -+board=$(board_name) -+ -+case "$board" in -+ archer-c58-v1|\ -+ archer-c59-v1|\ -+ archer-c59-v2|\ -+ archer-c60-v1) -+ echo $(macaddr_add $(mtd_get_mac_binary mac 0x8) $(($PHYNBR - 1)) ) > /sys${DEVPATH}/macaddress -+ ;; -+ *) -+ ;; -+esac -+ -diff --git a/target/linux/ar71xx/base-files/etc/hotplug.d/net/10-ar922x-led-fix b/target/linux/ar71xx/base-files/etc/hotplug.d/net/10-ar922x-led-fix -new file mode 100644 -index 0000000000..bd1abb9681 ---- /dev/null -+++ b/target/linux/ar71xx/base-files/etc/hotplug.d/net/10-ar922x-led-fix -@@ -0,0 +1,52 @@ -+#!/bin/sh -+ -+# For AR9220 and AR9223, GPIO JTAG must explicit be disabled -+# before LEDs start working. Do this when wifi device is -+# detected. -+ -+# -+# $DEVPATH is not valid for some boards (including WZR-HP-AG300H). -+# Manipulate the $DEVPATH to reach the corresponding phyN. -+# -+ -+devdir=$(dirname $DEVPATH) -+devdir=$(dirname $devdir) -+phydir=/sys$devdir/ieee80211 -+ -+[ -d $phydir ] || exit 0 -+ -+phyname=$(cat $phydir/phy*/name) -+ -+[ -z $phyname -o $ACTION != "add" ] && exit 0 -+ -+# -+# ar922x_disable_gpio_jtag(): -+# -+# Emulate -+# REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); -+# for AR9220 and AR9223. -+# -+ -+ar922x_disable_gpio_jtag() { -+ local regidx=0x4054 -+ -+ [ -f /sys/kernel/debug/ieee80211/$1/ath9k/regidx ] || return -+ -+ echo $regidx > /sys/kernel/debug/ieee80211/$1/ath9k/regidx -+ regval=$(cat /sys/kernel/debug/ieee80211/$1/ath9k/regval) -+ regval=$((regval | 0x20000)) -+ echo regval $regval -+ echo $regval > /sys/kernel/debug/ieee80211/$1/ath9k/regval -+} -+ -+[ $phyname -a $ACTION = "add" ] && { -+ . /lib/functions.sh -+ -+ case $(board_name) in -+ wzr-hp-ag300h) -+ ar922x_disable_gpio_jtag $phyname -+ ;; -+ esac; -+} -+ -+exit 0 -diff --git a/target/linux/ar71xx/base-files/etc/inittab b/target/linux/ar71xx/base-files/etc/inittab -new file mode 100644 -index 0000000000..9820e7144b ---- /dev/null -+++ b/target/linux/ar71xx/base-files/etc/inittab -@@ -0,0 +1,3 @@ -+::sysinit:/etc/init.d/rcS S boot -+::shutdown:/etc/init.d/rcS K shutdown -+::askconsole:/usr/libexec/login.sh -diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/03_network-switchX-migration b/target/linux/ar71xx/base-files/etc/uci-defaults/03_network-switchX-migration -new file mode 100644 -index 0000000000..0388fb6dc9 ---- /dev/null -+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/03_network-switchX-migration -@@ -0,0 +1,108 @@ -+#!/bin/sh -+# -+# Copyright (C) 2013 OpenWrt.org -+# -+ -+SWITCH_NAME_CHANGED= -+ -+. /lib/functions.sh -+ -+do_change_switch_name() { -+ local config="$1" -+ local option=$2 -+ local oldname=$3 -+ local newname=$4 -+ local val -+ -+ config_get val "$config" $option -+ [ "$val" != "$oldname" ] && return 0 -+ -+ uci_set network "$config" $option $newname -+ SWITCH_NAME_CHANGED=1 -+ -+ return 0 -+} -+ -+migrate_switch_name() { -+ local oldname=$1 -+ local newname=$2 -+ -+ config_load network -+ -+ logger -t migrate-switchX "Updating switch names in network configuration" -+ -+ config_foreach do_change_switch_name switch name $oldname $newname -+ config_foreach do_change_switch_name switch_vlan device $oldname $newname -+ -+ [ "$SWITCH_NAME_CHANGED" = "1" ] && { -+ logger -t migrate-switchX "Switch names updated, saving network configuration" -+ uci commit network -+ } -+} -+ -+board=$(board_name) -+ -+case "$board" in -+airrouter|\ -+ap121|\ -+ap121-mini|\ -+ap96|\ -+dir-600-a1|\ -+dir-615-c1|\ -+dir-615-e1|\ -+dir-615-e4|\ -+dir-825-c1|\ -+ebr-2310-c1|\ -+ew-dorin|\ -+ew-dorin-router|\ -+ja76pf|\ -+rb-750|\ -+rb-751|\ -+tew-632brp|\ -+tew-712br|\ -+tl-mr3220|\ -+tl-mr3220-v2 |\ -+tl-mr3420|\ -+tl-wdr4300|\ -+tl-wr741nd|\ -+tl-wr741nd-v4|\ -+tl-wr841n-v7|\ -+tl-wr1041n-v2|\ -+whr-g301n|\ -+whr-hp-g300n|\ -+whr-hp-gn|\ -+wrt160nl|\ -+wzr-hp-ag300h|\ -+wzr-hp-g300nh2|\ -+wzr-hp-g450h|\ -+z1) -+ migrate_switch_name "eth0" "switch0" -+ ;; -+ -+el-m150|\ -+rb-450) -+ migrate_switch_name "eth1" "switch0" -+ ;; -+ -+db120|\ -+rb-2011il|\ -+rb-2011ils|\ -+rb-2011l|\ -+rb-2011uas-2hnd) -+ migrate_switch_name "eth0" "switch0" -+ migrate_switch_name "eth1" "switch1" -+ ;; -+ -+dir-825-b1|\ -+nbg460n_550n_550nh|\ -+tew-673gru) -+ migrate_switch_name "rtl8366s" "switch0" -+ ;; -+ -+tl-wr1043nd) -+ migrate_switch_name "rtl8366rb" "switch0" -+ ;; -+ -+esac -+ -+exit 0 -diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/03_network-vlan-migration b/target/linux/ar71xx/base-files/etc/uci-defaults/03_network-vlan-migration -new file mode 100644 -index 0000000000..259d240610 ---- /dev/null -+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/03_network-vlan-migration -@@ -0,0 +1,13 @@ -+#!/bin/sh -+# -+# Copyright (C) 2010 OpenWrt.org -+# -+ -+dev="$(uci -q get network.@switch_vlan[0].device)" -+vlan="$(uci -q get network.@switch_vlan[0].vlan)" -+ -+if [ "$dev" = "rtl8366s" ] && [ "$vlan" = 0 ]; then -+ logger -t vlan-migration "VLAN 0 is invalid for RTL8366s, changing to 1" -+ uci set network.@switch_vlan[0].vlan=1 -+ uci commit network -+fi -diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/04_led_migration b/target/linux/ar71xx/base-files/etc/uci-defaults/04_led_migration -new file mode 100644 -index 0000000000..c244b3b460 ---- /dev/null -+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/04_led_migration -@@ -0,0 +1,84 @@ -+#!/bin/sh -+# -+# Copyright (C) 2013 OpenWrt.org -+# -+ -+LED_OPTIONS_CHANGED=0 -+ -+. /lib/functions.sh -+ -+do_led_update_sysfs() -+{ -+ local cfg=$1; shift -+ local tuples="$@" -+ local sysfs -+ local name -+ -+ config_get sysfs $cfg sysfs -+ config_get name $cfg name -+ -+ [ -z "$sysfs" ] && return -+ -+ for tuple in $tuples; do -+ local old=${tuple%=*} -+ local new=${tuple#*=} -+ local new_sysfs -+ -+ new_sysfs=$(echo ${sysfs} | sed "s/${old}/${new}/") -+ -+ [ "$new_sysfs" = "$sysfs" ] && continue -+ -+ uci set system.${cfg}.sysfs="${new_sysfs}" -+ LED_OPTIONS_CHANGED=1 -+ -+ logger -t led-migration "sysfs option of LED \"${name}\" updated to ${new_sysfs}" -+ done; -+} -+ -+migrate_leds() -+{ -+ config_load system -+ config_foreach do_led_update_sysfs led "$@" -+} -+ -+board=$(board_name) -+ -+case "$board" in -+archer-c7) -+ migrate_leds ":blue:=:green:" -+ ;; -+dhp-1565-a1|\ -+dir-825-c1|\ -+dir-835-a1) -+ migrate_leds ":orange:=:amber:" ":wifi_bgn=:wlan2g" -+ ;; -+dr344) -+ migrate_leds ":red:=:green:" ":yellow:=:green:" -+ ;; -+gl-ar150) -+ migrate_leds "gl-ar150:wlan=gl-ar150:orange:wlan" "gl-ar150:lan=gl-ar150:green:lan" "gl-ar150:wan=gl-ar150:green:wan" -+ ;; -+oolite-v1) -+ migrate_leds "oolite:=${board}" -+ ;; -+wndap360|\ -+wndr3700|\ -+wnr2000|\ -+wnr2200) -+ migrate_leds "${board}:=netgear:" -+ ;; -+wndr3700v4|\ -+wndr4300) -+ migrate_leds ":orange:=:amber:" -+ ;; -+wnr1000-v2) -+ migrate_leds "wnr1000v2:=netgear:" -+ ;; -+wnr612-v2) -+ migrate_leds "wnr612v2:=netgear:" -+ ;; -+esac -+ -+[ "$LED_OPTIONS_CHANGED" = "1" ] && uci commit system -+ -+exit 0 -diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/09_fix-checksum b/target/linux/ar71xx/base-files/etc/uci-defaults/09_fix-checksum -new file mode 100644 -index 0000000000..2d1afb11cb ---- /dev/null -+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/09_fix-checksum -@@ -0,0 +1,28 @@ -+#!/bin/sh -+# -+# Copyright (C) 2010 OpenWrt.org -+# -+ -+. /lib/functions.sh -+ -+board=$(board_name) -+ -+fixtrx() { -+ mtd -o 32 fixtrx firmware -+} -+ -+fixwrgg() { -+ local kernel_size=$(sed -n 's/mtd[0-9]*: \([0-9a-f]*\).*"kernel".*/\1/p' /proc/mtd) -+ -+ [ "$kernel_size" ] && mtd -c 0x$kernel_size fixwrgg firmware -+} -+ -+case "$board" in -+mynet-rext |\ -+wrt160nl) -+ fixtrx -+ ;; -+dap-2695-a1) -+ fixwrgg -+ ;; -+esac -diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/09_fix-seama-header b/target/linux/ar71xx/base-files/etc/uci-defaults/09_fix-seama-header -new file mode 100644 -index 0000000000..b3857ef07f ---- /dev/null -+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/09_fix-seama-header -@@ -0,0 +1,17 @@ -+#!/bin/sh -+ -+. /lib/functions.sh -+ -+fix_seama_header() { -+ local kernel_size=$(sed -n 's/mtd[0-9]*: \([0-9a-f]*\).*"kernel".*/\1/p' /proc/mtd) -+ -+ [ "$kernel_size" ] && mtd -c 0x$kernel_size fixseama firmware -+} -+ -+board=$(board_name) -+ -+case "$board" in -+dir-869-a1) -+ fix_seama_header -+ ;; -+esac -diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh -new file mode 100755 -index 0000000000..044ef4eae5 ---- /dev/null -+++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh -@@ -0,0 +1,1589 @@ -+#!/bin/sh -+# -+# Copyright (C) 2009-2011 OpenWrt.org -+# -+ -+AR71XX_BOARD_NAME= -+AR71XX_MODEL= -+ -+ar71xx_get_mtd_offset_size_format() { -+ local mtd="$1" -+ local offset="$2" -+ local size="$3" -+ local format="$4" -+ local dev -+ -+ dev=$(find_mtd_part $mtd) -+ [ -z "$dev" ] && return -+ -+ dd if=$dev iflag=skip_bytes bs=$size skip=$offset count=1 2>/dev/null | hexdump -v -e "1/1 \"$format\"" -+} -+ -+ar71xx_get_mtd_part_magic() { -+ local mtd="$1" -+ ar71xx_get_mtd_offset_size_format "$mtd" 0 4 %02x -+} -+ -+wndr3700_board_detect() { -+ local machine="$1" -+ local magic -+ local name -+ -+ name="wndr3700" -+ -+ magic="$(ar71xx_get_mtd_part_magic firmware)" -+ case $magic in -+ "33373030") -+ machine="NETGEAR WNDR3700" -+ ;; -+ "33373031") -+ model="$(ar71xx_get_mtd_offset_size_format art 41 32 %c)" -+ # Use awk to remove everything unprintable -+ model_stripped="$(ar71xx_get_mtd_offset_size_format art 41 32 %c | LC_CTYPE=C awk -v 'FS=[^[:print:]]' '{print $1; exit}')" -+ case $model in -+ $'\xff'*) -+ if [ "${model:24:1}" = 'N' ]; then -+ machine="NETGEAR WNDRMAC" -+ else -+ machine="NETGEAR WNDR3700v2" -+ fi -+ ;; -+ '29763654+16+64'*) -+ machine="NETGEAR ${model_stripped:14}" -+ ;; -+ '29763654+16+128'*) -+ machine="NETGEAR ${model_stripped:15}" -+ ;; -+ *) -+ # Unknown ID -+ machine="NETGEAR ${model_stripped}" -+ esac -+ esac -+ -+ AR71XX_BOARD_NAME="$name" -+ AR71XX_MODEL="$machine" -+} -+ -+ubnt_get_mtd_part_magic() { -+ ar71xx_get_mtd_offset_size_format EEPROM 4118 2 %02x -+} -+ -+ubnt_xm_board_detect() { -+ local model -+ local magic -+ -+ magic="$(ubnt_get_mtd_part_magic)" -+ case ${magic:0:3} in -+ "e00"|\ -+ "e01"|\ -+ "e80") -+ model="Ubiquiti NanoStation M" -+ ;; -+ "e0a") -+ model="Ubiquiti NanoStation loco M" -+ ;; -+ "e1b"|\ -+ "e1d") -+ model="Ubiquiti Rocket M" -+ ;; -+ "e20"|\ -+ "e2d") -+ model="Ubiquiti Bullet M" -+ ;; -+ "e30") -+ model="Ubiquiti PicoStation M" -+ ;; -+ esac -+ -+ [ -z "$model" ] || AR71XX_MODEL="${model}${magic:3:1}" -+} -+ -+ubnt_unifi_ac_get_mtd_part_magic() { -+ ar71xx_get_mtd_offset_size_format EEPROM 12 2 %02x -+} -+ -+ubnt_unifi_ac_board_detect() { -+ local model -+ local magic -+ -+ magic="$(ubnt_unifi_ac_get_mtd_part_magic)" -+ case ${magic:0:4} in -+ "e517") -+ model="Ubiquiti UniFi-AC-LITE" -+ ;; -+ "e527") -+ model="Ubiquiti UniFi-AC-LR" -+ ;; -+ "e537") -+ model="Ubiquiti UniFi-AC-PRO" -+ ;; -+ "e557") -+ model="Ubiquiti UniFi-AC-MESH" -+ ;; -+ "e567") -+ model="Ubiquiti UniFi-AC-MESH-PRO" -+ ;; -+ esac -+ -+ [ -z "$model" ] || AR71XX_MODEL="${model}" -+} -+ -+cybertan_get_hw_magic() { -+ local part -+ -+ part=$(find_mtd_part firmware) -+ [ -z "$part" ] && return 1 -+ -+ dd bs=8 count=1 skip=0 if=$part 2>/dev/null | hexdump -v -n 8 -e '1/1 "%02x"' -+} -+ -+dir505_board_detect() { -+ local dev=$(find_mtd_part 'mac') -+ [ -z "$dev" ] && return -+ -+ # The revision is stored at the beginning of the "mac" partition -+ local rev="$(LC_CTYPE=C awk -v 'FS=[^[:print:]]' '{print $1; exit}' $dev)" -+ AR71XX_MODEL="D-Link DIR-505 rev. $rev" -+} -+ -+tplink_get_hwid() { -+ local part -+ -+ part=$(find_mtd_part firmware) -+ [ -z "$part" ] && return 1 -+ -+ dd if=$part bs=4 count=1 skip=16 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' -+} -+ -+tplink_get_mid() { -+ local part -+ -+ part=$(find_mtd_part firmware) -+ [ -z "$part" ] && return 1 -+ -+ dd if=$part bs=4 count=1 skip=17 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' -+} -+ -+tplink_board_detect() { -+ local model="$1" -+ local hwid -+ local hwver -+ -+ hwid=$(tplink_get_hwid) -+ mid=$(tplink_get_mid) -+ hwver=${hwid:6:2} -+ hwver=" v${hwver#0}" -+ -+ case "$hwid" in -+ "001001"*) -+ model="TP-Link TL-MR10U" -+ ;; -+ "001101"*) -+ model="TP-Link TL-MR11U" -+ ;; -+ "001201"*) -+ model="TP-Link TL-MR12U" -+ ;; -+ "001301"*) -+ model="TP-Link TL-MR13U" -+ ;; -+ "007260"*) -+ model="TellStick ZNet Lite" -+ ;; -+ "015000"*) -+ model="EasyLink EL-M150" -+ ;; -+ "015300"*) -+ model="EasyLink EL-MINI" -+ ;; -+ "044401"*) -+ model="ANTMINER-S1" -+ ;; -+ "044403"*) -+ model="ANTMINER-S3" -+ ;; -+ "066601"*) -+ model="OMYlink OMY-G1" -+ ;; -+ "066602"*) -+ model="OMYlink OMY-X1" -+ ;; -+ "070100"*) -+ model="TP-Link TL-WA701N/ND" -+ ;; -+ "070301"*) -+ model="TP-Link TL-WR703N" -+ ;; -+ "071000"*) -+ model="TP-Link TL-WR710N" -+ -+ [ "$hwid" = '07100002' -a "$mid" = '00000002' ] && hwver=' v2.1' -+ ;; -+ "072001"*) -+ model="TP-Link TL-WR720N" -+ ;; -+ "073000"*) -+ model="TP-Link TL-WA730RE" -+ ;; -+ "074000"*) -+ model="TP-Link TL-WR740N/ND" -+ ;; -+ "074100"*) -+ model="TP-Link TL-WR741N/ND" -+ ;; -+ "074300"*) -+ model="TP-Link TL-WR743N/ND" -+ ;; -+ "075000"*) -+ model="TP-Link TL-WA750RE" -+ ;; -+ "080100"*) -+ model="TP-Link TL-WA801N/ND" -+ ;; -+ "080200"*) -+ model="TP-Link TL-WR802N" -+ -+ [ "$hwid" = '08020002' -a "$mid" = '00000002' ] && hwver=' v2' -+ ;; -+ "081000"*) -+ model="TP-Link TL-WR810N" -+ ;; -+ "083000"*) -+ model="TP-Link TL-WA830RE" -+ -+ [ "$hwver" = ' v10' ] && hwver=' v1' -+ ;; -+ "084100"*) -+ model="TP-Link TL-WR841N/ND" -+ -+ [ "$hwid" = '08410002' -a "$mid" = '00000002' ] && hwver=' v1.5' -+ ;; -+ "084200"*) -+ model="TP-Link TL-WR842N/ND" -+ ;; -+ "084300"*) -+ model="TP-Link TL-WR843N/ND" -+ ;; -+ "085000"*) -+ model="TP-Link TL-WA850RE" -+ ;; -+ "085500"*) -+ model="TP-Link TL-WA855RE" -+ ;; -+ "086000"*) -+ model="TP-Link TL-WA860RE" -+ ;; -+ "090100"*) -+ model="TP-Link TL-WA901N/ND" -+ ;; -+ "094000"*) -+ model="TP-Link TL-WR940N" -+ ;; -+ "094100"*) -+ model="TP-Link TL-WR941N/ND" -+ -+ [ "$hwid" = "09410002" -a "$mid" = "00420001" ] && { -+ model="Rosewill RNX-N360RT" -+ hwver="" -+ } -+ ;; -+ "104100"*) -+ model="TP-Link TL-WR1041N/ND" -+ ;; -+ "104300"*) -+ model="TP-Link TL-WR1043N/ND" -+ ;; -+ "120000"*) -+ model="MERCURY MAC1200R" -+ ;; -+ "254300"*) -+ model="TP-Link TL-WR2543N/ND" -+ ;; -+ "302000"*) -+ model="TP-Link TL-MR3020" -+ ;; -+ "304000"*) -+ model="TP-Link TL-MR3040" -+ ;; -+ "322000"*) -+ model="TP-Link TL-MR3220" -+ ;; -+ "332000"*) -+ model="TP-Link TL-WDR3320" -+ ;; -+ "342000"*) -+ model="TP-Link TL-MR3420" -+ ;; -+ "350000"*) -+ model="TP-Link TL-WDR3500" -+ ;; -+ "360000"*) -+ model="TP-Link TL-WDR3600" -+ ;; -+ "430000"*) -+ model="TP-Link TL-WDR4300" -+ ;; -+ "430080"*) -+ iw reg set IL -+ model="TP-Link TL-WDR4300 (IL)" -+ ;; -+ "431000"*) -+ model="TP-Link TL-WDR4310" -+ ;; -+ "44440101"*) -+ model="ANTROUTER-R1" -+ ;; -+ "453000"*) -+ model="Mercury MW4530R" -+ ;; -+ "49000002") -+ model="TP-Link TL-WDR4900" -+ ;; -+ "640000"*) -+ model="TP-Link TL-MR6400" -+ ;; -+ "65000002") -+ model="TP-Link TL-WDR6500" -+ ;; -+ "721000"*) -+ model="TP-Link TL-WA7210N" -+ ;; -+ "750000"*|\ -+ "c70000"*) -+ model="TP-Link Archer C7" -+ ;; -+ "751000"*) -+ model="TP-Link TL-WA7510N" -+ ;; -+ "934100"*) -+ model="NC-LINK SMART-300" -+ ;; -+ "c50000"*) -+ model="TP-Link Archer C5" -+ ;; -+ *) -+ hwver="" -+ ;; -+ esac -+ -+ AR71XX_MODEL="$model$hwver" -+} -+ -+tplink_pharos_get_model_string() { -+ local part -+ part=$(find_mtd_part 'product-info') -+ [ -z "$part" ] && return 1 -+ -+ # The returned string will end with \r\n, but we don't remove it here -+ # to simplify matching against it in the sysupgrade image check -+ dd if=$part bs=1 skip=4360 2>/dev/null | head -n 1 -+} -+ -+tplink_pharos_board_detect() { -+ local model_string="$1" -+ local oIFS="$IFS"; IFS=":"; set -- $model_string; IFS="$oIFS" -+ -+ local model="${1%%\(*}" -+ -+ AR71XX_MODEL="TP-Link $model v$2" -+} -+ -+tplink_pharos_v2_get_model_string() { -+ local part -+ part=$(find_mtd_part 'product-info') -+ [ -z "$part" ] && return 1 -+ -+ dd if=$part iflag=skip_bytes bs=64 skip=4360 count=1 2>/dev/null | tr -d '\r\0' | head -n 1 -+} -+ -+mikrotik_board_detect() { -+ local machine="$1" -+ -+ case "$machine" in -+ *"2011iL") -+ name="rb-2011il" -+ ;; -+ *"2011iLS") -+ name="rb-2011ils" -+ ;; -+ *"2011L") -+ name="rb-2011l" -+ ;; -+ *"2011UAS") -+ name="rb-2011uas" -+ ;; -+ *"2011UAS-2HnD") -+ name="rb-2011uas-2hnd" -+ ;; -+ *"2011UiAS") -+ name="rb-2011uias" -+ ;; -+ *"2011UiAS-2HnD") -+ name="rb-2011uias-2hnd" -+ ;; -+ *"2011UiAS-2HnD r2") -+ name="rb-2011uias-2hnd-r2" -+ ;; -+ *"411/A/AH") -+ name="rb-411" -+ ;; -+ *"411U") -+ name="rb-411u" -+ ;; -+ *"433/AH") -+ name="rb-433" -+ ;; -+ *"433UAH") -+ name="rb-433u" -+ ;; -+ *"435G") -+ name="rb-435g" -+ ;; -+ *"450") -+ name="rb-450" -+ ;; -+ *"450G") -+ name="rb-450g" -+ ;; -+ *"493/AH") -+ name="rb-493" -+ ;; -+ *"493G") -+ name="rb-493g" -+ ;; -+ *"750") -+ name="rb-750" -+ ;; -+ *"750 r2"|\ -+ *"750r2") -+ name="rb-750-r2" -+ ;; -+ *"750GL") -+ name="rb-750gl" -+ ;; -+ *"750P r2") -+ name="rb-750p-pbr2" -+ ;; -+ *"750UP r2"|\ -+ *"750UPr2") -+ name="rb-750up-r2" -+ ;; -+ *"751") -+ name="rb-751" -+ ;; -+ *"751G") -+ name="rb-751g" -+ ;; -+ *"911-2Hn") -+ name="rb-911-2hn" -+ ;; -+ *"911-5Hn") -+ name="rb-911-5hn" -+ ;; -+ *"911G-2HPnD") -+ name="rb-911g-2hpnd" -+ ;; -+ *"911G-5HPacD") -+ name="rb-911g-5hpacd" -+ ;; -+ *"911G-5HPnD") -+ name="rb-911g-5hpnd" -+ ;; -+ *"912UAG-2HPnD") -+ name="rb-912uag-2hpnd" -+ ;; -+ *"912UAG-5HPnD") -+ name="rb-912uag-5hpnd" -+ ;; -+ *"921GS-5HPacD r2") -+ name="rb-921gs-5hpacd-r2" -+ ;; -+ *"922UAGS-5HPacD") -+ name="rb-922uags-5hpacd" -+ ;; -+ *"931-2nD") -+ name="rb-931-2nd" -+ ;; -+ *"941-2nD") -+ name="rb-941-2nd" -+ ;; -+ *"951G-2HnD") -+ name="rb-951g-2hnd" -+ ;; -+ *"951Ui-2HnD") -+ name="rb-951ui-2hnd" -+ ;; -+ *"951Ui-2nD") -+ name="rb-951ui-2nd" -+ ;; -+ *"952Ui-5ac2nD") -+ name="rb-952ui-5ac2nd" -+ ;; -+ *"962UiGS-5HacT2HnT") -+ name="rb-962uigs-5hact2hnt" -+ ;; -+ *"LHG 5nD") -+ name="rb-lhg-5nd" -+ ;; -+ *"mAP 2nD"|\ -+ *"mAP2nD") -+ name="rb-map-2nd" -+ ;; -+ *"mAP L-2nD"|\ -+ *"mAPL-2nD") -+ name="rb-mapl-2nd" -+ ;; -+ *"SXT 2nD r3") -+ name="rb-sxt-2nd-r3" -+ ;; -+ *"SXT Lite2") -+ name="rb-sxt2n" -+ ;; -+ *"SXT Lite5") -+ name="rb-sxt5n" -+ ;; -+ *"wAP 2nD r2") -+ name="rb-wap-2nd" -+ ;; -+ *"wAP R-2nD"|\ -+ *"wAPR-2nD") -+ name="rb-wapr-2nd" -+ ;; -+ *"wAP G-5HacT2HnD"|\ -+ *"wAPG-5HacT2HnD") -+ name="rb-wapg-5hact2hnd" -+ ;; -+ esac -+ -+ echo "$name" -+} -+ -+ar71xx_board_detect() { -+ local machine -+ local name -+ -+ machine=$(awk 'BEGIN{FS="[ \t]+:[ \t]"} /machine/ {print $2}' /proc/cpuinfo) -+ -+ case "$machine" in -+ *"A40") -+ name="a40" -+ ;; -+ *"A60") -+ name="a60" -+ ;; -+ *"AC1750DB") -+ name="f9k1115v2" -+ ;; -+ *"AirGateway") -+ name="airgateway" -+ ;; -+ *"AirGateway Pro") -+ name="airgatewaypro" -+ ;; -+ *"AirRouter") -+ name="airrouter" -+ ;; -+ *"ALFA Network AP120C") -+ name="alfa-ap120c" -+ ;; -+ *"ALFA Network AP96") -+ name="alfa-ap96" -+ ;; -+ *"ALFA Network N2/N5") -+ name="alfa-nx" -+ ;; -+ *"ALL0258N") -+ name="all0258n" -+ ;; -+ *"ALL0305") -+ name="all0305" -+ ;; -+ *"ALL0315N") -+ name="all0315n" -+ ;; -+ *"Antminer-S1") -+ name="antminer-s1" -+ ;; -+ *"Antminer-S3") -+ name="antminer-s3" -+ ;; -+ *"AP121 reference board") -+ name="ap121" -+ ;; -+ *"AP121-MINI") -+ name="ap121-mini" -+ ;; -+ *"AP121F") -+ name="ap121f" -+ ;; -+ *"AP132 reference board") -+ name="ap132" -+ ;; -+ *"AP135-020 reference board") -+ name="ap135-020" -+ ;; -+ *"AP136-010 reference board") -+ name="ap136-010" -+ ;; -+ *"AP136-020 reference board") -+ name="ap136-020" -+ ;; -+ *"AP143 reference board") -+ name="ap143" -+ ;; -+ *"AP147-010 reference board") -+ name="ap147-010" -+ ;; -+ *"AP152 reference board") -+ name="ap152" -+ ;; -+ *"AP531B0") -+ name="ap531b0" -+ ;; -+ *"AP90Q") -+ name="ap90q" -+ ;; -+ *"AP91-5G") -+ name="ap91-5g" -+ ;; -+ *"Archer C25 v1") -+ name="archer-c25-v1" -+ ;; -+ *"Archer C5") -+ name="archer-c5" -+ ;; -+ *"Archer C7 v4") -+ name="archer-c7-v4" -+ ;; -+ *"Archer C7 v5") -+ name="archer-c7-v5" -+ ;; -+ *"Archer C58 v1") -+ name="archer-c58-v1" -+ ;; -+ *"Archer C59 v1") -+ name="archer-c59-v1" -+ ;; -+ *"Archer C59 v2") -+ name="archer-c59-v2" -+ ;; -+ *"Archer C60 v1") -+ name="archer-c60-v1" -+ ;; -+ *"Archer C60 v2") -+ name="archer-c60-v2" -+ ;; -+ *"Archer C7") -+ name="archer-c7" -+ ;; -+ *"Arduino Yun") -+ name="arduino-yun" -+ ;; -+ *"Atheros AP96") -+ name="ap96" -+ ;; -+ *"AW-NR580") -+ name="aw-nr580" -+ ;; -+ *"BHR-4GRV2") -+ name="bhr-4grv2" -+ ;; -+ *"Black Swift board"*) -+ name="bsb" -+ ;; -+ *"Bullet M") -+ name="bullet-m" -+ ubnt_xm_board_detect -+ ;; -+ *"Bullet M XW") -+ name="bullet-m-xw" -+ ;; -+ *"BXU2000n-2 rev. A1") -+ name="bxu2000n-2-a1" -+ ;; -+ *"C-55") -+ name="c-55" -+ ;; -+ *"C-60") -+ name="c-60" -+ ;; -+ *"CAP324") -+ name="cap324" -+ ;; -+ *"CAP4200AG") -+ name="cap4200ag" -+ ;; -+ *"Carambola2"*) -+ name="carambola2" -+ ;; -+ *"CF-E316N v2") -+ name="cf-e316n-v2" -+ ;; -+ *"CF-E320N v2") -+ name="cf-e320n-v2" -+ ;; -+ *"CF-E355AC v1") -+ name="cf-e355ac-v1" -+ ;; -+ *"CF-E355AC v2") -+ name="cf-e355ac-v2" -+ ;; -+ *"CF-E375AC") -+ name="cf-e375ac" -+ ;; -+ *"CF-E380AC v1") -+ name="cf-e380ac-v1" -+ ;; -+ *"CF-E380AC v2") -+ name="cf-e380ac-v2" -+ ;; -+ *"CF-E385AC") -+ name="cf-e385ac" -+ ;; -+ *"CF-E520N") -+ name="cf-e520n" -+ ;; -+ *"CF-E530N") -+ name="cf-e530n" -+ ;; -+ *"CPE210/220") -+ name="cpe210" -+ tplink_pharos_board_detect "$(tplink_pharos_get_model_string | tr -d '\r')" -+ ;; -+ *"CPE210 v2") -+ name="cpe210-v2" -+ tplink_pharos_board_detect "$(tplink_pharos_v2_get_model_string)" -+ ;; -+ *"CPE210 v3") -+ name="cpe210-v3" -+ tplink_pharos_board_detect "$(tplink_pharos_v2_get_model_string)" -+ ;; -+ *"CPE505N") -+ name="cpe505n" -+ ;; -+ *"CPE510/520") -+ name="cpe510" -+ tplink_pharos_board_detect "$(tplink_pharos_get_model_string | tr -d '\r')" -+ ;; -+ *"CPE510 v2") -+ name="cpe510-v2" -+ tplink_pharos_board_detect "$(tplink_pharos_v2_get_model_string)" -+ ;; -+ *"CPE830") -+ name="cpe830" -+ ;; -+ *"CPE870") -+ name="cpe870" -+ ;; -+ *"CR3000") -+ name="cr3000" -+ ;; -+ *"CR5000") -+ name="cr5000" -+ ;; -+ *"DAP-1330 Rev. A1") -+ name="dap-1330-a1" -+ ;; -+ *"DAP-2695 rev. A1") -+ name="dap-2695-a1" -+ ;; -+ *"DB120 reference board") -+ name="db120" -+ ;; -+ *"DGL-5500 rev. A1") -+ name="dgl-5500-a1" -+ ;; -+ *"DHP-1565 rev. A1") -+ name="dhp-1565-a1" -+ ;; -+ *"DIR-505 rev. A1") -+ name="dir-505-a1" -+ dir505_board_detect -+ ;; -+ *"DIR-600 rev. A1") -+ name="dir-600-a1" -+ ;; -+ *"DIR-615 rev. C1") -+ name="dir-615-c1" -+ ;; -+ *"DIR-615 rev. E1") -+ name="dir-615-e1" -+ ;; -+ *"DIR-615 rev. E4") -+ name="dir-615-e4" -+ ;; -+ *"DIR-615 rev. I1") -+ name="dir-615-i1" -+ ;; -+ *"DIR-825 rev. B1") -+ name="dir-825-b1" -+ ;; -+ *"DIR-825 rev. C1") -+ name="dir-825-c1" -+ ;; -+ *"DIR-835 rev. A1") -+ name="dir-835-a1" -+ ;; -+ *"DIR-869 rev. A1") -+ name="dir-869-a1" -+ ;; -+ *"dLAN Hotspot") -+ name="dlan-hotspot" -+ ;; -+ *"dLAN pro 1200+ WiFi ac") -+ name="dlan-pro-1200-ac" -+ ;; -+ *"dLAN pro 500 Wireless+") -+ name="dlan-pro-500-wp" -+ ;; -+ *"Domino Pi") -+ name="gl-domino" -+ ;; -+ *"DR342") -+ name="dr342" -+ ;; -+ *"DR344") -+ name="dr344" -+ ;; -+ *"DR531") -+ name="dr531" -+ ;; -+ *"Dragino v2") -+ name="dragino2" -+ ;; -+ *"DW33D") -+ name="dw33d" -+ ;; -+ *"E1700AC v2") -+ name="e1700ac-v2" -+ ;; -+ *"E2100L") -+ name="e2100l" -+ ;; -+ *"E558 v2") -+ name="e558-v2" -+ ;; -+ *"E600G v2") -+ name="e600g-v2" -+ ;; -+ *"E600GAC v2") -+ name="e600gac-v2" -+ ;; -+ *"E750A v4") -+ name="e750a-v4" -+ ;; -+ *"E750G v8") -+ name="e750g-v8" -+ ;; -+ *"EAP120") -+ name="eap120" -+ tplink_pharos_board_detect "$(tplink_pharos_get_model_string | tr -d '\r')" -+ ;; -+ *"EAP300 v2") -+ name="eap300v2" -+ ;; -+ *"EAP7660D") -+ name="eap7660d" -+ ;; -+ *"EBR-2310 rev. C1") -+ name="ebr-2310-c1" -+ ;; -+ *"EL-M150") -+ name="el-m150" -+ ;; -+ *"EL-MINI") -+ name="el-mini" -+ ;; -+ *"EmbWir-Balin") -+ name="ew-balin" -+ ;; -+ *"EmbWir-Dorin") -+ name="ew-dorin" -+ ;; -+ *"EmbWir-Dorin-Router") -+ name="ew-dorin-router" -+ ;; -+ *"ENS202EXT") -+ name="ens202ext" -+ ;; -+ *"EPG5000") -+ name="epg5000" -+ ;; -+ *"ESR1750") -+ name="esr1750" -+ ;; -+ *"ESR900") -+ name="esr900" -+ ;; -+ *"eTactica EG-200") -+ name="rme-eg200" -+ ;; -+ *"FRITZ!Box 4020") -+ name="fritz4020" -+ ;; -+ *"FRITZ!WLAN Repeater 300E") -+ name="fritz300e" -+ ;; -+ *"FRITZ!WLAN Repeater 450E") -+ name="fritz450e" -+ ;; -+ *"GL-AR150") -+ name="gl-ar150" -+ ;; -+ *"GL-AR300") -+ name="gl-ar300" -+ ;; -+ *"GL-AR300M") -+ name="gl-ar300m" -+ ;; -+ *"GL-AR750") -+ name="gl-ar750" -+ ;; -+ *"GL-AR750S") -+ name="gl-ar750s" -+ ;; -+ *"GL-CONNECT INET v1") -+ name="gl-inet" -+ -+ local size="$(mtd_get_part_size 'firmware')" -+ -+ [ "$size" = "8192000" ] && AR71XX_MODEL="GL-iNet 6408A v1" -+ [ "$size" = "16580608" ] && AR71XX_MODEL="GL-iNet 6416A v1" -+ ;; -+ *"GL-MIFI") -+ name="gl-mifi" -+ ;; -+ *"GL-USB150") -+ name="gl-usb150" -+ ;; -+ *"HiveAP-121") -+ name="hiveap-121" -+ ;; -+ *"HiWiFi HC6361") -+ name="hiwifi-hc6361" -+ ;; -+ *"Hornet-UB") -+ local size="$(mtd_get_part_size 'firmware')" -+ -+ [ "$size" = "7929856" ] && name="hornet-ub" -+ [ "$size" = "16318464" ] && name="hornet-ub-x2" -+ ;; -+ *"JA76PF") -+ name="ja76pf" -+ ;; -+ *"JA76PF2") -+ name="ja76pf2" -+ ;; -+ *"JWAP003") -+ name="jwap003" -+ ;; -+ *"JWAP230") -+ name="jwap230" -+ ;; -+ *"Koala") -+ name="koala" -+ ;; -+ *"LAN Turtle") -+ name="lan-turtle" -+ ;; -+ *"Lima"*) -+ name="lima" -+ ;; -+ *"Litebeam M5"*) -+ name="lbe-m5" -+ ;; -+ *"Loco M XW") -+ name="loco-m-xw" -+ ;; -+ *"LS-SR71") -+ name="ls-sr71" -+ ;; -+ *"MAC1200R") -+ name="mc-mac1200r" -+ ;; -+ "MikroTik"*|\ -+ "Mikrotik"*) -+ name=$(mikrotik_board_detect "$machine") -+ ;; -+ *"MiniBox V1.0") -+ name="minibox-v1" -+ ;; -+ *"Minibox V3.2") -+ name="minibox-v3.2" -+ ;; -+ *"MR12") -+ name="mr12" -+ ;; -+ *"MR16") -+ name="mr16" -+ ;; -+ *"MR1750") -+ name="mr1750" -+ ;; -+ *"MR1750v2") -+ name="mr1750v2" -+ ;; -+ *"MR18") -+ name="mr18" -+ ;; -+ *"MR600") -+ name="mr600" -+ ;; -+ *"MR600v2") -+ name="mr600v2" -+ ;; -+ *"MR900") -+ name="mr900" -+ ;; -+ *"MR900v2") -+ name="mr900v2" -+ ;; -+ *"My Net N600") -+ name="mynet-n600" -+ ;; -+ *"My Net N750") -+ name="mynet-n750" -+ ;; -+ *"My Net Wi-Fi Range Extender") -+ name="mynet-rext" -+ ;; -+ *"MZK-W04NU") -+ name="mzk-w04nu" -+ ;; -+ *"MZK-W300NH") -+ name="mzk-w300nh" -+ ;; -+ *"N5Q") -+ name="n5q" -+ ;; -+ *"Nanostation M") -+ name="nanostation-m" -+ ubnt_xm_board_detect -+ ;; -+ *"Nanostation M XW") -+ name="nanostation-m-xw" -+ ;; -+ *"NBG460N/550N/550NH") -+ name="nbg460n_550n_550nh" -+ ;; -+ *"NBG6616") -+ name="nbg6616" -+ ;; -+ *"NBG6716") -+ name="nbg6716" -+ ;; -+ *"OM2P") -+ name="om2p" -+ ;; -+ *"OM2P HS") -+ name="om2p-hs" -+ ;; -+ *"OM2P HSv2") -+ name="om2p-hsv2" -+ ;; -+ *"OM2P HSv3") -+ name="om2p-hsv3" -+ ;; -+ *"OM2P HSv4") -+ name="om2p-hsv4" -+ ;; -+ *"OM2P LC") -+ name="om2p-lc" -+ ;; -+ *"OM2Pv2") -+ name="om2pv2" -+ ;; -+ *"OM2Pv4") -+ name="om2pv4" -+ ;; -+ *"OM5P") -+ name="om5p" -+ ;; -+ *"OM5P AC") -+ name="om5p-ac" -+ ;; -+ *"OM5P ACv2") -+ name="om5p-acv2" -+ ;; -+ *"OM5P AN") -+ name="om5p-an" -+ ;; -+ *"OMY-G1") -+ name="omy-g1" -+ ;; -+ *"OMY-X1") -+ name="omy-x1" -+ ;; -+ *"Onion Omega") -+ name="onion-omega" -+ ;; -+ *"Oolite V1.0") -+ name="oolite-v1" -+ ;; -+ *"Packet Squirrel") -+ name="packet-squirrel" -+ ;; -+ *"Oolite V5.2") -+ name="oolite-v5.2" -+ ;; -+ *"Oolite V5.2-Dev") -+ name="oolite-v5.2-dev" -+ ;; -+ *"PB42") -+ name="pb42" -+ ;; -+ *"PB44 reference board") -+ name="pb44" -+ ;; -+ *"PQI Air Pen") -+ name="pqi-air-pen" -+ ;; -+ *"Qihoo 360 C301") -+ name="qihoo-c301" -+ ;; -+ *"R36A") -+ name="r36a" -+ ;; -+ *"R602N") -+ name="r602n" -+ ;; -+ *"R6100") -+ name="r6100" -+ ;; -+ *"Rambutan"*) -+ name="rambutan" -+ ;; -+ *"RE355") -+ name="re355" -+ ;; -+ *"RE450") -+ name="re450" -+ ;; -+ *"Rocket M") -+ name="rocket-m" -+ ubnt_xm_board_detect -+ ;; -+ *"Rocket M TI") -+ name="rocket-m-ti" -+ ;; -+ *"Rocket M XW") -+ name="rocket-m-xw" -+ ;; -+ *"RouterStation") -+ name="routerstation" -+ ;; -+ *"RouterStation Pro") -+ name="routerstation-pro" -+ ;; -+ *"RUT900") -+ name="rut900" -+ ;; -+ *"RW2458N") -+ name="rw2458n" -+ ;; -+ *"SC1750") -+ name="sc1750" -+ ;; -+ *"SC300M") -+ name="sc300m" -+ ;; -+ *"SC450") -+ name="sc450" -+ ;; -+ *"SMART-300") -+ name="smart-300" -+ ;; -+ *"SOM9331") -+ name="som9331" -+ ;; -+ *"SR3200") -+ name="sr3200" -+ ;; -+ *"T830") -+ name="t830" -+ ;; -+ *"TellStick ZNet Lite") -+ name="tellstick-znet-lite" -+ ;; -+ *"TEW-632BRP") -+ name="tew-632brp" -+ ;; -+ *"TEW-673GRU") -+ name="tew-673gru" -+ ;; -+ *"TEW-712BR") -+ name="tew-712br" -+ ;; -+ *"TEW-732BR") -+ name="tew-732br" -+ ;; -+ *"TEW-823DRU") -+ name="tew-823dru" -+ ;; -+ *"TL-MR10U") -+ name="tl-mr10u" -+ ;; -+ *"TL-MR11U") -+ name="tl-mr11u" -+ ;; -+ *"TL-MR12U") -+ name="tl-mr12u" -+ ;; -+ *"TL-MR13U v1") -+ name="tl-mr13u" -+ ;; -+ *"TL-MR3020") -+ name="tl-mr3020" -+ ;; -+ *"TL-MR3040") -+ name="tl-mr3040" -+ ;; -+ *"TL-MR3040 v2") -+ name="tl-mr3040-v2" -+ ;; -+ *"TL-MR3220") -+ name="tl-mr3220" -+ ;; -+ *"TL-MR3220 v2") -+ name="tl-mr3220-v2" -+ ;; -+ *"TL-MR3420") -+ name="tl-mr3420" -+ ;; -+ *"TL-MR3420 v2") -+ name="tl-mr3420-v2" -+ ;; -+ *"TL-MR6400") -+ name="tl-mr6400" -+ ;; -+ *"TL-WA701ND v2") -+ name="tl-wa701nd-v2" -+ ;; -+ *"TL-WA7210N v2") -+ name="tl-wa7210n-v2" -+ ;; -+ *"TL-WA750RE") -+ name="tl-wa750re" -+ ;; -+ *"TL-WA7510N v1") -+ name="tl-wa7510n" -+ ;; -+ *"TL-WA801ND v2") -+ name="tl-wa801nd-v2" -+ ;; -+ *"TL-WA801ND v3") -+ name="tl-wa801nd-v3" -+ ;; -+ *"TL-WA830RE v2") -+ name="tl-wa830re-v2" -+ ;; -+ *"TL-WA850RE") -+ name="tl-wa850re" -+ ;; -+ *"TL-WA850RE v2") -+ name="tl-wa850re-v2" -+ ;; -+ *"TL-WA855RE v1") -+ name="tl-wa855re-v1" -+ ;; -+ *"TL-WA860RE") -+ name="tl-wa860re" -+ ;; -+ *"TL-WA901ND") -+ name="tl-wa901nd" -+ ;; -+ *"TL-WA901ND v2") -+ name="tl-wa901nd-v2" -+ ;; -+ *"TL-WA901ND v3") -+ name="tl-wa901nd-v3" -+ ;; -+ *"TL-WA901ND v4") -+ name="tl-wa901nd-v4" -+ ;; -+ *"TL-WA901ND v5") -+ name="tl-wa901nd-v5" -+ ;; -+ *"TL-WDR3320 v2") -+ name="tl-wdr3320-v2" -+ ;; -+ *"TL-WDR3500") -+ name="tl-wdr3500" -+ ;; -+ *"TL-WDR3600/4300/4310") -+ name="tl-wdr4300" -+ ;; -+ *"TL-WDR4900 v2") -+ name="tl-wdr4900-v2" -+ ;; -+ *"TL-WDR6500 v2") -+ name="tl-wdr6500-v2" -+ ;; -+ *"TL-WPA8630") -+ name="tl-wpa8630" -+ ;; -+ *"TL-WR1041N v2") -+ name="tl-wr1041n-v2" -+ ;; -+ *"TL-WR1043N v5") -+ name="tl-wr1043n-v5" -+ ;; -+ *"TL-WR1043ND") -+ name="tl-wr1043nd" -+ ;; -+ *"TL-WR1043ND v2") -+ name="tl-wr1043nd-v2" -+ ;; -+ *"TL-WR1043ND v4") -+ name="tl-wr1043nd-v4" -+ ;; -+ *"TL-WR2543N"*) -+ name="tl-wr2543n" -+ ;; -+ *"TL-WR703N v1") -+ name="tl-wr703n" -+ ;; -+ *"TL-WR710N v1") -+ name="tl-wr710n" -+ ;; -+ *"TL-WR720N"*) -+ name="tl-wr720n-v3" -+ ;; -+ *"TL-WR740N/ND v6") -+ name="tl-wr740n-v6" -+ ;; -+ *"TL-WR741ND") -+ name="tl-wr741nd" -+ ;; -+ *"TL-WR741ND v4") -+ name="tl-wr741nd-v4" -+ ;; -+ *"TL-WR802N v1") -+ name="tl-wr802n-v1" -+ ;; -+ *"TL-WR802N v2") -+ name="tl-wr802n-v2" -+ ;; -+ *"TL-WR810N") -+ name="tl-wr810n" -+ ;; -+ *"TL-WR810N v2") -+ name="tl-wr810n-v2" -+ ;; -+ *"TL-WR840N v2") -+ name="tl-wr840n-v2" -+ ;; -+ *"TL-WR840N v3") -+ name="tl-wr840n-v3" -+ ;; -+ *"TL-WR841N v1") -+ name="tl-wr841n-v1" -+ ;; -+ *"TL-WR841N/ND v11") -+ name="tl-wr841n-v11" -+ ;; -+ *"TL-WR841N/ND v7") -+ name="tl-wr841n-v7" -+ ;; -+ *"TL-WR841N/ND v8") -+ name="tl-wr841n-v8" -+ ;; -+ *"TL-WR841N/ND v9") -+ name="tl-wr841n-v9" -+ ;; -+ *"TL-WR842N/ND v2") -+ name="tl-wr842n-v2" -+ ;; -+ *"TL-WR842N/ND v3") -+ name="tl-wr842n-v3" -+ ;; -+ *"TL-WR902AC v1") -+ name="tl-wr902ac-v1" -+ ;; -+ *"TL-WR940N v4") -+ name="tl-wr940n-v4" -+ ;; -+ *"TL-WR940N v6") -+ name="tl-wr940n-v6" -+ ;; -+ *"TL-WR941N/ND v5") -+ name="tl-wr941nd-v5" -+ ;; -+ *"TL-WR941N/ND v6") -+ name="tl-wr941nd-v6" -+ ;; -+ *"TL-WR941ND") -+ name="tl-wr941nd" -+ ;; -+ *"TL-WR942N v1") -+ name="tl-wr942n-v1" -+ ;; -+ *"TS-D084") -+ name="ts-d084" -+ ;; -+ *"Tube2H") -+ name="tube2h" -+ ;; -+ *"UniFi") -+ name="unifi" -+ ;; -+ *"UniFi AP Pro") -+ name="uap-pro" -+ ;; -+ *"UniFi-AC-LITE/MESH") -+ name="unifiac-lite" -+ ubnt_unifi_ac_board_detect -+ ;; -+ *"UniFi-AC-PRO/MESH-PRO") -+ name="unifiac-pro" -+ ubnt_unifi_ac_board_detect -+ ;; -+ *"UniFiAP Outdoor") -+ name="unifi-outdoor" -+ ;; -+ *"UniFiAP Outdoor+") -+ name="unifi-outdoor-plus" -+ ;; -+ *"WAM250") -+ name="wam250" -+ ;; -+ *"WBS210") -+ name="wbs210" -+ tplink_pharos_board_detect "$(tplink_pharos_get_model_string | tr -d '\r')" -+ ;; -+ *"WBS510") -+ name="wbs510" -+ tplink_pharos_board_detect "$(tplink_pharos_get_model_string | tr -d '\r')" -+ ;; -+ "WeIO"*) -+ name="weio" -+ ;; -+ *"WI2A-AC200i") -+ name="wi2a-ac200i" -+ ;; -+ *"WHR-G301N") -+ name="whr-g301n" -+ ;; -+ *"WHR-HP-G300N") -+ name="whr-hp-g300n" -+ ;; -+ *"WHR-HP-GN") -+ name="whr-hp-gn" -+ ;; -+ *"WiFi Pineapple NANO") -+ name="wifi-pineapple-nano" -+ ;; -+ *"WLAE-AG300N") -+ name="wlae-ag300n" -+ ;; -+ *"WLR-8100") -+ name="wlr8100" -+ ;; -+ *"WNDAP360") -+ name="wndap360" -+ ;; -+ *"WNDR3700/WNDR3800/WNDRMAC") -+ wndr3700_board_detect "$machine" -+ ;; -+ *"WNDR3700v4") -+ name="wndr3700v4" -+ ;; -+ *"WNDR4300") -+ name="wndr4300" -+ ;; -+ *"WNR1000 V2") -+ name="wnr1000-v2" -+ ;; -+ *"WNR2000") -+ name="wnr2000" -+ ;; -+ *"WNR2000 V3") -+ name="wnr2000-v3" -+ ;; -+ *"WNR2000 V4") -+ name="wnr2000-v4" -+ ;; -+ *"WNR2200") -+ name="wnr2200" -+ ;; -+ *"WNR612 V2") -+ name="wnr612-v2" -+ ;; -+ *"WP543") -+ name="wp543" -+ ;; -+ *"WPE72") -+ name="wpe72" -+ ;; -+ *"WPJ342") -+ name="wpj342" -+ ;; -+ *"WPJ344") -+ name="wpj344" -+ ;; -+ *"WPJ531") -+ name="wpj531" -+ ;; -+ *"WPJ558") -+ name="wpj558" -+ ;; -+ *"WPJ563") -+ name="wpj563" -+ ;; -+ *"WPN824N") -+ name="wpn824n" -+ ;; -+ *"WRT160NL") -+ name="wrt160nl" -+ ;; -+ *"WRT400N") -+ name="wrt400n" -+ ;; -+ *"WRTnode2Q"*) -+ name="wrtnode2q" -+ ;; -+ *"WZR-450HP2") -+ name="wzr-450hp2" -+ ;; -+ *"WZR-HP-AG300H/WZR-600DHP") -+ name="wzr-hp-ag300h" -+ ;; -+ *"WZR-HP-G300NH") -+ name="wzr-hp-g300nh" -+ ;; -+ *"WZR-HP-G300NH2") -+ name="wzr-hp-g300nh2" -+ ;; -+ *"WZR-HP-G450H") -+ name="wzr-hp-g450h" -+ ;; -+ *"XD3200") -+ name="xd3200" -+ ;; -+ *"Z1") -+ name="z1" -+ ;; -+ *"ZBT-WE1526") -+ name="zbt-we1526" -+ ;; -+ *"ZCN-1523H-2") -+ name="zcn-1523h-2" -+ ;; -+ *"ZCN-1523H-5") -+ name="zcn-1523h-5" -+ ;; -+ esac -+ -+ [ -z "$AR71XX_MODEL" ] && [ "${machine:0:8}" = 'TP-LINK ' ] && \ -+ tplink_board_detect "$machine" -+ -+ [ -z "$name" ] && name="unknown" -+ -+ [ -z "$AR71XX_BOARD_NAME" ] && AR71XX_BOARD_NAME="$name" -+ [ -z "$AR71XX_MODEL" ] && AR71XX_MODEL="$machine" -+ -+ [ -e "/tmp/sysinfo/" ] || mkdir -p "/tmp/sysinfo/" -+ -+ echo "$AR71XX_BOARD_NAME" > /tmp/sysinfo/board_name -+ echo "$AR71XX_MODEL" > /tmp/sysinfo/model -+} -diff --git a/target/linux/ar71xx/base-files/lib/preinit/01_preinit_do_ar71xx.sh b/target/linux/ar71xx/base-files/lib/preinit/01_preinit_do_ar71xx.sh -new file mode 100644 -index 0000000000..ff5407a0d4 ---- /dev/null -+++ b/target/linux/ar71xx/base-files/lib/preinit/01_preinit_do_ar71xx.sh -@@ -0,0 +1,9 @@ -+#!/bin/sh -+ -+do_ar71xx() { -+ . /lib/ar71xx.sh -+ -+ ar71xx_board_detect -+} -+ -+boot_hook_add preinit_main do_ar71xx -diff --git a/target/linux/ar71xx/base-files/lib/preinit/05_set_iface_mac_ar71xx b/target/linux/ar71xx/base-files/lib/preinit/05_set_iface_mac_ar71xx -new file mode 100644 -index 0000000000..b0aa150817 ---- /dev/null -+++ b/target/linux/ar71xx/base-files/lib/preinit/05_set_iface_mac_ar71xx -@@ -0,0 +1,60 @@ -+# -+# Copyright (C) 2009 OpenWrt.org -+# -+ -+fetch_mac_from_mtd() { -+ local mtd_part=$1 -+ local lan_env=$2 -+ local wan_env=$3 -+ local mtd mac -+ -+ mtd=$(grep $mtd_part /proc/mtd | cut -d: -f1) -+ [ -z $mtd ] && return -+ -+ mac=$(grep $lan_env /dev/$mtd | cut -d= -f2) -+ [ ! -z $mac ] && ifconfig eth0 hw ether $mac 2>/dev/null -+ -+ mac=$(grep $wan_env /dev/$mtd | cut -d= -f2) -+ [ ! -z $mac ] && ifconfig eth1 hw ether $mac 2>/dev/null -+} -+ -+preinit_set_mac_address() { -+ . /lib/functions.sh -+ -+ case $(board_name) in -+ c-55|\ -+ c-60) -+ mac_lan=$(mtd_get_mac_binary art 0x0) -+ [ -n "$mac_lan" ] && ifconfig eth0 hw ether "$mac_lan" -+ ;; -+ dir-615-c1|\ -+ tew-632brp) -+ fetch_mac_from_mtd config lan_mac wan_mac -+ ;; -+ dir-615-i1) -+ fetch_mac_from_mtd nvram sys_lan_mac sys_wan_mac -+ ;; -+ mr18|\ -+ z1) -+ mac_lan=$(mtd_get_mac_binary_ubi board-config 0x66) -+ [ -n "$mac_lan" ] && ifconfig eth0 hw ether "$mac_lan" -+ ;; -+ r6100) -+ mac_lan=$(mtd_get_mac_binary caldata 0x0) -+ [ -n "$mac_lan" ] && ifconfig eth1 hw ether "$mac_lan" -+ mac_wan=$(mtd_get_mac_binary caldata 0x6) -+ [ -n "$mac_wan" ] && ifconfig eth0 hw ether "$mac_wan" -+ ;; -+ rambutan) -+ mac_lan=$(mtd_get_mac_binary art 0x0) -+ [ -n "$mac_lan" ] && ifconfig eth0 hw ether "$mac_lan" -+ mac_wan=$(mtd_get_mac_binary art 0x6) -+ [ -n "$mac_wan" ] && ifconfig eth1 hw ether "$mac_wan" -+ ;; -+ wrt160nl) -+ fetch_mac_from_mtd nvram lan_hwaddr wan_hwaddr -+ ;; -+ esac -+} -+ -+boot_hook_add preinit_main preinit_set_mac_address -diff --git a/target/linux/ar71xx/base-files/lib/preinit/05_set_preinit_iface_ar71xx b/target/linux/ar71xx/base-files/lib/preinit/05_set_preinit_iface_ar71xx -new file mode 100644 -index 0000000000..68875fa1ec ---- /dev/null -+++ b/target/linux/ar71xx/base-files/lib/preinit/05_set_preinit_iface_ar71xx -@@ -0,0 +1,57 @@ -+#!/bin/sh -+ -+# -+# Copyright (C) 2009 OpenWrt.org -+# -+ -+set_preinit_iface() { -+ . /lib/functions.sh -+ -+ case $(board_name) in -+ alfa-ap96|\ -+ alfa-nx|\ -+ ap135-020|\ -+ ap136-020|\ -+ ap147-010|\ -+ archer-c5|\ -+ archer-c7|\ -+ bhr-4grv2|\ -+ dir-505-a1|\ -+ gl-ar750|\ -+ gl-inet|\ -+ jwap003|\ -+ pb42|\ -+ pb44|\ -+ rb-433|\ -+ rb-433u|\ -+ rb-435g|\ -+ rb-450|\ -+ rb-450g|\ -+ routerstation|\ -+ routerstation-pro|\ -+ smart-300|\ -+ tl-mr3420-v2|\ -+ tl-wdr4900-v2|\ -+ tl-wr1043nd-v2|\ -+ tl-wr710n|\ -+ tl-wr720n-v3|\ -+ tl-wr841n-v8|\ -+ tl-wr842n-v2|\ -+ tl-wr940n-v4|\ -+ tl-wr940n-v6|\ -+ tl-wr941nd-v6|\ -+ wnr1000-v2|\ -+ wnr2000-v3|\ -+ wnr2200|\ -+ wnr612-v2|\ -+ wpe72|\ -+ wpn824n) -+ ifname=eth1 -+ ;; -+ *) -+ ifname=eth0 -+ ;; -+ esac -+} -+ -+boot_hook_add preinit_main set_preinit_iface -diff --git a/target/linux/ar71xx/base-files/lib/preinit/82_patch_ath10k b/target/linux/ar71xx/base-files/lib/preinit/82_patch_ath10k -new file mode 100644 -index 0000000000..cc3dc42c9c ---- /dev/null -+++ b/target/linux/ar71xx/base-files/lib/preinit/82_patch_ath10k -@@ -0,0 +1,50 @@ -+#!/bin/sh -+ -+. /lib/functions.sh -+. /lib/functions/system.sh -+ -+do_patch_ath10k_firmware() { -+ local firmware_file="/lib/firmware/ath10k/QCA988X/hw2.0/firmware-5.bin" -+ -+ # bail out if firmware does not exist -+ [ -f "$firmware_file" ] || return -+ -+ local mac_offset=276 -+ local mac_length=6 -+ local default_mac="00:03:07:12:34:56" -+ local current_mac="$(hexdump -v -n $mac_length -s $mac_offset -e '5/1 "%02x:" 1/1 "%02x"' $firmware_file 2>/dev/null)" -+ -+ # check if mac address was already patched -+ [ "$default_mac" = "$current_mac" ] || return -+ -+ # some boards have bogus mac in otp (= directly in the PCIe card's EEPROM). -+ # we have to patch the default mac in the firmware because we cannot change -+ # the otp. -+ case $(board_name) in -+ dgl-5500-a1|\ -+ tew-823dru) -+ local mac -+ mac=$(mtd_get_mac_ascii nvram wlan1_mac) -+ -+ cp $firmware_file /tmp/ath10k-firmware.bin -+ macaddr_2bin $mac | dd of=/tmp/ath10k-firmware.bin \ -+ conv=notrunc bs=1 seek=$mac_offset count=$mac_length -+ ;; -+ esac -+ -+ [ -f /tmp/ath10k-firmware.bin ] || return -+ -+ cp /tmp/ath10k-firmware.bin $firmware_file -+ rm /tmp/ath10k-firmware.bin -+} -+ -+check_patch_ath10k_firmware() { -+ case $(board_name) in -+ dgl-5500-a1|\ -+ tew-823dru) -+ do_patch_ath10k_firmware -+ ;; -+ esac -+} -+ -+boot_hook_add preinit_main check_patch_ath10k_firmware -diff --git a/target/linux/ar71xx/base-files/lib/upgrade/allnet.sh b/target/linux/ar71xx/base-files/lib/upgrade/allnet.sh -new file mode 100644 -index 0000000000..5295d8cfe0 ---- /dev/null -+++ b/target/linux/ar71xx/base-files/lib/upgrade/allnet.sh -@@ -0,0 +1,155 @@ -+# The U-Boot loader of the some Allnet devices requires image sizes and -+# checksums to be provided in the U-Boot environment. -+# In case the check fails during boot, a failsafe-system is started to provide -+# a minimal web-interface for flashing a new firmware. -+ -+# determine size of the main firmware partition -+platform_get_firmware_size() { -+ local dev size erasesize name -+ while read dev size erasesize name; do -+ name=${name#'"'}; name=${name%'"'} -+ case "$name" in -+ firmware) -+ printf "%d" "0x$size" -+ break -+ ;; -+ esac -+ done < /proc/mtd -+} -+ -+# get the first 4 bytes (magic) of a given file starting at offset in hex format -+get_magic_long_at() { -+ dd if="$1" skip=$(( $CI_BLKSZ / 4 * $2 )) bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' -+} -+ -+get_filesize() { -+ wc -c "$1" | while read image_size _n ; do echo $image_size ; break; done -+} -+ -+# scan through the update image pages until matching a magic -+platform_get_offset() { -+ offsetcount=0 -+ magiclong="x" -+ if [ -n "$3" ]; then -+ offsetcount=$3 -+ fi -+ while magiclong=$( get_magic_long_at "$1" "$offsetcount" ) && [ -n "$magiclong" ]; do -+ case "$magiclong" in -+ "2705"*) -+ # U-Boot image magic -+ if [ "$2" = "uImage" ]; then -+ echo $offsetcount -+ return -+ fi -+ ;; -+ "68737173"|"73717368") -+ # SquashFS -+ if [ "$2" = "rootfs" ]; then -+ echo $offsetcount -+ return -+ fi -+ ;; -+ "deadc0de"|"19852003") -+ # JFFS2 empty page -+ if [ "$2" = "rootfs-data" ]; then -+ echo $offsetcount -+ return -+ fi -+ ;; -+ esac -+ offsetcount=$(( $offsetcount + 1 )) -+ done -+} -+ -+platform_check_image_allnet() { -+ local fw_printenv=/usr/sbin/fw_printenv -+ [ ! -n "$fw_printenv" -o ! -x "$fw_printenv" ] && { -+ echo "Please install uboot-envtools!" -+ return 1 -+ } -+ -+ [ ! -r "/etc/fw_env.config" ] && { -+ echo "/etc/fw_env.config is missing" -+ return 1 -+ } -+ -+ local image_size=$( get_filesize "$1" ) -+ local firmware_size=$( platform_get_firmware_size ) -+ [ $image_size -ge $firmware_size ] && -+ { -+ echo "upgrade image is too big (${image_size}b > ${firmware_size}b)" -+ } -+ -+ local vmlinux_blockoffset=$( platform_get_offset "$1" uImage ) -+ [ -z $vmlinux_blockoffset ] && { -+ echo "vmlinux-uImage not found" -+ return 1 -+ } -+ -+ local rootfs_blockoffset=$( platform_get_offset "$1" rootfs "$vmlinux_blockoffset" ) -+ [ -z $rootfs_blockoffset ] && { -+ echo "missing rootfs" -+ return 1 -+ } -+ -+ local data_blockoffset=$( platform_get_offset "$1" rootfs-data "$rootfs_blockoffset" ) -+ [ -z $data_blockoffset ] && { -+ echo "rootfs doesn't have JFFS2 end marker" -+ return 1 -+ } -+ -+ return 0 -+} -+ -+platform_do_upgrade_allnet() { -+ local firmware_base_addr=$( printf "%d" "$1" ) -+ local vmlinux_blockoffset=$( platform_get_offset "$2" uImage ) -+ if [ ! -n "$vmlinux_blockoffset" ]; then -+ echo "can't determine uImage offset" -+ return 1 -+ fi -+ local rootfs_blockoffset=$( platform_get_offset "$2" rootfs $(( $vmlinux_blockoffset + 1 )) ) -+ local vmlinux_offset=$(( $vmlinux_blockoffset * $CI_BLKSZ )) -+ local vmlinux_addr=$(( $firmware_base_addr + $vmlinux_offset )) -+ local vmlinux_hexaddr=0x$( printf "%08x" "$vmlinux_addr" ) -+ if [ ! -n "$rootfs_blockoffset" ]; then -+ echo "can't determine rootfs offset" -+ return 1 -+ fi -+ local rootfs_offset=$(( $rootfs_blockoffset * $CI_BLKSZ )) -+ local rootfs_addr=$(( $firmware_base_addr + $rootfs_offset )) -+ local rootfs_hexaddr=0x$( printf "%08x" "$rootfs_addr" ) -+ local vmlinux_blockcount=$(( $rootfs_blockoffset - $vmlinux_blockoffset )) -+ local vmlinux_size=$(( $rootfs_offset - $vmlinux_offset )) -+ local vmlinux_hexsize=0x$( printf "%08x" "$vmlinux_size" ) -+ local data_blockoffset=$( platform_get_offset "$2" rootfs-data $(( $rootfs_blockoffset + 1 )) ) -+ if [ ! -n "$data_blockoffset" ]; then -+ echo "can't determine rootfs size" -+ return 1 -+ fi -+ local data_offset=$(( $data_blockoffset * $CI_BLKSZ )) -+ local rootfs_blockcount=$(( $data_blockoffset - $rootfs_blockoffset )) -+ local rootfs_size=$(( $data_offset - $rootfs_offset )) -+ local rootfs_hexsize=0x$( printf "%08x" "$rootfs_size" ) -+ -+ local rootfs_md5=$( dd if="$2" bs=$CI_BLKSZ skip=$rootfs_blockoffset count=$rootfs_blockcount 2>/dev/null | md5sum -); rootfs_md5="${rootfs_md5%% *}" -+ local vmlinux_md5=$( dd if="$2" bs=$CI_BLKSZ skip=$vmlinux_blockoffset count=$vmlinux_blockcount 2>/dev/null | md5sum -); vmlinux_md5="${vmlinux_md5%% *}" -+ # this needs a recent version of uboot-envtools! -+ cat >/tmp/fw_env_upgrade </dev/null | hexdump -v -n 4 -e '1/1 "%02x"' -+} -+ -+dir825b_is_caldata_valid() { -+ local mtddev=$1 -+ local magic -+ -+ magic=$(get_magic_at $mtddev 4096) -+ [ "$magic" != "a55a" ] && return 0 -+ -+ magic=$(get_magic_at $mtddev 20480) -+ [ "$magic" != "a55a" ] && return 0 -+ -+ return 1 -+} -+ -+dir825b_copy_caldata() { -+ local cal_src=$1 -+ local cal_dst=$2 -+ local mtd_src -+ local mtd_dst -+ local md5_src -+ local md5_dst -+ -+ mtd_src=$(find_mtd_part $cal_src) -+ [ -z "$mtd_src" ] && { -+ echo "no $cal_src partition found" -+ return 1 -+ } -+ -+ mtd_dst=$(find_mtd_part $cal_dst) -+ [ -z "$mtd_dst" ] && { -+ echo "no $cal_dst partition found" -+ return 1 -+ } -+ -+ dir825b_is_caldata_valid "$mtd_src" && { -+ echo "no valid calibration data found in $cal_src" -+ return 1 -+ } -+ -+ dir825b_is_caldata_valid "$mtd_dst" && { -+ echo "Copying calibration data from $cal_src to $cal_dst..." -+ dd if="$mtd_src" 2>/dev/null | mtd -q -q write - "$cal_dst" -+ } -+ -+ md5_src=$(md5sum "$mtd_src") && md5_src="${md5_src%% *}" -+ md5_dst=$(md5sum "$mtd_dst") && md5_dst="${md5_dst%% *}" -+ -+ [ "$md5_src" != "$md5_dst" ] && { -+ echo "calibration data mismatch $cal_src:$md5_src $cal_dst:$md5_dst" -+ return 1 -+ } -+ -+ return 0 -+} -+ -+dir825b_do_upgrade_combined() { -+ local fw_part=$1 -+ local fw_file=$2 -+ local fw_mtd=$(find_mtd_part $fw_part) -+ local fw_length=0x$(dd if="$fw_file" bs=2 skip=1 count=4 2>/dev/null) -+ local fw_blocks=$(($fw_length / 65536)) -+ -+ if [ -n "$fw_mtd" ] && [ ${fw_blocks:-0} -gt 0 ]; then -+ local append="" -+ [ -f "$UPGRADE_BACKUP" ] && append="-j $UPGRADE_BACKUP" -+ -+ sync -+ dd if="$fw_file" bs=64k skip=1 count=$fw_blocks 2>/dev/null | \ -+ mtd $append write - "$fw_part" -+ fi -+} -+ -+dir825b_check_image() { -+ local magic="$(get_magic_long "$1")" -+ local fw_mtd=$(find_mtd_part "firmware_orig") -+ -+ case "$magic" in -+ "27051956") -+ ;; -+ "43493030") -+ local md5_img=$(dd if="$1" bs=2 skip=9 count=16 2>/dev/null) -+ local md5_chk=$(dd if="$1" bs=64k skip=1 2>/dev/null | md5sum -); md5_chk="${md5_chk%% *}" -+ local fw_len=$(dd if="$1" bs=2 skip=1 count=4 2>/dev/null) -+ local fw_part_len=$(mtd_get_part_size "firmware") -+ -+ if [ -z "$fw_mtd" ]; then -+ ask_bool 0 "Do you have a backup of the caldata partition?" || { -+ echo "Warning, please make sure that you have a backup of the caldata partition." -+ echo "Once you have that, use 'sysupgrade -i' for upgrading to the 'fat' firmware." -+ return 1 -+ } -+ fi -+ -+ if [ -z "$md5_img" -o -z "$md5_chk" ]; then -+ echo "Unable to get image checksums. Maybe you are using a streamed image?" -+ return 1 -+ fi -+ -+ if [ "$md5_img" != "$md5_chk" ]; then -+ echo "Invalid image. Contents do not match checksum (image:$md5_img calculated:$md5_chk)" -+ return 1 -+ fi -+ -+ fw_len=$((0x$fw_len)) -+ fw_part_len=${fw_part_len:-0} -+ -+ if [ $fw_part_len -lt $fw_len ]; then -+ echo "The upgrade image is too big (size:$fw_len available:$fw_part_len)" -+ return 1 -+ fi -+ ;; -+ *) -+ echo "Unsupported image format." -+ return 1 -+ ;; -+ esac -+ -+ return 0 -+} -+ -+platform_do_upgrade_dir825b() { -+ local magic="$(get_magic_long "$1")" -+ local fw_mtd=$(find_mtd_part "firmware_orig") -+ -+ case "$magic" in -+ "27051956") -+ if [ -n "$fw_mtd" ]; then -+ # restore calibration data before downgrading to -+ # the normal image -+ dir825b_copy_caldata "caldata" "caldata_orig" || { -+ echo "unable to restore calibration data" -+ exit 1 -+ } -+ PART_NAME="firmware_orig" -+ else -+ PART_NAME="firmware" -+ fi -+ default_do_upgrade "$1" -+ ;; -+ "43493030") -+ if [ -z "$fw_mtd" ]; then -+ # backup calibration data before upgrading to the -+ # fat image -+ dir825b_copy_caldata "caldata" "caldata_copy" || { -+ echo "unable to backup calibration data" -+ exit 1 -+ } -+ fi -+ dir825b_do_upgrade_combined "firmware" "$1" -+ ;; -+ esac -+} -diff --git a/target/linux/ar71xx/base-files/lib/upgrade/merakinand.sh b/target/linux/ar71xx/base-files/lib/upgrade/merakinand.sh -new file mode 100644 -index 0000000000..dfc57b23f5 ---- /dev/null -+++ b/target/linux/ar71xx/base-files/lib/upgrade/merakinand.sh -@@ -0,0 +1,165 @@ -+#!/bin/sh -+# -+# Copyright (C) 2015-2016 Chris Blake -+# -+# Custom upgrade script for Meraki NAND devices (ex. MR18) -+# Based on dir825.sh and stock nand functions -+# -+. /lib/ar71xx.sh -+. /lib/functions.sh -+ -+get_magic_at() { -+ local mtddev=$1 -+ local pos=$2 -+ dd bs=1 count=2 skip=$pos if=$mtddev 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' -+} -+ -+meraki_is_caldata_valid() { -+ local board=$1 -+ local mtddev=$2 -+ local magic -+ -+ case "$board" in -+ "mr18") -+ magic=$(get_magic_at $mtddev 4096) -+ [ "$magic" != "0202" ] && return 0 -+ -+ magic=$(get_magic_at $mtddev 20480) -+ [ "$magic" != "0202" ] && return 0 -+ -+ magic=$(get_magic_at $mtddev 36864) -+ [ "$magic" != "0202" ] && return 0 -+ -+ return 1 -+ ;; -+ "z1") -+ magic=$(get_magic_at $mtddev 4096) -+ [ "$magic" != "0202" ] && return 0 -+ -+ magic=$(get_magic_at $mtddev 86016) -+ [ "$magic" != "a55a" ] && return 0 -+ -+ return 1 -+ ;; -+ *) -+ return 1 -+ ;; -+ esac -+} -+ -+merakinand_copy_caldata() { -+ local cal_src=$1 -+ local cal_dst=$2 -+ local ubidev="$(nand_find_ubi $CI_UBIPART)" -+ local board_name="$(board_name)" -+ local rootfs_size="$(ubinfo /dev/ubi0 -N rootfs_data | grep "Size" | awk '{ print $6 }')" -+ -+ # Setup partitions using board name, in case of future platforms -+ case "$board_name" in -+ "mr18"|\ -+ "z1") -+ # Src is MTD -+ mtd_src="$(find_mtd_chardev $cal_src)" -+ [ -n "$mtd_src" ] || { -+ echo "no mtd device found for partition $cal_src" -+ exit 1 -+ } -+ -+ # Dest is UBI -+ # TODO: possibly add create (hard to do when rootfs_data is expanded & mounted) -+ # Would need to be done from ramdisk -+ mtd_dst="$(nand_find_volume $ubidev $cal_dst)" -+ [ -n "$mtd_dst" ] || { -+ echo "no ubi device found for partition $cal_dst" -+ exit 1 -+ } -+ -+ meraki_is_caldata_valid "$board_name" "$mtd_src" && { -+ echo "no valid calibration data found in $cal_src" -+ exit 1 -+ } -+ -+ meraki_is_caldata_valid "$board_name" "/dev/$mtd_dst" && { -+ echo "Copying calibration data from $cal_src to $cal_dst..." -+ dd if="$mtd_src" of=/tmp/caldata.tmp 2>/dev/null -+ ubiupdatevol "/dev/$mtd_dst" /tmp/caldata.tmp -+ rm /tmp/caldata.tmp -+ sync -+ } -+ return 0 -+ ;; -+ *) -+ echo "Unsupported device $board_name"; -+ return 1 -+ ;; -+ esac -+} -+ -+merakinand_do_kernel_check() { -+ local board_name="$1" -+ local tar_file="$2" -+ local image_magic_word=`(tar xf $tar_file sysupgrade-$board_name/kernel -O 2>/dev/null | dd bs=1 count=4 skip=0 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"')` -+ -+ # What is our kernel magic string? -+ case "$board_name" in -+ "mr18") -+ [ "$image_magic_word" == "8e73ed8a" ] && { -+ echo "pass" && return 0 -+ } -+ ;; -+ "z1") -+ [ "$image_magic_word" == "4d495053" ] && { -+ echo "pass" && return 0 -+ } -+ ;; -+ esac -+ -+ exit 1 -+} -+ -+merakinand_do_platform_check() { -+ local board_name="$1" -+ local tar_file="$2" -+ local control_length=`(tar xf $tar_file sysupgrade-$board_name/CONTROL -O | wc -c) 2> /dev/null` -+ local file_type="$(identify_tar $2 sysupgrade-$board_name/root)" -+ local kernel_magic="$(merakinand_do_kernel_check $1 $2)" -+ -+ case "$board_name" in -+ "mr18"|\ -+ "z1") -+ [ "$control_length" = 0 -o "$file_type" != "squashfs" -o "$kernel_magic" != "pass" ] && { -+ echo "Invalid sysupgrade file for $board_name" -+ return 1 -+ } -+ ;; -+ *) -+ echo "Unsupported device $board_name"; -+ return 1 -+ ;; -+ esac -+ -+ return 0 -+} -+ -+merakinand_do_upgrade() { -+ local tar_file="$1" -+ local board_name="$(board_name)" -+ -+ # Do we need to do any platform tweaks? -+ case "$board_name" in -+ "mr18") -+ # Check and create UBI caldata if it's invalid -+ merakinand_copy_caldata "odm-caldata" "caldata" -+ nand_do_upgrade $1 -+ ;; -+ "z1") -+ # Check and create UBI caldata if it's invalid -+ merakinand_copy_caldata "origcaldata" "caldata" -+ nand_do_upgrade $1 -+ ;; -+ *) -+ echo "Unsupported device $board_name"; -+ exit 1 -+ ;; -+ esac -+} -diff --git a/target/linux/ar71xx/base-files/lib/upgrade/openmesh.sh b/target/linux/ar71xx/base-files/lib/upgrade/openmesh.sh -new file mode 100644 -index 0000000000..f43bdcea7f ---- /dev/null -+++ b/target/linux/ar71xx/base-files/lib/upgrade/openmesh.sh -@@ -0,0 +1,232 @@ -+# The U-Boot loader of the OpenMesh devices requires image sizes and -+# checksums to be provided in the U-Boot environment. -+# The OpenMesh devices come with 2 main partitions - while one is active -+# sysupgrade will flash the other. The boot order is changed to boot the -+# newly flashed partition. If the new partition can't be booted due to -+# upgrade failures the previously used partition is loaded. -+ -+trim() -+{ -+ echo $1 -+} -+ -+cfg_value_get() -+{ -+ local cfg=$1 cfg_opt -+ local section=$2 our_section=0 -+ local param=$3 our_param= -+ -+ for cfg_opt in $cfg -+ do -+ [ "$cfg_opt" = "[$section]" ] && our_section=1 && continue -+ [ "$our_section" = "1" ] || continue -+ -+ our_param=$(echo ${cfg_opt%%=*}) -+ [ "$param" = "$our_param" ] && echo ${cfg_opt##*=} && break -+ done -+} -+ -+platform_check_image_target_openmesh() -+{ -+ img_board_target="$1" -+ -+ case "$img_board_target" in -+ A60) -+ [ "$board" = "a40" ] && return 0 -+ [ "$board" = "a60" ] && return 0 -+ echo "Invalid image board target ($img_board_target) for this platform: $board. Use the correct image for this platform" -+ return 1 -+ ;; -+ OM2P) -+ [ "$board" = "om2p" ] && return 0 -+ [ "$board" = "om2pv2" ] && return 0 -+ [ "$board" = "om2pv4" ] && return 0 -+ [ "$board" = "om2p-lc" ] && return 0 -+ [ "$board" = "om2p-hs" ] && return 0 -+ [ "$board" = "om2p-hsv2" ] && return 0 -+ [ "$board" = "om2p-hsv3" ] && return 0 -+ [ "$board" = "om2p-hsv4" ] && return 0 -+ echo "Invalid image board target ($img_board_target) for this platform: $board. Use the correct image for this platform" -+ return 1 -+ ;; -+ OM5P) -+ [ "$board" = "om5p" ] && return 0 -+ [ "$board" = "om5p-an" ] && return 0 -+ echo "Invalid image board target ($img_board_target) for this platform: $board. Use the correct image for this platform" -+ return 1 -+ ;; -+ OM5PAC) -+ [ "$board" = "om5p-ac" ] && return 0 -+ [ "$board" = "om5p-acv2" ] && return 0 -+ echo "Invalid image board target ($img_board_target) for this platform: $board. Use the correct image for this platform" -+ return 1 -+ ;; -+ MR1750) -+ [ "$board" = "mr1750" ] && return 0 -+ [ "$board" = "mr1750v2" ] && return 0 -+ echo "Invalid image board target ($img_board_target) for this platform: $board. Use the correct image for this platform" -+ return 1 -+ ;; -+ MR600) -+ [ "$board" = "mr600" ] && return 0 -+ [ "$board" = "mr600v2" ] && return 0 -+ echo "Invalid image board target ($img_board_target) for this platform: $board. Use the correct image for this platform" -+ return 1 -+ ;; -+ MR900) -+ [ "$board" = "mr900" ] && return 0 -+ [ "$board" = "mr900v2" ] && return 0 -+ echo "Invalid image board target ($img_board_target) for this platform: $board. Use the correct image for this platform" -+ return 1 -+ ;; -+ *) -+ echo "Invalid board target ($img_board_target). Use the correct image for this platform" -+ return 1 -+ ;; -+ esac -+} -+ -+platform_check_image_openmesh() -+{ -+ local img_magic=$1 -+ local img_path=$2 -+ local fw_printenv=/usr/sbin/fw_printenv -+ local img_board_target= img_num_files= i=0 -+ local cfg_name= kernel_name= rootfs_name= -+ -+ case "$img_magic" in -+ # Combined Extended Image v1 -+ 43453031) -+ img_board_target=$(trim $(dd if="$img_path" bs=4 skip=1 count=8 2>/dev/null)) -+ img_num_files=$(trim $(dd if="$img_path" bs=2 skip=18 count=1 2>/dev/null)) -+ ;; -+ *) -+ echo "Invalid image ($img_magic). Use combined extended images on this platform" -+ return 1 -+ ;; -+ esac -+ -+ platform_check_image_target_openmesh "$img_board_target" || return 1 -+ -+ [ $img_num_files -lt 3 ] && { -+ echo "Invalid number of embedded images ($img_num_files). Use the correct image for this platform" -+ return 1 -+ } -+ -+ cfg_name=$(trim $(dd if="$img_path" bs=2 skip=19 count=16 2>/dev/null)) -+ -+ [ "$cfg_name" != "fwupgrade.cfg" ] && { -+ echo "Invalid embedded config file ($cfg_name). Use the correct image for this platform" -+ return 1 -+ } -+ -+ kernel_name=$(trim $(dd if="$img_path" bs=2 skip=55 count=16 2>/dev/null)) -+ -+ [ "$kernel_name" != "kernel" ] && { -+ echo "Invalid embedded kernel file ($kernel_name). Use the correct image for this platform" -+ return 1 -+ } -+ -+ rootfs_name=$(trim $(dd if="$img_path" bs=2 skip=91 count=16 2>/dev/null)) -+ -+ [ "$rootfs_name" != "rootfs" ] && { -+ echo "Invalid embedded kernel file ($rootfs_name). Use the correct image for this platform" -+ return 1 -+ } -+ -+ [ ! -x "$fw_printenv" ] && { -+ echo "Please install uboot-envtools!" -+ return 1 -+ } -+ -+ [ ! -r "/etc/fw_env.config" ] && { -+ echo "/etc/fw_env.config is missing" -+ return 1 -+ } -+ -+ return 0 -+} -+ -+platform_do_upgrade_openmesh() -+{ -+ local img_path=$1 img_board_target= -+ local kernel_start_addr= kernel_start_addr1= kernel_start_addr2= -+ local kernel_size= kernel_md5= -+ local rootfs_size= rootfs_checksize= rootfs_md5= -+ local kernel_bsize= total_size= -+ local data_offset=$((64 * 1024)) block_size= offset= -+ local uboot_env_upgrade="/tmp/fw_env_upgrade" -+ local cfg_size= kernel_size= rootfs_size= -+ local append="" -+ -+ [ -f "$UPGRADE_BACKUP" ] && append="-j $UPGRADE_BACKUP" -+ -+ cfg_size=$(dd if="$img_path" bs=2 skip=35 count=4 2>/dev/null) -+ kernel_size=$(dd if="$img_path" bs=2 skip=71 count=4 2>/dev/null) -+ rootfs_size=$(dd if="$img_path" bs=2 skip=107 count=4 2>/dev/null) -+ -+ img_board_target=$(trim $(dd if="$img_path" bs=4 skip=1 count=8 2>/dev/null)) -+ cfg_content=$(dd if="$img_path" bs=1 skip=$data_offset count=$(echo $((0x$cfg_size))) 2>/dev/null) -+ -+ case $img_board_target in -+ OM2P) -+ block_size=$((256 * 1024)) -+ total_size=7340032 -+ kernel_start_addr1=0x9f1c0000 -+ kernel_start_addr2=0x9f8c0000 -+ ;; -+ OM5P|OM5PAC|MR600|MR900|MR1750|A60) -+ block_size=$((64 * 1024)) -+ total_size=7995392 -+ kernel_start_addr1=0x9f0b0000 -+ kernel_start_addr2=0x9f850000 -+ ;; -+ esac -+ -+ kernel_md5=$(cfg_value_get "$cfg_content" "vmlinux" "md5sum") -+ rootfs_md5=$(cfg_value_get "$cfg_content" "rootfs" "md5sum") -+ rootfs_checksize=$(cfg_value_get "$cfg_content" "rootfs" "checksize") -+ -+ if [ "$((0x$kernel_size % $block_size))" = "0" ] -+ then -+ kernel_bsize=$(echo $((0x$kernel_size))) -+ else -+ kernel_bsize=$((0x$kernel_size + ($block_size - (0x$kernel_size % $block_size)))) -+ fi -+ -+ mtd -q erase inactive -+ -+ offset=$(echo $(($data_offset + 0x$cfg_size + 0x$kernel_size))) -+ dd if="$img_path" bs=1 skip=$offset count=$(echo $((0x$rootfs_size))) 2>&- | mtd -n -p $kernel_bsize $append write - "inactive" -+ -+ offset=$(echo $(($data_offset + 0x$cfg_size))) -+ dd if="$img_path" bs=1 skip=$offset count=$(echo $((0x$kernel_size))) 2>&- | mtd -n write - "inactive" -+ -+ rm $uboot_env_upgrade 2>&- -+ -+ if [ "$(grep 'mtd3:.*inactive' /proc/mtd)" ] -+ then -+ printf "kernel_size_1 %u\n" $(($kernel_bsize / 1024)) >> $uboot_env_upgrade -+ printf "rootfs_size_1 %u\n" $((($total_size - $kernel_bsize) / 1024)) >> $uboot_env_upgrade -+ printf "bootseq 1,2\n" >> $uboot_env_upgrade -+ kernel_start_addr=$kernel_start_addr1 -+ else -+ printf "kernel_size_2 %u\n" $(($kernel_bsize / 1024)) >> $uboot_env_upgrade -+ printf "rootfs_size_2 %u\n" $((($total_size - $kernel_bsize) / 1024)) >> $uboot_env_upgrade -+ printf "bootseq 2,1\n" >> $uboot_env_upgrade -+ kernel_start_addr=$kernel_start_addr2 -+ fi -+ -+ printf "vmlinux_start_addr %s\n" $kernel_start_addr >> $uboot_env_upgrade -+ printf "vmlinux_size 0x%s\n" $kernel_size >> $uboot_env_upgrade -+ printf "vmlinux_checksum %s\n" $kernel_md5 >> $uboot_env_upgrade -+ printf "rootfs_start_addr 0x%x\n" $(($kernel_start_addr + $kernel_bsize)) >> $uboot_env_upgrade -+ printf "rootfs_size %s\n" $rootfs_checksize >> $uboot_env_upgrade -+ printf "rootfs_checksum %s\n" $rootfs_md5 >> $uboot_env_upgrade -+ -+ mkdir -p /var/lock -+ fw_setenv -s $uboot_env_upgrade || { -+ echo "failed to update U-Boot environment" -+ return 1 -+ } -+} -diff --git a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh -new file mode 100755 -index 0000000000..2391a1de8a ---- /dev/null -+++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh -@@ -0,0 +1,915 @@ -+# -+# Copyright (C) 2011 OpenWrt.org -+# -+ -+. /lib/functions/system.sh -+. /lib/ar71xx.sh -+ -+PART_NAME=firmware -+RAMFS_COPY_DATA='/lib/ar71xx.sh /etc/fw_env.config /var/lock/fw_printenv.lock' -+RAMFS_COPY_BIN='nandwrite fw_printenv fw_setenv' -+ -+CI_BLKSZ=65536 -+CI_LDADR=0x80060000 -+ -+PLATFORM_DO_UPGRADE_COMBINED_SEPARATE_MTD=0 -+ -+platform_find_partitions() { -+ local first dev size erasesize name -+ while read dev size erasesize name; do -+ name=${name#'"'}; name=${name%'"'} -+ case "$name" in -+ vmlinux.bin.l7|vmlinux|kernel|linux|linux.bin|rootfs|filesystem) -+ if [ -z "$first" ]; then -+ first="$name" -+ else -+ echo "$erasesize:$first:$name" -+ break -+ fi -+ ;; -+ esac -+ done < /proc/mtd -+} -+ -+platform_find_kernelpart() { -+ local part -+ for part in "${1%:*}" "${1#*:}"; do -+ case "$part" in -+ vmlinux.bin.l7|vmlinux|kernel|linux|linux.bin) -+ echo "$part" -+ break -+ ;; -+ esac -+ done -+} -+ -+platform_find_rootfspart() { -+ local part -+ for part in "${1%:*}" "${1#*:}"; do -+ [ "$part" != "$2" ] && echo "$part" && break -+ done -+} -+ -+platform_do_upgrade_combined() { -+ local partitions=$(platform_find_partitions) -+ local kernelpart=$(platform_find_kernelpart "${partitions#*:}") -+ local erase_size=$((0x${partitions%%:*})); partitions="${partitions#*:}" -+ local kern_length=0x$(dd if="$1" bs=2 skip=1 count=4 2>/dev/null) -+ local kern_blocks=$(($kern_length / $CI_BLKSZ)) -+ local root_blocks=$((0x$(dd if="$1" bs=2 skip=5 count=4 2>/dev/null) / $CI_BLKSZ)) -+ -+ if [ -n "$partitions" ] && [ -n "$kernelpart" ] && \ -+ [ ${kern_blocks:-0} -gt 0 ] && \ -+ [ ${root_blocks:-0} -gt 0 ] && \ -+ [ ${erase_size:-0} -gt 0 ]; -+ then -+ local rootfspart=$(platform_find_rootfspart "$partitions" "$kernelpart") -+ local append="" -+ [ -f "$UPGRADE_BACKUP" ] && append="-j $UPGRADE_BACKUP" -+ -+ if [ "$PLATFORM_DO_UPGRADE_COMBINED_SEPARATE_MTD" -ne 1 ]; then -+ ( dd if="$1" bs=$CI_BLKSZ skip=1 count=$kern_blocks 2>/dev/null; \ -+ dd if="$1" bs=$CI_BLKSZ skip=$((1+$kern_blocks)) count=$root_blocks 2>/dev/null ) | \ -+ mtd -r $append -F$kernelpart:$kern_length:$CI_LDADR,rootfs write - $partitions -+ elif [ -n "$rootfspart" ]; then -+ dd if="$1" bs=$CI_BLKSZ skip=1 count=$kern_blocks 2>/dev/null | \ -+ mtd write - $kernelpart -+ dd if="$1" bs=$CI_BLKSZ skip=$((1+$kern_blocks)) count=$root_blocks 2>/dev/null | \ -+ mtd -r $append write - $rootfspart -+ fi -+ fi -+ PLATFORM_DO_UPGRADE_COMBINED_SEPARATE_MTD=0 -+} -+ -+tplink_get_image_hwid() { -+ get_image "$@" | dd bs=4 count=1 skip=16 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' -+} -+ -+tplink_get_image_mid() { -+ get_image "$@" | dd bs=4 count=1 skip=17 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' -+} -+ -+tplink_get_image_boot_size() { -+ get_image "$@" | dd bs=4 count=1 skip=37 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' -+} -+ -+tplink_pharos_check_support_list() { -+ local image="$1" -+ local offset="$2" -+ local model="$3" -+ local trargs="$4" -+ -+ # Here $image is given to dd directly instead of using get_image; -+ # otherwise the skip will take almost a second (as dd can't seek) -+ dd if="$image" bs=1 skip=$offset count=1024 2>/dev/null | tr -d "$trargs" | ( -+ while IFS= read -r line; do -+ [ "$line" = "$model" ] && exit 0 -+ done -+ -+ exit 1 -+ ) -+} -+ -+tplink_pharos_check_image() { -+ local image_magic="$(get_magic_long "$1")" -+ local board_magic="$2" -+ [ "$image_magic" != "$board_magic" ] && { -+ echo "Invalid image magic '$image_magic'. Expected '$board_magic'." -+ return 1 -+ } -+ -+ local model_string="$3" -+ local trargs="$4" -+ -+ # New images have the support list at 7802888, old ones at 1511432 -+ tplink_pharos_check_support_list "$1" 7802888 "$model_string" "$trargs" || \ -+ tplink_pharos_check_support_list "$1" 1511432 "$model_string" "$trargs" || { -+ echo "Unsupported image (model not in support-list)" -+ return 1 -+ } -+ -+ return 0 -+} -+ -+seama_get_type_magic() { -+ get_image "$@" | dd bs=1 count=4 skip=53 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' -+} -+ -+wrgg_get_image_magic() { -+ get_image "$@" | dd bs=4 count=1 skip=8 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' -+} -+ -+cybertan_get_image_magic() { -+ get_image "$@" | dd bs=8 count=1 skip=0 2>/dev/null | hexdump -v -n 8 -e '1/1 "%02x"' -+} -+ -+cybertan_check_image() { -+ local magic="$(cybertan_get_image_magic "$1")" -+ local fw_magic="$(cybertan_get_hw_magic)" -+ -+ [ "$fw_magic" != "$magic" ] && { -+ echo "Invalid image, ID mismatch, got:$magic, but need:$fw_magic" -+ return 1 -+ } -+ -+ return 0 -+} -+ -+platform_do_upgrade_compex() { -+ local fw_file=$1 -+ local fw_part=$PART_NAME -+ local fw_mtd=$(find_mtd_part $fw_part) -+ local fw_length=0x$(dd if="$fw_file" bs=2 skip=1 count=4 2>/dev/null) -+ local fw_blocks=$(($fw_length / 65536)) -+ -+ if [ -n "$fw_mtd" ] && [ ${fw_blocks:-0} -gt 0 ]; then -+ local append="" -+ [ -f "$UPGRADE_BACKUP" ] && append="-j $UPGRADE_BACKUP" -+ -+ sync -+ dd if="$fw_file" bs=64k skip=1 count=$fw_blocks 2>/dev/null | \ -+ mtd $append write - "$fw_part" -+ fi -+} -+ -+alfa_check_image() { -+ local magic_long="$(get_magic_long "$1")" -+ local fw_part_size=$(mtd_get_part_size firmware) -+ -+ case "$magic_long" in -+ "27051956") -+ [ "$fw_part_size" != "16318464" ] && { -+ echo "Invalid image magic \"$magic_long\" for $fw_part_size bytes" -+ return 1 -+ } -+ ;; -+ "68737173") -+ [ "$fw_part_size" != "7929856" ] && { -+ echo "Invalid image magic \"$magic_long\" for $fw_part_size bytes" -+ return 1 -+ } -+ ;; -+ esac -+ -+ return 0 -+} -+ -+platform_check_image() { -+ local board=$(board_name) -+ local magic="$(get_magic_word "$1")" -+ local magic_long="$(get_magic_long "$1")" -+ -+ [ "$#" -gt 1 ] && return 1 -+ -+ case "$board" in -+ airgateway|\ -+ airgatewaypro|\ -+ airrouter|\ -+ ap121f|\ -+ ap132|\ -+ ap531b0|\ -+ ap90q|\ -+ archer-c25-v1|\ -+ archer-c58-v1|\ -+ archer-c59-v1|\ -+ archer-c59-v2|\ -+ archer-c60-v1|\ -+ archer-c60-v2|\ -+ archer-c7-v4|\ -+ archer-c7-v5|\ -+ arduino-yun|\ -+ bullet-m|\ -+ bullet-m-xw|\ -+ c-55|\ -+ carambola2|\ -+ cf-e316n-v2|\ -+ cf-e320n-v2|\ -+ cf-e355ac-v1|\ -+ cf-e355ac-v2|\ -+ cf-e375ac|\ -+ cf-e380ac-v1|\ -+ cf-e380ac-v2|\ -+ cf-e385ac|\ -+ cf-e520n|\ -+ cf-e530n|\ -+ cpe505n|\ -+ cpe830|\ -+ cpe870|\ -+ dap-1330-a1|\ -+ dgl-5500-a1|\ -+ dhp-1565-a1|\ -+ dir-505-a1|\ -+ dir-600-a1|\ -+ dir-615-c1|\ -+ dir-615-e1|\ -+ dir-615-e4|\ -+ dir-615-i1|\ -+ dir-825-c1|\ -+ dir-835-a1|\ -+ dlan-hotspot|\ -+ dlan-pro-1200-ac|\ -+ dlan-pro-500-wp|\ -+ dr342|\ -+ dr531|\ -+ dragino2|\ -+ e1700ac-v2|\ -+ e558-v2|\ -+ e600g-v2|\ -+ e600gac-v2|\ -+ e750a-v4|\ -+ e750g-v8|\ -+ ebr-2310-c1|\ -+ ens202ext|\ -+ epg5000|\ -+ esr1750|\ -+ esr900|\ -+ ew-balin|\ -+ ew-dorin|\ -+ ew-dorin-router|\ -+ gl-ar150|\ -+ gl-ar300m|\ -+ gl-ar300|\ -+ gl-ar750|\ -+ gl-ar750s|\ -+ gl-domino|\ -+ gl-mifi|\ -+ gl-usb150|\ -+ hiwifi-hc6361|\ -+ hornet-ub-x2|\ -+ jwap230|\ -+ lbe-m5|\ -+ lima|\ -+ loco-m-xw|\ -+ mzk-w04nu|\ -+ mzk-w300nh|\ -+ n5q|\ -+ nanostation-m|\ -+ nanostation-m-xw|\ -+ nbg460n_550n_550nh|\ -+ pqi-air-pen|\ -+ r36a|\ -+ r602n|\ -+ rme-eg200|\ -+ rocket-m|\ -+ rocket-m-ti|\ -+ rocket-m-xw|\ -+ rw2458n|\ -+ sc1750|\ -+ sc300m|\ -+ sc450|\ -+ sr3200|\ -+ t830|\ -+ tew-632brp|\ -+ tew-712br|\ -+ tew-732br|\ -+ tew-823dru|\ -+ tl-wr1043n-v5|\ -+ tl-wr942n-v1|\ -+ unifi|\ -+ unifi-outdoor|\ -+ unifiac-lite|\ -+ unifiac-pro|\ -+ wam250|\ -+ weio|\ -+ whr-g301n|\ -+ whr-hp-g300n|\ -+ whr-hp-gn|\ -+ wlae-ag300n|\ -+ wndap360|\ -+ wpj342|\ -+ wpj344|\ -+ wpj531|\ -+ wpj558|\ -+ wpj563|\ -+ wrt400n|\ -+ wrtnode2q|\ -+ wzr-450hp2|\ -+ wzr-hp-ag300h|\ -+ wzr-hp-g300nh|\ -+ wzr-hp-g300nh2|\ -+ wzr-hp-g450h|\ -+ xd3200) -+ [ "$magic" != "2705" ] && { -+ echo "Invalid image type." -+ return 1 -+ } -+ -+ return 0 -+ ;; -+ alfa-ap96|\ -+ alfa-nx|\ -+ ap121|\ -+ ap121-mini|\ -+ ap135-020|\ -+ ap136-010|\ -+ ap136-020|\ -+ ap147-010|\ -+ ap152|\ -+ ap91-5g|\ -+ ap96|\ -+ bhr-4grv2|\ -+ bxu2000n-2-a1|\ -+ db120|\ -+ dr344|\ -+ dw33d|\ -+ f9k1115v2|\ -+ hornet-ub|\ -+ mr12|\ -+ mr16|\ -+ zbt-we1526|\ -+ zcn-1523h-2|\ -+ zcn-1523h-5) -+ [ "$magic_long" != "68737173" -a "$magic_long" != "19852003" ] && { -+ echo "Invalid image type." -+ return 1 -+ } -+ -+ return 0 -+ ;; -+ all0258n|\ -+ all0315n|\ -+ cap324|\ -+ cap4200ag|\ -+ cr3000|\ -+ cr5000) -+ platform_check_image_allnet "$1" && return 0 -+ return 1 -+ ;; -+ all0305|\ -+ eap300v2|\ -+ eap7660d|\ -+ ja76pf|\ -+ ja76pf2|\ -+ jwap003|\ -+ ls-sr71|\ -+ pb42|\ -+ pb44|\ -+ routerstation|\ -+ routerstation-pro|\ -+ wp543|\ -+ wpe72) -+ [ "$magic" != "4349" ] && { -+ echo "Invalid image. Use *-sysupgrade.bin files on this board" -+ return 1 -+ } -+ -+ local md5_img=$(dd if="$1" bs=2 skip=9 count=16 2>/dev/null) -+ local md5_chk=$(fwtool -q -t -i /dev/null "$1"; dd if="$1" bs=$CI_BLKSZ skip=1 2>/dev/null | md5sum -); md5_chk="${md5_chk%% *}" -+ -+ if [ -n "$md5_img" -a -n "$md5_chk" ] && [ "$md5_img" = "$md5_chk" ]; then -+ return 0 -+ else -+ echo "Invalid image. Contents do not match checksum (image:$md5_img calculated:$md5_chk)" -+ return 1 -+ fi -+ -+ return 0 -+ ;; -+ antminer-s1|\ -+ antminer-s3|\ -+ antrouter-r1|\ -+ archer-c5|\ -+ archer-c7|\ -+ el-m150|\ -+ el-mini|\ -+ gl-inet|\ -+ lan-turtle|\ -+ mc-mac1200r|\ -+ minibox-v1|\ -+ minibox-v3.2|\ -+ omy-g1|\ -+ omy-x1|\ -+ onion-omega|\ -+ oolite-v1|\ -+ oolite-v5.2|\ -+ oolite-v5.2-dev|\ -+ packet-squirrel|\ -+ re355|\ -+ re450|\ -+ rut900|\ -+ smart-300|\ -+ som9331|\ -+ tellstick-znet-lite|\ -+ tl-mr10u|\ -+ tl-mr11u|\ -+ tl-mr12u|\ -+ tl-mr13u|\ -+ tl-mr3020|\ -+ tl-mr3040|\ -+ tl-mr3040-v2|\ -+ tl-mr3220|\ -+ tl-mr3220-v2|\ -+ tl-mr3420|\ -+ tl-mr3420-v2|\ -+ tl-mr6400|\ -+ tl-wa701nd-v2|\ -+ tl-wa7210n-v2|\ -+ tl-wa750re|\ -+ tl-wa7510n|\ -+ tl-wa801nd-v2|\ -+ tl-wa801nd-v3|\ -+ tl-wa830re-v2|\ -+ tl-wa850re|\ -+ tl-wa850re-v2|\ -+ tl-wa855re-v1|\ -+ tl-wa860re|\ -+ tl-wa901nd|\ -+ tl-wa901nd-v2|\ -+ tl-wa901nd-v3|\ -+ tl-wa901nd-v4|\ -+ tl-wa901nd-v5|\ -+ tl-wdr3320-v2|\ -+ tl-wdr3500|\ -+ tl-wdr4300|\ -+ tl-wdr4900-v2|\ -+ tl-wdr6500-v2|\ -+ tl-wpa8630|\ -+ tl-wr1041n-v2|\ -+ tl-wr1043nd|\ -+ tl-wr1043nd-v2|\ -+ tl-wr1043nd-v4|\ -+ tl-wr2543n|\ -+ tl-wr703n|\ -+ tl-wr710n|\ -+ tl-wr720n-v3|\ -+ tl-wr740n-v6|\ -+ tl-wr741nd|\ -+ tl-wr741nd-v4|\ -+ tl-wr802n-v1|\ -+ tl-wr802n-v2|\ -+ tl-wr810n|\ -+ tl-wr810n-v2|\ -+ tl-wr840n-v2|\ -+ tl-wr840n-v3|\ -+ tl-wr841n-v1|\ -+ tl-wr841n-v7|\ -+ tl-wr841n-v8|\ -+ tl-wr841n-v9|\ -+ tl-wr841n-v11|\ -+ tl-wr842n-v2|\ -+ tl-wr842n-v3|\ -+ tl-wr902ac-v1|\ -+ tl-wr940n-v4|\ -+ tl-wr940n-v6|\ -+ tl-wr941nd|\ -+ tl-wr941nd-v5|\ -+ tl-wr941nd-v6|\ -+ ts-d084|\ -+ wifi-pineapple-nano) -+ local magic_ver="0100" -+ -+ case "$board" in -+ tl-wdr3320-v2|tl-wdr6500-v2) -+ magic_ver="0200" -+ ;; -+ esac -+ -+ [ "$magic" != "$magic_ver" ] && { -+ echo "Invalid image type." -+ return 1 -+ } -+ -+ local hwid -+ local mid -+ local imagehwid -+ local imagemid -+ -+ hwid=$(tplink_get_hwid) -+ mid=$(tplink_get_mid) -+ imagehwid=$(tplink_get_image_hwid "$1") -+ imagemid=$(tplink_get_image_mid "$1") -+ -+ [ "$hwid" != "$imagehwid" -o "$mid" != "$imagemid" ] && { -+ echo "Invalid image, hardware ID mismatch, hw:$hwid $mid image:$imagehwid $imagemid." -+ return 1 -+ } -+ -+ local boot_size -+ -+ boot_size=$(tplink_get_image_boot_size "$1") -+ [ "$boot_size" != "00000000" ] && { -+ echo "Invalid image, it contains a bootloader." -+ return 1 -+ } -+ -+ return 0 -+ ;; -+ bsb|\ -+ dir-825-b1|\ -+ tew-673gru) -+ dir825b_check_image "$1" && return 0 -+ ;; -+ rb-411|\ -+ rb-411u|\ -+ rb-433|\ -+ rb-433u|\ -+ rb-435g|\ -+ rb-450|\ -+ rb-450g|\ -+ rb-493|\ -+ rb-493g|\ -+ rb-750|\ -+ rb-750gl|\ -+ rb-751|\ -+ rb-751g|\ -+ rb-911g-2hpnd|\ -+ rb-911g-5hpnd|\ -+ rb-911g-5hpacd|\ -+ rb-912uag-2hpnd|\ -+ rb-912uag-5hpnd|\ -+ rb-921gs-5hpacd-r2|\ -+ rb-922uags-5hpacd|\ -+ rb-951g-2hnd|\ -+ rb-951ui-2hnd|\ -+ rb-2011l|\ -+ rb-2011il|\ -+ rb-2011ils|\ -+ rb-2011uas|\ -+ rb-2011uas-2hnd|\ -+ rb-2011uias|\ -+ rb-2011uias-2hnd|\ -+ rb-2011uias-2hnd-r2|\ -+ rb-sxt2n|\ -+ rb-sxt5n) -+ nand_do_platform_check routerboard $1 -+ return $? -+ ;; -+ c-60|\ -+ hiveap-121|\ -+ nbg6716|\ -+ r6100|\ -+ rambutan|\ -+ wi2a-ac200i|\ -+ wndr3700v4|\ -+ wndr4300) -+ nand_do_platform_check $board $1 -+ return $? -+ ;; -+ cpe210|\ -+ cpe510|\ -+ eap120|\ -+ wbs210|\ -+ wbs510) -+ tplink_pharos_check_image "$1" "7f454c46" "$(tplink_pharos_get_model_string)" '' && return 0 -+ return 1 -+ ;; -+ cpe210-v2|\ -+ cpe210-v3) -+ tplink_pharos_check_image "$1" "01000000" "$(tplink_pharos_v2_get_model_string)" '\0\xff\r' && return 0 -+ return 1 -+ ;; -+ cpe510-v2) -+ tplink_pharos_check_image "$1" "7f454c46" "$(tplink_pharos_v2_get_model_string)" '\0\xff\r' && return 0 -+ return 1 -+ ;; -+ a40|\ -+ a60|\ -+ mr1750|\ -+ mr1750v2|\ -+ mr600|\ -+ mr600v2|\ -+ mr900|\ -+ mr900v2|\ -+ om2p|\ -+ om2p-hs|\ -+ om2p-hsv2|\ -+ om2p-hsv3|\ -+ om2p-hsv4|\ -+ om2p-lc|\ -+ om2pv2|\ -+ om2pv4|\ -+ om5p|\ -+ om5p-ac|\ -+ om5p-acv2|\ -+ om5p-an) -+ platform_check_image_openmesh "$magic_long" "$1" && return 0 -+ return 1 -+ ;; -+ mr18|\ -+ z1) -+ merakinand_do_platform_check $board $1 -+ return $? -+ ;; -+ dir-869-a1|\ -+ mynet-n600|\ -+ mynet-n750|\ -+ qihoo-c301) -+ [ "$magic_long" != "5ea3a417" ] && { -+ echo "Invalid image, bad magic: $magic_long" -+ return 1 -+ } -+ -+ local typemagic=$(seama_get_type_magic "$1") -+ [ "$typemagic" != "6669726d" ] && { -+ echo "Invalid image, bad type: $typemagic" -+ return 1 -+ } -+ -+ return 0 -+ ;; -+ e2100l|\ -+ mynet-rext|\ -+ wrt160nl) -+ cybertan_check_image "$1" && return 0 -+ return 1 -+ ;; -+ nbg6616|\ -+ uap-pro|\ -+ unifi-outdoor-plus) -+ [ "$magic_long" != "19852003" ] && { -+ echo "Invalid image type." -+ return 1 -+ } -+ -+ return 0 -+ ;; -+ tube2h) -+ alfa_check_image "$1" && return 0 -+ return 1 -+ ;; -+ wndr3700|\ -+ wnr1000-v2|\ -+ wnr2000-v3|\ -+ wnr612-v2|\ -+ wpn824n) -+ local hw_magic -+ -+ hw_magic="$(ar71xx_get_mtd_part_magic firmware)" -+ [ "$magic_long" != "$hw_magic" ] && { -+ echo "Invalid image, hardware ID mismatch, hw:$hw_magic image:$magic_long." -+ return 1 -+ } -+ -+ return 0 -+ ;; -+ wnr2000-v4) -+ [ "$magic_long" != "32303034" ] && { -+ echo "Invalid image type." -+ return 1 -+ } -+ -+ return 0 -+ ;; -+ wnr2200) -+ [ "$magic_long" != "32323030" ] && { -+ echo "Invalid image type." -+ return 1 -+ } -+ -+ return 0 -+ ;; -+ dap-2695-a1) -+ local magic=$(wrgg_get_image_magic "$1") -+ [ "$magic" != "21030820" ] && { -+ echo "Invalid image, bad type: $magic" -+ return 1 -+ } -+ -+ return 0; -+ ;; -+ # these boards use metadata images -+ fritz300e|\ -+ fritz4020|\ -+ fritz450e|\ -+ koala|\ -+ rb-750-r2|\ -+ rb-750p-pbr2|\ -+ rb-750up-r2|\ -+ rb-911-2hn|\ -+ rb-911-5hn|\ -+ rb-931-2nd|\ -+ rb-941-2nd|\ -+ rb-951ui-2nd|\ -+ rb-952ui-5ac2nd|\ -+ rb-962uigs-5hact2hnt|\ -+ rb-lhg-5nd|\ -+ rb-map-2nd|\ -+ rb-mapl-2nd|\ -+ rb-sxt-2nd-r3|\ -+ rb-wap-2nd|\ -+ rb-wapg-5hact2hnd|\ -+ rb-wapr-2nd) -+ return 0 -+ ;; -+ esac -+ -+ echo "Sysupgrade is not yet supported on $board." -+ return 1 -+} -+ -+platform_do_upgrade_mikrotik_rb() { -+ CI_KERNPART=none -+ local fw_mtd=$(find_mtd_part kernel) -+ fw_mtd="${fw_mtd/block/}" -+ [ -n "$fw_mtd" ] || return -+ -+ local board_dir=$(tar tf "$1" | grep -m 1 '^sysupgrade-.*/$') -+ board_dir=${board_dir%/} -+ [ -n "$board_dir" ] || return -+ -+ mtd erase kernel -+ tar xf "$1" ${board_dir}/kernel -O | nandwrite -o "$fw_mtd" - -+ -+ nand_do_upgrade "$1" -+} -+ -+platform_do_upgrade_nokia() { -+ case "$(fw_printenv -n dualPartition)" in -+ imgA) -+ fw_setenv dualPartition imgB -+ fw_setenv ActImg NokiaImageB -+ ;; -+ imgB) -+ fw_setenv dualPartition imgA -+ fw_setenv ActImg NokiaImageA -+ ;; -+ esac -+ ubiblock -r /dev/ubiblock0_0 2>/dev/null >/dev/null -+ rm -f /dev/ubiblock0_0 -+ ubidetach -d 0 2>/dev/null >/dev/null -+ CI_UBIPART=ubi_alt -+ CI_KERNPART=kernel_alt -+ -+ nand_do_upgrade "$1" -+} -+ -+platform_do_upgrade() { -+ local board=$(board_name) -+ -+ case "$board" in -+ rb-750-r2|\ -+ rb-750p-pbr2|\ -+ rb-750up-r2|\ -+ rb-911-2hn|\ -+ rb-911-5hn|\ -+ rb-931-2nd|\ -+ rb-941-2nd|\ -+ rb-951ui-2nd|\ -+ rb-952ui-5ac2nd|\ -+ rb-962uigs-5hact2hnt|\ -+ rb-lhg-5nd|\ -+ rb-map-2nd|\ -+ rb-mapl-2nd|\ -+ rb-sxt-2nd-r3|\ -+ rb-wap-2nd|\ -+ rb-wapg-5hact2hnd|\ -+ rb-wapr-2nd) -+ # erase firmware if booted from initramfs -+ [ -z "$(rootfs_type)" ] && mtd erase firmware -+ ;; -+ esac -+ -+ case "$board" in -+ all0258n) -+ platform_do_upgrade_allnet "0x9f050000" "$1" -+ ;; -+ all0305|\ -+ eap7660d|\ -+ ja76pf|\ -+ ja76pf2|\ -+ jwap003|\ -+ ls-sr71|\ -+ pb42|\ -+ pb44|\ -+ routerstation|\ -+ routerstation-pro) -+ platform_do_upgrade_combined "$1" -+ ;; -+ all0315n) -+ platform_do_upgrade_allnet "0x9f080000" "$1" -+ ;; -+ cap4200ag|\ -+ eap300v2|\ -+ ens202ext) -+ platform_do_upgrade_allnet "0xbf0a0000" "$1" -+ ;; -+ dir-825-b1|\ -+ tew-673gru) -+ platform_do_upgrade_dir825b "$1" -+ ;; -+ a40|\ -+ a60|\ -+ mr1750|\ -+ mr1750v2|\ -+ mr600|\ -+ mr600v2|\ -+ mr900|\ -+ mr900v2|\ -+ om2p|\ -+ om2p-hs|\ -+ om2p-hsv2|\ -+ om2p-hsv3|\ -+ om2p-hsv4|\ -+ om2p-lc|\ -+ om2pv2|\ -+ om2pv4|\ -+ om5p|\ -+ om5p-ac|\ -+ om5p-acv2|\ -+ om5p-an) -+ platform_do_upgrade_openmesh "$1" -+ ;; -+ c-60|\ -+ hiveap-121|\ -+ nbg6716|\ -+ r6100|\ -+ rambutan|\ -+ wndr3700v4|\ -+ wndr4300) -+ nand_do_upgrade "$1" -+ ;; -+ mr18|\ -+ z1) -+ merakinand_do_upgrade "$1" -+ ;; -+ rb-411|\ -+ rb-411u|\ -+ rb-433|\ -+ rb-433u|\ -+ rb-435g|\ -+ rb-450|\ -+ rb-450g|\ -+ rb-493|\ -+ rb-493g|\ -+ rb-750|\ -+ rb-750gl|\ -+ rb-751|\ -+ rb-751g|\ -+ rb-911g-2hpnd|\ -+ rb-911g-5hpacd|\ -+ rb-911g-5hpnd|\ -+ rb-912uag-2hpnd|\ -+ rb-912uag-5hpnd|\ -+ rb-921gs-5hpacd-r2|\ -+ rb-922uags-5hpacd|\ -+ rb-951g-2hnd|\ -+ rb-951ui-2hnd|\ -+ rb-2011il|\ -+ rb-2011ils|\ -+ rb-2011l|\ -+ rb-2011uas|\ -+ rb-2011uas-2hnd|\ -+ rb-2011uias|\ -+ rb-2011uias-2hnd|\ -+ rb-2011uias-2hnd-r2|\ -+ rb-sxt2n|\ -+ rb-sxt5n) -+ platform_do_upgrade_mikrotik_rb "$1" -+ ;; -+ uap-pro|\ -+ unifi-outdoor-plus) -+ MTD_CONFIG_ARGS="-s 0x180000" -+ default_do_upgrade "$1" -+ ;; -+ wi2a-ac200i) -+ platform_do_upgrade_nokia "$1" -+ ;; -+ wp543|\ -+ wpe72) -+ platform_do_upgrade_compex "$1" -+ ;; -+ *) -+ default_do_upgrade "$1" -+ ;; -+ esac -+} -diff --git a/target/linux/ar71xx/config-4.14 b/target/linux/ar71xx/config-4.14 -new file mode 100644 -index 0000000000..125b34bfa8 ---- /dev/null -+++ b/target/linux/ar71xx/config-4.14 -@@ -0,0 +1,477 @@ -+CONFIG_AG71XX=y -+# CONFIG_AG71XX_AR8216_SUPPORT is not set -+# CONFIG_AG71XX_DEBUG is not set -+# CONFIG_AG71XX_DEBUG_FS is not set -+CONFIG_ARCH_BINFMT_ELF_STATE=y -+CONFIG_ARCH_CLOCKSOURCE_DATA=y -+CONFIG_ARCH_DISCARD_MEMBLOCK=y -+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_HIBERNATION_POSSIBLE=y -+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -+CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=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_AT803X_PHY=y -+CONFIG_ATH79=y -+# CONFIG_ATH79_DEV_AP9X_PCI is not set -+# CONFIG_ATH79_DEV_DSA is not set -+# CONFIG_ATH79_DEV_ETH is not set -+# CONFIG_ATH79_DEV_GPIO_BUTTONS is not set -+# CONFIG_ATH79_DEV_LEDS_GPIO is not set -+# CONFIG_ATH79_DEV_M25P80 is not set -+# CONFIG_ATH79_DEV_SPI is not set -+# CONFIG_ATH79_DEV_USB is not set -+# CONFIG_ATH79_MACH_A60 is not set -+# CONFIG_ATH79_MACH_ALFA_AP120C is not set -+# CONFIG_ATH79_MACH_ALFA_AP96 is not set -+# CONFIG_ATH79_MACH_ALFA_NX is not set -+# CONFIG_ATH79_MACH_ALL0258N is not set -+# CONFIG_ATH79_MACH_ALL0315N is not set -+# CONFIG_ATH79_MACH_ANTMINER_S1 is not set -+# CONFIG_ATH79_MACH_ANTMINER_S3 is not set -+# CONFIG_ATH79_MACH_ANTROUTER_R1 is not set -+# CONFIG_ATH79_MACH_AP121 is not set -+# CONFIG_ATH79_MACH_AP121F is not set -+# CONFIG_ATH79_MACH_AP132 is not set -+# CONFIG_ATH79_MACH_AP136 is not set -+# CONFIG_ATH79_MACH_AP143 is not set -+# CONFIG_ATH79_MACH_AP147 is not set -+# CONFIG_ATH79_MACH_AP152 is not set -+# CONFIG_ATH79_MACH_AP531B0 is not set -+# CONFIG_ATH79_MACH_AP81 is not set -+# CONFIG_ATH79_MACH_AP90Q is not set -+# CONFIG_ATH79_MACH_AP91_5G is not set -+# CONFIG_ATH79_MACH_AP96 is not set -+# CONFIG_ATH79_MACH_ARCHER_C25_V1 is not set -+# CONFIG_ATH79_MACH_ARCHER_C58_V1 is not set -+# CONFIG_ATH79_MACH_ARCHER_C59_V1 is not set -+# CONFIG_ATH79_MACH_ARCHER_C59_V2 is not set -+# CONFIG_ATH79_MACH_ARCHER_C60_V1 is not set -+# CONFIG_ATH79_MACH_ARCHER_C60_V2 is not set -+# CONFIG_ATH79_MACH_ARCHER_C7 is not set -+# CONFIG_ATH79_MACH_ARDUINO_YUN is not set -+# CONFIG_ATH79_MACH_AW_NR580 is not set -+# CONFIG_ATH79_MACH_BHR_4GRV2 is not set -+# CONFIG_ATH79_MACH_BHU_BXU2000N2_A is not set -+# CONFIG_ATH79_MACH_BSB is not set -+# CONFIG_ATH79_MACH_C55 is not set -+# CONFIG_ATH79_MACH_C60 is not set -+# CONFIG_ATH79_MACH_CAP324 is not set -+# CONFIG_ATH79_MACH_CAP4200AG is not set -+# CONFIG_ATH79_MACH_CARAMBOLA2 is not set -+# CONFIG_ATH79_MACH_CF_E316N_V2 is not set -+# CONFIG_ATH79_MACH_CF_E320N_V2 is not set -+# CONFIG_ATH79_MACH_CF_E355AC is not set -+# CONFIG_ATH79_MACH_CF_E375AC is not set -+# CONFIG_ATH79_MACH_CF_E380AC_V1 is not set -+# CONFIG_ATH79_MACH_CF_E380AC_V2 is not set -+# CONFIG_ATH79_MACH_CF_E520N is not set -+# CONFIG_ATH79_MACH_CF_E530N is not set -+# CONFIG_ATH79_MACH_CPE505N is not set -+# CONFIG_ATH79_MACH_CPE510 is not set -+# CONFIG_ATH79_MACH_CPE830 is not set -+# CONFIG_ATH79_MACH_CPE870 is not set -+# CONFIG_ATH79_MACH_CR3000 is not set -+# CONFIG_ATH79_MACH_CR5000 is not set -+# CONFIG_ATH79_MACH_DAP_1330_A1 is not set -+# CONFIG_ATH79_MACH_DAP_2695_A1 is not set -+# CONFIG_ATH79_MACH_DB120 is not set -+# CONFIG_ATH79_MACH_DGL_5500_A1 is not set -+# CONFIG_ATH79_MACH_DHP_1565_A1 is not set -+# CONFIG_ATH79_MACH_DIR_505_A1 is not set -+# CONFIG_ATH79_MACH_DIR_600_A1 is not set -+# CONFIG_ATH79_MACH_DIR_615_C1 is not set -+# CONFIG_ATH79_MACH_DIR_615_I1 is not set -+# CONFIG_ATH79_MACH_DIR_825_B1 is not set -+# CONFIG_ATH79_MACH_DIR_825_C1 is not set -+# CONFIG_ATH79_MACH_DIR_869_A1 is not set -+# CONFIG_ATH79_MACH_DLAN_HOTSPOT is not set -+# CONFIG_ATH79_MACH_DLAN_PRO_1200_AC is not set -+# CONFIG_ATH79_MACH_DLAN_PRO_500_WP is not set -+# CONFIG_ATH79_MACH_DOMYWIFI_DW33D is not set -+# CONFIG_ATH79_MACH_DR342 is not set -+# CONFIG_ATH79_MACH_DR344 is not set -+# CONFIG_ATH79_MACH_DR531 is not set -+# CONFIG_ATH79_MACH_DRAGINO2 is not set -+# CONFIG_ATH79_MACH_E1700AC_V2 is not set -+# CONFIG_ATH79_MACH_E2100L is not set -+# CONFIG_ATH79_MACH_E558_V2 is not set -+# CONFIG_ATH79_MACH_E600G_V2 is not set -+# CONFIG_ATH79_MACH_E750A_V4 is not set -+# CONFIG_ATH79_MACH_E750G_V8 is not set -+# CONFIG_ATH79_MACH_EAP120 is not set -+# CONFIG_ATH79_MACH_EAP300V2 is not set -+# CONFIG_ATH79_MACH_EAP7660D is not set -+# CONFIG_ATH79_MACH_EL_M150 is not set -+# CONFIG_ATH79_MACH_EL_MINI is not set -+# CONFIG_ATH79_MACH_ENS202EXT is not set -+# CONFIG_ATH79_MACH_EPG5000 is not set -+# CONFIG_ATH79_MACH_ESR1750 is not set -+# CONFIG_ATH79_MACH_ESR900 is not set -+# CONFIG_ATH79_MACH_EW_BALIN is not set -+# CONFIG_ATH79_MACH_EW_DORIN is not set -+# CONFIG_ATH79_MACH_F9K1115V2 is not set -+# CONFIG_ATH79_MACH_FRITZ300E is not set -+# CONFIG_ATH79_MACH_FRITZ4020 is not set -+# CONFIG_ATH79_MACH_FRITZ450E is not set -+# CONFIG_ATH79_MACH_GL_AR150 is not set -+# CONFIG_ATH79_MACH_GL_AR300 is not set -+# CONFIG_ATH79_MACH_GL_AR300M is not set -+# CONFIG_ATH79_MACH_GL_AR750 is not set -+# CONFIG_ATH79_MACH_GL_AR750S is not set -+# CONFIG_ATH79_MACH_GL_DOMINO is not set -+# CONFIG_ATH79_MACH_GL_INET is not set -+# CONFIG_ATH79_MACH_GL_MIFI is not set -+# CONFIG_ATH79_MACH_GL_USB150 is not set -+# CONFIG_ATH79_MACH_GS_MINIBOX_V32 is not set -+# CONFIG_ATH79_MACH_GS_OOLITE_V1 is not set -+# CONFIG_ATH79_MACH_GS_OOLITE_V5_2 is not set -+# CONFIG_ATH79_MACH_HIVEAP_121 is not set -+# CONFIG_ATH79_MACH_HIWIFI_HC6361 is not set -+# CONFIG_ATH79_MACH_HORNET_UB is not set -+# CONFIG_ATH79_MACH_JA76PF is not set -+# CONFIG_ATH79_MACH_JWAP003 is not set -+# CONFIG_ATH79_MACH_JWAP230 is not set -+# CONFIG_ATH79_MACH_KOALA is not set -+# CONFIG_ATH79_MACH_LAN_TURTLE is not set -+# CONFIG_ATH79_MACH_LIMA is not set -+# CONFIG_ATH79_MACH_MC_MAC1200R is not set -+# CONFIG_ATH79_MACH_MR12 is not set -+# CONFIG_ATH79_MACH_MR16 is not set -+# CONFIG_ATH79_MACH_MR1750 is not set -+# CONFIG_ATH79_MACH_MR18 is not set -+# CONFIG_ATH79_MACH_MR600 is not set -+# CONFIG_ATH79_MACH_MR900 is not set -+# CONFIG_ATH79_MACH_MYNET_N600 is not set -+# CONFIG_ATH79_MACH_MYNET_N750 is not set -+# CONFIG_ATH79_MACH_MYNET_REXT is not set -+# CONFIG_ATH79_MACH_MZK_W04NU is not set -+# CONFIG_ATH79_MACH_MZK_W300NH is not set -+# CONFIG_ATH79_MACH_N5Q is not set -+# CONFIG_ATH79_MACH_NBG460N is not set -+# CONFIG_ATH79_MACH_NBG6716 is not set -+# CONFIG_ATH79_MACH_OM2P is not set -+# CONFIG_ATH79_MACH_OM5P is not set -+# CONFIG_ATH79_MACH_OM5P_AC is not set -+# CONFIG_ATH79_MACH_OM5P_ACv2 is not set -+# CONFIG_ATH79_MACH_OMY_G1 is not set -+# CONFIG_ATH79_MACH_OMY_X1 is not set -+# CONFIG_ATH79_MACH_ONION_OMEGA is not set -+# CONFIG_ATH79_MACH_PB42 is not set -+# CONFIG_ATH79_MACH_PB44 is not set -+# CONFIG_ATH79_MACH_PQI_AIR_PEN is not set -+# CONFIG_ATH79_MACH_QIHOO_C301 is not set -+# CONFIG_ATH79_MACH_R36A is not set -+# CONFIG_ATH79_MACH_R602N is not set -+# CONFIG_ATH79_MACH_R6100 is not set -+# CONFIG_ATH79_MACH_RAMBUTAN is not set -+# CONFIG_ATH79_MACH_RB2011 is not set -+# CONFIG_ATH79_MACH_RB4XX is not set -+# CONFIG_ATH79_MACH_RB750 is not set -+# CONFIG_ATH79_MACH_RB91X is not set -+# CONFIG_ATH79_MACH_RB922 is not set -+# CONFIG_ATH79_MACH_RB95X is not set -+# CONFIG_ATH79_MACH_RBSPI is not set -+# CONFIG_ATH79_MACH_RBSXTLITE is not set -+# CONFIG_ATH79_MACH_RE355 is not set -+# CONFIG_ATH79_MACH_RE450 is not set -+# CONFIG_ATH79_MACH_RME_EG200 is not set -+# CONFIG_ATH79_MACH_RUT9XX is not set -+# CONFIG_ATH79_MACH_RW2458N is not set -+# CONFIG_ATH79_MACH_SC1750 is not set -+# CONFIG_ATH79_MACH_SC300M is not set -+# CONFIG_ATH79_MACH_SC450 is not set -+# CONFIG_ATH79_MACH_SMART_300 is not set -+# CONFIG_ATH79_MACH_SOM9331 is not set -+# CONFIG_ATH79_MACH_SR3200 is not set -+# CONFIG_ATH79_MACH_T830 is not set -+# CONFIG_ATH79_MACH_TELLSTICK_ZNET_LITE is not set -+# CONFIG_ATH79_MACH_TEW_632BRP is not set -+# CONFIG_ATH79_MACH_TEW_673GRU is not set -+# CONFIG_ATH79_MACH_TEW_712BR is not set -+# CONFIG_ATH79_MACH_TEW_732BR is not set -+# CONFIG_ATH79_MACH_TEW_823DRU is not set -+# CONFIG_ATH79_MACH_TL_MR11U is not set -+# CONFIG_ATH79_MACH_TL_MR13U is not set -+# CONFIG_ATH79_MACH_TL_MR3020 is not set -+# CONFIG_ATH79_MACH_TL_MR3X20 is not set -+# CONFIG_ATH79_MACH_TL_MR6400 is not set -+# CONFIG_ATH79_MACH_TL_WA701ND_V2 is not set -+# CONFIG_ATH79_MACH_TL_WA7210N_V2 is not set -+# CONFIG_ATH79_MACH_TL_WA801ND_V3 is not set -+# CONFIG_ATH79_MACH_TL_WA830RE_V2 is not set -+# CONFIG_ATH79_MACH_TL_WA850RE_V2 is not set -+# CONFIG_ATH79_MACH_TL_WA855RE_V1 is not set -+# CONFIG_ATH79_MACH_TL_WA901ND is not set -+# CONFIG_ATH79_MACH_TL_WA901ND_V2 is not set -+# CONFIG_ATH79_MACH_TL_WA901ND_V4 is not set -+# CONFIG_ATH79_MACH_TL_WAX50RE is not set -+# CONFIG_ATH79_MACH_TL_WDR3320_V2 is not set -+# CONFIG_ATH79_MACH_TL_WDR3500 is not set -+# CONFIG_ATH79_MACH_TL_WDR4300 is not set -+# CONFIG_ATH79_MACH_TL_WDR6500_V2 is not set -+# CONFIG_ATH79_MACH_TL_WPA8630 is not set -+# CONFIG_ATH79_MACH_TL_WR1041N_V2 is not set -+# CONFIG_ATH79_MACH_TL_WR1043ND is not set -+# CONFIG_ATH79_MACH_TL_WR1043ND_V2 is not set -+# CONFIG_ATH79_MACH_TL_WR1043ND_V4 is not set -+# CONFIG_ATH79_MACH_TL_WR1043N_V5 is not set -+# CONFIG_ATH79_MACH_TL_WR2543N is not set -+# CONFIG_ATH79_MACH_TL_WR703N is not set -+# CONFIG_ATH79_MACH_TL_WR720N_V3 is not set -+# CONFIG_ATH79_MACH_TL_WR741ND is not set -+# CONFIG_ATH79_MACH_TL_WR741ND_V4 is not set -+# CONFIG_ATH79_MACH_TL_WR802N_V1 is not set -+# CONFIG_ATH79_MACH_TL_WR802N_V2 is not set -+# CONFIG_ATH79_MACH_TL_WR810N is not set -+# CONFIG_ATH79_MACH_TL_WR810N_V2 is not set -+# CONFIG_ATH79_MACH_TL_WR840N_V2 is not set -+# CONFIG_ATH79_MACH_TL_WR841N_V1 is not set -+# CONFIG_ATH79_MACH_TL_WR841N_V8 is not set -+# CONFIG_ATH79_MACH_TL_WR841N_V9 is not set -+# CONFIG_ATH79_MACH_TL_WR902AC_V1 is not set -+# CONFIG_ATH79_MACH_TL_WR940N_V4 is not set -+# CONFIG_ATH79_MACH_TL_WR941ND is not set -+# CONFIG_ATH79_MACH_TL_WR941ND_V6 is not set -+# CONFIG_ATH79_MACH_TL_WR942N_V1 is not set -+# CONFIG_ATH79_MACH_TS_D084 is not set -+# CONFIG_ATH79_MACH_TUBE2H is not set -+# CONFIG_ATH79_MACH_UBNT is not set -+# CONFIG_ATH79_MACH_UBNT_UNIFIAC is not set -+# CONFIG_ATH79_MACH_UBNT_XM is not set -+# CONFIG_ATH79_MACH_WAM250 is not set -+# CONFIG_ATH79_MACH_WEIO is not set -+# CONFIG_ATH79_MACH_WHR_HP_G300N is not set -+# CONFIG_ATH79_MACH_WI2A_AC200I is not set -+# CONFIG_ATH79_MACH_WIFI_PINEAPPLE_NANO is not set -+# CONFIG_ATH79_MACH_WLAE_AG300N is not set -+# CONFIG_ATH79_MACH_WLR8100 is not set -+# CONFIG_ATH79_MACH_WNDAP360 is not set -+# CONFIG_ATH79_MACH_WNDR3700 is not set -+# CONFIG_ATH79_MACH_WNDR4300 is not set -+# CONFIG_ATH79_MACH_WNR2000 is not set -+# CONFIG_ATH79_MACH_WNR2000_V3 is not set -+# CONFIG_ATH79_MACH_WNR2000_V4 is not set -+# CONFIG_ATH79_MACH_WNR2200 is not set -+# CONFIG_ATH79_MACH_WP543 is not set -+# CONFIG_ATH79_MACH_WPE72 is not set -+# CONFIG_ATH79_MACH_WPJ342 is not set -+# CONFIG_ATH79_MACH_WPJ344 is not set -+# CONFIG_ATH79_MACH_WPJ531 is not set -+# CONFIG_ATH79_MACH_WPJ558 is not set -+# CONFIG_ATH79_MACH_WPJ563 is not set -+# CONFIG_ATH79_MACH_WRT160NL is not set -+# CONFIG_ATH79_MACH_WRT400N is not set -+# CONFIG_ATH79_MACH_WRTNODE2Q is not set -+# CONFIG_ATH79_MACH_WZR_450HP2 is not set -+# CONFIG_ATH79_MACH_WZR_HP_AG300H is not set -+# CONFIG_ATH79_MACH_WZR_HP_G300NH is not set -+# CONFIG_ATH79_MACH_WZR_HP_G300NH2 is not set -+# CONFIG_ATH79_MACH_WZR_HP_G450H is not set -+# CONFIG_ATH79_MACH_XD3200 is not set -+# CONFIG_ATH79_MACH_Z1 is not set -+# CONFIG_ATH79_MACH_ZBT_WE1526 is not set -+# CONFIG_ATH79_MACH_ZCN_1523H is not set -+# CONFIG_ATH79_NVRAM is not set -+# CONFIG_ATH79_PCI_ATH9K_FIXUP is not set -+# CONFIG_ATH79_ROUTERBOOT is not set -+CONFIG_ATH79_WDT=y -+CONFIG_CEVT_R4K=y -+CONFIG_CLKDEV_LOOKUP=y -+CONFIG_CLONE_BACKWARDS=y -+CONFIG_CMDLINE="rootfstype=squashfs noinitrd" -+CONFIG_CMDLINE_BOOL=y -+# CONFIG_CMDLINE_OVERRIDE is not set -+# CONFIG_COMMON_CLK_BOSTON is not set -+CONFIG_COMMON_CLK=y -+CONFIG_CPU_BIG_ENDIAN=y -+CONFIG_CPU_GENERIC_DUMP_TLB=y -+CONFIG_CPU_HAS_PREFETCH=y -+CONFIG_CPU_HAS_RIXI=y -+CONFIG_CPU_HAS_SYNC=y -+CONFIG_CPU_MIPS32=y -+CONFIG_CPU_MIPS32_R2=y -+CONFIG_CPU_MIPSR2=y -+CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y -+CONFIG_CPU_R4K_CACHE_TLB=y -+CONFIG_CPU_R4K_FPU=y -+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -+CONFIG_CPU_SUPPORTS_HIGHMEM=y -+CONFIG_CPU_SUPPORTS_MSA=y -+CONFIG_CRYPTO_RNG2=y -+CONFIG_CRYPTO_WORKQUEUE=y -+CONFIG_CSRC_R4K=y -+CONFIG_DMA_NONCOHERENT=y -+CONFIG_EARLY_PRINTK=y -+CONFIG_ETHERNET_PACKET_MANGLE=y -+CONFIG_FIXED_PHY=y -+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_GPIOLIB_IRQCHIP=y -+CONFIG_GPIO_74X164=y -+CONFIG_GPIO_ATH79=y -+CONFIG_GPIO_GENERIC=y -+# CONFIG_GPIO_LATCH is not set -+CONFIG_GPIO_NXP_74HC153=y -+CONFIG_GPIO_PCF857X=y -+CONFIG_HANDLE_DOMAIN_IRQ=y -+CONFIG_HARDWARE_WATCHPOINTS=y -+CONFIG_HAS_DMA=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT_MAP=y -+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -+# CONFIG_HAVE_ARCH_BITREVERSE is not set -+CONFIG_HAVE_ARCH_JUMP_LABEL=y -+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_CBPF_JIT=y -+CONFIG_HAVE_CC_STACKPROTECTOR=y -+CONFIG_HAVE_CLK=y -+CONFIG_HAVE_CLK_PREPARE=y -+CONFIG_HAVE_CONTEXT_TRACKING=y -+CONFIG_HAVE_C_RECORDMCOUNT=y -+CONFIG_HAVE_DEBUG_KMEMLEAK=y -+CONFIG_HAVE_DEBUG_STACKOVERFLOW=y -+CONFIG_HAVE_DMA_API_DEBUG=y -+CONFIG_HAVE_DMA_CONTIGUOUS=y -+CONFIG_HAVE_DYNAMIC_FTRACE=y -+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -+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_KVM=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_HZ_PERIODIC=y -+CONFIG_I2C=y -+CONFIG_I2C_ALGOBIT=y -+CONFIG_I2C_BOARDINFO=y -+CONFIG_I2C_GPIO=y -+CONFIG_IMAGE_CMDLINE_HACK=y -+CONFIG_INITRAMFS_ROOT_GID=0 -+CONFIG_INITRAMFS_ROOT_UID=0 -+CONFIG_INITRAMFS_SOURCE="../../root" -+CONFIG_INTEL_XWAY_PHY=y -+CONFIG_IP17XX_PHY=y -+CONFIG_IRQ_DOMAIN=y -+CONFIG_IRQ_FORCED_THREADING=y -+CONFIG_IRQ_MIPS_CPU=y -+CONFIG_IRQ_WORK=y -+CONFIG_LEDS_GPIO=y -+CONFIG_MARVELL_PHY=y -+CONFIG_MDIO_BITBANG=y -+CONFIG_MDIO_BOARDINFO=y -+CONFIG_MDIO_GPIO=y -+CONFIG_MICREL_PHY=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=y -+CONFIG_MIPS_SPRAM=y -+CONFIG_MODULES_USE_ELF_REL=y -+CONFIG_MTD_CFI_ADV_OPTIONS=y -+CONFIG_MTD_CFI_GEOMETRY=y -+# CONFIG_MTD_CFI_I2 is not set -+# CONFIG_MTD_CFI_INTELEXT is not set -+CONFIG_MTD_CMDLINE_PARTS=y -+CONFIG_MTD_CYBERTAN_PARTS=y -+CONFIG_MTD_M25P80=y -+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set -+CONFIG_MTD_MYLOADER_PARTS=y -+CONFIG_MTD_PHYSMAP=y -+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-2 -+CONFIG_MTD_REDBOOT_PARTS=y -+CONFIG_MTD_SPI_NOR=y -+CONFIG_MTD_SPLIT_EVA_FW=y -+CONFIG_MTD_SPLIT_FIRMWARE=y -+CONFIG_MTD_SPLIT_LZMA_FW=y -+CONFIG_MTD_SPLIT_MINOR_FW=y -+CONFIG_MTD_SPLIT_SEAMA_FW=y -+CONFIG_MTD_SPLIT_TPLINK_FW=y -+CONFIG_MTD_SPLIT_UIMAGE_FW=y -+CONFIG_MTD_SPLIT_WRGG_FW=y -+CONFIG_MTD_TPLINK_PARTS=y -+CONFIG_NEED_DMA_MAP_STATE=y -+CONFIG_NEED_PER_CPU_KM=y -+CONFIG_NET_DSA=y -+CONFIG_NET_DSA_MV88E6060=y -+CONFIG_NET_DSA_MV88E6063=y -+CONFIG_NET_DSA_TAG_TRAILER=y -+CONFIG_NET_SWITCHDEV=y -+CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y -+# CONFIG_NO_IOPORT_MAP is not set -+# CONFIG_OF is not set -+# CONFIG_PCI_AR724X is not set -+CONFIG_PCI_DRIVERS_LEGACY=y -+CONFIG_PERF_USE_VMALLOC=y -+CONFIG_PGTABLE_LEVELS=2 -+CONFIG_PHYLIB=y -+CONFIG_RATIONAL=y -+# CONFIG_RCU_STALL_COMMON is not set -+# CONFIG_SCHED_INFO is not set -+# CONFIG_SCSI_DMA is not set -+# CONFIG_SERIAL_8250_FSL is not set -+CONFIG_SERIAL_8250_NR_UARTS=1 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=1 -+# CONFIG_SOC_AR71XX is not set -+# CONFIG_SOC_AR724X is not set -+# CONFIG_SOC_AR913X is not set -+# CONFIG_SOC_AR933X is not set -+# CONFIG_SOC_AR934X is not set -+# CONFIG_SOC_QCA953X is not set -+# CONFIG_SOC_QCA955X is not set -+# CONFIG_SOC_QCA956X is not set -+CONFIG_SPI=y -+CONFIG_SPI_ATH79=y -+CONFIG_SPI_BITBANG=y -+CONFIG_SPI_GPIO=y -+CONFIG_SPI_MASTER=y -+# CONFIG_SPI_RB4XX is not set -+# CONFIG_SPI_VSC7385 is not set -+CONFIG_SRCU=y -+CONFIG_SYSCTL_EXCEPTION_TRACE=y -+CONFIG_SYS_HAS_CPU_MIPS32_R2=y -+CONFIG_SYS_HAS_EARLY_PRINTK=y -+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -+CONFIG_SYS_SUPPORTS_MIPS16=y -+CONFIG_SYS_SUPPORTS_ZBOOT=y -+CONFIG_SYS_SUPPORTS_ZBOOT_UART_PROM=y -+CONFIG_TICK_CPU_ACCOUNTING=y -+CONFIG_USB_SUPPORT=y -+# CONFIG_MTD_SPLIT_ELF_FW is not set -+# CONFIG_MTD_SPLIT_BCM63XX_FW is not set -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/Kconfig.openwrt b/target/linux/ar71xx/files/arch/mips/ath79/Kconfig.openwrt -new file mode 100644 -index 0000000000..6fd78c46a0 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/Kconfig.openwrt -@@ -0,0 +1,2458 @@ -+config ATH79_MACH_A60 -+ bool "OpenMesh A40/A60 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_WI2A_AC200I -+ bool "Nokia WI2A-AC200i support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_NFC -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_ALFA_AP120C -+ bool "ALFA Network AP120C board support" -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_AP121F -+ bool "ALFA Network AP121F support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ALFA_AP96 -+ bool "ALFA Network AP96 board support" -+ select SOC_AR71XX -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_HORNET_UB -+ bool "ALFA Network Hornet-UB board support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ALFA_NX -+ bool "ALFA Network N2/N5 board support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_TUBE2H -+ bool "ALFA Network Tube2H board support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_SC1750 -+ bool "Abicom SC1750 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_SC300M -+ bool "Abicom SC300M board support" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_SC450 -+ bool "Abicom SC450 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ALL0258N -+ bool "Allnet ALL0258N support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_ALL0315N -+ bool "Allnet ALL0315N support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_ANTMINER_S1 -+ bool "Bitmain Antminer S1 support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ANTMINER_S3 -+ bool "Bitmain Antminer S3 support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ANTROUTER_R1 -+ bool "Bitmain Antrouter R1 support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ARDUINO_YUN -+ bool "Arduino Yun" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_AP132 -+ bool "Atheros AP132 reference board" -+ select SOC_QCA955X -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_AP143 -+ bool "Atheros AP143 reference board" -+ select SOC_QCA953X -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_SPI -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_ETH -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_AP147 -+ bool "Atheros AP147 reference board" -+ select SOC_QCA953X -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_AP9X_PCI if PCI -+ -+config ATH79_MACH_AP152 -+ bool "Atheros AP152 reference board" -+ select SOC_QCA956X -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_AP9X_PCI if PCI -+ -+config ATH79_MACH_AP531B0 -+ bool "Rockeetech AP531B0 support" -+ select SOC_QCA953X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_SPI -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_AP90Q -+ bool "YunCore AP80Q/AP90Q support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_AP91_5G -+ bool "ALFA Network AP91-5G support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_AP96 -+ bool "Atheros AP96 board support" -+ select SOC_AR71XX -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_PB42 -+ bool "Atheros PB42 board support" -+ select SOC_AR71XX -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_C55 -+ bool "AirTight Networks C-55 support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_C60 -+ bool "AirTight Networks C-60 support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_NFC -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_AW_NR580 -+ bool "AzureWave AW-NR580 board support" -+ select SOC_AR71XX -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_F9K1115V2 -+ bool "Belkin AC1750DB board support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_EPG5000 -+ bool "EnGenius EPG5000 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select ATH79_NVRAM -+ -+config ATH79_MACH_ESR1750 -+ bool "EnGenius ESR1750 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select ATH79_NVRAM -+ -+config ATH79_MACH_PQI_AIR_PEN -+ bool "PQI Air Pen" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_SOM9331 -+ bool "SOM9331 support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_SR3200 -+ bool "YunCore SR3200 support" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_BHR_4GRV2 -+ bool "Buffalo BHR-4GRV2 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_WHR_HP_G300N -+ bool "Buffalo WHR-HP-G300N board support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_WLAE_AG300N -+ bool "Buffalo WLAE-AG300N board support" -+ select SOC_AR71XX -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_WLR8100 -+ bool "Sitecom WLR-8100 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_WZR_HP_AG300H -+ bool "Buffalo WZR-HP-AG300H board support" -+ select SOC_AR71XX -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_WZR_HP_G300NH -+ bool "Buffalo WZR-HP-G300NH board support" -+ select SOC_AR913X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select RTL8366_SMI -+ -+config ATH79_MACH_WZR_HP_G300NH2 -+ bool "Buffalo WZR-HP-G300NH2 board support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_WZR_HP_G450H -+ bool "Buffalo WZR-HP-G450H board support" -+ select SOC_AR724X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_WZR_450HP2 -+ bool "Buffalo WZR-450HP2 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_WP543 -+ bool "Compex WP543/WPJ543 board support" -+ select SOC_AR71XX -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select MYLOADER -+ -+config ATH79_MACH_WPE72 -+ bool "Compex WPE72/WPE72NX board support" -+ select SOC_AR724X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select MYLOADER -+ -+config ATH79_MACH_WPJ342 -+ bool "Compex WPJ342 board support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_WPJ344 -+ bool "Compex WPJ344 board support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_WPJ531 -+ bool "Compex WPJ531 board support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_WPJ558 -+ bool "Compex WPJ558 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_WPJ563 -+ bool "Compex WPJ563 board support" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_XD3200 -+ bool "YunCore XD3200 support" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_DGL_5500_A1 -+ bool "D-Link DGL-5500 A1 support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_DHP_1565_A1 -+ bool "D-Link DHP-1565 rev. A1 board support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_DIR_505_A1 -+ bool "D-Link DIR-505-A1 support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_DIR_600_A1 -+ bool "D-Link DIR-600 A1/DIR-615 E1/DIR-615 E4 support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_NVRAM -+ -+config ATH79_MACH_DIR_615_C1 -+ bool "D-Link DIR-615 rev. C1 support" -+ select SOC_AR913X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ select ATH79_NVRAM -+ -+config ATH79_MACH_DIR_615_I1 -+ bool "D-Link DIR-615 rev. I1 support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_DIR_825_B1 -+ bool "D-Link DIR-825 rev. B1 board support" -+ select SOC_AR71XX -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_DIR_825_C1 -+ bool "D-Link DIR-825 rev. C1/DIR-835 rev. A1 board support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_DIR_869_A1 -+ bool "D-Link DIR-869 rev. A1" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ select ATH79_NVRAM -+ -+config ATH79_MACH_DLAN_HOTSPOT -+ bool "devolo dLAN Hotspot support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_DLAN_PRO_500_WP -+ bool "devolo dLAN pro 500 Wireless+ support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_SPI -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_DLAN_PRO_1200_AC -+ bool "devolo dLAN pro 1200+ WiFi ac support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_SPI -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_NFC -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_DOMYWIFI_DW33D -+ bool "DomyWifi DW33D support" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_NFC -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_DR342 -+ bool "Wallys DR342 board support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_DR344 -+ bool "Wallys DR344 board support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_DR531 -+ bool "Wallys DR531 board support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_DRAGINO2 -+ bool "DRAGINO V2 support" -+ select SOC_AR933X -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_ETH -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_E1700AC_V2 -+ bool "Qxwlan E1700AC v2 support" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_E2100L -+ bool "Linksys E2100L board support" -+ select SOC_AR913X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select ATH79_NVRAM -+ -+config ATH79_MACH_E558_V2 -+ bool "Qxwlan E558 v2 support" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_E600G_V2 -+ bool "Qxwlan E600G/E600GAC v2 support" -+ select SOC_QCA953X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_E750A_V4 -+ bool "Qxwlan E750A v4 support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_E750G_V8 -+ bool "Qxwlan E750G v8 support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ESR900 -+ bool "EnGenius ESR900 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select ATH79_NVRAM -+ -+config ATH79_MACH_EW_BALIN -+ bool "embedded wireless Balin Platform support" -+ select SOC_AR934X -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_ETH -+ select ATH79_DEV_USB -+ select ATH79_DEV_AP9X_PCI if PCI -+ -+config ATH79_MACH_EW_DORIN -+ bool "embedded wireless Dorin Platform support" -+ select SOC_AR933X -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_ETH -+ -+config ATH79_MACH_EL_M150 -+ bool "EasyLink EL-M150 support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_EL_MINI -+ bool "EasyLink EL-MINI support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_GL_AR150 -+ bool "GL AR150 support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_GL_AR300 -+ bool "GL_AR300 support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_GL_AR300M -+ bool "GL_AR300M support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_GL_AR750 -+ bool "GL.iNet GL-AR750 support" -+ select SOC_QCA953X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_GL_AR750S -+ bool "GL.iNet GL-AR750S support" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_GL_DOMINO -+ bool "DOMINO support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_GL_MIFI -+ bool "GL MIFI support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_GL_INET -+ bool "GL-INET support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_GL_USB150 -+ bool "GL.iNet GL-USB150 support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_EAP120 -+ bool "TP-LINK EAP120 support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ENS202EXT -+ bool "EnGenius ENS202EXT support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_EAP300V2 -+ bool "EnGenius EAP300 v2 support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_GS_MINIBOX_V32 -+ bool "Gainstrong Minibox V3.2 support" -+ select SOC_QCA953X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_SPI -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_ETH -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_GS_OOLITE_V1 -+ bool "GainStrong Oolite/Minibox V1.0 support" -+ select SOC_AR933X -+ select ARH79_DEV_ETH -+ select ARH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_GS_OOLITE_V5_2 -+ bool "GainStrong Oolite V5.2 support" -+ select SOC_QCA953X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_HIVEAP_121 -+ bool "Aerohive HiveAP-121 support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_NFC -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_HIWIFI_HC6361 -+ bool "HiWiFi HC6361 board support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_JA76PF -+ bool "jjPlus JA76PF board support" -+ select SOC_AR71XX -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_JWAP003 -+ bool "jjPlus JWAP003 board support" -+ select SOC_AR71XX -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_JWAP230 -+ bool "jjPlus JWAP230 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_KOALA -+ bool "OCEDO Koala board support" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_ETH -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_WAM250 -+ bool "Samsung WAM250 support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_WIFI_PINEAPPLE_NANO -+ bool "Hak5 WiFi Pineapple NANO support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_WRT160NL -+ bool "Linksys WRT160NL board support" -+ select SOC_AR913X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select ATH79_NVRAM -+ -+config ATH79_MACH_WRT400N -+ bool "Linksys WRT400N board support" -+ select SOC_AR71XX -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_WRTNODE2Q -+ bool "WRTnode2Q board support" -+ select SOC_QCA953X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_R36A -+ bool "ALFA Network R36A support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_R602N -+ bool "P&W R602N support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_R6100 -+ bool "NETGEAR R6100 board support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_NFC -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_MC_MAC1200R -+ bool "MERCURY MAC1200R board support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_RB4XX -+ bool "MikroTik RouterBOARD 4xx series support" -+ select SOC_AR71XX -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_RB750 -+ bool "MikroTik RouterBOARD 750 support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_USB -+ select ATH79_ROUTERBOOT -+ -+config ATH79_MACH_RB91X -+ bool "MikroTik RouterBOARD 91X support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_SPI -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_USB -+ select ATH79_ROUTERBOOT -+ -+config ATH79_MACH_RB922 -+ bool "MikroTik RouterBOARD 922 support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_NFC -+ select ATH79_DEV_USB -+ select ATH79_ROUTERBOOT -+ select RLE_DECOMPRESS -+ -+config ATH79_MACH_RB95X -+ bool "MikroTik RouterBOARD 95X support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_NFC -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_USB -+ select ATH79_ROUTERBOOT -+ -+config ATH79_MACH_RB2011 -+ bool "MikroTik RouterBOARD 2011 support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_NFC -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select ATH79_ROUTERBOOT -+ -+config ATH79_MACH_RBSPI -+ bool "MikroTik RouterBOARD SPI-NOR support" -+ select SOC_AR934X -+ select SOC_QCA953X -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select ATH79_ROUTERBOOT -+ help -+ Say 'Y' here if you want your kernel to support the -+ MikroTik ROuterBOARD 911-2Hn (911 Lite2) -+ MikroTik ROuterBOARD 911-5Hn (911 Lite5) -+ MikroTik RouterBOARD mAP -+ MikroTik RouterBOARD mAP lite -+ MikroTik RouterBOARD hAP mini -+ MikroTik RouterBOARD hAP lite -+ MikroTik RouterBOARD hAP -+ MikroTik RouterBOARD hAP ac -+ MikroTik RouterBOARD hAP ac lite -+ MikroTik RouterBOARD hEX PoE lite -+ MikroTik RouterBOARD hEX lite -+ MikroTik RouterBOARD Powerbox -+ MikroTik RouterBOARD LHG 5 -+ MikroTik RouterBOARD cAP (EXPERIMENTAL) -+ MikroTik RouterBOARD SXT Lite 2 r3 -+ MikroTik RouterBOARD wAP -+ MikroTik RouterBOARD wAP R-2nD -+ -+config ATH79_MACH_RBSXTLITE -+ bool "MikroTik RouterBOARD SXT Lite" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_NFC -+ select ATH79_DEV_WMAC -+ select ATH79_ROUTERBOOT -+ -+config ATH79_MACH_SMART_300 -+ bool "NC-LINK SMART-300 board support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_T830 -+ bool "YunCore T830 support" -+ select SOC_QCA953X -+ select ARH79_DEV_ETH -+ select ARH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TELLSTICK_ZNET_LITE -+ bool "TellStick ZNet Lite" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_WNDAP360 -+ bool "NETGEAR WNDAP360 board support" -+ select SOC_AR71XX -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_WNDR3700 -+ bool "NETGEAR WNDR3700 board support" -+ select SOC_AR71XX -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_WNDR4300 -+ bool "NETGEAR WNDR3700v4/WNDR4300 board support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_NFC -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_WNR2000 -+ bool "NETGEAR WNR2000 board support" -+ select SOC_AR913X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_WNR2000_V3 -+ bool "NETGEAR WNR2000 V3/WNR612 v2/WNR1000 v2/WPN824N board support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_WNR2200 -+ bool "NETGEAR WNR2200 board support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_WNR2000_V4 -+ bool "NETGEAR WNR2000 V4" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_OM2P -+ bool "OpenMesh OM2P board support" -+ select SOC_AR724X -+ select SOC_AR933X -+ select SOC_QCA953X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_OM5P -+ bool "OpenMesh OM5P board support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_OM5P_AC -+ bool "OpenMesh OM5P-AC board support" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_OM5P_ACv2 -+ bool "OpenMesh OM5P-ACv2 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_OMY_G1 -+ bool "OMYlink OMY G1 support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_OMY_X1 -+ bool "OMYlink OMY X1 support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ONION_OMEGA -+ bool "ONION OMEGA support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_MR12 -+ bool "Meraki MR12 board support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_MR16 -+ bool "Meraki MR16 board support" -+ select SOC_AR71XX -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_MR18 -+ bool "Meraki MR18 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_NFC -+ select ATH79_DEV_WMAC -+ select LEDS_NU801 -+ -+config ATH79_MACH_MR600 -+ bool "OpenMesh MR600 board support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_MZK_W04NU -+ bool "Planex MZK-W04NU board support" -+ select SOC_AR913X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_MZK_W300NH -+ bool "Planex MZK-W300NH board support" -+ select SOC_AR913X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_RE355 -+ bool "TP-LINK RE355 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_RE450 -+ bool "TP-LINK RE450 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_RME_EG200 -+ bool "eTactica EG200 board supprt" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_RUT9XX -+ bool "Teltonika RUT900 series support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select GPIO_PCA953X -+ -+config ATH79_MACH_RW2458N -+ bool "Redwave RW2458N board support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_CAP324 -+ bool "PowerCloud Systems CAP324 support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_CAP4200AG -+ bool "Senao CAP4200AG support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_CR3000 -+ bool "PowerCloud Systems CR3000 support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_CR5000 -+ bool "PowerCloud CR5000 support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_MR1750 -+ bool "OpenMesh MR1750 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_MR900 -+ bool "OpenMesh MR900 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_EAP7660D -+ bool "Senao EAP7660D support" -+ select SOC_AR71XX -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_BSB -+ bool "Smart Electronics Black Swift board" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ARCHER_C25_V1 -+ bool "TP-LINK Archer C25 v1 support" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ARCHER_C58_V1 -+ bool "TP-LINK Archer C58 v1 support" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ARCHER_C59_V1 -+ bool "TP-LINK Archer C59 v1 support" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ARCHER_C59_V2 -+ bool "TP-LINK Archer C59 v2 support" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ARCHER_C60_V1 -+ bool "TP-LINK Archer C60 v1 support" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ARCHER_C60_V2 -+ bool "TP-LINK Archer C60 v2 support" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ARCHER_C7 -+ bool "TP-LINK Archer C5/C7/TL-WDR4900 v2 board support" -+ select SOC_QCA955X -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_CPE505N -+ bool "P&W CPE505N support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_CPE510 -+ bool "TP-LINK CPE510 support" -+ select SOC_AR934X -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_CPE830 -+ bool "YunCore CPE830 support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_CPE870 -+ bool "YunCore CPE870 support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_MR11U -+ bool "TP-LINK TL-MR11U/TL-MR3040 support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_MR13U -+ bool "TP-LINK TL-MR13U support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_MR3020 -+ bool "TP-LINK TL-MR3020 support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_MR3X20 -+ bool "TP-LINK TL-MR3220/3420 support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_TL_MR6400 -+ bool "TP-LINK TL-MR6400 support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WAX50RE -+ bool "TP-LINK TL-WA750/850RE support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WA701ND_V2 -+ bool "TP-LINK TL-WA701ND v2 support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WA7210N_V2 -+ bool "TP-LINK TL-WA7210N v2 support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WA801ND_V3 -+ bool "TP-LINK TL-WA801ND v3 support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WA830RE_V2 -+ bool "TP-LINK TL-WA830RE v2 support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WA850RE_V2 -+ bool "TP-LINK TL-WA850RE v2 support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WA855RE_V1 -+ bool "TP-LINK TL-WA855RE V1 support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WA901ND -+ bool "TP-LINK TL-WA901ND/TL-WA7510N support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_TL_WA901ND_V2 -+ bool "TP-LINK TL-WA901ND v2 support" -+ select SOC_AR913X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WA901ND_V4 -+ bool "TP-LINK TL-WA901ND v4 support" -+ select SOC_QCA956X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WDR3320_V2 -+ bool "TP-LINK TL-WDR3320 v2 board support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WDR3500 -+ bool "TP-LINK TL-WDR3500 board support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WDR4300 -+ bool "TP-LINK TL-WDR3600/4300/4310 board support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WDR6500_V2 -+ bool "TP-LINK TL-WDR6500 v2 board support" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR703N -+ bool "TP-LINK TL-WR703N/TL-WR710N/TL-MR10U support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR720N_V3 -+ bool "TP-LINK TL-WR720N v3/v4 support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR741ND -+ bool "TP-LINK TL-WR741ND support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_TL_WR741ND_V4 -+ bool "TP-LINK TL-WR741ND v4/TL-MR3220 v2 support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR802N_V1 -+ bool "TP-LINK TL-WR802N v1 support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_TL_WR802N_V2 -+ bool "TP-LINK TL-WR802N v2 support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_TL_WR810N -+ bool "TP-LINK TL-WR810N support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR810N_V2 -+ bool "TP-LINK TL-WR810N v2 support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR840N_V2 -+ bool "TP-LINK TL-WR840N v2/v3 support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR841N_V1 -+ bool "TP-LINK TL-WR841N v1 support" -+ select SOC_AR71XX -+ select ATH79_DEV_DSA -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_TL_WR841N_V8 -+ bool "TP-LINK TL-WR841N/ND v8/TL-MR3420 v2 support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR841N_V9 -+ bool "TP-LINK TL-WR841N/ND v9/TL-WR842N/ND v3/TL-WR740N/ND v6 support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR902AC_V1 -+ bool "TP-LINK TL-WR902AC v1 support" -+ select SOC_QCA953X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR941ND -+ bool "TP-LINK TL-WR941ND support" -+ select SOC_AR913X -+ select ATH79_DEV_DSA -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR941ND_V6 -+ bool "TP-LINK TL-WR941ND v6 support" -+ select SOC_QCA956X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR940N_V4 -+ bool "TP-LINK TL-WR940N v4 support" -+ select SOC_QCA956X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR942N_V1 -+ bool "TP-LINK TL-WR942N v1 support" -+ select SOC_QCA956X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select ATH79_NVRAM -+ -+config ATH79_MACH_TL_WR1041N_V2 -+ bool "TP-LINK TL-WR1041N v2 support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR1043N_V5 -+ bool "TP-LINK TL-WR1043N v5 support" -+ select SOC_QCA956X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR1043ND -+ bool "TP-LINK TL-WR1043ND support" -+ select SOC_AR913X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR1043ND_V2 -+ bool "TP-LINK TL-WR1043ND v2 support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR1043ND_V4 -+ bool "TP-LINK TL-WR1043ND v4 support" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TL_WR2543N -+ bool "TP-LINK TL-WR2543N/ND support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_TS_D084 -+ bool "PISEN TS-D084 support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TEW_632BRP -+ bool "TRENDnet TEW-632BRP support" -+ select SOC_AR913X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ select ATH79_NVRAM -+ -+config ATH79_MACH_TEW_673GRU -+ bool "TRENDnet TEW-673GRU support" -+ select SOC_AR71XX -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_TEW_712BR -+ bool "TRENDnet TEW-712BR support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TEW_732BR -+ bool "TRENDnet TEW-732BR support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_TEW_823DRU -+ bool "TRENDnet TEW-823DRU support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_UBNT -+ bool "Ubiquiti AR71xx based boards support" -+ select SOC_AR71XX -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_UBNT_UNIFIAC -+ bool "Ubiquiti UniFi AC (LITE/LR/MESH/PRO/MESH-PRO) support" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_WEIO -+ bool "WeIO board" -+ select SOC_AR933X -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_MYNET_N600 -+ bool "WD My Net N600 board support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ select ATH79_NVRAM -+ -+config ATH79_MACH_MYNET_N750 -+ bool "WD My Net N750 board support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ select ATH79_NVRAM -+ -+config ATH79_MACH_MYNET_REXT -+ bool "WD My Net Wi-Fi Range Extender board support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ select ATH79_NVRAM -+ -+config ATH79_MACH_Z1 -+ bool "Meraki Z1 board support" -+ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_NFC -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select LEDS_NU801 -+ -+config ATH79_MACH_ZBT_WE1526 -+ bool "Zbtlink ZBT-WE1526 board support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_ZCN_1523H -+ bool "Zcomax ZCN-1523H support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_N5Q -+ bool "ALFA Network N5Q support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_NBG460N -+ bool "Zyxel NBG460N/550N/550NH board support" -+ select SOC_AR913X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_NBG6716 -+ bool "Zyxel NBG6616/NBG6716 board support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_NFC -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select ATH79_NVRAM -+ -+config ATH79_MACH_CARAMBOLA2 -+ bool "8devices Carambola2 board" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_LAN_TURTLE -+ bool "Hak5 LAN Turtle and Packet Squirrel support" -+ select SOC_AR933X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ -+config ATH79_MACH_LIMA -+ bool "8devices Lima board" -+ select SOC_QCA953X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_SPI -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_ETH -+ -+config ATH79_MACH_RAMBUTAN -+ bool "8devices Rambutan board" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_NFC -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_CF_E316N_V2 -+ bool "COMFAST CF-E316N v2 support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_CF_E320N_V2 -+ bool "COMFAST CF-E320N v2 support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_CF_E355AC -+ bool "COMFAST CF-E355AC v1/v2 support" -+ select SOC_QCA953X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_CF_E375AC -+ bool "COMFAST CF-E375AC support" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_CF_E380AC_V1 -+ bool "COMFAST CF-E380AC v1 support" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_CF_E380AC_V2 -+ bool "COMFAST CF-E380AC v2 support" -+ select SOC_QCA955X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_CF_E520N -+ bool "COMFAST CF-E520N support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_CF_E530N -+ bool "COMFAST CF-E530N support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_BHU_BXU2000N2_A -+ bool "BHU BXU2000n-2 rev. A support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_QIHOO_C301 -+ bool "Qihoo 360 C301 board support" -+ select SOC_AR934X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ select ATH79_DEV_USB -+ select ATH79_NVRAM -+ -+config ATH79_MACH_DAP_1330_A1 -+ bool "D-Link DAP-1330 rev. A1 support" -+ select SOC_QCA953X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_DAP_2695_A1 -+ bool "D-Link DAP-2695 rev. A1 support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ select ATH79_NVRAM -+ -+config ATH79_MACH_TL_WPA8630 -+ bool "TP-Link TL-WPA8630 support" -+ select SOC_QCA956X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -+ -+config ATH79_MACH_FRITZ300E -+ bool "AVM FRITZ!WLAN Repeater 300E support" -+ select SOC_AR724X -+ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_FRITZ4020 -+ bool "AVM FRITZ!Box 4020 support" -+ select SOC_QCA956X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_USB -+ select ATH79_DEV_M25P80 -+ -+config ATH79_MACH_FRITZ450E -+ bool "AVM FRITZ!WLAN Repeater 450E support" -+ select SOC_QCA955X -+ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -+ select ATH79_DEV_WMAC -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/Makefile b/target/linux/ar71xx/files/arch/mips/ath79/Makefile -new file mode 100644 -index 0000000000..0265b3d818 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/Makefile -@@ -0,0 +1,290 @@ -+# -+# Makefile for the Atheros AR71XX/AR724X/AR913X specific parts of the kernel -+# -+# Copyright (C) 2008-2011 Gabor Juhos -+# Copyright (C) 2008 Imre Kaloz -+# -+# This program is free software; you can redistribute it and/or modify it -+# under the terms of the GNU General Public License version 2 as published -+# by the Free Software Foundation. -+ -+obj-y := prom.o setup.o irq.o common.o clock.o gpio.o -+ -+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -+obj-$(CONFIG_PCI) += pci.o -+ -+# -+# Devices -+# -+obj-y += dev-common.o -+obj-$(CONFIG_ATH79_DEV_AP9X_PCI) += dev-ap9x-pci.o -+obj-$(CONFIG_ATH79_DEV_DSA) += dev-dsa.o -+obj-$(CONFIG_ATH79_DEV_ETH) += dev-eth.o -+obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o -+obj-$(CONFIG_ATH79_DEV_LEDS_GPIO) += dev-leds-gpio.o -+obj-$(CONFIG_ATH79_DEV_M25P80) += dev-m25p80.o -+obj-$(CONFIG_ATH79_DEV_NFC) += dev-nfc.o -+obj-$(CONFIG_ATH79_DEV_SPI) += dev-spi.o -+obj-$(CONFIG_ATH79_DEV_USB) += dev-usb.o -+obj-$(CONFIG_ATH79_DEV_WMAC) += dev-wmac.o -+ -+# -+# Miscellaneous objects -+# -+obj-$(CONFIG_ATH79_NVRAM) += nvram.o -+obj-$(CONFIG_ATH79_PCI_ATH9K_FIXUP) += pci-ath9k-fixup.o -+obj-$(CONFIG_ATH79_ROUTERBOOT) += routerboot.o -+ -+# -+# Machines -+# -+obj-$(CONFIG_ATH79_MACH_A60) += mach-a60.o -+obj-$(CONFIG_ATH79_MACH_WI2A_AC200I) += mach-wi2a-ac200i.o -+obj-$(CONFIG_ATH79_MACH_ALFA_AP120C) += mach-alfa-ap120c.o -+obj-$(CONFIG_ATH79_MACH_ALFA_AP96) += mach-alfa-ap96.o -+obj-$(CONFIG_ATH79_MACH_ALFA_NX) += mach-alfa-nx.o -+obj-$(CONFIG_ATH79_MACH_ALL0258N) += mach-all0258n.o -+obj-$(CONFIG_ATH79_MACH_ALL0315N) += mach-all0315n.o -+obj-$(CONFIG_ATH79_MACH_ANTMINER_S1) += mach-antminer-s1.o -+obj-$(CONFIG_ATH79_MACH_ANTMINER_S3) += mach-antminer-s3.o -+obj-$(CONFIG_ATH79_MACH_ANTROUTER_R1) += mach-antrouter-r1.o -+obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o -+obj-$(CONFIG_ATH79_MACH_AP121F) += mach-ap121f.o -+obj-$(CONFIG_ATH79_MACH_AP132) += mach-ap132.o -+obj-$(CONFIG_ATH79_MACH_AP136) += mach-ap136.o -+obj-$(CONFIG_ATH79_MACH_AP143) += mach-ap143.o -+obj-$(CONFIG_ATH79_MACH_AP147) += mach-ap147.o -+obj-$(CONFIG_ATH79_MACH_AP152) += mach-ap152.o -+obj-$(CONFIG_ATH79_MACH_AP531B0) += mach-ap531b0.o -+obj-$(CONFIG_ATH79_MACH_AP90Q) += mach-ap90q.o -+obj-$(CONFIG_ATH79_MACH_AP91_5G) += mach-ap91-5g.o -+obj-$(CONFIG_ATH79_MACH_AP96) += mach-ap96.o -+obj-$(CONFIG_ATH79_MACH_ARCHER_C25_V1) += mach-archer-c25-v1.o -+obj-$(CONFIG_ATH79_MACH_ARCHER_C58_V1) += mach-archer-c59-v1.o -+obj-$(CONFIG_ATH79_MACH_ARCHER_C59_V1) += mach-archer-c59-v1.o -+obj-$(CONFIG_ATH79_MACH_ARCHER_C60_V1) += mach-archer-c60-v1.o -+obj-$(CONFIG_ATH79_MACH_ARCHER_C60_V2) += mach-archer-c60-v1.o -+obj-$(CONFIG_ATH79_MACH_ARCHER_C7) += mach-archer-c7.o -+obj-$(CONFIG_ATH79_MACH_ARCHER_C7) += mach-archer-c7-v4.o -+obj-$(CONFIG_ATH79_MACH_ARCHER_C7) += mach-archer-c7-v5.o -+obj-$(CONFIG_ATH79_MACH_ARDUINO_YUN) += mach-arduino-yun.o -+obj-$(CONFIG_ATH79_MACH_AW_NR580) += mach-aw-nr580.o -+obj-$(CONFIG_ATH79_MACH_BHR_4GRV2) += mach-bhr-4grv2.o -+obj-$(CONFIG_ATH79_MACH_BHU_BXU2000N2_A) += mach-bhu-bxu2000n2-a.o -+obj-$(CONFIG_ATH79_MACH_BSB) += mach-bsb.o -+obj-$(CONFIG_ATH79_MACH_C55) += mach-c55.o -+obj-$(CONFIG_ATH79_MACH_C60) += mach-c60.o -+obj-$(CONFIG_ATH79_MACH_CAP324) += mach-cap324.o -+obj-$(CONFIG_ATH79_MACH_CAP4200AG) += mach-cap4200ag.o -+obj-$(CONFIG_ATH79_MACH_CARAMBOLA2) += mach-carambola2.o -+obj-$(CONFIG_ATH79_MACH_CF_E316N_V2) += mach-cf-e316n-v2.o -+obj-$(CONFIG_ATH79_MACH_CF_E320N_V2) += mach-cf-e316n-v2.o -+obj-$(CONFIG_ATH79_MACH_CF_E355AC) += mach-cf-e316n-v2.o -+obj-$(CONFIG_ATH79_MACH_CF_E375AC) += mach-cf-e316n-v2.o -+obj-$(CONFIG_ATH79_MACH_CF_E380AC_V1) += mach-cf-e316n-v2.o -+obj-$(CONFIG_ATH79_MACH_CF_E380AC_V2) += mach-cf-e316n-v2.o -+obj-$(CONFIG_ATH79_MACH_CF_E520N) += mach-cf-e316n-v2.o -+obj-$(CONFIG_ATH79_MACH_CF_E530N) += mach-cf-e316n-v2.o -+obj-$(CONFIG_ATH79_MACH_CPE505N) += mach-r602n.o -+obj-$(CONFIG_ATH79_MACH_CPE510) += mach-cpe510.o -+obj-$(CONFIG_ATH79_MACH_CPE830) += mach-ap90q.o -+obj-$(CONFIG_ATH79_MACH_CPE870) += mach-cpe870.o -+obj-$(CONFIG_ATH79_MACH_CR3000) += mach-cr3000.o -+obj-$(CONFIG_ATH79_MACH_CR5000) += mach-cr5000.o -+obj-$(CONFIG_ATH79_MACH_DAP_1330_A1) += mach-dap-1330-a1.o -+obj-$(CONFIG_ATH79_MACH_DAP_2695_A1) += mach-dap-2695-a1.o -+obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o -+obj-$(CONFIG_ATH79_MACH_DGL_5500_A1) += mach-dgl-5500-a1.o -+obj-$(CONFIG_ATH79_MACH_DHP_1565_A1) += mach-dhp-1565-a1.o -+obj-$(CONFIG_ATH79_MACH_DIR_505_A1) += mach-dir-505-a1.o -+obj-$(CONFIG_ATH79_MACH_DIR_600_A1) += mach-dir-600-a1.o -+obj-$(CONFIG_ATH79_MACH_DIR_615_C1) += mach-dir-615-c1.o -+obj-$(CONFIG_ATH79_MACH_DIR_615_I1) += mach-dir-615-i1.o -+obj-$(CONFIG_ATH79_MACH_DIR_825_B1) += mach-dir-825-b1.o -+obj-$(CONFIG_ATH79_MACH_DIR_825_C1) += mach-dir-825-c1.o -+obj-$(CONFIG_ATH79_MACH_DIR_869_A1) += mach-dir-869-a1.o -+obj-$(CONFIG_ATH79_MACH_DLAN_HOTSPOT) += mach-dlan-hotspot.o -+obj-$(CONFIG_ATH79_MACH_DLAN_PRO_1200_AC) += mach-dlan-pro-1200-ac.o -+obj-$(CONFIG_ATH79_MACH_DLAN_PRO_500_WP) += mach-dlan-pro-500-wp.o -+obj-$(CONFIG_ATH79_MACH_DOMYWIFI_DW33D) += mach-domywifi-dw33d.o -+obj-$(CONFIG_ATH79_MACH_DR342) += mach-dr344.o -+obj-$(CONFIG_ATH79_MACH_DR344) += mach-dr344.o -+obj-$(CONFIG_ATH79_MACH_DR531) += mach-dr531.o -+obj-$(CONFIG_ATH79_MACH_DRAGINO2) += mach-dragino2.o -+obj-$(CONFIG_ATH79_MACH_E1700AC_V2) += mach-e1700ac-v2.o -+obj-$(CONFIG_ATH79_MACH_E558_V2) += mach-e558-v2.o -+obj-$(CONFIG_ATH79_MACH_E600G_V2) += mach-e600g-v2.o -+obj-$(CONFIG_ATH79_MACH_E750A_V4) += mach-e750a-v4.o -+obj-$(CONFIG_ATH79_MACH_E750G_V8) += mach-e750g-v8.o -+obj-$(CONFIG_ATH79_MACH_EAP120) += mach-eap120.o -+obj-$(CONFIG_ATH79_MACH_EAP300V2) += mach-eap300v2.o -+obj-$(CONFIG_ATH79_MACH_EAP7660D) += mach-eap7660d.o -+obj-$(CONFIG_ATH79_MACH_EL_M150) += mach-el-m150.o -+obj-$(CONFIG_ATH79_MACH_EL_MINI) += mach-el-mini.o -+obj-$(CONFIG_ATH79_MACH_ENS202EXT) += mach-ens202ext.o -+obj-$(CONFIG_ATH79_MACH_EPG5000) += mach-epg5000.o -+obj-$(CONFIG_ATH79_MACH_ESR1750) += mach-esr1750.o -+obj-$(CONFIG_ATH79_MACH_ESR900) += mach-esr900.o -+obj-$(CONFIG_ATH79_MACH_EW_BALIN) += mach-ew-balin.o -+obj-$(CONFIG_ATH79_MACH_EW_DORIN) += mach-ew-dorin.o -+obj-$(CONFIG_ATH79_MACH_F9K1115V2) += mach-f9k1115v2.o -+obj-$(CONFIG_ATH79_MACH_FRITZ300E) += mach-fritz300e.o -+obj-$(CONFIG_ATH79_MACH_FRITZ4020) += mach-fritz4020.o -+obj-$(CONFIG_ATH79_MACH_FRITZ450E) += mach-fritz450e.o -+obj-$(CONFIG_ATH79_MACH_GL_AR150) += mach-gl-ar150.o -+obj-$(CONFIG_ATH79_MACH_GL_AR300) += mach-gl-ar300.o -+obj-$(CONFIG_ATH79_MACH_GL_AR300M) += mach-gl-ar300m.o -+obj-$(CONFIG_ATH79_MACH_GL_AR750) += mach-gl-ar750.o -+obj-$(CONFIG_ATH79_MACH_GL_AR750S) += mach-gl-ar750s.o -+obj-$(CONFIG_ATH79_MACH_GL_DOMINO) += mach-gl-domino.o -+obj-$(CONFIG_ATH79_MACH_GL_INET) += mach-gl-inet.o -+obj-$(CONFIG_ATH79_MACH_GL_MIFI) += mach-gl-mifi.o -+obj-$(CONFIG_ATH79_MACH_GL_USB150) += mach-gl-usb150.o -+obj-$(CONFIG_ATH79_MACH_GS_MINIBOX_V32) += mach-gs-minibox-v32.o -+obj-$(CONFIG_ATH79_MACH_GS_OOLITE_V1) += mach-gs-oolite-v1.o -+obj-$(CONFIG_ATH79_MACH_GS_OOLITE_V5_2) += mach-gs-oolite-v5-2.o -+obj-$(CONFIG_ATH79_MACH_HIVEAP_121) += mach-hiveap-121.o -+obj-$(CONFIG_ATH79_MACH_HIWIFI_HC6361) += mach-hiwifi-hc6361.o -+obj-$(CONFIG_ATH79_MACH_HORNET_UB) += mach-hornet-ub.o -+obj-$(CONFIG_ATH79_MACH_JA76PF) += mach-ja76pf.o -+obj-$(CONFIG_ATH79_MACH_JWAP003) += mach-jwap003.o -+obj-$(CONFIG_ATH79_MACH_JWAP230) += mach-jwap230.o -+obj-$(CONFIG_ATH79_MACH_KOALA) += mach-koala.o -+obj-$(CONFIG_ATH79_MACH_LAN_TURTLE) += mach-lan-turtle.o -+obj-$(CONFIG_ATH79_MACH_LIMA) += mach-lima.o -+obj-$(CONFIG_ATH79_MACH_MC_MAC1200R) += mach-mc-mac1200r.o -+obj-$(CONFIG_ATH79_MACH_MR12) += mach-mr12.o -+obj-$(CONFIG_ATH79_MACH_MR16) += mach-mr16.o -+obj-$(CONFIG_ATH79_MACH_MR1750) += mach-mr1750.o -+obj-$(CONFIG_ATH79_MACH_MR18) += mach-mr18.o -+obj-$(CONFIG_ATH79_MACH_MR600) += mach-mr600.o -+obj-$(CONFIG_ATH79_MACH_MR900) += mach-mr900.o -+obj-$(CONFIG_ATH79_MACH_MYNET_N600) += mach-mynet-n600.o -+obj-$(CONFIG_ATH79_MACH_MYNET_N750) += mach-mynet-n750.o -+obj-$(CONFIG_ATH79_MACH_MYNET_REXT) += mach-mynet-rext.o -+obj-$(CONFIG_ATH79_MACH_MZK_W04NU) += mach-mzk-w04nu.o -+obj-$(CONFIG_ATH79_MACH_MZK_W300NH) += mach-mzk-w300nh.o -+obj-$(CONFIG_ATH79_MACH_N5Q) += mach-n5q.o -+obj-$(CONFIG_ATH79_MACH_NBG460N) += mach-nbg460n.o -+obj-$(CONFIG_ATH79_MACH_NBG6716) += mach-nbg6716.o -+obj-$(CONFIG_ATH79_MACH_RAMBUTAN) += mach-rambutan.o -+obj-$(CONFIG_ATH79_MACH_OM2P) += mach-om2p.o -+obj-$(CONFIG_ATH79_MACH_OM5P) += mach-om5p.o -+obj-$(CONFIG_ATH79_MACH_OM5P_AC) += mach-om5pac.o -+obj-$(CONFIG_ATH79_MACH_OM5P_ACv2) += mach-om5pacv2.o -+obj-$(CONFIG_ATH79_MACH_OMY_G1) += mach-omy-g1.o -+obj-$(CONFIG_ATH79_MACH_OMY_X1) += mach-omy-x1.o -+obj-$(CONFIG_ATH79_MACH_ONION_OMEGA) += mach-onion-omega.o -+obj-$(CONFIG_ATH79_MACH_PB42) += mach-pb42.o -+obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o -+obj-$(CONFIG_ATH79_MACH_PQI_AIR_PEN) += mach-pqi-air-pen.o -+obj-$(CONFIG_ATH79_MACH_QIHOO_C301) += mach-qihoo-c301.o -+obj-$(CONFIG_ATH79_MACH_R36A) += mach-r36a.o -+obj-$(CONFIG_ATH79_MACH_R602N) += mach-r602n.o -+obj-$(CONFIG_ATH79_MACH_R6100) += mach-r6100.o -+obj-$(CONFIG_ATH79_MACH_RB2011) += mach-rb2011.o -+obj-$(CONFIG_ATH79_MACH_RB4XX) += mach-rb4xx.o -+obj-$(CONFIG_ATH79_MACH_RB750) += mach-rb750.o -+obj-$(CONFIG_ATH79_MACH_RB91X) += mach-rb91x.o -+obj-$(CONFIG_ATH79_MACH_RB922) += mach-rb922.o -+obj-$(CONFIG_ATH79_MACH_RB941) += mach-rb941.o -+obj-$(CONFIG_ATH79_MACH_RB95X) += mach-rb95x.o -+obj-$(CONFIG_ATH79_MACH_RBSPI) += mach-rbspi.o -+obj-$(CONFIG_ATH79_MACH_RBSXTLITE) += mach-rbsxtlite.o -+obj-$(CONFIG_ATH79_MACH_RE355) += mach-re450.o -+obj-$(CONFIG_ATH79_MACH_RE450) += mach-re450.o -+obj-$(CONFIG_ATH79_MACH_RME_EG200) += mach-rme-eg200.o -+obj-$(CONFIG_ATH79_MACH_RUT9XX) += mach-rut9xx.o -+obj-$(CONFIG_ATH79_MACH_RW2458N) += mach-rw2458n.o -+obj-$(CONFIG_ATH79_MACH_SC1750) += mach-sc1750.o -+obj-$(CONFIG_ATH79_MACH_SC300M) += mach-sc300m.o -+obj-$(CONFIG_ATH79_MACH_SC450) += mach-sc450.o -+obj-$(CONFIG_ATH79_MACH_SMART_300) += mach-smart-300.o -+obj-$(CONFIG_ATH79_MACH_SOM9331) += mach-som9331.o -+obj-$(CONFIG_ATH79_MACH_SR3200) += mach-sr3200.o -+obj-$(CONFIG_ATH79_MACH_T830) += mach-t830.o -+obj-$(CONFIG_ATH79_MACH_TELLSTICK_ZNET_LITE) += mach-tellstick-znet-lite.o -+obj-$(CONFIG_ATH79_MACH_TEW_632BRP) += mach-tew-632brp.o -+obj-$(CONFIG_ATH79_MACH_TEW_673GRU) += mach-tew-673gru.o -+obj-$(CONFIG_ATH79_MACH_TEW_712BR) += mach-tew-712br.o -+obj-$(CONFIG_ATH79_MACH_TEW_732BR) += mach-tew-732br.o -+obj-$(CONFIG_ATH79_MACH_TEW_823DRU) += mach-tew-823dru.o -+obj-$(CONFIG_ATH79_MACH_TL_MR11U) += mach-tl-mr11u.o -+obj-$(CONFIG_ATH79_MACH_TL_MR13U) += mach-tl-mr13u.o -+obj-$(CONFIG_ATH79_MACH_TL_MR3020) += mach-tl-mr3020.o -+obj-$(CONFIG_ATH79_MACH_TL_MR3X20) += mach-tl-mr3x20.o -+obj-$(CONFIG_ATH79_MACH_TL_MR6400) += mach-tl-mr6400.o -+obj-$(CONFIG_ATH79_MACH_TL_WA701ND_V2) += mach-tl-wa701nd-v2.o -+obj-$(CONFIG_ATH79_MACH_TL_WA7210N_V2) += mach-tl-wa7210n-v2.o -+obj-$(CONFIG_ATH79_MACH_TL_WA801ND_V3) += mach-tl-wa801nd-v3.o -+obj-$(CONFIG_ATH79_MACH_TL_WA830RE_V2) += mach-tl-wa830re-v2.o -+obj-$(CONFIG_ATH79_MACH_TL_WA850RE_V2) += mach-tl-wax50re.o -+obj-$(CONFIG_ATH79_MACH_TL_WA855RE_V1) += mach-tl-wax50re.o -+obj-$(CONFIG_ATH79_MACH_TL_WA901ND) += mach-tl-wa901nd.o -+obj-$(CONFIG_ATH79_MACH_TL_WA901ND_V2) += mach-tl-wa901nd-v2.o -+obj-$(CONFIG_ATH79_MACH_TL_WA901ND_V4) += mach-tl-wa901nd-v4.o -+obj-$(CONFIG_ATH79_MACH_TL_WAX50RE) += mach-tl-wax50re.o -+obj-$(CONFIG_ATH79_MACH_TL_WDR3320_V2) += mach-tl-wdr3320-v2.o -+obj-$(CONFIG_ATH79_MACH_TL_WDR3500) += mach-tl-wdr3500.o -+obj-$(CONFIG_ATH79_MACH_TL_WDR4300) += mach-tl-wdr4300.o -+obj-$(CONFIG_ATH79_MACH_TL_WDR6500_V2) += mach-tl-wdr6500-v2.o -+obj-$(CONFIG_ATH79_MACH_TL_WPA8630) += mach-tl-wpa8630.o -+obj-$(CONFIG_ATH79_MACH_TL_WR1041N_V2) += mach-tl-wr1041n-v2.o -+obj-$(CONFIG_ATH79_MACH_TL_WR1043ND) += mach-tl-wr1043nd.o -+obj-$(CONFIG_ATH79_MACH_TL_WR1043ND_V2) += mach-tl-wr1043nd-v2.o -+obj-$(CONFIG_ATH79_MACH_TL_WR1043ND_V4) += mach-tl-wr1043nd-v4.o -+obj-$(CONFIG_ATH79_MACH_TL_WR2543N) += mach-tl-wr2543n.o -+obj-$(CONFIG_ATH79_MACH_TL_WR703N) += mach-tl-wr703n.o -+obj-$(CONFIG_ATH79_MACH_TL_WR720N_V3) += mach-tl-wr720n-v3.o -+obj-$(CONFIG_ATH79_MACH_TL_WR741ND) += mach-tl-wr741nd.o -+obj-$(CONFIG_ATH79_MACH_TL_WR741ND_V4) += mach-tl-wr741nd-v4.o -+obj-$(CONFIG_ATH79_MACH_TL_WR802N_V1) += mach-tl-wr802n.o -+obj-$(CONFIG_ATH79_MACH_TL_WR802N_V2) += mach-tl-wr802n.o -+obj-$(CONFIG_ATH79_MACH_TL_WR810N) += mach-tl-wr810n.o -+obj-$(CONFIG_ATH79_MACH_TL_WR810N_V2) += mach-tl-wr810n.o -+obj-$(CONFIG_ATH79_MACH_TL_WR840N_V2) += mach-tl-wr841n-v9.o -+obj-$(CONFIG_ATH79_MACH_TL_WR841N_V1) += mach-tl-wr841n.o -+obj-$(CONFIG_ATH79_MACH_TL_WR841N_V8) += mach-tl-wr841n-v8.o -+obj-$(CONFIG_ATH79_MACH_TL_WR841N_V9) += mach-tl-wr841n-v9.o -+obj-$(CONFIG_ATH79_MACH_TL_WR902AC_V1) += mach-tl-wr902ac-v1.o -+obj-$(CONFIG_ATH79_MACH_TL_WR941ND) += mach-tl-wr941nd.o -+obj-$(CONFIG_ATH79_MACH_TL_WR941ND_V6) += mach-tl-wr941nd-v6.o -+obj-$(CONFIG_ATH79_MACH_TL_WR940N_V4) += mach-tl-wr940n-v4.o -+obj-$(CONFIG_ATH79_MACH_TL_WR942N_V1) += mach-tl-wr942n-v1.o -+obj-$(CONFIG_ATH79_MACH_TS_D084) += mach-ts-d084.o -+obj-$(CONFIG_ATH79_MACH_TUBE2H) += mach-tube2h.o -+obj-$(CONFIG_ATH79_MACH_UBNT) += mach-ubnt.o -+obj-$(CONFIG_ATH79_MACH_UBNT_UNIFIAC) += mach-ubnt-unifiac.o -+obj-$(CONFIG_ATH79_MACH_UBNT_XM) += mach-ubnt-xm.o -+obj-$(CONFIG_ATH79_MACH_WAM250) += mach-wam250.o -+obj-$(CONFIG_ATH79_MACH_WEIO) += mach-weio.o -+obj-$(CONFIG_ATH79_MACH_WHR_HP_G300N) += mach-whr-hp-g300n.o -+obj-$(CONFIG_ATH79_MACH_WIFI_PINEAPPLE_NANO) += mach-wifi-pineapple-nano.o -+obj-$(CONFIG_ATH79_MACH_WLAE_AG300N) += mach-wlae-ag300n.o -+obj-$(CONFIG_ATH79_MACH_WLR8100) += mach-wlr8100.o -+obj-$(CONFIG_ATH79_MACH_WNDAP360) += mach-wndap360.o -+obj-$(CONFIG_ATH79_MACH_WNDR3700) += mach-wndr3700.o -+obj-$(CONFIG_ATH79_MACH_WNDR4300) += mach-wndr4300.o -+obj-$(CONFIG_ATH79_MACH_WNR2000) += mach-wnr2000.o -+obj-$(CONFIG_ATH79_MACH_WNR2000_V3) += mach-wnr2000-v3.o -+obj-$(CONFIG_ATH79_MACH_WNR2000_V4) += mach-wnr2000-v4.o -+obj-$(CONFIG_ATH79_MACH_WNR2200) += mach-wnr2200.o -+obj-$(CONFIG_ATH79_MACH_WP543) += mach-wp543.o -+obj-$(CONFIG_ATH79_MACH_WPE72) += mach-wpe72.o -+obj-$(CONFIG_ATH79_MACH_WPJ342) += mach-wpj342.o -+obj-$(CONFIG_ATH79_MACH_WPJ344) += mach-wpj344.o -+obj-$(CONFIG_ATH79_MACH_WPJ531) += mach-wpj531.o -+obj-$(CONFIG_ATH79_MACH_WPJ558) += mach-wpj558.o -+obj-$(CONFIG_ATH79_MACH_WPJ563) += mach-wpj563.o -+obj-$(CONFIG_ATH79_MACH_WRT160NL) += mach-wrt160nl.o -+obj-$(CONFIG_ATH79_MACH_WRT400N) += mach-wrt400n.o -+obj-$(CONFIG_ATH79_MACH_WRTNODE2Q) += mach-wrtnode2q.o -+obj-$(CONFIG_ATH79_MACH_WZR_450HP2) += mach-wzr-450hp2.o -+obj-$(CONFIG_ATH79_MACH_WZR_HP_AG300H) += mach-wzr-hp-ag300h.o -+obj-$(CONFIG_ATH79_MACH_WZR_HP_G300NH) += mach-wzr-hp-g300nh.o -+obj-$(CONFIG_ATH79_MACH_WZR_HP_G300NH2) += mach-wzr-hp-g300nh2.o -+obj-$(CONFIG_ATH79_MACH_WZR_HP_G450H) += mach-wzr-hp-g450h.o -+obj-$(CONFIG_ATH79_MACH_XD3200) += mach-sr3200.o -+obj-$(CONFIG_ATH79_MACH_Z1) += mach-z1.o -+obj-$(CONFIG_ATH79_MACH_ZBT_WE1526) += mach-zbt-we1526.o -+obj-$(CONFIG_ATH79_MACH_ZCN_1523H) += mach-zcn-1523h.o -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.c b/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.c -new file mode 100644 -index 0000000000..483aed78ed ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.c -@@ -0,0 +1,173 @@ -+/* -+ * Atheros AP9X reference board PCI initialization -+ * -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "dev-ap9x-pci.h" -+#include "pci-ath9k-fixup.h" -+#include "pci.h" -+ -+static struct ath9k_platform_data ap9x_wmac0_data = { -+ .led_pin = -1, -+}; -+static struct ath9k_platform_data ap9x_wmac1_data = { -+ .led_pin = -1, -+}; -+static char ap9x_wmac0_mac[6]; -+static char ap9x_wmac1_mac[6]; -+ -+__init void ap9x_pci_setup_wmac_led_pin(unsigned wmac, int pin) -+{ -+ switch (wmac) { -+ case 0: -+ ap9x_wmac0_data.led_pin = pin; -+ break; -+ case 1: -+ ap9x_wmac1_data.led_pin = pin; -+ break; -+ } -+} -+ -+__init struct ath9k_platform_data *ap9x_pci_get_wmac_data(unsigned wmac) -+{ -+ switch (wmac) { -+ case 0: -+ return &ap9x_wmac0_data; -+ -+ case 1: -+ return &ap9x_wmac1_data; -+ } -+ -+ return NULL; -+} -+ -+__init void ap9x_pci_setup_wmac_gpio(unsigned wmac, u32 mask, u32 val) -+{ -+ switch (wmac) { -+ case 0: -+ ap9x_wmac0_data.gpio_mask = mask; -+ ap9x_wmac0_data.gpio_val = val; -+ break; -+ case 1: -+ ap9x_wmac1_data.gpio_mask = mask; -+ ap9x_wmac1_data.gpio_val = val; -+ break; -+ } -+} -+ -+__init void ap9x_pci_setup_wmac_leds(unsigned wmac, struct gpio_led *leds, -+ int num_leds) -+{ -+ switch (wmac) { -+ case 0: -+ ap9x_wmac0_data.leds = leds; -+ ap9x_wmac0_data.num_leds = num_leds; -+ break; -+ case 1: -+ ap9x_wmac1_data.leds = leds; -+ ap9x_wmac1_data.num_leds = num_leds; -+ break; -+ } -+} -+ -+__init void ap9x_pci_setup_wmac_btns(unsigned wmac, -+ struct gpio_keys_button *btns, -+ unsigned num_btns, unsigned poll_interval) -+{ -+ struct ath9k_platform_data *ap9x_wmac_data; -+ -+ if (!(ap9x_wmac_data = ap9x_pci_get_wmac_data(wmac))) -+ return; -+ -+ ap9x_wmac_data->btns = btns; -+ ap9x_wmac_data->num_btns = num_btns; -+ ap9x_wmac_data->btn_poll_interval = poll_interval; -+} -+ -+static int ap91_pci_plat_dev_init(struct pci_dev *dev) -+{ -+ switch (PCI_SLOT(dev->devfn)) { -+ case 0: -+ dev->dev.platform_data = &ap9x_wmac0_data; -+ break; -+ } -+ -+ return 0; -+} -+ -+__init void ap91_pci_init(u8 *cal_data, u8 *mac_addr) -+{ -+ if (cal_data) -+ memcpy(ap9x_wmac0_data.eeprom_data, cal_data, -+ sizeof(ap9x_wmac0_data.eeprom_data)); -+ -+ if (mac_addr) { -+ memcpy(ap9x_wmac0_mac, mac_addr, sizeof(ap9x_wmac0_mac)); -+ ap9x_wmac0_data.macaddr = ap9x_wmac0_mac; -+ } -+ -+ ath79_pci_set_plat_dev_init(ap91_pci_plat_dev_init); -+ ath79_register_pci(); -+ -+ pci_enable_ath9k_fixup(0, ap9x_wmac0_data.eeprom_data); -+} -+ -+__init void ap91_pci_init_simple(void) -+{ -+ ap91_pci_init(NULL, NULL); -+ ap9x_wmac0_data.eeprom_name = "pci_wmac0.eeprom"; -+} -+ -+static int ap94_pci_plat_dev_init(struct pci_dev *dev) -+{ -+ switch (PCI_SLOT(dev->devfn)) { -+ case 17: -+ dev->dev.platform_data = &ap9x_wmac0_data; -+ break; -+ -+ case 18: -+ dev->dev.platform_data = &ap9x_wmac1_data; -+ break; -+ } -+ -+ return 0; -+} -+ -+__init void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, -+ u8 *cal_data1, u8 *mac_addr1) -+{ -+ if (cal_data0) -+ memcpy(ap9x_wmac0_data.eeprom_data, cal_data0, -+ sizeof(ap9x_wmac0_data.eeprom_data)); -+ -+ if (cal_data1) -+ memcpy(ap9x_wmac1_data.eeprom_data, cal_data1, -+ sizeof(ap9x_wmac1_data.eeprom_data)); -+ -+ if (mac_addr0) { -+ memcpy(ap9x_wmac0_mac, mac_addr0, sizeof(ap9x_wmac0_mac)); -+ ap9x_wmac0_data.macaddr = ap9x_wmac0_mac; -+ } -+ -+ if (mac_addr1) { -+ memcpy(ap9x_wmac1_mac, mac_addr1, sizeof(ap9x_wmac1_mac)); -+ ap9x_wmac1_data.macaddr = ap9x_wmac1_mac; -+ } -+ -+ ath79_pci_set_plat_dev_init(ap94_pci_plat_dev_init); -+ ath79_register_pci(); -+ -+ pci_enable_ath9k_fixup(17, ap9x_wmac0_data.eeprom_data); -+ pci_enable_ath9k_fixup(18, ap9x_wmac1_data.eeprom_data); -+} -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.h b/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.h -new file mode 100644 -index 0000000000..d2a045fc1c ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.h -@@ -0,0 +1,55 @@ -+/* -+ * Atheros AP9X reference board PCI initialization -+ * -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _ATH79_DEV_AP9X_PCI_H -+#define _ATH79_DEV_AP9X_PCI_H -+ -+struct gpio_led; -+struct gpio_keys_button; -+struct ath9k_platform_data; -+ -+#if defined(CONFIG_ATH79_DEV_AP9X_PCI) -+void ap9x_pci_setup_wmac_led_pin(unsigned wmac, int pin); -+void ap9x_pci_setup_wmac_gpio(unsigned wmac, u32 mask, u32 val); -+void ap9x_pci_setup_wmac_leds(unsigned wmac, struct gpio_led *leds, -+ int num_leds); -+void ap9x_pci_setup_wmac_btns(unsigned wmac, struct gpio_keys_button *btns, -+ unsigned num_btns, unsigned poll_interval); -+struct ath9k_platform_data *ap9x_pci_get_wmac_data(unsigned wmac); -+ -+void ap91_pci_init(u8 *cal_data, u8 *mac_addr); -+void ap91_pci_init_simple(void); -+void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, -+ u8 *cal_data1, u8 *mac_addr1); -+ -+#else -+static inline void ap9x_pci_setup_wmac_led_pin(unsigned wmac, int pin) {} -+static inline void ap9x_pci_setup_wmac_gpio(unsigned wmac, -+ u32 mask, u32 val) {} -+static inline void ap9x_pci_setup_wmac_leds(unsigned wmac, -+ struct gpio_led *leds, -+ int num_leds) {} -+static inline void ap9x_pci_setup_wmac_btns(unsigned wmac, -+ struct gpio_keys_button *btns, -+ unsigned num_btns, -+ unsigned poll_interval) {} -+static inline struct ath9k_platform_data *ap9x_pci_get_wmac_data(unsigned wmac) -+{ -+ return NULL; -+} -+ -+static inline void ap91_pci_init(u8 *cal_data, u8 *mac_addr) {} -+static inline void ap91_pci_init_simple(void) {} -+static inline void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, -+ u8 *cal_data1, u8 *mac_addr1) {} -+#endif -+ -+#endif /* _ATH79_DEV_AP9X_PCI_H */ -+ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-dsa.c b/target/linux/ar71xx/files/arch/mips/ath79/dev-dsa.c -new file mode 100644 -index 0000000000..4ade218f7e ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-dsa.c -@@ -0,0 +1,36 @@ -+/* -+ * Atheros AR71xx DSA switch device support -+ * -+ * Copyright (C) 2008-2012 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "dev-dsa.h" -+ -+static struct platform_device ar71xx_dsa_switch_device = { -+ .name = "dsa", -+ .id = 0, -+}; -+ -+void __init ath79_register_dsa(struct device *netdev, -+ struct device *miidev, -+ struct dsa_platform_data *d) -+{ -+ int i; -+ -+ d->netdev = netdev; -+ for (i = 0; i < d->nr_chips; i++) -+ d->chip[i].host_dev = miidev; -+ -+ ar71xx_dsa_switch_device.dev.platform_data = d; -+ platform_device_register(&ar71xx_dsa_switch_device); -+} -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-dsa.h b/target/linux/ar71xx/files/arch/mips/ath79/dev-dsa.h -new file mode 100644 -index 0000000000..3730202e8d ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-dsa.h -@@ -0,0 +1,21 @@ -+/* -+ * Atheros AR71xx DSA switch device support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _ATH79_DEV_DSA_H -+#define _ATH79_DEV_DSA_H -+ -+#include -+ -+void ath79_register_dsa(struct device *netdev, -+ struct device *miidev, -+ struct dsa_platform_data *d); -+ -+#endif /* _ATH79_DEV_DSA_H */ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c -new file mode 100644 -index 0000000000..1e230bce61 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c -@@ -0,0 +1,1262 @@ -+/* -+ * Atheros AR71xx SoC platform devices -+ * -+ * Copyright (C) 2010-2011 Jaiganesh Narayanan -+ * Copyright (C) 2008-2012 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Parts of this file are based on Atheros 2.6.15 BSP -+ * Parts of this file are based on Atheros 2.6.31 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+ -+unsigned char ath79_mac_base[ETH_ALEN] __initdata; -+ -+static struct resource ath79_mdio0_resources[] = { -+ { -+ .name = "mdio_base", -+ .flags = IORESOURCE_MEM, -+ .start = AR71XX_GE0_BASE, -+ .end = AR71XX_GE0_BASE + 0x200 - 1, -+ } -+}; -+ -+struct ag71xx_mdio_platform_data ath79_mdio0_data; -+ -+struct platform_device ath79_mdio0_device = { -+ .name = "ag71xx-mdio", -+ .id = 0, -+ .resource = ath79_mdio0_resources, -+ .num_resources = ARRAY_SIZE(ath79_mdio0_resources), -+ .dev = { -+ .platform_data = &ath79_mdio0_data, -+ }, -+}; -+ -+static struct resource ath79_mdio1_resources[] = { -+ { -+ .name = "mdio_base", -+ .flags = IORESOURCE_MEM, -+ .start = AR71XX_GE1_BASE, -+ .end = AR71XX_GE1_BASE + 0x200 - 1, -+ } -+}; -+ -+struct ag71xx_mdio_platform_data ath79_mdio1_data; -+ -+struct platform_device ath79_mdio1_device = { -+ .name = "ag71xx-mdio", -+ .id = 1, -+ .resource = ath79_mdio1_resources, -+ .num_resources = ARRAY_SIZE(ath79_mdio1_resources), -+ .dev = { -+ .platform_data = &ath79_mdio1_data, -+ }, -+}; -+ -+static void ath79_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift) -+{ -+ void __iomem *base; -+ u32 t; -+ -+ base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); -+ -+ t = __raw_readl(base + cfg_reg); -+ t &= ~(3 << shift); -+ t |= (2 << shift); -+ __raw_writel(t, base + cfg_reg); -+ udelay(100); -+ -+ __raw_writel(pll_val, base + pll_reg); -+ -+ t |= (3 << shift); -+ __raw_writel(t, base + cfg_reg); -+ udelay(100); -+ -+ t &= ~(3 << shift); -+ __raw_writel(t, base + cfg_reg); -+ udelay(100); -+ -+ printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n", -+ (unsigned int)(base + pll_reg), __raw_readl(base + pll_reg)); -+ -+ iounmap(base); -+} -+ -+static void __init ath79_mii_ctrl_set_if(unsigned int reg, -+ unsigned int mii_if) -+{ -+ void __iomem *base; -+ u32 t; -+ -+ base = ioremap(AR71XX_MII_BASE, AR71XX_MII_SIZE); -+ -+ t = __raw_readl(base + reg); -+ t &= ~(AR71XX_MII_CTRL_IF_MASK); -+ t |= (mii_if & AR71XX_MII_CTRL_IF_MASK); -+ __raw_writel(t, base + reg); -+ -+ iounmap(base); -+} -+ -+static void ath79_mii_ctrl_set_speed(unsigned int reg, unsigned int speed) -+{ -+ void __iomem *base; -+ unsigned int mii_speed; -+ u32 t; -+ -+ switch (speed) { -+ case SPEED_10: -+ mii_speed = AR71XX_MII_CTRL_SPEED_10; -+ break; -+ case SPEED_100: -+ mii_speed = AR71XX_MII_CTRL_SPEED_100; -+ break; -+ case SPEED_1000: -+ mii_speed = AR71XX_MII_CTRL_SPEED_1000; -+ break; -+ default: -+ BUG(); -+ } -+ -+ base = ioremap(AR71XX_MII_BASE, AR71XX_MII_SIZE); -+ -+ t = __raw_readl(base + reg); -+ t &= ~(AR71XX_MII_CTRL_SPEED_MASK << AR71XX_MII_CTRL_SPEED_SHIFT); -+ t |= mii_speed << AR71XX_MII_CTRL_SPEED_SHIFT; -+ __raw_writel(t, base + reg); -+ -+ iounmap(base); -+} -+ -+static unsigned long ar934x_get_mdio_ref_clock(void) -+{ -+ void __iomem *base; -+ unsigned long ret; -+ u32 t; -+ -+ base = ioremap(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); -+ -+ ret = 0; -+ t = __raw_readl(base + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG); -+ if (t & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL) { -+ ret = 100 * 1000 * 1000; -+ } else { -+ struct clk *clk; -+ -+ clk = clk_get(NULL, "ref"); -+ if (!IS_ERR(clk)) -+ ret = clk_get_rate(clk); -+ } -+ -+ iounmap(base); -+ -+ return ret; -+} -+ -+void __init ath79_register_mdio(unsigned int id, u32 phy_mask) -+{ -+ struct platform_device *mdio_dev; -+ struct ag71xx_mdio_platform_data *mdio_data; -+ unsigned int max_id; -+ -+ if (ath79_soc == ATH79_SOC_AR9341 || -+ ath79_soc == ATH79_SOC_AR9342 || -+ ath79_soc == ATH79_SOC_AR9344 || -+ ath79_soc == ATH79_SOC_QCA9556 || -+ ath79_soc == ATH79_SOC_QCA9558 || -+ ath79_soc == ATH79_SOC_QCA956X) -+ max_id = 1; -+ else -+ max_id = 0; -+ -+ if (id > max_id) { -+ printk(KERN_ERR "ar71xx: invalid MDIO id %u\n", id); -+ return; -+ } -+ -+ switch (ath79_soc) { -+ case ATH79_SOC_AR7241: -+ case ATH79_SOC_AR9330: -+ case ATH79_SOC_AR9331: -+ case ATH79_SOC_QCA9533: -+ case ATH79_SOC_TP9343: -+ mdio_dev = &ath79_mdio1_device; -+ mdio_data = &ath79_mdio1_data; -+ break; -+ -+ case ATH79_SOC_AR9341: -+ case ATH79_SOC_AR9342: -+ case ATH79_SOC_AR9344: -+ case ATH79_SOC_QCA9556: -+ case ATH79_SOC_QCA9558: -+ case ATH79_SOC_QCA956X: -+ if (id == 0) { -+ mdio_dev = &ath79_mdio0_device; -+ mdio_data = &ath79_mdio0_data; -+ } else { -+ mdio_dev = &ath79_mdio1_device; -+ mdio_data = &ath79_mdio1_data; -+ } -+ break; -+ -+ case ATH79_SOC_AR7242: -+ ath79_set_pll(AR71XX_PLL_REG_SEC_CONFIG, -+ AR7242_PLL_REG_ETH0_INT_CLOCK, 0x62000000, -+ AR71XX_ETH0_PLL_SHIFT); -+ /* fall through */ -+ default: -+ mdio_dev = &ath79_mdio0_device; -+ mdio_data = &ath79_mdio0_data; -+ break; -+ } -+ -+ mdio_data->phy_mask = phy_mask; -+ -+ switch (ath79_soc) { -+ case ATH79_SOC_AR7240: -+ mdio_data->is_ar7240 = 1; -+ /* fall through */ -+ case ATH79_SOC_AR7241: -+ mdio_data->builtin_switch = 1; -+ break; -+ -+ case ATH79_SOC_AR9330: -+ mdio_data->is_ar9330 = 1; -+ /* fall through */ -+ case ATH79_SOC_AR9331: -+ mdio_data->builtin_switch = 1; -+ break; -+ -+ case ATH79_SOC_AR9341: -+ case ATH79_SOC_AR9342: -+ case ATH79_SOC_AR9344: -+ if (id == 1) { -+ mdio_data->builtin_switch = 1; -+ mdio_data->ref_clock = ar934x_get_mdio_ref_clock(); -+ mdio_data->mdio_clock = 6250000; -+ } -+ mdio_data->is_ar934x = 1; -+ break; -+ -+ case ATH79_SOC_QCA9533: -+ case ATH79_SOC_TP9343: -+ mdio_data->builtin_switch = 1; -+ break; -+ -+ case ATH79_SOC_QCA9556: -+ case ATH79_SOC_QCA9558: -+ mdio_data->is_ar934x = 1; -+ break; -+ -+ case ATH79_SOC_QCA956X: -+ if (id == 1) -+ mdio_data->builtin_switch = 1; -+ mdio_data->is_ar934x = 1; -+ break; -+ -+ default: -+ break; -+ } -+ -+ platform_device_register(mdio_dev); -+} -+ -+struct ath79_eth_pll_data ath79_eth0_pll_data; -+struct ath79_eth_pll_data ath79_eth1_pll_data; -+ -+static u32 ath79_get_eth_pll(unsigned int mac, int speed) -+{ -+ struct ath79_eth_pll_data *pll_data; -+ u32 pll_val; -+ -+ switch (mac) { -+ case 0: -+ pll_data = &ath79_eth0_pll_data; -+ break; -+ case 1: -+ pll_data = &ath79_eth1_pll_data; -+ break; -+ default: -+ BUG(); -+ } -+ -+ switch (speed) { -+ case SPEED_10: -+ pll_val = pll_data->pll_10; -+ break; -+ case SPEED_100: -+ pll_val = pll_data->pll_100; -+ break; -+ case SPEED_1000: -+ pll_val = pll_data->pll_1000; -+ break; -+ default: -+ BUG(); -+ } -+ -+ return pll_val; -+} -+ -+static void ath79_set_speed_ge0(int speed) -+{ -+ u32 val = ath79_get_eth_pll(0, speed); -+ -+ ath79_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK, -+ val, AR71XX_ETH0_PLL_SHIFT); -+ ath79_mii_ctrl_set_speed(AR71XX_MII_REG_MII0_CTRL, speed); -+} -+ -+static void ath79_set_speed_ge1(int speed) -+{ -+ u32 val = ath79_get_eth_pll(1, speed); -+ -+ ath79_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK, -+ val, AR71XX_ETH1_PLL_SHIFT); -+ ath79_mii_ctrl_set_speed(AR71XX_MII_REG_MII1_CTRL, speed); -+} -+ -+static void ar7242_set_speed_ge0(int speed) -+{ -+ u32 val = ath79_get_eth_pll(0, speed); -+ void __iomem *base; -+ -+ base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); -+ __raw_writel(val, base + AR7242_PLL_REG_ETH0_INT_CLOCK); -+ iounmap(base); -+} -+ -+static void ar91xx_set_speed_ge0(int speed) -+{ -+ u32 val = ath79_get_eth_pll(0, speed); -+ -+ ath79_set_pll(AR913X_PLL_REG_ETH_CONFIG, AR913X_PLL_REG_ETH0_INT_CLOCK, -+ val, AR913X_ETH0_PLL_SHIFT); -+ ath79_mii_ctrl_set_speed(AR71XX_MII_REG_MII0_CTRL, speed); -+} -+ -+static void ar91xx_set_speed_ge1(int speed) -+{ -+ u32 val = ath79_get_eth_pll(1, speed); -+ -+ ath79_set_pll(AR913X_PLL_REG_ETH_CONFIG, AR913X_PLL_REG_ETH1_INT_CLOCK, -+ val, AR913X_ETH1_PLL_SHIFT); -+ ath79_mii_ctrl_set_speed(AR71XX_MII_REG_MII1_CTRL, speed); -+} -+ -+static void ar934x_set_speed_ge0(int speed) -+{ -+ void __iomem *base; -+ u32 val = ath79_get_eth_pll(0, speed); -+ -+ base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); -+ __raw_writel(val, base + AR934X_PLL_ETH_XMII_CONTROL_REG); -+ iounmap(base); -+} -+ -+static void qca955x_set_speed_xmii(int speed) -+{ -+ void __iomem *base; -+ u32 val = ath79_get_eth_pll(0, speed); -+ -+ base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); -+ __raw_writel(val, base + QCA955X_PLL_ETH_XMII_CONTROL_REG); -+ iounmap(base); -+} -+ -+static void qca955x_set_speed_sgmii(int id, int speed) -+{ -+ void __iomem *base; -+ u32 val = ath79_get_eth_pll(id, speed); -+ -+ base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); -+ __raw_writel(val, base + QCA955X_PLL_ETH_SGMII_CONTROL_REG); -+ iounmap(base); -+} -+ -+static void qca9556_set_speed_sgmii(int speed) -+{ -+ qca955x_set_speed_sgmii(0, speed); -+} -+ -+static void qca9558_set_speed_sgmii(int speed) -+{ -+ qca955x_set_speed_sgmii(1, speed); -+} -+ -+static void qca956x_set_speed_sgmii(int speed) -+{ -+ void __iomem *base; -+ u32 val = ath79_get_eth_pll(0, speed); -+ -+ base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); -+ __raw_writel(val, base + QCA955X_PLL_ETH_SGMII_CONTROL_REG); -+ iounmap(base); -+} -+ -+static void ath79_set_speed_dummy(int speed) -+{ -+} -+ -+static void ath79_ddr_flush_ge0(void) -+{ -+ ath79_ddr_wb_flush(0); -+} -+ -+static void ath79_ddr_flush_ge1(void) -+{ -+ ath79_ddr_wb_flush(1); -+} -+ -+static struct resource ath79_eth0_resources[] = { -+ { -+ .name = "mac_base", -+ .flags = IORESOURCE_MEM, -+ .start = AR71XX_GE0_BASE, -+ .end = AR71XX_GE0_BASE + 0x200 - 1, -+ }, { -+ .name = "mac_irq", -+ .flags = IORESOURCE_IRQ, -+ .start = ATH79_CPU_IRQ(4), -+ .end = ATH79_CPU_IRQ(4), -+ }, -+}; -+ -+struct ag71xx_platform_data ath79_eth0_data = { -+ .reset_bit = AR71XX_RESET_GE0_MAC, -+}; -+ -+struct platform_device ath79_eth0_device = { -+ .name = "ag71xx", -+ .id = 0, -+ .resource = ath79_eth0_resources, -+ .num_resources = ARRAY_SIZE(ath79_eth0_resources), -+ .dev = { -+ .platform_data = &ath79_eth0_data, -+ }, -+}; -+ -+static struct resource ath79_eth1_resources[] = { -+ { -+ .name = "mac_base", -+ .flags = IORESOURCE_MEM, -+ .start = AR71XX_GE1_BASE, -+ .end = AR71XX_GE1_BASE + 0x200 - 1, -+ }, { -+ .name = "mac_irq", -+ .flags = IORESOURCE_IRQ, -+ .start = ATH79_CPU_IRQ(5), -+ .end = ATH79_CPU_IRQ(5), -+ }, -+}; -+ -+struct ag71xx_platform_data ath79_eth1_data = { -+ .reset_bit = AR71XX_RESET_GE1_MAC, -+}; -+ -+struct platform_device ath79_eth1_device = { -+ .name = "ag71xx", -+ .id = 1, -+ .resource = ath79_eth1_resources, -+ .num_resources = ARRAY_SIZE(ath79_eth1_resources), -+ .dev = { -+ .platform_data = &ath79_eth1_data, -+ }, -+}; -+ -+struct ag71xx_switch_platform_data ath79_switch_data; -+ -+#define AR71XX_PLL_VAL_1000 0x00110000 -+#define AR71XX_PLL_VAL_100 0x00001099 -+#define AR71XX_PLL_VAL_10 0x00991099 -+ -+#define AR724X_PLL_VAL_1000 0x00110000 -+#define AR724X_PLL_VAL_100 0x00001099 -+#define AR724X_PLL_VAL_10 0x00991099 -+ -+#define AR7242_PLL_VAL_1000 0x16000000 -+#define AR7242_PLL_VAL_100 0x00000101 -+#define AR7242_PLL_VAL_10 0x00001616 -+ -+#define AR913X_PLL_VAL_1000 0x1a000000 -+#define AR913X_PLL_VAL_100 0x13000a44 -+#define AR913X_PLL_VAL_10 0x00441099 -+ -+#define AR933X_PLL_VAL_1000 0x00110000 -+#define AR933X_PLL_VAL_100 0x00001099 -+#define AR933X_PLL_VAL_10 0x00991099 -+ -+#define AR934X_PLL_VAL_1000 0x16000000 -+#define AR934X_PLL_VAL_100 0x00000101 -+#define AR934X_PLL_VAL_10 0x00001616 -+ -+#define QCA956X_PLL_VAL_1000 0x03000000 -+#define QCA956X_PLL_VAL_100 0x00000101 -+#define QCA956X_PLL_VAL_10 0x00001919 -+ -+static void __init ath79_init_eth_pll_data(unsigned int id) -+{ -+ struct ath79_eth_pll_data *pll_data; -+ u32 pll_10, pll_100, pll_1000; -+ -+ switch (id) { -+ case 0: -+ pll_data = &ath79_eth0_pll_data; -+ break; -+ case 1: -+ pll_data = &ath79_eth1_pll_data; -+ break; -+ default: -+ BUG(); -+ } -+ -+ switch (ath79_soc) { -+ case ATH79_SOC_AR7130: -+ case ATH79_SOC_AR7141: -+ case ATH79_SOC_AR7161: -+ pll_10 = AR71XX_PLL_VAL_10; -+ pll_100 = AR71XX_PLL_VAL_100; -+ pll_1000 = AR71XX_PLL_VAL_1000; -+ break; -+ -+ case ATH79_SOC_AR7240: -+ case ATH79_SOC_AR7241: -+ pll_10 = AR724X_PLL_VAL_10; -+ pll_100 = AR724X_PLL_VAL_100; -+ pll_1000 = AR724X_PLL_VAL_1000; -+ break; -+ -+ case ATH79_SOC_AR7242: -+ pll_10 = AR7242_PLL_VAL_10; -+ pll_100 = AR7242_PLL_VAL_100; -+ pll_1000 = AR7242_PLL_VAL_1000; -+ break; -+ -+ case ATH79_SOC_AR9130: -+ case ATH79_SOC_AR9132: -+ pll_10 = AR913X_PLL_VAL_10; -+ pll_100 = AR913X_PLL_VAL_100; -+ pll_1000 = AR913X_PLL_VAL_1000; -+ break; -+ -+ case ATH79_SOC_AR9330: -+ case ATH79_SOC_AR9331: -+ pll_10 = AR933X_PLL_VAL_10; -+ pll_100 = AR933X_PLL_VAL_100; -+ pll_1000 = AR933X_PLL_VAL_1000; -+ break; -+ -+ case ATH79_SOC_AR9341: -+ case ATH79_SOC_AR9342: -+ case ATH79_SOC_AR9344: -+ case ATH79_SOC_QCA9533: -+ case ATH79_SOC_QCA9556: -+ case ATH79_SOC_QCA9558: -+ case ATH79_SOC_TP9343: -+ pll_10 = AR934X_PLL_VAL_10; -+ pll_100 = AR934X_PLL_VAL_100; -+ pll_1000 = AR934X_PLL_VAL_1000; -+ break; -+ -+ case ATH79_SOC_QCA956X: -+ pll_10 = QCA956X_PLL_VAL_10; -+ pll_100 = QCA956X_PLL_VAL_100; -+ pll_1000 = QCA956X_PLL_VAL_1000; -+ break; -+ -+ default: -+ BUG(); -+ } -+ -+ if (!pll_data->pll_10) -+ pll_data->pll_10 = pll_10; -+ -+ if (!pll_data->pll_100) -+ pll_data->pll_100 = pll_100; -+ -+ if (!pll_data->pll_1000) -+ pll_data->pll_1000 = pll_1000; -+} -+ -+static int __init ath79_setup_phy_if_mode(unsigned int id, -+ struct ag71xx_platform_data *pdata) -+{ -+ unsigned int mii_if; -+ -+ switch (id) { -+ case 0: -+ switch (ath79_soc) { -+ case ATH79_SOC_AR7130: -+ case ATH79_SOC_AR7141: -+ case ATH79_SOC_AR7161: -+ case ATH79_SOC_AR9130: -+ case ATH79_SOC_AR9132: -+ switch (pdata->phy_if_mode) { -+ case PHY_INTERFACE_MODE_MII: -+ mii_if = AR71XX_MII0_CTRL_IF_MII; -+ break; -+ case PHY_INTERFACE_MODE_GMII: -+ mii_if = AR71XX_MII0_CTRL_IF_GMII; -+ break; -+ case PHY_INTERFACE_MODE_RGMII: -+ mii_if = AR71XX_MII0_CTRL_IF_RGMII; -+ break; -+ case PHY_INTERFACE_MODE_RMII: -+ mii_if = AR71XX_MII0_CTRL_IF_RMII; -+ break; -+ default: -+ return -EINVAL; -+ } -+ ath79_mii_ctrl_set_if(AR71XX_MII_REG_MII0_CTRL, mii_if); -+ break; -+ -+ case ATH79_SOC_AR7240: -+ case ATH79_SOC_AR7241: -+ case ATH79_SOC_AR9330: -+ case ATH79_SOC_AR9331: -+ case ATH79_SOC_QCA9533: -+ case ATH79_SOC_TP9343: -+ pdata->phy_if_mode = PHY_INTERFACE_MODE_MII; -+ break; -+ -+ case ATH79_SOC_AR7242: -+ /* FIXME */ -+ -+ case ATH79_SOC_AR9341: -+ case ATH79_SOC_AR9342: -+ case ATH79_SOC_AR9344: -+ switch (pdata->phy_if_mode) { -+ case PHY_INTERFACE_MODE_MII: -+ case PHY_INTERFACE_MODE_GMII: -+ case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_RMII: -+ break; -+ default: -+ return -EINVAL; -+ } -+ break; -+ -+ case ATH79_SOC_QCA9556: -+ case ATH79_SOC_QCA9558: -+ case ATH79_SOC_QCA956X: -+ switch (pdata->phy_if_mode) { -+ case PHY_INTERFACE_MODE_MII: -+ case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_SGMII: -+ break; -+ default: -+ return -EINVAL; -+ } -+ break; -+ -+ default: -+ BUG(); -+ } -+ break; -+ case 1: -+ switch (ath79_soc) { -+ case ATH79_SOC_AR7130: -+ case ATH79_SOC_AR7141: -+ case ATH79_SOC_AR7161: -+ case ATH79_SOC_AR9130: -+ case ATH79_SOC_AR9132: -+ switch (pdata->phy_if_mode) { -+ case PHY_INTERFACE_MODE_RMII: -+ mii_if = AR71XX_MII1_CTRL_IF_RMII; -+ break; -+ case PHY_INTERFACE_MODE_RGMII: -+ mii_if = AR71XX_MII1_CTRL_IF_RGMII; -+ break; -+ default: -+ return -EINVAL; -+ } -+ ath79_mii_ctrl_set_if(AR71XX_MII_REG_MII1_CTRL, mii_if); -+ break; -+ -+ case ATH79_SOC_AR7240: -+ case ATH79_SOC_AR7241: -+ case ATH79_SOC_AR9330: -+ case ATH79_SOC_AR9331: -+ case ATH79_SOC_TP9343: -+ pdata->phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ break; -+ -+ case ATH79_SOC_AR7242: -+ /* FIXME */ -+ -+ case ATH79_SOC_AR9341: -+ case ATH79_SOC_AR9342: -+ case ATH79_SOC_AR9344: -+ case ATH79_SOC_QCA9533: -+ case ATH79_SOC_QCA956X: -+ switch (pdata->phy_if_mode) { -+ case PHY_INTERFACE_MODE_MII: -+ case PHY_INTERFACE_MODE_GMII: -+ break; -+ default: -+ return -EINVAL; -+ } -+ break; -+ -+ case ATH79_SOC_QCA9556: -+ case ATH79_SOC_QCA9558: -+ switch (pdata->phy_if_mode) { -+ case PHY_INTERFACE_MODE_MII: -+ case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_SGMII: -+ break; -+ default: -+ return -EINVAL; -+ } -+ break; -+ -+ default: -+ BUG(); -+ } -+ break; -+ } -+ -+ return 0; -+} -+ -+void __init ath79_setup_ar933x_phy4_switch(bool mac, bool mdio) -+{ -+ void __iomem *base; -+ u32 t; -+ -+ base = ioremap(AR933X_GMAC_BASE, AR933X_GMAC_SIZE); -+ -+ t = __raw_readl(base + AR933X_GMAC_REG_ETH_CFG); -+ t &= ~(AR933X_ETH_CFG_SW_PHY_SWAP | AR933X_ETH_CFG_SW_PHY_ADDR_SWAP); -+ if (mac) -+ t |= AR933X_ETH_CFG_SW_PHY_SWAP; -+ if (mdio) -+ t |= AR933X_ETH_CFG_SW_PHY_ADDR_SWAP; -+ __raw_writel(t, base + AR933X_GMAC_REG_ETH_CFG); -+ -+ iounmap(base); -+} -+ -+void __init ath79_setup_ar934x_eth_cfg(u32 mask) -+{ -+ void __iomem *base; -+ u32 t; -+ -+ base = ioremap(AR934X_GMAC_BASE, AR934X_GMAC_SIZE); -+ -+ t = __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); -+ -+ t &= ~(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_MII_GMAC0 | -+ AR934X_ETH_CFG_GMII_GMAC0 | -+ AR934X_ETH_CFG_SW_ONLY_MODE | -+ AR934X_ETH_CFG_SW_PHY_SWAP); -+ -+ t |= mask; -+ -+ __raw_writel(t, base + AR934X_GMAC_REG_ETH_CFG); -+ /* flush write */ -+ __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); -+ -+ iounmap(base); -+} -+ -+void __init ath79_setup_ar934x_eth_rx_delay(unsigned int rxd, -+ unsigned int rxdv) -+{ -+ void __iomem *base; -+ u32 t; -+ -+ rxd &= AR934X_ETH_CFG_RXD_DELAY_MASK; -+ rxdv &= AR934X_ETH_CFG_RDV_DELAY_MASK; -+ -+ base = ioremap(AR934X_GMAC_BASE, AR934X_GMAC_SIZE); -+ -+ t = __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); -+ -+ t &= ~(AR934X_ETH_CFG_RXD_DELAY_MASK << AR934X_ETH_CFG_RXD_DELAY_SHIFT | -+ AR934X_ETH_CFG_RDV_DELAY_MASK << AR934X_ETH_CFG_RDV_DELAY_SHIFT); -+ -+ t |= (rxd << AR934X_ETH_CFG_RXD_DELAY_SHIFT | -+ rxdv << AR934X_ETH_CFG_RDV_DELAY_SHIFT); -+ -+ __raw_writel(t, base + AR934X_GMAC_REG_ETH_CFG); -+ /* flush write */ -+ __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); -+ -+ iounmap(base); -+} -+ -+void __init ath79_setup_qca955x_eth_cfg(u32 mask) -+{ -+ void __iomem *base; -+ u32 t; -+ -+ base = ioremap(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE); -+ -+ t = __raw_readl(base + QCA955X_GMAC_REG_ETH_CFG); -+ -+ t &= ~(QCA955X_ETH_CFG_RGMII_EN | QCA955X_ETH_CFG_GE0_SGMII); -+ -+ t |= mask; -+ -+ __raw_writel(t, base + QCA955X_GMAC_REG_ETH_CFG); -+ -+ iounmap(base); -+} -+ -+void __init ath79_setup_qca956x_eth_cfg(u32 mask) -+{ -+ void __iomem *base; -+ u32 t; -+ -+ base = ioremap(QCA956X_GMAC_BASE, QCA956X_GMAC_SIZE); -+ -+ t = __raw_readl(base + QCA956X_GMAC_REG_ETH_CFG); -+ -+ t &= ~(QCA956X_ETH_CFG_SW_ONLY_MODE | -+ QCA956X_ETH_CFG_SW_PHY_SWAP); -+ -+ t |= mask; -+ -+ __raw_writel(t, base + QCA956X_GMAC_REG_ETH_CFG); -+ /* flush write */ -+ __raw_readl(base + QCA956X_GMAC_REG_ETH_CFG); -+ -+ iounmap(base); -+} -+ -+static int ath79_eth_instance __initdata; -+void __init ath79_register_eth(unsigned int id) -+{ -+ struct platform_device *pdev; -+ struct ag71xx_platform_data *pdata; -+ int err; -+ -+ if (id > 1) { -+ printk(KERN_ERR "ar71xx: invalid ethernet id %d\n", id); -+ return; -+ } -+ -+ ath79_init_eth_pll_data(id); -+ -+ if (id == 0) -+ pdev = &ath79_eth0_device; -+ else -+ pdev = &ath79_eth1_device; -+ -+ pdata = pdev->dev.platform_data; -+ -+ pdata->max_frame_len = 1540; -+ pdata->desc_pktlen_mask = 0xfff; -+ -+ err = ath79_setup_phy_if_mode(id, pdata); -+ if (err) { -+ printk(KERN_ERR -+ "ar71xx: invalid PHY interface mode for GE%u\n", id); -+ return; -+ } -+ -+ if (id == 0) -+ pdata->ddr_flush = ath79_ddr_flush_ge0; -+ else -+ pdata->ddr_flush = ath79_ddr_flush_ge1; -+ -+ switch (ath79_soc) { -+ case ATH79_SOC_AR7130: -+ if (id == 0) -+ pdata->set_speed = ath79_set_speed_ge0; -+ else -+ pdata->set_speed = ath79_set_speed_ge1; -+ break; -+ -+ case ATH79_SOC_AR7141: -+ case ATH79_SOC_AR7161: -+ if (id == 0) -+ pdata->set_speed = ath79_set_speed_ge0; -+ else -+ pdata->set_speed = ath79_set_speed_ge1; -+ pdata->has_gbit = 1; -+ break; -+ -+ case ATH79_SOC_AR7242: -+ if (id == 0) { -+ pdata->reset_bit |= AR724X_RESET_GE0_MDIO | -+ AR71XX_RESET_GE0_PHY; -+ pdata->set_speed = ar7242_set_speed_ge0; -+ } else { -+ pdata->reset_bit |= AR724X_RESET_GE1_MDIO | -+ AR71XX_RESET_GE1_PHY; -+ pdata->set_speed = ath79_set_speed_dummy; -+ } -+ pdata->has_gbit = 1; -+ pdata->is_ar724x = 1; -+ break; -+ -+ case ATH79_SOC_AR7241: -+ if (id == 0) -+ pdata->reset_bit |= AR724X_RESET_GE0_MDIO; -+ else -+ pdata->reset_bit |= AR724X_RESET_GE1_MDIO; -+ /* fall through */ -+ case ATH79_SOC_AR7240: -+ if (id == 0) { -+ pdata->reset_bit |= AR71XX_RESET_GE0_PHY; -+ pdata->set_speed = ath79_set_speed_dummy; -+ -+ pdata->phy_mask = BIT(4); -+ } else { -+ pdata->reset_bit |= AR71XX_RESET_GE1_PHY; -+ pdata->set_speed = ath79_set_speed_dummy; -+ -+ pdata->speed = SPEED_1000; -+ pdata->duplex = DUPLEX_FULL; -+ pdata->switch_data = &ath79_switch_data; -+ pdata->use_flow_control = 1; -+ -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ } -+ pdata->has_gbit = 1; -+ pdata->is_ar724x = 1; -+ if (ath79_soc == ATH79_SOC_AR7240) -+ pdata->is_ar7240 = 1; -+ break; -+ -+ case ATH79_SOC_AR9132: -+ pdata->has_gbit = 1; -+ /* fall through */ -+ case ATH79_SOC_AR9130: -+ if (id == 0) -+ pdata->set_speed = ar91xx_set_speed_ge0; -+ else -+ pdata->set_speed = ar91xx_set_speed_ge1; -+ pdata->is_ar91xx = 1; -+ break; -+ -+ case ATH79_SOC_AR9330: -+ case ATH79_SOC_AR9331: -+ if (id == 0) { -+ pdata->reset_bit = AR933X_RESET_GE0_MAC | -+ AR933X_RESET_GE0_MDIO; -+ pdata->set_speed = ath79_set_speed_dummy; -+ -+ pdata->phy_mask = BIT(4); -+ } else { -+ pdata->reset_bit = AR933X_RESET_GE1_MAC | -+ AR933X_RESET_GE1_MDIO; -+ pdata->set_speed = ath79_set_speed_dummy; -+ -+ pdata->speed = SPEED_1000; -+ pdata->has_gbit = 1; -+ pdata->duplex = DUPLEX_FULL; -+ pdata->switch_data = &ath79_switch_data; -+ pdata->use_flow_control = 1; -+ -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ } -+ -+ pdata->is_ar724x = 1; -+ break; -+ -+ case ATH79_SOC_AR9341: -+ case ATH79_SOC_AR9342: -+ case ATH79_SOC_AR9344: -+ case ATH79_SOC_QCA9533: -+ if (id == 0) { -+ pdata->reset_bit = AR934X_RESET_GE0_MAC | -+ AR934X_RESET_GE0_MDIO; -+ pdata->set_speed = ar934x_set_speed_ge0; -+ -+ if (ath79_soc == ATH79_SOC_QCA9533) -+ pdata->disable_inline_checksum_engine = 1; -+ } else { -+ pdata->reset_bit = AR934X_RESET_GE1_MAC | -+ AR934X_RESET_GE1_MDIO; -+ pdata->set_speed = ath79_set_speed_dummy; -+ -+ pdata->switch_data = &ath79_switch_data; -+ -+ /* reset the built-in switch */ -+ ath79_device_reset_set(AR934X_RESET_ETH_SWITCH); -+ ath79_device_reset_clear(AR934X_RESET_ETH_SWITCH); -+ } -+ -+ pdata->has_gbit = 1; -+ pdata->is_ar724x = 1; -+ -+ pdata->max_frame_len = SZ_16K - 1; -+ pdata->desc_pktlen_mask = SZ_16K - 1; -+ break; -+ -+ case ATH79_SOC_TP9343: -+ if (id == 0) { -+ pdata->reset_bit = AR933X_RESET_GE0_MAC | -+ AR933X_RESET_GE0_MDIO; -+ pdata->set_speed = ath79_set_speed_dummy; -+ -+ if (!pdata->phy_mask) -+ pdata->phy_mask = BIT(4); -+ } else { -+ pdata->reset_bit = AR933X_RESET_GE1_MAC | -+ AR933X_RESET_GE1_MDIO; -+ pdata->set_speed = ath79_set_speed_dummy; -+ -+ pdata->speed = SPEED_1000; -+ pdata->duplex = DUPLEX_FULL; -+ pdata->switch_data = &ath79_switch_data; -+ pdata->use_flow_control = 1; -+ -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ } -+ -+ pdata->has_gbit = 1; -+ pdata->is_ar724x = 1; -+ break; -+ -+ case ATH79_SOC_QCA9556: -+ case ATH79_SOC_QCA9558: -+ if (id == 0) { -+ pdata->reset_bit = QCA955X_RESET_GE0_MAC | -+ QCA955X_RESET_GE0_MDIO; -+ pdata->set_speed = qca955x_set_speed_xmii; -+ -+ /* QCA9556 only has SGMII interface */ -+ if (ath79_soc == ATH79_SOC_QCA9556) -+ pdata->set_speed = qca9556_set_speed_sgmii; -+ } else { -+ pdata->reset_bit = QCA955X_RESET_GE1_MAC | -+ QCA955X_RESET_GE1_MDIO; -+ pdata->set_speed = qca9558_set_speed_sgmii; -+ } -+ -+ pdata->has_gbit = 1; -+ pdata->is_ar724x = 1; -+ -+ /* -+ * Limit the maximum frame length to 4095 bytes. -+ * Although the documentation says that the hardware -+ * limit is 16383 bytes but that does not work in -+ * practice. It seems that the hardware only updates -+ * the lowest 12 bits of the packet length field -+ * in the RX descriptor. -+ */ -+ pdata->max_frame_len = SZ_4K - 1; -+ pdata->desc_pktlen_mask = SZ_16K - 1; -+ break; -+ -+ case ATH79_SOC_QCA956X: -+ if (id == 0) { -+ pdata->reset_bit = QCA955X_RESET_GE0_MAC | -+ QCA955X_RESET_GE0_MDIO; -+ -+ if (pdata->phy_if_mode == PHY_INTERFACE_MODE_SGMII) -+ pdata->set_speed = qca956x_set_speed_sgmii; -+ else -+ pdata->set_speed = ar934x_set_speed_ge0; -+ -+ pdata->disable_inline_checksum_engine = 1; -+ } else { -+ pdata->reset_bit = QCA955X_RESET_GE1_MAC | -+ QCA955X_RESET_GE1_MDIO; -+ -+ pdata->set_speed = ath79_set_speed_dummy; -+ -+ pdata->switch_data = &ath79_switch_data; -+ -+ pdata->speed = SPEED_1000; -+ pdata->duplex = DUPLEX_FULL; -+ pdata->use_flow_control = 1; -+ -+ /* reset the built-in switch */ -+ ath79_device_reset_set(AR934X_RESET_ETH_SWITCH); -+ ath79_device_reset_clear(AR934X_RESET_ETH_SWITCH); -+ } -+ -+ pdata->has_gbit = 1; -+ pdata->is_ar724x = 1; -+ break; -+ -+ default: -+ BUG(); -+ } -+ -+ switch (pdata->phy_if_mode) { -+ case PHY_INTERFACE_MODE_GMII: -+ case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_SGMII: -+ if (!pdata->has_gbit) { -+ printk(KERN_ERR "ar71xx: no gbit available on eth%d\n", -+ id); -+ return; -+ } -+ /* fallthrough */ -+ default: -+ break; -+ } -+ -+ if (!is_valid_ether_addr(pdata->mac_addr)) { -+ random_ether_addr(pdata->mac_addr); -+ printk(KERN_DEBUG -+ "ar71xx: using random MAC address for eth%d\n", -+ ath79_eth_instance); -+ } -+ -+ if (pdata->mii_bus_dev == NULL) { -+ switch (ath79_soc) { -+ case ATH79_SOC_AR9341: -+ case ATH79_SOC_AR9342: -+ case ATH79_SOC_AR9344: -+ if (id == 0) -+ pdata->mii_bus_dev = &ath79_mdio0_device.dev; -+ else -+ pdata->mii_bus_dev = &ath79_mdio1_device.dev; -+ break; -+ -+ case ATH79_SOC_AR7241: -+ case ATH79_SOC_AR9330: -+ case ATH79_SOC_AR9331: -+ case ATH79_SOC_QCA9533: -+ case ATH79_SOC_TP9343: -+ pdata->mii_bus_dev = &ath79_mdio1_device.dev; -+ break; -+ -+ case ATH79_SOC_QCA9556: -+ case ATH79_SOC_QCA9558: -+ /* don't assign any MDIO device by default */ -+ break; -+ -+ case ATH79_SOC_QCA956X: -+ if (pdata->phy_if_mode != PHY_INTERFACE_MODE_SGMII) -+ pdata->mii_bus_dev = &ath79_mdio1_device.dev; -+ break; -+ -+ default: -+ pdata->mii_bus_dev = &ath79_mdio0_device.dev; -+ break; -+ } -+ } -+ -+ /* Reset the device */ -+ ath79_device_reset_set(pdata->reset_bit); -+ msleep(100); -+ -+ ath79_device_reset_clear(pdata->reset_bit); -+ msleep(100); -+ -+ platform_device_register(pdev); -+ ath79_eth_instance++; -+} -+ -+void __init ath79_set_mac_base(unsigned char *mac) -+{ -+ memcpy(ath79_mac_base, mac, ETH_ALEN); -+} -+ -+void __init ath79_parse_ascii_mac(char *mac_str, u8 *mac) -+{ -+ int t; -+ -+ t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", -+ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); -+ -+ if (t != ETH_ALEN) -+ t = sscanf(mac_str, "%02hhx.%02hhx.%02hhx.%02hhx.%02hhx.%02hhx", -+ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); -+ -+ if (t != ETH_ALEN || !is_valid_ether_addr(mac)) { -+ memset(mac, 0, ETH_ALEN); -+ printk(KERN_DEBUG "ar71xx: invalid mac address \"%s\"\n", -+ mac_str); -+ } -+} -+ -+void __init ath79_extract_mac_reverse(u8 *ptr, u8 *out) -+{ -+ int i; -+ -+ for (i = 0; i < ETH_ALEN; i++) { -+ out[i] = ptr[ETH_ALEN-i-1]; -+ } -+} -+ -+static void __init ath79_set_mac_base_ascii(char *str) -+{ -+ u8 mac[ETH_ALEN]; -+ -+ ath79_parse_ascii_mac(str, mac); -+ ath79_set_mac_base(mac); -+} -+ -+static int __init ath79_ethaddr_setup(char *str) -+{ -+ ath79_set_mac_base_ascii(str); -+ return 1; -+} -+__setup("ethaddr=", ath79_ethaddr_setup); -+ -+static int __init ath79_kmac_setup(char *str) -+{ -+ ath79_set_mac_base_ascii(str); -+ return 1; -+} -+__setup("kmac=", ath79_kmac_setup); -+ -+void __init ath79_init_mac(unsigned char *dst, const unsigned char *src, -+ int offset) -+{ -+ int t; -+ -+ if (!dst) -+ return; -+ -+ if (!src || !is_valid_ether_addr(src)) { -+ memset(dst, '\0', ETH_ALEN); -+ return; -+ } -+ -+ t = (((u32) src[3]) << 16) + (((u32) src[4]) << 8) + ((u32) src[5]); -+ t += offset; -+ -+ dst[0] = src[0]; -+ dst[1] = src[1]; -+ dst[2] = src[2]; -+ dst[3] = (t >> 16) & 0xff; -+ dst[4] = (t >> 8) & 0xff; -+ dst[5] = t & 0xff; -+} -+ -+void __init ath79_init_local_mac(unsigned char *dst, const unsigned char *src) -+{ -+ int i; -+ -+ if (!dst) -+ return; -+ -+ if (!src || !is_valid_ether_addr(src)) { -+ memset(dst, '\0', ETH_ALEN); -+ return; -+ } -+ -+ for (i = 0; i < ETH_ALEN; i++) -+ dst[i] = src[i]; -+ dst[0] |= 0x02; -+} -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.h b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.h -new file mode 100644 -index 0000000000..4d78260fbe ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.h -@@ -0,0 +1,55 @@ -+/* -+ * Atheros AR71xx SoC device definitions -+ * -+ * Copyright (C) 2008-2012 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _ATH79_DEV_ETH_H -+#define _ATH79_DEV_ETH_H -+ -+#include -+ -+struct platform_device; -+ -+extern unsigned char ath79_mac_base[] __initdata; -+void ath79_parse_ascii_mac(char *mac_str, u8 *mac); -+void ath79_extract_mac_reverse(u8 *ptr, u8 *out); -+void ath79_init_mac(unsigned char *dst, const unsigned char *src, -+ int offset); -+void ath79_init_local_mac(unsigned char *dst, const unsigned char *src); -+ -+struct ath79_eth_pll_data { -+ u32 pll_10; -+ u32 pll_100; -+ u32 pll_1000; -+}; -+ -+extern struct ath79_eth_pll_data ath79_eth0_pll_data; -+extern struct ath79_eth_pll_data ath79_eth1_pll_data; -+ -+extern struct ag71xx_platform_data ath79_eth0_data; -+extern struct ag71xx_platform_data ath79_eth1_data; -+extern struct platform_device ath79_eth0_device; -+extern struct platform_device ath79_eth1_device; -+void ath79_register_eth(unsigned int id); -+ -+extern struct ag71xx_switch_platform_data ath79_switch_data; -+ -+extern struct ag71xx_mdio_platform_data ath79_mdio0_data; -+extern struct ag71xx_mdio_platform_data ath79_mdio1_data; -+extern struct platform_device ath79_mdio0_device; -+extern struct platform_device ath79_mdio1_device; -+void ath79_register_mdio(unsigned int id, u32 phy_mask); -+ -+void ath79_setup_ar933x_phy4_switch(bool mac, bool mdio); -+void ath79_setup_ar934x_eth_cfg(u32 mask); -+void ath79_setup_ar934x_eth_rx_delay(unsigned int rxd, unsigned int rxdv); -+void ath79_setup_qca955x_eth_cfg(u32 mask); -+void ath79_setup_qca956x_eth_cfg(u32 mask); -+ -+#endif /* _ATH79_DEV_ETH_H */ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c b/target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c -new file mode 100644 -index 0000000000..e53d97dcbf ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c -@@ -0,0 +1,101 @@ -+/* -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dev-spi.h" -+#include "dev-m25p80.h" -+ -+static struct spi_board_info ath79_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ }, -+ { -+ .bus_num = 0, -+ .chip_select = 1, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ } -+}; -+ -+static struct ath79_spi_platform_data ath79_spi_data; -+ -+void __init ath79_register_m25p80(struct flash_platform_data *pdata) -+{ -+ ath79_spi_data.bus_num = 0; -+ ath79_spi_data.num_chipselect = 1; -+ ath79_spi_info[0].platform_data = pdata; -+ ath79_register_spi(&ath79_spi_data, ath79_spi_info, 1); -+} -+ -+static struct flash_platform_data *multi_pdata; -+ -+static struct mtd_info *concat_devs[2] = { NULL, NULL }; -+static struct work_struct mtd_concat_work; -+ -+static void mtd_concat_add_work(struct work_struct *work) -+{ -+ struct mtd_info *mtd; -+ -+ mtd = mtd_concat_create(concat_devs, ARRAY_SIZE(concat_devs), "flash"); -+ -+ mtd_device_register(mtd, multi_pdata->parts, multi_pdata->nr_parts); -+} -+ -+static void mtd_concat_add(struct mtd_info *mtd) -+{ -+ static bool registered = false; -+ -+ if (registered) -+ return; -+ -+ if (!strcmp(mtd->name, "spi0.0")) -+ concat_devs[0] = mtd; -+ else if (!strcmp(mtd->name, "spi0.1")) -+ concat_devs[1] = mtd; -+ else -+ return; -+ -+ if (!concat_devs[0] || !concat_devs[1]) -+ return; -+ -+ registered = true; -+ INIT_WORK(&mtd_concat_work, mtd_concat_add_work); -+ schedule_work(&mtd_concat_work); -+} -+ -+static void mtd_concat_remove(struct mtd_info *mtd) -+{ -+} -+ -+static void add_mtd_concat_notifier(void) -+{ -+ static struct mtd_notifier not = { -+ .add = mtd_concat_add, -+ .remove = mtd_concat_remove, -+ }; -+ -+ register_mtd_user(¬); -+} -+ -+void __init ath79_register_m25p80_multi(struct flash_platform_data *pdata) -+{ -+ multi_pdata = pdata; -+ add_mtd_concat_notifier(); -+ ath79_spi_data.bus_num = 0; -+ ath79_spi_data.num_chipselect = 2; -+ ath79_register_spi(&ath79_spi_data, ath79_spi_info, 2); -+} -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.h b/target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.h -new file mode 100644 -index 0000000000..637b41a7d8 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.h -@@ -0,0 +1,17 @@ -+/* -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _ATH79_DEV_M25P80_H -+#define _ATH79_DEV_M25P80_H -+ -+#include -+ -+void ath79_register_m25p80(struct flash_platform_data *pdata) __init; -+void ath79_register_m25p80_multi(struct flash_platform_data *pdata) __init; -+ -+#endif /* _ATH79_DEV_M25P80_H */ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.c b/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.c -new file mode 100644 -index 0000000000..9b5256ecc2 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.c -@@ -0,0 +1,141 @@ -+/* -+ * Atheros AR934X SoCs built-in NAND flash controller support -+ * -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "dev-nfc.h" -+ -+static struct resource ath79_nfc_resources[2]; -+static u64 ar934x_nfc_dmamask = DMA_BIT_MASK(32); -+static struct ar934x_nfc_platform_data ath79_nfc_data; -+ -+static struct platform_device ath79_nfc_device = { -+ .name = AR934X_NFC_DRIVER_NAME, -+ .id = -1, -+ .resource = ath79_nfc_resources, -+ .num_resources = ARRAY_SIZE(ath79_nfc_resources), -+ .dev = { -+ .dma_mask = &ar934x_nfc_dmamask, -+ .coherent_dma_mask = DMA_BIT_MASK(32), -+ .platform_data = &ath79_nfc_data, -+ }, -+}; -+ -+static void __init ath79_nfc_init_resource(struct resource res[2], -+ unsigned long base, -+ unsigned long size, -+ int irq) -+{ -+ memset(res, 0, sizeof(struct resource) * 2); -+ -+ res[0].flags = IORESOURCE_MEM; -+ res[0].start = base; -+ res[0].end = base + size - 1; -+ -+ res[1].flags = IORESOURCE_IRQ; -+ res[1].start = irq; -+ res[1].end = irq; -+} -+ -+static void ar934x_nfc_hw_reset(bool active) -+{ -+ if (active) { -+ ath79_device_reset_set(AR934X_RESET_NANDF); -+ udelay(100); -+ -+ ath79_device_reset_set(AR934X_RESET_ETH_SWITCH_ANALOG); -+ udelay(250); -+ } else { -+ ath79_device_reset_clear(AR934X_RESET_ETH_SWITCH_ANALOG); -+ udelay(250); -+ -+ ath79_device_reset_clear(AR934X_RESET_NANDF); -+ udelay(100); -+ } -+} -+ -+static void ar934x_nfc_setup(void) -+{ -+ ath79_nfc_data.hw_reset = ar934x_nfc_hw_reset; -+ -+ ath79_nfc_init_resource(ath79_nfc_resources, -+ AR934X_NFC_BASE, AR934X_NFC_SIZE, -+ ATH79_MISC_IRQ(21)); -+ -+ platform_device_register(&ath79_nfc_device); -+} -+ -+static void qca955x_nfc_hw_reset(bool active) -+{ -+ if (active) { -+ ath79_device_reset_set(QCA955X_RESET_NANDF); -+ udelay(250); -+ } else { -+ ath79_device_reset_clear(QCA955X_RESET_NANDF); -+ udelay(100); -+ } -+} -+ -+static void qca955x_nfc_setup(void) -+{ -+ ath79_nfc_data.hw_reset = qca955x_nfc_hw_reset; -+ -+ ath79_nfc_init_resource(ath79_nfc_resources, -+ QCA955X_NFC_BASE, QCA955X_NFC_SIZE, -+ ATH79_MISC_IRQ(21)); -+ -+ platform_device_register(&ath79_nfc_device); -+} -+ -+void __init ath79_nfc_set_select_chip(void (*f)(int chip_no)) -+{ -+ ath79_nfc_data.select_chip = f; -+} -+ -+void __init ath79_nfc_set_scan_fixup(int (*f)(struct mtd_info *mtd)) -+{ -+ ath79_nfc_data.scan_fixup = f; -+} -+ -+void __init ath79_nfc_set_swap_dma(bool enable) -+{ -+ ath79_nfc_data.swap_dma = enable; -+} -+ -+void __init ath79_nfc_set_ecc_mode(enum ar934x_nfc_ecc_mode mode) -+{ -+ ath79_nfc_data.ecc_mode = mode; -+} -+ -+void __init ath79_nfc_set_parts(struct mtd_partition *parts, int nr_parts) -+{ -+ ath79_nfc_data.parts = parts; -+ ath79_nfc_data.nr_parts = nr_parts; -+} -+ -+void __init ath79_register_nfc(void) -+{ -+ if (soc_is_ar934x()) -+ ar934x_nfc_setup(); -+ else if (soc_is_qca955x()) -+ qca955x_nfc_setup(); -+ else -+ BUG(); -+} -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.h b/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.h -new file mode 100644 -index 0000000000..3a1c88fe98 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.h -@@ -0,0 +1,34 @@ -+/* -+ * Atheros AR934X SoCs built-in NAND Flash Controller support -+ * -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _ATH79_DEV_NFC_H -+#define _ATH79_DEV_NFC_H -+ -+struct mtd_partition; -+enum ar934x_nfc_ecc_mode; -+ -+#ifdef CONFIG_ATH79_DEV_NFC -+void ath79_nfc_set_parts(struct mtd_partition *parts, int nr_parts); -+void ath79_nfc_set_select_chip(void (*f)(int chip_no)); -+void ath79_nfc_set_scan_fixup(int (*f)(struct mtd_info *mtd)); -+void ath79_nfc_set_swap_dma(bool enable); -+void ath79_nfc_set_ecc_mode(enum ar934x_nfc_ecc_mode mode); -+void ath79_register_nfc(void); -+#else -+static inline void ath79_nfc_set_parts(struct mtd_partition *parts, -+ int nr_parts) {} -+static inline void ath79_nfc_set_select_chip(void (*f)(int chip_no)) {} -+static inline void ath79_nfc_set_scan_fixup(int (*f)(struct mtd_info *mtd)) {} -+static inline void ath79_nfc_set_swap_dma(bool enable) {} -+static inline void ath79_nfc_set_ecc_mode(enum ar934x_nfc_ecc_mode mode) {} -+static inline void ath79_register_nfc(void) {} -+#endif -+ -+#endif /* _ATH79_DEV_NFC_H */ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-a60.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-a60.c -new file mode 100644 -index 0000000000..084a4e4cc0 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-a60.c -@@ -0,0 +1,181 @@ -+/* -+ * OpenMesh A60 support -+ * -+ * Copyright (C) 2013 Marek Lindner -+ * Copyright (C) 2014-2017 Sven Eckelmann -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-gpio-buttons.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+#include "dev-usb.h" -+ -+#define A60_GPIO_LED_RED 22 -+#define A60_GPIO_LED_GREEN 23 -+#define A60_GPIO_LED_BLUE 13 -+ -+#define A60_GPIO_BTN_RESET 17 -+ -+#define A60_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define A60_KEYS_DEBOUNCE_INTERVAL (3 * A60_KEYS_POLL_INTERVAL) -+ -+#define A60_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led a40_leds_gpio[] __initdata = { -+ { -+ .name = "a40:red:status", -+ .gpio = A60_GPIO_LED_RED, -+ }, { -+ .name = "a40:green:status", -+ .gpio = A60_GPIO_LED_GREEN, -+ }, { -+ .name = "a40:blue:status", -+ .gpio = A60_GPIO_LED_BLUE, -+ } -+}; -+ -+static struct gpio_led a60_leds_gpio[] __initdata = { -+ { -+ .name = "a60:red:status", -+ .gpio = A60_GPIO_LED_RED, -+ }, { -+ .name = "a60:green:status", -+ .gpio = A60_GPIO_LED_GREEN, -+ }, { -+ .name = "a60:blue:status", -+ .gpio = A60_GPIO_LED_BLUE, -+ } -+}; -+ -+static struct gpio_keys_button a60_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = A60_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = A60_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct at803x_platform_data a60_at803x_data = { -+ .disable_smarteee = 1, -+ .enable_rgmii_rx_delay = 1, -+ .enable_rgmii_tx_delay = 1, -+}; -+ -+static struct mdio_board_info a60_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 1, -+ .platform_data = &a60_at803x_data, -+ }, -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 2, -+ .platform_data = &a60_at803x_data, -+ }, -+}; -+ -+static void __init a60_setup_qca955x_eth_cfg(u32 mask, -+ unsigned int rxd, -+ unsigned int rxdv, -+ unsigned int txd, -+ unsigned int txe) -+{ -+ void __iomem *base; -+ u32 t; -+ -+ base = ioremap(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE); -+ -+ t = mask; -+ t |= rxd << QCA955X_ETH_CFG_RXD_DELAY_SHIFT; -+ t |= rxdv << QCA955X_ETH_CFG_RDV_DELAY_SHIFT; -+ t |= txd << QCA955X_ETH_CFG_TXD_DELAY_SHIFT; -+ t |= txe << QCA955X_ETH_CFG_TXE_DELAY_SHIFT; -+ -+ __raw_writel(t, base + QCA955X_GMAC_REG_ETH_CFG); -+ -+ iounmap(base); -+} -+ -+static void __init a60_setup_common(void) -+{ -+ u8 *art = (u8 *)KSEG1ADDR(0x1fff0000); -+ u8 mac[6]; -+ -+ ath79_register_usb(); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_gpio_keys_polled(-1, A60_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(a60_gpio_keys), -+ a60_gpio_keys); -+ -+ ath79_init_mac(mac, art, 0x02); -+ ath79_register_wmac(art + A60_WMAC_CALDATA_OFFSET, mac); -+ -+ a60_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN, 3, 3, 0, 0); -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(a60_mdio0_info, ARRAY_SIZE(a60_mdio0_info)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art, 0x00); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art, 0x01); -+ -+ /* GMAC0 is connected to the PHY1 */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_data.phy_mask = BIT(1); -+ ath79_eth0_pll_data.pll_1000 = 0x82000101; -+ ath79_eth0_pll_data.pll_100 = 0x80000101; -+ ath79_eth0_pll_data.pll_10 = 0x80001313; -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to MDIO1 in SGMII mode */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth1_data.phy_mask = BIT(2); -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ ath79_eth1_pll_data.pll_100 = 0x80000101; -+ ath79_eth1_pll_data.pll_10 = 0x80001313; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_register_eth(1); -+ -+ ath79_register_pci(); -+} -+ -+static void __init a40_setup(void) -+{ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(a40_leds_gpio), a40_leds_gpio); -+ a60_setup_common(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_A40, "A40", "OpenMesh A40", a40_setup); -+ -+static void __init a60_setup(void) -+{ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(a60_leds_gpio), a60_leds_gpio); -+ a60_setup_common(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_A60, "A60", "OpenMesh A60", a60_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-ap120c.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-ap120c.c -new file mode 100644 -index 0000000000..032261f751 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-ap120c.c -@@ -0,0 +1,147 @@ -+/* -+ * ALFA Network AP120C board support -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * Copyright (C) 2016 Luka Perkov -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-ap9x-pci.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define ALFA_AP120C_GPIO_LED 0 -+ -+#define ALFA_AP120C_GPIO_BUTTON_WIFI 16 -+ -+#define ALFA_AP120C_GPIO_WATCH_DOG 20 -+ -+#define ALFA_AP120C_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define ALFA_AP120C_KEYS_DEBOUNCE_INTERVAL (3 * ALFA_AP120C_KEYS_POLL_INTERVAL) -+ -+#define ALFA_AP120C_MAC_OFFSET 0x1002 -+#define ALFA_AP120C_CAL0_OFFSET 0x1000 -+ -+static struct gpio_keys_button alfa_ap120c_gpio_keys[] __initdata = { -+ { -+ .desc = "Wireless button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = ALFA_AP120C_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ALFA_AP120C_GPIO_BUTTON_WIFI, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led alfa_ap120c_leds_gpio[] __initdata = { -+ { -+ .name = "ap120c:red:wlan", -+ .gpio = ALFA_AP120C_GPIO_LED, -+ .active_low = 0, -+ } -+}; -+ -+static struct ar8327_pad_cfg ap120c_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_platform_data ap120c_ar8327_data = { -+ .pad0_cfg = &ap120c_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info ap120c_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &ap120c_ar8327_data, -+ }, -+}; -+ -+static struct flash_platform_data flash __initdata = { NULL, NULL, 0 }; -+ -+#define ALFA_AP120C_LAN_PHYMASK BIT(5) -+#define ALFA_AP120C_MDIO_PHYMASK ALFA_AP120C_LAN_PHYMASK -+ -+static void __init alfa_ap120c_init(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 mac[ETH_ALEN]; -+ -+ struct ath9k_platform_data *pdata; -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(alfa_ap120c_leds_gpio), -+ alfa_ap120c_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, ALFA_AP120C_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(alfa_ap120c_gpio_keys), -+ alfa_ap120c_gpio_keys); -+ -+ ath79_gpio_function_enable(AR71XX_GPIO_FUNC_SPI_CS1_EN | -+ AR71XX_GPIO_FUNC_SPI_CS2_EN); -+ -+ ath79_register_m25p80_multi(&flash); -+ -+ ath79_init_mac(mac, art + ALFA_AP120C_MAC_OFFSET, 1); -+ ath79_register_wmac(art + ALFA_AP120C_CAL0_OFFSET, mac); -+ -+ ath79_init_mac(mac, art + ALFA_AP120C_MAC_OFFSET, 2); -+ ap91_pci_init(NULL, mac); -+ pdata = ap9x_pci_get_wmac_data(0); -+ if (!pdata) { -+ pr_err("ap120c: unable to get address of wlan data\n"); -+ return; -+ } -+ pdata->use_eeprom = true; -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ BIT(15) | BIT(17) | BIT(19) | BIT(21)); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + ALFA_AP120C_MAC_OFFSET, 0); -+ -+ mdiobus_register_board_info(ap120c_mdio0_info, ARRAY_SIZE(ap120c_mdio0_info)); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = ALFA_AP120C_LAN_PHYMASK; -+ -+ ath79_eth0_pll_data.pll_1000 = 0x42000000; -+ ath79_eth0_pll_data.pll_10 = 0x00001313; -+ -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ALFA_AP120C, "ALFA-AP120C", "ALFA Network AP120C", -+ alfa_ap120c_init); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-ap96.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-ap96.c -new file mode 100644 -index 0000000000..531e5fb18e ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-ap96.c -@@ -0,0 +1,132 @@ -+/* -+ * ALFA Network AP96 board support -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define ALFA_AP96_GPIO_PCIE_RESET 2 -+#define ALFA_AP96_GPIO_SIM_DETECT 3 -+#define ALFA_AP96_GPIO_MICROSD_CD 4 -+#define ALFA_AP96_GPIO_PCIE_W_DISABLE 5 -+ -+#define ALFA_AP96_GPIO_BUTTON_RESET 11 -+ -+#define ALFA_AP96_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define ALFA_AP96_KEYS_DEBOUNCE_INTERVAL (3 * ALFA_AP96_KEYS_POLL_INTERVAL) -+ -+static struct gpio_keys_button alfa_ap96_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ALFA_AP96_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ALFA_AP96_GPIO_BUTTON_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static struct mmc_spi_platform_data alfa_ap96_mmc_data = { -+ .flags = MMC_SPI_USE_CD_GPIO, -+ .cd_gpio = ALFA_AP96_GPIO_MICROSD_CD, -+ .cd_debounce = 1, -+ .caps = MMC_CAP_NEEDS_POLL, -+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, -+}; -+ -+static struct spi_board_info alfa_ap96_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ }, { -+ .bus_num = 0, -+ .chip_select = 1, -+ .max_speed_hz = 25000000, -+ .modalias = "mmc_spi", -+ .platform_data = &alfa_ap96_mmc_data, -+ }, { -+ .bus_num = 0, -+ .chip_select = 2, -+ .max_speed_hz = 6250000, -+ .modalias = "rtc-pcf2123", -+ }, -+}; -+ -+static struct ath79_spi_platform_data alfa_ap96_spi_data = { -+ .bus_num = 0, -+ .num_chipselect = 3, -+}; -+ -+static void __init alfa_ap96_gpio_setup(void) -+{ -+ ath79_gpio_function_enable(AR71XX_GPIO_FUNC_SPI_CS1_EN | -+ AR71XX_GPIO_FUNC_SPI_CS2_EN); -+ -+ gpio_request(ALFA_AP96_GPIO_MICROSD_CD, "microSD CD"); -+ gpio_direction_input(ALFA_AP96_GPIO_MICROSD_CD); -+ gpio_request(ALFA_AP96_GPIO_PCIE_RESET, "PCIe reset"); -+ gpio_direction_output(ALFA_AP96_GPIO_PCIE_RESET, 1); -+ gpio_request(ALFA_AP96_GPIO_PCIE_W_DISABLE, "PCIe write disable"); -+ gpio_direction_output(ALFA_AP96_GPIO_PCIE_W_DISABLE, 1); -+} -+ -+#define ALFA_AP96_WAN_PHYMASK BIT(4) -+#define ALFA_AP96_LAN_PHYMASK BIT(5) -+#define ALFA_AP96_MDIO_PHYMASK (ALFA_AP96_LAN_PHYMASK | ALFA_AP96_WAN_PHYMASK) -+ -+static void __init alfa_ap96_init(void) -+{ -+ alfa_ap96_gpio_setup(); -+ -+ ath79_register_mdio(0, ~ALFA_AP96_MDIO_PHYMASK); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = ALFA_AP96_WAN_PHYMASK; -+ ath79_eth1_pll_data.pll_1000 = 0x110000; -+ -+ ath79_register_eth(0); -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth1_data.phy_mask = ALFA_AP96_LAN_PHYMASK; -+ ath79_eth1_pll_data.pll_1000 = 0x110000; -+ -+ ath79_register_eth(1); -+ -+ ath79_register_pci(); -+ ath79_register_spi(&alfa_ap96_spi_data, alfa_ap96_spi_info, -+ ARRAY_SIZE(alfa_ap96_spi_info)); -+ -+ ath79_register_gpio_keys_polled(-1, ALFA_AP96_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(alfa_ap96_gpio_keys), -+ alfa_ap96_gpio_keys); -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ALFA_AP96, "ALFA-AP96", "ALFA Network AP96", -+ alfa_ap96_init); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-nx.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-nx.c -new file mode 100644 -index 0000000000..a515f4f540 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-nx.c -@@ -0,0 +1,113 @@ -+/* -+ * ALFA Network N2/N5 board support -+ * -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+ -+#define ALFA_NX_GPIO_LED_2 17 -+#define ALFA_NX_GPIO_LED_3 16 -+#define ALFA_NX_GPIO_LED_5 12 -+#define ALFA_NX_GPIO_LED_6 8 -+#define ALFA_NX_GPIO_LED_7 6 -+#define ALFA_NX_GPIO_LED_8 7 -+ -+#define ALFA_NX_GPIO_BTN_RESET 11 -+ -+#define ALFA_NX_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define ALFA_NX_KEYS_DEBOUNCE_INTERVAL (3 * ALFA_NX_KEYS_POLL_INTERVAL) -+ -+#define ALFA_NX_MAC0_OFFSET 0 -+#define ALFA_NX_MAC1_OFFSET 6 -+#define ALFA_NX_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_keys_button alfa_nx_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ALFA_NX_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ALFA_NX_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led alfa_nx_leds_gpio[] __initdata = { -+ { -+ .name = "alfa:green:led_2", -+ .gpio = ALFA_NX_GPIO_LED_2, -+ .active_low = 1, -+ }, { -+ .name = "alfa:green:led_3", -+ .gpio = ALFA_NX_GPIO_LED_3, -+ .active_low = 1, -+ }, { -+ .name = "alfa:red:led_5", -+ .gpio = ALFA_NX_GPIO_LED_5, -+ .active_low = 1, -+ }, { -+ .name = "alfa:amber:led_6", -+ .gpio = ALFA_NX_GPIO_LED_6, -+ .active_low = 1, -+ }, { -+ .name = "alfa:green:led_7", -+ .gpio = ALFA_NX_GPIO_LED_7, -+ .active_low = 1, -+ }, { -+ .name = "alfa:green:led_8", -+ .gpio = ALFA_NX_GPIO_LED_8, -+ .active_low = 1, -+ } -+}; -+ -+static void __init alfa_nx_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE, -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(0, ARRAY_SIZE(alfa_nx_leds_gpio), -+ alfa_nx_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, ALFA_NX_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(alfa_nx_gpio_keys), -+ alfa_nx_gpio_keys); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ art + ALFA_NX_MAC0_OFFSET, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, -+ art + ALFA_NX_MAC1_OFFSET, 0); -+ -+ /* WAN port */ -+ ath79_register_eth(0); -+ /* LAN port */ -+ ath79_register_eth(1); -+ -+ ap91_pci_init(art + ALFA_NX_CALDATA_OFFSET, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ALFA_NX, "ALFA-NX", "ALFA Network N2/N5", -+ alfa_nx_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-all0258n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-all0258n.c -new file mode 100644 -index 0000000000..2495bcba79 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-all0258n.c -@@ -0,0 +1,88 @@ -+/* -+ * Allnet ALL0258N support -+ * -+ * Copyright (C) 2011 Daniel Golle -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+ -+/* found via /sys/gpio/... try and error */ -+#define ALL0258N_GPIO_BTN_RESET 1 -+#define ALL0258N_GPIO_LED_RSSIHIGH 13 -+#define ALL0258N_GPIO_LED_RSSIMEDIUM 15 -+#define ALL0258N_GPIO_LED_RSSILOW 14 -+ -+/* defaults taken from others machs */ -+#define ALL0258N_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define ALL0258N_KEYS_DEBOUNCE_INTERVAL (3 * ALL0258N_KEYS_POLL_INTERVAL) -+ -+/* showed up in the original firmware's bootlog */ -+#define ALL0258N_SEC_PHYMASK BIT(3) -+ -+static struct gpio_led all0258n_leds_gpio[] __initdata = { -+ { -+ .name = "all0258n:green:rssihigh", -+ .gpio = ALL0258N_GPIO_LED_RSSIHIGH, -+ .active_low = 1, -+ }, { -+ .name = "all0258n:yellow:rssimedium", -+ .gpio = ALL0258N_GPIO_LED_RSSIMEDIUM, -+ .active_low = 1, -+ }, { -+ .name = "all0258n:red:rssilow", -+ .gpio = ALL0258N_GPIO_LED_RSSILOW, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button all0258n_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ALL0258N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ALL0258N_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init all0258n_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f7f0000); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1f7f1000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(all0258n_leds_gpio), -+ all0258n_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, ALL0258N_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(all0258n_gpio_keys), -+ all0258n_gpio_keys); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ -+ ath79_eth1_data.phy_mask = ALL0258N_SEC_PHYMASK; -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ap91_pci_init(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ALL0258N, "ALL0258N", "Allnet ALL0258N", -+ all0258n_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-all0315n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-all0315n.c -new file mode 100644 -index 0000000000..387ee7f9ea ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-all0315n.c -@@ -0,0 +1,85 @@ -+/* -+ * Allnet ALL0315N support -+ * -+ * Copyright (C) 2012 Daniel Golle -+ * -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-m25p80.h" -+#include "dev-leds-gpio.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define ALL0315N_GPIO_BTN_RESET 0 -+#define ALL0315N_GPIO_LED_RSSIHIGH 14 -+#define ALL0315N_GPIO_LED_RSSIMEDIUM 15 -+#define ALL0315N_GPIO_LED_RSSILOW 16 -+ -+#define ALL0315N_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define ALL0315N_KEYS_DEBOUNCE_INTERVAL (3 * ALL0315N_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led all0315n_leds_gpio[] __initdata = { -+ { -+ .name = "all0315n:green:rssihigh", -+ .gpio = ALL0315N_GPIO_LED_RSSIHIGH, -+ .active_low = 1, -+ }, { -+ .name = "all0315n:yellow:rssimedium", -+ .gpio = ALL0315N_GPIO_LED_RSSIMEDIUM, -+ .active_low = 1, -+ }, { -+ .name = "all0315n:red:rssilow", -+ .gpio = ALL0315N_GPIO_LED_RSSILOW, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button all0315n_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ALL0315N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ALL0315N_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init all0315n_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1ffc0000); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1ffc1000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(all0315n_leds_gpio), -+ all0315n_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, ALL0315N_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(all0315n_gpio_keys), -+ all0315n_gpio_keys); -+ -+ ap9x_pci_setup_wmac_led_pin(0, 1); -+ ap91_pci_init(ee, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ALL0315N, "ALL0315N", "Allnet ALL0315N", -+ all0315n_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-antminer-s1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-antminer-s1.c -new file mode 100644 -index 0000000000..0a81227b51 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-antminer-s1.c -@@ -0,0 +1,98 @@ -+/* -+ * Bitmain Antminer S1 board support -+ * -+ * Copyright (C) 2015 L. D. Pinney -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "dev-usb.h" -+ -+#define ANTMINER_S1_GPIO_BTN_RESET 11 -+ -+#define ANTMINER_S1_GPIO_LED_SYSTEM 23 -+#define ANTMINER_S1_GPIO_LED_WLAN 0 -+#define ANTMINER_S1_GPIO_USB_POWER 26 -+ -+#define ANTMINER_S1_KEYSPOLL_INTERVAL 20 /* msecs */ -+#define ANTMINER_S1_KEYSDEBOUNCE_INTERVAL (3 * ANTMINER_S1_KEYSPOLL_INTERVAL) -+ -+static const char *ANTMINER_S1_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data ANTMINER_S1_flash_data = { -+ .part_probes = ANTMINER_S1_part_probes, -+}; -+ -+static struct gpio_led ANTMINER_S1_leds_gpio[] __initdata = { -+ { -+ .name = "antminer-s1:green:system", -+ .gpio = ANTMINER_S1_GPIO_LED_SYSTEM, -+ .active_low = 0, -+ },{ -+ .name = "antminer-s1:green:wlan", -+ .gpio = ANTMINER_S1_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button ANTMINER_S1_GPIO_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ANTMINER_S1_KEYSDEBOUNCE_INTERVAL, -+ .gpio = ANTMINER_S1_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+}; -+ -+static void __init antminer_s1_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ANTMINER_S1_leds_gpio), -+ ANTMINER_S1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, ANTMINER_S1_KEYSPOLL_INTERVAL, -+ ARRAY_SIZE(ANTMINER_S1_GPIO_keys), -+ ANTMINER_S1_GPIO_keys); -+ -+ gpio_request_one(ANTMINER_S1_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ ath79_register_m25p80(&ANTMINER_S1_flash_data); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ANTMINER_S1, "ANTMINER-S1", -+ "Antminer-S1", antminer_s1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-antminer-s3.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-antminer-s3.c -new file mode 100644 -index 0000000000..b77a6ccc4e ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-antminer-s3.c -@@ -0,0 +1,103 @@ -+/* -+ * Bitmain Antminer S3 board support -+ * -+ * Copyright (C) 2015 L. D. Pinney -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "dev-usb.h" -+ -+#define ANTMINER_S3_GPIO_LED_WLAN 0 -+#define ANTMINER_S3_GPIO_LED_SYSTEM 17 -+#define ANTMINER_S3_GPIO_LED_LAN 22 -+#define ANTMINER_S3_GPIO_USB_POWER 26 -+ -+#define ANTMINER_S3_GPIO_BTN_RESET 11 -+ -+#define ANTMINER_S3_KEYSPOLL_INTERVAL 88 /* msecs */ -+#define ANTMINER_S3_KEYSDEBOUNCE_INTERVAL (3 * ANTMINER_S3_KEYSPOLL_INTERVAL) -+ -+static const char *ANTMINER_S3_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data ANTMINER_S3_flash_data = { -+ .part_probes = ANTMINER_S3_part_probes, -+}; -+ -+static struct gpio_led ANTMINER_S3_leds_gpio[] __initdata = { -+ { -+ .name = "antminer-s3:green:wlan", -+ .gpio = ANTMINER_S3_GPIO_LED_WLAN, -+ .active_low = 0, -+ },{ -+ .name = "antminer-s3:green:system", -+ .gpio = ANTMINER_S3_GPIO_LED_SYSTEM, -+ .active_low = 0, -+ },{ -+ .name = "antminer-s3:yellow:lan", -+ .gpio = ANTMINER_S3_GPIO_LED_LAN, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button ANTMINER_S3_GPIO_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ANTMINER_S3_KEYSDEBOUNCE_INTERVAL, -+ .gpio = ANTMINER_S3_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+}; -+ -+static void __init antminer_s3_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ANTMINER_S3_leds_gpio), -+ ANTMINER_S3_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, ANTMINER_S3_KEYSPOLL_INTERVAL, -+ ARRAY_SIZE(ANTMINER_S3_GPIO_keys), -+ ANTMINER_S3_GPIO_keys); -+ -+ gpio_request_one(ANTMINER_S3_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ ath79_register_m25p80(&ANTMINER_S3_flash_data); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ANTMINER_S3, "ANTMINER-S3", -+ "Antminer-S3", antminer_s3_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-antrouter-r1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-antrouter-r1.c -new file mode 100644 -index 0000000000..a8f7b5d687 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-antrouter-r1.c -@@ -0,0 +1,98 @@ -+/* -+ * Bitmain Antrouter R1 board support -+ * -+ * Copyright (C) 2015 L. D. Pinney -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "dev-usb.h" -+ -+#define ANTROUTER_R1_GPIO_BTN_RESET 11 -+ -+#define ANTROUTER_R1_GPIO_LED_WLAN 0 -+#define ANTROUTER_R1_GPIO_LED_BTC 22 -+#define ANTROUTER_R1_GPIO_USB_POWER 18 -+ -+#define ANTROUTER_R1_KEYSPOLL_INTERVAL 44 /* msecs */ -+#define ANTROUTER_R1_KEYSDEBOUNCE_INTERVAL (4 * ANTROUTER_R1_KEYSPOLL_INTERVAL) -+ -+static const char *ANTROUTER_R1_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data ANTROUTER_R1_flash_data = { -+ .part_probes = ANTROUTER_R1_part_probes, -+}; -+ -+static struct gpio_led ANTROUTER_R1_leds_gpio[] __initdata = { -+ { -+ .name = "antrouter-r1:green:wlan", -+ .gpio = ANTROUTER_R1_GPIO_LED_WLAN, -+ .active_low = 0, -+ },{ -+ .name = "antrouter-r1:green:system", -+ .gpio = ANTROUTER_R1_GPIO_LED_BTC, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button ANTROUTER_R1_GPIO_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ANTROUTER_R1_KEYSDEBOUNCE_INTERVAL, -+ .gpio = ANTROUTER_R1_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+}; -+ -+static void __init antrouter_r1_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ANTROUTER_R1_leds_gpio), -+ ANTROUTER_R1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, ANTROUTER_R1_KEYSPOLL_INTERVAL, -+ ARRAY_SIZE(ANTROUTER_R1_GPIO_keys), -+ ANTROUTER_R1_GPIO_keys); -+ -+ gpio_request_one(ANTROUTER_R1_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ ath79_register_m25p80(&ANTROUTER_R1_flash_data); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ANTROUTER_R1, "ANTROUTER-R1", -+ "Antrouter-R1", antrouter_r1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ap121f.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap121f.c -new file mode 100644 -index 0000000000..955b7faf63 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap121f.c -@@ -0,0 +1,103 @@ -+/* -+ * ALFA Network AP121F board support -+ * -+ * Copyright (C) 2017 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define AP121F_GPIO_LED_LAN 17 -+#define AP121F_GPIO_LED_VPN 27 -+#define AP121F_GPIO_LED_WLAN 0 -+ -+#define AP121F_GPIO_MICROSD_EN 26 -+ -+#define AP121F_GPIO_BTN_RESET 12 -+#define AP121F_GPIO_BTN_SWITCH 21 -+ -+#define AP121F_KEYS_POLL_INTERVAL 20 -+#define AP121F_KEYS_DEBOUNCE_INTERVAL (3 * AP121F_KEYS_POLL_INTERVAL) -+ -+#define AP121F_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led ap121f_leds_gpio[] __initdata = { -+ { -+ .name = "ap121f:green:lan", -+ .gpio = AP121F_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "ap121f:green:vpn", -+ .gpio = AP121F_GPIO_LED_VPN, -+ .active_low = 1, -+ }, { -+ .name = "ap121f:green:wlan", -+ .gpio = AP121F_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button ap121f_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = AP121F_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP121F_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "switch", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = AP121F_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP121F_GPIO_BTN_SWITCH, -+ .active_low = 0, -+ }, -+}; -+ -+static void __init ap121f_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1f040000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ /* LAN */ -+ ath79_register_mdio(0, 0x0); -+ ath79_init_mac(ath79_eth0_data.mac_addr, art, 0); -+ ath79_register_eth(0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap121f_leds_gpio), -+ ap121f_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, AP121F_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ap121f_gpio_keys), -+ ap121f_gpio_keys); -+ -+ gpio_request_one(AP121F_GPIO_MICROSD_EN, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "microSD enable"); -+ -+ ath79_register_wmac(art + AP121F_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_AP121F, "AP121F", "ALFA Network AP121F", ap121f_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ap132.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap132.c -new file mode 100644 -index 0000000000..2ebac057a7 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap132.c -@@ -0,0 +1,189 @@ -+/* -+ * Atheros AP132 reference board support -+ * -+ * Copyright (c) 2012 Qualcomm Atheros -+ * Copyright (c) 2012 Gabor Juhos -+ * Copyright (c) 2013 Embedded Wireless GmbH -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define AP132_GPIO_LED_USB 4 -+#define AP132_GPIO_LED_WLAN_5G 12 -+#define AP132_GPIO_LED_WLAN_2G 13 -+#define AP132_GPIO_LED_STATUS_RED 14 -+#define AP132_GPIO_LED_WPS_RED 15 -+ -+#define AP132_GPIO_BTN_WPS 16 -+ -+#define AP132_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define AP132_KEYS_DEBOUNCE_INTERVAL (3 * AP132_KEYS_POLL_INTERVAL) -+ -+#define AP132_MAC0_OFFSET 0 -+#define AP132_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led ap132_leds_gpio[] __initdata = { -+ { -+ .name = "ap132:red:status", -+ .gpio = AP132_GPIO_LED_STATUS_RED, -+ .active_low = 1, -+ }, -+ { -+ .name = "ap132:red:wps", -+ .gpio = AP132_GPIO_LED_WPS_RED, -+ .active_low = 1, -+ }, -+ { -+ .name = "ap132:red:wlan-2g", -+ .gpio = AP132_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "ap132:red:usb", -+ .gpio = AP132_GPIO_LED_USB, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button ap132_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = AP132_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP132_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg ap132_ar8327_pad0_cfg; -+ -+static struct ar8327_platform_data ap132_ar8327_data = { -+ .pad0_cfg = &ap132_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info ap132_mdio1_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.1", -+ .mdio_addr = 0, -+ .platform_data = &ap132_ar8327_data, -+ }, -+}; -+ -+static void __init ap132_mdio_setup(void) -+{ -+ void __iomem *base; -+ u32 t; -+ -+#define GPIO_IN_ENABLE3_ADDRESS 0x0050 -+#define GPIO_IN_ENABLE3_MII_GE1_MDI_MASK 0x00ff0000 -+#define GPIO_IN_ENABLE3_MII_GE1_MDI_LSB 16 -+#define GPIO_IN_ENABLE3_MII_GE1_MDI_SET(x) (((x) << GPIO_IN_ENABLE3_MII_GE1_MDI_LSB) & GPIO_IN_ENABLE3_MII_GE1_MDI_MASK) -+#define GPIO_OUT_FUNCTION4_ADDRESS 0x003c -+#define GPIO_OUT_FUNCTION4_ENABLE_GPIO_19_MASK 0xff000000 -+#define GPIO_OUT_FUNCTION4_ENABLE_GPIO_19_LSB 24 -+#define GPIO_OUT_FUNCTION4_ENABLE_GPIO_19_SET(x) (((x) << GPIO_OUT_FUNCTION4_ENABLE_GPIO_19_LSB) & GPIO_OUT_FUNCTION4_ENABLE_GPIO_19_MASK) -+#define GPIO_OUT_FUNCTION4_ENABLE_GPIO_17_MASK 0x0000ff00 -+#define GPIO_OUT_FUNCTION4_ENABLE_GPIO_17_LSB 8 -+#define GPIO_OUT_FUNCTION4_ENABLE_GPIO_17_SET(x) (((x) << GPIO_OUT_FUNCTION4_ENABLE_GPIO_17_LSB) & GPIO_OUT_FUNCTION4_ENABLE_GPIO_17_MASK) -+ -+ base = ioremap(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); -+ -+ t = __raw_readl(base + GPIO_IN_ENABLE3_ADDRESS); -+ t &= ~GPIO_IN_ENABLE3_MII_GE1_MDI_MASK; -+ t |= GPIO_IN_ENABLE3_MII_GE1_MDI_SET(19); -+ __raw_writel(t, base + GPIO_IN_ENABLE3_ADDRESS); -+ -+ -+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << 19), base + AR71XX_GPIO_REG_OE); -+ -+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << 17), base + AR71XX_GPIO_REG_OE); -+ -+ -+ t = __raw_readl(base + GPIO_OUT_FUNCTION4_ADDRESS); -+ t &= ~(GPIO_OUT_FUNCTION4_ENABLE_GPIO_19_MASK | GPIO_OUT_FUNCTION4_ENABLE_GPIO_17_MASK); -+ t |= GPIO_OUT_FUNCTION4_ENABLE_GPIO_19_SET(0x20) | GPIO_OUT_FUNCTION4_ENABLE_GPIO_17_SET(0x21); -+ __raw_writel(t, base + GPIO_OUT_FUNCTION4_ADDRESS); -+ -+ iounmap(base); -+ -+} -+ -+static void __init ap132_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap132_leds_gpio), -+ ap132_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, AP132_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ap132_gpio_keys), -+ ap132_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_register_wmac(art + AP132_WMAC_CALDATA_OFFSET, NULL); -+ -+ /* GMAC0 of the AR8327 switch is connected to GMAC1 via SGMII */ -+ ap132_ar8327_pad0_cfg.mode = AR8327_PAD_MAC_SGMII; -+ ap132_ar8327_pad0_cfg.sgmii_delay_en = true; -+ -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ -+ ap132_mdio_setup(); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + AP132_MAC0_OFFSET, 0); -+ -+ mdiobus_register_board_info(ap132_mdio1_info, -+ ARRAY_SIZE(ap132_mdio1_info)); -+ -+ /* GMAC1 is connected to the SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_mask = BIT(0); -+ ath79_eth1_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_AP132, "AP132", -+ "Atheros AP132 reference board", -+ ap132_setup); -+ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ap143.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap143.c -new file mode 100644 -index 0000000000..098420b92f ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap143.c -@@ -0,0 +1,142 @@ -+/* -+ * Atheros AP143 reference board support -+ * -+ * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. -+ * Copyright (c) 2012 Gabor Juhos -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define AP143_GPIO_LED_WLAN 12 -+#define AP143_GPIO_LED_WPS 13 -+#define AP143_GPIO_LED_STATUS 13 -+ -+#define AP143_GPIO_LED_WAN 4 -+#define AP143_GPIO_LED_LAN1 16 -+#define AP143_GPIO_LED_LAN2 15 -+#define AP143_GPIO_LED_LAN3 14 -+#define AP143_GPIO_LED_LAN4 11 -+ -+#define AP143_GPIO_BTN_WPS 17 -+ -+#define AP143_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define AP143_KEYS_DEBOUNCE_INTERVAL (3 * AP143_KEYS_POLL_INTERVAL) -+ -+#define AP143_MAC0_OFFSET 0 -+#define AP143_MAC1_OFFSET 6 -+#define AP143_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led ap143_leds_gpio[] __initdata = { -+ { -+ .name = "ap143:green:status", -+ .gpio = AP143_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, -+ { -+ .name = "ap143:green:wlan", -+ .gpio = AP143_GPIO_LED_WLAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button ap143_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = AP143_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP143_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init ap143_gpio_led_setup(void) -+{ -+ ath79_gpio_direction_select(AP143_GPIO_LED_WAN, true); -+ ath79_gpio_direction_select(AP143_GPIO_LED_LAN1, true); -+ ath79_gpio_direction_select(AP143_GPIO_LED_LAN2, true); -+ ath79_gpio_direction_select(AP143_GPIO_LED_LAN3, true); -+ ath79_gpio_direction_select(AP143_GPIO_LED_LAN4, true); -+ -+ ath79_gpio_output_select(AP143_GPIO_LED_WAN, -+ QCA953X_GPIO_OUT_MUX_LED_LINK5); -+ ath79_gpio_output_select(AP143_GPIO_LED_LAN1, -+ QCA953X_GPIO_OUT_MUX_LED_LINK1); -+ ath79_gpio_output_select(AP143_GPIO_LED_LAN2, -+ QCA953X_GPIO_OUT_MUX_LED_LINK2); -+ ath79_gpio_output_select(AP143_GPIO_LED_LAN3, -+ QCA953X_GPIO_OUT_MUX_LED_LINK3); -+ ath79_gpio_output_select(AP143_GPIO_LED_LAN4, -+ QCA953X_GPIO_OUT_MUX_LED_LINK4); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap143_leds_gpio), -+ ap143_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, AP143_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ap143_gpio_keys), -+ ap143_gpio_keys); -+} -+ -+static void __init ap143_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ap143_gpio_led_setup(); -+ -+ ath79_register_usb(); -+ -+ ath79_wmac_set_led_pin(AP143_GPIO_LED_WLAN); -+ ath79_register_wmac(art + AP143_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + AP143_MAC0_OFFSET, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + AP143_MAC1_OFFSET, 0); -+ -+ /* WAN port */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_register_eth(0); -+ -+ /* LAN ports */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_AP143, "AP143", "Qualcomm Atheros AP143 reference board", -+ ap143_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ap147.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap147.c -new file mode 100644 -index 0000000000..7b45da4711 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap147.c -@@ -0,0 +1,125 @@ -+/* -+ * Atheros AP147 reference board support -+ * -+ * Copyright (C) 2014 Matthias Schiffer -+ * Copyright (C) 2015 Sven Eckelmann -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define AP147_GPIO_LED_WAN 4 -+#define AP147_GPIO_LED_LAN1 16 -+#define AP147_GPIO_LED_LAN2 15 -+#define AP147_GPIO_LED_LAN3 14 -+#define AP147_GPIO_LED_LAN4 11 -+#define AP147_GPIO_LED_STATUS 13 -+#define AP147_GPIO_LED_WLAN_2G 12 -+ -+#define AP147_GPIO_BTN_WPS 17 -+ -+#define AP147_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define AP147_KEYS_DEBOUNCE_INTERVAL (3 * AP147_KEYS_POLL_INTERVAL) -+ -+#define AP147_MAC0_OFFSET 0x1000 -+ -+static struct gpio_led ap147_leds_gpio[] __initdata = { -+ { -+ .name = "ap147:green:status", -+ .gpio = AP147_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "ap147:green:wlan-2g", -+ .gpio = AP147_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ }, { -+ .name = "ap147:green:lan1", -+ .gpio = AP147_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "ap147:green:lan2", -+ .gpio = AP147_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "ap147:green:lan3", -+ .gpio = AP147_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "ap147:green:lan4", -+ .gpio = AP147_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "ap147:green:wan", -+ .gpio = AP147_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button ap147_gpio_keys[] __initdata = { -+ { -+ .desc = "wps button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = AP147_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP147_GPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static void __init ap147_setup(void) -+{ -+ u8 *art = (u8 *)KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap147_leds_gpio), -+ ap147_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, AP147_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ap147_gpio_keys), -+ ap147_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_register_pci(); -+ -+ ath79_register_wmac(art + AP147_MAC0_OFFSET, NULL); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art, 0); -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_init_mac(ath79_eth0_data.mac_addr, art, 1); -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_AP147_010, "AP147-010", "Atheros AP147-010 reference board", ap147_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ap152.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap152.c -new file mode 100644 -index 0000000000..277a934a18 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap152.c -@@ -0,0 +1,140 @@ -+ -+/* -+ * Qualcomm Atheros AP152 reference board support -+ * -+ * Copyright (c) 2015 Qualcomm Atheros -+ * Copyright (c) 2012 Gabor Juhos -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+#include "pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+ -+#define AP152_GPIO_LED_USB0 7 -+#define AP152_GPIO_LED_USB1 8 -+ -+#define AP152_GPIO_BTN_RESET 2 -+#define AP152_GPIO_BTN_WPS 1 -+#define AP152_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define AP152_KEYS_DEBOUNCE_INTERVAL (3 * AP152_KEYS_POLL_INTERVAL) -+ -+#define AP152_MAC0_OFFSET 0 -+#define AP152_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led ap152_leds_gpio[] __initdata = { -+ { -+ .name = "ap152:green:usb0", -+ .gpio = AP152_GPIO_LED_USB0, -+ .active_low = 1, -+ }, -+ { -+ .name = "ap152:green:usb1", -+ .gpio = AP152_GPIO_LED_USB1, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button ap152_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = AP152_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP152_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = AP152_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP152_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg ap152_ar8337_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+static struct ar8327_platform_data ap152_ar8337_data = { -+ .pad0_cfg = &ap152_ar8337_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info ap152_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &ap152_ar8337_data, -+ }, -+}; -+ -+static void __init ap152_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap152_leds_gpio), -+ ap152_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, AP152_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ap152_gpio_keys), -+ ap152_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ platform_device_register(&ath79_mdio0_device); -+ -+ mdiobus_register_board_info(ap152_mdio0_info, -+ ARRAY_SIZE(ap152_mdio0_info)); -+ -+ ath79_register_wmac(art + AP152_WMAC_CALDATA_OFFSET, NULL); -+ ath79_register_pci(); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + AP152_MAC0_OFFSET, 0); -+ -+ /* GMAC0 is connected to an AR8337 switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_AP152, "AP152", "Qualcomm Atheros AP152 reference board", -+ ap152_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ap531b0.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap531b0.c -new file mode 100644 -index 0000000000..3cb2697955 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap531b0.c -@@ -0,0 +1,112 @@ -+/* -+ * Rockeetech AP531B0 11ng wireless AP board support -+ * -+ * Copyright (C) 2013 Gabor Juhos -+ * Copyright (C) 2016 Shuanglin Liu -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+ -+#define AP531B0_GPIO_LED_WLAN 12 -+#define AP531B0_GPIO_LED_STATUS 11 -+ -+#define AP531B0_GPIO_RST_BTN 17 -+ -+#define AP531B0_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define AP531B0_KEYS_DEBOUNCE_INTERVAL (3 * AP531B0_KEYS_POLL_INTERVAL) -+ -+#define AP531B0_WMAC_CALDATA_OFFSET 0x1000 -+ -+ -+static struct gpio_led ap531b0_leds_gpio[] __initdata = { -+ { -+ .name = "ap531b0:green:status", -+ .gpio = AP531B0_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, -+ { -+ .name = "ap531b0:green:wlan", -+ .gpio = AP531B0_GPIO_LED_WLAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button ap531b0_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = AP531B0_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP531B0_GPIO_RST_BTN, -+ .active_low = 1, -+ }, -+}; -+ -+ -+static void __init ap531b0_gpio_led_setup(void) -+{ -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap531b0_leds_gpio), -+ ap531b0_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, AP531B0_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ap531b0_gpio_keys), -+ ap531b0_gpio_keys); -+} -+ -+static void __init ap531b0_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *pmac; -+ -+ ath79_register_m25p80(NULL); -+ ap531b0_gpio_led_setup(); -+ ath79_register_usb(); -+ ath79_register_pci(); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ pmac = art + AP531B0_WMAC_CALDATA_OFFSET + 2; -+ ath79_init_mac(ath79_eth0_data.mac_addr, pmac, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, pmac, 2); -+ -+ ath79_register_wmac(art + AP531B0_WMAC_CALDATA_OFFSET, pmac); -+ -+ /* WAN port */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_register_eth(0); -+ -+ /* LAN ports */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_AP531B0, "AP531B0", "Rockeetech AP531B0", -+ ap531b0_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ap90q.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap90q.c -new file mode 100644 -index 0000000000..99fceca3a0 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap90q.c -@@ -0,0 +1,201 @@ -+/* -+ * Support for YunCore boards: -+ * - AP80Q/AP90Q -+ * - CPE830 -+ * -+ * Copyright (C) 2016 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+/* AP90Q */ -+#define AP90Q_GPIO_LED_WAN 4 -+#define AP90Q_GPIO_LED_WLAN 12 -+#define AP90Q_GPIO_LED_LAN 16 -+ -+#define AP90Q_GPIO_BTN_RESET 17 -+ -+#define AP90Q_KEYS_POLL_INTERVAL 20 -+#define AP90Q_KEYS_DEBOUNCE_INTERVAL (3 * AP90Q_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led ap90q_leds_gpio[] __initdata = { -+ { -+ .name = "ap90q:green:lan", -+ .gpio = AP90Q_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "ap90q:green:wan", -+ .gpio = AP90Q_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "ap90q:green:wlan", -+ .gpio = AP90Q_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button ap90q_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = AP90Q_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP90Q_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+/* CPE830 */ -+#define CPE830_GPIO_LED_LINK4 0 -+#define CPE830_GPIO_LED_LINK1 1 -+#define CPE830_GPIO_LED_LINK2 2 -+#define CPE830_GPIO_LED_LINK3 3 -+#define CPE830_GPIO_LED_WAN 4 -+#define CPE830_GPIO_LED_WLAN 12 -+#define CPE830_GPIO_LED_LAN 16 -+ -+#define CPE830_GPIO_BTN_RESET 17 -+ -+static struct gpio_led cpe830_leds_gpio[] __initdata = { -+ { -+ .name = "cpe830:green:lan", -+ .gpio = CPE830_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "cpe830:green:wan", -+ .gpio = CPE830_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "cpe830:green:wlan", -+ .gpio = CPE830_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "cpe830:green:link1", -+ .gpio = CPE830_GPIO_LED_LINK1, -+ .active_low = 1, -+ }, -+ { -+ .name = "cpe830:green:link2", -+ .gpio = CPE830_GPIO_LED_LINK2, -+ .active_low = 1, -+ }, -+ { -+ .name = "cpe830:green:link3", -+ .gpio = CPE830_GPIO_LED_LINK3, -+ .active_low = 1, -+ }, -+ { -+ .name = "cpe830:green:link4", -+ .gpio = CPE830_GPIO_LED_LINK4, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init ap90q_cpe830_common_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ -+ /* LAN */ -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(art, NULL); -+ -+ /* For LED on GPIO4 */ -+ ath79_gpio_function_disable(AR934X_GPIO_FUNC_CLK_OBS4_EN); -+ -+ ath79_gpio_direction_select(AP90Q_GPIO_LED_LAN, true); -+ ath79_gpio_direction_select(AP90Q_GPIO_LED_WAN, true); -+ ath79_gpio_direction_select(AP90Q_GPIO_LED_WLAN, true); -+ -+ /* Mute LEDs on boot */ -+ gpio_set_value(AP90Q_GPIO_LED_LAN, 1); -+ gpio_set_value(AP90Q_GPIO_LED_WAN, 1); -+ -+ ath79_gpio_output_select(AP90Q_GPIO_LED_LAN, 0); -+ ath79_gpio_output_select(AP90Q_GPIO_LED_WAN, 0); -+ ath79_gpio_output_select(AP90Q_GPIO_LED_WLAN, 0); -+ -+ ath79_register_gpio_keys_polled(-1, AP90Q_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ap90q_gpio_keys), -+ ap90q_gpio_keys); -+} -+ -+static void __init ap90q_setup(void) -+{ -+ ap90q_cpe830_common_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap90q_leds_gpio), -+ ap90q_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_AP90Q, "AP90Q", "YunCore AP80Q/AP90Q", ap90q_setup); -+ -+static void __init cpe830_setup(void) -+{ -+ ap90q_cpe830_common_setup(); -+ -+ ath79_gpio_direction_select(CPE830_GPIO_LED_LINK1, true); -+ ath79_gpio_direction_select(CPE830_GPIO_LED_LINK2, true); -+ ath79_gpio_direction_select(CPE830_GPIO_LED_LINK3, true); -+ ath79_gpio_direction_select(CPE830_GPIO_LED_LINK4, true); -+ -+ /* Mute LEDs on boot */ -+ gpio_set_value(CPE830_GPIO_LED_LINK1, 1); -+ gpio_set_value(CPE830_GPIO_LED_LINK2, 1); -+ gpio_set_value(CPE830_GPIO_LED_LINK3, 1); -+ gpio_set_value(CPE830_GPIO_LED_LINK4, 1); -+ -+ ath79_gpio_output_select(CPE830_GPIO_LED_LINK1, 0); -+ ath79_gpio_output_select(CPE830_GPIO_LED_LINK2, 0); -+ ath79_gpio_output_select(CPE830_GPIO_LED_LINK3, 0); -+ ath79_gpio_output_select(CPE830_GPIO_LED_LINK4, 0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cpe830_leds_gpio), -+ cpe830_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CPE830, "CPE830", "YunCore CPE830", cpe830_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ap91-5g.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap91-5g.c -new file mode 100644 -index 0000000000..64b9430381 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap91-5g.c -@@ -0,0 +1,118 @@ -+/* -+ * ALFA Network AP91-5G board support -+ * -+ * Copyright (C) 2018 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+ -+#define AP91_5G_GPIO_LED_LAN 17 -+#define AP91_5G_GPIO_LED_SIGNAL1 12 -+#define AP91_5G_GPIO_LED_SIGNAL2 8 -+#define AP91_5G_GPIO_LED_SIGNAL3 6 -+#define AP91_5G_GPIO_LED_SIGNAL4 7 -+ -+#define AP91_5G_GPIO_WDT_EN 1 -+#define AP91_5G_GPIO_WDT_IN 0 -+ -+#define AP91_5G_GPIO_BTN_RESET 11 -+ -+#define AP91_5G_KEYS_POLL_INTERVAL 20 -+#define AP91_5G_KEYS_DEBOUNCE_INTERVAL (3 * AP91_5G_KEYS_POLL_INTERVAL) -+ -+#define AP91_5G_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led ap91_5g_leds_gpio[] __initdata = { -+ { -+ .name = "ap91-5g:green:lan", -+ .gpio = AP91_5G_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "ap91-5g:red:signal1", -+ .gpio = AP91_5G_GPIO_LED_SIGNAL1, -+ .active_low = 1, -+ }, { -+ .name = "ap91-5g:orange:signal2", -+ .gpio = AP91_5G_GPIO_LED_SIGNAL2, -+ .active_low = 1, -+ }, { -+ .name = "ap91-5g:green:signal3", -+ .gpio = AP91_5G_GPIO_LED_SIGNAL3, -+ .active_low = 1, -+ }, { -+ .name = "ap91-5g:green:signal4", -+ .gpio = AP91_5G_GPIO_LED_SIGNAL4, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button ap91_5g_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = AP91_5G_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP91_5G_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init ap91_5g_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE, -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ gpio_set_value(AP91_5G_GPIO_LED_LAN, 1); -+ gpio_set_value(AP91_5G_GPIO_LED_SIGNAL3, 1); -+ gpio_set_value(AP91_5G_GPIO_LED_SIGNAL4, 1); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN */ -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_init_mac(ath79_eth0_data.mac_addr, art, 0); -+ ath79_register_eth(0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap91_5g_leds_gpio), -+ ap91_5g_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, AP91_5G_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ap91_5g_gpio_keys), -+ ap91_5g_gpio_keys); -+ -+ gpio_request_one(AP91_5G_GPIO_WDT_IN, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "WDT input"); -+ -+ gpio_request_one(AP91_5G_GPIO_WDT_EN, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "WDT enable"); -+ -+ ap91_pci_init(art + AP91_5G_WMAC_CALDATA_OFFSET, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_AP91_5G, "AP91-5G", "ALFA Network AP91-5G", -+ ap91_5g_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ap96.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap96.c -new file mode 100644 -index 0000000000..35120d3e2e ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap96.c -@@ -0,0 +1,142 @@ -+/* -+ * Atheros AP96 board support -+ * -+ * Copyright (C) 2009 Marco Porsch -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * Copyright (C) 2010 Atheros Communications -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+ -+#define AP96_GPIO_LED_12_GREEN 0 -+#define AP96_GPIO_LED_3_GREEN 1 -+#define AP96_GPIO_LED_2_GREEN 2 -+#define AP96_GPIO_LED_WPS_GREEN 4 -+#define AP96_GPIO_LED_5_GREEN 5 -+#define AP96_GPIO_LED_4_ORANGE 6 -+ -+/* Reset button - next to the power connector */ -+#define AP96_GPIO_BTN_RESET 3 -+/* WPS button - next to a led on right */ -+#define AP96_GPIO_BTN_WPS 8 -+ -+#define AP96_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define AP96_KEYS_DEBOUNCE_INTERVAL (3 * AP96_KEYS_POLL_INTERVAL) -+ -+#define AP96_WMAC0_MAC_OFFSET 0x120c -+#define AP96_WMAC1_MAC_OFFSET 0x520c -+#define AP96_CALDATA0_OFFSET 0x1000 -+#define AP96_CALDATA1_OFFSET 0x5000 -+ -+/* -+ * AP96 has 12 unlabeled leds in the front; these are numbered from 1 to 12 -+ * below (from left to right on the board). Led 1 seems to be on whenever the -+ * board is powered. Led 11 shows LAN link activity actity. Led 3 is orange; -+ * others are green. -+ * -+ * In addition, there is one led next to a button on the right side for WPS. -+ */ -+static struct gpio_led ap96_leds_gpio[] __initdata = { -+ { -+ .name = "ap96:green:led2", -+ .gpio = AP96_GPIO_LED_2_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "ap96:green:led3", -+ .gpio = AP96_GPIO_LED_3_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "ap96:orange:led4", -+ .gpio = AP96_GPIO_LED_4_ORANGE, -+ .active_low = 1, -+ }, { -+ .name = "ap96:green:led5", -+ .gpio = AP96_GPIO_LED_5_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "ap96:green:led12", -+ .gpio = AP96_GPIO_LED_12_GREEN, -+ .active_low = 1, -+ }, { /* next to a button on right */ -+ .name = "ap96:green:wps", -+ .gpio = AP96_GPIO_LED_WPS_GREEN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button ap96_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = AP96_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP96_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = AP96_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AP96_GPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+#define AP96_WAN_PHYMASK 0x10 -+#define AP96_LAN_PHYMASK 0x0f -+ -+static void __init ap96_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_mdio(0, ~(AP96_WAN_PHYMASK | AP96_LAN_PHYMASK)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = AP96_LAN_PHYMASK; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(0); -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, art, 1); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth1_data.phy_mask = AP96_WAN_PHYMASK; -+ -+ ath79_eth1_pll_data.pll_1000 = 0x1f000000; -+ -+ ath79_register_eth(1); -+ -+ ath79_register_usb(); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap96_leds_gpio), -+ ap96_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, AP96_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ap96_gpio_keys), -+ ap96_gpio_keys); -+ -+ ap94_pci_init(art + AP96_CALDATA0_OFFSET, -+ art + AP96_WMAC0_MAC_OFFSET, -+ art + AP96_CALDATA1_OFFSET, -+ art + AP96_WMAC1_MAC_OFFSET); -+} -+ -+MIPS_MACHINE(ATH79_MACH_AP96, "AP96", "Atheros AP96", ap96_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c25-v1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c25-v1.c -new file mode 100644 -index 0000000000..c6c6463224 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c25-v1.c -@@ -0,0 +1,227 @@ -+/* -+ * TP-Link Archer C25 v1 board support -+ * -+ * Copyright (C) 2017 Ludwig Thomeczek -+ * based on mach-archer-c60/C59-v1.c -+ * Copyright (C) 2016 Henryk Heisig -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include -+#include -+ -+#define ARCHER_C25_GPIO_SHIFT_OE 21 /* OE, Output Enable */ -+#define ARCHER_C25_GPIO_SHIFT_SER 14 /* DS, Data Serial Input */ -+#define ARCHER_C25_GPIO_SHIFT_SRCLK 15 /* SHCP, Shift Reg Clock Input */ -+#define ARCHER_C25_GPIO_SHIFT_SRCLR 19 /* MR, Master Reset */ -+#define ARCHER_C25_GPIO_SHIFT_RCLK 16 /* STCP, Storage Reg Clock Input */ -+ -+#define ARCHER_C25_74HC_GPIO_BASE 32 -+#define ARCHER_C25_74HC_GPIO_LED_WAN_AMBER (ARCHER_C25_74HC_GPIO_BASE + 4) -+#define ARCHER_C25_74HC_GPIO_LED_WAN_GREEN (ARCHER_C25_74HC_GPIO_BASE + 5) -+#define ARCHER_C25_74HC_GPIO_LED_WLAN2 (ARCHER_C25_74HC_GPIO_BASE + 6) -+#define ARCHER_C25_74HC_GPIO_LED_WLAN5 (ARCHER_C25_74HC_GPIO_BASE + 7) -+#define ARCHER_C25_74HC_GPIO_LED_LAN1 (ARCHER_C25_74HC_GPIO_BASE + 0) -+#define ARCHER_C25_74HC_GPIO_LED_LAN2 (ARCHER_C25_74HC_GPIO_BASE + 1) -+#define ARCHER_C25_74HC_GPIO_LED_LAN3 (ARCHER_C25_74HC_GPIO_BASE + 2) -+#define ARCHER_C25_74HC_GPIO_LED_LAN4 (ARCHER_C25_74HC_GPIO_BASE + 3) -+ -+#define ARCHER_C25_V1_SSR_BIT_0 0 -+#define ARCHER_C25_V1_SSR_BIT_1 1 -+#define ARCHER_C25_V1_SSR_BIT_2 2 -+#define ARCHER_C25_V1_SSR_BIT_3 3 -+#define ARCHER_C25_V1_SSR_BIT_4 4 -+#define ARCHER_C25_V1_SSR_BIT_5 5 -+#define ARCHER_C25_V1_SSR_BIT_6 6 -+#define ARCHER_C25_V1_SSR_BIT_7 7 -+ -+ -+#define ARCHER_C25_V1_KEYS_POLL_INTERVAL 20 -+#define ARCHER_C25_V1_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * ARCHER_C25_V1_KEYS_POLL_INTERVAL) -+ -+#define ARCHER_C25_V1_GPIO_BTN_RESET 1 -+#define ARCHER_C25_V1_GPIO_BTN_RFKILL 22 -+ -+#define ARCHER_C25_V1_GPIO_LED_POWER 17 -+#define ARCHER_C25_V1_GPIO_LED_WPS 2 -+ -+#define ARCHER_C25_V1_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct spi_gpio_platform_data archer_c25_v1_spi_data = { -+ .sck = ARCHER_C25_GPIO_SHIFT_SRCLK, -+ .miso = SPI_GPIO_NO_MISO, -+ .mosi = ARCHER_C25_GPIO_SHIFT_SER, -+ .num_chipselect = 1, -+}; -+ -+static u8 archer_c25_v1_ssr_initdata[] = { -+ BIT(ARCHER_C25_V1_SSR_BIT_7) | -+ BIT(ARCHER_C25_V1_SSR_BIT_6) | -+ BIT(ARCHER_C25_V1_SSR_BIT_5) | -+ BIT(ARCHER_C25_V1_SSR_BIT_4) | -+ BIT(ARCHER_C25_V1_SSR_BIT_3) | -+ BIT(ARCHER_C25_V1_SSR_BIT_2) | -+ BIT(ARCHER_C25_V1_SSR_BIT_1) -+}; -+ -+static struct gen_74x164_chip_platform_data archer_c25_v1_ssr_data = { -+ .base = ARCHER_C25_74HC_GPIO_BASE, -+ .num_registers = ARRAY_SIZE(archer_c25_v1_ssr_initdata), -+ .init_data = archer_c25_v1_ssr_initdata, -+}; -+ -+static struct platform_device archer_c25_v1_spi_device = { -+ .name = "spi_gpio", -+ .id = 1, -+ .dev = { -+ .platform_data = &archer_c25_v1_spi_data, -+ }, -+}; -+ -+static struct spi_board_info archer_c25_v1_spi_info[] = { -+ { -+ .bus_num = 1, -+ .chip_select = 0, -+ .max_speed_hz = 10000000, -+ .modalias = "74x164", -+ .platform_data = &archer_c25_v1_ssr_data, -+ .controller_data = (void *) ARCHER_C25_GPIO_SHIFT_RCLK, -+ }, -+}; -+ -+static struct gpio_led archer_c25_v1_leds_gpio[] __initdata = { -+ { -+ .name = "archer-c25-v1:green:power", -+ .gpio = ARCHER_C25_V1_GPIO_LED_POWER, -+ .active_low = 1, -+ }, { -+ .name = "archer-c25-v1:green:wps", -+ .gpio = ARCHER_C25_V1_GPIO_LED_WPS, -+ .active_low = 1, -+ }, { -+ .name = "archer-c25-v1:green:wlan2g", -+ .gpio = ARCHER_C25_74HC_GPIO_LED_WLAN2, -+ .active_low = 1, -+ }, { -+ .name = "archer-c25-v1:green:wlan5g", -+ .gpio = ARCHER_C25_74HC_GPIO_LED_WLAN5, -+ .active_low = 1, -+ }, { -+ .name = "archer-c25-v1:green:lan1", -+ .gpio = ARCHER_C25_74HC_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "archer-c25-v1:green:lan2", -+ .gpio = ARCHER_C25_74HC_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "archer-c25-v1:green:lan3", -+ .gpio = ARCHER_C25_74HC_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "archer-c25-v1:green:lan4", -+ .gpio = ARCHER_C25_74HC_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "archer-c25-v1:green:wan", -+ .gpio = ARCHER_C25_74HC_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "archer-c25-v1:amber:wan", -+ .gpio = ARCHER_C25_74HC_GPIO_LED_WAN_AMBER, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button archer_c25_v1_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ARCHER_C25_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ARCHER_C25_V1_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "RFKILL button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = ARCHER_C25_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ARCHER_C25_V1_GPIO_BTN_RFKILL, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init archer_c25_v1_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f7e0008); -+ u8 *art = (u8 *) KSEG1ADDR(0x1f7f0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ spi_register_board_info(archer_c25_v1_spi_info, -+ ARRAY_SIZE(archer_c25_v1_spi_info)); -+ -+ platform_device_register(&archer_c25_v1_spi_device); -+ -+ gpio_request_one(ARCHER_C25_GPIO_SHIFT_OE, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "LED control"); -+ -+ gpio_request_one(ARCHER_C25_GPIO_SHIFT_SRCLR, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "LED reset"); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(archer_c25_v1_leds_gpio), -+ archer_c25_v1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, ARCHER_C25_V1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(archer_c25_v1_gpio_keys), -+ archer_c25_v1_gpio_keys); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -+ -+ /* WAN port */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_register_eth(0); -+ -+ /* LAN ports */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(art + ARCHER_C25_V1_WMAC_CALDATA_OFFSET, mac); -+ ap91_pci_init(NULL, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ARCHER_C25_V1, "ARCHER-C25-V1", "TP-LINK Archer C25 v1", -+ archer_c25_v1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c59-v1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c59-v1.c -new file mode 100644 -index 0000000000..6cc40e6a7b ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c59-v1.c -@@ -0,0 +1,342 @@ -+/* -+ * TP-Link Archer C58/C59 v1 board support -+ * -+ * Copyright (C) 2017 Henryk Heisig -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+ -+#define ARCHER_C59_V1_KEYS_POLL_INTERVAL 20 -+#define ARCHER_C59_V1_KEYS_DEBOUNCE_INTERVAL (3 * ARCHER_C59_V1_KEYS_POLL_INTERVAL) -+ -+#define ARCHER_C59_V1_GPIO_BTN_RESET 21 -+#define ARCHER_C59_V1_GPIO_BTN_RFKILL 2 -+#define ARCHER_C59_V1_GPIO_BTN_WPS 1 -+ -+#define ARCHER_C59_V1_GPIO_USB_POWER 22 -+ -+#define ARCHER_C59_GPIO_SHIFT_OE 16 -+#define ARCHER_C59_GPIO_SHIFT_SER 17 -+#define ARCHER_C59_GPIO_SHIFT_SRCLK 18 -+#define ARCHER_C59_GPIO_SHIFT_SRCLR 19 -+#define ARCHER_C59_GPIO_SHIFT_RCLK 20 -+ -+#define ARCHER_C59_74HC_GPIO_BASE 32 -+#define ARCHER_C59_74HC_GPIO_LED_POWER (ARCHER_C59_74HC_GPIO_BASE + 0) -+#define ARCHER_C59_74HC_GPIO_LED_WLAN2 (ARCHER_C59_74HC_GPIO_BASE + 1) -+#define ARCHER_C59_74HC_GPIO_LED_WLAN5 (ARCHER_C59_74HC_GPIO_BASE + 2) -+#define ARCHER_C59_74HC_GPIO_LED_LAN (ARCHER_C59_74HC_GPIO_BASE + 3) -+#define ARCHER_C59_74HC_GPIO_LED_WAN_GREEN (ARCHER_C59_74HC_GPIO_BASE + 4) -+#define ARCHER_C59_74HC_GPIO_LED_WAN_AMBER (ARCHER_C59_74HC_GPIO_BASE + 5) -+#define ARCHER_C59_74HC_GPIO_LED_WPS (ARCHER_C59_74HC_GPIO_BASE + 6) -+#define ARCHER_C59_74HC_GPIO_LED_USB (ARCHER_C59_74HC_GPIO_BASE + 7) -+ -+#define ARCHER_C59_V1_SSR_BIT_0 0 -+#define ARCHER_C59_V1_SSR_BIT_1 1 -+#define ARCHER_C59_V1_SSR_BIT_2 2 -+#define ARCHER_C59_V1_SSR_BIT_3 3 -+#define ARCHER_C59_V1_SSR_BIT_4 4 -+#define ARCHER_C59_V1_SSR_BIT_5 5 -+#define ARCHER_C59_V1_SSR_BIT_6 6 -+#define ARCHER_C59_V1_SSR_BIT_7 7 -+ -+#define ARCHER_C59_V1_WMAC_CALDATA_OFFSET 0x1000 -+#define ARCHER_C59_V1_PCI_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led archer_c58_v1_leds_gpio[] __initdata = { -+ { -+ .name = "archer-c58-v1:green:power", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c58-v1:green:wlan2g", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_WLAN2, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c58-v1:green:wlan5g", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_WLAN5, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c58-v1:green:lan", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c58-v1:green:wan", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c58-v1:amber:wan", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_WAN_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c58-v1:green:wps", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led archer_c59_v1_leds_gpio[] __initdata = { -+ { -+ .name = "archer-c59-v1:green:power", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c59-v1:green:wlan2g", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_WLAN2, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c59-v1:green:wlan5g", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_WLAN5, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c59-v1:green:lan", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c59-v1:green:wan", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c59-v1:amber:wan", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_WAN_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c59-v1:green:wps", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c59-v1:green:usb", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_USB, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led archer_c59_v2_leds_gpio[] __initdata = { -+ { -+ .name = "archer-c59-v2:green:power", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c59-v2:green:wlan2g", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_WLAN2, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c59-v2:green:wlan5g", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_WLAN5, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c59-v2:green:lan", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c59-v2:green:wan", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c59-v2:amber:wan", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_WAN_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c59-v2:green:wps", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c59-v2:green:usb", -+ .gpio = ARCHER_C59_74HC_GPIO_LED_USB, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button archer_c59_v1_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ARCHER_C59_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ARCHER_C59_V1_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "RFKILL button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = ARCHER_C59_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ARCHER_C59_V1_GPIO_BTN_RFKILL, -+ .active_low = 1, -+ }, -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = ARCHER_C59_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ARCHER_C59_V1_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct spi_gpio_platform_data archer_c59_v1_spi_data = { -+ .sck = ARCHER_C59_GPIO_SHIFT_SRCLK, -+ .miso = SPI_GPIO_NO_MISO, -+ .mosi = ARCHER_C59_GPIO_SHIFT_SER, -+ .num_chipselect = 1, -+}; -+ -+static u8 archer_c59_v1_ssr_initdata[] = { -+ BIT(ARCHER_C59_V1_SSR_BIT_7) | -+ BIT(ARCHER_C59_V1_SSR_BIT_6) | -+ BIT(ARCHER_C59_V1_SSR_BIT_5) | -+ BIT(ARCHER_C59_V1_SSR_BIT_4) | -+ BIT(ARCHER_C59_V1_SSR_BIT_3) | -+ BIT(ARCHER_C59_V1_SSR_BIT_2) | -+ BIT(ARCHER_C59_V1_SSR_BIT_1) -+}; -+ -+static struct gen_74x164_chip_platform_data archer_c59_v1_ssr_data = { -+ .base = ARCHER_C59_74HC_GPIO_BASE, -+ .num_registers = ARRAY_SIZE(archer_c59_v1_ssr_initdata), -+ .init_data = archer_c59_v1_ssr_initdata, -+}; -+ -+static struct platform_device archer_c59_v1_spi_device = { -+ .name = "spi_gpio", -+ .id = 1, -+ .dev = { -+ .platform_data = &archer_c59_v1_spi_data, -+ }, -+}; -+ -+static struct spi_board_info archer_c59_v1_spi_info[] = { -+ { -+ .bus_num = 1, -+ .chip_select = 0, -+ .max_speed_hz = 10000000, -+ .modalias = "74x164", -+ .platform_data = &archer_c59_v1_ssr_data, -+ .controller_data = (void *) ARCHER_C59_GPIO_SHIFT_RCLK, -+ }, -+}; -+ -+static void __init archer_c5x_v1_setup(u32 macLocation) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(macLocation); -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ spi_register_board_info(archer_c59_v1_spi_info, -+ ARRAY_SIZE(archer_c59_v1_spi_info)); -+ platform_device_register(&archer_c59_v1_spi_device); -+ -+ ath79_register_gpio_keys_polled(-1, ARCHER_C59_V1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(archer_c59_v1_gpio_keys), -+ archer_c59_v1_gpio_keys); -+ -+ ath79_setup_qca956x_eth_cfg(QCA956X_ETH_CFG_SW_PHY_SWAP | -+ QCA956X_ETH_CFG_SW_PHY_ADDR_SWAP); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ -+ /* WAN port */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_register_eth(0); -+ -+ /* LAN ports */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_switch_data.phy_poll_mask |= BIT(0); -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(art + ARCHER_C59_V1_WMAC_CALDATA_OFFSET, mac); -+ ap91_pci_init(art + ARCHER_C59_V1_PCI_CALDATA_OFFSET, NULL); -+ -+ ath79_register_usb(); -+ gpio_request_one(ARCHER_C59_V1_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ gpio_request_one(ARCHER_C59_GPIO_SHIFT_OE, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "LED control"); -+ gpio_request_one(ARCHER_C59_GPIO_SHIFT_SRCLR, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "LED reset"); -+} -+ -+static void __init archer_c58_v1_setup(void) -+{ -+ archer_c5x_v1_setup(0x1f010008); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(archer_c58_v1_leds_gpio), -+ archer_c58_v1_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ARCHER_C58_V1, "ARCHER-C58-V1", -+ "TP-LINK Archer C58 v1", archer_c58_v1_setup); -+ -+static void __init archer_c59_v1_setup(void) -+{ -+ archer_c5x_v1_setup(0x1f010008); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(archer_c59_v1_leds_gpio), -+ archer_c59_v1_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ARCHER_C59_V1, "ARCHER-C59-V1", -+ "TP-LINK Archer C59 v1", archer_c59_v1_setup); -+ -+static void __init archer_c59_v2_setup(void) -+{ -+ archer_c5x_v1_setup(0x1f030008); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(archer_c59_v2_leds_gpio), -+ archer_c59_v2_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ARCHER_C59_V2, "ARCHER-C59-V2", -+ "TP-LINK Archer C59 v2", archer_c59_v2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c60-v1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c60-v1.c -new file mode 100644 -index 0000000000..a0839e6bca ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c60-v1.c -@@ -0,0 +1,225 @@ -+/* -+ * TP-Link Archer C60 v1 board support -+ * -+ * Copyright (C) 2017 Henryk Heisig -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+ -+#define ARCHER_C60_V1_GPIO_LED_LAN 2 -+#define ARCHER_C60_V1_GPIO_LED_POWER 16 -+#define ARCHER_C60_V1_GPIO_LED_WLAN2 17 -+#define ARCHER_C60_V1_GPIO_LED_WLAN5 18 -+#define ARCHER_C60_V1_GPIO_LED_WPS 19 -+#define ARCHER_C60_V1_GPIO_LED_WAN_GREEN 20 -+#define ARCHER_C60_V1_GPIO_LED_WAN_AMBER 22 -+ -+ -+#define ARCHER_C60_V1_KEYS_POLL_INTERVAL 20 -+#define ARCHER_C60_V1_KEYS_DEBOUNCE_INTERVAL (3 * ARCHER_C60_V1_KEYS_POLL_INTERVAL) -+ -+#define ARCHER_C60_V1_GPIO_BTN_RESET 21 -+#define ARCHER_C60_V1_GPIO_BTN_RFKILL 1 -+ -+ -+ -+#define ARCHER_C60_V1_WMAC_CALDATA_OFFSET 0x1000 -+#define ARCHER_C60_V1_PCI_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led archer_c60_v1_leds_gpio[] __initdata = { -+ { -+ .name = "archer-c60-v1:green:power", -+ .gpio = ARCHER_C60_V1_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c60-v1:green:wlan2g", -+ .gpio = ARCHER_C60_V1_GPIO_LED_WLAN2, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c60-v1:green:wlan5g", -+ .gpio = ARCHER_C60_V1_GPIO_LED_WLAN5, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c60-v1:green:lan", -+ .gpio = ARCHER_C60_V1_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c60-v1:green:wan", -+ .gpio = ARCHER_C60_V1_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c60-v1:amber:wan", -+ .gpio = ARCHER_C60_V1_GPIO_LED_WAN_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c60-v1:green:wps", -+ .gpio = ARCHER_C60_V1_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led archer_c60_v2_leds_gpio[] __initdata = { -+ { -+ .name = "archer-c60-v2:green:power", -+ .gpio = ARCHER_C60_V1_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c60-v2:green:wlan2g", -+ .gpio = ARCHER_C60_V1_GPIO_LED_WLAN2, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c60-v2:green:wlan5g", -+ .gpio = ARCHER_C60_V1_GPIO_LED_WLAN5, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c60-v2:green:lan", -+ .gpio = ARCHER_C60_V1_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c60-v2:green:wan", -+ .gpio = ARCHER_C60_V1_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c60-v2:amber:wan", -+ .gpio = ARCHER_C60_V1_GPIO_LED_WAN_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "archer-c60-v2:green:wps", -+ .gpio = ARCHER_C60_V1_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button archer_c60_v1_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ARCHER_C60_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ARCHER_C60_V1_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "RFKILL button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = ARCHER_C60_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ARCHER_C60_V1_GPIO_BTN_RFKILL, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init archer_c60_v1_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f010008); -+ u8 *art = (u8 *) KSEG1ADDR(0x1f7f0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(archer_c60_v1_leds_gpio), -+ archer_c60_v1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, ARCHER_C60_V1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(archer_c60_v1_gpio_keys), -+ archer_c60_v1_gpio_keys); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ -+ /* WAN port */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_register_eth(0); -+ -+ /* LAN ports */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(art + ARCHER_C60_V1_WMAC_CALDATA_OFFSET, mac); -+ ap91_pci_init(art + ARCHER_C60_V1_PCI_CALDATA_OFFSET, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ARCHER_C60_V1, "ARCHER-C60-V1", -+ "TP-LINK Archer C60 v1", archer_c60_v1_setup); -+ -+static void __init archer_c60_v2_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fb08); -+ u8 *art = (u8 *) KSEG1ADDR(0x1f7f0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(archer_c60_v2_leds_gpio), -+ archer_c60_v2_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, ARCHER_C60_V1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(archer_c60_v1_gpio_keys), -+ archer_c60_v1_gpio_keys); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ -+ /* WAN port */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_register_eth(0); -+ -+ /* LAN ports */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(art + ARCHER_C60_V1_WMAC_CALDATA_OFFSET, mac); -+ ap91_pci_init(art + ARCHER_C60_V1_PCI_CALDATA_OFFSET, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ARCHER_C60_V2, "ARCHER-C60-V2", -+ "TP-LINK Archer C60 v2", archer_c60_v2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c7-v4.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c7-v4.c -new file mode 100644 -index 0000000000..ee9ce49bcf ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c7-v4.c -@@ -0,0 +1,260 @@ -+ -+/* -+ * Atheros ARCHER_C7 reference board support -+ * -+ * Copyright (c) 2017 Felix Fietkau -+ * Copyright (c) 2014 The Linux Foundation. All rights reserved. -+ * Copyright (c) 2012 Gabor Juhos -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+#include "pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+ -+ -+#define ARCHER_C7_GPIO_SHIFT_OE 1 -+#define ARCHER_C7_GPIO_SHIFT_SER 14 -+#define ARCHER_C7_GPIO_SHIFT_SRCLK 15 -+#define ARCHER_C7_GPIO_SHIFT_RCLK 16 -+#define ARCHER_C7_GPIO_SHIFT_SRCLR 21 -+ -+#define ARCHER_C7_GPIO_BTN_RESET 5 -+#define ARCHER_C7_GPIO_BTN_WPS_WIFI 2 -+ -+#define ARCHER_C7_GPIO_LED_WLAN5 9 -+#define ARCHER_C7_GPIO_LED_POWER 6 -+#define ARCHER_C7_GPIO_LED_USB1 7 -+#define ARCHER_C7_GPIO_LED_USB2 8 -+ -+#define ARCHER_C7_74HC_GPIO_BASE 32 -+#define ARCHER_C7_GPIO_LED_WPS (ARCHER_C7_74HC_GPIO_BASE + 0) -+#define ARCHER_C7_GPIO_LED_LAN1 (ARCHER_C7_74HC_GPIO_BASE + 1) -+#define ARCHER_C7_GPIO_LED_LAN2 (ARCHER_C7_74HC_GPIO_BASE + 2) -+#define ARCHER_C7_GPIO_LED_LAN3 (ARCHER_C7_74HC_GPIO_BASE + 3) -+#define ARCHER_C7_GPIO_LED_LAN4 (ARCHER_C7_74HC_GPIO_BASE + 4) -+#define ARCHER_C7_GPIO_LED_WAN_GREEN (ARCHER_C7_74HC_GPIO_BASE + 5) -+#define ARCHER_C7_GPIO_LED_WAN_AMBER (ARCHER_C7_74HC_GPIO_BASE + 6) -+#define ARCHER_C7_GPIO_LED_WLAN2 (ARCHER_C7_74HC_GPIO_BASE + 7) -+ -+#define ARCHER_C7_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define ARCHER_C7_KEYS_DEBOUNCE_INTERVAL (3 * ARCHER_C7_KEYS_POLL_INTERVAL) -+ -+#define ARCHER_C7_MAC0_OFFSET 0 -+#define ARCHER_C7_MAC1_OFFSET 6 -+#define ARCHER_C7_WMAC_CALDATA_OFFSET 0x1000 -+ -+#define ARCHER_C7_GPIO_MDC 3 -+#define ARCHER_C7_GPIO_MDIO 4 -+ -+static struct spi_gpio_platform_data archer_c7_v4_spi_data = { -+ .sck = ARCHER_C7_GPIO_SHIFT_SRCLK, -+ .miso = SPI_GPIO_NO_MISO, -+ .mosi = ARCHER_C7_GPIO_SHIFT_SER, -+ .num_chipselect = 1, -+}; -+ -+static u8 archer_c7_v4_ssr_initdata = 0xff; -+ -+static struct gen_74x164_chip_platform_data archer_c7_v4_ssr_data = { -+ .base = ARCHER_C7_74HC_GPIO_BASE, -+ .num_registers = 1, -+ .init_data = &archer_c7_v4_ssr_initdata, -+}; -+ -+static struct platform_device archer_c7_v4_spi_device = { -+ .name = "spi_gpio", -+ .id = 1, -+ .dev = { -+ .platform_data = &archer_c7_v4_spi_data, -+ }, -+}; -+ -+static struct spi_board_info archer_c7_v4_spi_info[] = { -+ { -+ .bus_num = 1, -+ .chip_select = 0, -+ .max_speed_hz = 10000000, -+ .modalias = "74x164", -+ .platform_data = &archer_c7_v4_ssr_data, -+ .controller_data = (void *) ARCHER_C7_GPIO_SHIFT_RCLK, -+ }, -+}; -+ -+static struct gpio_led archer_c7_v4_leds_gpio[] __initdata = { -+ { -+ .name = "archer-c7-v4:green:power", -+ .gpio = ARCHER_C7_GPIO_LED_POWER, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v4:green:wps", -+ .gpio = ARCHER_C7_GPIO_LED_WPS, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v4:green:wlan2g", -+ .gpio = ARCHER_C7_GPIO_LED_WLAN2, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v4:green:wlan5g", -+ .gpio = ARCHER_C7_GPIO_LED_WLAN5, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v4:green:lan1", -+ .gpio = ARCHER_C7_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v4:green:lan2", -+ .gpio = ARCHER_C7_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v4:green:lan3", -+ .gpio = ARCHER_C7_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v4:green:lan4", -+ .gpio = ARCHER_C7_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v4:green:wan", -+ .gpio = ARCHER_C7_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v4:amber:wan", -+ .gpio = ARCHER_C7_GPIO_LED_WAN_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v4:green:usb1", -+ .gpio = ARCHER_C7_GPIO_LED_USB1, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v4:green:usb2", -+ .gpio = ARCHER_C7_GPIO_LED_USB2, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button archer_c7_v4_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS and WIFI button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = ARCHER_C7_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ARCHER_C7_GPIO_BTN_WPS_WIFI, -+ .active_low = 1, -+ }, -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ARCHER_C7_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ARCHER_C7_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg archer_c7_v4_ar8337_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+static struct ar8327_platform_data archer_c7_v4_ar8337_data = { -+ .pad0_cfg = &archer_c7_v4_ar8337_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info archer_c7_v4_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &archer_c7_v4_ar8337_data, -+ }, -+}; -+ -+ -+static void __init archer_c7_v4_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac = (u8 *) KSEG1ADDR(0x1ff00008); -+ -+ ath79_register_m25p80(NULL); -+ -+ spi_register_board_info(archer_c7_v4_spi_info, -+ ARRAY_SIZE(archer_c7_v4_spi_info)); -+ -+ platform_device_register(&archer_c7_v4_spi_device); -+ -+ gpio_request_one(ARCHER_C7_GPIO_SHIFT_OE, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "LED control"); -+ -+ gpio_request_one(ARCHER_C7_GPIO_SHIFT_SRCLR, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "LED reset"); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(archer_c7_v4_leds_gpio), -+ archer_c7_v4_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, ARCHER_C7_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(archer_c7_v4_gpio_keys), -+ archer_c7_v4_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_gpio_output_select(ARCHER_C7_GPIO_MDC, QCA956X_GPIO_OUT_MUX_GE0_MDC); -+ ath79_gpio_output_select(ARCHER_C7_GPIO_MDIO, QCA956X_GPIO_OUT_MUX_GE0_MDO); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(archer_c7_v4_mdio0_info, -+ ARRAY_SIZE(archer_c7_v4_mdio0_info)); -+ -+ ath79_register_wmac(art + ARCHER_C7_WMAC_CALDATA_OFFSET, mac); -+ ath79_register_pci(); -+ -+ /* GMAC0 is connected to an AR8337 switch */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ARCHER_C7_V4, "ARCHER-C7-V4", "TP-LINK Archer C7 v4", -+ archer_c7_v4_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c7-v5.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c7-v5.c -new file mode 100644 -index 0000000000..0dec008314 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c7-v5.c -@@ -0,0 +1,207 @@ -+/* -+ * Atheros ARCHER_C7 reference board support -+ * -+ * Copyright (c) 2018 Arvid E. Picciani -+ * Copyright (c) 2017 Felix Fietkau -+ * Copyright (c) 2014 The Linux Foundation. All rights reserved. -+ * Copyright (c) 2012 Gabor Juhos -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+#include "pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+ -+ -+#define ARCHER_C7_GPIO_BTN_RESET 5 -+#define ARCHER_C7_GPIO_BTN_WPS_WIFI 2 -+ -+#define ARCHER_C7_GPIO_LED_WLAN5 9 -+#define ARCHER_C7_GPIO_LED_POWER 6 -+#define ARCHER_C7_GPIO_LED_USB 7 -+#define ARCHER_C7_GPIO_LED_WPS 1 -+#define ARCHER_C7_GPIO_LED_LAN1 8 -+#define ARCHER_C7_GPIO_LED_LAN2 17 -+#define ARCHER_C7_GPIO_LED_LAN3 16 -+#define ARCHER_C7_GPIO_LED_LAN4 15 -+#define ARCHER_C7_GPIO_LED_WAN_GREEN 21 -+#define ARCHER_C7_GPIO_LED_WAN_AMBER 20 -+#define ARCHER_C7_GPIO_LED_WLAN2 14 -+#define ARCHER_C7_GPIO_USB_PWR 19 -+ -+#define ARCHER_C7_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define ARCHER_C7_KEYS_DEBOUNCE_INTERVAL (3 * ARCHER_C7_KEYS_POLL_INTERVAL) -+ -+#define ARCHER_C7_MAC0_OFFSET 0 -+#define ARCHER_C7_MAC1_OFFSET 6 -+#define ARCHER_C7_WMAC_CALDATA_OFFSET 0x1000 -+ -+#define ARCHER_C7_GPIO_MDC 3 -+#define ARCHER_C7_GPIO_MDIO 4 -+ -+static struct gpio_led archer_c7_v5_leds_gpio[] __initdata = { -+ { -+ .name = "archer-c7-v5:green:power", -+ .gpio = ARCHER_C7_GPIO_LED_POWER, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v5:green:wps", -+ .gpio = ARCHER_C7_GPIO_LED_WPS, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v5:green:wlan2g", -+ .gpio = ARCHER_C7_GPIO_LED_WLAN2, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v5:green:wlan5g", -+ .gpio = ARCHER_C7_GPIO_LED_WLAN5, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v5:green:lan1", -+ .gpio = ARCHER_C7_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v5:green:lan2", -+ .gpio = ARCHER_C7_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v5:green:lan3", -+ .gpio = ARCHER_C7_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v5:green:lan4", -+ .gpio = ARCHER_C7_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v5:green:wan", -+ .gpio = ARCHER_C7_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v5:amber:wan", -+ .gpio = ARCHER_C7_GPIO_LED_WAN_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "archer-c7-v5:green:usb", -+ .gpio = ARCHER_C7_GPIO_LED_USB, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button archer_c7_v5_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS and WIFI button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = ARCHER_C7_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ARCHER_C7_GPIO_BTN_WPS_WIFI, -+ .active_low = 1, -+ }, -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ARCHER_C7_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ARCHER_C7_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+ -+static struct ar8327_pad_cfg archer_c7_v5_ar8337_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+static struct ar8327_platform_data archer_c7_v5_ar8337_data = { -+ .pad0_cfg = &archer_c7_v5_ar8337_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info archer_c7_v5_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &archer_c7_v5_ar8337_data, -+ }, -+}; -+ -+ -+static void __init archer_c7_v5_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1f050000); -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f060008); -+ -+ ath79_register_m25p80(NULL); -+ -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(archer_c7_v5_leds_gpio), -+ archer_c7_v5_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, ARCHER_C7_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(archer_c7_v5_gpio_keys), -+ archer_c7_v5_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_gpio_output_select(ARCHER_C7_GPIO_MDC, QCA956X_GPIO_OUT_MUX_GE0_MDC); -+ ath79_gpio_output_select(ARCHER_C7_GPIO_MDIO, QCA956X_GPIO_OUT_MUX_GE0_MDO); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(archer_c7_v5_mdio0_info, -+ ARRAY_SIZE(archer_c7_v5_mdio0_info)); -+ -+ gpio_request_one(ARCHER_C7_GPIO_USB_PWR, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ -+ ath79_register_wmac(art + ARCHER_C7_WMAC_CALDATA_OFFSET, mac); -+ ath79_register_pci(); -+ -+ /* GMAC0 is connected to an AR8337 switch */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ARCHER_C7_V5, "ARCHER-C7-V5", "TP-LINK Archer C7 v5", -+ archer_c7_v5_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c7.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c7.c -new file mode 100644 -index 0000000000..53c539f85a ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-archer-c7.c -@@ -0,0 +1,349 @@ -+/* -+ * TP-LINK Archer C5/C7/TL-WDR4900 v2 board support -+ * -+ * Copyright (c) 2013 Gabor Juhos -+ * Copyright (c) 2014 施康成 -+ * Copyright (c) 2014 Imre Kaloz -+ * -+ * Based on the Qualcomm Atheros AP135/AP136 reference board support code -+ * Copyright (c) 2012 Qualcomm Atheros -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define ARCHER_C7_GPIO_LED_WLAN2G 12 -+#define ARCHER_C7_GPIO_LED_SYSTEM 14 -+#define ARCHER_C7_GPIO_LED_QSS 15 -+#define ARCHER_C7_GPIO_LED_WLAN5G 17 -+#define ARCHER_C7_GPIO_LED_USB1 18 -+#define ARCHER_C7_GPIO_LED_USB2 19 -+ -+#define ARCHER_C7_GPIO_BTN_RFKILL 23 -+#define ARCHER_C7_V2_GPIO_BTN_RFKILL 23 -+#define ARCHER_C7_GPIO_BTN_RESET 16 -+ -+#define ARCHER_C7_GPIO_USB1_POWER 22 -+#define ARCHER_C7_GPIO_USB2_POWER 21 -+ -+#define ARCHER_C7_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define ARCHER_C7_KEYS_DEBOUNCE_INTERVAL (3 * ARCHER_C7_KEYS_POLL_INTERVAL) -+ -+#define ARCHER_C7_WMAC_CALDATA_OFFSET 0x1000 -+#define ARCHER_C7_PCIE_CALDATA_OFFSET 0x5000 -+ -+static const char *archer_c7_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data archer_c7_flash_data = { -+ .part_probes = archer_c7_part_probes, -+}; -+ -+static struct gpio_led archer_c7_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:qss", -+ .gpio = ARCHER_C7_GPIO_LED_QSS, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:system", -+ .gpio = ARCHER_C7_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:wlan2g", -+ .gpio = ARCHER_C7_GPIO_LED_WLAN2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:wlan5g", -+ .gpio = ARCHER_C7_GPIO_LED_WLAN5G, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:usb1", -+ .gpio = ARCHER_C7_GPIO_LED_USB1, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:usb2", -+ .gpio = ARCHER_C7_GPIO_LED_USB2, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led wdr4900_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:blue:qss", -+ .gpio = ARCHER_C7_GPIO_LED_QSS, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:blue:system", -+ .gpio = ARCHER_C7_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:blue:wlan2g", -+ .gpio = ARCHER_C7_GPIO_LED_WLAN2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:usb1", -+ .gpio = ARCHER_C7_GPIO_LED_USB1, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:usb2", -+ .gpio = ARCHER_C7_GPIO_LED_USB2, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button archer_c7_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = ARCHER_C7_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ARCHER_C7_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "RFKILL switch", -+ .type = EV_SW, -+ .code = KEY_RFKILL, -+ .debounce_interval = ARCHER_C7_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ARCHER_C7_GPIO_BTN_RFKILL, -+ }, -+}; -+ -+static struct gpio_keys_button archer_c7_v2_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = ARCHER_C7_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ARCHER_C7_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "RFKILL switch", -+ .type = EV_SW, -+ .code = KEY_RFKILL, -+ .debounce_interval = ARCHER_C7_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ARCHER_C7_V2_GPIO_BTN_RFKILL, -+ }, -+}; -+ -+static struct gpio_keys_button wdr4900_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = ARCHER_C7_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ARCHER_C7_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static const struct ar8327_led_info archer_c7_leds_ar8327[] = { -+ AR8327_LED_INFO(PHY0_0, HW, "tp-link:green:wan"), -+ AR8327_LED_INFO(PHY1_0, HW, "tp-link:green:lan1"), -+ AR8327_LED_INFO(PHY2_0, HW, "tp-link:green:lan2"), -+ AR8327_LED_INFO(PHY3_0, HW, "tp-link:green:lan3"), -+ AR8327_LED_INFO(PHY4_0, HW, "tp-link:green:lan4"), -+}; -+ -+/* GMAC0 of the AR8327 switch is connected to the QCA9558 SoC via SGMII */ -+static struct ar8327_pad_cfg archer_c7_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+/* GMAC6 of the AR8327 switch is connected to the QCA9558 SoC via RGMII */ -+static struct ar8327_pad_cfg archer_c7_ar8327_pad6_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_led_cfg archer_c7_ar8327_led_cfg = { -+ .led_ctrl0 = 0xc737c737, -+ .led_ctrl1 = 0x00000000, -+ .led_ctrl2 = 0x00000000, -+ .led_ctrl3 = 0x0030c300, -+ .open_drain = false, -+}; -+ -+static struct ar8327_platform_data archer_c7_ar8327_data = { -+ .pad0_cfg = &archer_c7_ar8327_pad0_cfg, -+ .pad6_cfg = &archer_c7_ar8327_pad6_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .port6_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &archer_c7_ar8327_led_cfg, -+ .num_leds = ARRAY_SIZE(archer_c7_leds_ar8327), -+ .leds = archer_c7_leds_ar8327, -+}; -+ -+static struct mdio_board_info archer_c7_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &archer_c7_ar8327_data, -+ }, -+}; -+ -+static void __init common_setup(bool pcie_slot) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 tmpmac[ETH_ALEN]; -+ u8 tmpmac2[ETH_ALEN]; -+ -+ ath79_register_m25p80(&archer_c7_flash_data); -+ -+ if (pcie_slot) { -+ ath79_register_wmac(art + ARCHER_C7_WMAC_CALDATA_OFFSET, mac); -+ ath79_register_pci(); -+ } else { -+ ath79_init_mac(tmpmac, mac, -1); -+ ath79_register_wmac(art + ARCHER_C7_WMAC_CALDATA_OFFSET, tmpmac); -+ -+ ath79_init_mac(tmpmac2, mac, -2); -+ ap9x_pci_setup_wmac_led_pin(0, 0); -+ ap91_pci_init(art + ARCHER_C7_PCIE_CALDATA_OFFSET, tmpmac2); -+ } -+ -+ mdiobus_register_board_info(archer_c7_mdio0_info, -+ ARRAY_SIZE(archer_c7_mdio0_info)); -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ /* GMAC0 is connected to the RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x56000000; -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_register_eth(1); -+ -+ gpio_request_one(ARCHER_C7_GPIO_USB1_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB1 power"); -+ gpio_request_one(ARCHER_C7_GPIO_USB2_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB2 power"); -+ ath79_register_usb(); -+} -+ -+static void __init archer_c5_setup(void) -+{ -+ ath79_register_gpio_keys_polled(-1, ARCHER_C7_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(archer_c7_gpio_keys), -+ archer_c7_gpio_keys); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(archer_c7_leds_gpio), -+ archer_c7_leds_gpio); -+ common_setup(true); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ARCHER_C5, "ARCHER-C5", "TP-LINK Archer C5", -+ archer_c5_setup); -+ -+static void __init archer_c7_setup(void) -+{ -+ ath79_register_gpio_keys_polled(-1, ARCHER_C7_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(archer_c7_gpio_keys), -+ archer_c7_gpio_keys); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(archer_c7_leds_gpio), -+ archer_c7_leds_gpio); -+ common_setup(true); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ARCHER_C7, "ARCHER-C7", "TP-LINK Archer C7", -+ archer_c7_setup); -+ -+static void __init archer_c7_v2_setup(void) -+{ -+ ath79_register_gpio_keys_polled(-1, ARCHER_C7_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(archer_c7_v2_gpio_keys), -+ archer_c7_v2_gpio_keys); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(archer_c7_leds_gpio), -+ archer_c7_leds_gpio); -+ common_setup(true); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ARCHER_C7_V2, "ARCHER-C7-V2", "TP-LINK Archer C7", -+ archer_c7_v2_setup); -+ -+static void __init tl_wdr4900_v2_setup(void) -+{ -+ ath79_register_gpio_keys_polled(-1, ARCHER_C7_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wdr4900_gpio_keys), -+ wdr4900_gpio_keys); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wdr4900_leds_gpio), -+ wdr4900_leds_gpio); -+ common_setup(false); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WDR4900_V2, "TL-WDR4900-v2", "TP-LINK TL-WDR4900 v2", -+ tl_wdr4900_v2_setup) -+ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-arduino-yun.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-arduino-yun.c -new file mode 100644 -index 0000000000..8ab07d514b ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-arduino-yun.c -@@ -0,0 +1,156 @@ -+/* -+ * Arduino Yun support -+ * -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * Copyright (C) 2015 Hauke Mehrtens -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include -+#include -+#include -+#include "common.h" -+ -+// Uncomment to have reset on gpio18 instead of gipo7 -+#define DS2_B -+ -+#define DS_GPIO_LED_WLAN 0 -+#define DS_GPIO_LED_USB 1 -+ -+#define DS_GPIO_OE 21 -+#define DS_GPIO_AVR_RESET 18 -+ -+// Maintained to have the console in the previous version of DS2 working -+#define DS_GPIO_AVR_RESET_DS2 7 -+ -+#define DS_GPIO_OE2 22 -+#define DS_GPIO_UART_ENA 23 -+#define DS_GPIO_CONF_BTN 20 -+ -+#define DS_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DS_KEYS_DEBOUNCE_INTERVAL (3 * DS_KEYS_POLL_INTERVAL) -+ -+#define DS_MAC0_OFFSET 0x0000 -+#define DS_MAC1_OFFSET 0x0006 -+#define DS_CALDATA_OFFSET 0x1000 -+#define DS_WMAC_MAC_OFFSET 0x1002 -+ -+ -+static struct gpio_led ds_leds_gpio[] __initdata = { -+ { -+ .name = "arduino:white:usb", -+ .gpio = DS_GPIO_LED_USB, -+ .active_low = 0, -+ }, -+ { -+ .name = "arduino:blue:wlan", -+ .gpio = DS_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button ds_gpio_keys[] __initdata = { -+ { -+ .desc = "configuration button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DS_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DS_GPIO_CONF_BTN, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init ds_common_setup(void) -+{ -+ static u8 mac[6]; -+ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ ath79_register_m25p80(NULL); -+ -+ if (ar93xx_wmac_read_mac_address(mac)) { -+ ath79_register_wmac(NULL, NULL); -+ } else { -+ ath79_register_wmac(art + DS_CALDATA_OFFSET, -+ art + DS_WMAC_MAC_OFFSET); -+ memcpy(mac, art + DS_WMAC_MAC_OFFSET, sizeof(mac)); -+ } -+ -+ mac[3] |= 0x08; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ -+ mac[3] &= 0xF7; -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN ports */ -+ ath79_register_eth(1); -+ -+ /* WAN port */ -+ ath79_register_eth(0); -+} -+ -+static void __init ds_setup(void) -+{ -+ u32 t; -+ -+ ds_common_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ds_leds_gpio), -+ ds_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, DS_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ds_gpio_keys), -+ ds_gpio_keys); -+ ath79_register_usb(); -+ -+ /* use the swtich_led directly form sysfs */ -+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN); -+ -+ //Disable the Function for some pins to have GPIO functionality active -+ // GPIO6-7-8 and GPIO11 -+ ath79_gpio_function_setup(AR933X_GPIO_FUNC_JTAG_DISABLE | AR933X_GPIO_FUNC_I2S_MCK_EN, 0); -+ -+ ath79_gpio_function2_setup(AR933X_GPIO_FUNC2_JUMPSTART_DISABLE, 0); -+ -+ printk("Setting DogStick2 GPIO\n"); -+ -+ t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); -+ t |= AR933X_BOOTSTRAP_MDIO_GPIO_EN; -+ ath79_reset_wr(AR933X_RESET_REG_BOOTSTRAP, t); -+ -+ // Put the avr reset to high -+ if (gpio_request_one(DS_GPIO_AVR_RESET_DS2, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, "OE-1") != 0) -+ printk("Error setting GPIO OE\n"); -+ gpio_unexport(DS_GPIO_AVR_RESET_DS2); -+ gpio_free(DS_GPIO_AVR_RESET_DS2); -+ -+ // enable OE of level shifter -+ if (gpio_request_one(DS_GPIO_OE, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, "OE-1") != 0) -+ printk("Error setting GPIO OE\n"); -+ -+ if (gpio_request_one(DS_GPIO_UART_ENA, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, "UART-ENA") != 0) -+ printk("Error setting GPIO Uart Enable\n"); -+ -+ // enable OE of level shifter -+ if (gpio_request_one(DS_GPIO_OE2, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, "OE-2") != 0) -+ printk("Error setting GPIO OE2\n"); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ARDUINO_YUN, "Yun", "Arduino Yun", ds_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-aw-nr580.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-aw-nr580.c -new file mode 100644 -index 0000000000..281129b787 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-aw-nr580.c -@@ -0,0 +1,107 @@ -+/* -+ * AzureWave AW-NR580 board support -+ * -+ * Copyright (C) 2008-2012 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-m25p80.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define AW_NR580_GPIO_LED_READY_RED 0 -+#define AW_NR580_GPIO_LED_WLAN 1 -+#define AW_NR580_GPIO_LED_READY_GREEN 2 -+#define AW_NR580_GPIO_LED_WPS_GREEN 4 -+#define AW_NR580_GPIO_LED_WPS_AMBER 5 -+ -+#define AW_NR580_GPIO_BTN_WPS 3 -+#define AW_NR580_GPIO_BTN_RESET 11 -+ -+#define AW_NR580_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define AW_NR580_KEYS_DEBOUNCE_INTERVAL (3 * AW_NR580_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led aw_nr580_leds_gpio[] __initdata = { -+ { -+ .name = "aw-nr580:red:ready", -+ .gpio = AW_NR580_GPIO_LED_READY_RED, -+ .active_low = 0, -+ }, { -+ .name = "aw-nr580:green:ready", -+ .gpio = AW_NR580_GPIO_LED_READY_GREEN, -+ .active_low = 0, -+ }, { -+ .name = "aw-nr580:green:wps", -+ .gpio = AW_NR580_GPIO_LED_WPS_GREEN, -+ .active_low = 0, -+ }, { -+ .name = "aw-nr580:amber:wps", -+ .gpio = AW_NR580_GPIO_LED_WPS_AMBER, -+ .active_low = 0, -+ }, { -+ .name = "aw-nr580:green:wlan", -+ .gpio = AW_NR580_GPIO_LED_WLAN, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button aw_nr580_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = AW_NR580_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AW_NR580_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = AW_NR580_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AW_NR580_GPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static const char *aw_nr580_part_probes[] = { -+ "RedBoot", -+ NULL, -+}; -+ -+static struct flash_platform_data aw_nr580_flash_data = { -+ .part_probes = aw_nr580_part_probes, -+}; -+ -+static void __init aw_nr580_setup(void) -+{ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(0); -+ -+ ath79_register_pci(); -+ -+ ath79_register_m25p80(&aw_nr580_flash_data); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(aw_nr580_leds_gpio), -+ aw_nr580_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, AW_NR580_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(aw_nr580_gpio_keys), -+ aw_nr580_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_AW_NR580, "AW-NR580", "AzureWave AW-NR580", -+ aw_nr580_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-bhr-4grv2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-bhr-4grv2.c -new file mode 100644 -index 0000000000..1630845cf8 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-bhr-4grv2.c -@@ -0,0 +1,171 @@ -+/* -+ * Buffalo BHR-4GRV2 board support -+ * -+ * Copyright (c) 2012 Qualcomm Atheros -+ * Copyright (c) 2012-2013 Gabor Juhos -+ * Copyright (c) 2016 FUKAUMI Naoki -+ * -+ * Based on mach-ap136.c and mach-wzr-450hp2.c -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+ -+#define BHR_4GRV2_GPIO_LED_VPN_RED 3 -+#define BHR_4GRV2_GPIO_LED_VPN_GREEN 18 -+#define BHR_4GRV2_GPIO_LED_POWER_GREEN 19 -+#define BHR_4GRV2_GPIO_LED_DIAG_RED 20 -+ -+#define BHR_4GRV2_GPIO_BTN_RESET 17 -+#define BHR_4GRV2_GPIO_BTN_ECO 21 -+ -+#define BHR_4GRV2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define BHR_4GRV2_KEYS_DEBOUNCE_INTERVAL (3 * BHR_4GRV2_KEYS_POLL_INTERVAL) -+#define BHR_4GRV2_MAC0_OFFSET 0 -+#define BHR_4GRV2_MAC1_OFFSET 6 -+ -+static struct gpio_led bhr_4grv2_leds_gpio[] __initdata = { -+ { -+ .name = "buffalo:red:vpn", -+ .gpio = BHR_4GRV2_GPIO_LED_VPN_RED, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:green:vpn", -+ .gpio = BHR_4GRV2_GPIO_LED_VPN_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:green:power", -+ .gpio = BHR_4GRV2_GPIO_LED_POWER_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:red:diag", -+ .gpio = BHR_4GRV2_GPIO_LED_DIAG_RED, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button bhr_4grv2_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = BHR_4GRV2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = BHR_4GRV2_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "ECO button", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = BHR_4GRV2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = BHR_4GRV2_GPIO_BTN_ECO, -+ .active_low = 1, -+ }, -+}; -+ -+/* GMAC0 of the AR8327 switch is connected to GMAC1 via SGMII */ -+static struct ar8327_pad_cfg bhr_4grv2_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+/* GMAC6 of the AR8327 switch is connected to GMAC0 via RGMII */ -+static struct ar8327_pad_cfg bhr_4grv2_ar8327_pad6_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_platform_data bhr_4grv2_ar8327_data = { -+ .pad0_cfg = &bhr_4grv2_ar8327_pad0_cfg, -+ .pad6_cfg = &bhr_4grv2_ar8327_pad6_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .port6_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info bhr_4grv2_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &bhr_4grv2_ar8327_data, -+ }, -+}; -+ -+static void __init bhr_4grv2_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(bhr_4grv2_leds_gpio), -+ bhr_4grv2_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, BHR_4GRV2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(bhr_4grv2_gpio_keys), -+ bhr_4grv2_gpio_keys); -+ -+ mdiobus_register_board_info(bhr_4grv2_mdio0_info, -+ ARRAY_SIZE(bhr_4grv2_mdio0_info)); -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ /* GMAC0 is connected to the RGMII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x56000000; -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + BHR_4GRV2_MAC0_OFFSET, 0); -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + BHR_4GRV2_MAC1_OFFSET, 0); -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_BHR_4GRV2, "BHR-4GRV2", -+ "Buffalo BHR-4GRV2", bhr_4grv2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-bhu-bxu2000n2-a.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-bhu-bxu2000n2-a.c -new file mode 100644 -index 0000000000..8d7c6112d7 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-bhu-bxu2000n2-a.c -@@ -0,0 +1,120 @@ -+/* -+ * BHU BXU2000n-2 A1 board support -+ * -+ * Copyright (C) 2013 Terry Yang -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define BHU_BXU2000N2_A1_GPIO_LED_WLAN 13 -+#define BHU_BXU2000N2_A1_GPIO_LED_WAN 19 -+#define BHU_BXU2000N2_A1_GPIO_LED_LAN 21 -+#define BHU_BXU2000N2_A1_GPIO_LED_SYSTEM 14 -+ -+#define BHU_BXU2000N2_A1_GPIO_BTN_RESET 17 -+ -+#define BHU_BXU2000N2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define BHU_BXU2000N2_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * BHU_BXU2000N2_KEYS_POLL_INTERVAL) -+ -+static const char *bhu_bxu2000n2_part_probes[] = { -+ "cmdlinepart", -+ NULL, -+}; -+ -+static struct flash_platform_data bhu_bxu2000n2_flash_data = { -+ .part_probes = bhu_bxu2000n2_part_probes, -+}; -+ -+static struct gpio_led bhu_bxu2000n2_a1_leds_gpio[] __initdata = { -+ { -+ .name = "bhu:green:status", -+ .gpio = BHU_BXU2000N2_A1_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "bhu:green:lan", -+ .gpio = BHU_BXU2000N2_A1_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "bhu:green:wan", -+ .gpio = BHU_BXU2000N2_A1_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "bhu:green:wlan", -+ .gpio = BHU_BXU2000N2_A1_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button bhu_bxu2000n2_a1_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = BHU_BXU2000N2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = BHU_BXU2000N2_A1_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init bhu_ap123_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_m25p80(&bhu_bxu2000n2_flash_data); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -+ -+ /* GMAC0 is connected to the PHY4 of the internal switch */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(4); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the internal switch. Only use PHY3 */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.phy_mask = BIT(3); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(ee, ee+2); -+} -+ -+static void __init bhu_bxu2000n2_a1_setup(void) -+{ -+ bhu_ap123_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(bhu_bxu2000n2_a1_leds_gpio), -+ bhu_bxu2000n2_a1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, BHU_BXU2000N2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(bhu_bxu2000n2_a1_gpio_keys), -+ bhu_bxu2000n2_a1_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_BHU_BXU2000N2_A1, "BXU2000n-2-A1", -+ "BHU BXU2000n-2 rev. A1", -+ bhu_bxu2000n2_a1_setup); -+ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-bsb.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-bsb.c -new file mode 100644 -index 0000000000..9f9be02eb3 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-bsb.c -@@ -0,0 +1,83 @@ -+/* -+ * Smart Electronics Black Swift board support -+ * -+ * Copyright (C) 2014 Dmitriy Zherebkov dzh@black-swift.com -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define BSB_GPIO_LED_SYS 27 -+ -+#define BSB_GPIO_BTN_RESET 11 -+ -+#define BSB_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define BSB_KEYS_DEBOUNCE_INTERVAL (3 * BSB_KEYS_POLL_INTERVAL) -+ -+#define BSB_MAC_OFFSET 0x0000 -+#define BSB_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led bsb_leds_gpio[] __initdata = { -+ { -+ .name = "bsb:red:sys", -+ .gpio = BSB_GPIO_LED_SYS, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button bsb_gpio_keys[] __initdata = { -+ { -+ .desc = "reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = BSB_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = BSB_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init bsb_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false,false); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(bsb_leds_gpio), -+ bsb_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, BSB_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(bsb_gpio_keys), -+ bsb_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + BSB_MAC_OFFSET, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + BSB_MAC_OFFSET, 2); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(art + BSB_CALDATA_OFFSET, -+ art + BSB_MAC_OFFSET); -+} -+ -+MIPS_MACHINE(ATH79_MACH_BSB, "BSB", "Smart Electronics Black Swift board", -+ bsb_setup); -+ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-c55.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-c55.c -new file mode 100644 -index 0000000000..8aa5ecb6a8 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-c55.c -@@ -0,0 +1,132 @@ -+/* -+ * AirTight Networks C-55 board support -+ * -+ * Copyright (C) 2014-2015 Chris Blake -+ * -+ * Based on Senao CAP4200AG board support -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define C55_GPIO_LED_PWR_GREEN 12 -+#define C55_GPIO_LED_PWR_AMBER 13 -+#define C55_GPIO_LED_LAN_GREEN 14 -+#define C55_GPIO_LED_LAN_AMBER 15 -+#define C55_GPIO_LED_WLAN_GREEN 18 -+#define C55_GPIO_LED_WLAN_AMBER 19 -+ -+#define C55_GPIO_BTN_RESET 17 -+ -+#define C55_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define C55_KEYS_DEBOUNCE_INTERVAL (3 * C55_KEYS_POLL_INTERVAL) -+ -+#define C55_MAC_OFFSET 0 -+#define C55_WMAC_CALDATA_OFFSET 0x1000 -+#define C55_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led c55_leds_gpio[] __initdata = { -+ { -+ .name = "c-55:green:pwr", -+ .gpio = C55_GPIO_LED_PWR_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "c-55:amber:pwr", -+ .gpio = C55_GPIO_LED_PWR_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "c-55:green:lan", -+ .gpio = C55_GPIO_LED_LAN_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "c-55:amber:lan", -+ .gpio = C55_GPIO_LED_LAN_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "c-55:green:wlan", -+ .gpio = C55_GPIO_LED_WLAN_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "c-55:amber:wlan", -+ .gpio = C55_GPIO_LED_WLAN_AMBER, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button c55_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = C55_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = C55_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init c55_setup(void) -+{ -+ /* SPI Storage*/ -+ ath79_register_m25p80(NULL); -+ -+ /* MDIO Interface */ -+ ath79_register_mdio(0, 0x0); -+ -+ /* AR8035-A Ethernet */ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_SW_ONLY_MODE); -+ ath79_init_mac(ath79_eth0_data.mac_addr, NULL, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_register_eth(0); -+ -+ /* LEDs & GPIO */ -+ ath79_gpio_output_select(C55_GPIO_LED_LAN_GREEN, -+ AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(C55_GPIO_LED_LAN_AMBER, -+ AR934X_GPIO_OUT_GPIO); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(c55_leds_gpio), -+ c55_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, C55_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(c55_gpio_keys), -+ c55_gpio_keys); -+ -+ /* WiFi */ -+ ath79_wmac_disable_2ghz(); -+ ath79_register_wmac_simple(); -+ ap91_pci_init_simple(); -+ -+} -+MIPS_MACHINE(ATH79_MACH_C55, "C-55", "AirTight Networks C-55", -+ c55_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-c60.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-c60.c -new file mode 100644 -index 0000000000..bccf2e5873 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-c60.c -@@ -0,0 +1,265 @@ -+/* -+ * AirTight Networks C-60 board support -+ * -+ * Copyright (C) 2016 Christian Lamparter -+ * -+ * Based on AirTight Networks C-55 board support -+ * -+ * Copyright (C) 2014-2015 Chris Blake -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) -+#include -+#else -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+#include "dev-usb.h" -+#include "dev-nfc.h" -+#include "machtypes.h" -+ -+#define C60_GPIO_LED_PWR_AMBER 11 -+#define C60_GPIO_LED_WLAN2_GREEN 12 -+#define C60_GPIO_LED_WLAN2_AMBER 13 -+#define C60_GPIO_LED_PWR_GREEN 16 -+ -+#define C60_GPIO_BTN_RESET 17 -+ -+/* GPIOs of the AR9300 PCIe chip */ -+#define C60_GPIO_WMAC_LED_WLAN1_AMBER 0 -+#define C60_GPIO_WMAC_LED_WLAN1_GREEN 3 -+ -+#define C60_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define C60_KEYS_DEBOUNCE_INTERVAL (3 * C60_KEYS_POLL_INTERVAL) -+ -+#define C60_ART_ADDR 0x1f7f0000 -+#define C60_ART_SIZE 0xffff -+#define C60_MAC_OFFSET 0 -+#define C60_WMAC_CALDATA_OFFSET 0x1000 -+#define C60_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led c60_leds_gpio[] __initdata = { -+ { -+ .name = "c-60:amber:pwr", -+ .gpio = C60_GPIO_LED_PWR_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "c-60:green:pwr", -+ .gpio = C60_GPIO_LED_PWR_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "c-60:green:wlan2", -+ .gpio = C60_GPIO_LED_WLAN2_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "c-60:amber:wlan2", -+ .gpio = C60_GPIO_LED_WLAN2_AMBER, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button c60_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = C60_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = C60_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg c60_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_platform_data c60_ar8327_data = { -+ .pad0_cfg = &c60_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ } -+}; -+ -+static struct mdio_board_info c60_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &c60_ar8327_data, -+ }, -+}; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+static struct nand_ecclayout c60_nand_ecclayout = { -+ .eccbytes = 7, -+ .eccpos = { 4, 8, 9, 10, 13, 14, 15 }, -+ .oobavail = 9, -+ .oobfree = { { 0, 3 }, { 6, 2 }, { 11, 2 }, } -+}; -+ -+#else -+ -+static int c60_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 4; -+ oobregion->length = 1; -+ return 0; -+ case 1: -+ oobregion->offset = 8; -+ oobregion->length = 3; -+ return 0; -+ case 2: -+ oobregion->offset = 13; -+ oobregion->length = 3; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static int c60_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 0; -+ oobregion->length = 3; -+ return 0; -+ case 1: -+ oobregion->offset = 6; -+ oobregion->length = 2; -+ return 0; -+ case 2: -+ oobregion->offset = 11; -+ oobregion->length = 2; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static const struct mtd_ooblayout_ops c60_nand_ecclayout_ops = { -+ .ecc = c60_ooblayout_ecc, -+ .free = c60_ooblayout_free, -+}; -+#endif /* < 4.6 */ -+ -+static int c60_nand_scan_fixup(struct mtd_info *mtd) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ struct nand_chip *chip = mtd->priv; -+#else -+ struct nand_chip *chip = mtd_to_nand(mtd); -+#endif -+ -+ chip->ecc.size = 512; -+ chip->ecc.strength = 4; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ chip->ecc.layout = &c60_nand_ecclayout; -+#else -+ mtd_set_ooblayout(mtd, &c60_nand_ecclayout_ops); -+#endif -+ return 0; -+} -+ -+static struct gpio_led c60_wmac0_leds_gpio[] = { -+ { -+ .name = "c-60:amber:wlan1", -+ .gpio = C60_GPIO_WMAC_LED_WLAN1_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "c-60:green:wlan1", -+ .gpio = C60_GPIO_WMAC_LED_WLAN1_GREEN, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init c60_setup(void) -+{ -+ u8 tmpmac[6]; -+ u8 *art = (u8 *) KSEG1ADDR(C60_ART_ADDR); -+ -+ /* NAND */ -+ ath79_nfc_set_ecc_mode(AR934X_NFC_ECC_SOFT_BCH); -+ ath79_nfc_set_scan_fixup(c60_nand_scan_fixup); -+ ath79_register_nfc(); -+ -+ /* SPI Storage*/ -+ ath79_register_m25p80(NULL); -+ -+ /* AR8327 Switch Ethernet */ -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0); -+ -+ mdiobus_register_board_info(c60_mdio0_info, -+ ARRAY_SIZE(c60_mdio0_info)); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* GMAC0 is connected to an AR8327N switch */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + C60_MAC_OFFSET, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_register_eth(0); -+ -+ /* LEDs & GPIO */ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(c60_leds_gpio), -+ c60_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, C60_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(c60_gpio_keys), -+ c60_gpio_keys); -+ ap9x_pci_setup_wmac_leds(0, c60_wmac0_leds_gpio, -+ ARRAY_SIZE(c60_wmac0_leds_gpio)); -+ /* USB */ -+ ath79_register_usb(); -+ -+ /* WiFi */ -+ ath79_init_mac(tmpmac, art + C60_MAC_OFFSET, 1); -+ ap91_pci_init(art + C60_PCIE_CALDATA_OFFSET, tmpmac); -+ ath79_init_mac(tmpmac, art + C60_MAC_OFFSET, 2); -+ ath79_register_wmac(art + C60_WMAC_CALDATA_OFFSET, tmpmac); -+} -+MIPS_MACHINE(ATH79_MACH_C60, "C-60", "AirTight Networks C-60", -+ c60_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-cap324.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-cap324.c -new file mode 100644 -index 0000000000..dffbb81bd4 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-cap324.c -@@ -0,0 +1,133 @@ -+/* -+ * PowerCloud Systems CAP324 board support -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * Copyright (C) 2012-2013 PowerCloud Systems -+ * Copyright (C) 2015 Daniel Dickinson -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define CAP324_GPIO_LED_POWER_GREEN 12 -+#define CAP324_GPIO_LED_POWER_AMBER 13 -+#define CAP324_GPIO_LED_LAN_GREEN 14 -+#define CAP324_GPIO_LED_LAN_AMBER 15 -+#define CAP324_GPIO_LED_WLAN_GREEN 18 -+#define CAP324_GPIO_LED_WLAN_AMBER 19 -+ -+#define CAP324_GPIO_BTN_RESET 17 -+ -+#define CAP324_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define CAP324_KEYS_DEBOUNCE_INTERVAL (3 * CAP324_KEYS_POLL_INTERVAL) -+ -+#define CAP324_MAC_OFFSET 0 -+#define CAP324_WMAC_CALDATA_OFFSET 0x1000 -+#define CAP324_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led cap324_leds_gpio[] __initdata = { -+ { -+ .name = "pcs:green:power", -+ .gpio = CAP324_GPIO_LED_POWER_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "pcs:amber:power", -+ .gpio = CAP324_GPIO_LED_POWER_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "pcs:green:lan", -+ .gpio = CAP324_GPIO_LED_LAN_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "pcs:amber:lan", -+ .gpio = CAP324_GPIO_LED_LAN_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "pcs:green:wlan", -+ .gpio = CAP324_GPIO_LED_WLAN_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "pcs:amber:wlan", -+ .gpio = CAP324_GPIO_LED_WLAN_AMBER, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button cap324_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = CAP324_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = CAP324_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init cap324_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 mac[6]; -+ -+ ath79_gpio_output_select(CAP324_GPIO_LED_LAN_GREEN, -+ AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(CAP324_GPIO_LED_LAN_AMBER, -+ AR934X_GPIO_OUT_GPIO); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cap324_leds_gpio), -+ cap324_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, CAP324_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(cap324_gpio_keys), -+ cap324_gpio_keys); -+ -+ ath79_init_mac(mac, art + CAP324_MAC_OFFSET, -2); -+ ath79_wmac_disable_2ghz(); -+ ath79_register_wmac(art + CAP324_WMAC_CALDATA_OFFSET, mac); -+ -+ ath79_init_mac(mac, art + CAP324_MAC_OFFSET, -1); -+ ap91_pci_init(art + CAP324_PCIE_CALDATA_OFFSET, mac); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ art + CAP324_MAC_OFFSET, 0); -+ -+ /* GMAC0 is connected to an external PHY */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CAP324, "CAP324", "PowerCloud Systems CAP324", -+ cap324_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-cap4200ag.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-cap4200ag.c -new file mode 100644 -index 0000000000..18944c40fa ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-cap4200ag.c -@@ -0,0 +1,131 @@ -+/* -+ * Senao CAP4200AG board support -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define CAP4200AG_GPIO_LED_PWR_GREEN 12 -+#define CAP4200AG_GPIO_LED_PWR_AMBER 13 -+#define CAP4200AG_GPIO_LED_LAN_GREEN 14 -+#define CAP4200AG_GPIO_LED_LAN_AMBER 15 -+#define CAP4200AG_GPIO_LED_WLAN_GREEN 18 -+#define CAP4200AG_GPIO_LED_WLAN_AMBER 19 -+ -+#define CAP4200AG_GPIO_BTN_RESET 17 -+ -+#define CAP4200AG_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define CAP4200AG_KEYS_DEBOUNCE_INTERVAL (3 * CAP4200AG_KEYS_POLL_INTERVAL) -+ -+#define CAP4200AG_MAC_OFFSET 0 -+#define CAP4200AG_WMAC_CALDATA_OFFSET 0x1000 -+#define CAP4200AG_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led cap4200ag_leds_gpio[] __initdata = { -+ { -+ .name = "senao:green:pwr", -+ .gpio = CAP4200AG_GPIO_LED_PWR_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "senao:amber:pwr", -+ .gpio = CAP4200AG_GPIO_LED_PWR_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "senao:green:lan", -+ .gpio = CAP4200AG_GPIO_LED_LAN_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "senao:amber:lan", -+ .gpio = CAP4200AG_GPIO_LED_LAN_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "senao:green:wlan", -+ .gpio = CAP4200AG_GPIO_LED_WLAN_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "senao:amber:wlan", -+ .gpio = CAP4200AG_GPIO_LED_WLAN_AMBER, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button cap4200ag_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = CAP4200AG_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = CAP4200AG_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init cap4200ag_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 mac[6]; -+ -+ ath79_gpio_output_select(CAP4200AG_GPIO_LED_LAN_GREEN, -+ AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(CAP4200AG_GPIO_LED_LAN_AMBER, -+ AR934X_GPIO_OUT_GPIO); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cap4200ag_leds_gpio), -+ cap4200ag_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, CAP4200AG_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(cap4200ag_gpio_keys), -+ cap4200ag_gpio_keys); -+ -+ ath79_init_mac(mac, art + CAP4200AG_MAC_OFFSET, -1); -+ ath79_wmac_disable_2ghz(); -+ ath79_register_wmac(art + CAP4200AG_WMAC_CALDATA_OFFSET, mac); -+ -+ ath79_init_mac(mac, art + CAP4200AG_MAC_OFFSET, -2); -+ ap91_pci_init(art + CAP4200AG_PCIE_CALDATA_OFFSET, mac); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ art + CAP4200AG_MAC_OFFSET, -2); -+ -+ /* GMAC0 is connected to an external PHY */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CAP4200AG, "CAP4200AG", "Senao CAP4200AG", -+ cap4200ag_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-carambola2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-carambola2.c -new file mode 100644 -index 0000000000..babe101141 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-carambola2.c -@@ -0,0 +1,105 @@ -+/* -+ * 8devices Carambola2 board support -+ * -+ * Copyright (C) 2013 Darius Augulis -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define CARAMBOLA2_GPIO_LED_WLAN 0 -+#define CARAMBOLA2_GPIO_LED_ETH0 14 -+#define CARAMBOLA2_GPIO_LED_ETH1 13 -+ -+#define CARAMBOLA2_GPIO_BTN_JUMPSTART 11 -+ -+#define CARAMBOLA2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define CARAMBOLA2_KEYS_DEBOUNCE_INTERVAL (3 * CARAMBOLA2_KEYS_POLL_INTERVAL) -+ -+#define CARAMBOLA2_MAC0_OFFSET 0x0000 -+#define CARAMBOLA2_MAC1_OFFSET 0x0006 -+#define CARAMBOLA2_CALDATA_OFFSET 0x1000 -+#define CARAMBOLA2_WMAC_MAC_OFFSET 0x1002 -+ -+static struct gpio_led carambola2_leds_gpio[] __initdata = { -+ { -+ .name = "carambola2:green:wlan", -+ .gpio = CARAMBOLA2_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "carambola2:orange:eth0", -+ .gpio = CARAMBOLA2_GPIO_LED_ETH0, -+ .active_low = 0, -+ }, { -+ .name = "carambola2:orange:eth1", -+ .gpio = CARAMBOLA2_GPIO_LED_ETH1, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button carambola2_gpio_keys[] __initdata = { -+ { -+ .desc = "jumpstart button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = CARAMBOLA2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = CARAMBOLA2_GPIO_BTN_JUMPSTART, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init carambola2_common_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_wmac(art + CARAMBOLA2_CALDATA_OFFSET, -+ art + CARAMBOLA2_WMAC_MAC_OFFSET); -+ -+ ath79_setup_ar933x_phy4_switch(true, true); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + CARAMBOLA2_MAC0_OFFSET, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + CARAMBOLA2_MAC1_OFFSET, 0); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN ports */ -+ ath79_register_eth(1); -+ -+ /* WAN port */ -+ ath79_register_eth(0); -+} -+ -+static void __init carambola2_setup(void) -+{ -+ carambola2_common_setup(); -+ -+ ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(carambola2_leds_gpio), -+ carambola2_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, CARAMBOLA2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(carambola2_gpio_keys), -+ carambola2_gpio_keys); -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CARAMBOLA2, "CARAMBOLA2", "8devices Carambola2 board", -+ carambola2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-cf-e316n-v2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-cf-e316n-v2.c -new file mode 100644 -index 0000000000..82174ba935 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-cf-e316n-v2.c -@@ -0,0 +1,765 @@ -+/* -+ * Support for COMFAST boards: -+ * - CF-E316N v2 (AR9341) -+ * - CF-E320N v2 (QCA9531) -+ * - CF-E355AC v1 (QCA9531 + QCA9882) -+ * - CF-E355AC v2 (QCA9531 + QCA9886) -+ * - CF-E375AC (QCA9563 + QCA9886 + QCA8337) -+ * - CF-E380AC v1/v2 (QCA9558) -+ * - CF-E385AC (QCA9558 + QCA9984 + QCA8337) -+ * - CF-E520N/CF-E530N (QCA9531) -+ * -+ * Copyright (C) 2016 Piotr Dymacz -+ * Copyright (C) 2016 Gareth Parker -+ * Copyright (C) 2015 Paul Fertser -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define CF_EXXXN_KEYS_POLL_INTERVAL 20 -+#define CF_EXXXN_KEYS_DEBOUNCE_INTERVAL (3 * CF_EXXXN_KEYS_POLL_INTERVAL) -+ -+/* CF-E316N v2 */ -+#define CF_E316N_V2_GPIO_LED_DIAG_B 0 -+#define CF_E316N_V2_GPIO_LED_DIAG_R 2 -+#define CF_E316N_V2_GPIO_LED_DIAG_G 3 -+#define CF_E316N_V2_GPIO_LED_WLAN 12 -+#define CF_E316N_V2_GPIO_LED_WAN 17 -+#define CF_E316N_V2_GPIO_LED_LAN 19 -+ -+#define CF_E316N_V2_GPIO_EXT_WDT 16 -+ -+#define CF_E316N_V2_GPIO_EXTERNAL_PA0 13 -+#define CF_E316N_V2_GPIO_EXTERNAL_PA1 14 -+ -+#define CF_E316N_V2_GPIO_BTN_RESET 20 -+ -+static struct gpio_led cf_e316n_v2_leds_gpio[] __initdata = { -+ { -+ .name = "cf-e316n-v2:blue:diag", -+ .gpio = CF_E316N_V2_GPIO_LED_DIAG_B, -+ .active_low = 0, -+ }, { -+ .name = "cf-e316n-v2:red:diag", -+ .gpio = CF_E316N_V2_GPIO_LED_DIAG_R, -+ .active_low = 0, -+ }, { -+ .name = "cf-e316n-v2:green:diag", -+ .gpio = CF_E316N_V2_GPIO_LED_DIAG_G, -+ .active_low = 0, -+ }, { -+ .name = "cf-e316n-v2:blue:wlan", -+ .gpio = CF_E316N_V2_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "cf-e316n-v2:blue:wan", -+ .gpio = CF_E316N_V2_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "cf-e316n-v2:blue:lan", -+ .gpio = CF_E316N_V2_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button cf_e316n_v2_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = CF_EXXXN_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = CF_E316N_V2_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+/* CF-E320N v2 */ -+#define CF_E320N_V2_GPIO_LED_WLAN 0 -+#define CF_E320N_V2_GPIO_LED_WAN 2 -+#define CF_E320N_V2_GPIO_LED_LAN 3 -+ -+#define CF_E320N_V2_GPIO_HEADER_J9_1 14 -+#define CF_E320N_V2_GPIO_HEADER_J9_2 12 -+#define CF_E320N_V2_GPIO_HEADER_J9_3 11 -+#define CF_E320N_V2_GPIO_HEADER_J9_4 16 -+ -+#define CF_E320N_V2_GPIO_EXT_WDT 13 -+ -+#define CF_E320N_V2_GPIO_BTN_RESET 17 -+ -+static struct gpio_led cf_e320n_v2_leds_gpio[] __initdata = { -+ { -+ .name = "cf-e320n-v2:green:lan", -+ .gpio = CF_E320N_V2_GPIO_LED_LAN, -+ .active_low = 0, -+ }, { -+ .name = "cf-e320n-v2:red:wan", -+ .gpio = CF_E320N_V2_GPIO_LED_WAN, -+ .active_low = 0, -+ }, { -+ .name = "cf-e320n-v2:blue:wlan", -+ .gpio = CF_E320N_V2_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button cf_e320n_v2_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = CF_EXXXN_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = CF_E320N_V2_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+/* CF-E355AC v1/v2 */ -+#define CF_E355AC_GPIO_LED_LAN 3 -+#define CF_E355AC_GPIO_LED_WLAN2G 0 -+#define CF_E355AC_GPIO_LED_WLAN5G 2 -+ -+#define CF_E355AC_GPIO_EXT_WDT 13 -+ -+#define CF_E355AC_GPIO_BTN_RESET 17 -+ -+static struct gpio_led cf_e355ac_v1_leds_gpio[] __initdata = { -+ { -+ .name = "cf-e355ac-v1:green:lan", -+ .gpio = CF_E355AC_GPIO_LED_LAN, -+ .active_low = 0, -+ }, { -+ .name = "cf-e355ac-v1:blue:wlan2g", -+ .gpio = CF_E355AC_GPIO_LED_WLAN2G, -+ .active_low = 0, -+ }, { -+ .name = "cf-e355ac-v1:red:wlan5g", -+ .gpio = CF_E355AC_GPIO_LED_WLAN5G, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_led cf_e355ac_v2_leds_gpio[] __initdata = { -+ { -+ .name = "cf-e355ac-v2:green:lan", -+ .gpio = CF_E355AC_GPIO_LED_LAN, -+ .active_low = 0, -+ }, { -+ .name = "cf-e355ac-v2:blue:wlan2g", -+ .gpio = CF_E355AC_GPIO_LED_WLAN2G, -+ .active_low = 0, -+ }, { -+ .name = "cf-e355ac-v2:red:wlan5g", -+ .gpio = CF_E355AC_GPIO_LED_WLAN5G, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button cf_e355ac_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = CF_EXXXN_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = CF_E355AC_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+/* CF-E375AC */ -+#define CF_E375AC_GPIO_LED_LAN 17 -+#define CF_E375AC_GPIO_LED_WLAN2G 16 -+#define CF_E375AC_GPIO_LED_WLAN5G 15 -+ -+#define CF_E375AC_GPIO_EXT_WDT 6 -+ -+#define CF_E375AC_GPIO_BTN_RESET 2 -+ -+static struct gpio_led cf_e375ac_leds_gpio[] __initdata = { -+ { -+ .name = "cf-e375ac:green:lan", -+ .gpio = CF_E375AC_GPIO_LED_LAN, -+ .active_low = 0, -+ }, { -+ .name = "cf-e375ac:red:wlan5g", -+ .gpio = CF_E375AC_GPIO_LED_WLAN5G, -+ .active_low = 0, -+ }, { -+ .name = "cf-e375ac:blue:wlan2g", -+ .gpio = CF_E375AC_GPIO_LED_WLAN2G, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button cf_e375ac_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = CF_EXXXN_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = CF_E375AC_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg cf_e375ac_ar8337_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+static struct ar8327_platform_data cf_e375ac_ar8337_data = { -+ .pad0_cfg = &cf_e375ac_ar8337_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info cf_e375ac_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &cf_e375ac_ar8337_data, -+ }, -+}; -+ -+/* CF-E380AC v1/v2, CF-E385AC */ -+#define CF_E38XAC_GPIO_LED_LAN 0 -+#define CF_E38XAC_GPIO_LED_WLAN2G 2 -+#define CF_E38XAC_GPIO_LED_WLAN5G 3 -+ -+#define CF_E38XAC_GPIO_EXT_WDT 17 -+ -+#define CF_E38XAC_GPIO_BTN_RESET 19 -+ -+static struct gpio_led cf_e380ac_v1_leds_gpio[] __initdata = { -+ { -+ .name = "cf-e380ac-v1:green:lan", -+ .gpio = CF_E38XAC_GPIO_LED_LAN, -+ .active_low = 0, -+ }, { -+ .name = "cf-e380ac-v1:blue:wlan2g", -+ .gpio = CF_E38XAC_GPIO_LED_WLAN2G, -+ .active_low = 0, -+ }, { -+ .name = "cf-e380ac-v1:red:wlan5g", -+ .gpio = CF_E38XAC_GPIO_LED_WLAN5G, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_led cf_e380ac_v2_leds_gpio[] __initdata = { -+ { -+ .name = "cf-e380ac-v2:green:lan", -+ .gpio = CF_E38XAC_GPIO_LED_LAN, -+ .active_low = 0, -+ }, { -+ .name = "cf-e380ac-v2:blue:wlan2g", -+ .gpio = CF_E38XAC_GPIO_LED_WLAN2G, -+ .active_low = 0, -+ }, { -+ .name = "cf-e380ac-v2:red:wlan5g", -+ .gpio = CF_E38XAC_GPIO_LED_WLAN5G, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_led cf_e385ac_leds_gpio[] __initdata = { -+ { -+ .name = "cf-e385ac:green:lan", -+ .gpio = CF_E38XAC_GPIO_LED_LAN, -+ .active_low = 0, -+ }, { -+ .name = "cf-e385ac:blue:wlan2g", -+ .gpio = CF_E38XAC_GPIO_LED_WLAN2G, -+ .active_low = 0, -+ }, { -+ .name = "cf-e385ac:red:wlan5g", -+ .gpio = CF_E38XAC_GPIO_LED_WLAN5G, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button cf_e38xac_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = CF_EXXXN_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = CF_E38XAC_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct at803x_platform_data cf_e380ac_v1v2_at803x_data = { -+ .disable_smarteee = 1, -+}; -+ -+static struct mdio_board_info cf_e380ac_v1v2_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &cf_e380ac_v1v2_at803x_data, -+ }, -+}; -+ -+/* CF-E520N/CF-E530N */ -+#define CF_E5X0N_GPIO_LED_WAN 11 -+#define CF_E5X0N_GPIO_BTN_RESET 17 -+ -+static struct gpio_led cf_e520n_leds_gpio[] __initdata = { -+ { -+ .name = "cf-e520n:blue:wan", -+ .gpio = CF_E5X0N_GPIO_LED_WAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led cf_e530n_leds_gpio[] __initdata = { -+ { -+ .name = "cf-e530n:blue:wan", -+ .gpio = CF_E5X0N_GPIO_LED_WAN, -+ .active_low = 1, -+ } -+}; -+ -+/* -+ * Some COMFAST devices include external hardware watchdog chip, -+ * Pericon Technology PT7A7514, connected to a selected GPIO -+ * and WiSoC RESET_L input. Watchdog time-out is ~1.6 s. -+ */ -+#define CF_EXXXN_EXT_WDT_TIMEOUT_MS 500 -+ -+static struct timer_list gpio_wdt_timer; -+ -+static void gpio_wdt_toggle(unsigned long gpio) -+{ -+ static int state; -+ -+ state = !state; -+ gpio_set_value(gpio, state); -+ -+ mod_timer(&gpio_wdt_timer, -+ jiffies + msecs_to_jiffies(CF_EXXXN_EXT_WDT_TIMEOUT_MS)); -+} -+ -+static void __init cf_exxxn_common_setup(unsigned long art_ofs, int gpio_wdt) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1f001000 + art_ofs); -+ -+ if (gpio_wdt > -1) { -+ gpio_request_one(gpio_wdt, GPIOF_OUT_INIT_HIGH, -+ "PT7A7514 watchdog"); -+ -+ setup_timer(&gpio_wdt_timer, gpio_wdt_toggle, gpio_wdt); -+ gpio_wdt_toggle(gpio_wdt); -+ } -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_wmac(art, NULL); -+ -+ ath79_register_usb(); -+} -+ -+static void __init cf_e316n_v2_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f010000); -+ -+ cf_exxxn_common_setup(0x10000, CF_E316N_V2_GPIO_EXT_WDT); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_PHY_SWAP); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ /* GMAC0 is connected to the PHY0 of the internal switch */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 2); -+ ath79_register_eth(1); -+ -+ /* Enable 2x Skyworks SE2576L WLAN power amplifiers */ -+ gpio_request_one(CF_E316N_V2_GPIO_EXTERNAL_PA0, GPIOF_OUT_INIT_HIGH, -+ "WLAN PA0"); -+ gpio_request_one(CF_E316N_V2_GPIO_EXTERNAL_PA1, GPIOF_OUT_INIT_HIGH, -+ "WLAN PA1"); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cf_e316n_v2_leds_gpio), -+ cf_e316n_v2_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, CF_EXXXN_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(cf_e316n_v2_gpio_keys), -+ cf_e316n_v2_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CF_E316N_V2, "CF-E316N-V2", "COMFAST CF-E316N v2", -+ cf_e316n_v2_setup); -+ -+static void __init cf_exxxn_qca953x_eth_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f010000); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ -+ /* LAN */ -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 2); -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_register_eth(0); -+} -+ -+static void __init cf_e320n_v2_setup(void) -+{ -+ cf_exxxn_common_setup(0x10000, CF_E320N_V2_GPIO_EXT_WDT); -+ -+ cf_exxxn_qca953x_eth_setup(); -+ -+ /* Disable JTAG (enables GPIO0-3) */ -+ ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE); -+ -+ ath79_gpio_direction_select(CF_E320N_V2_GPIO_LED_LAN, true); -+ ath79_gpio_direction_select(CF_E320N_V2_GPIO_LED_WAN, true); -+ ath79_gpio_direction_select(CF_E320N_V2_GPIO_LED_WLAN, true); -+ -+ ath79_gpio_output_select(CF_E320N_V2_GPIO_LED_LAN, 0); -+ ath79_gpio_output_select(CF_E320N_V2_GPIO_LED_WAN, 0); -+ ath79_gpio_output_select(CF_E320N_V2_GPIO_LED_WLAN, 0); -+ -+ /* Enable GPIO function for GPIOs in J9 header */ -+ ath79_gpio_output_select(CF_E320N_V2_GPIO_HEADER_J9_1, 0); -+ ath79_gpio_output_select(CF_E320N_V2_GPIO_HEADER_J9_2, 0); -+ ath79_gpio_output_select(CF_E320N_V2_GPIO_HEADER_J9_3, 0); -+ ath79_gpio_output_select(CF_E320N_V2_GPIO_HEADER_J9_4, 0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cf_e320n_v2_leds_gpio), -+ cf_e320n_v2_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, CF_EXXXN_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(cf_e320n_v2_gpio_keys), -+ cf_e320n_v2_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CF_E320N_V2, "CF-E320N-V2", "COMFAST CF-E320N v2", -+ cf_e320n_v2_setup); -+ -+static void __init cf_e355ac_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1f010000); -+ -+ /* Disable JTAG, enabling GPIOs 0-3 */ -+ ath79_gpio_function_setup(AR934X_GPIO_FUNC_JTAG_DISABLE, 0); -+ -+ cf_exxxn_common_setup(0x10000, CF_E355AC_GPIO_EXT_WDT); -+ -+ cf_exxxn_qca953x_eth_setup(); -+ -+ ath79_gpio_output_select(CF_E355AC_GPIO_LED_LAN, 0); -+ ath79_gpio_output_select(CF_E355AC_GPIO_LED_WLAN2G, 0); -+ ath79_gpio_output_select(CF_E355AC_GPIO_LED_WLAN5G, 0); -+ -+ ap91_pci_init(art + 0x5000, NULL); -+ -+ ath79_register_gpio_keys_polled(1, CF_EXXXN_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(cf_e355ac_gpio_keys), -+ cf_e355ac_gpio_keys); -+} -+ -+static void __init cf_e355ac_v1_setup(void) -+{ -+ cf_e355ac_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cf_e355ac_v1_leds_gpio), -+ cf_e355ac_v1_leds_gpio); -+} -+ -+static void __init cf_e355ac_v2_setup(void) -+{ -+ cf_e355ac_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cf_e355ac_v2_leds_gpio), -+ cf_e355ac_v2_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CF_E355AC, "CF-E355AC-V1", "COMFAST CF-E355AC v1", -+ cf_e355ac_v1_setup); -+ -+MIPS_MACHINE(ATH79_MACH_CF_E355AC_V2, "CF-E355AC-V2", "COMFAST CF-E355AC v2", -+ cf_e355ac_v2_setup); -+ -+static void __init cf_e375ac_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f040000); -+ -+ /* Disable JTAG, enabling GPIOs 0-3 */ -+ ath79_gpio_function_setup(AR934X_GPIO_FUNC_JTAG_DISABLE, 0); -+ -+ cf_exxxn_common_setup(0x40000, CF_E375AC_GPIO_EXT_WDT); -+ -+ ath79_gpio_output_select(CF_E375AC_GPIO_LED_LAN, 0); -+ ath79_gpio_output_select(CF_E375AC_GPIO_LED_WLAN2G, 0); -+ ath79_gpio_output_select(CF_E375AC_GPIO_LED_WLAN5G, 0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cf_e375ac_leds_gpio), -+ cf_e375ac_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, CF_EXXXN_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(cf_e375ac_gpio_keys), -+ cf_e375ac_gpio_keys); -+ -+ platform_device_register(&ath79_mdio0_device); -+ -+ mdiobus_register_board_info(cf_e375ac_mdio0_info, -+ ARRAY_SIZE(cf_e375ac_mdio0_info)); -+ -+ /* GMAC0 is connected to an AR8337 switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_register_eth(0); -+ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CF_E375AC, "CF-E375AC", "COMFAST CF-E375AC", -+ cf_e375ac_setup); -+ -+static void __init cf_e38xac_common_setup(unsigned long art_ofs) -+{ -+ cf_exxxn_common_setup(art_ofs, CF_E38XAC_GPIO_EXT_WDT); -+ -+ ath79_register_pci(); -+ -+ /* Disable JTAG (enables GPIO0-3) */ -+ ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE); -+ -+ ath79_gpio_direction_select(CF_E38XAC_GPIO_LED_LAN, true); -+ ath79_gpio_direction_select(CF_E38XAC_GPIO_LED_WLAN2G, true); -+ ath79_gpio_direction_select(CF_E38XAC_GPIO_LED_WLAN5G, true); -+ -+ ath79_gpio_output_select(CF_E38XAC_GPIO_LED_LAN, 0); -+ ath79_gpio_output_select(CF_E38XAC_GPIO_LED_WLAN2G, 0); -+ ath79_gpio_output_select(CF_E38XAC_GPIO_LED_WLAN5G, 0); -+ -+ /* For J7-4 */ -+ ath79_gpio_function_disable(AR934X_GPIO_FUNC_CLK_OBS4_EN); -+ -+ ath79_register_gpio_keys_polled(-1, CF_EXXXN_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(cf_e38xac_gpio_keys), -+ cf_e38xac_gpio_keys); -+} -+ -+static void __init cf_e380ac_v1v2_common_setup(unsigned long art_ofs) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f000000 + art_ofs); -+ -+ cf_e38xac_common_setup(art_ofs); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ ath79_register_mdio(0, 0x0); -+ mdiobus_register_board_info(cf_e380ac_v1v2_mdio0_info, -+ ARRAY_SIZE(cf_e380ac_v1v2_mdio0_info)); -+ -+ /* LAN */ -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_pll_data.pll_1000 = 0xbe000000; -+ ath79_eth0_pll_data.pll_100 = 0xb0000101; -+ ath79_eth0_pll_data.pll_10 = 0xb0001313; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_register_eth(0); -+} -+ -+static void __init cf_e380ac_v1_setup(void) -+{ -+ cf_e380ac_v1v2_common_setup(0x20000); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cf_e380ac_v1_leds_gpio), -+ cf_e380ac_v1_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CF_E380AC_V1, "CF-E380AC-V1", "COMFAST CF-E380AC v1", -+ cf_e380ac_v1_setup); -+ -+static void __init cf_e380ac_v2_setup(void) -+{ -+ cf_e380ac_v1v2_common_setup(0x40000); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cf_e380ac_v2_leds_gpio), -+ cf_e380ac_v2_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CF_E380AC_V2, "CF-E380AC-V2", "COMFAST CF-E380AC v2", -+ cf_e380ac_v2_setup); -+ -+/* QCA8337 GMAC0 is connected with QCA9558 over RGMII */ -+static struct ar8327_pad_cfg cf_e385ac_qca8337_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+}; -+ -+/* QCA8337 GMAC6 is connected with QCA9558 over SGMII */ -+static struct ar8327_pad_cfg cf_e385ac_qca8337_pad6_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL0, -+}; -+ -+static struct ar8327_platform_data cf_e385ac_qca8337_data = { -+ .pad0_cfg = &cf_e385ac_qca8337_pad0_cfg, -+ .pad6_cfg = &cf_e385ac_qca8337_pad6_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .port6_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info cf_e385ac_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &cf_e385ac_qca8337_data, -+ }, -+}; -+ -+static void __init cf_e385ac_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f040000); -+ -+ cf_e38xac_common_setup(0x40000); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cf_e385ac_leds_gpio), -+ cf_e385ac_leds_gpio); -+ -+ mdiobus_register_board_info(cf_e385ac_mdio0_info, -+ ARRAY_SIZE(cf_e385ac_mdio0_info)); -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ /* QCA9558 GMAC0 is connected to RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x96000000; -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_register_eth(0); -+ -+ /* QCA9558 GMAC1 is connected to SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CF_E385AC, "CF-E385AC", "COMFAST CF-E385AC", -+ cf_e385ac_setup); -+ -+static void __init cf_e5x0n_gpio_setup(void) -+{ -+ ath79_gpio_direction_select(CF_E5X0N_GPIO_LED_WAN, true); -+ -+ ath79_gpio_output_select(CF_E5X0N_GPIO_LED_WAN, 0); -+ -+ ath79_register_gpio_keys_polled(-1, CF_EXXXN_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(cf_e320n_v2_gpio_keys), -+ cf_e320n_v2_gpio_keys); -+} -+ -+static void __init cf_e520n_setup(void) -+{ -+ cf_exxxn_common_setup(0x10000, -1); -+ -+ cf_exxxn_qca953x_eth_setup(); -+ -+ cf_e5x0n_gpio_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cf_e520n_leds_gpio), -+ cf_e520n_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CF_E520N, "CF-E520N", "COMFAST CF-E520N", -+ cf_e520n_setup); -+ -+static void __init cf_e530n_setup(void) -+{ -+ cf_exxxn_common_setup(0x10000, -1); -+ -+ cf_exxxn_qca953x_eth_setup(); -+ -+ cf_e5x0n_gpio_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cf_e530n_leds_gpio), -+ cf_e530n_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CF_E530N, "CF-E530N", "COMFAST CF-E530N", -+ cf_e530n_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-cpe510.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-cpe510.c -new file mode 100644 -index 0000000000..49d9cf9bb5 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-cpe510.c -@@ -0,0 +1,281 @@ -+/* -+ * TP-LINK CPE210/210 v2/220/510/520 board support -+ * -+ * Copyright (C) 2014 Matthias Schiffer -+ * Copyright (C) 2017 Robert Marko -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+ -+#define CPE510_GPIO_LED_LAN0 11 -+#define CPE510_GPIO_LED_LAN1 12 -+#define CPE510_GPIO_LED_L1 13 -+#define CPE510_GPIO_LED_L2 14 -+#define CPE510_GPIO_LED_L3 15 -+#define CPE510_GPIO_LED_L4 16 -+ -+/* All LEDs/button except for link4 are the same for CPE and WBS series */ -+#define WBS510_GPIO_LED_L4 2 -+ -+#define CPE510_GPIO_EXTERNAL_LNA0 18 -+#define CPE510_GPIO_EXTERNAL_LNA1 19 -+ -+#define CPE510_GPIO_BTN_RESET 4 -+ -+#define CPE510_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define CPE510_KEYS_DEBOUNCE_INTERVAL (3 * CPE510_KEYS_POLL_INTERVAL) -+ -+/* CPE210 v2 reset GPIO */ -+#define CPE210_V2_GPIO_BTN_RESET 17 -+ -+static struct gpio_led cpe510_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan0", -+ .gpio = CPE510_GPIO_LED_LAN0, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan1", -+ .gpio = CPE510_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:link1", -+ .gpio = CPE510_GPIO_LED_L1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:link2", -+ .gpio = CPE510_GPIO_LED_L2, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:link3", -+ .gpio = CPE510_GPIO_LED_L3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:link4", -+ .gpio = CPE510_GPIO_LED_L4, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led wbs510_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan0", -+ .gpio = CPE510_GPIO_LED_LAN0, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan1", -+ .gpio = CPE510_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:link1", -+ .gpio = CPE510_GPIO_LED_L1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:link2", -+ .gpio = CPE510_GPIO_LED_L2, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:link3", -+ .gpio = CPE510_GPIO_LED_L3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:link4", -+ .gpio = WBS510_GPIO_LED_L4, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led cpe210_v2_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan0", -+ .gpio = CPE510_GPIO_LED_LAN0, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:link1", -+ .gpio = CPE510_GPIO_LED_L1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:link2", -+ .gpio = CPE510_GPIO_LED_L2, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:link3", -+ .gpio = CPE510_GPIO_LED_L3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:link4", -+ .gpio = CPE510_GPIO_LED_L4, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button cpe510_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = CPE510_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = CPE510_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button cpe210_v2_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = CPE510_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = CPE210_V2_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init cpe_setup(u8 *mac) -+{ -+ /* Disable JTAG, enabling GPIOs 0-3 */ -+ /* Configure OBS4 line, for GPIO 4*/ -+ ath79_gpio_function_setup(AR934X_GPIO_FUNC_JTAG_DISABLE, -+ AR934X_GPIO_FUNC_CLK_OBS4_EN); -+ -+ ath79_register_gpio_keys_polled(1, CPE510_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(cpe510_gpio_keys), -+ cpe510_gpio_keys); -+ -+ ath79_wmac_set_ext_lna_gpio(0, CPE510_GPIO_EXTERNAL_LNA0); -+ ath79_wmac_set_ext_lna_gpio(1, CPE510_GPIO_EXTERNAL_LNA1); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_mdio(1, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_register_eth(1); -+} -+ -+ -+static void __init cpe210_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f830008); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cpe510_leds_gpio), -+ cpe510_leds_gpio); -+ -+ cpe_setup(mac); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+static void __init cpe510_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f830008); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cpe510_leds_gpio), -+ cpe510_leds_gpio); -+ -+ cpe_setup(mac); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+static void __init wbs_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f830008); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wbs510_leds_gpio), -+ wbs510_leds_gpio); -+ -+ cpe_setup(mac); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+static void __init cpe210_v2_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f830008); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cpe210_v2_leds_gpio), -+ cpe210_v2_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, CPE510_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(cpe210_v2_gpio_keys), -+ cpe210_v2_gpio_keys); -+ ath79_register_m25p80(NULL); -+ ath79_register_mdio(0, 0x0); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_register_eth(0); -+ ath79_register_wmac(ee, mac); -+} -+ -+static void __init cpe510_v2_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f830008); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cpe210_v2_leds_gpio), -+ cpe210_v2_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, CPE510_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(cpe510_gpio_keys), -+ cpe510_gpio_keys); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_mdio(1, 0x0); -+ -+ /* LAN port */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(4); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CPE210, "CPE210", "TP-LINK CPE210/220", -+ cpe210_setup); -+ -+MIPS_MACHINE(ATH79_MACH_CPE210_V2, "CPE210V2", "TP-LINK CPE210 v2", -+ cpe210_v2_setup); -+ -+MIPS_MACHINE(ATH79_MACH_CPE210_V3, "CPE210V3", "TP-LINK CPE210 v3", -+ cpe210_v2_setup); -+ -+MIPS_MACHINE(ATH79_MACH_CPE510, "CPE510", "TP-LINK CPE510/520", -+ cpe510_setup); -+ -+MIPS_MACHINE(ATH79_MACH_CPE510_V2, "CPE510V2", "TP-LINK CPE510 v2", -+ cpe510_v2_setup); -+ -+MIPS_MACHINE(ATH79_MACH_WBS210, "WBS210", "TP-LINK WBS210", -+ wbs_setup); -+ -+MIPS_MACHINE(ATH79_MACH_WBS510, "WBS510", "TP-LINK WBS510", -+ wbs_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-cpe870.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-cpe870.c -new file mode 100644 -index 0000000000..284cdc71c2 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-cpe870.c -@@ -0,0 +1,152 @@ -+/* -+ * YunCore CPE870 board support -+ * -+ * Copyright (C) 2016 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define CPE870_GPIO_LED_LINK1 0 -+#define CPE870_GPIO_LED_LINK2 1 -+#define CPE870_GPIO_LED_LINK3 2 -+#define CPE870_GPIO_LED_LINK4 3 -+#define CPE870_GPIO_LED_WLAN 13 -+#define CPE870_GPIO_LED_WAN 19 -+#define CPE870_GPIO_LED_LAN 20 -+ -+#define CPE870_GPIO_BTN_RESET 16 -+ -+#define CPE870_KEYS_POLL_INTERVAL 20 -+#define CPE870_KEYS_DEBOUNCE_INTERVAL (3 * CPE870_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led cpe870_leds_gpio[] __initdata = { -+ { -+ .name = "cpe870:green:lan", -+ .gpio = CPE870_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "cpe870:green:wan", -+ .gpio = CPE870_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "cpe870:green:wlan", -+ .gpio = CPE870_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "cpe870:green:link1", -+ .gpio = CPE870_GPIO_LED_LINK1, -+ .active_low = 1, -+ }, -+ { -+ .name = "cpe870:green:link2", -+ .gpio = CPE870_GPIO_LED_LINK2, -+ .active_low = 1, -+ }, -+ { -+ .name = "cpe870:green:link3", -+ .gpio = CPE870_GPIO_LED_LINK3, -+ .active_low = 1, -+ }, -+ { -+ .name = "cpe870:green:link4", -+ .gpio = CPE870_GPIO_LED_LINK4, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button cpe870_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = CPE870_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = CPE870_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init cpe870_gpio_setup(void) -+{ -+ /* Disable JTAG (enables GPIO0-3) */ -+ ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE); -+ -+ ath79_gpio_direction_select(CPE870_GPIO_LED_LINK1, true); -+ ath79_gpio_direction_select(CPE870_GPIO_LED_LINK2, true); -+ ath79_gpio_direction_select(CPE870_GPIO_LED_LINK3, true); -+ ath79_gpio_direction_select(CPE870_GPIO_LED_LINK4, true); -+ -+ /* Mute LEDs on boot */ -+ gpio_set_value(CPE870_GPIO_LED_LAN, 1); -+ gpio_set_value(CPE870_GPIO_LED_WAN, 1); -+ gpio_set_value(CPE870_GPIO_LED_LINK1, 1); -+ gpio_set_value(CPE870_GPIO_LED_LINK2, 1); -+ gpio_set_value(CPE870_GPIO_LED_LINK3, 1); -+ gpio_set_value(CPE870_GPIO_LED_LINK4, 1); -+ -+ ath79_gpio_output_select(CPE870_GPIO_LED_LINK1, 0); -+ ath79_gpio_output_select(CPE870_GPIO_LED_LINK2, 0); -+ ath79_gpio_output_select(CPE870_GPIO_LED_LINK3, 0); -+ ath79_gpio_output_select(CPE870_GPIO_LED_LINK4, 0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cpe870_leds_gpio), -+ cpe870_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, CPE870_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(cpe870_gpio_keys), -+ cpe870_gpio_keys); -+} -+ -+static void __init cpe870_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ cpe870_gpio_setup(); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(4); -+ -+ /* LAN */ -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(art, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CPE870, "CPE870", "YunCore CPE870", cpe870_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-cr3000.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-cr3000.c -new file mode 100644 -index 0000000000..235b0ec769 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-cr3000.c -@@ -0,0 +1,168 @@ -+/* -+ * PowerCloud Systems CR3000 support -+ * -+ * Copyright (c) 2011 Qualcomm Atheros -+ * Copyright (c) 2011-2012 Gabor Juhos -+ * Copyright (c) 2012-2013 PowerCloud Systems -+ * Copyright (c) 2015 Daniel Dickinson -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define CR3000_GPIO_LED_WLAN_2G 13 -+#define CR3000_GPIO_LED_POWER_AMBER 15 -+#define CR3000_GPIO_LED_WAN 18 -+#define CR3000_GPIO_LED_LAN1 19 -+#define CR3000_GPIO_LED_LAN2 20 -+#define CR3000_GPIO_LED_LAN3 21 -+#define CR3000_GPIO_LED_LAN4 22 -+ -+#define CR3000_GPIO_BTN_WPS 16 -+#define CR3000_GPIO_BTN_RESET 17 -+ -+#define CR3000_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define CR3000_KEYS_DEBOUNCE_INTERVAL (3 * CR3000_KEYS_POLL_INTERVAL) -+ -+#define CR3000_MAC0_OFFSET 0 -+#define CR3000_MAC1_OFFSET 6 -+#define CR3000_WMAC_CALDATA_OFFSET 0x1000 -+#define CR3000_WMAC_MAC_OFFSET 0x1002 -+ -+static struct gpio_led cr3000_leds_gpio[] __initdata = { -+ { -+ .name = "pcs:amber:power", -+ .gpio = CR3000_GPIO_LED_POWER_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "pcs:blue:wlan", -+ .gpio = CR3000_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "pcs:blue:wan", -+ .gpio = CR3000_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "pcs:blue:lan1", -+ .gpio = CR3000_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, -+ { -+ .name = "pcs:blue:lan2", -+ .gpio = CR3000_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, -+ { -+ .name = "pcs:blue:lan3", -+ .gpio = CR3000_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, -+ { -+ .name = "pcs:blue:lan4", -+ .gpio = CR3000_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button cr3000_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = CR3000_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = CR3000_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = CR3000_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = CR3000_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init cr3000_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cr3000_leds_gpio), -+ cr3000_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, CR3000_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(cr3000_gpio_keys), -+ cr3000_gpio_keys); -+ -+ /* WLAN 2GHz onboard */ -+ ath79_register_wmac(art + CR3000_WMAC_CALDATA_OFFSET, art + CR3000_WMAC_MAC_OFFSET); -+ -+ /* FE Lan on first 4-ports of internal switch and attached to GMAC1 -+ * WAN Fast Ethernet interface attached to GMAC0 -+ * Could be configured as a 5-port switch, but we use -+ * the SoC capabilities to attach port 5 to a separate PHY/MAC -+ * theoretically this leaves future possibility of using SoC -+ * acceleration/offloading. -+ */ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_PHY_SWAP); -+ -+ /* GMAC0 attached to PHY4 (port 5 of the internal switch) */ -+ ath79_switch_data.phy4_mii_en = 1; -+ /* For switch carrier ignore port 5 (wan) */ -+ ath79_switch_data.phy_poll_mask = 0x1; -+ -+ /* Register MII bus */ -+ ath79_register_mdio(1, 0x0); -+ -+ /* GMAC0 attached to PHY4 (port 5 of the internal switch) */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = 0x1; -+ -+ /* LAN */ -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + CR3000_MAC0_OFFSET, 0); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_register_eth(1); -+ -+ /* Wan */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + CR3000_MAC0_OFFSET, 1); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CR3000, "CR3000", "PowerCloud Systems CR3000", -+ cr3000_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-cr5000.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-cr5000.c -new file mode 100644 -index 0000000000..7c41e7fbc0 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-cr5000.c -@@ -0,0 +1,179 @@ -+/* -+ * PowerCloud Systems CR5000 support -+ * -+ * Copyright (c) 2011 Qualcomm Atheros -+ * Copyright (c) 2011-2012 Gabor Juhos -+ * Copyright (c) 2012-2013 PowerCloud Systems -+ * Copyright (c) 2015 Daniel Dickinson -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define CR5000_GPIO_LED_WLAN_2G 14 -+#define CR5000_GPIO_LED_WPS 12 -+#define CR5000_GPIO_LED_POWER_AMBER 4 -+/* GPIO2 has to have JTAG disabled as it is also to -+ * power led -+ */ -+#define CR5000_GPIO_LED_POWER_ENABLE 2 -+#define CR5000_GPIO_BTN_WPS 16 -+#define CR5000_GPIO_BTN_RESET 17 -+ -+#define CR5000_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define CR5000_KEYS_DEBOUNCE_INTERVAL (3 * CR5000_KEYS_POLL_INTERVAL) -+ -+#define CR5000_MAC0_OFFSET 0 -+#define CR5000_WMAC_CALDATA_OFFSET 0x1000 -+#define CR5000_WMAC_MAC_OFFSET 0x1002 -+#define CR5000_PCIE_CALDATA_OFFSET 0x5000 -+#define CR5000_PCIE_WMAC_OFFSET 0x5002 -+ -+static struct gpio_led cr5000_leds_gpio[] __initdata = { -+ { -+ .name = "pcs:amber:power", -+ .gpio = CR5000_GPIO_LED_POWER_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "pcs:white:wps", -+ .gpio = CR5000_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+ { -+ .name = "pcs:blue:wlan", -+ .gpio = CR5000_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button cr5000_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = CR5000_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = CR5000_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = CR5000_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = CR5000_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg cr5000_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_led_cfg cr5000_ar8327_led_cfg = { -+ .led_ctrl0 = 0xcc35cc35, -+ .led_ctrl1 = 0xca35ca35, -+ .led_ctrl2 = 0xc935c935, -+ .led_ctrl3 = 0x03ffff00, -+ .open_drain = true, -+}; -+ -+static struct ar8327_platform_data cr5000_ar8327_data = { -+ .pad0_cfg = &cr5000_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &cr5000_ar8327_led_cfg, -+}; -+ -+static struct mdio_board_info cr5000_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &cr5000_ar8327_data, -+ }, -+}; -+ -+static void __init cr5000_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ struct ath9k_platform_data *pdata; -+ -+ ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE); -+ gpio_request_one(CR5000_GPIO_LED_POWER_ENABLE, -+ GPIOF_OUT_INIT_LOW, "Power LED enable"); -+ ath79_gpio_output_select(CR5000_GPIO_LED_POWER_AMBER, AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(CR5000_GPIO_LED_WLAN_2G, AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(CR5000_GPIO_LED_WPS, AR934X_GPIO_OUT_GPIO); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cr5000_leds_gpio), -+ cr5000_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, CR5000_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(cr5000_gpio_keys), -+ cr5000_gpio_keys); -+ ath79_register_usb(); -+ ath79_register_wmac(art + CR5000_WMAC_CALDATA_OFFSET, art + CR5000_WMAC_MAC_OFFSET); -+ ap91_pci_init(NULL, art + CR5000_PCIE_WMAC_OFFSET); -+ pdata = ap9x_pci_get_wmac_data(0); -+ if (pdata) -+ pdata->use_eeprom = true; -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0); -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + CR5000_MAC0_OFFSET, 0); -+ -+ mdiobus_register_board_info(cr5000_mdio0_info, -+ ARRAY_SIZE(cr5000_mdio0_info)); -+ -+ /* GMAC0 is connected to an AR8327 switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CR5000, "CR5000", "PowerCloud Systems CR5000", -+ cr5000_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dap-1330-a1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dap-1330-a1.c -new file mode 100644 -index 0000000000..9c50bc7e9b ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dap-1330-a1.c -@@ -0,0 +1,146 @@ -+/* -+ * D-Link DAP-1330 -+ * -+ * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. -+ * Copyright (c) 2017 Nicolò Veronese -+ * Copyright (c) 2017 Federico Cappon -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "nvram.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define DAP_1330_GPIO_LED_GREEN_POWER 13 -+#define DAP_1330_GPIO_LED_RED_POWER 3 -+#define DAP_1330_GPIO_LED_GREEN_WIFI 14 -+#define DAP_1330_GPIO_LED_RED_WIFI 11 -+#define DAP_1330_GPIO_LED_SIGNAL1 15 -+#define DAP_1330_GPIO_LED_SIGNAL2 16 -+ -+#define DAP_1330_GPIO_BTN_WPS 2 -+#define DAP_1330_GPIO_BTN_RESET 17 -+ -+#define DAP_1330_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DAP_1330_KEYS_DEBOUNCE_INTERVAL (3 * DAP_1330_KEYS_POLL_INTERVAL) -+ -+#define DAP1330_MAC_ADDR 0x1f020001 -+ -+#define DAP1330_WMAC_CALDATA_ADDR 0x1f010000 -+#define DAP_1330_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led dap_1330_leds_gpio[] __initdata = { -+ { -+ .name = "d-link:green:power", -+ .gpio = DAP_1330_GPIO_LED_GREEN_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:red:power", -+ .gpio = DAP_1330_GPIO_LED_RED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:green:wifi", -+ .gpio = DAP_1330_GPIO_LED_GREEN_WIFI, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:red:wifi", -+ .gpio = DAP_1330_GPIO_LED_RED_WIFI, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:green:signal1", -+ .gpio = DAP_1330_GPIO_LED_SIGNAL1, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:green:signal2", -+ .gpio = DAP_1330_GPIO_LED_SIGNAL2, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button dap_1330_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DAP_1330_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DAP_1330_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DAP_1330_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DAP_1330_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init dap_1330_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(DAP1330_WMAC_CALDATA_ADDR); -+ u8 *mac_ptr = (u8 *) KSEG1ADDR(DAP1330_MAC_ADDR); -+ u8 mac[ETH_ALEN]; -+ -+ ath79_parse_ascii_mac((char *) mac_ptr, mac); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dap_1330_leds_gpio), -+ dap_1330_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, DAP_1330_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dap_1330_gpio_keys), -+ dap_1330_gpio_keys); -+ -+ ath79_register_wmac(art + DAP_1330_WMAC_CALDATA_OFFSET, mac); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ -+ /* LAN ports */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DAP_1330_A1, "DAP-1330-A1", -+ "D-Link DAP-1330 Rev. A1", dap_1330_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dap-2695-a1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dap-2695-a1.c -new file mode 100644 -index 0000000000..2577dbffae ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dap-2695-a1.c -@@ -0,0 +1,191 @@ -+/* -+ * D-Link DAP-2695 rev. A1 support -+ * -+ * Copyright (c) 2012 Qualcomm Atheros -+ * Copyright (c) 2012-2013 Gabor Juhos -+ * Copyright (c) 2016 Stijn Tintel -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "nvram.h" -+ -+#define DAP2695_GPIO_LED_GREEN_POWER 23 -+#define DAP2695_GPIO_LED_RED_POWER 14 -+#define DAP2695_GPIO_LED_WLAN_2G 13 -+ -+#define DAP2695_GPIO_BTN_RESET 17 -+ -+#define DAP2695_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DAP2695_KEYS_DEBOUNCE_INTERVAL (3 * DAP2695_KEYS_POLL_INTERVAL) -+ -+#define DAP2695_NVRAM_ADDR 0x1f040000 -+#define DAP2695_NVRAM_SIZE 0x10000 -+ -+#define DAP2695_MAC0_OFFSET 1 -+#define DAP2695_MAC1_OFFSET 2 -+#define DAP2695_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led dap2695_leds_gpio[] __initdata = { -+ { -+ .name = "d-link:green:power", -+ .gpio = DAP2695_GPIO_LED_GREEN_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:red:power", -+ .gpio = DAP2695_GPIO_LED_RED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:green:wlan2g", -+ .gpio = DAP2695_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button dap2695_gpio_keys[] __initdata = { -+ { -+ .desc = "Soft reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DAP2695_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DAP2695_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg dap2695_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+ .mac06_exchange_dis = true, -+}; -+ -+static struct ar8327_pad_cfg dap2695_ar8327_pad6_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+static struct ar8327_platform_data dap2695_ar8327_data = { -+ .pad0_cfg = &dap2695_ar8327_pad0_cfg, -+ .pad6_cfg = &dap2695_ar8327_pad6_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .port6_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info dap2695_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &dap2695_ar8327_data, -+ }, -+}; -+ -+static struct flash_platform_data dap2695_flash_data = { -+ .type = "mx25l12805d", -+}; -+ -+static void dap2695_get_mac(const char *name, char *mac) -+{ -+ u8 *nvram = (u8 *) KSEG1ADDR(DAP2695_NVRAM_ADDR); -+ int err; -+ -+ err = ath79_nvram_parse_mac_addr(nvram, DAP2695_NVRAM_SIZE, -+ name, mac); -+ if (err) -+ pr_err("no MAC address found for %s\n", name); -+} -+ -+static void __init dap2695_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 mac0[ETH_ALEN], mac1[ETH_ALEN], wmac0[ETH_ALEN]; -+ -+ dap2695_get_mac("lanmac=", mac0); -+ dap2695_get_mac("wanmac=", mac1); -+ dap2695_get_mac("wlanmac=", wmac0); -+ -+ ath79_register_m25p80(&dap2695_flash_data); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dap2695_leds_gpio), -+ dap2695_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, DAP2695_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dap2695_gpio_keys), -+ dap2695_gpio_keys); -+ -+ ath79_register_wmac(art + DAP2695_WMAC_CALDATA_OFFSET, wmac0); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(dap2695_mdio0_info, -+ ARRAY_SIZE(dap2695_mdio0_info)); -+ -+ /* GMAC0 is connected to the RGMII interface */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac0, DAP2695_MAC0_OFFSET); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x56000000; -+ -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the SGMII interface */ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac1, DAP2695_MAC1_OFFSET); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ -+ ath79_register_eth(1); -+ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DAP_2695_A1, "DAP-2695-A1", -+ "D-Link DAP-2695 rev. A1", -+ dap2695_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dgl-5500-a1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dgl-5500-a1.c -new file mode 100644 -index 0000000000..f9f3f9e60d ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dgl-5500-a1.c -@@ -0,0 +1,150 @@ -+/* -+ * D-Link DGL-5500 board support -+ * -+ * Copyright (C) 2014 Gabor Juhos -+ * Copyright (C) 2014 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define DGL_5500_A1_GPIO_LED_POWER_ORANGE 14 -+#define DGL_5500_A1_GPIO_LED_POWER_GREEN 19 -+#define DGL_5500_A1_GPIO_LED_PLANET_GREEN 22 -+#define DGL_5500_A1_GPIO_LED_PLANET_ORANGE 23 -+ -+#define DGL_5500_A1_GPIO_BTN_WPS 16 -+#define DGL_5500_A1_GPIO_BTN_RESET 17 -+ -+#define DGL_5500_A1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DGL_5500_A1_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * DGL_5500_A1_KEYS_POLL_INTERVAL) -+ -+#define DGL_5500_A1_WMAC_CALDATA_OFFSET 0x1000 -+ -+#define DGL_5500_A1_LAN_MAC_OFFSET 0x04 -+#define DGL_5500_A1_WAN_MAC_OFFSET 0x16 -+ -+static struct gpio_led dgl_5500_a1_leds_gpio[] __initdata = { -+ { -+ .name = "d-link:green:power", -+ .gpio = DGL_5500_A1_GPIO_LED_POWER_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:orange:power", -+ .gpio = DGL_5500_A1_GPIO_LED_POWER_ORANGE, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:green:planet", -+ .gpio = DGL_5500_A1_GPIO_LED_PLANET_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:orange:planet", -+ .gpio = DGL_5500_A1_GPIO_LED_PLANET_ORANGE, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button dgl_5500_a1_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DGL_5500_A1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DGL_5500_A1_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DGL_5500_A1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DGL_5500_A1_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg dgl_5500_a1_ar8327_pad0_cfg = { -+ /* Use the SGMII interface for the GMAC0 of the AR8327 switch */ -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+static struct ar8327_platform_data dgl_5500_a1_ar8327_data = { -+ .pad0_cfg = &dgl_5500_a1_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info dgl_5500_a1_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &dgl_5500_a1_ar8327_data, -+ }, -+}; -+ -+static void __init dgl_5500_a1_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1ffe0000); -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 lan_mac[ETH_ALEN]; -+ -+ ath79_parse_ascii_mac(mac + DGL_5500_A1_LAN_MAC_OFFSET, lan_mac); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dgl_5500_a1_leds_gpio), -+ dgl_5500_a1_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, DGL_5500_A1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dgl_5500_a1_gpio_keys), -+ dgl_5500_a1_gpio_keys); -+ -+ ath79_register_wmac(art + DGL_5500_A1_WMAC_CALDATA_OFFSET, lan_mac); -+ -+ ath79_register_mdio(0, 0x0); -+ mdiobus_register_board_info(dgl_5500_a1_mdio0_info, -+ ARRAY_SIZE(dgl_5500_a1_mdio0_info)); -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, lan_mac, 0); -+ -+ /* GMAC1 is connected to an AR8327N switch via the SMGII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.phy_mask = BIT(0); -+ ath79_eth1_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ -+ ath79_register_eth(1); -+ -+ ath79_register_usb(); -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DGL_5500_A1, "DGL-5500-A1", "D-Link DGL-5500 rev. A1", -+ dgl_5500_a1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dhp-1565-a1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dhp-1565-a1.c -new file mode 100644 -index 0000000000..275d2a29a0 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dhp-1565-a1.c -@@ -0,0 +1,170 @@ -+/* -+ * D-Link DHP-1565 rev. A1 board support -+ * -+ * Copyright (C) 2014 Jacek Kikiewicz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define DHP1565A1_GPIO_LED_BLUE_USB 11 -+#define DHP1565A1_GPIO_LED_AMBER_POWER 14 -+#define DHP1565A1_GPIO_LED_BLUE_POWER 22 -+#define DHP1565A1_GPIO_LED_BLUE_WPS 15 -+#define DHP1565A1_GPIO_LED_AMBER_PLANET 19 -+#define DHP1565A1_GPIO_LED_BLUE_PLANET 18 -+#define DHP1565A1_GPIO_LED_WLAN_2G 13 -+ -+#define DHP1565A1_GPIO_WAN_LED_ENABLE 20 -+ -+#define DHP1565A1_GPIO_BTN_RESET 17 -+#define DHP1565A1_GPIO_BTN_WPS 16 -+ -+#define DHP1565A1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DHP1565A1_KEYS_DEBOUNCE_INTERVAL (3 * DHP1565A1_KEYS_POLL_INTERVAL) -+ -+#define DHP1565A1_MAC0_OFFSET 0xFFA0 -+#define DHP1565A1_MAC1_OFFSET 0xFFB4 -+#define DHP1565A1_WMAC0_OFFSET 0x5 -+#define DHP1565A1_WMAC_CALDATA_OFFSET 0x1000 -+#define DHP1565A1_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led dhp1565a1_leds_gpio[] __initdata = { -+ { -+ .name = "d-link:amber:power", -+ .gpio = DHP1565A1_GPIO_LED_AMBER_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:green:power", -+ .gpio = DHP1565A1_GPIO_LED_BLUE_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:amber:planet", -+ .gpio = DHP1565A1_GPIO_LED_AMBER_PLANET, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:green:planet", -+ .gpio = DHP1565A1_GPIO_LED_BLUE_PLANET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button dhp1565a1_gpio_keys[] __initdata = { -+ { -+ .desc = "Soft reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DHP1565A1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DHP1565A1_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DHP1565A1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DHP1565A1_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg dhp1565a1_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_platform_data dhp1565a1_ar8327_data = { -+ .pad0_cfg = &dhp1565a1_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info dhp1565a1_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &dhp1565a1_ar8327_data, -+ }, -+}; -+ -+static void __init dhp1565a1_generic_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1ffe0000); -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 mac0[ETH_ALEN], mac1[ETH_ALEN]; -+ u8 wmac0[ETH_ALEN]; -+ -+ ath79_parse_ascii_mac(mac + DHP1565A1_MAC0_OFFSET, mac0); -+ ath79_parse_ascii_mac(mac + DHP1565A1_MAC1_OFFSET, mac1); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_gpio_keys_polled(-1, DHP1565A1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dhp1565a1_gpio_keys), -+ dhp1565a1_gpio_keys); -+ -+ ath79_init_mac(wmac0, mac0, 0); -+ ath79_register_wmac(art + DHP1565A1_WMAC_CALDATA_OFFSET, wmac0); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0); -+ -+ mdiobus_register_board_info(dhp1565a1_mdio0_info, -+ ARRAY_SIZE(dhp1565a1_mdio0_info)); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac0, 1); -+ -+ /* GMAC0 is connected to an AR8327N switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_register_eth(0); -+ -+ ath79_register_usb(); -+} -+ -+static void __init dhp1565a1_setup(void) -+{ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dhp1565a1_leds_gpio), -+ dhp1565a1_leds_gpio); -+ -+ dhp1565a1_generic_setup(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DHP_1565_A1, "DHP-1565-A1", -+ "D-Link DHP-1565 rev. A1", -+ dhp1565a1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-505-a1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-505-a1.c -new file mode 100644 -index 0000000000..1367b64a8f ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-505-a1.c -@@ -0,0 +1,116 @@ -+/* -+ * DLink DIR-505 A1 board support -+ * -+ * Copyright (C) 2013 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+ -+#define DIR_505A1_GPIO_BTN_WPS 11 /* verify */ -+#define DIR_505A1_GPIO_BTN_RESET 12 /* verify */ -+ -+#define DIR_505A1_GPIO_LED_RED 26 /* unused, fyi */ -+#define DIR_505A1_GPIO_LED_GREEN 27 -+ -+#define DIR_505A1_GPIO_WAN_LED_ENABLE 1 -+ -+#define DIR_505A1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DIR_505A1_KEYS_DEBOUNCE_INTERVAL (3 * DIR_505A1_KEYS_POLL_INTERVAL) -+ -+#define DIR_505A1_ART_ADDRESS 0x1f010000 -+#define DIR_505A1_CALDATA_OFFSET 0x1000 -+ -+#define DIR_505A1_MAC_PART_ADDRESS 0x1f020000 -+#define DIR_505A1_LAN_MAC_OFFSET 0x04 -+#define DIR_505A1_WAN_MAC_OFFSET 0x16 -+ -+static struct gpio_led dir_505_a1_leds_gpio[] __initdata = { -+ { -+ .name = "d-link:green:power", -+ .gpio = DIR_505A1_GPIO_LED_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "d-link:red:status", -+ .gpio = DIR_505A1_GPIO_LED_RED, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button dir_505_a1_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DIR_505A1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR_505A1_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DIR_505A1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR_505A1_GPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static void __init dir_505_a1_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(DIR_505A1_ART_ADDRESS); -+ u8 *mac = (u8 *) KSEG1ADDR(DIR_505A1_MAC_PART_ADDRESS); -+ u8 lan_mac[ETH_ALEN]; -+ u8 wan_mac[ETH_ALEN]; -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ gpio_request_one(DIR_505A1_GPIO_WAN_LED_ENABLE, -+ GPIOF_OUT_INIT_LOW, "WAN LED enable"); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dir_505_a1_leds_gpio), -+ dir_505_a1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, DIR_505A1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dir_505_a1_gpio_keys), -+ dir_505_a1_gpio_keys); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_usb(); -+ -+ ath79_parse_ascii_mac(mac + DIR_505A1_LAN_MAC_OFFSET, lan_mac); -+ ath79_parse_ascii_mac(mac + DIR_505A1_WAN_MAC_OFFSET, wan_mac); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, wan_mac, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, lan_mac, 0); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(1); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(art + DIR_505A1_CALDATA_OFFSET, lan_mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DIR_505_A1, "DIR-505-A1", -+ "D-Link DIR-505 rev. A1", dir_505_a1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-600-a1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-600-a1.c -new file mode 100644 -index 0000000000..5e6134de7a ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-600-a1.c -@@ -0,0 +1,162 @@ -+/* -+ * D-Link DIR-600 rev. A1 board support -+ * -+ * Copyright (C) 2010-2012 Gabor Juhos -+ * Copyright (C) 2012 Vadim Girlin -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+#include "nvram.h" -+ -+#define DIR_600_A1_GPIO_LED_WPS 0 -+#define DIR_600_A1_GPIO_LED_POWER_AMBER 1 -+#define DIR_600_A1_GPIO_LED_POWER_GREEN 6 -+#define DIR_600_A1_GPIO_LED_LAN1 13 -+#define DIR_600_A1_GPIO_LED_LAN2 14 -+#define DIR_600_A1_GPIO_LED_LAN3 15 -+#define DIR_600_A1_GPIO_LED_LAN4 16 -+#define DIR_600_A1_GPIO_LED_WAN_AMBER 7 -+#define DIR_600_A1_GPIO_LED_WAN_GREEN 17 -+ -+#define DIR_600_A1_GPIO_BTN_RESET 8 -+#define DIR_600_A1_GPIO_BTN_WPS 12 -+ -+#define DIR_600_A1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DIR_600_A1_KEYS_DEBOUNCE_INTERVAL (3 * DIR_600_A1_KEYS_POLL_INTERVAL) -+ -+#define DIR_600_A1_NVRAM_ADDR 0x1f030000 -+#define DIR_600_A1_NVRAM_SIZE 0x10000 -+ -+static struct gpio_led dir_600_a1_leds_gpio[] __initdata = { -+ { -+ .name = "d-link:green:power", -+ .gpio = DIR_600_A1_GPIO_LED_POWER_GREEN, -+ }, { -+ .name = "d-link:amber:power", -+ .gpio = DIR_600_A1_GPIO_LED_POWER_AMBER, -+ }, { -+ .name = "d-link:amber:wan", -+ .gpio = DIR_600_A1_GPIO_LED_WAN_AMBER, -+ }, { -+ .name = "d-link:green:wan", -+ .gpio = DIR_600_A1_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "d-link:green:lan1", -+ .gpio = DIR_600_A1_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "d-link:green:lan2", -+ .gpio = DIR_600_A1_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "d-link:green:lan3", -+ .gpio = DIR_600_A1_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "d-link:green:lan4", -+ .gpio = DIR_600_A1_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "d-link:blue:wps", -+ .gpio = DIR_600_A1_GPIO_LED_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button dir_600_a1_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DIR_600_A1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR_600_A1_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DIR_600_A1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR_600_A1_GPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static void __init dir_600_a1_setup(void) -+{ -+ const char *nvram = (char *) KSEG1ADDR(DIR_600_A1_NVRAM_ADDR); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 mac_buff[6]; -+ u8 *mac = NULL; -+ -+ if (ath79_nvram_parse_mac_addr(nvram, DIR_600_A1_NVRAM_SIZE, -+ "lan_mac=", mac_buff) == 0) { -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac_buff, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac_buff, 1); -+ mac = mac_buff; -+ } -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dir_600_a1_leds_gpio), -+ dir_600_a1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, DIR_600_A1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dir_600_a1_gpio_keys), -+ dir_600_a1_gpio_keys); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN ports */ -+ ath79_register_eth(1); -+ -+ /* WAN port */ -+ ath79_register_eth(0); -+ -+ ap91_pci_init(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DIR_600_A1, "DIR-600-A1", "D-Link DIR-600 rev. A1", -+ dir_600_a1_setup); -+ -+MIPS_MACHINE(ATH79_MACH_EBR_2310_C1, "EBR-2310-C1", "D-Link EBR-2310 rev. C1", -+ dir_600_a1_setup); -+ -+static void __init dir_615_e1_setup(void) -+{ -+ dir_600_a1_setup(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DIR_615_E1, "DIR-615-E1", "D-Link DIR-615 rev. E1", -+ dir_615_e1_setup); -+ -+static void __init dir_615_e4_setup(void) -+{ -+ dir_600_a1_setup(); -+ ap9x_pci_setup_wmac_led_pin(0, 1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DIR_615_E4, "DIR-615-E4", "D-Link DIR-615 rev. E4", -+ dir_615_e4_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-615-c1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-615-c1.c -new file mode 100644 -index 0000000000..e55a43f9c7 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-615-c1.c -@@ -0,0 +1,135 @@ -+/* -+ * D-Link DIR-615 rev C1 board support -+ * -+ * Copyright (C) 2008-2012 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "nvram.h" -+ -+#define DIR_615C1_GPIO_LED_ORANGE_STATUS 1 /* ORANGE:STATUS:TRICOLOR */ -+#define DIR_615C1_GPIO_LED_BLUE_WPS 3 /* BLUE:WPS */ -+#define DIR_615C1_GPIO_LED_GREEN_WAN 4 /* GREEN:WAN:TRICOLOR */ -+#define DIR_615C1_GPIO_LED_GREEN_WANCPU 5 /* GREEN:WAN:CPU:TRICOLOR */ -+#define DIR_615C1_GPIO_LED_GREEN_WLAN 6 /* GREEN:WLAN */ -+#define DIR_615C1_GPIO_LED_GREEN_STATUS 14 /* GREEN:STATUS:TRICOLOR */ -+#define DIR_615C1_GPIO_LED_ORANGE_WAN 15 /* ORANGE:WAN:TRICOLOR */ -+ -+/* buttons may need refinement */ -+ -+#define DIR_615C1_GPIO_BTN_WPS 12 -+#define DIR_615C1_GPIO_BTN_RESET 21 -+ -+#define DIR_615C1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DIR_615C1_KEYS_DEBOUNCE_INTERVAL (3 * DIR_615C1_KEYS_POLL_INTERVAL) -+ -+#define DIR_615C1_CONFIG_ADDR 0x1f020000 -+#define DIR_615C1_CONFIG_SIZE 0x10000 -+ -+#define DIR_615C1_WLAN_MAC_ADDR 0x1f3fffb4 -+ -+static struct gpio_led dir_615c1_leds_gpio[] __initdata = { -+ { -+ .name = "d-link:orange:status", -+ .gpio = DIR_615C1_GPIO_LED_ORANGE_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "d-link:blue:wps", -+ .gpio = DIR_615C1_GPIO_LED_BLUE_WPS, -+ .active_low = 1, -+ }, { -+ .name = "d-link:green:wan", -+ .gpio = DIR_615C1_GPIO_LED_GREEN_WAN, -+ .active_low = 1, -+ }, { -+ .name = "d-link:green:wancpu", -+ .gpio = DIR_615C1_GPIO_LED_GREEN_WANCPU, -+ .active_low = 1, -+ }, { -+ .name = "d-link:green:wlan", -+ .gpio = DIR_615C1_GPIO_LED_GREEN_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "d-link:green:status", -+ .gpio = DIR_615C1_GPIO_LED_GREEN_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "d-link:orange:wan", -+ .gpio = DIR_615C1_GPIO_LED_ORANGE_WAN, -+ .active_low = 1, -+ } -+ -+}; -+ -+static struct gpio_keys_button dir_615c1_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DIR_615C1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR_615C1_GPIO_BTN_RESET, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DIR_615C1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR_615C1_GPIO_BTN_WPS, -+ } -+}; -+ -+#define DIR_615C1_LAN_PHYMASK BIT(0) -+#define DIR_615C1_WAN_PHYMASK BIT(4) -+#define DIR_615C1_MDIO_MASK (~(DIR_615C1_LAN_PHYMASK | \ -+ DIR_615C1_WAN_PHYMASK)) -+ -+static void __init dir_615c1_setup(void) -+{ -+ const char *config = (char *) KSEG1ADDR(DIR_615C1_CONFIG_ADDR); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 mac[ETH_ALEN], wlan_mac[ETH_ALEN]; -+ -+ if (ath79_nvram_parse_mac_addr(config, DIR_615C1_CONFIG_SIZE, -+ "lan_mac=", mac) == 0) { -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -+ } -+ -+ ath79_parse_ascii_mac((char *) KSEG1ADDR(DIR_615C1_WLAN_MAC_ADDR), wlan_mac); -+ -+ ath79_register_mdio(0, DIR_615C1_MDIO_MASK); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth0_data.phy_mask = DIR_615C1_LAN_PHYMASK; -+ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth1_data.phy_mask = DIR_615C1_WAN_PHYMASK; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dir_615c1_leds_gpio), -+ dir_615c1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, DIR_615C1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dir_615c1_gpio_keys), -+ dir_615c1_gpio_keys); -+ -+ ath79_register_wmac(eeprom, wlan_mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DIR_615_C1, "DIR-615-C1", "D-Link DIR-615 rev. C1", -+ dir_615c1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-615-i1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-615-i1.c -new file mode 100644 -index 0000000000..64fe438dcb ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-615-i1.c -@@ -0,0 +1,133 @@ -+/* -+ * D-Link DIR-615 rev. I1 board support -+ * Copyright (C) 2013-2015 Jaehoon You -+ * -+ * based on the DIR-600 rev. A1 board support code -+ * Copyright (C) 2010-2012 Gabor Juhos -+ * Copyright (C) 2012 Vadim Girlin -+ * -+ * based on the TP-LINK TL-WR841N/ND v8/TL-MR3420 v2 board support code -+ * Copyright (C) 2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define DIR_615_I1_GPIO_LED_WPS 15 -+#define DIR_615_I1_GPIO_LED_POWER_AMBER 14 -+#define DIR_615_I1_GPIO_LED_POWER_GREEN 4 -+#define DIR_615_I1_GPIO_LED_WAN_AMBER 22 -+#define DIR_615_I1_GPIO_LED_WAN_GREEN 12 -+#define DIR_615_I1_GPIO_LED_WLAN_GREEN 13 -+ -+#define DIR_615_I1_GPIO_BTN_WPS 16 -+#define DIR_615_I1_GPIO_BTN_RESET 17 -+ -+#define DIR_615_I1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DIR_615_I1_KEYS_DEBOUNCE_INTERVAL (3 * DIR_615_I1_KEYS_POLL_INTERVAL) -+ -+#define DIR_615_I1_LAN_PHYMASK BIT(0) -+#define DIR_615_I1_WAN_PHYMASK BIT(4) -+#define DIR_615_I1_WLAN_MAC_ADDR 0x1fffffb4 -+ -+static struct gpio_led dir_615_i1_leds_gpio[] __initdata = { -+ { -+ .name = "d-link:green:power", -+ .gpio = DIR_615_I1_GPIO_LED_POWER_GREEN, -+ }, { -+ .name = "d-link:amber:power", -+ .gpio = DIR_615_I1_GPIO_LED_POWER_AMBER, -+ }, { -+ .name = "d-link:amber:wan", -+ .gpio = DIR_615_I1_GPIO_LED_WAN_AMBER, -+ }, { -+ .name = "d-link:green:wan", -+ .gpio = DIR_615_I1_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "d-link:green:wlan", -+ .gpio = DIR_615_I1_GPIO_LED_WLAN_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "d-link:blue:wps", -+ .gpio = DIR_615_I1_GPIO_LED_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button dir_615_i1_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DIR_615_I1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR_615_I1_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DIR_615_I1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR_615_I1_GPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static void __init dir_615_i1_setup(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 mac[ETH_ALEN]; -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_mdio(1, ~(DIR_615_I1_WAN_PHYMASK)); -+ -+ ath79_parse_ascii_mac((char *) KSEG1ADDR(DIR_615_I1_WLAN_MAC_ADDR), mac); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ -+ /* GMAC0 is connected to the PHY0 of the internal switch */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = DIR_615_I1_WAN_PHYMASK; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_eth1_data.phy_mask = DIR_615_I1_LAN_PHYMASK; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_m25p80(NULL); -+ -+ /* Disable JTAG, enabling GPIOs 0-3 */ -+ /* Configure OBS4 line, for GPIO 4*/ -+ ath79_gpio_function_setup(AR934X_GPIO_FUNC_JTAG_DISABLE, -+ AR934X_GPIO_FUNC_CLK_OBS4_EN); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dir_615_i1_leds_gpio), -+ dir_615_i1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, DIR_615_I1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dir_615_i1_gpio_keys), -+ dir_615_i1_gpio_keys); -+ -+ ath79_register_wmac(eeprom, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DIR_615_I1, "DIR-615-I1", "D-Link DIR-615 rev. I1", -+ dir_615_i1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-825-b1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-825-b1.c -new file mode 100644 -index 0000000000..9b82990b13 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-825-b1.c -@@ -0,0 +1,191 @@ -+/* -+ * D-Link DIR-825 rev. B1 board support -+ * -+ * Copyright (C) 2009-2011 Lukas Kuna, Evkanet, s.r.o. -+ * -+ * based on mach-wndr3700.c -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+ -+#define DIR825B1_GPIO_LED_BLUE_USB 0 -+#define DIR825B1_GPIO_LED_ORANGE_POWER 1 -+#define DIR825B1_GPIO_LED_BLUE_POWER 2 -+#define DIR825B1_GPIO_LED_BLUE_WPS 4 -+#define DIR825B1_GPIO_LED_ORANGE_PLANET 6 -+#define DIR825B1_GPIO_LED_BLUE_PLANET 11 -+ -+#define DIR825B1_GPIO_BTN_RESET 3 -+#define DIR825B1_GPIO_BTN_WPS 8 -+ -+#define DIR825B1_GPIO_RTL8366_SDA 5 -+#define DIR825B1_GPIO_RTL8366_SCK 7 -+ -+#define DIR825B1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DIR825B1_KEYS_DEBOUNCE_INTERVAL (3 * DIR825B1_KEYS_POLL_INTERVAL) -+ -+#define DIR825B1_CAL0_OFFSET 0x1000 -+#define DIR825B1_CAL1_OFFSET 0x5000 -+#define DIR825B1_MAC0_OFFSET 0xffa0 -+#define DIR825B1_MAC1_OFFSET 0xffb4 -+ -+#define DIR825B1_CAL_LOCATION_0 0x1f660000 -+#define DIR825B1_CAL_LOCATION_1 0x1f7f0000 -+ -+static struct gpio_led dir825b1_leds_gpio[] __initdata = { -+ { -+ .name = "d-link:blue:usb", -+ .gpio = DIR825B1_GPIO_LED_BLUE_USB, -+ .active_low = 1, -+ }, { -+ .name = "d-link:orange:power", -+ .gpio = DIR825B1_GPIO_LED_ORANGE_POWER, -+ .active_low = 1, -+ }, { -+ .name = "d-link:blue:power", -+ .gpio = DIR825B1_GPIO_LED_BLUE_POWER, -+ .active_low = 1, -+ }, { -+ .name = "d-link:blue:wps", -+ .gpio = DIR825B1_GPIO_LED_BLUE_WPS, -+ .active_low = 1, -+ }, { -+ .name = "d-link:orange:planet", -+ .gpio = DIR825B1_GPIO_LED_ORANGE_PLANET, -+ .active_low = 1, -+ }, { -+ .name = "d-link:blue:planet", -+ .gpio = DIR825B1_GPIO_LED_BLUE_PLANET, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button dir825b1_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DIR825B1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR825B1_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DIR825B1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR825B1_GPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static struct rtl8366_initval dir825b1_rtl8366s_initvals[] = { -+ { .reg = 0x06, .val = 0x0108 }, -+}; -+ -+static struct rtl8366_platform_data dir825b1_rtl8366s_data = { -+ .gpio_sda = DIR825B1_GPIO_RTL8366_SDA, -+ .gpio_sck = DIR825B1_GPIO_RTL8366_SCK, -+ .num_initvals = ARRAY_SIZE(dir825b1_rtl8366s_initvals), -+ .initvals = dir825b1_rtl8366s_initvals, -+}; -+ -+static struct platform_device dir825b1_rtl8366s_device = { -+ .name = RTL8366S_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &dir825b1_rtl8366s_data, -+ } -+}; -+ -+static bool __init dir825b1_is_caldata_valid(u8 *p) -+{ -+ u16 *magic0, *magic1; -+ -+ magic0 = (u16 *)(p + DIR825B1_CAL0_OFFSET); -+ magic1 = (u16 *)(p + DIR825B1_CAL1_OFFSET); -+ -+ return (*magic0 == 0xa55a && *magic1 == 0xa55a); -+} -+ -+static void __init dir825b1_wlan_init(void) -+{ -+ u8 *caldata; -+ u8 mac0[ETH_ALEN], mac1[ETH_ALEN]; -+ u8 wmac0[ETH_ALEN], wmac1[ETH_ALEN]; -+ -+ caldata = (u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_0); -+ if (!dir825b1_is_caldata_valid(caldata)) { -+ caldata = (u8 *)KSEG1ADDR(DIR825B1_CAL_LOCATION_1); -+ if (!dir825b1_is_caldata_valid(caldata)) { -+ pr_err("no calibration data found\n"); -+ return; -+ } -+ } -+ -+ ath79_parse_ascii_mac(caldata + DIR825B1_MAC0_OFFSET, mac0); -+ ath79_parse_ascii_mac(caldata + DIR825B1_MAC1_OFFSET, mac1); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac0, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac1, 0); -+ ath79_init_mac(wmac0, mac0, 0); -+ ath79_init_mac(wmac1, mac1, 1); -+ -+ ap9x_pci_setup_wmac_led_pin(0, 5); -+ ap9x_pci_setup_wmac_led_pin(1, 5); -+ -+ ap94_pci_init(caldata + DIR825B1_CAL0_OFFSET, wmac0, -+ caldata + DIR825B1_CAL1_OFFSET, wmac1); -+} -+ -+static void __init dir825b1_setup(void) -+{ -+ dir825b1_wlan_init(); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_eth0_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_pll_data.pll_1000 = 0x11110000; -+ -+ ath79_eth1_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth1_data.phy_mask = 0x10; -+ ath79_eth1_pll_data.pll_1000 = 0x11110000; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dir825b1_leds_gpio), -+ dir825b1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, DIR825B1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dir825b1_gpio_keys), -+ dir825b1_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ platform_device_register(&dir825b1_rtl8366s_device); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DIR_825_B1, "DIR-825-B1", "D-Link DIR-825 rev. B1", -+ dir825b1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-825-c1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-825-c1.c -new file mode 100644 -index 0000000000..0d586c27e4 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-825-c1.c -@@ -0,0 +1,241 @@ -+/* -+ * D-Link DIR-825 rev. C1 board support -+ * -+ * Copyright (C) 2013 Alexander Stadler -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define DIR825C1_GPIO_LED_BLUE_USB 11 -+#define DIR825C1_GPIO_LED_AMBER_POWER 14 -+#define DIR825C1_GPIO_LED_BLUE_POWER 22 -+#define DIR825C1_GPIO_LED_BLUE_WPS 15 -+#define DIR825C1_GPIO_LED_AMBER_PLANET 19 -+#define DIR825C1_GPIO_LED_BLUE_PLANET 18 -+#define DIR825C1_GPIO_LED_WLAN_2G 13 -+ -+#define DIR825C1_GPIO_WAN_LED_ENABLE 20 -+ -+#define DIR825C1_GPIO_BTN_RESET 17 -+#define DIR825C1_GPIO_BTN_WPS 16 -+ -+#define DIR825C1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DIR825C1_KEYS_DEBOUNCE_INTERVAL (3 * DIR825C1_KEYS_POLL_INTERVAL) -+ -+#define DIR825C1_MAC0_OFFSET 0x4 -+#define DIR825C1_MAC1_OFFSET 0x18 -+#define DIR825C1_WMAC_CALDATA_OFFSET 0x1000 -+#define DIR825C1_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led dir825c1_leds_gpio[] __initdata = { -+ { -+ .name = "d-link:blue:usb", -+ .gpio = DIR825C1_GPIO_LED_BLUE_USB, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:amber:power", -+ .gpio = DIR825C1_GPIO_LED_AMBER_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:blue:power", -+ .gpio = DIR825C1_GPIO_LED_BLUE_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:blue:wps", -+ .gpio = DIR825C1_GPIO_LED_BLUE_WPS, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:amber:planet", -+ .gpio = DIR825C1_GPIO_LED_AMBER_PLANET, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:blue:wlan2g", -+ .gpio = DIR825C1_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led dir835a1_leds_gpio[] __initdata = { -+ { -+ .name = "d-link:amber:power", -+ .gpio = DIR825C1_GPIO_LED_AMBER_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:green:power", -+ .gpio = DIR825C1_GPIO_LED_BLUE_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:blue:wps", -+ .gpio = DIR825C1_GPIO_LED_BLUE_WPS, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:amber:planet", -+ .gpio = DIR825C1_GPIO_LED_AMBER_PLANET, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:green:planet", -+ .gpio = DIR825C1_GPIO_LED_BLUE_PLANET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button dir825c1_gpio_keys[] __initdata = { -+ { -+ .desc = "Soft reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DIR825C1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR825C1_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DIR825C1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR825C1_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg dir825c1_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_led_cfg dir825c1_ar8327_led_cfg = { -+ .led_ctrl0 = 0x00000000, -+ .led_ctrl1 = 0xc737c737, -+ .led_ctrl2 = 0x00000000, -+ .led_ctrl3 = 0x00c30c00, -+ .open_drain = true, -+}; -+ -+static struct ar8327_platform_data dir825c1_ar8327_data = { -+ .pad0_cfg = &dir825c1_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &dir825c1_ar8327_led_cfg, -+}; -+ -+static struct mdio_board_info dir825c1_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &dir825c1_ar8327_data, -+ }, -+}; -+ -+static void __init dir825c1_generic_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1ffe0000); -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 mac0[ETH_ALEN], mac1[ETH_ALEN]; -+ u8 wmac0[ETH_ALEN], wmac1[ETH_ALEN]; -+ -+ ath79_parse_ascii_mac(mac + DIR825C1_MAC0_OFFSET, mac0); -+ ath79_parse_ascii_mac(mac + DIR825C1_MAC1_OFFSET, mac1); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_gpio_keys_polled(-1, DIR825C1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dir825c1_gpio_keys), -+ dir825c1_gpio_keys); -+ -+ ath79_init_mac(wmac0, mac0, 0); -+ ath79_register_wmac(art + DIR825C1_WMAC_CALDATA_OFFSET, wmac0); -+ -+ ath79_init_mac(wmac1, mac1, 1); -+ ap91_pci_init(art + DIR825C1_PCIE_CALDATA_OFFSET, wmac1); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0); -+ -+ mdiobus_register_board_info(dir825c1_mdio0_info, -+ ARRAY_SIZE(dir825c1_mdio0_info)); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac0, 0); -+ -+ /* GMAC0 is connected to an AR8327N switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_register_eth(0); -+ -+ ath79_register_usb(); -+} -+ -+static void __init dir825c1_setup(void) -+{ -+ ath79_gpio_output_select(DIR825C1_GPIO_LED_BLUE_USB, -+ AR934X_GPIO_OUT_GPIO); -+ -+ gpio_request_one(DIR825C1_GPIO_WAN_LED_ENABLE, -+ GPIOF_OUT_INIT_LOW, "WAN LED enable"); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dir825c1_leds_gpio), -+ dir825c1_leds_gpio); -+ -+ ap9x_pci_setup_wmac_led_pin(0, 0); -+ -+ dir825c1_generic_setup(); -+} -+ -+static void __init dir835a1_setup(void) -+{ -+ dir825c1_ar8327_data.led_cfg = NULL; -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dir835a1_leds_gpio), -+ dir835a1_leds_gpio); -+ -+ dir825c1_generic_setup(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DIR_825_C1, "DIR-825-C1", -+ "D-Link DIR-825 rev. C1", -+ dir825c1_setup); -+ -+MIPS_MACHINE(ATH79_MACH_DIR_835_A1, "DIR-835-A1", -+ "D-Link DIR-835 rev. A1", -+ dir835a1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-869-a1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-869-a1.c -new file mode 100644 -index 0000000000..3841c3d5d5 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-869-a1.c -@@ -0,0 +1,175 @@ -+/* -+ * D-Link DIR-869 A1 support -+ * -+ * Copyright (C) 2015-2016 P. Wassi -+ * Copyright (C) 2016 Matthias Schiffer -+ * -+ * Derived from: mach-ubnt-unifiac.c -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "nvram.h" -+ -+ -+#define DIR869A1_GPIO_BTN_RESET 1 -+#define DIR869A1_GPIO_BTN_WPS 2 -+#define DIR869A1_GPIO_SWITCH_MODE 8 -+ -+#define DIR869A1_GPIO_ENABLE_SWITCH 11 -+ -+#define DIR869A1_GPIO_LED_ORANGE 15 -+#define DIR869A1_GPIO_LED_WHITE 16 -+ -+#define DIR869A1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DIR869A1_KEYS_DEBOUNCE_INTERVAL (3 * DIR869A1_KEYS_POLL_INTERVAL) -+ -+ -+#define DIR869A1_DEVDATA_ADDR 0x1f050000 -+#define DIR869A1_DEVDATA_SIZE 0x10000 -+ -+#define DIR869A1_EEPROM_ADDR 0x1fff0000 -+#define DIR869A1_WMAC_CALDATA_OFFSET 0x1000 -+#define DIR869A1_PCI_CALDATA_OFFSET 0x5000 -+ -+ -+static struct gpio_led dir869a1_leds_gpio[] __initdata = { -+ { -+ .name = "d-link:white:status", -+ .gpio = DIR869A1_GPIO_LED_WHITE, -+ .active_low = 1, -+ }, -+ { -+ .name = "d-link:orange:status", -+ .gpio = DIR869A1_GPIO_LED_ORANGE, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button dir869a1_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DIR869A1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR869A1_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DIR869A1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR869A1_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+ { -+ .desc = "mode", -+ .type = EV_SW, -+ .code = BTN_0, -+ .debounce_interval = DIR869A1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DIR869A1_GPIO_SWITCH_MODE, -+ .active_low = 0, -+ }, -+}; -+ -+ -+static struct ar8327_pad_cfg dir869a1_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+static struct ar8327_platform_data dir869a1_ar8327_data = { -+ .pad0_cfg = &dir869a1_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+ -+static struct mdio_board_info dir869a1_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &dir869a1_ar8327_data, -+ }, -+}; -+ -+ -+static void dir869a1_get_mac(const char *name, char *mac) -+{ -+ u8 *nvram = (u8 *) KSEG1ADDR(DIR869A1_DEVDATA_ADDR); -+ int err; -+ -+ err = ath79_nvram_parse_mac_addr(nvram, DIR869A1_DEVDATA_SIZE, -+ name, mac); -+ if (err) -+ pr_err("no MAC address found for %s\n", name); -+} -+ -+static void __init dir869a1_setup(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(DIR869A1_EEPROM_ADDR); -+ u8 wlan24mac[ETH_ALEN] = {}, wlan5mac[ETH_ALEN] = {}; -+ -+ ath79_register_m25p80(NULL); -+ -+ gpio_request_one(DIR869A1_GPIO_ENABLE_SWITCH, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "Switch power"); -+ -+ dir869a1_get_mac("lanmac=", ath79_eth0_data.mac_addr); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_data.phy_mask = BIT(0); -+ -+ mdiobus_register_board_info(dir869a1_mdio0_info, -+ ARRAY_SIZE(dir869a1_mdio0_info)); -+ -+ ath79_register_mdio(0, 0); -+ ath79_register_eth(0); -+ -+ dir869a1_get_mac("wlan24mac=", wlan24mac); -+ ath79_register_wmac(eeprom + DIR869A1_WMAC_CALDATA_OFFSET, wlan24mac); -+ -+ dir869a1_get_mac("wlan5mac=", wlan5mac); -+ ap91_pci_init(eeprom + DIR869A1_PCI_CALDATA_OFFSET, wlan5mac); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dir869a1_leds_gpio), -+ dir869a1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, DIR869A1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dir869a1_gpio_keys), -+ dir869a1_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DIR_869_A1, "DIR-869-A1", "D-Link DIR-869 rev. A1", -+ dir869a1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dlan-hotspot.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dlan-hotspot.c -new file mode 100644 -index 0000000000..3ae46514fc ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dlan-hotspot.c -@@ -0,0 +1,117 @@ -+/* -+ * devolo dLAN Hotspot board support -+ * -+ * Copyright (C) 2015 Torsten Schnuis -+ * Copyright (C) 2015 devolo AG -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define DLAN_HOTSPOT_GPIO_LED_WIFI 0 -+ -+#define DLAN_HOTSPOT_GPIO_BTN_RESET 11 -+#define DLAN_HOTSPOT_GPIO_BTN_PLC_PAIRING 12 -+#define DLAN_HOTSPOT_GPIO_BTN_WIFI 21 -+ -+#define DLAN_HOTSPOT_GPIO_PLC_POWER 22 -+#define DLAN_HOTSPOT_GPIO_PLC_RESET 20 -+#define DLAN_HOTSPOT_GPIO_PLC_DISABLE_LEDS 18 -+ -+#define DLAN_HOTSPOT_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DLAN_HOTSPOT_KEYS_DEBOUNCE_INTERVAL (3 * DLAN_HOTSPOT_KEYS_POLL_INTERVAL) -+ -+#define DLAN_HOTSPOT_ART_ADDRESS 0x1fff0000 -+#define DLAN_HOTSPOT_CALDATA_OFFSET 0x00001000 -+#define DLAN_HOTSPOT_MAC_ADDRESS_OFFSET 0x00001002 -+ -+static struct gpio_led dlan_hotspot_leds_gpio[] __initdata = { -+ { -+ .name = "devolo:green:wifi", -+ .gpio = DLAN_HOTSPOT_GPIO_LED_WIFI, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button dlan_hotspot_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DLAN_HOTSPOT_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DLAN_HOTSPOT_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+ { -+ .desc = "Pairing button", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = DLAN_HOTSPOT_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DLAN_HOTSPOT_GPIO_BTN_PLC_PAIRING, -+ .active_low = 0, -+ }, -+ { -+ .desc = "WLAN button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DLAN_HOTSPOT_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DLAN_HOTSPOT_GPIO_BTN_WIFI, -+ .active_low = 0, -+ } -+}; -+ -+static void __init dlan_hotspot_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(DLAN_HOTSPOT_ART_ADDRESS); -+ u8 *cal = art + DLAN_HOTSPOT_CALDATA_OFFSET; -+ u8 *wifi_mac = art + DLAN_HOTSPOT_MAC_ADDRESS_OFFSET; -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dlan_hotspot_leds_gpio), -+ dlan_hotspot_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, DLAN_HOTSPOT_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dlan_hotspot_gpio_keys), -+ dlan_hotspot_gpio_keys); -+ -+ gpio_request_one(DLAN_HOTSPOT_GPIO_PLC_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "PLC power"); -+ gpio_request_one(DLAN_HOTSPOT_GPIO_PLC_RESET, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "PLC reset"); -+ gpio_request_one(DLAN_HOTSPOT_GPIO_PLC_DISABLE_LEDS, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "PLC LEDs"); -+ -+ ath79_register_usb(); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, wifi_mac, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, wifi_mac, 2); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(cal, wifi_mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DLAN_HOTSPOT, "dLAN-Hotspot", -+ "dLAN Hotspot", dlan_hotspot_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dlan-pro-1200-ac.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dlan-pro-1200-ac.c -new file mode 100644 -index 0000000000..2100a9608d ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dlan-pro-1200-ac.c -@@ -0,0 +1,190 @@ -+/* -+ * devolo dLAN pro 500 Wireless+ support -+ * -+ * Copyright (c) 2013-2015 devolo AG -+ * Copyright (c) 2011-2012 Gabor Juhos -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-nfc.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define DLAN_PRO_1200_AC_GPIO_DLAN_POWER_ENABLE 13 -+#define DLAN_PRO_1200_AC_GPIO_WLAN_POWER_ENABLE 21 -+#define DLAN_PRO_1200_AC_GPIO_LED_WLAN 12 -+#define DLAN_PRO_1200_AC_GPIO_LED_DLAN 14 -+#define DLAN_PRO_1200_AC_GPIO_LED_DLAN_ERR 15 -+ -+#define DLAN_PRO_1200_AC_GPIO_BTN_WLAN 20 -+#define DLAN_PRO_1200_AC_GPIO_BTN_DLAN 22 -+#define DLAN_PRO_1200_AC_GPIO_BTN_RESET 4 -+#define DLAN_PRO_1200_AC_GPIO_DLAN_IND 17 -+#define DLAN_PRO_1200_AC_GPIO_DLAN_ERR_IND 16 -+ -+#define DLAN_PRO_1200_AC_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DLAN_PRO_1200_AC_KEYS_DEBOUNCE_INTERVAL (3 * DLAN_PRO_1200_AC_KEYS_POLL_INTERVAL) -+ -+#define DLAN_PRO_1200_AC_ART_ADDRESS 0x1fff0000 -+#define DLAN_PRO_1200_AC_CALDATA_OFFSET 0x1000 -+#define DLAN_PRO_1200_AC_WIFIMAC_OFFSET 0x1002 -+#define DLAN_PRO_1200_AC_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led dlan_pro_1200_ac_leds_gpio[] __initdata = { -+ { -+ .name = "devolo:status:wlan", -+ .gpio = DLAN_PRO_1200_AC_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "devolo:status:dlan", -+ .gpio = DLAN_PRO_1200_AC_GPIO_LED_DLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "devolo:error:dlan", -+ .gpio = DLAN_PRO_1200_AC_GPIO_LED_DLAN_ERR, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button dlan_pro_1200_ac_gpio_keys[] __initdata = { -+ { -+ .desc = "dLAN button", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = DLAN_PRO_1200_AC_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DLAN_PRO_1200_AC_GPIO_BTN_DLAN, -+ .active_low = 1, -+ }, -+ { -+ .desc = "WLAN button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DLAN_PRO_1200_AC_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DLAN_PRO_1200_AC_GPIO_BTN_WLAN, -+ .active_low = 0, -+ }, -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DLAN_PRO_1200_AC_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DLAN_PRO_1200_AC_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static struct ar8327_pad_cfg dlan_pro_1200_ac_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = false, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL0, -+ .mac06_exchange_dis = true, -+}; -+ -+static struct ar8327_pad_cfg dlan_pro_1200_ac_ar8327_pad5_cfg = { -+ .mode = 0, -+ .txclk_delay_en = 0, -+ .rxclk_delay_en = 0, -+ .txclk_delay_sel = 0, -+ .rxclk_delay_sel = 0, -+}; -+ -+static struct ar8327_platform_data dlan_pro_1200_ac_ar8327_data = { -+ .pad0_cfg = &dlan_pro_1200_ac_ar8327_pad0_cfg, -+ .pad5_cfg = &dlan_pro_1200_ac_ar8327_pad5_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info dlan_pro_1200_ac_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &dlan_pro_1200_ac_ar8327_data, -+ }, -+}; -+ -+static void __init dlan_pro_1200_ac_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(DLAN_PRO_1200_AC_ART_ADDRESS); -+ u8 *cal = art + DLAN_PRO_1200_AC_CALDATA_OFFSET; -+ u8 *wifi_mac = art + DLAN_PRO_1200_AC_WIFIMAC_OFFSET; -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dlan_pro_1200_ac_leds_gpio), -+ dlan_pro_1200_ac_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, DLAN_PRO_1200_AC_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dlan_pro_1200_ac_gpio_keys), -+ dlan_pro_1200_ac_gpio_keys); -+ -+ /* dLAN power must be enabled from user-space as soon as the boot-from-host daemon is running */ -+ gpio_request_one(DLAN_PRO_1200_AC_GPIO_DLAN_POWER_ENABLE, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "dLAN power"); -+ -+ /* WLAN power is turned on initially to allow the PCI bus scan to succeed */ -+ gpio_request_one(DLAN_PRO_1200_AC_GPIO_WLAN_POWER_ENABLE, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "WLAN power"); -+ -+ ath79_register_wmac(cal, wifi_mac); -+ ap91_pci_init(art + DLAN_PRO_1200_AC_PCIE_CALDATA_OFFSET, NULL); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_register_mdio(1, 0x0); -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, wifi_mac, 2); -+ -+ mdiobus_register_board_info(dlan_pro_1200_ac_mdio0_info, -+ ARRAY_SIZE(dlan_pro_1200_ac_mdio0_info)); -+ -+ /* GMAC0 is connected to an AR8337 */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x02000000; -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DLAN_PRO_1200_AC, "dLAN-pro-1200-ac", "devolo dLAN pro 1200+ WiFi ac", -+ dlan_pro_1200_ac_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dlan-pro-500-wp.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dlan-pro-500-wp.c -new file mode 100644 -index 0000000000..931eafffcb ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dlan-pro-500-wp.c -@@ -0,0 +1,203 @@ -+/* -+ * devolo dLAN pro 500 Wireless+ support -+ * -+ * Copyright (c) 2013-2015 devolo AG -+ * Copyright (c) 2011-2012 Gabor Juhos -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define DLAN_PRO_500_WP_GPIO_DLAN_POWER_ENABLE 13 -+#define DLAN_PRO_500_WP_GPIO_DLAN_LED_ENABLE 17 -+#define DLAN_PRO_500_WP_GPIO_LED_WLAN_5G 11 -+#define DLAN_PRO_500_WP_GPIO_LED_WLAN_2G 12 -+#define DLAN_PRO_500_WP_GPIO_LED_STATUS 16 -+#define DLAN_PRO_500_WP_GPIO_LED_ETH 14 -+ -+#define DLAN_PRO_500_WP_GPIO_BTN_WPS 20 -+#define DLAN_PRO_500_WP_GPIO_BTN_WLAN 22 -+#define DLAN_PRO_500_WP_GPIO_BTN_DLAN 21 -+#define DLAN_PRO_500_WP_GPIO_BTN_RESET 4 -+ -+#define DLAN_PRO_500_WP_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DLAN_PRO_500_WP_KEYS_DEBOUNCE_INTERVAL (3 * DLAN_PRO_500_WP_KEYS_POLL_INTERVAL) -+ -+#define DLAN_PRO_500_WP_ART_ADDRESS 0x1fff0000 -+#define DLAN_PRO_500_WP_CALDATA_OFFSET 0x1000 -+#define DLAN_PRO_500_WP_MAC_ADDRESS_OFFSET 0x1002 -+#define DLAN_PRO_500_WP_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led dlan_pro_500_wp_leds_gpio[] __initdata = { -+ { -+ .name = "devolo:green:status", -+ .gpio = DLAN_PRO_500_WP_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, -+ { -+ .name = "devolo:green:eth", -+ .gpio = DLAN_PRO_500_WP_GPIO_LED_ETH, -+ .active_low = 1, -+ }, -+ { -+ .name = "devolo:blue:wlan-5g", -+ .gpio = DLAN_PRO_500_WP_GPIO_LED_WLAN_5G, -+ .active_low = 1, -+ }, -+ { -+ .name = "devolo:green:wlan-2g", -+ .gpio = DLAN_PRO_500_WP_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button dlan_pro_500_wp_gpio_keys[] __initdata = { -+ { -+ .desc = "dLAN button", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = DLAN_PRO_500_WP_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DLAN_PRO_500_WP_GPIO_BTN_DLAN, -+ .active_low = 0, -+ }, -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DLAN_PRO_500_WP_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DLAN_PRO_500_WP_GPIO_BTN_WPS, -+ .active_low = 0, -+ }, -+ { -+ .desc = "WLAN button", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .debounce_interval = DLAN_PRO_500_WP_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DLAN_PRO_500_WP_GPIO_BTN_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DLAN_PRO_500_WP_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DLAN_PRO_500_WP_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static struct ar8327_pad_cfg dlan_pro_500_wp_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_PHY_RGMII, -+ .txclk_delay_en = false, -+ .rxclk_delay_en = false, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL0, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL0, -+}; -+ -+static struct ar8327_led_cfg dlan_pro_500_wp_ar8327_led_cfg = { -+ .led_ctrl0 = 0x00000000, -+ .led_ctrl1 = 0xc737c737, -+ .led_ctrl2 = 0x00000000, -+ .led_ctrl3 = 0x00c30c00, -+ .open_drain = true, -+}; -+ -+static struct ar8327_platform_data dlan_pro_500_wp_ar8327_data = { -+ .pad0_cfg = &dlan_pro_500_wp_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 0, -+ .rxpause = 0, -+ }, -+ .led_cfg = &dlan_pro_500_wp_ar8327_led_cfg, -+}; -+ -+static struct mdio_board_info dlan_pro_500_wp_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &dlan_pro_500_wp_ar8327_data, -+ }, -+}; -+ -+static void __init dlan_pro_500_wp_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(DLAN_PRO_500_WP_ART_ADDRESS); -+ u8 *cal = art + DLAN_PRO_500_WP_CALDATA_OFFSET; -+ u8 *wifi_mac = art + DLAN_PRO_500_WP_MAC_ADDRESS_OFFSET; -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dlan_pro_500_wp_leds_gpio), -+ dlan_pro_500_wp_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, DLAN_PRO_500_WP_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dlan_pro_500_wp_gpio_keys), -+ dlan_pro_500_wp_gpio_keys); -+ -+ gpio_request_one(DLAN_PRO_500_WP_GPIO_DLAN_POWER_ENABLE, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "PLC power"); -+ gpio_request_one(DLAN_PRO_500_WP_GPIO_DLAN_LED_ENABLE, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "PLC LEDs"); -+ -+ ath79_register_wmac(cal, wifi_mac); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0); -+ -+ ath79_register_mdio(1, 0x0); -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(dlan_pro_500_wp_mdio0_info, -+ ARRAY_SIZE(dlan_pro_500_wp_mdio0_info)); -+ -+ /* GMAC0 is connected to a AR7400 PLC in PHY mode */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, wifi_mac, 2); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_pll_data.pll_1000 = 0x0e000000; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_init_mac(ath79_eth1_data.mac_addr, wifi_mac, 1); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DLAN_PRO_500_WP, "dLAN-pro-500-wp", "devolo dLAN pro 500 Wireless+", -+ dlan_pro_500_wp_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-domywifi-dw33d.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-domywifi-dw33d.c -new file mode 100644 -index 0000000000..ac4aa8eadf ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-domywifi-dw33d.c -@@ -0,0 +1,192 @@ -+/* -+ * DomyWifi DW33D support -+ * -+ * Copyright (c) 2012 Qualcomm Atheros -+ * Copyright (c) 2012-2013 Gabor Juhos -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) -+#include -+#else -+#include -+#endif -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-nfc.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define DW33D_GPIO_LED_MMC 4 -+#define DW33D_GPIO_LED_WLAN_2G 13 -+#define DW33D_GPIO_LED_STATUS 14 -+#define DW33D_GPIO_LED_USB 15 -+#define DW33D_GPIO_LED_INTERNET 22 -+ -+#define DW33D_GPIO_BTN_RESET 17 -+ -+#define DW33D_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DW33D_KEYS_DEBOUNCE_INTERVAL (3 * DW33D_KEYS_POLL_INTERVAL) -+ -+#define DW33D_MAC0_OFFSET 0 -+#define DW33D_MAC1_OFFSET 6 -+#define DW33D_WMAC_OFFSET 12 -+#define DW33D_WMAC_CALDATA_OFFSET 0x1000 -+#define DW33D_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led dw33d_leds_gpio[] __initdata = { -+ { -+ .name = "dw33d:blue:status", -+ .gpio = DW33D_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, -+ { -+ .name = "dw33d:blue:mmc", -+ .gpio = DW33D_GPIO_LED_MMC, -+ .active_low = 1, -+ }, -+ { -+ .name = "dw33d:blue:usb", -+ .gpio = DW33D_GPIO_LED_USB, -+ .active_low = 1, -+ }, -+ { -+ .name = "dw33d:blue:wlan-2g", -+ .gpio = DW33D_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "dw33d:blue:internet", -+ .gpio = DW33D_GPIO_LED_INTERNET, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button dw33d_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DW33D_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DW33D_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+/* GMAC6 of the QCA8337 switch is connected to the QCA9558 SoC via SGMII */ -+static struct ar8327_pad_cfg dw33d_qca8337_pad6_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+/* GMAC0 of the QCA8337 switch is connected to the QCA9558 SoC via RGMII */ -+static struct ar8327_pad_cfg dw33d_qca8337_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_platform_data dw33d_qca8337_data = { -+ .pad0_cfg = &dw33d_qca8337_pad0_cfg, -+ .pad6_cfg = &dw33d_qca8337_pad6_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .port6_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info dw33d_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &dw33d_qca8337_data, -+ }, -+}; -+ -+static void __init dw33d_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dw33d_leds_gpio), -+ dw33d_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, DW33D_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dw33d_gpio_keys), -+ dw33d_gpio_keys); -+ -+ ath79_register_usb(); -+ ath79_nfc_set_ecc_mode(AR934X_NFC_ECC_HW); -+ ath79_register_nfc(); -+ ath79_register_pci(); -+ -+ ath79_register_wmac(art + DW33D_WMAC_CALDATA_OFFSET, art + DW33D_WMAC_OFFSET); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + DW33D_MAC0_OFFSET, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + DW33D_MAC1_OFFSET, 0); -+ -+ mdiobus_register_board_info(dw33d_mdio0_info, -+ ARRAY_SIZE(dw33d_mdio0_info)); -+ -+ /* GMAC0 is connected to the RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x56000000; -+ -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected tot eh SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DOMYWIFI_DW33D, "DW33D", -+ "DomyWifi DW33D", -+ dw33d_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dr344.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dr344.c -new file mode 100644 -index 0000000000..888c9c949f ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dr344.c -@@ -0,0 +1,224 @@ -+/* -+ * Wallys DR342/DR344 boards support -+ * -+ * Copyright (c) 2011 Qualcomm Atheros -+ * Copyright (c) 2011-2012 Gabor Juhos -+ * Copyright (c) 2015 Philippe Duchein -+ * Copyright (c) 2017 Piotr Dymacz -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-usb.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define DR34X_GPIO_LED_SIG1 12 -+#define DR34X_GPIO_LED_SIG2 13 -+#define DR34X_GPIO_LED_SIG3 14 -+#define DR34X_GPIO_LED_SIG4 15 -+#define DR34X_GPIO_LED_STATUS 11 -+#define DR344_GPIO_LED_LAN 17 -+#define DR344_GPIO_EXTERNAL_LNA0 18 -+#define DR344_GPIO_EXTERNAL_LNA1 19 -+ -+#define DR34X_GPIO_BTN_RESET 16 -+ -+#define DR344_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DR344_KEYS_DEBOUNCE_INTERVAL (3 * DR344_KEYS_POLL_INTERVAL) -+ -+#define DR34X_MAC0_OFFSET 0 -+#define DR34X_MAC1_OFFSET 8 -+#define DR34X_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led dr342_leds_gpio[] __initdata = { -+ { -+ .name = "dr342:green:status", -+ .gpio = DR34X_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, -+ { -+ .name = "dr342:green:sig1", -+ .gpio = DR34X_GPIO_LED_SIG1, -+ .active_low = 1, -+ }, -+ { -+ .name = "dr342:green:sig2", -+ .gpio = DR34X_GPIO_LED_SIG2, -+ .active_low = 1, -+ }, -+ { -+ .name = "dr342:green:sig3", -+ .gpio = DR34X_GPIO_LED_SIG3, -+ .active_low = 1, -+ }, -+ { -+ .name = "dr342:green:sig4", -+ .gpio = DR34X_GPIO_LED_SIG4, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led dr344_leds_gpio[] __initdata = { -+ { -+ .name = "dr344:green:lan", -+ .gpio = DR344_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "dr344:green:status", -+ .gpio = DR34X_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, -+ { -+ .name = "dr344:green:sig1", -+ .gpio = DR34X_GPIO_LED_SIG1, -+ .active_low = 1, -+ }, -+ { -+ .name = "dr344:green:sig2", -+ .gpio = DR34X_GPIO_LED_SIG2, -+ .active_low = 1, -+ }, -+ { -+ .name = "dr344:green:sig3", -+ .gpio = DR34X_GPIO_LED_SIG3, -+ .active_low = 1, -+ }, -+ { -+ .name = "dr344:green:sig4", -+ .gpio = DR34X_GPIO_LED_SIG4, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button dr34x_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DR344_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DR34X_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct at803x_platform_data dr34x_at803x_data = { -+ .disable_smarteee = 1, -+ .enable_rgmii_rx_delay = 1, -+ .enable_rgmii_tx_delay = 1, -+}; -+ -+static struct mdio_board_info dr34x_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &dr34x_at803x_data, -+ }, -+}; -+ -+static void __init dr34x_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f03f810); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_gpio_direction_select(DR34X_GPIO_LED_STATUS, true); -+ gpio_set_value(DR34X_GPIO_LED_STATUS, 1); -+ ath79_gpio_output_select(DR34X_GPIO_LED_STATUS, 0); -+ -+ ath79_register_gpio_keys_polled(-1, DR344_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dr34x_gpio_keys), -+ dr34x_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_register_wmac(art + DR34X_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_pci(); -+ -+ mdiobus_register_board_info(dr34x_mdio0_info, -+ ARRAY_SIZE(dr34x_mdio0_info)); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ /* GMAC0 is connected to an AR8035 Gbps PHY */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x02000000; -+ ath79_eth0_pll_data.pll_100 = 0x0101; -+ ath79_eth0_pll_data.pll_10 = 0x1313; -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac + DR34X_MAC0_OFFSET, 0); -+ ath79_register_eth(0); -+} -+ -+static void __init dr342_setup(void) -+{ -+ dr34x_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dr342_leds_gpio), -+ dr342_leds_gpio); -+} -+ -+static void __init dr344_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f03f810); -+ -+ dr34x_setup(); -+ -+ ath79_gpio_direction_select(DR344_GPIO_LED_LAN, true); -+ gpio_set_value(DR344_GPIO_LED_LAN, 1); -+ ath79_gpio_output_select(DR344_GPIO_LED_LAN, 0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dr344_leds_gpio), -+ dr344_leds_gpio); -+ -+ ath79_wmac_set_ext_lna_gpio(0, DR344_GPIO_EXTERNAL_LNA0); -+ ath79_wmac_set_ext_lna_gpio(1, DR344_GPIO_EXTERNAL_LNA1); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac + DR34X_MAC1_OFFSET, 0); -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DR342, "DR342", "Wallys DR342", dr342_setup); -+MIPS_MACHINE(ATH79_MACH_DR344, "DR344", "Wallys DR344", dr344_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dr531.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dr531.c -new file mode 100644 -index 0000000000..b638a9001c ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dr531.c -@@ -0,0 +1,155 @@ -+/* -+ * Wallys DR531 board support -+ * -+ * Copyright (C) 2016 Piotr Dymacz -+ * -+ * Based on mach-wpj531.c -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define DR531_GPIO_BUZZER 4 -+#define DR531_GPIO_LED_WAN 11 -+#define DR531_GPIO_LED_LAN 14 -+#define DR531_GPIO_LED_SIG1 12 -+#define DR531_GPIO_LED_SIG2 16 -+#define DR531_GPIO_LED_SIG3 15 -+#define DR531_GPIO_LED_SIG4 13 -+ -+#define DR531_GPIO_BTN_RESET 17 -+ -+#define DR531_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DR531_KEYS_DEBOUNCE_INTERVAL (3 * DR531_KEYS_POLL_INTERVAL) -+ -+#define DR531_MAC0_OFFSET 0x0 -+#define DR531_MAC1_OFFSET 0x8 -+#define DR531_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led dr531_leds_gpio[] __initdata = { -+ { -+ .name = "dr531:green:wan", -+ .gpio = DR531_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "dr531:green:lan", -+ .gpio = DR531_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "dr531:green:sig1", -+ .gpio = DR531_GPIO_LED_SIG1, -+ .active_low = 1, -+ }, -+ { -+ .name = "dr531:green:sig2", -+ .gpio = DR531_GPIO_LED_SIG2, -+ .active_low = 1, -+ }, -+ { -+ .name = "dr531:green:sig3", -+ .gpio = DR531_GPIO_LED_SIG3, -+ .active_low = 1, -+ }, -+ { -+ .name = "dr531:green:sig4", -+ .gpio = DR531_GPIO_LED_SIG4, -+ .active_low = 1, -+ }, -+ { -+ .name = "dr531:buzzer", -+ .gpio = DR531_GPIO_BUZZER, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button dr531_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DR531_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DR531_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init dr531_gpio_setup(void) -+{ -+ ath79_gpio_direction_select(DR531_GPIO_BUZZER, true); -+ ath79_gpio_direction_select(DR531_GPIO_LED_WAN, true); -+ ath79_gpio_direction_select(DR531_GPIO_LED_LAN, true); -+ ath79_gpio_direction_select(DR531_GPIO_LED_SIG1, true); -+ ath79_gpio_direction_select(DR531_GPIO_LED_SIG2, true); -+ ath79_gpio_direction_select(DR531_GPIO_LED_SIG3, true); -+ ath79_gpio_direction_select(DR531_GPIO_LED_SIG4, true); -+ -+ ath79_gpio_output_select(DR531_GPIO_BUZZER, 0); -+ ath79_gpio_output_select(DR531_GPIO_LED_WAN, 0); -+ ath79_gpio_output_select(DR531_GPIO_LED_LAN, 0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dr531_leds_gpio), -+ dr531_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, DR531_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dr531_gpio_keys), -+ dr531_gpio_keys); -+} -+ -+static void __init dr531_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f03f810); -+ -+ ath79_register_m25p80(NULL); -+ -+ dr531_gpio_setup(); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN */ -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac + DR531_MAC1_OFFSET, 0); -+ ath79_register_eth(0); -+ -+ /* WAN */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac + DR531_MAC0_OFFSET, 0); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(art + DR531_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_pci(); -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DR531, "DR531", "Wallys DR531", dr531_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dragino2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dragino2.c -new file mode 100644 -index 0000000000..95bd6f41a3 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dragino2.c -@@ -0,0 +1,136 @@ -+/* -+ * DRAGINO V2 board support, based on Atheros AP121 board support -+ * -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * Copyright (C) 2012 Elektra Wagenrad -+ * Copyright (C) 2014 Vittorio Gambaletta -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define DRAGINO2_GPIO_LED_WLAN 0 -+#define DRAGINO2_GPIO_LED_LAN 13 -+#define DRAGINO2_GPIO_LED_WAN 17 -+ -+/* -+ * The following GPIO is named "SYS" on newer revisions of the the board. -+ * It was previously used to indicate USB activity, even though it was -+ * named "Router". -+ */ -+ -+#define DRAGINO2_GPIO_LED_SYS 28 -+#define DRAGINO2_GPIO_BTN_JUMPSTART 11 -+#define DRAGINO2_GPIO_BTN_RESET 12 -+ -+#define DRAGINO2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DRAGINO2_KEYS_DEBOUNCE_INTERVAL (3 * DRAGINO2_KEYS_POLL_INTERVAL) -+ -+#define DRAGINO2_MAC0_OFFSET 0x0000 -+#define DRAGINO2_MAC1_OFFSET 0x0006 -+#define DRAGINO2_CALDATA_OFFSET 0x1000 -+#define DRAGINO2_WMAC_MAC_OFFSET 0x1002 -+ -+static struct gpio_led dragino2_leds_gpio[] __initdata = { -+ { -+ .name = "dragino2:red:wlan", -+ .gpio = DRAGINO2_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+ { -+ .name = "dragino2:red:wan", -+ .gpio = DRAGINO2_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "dragino2:red:lan", -+ .gpio = DRAGINO2_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "dragino2:red:system", -+ .gpio = DRAGINO2_GPIO_LED_SYS, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button dragino2_gpio_keys[] __initdata = { -+ { -+ .desc = "jumpstart button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DRAGINO2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DRAGINO2_GPIO_BTN_JUMPSTART, -+ .active_low = 1, -+ }, -+ { -+ .desc = "reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DRAGINO2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DRAGINO2_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init dragino2_common_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_wmac(art + DRAGINO2_CALDATA_OFFSET, -+ art + DRAGINO2_WMAC_MAC_OFFSET); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + DRAGINO2_MAC0_OFFSET, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + DRAGINO2_MAC1_OFFSET, 0); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* Enable GPIO13, GPIO14, GPIO15, GPIO16 and GPIO17 */ -+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ /* LAN port */ -+ ath79_register_eth(1); -+ -+ /* WAN port */ -+ ath79_register_eth(0); -+ -+ /* Enable GPIO26 and GPIO27 */ -+ ath79_reset_wr(AR933X_RESET_REG_BOOTSTRAP, -+ ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP) | -+ AR933X_BOOTSTRAP_MDIO_GPIO_EN); -+} -+ -+static void __init dragino2_setup(void) -+{ -+ dragino2_common_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dragino2_leds_gpio), -+ dragino2_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, DRAGINO2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dragino2_gpio_keys), -+ dragino2_gpio_keys); -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_DRAGINO2, "DRAGINO2", "Dragino Dragino v2", -+ dragino2_setup); -+ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-e1700ac-v2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-e1700ac-v2.c -new file mode 100644 -index 0000000000..1ba47a4255 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-e1700ac-v2.c -@@ -0,0 +1,145 @@ -+/* -+ * Qxwlan E1700AC v2 board support -+ * -+ * Copyright (C) 2017 Peng Zhang -+ * Copyright (C) 2018 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define E1700AC_V2_GPIO_LED_SYS 1 -+#define E1700AC_V2_GPIO_LED_USB 7 -+#define E1700AC_V2_GPIO_LED_WLAN2G 19 -+ -+#define E1700AC_V2_GPIO_BTN_SW1 2 -+#define E1700AC_V2_GPIO_BTN_RESET 11 -+ -+#define E1700AC_V2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define E1700AC_V2_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * E1700AC_V2_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led e1700ac_v2_leds_gpio[] __initdata = { -+ { -+ .name = "e1700ac-v2:green:system", -+ .gpio = E1700AC_V2_GPIO_LED_SYS, -+ .active_low = 1, -+ }, { -+ .name = "e1700ac-v2:green:usb", -+ .gpio = E1700AC_V2_GPIO_LED_USB, -+ .active_low = 1, -+ }, { -+ .name = "e1700ac-v2:green:wlan2g", -+ .gpio = E1700AC_V2_GPIO_LED_WLAN2G, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button e1700ac_v2_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = E1700AC_V2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = E1700AC_V2_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "sw1", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = E1700AC_V2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = E1700AC_V2_GPIO_BTN_SW1, -+ .active_low = 1, -+ }, -+}; -+ -+static const struct ar8327_led_info e1700ac_v2_leds_qca8334[] = { -+ AR8327_LED_INFO(PHY1_0, HW, "e1700ac-v2:green:lan"), -+ AR8327_LED_INFO(PHY2_0, HW, "e1700ac-v2:green:wan"), -+}; -+ -+/* Blink rate: 1 Gbps -> 8 hz, 100 Mbs -> 4 Hz, 10 Mbps -> 2 Hz */ -+static struct ar8327_led_cfg e1700ac_v2_qca8334_led_cfg = { -+ .led_ctrl0 = 0xcf37cf37, -+ .led_ctrl1 = 0xcf37cf37, -+ .led_ctrl2 = 0xcf37cf37, -+ .led_ctrl3 = 0x0, -+ .open_drain = true, -+}; -+ -+static struct ar8327_pad_cfg e1700ac_v2_qca8334_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+static struct ar8327_platform_data e1700ac_v2_qca8334_data = { -+ .pad0_cfg = &e1700ac_v2_qca8334_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &e1700ac_v2_qca8334_led_cfg, -+ .leds = e1700ac_v2_leds_qca8334, -+ .num_leds = ARRAY_SIZE(e1700ac_v2_leds_qca8334), -+}; -+ -+static struct mdio_board_info e1700ac_v2_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &e1700ac_v2_qca8334_data, -+ }, -+}; -+ -+static void __init e1700ac_v2_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f050400); -+ u8 *art = (u8 *) KSEG1ADDR(0x1f061000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(e1700ac_v2_leds_gpio), -+ e1700ac_v2_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, E1700AC_V2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(e1700ac_v2_gpio_keys), -+ e1700ac_v2_gpio_keys); -+ -+ ath79_register_mdio(0, 0x0); -+ mdiobus_register_board_info(e1700ac_v2_mdio0_info, -+ ARRAY_SIZE(e1700ac_v2_mdio0_info)); -+ -+ /* GMAC0 is connected to QCA8334 switch */ -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_pll_data.pll_1000 = 0x03000101; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_register_eth(0); -+ -+ ath79_register_pci(); -+ ath79_register_usb(); -+ ath79_register_wmac(art, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_E1700AC_V2, "E1700AC-V2", "Qxwlan E1700AC v2", -+ e1700ac_v2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-e2100l.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-e2100l.c -new file mode 100644 -index 0000000000..c09083460e ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-e2100l.c -@@ -0,0 +1,126 @@ -+/* -+ * Linksys E2100L board support -+ * -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "nvram.h" -+#include "machtypes.h" -+ -+#define E2100L_GPIO_LED_POWER 14 -+#define E2100L_GPIO_LED_WPS_AMBER 9 -+#define E2100L_GPIO_LED_WPS_BLUE 8 -+#define E2100L_GPIO_LED_WLAN 6 -+ -+#define E2100L_GPIO_BTN_WPS 7 -+#define E2100L_GPIO_BTN_RESET 21 -+ -+#define E2100L_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define E2100L_KEYS_DEBOUNCE_INTERVAL (3 * E2100L_KEYS_POLL_INTERVAL) -+ -+#define E2100L_NVRAM_ADDR 0x1f7e0000 -+#define E2100L_NVRAM_SIZE 0x10000 -+ -+static const char *e2100l_part_probes[] = { -+ "cybertan", -+ NULL, -+}; -+ -+static struct flash_platform_data e2100l_flash_data = { -+ .part_probes = e2100l_part_probes, -+}; -+ -+static struct gpio_led e2100l_leds_gpio[] __initdata = { -+ { -+ .name = "e2100l:blue:power", -+ .gpio = E2100L_GPIO_LED_POWER, -+ .active_low = 1, -+ .default_trigger = "default-on", -+ }, { -+ .name = "e2100l:amber:wps", -+ .gpio = E2100L_GPIO_LED_WPS_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "e2100l:blue:wps", -+ .gpio = E2100L_GPIO_LED_WPS_BLUE, -+ .active_low = 1, -+ }, { -+ .name = "e2100l:blue:wlan", -+ .gpio = E2100L_GPIO_LED_WLAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button e2100l_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = E2100L_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = E2100L_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = E2100L_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = E2100L_GPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static void __init e2100l_setup(void) -+{ -+ const char *nvram = (char *) KSEG1ADDR(E2100L_NVRAM_ADDR); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 mac[6]; -+ -+ if (ath79_nvram_parse_mac_addr(nvram, E2100L_NVRAM_SIZE, -+ "lan_hwaddr=", mac) == 0) { -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -+ } -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth0_data.phy_mask = 0x01; -+ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth1_data.phy_mask = 0x10; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_m25p80(&e2100l_flash_data); -+ -+ ath79_register_usb(); -+ -+ if (ath79_nvram_parse_mac_addr(nvram, E2100L_NVRAM_SIZE, -+ "wl0_hwaddr=", mac) == 0) -+ ath79_register_wmac(eeprom, mac); -+ else -+ ath79_register_wmac(eeprom, NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(e2100l_leds_gpio), -+ e2100l_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, E2100L_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(e2100l_gpio_keys), -+ e2100l_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_E2100L, "E2100L", "Linksys E2100L", -+ e2100l_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-e558-v2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-e558-v2.c -new file mode 100644 -index 0000000000..cc08147209 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-e558-v2.c -@@ -0,0 +1,170 @@ -+/* -+ * Qxwlan E558 v2 board support -+ * -+ * Copyright (C) 2017 Peng Zhang -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define E558_V2_GPIO_LED_WLAN 13 -+#define E558_V2_GPIO_LED_SYSTEM 14 -+#define E558_V2_GPIO_LED_QSS 15 -+ -+#define E558_V2_GPIO_BTN_RESET 16 -+ -+#define E558_V2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define E558_V2_KEYS_DEBOUNCE_INTERVAL (3 * E558_V2_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led e558_v2_leds_gpio[] __initdata = { -+ { -+ .name = "e558-v2:green:qss", -+ .gpio = E558_V2_GPIO_LED_QSS, -+ .active_low = 1, -+ }, -+ { -+ .name = "e558-v2:green:system", -+ .gpio = E558_V2_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+ { -+ .name = "e558-v2:green:wlan", -+ .gpio = E558_V2_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button e558_v2_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = E558_V2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = E558_V2_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+/* GMAC0 of the AR8327 switch is connected to the QCA9558 SoC via SGMII */ -+static struct ar8327_pad_cfg e558_v2_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+/* GMAC6 of the AR8327 switch is connected to the QCA9558 SoC via RGMII */ -+static struct ar8327_pad_cfg e558_v2_ar8327_pad6_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static const struct ar8327_led_info e558_v2_leds_qca8334[] = { -+ AR8327_LED_INFO(PHY2_0, HW, "e558-v2:green:wan"), -+ AR8327_LED_INFO(PHY3_0, HW, "e558-v2:green:lan1"), -+ AR8327_LED_INFO(PHY4_0, HW, "e558-v2:green:lan2"), -+}; -+ -+static struct ar8327_led_cfg e558_v2_ar8327_led_cfg = { -+ .led_ctrl0 = 0xc737c737, -+ .led_ctrl1 = 0x00000000, -+ .led_ctrl2 = 0x00000000, -+ .led_ctrl3 = 0x0030c300, -+ .open_drain = false, -+}; -+ -+static struct ar8327_platform_data e558_v2_ar8327_data = { -+ .pad0_cfg = &e558_v2_ar8327_pad0_cfg, -+ .pad6_cfg = &e558_v2_ar8327_pad6_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .port6_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &e558_v2_ar8327_led_cfg, -+ .leds = e558_v2_leds_qca8334, -+ .num_leds = ARRAY_SIZE(e558_v2_leds_qca8334), -+}; -+ -+static struct mdio_board_info e558_v2_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &e558_v2_ar8327_data, -+ }, -+}; -+ -+static void __init e558_v2_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f050400); -+ u8 *art = (u8 *) KSEG1ADDR(0x1f061000); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(e558_v2_leds_gpio), -+ e558_v2_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, E558_V2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(e558_v2_gpio_keys), -+ e558_v2_gpio_keys); -+ -+ ath79_register_mdio(0, 0x0); -+ mdiobus_register_board_info(e558_v2_mdio0_info, -+ ARRAY_SIZE(e558_v2_mdio0_info)); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ /* GMAC0 is connected to the RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x56000000; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_register_eth(1); -+ -+ ath79_register_pci(); -+ ath79_register_usb(); -+ ath79_register_wmac(art, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_E558_V2, "E558-V2", "Qxwlan E558 v2", -+ e558_v2_setup); -+ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-e600g-v2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-e600g-v2.c -new file mode 100644 -index 0000000000..29411dea86 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-e600g-v2.c -@@ -0,0 +1,184 @@ -+/* -+ * Qxwlan E600G/E600GAC v2 board support -+ * -+ * Copyright (C) 2017 Peng Zhang -+ * Copyright (C) 2018 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define E600G_V2_GPIO_LED_LAN 16 -+#define E600G_V2_GPIO_LED_SYS 13 -+#define E600G_V2_GPIO_LED_WAN_B 4 -+#define E600G_V2_GPIO_LED_WAN_G 15 -+ -+#define E600GAC_V2_GPIO_LED_CTRL_B 14 -+#define E600GAC_V2_GPIO_LED_CTRL_G 11 -+#define E600GAC_V2_GPIO_LED_CTRL_R 12 -+#define E600GAC_V2_GPIO_LED_LAN 16 -+#define E600GAC_V2_GPIO_LED_SYS 13 -+#define E600GAC_V2_GPIO_LED_WAN_G 15 -+#define E600GAC_V2_GPIO_LED_WAN_O 4 -+ -+#define E600G_V2_GPIO_BTN_RESET 17 -+#define E600GAC_V2_GPIO_BTN_WPS 1 -+ -+#define E600G_V2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define E600G_V2_KEYS_DEBOUNCE_INTERVAL (3 * E600G_V2_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led e600g_v2_leds_gpio[] __initdata = { -+ { -+ .name = "e600g-v2:blue:system", -+ .gpio = E600G_V2_GPIO_LED_SYS, -+ .active_low = 1, -+ }, { -+ .name = "e600g-v2:blue:wan", -+ .gpio = E600G_V2_GPIO_LED_WAN_B, -+ .active_low = 1, -+ }, { -+ .name = "e600g-v2:green:lan", -+ .gpio = E600G_V2_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "e600g-v2:green:wan", -+ .gpio = E600G_V2_GPIO_LED_WAN_G, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led e600gac_v2_leds_gpio[] __initdata = { -+ { -+ .name = "e600gac-v2:blue:control", -+ .gpio = E600GAC_V2_GPIO_LED_CTRL_B, -+ .active_low = 1, -+ }, { -+ .name = "e600gac-v2:green:control", -+ .gpio = E600GAC_V2_GPIO_LED_CTRL_G, -+ .active_low = 1, -+ }, { -+ .name = "e600gac-v2:red:control", -+ .gpio = E600GAC_V2_GPIO_LED_CTRL_R, -+ .active_low = 1, -+ }, { -+ .name = "e600gac-v2:green:system", -+ .gpio = E600GAC_V2_GPIO_LED_SYS, -+ .active_low = 1, -+ }, { -+ .name = "e600gac-v2:orange:wan", -+ .gpio = E600GAC_V2_GPIO_LED_WAN_O, -+ .active_low = 1, -+ }, { -+ .name = "e600gac-v2:green:lan", -+ .gpio = E600GAC_V2_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "e600gac-v2:green:wan", -+ .gpio = E600GAC_V2_GPIO_LED_WAN_G, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button e600g_v2_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = E600G_V2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = E600G_V2_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button e600gac_v2_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = E600G_V2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = E600G_V2_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = E600G_V2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = E600GAC_V2_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init e600g_v2_common_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f050400); -+ u8 *art = (u8 *) KSEG1ADDR(0x1f061000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = 0xfe; -+ -+ /* LAN */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_register_eth(0); -+ -+ /* WAN */ -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.phy_mask = BIT(0); -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_register_eth(1); -+ -+ ath79_register_pci(); -+ ath79_register_usb(); -+ ath79_register_wmac(art, NULL); -+} -+ -+static void __init e600g_v2_setup(void) -+{ -+ e600g_v2_common_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(e600g_v2_leds_gpio), -+ e600g_v2_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, E600G_V2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(e600g_v2_gpio_keys), -+ e600g_v2_gpio_keys); -+} -+ -+static void __init e600gac_v2_setup(void) -+{ -+ e600g_v2_common_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(e600gac_v2_leds_gpio), -+ e600gac_v2_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, E600G_V2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(e600gac_v2_gpio_keys), -+ e600gac_v2_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_E600G_V2, "E600G-V2", "Qxwlan E600G v2", -+ e600g_v2_setup); -+ -+MIPS_MACHINE(ATH79_MACH_E600GAC_V2, "E600GAC-V2", "Qxwlan E600GAC v2", -+ e600gac_v2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-e750a-v4.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-e750a-v4.c -new file mode 100644 -index 0000000000..7cf3292c68 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-e750a-v4.c -@@ -0,0 +1,122 @@ -+/* -+ * Qxwlan E750A v4 board support -+ * -+ * Copyright (C) 2017 Peng Zhang -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define E750A_V4_GPIO_LED_SYS 14 -+#define E750A_V4_GPIO_LED_LAN 19 -+#define E750A_V4_GPIO_LED_WAN 18 -+#define E750A_V4_GPIO_LED_DS10 15 -+#define E750A_V4_GPIO_LED_DS20 20 -+#define E750A_V4_GPIO_LED_WLAN 21 -+ -+#define E750A_V4_GPIO_BTN_RESET 12 -+ -+#define E750A_V4_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define E750A_V4_KEYS_DEBOUNCE_INTERVAL (3 * E750A_V4_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led e750a_v4_leds_gpio[] __initdata = { -+ { -+ .name = "e750a-v4:green:system", -+ .gpio = E750A_V4_GPIO_LED_SYS, -+ .active_low = 1, -+ }, -+ { -+ .name = "e750a-v4:green:lan", -+ .gpio = E750A_V4_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "e750a-v4:green:wan", -+ .gpio = E750A_V4_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "e750a-v4:green:wlan", -+ .gpio = E750A_V4_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "e750a-v4:green:ds10", -+ .gpio = E750A_V4_GPIO_LED_DS10, -+ .active_low = 1, -+ }, -+ { -+ .name = "e750a-v4:green:ds20", -+ .gpio = E750A_V4_GPIO_LED_DS20, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button e750a_v4_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = E750A_V4_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = E750A_V4_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+ -+static void __init e750a_v4_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f050400); -+ u8 *art = (u8 *) KSEG1ADDR(0x1f061000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(e750a_v4_leds_gpio), -+ e750a_v4_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, E750A_V4_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(e750a_v4_gpio_keys), -+ e750a_v4_gpio_keys); -+ -+ ath79_register_mdio(1, 0x0); -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_register_eth(1); -+ -+ /* GMAC0 is connected to the PHY4 of the internal switch */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(4); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_register_eth(0); -+ -+ ath79_register_pci(); -+ ath79_register_usb(); -+ ath79_register_wmac(art, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_E750A_V4, "E750A-V4", "Qxlan E750A v4", -+ e750a_v4_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-e750g-v8.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-e750g-v8.c -new file mode 100644 -index 0000000000..9252d1d5ad ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-e750g-v8.c -@@ -0,0 +1,151 @@ -+/* -+ * Qxwlan E750G v8 board support -+ * -+ * Copyright (C) 2017 Peng Zhang -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-usb.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define E750G_V8_GPIO_LED_SYS 14 -+#define E750G_V8_GPIO_LED_DS20 15 -+#define E750G_V8_GPIO_LED_DS10 20 -+#define E750G_V8_GPIO_LED_WLAN 21 -+ -+#define E750G_V8_GPIO_BTN_RESET 12 -+ -+#define E750G_V8_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define E750G_V8_KEYS_DEBOUNCE_INTERVAL (3 * E750G_V8_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led e750g_v8_leds_gpio[] __initdata = { -+ { -+ .name = "e750g-v8:green:system", -+ .gpio = E750G_V8_GPIO_LED_SYS, -+ .active_low = 1, -+ }, -+ { -+ .name = "e750g-v8:green:ds10", -+ .gpio = E750G_V8_GPIO_LED_DS10, -+ .active_low = 1, -+ }, -+ { -+ .name = "e750g-v8:green:ds20", -+ .gpio = E750G_V8_GPIO_LED_DS20, -+ .active_low = 1, -+ }, -+ { -+ .name = "e750g-v8:green:wlan", -+ .gpio = E750G_V8_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button e750g_v8_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = E750G_V8_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = E750G_V8_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static const struct ar8327_led_info e750g_v8_leds_qca8334[] = { -+ AR8327_LED_INFO(PHY1_0, HW, "e750g-v8:green:lan"), -+ AR8327_LED_INFO(PHY2_0, HW, "e750g-v8:green:wan"), -+}; -+ -+static struct ar8327_pad_cfg e750g_v8_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+ .mac06_exchange_dis = true, -+}; -+ -+static struct ar8327_led_cfg e750g_v8_ar8327_led_cfg = { -+ .led_ctrl0 = 0x00000000, -+ .led_ctrl1 = 0xc737c737, -+ .led_ctrl2 = 0x00000000, -+ .led_ctrl3 = 0x00c30c00, -+ .open_drain = true, -+}; -+ -+static struct ar8327_platform_data e750g_v8_ar8327_data = { -+ .pad0_cfg = &e750g_v8_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &e750g_v8_ar8327_led_cfg, -+ .leds = e750g_v8_leds_qca8334, -+ .num_leds = ARRAY_SIZE(e750g_v8_leds_qca8334), -+}; -+ -+static struct mdio_board_info e750g_v8_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &e750g_v8_ar8327_data, -+ }, -+}; -+ -+static void __init e750g_v8_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f050400); -+ u8 *art = (u8 *) KSEG1ADDR(0x1f061000); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(e750g_v8_leds_gpio), -+ e750g_v8_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, E750G_V8_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(e750g_v8_gpio_keys), -+ e750g_v8_gpio_keys); -+ -+ mdiobus_register_board_info(e750g_v8_mdio0_info, -+ ARRAY_SIZE(e750g_v8_mdio0_info)); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ /* GMAC0 is connected to an AR8327 switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_register_eth(0); -+ -+ ath79_register_pci(); -+ ath79_register_usb(); -+ ath79_register_wmac(art, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_E750G_V8, "E750G-V8", "Qxwlan E750G v8", -+ e750g_v8_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-eap120.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-eap120.c -new file mode 100644 -index 0000000000..130c7706a6 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-eap120.c -@@ -0,0 +1,126 @@ -+/* -+ * TP-LINK EAP120 board support -+ * -+ * Copyright (C) 2016 Henryk Heisig -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+ -+#define EAP120_GPIO_LED_RED 12 -+#define EAP120_GPIO_LED_YEL 13 -+#define EAP120_GPIO_LED_GRN 15 -+#define EAP120_GPIO_BTN_RESET 4 -+ -+#define EAP120_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define EAP120_KEYS_DEBOUNCE_INTERVAL (3 * EAP120_KEYS_POLL_INTERVAL) -+ -+#define EAP120_GPIO_SMI_MDIO 16 -+#define EAP120_GPIO_SMI_MDC 17 -+ -+#define EAP120_LAN_PHYADDR 4 -+ -+static struct gpio_led eap120_leds_gpio[] __initdata = { -+ { -+ .name = "eap120:red:system", -+ .gpio = EAP120_GPIO_LED_RED, -+ .active_low = 1, -+ }, { -+ .name = "eap120:yellow:system", -+ .gpio = EAP120_GPIO_LED_YEL, -+ .active_low = 1, -+ }, { -+ .name = "eap120:green:system", -+ .gpio = EAP120_GPIO_LED_GRN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button eap120_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = EAP120_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = EAP120_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static struct mdio_gpio_platform_data eap120_mdio = { -+ .mdc = EAP120_GPIO_SMI_MDC, -+ .mdio = EAP120_GPIO_SMI_MDIO, -+ .phy_mask = ~BIT(EAP120_LAN_PHYADDR), -+}; -+ -+static struct at803x_platform_data eap120_ar8035_data = { -+ .disable_smarteee = 0, -+ .enable_rgmii_rx_delay = 1, -+ .enable_rgmii_tx_delay = 0, -+ .fixup_rgmii_tx_delay = 1, -+}; -+ -+static struct platform_device eap120_phy_device = { -+ .name = "mdio-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &eap120_mdio, &eap120_ar8035_data -+ }, -+}; -+ -+static void __init eap_setup(u8 *mac) -+{ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(eap120_leds_gpio), -+ eap120_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, EAP120_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(eap120_gpio_keys), -+ eap120_gpio_keys); -+ -+ ath79_register_m25p80(NULL); -+ -+ /* MDIO Interface */ -+ platform_device_register(&eap120_phy_device); -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0); -+ -+ /* GMAC0 is connected to the RGMII interface to an Atheros AR8035-A */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_eth0_data.mii_bus_dev = &eap120_phy_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(EAP120_LAN_PHYADDR); -+ ath79_eth0_pll_data.pll_1000 = 0x0e000000; -+ ath79_eth0_pll_data.pll_100 = 0x00000101; -+ ath79_eth0_pll_data.pll_10 = 0x00001313; -+ ath79_register_eth(0); -+} -+ -+static void __init eap120_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f030008); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ eap_setup(mac); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_EAP120, "EAP120", "TP-LINK EAP120", -+ eap120_setup); -+ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-eap300v2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-eap300v2.c -new file mode 100644 -index 0000000000..ba577e2517 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-eap300v2.c -@@ -0,0 +1,101 @@ -+/* -+ * EnGenius EAP300 v2 board support -+ * -+ * Copyright (C) 2014 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define EAP300V2_GPIO_LED_POWER 0 -+#define EAP300V2_GPIO_LED_LAN 16 -+#define EAP300V2_GPIO_LED_WLAN 17 -+ -+#define EAP300V2_GPIO_BTN_RESET 1 -+ -+#define EAP300V2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define EAP300V2_KEYS_DEBOUNCE_INTERVAL (3 * EAP300V2_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led eap300v2_leds_gpio[] __initdata = { -+ { -+ .name = "engenius:blue:power", -+ .gpio = EAP300V2_GPIO_LED_POWER, -+ .active_low = 1, -+ }, { -+ .name = "engenius:blue:lan", -+ .gpio = EAP300V2_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "engenius:blue:wlan", -+ .gpio = EAP300V2_GPIO_LED_WLAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button eap300v2_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = EAP300V2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = EAP300V2_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+#define EAP300V2_ART_MAC_OFFSET 2 -+ -+#define EAP300V2_LAN_PHYMASK BIT(0) -+ -+static void __init eap300v2_setup(void) -+{ -+ u8 *art = (u8 *)KSEG1ADDR(0x1fff1000); -+ -+ ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE); -+ -+ ath79_gpio_output_select(EAP300V2_GPIO_LED_POWER, AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(EAP300V2_GPIO_LED_LAN, AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(EAP300V2_GPIO_LED_WLAN, AR934X_GPIO_OUT_GPIO); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(eap300v2_leds_gpio), -+ eap300v2_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, EAP300V2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(eap300v2_gpio_keys), -+ eap300v2_gpio_keys); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_wmac(art, NULL); -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_PHY_SWAP); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ art + EAP300V2_ART_MAC_OFFSET, 0); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = EAP300V2_LAN_PHYMASK; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = EAP300V2_LAN_PHYMASK; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_EAP300V2, "EAP300V2", "EnGenius EAP300 v2", -+ eap300v2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-eap7660d.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-eap7660d.c -new file mode 100644 -index 0000000000..787e6275d6 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-eap7660d.c -@@ -0,0 +1,181 @@ -+/* -+ * Senao EAP7660D board support -+ * -+ * Copyright (C) 2010 Daniel Golle -+ * Copyright (C) 2008 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define EAP7660D_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define EAP7660D_KEYS_DEBOUNCE_INTERVAL (3 * EAP7660D_KEYS_POLL_INTERVAL) -+ -+#define EAP7660D_GPIO_DS4 7 -+#define EAP7660D_GPIO_DS5 2 -+#define EAP7660D_GPIO_DS7 0 -+#define EAP7660D_GPIO_DS8 4 -+#define EAP7660D_GPIO_SW1 3 -+#define EAP7660D_GPIO_SW3 8 -+#define EAP7660D_PHYMASK BIT(20) -+#define EAP7660D_BOARDCONFIG 0x1F7F0000 -+#define EAP7660D_GBIC_MAC_OFFSET 0x1000 -+#define EAP7660D_WMAC0_MAC_OFFSET 0x1010 -+#define EAP7660D_WMAC1_MAC_OFFSET 0x1016 -+#define EAP7660D_WMAC0_CALDATA_OFFSET 0x2000 -+#define EAP7660D_WMAC1_CALDATA_OFFSET 0x3000 -+ -+#ifdef CONFIG_PCI -+static struct ath5k_platform_data eap7660d_wmac0_data; -+static struct ath5k_platform_data eap7660d_wmac1_data; -+static char eap7660d_wmac0_mac[6]; -+static char eap7660d_wmac1_mac[6]; -+static u16 eap7660d_wmac0_eeprom[ATH5K_PLAT_EEP_MAX_WORDS]; -+static u16 eap7660d_wmac1_eeprom[ATH5K_PLAT_EEP_MAX_WORDS]; -+ -+static int eap7660d_pci_plat_dev_init(struct pci_dev *dev) -+{ -+ switch (PCI_SLOT(dev->devfn)) { -+ case 17: -+ dev->dev.platform_data = &eap7660d_wmac0_data; -+ break; -+ -+ case 18: -+ dev->dev.platform_data = &eap7660d_wmac1_data; -+ break; -+ } -+ -+ return 0; -+} -+ -+void __init eap7660d_pci_init(u8 *cal_data0, u8 *mac_addr0, -+ u8 *cal_data1, u8 *mac_addr1) -+{ -+ if (cal_data0 && *cal_data0 == 0xa55a) { -+ memcpy(eap7660d_wmac0_eeprom, cal_data0, -+ ATH5K_PLAT_EEP_MAX_WORDS); -+ eap7660d_wmac0_data.eeprom_data = eap7660d_wmac0_eeprom; -+ } -+ -+ if (cal_data1 && *cal_data1 == 0xa55a) { -+ memcpy(eap7660d_wmac1_eeprom, cal_data1, -+ ATH5K_PLAT_EEP_MAX_WORDS); -+ eap7660d_wmac1_data.eeprom_data = eap7660d_wmac1_eeprom; -+ } -+ -+ if (mac_addr0) { -+ memcpy(eap7660d_wmac0_mac, mac_addr0, -+ sizeof(eap7660d_wmac0_mac)); -+ eap7660d_wmac0_data.macaddr = eap7660d_wmac0_mac; -+ } -+ -+ if (mac_addr1) { -+ memcpy(eap7660d_wmac1_mac, mac_addr1, -+ sizeof(eap7660d_wmac1_mac)); -+ eap7660d_wmac1_data.macaddr = eap7660d_wmac1_mac; -+ } -+ -+ ath79_pci_set_plat_dev_init(eap7660d_pci_plat_dev_init); -+ ath79_register_pci(); -+} -+#else -+static inline void eap7660d_pci_init(u8 *cal_data0, u8 *mac_addr0, -+ u8 *cal_data1, u8 *mac_addr1) -+{ -+} -+#endif /* CONFIG_PCI */ -+ -+static struct gpio_led eap7660d_leds_gpio[] __initdata = { -+ { -+ .name = "eap7660d:green:ds8", -+ .gpio = EAP7660D_GPIO_DS8, -+ .active_low = 0, -+ }, -+ { -+ .name = "eap7660d:green:ds5", -+ .gpio = EAP7660D_GPIO_DS5, -+ .active_low = 0, -+ }, -+ { -+ .name = "eap7660d:green:ds7", -+ .gpio = EAP7660D_GPIO_DS7, -+ .active_low = 0, -+ }, -+ { -+ .name = "eap7660d:green:ds4", -+ .gpio = EAP7660D_GPIO_DS4, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button eap7660d_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = EAP7660D_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = EAP7660D_GPIO_SW1, -+ .active_low = 1, -+ }, -+ { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = EAP7660D_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = EAP7660D_GPIO_SW3, -+ .active_low = 1, -+ } -+}; -+ -+static const char *eap7660d_part_probes[] = { -+ "RedBoot", -+ NULL, -+}; -+ -+static struct flash_platform_data eap7660d_flash_data = { -+ .part_probes = eap7660d_part_probes, -+}; -+ -+static void __init eap7660d_setup(void) -+{ -+ u8 *boardconfig = (u8 *) KSEG1ADDR(EAP7660D_BOARDCONFIG); -+ -+ ath79_register_mdio(0, ~EAP7660D_PHYMASK); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ boardconfig + EAP7660D_GBIC_MAC_OFFSET, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = EAP7660D_PHYMASK; -+ ath79_register_eth(0); -+ ath79_register_m25p80(&eap7660d_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(eap7660d_leds_gpio), -+ eap7660d_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, EAP7660D_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(eap7660d_gpio_keys), -+ eap7660d_gpio_keys); -+ eap7660d_pci_init(boardconfig + EAP7660D_WMAC0_CALDATA_OFFSET, -+ boardconfig + EAP7660D_WMAC0_MAC_OFFSET, -+ boardconfig + EAP7660D_WMAC1_CALDATA_OFFSET, -+ boardconfig + EAP7660D_WMAC1_MAC_OFFSET); -+}; -+ -+MIPS_MACHINE(ATH79_MACH_EAP7660D, "EAP7660D", "Senao EAP7660D", -+ eap7660d_setup); -+ -+MIPS_MACHINE(ATH79_MACH_ALL0305, "ALL0305", "Allnet ALL0305", -+ eap7660d_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-el-m150.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-el-m150.c -new file mode 100644 -index 0000000000..b95d6c2f68 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-el-m150.c -@@ -0,0 +1,112 @@ -+/* -+ * Easy-Link EL-M150 board support -+ * -+ * Copyright (C) 2012 huangfc -+ * Copyright (C) 2012 HYS <550663898@qq.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "dev-usb.h" -+ -+#define EL_M150_GPIO_BTN6 6 -+#define EL_M150_GPIO_BTN7 7 -+#define EL_M150_GPIO_BTN_RESET 11 -+ -+#define EL_M150_GPIO_LED_SYSTEM 27 -+#define EL_M150_GPIO_USB_POWER 8 -+ -+#define EL_M150_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define EL_M150_KEYS_DEBOUNCE_INTERVAL (3 * EL_M150_KEYS_POLL_INTERVAL) -+ -+static const char *EL_M150_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data EL_M150_flash_data = { -+ .part_probes = EL_M150_part_probes, -+}; -+ -+static struct gpio_led EL_M150_leds_gpio[] __initdata = { -+ { -+ .name = "easylink:green:system", -+ .gpio = EL_M150_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button EL_M150_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = EL_M150_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = EL_M150_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+ { -+ .desc = "BTN_6", -+ .type = EV_KEY, -+ .code = BTN_6, -+ .debounce_interval = EL_M150_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = EL_M150_GPIO_BTN6, -+ .active_low = 1, -+ }, -+ { -+ .desc = "BTN_7", -+ .type = EV_KEY, -+ .code = BTN_7, -+ .debounce_interval = EL_M150_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = EL_M150_GPIO_BTN7, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init el_m150_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(EL_M150_leds_gpio), -+ EL_M150_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, EL_M150_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(EL_M150_gpio_keys), -+ EL_M150_gpio_keys); -+ -+ gpio_request_one(EL_M150_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ ath79_register_m25p80(&EL_M150_flash_data); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_EL_M150, "EL-M150", -+ "EasyLink EL-M150", el_m150_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-el-mini.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-el-mini.c -new file mode 100644 -index 0000000000..9879b18f7c ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-el-mini.c -@@ -0,0 +1,86 @@ -+/* -+ * Easy-Link EL-MINI board support -+ * -+ * Copyright (C) 2012 huangfc -+ * Copyright (C) 2011 hys <550663898@qq.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define MINI_GPIO_LED_SYSTEM 27 -+#define MINI_GPIO_BTN_RESET 11 -+ -+#define MINI_GPIO_USB_POWER 8 -+ -+#define MINI_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define MINI_KEYS_DEBOUNCE_INTERVAL (3 * MINI_KEYS_POLL_INTERVAL) -+ -+static const char *mini_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data mini_flash_data = { -+ .part_probes = mini_part_probes, -+}; -+ -+static struct gpio_led mini_leds_gpio[] __initdata = { -+ { -+ .name = "easylink:green:system", -+ .gpio = MINI_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button mini_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = MINI_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MINI_GPIO_BTN_RESET, -+ .active_low = 0, -+ } -+}; -+ -+static void __init el_mini_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_m25p80(&mini_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(mini_leds_gpio), -+ mini_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, MINI_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(mini_gpio_keys), -+ mini_gpio_keys); -+ -+ gpio_request_one(MINI_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, -1); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_EL_MINI, "EL-MINI", "EasyLink EL-MINI", -+ el_mini_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ens202ext.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ens202ext.c -new file mode 100644 -index 0000000000..07dbc2e69d ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ens202ext.c -@@ -0,0 +1,124 @@ -+/* -+ * EnGenius ENS202EXT board support -+ * -+ * Copyright (C) 2017 Marty Plummer -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "nvram.h" -+ -+#define ENS202_GPIO_LED_WLAN4 0 -+#define ENS202_GPIO_LED_POWER 14 -+#define ENS202_GPIO_LED_WLAN2 16 -+#define ENS202_GPIO_LED_WLAN3 17 -+#define ENS202_GPIO_LED_WLAN1 18 -+ -+#define ENS202_GPIO_BTN_RESET 1 -+ -+#define ENS202_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define ENS202_KEYS_DEBOUNCE_INTERVAL (3 * ENS202_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led ens202_leds_gpio[] __initdata = { -+ { -+ .name = "engenius:amber:wlan1", -+ .gpio = ENS202_GPIO_LED_WLAN1, -+ .active_low = 1, -+ }, { -+ .name = "engenius:red:wlan2", -+ .gpio = ENS202_GPIO_LED_WLAN2, -+ .active_low = 1, -+ }, { -+ .name = "engenius:amber:wlan3", -+ .gpio = ENS202_GPIO_LED_WLAN3, -+ .active_low = 1, -+ }, { -+ .name = "engenius:green:wlan4", -+ .gpio = ENS202_GPIO_LED_WLAN4, -+ .active_low = 1, -+ }, { -+ .name = "engenius:amber:power", -+ .gpio = ENS202_GPIO_LED_POWER, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button ens202_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ENS202_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ENS202_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init ens202_setup(void) -+{ -+ const char *nvram = (char *) KSEG1ADDR(0x1f040000); -+ u8 mac_buff[6]; -+ u8 *mac = NULL; -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ if (ath79_nvram_parse_mac_addr(nvram, 0x10000, -+ "ethaddr=", mac_buff) == 0) { -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac_buff, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac_buff, 1); -+ mac = mac_buff; -+ } -+ -+ ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE); -+ -+ ath79_gpio_output_select(ENS202_GPIO_LED_POWER, AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(ENS202_GPIO_LED_WLAN1, AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(ENS202_GPIO_LED_WLAN2, AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(ENS202_GPIO_LED_WLAN3, AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(ENS202_GPIO_LED_WLAN4, AR934X_GPIO_OUT_GPIO); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ens202_leds_gpio), -+ ens202_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, ENS202_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ens202_gpio_keys), -+ ens202_gpio_keys); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_wmac(art + 0x1000, NULL); -+ -+ ath79_register_mdio(1, 0); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_SW_ONLY_MODE); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ENS202EXT, "ENS202EXT", "EnGenius ENS202EXT", -+ ens202_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-epg5000.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-epg5000.c -new file mode 100644 -index 0000000000..89d6ec6fe3 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-epg5000.c -@@ -0,0 +1,177 @@ -+/* -+ * EnGenius EPG5000 board support -+ * -+ * Copyright (c) 2014 Jon Suphammer -+ * Copyright (c) 2015 Christian Beier -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "nvram.h" -+ -+#define EPG5000_GPIO_LED_WLAN_5G 23 -+#define EPG5000_GPIO_LED_WLAN_2G 13 -+#define EPG5000_GPIO_LED_POWER_AMBER 2 -+#define EPG5000_GPIO_LED_WPS_AMBER 22 -+#define EPG5000_GPIO_LED_WPS_BLUE 19 -+ -+#define EPG5000_GPIO_BTN_WPS 16 -+#define EPG5000_GPIO_BTN_RESET 17 -+ -+#define EPG5000_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define EPG5000_KEYS_DEBOUNCE_INTERVAL (3 * EPG5000_KEYS_POLL_INTERVAL) -+ -+#define EPG5000_CALDATA_ADDR 0x1fff0000 -+#define EPG5000_WMAC_CALDATA_OFFSET 0x1000 -+#define EPG5000_PCIE_CALDATA_OFFSET 0x5000 -+ -+#define EPG5000_NVRAM_ADDR 0x1f030000 -+#define EPG5000_NVRAM_SIZE 0x10000 -+ -+static struct gpio_led epg5000_leds_gpio[] __initdata = { -+ { -+ .name = "epg5000:amber:power", -+ .gpio = EPG5000_GPIO_LED_POWER_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "epg5000:blue:wps", -+ .gpio = EPG5000_GPIO_LED_WPS_BLUE, -+ .active_low = 1, -+ }, -+ { -+ .name = "epg5000:amber:wps", -+ .gpio = EPG5000_GPIO_LED_WPS_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "epg5000:blue:wlan-2g", -+ .gpio = EPG5000_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "epg5000:blue:wlan-5g", -+ .gpio = EPG5000_GPIO_LED_WLAN_5G, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button epg5000_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = EPG5000_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = EPG5000_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = EPG5000_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = EPG5000_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg epg5000_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_platform_data epg5000_ar8327_data = { -+ .pad0_cfg = &epg5000_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info epg5000_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &epg5000_ar8327_data, -+ }, -+}; -+ -+static int epg5000_get_mac(const char *name, char *mac) -+{ -+ u8 *nvram = (u8 *) KSEG1ADDR(EPG5000_NVRAM_ADDR); -+ int err; -+ -+ err = ath79_nvram_parse_mac_addr(nvram, EPG5000_NVRAM_SIZE, -+ name, mac); -+ if (err) { -+ pr_err("no MAC address found for %s\n", name); -+ return false; -+ } -+ -+ return true; -+} -+ -+static void __init epg5000_setup(void) -+{ -+ u8 *caldata = (u8 *) KSEG1ADDR(EPG5000_CALDATA_ADDR); -+ u8 mac1[ETH_ALEN]; -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(epg5000_leds_gpio), -+ epg5000_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, EPG5000_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(epg5000_gpio_keys), -+ epg5000_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(epg5000_mdio0_info, -+ ARRAY_SIZE(epg5000_mdio0_info)); -+ -+ /* GMAC0 is connected to an QCA8327N switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ if (epg5000_get_mac("ethaddr=", mac1)) -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); -+ -+ ath79_eth0_pll_data.pll_1000 = 0xa6000000; -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(caldata + EPG5000_WMAC_CALDATA_OFFSET, mac1); -+ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_EPG5000, "EPG5000", -+ "EnGenius EPG5000", -+ epg5000_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-esr1750.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-esr1750.c -new file mode 100644 -index 0000000000..c275ef6f1b ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-esr1750.c -@@ -0,0 +1,176 @@ -+/* -+ * EnGenius ESR1750 board support -+ * -+ * Copyright (c) 2014 Jon Suphammer -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "nvram.h" -+ -+#define ESR1750_GPIO_LED_WLAN_5G 23 -+#define ESR1750_GPIO_LED_WLAN_2G 13 -+#define ESR1750_GPIO_LED_POWER_AMBER 2 -+#define ESR1750_GPIO_LED_WPS_AMBER 22 -+#define ESR1750_GPIO_LED_WPS_BLUE 19 -+ -+#define ESR1750_GPIO_BTN_WPS 16 -+#define ESR1750_GPIO_BTN_RESET 17 -+ -+#define ESR1750_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define ESR1750_KEYS_DEBOUNCE_INTERVAL (3 * ESR1750_KEYS_POLL_INTERVAL) -+ -+#define ESR1750_CALDATA_ADDR 0x1fff0000 -+#define ESR1750_WMAC_CALDATA_OFFSET 0x1000 -+#define ESR1750_PCIE_CALDATA_OFFSET 0x5000 -+ -+#define ESR1750_NVRAM_ADDR 0x1f030000 -+#define ESR1750_NVRAM_SIZE 0x10000 -+ -+static struct gpio_led esr1750_leds_gpio[] __initdata = { -+ { -+ .name = "esr1750:amber:power", -+ .gpio = ESR1750_GPIO_LED_POWER_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "esr1750:blue:wps", -+ .gpio = ESR1750_GPIO_LED_WPS_BLUE, -+ .active_low = 1, -+ }, -+ { -+ .name = "esr1750:amber:wps", -+ .gpio = ESR1750_GPIO_LED_WPS_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "esr1750:blue:wlan-2g", -+ .gpio = ESR1750_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "esr1750:blue:wlan-5g", -+ .gpio = ESR1750_GPIO_LED_WLAN_5G, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button esr1750_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = ESR1750_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ESR1750_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ESR1750_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ESR1750_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg esr1750_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_platform_data esr1750_ar8327_data = { -+ .pad0_cfg = &esr1750_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info esr1750_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &esr1750_ar8327_data, -+ }, -+}; -+ -+static int esr1750_get_mac(const char *name, char *mac) -+{ -+ u8 *nvram = (u8 *) KSEG1ADDR(ESR1750_NVRAM_ADDR); -+ int err; -+ -+ err = ath79_nvram_parse_mac_addr(nvram, ESR1750_NVRAM_SIZE, -+ name, mac); -+ if (err) { -+ pr_err("no MAC address found for %s\n", name); -+ return false; -+ } -+ -+ return true; -+} -+ -+static void __init esr1750_setup(void) -+{ -+ u8 *caldata = (u8 *) KSEG1ADDR(ESR1750_CALDATA_ADDR); -+ u8 mac1[ETH_ALEN]; -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(esr1750_leds_gpio), -+ esr1750_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, ESR1750_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(esr1750_gpio_keys), -+ esr1750_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(esr1750_mdio0_info, -+ ARRAY_SIZE(esr1750_mdio0_info)); -+ -+ /* GMAC0 is connected to an QCA8327N switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ if (esr1750_get_mac("ethaddr=", mac1)) -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); -+ -+ ath79_eth0_pll_data.pll_1000 = 0xa6000000; -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(caldata + ESR1750_WMAC_CALDATA_OFFSET, mac1); -+ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ESR1750, "ESR1750", -+ "EnGenius ESR1750", -+ esr1750_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-esr900.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-esr900.c -new file mode 100644 -index 0000000000..cf2ee9295a ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-esr900.c -@@ -0,0 +1,200 @@ -+/* -+ * EnGenius ESR900 board support -+ * -+ * Copyright (C) 2008-2012 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#define pr_fmt(fmt) "esr900: " fmt -+ -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "nvram.h" -+ -+#define ESR900_GPIO_LED_POWER 2 -+#define ESR900_GPIO_LED_WLAN_2G 13 -+#define ESR900_GPIO_LED_WPS_BLUE 19 -+#define ESR900_GPIO_LED_WPS_AMBER 22 -+#define ESR900_GPIO_LED_WLAN_5G 23 -+ -+#define ESR900_GPIO_BTN_WPS 16 -+#define ESR900_GPIO_BTN_RESET 17 -+ -+#define ESR900_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define ESR900_KEYS_DEBOUNCE_INTERVAL (3 * ESR900_KEYS_POLL_INTERVAL) -+ -+#define ESR900_CALDATA_ADDR 0x1fff0000 -+#define ESR900_WMAC_CALDATA_OFFSET 0x1000 -+#define ESR900_PCIE_CALDATA_OFFSET 0x5000 -+ -+#define ESR900_CONFIG_ADDR 0x1f030000 -+#define ESR900_CONFIG_SIZE 0x10000 -+ -+#define ESR900_LAN_PHYMASK BIT(0) -+#define ESR900_WAN_PHYMASK BIT(5) -+#define ESR900_MDIO_MASK (~(ESR900_LAN_PHYMASK | ESR900_WAN_PHYMASK)) -+ -+static struct gpio_led esr900_leds_gpio[] __initdata = { -+ { -+ .name = "engenius:amber:power", -+ .gpio = ESR900_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "engenius:blue:wlan-2g", -+ .gpio = ESR900_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "engenius:blue:wps", -+ .gpio = ESR900_GPIO_LED_WPS_BLUE, -+ .active_low = 1, -+ }, -+ { -+ .name = "engenius:amber:wps", -+ .gpio = ESR900_GPIO_LED_WPS_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "engenius:blue:wlan-5g", -+ .gpio = ESR900_GPIO_LED_WLAN_5G, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button esr900_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = ESR900_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ESR900_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ESR900_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ESR900_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg esr900_ar8327_pad0_cfg = { -+ /* GMAC0 of the AR8337 switch is connected to GMAC0 via RGMII */ -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_pad_cfg esr900_ar8327_pad6_cfg = { -+ /* GMAC6 of the AR8337 switch is connected to GMAC1 via SGMII */ -+ .mode = AR8327_PAD_MAC_SGMII, -+ .rxclk_delay_en = true, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL0, -+}; -+ -+static struct ar8327_platform_data esr900_ar8327_data = { -+ .pad0_cfg = &esr900_ar8327_pad0_cfg, -+ .pad6_cfg = &esr900_ar8327_pad6_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .port6_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info esr900_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &esr900_ar8327_data, -+ }, -+}; -+ -+static void __init esr900_setup(void) -+{ -+ const char *config = (char *) KSEG1ADDR(ESR900_CONFIG_ADDR); -+ u8 *art = (u8 *) KSEG1ADDR(ESR900_CALDATA_ADDR); -+ u8 lan_mac[ETH_ALEN]; -+ u8 wlan0_mac[ETH_ALEN]; -+ u8 wlan1_mac[ETH_ALEN]; -+ -+ if (ath79_nvram_parse_mac_addr(config, ESR900_CONFIG_SIZE, -+ "ethaddr=", lan_mac) == 0) { -+ ath79_init_local_mac(ath79_eth0_data.mac_addr, lan_mac); -+ ath79_init_mac(wlan0_mac, lan_mac, 0); -+ ath79_init_mac(wlan1_mac, lan_mac, 1); -+ } else { -+ pr_err("could not find ethaddr in u-boot environment\n"); -+ } -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(esr900_leds_gpio), -+ esr900_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, ESR900_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(esr900_gpio_keys), -+ esr900_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_register_wmac(art + ESR900_WMAC_CALDATA_OFFSET, wlan0_mac); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(esr900_mdio0_info, -+ ARRAY_SIZE(esr900_mdio0_info)); -+ -+ /* GMAC0 is connected to the RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = ESR900_LAN_PHYMASK; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ ath79_eth0_pll_data.pll_1000 = 0xa6000000; -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ ath79_register_eth(1); -+ -+ ap91_pci_init(art + ESR900_PCIE_CALDATA_OFFSET, wlan1_mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ESR900, "ESR900", "EnGenius ESR900", esr900_setup); -+ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ew-balin.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ew-balin.c -new file mode 100644 -index 0000000000..2e82ffdaa1 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ew-balin.c -@@ -0,0 +1,110 @@ -+/* -+ * EW Balin board support -+ * (based on Atheros DB120 reference board support) -+ * -+ * Copyright (c) 2011 Qualcomm Atheros -+ * Copyright (c) 2011-2012 Gabor Juhos -+ * Copyright (C) 2017 Embedded Wireless GmbH www.80211.de -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define BALIN_GPIO_LED_STATUS 14 -+ -+#define BALIN_GPIO_BTN_WPS 18 -+ -+#define BALIN_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define BALIN_KEYS_DEBOUNCE_INTERVAL (3 * BALIN_KEYS_POLL_INTERVAL) -+ -+#define BALIN_CALDATA_OFFSET 0x1000 -+#define BALIN_WMAC_MAC_OFFSET (BALIN_CALDATA_OFFSET + 0x02) -+ -+static struct gpio_led balin_leds_gpio[] __initdata = { -+ { -+ .name = "balin:green:status", -+ .gpio = BALIN_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button balin_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = BALIN_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = BALIN_GPIO_BTN_WPS, -+ .active_low = 0, -+ }, -+}; -+ -+ -+static void __init balin_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ static u8 mac[6]; -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(balin_leds_gpio), -+ balin_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, BALIN_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(balin_gpio_keys), -+ balin_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_register_wmac(art + BALIN_CALDATA_OFFSET, NULL); -+ -+ ath79_register_pci(); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ /* GMAC1 is connected to the internal switch */ -+ memcpy(mac, art + BALIN_WMAC_MAC_OFFSET, sizeof(mac)); -+ mac[3] |= 0x40; -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_EW_BALIN, "EW-BALIN", "EmbWir-Balin", -+ balin_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ew-dorin.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ew-dorin.c -new file mode 100644 -index 0000000000..5544596f91 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ew-dorin.c -@@ -0,0 +1,138 @@ -+/* -+ * EW Dorin board support -+ * (based on Atheros Ref. Design AP121) -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * Copyright (C) 2012-2017 Embedded Wireless GmbH www.80211.de -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define DORIN_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DORIN_KEYS_DEBOUNCE_INTERVAL (3 * DORIN_KEYS_POLL_INTERVAL) -+ -+#define DORIN_CALDATA_OFFSET 0x1000 -+#define DORIN_WMAC_MAC_OFFSET 0x1002 -+ -+#define DORIN_GPIO_LED_STATUS 21 -+ -+#define DORIN_GPIO_BTN_JUMPSTART 11 -+#define DORIN_GPIO_BTN_RESET 6 -+ -+static struct gpio_led dorin_leds_gpio[] __initdata = { -+ { -+ .name = "dorin:green:status", -+ .gpio = DORIN_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button dorin_gpio_keys[] __initdata = { -+ { -+ .desc = "jumpstart button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DORIN_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DORIN_GPIO_BTN_JUMPSTART, -+ .active_low = 0, -+ }, -+ { -+ .desc = "reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DORIN_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DORIN_GPIO_BTN_RESET, -+ .active_low = 0, -+ } -+}; -+ -+static void __init ew_dorin_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ static u8 mac[6]; -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_usb(); -+ -+ if (ar93xx_wmac_read_mac_address(mac)) { -+ ath79_register_wmac(NULL, NULL); -+ } else { -+ ath79_register_wmac(art + DORIN_CALDATA_OFFSET, -+ art + DORIN_WMAC_MAC_OFFSET); -+ memcpy(mac, art + DORIN_WMAC_MAC_OFFSET, sizeof(mac)); -+ } -+ -+ mac[3] |= 0x40; -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN ports */ -+ ath79_register_eth(1); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dorin_leds_gpio), -+ dorin_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, DORIN_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dorin_gpio_keys), -+ dorin_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_EW_DORIN, "EW-DORIN", "EmbWir-Dorin", -+ ew_dorin_setup); -+ -+ -+static void __init ew_dorin_router_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ static u8 mac[6]; -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_usb(); -+ -+ if (ar93xx_wmac_read_mac_address(mac)) { -+ ath79_register_wmac(NULL, NULL); -+ } else { -+ ath79_register_wmac(art + DORIN_CALDATA_OFFSET, -+ art + DORIN_WMAC_MAC_OFFSET); -+ memcpy(mac, art + DORIN_WMAC_MAC_OFFSET, sizeof(mac)); -+ } -+ -+ mac[3] |= 0x40; -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ -+ mac[3] &= 0x3F; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_setup_ar933x_phy4_switch(true, true); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN ports */ -+ ath79_register_eth(1); -+ -+ /* WAN port */ -+ ath79_register_eth(0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(dorin_leds_gpio), -+ dorin_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, DORIN_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(dorin_gpio_keys), -+ dorin_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_EW_DORIN_ROUTER, "EW-DORIN-ROUTER", -+ "EmbWir-Dorin-Router", ew_dorin_router_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-f9k1115v2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-f9k1115v2.c -new file mode 100644 -index 0000000000..232105e068 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-f9k1115v2.c -@@ -0,0 +1,189 @@ -+/* -+ * Belkin AC1750DB (F9K1115V2) board support -+ * -+ * Copyright (C) 2014 Gabor Juhos -+ * Copyright (C) 2014 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define F9K1115V2_GPIO_LED_USB2 4 -+#define F9K1115V2_GPIO_LED_WPS_AMBER 14 -+#define F9K1115V2_GPIO_LED_STATUS_AMBER 15 -+#define F9K1115V2_GPIO_LED_WPS_BLUE 19 -+#define F9K1115V2_GPIO_LED_STATUS_BLUE 20 -+ -+#define F9K1115V2_GPIO_BTN_WPS 16 -+#define F9K1115V2_GPIO_BTN_RESET 17 -+ -+#define F9K1115V2_GPIO_USB2_POWER 21 -+ -+#define F9K1115V2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define F9K1115V2_KEYS_DEBOUNCE_INTERVAL (3 * F9K1115V2_KEYS_POLL_INTERVAL) -+ -+#define F9K1115V2_WAN_MAC_OFFSET 0 -+#define F9K1115V2_LAN_MAC_OFFSET 6 -+#define F9K1115V2_WMAC_CALDATA_OFFSET 0x1000 -+#define F9K1115V2_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led f9k1115v2_leds_gpio[] __initdata = { -+ { -+ .name = "belkin:amber:status", -+ .gpio = F9K1115V2_GPIO_LED_STATUS_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "belkin:blue:status", -+ .gpio = F9K1115V2_GPIO_LED_STATUS_BLUE, -+ .active_low = 1, -+ }, -+ { -+ .name = "belkin:blue:wps", -+ .gpio = F9K1115V2_GPIO_LED_WPS_BLUE, -+ .active_low = 1, -+ }, -+ { -+ .name = "belkin:amber:wps", -+ .gpio = F9K1115V2_GPIO_LED_WPS_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "belkin:green:usb2", -+ .gpio = F9K1115V2_GPIO_LED_USB2, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button f9k1115v2_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = F9K1115V2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = F9K1115V2_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = F9K1115V2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = F9K1115V2_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg f9k1115v2_ar8327_pad0_cfg = { -+ /* Use the RGMII interface for the GMAC0 of the AR8337 switch */ -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_pad_cfg f9k1115v2_ar8327_pad6_cfg = { -+ /* Use the SGMII interface for the GMAC6 of the AR8337 switch */ -+ .mode = AR8327_PAD_MAC_SGMII, -+ .rxclk_delay_en = true, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL0, -+}; -+ -+static struct ar8327_platform_data f9k1115v2_ar8327_data = { -+ .pad0_cfg = &f9k1115v2_ar8327_pad0_cfg, -+ .pad6_cfg = &f9k1115v2_ar8327_pad6_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .port6_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info f9k1115v2_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &f9k1115v2_ar8327_data, -+ }, -+}; -+ -+static void __init f9k1115v2_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(f9k1115v2_leds_gpio), -+ f9k1115v2_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, F9K1115V2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(f9k1115v2_gpio_keys), -+ f9k1115v2_gpio_keys); -+ -+ ath79_register_wmac(art + F9K1115V2_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_mdio(0, 0x0); -+ mdiobus_register_board_info(f9k1115v2_mdio0_info, -+ ARRAY_SIZE(f9k1115v2_mdio0_info)); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ art + F9K1115V2_WAN_MAC_OFFSET, 0); -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, -+ art + F9K1115V2_LAN_MAC_OFFSET, 0); -+ -+ ath79_eth0_pll_data.pll_1000 = 0xa6000000; -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ -+ /* GMAC0 is connected to the RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(1); -+ -+ ath79_register_pci(); -+ -+ ath79_register_usb(); -+ gpio_request_one(F9K1115V2_GPIO_USB2_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB2 power"); -+} -+ -+MIPS_MACHINE(ATH79_MACH_F9K1115V2, "F9K1115V2", "Belkin AC1750DB", -+ f9k1115v2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-fritz300e.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-fritz300e.c -new file mode 100644 -index 0000000000..43af71a0a8 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-fritz300e.c -@@ -0,0 +1,132 @@ -+/* -+ * AVM FRITZ!WLAN Repeater 300E board support -+ * -+ * Copyright (C) 2017 Mathias Kresin -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+ -+#define FRITZ300E_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define FRITZ300E_KEYS_DEBOUNCE_INTERVAL (3 * FRITZ300E_KEYS_POLL_INTERVAL) -+ -+static struct mtd_partition fritz300e_flash_partitions[] = { -+ { -+ .name = "urloader", -+ .offset = 0, -+ .size = 0x0020000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x0020000, -+ .size = 0x0ee0000, -+ }, { -+ .name = "tffs (1)", -+ .offset = 0x0f00000, -+ .size = 0x0080000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "tffs (2)", -+ .offset = 0x0f80000, -+ .size = 0x0080000, -+ .mask_flags = MTD_WRITEABLE, -+ } -+}; -+ -+static struct flash_platform_data fritz300e_flash_data = { -+ .parts = fritz300e_flash_partitions, -+ .nr_parts = ARRAY_SIZE(fritz300e_flash_partitions), -+}; -+ -+static struct gpio_led fritz300e_leds_gpio[] __initdata = { -+ { -+ .name = "fritz300e:green:power", -+ .gpio = 13, -+ .active_low = 1, -+ }, { -+ .name = "fritz300e:green:lan", -+ .gpio = 15, -+ .active_low = 1, -+ }, { -+ .name = "fritz300e:green:wlan", -+ .gpio = 16, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led fritz300e_wmac_leds_gpio[] = { -+ { -+ .name = "fritz300e:green:rssi0", -+ .gpio = 10, -+ .active_low = 1, -+ }, { -+ .name = "fritz300e:green:rssi1", -+ .gpio = 4, -+ .active_low = 1, -+ }, { -+ .name = "fritz300e:green:rssi2", -+ .gpio = 6, -+ .active_low = 1, -+ }, { -+ .name = "fritz300e:green:rssi3", -+ .gpio = 7, -+ .active_low = 1, -+ }, { -+ .name = "fritz300e:green:rssi4", -+ .gpio = 5, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button fritz300e_gpio_keys[] __initdata = { -+ { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = FRITZ300E_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 12, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init fritz300e_setup(void) -+{ -+ /* get the Lantiq PEF7071V phy out of reset */ -+ gpio_request_one(11, GPIOF_OUT_INIT_HIGH, "phy reset"); -+ -+ ath79_register_m25p80(&fritz300e_flash_data); -+ -+ ath79_register_mdio(0, ~(BIT(0))); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(0); -+ -+ ath79_register_eth(0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(fritz300e_leds_gpio), -+ fritz300e_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, FRITZ300E_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(fritz300e_gpio_keys), -+ fritz300e_gpio_keys); -+ -+ ap9x_pci_setup_wmac_leds(0, fritz300e_wmac_leds_gpio, -+ ARRAY_SIZE(fritz300e_wmac_leds_gpio)); -+ ap91_pci_init_simple(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_FRITZ300E, "FRITZ300E", -+ "AVM FRITZ!WLAN Repeater 300E", fritz300e_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-fritz4020.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-fritz4020.c -new file mode 100644 -index 0000000000..c00cf681b2 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-fritz4020.c -@@ -0,0 +1,242 @@ -+/* -+ * AVM FRITZ!Box 4020 board support -+ * -+ * Copyright (C) 2018 David Bauer -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+ -+#define FRITZ4020_GPIO_SHIFT_SER 19 /* DS, Data Serial Input */ -+#define FRITZ4020_GPIO_SHIFT_SRCLK 20 /* SHCP, Shift Reg Clock Input */ -+ -+#define FRITZ4020_SSR_BIT_0 0 -+#define FRITZ4020_SSR_BIT_1 1 -+#define FRITZ4020_SSR_BIT_2 2 -+#define FRITZ4020_SSR_BIT_3 3 -+#define FRITZ4020_SSR_BIT_4 4 -+#define FRITZ4020_SSR_BIT_5 5 -+#define FRITZ4020_SSR_BIT_6 6 -+#define FRITZ4020_SSR_BIT_7 7 -+ -+#define FRITZ4020_74HC_GPIO_BASE 32 -+#define FRITZ4020_74HC_GPIO_LED_LAN (FRITZ4020_74HC_GPIO_BASE + 0) -+#define FRITZ4020_74HC_GPIO_LED_INFO_RED (FRITZ4020_74HC_GPIO_BASE + 1) -+#define FRITZ4020_74HC_GPIO_LED_POWER (FRITZ4020_74HC_GPIO_BASE + 2) -+#define FRITZ4020_74HC_GPIO_LED_WLAN (FRITZ4020_74HC_GPIO_BASE + 3) -+#define FRITZ4020_74HC_GPIO_LED_WAN (FRITZ4020_74HC_GPIO_BASE + 4) -+#define FRITZ4020_74HC_GPIO_USB_RST (FRITZ4020_74HC_GPIO_BASE + 5) -+#define FRITZ4020_74HC_GPIO_LED_INFO (FRITZ4020_74HC_GPIO_BASE + 6) -+ -+ -+#define FRITZ4020_GPIO_BTN_WPS 2 -+#define FRITZ4020_GPIO_BTN_WLAN 21 -+#define FRITZ4020_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define FRITZ4020_KEYS_DEBOUNCE_INTERVAL (3 * FRITZ4020_KEYS_POLL_INTERVAL) -+ -+#define FRTIZ4020_OFFSET_URLADER_WIFI_MAC_REVERSE 0x1979 -+ -+ -+static struct spi_gpio_platform_data fritz4020_spi_data = { -+ .sck = FRITZ4020_GPIO_SHIFT_SRCLK, -+ .miso = SPI_GPIO_NO_MISO, -+ .mosi = FRITZ4020_GPIO_SHIFT_SER, -+ .num_chipselect = 1, -+}; -+ -+static u8 fritz4020_ssr_initdata[] = { -+ BIT(FRITZ4020_SSR_BIT_7) | -+ BIT(FRITZ4020_SSR_BIT_6) | -+ BIT(FRITZ4020_SSR_BIT_5) | -+ BIT(FRITZ4020_SSR_BIT_4) | -+ BIT(FRITZ4020_SSR_BIT_3) | -+ BIT(FRITZ4020_SSR_BIT_2) | -+ BIT(FRITZ4020_SSR_BIT_1) -+}; -+ -+static struct gen_74x164_chip_platform_data fritz4020_ssr_data = { -+ .base = FRITZ4020_74HC_GPIO_BASE, -+ .num_registers = ARRAY_SIZE(fritz4020_ssr_initdata), -+ .init_data = fritz4020_ssr_initdata, -+}; -+ -+static struct platform_device fritz4020_spi_device = { -+ .name = "spi_gpio", -+ .id = 1, -+ .dev = { -+ .platform_data = &fritz4020_spi_data, -+ }, -+}; -+ -+static struct spi_board_info fritz4020_spi_info[] = { -+ { -+ .bus_num = 1, -+ .chip_select = 0, -+ .max_speed_hz = 10000000, -+ .modalias = "74x164", -+ .platform_data = &fritz4020_ssr_data, -+ .controller_data = (void *) 0x0, -+ }, -+}; -+ -+static struct mtd_partition fritz4020_flash_partitions[] = { -+ { -+ .name = "urlader", -+ .offset = 0, -+ .size = 0x0020000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x0020000, -+ .size = 0x0EE0000, -+ }, { -+ .name = "tffs (1)", -+ .offset = 0x0f00000, -+ .size = 0x0080000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "tffs (2)", -+ .offset = 0x0f80000, -+ .size = 0x0080000, -+ .mask_flags = MTD_WRITEABLE, -+ } -+}; -+ -+static struct flash_platform_data fritz4020_flash_data = { -+ .parts = fritz4020_flash_partitions, -+ .nr_parts = ARRAY_SIZE(fritz4020_flash_partitions), -+}; -+ -+static struct gpio_led fritz4020_leds_gpio[] __initdata = { -+ { -+ .name = "fritz4020:green:lan", -+ .gpio = FRITZ4020_74HC_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "fritz4020:green:info", -+ .gpio = FRITZ4020_74HC_GPIO_LED_INFO, -+ .active_low = 1, -+ }, { -+ .name = "fritz4020:red:info", -+ .gpio = FRITZ4020_74HC_GPIO_LED_INFO_RED, -+ .active_low = 1, -+ }, { -+ .name = "fritz4020:green:power", -+ .gpio = FRITZ4020_74HC_GPIO_LED_POWER, -+ .active_low = 1, -+ }, { -+ .name = "fritz4020:green:wlan", -+ .gpio = FRITZ4020_74HC_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "fritz4020:green:wan", -+ .gpio = FRITZ4020_74HC_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button fritz4020_gpio_keys[] __initdata = { -+ { -+ .desc = "RFKILL button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = FRITZ4020_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = FRITZ4020_GPIO_BTN_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = FRITZ4020_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = FRITZ4020_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init fritz4020_setup(void) { -+ u8 *urlader = (u8 *) KSEG1ADDR(0x1f000000); -+ u8 wifi_mac[ETH_ALEN]; -+ -+ ath79_register_m25p80(&fritz4020_flash_data); -+ -+ /* Initialize ethernet */ -+ ath79_extract_mac_reverse(urlader + FRTIZ4020_OFFSET_URLADER_WIFI_MAC_REVERSE, wifi_mac); -+ ath79_setup_qca956x_eth_cfg(QCA956X_ETH_CFG_SW_PHY_SWAP | -+ QCA956X_ETH_CFG_SW_PHY_ADDR_SWAP); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_mdio(1, 0x0); -+ ath79_init_mac(ath79_eth0_data.mac_addr, wifi_mac, -1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, wifi_mac, -2); -+ -+ /* WAN port */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_register_eth(0); -+ -+ /* LAN ports */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_switch_data.phy_poll_mask |= BIT(0); -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_register_eth(1); -+ -+ /* Initialize 2.4GHz WiFi */ -+ ath79_register_wmac_simple(); -+ -+ /* Activate USB Power */ -+ gpio_request_one(FRITZ4020_74HC_GPIO_USB_RST, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ -+ /* Initialize USB port */ -+ ath79_register_usb(); -+ -+ /* Register LED shift-register */ -+ spi_register_board_info(fritz4020_spi_info, -+ ARRAY_SIZE(fritz4020_spi_info)); -+ platform_device_register(&fritz4020_spi_device); -+ -+ /* Register GPIO buttons */ -+ ath79_register_gpio_keys_polled(-1, FRITZ4020_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(fritz4020_gpio_keys), -+ fritz4020_gpio_keys); -+ -+ /* Register LEDs */ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(fritz4020_leds_gpio), -+ fritz4020_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_FRITZ4020, "FRITZ4020", -+ "AVM FRITZ!Box 4020", fritz4020_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-fritz450e.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-fritz450e.c -new file mode 100644 -index 0000000000..5bded81a4d ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-fritz450e.c -@@ -0,0 +1,179 @@ -+/* -+ * AVM FRITZ!WLAN Repeater 450E board support -+ * -+ * Copyright (C) 2018 David Bauer -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define FRITZ450E_GPIO_LED_POWER 14 -+#define FRITZ450E_GPIO_LED_LAN 13 -+#define FRITZ450E_GPIO_LED_WLAN 15 -+#define FRITZ450E_GPIO_LED_RSSI2 16 -+#define FRITZ450E_GPIO_LED_RSSI3 17 -+#define FRITZ450E_GPIO_LED_RSSI4 18 -+ -+#define FRITZ450E_GPIO_BTN_WPS 4 -+#define FRITZ450E_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define FRITZ450E_KEYS_DEBOUNCE_INTERVAL (3 * FRITZ450E_KEYS_POLL_INTERVAL) -+ -+#define FRITZ450E_PHY_ADDRESS 0 -+#define FRITZ450E_GPIO_PHY_RESET 11 -+#define FRITZ450E_GPIO_MDIO_CLK 12 -+#define FRITZ450E_GPIO_MDIO_DATA 19 -+ -+#define FRITZ450E_OFFSET_URLADER_WIFI_MAC_REVERSE 0x1979 -+ -+ -+static struct mtd_partition fritz450E_flash_partitions[] = { -+ { -+ .name = "urlader", -+ .offset = 0, -+ .size = 0x0020000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x0020000, -+ .size = 0x0EE0000, -+ }, { -+ .name = "tffs (1)", -+ .offset = 0x0f00000, -+ .size = 0x0080000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "tffs (2)", -+ .offset = 0x0f80000, -+ .size = 0x0080000, -+ .mask_flags = MTD_WRITEABLE, -+ } -+}; -+ -+static struct flash_platform_data fritz450E_flash_data = { -+ .parts = fritz450E_flash_partitions, -+ .nr_parts = ARRAY_SIZE(fritz450E_flash_partitions), -+}; -+ -+static struct gpio_led fritz450E_leds_gpio[] __initdata = { -+ { -+ .name = "fritz450e:green:lan", -+ .gpio = FRITZ450E_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "fritz450e:green:rssi2", -+ .gpio = FRITZ450E_GPIO_LED_RSSI2, -+ .active_low = 1, -+ }, { -+ .name = "fritz450e:green:rssi3", -+ .gpio = FRITZ450E_GPIO_LED_RSSI3, -+ .active_low = 1, -+ }, { -+ .name = "fritz450e:green:rssi4", -+ .gpio = FRITZ450E_GPIO_LED_RSSI4, -+ .active_low = 1, -+ }, { -+ .name = "fritz450e:green:wlan", -+ .gpio = FRITZ450E_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "fritz450e:green:power", -+ .gpio = FRITZ450E_GPIO_LED_POWER, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button fritz450E_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS Button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = FRITZ450E_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = FRITZ450E_GPIO_BTN_WPS, -+ .active_low = 0, -+ } -+}; -+ -+static struct at803x_platform_data fritz450E_at803x_data = { -+ .disable_smarteee = 1, -+ .has_reset_gpio = 1, -+ .override_sgmii_aneg = 1, -+ .reset_gpio = FRITZ450E_GPIO_PHY_RESET, -+}; -+ -+static struct mdio_board_info fritz450E_mdio_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.1", -+ .mdio_addr = FRITZ450E_PHY_ADDRESS, -+ .platform_data = &fritz450E_at803x_data, -+ }, -+}; -+ -+static void __init fritz450E_setup(void) { -+ u8 *urlader = (u8 *) KSEG1ADDR(0x1f000000); -+ u8 wifi_mac[ETH_ALEN]; -+ -+ ath79_register_m25p80(&fritz450E_flash_data); -+ -+ gpio_request_one(FRITZ450E_GPIO_MDIO_CLK, GPIOF_OUT_INIT_HIGH, "MDC Pull-UP"); -+ gpio_request_one(FRITZ450E_GPIO_MDIO_DATA, GPIOF_OUT_INIT_HIGH, "MDIO Pull-UP"); -+ gpio_request_one(FRITZ450E_GPIO_PHY_RESET, GPIOF_OUT_INIT_HIGH, "PHY reset"); -+ -+ /* Register PHY device */ -+ mdiobus_register_board_info(fritz450E_mdio_info, -+ ARRAY_SIZE(fritz450E_mdio_info)); -+ -+ /* Initialize Ethernet */ -+ ath79_extract_mac_reverse(urlader + FRITZ450E_OFFSET_URLADER_WIFI_MAC_REVERSE, wifi_mac); -+ ath79_init_mac(ath79_eth0_data.mac_addr, wifi_mac, -2); -+ -+ ath79_register_mdio(1, ~BIT(FRITZ450E_PHY_ADDRESS)); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth0_data.phy_mask = BIT(FRITZ450E_PHY_ADDRESS); -+ ath79_eth0_data.enable_sgmii_fixup = 1; -+ ath79_eth0_pll_data.pll_1000 = 0x03000000; -+ ath79_eth0_pll_data.pll_100 = 0x00000101; -+ ath79_eth0_pll_data.pll_10 = 0x00001313; -+ ath79_register_eth(0); -+ -+ /* Initialize 2.4GHz WiFi */ -+ ath79_register_wmac_simple(); -+ -+ /* Register GPIO buttons */ -+ ath79_register_gpio_keys_polled(-1, FRITZ450E_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(fritz450E_gpio_keys), -+ fritz450E_gpio_keys); -+ -+ /* Register LEDs */ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(fritz450E_leds_gpio), -+ fritz450E_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_FRITZ450E, "FRITZ450E", -+ "AVM FRITZ!WLAN Repeater 450E", fritz450E_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar150.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar150.c -new file mode 100644 -index 0000000000..9febc7a839 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar150.c -@@ -0,0 +1,125 @@ -+/* -+ * GL_ar150 board support -+ * -+ * Copyright (C) 2011 dongyuqi <729650915@qq.com> -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * Copyright (C) 2013 alzhao -+ * Copyright (C) 2014 Michel Stempin -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+*/ -+ -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define GL_AR150_GPIO_LED_WLAN 0 -+#define GL_AR150_GPIO_LED_LAN 13 -+#define GL_AR150_GPIO_LED_WAN 15 -+ -+#define GL_AR150_GPIO_BIN_USB 6 -+#define GL_AR150_GPIO_BTN_MANUAL 7 -+#define GL_AR150_GPIO_BTN_AUTO 8 -+#define GL_AR150_GPIO_BTN_RESET 11 -+ -+#define GL_AR150_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define GL_AR150_KEYS_DEBOUNCE_INTERVAL (3 * GL_AR150_KEYS_POLL_INTERVAL) -+ -+#define GL_AR150_MAC0_OFFSET 0x0000 -+#define GL_AR150_MAC1_OFFSET 0x0000 -+#define GL_AR150_CALDATA_OFFSET 0x1000 -+#define GL_AR150_WMAC_MAC_OFFSET 0x0000 -+ -+static struct gpio_led gl_ar150_leds_gpio[] __initdata = { -+ { -+ .name = "gl-ar150:orange:wlan", -+ .gpio = GL_AR150_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+ { -+ .name = "gl-ar150:green:lan", -+ .gpio = GL_AR150_GPIO_LED_LAN, -+ .active_low = 0, -+ }, -+ { -+ .name = "gl-ar150:green:wan", -+ .gpio = GL_AR150_GPIO_LED_WAN, -+ .active_low = 0, -+ .default_state = 1, -+ }, -+}; -+ -+static struct gpio_keys_button gl_ar150_gpio_keys[] __initdata = { -+ { -+ .desc = "BTN_7", -+ .type = EV_KEY, -+ .code = BTN_7, -+ .debounce_interval = GL_AR150_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GL_AR150_GPIO_BTN_MANUAL, -+ .active_low = 0, -+ }, -+ { -+ .desc = "BTN_8", -+ .type = EV_KEY, -+ .code = BTN_8, -+ .debounce_interval = GL_AR150_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GL_AR150_GPIO_BTN_AUTO, -+ .active_low = 0, -+ }, -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = GL_AR150_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GL_AR150_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+}; -+ -+static void __init gl_ar150_setup(void) -+{ -+ -+ /* ART base address */ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ /* register flash. */ -+ ath79_register_m25p80(NULL); -+ -+ /* register gpio LEDs and keys */ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(gl_ar150_leds_gpio), -+ gl_ar150_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, GL_AR150_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(gl_ar150_gpio_keys), -+ gl_ar150_gpio_keys); -+ -+ /* enable usb */ -+ gpio_request_one(GL_AR150_GPIO_BIN_USB, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ /* register eth0 as WAN, eth1 as LAN */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art+GL_AR150_MAC0_OFFSET, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art+GL_AR150_MAC1_OFFSET, 0); -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ /* register wireless mac with cal data */ -+ ath79_register_wmac(art + GL_AR150_CALDATA_OFFSET, art + GL_AR150_WMAC_MAC_OFFSET); -+} -+ -+MIPS_MACHINE(ATH79_MACH_GL_AR150, "GL-AR150", "GL.iNet GL-AR150", gl_ar150_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar300.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar300.c -new file mode 100644 -index 0000000000..1708d696b8 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar300.c -@@ -0,0 +1,103 @@ -+/* -+ * Domino board support -+ * -+ * Copyright (C) 2011 dongyuqi <729650915@qq.com> -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * Copyright (C) 2013 alzhao -+ * Copyright (C) 2014 Michel Stempin -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define GL_AR300_GPIO_LED_WLAN 13 -+#define GL_AR300_GPIO_LED_WAN 14 -+#define GL_AR300_GPIO_BTN_RESET 16 -+ -+ -+#define GL_AR300_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define GL_AR300_KEYS_DEBOUNCE_INTERVAL (3 * GL_AR300_KEYS_POLL_INTERVAL) -+ -+#define GL_AR300_MAC0_OFFSET 0x0000 -+#define GL_AR300_MAC1_OFFSET 0x0000 -+#define GL_AR300_CALDATA_OFFSET 0x1000 -+#define GL_AR300_WMAC_MAC_OFFSET 0x0000 -+ -+static struct gpio_led gl_ar300_leds_gpio[] __initdata = { -+ { -+ .name = "gl-ar300:wlan", -+ .gpio = GL_AR300_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "gl-ar300:wan", -+ .gpio = GL_AR300_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button gl_ar300_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = GL_AR300_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GL_AR300_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init gl_ar300_setup(void) -+{ -+ -+ /* ART base address */ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ /* register flash. */ -+ ath79_register_m25p80(NULL); -+ -+ /* register gpio LEDs and keys */ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(gl_ar300_leds_gpio), -+ gl_ar300_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, GL_AR300_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(gl_ar300_gpio_keys), -+ gl_ar300_gpio_keys); -+ -+ /* enable usb */ -+ ath79_register_usb(); -+ ath79_register_mdio(1, 0x0); -+ -+ /* register eth0 as WAN, eth1 as LAN */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art+GL_AR300_MAC0_OFFSET, 0); -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(4); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_register_eth(0); -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, art+GL_AR300_MAC1_OFFSET, 0); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_register_eth(1); -+ -+ /* register wireless mac with cal data */ -+ ath79_register_wmac(art + GL_AR300_CALDATA_OFFSET, art + GL_AR300_WMAC_MAC_OFFSET); -+} -+ -+MIPS_MACHINE(ATH79_MACH_GL_AR300, "GL-AR300", "GL.iNet GL-AR300", gl_ar300_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar300m.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar300m.c -new file mode 100644 -index 0000000000..d10a910129 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar300m.c -@@ -0,0 +1,158 @@ -+/* -+ * GLI AR300M(D) board support -+ * -+ * Copyright (C) 2011 dongyuqi <729650915@qq.com> -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * Copyright (C) 2013 alzhao -+ * Copyright (C) 2014 Michel Stempin -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define GL_AR300M_GPIO_LED_WLAN 14 -+#define GL_AR300M_GPIO_LED_LAN 13 -+#define GL_AR300M_GPIO_LED_SYSTEM 12 -+#define GL_AR300M_GPIO_BTN_RESET 3 -+#define GL_AR300M_GPIO_BTN_LEFT 0 -+#define GL_AR300M_GPIO_BTN_RIGHT 1 -+ -+#define GL_AR300M_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define GL_AR300M_KEYS_DEBOUNCE_INTERVAL (3 * GL_AR300M_KEYS_POLL_INTERVAL) -+ -+#define GL_AR300M_MAC0_OFFSET 0 -+#define GL_AR300M_MAC1_OFFSET 6 -+#define GL_AR300M_WMAC_CALDATA_OFFSET 0x1000 -+#define GL_AR300M_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led gl_ar300m_leds_gpio[] __initdata = { -+ { -+ .name = "gl-ar300m:red:wlan", -+ .gpio = GL_AR300M_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "gl-ar300m:green:lan", -+ .gpio = GL_AR300M_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "gl-ar300m:green:system", -+ .gpio = GL_AR300M_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ .default_state = 1, -+ }, -+}; -+ -+static struct gpio_keys_button gl_ar300m_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = GL_AR300M_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GL_AR300M_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "button right", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = GL_AR300M_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GL_AR300M_GPIO_BTN_LEFT, -+ .active_low = 0, -+ }, -+ { -+ .desc = "button left", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .debounce_interval = GL_AR300M_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GL_AR300M_GPIO_BTN_RIGHT, -+ .active_low = 0, -+ }, -+}; -+ -+static struct spi_board_info gl_ar300m_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ .platform_data = NULL, -+ }, -+ { -+ .bus_num = 0, -+ .chip_select = 1, -+ .max_speed_hz = 25000000, -+ .modalias = "ath79-spinand", -+ .platform_data = NULL, -+ } -+}; -+ -+static struct ath79_spi_platform_data gl_ar300m_spi_data = { -+ .bus_num = 0, -+ .num_chipselect = 2, -+}; -+ -+static void __init gl_ar300m_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 tmpmac[ETH_ALEN]; -+ -+ ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE); -+ ath79_register_spi(&gl_ar300m_spi_data, gl_ar300m_spi_info, 2); -+ -+ /* register gpio LEDs and keys */ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(gl_ar300m_leds_gpio), -+ gl_ar300m_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, GL_AR300M_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(gl_ar300m_gpio_keys), -+ gl_ar300m_gpio_keys); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* WAN */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + GL_AR300M_MAC0_OFFSET, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_register_eth(0); -+ -+ /* LAN */ -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + GL_AR300M_MAC1_OFFSET, 0); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_register_eth(1); -+ -+ ath79_init_mac(tmpmac, art + GL_AR300M_WMAC_CALDATA_OFFSET + 2, 0); -+ ath79_register_wmac(art + GL_AR300M_WMAC_CALDATA_OFFSET, tmpmac); -+ -+ /* enable usb */ -+ ath79_register_usb(); -+ /* enable pci */ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_GL_AR300M, "GL-AR300M", "GL.iNet GL-AR300M", gl_ar300m_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar750.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar750.c -new file mode 100644 -index 0000000000..9ee6e29c02 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar750.c -@@ -0,0 +1,146 @@ -+/* -+ * GL.iNet GL-AR750 board support -+ * -+ * Copyright (C) 2018 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define GL_AR750_GPIO_LED_POWER 12 -+#define GL_AR750_GPIO_LED_WLAN2G 14 -+#define GL_AR750_GPIO_LED_WLAN5G 13 -+ -+#define GL_AR750_GPIO_BTN_RESET 3 -+#define GL_AR750_GPIO_BTN_SW1 0 -+ -+#define GL_AR750_GPIO_I2C_SCL 16 -+#define GL_AR750_GPIO_I2C_SDA 17 -+ -+#define GL_AR750_GPIO_USB_POWER 2 -+ -+#define GL_AR750_KEYS_POLL_INTERVAL 20 -+#define GL_AR750_KEYS_DEBOUNCE_INTERVAL (3 * GL_AR750_KEYS_POLL_INTERVAL) -+ -+#define GL_AR750_MAC0_OFFSET 0 -+#define GL_AR750_WMAC2G_CALDATA_OFFSET 0x1000 -+#define GL_AR750_WMAC5G_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led gl_ar750_leds_gpio[] __initdata = { -+ { -+ .name = "gl-ar750:white:power", -+ .gpio = GL_AR750_GPIO_LED_POWER, -+ .default_state = LEDS_GPIO_DEFSTATE_KEEP, -+ .active_low = 1, -+ }, { -+ .name = "gl-ar750:white:wlan2g", -+ .gpio = GL_AR750_GPIO_LED_WLAN2G, -+ .active_low = 1, -+ }, { -+ .name = "gl-ar750:white:wlan5g", -+ .gpio = GL_AR750_GPIO_LED_WLAN5G, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button gl_ar750_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = GL_AR750_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GL_AR750_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "sw1", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = GL_AR750_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GL_AR750_GPIO_BTN_SW1, -+ .active_low = 1, -+ }, -+}; -+ -+static struct i2c_gpio_platform_data gl_ar750_i2c_gpio_data = { -+ .sda_pin = GL_AR750_GPIO_I2C_SDA, -+ .scl_pin = GL_AR750_GPIO_I2C_SCL, -+}; -+ -+static struct platform_device gl_ar750_i2c_gpio = { -+ .name = "i2c-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &gl_ar750_i2c_gpio_data, -+ }, -+}; -+ -+static void __init gl_ar750_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1f050000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = 0xfc; -+ -+ /* WAN */ -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + GL_AR750_MAC0_OFFSET, 0); -+ ath79_register_eth(0); -+ -+ /* LAN */ -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + GL_AR750_MAC0_OFFSET, 1); -+ ath79_register_eth(1); -+ -+ /* Disable JTAG (enables GPIO0-3) */ -+ ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(gl_ar750_leds_gpio), -+ gl_ar750_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, GL_AR750_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(gl_ar750_gpio_keys), -+ gl_ar750_gpio_keys); -+ -+ gpio_request_one(GL_AR750_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ -+ platform_device_register(&gl_ar750_i2c_gpio); -+ -+ ath79_register_usb(); -+ -+ ath79_register_wmac(art + GL_AR750_WMAC2G_CALDATA_OFFSET, NULL); -+ -+ ap91_pci_init(art + GL_AR750_WMAC5G_CALDATA_OFFSET, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_GL_AR750, "GL-AR750", "GL.iNet GL-AR750", -+ gl_ar750_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar750s.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar750s.c -new file mode 100644 -index 0000000000..cc5d759273 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-ar750s.c -@@ -0,0 +1,193 @@ -+/* -+ * GL.iNet GL-AR750S board support -+ * -+ * Copyright (C) 2018 luochongjun -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-spi.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+ -+ -+#define GL_AR750S_KEYS_POLL_INTERVAL 20 -+#define GL_AR750S_KEYS_DEBOUNCE_INTERVAL (3 * GL_AR750S_KEYS_POLL_INTERVAL) -+ -+ -+#define GL_AR750S_GPIO_LED_WLAN2G 19 -+#define GL_AR750S_GPIO_LED_WLAN5G 20 -+#define GL_AR750S_GPIO_LED_POWER 1 -+#define GL_AR750S_GPIO_USB_POWER 7 -+ -+#define GL_AR750S_GPIO_BTN_RESET 2 -+#define GL_AR750S_GPIO_BTN_RIGHT 8 -+ -+#define GL_AR750S_MAC0_OFFSET 0x0000 -+#define GL_AR750S_WMAC_CALDATA_OFFSET 0x1000 -+#define GL_AR750S_PCI_CALDATA_OFFSET 0x5000 -+ -+#define GL_AR750S_GPIO_I2C_SDA 5 -+#define GL_AR750S_GPIO_I2C_SCL 21 -+ -+ -+ -+static struct spi_board_info gl_ar750s_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ .platform_data = NULL, -+ }, -+}; -+ -+static struct ath79_spi_platform_data gl_ar750s_spi_data = { -+ .bus_num = 0, -+ .num_chipselect = 2, -+}; -+ -+static struct gpio_led gl_ar750s_leds_gpio[] __initdata = { -+ { -+ .name = "gl-ar750s:green:power", -+ .gpio = GL_AR750S_GPIO_LED_POWER, -+ .default_state = LEDS_GPIO_DEFSTATE_KEEP, -+ .active_low = 1, -+ },{ -+ .name = "gl-ar750s:green:usbpower", -+ .gpio = GL_AR750S_GPIO_USB_POWER, -+ .active_low = 1, -+ },{ -+ .name = "gl-ar750s:green:wlan2g", -+ .gpio = GL_AR750S_GPIO_LED_WLAN2G, -+ .active_low = 1, -+ },{ -+ .name = "gl-ar750s:green:wlan5g", -+ .gpio = GL_AR750S_GPIO_LED_WLAN5G, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button gl_ar750s_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = GL_AR750S_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GL_AR750S_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "right", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = GL_AR750S_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GL_AR750S_GPIO_BTN_RIGHT, -+ .active_low = 1, -+ }, -+}; -+ -+static struct i2c_gpio_platform_data gl_ar750s_i2c_gpio_data = { -+ .sda_pin = GL_AR750S_GPIO_I2C_SDA, -+ .scl_pin = GL_AR750S_GPIO_I2C_SCL, -+}; -+ -+static struct platform_device gl_ar750s_i2c_gpio_device = { -+ .name = "i2c-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &gl_ar750s_i2c_gpio_data, -+ } -+ -+}; -+ -+static struct ar8327_pad_cfg gl_ar750s_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+static struct ar8327_platform_data gl_ar750s_ar8327_data = { -+ .pad0_cfg = &gl_ar750s_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+ -+static struct mdio_board_info gl_ar750s_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &gl_ar750s_ar8327_data, -+ }, -+}; -+ -+static void __init gl_ar750s_setup(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1f050000); -+ -+ ath79_register_spi(&gl_ar750s_spi_data, gl_ar750s_spi_info, 1); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ eeprom + GL_AR750S_MAC0_OFFSET, 0); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_data.phy_mask = BIT(0); -+ -+ mdiobus_register_board_info(gl_ar750s_mdio0_info, -+ ARRAY_SIZE(gl_ar750s_mdio0_info)); -+ -+ ath79_register_mdio(0, 0x00); -+ ath79_register_eth(0); -+ -+ -+ ath79_register_usb(); -+ -+ -+ ath79_register_wmac(eeprom + GL_AR750S_WMAC_CALDATA_OFFSET, NULL); -+ -+ -+ ap91_pci_init(eeprom + GL_AR750S_PCI_CALDATA_OFFSET, NULL); -+ -+ platform_device_register(&gl_ar750s_i2c_gpio_device); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(gl_ar750s_leds_gpio), -+ gl_ar750s_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, GL_AR750S_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(gl_ar750s_gpio_keys), -+ gl_ar750s_gpio_keys); -+} -+ -+ -+MIPS_MACHINE(ATH79_MACH_GL_AR750S, "GL-AR750S", "GL-AR750S", -+ gl_ar750s_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-domino.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-domino.c -new file mode 100644 -index 0000000000..4ff8ff637e ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-domino.c -@@ -0,0 +1,136 @@ -+/* -+ * Domino board support -+ * -+ * Copyright (C) 2011 dongyuqi <729650915@qq.com> -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * Copyright (C) 2013 alzhao -+ * Copyright (C) 2014 Michel Stempin -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+*/ -+ -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define DOMINO_GPIO_LED_WLAN 0 -+#define DOMINO_GPIO_LED_WAN 17 -+#define DOMINO_GPIO_LED_USB 1 -+#define DOMINO_GPIO_LED_LAN1 13 -+#define DOMINO_GPIO_LED_LAN2 14 -+#define DOMINO_GPIO_LED_LAN3 15 -+#define DOMINO_GPIO_LED_LAN4 16 -+#define DOMINO_GPIO_LED_SYS 27 -+#define DOMINO_GPIO_LED_WPS 26 -+#define DOMINO_GPIO_USB_POWER 6 -+ -+#define DOMINO_GPIO_BTN_RESET 11 -+#define DOMINO_GPIO_BTN_WPS 20 -+ -+#define DOMINO_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define DOMINO_KEYS_DEBOUNCE_INTERVAL (3 * DOMINO_KEYS_POLL_INTERVAL) -+ -+#define DOMINO_MAC0_OFFSET 0x0000 -+#define DOMINO_MAC1_OFFSET 0x0000 -+#define DOMINO_CALDATA_OFFSET 0x1000 -+#define DOMINO_WMAC_MAC_OFFSET 0x0000 -+ -+static struct gpio_led domino_leds_gpio[] __initdata = { -+ { -+ .name = "gl-domino:blue:wlan", -+ .gpio = DOMINO_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+ { -+ .name = "gl-domino:red:wan", -+ .gpio = DOMINO_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "gl-domino:white:usb", -+ .gpio = DOMINO_GPIO_LED_USB, -+ .active_low = 0, -+ }, -+ { -+ .name = "gl-domino:green:lan1", -+ .gpio = DOMINO_GPIO_LED_LAN1, -+ .active_low = 0, -+ }, -+ { -+ .name = "gl-domino:yellow:wps", -+ .gpio = DOMINO_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+ { -+ .name = "gl-domino:orange:sys", -+ .gpio = DOMINO_GPIO_LED_SYS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button domino_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = DOMINO_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DOMINO_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+ { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = DOMINO_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = DOMINO_GPIO_BTN_WPS, -+ .active_low = 0, -+ } -+}; -+ -+static void __init domino_setup(void) -+{ -+ -+ /* ART base address */ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ /* register flash. */ -+ ath79_register_m25p80(NULL); -+ -+ /* register gpio LEDs and keys */ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(domino_leds_gpio), -+ domino_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, DOMINO_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(domino_gpio_keys), -+ domino_gpio_keys); -+ -+ gpio_request_one(DOMINO_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ /* enable usb */ -+ ath79_register_usb(); -+ -+ /* register eth0 as WAN, eth1 as LAN */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art+DOMINO_MAC0_OFFSET, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art+DOMINO_MAC1_OFFSET, 0); -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ /* register wireless mac with cal data */ -+ ath79_register_wmac(art + DOMINO_CALDATA_OFFSET, art + DOMINO_WMAC_MAC_OFFSET); -+} -+ -+MIPS_MACHINE(ATH79_MACH_GL_DOMINO, "DOMINO", "Domino Pi", domino_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-inet.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-inet.c -new file mode 100644 -index 0000000000..6f603d9579 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-inet.c -@@ -0,0 +1,104 @@ -+/* -+ * GL-CONNECT iNet board support -+ * -+ * Copyright (C) 2011 dongyuqi <729650915@qq.com> -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * Copyright (C) 2013 alzhao -+ * Copyright (C) 2014 Michel Stempin -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define GL_INET_GPIO_LED_WLAN 0 -+#define GL_INET_GPIO_LED_LAN 13 -+#define GL_INET_GPIO_BTN_RESET 11 -+ -+#define GL_INET_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define GL_INET_KEYS_DEBOUNCE_INTERVAL (3 * GL_INET_KEYS_POLL_INTERVAL) -+ -+static const char * gl_inet_part_probes[] = { -+ "tp-link", /* dont change, this will use tplink parser */ -+ NULL , -+}; -+ -+static struct flash_platform_data gl_inet_flash_data = { -+ .part_probes = gl_inet_part_probes, -+}; -+ -+static struct gpio_led gl_inet_leds_gpio[] __initdata = { -+ { -+ .name = "gl-inet:red:wlan", -+ .gpio = GL_INET_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+ { -+ .name = "gl-inet:green:lan", -+ .gpio = GL_INET_GPIO_LED_LAN, -+ .active_low = 0, -+ .default_state = 1, -+ }, -+}; -+ -+static struct gpio_keys_button gl_inet_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = GL_INET_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GL_INET_GPIO_BTN_RESET, -+ .active_low = 0, -+ } -+}; -+ -+static void __init gl_inet_setup(void) -+{ -+ /* get the mac address which is stored in the 1st 64k uboot MTD */ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ -+ /* get the art address, which is the last 64K. By using -+ 0x1fff1000, it doesn't matter it is 4M, 8M or 16M flash */ -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ /* register flash. MTD will use tp-link parser to parser MTD */ -+ ath79_register_m25p80(&gl_inet_flash_data); -+ -+ /* register gpio LEDs and keys */ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(gl_inet_leds_gpio), -+ gl_inet_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, GL_INET_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(gl_inet_gpio_keys), -+ gl_inet_gpio_keys); -+ -+ /* enable usb */ -+ ath79_register_usb(); -+ -+ /* register eth0 as WAN, eth1 as LAN */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_register_eth(1); -+ -+ /* register wireless mac with cal data */ -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_GL_INET, "GL-INET", "GL-CONNECT INET v1", -+ gl_inet_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-mifi.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-mifi.c -new file mode 100644 -index 0000000000..a5c68ed65a ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-mifi.c -@@ -0,0 +1,114 @@ -+/* -+ * Mifi board support -+ * -+ * Copyright (C) 2011 dongyuqi <729650915@qq.com> -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * Copyright (C) 2013 alzhao -+ * Copyright (C) 2014 Michel Stempin -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+*/ -+ -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define GL_MIFI_GPIO_LED_WAN 27 -+#define GL_MIFI_GPIO_LED_LAN 16 -+#define GL_MIFI_GPIO_LED_WLAN 1 -+#define GL_MIFI_GPIO_LED_NET 0 -+#define GL_MIFI_GPIO_LED_3GCONTROL 7 -+ -+#define GL_MIFI_GPIO_BTN_RESET 11 -+ -+#define GL_MIFI_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define GL_MIFI_KEYS_DEBOUNCE_INTERVAL (3 * GL_MIFI_KEYS_POLL_INTERVAL) -+ -+#define GL_MIFI_MAC0_OFFSET 0x0000 -+#define GL_MIFI_MAC1_OFFSET 0x0000 -+#define GL_MIFI_CALDATA_OFFSET 0x1000 -+#define GL_MIFI_WMAC_MAC_OFFSET 0x0000 -+ -+static struct gpio_led gl_mifi_leds_gpio[] __initdata = { -+ { -+ .name = "gl-mifi:green:wan", -+ .gpio = GL_MIFI_GPIO_LED_WAN, -+ .active_low = 0, -+ }, -+ { -+ .name = "gl-mifi:green:lan", -+ .gpio = GL_MIFI_GPIO_LED_LAN, -+ .active_low = 0, -+ }, -+ { -+ .name = "gl-mifi:green:wlan", -+ .gpio = GL_MIFI_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+ { -+ .name = "gl-mifi:green:net", -+ .gpio = GL_MIFI_GPIO_LED_NET, -+ .active_low = 0, -+ }, -+ { -+ .name = "gl-mifi:green:3gcontrol", -+ .gpio = GL_MIFI_GPIO_LED_3GCONTROL, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button gl_mifi_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = GL_MIFI_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GL_MIFI_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+}; -+ -+static void __init gl_mifi_setup(void) -+{ -+ -+ /* ART base address */ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ /* register flash. */ -+ ath79_register_m25p80(NULL); -+ -+ /* register gpio LEDs and keys */ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(gl_mifi_leds_gpio), -+ gl_mifi_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, GL_MIFI_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(gl_mifi_gpio_keys), -+ gl_mifi_gpio_keys); -+ -+ /* enable usb */ -+ ath79_register_usb(); -+ -+ /* register eth0 as WAN, eth1 as LAN */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art+GL_MIFI_MAC0_OFFSET, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art+GL_MIFI_MAC1_OFFSET, 0); -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ /* register wireless mac with cal data */ -+ ath79_register_wmac(art + GL_MIFI_CALDATA_OFFSET, art + GL_MIFI_WMAC_MAC_OFFSET); -+} -+ -+MIPS_MACHINE(ATH79_MACH_GL_MIFI, "GL-MIFI", "GL.iNet GL-MIFI", gl_mifi_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-usb150.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-usb150.c -new file mode 100644 -index 0000000000..6cc27e1ada ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-gl-usb150.c -@@ -0,0 +1,87 @@ -+/* -+ * GL.iNet GL-USB150 board support -+ * -+ * Copyright (C) 2017 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define GL_USB150_GPIO_LED_POWER 13 -+#define GL_USB150_GPIO_LED_WLAN 0 -+#define GL_USB150_GPIO_LAN_RESET 7 -+#define GL_USB150_GPIO_BTN_RESET 11 -+ -+#define GL_USB150_KEYS_POLL_INTERVAL 20 -+#define GL_USB150_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * GL_USB150_KEYS_POLL_INTERVAL) -+ -+#define GL_USB150_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led gl_usb150_leds_gpio[] __initdata = { -+ { -+ .name = "gl-usb150:green:power", -+ .gpio = GL_USB150_GPIO_LED_POWER, -+ .active_low = 0, -+ }, { -+ .name = "gl-usb150:green:wlan", -+ .gpio = GL_USB150_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button gl_usb150_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = GL_USB150_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GL_USB150_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+}; -+ -+static void __init gl_usb150_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ /* LAN (PHY4 connected with Realtek RTL8152B) */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art, 0); -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(gl_usb150_leds_gpio), -+ gl_usb150_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, GL_USB150_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(gl_usb150_gpio_keys), -+ gl_usb150_gpio_keys); -+ -+ gpio_request_one(GL_USB150_GPIO_LAN_RESET, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "LAN reset"); -+ -+ ath79_register_wmac(art + GL_USB150_WMAC_CALDATA_OFFSET, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_GL_USB150, "GL-USB150", "GL.iNet GL-USB150", -+ gl_usb150_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-gs-minibox-v32.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-gs-minibox-v32.c -new file mode 100644 -index 0000000000..469c6f39ea ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-gs-minibox-v32.c -@@ -0,0 +1,121 @@ -+/* -+ * Atheros GS_MINIBOX_V3.2 reference board support -+ * -+ * Copyright (c) 2018 OpenWRT.org -+ * Copyright (c) 2013 The Linux Foundation. All rights reserved. -+ * Copyright (c) 2012 Gabor Juhos -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define GS_MINIBOX_V3_GPIO_LED_STATUS 14 -+#define GS_MINIBOX_V3_GPIO_BTN_RST 17 -+#define GS_MINIBOX_V3_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define GS_MINIBOX_V3_KEYS_DEBOUNCE_INTERVAL (3 * GS_MINIBOX_V3_KEYS_POLL_INTERVAL) -+#define GS_MINIBOX_V3_MAC0_OFFSET 0 -+#define GS_MINIBOX_V3_MAC1_OFFSET 6 -+#define GS_MINIBOX_V3_WMAC_CALDATA_OFFSET 0x1000 -+ -+static const char *gs_minibox_v3_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data gs_minibox_v3_flash_data = { -+ .part_probes = gs_minibox_v3_part_probes, -+}; -+ -+static struct gpio_led gs_minibox_v3_leds_gpio[] __initdata = { -+ { -+ .name = "minibox_v3.2:green:system", -+ .gpio = GS_MINIBOX_V3_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button gs_minibox_v3_gpio_keys[] __initdata = { -+ { -+ .desc = "reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = GS_MINIBOX_V3_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GS_MINIBOX_V3_GPIO_BTN_RST, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init gs_minibox_v3_gpio_led_setup(void) -+{ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(gs_minibox_v3_leds_gpio), -+ gs_minibox_v3_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, GS_MINIBOX_V3_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(gs_minibox_v3_gpio_keys), -+ gs_minibox_v3_gpio_keys); -+} -+ -+static void __init gs_minibox_v3_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(&gs_minibox_v3_flash_data); -+ gs_minibox_v3_gpio_led_setup(); -+ -+ ath79_register_usb(); -+ -+ ath79_register_wmac(art + GS_MINIBOX_V3_WMAC_CALDATA_OFFSET, NULL); -+ ath79_register_mdio(0, 0x0); -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + GS_MINIBOX_V3_MAC0_OFFSET, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + GS_MINIBOX_V3_MAC1_OFFSET, 0); -+ -+ /* WAN port */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_register_eth(0); -+ -+ /* LAN ports */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_register_eth(1); -+ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_GS_MINIBOX_V32, "MINIBOX-V3.2", "Minibox V3.2", -+ gs_minibox_v3_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-gs-oolite-v1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-gs-oolite-v1.c -new file mode 100644 -index 0000000000..d424e0f111 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-gs-oolite-v1.c -@@ -0,0 +1,143 @@ -+/* -+ * GainStrong Oolite/MiniBox V1.0 boards support -+ * -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "dev-usb.h" -+ -+#define GS_MINIBOX_V1_GPIO_BTN_RESET 11 -+#define GS_MINIBOX_V1_GPIO_LED_SYSTEM 1 -+ -+#define GS_OOLITE_V1_GPIO_BTN6 6 -+#define GS_OOLITE_V1_GPIO_BTN7 7 -+#define GS_OOLITE_V1_GPIO_BTN_RESET 11 -+#define GS_OOLITE_V1_GPIO_LED_SYSTEM 27 -+ -+#define GS_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define GS_KEYS_DEBOUNCE_INTERVAL (3 * GS_KEYS_POLL_INTERVAL) -+ -+static const char *gs_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data gs_flash_data = { -+ .part_probes = gs_part_probes, -+}; -+ -+static struct gpio_led gs_minibox_v1_leds_gpio[] __initdata = { -+ { -+ .name = "minibox-v1:green:system", -+ .gpio = GS_MINIBOX_V1_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led gs_oolite_v1_leds_gpio[] __initdata = { -+ { -+ .name = "oolite-v1:red:system", -+ .gpio = GS_OOLITE_V1_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button gs_minibox_v1_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = GS_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GS_MINIBOX_V1_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button gs_oolite_v1_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = GS_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GS_OOLITE_V1_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, { -+ .desc = "BTN_6", -+ .type = EV_KEY, -+ .code = BTN_6, -+ .debounce_interval = GS_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GS_OOLITE_V1_GPIO_BTN6, -+ .active_low = 0, -+ }, { -+ .desc = "BTN_7", -+ .type = EV_KEY, -+ .code = BTN_7, -+ .debounce_interval = GS_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GS_OOLITE_V1_GPIO_BTN7, -+ .active_low = 0, -+ }, -+}; -+ -+static void __init gs_common_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ -+ ath79_register_usb(); -+ -+ ath79_register_m25p80(&gs_flash_data); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(1); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(art, mac); -+} -+ -+static void __init gs_minibox_v1_setup(void) -+{ -+ gs_common_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(gs_minibox_v1_leds_gpio), -+ gs_minibox_v1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, GS_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(gs_minibox_v1_gpio_keys), -+ gs_minibox_v1_gpio_keys); -+} -+ -+static void __init gs_oolite_v1_setup(void) -+{ -+ gs_common_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(gs_oolite_v1_leds_gpio), -+ gs_oolite_v1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, GS_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(gs_oolite_v1_gpio_keys), -+ gs_oolite_v1_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_GS_MINIBOX_V1, "MINIBOX-V1", "GainStrong MiniBox V1.0", -+ gs_minibox_v1_setup); -+ -+MIPS_MACHINE(ATH79_MACH_GS_OOLITE_V1, "OOLITE-V1", "GainStrong Oolite V1.0", -+ gs_oolite_v1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-gs-oolite-v5-2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-gs-oolite-v5-2.c -new file mode 100644 -index 0000000000..64dc4f3345 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-gs-oolite-v5-2.c -@@ -0,0 +1,111 @@ -+/* -+ * GainStrong Oolite V5.2 module and development board support -+ * -+ * Copyright (C) 2018 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define GS_OOLITE_V5_2_DEV_GPIO_BTN_RESET 17 -+#define GS_OOLITE_V5_2_DEV_GPIO_LED_SYSTEM 13 -+ -+#define GS_KEYS_POLL_INTERVAL 20 /* msec */ -+#define GS_KEYS_DEBOUNCE_INTERVAL (3 * GS_KEYS_POLL_INTERVAL) -+ -+#define GS_OOLITE_V5_2_WMAC_CALDATA_OFFSET 0x1000 -+ -+static const char *gs_oolite_v5_2_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data gs_oolite_v5_2_flash_data = { -+ .part_probes = gs_oolite_v5_2_part_probes, -+}; -+ -+static struct gpio_led gs_oolite_v5_2_dev_gpio_leds[] __initdata = { -+ { -+ .name = "oolite-v5.2-dev:blue:system", -+ .gpio = GS_OOLITE_V5_2_DEV_GPIO_LED_SYSTEM, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button gs_oolite_v5_2_dev_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = GS_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = GS_OOLITE_V5_2_DEV_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init gs_oolite_v5_2_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(&gs_oolite_v5_2_flash_data); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ -+ /* LAN */ -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + 6, 0); -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_init_mac(ath79_eth0_data.mac_addr, art, 0); -+ ath79_register_eth(0); -+ -+ ath79_register_pci(); -+ ath79_register_usb(); -+ ath79_register_wmac(art + GS_OOLITE_V5_2_WMAC_CALDATA_OFFSET, NULL); -+} -+ -+static void __init gs_oolite_v5_2_dev_setup(void) -+{ -+ gs_oolite_v5_2_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(gs_oolite_v5_2_dev_gpio_leds), -+ gs_oolite_v5_2_dev_gpio_leds); -+ -+ ath79_register_gpio_keys_polled(-1, GS_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(gs_oolite_v5_2_dev_gpio_keys), -+ gs_oolite_v5_2_dev_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_GS_OOLITE_V5_2, "OOLITE-V5-2", -+ "GainStrong Oolite V5.2", gs_oolite_v5_2_setup); -+ -+MIPS_MACHINE(ATH79_MACH_GS_OOLITE_V5_2_DEV, "OOLITE-V5-2-DEV", -+ "GainStrong Oolite V5.2-Dev", gs_oolite_v5_2_dev_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-hiveap-121.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-hiveap-121.c -new file mode 100644 -index 0000000000..5cbb2054f7 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-hiveap-121.c -@@ -0,0 +1,153 @@ -+/* -+ * Aerohive HiveAP 121 board support -+ * -+ * Copyright (C) 2017 Chris Blake -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-nfc.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "dev-ap9x-pci.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+ -+#define HIVEAP_121_GPIO_LED_ORANGE 14 -+#define HIVEAP_121_GPIO_LED_WHITE 21 -+#define HIVEAP_121_GPIO_I2C_SCL 12 -+#define HIVEAP_121_GPIO_I2C_SDA 13 -+#define HIVEAP_121_GPIO_XLNA0 20 -+#define HIVEAP_121_GPIO_XLNA1 19 -+#define HIVEAP_121_GPIO_USB_POWER 15 -+ -+#define HIVEAP_121_GPIO_BTN_RESET 4 -+#define HIVEAP_121_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define HIVEAP_121_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * HIVEAP_121_KEYS_POLL_INTERVAL) -+ -+#define HIVEAP_121_MAC_OFFSET 0x90000 -+ -+#define HIVEAP_121_LAN_PHYADDR 0 -+ -+static struct gpio_led hiveap_121_leds_gpio[] __initdata = { -+ { -+ .name = "hiveap-121:orange:power", -+ .gpio = HIVEAP_121_GPIO_LED_ORANGE, -+ .active_low = 1, -+ }, { -+ .name = "hiveap-121:white:power", -+ .gpio = HIVEAP_121_GPIO_LED_WHITE, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button hiveap_121_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = HIVEAP_121_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = HIVEAP_121_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct i2c_gpio_platform_data hiveap_121_i2c_gpio_data = { -+ .sda_pin = HIVEAP_121_GPIO_I2C_SDA, -+ .scl_pin = HIVEAP_121_GPIO_I2C_SCL, -+}; -+ -+static struct platform_device hiveap_121_i2c_gpio_device = { -+ .name = "i2c-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &hiveap_121_i2c_gpio_data, -+ } -+}; -+ -+static struct i2c_board_info tpm_i2c_info[] __initdata = { -+ { -+ I2C_BOARD_INFO("tpm_i2c_atmel", 0x29), -+ } -+}; -+ -+static void __init hiveap_121_setup(void) -+{ -+ u8 *base = (u8 *) KSEG1ADDR(0x1f000000); -+ u8 wlan0_mac[ETH_ALEN]; -+ u8 wlan1_mac[ETH_ALEN]; -+ -+ /* NAND */ -+ ath79_nfc_set_ecc_mode(AR934X_NFC_ECC_HW); -+ ath79_register_nfc(); -+ -+ /* SPI */ -+ ath79_register_m25p80(NULL); -+ -+ /* MDIO Interface */ -+ ath79_register_mdio(0, 0x0); -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_RXD_DELAY | -+ AR934X_ETH_CFG_RDV_DELAY); -+ -+ /* GMAC0 is connected to the RGMII interface to an Atheros AR8035-A */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ base + HIVEAP_121_MAC_OFFSET, 0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(HIVEAP_121_LAN_PHYADDR); -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_eth0_pll_data.pll_100 = 0x00000101; -+ ath79_eth0_pll_data.pll_10 = 0x00001313; -+ ath79_register_eth(0); -+ -+ /* i2c */ -+ ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE); -+ platform_device_register(&hiveap_121_i2c_gpio_device); -+ -+ /* TPM */ -+ i2c_register_board_info(0, tpm_i2c_info, ARRAY_SIZE(tpm_i2c_info)); -+ -+ /* LEDs and Buttons */ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(hiveap_121_leds_gpio), -+ hiveap_121_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, HIVEAP_121_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(hiveap_121_gpio_keys), -+ hiveap_121_gpio_keys); -+ -+ /* USB */ -+ gpio_request_one(HIVEAP_121_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ /* XLNA - SoC Wireless */ -+ ath79_wmac_set_ext_lna_gpio(0, HIVEAP_121_GPIO_XLNA0); -+ ath79_wmac_set_ext_lna_gpio(1, HIVEAP_121_GPIO_XLNA1); -+ -+ /* SoC Wireless */ -+ ath79_init_mac(wlan0_mac, base + HIVEAP_121_MAC_OFFSET, 1); -+ ath79_register_wmac(NULL, wlan0_mac); /* Caldata in OTP */ -+ -+ /* PCIe Wireless */ -+ ath79_init_mac(wlan1_mac, base + HIVEAP_121_MAC_OFFSET, 2); -+ ap91_pci_init(NULL, wlan1_mac); /* Caldata in OTP */ -+} -+ -+MIPS_MACHINE(ATH79_MACH_HIVEAP_121, "HiveAP-121", "Aerohive HiveAP-121", -+ hiveap_121_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-hiwifi-hc6361.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-hiwifi-hc6361.c -new file mode 100644 -index 0000000000..6600595c05 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-hiwifi-hc6361.c -@@ -0,0 +1,115 @@ -+/* -+ * HiWiFi HC6361 board support -+ * -+ * Copyright (C) 2012-2013 eric -+ * Copyright (C) 2014 Yousong Zhou -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define HIWIFI_HC6361_GPIO_LED_WLAN_2P4 0 /* 2.4G WLAN LED */ -+#define HIWIFI_HC6361_GPIO_LED_SYSTEM 1 /* System LED */ -+#define HIWIFI_HC6361_GPIO_LED_INTERNET 27 /* Internet LED */ -+ -+#define HIWIFI_HC6361_GPIO_USBPOWER 20 /* USB power control */ -+#define HIWIFI_HC6361_GPIO_BTN_RST 11 /* Reset button */ -+ -+#define HIWIFI_HC6361_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define HIWIFI_HC6361_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * HIWIFI_HC6361_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led hiwifi_leds_gpio[] __initdata = { -+ { -+ .name = "hiwifi:blue:wlan-2p4", -+ .gpio = HIWIFI_HC6361_GPIO_LED_WLAN_2P4, -+ .active_low = 1, -+ }, { -+ .name = "hiwifi:blue:system", -+ .gpio = HIWIFI_HC6361_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "hiwifi:blue:internet", -+ .gpio = HIWIFI_HC6361_GPIO_LED_INTERNET, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button hiwifi_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = HIWIFI_HC6361_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = HIWIFI_HC6361_GPIO_BTN_RST, -+ .active_low = 1, -+ } -+}; -+ -+static void __init get_mac_from_bdinfo(u8 *mac, void *bdinfo) -+{ -+ if (sscanf(bdinfo, "fac_mac = %2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", -+ &mac[0], &mac[1], &mac[2], &mac[3], -+ &mac[4], &mac[5]) == 6) { -+ return; -+ } -+ -+ printk(KERN_WARNING "Parsing MAC address failed.\n"); -+ memcpy(mac, "\x00\xba\xbe\x00\x00\x00", 6); -+} -+ -+static void __init hiwifi_hc6361_setup(void) -+{ -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 mac[6]; -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_m25p80(NULL); -+ ath79_gpio_function_enable( -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(hiwifi_leds_gpio), -+ hiwifi_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, HIWIFI_HC6361_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(hiwifi_gpio_keys), -+ hiwifi_gpio_keys); -+ gpio_request_one(HIWIFI_HC6361_GPIO_USBPOWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ get_mac_from_bdinfo(mac, (void *) KSEG1ADDR(0x1f010180)); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_register_eth(1); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_HIWIFI_HC6361, "HiWiFi-HC6361", -+ "HiWiFi HC6361", hiwifi_hc6361_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-hornet-ub.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-hornet-ub.c -new file mode 100644 -index 0000000000..1d21424585 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-hornet-ub.c -@@ -0,0 +1,142 @@ -+/* -+ * ALFA NETWORK Hornet-UB board support -+ * -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define HORNET_UB_GPIO_LED_WLAN 0 -+#define HORNET_UB_GPIO_LED_USB 1 -+#define HORNET_UB_GPIO_LED_LAN 13 -+#define HORNET_UB_GPIO_LED_WAN 17 -+#define HORNET_UB_GPIO_LED_WPS 27 -+#define HORNET_UB_GPIO_EXT_LNA 28 -+ -+#define HORNET_UB_GPIO_BTN_RESET 12 -+#define HORNET_UB_GPIO_BTN_WPS 11 -+ -+#define HORNET_UB_GPIO_USB_POWER 26 -+ -+#define HORNET_UB_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define HORNET_UB_KEYS_DEBOUNCE_INTERVAL (3 * HORNET_UB_KEYS_POLL_INTERVAL) -+ -+#define HORNET_UB_MAC0_OFFSET 0x0000 -+#define HORNET_UB_MAC1_OFFSET 0x0006 -+#define HORNET_UB_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led hornet_ub_leds_gpio[] __initdata = { -+ { -+ .name = "alfa:blue:lan", -+ .gpio = HORNET_UB_GPIO_LED_LAN, -+ .active_low = 0, -+ }, -+ { -+ .name = "alfa:blue:usb", -+ .gpio = HORNET_UB_GPIO_LED_USB, -+ .active_low = 0, -+ }, -+ { -+ .name = "alfa:blue:wan", -+ .gpio = HORNET_UB_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "alfa:blue:wlan", -+ .gpio = HORNET_UB_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+ { -+ .name = "alfa:blue:wps", -+ .gpio = HORNET_UB_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button hornet_ub_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = HORNET_UB_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = HORNET_UB_GPIO_BTN_WPS, -+ .active_low = 0, -+ }, -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = HORNET_UB_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = HORNET_UB_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init hornet_ub_gpio_setup(void) -+{ -+ u32 t; -+ -+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); -+ t |= AR933X_BOOTSTRAP_MDIO_GPIO_EN; -+ ath79_reset_wr(AR933X_RESET_REG_BOOTSTRAP, t); -+ -+ gpio_request_one(HORNET_UB_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ gpio_request_one(HORNET_UB_GPIO_EXT_LNA, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "external LNA0"); -+ -+} -+ -+static void __init hornet_ub_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ hornet_ub_gpio_setup(); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(hornet_ub_leds_gpio), -+ hornet_ub_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, HORNET_UB_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(hornet_ub_gpio_keys), -+ hornet_ub_gpio_keys); -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, -+ art + HORNET_UB_MAC0_OFFSET, 0); -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ art + HORNET_UB_MAC1_OFFSET, 0); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_register_eth(1); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(art + HORNET_UB_CALDATA_OFFSET, NULL); -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_HORNET_UB, "HORNET-UB", "ALFA NETWORK Hornet-UB", -+ hornet_ub_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ja76pf.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ja76pf.c -new file mode 100644 -index 0000000000..d1fe0f8a26 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ja76pf.c -@@ -0,0 +1,190 @@ -+/* -+ * jjPlus JA76PF board support -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define JA76PF_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define JA76PF_KEYS_DEBOUNCE_INTERVAL (3 * JA76PF_KEYS_POLL_INTERVAL) -+ -+#define JA76PF_GPIO_I2C_SCL 0 -+#define JA76PF_GPIO_I2C_SDA 1 -+#define JA76PF_GPIO_LED_1 5 -+#define JA76PF_GPIO_LED_2 4 -+#define JA76PF_GPIO_LED_3 3 -+#define JA76PF_GPIO_BTN_RESET 11 -+ -+static struct gpio_led ja76pf_leds_gpio[] __initdata = { -+ { -+ .name = "jjplus:green:led1", -+ .gpio = JA76PF_GPIO_LED_1, -+ .active_low = 1, -+ }, { -+ .name = "jjplus:green:led2", -+ .gpio = JA76PF_GPIO_LED_2, -+ .active_low = 1, -+ }, { -+ .name = "jjplus:green:led3", -+ .gpio = JA76PF_GPIO_LED_3, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button ja76pf_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = JA76PF_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = JA76PF_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static struct i2c_gpio_platform_data ja76pf_i2c_gpio_data = { -+ .sda_pin = JA76PF_GPIO_I2C_SDA, -+ .scl_pin = JA76PF_GPIO_I2C_SCL, -+}; -+ -+static struct platform_device ja76pf_i2c_gpio_device = { -+ .name = "i2c-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &ja76pf_i2c_gpio_data, -+ } -+}; -+ -+static const char *ja76pf_part_probes[] = { -+ "RedBoot", -+ NULL, -+}; -+ -+static struct flash_platform_data ja76pf_flash_data = { -+ .part_probes = ja76pf_part_probes, -+}; -+ -+#define JA76PF_WAN_PHYMASK (1 << 4) -+#define JA76PF_LAN_PHYMASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 < 3)) -+#define JA76PF_MDIO_PHYMASK (JA76PF_LAN_PHYMASK | JA76PF_WAN_PHYMASK) -+ -+static void __init ja76pf_init(void) -+{ -+ ath79_register_m25p80(&ja76pf_flash_data); -+ -+ ath79_register_mdio(0, ~JA76PF_MDIO_PHYMASK); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = JA76PF_LAN_PHYMASK; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth1_data.phy_mask = JA76PF_WAN_PHYMASK; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ platform_device_register(&ja76pf_i2c_gpio_device); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ja76pf_leds_gpio), -+ ja76pf_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, JA76PF_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ja76pf_gpio_keys), -+ ja76pf_gpio_keys); -+ -+ ath79_register_usb(); -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_JA76PF, "JA76PF", "jjPlus JA76PF", ja76pf_init); -+ -+#define JA76PF2_GPIO_LED_D2 5 -+#define JA76PF2_GPIO_LED_D3 4 -+#define JA76PF2_GPIO_LED_D4 3 -+#define JA76PF2_GPIO_BTN_RESET 7 -+#define JA76PF2_GPIO_BTN_WPS 8 -+ -+static struct gpio_led ja76pf2_leds_gpio[] __initdata = { -+ { -+ .name = "jjplus:green:led1", -+ .gpio = JA76PF2_GPIO_LED_D2, -+ .active_low = 1, -+ }, { -+ .name = "jjplus:green:led2", -+ .gpio = JA76PF2_GPIO_LED_D3, -+ .active_low = 0, -+ }, { -+ .name = "jjplus:green:led3", -+ .gpio = JA76PF2_GPIO_LED_D4, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button ja76pf2_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = JA76PF_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = JA76PF2_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = JA76PF_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = JA76PF2_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+#define JA76PF2_LAN_PHYMASK BIT(0) -+#define JA76PF2_WAN_PHYMASK BIT(4) -+#define JA76PF2_MDIO_PHYMASK (JA76PF2_LAN_PHYMASK | JA76PF2_WAN_PHYMASK) -+ -+static void __init ja76pf2_init(void) -+{ -+ ath79_register_m25p80(&ja76pf_flash_data); -+ -+ ath79_register_mdio(0, ~JA76PF2_MDIO_PHYMASK); -+ -+ /* MAC0 is connected to the CPU port of the AR8316 switch */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ -+ /* MAC1 is connected to the PHY4 of the AR8316 switch */ -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth1_data.phy_mask = BIT(4); -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ja76pf2_leds_gpio), -+ ja76pf2_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, JA76PF_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ja76pf2_gpio_keys), -+ ja76pf2_gpio_keys); -+ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_JA76PF2, "JA76PF2", "jjPlus JA76PF2", ja76pf2_init); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-jwap003.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-jwap003.c -new file mode 100644 -index 0000000000..a3c93ccd90 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-jwap003.c -@@ -0,0 +1,95 @@ -+/* -+ * jjPlus JWAP003 board support -+ * -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-m25p80.h" -+#include "dev-gpio-buttons.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define JWAP003_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define JWAP003_KEYS_DEBOUNCE_INTERVAL (3 * JWAP003_KEYS_POLL_INTERVAL) -+ -+#define JWAP003_GPIO_WPS 11 -+#define JWAP003_GPIO_I2C_SCL 0 -+#define JWAP003_GPIO_I2C_SDA 1 -+ -+static struct gpio_keys_button jwap003_gpio_keys[] __initdata = { -+ { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = JWAP003_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = JWAP003_GPIO_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static struct i2c_gpio_platform_data jwap003_i2c_gpio_data = { -+ .sda_pin = JWAP003_GPIO_I2C_SDA, -+ .scl_pin = JWAP003_GPIO_I2C_SCL, -+}; -+ -+static struct platform_device jwap003_i2c_gpio_device = { -+ .name = "i2c-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &jwap003_i2c_gpio_data, -+ } -+}; -+ -+static const char *jwap003_part_probes[] = { -+ "RedBoot", -+ NULL, -+}; -+ -+static struct flash_platform_data jwap003_flash_data = { -+ .part_probes = jwap003_part_probes, -+}; -+ -+#define JWAP003_WAN_PHYMASK BIT(0) -+#define JWAP003_LAN_PHYMASK BIT(4) -+ -+static void __init jwap003_init(void) -+{ -+ ath79_register_m25p80(&jwap003_flash_data); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth0_data.phy_mask = JWAP003_WAN_PHYMASK; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.has_ar8216 = 1; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth1_data.phy_mask = JWAP003_LAN_PHYMASK; -+ ath79_eth1_data.speed = SPEED_100; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ platform_device_register(&jwap003_i2c_gpio_device); -+ -+ ath79_register_usb(); -+ -+ ath79_register_gpio_keys_polled(-1, JWAP003_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(jwap003_gpio_keys), -+ jwap003_gpio_keys); -+ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_JWAP003, "JWAP003", "jjPlus JWAP003", jwap003_init); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-jwap230.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-jwap230.c -new file mode 100644 -index 0000000000..de24db4d4b ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-jwap230.c -@@ -0,0 +1,158 @@ -+/* -+ * jjPlus JWAP230 board support -+ * -+ * Copyright (C) 2016 Piotr Dymacz -+ * -+ * Based on mach-wpj558.c and mach-tl-wr1043nd-v2.c -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define JWAP230_GPIO_LED_LED1 23 -+#define JWAP230_GPIO_LED_LED2 22 -+#define JWAP230_GPIO_LED_LED3 21 -+ -+#define JWAP230_MAC0_OFFSET 0x0 -+#define JWAP230_MAC1_OFFSET 0x6 -+#define JWAP230_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led jwap230_leds_gpio[] __initdata = { -+ { -+ .name = "jwap230:green:led1", -+ .gpio = JWAP230_GPIO_LED_LED1, -+ .active_low = 1, -+ }, -+ { -+ .name = "jwap230:green:led2", -+ .gpio = JWAP230_GPIO_LED_LED2, -+ .active_low = 1, -+ }, -+ { -+ .name = "jwap230:green:led3", -+ .gpio = JWAP230_GPIO_LED_LED3, -+ .active_low = 1, -+ } -+}; -+ -+static const struct ar8327_led_info jwap230_leds_qca8337[] = { -+ AR8327_LED_INFO(PHY0_0, HW, "jwap230:green:lan"), -+ AR8327_LED_INFO(PHY4_0, HW, "jwap230:green:wan"), -+}; -+ -+/* Blink rate: 1 Gbps -> 8 hz, 100 Mbs -> 4 Hz, 10 Mbps -> 2 Hz */ -+static struct ar8327_led_cfg jwap230_qca8337_led_cfg = { -+ .led_ctrl0 = 0xcf37cf37, -+ .led_ctrl1 = 0xcf37cf37, -+ .led_ctrl2 = 0xcf37cf37, -+ .led_ctrl3 = 0x0, -+ .open_drain = true, -+}; -+ -+/* QCA8337 GMAC0 is connected with QCA9558 over RGMII */ -+static struct ar8327_pad_cfg jwap230_qca8337_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+ .mac06_exchange_dis = true, -+}; -+ -+/* QCA8337 GMAC6 is connected with QCA9558 over SGMII */ -+static struct ar8327_pad_cfg jwap230_qca8337_pad6_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL0, -+}; -+ -+static struct ar8327_platform_data jwap230_qca8337_data = { -+ .pad0_cfg = &jwap230_qca8337_pad0_cfg, -+ .pad6_cfg = &jwap230_qca8337_pad6_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .port6_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &jwap230_qca8337_led_cfg, -+ .num_leds = ARRAY_SIZE(jwap230_leds_qca8337), -+ .leds = jwap230_leds_qca8337, -+}; -+ -+static struct mdio_board_info jwap230_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &jwap230_qca8337_data, -+ }, -+}; -+ -+static void __init jwap230_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(jwap230_leds_gpio), -+ jwap230_leds_gpio); -+ -+ mdiobus_register_board_info(jwap230_mdio0_info, -+ ARRAY_SIZE(jwap230_mdio0_info)); -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ /* QCA9558 GMAC0 is connected to RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0xa6000000; -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + JWAP230_MAC0_OFFSET, 0); -+ ath79_register_eth(0); -+ -+ /* QCA9558 GMAC1 is connected to SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + JWAP230_MAC1_OFFSET, 0); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(art + JWAP230_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_pci(); -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_JWAP230, "JWAP230", "jjPlus JWAP230", jwap230_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-koala.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-koala.c -new file mode 100644 -index 0000000000..41254a6d7a ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-koala.c -@@ -0,0 +1,161 @@ -+/* -+ * OCEDO Koala board support -+ * Based on the MR1750 machine file -+ * -+ * Copyright (c) 2012 Qualcomm Atheros -+ * Copyright (c) 2012-2013 Marek Lindner -+ * Copyright (c) 2018 David Bauer -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define KOALA_GPIO_LED_POWER 22 -+#define KOALA_GPIO_LED_WLAN_5G 13 -+#define KOALA_GPIO_LED_WLAN_2G 23 -+#define KOALA_GPIO_LED_WLAN_SYS 19 -+ -+#define KOALA_GPIO_BTN_RESET 17 -+ -+#define KOALA_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define KOALA_KEYS_DEBOUNCE_INTERVAL (3 * KOALA_KEYS_POLL_INTERVAL) -+ -+#define KOALA_LAN_MAC_OFFSET 0 -+#define KOALA_WIFI2G_MAC_OFFSET 0x06 -+#define KOALA_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led koala_leds_gpio[] __initdata = { -+ { -+ .name = "koala:green:power", -+ .gpio = KOALA_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "koala:red:wlan58", -+ .gpio = KOALA_GPIO_LED_WLAN_5G, -+ .active_low = 1, -+ }, -+ { -+ .name = "koala:yellow:wlan2", -+ .gpio = KOALA_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "koala:blue:sys", -+ .gpio = KOALA_GPIO_LED_WLAN_SYS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button koala_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = KOALA_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = KOALA_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct at803x_platform_data koala_at803x_data = { -+ .disable_smarteee = 1, -+ .enable_rgmii_rx_delay = 1, -+ .enable_rgmii_tx_delay = 0, -+ .fixup_rgmii_tx_delay = 1, -+}; -+ -+static struct mdio_board_info koala_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 5, -+ .platform_data = &koala_at803x_data, -+ }, -+}; -+ -+static void __init koala_setup_qca955x_eth_cfg(u32 mask, -+ unsigned int rxd, -+ unsigned int rxdv, -+ unsigned int txd, -+ unsigned int txe) -+{ -+ void __iomem *base; -+ u32 t; -+ -+ base = ioremap(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE); -+ -+ t = mask; -+ t |= rxd << QCA955X_ETH_CFG_RXD_DELAY_SHIFT; -+ t |= rxdv << QCA955X_ETH_CFG_RDV_DELAY_SHIFT; -+ t |= txd << QCA955X_ETH_CFG_TXD_DELAY_SHIFT; -+ t |= txe << QCA955X_ETH_CFG_TXE_DELAY_SHIFT; -+ -+ __raw_writel(t, base + QCA955X_GMAC_REG_ETH_CFG); -+ -+ iounmap(base); -+} -+ -+static void __init koala_setup(void) -+{ -+ u8 *art = (u8 *)KSEG1ADDR(0x1fff0000); -+ u8 mac[6]; -+ -+ ath79_eth0_pll_data.pll_1000 = 0xae000000; -+ ath79_eth0_pll_data.pll_100 = 0xa0000101; -+ ath79_eth0_pll_data.pll_10 = 0xa0001313; -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(koala_leds_gpio), -+ koala_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, KOALA_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(koala_gpio_keys), -+ koala_gpio_keys); -+ -+ ath79_init_mac(mac, art + KOALA_WIFI2G_MAC_OFFSET, 0); -+ ath79_register_wmac(art + KOALA_WMAC_CALDATA_OFFSET, mac); -+ ath79_register_pci(); -+ -+ koala_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN, 3, 3, 0, 0); -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(koala_mdio0_info, -+ ARRAY_SIZE(koala_mdio0_info)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + KOALA_LAN_MAC_OFFSET, 0); -+ -+ /* GMAC0 is connected to the RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(5); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_KOALA, "KOALA", "OCEDO Koala", koala_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-lan-turtle.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-lan-turtle.c -new file mode 100644 -index 0000000000..d2faa2c740 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-lan-turtle.c -@@ -0,0 +1,178 @@ -+/* -+ * Hak5 LAN Turtle and Packet Squirrel boards support -+ * -+ * Copyright (C) 2018 Sebastian Kinne -+ * Copyright (C) 2018 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+ -+#define LAN_TURTLE_GPIO_BTN_RESET 11 -+#define LAN_TURTLE_GPIO_LED_SYS 13 -+ -+#define PACKET_SQUIRREL_GPIO_BTN_SW1 18 -+#define PACKET_SQUIRREL_GPIO_BTN_SW2 20 -+#define PACKET_SQUIRREL_GPIO_BTN_SW3 21 -+#define PACKET_SQUIRREL_GPIO_BTN_SW4 24 -+#define PACKET_SQUIRREL_GPIO_BTN_RESET 11 -+#define PACKET_SQUIRREL_GPIO_LED_B 23 -+#define PACKET_SQUIRREL_GPIO_LED_G 22 -+#define PACKET_SQUIRREL_GPIO_LED_R 19 -+ -+#define HAK5_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define HAK5_KEYS_DEBOUNCE_INTERVAL (3 * HAK5_KEYS_POLL_INTERVAL) -+ -+static const char *hak5_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data hak5_flash_data = { -+ .part_probes = hak5_part_probes, -+}; -+ -+/* LAN Turtle */ -+static struct gpio_led lan_turtle_leds_gpio[] __initdata = { -+ { -+ .name = "lan-turtle:orange:system", -+ .gpio = LAN_TURTLE_GPIO_LED_SYS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button lan_turtle_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = HAK5_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = LAN_TURTLE_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+/* Packet Squirrel */ -+static struct gpio_led packet_squirrel_leds_gpio[] __initdata = { -+ { -+ .name = "packet-squirrel:blue:system", -+ .gpio = PACKET_SQUIRREL_GPIO_LED_B, -+ .active_low = 1, -+ }, { -+ .name = "packet-squirrel:green:system", -+ .gpio = PACKET_SQUIRREL_GPIO_LED_G, -+ .active_low = 1, -+ }, { -+ .name = "packet-squirrel:red:system", -+ .gpio = PACKET_SQUIRREL_GPIO_LED_R, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button packet_squirrel_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = HAK5_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = PACKET_SQUIRREL_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "sw1", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = HAK5_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = PACKET_SQUIRREL_GPIO_BTN_SW1, -+ .active_low = 1, -+ }, { -+ .desc = "sw2", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .debounce_interval = HAK5_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = PACKET_SQUIRREL_GPIO_BTN_SW2, -+ .active_low = 1, -+ }, { -+ .desc = "sw3", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .debounce_interval = HAK5_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = PACKET_SQUIRREL_GPIO_BTN_SW3, -+ .active_low = 1, -+ }, { -+ .desc = "sw4", -+ .type = EV_KEY, -+ .code = BTN_3, -+ .debounce_interval = HAK5_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = PACKET_SQUIRREL_GPIO_BTN_SW4, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init hak5_common_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ -+ ath79_register_m25p80(&hak5_flash_data); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_switch_data.phy_poll_mask = 0xfe; -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_register_eth(0); -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); -+ ath79_register_eth(1); -+ -+ ath79_register_usb(); -+ -+ /* GPIO11/12 */ -+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_UART_RTS_CTS_EN); -+} -+ -+static void __init lan_turtle_setup(void) -+{ -+ hak5_common_setup(); -+ -+ /* GPIO13 */ -+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(lan_turtle_leds_gpio), -+ lan_turtle_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, HAK5_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(lan_turtle_gpio_keys), -+ lan_turtle_gpio_keys); -+} -+ -+static void __init packet_squirrel_setup(void) -+{ -+ hak5_common_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(packet_squirrel_leds_gpio), -+ packet_squirrel_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, HAK5_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(packet_squirrel_gpio_keys), -+ packet_squirrel_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_LAN_TURTLE, "LAN-TURTLE", -+ "Hak5 LAN Turtle", lan_turtle_setup); -+ -+MIPS_MACHINE(ATH79_MACH_PACKET_SQUIRREL, "PACKET-SQUIRREL", -+ "Hak5 Packet Squirrel", packet_squirrel_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-lima.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-lima.c -new file mode 100644 -index 0000000000..9867429684 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-lima.c -@@ -0,0 +1,86 @@ -+/* -+ * 8devices Lima board support -+ * -+ * Copyright (C) 2016 Mantas Pucka -+ * Copyright (C) 2017 Karol Dudek -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define LIMA_GPIO_BTN_1_DEFAULT 16 -+#define LIMA_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define LIMA_KEYS_DEBOUNCE_INTERVAL (3 * LIMA_KEYS_POLL_INTERVAL) -+ -+#define LIMA_ETH_PHYS (BIT(0) | BIT(1)) -+ -+#define LIMA_MAC0_OFFSET 0x0000 -+#define LIMA_MAC1_OFFSET 0x0006 -+ -+#define LIMA_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_keys_button lima_gpio_keys[] __initdata = { -+ { -+ .desc = "button1", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .debounce_interval = LIMA_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = LIMA_GPIO_BTN_1_DEFAULT, -+ .active_low = 1, -+ } -+}; -+ -+static void __init lima_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1f080000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_gpio_keys_polled(-1, LIMA_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(lima_gpio_keys), -+ lima_gpio_keys); -+ -+ ath79_setup_ar933x_phy4_switch(true, true); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + LIMA_MAC0_OFFSET, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + LIMA_MAC1_OFFSET, 0); -+ -+ ath79_register_mdio(0, ~LIMA_ETH_PHYS); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ -+ ath79_switch_data.phy_poll_mask |= BIT(0); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_mask = BIT(1); -+ ath79_register_eth(1); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(art + LIMA_CALDATA_OFFSET, NULL); -+ ath79_register_usb(); -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_LIMA, "LIMA", "8devices Lima board", lima_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-mc-mac1200r.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-mc-mac1200r.c -new file mode 100644 -index 0000000000..70051cff47 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-mc-mac1200r.c -@@ -0,0 +1,155 @@ -+/* -+ * MERCURY MAC1200R board support -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * Copyright (C) 2013 Gui Iribarren -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define MAC1200R_GPIO_LED_WLAN2G 13 -+#define MAC1200R_GPIO_LED_WLAN5G 17 -+#define MAC1200R_GPIO_LED_SYSTEM 14 -+#define MAC1200R_GPIO_LED_WPS 11 -+#define MAC1200R_GPIO_LED_WAN 12 -+#define MAC1200R_GPIO_LED_LAN1 15 -+#define MAC1200R_GPIO_LED_LAN2 21 -+#define MAC1200R_GPIO_LED_LAN3 22 -+#define MAC1200R_GPIO_LED_LAN4 20 -+ -+#define MAC1200R_GPIO_BTN_WPS 16 -+ -+#define MAC1200R_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define MAC1200R_KEYS_DEBOUNCE_INTERVAL (3 * MAC1200R_KEYS_POLL_INTERVAL) -+ -+#define MAC1200R_MAC0_OFFSET 0 -+#define MAC1200R_MAC1_OFFSET 6 -+#define MAC1200R_WMAC_CALDATA_OFFSET 0x1000 -+#define MAC1200R_PCIE_CALDATA_OFFSET 0x5000 -+ -+static const char *mac1200r_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data mac1200r_flash_data = { -+ .part_probes = mac1200r_part_probes, -+}; -+ -+static struct gpio_led mac1200r_leds_gpio[] __initdata = { -+ { -+ .name = "mercury:green:wps", -+ .gpio = MAC1200R_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+ { -+ .name = "mercury:green:system", -+ .gpio = MAC1200R_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+ { -+ .name = "mercury:green:wlan2g", -+ .gpio = MAC1200R_GPIO_LED_WLAN2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "mercury:green:wlan5g", -+ .gpio = MAC1200R_GPIO_LED_WLAN5G, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button mac1200r_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = MAC1200R_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MAC1200R_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+ -+static void __init mac1200r_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 tmpmac[ETH_ALEN]; -+ -+ ath79_register_m25p80(&mac1200r_flash_data); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(mac1200r_leds_gpio), -+ mac1200r_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, MAC1200R_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(mac1200r_gpio_keys), -+ mac1200r_gpio_keys); -+ -+ ath79_init_mac(tmpmac, mac, 0); -+ ath79_wmac_disable_5ghz(); -+ ath79_register_wmac(art + MAC1200R_WMAC_CALDATA_OFFSET, tmpmac); -+ -+ ath79_init_mac(tmpmac, mac, 1); -+ ap91_pci_init(art + MAC1200R_PCIE_CALDATA_OFFSET, tmpmac); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ /* LAN */ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 2); -+ -+ /* GMAC0 is connected to the PHY4 of the internal switch */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(4); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ -+ ath79_register_eth(0); -+ -+ ath79_gpio_output_select(MAC1200R_GPIO_LED_LAN1, -+ AR934X_GPIO_OUT_LED_LINK3); -+ ath79_gpio_output_select(MAC1200R_GPIO_LED_LAN2, -+ AR934X_GPIO_OUT_LED_LINK2); -+ ath79_gpio_output_select(MAC1200R_GPIO_LED_LAN3, -+ AR934X_GPIO_OUT_LED_LINK1); -+ ath79_gpio_output_select(MAC1200R_GPIO_LED_LAN4, -+ AR934X_GPIO_OUT_LED_LINK0); -+ ath79_gpio_output_select(MAC1200R_GPIO_LED_WAN, -+ AR934X_GPIO_OUT_LED_LINK4); -+} -+ -+MIPS_MACHINE(ATH79_MACH_MC_MAC1200R, "MC-MAC1200R", -+ "MERCURY MAC1200R", -+ mac1200r_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-mr12.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr12.c -new file mode 100644 -index 0000000000..5a337e5c9f ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr12.c -@@ -0,0 +1,114 @@ -+/* -+ * Cisco Meraki MR12 board support -+ * -+ * Copyright (C) 2014-2015 Chris Blake -+ * -+ * Based on Atheros AP96 board support configuration -+ * -+ * Copyright (C) 2009 Marco Porsch -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * Copyright (C) 2010 Atheros Communications -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+ -+#define MR12_GPIO_LED_W4_GREEN 14 -+#define MR12_GPIO_LED_W3_GREEN 13 -+#define MR12_GPIO_LED_W2_GREEN 12 -+#define MR12_GPIO_LED_W1_GREEN 11 -+ -+#define MR12_GPIO_LED_WAN 15 -+ -+#define MR12_GPIO_LED_POWER_ORANGE 16 -+#define MR12_GPIO_LED_POWER_GREEN 17 -+ -+#define MR12_GPIO_BTN_RESET 8 -+#define MR12_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define MR12_KEYS_DEBOUNCE_INTERVAL (3 * MR12_KEYS_POLL_INTERVAL) -+ -+#define MR12_WAN_PHYMASK BIT(4) -+ -+#define MR12_CALDATA0_OFFSET 0x21000 -+ -+static struct gpio_led MR12_leds_gpio[] __initdata = { -+ { -+ .name = "mr12:green:wan", -+ .gpio = MR12_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "mr12:orange:power", -+ .gpio = MR12_GPIO_LED_POWER_ORANGE, -+ .active_low = 1, -+ }, { -+ .name = "mr12:green:power", -+ .gpio = MR12_GPIO_LED_POWER_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "mr12:green:wifi4", -+ .gpio = MR12_GPIO_LED_W4_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "mr12:green:wifi3", -+ .gpio = MR12_GPIO_LED_W3_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "mr12:green:wifi2", -+ .gpio = MR12_GPIO_LED_W2_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "mr12:green:wifi1", -+ .gpio = MR12_GPIO_LED_W1_GREEN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button MR12_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = MR12_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MR12_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init MR12_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0xbffd0000); -+ u8 wlan_mac[ETH_ALEN]; -+ -+ ath79_register_mdio(0,0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = MR12_WAN_PHYMASK; -+ ath79_register_eth(0); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(MR12_leds_gpio), -+ MR12_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, MR12_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(MR12_gpio_keys), -+ MR12_gpio_keys); -+ -+ ath79_init_mac(wlan_mac, mac, 1); -+ ap91_pci_init(mac + MR12_CALDATA0_OFFSET, wlan_mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_MR12, "MR12", "Meraki MR12", MR12_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-mr16.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr16.c -new file mode 100644 -index 0000000000..9da21eab5a ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr16.c -@@ -0,0 +1,118 @@ -+/* -+ * Cisco Meraki MR16 board support -+ * -+ * Copyright (C) 2015 Chris Blake -+ * -+ * Based on Atheros AP96 board support configuration -+ * -+ * Copyright (C) 2009 Marco Porsch -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * Copyright (C) 2010 Atheros Communications -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+ -+#define MR16_GPIO_LED_W4_GREEN 3 -+#define MR16_GPIO_LED_W3_GREEN 2 -+#define MR16_GPIO_LED_W2_GREEN 1 -+#define MR16_GPIO_LED_W1_GREEN 0 -+ -+#define MR16_GPIO_LED_WAN 4 -+ -+#define MR16_GPIO_LED_POWER_ORANGE 5 -+#define MR16_GPIO_LED_POWER_GREEN 6 -+ -+#define MR16_GPIO_BTN_RESET 7 -+#define MR16_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define MR16_KEYS_DEBOUNCE_INTERVAL (3 * MR16_KEYS_POLL_INTERVAL) -+ -+#define MR16_WAN_PHYMASK BIT(0) -+ -+#define MR16_CALDATA0_OFFSET 0x21000 -+#define MR16_CALDATA1_OFFSET 0x25000 -+ -+static struct gpio_led MR16_leds_gpio[] __initdata = { -+ { -+ .name = "mr16:green:wan", -+ .gpio = MR16_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "mr16:orange:power", -+ .gpio = MR16_GPIO_LED_POWER_ORANGE, -+ .active_low = 1, -+ }, { -+ .name = "mr16:green:power", -+ .gpio = MR16_GPIO_LED_POWER_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "mr16:green:wifi4", -+ .gpio = MR16_GPIO_LED_W4_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "mr16:green:wifi3", -+ .gpio = MR16_GPIO_LED_W3_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "mr16:green:wifi2", -+ .gpio = MR16_GPIO_LED_W2_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "mr16:green:wifi1", -+ .gpio = MR16_GPIO_LED_W1_GREEN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button MR16_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = MR16_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MR16_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init MR16_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0xbffd0000); -+ u8 wlan0_mac[ETH_ALEN]; -+ u8 wlan1_mac[ETH_ALEN]; -+ -+ ath79_register_mdio(0,0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = MR16_WAN_PHYMASK; -+ ath79_register_eth(0); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(MR16_leds_gpio), -+ MR16_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, MR16_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(MR16_gpio_keys), -+ MR16_gpio_keys); -+ -+ ath79_init_mac(wlan0_mac, mac, 1); -+ ath79_init_mac(wlan1_mac, mac, 2); -+ ap94_pci_init(mac + MR16_CALDATA0_OFFSET, wlan0_mac, -+ mac + MR16_CALDATA1_OFFSET, wlan1_mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_MR16, "MR16", "Meraki MR16", MR16_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-mr1750.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr1750.c -new file mode 100644 -index 0000000000..987ed4bd5d ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr1750.c -@@ -0,0 +1,171 @@ -+/* -+ * MR1750 board support -+ * -+ * Copyright (c) 2012 Qualcomm Atheros -+ * Copyright (c) 2012-2013 Marek Lindner -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define MR1750_GPIO_LED_LAN 12 -+#define MR1750_GPIO_LED_WLAN_2G 13 -+#define MR1750_GPIO_LED_STATUS_GREEN 19 -+#define MR1750_GPIO_LED_STATUS_RED 21 -+#define MR1750_GPIO_LED_POWER 22 -+#define MR1750_GPIO_LED_WLAN_5G 23 -+ -+#define MR1750_GPIO_BTN_RESET 17 -+ -+#define MR1750_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define MR1750_KEYS_DEBOUNCE_INTERVAL (3 * MR1750_KEYS_POLL_INTERVAL) -+ -+#define MR1750_MAC0_OFFSET 0 -+#define MR1750_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led mr1750_leds_gpio[] __initdata = { -+ { -+ .name = "mr1750:blue:power", -+ .gpio = MR1750_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr1750:blue:wan", -+ .gpio = MR1750_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr1750:blue:wlan24", -+ .gpio = MR1750_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr1750:blue:wlan58", -+ .gpio = MR1750_GPIO_LED_WLAN_5G, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr1750:green:status", -+ .gpio = MR1750_GPIO_LED_STATUS_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr1750:red:status", -+ .gpio = MR1750_GPIO_LED_STATUS_RED, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button mr1750_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = MR1750_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MR1750_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct at803x_platform_data mr1750_at803x_data = { -+ .disable_smarteee = 1, -+ .enable_rgmii_rx_delay = 1, -+ .enable_rgmii_tx_delay = 0, -+ .fixup_rgmii_tx_delay = 1, -+}; -+ -+static struct mdio_board_info mr1750_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 5, -+ .platform_data = &mr1750_at803x_data, -+ }, -+}; -+ -+static void __init mr1750_setup_qca955x_eth_cfg(u32 mask, -+ unsigned int rxd, -+ unsigned int rxdv, -+ unsigned int txd, -+ unsigned int txe) -+{ -+ void __iomem *base; -+ u32 t; -+ -+ base = ioremap(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE); -+ -+ t = mask; -+ t |= rxd << QCA955X_ETH_CFG_RXD_DELAY_SHIFT; -+ t |= rxdv << QCA955X_ETH_CFG_RDV_DELAY_SHIFT; -+ t |= txd << QCA955X_ETH_CFG_TXD_DELAY_SHIFT; -+ t |= txe << QCA955X_ETH_CFG_TXE_DELAY_SHIFT; -+ -+ __raw_writel(t, base + QCA955X_GMAC_REG_ETH_CFG); -+ -+ iounmap(base); -+} -+ -+static void __init mr1750_setup(void) -+{ -+ u8 *art = (u8 *)KSEG1ADDR(0x1fff0000); -+ u8 mac[6]; -+ -+ ath79_eth0_pll_data.pll_1000 = 0xae000000; -+ ath79_eth0_pll_data.pll_100 = 0xa0000101; -+ ath79_eth0_pll_data.pll_10 = 0xa0001313; -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(mr1750_leds_gpio), -+ mr1750_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, MR1750_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(mr1750_gpio_keys), -+ mr1750_gpio_keys); -+ -+ ath79_init_mac(mac, art + MR1750_MAC0_OFFSET, 1); -+ ath79_register_wmac(art + MR1750_WMAC_CALDATA_OFFSET, mac); -+ ath79_register_pci(); -+ -+ mr1750_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN, 3, 3, 0, 0); -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(mr1750_mdio0_info, -+ ARRAY_SIZE(mr1750_mdio0_info)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + MR1750_MAC0_OFFSET, 0); -+ -+ /* GMAC0 is connected to the RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(5); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_MR1750, "MR1750", "OpenMesh MR1750", mr1750_setup); -+MIPS_MACHINE(ATH79_MACH_MR1750V2, "MR1750v2", "OpenMesh MR1750v2", mr1750_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c -new file mode 100644 -index 0000000000..2d2fb6e84c ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c -@@ -0,0 +1,286 @@ -+/* -+ * Cisco Meraki MR18 board support -+ * -+ * Copyright (C) 2015 Chris Blake -+ * Copyright (C) 2015 Christian Lamparter -+ * Copyright (C) 2015 Thomas Hebb -+ * -+ * Based on Cisco Meraki GPL Release r23-20150601 MR18 Device Config -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-nfc.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define MR18_GPIO_LED_POWER_WHITE 18 -+#define MR18_GPIO_LED_POWER_ORANGE 21 -+ -+#define MR18_GPIO_BTN_RESET 17 -+#define MR18_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define MR18_KEYS_DEBOUNCE_INTERVAL (3 * MR18_KEYS_POLL_INTERVAL) -+ -+#define MR18_WAN_PHYADDR 3 -+ -+/* used for eth calibration */ -+#define MR18_OTP_BASE (AR71XX_APB_BASE + 0x130000) -+#define MR18_OTP_SIZE (0x2000) /* just a guess */ -+#define MR18_OTP_MEM_0_REG (0x0000) -+#define MR18_OTP_INTF2_REG (0x1008) -+#define MR18_OTP_STATUS0_REG (0x1018) -+#define MR18_OTP_STATUS0_EFUSE_VALID BIT(2) -+ -+#define MR18_OTP_STATUS1_REG (0x101c) -+#define MR18_OTP_LDO_CTRL_REG (0x1024) -+#define MR18_OTP_LDO_STATUS_REG (0x102c) -+#define MR18_OTP_LDO_STATUS_POWER_ON BIT(0) -+ -+static struct gpio_led MR18_leds_gpio[] __initdata = { -+ { -+ .name = "mr18:white:power", -+ .gpio = MR18_GPIO_LED_POWER_WHITE, -+ .active_low = 1, -+ }, { -+ .name = "mr18:orange:power", -+ .gpio = MR18_GPIO_LED_POWER_ORANGE, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button MR18_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = MR18_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MR18_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct led_nu801_template tricolor_led_template = { -+ .device_name = "mr18", -+ .name = "tricolor", -+ .num_leds = 1, -+ .cki = 11, -+ .sdi = 12, -+ .lei = -1, -+ .ndelay = 500, -+ .init_brightness = { -+ LED_OFF, -+ LED_OFF, -+ LED_OFF, -+ }, -+ .default_trigger = "none", -+ .led_colors = { "red", "green", "blue" }, -+}; -+ -+static struct led_nu801_platform_data tricolor_led_data = { -+ .num_controllers = 1, -+ .template = &tricolor_led_template, -+}; -+ -+static struct platform_device tricolor_leds = { -+ .name = "leds-nu801", -+ .id = -1, -+ .dev.platform_data = &tricolor_led_data, -+}; -+ -+static int mr18_extract_sgmii_res_cal(void) -+{ -+ void __iomem *base; -+ unsigned int reversed_sgmii_value; -+ -+ unsigned int otp_value, otp_per_val, rbias_per, read_data; -+ unsigned int rbias_pos_or_neg; -+ unsigned int sgmii_res_cal_value; -+ int res_cal_val; -+ -+ base = ioremap_nocache(MR18_OTP_BASE, MR18_OTP_SIZE); -+ if (!base) -+ return -EIO; -+ -+ __raw_writel(0x7d, base + MR18_OTP_INTF2_REG); -+ __raw_writel(0x00, base + MR18_OTP_LDO_CTRL_REG); -+ -+ while (__raw_readl(base + MR18_OTP_LDO_STATUS_REG) & -+ MR18_OTP_LDO_STATUS_POWER_ON); -+ -+ __raw_readl(base + MR18_OTP_MEM_0_REG + 4); -+ -+ while (!(__raw_readl(base + MR18_OTP_STATUS0_REG) & -+ MR18_OTP_STATUS0_EFUSE_VALID)); -+ -+ read_data = __raw_readl(base + MR18_OTP_STATUS1_REG); -+ -+ iounmap(base); -+ -+ if (!(read_data & 0x1fff)) -+ return -ENODEV; -+ -+ if (read_data & 0x00001000) -+ otp_value = (read_data & 0xfc0) >> 6; -+ else -+ otp_value = read_data & 0x3f; -+ -+ if (otp_value > 31) { -+ otp_per_val = 63 - otp_value; -+ rbias_pos_or_neg = 1; -+ } else { -+ otp_per_val = otp_value; -+ rbias_pos_or_neg = 0; -+ } -+ -+ rbias_per = otp_per_val * 15; -+ -+ if (rbias_pos_or_neg == 1) -+ res_cal_val = (rbias_per + 34) / 21; -+ else if (rbias_per > 34) -+ res_cal_val = -((rbias_per - 34) / 21); -+ else -+ res_cal_val = (34 - rbias_per) / 21; -+ -+ sgmii_res_cal_value = (8 + res_cal_val) & 0xf; -+ -+ reversed_sgmii_value = (sgmii_res_cal_value & 8) >> 3; -+ reversed_sgmii_value |= (sgmii_res_cal_value & 4) >> 1; -+ reversed_sgmii_value |= (sgmii_res_cal_value & 2) << 1; -+ reversed_sgmii_value |= (sgmii_res_cal_value & 1) << 3; -+ printk(KERN_INFO "SGMII cal value = 0x%x\n", reversed_sgmii_value); -+ return reversed_sgmii_value; -+} -+ -+static void mr18_setup_qca955x_eth_serdes_cal(unsigned int sgmii_value) -+{ -+ void __iomem *ethbase, *pllbase; -+ u32 t; -+ -+ ethbase = ioremap_nocache(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE); -+ pllbase = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); -+ -+ /* To Check the locking of the SGMII PLL */ -+ t = __raw_readl(ethbase + QCA955X_GMAC_REG_SGMII_SERDES); -+ t &= ~(QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK << -+ QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT); -+ t |= (sgmii_value & QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK) << -+ QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT; -+ __raw_writel(t, ethbase + QCA955X_GMAC_REG_SGMII_SERDES); -+ -+ __raw_writel(QCA955X_PLL_ETH_SGMII_SERDES_LOCK_DETECT | -+ QCA955X_PLL_ETH_SGMII_SERDES_PLL_REFCLK | -+ QCA955X_PLL_ETH_SGMII_SERDES_EN_PLL, -+ pllbase + QCA955X_PLL_ETH_SGMII_SERDES_REG); -+ -+ ath79_device_reset_clear(QCA955X_RESET_SGMII_ANALOG); -+ ath79_device_reset_clear(QCA955X_RESET_SGMII); -+ -+ while (!(__raw_readl(ethbase + QCA955X_GMAC_REG_SGMII_SERDES) & -+ QCA955X_SGMII_SERDES_LOCK_DETECT_STATUS)); -+ -+ iounmap(ethbase); -+ iounmap(pllbase); -+} -+ -+static struct ath9k_platform_data pci_main_wifi_data = { -+ .led_pin = -1, -+}; -+static struct ath9k_platform_data pci_scan_wifi_data = { -+ .led_pin = -1, -+}; -+ -+static int mr18_dual_pci_plat_dev_init(struct pci_dev *dev) -+{ -+ /* The PCIE devices are attached to different busses but they -+ * both share the same slot number. Checking the PCI_SLOT vals -+ * does not work. -+ */ -+ switch (dev->bus->number) { -+ case 0: -+ dev->dev.platform_data = &pci_main_wifi_data; -+ break; -+ case 1: -+ dev->dev.platform_data = &pci_scan_wifi_data; -+ break; -+ } -+ -+ return 0; -+} -+ -+static void __init mr18_setup(void) -+{ -+ int res; -+ -+ /* NAND */ -+ ath79_nfc_set_ecc_mode(AR934X_NFC_ECC_SOFT_BCH); -+ ath79_register_nfc(); -+ -+ /* even though, the PHY is connected via RGMII, -+ * the SGMII/SERDES PLLs need to be calibrated and locked. -+ * Or else, the PHY won't be working for this platfrom. -+ * -+ * Figuring this out took such a long time, that we want to -+ * point this quirk out, before someone wants to remove it. -+ */ -+ res = mr18_extract_sgmii_res_cal(); -+ if (res >= 0) { -+ /* Setup SoC Eth Config */ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN | -+ (3 << QCA955X_ETH_CFG_RXD_DELAY_SHIFT) | -+ (3 << QCA955X_ETH_CFG_RDV_DELAY_SHIFT)); -+ -+ /* MDIO Interface */ -+ ath79_register_mdio(0, 0x0); -+ -+ mr18_setup_qca955x_eth_serdes_cal(res); -+ -+ /* GMAC0 is connected to an Atheros AR8035-A */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, NULL, 0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(MR18_WAN_PHYADDR); -+ ath79_eth0_pll_data.pll_1000 = 0xa6000000; -+ ath79_eth0_pll_data.pll_100 = 0xa0000101; -+ ath79_eth0_pll_data.pll_10 = 0x80001313; -+ ath79_register_eth(0); -+ } else { -+ printk(KERN_ERR "failed to read EFUSE for ethernet cal\n"); -+ } -+ -+ /* LEDs and Buttons */ -+ platform_device_register(&tricolor_leds); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(MR18_leds_gpio), -+ MR18_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, MR18_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(MR18_gpio_keys), -+ MR18_gpio_keys); -+ -+ /* Clear RTC reset (Needed by SoC WiFi) */ -+ ath79_device_reset_clear(QCA955X_RESET_RTC); -+ -+ /* WiFi */ -+ ath79_register_wmac_simple(); -+ -+ pci_main_wifi_data.eeprom_name = "pci_wmac0.eeprom"; -+ pci_scan_wifi_data.eeprom_name = "pci_wmac1.eeprom"; -+ ath79_pci_set_plat_dev_init(mr18_dual_pci_plat_dev_init); -+ ath79_register_pci(); -+} -+MIPS_MACHINE(ATH79_MACH_MR18, "MR18", "Meraki MR18", mr18_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-mr600.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr600.c -new file mode 100644 -index 0000000000..701330cebd ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr600.c -@@ -0,0 +1,177 @@ -+/* -+ * OpenMesh OM2P board support -+ * -+ * Copyright (C) 2012 Marek Lindner -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define MR600_GPIO_LED_WLAN58 12 -+#define MR600_GPIO_LED_WPS 13 -+#define MR600_GPIO_LED_POWER 14 -+ -+#define MR600V2_GPIO_LED_WLAN58_RED 12 -+#define MR600V2_GPIO_LED_WPS 13 -+#define MR600V2_GPIO_LED_POWER 14 -+#define MR600V2_GPIO_LED_WLAN24_GREEN 18 -+#define MR600V2_GPIO_LED_WLAN24_YELLOW 19 -+#define MR600V2_GPIO_LED_WLAN24_RED 20 -+#define MR600V2_GPIO_LED_WLAN58_GREEN 21 -+#define MR600V2_GPIO_LED_WLAN58_YELLOW 22 -+ -+#define MR600_GPIO_BTN_RESET 17 -+ -+#define MR600_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define MR600_KEYS_DEBOUNCE_INTERVAL (3 * MR600_KEYS_POLL_INTERVAL) -+ -+#define MR600_MAC_OFFSET 0 -+#define MR600_WMAC_CALDATA_OFFSET 0x1000 -+#define MR600_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led mr600_leds_gpio[] __initdata = { -+ { -+ .name = "mr600:orange:power", -+ .gpio = MR600_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr600:blue:wps", -+ .gpio = MR600_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr600:green:wlan58", -+ .gpio = MR600_GPIO_LED_WLAN58, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led mr600v2_leds_gpio[] __initdata = { -+ { -+ .name = "mr600:blue:power", -+ .gpio = MR600V2_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr600:blue:wps", -+ .gpio = MR600V2_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr600:red:wlan24", -+ .gpio = MR600V2_GPIO_LED_WLAN24_RED, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr600:yellow:wlan24", -+ .gpio = MR600V2_GPIO_LED_WLAN24_YELLOW, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr600:green:wlan24", -+ .gpio = MR600V2_GPIO_LED_WLAN24_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr600:red:wlan58", -+ .gpio = MR600V2_GPIO_LED_WLAN58_RED, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr600:yellow:wlan58", -+ .gpio = MR600V2_GPIO_LED_WLAN58_YELLOW, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr600:green:wlan58", -+ .gpio = MR600V2_GPIO_LED_WLAN58_GREEN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button mr600_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = MR600_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MR600_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init mr600_base_setup(unsigned num_leds, struct gpio_led *leds) -+{ -+ u8 *art = (u8 *)KSEG1ADDR(0x1fff0000); -+ u8 mac[6]; -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, num_leds, leds); -+ ath79_register_gpio_keys_polled(-1, MR600_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(mr600_gpio_keys), -+ mr600_gpio_keys); -+ -+ ath79_init_mac(mac, art + MR600_MAC_OFFSET, 1); -+ ath79_register_wmac(art + MR600_WMAC_CALDATA_OFFSET, mac); -+ -+ ath79_init_mac(mac, art + MR600_MAC_OFFSET, 8); -+ ap91_pci_init(art + MR600_PCIE_CALDATA_OFFSET, mac); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + MR600_MAC_OFFSET, 0); -+ -+ /* GMAC0 is connected to an external PHY */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_register_eth(0); -+} -+ -+static void __init mr600_setup(void) -+{ -+ mr600_base_setup(ARRAY_SIZE(mr600_leds_gpio), mr600_leds_gpio); -+ ap9x_pci_setup_wmac_led_pin(0, 0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_MR600, "MR600", "OpenMesh MR600", mr600_setup); -+ -+static void __init mr600v2_setup(void) -+{ -+ mr600_base_setup(ARRAY_SIZE(mr600v2_leds_gpio), mr600v2_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_MR600V2, "MR600v2", "OpenMesh MR600v2", mr600v2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-mr900.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr900.c -new file mode 100644 -index 0000000000..6b83c4cdf4 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr900.c -@@ -0,0 +1,181 @@ -+/* -+ * MR900 board support -+ * -+ * Copyright (c) 2012 Qualcomm Atheros -+ * Copyright (c) 2012-2013 Marek Lindner -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define MR900_GPIO_LED_LAN 12 -+#define MR900_GPIO_LED_WLAN_2G 13 -+#define MR900_GPIO_LED_STATUS_GREEN 19 -+#define MR900_GPIO_LED_STATUS_RED 21 -+#define MR900_GPIO_LED_POWER 22 -+#define MR900_GPIO_LED_WLAN_5G 23 -+ -+#define MR900_GPIO_BTN_RESET 17 -+ -+#define MR900_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define MR900_KEYS_DEBOUNCE_INTERVAL (3 * MR900_KEYS_POLL_INTERVAL) -+ -+#define MR900_MAC0_OFFSET 0 -+#define MR900_WMAC_CALDATA_OFFSET 0x1000 -+#define MR900_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led mr900_leds_gpio[] __initdata = { -+ { -+ .name = "mr900:blue:power", -+ .gpio = MR900_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr900:blue:wan", -+ .gpio = MR900_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr900:blue:wlan24", -+ .gpio = MR900_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr900:blue:wlan58", -+ .gpio = MR900_GPIO_LED_WLAN_5G, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr900:green:status", -+ .gpio = MR900_GPIO_LED_STATUS_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "mr900:red:status", -+ .gpio = MR900_GPIO_LED_STATUS_RED, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button mr900_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = MR900_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MR900_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct at803x_platform_data mr900_at803x_data = { -+ .disable_smarteee = 1, -+ .enable_rgmii_rx_delay = 1, -+ .enable_rgmii_tx_delay = 0, -+ .fixup_rgmii_tx_delay = 1, -+}; -+ -+static struct mdio_board_info mr900_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 5, -+ .platform_data = &mr900_at803x_data, -+ }, -+}; -+ -+static void __init mr900_setup_qca955x_eth_cfg(u32 mask, -+ unsigned int rxd, -+ unsigned int rxdv, -+ unsigned int txd, -+ unsigned int txe) -+{ -+ void __iomem *base; -+ u32 t; -+ -+ base = ioremap(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE); -+ -+ t = mask; -+ t |= rxd << QCA955X_ETH_CFG_RXD_DELAY_SHIFT; -+ t |= rxdv << QCA955X_ETH_CFG_RDV_DELAY_SHIFT; -+ t |= txd << QCA955X_ETH_CFG_TXD_DELAY_SHIFT; -+ t |= txe << QCA955X_ETH_CFG_TXE_DELAY_SHIFT; -+ -+ __raw_writel(t, base + QCA955X_GMAC_REG_ETH_CFG); -+ -+ iounmap(base); -+} -+ -+static void __init mr900_setup(void) -+{ -+ u8 *art = (u8 *)KSEG1ADDR(0x1fff0000); -+ u8 mac[6], pcie_mac[6]; -+ struct ath9k_platform_data *pdata; -+ -+ ath79_eth0_pll_data.pll_1000 = 0xae000000; -+ ath79_eth0_pll_data.pll_100 = 0xa0000101; -+ ath79_eth0_pll_data.pll_10 = 0xa0001313; -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(mr900_leds_gpio), -+ mr900_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, MR900_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(mr900_gpio_keys), -+ mr900_gpio_keys); -+ -+ ath79_init_mac(mac, art + MR900_MAC0_OFFSET, 1); -+ ath79_register_wmac(art + MR900_WMAC_CALDATA_OFFSET, mac); -+ ath79_init_mac(pcie_mac, art + MR900_MAC0_OFFSET, 16); -+ ap91_pci_init(art + MR900_PCIE_CALDATA_OFFSET, pcie_mac); -+ pdata = ap9x_pci_get_wmac_data(0); -+ if (!pdata) { -+ pr_err("mr900: unable to get address of wlan data\n"); -+ return; -+ } -+ pdata->use_eeprom = true; -+ -+ mr900_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN, 3, 3, 0, 0); -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(mr900_mdio0_info, -+ ARRAY_SIZE(mr900_mdio0_info)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + MR900_MAC0_OFFSET, 0); -+ -+ /* GMAC0 is connected to the RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(5); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_MR900, "MR900", "OpenMesh MR900", mr900_setup); -+MIPS_MACHINE(ATH79_MACH_MR900v2, "MR900v2", "OpenMesh MR900v2", mr900_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-mynet-n600.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-mynet-n600.c -new file mode 100644 -index 0000000000..a87413d201 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-mynet-n600.c -@@ -0,0 +1,202 @@ -+/* -+ * WD My Net N600 board support -+ * -+ * Copyright (C) 2013 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "nvram.h" -+ -+#define MYNET_N600_GPIO_LED_WIFI 0 -+#define MYNET_N600_GPIO_LED_POWER 11 -+#define MYNET_N600_GPIO_LED_INTERNET 12 -+#define MYNET_N600_GPIO_LED_WPS 13 -+ -+#define MYNET_N600_GPIO_LED_LAN1 4 -+#define MYNET_N600_GPIO_LED_LAN2 3 -+#define MYNET_N600_GPIO_LED_LAN3 2 -+#define MYNET_N600_GPIO_LED_LAN4 1 -+ -+#define MYNET_N600_GPIO_BTN_RESET 16 -+#define MYNET_N600_GPIO_BTN_WPS 17 -+ -+#define MYNET_N600_GPIO_EXTERNAL_LNA0 14 -+#define MYNET_N600_GPIO_EXTERNAL_LNA1 15 -+ -+#define MYNET_N600_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define MYNET_N600_KEYS_DEBOUNCE_INTERVAL (3 * MYNET_N600_KEYS_POLL_INTERVAL) -+ -+#define MYNET_N600_MAC0_OFFSET 0 -+#define MYNET_N600_MAC1_OFFSET 6 -+#define MYNET_N600_WMAC_CALDATA_OFFSET 0x1000 -+#define MYNET_N600_PCIE_CALDATA_OFFSET 0x5000 -+ -+#define MYNET_N600_NVRAM_ADDR 0x1f058010 -+#define MYNET_N600_NVRAM_SIZE 0x7ff0 -+ -+static struct gpio_led mynet_n600_leds_gpio[] __initdata = { -+ { -+ .name = "wd:blue:power", -+ .gpio = MYNET_N600_GPIO_LED_POWER, -+ .active_low = 0, -+ }, -+ { -+ .name = "wd:blue:wps", -+ .gpio = MYNET_N600_GPIO_LED_WPS, -+ .active_low = 0, -+ }, -+ { -+ .name = "wd:blue:wireless", -+ .gpio = MYNET_N600_GPIO_LED_WIFI, -+ .active_low = 0, -+ }, -+ { -+ .name = "wd:blue:internet", -+ .gpio = MYNET_N600_GPIO_LED_INTERNET, -+ .active_low = 0, -+ }, -+ { -+ .name = "wd:green:lan1", -+ .gpio = MYNET_N600_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, -+ { -+ .name = "wd:green:lan2", -+ .gpio = MYNET_N600_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, -+ { -+ .name = "wd:green:lan3", -+ .gpio = MYNET_N600_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, -+ { -+ .name = "wd:green:lan4", -+ .gpio = MYNET_N600_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button mynet_n600_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = MYNET_N600_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MYNET_N600_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = MYNET_N600_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MYNET_N600_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static void mynet_n600_get_mac(const char *name, char *mac) -+{ -+ u8 *nvram = (u8 *) KSEG1ADDR(MYNET_N600_NVRAM_ADDR); -+ int err; -+ -+ err = ath79_nvram_parse_mac_addr(nvram, MYNET_N600_NVRAM_SIZE, -+ name, mac); -+ if (err) -+ pr_err("no MAC address found for %s\n", name); -+} -+ -+#define MYNET_N600_WAN_PHY_MASK BIT(0) -+ -+static void __init mynet_n600_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 tmpmac[ETH_ALEN]; -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_gpio_output_select(MYNET_N600_GPIO_LED_LAN1, -+ AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(MYNET_N600_GPIO_LED_LAN2, -+ AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(MYNET_N600_GPIO_LED_LAN3, -+ AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(MYNET_N600_GPIO_LED_LAN4, -+ AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(MYNET_N600_GPIO_LED_INTERNET, -+ AR934X_GPIO_OUT_GPIO); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(mynet_n600_leds_gpio), -+ mynet_n600_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, MYNET_N600_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(mynet_n600_gpio_keys), -+ mynet_n600_gpio_keys); -+ -+ /* -+ * Control signal for external LNAs 0 and 1 -+ * Taken from GPL bootloader source: -+ * board/ar7240/db12x/alpha_gpio.c -+ */ -+ ath79_wmac_set_ext_lna_gpio(0, MYNET_N600_GPIO_EXTERNAL_LNA0); -+ ath79_wmac_set_ext_lna_gpio(1, MYNET_N600_GPIO_EXTERNAL_LNA1); -+ -+ mynet_n600_get_mac("wlan24mac=", tmpmac); -+ ath79_register_wmac(art + MYNET_N600_WMAC_CALDATA_OFFSET, tmpmac); -+ -+ mynet_n600_get_mac("wlan5mac=", tmpmac); -+ ap91_pci_init(art + MYNET_N600_PCIE_CALDATA_OFFSET, tmpmac); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_ONLY_MODE | -+ AR934X_ETH_CFG_SW_PHY_SWAP); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ /* LAN */ -+ mynet_n600_get_mac("lanmac=", ath79_eth1_data.mac_addr); -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ mynet_n600_get_mac("wanmac=", ath79_eth0_data.mac_addr); -+ -+ /* GMAC0 is connected to the PHY4 of the internal switch */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = MYNET_N600_WAN_PHY_MASK; -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = MYNET_N600_WAN_PHY_MASK; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ -+ ath79_register_eth(0); -+ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_MYNET_N600, "MYNET-N600", "WD My Net N600", -+ mynet_n600_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-mynet-n750.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-mynet-n750.c -new file mode 100644 -index 0000000000..a822b6c3e2 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-mynet-n750.c -@@ -0,0 +1,226 @@ -+/* -+ * WD My Net N750 board support -+ * -+ * Copyright (C) 2013 Felix Kaechele -+ * Copyright (C) 2013 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "nvram.h" -+ -+ -+/* -+ * Taken from GPL bootloader source: -+ * board/ar7240/db12x/alpha_gpio.c -+ */ -+#define MYNET_N750_GPIO_LED_WIFI 11 -+#define MYNET_N750_GPIO_LED_INTERNET 12 -+#define MYNET_N750_GPIO_LED_WPS 13 -+#define MYNET_N750_GPIO_LED_POWER 14 -+ -+#define MYNET_N750_GPIO_BTN_RESET 17 -+#define MYNET_N750_GPIO_BTN_WPS 19 -+ -+#define MYNET_N750_GPIO_EXTERNAL_LNA0 15 -+#define MYNET_N750_GPIO_EXTERNAL_LNA1 18 -+ -+#define MYNET_N750_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define MYNET_N750_KEYS_DEBOUNCE_INTERVAL (3 * MYNET_N750_KEYS_POLL_INTERVAL) -+ -+#define MYNET_N750_WMAC_CALDATA_OFFSET 0x1000 -+#define MYNET_N750_PCIE_CALDATA_OFFSET 0x5000 -+ -+#define MYNET_N750_NVRAM_ADDR 0x1f058010 -+#define MYNET_N750_NVRAM_SIZE 0x7ff0 -+ -+static struct gpio_led mynet_n750_leds_gpio[] __initdata = { -+ { -+ .name = "wd:blue:power", -+ .gpio = MYNET_N750_GPIO_LED_POWER, -+ .active_low = 0, -+ }, -+ { -+ .name = "wd:blue:wps", -+ .gpio = MYNET_N750_GPIO_LED_WPS, -+ .active_low = 0, -+ }, -+ { -+ .name = "wd:blue:wireless", -+ .gpio = MYNET_N750_GPIO_LED_WIFI, -+ .active_low = 0, -+ }, -+ { -+ .name = "wd:blue:internet", -+ .gpio = MYNET_N750_GPIO_LED_INTERNET, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button mynet_n750_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = MYNET_N750_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MYNET_N750_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = MYNET_N750_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MYNET_N750_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static const struct ar8327_led_info mynet_n750_leds_ar8327[] = { -+ AR8327_LED_INFO(PHY0_0, HW, "wd:green:lan1"), -+ AR8327_LED_INFO(PHY1_0, HW, "wd:green:lan2"), -+ AR8327_LED_INFO(PHY2_0, HW, "wd:green:lan3"), -+ AR8327_LED_INFO(PHY3_0, HW, "wd:green:lan4"), -+ AR8327_LED_INFO(PHY4_0, HW, "wd:green:wan"), -+ AR8327_LED_INFO(PHY0_1, HW, "wd:yellow:lan1"), -+ AR8327_LED_INFO(PHY1_1, HW, "wd:yellow:lan2"), -+ AR8327_LED_INFO(PHY2_1, HW, "wd:yellow:lan3"), -+ AR8327_LED_INFO(PHY3_1, HW, "wd:yellow:lan4"), -+ AR8327_LED_INFO(PHY4_1, HW, "wd:yellow:wan"), -+}; -+ -+static struct ar8327_pad_cfg mynet_n750_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_led_cfg mynet_n750_ar8327_led_cfg = { -+ .led_ctrl0 = 0xcc35cc35, -+ .led_ctrl1 = 0xca35ca35, -+ .led_ctrl2 = 0xc935c935, -+ .led_ctrl3 = 0x03ffff00, -+ .open_drain = false, -+}; -+ -+static struct ar8327_platform_data mynet_n750_ar8327_data = { -+ .pad0_cfg = &mynet_n750_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &mynet_n750_ar8327_led_cfg, -+ .num_leds = ARRAY_SIZE(mynet_n750_leds_ar8327), -+ .leds = mynet_n750_leds_ar8327, -+}; -+ -+static struct mdio_board_info mynet_n750_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &mynet_n750_ar8327_data, -+ }, -+}; -+ -+static void mynet_n750_get_mac(const char *name, char *mac) -+{ -+ u8 *nvram = (u8 *) KSEG1ADDR(MYNET_N750_NVRAM_ADDR); -+ int err; -+ -+ err = ath79_nvram_parse_mac_addr(nvram, MYNET_N750_NVRAM_SIZE, -+ name, mac); -+ if (err) -+ pr_err("no MAC address found for %s\n", name); -+} -+ -+/* -+ * The bootloader on this board powers down all PHYs on the switch -+ * before booting the kernel. We bring all PHYs back up so that they are -+ * discoverable by the mdio bus scan and the switch is detected -+ * correctly. -+ */ -+static void mynet_n750_mdio_fixup(struct mii_bus *bus) -+{ -+ int i; -+ -+ for (i = 0; i < 5; i++) -+ bus->write(bus, i, MII_BMCR, -+ (BMCR_RESET | BMCR_ANENABLE | BMCR_SPEED1000)); -+ -+ mdelay(1000); -+} -+ -+static void __init mynet_n750_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 tmpmac[ETH_ALEN]; -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(mynet_n750_leds_gpio), -+ mynet_n750_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, MYNET_N750_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(mynet_n750_gpio_keys), -+ mynet_n750_gpio_keys); -+ /* -+ * Control signal for external LNAs 0 and 1 -+ * Taken from GPL bootloader source: -+ * board/ar7240/db12x/alpha_gpio.c -+ */ -+ ath79_wmac_set_ext_lna_gpio(0, MYNET_N750_GPIO_EXTERNAL_LNA0); -+ ath79_wmac_set_ext_lna_gpio(1, MYNET_N750_GPIO_EXTERNAL_LNA1); -+ -+ mynet_n750_get_mac("wlan24mac=", tmpmac); -+ ath79_register_wmac(art + MYNET_N750_WMAC_CALDATA_OFFSET, tmpmac); -+ -+ mynet_n750_get_mac("wlan5mac=", tmpmac); -+ ap91_pci_init(art + MYNET_N750_PCIE_CALDATA_OFFSET, tmpmac); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0); -+ -+ mdiobus_register_board_info(mynet_n750_mdio0_info, -+ ARRAY_SIZE(mynet_n750_mdio0_info)); -+ -+ ath79_mdio0_data.reset = mynet_n750_mdio_fixup; -+ ath79_register_mdio(0, 0x0); -+ -+ mynet_n750_get_mac("lanmac=", ath79_eth0_data.mac_addr); -+ -+ /* GMAC0 is connected to an AR8327N switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_register_eth(0); -+ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_MYNET_N750, "MYNET-N750", "WD My Net N750", -+ mynet_n750_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-mynet-rext.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-mynet-rext.c -new file mode 100644 -index 0000000000..cfb075b681 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-mynet-rext.c -@@ -0,0 +1,208 @@ -+/* -+ * WD My Net WI-FI Range Extender (Codename:Starfish db12x) board support -+ * -+ * Copyright (C) 2013 Christian Lamparter -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "nvram.h" -+ -+#define MYNET_REXT_GPIO_LED_POWER 11 -+#define MYNET_REXT_GPIO_LED_ETHERNET 12 -+#define MYNET_REXT_GPIO_LED_WIFI 19 -+ -+#define MYNET_REXT_GPIO_LED_RF_QTY1 20 -+#define MYNET_REXT_GPIO_LED_RF_QTY2 21 -+#define MYNET_REXT_GPIO_LED_RF_QTY3 22 -+ -+#define MYNET_REXT_GPIO_BTN_RESET 13 -+#define MYNET_REXT_GPIO_BTN_WPS 15 -+#define MYNET_REXT_GPIO_SW_RF 14 -+ -+#define MYNET_REXT_GPIO_PHY_SWRST 16 /* disables Ethernet PHY */ -+#define MYNET_REXT_GPIO_PHY_INT 17 -+#define MYNET_REXT_GPIO_18 18 -+ -+#define MYNET_REXT_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define MYNET_REXT_KEYS_DEBOUNCE_INTERVAL (3 * MYNET_REXT_KEYS_POLL_INTERVAL) -+ -+#define MYNET_REXT_WMAC_CALDATA_OFFSET 0x1000 -+ -+#define MYNET_REXT_NVRAM_ADDR 0x1f7e0010 -+#define MYNET_REXT_NVRAM_SIZE 0xfff0 -+ -+#define MYNET_REXT_ART_ADDR 0x1f7f0000 -+ -+static const char *mynet_rext_part_probes[] = { -+ "cybertan", -+ NULL, -+}; -+ -+static struct flash_platform_data mynet_rext_flash_data = { -+ .type = "s25fl064k", -+ .part_probes = mynet_rext_part_probes, -+}; -+ -+static struct gpio_led mynet_rext_leds_gpio[] __initdata = { -+ { -+ .name = "wd:blue:power", -+ .gpio = MYNET_REXT_GPIO_LED_POWER, -+ .active_low = 0, -+ }, -+ { -+ .name = "wd:blue:wireless", -+ .gpio = MYNET_REXT_GPIO_LED_WIFI, -+ .active_low = 1, -+ }, -+ { -+ .name = "wd:blue:ethernet", -+ .gpio = MYNET_REXT_GPIO_LED_ETHERNET, -+ .active_low = 1, -+ }, -+ { -+ .name = "wd:blue:quality1", -+ .gpio = MYNET_REXT_GPIO_LED_RF_QTY1, -+ .active_low = 1, -+ }, -+ { -+ .name = "wd:blue:quality2", -+ .gpio = MYNET_REXT_GPIO_LED_RF_QTY2, -+ .active_low = 1, -+ }, -+ { -+ .name = "wd:blue:quality3", -+ .gpio = MYNET_REXT_GPIO_LED_RF_QTY3, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button mynet_rext_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = MYNET_REXT_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MYNET_REXT_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = MYNET_REXT_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MYNET_REXT_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+ { -+ .desc = "RF Band switch", -+ .type = EV_SW, -+ .code = BTN_1, -+ .debounce_interval = MYNET_REXT_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MYNET_REXT_GPIO_SW_RF, -+ }, -+}; -+ -+static struct at803x_platform_data mynet_rext_at803x_data = { -+ .disable_smarteee = 0, -+ .enable_rgmii_rx_delay = 1, -+ .enable_rgmii_tx_delay = 0, -+ .fixup_rgmii_tx_delay = 1, -+}; -+ -+static struct mdio_board_info mynet_rext_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 4, -+ .platform_data = &mynet_rext_at803x_data, -+ }, -+}; -+ -+static void mynet_rext_get_mac(const char *name, char *mac) -+{ -+ u8 *nvram = (u8 *) KSEG1ADDR(MYNET_REXT_NVRAM_ADDR); -+ int err; -+ -+ err = ath79_nvram_parse_mac_addr(nvram, MYNET_REXT_NVRAM_SIZE, -+ name, mac); -+ if (err) -+ pr_err("no MAC address found for %s\n", name); -+} -+ -+static void __init mynet_rext_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(MYNET_REXT_ART_ADDR); -+ u8 tmpmac[ETH_ALEN]; -+ -+ ath79_register_m25p80(&mynet_rext_flash_data); -+ -+ /* GPIO configuration from drivers/char/GPIO8.c */ -+ -+ ath79_gpio_output_select(MYNET_REXT_GPIO_LED_POWER, -+ AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(MYNET_REXT_GPIO_LED_WIFI, -+ AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(MYNET_REXT_GPIO_LED_RF_QTY1, -+ AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(MYNET_REXT_GPIO_LED_RF_QTY2, -+ AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(MYNET_REXT_GPIO_LED_RF_QTY3, -+ AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(MYNET_REXT_GPIO_LED_ETHERNET, -+ AR934X_GPIO_OUT_GPIO); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(mynet_rext_leds_gpio), -+ mynet_rext_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, MYNET_REXT_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(mynet_rext_gpio_keys), -+ mynet_rext_gpio_keys); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_RXD_DELAY | -+ AR934X_ETH_CFG_RDV_DELAY); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(mynet_rext_mdio0_info, -+ ARRAY_SIZE(mynet_rext_mdio0_info)); -+ -+ /* LAN */ -+ mynet_rext_get_mac("et0macaddr=", ath79_eth0_data.mac_addr); -+ -+ /* GMAC0 is connected to an external PHY on Port 4 */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_pll_data.pll_10 = 0x00001313; /* athrs_mac.c */ -+ ath79_eth0_pll_data.pll_1000 = 0x0e000000; /* athrs_mac.c */ -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_register_eth(0); -+ -+ /* WLAN */ -+ mynet_rext_get_mac("wl0_hwaddr=", tmpmac); -+ ap91_pci_init(art + MYNET_REXT_WMAC_CALDATA_OFFSET, tmpmac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_MYNET_REXT, "MYNET-REXT", -+ "WD My Net Wi-Fi Range Extender", mynet_rext_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-mzk-w04nu.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-mzk-w04nu.c -new file mode 100644 -index 0000000000..c2460ce33c ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-mzk-w04nu.c -@@ -0,0 +1,124 @@ -+/* -+ * Planex MZK-W04NU board support -+ * -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define MZK_W04NU_GPIO_LED_USB 0 -+#define MZK_W04NU_GPIO_LED_STATUS 1 -+#define MZK_W04NU_GPIO_LED_WPS 3 -+#define MZK_W04NU_GPIO_LED_WLAN 6 -+#define MZK_W04NU_GPIO_LED_AP 15 -+#define MZK_W04NU_GPIO_LED_ROUTER 16 -+ -+#define MZK_W04NU_GPIO_BTN_APROUTER 5 -+#define MZK_W04NU_GPIO_BTN_WPS 12 -+#define MZK_W04NU_GPIO_BTN_RESET 21 -+ -+#define MZK_W04NU_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define MZK_W04NU_KEYS_DEBOUNCE_INTERVAL (3 * MZK_W04NU_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led mzk_w04nu_leds_gpio[] __initdata = { -+ { -+ .name = "planex:green:status", -+ .gpio = MZK_W04NU_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "planex:blue:wps", -+ .gpio = MZK_W04NU_GPIO_LED_WPS, -+ .active_low = 1, -+ }, { -+ .name = "planex:green:wlan", -+ .gpio = MZK_W04NU_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "planex:green:usb", -+ .gpio = MZK_W04NU_GPIO_LED_USB, -+ .active_low = 1, -+ }, { -+ .name = "planex:green:ap", -+ .gpio = MZK_W04NU_GPIO_LED_AP, -+ .active_low = 1, -+ }, { -+ .name = "planex:green:router", -+ .gpio = MZK_W04NU_GPIO_LED_ROUTER, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button mzk_w04nu_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MZK_W04NU_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MZK_W04NU_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, { -+ .desc = "aprouter", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MZK_W04NU_GPIO_BTN_APROUTER, -+ .active_low = 0, -+ } -+}; -+ -+#define MZK_W04NU_WAN_PHYMASK BIT(4) -+#define MZK_W04NU_MDIO_MASK (~MZK_W04NU_WAN_PHYMASK) -+ -+static void __init mzk_w04nu_setup(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_mdio(0, MZK_W04NU_MDIO_MASK); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, eeprom, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.has_ar8216 = 1; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, eeprom, 1); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth1_data.phy_mask = MZK_W04NU_WAN_PHYMASK; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(mzk_w04nu_leds_gpio), -+ mzk_w04nu_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, MZK_W04NU_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(mzk_w04nu_gpio_keys), -+ mzk_w04nu_gpio_keys); -+ ath79_register_usb(); -+ -+ ath79_register_wmac(eeprom, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_MZK_W04NU, "MZK-W04NU", "Planex MZK-W04NU", -+ mzk_w04nu_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-mzk-w300nh.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-mzk-w300nh.c -new file mode 100644 -index 0000000000..8c40365283 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-mzk-w300nh.c -@@ -0,0 +1,115 @@ -+/* -+ * Planex MZK-W300NH board support -+ * -+ * Copyright (C) 2008-2012 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define MZK_W300NH_GPIO_LED_STATUS 1 -+#define MZK_W300NH_GPIO_LED_WPS 3 -+#define MZK_W300NH_GPIO_LED_WLAN 6 -+#define MZK_W300NH_GPIO_LED_AP_GREEN 15 -+#define MZK_W300NH_GPIO_LED_AP_AMBER 16 -+ -+#define MZK_W300NH_GPIO_BTN_APROUTER 5 -+#define MZK_W300NH_GPIO_BTN_WPS 12 -+#define MZK_W300NH_GPIO_BTN_RESET 21 -+ -+#define MZK_W300NH_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define MZK_W300NH_KEYS_DEBOUNCE_INTERVAL (3 * MZK_W300NH_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led mzk_w300nh_leds_gpio[] __initdata = { -+ { -+ .name = "planex:green:status", -+ .gpio = MZK_W300NH_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "planex:blue:wps", -+ .gpio = MZK_W300NH_GPIO_LED_WPS, -+ .active_low = 1, -+ }, { -+ .name = "planex:green:wlan", -+ .gpio = MZK_W300NH_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "planex:green:aprouter", -+ .gpio = MZK_W300NH_GPIO_LED_AP_GREEN, -+ }, { -+ .name = "planex:amber:aprouter", -+ .gpio = MZK_W300NH_GPIO_LED_AP_AMBER, -+ } -+}; -+ -+static struct gpio_keys_button mzk_w300nh_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MZK_W300NH_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MZK_W300NH_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, { -+ .desc = "aprouter", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = MZK_W300NH_GPIO_BTN_APROUTER, -+ .active_low = 0, -+ } -+}; -+ -+#define MZK_W300NH_WAN_PHYMASK BIT(4) -+#define MZK_W300NH_MDIO_MASK (~MZK_W300NH_WAN_PHYMASK) -+ -+static void __init mzk_w300nh_setup(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_mdio(0, MZK_W300NH_MDIO_MASK); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, eeprom, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.has_ar8216 = 1; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, eeprom, 1); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth1_data.phy_mask = MZK_W300NH_WAN_PHYMASK; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(mzk_w300nh_leds_gpio), -+ mzk_w300nh_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, MZK_W300NH_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(mzk_w300nh_gpio_keys), -+ mzk_w300nh_gpio_keys); -+ ath79_register_wmac(eeprom, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_MZK_W300NH, "MZK-W300NH", "Planex MZK-W300NH", -+ mzk_w300nh_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-n5q.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-n5q.c -new file mode 100644 -index 0000000000..895fc32933 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-n5q.c -@@ -0,0 +1,132 @@ -+/* -+ * ALFA Network N5Q board support -+ * -+ * Copyright (C) 2018 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define N5Q_GPIO_LED_LAN 19 -+#define N5Q_GPIO_LED_SIGNAL1 0 -+#define N5Q_GPIO_LED_SIGNAL2 1 -+#define N5Q_GPIO_LED_SIGNAL3 2 -+#define N5Q_GPIO_LED_SIGNAL4 3 -+#define N5Q_GPIO_LED_WAN 18 -+#define N5Q_GPIO_LED_WLAN 12 -+ -+#define N5Q_GPIO_WDT_EN 16 -+#define N5Q_GPIO_WDT_IN 17 -+ -+#define N5Q_GPIO_BTN_RESET 11 -+ -+#define N5Q_MAC0_OFFSET 0 -+#define N5Q_MAC1_OFFSET 6 -+#define N5Q_WMAC_CALDATA_OFFSET 0x1000 -+ -+#define N5Q_KEYS_POLL_INTERVAL 20 -+#define N5Q_KEYS_DEBOUNCE_INTERVAL (3 * N5Q_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led n5q_leds_gpio[] __initdata = { -+ { -+ .name = "n5q:green:lan", -+ .gpio = N5Q_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "n5q:red:signal1", -+ .gpio = N5Q_GPIO_LED_SIGNAL1, -+ .active_low = 1, -+ }, { -+ .name = "n5q:orange:signal2", -+ .gpio = N5Q_GPIO_LED_SIGNAL2, -+ .active_low = 1, -+ }, { -+ .name = "n5q:green:signal3", -+ .gpio = N5Q_GPIO_LED_SIGNAL3, -+ .active_low = 1, -+ }, { -+ .name = "n5q:green:signal4", -+ .gpio = N5Q_GPIO_LED_SIGNAL4, -+ .active_low = 1, -+ }, { -+ .name = "n5q:green:wan", -+ .gpio = N5Q_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "n5q:green:wlan", -+ .gpio = N5Q_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button n5q_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = N5Q_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = N5Q_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init n5q_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1f070000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = 0xf7; -+ -+ /* LAN */ -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + N5Q_MAC1_OFFSET, 0); -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + N5Q_MAC0_OFFSET, 0); -+ ath79_register_eth(0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(n5q_leds_gpio), -+ n5q_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, N5Q_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(n5q_gpio_keys), -+ n5q_gpio_keys); -+ -+ gpio_request_one(N5Q_GPIO_WDT_IN, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "WDT input"); -+ -+ gpio_request_one(N5Q_GPIO_WDT_EN, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "WDT enable"); -+ -+ ath79_register_wmac(art + N5Q_WMAC_CALDATA_OFFSET, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_N5Q, "N5Q", "ALFA Network N5Q", n5q_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-nbg460n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-nbg460n.c -new file mode 100644 -index 0000000000..ca007779ec ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-nbg460n.c -@@ -0,0 +1,220 @@ -+/* -+ * Zyxel NBG 460N/550N/550NH board support -+ * -+ * Copyright (C) 2010 Michael Kurz -+ * -+ * based on mach-tl-wr1043nd.c -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+/* LEDs */ -+#define NBG460N_GPIO_LED_WPS 3 -+#define NBG460N_GPIO_LED_WAN 6 -+#define NBG460N_GPIO_LED_POWER 14 -+#define NBG460N_GPIO_LED_WLAN 15 -+ -+/* Buttons */ -+#define NBG460N_GPIO_BTN_WPS 12 -+#define NBG460N_GPIO_BTN_RESET 21 -+ -+#define NBG460N_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define NBG460N_KEYS_DEBOUNCE_INTERVAL (3 * NBG460N_KEYS_POLL_INTERVAL) -+ -+/* RTC chip PCF8563 I2C interface */ -+#define NBG460N_GPIO_PCF8563_SDA 8 -+#define NBG460N_GPIO_PCF8563_SCK 7 -+ -+/* Switch configuration I2C interface */ -+#define NBG460N_GPIO_RTL8366_SDA 16 -+#define NBG460N_GPIO_RTL8366_SCK 18 -+ -+static struct mtd_partition nbg460n_partitions[] = { -+ { -+ .name = "Bootbase", -+ .offset = 0, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "U-Boot Config", -+ .offset = 0x010000, -+ .size = 0x030000, -+ }, { -+ .name = "U-Boot", -+ .offset = 0x040000, -+ .size = 0x030000, -+ }, { -+ .name = "linux", -+ .offset = 0x070000, -+ .size = 0x0e0000, -+ }, { -+ .name = "rootfs", -+ .offset = 0x150000, -+ .size = 0x2a0000, -+ }, { -+ .name = "CalibData", -+ .offset = 0x3f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x070000, -+ .size = 0x380000, -+ } -+}; -+ -+static struct flash_platform_data nbg460n_flash_data = { -+ .parts = nbg460n_partitions, -+ .nr_parts = ARRAY_SIZE(nbg460n_partitions), -+}; -+ -+static struct gpio_led nbg460n_leds_gpio[] __initdata = { -+ { -+ .name = "nbg460n:green:power", -+ .gpio = NBG460N_GPIO_LED_POWER, -+ .active_low = 0, -+ .default_trigger = "default-on", -+ }, { -+ .name = "nbg460n:green:wps", -+ .gpio = NBG460N_GPIO_LED_WPS, -+ .active_low = 0, -+ }, { -+ .name = "nbg460n:green:wlan", -+ .gpio = NBG460N_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, { -+ /* Not really for controlling the LED, -+ when set low the LED blinks uncontrollable */ -+ .name = "nbg460n:green:wan", -+ .gpio = NBG460N_GPIO_LED_WAN, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button nbg460n_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = NBG460N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = NBG460N_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = NBG460N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = NBG460N_GPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static struct i2c_gpio_platform_data nbg460n_i2c_device_platdata = { -+ .sda_pin = NBG460N_GPIO_PCF8563_SDA, -+ .scl_pin = NBG460N_GPIO_PCF8563_SCK, -+ .udelay = 10, -+}; -+ -+static struct platform_device nbg460n_i2c_device = { -+ .name = "i2c-gpio", -+ .id = -1, -+ .num_resources = 0, -+ .resource = NULL, -+ .dev = { -+ .platform_data = &nbg460n_i2c_device_platdata, -+ }, -+}; -+ -+static struct i2c_board_info nbg460n_i2c_devs[] __initdata = { -+ { -+ I2C_BOARD_INFO("pcf8563", 0x51), -+ }, -+}; -+ -+static void nbg460n_i2c_init(void) -+{ -+ /* The gpio interface */ -+ platform_device_register(&nbg460n_i2c_device); -+ /* I2C devices */ -+ i2c_register_board_info(0, nbg460n_i2c_devs, -+ ARRAY_SIZE(nbg460n_i2c_devs)); -+} -+ -+ -+static struct rtl8366_platform_data nbg460n_rtl8366s_data = { -+ .gpio_sda = NBG460N_GPIO_RTL8366_SDA, -+ .gpio_sck = NBG460N_GPIO_RTL8366_SCK, -+}; -+ -+static struct platform_device nbg460n_rtl8366s_device = { -+ .name = RTL8366S_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &nbg460n_rtl8366s_data, -+ } -+}; -+ -+static void __init nbg460n_setup(void) -+{ -+ /* end of bootloader sector contains mac address */ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1fc0fff8); -+ /* last sector contains wlan calib data */ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* LAN Port */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_eth0_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ -+ /* WAN Port */ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -+ ath79_eth1_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth1_data.phy_mask = 0x10; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ /* register the switch phy */ -+ platform_device_register(&nbg460n_rtl8366s_device); -+ -+ /* register flash */ -+ ath79_register_m25p80(&nbg460n_flash_data); -+ -+ ath79_register_wmac(eeprom, mac); -+ -+ /* register RTC chip */ -+ nbg460n_i2c_init(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(nbg460n_leds_gpio), -+ nbg460n_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, NBG460N_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(nbg460n_gpio_keys), -+ nbg460n_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_NBG460N, "NBG460N", "Zyxel NBG460N/550N/550NH", -+ nbg460n_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-nbg6716.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-nbg6716.c -new file mode 100644 -index 0000000000..b0fbb78d82 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-nbg6716.c -@@ -0,0 +1,385 @@ -+/* -+ * ZyXEL NBG6716/NBG6616 board support -+ * -+ * Based on the Qualcomm Atheros AP135/AP136 reference board support code -+ * Copyright (c) 2012 Qualcomm Atheros -+ * Copyright (c) 2012-2013 Gabor Juhos -+ * Copyright (c) 2013 Andre Valentin -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) -+#include -+#else -+#include -+#endif -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-nfc.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "nvram.h" -+ -+#define NBG6716_GPIO_LED_INTERNET 18 -+#define NBG6716_GPIO_LED_POWER 15 -+#define NBG6716_GPIO_LED_USB1 4 -+#define NBG6716_GPIO_LED_USB2 13 -+#define NBG6716_GPIO_LED_WIFI2G 19 -+#define NBG6716_GPIO_LED_WIFI5G 17 -+#define NBG6716_GPIO_LED_WPS 21 -+ -+#define NBG6716_GPIO_BTN_RESET 23 -+#define NBG6716_GPIO_BTN_RFKILL 1 -+#define NBG6716_GPIO_BTN_USB1 0 -+#define NBG6716_GPIO_BTN_USB2 14 -+#define NBG6716_GPIO_BTN_WPS 22 -+ -+#define NBG6716_GPIO_USB_POWER 16 -+ -+#define NBG6716_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define NBG6716_KEYS_DEBOUNCE_INTERVAL (3 * NBG6716_KEYS_POLL_INTERVAL) -+ -+#define NBG6716_MAC0_OFFSET 0 -+#define NBG6716_MAC1_OFFSET 6 -+#define NBG6716_WMAC_CALDATA_OFFSET 0x1000 -+#define NBG6716_PCIE_CALDATA_OFFSET 0x5000 -+ -+/* NBG6616 has a different GPIO usage as it does not have USB Buttons */ -+#define NBG6616_GPIO_LED_USB0 14 -+#define NBG6616_GPIO_LED_USB1 21 -+#define NBG6616_GPIO_LED_WPS 0 -+ -+static struct gpio_led nbg6716_leds_gpio[] __initdata = { -+ { -+ .name = "nbg6716:white:internet", -+ .gpio = NBG6716_GPIO_LED_INTERNET, -+ .active_low = 1, -+ }, -+ { -+ .name = "nbg6716:white:power", -+ .gpio = NBG6716_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "nbg6716:white:usb1", -+ .gpio = NBG6716_GPIO_LED_USB1, -+ .active_low = 1, -+ }, -+ { -+ .name = "nbg6716:white:usb2", -+ .gpio = NBG6716_GPIO_LED_USB2, -+ .active_low = 1, -+ }, -+ { -+ .name = "nbg6716:white:wifi2g", -+ .gpio = NBG6716_GPIO_LED_WIFI2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "nbg6716:white:wifi5g", -+ .gpio = NBG6716_GPIO_LED_WIFI5G, -+ .active_low = 1, -+ }, -+ { -+ .name = "nbg6716:white:wps", -+ .gpio = NBG6716_GPIO_LED_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button nbg6716_gpio_keys[] __initdata = { -+ { -+ .desc = "RESET button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = NBG6716_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = NBG6716_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "RFKILL button", -+ .type = EV_SW, -+ .code = KEY_RFKILL, -+ .debounce_interval = NBG6716_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = NBG6716_GPIO_BTN_RFKILL, -+ .active_low = 0, -+ }, -+ { -+ .desc = "USB1 eject button", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .debounce_interval = NBG6716_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = NBG6716_GPIO_BTN_USB1, -+ .active_low = 1, -+ }, -+ { -+ .desc = "USB2 eject button", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .debounce_interval = NBG6716_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = NBG6716_GPIO_BTN_USB2, -+ .active_low = 1, -+ }, -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = NBG6716_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = NBG6716_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+ -+ -+static struct gpio_led nbg6616_leds_gpio[] __initdata = { -+ { -+ .name = "nbg6616:green:power", -+ .gpio = NBG6716_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "nbg6616:green:usb2", -+ .gpio = NBG6616_GPIO_LED_USB0, -+ .active_low = 1, -+ }, -+ { -+ .name = "nbg6616:green:usb1", -+ .gpio = NBG6616_GPIO_LED_USB1, -+ .active_low = 1, -+ }, -+ { -+ .name = "nbg6616:green:wifi2g", -+ .gpio = NBG6716_GPIO_LED_WIFI2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "nbg6616:green:wifi5g", -+ .gpio = NBG6716_GPIO_LED_WIFI5G, -+ .active_low = 1, -+ }, -+ { -+ .name = "nbg6616:green:wps", -+ .gpio = NBG6616_GPIO_LED_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button nbg6616_gpio_keys[] __initdata = { -+ { -+ .desc = "RESET button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = NBG6716_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = NBG6716_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "RFKILL button", -+ .type = EV_SW, -+ .code = KEY_RFKILL, -+ .debounce_interval = NBG6716_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = NBG6716_GPIO_BTN_RFKILL, -+ .active_low = 0, -+ }, -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = NBG6716_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = NBG6716_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+ -+static struct ar8327_pad_cfg nbg6716_ar8327_pad0_cfg; -+static struct ar8327_pad_cfg nbg6716_ar8327_pad6_cfg; -+static struct ar8327_led_cfg nbg6716_ar8327_led_cfg; -+ -+static struct ar8327_platform_data nbg6716_ar8327_data = { -+ .pad0_cfg = &nbg6716_ar8327_pad0_cfg, -+ .pad6_cfg = &nbg6716_ar8327_pad6_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .port6_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &nbg6716_ar8327_led_cfg -+}; -+ -+static struct mdio_board_info nbg6716_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &nbg6716_ar8327_data, -+ }, -+}; -+ -+static void nbg6716_get_mac(void* nvram_addr, const char *name, char *mac) -+{ -+ u8 *nvram = (u8 *) KSEG1ADDR(nvram_addr); -+ int err; -+ -+ err = ath79_nvram_parse_mac_addr(nvram, 0x10000, -+ name, mac); -+ if (err) -+ pr_err("no MAC address found for %s\n", name); -+} -+ -+static void __init nbg6716_common_setup(u32 leds_num, struct gpio_led* leds, -+ u32 keys_num, -+ struct gpio_keys_button* keys, -+ void* art_addr, void* nvram) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(art_addr); -+ u8 tmpmac[ETH_ALEN]; -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, leds_num, leds); -+ ath79_register_gpio_keys_polled(-1, NBG6716_KEYS_POLL_INTERVAL, -+ keys_num, keys); -+ -+ ath79_nfc_set_ecc_mode(AR934X_NFC_ECC_HW); -+ ath79_register_nfc(); -+ -+ gpio_request_one(NBG6716_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ -+ ath79_register_usb(); -+ -+ nbg6716_get_mac(nvram, "ethaddr=", tmpmac); -+ -+ ath79_register_pci(); -+ -+ ath79_register_wmac(art + NBG6716_WMAC_CALDATA_OFFSET, tmpmac); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, tmpmac, 2); -+ ath79_init_mac(ath79_eth1_data.mac_addr, tmpmac, 3); -+ -+ mdiobus_register_board_info(nbg6716_mdio0_info, -+ ARRAY_SIZE(nbg6716_mdio0_info)); -+ -+ /* GMAC0 is connected to the RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(1); -+} -+ -+static void __init nbg6716_010_setup(void) -+{ -+ /* GMAC0 of the AR8337 switch is connected to GMAC0 via RGMII */ -+ nbg6716_ar8327_pad0_cfg.mode = AR8327_PAD_MAC_RGMII; -+ nbg6716_ar8327_pad0_cfg.txclk_delay_en = true; -+ nbg6716_ar8327_pad0_cfg.rxclk_delay_en = true; -+ nbg6716_ar8327_pad0_cfg.txclk_delay_sel = AR8327_CLK_DELAY_SEL1; -+ nbg6716_ar8327_pad0_cfg.rxclk_delay_sel = AR8327_CLK_DELAY_SEL2; -+ -+ /* GMAC6 of the AR8337 switch is connected to GMAC1 via SGMII */ -+ nbg6716_ar8327_pad6_cfg.mode = AR8327_PAD_MAC_SGMII; -+ nbg6716_ar8327_pad6_cfg.rxclk_delay_en = true; -+ nbg6716_ar8327_pad6_cfg.rxclk_delay_sel = AR8327_CLK_DELAY_SEL0; -+ -+ ath79_eth0_pll_data.pll_1000 = 0xa6000000; -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ -+ nbg6716_ar8327_led_cfg.open_drain = 0; -+ nbg6716_ar8327_led_cfg.led_ctrl0 = 0xffb7ffb7; -+ nbg6716_ar8327_led_cfg.led_ctrl1 = 0xffb7ffb7; -+ nbg6716_ar8327_led_cfg.led_ctrl2 = 0xffb7ffb7; -+ nbg6716_ar8327_led_cfg.led_ctrl3 = 0x03ffff00; -+ -+ nbg6716_common_setup(ARRAY_SIZE(nbg6716_leds_gpio), nbg6716_leds_gpio, -+ ARRAY_SIZE(nbg6716_gpio_keys), nbg6716_gpio_keys, -+ (void*) 0x1f050000, (void*) 0x1f040000); -+} -+ -+static void __init nbg6616_010_setup(void) -+{ -+ /* GMAC0 of the AR8337 switch is connected to GMAC0 via RGMII */ -+ nbg6716_ar8327_pad0_cfg.mode = AR8327_PAD_MAC_RGMII; -+ nbg6716_ar8327_pad0_cfg.txclk_delay_en = true; -+ nbg6716_ar8327_pad0_cfg.rxclk_delay_en = true; -+ nbg6716_ar8327_pad0_cfg.txclk_delay_sel = AR8327_CLK_DELAY_SEL1; -+ nbg6716_ar8327_pad0_cfg.rxclk_delay_sel = AR8327_CLK_DELAY_SEL2; -+ -+ /* GMAC6 of the AR8337 switch is connected to GMAC1 via SGMII */ -+ nbg6716_ar8327_pad6_cfg.mode = AR8327_PAD_MAC_SGMII; -+ nbg6716_ar8327_pad6_cfg.rxclk_delay_en = true; -+ nbg6716_ar8327_pad6_cfg.rxclk_delay_sel = AR8327_CLK_DELAY_SEL0; -+ -+ ath79_eth0_pll_data.pll_1000 = 0xa6000000; -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ -+ nbg6716_ar8327_led_cfg.open_drain = 0; -+ nbg6716_ar8327_led_cfg.led_ctrl0 = 0xffb7ffb7; -+ nbg6716_ar8327_led_cfg.led_ctrl1 = 0xffb7ffb7; -+ nbg6716_ar8327_led_cfg.led_ctrl2 = 0xffb7ffb7; -+ nbg6716_ar8327_led_cfg.led_ctrl3 = 0x03ffff00; -+ -+ -+ nbg6716_common_setup(ARRAY_SIZE(nbg6616_leds_gpio), nbg6616_leds_gpio, -+ ARRAY_SIZE(nbg6616_gpio_keys), nbg6616_gpio_keys, -+ (void*) 0x1f040000, (void*) 0x1f030000); -+} -+ -+ -+MIPS_MACHINE(ATH79_MACH_NBG6716, "NBG6716", -+ "Zyxel NBG6716", -+ nbg6716_010_setup); -+ -+MIPS_MACHINE(ATH79_MACH_NBG6616, "NBG6616", -+ "Zyxel NBG6616", -+ nbg6616_010_setup); -+ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-om2p.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-om2p.c -new file mode 100644 -index 0000000000..c888f7d1a8 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-om2p.c -@@ -0,0 +1,320 @@ -+/* -+ * OpenMesh OM2P support -+ * -+ * Copyright (C) 2011 Marek Lindner -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define OM2P_GPIO_LED_POWER 0 -+#define OM2P_GPIO_LED_GREEN 13 -+#define OM2P_GPIO_LED_RED 14 -+#define OM2P_GPIO_LED_YELLOW 15 -+#define OM2P_GPIO_LED_LAN 16 -+#define OM2P_GPIO_LED_WAN 17 -+#define OM2P_GPIO_BTN_RESET 1 -+ -+#define OM2P_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define OM2P_KEYS_DEBOUNCE_INTERVAL (3 * OM2P_KEYS_POLL_INTERVAL) -+ -+#define OM2P_WAN_PHYMASK BIT(4) -+ -+#define OM2P_LC_GPIO_LED_POWER 1 -+#define OM2P_LC_GPIO_LED_GREEN 15 -+#define OM2P_LC_GPIO_LED_RED 16 -+#define OM2P_LC_GPIO_LED_YELLOW 0 -+#define OM2P_LC_GPIO_LED_LAN 13 -+#define OM2P_LC_GPIO_LED_WAN 17 -+#define OM2P_LC_GPIO_BTN_RESET 12 -+ -+#define OM2Pv4_GPIO_LED_POWER 0 -+#define OM2Pv4_GPIO_LED_GREEN 2 -+#define OM2Pv4_GPIO_LED_RED 4 -+#define OM2Pv4_GPIO_LED_YELLOW 3 -+#define OM2Pv4_GPIO_LED_LAN 14 -+#define OM2Pv4_GPIO_LED_WAN 13 -+#define OM2Pv4_GPIO_BTN_RESET 1 -+ -+#define OM2P_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct flash_platform_data om2p_flash_data = { -+ .type = "s25sl12800", -+ .name = "ar7240-nor0", -+}; -+ -+static struct gpio_led om2p_leds_gpio[] __initdata = { -+ { -+ .name = "om2p:blue:power", -+ .gpio = OM2P_GPIO_LED_POWER, -+ .active_low = 1, -+ }, { -+ .name = "om2p:red:wifi", -+ .gpio = OM2P_GPIO_LED_RED, -+ .active_low = 1, -+ }, { -+ .name = "om2p:yellow:wifi", -+ .gpio = OM2P_GPIO_LED_YELLOW, -+ .active_low = 1, -+ }, { -+ .name = "om2p:green:wifi", -+ .gpio = OM2P_GPIO_LED_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "om2p:blue:lan", -+ .gpio = OM2P_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "om2p:blue:wan", -+ .gpio = OM2P_GPIO_LED_WAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button om2p_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = OM2P_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = OM2P_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init om2p_setup(void) -+{ -+ u8 *mac1 = (u8 *)KSEG1ADDR(0x1ffc0000); -+ u8 *mac2 = (u8 *)KSEG1ADDR(0x1ffc0000 + ETH_ALEN); -+ u8 *ee = (u8 *)KSEG1ADDR(0x1ffc1000); -+ -+ ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ ath79_register_m25p80(&om2p_flash_data); -+ -+ ath79_register_mdio(0, ~OM2P_WAN_PHYMASK); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 0); -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ap91_pci_init(ee, NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(om2p_leds_gpio), -+ om2p_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, OM2P_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(om2p_gpio_keys), -+ om2p_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_OM2P, "OM2P", "OpenMesh OM2P", om2p_setup); -+ -+ -+static struct flash_platform_data om2p_lc_flash_data = { -+ .type = "s25sl12800", -+}; -+ -+static void __init om2p_lc_setup(void) -+{ -+ u8 *mac1 = (u8 *)KSEG1ADDR(0x1ffc0000); -+ u8 *mac2 = (u8 *)KSEG1ADDR(0x1ffc0000 + ETH_ALEN); -+ u8 *art = (u8 *)KSEG1ADDR(0x1ffc1000); -+ u32 t; -+ -+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); -+ t |= AR933X_BOOTSTRAP_MDIO_GPIO_EN; -+ ath79_reset_wr(AR933X_RESET_REG_BOOTSTRAP, t); -+ -+ ath79_register_m25p80(&om2p_lc_flash_data); -+ -+ om2p_leds_gpio[0].gpio = OM2P_LC_GPIO_LED_POWER; -+ om2p_leds_gpio[1].gpio = OM2P_LC_GPIO_LED_RED; -+ om2p_leds_gpio[2].gpio = OM2P_LC_GPIO_LED_YELLOW; -+ om2p_leds_gpio[3].gpio = OM2P_LC_GPIO_LED_GREEN; -+ om2p_leds_gpio[4].gpio = OM2P_LC_GPIO_LED_LAN; -+ om2p_leds_gpio[5].gpio = OM2P_LC_GPIO_LED_WAN; -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(om2p_leds_gpio), -+ om2p_leds_gpio); -+ -+ om2p_gpio_keys[0].gpio = OM2P_LC_GPIO_BTN_RESET; -+ ath79_register_gpio_keys_polled(-1, OM2P_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(om2p_gpio_keys), -+ om2p_gpio_keys); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 0); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(art, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_OM2P_LC, "OM2P-LC", "OpenMesh OM2P LC", om2p_lc_setup); -+MIPS_MACHINE(ATH79_MACH_OM2Pv2, "OM2Pv2", "OpenMesh OM2Pv2", om2p_lc_setup); -+ -+static void __init om2p_hs_setup(void) -+{ -+ u8 *mac1 = (u8 *)KSEG1ADDR(0x1ffc0000); -+ u8 *mac2 = (u8 *)KSEG1ADDR(0x1ffc0000 + ETH_ALEN); -+ u8 *art = (u8 *)KSEG1ADDR(0x1ffc1000); -+ -+ /* make lan / wan leds software controllable */ -+ ath79_gpio_output_select(OM2P_GPIO_LED_LAN, AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(OM2P_GPIO_LED_WAN, AR934X_GPIO_OUT_GPIO); -+ -+ /* enable reset button */ -+ ath79_gpio_output_select(OM2P_GPIO_BTN_RESET, AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE); -+ -+ om2p_leds_gpio[4].gpio = OM2P_GPIO_LED_WAN; -+ om2p_leds_gpio[5].gpio = OM2P_GPIO_LED_LAN; -+ -+ ath79_register_m25p80(&om2p_lc_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(om2p_leds_gpio), -+ om2p_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, OM2P_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(om2p_gpio_keys), -+ om2p_gpio_keys); -+ -+ ath79_register_wmac(art, NULL); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_PHY_SWAP); -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 0); -+ -+ /* GMAC0 is connected to the PHY0 of the internal switch */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_OM2P_HS, "OM2P-HS", "OpenMesh OM2P HS", om2p_hs_setup); -+MIPS_MACHINE(ATH79_MACH_OM2P_HSv2, "OM2P-HSv2", "OpenMesh OM2P HSv2", om2p_hs_setup); -+MIPS_MACHINE(ATH79_MACH_OM2P_HSv3, "OM2P-HSv3", "OpenMesh OM2P HSv3", om2p_hs_setup); -+ -+static struct flash_platform_data om2pv4_flash_data = { -+ .type = "s25sl12800", -+}; -+ -+static struct gpio_led om2pv4_leds_gpio[] __initdata = { -+ { -+ .name = "om2p:blue:power", -+ .gpio = OM2Pv4_GPIO_LED_POWER, -+ .active_low = 1, -+ }, { -+ .name = "om2p:red:wifi", -+ .gpio = OM2Pv4_GPIO_LED_RED, -+ .active_low = 1, -+ }, { -+ .name = "om2p:yellow:wifi", -+ .gpio = OM2Pv4_GPIO_LED_YELLOW, -+ .active_low = 1, -+ }, { -+ .name = "om2p:green:wifi", -+ .gpio = OM2Pv4_GPIO_LED_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "om2p:blue:lan", -+ .gpio = OM2Pv4_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "om2p:blue:wan", -+ .gpio = OM2Pv4_GPIO_LED_WAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button om2pv4_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = OM2P_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = OM2Pv4_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init om2pv4_setup(void) -+{ -+ u8 *mac1 = (u8 *)KSEG1ADDR(0x1ffc0000); -+ u8 *mac2 = (u8 *)KSEG1ADDR(0x1ffc0000 + ETH_ALEN); -+ u8 *art = (u8 *)KSEG1ADDR(0x1ffc0000); -+ u8 wmac[6]; -+ -+ ath79_register_m25p80(&om2pv4_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(om2pv4_leds_gpio), -+ om2pv4_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, OM2P_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(om2pv4_gpio_keys), -+ om2pv4_gpio_keys); -+ -+ ath79_init_mac(wmac, art, 0x02); -+ ath79_register_wmac(art + OM2P_WMAC_CALDATA_OFFSET, wmac); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 0); -+ ath79_register_eth(0); -+ -+ /* WAN */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_OM2Pv4, "OM2Pv4", "OpenMesh OM2Pv4", om2pv4_setup); -+MIPS_MACHINE(ATH79_MACH_OM2P_HSv4, "OM2P-HSv4", "OpenMesh OM2P HSv4", om2pv4_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-om5p.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-om5p.c -new file mode 100644 -index 0000000000..61ff6a755d ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-om5p.c -@@ -0,0 +1,218 @@ -+/* -+ * OpenMesh OM5P support -+ * -+ * Copyright (C) 2013 Marek Lindner -+ * Copyright (C) 2014 Sven Eckelmann -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define OM5P_GPIO_LED_POWER 13 -+#define OM5P_GPIO_LED_GREEN 16 -+#define OM5P_GPIO_LED_RED 19 -+#define OM5P_GPIO_LED_YELLOW 17 -+#define OM5P_GPIO_LED_LAN 14 -+#define OM5P_GPIO_LED_WAN 15 -+#define OM5P_GPIO_BTN_RESET 4 -+#define OM5P_GPIO_I2C_SCL 20 -+#define OM5P_GPIO_I2C_SDA 21 -+ -+#define OM5P_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define OM5P_KEYS_DEBOUNCE_INTERVAL (3 * OM5P_KEYS_POLL_INTERVAL) -+ -+#define OM5P_WMAC_CALDATA_OFFSET 0x1000 -+#define OM5P_PCI_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led om5p_leds_gpio[] __initdata = { -+ { -+ .name = "om5p:blue:power", -+ .gpio = OM5P_GPIO_LED_POWER, -+ .active_low = 1, -+ }, { -+ .name = "om5p:red:wifi", -+ .gpio = OM5P_GPIO_LED_RED, -+ .active_low = 1, -+ }, { -+ .name = "om5p:yellow:wifi", -+ .gpio = OM5P_GPIO_LED_YELLOW, -+ .active_low = 1, -+ }, { -+ .name = "om5p:green:wifi", -+ .gpio = OM5P_GPIO_LED_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "om5p:blue:lan", -+ .gpio = OM5P_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "om5p:blue:wan", -+ .gpio = OM5P_GPIO_LED_WAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button om5p_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = OM5P_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = OM5P_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static struct flash_platform_data om5p_flash_data = { -+ .type = "mx25l12805d", -+}; -+ -+static void __init om5p_setup(void) -+{ -+ u8 *art = (u8 *)KSEG1ADDR(0x1fff0000); -+ u8 mac[6]; -+ -+ /* make lan / wan leds software controllable */ -+ ath79_gpio_output_select(OM5P_GPIO_LED_LAN, AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(OM5P_GPIO_LED_WAN, AR934X_GPIO_OUT_GPIO); -+ -+ ath79_register_m25p80(&om5p_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(om5p_leds_gpio), -+ om5p_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, OM5P_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(om5p_gpio_keys), -+ om5p_gpio_keys); -+ -+ ath79_init_mac(mac, art, 2); -+ ath79_register_wmac(art + OM5P_WMAC_CALDATA_OFFSET, mac); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_PHY_SWAP); -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art, 1); -+ -+ /* GMAC0 is connected to the PHY0 of the internal switch */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_OM5P, "OM5P", "OpenMesh OM5P", om5p_setup); -+ -+static struct i2c_gpio_platform_data om5pan_i2c_device_platdata = { -+ .sda_pin = OM5P_GPIO_I2C_SDA, -+ .scl_pin = OM5P_GPIO_I2C_SCL, -+ .udelay = 10, -+ .sda_is_open_drain = 1, -+ .scl_is_open_drain = 1, -+}; -+ -+static struct platform_device om5pan_i2c_device = { -+ .name = "i2c-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &om5pan_i2c_device_platdata, -+ }, -+}; -+ -+static struct i2c_board_info om5pan_i2c_devs[] __initdata = { -+ { -+ I2C_BOARD_INFO("tmp423", 0x4c), -+ }, -+}; -+ -+static struct at803x_platform_data om5p_an_at803x_data = { -+ .disable_smarteee = 1, -+ .enable_rgmii_rx_delay = 1, -+ .enable_rgmii_tx_delay = 1, -+}; -+ -+static struct mdio_board_info om5p_an_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 7, -+ .platform_data = &om5p_an_at803x_data, -+ }, -+}; -+ -+static void __init om5p_an_setup(void) -+{ -+ u8 *art = (u8 *)KSEG1ADDR(0x1fff0000); -+ u8 mac[6]; -+ -+ /* temperature sensor */ -+ platform_device_register(&om5pan_i2c_device); -+ i2c_register_board_info(0, om5pan_i2c_devs, -+ ARRAY_SIZE(om5pan_i2c_devs)); -+ -+ /* make lan / wan leds software controllable */ -+ ath79_gpio_output_select(OM5P_GPIO_LED_LAN, AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(OM5P_GPIO_LED_WAN, AR934X_GPIO_OUT_GPIO); -+ -+ ath79_register_m25p80(&om5p_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(om5p_leds_gpio), -+ om5p_leds_gpio); -+ -+ ath79_init_mac(mac, art, 0x02); -+ ath79_register_wmac(art + OM5P_WMAC_CALDATA_OFFSET, mac); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0); -+ ath79_setup_ar934x_eth_rx_delay(2, 2); -+ ath79_register_mdio(0, 0x0); -+ ath79_register_mdio(1, 0x0); -+ -+ mdiobus_register_board_info(om5p_an_mdio0_info, -+ ARRAY_SIZE(om5p_an_mdio0_info)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art, 0x00); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art, 0x01); -+ -+ /* GMAC0 is connected to the PHY7 */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_data.phy_mask = BIT(7); -+ ath79_eth0_pll_data.pll_1000 = 0x02000000; -+ ath79_eth0_pll_data.pll_100 = 0x00000101; -+ ath79_eth0_pll_data.pll_10 = 0x00001313; -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_register_eth(1); -+ -+ ath79_init_mac(mac, art, 0x10); -+ ap91_pci_init(art + OM5P_PCI_CALDATA_OFFSET, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_OM5P_AN, "OM5P-AN", "OpenMesh OM5P AN", om5p_an_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-om5pac.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-om5pac.c -new file mode 100644 -index 0000000000..10771ea7b1 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-om5pac.c -@@ -0,0 +1,193 @@ -+/* -+ * OpenMesh OM5P-AC support -+ * -+ * Copyright (C) 2013 Marek Lindner -+ * Copyright (C) 2014 Sven Eckelmann -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define OM5PAC_GPIO_LED_POWER 18 -+#define OM5PAC_GPIO_LED_GREEN 21 -+#define OM5PAC_GPIO_LED_RED 23 -+#define OM5PAC_GPIO_LED_YELLOW 22 -+#define OM5PAC_GPIO_LED_LAN 20 -+#define OM5PAC_GPIO_LED_WAN 19 -+#define OM5PAC_GPIO_I2C_SCL 12 -+#define OM5PAC_GPIO_I2C_SDA 11 -+ -+#define OM5PAC_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define OM5PAC_KEYS_DEBOUNCE_INTERVAL (3 * OM5PAC_KEYS_POLL_INTERVAL) -+ -+#define OM5PAC_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led om5pac_leds_gpio[] __initdata = { -+ { -+ .name = "om5pac:blue:power", -+ .gpio = OM5PAC_GPIO_LED_POWER, -+ .active_low = 1, -+ }, { -+ .name = "om5pac:red:wifi", -+ .gpio = OM5PAC_GPIO_LED_RED, -+ .active_low = 1, -+ }, { -+ .name = "om5pac:yellow:wifi", -+ .gpio = OM5PAC_GPIO_LED_YELLOW, -+ .active_low = 1, -+ }, { -+ .name = "om5pac:green:wifi", -+ .gpio = OM5PAC_GPIO_LED_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "om5pac:blue:lan", -+ .gpio = OM5PAC_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "om5pac:blue:wan", -+ .gpio = OM5PAC_GPIO_LED_WAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct flash_platform_data om5pac_flash_data = { -+ .type = "mx25l12805d", -+}; -+ -+static struct i2c_gpio_platform_data om5pac_i2c_device_platdata = { -+ .sda_pin = OM5PAC_GPIO_I2C_SDA, -+ .scl_pin = OM5PAC_GPIO_I2C_SCL, -+ .udelay = 10, -+ .sda_is_open_drain = 1, -+ .scl_is_open_drain = 1, -+}; -+ -+static struct platform_device om5pac_i2c_device = { -+ .name = "i2c-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &om5pac_i2c_device_platdata, -+ }, -+}; -+ -+static struct i2c_board_info om5pac_i2c_devs[] __initdata = { -+ { -+ I2C_BOARD_INFO("tmp423", 0x4c), -+ }, -+}; -+ -+static struct at803x_platform_data om5pac_at803x_data = { -+ .disable_smarteee = 1, -+ .enable_rgmii_rx_delay = 1, -+ .enable_rgmii_tx_delay = 1, -+}; -+ -+static struct mdio_board_info om5pac_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 1, -+ .platform_data = &om5pac_at803x_data, -+ }, -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 2, -+ .platform_data = &om5pac_at803x_data, -+ }, -+}; -+ -+static void __init om5p_ac_setup_qca955x_eth_cfg(u32 mask, -+ unsigned int rxd, -+ unsigned int rxdv, -+ unsigned int txd, -+ unsigned int txe) -+{ -+ void __iomem *base; -+ u32 t; -+ -+ base = ioremap(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE); -+ -+ t = mask; -+ t |= rxd << QCA955X_ETH_CFG_RXD_DELAY_SHIFT; -+ t |= rxdv << QCA955X_ETH_CFG_RDV_DELAY_SHIFT; -+ t |= txd << QCA955X_ETH_CFG_TXD_DELAY_SHIFT; -+ t |= txe << QCA955X_ETH_CFG_TXE_DELAY_SHIFT; -+ -+ __raw_writel(t, base + QCA955X_GMAC_REG_ETH_CFG); -+ -+ iounmap(base); -+} -+ -+static void __init om5p_ac_setup(void) -+{ -+ u8 *art = (u8 *)KSEG1ADDR(0x1fff0000); -+ u8 mac[6]; -+ -+ /* temperature sensor */ -+ platform_device_register(&om5pac_i2c_device); -+ i2c_register_board_info(0, om5pac_i2c_devs, -+ ARRAY_SIZE(om5pac_i2c_devs)); -+ -+ ath79_gpio_output_select(OM5PAC_GPIO_LED_WAN, QCA955X_GPIO_OUT_GPIO); -+ -+ ath79_register_m25p80(&om5pac_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(om5pac_leds_gpio), -+ om5pac_leds_gpio); -+ -+ ath79_init_mac(mac, art, 0x02); -+ ath79_register_wmac(art + OM5PAC_WMAC_CALDATA_OFFSET, mac); -+ -+ om5p_ac_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN, 3, 3, 0, 0); -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(om5pac_mdio0_info, -+ ARRAY_SIZE(om5pac_mdio0_info)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art, 0x00); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art, 0x01); -+ -+ /* GMAC0 is connected to the PHY1 */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_data.phy_mask = BIT(1); -+ ath79_eth0_pll_data.pll_1000 = 0x82000101; -+ ath79_eth0_pll_data.pll_100 = 0x80000101; -+ ath79_eth0_pll_data.pll_10 = 0x80001313; -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to MDIO1 in SGMII mode */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth1_data.phy_mask = BIT(2); -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ ath79_eth1_pll_data.pll_100 = 0x80000101; -+ ath79_eth1_pll_data.pll_10 = 0x80001313; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_register_eth(1); -+ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_OM5P_AC, "OM5P-AC", "OpenMesh OM5P AC", om5p_ac_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-om5pacv2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-om5pacv2.c -new file mode 100644 -index 0000000000..f72700138f ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-om5pacv2.c -@@ -0,0 +1,215 @@ -+/* -+ * OpenMesh OM5P-ACv2 support -+ * -+ * Copyright (C) 2013 Marek Lindner -+ * Copyright (C) 2014-2016 Sven Eckelmann -+ * Copyright (C) 2015 Open-Mesh - Jim Collar -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define OM5PACV2_GPIO_LED_POWER 14 -+#define OM5PACV2_GPIO_LED_GREEN 13 -+#define OM5PACV2_GPIO_LED_RED 23 -+#define OM5PACV2_GPIO_LED_YELLOW 15 -+#define OM5PACV2_GPIO_BTN_RESET 1 -+#define OM5PACV2_GPIO_I2C_SCL 18 -+#define OM5PACV2_GPIO_I2C_SDA 19 -+#define OM5PACV2_GPIO_PA_DCDC 2 -+#define OM5PACV2_GPIO_PA_HIGH 16 -+ -+#define OM5PACV2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define OM5PACV2_KEYS_DEBOUNCE_INTERVAL (3 * OM5PACV2_KEYS_POLL_INTERVAL) -+ -+#define OM5PACV2_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led om5pacv2_leds_gpio[] __initdata = { -+ { -+ .name = "om5pac:blue:power", -+ .gpio = OM5PACV2_GPIO_LED_POWER, -+ .active_low = 1, -+ }, { -+ .name = "om5pac:red:wifi", -+ .gpio = OM5PACV2_GPIO_LED_RED, -+ .active_low = 1, -+ }, { -+ .name = "om5pac:yellow:wifi", -+ .gpio = OM5PACV2_GPIO_LED_YELLOW, -+ .active_low = 1, -+ }, { -+ .name = "om5pac:green:wifi", -+ .gpio = OM5PACV2_GPIO_LED_GREEN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button om5pacv2_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = OM5PACV2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = OM5PACV2_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static struct i2c_gpio_platform_data om5pacv2_i2c_device_platdata = { -+ .sda_pin = OM5PACV2_GPIO_I2C_SDA, -+ .scl_pin = OM5PACV2_GPIO_I2C_SCL, -+ .udelay = 10, -+ .sda_is_open_drain = 1, -+ .scl_is_open_drain = 1, -+}; -+ -+static struct platform_device om5pacv2_i2c_device = { -+ .name = "i2c-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &om5pacv2_i2c_device_platdata, -+ }, -+}; -+ -+static struct i2c_board_info om5pacv2_i2c_devs[] __initdata = { -+ { -+ I2C_BOARD_INFO("tmp423", 0x4e), -+ }, -+}; -+ -+static struct flash_platform_data om5pacv2_flash_data = { -+ .type = "mx25l12805d", -+}; -+ -+static struct at803x_platform_data om5pacv2_an_at803x_data = { -+ .disable_smarteee = 1, -+ .enable_rgmii_rx_delay = 1, -+ .enable_rgmii_tx_delay = 1, -+}; -+ -+static struct at803x_platform_data om5pacv2_an_at8031_data = { -+ .disable_smarteee = 1, -+ .enable_rgmii_rx_delay = 1, -+ .enable_rgmii_tx_delay = 1, -+}; -+ -+static struct mdio_board_info om5pacv2_an_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 4, -+ .platform_data = &om5pacv2_an_at803x_data, -+ }, -+ { -+ .bus_id = "ag71xx-mdio.1", -+ .mdio_addr = 1, -+ .platform_data = &om5pacv2_an_at8031_data, -+ }, -+}; -+ -+static void __init om5p_acv2_setup_qca955x_eth_cfg(u32 mask, -+ unsigned int rxd, -+ unsigned int rxdv, -+ unsigned int txd, -+ unsigned int txe) -+{ -+ void __iomem *base; -+ u32 t; -+ -+ base = ioremap(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE); -+ -+ t = mask; -+ t |= rxd << QCA955X_ETH_CFG_RXD_DELAY_SHIFT; -+ t |= rxdv << QCA955X_ETH_CFG_RDV_DELAY_SHIFT; -+ t |= txd << QCA955X_ETH_CFG_TXD_DELAY_SHIFT; -+ t |= txe << QCA955X_ETH_CFG_TXE_DELAY_SHIFT; -+ -+ __raw_writel(t, base + QCA955X_GMAC_REG_ETH_CFG); -+ -+ iounmap(base); -+} -+ -+static void __init om5p_acv2_setup(void) -+{ -+ u8 *art = (u8 *)KSEG1ADDR(0x1fff0000); -+ u8 mac[6]; -+ -+ /* power amplifier high power, 4.2V at RFFM4203/4503 instead of 3.3 */ -+ ath79_gpio_function_enable(QCA955X_GPIO_FUNC_JTAG_DISABLE); -+ ath79_gpio_output_select(OM5PACV2_GPIO_PA_DCDC, QCA955X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(OM5PACV2_GPIO_PA_HIGH, QCA955X_GPIO_OUT_GPIO); -+ gpio_request_one(OM5PACV2_GPIO_PA_DCDC, GPIOF_OUT_INIT_HIGH, -+ "PA DC/DC"); -+ gpio_request_one(OM5PACV2_GPIO_PA_HIGH, GPIOF_OUT_INIT_HIGH, "PA HIGH"); -+ -+ /* temperature sensor */ -+ platform_device_register(&om5pacv2_i2c_device); -+ i2c_register_board_info(0, om5pacv2_i2c_devs, -+ ARRAY_SIZE(om5pacv2_i2c_devs)); -+ -+ ath79_register_m25p80(&om5pacv2_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(om5pacv2_leds_gpio), -+ om5pacv2_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, OM5PACV2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(om5pacv2_gpio_keys), -+ om5pacv2_gpio_keys); -+ -+ ath79_init_mac(mac, art, 0x02); -+ ath79_register_wmac(art + OM5PACV2_WMAC_CALDATA_OFFSET, mac); -+ -+ om5p_acv2_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN, 2, 2, 0, 0); -+ ath79_register_mdio(0, 0x0); -+ ath79_register_mdio(1, 0x0); -+ -+ mdiobus_register_board_info(om5pacv2_an_mdio0_info, -+ ARRAY_SIZE(om5pacv2_an_mdio0_info)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art, 0x00); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art, 0x01); -+ -+ /* GMAC0 is connected to the PHY4 */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_pll_data.pll_1000 = 0x82000101; -+ ath79_eth0_pll_data.pll_100 = 0x80000101; -+ ath79_eth0_pll_data.pll_10 = 0x80001313; -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to MDIO1 in SGMII mode */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_eth1_data.phy_mask = BIT(1); -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ ath79_eth1_pll_data.pll_100 = 0x80000101; -+ ath79_eth1_pll_data.pll_10 = 0x80001313; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_register_eth(1); -+ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_OM5P_ACv2, "OM5P-ACv2", "OpenMesh OM5P ACv2", om5p_acv2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-omy-g1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-omy-g1.c -new file mode 100644 -index 0000000000..25ca27cba8 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-omy-g1.c -@@ -0,0 +1,123 @@ -+/* -+ * OMYlink OMY-G1 board support -+ * -+ * Copyright (C) 2016 L. D. Pinney -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define OMY_G1_GPIO_LED_WLAN 13 -+#define OMY_G1_GPIO_LED_WAN 18 -+#define OMY_G1_GPIO_LED_LAN 19 -+ -+#define OMY_G1_GPIO_USB_POWER 4 -+ -+#define OMY_G1_GPIO_BTN_RESET 17 -+ -+#define OMY_G1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define OMY_G1_KEYS_DEBOUNCE_INTERVAL (3 * OMY_G1_KEYS_POLL_INTERVAL) -+ -+static const char *omy_g1_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data omy_g1_flash_data = { -+ .part_probes = omy_g1_part_probes, -+}; -+ -+static struct gpio_led omy_g1_leds_gpio[] __initdata = { -+ { -+ .name = "omy:green:wlan", -+ .gpio = OMY_G1_GPIO_LED_WLAN, -+ .active_low = 1, -+ },{ -+ .name = "omy:green:wan", -+ .gpio = OMY_G1_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "omy:green:lan", -+ .gpio = OMY_G1_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button omy_g1_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = OMY_G1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = OMY_G1_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init omy_g1_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_gpio_function_setup(AR934X_GPIO_FUNC_JTAG_DISABLE, -+ AR934X_GPIO_FUNC_CLK_OBS4_EN); -+ -+ ath79_register_m25p80(&omy_g1_flash_data); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(omy_g1_leds_gpio), -+ omy_g1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, OMY_G1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(omy_g1_gpio_keys), -+ omy_g1_gpio_keys); -+ -+ ath79_gpio_output_select(OMY_G1_GPIO_USB_POWER, -+ AR934X_GPIO_OUT_GPIO); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_PHY_SWAP); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, -1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_register_eth(0); -+ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(ee, mac); -+ -+ ath79_gpio_output_select(OMY_G1_GPIO_USB_POWER, -+ AR934X_GPIO_OUT_GPIO); -+ -+ gpio_request_one(OMY_G1_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_OMY_G1, "OMY-G1", "OMYlink OMY-G1", -+ omy_g1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-omy-x1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-omy-x1.c -new file mode 100644 -index 0000000000..c99e3d7457 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-omy-x1.c -@@ -0,0 +1,106 @@ -+/* -+ * OMYlink OMY-X1 board support -+ * -+ * Copyright (C) 2016 L. D. Pinney -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+ -+ -+#define OMY_X1_GPIO_LED_POWER 19 -+#define OMY_X1_GPIO_LED_WAN 22 -+ -+#define OMY_X1_GPIO_BTN_RESET 17 -+ -+#define OMY_X1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define OMY_X1_KEYS_DEBOUNCE_INTERVAL (3 * OMY_X1_KEYS_POLL_INTERVAL) -+ -+static const char *omy_x1_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data omy_x1_flash_data = { -+ .part_probes = omy_x1_part_probes, -+}; -+ -+static struct gpio_led omy_x1_leds_gpio[] __initdata = { -+ { -+ .name = "omy:green:wan", -+ .gpio = OMY_X1_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "omy:green:power", -+ .gpio = OMY_X1_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button omy_x1_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = OMY_X1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = OMY_X1_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init omy_x1_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_gpio_function_setup(AR934X_GPIO_FUNC_JTAG_DISABLE, -+ AR934X_GPIO_FUNC_CLK_OBS4_EN); -+ -+ ath79_register_m25p80(&omy_x1_flash_data); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(omy_x1_leds_gpio), -+ omy_x1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, OMY_X1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(omy_x1_gpio_keys), -+ omy_x1_gpio_keys); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_PHY_SWAP); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, -1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_register_eth(0); -+ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(ee, mac); -+ -+} -+ -+MIPS_MACHINE(ATH79_MACH_OMY_X1, "OMY-X1", "OMYlink OMY-X1", -+ omy_x1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-onion-omega.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-onion-omega.c -new file mode 100644 -index 0000000000..c739840377 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-onion-omega.c -@@ -0,0 +1,84 @@ -+/* -+ * Onion Omega board support -+ * -+ * Copyright (C) 2015 Boken Lin -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define OMEGA_GPIO_LED_SYSTEM 27 -+#define OMEGA_GPIO_BTN_RESET 11 -+ -+#define OMEGA_GPIO_USB_POWER 8 -+ -+#define OMEGA_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define OMEGA_KEYS_DEBOUNCE_INTERVAL (3 * OMEGA_KEYS_POLL_INTERVAL) -+ -+static const char *omega_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data omega_flash_data = { -+ .part_probes = omega_part_probes, -+}; -+ -+static struct gpio_led omega_leds_gpio[] __initdata = { -+ { -+ .name = "onion:amber:system", -+ .gpio = OMEGA_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button omega_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = OMEGA_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = OMEGA_GPIO_BTN_RESET, -+ .active_low = 0, -+ } -+}; -+ -+static void __init onion_omega_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_m25p80(&omega_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(omega_leds_gpio), -+ omega_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, OMEGA_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(omega_gpio_keys), -+ omega_gpio_keys); -+ -+ gpio_request_one(OMEGA_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, -1); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ONION_OMEGA, "ONION-OMEGA", "Onion Omega", onion_omega_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-pb42.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-pb42.c -new file mode 100644 -index 0000000000..3a350e90a1 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-pb42.c -@@ -0,0 +1,83 @@ -+/* -+ * Atheros PB42 board support -+ * -+ * Copyright (C) 2008-2012 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define PB42_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define PB42_KEYS_DEBOUNCE_INTERVAL (3 * PB42_KEYS_POLL_INTERVAL) -+ -+#define PB42_GPIO_BTN_SW4 8 -+#define PB42_GPIO_BTN_SW5 3 -+ -+static struct gpio_keys_button pb42_gpio_keys[] __initdata = { -+ { -+ .desc = "sw4", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = PB42_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = PB42_GPIO_BTN_SW4, -+ .active_low = 1, -+ }, { -+ .desc = "sw5", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .debounce_interval = PB42_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = PB42_GPIO_BTN_SW5, -+ .active_low = 1, -+ } -+}; -+ -+static const char *pb42_part_probes[] = { -+ "RedBoot", -+ NULL, -+}; -+ -+static struct flash_platform_data pb42_flash_data = { -+ .part_probes = pb42_part_probes, -+}; -+ -+#define PB42_WAN_PHYMASK BIT(20) -+#define PB42_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19)) -+#define PB42_MDIO_PHYMASK (PB42_LAN_PHYMASK | PB42_WAN_PHYMASK) -+ -+static void __init pb42_init(void) -+{ -+ ath79_register_m25p80(&pb42_flash_data); -+ -+ ath79_register_mdio(0, ~PB42_MDIO_PHYMASK); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = PB42_WAN_PHYMASK; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth1_data.speed = SPEED_100; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_gpio_keys_polled(-1, PB42_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(pb42_gpio_keys), -+ pb42_gpio_keys); -+ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_PB42, "PB42", "Atheros PB42", pb42_init); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-pqi-air-pen.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-pqi-air-pen.c -new file mode 100644 -index 0000000000..56769bfb61 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-pqi-air-pen.c -@@ -0,0 +1,99 @@ -+/* -+ * PQI Air Pen stick support -+ * -+ * Copyright (C) 2016 YuheiOKAWA -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+*/ -+ -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define PQI_AIR_PEN_GPIO_LED_WLAN 0 -+#define PQI_AIR_PEN_GPIO_LED_WPS 23 -+ -+#define PQI_AIR_PEN_GPIO_BTN_WPS 22 -+#define PQI_AIR_PEN_GPIO_BTN_RESET 12 -+ -+#define PQI_AIR_PEN_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define PQI_AIR_PEN_KEYS_DEBOUNCE_INTERVAL (3 * PQI_AIR_PEN_KEYS_POLL_INTERVAL) -+ -+#define PQI_AIR_PEN_WMAC_CALDATA_OFFSET 0x1000 -+#define PQI_AIR_PEN_LAN_MAC_OFFSET 0x1002 -+#define PQI_AIR_PEN_WMAC_MAC_OFFSET 0x1002 -+ -+static struct gpio_led pqi_air_pen_leds_gpio[] __initdata = { -+ { -+ .name = "pqi-air-pen:blue:wlan", -+ .gpio = PQI_AIR_PEN_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+ { -+ .name = "pqi-air-pen:blue:wps", -+ .gpio = PQI_AIR_PEN_GPIO_LED_WPS, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button pqi_air_pen_gpio_keys[] __initdata = { -+ { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = PQI_AIR_PEN_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = PQI_AIR_PEN_GPIO_BTN_WPS, -+ .active_low = 0, -+ }, -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = PQI_AIR_PEN_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = PQI_AIR_PEN_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+}; -+ -+static void __init pqi_air_pen_setup(void) -+{ -+ /* ART base address */ -+ u8 *art = (u8 *) KSEG1ADDR(0x9f050000); -+ -+ /* register flash. */ -+ ath79_register_m25p80(NULL); -+ -+ /* register wireless mac with cal data */ -+ ath79_register_wmac(art + PQI_AIR_PEN_WMAC_CALDATA_OFFSET, art + PQI_AIR_PEN_WMAC_MAC_OFFSET); -+ -+ /* false PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ /* register gpio LEDs and keys */ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(pqi_air_pen_leds_gpio), -+ pqi_air_pen_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, PQI_AIR_PEN_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(pqi_air_pen_gpio_keys), -+ pqi_air_pen_gpio_keys); -+ -+ /* enable usb */ -+ ath79_register_usb(); -+ -+ /* register eth0 as LAN */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + PQI_AIR_PEN_LAN_MAC_OFFSET, 0); -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_PQI_AIR_PEN, "PQI-AIR-PEN", "PQI Air Pen",pqi_air_pen_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-qihoo-c301.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-qihoo-c301.c -new file mode 100644 -index 0000000000..a682f35e2c ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-qihoo-c301.c -@@ -0,0 +1,166 @@ -+/* -+ * Qihoo 360 C301 board support -+ * -+ * Copyright (C) 2013 Gabor Juhos -+ * Copyright (C) 2014 Weijie Gao -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "nvram.h" -+ -+#define QIHOO_C301_GPIO_LED_STATUS_GREEN 0 -+#define QIHOO_C301_GPIO_LED_STATUS_RED 11 -+ -+#define QIHOO_C301_GPIO_LED_WAN 1 -+#define QIHOO_C301_GPIO_LED_LAN1 2 -+#define QIHOO_C301_GPIO_LED_LAN2 3 -+#define QIHOO_C301_GPIO_ETH_LEN_EN 18 -+ -+#define QIHOO_C301_GPIO_BTN_RESET 16 -+ -+#define QIHOO_C301_GPIO_USB_POWER 19 -+ -+#define QIHOO_C301_GPIO_SPI_CS1 12 -+ -+#define QIHOO_C301_GPIO_EXTERNAL_LNA0 14 -+#define QIHOO_C301_GPIO_EXTERNAL_LNA1 15 -+ -+#define QIHOO_C301_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define QIHOO_C301_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * QIHOO_C301_KEYS_POLL_INTERVAL) -+ -+#define QIHOO_C301_WMAC_CALDATA_OFFSET 0x1000 -+ -+#define QIHOO_C301_NVRAM_ADDR 0x1f058010 -+#define QIHOO_C301_NVRAM_SIZE 0x7ff0 -+ -+static struct gpio_led qihoo_c301_leds_gpio[] __initdata = { -+ { -+ .name = "qihoo:green:status", -+ .gpio = QIHOO_C301_GPIO_LED_STATUS_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "qihoo:red:status", -+ .gpio = QIHOO_C301_GPIO_LED_STATUS_RED, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button qihoo_c301_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = QIHOO_C301_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = QIHOO_C301_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct flash_platform_data flash __initdata = {NULL, NULL, 0}; -+ -+static void qihoo_c301_get_mac(const char *name, char *mac) -+{ -+ u8 *nvram = (u8 *) KSEG1ADDR(QIHOO_C301_NVRAM_ADDR); -+ int err; -+ -+ err = ath79_nvram_parse_mac_addr(nvram, QIHOO_C301_NVRAM_SIZE, -+ name, mac); -+ if (err) -+ pr_err("no MAC address found for %s\n", name); -+} -+ -+static void __init qihoo_c301_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 tmpmac[ETH_ALEN]; -+ -+ ath79_register_m25p80_multi(&flash); -+ -+ ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE); -+ -+ ath79_gpio_output_select(QIHOO_C301_GPIO_LED_WAN, -+ AR934X_GPIO_OUT_LED_LINK4); -+ ath79_gpio_output_select(QIHOO_C301_GPIO_LED_LAN1, -+ AR934X_GPIO_OUT_LED_LINK1); -+ ath79_gpio_output_select(QIHOO_C301_GPIO_LED_LAN2, -+ AR934X_GPIO_OUT_LED_LINK2); -+ -+ ath79_gpio_output_select(QIHOO_C301_GPIO_SPI_CS1, -+ AR934X_GPIO_OUT_SPI_CS1); -+ -+ gpio_request_one(QIHOO_C301_GPIO_ETH_LEN_EN, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "Ethernet LED enable"); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(qihoo_c301_leds_gpio), -+ qihoo_c301_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, QIHOO_C301_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(qihoo_c301_gpio_keys), -+ qihoo_c301_gpio_keys); -+ -+ ath79_wmac_set_ext_lna_gpio(0, QIHOO_C301_GPIO_EXTERNAL_LNA0); -+ ath79_wmac_set_ext_lna_gpio(1, QIHOO_C301_GPIO_EXTERNAL_LNA1); -+ -+ qihoo_c301_get_mac("wlan24mac=", tmpmac); -+ ath79_register_wmac(art + QIHOO_C301_WMAC_CALDATA_OFFSET, tmpmac); -+ -+ ath79_register_pci(); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_ONLY_MODE | -+ AR934X_ETH_CFG_SW_PHY_SWAP); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ /* LAN */ -+ qihoo_c301_get_mac("lanmac=", ath79_eth1_data.mac_addr); -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ qihoo_c301_get_mac("wanmac=", ath79_eth0_data.mac_addr); -+ -+ /* GMAC0 is connected to the PHY4 of the internal switch */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(0); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ -+ ath79_register_eth(0); -+ -+ gpio_request_one(QIHOO_C301_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_QIHOO_C301, "QIHOO-C301", "Qihoo 360 C301", -+ qihoo_c301_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-r36a.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-r36a.c -new file mode 100644 -index 0000000000..b3493e2c42 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-r36a.c -@@ -0,0 +1,140 @@ -+/* -+ * ALFA Network R36A board support -+ * -+ * Copyright (C) 2018 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define R36A_GPIO_LED_LAN 4 -+#define R36A_GPIO_LED_STATUS 14 -+#define R36A_GPIO_LED_USB 12 -+#define R36A_GPIO_LED_WAN 16 -+#define R36A_GPIO_LED_WLAN 15 -+ -+#define R36A_GPIO_WDT_EN 1 -+#define R36A_GPIO_WDT_IN 0 -+#define R36A_GPIO_USB_PWR 3 -+ -+#define R36A_GPIO_BTN_RESET 2 -+#define R36A_GPIO_BTN_RFKILL 17 -+ -+#define R36A_KEYS_POLL_INTERVAL 20 -+#define R36A_KEYS_DEBOUNCE_INTERVAL (3 * R36A_KEYS_POLL_INTERVAL) -+ -+#define R36A_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led r36a_leds_gpio[] __initdata = { -+ { -+ .name = "r36a:blue:lan", -+ .gpio = R36A_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "r36a:blue:status", -+ .gpio = R36A_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "r36a:blue:usb", -+ .gpio = R36A_GPIO_LED_USB, -+ .active_low = 1, -+ }, { -+ .name = "r36a:blue:wan", -+ .gpio = R36A_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "r36a:blue:wlan", -+ .gpio = R36A_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button r36a_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = R36A_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = R36A_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "rfkill", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = R36A_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = R36A_GPIO_BTN_RFKILL, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init r36a_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1f070000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = 0xf7; -+ -+ /* LAN */ -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_init_mac(ath79_eth0_data.mac_addr, art, 0); -+ ath79_register_eth(0); -+ -+ /* WAN */ -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_init_mac(ath79_eth1_data.mac_addr, art, 1); -+ ath79_register_eth(1); -+ -+ /* Disable JTAG (enables GPIO0-3) */ -+ ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(r36a_leds_gpio), -+ r36a_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, R36A_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(r36a_gpio_keys), -+ r36a_gpio_keys); -+ -+ gpio_request_one(R36A_GPIO_WDT_IN, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "WDT input"); -+ -+ gpio_request_one(R36A_GPIO_WDT_EN, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "WDT enable"); -+ -+ gpio_request_one(R36A_GPIO_USB_PWR, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ -+ ath79_register_wmac(art + R36A_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_R36A, "R36A", "ALFA Network R36A", r36a_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-r602n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-r602n.c -new file mode 100644 -index 0000000000..4aef0a932a ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-r602n.c -@@ -0,0 +1,213 @@ -+/* -+ * P&W (Shenzhen Progress&Win Technologies) R602N and CPE505N boards support -+ * -+ * Copyright (C) 2017 Piotr Dymacz -+ * -+ * Based on mach-zbt-we1526.c -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define PW_GPIO_BTN_RESET 17 -+ -+#define PW_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define PW_KEYS_DEBOUNCE_INTERVAL (3 * PW_KEYS_POLL_INTERVAL) -+ -+#define PW_MAC0_OFFSET 0x0 -+#define PW_MAC1_OFFSET 0x6 -+#define PW_WMAC_CALDATA_OFFSET 0x1000 -+ -+/* CPE505N GPIO LEDs */ -+#define CPE505N_GPIO_LED_DIAG 12 -+#define CPE505N_GPIO_LED_LAN 11 -+#define CPE505N_GPIO_LED_STATUS 14 -+#define CPE505N_GPIO_LED_WAN 4 -+#define CPE505N_GPIO_LED_WLAN 15 -+ -+static struct gpio_led cpe505n_leds_gpio[] __initdata = { -+ { -+ .name = "cpe505n:red:diag", -+ .gpio = CPE505N_GPIO_LED_DIAG, -+ .active_low = 1, -+ }, { -+ .name = "cpe505n:green:lan", -+ .gpio = CPE505N_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "cpe505n:green:status", -+ .gpio = CPE505N_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "cpe505n:green:wan", -+ .gpio = CPE505N_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "cpe505n:blue:wlan", -+ .gpio = CPE505N_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init cpe505n_gpio_setup(void) -+{ -+ /* For LED on GPIO4 */ -+ ath79_gpio_function_disable(AR934X_GPIO_FUNC_CLK_OBS4_EN); -+ ath79_gpio_output_select(CPE505N_GPIO_LED_WAN, 0); -+ -+ ath79_gpio_direction_select(CPE505N_GPIO_LED_DIAG, true); -+ ath79_gpio_direction_select(CPE505N_GPIO_LED_LAN, true); -+ ath79_gpio_direction_select(CPE505N_GPIO_LED_STATUS, true); -+ ath79_gpio_direction_select(CPE505N_GPIO_LED_WAN, true); -+ ath79_gpio_direction_select(CPE505N_GPIO_LED_WLAN, true); -+ -+ /* Mute LEDs */ -+ gpio_set_value(CPE505N_GPIO_LED_DIAG, 1); -+ gpio_set_value(CPE505N_GPIO_LED_LAN, 1); -+ gpio_set_value(CPE505N_GPIO_LED_STATUS, 1); -+ gpio_set_value(CPE505N_GPIO_LED_WAN, 1); -+ gpio_set_value(CPE505N_GPIO_LED_WLAN, 1); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cpe505n_leds_gpio), -+ cpe505n_leds_gpio); -+} -+ -+/* R602N GPIO LEDs */ -+#define R602N_GPIO_LED_LAN1 16 -+#define R602N_GPIO_LED_LAN2 15 -+#define R602N_GPIO_LED_LAN3 14 -+#define R602N_GPIO_LED_LAN4 11 -+#define R602N_GPIO_LED_WAN 4 -+#define R602N_GPIO_LED_WLAN 12 -+ -+static struct gpio_led r602n_leds_gpio[] __initdata = { -+ { -+ .name = "r602n:green:lan1", -+ .gpio = R602N_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "r602n:green:lan2", -+ .gpio = R602N_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "r602n:green:lan3", -+ .gpio = R602N_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "r602n:green:lan4", -+ .gpio = R602N_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "r602n:green:wan", -+ .gpio = R602N_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "r602n:green:wlan", -+ .gpio = R602N_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init r602n_gpio_setup(void) -+{ -+ /* For LED on GPIO4 */ -+ ath79_gpio_function_disable(AR934X_GPIO_FUNC_CLK_OBS4_EN); -+ ath79_gpio_output_select(R602N_GPIO_LED_WAN, 0); -+ -+ ath79_gpio_direction_select(R602N_GPIO_LED_LAN1, true); -+ ath79_gpio_direction_select(R602N_GPIO_LED_LAN2, true); -+ ath79_gpio_direction_select(R602N_GPIO_LED_LAN3, true); -+ ath79_gpio_direction_select(R602N_GPIO_LED_LAN4, true); -+ ath79_gpio_direction_select(R602N_GPIO_LED_WAN, true); -+ ath79_gpio_direction_select(R602N_GPIO_LED_WLAN, true); -+ -+ /* Mute LEDs */ -+ gpio_set_value(R602N_GPIO_LED_LAN1, 1); -+ gpio_set_value(R602N_GPIO_LED_LAN2, 1); -+ gpio_set_value(R602N_GPIO_LED_LAN3, 1); -+ gpio_set_value(R602N_GPIO_LED_LAN4, 1); -+ gpio_set_value(R602N_GPIO_LED_WAN, 1); -+ gpio_set_value(R602N_GPIO_LED_WLAN, 1); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(r602n_leds_gpio), -+ r602n_leds_gpio); -+} -+ -+static struct gpio_keys_button pw_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = PW_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = PW_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init r602n_cpe505n_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN */ -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + PW_MAC1_OFFSET, 0); -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + PW_MAC0_OFFSET, 0); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(art + PW_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_gpio_keys_polled(-1, PW_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(pw_gpio_keys), -+ pw_gpio_keys); -+} -+ -+static void __init cpe505n_setup(void) -+{ -+ r602n_cpe505n_setup(); -+ -+ cpe505n_gpio_setup(); -+} -+ -+static void __init r602n_setup(void) -+{ -+ r602n_cpe505n_setup(); -+ -+ r602n_gpio_setup(); -+ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CPE505N, "CPE505N", "P&W CPE505N", cpe505n_setup); -+MIPS_MACHINE(ATH79_MACH_R602N, "R602N", "P&W R602N", r602n_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-r6100.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-r6100.c -new file mode 100644 -index 0000000000..c1f0e2c400 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-r6100.c -@@ -0,0 +1,146 @@ -+/* -+ * NETGEAR R6100 board support -+ * -+ * Copyright (C) 2014 Gabor Juhos -+ * Copyright (C) 2014 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-nfc.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define R6100_GPIO_LED_WLAN 0 -+#define R6100_GPIO_LED_USB 11 -+#define R6100_GPIO_LED_WAN_GREEN 13 -+#define R6100_GPIO_LED_POWER_AMBER 14 -+#define R6100_GPIO_LED_WAN_AMBER 15 -+#define R6100_GPIO_LED_POWER_GREEN 17 -+ -+#define R6100_GPIO_BTN_WIRELESS 1 -+#define R6100_GPIO_BTN_WPS 3 -+#define R6100_GPIO_BTN_RESET 12 -+ -+#define R6100_GPIO_USB_POWER 16 -+ -+#define R6100_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define R6100_KEYS_DEBOUNCE_INTERVAL (3 * R6100_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led r6100_leds_gpio[] __initdata = { -+ { -+ .name = "netgear:green:power", -+ .gpio = R6100_GPIO_LED_POWER_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:amber:power", -+ .gpio = R6100_GPIO_LED_POWER_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:green:wan", -+ .gpio = R6100_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:amber:wan", -+ .gpio = R6100_GPIO_LED_WAN_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:blue:usb", -+ .gpio = R6100_GPIO_LED_USB, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:blue:wlan", -+ .gpio = R6100_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button r6100_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = R6100_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = R6100_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = R6100_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = R6100_GPIO_BTN_WPS, -+ .active_low = 0, -+ }, -+ { -+ .desc = "RFKILL switch", -+ .type = EV_SW, -+ .code = KEY_RFKILL, -+ .debounce_interval = R6100_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = R6100_GPIO_BTN_WIRELESS, -+ .active_low = 0, -+ }, -+}; -+ -+static void __init r6100_setup(void) -+{ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(r6100_leds_gpio), -+ r6100_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, R6100_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(r6100_gpio_keys), -+ r6100_gpio_keys); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_PHY_SWAP); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ /* GMAC0 is connected to the PHY0 of the internal switch */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_register_eth(1); -+ -+ gpio_request_one(R6100_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ -+ ath79_nfc_set_ecc_mode(AR934X_NFC_ECC_HW); -+ ath79_register_nfc(); -+ -+ ath79_register_usb(); -+ -+ ath79_register_wmac_simple(); -+ -+ ap91_pci_init_simple(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_R6100, "R6100", "NETGEAR R6100", -+ r6100_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rambutan.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rambutan.c -new file mode 100644 -index 0000000000..1730a29f33 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rambutan.c -@@ -0,0 +1,92 @@ -+/* -+ * 8devices Rambutan board support -+ * -+ * Copyright (C) 2017 Mantas Pucka -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-nfc.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+static struct at803x_platform_data rambutan_ar8032_data = { -+ .has_reset_gpio = 1, -+ .reset_gpio = 17, -+}; -+ -+static struct mdio_board_info rambutan_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &rambutan_ar8032_data, -+ }, -+}; -+ -+static struct at803x_platform_data rambutan_ar8033_data = { -+ .has_reset_gpio = 1, -+ .override_sgmii_aneg = 1, -+ .reset_gpio = 23, -+}; -+ -+static struct mdio_board_info rambutan_mdio1_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.1", -+ .mdio_addr = 0, -+ .platform_data = &rambutan_ar8033_data, -+ }, -+}; -+ -+static void __init rambutan_setup(void) -+{ -+ ath79_nfc_set_ecc_mode(AR934X_NFC_ECC_HW); -+ ath79_register_nfc(); -+ ath79_register_usb(); -+ ath79_register_pci(); -+ ath79_register_wmac_simple(); -+ -+ mdiobus_register_board_info(rambutan_mdio0_info, -+ ARRAY_SIZE(rambutan_mdio0_info)); -+ mdiobus_register_board_info(rambutan_mdio1_info, -+ ARRAY_SIZE(rambutan_mdio1_info)); -+ ath79_register_mdio(0, 0x0); -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_register_eth(0); -+ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.phy_mask = BIT(0); -+ ath79_eth1_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_eth1_data.enable_sgmii_fixup = 1; -+ ath79_eth1_pll_data.pll_1000 = 0x17000000; -+ ath79_eth1_pll_data.pll_10 = 0x1313; -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RAMBUTAN, "RAMBUTAN", "8devices Rambutan board", -+ rambutan_setup); -+ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rb2011.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb2011.c -new file mode 100644 -index 0000000000..aee0fb2014 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb2011.c -@@ -0,0 +1,406 @@ -+/* -+ * MikroTik RouterBOARD 2011 support -+ * -+ * Copyright (C) 2012 Stijn Tintel -+ * Copyright (C) 2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#define pr_fmt(fmt) "rb2011: " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) -+#include -+#else -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-m25p80.h" -+#include "dev-nfc.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "routerboot.h" -+ -+#define RB2011_GPIO_NAND_NCE 14 -+#define RB2011_GPIO_SFP_LOS 21 -+ -+#define RB_ROUTERBOOT_OFFSET 0x0000 -+#define RB_ROUTERBOOT_MIN_SIZE 0xb000 -+#define RB_HARD_CFG_SIZE 0x1000 -+#define RB_BIOS_OFFSET 0xd000 -+#define RB_BIOS_SIZE 0x1000 -+#define RB_SOFT_CFG_OFFSET 0xf000 -+#define RB_SOFT_CFG_SIZE 0x1000 -+ -+#define RB_ART_SIZE 0x10000 -+ -+#define RB2011_FLAG_SFP BIT(0) -+#define RB2011_FLAG_USB BIT(1) -+#define RB2011_FLAG_WLAN BIT(2) -+ -+static struct mtd_partition rb2011_spi_partitions[] = { -+ { -+ .name = "routerboot", -+ .offset = RB_ROUTERBOOT_OFFSET, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "hard_config", -+ .size = RB_HARD_CFG_SIZE, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "bios", -+ .offset = RB_BIOS_OFFSET, -+ .size = RB_BIOS_SIZE, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "soft_config", -+ .size = RB_SOFT_CFG_SIZE, -+ } -+}; -+ -+static void __init rb2011_init_partitions(const struct rb_info *info) -+{ -+ rb2011_spi_partitions[0].size = info->hard_cfg_offs; -+ rb2011_spi_partitions[1].offset = info->hard_cfg_offs; -+ rb2011_spi_partitions[3].offset = info->soft_cfg_offs; -+} -+ -+static struct mtd_partition rb2011_nand_partitions[] = { -+ { -+ .name = "booter", -+ .offset = 0, -+ .size = (256 * 1024), -+ .mask_flags = MTD_WRITEABLE, -+ }, -+ { -+ .name = "kernel", -+ .offset = (256 * 1024), -+ .size = (4 * 1024 * 1024) - (256 * 1024), -+ }, -+ { -+ .name = "ubi", -+ .offset = MTDPART_OFS_NXTBLK, -+ .size = MTDPART_SIZ_FULL, -+ }, -+}; -+ -+static struct flash_platform_data rb2011_spi_flash_data = { -+ .parts = rb2011_spi_partitions, -+ .nr_parts = ARRAY_SIZE(rb2011_spi_partitions), -+}; -+ -+static struct ar8327_pad_cfg rb2011_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL3, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL0, -+}; -+ -+static struct ar8327_pad_cfg rb2011_ar8327_pad6_cfg; -+static struct ar8327_sgmii_cfg rb2011_ar8327_sgmii_cfg; -+ -+static struct ar8327_led_cfg rb2011_ar8327_led_cfg = { -+ .led_ctrl0 = 0xc731c731, -+ .led_ctrl1 = 0x00000000, -+ .led_ctrl2 = 0x00000000, -+ .led_ctrl3 = 0x0030c300, -+ .open_drain = false, -+}; -+ -+static const struct ar8327_led_info rb2011_ar8327_leds[] = { -+ AR8327_LED_INFO(PHY0_0, HW, "rb:green:eth1"), -+ AR8327_LED_INFO(PHY1_0, HW, "rb:green:eth2"), -+ AR8327_LED_INFO(PHY2_0, HW, "rb:green:eth3"), -+ AR8327_LED_INFO(PHY3_0, HW, "rb:green:eth4"), -+ AR8327_LED_INFO(PHY4_0, HW, "rb:green:eth5"), -+ AR8327_LED_INFO(PHY0_1, SW, "rb:green:eth6"), -+ AR8327_LED_INFO(PHY1_1, SW, "rb:green:eth7"), -+ AR8327_LED_INFO(PHY2_1, SW, "rb:green:eth8"), -+ AR8327_LED_INFO(PHY3_1, SW, "rb:green:eth9"), -+ AR8327_LED_INFO(PHY4_1, SW, "rb:green:eth10"), -+ AR8327_LED_INFO(PHY4_2, SW, "rb:green:usr"), -+}; -+ -+static struct ar8327_platform_data rb2011_ar8327_data = { -+ .pad0_cfg = &rb2011_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &rb2011_ar8327_led_cfg, -+ .num_leds = ARRAY_SIZE(rb2011_ar8327_leds), -+ .leds = rb2011_ar8327_leds, -+}; -+ -+static struct mdio_board_info rb2011_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &rb2011_ar8327_data, -+ }, -+}; -+ -+static void __init rb2011_wlan_init(void) -+{ -+ char *art_buf; -+ u8 wlan_mac[ETH_ALEN]; -+ -+ art_buf = rb_get_wlan_data(); -+ if (art_buf == NULL) -+ return; -+ -+ ath79_init_mac(wlan_mac, ath79_mac_base, 11); -+ ath79_register_wmac(art_buf + 0x1000, wlan_mac); -+ -+ kfree(art_buf); -+} -+ -+static void rb2011_nand_select_chip(int chip_no) -+{ -+ switch (chip_no) { -+ case 0: -+ gpio_set_value(RB2011_GPIO_NAND_NCE, 0); -+ break; -+ default: -+ gpio_set_value(RB2011_GPIO_NAND_NCE, 1); -+ break; -+ } -+ ndelay(500); -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+static struct nand_ecclayout rb2011_nand_ecclayout = { -+ .eccbytes = 6, -+ .eccpos = { 8, 9, 10, 13, 14, 15 }, -+ .oobavail = 9, -+ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } -+}; -+ -+#else -+ -+static int rb2011_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 8; -+ oobregion->length = 3; -+ return 0; -+ case 1: -+ oobregion->offset = 13; -+ oobregion->length = 3; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static int rb2011_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 0; -+ oobregion->length = 4; -+ return 0; -+ case 1: -+ oobregion->offset = 4; -+ oobregion->length = 1; -+ return 0; -+ case 2: -+ oobregion->offset = 6; -+ oobregion->length = 2; -+ return 0; -+ case 3: -+ oobregion->offset = 11; -+ oobregion->length = 2; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static const struct mtd_ooblayout_ops rb2011_nand_ecclayout_ops = { -+ .ecc = rb2011_ooblayout_ecc, -+ .free = rb2011_ooblayout_free, -+}; -+#endif /* < 4.6 */ -+ -+static int rb2011_nand_scan_fixup(struct mtd_info *mtd) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ struct nand_chip *chip = mtd->priv; -+#else -+ struct nand_chip *chip = mtd_to_nand(mtd); -+#endif /* < 4.6.0 */ -+ -+ if (mtd->writesize == 512) { -+ /* -+ * Use the OLD Yaffs-1 OOB layout, otherwise RouterBoot -+ * will not be able to find the kernel that we load. -+ */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ chip->ecc.layout = &rb2011_nand_ecclayout; -+#else -+ mtd_set_ooblayout(mtd, &rb2011_nand_ecclayout_ops); -+#endif -+ } -+ -+ chip->options = NAND_NO_SUBPAGE_WRITE; -+ -+ return 0; -+} -+ -+static void __init rb2011_nand_init(void) -+{ -+ gpio_request_one(RB2011_GPIO_NAND_NCE, GPIOF_OUT_INIT_HIGH, "NAND nCE"); -+ -+ ath79_nfc_set_scan_fixup(rb2011_nand_scan_fixup); -+ ath79_nfc_set_parts(rb2011_nand_partitions, -+ ARRAY_SIZE(rb2011_nand_partitions)); -+ ath79_nfc_set_select_chip(rb2011_nand_select_chip); -+ ath79_nfc_set_swap_dma(true); -+ ath79_register_nfc(); -+} -+ -+static int rb2011_get_port_link(unsigned port) -+{ -+ if (port != 6) -+ return -EINVAL; -+ -+ /* The Loss of signal line is active low */ -+ return !gpio_get_value(RB2011_GPIO_SFP_LOS); -+} -+ -+static void __init rb2011_sfp_init(void) -+{ -+ gpio_request_one(RB2011_GPIO_SFP_LOS, GPIOF_IN, "SFP LOS"); -+ -+ rb2011_ar8327_pad6_cfg.mode = AR8327_PAD_MAC_SGMII; -+ -+ rb2011_ar8327_data.pad6_cfg = &rb2011_ar8327_pad6_cfg; -+ -+ rb2011_ar8327_sgmii_cfg.sgmii_ctrl = 0xc70167d0; -+ rb2011_ar8327_sgmii_cfg.serdes_aen = true; -+ -+ rb2011_ar8327_data.sgmii_cfg = &rb2011_ar8327_sgmii_cfg; -+ -+ rb2011_ar8327_data.port6_cfg.force_link = 1; -+ rb2011_ar8327_data.port6_cfg.speed = AR8327_PORT_SPEED_1000; -+ rb2011_ar8327_data.port6_cfg.duplex = 1; -+ -+ rb2011_ar8327_data.get_port_link = rb2011_get_port_link; -+} -+ -+static int __init rb2011_setup(u32 flags) -+{ -+ const struct rb_info *info; -+ char buf[64]; -+ -+ info = rb_init_info((void *) KSEG1ADDR(0x1f000000), 0x10000); -+ if (!info) -+ return -ENODEV; -+ -+ scnprintf(buf, sizeof(buf), "Mikrotik RouterBOARD %s", -+ (info->board_name) ? info->board_name : ""); -+ mips_set_machine_name(buf); -+ -+ rb2011_init_partitions(info); -+ -+ ath79_register_m25p80(&rb2011_spi_flash_data); -+ rb2011_nand_init(); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_RXD_DELAY | -+ AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_register_mdio(1, 0x0); -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(rb2011_mdio0_info, -+ ARRAY_SIZE(rb2011_mdio0_info)); -+ -+ /* GMAC0 is connected to an ar8327 switch */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x6f000000; -+ -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 5); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(1); -+ -+ if (flags & RB2011_FLAG_SFP) -+ rb2011_sfp_init(); -+ -+ if (flags & RB2011_FLAG_WLAN) -+ rb2011_wlan_init(); -+ -+ if (flags & RB2011_FLAG_USB) -+ ath79_register_usb(); -+ -+ return 0; -+} -+ -+static void __init rb2011l_setup(void) -+{ -+ rb2011_setup(0); -+} -+ -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_2011L, "2011L", rb2011l_setup); -+ -+static void __init rb2011us_setup(void) -+{ -+ rb2011_setup(RB2011_FLAG_SFP | RB2011_FLAG_USB); -+} -+ -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_2011US, "2011US", rb2011us_setup); -+ -+static void __init rb2011r5_setup(void) -+{ -+ rb2011_setup(RB2011_FLAG_SFP | RB2011_FLAG_USB | RB2011_FLAG_WLAN); -+} -+ -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_2011R5, "2011r5", rb2011r5_setup); -+ -+static void __init rb2011g_setup(void) -+{ -+ rb2011_setup(RB2011_FLAG_SFP | -+ RB2011_FLAG_USB | -+ RB2011_FLAG_WLAN); -+} -+ -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_2011G, "2011G", rb2011g_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rb4xx.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb4xx.c -new file mode 100644 -index 0000000000..edf90e1872 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb4xx.c -@@ -0,0 +1,465 @@ -+/* -+ * MikroTik RouterBOARD 4xx series support -+ * -+ * Copyright (C) 2008-2012 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define RB4XX_GPIO_USER_LED 4 -+#define RB4XX_GPIO_RESET_SWITCH 7 -+ -+#define RB4XX_GPIO_CPLD_BASE 32 -+#define RB4XX_GPIO_CPLD_LED1 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED1) -+#define RB4XX_GPIO_CPLD_LED2 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED2) -+#define RB4XX_GPIO_CPLD_LED3 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED3) -+#define RB4XX_GPIO_CPLD_LED4 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED4) -+#define RB4XX_GPIO_CPLD_LED5 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED5) -+ -+#define RB4XX_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define RB4XX_KEYS_DEBOUNCE_INTERVAL (3 * RB4XX_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led rb4xx_leds_gpio[] __initdata = { -+ { -+ .name = "rb4xx:yellow:user", -+ .gpio = RB4XX_GPIO_USER_LED, -+ .active_low = 0, -+ }, { -+ .name = "rb4xx:green:led1", -+ .gpio = RB4XX_GPIO_CPLD_LED1, -+ .active_low = 1, -+ }, { -+ .name = "rb4xx:green:led2", -+ .gpio = RB4XX_GPIO_CPLD_LED2, -+ .active_low = 1, -+ }, { -+ .name = "rb4xx:green:led3", -+ .gpio = RB4XX_GPIO_CPLD_LED3, -+ .active_low = 1, -+ }, { -+ .name = "rb4xx:green:led4", -+ .gpio = RB4XX_GPIO_CPLD_LED4, -+ .active_low = 1, -+ }, { -+ .name = "rb4xx:green:led5", -+ .gpio = RB4XX_GPIO_CPLD_LED5, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button rb4xx_gpio_keys[] __initdata = { -+ { -+ .desc = "reset_switch", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = RB4XX_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = RB4XX_GPIO_RESET_SWITCH, -+ .active_low = 1, -+ } -+}; -+ -+static struct platform_device rb4xx_nand_device = { -+ .name = "rb4xx-nand", -+ .id = -1, -+}; -+ -+static struct ath79_pci_irq rb4xx_pci_irqs[] = { -+ { -+ .slot = 17, -+ .pin = 1, -+ .irq = ATH79_PCI_IRQ(2), -+ }, { -+ .slot = 18, -+ .pin = 1, -+ .irq = ATH79_PCI_IRQ(0), -+ }, { -+ .slot = 18, -+ .pin = 2, -+ .irq = ATH79_PCI_IRQ(1), -+ }, { -+ .slot = 19, -+ .pin = 1, -+ .irq = ATH79_PCI_IRQ(1), -+ }, { -+ .slot = 19, -+ .pin = 2, -+ .irq = ATH79_PCI_IRQ(2), -+ }, { -+ .slot = 20, -+ .pin = 1, -+ .irq = ATH79_PCI_IRQ(2), -+ }, { -+ .slot = 20, -+ .pin = 2, -+ .irq = ATH79_PCI_IRQ(0), -+ }, { -+ .slot = 21, -+ .pin = 1, -+ .irq = ATH79_PCI_IRQ(0), -+ }, { -+ .slot = 22, -+ .pin = 1, -+ .irq = ATH79_PCI_IRQ(1), -+ }, { -+ .slot = 22, -+ .pin = 2, -+ .irq = ATH79_PCI_IRQ(2), -+ }, { -+ .slot = 23, -+ .pin = 1, -+ .irq = ATH79_PCI_IRQ(2), -+ }, { -+ .slot = 23, -+ .pin = 2, -+ .irq = ATH79_PCI_IRQ(0), -+ } -+}; -+ -+static struct mtd_partition rb4xx_partitions[] = { -+ { -+ .name = "routerboot", -+ .offset = 0, -+ .size = 0x0b000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "hard_config", -+ .offset = 0x0b000, -+ .size = 0x01000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "bios", -+ .offset = 0x0d000, -+ .size = 0x02000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "soft_config", -+ .offset = 0x0f000, -+ .size = 0x01000, -+ } -+}; -+ -+static struct flash_platform_data rb4xx_flash_data = { -+ .type = "pm25lv512", -+ .parts = rb4xx_partitions, -+ .nr_parts = ARRAY_SIZE(rb4xx_partitions), -+}; -+ -+static struct rb4xx_cpld_platform_data rb4xx_cpld_data = { -+ .gpio_base = RB4XX_GPIO_CPLD_BASE, -+}; -+ -+static struct mmc_spi_platform_data rb4xx_mmc_data = { -+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, -+}; -+ -+static struct spi_board_info rb4xx_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ .platform_data = &rb4xx_flash_data, -+ }, { -+ .bus_num = 0, -+ .chip_select = 1, -+ .max_speed_hz = 25000000, -+ .modalias = "spi-rb4xx-cpld", -+ .platform_data = &rb4xx_cpld_data, -+ } -+}; -+ -+static struct spi_board_info rb4xx_microsd_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 2, -+ .max_speed_hz = 25000000, -+ .modalias = "mmc_spi", -+ .platform_data = &rb4xx_mmc_data, -+ } -+}; -+ -+ -+static struct resource rb4xx_spi_resources[] = { -+ { -+ .start = AR71XX_SPI_BASE, -+ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+}; -+ -+static struct platform_device rb4xx_spi_device = { -+ .name = "rb4xx-spi", -+ .id = -1, -+ .resource = rb4xx_spi_resources, -+ .num_resources = ARRAY_SIZE(rb4xx_spi_resources), -+}; -+ -+static void __init rb4xx_generic_setup(void) -+{ -+ ath79_gpio_function_enable(AR71XX_GPIO_FUNC_SPI_CS1_EN | -+ AR71XX_GPIO_FUNC_SPI_CS2_EN); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rb4xx_leds_gpio), -+ rb4xx_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, RB4XX_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(rb4xx_gpio_keys), -+ rb4xx_gpio_keys); -+ -+ spi_register_board_info(rb4xx_spi_info, ARRAY_SIZE(rb4xx_spi_info)); -+ platform_device_register(&rb4xx_spi_device); -+ platform_device_register(&rb4xx_nand_device); -+} -+ -+static void __init rb411_setup(void) -+{ -+ rb4xx_generic_setup(); -+ spi_register_board_info(rb4xx_microsd_info, -+ ARRAY_SIZE(rb4xx_microsd_info)); -+ -+ ath79_register_mdio(0, 0xfffffffc); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = 0x00000003; -+ -+ ath79_register_eth(0); -+ -+ ath79_pci_set_irq_map(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RB_411, "411", "MikroTik RouterBOARD 411/A/AH", -+ rb411_setup); -+ -+static void __init rb411u_setup(void) -+{ -+ rb411_setup(); -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RB_411U, "411U", "MikroTik RouterBOARD 411U", -+ rb411u_setup); -+ -+#define RB433_LAN_PHYMASK BIT(0) -+#define RB433_WAN_PHYMASK BIT(4) -+#define RB433_MDIO_PHYMASK (RB433_LAN_PHYMASK | RB433_WAN_PHYMASK) -+ -+static void __init rb433_setup(void) -+{ -+ rb4xx_generic_setup(); -+ spi_register_board_info(rb4xx_microsd_info, -+ ARRAY_SIZE(rb4xx_microsd_info)); -+ -+ ath79_register_mdio(0, ~RB433_MDIO_PHYMASK); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 1); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = RB433_LAN_PHYMASK; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth1_data.phy_mask = RB433_WAN_PHYMASK; -+ -+ ath79_register_eth(1); -+ ath79_register_eth(0); -+ -+ ath79_pci_set_irq_map(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RB_433, "433", "MikroTik RouterBOARD 433/AH", -+ rb433_setup); -+ -+static void __init rb433u_setup(void) -+{ -+ rb433_setup(); -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RB_433U, "433U", "MikroTik RouterBOARD 433UAH", -+ rb433u_setup); -+ -+static void __init rb435g_setup(void) -+{ -+ rb4xx_generic_setup(); -+ -+ spi_register_board_info(rb4xx_microsd_info, -+ ARRAY_SIZE(rb4xx_microsd_info)); -+ -+ ath79_register_mdio(0, ~RB433_MDIO_PHYMASK); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 1); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = RB433_LAN_PHYMASK; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth1_data.phy_mask = RB433_WAN_PHYMASK; -+ -+ ath79_register_eth(1); -+ ath79_register_eth(0); -+ -+ ath79_pci_set_irq_map(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); -+ ath79_register_pci(); -+ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RB_435G, "435G", "MikroTik RouterBOARD 435G", -+ rb435g_setup); -+ -+#define RB450_LAN_PHYMASK BIT(0) -+#define RB450_WAN_PHYMASK BIT(4) -+#define RB450_MDIO_PHYMASK (RB450_LAN_PHYMASK | RB450_WAN_PHYMASK) -+ -+static void __init rb450_generic_setup(int gige) -+{ -+ rb4xx_generic_setup(); -+ ath79_register_mdio(0, ~RB450_MDIO_PHYMASK); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 1); -+ ath79_eth0_data.phy_if_mode = (gige) ? -+ PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = RB450_LAN_PHYMASK; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth1_data.phy_if_mode = (gige) ? -+ PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_RMII; -+ ath79_eth1_data.phy_mask = RB450_WAN_PHYMASK; -+ -+ ath79_register_eth(1); -+ ath79_register_eth(0); -+} -+ -+static void __init rb450_setup(void) -+{ -+ rb450_generic_setup(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RB_450, "450", "MikroTik RouterBOARD 450", -+ rb450_setup); -+ -+static void __init rb450g_setup(void) -+{ -+ rb450_generic_setup(1); -+ spi_register_board_info(rb4xx_microsd_info, -+ ARRAY_SIZE(rb4xx_microsd_info)); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RB_450G, "450G", "MikroTik RouterBOARD 450G", -+ rb450g_setup); -+ -+static void __init rb493_setup(void) -+{ -+ rb4xx_generic_setup(); -+ -+ ath79_register_mdio(0, 0x3fffff00); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth1_data.phy_mask = 0x00000001; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_pci_set_irq_map(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RB_493, "493", "MikroTik RouterBOARD 493/AH", -+ rb493_setup); -+ -+#define RB493G_GPIO_MDIO_MDC 7 -+#define RB493G_GPIO_MDIO_DATA 8 -+ -+#define RB493G_MDIO_PHYMASK BIT(0) -+ -+static struct mdio_gpio_platform_data rb493g_mdio_data = { -+ .mdc = RB493G_GPIO_MDIO_MDC, -+ .mdio = RB493G_GPIO_MDIO_DATA, -+ -+ .phy_mask = ~RB493G_MDIO_PHYMASK, -+}; -+ -+static struct platform_device rb493g_mdio_device = { -+ .name = "mdio-gpio", -+ .id = -1, -+ .dev = { -+ .platform_data = &rb493g_mdio_data, -+ }, -+}; -+ -+static void __init rb493g_setup(void) -+{ -+ ath79_gpio_function_enable(AR71XX_GPIO_FUNC_SPI_CS1_EN | -+ AR71XX_GPIO_FUNC_SPI_CS2_EN); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rb4xx_leds_gpio), -+ rb4xx_leds_gpio); -+ -+ spi_register_board_info(rb4xx_spi_info, ARRAY_SIZE(rb4xx_spi_info)); -+ spi_register_board_info(rb4xx_microsd_info, -+ ARRAY_SIZE(rb4xx_microsd_info)); -+ -+ platform_device_register(&rb4xx_spi_device); -+ platform_device_register(&rb4xx_nand_device); -+ -+ ath79_register_mdio(0, ~RB493G_MDIO_PHYMASK); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = RB493G_MDIO_PHYMASK; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth1_data.mii_bus_dev = &rb493g_mdio_device.dev; -+ ath79_eth1_data.phy_mask = RB493G_MDIO_PHYMASK; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ platform_device_register(&rb493g_mdio_device); -+ -+ ath79_register_eth(1); -+ ath79_register_eth(0); -+ -+ ath79_register_usb(); -+ -+ ath79_pci_set_irq_map(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RB_493G, "493G", "MikroTik RouterBOARD 493G", -+ rb493g_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rb750.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb750.c -new file mode 100644 -index 0000000000..0ec94a80e3 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb750.c -@@ -0,0 +1,349 @@ -+/* -+ * MikroTik RouterBOARD 750/750GL support -+ * -+ * Copyright (C) 2010-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-usb.h" -+#include "dev-eth.h" -+#include "machtypes.h" -+#include "routerboot.h" -+ -+static struct rb750_led_data rb750_leds[] = { -+ { -+ .name = "rb750:green:act", -+ .mask = RB750_LED_ACT, -+ .active_low = 1, -+ }, { -+ .name = "rb750:green:port1", -+ .mask = RB750_LED_PORT5, -+ .active_low = 1, -+ }, { -+ .name = "rb750:green:port2", -+ .mask = RB750_LED_PORT4, -+ .active_low = 1, -+ }, { -+ .name = "rb750:green:port3", -+ .mask = RB750_LED_PORT3, -+ .active_low = 1, -+ }, { -+ .name = "rb750:green:port4", -+ .mask = RB750_LED_PORT2, -+ .active_low = 1, -+ }, { -+ .name = "rb750:green:port5", -+ .mask = RB750_LED_PORT1, -+ .active_low = 1, -+ } -+}; -+ -+static struct rb750_led_data rb750gr3_leds[] = { -+ { -+ .name = "rb750:green:act", -+ .mask = RB7XX_LED_ACT, -+ .active_low = 1, -+ }, -+}; -+ -+static struct rb750_led_platform_data rb750_leds_data; -+static struct platform_device rb750_leds_device = { -+ .name = "leds-rb750", -+ .dev = { -+ .platform_data = &rb750_leds_data, -+ } -+}; -+ -+static struct rb7xx_nand_platform_data rb750_nand_data; -+static struct platform_device rb750_nand_device = { -+ .name = "rb750-nand", -+ .id = -1, -+ .dev = { -+ .platform_data = &rb750_nand_data, -+ } -+}; -+ -+static void rb750_latch_change(u32 mask_clr, u32 mask_set) -+{ -+ static DEFINE_SPINLOCK(lock); -+ static u32 latch_set = RB750_LED_BITS | RB750_LVC573_LE; -+ static u32 latch_oe; -+ static u32 latch_clr; -+ unsigned long flags; -+ u32 t; -+ -+ spin_lock_irqsave(&lock, flags); -+ -+ if ((mask_clr & BIT(31)) != 0 && -+ (latch_set & RB750_LVC573_LE) == 0) { -+ goto unlock; -+ } -+ -+ latch_set = (latch_set | mask_set) & ~mask_clr; -+ latch_clr = (latch_clr | mask_clr) & ~mask_set; -+ -+ if (latch_oe == 0) -+ latch_oe = __raw_readl(ath79_gpio_base + AR71XX_GPIO_REG_OE); -+ -+ if (likely(latch_set & RB750_LVC573_LE)) { -+ void __iomem *base = ath79_gpio_base; -+ -+ t = __raw_readl(base + AR71XX_GPIO_REG_OE); -+ t |= mask_clr | latch_oe | mask_set; -+ -+ __raw_writel(t, base + AR71XX_GPIO_REG_OE); -+ __raw_writel(latch_clr, base + AR71XX_GPIO_REG_CLEAR); -+ __raw_writel(latch_set, base + AR71XX_GPIO_REG_SET); -+ } else if (mask_clr & RB750_LVC573_LE) { -+ void __iomem *base = ath79_gpio_base; -+ -+ latch_oe = __raw_readl(base + AR71XX_GPIO_REG_OE); -+ __raw_writel(RB750_LVC573_LE, base + AR71XX_GPIO_REG_CLEAR); -+ /* flush write */ -+ __raw_readl(base + AR71XX_GPIO_REG_CLEAR); -+ } -+ -+unlock: -+ spin_unlock_irqrestore(&lock, flags); -+} -+ -+static void rb750_nand_enable_pins(void) -+{ -+ rb750_latch_change(RB750_LVC573_LE, 0); -+ ath79_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE, -+ AR724X_GPIO_FUNC_SPI_EN); -+} -+ -+static void rb750_nand_disable_pins(void) -+{ -+ ath79_gpio_function_setup(AR724X_GPIO_FUNC_SPI_EN, -+ AR724X_GPIO_FUNC_JTAG_DISABLE); -+ rb750_latch_change(0, RB750_LVC573_LE); -+} -+ -+static void __init rb750_setup(void) -+{ -+ ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN ports */ -+ ath79_register_eth(1); -+ -+ /* WAN port */ -+ ath79_register_eth(0); -+ -+ rb750_leds_data.num_leds = ARRAY_SIZE(rb750_leds); -+ rb750_leds_data.leds = rb750_leds; -+ rb750_leds_data.latch_change = rb750_latch_change; -+ platform_device_register(&rb750_leds_device); -+ -+ rb750_nand_data.nce_line = RB750_NAND_NCE; -+ rb750_nand_data.enable_pins = rb750_nand_enable_pins; -+ rb750_nand_data.disable_pins = rb750_nand_disable_pins; -+ rb750_nand_data.latch_change = rb750_latch_change; -+ platform_device_register(&rb750_nand_device); -+ -+ /* USB */ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RB_750, "750i", "MikroTik RouterBOARD 750", -+ rb750_setup); -+ -+static struct ar8327_pad_cfg rb750gr3_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_platform_data rb750gr3_ar8327_data = { -+ .pad0_cfg = &rb750gr3_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ } -+}; -+ -+static struct mdio_board_info rb750g3_mdio_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &rb750gr3_ar8327_data, -+ }, -+}; -+ -+static void rb750gr3_nand_enable_pins(void) -+{ -+ ath79_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE, -+ AR724X_GPIO_FUNC_SPI_EN | -+ AR724X_GPIO_FUNC_SPI_CS_EN2); -+} -+ -+static void rb750gr3_nand_disable_pins(void) -+{ -+ ath79_gpio_function_setup(AR724X_GPIO_FUNC_SPI_EN | -+ AR724X_GPIO_FUNC_SPI_CS_EN2, -+ AR724X_GPIO_FUNC_JTAG_DISABLE); -+} -+ -+static void rb750gr3_latch_change(u32 mask_clr, u32 mask_set) -+{ -+ static DEFINE_SPINLOCK(lock); -+ static u32 latch_set = RB7XX_LED_ACT; -+ static u32 latch_clr; -+ void __iomem *base = ath79_gpio_base; -+ unsigned long flags; -+ u32 t; -+ -+ spin_lock_irqsave(&lock, flags); -+ -+ latch_set = (latch_set | mask_set) & ~mask_clr; -+ latch_clr = (latch_clr | mask_clr) & ~mask_set; -+ -+ mask_set = latch_set & (RB7XX_USB_POWERON | RB7XX_MONITOR); -+ mask_clr = latch_clr & (RB7XX_USB_POWERON | RB7XX_MONITOR); -+ -+ if ((latch_set ^ RB7XX_LED_ACT) & RB7XX_LED_ACT) { -+ /* enable output mode */ -+ t = __raw_readl(base + AR71XX_GPIO_REG_OE); -+ t |= RB7XX_LED_ACT; -+ __raw_writel(t, base + AR71XX_GPIO_REG_OE); -+ -+ mask_clr |= RB7XX_LED_ACT; -+ } else { -+ /* disable output mode */ -+ t = __raw_readl(base + AR71XX_GPIO_REG_OE); -+ t &= ~RB7XX_LED_ACT; -+ __raw_writel(t, base + AR71XX_GPIO_REG_OE); -+ } -+ -+ __raw_writel(mask_set, base + AR71XX_GPIO_REG_SET); -+ __raw_writel(mask_clr, base + AR71XX_GPIO_REG_CLEAR); -+ -+ spin_unlock_irqrestore(&lock, flags); -+} -+ -+static void __init rb750gr3_setup(void) -+{ -+ ath79_register_mdio(0, 0x0); -+ mdiobus_register_board_info(rb750g3_mdio_info, -+ ARRAY_SIZE(rb750g3_mdio_info)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_pll_data.pll_1000 = 0x62000000; -+ -+ ath79_register_eth(0); -+ -+ rb750_leds_data.num_leds = ARRAY_SIZE(rb750gr3_leds); -+ rb750_leds_data.leds = rb750gr3_leds; -+ rb750_leds_data.latch_change = rb750gr3_latch_change; -+ platform_device_register(&rb750_leds_device); -+ -+ rb750_nand_data.nce_line = RB7XX_NAND_NCE; -+ rb750_nand_data.enable_pins = rb750gr3_nand_enable_pins; -+ rb750_nand_data.disable_pins = rb750gr3_nand_disable_pins; -+ rb750_nand_data.latch_change = rb750gr3_latch_change; -+ platform_device_register(&rb750_nand_device); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RB_750G_R3, "750Gr3", "MikroTik RouterBOARD 750GL", -+ rb750gr3_setup); -+ -+#define RB751_HARDCONFIG 0x1f00b000 -+#define RB751_HARDCONFIG_SIZE 0x1000 -+ -+static void __init rb751_wlan_setup(void) -+{ -+ u8 *hardconfig = (u8 *) KSEG1ADDR(RB751_HARDCONFIG); -+ struct ath9k_platform_data *wmac_data; -+ u16 tag_len; -+ u8 *tag; -+ u16 mac_len; -+ u8 *mac; -+ int err; -+ -+ wmac_data = ap9x_pci_get_wmac_data(0); -+ if (!wmac_data) { -+ pr_err("rb75x: unable to get address of wlan data\n"); -+ return; -+ } -+ -+ ap9x_pci_setup_wmac_led_pin(0, 9); -+ -+ err = routerboot_find_tag(hardconfig, RB751_HARDCONFIG_SIZE, -+ RB_ID_WLAN_DATA, &tag, &tag_len); -+ if (err) { -+ pr_err("rb75x: no calibration data found\n"); -+ return; -+ } -+ -+ err = rle_decode(tag, tag_len, (unsigned char *) wmac_data->eeprom_data, -+ sizeof(wmac_data->eeprom_data), NULL, NULL); -+ if (err) { -+ pr_err("rb75x: unable to decode wlan eeprom data\n"); -+ return; -+ } -+ -+ err = routerboot_find_tag(hardconfig, RB751_HARDCONFIG_SIZE, -+ RB_ID_MAC_ADDRESS_PACK, &mac, &mac_len); -+ if (err) { -+ pr_err("rb75x: no mac address found\n"); -+ return; -+ } -+ -+ ap91_pci_init(NULL, mac); -+} -+ -+static void __init rb751_setup(void) -+{ -+ rb750_setup(); -+ ath79_register_usb(); -+ rb751_wlan_setup(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RB_751, "751", "MikroTik RouterBOARD 751", -+ rb751_setup); -+ -+static void __init rb751g_setup(void) -+{ -+ rb750gr3_setup(); -+ ath79_register_usb(); -+ rb751_wlan_setup(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RB_751G, "751g", "MikroTik RouterBOARD 751G", -+ rb751g_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rb91x.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb91x.c -new file mode 100644 -index 0000000000..9620718962 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb91x.c -@@ -0,0 +1,348 @@ -+/* -+ * MikroTik RouterBOARD 91X support -+ * -+ * Copyright (C) 2013 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#define pr_fmt(fmt) "rb91x: " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) -+#include -+#else -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-nfc.h" -+#include "dev-usb.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+#include "routerboot.h" -+ -+#define RB_ROUTERBOOT_OFFSET 0x0000 -+#define RB_ROUTERBOOT_MIN_SIZE 0xb000 -+#define RB_HARD_CFG_SIZE 0x1000 -+#define RB_BIOS_OFFSET 0xd000 -+#define RB_BIOS_SIZE 0x1000 -+#define RB_SOFT_CFG_OFFSET 0xf000 -+#define RB_SOFT_CFG_SIZE 0x1000 -+ -+#define RB91X_FLAG_USB BIT(0) -+#define RB91X_FLAG_PCIE BIT(1) -+ -+#define RB91X_LATCH_GPIO_BASE 32 -+#define RB91X_LATCH_GPIO(_x) (RB91X_LATCH_GPIO_BASE + (_x)) -+ -+#define RB91X_SSR_GPIO_BASE (RB91X_LATCH_GPIO_BASE + AR934X_GPIO_COUNT) -+#define RB91X_SSR_GPIO(_x) (RB91X_SSR_GPIO_BASE + (_x)) -+ -+#define RB91X_SSR_BIT_LED1 0 -+#define RB91X_SSR_BIT_LED2 1 -+#define RB91X_SSR_BIT_LED3 2 -+#define RB91X_SSR_BIT_LED4 3 -+#define RB91X_SSR_BIT_LED5 4 -+#define RB91X_SSR_BIT_5 5 -+#define RB91X_SSR_BIT_USB_POWER 6 -+#define RB91X_SSR_BIT_PCIE_POWER 7 -+ -+#define RB91X_GPIO_SSR_STROBE RB91X_LATCH_GPIO(0) -+#define RB91X_GPIO_LED_POWER RB91X_LATCH_GPIO(1) -+#define RB91X_GPIO_LED_USER RB91X_LATCH_GPIO(2) -+#define RB91X_GPIO_NAND_READ RB91X_LATCH_GPIO(3) -+#define RB91X_GPIO_NAND_RDY RB91X_LATCH_GPIO(4) -+#define RB91X_GPIO_NLE RB91X_LATCH_GPIO(11) -+#define RB91X_GPIO_NAND_NRW RB91X_LATCH_GPIO(12) -+#define RB91X_GPIO_NAND_NCE RB91X_LATCH_GPIO(13) -+#define RB91X_GPIO_NAND_CLE RB91X_LATCH_GPIO(14) -+#define RB91X_GPIO_NAND_ALE RB91X_LATCH_GPIO(15) -+ -+#define RB91X_GPIO_LED_1 RB91X_SSR_GPIO(RB91X_SSR_BIT_LED1) -+#define RB91X_GPIO_LED_2 RB91X_SSR_GPIO(RB91X_SSR_BIT_LED2) -+#define RB91X_GPIO_LED_3 RB91X_SSR_GPIO(RB91X_SSR_BIT_LED3) -+#define RB91X_GPIO_LED_4 RB91X_SSR_GPIO(RB91X_SSR_BIT_LED4) -+#define RB91X_GPIO_LED_5 RB91X_SSR_GPIO(RB91X_SSR_BIT_LED5) -+#define RB91X_GPIO_USB_POWER RB91X_SSR_GPIO(RB91X_SSR_BIT_USB_POWER) -+#define RB91X_GPIO_PCIE_POWER RB91X_SSR_GPIO(RB91X_SSR_BIT_PCIE_POWER) -+ -+struct rb_board_info { -+ const char *name; -+ u32 flags; -+}; -+ -+static struct mtd_partition rb711gr100_spi_partitions[] = { -+ { -+ .name = "routerboot", -+ .offset = RB_ROUTERBOOT_OFFSET, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "hard_config", -+ .size = RB_HARD_CFG_SIZE, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "bios", -+ .offset = RB_BIOS_OFFSET, -+ .size = RB_BIOS_SIZE, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "soft_config", -+ .size = RB_SOFT_CFG_SIZE, -+ } -+}; -+ -+static struct flash_platform_data rb711gr100_spi_flash_data = { -+ .parts = rb711gr100_spi_partitions, -+ .nr_parts = ARRAY_SIZE(rb711gr100_spi_partitions), -+}; -+ -+static int rb711gr100_gpio_latch_gpios[AR934X_GPIO_COUNT] __initdata = { -+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 -+}; -+ -+static struct gpio_latch_platform_data rb711gr100_gpio_latch_data __initdata = { -+ .base = RB91X_LATCH_GPIO_BASE, -+ .num_gpios = ARRAY_SIZE(rb711gr100_gpio_latch_gpios), -+ .gpios = rb711gr100_gpio_latch_gpios, -+ .le_gpio_index = 11, -+ .le_active_low = true, -+}; -+ -+static struct rb91x_nand_platform_data rb711gr100_nand_data __initdata = { -+ .gpio_nce = RB91X_GPIO_NAND_NCE, -+ .gpio_ale = RB91X_GPIO_NAND_ALE, -+ .gpio_cle = RB91X_GPIO_NAND_CLE, -+ .gpio_rdy = RB91X_GPIO_NAND_RDY, -+ .gpio_read = RB91X_GPIO_NAND_READ, -+ .gpio_nrw = RB91X_GPIO_NAND_NRW, -+ .gpio_nle = RB91X_GPIO_NLE, -+}; -+ -+static u8 rb711gr100_ssr_initdata[] = { -+ BIT(RB91X_SSR_BIT_PCIE_POWER) | -+ BIT(RB91X_SSR_BIT_USB_POWER) | -+ BIT(RB91X_SSR_BIT_5) -+}; -+ -+static struct gen_74x164_chip_platform_data rb711gr100_ssr_data = { -+ .base = RB91X_SSR_GPIO_BASE, -+ .num_registers = ARRAY_SIZE(rb711gr100_ssr_initdata), -+ .init_data = rb711gr100_ssr_initdata, -+}; -+ -+static struct spi_board_info rb711gr100_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ .platform_data = &rb711gr100_spi_flash_data, -+ }, { -+ .bus_num = 0, -+ .chip_select = 1, -+ .max_speed_hz = 10000000, -+ .modalias = "74x164", -+ .platform_data = &rb711gr100_ssr_data, -+ } -+}; -+ -+static int rb711gr100_spi_cs_gpios[2] = { -+ -ENOENT, -+ RB91X_GPIO_SSR_STROBE, -+}; -+ -+static struct ath79_spi_platform_data rb711gr100_spi_data __initdata = { -+ .bus_num = 0, -+ .num_chipselect = 2, -+ .cs_gpios = rb711gr100_spi_cs_gpios, -+}; -+ -+static struct gpio_led rb711gr100_leds[] __initdata = { -+ { -+ .name = "rb:green:led1", -+ .gpio = RB91X_GPIO_LED_1, -+ .active_low = 0, -+ }, -+ { -+ .name = "rb:green:led2", -+ .gpio = RB91X_GPIO_LED_2, -+ .active_low = 0, -+ }, -+ { -+ .name = "rb:green:led3", -+ .gpio = RB91X_GPIO_LED_3, -+ .active_low = 0, -+ }, -+ { -+ .name = "rb:green:led4", -+ .gpio = RB91X_GPIO_LED_4, -+ .active_low = 0, -+ }, -+ { -+ .name = "rb:green:led5", -+ .gpio = RB91X_GPIO_LED_5, -+ .active_low = 0, -+ }, -+ { -+ .name = "rb:green:user", -+ .gpio = RB91X_GPIO_LED_USER, -+ .active_low = 0, -+ }, -+ { -+ .name = "rb:green:power", -+ .gpio = RB91X_GPIO_LED_POWER, -+ .active_low = 0, -+ .default_state = LEDS_GPIO_DEFSTATE_ON, -+ }, -+}; -+ -+static struct at803x_platform_data rb91x_at803x_data = { -+ .disable_smarteee = 1, -+ .enable_rgmii_rx_delay = 1, -+ .enable_rgmii_tx_delay = 1, -+}; -+ -+static struct mdio_board_info rb91x_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &rb91x_at803x_data, -+ }, -+}; -+ -+static void __init rb711gr100_init_partitions(const struct rb_info *info) -+{ -+ rb711gr100_spi_partitions[0].size = info->hard_cfg_offs; -+ rb711gr100_spi_partitions[1].offset = info->hard_cfg_offs; -+ -+ rb711gr100_spi_partitions[3].offset = info->soft_cfg_offs; -+} -+ -+void __init rb711gr100_wlan_init(void) -+{ -+ char *caldata; -+ u8 wlan_mac[ETH_ALEN]; -+ -+ caldata = rb_get_wlan_data(); -+ if (caldata == NULL) -+ return; -+ -+ ath79_init_mac(wlan_mac, ath79_mac_base, 1); -+ ath79_register_wmac(caldata + 0x1000, wlan_mac); -+ -+ kfree(caldata); -+} -+ -+#define RB_BOARD_INFO(_name, _flags) \ -+ { \ -+ .name = (_name), \ -+ .flags = (_flags), \ -+ } -+ -+static const struct rb_board_info rb711gr100_boards[] __initconst = { -+ RB_BOARD_INFO("911G-2HPnD", 0), -+ RB_BOARD_INFO("911G-5HPnD", 0), -+ RB_BOARD_INFO("912UAG-2HPnD", RB91X_FLAG_USB | RB91X_FLAG_PCIE), -+ RB_BOARD_INFO("912UAG-5HPnD", RB91X_FLAG_USB | RB91X_FLAG_PCIE), -+}; -+ -+static u32 rb711gr100_get_flags(const struct rb_info *info) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(rb711gr100_boards); i++) { -+ const struct rb_board_info *bi; -+ -+ bi = &rb711gr100_boards[i]; -+ if (strcmp(info->board_name, bi->name) == 0) -+ return bi->flags; -+ } -+ -+ return 0; -+} -+ -+static void __init rb711gr100_setup(void) -+{ -+ const struct rb_info *info; -+ char buf[64]; -+ u32 flags; -+ -+ info = rb_init_info((void *) KSEG1ADDR(0x1f000000), 0x10000); -+ if (!info) -+ return; -+ -+ scnprintf(buf, sizeof(buf), "Mikrotik RouterBOARD %s", -+ (info->board_name) ? info->board_name : ""); -+ mips_set_machine_name(buf); -+ -+ rb711gr100_init_partitions(info); -+ ath79_register_spi(&rb711gr100_spi_data, rb711gr100_spi_info, -+ ARRAY_SIZE(rb711gr100_spi_info)); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_RXD_DELAY | -+ AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(rb91x_mdio0_info, -+ ARRAY_SIZE(rb91x_mdio0_info)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_pll_data.pll_1000 = 0x02000000; -+ -+ ath79_register_eth(0); -+ -+ rb711gr100_wlan_init(); -+ -+ platform_device_register_data(NULL, "rb91x-nand", -1, -+ &rb711gr100_nand_data, -+ sizeof(rb711gr100_nand_data)); -+ -+ platform_device_register_data(NULL, "gpio-latch", -1, -+ &rb711gr100_gpio_latch_data, -+ sizeof(rb711gr100_gpio_latch_data)); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rb711gr100_leds), -+ rb711gr100_leds); -+ -+ flags = rb711gr100_get_flags(info); -+ -+ if (flags & RB91X_FLAG_USB) -+ ath79_register_usb(); -+ -+ if (flags & RB91X_FLAG_PCIE) -+ ath79_register_pci(); -+ -+} -+ -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_711GR100, "711Gr100", rb711gr100_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rb922.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb922.c -new file mode 100644 -index 0000000000..1c1cae1e76 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb922.c -@@ -0,0 +1,361 @@ -+/* -+ * MikroTik RouterBOARD 92X support -+ * -+ * Copyright (C) 2015 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) -+#include -+#else -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-nfc.h" -+#include "dev-usb.h" -+#include "dev-spi.h" -+#include "machtypes.h" -+#include "pci.h" -+#include "routerboot.h" -+ -+#define RB922_GPIO_LED_USR 12 -+#define RB922_GPIO_USB_POWER 13 -+#define RB922_GPIO_FAN_CTRL 14 -+#define RB922_GPIO_BTN_RESET 20 -+#define RB922_GPIO_NAND_NCE 23 -+ -+#define RB92X_FLAG_USB BIT(0) -+#define RB92X_FLAG_USB_POWER BIT(1) -+#define RB92X_FLAG_PCIE BIT(2) -+ -+#define RB922_PHY_ADDR 4 -+ -+#define RB922_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define RB922_KEYS_DEBOUNCE_INTERVAL (3 * RB922_KEYS_POLL_INTERVAL) -+ -+#define RB_ROUTERBOOT_OFFSET 0x0000 -+#define RB_ROUTERBOOT_MIN_SIZE 0xb000 -+#define RB_HARD_CFG_SIZE 0x1000 -+#define RB_BIOS_OFFSET 0xd000 -+#define RB_BIOS_SIZE 0x1000 -+#define RB_SOFT_CFG_OFFSET 0xf000 -+#define RB_SOFT_CFG_SIZE 0x1000 -+ -+struct rb_board_info { -+ const char *name; -+ u32 flags; -+}; -+ -+static struct mtd_partition rb922gs_spi_partitions[] = { -+ { -+ .name = "routerboot", -+ .offset = RB_ROUTERBOOT_OFFSET, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "hard_config", -+ .size = RB_HARD_CFG_SIZE, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "bios", -+ .offset = RB_BIOS_OFFSET, -+ .size = RB_BIOS_SIZE, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "soft_config", -+ .size = RB_SOFT_CFG_SIZE, -+ } -+}; -+ -+static void __init rb922gs_init_partitions(const struct rb_info *info) -+{ -+ rb922gs_spi_partitions[0].size = info->hard_cfg_offs; -+ rb922gs_spi_partitions[1].offset = info->hard_cfg_offs; -+ rb922gs_spi_partitions[3].offset = info->soft_cfg_offs; -+} -+ -+static struct mtd_partition rb922gs_nand_partitions[] = { -+ { -+ .name = "booter", -+ .offset = 0, -+ .size = (256 * 1024), -+ .mask_flags = MTD_WRITEABLE, -+ }, -+ { -+ .name = "kernel", -+ .offset = (256 * 1024), -+ .size = (4 * 1024 * 1024) - (256 * 1024), -+ }, -+ { -+ .name = "ubi", -+ .offset = MTDPART_OFS_NXTBLK, -+ .size = MTDPART_SIZ_FULL, -+ }, -+}; -+ -+static struct flash_platform_data rb922gs_spi_flash_data = { -+ .parts = rb922gs_spi_partitions, -+ .nr_parts = ARRAY_SIZE(rb922gs_spi_partitions), -+}; -+ -+static struct gpio_led rb922gs_leds[] __initdata = { -+ { -+ .name = "rb:green:user", -+ .gpio = RB922_GPIO_LED_USR, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button rb922gs_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = RB922_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = RB922_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct at803x_platform_data rb922gs_at803x_data = { -+ .disable_smarteee = 1, -+}; -+ -+static struct mdio_board_info rb922gs_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = RB922_PHY_ADDR, -+ .platform_data = &rb922gs_at803x_data, -+ }, -+}; -+ -+ -+ -+static void rb922gs_nand_select_chip(int chip_no) -+{ -+ switch (chip_no) { -+ case 0: -+ gpio_set_value(RB922_GPIO_NAND_NCE, 0); -+ break; -+ default: -+ gpio_set_value(RB922_GPIO_NAND_NCE, 1); -+ break; -+ } -+ ndelay(500); -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+static struct nand_ecclayout rb922gs_nand_ecclayout = { -+ .eccbytes = 6, -+ .eccpos = { 8, 9, 10, 13, 14, 15 }, -+ .oobavail = 9, -+ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } -+}; -+ -+#else -+ -+static int rb922gs_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 8; -+ oobregion->length = 3; -+ return 0; -+ case 1: -+ oobregion->offset = 13; -+ oobregion->length = 3; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static int rb922gs_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 0; -+ oobregion->length = 4; -+ return 0; -+ case 1: -+ oobregion->offset = 4; -+ oobregion->length = 1; -+ return 0; -+ case 2: -+ oobregion->offset = 6; -+ oobregion->length = 2; -+ return 0; -+ case 3: -+ oobregion->offset = 11; -+ oobregion->length = 2; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static const struct mtd_ooblayout_ops rb922gs_nand_ecclayout_ops = { -+ .ecc = rb922gs_ooblayout_ecc, -+ .free = rb922gs_ooblayout_free, -+}; -+#endif /* < 4.6 */ -+ -+static int rb922gs_nand_scan_fixup(struct mtd_info *mtd) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ struct nand_chip *chip = mtd->priv; -+#else -+ struct nand_chip *chip = mtd_to_nand(mtd); -+#endif /* < 4.6.0 */ -+ -+ if (mtd->writesize == 512) { -+ /* -+ * Use the OLD Yaffs-1 OOB layout, otherwise RouterBoot -+ * will not be able to find the kernel that we load. -+ */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ chip->ecc.layout = &rb922gs_nand_ecclayout; -+#else -+ mtd_set_ooblayout(mtd, &rb922gs_nand_ecclayout_ops); -+#endif -+ } -+ -+ chip->options = NAND_NO_SUBPAGE_WRITE; -+ -+ return 0; -+} -+ -+static void __init rb922gs_nand_init(void) -+{ -+ gpio_request_one(RB922_GPIO_NAND_NCE, GPIOF_OUT_INIT_HIGH, "NAND nCE"); -+ -+ ath79_nfc_set_scan_fixup(rb922gs_nand_scan_fixup); -+ ath79_nfc_set_parts(rb922gs_nand_partitions, -+ ARRAY_SIZE(rb922gs_nand_partitions)); -+ ath79_nfc_set_select_chip(rb922gs_nand_select_chip); -+ ath79_nfc_set_swap_dma(true); -+ ath79_register_nfc(); -+} -+ -+#define RB_BOARD_INFO(_name, _flags) \ -+ { \ -+ .name = (_name), \ -+ .flags = (_flags), \ -+ } -+ -+static const struct rb_board_info rb92x_boards[] __initconst = { -+ RB_BOARD_INFO("921GS-5HPacD r2", RB92X_FLAG_PCIE), -+ RB_BOARD_INFO("922UAGS-5HPacD", RB92X_FLAG_USB | RB92X_FLAG_USB_POWER | RB92X_FLAG_PCIE), -+}; -+ -+static u32 rb92x_get_flags(const struct rb_info *info) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(rb92x_boards); i++) { -+ const struct rb_board_info *bi; -+ -+ bi = &rb92x_boards[i]; -+ if (strcmp(info->board_name, bi->name) == 0) -+ return bi->flags; -+ } -+ -+ return 0; -+} -+ -+static void __init rb922gs_setup(void) -+{ -+ const struct rb_info *info; -+ char buf[64]; -+ u32 flags; -+ -+ info = rb_init_info((void *) KSEG1ADDR(0x1f000000), 0x10000); -+ if (!info) -+ return; -+ -+ scnprintf(buf, sizeof(buf), "MikroTik RouterBOARD %s", -+ (info->board_name) ? info->board_name : ""); -+ mips_set_machine_name(buf); -+ -+ rb922gs_init_partitions(info); -+ ath79_register_m25p80(&rb922gs_spi_flash_data); -+ -+ rb922gs_nand_init(); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(rb922gs_mdio0_info, -+ ARRAY_SIZE(rb922gs_mdio0_info)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(RB922_PHY_ADDR); -+ if (strcmp(info->board_name, "921GS-5HPacD r2") == 0 || -+ strcmp(info->board_name, "922UAGS-5HPacD") == 0) -+ { -+ ath79_eth0_pll_data.pll_10 = 0xa0001313; -+ ath79_eth0_pll_data.pll_100 = 0xa0000101; -+ ath79_eth0_pll_data.pll_1000 = 0x8f000000; -+ } -+ else { -+ ath79_eth0_pll_data.pll_10 = 0x81001313; -+ ath79_eth0_pll_data.pll_100 = 0x81000101; -+ ath79_eth0_pll_data.pll_1000 = 0x8f000000; -+ } -+ -+ ath79_register_eth(0); -+ -+ flags = rb92x_get_flags(info); -+ -+ if (flags & RB92X_FLAG_USB) -+ ath79_register_usb(); -+ -+ if (flags & RB92X_FLAG_USB_POWER) -+ gpio_request_one(RB922_GPIO_USB_POWER, GPIOF_OUT_INIT_LOW | -+ GPIOF_EXPORT_DIR_FIXED, "USB power"); -+ -+ if (flags & RB92X_FLAG_PCIE) -+ ath79_register_pci(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rb922gs_leds), rb922gs_leds); -+ ath79_register_gpio_keys_polled(-1, RB922_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(rb922gs_gpio_keys), -+ rb922gs_gpio_keys); -+ -+ /* NOTE: -+ * This only supports the RB911G-5HPacD board for now. For other boards -+ * more devices must be registered based on the hardware options which -+ * can be found in the hardware configuration of RouterBOOT. -+ */ -+} -+ -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_922GS, "922gs", rb922gs_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rb95x.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb95x.c -new file mode 100644 -index 0000000000..c4cf5f12a8 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb95x.c -@@ -0,0 +1,327 @@ -+/* -+ * MikroTik RouterBOARD 95X support -+ * -+ * Copyright (C) 2012 Stijn Tintel -+ * Copyright (C) 2012 Gabor Juhos -+ * Copyright (C) 2013 Kamil Trzcinski -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#define pr_fmt(fmt) "rb95x: " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) -+#include -+#else -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-m25p80.h" -+#include "dev-nfc.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "routerboot.h" -+#include "dev-leds-gpio.h" -+ -+#define RB95X_GPIO_NAND_NCE 14 -+ -+static struct mtd_partition rb95x_nand_partitions[] = { -+ { -+ .name = "booter", -+ .offset = 0, -+ .size = (256 * 1024), -+ .mask_flags = MTD_WRITEABLE, -+ }, -+ { -+ .name = "kernel", -+ .offset = (256 * 1024), -+ .size = (4 * 1024 * 1024) - (256 * 1024), -+ }, -+ { -+ .name = "ubi", -+ .offset = MTDPART_OFS_NXTBLK, -+ .size = MTDPART_SIZ_FULL, -+ }, -+}; -+ -+static struct gpio_led rb951ui_leds_gpio[] __initdata = { -+ { -+ .name = "rb:green:wlan", -+ .gpio = 11, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:act", -+ .gpio = 3, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:port1", -+ .gpio = 13, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:port2", -+ .gpio = 12, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:port3", -+ .gpio = 4, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:port4", -+ .gpio = 21, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:port5", -+ .gpio = 16, -+ .active_low = 1, -+ } -+}; -+ -+static struct ar8327_pad_cfg rb95x_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_platform_data rb95x_ar8327_data = { -+ .pad0_cfg = &rb95x_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ } -+}; -+ -+static struct mdio_board_info rb95x_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &rb95x_ar8327_data, -+ }, -+}; -+ -+void __init rb95x_wlan_init(void) -+{ -+ char *art_buf; -+ u8 wlan_mac[ETH_ALEN]; -+ -+ art_buf = rb_get_wlan_data(); -+ if (art_buf == NULL) -+ return; -+ -+ ath79_init_mac(wlan_mac, ath79_mac_base, 11); -+ ath79_register_wmac(art_buf + 0x1000, wlan_mac); -+ -+ kfree(art_buf); -+} -+ -+static void rb95x_nand_select_chip(int chip_no) -+{ -+ switch (chip_no) { -+ case 0: -+ gpio_set_value(RB95X_GPIO_NAND_NCE, 0); -+ break; -+ default: -+ gpio_set_value(RB95X_GPIO_NAND_NCE, 1); -+ break; -+ } -+ ndelay(500); -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+static struct nand_ecclayout rb95x_nand_ecclayout = { -+ .eccbytes = 6, -+ .eccpos = { 8, 9, 10, 13, 14, 15 }, -+ .oobavail = 9, -+ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } -+}; -+ -+#else -+ -+static int rb95x_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 8; -+ oobregion->length = 3; -+ return 0; -+ case 1: -+ oobregion->offset = 13; -+ oobregion->length = 3; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static int rb95x_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 0; -+ oobregion->length = 4; -+ return 0; -+ case 1: -+ oobregion->offset = 4; -+ oobregion->length = 1; -+ return 0; -+ case 2: -+ oobregion->offset = 6; -+ oobregion->length = 2; -+ return 0; -+ case 3: -+ oobregion->offset = 11; -+ oobregion->length = 2; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static const struct mtd_ooblayout_ops rb95x_nand_ecclayout_ops = { -+ .ecc = rb95x_ooblayout_ecc, -+ .free = rb95x_ooblayout_free, -+}; -+#endif /* < 4.6 */ -+ -+static int rb95x_nand_scan_fixup(struct mtd_info *mtd) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ struct nand_chip *chip = mtd->priv; -+#else -+ struct nand_chip *chip = mtd_to_nand(mtd); -+#endif /* < 4.6.0 */ -+ -+ if (mtd->writesize == 512) { -+ /* -+ * Use the OLD Yaffs-1 OOB layout, otherwise RouterBoot -+ * will not be able to find the kernel that we load. -+ */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ chip->ecc.layout = &rb95x_nand_ecclayout; -+#else -+ mtd_set_ooblayout(mtd, &rb95x_nand_ecclayout_ops); -+#endif -+ } -+ -+ chip->options = NAND_NO_SUBPAGE_WRITE; -+ -+ return 0; -+} -+ -+void __init rb95x_nand_init(void) -+{ -+ gpio_request_one(RB95X_GPIO_NAND_NCE, GPIOF_OUT_INIT_HIGH, "NAND nCE"); -+ -+ ath79_nfc_set_scan_fixup(rb95x_nand_scan_fixup); -+ ath79_nfc_set_parts(rb95x_nand_partitions, -+ ARRAY_SIZE(rb95x_nand_partitions)); -+ ath79_nfc_set_select_chip(rb95x_nand_select_chip); -+ ath79_nfc_set_swap_dma(true); -+ ath79_register_nfc(); -+} -+ -+static int __init rb95x_setup(void) -+{ -+ const struct rb_info *info; -+ -+ info = rb_init_info((void *)(KSEG1ADDR(AR71XX_SPI_BASE)), 0x10000); -+ if (!info) -+ return -EINVAL; -+ -+ rb95x_nand_init(); -+ -+ return 0; -+} -+ -+static void __init rb951g_setup(void) -+{ -+ if (rb95x_setup()) -+ return; -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_RXD_DELAY | -+ AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(rb95x_mdio0_info, -+ ARRAY_SIZE(rb95x_mdio0_info)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_pll_data.pll_1000 = 0x6f000000; -+ -+ ath79_register_eth(0); -+ -+ rb95x_wlan_init(); -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RB_951G, "951G", "MikroTik RouterBOARD 951G-2HnD", -+ rb951g_setup); -+ -+static void __init rb951ui_setup(void) -+{ -+ if (rb95x_setup()) -+ return; -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(4); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_register_eth(0); -+ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_register_eth(1); -+ -+ gpio_request_one(20, GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ -+ gpio_request_one(2, GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "POE power"); -+ -+ rb95x_wlan_init(); -+ ath79_register_usb(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rb951ui_leds_gpio), -+ rb951ui_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RB_951U, "951HnD", "MikroTik RouterBOARD 951Ui-2HnD", -+ rb951ui_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rbspi.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rbspi.c -new file mode 100644 -index 0000000000..cb05c9142c ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rbspi.c -@@ -0,0 +1,1262 @@ -+/* -+ * MikroTik SPI-NOR RouterBOARDs support -+ * -+ * - MikroTik RouterBOARD mAP 2nD -+ * - MikroTik RouterBOARD mAP L-2nD -+ * - MikroTik RouterBOARD 911-2Hn (911 Lite2) -+ * - MikroTik RouterBOARD 911-5Hn (911 Lite5) -+ * - MikroTik RouterBOARD 931-2nD (hAP mini) -+ * - MikroTik RouterBOARD 941L-2nD -+ * - MikroTik RouterBOARD 951Ui-2nD -+ * - MikroTik RouterBOARD 952Ui-5ac2nD -+ * - MikroTik RouterBOARD 962UiGS-5HacT2HnT -+ * - MikroTik RouterBOARD 750UP r2 -+ * - MikroTik RouterBOARD 750P-PBr2 -+ * - MikroTik RouterBOARD 750 r2 -+ * - MikroTik RouterBOARD LHG 5nD -+ * - MikroTik RouterBOARD wAP2nD -+ * - MikroTik RouterBOARD wAP G-5HacT2HnDwAP (wAP AC) -+ * - MikroTik RouterBOARD wAP R-2nD -+ * -+ * Preliminary support for the following hardware -+ * - MikroTik RouterBOARD cAP2nD -+ * Furthermore, the cAP lite (cAPL2nD) appears to feature the exact same -+ * hardware as the mAP L-2nD. It is unknown if they share the same board -+ * identifier. -+ * -+ * Copyright (C) 2017-2018 Thibaut VARENE -+ * Copyright (C) 2016 David Hutchison -+ * Copyright (C) 2017 Ryan Mounce -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-spi.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+#include "routerboot.h" -+ -+#define RBSPI_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define RBSPI_KEYS_DEBOUNCE_INTERVAL (3 * RBSPI_KEYS_POLL_INTERVAL) -+ -+#define RBSPI_HAS_USB BIT(0) -+#define RBSPI_HAS_WLAN0 BIT(1) -+#define RBSPI_HAS_WLAN1 BIT(2) -+#define RBSPI_HAS_WAN4 BIT(3) /* has WAN port on PHY4 */ -+#define RBSPI_HAS_SSR BIT(4) /* has an SSR on SPI bus 0 */ -+#define RBSPI_HAS_POE BIT(5) -+#define RBSPI_HAS_MDIO1 BIT(6) -+#define RBSPI_HAS_PCI BIT(7) -+ -+#define RB_ROUTERBOOT_OFFSET 0x0000 -+#define RB_BIOS_SIZE 0x1000 -+#define RB_SOFT_CFG_SIZE 0x1000 -+ -+/* Flash partitions indexes */ -+enum { -+ RBSPI_PART_RBOOT, -+ RBSPI_PART_HCONF, -+ RBSPI_PART_BIOS, -+ RBSPI_PART_RBOOT2, -+ RBSPI_PART_SCONF, -+ RBSPI_PART_FIRMW, -+ RBSPI_PARTS -+}; -+ -+static struct mtd_partition rbspi_spi_partitions[RBSPI_PARTS]; -+ -+/* -+ * Setup the SPI flash partition table based on initial parsing. -+ * The kernel can be at any aligned position and have any size. -+ */ -+static void __init rbspi_init_partitions(const struct rb_info *info) -+{ -+ struct mtd_partition *parts = rbspi_spi_partitions; -+ memset(parts, 0x0, sizeof(*parts)); -+ -+ parts[RBSPI_PART_RBOOT].name = "routerboot"; -+ parts[RBSPI_PART_RBOOT].offset = RB_ROUTERBOOT_OFFSET; -+ parts[RBSPI_PART_RBOOT].size = info->hard_cfg_offs; -+ parts[RBSPI_PART_RBOOT].mask_flags = MTD_WRITEABLE; -+ -+ parts[RBSPI_PART_HCONF].name = "hard_config"; -+ parts[RBSPI_PART_HCONF].offset = info->hard_cfg_offs; -+ parts[RBSPI_PART_HCONF].size = info->hard_cfg_size; -+ parts[RBSPI_PART_HCONF].mask_flags = MTD_WRITEABLE; -+ -+ parts[RBSPI_PART_BIOS].name = "bios"; -+ parts[RBSPI_PART_BIOS].offset = info->hard_cfg_offs -+ + info->hard_cfg_size; -+ parts[RBSPI_PART_BIOS].size = RB_BIOS_SIZE; -+ parts[RBSPI_PART_BIOS].mask_flags = MTD_WRITEABLE; -+ -+ parts[RBSPI_PART_RBOOT2].name = "routerboot2"; -+ parts[RBSPI_PART_RBOOT2].offset = parts[RBSPI_PART_BIOS].offset -+ + RB_BIOS_SIZE; -+ parts[RBSPI_PART_RBOOT2].size = info->soft_cfg_offs -+ - parts[RBSPI_PART_RBOOT2].offset; -+ parts[RBSPI_PART_RBOOT2].mask_flags = MTD_WRITEABLE; -+ -+ parts[RBSPI_PART_SCONF].name = "soft_config"; -+ parts[RBSPI_PART_SCONF].offset = info->soft_cfg_offs; -+ parts[RBSPI_PART_SCONF].size = RB_SOFT_CFG_SIZE; -+ -+ parts[RBSPI_PART_FIRMW].name = "firmware"; -+ parts[RBSPI_PART_FIRMW].offset = parts[RBSPI_PART_SCONF].offset -+ + parts[RBSPI_PART_SCONF].size; -+ parts[RBSPI_PART_FIRMW].size = MTDPART_SIZ_FULL; -+} -+ -+static struct flash_platform_data rbspi_spi_flash_data = { -+ .parts = rbspi_spi_partitions, -+ .nr_parts = ARRAY_SIZE(rbspi_spi_partitions), -+}; -+ -+/* -+ * Several boards only have a single reset button, use a common -+ * structure for that. -+ */ -+static struct gpio_keys_button rbspi_gpio_keys_reset[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = RBSPI_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = -ENOENT, /* filled dynamically */ -+ .active_low = 1, -+ }, -+}; -+ -+/* RB mAP L-2nD gpios */ -+#define RBMAPL_GPIO_LED_POWER 17 -+#define RBMAPL_GPIO_LED_USER 14 -+#define RBMAPL_GPIO_LED_ETH 4 -+#define RBMAPL_GPIO_LED_WLAN 11 -+#define RBMAPL_GPIO_BTN_RESET 16 -+ -+static struct gpio_led rbmapl_leds[] __initdata = { -+ { -+ .name = "rb:green:power", -+ .gpio = RBMAPL_GPIO_LED_POWER, -+ .active_low = 0, -+ .default_state = LEDS_GPIO_DEFSTATE_ON, -+ }, { -+ .name = "rb:green:user", -+ .gpio = RBMAPL_GPIO_LED_USER, -+ .active_low = 0, -+ }, { -+ .name = "rb:green:eth", -+ .gpio = RBMAPL_GPIO_LED_ETH, -+ .active_low = 0, -+ }, { -+ .name = "rb:green:wlan", -+ .gpio = RBMAPL_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+}; -+ -+/* RB 941L-2nD gpios */ -+#define RBHAPL_GPIO_LED_USER 14 -+#define RBHAPL_GPIO_BTN_RESET 16 -+ -+static struct gpio_led rbhapl_leds[] __initdata = { -+ { -+ .name = "rb:green:user", -+ .gpio = RBHAPL_GPIO_LED_USER, -+ .active_low = 1, -+ }, -+}; -+ -+/* common RB SSRs */ -+#define RBSPI_SSR_GPIO_BASE 40 -+#define RBSPI_SSR_GPIO(bit) (RBSPI_SSR_GPIO_BASE + (bit)) -+ -+/* RB 951Ui-2nD gpios */ -+#define RB952_SSR_BIT_LED_LAN1 0 -+#define RB952_SSR_BIT_LED_LAN2 1 -+#define RB952_SSR_BIT_LED_LAN3 2 -+#define RB952_SSR_BIT_LED_LAN4 3 -+#define RB952_SSR_BIT_LED_LAN5 4 -+#define RB952_SSR_BIT_USB_POWER 5 -+#define RB952_SSR_BIT_LED_WLAN 6 -+#define RB952_GPIO_SSR_CS 11 -+#define RB952_GPIO_LED_USER 4 -+#define RB952_GPIO_POE_POWER 14 -+#define RB952_GPIO_POE_STATUS 12 -+#define RB952_GPIO_BTN_RESET 16 -+#define RB952_GPIO_USB_PWROFF RBSPI_SSR_GPIO(RB952_SSR_BIT_USB_POWER) -+#define RB952_GPIO_LED_LAN1 RBSPI_SSR_GPIO(RB952_SSR_BIT_LED_LAN1) -+#define RB952_GPIO_LED_LAN2 RBSPI_SSR_GPIO(RB952_SSR_BIT_LED_LAN2) -+#define RB952_GPIO_LED_LAN3 RBSPI_SSR_GPIO(RB952_SSR_BIT_LED_LAN3) -+#define RB952_GPIO_LED_LAN4 RBSPI_SSR_GPIO(RB952_SSR_BIT_LED_LAN4) -+#define RB952_GPIO_LED_LAN5 RBSPI_SSR_GPIO(RB952_SSR_BIT_LED_LAN5) -+#define RB952_GPIO_LED_WLAN RBSPI_SSR_GPIO(RB952_SSR_BIT_LED_WLAN) -+ -+static struct gpio_led rb952_leds[] __initdata = { -+ { -+ .name = "rb:green:user", -+ .gpio = RB952_GPIO_LED_USER, -+ .active_low = 0, -+ }, { -+ .name = "rb:blue:wlan", -+ .gpio = RB952_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:port1", -+ .gpio = RB952_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:port2", -+ .gpio = RB952_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:port3", -+ .gpio = RB952_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:port4", -+ .gpio = RB952_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:port5", -+ .gpio = RB952_GPIO_LED_LAN5, -+ .active_low = 1, -+ }, -+}; -+ -+ -+/* RB 962UiGS-5HacT2HnT gpios */ -+#define RB962_WIFI_LED_1 1 -+#define RB962_WIFI_LED_2 2 -+#define RB962_GPIO_POE_STATUS 2 -+#define RB962_GPIO_POE_POWER 3 -+#define RB962_GPIO_LED_USER 12 -+#define RB962_GPIO_USB_PWROFF 13 -+#define RB962_GPIO_BTN_RESET 20 -+ -+static struct gpio_led rb962_leds_gpio[] __initdata = { -+ { -+ .name = "rb:green:user", -+ .gpio = RB962_GPIO_LED_USER, -+ .active_low = 1, -+ }, -+}; -+ -+static const struct ar8327_led_info rb962_leds_ar8327[] = { -+ AR8327_LED_INFO(PHY0_0, HW, "rb:green:port1"), -+ AR8327_LED_INFO(PHY1_0, HW, "rb:green:port2"), -+ AR8327_LED_INFO(PHY2_0, HW, "rb:green:port3"), -+ AR8327_LED_INFO(PHY3_0, HW, "rb:green:port4"), -+ AR8327_LED_INFO(PHY4_0, HW, "rb:green:port5"), -+}; -+ -+static struct ar8327_pad_cfg rb962_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+ .mac06_exchange_dis = true, -+}; -+ -+static struct ar8327_pad_cfg rb962_ar8327_pad6_cfg = { -+ /* Use SGMII interface for GMAC6 of the AR8337 switch */ -+ .mode = AR8327_PAD_MAC_SGMII, -+ .rxclk_delay_en = true, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL0, -+}; -+ -+static struct ar8327_led_cfg rb962_ar8327_led_cfg = { -+ .led_ctrl0 = 0xc737c737, -+ .led_ctrl1 = 0x00000000, -+ .led_ctrl2 = 0x00000000, -+ .led_ctrl3 = 0x0030c300, -+ .open_drain = false, -+}; -+ -+static struct ar8327_platform_data rb962_ar8327_data = { -+ .pad0_cfg = &rb962_ar8327_pad0_cfg, -+ .pad6_cfg = &rb962_ar8327_pad6_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .port6_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &rb962_ar8327_led_cfg, -+ .num_leds = ARRAY_SIZE(rb962_leds_ar8327), -+ .leds = rb962_leds_ar8327, -+}; -+ -+static struct mdio_board_info rb962_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &rb962_ar8327_data, -+ }, -+}; -+ -+/* RB wAP-2nD gpios */ -+#define RBWAP_GPIO_LED_USER 14 -+#define RBWAP_GPIO_LED_WLAN 11 -+#define RBWAP_GPIO_BTN_RESET 16 -+ -+static struct gpio_led rbwap_leds[] __initdata = { -+ { -+ .name = "rb:green:user", -+ .gpio = RBWAP_GPIO_LED_USER, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:wlan", -+ .gpio = RBWAP_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+/* RB cAP-2nD gpios */ -+#define RBCAP_GPIO_LED_1 14 -+#define RBCAP_GPIO_LED_2 12 -+#define RBCAP_GPIO_LED_3 11 -+#define RBCAP_GPIO_LED_4 4 -+#define RBCAP_GPIO_LED_ALL 13 -+ -+static struct gpio_led rbcap_leds[] __initdata = { -+ { -+ .name = "rb:green:rssi1", -+ .gpio = RBCAP_GPIO_LED_1, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:rssi2", -+ .gpio = RBCAP_GPIO_LED_2, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:rssi3", -+ .gpio = RBCAP_GPIO_LED_3, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:rssi4", -+ .gpio = RBCAP_GPIO_LED_4, -+ .active_low = 1, -+ }, -+}; -+ -+/* RB mAP-2nD gpios */ -+#define RBMAP_SSR_BIT_LED_LAN1 0 -+#define RBMAP_SSR_BIT_LED_LAN2 1 -+#define RBMAP_SSR_BIT_LED_POEO 2 -+#define RBMAP_SSR_BIT_LED_USER 3 -+#define RBMAP_SSR_BIT_LED_WLAN 4 -+#define RBMAP_SSR_BIT_USB_POWER 5 -+#define RBMAP_SSR_BIT_LED_APCAP 6 -+#define RBMAP_GPIO_BTN_RESET 16 -+#define RBMAP_GPIO_SSR_CS 11 -+#define RBMAP_GPIO_LED_POWER 4 -+#define RBMAP_GPIO_POE_POWER 14 -+#define RBMAP_GPIO_POE_STATUS 12 -+#define RBMAP_GPIO_USB_PWROFF RBSPI_SSR_GPIO(RBMAP_SSR_BIT_USB_POWER) -+#define RBMAP_GPIO_LED_LAN1 RBSPI_SSR_GPIO(RBMAP_SSR_BIT_LED_LAN1) -+#define RBMAP_GPIO_LED_LAN2 RBSPI_SSR_GPIO(RBMAP_SSR_BIT_LED_LAN2) -+#define RBMAP_GPIO_LED_POEO RBSPI_SSR_GPIO(RBMAP_SSR_BIT_LED_POEO) -+#define RBMAP_GPIO_LED_USER RBSPI_SSR_GPIO(RBMAP_SSR_BIT_LED_USER) -+#define RBMAP_GPIO_LED_WLAN RBSPI_SSR_GPIO(RBMAP_SSR_BIT_LED_WLAN) -+#define RBMAP_GPIO_LED_APCAP RBSPI_SSR_GPIO(RBMAP_SSR_BIT_LED_APCAP) -+ -+static struct gpio_led rbmap_leds[] __initdata = { -+ { -+ .name = "rb:green:power", -+ .gpio = RBMAP_GPIO_LED_POWER, -+ .active_low = 1, -+ .default_state = LEDS_GPIO_DEFSTATE_ON, -+ }, { -+ .name = "rb:green:eth1", -+ .gpio = RBMAP_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:eth2", -+ .gpio = RBMAP_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "rb:red:poe_out", -+ .gpio = RBMAP_GPIO_LED_POEO, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:user", -+ .gpio = RBMAP_GPIO_LED_USER, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:wlan", -+ .gpio = RBMAP_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:ap_cap", -+ .gpio = RBMAP_GPIO_LED_APCAP, -+ .active_low = 1, -+ }, -+}; -+ -+/* RB LHG 5nD gpios */ -+#define RBLHG_GPIO_LED_0 13 -+#define RBLHG_GPIO_LED_1 12 -+#define RBLHG_GPIO_LED_2 4 -+#define RBLHG_GPIO_LED_3 21 -+#define RBLHG_GPIO_LED_4 18 -+#define RBLHG_GPIO_LED_ETH 14 -+#define RBLHG_GPIO_LED_POWER 11 -+#define RBLHG_GPIO_LED_USER 20 -+#define RBLHG_GPIO_BTN_RESET 15 -+ -+static struct gpio_led rblhg_leds[] __initdata = { -+ { -+ .name = "rb:green:rssi0", -+ .gpio = RBLHG_GPIO_LED_0, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:rssi1", -+ .gpio = RBLHG_GPIO_LED_1, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:rssi2", -+ .gpio = RBLHG_GPIO_LED_2, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:rssi3", -+ .gpio = RBLHG_GPIO_LED_3, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:rssi4", -+ .gpio = RBLHG_GPIO_LED_4, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:eth", -+ .gpio = RBLHG_GPIO_LED_ETH, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:user", -+ .gpio = RBLHG_GPIO_LED_USER, -+ .active_low = 1, -+ }, { -+ .name = "rb:blue:power", -+ .gpio = RBLHG_GPIO_LED_POWER, -+ .active_low = 0, -+ .default_state = LEDS_GPIO_DEFSTATE_ON, -+ }, -+}; -+ -+/* RB w APG-5HacT2HnD (wAP AC) gpios*/ -+#define RBWAPGSC_WIFI_LED_1 1 -+#define RBWAPGSC_WIFI_LED_2 8 -+#define RBWAPGSC_WIFI_LED_3 9 -+#define RBWAPGSC_GPIO_LED_POWER 16 -+#define RBWAPGSC_GPIO_BTN_RESET 1 -+#define RBWAPGSC_GPIO_MDIO_MDC 12 -+#define RBWAPGSC_GPIO_MDIO_DATA 11 -+#define RBWAPGSC_MDIO_PHYADDR 0 -+ -+static struct gpio_led rbwapgsc_leds[] __initdata = { -+ { -+ .name = "rb:green:power", -+ .gpio = RBWAPGSC_GPIO_LED_POWER, -+ .active_low = 1, -+ .default_state = LEDS_GPIO_DEFSTATE_ON, -+ }, -+}; -+ -+static struct mdio_gpio_platform_data rbwapgsc_mdio_data = { -+ .mdc = RBWAPGSC_GPIO_MDIO_MDC, -+ .mdio = RBWAPGSC_GPIO_MDIO_DATA, -+ .phy_mask = ~BIT(RBWAPGSC_MDIO_PHYADDR), -+}; -+ -+static struct platform_device rbwapgsc_phy_device = { -+ .name = "mdio-gpio", -+ .id = 1, -+ .dev = { -+ .platform_data = &rbwapgsc_mdio_data -+ }, -+}; -+ -+static struct at803x_platform_data rbwapgsc_at803x_data = { -+ .override_sgmii_aneg = 1, -+}; -+ -+static struct mdio_board_info rbwapgsc_mdio_info[] = { -+ { -+ .bus_id = "gpio-1", -+ .mdio_addr = RBWAPGSC_MDIO_PHYADDR, -+ .platform_data = &rbwapgsc_at803x_data, -+ }, -+}; -+ -+/* RB911L GPIOs */ -+#define RB911L_GPIO_BTN_RESET 15 -+#define RB911L_GPIO_LED_1 13 -+#define RB911L_GPIO_LED_2 12 -+#define RB911L_GPIO_LED_3 4 -+#define RB911L_GPIO_LED_4 21 -+#define RB911L_GPIO_LED_5 18 -+#define RB911L_GPIO_LED_ETH 20 -+#define RB911L_GPIO_LED_POWER 11 -+#define RB911L_GPIO_LED_USER 3 -+#define RB911L_GPIO_PIN_HOLE 14 /* for reference, active low */ -+ -+static struct gpio_led rb911l_leds[] __initdata = { -+ { -+ .name = "rb:green:eth", -+ .gpio = RB911L_GPIO_LED_ETH, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:led1", -+ .gpio = RB911L_GPIO_LED_1, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:led2", -+ .gpio = RB911L_GPIO_LED_2, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:led3", -+ .gpio = RB911L_GPIO_LED_3, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:led4", -+ .gpio = RB911L_GPIO_LED_4, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:led5", -+ .gpio = RB911L_GPIO_LED_5, -+ .active_low = 1, -+ }, { -+ .name = "rb:green:power", -+ .gpio = RB911L_GPIO_LED_POWER, -+ .default_state = LEDS_GPIO_DEFSTATE_ON, -+ .active_low = 1, -+ .open_drain = 1, -+ }, { -+ .name = "rb:green:user", -+ .gpio = RB911L_GPIO_LED_USER, -+ .active_low = 1, -+ .open_drain = 1, -+ }, -+}; -+ -+/* RB 931-2nD gpios */ -+#define RB931_GPIO_BTN_RESET 0 -+#define RB931_GPIO_BTN_MODE 9 -+#define RB931_GPIO_LED_USER 1 -+ -+static struct gpio_keys_button rb931_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = RBSPI_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = RB931_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "Mode button", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = RBSPI_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = RB931_GPIO_BTN_MODE, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led rb931_leds[] __initdata = { -+ { -+ .name = "rb:green:user", -+ .gpio = RB931_GPIO_LED_USER, -+ .active_low = 1, -+ }, -+}; -+ -+/* RB wAP R-2nD (wAP R) gpios*/ -+#define RBWAPR_GPIO_LED_USER 14 -+#define RBWAPR_GPIO_LED1 12 -+#define RBWAPR_GPIO_LED2 13 -+#define RBWAPR_GPIO_LED3 3 -+#define RBWAPR_GPIO_PCIE_PWROFF 15 -+#define RBWAPR_GPIO_CONTROL 10 -+#define RBWAPR_GPIO_BTN_RESET 16 -+ -+static struct gpio_led rbwapr_leds[] __initdata = { -+ { -+ .name = "rb:green:user", -+ .gpio = RBWAPR_GPIO_LED_USER, -+ .active_low = 0, -+ },{ -+ .name = "rb:green:led1", -+ .gpio = RBWAPR_GPIO_LED1, -+ .active_low = 1, -+ },{ -+ .name = "rb:green:led2", -+ .gpio = RBWAPR_GPIO_LED2, -+ .active_low = 1, -+ },{ -+ .name = "rb:green:led3", -+ .gpio = RBWAPR_GPIO_LED3, -+ .active_low = 0, -+ }, -+}; -+ -+ -+static struct gen_74x164_chip_platform_data rbspi_ssr_data = { -+ .base = RBSPI_SSR_GPIO_BASE, -+ .num_registers = 1, -+}; -+ -+/* the spi-ath79 driver can only natively handle CS0. Other CS are bit-banged */ -+static int rbspi_spi_cs_gpios[] = { -+ -ENOENT, /* CS0 is always -ENOENT: natively handled */ -+ -ENOENT, /* CS1 can be updated by the code as necessary */ -+}; -+ -+static struct ath79_spi_platform_data rbspi_ath79_spi_data = { -+ .bus_num = 0, -+ .cs_gpios = rbspi_spi_cs_gpios, -+}; -+ -+/* -+ * Global spi_board_info: devices that don't have an SSR only have the SPI NOR -+ * flash on bus0 CS0, while devices that have an SSR add it on the same bus CS1 -+ */ -+static struct spi_board_info rbspi_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ .platform_data = &rbspi_spi_flash_data, -+ }, { -+ .bus_num = 0, -+ .chip_select = 1, -+ .max_speed_hz = 25000000, -+ .modalias = "74x164", -+ .platform_data = &rbspi_ssr_data, -+ } -+}; -+ -+void __init rbspi_wlan_init(int wmac_offset) -+{ -+ char *art_buf; -+ u8 wlan_mac[ETH_ALEN]; -+ -+ art_buf = rb_get_wlan_data(); -+ if (!art_buf) -+ return; -+ -+ ath79_init_mac(wlan_mac, ath79_mac_base, wmac_offset); -+ ath79_register_wmac(art_buf + 0x1000, wlan_mac); -+ -+ kfree(art_buf); -+} -+ -+#define RBSPI_MACH_BUFLEN 64 -+/* -+ * Common platform init routine for all SPI NOR devices. -+ */ -+static __init const struct rb_info *rbspi_platform_setup(void) -+{ -+ const struct rb_info *info; -+ char buf[RBSPI_MACH_BUFLEN] = "MikroTik "; -+ char *str; -+ int len = RBSPI_MACH_BUFLEN - strlen(buf) - 1; -+ -+ info = rb_init_info((void *)(KSEG1ADDR(AR71XX_SPI_BASE)), 0x20000); -+ if (!info) -+ return NULL; -+ -+ if (info->board_name) { -+ str = "RouterBOARD "; -+ if (strncmp(info->board_name, str, strlen(str))) { -+ strncat(buf, str, len); -+ len -= strlen(str); -+ } -+ strncat(buf, info->board_name, len); -+ } -+ else -+ strncat(buf, "UNKNOWN", len); -+ -+ mips_set_machine_name(buf); -+ -+ /* fix partitions based on flash parsing */ -+ rbspi_init_partitions(info); -+ -+ return info; -+} -+ -+/* -+ * Common peripherals init routine for all SPI NOR devices. -+ * Sets SPI and USB. -+ */ -+static void __init rbspi_peripherals_setup(u32 flags) -+{ -+ unsigned spi_n; -+ -+ if (flags & RBSPI_HAS_SSR) -+ spi_n = ARRAY_SIZE(rbspi_spi_info); -+ else -+ spi_n = 1; /* only one device on bus0 */ -+ -+ rbspi_ath79_spi_data.num_chipselect = spi_n; -+ rbspi_ath79_spi_data.cs_gpios = rbspi_spi_cs_gpios; -+ ath79_register_spi(&rbspi_ath79_spi_data, rbspi_spi_info, spi_n); -+ -+ if (flags & RBSPI_HAS_USB) -+ ath79_register_usb(); -+ -+ if (flags & RBSPI_HAS_PCI) -+ ath79_register_pci(); -+} -+ -+/* -+ * Common network init routine for all SPI NOR devices. -+ * Sets LAN/WAN/WLAN. -+ */ -+static void __init rbspi_network_setup(u32 flags, int gmac1_offset, -+ int wmac0_offset, int wmac1_offset) -+{ -+ /* for QCA953x that will init mdio1_device/data */ -+ ath79_register_mdio(0, 0x0); -+ if (flags & RBSPI_HAS_MDIO1) -+ ath79_register_mdio(1, 0x0); -+ -+ if (flags & RBSPI_HAS_WAN4) { -+ ath79_setup_ar934x_eth_cfg(0); -+ -+ /* set switch to oper mode 1, PHY4 connected to CPU */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ -+ /* init GMAC0 connected to PHY4 at 100M */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_register_eth(0); -+ } else { -+ /* set the SoC to SW_ONLY_MODE, which connects all PHYs -+ * to the internal switch. -+ * We hijack ath79_setup_ar934x_eth_cfg() to set the switch in -+ * the QCA953x, this works because this configuration bit is -+ * the same as the AR934x. There's no equivalent function for -+ * QCA953x for now. */ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_ONLY_MODE); -+ } -+ -+ /* init GMAC1 */ -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, gmac1_offset); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_register_eth(1); -+ -+ if (flags & RBSPI_HAS_WLAN0) -+ rbspi_wlan_init(wmac0_offset); -+ -+ if (flags & RBSPI_HAS_WLAN1) -+ rbspi_wlan_init(wmac1_offset); -+} -+ -+static __init void rbspi_register_reset_button(int gpio) -+{ -+ rbspi_gpio_keys_reset[0].gpio = gpio; -+ ath79_register_gpio_keys_polled(-1, RBSPI_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(rbspi_gpio_keys_reset), -+ rbspi_gpio_keys_reset); -+} -+ -+/* -+ * Init the mAP lite hardware (QCA953x). -+ * The mAP L-2nD (mAP lite) has a single ethernet port, connected to PHY0. -+ * Trying to use GMAC0 in direct mode was unsucessful, so we're -+ * using SW_ONLY_MODE, which connects PHY0 to MAC1 on the internal -+ * switch, which is connected to GMAC1 on the SoC. GMAC0 is unused. -+ */ -+static void __init rbmapl_setup(void) -+{ -+ u32 flags = RBSPI_HAS_WLAN0; -+ -+ if (!rbspi_platform_setup()) -+ return; -+ -+ rbspi_peripherals_setup(flags); -+ -+ /* GMAC1 is HW MAC, WLAN0 MAC is HW MAC + 1 */ -+ rbspi_network_setup(flags, 0, 1, 0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rbmapl_leds), rbmapl_leds); -+ -+ /* mAP lite has a single reset button as gpio 16 */ -+ rbspi_register_reset_button(RBMAPL_GPIO_BTN_RESET); -+ -+ /* clear internal multiplexing */ -+ ath79_gpio_output_select(RBMAPL_GPIO_LED_ETH, AR934X_GPIO_OUT_GPIO); -+ ath79_gpio_output_select(RBMAPL_GPIO_LED_POWER, AR934X_GPIO_OUT_GPIO); -+} -+ -+/* -+ * Init the hAP lite hardware (QCA953x). -+ * The 941-2nD (hAP lite) has 4 ethernet ports, with port 2-4 -+ * being assigned to LAN on the casing, and port 1 being assigned -+ * to "internet" (WAN) on the casing. Port 1 is connected to PHY3. -+ * Since WAN is neither PHY0 nor PHY4, we cannot use GMAC0 with this device. -+ */ -+static void __init rbhapl_setup(void) -+{ -+ u32 flags = RBSPI_HAS_WLAN0; -+ -+ if (!rbspi_platform_setup()) -+ return; -+ -+ rbspi_peripherals_setup(flags); -+ -+ /* GMAC1 is HW MAC, WLAN0 MAC is HW MAC + 4 */ -+ rbspi_network_setup(flags, 0, 4, 0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rbhapl_leds), rbhapl_leds); -+ -+ /* hAP lite has a single reset button as gpio 16 */ -+ rbspi_register_reset_button(RBHAPL_GPIO_BTN_RESET); -+} -+ -+/* -+ * The hAP, hAP ac lite, hEX lite and hEX PoE lite share the same platform -+ */ -+static void __init rbspi_952_750r2_setup(u32 flags) -+{ -+ if (flags & RBSPI_HAS_SSR) -+ rbspi_spi_cs_gpios[1] = RB952_GPIO_SSR_CS; -+ -+ rbspi_peripherals_setup(flags); -+ -+ /* -+ * GMAC1 is HW MAC + 1, WLAN0 MAC IS HW MAC + 5 (hAP), -+ * WLAN1 MAC IS HW MAC + 6 (hAP ac lite) -+ */ -+ rbspi_network_setup(flags, 1, 5, 6); -+ -+ if (flags & RBSPI_HAS_USB) -+ gpio_request_one(RB952_GPIO_USB_PWROFF, GPIOF_ACTIVE_LOW | -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power off"); -+ -+ if (flags & RBSPI_HAS_POE) -+ gpio_request_one(RB952_GPIO_POE_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "POE power"); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rb952_leds), rb952_leds); -+ -+ /* These devices have a single reset button as gpio 16 */ -+ rbspi_register_reset_button(RB952_GPIO_BTN_RESET); -+} -+ -+/* -+ * Init the hAP (ac lite) hardware (QCA953x). -+ * The 951Ui-2nD (hAP) has 5 ethernet ports, with ports 2-5 being assigned -+ * to LAN on the casing, and port 1 being assigned to "internet" (WAN). -+ * Port 1 is connected to PHY4 (the ports are labelled in reverse physical -+ * number), so the SoC can be set to connect GMAC0 to PHY4 and GMAC1 to the -+ * internal switch for the LAN ports. -+ * The device also has USB, PoE output and an SSR used for LED multiplexing. -+ * The 952Ui-5ac2nD (hAP ac lite) is nearly identical to the hAP, it adds a -+ * QCA9887 5GHz radio via PCI and moves 2.4GHz from WLAN0 to WLAN1. -+ */ -+static void __init rb952_setup(void) -+{ -+ u32 flags = RBSPI_HAS_WAN4 | RBSPI_HAS_USB | -+ RBSPI_HAS_SSR | RBSPI_HAS_POE; -+ -+ if (!rbspi_platform_setup()) -+ return; -+ -+ /* differentiate the hAP from the hAP ac lite */ -+ if (strstr(mips_get_machine_name(), "952Ui-5ac2nD")) -+ flags |= RBSPI_HAS_WLAN1 | RBSPI_HAS_PCI; -+ else -+ flags |= RBSPI_HAS_WLAN0; -+ -+ rbspi_952_750r2_setup(flags); -+} -+ -+/* -+ * Init the hEX (PoE) lite hardware (QCA953x). -+ * The 750UP r2 (hEX PoE lite) is nearly identical to the hAP, only without -+ * WLAN. The 750 r2 (hEX lite) is nearly identical to the 750UP r2, only -+ * without USB and POE. The 750P Pbr2 (Powerbox) is nearly identical to hEX PoE -+ * lite, only without USB. It shares the same bootloader board identifier. -+ */ -+static void __init rb750upr2_setup(void) -+{ -+ u32 flags = RBSPI_HAS_WAN4 | RBSPI_HAS_SSR; -+ -+ if (!rbspi_platform_setup()) -+ return; -+ -+ /* differentiate the hEX lite from the hEX PoE lite */ -+ if (strstr(mips_get_machine_name(), "750UP r2")) -+ flags |= RBSPI_HAS_USB | RBSPI_HAS_POE; -+ -+ /* differentiate the Powerbox from the hEX lite */ -+ else if (strstr(mips_get_machine_name(), "750P r2")) -+ flags |= RBSPI_HAS_POE; -+ -+ rbspi_952_750r2_setup(flags); -+} -+ -+/* -+ * Init the hAP ac / 962UiGS-5HacT2HnT hardware (QCA9558). -+ * The hAP ac has 5 ethernet ports provided by an AR8337 switch. Port 1 is -+ * assigned to WAN, ports 2-5 are assigned to LAN. Port 0 is connected to the -+ * SoC, ports 1-5 of the switch are connected to physical ports 1-5 in order. -+ * The SFP cage is not assigned by default on RouterOS. Extra work is required -+ * to support this interface as it is directly connected to the SoC (eth1). -+ * Wireless is provided by a 2.4GHz radio on the SoC (WLAN1) and a 5GHz radio -+ * attached via PCI (QCA9880). Red and green WLAN LEDs are populated however -+ * they are not attached to GPIOs, extra work is required to support these. -+ * PoE and USB output power control is supported. -+ */ -+static void __init rb962_setup(void) -+{ -+ u32 flags = RBSPI_HAS_USB | RBSPI_HAS_POE | RBSPI_HAS_PCI; -+ -+ if (!rbspi_platform_setup()) -+ return; -+ -+ rbspi_peripherals_setup(flags); -+ -+ /* Do not call rbspi_network_setup as we have a discrete switch chip */ -+ ath79_eth0_pll_data.pll_1000 = 0xae000000; -+ ath79_eth0_pll_data.pll_100 = 0xa0000101; -+ ath79_eth0_pll_data.pll_10 = 0xa0001313; -+ -+ ath79_register_mdio(0, 0x0); -+ mdiobus_register_board_info(rb962_mdio0_info, -+ ARRAY_SIZE(rb962_mdio0_info)); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_register_eth(0); -+ -+ /* WLAN1 MAC is HW MAC + 7 */ -+ rbspi_wlan_init(7); -+ -+ if (flags & RBSPI_HAS_USB) -+ gpio_request_one(RB962_GPIO_USB_PWROFF, GPIOF_ACTIVE_LOW | -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power off"); -+ -+ /* PoE output GPIO is inverted, set GPIOF_ACTIVE_LOW for consistency */ -+ if (flags & RBSPI_HAS_POE) -+ gpio_request_one(RB962_GPIO_POE_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_ACTIVE_LOW | -+ GPIOF_EXPORT_DIR_FIXED, -+ "POE power"); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rb962_leds_gpio), -+ rb962_leds_gpio); -+ -+ /* This device has a single reset button as gpio 20 */ -+ rbspi_register_reset_button(RB962_GPIO_BTN_RESET); -+} -+ -+/* -+ * Init the LHG hardware (AR9344). -+ * The LHG 5nD has a single ethernet port connected to PHY0. -+ * Wireless is provided via 5GHz WLAN1. -+ */ -+static void __init rblhg_setup(void) -+{ -+ u32 flags = RBSPI_HAS_WLAN1 | RBSPI_HAS_MDIO1; -+ -+ if (!rbspi_platform_setup()) -+ return; -+ -+ rbspi_peripherals_setup(flags); -+ -+ /* GMAC1 is HW MAC, WLAN1 MAC is HW MAC + 1 */ -+ rbspi_network_setup(flags, 0, 0, 1); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rblhg_leds), rblhg_leds); -+ -+ rbspi_register_reset_button(RBLHG_GPIO_BTN_RESET); -+} -+ -+/* -+ * Init the wAP hardware. -+ * The wAP 2nD has a single ethernet port. -+ */ -+static void __init rbwap_setup(void) -+{ -+ u32 flags = RBSPI_HAS_WLAN0; -+ -+ if (!rbspi_platform_setup()) -+ return; -+ -+ rbspi_peripherals_setup(flags); -+ -+ /* GMAC1 is HW MAC, WLAN0 MAC is HW MAC + 1 */ -+ rbspi_network_setup(flags, 0, 1, 0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rbwap_leds), rbwap_leds); -+ -+ /* wAP has a single reset button as GPIO 16 */ -+ rbspi_register_reset_button(RBWAP_GPIO_BTN_RESET); -+} -+ -+/* -+ * Init the cAP hardware (EXPERIMENTAL). -+ * The cAP 2nD has a single ethernet port, and a global LED switch. -+ */ -+static void __init rbcap_setup(void) -+{ -+ u32 flags = RBSPI_HAS_WLAN0; -+ -+ if (!rbspi_platform_setup()) -+ return; -+ -+ rbspi_peripherals_setup(flags); -+ -+ /* GMAC1 is HW MAC, WLAN0 MAC is HW MAC + 1 */ -+ rbspi_network_setup(flags, 0, 1, 0); -+ -+ gpio_request_one(RBCAP_GPIO_LED_ALL, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "LEDs enable"); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rbcap_leds), rbcap_leds); -+} -+ -+/* -+ * Init the mAP hardware. -+ * The mAP 2nD has two ethernet ports, PoE output, SSR for LED -+ * multiplexing and USB port. -+ */ -+static void __init rbmap_setup(void) -+{ -+ u32 flags = RBSPI_HAS_USB | RBSPI_HAS_WLAN0 | -+ RBSPI_HAS_SSR | RBSPI_HAS_POE; -+ -+ if (!rbspi_platform_setup()) -+ return; -+ -+ rbspi_spi_cs_gpios[1] = RBMAP_GPIO_SSR_CS; -+ rbspi_peripherals_setup(flags); -+ -+ /* GMAC1 is HW MAC, WLAN0 MAC is HW MAC + 2 */ -+ rbspi_network_setup(flags, 0, 2, 0); -+ -+ if (flags & RBSPI_HAS_POE) -+ gpio_request_one(RBMAP_GPIO_POE_POWER, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "POE power"); -+ -+ if (flags & RBSPI_HAS_USB) -+ gpio_request_one(RBMAP_GPIO_USB_PWROFF, -+ GPIOF_OUT_INIT_HIGH | GPIOF_ACTIVE_LOW | -+ GPIOF_EXPORT_DIR_FIXED, -+ "USB power off"); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rbmap_leds), rbmap_leds); -+ -+ /* mAP 2nD has a single reset button as gpio 16 */ -+ rbspi_register_reset_button(RBMAP_GPIO_BTN_RESET); -+} -+ -+/* -+ * Init the wAPGSC (RB wAPG-5HacT2HnD // wAP AC) hardware. -+ * The wAPGSC has one Ethernet port via AR8033 with PoE input, dual radio (SoC -+ * 2.4 GHz and external QCA9880) and a ZT2046Q temperature and voltage sensor -+ * (currently not supported). -+ */ -+static void __init rbwapgsc_setup(void) -+{ -+ u32 flags = RBSPI_HAS_PCI; -+ -+ if (!rbspi_platform_setup()) -+ return; -+ -+ rbspi_peripherals_setup(flags); -+ -+ platform_device_register(&rbwapgsc_phy_device); -+ -+ mdiobus_register_board_info(rbwapgsc_mdio_info, -+ ARRAY_SIZE(rbwapgsc_mdio_info)); -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth1_data.mii_bus_dev = &rbwapgsc_phy_device.dev; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.phy_mask = BIT(RBWAPGSC_MDIO_PHYADDR); -+ ath79_eth1_data.enable_sgmii_fixup = 1; -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ ath79_eth1_pll_data.pll_100 = 0x80000101; -+ ath79_eth1_pll_data.pll_10 = 0x80001313; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_register_eth(1); -+ -+ rbspi_wlan_init(2); -+ -+ rbspi_register_reset_button(RBWAPGSC_GPIO_BTN_RESET); -+ -+ ath79_gpio_function_enable(QCA955X_GPIO_FUNC_JTAG_DISABLE| -+ QCA955X_GPIO_REG_OUT_FUNC4| -+ QCA955X_GPIO_REG_OUT_FUNC3); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rbwapgsc_leds), -+ rbwapgsc_leds); -+} -+ -+/* -+ * Setup the 911L hardware (AR9344). -+ */ -+static void __init rb911l_setup(void) -+{ -+ const struct rb_info *info; -+ -+ info = rbspi_platform_setup(); -+ if (!info) -+ return; -+ -+ if (!rb_has_hw_option(info, RB_HW_OPT_NO_NAND)) { -+ /* -+ * Old hardware revisions might be equipped with a NAND flash -+ * chip instead of the 16MiB SPI NOR device. Those boards are -+ * not supported at the moment, so throw a warning and skip -+ * the peripheral setup to avoid messing up the data in the -+ * flash chip. -+ */ -+ WARN(1, "The NAND flash on this board is not supported.\n"); -+ } else { -+ rbspi_peripherals_setup(0); -+ } -+ -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 0); -+ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(1); -+ -+ rbspi_wlan_init(1); -+ -+ rbspi_register_reset_button(RB911L_GPIO_BTN_RESET); -+ -+ /* Make the eth LED controllable by software. */ -+ ath79_gpio_output_select(RB911L_GPIO_LED_ETH, AR934X_GPIO_OUT_GPIO); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rb911l_leds), rb911l_leds); -+} -+ -+/* -+ * Init the hAP mini hardware (QCA953x). -+ * The 931-2nD (hAP mini) has 3 ethernet ports, with port 2-3 -+ * being assigned to LAN on the casing, and port 1 being assigned -+ * to "internet" (WAN) on the casing. Port 1 is connected to PHY2. -+ * Since WAN is neither PHY0 nor PHY4, we cannot use GMAC0 with this device. -+ */ -+static void __init rb931_setup(void) -+{ -+ u32 flags = RBSPI_HAS_WLAN0; -+ -+ if (!rbspi_platform_setup()) -+ return; -+ -+ rbspi_peripherals_setup(flags); -+ -+ /* GMAC1 is HW MAC, WLAN0 MAC is HW MAC + 3 */ -+ rbspi_network_setup(flags, 0, 3, 0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rb931_leds), rb931_leds); -+ -+ /* hAP mini has two buttons */ -+ ath79_register_gpio_keys_polled(-1, RBSPI_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(rb931_gpio_keys), -+ rb931_gpio_keys); -+} -+ -+/* -+ * Init the wAP R hardware. -+ * The wAP R-2nD has a single ethernet port and a mini PCIe slot. -+ * The OEM source shows it has usb (used over PCIe for LTE devices), -+ * and the 'control' GPIO is assumed to be an output pin not tied to an LED. -+ */ -+static void __init rbwapr_setup(void) -+{ -+ u32 flags = RBSPI_HAS_WLAN0 | RBSPI_HAS_USB | RBSPI_HAS_PCI; -+ -+ if (!rbspi_platform_setup()) -+ return; -+ -+ rbspi_peripherals_setup(flags); -+ -+ /* GMAC1 is HW MAC, WLAN0 MAC is HW MAC + 1 */ -+ rbspi_network_setup(flags, 0, 1, 0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rbwapr_leds), rbwapr_leds); -+ -+ gpio_request_one(RBWAPR_GPIO_PCIE_PWROFF, GPIOF_OUT_INIT_HIGH | -+ GPIOF_ACTIVE_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "PCIE power off"); -+ -+ gpio_request_one(RBWAPR_GPIO_CONTROL, GPIOF_OUT_INIT_LOW | -+ GPIOF_ACTIVE_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "control"); -+ -+ rbspi_register_reset_button(RBWAPR_GPIO_BTN_RESET); -+} -+ -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_MAPL, "map-hb", rbmapl_setup); -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_941, "H951L", rbhapl_setup); -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_911L, "911L", rb911l_setup); -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_952, "952-hb", rb952_setup); -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_962, "962", rb962_setup); -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_750UPR2, "750-hb", rb750upr2_setup); -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_LHG5, "lhg", rblhg_setup); -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_WAP, "wap-hb", rbwap_setup); -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_WAPR, "wap-lte", rbwapr_setup); -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_CAP, "cap-hb", rbcap_setup); -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_MAP, "map2-hb", rbmap_setup); -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_WAPAC, "wapg-sc", rbwapgsc_setup); -+MIPS_MACHINE_NONAME(ATH79_MACH_RB_931, "931", rb931_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rbsxtlite.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rbsxtlite.c -new file mode 100644 -index 0000000000..7eb0e54151 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rbsxtlite.c -@@ -0,0 +1,302 @@ -+/* -+ * MikroTik RouterBOARD SXT Lite support -+ * -+ * Copyright (C) 2012 Stijn Tintel -+ * Copyright (C) 2012 Gabor Juhos -+ * Copyright (C) 2013 Vyacheslav Adamanov -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#define pr_fmt(fmt) "sxtlite: " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) -+#include -+#else -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-eth.h" -+#include "dev-m25p80.h" -+#include "dev-nfc.h" -+#include "dev-wmac.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+#include "routerboot.h" -+#include -+ -+#define SXTLITE_GPIO_NAND_NCE 14 -+#define SXTLITE_GPIO_LED_USER 3 -+#define SXTLITE_GPIO_LED_1 13 -+#define SXTLITE_GPIO_LED_2 12 -+#define SXTLITE_GPIO_LED_3 4 -+#define SXTLITE_GPIO_LED_4 21 -+#define SXTLITE_GPIO_LED_5 18 -+#define SXTLITE_GPIO_LED_POWER 11 -+ -+#define SXTLITE_GPIO_BUZZER 19 -+ -+#define SXTLITE_GPIO_BTN_RESET 15 -+ -+#define SXTLITE_KEYS_POLL_INTERVAL 20 -+#define SXTLITE_KEYS_DEBOUNCE_INTERVAL (3 * SXTLITE_KEYS_POLL_INTERVAL) -+ -+static struct mtd_partition rbsxtlite_nand_partitions[] = { -+ { -+ .name = "booter", -+ .offset = 0, -+ .size = (256 * 1024), -+ .mask_flags = MTD_WRITEABLE, -+ }, -+ { -+ .name = "kernel", -+ .offset = (256 * 1024), -+ .size = (4 * 1024 * 1024) - (256 * 1024), -+ }, -+ { -+ .name = "ubi", -+ .offset = MTDPART_OFS_NXTBLK, -+ .size = MTDPART_SIZ_FULL, -+ }, -+}; -+ -+static struct gpio_led rbsxtlite_leds_gpio[] __initdata = { -+ { -+ .name = "rb:green:user", -+ .gpio = SXTLITE_GPIO_LED_USER, -+ .active_low = 1, -+ }, -+ { -+ .name = "rb:green:led1", -+ .gpio = SXTLITE_GPIO_LED_1, -+ .active_low = 1, -+ }, -+ { -+ .name = "rb:green:led2", -+ .gpio = SXTLITE_GPIO_LED_2, -+ .active_low = 1, -+ }, -+ { -+ .name = "rb:green:led3", -+ .gpio = SXTLITE_GPIO_LED_3, -+ .active_low = 1, -+ }, -+ { -+ .name = "rb:green:led4", -+ .gpio = SXTLITE_GPIO_LED_4, -+ .active_low = 1, -+ }, -+ { -+ .name = "rb:green:led5", -+ .gpio = SXTLITE_GPIO_LED_5, -+ .active_low = 1, -+ }, -+ { -+ .name = "rb:green:power", -+ .gpio = SXTLITE_GPIO_LED_POWER, -+ .default_state = LEDS_GPIO_DEFSTATE_ON, -+ }, -+}; -+ -+static struct gpio_keys_button rbsxtlite_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = SXTLITE_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = SXTLITE_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+}; -+ -+static int __init rbsxtlite_rbinfo_init(void) -+{ -+ const struct rb_info *info; -+ -+ info = rb_init_info((void *)(KSEG1ADDR(AR71XX_SPI_BASE)), 0x10000); -+ if (!info) -+ return -EINVAL; -+ return 0; -+ -+} -+ -+void __init rbsxtlite_wlan_init(void) -+{ -+ char *art_buf; -+ u8 wlan_mac[ETH_ALEN]; -+ -+ art_buf = rb_get_wlan_data(); -+ if (art_buf == NULL) -+ return; -+ -+ ath79_init_mac(wlan_mac, ath79_mac_base, 1); -+ ath79_register_wmac(art_buf + 0x1000, wlan_mac); -+ -+ kfree(art_buf); -+} -+ -+static void rbsxtlite_nand_select_chip(int chip_no) -+{ -+ switch (chip_no) { -+ case 0: -+ gpio_set_value(SXTLITE_GPIO_NAND_NCE, 0); -+ break; -+ default: -+ gpio_set_value(SXTLITE_GPIO_NAND_NCE, 1); -+ break; -+ } -+ ndelay(500); -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+static struct nand_ecclayout rbsxtlite_nand_ecclayout = { -+ .eccbytes = 6, -+ .eccpos = { 8, 9, 10, 13, 14, 15 }, -+ .oobavail = 9, -+ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } -+}; -+ -+#else -+ -+static int rbsxtlite_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 8; -+ oobregion->length = 3; -+ return 0; -+ case 1: -+ oobregion->offset = 13; -+ oobregion->length = 3; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static int rbsxtlite_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 0; -+ oobregion->length = 4; -+ return 0; -+ case 1: -+ oobregion->offset = 4; -+ oobregion->length = 1; -+ return 0; -+ case 2: -+ oobregion->offset = 6; -+ oobregion->length = 2; -+ return 0; -+ case 3: -+ oobregion->offset = 11; -+ oobregion->length = 2; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static const struct mtd_ooblayout_ops rbsxtlite_nand_ecclayout_ops = { -+ .ecc = rbsxtlite_ooblayout_ecc, -+ .free = rbsxtlite_ooblayout_free, -+}; -+#endif /* < 4.6 */ -+ -+static int rbsxtlite_nand_scan_fixup(struct mtd_info *mtd) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ struct nand_chip *chip = mtd->priv; -+#endif -+ -+ if (mtd->writesize == 512) { -+ /* -+ * Use the OLD Yaffs-1 OOB layout, otherwise RouterBoot -+ * will not be able to find the kernel that we load. -+ */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ chip->ecc.layout = &rbsxtlite_nand_ecclayout; -+#else -+ mtd_set_ooblayout(mtd, &rbsxtlite_nand_ecclayout_ops); -+#endif -+ } -+ -+ return 0; -+} -+ -+void __init rbsxtlite_gpio_init(void) -+{ -+ gpio_request_one(SXTLITE_GPIO_NAND_NCE, GPIOF_OUT_INIT_HIGH, "NAND nCE"); -+} -+ -+void __init rbsxtlite_nand_init(void) -+{ -+ ath79_nfc_set_scan_fixup(rbsxtlite_nand_scan_fixup); -+ ath79_nfc_set_parts(rbsxtlite_nand_partitions, -+ ARRAY_SIZE(rbsxtlite_nand_partitions)); -+ ath79_nfc_set_select_chip(rbsxtlite_nand_select_chip); -+ ath79_nfc_set_swap_dma(true); -+ ath79_register_nfc(); -+} -+ -+ -+static void __init rbsxtlite_setup(void) -+{ -+ if(rbsxtlite_rbinfo_init()) -+ return; -+ rbsxtlite_nand_init(); -+ rbsxtlite_wlan_init(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rbsxtlite_leds_gpio), -+ rbsxtlite_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, SXTLITE_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(rbsxtlite_gpio_keys), -+ rbsxtlite_gpio_keys); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ /* GMAC0 is left unused */ -+ -+ /* GMAC1 is connected to MAC0 on the internal switch */ -+ /* The ethernet port connects to PHY P0, which connects to MAC1 -+ on the internal switch */ -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_register_eth(1); -+ -+ -+} -+ -+ -+MIPS_MACHINE(ATH79_MACH_RB_SXTLITE2ND, "sxt2n", "MikroTik RouterBOARD SXT Lite2", -+ rbsxtlite_setup); -+ -+MIPS_MACHINE(ATH79_MACH_RB_SXTLITE5ND, "sxt5n", "MikroTik RouterBOARD SXT Lite5", -+ rbsxtlite_setup); -+ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-re450.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-re450.c -new file mode 100644 -index 0000000000..991aa1c9a9 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-re450.c -@@ -0,0 +1,239 @@ -+/* -+ * TP-LINK RE355/RE450 board support -+ * -+ * Copyright (c) 2013 Gabor Juhos -+ * Copyright (c) 2016 Tal Keren -+ * Copyright (c) 2018 Henryk Heisig -+ * -+ * Based on the Qualcomm Atheros AP135/AP136 reference board support code -+ * Copyright (c) 2012 Qualcomm Atheros -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define RE450_GPIO_LED_SYSTEM 12 -+#define RE450_GPIO_LED_WLAN2G 13 -+#define RE450_GPIO_LED_WLAN5G 14 -+#define RE450_GPIO_LED_LAN_DATA 17 -+#define RE450_GPIO_LED_JUMPSTART 21 -+#define RE450_GPIO_LED_JUMPSTART_RED 22 -+#define RE450_GPIO_LED_LAN_LINK 23 -+ -+#define RE450_GPIO_BTN_RESET 18 -+#define RE450_GPIO_BTN_LED 19 -+#define RE450_GPIO_BTN_JUMPSTART 20 -+ -+#define RE450_GPIO_SMI_MDIO 1 -+#define RE450_GPIO_SMI_MDC 3 -+ -+#define RE450_LAN_PHYADDR 4 -+ -+#define RE450_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define RE450_KEYS_DEBOUNCE_INTERVAL (3 * RE450_KEYS_POLL_INTERVAL) -+ -+#define RE450_WMAC_CALDATA_OFFSET 0x1000 -+ -+static const char *tl_re450_part_probes[] = { -+ "cmdlinepart", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_re450_flash_data = { -+ .part_probes = tl_re450_part_probes, -+}; -+ -+static struct gpio_led re355_leds_gpio[] __initdata = { -+ { -+ .name = "re355:blue:power", -+ .gpio = RE450_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+ { -+ .name = "re355:blue:wlan2g", -+ .gpio = RE450_GPIO_LED_WLAN2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "re355:blue:wlan5g", -+ .gpio = RE450_GPIO_LED_WLAN5G, -+ .active_low = 1, -+ }, -+ { -+ .name = "re355:blue:wps", -+ .gpio = RE450_GPIO_LED_JUMPSTART, -+ }, -+ { -+ .name = "re355:red:wps", -+ .gpio = RE450_GPIO_LED_JUMPSTART_RED, -+ }, -+ { -+ .name = "re355:green:lan_data", -+ .gpio = RE450_GPIO_LED_LAN_DATA, -+ .active_low = 1, -+ }, -+ { -+ .name = "re355:green:lan_link", -+ .gpio = RE450_GPIO_LED_LAN_LINK, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led re450_leds_gpio[] __initdata = { -+ { -+ .name = "re450:blue:power", -+ .gpio = RE450_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+ { -+ .name = "re450:blue:wlan2g", -+ .gpio = RE450_GPIO_LED_WLAN2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "re450:blue:wlan5g", -+ .gpio = RE450_GPIO_LED_WLAN5G, -+ .active_low = 1, -+ }, -+ { -+ .name = "re450:blue:wps", -+ .gpio = RE450_GPIO_LED_JUMPSTART, -+ }, -+ { -+ .name = "re450:red:wps", -+ .gpio = RE450_GPIO_LED_JUMPSTART_RED, -+ }, -+ { -+ .name = "re450:green:lan_data", -+ .gpio = RE450_GPIO_LED_LAN_DATA, -+ .active_low = 1, -+ }, -+ { -+ .name = "re450:green:lan_link", -+ .gpio = RE450_GPIO_LED_LAN_LINK, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button re450_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = RE450_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = RE450_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = RE450_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = RE450_GPIO_BTN_JUMPSTART, -+ .active_low = 1, -+ }, -+ { -+ .desc = "Control LED button", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = RE450_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = RE450_GPIO_BTN_LED, -+ .active_low = 1, -+ }, -+}; -+ -+static struct mdio_gpio_platform_data re450_mdio = { -+ .mdc = RE450_GPIO_SMI_MDC, -+ .mdio = RE450_GPIO_SMI_MDIO, -+ .phy_mask = ~BIT(RE450_LAN_PHYADDR), -+}; -+ -+static struct platform_device re450_phy_device = { -+ .name = "mdio-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &re450_mdio, -+ }, -+}; -+ -+static void __init rex5x_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f610008); -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 tmpmac[ETH_ALEN]; -+ -+ ath79_register_m25p80(&tl_re450_flash_data); -+ ath79_register_gpio_keys_polled(-1, RE450_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(re450_gpio_keys), -+ re450_gpio_keys); -+ -+ ath79_init_mac(tmpmac, mac, -1); -+ ath79_register_wmac(art + RE450_WMAC_CALDATA_OFFSET, tmpmac); -+ -+ ath79_register_pci(); -+ -+ /* MDIO Interface */ -+ platform_device_register(&re450_phy_device); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ /* GMAC0 is connected to the RGMII interface to an Atheros AR8035-A */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_eth0_data.mii_bus_dev = &re450_phy_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(RE450_LAN_PHYADDR); -+ ath79_eth0_pll_data.pll_1000 = 0xa6000000; -+ ath79_eth0_pll_data.pll_100 = 0xa0000101; -+ ath79_eth0_pll_data.pll_10 = 0x80001313; -+ ath79_register_eth(0); -+} -+ -+static void __init re355_setup(void) -+{ -+ rex5x_setup(); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(re355_leds_gpio), -+ re355_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RE355, "RE355", "TP-LINK RE355", -+ re355_setup) -+ -+static void __init re450_setup(void) -+{ -+ rex5x_setup(); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(re450_leds_gpio), -+ re450_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RE450, "RE450", "TP-LINK RE450", -+ re450_setup) -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rme-eg200.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rme-eg200.c -new file mode 100644 -index 0000000000..332b0780d0 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rme-eg200.c -@@ -0,0 +1,99 @@ -+/* -+ * eTactica EG-200 board, based on 8devices Carambola2 module -+ * -+ * Copyright (C) 2015 Karl Palsson -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define RME_EG200_GPIO_LED_WLAN 0 -+#define RME_EG200_GPIO_LED_ETH0 13 -+#define RME_EG200_GPIO_LED_ETACTICA 15 -+#define RME_EG200_GPIO_LED_MODBUS 16 -+ -+#define RME_EG200_GPIO_BTN_RESTORE 11 -+ -+#define RME_EG200_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define RME_EG200_KEYS_DEBOUNCE_INTERVAL (3 * RME_EG200_KEYS_POLL_INTERVAL) -+ -+#define RME_EG200_MAC0_OFFSET 0x0000 -+#define RME_EG200_CALDATA_OFFSET 0x1000 -+#define RME_EG200_WMAC_MAC_OFFSET 0x1002 -+ -+static struct gpio_led rme_eg200_leds_gpio[] __initdata = { -+ { -+ .name = "eg200:red:wlan", -+ .gpio = RME_EG200_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "eg200:red:eth0", -+ .gpio = RME_EG200_GPIO_LED_ETH0, -+ .active_low = 1, -+ }, { -+ .name = "eg200:red:etactica", -+ .gpio = RME_EG200_GPIO_LED_ETACTICA, -+ .active_low = 0, -+ }, { -+ .name = "eg200:red:modbus", -+ .gpio = RME_EG200_GPIO_LED_MODBUS, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button rme_eg200_keys[] __initdata = { -+ { -+ .desc = "restore button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = RME_EG200_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = RME_EG200_GPIO_BTN_RESTORE, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init rme_eg200_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_wmac(art + RME_EG200_CALDATA_OFFSET, -+ art + RME_EG200_WMAC_MAC_OFFSET); -+ -+ ath79_setup_ar933x_phy4_switch(true, true); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + RME_EG200_MAC0_OFFSET, 0); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* WAN port */ -+ ath79_register_eth(0); -+ -+ ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rme_eg200_leds_gpio), -+ rme_eg200_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, RME_EG200_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(rme_eg200_keys), -+ rme_eg200_keys); -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RME_EG200, "RME-EG200", "eTactica EG-200", -+ rme_eg200_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rut9xx.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rut9xx.c -new file mode 100644 -index 0000000000..43a2a78c67 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rut9xx.c -@@ -0,0 +1,191 @@ -+/* -+ * Teltonika RUT900 series boards support -+ * -+ * Copyright (C) 2018 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define RUT9XX_GPIO_LED_LAN1 14 -+#define RUT9XX_GPIO_LED_LAN2 13 -+#define RUT9XX_GPIO_LED_LAN3 22 -+#define RUT9XX_GPIO_LED_WAN 1 -+ -+#define RUT9XX_PCA9539_GPIO_BASE 32 -+#define RUT9XX_PCA9539_GPIO_SIGNAL1 (0 + RUT9XX_PCA9539_GPIO_BASE) -+#define RUT9XX_PCA9539_GPIO_SIGNAL2 (1 + RUT9XX_PCA9539_GPIO_BASE) -+#define RUT9XX_PCA9539_GPIO_SIGNAL3 (2 + RUT9XX_PCA9539_GPIO_BASE) -+#define RUT9XX_PCA9539_GPIO_SIGNAL4 (3 + RUT9XX_PCA9539_GPIO_BASE) -+#define RUT9XX_PCA9539_GPIO_SIGNAL5 (4 + RUT9XX_PCA9539_GPIO_BASE) -+#define RUT9XX_PCA9539_GPIO_STATUS_R (5 + RUT9XX_PCA9539_GPIO_BASE) -+#define RUT9XX_PCA9539_GPIO_STATUS_G (6 + RUT9XX_PCA9539_GPIO_BASE) -+ -+#define RUT9XX_GPIO_BTN_RESET 15 -+ -+#define RUT9XX_GPIO_I2C_SCK 16 -+#define RUT9XX_GPIO_I2C_SDA 17 -+ -+#define RUT9XX_GPIO_EXT_LNA0 2 -+ -+#define RUT9XX_WMAC_CALDATA_OFFSET 0x1000 -+ -+#define RUT9XX_KEYS_POLL_INTERVAL 20 -+#define RUT9XX_KEYS_DEBOUNCE_INTERVAL (3 * RUT9XX_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led rut900_leds_gpio[] __initdata = { -+ { -+ .name = "rut900:green:lan1", -+ .gpio = RUT9XX_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "rut900:green:lan2", -+ .gpio = RUT9XX_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "rut900:green:lan3", -+ .gpio = RUT9XX_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "rut900:green:signal1", -+ .gpio = RUT9XX_PCA9539_GPIO_SIGNAL1, -+ .active_low = 0, -+ }, { -+ .name = "rut900:green:signal2", -+ .gpio = RUT9XX_PCA9539_GPIO_SIGNAL2, -+ .active_low = 0, -+ }, { -+ .name = "rut900:green:signal3", -+ .gpio = RUT9XX_PCA9539_GPIO_SIGNAL3, -+ .active_low = 0, -+ }, { -+ .name = "rut900:green:signal4", -+ .gpio = RUT9XX_PCA9539_GPIO_SIGNAL4, -+ .active_low = 0, -+ }, { -+ .name = "rut900:green:signal5", -+ .gpio = RUT9XX_PCA9539_GPIO_SIGNAL5, -+ .active_low = 0, -+ }, { -+ .name = "rut900:green:status", -+ .gpio = RUT9XX_PCA9539_GPIO_STATUS_G, -+ .active_low = 0, -+ }, { -+ .name = "rut900:green:wan", -+ .gpio = RUT9XX_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "rut900:red:status", -+ .gpio = RUT9XX_PCA9539_GPIO_STATUS_R, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button rut900_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = RUT9XX_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = RUT9XX_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct i2c_gpio_platform_data rut900_i2c_gpio_data = { -+ .sda_pin = RUT9XX_GPIO_I2C_SDA, -+ .scl_pin = RUT9XX_GPIO_I2C_SCK, -+ .udelay = 10, -+}; -+ -+static struct platform_device rut900_i2c_device = { -+ .name = "i2c-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &rut900_i2c_gpio_data, -+ }, -+}; -+ -+static struct pca953x_platform_data rut9xx_pca9539_data = { -+ .gpio_base = RUT9XX_PCA9539_GPIO_BASE, -+ .irq_base = -1, -+}; -+ -+static struct i2c_board_info rut900_i2c_devs[] __initdata = { -+ { -+ I2C_BOARD_INFO("pca9539", 0x74), -+ .platform_data = &rut9xx_pca9539_data, -+ }, -+}; -+ -+static void __init rut900_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1f030000); -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f020000); -+ u8 wlan_mac[ETH_ALEN]; -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = 0xf1; -+ -+ /* LAN */ -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_register_eth(0); -+ -+ platform_device_register(&rut900_i2c_device); -+ i2c_register_board_info(0, rut900_i2c_devs, -+ ARRAY_SIZE(rut900_i2c_devs)); -+ -+ /* Disable JTAG (enables GPIO0-3) */ -+ ath79_gpio_function_enable(AR934X_GPIO_FUNC_JTAG_DISABLE); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rut900_leds_gpio), -+ rut900_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, RUT9XX_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(rut900_gpio_keys), -+ rut900_gpio_keys); -+ -+ ath79_wmac_set_ext_lna_gpio(0, RUT9XX_GPIO_EXT_LNA0); -+ -+ ath79_init_mac(wlan_mac, mac, 2); -+ ath79_register_wmac(art + RUT9XX_WMAC_CALDATA_OFFSET, wlan_mac); -+ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RUT9XX, "RUT900", "Teltonika RUT900", rut900_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rw2458n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rw2458n.c -new file mode 100644 -index 0000000000..bb7c2475bd ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rw2458n.c -@@ -0,0 +1,91 @@ -+/* -+ * Redwave RW2458N support -+ * -+ * Copyright (C) 2011-2013 Cezary Jackiewicz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define RW2458N_GPIO_LED_D3 1 -+#define RW2458N_GPIO_LED_D4 0 -+#define RW2458N_GPIO_LED_D5 11 -+#define RW2458N_GPIO_LED_D6 7 -+#define RW2458N_GPIO_BTN_RESET 12 -+ -+#define RW2458N_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define RW2458N_KEYS_DEBOUNCE_INTERVAL (3 * RW2458N_KEYS_POLL_INTERVAL) -+ -+static struct gpio_keys_button rw2458n_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = RW2458N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = RW2458N_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+#define RW2458N_WAN_PHYMASK BIT(4) -+ -+static struct gpio_led rw2458n_leds_gpio[] __initdata = { -+ { -+ .name = "rw2458n:green:d3", -+ .gpio = RW2458N_GPIO_LED_D3, -+ .active_low = 1, -+ }, { -+ .name = "rw2458n:green:d4", -+ .gpio = RW2458N_GPIO_LED_D4, -+ .active_low = 1, -+ }, { -+ .name = "rw2458n:green:d5", -+ .gpio = RW2458N_GPIO_LED_D5, -+ .active_low = 1, -+ }, { -+ .name = "rw2458n:green:d6", -+ .gpio = RW2458N_GPIO_LED_D6, -+ .active_low = 1, -+ } -+}; -+ -+static void __init rw2458n_setup(void) -+{ -+ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac2 = (u8 *) KSEG1ADDR(0x1fff0000 + ETH_ALEN); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_mdio(0, ~RW2458N_WAN_PHYMASK); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 0); -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(rw2458n_leds_gpio), -+ rw2458n_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, RW2458N_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(rw2458n_gpio_keys), -+ rw2458n_gpio_keys); -+ ath79_register_usb(); -+ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_RW2458N, "RW2458N", "Redwave RW2458N", -+ rw2458n_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-sc1750.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-sc1750.c -new file mode 100644 -index 0000000000..3a7d654b85 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-sc1750.c -@@ -0,0 +1,145 @@ -+/* -+ * Abicom International Scorpion SC1750 support. -+ * -+ * Copyright (c) 2012 Qualcomm Atheros -+ * Copyright (c) 2012-2013 Gabor Juhos -+ * Copyright (c) 2017 Conor O'Gorman -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-nfc.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define SC1750_GPIO_LED_POWER 11 -+#define SC1750_GPIO_LED_ERR1 12 -+#define SC1750_GPIO_LED_WLAN 13 -+#define SC1750_GPIO_LED_ERR2 14 -+#define SC1750_GPIO_LED_OK3 15 -+#define SC1750_GPIO_LED_ERR3 16 -+#define SC1750_GPIO_BTN_RESET 4 -+ -+#define SC1750_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define SC1750_KEYS_DEBOUNCE_INTERVAL (3 * SC1750_KEYS_POLL_INTERVAL) -+ -+#define SC1750_MAC0_OFFSET 0 -+#define SC1750_MAC1_OFFSET 6 -+#define SC1750_WMAC_CALDATA_OFFSET 0x1000 -+#define SC1750_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led sc1750_leds_gpio[] __initdata = { -+ { -+ .name = "sc1750:green:power", -+ .gpio = SC1750_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "sc1750:red:power", -+ .gpio = SC1750_GPIO_LED_ERR1, -+ .active_low = 1, -+ }, -+ { -+ .name = "sc1750:green:wlan", -+ .gpio = SC1750_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "sc1750:red:wlan", -+ .gpio = SC1750_GPIO_LED_ERR2, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button sc1750_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = SC1750_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = SC1750_GPIO_BTN_RESET, -+ .active_low = 0, -+ } -+}; -+ -+static struct at803x_platform_data at803x_data = { -+ .disable_smarteee = 1, -+ .enable_rgmii_rx_delay = 0, -+ .enable_rgmii_tx_delay = 0, -+}; -+ -+static struct mdio_board_info sc1750_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 1, -+ .platform_data = &at803x_data, -+ }, -+}; -+ -+static void __init sc1750_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(sc1750_leds_gpio), -+ sc1750_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, SC1750_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(sc1750_gpio_keys), -+ sc1750_gpio_keys); -+ -+ ath79_register_usb(); -+ ath79_register_nfc(); -+ -+ ath79_register_wmac(art + SC1750_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_mdio(0, 0); -+ mdiobus_register_board_info(sc1750_mdio0_info, -+ ARRAY_SIZE(sc1750_mdio0_info)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + SC1750_MAC0_OFFSET, 0); -+ -+ ath79_eth0_pll_data.pll_1000 = 0xa6000101; -+ ath79_eth0_pll_data.pll_100 = 0xa4000101; -+ /* GMAC0 is connected to the RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = 0xF; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(1); -+ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_SC1750, "SC1750", "Abicom SC1750", sc1750_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-sc300m.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-sc300m.c -new file mode 100644 -index 0000000000..6dd81ecd5a ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-sc300m.c -@@ -0,0 +1,132 @@ -+/* -+ * Abicom International Scorpion SC300M Module support. -+ * -+ * Copyright (c) 2012 Qualcomm Atheros -+ * Copyright (c) 2012-2013 Gabor Juhos -+ * Copyright (c) 2017 Conor O'Gorman -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-nfc.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define SC300M_GPIO_LED_WLAN 0 -+#define SC300M_GPIO_LED_POWER 1 -+ -+#define SC300M_GPIO_BTN_RESET 17 -+ -+#define SC300M_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define SC300M_KEYS_DEBOUNCE_INTERVAL (3 * SC300M_KEYS_POLL_INTERVAL) -+ -+#define SC300M_MAC0_OFFSET 0 -+#define SC300M_MAC1_OFFSET 6 -+#define SC300M_WMAC_CALDATA_OFFSET 0x1000 -+#define SC300M_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led sc300m_leds_gpio[] __initdata = { -+ { -+ .name = "sc300m:blue:wlan", -+ .gpio = SC300M_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "sc300m:blue:power", -+ .gpio = SC300M_GPIO_LED_POWER, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button sc300m_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = SC300M_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = SC300M_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static struct at803x_platform_data at803x_data = { -+ .disable_smarteee = 1, -+ .enable_rgmii_rx_delay = 0, -+ .enable_rgmii_tx_delay = 0, -+}; -+ -+static struct mdio_board_info sc300m_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 1, -+ .platform_data = &at803x_data, -+ }, -+}; -+ -+static void __init sc300m_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(sc300m_leds_gpio), -+ sc300m_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, SC300M_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(sc300m_gpio_keys), -+ sc300m_gpio_keys); -+ -+ ath79_register_usb(); -+ ath79_register_nfc(); -+ -+ ath79_register_wmac(art + SC300M_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_mdio(0, 0); -+ mdiobus_register_board_info(sc300m_mdio0_info, -+ ARRAY_SIZE(sc300m_mdio0_info)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + SC300M_MAC0_OFFSET, 0); -+ -+ ath79_eth0_pll_data.pll_1000 = 0xa6000101; -+ ath79_eth0_pll_data.pll_100 = 0xa4000101; -+ /* GMAC0 is connected to the RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = 0xF; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(1); -+ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_SC300M, "SC300M", "Abicom SC300M", sc300m_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-sc450.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-sc450.c -new file mode 100644 -index 0000000000..dee183e790 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-sc450.c -@@ -0,0 +1,149 @@ -+/* -+ * Abicom International Scorpion SC450 support. -+ * -+ * Copyright (c) 2012 Qualcomm Atheros -+ * Copyright (c) 2012-2013 Gabor Juhos -+ * Copyright (c) 2017 Conor O'Gorman -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-nfc.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define SC450_GPIO_LED_POWER 13 -+#define SC450_GPIO_LED_ERR1 14 -+#define SC450_GPIO_LED_ERR2 15 -+#define SC450_GPIO_LED_WLAN 16 -+#define SC450_GPIO_BTN_RESET 17 -+#define SC450_GPIO_WP 18 -+#define SC450_GPIO_POE 19 -+#define SC450_GPIO_RX_LOS 20 -+#define SC450_GPIO_MOD_GND 21 -+#define SC450_GPIO_MOD_SCL 22 -+#define SC450_GPIO_MOD_SDA 23 -+ -+#define SC450_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define SC450_KEYS_DEBOUNCE_INTERVAL (3 * SC450_KEYS_POLL_INTERVAL) -+ -+#define SC450_MAC0_OFFSET 0 -+#define SC450_MAC1_OFFSET 6 -+#define SC450_WMAC_CALDATA_OFFSET 0x1000 -+#define SC450_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led sc450_leds_gpio[] __initdata = { -+ { -+ .name = "sc450:green:power", -+ .gpio = SC450_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "sc450:red:power", -+ .gpio = SC450_GPIO_LED_ERR1, -+ .active_low = 1, -+ }, -+ { -+ .name = "sc450:green:wlan", -+ .gpio = SC450_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "sc450:red:wlan", -+ .gpio = SC450_GPIO_LED_ERR2, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button sc450_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = SC450_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = SC450_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static struct at803x_platform_data at803x_data = { -+ .disable_smarteee = 1, -+ .enable_rgmii_rx_delay = 0, -+ .enable_rgmii_tx_delay = 0, -+}; -+ -+static struct mdio_board_info sc450_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 1, -+ .platform_data = &at803x_data, -+ }, -+}; -+ -+static void __init sc450_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(sc450_leds_gpio), -+ sc450_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, SC450_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(sc450_gpio_keys), -+ sc450_gpio_keys); -+ -+ ath79_register_usb(); -+ ath79_register_nfc(); -+ -+ ath79_register_wmac(art + SC450_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_mdio(0, 0); -+ mdiobus_register_board_info(sc450_mdio0_info, -+ ARRAY_SIZE(sc450_mdio0_info)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + SC450_MAC0_OFFSET, 0); -+ -+ ath79_eth0_pll_data.pll_1000 = 0xa6000101; -+ ath79_eth0_pll_data.pll_100 = 0xa4000101; -+ /* GMAC0 is connected to the RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = 0xF; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(1); -+ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_SC450, "SC450", "Abicom SC450", sc450_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-smart-300.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-smart-300.c -new file mode 100644 -index 0000000000..2520e960d3 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-smart-300.c -@@ -0,0 +1,135 @@ -+/* -+ * NC-LINK SMART-300 board support -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * Copyright (C) 2014 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define SMART_300_GPIO_LED_WLAN 13 -+#define SMART_300_GPIO_LED_WAN 18 -+#define SMART_300_GPIO_LED_LAN4 19 -+#define SMART_300_GPIO_LED_LAN3 12 -+#define SMART_300_GPIO_LED_LAN2 21 -+#define SMART_300_GPIO_LED_LAN1 20 -+#define SMART_300_GPIO_LED_SYSTEM 15 -+#define SMART_300_GPIO_LED_POWER 14 -+ -+#define SMART_300_GPIO_BTN_RESET 17 -+#define SMART_300_GPIO_SW_RFKILL 16 -+ -+#define SMART_300_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define SMART_300_KEYS_DEBOUNCE_INTERVAL (3 * SMART_300_KEYS_POLL_INTERVAL) -+ -+#define SMART_300_GPIO_MASK 0x007fffff -+ -+static const char *smart_300_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data smart_300_flash_data = { -+ .part_probes = smart_300_part_probes, -+}; -+ -+static struct gpio_led smart_300_leds_gpio[] __initdata = { -+ { -+ .name = "nc-link:green:lan1", -+ .gpio = SMART_300_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "nc-link:green:lan2", -+ .gpio = SMART_300_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "nc-link:green:lan3", -+ .gpio = SMART_300_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "nc-link:green:lan4", -+ .gpio = SMART_300_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "nc-link:green:system", -+ .gpio = SMART_300_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "nc-link:green:wan", -+ .gpio = SMART_300_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "nc-link:green:wlan", -+ .gpio = SMART_300_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button smart_300_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = SMART_300_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = SMART_300_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init smart_300_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(smart_300_leds_gpio), -+ smart_300_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, SMART_300_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(smart_300_gpio_keys), -+ smart_300_gpio_keys); -+ -+ ath79_register_m25p80(&smart_300_flash_data); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, -1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -+ -+ /* GMAC0 is connected to the PHY0 of the internal switch */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(4); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(ee, mac); -+ -+ gpio_request(SMART_300_GPIO_LED_POWER, "power"); -+ gpio_direction_output(SMART_300_GPIO_LED_POWER, GPIOF_OUT_INIT_LOW); -+} -+ -+MIPS_MACHINE(ATH79_MACH_SMART_300, "SMART-300", "NC-LINK SMART-300", -+ smart_300_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-som9331.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-som9331.c -new file mode 100644 -index 0000000000..eef5bcedc2 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-som9331.c -@@ -0,0 +1,125 @@ -+/* -+ * OpenEmbed SOM9331 board support -+ * -+ * Copyright (C) 2011 dongyuqi <729650915@qq.com> -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * 5/27/2016 - Modified by Allan Nick Pedrana -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define SOM9331_GPIO_LED_WLAN 27 -+#define SOM9331_GPIO_LED_SYSTEM 0 -+#define SOM9331_GPIO_LED_2 13 -+#define SOM9331_GPIO_LED_3 14 -+#define SOM9331_GPIO_LED_5 16 -+#define SOM9331_GPIO_LED_WAN SOM9331_GPIO_LED_2 -+#define SOM9331_GPIO_LED_LAN1 SOM9331_GPIO_LED_3 -+#define SOM9331_GPIO_LED_LAN2 SOM9331_GPIO_LED_5 -+#define SOM9331_GPIO_BTN_RESET 11 -+ -+#define SOM9331_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define SOM9331_KEYS_DEBOUNCE_INTERVAL (3 * SOM9331_KEYS_POLL_INTERVAL) -+ -+static const char *som9331_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data som9331_flash_data = { -+ .part_probes = som9331_part_probes, -+}; -+ -+static struct gpio_led som9331_leds_gpio[] __initdata = { -+ { -+ .name = "som9331:red:wlan", -+ .gpio = SOM9331_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "som9331:orange:wan", -+ .gpio = SOM9331_GPIO_LED_WAN, -+ .active_low = 0, -+ }, -+ { -+ .name = "som9331:orange:lan1", -+ .gpio = SOM9331_GPIO_LED_LAN1, -+ .active_low = 0, -+ }, -+ { -+ .name = "som9331:orange:lan2", -+ .gpio = SOM9331_GPIO_LED_LAN2, -+ .active_low = 0, -+ }, -+ { -+ .name = "som9331:blue:system", -+ .gpio = SOM9331_GPIO_LED_SYSTEM, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button som9331_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = SOM9331_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = SOM9331_GPIO_BTN_RESET, -+ .active_low = 0, -+ } -+}; -+ -+static void __init som9331_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_setup_ar933x_phy4_switch(true, true); -+ -+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ ath79_register_m25p80(&som9331_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(som9331_leds_gpio), -+ som9331_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, SOM9331_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(som9331_gpio_keys), -+ som9331_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN ports */ -+ ath79_register_eth(1); -+ -+ /* WAN port */ -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_SOM9331, "SOM9331", "OpenEmbed SOM9331", som9331_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-sr3200.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-sr3200.c -new file mode 100644 -index 0000000000..72d46c0c47 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-sr3200.c -@@ -0,0 +1,187 @@ -+/* -+ * Support for YunCore SR3200 and XD3200 boards -+ * -+ * Copyright (C) 2016 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define SR3200_XD3200_GPIO_LED_SYSTEM 1 -+#define SR3200_XD3200_GPIO_LED_WLAN2G 19 -+ -+#define SR3200_XD3200_GPIO_BTN_RESET 2 -+ -+#define SR3200_XD3200_KEYS_POLL_INTERVAL 20 -+#define SR3200_XD3200_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * SR3200_XD3200_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led xd3200_leds_gpio[] __initdata = { -+ { -+ .name = "xd3200:green:system", -+ .gpio = SR3200_XD3200_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+ { -+ .name = "xd3200:blue:wlan2g", -+ .gpio = SR3200_XD3200_GPIO_LED_WLAN2G, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led sr3200_leds_gpio[] __initdata = { -+ { -+ .name = "sr3200:green:system", -+ .gpio = SR3200_XD3200_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+ { -+ .name = "sr3200:green:wlan2g", -+ .gpio = SR3200_XD3200_GPIO_LED_WLAN2G, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button sr3200_xd3200_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = SR3200_XD3200_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = SR3200_XD3200_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static const struct ar8327_led_info sr3200_leds_qca833x[] = { -+ AR8327_LED_INFO(PHY0_0, HW, "sr3200:green:lan1"), -+ AR8327_LED_INFO(PHY1_0, HW, "sr3200:green:lan2"), -+ AR8327_LED_INFO(PHY2_0, HW, "sr3200:green:lan3"), -+ AR8327_LED_INFO(PHY3_0, HW, "sr3200:green:lan4"), -+ AR8327_LED_INFO(PHY4_0, HW, "sr3200:green:wan"), -+}; -+ -+static const struct ar8327_led_info xd3200_leds_qca833x[] = { -+ AR8327_LED_INFO(PHY1_0, HW, "xd3200:green:lan"), -+ AR8327_LED_INFO(PHY2_0, HW, "xd3200:green:wan"), -+}; -+ -+/* Blink rate: 1 Gbps -> 8 hz, 100 Mbs -> 4 Hz, 10 Mbps -> 2 Hz */ -+static struct ar8327_led_cfg sr3200_xd3200_qca833x_led_cfg = { -+ .led_ctrl0 = 0xcf37cf37, -+ .led_ctrl1 = 0xcf37cf37, -+ .led_ctrl2 = 0xcf37cf37, -+ .led_ctrl3 = 0x0, -+ .open_drain = true, -+}; -+ -+static struct ar8327_pad_cfg sr3200_xd3200_qca833x_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+static struct ar8327_platform_data sr3200_xd3200_qca833x_data = { -+ .pad0_cfg = &sr3200_xd3200_qca833x_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &sr3200_xd3200_qca833x_led_cfg, -+}; -+ -+static struct mdio_board_info sr3200_xd3200_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &sr3200_xd3200_qca833x_data, -+ }, -+}; -+ -+static void __init sr3200_xd3200_common_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_mdio(0, 0x0); -+ mdiobus_register_board_info(sr3200_xd3200_mdio0_info, -+ ARRAY_SIZE(sr3200_xd3200_mdio0_info)); -+ -+ /* GMAC0 is connected to QCA8334/QCA8337N switch */ -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(mac + 0x1000, NULL); -+ -+ ap91_pci_init(mac + 0x5000, NULL); -+ -+ ath79_gpio_direction_select(SR3200_XD3200_GPIO_LED_SYSTEM, true); -+ ath79_gpio_direction_select(SR3200_XD3200_GPIO_LED_WLAN2G, true); -+ -+ /* Mute LEDs on boot */ -+ gpio_set_value(SR3200_XD3200_GPIO_LED_SYSTEM, 1); -+ gpio_set_value(SR3200_XD3200_GPIO_LED_WLAN2G, 1); -+ -+ ath79_gpio_output_select(SR3200_XD3200_GPIO_LED_SYSTEM, 0); -+ ath79_gpio_output_select(SR3200_XD3200_GPIO_LED_WLAN2G, 0); -+ -+ ath79_register_gpio_keys_polled(-1, SR3200_XD3200_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(sr3200_xd3200_gpio_keys), -+ sr3200_xd3200_gpio_keys); -+} -+ -+static void __init sr3200_setup(void) -+{ -+ sr3200_xd3200_qca833x_data.leds = sr3200_leds_qca833x; -+ sr3200_xd3200_qca833x_data.num_leds = ARRAY_SIZE(sr3200_leds_qca833x); -+ -+ sr3200_xd3200_common_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(sr3200_leds_gpio), -+ sr3200_leds_gpio); -+ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_SR3200, "SR3200", "YunCore SR3200", sr3200_setup); -+ -+static void __init xd3200_setup(void) -+{ -+ sr3200_xd3200_qca833x_data.leds = xd3200_leds_qca833x; -+ sr3200_xd3200_qca833x_data.num_leds = ARRAY_SIZE(xd3200_leds_qca833x); -+ -+ sr3200_xd3200_common_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(xd3200_leds_gpio), -+ xd3200_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_XD3200, "XD3200", "YunCore XD3200", xd3200_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-t830.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-t830.c -new file mode 100644 -index 0000000000..ffdb2ca533 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-t830.c -@@ -0,0 +1,127 @@ -+/* -+ * YunCore T830 board support -+ * -+ * Copyright (C) 2018 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define T830_GPIO_LED_LAN1 16 -+#define T830_GPIO_LED_LAN2 15 -+#define T830_GPIO_LED_LAN3 14 -+#define T830_GPIO_LED_LAN4 11 -+#define T830_GPIO_LED_USB 13 -+#define T830_GPIO_LED_WAN 4 -+#define T830_GPIO_LED_WLAN 12 -+ -+#define T830_GPIO_BTN_RESET 17 -+ -+#define T830_KEYS_POLL_INTERVAL 20 /* msec */ -+#define T830_KEYS_DEBOUNCE_INTERVAL (3 * T830_KEYS_POLL_INTERVAL) -+ -+#define T830_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led t830_gpio_leds[] __initdata = { -+ { -+ .name = "t830:green:lan1", -+ .gpio = T830_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "t830:green:lan2", -+ .gpio = T830_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "t830:green:lan3", -+ .gpio = T830_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "t830:green:lan4", -+ .gpio = T830_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "t830:green:usb", -+ .gpio = T830_GPIO_LED_USB, -+ .active_low = 1, -+ .default_state = LEDS_GPIO_DEFSTATE_KEEP, -+ }, { -+ .name = "t830:green:wan", -+ .gpio = T830_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "t830:green:wlan", -+ .gpio = T830_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button t830_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = T830_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = T830_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init t830_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ -+ /* LAN */ -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac + 6, 0); -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_register_eth(0); -+ -+ ath79_gpio_function_setup(AR934X_GPIO_FUNC_JTAG_DISABLE, -+ AR934X_GPIO_FUNC_CLK_OBS4_EN); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(t830_gpio_leds), -+ t830_gpio_leds); -+ -+ ath79_register_gpio_keys_polled(-1, T830_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(t830_gpio_keys), -+ t830_gpio_keys); -+ -+ ath79_register_usb(); -+ ath79_register_wmac(art, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_T830, "T830", "YunCore T830", t830_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tellstick-znet-lite.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tellstick-znet-lite.c -new file mode 100644 -index 0000000000..0950d9a99d ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tellstick-znet-lite.c -@@ -0,0 +1,129 @@ -+/* -+ * Telldus TellStick ZNet Lite board support -+ * -+ * Copyright (C) 2016 Micke Prag -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TELLSTICK_GPIO_LED_SYSTEM 27 -+#define TELLSTICK_GPIO_LED_BLUE 0 -+#define TELLSTICK_GPIO_LED_RED 14 -+#define TELLSTICK_GPIO_LED_GREEN 15 -+#define TELLSTICK_GPIO_LED_LAN_GREEN 16 -+#define TELLSTICK_GPIO_LED_LAN_ORANGE 17 -+ -+#define TELLSTICK_GPIO_BTN_RESET 11 -+ -+#define TELLSTICK_GPIO_RF433_RESET 13 -+ -+#define TELLSTICK_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TELLSTICK_KEYS_DEBOUNCE_INTERVAL (3 * TELLSTICK_KEYS_POLL_INTERVAL) -+ -+static const char *tellstick_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tellstick_flash_data = { -+ .part_probes = tellstick_part_probes, -+}; -+ -+static struct gpio_led tellstick_leds_gpio[] __initdata = { -+ { -+ .name = "tellstick:white:system", -+ .gpio = TELLSTICK_GPIO_LED_SYSTEM, -+ .active_low = 0, -+ }, -+ { -+ .name = "tellstick:blue:status", -+ .gpio = TELLSTICK_GPIO_LED_BLUE, -+ .active_low = 0, -+ }, -+ { -+ .name = "tellstick:red:status", -+ .gpio = TELLSTICK_GPIO_LED_RED, -+ .active_low = 0, -+ }, -+ { -+ .name = "tellstick:green:status", -+ .gpio = TELLSTICK_GPIO_LED_GREEN, -+ .active_low = 0, -+ }, -+ { -+ .name = "tellstick:green:lan", -+ .gpio = TELLSTICK_GPIO_LED_LAN_GREEN, -+ .active_low = 0, -+ }, -+ { -+ .name = "tellstick:orange:lan", -+ .gpio = TELLSTICK_GPIO_LED_LAN_ORANGE, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button tellstick_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TELLSTICK_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TELLSTICK_GPIO_BTN_RESET, -+ .active_low = 0, -+ } -+}; -+ -+static void __init tellstick_znet_lite_setup(void) -+{ -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 mac[ETH_ALEN]; -+ memcpy(&mac, (u8 *) KSEG1ADDR(0x1f01fc00), sizeof(mac)); -+ -+ ath79_gpio_function_disable( -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN -+ ); -+ -+ ath79_register_m25p80(&tellstick_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tellstick_leds_gpio), -+ tellstick_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, TELLSTICK_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tellstick_gpio_keys), -+ tellstick_gpio_keys); -+ -+ gpio_request_one(TELLSTICK_GPIO_RF433_RESET, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "rf433 reset"); -+ ath79_register_usb(); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, (u8 *)mac, 0); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ -+ // wlan0 mac needs to be different then eth0 -+ mac[3] += 1; -+ ath79_register_wmac(ee, (u8 *)mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TELLSTICK_ZNET_LITE, "TELLSTICK-ZNET-LITE", "Telldus TellStick ZNet Lite", -+ tellstick_znet_lite_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-632brp.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-632brp.c -new file mode 100644 -index 0000000000..855664e562 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-632brp.c -@@ -0,0 +1,111 @@ -+/* -+ * TrendNET TEW-632BRP board support -+ * -+ * Copyright (C) 2008-2012 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "nvram.h" -+ -+#define TEW_632BRP_GPIO_LED_STATUS 1 -+#define TEW_632BRP_GPIO_LED_WPS 3 -+#define TEW_632BRP_GPIO_LED_WLAN 6 -+#define TEW_632BRP_GPIO_BTN_WPS 12 -+#define TEW_632BRP_GPIO_BTN_RESET 21 -+ -+#define TEW_632BRP_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TEW_632BRP_KEYS_DEBOUNCE_INTERVAL (3 * TEW_632BRP_KEYS_POLL_INTERVAL) -+ -+#define TEW_632BRP_CONFIG_ADDR 0x1f020000 -+#define TEW_632BRP_CONFIG_SIZE 0x10000 -+ -+static struct gpio_led tew_632brp_leds_gpio[] __initdata = { -+ { -+ .name = "tew-632brp:green:status", -+ .gpio = TEW_632BRP_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "tew-632brp:blue:wps", -+ .gpio = TEW_632BRP_GPIO_LED_WPS, -+ .active_low = 1, -+ }, { -+ .name = "tew-632brp:green:wlan", -+ .gpio = TEW_632BRP_GPIO_LED_WLAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button tew_632brp_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TEW_632BRP_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TEW_632BRP_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TEW_632BRP_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TEW_632BRP_GPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+#define TEW_632BRP_LAN_PHYMASK BIT(0) -+#define TEW_632BRP_WAN_PHYMASK BIT(4) -+#define TEW_632BRP_MDIO_MASK (~(TEW_632BRP_LAN_PHYMASK | \ -+ TEW_632BRP_WAN_PHYMASK)) -+ -+static void __init tew_632brp_setup(void) -+{ -+ const char *config = (char *) KSEG1ADDR(TEW_632BRP_CONFIG_ADDR); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 mac[6]; -+ u8 *wlan_mac = NULL; -+ -+ if (ath79_nvram_parse_mac_addr(config, TEW_632BRP_CONFIG_SIZE, -+ "lan_mac=", mac) == 0) { -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -+ wlan_mac = mac; -+ } -+ -+ ath79_register_mdio(0, TEW_632BRP_MDIO_MASK); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth0_data.phy_mask = TEW_632BRP_LAN_PHYMASK; -+ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth1_data.phy_mask = TEW_632BRP_WAN_PHYMASK; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tew_632brp_leds_gpio), -+ tew_632brp_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TEW_632BRP_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tew_632brp_gpio_keys), -+ tew_632brp_gpio_keys); -+ -+ ath79_register_wmac(eeprom, wlan_mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TEW_632BRP, "TEW-632BRP", "TRENDnet TEW-632BRP", -+ tew_632brp_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-673gru.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-673gru.c -new file mode 100644 -index 0000000000..80a5443c70 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-673gru.c -@@ -0,0 +1,198 @@ -+/* -+ * TRENDnet TEW-673GRU board support -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+ -+#define TEW673GRU_GPIO_LCD_SCK 0 -+#define TEW673GRU_GPIO_LCD_MOSI 1 -+#define TEW673GRU_GPIO_LCD_MISO 2 -+#define TEW673GRU_GPIO_LCD_CS 6 -+ -+#define TEW673GRU_GPIO_LED_WPS 9 -+ -+#define TEW673GRU_GPIO_BTN_RESET 3 -+#define TEW673GRU_GPIO_BTN_WPS 8 -+ -+#define TEW673GRU_GPIO_RTL8366_SDA 5 -+#define TEW673GRU_GPIO_RTL8366_SCK 7 -+ -+#define TEW673GRU_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TEW673GRU_KEYS_DEBOUNCE_INTERVAL (3 * TEW673GRU_KEYS_POLL_INTERVAL) -+ -+#define TEW673GRU_CAL0_OFFSET 0x1000 -+#define TEW673GRU_CAL1_OFFSET 0x5000 -+#define TEW673GRU_MAC0_OFFSET 0xffa0 -+#define TEW673GRU_MAC1_OFFSET 0xffb4 -+ -+#define TEW673GRU_CAL_LOCATION_0 0x1f660000 -+#define TEW673GRU_CAL_LOCATION_1 0x1f7f0000 -+ -+static struct gpio_led tew673gru_leds_gpio[] __initdata = { -+ { -+ .name = "trendnet:blue:wps", -+ .gpio = TEW673GRU_GPIO_LED_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button tew673gru_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TEW673GRU_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TEW673GRU_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TEW673GRU_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TEW673GRU_GPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static struct rtl8366_initval tew673gru_rtl8366s_initvals[] = { -+ { .reg = 0x06, .val = 0x0108 }, -+}; -+ -+static struct rtl8366_platform_data tew673gru_rtl8366s_data = { -+ .gpio_sda = TEW673GRU_GPIO_RTL8366_SDA, -+ .gpio_sck = TEW673GRU_GPIO_RTL8366_SCK, -+ .num_initvals = ARRAY_SIZE(tew673gru_rtl8366s_initvals), -+ .initvals = tew673gru_rtl8366s_initvals, -+}; -+ -+static struct platform_device tew673gru_rtl8366s_device = { -+ .name = RTL8366S_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &tew673gru_rtl8366s_data, -+ } -+}; -+ -+static struct spi_board_info tew673gru_spi_info[] = { -+ { -+ .bus_num = 1, -+ .chip_select = 0, -+ .max_speed_hz = 400000, -+ .modalias = "spidev", -+ .mode = SPI_MODE_2, -+ .controller_data = (void *) TEW673GRU_GPIO_LCD_CS, -+ }, -+}; -+ -+static struct spi_gpio_platform_data tew673gru_spi_data = { -+ .sck = TEW673GRU_GPIO_LCD_SCK, -+ .miso = TEW673GRU_GPIO_LCD_MISO, -+ .mosi = TEW673GRU_GPIO_LCD_MOSI, -+ .num_chipselect = 1, -+}; -+ -+static struct platform_device tew673gru_spi_device = { -+ .name = "spi_gpio", -+ .id = 1, -+ .dev = { -+ .platform_data = &tew673gru_spi_data, -+ }, -+}; -+ -+static bool __init tew673gru_is_caldata_valid(u8 *p) -+{ -+ u16 *magic0, *magic1; -+ -+ magic0 = (u16 *)(p + TEW673GRU_CAL0_OFFSET); -+ magic1 = (u16 *)(p + TEW673GRU_CAL1_OFFSET); -+ -+ return (*magic0 == 0xa55a && *magic1 == 0xa55a); -+} -+ -+static void __init tew673gru_wlan_init(void) -+{ -+ u8 mac1[ETH_ALEN], mac2[ETH_ALEN]; -+ u8 *caldata; -+ -+ caldata = (u8 *) KSEG1ADDR(TEW673GRU_CAL_LOCATION_0); -+ if (!tew673gru_is_caldata_valid(caldata)) { -+ caldata = (u8 *)KSEG1ADDR(TEW673GRU_CAL_LOCATION_1); -+ if (!tew673gru_is_caldata_valid(caldata)) { -+ pr_err("no calibration data found\n"); -+ return; -+ } -+ } -+ -+ ath79_parse_ascii_mac(caldata + TEW673GRU_MAC0_OFFSET, mac1); -+ ath79_parse_ascii_mac(caldata + TEW673GRU_MAC1_OFFSET, mac2); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 2); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac1, 3); -+ -+ ap9x_pci_setup_wmac_led_pin(0, 5); -+ ap9x_pci_setup_wmac_led_pin(1, 5); -+ -+ ap94_pci_init(caldata + TEW673GRU_CAL0_OFFSET, mac1, -+ caldata + TEW673GRU_CAL1_OFFSET, mac2); -+} -+ -+static void __init tew673gru_setup(void) -+{ -+ tew673gru_wlan_init(); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_eth0_data.mii_bus_dev = &tew673gru_rtl8366s_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_pll_data.pll_1000 = 0x11110000; -+ -+ ath79_eth1_data.mii_bus_dev = &tew673gru_rtl8366s_device.dev; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth1_data.phy_mask = 0x10; -+ ath79_eth1_pll_data.pll_1000 = 0x11110000; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tew673gru_leds_gpio), -+ tew673gru_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TEW673GRU_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tew673gru_gpio_keys), -+ tew673gru_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ platform_device_register(&tew673gru_rtl8366s_device); -+ -+ spi_register_board_info(tew673gru_spi_info, -+ ARRAY_SIZE(tew673gru_spi_info)); -+ platform_device_register(&tew673gru_spi_device); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TEW_673GRU, "TEW-673GRU", "TRENDnet TEW-673GRU", -+ tew673gru_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-712br.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-712br.c -new file mode 100644 -index 0000000000..304b994887 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-712br.c -@@ -0,0 +1,153 @@ -+/* -+ * TRENDnet TEW-712BR board support -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TEW_712BR_GPIO_BTN_WPS 11 -+#define TEW_712BR_GPIO_BTN_RESET 12 -+ -+#define TEW_712BR_GPIO_LED_LAN1 13 -+#define TEW_712BR_GPIO_LED_LAN2 14 -+#define TEW_712BR_GPIO_LED_LAN3 15 -+#define TEW_712BR_GPIO_LED_LAN4 16 -+#define TEW_712BR_GPIO_LED_POWER_GREEN 20 -+#define TEW_712BR_GPIO_LED_POWER_ORANGE 27 -+#define TEW_712BR_GPIO_LED_WAN_GREEN 17 -+#define TEW_712BR_GPIO_LED_WAN_ORANGE 23 -+#define TEW_712BR_GPIO_LED_WLAN 0 -+#define TEW_712BR_GPIO_LED_WPS 26 -+ -+#define TEW_712BR_GPIO_WAN_LED_ENABLE 1 -+ -+#define TEW_712BR_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TEW_712BR_KEYS_DEBOUNCE_INTERVAL (3 * TEW_712BR_KEYS_POLL_INTERVAL) -+ -+#define TEW_712BR_ART_ADDRESS 0x1f010000 -+#define TEW_712BR_CALDATA_OFFSET 0x1000 -+ -+#define TEW_712BR_MAC_PART_ADDRESS 0x1f020000 -+#define TEW_712BR_LAN_MAC_OFFSET 0x04 -+#define TEW_712BR_WAN_MAC_OFFSET 0x16 -+ -+static struct gpio_led tew_712br_leds_gpio[] __initdata = { -+ { -+ .name = "trendnet:green:lan1", -+ .gpio = TEW_712BR_GPIO_LED_LAN1, -+ .active_low = 0, -+ }, { -+ .name = "trendnet:green:lan2", -+ .gpio = TEW_712BR_GPIO_LED_LAN2, -+ .active_low = 0, -+ }, { -+ .name = "trendnet:green:lan3", -+ .gpio = TEW_712BR_GPIO_LED_LAN3, -+ .active_low = 0, -+ }, { -+ .name = "trendnet:green:lan4", -+ .gpio = TEW_712BR_GPIO_LED_LAN4, -+ .active_low = 0, -+ }, { -+ .name = "trendnet:blue:wps", -+ .gpio = TEW_712BR_GPIO_LED_WPS, -+ .active_low = 1, -+ }, { -+ .name = "trendnet:green:power", -+ .gpio = TEW_712BR_GPIO_LED_POWER_GREEN, -+ .active_low = 0, -+ }, { -+ .name = "trendnet:orange:power", -+ .gpio = TEW_712BR_GPIO_LED_POWER_ORANGE, -+ .active_low = 0, -+ }, { -+ .name = "trendnet:green:wan", -+ .gpio = TEW_712BR_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "trendnet:orange:wan", -+ .gpio = TEW_712BR_GPIO_LED_WAN_ORANGE, -+ .active_low = 0, -+ }, { -+ .name = "trendnet:green:wlan", -+ .gpio = TEW_712BR_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button tew_712br_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TEW_712BR_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TEW_712BR_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TEW_712BR_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TEW_712BR_GPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static void __init tew_712br_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(TEW_712BR_ART_ADDRESS); -+ u8 *mac = (u8 *) KSEG1ADDR(TEW_712BR_MAC_PART_ADDRESS); -+ u8 lan_mac[ETH_ALEN]; -+ u8 wan_mac[ETH_ALEN]; -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ gpio_request_one(TEW_712BR_GPIO_WAN_LED_ENABLE, -+ GPIOF_OUT_INIT_LOW, "WAN LED enable"); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tew_712br_leds_gpio), -+ tew_712br_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, TEW_712BR_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tew_712br_gpio_keys), -+ tew_712br_gpio_keys); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_parse_ascii_mac(mac + TEW_712BR_LAN_MAC_OFFSET, lan_mac); -+ ath79_parse_ascii_mac(mac + TEW_712BR_WAN_MAC_OFFSET, wan_mac); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, wan_mac, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, lan_mac, 0); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(1); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(art + TEW_712BR_CALDATA_OFFSET, wan_mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TEW_712BR, "TEW-712BR", -+ "TRENDnet TEW-712BR", tew_712br_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-732br.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-732br.c -new file mode 100644 -index 0000000000..1f26f6f4b0 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-732br.c -@@ -0,0 +1,127 @@ -+/* -+ * TRENDnet TEW-732BR board support -+ * -+ * Copyright (C) 2013 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TEW_732BR_GPIO_BTN_WPS 16 -+#define TEW_732BR_GPIO_BTN_RESET 17 -+ -+#define TEW_732BR_GPIO_LED_POWER_GREEN 4 -+#define TEW_732BR_GPIO_LED_POWER_AMBER 14 -+#define TEW_732BR_GPIO_LED_PLANET_GREEN 12 -+#define TEW_732BR_GPIO_LED_PLANET_AMBER 22 -+ -+#define TEW_732BR_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TEW_732BR_KEYS_DEBOUNCE_INTERVAL (3 * TEW_732BR_KEYS_POLL_INTERVAL) -+ -+#define TEW_732BR_ART_ADDRESS 0x1fff0000 -+#define TEW_732BR_CALDATA_OFFSET 0x1000 -+#define TEW_732BR_LAN_MAC_OFFSET 0xffa0 -+#define TEW_732BR_WAN_MAC_OFFSET 0xffb4 -+ -+static struct gpio_led tew_732br_leds_gpio[] __initdata = { -+ { -+ .name = "trendnet:green:power", -+ .gpio = TEW_732BR_GPIO_LED_POWER_GREEN, -+ .active_low = 0, -+ }, -+ { -+ .name = "trendnet:amber:power", -+ .gpio = TEW_732BR_GPIO_LED_POWER_AMBER, -+ .active_low = 0, -+ }, -+ { -+ .name = "trendnet:green:wan", -+ .gpio = TEW_732BR_GPIO_LED_PLANET_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "trendnet:amber:wan", -+ .gpio = TEW_732BR_GPIO_LED_PLANET_AMBER, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button tew_732br_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TEW_732BR_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TEW_732BR_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TEW_732BR_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TEW_732BR_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init tew_732br_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(TEW_732BR_ART_ADDRESS); -+ u8 lan_mac[ETH_ALEN]; -+ u8 wan_mac[ETH_ALEN]; -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tew_732br_leds_gpio), -+ tew_732br_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, TEW_732BR_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tew_732br_gpio_keys), -+ tew_732br_gpio_keys); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_parse_ascii_mac(art + TEW_732BR_LAN_MAC_OFFSET, lan_mac); -+ ath79_parse_ascii_mac(art + TEW_732BR_WAN_MAC_OFFSET, wan_mac); -+ -+ ath79_register_wmac(art + TEW_732BR_CALDATA_OFFSET, lan_mac); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ /* LAN: GMAC1 is connected to the internal switch */ -+ ath79_init_mac(ath79_eth1_data.mac_addr, lan_mac, 0); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ -+ ath79_register_eth(1); -+ -+ /* WAN: GMAC0 is connected to the PHY4 of the internal switch */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, wan_mac, 0); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(4); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TEW_732BR, "TEW-732BR", "TRENDnet TEW-732BR", -+ tew_732br_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-823dru.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-823dru.c -new file mode 100644 -index 0000000000..e631828a65 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-823dru.c -@@ -0,0 +1,181 @@ -+/* -+ * TRENDnet TEW-823DRU board support -+ * -+ * Copyright (C) 2015 Cezary Jackiewicz -+ * Copyright (C) 2014 Gabor Juhos -+ * Copyright (C) 2014 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TEW_823DRU_GPIO_LED_POWER_ORANGE 14 -+#define TEW_823DRU_GPIO_LED_POWER_GREEN 19 -+#define TEW_823DRU_GPIO_LED_PLANET_GREEN 22 -+#define TEW_823DRU_GPIO_LED_PLANET_ORANGE 23 -+ -+#define TEW_823DRU_GPIO_BTN_WPS 16 -+#define TEW_823DRU_GPIO_BTN_RESET 17 -+ -+#define TEW_823DRU_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TEW_823DRU_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * TEW_823DRU_KEYS_POLL_INTERVAL) -+ -+#define TEW_823DRU_WMAC_CALDATA_OFFSET 0x1000 -+ -+#define TEW_823DRU_LAN_MAC_OFFSET 0x04 -+#define TEW_823DRU_WAN_MAC_OFFSET 0x18 -+ -+static struct gpio_led tew_823dru_leds_gpio[] __initdata = { -+ { -+ .name = "trendnet:green:power", -+ .gpio = TEW_823DRU_GPIO_LED_POWER_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "trendnet:orange:power", -+ .gpio = TEW_823DRU_GPIO_LED_POWER_ORANGE, -+ .active_low = 1, -+ }, -+ { -+ .name = "trendnet:green:planet", -+ .gpio = TEW_823DRU_GPIO_LED_PLANET_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "trendnet:orange:planet", -+ .gpio = TEW_823DRU_GPIO_LED_PLANET_ORANGE, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tew_823dru_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TEW_823DRU_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TEW_823DRU_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TEW_823DRU_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TEW_823DRU_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+/* GMAC0 of the AR8327 switch is connected to the QCA9558 SoC via SGMII */ -+static struct ar8327_pad_cfg tew_823dru_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+/* GMAC6 of the AR8327 switch is connected to the QCA9558 SoC via RGMII */ -+static struct ar8327_pad_cfg tew_823dru_ar8327_pad6_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_platform_data tew_823dru_ar8327_data = { -+ .pad0_cfg = &tew_823dru_ar8327_pad0_cfg, -+ .pad6_cfg = &tew_823dru_ar8327_pad6_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .port6_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info tew_823dru_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &tew_823dru_ar8327_data, -+ }, -+}; -+ -+static void __init tew_823dru_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1ffe0000); -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 lan_mac[ETH_ALEN]; -+ u8 wan_mac[ETH_ALEN]; -+ -+ ath79_parse_ascii_mac(mac + TEW_823DRU_LAN_MAC_OFFSET, lan_mac); -+ ath79_parse_ascii_mac(mac + TEW_823DRU_WAN_MAC_OFFSET, wan_mac); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tew_823dru_leds_gpio), -+ tew_823dru_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, TEW_823DRU_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tew_823dru_gpio_keys), -+ tew_823dru_gpio_keys); -+ -+ ath79_register_wmac(art + TEW_823DRU_WMAC_CALDATA_OFFSET, lan_mac); -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, lan_mac, 0); -+ ath79_init_mac(ath79_eth0_data.mac_addr, wan_mac, 0); -+ -+ -+ mdiobus_register_board_info(tew_823dru_mdio0_info, -+ ARRAY_SIZE(tew_823dru_mdio0_info)); -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ /* GMAC0 is connected to the RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x56000000; -+ -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ -+ ath79_register_eth(1); -+ -+ ath79_register_usb(); -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TEW_823DRU, "TEW-823DRU", "TRENDnet TEW-823DRU", -+ tew_823dru_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr11u.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr11u.c -new file mode 100644 -index 0000000000..74ccf639e0 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr11u.c -@@ -0,0 +1,183 @@ -+/* -+ * TP-LINK TL-MR11U/TL-MR3040 board support -+ * -+ * Copyright (C) 2011 dongyuqi <729650915@qq.com> -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_MR11U_GPIO_LED_3G 27 -+#define TL_MR11U_GPIO_LED_WLAN 26 -+#define TL_MR11U_GPIO_LED_LAN 17 -+ -+#define TL_MR11U_GPIO_BTN_WPS 20 -+#define TL_MR11U_GPIO_BTN_RESET 11 -+ -+#define TL_MR11U_GPIO_USB_POWER 8 -+#define TL_MR3040_GPIO_USB_POWER 18 -+ -+#define TL_MR3040_V2_GPIO_BTN_SW1 19 -+#define TL_MR3040_V2_GPIO_BTN_SW2 20 -+ -+#define TL_MR11U_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_MR11U_KEYS_DEBOUNCE_INTERVAL (3 * TL_MR11U_KEYS_POLL_INTERVAL) -+ -+static const char *tl_mr11u_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_mr11u_flash_data = { -+ .part_probes = tl_mr11u_part_probes, -+}; -+ -+static struct gpio_led tl_mr11u_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:3g", -+ .gpio = TL_MR11U_GPIO_LED_3G, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_MR11U_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:lan", -+ .gpio = TL_MR11U_GPIO_LED_LAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button tl_mr11u_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_MR11U_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR11U_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+ { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_MR11U_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR11U_GPIO_BTN_WPS, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button tl_mr3040_v2_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_MR11U_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR11U_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+ { -+ .desc = "sw1", -+ .type = EV_SW, -+ .code = BTN_0, -+ .debounce_interval = TL_MR11U_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR3040_V2_GPIO_BTN_SW1, -+ .active_low = 0, -+ }, -+ { -+ .desc = "sw2", -+ .type = EV_SW, -+ .code = BTN_1, -+ .debounce_interval = TL_MR11U_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR3040_V2_GPIO_BTN_SW2, -+ .active_low = 0, -+ } -+}; -+ -+static void __init common_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* Disable hardware control LAN1 and LAN2 LEDs, enabling GPIO14 and GPIO15 */ -+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_m25p80(&tl_mr11u_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_mr11u_leds_gpio), -+ tl_mr11u_leds_gpio); -+ -+ ath79_register_usb(); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+static void __init tl_mr11u_setup(void) -+{ -+ common_setup(); -+ -+ ath79_register_gpio_keys_polled(-1, TL_MR11U_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_mr11u_gpio_keys), -+ tl_mr11u_gpio_keys); -+ gpio_request_one(TL_MR11U_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_MR11U, "TL-MR11U", "TP-LINK TL-MR11U", -+ tl_mr11u_setup); -+ -+static void __init tl_mr3040_setup(void) -+{ -+ common_setup(); -+ -+ ath79_register_gpio_keys_polled(-1, TL_MR11U_KEYS_POLL_INTERVAL, -+ 1, tl_mr11u_gpio_keys); -+ gpio_request_one(TL_MR3040_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_MR3040, "TL-MR3040", "TP-LINK TL-MR3040", -+ tl_mr3040_setup); -+ -+static void __init tl_mr3040_v2_setup(void) -+{ -+ common_setup(); -+ -+ ath79_register_gpio_keys_polled(-1, TL_MR11U_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_mr3040_v2_gpio_keys), -+ tl_mr3040_v2_gpio_keys); -+ gpio_request_one(TL_MR3040_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_MR3040_V2, "TL-MR3040-v2", "TP-LINK TL-MR3040 v2", -+ tl_mr3040_v2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr13u.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr13u.c -new file mode 100644 -index 0000000000..84b6937849 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr13u.c -@@ -0,0 +1,107 @@ -+/* -+ * TP-LINK TL-MR13U board support -+ * -+ * Copyright (C) 2011 dongyuqi <729650915@qq.com> -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_MR13U_GPIO_LED_SYSTEM 27 -+ -+#define TL_MR13U_GPIO_BTN_RESET 11 -+#define TL_MR13U_GPIO_BTN_SW1 6 -+#define TL_MR13U_GPIO_BTN_SW2 7 -+ -+#define TL_MR13U_GPIO_USB_POWER 18 -+ -+#define TL_MR13U_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_MR13U_KEYS_DEBOUNCE_INTERVAL (3 * TL_MR13U_KEYS_POLL_INTERVAL) -+ -+static const char *tl_mr13u_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_mr13u_flash_data = { -+ .part_probes = tl_mr13u_part_probes, -+}; -+ -+static struct gpio_led tl_mr13u_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:blue:system", -+ .gpio = TL_MR13U_GPIO_LED_SYSTEM, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button tl_mr13u_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_MR13U_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR13U_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+ { -+ .desc = "sw1", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = TL_MR13U_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR13U_GPIO_BTN_SW1, -+ .active_low = 0, -+ }, -+ { -+ .desc = "sw2", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .debounce_interval = TL_MR13U_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR13U_GPIO_BTN_SW2, -+ .active_low = 0, -+ }, -+}; -+ -+static void __init tl_mr13u_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_m25p80(&tl_mr13u_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_mr13u_leds_gpio), -+ tl_mr13u_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, TL_MR13U_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_mr13u_gpio_keys), -+ tl_mr13u_gpio_keys); -+ -+ gpio_request_one(TL_MR13U_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_MR13U, "TL-MR13U", "TP-LINK TL-MR13U v1", -+ tl_mr13u_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3020.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3020.c -new file mode 100644 -index 0000000000..e3b4087eff ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3020.c -@@ -0,0 +1,126 @@ -+/* -+ * TP-LINK TL-MR3020 board support -+ * -+ * Copyright (C) 2011 dongyuqi <729650915@qq.com> -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_MR3020_GPIO_LED_3G 27 -+#define TL_MR3020_GPIO_LED_WLAN 0 -+#define TL_MR3020_GPIO_LED_LAN 17 -+#define TL_MR3020_GPIO_LED_WPS 26 -+ -+#define TL_MR3020_GPIO_BTN_WPS 11 -+#define TL_MR3020_GPIO_BTN_SW1 18 -+#define TL_MR3020_GPIO_BTN_SW2 20 -+ -+#define TL_MR3020_GPIO_USB_POWER 8 -+ -+#define TL_MR3020_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_MR3020_KEYS_DEBOUNCE_INTERVAL (3 * TL_MR3020_KEYS_POLL_INTERVAL) -+ -+static const char *tl_mr3020_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_mr3020_flash_data = { -+ .part_probes = tl_mr3020_part_probes, -+}; -+ -+static struct gpio_led tl_mr3020_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:3g", -+ .gpio = TL_MR3020_GPIO_LED_3G, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_MR3020_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+ { -+ .name = "tp-link:green:lan", -+ .gpio = TL_MR3020_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:wps", -+ .gpio = TL_MR3020_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_mr3020_gpio_keys[] __initdata = { -+ { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_MR3020_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR3020_GPIO_BTN_WPS, -+ .active_low = 0, -+ }, -+ { -+ .desc = "sw1", -+ .type = EV_SW, -+ .code = BTN_0, -+ .debounce_interval = TL_MR3020_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR3020_GPIO_BTN_SW1, -+ .active_low = 0, -+ }, -+ { -+ .desc = "sw2", -+ .type = EV_SW, -+ .code = BTN_1, -+ .debounce_interval = TL_MR3020_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR3020_GPIO_BTN_SW2, -+ .active_low = 0, -+ } -+}; -+ -+static void __init tl_mr3020_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_m25p80(&tl_mr3020_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_mr3020_leds_gpio), -+ tl_mr3020_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, TL_MR3020_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_mr3020_gpio_keys), -+ tl_mr3020_gpio_keys); -+ -+ gpio_request_one(TL_MR3020_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_MR3020, "TL-MR3020", "TP-LINK TL-MR3020", -+ tl_mr3020_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c -new file mode 100644 -index 0000000000..5924ac5048 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c -@@ -0,0 +1,147 @@ -+/* -+ * TP-LINK TL-MR3220/3420 board support -+ * -+ * Copyright (C) 2010-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+ -+#define TL_MR3X20_GPIO_LED_QSS 0 -+#define TL_MR3X20_GPIO_LED_SYSTEM 1 -+#define TL_MR3X20_GPIO_LED_3G 8 -+ -+#define TL_MR3X20_GPIO_BTN_RESET 11 -+#define TL_MR3X20_GPIO_BTN_QSS 12 -+ -+#define TL_MR3X20_GPIO_USB_POWER 6 -+ -+#define TL_MR3X20_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_MR3X20_KEYS_DEBOUNCE_INTERVAL (3 * TL_MR3X20_KEYS_POLL_INTERVAL) -+ -+static const char *tl_mr3x20_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_mr3x20_flash_data = { -+ .part_probes = tl_mr3x20_part_probes, -+}; -+ -+static struct gpio_led tl_mr3x20_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:system", -+ .gpio = TL_MR3X20_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:qss", -+ .gpio = TL_MR3X20_GPIO_LED_QSS, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:3g", -+ .gpio = TL_MR3X20_GPIO_LED_3G, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button tl_mr3x20_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_MR3X20_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR3X20_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "qss", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_MR3X20_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR3X20_GPIO_BTN_QSS, -+ .active_low = 1, -+ } -+}; -+ -+static void __init tl_ap99_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_m25p80(&tl_mr3x20_flash_data); -+ -+ ath79_register_gpio_keys_polled(-1, TL_MR3X20_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_mr3x20_gpio_keys), -+ tl_mr3x20_gpio_keys); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN ports */ -+ ath79_register_eth(1); -+ /* WAN port */ -+ ath79_register_eth(0); -+ -+ ap91_pci_init(ee, mac); -+} -+ -+static void __init tl_mr3x20_usb_setup(void) -+{ -+ /* enable power for the USB port */ -+ gpio_request_one(TL_MR3X20_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+} -+ -+static void __init tl_mr3220_setup(void) -+{ -+ tl_ap99_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_mr3x20_leds_gpio), -+ tl_mr3x20_leds_gpio); -+ ap9x_pci_setup_wmac_led_pin(0, 1); -+ tl_mr3x20_usb_setup(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_MR3220, "TL-MR3220", "TP-LINK TL-MR3220", -+ tl_mr3220_setup); -+ -+static void __init tl_mr3420_setup(void) -+{ -+ tl_ap99_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_mr3x20_leds_gpio), -+ tl_mr3x20_leds_gpio); -+ ap9x_pci_setup_wmac_led_pin(0, 0); -+ tl_mr3x20_usb_setup(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_MR3420, "TL-MR3420", "TP-LINK TL-MR3420", -+ tl_mr3420_setup); -+ -+static void __init tl_wr841n_v7_setup(void) -+{ -+ tl_ap99_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_mr3x20_leds_gpio) - 1, -+ tl_mr3x20_leds_gpio); -+ ap9x_pci_setup_wmac_led_pin(0, 0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR841N_V7, "TL-WR841N-v7", -+ "TP-LINK TL-WR841N/ND v7", tl_wr841n_v7_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr6400.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr6400.c -new file mode 100644 -index 0000000000..be49c89cab ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr6400.c -@@ -0,0 +1,151 @@ -+/* -+ * TP-LINK TL-MR6400 board support -+ * -+ * Copyright (C) 2017 Filip Moc -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * The name of the author may not be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -+ * DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE. -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_MR6400_GPIO_LTE_POWER 4 -+#define TL_MR6400_GPIO_BTN_RESET 12 /* SW2 */ -+#define TL_MR6400_GPIO_BTN_RFKILL 14 /* SW3 */ -+#define TL_MR6400_GPIO_LED_WAN 0 /* D12 */ -+#define TL_MR6400_GPIO_LED_4G 1 /* D11 */ -+#define TL_MR6400_GPIO_LED_WPS 3 /* D5 */ -+#define TL_MR6400_GPIO_LED_WLAN 11 /* D3 */ -+#define TL_MR6400_GPIO_LED_POWER 13 /* D2 */ -+#define TL_MR6400_GPIO_LED_LAN 16 /* D4 */ -+ -+#define TL_MR6400_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_MR6400_KEYS_DEBOUNCE_INTERVAL (3 * TL_MR6400_KEYS_POLL_INTERVAL) -+ -+#define TL_MR6400_WMAC_CALDATA_OFFSET 0x1000 -+ -+static const char *tl_mr6400_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_mr6400_flash_data = { -+ .part_probes = tl_mr6400_part_probes, -+ .type = "w25q64", -+}; -+ -+static struct gpio_led tl_mr6400_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:white:wan", -+ .gpio = TL_MR6400_GPIO_LED_WAN, -+ .active_low = 0, -+ }, -+ { -+ .name = "tp-link:white:4g", -+ .gpio = TL_MR6400_GPIO_LED_4G, -+ .active_low = 0, -+ }, -+ { -+ .name = "tp-link:white:wps", -+ .gpio = TL_MR6400_GPIO_LED_WPS, -+ .active_low = 0, -+ }, -+ { -+ .name = "tp-link:white:wlan", -+ .gpio = TL_MR6400_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, -+ { -+ .name = "tp-link:white:power", -+ .gpio = TL_MR6400_GPIO_LED_POWER, -+ .active_low = 0, -+ }, -+ { -+ .name = "tp-link:white:lan", -+ .gpio = TL_MR6400_GPIO_LED_LAN, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button tl_mr6400_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_MR6400_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR6400_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "rfkill", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = TL_MR6400_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR6400_GPIO_BTN_RFKILL, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init tl_mr6400_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(&tl_mr6400_flash_data); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN1, LAN2, LAN3 */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask |= BIT(0); -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); -+ ath79_register_eth(1); -+ -+ /* LAN4 / WAN */ -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(art + TL_MR6400_WMAC_CALDATA_OFFSET, mac); -+ -+ ath79_register_leds_gpio(-1, -+ ARRAY_SIZE(tl_mr6400_leds_gpio), -+ tl_mr6400_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, -+ TL_MR6400_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_mr6400_gpio_keys), -+ tl_mr6400_gpio_keys); -+ -+ gpio_request_one(TL_MR6400_GPIO_LTE_POWER, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED | GPIOF_ACTIVE_LOW, -+ "LTE power"); -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_MR6400, "TL-MR6400", "TP-LINK TL-MR6400", -+ tl_mr6400_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa701nd-v2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa701nd-v2.c -new file mode 100644 -index 0000000000..aab92b30d4 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa701nd-v2.c -@@ -0,0 +1,116 @@ -+/* -+ * TP-LINK TL-WA701ND v2 board support -+ * -+ * Copyright (C) 2015 Luigi Tarenga -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_WA701NDV2_GPIO_LED_WLAN 0 -+#define TL_WA701NDV2_GPIO_LED_QSS 1 -+#define TL_WA701NDV2_GPIO_LED_LAN 17 -+#define TL_WA701NDV2_GPIO_LED_SYSTEM 27 -+ -+#define TL_WA701NDV2_GPIO_BTN_RESET 11 -+#define TL_WA701NDV2_GPIO_BTN_QSS 26 -+ -+#define TL_WA701NDV2_GPIO_USB_POWER 8 -+ -+#define TL_WA701NDV2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WA701NDV2_KEYS_DEBOUNCE_INTERVAL (3 * TL_WA701NDV2_KEYS_POLL_INTERVAL) -+ -+static const char *tl_wa701ndv2_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wa701ndv2_flash_data = { -+ .part_probes = tl_wa701ndv2_part_probes, -+}; -+ -+static struct gpio_led tl_wa701ndv2_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WA701NDV2_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WA701NDV2_GPIO_LED_QSS, -+ .active_low = 0, -+ }, { -+ .name = "tp-link:green:lan", -+ .gpio = TL_WA701NDV2_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:system", -+ .gpio = TL_WA701NDV2_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button tl_wa701ndv2_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WA701NDV2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA701NDV2_GPIO_BTN_RESET, -+ .active_low = 0, -+ } , { -+ .desc = "qss", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WA701NDV2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA701NDV2_GPIO_BTN_QSS, -+ .active_low = 0, -+ } -+ -+}; -+ -+static void __init tl_wa701ndv2_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wa701ndv2_leds_gpio), -+ tl_wa701ndv2_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WA701NDV2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wa701ndv2_gpio_keys), -+ tl_wa701ndv2_gpio_keys); -+ -+ gpio_request_one(TL_WA701NDV2_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ ath79_register_m25p80(&tl_wa701ndv2_flash_data); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ /* ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); */ -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WA701ND_V2, "TL-WA701ND-v2", -+ "TP-LINK TL-WA701ND v2", tl_wa701ndv2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa7210n-v2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa7210n-v2.c -new file mode 100644 -index 0000000000..276353a6c3 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa7210n-v2.c -@@ -0,0 +1,125 @@ -+/* -+ * TP-LINK TL-WA7210N v2.1 board support -+ * -+ * Copyright (C) 2011 dongyuqi <729650915@qq.com> -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * Copyright (C) 2014 Nicolas Braud-Santoni -+ * Copyright (C) 2014 Alexander List -+ * Copyright (C) 2015 Hendrik Frenzel -+ * -+ * rebased on TL-WA7510Nv1 support, -+ * Copyright (C) 2012 Stefan Helmert -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "dev-dsa.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#include "common.h" -+ -+#define TL_WA7210N_V2_GPIO_BTN_RESET 11 -+#define TL_WA7210N_V2_KEYS_POLL_INT 20 -+#define TL_WA7210N_V2_KEYS_DEBOUNCE_INT (3 * TL_WA7210N_V2_KEYS_POLL_INT) -+ -+#define TL_WA7210N_V2_GPIO_LED_LAN 17 -+#define TL_WA7210N_V2_GPIO_LED_SIG1 0 -+#define TL_WA7210N_V2_GPIO_LED_SIG2 1 -+#define TL_WA7210N_V2_GPIO_LED_SIG3 27 -+#define TL_WA7210N_V2_GPIO_LED_SIG4 26 -+ -+#define TL_WA7210N_V2_GPIO_LNA_EN 28 -+ -+static const char *tl_wa7210n_v2_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct gpio_keys_button tl_wa7210n_v2_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WA7210N_V2_KEYS_DEBOUNCE_INT, -+ .gpio = TL_WA7210N_V2_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_led tl_wa7210n_v2_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan", -+ .gpio = TL_WA7210N_V2_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:signal1", -+ .gpio = TL_WA7210N_V2_GPIO_LED_SIG1, -+ .active_low = 0, -+ }, { -+ .name = "tp-link:green:signal2", -+ .gpio = TL_WA7210N_V2_GPIO_LED_SIG2, -+ .active_low = 0, -+ }, { -+ .name = "tp-link:green:signal3", -+ .gpio = TL_WA7210N_V2_GPIO_LED_SIG3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:signal4", -+ .gpio = TL_WA7210N_V2_GPIO_LED_SIG4, -+ .active_low = 1, -+ }, -+}; -+ -+static struct flash_platform_data tl_wa7210n_v2_flash_data = { -+ .part_probes = tl_wa7210n_v2_part_probes, -+}; -+ -+static void __init tl_wa7210n_v2_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WA7210N_V2_KEYS_POLL_INT, -+ ARRAY_SIZE(tl_wa7210n_v2_gpio_keys), -+ tl_wa7210n_v2_gpio_keys); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wa7210n_v2_leds_gpio), -+ tl_wa7210n_v2_leds_gpio); -+ -+ ath79_gpio_function_enable(TL_WA7210N_V2_GPIO_LNA_EN); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, -1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_register_wmac(ee, mac); -+ -+ ath79_register_m25p80(&tl_wa7210n_v2_flash_data); -+ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WA7210N_V2, "TL-WA7210N-v2", "TP-LINK TL-WA7210N v2", -+ tl_wa7210n_v2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa801nd-v3.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa801nd-v3.c -new file mode 100644 -index 0000000000..1637382192 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa801nd-v3.c -@@ -0,0 +1,137 @@ -+/* -+ * TP-LINK TL-WA801ND v3 adapted from TP-LINK TL-WR841N/ND v9 -+ * TP-LINK TL-WA801ND v4 -+ * -+ * Copyright (C) 2014 Matthias Schiffer -+ * Copyright (C) 2016 Tiziano Bacocco -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_WA801NDV3_GPIO_LED_WLAN 12 -+#define TL_WA801NDV3_GPIO_LED_SYSTEM 13 -+#define TL_WA801NDV3_GPIO_LED_SECURITY_RED 11 -+#define TL_WA801NDV3_GPIO_LED_SECURITY_GREEN 15 -+#define TL_WA801NDV3_GPIO_LED_LAN 3 -+ -+#define TL_WA801NDV3_GPIO_BTN_RESET 2 -+#define TL_WA801NDV3_GPIO_BTN_WIFI 1 -+ -+#define TL_WA801NDV3_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WA801NDV3_KEYS_DEBOUNCE_INTERVAL (3 * TL_WA801NDV3_KEYS_POLL_INTERVAL) -+ -+static const char *tl_wa801n_v3_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wa801n_v3_flash_data = { -+ .part_probes = tl_wa801n_v3_part_probes, -+}; -+ -+static struct gpio_led tl_wa801n_v3_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:system", -+ .gpio = TL_WA801NDV3_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan", -+ .gpio = TL_WA801NDV3_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WA801NDV3_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:red:security", -+ .gpio = TL_WA801NDV3_GPIO_LED_SECURITY_RED, -+ .active_low = 0, -+ }, { -+ .name = "tp-link:green:security", -+ .gpio = TL_WA801NDV3_GPIO_LED_SECURITY_GREEN, -+ .active_low = 0, -+ } -+ -+}; -+ -+static struct gpio_keys_button tl_wa801n_v3_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WA801NDV3_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA801NDV3_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "WIFI button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = TL_WA801NDV3_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA801NDV3_GPIO_BTN_WIFI, -+ .active_low = 1, -+ } -+}; -+ -+ -+static void __init tl_ap143_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 tmpmac[ETH_ALEN]; -+ -+ ath79_register_m25p80(&tl_wa801n_v3_flash_data); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_register_eth(0); -+ -+ ath79_init_mac(tmpmac, mac, 0); -+ ath79_register_wmac(ee, tmpmac); -+} -+ -+static void __init tl_wa801n_v3_setup(void) -+{ -+ tl_ap143_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wa801n_v3_leds_gpio), -+ tl_wa801n_v3_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, TL_WA801NDV3_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wa801n_v3_gpio_keys), -+ tl_wa801n_v3_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WA801ND_V3, "TL-WA801ND-v3", "TP-LINK TL-WA801ND v3", -+ tl_wa801n_v3_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa830re-v2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa830re-v2.c -new file mode 100644 -index 0000000000..1c74fed98e ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa830re-v2.c -@@ -0,0 +1,132 @@ -+/* -+ * TP-LINK TL-WA830RE v2 board support -+ * -+ * Copyright (C) 2014 Fredrik Jonson -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_WA830REV2_GPIO_LED_WLAN 13 -+#define TL_WA830REV2_GPIO_LED_QSS 15 -+#define TL_WA830REV2_GPIO_LED_LAN 18 -+#define TL_WA830REV2_GPIO_LED_SYSTEM 14 -+ -+#define TL_WA830REV2_GPIO_BTN_RESET 17 -+#define TL_WA830REV2_GPIO_SW_RFKILL 16 /* WPS for MR3420 v2 */ -+ -+#define TL_WA830REV2_GPIO_USB_POWER 4 -+ -+#define TL_WA830REV2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WA830REV2_KEYS_DEBOUNCE_INTERVAL (3 * TL_WA830REV2_KEYS_POLL_INTERVAL) -+ -+static const char *tl_wa830re_v2_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wa830re_v2_flash_data = { -+ .part_probes = tl_wa830re_v2_part_probes, -+}; -+ -+static struct gpio_led tl_wa830re_v2_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WA830REV2_GPIO_LED_QSS, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:system", -+ .gpio = TL_WA830REV2_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan", -+ .gpio = TL_WA830REV2_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WA830REV2_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wa830re_v2_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WA830REV2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA830REV2_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "RFKILL switch", -+ .type = EV_SW, -+ .code = KEY_RFKILL, -+ .debounce_interval = TL_WA830REV2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA830REV2_GPIO_SW_RFKILL, -+ .active_low = 0, -+ } -+}; -+ -+static void __init tl_ap123_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* Disable JTAG, enabling GPIOs 0-3 */ -+ /* Configure OBS4 line, for GPIO 4*/ -+ ath79_gpio_function_setup(AR934X_GPIO_FUNC_JTAG_DISABLE, -+ AR934X_GPIO_FUNC_CLK_OBS4_EN); -+ -+ /* config gpio4 as normal gpio function */ -+ ath79_gpio_output_select(TL_WA830REV2_GPIO_USB_POWER, -+ AR934X_GPIO_OUT_GPIO); -+ -+ ath79_register_m25p80(&tl_wa830re_v2_flash_data); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_PHY_SWAP); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ -+ /* GMAC0 is connected to the PHY0 of the internal switch */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+static void __init tl_wa830re_v2_setup(void) -+{ -+ tl_ap123_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wa830re_v2_leds_gpio) - 1, -+ tl_wa830re_v2_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, TL_WA830REV2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wa830re_v2_gpio_keys), -+ tl_wa830re_v2_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WA830RE_V2, "TL-WA830RE-v2", "TP-LINK TL-WA830RE v2", -+ tl_wa830re_v2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd-v2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd-v2.c -new file mode 100644 -index 0000000000..b4fb2a9f91 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd-v2.c -@@ -0,0 +1,104 @@ -+/* -+ * TP-LINK TL-WA901N/ND v2 board support -+ * -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * Copyright (C) 2010 Pieter Hollants -+ * Copyright (C) 2011 Jonathan Bennett -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include "dev-eth.h" -+#include "dev-m25p80.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_WA901ND_V2_GPIO_LED_QSS 4 -+#define TL_WA901ND_V2_GPIO_LED_SYSTEM 2 -+#define TL_WA901ND_V2_GPIO_LED_WLAN 9 -+ -+#define TL_WA901ND_V2_GPIO_BTN_RESET 3 -+#define TL_WA901ND_V2_GPIO_BTN_QSS 7 -+ -+#define TL_WA901ND_V2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * TL_WA901ND_V2_KEYS_POLL_INTERVAL) -+ -+static const char *tl_wa901nd_v2_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wa901nd_v2_flash_data = { -+ .part_probes = tl_wa901nd_v2_part_probes, -+}; -+ -+static struct gpio_led tl_wa901nd_v2_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:system", -+ .gpio = TL_WA901ND_V2_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WA901ND_V2_GPIO_LED_QSS, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WA901ND_V2_GPIO_LED_WLAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button tl_wa901nd_v2_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA901ND_V2_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "qss", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA901ND_V2_GPIO_BTN_QSS, -+ .active_low = 1, -+ } -+}; -+ -+static void __init tl_wa901nd_v2_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = 0x00001000; -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_eth0_data.reset_bit = AR71XX_RESET_GE0_MAC | -+ AR71XX_RESET_GE0_PHY; -+ ath79_register_eth(0); -+ -+ ath79_register_m25p80(&tl_wa901nd_v2_flash_data); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wa901nd_v2_leds_gpio), -+ tl_wa901nd_v2_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WA901ND_V2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wa901nd_v2_gpio_keys), -+ tl_wa901nd_v2_gpio_keys); -+ -+ ath79_register_wmac(eeprom, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WA901ND_V2, "TL-WA901ND-v2", -+ "TP-LINK TL-WA901ND v2", tl_wa901nd_v2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd-v4.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd-v4.c -new file mode 100644 -index 0000000000..ffbcd6fe42 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd-v4.c -@@ -0,0 +1,115 @@ -+/* -+ * TP-LINK TL-WA901ND v4, v5 board -+ * -+ * Copyright (C) 2015 Matthias Schiffer -+ * Copyright (C) 2016 Tiziano Bacocco -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+ -+#define TL_WA901ND_V4_GPIO_LED_QSS 3 -+#define TL_WA901ND_V4_GPIO_LED_LAN 7 -+#define TL_WA901ND_V4_GPIO_LED_WLAN 8 -+#define TL_WA901ND_V4_GPIO_LED_SYSTEM 18 -+ -+#define TL_WA901ND_V4_GPIO_BTN_RESET 1 -+ -+#define TL_WA901ND_V4_KEYS_POLL_INTERVAL 20 -+#define TL_WA901ND_V4_KEYS_DEBOUNCE_INTERVAL (3 * TL_WA901ND_V4_KEYS_POLL_INTERVAL) -+ -+ -+static struct gpio_led TL_WA901ND_V4_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WA901ND_V4_GPIO_LED_QSS, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:lan", -+ .gpio = TL_WA901ND_V4_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WA901ND_V4_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:system", -+ .gpio = TL_WA901ND_V4_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button TL_WA901ND_V4_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WA901ND_V4_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA901ND_V4_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+ -+static const char *tl_wa901nd_v4_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wa901nd_v4_flash_data = { -+ .part_probes = tl_wa901nd_v4_part_probes, -+}; -+ -+ -+static void __init TL_WA901ND_V4_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_m25p80(&tl_wa901nd_v4_flash_data); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(TL_WA901ND_V4_leds_gpio), -+ TL_WA901ND_V4_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WA901ND_V4_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(TL_WA901ND_V4_gpio_keys), -+ TL_WA901ND_V4_gpio_keys); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(ee, mac); -+ -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WA901ND_V4, "TL-WA901ND-v4", "TP-LINK TL-WA901ND v4", -+ TL_WA901ND_V4_setup); -+ -+MIPS_MACHINE(ATH79_MACH_TL_WA901ND_V5, "TL-WA901ND-v5", "TP-LINK TL-WA901ND v5", -+ TL_WA901ND_V4_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd.c -new file mode 100644 -index 0000000000..957b92cba6 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd.c -@@ -0,0 +1,127 @@ -+/* -+ * TP-LINK TL-WA901N/ND v1, TL-WA7510N v1 board support -+ * -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * Copyright (C) 2010 Pieter Hollants -+ * Copyright (C) 2012 Stefan Helmert -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define TL_WA901ND_GPIO_LED_QSS 0 -+#define TL_WA901ND_GPIO_LED_SYSTEM 1 -+#define TL_WA901ND_GPIO_LED_LAN 13 -+ -+#define TL_WA901ND_GPIO_BTN_RESET 11 -+#define TL_WA901ND_GPIO_BTN_QSS 12 -+ -+#define TL_WA901ND_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WA901ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WA901ND_KEYS_POLL_INTERVAL) -+ -+static const char *tl_wa901nd_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wa901nd_flash_data = { -+ .part_probes = tl_wa901nd_part_probes, -+}; -+ -+static struct gpio_led tl_wa901nd_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan", -+ .gpio = TL_WA901ND_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:system", -+ .gpio = TL_WA901ND_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WA901ND_GPIO_LED_QSS, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button tl_wa901nd_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WA901ND_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA901ND_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "qss", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WA901ND_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA901ND_GPIO_BTN_QSS, -+ .active_low = 1, -+ } -+}; -+ -+static void __init common_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ -+ /* -+ * ath79_eth0 would be the WAN port, but is not connected. -+ * ath79_eth1 connects to the internal switch chip, however -+ * we have a single LAN port only. -+ */ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(1); -+ -+ ath79_register_m25p80(&tl_wa901nd_flash_data); -+} -+ -+static void __init tl_wa901nd_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ common_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wa901nd_leds_gpio), -+ tl_wa901nd_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WA901ND_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wa901nd_gpio_keys), -+ tl_wa901nd_gpio_keys); -+ -+ ap91_pci_init(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WA901ND, "TL-WA901ND", "TP-LINK TL-WA901ND", -+ tl_wa901nd_setup); -+ -+static void __init tl_wa7510n_v1_setup(void) -+{ -+ common_setup(); -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WA7510N_V1, "TL-WA7510N", "TP-LINK TL-WA7510N v1", -+ tl_wa7510n_v1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wax50re.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wax50re.c -new file mode 100644 -index 0000000000..955628fecb ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wax50re.c -@@ -0,0 +1,445 @@ -+/* -+ * Support for TP-Link boards: -+ * - TL-WA750RE v1 -+ * - TL-WA801ND v2 -+ * - TL-WA850RE v1/v2 -+ * - TL-WA855RE v1 -+ * - TL-WA901ND v3 -+ * -+ * Copyright (C) 2013 Martijn Zilverschoon -+ * Copyright (C) 2013 Jiri Pirko -+ * Copyright (C) 2017 Piotr Dymacz -+ * Copyright (C) 2017 Federico Cappon -+ * Copyright (C) 2017 Nicolò Veronese -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_WAX50RE_GPIO_LED_LAN 20 -+#define TL_WAX50RE_GPIO_LED_WLAN 13 -+#define TL_WAX50RE_GPIO_LED_RE 15 -+#define TL_WAX50RE_GPIO_LED_SIGNAL1 0 -+#define TL_WAX50RE_GPIO_LED_SIGNAL2 1 -+#define TL_WAX50RE_GPIO_LED_SIGNAL3 2 -+#define TL_WAX50RE_GPIO_LED_SIGNAL4 3 -+#define TL_WAX50RE_GPIO_LED_SIGNAL5 4 -+ -+#define TL_WA850RE_V2_GPIO_LED_LAN 14 -+#define TL_WA850RE_V2_GPIO_LED_RE 12 -+#define TL_WA850RE_V2_GPIO_LED_SIGNAL1 0 -+#define TL_WA850RE_V2_GPIO_LED_SIGNAL2 1 -+#define TL_WA850RE_V2_GPIO_LED_SIGNAL3 2 -+#define TL_WA850RE_V2_GPIO_LED_SIGNAL4 3 -+#define TL_WA850RE_V2_GPIO_LED_SIGNAL5 4 -+#define TL_WA850RE_V2_GPIO_LED_WLAN 13 -+ -+#define TL_WA850RE_V2_GPIO_ENABLE_LEDS 15 -+ -+#define TL_WA855REV1_GPIO_LED_RED 11 -+#define TL_WA855REV1_GPIO_LED_GREEN 12 -+ -+#define TL_WA860RE_GPIO_LED_WLAN_ORANGE 0 -+#define TL_WA860RE_GPIO_LED_WLAN_GREEN 2 -+#define TL_WA860RE_GPIO_LED_POWER_ORANGE 12 -+#define TL_WA860RE_GPIO_LED_POWER_GREEN 14 -+#define TL_WA860RE_GPIO_LED_LAN 20 -+ -+#define TL_WA801ND_V2_GPIO_LED_LAN 18 -+#define TL_WA801ND_V2_GPIO_LED_SYSTEM 14 -+ -+#define TL_WAX50RE_GPIO_BTN_RESET 17 -+#define TL_WAX50RE_GPIO_BTN_WPS 16 -+ -+#define TL_WA860RE_GPIO_BTN_RESET 17 -+#define TL_WA860RE_GPIO_BTN_WPS 16 -+#define TL_WA860RE_GPIO_BTN_ONOFF 11 -+ -+#define TL_WAX50RE_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WAX50RE_KEYS_DEBOUNCE_INTERVAL (3 * TL_WAX50RE_KEYS_POLL_INTERVAL) -+ -+static const char *tl_wax50re_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wax50re_flash_data = { -+ .part_probes = tl_wax50re_part_probes, -+}; -+ -+static struct gpio_led tl_wa750re_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:orange:lan", -+ .gpio = TL_WAX50RE_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:orange:wlan", -+ .gpio = TL_WAX50RE_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:orange:re", -+ .gpio = TL_WAX50RE_GPIO_LED_RE, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:orange:signal1", -+ .gpio = TL_WAX50RE_GPIO_LED_SIGNAL1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:orange:signal2", -+ .gpio = TL_WAX50RE_GPIO_LED_SIGNAL2, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:orange:signal3", -+ .gpio = TL_WAX50RE_GPIO_LED_SIGNAL3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:orange:signal4", -+ .gpio = TL_WAX50RE_GPIO_LED_SIGNAL4, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:orange:signal5", -+ .gpio = TL_WAX50RE_GPIO_LED_SIGNAL5, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led tl_wa850re_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:blue:lan", -+ .gpio = TL_WAX50RE_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:blue:wlan", -+ .gpio = TL_WAX50RE_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:blue:re", -+ .gpio = TL_WAX50RE_GPIO_LED_RE, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:blue:signal1", -+ .gpio = TL_WAX50RE_GPIO_LED_SIGNAL1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:blue:signal2", -+ .gpio = TL_WAX50RE_GPIO_LED_SIGNAL2, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:blue:signal3", -+ .gpio = TL_WAX50RE_GPIO_LED_SIGNAL3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:blue:signal4", -+ .gpio = TL_WAX50RE_GPIO_LED_SIGNAL4, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:blue:signal5", -+ .gpio = TL_WAX50RE_GPIO_LED_SIGNAL5, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led tl_wa850re_v2_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:blue:lan", -+ .gpio = TL_WA850RE_V2_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:blue:re", -+ .gpio = TL_WA850RE_V2_GPIO_LED_RE, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:blue:signal1", -+ .gpio = TL_WA850RE_V2_GPIO_LED_SIGNAL1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:blue:signal2", -+ .gpio = TL_WA850RE_V2_GPIO_LED_SIGNAL2, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:blue:signal3", -+ .gpio = TL_WA850RE_V2_GPIO_LED_SIGNAL3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:blue:signal4", -+ .gpio = TL_WA850RE_V2_GPIO_LED_SIGNAL4, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:blue:signal5", -+ .gpio = TL_WA850RE_V2_GPIO_LED_SIGNAL5, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:blue:wlan", -+ .gpio = TL_WA850RE_V2_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led tl_wa855re_v1_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:power", -+ .gpio = TL_WA855REV1_GPIO_LED_GREEN, -+ .active_low = 0, -+ }, { -+ .name = "tp-link:red:power", -+ .gpio = TL_WA855REV1_GPIO_LED_RED, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_led tl_wa860re_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan", -+ .gpio = TL_WA860RE_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:power", -+ .gpio = TL_WA860RE_GPIO_LED_POWER_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:orange:power", -+ .gpio = TL_WA860RE_GPIO_LED_POWER_ORANGE, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WA860RE_GPIO_LED_WLAN_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:orange:wlan", -+ .gpio = TL_WA860RE_GPIO_LED_WLAN_ORANGE, -+ .active_low = 1, -+ }, -+}; -+ -+ -+static struct gpio_keys_button tl_wax50re_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WAX50RE_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WAX50RE_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "WPS", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WAX50RE_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WAX50RE_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wa860re_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WAX50RE_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA860RE_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "WPS", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WAX50RE_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA860RE_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, { -+ .desc = "ONOFF", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .debounce_interval = TL_WAX50RE_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WA860RE_GPIO_BTN_ONOFF, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led tl_wa801nd_v2_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan", -+ .gpio = TL_WA801ND_V2_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WAX50RE_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WAX50RE_GPIO_LED_RE, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:system", -+ .gpio = TL_WA801ND_V2_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init tl_ap123_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_m25p80(&tl_wax50re_flash_data); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_PHY_SWAP); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+static void __init tl_ap143_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f3c0008); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 tmpmac[ETH_ALEN]; -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, -2); -+ ath79_register_eth(0); -+ -+ ath79_init_mac(tmpmac, mac, 0); -+ ath79_register_wmac(ee, mac); -+} -+ -+static void __init tl_wa750re_setup(void) -+{ -+ tl_ap123_setup(); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wa750re_leds_gpio), -+ tl_wa750re_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WAX50RE_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wax50re_gpio_keys), -+ tl_wax50re_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WA750RE, "TL-WA750RE", "TP-LINK TL-WA750RE", -+ tl_wa750re_setup); -+ -+static void __init tl_wa801nd_v2_setup(void) -+{ -+ tl_ap123_setup(); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wa801nd_v2_leds_gpio), -+ tl_wa801nd_v2_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WAX50RE_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wax50re_gpio_keys), -+ tl_wax50re_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WA801ND_V2, "TL-WA801ND-v2", "TP-LINK TL-WA801ND v2", -+ tl_wa801nd_v2_setup); -+ -+static void __init tl_wa850re_setup(void) -+{ -+ tl_ap123_setup(); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wa850re_leds_gpio), -+ tl_wa850re_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WAX50RE_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wax50re_gpio_keys), -+ tl_wax50re_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WA850RE, "TL-WA850RE", "TP-LINK TL-WA850RE", -+ tl_wa850re_setup); -+ -+static void __init tl_wa850re_v2_setup(void) -+{ -+ tl_ap143_setup(); -+ -+ /* For GPIO 0~4 */ -+ ath79_gpio_function_setup(AR934X_GPIO_FUNC_JTAG_DISABLE, -+ AR934X_GPIO_FUNC_CLK_OBS4_EN); -+ -+ /* Allow to enable/disable all LEDs from userspace */ -+ gpio_request_one(TL_WA850RE_V2_GPIO_ENABLE_LEDS, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "LEDs enable"); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wa850re_v2_leds_gpio), -+ tl_wa850re_v2_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WAX50RE_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wax50re_gpio_keys), -+ tl_wax50re_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WA850RE_V2, "TL-WA850RE-V2", -+ "TP-LINK TL-WA850RE v2", tl_wa850re_v2_setup); -+ -+static void __init tl_wa855re_v1_setup(void) -+{ -+ tl_ap143_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wa855re_v1_leds_gpio), -+ tl_wa855re_v1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WAX50RE_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wax50re_gpio_keys), -+ tl_wax50re_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WA855RE_V1, "TL-WA855RE-v1", "TP-LINK TL-WA855RE v1", -+ tl_wa855re_v1_setup); -+ -+static void __init tl_wa860re_setup(void) -+{ -+ tl_ap123_setup(); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wa860re_leds_gpio), -+ tl_wa860re_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WAX50RE_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wa860re_gpio_keys), -+ tl_wa860re_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WA860RE, "TL-WA860RE", "TP-LINK TL-WA860RE", -+ tl_wa860re_setup); -+ -+static void __init tl_wa901nd_v3_setup(void) -+{ -+ tl_ap123_setup(); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wa801nd_v2_leds_gpio), -+ tl_wa801nd_v2_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WAX50RE_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wax50re_gpio_keys) - 1, -+ tl_wax50re_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WA901ND_V3, "TL-WA901ND-v3", "TP-LINK TL-WA901ND v3", -+ tl_wa901nd_v3_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr3320-v2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr3320-v2.c -new file mode 100644 -index 0000000000..3e452f2a4a ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr3320-v2.c -@@ -0,0 +1,146 @@ -+/* -+ * TP-LINK TL-WDR3320 v2 board support -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * Copyright (C) 2015 Weijie Gao -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define WDR3320_GPIO_LED_WLAN5G 12 -+#define WDR3320_GPIO_LED_SYSTEM 14 -+#define WDR3320_GPIO_LED_QSS 15 -+#define WDR3320_GPIO_LED_WAN 4 -+#define WDR3320_GPIO_LED_LAN1 18 -+#define WDR3320_GPIO_LED_LAN2 20 -+#define WDR3320_GPIO_LED_LAN3 21 -+#define WDR3320_GPIO_LED_LAN4 22 -+ -+#define WDR3320_GPIO_BTN_RESET 16 -+ -+#define WDR3320_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WDR3320_KEYS_DEBOUNCE_INTERVAL (3 * WDR3320_KEYS_POLL_INTERVAL) -+ -+#define WDR3320_WMAC_CALDATA_OFFSET 0x1000 -+#define WDR3320_PCIE_CALDATA_OFFSET 0x5000 -+ -+static const char *wdr3320_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data wdr3320_flash_data = { -+ .part_probes = wdr3320_part_probes, -+}; -+ -+static struct gpio_led wdr3320_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:qss", -+ .gpio = WDR3320_GPIO_LED_QSS, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:system", -+ .gpio = WDR3320_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:wlan5g", -+ .gpio = WDR3320_GPIO_LED_WLAN5G, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button wdr3320_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WDR3320_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WDR3320_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init wdr3320_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 tmpmac[ETH_ALEN]; -+ -+ ath79_register_m25p80(&wdr3320_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wdr3320_leds_gpio), -+ wdr3320_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, WDR3320_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wdr3320_gpio_keys), -+ wdr3320_gpio_keys); -+ -+ ath79_init_mac(tmpmac, mac, 0); -+ ath79_register_wmac(art + WDR3320_WMAC_CALDATA_OFFSET, tmpmac); -+ -+ ath79_init_mac(tmpmac, mac, -1); -+ ap9x_pci_setup_wmac_led_pin(0, 0); -+ ap91_pci_init(art + WDR3320_PCIE_CALDATA_OFFSET, tmpmac); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ /* LAN */ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ -+ /* GMAC0 is connected to the PHY4 of the internal switch */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(4); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ -+ ath79_register_eth(0); -+ -+ ath79_register_usb(); -+ -+ ath79_gpio_output_select(WDR3320_GPIO_LED_LAN1, -+ AR934X_GPIO_OUT_LED_LINK0); -+ ath79_gpio_output_select(WDR3320_GPIO_LED_LAN2, -+ AR934X_GPIO_OUT_LED_LINK1); -+ ath79_gpio_output_select(WDR3320_GPIO_LED_LAN3, -+ AR934X_GPIO_OUT_LED_LINK2); -+ ath79_gpio_output_select(WDR3320_GPIO_LED_LAN4, -+ AR934X_GPIO_OUT_LED_LINK3); -+ ath79_gpio_output_select(WDR3320_GPIO_LED_WAN, -+ AR934X_GPIO_OUT_LED_LINK4); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WDR3320_V2, "TL-WDR3320-v2", -+ "TP-LINK TL-WDR3320 v2", -+ wdr3320_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr3500.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr3500.c -new file mode 100644 -index 0000000000..452c20b777 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr3500.c -@@ -0,0 +1,169 @@ -+/* -+ * TP-LINK TL-WDR3500 board support -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * Copyright (C) 2013 Gui Iribarren -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define WDR3500_GPIO_LED_USB 11 -+#define WDR3500_GPIO_LED_WLAN2G 13 -+#define WDR3500_GPIO_LED_SYSTEM 14 -+#define WDR3500_GPIO_LED_QSS 15 -+#define WDR3500_GPIO_LED_WAN 18 -+#define WDR3500_GPIO_LED_LAN1 19 -+#define WDR3500_GPIO_LED_LAN2 20 -+#define WDR3500_GPIO_LED_LAN3 21 -+#define WDR3500_GPIO_LED_LAN4 22 -+ -+#define WDR3500_GPIO_BTN_WPS 16 -+#define WDR3500_GPIO_BTN_RFKILL 17 -+ -+#define WDR3500_GPIO_USB_POWER 12 -+ -+#define WDR3500_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WDR3500_KEYS_DEBOUNCE_INTERVAL (3 * WDR3500_KEYS_POLL_INTERVAL) -+ -+#define WDR3500_MAC0_OFFSET 0 -+#define WDR3500_MAC1_OFFSET 6 -+#define WDR3500_WMAC_CALDATA_OFFSET 0x1000 -+#define WDR3500_PCIE_CALDATA_OFFSET 0x5000 -+ -+static const char *wdr3500_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data wdr3500_flash_data = { -+ .part_probes = wdr3500_part_probes, -+}; -+ -+static struct gpio_led wdr3500_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:qss", -+ .gpio = WDR3500_GPIO_LED_QSS, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:system", -+ .gpio = WDR3500_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:usb", -+ .gpio = WDR3500_GPIO_LED_USB, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:wlan2g", -+ .gpio = WDR3500_GPIO_LED_WLAN2G, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button wdr3500_gpio_keys[] __initdata = { -+ { -+ .desc = "QSS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WDR3500_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WDR3500_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+ { -+ .desc = "RFKILL switch", -+ .type = EV_SW, -+ .code = KEY_RFKILL, -+ .debounce_interval = WDR3500_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WDR3500_GPIO_BTN_RFKILL, -+ }, -+}; -+ -+ -+static void __init wdr3500_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 tmpmac[ETH_ALEN]; -+ -+ ath79_register_m25p80(&wdr3500_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wdr3500_leds_gpio), -+ wdr3500_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, WDR3500_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wdr3500_gpio_keys), -+ wdr3500_gpio_keys); -+ -+ ath79_init_mac(tmpmac, mac, 0); -+ ath79_register_wmac(art + WDR3500_WMAC_CALDATA_OFFSET, tmpmac); -+ -+ ath79_init_mac(tmpmac, mac, 1); -+ ap9x_pci_setup_wmac_led_pin(0, 0); -+ ap91_pci_init(art + WDR3500_PCIE_CALDATA_OFFSET, tmpmac); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ /* LAN */ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 2); -+ -+ /* GMAC0 is connected to the PHY4 of the internal switch */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(4); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ -+ ath79_register_eth(0); -+ -+ gpio_request_one(WDR3500_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ ath79_gpio_output_select(WDR3500_GPIO_LED_LAN1, -+ AR934X_GPIO_OUT_LED_LINK3); -+ ath79_gpio_output_select(WDR3500_GPIO_LED_LAN2, -+ AR934X_GPIO_OUT_LED_LINK2); -+ ath79_gpio_output_select(WDR3500_GPIO_LED_LAN3, -+ AR934X_GPIO_OUT_LED_LINK1); -+ ath79_gpio_output_select(WDR3500_GPIO_LED_LAN4, -+ AR934X_GPIO_OUT_LED_LINK0); -+ ath79_gpio_output_select(WDR3500_GPIO_LED_WAN, -+ AR934X_GPIO_OUT_LED_LINK4); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WDR3500, "TL-WDR3500", -+ "TP-LINK TL-WDR3500", -+ wdr3500_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr4300.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr4300.c -new file mode 100644 -index 0000000000..b9fea95bc2 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr4300.c -@@ -0,0 +1,206 @@ -+/* -+ * TP-LINK TL-WDR4300 board support -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define WDR4300_GPIO_LED_USB1 11 -+#define WDR4300_GPIO_LED_USB2 12 -+#define WDR4300_GPIO_LED_WLAN2G 13 -+#define WDR4300_GPIO_LED_SYSTEM 14 -+#define WDR4300_GPIO_LED_QSS 15 -+ -+#define WDR4300_GPIO_BTN_WPS 16 -+#define WDR4300_GPIO_BTN_RFKILL 17 -+ -+#define WDR4300_GPIO_EXTERNAL_LNA0 18 -+#define WDR4300_GPIO_EXTERNAL_LNA1 19 -+ -+#define WDR4300_GPIO_USB1_POWER 22 -+#define WDR4300_GPIO_USB2_POWER 21 -+ -+#define WDR4300_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WDR4300_KEYS_DEBOUNCE_INTERVAL (3 * WDR4300_KEYS_POLL_INTERVAL) -+ -+#define WDR4300_MAC0_OFFSET 0 -+#define WDR4300_MAC1_OFFSET 6 -+#define WDR4300_WMAC_CALDATA_OFFSET 0x1000 -+#define WDR4300_PCIE_CALDATA_OFFSET 0x5000 -+ -+static const char *wdr4300_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data wdr4300_flash_data = { -+ .part_probes = wdr4300_part_probes, -+}; -+ -+static struct gpio_led wdr4300_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:blue:qss", -+ .gpio = WDR4300_GPIO_LED_QSS, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:blue:system", -+ .gpio = WDR4300_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:usb1", -+ .gpio = WDR4300_GPIO_LED_USB1, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:usb2", -+ .gpio = WDR4300_GPIO_LED_USB2, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:blue:wlan2g", -+ .gpio = WDR4300_GPIO_LED_WLAN2G, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button wdr4300_gpio_keys[] __initdata = { -+ { -+ .desc = "QSS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WDR4300_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WDR4300_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+ { -+ .desc = "RFKILL switch", -+ .type = EV_SW, -+ .code = KEY_RFKILL, -+ .debounce_interval = WDR4300_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WDR4300_GPIO_BTN_RFKILL, -+ .active_low = 1, -+ }, -+}; -+ -+static const struct ar8327_led_info wdr4300_leds_ar8327[] = { -+ AR8327_LED_INFO(PHY0_0, HW, "tp-link:blue:wan"), -+ AR8327_LED_INFO(PHY1_0, HW, "tp-link:blue:lan1"), -+ AR8327_LED_INFO(PHY2_0, HW, "tp-link:blue:lan2"), -+ AR8327_LED_INFO(PHY3_0, HW, "tp-link:blue:lan3"), -+ AR8327_LED_INFO(PHY4_0, HW, "tp-link:blue:lan4"), -+}; -+ -+static struct ar8327_pad_cfg wdr4300_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_led_cfg wdr4300_ar8327_led_cfg = { -+ .led_ctrl0 = 0xc737c737, -+ .led_ctrl1 = 0x00000000, -+ .led_ctrl2 = 0x00000000, -+ .led_ctrl3 = 0x0030c300, -+ .open_drain = false, -+}; -+ -+static struct ar8327_platform_data wdr4300_ar8327_data = { -+ .pad0_cfg = &wdr4300_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &wdr4300_ar8327_led_cfg, -+ .num_leds = ARRAY_SIZE(wdr4300_leds_ar8327), -+ .leds = wdr4300_leds_ar8327, -+}; -+ -+static struct mdio_board_info wdr4300_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &wdr4300_ar8327_data, -+ }, -+}; -+ -+static void __init wdr4300_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 tmpmac[ETH_ALEN]; -+ -+ ath79_register_m25p80(&wdr4300_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wdr4300_leds_gpio), -+ wdr4300_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, WDR4300_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wdr4300_gpio_keys), -+ wdr4300_gpio_keys); -+ -+ ath79_wmac_set_ext_lna_gpio(0, WDR4300_GPIO_EXTERNAL_LNA0); -+ ath79_wmac_set_ext_lna_gpio(1, WDR4300_GPIO_EXTERNAL_LNA1); -+ -+ ath79_init_mac(tmpmac, mac, -1); -+ ath79_register_wmac(art + WDR4300_WMAC_CALDATA_OFFSET, tmpmac); -+ -+ ath79_init_mac(tmpmac, mac, 0); -+ ap9x_pci_setup_wmac_led_pin(0, 0); -+ ap91_pci_init(art + WDR4300_PCIE_CALDATA_OFFSET, tmpmac); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0); -+ -+ mdiobus_register_board_info(wdr4300_mdio0_info, -+ ARRAY_SIZE(wdr4300_mdio0_info)); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ -+ /* GMAC0 is connected to an AR8327N switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_register_eth(0); -+ -+ gpio_request_one(WDR4300_GPIO_USB1_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB1 power"); -+ gpio_request_one(WDR4300_GPIO_USB2_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB2 power"); -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WDR4300, "TL-WDR4300", -+ "TP-LINK TL-WDR3600/4300/4310", -+ wdr4300_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr6500-v2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr6500-v2.c -new file mode 100644 -index 0000000000..1e72477646 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr6500-v2.c -@@ -0,0 +1,142 @@ -+/* -+ * TP-LINK TL-WDR6500 v2 -+ * -+ * Copyright (C) 2015 Weijie Gao -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define TL_WDR6500_V2_GPIO_LED_SYS 21 -+#define TL_WDR6500_V2_GPIO_LED_WAN 18 -+#define TL_WDR6500_V2_GPIO_LED_LAN1 17 -+#define TL_WDR6500_V2_GPIO_LED_LAN2 16 -+#define TL_WDR6500_V2_GPIO_LED_LAN3 15 -+#define TL_WDR6500_V2_GPIO_LED_LAN4 14 -+ -+#define TL_WDR6500_V2_GPIO_BTN_RESET 1 -+ -+#define TL_WDR6500_V2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WDR6500_V2_KEYS_DEBOUNCE_INTERVAL (3 * TL_WDR6500_V2_KEYS_POLL_INTERVAL) -+ -+#define TL_WDR6500_V2_WMAC_CALDATA_OFFSET 0x1000 -+#define TL_WDR6500_V2_PCIE_CALDATA_OFFSET 0x5000 -+ -+static const char *tl_wdr6500_v2_part_probes[] = { -+ "tp-link-64k", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wdr6500_v2_flash_data = { -+ .part_probes = tl_wdr6500_v2_part_probes, -+}; -+ -+static struct gpio_led tl_wdr6500_v2_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan1", -+ .gpio = TL_WDR6500_V2_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan2", -+ .gpio = TL_WDR6500_V2_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan3", -+ .gpio = TL_WDR6500_V2_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan4", -+ .gpio = TL_WDR6500_V2_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wan", -+ .gpio = TL_WDR6500_V2_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:white:system", -+ .gpio = TL_WDR6500_V2_GPIO_LED_SYS, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wdr6500_v2_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WDR6500_V2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WDR6500_V2_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+ -+static void __init tl_ap151_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f00fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 tmpmac[ETH_ALEN]; -+ -+ ath79_register_m25p80(&tl_wdr6500_v2_flash_data); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ /* WAN */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(4); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_register_eth(0); -+ -+ /* LAN */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_register_eth(1); -+ -+ ath79_init_mac(tmpmac, mac, -1); -+ ath79_register_wmac(ee + TL_WDR6500_V2_WMAC_CALDATA_OFFSET, tmpmac); -+ -+ ath79_register_pci(); -+ -+ ath79_register_usb(); -+} -+ -+static void __init tl_wdr6500_v2_setup(void) -+{ -+ tl_ap151_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wdr6500_v2_leds_gpio), -+ tl_wdr6500_v2_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, TL_WDR6500_V2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wdr6500_v2_gpio_keys), -+ tl_wdr6500_v2_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WDR6500_V2, "TL-WDR6500-v2", "TP-LINK TL-WDR6500 v2", -+ tl_wdr6500_v2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wpa8630.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wpa8630.c -new file mode 100644 -index 0000000000..a95a11c122 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wpa8630.c -@@ -0,0 +1,172 @@ -+/* -+ * TP-Link TL-WPA8630 board support -+ * -+ * Copyright (C) 2016 Henryk Heisig -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+ -+#define TL_WPA8630_KEYS_POLL_INTERVAL 20 -+#define TL_WPA8630_KEYS_DEBOUNCE_INTERVAL (3 * TL_WPA8630_KEYS_POLL_INTERVAL) -+ -+#define TL_WPA8630_GPIO_LED_POWER 1 -+#define TL_WPA8630_GPIO_LED_LAN 5 -+#define TL_WPA8630_GPIO_LED_WLAN 19 -+#define TL_WPA8630_GPIO_LED_WLAN5 21 -+ -+#define TL_WPA8630_GPIO_BTN_RESET 2 -+#define TL_WPA8630_GPIO_BTN_RFKILL 8 -+#define TL_WPA8630_GPIO_BTN_LED 6 -+#define TL_WPA8630_GPIO_BTN_PAIR 7 -+ -+#define TL_WPA8630_MAC0_OFFSET 0x0000 -+#define TL_WPA8630_WMAC_CALDATA_OFFSET 0x1000 -+#define TL_WPA8630_PCI_CALDATA_OFFSET 0x5000 -+ -+static const char *tl_wpa8630_part_probes[] = { -+ "tp-link-64k", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wpa8630_flash_data = { -+ .part_probes = tl_wpa8630_part_probes, -+ .type = "s25fl064k", -+}; -+ -+static struct gpio_led tl_wpa8630_leds_gpio[] __initdata = { -+ { -+ .name = "tl-wpa8630:green:power", -+ .gpio = TL_WPA8630_GPIO_LED_POWER, -+ .active_low = 1, -+ }, -+ { -+ .name = "tl-wpa8630:green:lan", -+ .gpio = TL_WPA8630_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "tl-wpa8630:green:wlan", -+ .gpio = TL_WPA8630_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "tl-wpa8630:green:wlan5", -+ .gpio = TL_WPA8630_GPIO_LED_WLAN5, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wpa8630_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WPA8630_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WPA8630_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "RFKILL button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = TL_WPA8630_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WPA8630_GPIO_BTN_RFKILL, -+ .active_low = 1, -+ }, -+ { -+ .desc = "LED", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = TL_WPA8630_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WPA8630_GPIO_BTN_LED, -+ .active_low = 1, -+ }, -+ { -+ .desc = "Pair", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .debounce_interval = TL_WPA8630_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WPA8630_GPIO_BTN_PAIR, -+ .active_low = 1, -+ }, -+}; -+ -+/* GMAC0 of the QCA8337 switch is connected to the QCA9563 SoC via SGMII */ -+static struct ar8327_pad_cfg tl_wpa8630_qca8337_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+static struct ar8327_platform_data tl_wpa8630_qca8337_data = { -+ .pad0_cfg = &tl_wpa8630_qca8337_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info tl_wpa8630_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &tl_wpa8630_qca8337_data, -+ }, -+}; -+ -+static void __init tl_wpa8630_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f00fc00); -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(&tl_wpa8630_flash_data); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ art + TL_WPA8630_MAC0_OFFSET, 0); -+ -+ platform_device_register(&ath79_mdio0_device); -+ -+ mdiobus_register_board_info(tl_wpa8630_mdio0_info, -+ ARRAY_SIZE(tl_wpa8630_mdio0_info)); -+ -+ /* GMAC0 is connected to an AR8337 switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_data.phy_mask = ~BIT(4); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(art + TL_WPA8630_WMAC_CALDATA_OFFSET, mac); -+ -+ ap91_pci_init(art + TL_WPA8630_PCI_CALDATA_OFFSET, NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wpa8630_leds_gpio), -+ tl_wpa8630_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WPA8630_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wpa8630_gpio_keys), -+ tl_wpa8630_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WPA8630, "TL-WPA8630", "TP-LINK TL-WPA8630", -+ tl_wpa8630_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1041n-v2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1041n-v2.c -new file mode 100644 -index 0000000000..c98dd4ff00 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1041n-v2.c -@@ -0,0 +1,157 @@ -+/* -+ * TP-LINK TL-WR1041 v2 board support -+ * -+ * Copyright (C) 2010-2012 Gabor Juhos -+ * Copyright (C) 2011-2012 Anan Huang -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_WR1041NV2_GPIO_BTN_RESET 14 -+#define TL_WR1041NV2_GPIO_LED_WPS 13 -+#define TL_WR1041NV2_GPIO_LED_WLAN 11 -+ -+#define TL_WR1041NV2_GPIO_LED_SYSTEM 12 -+ -+#define TL_WR1041NV2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR1041NV2_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR1041NV2_KEYS_POLL_INTERVAL) -+ -+#define TL_WR1041NV2_PCIE_CALDATA_OFFSET 0x5000 -+ -+static const char *tl_wr1041nv2_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wr1041nv2_flash_data = { -+ .part_probes = tl_wr1041nv2_part_probes, -+}; -+ -+static struct gpio_led tl_wr1041nv2_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:system", -+ .gpio = TL_WR1041NV2_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wps", -+ .gpio = TL_WR1041NV2_GPIO_LED_WPS, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WR1041NV2_GPIO_LED_WLAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button tl_wr1041nv2_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR1041NV2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR1041NV2_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static const struct ar8327_led_info tl_wr1041n_leds_ar8327[] = { -+ AR8327_LED_INFO(PHY0_0, HW, "tp-link:green:wan"), -+ AR8327_LED_INFO(PHY1_0, HW, "tp-link:green:lan1"), -+ AR8327_LED_INFO(PHY2_0, HW, "tp-link:green:lan2"), -+ AR8327_LED_INFO(PHY3_0, HW, "tp-link:green:lan3"), -+ AR8327_LED_INFO(PHY4_0, HW, "tp-link:green:lan4"), -+}; -+ -+static struct ar8327_led_cfg wr1041n_v2_ar8327_led_cfg = { -+ .led_ctrl0 = 0xcf35cf35, /* LED0: blink at 10/100/1000M */ -+ .led_ctrl1 = 0xcf35cf35, /* LED1: blink at 10/100/1000M: anyway, no LED1 on tl-wr1041n */ -+ .led_ctrl2 = 0xcf35cf35, /* LED2: blink at 10/100/1000M: anyway, no LED2 on tl-wr1041n */ -+ .led_ctrl3 = 0x03ffff00, /* Pattern enabled for LED 0-2 of port 1-3 */ -+ .open_drain = true, -+}; -+ -+static struct ar8327_pad_cfg db120_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_platform_data db120_ar8327_data = { -+ .pad0_cfg = &db120_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &wr1041n_v2_ar8327_led_cfg, -+ .num_leds = ARRAY_SIZE(tl_wr1041n_leds_ar8327), -+ .leds = tl_wr1041n_leds_ar8327 -+}; -+ -+static struct mdio_board_info db120_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &db120_ar8327_data, -+ }, -+}; -+ -+static void __init tl_wr1041nv2_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_m25p80(&tl_wr1041nv2_flash_data); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr1041nv2_leds_gpio), -+ tl_wr1041nv2_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, TL_WR1041NV2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr1041nv2_gpio_keys), -+ tl_wr1041nv2_gpio_keys); -+ ath79_register_wmac(ee, mac); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_register_mdio(1, 0x0); -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ -+ mdiobus_register_board_info(db120_mdio0_info, -+ ARRAY_SIZE(db120_mdio0_info)); -+ -+ /* GMAC0 is connected to an AR8327 switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR1041N_V2, "TL-WR1041N-v2", -+ "TP-LINK TL-WR1041N v2", tl_wr1041nv2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1043nd-v2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1043nd-v2.c -new file mode 100644 -index 0000000000..90b649957d ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1043nd-v2.c -@@ -0,0 +1,215 @@ -+/* -+ * TP-LINK TL-WR1043ND v2 board support -+ * -+ * Copyright (c) 2013 Gabor Juhos -+ * -+ * Based on the Qualcomm Atheros AP135/AP136 reference board support code -+ * Copyright (c) 2012 Qualcomm Atheros -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_WR1043_V2_GPIO_LED_WLAN 12 -+#define TL_WR1043_V2_GPIO_LED_USB 15 -+#define TL_WR1043_V2_GPIO_LED_WPS 18 -+#define TL_WR1043_V2_GPIO_LED_SYSTEM 19 -+ -+#define TL_WR1043_V2_GPIO_BTN_RESET 16 -+#define TL_WR1043_V2_GPIO_BTN_RFKILL 17 -+ -+#define TL_WR1043_V2_GPIO_USB_POWER 21 -+ -+#define TL_WR1043_V2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR1043_V2_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR1043_V2_KEYS_POLL_INTERVAL) -+ -+#define TL_WR1043_V2_WMAC_CALDATA_OFFSET 0x1000 -+ -+static const char *wr1043nd_v2_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data wr1043nd_v2_flash_data = { -+ .part_probes = wr1043nd_v2_part_probes, -+}; -+ -+static struct gpio_led tl_wr1043_v2_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:wps", -+ .gpio = TL_WR1043_V2_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:system", -+ .gpio = TL_WR1043_V2_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WR1043_V2_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:usb", -+ .gpio = TL_WR1043_V2_GPIO_LED_USB, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr1043_v2_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR1043_V2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR1043_V2_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "RFKILL button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = TL_WR1043_V2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR1043_V2_GPIO_BTN_RFKILL, -+ .active_low = 1, -+ }, -+}; -+ -+static const struct ar8327_led_info tl_wr1043_leds_ar8327[] = { -+ AR8327_LED_INFO(PHY0_0, HW, "tp-link:green:lan4"), -+ AR8327_LED_INFO(PHY1_0, HW, "tp-link:green:lan3"), -+ AR8327_LED_INFO(PHY2_0, HW, "tp-link:green:lan2"), -+ AR8327_LED_INFO(PHY3_0, HW, "tp-link:green:lan1"), -+ AR8327_LED_INFO(PHY4_0, HW, "tp-link:green:wan"), -+}; -+ -+/* GMAC0 of the AR8327 switch is connected to the QCA9558 SoC via SGMII */ -+static struct ar8327_pad_cfg wr1043nd_v2_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+/* GMAC6 of the AR8327 switch is connected to the QCA9558 SoC via RGMII */ -+static struct ar8327_pad_cfg wr1043nd_v2_ar8327_pad6_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_led_cfg wr1043nd_v2_ar8327_led_cfg = { -+ .led_ctrl0 = 0xcc35cc35, -+ .led_ctrl1 = 0xca35ca35, -+ .led_ctrl2 = 0xc935c935, -+ .led_ctrl3 = 0x03ffff00, -+ .open_drain = true, -+}; -+ -+static struct ar8327_platform_data wr1043nd_v2_ar8327_data = { -+ .pad0_cfg = &wr1043nd_v2_ar8327_pad0_cfg, -+ .pad6_cfg = &wr1043nd_v2_ar8327_pad6_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .port6_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &wr1043nd_v2_ar8327_led_cfg, -+ .num_leds = ARRAY_SIZE(tl_wr1043_leds_ar8327), -+ .leds = tl_wr1043_leds_ar8327, -+}; -+ -+static struct mdio_board_info wr1043nd_v2_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &wr1043nd_v2_ar8327_data, -+ }, -+}; -+ -+static void __init tl_wr1043nd_v2_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(&wr1043nd_v2_flash_data); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr1043_v2_leds_gpio), -+ tl_wr1043_v2_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, TL_WR1043_V2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr1043_v2_gpio_keys), -+ tl_wr1043_v2_gpio_keys); -+ -+ ath79_register_wmac(art + TL_WR1043_V2_WMAC_CALDATA_OFFSET, mac); -+ -+ mdiobus_register_board_info(wr1043nd_v2_mdio0_info, -+ ARRAY_SIZE(wr1043nd_v2_mdio0_info)); -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ /* GMAC0 is connected to the RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x56000000; -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_register_eth(1); -+ -+ ath79_register_usb(); -+ -+ gpio_request_one(TL_WR1043_V2_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR1043ND_V2, "TL-WR1043ND-v2", -+ "TP-LINK TL-WR1043ND v2", tl_wr1043nd_v2_setup); -+ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1043nd-v4.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1043nd-v4.c -new file mode 100644 -index 0000000000..04ea49c753 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1043nd-v4.c -@@ -0,0 +1,283 @@ -+/* -+ * TP-LINK WR1043 V4 support -+ * -+ * Copyright (C) 2015-2016 P. Wassi -+ * Copyright (C) 2016 Matthias Schiffer -+ * Copyright (C) 2016 Andreas Ziegler -+ * Copyright (C) 2016 Ludwig Thomeczek -+ * Copyright (C) 2017 Tim Thorpe -+ * -+ * Derived from: mach-dir-869-a1.c -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+#include "nvram.h" -+ -+#define TL_WR1043_V4_GPIO_BTN_RESET 2 -+#define TL_WR1043_V4_GPIO_BTN_RFKILL 5 -+ -+#define TL_WR1043_V4_GPIO_LED_WLAN 19 -+#define TL_WR1043_V4_GPIO_LED_USB 7 -+#define TL_WR1043_V4_GPIO_LED_WPS 1 -+#define TL_WR1043_V4_GPIO_LED_SYSTEM 6 -+ -+#define TL_WR1043_V4_GPIO_USB_POWER 8 -+ -+#define TL_WR1043_V4_GPIO_LED_INET 15 -+#define TL_WR1043_V4_GPIO_LED_WAN 16 -+#define TL_WR1043_V4_GPIO_LED_LAN1 9 -+#define TL_WR1043_V4_GPIO_LED_LAN2 14 -+#define TL_WR1043_V4_GPIO_LED_LAN3 21 -+#define TL_WR1043_V4_GPIO_LED_LAN4 20 -+ -+#define TL_WR1043_V4_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR1043_V4_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR1043_V4_KEYS_POLL_INTERVAL) -+ -+#define TL_WR1043_V4_MAC_LOCATION 0x1ff50008 -+ -+#define TL_WR1043_V4_EEPROM_ADDR 0x1fff0000 -+#define TL_WR1043_V4_WMAC_CALDATA_OFFSET 0x1000 -+ -+#define TL_WR1043_V5_MAC_LOCATION 0x1ff00008 -+ -+static struct gpio_led tl_wr1043nd_v4_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:wps", -+ .gpio = TL_WR1043_V4_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:system", -+ .gpio = TL_WR1043_V4_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WR1043_V4_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:usb", -+ .gpio = TL_WR1043_V4_GPIO_LED_USB, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:wan", -+ .gpio = TL_WR1043_V4_GPIO_LED_INET, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:orange:wan", -+ .gpio = TL_WR1043_V4_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:lan1", -+ .gpio = TL_WR1043_V4_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:lan2", -+ .gpio = TL_WR1043_V4_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:lan3", -+ .gpio = TL_WR1043_V4_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:lan4", -+ .gpio = TL_WR1043_V4_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr1043nd_v4_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR1043_V4_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR1043_V4_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "RFKILL button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = TL_WR1043_V4_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR1043_V4_GPIO_BTN_RFKILL, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg tl_wr1043nd_v4_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+static struct ar8327_platform_data tl_wr1043nd_v4_ar8327_data = { -+ .pad0_cfg = &tl_wr1043nd_v4_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info tl_wr1043nd_v4_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &tl_wr1043nd_v4_ar8327_data, -+ }, -+}; -+ -+static void __init tl_wr1043nd_v4_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(TL_WR1043_V4_MAC_LOCATION); -+ u8 *eeprom = (u8 *) KSEG1ADDR(TL_WR1043_V4_EEPROM_ADDR); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_data.phy_mask = BIT(0); -+ -+ mdiobus_register_board_info(tl_wr1043nd_v4_mdio0_info, -+ ARRAY_SIZE(tl_wr1043nd_v4_mdio0_info)); -+ -+ ath79_register_usb(); -+ ath79_register_mdio(0, 0); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(eeprom + TL_WR1043_V4_WMAC_CALDATA_OFFSET, mac); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr1043nd_v4_leds_gpio), -+ tl_wr1043nd_v4_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WR1043_V4_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr1043nd_v4_gpio_keys), -+ tl_wr1043nd_v4_gpio_keys); -+ -+ gpio_request_one(TL_WR1043_V4_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR1043ND_V4, "TL-WR1043ND-v4", -+ "TP-LINK TL-WR1043ND v4", tl_wr1043nd_v4_setup); -+ -+static struct gpio_led tl_wr1043n_v5_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:wps", -+ .gpio = TL_WR1043_V4_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:system", -+ .gpio = TL_WR1043_V4_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WR1043_V4_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:wan", -+ .gpio = TL_WR1043_V4_GPIO_LED_INET, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:orange:wan", -+ .gpio = TL_WR1043_V4_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:lan1", -+ .gpio = TL_WR1043_V4_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:lan2", -+ .gpio = TL_WR1043_V4_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:lan3", -+ .gpio = TL_WR1043_V4_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:lan4", -+ .gpio = TL_WR1043_V4_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, -+}; -+ -+/* The 1043Nv5 is identical to the 1043NDv4, -+ * only missing the usb and small firmware layout changes */ -+static void __init tl_wr1043nv5_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(TL_WR1043_V4_EEPROM_ADDR); -+ u8 *mac = (u8 *) KSEG1ADDR(TL_WR1043_V5_MAC_LOCATION); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr1043n_v5_leds_gpio), -+ tl_wr1043n_v5_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, TL_WR1043_V4_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr1043nd_v4_gpio_keys), -+ tl_wr1043nd_v4_gpio_keys); -+ -+ platform_device_register(&ath79_mdio0_device); -+ -+ mdiobus_register_board_info(tl_wr1043nd_v4_mdio0_info, -+ ARRAY_SIZE(tl_wr1043nd_v4_mdio0_info)); -+ -+ ath79_register_wmac(art + TL_WR1043_V4_WMAC_CALDATA_OFFSET, mac); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ -+ /* GMAC0 is connected to an AR8337 switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR1043N_V5, "TL-WR1043N-v5", "TP-LINK TL-WR1043N v5", -+ tl_wr1043nv5_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1043nd.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1043nd.c -new file mode 100644 -index 0000000000..4e4b85d736 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1043nd.c -@@ -0,0 +1,141 @@ -+/* -+ * TP-LINK TL-WR1043N/ND board support -+ * -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "dev-eth.h" -+#include "dev-m25p80.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_WR1043ND_GPIO_LED_USB 1 -+#define TL_WR1043ND_GPIO_LED_SYSTEM 2 -+#define TL_WR1043ND_GPIO_LED_QSS 5 -+#define TL_WR1043ND_GPIO_LED_WLAN 9 -+ -+#define TL_WR1043ND_GPIO_BTN_RESET 3 -+#define TL_WR1043ND_GPIO_BTN_QSS 7 -+ -+#define TL_WR1043ND_GPIO_RTL8366_SDA 18 -+#define TL_WR1043ND_GPIO_RTL8366_SCK 19 -+ -+#define TL_WR1043ND_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR1043ND_KEYS_POLL_INTERVAL) -+ -+static const char *tl_wr1043nd_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wr1043nd_flash_data = { -+ .part_probes = tl_wr1043nd_part_probes, -+}; -+ -+static struct gpio_led tl_wr1043nd_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:usb", -+ .gpio = TL_WR1043ND_GPIO_LED_USB, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:system", -+ .gpio = TL_WR1043ND_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WR1043ND_GPIO_LED_QSS, -+ .active_low = 0, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WR1043ND_GPIO_LED_WLAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button tl_wr1043nd_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR1043ND_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "qss", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR1043ND_GPIO_BTN_QSS, -+ .active_low = 1, -+ } -+}; -+ -+static void tl_wr1043nd_rtl8366rb_hw_reset(struct rtl8366_smi *smi, bool active) -+{ -+ if (active) -+ ath79_device_reset_set(AR71XX_RESET_GE0_PHY); -+ else -+ ath79_device_reset_clear(AR71XX_RESET_GE0_PHY); -+} -+ -+static struct rtl8366_platform_data tl_wr1043nd_rtl8366rb_data = { -+ .gpio_sda = TL_WR1043ND_GPIO_RTL8366_SDA, -+ .gpio_sck = TL_WR1043ND_GPIO_RTL8366_SCK, -+ .hw_reset = tl_wr1043nd_rtl8366rb_hw_reset, -+}; -+ -+static struct platform_device tl_wr1043nd_rtl8366rb_device = { -+ .name = RTL8366RB_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &tl_wr1043nd_rtl8366rb_data, -+ } -+}; -+ -+static void __init tl_wr1043nd_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ tl_wr1043nd_rtl8366rb_hw_reset(NULL, true); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_eth0_data.mii_bus_dev = &tl_wr1043nd_rtl8366rb_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_pll_data.pll_1000 = 0x1a000000; -+ -+ ath79_register_eth(0); -+ -+ ath79_register_usb(); -+ -+ ath79_register_m25p80(&tl_wr1043nd_flash_data); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr1043nd_leds_gpio), -+ tl_wr1043nd_leds_gpio); -+ -+ platform_device_register(&tl_wr1043nd_rtl8366rb_device); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WR1043ND_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr1043nd_gpio_keys), -+ tl_wr1043nd_gpio_keys); -+ -+ ath79_register_wmac(eeprom, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR1043ND, "TL-WR1043ND", "TP-LINK TL-WR1043ND", -+ tl_wr1043nd_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr2543n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr2543n.c -new file mode 100644 -index 0000000000..141914aa29 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr2543n.c -@@ -0,0 +1,150 @@ -+/* -+ * TP-LINK TL-WR2543N/ND board support -+ * -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+ -+#define TL_WR2543N_GPIO_LED_WPS 0 -+#define TL_WR2543N_GPIO_LED_USB 8 -+ -+/* The WLAN LEDs use GPIOs on the discrete AR9380 wmac */ -+#define TL_WR2543N_GPIO_WMAC_LED_WLAN2G 0 -+#define TL_WR2543N_GPIO_WMAC_LED_WLAN5G 1 -+ -+#define TL_WR2543N_GPIO_BTN_RESET 11 -+#define TL_WR2543N_GPIO_BTN_WPS 12 -+ -+#define TL_WR2543N_GPIO_RTL8367_SDA 1 -+#define TL_WR2543N_GPIO_RTL8367_SCK 6 -+ -+#define TL_WR2543N_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR2543N_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR2543N_KEYS_POLL_INTERVAL) -+ -+static const char *tl_wr2543n_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wr2543n_flash_data = { -+ .part_probes = tl_wr2543n_part_probes, -+}; -+ -+static struct gpio_led tl_wr2543n_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:usb", -+ .gpio = TL_WR2543N_GPIO_LED_USB, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wps", -+ .gpio = TL_WR2543N_GPIO_LED_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led tl_wr2543n_wmac_leds_gpio[] = { -+ { -+ .name = "tp-link:green:wlan2g", -+ .gpio = TL_WR2543N_GPIO_WMAC_LED_WLAN2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:green:wlan5g", -+ .gpio = TL_WR2543N_GPIO_WMAC_LED_WLAN5G, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr2543n_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR2543N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR2543N_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WR2543N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR2543N_GPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static struct rtl8367_extif_config tl_wr2543n_rtl8367_extif0_cfg = { -+ .mode = RTL8367_EXTIF_MODE_RGMII, -+ .txdelay = 1, -+ .rxdelay = 0, -+ .ability = { -+ .force_mode = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ .link = 1, -+ .duplex = 1, -+ .speed = RTL8367_PORT_SPEED_1000, -+ }, -+}; -+ -+static struct rtl8367_platform_data tl_wr2543n_rtl8367_data = { -+ .gpio_sda = TL_WR2543N_GPIO_RTL8367_SDA, -+ .gpio_sck = TL_WR2543N_GPIO_RTL8367_SCK, -+ .extif0_cfg = &tl_wr2543n_rtl8367_extif0_cfg, -+}; -+ -+static struct platform_device tl_wr2543n_rtl8367_device = { -+ .name = RTL8367_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &tl_wr2543n_rtl8367_data, -+ } -+}; -+ -+static void __init tl_wr2543n_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_m25p80(&tl_wr2543n_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr2543n_leds_gpio), -+ tl_wr2543n_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, TL_WR2543N_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr2543n_gpio_keys), -+ tl_wr2543n_gpio_keys); -+ ath79_register_usb(); -+ -+ ap9x_pci_setup_wmac_leds(0, tl_wr2543n_wmac_leds_gpio, -+ ARRAY_SIZE(tl_wr2543n_wmac_leds_gpio)); -+ ap91_pci_init(eeprom, mac); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, -1); -+ ath79_eth0_data.mii_bus_dev = &tl_wr2543n_rtl8367_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_pll_data.pll_1000 = 0x1a000000; -+ -+ ath79_register_eth(0); -+ -+ platform_device_register(&tl_wr2543n_rtl8367_device); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR2543N, "TL-WR2543N", "TP-LINK TL-WR2543N/ND", -+ tl_wr2543n_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr703n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr703n.c -new file mode 100644 -index 0000000000..1d8d01cc63 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr703n.c -@@ -0,0 +1,118 @@ -+/* -+ * TP-LINK TL-WR703N/TL-MR10U board support -+ * -+ * Copyright (C) 2011 dongyuqi <729650915@qq.com> -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_WR703N_GPIO_LED_SYSTEM 27 -+#define TL_WR703N_GPIO_BTN_RESET 11 -+ -+#define TL_WR703N_GPIO_USB_POWER 8 -+ -+#define TL_MR10U_GPIO_USB_POWER 18 -+ -+#define TL_WR703N_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR703N_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR703N_KEYS_POLL_INTERVAL) -+ -+static const char *tl_wr703n_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wr703n_flash_data = { -+ .part_probes = tl_wr703n_part_probes, -+}; -+ -+static struct gpio_led tl_wr703n_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:blue:system", -+ .gpio = TL_WR703N_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr703n_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR703N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR703N_GPIO_BTN_RESET, -+ .active_low = 0, -+ } -+}; -+ -+static void __init common_setup(unsigned usb_power_gpio, bool sec_ethernet) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_m25p80(&tl_wr703n_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr703n_leds_gpio), -+ tl_wr703n_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, TL_WR703N_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr703n_gpio_keys), -+ tl_wr703n_gpio_keys); -+ -+ gpio_request_one(usb_power_gpio, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ -+ if (sec_ethernet) -+ { -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); -+ ath79_register_eth(1); -+ } -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+static void __init tl_mr10u_setup(void) -+{ -+ common_setup(TL_MR10U_GPIO_USB_POWER, false); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_MR10U, "TL-MR10U", "TP-LINK TL-MR10U", -+ tl_mr10u_setup); -+ -+static void __init tl_wr703n_setup(void) -+{ -+ common_setup(TL_WR703N_GPIO_USB_POWER, false); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR703N, "TL-WR703N", "TP-LINK TL-WR703N v1", -+ tl_wr703n_setup); -+ -+static void __init tl_wr710n_setup(void) -+{ -+ common_setup(TL_WR703N_GPIO_USB_POWER, true); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR710N, "TL-WR710N", "TP-LINK TL-WR710N v1", -+ tl_wr710n_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr720n-v3.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr720n-v3.c -new file mode 100644 -index 0000000000..2bb3b44a71 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr720n-v3.c -@@ -0,0 +1,108 @@ -+/* -+ * TP-LINK TL-WR720N board support -+ * -+ * Copyright (C) 2011 dongyuqi <729650915@qq.com> -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * Copyright (C) 2013 yousong -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_WR720N_GPIO_LED_SYSTEM 27 -+#define TL_WR720N_GPIO_BTN_RESET 11 -+#define TL_WR720N_GPIO_BTN_SW1 18 -+#define TL_WR720N_GPIO_BTN_SW2 20 -+ -+#define TL_WR720N_GPIO_USB_POWER 8 -+ -+#define TL_WR720N_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR720N_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR720N_KEYS_POLL_INTERVAL) -+ -+static const char *tl_wr720n_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wr720n_flash_data = { -+ .part_probes = tl_wr720n_part_probes, -+}; -+ -+static struct gpio_led tl_wr720n_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:blue:system", -+ .gpio = TL_WR720N_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr720n_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR720N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR720N_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, { -+ .desc = "sw1", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = TL_WR720N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR720N_GPIO_BTN_SW1, -+ .active_low = 0, -+ }, { -+ .desc = "sw2", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .debounce_interval = TL_WR720N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR720N_GPIO_BTN_SW2, -+ .active_low = 0, -+ } -+}; -+ -+static void __init tl_wr720n_v3_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_m25p80(&tl_wr720n_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr720n_leds_gpio), -+ tl_wr720n_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, TL_WR720N_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr720n_gpio_keys), -+ tl_wr720n_gpio_keys); -+ -+ gpio_request_one(TL_WR720N_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 2); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR720N_V3, "TL-WR720N-v3", "TP-LINK TL-WR720N v3/v4", -+ tl_wr720n_v3_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr741nd-v4.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr741nd-v4.c -new file mode 100644 -index 0000000000..851b7624ff ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr741nd-v4.c -@@ -0,0 +1,187 @@ -+/* -+ * TP-LINK TL-WR741ND v4/TL-MR3220 v2 board support -+ * -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_WR741NDV4_GPIO_BTN_RESET 11 -+#define TL_WR741NDV4_GPIO_BTN_WPS 26 -+ -+#define TL_WR741NDV4_GPIO_LED_WLAN 0 -+#define TL_WR741NDV4_GPIO_LED_QSS 1 -+#define TL_WR741NDV4_GPIO_LED_WAN 13 -+#define TL_WR741NDV4_GPIO_LED_LAN1 14 -+#define TL_WR741NDV4_GPIO_LED_LAN2 15 -+#define TL_WR741NDV4_GPIO_LED_LAN3 16 -+#define TL_WR741NDV4_GPIO_LED_LAN4 17 -+#define TL_WR741NDV4_GPIO_LED_SYSTEM 27 -+ -+#define TL_MR3220V2_GPIO_BTN_WPS 11 -+#define TL_MR3220V2_GPIO_BTN_WIFI 24 -+ -+#define TL_MR3220V2_GPIO_LED_3G 26 -+#define TL_MR3220V2_GPIO_USB_POWER 8 -+ -+#define TL_WR741NDV4_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR741NDV4_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR741NDV4_KEYS_POLL_INTERVAL) -+ -+static const char *tl_wr741ndv4_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wr741ndv4_flash_data = { -+ .part_probes = tl_wr741ndv4_part_probes, -+}; -+ -+static struct gpio_led tl_wr741ndv4_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan1", -+ .gpio = TL_WR741NDV4_GPIO_LED_LAN1, -+ .active_low = 0, -+ }, { -+ .name = "tp-link:green:lan2", -+ .gpio = TL_WR741NDV4_GPIO_LED_LAN2, -+ .active_low = 0, -+ }, { -+ .name = "tp-link:green:lan3", -+ .gpio = TL_WR741NDV4_GPIO_LED_LAN3, -+ .active_low = 0, -+ }, { -+ .name = "tp-link:green:lan4", -+ .gpio = TL_WR741NDV4_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WR741NDV4_GPIO_LED_QSS, -+ .active_low = 0, -+ }, { -+ .name = "tp-link:green:system", -+ .gpio = TL_WR741NDV4_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wan", -+ .gpio = TL_WR741NDV4_GPIO_LED_WAN, -+ .active_low = 0, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WR741NDV4_GPIO_LED_WLAN, -+ .active_low = 0, -+ }, { -+ /* the 3G LED is only present on the MR3220 v2 */ -+ .name = "tp-link:green:3g", -+ .gpio = TL_MR3220V2_GPIO_LED_3G, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr741ndv4_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR741NDV4_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR741NDV4_GPIO_BTN_RESET, -+ .active_low = 0, -+ }, { -+ .desc = "WPS", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WR741NDV4_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR741NDV4_GPIO_BTN_WPS, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button tl_mr3220v2_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WR741NDV4_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR3220V2_GPIO_BTN_WPS, -+ .active_low = 0, -+ }, { -+ .desc = "WIFI button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = TL_WR741NDV4_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_MR3220V2_GPIO_BTN_WIFI, -+ .active_low = 0, -+ } -+}; -+ -+static void __init tl_ap121_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_setup_ar933x_phy4_switch(true, true); -+ -+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ ath79_register_m25p80(&tl_wr741ndv4_flash_data); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(1); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+static void __init tl_wr741ndv4_setup(void) -+{ -+ tl_ap121_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr741ndv4_leds_gpio) - 1, -+ tl_wr741ndv4_leds_gpio); -+ ath79_register_gpio_keys_polled(1, TL_WR741NDV4_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr741ndv4_gpio_keys), -+ tl_wr741ndv4_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR741ND_V4, "TL-WR741ND-v4", -+ "TP-LINK TL-WR741ND v4", tl_wr741ndv4_setup); -+ -+static void __init tl_mr3220v2_setup(void) -+{ -+ tl_ap121_setup(); -+ -+ gpio_request_one(TL_MR3220V2_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr741ndv4_leds_gpio), -+ tl_wr741ndv4_leds_gpio); -+ ath79_register_gpio_keys_polled(1, TL_WR741NDV4_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_mr3220v2_gpio_keys), -+ tl_mr3220v2_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_MR3220_V2, "TL-MR3220-v2", -+ "TP-LINK TL-MR3220 v2", tl_mr3220v2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr741nd.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr741nd.c -new file mode 100644 -index 0000000000..5931654bbd ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr741nd.c -@@ -0,0 +1,130 @@ -+/* -+ * TP-LINK TL-WR741ND board support -+ * -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+ -+#define TL_WR741ND_GPIO_LED_QSS 0 -+#define TL_WR741ND_GPIO_LED_SYSTEM 1 -+#define TL_WR741ND_GPIO_LED_LAN1 13 -+#define TL_WR741ND_GPIO_LED_LAN2 14 -+#define TL_WR741ND_GPIO_LED_LAN3 15 -+#define TL_WR741ND_GPIO_LED_LAN4 16 -+#define TL_WR741ND_GPIO_LED_WAN 17 -+ -+#define TL_WR741ND_GPIO_BTN_RESET 11 -+#define TL_WR741ND_GPIO_BTN_QSS 12 -+ -+#define TL_WR741ND_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR741ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR741ND_KEYS_POLL_INTERVAL) -+ -+static const char *tl_wr741nd_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wr741nd_flash_data = { -+ .part_probes = tl_wr741nd_part_probes, -+}; -+ -+static struct gpio_led tl_wr741nd_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan1", -+ .gpio = TL_WR741ND_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan2", -+ .gpio = TL_WR741ND_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan3", -+ .gpio = TL_WR741ND_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan4", -+ .gpio = TL_WR741ND_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WR741ND_GPIO_LED_QSS, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:system", -+ .gpio = TL_WR741ND_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wan", -+ .gpio = TL_WR741ND_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr741nd_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR741ND_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR741ND_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "qss", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WR741ND_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR741ND_GPIO_BTN_QSS, -+ .active_low = 1, -+ } -+}; -+ -+static void __init tl_wr741nd_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_m25p80(&tl_wr741nd_flash_data); -+ -+ ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr741nd_leds_gpio), -+ tl_wr741nd_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WR741ND_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr741nd_gpio_keys), -+ tl_wr741nd_gpio_keys); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN ports */ -+ ath79_register_eth(1); -+ -+ /* WAN port */ -+ ath79_register_eth(0); -+ -+ ap9x_pci_setup_wmac_led_pin(0, 1); -+ ap91_pci_init(ee, mac); -+} -+MIPS_MACHINE(ATH79_MACH_TL_WR741ND, "TL-WR741ND", "TP-LINK TL-WR741ND", -+ tl_wr741nd_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr802n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr802n.c -new file mode 100644 -index 0000000000..514529ca18 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr802n.c -@@ -0,0 +1,117 @@ -+/* -+ * TP-LINK TL-WR802N v1, v2 -+ * -+ * Copyright (C) 2015 Rick Pannen > -+ * Copyright (C) 2016 Thomas Roberts > -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_WR802N_GPIO_LED_SYSTEM 13 -+#define TL_WR802N_GPIO_BTN_RESET 12 -+ -+#define TL_WR802N_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR802N_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR802N_KEYS_POLL_INTERVAL) -+ -+static const char *tl_wr802n_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wr802n_flash_data = { -+ .part_probes = tl_wr802n_part_probes, -+}; -+ -+static struct gpio_led tl_wr802n_v1_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:blue:system", -+ .gpio = TL_WR802N_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led tl_wr802n_v2_leds_gpio[] __initdata = { -+ { -+ .name = "tl-wr802n-v2:green:system", -+ .gpio = TL_WR802N_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr802n_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR802N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR802N_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init tl_ap143_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 tmpmac[ETH_ALEN]; -+ -+ ath79_register_m25p80(&tl_wr802n_flash_data); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_register_eth(0); -+ -+ ath79_init_mac(tmpmac, mac, 0); -+ ath79_register_wmac(ee, tmpmac); -+ -+ ath79_register_gpio_keys_polled(1, TL_WR802N_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr802n_gpio_keys), -+ tl_wr802n_gpio_keys); -+} -+ -+static void __init tl_wr802n_v1_setup(void) -+{ -+ tl_ap143_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr802n_v1_leds_gpio), -+ tl_wr802n_v1_leds_gpio); -+} -+ -+static void __init tl_wr802n_v2_setup(void) -+{ -+ tl_ap143_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr802n_v2_leds_gpio), -+ tl_wr802n_v2_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR802N_V1, "TL-WR802N-v1", "TP-LINK TL-WR802N v1", -+ tl_wr802n_v1_setup); -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR802N_V2, "TL-WR802N-v2", "TP-LINK TL-WR802N v2", -+ tl_wr802n_v2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr810n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr810n.c -new file mode 100644 -index 0000000000..588bb9d861 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr810n.c -@@ -0,0 +1,149 @@ -+/* -+ * TP-LINK TL-WR810N board support -+ * -+ * Copyright (c) 2012 Qualcomm Atheros -+ * Copyright (c) 2012 Gabor Juhos -+ * Copyright (c) 2016 Jens Steinhauser -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_WR810N_GPIO_SWITCH_B1 0 -+#define TL_WR810N_GPIO_SWITCH_B0 1 -+#define TL_WR810N_GPIO_USB_POWER 11 -+#define TL_WR810N_GPIO_BTN_RESET 12 -+#define TL_WR810N_GPIO_LED_SYSTEM 13 -+ -+#define TL_WR810N_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR810N_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR810N_KEYS_POLL_INTERVAL) -+ -+#define TL_WR810N_WMAC_CALDATA_OFFSET 0x1000 -+ -+static const char *tl_wr810n_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wr810n_flash_data = { -+ .part_probes = tl_wr810n_part_probes, -+}; -+ -+static struct gpio_led tl_wr810n_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:blue:system", -+ .gpio = TL_WR810N_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr810n_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR810N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR810N_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "switch_b0", -+ .type = EV_SW, -+ .code = BTN_0, -+ .debounce_interval = TL_WR810N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR810N_GPIO_SWITCH_B0, -+ .active_low = 0, -+ }, -+ { -+ .desc = "switch_b1", -+ .type = EV_SW, -+ .code = BTN_1, -+ .debounce_interval = TL_WR810N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR810N_GPIO_SWITCH_B1, -+ .active_low = 0, -+ }, -+}; -+ -+static void __init tl_ap143_setup(int lan_mac_offset) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(&tl_wr810n_flash_data); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* WAN */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_register_eth(0); -+ -+ /* LAN */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, lan_mac_offset); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(art + TL_WR810N_WMAC_CALDATA_OFFSET, mac); -+ -+ ath79_register_leds_gpio(-1, -+ ARRAY_SIZE(tl_wr810n_leds_gpio), -+ tl_wr810n_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, -+ TL_WR810N_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr810n_gpio_keys), -+ tl_wr810n_gpio_keys); -+} -+ -+static void __init tl_wr810n_setup(void) -+{ -+ tl_ap143_setup(-1); -+ -+ gpio_request_one(TL_WR810N_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+} -+ -+static void __init tl_wr810n_v2_setup(void) -+{ -+ tl_ap143_setup(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR810N, "TL-WR810N", "TP-LINK TL-WR810N", -+ tl_wr810n_setup); -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR810N_V2, "TL-WR810N-v2", "TP-LINK TL-WR810N v2", -+ tl_wr810n_v2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n-v8.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n-v8.c -new file mode 100644 -index 0000000000..73cfdd9cc6 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n-v8.c -@@ -0,0 +1,286 @@ -+/* -+ * TP-LINK TL-WR841N/ND v8/TL-MR3420 v2 board support -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_WR841NV8_GPIO_LED_WLAN 13 -+#define TL_WR841NV8_GPIO_LED_QSS 15 -+#define TL_WR841NV8_GPIO_LED_WAN 18 -+#define TL_WR841NV8_GPIO_LED_LAN1 19 -+#define TL_WR841NV8_GPIO_LED_LAN2 20 -+#define TL_WR841NV8_GPIO_LED_LAN3 21 -+#define TL_WR841NV8_GPIO_LED_LAN4 12 -+#define TL_WR841NV8_GPIO_LED_SYSTEM 14 -+ -+#define TL_WR841NV8_GPIO_BTN_RESET 17 -+#define TL_WR841NV8_GPIO_SW_RFKILL 16 /* WPS for MR3420 v2 */ -+ -+#define TL_MR3420V2_GPIO_LED_3G 11 -+#define TL_MR3420V2_GPIO_USB_POWER 4 -+ -+#define TL_WR941NDV5_GPIO_LED_WLAN 13 -+#define TL_WR941NDV5_GPIO_LED_QSS 15 -+#define TL_WR941NDV5_GPIO_LED_WAN 18 -+#define TL_WR941NDV5_GPIO_LED_LAN1 19 -+#define TL_WR941NDV5_GPIO_LED_LAN2 20 -+#define TL_WR941NDV5_GPIO_LED_LAN3 2 -+#define TL_WR941NDV5_GPIO_LED_LAN4 3 -+#define TL_WR941NDV5_GPIO_LED_SYSTEM 14 -+ -+#define TL_WR841NV8_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR841NV8_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR841NV8_KEYS_POLL_INTERVAL) -+ -+static const char *tl_wr841n_v8_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wr841n_v8_flash_data = { -+ .part_probes = tl_wr841n_v8_part_probes, -+}; -+ -+static struct gpio_led tl_wr841n_v8_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan1", -+ .gpio = TL_WR841NV8_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan2", -+ .gpio = TL_WR841NV8_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan3", -+ .gpio = TL_WR841NV8_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan4", -+ .gpio = TL_WR841NV8_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WR841NV8_GPIO_LED_QSS, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:system", -+ .gpio = TL_WR841NV8_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wan", -+ .gpio = TL_WR841NV8_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WR841NV8_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ /* the 3G LED is only present on the MR3420 v2 */ -+ .name = "tp-link:green:3g", -+ .gpio = TL_MR3420V2_GPIO_LED_3G, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr841n_v8_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR841NV8_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR841NV8_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "RFKILL switch", -+ .type = EV_SW, -+ .code = KEY_RFKILL, -+ .debounce_interval = TL_WR841NV8_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR841NV8_GPIO_SW_RFKILL, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button tl_mr3420v2_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR841NV8_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR841NV8_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "WPS", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WR841NV8_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR841NV8_GPIO_SW_RFKILL, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_led tl_wr941nd_v5_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan1", -+ .gpio = TL_WR941NDV5_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan2", -+ .gpio = TL_WR941NDV5_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan3", -+ .gpio = TL_WR941NDV5_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan4", -+ .gpio = TL_WR941NDV5_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WR941NDV5_GPIO_LED_QSS, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:system", -+ .gpio = TL_WR941NDV5_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wan", -+ .gpio = TL_WR941NDV5_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WR941NDV5_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init tl_ap123_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* Disable JTAG, enabling GPIOs 0-3 */ -+ /* Configure OBS4 line, for GPIO 4*/ -+ ath79_gpio_function_setup(AR934X_GPIO_FUNC_JTAG_DISABLE, -+ AR934X_GPIO_FUNC_CLK_OBS4_EN); -+ -+ /* config gpio4 as normal gpio function */ -+ ath79_gpio_output_select(TL_MR3420V2_GPIO_USB_POWER, -+ AR934X_GPIO_OUT_GPIO); -+ -+ ath79_register_m25p80(&tl_wr841n_v8_flash_data); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_PHY_SWAP); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, -1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ -+ /* GMAC0 is connected to the PHY0 of the internal switch */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the internal switch */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+static void __init tl_wr841n_v8_setup(void) -+{ -+ tl_ap123_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr841n_v8_leds_gpio) - 1, -+ tl_wr841n_v8_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, TL_WR841NV8_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr841n_v8_gpio_keys), -+ tl_wr841n_v8_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR841N_V8, "TL-WR841N-v8", "TP-LINK TL-WR841N/ND v8", -+ tl_wr841n_v8_setup); -+ -+ -+static void __init tl_wr842n_v2_setup(void) -+{ -+ tl_ap123_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr841n_v8_leds_gpio), -+ tl_wr841n_v8_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, TL_WR841NV8_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr841n_v8_gpio_keys), -+ tl_wr841n_v8_gpio_keys); -+ -+ gpio_request_one(TL_MR3420V2_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR842N_V2, "TL-WR842N-v2", "TP-LINK TL-WR842N/ND v2", -+ tl_wr842n_v2_setup); -+ -+static void __init tl_mr3420v2_setup(void) -+{ -+ tl_ap123_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr841n_v8_leds_gpio), -+ tl_wr841n_v8_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, TL_WR841NV8_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_mr3420v2_gpio_keys), -+ tl_mr3420v2_gpio_keys); -+ -+ /* enable power for the USB port */ -+ gpio_request_one(TL_MR3420V2_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_MR3420_V2, "TL-MR3420-v2", "TP-LINK TL-MR3420 v2", -+ tl_mr3420v2_setup); -+ -+ -+static void __init tl_wr941nd_v5_setup(void) -+{ -+ tl_ap123_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr941nd_v5_leds_gpio), -+ tl_wr941nd_v5_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, TL_WR841NV8_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr841n_v8_gpio_keys), -+ tl_wr841n_v8_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR941ND_V5, "TL-WR941ND-v5", "TP-LINK TL-WR941N/ND v5", -+ tl_wr941nd_v5_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n-v9.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n-v9.c -new file mode 100644 -index 0000000000..304d8ff6e9 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n-v9.c -@@ -0,0 +1,457 @@ -+/* -+ * TP-LINK TL-WR840N v2/v3 / TL-WR841N/ND v9/v11 / TL-WR842N/ND v3 -+ * -+ * Copyright (C) 2014 Matthias Schiffer -+ * Copyright (C) 2016 Cezary Jackiewicz -+ * Copyright (C) 2016 Stijn Segers -+ * Copyright (C) 2017 Vaclav Svoboda -+ * Copyright (C) 2017 Andrey Polischuk -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_WR840NV2_GPIO_LED_SYSTEM 15 -+#define TL_WR840NV2_GPIO_LED_WLAN 13 -+#define TL_WR840NV2_GPIO_LED_WPS 3 -+#define TL_WR840NV2_GPIO_LED_WAN 4 -+#define TL_WR840NV2_GPIO_LED_LAN 16 -+ -+#define TL_WR840NV2_GPIO_BTN_RESET 12 -+ -+#define TL_WR841NV9_GPIO_LED_WLAN 13 -+#define TL_WR841NV9_GPIO_LED_QSS 3 -+#define TL_WR841NV9_GPIO_LED_WAN 4 -+#define TL_WR841NV9_GPIO_LED_LAN1 16 -+#define TL_WR841NV9_GPIO_LED_LAN2 15 -+#define TL_WR841NV9_GPIO_LED_LAN3 14 -+#define TL_WR841NV9_GPIO_LED_LAN4 11 -+ -+#define TL_WR841NV9_GPIO_BTN_RESET 12 -+#define TL_WR841NV9_GPIO_BTN_WIFI 17 -+ -+#define TL_WR841NV11_GPIO_LED_SYSTEM 1 -+#define TL_WR841NV11_GPIO_LED_QSS 3 -+#define TL_WR841NV11_GPIO_LED_WAN 4 -+#define TL_WR841NV11_GPIO_LED_WAN_STATUS 2 -+#define TL_WR841NV11_GPIO_LED_WLAN 13 -+#define TL_WR841NV11_GPIO_LED_LAN1 16 -+#define TL_WR841NV11_GPIO_LED_LAN2 15 -+#define TL_WR841NV11_GPIO_LED_LAN3 14 -+#define TL_WR841NV11_GPIO_LED_LAN4 11 -+ -+#define TL_WR841NV11_GPIO_BTN_RESET 12 -+#define TL_WR841NV11_GPIO_BTN_WIFI 17 -+ -+#define TL_WR842NV3_GPIO_LED_SYSTEM 2 -+#define TL_WR842NV3_GPIO_LED_WLAN 3 -+#define TL_WR842NV3_GPIO_LED_WAN_RED 4 -+#define TL_WR842NV3_GPIO_LED_WAN_GREEN 11 -+#define TL_WR842NV3_GPIO_LED_LAN1 12 -+#define TL_WR842NV3_GPIO_LED_LAN2 13 -+#define TL_WR842NV3_GPIO_LED_LAN3 14 -+#define TL_WR842NV3_GPIO_LED_LAN4 15 -+#define TL_WR842NV3_GPIO_LED_3G 16 -+#define TL_WR842NV3_GPIO_LED_WPS 17 -+ -+#define TL_WR842NV3_GPIO_BTN_RESET 1 -+#define TL_WR842NV3_GPIO_BTN_WIFI 0 -+ -+#define TL_WR740NV6_GPIO_LED_SYSTEM 1 -+#define TL_WR740NV6_GPIO_LED_QSS 3 -+#define TL_WR740NV6_GPIO_LED_WAN_ORANGE 2 -+#define TL_WR740NV6_GPIO_LED_WAN_GREEN 4 -+#define TL_WR740NV6_GPIO_LED_LAN1 16 -+#define TL_WR740NV6_GPIO_LED_LAN2 15 -+#define TL_WR740NV6_GPIO_LED_LAN3 14 -+#define TL_WR740NV6_GPIO_LED_LAN4 11 -+#define TL_WR740NV6_GPIO_LED_WLAN 13 -+ -+#define TL_WR740NV6_GPIO_BTN_RESET 12 -+#define TL_WR740NV6_GPIO_BTN_WIFI 17 -+ -+#define TL_WR841NV9_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR841NV9_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR841NV9_KEYS_POLL_INTERVAL) -+ -+static const char *tl_wr841n_v9_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wr841n_v9_flash_data = { -+ .part_probes = tl_wr841n_v9_part_probes, -+}; -+ -+static struct gpio_led tl_wr840n_v2_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:system", -+ .gpio = TL_WR840NV2_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan", -+ .gpio = TL_WR840NV2_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wps", -+ .gpio = TL_WR840NV2_GPIO_LED_WPS, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wan", -+ .gpio = TL_WR840NV2_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WR840NV2_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr840n_v2_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR841NV9_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR840NV2_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led tl_wr841n_v9_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan1", -+ .gpio = TL_WR841NV9_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan2", -+ .gpio = TL_WR841NV9_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan3", -+ .gpio = TL_WR841NV9_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan4", -+ .gpio = TL_WR841NV9_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WR841NV9_GPIO_LED_QSS, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wan", -+ .gpio = TL_WR841NV9_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WR841NV9_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr841n_v9_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR841NV9_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR841NV9_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "WIFI button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = TL_WR841NV9_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR841NV9_GPIO_BTN_WIFI, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led tl_wr841n_v11_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan1", -+ .gpio = TL_WR841NV9_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan2", -+ .gpio = TL_WR841NV9_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan3", -+ .gpio = TL_WR841NV9_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan4", -+ .gpio = TL_WR841NV9_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WR841NV9_GPIO_LED_QSS, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:system", -+ .gpio = TL_WR841NV11_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wan", -+ .gpio = TL_WR841NV9_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wan_status", -+ .gpio = TL_WR841NV11_GPIO_LED_WAN_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WR841NV9_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led tl_wr842n_v3_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan1", -+ .gpio = TL_WR842NV3_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan2", -+ .gpio = TL_WR842NV3_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan3", -+ .gpio = TL_WR842NV3_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan4", -+ .gpio = TL_WR842NV3_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wan", -+ .gpio = TL_WR842NV3_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:red:wan", -+ .gpio = TL_WR842NV3_GPIO_LED_WAN_RED, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WR842NV3_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:system", -+ .gpio = TL_WR842NV3_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:3g", -+ .gpio = TL_WR842NV3_GPIO_LED_3G, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wps", -+ .gpio = TL_WR842NV3_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr842n_v3_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR841NV9_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR842NV3_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "WIFI button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = TL_WR841NV9_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR842NV3_GPIO_BTN_WIFI, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led tl_wr740n_v6_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan1", -+ .gpio = TL_WR740NV6_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan2", -+ .gpio = TL_WR740NV6_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan3", -+ .gpio = TL_WR740NV6_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan4", -+ .gpio = TL_WR740NV6_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:system", -+ .gpio = TL_WR740NV6_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WR740NV6_GPIO_LED_QSS, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wan", -+ .gpio = TL_WR740NV6_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:orange:wan", -+ .gpio = TL_WR740NV6_GPIO_LED_WAN_ORANGE, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WR740NV6_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr740n_v6_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR841NV9_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR740NV6_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "WIFI button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = TL_WR841NV9_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR740NV6_GPIO_BTN_WIFI, -+ .active_low = 1, -+ } -+}; -+ -+static void __init tl_ap143_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 tmpmac[ETH_ALEN]; -+ -+ ath79_register_m25p80(&tl_wr841n_v9_flash_data); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_register_eth(0); -+ -+ ath79_init_mac(tmpmac, mac, 0); -+ ath79_register_wmac(ee, tmpmac); -+} -+ -+ -+static void __init tl_wr840n_v2_setup(void) -+{ -+ tl_ap143_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr840n_v2_leds_gpio), -+ tl_wr840n_v2_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, TL_WR841NV9_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr840n_v2_gpio_keys), -+ tl_wr840n_v2_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR840N_V2, "TL-WR840N-v2", "TP-LINK TL-WR840N v2", -+ tl_wr840n_v2_setup); -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR840N_V3, "TL-WR840N-v3", "TP-LINK TL-WR840N v3", -+ tl_wr840n_v2_setup); -+ -+static void __init tl_wr841n_v9_setup(void) -+{ -+ tl_ap143_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr841n_v9_leds_gpio), -+ tl_wr841n_v9_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, TL_WR841NV9_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr841n_v9_gpio_keys), -+ tl_wr841n_v9_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR841N_V9, "TL-WR841N-v9", "TP-LINK TL-WR841N/ND v9", -+ tl_wr841n_v9_setup); -+ -+static void __init tl_wr841n_v11_setup(void) -+{ -+ tl_ap143_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr841n_v11_leds_gpio), -+ tl_wr841n_v11_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, TL_WR841NV9_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr841n_v9_gpio_keys), -+ tl_wr841n_v9_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR841N_V11, "TL-WR841N-v11", "TP-LINK TL-WR841N/ND v11", -+ tl_wr841n_v11_setup); -+ -+static void __init tl_wr842n_v3_setup(void) -+{ -+ tl_ap143_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr842n_v3_leds_gpio), -+ tl_wr842n_v3_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, TL_WR841NV9_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr842n_v3_gpio_keys), -+ tl_wr842n_v3_gpio_keys); -+ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR842N_V3, "TL-WR842N-v3", "TP-LINK TL-WR842N/ND v3", -+ tl_wr842n_v3_setup); -+ -+static void __init tl_wr740n_v6_setup(void) -+{ -+ tl_ap143_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr740n_v6_leds_gpio), -+ tl_wr740n_v6_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, TL_WR841NV9_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr740n_v6_gpio_keys), -+ tl_wr740n_v6_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR740N_V6, "TL-WR740N-v6", "TP-LINK TL-WR740N/ND v6", -+ tl_wr740n_v6_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n.c -new file mode 100644 -index 0000000000..11f853f057 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n.c -@@ -0,0 +1,140 @@ -+/* -+ * TP-LINK TL-WR841N/ND v1 board support -+ * -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "dev-dsa.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define TL_WR841ND_V1_GPIO_LED_SYSTEM 2 -+#define TL_WR841ND_V1_GPIO_LED_QSS_GREEN 4 -+#define TL_WR841ND_V1_GPIO_LED_QSS_RED 5 -+ -+#define TL_WR841ND_V1_GPIO_BTN_RESET 3 -+#define TL_WR841ND_V1_GPIO_BTN_QSS 7 -+ -+#define TL_WR841ND_V1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * TL_WR841ND_V1_KEYS_POLL_INTERVAL) -+ -+static struct mtd_partition tl_wr841n_v1_partitions[] = { -+ { -+ .name = "redboot", -+ .offset = 0, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "kernel", -+ .offset = 0x020000, -+ .size = 0x140000, -+ }, { -+ .name = "rootfs", -+ .offset = 0x160000, -+ .size = 0x280000, -+ }, { -+ .name = "config", -+ .offset = 0x3e0000, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x020000, -+ .size = 0x3c0000, -+ } -+}; -+ -+static struct flash_platform_data tl_wr841n_v1_flash_data = { -+ .parts = tl_wr841n_v1_partitions, -+ .nr_parts = ARRAY_SIZE(tl_wr841n_v1_partitions), -+}; -+ -+static struct gpio_led tl_wr841n_v1_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:system", -+ .gpio = TL_WR841ND_V1_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:red:qss", -+ .gpio = TL_WR841ND_V1_GPIO_LED_QSS_RED, -+ }, { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WR841ND_V1_GPIO_LED_QSS_GREEN, -+ } -+}; -+ -+static struct gpio_keys_button tl_wr841n_v1_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR841ND_V1_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "qss", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR841ND_V1_GPIO_BTN_QSS, -+ .active_low = 1, -+ } -+}; -+ -+static struct dsa_chip_data tl_wr841n_v1_dsa_chip = { -+ .port_names[0] = "wan", -+ .port_names[1] = "lan1", -+ .port_names[2] = "lan2", -+ .port_names[3] = "lan3", -+ .port_names[4] = "lan4", -+ .port_names[5] = "cpu", -+}; -+ -+static struct dsa_platform_data tl_wr841n_v1_dsa_data = { -+ .nr_chips = 1, -+ .chip = &tl_wr841n_v1_dsa_chip, -+}; -+ -+static void __init tl_wr841n_v1_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(0); -+ ath79_register_dsa(&ath79_eth0_device.dev, &ath79_mdio0_device.dev, -+ &tl_wr841n_v1_dsa_data); -+ -+ ath79_register_m25p80(&tl_wr841n_v1_flash_data); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr841n_v1_leds_gpio), -+ tl_wr841n_v1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WR841ND_V1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr841n_v1_gpio_keys), -+ tl_wr841n_v1_gpio_keys); -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR841N_V1, "TL-WR841N-v1.5", "TP-LINK TL-WR841N v1", -+ tl_wr841n_v1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr902ac-v1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr902ac-v1.c -new file mode 100644 -index 0000000000..8d2cea828a ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr902ac-v1.c -@@ -0,0 +1,145 @@ -+/* -+ * TP-Link TL-WR902AC v1 board support -+ * -+ * Copyright (C) 2017 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+ -+#define TL_WR902AC_V1_GPIO_LED_INTERNET 12 -+#define TL_WR902AC_V1_GPIO_LED_LAN 15 -+#define TL_WR902AC_V1_GPIO_LED_POWER 13 -+#define TL_WR902AC_V1_GPIO_LED_USB 4 -+#define TL_WR902AC_V1_GPIO_LED_WLAN2G 11 -+#define TL_WR902AC_V1_GPIO_LED_WPS 0 -+ -+#define TL_WR902AC_V1_GPIO_BTN_RESET 3 -+#define TL_WR902AC_V1_GPIO_BTN_SW1 17 -+#define TL_WR902AC_V1_GPIO_BTN_SW2 14 -+#define TL_WR902AC_V1_GPIO_BTN_WPS 2 -+ -+#define TL_WR902AC_V1_GPIO_USB_POWER 1 -+ -+#define TL_WR902AC_V1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR902AC_V1_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * TL_WR902AC_V1_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led tl_wr902ac_v1_leds_gpio[] __initdata = { -+ { -+ .name = "tl-wr902ac-v1:green:internet", -+ .gpio = TL_WR902AC_V1_GPIO_LED_INTERNET, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr902ac-v1:green:lan", -+ .gpio = TL_WR902AC_V1_GPIO_LED_LAN, -+ .active_low = 0, -+ }, { -+ .name = "tl-wr902ac-v1:green:power", -+ .gpio = TL_WR902AC_V1_GPIO_LED_POWER, -+ .active_low = 0, -+ }, { -+ .name = "tl-wr902ac-v1:green:usb", -+ .gpio = TL_WR902AC_V1_GPIO_LED_USB, -+ .active_low = 0, -+ }, { -+ .name = "tl-wr902ac-v1:green:wlan2g", -+ .gpio = TL_WR902AC_V1_GPIO_LED_WLAN2G, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr902ac-v1:green:wps", -+ .gpio = TL_WR902AC_V1_GPIO_LED_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button tl_wr902ac_v1_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR902AC_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR902AC_V1_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "sw1", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = TL_WR902AC_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR902AC_V1_GPIO_BTN_SW1, -+ .active_low = 1, -+ }, { -+ .desc = "sw2", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .debounce_interval = TL_WR902AC_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR902AC_V1_GPIO_BTN_SW2, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WR902AC_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR902AC_V1_GPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static void __init tl_wr902ac_v1_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1f7f0000); -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f750008); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.speed = SPEED_100; -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_register_eth(0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr902ac_v1_leds_gpio), -+ tl_wr902ac_v1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WR902AC_V1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr902ac_v1_gpio_keys), -+ tl_wr902ac_v1_gpio_keys); -+ -+ gpio_request_one(TL_WR902AC_V1_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ -+ ath79_register_usb(); -+ -+ ath79_register_wmac(art + 0x1000, mac); -+ -+ ap91_pci_init(art + 0x5000, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR902AC_V1, "TL-WR902AC-V1", "TP-LINK TL-WR902AC v1", -+ tl_wr902ac_v1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr940n-v4.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr940n-v4.c -new file mode 100644 -index 0000000000..9324b2b924 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr940n-v4.c -@@ -0,0 +1,184 @@ -+/* -+ * TP-LINK TL-WR940N v4 and v6 board support -+ * -+ * Copyright (C) 2016 David Lutz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+ -+#define TL_WR940N_V4_GPIO_LED_QSS 3 -+#define TL_WR940N_V4_GPIO_LED_WAN 14 -+#define TL_WR940N_V4_GPIO_LED_WAN_RED 15 -+#define TL_WR940N_V4_GPIO_LED_LAN4 4 -+#define TL_WR940N_V4_GPIO_LED_LAN3 18 -+#define TL_WR940N_V4_GPIO_LED_LAN2 6 -+#define TL_WR940N_V4_GPIO_LED_LAN1 8 -+#define TL_WR940N_V4_GPIO_LED_WLAN 7 -+#define TL_WR940N_V4_GPIO_LED_SYSTEM 5 -+/* WR940N v6 specific GPIO*/ -+#define TL_WR940N_V6_GPIO_LED_DIAG_ORANGE 15 -+#define TL_WR940N_V6_GPIO_LED_WAN_BLUE 14 -+ -+#define TL_WR940N_V4_GPIO_BTN_RESET 1 -+#define TL_WR940N_V4_GPIO_BTN_RFKILL 2 -+ -+#define TL_WR940N_KEYS_POLL_INTERVAL 20 -+#define TL_WR940N_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR940N_KEYS_POLL_INTERVAL) -+ -+ -+static struct gpio_led tl_wr940n_v4_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:blue:qss", -+ .gpio = TL_WR940N_V4_GPIO_LED_QSS, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:blue:wan", -+ .gpio = TL_WR940N_V4_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:red:wan", -+ .gpio = TL_WR940N_V4_GPIO_LED_WAN_RED, -+ .active_low = 0, -+ }, -+ { -+ .name = "tp-link:blue:lan1", -+ .gpio = TL_WR940N_V4_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:blue:lan2", -+ .gpio = TL_WR940N_V4_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:blue:lan3", -+ .gpio = TL_WR940N_V4_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:blue:lan4", -+ .gpio = TL_WR940N_V4_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:blue:wlan", -+ .gpio = TL_WR940N_V4_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:blue:system", -+ .gpio = TL_WR940N_V4_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr940n_v4_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR940N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR940N_V4_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "RFKILL button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = TL_WR940N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR940N_V4_GPIO_BTN_RFKILL, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led tl_wr940n_v6_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:blue:wan", -+ .gpio = TL_WR940N_V6_GPIO_LED_WAN_BLUE, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:orange:diag", -+ .gpio = TL_WR940N_V6_GPIO_LED_DIAG_ORANGE, -+ .active_low = 0, -+ }, -+}; -+ -+ -+static const char *tl_wr940n_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wr940n_flash_data = { -+ .part_probes = tl_wr940n_part_probes, -+}; -+ -+ -+static void __init tl_wr940n_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_m25p80(&tl_wr940n_flash_data); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(ee, mac); -+ -+} -+ -+static void __init tl_wr940n_v4_setup(void) -+{ -+ tl_wr940n_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr940n_v4_leds_gpio), -+ tl_wr940n_v4_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WR940N_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr940n_v4_gpio_keys), -+ tl_wr940n_v4_gpio_keys); -+} -+ -+static void __init tl_wr940n_v6_setup(void) -+{ -+ tl_wr940n_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr940n_v6_leds_gpio), -+ tl_wr940n_v6_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WR940N_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr940n_v4_gpio_keys), -+ tl_wr940n_v4_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR940N_V4, "TL-WR940N-v4", "TP-LINK TL-WR940N v4", -+ tl_wr940n_v4_setup); -+MIPS_MACHINE(ATH79_MACH_TL_WR940N_V6, "TL-WR940N-v6", "TP-LINK TL-WR940N v6", -+ tl_wr940n_v6_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr941nd-v6.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr941nd-v6.c -new file mode 100644 -index 0000000000..8c788e2841 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr941nd-v6.c -@@ -0,0 +1,149 @@ -+/* -+ * TP-LINK TL-WR941N/ND v6 board support -+ * -+ * Copyright (C) 2015 Matthias Schiffer -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+ -+#define TL_WR941ND_V6_GPIO_LED_QSS 3 -+#define TL_WR941ND_V6_GPIO_LED_WAN 14 -+#define TL_WR941ND_V6_GPIO_LED_WAN_RED 15 -+#define TL_WR941ND_V6_GPIO_LED_LAN1 7 -+#define TL_WR941ND_V6_GPIO_LED_LAN2 6 -+#define TL_WR941ND_V6_GPIO_LED_LAN3 5 -+#define TL_WR941ND_V6_GPIO_LED_LAN4 4 -+#define TL_WR941ND_V6_GPIO_LED_WLAN 8 -+#define TL_WR941ND_V6_GPIO_LED_SYSTEM 18 -+ -+#define TL_WR941ND_V6_GPIO_BTN_RESET 1 -+#define TL_WR941ND_V6_GPIO_BTN_RFKILL 2 -+ -+#define TL_WR941ND_V6_KEYS_POLL_INTERVAL 20 -+#define TL_WR941ND_V6_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR941ND_V6_KEYS_POLL_INTERVAL) -+ -+ -+static struct gpio_led tl_wr941nd_v6_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:blue:qss", -+ .gpio = TL_WR941ND_V6_GPIO_LED_QSS, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:blue:wan", -+ .gpio = TL_WR941ND_V6_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:red:wan", -+ .gpio = TL_WR941ND_V6_GPIO_LED_WAN_RED, -+ .active_low = 0, -+ }, -+ { -+ .name = "tp-link:blue:lan1", -+ .gpio = TL_WR941ND_V6_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:blue:lan2", -+ .gpio = TL_WR941ND_V6_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:blue:lan3", -+ .gpio = TL_WR941ND_V6_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:blue:lan4", -+ .gpio = TL_WR941ND_V6_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:blue:wlan", -+ .gpio = TL_WR941ND_V6_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "tp-link:blue:system", -+ .gpio = TL_WR941ND_V6_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr941nd_v6_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR941ND_V6_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR941ND_V6_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "RFKILL button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = TL_WR941ND_V6_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR941ND_V6_GPIO_BTN_RFKILL, -+ .active_low = 1, -+ } -+}; -+ -+ -+static const char *tl_wr941n_v6_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wr941n_v6_flash_data = { -+ .part_probes = tl_wr941n_v6_part_probes, -+}; -+ -+ -+static void __init tl_wr941nd_v6_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_m25p80(&tl_wr941n_v6_flash_data); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr941nd_v6_leds_gpio), -+ tl_wr941nd_v6_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WR941ND_V6_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr941nd_v6_gpio_keys), -+ tl_wr941nd_v6_gpio_keys); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(ee, mac); -+ -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR941ND_V6, "TL-WR941ND-v6", "TP-LINK TL-WR941N/ND v6", -+ tl_wr941nd_v6_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr941nd.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr941nd.c -new file mode 100644 -index 0000000000..1ddeec730e ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr941nd.c -@@ -0,0 +1,121 @@ -+/* -+ * TP-LINK TL-WR941ND board support -+ * -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+ -+#include "dev-dsa.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TL_WR941ND_GPIO_LED_SYSTEM 2 -+#define TL_WR941ND_GPIO_LED_QSS_RED 4 -+#define TL_WR941ND_GPIO_LED_QSS_GREEN 5 -+#define TL_WR941ND_GPIO_LED_WLAN 9 -+ -+#define TL_WR941ND_GPIO_BTN_RESET 3 -+#define TL_WR941ND_GPIO_BTN_QSS 7 -+ -+#define TL_WR941ND_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TL_WR941ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR941ND_KEYS_POLL_INTERVAL) -+ -+static const char *tl_wr941nd_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data tl_wr941nd_flash_data = { -+ .part_probes = tl_wr941nd_part_probes, -+}; -+ -+static struct gpio_led tl_wr941nd_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:system", -+ .gpio = TL_WR941ND_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:red:qss", -+ .gpio = TL_WR941ND_GPIO_LED_QSS_RED, -+ }, { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WR941ND_GPIO_LED_QSS_GREEN, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WR941ND_GPIO_LED_WLAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button tl_wr941nd_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR941ND_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR941ND_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "qss", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = TL_WR941ND_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR941ND_GPIO_BTN_QSS, -+ .active_low = 1, -+ } -+}; -+ -+static struct dsa_chip_data tl_wr941nd_dsa_chip = { -+ .port_names[0] = "wan", -+ .port_names[1] = "lan1", -+ .port_names[2] = "lan2", -+ .port_names[3] = "lan3", -+ .port_names[4] = "lan4", -+ .port_names[5] = "cpu", -+}; -+ -+static struct dsa_platform_data tl_wr941nd_dsa_data = { -+ .nr_chips = 1, -+ .chip = &tl_wr941nd_dsa_chip, -+}; -+ -+static void __init tl_wr941nd_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(0); -+ ath79_register_dsa(&ath79_eth0_device.dev, &ath79_mdio0_device.dev, -+ &tl_wr941nd_dsa_data); -+ -+ ath79_register_m25p80(&tl_wr941nd_flash_data); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr941nd_leds_gpio), -+ tl_wr941nd_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WR941ND_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr941nd_gpio_keys), -+ tl_wr941nd_gpio_keys); -+ ath79_register_wmac(eeprom, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR941ND, "TL-WR941ND", "TP-LINK TL-WR941ND", -+ tl_wr941nd_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr942n-v1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr942n-v1.c -new file mode 100644 -index 0000000000..32e2bc9521 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr942n-v1.c -@@ -0,0 +1,279 @@ -+/* -+ * TP-Link TL-WR942N(RU) v1 board support -+ * -+ * Copyright (C) 2017 Sergey Studzinski -+ * Thanks to Henryk Heisig -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "nvram.h" -+ -+#define TL_WR942N_V1_KEYS_POLL_INTERVAL 20 -+#define TL_WR942N_V1_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * TL_WR942N_V1_KEYS_POLL_INTERVAL) -+ -+#define TL_WR942N_V1_GPIO_BTN_RESET 1 -+#define TL_WR942N_V1_GPIO_BTN_RFKILL 2 -+ -+#define TL_WR942N_V1_GPIO_UART_TX 4 -+#define TL_WR942N_V1_GPIO_UART_RX 5 -+ -+#define TL_WR942N_V1_GPIO_LED_USB2 14 -+#define TL_WR942N_V1_GPIO_LED_USB1 15 -+ -+#define TL_WR942N_V1_GPIO_SHIFT_OE 16 -+#define TL_WR942N_V1_GPIO_SHIFT_SER 17 -+#define TL_WR942N_V1_GPIO_SHIFT_SRCLK 18 -+#define TL_WR942N_V1_GPIO_SHIFT_SRCLR 19 -+#define TL_WR942N_V1_GPIO_SHIFT_RCLK 20 -+#define TL_WR942N_V1_GPIO_LED_WPS 21 -+#define TL_WR942N_V1_GPIO_LED_STATUS 22 -+ -+#define TL_WR942N_V1_74HC_GPIO_BASE 32 -+#define TL_WR942N_V1_74HC_GPIO_LED_LAN4 (TL_WR942N_V1_74HC_GPIO_BASE + 0) -+#define TL_WR942N_V1_74HC_GPIO_LED_LAN3 (TL_WR942N_V1_74HC_GPIO_BASE + 1) -+#define TL_WR942N_V1_74HC_GPIO_LED_LAN2 (TL_WR942N_V1_74HC_GPIO_BASE + 2) -+#define TL_WR942N_V1_74HC_GPIO_LED_LAN1 (TL_WR942N_V1_74HC_GPIO_BASE + 3) -+#define TL_WR942N_V1_74HC_GPIO_LED_WAN_GREEN (TL_WR942N_V1_74HC_GPIO_BASE + 4) -+#define TL_WR942N_V1_74HC_GPIO_LED_WAN_AMBER (TL_WR942N_V1_74HC_GPIO_BASE + 5) -+#define TL_WR942N_V1_74HC_GPIO_LED_WLAN (TL_WR942N_V1_74HC_GPIO_BASE + 6) -+#define TL_WR942N_V1_74HC_GPIO_HUB_RESET (TL_WR942N_V1_74HC_GPIO_BASE + 7) /* from u-boot sources */ -+ -+#define TL_WR942N_V1_SSR_BIT_0 0 -+#define TL_WR942N_V1_SSR_BIT_1 1 -+#define TL_WR942N_V1_SSR_BIT_2 2 -+#define TL_WR942N_V1_SSR_BIT_3 3 -+#define TL_WR942N_V1_SSR_BIT_4 4 -+#define TL_WR942N_V1_SSR_BIT_5 5 -+#define TL_WR942N_V1_SSR_BIT_6 6 -+#define TL_WR942N_V1_SSR_BIT_7 7 -+ -+#define TL_WR942N_V1_WMAC_CALDATA_OFFSET 0x1000 -+#define TL_WR942N_V1_DEFAULT_MAC_ADDR 0x1fe40008 -+#define TL_WR942N_V1_DEFAULT_MAC_SIZE 0x200 -+ -+#define GPIO_IN_ENABLE0_UART_SIN_LSB 8 -+#define GPIO_IN_ENABLE0_UART_SIN_MASK 0x0000ff00 -+ -+static struct gpio_led tl_wr942n_v1_leds_gpio[] __initdata = { -+ { -+ .name = "tl-wr942n-v1:green:status", -+ .gpio = TL_WR942N_V1_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr942n-v1:green:wlan", -+ .gpio = TL_WR942N_V1_74HC_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr942n-v1:green:lan1", -+ .gpio = TL_WR942N_V1_74HC_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr942n-v1:green:lan2", -+ .gpio = TL_WR942N_V1_74HC_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr942n-v1:green:lan3", -+ .gpio = TL_WR942N_V1_74HC_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr942n-v1:green:lan4", -+ .gpio = TL_WR942N_V1_74HC_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr942n-v1:green:wan", -+ .gpio = TL_WR942N_V1_74HC_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr942n-v1:amber:wan", -+ .gpio = TL_WR942N_V1_74HC_GPIO_LED_WAN_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr942n-v1:green:wps", -+ .gpio = TL_WR942N_V1_GPIO_LED_WPS, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr942n-v1:green:usb1", -+ .gpio = TL_WR942N_V1_GPIO_LED_USB1, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr942n-v1:green:usb2", -+ .gpio = TL_WR942N_V1_GPIO_LED_USB2, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button tl_wr942n_v1_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TL_WR942N_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR942N_V1_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "RFKILL button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = TL_WR942N_V1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TL_WR942N_V1_GPIO_BTN_RFKILL, -+ .active_low = 1, -+ }, -+}; -+ -+static struct spi_gpio_platform_data tl_wr942n_v1_spi_data = { -+ .sck = TL_WR942N_V1_GPIO_SHIFT_SRCLK, -+ .miso = SPI_GPIO_NO_MISO, -+ .mosi = TL_WR942N_V1_GPIO_SHIFT_SER, -+ .num_chipselect = 1, -+}; -+ -+static u8 tl_wr942n_v1_ssr_initdata[] = { -+ BIT(TL_WR942N_V1_SSR_BIT_7) | -+ BIT(TL_WR942N_V1_SSR_BIT_6) | -+ BIT(TL_WR942N_V1_SSR_BIT_5) | -+ BIT(TL_WR942N_V1_SSR_BIT_4) | -+ BIT(TL_WR942N_V1_SSR_BIT_3) | -+ BIT(TL_WR942N_V1_SSR_BIT_2) | -+ BIT(TL_WR942N_V1_SSR_BIT_1) | -+ BIT(TL_WR942N_V1_SSR_BIT_0) -+}; -+ -+static struct gen_74x164_chip_platform_data tl_wr942n_v1_ssr_data = { -+ .base = TL_WR942N_V1_74HC_GPIO_BASE, -+ .num_registers = ARRAY_SIZE(tl_wr942n_v1_ssr_initdata), -+ .init_data = tl_wr942n_v1_ssr_initdata, -+}; -+ -+static struct platform_device tl_wr942n_v1_spi_device = { -+ .name = "spi_gpio", -+ .id = 1, -+ .dev = { -+ .platform_data = &tl_wr942n_v1_spi_data, -+ }, -+}; -+ -+static struct spi_board_info tl_wr942n_v1_spi_info[] = { -+ { -+ .bus_num = 1, -+ .chip_select = 0, -+ .max_speed_hz = 10000000, -+ .modalias = "74x164", -+ .platform_data = &tl_wr942n_v1_ssr_data, -+ .controller_data = (void *) TL_WR942N_V1_GPIO_SHIFT_RCLK, -+ }, -+}; -+ -+static void tl_wr942n_v1_get_mac(const char *name, char *mac) -+{ -+ u8 *nvram = (u8 *) KSEG1ADDR(TL_WR942N_V1_DEFAULT_MAC_ADDR); -+ int err; -+ -+ err = ath79_nvram_parse_mac_addr(nvram, TL_WR942N_V1_DEFAULT_MAC_SIZE, -+ name, mac); -+ -+ if (err) -+ pr_err("no MAC address found for %s\n", name); -+} -+ -+static void __init tl_wr942n_v1_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 tmpmac[ETH_ALEN]; -+ void __iomem *base; -+ u32 t; -+ -+ ath79_register_m25p80(NULL); -+ -+ spi_register_board_info(tl_wr942n_v1_spi_info, -+ ARRAY_SIZE(tl_wr942n_v1_spi_info)); -+ platform_device_register(&tl_wr942n_v1_spi_device); -+ -+ /* Check inherited UART RX GPIO definition */ -+ base = ioremap(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); -+ -+ t = __raw_readl(base + QCA956X_GPIO_REG_IN_ENABLE0); -+ if (((t & GPIO_IN_ENABLE0_UART_SIN_MASK) -+ >> GPIO_IN_ENABLE0_UART_SIN_LSB) == TL_WR942N_V1_GPIO_LED_USB1) { -+ pr_warn("Active UART detected on USBLED's GPIOs!\n"); -+ -+ tl_wr942n_v1_leds_gpio[9].gpio = TL_WR942N_V1_GPIO_UART_TX; -+ tl_wr942n_v1_leds_gpio[10].gpio = TL_WR942N_V1_GPIO_UART_RX; -+ } -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr942n_v1_leds_gpio), -+ tl_wr942n_v1_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, TL_WR942N_V1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr942n_v1_gpio_keys), -+ tl_wr942n_v1_gpio_keys); -+ -+ tl_wr942n_v1_get_mac("MAC:", tmpmac); -+ -+ /* swap PHYs */ -+ ath79_setup_qca956x_eth_cfg(QCA956X_ETH_CFG_SW_PHY_SWAP | -+ QCA956X_ETH_CFG_SW_PHY_ADDR_SWAP); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_mdio(1, 0x0); -+ -+ /* WAN port */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, tmpmac, 1); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ -+ /* swaped PHYs */ -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_register_eth(0); -+ -+ /* LAN ports */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_init_mac(ath79_eth1_data.mac_addr, tmpmac, 0); -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ /* swaped PHYs */ -+ ath79_switch_data.phy_poll_mask |= BIT(0); -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(art + TL_WR942N_V1_WMAC_CALDATA_OFFSET, tmpmac); -+ -+ ath79_register_usb(); -+ -+ gpio_request_one(TL_WR942N_V1_74HC_GPIO_HUB_RESET, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ -+ gpio_request_one(TL_WR942N_V1_GPIO_SHIFT_OE, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "LED control"); -+ -+ gpio_request_one(TL_WR942N_V1_GPIO_SHIFT_SRCLR, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "LED reset"); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR942N_V1, "TL-WR942N-V1", "TP-LINK TL-WR942N v1", -+ tl_wr942n_v1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ts-d084.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ts-d084.c -new file mode 100644 -index 0000000000..38786fdeda ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ts-d084.c -@@ -0,0 +1,86 @@ -+/* -+ * PISEN TS-D084 board support -+ * Based on TP-LINK TL-WR703N/TL-MR10U board support -+ * -+ * Copyright (C) 2011 dongyuqi <729650915@qq.com> -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TS_D084_GPIO_LED_SYSTEM 0 -+#define TS_D084_GPIO_BTN_RESET 12 -+ -+ -+#define TS_D084_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TS_D084_KEYS_DEBOUNCE_INTERVAL (3 * TS_D084_KEYS_POLL_INTERVAL) -+ -+static const char *ts_d084_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data ts_d084_flash_data = { -+ .part_probes = ts_d084_part_probes, -+}; -+ -+static struct gpio_led ts_d084_leds_gpio[] __initdata = { -+ { -+ .name = "ts-d084:blue:system", -+ .gpio = TS_D084_GPIO_LED_SYSTEM, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button ts_d084_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TS_D084_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TS_D084_GPIO_BTN_RESET, -+ .active_low = 0, -+ } -+}; -+ -+static void __init ts_d084_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* disable PHY_SWAP and PHY_ADDR_SWAP bits */ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_m25p80(&ts_d084_flash_data); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ts_d084_leds_gpio), -+ ts_d084_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, TS_D084_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ts_d084_gpio_keys), -+ ts_d084_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TS_D084, "TS-D084", "PISEN TS-D084", -+ ts_d084_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tube2h.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tube2h.c -new file mode 100644 -index 0000000000..06b3616536 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tube2h.c -@@ -0,0 +1,129 @@ -+/* -+ * ALFA NETWORK Tube2H board support -+ * -+ * Copyright (C) 2014 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define TUBE2H_GPIO_LED_SIGNAL4 0 -+#define TUBE2H_GPIO_LED_SIGNAL3 1 -+#define TUBE2H_GPIO_LED_SIGNAL2 13 -+#define TUBE2H_GPIO_LED_LAN 17 -+#define TUBE2H_GPIO_LED_SIGNAL1 27 -+#define TUBE2H_GPIO_EXT_LNA 28 -+ -+#define TUBE2H_GPIO_WDT_EN 22 -+#define TUBE2H_GPIO_WDT_IN 18 -+ -+#define TUBE2H_GPIO_BTN_RESET 12 -+ -+#define TUBE2H_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define TUBE2H_KEYS_DEBOUNCE_INTERVAL (3 * TUBE2H_KEYS_POLL_INTERVAL) -+ -+#define TUBE2H_ART_ADDRESS 0x1fff0000 -+#define TUBE2H_LAN_MAC_OFFSET 0x06 -+#define TUBE2H_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led tube2h_leds_gpio[] __initdata = { -+ { -+ .name = "alfa:blue:lan", -+ .gpio = TUBE2H_GPIO_LED_LAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "alfa:red:signal1", -+ .gpio = TUBE2H_GPIO_LED_SIGNAL1, -+ .active_low = 1, -+ }, -+ { -+ .name = "alfa:orange:signal2", -+ .gpio = TUBE2H_GPIO_LED_SIGNAL2, -+ .active_low = 0, -+ }, -+ { -+ .name = "alfa:green:signal3", -+ .gpio = TUBE2H_GPIO_LED_SIGNAL3, -+ .active_low = 0, -+ }, -+ { -+ .name = "alfa:green:signal4", -+ .gpio = TUBE2H_GPIO_LED_SIGNAL4, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button tube2h_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = TUBE2H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = TUBE2H_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init tube2h_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(TUBE2H_ART_ADDRESS); -+ u32 t; -+ -+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_JTAG_DISABLE | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ /* Ensure that GPIO26 and GPIO27 are controllable by software */ -+ t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); -+ t |= AR933X_BOOTSTRAP_MDIO_GPIO_EN; -+ ath79_reset_wr(AR933X_RESET_REG_BOOTSTRAP, t); -+ -+ gpio_request_one(TUBE2H_GPIO_EXT_LNA, -+ GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "external LNA0"); -+ -+ gpio_request_one(TUBE2H_GPIO_WDT_IN, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "WDT input"); -+ -+ gpio_request_one(TUBE2H_GPIO_WDT_EN, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED, -+ "WDT enable"); -+ -+ ath79_register_wmac(art + TUBE2H_CALDATA_OFFSET, NULL); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tube2h_leds_gpio), -+ tube2h_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, TUBE2H_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tube2h_gpio_keys), -+ tube2h_gpio_keys); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ art + TUBE2H_LAN_MAC_OFFSET, 0); -+ ath79_register_mdio(0, 0x0); -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TUBE2H, "TUBE2H", "ALFA NETWORK Tube2H", -+ tube2h_setup); -+ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ubnt-unifiac.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ubnt-unifiac.c -new file mode 100644 -index 0000000000..09a0bba867 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ubnt-unifiac.c -@@ -0,0 +1,179 @@ -+/* -+ * Ubiquiti UniFi AC (LITE) board support -+ * -+ * Copyright (C) 2015-2016 P. Wassi -+ * -+ * Derived from: mach-ubnt-xm.c -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+ -+ -+#define UNIFIAC_KEYS_POLL_INTERVAL 20 -+#define UNIFIAC_KEYS_DEBOUNCE_INTERVAL (3 * UNIFIAC_KEYS_POLL_INTERVAL) -+ -+#define UNIFIAC_GPIO_LED_WHITE 7 -+#define UNIFIAC_GPIO_LED_BLUE 8 -+ -+#define UNIFIAC_GPIO_BTN_RESET 2 -+ -+#define UNIFIAC_MAC0_OFFSET 0x0000 -+#define UNIFIAC_WMAC_CALDATA_OFFSET 0x1000 -+#define UNIFIAC_PCI_CALDATA_OFFSET 0x5000 -+ -+ -+static struct flash_platform_data ubnt_unifiac_flash_data = { -+ /* mx25l12805d and mx25l12835f have the same JEDEC ID */ -+ .type = "mx25l12805d", -+}; -+ -+static struct gpio_led ubnt_unifiac_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:white:dome", -+ .gpio = UNIFIAC_GPIO_LED_WHITE, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:blue:dome", -+ .gpio = UNIFIAC_GPIO_LED_BLUE, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button ubnt_unifiac_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = UNIFIAC_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = UNIFIAC_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init ubnt_unifiac_lite_setup(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(&ubnt_unifiac_flash_data); -+ -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ eeprom + UNIFIAC_MAC0_OFFSET, 0); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_pll_data.pll_10 = 0x00001313; -+ -+ ath79_register_mdio(0, ~BIT(4)); -+ ath79_register_eth(0); -+ -+ -+ ath79_register_wmac(eeprom + UNIFIAC_WMAC_CALDATA_OFFSET, NULL); -+ -+ -+ ap91_pci_init(eeprom + UNIFIAC_PCI_CALDATA_OFFSET, NULL); -+ -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_unifiac_leds_gpio), -+ ubnt_unifiac_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, UNIFIAC_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_unifiac_gpio_keys), -+ ubnt_unifiac_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_UNIFIAC_LITE, "UBNT-UF-AC-LITE", -+ "Ubiquiti UniFi-AC-LITE/MESH", ubnt_unifiac_lite_setup); -+ -+static struct ar8327_pad_cfg ubnt_unifiac_pro_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+static struct ar8327_platform_data ubnt_unifiac_pro_ar8327_data = { -+ .pad0_cfg = &ubnt_unifiac_pro_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+ -+static struct mdio_board_info ubnt_unifiac_pro_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &ubnt_unifiac_pro_ar8327_data, -+ }, -+}; -+ -+static void __init ubnt_unifiac_pro_setup(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(&ubnt_unifiac_flash_data); -+ -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ eeprom + UNIFIAC_MAC0_OFFSET, 0); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_data.phy_mask = BIT(0); -+ -+ mdiobus_register_board_info(ubnt_unifiac_pro_mdio0_info, -+ ARRAY_SIZE(ubnt_unifiac_pro_mdio0_info)); -+ -+ ath79_register_mdio(0, 0x00); -+ ath79_register_eth(0); -+ -+ -+ ath79_register_usb(); -+ -+ -+ ath79_register_wmac(eeprom + UNIFIAC_WMAC_CALDATA_OFFSET, NULL); -+ -+ -+ ap91_pci_init(eeprom + UNIFIAC_PCI_CALDATA_OFFSET, NULL); -+ -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_unifiac_leds_gpio), -+ ubnt_unifiac_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, UNIFIAC_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_unifiac_gpio_keys), -+ ubnt_unifiac_gpio_keys); -+} -+ -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_UNIFIAC_PRO, "UBNT-UF-AC-PRO", -+ "Ubiquiti UniFi-AC-PRO/MESH-PRO", ubnt_unifiac_pro_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ubnt-xm.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ubnt-xm.c -new file mode 100644 -index 0000000000..6ceb91efff ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ubnt-xm.c -@@ -0,0 +1,781 @@ -+/* -+ * Ubiquiti Networks XM (rev 1.0) board support -+ * -+ * Copyright (C) 2011 René Bolldorf -+ * -+ * Derived from: mach-pb44.c -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define UBNT_XM_GPIO_LED_L1 0 -+#define UBNT_XM_GPIO_LED_L2 1 -+#define UBNT_XM_GPIO_LED_L3 11 -+#define UBNT_XM_GPIO_LED_L4 7 -+ -+#define UBNT_XM_GPIO_BTN_RESET 12 -+ -+#define UBNT_XM_KEYS_POLL_INTERVAL 20 -+#define UBNT_XM_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_XM_KEYS_POLL_INTERVAL) -+ -+#define UBNT_XM_EEPROM_ADDR 0x1fff1000 -+ -+static struct gpio_led ubnt_xm_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:red:link1", -+ .gpio = UBNT_XM_GPIO_LED_L1, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:orange:link2", -+ .gpio = UBNT_XM_GPIO_LED_L2, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:link3", -+ .gpio = UBNT_XM_GPIO_LED_L3, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:link4", -+ .gpio = UBNT_XM_GPIO_LED_L4, -+ .active_low = 0, -+ }, -+}; -+ -+static struct gpio_keys_button ubnt_xm_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = UBNT_XM_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = UBNT_XM_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+#define UBNT_M_WAN_PHYMASK BIT(4) -+ -+static void __init ubnt_xm_init(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(UBNT_XM_EEPROM_ADDR); -+ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac2 = (u8 *) KSEG1ADDR(0x1fff0000 + ETH_ALEN); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_xm_leds_gpio), -+ ubnt_xm_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_xm_gpio_keys), -+ ubnt_xm_gpio_keys); -+ -+ ath79_register_m25p80(NULL); -+ ap91_pci_init(eeprom, NULL); -+ -+ ath79_register_mdio(0, ~UBNT_M_WAN_PHYMASK); -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); -+ ath79_eth1_data.speed = SPEED_100; -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 0); -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_XM, -+ "UBNT-XM", -+ "Ubiquiti Networks XM (rev 1.0) board", -+ ubnt_xm_init); -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_BULLET_M, "UBNT-BM", "Ubiquiti Bullet M", -+ ubnt_xm_init); -+ -+static void __init ubnt_rocket_m_setup(void) -+{ -+ ubnt_xm_init(); -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_ROCKET_M, "UBNT-RM", "Ubiquiti Rocket M", -+ ubnt_rocket_m_setup); -+ -+static void __init ubnt_nano_m_setup(void) -+{ -+ ubnt_xm_init(); -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_NANO_M, "UBNT-NM", "Ubiquiti Nanostation M", -+ ubnt_nano_m_setup); -+ -+static struct gpio_led ubnt_airrouter_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:green:globe", -+ .gpio = 0, -+ .active_low = 1, -+ }, { -+ .name = "ubnt:green:power", -+ .gpio = 11, -+ .active_low = 1, -+ .default_state = LEDS_GPIO_DEFSTATE_ON, -+ } -+}; -+ -+static void __init ubnt_airrouter_setup(void) -+{ -+ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_mdio(0, ~UBNT_M_WAN_PHYMASK); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); -+ ath79_init_local_mac(ath79_eth1_data.mac_addr, mac1); -+ -+ ath79_register_eth(1); -+ ath79_register_eth(0); -+ ath79_register_usb(); -+ -+ ap91_pci_init(ee, NULL); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_airrouter_leds_gpio), -+ ubnt_airrouter_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_xm_gpio_keys), -+ ubnt_xm_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_AIRROUTER, "UBNT-AR", "Ubiquiti AirRouter", -+ ubnt_airrouter_setup); -+ -+static struct gpio_led ubnt_unifi_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:orange:dome", -+ .gpio = 1, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:dome", -+ .gpio = 0, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_led ubnt_unifi_outdoor_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:orange:front", -+ .gpio = 1, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:front", -+ .gpio = 0, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_led ubnt_unifi_outdoor_plus_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:white:front", -+ .gpio = 1, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:blue:front", -+ .gpio = 0, -+ .active_low = 0, -+ } -+}; -+ -+ -+static void __init ubnt_unifi_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_mdio(0, ~UBNT_M_WAN_PHYMASK); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_register_eth(0); -+ -+ ap91_pci_init(ee, NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_unifi_leds_gpio), -+ ubnt_unifi_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_xm_gpio_keys), -+ ubnt_xm_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_UNIFI, "UBNT-UF", "Ubiquiti UniFi", -+ ubnt_unifi_setup); -+ -+ -+#define UBNT_UNIFIOD_PRI_PHYMASK BIT(4) -+#define UBNT_UNIFIOD_2ND_PHYMASK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) -+ -+static void __init ubnt_unifi_outdoor_setup(void) -+{ -+ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac2 = (u8 *) KSEG1ADDR(0x1fff0000 + ETH_ALEN); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_mdio(0, ~(UBNT_UNIFIOD_PRI_PHYMASK | -+ UBNT_UNIFIOD_2ND_PHYMASK)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 0); -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ap91_pci_init(ee, NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_unifi_outdoor_leds_gpio), -+ ubnt_unifi_outdoor_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_xm_gpio_keys), -+ ubnt_xm_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_UNIFI_OUTDOOR, "UBNT-U20", -+ "Ubiquiti UniFiAP Outdoor", -+ ubnt_unifi_outdoor_setup); -+ -+ -+static void __init ubnt_unifi_outdoor_plus_setup(void) -+{ -+ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac2 = (u8 *) KSEG1ADDR(0x1fff0000 + ETH_ALEN); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_mdio(0, ~(UBNT_UNIFIOD_PRI_PHYMASK | -+ UBNT_UNIFIOD_2ND_PHYMASK)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 0); -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ap9x_pci_get_wmac_data(0)->ubnt_hsr = true; -+ ap91_pci_init(ee, NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_unifi_outdoor_plus_leds_gpio), -+ ubnt_unifi_outdoor_plus_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_xm_gpio_keys), -+ ubnt_xm_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_UNIFI_OUTDOOR_PLUS, "UBNT-UOP", -+ "Ubiquiti UniFiAP Outdoor+", -+ ubnt_unifi_outdoor_plus_setup); -+ -+ -+static struct gpio_led ubnt_uap_pro_gpio_leds[] __initdata = { -+ { -+ .name = "ubnt:white:dome", -+ .gpio = 12, -+ }, { -+ .name = "ubnt:blue:dome", -+ .gpio = 13, -+ } -+}; -+ -+static struct gpio_keys_button uap_pro_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = UBNT_XM_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 17, -+ .active_low = 1, -+ } -+}; -+ -+static struct ar8327_pad_cfg uap_pro_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_platform_data uap_pro_ar8327_data = { -+ .pad0_cfg = &uap_pro_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info uap_pro_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &uap_pro_ar8327_data, -+ }, -+}; -+ -+#define UAP_PRO_MAC0_OFFSET 0x0000 -+#define UAP_PRO_MAC1_OFFSET 0x0006 -+#define UAP_PRO_WMAC_CALDATA_OFFSET 0x1000 -+#define UAP_PRO_PCI_CALDATA_OFFSET 0x5000 -+ -+static void __init ubnt_uap_pro_setup(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_uap_pro_gpio_leds), -+ ubnt_uap_pro_gpio_leds); -+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(uap_pro_gpio_keys), -+ uap_pro_gpio_keys); -+ -+ ath79_register_wmac(eeprom + UAP_PRO_WMAC_CALDATA_OFFSET, NULL); -+ ap91_pci_init(eeprom + UAP_PRO_PCI_CALDATA_OFFSET, NULL); -+ -+ ath79_register_mdio(0, 0x0); -+ mdiobus_register_board_info(uap_pro_mdio0_info, -+ ARRAY_SIZE(uap_pro_mdio0_info)); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0); -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ eeprom + UAP_PRO_MAC0_OFFSET, 0); -+ -+ /* GMAC0 is connected to an AR8327 switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_UAP_PRO, "UAP-PRO", "Ubiquiti UniFi AP Pro", -+ ubnt_uap_pro_setup); -+ -+#define UBNT_XW_GPIO_LED_L1 11 -+#define UBNT_XW_GPIO_LED_L2 16 -+#define UBNT_XW_GPIO_LED_L3 13 -+#define UBNT_XW_GPIO_LED_L4 14 -+ -+static struct gpio_led ubnt_xw_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:red:link1", -+ .gpio = UBNT_XW_GPIO_LED_L1, -+ .active_low = 1, -+ }, { -+ .name = "ubnt:orange:link2", -+ .gpio = UBNT_XW_GPIO_LED_L2, -+ .active_low = 1, -+ }, { -+ .name = "ubnt:green:link3", -+ .gpio = UBNT_XW_GPIO_LED_L3, -+ .active_low = 1, -+ }, { -+ .name = "ubnt:green:link4", -+ .gpio = UBNT_XW_GPIO_LED_L4, -+ .active_low = 1, -+ }, -+}; -+ -+#define UBNT_ROCKET_TI_GPIO_LED_L1 16 -+#define UBNT_ROCKET_TI_GPIO_LED_L2 17 -+#define UBNT_ROCKET_TI_GPIO_LED_L3 18 -+#define UBNT_ROCKET_TI_GPIO_LED_L4 19 -+#define UBNT_ROCKET_TI_GPIO_LED_L5 20 -+#define UBNT_ROCKET_TI_GPIO_LED_L6 21 -+static struct gpio_led ubnt_rocket_ti_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:green:link1", -+ .gpio = UBNT_ROCKET_TI_GPIO_LED_L1, -+ .active_low = 1, -+ }, { -+ .name = "ubnt:green:link2", -+ .gpio = UBNT_ROCKET_TI_GPIO_LED_L2, -+ .active_low = 1, -+ }, { -+ .name = "ubnt:green:link3", -+ .gpio = UBNT_ROCKET_TI_GPIO_LED_L3, -+ .active_low = 1, -+ }, { -+ .name = "ubnt:green:link4", -+ .gpio = UBNT_ROCKET_TI_GPIO_LED_L4, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:link5", -+ .gpio = UBNT_ROCKET_TI_GPIO_LED_L5, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:link6", -+ .gpio = UBNT_ROCKET_TI_GPIO_LED_L6, -+ .active_low = 0, -+ }, -+}; -+ -+static void __init ubnt_xw_init(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_xw_leds_gpio), -+ ubnt_xw_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_xm_gpio_keys), -+ ubnt_xm_gpio_keys); -+ -+ ath79_register_wmac(eeprom + UAP_PRO_WMAC_CALDATA_OFFSET, NULL); -+ ap91_pci_init(eeprom + UAP_PRO_PCI_CALDATA_OFFSET, NULL); -+ -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_MII_GMAC0 | AR934X_ETH_CFG_MII_GMAC0_SLAVE); -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ eeprom + UAP_PRO_MAC0_OFFSET, 0); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+} -+ -+static void __init ubnt_nano_m_xw_setup(void) -+{ -+ ubnt_xw_init(); -+ -+ /* GMAC0 is connected to an AR8326 switch */ -+ ath79_register_mdio(0, ~(BIT(0) | BIT(1) | BIT(5))); -+ ath79_eth0_data.phy_mask = (BIT(0) | BIT(1) | BIT(5)); -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_register_eth(0); -+} -+ -+static struct at803x_platform_data ubnt_loco_m_xw_at803x_data = { -+ .has_reset_gpio = 1, -+ .reset_gpio = 0, -+}; -+ -+static struct mdio_board_info ubnt_loco_m_xw_mdio_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 1, -+ .platform_data = &ubnt_loco_m_xw_at803x_data, -+ }, -+}; -+ -+static void __init ubnt_loco_m_xw_setup(void) -+{ -+ ubnt_xw_init(); -+ -+ mdiobus_register_board_info(ubnt_loco_m_xw_mdio_info, -+ ARRAY_SIZE(ubnt_loco_m_xw_mdio_info)); -+ -+ ath79_register_mdio(0, ~BIT(1)); -+ ath79_eth0_data.phy_mask = BIT(1); -+ ath79_register_eth(0); -+} -+ -+#define UBNT_LBE_M5_GPIO_LED_LAN 13 -+#define UBNT_LBE_M5_GPIO_LED_WLAN 14 -+#define UBNT_LBE_M5_GPIO_LED_SYS 16 -+ -+static struct gpio_led ubnt_lbe_m5_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:green:lan", -+ .gpio = UBNT_LBE_M5_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "ubnt:green:wlan", -+ .gpio = UBNT_LBE_M5_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "ubnt:green:sys", -+ .gpio = UBNT_LBE_M5_GPIO_LED_SYS, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init ubnt_lbe_m5_setup(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_wmac(eeprom + UAP_PRO_WMAC_CALDATA_OFFSET, NULL); -+ ap91_pci_init(eeprom + UAP_PRO_PCI_CALDATA_OFFSET, NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_lbe_m5_leds_gpio), -+ ubnt_lbe_m5_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_xm_gpio_keys), -+ ubnt_xm_gpio_keys); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_MII_GMAC0 | -+ AR934X_ETH_CFG_MII_GMAC0_SLAVE); -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ eeprom + UAP_PRO_MAC0_OFFSET, 0); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ gpio_request_one(0, GPIOF_OUT_INIT_LOW | GPIOF_ACTIVE_LOW | -+ GPIOF_EXPORT_DIR_FIXED, "SPI nWP"); -+ -+ mdiobus_register_board_info(ubnt_loco_m_xw_mdio_info, -+ ARRAY_SIZE(ubnt_loco_m_xw_mdio_info)); -+ -+ ath79_register_mdio(0, ~BIT(1)); -+ ath79_eth0_data.phy_mask = BIT(1); -+ ath79_register_eth(0); -+} -+ -+static void __init ubnt_rocket_m_xw_setup(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_xw_leds_gpio), -+ ubnt_xw_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_xm_gpio_keys), -+ ubnt_xm_gpio_keys); -+ -+ ath79_register_wmac(eeprom + UAP_PRO_WMAC_CALDATA_OFFSET, NULL); -+ ap91_pci_init(eeprom + UAP_PRO_PCI_CALDATA_OFFSET, NULL); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0); -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ eeprom + UAP_PRO_MAC0_OFFSET, 0); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ ath79_register_mdio(0, ~BIT(4)); -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_register_eth(0); -+} -+ -+static struct at803x_platform_data ubnt_rocket_m_ti_at803_data = { -+ .disable_smarteee = 1, -+ .enable_rgmii_rx_delay = 1, -+ .enable_rgmii_tx_delay = 1, -+}; -+static struct mdio_board_info ubnt_rocket_m_ti_mdio_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 4, -+ .platform_data = &ubnt_rocket_m_ti_at803_data, -+ }, -+}; -+ -+static void __init ubnt_rocket_m_ti_setup(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_rocket_ti_leds_gpio), -+ ubnt_rocket_ti_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_xm_gpio_keys), -+ ubnt_xm_gpio_keys); -+ -+ ap91_pci_init(eeprom + 0x1000, NULL); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0); -+ ath79_setup_ar934x_eth_rx_delay(3, 3); -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ eeprom + UAP_PRO_MAC0_OFFSET, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, -+ eeprom + UAP_PRO_MAC1_OFFSET, 0); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ -+ mdiobus_register_board_info(ubnt_rocket_m_ti_mdio_info, -+ ARRAY_SIZE(ubnt_rocket_m_ti_mdio_info)); -+ ath79_register_mdio(0, 0x0); -+ -+ -+ ath79_eth0_data.phy_mask = BIT(4); -+ /* read out from vendor */ -+ ath79_eth0_pll_data.pll_1000 = 0x2000000; -+ ath79_eth0_pll_data.pll_10 = 0x1313; -+ ath79_register_eth(0); -+ -+ ath79_register_mdio(1, 0x0); -+ ath79_eth1_data.phy_mask = BIT(3); -+ ath79_register_eth(1); -+} -+ -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_NANO_M_XW, "UBNT-NM-XW", "Ubiquiti Nanostation M XW", -+ ubnt_nano_m_xw_setup); -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_LBE_M5, "UBNT-LBE-M5", "Ubiquiti Litebeam M5", -+ ubnt_lbe_m5_setup); -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_LOCO_M_XW, "UBNT-LOCO-XW", "Ubiquiti Loco M XW", -+ ubnt_loco_m_xw_setup); -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_ROCKET_M_XW, "UBNT-RM-XW", "Ubiquiti Rocket M XW", -+ ubnt_rocket_m_xw_setup); -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_BULLET_M_XW, "UBNT-BM-XW", "Ubiquiti Bullet M XW", -+ ubnt_rocket_m_xw_setup); -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_ROCKET_M_TI, "UBNT-RM-TI", "Ubiquiti Rocket M TI", -+ ubnt_rocket_m_ti_setup); -+ -+static struct gpio_led ubnt_airgateway_gpio_leds[] __initdata = { -+ { -+ .name = "ubnt:blue:wlan", -+ .gpio = 0, -+ }, { -+ .name = "ubnt:white:status", -+ .gpio = 1, -+ }, -+}; -+ -+static struct gpio_keys_button airgateway_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = UBNT_XM_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 12, -+ .active_low = 1, -+ } -+}; -+ -+static void __init ubnt_airgateway_setup(void) -+{ -+ u32 t; -+ u8 *mac0 = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000 + ETH_ALEN); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ -+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); -+ t |= AR933X_BOOTSTRAP_MDIO_GPIO_EN; -+ ath79_reset_wr(AR933X_RESET_REG_BOOTSTRAP, t); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_airgateway_gpio_leds), -+ ubnt_airgateway_gpio_leds); -+ -+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(airgateway_gpio_keys), -+ airgateway_gpio_keys); -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac0, 0); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_register_eth(1); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(ee, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_AIRGW, "UBNT-AGW", "Ubiquiti AirGateway", -+ ubnt_airgateway_setup); -+ -+static struct gpio_led ubnt_airgateway_pro_gpio_leds[] __initdata = { -+ { -+ .name = "ubnt:blue:wlan", -+ .gpio = 13, -+ }, { -+ .name = "ubnt:white:status", -+ .gpio = 17, -+ }, -+}; -+ -+ -+static struct gpio_keys_button airgateway_pro_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = UBNT_XM_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 12, -+ .active_low = 1, -+ } -+}; -+ -+static void __init ubnt_airgateway_pro_setup(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac0 = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_airgateway_pro_gpio_leds), -+ ubnt_airgateway_pro_gpio_leds); -+ -+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(airgateway_pro_gpio_keys), -+ airgateway_pro_gpio_keys); -+ -+ ath79_register_wmac(eeprom + UAP_PRO_WMAC_CALDATA_OFFSET, NULL); -+ ap91_pci_init(eeprom + UAP_PRO_PCI_CALDATA_OFFSET, NULL); -+ -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ /* GMAC0 is left unused in this configuration */ -+ -+ /* GMAC1 is connected to MAC0 on the internal switch */ -+ /* The PoE/WAN port connects to port 5 on the internal switch */ -+ /* The LAN port connects to port 4 on the internal switch */ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac0, 0); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_register_eth(1); -+ -+} -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_AIRGWP, "UBNT-AGWP", "Ubiquiti AirGateway Pro", -+ ubnt_airgateway_pro_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ubnt.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ubnt.c -new file mode 100644 -index 0000000000..e49ac23fd1 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ubnt.c -@@ -0,0 +1,205 @@ -+/* -+ * Ubiquiti RouterStation support -+ * -+ * Copyright (C) 2008-2012 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * Copyright (C) 2008 Ubiquiti -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define UBNT_RS_GPIO_LED_RF 2 -+#define UBNT_RS_GPIO_SW4 8 -+ -+#define UBNT_LS_SR71_GPIO_LED_D25 0 -+#define UBNT_LS_SR71_GPIO_LED_D26 1 -+#define UBNT_LS_SR71_GPIO_LED_D24 2 -+#define UBNT_LS_SR71_GPIO_LED_D23 4 -+#define UBNT_LS_SR71_GPIO_LED_D22 5 -+#define UBNT_LS_SR71_GPIO_LED_D27 6 -+#define UBNT_LS_SR71_GPIO_LED_D28 7 -+ -+#define UBNT_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define UBNT_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led ubnt_rs_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:green:rf", -+ .gpio = UBNT_RS_GPIO_LED_RF, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_led ubnt_ls_sr71_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:green:d22", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D22, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:d23", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D23, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:d24", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D24, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:red:d25", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D25, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:red:d26", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D26, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:d27", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D27, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:d28", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D28, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button ubnt_gpio_keys[] __initdata = { -+ { -+ .desc = "sw4", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = UBNT_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = UBNT_RS_GPIO_SW4, -+ .active_low = 1, -+ } -+}; -+ -+static const char *ubnt_part_probes[] = { -+ "RedBoot", -+ NULL, -+}; -+ -+static struct flash_platform_data ubnt_flash_data = { -+ .part_probes = ubnt_part_probes, -+}; -+ -+static void __init ubnt_generic_setup(void) -+{ -+ ath79_register_m25p80(&ubnt_flash_data); -+ -+ ath79_register_gpio_keys_polled(-1, UBNT_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_gpio_keys), -+ ubnt_gpio_keys); -+ ath79_register_pci(); -+} -+ -+#define UBNT_RS_WAN_PHYMASK BIT(20) -+#define UBNT_RS_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19)) -+ -+static void __init ubnt_rs_setup(void) -+{ -+ ubnt_generic_setup(); -+ -+ ath79_register_mdio(0, ~(UBNT_RS_WAN_PHYMASK | UBNT_RS_LAN_PHYMASK)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = UBNT_RS_WAN_PHYMASK; -+ -+ /* -+ * There is Secondary MAC address duplicate problem with some -+ * UBNT HW batches. Do not increase Secondary MAC address by 1 -+ * but do workaround with 'Locally Administrated' bit. -+ */ -+ ath79_init_local_mac(ath79_eth1_data.mac_addr, ath79_mac_base); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth1_data.speed = SPEED_100; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_usb(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio), -+ ubnt_rs_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_RS, "UBNT-RS", "Ubiquiti RouterStation", -+ ubnt_rs_setup); -+ -+#define UBNT_RSPRO_WAN_PHYMASK BIT(4) -+#define UBNT_RSPRO_LAN_PHYMASK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) -+ -+static void __init ubnt_rspro_setup(void) -+{ -+ ubnt_generic_setup(); -+ -+ ath79_register_mdio(0, ~(UBNT_RSPRO_WAN_PHYMASK | -+ UBNT_RSPRO_LAN_PHYMASK)); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = UBNT_RSPRO_WAN_PHYMASK; -+ -+ /* -+ * There is Secondary MAC address duplicate problem with some -+ * UBNT HW batches. Do not increase Secondary MAC address by 1 -+ * but do workaround with 'Locally Administrated' bit. -+ */ -+ ath79_init_local_mac(ath79_eth1_data.mac_addr, ath79_mac_base); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth1_data.phy_mask = UBNT_RSPRO_LAN_PHYMASK; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_usb(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio), -+ ubnt_rs_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_RSPRO, "UBNT-RSPRO", "Ubiquiti RouterStation Pro", -+ ubnt_rspro_setup); -+ -+static void __init ubnt_lsx_setup(void) -+{ -+ ubnt_generic_setup(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_LSX, "UBNT-LSX", "Ubiquiti LSX", ubnt_lsx_setup); -+ -+#define UBNT_LSSR71_PHY_MASK BIT(1) -+ -+static void __init ubnt_lssr71_setup(void) -+{ -+ ubnt_generic_setup(); -+ -+ ath79_register_mdio(0, ~UBNT_LSSR71_PHY_MASK); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = UBNT_LSSR71_PHY_MASK; -+ -+ ath79_register_eth(0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_ls_sr71_leds_gpio), -+ ubnt_ls_sr71_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_UBNT_LSSR71, "UBNT-LS-SR71", "Ubiquiti LS-SR71", -+ ubnt_lssr71_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wam250.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wam250.c -new file mode 100644 -index 0000000000..31817bddf2 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wam250.c -@@ -0,0 +1,122 @@ -+/* -+ * Samsung WAM250 board support -+ * -+ * Copyright (C) 2018 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define WAM250_GPIO_LED_LAN 13 -+#define WAM250_GPIO_LED_POWER 15 -+#define WAM250_GPIO_LED_REPEATER 14 -+#define WAM250_GPIO_LED_WLAN 12 -+ -+#define WAM250_GPIO_BTN_RESET 17 -+#define WAM250_GPIO_BTN_SPKADD 1 -+ -+#define WAM250_GPIO_EXT_LNA 19 -+ -+#define WAM250_MAC_OFFSET 2 -+ -+#define WAM250_KEYS_POLL_INTERVAL 20 -+#define WAM250_KEYS_DEBOUNCE_INTERVAL (3 * WAM250_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led wam250_leds_gpio[] __initdata = { -+ { -+ .name = "wam250:white:lan", -+ .gpio = WAM250_GPIO_LED_LAN, -+ .active_low = 1, -+ }, { -+ .name = "wam250:white:power", -+ .gpio = WAM250_GPIO_LED_POWER, -+ .default_state = LEDS_GPIO_DEFSTATE_KEEP, -+ .active_low = 1, -+ }, { -+ .name = "wam250:white:repeater", -+ .gpio = WAM250_GPIO_LED_REPEATER, -+ .active_low = 1, -+ }, { -+ .name = "wam250:white:wlan", -+ .gpio = WAM250_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button wam250_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WAM250_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WAM250_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WAM250_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WAM250_GPIO_BTN_SPKADD, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init wam250_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_PHY_SWAP); -+ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = 0xfd; -+ -+ /* LAN */ -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.phy_mask = BIT(1); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + WAM250_MAC_OFFSET, 0); -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + WAM250_MAC_OFFSET, 1); -+ ath79_register_eth(0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wam250_leds_gpio), -+ wam250_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, WAM250_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wam250_gpio_keys), -+ wam250_gpio_keys); -+ -+ ath79_wmac_set_ext_lna_gpio(0, WAM250_GPIO_EXT_LNA); -+ -+ ath79_register_usb(); -+ ath79_register_wmac(art, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WAM250, "WAM250", "Samsung WAM250", wam250_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-weio.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-weio.c -new file mode 100644 -index 0000000000..3973ada7c3 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-weio.c -@@ -0,0 +1,140 @@ -+/** -+ * WEIO Web Of Things Platform -+ * -+ * Copyright (C) 2013 Drasko DRASKOVIC and Uros PETREVSKI -+ * -+ * ## ## ######## #### ####### -+ * ## ## ## ## ## ## ## -+ * ## ## ## ## ## ## ## -+ * ## ## ## ###### ## ## ## -+ * ## ## ## ## ## ## ## -+ * ## ## ## ## ## ## ## -+ * ### ### ######## #### ####### -+ * -+ * Web Of Things Platform -+ * -+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * Authors : -+ * Drasko DRASKOVIC -+ * Uros PETREVSKI -+ */ -+ -+#include -+#include -+#include -+#include -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define WEIO_GPIO_LED_STA 1 -+#define WEIO_GPIO_LED_AP 16 -+ -+#define WEIO_GPIO_BTN_AP 20 -+#define WEIO_GPIO_BTN_RESET 23 -+ -+#define WEIO_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WEIO_KEYS_DEBOUNCE_INTERVAL (3 * WEIO_KEYS_POLL_INTERVAL) -+ -+#define WEIO_MAC0_OFFSET 0x0000 -+#define WEIO_MAC1_OFFSET 0x0006 -+#define WEIO_CALDATA_OFFSET 0x1000 -+#define WEIO_WMAC_MAC_OFFSET 0x1002 -+ -+static struct gpio_led weio_leds_gpio[] __initdata = { -+ { -+ .name = "weio:green:sta", -+ .gpio = WEIO_GPIO_LED_STA, -+ .active_low = 1, -+ .default_state = LEDS_GPIO_DEFSTATE_ON, -+ }, -+ { -+ .name = "weio:green:ap", -+ .gpio = WEIO_GPIO_LED_AP, -+ .active_low = 1, -+ .default_state = LEDS_GPIO_DEFSTATE_ON, -+ } -+}; -+ -+static struct gpio_keys_button weio_gpio_keys[] __initdata = { -+ { -+ .desc = "ap button", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = WEIO_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WEIO_GPIO_BTN_AP, -+ .active_low = 1, -+ }, -+ { -+ .desc = "soft-reset button", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .debounce_interval = WEIO_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WEIO_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static struct i2c_gpio_platform_data weio_i2c_gpio_data = { -+ .sda_pin = 18, -+ .scl_pin = 19, -+}; -+ -+static struct platform_device weio_i2c_gpio = { -+ .name = "i2c-gpio", -+ .id = 0, -+ .dev = { -+ .platform_data = &weio_i2c_gpio_data, -+ }, -+}; -+ -+static void __init weio_common_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_wmac(art + WEIO_CALDATA_OFFSET, art + WEIO_WMAC_MAC_OFFSET); -+} -+ -+static void __init weio_setup(void) -+{ -+ weio_common_setup(); -+ -+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ platform_device_register(&weio_i2c_gpio); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(weio_leds_gpio), -+ weio_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, WEIO_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(weio_gpio_keys), -+ weio_gpio_keys); -+ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WEIO, "WEIO", "WeIO board", weio_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-whr-hp-g300n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-whr-hp-g300n.c -new file mode 100644 -index 0000000000..48f49ad0f7 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-whr-hp-g300n.c -@@ -0,0 +1,155 @@ -+/* -+ * Buffalo WHR-HP-G300N board support -+ * -+ * based on ... -+ * -+ * TP-LINK TL-WR741ND board support -+ * -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+ -+#define WHRHPG300N_GPIO_LED_SECURITY 0 -+#define WHRHPG300N_GPIO_LED_DIAG 1 -+#define WHRHPG300N_GPIO_LED_ROUTER 6 -+ -+#define WHRHPG300N_GPIO_BTN_ROUTER_ON 7 -+#define WHRHPG300N_GPIO_BTN_ROUTER_AUTO 8 -+#define WHRHPG300N_GPIO_BTN_RESET 11 -+#define WHRHPG300N_GPIO_BTN_AOSS 12 -+#define WHRHPG300N_GPIO_LED_LAN1 13 -+#define WHRHPG300N_GPIO_LED_LAN2 14 -+#define WHRHPG300N_GPIO_LED_LAN3 15 -+#define WHRHPG300N_GPIO_LED_LAN4 16 -+#define WHRHPG300N_GPIO_LED_WAN 17 -+ -+#define WHRHPG300N_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WHRHPG300N_KEYS_DEBOUNCE_INTERVAL (3 * WHRHPG300N_KEYS_POLL_INTERVAL) -+ -+#define WHRHPG300N_MAC_OFFSET 0x20c -+ -+static struct gpio_led whrhpg300n_leds_gpio[] __initdata = { -+ { -+ .name = "buffalo:orange:security", -+ .gpio = WHRHPG300N_GPIO_LED_SECURITY, -+ .active_low = 1, -+ }, { -+ .name = "buffalo:red:diag", -+ .gpio = WHRHPG300N_GPIO_LED_DIAG, -+ .active_low = 1, -+ }, { -+ .name = "buffalo:green:router", -+ .gpio = WHRHPG300N_GPIO_LED_ROUTER, -+ .active_low = 1, -+ }, { -+ .name = "buffalo:green:wan", -+ .gpio = WHRHPG300N_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "buffalo:green:lan1", -+ .gpio = WHRHPG300N_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "buffalo:green:lan2", -+ .gpio = WHRHPG300N_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "buffalo:green:lan3", -+ .gpio = WHRHPG300N_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "buffalo:green:lan4", -+ .gpio = WHRHPG300N_GPIO_LED_LAN4, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button whrhpg300n_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WHRHPG300N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WHRHPG300N_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "aoss/wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .gpio = WHRHPG300N_GPIO_BTN_AOSS, -+ .debounce_interval = WHRHPG300N_KEYS_DEBOUNCE_INTERVAL, -+ .active_low = 1, -+ }, { -+ .desc = "router_on", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .gpio = WHRHPG300N_GPIO_BTN_ROUTER_ON, -+ .debounce_interval = WHRHPG300N_KEYS_DEBOUNCE_INTERVAL, -+ .active_low = 1, -+ }, { -+ .desc = "router_auto", -+ .type = EV_KEY, -+ .code = BTN_3, -+ .gpio = WHRHPG300N_GPIO_BTN_ROUTER_AUTO, -+ .debounce_interval = WHRHPG300N_KEYS_DEBOUNCE_INTERVAL, -+ .active_low = 1, -+ } -+}; -+ -+static void __init whrhpg300n_setup(void) -+{ -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 *mac = (u8 *) KSEG1ADDR(ee + WHRHPG300N_MAC_OFFSET); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(whrhpg300n_leds_gpio), -+ whrhpg300n_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, WHRHPG300N_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(whrhpg300n_gpio_keys), -+ whrhpg300n_gpio_keys); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN ports */ -+ ath79_register_eth(1); -+ /* WAN port */ -+ ath79_register_eth(0); -+ -+ ap9x_pci_setup_wmac_led_pin(0, 1); -+ -+ ap91_pci_init(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WHR_HP_G300N, "WHR-HP-G300N", "Buffalo WHR-HP-G300N", -+ whrhpg300n_setup); -+ -+MIPS_MACHINE(ATH79_MACH_WHR_G301N, "WHR-G301N", "Buffalo WHR-G301N", -+ whrhpg300n_setup); -+ -+MIPS_MACHINE(ATH79_MACH_WHR_HP_GN, "WHR-HP-GN", "Buffalo WHR-HP-GN", -+ whrhpg300n_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wi2a-ac200i.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wi2a-ac200i.c -new file mode 100644 -index 0000000000..85e0c8fea3 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wi2a-ac200i.c -@@ -0,0 +1,217 @@ -+/* -+ * Nokia WI2A-AC200i support -+ * -+ * Copyright (c) 2012 Qualcomm Atheros -+ * Copyright (c) 2012-2013 Gabor Juhos -+ * Copyright (c) 2017 Felix Fietkau -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-nfc.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define AC200I_GPIO_BTN_RESET 17 -+ -+#define AC200I_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define AC200I_KEYS_DEBOUNCE_INTERVAL (3 * AC200I_KEYS_POLL_INTERVAL) -+ -+#define AC200I_MAC_ADDR 0x1f040249 -+#define AC200I_MAC1_OFFSET 6 -+#define AC200I_WMAC_CALDATA_ADDR 0x1f061000 -+ -+static struct gpio_led ac200i_leds_gpio[] __initdata = { -+ { -+ .name = "nokia:red:wlan-2g", -+ .gpio = 0, -+ .active_low = 1, -+ }, -+ { -+ .name = "nokia:green:power", -+ .gpio = 1, -+ .active_low = 1, -+ }, -+ { -+ .name = "nokia:green:wlan-2g", -+ .gpio = 2, -+ .active_low = 1, -+ }, -+ { -+ .name = "nokia:green:ctrl", -+ .gpio = 3, -+ .active_low = 1, -+ }, -+ { -+ .name = "nokia:green:eth", -+ .gpio = 4, -+ .active_low = 1, -+ }, -+ { -+ .name = "nokia:red:power", -+ .gpio = 13, -+ .active_low = 1, -+ }, -+ { -+ .name = "nokia:red:eth", -+ .gpio = 14, -+ .active_low = 1, -+ }, -+ { -+ .name = "nokia:red:wlan-5g", -+ .gpio = 18, -+ .active_low = 1, -+ }, -+ { -+ .name = "nokia:green:wlan-5g", -+ .gpio = 19, -+ .active_low = 1, -+ }, -+ { -+ .name = "nokia:red:ctrl", -+ .gpio = 20, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button ac200i_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = AC200I_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = AC200I_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct mtd_partition ac200i_nand_partitions[] = { -+ { -+ .name = "cfg", -+ .offset = 0x0100000, -+ .size = 0x1800000, -+ .mask_flags = MTD_WRITEABLE, -+ }, -+ { -+ .name = "kernel", -+ .offset = 0x2000000, -+ .size = 0x0400000, -+ }, -+ { -+ .name = "ubi", -+ .offset = 0x2400000, -+ .size = 0x2000000, -+ }, -+ { -+ .name = "kernel", -+ .offset = 0x5000000, -+ .size = 0x0400000, -+ }, -+ { -+ .name = "ubi", -+ .offset = 0x5400000, -+ .size = 0x2000000, -+ }, -+}; -+ -+static const char *boot_getenv(const char *key) -+{ -+ const char *start = (const char *) KSEG1ADDR(0x1f070000); -+ const char *end = start + 0x20000; -+ const char *addr; -+ -+ for (addr = start + 4; -+ *addr && *addr != 0xff && addr < end && -+ strnlen(addr, end - addr) < end - addr; -+ addr += strnlen(addr, end - addr) + 1) { -+ const char *val; -+ -+ val = strchr(addr, '='); -+ if (!val) -+ continue; -+ -+ if (strncmp(addr, key, val - addr)) -+ continue; -+ -+ return val + 1; -+ } -+ return NULL; -+} -+ -+static void __init ac200i_setup(void) -+{ -+ const char *img; -+ u8 *wmac = (u8 *) KSEG1ADDR(AC200I_WMAC_CALDATA_ADDR); -+ u8 *mac_addr = (u8 *) KSEG1ADDR(AC200I_MAC_ADDR); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ac200i_leds_gpio), -+ ac200i_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, AC200I_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ac200i_gpio_keys), -+ ac200i_gpio_keys); -+ -+ ath79_register_usb(); -+ ath79_nfc_set_parts(ac200i_nand_partitions, -+ ARRAY_SIZE(ac200i_nand_partitions)); -+ ath79_nfc_set_ecc_mode(AR934X_NFC_ECC_HW); -+ ath79_register_nfc(); -+ -+ ath79_register_wmac(wmac, NULL); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac_addr, 0); -+ -+ /* GMAC0 is connected to the SGMII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x03000101; -+ ath79_eth0_pll_data.pll_100 = 0x80000101; -+ ath79_eth0_pll_data.pll_10 = 0x80001313; -+ -+ img = boot_getenv("dualPartition"); -+ if (img && !strcmp(img, "imgA")) { -+ ac200i_nand_partitions[3].name = "kernel_alt"; -+ ac200i_nand_partitions[4].name = "ubi_alt"; -+ } else { -+ ac200i_nand_partitions[1].name = "kernel_alt"; -+ ac200i_nand_partitions[2].name = "ubi_alt"; -+ } -+ -+ ath79_register_eth(0); -+ -+ ath79_register_pci(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WI2A_AC200I, "WI2A-AC200i", -+ "Nokia WI2A-AC200i", -+ ac200i_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wifi-pineapple-nano.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wifi-pineapple-nano.c -new file mode 100644 -index 0000000000..645f367f6c ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wifi-pineapple-nano.c -@@ -0,0 +1,107 @@ -+/* -+ * Hak5 WiFi Pineapple NANO board support -+ * -+ * Copyright (C) 2018 Sebastian Kinne -+ * Copyright (C) 2018 Piotr Dymacz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define WIFI_PINEAPPLE_NANO_GPIO_LED_SYSTEM 18 -+ -+#define WIFI_PINEAPPLE_NANO_GPIO_BTN_RESET 12 -+#define WIFI_PINEAPPLE_NANO_GPIO_SD_DET 19 -+#define WIFI_PINEAPPLE_NANO_GPIO_USB_ALARM 20 -+#define WIFI_PINEAPPLE_NANO_GPIO_USB_POWER 23 -+ -+#define HAK5_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define HAK5_KEYS_DEBOUNCE_INTERVAL (3 * HAK5_KEYS_POLL_INTERVAL) -+ -+#define WIFI_PINEAPPLE_NANO_MAC1_OFFSET 0x0006 -+#define WIFI_PINEAPPLE_NANO_CALDATA_OFFSET 0x1000 -+ -+static const char *hak5_part_probes[] = { -+ "tp-link", -+ NULL, -+}; -+ -+static struct flash_platform_data hak5_flash_data = { -+ .part_probes = hak5_part_probes, -+}; -+ -+static struct gpio_led wifi_pineapple_nano_leds_gpio[] __initdata = { -+ { -+ .name = "wifi-pineapple-nano:blue:system", -+ .gpio = WIFI_PINEAPPLE_NANO_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button wifi_pineapple_nano_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = HAK5_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WIFI_PINEAPPLE_NANO_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static void __init wifi_pineapple_nano_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(&hak5_flash_data); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ art + WIFI_PINEAPPLE_NANO_MAC1_OFFSET, 0); -+ ath79_register_eth(0); -+ -+ /* GPIO11/12 */ -+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_UART_RTS_CTS_EN); -+ -+ gpio_request_one(WIFI_PINEAPPLE_NANO_GPIO_SD_DET, -+ GPIOF_IN | GPIOF_EXPORT_DIR_FIXED | GPIOF_ACTIVE_LOW, -+ "SD card present"); -+ -+ gpio_request_one(WIFI_PINEAPPLE_NANO_GPIO_USB_ALARM, -+ GPIOF_IN | GPIOF_EXPORT_DIR_FIXED | GPIOF_ACTIVE_LOW, -+ "USB alarm"); -+ -+ gpio_request_one(WIFI_PINEAPPLE_NANO_GPIO_USB_POWER, -+ GPIOF_OUT_INIT_LOW | GPIOF_EXPORT_DIR_FIXED | -+ GPIOF_ACTIVE_LOW, "USB power"); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wifi_pineapple_nano_leds_gpio), -+ wifi_pineapple_nano_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, HAK5_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wifi_pineapple_nano_gpio_keys), -+ wifi_pineapple_nano_gpio_keys); -+ -+ ath79_register_usb(); -+ ath79_register_wmac(art + WIFI_PINEAPPLE_NANO_CALDATA_OFFSET, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WIFI_PINEAPPLE_NANO, "WIFI-PINEAPPLE-NANO", -+ "Hak5 WiFi Pineapple NANO", wifi_pineapple_nano_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wlae-ag300n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wlae-ag300n.c -new file mode 100644 -index 0000000000..11006fd1bc ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wlae-ag300n.c -@@ -0,0 +1,114 @@ -+/* -+ * Buffalo WLAE-AG300N board support -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+ -+#define WLAEAG300N_MAC_OFFSET 0x20c -+#define WLAEAG300N_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WLAEAG300N_KEYS_DEBOUNCE_INTERVAL (3 * WLAEAG300N_KEYS_POLL_INTERVAL) -+ -+ -+static struct gpio_led wlaeag300n_leds_gpio[] __initdata = { -+ /* -+ * Note: Writing 1 into GPIO 13 will power down the device. -+ */ -+ { -+ .name = "buffalo:green:wireless", -+ .gpio = 14, -+ .active_low = 1, -+ }, { -+ .name = "buffalo:red:wireless", -+ .gpio = 15, -+ .active_low = 1, -+ }, { -+ .name = "buffalo:green:status", -+ .gpio = 16, -+ .active_low = 1, -+ }, { -+ .name = "buffalo:red:status", -+ .gpio = 17, -+ .active_low = 1, -+ } -+}; -+ -+ -+static struct gpio_keys_button wlaeag300n_gpio_keys[] __initdata = { -+ { -+ .desc = "function", -+ .type = EV_KEY, -+ .code = KEY_MODE, -+ .debounce_interval = WLAEAG300N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 0, -+ .active_low = 1, -+ }, { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WLAEAG300N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 1, -+ .active_low = 1, -+ }, { -+ .desc = "power", -+ .type = EV_KEY, -+ .code = KEY_POWER, -+ .debounce_interval = WLAEAG300N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 11, -+ .active_low = 1, -+ }, { -+ .desc = "aoss", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WLAEAG300N_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 12, -+ .active_low = 1, -+ } -+}; -+ -+static void __init wlaeag300n_setup(void) -+{ -+ u8 *eeprom1 = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 *mac1 = eeprom1 + WLAEAG300N_MAC_OFFSET; -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac1, 1); -+ -+ ath79_register_mdio(0, ~(BIT(0) | BIT(4))); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(0); -+ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth1_data.phy_mask = BIT(4); -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wlaeag300n_leds_gpio), -+ wlaeag300n_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, WLAEAG300N_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wlaeag300n_gpio_keys), -+ wlaeag300n_gpio_keys); -+ -+ ath79_register_m25p80(NULL); -+ -+ ap91_pci_init(eeprom1, mac1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WLAE_AG300N, "WLAE-AG300N", -+ "Buffalo WLAE-AG300N", wlaeag300n_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wlr8100.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wlr8100.c -new file mode 100644 -index 0000000000..04b12fc7cc ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wlr8100.c -@@ -0,0 +1,195 @@ -+/* -+ * Sitecom X8 AC1750 WLR-8100 board support -+ * -+ * Based on the Qualcomm Atheros AP135/AP136 reference board support code -+ * Copyright (c) 2012 Qualcomm Atheros -+ * Copyright (c) 2012-2013 Gabor Juhos -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define WLR8100_GPIO_LED_USB 4 -+#define WLR8100_GPIO_LED_WLAN_5G 12 -+#define WLR8100_GPIO_LED_WLAN_2G 13 -+#define WLR8100_GPIO_LED_STATUS_RED 14 -+#define WLR8100_GPIO_LED_WPS_RED 15 -+#define WLR8100_GPIO_LED_STATUS_AMBER 19 -+#define WLR8100_GPIO_LED_WPS_GREEN 20 -+ -+#define WLR8100_GPIO_BTN_WPS 16 -+#define WLR8100_GPIO_BTN_RFKILL 21 -+ -+#define WLR8100_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WLR8100_KEYS_DEBOUNCE_INTERVAL (3 * WLR8100_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led wlr8100_leds_gpio[] __initdata = { -+ { -+ .name = "wlr8100:amber:status", -+ .gpio = WLR8100_GPIO_LED_STATUS_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "wlr8100:red:status", -+ .gpio = WLR8100_GPIO_LED_STATUS_RED, -+ .active_low = 1, -+ }, -+ { -+ .name = "wlr8100:green:wps", -+ .gpio = WLR8100_GPIO_LED_WPS_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "wlr8100:red:wps", -+ .gpio = WLR8100_GPIO_LED_WPS_RED, -+ .active_low = 1, -+ }, -+ { -+ .name = "wlr8100:red:wlan-2g", -+ .gpio = WLR8100_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "wlr8100:red:usb", -+ .gpio = WLR8100_GPIO_LED_USB, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button wlr8100_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WLR8100_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WLR8100_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+ { -+ .desc = "RFKILL button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = WLR8100_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WLR8100_GPIO_BTN_RFKILL, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg wlr8100_ar8327_pad0_cfg; -+static struct ar8327_pad_cfg wlr8100_ar8327_pad6_cfg; -+ -+static struct ar8327_platform_data wlr8100_ar8327_data = { -+ .pad0_cfg = &wlr8100_ar8327_pad0_cfg, -+ .pad6_cfg = &wlr8100_ar8327_pad6_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .port6_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info wlr8100_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &wlr8100_ar8327_data, -+ }, -+}; -+ -+static void __init wlr8100_common_setup(void) -+{ -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wlr8100_leds_gpio), -+ wlr8100_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, WLR8100_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wlr8100_gpio_keys), -+ wlr8100_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_register_wmac_simple(); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ mdiobus_register_board_info(wlr8100_mdio0_info, -+ ARRAY_SIZE(wlr8100_mdio0_info)); -+ -+ /* GMAC0 is connected to the RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected tot eh SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(1); -+} -+ -+static void __init wlr8100_010_setup(void) -+{ -+ /* GMAC0 of the AR8337 switch is connected to GMAC0 via RGMII */ -+ wlr8100_ar8327_pad0_cfg.mode = AR8327_PAD_MAC_RGMII; -+ wlr8100_ar8327_pad0_cfg.txclk_delay_en = true; -+ wlr8100_ar8327_pad0_cfg.rxclk_delay_en = true; -+ wlr8100_ar8327_pad0_cfg.txclk_delay_sel = AR8327_CLK_DELAY_SEL1; -+ wlr8100_ar8327_pad0_cfg.rxclk_delay_sel = AR8327_CLK_DELAY_SEL2; -+ -+ /* GMAC6 of the AR8337 switch is connected to GMAC1 via SGMII */ -+ wlr8100_ar8327_pad6_cfg.mode = AR8327_PAD_MAC_SGMII; -+ wlr8100_ar8327_pad6_cfg.rxclk_delay_en = true; -+ wlr8100_ar8327_pad6_cfg.rxclk_delay_sel = AR8327_CLK_DELAY_SEL0; -+ -+ ath79_eth0_pll_data.pll_1000 = 0xa6000000; -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ -+ wlr8100_common_setup(); -+ ap91_pci_init_simple(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WLR8100, "WLR8100", -+ "Sitecom WLR-8100", -+ wlr8100_010_setup); -+ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wndap360.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wndap360.c -new file mode 100644 -index 0000000000..eae1c383ee ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wndap360.c -@@ -0,0 +1,105 @@ -+/* -+ * Netgear WNDAP360 board support (proper leds / button support missing) -+ * -+ * Based on AP96 -+ * Copyright (C) 2013 Jacek Kikiewicz -+ * Copyright (C) 2009 Marco Porsch -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * Copyright (C) 2010 Atheros Communications -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+ -+#define WNDAP360_GPIO_LED_POWER_ORANGE 0 -+#define WNDAP360_GPIO_LED_POWER_GREEN 2 -+ -+/* Reset button - next to the power connector */ -+#define WNDAP360_GPIO_BTN_RESET 8 -+ -+#define WNDAP360_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WNDAP360_KEYS_DEBOUNCE_INTERVAL (3 * WNDAP360_KEYS_POLL_INTERVAL) -+ -+#define WNDAP360_WMAC0_MAC_OFFSET 0x120c -+#define WNDAP360_WMAC1_MAC_OFFSET 0x520c -+#define WNDAP360_CALDATA0_OFFSET 0x1000 -+#define WNDAP360_CALDATA1_OFFSET 0x5000 -+ -+/* -+ * WNDAP360 this still uses leds definitions from AP96 -+ * -+ */ -+static struct gpio_led wndap360_leds_gpio[] __initdata = { -+ { -+ .name = "netgear:green:power", -+ .gpio = WNDAP360_GPIO_LED_POWER_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:orange:power", -+ .gpio = WNDAP360_GPIO_LED_POWER_ORANGE, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button wndap360_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WNDAP360_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNDAP360_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+#define WNDAP360_LAN_PHYMASK 0x0f -+ -+static void __init wndap360_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_mdio(0, ~(WNDAP360_LAN_PHYMASK)); -+ -+ /* Reusing wifi MAC with offset of 1 as eth0 MAC */ -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ art + WNDAP360_WMAC0_MAC_OFFSET, 1); -+ ath79_eth0_pll_data.pll_1000 = 0x11110000; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = WNDAP360_LAN_PHYMASK; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ -+ ath79_register_eth(0); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wndap360_leds_gpio), -+ wndap360_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, WNDAP360_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wndap360_gpio_keys), -+ wndap360_gpio_keys); -+ -+ ap9x_pci_setup_wmac_led_pin(0, 5); -+ ap9x_pci_setup_wmac_led_pin(1, 5); -+ -+ ap94_pci_init(art + WNDAP360_CALDATA0_OFFSET, -+ art + WNDAP360_WMAC0_MAC_OFFSET, -+ art + WNDAP360_CALDATA1_OFFSET, -+ art + WNDAP360_WMAC1_MAC_OFFSET); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WNDAP360, "WNDAP360", "NETGEAR WNDAP360", wndap360_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wndr3700.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wndr3700.c -new file mode 100644 -index 0000000000..b9132fc363 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wndr3700.c -@@ -0,0 +1,172 @@ -+/* -+ * Netgear WNDR3700 board support -+ * -+ * Copyright (C) 2009 Marco Porsch -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+ -+#define WNDR3700_GPIO_LED_WPS_ORANGE 0 -+#define WNDR3700_GPIO_LED_POWER_ORANGE 1 -+#define WNDR3700_GPIO_LED_POWER_GREEN 2 -+#define WNDR3700_GPIO_LED_WPS_GREEN 4 -+#define WNDR3700_GPIO_LED_WAN_GREEN 6 -+ -+#define WNDR3700_GPIO_BTN_WPS 3 -+#define WNDR3700_GPIO_BTN_RESET 8 -+#define WNDR3700_GPIO_BTN_RFKILL 11 -+ -+#define WNDR3700_GPIO_RTL8366_SDA 5 -+#define WNDR3700_GPIO_RTL8366_SCK 7 -+ -+#define WNDR3700_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WNDR3700_KEYS_DEBOUNCE_INTERVAL (3 * WNDR3700_KEYS_POLL_INTERVAL) -+ -+#define WNDR3700_ETH0_MAC_OFFSET 0 -+#define WNDR3700_ETH1_MAC_OFFSET 0x6 -+ -+#define WNDR3700_WMAC0_MAC_OFFSET 0 -+#define WNDR3700_WMAC1_MAC_OFFSET 0xc -+#define WNDR3700_CALDATA0_OFFSET 0x1000 -+#define WNDR3700_CALDATA1_OFFSET 0x5000 -+ -+static struct gpio_led wndr3700_leds_gpio[] __initdata = { -+ { -+ .name = "netgear:green:power", -+ .gpio = WNDR3700_GPIO_LED_POWER_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:orange:power", -+ .gpio = WNDR3700_GPIO_LED_POWER_ORANGE, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:wps", -+ .gpio = WNDR3700_GPIO_LED_WPS_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:orange:wps", -+ .gpio = WNDR3700_GPIO_LED_WPS_ORANGE, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:wan", -+ .gpio = WNDR3700_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button wndr3700_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNDR3700_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNDR3700_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, { -+ .desc = "rfkill", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNDR3700_GPIO_BTN_RFKILL, -+ .active_low = 1, -+ } -+}; -+ -+static struct rtl8366_platform_data wndr3700_rtl8366s_data = { -+ .gpio_sda = WNDR3700_GPIO_RTL8366_SDA, -+ .gpio_sck = WNDR3700_GPIO_RTL8366_SCK, -+}; -+ -+static struct platform_device wndr3700_rtl8366s_device = { -+ .name = RTL8366S_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &wndr3700_rtl8366s_data, -+ } -+}; -+ -+static void __init wndr3700_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ /* -+ * The eth0 and wmac0 interfaces share the same MAC address which -+ * can lead to problems if operated unbridged. Set the locally -+ * administered bit on the eth0 MAC to make it unique. -+ */ -+ ath79_init_local_mac(ath79_eth0_data.mac_addr, -+ art + WNDR3700_ETH0_MAC_OFFSET); -+ ath79_eth0_pll_data.pll_1000 = 0x11110000; -+ ath79_eth0_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, -+ art + WNDR3700_ETH1_MAC_OFFSET, 0); -+ ath79_eth1_pll_data.pll_1000 = 0x11110000; -+ ath79_eth1_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth1_data.phy_mask = 0x10; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_usb(); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wndr3700_leds_gpio), -+ wndr3700_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, WNDR3700_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wndr3700_gpio_keys), -+ wndr3700_gpio_keys); -+ -+ platform_device_register(&wndr3700_rtl8366s_device); -+ platform_device_register_simple("wndr3700-led-usb", -1, NULL, 0); -+ -+ ap9x_pci_setup_wmac_led_pin(0, 5); -+ ap9x_pci_setup_wmac_led_pin(1, 5); -+ -+ /* 2.4 GHz uses the first fixed antenna group (1, 0, 1, 0) */ -+ ap9x_pci_setup_wmac_gpio(0, (0xf << 6), (0xa << 6)); -+ -+ /* 5 GHz uses the second fixed antenna group (0, 1, 1, 0) */ -+ ap9x_pci_setup_wmac_gpio(1, (0xf << 6), (0x6 << 6)); -+ -+ ap94_pci_init(art + WNDR3700_CALDATA0_OFFSET, -+ art + WNDR3700_WMAC0_MAC_OFFSET, -+ art + WNDR3700_CALDATA1_OFFSET, -+ art + WNDR3700_WMAC1_MAC_OFFSET); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WNDR3700, "WNDR3700", -+ "NETGEAR WNDR3700/WNDR3800/WNDRMAC", -+ wndr3700_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wndr4300.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wndr4300.c -new file mode 100644 -index 0000000000..339216da1b ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wndr4300.c -@@ -0,0 +1,215 @@ -+/* -+ * NETGEAR WNDR3700v4/WNDR4300 board support -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * Copyright (C) 2014 Ralph Perlich -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) -+#include -+#else -+#include -+#endif -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-nfc.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+/* AR9344 GPIOs */ -+#define WNDR4300_GPIO_LED_POWER_GREEN 0 -+#define WNDR4300_GPIO_LED_POWER_AMBER 2 -+#define WNDR4300_GPIO_LED_USB 13 -+#define WNDR4300_GPIO_LED_WAN_GREEN 1 -+#define WNDR4300_GPIO_LED_WAN_AMBER 3 -+#define WNDR4300_GPIO_LED_WLAN2G 11 -+#define WNDR4300_GPIO_LED_WLAN5G 14 -+#define WNDR4300_GPIO_LED_WPS_GREEN 16 -+#define WNDR4300_GPIO_LED_WPS_AMBER 17 -+ -+#define WNDR4300_GPIO_BTN_RESET 21 -+#define WNDR4300_GPIO_BTN_WIRELESS 15 -+#define WNDR4300_GPIO_BTN_WPS 12 -+ -+/* AR9580 GPIOs */ -+#define WNDR4300_GPIO_USB_5V 0 -+ -+#define WNDR4300_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WNDR4300_KEYS_DEBOUNCE_INTERVAL (3 * WNDR4300_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led wndr4300_leds_gpio[] __initdata = { -+ { -+ .name = "netgear:green:power", -+ .gpio = WNDR4300_GPIO_LED_POWER_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:amber:power", -+ .gpio = WNDR4300_GPIO_LED_POWER_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:green:wan", -+ .gpio = WNDR4300_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:amber:wan", -+ .gpio = WNDR4300_GPIO_LED_WAN_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:green:usb", -+ .gpio = WNDR4300_GPIO_LED_USB, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:green:wps", -+ .gpio = WNDR4300_GPIO_LED_WPS_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:amber:wps", -+ .gpio = WNDR4300_GPIO_LED_WPS_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:green:wlan2g", -+ .gpio = WNDR4300_GPIO_LED_WLAN2G, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:blue:wlan5g", -+ .gpio = WNDR4300_GPIO_LED_WLAN5G, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button wndr4300_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WNDR4300_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNDR4300_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WNDR4300_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNDR4300_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+ { -+ .desc = "rfkill", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = WNDR4300_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNDR4300_GPIO_BTN_WIRELESS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg wndr4300_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_led_cfg wndr4300_ar8327_led_cfg = { -+ .led_ctrl0 = 0xcc35cc35, -+ .led_ctrl1 = 0xcb37cb37, -+ .led_ctrl2 = 0x00000000, -+ .led_ctrl3 = 0x00f3cf00, -+ .open_drain = true, -+}; -+ -+static struct ar8327_platform_data wndr4300_ar8327_data = { -+ .pad0_cfg = &wndr4300_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &wndr4300_ar8327_led_cfg, -+}; -+ -+static struct mdio_board_info wndr4300_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &wndr4300_ar8327_data, -+ }, -+}; -+ -+static void __init wndr4300_setup(void) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(wndr4300_leds_gpio); i++) -+ ath79_gpio_output_select(wndr4300_leds_gpio[i].gpio, -+ AR934X_GPIO_OUT_GPIO); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wndr4300_leds_gpio), -+ wndr4300_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, WNDR4300_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wndr4300_gpio_keys), -+ wndr4300_gpio_keys); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0); -+ -+ mdiobus_register_board_info(wndr4300_mdio0_info, -+ ARRAY_SIZE(wndr4300_mdio0_info)); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* GMAC0 is connected to an AR8327N switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_register_eth(0); -+ -+ ath79_nfc_set_ecc_mode(AR934X_NFC_ECC_HW); -+ ath79_register_nfc(); -+ ath79_register_usb(); -+ -+ ath79_register_wmac_simple(); -+ -+ /* enable power for the USB port */ -+ ap9x_pci_setup_wmac_gpio(0, BIT(WNDR4300_GPIO_USB_5V), -+ BIT(WNDR4300_GPIO_USB_5V)); -+ -+ ap91_pci_init_simple(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WNDR3700_V4, "WNDR3700_V4", "NETGEAR WNDR3700v4", -+ wndr4300_setup); -+MIPS_MACHINE(ATH79_MACH_WNDR4300, "WNDR4300", "NETGEAR WNDR4300", -+ wndr4300_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2000-v3.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2000-v3.c -new file mode 100644 -index 0000000000..76c9cb99c9 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2000-v3.c -@@ -0,0 +1,637 @@ -+/* -+ * NETGEAR WNR2000v3/WNR612v2/WNR1000v2/WPN824N board support -+ * -+ * Copyright (C) 2015 Hartmut Knaack -+ * Copyright (C) 2013 Mathieu Olivari -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * Copyright (C) 2008-2009 Andy Boyett -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include /* for max() macro */ -+#include /* PLATFORM_DEVID_AUTO is defined here */ -+ -+#include -+#include /* needed to disable switch LEDs */ -+#include "common.h" /* needed to disable switch LEDs */ -+ -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+ -+/* WNR2000v3 - connected through AR7241 */ -+#define WNR2000V3_GPIO_LED_WAN_GREEN 0 -+#define WNR2000V3_GPIO_LED_LAN1_AMBER 1 -+#define WNR2000V3_GPIO_LED_LAN2_AMBER 6 -+#define WNR2000V3_GPIO_LED_WPS_GREEN 7 -+#define WNR2000V3_GPIO_LED_LAN3_AMBER 8 -+#define WNR2000V3_GPIO_BTN_WPS 11 -+#define WNR2000V3_GPIO_LED_LAN4_AMBER 12 -+#define WNR2000V3_GPIO_LED_LAN1_GREEN 13 -+#define WNR2000V3_GPIO_LED_LAN2_GREEN 14 -+#define WNR2000V3_GPIO_LED_LAN3_GREEN 15 -+#define WNR2000V3_GPIO_LED_LAN4_GREEN 16 -+#define WNR2000V3_GPIO_LED_WAN_AMBER 17 -+ -+/* WNR2000v3 - connected through AR9287 */ -+#define WNR2000V3_GPIO_WMAC_LED_WLAN_BLUE 1 -+#define WNR2000V3_GPIO_WMAC_LED_TEST_AMBER 2 -+#define WNR2000V3_GPIO_WMAC_LED_POWER_GREEN 3 -+#define WNR2000V3_GPIO_WMAC_BTN_RESET 8 -+#define WNR2000V3_GPIO_WMAC_BTN_RFKILL 9 -+ -+/* WNR612v2 - connected through AR7241 */ -+#define WNR612V2_GPIO_LED_POWER_GREEN 11 -+#define WNR612V2_GPIO_LED_LAN1_GREEN 13 -+#define WNR612V2_GPIO_LED_LAN2_GREEN 14 -+#define WNR612V2_GPIO_LED_WAN_GREEN 17 -+ -+/* WNR612v2 - connected through AR9285 */ -+#define WNR612V2_GPIO_WMAC_LED_WLAN_GREEN 1 -+#define WNR612V2_GPIO_WMAC_BTN_RESET 7 -+ -+/* WNR1000v2 - connected through AR7240 */ -+#define WNR1000V2_GPIO_LED_WAN_AMBER 0 -+#define WNR1000V2_GPIO_LED_TEST_AMBER 1 -+#define WNR1000V2_GPIO_LED_LAN1_AMBER 6 /* AR724X_GPIO_FUNC_JTAG_DISABLE */ -+#define WNR1000V2_GPIO_LED_LAN2_AMBER 7 /* AR724X_GPIO_FUNC_JTAG_DISABLE */ -+#define WNR1000V2_GPIO_LED_LAN3_AMBER 8 /* AR724X_GPIO_FUNC_JTAG_DISABLE */ -+#define WNR1000V2_GPIO_LED_POWER_GREEN 11 -+#define WNR1000V2_GPIO_LED_LAN4_AMBER 12 -+#define WNR1000V2_GPIO_LED_LAN1_GREEN 13 /* AR724X_..._ETH_SWITCH_LED0 */ -+#define WNR1000V2_GPIO_LED_LAN2_GREEN 14 /* AR724X_..._ETH_SWITCH_LED1 */ -+#define WNR1000V2_GPIO_LED_LAN3_GREEN 15 /* AR724X_..._ETH_SWITCH_LED2 */ -+#define WNR1000V2_GPIO_LED_LAN4_GREEN 16 /* AR724X_..._ETH_SWITCH_LED3 */ -+#define WNR1000V2_GPIO_LED_WAN_GREEN 17 /* AR724X_..._ETH_SWITCH_LED4 */ -+ -+/* WNR1000v2 - connected through AR9285 */ -+#define WNR1000V2_GPIO_WMAC_LED_WLAN_BLUE 1 -+#define WNR1000V2_GPIO_WMAC_LED_WPS_GREEN 5 -+#define WNR1000V2_GPIO_WMAC_BTN_WPS 6 -+#define WNR1000V2_GPIO_WMAC_BTN_RESET 7 -+#define WNR1000V2_GPIO_WMAC_BTN_RFKILL 8 -+ -+/* WPN824N - connected through AR7240 */ -+#define WPN824N_GPIO_LED_WAN_AMBER 0 -+#define WPN824N_GPIO_LED_STATUS_AMBER 1 -+#define WPN824N_GPIO_LED_LAN1_AMBER 6 /* AR724X_GPIO_FUNC_JTAG_DISABLE */ -+#define WPN824N_GPIO_LED_LAN2_AMBER 7 /* AR724X_GPIO_FUNC_JTAG_DISABLE */ -+#define WPN824N_GPIO_LED_LAN3_AMBER 8 /* AR724X_GPIO_FUNC_JTAG_DISABLE */ -+#define WPN824N_GPIO_LED_LAN4_AMBER 12 -+#define WPN824N_GPIO_LED_LAN1_GREEN 13 -+#define WPN824N_GPIO_LED_LAN2_GREEN 14 -+#define WPN824N_GPIO_LED_LAN3_GREEN 15 /* AR724X_GPIO_FUNC_CLK_OBS3_EN */ -+#define WPN824N_GPIO_LED_LAN4_GREEN 16 -+#define WPN824N_GPIO_LED_WAN_GREEN 17 -+ -+/* WPN824N - connected through AR9285 */ -+#define WPN824N_WGPIO_LED_PWR_GREEN 0 -+#define WPN824N_WGPIO_LED_WLAN_BLUE 1 -+#define WPN824N_WGPIO_LED_WPS1_BLUE 5 -+#define WPN824N_WGPIO_LED_WPS2_BLUE 9 -+#define WPN824N_WGPIO_LED_TEST_AMBER 10 -+#define WPN824N_WGPIO_BTN_WPS 6 -+#define WPN824N_WGPIO_BTN_RESET 7 -+#define WPN824N_WGPIO_BTN_WLAN 8 -+ -+#define WNR2000V3_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WNR2000V3_KEYS_DEBOUNCE_INTERVAL (3 * WNR2000V3_KEYS_POLL_INTERVAL) -+ -+/* ART offsets for: WNR2000v3, WNR612v2, WNR1000v2 */ -+#define WNR2000V3_MAC0_OFFSET 0 -+#define WNR2000V3_MAC1_OFFSET 6 -+#define WNR2000V3_PCIE_CALDATA_OFFSET 0x1000 -+#define WNR2000V3_WMAC_OFFSET 0x108c /* wireless MAC is inside ART */ -+ -+static struct gpio_led wnr2000v3_leds_gpio[] __initdata = { -+ { -+ .name = "netgear:green:wan", -+ .gpio = WNR2000V3_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:lan1", -+ .gpio = WNR2000V3_GPIO_LED_LAN1_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:lan2", -+ .gpio = WNR2000V3_GPIO_LED_LAN2_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:lan3", -+ .gpio = WNR2000V3_GPIO_LED_LAN3_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:lan4", -+ .gpio = WNR2000V3_GPIO_LED_LAN4_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:wps", -+ .gpio = WNR2000V3_GPIO_LED_WPS_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan1", -+ .gpio = WNR2000V3_GPIO_LED_LAN1_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan2", -+ .gpio = WNR2000V3_GPIO_LED_LAN2_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan3", -+ .gpio = WNR2000V3_GPIO_LED_LAN3_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan4", -+ .gpio = WNR2000V3_GPIO_LED_LAN4_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:wan", -+ .gpio = WNR2000V3_GPIO_LED_WAN_AMBER, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led wnr2000v3_wmac_leds_gpio[] = { -+ { -+ .name = "netgear:green:power", -+ .gpio = WNR2000V3_GPIO_WMAC_LED_POWER_GREEN, -+ .active_low = 1, -+ .default_state = LEDS_GPIO_DEFSTATE_ON, -+ }, { -+ .name = "netgear:amber:test", -+ .gpio = WNR2000V3_GPIO_WMAC_LED_TEST_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:blue:wlan", -+ .gpio = WNR2000V3_GPIO_WMAC_LED_WLAN_BLUE, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led wnr612v2_leds_gpio[] __initdata = { -+ { -+ .name = "netgear:green:power", -+ .gpio = WNR612V2_GPIO_LED_POWER_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan1", -+ .gpio = WNR612V2_GPIO_LED_LAN1_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan2", -+ .gpio = WNR612V2_GPIO_LED_LAN2_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:wan", -+ .gpio = WNR612V2_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led wnr612v2_wmac_leds_gpio[] = { -+ { -+ .name = "netgear:green:wlan", -+ .gpio = WNR612V2_GPIO_WMAC_LED_WLAN_GREEN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led wnr1000v2_leds_gpio[] __initdata = { -+ { -+ .name = "netgear:amber:lan1", -+ .gpio = WNR1000V2_GPIO_LED_LAN1_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:lan2", -+ .gpio = WNR1000V2_GPIO_LED_LAN2_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:lan3", -+ .gpio = WNR1000V2_GPIO_LED_LAN3_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:lan4", -+ .gpio = WNR1000V2_GPIO_LED_LAN4_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:test", -+ .gpio = WNR1000V2_GPIO_LED_TEST_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:wan", -+ .gpio = WNR1000V2_GPIO_LED_WAN_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan1", -+ .gpio = WNR1000V2_GPIO_LED_LAN1_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan2", -+ .gpio = WNR1000V2_GPIO_LED_LAN2_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan3", -+ .gpio = WNR1000V2_GPIO_LED_LAN3_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan4", -+ .gpio = WNR1000V2_GPIO_LED_LAN4_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:power", -+ .gpio = WNR1000V2_GPIO_LED_POWER_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:wan", -+ .gpio = WNR1000V2_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led wnr1000v2_wmac_leds_gpio[] = { -+ { -+ .name = "netgear:green:wps", -+ .gpio = WNR1000V2_GPIO_WMAC_LED_WPS_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:blue:wlan", -+ .gpio = WNR1000V2_GPIO_WMAC_LED_WLAN_BLUE, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led wpn824n_leds_gpio[] __initdata = { -+ { -+ .name = "netgear:amber:wan", -+ .gpio = WPN824N_GPIO_LED_WAN_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:status", -+ .gpio = WPN824N_GPIO_LED_STATUS_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:lan1", -+ .gpio = WPN824N_GPIO_LED_LAN1_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:lan2", -+ .gpio = WPN824N_GPIO_LED_LAN2_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:lan3", -+ .gpio = WPN824N_GPIO_LED_LAN3_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:lan4", -+ .gpio = WPN824N_GPIO_LED_LAN4_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan1", -+ .gpio = WPN824N_GPIO_LED_LAN1_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan2", -+ .gpio = WPN824N_GPIO_LED_LAN2_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan3", -+ .gpio = WPN824N_GPIO_LED_LAN3_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan4", -+ .gpio = WPN824N_GPIO_LED_LAN4_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:wan", -+ .gpio = WPN824N_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led wpn824n_wmac_leds_gpio[] = { -+ { -+ .name = "netgear:green:power", -+ .gpio = WPN824N_WGPIO_LED_PWR_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:blue:wps1", -+ .gpio = WPN824N_WGPIO_LED_WPS1_BLUE, -+ .active_low = 1, -+ }, { -+ .name = "netgear:blue:wps2", -+ .gpio = WPN824N_WGPIO_LED_WPS2_BLUE, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:test", -+ .gpio = WPN824N_WGPIO_LED_TEST_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:blue:wlan", -+ .gpio = WPN824N_WGPIO_LED_WLAN_BLUE, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button wnr2000v3_keys_gpio[] __initdata = { -+ { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WNR2000V3_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR2000V3_GPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button wnr2000v3_wmac_keys_gpio[] = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WNR2000V3_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR2000V3_GPIO_WMAC_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "rfkill", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = WNR2000V3_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR2000V3_GPIO_WMAC_BTN_RFKILL, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button wnr612v2_wmac_keys_gpio[] = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WNR2000V3_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR612V2_GPIO_WMAC_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button wnr1000v2_wmac_keys_gpio[] = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WNR2000V3_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR1000V2_GPIO_WMAC_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "rfkill", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = WNR2000V3_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR1000V2_GPIO_WMAC_BTN_RFKILL, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WNR2000V3_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR1000V2_GPIO_WMAC_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button wpn824n_wmac_keys_gpio[] = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WNR2000V3_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WPN824N_WGPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "rfkill", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = WNR2000V3_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WPN824N_WGPIO_BTN_WLAN, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WNR2000V3_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WPN824N_WGPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+/* -+ * For WNR2000v3 ART flash area used for WLAN MAC is usually empty (0xff) -+ * so ath9k driver uses random MAC instead each time module is loaded. -+ * To fix that, assign permanent WLAN MAC equal to ethN's MAC plus 1, -+ * so network interfaces get sequential addresses. -+ * If ART wireless MAC address field has been filled by user, use it. -+ */ -+static void __init wnr_get_wmac(u8 *wmac_gen_addr, int mac0_art_offset, -+ int mac1_art_offset, int wmac_art_offset) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *eth0_mac_addr = (u8 *) (art + mac0_art_offset); -+ u8 *eth1_mac_addr = (u8 *) (art + mac1_art_offset); -+ u8 *wlan_mac_addr = (u8 *) (art + wmac_art_offset); -+ -+ /* only 0xff if all bits are set - address is invalid, empty area */ -+ if ((wlan_mac_addr[0] & wlan_mac_addr[1] & wlan_mac_addr[2] & -+ wlan_mac_addr[3] & wlan_mac_addr[4] & wlan_mac_addr[5]) == 0xff) { -+ memcpy(wmac_gen_addr, eth0_mac_addr, 5); -+ wmac_gen_addr[5] = max(eth0_mac_addr[5], eth1_mac_addr[5]) + 1; -+ -+ /* Avoid potential conflict in case max(0xff,0x00)+1==0x00 */ -+ if (!wmac_gen_addr[5]) -+ wmac_gen_addr[5] = 1; -+ } else -+ memcpy(wmac_gen_addr, wlan_mac_addr, 6); -+} -+ -+static void __init wnr_common_setup(u8 *wmac_addr) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art+WNR2000V3_MAC0_OFFSET, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, art+WNR2000V3_MAC1_OFFSET, 0); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth1_data.phy_mask = 0x10; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_m25p80(NULL); -+ ap91_pci_init(art + WNR2000V3_PCIE_CALDATA_OFFSET, wmac_addr); -+} -+ -+static void __init wnr2000v3_setup(void) -+{ -+ u8 wlan_mac_addr[6]; -+ -+ /* -+ * Disable JTAG to use all AR724X GPIO LEDs. -+ * Also disable CLKs and bit 20 as u-boot does. -+ * Finally, allow OS to control all link LEDs. -+ */ -+ ath79_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE | -+ AR724X_GPIO_FUNC_UART_EN, -+ AR724X_GPIO_FUNC_CLK_OBS1_EN | -+ AR724X_GPIO_FUNC_CLK_OBS2_EN | -+ AR724X_GPIO_FUNC_CLK_OBS3_EN | -+ AR724X_GPIO_FUNC_CLK_OBS4_EN | -+ AR724X_GPIO_FUNC_CLK_OBS5_EN | -+ AR724X_GPIO_FUNC_GE0_MII_CLK_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN | -+ BIT(20)); -+ -+ wnr_get_wmac(wlan_mac_addr, WNR2000V3_MAC0_OFFSET, -+ WNR2000V3_MAC1_OFFSET, WNR2000V3_WMAC_OFFSET); -+ -+ wnr_common_setup(wlan_mac_addr); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wnr2000v3_leds_gpio), -+ wnr2000v3_leds_gpio); -+ -+ /* Do not use id=-1, we can have more GPIO key-polled devices */ -+ ath79_register_gpio_keys_polled(PLATFORM_DEVID_AUTO, -+ WNR2000V3_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wnr2000v3_keys_gpio), -+ wnr2000v3_keys_gpio); -+ -+ ap9x_pci_setup_wmac_leds(0, wnr2000v3_wmac_leds_gpio, -+ ARRAY_SIZE(wnr2000v3_wmac_leds_gpio)); -+ -+ ap9x_pci_setup_wmac_btns(0, wnr2000v3_wmac_keys_gpio, -+ ARRAY_SIZE(wnr2000v3_wmac_keys_gpio), -+ WNR2000V3_KEYS_POLL_INTERVAL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WNR2000_V3, "WNR2000V3", "NETGEAR WNR2000 V3", wnr2000v3_setup); -+ -+static void __init wnr612v2_setup(void) -+{ -+ u8 wlan_mac_addr[6]; -+ -+ /* -+ * Disable JTAG and CLKs. Allow OS to control all link LEDs. -+ * Note: U-Boot for WNR612v2 sets undocumented bit 15 but -+ * we leave it for now. -+ */ -+ ath79_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE | -+ AR724X_GPIO_FUNC_UART_EN, -+ AR724X_GPIO_FUNC_CLK_OBS1_EN | -+ AR724X_GPIO_FUNC_CLK_OBS2_EN | -+ AR724X_GPIO_FUNC_CLK_OBS3_EN | -+ AR724X_GPIO_FUNC_CLK_OBS4_EN | -+ AR724X_GPIO_FUNC_CLK_OBS5_EN | -+ AR724X_GPIO_FUNC_GE0_MII_CLK_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ wnr_get_wmac(wlan_mac_addr, WNR2000V3_MAC0_OFFSET, -+ WNR2000V3_MAC1_OFFSET, WNR2000V3_WMAC_OFFSET); -+ -+ wnr_common_setup(wlan_mac_addr); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wnr612v2_leds_gpio), -+ wnr612v2_leds_gpio); -+ -+ ap9x_pci_setup_wmac_leds(0, wnr612v2_wmac_leds_gpio, -+ ARRAY_SIZE(wnr612v2_wmac_leds_gpio)); -+ -+ ap9x_pci_setup_wmac_btns(0, wnr612v2_wmac_keys_gpio, -+ ARRAY_SIZE(wnr612v2_wmac_keys_gpio), -+ WNR2000V3_KEYS_POLL_INTERVAL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WNR612_V2, "WNR612V2", "NETGEAR WNR612 V2", wnr612v2_setup); -+ -+static void __init wnr1000v2_setup(void) -+{ -+ u8 wlan_mac_addr[6]; -+ -+ /* -+ * Disable JTAG and CLKs. Allow OS to control all link LEDs. -+ * Note: U-Boot for WNR1000v2 sets undocumented bit 15 but -+ * we leave it for now. -+ */ -+ ath79_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE | -+ AR724X_GPIO_FUNC_UART_EN, -+ AR724X_GPIO_FUNC_CLK_OBS1_EN | -+ AR724X_GPIO_FUNC_CLK_OBS2_EN | -+ AR724X_GPIO_FUNC_CLK_OBS3_EN | -+ AR724X_GPIO_FUNC_CLK_OBS4_EN | -+ AR724X_GPIO_FUNC_CLK_OBS5_EN | -+ AR724X_GPIO_FUNC_GE0_MII_CLK_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ wnr_get_wmac(wlan_mac_addr, WNR2000V3_MAC0_OFFSET, -+ WNR2000V3_MAC1_OFFSET, WNR2000V3_WMAC_OFFSET); -+ -+ wnr_common_setup(wlan_mac_addr); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wnr1000v2_leds_gpio), -+ wnr1000v2_leds_gpio); -+ -+ ap9x_pci_setup_wmac_leds(0, wnr1000v2_wmac_leds_gpio, -+ ARRAY_SIZE(wnr1000v2_wmac_leds_gpio)); -+ -+ /* All 3 buttons are connected to wireless chip */ -+ ap9x_pci_setup_wmac_btns(0, wnr1000v2_wmac_keys_gpio, -+ ARRAY_SIZE(wnr1000v2_wmac_keys_gpio), -+ WNR2000V3_KEYS_POLL_INTERVAL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WNR1000_V2, "WNR1000V2", "NETGEAR WNR1000 V2", wnr1000v2_setup); -+ -+static void __init wpn824n_setup(void) -+{ -+ ath79_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE, -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN | -+ AR724X_GPIO_FUNC_CLK_OBS3_EN); -+ -+ wnr_common_setup(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wpn824n_leds_gpio), -+ wpn824n_leds_gpio); -+ -+ ap9x_pci_setup_wmac_leds(0, wpn824n_wmac_leds_gpio, -+ ARRAY_SIZE(wpn824n_wmac_leds_gpio)); -+ ap9x_pci_setup_wmac_btns(0, wpn824n_wmac_keys_gpio, -+ ARRAY_SIZE(wpn824n_wmac_keys_gpio), -+ WNR2000V3_KEYS_POLL_INTERVAL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WPN824N, "WPN824N", "NETGEAR WPN824N", wpn824n_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2000-v4.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2000-v4.c -new file mode 100644 -index 0000000000..c5159a30ca ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2000-v4.c -@@ -0,0 +1,214 @@ -+/* -+ * NETGEAR WNR2000v4 board support -+ * -+ * Copyright (C) 2015 Michael Bazzinotti -+ * Copyright (C) 2014 Michaël Burtin -+ * Copyright (C) 2013 Mathieu Olivari -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * Copyright (C) 2008-2009 Andy Boyett -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+/* AR9341 GPIOs */ -+#define WNR2000V4_GPIO_LED_PWR_GREEN 0 -+#define WNR2000V4_GPIO_LED_PWR_AMBER 1 -+#define WNR2000V4_GPIO_LED_WPS 2 -+#define WNR2000V4_GPIO_LED_WLAN 12 -+#define WNR2000V4_GPIO_LED_LAN1_GREEN 13 -+#define WNR2000V4_GPIO_LED_LAN2_GREEN 14 -+#define WNR2000V4_GPIO_LED_LAN3_GREEN 15 -+#define WNR2000V4_GPIO_LED_LAN4_GREEN 16 -+#define WNR2000V4_GPIO_LED_LAN1_AMBER 18 -+#define WNR2000V4_GPIO_LED_LAN2_AMBER 19 -+#define WNR2000V4_GPIO_LED_LAN3_AMBER 20 -+#define WNR2000V4_GPIO_LED_LAN4_AMBER 21 -+#define WNR2000V4_GPIO_LED_WAN_GREEN 17 -+#define WNR2000V4_GPIO_LED_WAN_AMBER 22 -+/* Buttons */ -+#define WNR2000V4_GPIO_BTN_WPS 3 -+#define WNR2000V4_GPIO_BTN_RESET 4 -+#define WNR2000V4_GPIO_BTN_WLAN 11 -+#define WNR2000V4_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WNR2000V4_KEYS_DEBOUNCE_INTERVAL (3 * WNR2000V4_KEYS_POLL_INTERVAL) -+ -+ -+/* ART offsets */ -+#define WNR2000V4_MAC0_OFFSET 0 /* WAN/WLAN0 MAC */ -+#define WNR2000V4_MAC1_OFFSET 6 /* Eth-switch0 MAC */ -+ -+static struct gpio_led wnr2000v4_leds_gpio[] __initdata = { -+ { -+ .name = "netgear:green:power", -+ .gpio = WNR2000V4_GPIO_LED_PWR_GREEN, -+ .active_low = 1, -+ .default_trigger = "default-on", -+ }, -+ { -+ .name = "netgear:amber:status", -+ .gpio = WNR2000V4_GPIO_LED_PWR_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:green:wan", -+ .gpio = WNR2000V4_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:amber:wan", -+ .gpio = WNR2000V4_GPIO_LED_WAN_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:blue:wlan", -+ .gpio = WNR2000V4_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+ /* LAN LEDS */ -+ { -+ .name = "netgear:green:lan1", -+ .gpio = WNR2000V4_GPIO_LED_LAN1_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:green:lan2", -+ .gpio = WNR2000V4_GPIO_LED_LAN2_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:green:lan3", -+ .gpio = WNR2000V4_GPIO_LED_LAN3_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:green:lan4", -+ .gpio = WNR2000V4_GPIO_LED_LAN4_GREEN, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:amber:lan1", -+ .gpio = WNR2000V4_GPIO_LED_LAN1_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:amber:lan2", -+ .gpio = WNR2000V4_GPIO_LED_LAN2_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:amber:lan3", -+ .gpio = WNR2000V4_GPIO_LED_LAN3_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:amber:lan4", -+ .gpio = WNR2000V4_GPIO_LED_LAN4_AMBER, -+ .active_low = 1, -+ }, -+ { -+ .name = "netgear:green:wps", -+ .gpio = WNR2000V4_GPIO_LED_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button wnr2000v4_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WNR2000V4_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR2000V4_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WNR2000V4_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR2000V4_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+ { -+ .desc = "WLAN button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = WNR2000V4_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR2000V4_GPIO_BTN_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init wnr_common_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_register_usb(); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art+WNR2000V4_MAC0_OFFSET, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art+WNR2000V4_MAC1_OFFSET, 0); -+ -+ /* GMAC0 is connected to the PHY0 of the internal switch, GE0 */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_switch_data.phy_poll_mask = BIT(4); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the internal switch, GE1 */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(ee, art); -+} -+ -+static void __init wnr2000v4_setup(void) -+{ -+ int i; -+ -+ wnr_common_setup(); -+ -+ /* Ensure no LED has an internal MUX signal, otherwise -+ control of LED could be lost... This is especially important -+ for most green LEDS (Eth,WAN).. who arrive in this function with -+ MUX signals set. */ -+ for (i = 0; i < ARRAY_SIZE(wnr2000v4_leds_gpio); i++) -+ ath79_gpio_output_select(wnr2000v4_leds_gpio[i].gpio, -+ AR934X_GPIO_OUT_GPIO); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wnr2000v4_leds_gpio), -+ wnr2000v4_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, WNR2000V4_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wnr2000v4_gpio_keys), -+ wnr2000v4_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WNR2000_V4, "WNR2000V4", "NETGEAR WNR2000 V4", wnr2000v4_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2000.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2000.c -new file mode 100644 -index 0000000000..6e3becab3a ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2000.c -@@ -0,0 +1,102 @@ -+/* -+ * NETGEAR WNR2000 board support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * Copyright (C) 2008-2009 Andy Boyett -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define WNR2000_GPIO_LED_PWR_GREEN 14 -+#define WNR2000_GPIO_LED_PWR_AMBER 7 -+#define WNR2000_GPIO_LED_WPS 4 -+#define WNR2000_GPIO_LED_WLAN 6 -+#define WNR2000_GPIO_BTN_RESET 21 -+#define WNR2000_GPIO_BTN_WPS 8 -+ -+#define WNR2000_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WNR2000_KEYS_DEBOUNCE_INTERVAL (3 * WNR2000_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led wnr2000_leds_gpio[] __initdata = { -+ { -+ .name = "netgear:green:power", -+ .gpio = WNR2000_GPIO_LED_PWR_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:power", -+ .gpio = WNR2000_GPIO_LED_PWR_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:wps", -+ .gpio = WNR2000_GPIO_LED_WPS, -+ .active_low = 1, -+ }, { -+ .name = "netgear:blue:wlan", -+ .gpio = WNR2000_GPIO_LED_WLAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button wnr2000_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WNR2000_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR2000_GPIO_BTN_RESET, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WNR2000_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR2000_GPIO_BTN_WPS, -+ } -+}; -+ -+static void __init wnr2000_setup(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, eeprom, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.has_ar8216 = 1; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, eeprom, 1); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth1_data.phy_mask = 0x10; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wnr2000_leds_gpio), -+ wnr2000_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, WNR2000_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wnr2000_gpio_keys), -+ wnr2000_gpio_keys); -+ -+ ath79_register_wmac(eeprom, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WNR2000, "WNR2000", "NETGEAR WNR2000", wnr2000_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2200.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2200.c -new file mode 100644 -index 0000000000..74166c5376 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2200.c -@@ -0,0 +1,246 @@ -+/* -+ * NETGEAR WNR2200 board support -+ * -+ * Copyright (C) 2013 Aidan Kissane -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include -+#include -+#include /* for max() macro */ -+ -+#include -+#include /* needed to disable switch LEDs */ -+#include "common.h" /* needed to disable switch LEDs */ -+ -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+ -+/* WNR2200 - connected through AR7241 */ -+#define WNR2200_GPIO_LED_LAN2_AMBER 0 -+#define WNR2200_GPIO_LED_LAN4_AMBER 1 -+#define WNR2200_GPIO_LED_LAN1_AMBER 6 /* AR724X_GPIO_FUNC_JTAG_DISABLE */ -+#define WNR2200_GPIO_LED_WPS_GREEN 7 /* AR724X_GPIO_FUNC_JTAG_DISABLE */ -+#define WNR2200_GPIO_LED_USB_GREEN 8 /* AR724X_GPIO_FUNC_JTAG_DISABLE */ -+#define WNR2200_GPIO_LED_LAN3_AMBER 11 -+#define WNR2200_GPIO_LED_WAN_AMBER 12 -+#define WNR2200_GPIO_LED_LAN1_GREEN 13 /* AR724X_..._ETH_SWITCH_LED0 */ -+#define WNR2200_GPIO_LED_LAN2_GREEN 14 /* AR724X_..._ETH_SWITCH_LED1 */ -+#define WNR2200_GPIO_LED_LAN3_GREEN 15 /* AR724X_..._ETH_SWITCH_LED2 */ -+#define WNR2200_GPIO_LED_LAN4_GREEN 16 /* AR724X_..._ETH_SWITCH_LED3 */ -+#define WNR2200_GPIO_LED_WAN_GREEN 17 /* AR724X_..._ETH_SWITCH_LED4 */ -+ -+/* WNR2200 - connected through AR9287 */ -+#define WNR2200_GPIO_WMAC_LED_WLAN_BLUE 0 -+#define WNR2200_GPIO_WMAC_LED_TEST_AMBER 1 -+#define WNR2200_GPIO_WMAC_LED_POWER_GREEN 2 -+#define WNR2200_GPIO_WMAC_BTN_RFKILL 3 -+#define WNR2200_GPIO_WMAC_USB_5V 4 -+#define WNR2200_GPIO_WMAC_BTN_WPS 5 -+#define WNR2200_GPIO_WMAC_BTN_RESET 6 -+ -+#define WNR2200_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WNR2200_KEYS_DEBOUNCE_INTERVAL (3 * WNR2200_KEYS_POLL_INTERVAL) -+ -+#define WNR2200_MAC0_OFFSET 0 -+#define WNR2200_MAC1_OFFSET 6 -+#define WNR2200_PCIE_CALDATA_OFFSET 0x1000 -+#define WNR2200_WMAC_OFFSET 0x108c /* wireless MAC is inside ART */ -+ -+static struct gpio_led wnr2200_leds_gpio[] __initdata = { -+ { -+ .name = "netgear:amber:lan1", -+ .gpio = WNR2200_GPIO_LED_LAN1_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:lan2", -+ .gpio = WNR2200_GPIO_LED_LAN2_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:lan3", -+ .gpio = WNR2200_GPIO_LED_LAN3_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:lan4", -+ .gpio = WNR2200_GPIO_LED_LAN4_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:amber:wan", -+ .gpio = WNR2200_GPIO_LED_WAN_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan1", -+ .gpio = WNR2200_GPIO_LED_LAN1_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan2", -+ .gpio = WNR2200_GPIO_LED_LAN2_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan3", -+ .gpio = WNR2200_GPIO_LED_LAN3_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:lan4", -+ .gpio = WNR2200_GPIO_LED_LAN4_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:usb", -+ .gpio = WNR2200_GPIO_LED_USB_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:wan", -+ .gpio = WNR2200_GPIO_LED_WAN_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:wps", -+ .gpio = WNR2200_GPIO_LED_WPS_GREEN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led wnr2200_wmac_leds_gpio[] = { -+ { -+ .name = "netgear:amber:test", -+ .gpio = WNR2200_GPIO_WMAC_LED_TEST_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "netgear:green:power", -+ .gpio = WNR2200_GPIO_WMAC_LED_POWER_GREEN, -+ .active_low = 1, -+ .default_state = LEDS_GPIO_DEFSTATE_ON, -+ }, { -+ .name = "netgear:blue:wlan", -+ .gpio = WNR2200_GPIO_WMAC_LED_WLAN_BLUE, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button wnr2200_wmac_keys_gpio[] = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WNR2200_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR2200_GPIO_WMAC_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "rfkill", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = WNR2200_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR2200_GPIO_WMAC_BTN_RFKILL, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WNR2200_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WNR2200_GPIO_WMAC_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+/* -+ * For WNR2200 ART flash area used for WLAN MAC is usually empty (0xff) -+ * so ath9k driver uses random MAC instead each time module is loaded. -+ * OpenWrt's original fix was to copy eth1 address to WLAN interface. -+ * New solution does not duplicate hardware addresses and is taken from -+ * WNR2000v3 code. It assigns permanent WLAN MAC equal to ethN's MAC -+ * plus 1, so network interfaces get sequential addresses. -+ * If ART wireless MAC address field has been filled by user, use it. -+ */ -+static void __init wnr2200_get_wmac(u8 *wmac_gen_addr, int mac0_art_offset, -+ int mac1_art_offset, int wmac_art_offset) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *eth0_mac_addr = (u8 *) (art + mac0_art_offset); -+ u8 *eth1_mac_addr = (u8 *) (art + mac1_art_offset); -+ u8 *wlan_mac_addr = (u8 *) (art + wmac_art_offset); -+ -+ /* only 0xff if all bits are set - address is invalid, empty area */ -+ if ((wlan_mac_addr[0] & wlan_mac_addr[1] & wlan_mac_addr[2] & -+ wlan_mac_addr[3] & wlan_mac_addr[4] & wlan_mac_addr[5]) == 0xff) { -+ memcpy(wmac_gen_addr, eth0_mac_addr, 5); -+ wmac_gen_addr[5] = max(eth0_mac_addr[5], eth1_mac_addr[5]) + 1; -+ -+ /* Avoid potential conflict in case max(0xff,0x00)+1==0x00 */ -+ if (!wmac_gen_addr[5]) -+ wmac_gen_addr[5] = 1; -+ } else -+ memcpy(wmac_gen_addr, wlan_mac_addr, 6); -+} -+ -+static void __init wnr2200_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 wlan_mac_addr[6]; -+ -+ /* -+ * Disable JTAG to use all AR724X GPIO LEDs. Disable CLKs. -+ * Allow OS to control all link LEDs. -+ */ -+ ath79_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE | -+ AR724X_GPIO_FUNC_UART_EN, -+ AR724X_GPIO_FUNC_CLK_OBS1_EN | -+ AR724X_GPIO_FUNC_CLK_OBS2_EN | -+ AR724X_GPIO_FUNC_CLK_OBS3_EN | -+ AR724X_GPIO_FUNC_CLK_OBS4_EN | -+ AR724X_GPIO_FUNC_CLK_OBS5_EN | -+ AR724X_GPIO_FUNC_GE0_MII_CLK_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + WNR2200_MAC0_OFFSET, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + WNR2200_MAC1_OFFSET, 0); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth1_data.phy_mask = 0x10; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_m25p80(NULL); -+ -+ wnr2200_get_wmac(wlan_mac_addr, WNR2200_MAC0_OFFSET, -+ WNR2200_MAC1_OFFSET, WNR2200_WMAC_OFFSET); -+ ap9x_pci_setup_wmac_led_pin(0, 0); -+ ap91_pci_init(art + WNR2200_PCIE_CALDATA_OFFSET, wlan_mac_addr); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wnr2200_leds_gpio), -+ wnr2200_leds_gpio); -+ -+ ap9x_pci_setup_wmac_leds(0, wnr2200_wmac_leds_gpio, -+ ARRAY_SIZE(wnr2200_wmac_leds_gpio)); -+ -+ /* All 3 buttons are connected to wireless chip */ -+ ap9x_pci_setup_wmac_btns(0, wnr2200_wmac_keys_gpio, -+ ARRAY_SIZE(wnr2200_wmac_keys_gpio), -+ WNR2200_KEYS_POLL_INTERVAL); -+ -+ /* enable power for the USB port */ -+ ap9x_pci_setup_wmac_gpio(0, BIT(WNR2200_GPIO_WMAC_USB_5V), -+ BIT(WNR2200_GPIO_WMAC_USB_5V)); -+ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WNR2200, "WNR2200", "NETGEAR WNR2200", wnr2200_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wp543.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wp543.c -new file mode 100644 -index 0000000000..dc4aee0c1b ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wp543.c -@@ -0,0 +1,109 @@ -+/* -+ * Compex WP543/WPJ543 board support -+ * -+ * Copyright (C) 2008-2012 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define WP543_GPIO_SW6 2 -+#define WP543_GPIO_LED_1 3 -+#define WP543_GPIO_LED_2 4 -+#define WP543_GPIO_LED_WLAN 5 -+#define WP543_GPIO_LED_CONN 6 -+#define WP543_GPIO_LED_DIAG 7 -+#define WP543_GPIO_SW4 8 -+ -+#define WP543_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WP543_KEYS_DEBOUNCE_INTERVAL (3 * WP543_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led wp543_leds_gpio[] __initdata = { -+ { -+ .name = "wp543:green:led1", -+ .gpio = WP543_GPIO_LED_1, -+ .active_low = 1, -+ }, { -+ .name = "wp543:green:led2", -+ .gpio = WP543_GPIO_LED_2, -+ .active_low = 1, -+ }, { -+ .name = "wp543:green:wlan", -+ .gpio = WP543_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "wp543:green:conn", -+ .gpio = WP543_GPIO_LED_CONN, -+ .active_low = 1, -+ }, { -+ .name = "wp543:green:diag", -+ .gpio = WP543_GPIO_LED_DIAG, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button wp543_gpio_keys[] __initdata = { -+ { -+ .desc = "sw6", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .debounce_interval = WP543_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WP543_GPIO_SW6, -+ .active_low = 1, -+ }, { -+ .desc = "sw4", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WP543_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WP543_GPIO_SW4, -+ .active_low = 1, -+ } -+}; -+ -+static const char *wp543_part_probes[] = { -+ "MyLoader", -+ NULL, -+}; -+ -+static struct flash_platform_data wp543_flash_data = { -+ .part_probes = wp543_part_probes, -+}; -+ -+static void __init wp543_setup(void) -+{ -+ ath79_register_m25p80(&wp543_flash_data); -+ -+ ath79_register_mdio(0, 0xfffffff0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = 0x0f; -+ ath79_eth0_data.reset_bit = AR71XX_RESET_GE0_MAC | -+ AR71XX_RESET_GE0_PHY; -+ ath79_register_eth(0); -+ -+ ath79_register_usb(); -+ ath79_register_pci(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wp543_leds_gpio), -+ wp543_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, WP543_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wp543_gpio_keys), -+ wp543_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WP543, "WP543", "Compex WP543", wp543_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wpe72.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wpe72.c -new file mode 100644 -index 0000000000..9452484279 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wpe72.c -@@ -0,0 +1,97 @@ -+/* -+ * Compex WPE72 board support -+ * -+ * Copyright (C) 2012 Johnathan Boyce -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define WPE72_GPIO_RESET 12 -+#define WPE72_GPIO_LED_DIAG 13 -+#define WPE72_GPIO_LED_1 14 -+#define WPE72_GPIO_LED_2 15 -+#define WPE72_GPIO_LED_3 16 -+#define WPE72_GPIO_LED_4 17 -+ -+#define WPE72_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WPE72_KEYS_DEBOUNCE_INTERVAL (3 * WPE72_KEYS_POLL_INTERVAL) -+ -+static struct gpio_led wpe72_leds_gpio[] __initdata = { -+ { -+ .name = "wpe72:green:led1", -+ .gpio = WPE72_GPIO_LED_1, -+ .active_low = 1, -+ }, { -+ .name = "wpe72:green:led2", -+ .gpio = WPE72_GPIO_LED_2, -+ .active_low = 1, -+ }, { -+ .name = "wpe72:green:led3", -+ .gpio = WPE72_GPIO_LED_3, -+ .active_low = 1, -+ }, { -+ .name = "wpe72:green:led4", -+ .gpio = WPE72_GPIO_LED_4, -+ .active_low = 1, -+ }, { -+ .name = "wpe72:green:diag", -+ .gpio = WPE72_GPIO_LED_DIAG, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button wpe72_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WPE72_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WPE72_GPIO_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static const char *wpe72_part_probes[] = { -+ "MyLoader", -+ NULL, -+}; -+ -+static struct flash_platform_data wpe72_flash_data = { -+ .part_probes = wpe72_part_probes, -+}; -+ -+static void __init wpe72_setup(void) -+{ -+ ath79_register_m25p80(&wpe72_flash_data); -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_usb(); -+ ath79_register_pci(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wpe72_leds_gpio), -+ wpe72_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, WPE72_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wpe72_gpio_keys), -+ wpe72_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WPE72, "WPE72", "Compex WPE72", wpe72_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wpj342.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wpj342.c -new file mode 100644 -index 0000000000..65d6478867 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wpj342.c -@@ -0,0 +1,178 @@ -+/* -+ * Compex WPJ342 board support -+ * -+ * Copyright (c) 2011 Qualcomm Atheros -+ * Copyright (c) 2011-2012 Gabor Juhos -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "pci.h" -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-nfc.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define WPJ342_GPIO_LED_STATUS 11 -+#define WPJ342_GPIO_LED_SIG1 14 -+#define WPJ342_GPIO_LED_SIG2 13 -+#define WPJ342_GPIO_LED_SIG3 12 -+#define WPJ342_GPIO_LED_SIG4 11 -+#define WPJ342_GPIO_BUZZER 15 -+ -+#define WPJ342_GPIO_BTN_RESET 17 -+ -+#define WPJ342_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WPJ342_KEYS_DEBOUNCE_INTERVAL (3 * WPJ342_KEYS_POLL_INTERVAL) -+ -+#define WPJ342_MAC0_OFFSET 0x10 -+#define WPJ342_MAC1_OFFSET 0x18 -+#define WPJ342_WMAC_CALDATA_OFFSET 0x1000 -+#define WPJ342_PCIE_CALDATA_OFFSET 0x5000 -+ -+#define WPJ342_ART_SIZE 0x8000 -+ -+static struct gpio_led wpj342_leds_gpio[] __initdata = { -+ { -+ .name = "wpj342:red:sig1", -+ .gpio = WPJ342_GPIO_LED_SIG1, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj342:yellow:sig2", -+ .gpio = WPJ342_GPIO_LED_SIG2, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj342:green:sig3", -+ .gpio = WPJ342_GPIO_LED_SIG3, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj342:green:sig4", -+ .gpio = WPJ342_GPIO_LED_SIG4, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj342:buzzer", -+ .gpio = WPJ342_GPIO_BUZZER, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button wpj342_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WPJ342_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WPJ342_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg wpj342_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_led_cfg wpj342_ar8327_led_cfg = { -+ .led_ctrl0 = 0x00000000, -+ .led_ctrl1 = 0xc737c737, -+ .led_ctrl2 = 0x00000000, -+ .led_ctrl3 = 0x00c30c00, -+ .open_drain = true, -+}; -+ -+static struct ar8327_platform_data wpj342_ar8327_data = { -+ .pad0_cfg = &wpj342_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &wpj342_ar8327_led_cfg, -+}; -+ -+static struct mdio_board_info wpj342_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &wpj342_ar8327_data, -+ }, -+}; -+ -+ -+static void __init wpj342_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f02e000); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wpj342_leds_gpio), -+ wpj342_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, WPJ342_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wpj342_gpio_keys), -+ wpj342_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_register_wmac(art + WPJ342_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_pci(); -+ -+ mdiobus_register_board_info(wpj342_mdio0_info, -+ ARRAY_SIZE(wpj342_mdio0_info)); -+ -+ ath79_register_mdio(1, 0x0); -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac + WPJ342_MAC0_OFFSET, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac + WPJ342_MAC1_OFFSET, 0); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_MII_GMAC0); -+ -+ /* GMAC0 is connected to an AR8236 switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WPJ342, "WPJ342", "Compex WPJ342", wpj342_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wpj344.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wpj344.c -new file mode 100644 -index 0000000000..ffb9ef6dfa ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wpj344.c -@@ -0,0 +1,169 @@ -+/* -+ * Compex WPJ344 board support -+ * -+ * Copyright (c) 2011 Qualcomm Atheros -+ * Copyright (c) 2011-2012 Gabor Juhos -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-usb.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define WPJ344_GPIO_LED_SIG1 15 -+#define WPJ344_GPIO_LED_SIG2 20 -+#define WPJ344_GPIO_LED_SIG3 21 -+#define WPJ344_GPIO_LED_SIG4 22 -+#define WPJ344_GPIO_LED_STATUS 14 -+ -+#define WPJ344_GPIO_BTN_RESET 12 -+ -+#define WPJ344_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WPJ344_KEYS_DEBOUNCE_INTERVAL (3 * WPJ344_KEYS_POLL_INTERVAL) -+ -+#define WPJ344_MAC0_OFFSET 0x10 -+#define WPJ344_MAC1_OFFSET 0x18 -+#define WPJ344_WMAC_CALDATA_OFFSET 0x1000 -+#define WPJ344_PCIE_CALDATA_OFFSET 0x5000 -+ -+static struct gpio_led wpj344_leds_gpio[] __initdata = { -+ { -+ .name = "wpj344:green:status", -+ .gpio = WPJ344_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj344:red:sig1", -+ .gpio = WPJ344_GPIO_LED_SIG1, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj344:yellow:sig2", -+ .gpio = WPJ344_GPIO_LED_SIG2, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj344:green:sig3", -+ .gpio = WPJ344_GPIO_LED_SIG3, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj344:green:sig4", -+ .gpio = WPJ344_GPIO_LED_SIG4, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button wpj344_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WPJ344_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WPJ344_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg wpj344_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+ .mac06_exchange_dis = true, -+}; -+ -+static struct ar8327_led_cfg wpj344_ar8327_led_cfg = { -+ .led_ctrl0 = 0x00000000, -+ .led_ctrl1 = 0xc737c737, -+ .led_ctrl2 = 0x00000000, -+ .led_ctrl3 = 0x00c30c00, -+ .open_drain = true, -+}; -+ -+static struct ar8327_platform_data wpj344_ar8327_data = { -+ .pad0_cfg = &wpj344_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &wpj344_ar8327_led_cfg, -+}; -+ -+static struct mdio_board_info wpj344_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &wpj344_ar8327_data, -+ }, -+}; -+ -+static void __init wpj344_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f02e000); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wpj344_leds_gpio), -+ wpj344_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, WPJ344_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wpj344_gpio_keys), -+ wpj344_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_register_wmac(art + WPJ344_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_pci(); -+ -+ mdiobus_register_board_info(wpj344_mdio0_info, -+ ARRAY_SIZE(wpj344_mdio0_info)); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac + WPJ344_MAC0_OFFSET, 0); -+ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ /* GMAC0 is connected to an AR8327 switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WPJ344, "WPJ344", "Compex WPJ344", wpj344_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wpj531.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wpj531.c -new file mode 100644 -index 0000000000..351293230f ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wpj531.c -@@ -0,0 +1,143 @@ -+/* -+ * Compex WPJ531 board support -+ * -+ * Copyright (c) 2012 Qualcomm Atheros -+ * Copyright (c) 2012 Gabor Juhos -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "pci.h" -+#include "common.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define WPJ531_GPIO_LED_SIG1 12 -+#define WPJ531_GPIO_LED_SIG2 14 -+#define WPJ531_GPIO_LED_SIG3 15 -+#define WPJ531_GPIO_LED_SIG4 16 -+#define WPJ531_GPIO_BUZZER 4 -+ -+#define WPJ531_GPIO_BTN_RESET 17 -+ -+#define WPJ531_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WPJ531_KEYS_DEBOUNCE_INTERVAL (3 * WPJ531_KEYS_POLL_INTERVAL) -+ -+#define WPJ531_MAC0_OFFSET 0x10 -+#define WPJ531_MAC1_OFFSET 0x18 -+#define WPJ531_WMAC_CALDATA_OFFSET 0x1000 -+#define WPJ531_PCIE_CALDATA_OFFSET 0x5000 -+ -+#define WPJ531_ART_SIZE 0x8000 -+ -+static struct gpio_led wpj531_leds_gpio[] __initdata = { -+ { -+ .name = "wpj531:red:sig1", -+ .gpio = WPJ531_GPIO_LED_SIG1, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj531:yellow:sig2", -+ .gpio = WPJ531_GPIO_LED_SIG2, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj531:green:sig3", -+ .gpio = WPJ531_GPIO_LED_SIG3, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj531:green:sig4", -+ .gpio = WPJ531_GPIO_LED_SIG4, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj531:buzzer", -+ .gpio = WPJ531_GPIO_BUZZER, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button wpj531_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WPJ531_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WPJ531_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init common_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f02e000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN */ -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac + WPJ531_MAC0_OFFSET, 0); -+ ath79_register_eth(0); -+ -+ /* WAN */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac + WPJ531_MAC1_OFFSET, 0); -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(art + WPJ531_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_pci(); -+ ath79_register_usb(); -+} -+ -+static void __init wpj531_setup(void) -+{ -+ common_setup(); -+ -+ ath79_register_leds_gpio(-1, -+ ARRAY_SIZE(wpj531_leds_gpio), -+ wpj531_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, -+ WPJ531_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wpj531_gpio_keys), -+ wpj531_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WPJ531, "WPJ531", "Compex WPJ531", wpj531_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wpj558.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wpj558.c -new file mode 100644 -index 0000000000..1839cc6676 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wpj558.c -@@ -0,0 +1,170 @@ -+/* -+ * Compex WPJ558 board support -+ * -+ * Copyright (c) 2012 Qualcomm Atheros -+ * Copyright (c) 2012-2013 Gabor Juhos -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "pci.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-eth.h" -+#include "dev-usb.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define WPJ558_GPIO_LED_SIG1 14 -+#define WPJ558_GPIO_LED_SIG2 15 -+#define WPJ558_GPIO_LED_SIG3 22 -+#define WPJ558_GPIO_LED_SIG4 23 -+#define WPJ558_GPIO_BUZZER 4 -+ -+#define WPJ558_GPIO_BTN_RESET 17 -+ -+#define WPJ558_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WPJ558_KEYS_DEBOUNCE_INTERVAL (3 * WPJ558_KEYS_POLL_INTERVAL) -+ -+#define WPJ558_MAC_OFFSET 0x10 -+#define WPJ558_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led wpj558_leds_gpio[] __initdata = { -+ { -+ .name = "wpj558:red:sig1", -+ .gpio = WPJ558_GPIO_LED_SIG1, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj558:yellow:sig2", -+ .gpio = WPJ558_GPIO_LED_SIG2, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj558:green:sig3", -+ .gpio = WPJ558_GPIO_LED_SIG3, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj558:green:sig4", -+ .gpio = WPJ558_GPIO_LED_SIG4, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj558:buzzer", -+ .gpio = WPJ558_GPIO_BUZZER, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button wpj558_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WPJ558_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WPJ558_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg wpj558_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+static struct ar8327_pad_cfg wpj558_ar8327_pad6_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_platform_data wpj558_ar8327_data = { -+ .pad0_cfg = &wpj558_ar8327_pad0_cfg, -+ .pad6_cfg = &wpj558_ar8327_pad6_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .port6_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info wpj558_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &wpj558_ar8327_data, -+ }, -+}; -+ -+static void __init wpj558_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f02e000); -+ -+ ath79_register_m25p80(NULL); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wpj558_leds_gpio), -+ wpj558_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, WPJ558_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wpj558_gpio_keys), -+ wpj558_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_register_wmac(art + WPJ558_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_pci(); -+ -+ mdiobus_register_board_info(wpj558_mdio0_info, -+ ARRAY_SIZE(wpj558_mdio0_info)); -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac + WPJ558_MAC_OFFSET, 0); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ /* GMAC0 is connected to an AR8327 switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x56000000; -+ -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WPJ558, "WPJ558", "Compex WPJ558", wpj558_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wpj563.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wpj563.c -new file mode 100644 -index 0000000000..d884be916b ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wpj563.c -@@ -0,0 +1,150 @@ -+/* -+ * Compex WPJ563 board support -+ * -+ * Copyright (c) 2015 Qualcomm Atheros -+ * Copyright (c) 2012 Gabor Juhos -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+#include "pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+ -+#define WPJ563_GPIO_LED_SIG1 1 -+#define WPJ563_GPIO_LED_SIG2 5 -+#define WPJ563_GPIO_LED_SIG3 6 -+#define WPJ563_GPIO_LED_SIG4 7 -+#define WPJ563_GPIO_BUZZER 19 -+ -+#define WPJ563_GPIO_BTN_RESET 2 -+#define WPJ563_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WPJ563_KEYS_DEBOUNCE_INTERVAL (3 * WPJ563_KEYS_POLL_INTERVAL) -+ -+#define WPJ563_MAC0_OFFSET 0x10 -+#define WPJ563_MAC1_OFFSET 0x18 -+#define WPJ563_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led WPJ563_leds_gpio[] __initdata = { -+ { -+ .name = "wpj563:green:sig1", -+ .gpio = WPJ563_GPIO_LED_SIG1, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj563:green:sig2", -+ .gpio = WPJ563_GPIO_LED_SIG2, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj563:green:sig3", -+ .gpio = WPJ563_GPIO_LED_SIG3, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj563:green:sig4", -+ .gpio = WPJ563_GPIO_LED_SIG4, -+ .active_low = 1, -+ }, -+ { -+ .name = "wpj563:buzzer", -+ .gpio = WPJ563_GPIO_BUZZER, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_keys_button WPJ563_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WPJ563_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WPJ563_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ar8327_pad_cfg WPJ563_ar8337_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+static struct ar8327_platform_data WPJ563_ar8337_data = { -+ .pad0_cfg = &WPJ563_ar8337_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info WPJ563_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &WPJ563_ar8337_data, -+ }, -+}; -+ -+static void __init WPJ563_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f02e000); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(WPJ563_leds_gpio), -+ WPJ563_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, WPJ563_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(WPJ563_gpio_keys), -+ WPJ563_gpio_keys); -+ -+ ath79_register_usb(); -+ -+ ath79_register_wmac(art + WPJ563_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_pci(); -+ -+ mdiobus_register_board_info(WPJ563_mdio0_info, -+ ARRAY_SIZE(WPJ563_mdio0_info)); -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac + WPJ563_MAC0_OFFSET, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac + WPJ563_MAC1_OFFSET, 0); -+ -+ /* GMAC0 is connected to an QCA8334 switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WPJ563, "WPJ563", "Compex WPJ563", WPJ563_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wrt160nl.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wrt160nl.c -new file mode 100644 -index 0000000000..ede3c214c2 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wrt160nl.c -@@ -0,0 +1,126 @@ -+/* -+ * Linksys WRT160NL board support -+ * -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "nvram.h" -+#include "machtypes.h" -+ -+#define WRT160NL_GPIO_LED_POWER 14 -+#define WRT160NL_GPIO_LED_WPS_AMBER 9 -+#define WRT160NL_GPIO_LED_WPS_BLUE 8 -+#define WRT160NL_GPIO_LED_WLAN 6 -+ -+#define WRT160NL_GPIO_BTN_WPS 7 -+#define WRT160NL_GPIO_BTN_RESET 21 -+ -+#define WRT160NL_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WRT160NL_KEYS_DEBOUNCE_INTERVAL (3 * WRT160NL_KEYS_POLL_INTERVAL) -+ -+#define WRT160NL_NVRAM_ADDR 0x1f7e0000 -+#define WRT160NL_NVRAM_SIZE 0x10000 -+ -+static const char *wrt160nl_part_probes[] = { -+ "cybertan", -+ NULL, -+}; -+ -+static struct flash_platform_data wrt160nl_flash_data = { -+ .part_probes = wrt160nl_part_probes, -+}; -+ -+static struct gpio_led wrt160nl_leds_gpio[] __initdata = { -+ { -+ .name = "wrt160nl:blue:power", -+ .gpio = WRT160NL_GPIO_LED_POWER, -+ .active_low = 1, -+ .default_trigger = "default-on", -+ }, { -+ .name = "wrt160nl:amber:wps", -+ .gpio = WRT160NL_GPIO_LED_WPS_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "wrt160nl:blue:wps", -+ .gpio = WRT160NL_GPIO_LED_WPS_BLUE, -+ .active_low = 1, -+ }, { -+ .name = "wrt160nl:blue:wlan", -+ .gpio = WRT160NL_GPIO_LED_WLAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button wrt160nl_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WRT160NL_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WRT160NL_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WRT160NL_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WRT160NL_GPIO_BTN_WPS, -+ .active_low = 1, -+ } -+}; -+ -+static void __init wrt160nl_setup(void) -+{ -+ const char *nvram = (char *) KSEG1ADDR(WRT160NL_NVRAM_ADDR); -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 mac[6]; -+ -+ if (ath79_nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE, -+ "lan_hwaddr=", mac) == 0) { -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -+ } -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth0_data.phy_mask = 0x01; -+ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth1_data.phy_mask = 0x10; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_m25p80(&wrt160nl_flash_data); -+ -+ ath79_register_usb(); -+ -+ if (ath79_nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE, -+ "wl0_hwaddr=", mac) == 0) -+ ath79_register_wmac(eeprom, mac); -+ else -+ ath79_register_wmac(eeprom, NULL); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wrt160nl_leds_gpio), -+ wrt160nl_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, WRT160NL_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wrt160nl_gpio_keys), -+ wrt160nl_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WRT160NL, "WRT160NL", "Linksys WRT160NL", -+ wrt160nl_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wrt400n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wrt400n.c -new file mode 100644 -index 0000000000..6c4c1cb0d6 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wrt400n.c -@@ -0,0 +1,161 @@ -+/* -+ * Linksys WRT400N board support -+ * -+ * Copyright (C) 2009-2012 Gabor Juhos -+ * Copyright (C) 2009 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "machtypes.h" -+ -+#define WRT400N_GPIO_LED_POWER 1 -+#define WRT400N_GPIO_LED_WPS_BLUE 4 -+#define WRT400N_GPIO_LED_WPS_AMBER 5 -+#define WRT400N_GPIO_LED_WLAN 6 -+ -+#define WRT400N_GPIO_BTN_RESET 8 -+#define WRT400N_GPIO_BTN_WLSEC 3 -+ -+#define WRT400N_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WRT400N_KEYS_DEBOUNE_INTERVAL (3 * WRT400N_KEYS_POLL_INTERVAL) -+ -+#define WRT400N_MAC_ADDR_OFFSET 0x120c -+#define WRT400N_CALDATA0_OFFSET 0x1000 -+#define WRT400N_CALDATA1_OFFSET 0x5000 -+ -+static struct mtd_partition wrt400n_partitions[] = { -+ { -+ .name = "uboot", -+ .offset = 0, -+ .size = 0x030000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "env", -+ .offset = 0x030000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "linux", -+ .offset = 0x040000, -+ .size = 0x140000, -+ }, { -+ .name = "rootfs", -+ .offset = 0x180000, -+ .size = 0x630000, -+ }, { -+ .name = "nvram", -+ .offset = 0x7b0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "factory", -+ .offset = 0x7c0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "language", -+ .offset = 0x7d0000, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "caldata", -+ .offset = 0x7f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x040000, -+ .size = 0x770000, -+ } -+}; -+ -+static struct flash_platform_data wrt400n_flash_data = { -+ .parts = wrt400n_partitions, -+ .nr_parts = ARRAY_SIZE(wrt400n_partitions), -+}; -+ -+static struct gpio_led wrt400n_leds_gpio[] __initdata = { -+ { -+ .name = "wrt400n:blue:wps", -+ .gpio = WRT400N_GPIO_LED_WPS_BLUE, -+ .active_low = 1, -+ }, { -+ .name = "wrt400n:amber:wps", -+ .gpio = WRT400N_GPIO_LED_WPS_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "wrt400n:blue:wlan", -+ .gpio = WRT400N_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "wrt400n:blue:power", -+ .gpio = WRT400N_GPIO_LED_POWER, -+ .active_low = 0, -+ .default_trigger = "default-on", -+ } -+}; -+ -+static struct gpio_keys_button wrt400n_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WRT400N_KEYS_DEBOUNE_INTERVAL, -+ .gpio = WRT400N_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "wlsec", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WRT400N_KEYS_DEBOUNE_INTERVAL, -+ .gpio = WRT400N_GPIO_BTN_WLSEC, -+ .active_low = 1, -+ } -+}; -+ -+static void __init wrt400n_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac = art + WRT400N_MAC_ADDR_OFFSET; -+ -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 2); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ath79_eth1_data.phy_mask = 0x10; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_m25p80(&wrt400n_flash_data); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wrt400n_leds_gpio), -+ wrt400n_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, WRT400N_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wrt400n_gpio_keys), -+ wrt400n_gpio_keys); -+ -+ ap94_pci_init(art + WRT400N_CALDATA0_OFFSET, NULL, -+ art + WRT400N_CALDATA1_OFFSET, NULL); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WRT400N, "WRT400N", "Linksys WRT400N", wrt400n_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wrtnode2q.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wrtnode2q.c -new file mode 100644 -index 0000000000..150a28b0d7 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wrtnode2q.c -@@ -0,0 +1,126 @@ -+/* -+ * WRTnode2Q board support -+ * -+ * Copyright (c) 2013 The Linux Foundation. All rights reserved. -+ * Copyright (c) 2012 Gabor Juhos -+ * Copyright (c) 2015 Kelei -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+#include "pci.h" -+ -+#define WRTNODE2Q_GPIO_LED_WLAN 12 -+#define WRTNODE2Q_GPIO_LED_WPS 13 -+#define WRTNODE2Q_GPIO_LED_STATUS 13 -+ -+#define WRTNODE2Q_GPIO_LED_WAN 4 -+#define WRTNODE2Q_GPIO_LED_LAN1 16 -+#define WRTNODE2Q_GPIO_LED_LAN2 15 -+#define WRTNODE2Q_GPIO_LED_LAN3 14 -+#define WRTNODE2Q_GPIO_LED_LAN4 11 -+ -+#define WRTNODE2Q_GPIO_BTN_WPS 17 -+ -+#define WRTNODE2Q_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WRTNODE2Q_KEYS_DEBOUNCE_INTERVAL (3 * WRTNODE2Q_KEYS_POLL_INTERVAL) -+ -+#define WRTNODE2Q_MAC0_OFFSET 0 -+#define WRTNODE2Q_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led wrtnode2q_leds_gpio[] __initdata = { -+ { -+ .name = "wrtnode2q:green:status", -+ .gpio = WRTNODE2Q_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, -+ { -+ .name = "wrtnode2q:green:wlan", -+ .gpio = WRTNODE2Q_GPIO_LED_WLAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button wrtnode2q_gpio_keys[] __initdata = { -+ { -+ .desc = "WPS button", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WRTNODE2Q_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WRTNODE2Q_GPIO_BTN_WPS, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init wrtnode2q_gpio_led_setup(void) -+{ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wrtnode2q_leds_gpio), -+ wrtnode2q_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, WRTNODE2Q_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wrtnode2q_gpio_keys), -+ wrtnode2q_gpio_keys); -+} -+ -+static void __init wrtnode2q_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1f040000); -+ -+ ath79_register_m25p80(NULL); -+ -+ wrtnode2q_gpio_led_setup(); -+ -+ ath79_register_pci(); -+ ath79_register_usb(); -+ -+ ath79_register_wmac(art + WRTNODE2Q_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_mdio(0, 0x0); -+ ath79_register_mdio(1, 0x0); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, art + WRTNODE2Q_MAC0_OFFSET, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, art + WRTNODE2Q_MAC0_OFFSET, 1); -+ -+ /* LAN ports */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_register_eth(1); -+ -+ /* WAN port */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_register_eth(0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WRTNODE2Q, "WRTNODE2Q", "WRTnode2Q board", -+ wrtnode2q_setup); -\ No newline at end of file -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-450hp2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-450hp2.c -new file mode 100644 -index 0000000000..ca45309487 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-450hp2.c -@@ -0,0 +1,221 @@ -+/* -+ * Buffalo WZR-450HP2 board support -+ * -+ * Copyright (c) 2013 Gabor Juhos -+ * -+ * Based on the Qualcomm Atheros AP135/AP136 reference board support code -+ * Copyright (c) 2012 Qualcomm Atheros -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-spi.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define WZR_450HP2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WZR_450HP2_KEYS_DEBOUNCE_INTERVAL (3 * WZR_450HP2_KEYS_POLL_INTERVAL) -+ -+#define WZR_450HP2_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct mtd_partition wzrhpg450h_partitions[] = { -+ { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x0040000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "u-boot-env", -+ .offset = 0x0040000, -+ .size = 0x0010000, -+ }, { -+ .name = "ART", -+ .offset = 0x0ff0000, -+ .size = 0x0010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x0050000, -+ .size = 0x0f90000, -+ }, { -+ .name = "user_property", -+ .offset = 0x0fe0000, -+ .size = 0x0010000, -+ } -+}; -+ -+static struct flash_platform_data wzr_450hp2_flash_data = { -+ .parts = wzrhpg450h_partitions, -+ .nr_parts = ARRAY_SIZE(wzrhpg450h_partitions), -+}; -+ -+static struct gpio_led wzr_450hp2_leds_gpio[] __initdata = { -+ { -+ .name = "buffalo:green:wps", -+ .gpio = 3, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:green:system", -+ .gpio = 20, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:green:wlan", -+ .gpio = 18, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button wzr_450hp2_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WZR_450HP2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 17, -+ .active_low = 1, -+ }, -+ { -+ .desc = "RFKILL button", -+ .type = EV_KEY, -+ .code = KEY_RFKILL, -+ .debounce_interval = WZR_450HP2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 21, -+ .active_low = 1, -+ }, -+}; -+ -+static const struct ar8327_led_info wzr_450hp2_leds_ar8327[] = { -+ AR8327_LED_INFO(PHY0_0, HW, "buffalo:green:lan1"), -+ AR8327_LED_INFO(PHY1_0, HW, "buffalo:green:lan2"), -+ AR8327_LED_INFO(PHY2_0, HW, "buffalo:green:lan3"), -+ AR8327_LED_INFO(PHY3_0, HW, "buffalo:green:lan4"), -+ AR8327_LED_INFO(PHY4_0, HW, "buffalo:green:wan"), -+}; -+ -+/* GMAC0 of the AR8327 switch is connected to the QCA9558 SoC via SGMII */ -+static struct ar8327_pad_cfg wzr_450hp2_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_SGMII, -+ .sgmii_delay_en = true, -+}; -+ -+/* GMAC6 of the AR8327 switch is connected to the QCA9558 SoC via RGMII */ -+static struct ar8327_pad_cfg wzr_450hp2_ar8327_pad6_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_led_cfg wzr_450hp2_ar8327_led_cfg = { -+ .led_ctrl0 = 0xcc35cc35, -+ .led_ctrl1 = 0xca35ca35, -+ .led_ctrl2 = 0xc935c935, -+ .led_ctrl3 = 0x03ffff00, -+ .open_drain = true, -+}; -+ -+static struct ar8327_platform_data wzr_450hp2_ar8327_data = { -+ .pad0_cfg = &wzr_450hp2_ar8327_pad0_cfg, -+ .pad6_cfg = &wzr_450hp2_ar8327_pad6_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .port6_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+ .led_cfg = &wzr_450hp2_ar8327_led_cfg, -+ .num_leds = ARRAY_SIZE(wzr_450hp2_leds_ar8327), -+ .leds = wzr_450hp2_leds_ar8327, -+}; -+ -+static struct mdio_board_info wzr_450hp2_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = 0, -+ .platform_data = &wzr_450hp2_ar8327_data, -+ }, -+}; -+ -+static void __init wzr_450hp2_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ u8 *mac_wan = art; -+ u8 *mac_lan = mac_wan + ETH_ALEN; -+ -+ ath79_register_m25p80(&wzr_450hp2_flash_data); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wzr_450hp2_leds_gpio), -+ wzr_450hp2_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, WZR_450HP2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wzr_450hp2_gpio_keys), -+ wzr_450hp2_gpio_keys); -+ -+ ath79_register_wmac(art + WZR_450HP2_WMAC_CALDATA_OFFSET, mac_lan); -+ -+ mdiobus_register_board_info(wzr_450hp2_mdio0_info, -+ ARRAY_SIZE(wzr_450hp2_mdio0_info)); -+ ath79_register_mdio(0, 0x0); -+ -+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+ /* GMAC0 is connected to the RMGII interface */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(0); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x56000000; -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac_wan, 0); -+ ath79_register_eth(0); -+ -+ /* GMAC1 is connected to the SGMII interface */ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -+ ath79_eth1_data.speed = SPEED_1000; -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_pll_data.pll_1000 = 0x03000101; -+ -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac_lan, 0); -+ ath79_register_eth(1); -+ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WZR_450HP2, "WZR-450HP2", -+ "Buffalo WZR-450HP2", wzr_450hp2_setup); -+ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-ag300h.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-ag300h.c -new file mode 100644 -index 0000000000..a9ed3fdd46 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-ag300h.c -@@ -0,0 +1,202 @@ -+/* -+ * Buffalo WZR-HP-AG300H board support -+ * -+ * Copyright (C) 2011 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+ -+#define WZRHPAG300H_MAC_OFFSET 0x20c -+#define WZRHPAG300H_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL (3 * WZRHPAG300H_KEYS_POLL_INTERVAL) -+ -+static struct mtd_partition wzrhpag300h_flash_partitions[] = { -+ { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x0040000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "u-boot-env", -+ .offset = 0x0040000, -+ .size = 0x0010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "art", -+ .offset = 0x0050000, -+ .size = 0x0010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x0060000, -+ .size = 0x1f90000, -+ }, { -+ .name = "user_property", -+ .offset = 0x1ff0000, -+ .size = 0x0010000, -+ .mask_flags = MTD_WRITEABLE, -+ } -+}; -+ -+static struct flash_platform_data wzrhpag300h_flash_data = { -+ .parts = wzrhpag300h_flash_partitions, -+ .nr_parts = ARRAY_SIZE(wzrhpag300h_flash_partitions), -+}; -+ -+static struct gpio_led wzrhpag300h_leds_gpio[] __initdata = { -+ { -+ .name = "buffalo:red:diag", -+ .gpio = 1, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led wzrhpag300h_wmac0_leds_gpio[] = { -+ { -+ .name = "buffalo:amber:band2g", -+ .gpio = 1, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:green:usb", -+ .gpio = 3, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:green:band2g", -+ .gpio = 5, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led wzrhpag300h_wmac1_leds_gpio[] = { -+ { -+ .name = "buffalo:green:band5g", -+ .gpio = 1, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:green:router", -+ .gpio = 3, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:blue:movie_engine", -+ .gpio = 4, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:amber:band5g", -+ .gpio = 5, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button wzrhpag300h_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 11, -+ .active_low = 1, -+ }, { -+ .desc = "usb", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 3, -+ .active_low = 1, -+ }, { -+ .desc = "aoss", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 5, -+ .active_low = 1, -+ }, { -+ .desc = "router_auto", -+ .type = EV_SW, -+ .code = BTN_6, -+ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 6, -+ .active_low = 1, -+ }, { -+ .desc = "router_off", -+ .type = EV_SW, -+ .code = BTN_5, -+ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 7, -+ .active_low = 1, -+ }, { -+ .desc = "movie_engine", -+ .type = EV_SW, -+ .code = BTN_7, -+ .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 8, -+ .active_low = 1, -+ } -+}; -+ -+static void __init wzrhpag300h_setup(void) -+{ -+ u8 *eeprom1 = (u8 *) KSEG1ADDR(0x1f051000); -+ u8 *eeprom2 = (u8 *) KSEG1ADDR(0x1f055000); -+ u8 *mac1 = eeprom1 + WZRHPAG300H_MAC_OFFSET; -+ u8 *mac2 = eeprom2 + WZRHPAG300H_MAC_OFFSET; -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 1); -+ -+ ath79_register_mdio(0, ~(BIT(0) | BIT(4))); -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(0); -+ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth1_data.phy_mask = BIT(4); -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ gpio_request_one(2, GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wzrhpag300h_leds_gpio), -+ wzrhpag300h_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, WZRHPAG300H_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wzrhpag300h_gpio_keys), -+ wzrhpag300h_gpio_keys); -+ -+ ath79_register_m25p80_multi(&wzrhpag300h_flash_data); -+ -+ ap94_pci_init(eeprom1, mac1, eeprom2, mac2); -+ -+ ap9x_pci_setup_wmac_leds(0, wzrhpag300h_wmac0_leds_gpio, -+ ARRAY_SIZE(wzrhpag300h_wmac0_leds_gpio)); -+ ap9x_pci_setup_wmac_leds(1, wzrhpag300h_wmac1_leds_gpio, -+ ARRAY_SIZE(wzrhpag300h_wmac1_leds_gpio)); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WZR_HP_AG300H, "WZR-HP-AG300H", -+ "Buffalo WZR-HP-AG300H/WZR-600DHP", wzrhpag300h_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g300nh.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g300nh.c -new file mode 100644 -index 0000000000..0a3eba9f77 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g300nh.c -@@ -0,0 +1,279 @@ -+/* -+ * Buffalo WZR-HP-G300NH board support -+ * -+ * Copyright (C) 2010-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define WZRHPG300NH_GPIO_LED_USB 0 -+#define WZRHPG300NH_GPIO_LED_DIAG 1 -+#define WZRHPG300NH_GPIO_LED_WIRELESS 6 -+#define WZRHPG300NH_GPIO_LED_SECURITY 17 -+#define WZRHPG300NH_GPIO_LED_ROUTER 18 -+ -+#define WZRHPG300NH_GPIO_RTL8366_SDA 19 -+#define WZRHPG300NH_GPIO_RTL8366_SCK 20 -+ -+#define WZRHPG300NH_GPIO_74HC153_S0 9 -+#define WZRHPG300NH_GPIO_74HC153_S1 11 -+#define WZRHPG300NH_GPIO_74HC153_1Y 12 -+#define WZRHPG300NH_GPIO_74HC153_2Y 14 -+ -+#define WZRHPG300NH_GPIO_EXP_BASE 32 -+#define WZRHPG300NH_GPIO_BTN_AOSS (WZRHPG300NH_GPIO_EXP_BASE + 0) -+#define WZRHPG300NH_GPIO_BTN_RESET (WZRHPG300NH_GPIO_EXP_BASE + 1) -+#define WZRHPG300NH_GPIO_BTN_ROUTER_ON (WZRHPG300NH_GPIO_EXP_BASE + 2) -+#define WZRHPG300NH_GPIO_BTN_QOS_ON (WZRHPG300NH_GPIO_EXP_BASE + 3) -+#define WZRHPG300NH_GPIO_BTN_USB (WZRHPG300NH_GPIO_EXP_BASE + 5) -+#define WZRHPG300NH_GPIO_BTN_ROUTER_AUTO (WZRHPG300NH_GPIO_EXP_BASE + 6) -+#define WZRHPG300NH_GPIO_BTN_QOS_OFF (WZRHPG300NH_GPIO_EXP_BASE + 7) -+ -+#define WZRHPG300NH_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL (3 * WZRHPG300NH_KEYS_POLL_INTERVAL) -+ -+#define WZRHPG300NH_MAC_OFFSET 0x20c -+ -+static struct mtd_partition wzrhpg300nh_flash_partitions[] = { -+ { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x0040000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "u-boot-env", -+ .offset = 0x0040000, -+ .size = 0x0020000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x0060000, -+ .size = 0x1f60000, -+ }, { -+ .name = "user_property", -+ .offset = 0x1fc0000, -+ .size = 0x0020000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "art", -+ .offset = 0x1fe0000, -+ .size = 0x0020000, -+ .mask_flags = MTD_WRITEABLE, -+ } -+}; -+ -+static struct physmap_flash_data wzrhpg300nh_flash_data = { -+ .width = 2, -+ .parts = wzrhpg300nh_flash_partitions, -+ .nr_parts = ARRAY_SIZE(wzrhpg300nh_flash_partitions), -+}; -+ -+#define WZRHPG300NH_FLASH_BASE 0x1e000000 -+#define WZRHPG300NH_FLASH_SIZE (32 * 1024 * 1024) -+ -+static struct resource wzrhpg300nh_flash_resources[] = { -+ [0] = { -+ .start = WZRHPG300NH_FLASH_BASE, -+ .end = WZRHPG300NH_FLASH_BASE + WZRHPG300NH_FLASH_SIZE - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+}; -+ -+static struct platform_device wzrhpg300nh_flash_device = { -+ .name = "physmap-flash", -+ .id = -1, -+ .resource = wzrhpg300nh_flash_resources, -+ .num_resources = ARRAY_SIZE(wzrhpg300nh_flash_resources), -+ .dev = { -+ .platform_data = &wzrhpg300nh_flash_data, -+ } -+}; -+ -+static struct gpio_led wzrhpg300nh_leds_gpio[] __initdata = { -+ { -+ .name = "buffalo:orange:security", -+ .gpio = WZRHPG300NH_GPIO_LED_SECURITY, -+ .active_low = 1, -+ }, { -+ .name = "buffalo:green:wireless", -+ .gpio = WZRHPG300NH_GPIO_LED_WIRELESS, -+ .active_low = 1, -+ }, { -+ .name = "buffalo:green:router", -+ .gpio = WZRHPG300NH_GPIO_LED_ROUTER, -+ .active_low = 1, -+ }, { -+ .name = "buffalo:red:diag", -+ .gpio = WZRHPG300NH_GPIO_LED_DIAG, -+ .active_low = 1, -+ }, { -+ .name = "buffalo:blue:usb", -+ .gpio = WZRHPG300NH_GPIO_LED_USB, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_keys_button wzrhpg300nh_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WZRHPG300NH_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "aoss", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WZRHPG300NH_GPIO_BTN_AOSS, -+ .active_low = 1, -+ }, { -+ .desc = "usb", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WZRHPG300NH_GPIO_BTN_USB, -+ .active_low = 1, -+ }, { -+ .desc = "qos_on", -+ .type = EV_KEY, -+ .code = BTN_3, -+ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WZRHPG300NH_GPIO_BTN_QOS_ON, -+ .active_low = 0, -+ }, { -+ .desc = "qos_off", -+ .type = EV_KEY, -+ .code = BTN_4, -+ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WZRHPG300NH_GPIO_BTN_QOS_OFF, -+ .active_low = 0, -+ }, { -+ .desc = "router_on", -+ .type = EV_KEY, -+ .code = BTN_5, -+ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_ON, -+ .active_low = 0, -+ }, { -+ .desc = "router_auto", -+ .type = EV_KEY, -+ .code = BTN_6, -+ .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_AUTO, -+ .active_low = 0, -+ } -+}; -+ -+static struct nxp_74hc153_platform_data wzrhpg300nh_74hc153_data = { -+ .gpio_base = WZRHPG300NH_GPIO_EXP_BASE, -+ .gpio_pin_s0 = WZRHPG300NH_GPIO_74HC153_S0, -+ .gpio_pin_s1 = WZRHPG300NH_GPIO_74HC153_S1, -+ .gpio_pin_1y = WZRHPG300NH_GPIO_74HC153_1Y, -+ .gpio_pin_2y = WZRHPG300NH_GPIO_74HC153_2Y, -+}; -+ -+static struct platform_device wzrhpg300nh_74hc153_device = { -+ .name = NXP_74HC153_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &wzrhpg300nh_74hc153_data, -+ } -+}; -+ -+static struct rtl8366_platform_data wzrhpg300nh_rtl8366_data = { -+ .gpio_sda = WZRHPG300NH_GPIO_RTL8366_SDA, -+ .gpio_sck = WZRHPG300NH_GPIO_RTL8366_SCK, -+}; -+ -+static struct platform_device wzrhpg300nh_rtl8366s_device = { -+ .name = RTL8366S_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &wzrhpg300nh_rtl8366_data, -+ } -+}; -+ -+static struct platform_device wzrhpg300nh_rtl8366rb_device = { -+ .name = RTL8366RB_DRIVER_NAME, -+ .id = -1, -+ .dev = { -+ .platform_data = &wzrhpg300nh_rtl8366_data, -+ } -+}; -+ -+static void __init wzrhpg300nh_setup(void) -+{ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -+ u8 *mac = eeprom + WZRHPG300NH_MAC_OFFSET; -+ bool hasrtl8366rb = false; -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -+ -+ if (rtl8366_smi_detect(&wzrhpg300nh_rtl8366_data) == RTL8366_TYPE_RB) -+ hasrtl8366rb = true; -+ -+ if (hasrtl8366rb) { -+ ath79_eth0_pll_data.pll_1000 = 0x1f000000; -+ ath79_eth0_data.mii_bus_dev = &wzrhpg300nh_rtl8366rb_device.dev; -+ ath79_eth1_pll_data.pll_1000 = 0x100; -+ ath79_eth1_data.mii_bus_dev = &wzrhpg300nh_rtl8366rb_device.dev; -+ } else { -+ ath79_eth0_pll_data.pll_1000 = 0x1e000100; -+ ath79_eth0_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev; -+ ath79_eth1_pll_data.pll_1000 = 0x1e000100; -+ ath79_eth1_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev; -+ } -+ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth1_data.phy_mask = 0x10; -+ -+ ath79_register_eth(0); -+ ath79_register_eth(1); -+ -+ ath79_register_usb(); -+ ath79_register_wmac(eeprom, NULL); -+ -+ platform_device_register(&wzrhpg300nh_74hc153_device); -+ platform_device_register(&wzrhpg300nh_flash_device); -+ -+ if (hasrtl8366rb) -+ platform_device_register(&wzrhpg300nh_rtl8366rb_device); -+ else -+ platform_device_register(&wzrhpg300nh_rtl8366s_device); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wzrhpg300nh_leds_gpio), -+ wzrhpg300nh_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, WZRHPG300NH_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wzrhpg300nh_gpio_keys), -+ wzrhpg300nh_gpio_keys); -+ -+} -+ -+MIPS_MACHINE(ATH79_MACH_WZR_HP_G300NH, "WZR-HP-G300NH", -+ "Buffalo WZR-HP-G300NH", wzrhpg300nh_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g300nh2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g300nh2.c -new file mode 100644 -index 0000000000..c44a9cf770 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g300nh2.c -@@ -0,0 +1,174 @@ -+/* -+ * Buffalo WZR-HP-G300NH2 board support -+ * -+ * Copyright (C) 2011 Felix Fietkau -+ * Copyright (C) 2011 Mark Deneen -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include "dev-ap9x-pci.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+ -+#define WZRHPG300NH2_MAC_OFFSET 0x20c -+#define WZRHPG300NH2_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WZRHPG300NH2_KEYS_DEBOUNCE_INTERVAL (3 * WZRHPG300NH2_KEYS_POLL_INTERVAL) -+ -+static struct mtd_partition wzrhpg300nh2_flash_partitions[] = { -+ { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x0040000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "u-boot-env", -+ .offset = 0x0040000, -+ .size = 0x0010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "art", -+ .offset = 0x0050000, -+ .size = 0x0010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x0060000, -+ .size = 0x1f90000, -+ }, { -+ .name = "user_property", -+ .offset = 0x1ff0000, -+ .size = 0x0010000, -+ .mask_flags = MTD_WRITEABLE, -+ } -+}; -+ -+static struct flash_platform_data wzrhpg300nh2_flash_data = { -+ .parts = wzrhpg300nh2_flash_partitions, -+ .nr_parts = ARRAY_SIZE(wzrhpg300nh2_flash_partitions), -+}; -+ -+static struct gpio_led wzrhpg300nh2_leds_gpio[] __initdata = { -+ { -+ .name = "buffalo:red:diag", -+ .gpio = 16, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_led wzrhpg300nh2_wmac_leds_gpio[] = { -+ { -+ .name = "buffalo:blue:usb", -+ .gpio = 4, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:green:wireless", -+ .gpio = 5, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:orange:security", -+ .gpio = 6, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:green:router", -+ .gpio = 7, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:blue:movie_engine_on", -+ .gpio = 8, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:blue:movie_engine_off", -+ .gpio = 9, -+ .active_low = 1, -+ }, -+}; -+ -+/* The AOSS button is wmac gpio 12 */ -+static struct gpio_keys_button wzrhpg300nh2_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WZRHPG300NH2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 1, -+ .active_low = 1, -+ }, { -+ .desc = "usb", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .debounce_interval = WZRHPG300NH2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 7, -+ .active_low = 1, -+ }, { -+ .desc = "qos", -+ .type = EV_KEY, -+ .code = BTN_3, -+ .debounce_interval = WZRHPG300NH2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 11, -+ .active_low = 0, -+ }, { -+ .desc = "router_on", -+ .type = EV_KEY, -+ .code = BTN_5, -+ .debounce_interval = WZRHPG300NH2_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 8, -+ .active_low = 0, -+ }, -+}; -+ -+static void __init wzrhpg300nh2_setup(void) -+{ -+ -+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1f051000); -+ u8 *mac0 = eeprom + WZRHPG300NH2_MAC_OFFSET; -+ /* There is an eth1 but it is not connected to the switch */ -+ -+ ath79_register_m25p80_multi(&wzrhpg300nh2_flash_data); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac0, 0); -+ ath79_register_mdio(0, ~(BIT(0))); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac0, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(0); -+ -+ ath79_register_eth(0); -+ -+ /* gpio13 is usb power. Turn it on. */ -+ gpio_request_one(13, GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wzrhpg300nh2_leds_gpio), -+ wzrhpg300nh2_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, WZRHPG300NH2_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wzrhpg300nh2_gpio_keys), -+ wzrhpg300nh2_gpio_keys); -+ ap9x_pci_setup_wmac_leds(0, wzrhpg300nh2_wmac_leds_gpio, -+ ARRAY_SIZE(wzrhpg300nh2_wmac_leds_gpio)); -+ -+ ap91_pci_init(eeprom, mac0); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WZR_HP_G300NH2, "WZR-HP-G300NH2", -+ "Buffalo WZR-HP-G300NH2", wzrhpg300nh2_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g450h.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g450h.c -new file mode 100644 -index 0000000000..5d235c49f4 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g450h.c -@@ -0,0 +1,169 @@ -+/* -+ * Buffalo WZR-HP-G450G board support -+ * -+ * Copyright (C) 2011 Felix Fietkau -+ * Copyright (C) 2008-2012 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "dev-eth.h" -+#include "dev-m25p80.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-usb.h" -+#include "machtypes.h" -+ -+#define WZRHPG450H_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define WZRHPG450H_KEYS_DEBOUNCE_INTERVAL (3 * WZRHPG450H_KEYS_POLL_INTERVAL) -+ -+static struct mtd_partition wzrhpg450h_partitions[] = { -+ { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x0040000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "u-boot-env", -+ .offset = 0x0040000, -+ .size = 0x0010000, -+ }, { -+ .name = "ART", -+ .offset = 0x0050000, -+ .size = 0x0010000, -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "firmware", -+ .offset = 0x0060000, -+ .size = 0x1f80000, -+ }, { -+ .name = "user_property", -+ .offset = 0x1fe0000, -+ .size = 0x0020000, -+ } -+}; -+ -+static struct flash_platform_data wzrhpg450h_flash_data = { -+ .parts = wzrhpg450h_partitions, -+ .nr_parts = ARRAY_SIZE(wzrhpg450h_partitions), -+}; -+ -+static struct gpio_led wzrhpg450h_leds_gpio[] __initdata = { -+ { -+ .name = "buffalo:red:diag", -+ .gpio = 14, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:orange:security", -+ .gpio = 13, -+ .active_low = 1, -+ }, -+}; -+ -+ -+static struct gpio_led wzrhpg450h_wmac_leds_gpio[] = { -+ { -+ .name = "buffalo:blue:movie_engine", -+ .gpio = 13, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:green:router", -+ .gpio = 14, -+ .active_low = 1, -+ }, -+ { -+ .name = "buffalo:green:wireless", -+ .gpio = 15, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button wzrhpg450h_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = WZRHPG450H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 6, -+ .active_low = 1, -+ }, { -+ .desc = "usb", -+ .type = EV_KEY, -+ .code = BTN_2, -+ .debounce_interval = WZRHPG450H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 1, -+ .active_low = 1, -+ }, { -+ .desc = "aoss", -+ .type = EV_KEY, -+ .code = KEY_WPS_BUTTON, -+ .debounce_interval = WZRHPG450H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 8, -+ .active_low = 1, -+ }, { -+ .desc = "movie_engine", -+ .type = EV_KEY, -+ .code = BTN_6, -+ .debounce_interval = WZRHPG450H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 7, -+ .active_low = 0, -+ }, { -+ .desc = "router_off", -+ .type = EV_KEY, -+ .code = BTN_5, -+ .debounce_interval = WZRHPG450H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = 12, -+ .active_low = 0, -+ } -+}; -+ -+ -+static void __init wzrhpg450h_init(void) -+{ -+ u8 *ee = (u8 *) KSEG1ADDR(0x1f051000); -+ u8 *mac = (u8 *) ee + 2; -+ -+ ath79_register_m25p80_multi(&wzrhpg450h_flash_data); -+ -+ ath79_register_mdio(0, ~BIT(0)); -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.speed = SPEED_1000; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_mask = BIT(0); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(wzrhpg450h_leds_gpio), -+ wzrhpg450h_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, WZRHPG450H_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(wzrhpg450h_gpio_keys), -+ wzrhpg450h_gpio_keys); -+ -+ ath79_register_eth(0); -+ -+ gpio_request_one(16, GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, -+ "USB power"); -+ ath79_register_usb(); -+ -+ ap91_pci_init(ee, NULL); -+ ap9x_pci_get_wmac_data(0)->tx_gain_buffalo = true; -+ ap9x_pci_get_wmac_data(1)->tx_gain_buffalo = true; -+ ap9x_pci_setup_wmac_leds(0, wzrhpg450h_wmac_leds_gpio, -+ ARRAY_SIZE(wzrhpg450h_wmac_leds_gpio)); -+} -+ -+MIPS_MACHINE(ATH79_MACH_WZR_HP_G450H, "WZR-HP-G450H", "Buffalo WZR-HP-G450H", -+ wzrhpg450h_init); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-z1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-z1.c -new file mode 100644 -index 0000000000..912e9b2a6f ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-z1.c -@@ -0,0 +1,164 @@ -+/* -+ * Cisco Meraki Z1 board support -+ * -+ * Copyright (C) 2016 Chris Blake -+ * Copyright (C) 2016 Christian Lamparter -+ * -+ * Based on Cisco Meraki GPL Release r23-20150601 Z1 Device Config -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-nfc.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "dev-ap9x-pci.h" -+#include "machtypes.h" -+ -+#define Z1_GPIO_LED_POWER_ORANGE 17 -+ -+#define Z1_GPIO_NU801_CKI 14 -+#define Z1_GPIO_NU801_SDI 15 -+ -+#define Z1_GPIO_XLNA0 18 -+#define Z1_GPIO_XLNA1 19 -+ -+#define Z1_GPIO_BTN_RESET 12 -+#define Z1_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define Z1_KEYS_DEBOUNCE_INTERVAL (3 * Z1_KEYS_POLL_INTERVAL) -+ -+#define Z1_ETH_SWITCH_PHY 0 -+ -+static struct gpio_led Z1_leds_gpio[] __initdata = { -+ { -+ .name = "z1:orange:power", -+ .gpio = Z1_GPIO_LED_POWER_ORANGE, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button Z1_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = Z1_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = Z1_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static struct led_nu801_template tricolor_led_template = { -+ .device_name = "z1", -+ .name = "tricolor", -+ .num_leds = 1, -+ .cki = Z1_GPIO_NU801_CKI, -+ .sdi = Z1_GPIO_NU801_SDI, -+ .lei = -1, -+ .ndelay = 500, -+ .init_brightness = { -+ LED_OFF, -+ LED_OFF, -+ LED_OFF, -+ }, -+ .default_trigger = "none", -+}; -+ -+static struct led_nu801_platform_data tricolor_led_data = { -+ .num_controllers = 1, -+ .template = &tricolor_led_template, -+}; -+ -+static struct platform_device tricolor_leds = { -+ .name = "leds-nu801", -+ .id = -1, -+ .dev.platform_data = &tricolor_led_data, -+}; -+ -+static struct ar8327_pad_cfg z1_ar8327_pad0_cfg = { -+ .mode = AR8327_PAD_MAC_RGMII, -+ .txclk_delay_en = true, -+ .rxclk_delay_en = true, -+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+}; -+ -+static struct ar8327_platform_data z1_ar8327_data = { -+ .pad0_cfg = &z1_ar8327_pad0_cfg, -+ .port0_cfg = { -+ .force_link = 1, -+ .speed = AR8327_PORT_SPEED_1000, -+ .duplex = 1, -+ .txpause = 1, -+ .rxpause = 1, -+ }, -+}; -+ -+static struct mdio_board_info z1_mdio0_info[] = { -+ { -+ .bus_id = "ag71xx-mdio.0", -+ .mdio_addr = Z1_ETH_SWITCH_PHY, -+ .platform_data = &z1_ar8327_data, -+ }, -+}; -+ -+static void __init z1_setup(void) -+{ -+ /* NAND */ -+ ath79_nfc_set_ecc_mode(AR934X_NFC_ECC_SOFT_BCH); -+ ath79_register_nfc(); -+ -+ /* Eth Config */ -+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -+ AR934X_ETH_CFG_SW_ONLY_MODE); -+ -+ /* MDIO Interface */ -+ ath79_register_mdio(1, 0x0); -+ ath79_register_mdio(0, 0x0); -+ mdiobus_register_board_info(z1_mdio0_info, -+ ARRAY_SIZE(z1_mdio0_info)); -+ -+ /* GMAC0 is connected to an AR8327 switch */ -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -+ ath79_eth0_data.phy_mask = BIT(Z1_ETH_SWITCH_PHY); -+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -+ ath79_eth0_pll_data.pll_1000 = 0x06000000; -+ ath79_register_eth(0); -+ -+ /* XLNA */ -+ ath79_wmac_set_ext_lna_gpio(0, Z1_GPIO_XLNA0); -+ ath79_wmac_set_ext_lna_gpio(1, Z1_GPIO_XLNA1); -+ -+ /* LEDs and Buttons */ -+ platform_device_register(&tricolor_leds); -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(Z1_leds_gpio), -+ Z1_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, Z1_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(Z1_gpio_keys), -+ Z1_gpio_keys); -+ -+ /* USB */ -+ ath79_register_usb(); -+ -+ /* Wireless */ -+ ath79_register_wmac_simple(); -+ ap91_pci_init_simple(); -+} -+MIPS_MACHINE(ATH79_MACH_Z1, "Z1", "Meraki Z1", z1_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-zbt-we1526.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-zbt-we1526.c -new file mode 100644 -index 0000000000..42bad11905 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-zbt-we1526.c -@@ -0,0 +1,153 @@ -+/* -+ * Zbtlink ZBT-WE1526 board support -+ * -+ * Copyright (C) 2016 Piotr Dymacz -+ * -+ * Based on mach-dr531.c and mach-tl-wr841n-v9.c -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-usb.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+#define ZBT_WE1526_GPIO_LED_STATUS 13 -+#define ZBT_WE1526_GPIO_LED_LAN1 16 -+#define ZBT_WE1526_GPIO_LED_LAN2 15 -+#define ZBT_WE1526_GPIO_LED_LAN3 14 -+#define ZBT_WE1526_GPIO_LED_LAN4 11 -+#define ZBT_WE1526_GPIO_LED_WAN 4 -+#define ZBT_WE1526_GPIO_LED_WLAN 12 -+ -+#define ZBT_WE1526_GPIO_BTN_RESET 17 -+ -+#define ZBT_WE1526_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define ZBT_WE1526_KEYS_DEBOUNCE_INTERVAL \ -+ (3 * ZBT_WE1526_KEYS_POLL_INTERVAL) -+ -+#define ZBT_WE1526_MAC0_OFFSET 0x0 -+#define ZBT_WE1526_MAC1_OFFSET 0x6 -+#define ZBT_WE1526_WMAC_CALDATA_OFFSET 0x1000 -+ -+static struct gpio_led zbt_we1526_leds_gpio[] __initdata = { -+ { -+ .name = "zbt-we1526:green:status", -+ .gpio = ZBT_WE1526_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, -+ { -+ .name = "zbt-we1526:green:lan1", -+ .gpio = ZBT_WE1526_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, -+ { -+ .name = "zbt-we1526:green:lan2", -+ .gpio = ZBT_WE1526_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, -+ { -+ .name = "zbt-we1526:green:lan3", -+ .gpio = ZBT_WE1526_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, -+ { -+ .name = "zbt-we1526:green:lan4", -+ .gpio = ZBT_WE1526_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, -+ { -+ .name = "zbt-we1526:green:wan", -+ .gpio = ZBT_WE1526_GPIO_LED_WAN, -+ .active_low = 1, -+ }, -+ { -+ .name = "zbt-we1526:green:wlan", -+ .gpio = ZBT_WE1526_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button zbt_we1526_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ZBT_WE1526_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ZBT_WE1526_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, -+}; -+ -+static void __init zbt_we1526_gpio_setup(void) -+{ -+ /* For LED on GPIO4 */ -+ ath79_gpio_function_disable(AR934X_GPIO_FUNC_CLK_OBS4_EN); -+ ath79_gpio_output_select(ZBT_WE1526_GPIO_LED_WAN, 0); -+ -+ ath79_gpio_direction_select(ZBT_WE1526_GPIO_LED_STATUS, true); -+ ath79_gpio_direction_select(ZBT_WE1526_GPIO_LED_LAN1, true); -+ ath79_gpio_direction_select(ZBT_WE1526_GPIO_LED_LAN2, true); -+ ath79_gpio_direction_select(ZBT_WE1526_GPIO_LED_LAN3, true); -+ ath79_gpio_direction_select(ZBT_WE1526_GPIO_LED_LAN4, true); -+ ath79_gpio_direction_select(ZBT_WE1526_GPIO_LED_WAN, true); -+ ath79_gpio_direction_select(ZBT_WE1526_GPIO_LED_WLAN, true); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(zbt_we1526_leds_gpio), -+ zbt_we1526_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, ZBT_WE1526_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(zbt_we1526_gpio_keys), -+ zbt_we1526_gpio_keys); -+} -+ -+static void __init zbt_we1526_setup(void) -+{ -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+ ath79_register_m25p80(NULL); -+ -+ zbt_we1526_gpio_setup(); -+ -+ ath79_setup_ar933x_phy4_switch(false, false); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN */ -+ ath79_eth1_data.duplex = DUPLEX_FULL; -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_switch_data.phy_poll_mask |= BIT(4); -+ ath79_init_mac(ath79_eth1_data.mac_addr, -+ art + ZBT_WE1526_MAC0_OFFSET, 0); -+ ath79_register_eth(1); -+ -+ /* WAN */ -+ ath79_switch_data.phy4_mii_en = 1; -+ ath79_eth0_data.duplex = DUPLEX_FULL; -+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ath79_eth0_data.phy_mask = BIT(4); -+ ath79_eth0_data.speed = SPEED_100; -+ ath79_init_mac(ath79_eth0_data.mac_addr, -+ art + ZBT_WE1526_MAC1_OFFSET, 0); -+ ath79_register_eth(0); -+ -+ ath79_register_wmac(art + ZBT_WE1526_WMAC_CALDATA_OFFSET, NULL); -+ -+ ath79_register_usb(); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ZBT_WE1526, "ZBT-WE1526", "Zbtlink ZBT-WE1526", -+ zbt_we1526_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-zcn-1523h.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-zcn-1523h.c -new file mode 100644 -index 0000000000..bc79ab9953 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-zcn-1523h.c -@@ -0,0 +1,154 @@ -+/* -+ * Zcomax ZCN-1523H-2-8/5-16 board support -+ * -+ * Copyright (C) 2010-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-m25p80.h" -+#include "dev-ap9x-pci.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "machtypes.h" -+ -+#define ZCN_1523H_GPIO_BTN_RESET 0 -+#define ZCN_1523H_GPIO_LED_INIT 11 -+#define ZCN_1523H_GPIO_LED_LAN1 17 -+ -+#define ZCN_1523H_2_GPIO_LED_WEAK 13 -+#define ZCN_1523H_2_GPIO_LED_MEDIUM 14 -+#define ZCN_1523H_2_GPIO_LED_STRONG 15 -+ -+#define ZCN_1523H_5_GPIO_LAN2_POWER 1 -+#define ZCN_1523H_5_GPIO_LED_LAN2 13 -+#define ZCN_1523H_5_GPIO_LED_WEAK 14 -+#define ZCN_1523H_5_GPIO_LED_MEDIUM 15 -+#define ZCN_1523H_5_GPIO_LED_STRONG 16 -+ -+#define ZCN_1523H_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define ZCN_1523H_KEYS_DEBOUNCE_INTERVAL (3 * ZCN_1523H_KEYS_POLL_INTERVAL) -+ -+static struct gpio_keys_button zcn_1523h_gpio_keys[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = ZCN_1523H_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = ZCN_1523H_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led zcn_1523h_leds_gpio[] __initdata = { -+ { -+ .name = "zcn-1523h:amber:init", -+ .gpio = ZCN_1523H_GPIO_LED_INIT, -+ .active_low = 1, -+ }, { -+ .name = "zcn-1523h:green:lan1", -+ .gpio = ZCN_1523H_GPIO_LED_LAN1, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led zcn_1523h_2_leds_gpio[] __initdata = { -+ { -+ .name = "zcn-1523h:red:weak", -+ .gpio = ZCN_1523H_2_GPIO_LED_WEAK, -+ .active_low = 1, -+ }, { -+ .name = "zcn-1523h:amber:medium", -+ .gpio = ZCN_1523H_2_GPIO_LED_MEDIUM, -+ .active_low = 1, -+ }, { -+ .name = "zcn-1523h:green:strong", -+ .gpio = ZCN_1523H_2_GPIO_LED_STRONG, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_led zcn_1523h_5_leds_gpio[] __initdata = { -+ { -+ .name = "zcn-1523h:red:weak", -+ .gpio = ZCN_1523H_5_GPIO_LED_WEAK, -+ .active_low = 1, -+ }, { -+ .name = "zcn-1523h:amber:medium", -+ .gpio = ZCN_1523H_5_GPIO_LED_MEDIUM, -+ .active_low = 1, -+ }, { -+ .name = "zcn-1523h:green:strong", -+ .gpio = ZCN_1523H_5_GPIO_LED_STRONG, -+ .active_low = 1, -+ }, { -+ .name = "zcn-1523h:green:lan2", -+ .gpio = ZCN_1523H_5_GPIO_LED_LAN2, -+ .active_low = 1, -+ } -+}; -+ -+static void __init zcn_1523h_generic_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f7e0004); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | -+ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_leds_gpio(0, ARRAY_SIZE(zcn_1523h_leds_gpio), -+ zcn_1523h_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(-1, ZCN_1523H_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(zcn_1523h_gpio_keys), -+ zcn_1523h_gpio_keys); -+ -+ ap91_pci_init(ee, mac); -+ -+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -+ -+ ath79_register_mdio(0, 0x0); -+ -+ /* LAN1 port */ -+ ath79_register_eth(0); -+} -+ -+static void __init zcn_1523h_2_setup(void) -+{ -+ zcn_1523h_generic_setup(); -+ ap9x_pci_setup_wmac_gpio(0, BIT(9), 0); -+ -+ ath79_register_leds_gpio(1, ARRAY_SIZE(zcn_1523h_2_leds_gpio), -+ zcn_1523h_2_leds_gpio); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ZCN_1523H_2, "ZCN-1523H-2", "Zcomax ZCN-1523H-2", -+ zcn_1523h_2_setup); -+ -+static void __init zcn_1523h_5_setup(void) -+{ -+ zcn_1523h_generic_setup(); -+ ap9x_pci_setup_wmac_gpio(0, BIT(8), 0); -+ -+ ath79_register_leds_gpio(1, ARRAY_SIZE(zcn_1523h_5_leds_gpio), -+ zcn_1523h_5_leds_gpio); -+ -+ /* LAN2 port */ -+ ath79_register_eth(1); -+} -+ -+MIPS_MACHINE(ATH79_MACH_ZCN_1523H_5, "ZCN-1523H-5", "Zcomax ZCN-1523H-5", -+ zcn_1523h_5_setup); -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h b/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h -new file mode 100644 -index 0000000000..900b4ec87b ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h -@@ -0,0 +1,387 @@ -+/* -+ * Atheros AR71XX/AR724X/AR913X machine type definitions -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _ATH79_MACHTYPE_H -+#define _ATH79_MACHTYPE_H -+ -+#include -+ -+enum ath79_mach_type { -+ ATH79_MACH_GENERIC_OF = -1, /* Device tree board */ -+ ATH79_MACH_GENERIC = 0, -+ ATH79_MACH_A40, /* OpenMesh A40 */ -+ ATH79_MACH_A60, /* OpenMesh A60 */ -+ ATH79_MACH_WI2A_AC200I, /* Nokia WI2A-AC200i */ -+ ATH79_MACH_ALFA_AP120C, /* ALFA Network AP120C board */ -+ ATH79_MACH_ALFA_AP96, /* ALFA Network AP96 board */ -+ ATH79_MACH_ALFA_NX, /* ALFA Network N2/N5 board */ -+ ATH79_MACH_ALL0258N, /* Allnet ALL0258N */ -+ ATH79_MACH_ALL0305, /* Allnet ALL0305 */ -+ ATH79_MACH_ALL0315N, /* Allnet ALL0315N */ -+ ATH79_MACH_ANTMINER_S1, /* Antminer S1 */ -+ ATH79_MACH_ANTMINER_S3, /* Antminer S3 */ -+ ATH79_MACH_ANTROUTER_R1, /* Antrouter R1 */ -+ ATH79_MACH_AP121, /* Atheros AP121 reference board */ -+ ATH79_MACH_AP121_MINI, /* Atheros AP121-MINI reference board */ -+ ATH79_MACH_AP121F, /* ALFA Network AP121F */ -+ ATH79_MACH_AP132, /* Atheros AP132 reference board */ -+ ATH79_MACH_AP135_020, /* Atheros AP135-020 reference board */ -+ ATH79_MACH_AP136_010, /* Atheros AP136-010 reference board */ -+ ATH79_MACH_AP136_020, /* Atheros AP136-020 reference board */ -+ ATH79_MACH_AP143, /* Atheros AP143 reference board */ -+ ATH79_MACH_AP147_010, /* Atheros AP147-010 reference board */ -+ ATH79_MACH_AP152, /* Atheros AP152 reference board */ -+ ATH79_MACH_AP531B0, /* Rockeetech AP531B0 */ -+ ATH79_MACH_AP90Q, /* YunCore AP80Q/AP90Q */ -+ ATH79_MACH_AP91_5G, /* ALFA Network AP91-5G */ -+ ATH79_MACH_AP96, /* Atheros AP96 */ -+ ATH79_MACH_ARCHER_C25_V1, /* TP-LINK Archer C25 V1 board */ -+ ATH79_MACH_ARCHER_C5, /* TP-LINK Archer C5 board */ -+ ATH79_MACH_ARCHER_C58_V1, /* TP-LINK Archer C58 V1 board */ -+ ATH79_MACH_ARCHER_C59_V1, /* TP-LINK Archer C59 V1 board */ -+ ATH79_MACH_ARCHER_C59_V2, /* TP-LINK Archer C59 V2 board */ -+ ATH79_MACH_ARCHER_C60_V1, /* TP-LINK Archer C60 V1 board */ -+ ATH79_MACH_ARCHER_C60_V2, /* TP-LINK Archer C60 V2 board */ -+ ATH79_MACH_ARCHER_C7, /* TP-LINK Archer C7 board */ -+ ATH79_MACH_ARCHER_C7_V2, /* TP-LINK Archer C7 V2 board */ -+ ATH79_MACH_ARCHER_C7_V4, /* TP-LINK Archer C7 V4 board */ -+ ATH79_MACH_ARCHER_C7_V5, /* TP-LINK Archer C7 V5 board */ -+ ATH79_MACH_ARDUINO_YUN, /* Yun */ -+ ATH79_MACH_AW_NR580, /* AzureWave AW-NR580 */ -+ ATH79_MACH_BHR_4GRV2, /* Buffalo BHR-4GRV2 */ -+ ATH79_MACH_BHU_BXU2000N2_A1, /* BHU BXU2000n-2 A1 */ -+ ATH79_MACH_BSB, /* Smart Electronics Black Swift board */ -+ ATH79_MACH_C55, /* AirTight Networks C-55 */ -+ ATH79_MACH_C60, /* AirTight Networks C-60 */ -+ ATH79_MACH_CAP324, /* PowerCloud Systems CAP324 */ -+ ATH79_MACH_CAP4200AG, /* Senao CAP4200AG */ -+ ATH79_MACH_CARAMBOLA2, /* 8devices Carambola2 */ -+ ATH79_MACH_CF_E316N_V2, /* COMFAST CF-E316N v2 */ -+ ATH79_MACH_CF_E320N_V2, /* COMFAST CF-E320N v2 */ -+ ATH79_MACH_CF_E355AC, /* COMFAST CF-E355AC */ -+ ATH79_MACH_CF_E355AC_V2, /* COMFAST CF-E355AC v2*/ -+ ATH79_MACH_CF_E375AC, /* COMFAST CF-E375AC */ -+ ATH79_MACH_CF_E380AC_V1, /* COMFAST CF-E380AC v1 */ -+ ATH79_MACH_CF_E380AC_V2, /* COMFAST CF-E380AC v2 */ -+ ATH79_MACH_CF_E385AC, /* COMFAST CF-E385AC */ -+ ATH79_MACH_CF_E520N, /* COMFAST CF-E520N */ -+ ATH79_MACH_CF_E530N, /* COMFAST CF-E530N */ -+ ATH79_MACH_CPE210, /* TP-LINK CPE210 v1 */ -+ ATH79_MACH_CPE210_V2, /* TP-LINK CPE210 v2 */ -+ ATH79_MACH_CPE210_V3, /* TP-LINK CPE210 v3 */ -+ ATH79_MACH_CPE505N, /* P&W CPE505N */ -+ ATH79_MACH_CPE510, /* TP-LINK CPE510 */ -+ ATH79_MACH_CPE510_V2, /* TP-LINK CPE510 v2 */ -+ ATH79_MACH_CPE830, /* YunCore CPE830 */ -+ ATH79_MACH_CPE870, /* YunCore CPE870 */ -+ ATH79_MACH_CR3000, /* PowerCloud Systems CR3000 */ -+ ATH79_MACH_CR5000, /* PowerCloud Systems CR5000 */ -+ ATH79_MACH_DAP_1330_A1, /* D-Link DAP-1330 rev. A1 */ -+ ATH79_MACH_DAP_2695_A1, /* D-Link DAP-2695 rev. A1 */ -+ ATH79_MACH_DB120, /* Atheros DB120 reference board */ -+ ATH79_MACH_DGL_5500_A1, /* D-link DGL-5500 rev. A1 */ -+ ATH79_MACH_DHP_1565_A1, /* D-Link DHP-1565 rev. A1 */ -+ ATH79_MACH_DIR_505_A1, /* D-Link DIR-505 rev. A1 */ -+ ATH79_MACH_DIR_600_A1, /* D-Link DIR-600 rev. A1 */ -+ ATH79_MACH_DIR_615_C1, /* D-Link DIR-615 rev. C1 */ -+ ATH79_MACH_DIR_615_E1, /* D-Link DIR-615 rev. E1 */ -+ ATH79_MACH_DIR_615_E4, /* D-Link DIR-615 rev. E4 */ -+ ATH79_MACH_DIR_615_I1, /* D-Link DIR-615 rev. I1 */ -+ ATH79_MACH_DIR_825_B1, /* D-Link DIR-825 rev. B1 */ -+ ATH79_MACH_DIR_825_C1, /* D-Link DIR-825 rev. C1 */ -+ ATH79_MACH_DIR_835_A1, /* D-Link DIR-835 rev. A1 */ -+ ATH79_MACH_DIR_869_A1, /* D-Link DIR-869 rev. A1 */ -+ ATH79_MACH_DLAN_HOTSPOT, /* devolo dLAN Hotspot */ -+ ATH79_MACH_DLAN_PRO_1200_AC, /* devolo dLAN pro 1200+ WiFi ac*/ -+ ATH79_MACH_DLAN_PRO_500_WP, /* devolo dLAN pro 500 Wireless+ */ -+ ATH79_MACH_DOMYWIFI_DW33D, /* DomyWifi DW33D */ -+ ATH79_MACH_DR342, /* Wallys DR342 */ -+ ATH79_MACH_DR344, /* Wallys DR344 */ -+ ATH79_MACH_DR531, /* Wallys DR531 */ -+ ATH79_MACH_DRAGINO2, /* Dragino Version 2 */ -+ ATH79_MACH_E1700AC_V2, /* Qxwlan E1700AC v2 */ -+ ATH79_MACH_E558_V2, /* Qxwlan E558 v2 */ -+ ATH79_MACH_E600G_V2, /* Qxwlan E600G v2 */ -+ ATH79_MACH_E600GAC_V2, /* Qxwlan E600GAC v2 */ -+ ATH79_MACH_E750A_V4, /* Qxwlan E750A v4 */ -+ ATH79_MACH_E750G_V8, /* Qxwlan E750G v8 */ -+ ATH79_MACH_EAP120, /* TP-LINK EAP120 */ -+ ATH79_MACH_EAP300V2, /* EnGenius EAP300 v2 */ -+ ATH79_MACH_EAP7660D, /* Senao EAP7660D */ -+ ATH79_MACH_EBR_2310_C1, /* D-link EBR-2310 rev. C1 */ -+ ATH79_MACH_EL_M150, /* EasyLink EL-M150 */ -+ ATH79_MACH_EL_MINI, /* EasyLink EL-MINI */ -+ ATH79_MACH_ENS202EXT, /* EnGenius ENS202EXT */ -+ ATH79_MACH_EPG5000, /* EnGenius EPG5000 */ -+ ATH79_MACH_ESR1750, /* EnGenius ESR1750 */ -+ ATH79_MACH_ESR900, /* EnGenius ESR900 */ -+ ATH79_MACH_EW_BALIN, /* embedded wireless Balin Platform */ -+ ATH79_MACH_EW_DORIN, /* embedded wireless Dorin Platform */ -+ ATH79_MACH_EW_DORIN_ROUTER, /* embedded wireless Dorin Router Platform */ -+ ATH79_MACH_F9K1115V2, /* Belkin AC1750DB */ -+ ATH79_MACH_FRITZ300E, /* AVM FRITZ!WLAN Repeater 300E */ -+ ATH79_MACH_FRITZ4020, /* AVM FRITZ!Box 4020 */ -+ ATH79_MACH_FRITZ450E, /* AVM FRITZ!WLAN Repeater 450E */ -+ ATH79_MACH_GL_AR150, /* GL-AR150 support */ -+ ATH79_MACH_GL_AR300, /* GL-AR300 */ -+ ATH79_MACH_GL_AR300M, /* GL-AR300M */ -+ ATH79_MACH_GL_AR750, /* GL.iNet GL-AR750 */ -+ ATH79_MACH_GL_AR750S, /* GL.iNet GL-AR750S */ -+ ATH79_MACH_GL_DOMINO, /* Domino */ -+ ATH79_MACH_GL_INET, /* GL-CONNECT GL-INET */ -+ ATH79_MACH_GL_MIFI, /* GL-MIFI support */ -+ ATH79_MACH_GL_USB150, /* GL.iNet GL-USB150 */ -+ ATH79_MACH_GS_MINIBOX_V1, /* GainStrong MiniBox V1.0 */ -+ ATH79_MACH_GS_MINIBOX_V32, /* Gainstrong MiniBox V3.2 */ -+ ATH79_MACH_GS_OOLITE_V1, /* GainStrong Oolite V1.0 */ -+ ATH79_MACH_GS_OOLITE_V5_2, /* GainStrong Oolite V5.2 */ -+ ATH79_MACH_GS_OOLITE_V5_2_DEV, /* GainStrong Oolite V5.2-Dev */ -+ ATH79_MACH_HIVEAP_121, /* Aerohive HiveAP-121*/ -+ ATH79_MACH_HIWIFI_HC6361, /* HiWiFi HC6361 */ -+ ATH79_MACH_HORNET_UB, /* ALFA Networks Hornet-UB */ -+ ATH79_MACH_JA76PF, /* jjPlus JA76PF */ -+ ATH79_MACH_JA76PF2, /* jjPlus JA76PF2 */ -+ ATH79_MACH_JWAP003, /* jjPlus JWAP003 */ -+ ATH79_MACH_JWAP230, /* jjPlus JWAP230 */ -+ ATH79_MACH_KOALA, /* OCEDO Koala */ -+ ATH79_MACH_LAN_TURTLE, /* Hak5 LAN Turtle */ -+ ATH79_MACH_LIMA, /* 8devices Lima */ -+ ATH79_MACH_MC_MAC1200R, /* MERCURY MAC1200R */ -+ ATH79_MACH_MR12, /* Cisco Meraki MR12 */ -+ ATH79_MACH_MR16, /* Cisco Meraki MR16 */ -+ ATH79_MACH_MR1750, /* OpenMesh MR1750 */ -+ ATH79_MACH_MR1750V2, /* OpenMesh MR1750v2 */ -+ ATH79_MACH_MR18, /* Cisco Meraki MR18 */ -+ ATH79_MACH_MR600, /* OpenMesh MR600 */ -+ ATH79_MACH_MR600V2, /* OpenMesh MR600v2 */ -+ ATH79_MACH_MR900, /* OpenMesh MR900 */ -+ ATH79_MACH_MR900v2, /* OpenMesh MR900v2 */ -+ ATH79_MACH_MYNET_N600, /* WD My Net N600 */ -+ ATH79_MACH_MYNET_N750, /* WD My Net N750 */ -+ ATH79_MACH_MYNET_REXT, /* WD My Net Wi-Fi Range Extender */ -+ ATH79_MACH_MZK_W04NU, /* Planex MZK-W04NU */ -+ ATH79_MACH_MZK_W300NH, /* Planex MZK-W300NH */ -+ ATH79_MACH_N5Q, /* ALFA Network N5Q */ -+ ATH79_MACH_NBG460N, /* Zyxel NBG460N/550N/550NH */ -+ ATH79_MACH_NBG6616, /* Zyxel NBG6616 */ -+ ATH79_MACH_NBG6716, /* Zyxel NBG6716 */ -+ ATH79_MACH_OM2P, /* OpenMesh OM2P */ -+ ATH79_MACH_OM2Pv2, /* OpenMesh OM2Pv2 */ -+ ATH79_MACH_OM2Pv4, /* OpenMesh OM2Pv4 */ -+ ATH79_MACH_OM2P_HS, /* OpenMesh OM2P-HS */ -+ ATH79_MACH_OM2P_HSv2, /* OpenMesh OM2P-HSv2 */ -+ ATH79_MACH_OM2P_HSv3, /* OpenMesh OM2P-HSv3 */ -+ ATH79_MACH_OM2P_HSv4, /* OpenMesh OM2P-HSv4 */ -+ ATH79_MACH_OM2P_LC, /* OpenMesh OM2P-LC */ -+ ATH79_MACH_OM5P, /* OpenMesh OM5P */ -+ ATH79_MACH_OM5P_AC, /* OpenMesh OM5P-AC */ -+ ATH79_MACH_OM5P_ACv2, /* OpenMesh OM5P-ACv2 */ -+ ATH79_MACH_OM5P_AN, /* OpenMesh OM5P-AN */ -+ ATH79_MACH_OMY_G1, /* OMYlink OMY-G1 */ -+ ATH79_MACH_OMY_X1, /* OMYlink OMY-X1 */ -+ ATH79_MACH_ONION_OMEGA, /* ONION OMEGA */ -+ ATH79_MACH_PACKET_SQUIRREL, /* Hak5 Packet Squirrel */ -+ ATH79_MACH_PB42, /* Atheros PB42 */ -+ ATH79_MACH_PB44, /* Atheros PB44 reference board */ -+ ATH79_MACH_PQI_AIR_PEN, /* PQI Air Pen */ -+ ATH79_MACH_QIHOO_C301, /* Qihoo 360 C301 */ -+ ATH79_MACH_R36A, /* ALFA Network R36A */ -+ ATH79_MACH_R602N, /* P&W R602N */ -+ ATH79_MACH_R6100, /* NETGEAR R6100 */ -+ ATH79_MACH_RAMBUTAN, /* 8devices Rambutan */ -+ ATH79_MACH_RB_2011G, /* Mikrotik RouterBOARD 2011UAS-2HnD */ -+ ATH79_MACH_RB_2011L, /* Mikrotik RouterBOARD 2011L */ -+ ATH79_MACH_RB_2011R5, /* Mikrotik RouterBOARD 2011UiAS(-2Hnd) */ -+ ATH79_MACH_RB_2011US, /* Mikrotik RouterBOARD 2011UAS */ -+ ATH79_MACH_RB_411, /* MikroTik RouterBOARD 411/411A/411AH */ -+ ATH79_MACH_RB_411U, /* MikroTik RouterBOARD 411U */ -+ ATH79_MACH_RB_433, /* MikroTik RouterBOARD 433/433AH */ -+ ATH79_MACH_RB_433U, /* MikroTik RouterBOARD 433UAH */ -+ ATH79_MACH_RB_435G, /* MikroTik RouterBOARD 435G */ -+ ATH79_MACH_RB_450, /* MikroTik RouterBOARD 450 */ -+ ATH79_MACH_RB_450G, /* MikroTik RouterBOARD 450G */ -+ ATH79_MACH_RB_493, /* Mikrotik RouterBOARD 493/493AH */ -+ ATH79_MACH_RB_493G, /* Mikrotik RouterBOARD 493G */ -+ ATH79_MACH_RB_711GR100, /* Mikrotik RouterBOARD 911/912 boards */ -+ ATH79_MACH_RB_750, /* MikroTik RouterBOARD 750 */ -+ ATH79_MACH_RB_750G_R3, /* MikroTik RouterBOARD 750GL */ -+ ATH79_MACH_RB_750UPR2, /* MikroTik RouterBOARD 750UP r2 */ -+ ATH79_MACH_RB_751, /* MikroTik RouterBOARD 751 */ -+ ATH79_MACH_RB_751G, /* Mikrotik RouterBOARD 751G */ -+ ATH79_MACH_RB_911L, /* Mikrotik RouterBOARD 911-2Hn/911-5Hn boards */ -+ ATH79_MACH_RB_922GS, /* Mikrotik RouterBOARD 911/922GS boards */ -+ ATH79_MACH_RB_931, /* MikroTik RouterBOARD 931-2nD */ -+ ATH79_MACH_RB_941, /* MikroTik RouterBOARD 941-2nD */ -+ ATH79_MACH_RB_951G, /* Mikrotik RouterBOARD 951G */ -+ ATH79_MACH_RB_951U, /* Mikrotik RouterBOARD 951Ui-2HnD */ -+ ATH79_MACH_RB_952, /* MikroTik RouterBOARD 951Ui-2nD / 952Ui-5ac2nD */ -+ ATH79_MACH_RB_962, /* MikroTik RouterBOARD 962UiGS-5HacT2HnT */ -+ ATH79_MACH_RB_CAP, /* Mikrotik RouterBOARD cAP2nD */ -+ ATH79_MACH_RB_LHG5, /* Mikrotik RouterBOARD LHG5 */ -+ ATH79_MACH_RB_MAP, /* Mikrotik RouterBOARD mAP2nD */ -+ ATH79_MACH_RB_MAPL, /* Mikrotik RouterBOARD mAP L-2nD */ -+ ATH79_MACH_RB_WAP, /* Mikrotik RouterBOARD wAP2nD */ -+ ATH79_MACH_RB_WAPR, /* Mikrotik RouterBOARD wAPR2nD */ -+ ATH79_MACH_RB_WAPAC, /* Mikrotik RouterBOARD wAPG-5HacT2HnD */ -+ ATH79_MACH_RB_SXTLITE2ND, /* Mikrotik RouterBOARD SXT Lite 2nD */ -+ ATH79_MACH_RB_SXTLITE5ND, /* Mikrotik RouterBOARD SXT Lite 5nD */ -+ ATH79_MACH_RE355, /* TP-LINK RE355 */ -+ ATH79_MACH_RE450, /* TP-LINK RE450 */ -+ ATH79_MACH_RME_EG200, /* eTactica EG200 */ -+ ATH79_MACH_RUT9XX, /* Teltonika RUT900 series */ -+ ATH79_MACH_RW2458N, /* Redwave RW2458N */ -+ ATH79_MACH_SC1750, /* Abicom SC1750 */ -+ ATH79_MACH_SC300M, /* Abicom SC300M */ -+ ATH79_MACH_SC450, /* Abicom SC450 */ -+ ATH79_MACH_SMART_300, /* NC-LINK SMART-300 */ -+ ATH79_MACH_SOM9331, /* OpenEmbed SOM9331 */ -+ ATH79_MACH_SR3200, /* YunCore SR3200 */ -+ ATH79_MACH_T830, /* YunCore T830 */ -+ ATH79_MACH_TELLSTICK_ZNET_LITE, /* TellStick ZNet Lite */ -+ ATH79_MACH_TEW_632BRP, /* TRENDnet TEW-632BRP */ -+ ATH79_MACH_TEW_673GRU, /* TRENDnet TEW-673GRU */ -+ ATH79_MACH_TEW_712BR, /* TRENDnet TEW-712BR */ -+ ATH79_MACH_TEW_732BR, /* TRENDnet TEW-732BR */ -+ ATH79_MACH_TEW_823DRU, /* TRENDnet TEW-823DRU */ -+ ATH79_MACH_TL_MR10U, /* TP-LINK TL-MR10U */ -+ ATH79_MACH_TL_MR11U, /* TP-LINK TL-MR11U */ -+ ATH79_MACH_TL_MR13U, /* TP-LINK TL-MR13U */ -+ ATH79_MACH_TL_MR3020, /* TP-LINK TL-MR3020 */ -+ ATH79_MACH_TL_MR3040, /* TP-LINK TL-MR3040 */ -+ ATH79_MACH_TL_MR3040_V2, /* TP-LINK TL-MR3040 v2 */ -+ ATH79_MACH_TL_MR3220, /* TP-LINK TL-MR3220 */ -+ ATH79_MACH_TL_MR3220_V2, /* TP-LINK TL-MR3220 v2 */ -+ ATH79_MACH_TL_MR3420, /* TP-LINK TL-MR3420 */ -+ ATH79_MACH_TL_MR3420_V2, /* TP-LINK TL-MR3420 v2 */ -+ ATH79_MACH_TL_MR6400, /* TP-LINK TL-MR6400 */ -+ ATH79_MACH_TL_WA701ND_V2, /* TP-LINK TL-WA701ND v2 */ -+ ATH79_MACH_TL_WA7210N_V2, /* TP-LINK TL-WA7210N v2 */ -+ ATH79_MACH_TL_WA750RE, /* TP-LINK TL-WA750RE */ -+ ATH79_MACH_TL_WA7510N_V1, /* TP-LINK TL-WA7510N v1 */ -+ ATH79_MACH_TL_WA801ND_V2, /* TP-LINK TL-WA801ND v2 */ -+ ATH79_MACH_TL_WA801ND_V3, /* TP-LINK TL-WA801ND v3 */ -+ ATH79_MACH_TL_WA830RE_V2, /* TP-LINK TL-WA830RE v2 */ -+ ATH79_MACH_TL_WA850RE, /* TP-LINK TL-WA850RE */ -+ ATH79_MACH_TL_WA850RE_V2, /* TP-LINK TL-WA850RE v2 */ -+ ATH79_MACH_TL_WA855RE_V1, /* TP-LINK TL-WA855RE v1 */ -+ ATH79_MACH_TL_WA860RE, /* TP-LINK TL-WA860RE */ -+ ATH79_MACH_TL_WA901ND, /* TP-LINK TL-WA901ND */ -+ ATH79_MACH_TL_WA901ND_V2, /* TP-LINK TL-WA901ND v2 */ -+ ATH79_MACH_TL_WA901ND_V3, /* TP-LINK TL-WA901ND v3 */ -+ ATH79_MACH_TL_WA901ND_V4, /* TP-LINK TL-WA901ND v4 */ -+ ATH79_MACH_TL_WA901ND_V5, /* TP-LINK TL-WA901ND v5 */ -+ ATH79_MACH_TL_WDR3320_V2, /* TP-LINK TL-WDR3320 v2 */ -+ ATH79_MACH_TL_WDR3500, /* TP-LINK TL-WDR3500 */ -+ ATH79_MACH_TL_WDR4300, /* TP-LINK TL-WDR4300 */ -+ ATH79_MACH_TL_WDR4900_V2, /* TP-LINK TL-WDR4900 v2 */ -+ ATH79_MACH_TL_WDR6500_V2, /* TP-LINK TL-WDR6500 v2 */ -+ ATH79_MACH_TL_WPA8630, /* TP-Link TL-WPA8630 */ -+ ATH79_MACH_TL_WR1041N_V2, /* TP-LINK TL-WR1041N v2 */ -+ ATH79_MACH_TL_WR1043N_V5, /* TP-LINK TL-WR1043N v5 */ -+ ATH79_MACH_TL_WR1043ND, /* TP-LINK TL-WR1043ND */ -+ ATH79_MACH_TL_WR1043ND_V2, /* TP-LINK TL-WR1043ND v2 */ -+ ATH79_MACH_TL_WR1043ND_V4, /* TP-LINK TL-WR1043ND v4 */ -+ ATH79_MACH_TL_WR2543N, /* TP-LINK TL-WR2543N/ND */ -+ ATH79_MACH_TL_WR703N, /* TP-LINK TL-WR703N */ -+ ATH79_MACH_TL_WR710N, /* TP-LINK TL-WR710N */ -+ ATH79_MACH_TL_WR720N_V3, /* TP-LINK TL-WR720N v3/v4 */ -+ ATH79_MACH_TL_WR740N_V6, /* TP-LINK TL-WR740N/ND v6 */ -+ ATH79_MACH_TL_WR741ND, /* TP-LINK TL-WR741ND */ -+ ATH79_MACH_TL_WR741ND_V4, /* TP-LINK TL-WR741ND v4 */ -+ ATH79_MACH_TL_WR802N_V1, /* TP-LINK TL-WR802N v1 */ -+ ATH79_MACH_TL_WR802N_V2, /* TP-LINK TL-WR802N v2 */ -+ ATH79_MACH_TL_WR810N, /* TP-LINK TL-WR810N */ -+ ATH79_MACH_TL_WR810N_V2, /* TP-LINK TL-WR810N v2 */ -+ ATH79_MACH_TL_WR840N_V2, /* TP-LINK TL-WR840N v2 */ -+ ATH79_MACH_TL_WR840N_V3, /* TP-LINK TL-WR840N v3 */ -+ ATH79_MACH_TL_WR841N_V1, /* TP-LINK TL-WR841N v1 */ -+ ATH79_MACH_TL_WR841N_V11, /* TP-LINK TL-WR841N/ND v11 */ -+ ATH79_MACH_TL_WR841N_V7, /* TP-LINK TL-WR841N/ND v7 */ -+ ATH79_MACH_TL_WR841N_V8, /* TP-LINK TL-WR841N/ND v8 */ -+ ATH79_MACH_TL_WR841N_V9, /* TP-LINK TL-WR841N/ND v9 */ -+ ATH79_MACH_TL_WR842N_V2, /* TP-LINK TL-WR842N/ND v2 */ -+ ATH79_MACH_TL_WR842N_V3, /* TP-LINK TL-WR842N/ND v3 */ -+ ATH79_MACH_TL_WR902AC_V1, /* TP-LINK TL-WR902AC v1 */ -+ ATH79_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */ -+ ATH79_MACH_TL_WR941ND_V5, /* TP-LINK TL-WR941ND v5 */ -+ ATH79_MACH_TL_WR941ND_V6, /* TP-LINK TL-WR941ND v6 */ -+ ATH79_MACH_TL_WR940N_V4, /* TP-LINK TL-WR940N v4 */ -+ ATH79_MACH_TL_WR940N_V6, /* TP-LINK TL-WR940N v6 */ -+ ATH79_MACH_TL_WR942N_V1, /* TP-LINK TL-WR942N v1 */ -+ ATH79_MACH_TS_D084, /* PISEN TS-D084 */ -+ ATH79_MACH_TUBE2H, /* Alfa Network Tube2H */ -+ ATH79_MACH_UBNT_AIRGW, /* Ubiquiti AirGateway */ -+ ATH79_MACH_UBNT_AIRGWP, /* Ubiquiti AirGateway Pro */ -+ ATH79_MACH_UBNT_AIRROUTER, /* Ubiquiti AirRouter */ -+ ATH79_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */ -+ ATH79_MACH_UBNT_BULLET_M_XW, /* Ubiquiti Bullet M XW */ -+ ATH79_MACH_UBNT_LBE_M5, /* Ubiquiti Litebeam M5 */ -+ ATH79_MACH_UBNT_LOCO_M_XW, /* Ubiquiti Loco M XW */ -+ ATH79_MACH_UBNT_LSSR71, /* Ubiquiti LS-SR71 */ -+ ATH79_MACH_UBNT_LSX, /* Ubiquiti LSX */ -+ ATH79_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */ -+ ATH79_MACH_UBNT_NANO_M_XW, /* Ubiquiti NanoStation M XW */ -+ ATH79_MACH_UBNT_ROCKET_M, /* Ubiquiti Rocket M */ -+ ATH79_MACH_UBNT_ROCKET_M_TI, /* Ubiquiti Rocket M TI */ -+ ATH79_MACH_UBNT_ROCKET_M_XW, /* Ubiquiti Rocket M XW */ -+ ATH79_MACH_UBNT_RS, /* Ubiquiti RouterStation */ -+ ATH79_MACH_UBNT_RSPRO, /* Ubiquiti RouterStation Pro */ -+ ATH79_MACH_UBNT_UAP_PRO, /* Ubiquiti UniFi AP Pro */ -+ ATH79_MACH_UBNT_UNIFI, /* Ubiquiti Unifi */ -+ ATH79_MACH_UBNT_UNIFIAC_LITE, /* Ubiquiti Unifi AC LITE/LR/MESH */ -+ ATH79_MACH_UBNT_UNIFIAC_PRO, /* Ubiquiti Unifi AC PRO/MESH PRO */ -+ ATH79_MACH_UBNT_UNIFI_OUTDOOR, /* Ubiquiti UnifiAP Outdoor */ -+ ATH79_MACH_UBNT_UNIFI_OUTDOOR_PLUS, /* Ubiquiti UnifiAP Outdoor+ */ -+ ATH79_MACH_UBNT_XM, /* Ubiquiti Networks XM board rev 1.0 */ -+ ATH79_MACH_WAM250, /* Samsung WAM250 */ -+ ATH79_MACH_WBS210, /* TP-LINK WBS210 */ -+ ATH79_MACH_WBS510, /* TP-LINK WBS510 */ -+ ATH79_MACH_WEIO, /* WeIO board */ -+ ATH79_MACH_WHR_G301N, /* Buffalo WHR-G301N */ -+ ATH79_MACH_WHR_HP_G300N, /* Buffalo WHR-HP-G300N */ -+ ATH79_MACH_WHR_HP_GN, /* Buffalo WHR-HP-GN */ -+ ATH79_MACH_WIFI_PINEAPPLE_NANO, /* Hak5 WiFi Pineapple NANO */ -+ ATH79_MACH_WLAE_AG300N, /* Buffalo WLAE-AG300N */ -+ ATH79_MACH_WLR8100, /* SITECOM WLR-8100 */ -+ ATH79_MACH_WNDAP360, /* NETGEAR WNDAP360 */ -+ ATH79_MACH_WNDR3700, /* NETGEAR WNDR3700/WNDR3800/WNDRMAC */ -+ ATH79_MACH_WNDR3700_V4, /* NETGEAR WNDR3700v4 */ -+ ATH79_MACH_WNDR4300, /* NETGEAR WNDR4300 */ -+ ATH79_MACH_WNR1000_V2, /* NETGEAR WNR1000 v2 */ -+ ATH79_MACH_WNR2000, /* NETGEAR WNR2000 */ -+ ATH79_MACH_WNR2000_V3, /* NETGEAR WNR2000 v3 */ -+ ATH79_MACH_WNR2000_V4, /* NETGEAR WNR2000 v4 */ -+ ATH79_MACH_WNR2200, /* NETGEAR WNR2200 */ -+ ATH79_MACH_WNR612_V2, /* NETGEAR WNR612 v2 */ -+ ATH79_MACH_WP543, /* Compex WP543 */ -+ ATH79_MACH_WPE72, /* Compex WPE72 */ -+ ATH79_MACH_WPJ342, /* Compex WPJ342 */ -+ ATH79_MACH_WPJ344, /* Compex WPJ344 */ -+ ATH79_MACH_WPJ531, /* Compex WPJ531 */ -+ ATH79_MACH_WPJ558, /* Compex WPJ558 */ -+ ATH79_MACH_WPJ563, /* Compex WPJ563 */ -+ ATH79_MACH_WPN824N, /* NETGEAR WPN824N */ -+ ATH79_MACH_WRT160NL, /* Linksys WRT160NL */ -+ ATH79_MACH_WRT400N, /* Linksys WRT400N */ -+ ATH79_MACH_WRTNODE2Q, /* WRTnode2Q */ -+ ATH79_MACH_WZR_450HP2, /* Buffalo WZR-450HP2 */ -+ ATH79_MACH_WZR_HP_AG300H, /* Buffalo WZR-HP-AG300H */ -+ ATH79_MACH_WZR_HP_G300NH, /* Buffalo WZR-HP-G300NH */ -+ ATH79_MACH_WZR_HP_G300NH2, /* Buffalo WZR-HP-G300NH2 */ -+ ATH79_MACH_WZR_HP_G450H, /* Buffalo WZR-HP-G450H */ -+ ATH79_MACH_XD3200, /* YunCore XD3200 */ -+ ATH79_MACH_Z1, /* Cisco Meraki Z1 */ -+ ATH79_MACH_ZBT_WE1526, /* Zbtlink ZBT-WE1526 */ -+ ATH79_MACH_ZCN_1523H_2, /* Zcomax ZCN-1523H-2-xx */ -+ ATH79_MACH_ZCN_1523H_5, /* Zcomax ZCN-1523H-5-xx */ -+}; -+ -+#endif /* _ATH79_MACHTYPE_H */ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/nvram.c b/target/linux/ar71xx/files/arch/mips/ath79/nvram.c -new file mode 100644 -index 0000000000..a1de55fb19 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/nvram.c -@@ -0,0 +1,85 @@ -+/* -+ * Atheros AR71xx minimal nvram support -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "nvram.h" -+ -+char *ath79_nvram_find_var(const char *name, const char *buf, unsigned buf_len) -+{ -+ unsigned len = strlen(name); -+ char *cur, *last; -+ -+ if (buf_len == 0 || len == 0) -+ return NULL; -+ -+ if (buf_len < len) -+ return NULL; -+ -+ if (len == 1) -+ return memchr(buf, (int) *name, buf_len); -+ -+ last = (char *) buf + buf_len - len; -+ for (cur = (char *) buf; cur <= last; cur++) -+ if (cur[0] == name[0] && memcmp(cur, name, len) == 0) -+ return cur + len; -+ -+ return NULL; -+} -+ -+int ath79_nvram_parse_mac_addr(const char *nvram, unsigned nvram_len, -+ const char *name, char *mac) -+{ -+ char *buf; -+ char *mac_str; -+ int ret; -+ int t; -+ -+ buf = vmalloc(nvram_len); -+ if (!buf) -+ return -ENOMEM; -+ -+ memcpy(buf, nvram, nvram_len); -+ buf[nvram_len - 1] = '\0'; -+ -+ mac_str = ath79_nvram_find_var(name, buf, nvram_len); -+ if (!mac_str) { -+ ret = -EINVAL; -+ goto free; -+ } -+ -+ if (strlen(mac_str) == 19 && mac_str[0] == '"' && mac_str[18] == '"') { -+ mac_str[18] = 0; -+ mac_str++; -+ } -+ -+ t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", -+ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); -+ -+ if (t != ETH_ALEN) -+ t = sscanf(mac_str, "%02hhx-%02hhx-%02hhx-%02hhx-%02hhx-%02hhx", -+ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); -+ -+ if (t != ETH_ALEN) { -+ ret = -EINVAL; -+ goto free; -+ } -+ -+ ret = 0; -+ -+free: -+ vfree(buf); -+ return ret; -+} -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/nvram.h b/target/linux/ar71xx/files/arch/mips/ath79/nvram.h -new file mode 100644 -index 0000000000..75151d4a3c ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/nvram.h -@@ -0,0 +1,19 @@ -+/* -+ * Atheros AR71xx minimal nvram support -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _ATH79_NVRAM_H -+#define _ATH79_NVRAM_H -+ -+char *ath79_nvram_find_var(const char *name, const char *buf, -+ unsigned buf_len); -+int ath79_nvram_parse_mac_addr(const char *nvram, unsigned nvram_len, -+ const char *name, char *mac); -+ -+#endif /* _ATH79_NVRAM_H */ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.c b/target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.c -new file mode 100644 -index 0000000000..2202351806 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.c -@@ -0,0 +1,126 @@ -+/* -+ * Atheros AP94 reference board PCI initialization -+ * -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+struct ath9k_fixup { -+ u16 *cal_data; -+ unsigned slot; -+}; -+ -+static int ath9k_num_fixups; -+static struct ath9k_fixup ath9k_fixups[2]; -+ -+static void ath9k_pci_fixup(struct pci_dev *dev) -+{ -+ void __iomem *mem; -+ u16 *cal_data = NULL; -+ u16 cmd; -+ u32 bar0; -+ u32 val; -+ unsigned i; -+ -+ for (i = 0; i < ath9k_num_fixups; i++) { -+ if (ath9k_fixups[i].cal_data == NULL) -+ continue; -+ -+ if (ath9k_fixups[i].slot != PCI_SLOT(dev->devfn)) -+ continue; -+ -+ cal_data = ath9k_fixups[i].cal_data; -+ break; -+ } -+ -+ if (cal_data == NULL) -+ return; -+ -+ if (*cal_data != 0xa55a) { -+ pr_err("pci %s: invalid calibration data\n", pci_name(dev)); -+ return; -+ } -+ -+ pr_info("pci %s: fixup device configuration\n", pci_name(dev)); -+ -+ mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000); -+ if (!mem) { -+ pr_err("pci %s: ioremap error\n", pci_name(dev)); -+ return; -+ } -+ -+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); -+ -+ switch (ath79_soc) { -+ case ATH79_SOC_AR7161: -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, -+ AR71XX_PCI_MEM_BASE); -+ break; -+ case ATH79_SOC_AR7240: -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffff); -+ break; -+ -+ case ATH79_SOC_AR7241: -+ case ATH79_SOC_AR7242: -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x1000ffff); -+ break; -+ case ATH79_SOC_AR9344: -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x1000ffff); -+ break; -+ -+ default: -+ BUG(); -+ } -+ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+ -+ /* set pointer to first reg address */ -+ cal_data += 3; -+ while (*cal_data != 0xffff) { -+ u32 reg; -+ reg = *cal_data++; -+ val = *cal_data++; -+ val |= (*cal_data++) << 16; -+ -+ __raw_writel(val, mem + reg); -+ udelay(100); -+ } -+ -+ pci_read_config_dword(dev, PCI_VENDOR_ID, &val); -+ dev->vendor = val & 0xffff; -+ dev->device = (val >> 16) & 0xffff; -+ -+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &val); -+ dev->revision = val & 0xff; -+ dev->class = val >> 8; /* upper 3 bytes */ -+ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+ -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0); -+ -+ iounmap(mem); -+} -+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup); -+ -+void __init pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data) -+{ -+ if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups)) -+ return; -+ -+ ath9k_fixups[ath9k_num_fixups].slot = slot; -+ ath9k_fixups[ath9k_num_fixups].cal_data = cal_data; -+ ath9k_num_fixups++; -+} -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.h b/target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.h -new file mode 100644 -index 0000000000..5794941f08 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.h -@@ -0,0 +1,6 @@ -+#ifndef _PCI_ATH9K_FIXUP -+#define _PCI_ATH9K_FIXUP -+ -+void pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data) __init; -+ -+#endif /* _PCI_ATH9K_FIXUP */ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/routerboot.c b/target/linux/ar71xx/files/arch/mips/ath79/routerboot.c -new file mode 100644 -index 0000000000..4c0cd1314a ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/routerboot.c -@@ -0,0 +1,354 @@ -+/* -+ * RouterBoot helper routines -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#define pr_fmt(fmt) "rb: " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "routerboot.h" -+ -+#define RB_BLOCK_SIZE 0x1000 -+#define RB_ART_SIZE 0x10000 -+#define RB_MAGIC_ERD 0x00455244 /* extended radio data */ -+ -+static struct rb_info rb_info; -+ -+static u32 get_u32(void *buf) -+{ -+ u8 *p = buf; -+ -+ return ((u32) p[3] + ((u32) p[2] << 8) + ((u32) p[1] << 16) + -+ ((u32) p[0] << 24)); -+} -+ -+static u16 get_u16(void *buf) -+{ -+ u8 *p = buf; -+ -+ return (u16) p[1] + ((u16) p[0] << 8); -+} -+ -+__init int -+routerboot_find_magic(u8 *buf, unsigned int buflen, u32 *offset, bool hard) -+{ -+ u32 magic_ref = hard ? RB_MAGIC_HARD : RB_MAGIC_SOFT; -+ u32 magic; -+ u32 cur = *offset; -+ -+ while (cur < buflen) { -+ magic = get_u32(buf + cur); -+ if (magic == magic_ref) { -+ *offset = cur; -+ return 0; -+ } -+ -+ cur += 0x1000; -+ } -+ -+ return -ENOENT; -+} -+ -+__init int -+routerboot_find_tag(u8 *buf, unsigned int buflen, u16 tag_id, -+ u8 **tag_data, u16 *tag_len) -+{ -+ uint32_t magic; -+ bool align = false; -+ int ret; -+ -+ if (buflen < 4) -+ return -EINVAL; -+ -+ magic = get_u32(buf); -+ switch (magic) { -+ case RB_MAGIC_ERD: -+ align = true; -+ /* fall trough */ -+ case RB_MAGIC_HARD: -+ /* skip magic value */ -+ buf += 4; -+ buflen -= 4; -+ break; -+ -+ case RB_MAGIC_SOFT: -+ if (buflen < 8) -+ return -EINVAL; -+ -+ /* skip magic and CRC value */ -+ buf += 8; -+ buflen -= 8; -+ -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ ret = -ENOENT; -+ while (buflen > 2) { -+ u16 id; -+ u16 len; -+ -+ len = get_u16(buf); -+ buf += 2; -+ buflen -= 2; -+ -+ if (buflen < 2) -+ break; -+ -+ id = get_u16(buf); -+ buf += 2; -+ buflen -= 2; -+ -+ if (id == RB_ID_TERMINATOR) -+ break; -+ -+ if (buflen < len) -+ break; -+ -+ if (id == tag_id) { -+ if (tag_len) -+ *tag_len = len; -+ if (tag_data) -+ *tag_data = buf; -+ ret = 0; -+ break; -+ } -+ -+ if (align) -+ len = (len + 3) / 4; -+ -+ buf += len; -+ buflen -= len; -+ } -+ -+ return ret; -+} -+ -+static inline int -+rb_find_hard_cfg_tag(u16 tag_id, u8 **tag_data, u16 *tag_len) -+{ -+ if (!rb_info.hard_cfg_data || -+ !rb_info.hard_cfg_size) -+ return -ENOENT; -+ -+ return routerboot_find_tag(rb_info.hard_cfg_data, -+ rb_info.hard_cfg_size, -+ tag_id, tag_data, tag_len); -+} -+ -+__init const char * -+rb_get_board_name(void) -+{ -+ u16 tag_len; -+ u8 *tag; -+ int err; -+ -+ err = rb_find_hard_cfg_tag(RB_ID_BOARD_NAME, &tag, &tag_len); -+ if (err) -+ return NULL; -+ -+ return tag; -+} -+ -+__init u32 -+rb_get_hw_options(void) -+{ -+ u16 tag_len; -+ u8 *tag; -+ int err; -+ -+ err = rb_find_hard_cfg_tag(RB_ID_HW_OPTIONS, &tag, &tag_len); -+ if (err) -+ return 0; -+ -+ return get_u32(tag); -+} -+ -+static void * __init -+__rb_get_wlan_data(u16 id) -+{ -+ u16 tag_len; -+ u8 *tag; -+ void *buf; -+ int err; -+ u32 magic; -+ size_t src_done; -+ size_t dst_done; -+ -+ err = rb_find_hard_cfg_tag(RB_ID_WLAN_DATA, &tag, &tag_len); -+ if (err) { -+ pr_err("no calibration data found\n"); -+ goto err; -+ } -+ -+ buf = kmalloc(RB_ART_SIZE, GFP_KERNEL); -+ if (buf == NULL) { -+ pr_err("no memory for calibration data\n"); -+ goto err; -+ } -+ -+ magic = get_u32(tag); -+ if (magic == RB_MAGIC_ERD) { -+ u8 *erd_data; -+ u16 erd_len; -+ -+ err = routerboot_find_tag(tag, tag_len, 0x1, -+ &erd_data, &erd_len); -+ if (err) { -+ pr_err("no ERD data found for id %u\n", id); -+ goto err_free; -+ } -+ -+ dst_done = RB_ART_SIZE; -+ err = lzo1x_decompress_safe(erd_data, erd_len, buf, &dst_done); -+ if (err) { -+ pr_err("unable to decompress calibration data %d\n", -+ err); -+ goto err_free; -+ } -+ } else { -+ err = rle_decode((char *) tag, tag_len, buf, RB_ART_SIZE, -+ &src_done, &dst_done); -+ if (err) { -+ pr_err("unable to decode calibration data\n"); -+ goto err_free; -+ } -+ } -+ -+ return buf; -+ -+err_free: -+ kfree(buf); -+err: -+ return NULL; -+} -+ -+__init void * -+rb_get_wlan_data(void) -+{ -+ return __rb_get_wlan_data(0); -+} -+ -+__init void * -+rb_get_ext_wlan_data(u16 id) -+{ -+ return __rb_get_wlan_data(id); -+} -+ -+__init const struct rb_info * -+rb_init_info(void *data, unsigned int size) -+{ -+ unsigned int offset; -+ -+ if (size == 0 || (size % RB_BLOCK_SIZE) != 0) -+ return NULL; -+ -+ for (offset = 0; offset < size; offset += RB_BLOCK_SIZE) { -+ u32 magic; -+ -+ magic = get_u32(data + offset); -+ switch (magic) { -+ case RB_MAGIC_HARD: -+ rb_info.hard_cfg_offs = offset; -+ break; -+ -+ case RB_MAGIC_SOFT: -+ rb_info.soft_cfg_offs = offset; -+ break; -+ } -+ } -+ -+ if (!rb_info.hard_cfg_offs) { -+ pr_err("could not find a valid RouterBOOT hard config\n"); -+ return NULL; -+ } -+ -+ if (!rb_info.soft_cfg_offs) { -+ pr_err("could not find a valid RouterBOOT soft config\n"); -+ return NULL; -+ } -+ -+ rb_info.hard_cfg_size = RB_BLOCK_SIZE; -+ rb_info.hard_cfg_data = kmemdup(data + rb_info.hard_cfg_offs, -+ RB_BLOCK_SIZE, GFP_KERNEL); -+ if (!rb_info.hard_cfg_data) -+ return NULL; -+ -+ rb_info.board_name = rb_get_board_name(); -+ rb_info.hw_options = rb_get_hw_options(); -+ -+ return &rb_info; -+} -+ -+#if 0 -+static char *rb_ext_wlan_data; -+ -+static ssize_t -+rb_ext_wlan_data_read(struct file *filp, struct kobject *kobj, -+ struct bin_attribute *attr, char *buf, -+ loff_t off, size_t count) -+{ -+ if (off + count > attr->size) -+ return -EFBIG; -+ -+ memcpy(buf, &rb_ext_wlan_data[off], count); -+ -+ return count; -+} -+ -+static const struct bin_attribute rb_ext_wlan_data_attr = { -+ .attr = { -+ .name = "ext_wlan_data", -+ .mode = S_IRUSR | S_IWUSR, -+ }, -+ .read = rb_ext_wlan_data_read, -+ .size = RB_ART_SIZE, -+}; -+ -+static int __init rb_sysfs_init(void) -+{ -+ struct kobject *rb_kobj; -+ int ret; -+ -+ rb_ext_wlan_data = rb_get_ext_wlan_data(1); -+ if (rb_ext_wlan_data == NULL) -+ return -ENOENT; -+ -+ rb_kobj = kobject_create_and_add("routerboot", firmware_kobj); -+ if (rb_kobj == NULL) { -+ ret = -ENOMEM; -+ pr_err("unable to create sysfs entry\n"); -+ goto err_free_wlan_data; -+ } -+ -+ ret = sysfs_create_bin_file(rb_kobj, &rb_ext_wlan_data_attr); -+ if (ret) { -+ pr_err("unable to create sysfs file, %d\n", ret); -+ goto err_put_kobj; -+ } -+ -+ return 0; -+ -+err_put_kobj: -+ kobject_put(rb_kobj); -+err_free_wlan_data: -+ kfree(rb_ext_wlan_data); -+ return ret; -+} -+ -+late_initcall(rb_sysfs_init); -+#endif -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/routerboot.h b/target/linux/ar71xx/files/arch/mips/ath79/routerboot.h -new file mode 100644 -index 0000000000..cf189362d6 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/routerboot.h -@@ -0,0 +1,89 @@ -+/* -+ * RouterBoot definitions -+ * -+ * Copyright (C) 2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _ATH79_ROUTERBOOT_H_ -+#define _ATH79_ROUTERBOOT_H_ -+ -+struct rb_info { -+ unsigned int hard_cfg_offs; -+ unsigned int hard_cfg_size; -+ void *hard_cfg_data; -+ unsigned int soft_cfg_offs; -+ -+ const char *board_name; -+ u32 hw_options; -+}; -+ -+/* Bit definitions for hardware options */ -+#define RB_HW_OPT_UART_ABSENT BIT(0) -+#define RB_HW_OPT_HAS_VOLTAGE BIT(1) -+#define RB_HW_OPT_HAS_USB BIT(2) -+#define RB_HW_OPT_HAS_ATTINY BIT(3) -+#define RB_HW_OPT_NO_NAND BIT(14) -+#define RB_HW_OPT_HAS_LCD BIT(15) -+#define RB_HW_OPT_HAS_POE_OUT BIT(16) -+#define RB_HW_OPT_HAS_uSD BIT(17) -+#define RB_HW_OPT_HAS_SFP BIT(20) -+#define RB_HW_OPT_HAS_WIFI BIT(21) -+#define RB_HW_OPT_HAS_TS_FOR_ADC BIT(22) -+#define RB_HW_OPT_HAS_PLC BIT(29) -+ -+static inline bool -+rb_hw_option_match(const struct rb_info *info, u32 mask, u32 val) -+{ -+ return (info->hw_options & (val | mask)) == val; -+} -+ -+static inline bool -+rb_has_hw_option(const struct rb_info *info, u32 mask) -+{ -+ return rb_hw_option_match(info, mask, mask); -+} -+ -+#ifdef CONFIG_ATH79_ROUTERBOOT -+const struct rb_info *rb_init_info(void *data, unsigned int size); -+void *rb_get_wlan_data(void); -+void *rb_get_ext_wlan_data(u16 id); -+ -+int routerboot_find_tag(u8 *buf, unsigned int buflen, u16 tag_id, -+ u8 **tag_data, u16 *tag_len); -+int routerboot_find_magic(u8 *buf, unsigned int buflen, u32 *offset, bool hard); -+#else -+static inline const struct rb_info * -+rb_init_info(void *data, unsigned int size) -+{ -+ return NULL; -+} -+ -+static inline void *rb_get_wlan_data(void) -+{ -+ return NULL; -+} -+ -+static inline void *rb_get_wlan_data(u16 id) -+{ -+ return NULL; -+} -+ -+static inline int -+routerboot_find_tag(u8 *buf, unsigned int buflen, u16 tag_id, -+ u8 **tag_data, u16 *tag_len) -+{ -+ return -ENOENT; -+} -+ -+static inline int -+routerboot_find_magic(u8 *buf, unsigned int buflen, u32 *offset, bool hard) -+{ -+ return -ENOENT; -+} -+#endif -+ -+#endif /* _ATH79_ROUTERBOOT_H_ */ -diff --git a/target/linux/ar71xx/files/arch/mips/include/asm/fw/myloader/myloader.h b/target/linux/ar71xx/files/arch/mips/include/asm/fw/myloader/myloader.h -new file mode 100644 -index 0000000000..8a99d566d7 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/include/asm/fw/myloader/myloader.h -@@ -0,0 +1,34 @@ -+/* -+ * Compex's MyLoader specific definitions -+ * -+ * Copyright (C) 2006-2008 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#ifndef _ASM_MIPS_FW_MYLOADER_H -+#define _ASM_MIPS_FW_MYLOADER_H -+ -+#include -+ -+struct myloader_info { -+ uint32_t vid; -+ uint32_t did; -+ uint32_t svid; -+ uint32_t sdid; -+ uint8_t macs[MYLO_ETHADDR_COUNT][6]; -+}; -+ -+#ifdef CONFIG_MYLOADER -+extern struct myloader_info *myloader_get_info(void) __init; -+#else -+static inline struct myloader_info *myloader_get_info(void) -+{ -+ return NULL; -+} -+#endif /* CONFIG_MYLOADER */ -+ -+#endif /* _ASM_MIPS_FW_MYLOADER_H */ -diff --git a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h -new file mode 100644 -index 0000000000..e476d57e45 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h -@@ -0,0 +1,65 @@ -+/* -+ * Atheros AR71xx SoC specific platform data definitions -+ * -+ * Copyright (C) 2008-2012 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef __ASM_MACH_ATH79_PLATFORM_H -+#define __ASM_MACH_ATH79_PLATFORM_H -+ -+#include -+#include -+#include -+#include -+ -+struct ag71xx_switch_platform_data { -+ u8 phy4_mii_en:1; -+ u8 phy_poll_mask; -+}; -+ -+struct ag71xx_platform_data { -+ phy_interface_t phy_if_mode; -+ u32 phy_mask; -+ int speed; -+ int duplex; -+ u32 reset_bit; -+ u8 mac_addr[ETH_ALEN]; -+ struct device *mii_bus_dev; -+ -+ u8 has_gbit:1; -+ u8 is_ar91xx:1; -+ u8 is_ar7240:1; -+ u8 is_ar724x:1; -+ u8 has_ar8216:1; -+ u8 use_flow_control:1; -+ u8 enable_sgmii_fixup:1; -+ u8 disable_inline_checksum_engine:1; -+ -+ struct ag71xx_switch_platform_data *switch_data; -+ -+ void (*ddr_flush)(void); -+ void (*set_speed)(int speed); -+ void (*update_pll)(u32 pll_10, u32 pll_100, u32 pll_1000); -+ -+ unsigned int max_frame_len; -+ unsigned int desc_pktlen_mask; -+}; -+ -+struct ag71xx_mdio_platform_data { -+ u32 phy_mask; -+ u8 builtin_switch:1; -+ u8 is_ar7240:1; -+ u8 is_ar9330:1; -+ u8 is_ar934x:1; -+ unsigned long mdio_clock; -+ unsigned long ref_clock; -+ -+ void (*reset)(struct mii_bus *bus); -+}; -+ -+#endif /* __ASM_MACH_ATH79_PLATFORM_H */ -diff --git a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/mach-rb750.h b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/mach-rb750.h -new file mode 100644 -index 0000000000..50d5a20974 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/mach-rb750.h -@@ -0,0 +1,84 @@ -+/* -+ * MikroTik RouterBOARD 750 definitions -+ * -+ * Copyright (C) 2010-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+#ifndef _MACH_RB750_H -+#define _MACH_RB750_H -+ -+#include -+ -+#define RB750_GPIO_LVC573_LE 0 /* Latch enable on LVC573 */ -+#define RB750_GPIO_NAND_IO0 1 /* NAND I/O 0 */ -+#define RB750_GPIO_NAND_IO1 2 /* NAND I/O 1 */ -+#define RB750_GPIO_NAND_IO2 3 /* NAND I/O 2 */ -+#define RB750_GPIO_NAND_IO3 4 /* NAND I/O 3 */ -+#define RB750_GPIO_NAND_IO4 5 /* NAND I/O 4 */ -+#define RB750_GPIO_NAND_IO5 6 /* NAND I/O 5 */ -+#define RB750_GPIO_NAND_IO6 7 /* NAND I/O 6 */ -+#define RB750_GPIO_NAND_IO7 8 /* NAND I/O 7 */ -+#define RB750_GPIO_NAND_NCE 11 /* NAND Chip Enable (active low) */ -+#define RB750_GPIO_NAND_RDY 12 /* NAND Ready */ -+#define RB750_GPIO_NAND_CLE 14 /* NAND Command Latch Enable */ -+#define RB750_GPIO_NAND_ALE 15 /* NAND Address Latch Enable */ -+#define RB750_GPIO_NAND_NRE 16 /* NAND Read Enable (active low) */ -+#define RB750_GPIO_NAND_NWE 17 /* NAND Write Enable (active low) */ -+ -+#define RB750_GPIO_BTN_RESET 1 -+#define RB750_GPIO_SPI_CS0 2 -+#define RB750_GPIO_LED_ACT 12 -+#define RB750_GPIO_LED_PORT1 13 -+#define RB750_GPIO_LED_PORT2 14 -+#define RB750_GPIO_LED_PORT3 15 -+#define RB750_GPIO_LED_PORT4 16 -+#define RB750_GPIO_LED_PORT5 17 -+ -+#define RB750_LED_ACT BIT(RB750_GPIO_LED_ACT) -+#define RB750_LED_PORT1 BIT(RB750_GPIO_LED_PORT1) -+#define RB750_LED_PORT2 BIT(RB750_GPIO_LED_PORT2) -+#define RB750_LED_PORT3 BIT(RB750_GPIO_LED_PORT3) -+#define RB750_LED_PORT4 BIT(RB750_GPIO_LED_PORT4) -+#define RB750_LED_PORT5 BIT(RB750_GPIO_LED_PORT5) -+#define RB750_NAND_NCE BIT(RB750_GPIO_NAND_NCE) -+ -+#define RB750_LVC573_LE BIT(RB750_GPIO_LVC573_LE) -+ -+#define RB750_LED_BITS (RB750_LED_PORT1 | RB750_LED_PORT2 | RB750_LED_PORT3 | \ -+ RB750_LED_PORT4 | RB750_LED_PORT5 | RB750_LED_ACT) -+ -+#define RB7XX_GPIO_NAND_NCE 0 -+#define RB7XX_GPIO_MON 9 -+#define RB7XX_GPIO_LED_ACT 11 -+#define RB7XX_GPIO_USB_POWERON 13 -+ -+#define RB7XX_NAND_NCE BIT(RB7XX_GPIO_NAND_NCE) -+#define RB7XX_LED_ACT BIT(RB7XX_GPIO_LED_ACT) -+#define RB7XX_MONITOR BIT(RB7XX_GPIO_MON) -+#define RB7XX_USB_POWERON BIT(RB7XX_GPIO_USB_POWERON) -+ -+struct rb750_led_data { -+ char *name; -+ char *default_trigger; -+ u32 mask; -+ int active_low; -+}; -+ -+struct rb750_led_platform_data { -+ int num_leds; -+ struct rb750_led_data *leds; -+ void (*latch_change)(u32 clear, u32 set); -+}; -+ -+struct rb7xx_nand_platform_data { -+ u32 nce_line; -+ -+ void (*enable_pins)(void); -+ void (*disable_pins)(void); -+ void (*latch_change)(u32, u32); -+}; -+ -+#endif /* _MACH_RB750_H */ -\ No newline at end of file -diff --git a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/rb4xx_cpld.h b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/rb4xx_cpld.h -new file mode 100644 -index 0000000000..37512ba1a1 ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/rb4xx_cpld.h -@@ -0,0 +1,43 @@ -+/* -+ * SPI driver definitions for the CPLD chip on the Mikrotik RB4xx boards -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This file was based on the patches for Linux 2.6.27.39 published by -+ * MikroTik for their RouterBoard 4xx series devices. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#define CPLD_GPIO_nLED1 0 -+#define CPLD_GPIO_nLED2 1 -+#define CPLD_GPIO_nLED3 2 -+#define CPLD_GPIO_nLED4 3 -+#define CPLD_GPIO_FAN 4 -+#define CPLD_GPIO_ALE 5 -+#define CPLD_GPIO_CLE 6 -+#define CPLD_GPIO_nCE 7 -+#define CPLD_GPIO_nLED5 8 -+ -+#define CPLD_NUM_GPIOS 9 -+ -+#define CPLD_CFG_nLED1 BIT(CPLD_GPIO_nLED1) -+#define CPLD_CFG_nLED2 BIT(CPLD_GPIO_nLED2) -+#define CPLD_CFG_nLED3 BIT(CPLD_GPIO_nLED3) -+#define CPLD_CFG_nLED4 BIT(CPLD_GPIO_nLED4) -+#define CPLD_CFG_FAN BIT(CPLD_GPIO_FAN) -+#define CPLD_CFG_ALE BIT(CPLD_GPIO_ALE) -+#define CPLD_CFG_CLE BIT(CPLD_GPIO_CLE) -+#define CPLD_CFG_nCE BIT(CPLD_GPIO_nCE) -+#define CPLD_CFG_nLED5 BIT(CPLD_GPIO_nLED5) -+ -+struct rb4xx_cpld_platform_data { -+ unsigned gpio_base; -+}; -+ -+extern int rb4xx_cpld_change_cfg(unsigned mask, unsigned value); -+extern int rb4xx_cpld_read(unsigned char *rx_buf, -+ unsigned cnt); -+extern int rb4xx_cpld_write(const unsigned char *buf, unsigned count); -diff --git a/target/linux/ar71xx/files/drivers/gpio/gpio-latch.c b/target/linux/ar71xx/files/drivers/gpio/gpio-latch.c -new file mode 100644 -index 0000000000..d911f6a2cb ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/gpio/gpio-latch.c -@@ -0,0 +1,220 @@ -+/* -+ * GPIO latch driver -+ * -+ * Copyright (C) 2014 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+struct gpio_latch_chip { -+ struct gpio_chip gc; -+ -+ struct mutex mutex; -+ struct mutex latch_mutex; -+ bool latch_enabled; -+ int le_gpio; -+ bool le_active_low; -+ int *gpios; -+}; -+ -+static inline struct gpio_latch_chip *to_gpio_latch_chip(struct gpio_chip *gc) -+{ -+ return container_of(gc, struct gpio_latch_chip, gc); -+} -+ -+static void gpio_latch_lock(struct gpio_latch_chip *glc, bool enable) -+{ -+ mutex_lock(&glc->mutex); -+ -+ if (enable) -+ glc->latch_enabled = true; -+ -+ if (glc->latch_enabled) -+ mutex_lock(&glc->latch_mutex); -+} -+ -+static void gpio_latch_unlock(struct gpio_latch_chip *glc, bool disable) -+{ -+ if (glc->latch_enabled) -+ mutex_unlock(&glc->latch_mutex); -+ -+ if (disable) -+ glc->latch_enabled = true; -+ -+ mutex_unlock(&glc->mutex); -+} -+ -+static int -+gpio_latch_get(struct gpio_chip *gc, unsigned offset) -+{ -+ struct gpio_latch_chip *glc = to_gpio_latch_chip(gc); -+ int ret; -+ -+ gpio_latch_lock(glc, false); -+ ret = gpio_get_value(glc->gpios[offset]); -+ gpio_latch_unlock(glc, false); -+ -+ return ret; -+} -+ -+static void -+gpio_latch_set(struct gpio_chip *gc, unsigned offset, int value) -+{ -+ struct gpio_latch_chip *glc = to_gpio_latch_chip(gc); -+ bool enable_latch = false; -+ bool disable_latch = false; -+ int gpio; -+ -+ gpio = glc->gpios[offset]; -+ -+ if (gpio == glc->le_gpio) { -+ enable_latch = value ^ glc->le_active_low; -+ disable_latch = !enable_latch; -+ } -+ -+ gpio_latch_lock(glc, enable_latch); -+ gpio_set_value(gpio, value); -+ gpio_latch_unlock(glc, disable_latch); -+} -+ -+static int -+gpio_latch_direction_input(struct gpio_chip *gc, unsigned offset) -+{ -+ struct gpio_latch_chip *glc = to_gpio_latch_chip(gc); -+ int ret; -+ -+ gpio_latch_lock(glc, false); -+ ret = gpio_direction_input(glc->gpios[offset]); -+ gpio_latch_unlock(glc, false); -+ -+ return ret; -+} -+ -+static int -+gpio_latch_direction_output(struct gpio_chip *gc, unsigned offset, int value) -+{ -+ struct gpio_latch_chip *glc = to_gpio_latch_chip(gc); -+ bool enable_latch = false; -+ bool disable_latch = false; -+ int gpio; -+ int ret; -+ -+ gpio = glc->gpios[offset]; -+ -+ if (gpio == glc->le_gpio) { -+ enable_latch = value ^ glc->le_active_low; -+ disable_latch = !enable_latch; -+ } -+ -+ gpio_latch_lock(glc, enable_latch); -+ ret = gpio_direction_output(gpio, value); -+ gpio_latch_unlock(glc, disable_latch); -+ -+ return ret; -+} -+ -+static int gpio_latch_probe(struct platform_device *pdev) -+{ -+ struct gpio_latch_chip *glc; -+ struct gpio_latch_platform_data *pdata; -+ struct gpio_chip *gc; -+ int size; -+ int ret; -+ int i; -+ -+ pdata = dev_get_platdata(&pdev->dev); -+ if (!pdata) -+ return -EINVAL; -+ -+ if (pdata->le_gpio_index >= pdata->num_gpios || -+ !pdata->num_gpios || -+ !pdata->gpios) -+ return -EINVAL; -+ -+ for (i = 0; i < pdata->num_gpios; i++) { -+ int gpio = pdata->gpios[i]; -+ -+ ret = devm_gpio_request(&pdev->dev, gpio, -+ GPIO_LATCH_DRIVER_NAME); -+ if (ret) -+ return ret; -+ } -+ -+ glc = devm_kzalloc(&pdev->dev, sizeof(*glc), GFP_KERNEL); -+ if (!glc) -+ return -ENOMEM; -+ -+ mutex_init(&glc->mutex); -+ mutex_init(&glc->latch_mutex); -+ -+ size = pdata->num_gpios * sizeof(glc->gpios[0]); -+ glc->gpios = devm_kzalloc(&pdev->dev, size , GFP_KERNEL); -+ if (!glc->gpios) -+ return -ENOMEM; -+ -+ memcpy(glc->gpios, pdata->gpios, size); -+ -+ glc->le_gpio = glc->gpios[pdata->le_gpio_index]; -+ glc->le_active_low = pdata->le_active_low; -+ -+ gc = &glc->gc; -+ -+ gc->label = GPIO_LATCH_DRIVER_NAME; -+ gc->base = pdata->base; -+ gc->can_sleep = true; -+ gc->ngpio = pdata->num_gpios; -+ gc->get = gpio_latch_get; -+ gc->set = gpio_latch_set; -+ gc->direction_input = gpio_latch_direction_input, -+ gc->direction_output = gpio_latch_direction_output; -+ -+ platform_set_drvdata(pdev, glc); -+ -+ ret = gpiochip_add(&glc->gc); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static int gpio_latch_remove(struct platform_device *pdev) -+{ -+ struct gpio_latch_chip *glc = platform_get_drvdata(pdev); -+ -+ gpiochip_remove(&glc->gc); -+ return 0; -+} -+ -+ -+static struct platform_driver gpio_latch_driver = { -+ .probe = gpio_latch_probe, -+ .remove = gpio_latch_remove, -+ .driver = { -+ .name = GPIO_LATCH_DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init gpio_latch_init(void) -+{ -+ return platform_driver_register(&gpio_latch_driver); -+} -+ -+postcore_initcall(gpio_latch_init); -+ -+MODULE_DESCRIPTION("GPIO latch driver"); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" GPIO_LATCH_DRIVER_NAME); -diff --git a/target/linux/ar71xx/files/drivers/gpio/gpio-nxp-74hc153.c b/target/linux/ar71xx/files/drivers/gpio/gpio-nxp-74hc153.c -new file mode 100644 -index 0000000000..82e6e943ff ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/gpio/gpio-nxp-74hc153.c -@@ -0,0 +1,243 @@ -+/* -+ * NXP 74HC153 - Dual 4-input multiplexer GPIO driver -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define NXP_74HC153_NUM_GPIOS 8 -+#define NXP_74HC153_S0_MASK 0x1 -+#define NXP_74HC153_S1_MASK 0x2 -+#define NXP_74HC153_BANK_MASK 0x4 -+ -+struct nxp_74hc153_chip { -+ struct device *parent; -+ struct gpio_chip gpio_chip; -+ struct mutex lock; -+}; -+ -+static struct nxp_74hc153_chip *gpio_to_nxp(struct gpio_chip *gc) -+{ -+ return container_of(gc, struct nxp_74hc153_chip, gpio_chip); -+} -+ -+static int nxp_74hc153_direction_input(struct gpio_chip *gc, unsigned offset) -+{ -+ return 0; -+} -+ -+static int nxp_74hc153_direction_output(struct gpio_chip *gc, -+ unsigned offset, int val) -+{ -+ return -EINVAL; -+} -+ -+static int nxp_74hc153_get_value(struct gpio_chip *gc, unsigned offset) -+{ -+ struct nxp_74hc153_chip *nxp; -+ struct nxp_74hc153_platform_data *pdata; -+ unsigned s0; -+ unsigned s1; -+ unsigned pin; -+ int ret; -+ -+ nxp = gpio_to_nxp(gc); -+ pdata = nxp->parent->platform_data; -+ -+ s0 = !!(offset & NXP_74HC153_S0_MASK); -+ s1 = !!(offset & NXP_74HC153_S1_MASK); -+ pin = (offset & NXP_74HC153_BANK_MASK) ? pdata->gpio_pin_2y -+ : pdata->gpio_pin_1y; -+ -+ mutex_lock(&nxp->lock); -+ gpio_set_value(pdata->gpio_pin_s0, s0); -+ gpio_set_value(pdata->gpio_pin_s1, s1); -+ ret = gpio_get_value(pin); -+ mutex_unlock(&nxp->lock); -+ -+ return ret; -+} -+ -+static void nxp_74hc153_set_value(struct gpio_chip *gc, -+ unsigned offset, int val) -+{ -+ /* not supported */ -+} -+ -+static int nxp_74hc153_probe(struct platform_device *pdev) -+{ -+ struct nxp_74hc153_platform_data *pdata; -+ struct nxp_74hc153_chip *nxp; -+ struct gpio_chip *gc; -+ int err; -+ -+ pdata = pdev->dev.platform_data; -+ if (pdata == NULL) { -+ dev_dbg(&pdev->dev, "no platform data specified\n"); -+ return -EINVAL; -+ } -+ -+ nxp = kzalloc(sizeof(struct nxp_74hc153_chip), GFP_KERNEL); -+ if (nxp == NULL) { -+ dev_err(&pdev->dev, "no memory for private data\n"); -+ return -ENOMEM; -+ } -+ -+ err = gpio_request(pdata->gpio_pin_s0, dev_name(&pdev->dev)); -+ if (err) { -+ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", -+ pdata->gpio_pin_s0, err); -+ goto err_free_nxp; -+ } -+ -+ err = gpio_request(pdata->gpio_pin_s1, dev_name(&pdev->dev)); -+ if (err) { -+ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", -+ pdata->gpio_pin_s1, err); -+ goto err_free_s0; -+ } -+ -+ err = gpio_request(pdata->gpio_pin_1y, dev_name(&pdev->dev)); -+ if (err) { -+ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", -+ pdata->gpio_pin_1y, err); -+ goto err_free_s1; -+ } -+ -+ err = gpio_request(pdata->gpio_pin_2y, dev_name(&pdev->dev)); -+ if (err) { -+ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", -+ pdata->gpio_pin_2y, err); -+ goto err_free_1y; -+ } -+ -+ err = gpio_direction_output(pdata->gpio_pin_s0, 0); -+ if (err) { -+ dev_err(&pdev->dev, -+ "unable to set direction of gpio %u, err=%d\n", -+ pdata->gpio_pin_s0, err); -+ goto err_free_2y; -+ } -+ -+ err = gpio_direction_output(pdata->gpio_pin_s1, 0); -+ if (err) { -+ dev_err(&pdev->dev, -+ "unable to set direction of gpio %u, err=%d\n", -+ pdata->gpio_pin_s1, err); -+ goto err_free_2y; -+ } -+ -+ err = gpio_direction_input(pdata->gpio_pin_1y); -+ if (err) { -+ dev_err(&pdev->dev, -+ "unable to set direction of gpio %u, err=%d\n", -+ pdata->gpio_pin_1y, err); -+ goto err_free_2y; -+ } -+ -+ err = gpio_direction_input(pdata->gpio_pin_2y); -+ if (err) { -+ dev_err(&pdev->dev, -+ "unable to set direction of gpio %u, err=%d\n", -+ pdata->gpio_pin_2y, err); -+ goto err_free_2y; -+ } -+ -+ nxp->parent = &pdev->dev; -+ mutex_init(&nxp->lock); -+ -+ gc = &nxp->gpio_chip; -+ -+ gc->direction_input = nxp_74hc153_direction_input; -+ gc->direction_output = nxp_74hc153_direction_output; -+ gc->get = nxp_74hc153_get_value; -+ gc->set = nxp_74hc153_set_value; -+ gc->can_sleep = 1; -+ -+ gc->base = pdata->gpio_base; -+ gc->ngpio = NXP_74HC153_NUM_GPIOS; -+ gc->label = dev_name(nxp->parent); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) -+ gc->dev = nxp->parent; -+#else -+ gc->parent = nxp->parent; -+#endif -+ gc->owner = THIS_MODULE; -+ -+ err = gpiochip_add(&nxp->gpio_chip); -+ if (err) { -+ dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err); -+ goto err_free_2y; -+ } -+ -+ platform_set_drvdata(pdev, nxp); -+ return 0; -+ -+err_free_2y: -+ gpio_free(pdata->gpio_pin_2y); -+err_free_1y: -+ gpio_free(pdata->gpio_pin_1y); -+err_free_s1: -+ gpio_free(pdata->gpio_pin_s1); -+err_free_s0: -+ gpio_free(pdata->gpio_pin_s0); -+err_free_nxp: -+ kfree(nxp); -+ return err; -+} -+ -+static int nxp_74hc153_remove(struct platform_device *pdev) -+{ -+ struct nxp_74hc153_chip *nxp = platform_get_drvdata(pdev); -+ struct nxp_74hc153_platform_data *pdata = pdev->dev.platform_data; -+ -+ if (nxp) { -+ gpiochip_remove(&nxp->gpio_chip); -+ gpio_free(pdata->gpio_pin_2y); -+ gpio_free(pdata->gpio_pin_1y); -+ gpio_free(pdata->gpio_pin_s1); -+ gpio_free(pdata->gpio_pin_s0); -+ -+ kfree(nxp); -+ platform_set_drvdata(pdev, NULL); -+ } -+ -+ return 0; -+} -+ -+static struct platform_driver nxp_74hc153_driver = { -+ .probe = nxp_74hc153_probe, -+ .remove = nxp_74hc153_remove, -+ .driver = { -+ .name = NXP_74HC153_DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init nxp_74hc153_init(void) -+{ -+ return platform_driver_register(&nxp_74hc153_driver); -+} -+subsys_initcall(nxp_74hc153_init); -+ -+static void __exit nxp_74hc153_exit(void) -+{ -+ platform_driver_unregister(&nxp_74hc153_driver); -+} -+module_exit(nxp_74hc153_exit); -+ -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_DESCRIPTION("GPIO expander driver for NXP 74HC153"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" NXP_74HC153_DRIVER_NAME); -diff --git a/target/linux/ar71xx/files/drivers/leds/leds-nu801.c b/target/linux/ar71xx/files/drivers/leds/leds-nu801.c -new file mode 100644 -index 0000000000..11e8927785 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/leds/leds-nu801.c -@@ -0,0 +1,396 @@ -+/* -+ * LED driver for NU801 -+ * -+ * Kevin Paul Herbert -+ * Copyright (c) 2012, Meraki, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define MAX_NAME_LENGTH 24 -+#define NUM_COLORS 3 -+ -+static const char * const led_nu801_colors[] = { "blue", "green", "red" }; -+ -+struct led_nu801_led_data { -+ struct led_classdev cdev; -+ struct led_nu801_data *controller; -+ enum led_brightness level; -+ char name[MAX_NAME_LENGTH]; -+}; -+ -+struct led_nu801_data { -+ unsigned cki; -+ unsigned sdi; -+ int lei; -+ struct delayed_work work; -+ struct led_nu801_led_data *led_chain; -+ int num_leds; -+ const char *device_name; -+ const char *name; -+ u32 ndelay; -+ atomic_t pending; -+}; -+ -+static void led_nu801_work(struct work_struct *work) -+{ -+ struct led_nu801_data *controller = -+ container_of(work, struct led_nu801_data, work.work); -+ struct led_nu801_led_data *led; -+ u16 bit; -+ u16 brightness; -+ int index; -+ -+ for (index = 0; index < controller->num_leds; index++) { -+ led = &controller->led_chain[index]; -+ brightness = led->level << 8; /* To do: gamma correction */ -+ for (bit = 0x8000; bit; bit = bit >> 1) { -+ gpio_set_value(controller->sdi, -+ (brightness & bit) != 0); -+ gpio_set_value(controller->cki, 1); -+ if (unlikely(((index == (controller->num_leds - 1)) && -+ (bit == 1) && -+ (controller->lei < 0)))) { -+ udelay(600); -+ } else { -+ ndelay(controller->ndelay); -+ } -+ gpio_set_value(controller->cki, 0); -+ ndelay(controller->ndelay); -+ } -+ } -+ if (controller->lei >= 0) { -+ gpio_set_value(controller->lei, 1); -+ ndelay(controller->ndelay); -+ gpio_set_value(controller->lei, 0); -+ } -+ atomic_set(&controller->pending, 1); -+} -+ -+static void led_nu801_set(struct led_classdev *led_cdev, -+ enum led_brightness value) -+{ -+ struct led_nu801_led_data *led_dat = -+ container_of(led_cdev, struct led_nu801_led_data, cdev); -+ struct led_nu801_data *controller = led_dat->controller; -+ -+ if (led_dat->level != value) { -+ led_dat->level = value; -+ if (atomic_dec_and_test(&controller->pending)) -+ schedule_delayed_work(&led_dat->controller->work, -+ (HZ/1000) + 1); -+ } -+} -+ -+static int led_nu801_create(struct led_nu801_data *controller, -+ struct device *parent, -+ int index, -+ enum led_brightness brightness, -+#ifdef CONFIG_LEDS_TRIGGERS -+ const char *default_trigger, -+#endif -+ const char *color) -+{ -+ struct led_nu801_led_data *led = &controller->led_chain[index]; -+ int ret; -+ -+ scnprintf(led->name, sizeof(led->name), "%s:%s:%s%d", -+ controller->device_name, color, controller->name, -+ (controller->num_leds - (index + 1)) / NUM_COLORS); -+ led->cdev.name = led->name; -+ led->cdev.brightness_set = led_nu801_set; -+#ifdef CONFIG_LEDS_TRIGGERS -+ led->cdev.default_trigger = default_trigger; -+#endif -+ led->level = brightness; -+ led->controller = controller; -+ ret = led_classdev_register(parent, &led->cdev); -+ if (ret < 0) -+ goto err; -+ -+ return 0; -+ -+err: -+ kfree(led); -+ return ret; -+} -+ -+static int -+led_nu801_create_chain(const struct led_nu801_template *template, -+ struct led_nu801_data *controller, -+ struct device *parent) -+{ -+ int ret; -+ int index; -+ -+ controller->cki = template->cki; -+ controller->sdi = template->sdi; -+ controller->lei = template->lei; -+ controller->num_leds = template->num_leds * 3; -+ controller->device_name = template->device_name; -+ controller->name = template->name; -+ controller->ndelay = template->ndelay; -+ atomic_set(&controller->pending, 1); -+ -+ controller->led_chain = kzalloc(sizeof(struct led_nu801_led_data) * -+ controller->num_leds, GFP_KERNEL); -+ -+ if (!controller->led_chain) -+ return -ENOMEM; -+ -+ ret = gpio_request(controller->cki, template->name); -+ if (ret < 0) -+ goto err_free_chain; -+ -+ ret = gpio_request(controller->sdi, template->name); -+ if (ret < 0) -+ goto err_ret_cki; -+ -+ if (controller->lei >= 0) { -+ ret = gpio_request(controller->lei, template->name); -+ if (ret < 0) -+ goto err_ret_sdi; -+ ret = gpio_direction_output(controller->lei, 0); -+ if (ret < 0) -+ goto err_ret_lei; -+ } -+ -+ ret = gpio_direction_output(controller->cki, 0); -+ if (ret < 0) -+ goto err_ret_lei; -+ -+ ret = gpio_direction_output(controller->sdi, 0); -+ if (ret < 0) -+ goto err_ret_lei; -+ -+ for (index = 0; index < controller->num_leds; index++) { -+ ret = led_nu801_create(controller, parent, index, -+ template->init_brightness -+ [index % NUM_COLORS], -+#ifdef CONFIG_LEDS_TRIGGERS -+ template->default_trigger, -+#endif -+ template->led_colors[index % NUM_COLORS] ? -+ template->led_colors[index % NUM_COLORS] : -+ led_nu801_colors[index % NUM_COLORS]); -+ if (ret < 0) -+ goto err_ret_sdi; -+ } -+ -+ INIT_DELAYED_WORK(&controller->work, led_nu801_work); -+ schedule_delayed_work(&controller->work, 0); -+ -+ return 0; -+ -+err_ret_lei: -+ if (controller->lei >= 0) -+ gpio_free(controller->lei); -+err_ret_sdi: -+ gpio_free(controller->sdi); -+err_ret_cki: -+ gpio_free(controller->cki); -+err_free_chain: -+ kfree(controller->led_chain); -+ -+ return ret; -+} -+ -+static void led_nu801_delete_chain(struct led_nu801_data *controller) -+{ -+ struct led_nu801_led_data *led_chain; -+ struct led_nu801_led_data *led; -+ int index; -+ int num_leds; -+ -+ led_chain = controller->led_chain; -+ controller->led_chain = 0; -+ num_leds = controller->num_leds; -+ controller->num_leds = 0; -+ cancel_delayed_work_sync(&controller->work); -+ -+ for (index = 0; index < num_leds; index++) { -+ led = &led_chain[index]; -+ led_classdev_unregister(&led->cdev); -+ } -+ -+ gpio_free(controller->cki); -+ gpio_free(controller->sdi); -+ if (controller->lei >= 0) -+ gpio_free(controller->lei); -+ -+ kfree(led_chain); -+} -+ -+static struct led_nu801_data * -+leds_nu801_create_of(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node, *child; -+ struct led_nu801_data *controllers; -+ int count = 0, ret; -+ int i = 0; -+ -+ for_each_child_of_node(np, child) -+ count++; -+ if (!count) -+ return NULL; -+ -+ controllers = kzalloc(sizeof(struct led_nu801_data) * count, -+ GFP_KERNEL); -+ if (!controllers) -+ return NULL; -+ -+ for_each_child_of_node(np, child) { -+ const char *state; -+ struct led_nu801_template template = {}; -+ struct device_node *colors; -+ int jj; -+ -+ template.cki = of_get_named_gpio_flags(child, "cki", 0, NULL); -+ template.sdi = of_get_named_gpio_flags(child, "sdi", 0, NULL); -+ if (of_find_property(child, "lei", NULL)) { -+ template.lei = of_get_named_gpio_flags(child, "lei", -+ 0, NULL); -+ } else { -+ template.lei = -1; -+ } -+ of_property_read_u32(child, "ndelay", &template.ndelay); -+ of_property_read_u32(child, "num_leds", &template.num_leds); -+ template.name = of_get_property(child, "label", NULL) ? : -+ child->name; -+ template.default_trigger = of_get_property(child, -+ "default-trigger", NULL); -+ -+ jj = 0; -+ for_each_child_of_node(child, colors) { -+ template.led_colors[jj] = of_get_property(colors, -+ "label", NULL); -+ state = of_get_property(colors, "state", NULL); -+ if (!strncmp(state, "off", 3)) -+ template.init_brightness[jj] = LED_OFF; -+ else if (!strncmp(state, "half", 4)) -+ template.init_brightness[jj] = LED_HALF; -+ else if (!strncmp(state, "full", 4)) -+ template.init_brightness[jj] = LED_FULL; -+ jj++; -+ } -+ -+ ret = led_nu801_create_chain(&template, -+ &controllers[i], -+ &pdev->dev); -+ if (ret < 0) -+ goto err; -+ i++; -+ } -+ -+ return controllers; -+ -+err: -+ for (i = i - 1; i >= 0; i--) -+ led_nu801_delete_chain(&controllers[i]); -+ kfree(controllers); -+ return NULL; -+} -+ -+static int led_nu801_probe(struct platform_device *pdev) -+{ -+ struct led_nu801_platform_data *pdata = pdev->dev.platform_data; -+ struct led_nu801_data *controllers; -+ int i, ret = 0; -+ -+ if (!(pdata && pdata->num_controllers)) { -+ controllers = leds_nu801_create_of(pdev); -+ if (!controllers) -+ return -ENODEV; -+ } -+ -+ controllers = kzalloc(sizeof(struct led_nu801_data) * -+ pdata->num_controllers, GFP_KERNEL); -+ if (!controllers) -+ return -ENOMEM; -+ -+ for (i = 0; i < pdata->num_controllers; i++) { -+ ret = led_nu801_create_chain(&pdata->template[i], -+ &controllers[i], -+ &pdev->dev); -+ if (ret < 0) -+ goto err; -+ } -+ -+ platform_set_drvdata(pdev, controllers); -+ -+ return 0; -+ -+err: -+ for (i = i - 1; i >= 0; i--) -+ led_nu801_delete_chain(&controllers[i]); -+ -+ kfree(controllers); -+ -+ return ret; -+} -+ -+static int led_nu801_remove(struct platform_device *pdev) -+{ -+ int i; -+ struct led_nu801_platform_data *pdata = pdev->dev.platform_data; -+ struct led_nu801_data *controllers; -+ -+ controllers = platform_get_drvdata(pdev); -+ -+ for (i = 0; i < pdata->num_controllers; i++) -+ led_nu801_delete_chain(&controllers[i]); -+ -+ kfree(controllers); -+ -+ return 0; -+} -+ -+static const struct of_device_id of_numen_leds_match[] = { -+ { .compatible = "numen,leds-nu801", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, of_pwm_leds_match); -+ -+static struct platform_driver led_nu801_driver = { -+ .probe = led_nu801_probe, -+ .remove = led_nu801_remove, -+ .driver = { -+ .name = "leds-nu801", -+ .owner = THIS_MODULE, -+ .of_match_table = of_numen_leds_match, -+ }, -+}; -+ -+static int __init led_nu801_init(void) -+{ -+ return platform_driver_register(&led_nu801_driver); -+} -+ -+static void __exit led_nu801_exit(void) -+{ -+ platform_driver_unregister(&led_nu801_driver); -+} -+ -+module_init(led_nu801_init); -+module_exit(led_nu801_exit); -+ -+MODULE_AUTHOR("Kevin Paul Herbert "); -+MODULE_DESCRIPTION("NU801 LED driver"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:leds-nu801"); -diff --git a/target/linux/ar71xx/files/drivers/leds/leds-rb750.c b/target/linux/ar71xx/files/drivers/leds/leds-rb750.c -new file mode 100644 -index 0000000000..79e98b4882 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/leds/leds-rb750.c -@@ -0,0 +1,144 @@ -+/* -+ * LED driver for the RouterBOARD 750 -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define DRV_NAME "leds-rb750" -+ -+struct rb750_led_dev { -+ struct led_classdev cdev; -+ u32 mask; -+ int active_low; -+ void (*latch_change)(u32 clear, u32 set); -+}; -+ -+struct rb750_led_drvdata { -+ struct rb750_led_dev *led_devs; -+ int num_leds; -+}; -+ -+static inline struct rb750_led_dev *to_rbled(struct led_classdev *led_cdev) -+{ -+ return (struct rb750_led_dev *)container_of(led_cdev, -+ struct rb750_led_dev, cdev); -+} -+ -+static void rb750_led_brightness_set(struct led_classdev *led_cdev, -+ enum led_brightness value) -+{ -+ struct rb750_led_dev *rbled = to_rbled(led_cdev); -+ int level; -+ -+ level = (value == LED_OFF) ? 0 : 1; -+ level ^= rbled->active_low; -+ -+ if (level) -+ rbled->latch_change(0, rbled->mask); -+ else -+ rbled->latch_change(rbled->mask, 0); -+} -+ -+static int rb750_led_probe(struct platform_device *pdev) -+{ -+ struct rb750_led_platform_data *pdata; -+ struct rb750_led_drvdata *drvdata; -+ int ret = 0; -+ int i; -+ -+ pdata = pdev->dev.platform_data; -+ if (!pdata) -+ return -EINVAL; -+ -+ drvdata = kzalloc(sizeof(struct rb750_led_drvdata) + -+ sizeof(struct rb750_led_dev) * pdata->num_leds, -+ GFP_KERNEL); -+ if (!drvdata) -+ return -ENOMEM; -+ -+ drvdata->num_leds = pdata->num_leds; -+ drvdata->led_devs = (struct rb750_led_dev *) &drvdata[1]; -+ -+ for (i = 0; i < drvdata->num_leds; i++) { -+ struct rb750_led_dev *rbled = &drvdata->led_devs[i]; -+ struct rb750_led_data *led_data = &pdata->leds[i]; -+ -+ rbled->cdev.name = led_data->name; -+ rbled->cdev.default_trigger = led_data->default_trigger; -+ rbled->cdev.brightness_set = rb750_led_brightness_set; -+ rbled->cdev.brightness = LED_OFF; -+ -+ rbled->mask = led_data->mask; -+ rbled->active_low = !!led_data->active_low; -+ rbled->latch_change = pdata->latch_change; -+ -+ ret = led_classdev_register(&pdev->dev, &rbled->cdev); -+ if (ret) -+ goto err; -+ } -+ -+ platform_set_drvdata(pdev, drvdata); -+ return 0; -+ -+err: -+ for (i = i - 1; i >= 0; i--) -+ led_classdev_unregister(&drvdata->led_devs[i].cdev); -+ -+ kfree(drvdata); -+ return ret; -+} -+ -+static int rb750_led_remove(struct platform_device *pdev) -+{ -+ struct rb750_led_drvdata *drvdata; -+ int i; -+ -+ drvdata = platform_get_drvdata(pdev); -+ for (i = 0; i < drvdata->num_leds; i++) -+ led_classdev_unregister(&drvdata->led_devs[i].cdev); -+ -+ kfree(drvdata); -+ return 0; -+} -+ -+static struct platform_driver rb750_led_driver = { -+ .probe = rb750_led_probe, -+ .remove = rb750_led_remove, -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+MODULE_ALIAS("platform:leds-rb750"); -+ -+static int __init rb750_led_init(void) -+{ -+ return platform_driver_register(&rb750_led_driver); -+} -+ -+static void __exit rb750_led_exit(void) -+{ -+ platform_driver_unregister(&rb750_led_driver); -+} -+ -+module_init(rb750_led_init); -+module_exit(rb750_led_exit); -+ -+MODULE_DESCRIPTION(DRV_NAME); -+MODULE_DESCRIPTION("LED driver for the RouterBOARD 750"); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -diff --git a/target/linux/ar71xx/files/drivers/leds/leds-wndr3700-usb.c b/target/linux/ar71xx/files/drivers/leds/leds-wndr3700-usb.c -new file mode 100644 -index 0000000000..6425b055da ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/leds/leds-wndr3700-usb.c -@@ -0,0 +1,76 @@ -+/* -+ * USB LED driver for the NETGEAR WNDR3700 -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define DRIVER_NAME "wndr3700-led-usb" -+ -+static void wndr3700_usb_led_set(struct led_classdev *cdev, -+ enum led_brightness brightness) -+{ -+ if (brightness) -+ ath79_device_reset_clear(AR71XX_RESET_GE1_PHY); -+ else -+ ath79_device_reset_set(AR71XX_RESET_GE1_PHY); -+} -+ -+static enum led_brightness wndr3700_usb_led_get(struct led_classdev *cdev) -+{ -+ return ath79_device_reset_get(AR71XX_RESET_GE1_PHY) ? LED_OFF : LED_FULL; -+} -+ -+static struct led_classdev wndr3700_usb_led = { -+ .name = "netgear:green:usb", -+ .brightness_set = wndr3700_usb_led_set, -+ .brightness_get = wndr3700_usb_led_get, -+}; -+ -+static int wndr3700_usb_led_probe(struct platform_device *pdev) -+{ -+ return led_classdev_register(&pdev->dev, &wndr3700_usb_led); -+} -+ -+static int wndr3700_usb_led_remove(struct platform_device *pdev) -+{ -+ led_classdev_unregister(&wndr3700_usb_led); -+ return 0; -+} -+ -+static struct platform_driver wndr3700_usb_led_driver = { -+ .probe = wndr3700_usb_led_probe, -+ .remove = wndr3700_usb_led_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init wndr3700_usb_led_init(void) -+{ -+ return platform_driver_register(&wndr3700_usb_led_driver); -+} -+ -+static void __exit wndr3700_usb_led_exit(void) -+{ -+ platform_driver_unregister(&wndr3700_usb_led_driver); -+} -+ -+module_init(wndr3700_usb_led_init); -+module_exit(wndr3700_usb_led_exit); -+ -+MODULE_DESCRIPTION("USB LED driver for the NETGEAR WNDR3700"); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" DRIVER_NAME); -diff --git a/target/linux/ar71xx/files/drivers/mtd/cybertan_part.c b/target/linux/ar71xx/files/drivers/mtd/cybertan_part.c -new file mode 100644 -index 0000000000..4d33c19b7e ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/mtd/cybertan_part.c -@@ -0,0 +1,206 @@ -+/* -+ * Copyright (C) 2009 Christian Daniel -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * 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 -+ * -+ * TRX flash partition table. -+ * Based on ar7 map by Felix Fietkau -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+struct cybertan_header { -+ char magic[4]; -+ u8 res1[4]; -+ char fw_date[3]; -+ char fw_ver[3]; -+ char id[4]; -+ char hw_ver; -+ char unused; -+ u8 flags[2]; -+ u8 res2[10]; -+}; -+ -+#define TRX_PARTS 6 -+#define TRX_MAGIC 0x30524448 -+#define TRX_MAX_OFFSET 3 -+ -+struct trx_header { -+ uint32_t magic; /* "HDR0" */ -+ uint32_t len; /* Length of file including header */ -+ uint32_t crc32; /* 32-bit CRC from flag_version to end of file */ -+ uint32_t flag_version; /* 0:15 flags, 16:31 version */ -+ uint32_t offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ -+}; -+ -+#define IH_MAGIC 0x27051956 /* Image Magic Number */ -+#define IH_NMLEN 32 /* Image Name Length */ -+ -+struct uimage_header { -+ uint32_t ih_magic; /* Image Header Magic Number */ -+ uint32_t ih_hcrc; /* Image Header CRC Checksum */ -+ uint32_t ih_time; /* Image Creation Timestamp */ -+ uint32_t ih_size; /* Image Data Size */ -+ uint32_t ih_load; /* Data» Load Address */ -+ uint32_t ih_ep; /* Entry Point Address */ -+ uint32_t ih_dcrc; /* Image Data CRC Checksum */ -+ uint8_t ih_os; /* Operating System */ -+ uint8_t ih_arch; /* CPU architecture */ -+ uint8_t ih_type; /* Image Type */ -+ uint8_t ih_comp; /* Compression Type */ -+ uint8_t ih_name[IH_NMLEN]; /* Image Name */ -+}; -+ -+struct firmware_header { -+ struct cybertan_header cybertan; -+ struct trx_header trx; -+ struct uimage_header uimage; -+} __packed; -+ -+#define UBOOT_LEN 0x40000 -+#define ART_LEN 0x10000 -+#define NVRAM_LEN 0x10000 -+ -+static int cybertan_parse_partitions(struct mtd_info *master, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) -+ struct mtd_partition **pparts, -+#else -+ const struct mtd_partition **pparts, -+#endif -+ struct mtd_part_parser_data *data) -+{ -+ struct firmware_header *header; -+ struct trx_header *theader; -+ struct uimage_header *uheader; -+ struct mtd_partition *trx_parts; -+ size_t retlen; -+ unsigned int kernel_len; -+ unsigned int uboot_len; -+ unsigned int nvram_len; -+ unsigned int art_len; -+ int ret; -+ -+ uboot_len = max_t(unsigned int, master->erasesize, UBOOT_LEN); -+ nvram_len = max_t(unsigned int, master->erasesize, NVRAM_LEN); -+ art_len = max_t(unsigned int, master->erasesize, ART_LEN); -+ -+ trx_parts = kzalloc(TRX_PARTS * sizeof(struct mtd_partition), -+ GFP_KERNEL); -+ if (!trx_parts) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ header = vmalloc(sizeof(*header)); -+ if (!header) { -+ return -ENOMEM; -+ goto free_parts; -+ } -+ -+ ret = mtd_read(master, uboot_len, sizeof(*header), -+ &retlen, (void *) header); -+ if (ret) -+ goto free_hdr; -+ -+ if (retlen != sizeof(*header)) { -+ ret = -EIO; -+ goto free_hdr; -+ } -+ -+ theader = &header->trx; -+ if (le32_to_cpu(theader->magic) != TRX_MAGIC) { -+ printk(KERN_NOTICE "%s: no TRX header found\n", master->name); -+ goto free_hdr; -+ } -+ -+ uheader = &header->uimage; -+ if (uheader->ih_magic != IH_MAGIC) { -+ printk(KERN_NOTICE "%s: no uImage found\n", master->name); -+ goto free_hdr; -+ } -+ -+ kernel_len = le32_to_cpu(theader->offsets[1]) + -+ sizeof(struct cybertan_header); -+ -+ trx_parts[0].name = "u-boot"; -+ trx_parts[0].offset = 0; -+ trx_parts[0].size = uboot_len; -+ trx_parts[0].mask_flags = MTD_WRITEABLE; -+ -+ trx_parts[1].name = "kernel"; -+ trx_parts[1].offset = trx_parts[0].offset + trx_parts[0].size; -+ trx_parts[1].size = kernel_len; -+ trx_parts[1].mask_flags = 0; -+ -+ trx_parts[2].name = "rootfs"; -+ trx_parts[2].offset = trx_parts[1].offset + trx_parts[1].size; -+ trx_parts[2].size = master->size - uboot_len - nvram_len - art_len - -+ trx_parts[1].size; -+ trx_parts[2].mask_flags = 0; -+ -+ trx_parts[3].name = "nvram"; -+ trx_parts[3].offset = master->size - nvram_len - art_len; -+ trx_parts[3].size = nvram_len; -+ trx_parts[3].mask_flags = MTD_WRITEABLE; -+ -+ trx_parts[4].name = "art"; -+ trx_parts[4].offset = master->size - art_len; -+ trx_parts[4].size = art_len; -+ trx_parts[4].mask_flags = MTD_WRITEABLE; -+ -+ trx_parts[5].name = "firmware"; -+ trx_parts[5].offset = uboot_len; -+ trx_parts[5].size = master->size - uboot_len - nvram_len - art_len; -+ trx_parts[5].mask_flags = 0; -+ -+ vfree(header); -+ -+ *pparts = trx_parts; -+ return TRX_PARTS; -+ -+free_hdr: -+ vfree(header); -+free_parts: -+ kfree(trx_parts); -+out: -+ return ret; -+} -+ -+static struct mtd_part_parser cybertan_parser = { -+ .owner = THIS_MODULE, -+ .parse_fn = cybertan_parse_partitions, -+ .name = "cybertan", -+}; -+ -+static int __init cybertan_parser_init(void) -+{ -+ register_mtd_parser(&cybertan_parser); -+ -+ return 0; -+} -+ -+module_init(cybertan_parser_init); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Christian Daniel "); -diff --git a/target/linux/ar71xx/files/drivers/mtd/nand/ar934x_nfc.c b/target/linux/ar71xx/files/drivers/mtd/nand/ar934x_nfc.c -new file mode 100644 -index 0000000000..2e25c6b885 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/mtd/nand/ar934x_nfc.c -@@ -0,0 +1,1591 @@ -+/* -+ * Driver for the built-in NAND controller of the Atheros AR934x SoCs -+ * -+ * Copyright (C) 2011-2013 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) -+#include -+#else -+#include -+#endif -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define AR934X_NFC_REG_CMD 0x00 -+#define AR934X_NFC_REG_CTRL 0x04 -+#define AR934X_NFC_REG_STATUS 0x08 -+#define AR934X_NFC_REG_INT_MASK 0x0c -+#define AR934X_NFC_REG_INT_STATUS 0x10 -+#define AR934X_NFC_REG_ECC_CTRL 0x14 -+#define AR934X_NFC_REG_ECC_OFFSET 0x18 -+#define AR934X_NFC_REG_ADDR0_0 0x1c -+#define AR934X_NFC_REG_ADDR0_1 0x24 -+#define AR934X_NFC_REG_ADDR1_0 0x20 -+#define AR934X_NFC_REG_ADDR1_1 0x28 -+#define AR934X_NFC_REG_SPARE_SIZE 0x30 -+#define AR934X_NFC_REG_PROTECT 0x38 -+#define AR934X_NFC_REG_LOOKUP_EN 0x40 -+#define AR934X_NFC_REG_LOOKUP(_x) (0x44 + (_i) * 4) -+#define AR934X_NFC_REG_DMA_ADDR 0x64 -+#define AR934X_NFC_REG_DMA_COUNT 0x68 -+#define AR934X_NFC_REG_DMA_CTRL 0x6c -+#define AR934X_NFC_REG_MEM_CTRL 0x80 -+#define AR934X_NFC_REG_DATA_SIZE 0x84 -+#define AR934X_NFC_REG_READ_STATUS 0x88 -+#define AR934X_NFC_REG_TIME_SEQ 0x8c -+#define AR934X_NFC_REG_TIMINGS_ASYN 0x90 -+#define AR934X_NFC_REG_TIMINGS_SYN 0x94 -+#define AR934X_NFC_REG_FIFO_DATA 0x98 -+#define AR934X_NFC_REG_TIME_MODE 0x9c -+#define AR934X_NFC_REG_DMA_ADDR_OFFS 0xa0 -+#define AR934X_NFC_REG_FIFO_INIT 0xb0 -+#define AR934X_NFC_REG_GEN_SEQ_CTRL 0xb4 -+ -+#define AR934X_NFC_CMD_CMD_SEQ_S 0 -+#define AR934X_NFC_CMD_CMD_SEQ_M 0x3f -+#define AR934X_NFC_CMD_SEQ_1C 0x00 -+#define AR934X_NFC_CMD_SEQ_ERASE 0x0e -+#define AR934X_NFC_CMD_SEQ_12 0x0c -+#define AR934X_NFC_CMD_SEQ_1C1AXR 0x21 -+#define AR934X_NFC_CMD_SEQ_S 0x24 -+#define AR934X_NFC_CMD_SEQ_1C3AXR 0x27 -+#define AR934X_NFC_CMD_SEQ_1C5A1CXR 0x2a -+#define AR934X_NFC_CMD_SEQ_18 0x32 -+#define AR934X_NFC_CMD_INPUT_SEL_SIU 0 -+#define AR934X_NFC_CMD_INPUT_SEL_DMA BIT(6) -+#define AR934X_NFC_CMD_ADDR_SEL_0 0 -+#define AR934X_NFC_CMD_ADDR_SEL_1 BIT(7) -+#define AR934X_NFC_CMD_CMD0_S 8 -+#define AR934X_NFC_CMD_CMD0_M 0xff -+#define AR934X_NFC_CMD_CMD1_S 16 -+#define AR934X_NFC_CMD_CMD1_M 0xff -+#define AR934X_NFC_CMD_CMD2_S 24 -+#define AR934X_NFC_CMD_CMD2_M 0xff -+ -+#define AR934X_NFC_CTRL_ADDR_CYCLE0_M 0x7 -+#define AR934X_NFC_CTRL_ADDR_CYCLE0_S 0 -+#define AR934X_NFC_CTRL_SPARE_EN BIT(3) -+#define AR934X_NFC_CTRL_INT_EN BIT(4) -+#define AR934X_NFC_CTRL_ECC_EN BIT(5) -+#define AR934X_NFC_CTRL_BLOCK_SIZE_S 6 -+#define AR934X_NFC_CTRL_BLOCK_SIZE_M 0x3 -+#define AR934X_NFC_CTRL_BLOCK_SIZE_32 0 -+#define AR934X_NFC_CTRL_BLOCK_SIZE_64 1 -+#define AR934X_NFC_CTRL_BLOCK_SIZE_128 2 -+#define AR934X_NFC_CTRL_BLOCK_SIZE_256 3 -+#define AR934X_NFC_CTRL_PAGE_SIZE_S 8 -+#define AR934X_NFC_CTRL_PAGE_SIZE_M 0x7 -+#define AR934X_NFC_CTRL_PAGE_SIZE_256 0 -+#define AR934X_NFC_CTRL_PAGE_SIZE_512 1 -+#define AR934X_NFC_CTRL_PAGE_SIZE_1024 2 -+#define AR934X_NFC_CTRL_PAGE_SIZE_2048 3 -+#define AR934X_NFC_CTRL_PAGE_SIZE_4096 4 -+#define AR934X_NFC_CTRL_PAGE_SIZE_8192 5 -+#define AR934X_NFC_CTRL_PAGE_SIZE_16384 6 -+#define AR934X_NFC_CTRL_CUSTOM_SIZE_EN BIT(11) -+#define AR934X_NFC_CTRL_IO_WIDTH_8BITS 0 -+#define AR934X_NFC_CTRL_IO_WIDTH_16BITS BIT(12) -+#define AR934X_NFC_CTRL_LOOKUP_EN BIT(13) -+#define AR934X_NFC_CTRL_PROT_EN BIT(14) -+#define AR934X_NFC_CTRL_WORK_MODE_ASYNC 0 -+#define AR934X_NFC_CTRL_WORK_MODE_SYNC BIT(15) -+#define AR934X_NFC_CTRL_ADDR0_AUTO_INC BIT(16) -+#define AR934X_NFC_CTRL_ADDR1_AUTO_INC BIT(17) -+#define AR934X_NFC_CTRL_ADDR_CYCLE1_M 0x7 -+#define AR934X_NFC_CTRL_ADDR_CYCLE1_S 18 -+#define AR934X_NFC_CTRL_SMALL_PAGE BIT(21) -+ -+#define AR934X_NFC_DMA_CTRL_DMA_START BIT(7) -+#define AR934X_NFC_DMA_CTRL_DMA_DIR_WRITE 0 -+#define AR934X_NFC_DMA_CTRL_DMA_DIR_READ BIT(6) -+#define AR934X_NFC_DMA_CTRL_DMA_MODE_SG BIT(5) -+#define AR934X_NFC_DMA_CTRL_DMA_BURST_S 2 -+#define AR934X_NFC_DMA_CTRL_DMA_BURST_0 0 -+#define AR934X_NFC_DMA_CTRL_DMA_BURST_1 1 -+#define AR934X_NFC_DMA_CTRL_DMA_BURST_2 2 -+#define AR934X_NFC_DMA_CTRL_DMA_BURST_3 3 -+#define AR934X_NFC_DMA_CTRL_DMA_BURST_4 4 -+#define AR934X_NFC_DMA_CTRL_DMA_BURST_5 5 -+#define AR934X_NFC_DMA_CTRL_ERR_FLAG BIT(1) -+#define AR934X_NFC_DMA_CTRL_DMA_READY BIT(0) -+ -+#define AR934X_NFC_INT_DEV_RDY(_x) BIT(4 + (_x)) -+#define AR934X_NFC_INT_CMD_END BIT(1) -+ -+#define AR934X_NFC_ECC_CTRL_ERR_THRES_S 8 -+#define AR934X_NFC_ECC_CTRL_ERR_THRES_M 0x1f -+#define AR934X_NFC_ECC_CTRL_ECC_CAP_S 5 -+#define AR934X_NFC_ECC_CTRL_ECC_CAP_M 0x7 -+#define AR934X_NFC_ECC_CTRL_ECC_CAP_2 0 -+#define AR934X_NFC_ECC_CTRL_ECC_CAP_4 1 -+#define AR934X_NFC_ECC_CTRL_ECC_CAP_6 2 -+#define AR934X_NFC_ECC_CTRL_ECC_CAP_8 3 -+#define AR934X_NFC_ECC_CTRL_ECC_CAP_10 4 -+#define AR934X_NFC_ECC_CTRL_ECC_CAP_12 5 -+#define AR934X_NFC_ECC_CTRL_ECC_CAP_14 6 -+#define AR934X_NFC_ECC_CTRL_ECC_CAP_16 7 -+#define AR934X_NFC_ECC_CTRL_ERR_OVER BIT(2) -+#define AR934X_NFC_ECC_CTRL_ERR_UNCORRECT BIT(1) -+#define AR934X_NFC_ECC_CTRL_ERR_CORRECT BIT(0) -+ -+#define AR934X_NFC_ECC_OFFS_OFSET_M 0xffff -+ -+/* default timing values */ -+#define AR934X_NFC_TIME_SEQ_DEFAULT 0x7fff -+#define AR934X_NFC_TIMINGS_ASYN_DEFAULT 0x22 -+#define AR934X_NFC_TIMINGS_SYN_DEFAULT 0xf -+ -+#define AR934X_NFC_ID_BUF_SIZE 8 -+#define AR934X_NFC_DEV_READY_TIMEOUT 25 /* msecs */ -+#define AR934X_NFC_DMA_READY_TIMEOUT 25 /* msecs */ -+#define AR934X_NFC_DONE_TIMEOUT 1000 -+#define AR934X_NFC_DMA_RETRIES 20 -+ -+#define AR934X_NFC_USE_IRQ true -+#define AR934X_NFC_IRQ_MASK AR934X_NFC_INT_DEV_RDY(0) -+ -+#define AR934X_NFC_GENSEQ_SMALL_PAGE_READ 0x30043 -+ -+#undef AR934X_NFC_DEBUG_DATA -+#undef AR934X_NFC_DEBUG -+ -+struct ar934x_nfc; -+ -+static inline __attribute__ ((format (printf, 2, 3))) -+void _nfc_dbg(struct ar934x_nfc *nfc, const char *fmt, ...) -+{ -+} -+ -+#ifdef AR934X_NFC_DEBUG -+#define nfc_dbg(_nfc, fmt, ...) \ -+ dev_info((_nfc)->parent, fmt, ##__VA_ARGS__) -+#else -+#define nfc_dbg(_nfc, fmt, ...) \ -+ _nfc_dbg((_nfc), fmt, ##__VA_ARGS__) -+#endif /* AR934X_NFC_DEBUG */ -+ -+#ifdef AR934X_NFC_DEBUG_DATA -+static void -+nfc_debug_data(const char *label, void *data, int len) -+{ -+ print_hex_dump(KERN_WARNING, label, DUMP_PREFIX_OFFSET, 16, 1, -+ data, len, 0); -+} -+#else -+static inline void -+nfc_debug_data(const char *label, void *data, int len) {} -+#endif /* AR934X_NFC_DEBUG_DATA */ -+ -+struct ar934x_nfc { -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ struct mtd_info mtd; -+#endif -+ struct nand_chip nand_chip; -+ struct device *parent; -+ void __iomem *base; -+ void (*select_chip)(int chip_no); -+ bool swap_dma; -+ int irq; -+ wait_queue_head_t irq_waitq; -+ -+ bool spurious_irq_expected; -+ u32 irq_status; -+ -+ u32 ctrl_reg; -+ u32 ecc_ctrl_reg; -+ u32 ecc_offset_reg; -+ u32 ecc_thres; -+ u32 ecc_oob_pos; -+ -+ bool small_page; -+ unsigned int addr_count0; -+ unsigned int addr_count1; -+ -+ u8 *buf; -+ dma_addr_t buf_dma; -+ unsigned int buf_size; -+ int buf_index; -+ -+ bool read_id; -+ -+ int erase1_page_addr; -+ -+ int rndout_page_addr; -+ int rndout_read_cmd; -+ -+ int seqin_page_addr; -+ int seqin_column; -+ int seqin_read_cmd; -+}; -+ -+static void ar934x_nfc_restart(struct ar934x_nfc *nfc); -+ -+static inline bool -+is_all_ff(u8 *buf, int len) -+{ -+ while (len--) -+ if (buf[len] != 0xff) -+ return false; -+ -+ return true; -+} -+ -+static inline void -+ar934x_nfc_wr(struct ar934x_nfc *nfc, unsigned reg, u32 val) -+{ -+ __raw_writel(val, nfc->base + reg); -+} -+ -+static inline u32 -+ar934x_nfc_rr(struct ar934x_nfc *nfc, unsigned reg) -+{ -+ return __raw_readl(nfc->base + reg); -+} -+ -+static inline struct ar934x_nfc_platform_data * -+ar934x_nfc_get_platform_data(struct ar934x_nfc *nfc) -+{ -+ return nfc->parent->platform_data; -+} -+ -+static inline struct -+ar934x_nfc *mtd_to_ar934x_nfc(struct mtd_info *mtd) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ return container_of(mtd, struct ar934x_nfc, mtd); -+#else -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ -+ return container_of(chip, struct ar934x_nfc, nand_chip); -+#endif -+} -+ -+static struct mtd_info *ar934x_nfc_to_mtd(struct ar934x_nfc *nfc) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ return &nfc->mtd; -+#else -+ return nand_to_mtd(&nfc->nand_chip); -+#endif -+} -+ -+static inline bool ar934x_nfc_use_irq(struct ar934x_nfc *nfc) -+{ -+ return AR934X_NFC_USE_IRQ; -+} -+ -+static inline void ar934x_nfc_write_cmd_reg(struct ar934x_nfc *nfc, u32 cmd_reg) -+{ -+ wmb(); -+ -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_CMD, cmd_reg); -+ /* flush write */ -+ ar934x_nfc_rr(nfc, AR934X_NFC_REG_CMD); -+} -+ -+static bool -+__ar934x_nfc_dev_ready(struct ar934x_nfc *nfc) -+{ -+ u32 status; -+ -+ status = ar934x_nfc_rr(nfc, AR934X_NFC_REG_STATUS); -+ return (status & 0xff) == 0xff; -+} -+ -+static inline bool -+__ar934x_nfc_is_dma_ready(struct ar934x_nfc *nfc) -+{ -+ u32 status; -+ -+ status = ar934x_nfc_rr(nfc, AR934X_NFC_REG_DMA_CTRL); -+ return (status & AR934X_NFC_DMA_CTRL_DMA_READY) != 0; -+} -+ -+static int -+ar934x_nfc_wait_dev_ready(struct ar934x_nfc *nfc) -+{ -+ unsigned long timeout; -+ -+ timeout = jiffies + msecs_to_jiffies(AR934X_NFC_DEV_READY_TIMEOUT); -+ do { -+ if (__ar934x_nfc_dev_ready(nfc)) -+ return 0; -+ } while time_before(jiffies, timeout); -+ -+ nfc_dbg(nfc, "timeout waiting for device ready, status:%08x int:%08x\n", -+ ar934x_nfc_rr(nfc, AR934X_NFC_REG_STATUS), -+ ar934x_nfc_rr(nfc, AR934X_NFC_REG_INT_STATUS)); -+ return -ETIMEDOUT; -+} -+ -+static int -+ar934x_nfc_wait_dma_ready(struct ar934x_nfc *nfc) -+{ -+ unsigned long timeout; -+ -+ timeout = jiffies + msecs_to_jiffies(AR934X_NFC_DMA_READY_TIMEOUT); -+ do { -+ if (__ar934x_nfc_is_dma_ready(nfc)) -+ return 0; -+ } while time_before(jiffies, timeout); -+ -+ nfc_dbg(nfc, "timeout waiting for DMA ready, dma_ctrl:%08x\n", -+ ar934x_nfc_rr(nfc, AR934X_NFC_REG_DMA_CTRL)); -+ return -ETIMEDOUT; -+} -+ -+static int -+ar934x_nfc_wait_irq(struct ar934x_nfc *nfc) -+{ -+ long timeout; -+ int ret; -+ -+ timeout = wait_event_timeout(nfc->irq_waitq, -+ (nfc->irq_status & AR934X_NFC_IRQ_MASK) != 0, -+ msecs_to_jiffies(AR934X_NFC_DEV_READY_TIMEOUT)); -+ -+ ret = 0; -+ if (!timeout) { -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_INT_MASK, 0); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_INT_STATUS, 0); -+ /* flush write */ -+ ar934x_nfc_rr(nfc, AR934X_NFC_REG_INT_STATUS); -+ -+ nfc_dbg(nfc, -+ "timeout waiting for interrupt, status:%08x\n", -+ nfc->irq_status); -+ ret = -ETIMEDOUT; -+ } -+ -+ nfc->irq_status = 0; -+ return ret; -+} -+ -+static int -+ar934x_nfc_wait_done(struct ar934x_nfc *nfc) -+{ -+ int ret; -+ -+ if (ar934x_nfc_use_irq(nfc)) -+ ret = ar934x_nfc_wait_irq(nfc); -+ else -+ ret = ar934x_nfc_wait_dev_ready(nfc); -+ -+ if (ret) -+ return ret; -+ -+ return ar934x_nfc_wait_dma_ready(nfc); -+} -+ -+static int -+ar934x_nfc_alloc_buf(struct ar934x_nfc *nfc, unsigned size) -+{ -+ nfc->buf = dma_alloc_coherent(nfc->parent, size, -+ &nfc->buf_dma, GFP_KERNEL); -+ if (nfc->buf == NULL) { -+ dev_err(nfc->parent, "no memory for DMA buffer\n"); -+ return -ENOMEM; -+ } -+ -+ nfc->buf_size = size; -+ nfc_dbg(nfc, "buf:%p size:%u\n", nfc->buf, nfc->buf_size); -+ -+ return 0; -+} -+ -+static void -+ar934x_nfc_free_buf(struct ar934x_nfc *nfc) -+{ -+ dma_free_coherent(nfc->parent, nfc->buf_size, nfc->buf, nfc->buf_dma); -+} -+ -+static void -+ar934x_nfc_get_addr(struct ar934x_nfc *nfc, int column, int page_addr, -+ u32 *addr0, u32 *addr1) -+{ -+ u32 a0, a1; -+ -+ a0 = 0; -+ a1 = 0; -+ -+ if (column == -1) { -+ /* ERASE1 */ -+ a0 = (page_addr & 0xffff) << 16; -+ a1 = (page_addr >> 16) & 0xf; -+ } else if (page_addr != -1) { -+ /* SEQIN, READ0, etc.. */ -+ -+ /* TODO: handle 16bit bus width */ -+ if (nfc->small_page) { -+ a0 = column & 0xff; -+ a0 |= (page_addr & 0xff) << 8; -+ a0 |= ((page_addr >> 8) & 0xff) << 16; -+ a0 |= ((page_addr >> 16) & 0xff) << 24; -+ } else { -+ a0 = column & 0x0FFF; -+ a0 |= (page_addr & 0xffff) << 16; -+ -+ if (nfc->addr_count0 > 4) -+ a1 = (page_addr >> 16) & 0xf; -+ } -+ } -+ -+ *addr0 = a0; -+ *addr1 = a1; -+} -+ -+static void -+ar934x_nfc_send_cmd(struct ar934x_nfc *nfc, unsigned command) -+{ -+ u32 cmd_reg; -+ -+ cmd_reg = AR934X_NFC_CMD_INPUT_SEL_SIU | AR934X_NFC_CMD_ADDR_SEL_0 | -+ AR934X_NFC_CMD_SEQ_1C; -+ cmd_reg |= (command & AR934X_NFC_CMD_CMD0_M) << AR934X_NFC_CMD_CMD0_S; -+ -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_INT_STATUS, 0); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_CTRL, nfc->ctrl_reg); -+ -+ ar934x_nfc_write_cmd_reg(nfc, cmd_reg); -+ ar934x_nfc_wait_dev_ready(nfc); -+} -+ -+static int -+ar934x_nfc_do_rw_command(struct ar934x_nfc *nfc, int column, int page_addr, -+ int len, u32 cmd_reg, u32 ctrl_reg, bool write) -+{ -+ u32 addr0, addr1; -+ u32 dma_ctrl; -+ int dir; -+ int err; -+ int retries = 0; -+ -+ WARN_ON(len & 3); -+ -+ if (WARN_ON(len > nfc->buf_size)) -+ dev_err(nfc->parent, "len=%d > buf_size=%d", len, nfc->buf_size); -+ -+ if (write) { -+ dma_ctrl = AR934X_NFC_DMA_CTRL_DMA_DIR_WRITE; -+ dir = DMA_TO_DEVICE; -+ } else { -+ dma_ctrl = AR934X_NFC_DMA_CTRL_DMA_DIR_READ; -+ dir = DMA_FROM_DEVICE; -+ } -+ -+ ar934x_nfc_get_addr(nfc, column, page_addr, &addr0, &addr1); -+ -+ dma_ctrl |= AR934X_NFC_DMA_CTRL_DMA_START | -+ (AR934X_NFC_DMA_CTRL_DMA_BURST_3 << -+ AR934X_NFC_DMA_CTRL_DMA_BURST_S); -+ -+ cmd_reg |= AR934X_NFC_CMD_INPUT_SEL_DMA | AR934X_NFC_CMD_ADDR_SEL_0; -+ ctrl_reg |= AR934X_NFC_CTRL_INT_EN; -+ -+ nfc_dbg(nfc, "%s a0:%08x a1:%08x len:%x cmd:%08x dma:%08x ctrl:%08x\n", -+ (write) ? "write" : "read", -+ addr0, addr1, len, cmd_reg, dma_ctrl, ctrl_reg); -+ -+retry: -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_INT_STATUS, 0); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_ADDR0_0, addr0); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_ADDR0_1, addr1); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_DMA_ADDR, nfc->buf_dma); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_DMA_COUNT, len); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_DATA_SIZE, len); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_CTRL, ctrl_reg); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_DMA_CTRL, dma_ctrl); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_ECC_CTRL, nfc->ecc_ctrl_reg); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_ECC_OFFSET, nfc->ecc_offset_reg); -+ -+ if (ar934x_nfc_use_irq(nfc)) { -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_INT_MASK, AR934X_NFC_IRQ_MASK); -+ /* flush write */ -+ ar934x_nfc_rr(nfc, AR934X_NFC_REG_INT_MASK); -+ } -+ -+ ar934x_nfc_write_cmd_reg(nfc, cmd_reg); -+ err = ar934x_nfc_wait_done(nfc); -+ if (err) { -+ dev_dbg(nfc->parent, "%s operation stuck at page %d\n", -+ (write) ? "write" : "read", page_addr); -+ -+ ar934x_nfc_restart(nfc); -+ if (retries++ < AR934X_NFC_DMA_RETRIES) -+ goto retry; -+ -+ dev_err(nfc->parent, "%s operation failed on page %d\n", -+ (write) ? "write" : "read", page_addr); -+ } -+ -+ return err; -+} -+ -+static int -+ar934x_nfc_send_readid(struct ar934x_nfc *nfc, unsigned command) -+{ -+ u32 cmd_reg; -+ int err; -+ -+ nfc_dbg(nfc, "readid, cmd:%02x\n", command); -+ -+ cmd_reg = AR934X_NFC_CMD_SEQ_1C1AXR; -+ cmd_reg |= (command & AR934X_NFC_CMD_CMD0_M) << AR934X_NFC_CMD_CMD0_S; -+ -+ err = ar934x_nfc_do_rw_command(nfc, -1, -1, AR934X_NFC_ID_BUF_SIZE, -+ cmd_reg, nfc->ctrl_reg, false); -+ -+ nfc_debug_data("[id] ", nfc->buf, AR934X_NFC_ID_BUF_SIZE); -+ -+ return err; -+} -+ -+static int -+ar934x_nfc_send_read(struct ar934x_nfc *nfc, unsigned command, int column, -+ int page_addr, int len) -+{ -+ u32 cmd_reg; -+ int err; -+ -+ nfc_dbg(nfc, "read, column=%d page=%d len=%d\n", -+ column, page_addr, len); -+ -+ cmd_reg = (command & AR934X_NFC_CMD_CMD0_M) << AR934X_NFC_CMD_CMD0_S; -+ -+ if (nfc->small_page) { -+ cmd_reg |= AR934X_NFC_CMD_SEQ_18; -+ } else { -+ cmd_reg |= NAND_CMD_READSTART << AR934X_NFC_CMD_CMD1_S; -+ cmd_reg |= AR934X_NFC_CMD_SEQ_1C5A1CXR; -+ } -+ -+ err = ar934x_nfc_do_rw_command(nfc, column, page_addr, len, -+ cmd_reg, nfc->ctrl_reg, false); -+ -+ nfc_debug_data("[data] ", nfc->buf, len); -+ -+ return err; -+} -+ -+static void -+ar934x_nfc_send_erase(struct ar934x_nfc *nfc, unsigned command, int column, -+ int page_addr) -+{ -+ u32 addr0, addr1; -+ u32 ctrl_reg; -+ u32 cmd_reg; -+ -+ ar934x_nfc_get_addr(nfc, column, page_addr, &addr0, &addr1); -+ -+ ctrl_reg = nfc->ctrl_reg; -+ if (nfc->small_page) { -+ /* override number of address cycles for the erase command */ -+ ctrl_reg &= ~(AR934X_NFC_CTRL_ADDR_CYCLE0_M << -+ AR934X_NFC_CTRL_ADDR_CYCLE0_S); -+ ctrl_reg &= ~(AR934X_NFC_CTRL_ADDR_CYCLE1_M << -+ AR934X_NFC_CTRL_ADDR_CYCLE1_S); -+ ctrl_reg &= ~(AR934X_NFC_CTRL_SMALL_PAGE); -+ ctrl_reg |= (nfc->addr_count0 + 1) << -+ AR934X_NFC_CTRL_ADDR_CYCLE0_S; -+ } -+ -+ cmd_reg = NAND_CMD_ERASE1 << AR934X_NFC_CMD_CMD0_S; -+ cmd_reg |= command << AR934X_NFC_CMD_CMD1_S; -+ cmd_reg |= AR934X_NFC_CMD_SEQ_ERASE; -+ -+ nfc_dbg(nfc, "erase page %d, a0:%08x a1:%08x cmd:%08x ctrl:%08x\n", -+ page_addr, addr0, addr1, cmd_reg, ctrl_reg); -+ -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_INT_STATUS, 0); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_CTRL, ctrl_reg); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_ADDR0_0, addr0); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_ADDR0_1, addr1); -+ -+ ar934x_nfc_write_cmd_reg(nfc, cmd_reg); -+ ar934x_nfc_wait_dev_ready(nfc); -+} -+ -+static int -+ar934x_nfc_send_write(struct ar934x_nfc *nfc, unsigned command, int column, -+ int page_addr, int len) -+{ -+ u32 cmd_reg; -+ -+ nfc_dbg(nfc, "write, column=%d page=%d len=%d\n", -+ column, page_addr, len); -+ -+ nfc_debug_data("[data] ", nfc->buf, len); -+ -+ cmd_reg = NAND_CMD_SEQIN << AR934X_NFC_CMD_CMD0_S; -+ cmd_reg |= command << AR934X_NFC_CMD_CMD1_S; -+ cmd_reg |= AR934X_NFC_CMD_SEQ_12; -+ -+ return ar934x_nfc_do_rw_command(nfc, column, page_addr, len, -+ cmd_reg, nfc->ctrl_reg, true); -+} -+ -+static void -+ar934x_nfc_read_status(struct ar934x_nfc *nfc) -+{ -+ u32 cmd_reg; -+ u32 status; -+ -+ cmd_reg = NAND_CMD_STATUS << AR934X_NFC_CMD_CMD0_S; -+ cmd_reg |= AR934X_NFC_CMD_SEQ_S; -+ -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_INT_STATUS, 0); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_CTRL, nfc->ctrl_reg); -+ -+ ar934x_nfc_write_cmd_reg(nfc, cmd_reg); -+ ar934x_nfc_wait_dev_ready(nfc); -+ -+ status = ar934x_nfc_rr(nfc, AR934X_NFC_REG_READ_STATUS); -+ -+ nfc_dbg(nfc, "read status, cmd:%08x status:%02x\n", -+ cmd_reg, (status & 0xff)); -+ -+ if (nfc->swap_dma) -+ nfc->buf[0 ^ 3] = status; -+ else -+ nfc->buf[0] = status; -+} -+ -+static void -+ar934x_nfc_cmdfunc(struct mtd_info *mtd, unsigned int command, int column, -+ int page_addr) -+{ -+ struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); -+ struct nand_chip *nand = &nfc->nand_chip; -+ -+ nfc->read_id = false; -+ if (command != NAND_CMD_PAGEPROG) -+ nfc->buf_index = 0; -+ -+ switch (command) { -+ case NAND_CMD_RESET: -+ ar934x_nfc_send_cmd(nfc, command); -+ break; -+ -+ case NAND_CMD_READID: -+ nfc->read_id = true; -+ ar934x_nfc_send_readid(nfc, command); -+ break; -+ -+ case NAND_CMD_READ0: -+ case NAND_CMD_READ1: -+ if (nfc->small_page) { -+ ar934x_nfc_send_read(nfc, command, column, page_addr, -+ mtd->writesize + mtd->oobsize); -+ } else { -+ ar934x_nfc_send_read(nfc, command, 0, page_addr, -+ mtd->writesize + mtd->oobsize); -+ nfc->buf_index = column; -+ nfc->rndout_page_addr = page_addr; -+ nfc->rndout_read_cmd = command; -+ } -+ break; -+ -+ case NAND_CMD_READOOB: -+ if (nfc->small_page) -+ ar934x_nfc_send_read(nfc, NAND_CMD_READOOB, -+ column, page_addr, -+ mtd->oobsize); -+ else -+ ar934x_nfc_send_read(nfc, NAND_CMD_READ0, -+ mtd->writesize, page_addr, -+ mtd->oobsize); -+ break; -+ -+ case NAND_CMD_RNDOUT: -+ if (WARN_ON(nfc->small_page)) -+ break; -+ -+ /* emulate subpage read */ -+ ar934x_nfc_send_read(nfc, nfc->rndout_read_cmd, 0, -+ nfc->rndout_page_addr, -+ mtd->writesize + mtd->oobsize); -+ nfc->buf_index = column; -+ break; -+ -+ case NAND_CMD_ERASE1: -+ nfc->erase1_page_addr = page_addr; -+ break; -+ -+ case NAND_CMD_ERASE2: -+ ar934x_nfc_send_erase(nfc, command, -1, nfc->erase1_page_addr); -+ break; -+ -+ case NAND_CMD_STATUS: -+ ar934x_nfc_read_status(nfc); -+ break; -+ -+ case NAND_CMD_SEQIN: -+ if (nfc->small_page) { -+ /* output read command */ -+ if (column >= mtd->writesize) { -+ column -= mtd->writesize; -+ nfc->seqin_read_cmd = NAND_CMD_READOOB; -+ } else if (column < 256) { -+ nfc->seqin_read_cmd = NAND_CMD_READ0; -+ } else { -+ column -= 256; -+ nfc->seqin_read_cmd = NAND_CMD_READ1; -+ } -+ } else { -+ nfc->seqin_read_cmd = NAND_CMD_READ0; -+ } -+ nfc->seqin_column = column; -+ nfc->seqin_page_addr = page_addr; -+ break; -+ -+ case NAND_CMD_PAGEPROG: -+ if (nand->ecc.mode == NAND_ECC_HW) { -+ /* the data is already written */ -+ break; -+ } -+ -+ if (nfc->small_page) -+ ar934x_nfc_send_cmd(nfc, nfc->seqin_read_cmd); -+ -+ ar934x_nfc_send_write(nfc, command, nfc->seqin_column, -+ nfc->seqin_page_addr, -+ nfc->buf_index); -+ break; -+ -+ default: -+ dev_err(nfc->parent, -+ "unsupported command: %x, column:%d page_addr=%d\n", -+ command, column, page_addr); -+ break; -+ } -+} -+ -+static int -+ar934x_nfc_dev_ready(struct mtd_info *mtd) -+{ -+ struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); -+ -+ return __ar934x_nfc_dev_ready(nfc); -+} -+ -+static void -+ar934x_nfc_select_chip(struct mtd_info *mtd, int chip_no) -+{ -+ struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); -+ -+ if (nfc->select_chip) -+ nfc->select_chip(chip_no); -+} -+ -+static u8 -+ar934x_nfc_read_byte(struct mtd_info *mtd) -+{ -+ struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); -+ u8 data; -+ -+ WARN_ON(nfc->buf_index >= nfc->buf_size); -+ -+ if (nfc->swap_dma || nfc->read_id) -+ data = nfc->buf[nfc->buf_index ^ 3]; -+ else -+ data = nfc->buf[nfc->buf_index]; -+ -+ nfc->buf_index++; -+ -+ return data; -+} -+ -+static void -+ar934x_nfc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) -+{ -+ struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); -+ int i; -+ -+ WARN_ON(nfc->buf_index + len > nfc->buf_size); -+ -+ if (nfc->swap_dma) { -+ for (i = 0; i < len; i++) { -+ nfc->buf[nfc->buf_index ^ 3] = buf[i]; -+ nfc->buf_index++; -+ } -+ } else { -+ for (i = 0; i < len; i++) { -+ nfc->buf[nfc->buf_index] = buf[i]; -+ nfc->buf_index++; -+ } -+ } -+} -+ -+static void -+ar934x_nfc_read_buf(struct mtd_info *mtd, u8 *buf, int len) -+{ -+ struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); -+ int buf_index; -+ int i; -+ -+ WARN_ON(nfc->buf_index + len > nfc->buf_size); -+ -+ buf_index = nfc->buf_index; -+ -+ if (nfc->swap_dma || nfc->read_id) { -+ for (i = 0; i < len; i++) { -+ buf[i] = nfc->buf[buf_index ^ 3]; -+ buf_index++; -+ } -+ } else { -+ for (i = 0; i < len; i++) { -+ buf[i] = nfc->buf[buf_index]; -+ buf_index++; -+ } -+ } -+ -+ nfc->buf_index = buf_index; -+} -+ -+static inline void -+ar934x_nfc_enable_hwecc(struct ar934x_nfc *nfc) -+{ -+ nfc->ctrl_reg |= AR934X_NFC_CTRL_ECC_EN; -+ nfc->ctrl_reg &= ~AR934X_NFC_CTRL_CUSTOM_SIZE_EN; -+} -+ -+static inline void -+ar934x_nfc_disable_hwecc(struct ar934x_nfc *nfc) -+{ -+ nfc->ctrl_reg &= ~AR934X_NFC_CTRL_ECC_EN; -+ nfc->ctrl_reg |= AR934X_NFC_CTRL_CUSTOM_SIZE_EN; -+} -+ -+static int -+ar934x_nfc_read_oob(struct mtd_info *mtd, struct nand_chip *chip, -+ int page) -+{ -+ struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); -+ int err; -+ -+ nfc_dbg(nfc, "read_oob: page:%d\n", page); -+ -+ err = ar934x_nfc_send_read(nfc, NAND_CMD_READ0, mtd->writesize, page, -+ mtd->oobsize); -+ if (err) -+ return err; -+ -+ memcpy(chip->oob_poi, nfc->buf, mtd->oobsize); -+ -+ return 0; -+} -+ -+static int -+ar934x_nfc_write_oob(struct mtd_info *mtd, struct nand_chip *chip, -+ int page) -+{ -+ struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); -+ -+ nfc_dbg(nfc, "write_oob: page:%d\n", page); -+ -+ memcpy(nfc->buf, chip->oob_poi, mtd->oobsize); -+ -+ return ar934x_nfc_send_write(nfc, NAND_CMD_PAGEPROG, mtd->writesize, -+ page, mtd->oobsize); -+} -+ -+static int -+ar934x_nfc_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, -+ u8 *buf, int oob_required, int page) -+{ -+ struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); -+ int len; -+ int err; -+ -+ nfc_dbg(nfc, "read_page_raw: page:%d oob:%d\n", page, oob_required); -+ -+ len = mtd->writesize; -+ if (oob_required) -+ len += mtd->oobsize; -+ -+ err = ar934x_nfc_send_read(nfc, NAND_CMD_READ0, 0, page, len); -+ if (err) -+ return err; -+ -+ memcpy(buf, nfc->buf, mtd->writesize); -+ -+ if (oob_required) -+ memcpy(chip->oob_poi, &nfc->buf[mtd->writesize], mtd->oobsize); -+ -+ return 0; -+} -+ -+static int -+ar934x_nfc_read_page(struct mtd_info *mtd, struct nand_chip *chip, -+ u8 *buf, int oob_required, int page) -+{ -+ struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); -+ u32 ecc_ctrl; -+ int max_bitflips = 0; -+ bool ecc_failed; -+ bool ecc_corrected; -+ int err; -+ -+ nfc_dbg(nfc, "read_page: page:%d oob:%d\n", page, oob_required); -+ -+ ar934x_nfc_enable_hwecc(nfc); -+ err = ar934x_nfc_send_read(nfc, NAND_CMD_READ0, 0, page, -+ mtd->writesize); -+ ar934x_nfc_disable_hwecc(nfc); -+ -+ if (err) -+ return err; -+ -+ /* TODO: optimize to avoid memcpy */ -+ memcpy(buf, nfc->buf, mtd->writesize); -+ -+ /* read the ECC status */ -+ ecc_ctrl = ar934x_nfc_rr(nfc, AR934X_NFC_REG_ECC_CTRL); -+ ecc_failed = ecc_ctrl & AR934X_NFC_ECC_CTRL_ERR_UNCORRECT; -+ ecc_corrected = ecc_ctrl & AR934X_NFC_ECC_CTRL_ERR_CORRECT; -+ -+ if (oob_required || ecc_failed) { -+ err = ar934x_nfc_send_read(nfc, NAND_CMD_READ0, mtd->writesize, -+ page, mtd->oobsize); -+ if (err) -+ return err; -+ -+ if (oob_required) -+ memcpy(chip->oob_poi, nfc->buf, mtd->oobsize); -+ } -+ -+ if (ecc_failed) { -+ /* -+ * The hardware ECC engine reports uncorrectable errors -+ * on empty pages. Check the ECC bytes and the data. If -+ * both contains 0xff bytes only, dont report a failure. -+ * -+ * TODO: prebuild a buffer with 0xff bytes and use memcmp -+ * for better performance? -+ */ -+ if (!is_all_ff(&nfc->buf[nfc->ecc_oob_pos], chip->ecc.total) || -+ !is_all_ff(buf, mtd->writesize)) -+ mtd->ecc_stats.failed++; -+ } else if (ecc_corrected) { -+ /* -+ * The hardware does not report the exact count of the -+ * corrected bitflips, use assumptions based on the -+ * threshold. -+ */ -+ if (ecc_ctrl & AR934X_NFC_ECC_CTRL_ERR_OVER) { -+ /* -+ * The number of corrected bitflips exceeds the -+ * threshold. Assume the maximum. -+ */ -+ max_bitflips = chip->ecc.strength * chip->ecc.steps; -+ } else { -+ max_bitflips = nfc->ecc_thres * chip->ecc.steps; -+ } -+ -+ mtd->ecc_stats.corrected += max_bitflips; -+ } -+ -+ return max_bitflips; -+} -+ -+static int -+ar934x_nfc_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, -+ const u8 *buf, int oob_required, int page) -+{ -+ struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); -+ int len; -+ -+ nfc_dbg(nfc, "write_page_raw: page:%d oob:%d\n", page, oob_required); -+ -+ memcpy(nfc->buf, buf, mtd->writesize); -+ len = mtd->writesize; -+ -+ if (oob_required) { -+ memcpy(&nfc->buf[mtd->writesize], chip->oob_poi, mtd->oobsize); -+ len += mtd->oobsize; -+ } -+ -+ return ar934x_nfc_send_write(nfc, NAND_CMD_PAGEPROG, 0, page, len); -+} -+ -+static int -+ar934x_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip, -+ const u8 *buf, int oob_required, int page) -+{ -+ struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); -+ int err; -+ -+ nfc_dbg(nfc, "write_page: page:%d oob:%d\n", page, oob_required); -+ -+ /* write OOB first */ -+ if (oob_required && -+ !is_all_ff(chip->oob_poi, mtd->oobsize)) { -+ err = ar934x_nfc_write_oob(mtd, chip, page); -+ if (err) -+ return err; -+ } -+ -+ /* TODO: optimize to avoid memcopy */ -+ memcpy(nfc->buf, buf, mtd->writesize); -+ -+ ar934x_nfc_enable_hwecc(nfc); -+ err = ar934x_nfc_send_write(nfc, NAND_CMD_PAGEPROG, 0, page, -+ mtd->writesize); -+ ar934x_nfc_disable_hwecc(nfc); -+ -+ return err; -+} -+ -+static void -+ar934x_nfc_hw_init(struct ar934x_nfc *nfc) -+{ -+ struct ar934x_nfc_platform_data *pdata; -+ -+ pdata = ar934x_nfc_get_platform_data(nfc); -+ if (pdata->hw_reset) { -+ pdata->hw_reset(true); -+ pdata->hw_reset(false); -+ } -+ -+ /* -+ * setup timings -+ * TODO: make it configurable via platform data -+ */ -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_TIME_SEQ, -+ AR934X_NFC_TIME_SEQ_DEFAULT); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_TIMINGS_ASYN, -+ AR934X_NFC_TIMINGS_ASYN_DEFAULT); -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_TIMINGS_SYN, -+ AR934X_NFC_TIMINGS_SYN_DEFAULT); -+ -+ /* disable WP on all chips, and select chip 0 */ -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_MEM_CTRL, 0xff00); -+ -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_DMA_ADDR_OFFS, 0); -+ -+ /* initialize Control register */ -+ nfc->ctrl_reg = AR934X_NFC_CTRL_CUSTOM_SIZE_EN; -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_CTRL, nfc->ctrl_reg); -+ -+ if (nfc->small_page) { -+ /* Setup generic sequence register for small page reads. */ -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_GEN_SEQ_CTRL, -+ AR934X_NFC_GENSEQ_SMALL_PAGE_READ); -+ } -+} -+ -+static void -+ar934x_nfc_restart(struct ar934x_nfc *nfc) -+{ -+ u32 ctrl_reg; -+ -+ if (nfc->select_chip) -+ nfc->select_chip(-1); -+ -+ ctrl_reg = nfc->ctrl_reg; -+ ar934x_nfc_hw_init(nfc); -+ nfc->ctrl_reg = ctrl_reg; -+ -+ if (nfc->select_chip) -+ nfc->select_chip(0); -+ -+ ar934x_nfc_send_cmd(nfc, NAND_CMD_RESET); -+} -+ -+static irqreturn_t -+ar934x_nfc_irq_handler(int irq, void *data) -+{ -+ struct ar934x_nfc *nfc = data; -+ u32 status; -+ -+ status = ar934x_nfc_rr(nfc, AR934X_NFC_REG_INT_STATUS); -+ -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_INT_STATUS, 0); -+ /* flush write */ -+ ar934x_nfc_rr(nfc, AR934X_NFC_REG_INT_STATUS); -+ -+ status &= ar934x_nfc_rr(nfc, AR934X_NFC_REG_INT_MASK); -+ if (status) { -+ nfc_dbg(nfc, "got IRQ, status:%08x\n", status); -+ -+ nfc->irq_status = status; -+ nfc->spurious_irq_expected = true; -+ wake_up(&nfc->irq_waitq); -+ } else { -+ if (nfc->spurious_irq_expected) { -+ nfc->spurious_irq_expected = false; -+ } else { -+ dev_warn(nfc->parent, "spurious interrupt\n"); -+ } -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static int -+ar934x_nfc_init_tail(struct mtd_info *mtd) -+{ -+ struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); -+ struct nand_chip *chip = &nfc->nand_chip; -+ u32 ctrl; -+ u32 t; -+ int err; -+ -+ switch (mtd->oobsize) { -+ case 16: -+ case 64: -+ case 128: -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_SPARE_SIZE, mtd->oobsize); -+ break; -+ -+ default: -+ dev_err(nfc->parent, "unsupported OOB size: %d bytes\n", -+ mtd->oobsize); -+ return -ENXIO; -+ } -+ -+ ctrl = AR934X_NFC_CTRL_CUSTOM_SIZE_EN; -+ -+ switch (mtd->erasesize / mtd->writesize) { -+ case 32: -+ t = AR934X_NFC_CTRL_BLOCK_SIZE_32; -+ break; -+ -+ case 64: -+ t = AR934X_NFC_CTRL_BLOCK_SIZE_64; -+ break; -+ -+ case 128: -+ t = AR934X_NFC_CTRL_BLOCK_SIZE_128; -+ break; -+ -+ case 256: -+ t = AR934X_NFC_CTRL_BLOCK_SIZE_256; -+ break; -+ -+ default: -+ dev_err(nfc->parent, "unsupported block size: %u\n", -+ mtd->erasesize / mtd->writesize); -+ return -ENXIO; -+ } -+ -+ ctrl |= t << AR934X_NFC_CTRL_BLOCK_SIZE_S; -+ -+ switch (mtd->writesize) { -+ case 256: -+ nfc->small_page = 1; -+ t = AR934X_NFC_CTRL_PAGE_SIZE_256; -+ break; -+ -+ case 512: -+ nfc->small_page = 1; -+ t = AR934X_NFC_CTRL_PAGE_SIZE_512; -+ break; -+ -+ case 1024: -+ t = AR934X_NFC_CTRL_PAGE_SIZE_1024; -+ break; -+ -+ case 2048: -+ t = AR934X_NFC_CTRL_PAGE_SIZE_2048; -+ break; -+ -+ case 4096: -+ t = AR934X_NFC_CTRL_PAGE_SIZE_4096; -+ break; -+ -+ case 8192: -+ t = AR934X_NFC_CTRL_PAGE_SIZE_8192; -+ break; -+ -+ case 16384: -+ t = AR934X_NFC_CTRL_PAGE_SIZE_16384; -+ break; -+ -+ default: -+ dev_err(nfc->parent, "unsupported write size: %d bytes\n", -+ mtd->writesize); -+ return -ENXIO; -+ } -+ -+ ctrl |= t << AR934X_NFC_CTRL_PAGE_SIZE_S; -+ -+ if (nfc->small_page) { -+ ctrl |= AR934X_NFC_CTRL_SMALL_PAGE; -+ -+ if (chip->chipsize > (32 << 20)) { -+ nfc->addr_count0 = 4; -+ nfc->addr_count1 = 3; -+ } else if (chip->chipsize > (2 << 16)) { -+ nfc->addr_count0 = 3; -+ nfc->addr_count1 = 2; -+ } else { -+ nfc->addr_count0 = 2; -+ nfc->addr_count1 = 1; -+ } -+ } else { -+ if (chip->chipsize > (128 << 20)) { -+ nfc->addr_count0 = 5; -+ nfc->addr_count1 = 3; -+ } else if (chip->chipsize > (8 << 16)) { -+ nfc->addr_count0 = 4; -+ nfc->addr_count1 = 2; -+ } else { -+ nfc->addr_count0 = 3; -+ nfc->addr_count1 = 1; -+ } -+ } -+ -+ ctrl |= nfc->addr_count0 << AR934X_NFC_CTRL_ADDR_CYCLE0_S; -+ ctrl |= nfc->addr_count1 << AR934X_NFC_CTRL_ADDR_CYCLE1_S; -+ -+ nfc->ctrl_reg = ctrl; -+ ar934x_nfc_wr(nfc, AR934X_NFC_REG_CTRL, nfc->ctrl_reg); -+ -+ ar934x_nfc_free_buf(nfc); -+ err = ar934x_nfc_alloc_buf(nfc, mtd->writesize + mtd->oobsize); -+ -+ return err; -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+static struct nand_ecclayout ar934x_nfc_oob_64_hwecc = { -+ .eccbytes = 28, -+ .eccpos = { -+ 20, 21, 22, 23, 24, 25, 26, -+ 27, 28, 29, 30, 31, 32, 33, -+ 34, 35, 36, 37, 38, 39, 40, -+ 41, 42, 43, 44, 45, 46, 47, -+ }, -+ .oobfree = { -+ { -+ .offset = 4, -+ .length = 16, -+ }, -+ { -+ .offset = 48, -+ .length = 16, -+ }, -+ }, -+}; -+ -+#else -+ -+static int ar934x_nfc_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ if (section) -+ return -ERANGE; -+ -+ oobregion->offset = 20; -+ oobregion->length = 28; -+ -+ return 0; -+} -+ -+static int ar934x_nfc_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 4; -+ oobregion->length = 16; -+ return 0; -+ case 1: -+ oobregion->offset = 48; -+ oobregion->length = 16; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static const struct mtd_ooblayout_ops ar934x_nfc_ecclayout_ops = { -+ .ecc = ar934x_nfc_ooblayout_ecc, -+ .free = ar934x_nfc_ooblayout_free, -+}; -+#endif /* < 4.6 */ -+ -+static int -+ar934x_nfc_setup_hwecc(struct ar934x_nfc *nfc) -+{ -+ struct nand_chip *nand = &nfc->nand_chip; -+ struct mtd_info *mtd = ar934x_nfc_to_mtd(nfc); -+ u32 ecc_cap; -+ u32 ecc_thres; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) -+ struct mtd_oob_region oobregion; -+#endif -+ -+ if (!IS_ENABLED(CONFIG_MTD_NAND_AR934X_HW_ECC)) { -+ dev_err(nfc->parent, "hardware ECC support is disabled\n"); -+ return -EINVAL; -+ } -+ -+ switch (mtd->writesize) { -+ case 2048: -+ /* -+ * Writing a subpage separately is not supported, because -+ * the controller only does ECC on full-page accesses. -+ */ -+ nand->options = NAND_NO_SUBPAGE_WRITE; -+ -+ nand->ecc.size = 512; -+ nand->ecc.bytes = 7; -+ nand->ecc.strength = 4; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ nand->ecc.layout = &ar934x_nfc_oob_64_hwecc; -+#else -+ mtd_set_ooblayout(mtd, &ar934x_nfc_ecclayout_ops); -+#endif -+ break; -+ -+ default: -+ dev_err(nfc->parent, -+ "hardware ECC is not available for %d byte pages\n", -+ mtd->writesize); -+ return -EINVAL; -+ } -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ BUG_ON(!nand->ecc.layout); -+#else -+ BUG_ON(!mtd->ooblayout->ecc); -+#endif -+ -+ switch (nand->ecc.strength) { -+ case 4: -+ ecc_cap = AR934X_NFC_ECC_CTRL_ECC_CAP_4; -+ ecc_thres = 4; -+ break; -+ -+ default: -+ dev_err(nfc->parent, "unsupported ECC strength %u\n", -+ nand->ecc.strength); -+ return -EINVAL; -+ } -+ -+ nfc->ecc_thres = ecc_thres; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ nfc->ecc_oob_pos = nand->ecc.layout->eccpos[0]; -+#else -+ mtd->ooblayout->ecc(mtd, 0, &oobregion); -+ nfc->ecc_oob_pos = oobregion.offset; -+#endif -+ -+ nfc->ecc_ctrl_reg = ecc_cap << AR934X_NFC_ECC_CTRL_ECC_CAP_S; -+ nfc->ecc_ctrl_reg |= ecc_thres << AR934X_NFC_ECC_CTRL_ERR_THRES_S; -+ -+ nfc->ecc_offset_reg = mtd->writesize + nfc->ecc_oob_pos; -+ -+ nand->ecc.mode = NAND_ECC_HW; -+ nand->ecc.read_page = ar934x_nfc_read_page; -+ nand->ecc.read_page_raw = ar934x_nfc_read_page_raw; -+ nand->ecc.write_page = ar934x_nfc_write_page; -+ nand->ecc.write_page_raw = ar934x_nfc_write_page_raw; -+ nand->ecc.read_oob = ar934x_nfc_read_oob; -+ nand->ecc.write_oob = ar934x_nfc_write_oob; -+ -+ return 0; -+} -+ -+static int -+ar934x_nfc_probe(struct platform_device *pdev) -+{ -+ static const char *part_probes[] = { "cmdlinepart", NULL, }; -+ struct ar934x_nfc_platform_data *pdata; -+ struct ar934x_nfc *nfc; -+ struct resource *res; -+ struct mtd_info *mtd; -+ struct nand_chip *nand; -+ struct mtd_part_parser_data ppdata; -+ int ret; -+ -+ pdata = pdev->dev.platform_data; -+ if (pdata == NULL) { -+ dev_err(&pdev->dev, "no platform data defined\n"); -+ return -EINVAL; -+ } -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "failed to get I/O memory\n"); -+ return -EINVAL; -+ } -+ -+ nfc = devm_kzalloc(&pdev->dev, sizeof(struct ar934x_nfc), GFP_KERNEL); -+ if (!nfc) { -+ dev_err(&pdev->dev, "failed to allocate driver data\n"); -+ return -ENOMEM; -+ } -+ -+ nfc->base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(nfc->base)) { -+ dev_err(&pdev->dev, "failed to remap I/O memory\n"); -+ return PTR_ERR(nfc->base); -+ } -+ -+ nfc->irq = platform_get_irq(pdev, 0); -+ if (nfc->irq < 0) { -+ dev_err(&pdev->dev, "no IRQ resource specified\n"); -+ return -EINVAL; -+ } -+ -+ init_waitqueue_head(&nfc->irq_waitq); -+ ret = request_irq(nfc->irq, ar934x_nfc_irq_handler, 0, -+ dev_name(&pdev->dev), nfc); -+ if (ret) { -+ dev_err(&pdev->dev, "requast_irq failed, err:%d\n", ret); -+ return ret; -+ } -+ -+ nfc->parent = &pdev->dev; -+ nfc->select_chip = pdata->select_chip; -+ nfc->swap_dma = pdata->swap_dma; -+ -+ nand = &nfc->nand_chip; -+ mtd = ar934x_nfc_to_mtd(nfc); -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ mtd->priv = nand; -+#endif -+ mtd->owner = THIS_MODULE; -+ if (pdata->name) -+ mtd->name = pdata->name; -+ else -+ mtd->name = dev_name(&pdev->dev); -+ -+ nand->chip_delay = 25; -+ -+ nand->dev_ready = ar934x_nfc_dev_ready; -+ nand->cmdfunc = ar934x_nfc_cmdfunc; -+ nand->read_byte = ar934x_nfc_read_byte; -+ nand->write_buf = ar934x_nfc_write_buf; -+ nand->read_buf = ar934x_nfc_read_buf; -+ nand->select_chip = ar934x_nfc_select_chip; -+ -+ ret = ar934x_nfc_alloc_buf(nfc, AR934X_NFC_ID_BUF_SIZE); -+ if (ret) -+ goto err_free_irq; -+ -+ platform_set_drvdata(pdev, nfc); -+ -+ ar934x_nfc_hw_init(nfc); -+ -+ ret = nand_scan_ident(mtd, 1, NULL); -+ if (ret) { -+ dev_err(&pdev->dev, "nand_scan_ident failed, err:%d\n", ret); -+ goto err_free_buf; -+ } -+ -+ ret = ar934x_nfc_init_tail(mtd); -+ if (ret) { -+ dev_err(&pdev->dev, "init tail failed, err:%d\n", ret); -+ goto err_free_buf; -+ } -+ -+ if (pdata->scan_fixup) { -+ ret = pdata->scan_fixup(mtd); -+ if (ret) -+ goto err_free_buf; -+ } -+ -+ switch (pdata->ecc_mode) { -+ case AR934X_NFC_ECC_SOFT: -+ nand->ecc.mode = NAND_ECC_SOFT; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) -+ nand->ecc.algo = NAND_ECC_HAMMING; -+#endif -+ break; -+ -+ case AR934X_NFC_ECC_SOFT_BCH: -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ nand->ecc.mode = NAND_ECC_SOFT_BCH; -+#else -+ nand->ecc.mode = NAND_ECC_SOFT; -+ nand->ecc.algo = NAND_ECC_BCH; -+#endif -+ break; -+ -+ case AR934X_NFC_ECC_HW: -+ ret = ar934x_nfc_setup_hwecc(nfc); -+ if (ret) -+ goto err_free_buf; -+ -+ break; -+ -+ default: -+ dev_err(nfc->parent, "unknown ECC mode %d\n", pdata->ecc_mode); -+ return -EINVAL; -+ } -+ -+ ret = nand_scan_tail(mtd); -+ if (ret) { -+ dev_err(&pdev->dev, "scan tail failed, err:%d\n", ret); -+ goto err_free_buf; -+ } -+ -+ memset(&ppdata, '\0', sizeof(ppdata)); -+ ret = mtd_device_parse_register(mtd, part_probes, &ppdata, -+ pdata->parts, pdata->nr_parts); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to register mtd, err:%d\n", ret); -+ goto err_free_buf; -+ } -+ -+ return 0; -+ -+err_free_buf: -+ ar934x_nfc_free_buf(nfc); -+err_free_irq: -+ free_irq(nfc->irq, nfc); -+ return ret; -+} -+ -+static int -+ar934x_nfc_remove(struct platform_device *pdev) -+{ -+ struct ar934x_nfc *nfc; -+ struct mtd_info *mtd; -+ -+ nfc = platform_get_drvdata(pdev); -+ if (nfc) { -+ mtd = ar934x_nfc_to_mtd(nfc); -+ nand_release(&nfc->nand_chip); -+ ar934x_nfc_free_buf(nfc); -+ free_irq(nfc->irq, nfc); -+ } -+ -+ return 0; -+} -+ -+static struct platform_driver ar934x_nfc_driver = { -+ .probe = ar934x_nfc_probe, -+ .remove = ar934x_nfc_remove, -+ .driver = { -+ .name = AR934X_NFC_DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+module_platform_driver(ar934x_nfc_driver); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_DESCRIPTION("Atheros AR934x NAND Flash Controller driver"); -+MODULE_ALIAS("platform:" AR934X_NFC_DRIVER_NAME); -diff --git a/target/linux/ar71xx/files/drivers/mtd/nand/rb4xx_nand.c b/target/linux/ar71xx/files/drivers/mtd/nand/rb4xx_nand.c -new file mode 100644 -index 0000000000..7dde613131 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/mtd/nand/rb4xx_nand.c -@@ -0,0 +1,396 @@ -+/* -+ * NAND flash driver for the MikroTik RouterBoard 4xx series -+ * -+ * Copyright (C) 2008-2011 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * This file was based on the driver for Linux 2.6.22 published by -+ * MikroTik for their RouterBoard 4xx series devices. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) -+#include -+#else -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define DRV_NAME "rb4xx-nand" -+#define DRV_VERSION "0.2.0" -+#define DRV_DESC "NAND flash driver for RouterBoard 4xx series" -+ -+#define RB4XX_NAND_GPIO_READY 5 -+#define RB4XX_NAND_GPIO_ALE 37 -+#define RB4XX_NAND_GPIO_CLE 38 -+#define RB4XX_NAND_GPIO_NCE 39 -+ -+struct rb4xx_nand_info { -+ struct nand_chip chip; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ struct mtd_info mtd; -+#endif -+}; -+ -+static inline struct rb4xx_nand_info *mtd_to_rbinfo(struct mtd_info *mtd) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ return container_of(mtd, struct rb4xx_nand_info, mtd); -+#else -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ -+ return container_of(chip, struct rb4xx_nand_info, chip); -+#endif -+} -+ -+static struct mtd_info *rbinfo_to_mtd(struct rb4xx_nand_info *nfc) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ return &nfc->mtd; -+#else -+ return nand_to_mtd(&nfc->chip); -+#endif -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+/* -+ * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader -+ * will not be able to find the kernel that we load. -+ */ -+static struct nand_ecclayout rb4xx_nand_ecclayout = { -+ .eccbytes = 6, -+ .eccpos = { 8, 9, 10, 13, 14, 15 }, -+ .oobavail = 9, -+ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } -+}; -+ -+#else -+ -+static int rb4xx_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 8; -+ oobregion->length = 3; -+ return 0; -+ case 1: -+ oobregion->offset = 13; -+ oobregion->length = 3; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static int rb4xx_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 0; -+ oobregion->length = 4; -+ return 0; -+ case 1: -+ oobregion->offset = 4; -+ oobregion->length = 1; -+ return 0; -+ case 2: -+ oobregion->offset = 6; -+ oobregion->length = 2; -+ return 0; -+ case 3: -+ oobregion->offset = 11; -+ oobregion->length = 2; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static const struct mtd_ooblayout_ops rb4xx_nand_ecclayout_ops = { -+ .ecc = rb4xx_ooblayout_ecc, -+ .free = rb4xx_ooblayout_free, -+}; -+#endif /* < 4.6 */ -+ -+static struct mtd_partition rb4xx_nand_partitions[] = { -+ { -+ .name = "booter", -+ .offset = 0, -+ .size = (256 * 1024), -+ .mask_flags = MTD_WRITEABLE, -+ }, -+ { -+ .name = "kernel", -+ .offset = (256 * 1024), -+ .size = (4 * 1024 * 1024) - (256 * 1024), -+ }, -+ { -+ .name = "ubi", -+ .offset = MTDPART_OFS_NXTBLK, -+ .size = MTDPART_SIZ_FULL, -+ }, -+}; -+ -+static int rb4xx_nand_dev_ready(struct mtd_info *mtd) -+{ -+ return gpio_get_value_cansleep(RB4XX_NAND_GPIO_READY); -+} -+ -+static void rb4xx_nand_write_cmd(unsigned char cmd) -+{ -+ unsigned char data = cmd; -+ int err; -+ -+ err = rb4xx_cpld_write(&data, 1); -+ if (err) -+ pr_err("rb4xx_nand: write cmd failed, err=%d\n", err); -+} -+ -+static void rb4xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, -+ unsigned int ctrl) -+{ -+ if (ctrl & NAND_CTRL_CHANGE) { -+ gpio_set_value_cansleep(RB4XX_NAND_GPIO_CLE, -+ (ctrl & NAND_CLE) ? 1 : 0); -+ gpio_set_value_cansleep(RB4XX_NAND_GPIO_ALE, -+ (ctrl & NAND_ALE) ? 1 : 0); -+ gpio_set_value_cansleep(RB4XX_NAND_GPIO_NCE, -+ (ctrl & NAND_NCE) ? 0 : 1); -+ } -+ -+ if (cmd != NAND_CMD_NONE) -+ rb4xx_nand_write_cmd(cmd); -+} -+ -+static unsigned char rb4xx_nand_read_byte(struct mtd_info *mtd) -+{ -+ unsigned char data = 0; -+ int err; -+ -+ err = rb4xx_cpld_read(&data, 1); -+ if (err) { -+ pr_err("rb4xx_nand: read data failed, err=%d\n", err); -+ data = 0xff; -+ } -+ -+ return data; -+} -+ -+static void rb4xx_nand_write_buf(struct mtd_info *mtd, const unsigned char *buf, -+ int len) -+{ -+ int err; -+ -+ err = rb4xx_cpld_write(buf, len); -+ if (err) -+ pr_err("rb4xx_nand: write buf failed, err=%d\n", err); -+} -+ -+static void rb4xx_nand_read_buf(struct mtd_info *mtd, unsigned char *buf, -+ int len) -+{ -+ int err; -+ -+ err = rb4xx_cpld_read(buf, len); -+ if (err) -+ pr_err("rb4xx_nand: read buf failed, err=%d\n", err); -+} -+ -+static int rb4xx_nand_probe(struct platform_device *pdev) -+{ -+ struct rb4xx_nand_info *info; -+ struct mtd_info *mtd; -+ int ret; -+ -+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); -+ -+ ret = gpio_request(RB4XX_NAND_GPIO_READY, "NAND RDY"); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to request gpio %d\n", -+ RB4XX_NAND_GPIO_READY); -+ goto err; -+ } -+ -+ ret = gpio_direction_input(RB4XX_NAND_GPIO_READY); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to set input mode on gpio %d\n", -+ RB4XX_NAND_GPIO_READY); -+ goto err_free_gpio_ready; -+ } -+ -+ ret = gpio_request(RB4XX_NAND_GPIO_ALE, "NAND ALE"); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to request gpio %d\n", -+ RB4XX_NAND_GPIO_ALE); -+ goto err_free_gpio_ready; -+ } -+ -+ ret = gpio_direction_output(RB4XX_NAND_GPIO_ALE, 0); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", -+ RB4XX_NAND_GPIO_ALE); -+ goto err_free_gpio_ale; -+ } -+ -+ ret = gpio_request(RB4XX_NAND_GPIO_CLE, "NAND CLE"); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to request gpio %d\n", -+ RB4XX_NAND_GPIO_CLE); -+ goto err_free_gpio_ale; -+ } -+ -+ ret = gpio_direction_output(RB4XX_NAND_GPIO_CLE, 0); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", -+ RB4XX_NAND_GPIO_CLE); -+ goto err_free_gpio_cle; -+ } -+ -+ ret = gpio_request(RB4XX_NAND_GPIO_NCE, "NAND NCE"); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to request gpio %d\n", -+ RB4XX_NAND_GPIO_NCE); -+ goto err_free_gpio_cle; -+ } -+ -+ ret = gpio_direction_output(RB4XX_NAND_GPIO_NCE, 1); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", -+ RB4XX_NAND_GPIO_ALE); -+ goto err_free_gpio_nce; -+ } -+ -+ info = kzalloc(sizeof(*info), GFP_KERNEL); -+ if (!info) { -+ dev_err(&pdev->dev, "rb4xx-nand: no memory for private data\n"); -+ ret = -ENOMEM; -+ goto err_free_gpio_nce; -+ } -+ -+ info->chip.priv = &info; -+ mtd = rbinfo_to_mtd(info); -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ mtd->priv = &info->chip; -+#endif -+ mtd->owner = THIS_MODULE; -+ -+ info->chip.cmd_ctrl = rb4xx_nand_cmd_ctrl; -+ info->chip.dev_ready = rb4xx_nand_dev_ready; -+ info->chip.read_byte = rb4xx_nand_read_byte; -+ info->chip.write_buf = rb4xx_nand_write_buf; -+ info->chip.read_buf = rb4xx_nand_read_buf; -+ -+ info->chip.chip_delay = 25; -+ info->chip.ecc.mode = NAND_ECC_SOFT; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) -+ info->chip.ecc.algo = NAND_ECC_HAMMING; -+#endif -+ info->chip.options = NAND_NO_SUBPAGE_WRITE; -+ -+ platform_set_drvdata(pdev, info); -+ -+ ret = nand_scan_ident(mtd, 1, NULL); -+ if (ret) { -+ ret = -ENXIO; -+ goto err_free_info; -+ } -+ -+ if (mtd->writesize == 512) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ info->chip.ecc.layout = &rb4xx_nand_ecclayout; -+#else -+ mtd_set_ooblayout(mtd, &rb4xx_nand_ecclayout_ops); -+#endif -+ -+ ret = nand_scan_tail(mtd); -+ if (ret) { -+ return -ENXIO; -+ goto err_set_drvdata; -+ } -+ -+ mtd_device_register(mtd, rb4xx_nand_partitions, -+ ARRAY_SIZE(rb4xx_nand_partitions)); -+ if (ret) -+ goto err_release_nand; -+ -+ return 0; -+ -+err_release_nand: -+ nand_release(&info->chip); -+err_set_drvdata: -+ platform_set_drvdata(pdev, NULL); -+err_free_info: -+ kfree(info); -+err_free_gpio_nce: -+ gpio_free(RB4XX_NAND_GPIO_NCE); -+err_free_gpio_cle: -+ gpio_free(RB4XX_NAND_GPIO_CLE); -+err_free_gpio_ale: -+ gpio_free(RB4XX_NAND_GPIO_ALE); -+err_free_gpio_ready: -+ gpio_free(RB4XX_NAND_GPIO_READY); -+err: -+ return ret; -+} -+ -+static int rb4xx_nand_remove(struct platform_device *pdev) -+{ -+ struct rb4xx_nand_info *info = platform_get_drvdata(pdev); -+ -+ nand_release(&info->chip); -+ platform_set_drvdata(pdev, NULL); -+ kfree(info); -+ gpio_free(RB4XX_NAND_GPIO_NCE); -+ gpio_free(RB4XX_NAND_GPIO_CLE); -+ gpio_free(RB4XX_NAND_GPIO_ALE); -+ gpio_free(RB4XX_NAND_GPIO_READY); -+ -+ return 0; -+} -+ -+static struct platform_driver rb4xx_nand_driver = { -+ .probe = rb4xx_nand_probe, -+ .remove = rb4xx_nand_remove, -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init rb4xx_nand_init(void) -+{ -+ return platform_driver_register(&rb4xx_nand_driver); -+} -+ -+static void __exit rb4xx_nand_exit(void) -+{ -+ platform_driver_unregister(&rb4xx_nand_driver); -+} -+ -+module_init(rb4xx_nand_init); -+module_exit(rb4xx_nand_exit); -+ -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_AUTHOR("Imre Kaloz "); -+MODULE_LICENSE("GPL v2"); -diff --git a/target/linux/ar71xx/files/drivers/mtd/nand/rb750_nand.c b/target/linux/ar71xx/files/drivers/mtd/nand/rb750_nand.c -new file mode 100644 -index 0000000000..a578c54ad3 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/mtd/nand/rb750_nand.c -@@ -0,0 +1,440 @@ -+/* -+ * NAND flash driver for the MikroTik RouterBOARD 750 -+ * -+ * Copyright (C) 2010-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) -+#include -+#else -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#define DRV_NAME "rb750-nand" -+#define DRV_VERSION "0.1.0" -+#define DRV_DESC "NAND flash driver for the RouterBOARD 750" -+ -+#define RB750_NAND_IO0 BIT(RB750_GPIO_NAND_IO0) -+#define RB750_NAND_ALE BIT(RB750_GPIO_NAND_ALE) -+#define RB750_NAND_CLE BIT(RB750_GPIO_NAND_CLE) -+#define RB750_NAND_NRE BIT(RB750_GPIO_NAND_NRE) -+#define RB750_NAND_NWE BIT(RB750_GPIO_NAND_NWE) -+#define RB750_NAND_RDY BIT(RB750_GPIO_NAND_RDY) -+ -+#define RB750_NAND_DATA_SHIFT 1 -+#define RB750_NAND_DATA_BITS (0xff << RB750_NAND_DATA_SHIFT) -+#define RB750_NAND_INPUT_BITS (RB750_NAND_DATA_BITS | RB750_NAND_RDY) -+#define RB750_NAND_OUTPUT_BITS (RB750_NAND_ALE | RB750_NAND_CLE | \ -+ RB750_NAND_NRE | RB750_NAND_NWE) -+ -+struct rb750_nand_info { -+ struct nand_chip chip; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ struct mtd_info mtd; -+#endif -+ struct rb7xx_nand_platform_data *pdata; -+}; -+ -+static inline struct rb750_nand_info *mtd_to_rbinfo(struct mtd_info *mtd) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ return container_of(mtd, struct rb750_nand_info, mtd); -+#else -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ -+ return container_of(chip, struct rb750_nand_info, chip); -+#endif -+} -+ -+static struct mtd_info *rbinfo_to_mtd(struct rb750_nand_info *nfc) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ return &nfc->mtd; -+#else -+ return nand_to_mtd(&nfc->chip); -+#endif -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+/* -+ * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader -+ * will not be able to find the kernel that we load. -+ */ -+static struct nand_ecclayout rb750_nand_ecclayout = { -+ .eccbytes = 6, -+ .eccpos = { 8, 9, 10, 13, 14, 15 }, -+ .oobavail = 9, -+ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } -+}; -+ -+#else -+ -+static int rb750_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 8; -+ oobregion->length = 3; -+ return 0; -+ case 1: -+ oobregion->offset = 13; -+ oobregion->length = 3; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static int rb750_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 0; -+ oobregion->length = 4; -+ return 0; -+ case 1: -+ oobregion->offset = 4; -+ oobregion->length = 1; -+ return 0; -+ case 2: -+ oobregion->offset = 6; -+ oobregion->length = 2; -+ return 0; -+ case 3: -+ oobregion->offset = 11; -+ oobregion->length = 2; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static const struct mtd_ooblayout_ops rb750_nand_ecclayout_ops = { -+ .ecc = rb750_ooblayout_ecc, -+ .free = rb750_ooblayout_free, -+}; -+#endif /* < 4.6 */ -+ -+static struct mtd_partition rb750_nand_partitions[] = { -+ { -+ .name = "booter", -+ .offset = 0, -+ .size = (256 * 1024), -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "kernel", -+ .offset = (256 * 1024), -+ .size = (4 * 1024 * 1024) - (256 * 1024), -+ }, { -+ .name = "ubi", -+ .offset = MTDPART_OFS_NXTBLK, -+ .size = MTDPART_SIZ_FULL, -+ }, -+}; -+ -+static void rb750_nand_write(const u8 *buf, unsigned len) -+{ -+ void __iomem *base = ath79_gpio_base; -+ u32 out; -+ u32 t; -+ unsigned i; -+ -+ /* set data lines to output mode */ -+ t = __raw_readl(base + AR71XX_GPIO_REG_OE); -+ __raw_writel(t | RB750_NAND_DATA_BITS, base + AR71XX_GPIO_REG_OE); -+ -+ out = __raw_readl(base + AR71XX_GPIO_REG_OUT); -+ out &= ~(RB750_NAND_DATA_BITS | RB750_NAND_NWE); -+ for (i = 0; i != len; i++) { -+ u32 data; -+ -+ data = buf[i]; -+ data <<= RB750_NAND_DATA_SHIFT; -+ data |= out; -+ __raw_writel(data, base + AR71XX_GPIO_REG_OUT); -+ -+ __raw_writel(data | RB750_NAND_NWE, base + AR71XX_GPIO_REG_OUT); -+ /* flush write */ -+ __raw_readl(base + AR71XX_GPIO_REG_OUT); -+ } -+ -+ /* set data lines to input mode */ -+ t = __raw_readl(base + AR71XX_GPIO_REG_OE); -+ __raw_writel(t & ~RB750_NAND_DATA_BITS, base + AR71XX_GPIO_REG_OE); -+ /* flush write */ -+ __raw_readl(base + AR71XX_GPIO_REG_OE); -+} -+ -+static void rb750_nand_read(u8 *read_buf, unsigned len) -+{ -+ void __iomem *base = ath79_gpio_base; -+ unsigned i; -+ -+ for (i = 0; i < len; i++) { -+ u8 data; -+ -+ /* activate RE line */ -+ __raw_writel(RB750_NAND_NRE, base + AR71XX_GPIO_REG_CLEAR); -+ /* flush write */ -+ __raw_readl(base + AR71XX_GPIO_REG_CLEAR); -+ -+ /* read input lines */ -+ data = __raw_readl(base + AR71XX_GPIO_REG_IN) >> -+ RB750_NAND_DATA_SHIFT; -+ -+ /* deactivate RE line */ -+ __raw_writel(RB750_NAND_NRE, base + AR71XX_GPIO_REG_SET); -+ -+ read_buf[i] = data; -+ } -+} -+ -+static void rb750_nand_select_chip(struct mtd_info *mtd, int chip) -+{ -+ struct rb750_nand_info *rbinfo = mtd_to_rbinfo(mtd); -+ void __iomem *base = ath79_gpio_base; -+ u32 t; -+ -+ if (chip >= 0) { -+ rbinfo->pdata->enable_pins(); -+ -+ /* set input mode for data lines */ -+ t = __raw_readl(base + AR71XX_GPIO_REG_OE); -+ __raw_writel(t & ~RB750_NAND_INPUT_BITS, -+ base + AR71XX_GPIO_REG_OE); -+ -+ /* deactivate RE and WE lines */ -+ __raw_writel(RB750_NAND_NRE | RB750_NAND_NWE, -+ base + AR71XX_GPIO_REG_SET); -+ /* flush write */ -+ (void) __raw_readl(base + AR71XX_GPIO_REG_SET); -+ -+ /* activate CE line */ -+ __raw_writel(rbinfo->pdata->nce_line, -+ base + AR71XX_GPIO_REG_CLEAR); -+ } else { -+ /* deactivate CE line */ -+ __raw_writel(rbinfo->pdata->nce_line, -+ base + AR71XX_GPIO_REG_SET); -+ /* flush write */ -+ (void) __raw_readl(base + AR71XX_GPIO_REG_SET); -+ -+ t = __raw_readl(base + AR71XX_GPIO_REG_OE); -+ __raw_writel(t | RB750_NAND_IO0 | RB750_NAND_RDY, -+ base + AR71XX_GPIO_REG_OE); -+ -+ rbinfo->pdata->disable_pins(); -+ } -+} -+ -+static int rb750_nand_dev_ready(struct mtd_info *mtd) -+{ -+ void __iomem *base = ath79_gpio_base; -+ -+ return !!(__raw_readl(base + AR71XX_GPIO_REG_IN) & RB750_NAND_RDY); -+} -+ -+static void rb750_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, -+ unsigned int ctrl) -+{ -+ if (ctrl & NAND_CTRL_CHANGE) { -+ void __iomem *base = ath79_gpio_base; -+ u32 t; -+ -+ t = __raw_readl(base + AR71XX_GPIO_REG_OUT); -+ -+ t &= ~(RB750_NAND_CLE | RB750_NAND_ALE); -+ t |= (ctrl & NAND_CLE) ? RB750_NAND_CLE : 0; -+ t |= (ctrl & NAND_ALE) ? RB750_NAND_ALE : 0; -+ -+ __raw_writel(t, base + AR71XX_GPIO_REG_OUT); -+ /* flush write */ -+ __raw_readl(base + AR71XX_GPIO_REG_OUT); -+ } -+ -+ if (cmd != NAND_CMD_NONE) { -+ u8 t = cmd; -+ rb750_nand_write(&t, 1); -+ } -+} -+ -+static u8 rb750_nand_read_byte(struct mtd_info *mtd) -+{ -+ u8 data = 0; -+ rb750_nand_read(&data, 1); -+ return data; -+} -+ -+static void rb750_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len) -+{ -+ rb750_nand_read(buf, len); -+} -+ -+static void rb750_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len) -+{ -+ rb750_nand_write(buf, len); -+} -+ -+static void __init rb750_nand_gpio_init(struct rb750_nand_info *info) -+{ -+ void __iomem *base = ath79_gpio_base; -+ u32 out; -+ u32 t; -+ -+ out = __raw_readl(base + AR71XX_GPIO_REG_OUT); -+ -+ /* setup output levels */ -+ __raw_writel(RB750_NAND_NCE | RB750_NAND_NRE | RB750_NAND_NWE, -+ base + AR71XX_GPIO_REG_SET); -+ -+ __raw_writel(RB750_NAND_ALE | RB750_NAND_CLE, -+ base + AR71XX_GPIO_REG_CLEAR); -+ -+ /* setup input lines */ -+ t = __raw_readl(base + AR71XX_GPIO_REG_OE); -+ __raw_writel(t & ~(RB750_NAND_INPUT_BITS), base + AR71XX_GPIO_REG_OE); -+ -+ /* setup output lines */ -+ t = __raw_readl(base + AR71XX_GPIO_REG_OE); -+ t |= RB750_NAND_OUTPUT_BITS; -+ t |= info->pdata->nce_line; -+ __raw_writel(t, base + AR71XX_GPIO_REG_OE); -+ -+ info->pdata->latch_change(~out & RB750_NAND_IO0, out & RB750_NAND_IO0); -+} -+ -+static int rb750_nand_probe(struct platform_device *pdev) -+{ -+ struct rb750_nand_info *info; -+ struct rb7xx_nand_platform_data *pdata; -+ struct mtd_info *mtd; -+ int ret; -+ -+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); -+ -+ pdata = pdev->dev.platform_data; -+ if (!pdata) -+ return -EINVAL; -+ -+ info = kzalloc(sizeof(*info), GFP_KERNEL); -+ if (!info) -+ return -ENOMEM; -+ -+ info->chip.priv = &info; -+ -+ mtd = rbinfo_to_mtd(info); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ mtd->priv = &info->chip; -+#endif -+ mtd->owner = THIS_MODULE; -+ -+ info->chip.select_chip = rb750_nand_select_chip; -+ info->chip.cmd_ctrl = rb750_nand_cmd_ctrl; -+ info->chip.dev_ready = rb750_nand_dev_ready; -+ info->chip.read_byte = rb750_nand_read_byte; -+ info->chip.write_buf = rb750_nand_write_buf; -+ info->chip.read_buf = rb750_nand_read_buf; -+ -+ info->chip.chip_delay = 25; -+ info->chip.ecc.mode = NAND_ECC_SOFT; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) -+ info->chip.ecc.algo = NAND_ECC_HAMMING; -+#endif -+ info->chip.options = NAND_NO_SUBPAGE_WRITE; -+ -+ info->pdata = pdata; -+ -+ platform_set_drvdata(pdev, info); -+ -+ rb750_nand_gpio_init(info); -+ -+ ret = nand_scan_ident(mtd, 1, NULL); -+ if (ret) { -+ ret = -ENXIO; -+ goto err_free_info; -+ } -+ -+ if (mtd->writesize == 512) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ info->chip.ecc.layout = &rb750_nand_ecclayout; -+#else -+ mtd_set_ooblayout(mtd, &rb750_nand_ecclayout_ops); -+#endif -+ -+ ret = nand_scan_tail(mtd); -+ if (ret) { -+ return -ENXIO; -+ goto err_set_drvdata; -+ } -+ -+ ret = mtd_device_register(mtd, rb750_nand_partitions, -+ ARRAY_SIZE(rb750_nand_partitions)); -+ if (ret) -+ goto err_release_nand; -+ -+ return 0; -+ -+err_release_nand: -+ nand_release(&info->chip); -+err_set_drvdata: -+ platform_set_drvdata(pdev, NULL); -+err_free_info: -+ kfree(info); -+ return ret; -+} -+ -+static int rb750_nand_remove(struct platform_device *pdev) -+{ -+ struct rb750_nand_info *info = platform_get_drvdata(pdev); -+ -+ nand_release(&info->chip); -+ platform_set_drvdata(pdev, NULL); -+ kfree(info); -+ -+ return 0; -+} -+ -+static struct platform_driver rb750_nand_driver = { -+ .probe = rb750_nand_probe, -+ .remove = rb750_nand_remove, -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init rb750_nand_init(void) -+{ -+ return platform_driver_register(&rb750_nand_driver); -+} -+ -+static void __exit rb750_nand_exit(void) -+{ -+ platform_driver_unregister(&rb750_nand_driver); -+} -+ -+module_init(rb750_nand_init); -+module_exit(rb750_nand_exit); -+ -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -diff --git a/target/linux/ar71xx/files/drivers/mtd/nand/rb91x_nand.c b/target/linux/ar71xx/files/drivers/mtd/nand/rb91x_nand.c -new file mode 100644 -index 0000000000..94e709b7e4 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/mtd/nand/rb91x_nand.c -@@ -0,0 +1,464 @@ -+/* -+ * NAND flash driver for the MikroTik RouterBOARD 91x series -+ * -+ * Copyright (C) 2013-2014 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) -+#include -+#else -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define DRV_DESC "NAND flash driver for the RouterBOARD 91x series" -+ -+#define RB91X_NAND_NRWE BIT(12) -+ -+#define RB91X_NAND_DATA_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) |\ -+ BIT(13) | BIT(14) | BIT(15)) -+ -+#define RB91X_NAND_INPUT_BITS (RB91X_NAND_DATA_BITS | RB91X_NAND_RDY) -+#define RB91X_NAND_OUTPUT_BITS (RB91X_NAND_DATA_BITS | RB91X_NAND_NRWE) -+ -+#define RB91X_NAND_LOW_DATA_MASK 0x1f -+#define RB91X_NAND_HIGH_DATA_MASK 0xe0 -+#define RB91X_NAND_HIGH_DATA_SHIFT 8 -+ -+struct rb91x_nand_info { -+ struct nand_chip chip; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ struct mtd_info mtd; -+#endif -+ struct device *dev; -+ -+ int gpio_nce; -+ int gpio_ale; -+ int gpio_cle; -+ int gpio_rdy; -+ int gpio_read; -+ int gpio_nrw; -+ int gpio_nle; -+}; -+ -+static inline struct rb91x_nand_info *mtd_to_rbinfo(struct mtd_info *mtd) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ return container_of(mtd, struct rb91x_nand_info, mtd); -+#else -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ -+ return container_of(chip, struct rb91x_nand_info, chip); -+#endif -+} -+ -+static struct mtd_info *rbinfo_to_mtd(struct rb91x_nand_info *nfc) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ return &nfc->mtd; -+#else -+ return nand_to_mtd(&nfc->chip); -+#endif -+} -+ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+/* -+ * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader -+ * will not be able to find the kernel that we load. -+ */ -+static struct nand_ecclayout rb91x_nand_ecclayout = { -+ .eccbytes = 6, -+ .eccpos = { 8, 9, 10, 13, 14, 15 }, -+ .oobavail = 9, -+ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } -+}; -+ -+#else -+ -+static int rb91x_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 8; -+ oobregion->length = 3; -+ return 0; -+ case 1: -+ oobregion->offset = 13; -+ oobregion->length = 3; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static int rb91x_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ switch (section) { -+ case 0: -+ oobregion->offset = 0; -+ oobregion->length = 4; -+ return 0; -+ case 1: -+ oobregion->offset = 4; -+ oobregion->length = 1; -+ return 0; -+ case 2: -+ oobregion->offset = 6; -+ oobregion->length = 2; -+ return 0; -+ case 3: -+ oobregion->offset = 11; -+ oobregion->length = 2; -+ return 0; -+ default: -+ return -ERANGE; -+ } -+} -+ -+static const struct mtd_ooblayout_ops rb91x_nand_ecclayout_ops = { -+ .ecc = rb91x_ooblayout_ecc, -+ .free = rb91x_ooblayout_free, -+}; -+#endif /* < 4.6 */ -+ -+static struct mtd_partition rb91x_nand_partitions[] = { -+ { -+ .name = "booter", -+ .offset = 0, -+ .size = (256 * 1024), -+ .mask_flags = MTD_WRITEABLE, -+ }, { -+ .name = "kernel", -+ .offset = (256 * 1024), -+ .size = (4 * 1024 * 1024) - (256 * 1024), -+ }, { -+ .name = "ubi", -+ .offset = MTDPART_OFS_NXTBLK, -+ .size = MTDPART_SIZ_FULL, -+ }, -+}; -+ -+static void rb91x_nand_write(struct rb91x_nand_info *rbni, -+ const u8 *buf, -+ unsigned len) -+{ -+ void __iomem *base = ath79_gpio_base; -+ u32 oe_reg; -+ u32 out_reg; -+ u32 out; -+ unsigned i; -+ -+ /* enable the latch */ -+ gpio_set_value_cansleep(rbni->gpio_nle, 0); -+ -+ oe_reg = __raw_readl(base + AR71XX_GPIO_REG_OE); -+ out_reg = __raw_readl(base + AR71XX_GPIO_REG_OUT); -+ -+ /* set data lines to output mode */ -+ __raw_writel(oe_reg & ~(RB91X_NAND_DATA_BITS | RB91X_NAND_NRWE), -+ base + AR71XX_GPIO_REG_OE); -+ -+ out = out_reg & ~(RB91X_NAND_DATA_BITS | RB91X_NAND_NRWE); -+ for (i = 0; i != len; i++) { -+ u32 data; -+ -+ data = (buf[i] & RB91X_NAND_HIGH_DATA_MASK) << -+ RB91X_NAND_HIGH_DATA_SHIFT; -+ data |= buf[i] & RB91X_NAND_LOW_DATA_MASK; -+ data |= out; -+ __raw_writel(data, base + AR71XX_GPIO_REG_OUT); -+ -+ /* deactivate WE line */ -+ data |= RB91X_NAND_NRWE; -+ __raw_writel(data, base + AR71XX_GPIO_REG_OUT); -+ /* flush write */ -+ __raw_readl(base + AR71XX_GPIO_REG_OUT); -+ } -+ -+ /* restore registers */ -+ __raw_writel(out_reg, base + AR71XX_GPIO_REG_OUT); -+ __raw_writel(oe_reg, base + AR71XX_GPIO_REG_OE); -+ /* flush write */ -+ __raw_readl(base + AR71XX_GPIO_REG_OUT); -+ -+ /* disable the latch */ -+ gpio_set_value_cansleep(rbni->gpio_nle, 1); -+} -+ -+static void rb91x_nand_read(struct rb91x_nand_info *rbni, -+ u8 *read_buf, -+ unsigned len) -+{ -+ void __iomem *base = ath79_gpio_base; -+ u32 oe_reg; -+ u32 out_reg; -+ unsigned i; -+ -+ /* enable read mode */ -+ gpio_set_value_cansleep(rbni->gpio_read, 1); -+ -+ /* enable latch */ -+ gpio_set_value_cansleep(rbni->gpio_nle, 0); -+ -+ /* save registers */ -+ oe_reg = __raw_readl(base + AR71XX_GPIO_REG_OE); -+ out_reg = __raw_readl(base + AR71XX_GPIO_REG_OUT); -+ -+ /* set data lines to input mode */ -+ __raw_writel(oe_reg | RB91X_NAND_DATA_BITS, -+ base + AR71XX_GPIO_REG_OE); -+ -+ for (i = 0; i < len; i++) { -+ u32 in; -+ u8 data; -+ -+ /* activate RE line */ -+ __raw_writel(RB91X_NAND_NRWE, base + AR71XX_GPIO_REG_CLEAR); -+ /* flush write */ -+ __raw_readl(base + AR71XX_GPIO_REG_CLEAR); -+ -+ /* read input lines */ -+ in = __raw_readl(base + AR71XX_GPIO_REG_IN); -+ -+ /* deactivate RE line */ -+ __raw_writel(RB91X_NAND_NRWE, base + AR71XX_GPIO_REG_SET); -+ -+ data = (in & RB91X_NAND_LOW_DATA_MASK); -+ data |= (in >> RB91X_NAND_HIGH_DATA_SHIFT) & -+ RB91X_NAND_HIGH_DATA_MASK; -+ -+ read_buf[i] = data; -+ } -+ -+ /* restore registers */ -+ __raw_writel(out_reg, base + AR71XX_GPIO_REG_OUT); -+ __raw_writel(oe_reg, base + AR71XX_GPIO_REG_OE); -+ /* flush write */ -+ __raw_readl(base + AR71XX_GPIO_REG_OUT); -+ -+ /* disable latch */ -+ gpio_set_value_cansleep(rbni->gpio_nle, 1); -+ -+ /* disable read mode */ -+ gpio_set_value_cansleep(rbni->gpio_read, 0); -+} -+ -+static int rb91x_nand_dev_ready(struct mtd_info *mtd) -+{ -+ struct rb91x_nand_info *rbni = mtd_to_rbinfo(mtd); -+ -+ return gpio_get_value_cansleep(rbni->gpio_rdy); -+} -+ -+static void rb91x_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, -+ unsigned int ctrl) -+{ -+ struct rb91x_nand_info *rbni = mtd_to_rbinfo(mtd); -+ -+ if (ctrl & NAND_CTRL_CHANGE) { -+ gpio_set_value_cansleep(rbni->gpio_cle, -+ (ctrl & NAND_CLE) ? 1 : 0); -+ gpio_set_value_cansleep(rbni->gpio_ale, -+ (ctrl & NAND_ALE) ? 1 : 0); -+ gpio_set_value_cansleep(rbni->gpio_nce, -+ (ctrl & NAND_NCE) ? 0 : 1); -+ } -+ -+ if (cmd != NAND_CMD_NONE) { -+ u8 t = cmd; -+ -+ rb91x_nand_write(rbni, &t, 1); -+ } -+} -+ -+static u8 rb91x_nand_read_byte(struct mtd_info *mtd) -+{ -+ struct rb91x_nand_info *rbni = mtd_to_rbinfo(mtd); -+ u8 data = 0xff; -+ -+ rb91x_nand_read(rbni, &data, 1); -+ -+ return data; -+} -+ -+static void rb91x_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len) -+{ -+ struct rb91x_nand_info *rbni = mtd_to_rbinfo(mtd); -+ -+ rb91x_nand_read(rbni, buf, len); -+} -+ -+static void rb91x_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len) -+{ -+ struct rb91x_nand_info *rbni = mtd_to_rbinfo(mtd); -+ -+ rb91x_nand_write(rbni, buf, len); -+} -+ -+static int rb91x_nand_gpio_init(struct rb91x_nand_info *info) -+{ -+ int ret; -+ -+ /* -+ * Ensure that the LATCH is disabled before initializing -+ * control lines. -+ */ -+ ret = devm_gpio_request_one(info->dev, info->gpio_nle, -+ GPIOF_OUT_INIT_HIGH, "LATCH enable"); -+ if (ret) -+ return ret; -+ -+ ret = devm_gpio_request_one(info->dev, info->gpio_nce, -+ GPIOF_OUT_INIT_HIGH, "NAND nCE"); -+ if (ret) -+ return ret; -+ -+ ret = devm_gpio_request_one(info->dev, info->gpio_nrw, -+ GPIOF_OUT_INIT_HIGH, "NAND nRW"); -+ if (ret) -+ return ret; -+ -+ ret = devm_gpio_request_one(info->dev, info->gpio_cle, -+ GPIOF_OUT_INIT_LOW, "NAND CLE"); -+ if (ret) -+ return ret; -+ -+ ret = devm_gpio_request_one(info->dev, info->gpio_ale, -+ GPIOF_OUT_INIT_LOW, "NAND ALE"); -+ if (ret) -+ return ret; -+ -+ ret = devm_gpio_request_one(info->dev, info->gpio_read, -+ GPIOF_OUT_INIT_LOW, "NAND READ"); -+ if (ret) -+ return ret; -+ -+ ret = devm_gpio_request_one(info->dev, info->gpio_rdy, -+ GPIOF_IN, "NAND RDY"); -+ return ret; -+} -+ -+static int rb91x_nand_probe(struct platform_device *pdev) -+{ -+ struct rb91x_nand_info *rbni; -+ struct rb91x_nand_platform_data *pdata; -+ struct mtd_info *mtd; -+ int ret; -+ -+ pr_info(DRV_DESC "\n"); -+ -+ pdata = dev_get_platdata(&pdev->dev); -+ if (!pdata) -+ return -EINVAL; -+ -+ rbni = devm_kzalloc(&pdev->dev, sizeof(*rbni), GFP_KERNEL); -+ if (!rbni) -+ return -ENOMEM; -+ -+ rbni->dev = &pdev->dev; -+ rbni->gpio_nce = pdata->gpio_nce; -+ rbni->gpio_ale = pdata->gpio_ale; -+ rbni->gpio_cle = pdata->gpio_cle; -+ rbni->gpio_read = pdata->gpio_read; -+ rbni->gpio_nrw = pdata->gpio_nrw; -+ rbni->gpio_rdy = pdata->gpio_rdy; -+ rbni->gpio_nle = pdata->gpio_nle; -+ -+ rbni->chip.priv = &rbni; -+ mtd = rbinfo_to_mtd(rbni); -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ mtd->priv = &rbni->chip; -+#endif -+ mtd->owner = THIS_MODULE; -+ -+ rbni->chip.cmd_ctrl = rb91x_nand_cmd_ctrl; -+ rbni->chip.dev_ready = rb91x_nand_dev_ready; -+ rbni->chip.read_byte = rb91x_nand_read_byte; -+ rbni->chip.write_buf = rb91x_nand_write_buf; -+ rbni->chip.read_buf = rb91x_nand_read_buf; -+ -+ rbni->chip.chip_delay = 25; -+ rbni->chip.ecc.mode = NAND_ECC_SOFT; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) -+ rbni->chip.ecc.algo = NAND_ECC_HAMMING; -+#endif -+ rbni->chip.options = NAND_NO_SUBPAGE_WRITE; -+ -+ platform_set_drvdata(pdev, rbni); -+ -+ ret = rb91x_nand_gpio_init(rbni); -+ if (ret) -+ return ret; -+ -+ ret = nand_scan_ident(mtd, 1, NULL); -+ if (ret) -+ return ret; -+ -+ if (mtd->writesize == 512) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) -+ rbni->chip.ecc.layout = &rb91x_nand_ecclayout; -+#else -+ mtd_set_ooblayout(mtd, &rb91x_nand_ecclayout_ops); -+#endif -+ -+ ret = nand_scan_tail(mtd); -+ if (ret) -+ return ret; -+ -+ ret = mtd_device_register(mtd, rb91x_nand_partitions, -+ ARRAY_SIZE(rb91x_nand_partitions)); -+ if (ret) -+ goto err_release_nand; -+ -+ return 0; -+ -+err_release_nand: -+ nand_release(&rbni->chip); -+ return ret; -+} -+ -+static int rb91x_nand_remove(struct platform_device *pdev) -+{ -+ struct rb91x_nand_info *info = platform_get_drvdata(pdev); -+ -+ nand_release(&info->chip); -+ -+ return 0; -+} -+ -+static struct platform_driver rb91x_nand_driver = { -+ .probe = rb91x_nand_probe, -+ .remove = rb91x_nand_remove, -+ .driver = { -+ .name = RB91X_NAND_DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+module_platform_driver(rb91x_nand_driver); -+ -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -diff --git a/target/linux/ar71xx/files/drivers/mtd/tplinkpart.c b/target/linux/ar71xx/files/drivers/mtd/tplinkpart.c -new file mode 100644 -index 0000000000..1b94163b83 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/mtd/tplinkpart.c -@@ -0,0 +1,235 @@ -+/* -+ * Copyright (C) 2011 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#define TPLINK_NUM_PARTS 5 -+#define TPLINK_HEADER_V1 0x01000000 -+#define TPLINK_HEADER_V2 0x02000000 -+#define MD5SUM_LEN 16 -+ -+#define TPLINK_ART_LEN 0x10000 -+#define TPLINK_KERNEL_OFFS 0x20000 -+#define TPLINK_64K_KERNEL_OFFS 0x10000 -+ -+struct tplink_fw_header { -+ uint32_t version; /* header version */ -+ char vendor_name[24]; -+ char fw_version[36]; -+ uint32_t hw_id; /* hardware id */ -+ uint32_t hw_rev; /* hardware revision */ -+ uint32_t unk1; -+ uint8_t md5sum1[MD5SUM_LEN]; -+ uint32_t unk2; -+ uint8_t md5sum2[MD5SUM_LEN]; -+ uint32_t unk3; -+ uint32_t kernel_la; /* kernel load address */ -+ uint32_t kernel_ep; /* kernel entry point */ -+ uint32_t fw_length; /* total length of the firmware */ -+ uint32_t kernel_ofs; /* kernel data offset */ -+ uint32_t kernel_len; /* kernel data length */ -+ uint32_t rootfs_ofs; /* rootfs data offset */ -+ uint32_t rootfs_len; /* rootfs data length */ -+ uint32_t boot_ofs; /* bootloader data offset */ -+ uint32_t boot_len; /* bootloader data length */ -+ uint8_t pad[360]; -+} __attribute__ ((packed)); -+ -+static struct tplink_fw_header * -+tplink_read_header(struct mtd_info *mtd, size_t offset) -+{ -+ struct tplink_fw_header *header; -+ size_t header_len; -+ size_t retlen; -+ int ret; -+ u32 t; -+ -+ header = vmalloc(sizeof(*header)); -+ if (!header) -+ goto err; -+ -+ header_len = sizeof(struct tplink_fw_header); -+ ret = mtd_read(mtd, offset, header_len, &retlen, -+ (unsigned char *) header); -+ if (ret) -+ goto err_free_header; -+ -+ if (retlen != header_len) -+ goto err_free_header; -+ -+ /* sanity checks */ -+ t = be32_to_cpu(header->version); -+ if ((t != TPLINK_HEADER_V1) && (t != TPLINK_HEADER_V2)) -+ goto err_free_header; -+ -+ t = be32_to_cpu(header->kernel_ofs); -+ if (t != header_len) -+ goto err_free_header; -+ -+ return header; -+ -+err_free_header: -+ vfree(header); -+err: -+ return NULL; -+} -+ -+static int tplink_check_rootfs_magic(struct mtd_info *mtd, size_t offset) -+{ -+ u32 magic; -+ size_t retlen; -+ int ret; -+ -+ ret = mtd_read(mtd, offset, sizeof(magic), &retlen, -+ (unsigned char *) &magic); -+ if (ret) -+ return ret; -+ -+ if (retlen != sizeof(magic)) -+ return -EIO; -+ -+ if (le32_to_cpu(magic) != SQUASHFS_MAGIC && -+ magic != 0x19852003) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int tplink_parse_partitions_offset(struct mtd_info *master, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) -+ struct mtd_partition **pparts, -+#else -+ const struct mtd_partition **pparts, -+#endif -+ struct mtd_part_parser_data *data, -+ size_t offset) -+{ -+ struct mtd_partition *parts; -+ struct tplink_fw_header *header; -+ int nr_parts; -+ size_t art_offset; -+ size_t rootfs_offset; -+ size_t squashfs_offset; -+ int ret; -+ -+ nr_parts = TPLINK_NUM_PARTS; -+ parts = kzalloc(nr_parts * sizeof(struct mtd_partition), GFP_KERNEL); -+ if (!parts) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ header = tplink_read_header(master, offset); -+ if (!header) { -+ pr_notice("%s: no TP-Link header found\n", master->name); -+ ret = -ENODEV; -+ goto err_free_parts; -+ } -+ -+ squashfs_offset = offset + sizeof(struct tplink_fw_header) + -+ be32_to_cpu(header->kernel_len); -+ -+ ret = tplink_check_rootfs_magic(master, squashfs_offset); -+ if (ret == 0) -+ rootfs_offset = squashfs_offset; -+ else -+ rootfs_offset = offset + be32_to_cpu(header->rootfs_ofs); -+ -+ art_offset = master->size - TPLINK_ART_LEN; -+ -+ parts[0].name = "u-boot"; -+ parts[0].offset = 0; -+ parts[0].size = offset; -+ parts[0].mask_flags = MTD_WRITEABLE; -+ -+ parts[1].name = "kernel"; -+ parts[1].offset = offset; -+ parts[1].size = rootfs_offset - offset; -+ -+ parts[2].name = "rootfs"; -+ parts[2].offset = rootfs_offset; -+ parts[2].size = art_offset - rootfs_offset; -+ -+ parts[3].name = "art"; -+ parts[3].offset = art_offset; -+ parts[3].size = TPLINK_ART_LEN; -+ parts[3].mask_flags = MTD_WRITEABLE; -+ -+ parts[4].name = "firmware"; -+ parts[4].offset = offset; -+ parts[4].size = art_offset - offset; -+ -+ vfree(header); -+ -+ *pparts = parts; -+ return nr_parts; -+ -+err_free_parts: -+ kfree(parts); -+err: -+ *pparts = NULL; -+ return ret; -+} -+ -+static int tplink_parse_partitions(struct mtd_info *master, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) -+ struct mtd_partition **pparts, -+#else -+ const struct mtd_partition **pparts, -+#endif -+ struct mtd_part_parser_data *data) -+{ -+ return tplink_parse_partitions_offset(master, pparts, data, -+ TPLINK_KERNEL_OFFS); -+} -+ -+static int tplink_parse_64k_partitions(struct mtd_info *master, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) -+ struct mtd_partition **pparts, -+#else -+ const struct mtd_partition **pparts, -+#endif -+ struct mtd_part_parser_data *data) -+{ -+ return tplink_parse_partitions_offset(master, pparts, data, -+ TPLINK_64K_KERNEL_OFFS); -+} -+ -+static struct mtd_part_parser tplink_parser = { -+ .owner = THIS_MODULE, -+ .parse_fn = tplink_parse_partitions, -+ .name = "tp-link", -+}; -+ -+static struct mtd_part_parser tplink_64k_parser = { -+ .owner = THIS_MODULE, -+ .parse_fn = tplink_parse_64k_partitions, -+ .name = "tp-link-64k", -+}; -+ -+static int __init tplink_parser_init(void) -+{ -+ register_mtd_parser(&tplink_parser); -+ register_mtd_parser(&tplink_64k_parser); -+ -+ return 0; -+} -+ -+module_init(tplink_parser_init); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Gabor Juhos "); -diff --git a/target/linux/ar71xx/files/drivers/net/dsa/mv88e6063.c b/target/linux/ar71xx/files/drivers/net/dsa/mv88e6063.c -new file mode 100644 -index 0000000000..71ecd61c80 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/net/dsa/mv88e6063.c -@@ -0,0 +1,307 @@ -+/* -+ * net/dsa/mv88e6063.c - Driver for Marvell 88e6063 switch chips -+ * Copyright (c) 2009 Gabor Juhos -+ * -+ * This driver was base on: net/dsa/mv88e6060.c -+ * net/dsa/mv88e6063.c - Driver for Marvell 88e6060 switch chips -+ * Copyright (c) 2008-2009 Marvell Semiconductor -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define REG_BASE 0x10 -+#define REG_PHY(p) (REG_BASE + (p)) -+#define REG_PORT(p) (REG_BASE + 8 + (p)) -+#define REG_GLOBAL (REG_BASE + 0x0f) -+#define NUM_PORTS 7 -+ -+static int reg_read(struct dsa_switch *ds, int addr, int reg) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) -+ struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev); -+ return mdiobus_read(bus, addr, reg); -+#else -+ struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->dev); -+ return mdiobus_read(bus, addr, reg); -+#endif -+} -+ -+#define REG_READ(addr, reg) \ -+ ({ \ -+ int __ret; \ -+ \ -+ __ret = reg_read(ds, addr, reg); \ -+ if (__ret < 0) \ -+ return __ret; \ -+ __ret; \ -+ }) -+ -+ -+static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) -+ struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev); -+ return mdiobus_write(bus, addr, reg, val); -+#else -+ struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->dev); -+ return mdiobus_write(bus, addr, reg, val); -+#endif -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0) -+static enum dsa_tag_protocol mv88e6063_get_tag_protocol(struct dsa_switch *ds) -+{ -+ return DSA_TAG_PROTO_TRAILER; -+} -+#endif -+ -+#define REG_WRITE(addr, reg, val) \ -+ ({ \ -+ int __ret; \ -+ \ -+ __ret = reg_write(ds, addr, reg, val); \ -+ if (__ret < 0) \ -+ return __ret; \ -+ }) -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) -+static char *mv88e6063_drv_probe(struct device *host_dev, int sw_addr) -+#else -+static const char *mv88e6063_drv_probe(struct device *dsa_dev, -+ struct device *host_dev, int sw_addr, -+ void **_priv) -+#endif -+{ -+ struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev); -+ int ret; -+ -+ if (!bus) -+ return NULL; -+ -+ ret = mdiobus_read(bus, REG_PORT(0), 0x03); -+ if (ret >= 0) { -+ ret &= 0xfff0; -+ if (ret == 0x1530) -+ return "Marvell 88E6063"; -+ } -+ -+ return NULL; -+} -+ -+static int mv88e6063_switch_reset(struct dsa_switch *ds) -+{ -+ int i; -+ int ret; -+ -+ /* -+ * Set all ports to the disabled state. -+ */ -+ for (i = 0; i < NUM_PORTS; i++) { -+ ret = REG_READ(REG_PORT(i), 0x04); -+ REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc); -+ } -+ -+ /* -+ * Wait for transmit queues to drain. -+ */ -+ msleep(2); -+ -+ /* -+ * Reset the switch. -+ */ -+ REG_WRITE(REG_GLOBAL, 0x0a, 0xa130); -+ -+ /* -+ * Wait up to one second for reset to complete. -+ */ -+ for (i = 0; i < 1000; i++) { -+ ret = REG_READ(REG_GLOBAL, 0x00); -+ if ((ret & 0x8000) == 0x0000) -+ break; -+ -+ msleep(1); -+ } -+ if (i == 1000) -+ return -ETIMEDOUT; -+ -+ return 0; -+} -+ -+static int mv88e6063_setup_global(struct dsa_switch *ds) -+{ -+ /* -+ * Disable discarding of frames with excessive collisions, -+ * set the maximum frame size to 1536 bytes, and mask all -+ * interrupt sources. -+ */ -+ REG_WRITE(REG_GLOBAL, 0x04, 0x0800); -+ -+ /* -+ * Enable automatic address learning, set the address -+ * database size to 1024 entries, and set the default aging -+ * time to 5 minutes. -+ */ -+ REG_WRITE(REG_GLOBAL, 0x0a, 0x2130); -+ -+ return 0; -+} -+ -+static int mv88e6063_setup_port(struct dsa_switch *ds, int p) -+{ -+ int addr = REG_PORT(p); -+ -+ /* -+ * Do not force flow control, disable Ingress and Egress -+ * Header tagging, disable VLAN tunneling, and set the port -+ * state to Forwarding. Additionally, if this is the CPU -+ * port, enable Ingress and Egress Trailer tagging mode. -+ */ -+ REG_WRITE(addr, 0x04, dsa_is_cpu_port(ds, p) ? 0x4103 : 0x0003); -+ -+ /* -+ * Port based VLAN map: give each port its own address -+ * database, allow the CPU port to talk to each of the 'real' -+ * ports, and allow each of the 'real' ports to only talk to -+ * the CPU port. -+ */ -+ REG_WRITE(addr, 0x06, -+ ((p & 0xf) << 12) | -+ (dsa_is_cpu_port(ds, p) ? -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) -+ ds->phys_port_mask : -+#else -+ ds->enabled_port_mask : -+#endif -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) -+ (1 << ds->dst->cpu_port))); -+#else -+ (1 << ds->dst->cpu_dp->index))); -+#endif -+ -+ /* -+ * Port Association Vector: when learning source addresses -+ * of packets, add the address to the address database using -+ * a port bitmap that has only the bit for this port set and -+ * the other bits clear. -+ */ -+ REG_WRITE(addr, 0x0b, 1 << p); -+ -+ return 0; -+} -+ -+static int mv88e6063_setup(struct dsa_switch *ds) -+{ -+ int i; -+ int ret; -+ -+ ret = mv88e6063_switch_reset(ds); -+ if (ret < 0) -+ return ret; -+ -+ /* @@@ initialise atu */ -+ -+ ret = mv88e6063_setup_global(ds); -+ if (ret < 0) -+ return ret; -+ -+ for (i = 0; i < NUM_PORTS; i++) { -+ ret = mv88e6063_setup_port(ds, i); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int mv88e6063_set_addr(struct dsa_switch *ds, u8 *addr) -+{ -+ REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]); -+ REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]); -+ REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]); -+ -+ return 0; -+} -+ -+static int mv88e6063_port_to_phy_addr(int port) -+{ -+ if (port >= 0 && port <= NUM_PORTS) -+ return REG_PHY(port); -+ return -1; -+} -+ -+static int mv88e6063_phy_read(struct dsa_switch *ds, int port, int regnum) -+{ -+ int addr; -+ -+ addr = mv88e6063_port_to_phy_addr(port); -+ if (addr == -1) -+ return 0xffff; -+ -+ return reg_read(ds, addr, regnum); -+} -+ -+static int -+mv88e6063_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) -+{ -+ int addr; -+ -+ addr = mv88e6063_port_to_phy_addr(port); -+ if (addr == -1) -+ return 0xffff; -+ -+ return reg_write(ds, addr, regnum, val); -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0) -+static struct dsa_switch_driver mv88e6063_switch_ops = { -+#else -+static struct dsa_switch_ops mv88e6063_switch_ops = { -+#endif -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0) -+ .tag_protocol = htons(ETH_P_TRAILER), -+#else -+ .get_tag_protocol = mv88e6063_get_tag_protocol, -+#endif -+ .probe = mv88e6063_drv_probe, -+ .setup = mv88e6063_setup, -+ .set_addr = mv88e6063_set_addr, -+ .phy_read = mv88e6063_phy_read, -+ .phy_write = mv88e6063_phy_write, -+}; -+ -+#if LINUX_VERSION_CODE > KERNEL_VERSION(4,13,0) -+static struct dsa_switch_driver mv88e6063_switch_drv = { -+ .ops = &mv88e6063_switch_ops, -+}; -+#endif -+ -+static int __init mv88e6063_init(void) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) -+ register_switch_driver(&mv88e6063_switch_ops); -+#else -+ register_switch_driver(&mv88e6063_switch_drv); -+#endif -+ return 0; -+} -+module_init(mv88e6063_init); -+ -+static void __exit mv88e6063_cleanup(void) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) -+ unregister_switch_driver(&mv88e6063_switch_ops); -+#else -+ unregister_switch_driver(&mv88e6063_switch_drv); -+#endif -+} -+module_exit(mv88e6063_cleanup); -diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Kconfig b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Kconfig -new file mode 100644 -index 0000000000..42d544f731 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Kconfig -@@ -0,0 +1,33 @@ -+config AG71XX -+ tristate "Atheros AR7XXX/AR9XXX built-in ethernet mac support" -+ depends on ATH79 -+ select PHYLIB -+ help -+ If you wish to compile a kernel for AR7XXX/91XXX and enable -+ ethernet support, then you should always answer Y to this. -+ -+if AG71XX -+ -+config AG71XX_DEBUG -+ bool "Atheros AR71xx built-in ethernet driver debugging" -+ default n -+ help -+ Atheros AR71xx built-in ethernet driver debugging messages. -+ -+config AG71XX_DEBUG_FS -+ bool "Atheros AR71xx built-in ethernet driver debugfs support" -+ depends on DEBUG_FS -+ default n -+ help -+ Say Y, if you need access to various statistics provided by -+ the ag71xx driver. -+ -+config AG71XX_AR8216_SUPPORT -+ bool "special support for the Atheros AR8216 switch" -+ default n -+ default y if ATH79_MACH_WNR2000 || ATH79_MACH_MZK_W04NU -+ help -+ Say 'y' here if you want to enable special support for the -+ Atheros AR8216 switch found on some boards. -+ -+endif -diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Makefile b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Makefile -new file mode 100644 -index 0000000000..b3ec4084c8 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Makefile -@@ -0,0 +1,15 @@ -+# -+# Makefile for the Atheros AR71xx built-in ethernet macs -+# -+ -+ag71xx-y += ag71xx_main.o -+ag71xx-y += ag71xx_ethtool.o -+ag71xx-y += ag71xx_phy.o -+ag71xx-y += ag71xx_mdio.o -+ag71xx-y += ag71xx_ar7240.o -+ -+ag71xx-$(CONFIG_AG71XX_DEBUG_FS) += ag71xx_debugfs.o -+ag71xx-$(CONFIG_AG71XX_AR8216_SUPPORT) += ag71xx_ar8216.o -+ -+obj-$(CONFIG_AG71XX) += ag71xx.o -+ -diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h -new file mode 100644 -index 0000000000..2d9a865043 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h -@@ -0,0 +1,508 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef __AG71XX_H -+#define __AG71XX_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+#include -+ -+#define AG71XX_DRV_NAME "ag71xx" -+#define AG71XX_DRV_VERSION "0.5.35" -+ -+/* -+ * For our NAPI weight bigger does *NOT* mean better - it means more -+ * D-cache misses and lots more wasted cycles than we'll ever -+ * possibly gain from saving instructions. -+ */ -+#define AG71XX_NAPI_WEIGHT 32 -+#define AG71XX_OOM_REFILL (1 + HZ/10) -+ -+#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE) -+#define AG71XX_INT_TX (AG71XX_INT_TX_PS) -+#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF) -+ -+#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX) -+#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL) -+ -+#define AG71XX_TX_MTU_LEN 1540 -+ -+#define AG71XX_TX_RING_SPLIT 512 -+#define AG71XX_TX_RING_DS_PER_PKT DIV_ROUND_UP(AG71XX_TX_MTU_LEN, \ -+ AG71XX_TX_RING_SPLIT) -+#define AG71XX_TX_RING_SIZE_DEFAULT 128 -+#define AG71XX_RX_RING_SIZE_DEFAULT 256 -+ -+#define AG71XX_TX_RING_SIZE_MAX 128 -+#define AG71XX_RX_RING_SIZE_MAX 256 -+ -+#define QCA955X_SGMII_LINK_WAR_MAX_TRY 10 -+ -+#ifdef CONFIG_AG71XX_DEBUG -+#define DBG(fmt, args...) pr_debug(fmt, ## args) -+#else -+#define DBG(fmt, args...) do {} while (0) -+#endif -+ -+#define ag71xx_assert(_cond) \ -+do { \ -+ if (_cond) \ -+ break; \ -+ printk("%s,%d: assertion failed\n", __FILE__, __LINE__); \ -+ BUG(); \ -+} while (0) -+ -+struct ag71xx_desc { -+ u32 data; -+ u32 ctrl; -+#define DESC_EMPTY BIT(31) -+#define DESC_MORE BIT(24) -+#define DESC_PKTLEN_M 0xfff -+ u32 next; -+ u32 pad; -+} __attribute__((aligned(4))); -+ -+#define AG71XX_DESC_SIZE roundup(sizeof(struct ag71xx_desc), \ -+ L1_CACHE_BYTES) -+ -+struct ag71xx_buf { -+ union { -+ struct sk_buff *skb; -+ void *rx_buf; -+ }; -+ union { -+ dma_addr_t dma_addr; -+ unsigned int len; -+ }; -+}; -+ -+struct ag71xx_ring { -+ struct ag71xx_buf *buf; -+ u8 *descs_cpu; -+ dma_addr_t descs_dma; -+ u16 desc_split; -+ u16 order; -+ unsigned int curr; -+ unsigned int dirty; -+}; -+ -+struct ag71xx_mdio { -+ struct mii_bus *mii_bus; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) -+ int mii_irq[PHY_MAX_ADDR]; -+#endif -+ void __iomem *mdio_base; -+ struct ag71xx_mdio_platform_data *pdata; -+}; -+ -+struct ag71xx_int_stats { -+ unsigned long rx_pr; -+ unsigned long rx_be; -+ unsigned long rx_of; -+ unsigned long tx_ps; -+ unsigned long tx_be; -+ unsigned long tx_ur; -+ unsigned long total; -+}; -+ -+struct ag71xx_napi_stats { -+ unsigned long napi_calls; -+ unsigned long rx_count; -+ unsigned long rx_packets; -+ unsigned long rx_packets_max; -+ unsigned long tx_count; -+ unsigned long tx_packets; -+ unsigned long tx_packets_max; -+ -+ unsigned long rx[AG71XX_NAPI_WEIGHT + 1]; -+ unsigned long tx[AG71XX_NAPI_WEIGHT + 1]; -+}; -+ -+struct ag71xx_debug { -+ struct dentry *debugfs_dir; -+ -+ struct ag71xx_int_stats int_stats; -+ struct ag71xx_napi_stats napi_stats; -+}; -+ -+struct ag71xx { -+ /* -+ * Critical data related to the per-packet data path are clustered -+ * early in this structure to help improve the D-cache footprint. -+ */ -+ struct ag71xx_ring rx_ring ____cacheline_aligned; -+ struct ag71xx_ring tx_ring ____cacheline_aligned; -+ -+ unsigned int max_frame_len; -+ unsigned int desc_pktlen_mask; -+ unsigned int rx_buf_size; -+ -+ struct net_device *dev; -+ struct platform_device *pdev; -+ spinlock_t lock; -+ struct napi_struct napi; -+ u32 msg_enable; -+ -+ /* -+ * From this point onwards we're not looking at per-packet fields. -+ */ -+ void __iomem *mac_base; -+ -+ struct ag71xx_desc *stop_desc; -+ dma_addr_t stop_desc_dma; -+ -+ struct mii_bus *mii_bus; -+ struct phy_device *phy_dev; -+ void *phy_priv; -+ -+ unsigned int link; -+ unsigned int speed; -+ int duplex; -+ -+ struct delayed_work restart_work; -+ struct delayed_work link_work; -+ struct timer_list oom_timer; -+ -+#ifdef CONFIG_AG71XX_DEBUG_FS -+ struct ag71xx_debug debug; -+#endif -+}; -+ -+extern struct ethtool_ops ag71xx_ethtool_ops; -+void ag71xx_link_adjust(struct ag71xx *ag); -+ -+int ag71xx_mdio_driver_init(void) __init; -+void ag71xx_mdio_driver_exit(void); -+ -+int ag71xx_phy_connect(struct ag71xx *ag); -+void ag71xx_phy_disconnect(struct ag71xx *ag); -+void ag71xx_phy_start(struct ag71xx *ag); -+void ag71xx_phy_stop(struct ag71xx *ag); -+ -+static inline struct ag71xx_platform_data *ag71xx_get_pdata(struct ag71xx *ag) -+{ -+ return ag->pdev->dev.platform_data; -+} -+ -+static inline int ag71xx_desc_empty(struct ag71xx_desc *desc) -+{ -+ return (desc->ctrl & DESC_EMPTY) != 0; -+} -+ -+static inline struct ag71xx_desc * -+ag71xx_ring_desc(struct ag71xx_ring *ring, int idx) -+{ -+ return (struct ag71xx_desc *) &ring->descs_cpu[idx * AG71XX_DESC_SIZE]; -+} -+ -+static inline int -+ag71xx_ring_size_order(int size) -+{ -+ return fls(size - 1); -+} -+ -+/* Register offsets */ -+#define AG71XX_REG_MAC_CFG1 0x0000 -+#define AG71XX_REG_MAC_CFG2 0x0004 -+#define AG71XX_REG_MAC_IPG 0x0008 -+#define AG71XX_REG_MAC_HDX 0x000c -+#define AG71XX_REG_MAC_MFL 0x0010 -+#define AG71XX_REG_MII_CFG 0x0020 -+#define AG71XX_REG_MII_CMD 0x0024 -+#define AG71XX_REG_MII_ADDR 0x0028 -+#define AG71XX_REG_MII_CTRL 0x002c -+#define AG71XX_REG_MII_STATUS 0x0030 -+#define AG71XX_REG_MII_IND 0x0034 -+#define AG71XX_REG_MAC_IFCTL 0x0038 -+#define AG71XX_REG_MAC_ADDR1 0x0040 -+#define AG71XX_REG_MAC_ADDR2 0x0044 -+#define AG71XX_REG_FIFO_CFG0 0x0048 -+#define AG71XX_REG_FIFO_CFG1 0x004c -+#define AG71XX_REG_FIFO_CFG2 0x0050 -+#define AG71XX_REG_FIFO_CFG3 0x0054 -+#define AG71XX_REG_FIFO_CFG4 0x0058 -+#define AG71XX_REG_FIFO_CFG5 0x005c -+#define AG71XX_REG_FIFO_RAM0 0x0060 -+#define AG71XX_REG_FIFO_RAM1 0x0064 -+#define AG71XX_REG_FIFO_RAM2 0x0068 -+#define AG71XX_REG_FIFO_RAM3 0x006c -+#define AG71XX_REG_FIFO_RAM4 0x0070 -+#define AG71XX_REG_FIFO_RAM5 0x0074 -+#define AG71XX_REG_FIFO_RAM6 0x0078 -+#define AG71XX_REG_FIFO_RAM7 0x007c -+ -+#define AG71XX_REG_TX_CTRL 0x0180 -+#define AG71XX_REG_TX_DESC 0x0184 -+#define AG71XX_REG_TX_STATUS 0x0188 -+#define AG71XX_REG_RX_CTRL 0x018c -+#define AG71XX_REG_RX_DESC 0x0190 -+#define AG71XX_REG_RX_STATUS 0x0194 -+#define AG71XX_REG_INT_ENABLE 0x0198 -+#define AG71XX_REG_INT_STATUS 0x019c -+ -+#define AG71XX_REG_FIFO_DEPTH 0x01a8 -+#define AG71XX_REG_RX_SM 0x01b0 -+#define AG71XX_REG_TX_SM 0x01b4 -+ -+#define MAC_CFG1_TXE BIT(0) /* Tx Enable */ -+#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */ -+#define MAC_CFG1_RXE BIT(2) /* Rx Enable */ -+#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */ -+#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */ -+#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */ -+#define MAC_CFG1_LB BIT(8) /* Loopback mode */ -+#define MAC_CFG1_SR BIT(31) /* Soft Reset */ -+ -+#define MAC_CFG2_FDX BIT(0) -+#define MAC_CFG2_CRC_EN BIT(1) -+#define MAC_CFG2_PAD_CRC_EN BIT(2) -+#define MAC_CFG2_LEN_CHECK BIT(4) -+#define MAC_CFG2_HUGE_FRAME_EN BIT(5) -+#define MAC_CFG2_IF_1000 BIT(9) -+#define MAC_CFG2_IF_10_100 BIT(8) -+ -+#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */ -+#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */ -+#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */ -+#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */ -+#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */ -+#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \ -+ | FIFO_CFG0_TXS | FIFO_CFG0_TXF) -+ -+#define FIFO_CFG0_ENABLE_SHIFT 8 -+ -+#define FIFO_CFG4_DE BIT(0) /* Drop Event */ -+#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */ -+#define FIFO_CFG4_FC BIT(2) /* False Carrier */ -+#define FIFO_CFG4_CE BIT(3) /* Code Error */ -+#define FIFO_CFG4_CR BIT(4) /* CRC error */ -+#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */ -+#define FIFO_CFG4_LO BIT(6) /* Length out of range */ -+#define FIFO_CFG4_OK BIT(7) /* Packet is OK */ -+#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */ -+#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */ -+#define FIFO_CFG4_DR BIT(10) /* Dribble */ -+#define FIFO_CFG4_LE BIT(11) /* Long Event */ -+#define FIFO_CFG4_CF BIT(12) /* Control Frame */ -+#define FIFO_CFG4_PF BIT(13) /* Pause Frame */ -+#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */ -+#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */ -+#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */ -+#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */ -+ -+#define FIFO_CFG5_DE BIT(0) /* Drop Event */ -+#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */ -+#define FIFO_CFG5_FC BIT(2) /* False Carrier */ -+#define FIFO_CFG5_CE BIT(3) /* Code Error */ -+#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */ -+#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */ -+#define FIFO_CFG5_OK BIT(6) /* Packet is OK */ -+#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */ -+#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */ -+#define FIFO_CFG5_DR BIT(9) /* Dribble */ -+#define FIFO_CFG5_CF BIT(10) /* Control Frame */ -+#define FIFO_CFG5_PF BIT(11) /* Pause Frame */ -+#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */ -+#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */ -+#define FIFO_CFG5_LE BIT(14) /* Long Event */ -+#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */ -+#define FIFO_CFG5_16 BIT(16) /* unknown */ -+#define FIFO_CFG5_17 BIT(17) /* unknown */ -+#define FIFO_CFG5_SF BIT(18) /* Short Frame */ -+#define FIFO_CFG5_BM BIT(19) /* Byte Mode */ -+ -+#define AG71XX_INT_TX_PS BIT(0) -+#define AG71XX_INT_TX_UR BIT(1) -+#define AG71XX_INT_TX_BE BIT(3) -+#define AG71XX_INT_RX_PR BIT(4) -+#define AG71XX_INT_RX_OF BIT(6) -+#define AG71XX_INT_RX_BE BIT(7) -+ -+#define MAC_IFCTL_SPEED BIT(16) -+ -+#define MII_CFG_CLK_DIV_4 0 -+#define MII_CFG_CLK_DIV_6 2 -+#define MII_CFG_CLK_DIV_8 3 -+#define MII_CFG_CLK_DIV_10 4 -+#define MII_CFG_CLK_DIV_14 5 -+#define MII_CFG_CLK_DIV_20 6 -+#define MII_CFG_CLK_DIV_28 7 -+#define MII_CFG_CLK_DIV_34 8 -+#define MII_CFG_CLK_DIV_42 9 -+#define MII_CFG_CLK_DIV_50 10 -+#define MII_CFG_CLK_DIV_58 11 -+#define MII_CFG_CLK_DIV_66 12 -+#define MII_CFG_CLK_DIV_74 13 -+#define MII_CFG_CLK_DIV_82 14 -+#define MII_CFG_CLK_DIV_98 15 -+#define MII_CFG_RESET BIT(31) -+ -+#define MII_CMD_WRITE 0x0 -+#define MII_CMD_READ 0x1 -+#define MII_ADDR_SHIFT 8 -+#define MII_IND_BUSY BIT(0) -+#define MII_IND_INVALID BIT(2) -+ -+#define TX_CTRL_TXE BIT(0) /* Tx Enable */ -+ -+#define TX_STATUS_PS BIT(0) /* Packet Sent */ -+#define TX_STATUS_UR BIT(1) /* Tx Underrun */ -+#define TX_STATUS_BE BIT(3) /* Bus Error */ -+ -+#define RX_CTRL_RXE BIT(0) /* Rx Enable */ -+ -+#define RX_STATUS_PR BIT(0) /* Packet Received */ -+#define RX_STATUS_OF BIT(2) /* Rx Overflow */ -+#define RX_STATUS_BE BIT(3) /* Bus Error */ -+ -+static inline void ag71xx_check_reg_offset(struct ag71xx *ag, unsigned reg) -+{ -+ switch (reg) { -+ case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL: -+ case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_TX_SM: -+ case AG71XX_REG_MII_CFG: -+ break; -+ -+ default: -+ BUG(); -+ } -+} -+ -+static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value) -+{ -+ ag71xx_check_reg_offset(ag, reg); -+ -+ __raw_writel(value, ag->mac_base + reg); -+ /* flush write */ -+ (void) __raw_readl(ag->mac_base + reg); -+} -+ -+static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg) -+{ -+ ag71xx_check_reg_offset(ag, reg); -+ -+ return __raw_readl(ag->mac_base + reg); -+} -+ -+static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask) -+{ -+ void __iomem *r; -+ -+ ag71xx_check_reg_offset(ag, reg); -+ -+ r = ag->mac_base + reg; -+ __raw_writel(__raw_readl(r) | mask, r); -+ /* flush write */ -+ (void)__raw_readl(r); -+} -+ -+static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask) -+{ -+ void __iomem *r; -+ -+ ag71xx_check_reg_offset(ag, reg); -+ -+ r = ag->mac_base + reg; -+ __raw_writel(__raw_readl(r) & ~mask, r); -+ /* flush write */ -+ (void) __raw_readl(r); -+} -+ -+static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints) -+{ -+ ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints); -+} -+ -+static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints) -+{ -+ ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints); -+} -+ -+#ifdef CONFIG_AG71XX_AR8216_SUPPORT -+void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb); -+int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb, -+ int pktlen); -+static inline int ag71xx_has_ar8216(struct ag71xx *ag) -+{ -+ return ag71xx_get_pdata(ag)->has_ar8216; -+} -+#else -+static inline void ag71xx_add_ar8216_header(struct ag71xx *ag, -+ struct sk_buff *skb) -+{ -+} -+ -+static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag, -+ struct sk_buff *skb, -+ int pktlen) -+{ -+ return 0; -+} -+static inline int ag71xx_has_ar8216(struct ag71xx *ag) -+{ -+ return 0; -+} -+#endif -+ -+#ifdef CONFIG_AG71XX_DEBUG_FS -+int ag71xx_debugfs_root_init(void); -+void ag71xx_debugfs_root_exit(void); -+int ag71xx_debugfs_init(struct ag71xx *ag); -+void ag71xx_debugfs_exit(struct ag71xx *ag); -+void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status); -+void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx); -+#else -+static inline int ag71xx_debugfs_root_init(void) { return 0; } -+static inline void ag71xx_debugfs_root_exit(void) {} -+static inline int ag71xx_debugfs_init(struct ag71xx *ag) { return 0; } -+static inline void ag71xx_debugfs_exit(struct ag71xx *ag) {} -+static inline void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, -+ u32 status) {} -+static inline void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, -+ int rx, int tx) {} -+#endif /* CONFIG_AG71XX_DEBUG_FS */ -+ -+void ag71xx_ar7240_start(struct ag71xx *ag); -+void ag71xx_ar7240_stop(struct ag71xx *ag); -+int ag71xx_ar7240_init(struct ag71xx *ag); -+void ag71xx_ar7240_cleanup(struct ag71xx *ag); -+ -+int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg); -+void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val); -+ -+u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr, -+ unsigned reg_addr); -+int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr, -+ unsigned reg_addr, u16 reg_val); -+ -+#endif /* _AG71XX_H */ -diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c -new file mode 100644 -index 0000000000..2859c0dbe1 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c -@@ -0,0 +1,1386 @@ -+/* -+ * Driver for the built-in ethernet switch of the Atheros AR7240 SoC -+ * Copyright (c) 2010 Gabor Juhos -+ * Copyright (c) 2010 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "ag71xx.h" -+ -+#define BITM(_count) (BIT(_count) - 1) -+#define BITS(_shift, _count) (BITM(_count) << _shift) -+ -+#define AR7240_REG_MASK_CTRL 0x00 -+#define AR7240_MASK_CTRL_REVISION_M BITM(8) -+#define AR7240_MASK_CTRL_VERSION_M BITM(8) -+#define AR7240_MASK_CTRL_VERSION_S 8 -+#define AR7240_MASK_CTRL_VERSION_AR7240 0x01 -+#define AR7240_MASK_CTRL_VERSION_AR934X 0x02 -+#define AR7240_MASK_CTRL_SOFT_RESET BIT(31) -+ -+#define AR7240_REG_MAC_ADDR0 0x20 -+#define AR7240_REG_MAC_ADDR1 0x24 -+ -+#define AR7240_REG_FLOOD_MASK 0x2c -+#define AR7240_FLOOD_MASK_BROAD_TO_CPU BIT(26) -+ -+#define AR7240_REG_GLOBAL_CTRL 0x30 -+#define AR7240_GLOBAL_CTRL_MTU_M BITM(11) -+#define AR9340_GLOBAL_CTRL_MTU_M BITM(14) -+ -+#define AR7240_REG_VTU 0x0040 -+#define AR7240_VTU_OP BITM(3) -+#define AR7240_VTU_OP_NOOP 0x0 -+#define AR7240_VTU_OP_FLUSH 0x1 -+#define AR7240_VTU_OP_LOAD 0x2 -+#define AR7240_VTU_OP_PURGE 0x3 -+#define AR7240_VTU_OP_REMOVE_PORT 0x4 -+#define AR7240_VTU_ACTIVE BIT(3) -+#define AR7240_VTU_FULL BIT(4) -+#define AR7240_VTU_PORT BITS(8, 4) -+#define AR7240_VTU_PORT_S 8 -+#define AR7240_VTU_VID BITS(16, 12) -+#define AR7240_VTU_VID_S 16 -+#define AR7240_VTU_PRIO BITS(28, 3) -+#define AR7240_VTU_PRIO_S 28 -+#define AR7240_VTU_PRIO_EN BIT(31) -+ -+#define AR7240_REG_VTU_DATA 0x0044 -+#define AR7240_VTUDATA_MEMBER BITS(0, 10) -+#define AR7240_VTUDATA_VALID BIT(11) -+ -+#define AR7240_REG_ATU 0x50 -+#define AR7240_ATU_FLUSH_ALL 0x1 -+ -+#define AR7240_REG_AT_CTRL 0x5c -+#define AR7240_AT_CTRL_AGE_TIME BITS(0, 15) -+#define AR7240_AT_CTRL_AGE_EN BIT(17) -+#define AR7240_AT_CTRL_LEARN_CHANGE BIT(18) -+#define AR7240_AT_CTRL_RESERVED BIT(19) -+#define AR7240_AT_CTRL_ARP_EN BIT(20) -+ -+#define AR7240_REG_TAG_PRIORITY 0x70 -+ -+#define AR7240_REG_SERVICE_TAG 0x74 -+#define AR7240_SERVICE_TAG_M BITM(16) -+ -+#define AR7240_REG_CPU_PORT 0x78 -+#define AR7240_MIRROR_PORT_S 4 -+#define AR7240_MIRROR_PORT_M BITM(4) -+#define AR7240_CPU_PORT_EN BIT(8) -+ -+#define AR7240_REG_MIB_FUNCTION0 0x80 -+#define AR7240_MIB_TIMER_M BITM(16) -+#define AR7240_MIB_AT_HALF_EN BIT(16) -+#define AR7240_MIB_BUSY BIT(17) -+#define AR7240_MIB_FUNC_S 24 -+#define AR7240_MIB_FUNC_M BITM(3) -+#define AR7240_MIB_FUNC_NO_OP 0x0 -+#define AR7240_MIB_FUNC_FLUSH 0x1 -+#define AR7240_MIB_FUNC_CAPTURE 0x3 -+ -+#define AR7240_REG_MDIO_CTRL 0x98 -+#define AR7240_MDIO_CTRL_DATA_M BITM(16) -+#define AR7240_MDIO_CTRL_REG_ADDR_S 16 -+#define AR7240_MDIO_CTRL_PHY_ADDR_S 21 -+#define AR7240_MDIO_CTRL_CMD_WRITE 0 -+#define AR7240_MDIO_CTRL_CMD_READ BIT(27) -+#define AR7240_MDIO_CTRL_MASTER_EN BIT(30) -+#define AR7240_MDIO_CTRL_BUSY BIT(31) -+ -+#define AR7240_REG_PORT_BASE(_port) (0x100 + (_port) * 0x100) -+ -+#define AR7240_REG_PORT_STATUS(_port) (AR7240_REG_PORT_BASE((_port)) + 0x00) -+#define AR7240_PORT_STATUS_SPEED_S 0 -+#define AR7240_PORT_STATUS_SPEED_M BITM(2) -+#define AR7240_PORT_STATUS_SPEED_10 0 -+#define AR7240_PORT_STATUS_SPEED_100 1 -+#define AR7240_PORT_STATUS_SPEED_1000 2 -+#define AR7240_PORT_STATUS_TXMAC BIT(2) -+#define AR7240_PORT_STATUS_RXMAC BIT(3) -+#define AR7240_PORT_STATUS_TXFLOW BIT(4) -+#define AR7240_PORT_STATUS_RXFLOW BIT(5) -+#define AR7240_PORT_STATUS_DUPLEX BIT(6) -+#define AR7240_PORT_STATUS_LINK_UP BIT(8) -+#define AR7240_PORT_STATUS_LINK_AUTO BIT(9) -+#define AR7240_PORT_STATUS_LINK_PAUSE BIT(10) -+ -+#define AR7240_REG_PORT_CTRL(_port) (AR7240_REG_PORT_BASE((_port)) + 0x04) -+#define AR7240_PORT_CTRL_STATE_M BITM(3) -+#define AR7240_PORT_CTRL_STATE_DISABLED 0 -+#define AR7240_PORT_CTRL_STATE_BLOCK 1 -+#define AR7240_PORT_CTRL_STATE_LISTEN 2 -+#define AR7240_PORT_CTRL_STATE_LEARN 3 -+#define AR7240_PORT_CTRL_STATE_FORWARD 4 -+#define AR7240_PORT_CTRL_LEARN_LOCK BIT(7) -+#define AR7240_PORT_CTRL_VLAN_MODE_S 8 -+#define AR7240_PORT_CTRL_VLAN_MODE_KEEP 0 -+#define AR7240_PORT_CTRL_VLAN_MODE_STRIP 1 -+#define AR7240_PORT_CTRL_VLAN_MODE_ADD 2 -+#define AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG 3 -+#define AR7240_PORT_CTRL_IGMP_SNOOP BIT(10) -+#define AR7240_PORT_CTRL_HEADER BIT(11) -+#define AR7240_PORT_CTRL_MAC_LOOP BIT(12) -+#define AR7240_PORT_CTRL_SINGLE_VLAN BIT(13) -+#define AR7240_PORT_CTRL_LEARN BIT(14) -+#define AR7240_PORT_CTRL_DOUBLE_TAG BIT(15) -+#define AR7240_PORT_CTRL_MIRROR_TX BIT(16) -+#define AR7240_PORT_CTRL_MIRROR_RX BIT(17) -+ -+#define AR7240_REG_PORT_VLAN(_port) (AR7240_REG_PORT_BASE((_port)) + 0x08) -+ -+#define AR7240_PORT_VLAN_DEFAULT_ID_S 0 -+#define AR7240_PORT_VLAN_DEST_PORTS_S 16 -+#define AR7240_PORT_VLAN_MODE_S 30 -+#define AR7240_PORT_VLAN_MODE_PORT_ONLY 0 -+#define AR7240_PORT_VLAN_MODE_PORT_FALLBACK 1 -+#define AR7240_PORT_VLAN_MODE_VLAN_ONLY 2 -+#define AR7240_PORT_VLAN_MODE_SECURE 3 -+ -+ -+#define AR7240_REG_STATS_BASE(_port) (0x20000 + (_port) * 0x100) -+ -+#define AR7240_STATS_RXBROAD 0x00 -+#define AR7240_STATS_RXPAUSE 0x04 -+#define AR7240_STATS_RXMULTI 0x08 -+#define AR7240_STATS_RXFCSERR 0x0c -+#define AR7240_STATS_RXALIGNERR 0x10 -+#define AR7240_STATS_RXRUNT 0x14 -+#define AR7240_STATS_RXFRAGMENT 0x18 -+#define AR7240_STATS_RX64BYTE 0x1c -+#define AR7240_STATS_RX128BYTE 0x20 -+#define AR7240_STATS_RX256BYTE 0x24 -+#define AR7240_STATS_RX512BYTE 0x28 -+#define AR7240_STATS_RX1024BYTE 0x2c -+#define AR7240_STATS_RX1518BYTE 0x30 -+#define AR7240_STATS_RXMAXBYTE 0x34 -+#define AR7240_STATS_RXTOOLONG 0x38 -+#define AR7240_STATS_RXGOODBYTE 0x3c -+#define AR7240_STATS_RXBADBYTE 0x44 -+#define AR7240_STATS_RXOVERFLOW 0x4c -+#define AR7240_STATS_FILTERED 0x50 -+#define AR7240_STATS_TXBROAD 0x54 -+#define AR7240_STATS_TXPAUSE 0x58 -+#define AR7240_STATS_TXMULTI 0x5c -+#define AR7240_STATS_TXUNDERRUN 0x60 -+#define AR7240_STATS_TX64BYTE 0x64 -+#define AR7240_STATS_TX128BYTE 0x68 -+#define AR7240_STATS_TX256BYTE 0x6c -+#define AR7240_STATS_TX512BYTE 0x70 -+#define AR7240_STATS_TX1024BYTE 0x74 -+#define AR7240_STATS_TX1518BYTE 0x78 -+#define AR7240_STATS_TXMAXBYTE 0x7c -+#define AR7240_STATS_TXOVERSIZE 0x80 -+#define AR7240_STATS_TXBYTE 0x84 -+#define AR7240_STATS_TXCOLLISION 0x8c -+#define AR7240_STATS_TXABORTCOL 0x90 -+#define AR7240_STATS_TXMULTICOL 0x94 -+#define AR7240_STATS_TXSINGLECOL 0x98 -+#define AR7240_STATS_TXEXCDEFER 0x9c -+#define AR7240_STATS_TXDEFER 0xa0 -+#define AR7240_STATS_TXLATECOL 0xa4 -+ -+#define AR7240_PORT_CPU 0 -+#define AR7240_NUM_PORTS 6 -+#define AR7240_NUM_PHYS 5 -+ -+#define AR7240_PHY_ID1 0x004d -+#define AR7240_PHY_ID2 0xd041 -+ -+#define AR934X_PHY_ID1 0x004d -+#define AR934X_PHY_ID2 0xd042 -+ -+#define AR7240_MAX_VLANS 16 -+ -+#define AR934X_REG_OPER_MODE0 0x04 -+#define AR934X_OPER_MODE0_MAC_GMII_EN BIT(6) -+#define AR934X_OPER_MODE0_PHY_MII_EN BIT(10) -+ -+#define AR934X_REG_OPER_MODE1 0x08 -+#define AR934X_REG_OPER_MODE1_PHY4_MII_EN BIT(28) -+ -+#define AR934X_REG_FLOOD_MASK 0x2c -+#define AR934X_FLOOD_MASK_MC_DP(_p) BIT(16 + (_p)) -+#define AR934X_FLOOD_MASK_BC_DP(_p) BIT(25 + (_p)) -+ -+#define AR934X_REG_QM_CTRL 0x3c -+#define AR934X_QM_CTRL_ARP_EN BIT(15) -+ -+#define AR934X_REG_AT_CTRL 0x5c -+#define AR934X_AT_CTRL_AGE_TIME BITS(0, 15) -+#define AR934X_AT_CTRL_AGE_EN BIT(17) -+#define AR934X_AT_CTRL_LEARN_CHANGE BIT(18) -+ -+#define AR934X_MIB_ENABLE BIT(30) -+ -+#define AR934X_REG_PORT_BASE(_port) (0x100 + (_port) * 0x100) -+ -+#define AR934X_REG_PORT_VLAN1(_port) (AR934X_REG_PORT_BASE((_port)) + 0x08) -+#define AR934X_PORT_VLAN1_DEFAULT_SVID_S 0 -+#define AR934X_PORT_VLAN1_FORCE_DEFAULT_VID_EN BIT(12) -+#define AR934X_PORT_VLAN1_PORT_TLS_MODE BIT(13) -+#define AR934X_PORT_VLAN1_PORT_VLAN_PROP_EN BIT(14) -+#define AR934X_PORT_VLAN1_PORT_CLONE_EN BIT(15) -+#define AR934X_PORT_VLAN1_DEFAULT_CVID_S 16 -+#define AR934X_PORT_VLAN1_FORCE_PORT_VLAN_EN BIT(28) -+#define AR934X_PORT_VLAN1_ING_PORT_PRI_S 29 -+ -+#define AR934X_REG_PORT_VLAN2(_port) (AR934X_REG_PORT_BASE((_port)) + 0x0c) -+#define AR934X_PORT_VLAN2_PORT_VID_MEM_S 16 -+#define AR934X_PORT_VLAN2_8021Q_MODE_S 30 -+#define AR934X_PORT_VLAN2_8021Q_MODE_PORT_ONLY 0 -+#define AR934X_PORT_VLAN2_8021Q_MODE_PORT_FALLBACK 1 -+#define AR934X_PORT_VLAN2_8021Q_MODE_VLAN_ONLY 2 -+#define AR934X_PORT_VLAN2_8021Q_MODE_SECURE 3 -+ -+#define sw_to_ar7240(_dev) container_of(_dev, struct ar7240sw, swdev) -+ -+struct ar7240sw_port_stat { -+ unsigned long rx_broadcast; -+ unsigned long rx_pause; -+ unsigned long rx_multicast; -+ unsigned long rx_fcs_error; -+ unsigned long rx_align_error; -+ unsigned long rx_runt; -+ unsigned long rx_fragments; -+ unsigned long rx_64byte; -+ unsigned long rx_128byte; -+ unsigned long rx_256byte; -+ unsigned long rx_512byte; -+ unsigned long rx_1024byte; -+ unsigned long rx_1518byte; -+ unsigned long rx_maxbyte; -+ unsigned long rx_toolong; -+ unsigned long rx_good_byte; -+ unsigned long rx_bad_byte; -+ unsigned long rx_overflow; -+ unsigned long filtered; -+ -+ unsigned long tx_broadcast; -+ unsigned long tx_pause; -+ unsigned long tx_multicast; -+ unsigned long tx_underrun; -+ unsigned long tx_64byte; -+ unsigned long tx_128byte; -+ unsigned long tx_256byte; -+ unsigned long tx_512byte; -+ unsigned long tx_1024byte; -+ unsigned long tx_1518byte; -+ unsigned long tx_maxbyte; -+ unsigned long tx_oversize; -+ unsigned long tx_byte; -+ unsigned long tx_collision; -+ unsigned long tx_abortcol; -+ unsigned long tx_multicol; -+ unsigned long tx_singlecol; -+ unsigned long tx_excdefer; -+ unsigned long tx_defer; -+ unsigned long tx_xlatecol; -+}; -+ -+struct ar7240sw { -+ struct mii_bus *mii_bus; -+ struct ag71xx_switch_platform_data *swdata; -+ struct switch_dev swdev; -+ int num_ports; -+ u8 ver; -+ bool vlan; -+ u16 vlan_id[AR7240_MAX_VLANS]; -+ u8 vlan_table[AR7240_MAX_VLANS]; -+ u8 vlan_tagged; -+ u16 pvid[AR7240_NUM_PORTS]; -+ char buf[80]; -+ -+ rwlock_t stats_lock; -+ struct ar7240sw_port_stat port_stats[AR7240_NUM_PORTS]; -+}; -+ -+struct ar7240sw_hw_stat { -+ char string[ETH_GSTRING_LEN]; -+ int sizeof_stat; -+ int reg; -+}; -+ -+static DEFINE_MUTEX(reg_mutex); -+ -+static inline int sw_is_ar7240(struct ar7240sw *as) -+{ -+ return as->ver == AR7240_MASK_CTRL_VERSION_AR7240; -+} -+ -+static inline int sw_is_ar934x(struct ar7240sw *as) -+{ -+ return as->ver == AR7240_MASK_CTRL_VERSION_AR934X; -+} -+ -+static inline u32 ar7240sw_port_mask(struct ar7240sw *as, int port) -+{ -+ return BIT(port); -+} -+ -+static inline u32 ar7240sw_port_mask_all(struct ar7240sw *as) -+{ -+ return BIT(as->swdev.ports) - 1; -+} -+ -+static inline u32 ar7240sw_port_mask_but(struct ar7240sw *as, int port) -+{ -+ return ar7240sw_port_mask_all(as) & ~BIT(port); -+} -+ -+static inline u16 mk_phy_addr(u32 reg) -+{ -+ return 0x17 & ((reg >> 4) | 0x10); -+} -+ -+static inline u16 mk_phy_reg(u32 reg) -+{ -+ return (reg << 1) & 0x1e; -+} -+ -+static inline u16 mk_high_addr(u32 reg) -+{ -+ return (reg >> 7) & 0x1ff; -+} -+ -+static u32 __ar7240sw_reg_read(struct mii_bus *mii, u32 reg) -+{ -+ unsigned long flags; -+ u16 phy_addr; -+ u16 phy_reg; -+ u32 hi, lo; -+ -+ reg = (reg & 0xfffffffc) >> 2; -+ phy_addr = mk_phy_addr(reg); -+ phy_reg = mk_phy_reg(reg); -+ -+ local_irq_save(flags); -+ ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg)); -+ lo = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg); -+ hi = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg + 1); -+ local_irq_restore(flags); -+ -+ return (hi << 16) | lo; -+} -+ -+static void __ar7240sw_reg_write(struct mii_bus *mii, u32 reg, u32 val) -+{ -+ unsigned long flags; -+ u16 phy_addr; -+ u16 phy_reg; -+ -+ reg = (reg & 0xfffffffc) >> 2; -+ phy_addr = mk_phy_addr(reg); -+ phy_reg = mk_phy_reg(reg); -+ -+ local_irq_save(flags); -+ ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg)); -+ ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg + 1, (val >> 16)); -+ ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg, (val & 0xffff)); -+ local_irq_restore(flags); -+} -+ -+static u32 ar7240sw_reg_read(struct mii_bus *mii, u32 reg_addr) -+{ -+ u32 ret; -+ -+ mutex_lock(®_mutex); -+ ret = __ar7240sw_reg_read(mii, reg_addr); -+ mutex_unlock(®_mutex); -+ -+ return ret; -+} -+ -+static void ar7240sw_reg_write(struct mii_bus *mii, u32 reg_addr, u32 reg_val) -+{ -+ mutex_lock(®_mutex); -+ __ar7240sw_reg_write(mii, reg_addr, reg_val); -+ mutex_unlock(®_mutex); -+} -+ -+static u32 ar7240sw_reg_rmw(struct mii_bus *mii, u32 reg, u32 mask, u32 val) -+{ -+ u32 t; -+ -+ mutex_lock(®_mutex); -+ t = __ar7240sw_reg_read(mii, reg); -+ t &= ~mask; -+ t |= val; -+ __ar7240sw_reg_write(mii, reg, t); -+ mutex_unlock(®_mutex); -+ -+ return t; -+} -+ -+static void ar7240sw_reg_set(struct mii_bus *mii, u32 reg, u32 val) -+{ -+ u32 t; -+ -+ mutex_lock(®_mutex); -+ t = __ar7240sw_reg_read(mii, reg); -+ t |= val; -+ __ar7240sw_reg_write(mii, reg, t); -+ mutex_unlock(®_mutex); -+} -+ -+static int __ar7240sw_reg_wait(struct mii_bus *mii, u32 reg, u32 mask, u32 val, -+ unsigned timeout) -+{ -+ int i; -+ -+ for (i = 0; i < timeout; i++) { -+ u32 t; -+ -+ t = __ar7240sw_reg_read(mii, reg); -+ if ((t & mask) == val) -+ return 0; -+ -+ usleep_range(1000, 2000); -+ } -+ -+ return -ETIMEDOUT; -+} -+ -+static int ar7240sw_reg_wait(struct mii_bus *mii, u32 reg, u32 mask, u32 val, -+ unsigned timeout) -+{ -+ int ret; -+ -+ mutex_lock(®_mutex); -+ ret = __ar7240sw_reg_wait(mii, reg, mask, val, timeout); -+ mutex_unlock(®_mutex); -+ return ret; -+} -+ -+u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr, -+ unsigned reg_addr) -+{ -+ u32 t, val = 0xffff; -+ int err; -+ -+ if (phy_addr >= AR7240_NUM_PHYS) -+ return 0xffff; -+ -+ mutex_lock(®_mutex); -+ t = (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) | -+ (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) | -+ AR7240_MDIO_CTRL_MASTER_EN | -+ AR7240_MDIO_CTRL_BUSY | -+ AR7240_MDIO_CTRL_CMD_READ; -+ -+ __ar7240sw_reg_write(mii, AR7240_REG_MDIO_CTRL, t); -+ err = __ar7240sw_reg_wait(mii, AR7240_REG_MDIO_CTRL, -+ AR7240_MDIO_CTRL_BUSY, 0, 5); -+ if (!err) -+ val = __ar7240sw_reg_read(mii, AR7240_REG_MDIO_CTRL); -+ mutex_unlock(®_mutex); -+ -+ return val & AR7240_MDIO_CTRL_DATA_M; -+} -+ -+int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr, -+ unsigned reg_addr, u16 reg_val) -+{ -+ u32 t; -+ int ret; -+ -+ if (phy_addr >= AR7240_NUM_PHYS) -+ return -EINVAL; -+ -+ mutex_lock(®_mutex); -+ t = (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) | -+ (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) | -+ AR7240_MDIO_CTRL_MASTER_EN | -+ AR7240_MDIO_CTRL_BUSY | -+ AR7240_MDIO_CTRL_CMD_WRITE | -+ reg_val; -+ -+ __ar7240sw_reg_write(mii, AR7240_REG_MDIO_CTRL, t); -+ ret = __ar7240sw_reg_wait(mii, AR7240_REG_MDIO_CTRL, -+ AR7240_MDIO_CTRL_BUSY, 0, 5); -+ mutex_unlock(®_mutex); -+ -+ return ret; -+} -+ -+static int ar7240sw_capture_stats(struct ar7240sw *as) -+{ -+ struct mii_bus *mii = as->mii_bus; -+ int port; -+ int ret; -+ -+ write_lock(&as->stats_lock); -+ -+ /* Capture the hardware statistics for all ports */ -+ ar7240sw_reg_rmw(mii, AR7240_REG_MIB_FUNCTION0, -+ (AR7240_MIB_FUNC_M << AR7240_MIB_FUNC_S), -+ (AR7240_MIB_FUNC_CAPTURE << AR7240_MIB_FUNC_S)); -+ -+ /* Wait for the capturing to complete. */ -+ ret = ar7240sw_reg_wait(mii, AR7240_REG_MIB_FUNCTION0, -+ AR7240_MIB_BUSY, 0, 10); -+ -+ if (ret) -+ goto unlock; -+ -+ for (port = 0; port < AR7240_NUM_PORTS; port++) { -+ unsigned int base; -+ struct ar7240sw_port_stat *stats; -+ -+ base = AR7240_REG_STATS_BASE(port); -+ stats = &as->port_stats[port]; -+ -+#define READ_STAT(_r) ar7240sw_reg_read(mii, base + AR7240_STATS_ ## _r) -+ -+ stats->rx_good_byte += READ_STAT(RXGOODBYTE); -+ stats->tx_byte += READ_STAT(TXBYTE); -+ -+#undef READ_STAT -+ } -+ -+ ret = 0; -+ -+unlock: -+ write_unlock(&as->stats_lock); -+ return ret; -+} -+ -+static void ar7240sw_disable_port(struct ar7240sw *as, unsigned port) -+{ -+ ar7240sw_reg_write(as->mii_bus, AR7240_REG_PORT_CTRL(port), -+ AR7240_PORT_CTRL_STATE_DISABLED); -+} -+ -+static void ar7240sw_setup(struct ar7240sw *as) -+{ -+ struct mii_bus *mii = as->mii_bus; -+ -+ /* Enable CPU port, and disable mirror port */ -+ ar7240sw_reg_write(mii, AR7240_REG_CPU_PORT, -+ AR7240_CPU_PORT_EN | -+ (15 << AR7240_MIRROR_PORT_S)); -+ -+ /* Setup TAG priority mapping */ -+ ar7240sw_reg_write(mii, AR7240_REG_TAG_PRIORITY, 0xfa50); -+ -+ if (sw_is_ar934x(as)) { -+ /* Enable aging, MAC replacing */ -+ ar7240sw_reg_write(mii, AR934X_REG_AT_CTRL, -+ 0x2b /* 5 min age time */ | -+ AR934X_AT_CTRL_AGE_EN | -+ AR934X_AT_CTRL_LEARN_CHANGE); -+ /* Enable ARP frame acknowledge */ -+ ar7240sw_reg_set(mii, AR934X_REG_QM_CTRL, -+ AR934X_QM_CTRL_ARP_EN); -+ /* Enable Broadcast/Multicast frames transmitted to the CPU */ -+ ar7240sw_reg_set(mii, AR934X_REG_FLOOD_MASK, -+ AR934X_FLOOD_MASK_BC_DP(0) | -+ AR934X_FLOOD_MASK_MC_DP(0)); -+ -+ /* setup MTU */ -+ ar7240sw_reg_rmw(mii, AR7240_REG_GLOBAL_CTRL, -+ AR9340_GLOBAL_CTRL_MTU_M, -+ AR9340_GLOBAL_CTRL_MTU_M); -+ -+ /* Enable MIB counters */ -+ ar7240sw_reg_set(mii, AR7240_REG_MIB_FUNCTION0, -+ AR934X_MIB_ENABLE); -+ -+ } else { -+ /* Enable ARP frame acknowledge, aging, MAC replacing */ -+ ar7240sw_reg_write(mii, AR7240_REG_AT_CTRL, -+ AR7240_AT_CTRL_RESERVED | -+ 0x2b /* 5 min age time */ | -+ AR7240_AT_CTRL_AGE_EN | -+ AR7240_AT_CTRL_ARP_EN | -+ AR7240_AT_CTRL_LEARN_CHANGE); -+ /* Enable Broadcast frames transmitted to the CPU */ -+ ar7240sw_reg_set(mii, AR7240_REG_FLOOD_MASK, -+ AR7240_FLOOD_MASK_BROAD_TO_CPU); -+ -+ /* setup MTU */ -+ ar7240sw_reg_rmw(mii, AR7240_REG_GLOBAL_CTRL, -+ AR7240_GLOBAL_CTRL_MTU_M, -+ AR7240_GLOBAL_CTRL_MTU_M); -+ } -+ -+ /* setup Service TAG */ -+ ar7240sw_reg_rmw(mii, AR7240_REG_SERVICE_TAG, AR7240_SERVICE_TAG_M, 0); -+} -+ -+/* inspired by phy_poll_reset in drivers/net/phy/phy_device.c */ -+static int -+ar7240sw_phy_poll_reset(struct mii_bus *bus) -+{ -+ const unsigned int sleep_msecs = 20; -+ int ret, elapsed, i; -+ -+ for (elapsed = sleep_msecs; elapsed <= 600; -+ elapsed += sleep_msecs) { -+ msleep(sleep_msecs); -+ for (i = 0; i < AR7240_NUM_PHYS; i++) { -+ ret = ar7240sw_phy_read(bus, i, MII_BMCR); -+ if (ret < 0) -+ return ret; -+ if (ret & BMCR_RESET) -+ break; -+ if (i == AR7240_NUM_PHYS - 1) { -+ usleep_range(1000, 2000); -+ return 0; -+ } -+ } -+ } -+ return -ETIMEDOUT; -+} -+ -+static int ar7240sw_reset(struct ar7240sw *as) -+{ -+ struct mii_bus *mii = as->mii_bus; -+ int ret; -+ int i; -+ -+ /* Set all ports to disabled state. */ -+ for (i = 0; i < AR7240_NUM_PORTS; i++) -+ ar7240sw_disable_port(as, i); -+ -+ /* Wait for transmit queues to drain. */ -+ usleep_range(2000, 3000); -+ -+ /* Reset the switch. */ -+ ar7240sw_reg_write(mii, AR7240_REG_MASK_CTRL, -+ AR7240_MASK_CTRL_SOFT_RESET); -+ -+ ret = ar7240sw_reg_wait(mii, AR7240_REG_MASK_CTRL, -+ AR7240_MASK_CTRL_SOFT_RESET, 0, 1000); -+ -+ /* setup PHYs */ -+ for (i = 0; i < AR7240_NUM_PHYS; i++) { -+ ar7240sw_phy_write(mii, i, MII_ADVERTISE, -+ ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | -+ ADVERTISE_PAUSE_ASYM); -+ ar7240sw_phy_write(mii, i, MII_BMCR, -+ BMCR_RESET | BMCR_ANENABLE); -+ } -+ ret = ar7240sw_phy_poll_reset(mii); -+ if (ret) -+ return ret; -+ -+ ar7240sw_setup(as); -+ return ret; -+} -+ -+static void ar7240sw_setup_port(struct ar7240sw *as, unsigned port, u8 portmask) -+{ -+ struct mii_bus *mii = as->mii_bus; -+ u32 ctrl; -+ u32 vid, mode; -+ -+ ctrl = AR7240_PORT_CTRL_STATE_FORWARD | AR7240_PORT_CTRL_LEARN | -+ AR7240_PORT_CTRL_SINGLE_VLAN; -+ -+ if (port == AR7240_PORT_CPU) { -+ ar7240sw_reg_write(mii, AR7240_REG_PORT_STATUS(port), -+ AR7240_PORT_STATUS_SPEED_1000 | -+ AR7240_PORT_STATUS_TXFLOW | -+ AR7240_PORT_STATUS_RXFLOW | -+ AR7240_PORT_STATUS_TXMAC | -+ AR7240_PORT_STATUS_RXMAC | -+ AR7240_PORT_STATUS_DUPLEX); -+ } else { -+ ar7240sw_reg_write(mii, AR7240_REG_PORT_STATUS(port), -+ AR7240_PORT_STATUS_LINK_AUTO); -+ } -+ -+ /* Set the default VID for this port */ -+ if (as->vlan) { -+ vid = as->vlan_id[as->pvid[port]]; -+ mode = AR7240_PORT_VLAN_MODE_SECURE; -+ } else { -+ vid = port; -+ mode = AR7240_PORT_VLAN_MODE_PORT_ONLY; -+ } -+ -+ if (as->vlan) { -+ if (as->vlan_tagged & BIT(port)) -+ ctrl |= AR7240_PORT_CTRL_VLAN_MODE_ADD << -+ AR7240_PORT_CTRL_VLAN_MODE_S; -+ else -+ ctrl |= AR7240_PORT_CTRL_VLAN_MODE_STRIP << -+ AR7240_PORT_CTRL_VLAN_MODE_S; -+ } else { -+ ctrl |= AR7240_PORT_CTRL_VLAN_MODE_KEEP << -+ AR7240_PORT_CTRL_VLAN_MODE_S; -+ } -+ -+ if (!portmask) { -+ if (port == AR7240_PORT_CPU) -+ portmask = ar7240sw_port_mask_but(as, AR7240_PORT_CPU); -+ else -+ portmask = ar7240sw_port_mask(as, AR7240_PORT_CPU); -+ } -+ -+ /* preserve mirror rx&tx flags */ -+ ctrl |= ar7240sw_reg_read(mii, AR7240_REG_PORT_CTRL(port)) & -+ (AR7240_PORT_CTRL_MIRROR_RX | AR7240_PORT_CTRL_MIRROR_TX); -+ -+ /* allow the port to talk to all other ports, but exclude its -+ * own ID to prevent frames from being reflected back to the -+ * port that they came from */ -+ portmask &= ar7240sw_port_mask_but(as, port); -+ -+ ar7240sw_reg_write(mii, AR7240_REG_PORT_CTRL(port), ctrl); -+ if (sw_is_ar934x(as)) { -+ u32 vlan1, vlan2; -+ -+ vlan1 = (vid << AR934X_PORT_VLAN1_DEFAULT_CVID_S); -+ vlan2 = (portmask << AR934X_PORT_VLAN2_PORT_VID_MEM_S) | -+ (mode << AR934X_PORT_VLAN2_8021Q_MODE_S); -+ ar7240sw_reg_write(mii, AR934X_REG_PORT_VLAN1(port), vlan1); -+ ar7240sw_reg_write(mii, AR934X_REG_PORT_VLAN2(port), vlan2); -+ } else { -+ u32 vlan; -+ -+ vlan = vid | (mode << AR7240_PORT_VLAN_MODE_S) | -+ (portmask << AR7240_PORT_VLAN_DEST_PORTS_S); -+ -+ ar7240sw_reg_write(mii, AR7240_REG_PORT_VLAN(port), vlan); -+ } -+} -+ -+static int ar7240_set_addr(struct ar7240sw *as, u8 *addr) -+{ -+ struct mii_bus *mii = as->mii_bus; -+ u32 t; -+ -+ t = (addr[4] << 8) | addr[5]; -+ ar7240sw_reg_write(mii, AR7240_REG_MAC_ADDR0, t); -+ -+ t = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3]; -+ ar7240sw_reg_write(mii, AR7240_REG_MAC_ADDR1, t); -+ -+ return 0; -+} -+ -+static int -+ar7240_set_vid(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ as->vlan_id[val->port_vlan] = val->value.i; -+ return 0; -+} -+ -+static int -+ar7240_get_vid(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ val->value.i = as->vlan_id[val->port_vlan]; -+ return 0; -+} -+ -+static int -+ar7240_set_pvid(struct switch_dev *dev, int port, int vlan) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ -+ /* make sure no invalid PVIDs get set */ -+ -+ if (vlan >= dev->vlans) -+ return -EINVAL; -+ -+ as->pvid[port] = vlan; -+ return 0; -+} -+ -+static int -+ar7240_get_pvid(struct switch_dev *dev, int port, int *vlan) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ *vlan = as->pvid[port]; -+ return 0; -+} -+ -+static int -+ar7240_get_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ u8 ports = as->vlan_table[val->port_vlan]; -+ int i; -+ -+ val->len = 0; -+ for (i = 0; i < as->swdev.ports; i++) { -+ struct switch_port *p; -+ -+ if (!(ports & (1 << i))) -+ continue; -+ -+ p = &val->value.ports[val->len++]; -+ p->id = i; -+ if (as->vlan_tagged & (1 << i)) -+ p->flags = (1 << SWITCH_PORT_FLAG_TAGGED); -+ else -+ p->flags = 0; -+ } -+ return 0; -+} -+ -+static int -+ar7240_set_ports(struct switch_dev *dev, struct switch_val *val) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ u8 *vt = &as->vlan_table[val->port_vlan]; -+ int i, j; -+ -+ *vt = 0; -+ for (i = 0; i < val->len; i++) { -+ struct switch_port *p = &val->value.ports[i]; -+ -+ if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) -+ as->vlan_tagged |= (1 << p->id); -+ else { -+ as->vlan_tagged &= ~(1 << p->id); -+ as->pvid[p->id] = val->port_vlan; -+ -+ /* make sure that an untagged port does not -+ * appear in other vlans */ -+ for (j = 0; j < AR7240_MAX_VLANS; j++) { -+ if (j == val->port_vlan) -+ continue; -+ as->vlan_table[j] &= ~(1 << p->id); -+ } -+ } -+ -+ *vt |= 1 << p->id; -+ } -+ return 0; -+} -+ -+static int -+ar7240_set_vlan(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ as->vlan = !!val->value.i; -+ return 0; -+} -+ -+static int -+ar7240_get_vlan(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ val->value.i = as->vlan; -+ return 0; -+} -+ -+static void -+ar7240_vtu_op(struct ar7240sw *as, u32 op, u32 val) -+{ -+ struct mii_bus *mii = as->mii_bus; -+ -+ if (ar7240sw_reg_wait(mii, AR7240_REG_VTU, AR7240_VTU_ACTIVE, 0, 5)) -+ return; -+ -+ if ((op & AR7240_VTU_OP) == AR7240_VTU_OP_LOAD) { -+ val &= AR7240_VTUDATA_MEMBER; -+ val |= AR7240_VTUDATA_VALID; -+ ar7240sw_reg_write(mii, AR7240_REG_VTU_DATA, val); -+ } -+ op |= AR7240_VTU_ACTIVE; -+ ar7240sw_reg_write(mii, AR7240_REG_VTU, op); -+} -+ -+static int -+ar7240_hw_apply(struct switch_dev *dev) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ u8 portmask[AR7240_NUM_PORTS]; -+ int i, j; -+ -+ /* flush all vlan translation unit entries */ -+ ar7240_vtu_op(as, AR7240_VTU_OP_FLUSH, 0); -+ -+ memset(portmask, 0, sizeof(portmask)); -+ if (as->vlan) { -+ /* calculate the port destination masks and load vlans -+ * into the vlan translation unit */ -+ for (j = 0; j < AR7240_MAX_VLANS; j++) { -+ u8 vp = as->vlan_table[j]; -+ -+ if (!vp) -+ continue; -+ -+ for (i = 0; i < as->swdev.ports; i++) { -+ u8 mask = (1 << i); -+ if (vp & mask) -+ portmask[i] |= vp & ~mask; -+ } -+ -+ ar7240_vtu_op(as, -+ AR7240_VTU_OP_LOAD | -+ (as->vlan_id[j] << AR7240_VTU_VID_S), -+ as->vlan_table[j]); -+ } -+ } else { -+ /* vlan disabled: -+ * isolate all ports, but connect them to the cpu port */ -+ for (i = 0; i < as->swdev.ports; i++) { -+ if (i == AR7240_PORT_CPU) -+ continue; -+ -+ portmask[i] = 1 << AR7240_PORT_CPU; -+ portmask[AR7240_PORT_CPU] |= (1 << i); -+ } -+ } -+ -+ /* update the port destination mask registers and tag settings */ -+ for (i = 0; i < as->swdev.ports; i++) -+ ar7240sw_setup_port(as, i, portmask[i]); -+ -+ return 0; -+} -+ -+static int -+ar7240_reset_switch(struct switch_dev *dev) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ ar7240sw_reset(as); -+ return 0; -+} -+ -+static int -+ar7240_get_port_link(struct switch_dev *dev, int port, -+ struct switch_port_link *link) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ struct mii_bus *mii = as->mii_bus; -+ u32 status; -+ -+ if (port >= AR7240_NUM_PORTS) -+ return -EINVAL; -+ -+ status = ar7240sw_reg_read(mii, AR7240_REG_PORT_STATUS(port)); -+ link->aneg = !!(status & AR7240_PORT_STATUS_LINK_AUTO); -+ if (link->aneg) { -+ link->link = !!(status & AR7240_PORT_STATUS_LINK_UP); -+ if (!link->link) -+ return 0; -+ } else { -+ link->link = true; -+ } -+ -+ link->duplex = !!(status & AR7240_PORT_STATUS_DUPLEX); -+ link->tx_flow = !!(status & AR7240_PORT_STATUS_TXFLOW); -+ link->rx_flow = !!(status & AR7240_PORT_STATUS_RXFLOW); -+ switch (status & AR7240_PORT_STATUS_SPEED_M) { -+ case AR7240_PORT_STATUS_SPEED_10: -+ link->speed = SWITCH_PORT_SPEED_10; -+ break; -+ case AR7240_PORT_STATUS_SPEED_100: -+ link->speed = SWITCH_PORT_SPEED_100; -+ break; -+ case AR7240_PORT_STATUS_SPEED_1000: -+ link->speed = SWITCH_PORT_SPEED_1000; -+ break; -+ } -+ -+ return 0; -+} -+ -+static int -+ar7240_get_port_stats(struct switch_dev *dev, int port, -+ struct switch_port_stats *stats) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ -+ if (port >= AR7240_NUM_PORTS) -+ return -EINVAL; -+ -+ ar7240sw_capture_stats(as); -+ -+ read_lock(&as->stats_lock); -+ stats->rx_bytes = as->port_stats[port].rx_good_byte; -+ stats->tx_bytes = as->port_stats[port].tx_byte; -+ read_unlock(&as->stats_lock); -+ -+ return 0; -+} -+ -+static int -+ar7240_set_mirror_monitor_port(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ struct mii_bus *mii = as->mii_bus; -+ -+ int port = val->value.i; -+ -+ if (port > 15) -+ return -EINVAL; -+ -+ ar7240sw_reg_rmw(mii, AR7240_REG_CPU_PORT, -+ AR7240_MIRROR_PORT_M << AR7240_MIRROR_PORT_S, -+ port << AR7240_MIRROR_PORT_S); -+ -+ return 0; -+} -+ -+static int -+ar7240_get_mirror_monitor_port(struct switch_dev *dev, -+ const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ struct mii_bus *mii = as->mii_bus; -+ -+ u32 ret; -+ -+ ret = ar7240sw_reg_read(mii, AR7240_REG_CPU_PORT); -+ val->value.i = (ret >> AR7240_MIRROR_PORT_S) & AR7240_MIRROR_PORT_M; -+ -+ return 0; -+} -+ -+static int -+ar7240_set_mirror_rx(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ struct mii_bus *mii = as->mii_bus; -+ -+ int port = val->port_vlan; -+ -+ if (port >= dev->ports) -+ return -EINVAL; -+ -+ if (val && val->value.i == 1) -+ ar7240sw_reg_set(mii, AR7240_REG_PORT_CTRL(port), -+ AR7240_PORT_CTRL_MIRROR_RX); -+ else -+ ar7240sw_reg_rmw(mii, AR7240_REG_PORT_CTRL(port), -+ AR7240_PORT_CTRL_MIRROR_RX, 0); -+ -+ return 0; -+} -+ -+static int -+ar7240_get_mirror_rx(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ struct mii_bus *mii = as->mii_bus; -+ -+ u32 ctrl; -+ -+ int port = val->port_vlan; -+ -+ if (port >= dev->ports) -+ return -EINVAL; -+ -+ ctrl = ar7240sw_reg_read(mii, AR7240_REG_PORT_CTRL(port)); -+ -+ if ((ctrl & AR7240_PORT_CTRL_MIRROR_RX) == AR7240_PORT_CTRL_MIRROR_RX) -+ val->value.i = 1; -+ else -+ val->value.i = 0; -+ -+ return 0; -+} -+ -+static int -+ar7240_set_mirror_tx(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ struct mii_bus *mii = as->mii_bus; -+ -+ int port = val->port_vlan; -+ -+ if (port >= dev->ports) -+ return -EINVAL; -+ -+ if (val && val->value.i == 1) -+ ar7240sw_reg_set(mii, AR7240_REG_PORT_CTRL(port), -+ AR7240_PORT_CTRL_MIRROR_TX); -+ else -+ ar7240sw_reg_rmw(mii, AR7240_REG_PORT_CTRL(port), -+ AR7240_PORT_CTRL_MIRROR_TX, 0); -+ -+ return 0; -+} -+ -+static int -+ar7240_get_mirror_tx(struct switch_dev *dev, const struct switch_attr *attr, -+ struct switch_val *val) -+{ -+ struct ar7240sw *as = sw_to_ar7240(dev); -+ struct mii_bus *mii = as->mii_bus; -+ -+ u32 ctrl; -+ -+ int port = val->port_vlan; -+ -+ if (port >= dev->ports) -+ return -EINVAL; -+ -+ ctrl = ar7240sw_reg_read(mii, AR7240_REG_PORT_CTRL(port)); -+ -+ if ((ctrl & AR7240_PORT_CTRL_MIRROR_TX) == AR7240_PORT_CTRL_MIRROR_TX) -+ val->value.i = 1; -+ else -+ val->value.i = 0; -+ -+ return 0; -+} -+ -+static struct switch_attr ar7240_globals[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_vlan", -+ .description = "Enable VLAN mode", -+ .set = ar7240_set_vlan, -+ .get = ar7240_get_vlan, -+ .max = 1 -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "mirror_monitor_port", -+ .description = "Mirror monitor port", -+ .set = ar7240_set_mirror_monitor_port, -+ .get = ar7240_get_mirror_monitor_port, -+ .max = 15 -+ }, -+}; -+ -+static struct switch_attr ar7240_port[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_mirror_rx", -+ .description = "Enable mirroring of RX packets", -+ .set = ar7240_set_mirror_rx, -+ .get = ar7240_get_mirror_rx, -+ .max = 1 -+ }, -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "enable_mirror_tx", -+ .description = "Enable mirroring of TX packets", -+ .set = ar7240_set_mirror_tx, -+ .get = ar7240_get_mirror_tx, -+ .max = 1 -+ }, -+}; -+ -+static struct switch_attr ar7240_vlan[] = { -+ { -+ .type = SWITCH_TYPE_INT, -+ .name = "vid", -+ .description = "VLAN ID", -+ .set = ar7240_set_vid, -+ .get = ar7240_get_vid, -+ .max = 4094, -+ }, -+}; -+ -+static const struct switch_dev_ops ar7240_ops = { -+ .attr_global = { -+ .attr = ar7240_globals, -+ .n_attr = ARRAY_SIZE(ar7240_globals), -+ }, -+ .attr_port = { -+ .attr = ar7240_port, -+ .n_attr = ARRAY_SIZE(ar7240_port), -+ }, -+ .attr_vlan = { -+ .attr = ar7240_vlan, -+ .n_attr = ARRAY_SIZE(ar7240_vlan), -+ }, -+ .get_port_pvid = ar7240_get_pvid, -+ .set_port_pvid = ar7240_set_pvid, -+ .get_vlan_ports = ar7240_get_ports, -+ .set_vlan_ports = ar7240_set_ports, -+ .apply_config = ar7240_hw_apply, -+ .reset_switch = ar7240_reset_switch, -+ .get_port_link = ar7240_get_port_link, -+ .get_port_stats = ar7240_get_port_stats, -+}; -+ -+static struct ar7240sw *ar7240_probe(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ struct mii_bus *mii = ag->mii_bus; -+ struct ar7240sw *as; -+ struct switch_dev *swdev; -+ u32 ctrl; -+ u16 phy_id1; -+ u16 phy_id2; -+ int i; -+ -+ phy_id1 = ar7240sw_phy_read(mii, 0, MII_PHYSID1); -+ phy_id2 = ar7240sw_phy_read(mii, 0, MII_PHYSID2); -+ if ((phy_id1 != AR7240_PHY_ID1 || phy_id2 != AR7240_PHY_ID2) && -+ (phy_id1 != AR934X_PHY_ID1 || phy_id2 != AR934X_PHY_ID2)) { -+ pr_err("%s: unknown phy id '%04x:%04x'\n", -+ dev_name(&mii->dev), phy_id1, phy_id2); -+ return NULL; -+ } -+ -+ as = kzalloc(sizeof(*as), GFP_KERNEL); -+ if (!as) -+ return NULL; -+ -+ as->mii_bus = mii; -+ as->swdata = pdata->switch_data; -+ -+ swdev = &as->swdev; -+ -+ ctrl = ar7240sw_reg_read(mii, AR7240_REG_MASK_CTRL); -+ as->ver = (ctrl >> AR7240_MASK_CTRL_VERSION_S) & -+ AR7240_MASK_CTRL_VERSION_M; -+ -+ if (sw_is_ar7240(as)) { -+ swdev->name = "AR7240/AR9330 built-in switch"; -+ swdev->ports = AR7240_NUM_PORTS - 1; -+ } else if (sw_is_ar934x(as)) { -+ swdev->name = "AR934X built-in switch"; -+ -+ if (pdata->phy_if_mode == PHY_INTERFACE_MODE_GMII) { -+ ar7240sw_reg_set(mii, AR934X_REG_OPER_MODE0, -+ AR934X_OPER_MODE0_MAC_GMII_EN); -+ } else if (pdata->phy_if_mode == PHY_INTERFACE_MODE_MII) { -+ ar7240sw_reg_set(mii, AR934X_REG_OPER_MODE0, -+ AR934X_OPER_MODE0_PHY_MII_EN); -+ } else { -+ pr_err("%s: invalid PHY interface mode\n", -+ dev_name(&mii->dev)); -+ goto err_free; -+ } -+ -+ if (as->swdata->phy4_mii_en) { -+ ar7240sw_reg_set(mii, AR934X_REG_OPER_MODE1, -+ AR934X_REG_OPER_MODE1_PHY4_MII_EN); -+ swdev->ports = AR7240_NUM_PORTS - 1; -+ } else { -+ swdev->ports = AR7240_NUM_PORTS; -+ } -+ } else { -+ pr_err("%s: unsupported chip, ctrl=%08x\n", -+ dev_name(&mii->dev), ctrl); -+ goto err_free; -+ } -+ -+ swdev->cpu_port = AR7240_PORT_CPU; -+ swdev->vlans = AR7240_MAX_VLANS; -+ swdev->ops = &ar7240_ops; -+ -+ if (register_switch(&as->swdev, ag->dev) < 0) -+ goto err_free; -+ -+ pr_info("%s: Found an %s\n", dev_name(&mii->dev), swdev->name); -+ -+ /* initialize defaults */ -+ for (i = 0; i < AR7240_MAX_VLANS; i++) -+ as->vlan_id[i] = i; -+ -+ as->vlan_table[0] = ar7240sw_port_mask_all(as); -+ -+ return as; -+ -+err_free: -+ kfree(as); -+ return NULL; -+} -+ -+static void link_function(struct work_struct *work) { -+ struct ag71xx *ag = container_of(work, struct ag71xx, link_work.work); -+ struct ar7240sw *as = ag->phy_priv; -+ unsigned long flags; -+ u8 mask; -+ int i; -+ int status = 0; -+ -+ mask = ~as->swdata->phy_poll_mask; -+ for (i = 0; i < AR7240_NUM_PHYS; i++) { -+ int link; -+ -+ if (!(mask & BIT(i))) -+ continue; -+ -+ link = ar7240sw_phy_read(ag->mii_bus, i, MII_BMSR); -+ if (link & BMSR_LSTATUS) { -+ status = 1; -+ break; -+ } -+ } -+ -+ spin_lock_irqsave(&ag->lock, flags); -+ if (status != ag->link) { -+ ag->link = status; -+ ag71xx_link_adjust(ag); -+ } -+ spin_unlock_irqrestore(&ag->lock, flags); -+ -+ schedule_delayed_work(&ag->link_work, HZ / 2); -+} -+ -+void ag71xx_ar7240_start(struct ag71xx *ag) -+{ -+ struct ar7240sw *as = ag->phy_priv; -+ -+ ar7240sw_reset(as); -+ -+ ag->speed = SPEED_1000; -+ ag->duplex = 1; -+ -+ ar7240_set_addr(as, ag->dev->dev_addr); -+ ar7240_hw_apply(&as->swdev); -+ -+ schedule_delayed_work(&ag->link_work, HZ / 10); -+} -+ -+void ag71xx_ar7240_stop(struct ag71xx *ag) -+{ -+ cancel_delayed_work_sync(&ag->link_work); -+} -+ -+int ag71xx_ar7240_init(struct ag71xx *ag) -+{ -+ struct ar7240sw *as; -+ -+ as = ar7240_probe(ag); -+ if (!as) -+ return -ENODEV; -+ -+ ag->phy_priv = as; -+ ar7240sw_reset(as); -+ -+ rwlock_init(&as->stats_lock); -+ INIT_DELAYED_WORK(&ag->link_work, link_function); -+ -+ return 0; -+} -+ -+void ag71xx_ar7240_cleanup(struct ag71xx *ag) -+{ -+ struct ar7240sw *as = ag->phy_priv; -+ -+ if (!as) -+ return; -+ -+ unregister_switch(&as->swdev); -+ kfree(as); -+ ag->phy_priv = NULL; -+} -diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar8216.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar8216.c -new file mode 100644 -index 0000000000..7ec43b7221 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar8216.c -@@ -0,0 +1,44 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * Special support for the Atheros ar8216 switch chip -+ * -+ * Copyright (C) 2009-2010 Gabor Juhos -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "ag71xx.h" -+ -+#define AR8216_PACKET_TYPE_MASK 0xf -+#define AR8216_PACKET_TYPE_NORMAL 0 -+ -+#define AR8216_HEADER_LEN 2 -+ -+void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb) -+{ -+ skb_push(skb, AR8216_HEADER_LEN); -+ skb->data[0] = 0x10; -+ skb->data[1] = 0x80; -+} -+ -+int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb, -+ int pktlen) -+{ -+ u8 type; -+ -+ type = skb->data[1] & AR8216_PACKET_TYPE_MASK; -+ switch (type) { -+ case AR8216_PACKET_TYPE_NORMAL: -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ skb_pull(skb, AR8216_HEADER_LEN); -+ return 0; -+} -diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c -new file mode 100644 -index 0000000000..20cf1c15c8 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c -@@ -0,0 +1,285 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+ -+#include "ag71xx.h" -+ -+static struct dentry *ag71xx_debugfs_root; -+ -+static int ag71xx_debugfs_generic_open(struct inode *inode, struct file *file) -+{ -+ file->private_data = inode->i_private; -+ return 0; -+} -+ -+void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status) -+{ -+ if (status) -+ ag->debug.int_stats.total++; -+ if (status & AG71XX_INT_TX_PS) -+ ag->debug.int_stats.tx_ps++; -+ if (status & AG71XX_INT_TX_UR) -+ ag->debug.int_stats.tx_ur++; -+ if (status & AG71XX_INT_TX_BE) -+ ag->debug.int_stats.tx_be++; -+ if (status & AG71XX_INT_RX_PR) -+ ag->debug.int_stats.rx_pr++; -+ if (status & AG71XX_INT_RX_OF) -+ ag->debug.int_stats.rx_of++; -+ if (status & AG71XX_INT_RX_BE) -+ ag->debug.int_stats.rx_be++; -+} -+ -+static ssize_t read_file_int_stats(struct file *file, char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+#define PR_INT_STAT(_label, _field) \ -+ len += snprintf(buf + len, sizeof(buf) - len, \ -+ "%20s: %10lu\n", _label, ag->debug.int_stats._field); -+ -+ struct ag71xx *ag = file->private_data; -+ char buf[256]; -+ unsigned int len = 0; -+ -+ PR_INT_STAT("TX Packet Sent", tx_ps); -+ PR_INT_STAT("TX Underrun", tx_ur); -+ PR_INT_STAT("TX Bus Error", tx_be); -+ PR_INT_STAT("RX Packet Received", rx_pr); -+ PR_INT_STAT("RX Overflow", rx_of); -+ PR_INT_STAT("RX Bus Error", rx_be); -+ len += snprintf(buf + len, sizeof(buf) - len, "\n"); -+ PR_INT_STAT("Total", total); -+ -+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -+#undef PR_INT_STAT -+} -+ -+static const struct file_operations ag71xx_fops_int_stats = { -+ .open = ag71xx_debugfs_generic_open, -+ .read = read_file_int_stats, -+ .owner = THIS_MODULE -+}; -+ -+void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx) -+{ -+ struct ag71xx_napi_stats *stats = &ag->debug.napi_stats; -+ -+ if (rx) { -+ stats->rx_count++; -+ stats->rx_packets += rx; -+ if (rx <= AG71XX_NAPI_WEIGHT) -+ stats->rx[rx]++; -+ if (rx > stats->rx_packets_max) -+ stats->rx_packets_max = rx; -+ } -+ -+ if (tx) { -+ stats->tx_count++; -+ stats->tx_packets += tx; -+ if (tx <= AG71XX_NAPI_WEIGHT) -+ stats->tx[tx]++; -+ if (tx > stats->tx_packets_max) -+ stats->tx_packets_max = tx; -+ } -+} -+ -+static ssize_t read_file_napi_stats(struct file *file, char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct ag71xx *ag = file->private_data; -+ struct ag71xx_napi_stats *stats = &ag->debug.napi_stats; -+ char *buf; -+ unsigned int buflen; -+ unsigned int len = 0; -+ unsigned long rx_avg = 0; -+ unsigned long tx_avg = 0; -+ int ret; -+ int i; -+ -+ buflen = 2048; -+ buf = kmalloc(buflen, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ if (stats->rx_count) -+ rx_avg = stats->rx_packets / stats->rx_count; -+ -+ if (stats->tx_count) -+ tx_avg = stats->tx_packets / stats->tx_count; -+ -+ len += snprintf(buf + len, buflen - len, "%3s %10s %10s\n", -+ "len", "rx", "tx"); -+ -+ for (i = 1; i <= AG71XX_NAPI_WEIGHT; i++) -+ len += snprintf(buf + len, buflen - len, -+ "%3d: %10lu %10lu\n", -+ i, stats->rx[i], stats->tx[i]); -+ -+ len += snprintf(buf + len, buflen - len, "\n"); -+ -+ len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n", -+ "sum", stats->rx_count, stats->tx_count); -+ len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n", -+ "avg", rx_avg, tx_avg); -+ len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n", -+ "max", stats->rx_packets_max, stats->tx_packets_max); -+ len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n", -+ "pkt", stats->rx_packets, stats->tx_packets); -+ -+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ kfree(buf); -+ -+ return ret; -+} -+ -+static const struct file_operations ag71xx_fops_napi_stats = { -+ .open = ag71xx_debugfs_generic_open, -+ .read = read_file_napi_stats, -+ .owner = THIS_MODULE -+}; -+ -+#define DESC_PRINT_LEN 64 -+ -+static ssize_t read_file_ring(struct file *file, char __user *user_buf, -+ size_t count, loff_t *ppos, -+ struct ag71xx *ag, -+ struct ag71xx_ring *ring, -+ unsigned desc_reg) -+{ -+ int ring_size = BIT(ring->order); -+ int ring_mask = ring_size - 1; -+ char *buf; -+ unsigned int buflen; -+ unsigned int len = 0; -+ unsigned long flags; -+ ssize_t ret; -+ int curr; -+ int dirty; -+ u32 desc_hw; -+ int i; -+ -+ buflen = (ring_size * DESC_PRINT_LEN); -+ buf = kmalloc(buflen, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ len += snprintf(buf + len, buflen - len, -+ "Idx ... %-8s %-8s %-8s %-8s .\n", -+ "desc", "next", "data", "ctrl"); -+ -+ spin_lock_irqsave(&ag->lock, flags); -+ -+ curr = (ring->curr & ring_mask); -+ dirty = (ring->dirty & ring_mask); -+ desc_hw = ag71xx_rr(ag, desc_reg); -+ for (i = 0; i < ring_size; i++) { -+ struct ag71xx_desc *desc = ag71xx_ring_desc(ring, i); -+ u32 desc_dma = ((u32) ring->descs_dma) + i * AG71XX_DESC_SIZE; -+ -+ len += snprintf(buf + len, buflen - len, -+ "%3d %c%c%c %08x %08x %08x %08x %c\n", -+ i, -+ (i == curr) ? 'C' : ' ', -+ (i == dirty) ? 'D' : ' ', -+ (desc_hw == desc_dma) ? 'H' : ' ', -+ desc_dma, -+ desc->next, -+ desc->data, -+ desc->ctrl, -+ (desc->ctrl & DESC_EMPTY) ? 'E' : '*'); -+ } -+ -+ spin_unlock_irqrestore(&ag->lock, flags); -+ -+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ kfree(buf); -+ -+ return ret; -+} -+ -+static ssize_t read_file_tx_ring(struct file *file, char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct ag71xx *ag = file->private_data; -+ -+ return read_file_ring(file, user_buf, count, ppos, ag, &ag->tx_ring, -+ AG71XX_REG_TX_DESC); -+} -+ -+static const struct file_operations ag71xx_fops_tx_ring = { -+ .open = ag71xx_debugfs_generic_open, -+ .read = read_file_tx_ring, -+ .owner = THIS_MODULE -+}; -+ -+static ssize_t read_file_rx_ring(struct file *file, char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct ag71xx *ag = file->private_data; -+ -+ return read_file_ring(file, user_buf, count, ppos, ag, &ag->rx_ring, -+ AG71XX_REG_RX_DESC); -+} -+ -+static const struct file_operations ag71xx_fops_rx_ring = { -+ .open = ag71xx_debugfs_generic_open, -+ .read = read_file_rx_ring, -+ .owner = THIS_MODULE -+}; -+ -+void ag71xx_debugfs_exit(struct ag71xx *ag) -+{ -+ debugfs_remove_recursive(ag->debug.debugfs_dir); -+} -+ -+int ag71xx_debugfs_init(struct ag71xx *ag) -+{ -+ struct device *dev = &ag->pdev->dev; -+ -+ ag->debug.debugfs_dir = debugfs_create_dir(dev_name(dev), -+ ag71xx_debugfs_root); -+ if (!ag->debug.debugfs_dir) { -+ dev_err(dev, "unable to create debugfs directory\n"); -+ return -ENOENT; -+ } -+ -+ debugfs_create_file("int_stats", S_IRUGO, ag->debug.debugfs_dir, -+ ag, &ag71xx_fops_int_stats); -+ debugfs_create_file("napi_stats", S_IRUGO, ag->debug.debugfs_dir, -+ ag, &ag71xx_fops_napi_stats); -+ debugfs_create_file("tx_ring", S_IRUGO, ag->debug.debugfs_dir, -+ ag, &ag71xx_fops_tx_ring); -+ debugfs_create_file("rx_ring", S_IRUGO, ag->debug.debugfs_dir, -+ ag, &ag71xx_fops_rx_ring); -+ -+ return 0; -+} -+ -+int ag71xx_debugfs_root_init(void) -+{ -+ if (ag71xx_debugfs_root) -+ return -EBUSY; -+ -+ ag71xx_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); -+ if (!ag71xx_debugfs_root) -+ return -ENOENT; -+ -+ return 0; -+} -+ -+void ag71xx_debugfs_root_exit(void) -+{ -+ debugfs_remove(ag71xx_debugfs_root); -+ ag71xx_debugfs_root = NULL; -+} -diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ethtool.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ethtool.c -new file mode 100644 -index 0000000000..9e5a53e7fc ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ethtool.c -@@ -0,0 +1,120 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "ag71xx.h" -+#include -+ -+static void ag71xx_ethtool_get_drvinfo(struct net_device *dev, -+ struct ethtool_drvinfo *info) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ -+ strcpy(info->driver, ag->pdev->dev.driver->name); -+ strcpy(info->version, AG71XX_DRV_VERSION); -+ strcpy(info->bus_info, dev_name(&ag->pdev->dev)); -+} -+ -+static u32 ag71xx_ethtool_get_msglevel(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ -+ return ag->msg_enable; -+} -+ -+static void ag71xx_ethtool_set_msglevel(struct net_device *dev, u32 msg_level) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ -+ ag->msg_enable = msg_level; -+} -+ -+static void ag71xx_ethtool_get_ringparam(struct net_device *dev, -+ struct ethtool_ringparam *er) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ -+ er->tx_max_pending = AG71XX_TX_RING_SIZE_MAX; -+ er->rx_max_pending = AG71XX_RX_RING_SIZE_MAX; -+ er->rx_mini_max_pending = 0; -+ er->rx_jumbo_max_pending = 0; -+ -+ er->tx_pending = BIT(ag->tx_ring.order); -+ er->rx_pending = BIT(ag->rx_ring.order); -+ er->rx_mini_pending = 0; -+ er->rx_jumbo_pending = 0; -+ -+ if (ag->tx_ring.desc_split) -+ er->tx_pending /= AG71XX_TX_RING_DS_PER_PKT; -+} -+ -+static int ag71xx_ethtool_set_ringparam(struct net_device *dev, -+ struct ethtool_ringparam *er) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ unsigned tx_size; -+ unsigned rx_size; -+ int err = 0; -+ -+ if (er->rx_mini_pending != 0|| -+ er->rx_jumbo_pending != 0 || -+ er->rx_pending == 0 || -+ er->tx_pending == 0) -+ return -EINVAL; -+ -+ tx_size = er->tx_pending < AG71XX_TX_RING_SIZE_MAX ? -+ er->tx_pending : AG71XX_TX_RING_SIZE_MAX; -+ -+ rx_size = er->rx_pending < AG71XX_RX_RING_SIZE_MAX ? -+ er->rx_pending : AG71XX_RX_RING_SIZE_MAX; -+ -+ if (netif_running(dev)) { -+ err = dev->netdev_ops->ndo_stop(dev); -+ if (err) -+ return err; -+ } -+ -+ if (ag->tx_ring.desc_split) -+ tx_size *= AG71XX_TX_RING_DS_PER_PKT; -+ -+ ag->tx_ring.order = ag71xx_ring_size_order(tx_size); -+ ag->rx_ring.order = ag71xx_ring_size_order(rx_size); -+ -+ if (netif_running(dev)) -+ err = dev->netdev_ops->ndo_open(dev); -+ -+ return err; -+} -+ -+static int ag71xx_ethtool_nway_reset(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ struct phy_device *phydev = ag->phy_dev; -+ -+ if (!phydev) -+ return -ENODEV; -+ -+ return genphy_restart_aneg(phydev); -+} -+ -+struct ethtool_ops ag71xx_ethtool_ops = { -+ .get_drvinfo = ag71xx_ethtool_get_drvinfo, -+ .get_msglevel = ag71xx_ethtool_get_msglevel, -+ .set_msglevel = ag71xx_ethtool_set_msglevel, -+ .get_ringparam = ag71xx_ethtool_get_ringparam, -+ .set_ringparam = ag71xx_ethtool_set_ringparam, -+ .get_link_ksettings = phy_ethtool_get_link_ksettings, -+ .set_link_ksettings = phy_ethtool_set_link_ksettings, -+ .get_link = ethtool_op_get_link, -+ .get_ts_info = ethtool_op_get_ts_info, -+ .nway_reset = ag71xx_ethtool_nway_reset, -+}; -diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c -new file mode 100644 -index 0000000000..ebbe8a7472 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c -@@ -0,0 +1,1494 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "ag71xx.h" -+ -+#define AG71XX_DEFAULT_MSG_ENABLE \ -+ (NETIF_MSG_DRV \ -+ | NETIF_MSG_PROBE \ -+ | NETIF_MSG_LINK \ -+ | NETIF_MSG_TIMER \ -+ | NETIF_MSG_IFDOWN \ -+ | NETIF_MSG_IFUP \ -+ | NETIF_MSG_RX_ERR \ -+ | NETIF_MSG_TX_ERR) -+ -+static int ag71xx_msg_level = -1; -+ -+module_param_named(msg_level, ag71xx_msg_level, int, 0); -+MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)"); -+ -+#define ETH_SWITCH_HEADER_LEN 2 -+ -+static int ag71xx_tx_packets(struct ag71xx *ag, bool flush); -+static void ag71xx_qca955x_sgmii_init(void); -+ -+static inline unsigned int ag71xx_max_frame_len(unsigned int mtu) -+{ -+ return ETH_SWITCH_HEADER_LEN + ETH_HLEN + VLAN_HLEN + mtu + ETH_FCS_LEN; -+} -+ -+static void ag71xx_dump_dma_regs(struct ag71xx *ag) -+{ -+ DBG("%s: dma_tx_ctrl=%08x, dma_tx_desc=%08x, dma_tx_status=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_TX_CTRL), -+ ag71xx_rr(ag, AG71XX_REG_TX_DESC), -+ ag71xx_rr(ag, AG71XX_REG_TX_STATUS)); -+ -+ DBG("%s: dma_rx_ctrl=%08x, dma_rx_desc=%08x, dma_rx_status=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_RX_CTRL), -+ ag71xx_rr(ag, AG71XX_REG_RX_DESC), -+ ag71xx_rr(ag, AG71XX_REG_RX_STATUS)); -+} -+ -+static void ag71xx_dump_regs(struct ag71xx *ag) -+{ -+ DBG("%s: mac_cfg1=%08x, mac_cfg2=%08x, ipg=%08x, hdx=%08x, mfl=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_MAC_CFG1), -+ ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), -+ ag71xx_rr(ag, AG71XX_REG_MAC_IPG), -+ ag71xx_rr(ag, AG71XX_REG_MAC_HDX), -+ ag71xx_rr(ag, AG71XX_REG_MAC_MFL)); -+ DBG("%s: mac_ifctl=%08x, mac_addr1=%08x, mac_addr2=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), -+ ag71xx_rr(ag, AG71XX_REG_MAC_ADDR1), -+ ag71xx_rr(ag, AG71XX_REG_MAC_ADDR2)); -+ DBG("%s: fifo_cfg0=%08x, fifo_cfg1=%08x, fifo_cfg2=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); -+ DBG("%s: fifo_cfg3=%08x, fifo_cfg4=%08x, fifo_cfg5=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); -+} -+ -+static inline void ag71xx_dump_intr(struct ag71xx *ag, char *label, u32 intr) -+{ -+ DBG("%s: %s intr=%08x %s%s%s%s%s%s\n", -+ ag->dev->name, label, intr, -+ (intr & AG71XX_INT_TX_PS) ? "TXPS " : "", -+ (intr & AG71XX_INT_TX_UR) ? "TXUR " : "", -+ (intr & AG71XX_INT_TX_BE) ? "TXBE " : "", -+ (intr & AG71XX_INT_RX_PR) ? "RXPR " : "", -+ (intr & AG71XX_INT_RX_OF) ? "RXOF " : "", -+ (intr & AG71XX_INT_RX_BE) ? "RXBE " : ""); -+} -+ -+static void ag71xx_ring_tx_clean(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->tx_ring; -+ struct net_device *dev = ag->dev; -+ int ring_mask = BIT(ring->order) - 1; -+ u32 bytes_compl = 0, pkts_compl = 0; -+ -+ while (ring->curr != ring->dirty) { -+ struct ag71xx_desc *desc; -+ u32 i = ring->dirty & ring_mask; -+ -+ desc = ag71xx_ring_desc(ring, i); -+ if (!ag71xx_desc_empty(desc)) { -+ desc->ctrl = 0; -+ dev->stats.tx_errors++; -+ } -+ -+ if (ring->buf[i].skb) { -+ bytes_compl += ring->buf[i].len; -+ pkts_compl++; -+ dev_kfree_skb_any(ring->buf[i].skb); -+ } -+ ring->buf[i].skb = NULL; -+ ring->dirty++; -+ } -+ -+ /* flush descriptors */ -+ wmb(); -+ -+ netdev_completed_queue(dev, pkts_compl, bytes_compl); -+} -+ -+static void ag71xx_ring_tx_init(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->tx_ring; -+ int ring_size = BIT(ring->order); -+ int ring_mask = BIT(ring->order) - 1; -+ int i; -+ -+ for (i = 0; i < ring_size; i++) { -+ struct ag71xx_desc *desc = ag71xx_ring_desc(ring, i); -+ -+ desc->next = (u32) (ring->descs_dma + -+ AG71XX_DESC_SIZE * ((i + 1) & ring_mask)); -+ -+ desc->ctrl = DESC_EMPTY; -+ ring->buf[i].skb = NULL; -+ } -+ -+ /* flush descriptors */ -+ wmb(); -+ -+ ring->curr = 0; -+ ring->dirty = 0; -+ netdev_reset_queue(ag->dev); -+} -+ -+static void ag71xx_ring_rx_clean(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ int ring_size = BIT(ring->order); -+ int i; -+ -+ if (!ring->buf) -+ return; -+ -+ for (i = 0; i < ring_size; i++) -+ if (ring->buf[i].rx_buf) { -+ dma_unmap_single(&ag->pdev->dev, ring->buf[i].dma_addr, -+ ag->rx_buf_size, DMA_FROM_DEVICE); -+ skb_free_frag(ring->buf[i].rx_buf); -+ } -+} -+ -+static int ag71xx_buffer_offset(struct ag71xx *ag) -+{ -+ int offset = NET_SKB_PAD; -+ -+ /* -+ * On AR71xx/AR91xx packets must be 4-byte aligned. -+ * -+ * When using builtin AR8216 support, hardware adds a 2-byte header, -+ * so we don't need any extra alignment in that case. -+ */ -+ if (!ag71xx_get_pdata(ag)->is_ar724x || ag71xx_has_ar8216(ag)) -+ return offset; -+ -+ return offset + NET_IP_ALIGN; -+} -+ -+static int ag71xx_buffer_size(struct ag71xx *ag) -+{ -+ return ag->rx_buf_size + -+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -+} -+ -+static bool ag71xx_fill_rx_buf(struct ag71xx *ag, struct ag71xx_buf *buf, -+ int offset, -+ void *(*alloc)(unsigned int size)) -+{ -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ struct ag71xx_desc *desc = ag71xx_ring_desc(ring, buf - &ring->buf[0]); -+ void *data; -+ -+ data = alloc(ag71xx_buffer_size(ag)); -+ if (!data) -+ return false; -+ -+ buf->rx_buf = data; -+ buf->dma_addr = dma_map_single(&ag->pdev->dev, data, ag->rx_buf_size, -+ DMA_FROM_DEVICE); -+ desc->data = (u32) buf->dma_addr + offset; -+ return true; -+} -+ -+static int ag71xx_ring_rx_init(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ int ring_size = BIT(ring->order); -+ int ring_mask = BIT(ring->order) - 1; -+ unsigned int i; -+ int ret; -+ int offset = ag71xx_buffer_offset(ag); -+ -+ ret = 0; -+ for (i = 0; i < ring_size; i++) { -+ struct ag71xx_desc *desc = ag71xx_ring_desc(ring, i); -+ -+ desc->next = (u32) (ring->descs_dma + -+ AG71XX_DESC_SIZE * ((i + 1) & ring_mask)); -+ -+ DBG("ag71xx: RX desc at %p, next is %08x\n", -+ desc, desc->next); -+ } -+ -+ for (i = 0; i < ring_size; i++) { -+ struct ag71xx_desc *desc = ag71xx_ring_desc(ring, i); -+ -+ if (!ag71xx_fill_rx_buf(ag, &ring->buf[i], offset, -+ netdev_alloc_frag)) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ desc->ctrl = DESC_EMPTY; -+ } -+ -+ /* flush descriptors */ -+ wmb(); -+ -+ ring->curr = 0; -+ ring->dirty = 0; -+ -+ return ret; -+} -+ -+static int ag71xx_ring_rx_refill(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ int ring_mask = BIT(ring->order) - 1; -+ unsigned int count; -+ int offset = ag71xx_buffer_offset(ag); -+ -+ count = 0; -+ for (; ring->curr - ring->dirty > 0; ring->dirty++) { -+ struct ag71xx_desc *desc; -+ unsigned int i; -+ -+ i = ring->dirty & ring_mask; -+ desc = ag71xx_ring_desc(ring, i); -+ -+ if (!ring->buf[i].rx_buf && -+ !ag71xx_fill_rx_buf(ag, &ring->buf[i], offset, -+ napi_alloc_frag)) -+ break; -+ -+ desc->ctrl = DESC_EMPTY; -+ count++; -+ } -+ -+ /* flush descriptors */ -+ wmb(); -+ -+ DBG("%s: %u rx descriptors refilled\n", ag->dev->name, count); -+ -+ return count; -+} -+ -+static int ag71xx_rings_init(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *tx = &ag->tx_ring; -+ struct ag71xx_ring *rx = &ag->rx_ring; -+ int ring_size = BIT(tx->order) + BIT(rx->order); -+ int tx_size = BIT(tx->order); -+ -+ tx->buf = kzalloc(ring_size * sizeof(*tx->buf), GFP_KERNEL); -+ if (!tx->buf) -+ return -ENOMEM; -+ -+ tx->descs_cpu = dma_alloc_coherent(&ag->pdev->dev, ring_size * AG71XX_DESC_SIZE, -+ &tx->descs_dma, GFP_KERNEL); -+ if (!tx->descs_cpu) { -+ kfree(tx->buf); -+ tx->buf = NULL; -+ return -ENOMEM; -+ } -+ -+ rx->buf = &tx->buf[tx_size]; -+ rx->descs_cpu = ((void *)tx->descs_cpu) + tx_size * AG71XX_DESC_SIZE; -+ rx->descs_dma = tx->descs_dma + tx_size * AG71XX_DESC_SIZE; -+ -+ ag71xx_ring_tx_init(ag); -+ return ag71xx_ring_rx_init(ag); -+} -+ -+static void ag71xx_rings_free(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *tx = &ag->tx_ring; -+ struct ag71xx_ring *rx = &ag->rx_ring; -+ int ring_size = BIT(tx->order) + BIT(rx->order); -+ -+ if (tx->descs_cpu) -+ dma_free_coherent(&ag->pdev->dev, ring_size * AG71XX_DESC_SIZE, -+ tx->descs_cpu, tx->descs_dma); -+ -+ kfree(tx->buf); -+ -+ tx->descs_cpu = NULL; -+ rx->descs_cpu = NULL; -+ tx->buf = NULL; -+ rx->buf = NULL; -+} -+ -+static void ag71xx_rings_cleanup(struct ag71xx *ag) -+{ -+ ag71xx_ring_rx_clean(ag); -+ ag71xx_ring_tx_clean(ag); -+ ag71xx_rings_free(ag); -+ -+ netdev_reset_queue(ag->dev); -+} -+ -+static unsigned char *ag71xx_speed_str(struct ag71xx *ag) -+{ -+ switch (ag->speed) { -+ case SPEED_1000: -+ return "1000"; -+ case SPEED_100: -+ return "100"; -+ case SPEED_10: -+ return "10"; -+ } -+ -+ return "?"; -+} -+ -+static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) -+{ -+ u32 t; -+ -+ t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16) -+ | (((u32) mac[3]) << 8) | ((u32) mac[2]); -+ -+ ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t); -+ -+ t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16); -+ ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t); -+} -+ -+static void ag71xx_dma_reset(struct ag71xx *ag) -+{ -+ u32 val; -+ int i; -+ -+ ag71xx_dump_dma_regs(ag); -+ -+ /* stop RX and TX */ -+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); -+ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); -+ -+ /* -+ * give the hardware some time to really stop all rx/tx activity -+ * clearing the descriptors too early causes random memory corruption -+ */ -+ mdelay(1); -+ -+ /* clear descriptor addresses */ -+ ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->stop_desc_dma); -+ ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->stop_desc_dma); -+ -+ /* clear pending RX/TX interrupts */ -+ for (i = 0; i < 256; i++) { -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); -+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); -+ } -+ -+ /* clear pending errors */ -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF); -+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR); -+ -+ val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); -+ if (val) -+ pr_alert("%s: unable to clear DMA Rx status: %08x\n", -+ ag->dev->name, val); -+ -+ val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); -+ -+ /* mask out reserved bits */ -+ val &= ~0xff000000; -+ -+ if (val) -+ pr_alert("%s: unable to clear DMA Tx status: %08x\n", -+ ag->dev->name, val); -+ -+ ag71xx_dump_dma_regs(ag); -+} -+ -+#define MAC_CFG1_INIT (MAC_CFG1_RXE | MAC_CFG1_TXE | \ -+ MAC_CFG1_SRX | MAC_CFG1_STX) -+ -+#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT) -+ -+#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \ -+ FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \ -+ FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \ -+ FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \ -+ FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \ -+ FIFO_CFG4_VT) -+ -+#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \ -+ FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \ -+ FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \ -+ FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \ -+ FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \ -+ FIFO_CFG5_17 | FIFO_CFG5_SF) -+ -+static void ag71xx_hw_stop(struct ag71xx *ag) -+{ -+ /* disable all interrupts and stop the rx/tx engine */ -+ ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0); -+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); -+ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); -+} -+ -+static void ag71xx_hw_setup(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ u32 init = MAC_CFG1_INIT; -+ -+ /* setup MAC configuration registers */ -+ if (pdata->use_flow_control) -+ init |= MAC_CFG1_TFC | MAC_CFG1_RFC; -+ ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, init); -+ -+ ag71xx_sb(ag, AG71XX_REG_MAC_CFG2, -+ MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK); -+ -+ /* setup max frame length to zero */ -+ ag71xx_wr(ag, AG71XX_REG_MAC_MFL, 0); -+ -+ /* setup FIFO configuration registers */ -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT); -+ if (pdata->is_ar724x) { -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0010ffff); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x015500aa); -+ } else { -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff); -+ } -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT); -+} -+ -+static void ag71xx_hw_init(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ u32 reset_mask = pdata->reset_bit; -+ -+ ag71xx_hw_stop(ag); -+ -+ if (pdata->is_ar724x) { -+ u32 reset_phy = reset_mask; -+ -+ reset_phy &= AR71XX_RESET_GE0_PHY | AR71XX_RESET_GE1_PHY; -+ reset_mask &= ~(AR71XX_RESET_GE0_PHY | AR71XX_RESET_GE1_PHY); -+ -+ ath79_device_reset_set(reset_phy); -+ msleep(50); -+ ath79_device_reset_clear(reset_phy); -+ msleep(200); -+ } -+ -+ ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR); -+ udelay(20); -+ -+ ath79_device_reset_set(reset_mask); -+ msleep(100); -+ ath79_device_reset_clear(reset_mask); -+ msleep(200); -+ -+ ag71xx_hw_setup(ag); -+ -+ ag71xx_dma_reset(ag); -+} -+ -+static void ag71xx_fast_reset(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ struct net_device *dev = ag->dev; -+ u32 reset_mask = pdata->reset_bit; -+ u32 rx_ds; -+ u32 mii_reg; -+ -+ reset_mask &= AR71XX_RESET_GE0_MAC | AR71XX_RESET_GE1_MAC; -+ -+ ag71xx_hw_stop(ag); -+ wmb(); -+ -+ mii_reg = ag71xx_rr(ag, AG71XX_REG_MII_CFG); -+ rx_ds = ag71xx_rr(ag, AG71XX_REG_RX_DESC); -+ -+ ag71xx_tx_packets(ag, true); -+ -+ ath79_device_reset_set(reset_mask); -+ udelay(10); -+ ath79_device_reset_clear(reset_mask); -+ udelay(10); -+ -+ ag71xx_dma_reset(ag); -+ ag71xx_hw_setup(ag); -+ ag->tx_ring.curr = 0; -+ ag->tx_ring.dirty = 0; -+ netdev_reset_queue(ag->dev); -+ -+ /* setup max frame length */ -+ ag71xx_wr(ag, AG71XX_REG_MAC_MFL, -+ ag71xx_max_frame_len(ag->dev->mtu)); -+ -+ ag71xx_wr(ag, AG71XX_REG_RX_DESC, rx_ds); -+ ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->tx_ring.descs_dma); -+ ag71xx_wr(ag, AG71XX_REG_MII_CFG, mii_reg); -+ -+ ag71xx_hw_set_macaddr(ag, dev->dev_addr); -+} -+ -+static void ag71xx_hw_start(struct ag71xx *ag) -+{ -+ /* start RX engine */ -+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); -+ -+ /* enable interrupts */ -+ ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT); -+ -+ netif_wake_queue(ag->dev); -+} -+ -+static void -+__ag71xx_link_adjust(struct ag71xx *ag, bool update) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ u32 cfg2; -+ u32 ifctl; -+ u32 fifo5; -+ u32 fifo3; -+ -+ if (!ag->link && update) { -+ ag71xx_hw_stop(ag); -+ netif_carrier_off(ag->dev); -+ if (netif_msg_link(ag)) -+ pr_info("%s: link down\n", ag->dev->name); -+ return; -+ } -+ -+ if (pdata->is_ar724x) -+ ag71xx_fast_reset(ag); -+ -+ cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2); -+ cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX); -+ cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0; -+ -+ ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL); -+ ifctl &= ~(MAC_IFCTL_SPEED); -+ -+ fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5); -+ fifo5 &= ~FIFO_CFG5_BM; -+ -+ switch (ag->speed) { -+ case SPEED_1000: -+ cfg2 |= MAC_CFG2_IF_1000; -+ fifo5 |= FIFO_CFG5_BM; -+ break; -+ case SPEED_100: -+ cfg2 |= MAC_CFG2_IF_10_100; -+ ifctl |= MAC_IFCTL_SPEED; -+ break; -+ case SPEED_10: -+ cfg2 |= MAC_CFG2_IF_10_100; -+ break; -+ default: -+ BUG(); -+ return; -+ } -+ -+ if (pdata->is_ar91xx) -+ fifo3 = 0x00780fff; -+ else if (pdata->is_ar724x) -+ fifo3 = 0x01f00140; -+ else -+ fifo3 = 0x008001ff; -+ -+ if (ag->tx_ring.desc_split) { -+ fifo3 &= 0xffff; -+ fifo3 |= ((2048 - ag->tx_ring.desc_split) / 4) << 16; -+ } -+ -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, fifo3); -+ -+ if (update && pdata->set_speed) -+ pdata->set_speed(ag->speed); -+ -+ if (update && pdata->enable_sgmii_fixup) -+ ag71xx_qca955x_sgmii_init(); -+ -+ ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5); -+ ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl); -+ -+ if (pdata->disable_inline_checksum_engine) { -+ /* -+ * The rx ring buffer can stall on small packets on QCA953x and -+ * QCA956x. Disabling the inline checksum engine fixes the stall. -+ * The wr, rr functions cannot be used since this hidden register -+ * is outside of the normal ag71xx register block. -+ */ -+ void __iomem *dam = ioremap_nocache(0xb90001bc, 0x4); -+ if (dam) { -+ __raw_writel(__raw_readl(dam) & ~BIT(27), dam); -+ (void)__raw_readl(dam); -+ iounmap(dam); -+ } -+ } -+ -+ ag71xx_hw_start(ag); -+ -+ netif_carrier_on(ag->dev); -+ if (update && netif_msg_link(ag)) -+ pr_info("%s: link up (%sMbps/%s duplex)\n", -+ ag->dev->name, -+ ag71xx_speed_str(ag), -+ (DUPLEX_FULL == ag->duplex) ? "Full" : "Half"); -+ -+ ag71xx_dump_regs(ag); -+} -+ -+void ag71xx_link_adjust(struct ag71xx *ag) -+{ -+ __ag71xx_link_adjust(ag, true); -+} -+ -+static int ag71xx_hw_enable(struct ag71xx *ag) -+{ -+ int ret; -+ -+ ret = ag71xx_rings_init(ag); -+ if (ret) -+ return ret; -+ -+ napi_enable(&ag->napi); -+ ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->tx_ring.descs_dma); -+ ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->rx_ring.descs_dma); -+ netif_start_queue(ag->dev); -+ -+ return 0; -+} -+ -+static void ag71xx_hw_disable(struct ag71xx *ag) -+{ -+ netif_stop_queue(ag->dev); -+ -+ ag71xx_hw_stop(ag); -+ ag71xx_dma_reset(ag); -+ -+ napi_disable(&ag->napi); -+ del_timer_sync(&ag->oom_timer); -+ -+ ag71xx_rings_cleanup(ag); -+} -+ -+static int ag71xx_open(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ unsigned int max_frame_len; -+ int ret; -+ -+ netif_carrier_off(dev); -+ max_frame_len = ag71xx_max_frame_len(dev->mtu); -+ ag->rx_buf_size = SKB_DATA_ALIGN(max_frame_len + NET_SKB_PAD + NET_IP_ALIGN); -+ -+ /* setup max frame length */ -+ ag71xx_wr(ag, AG71XX_REG_MAC_MFL, max_frame_len); -+ ag71xx_hw_set_macaddr(ag, dev->dev_addr); -+ -+ ret = ag71xx_hw_enable(ag); -+ if (ret) -+ goto err; -+ -+ ag71xx_phy_start(ag); -+ -+ return 0; -+ -+err: -+ ag71xx_rings_cleanup(ag); -+ return ret; -+} -+ -+static int ag71xx_stop(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ -+ netif_carrier_off(dev); -+ ag71xx_phy_stop(ag); -+ ag71xx_hw_disable(ag); -+ -+ return 0; -+} -+ -+static int ag71xx_fill_dma_desc(struct ag71xx_ring *ring, u32 addr, int len) -+{ -+ int i; -+ struct ag71xx_desc *desc; -+ int ring_mask = BIT(ring->order) - 1; -+ int ndesc = 0; -+ int split = ring->desc_split; -+ -+ if (!split) -+ split = len; -+ -+ while (len > 0) { -+ unsigned int cur_len = len; -+ -+ i = (ring->curr + ndesc) & ring_mask; -+ desc = ag71xx_ring_desc(ring, i); -+ -+ if (!ag71xx_desc_empty(desc)) -+ return -1; -+ -+ if (cur_len > split) { -+ cur_len = split; -+ -+ /* -+ * TX will hang if DMA transfers <= 4 bytes, -+ * make sure next segment is more than 4 bytes long. -+ */ -+ if (len <= split + 4) -+ cur_len -= 4; -+ } -+ -+ desc->data = addr; -+ addr += cur_len; -+ len -= cur_len; -+ -+ if (len > 0) -+ cur_len |= DESC_MORE; -+ -+ /* prevent early tx attempt of this descriptor */ -+ if (!ndesc) -+ cur_len |= DESC_EMPTY; -+ -+ desc->ctrl = cur_len; -+ ndesc++; -+ } -+ -+ return ndesc; -+} -+ -+static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb, -+ struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ struct ag71xx_ring *ring = &ag->tx_ring; -+ int ring_mask = BIT(ring->order) - 1; -+ int ring_size = BIT(ring->order); -+ struct ag71xx_desc *desc; -+ dma_addr_t dma_addr; -+ int i, n, ring_min; -+ -+ if (ag71xx_has_ar8216(ag)) -+ ag71xx_add_ar8216_header(ag, skb); -+ -+ if (skb->len <= 4) { -+ DBG("%s: packet len is too small\n", ag->dev->name); -+ goto err_drop; -+ } -+ -+ dma_addr = dma_map_single(&ag->pdev->dev, skb->data, skb->len, -+ DMA_TO_DEVICE); -+ -+ i = ring->curr & ring_mask; -+ desc = ag71xx_ring_desc(ring, i); -+ -+ /* setup descriptor fields */ -+ n = ag71xx_fill_dma_desc(ring, (u32) dma_addr, skb->len & ag->desc_pktlen_mask); -+ if (n < 0) -+ goto err_drop_unmap; -+ -+ i = (ring->curr + n - 1) & ring_mask; -+ ring->buf[i].len = skb->len; -+ ring->buf[i].skb = skb; -+ -+ netdev_sent_queue(dev, skb->len); -+ -+ skb_tx_timestamp(skb); -+ -+ desc->ctrl &= ~DESC_EMPTY; -+ ring->curr += n; -+ -+ /* flush descriptor */ -+ wmb(); -+ -+ ring_min = 2; -+ if (ring->desc_split) -+ ring_min *= AG71XX_TX_RING_DS_PER_PKT; -+ -+ if (ring->curr - ring->dirty >= ring_size - ring_min) { -+ DBG("%s: tx queue full\n", dev->name); -+ netif_stop_queue(dev); -+ } -+ -+ DBG("%s: packet injected into TX queue\n", ag->dev->name); -+ -+ /* enable TX engine */ -+ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE); -+ -+ return NETDEV_TX_OK; -+ -+err_drop_unmap: -+ dma_unmap_single(&ag->pdev->dev, dma_addr, skb->len, DMA_TO_DEVICE); -+ -+err_drop: -+ dev->stats.tx_dropped++; -+ -+ dev_kfree_skb(skb); -+ return NETDEV_TX_OK; -+} -+ -+static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ -+ switch (cmd) { -+ case SIOCSIFHWADDR: -+ if (copy_from_user -+ (dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr))) -+ return -EFAULT; -+ return 0; -+ -+ case SIOCGIFHWADDR: -+ if (copy_to_user -+ (ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr))) -+ return -EFAULT; -+ return 0; -+ -+ case SIOCGMIIPHY: -+ case SIOCGMIIREG: -+ case SIOCSMIIREG: -+ if (ag->phy_dev == NULL) -+ break; -+ -+ return phy_mii_ioctl(ag->phy_dev, ifr, cmd); -+ -+ default: -+ break; -+ } -+ -+ return -EOPNOTSUPP; -+} -+ -+static void ag71xx_oom_timer_handler(unsigned long data) -+{ -+ struct net_device *dev = (struct net_device *) data; -+ struct ag71xx *ag = netdev_priv(dev); -+ -+ napi_schedule(&ag->napi); -+} -+ -+static void ag71xx_tx_timeout(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ -+ if (netif_msg_tx_err(ag)) -+ pr_info("%s: tx timeout\n", ag->dev->name); -+ -+ schedule_delayed_work(&ag->restart_work, 1); -+} -+ -+static void ag71xx_bit_set(void __iomem *reg, u32 bit) -+{ -+ u32 val = __raw_readl(reg) | bit; -+ __raw_writel(val, reg); -+ __raw_readl(reg); -+} -+ -+static void ag71xx_bit_clear(void __iomem *reg, u32 bit) -+{ -+ u32 val = __raw_readl(reg) & ~bit; -+ __raw_writel(val, reg); -+ __raw_readl(reg); -+} -+ -+static void ag71xx_qca955x_sgmii_init() -+{ -+ void __iomem *gmac_base; -+ u32 mr_an_status, sgmii_status; -+ u8 tries = 0; -+ -+ gmac_base = ioremap_nocache(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE); -+ -+ if (!gmac_base) -+ goto sgmii_out; -+ -+ mr_an_status = __raw_readl(gmac_base + QCA955X_GMAC_REG_MR_AN_STATUS); -+ if (!(mr_an_status & QCA955X_MR_AN_STATUS_AN_ABILITY)) -+ goto sgmii_out; -+ -+ __raw_writel(QCA955X_SGMII_RESET_RX_CLK_N_RESET , -+ gmac_base + QCA955X_GMAC_REG_SGMII_RESET); -+ __raw_readl(gmac_base + QCA955X_GMAC_REG_SGMII_RESET); -+ udelay(10); -+ -+ /* Init sequence */ -+ ag71xx_bit_set(gmac_base + QCA955X_GMAC_REG_SGMII_RESET, -+ QCA955X_SGMII_RESET_HW_RX_125M_N); -+ udelay(10); -+ -+ ag71xx_bit_set(gmac_base + QCA955X_GMAC_REG_SGMII_RESET, -+ QCA955X_SGMII_RESET_RX_125M_N); -+ udelay(10); -+ -+ ag71xx_bit_set(gmac_base + QCA955X_GMAC_REG_SGMII_RESET, -+ QCA955X_SGMII_RESET_TX_125M_N); -+ udelay(10); -+ -+ ag71xx_bit_set(gmac_base + QCA955X_GMAC_REG_SGMII_RESET, -+ QCA955X_SGMII_RESET_RX_CLK_N); -+ udelay(10); -+ -+ ag71xx_bit_set(gmac_base + QCA955X_GMAC_REG_SGMII_RESET, -+ QCA955X_SGMII_RESET_TX_CLK_N); -+ udelay(10); -+ -+ do { -+ ag71xx_bit_set(gmac_base + QCA955X_GMAC_REG_MR_AN_CONTROL, -+ QCA955X_MR_AN_CONTROL_PHY_RESET | -+ QCA955X_MR_AN_CONTROL_AN_ENABLE); -+ udelay(100); -+ ag71xx_bit_clear(gmac_base + QCA955X_GMAC_REG_MR_AN_CONTROL, -+ QCA955X_MR_AN_CONTROL_PHY_RESET); -+ mdelay(10); -+ sgmii_status = __raw_readl(gmac_base + QCA955X_GMAC_REG_SGMII_DEBUG) & 0xF; -+ -+ if (tries++ >= QCA955X_SGMII_LINK_WAR_MAX_TRY) { -+ pr_warn("ag71xx: max retries for SGMII fixup exceeded!\n"); -+ break; -+ } -+ } while (!(sgmii_status == 0xf || sgmii_status == 0x10)); -+ -+sgmii_out: -+ iounmap(gmac_base); -+} -+ -+static void ag71xx_restart_work_func(struct work_struct *work) -+{ -+ struct ag71xx *ag = container_of(work, struct ag71xx, restart_work.work); -+ -+ rtnl_lock(); -+ ag71xx_hw_disable(ag); -+ ag71xx_hw_enable(ag); -+ if (ag->link) -+ __ag71xx_link_adjust(ag, false); -+ rtnl_unlock(); -+} -+ -+static bool ag71xx_check_dma_stuck(struct ag71xx *ag) -+{ -+ unsigned long timestamp; -+ u32 rx_sm, tx_sm, rx_fd; -+ -+ timestamp = netdev_get_tx_queue(ag->dev, 0)->trans_start; -+ if (likely(time_before(jiffies, timestamp + HZ/10))) -+ return false; -+ -+ if (!netif_carrier_ok(ag->dev)) -+ return false; -+ -+ rx_sm = ag71xx_rr(ag, AG71XX_REG_RX_SM); -+ if ((rx_sm & 0x7) == 0x3 && ((rx_sm >> 4) & 0x7) == 0x6) -+ return true; -+ -+ tx_sm = ag71xx_rr(ag, AG71XX_REG_TX_SM); -+ rx_fd = ag71xx_rr(ag, AG71XX_REG_FIFO_DEPTH); -+ if (((tx_sm >> 4) & 0x7) == 0 && ((rx_sm & 0x7) == 0) && -+ ((rx_sm >> 4) & 0x7) == 0 && rx_fd == 0) -+ return true; -+ -+ return false; -+} -+ -+static int ag71xx_tx_packets(struct ag71xx *ag, bool flush) -+{ -+ struct ag71xx_ring *ring = &ag->tx_ring; -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ bool dma_stuck = false; -+ int ring_mask = BIT(ring->order) - 1; -+ int ring_size = BIT(ring->order); -+ int sent = 0; -+ int bytes_compl = 0; -+ int n = 0; -+ -+ DBG("%s: processing TX ring\n", ag->dev->name); -+ -+ while (ring->dirty + n != ring->curr) { -+ unsigned int i = (ring->dirty + n) & ring_mask; -+ struct ag71xx_desc *desc = ag71xx_ring_desc(ring, i); -+ struct sk_buff *skb = ring->buf[i].skb; -+ -+ if (!flush && !ag71xx_desc_empty(desc)) { -+ if (pdata->is_ar724x && -+ ag71xx_check_dma_stuck(ag)) { -+ schedule_delayed_work(&ag->restart_work, HZ / 2); -+ dma_stuck = true; -+ } -+ break; -+ } -+ -+ if (flush) -+ desc->ctrl |= DESC_EMPTY; -+ -+ n++; -+ if (!skb) -+ continue; -+ -+ dev_kfree_skb_any(skb); -+ ring->buf[i].skb = NULL; -+ -+ bytes_compl += ring->buf[i].len; -+ -+ sent++; -+ ring->dirty += n; -+ -+ while (n > 0) { -+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); -+ n--; -+ } -+ } -+ -+ DBG("%s: %d packets sent out\n", ag->dev->name, sent); -+ -+ if (!sent) -+ return 0; -+ -+ ag->dev->stats.tx_bytes += bytes_compl; -+ ag->dev->stats.tx_packets += sent; -+ -+ netdev_completed_queue(ag->dev, sent, bytes_compl); -+ if ((ring->curr - ring->dirty) < (ring_size * 3) / 4) -+ netif_wake_queue(ag->dev); -+ -+ if (!dma_stuck) -+ cancel_delayed_work(&ag->restart_work); -+ -+ return sent; -+} -+ -+static int ag71xx_rx_packets(struct ag71xx *ag, int limit) -+{ -+ struct net_device *dev = ag->dev; -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ int offset = ag71xx_buffer_offset(ag); -+ unsigned int pktlen_mask = ag->desc_pktlen_mask; -+ int ring_mask = BIT(ring->order) - 1; -+ int ring_size = BIT(ring->order); -+ struct sk_buff_head queue; -+ struct sk_buff *skb; -+ int done = 0; -+ -+ DBG("%s: rx packets, limit=%d, curr=%u, dirty=%u\n", -+ dev->name, limit, ring->curr, ring->dirty); -+ -+ skb_queue_head_init(&queue); -+ -+ while (done < limit) { -+ unsigned int i = ring->curr & ring_mask; -+ struct ag71xx_desc *desc = ag71xx_ring_desc(ring, i); -+ int pktlen; -+ int err = 0; -+ -+ if (ag71xx_desc_empty(desc)) -+ break; -+ -+ if ((ring->dirty + ring_size) == ring->curr) { -+ ag71xx_assert(0); -+ break; -+ } -+ -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); -+ -+ pktlen = desc->ctrl & pktlen_mask; -+ pktlen -= ETH_FCS_LEN; -+ -+ dma_unmap_single(&ag->pdev->dev, ring->buf[i].dma_addr, -+ ag->rx_buf_size, DMA_FROM_DEVICE); -+ -+ dev->stats.rx_packets++; -+ dev->stats.rx_bytes += pktlen; -+ -+ skb = build_skb(ring->buf[i].rx_buf, ag71xx_buffer_size(ag)); -+ if (!skb) { -+ skb_free_frag(ring->buf[i].rx_buf); -+ goto next; -+ } -+ -+ skb_reserve(skb, offset); -+ skb_put(skb, pktlen); -+ -+ if (ag71xx_has_ar8216(ag)) -+ err = ag71xx_remove_ar8216_header(ag, skb, pktlen); -+ -+ if (err) { -+ dev->stats.rx_dropped++; -+ kfree_skb(skb); -+ } else { -+ skb->dev = dev; -+ skb->ip_summed = CHECKSUM_NONE; -+ __skb_queue_tail(&queue, skb); -+ } -+ -+next: -+ ring->buf[i].rx_buf = NULL; -+ done++; -+ -+ ring->curr++; -+ } -+ -+ ag71xx_ring_rx_refill(ag); -+ -+ while ((skb = __skb_dequeue(&queue)) != NULL) { -+ skb->protocol = eth_type_trans(skb, dev); -+ netif_receive_skb(skb); -+ } -+ -+ DBG("%s: rx finish, curr=%u, dirty=%u, done=%d\n", -+ dev->name, ring->curr, ring->dirty, done); -+ -+ return done; -+} -+ -+static int ag71xx_poll(struct napi_struct *napi, int limit) -+{ -+ struct ag71xx *ag = container_of(napi, struct ag71xx, napi); -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ struct net_device *dev = ag->dev; -+ struct ag71xx_ring *rx_ring = &ag->rx_ring; -+ int rx_ring_size = BIT(rx_ring->order); -+ unsigned long flags; -+ u32 status; -+ int tx_done; -+ int rx_done; -+ -+ pdata->ddr_flush(); -+ tx_done = ag71xx_tx_packets(ag, false); -+ -+ DBG("%s: processing RX ring\n", dev->name); -+ rx_done = ag71xx_rx_packets(ag, limit); -+ -+ ag71xx_debugfs_update_napi_stats(ag, rx_done, tx_done); -+ -+ if (rx_ring->buf[rx_ring->dirty % rx_ring_size].rx_buf == NULL) -+ goto oom; -+ -+ status = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); -+ if (unlikely(status & RX_STATUS_OF)) { -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF); -+ dev->stats.rx_fifo_errors++; -+ -+ /* restart RX */ -+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); -+ } -+ -+ if (rx_done < limit) { -+ if (status & RX_STATUS_PR) -+ goto more; -+ -+ status = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); -+ if (status & TX_STATUS_PS) -+ goto more; -+ -+ DBG("%s: disable polling mode, rx=%d, tx=%d,limit=%d\n", -+ dev->name, rx_done, tx_done, limit); -+ -+ napi_complete(napi); -+ -+ /* enable interrupts */ -+ spin_lock_irqsave(&ag->lock, flags); -+ ag71xx_int_enable(ag, AG71XX_INT_POLL); -+ spin_unlock_irqrestore(&ag->lock, flags); -+ return rx_done; -+ } -+ -+more: -+ DBG("%s: stay in polling mode, rx=%d, tx=%d, limit=%d\n", -+ dev->name, rx_done, tx_done, limit); -+ return limit; -+ -+oom: -+ if (netif_msg_rx_err(ag)) -+ pr_info("%s: out of memory\n", dev->name); -+ -+ mod_timer(&ag->oom_timer, jiffies + AG71XX_OOM_REFILL); -+ napi_complete(napi); -+ return 0; -+} -+ -+static irqreturn_t ag71xx_interrupt(int irq, void *dev_id) -+{ -+ struct net_device *dev = dev_id; -+ struct ag71xx *ag = netdev_priv(dev); -+ u32 status; -+ -+ status = ag71xx_rr(ag, AG71XX_REG_INT_STATUS); -+ ag71xx_dump_intr(ag, "raw", status); -+ -+ if (unlikely(!status)) -+ return IRQ_NONE; -+ -+ if (unlikely(status & AG71XX_INT_ERR)) { -+ if (status & AG71XX_INT_TX_BE) { -+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE); -+ dev_err(&dev->dev, "TX BUS error\n"); -+ } -+ if (status & AG71XX_INT_RX_BE) { -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE); -+ dev_err(&dev->dev, "RX BUS error\n"); -+ } -+ } -+ -+ if (likely(status & AG71XX_INT_POLL)) { -+ ag71xx_int_disable(ag, AG71XX_INT_POLL); -+ DBG("%s: enable polling mode\n", dev->name); -+ napi_schedule(&ag->napi); -+ } -+ -+ ag71xx_debugfs_update_int_stats(ag, status); -+ -+ return IRQ_HANDLED; -+} -+ -+#ifdef CONFIG_NET_POLL_CONTROLLER -+/* -+ * Polling 'interrupt' - used by things like netconsole to send skbs -+ * without having to re-enable interrupts. It's not called while -+ * the interrupt routine is executing. -+ */ -+static void ag71xx_netpoll(struct net_device *dev) -+{ -+ disable_irq(dev->irq); -+ ag71xx_interrupt(dev->irq, dev); -+ enable_irq(dev->irq); -+} -+#endif -+ -+static int ag71xx_change_mtu(struct net_device *dev, int new_mtu) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ unsigned int max_frame_len; -+ -+ max_frame_len = ag71xx_max_frame_len(new_mtu); -+ if (new_mtu < 68 || max_frame_len > ag->max_frame_len) -+ return -EINVAL; -+ -+ if (netif_running(dev)) -+ return -EBUSY; -+ -+ dev->mtu = new_mtu; -+ ag71xx_wr(ag, AG71XX_REG_MAC_MFL, -+ ag71xx_max_frame_len(dev->mtu)); -+ -+ return 0; -+} -+ -+static const struct net_device_ops ag71xx_netdev_ops = { -+ .ndo_open = ag71xx_open, -+ .ndo_stop = ag71xx_stop, -+ .ndo_start_xmit = ag71xx_hard_start_xmit, -+ .ndo_do_ioctl = ag71xx_do_ioctl, -+ .ndo_tx_timeout = ag71xx_tx_timeout, -+ .ndo_change_mtu = ag71xx_change_mtu, -+ .ndo_set_mac_address = eth_mac_addr, -+ .ndo_validate_addr = eth_validate_addr, -+#ifdef CONFIG_NET_POLL_CONTROLLER -+ .ndo_poll_controller = ag71xx_netpoll, -+#endif -+}; -+ -+static int ag71xx_probe(struct platform_device *pdev) -+{ -+ struct net_device *dev; -+ struct resource *res; -+ struct ag71xx *ag; -+ struct ag71xx_platform_data *pdata; -+ int tx_size, err; -+ -+ pdata = pdev->dev.platform_data; -+ if (!pdata) { -+ dev_err(&pdev->dev, "no platform data specified\n"); -+ return -ENXIO; -+ -+ } -+ -+ if (pdata->mii_bus_dev == NULL && pdata->phy_mask) { -+ dev_err(&pdev->dev, "no MII bus device specified\n"); -+ return -EINVAL; -+ } -+ -+ dev = devm_alloc_etherdev(&pdev->dev, sizeof(*ag)); -+ if (!dev) -+ return -ENOMEM; -+ -+ if (!pdata->max_frame_len || !pdata->desc_pktlen_mask) -+ return -EINVAL; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -EINVAL; -+ -+ SET_NETDEV_DEV(dev, &pdev->dev); -+ -+ ag = netdev_priv(dev); -+ ag->pdev = pdev; -+ ag->dev = dev; -+ ag->msg_enable = netif_msg_init(ag71xx_msg_level, -+ AG71XX_DEFAULT_MSG_ENABLE); -+ spin_lock_init(&ag->lock); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac_base"); -+ if (!res) { -+ dev_err(&pdev->dev, "no mac_base resource found\n"); -+ return -ENXIO; -+ } -+ -+ ag->mac_base = devm_ioremap_nocache(&pdev->dev, res->start, -+ res->end - res->start + 1); -+ if (!ag->mac_base) -+ return -ENOMEM; -+ -+ dev->irq = platform_get_irq(pdev, 0); -+ err = devm_request_irq(&pdev->dev, dev->irq, ag71xx_interrupt, -+ 0x0, dev_name(&pdev->dev), dev); -+ if (err) { -+ dev_err(&pdev->dev, "unable to request IRQ %d\n", dev->irq); -+ return err; -+ } -+ -+ dev->base_addr = (unsigned long)ag->mac_base; -+ dev->netdev_ops = &ag71xx_netdev_ops; -+ dev->ethtool_ops = &ag71xx_ethtool_ops; -+ -+ INIT_DELAYED_WORK(&ag->restart_work, ag71xx_restart_work_func); -+ -+ init_timer(&ag->oom_timer); -+ ag->oom_timer.data = (unsigned long) dev; -+ ag->oom_timer.function = ag71xx_oom_timer_handler; -+ -+ tx_size = AG71XX_TX_RING_SIZE_DEFAULT; -+ ag->rx_ring.order = ag71xx_ring_size_order(AG71XX_RX_RING_SIZE_DEFAULT); -+ -+ ag->max_frame_len = pdata->max_frame_len; -+ ag->desc_pktlen_mask = pdata->desc_pktlen_mask; -+ -+ if (!pdata->is_ar724x && !pdata->is_ar91xx) { -+ ag->tx_ring.desc_split = AG71XX_TX_RING_SPLIT; -+ tx_size *= AG71XX_TX_RING_DS_PER_PKT; -+ } -+ ag->tx_ring.order = ag71xx_ring_size_order(tx_size); -+ -+ ag->stop_desc = dmam_alloc_coherent(&pdev->dev, -+ sizeof(struct ag71xx_desc), -+ &ag->stop_desc_dma, GFP_KERNEL); -+ -+ if (!ag->stop_desc) -+ return -ENOMEM; -+ -+ ag->stop_desc->data = 0; -+ ag->stop_desc->ctrl = 0; -+ ag->stop_desc->next = (u32) ag->stop_desc_dma; -+ -+ memcpy(dev->dev_addr, pdata->mac_addr, ETH_ALEN); -+ -+ netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT); -+ -+ ag71xx_dump_regs(ag); -+ -+ ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, 0); -+ -+ ag71xx_hw_init(ag); -+ -+ ag71xx_dump_regs(ag); -+ -+ err = ag71xx_phy_connect(ag); -+ if (err) -+ return err; -+ -+ err = ag71xx_debugfs_init(ag); -+ if (err) -+ goto err_phy_disconnect; -+ -+ platform_set_drvdata(pdev, dev); -+ -+ err = register_netdev(dev); -+ if (err) { -+ dev_err(&pdev->dev, "unable to register net device\n"); -+ platform_set_drvdata(pdev, NULL); -+ ag71xx_debugfs_exit(ag); -+ goto err_phy_disconnect; -+ } -+ -+ pr_info("%s: Atheros AG71xx at 0x%08lx, irq %d, mode: %s\n", -+ dev->name, (unsigned long) ag->mac_base, dev->irq, -+ phy_modes(pdata->phy_if_mode)); -+ -+ return 0; -+ -+err_phy_disconnect: -+ ag71xx_phy_disconnect(ag); -+ return err; -+} -+ -+static int ag71xx_remove(struct platform_device *pdev) -+{ -+ struct net_device *dev = platform_get_drvdata(pdev); -+ struct ag71xx *ag; -+ -+ if (!dev) -+ return 0; -+ -+ ag = netdev_priv(dev); -+ ag71xx_debugfs_exit(ag); -+ ag71xx_phy_disconnect(ag); -+ unregister_netdev(dev); -+ platform_set_drvdata(pdev, NULL); -+ return 0; -+} -+ -+static struct platform_driver ag71xx_driver = { -+ .probe = ag71xx_probe, -+ .remove = ag71xx_remove, -+ .driver = { -+ .name = AG71XX_DRV_NAME, -+ } -+}; -+ -+static int __init ag71xx_module_init(void) -+{ -+ int ret; -+ -+ ret = ag71xx_debugfs_root_init(); -+ if (ret) -+ goto err_out; -+ -+ ret = ag71xx_mdio_driver_init(); -+ if (ret) -+ goto err_debugfs_exit; -+ -+ ret = platform_driver_register(&ag71xx_driver); -+ if (ret) -+ goto err_mdio_exit; -+ -+ return 0; -+ -+err_mdio_exit: -+ ag71xx_mdio_driver_exit(); -+err_debugfs_exit: -+ ag71xx_debugfs_root_exit(); -+err_out: -+ return ret; -+} -+ -+static void __exit ag71xx_module_exit(void) -+{ -+ platform_driver_unregister(&ag71xx_driver); -+ ag71xx_mdio_driver_exit(); -+ ag71xx_debugfs_root_exit(); -+} -+ -+module_init(ag71xx_module_init); -+module_exit(ag71xx_module_exit); -+ -+MODULE_VERSION(AG71XX_DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_AUTHOR("Imre Kaloz "); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" AG71XX_DRV_NAME); -diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c -new file mode 100644 -index 0000000000..cf41aa8a3f ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c -@@ -0,0 +1,320 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "ag71xx.h" -+ -+#define AG71XX_MDIO_RETRY 1000 -+#define AG71XX_MDIO_DELAY 5 -+ -+static inline void ag71xx_mdio_wr(struct ag71xx_mdio *am, unsigned reg, -+ u32 value) -+{ -+ void __iomem *r; -+ -+ r = am->mdio_base + reg; -+ __raw_writel(value, r); -+ -+ /* flush write */ -+ (void) __raw_readl(r); -+} -+ -+static inline u32 ag71xx_mdio_rr(struct ag71xx_mdio *am, unsigned reg) -+{ -+ return __raw_readl(am->mdio_base + reg); -+} -+ -+static void ag71xx_mdio_dump_regs(struct ag71xx_mdio *am) -+{ -+ DBG("%s: mii_cfg=%08x, mii_cmd=%08x, mii_addr=%08x\n", -+ am->mii_bus->name, -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_CFG), -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_CMD), -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_ADDR)); -+ DBG("%s: mii_ctrl=%08x, mii_status=%08x, mii_ind=%08x\n", -+ am->mii_bus->name, -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_CTRL), -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS), -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_IND)); -+} -+ -+static int ag71xx_mdio_wait_busy(struct ag71xx_mdio *am) -+{ -+ int i; -+ -+ for (i = 0; i < AG71XX_MDIO_RETRY; i++) { -+ u32 busy; -+ -+ udelay(AG71XX_MDIO_DELAY); -+ -+ busy = ag71xx_mdio_rr(am, AG71XX_REG_MII_IND); -+ if (!busy) -+ return 0; -+ -+ udelay(AG71XX_MDIO_DELAY); -+ } -+ -+ pr_err("%s: MDIO operation timed out\n", am->mii_bus->name); -+ -+ return -ETIMEDOUT; -+} -+ -+int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg) -+{ -+ int err; -+ int ret; -+ -+ err = ag71xx_mdio_wait_busy(am); -+ if (err) -+ return 0xffff; -+ -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE); -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR, -+ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_READ); -+ -+ err = ag71xx_mdio_wait_busy(am); -+ if (err) -+ return 0xffff; -+ -+ ret = ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS) & 0xffff; -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE); -+ -+ DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret); -+ -+ return ret; -+} -+ -+void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val) -+{ -+ DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val); -+ -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR, -+ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CTRL, val); -+ -+ ag71xx_mdio_wait_busy(am); -+} -+ -+static const u32 ar71xx_mdio_div_table[] = { -+ 4, 4, 6, 8, 10, 14, 20, 28, -+}; -+ -+static const u32 ar7240_mdio_div_table[] = { -+ 2, 2, 4, 6, 8, 12, 18, 26, 32, 40, 48, 56, 62, 70, 78, 96, -+}; -+ -+static const u32 ar933x_mdio_div_table[] = { -+ 4, 4, 6, 8, 10, 14, 20, 28, 34, 42, 50, 58, 66, 74, 82, 98, -+}; -+ -+static int ag71xx_mdio_get_divider(struct ag71xx_mdio *am, u32 *div) -+{ -+ unsigned long ref_clock, mdio_clock; -+ const u32 *table; -+ int ndivs; -+ int i; -+ -+ ref_clock = am->pdata->ref_clock; -+ mdio_clock = am->pdata->mdio_clock; -+ -+ if (!ref_clock || !mdio_clock) -+ return -EINVAL; -+ -+ if (am->pdata->is_ar9330 || am->pdata->is_ar934x) { -+ table = ar933x_mdio_div_table; -+ ndivs = ARRAY_SIZE(ar933x_mdio_div_table); -+ } else if (am->pdata->is_ar7240) { -+ table = ar7240_mdio_div_table; -+ ndivs = ARRAY_SIZE(ar7240_mdio_div_table); -+ } else { -+ table = ar71xx_mdio_div_table; -+ ndivs = ARRAY_SIZE(ar71xx_mdio_div_table); -+ } -+ -+ for (i = 0; i < ndivs; i++) { -+ unsigned long t; -+ -+ t = ref_clock / table[i]; -+ if (t <= mdio_clock) { -+ *div = i; -+ return 0; -+ } -+ } -+ -+ dev_err(&am->mii_bus->dev, "no divider found for %lu/%lu\n", -+ ref_clock, mdio_clock); -+ return -ENOENT; -+} -+ -+static int ag71xx_mdio_reset(struct mii_bus *bus) -+{ -+ struct ag71xx_mdio *am = bus->priv; -+ u32 t; -+ int err; -+ -+ err = ag71xx_mdio_get_divider(am, &t); -+ if (err) { -+ /* fallback */ -+ if (am->pdata->is_ar7240) -+ t = MII_CFG_CLK_DIV_6; -+ else if (am->pdata->builtin_switch && !am->pdata->is_ar934x) -+ t = MII_CFG_CLK_DIV_10; -+ else if (!am->pdata->builtin_switch && am->pdata->is_ar934x) -+ t = MII_CFG_CLK_DIV_58; -+ else -+ t = MII_CFG_CLK_DIV_28; -+ } -+ -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t | MII_CFG_RESET); -+ udelay(100); -+ -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t); -+ udelay(100); -+ -+ if (am->pdata->reset) -+ am->pdata->reset(bus); -+ -+ return 0; -+} -+ -+static int ag71xx_mdio_read(struct mii_bus *bus, int addr, int reg) -+{ -+ struct ag71xx_mdio *am = bus->priv; -+ -+ if (am->pdata->builtin_switch) -+ return ar7240sw_phy_read(bus, addr, reg); -+ else -+ return ag71xx_mdio_mii_read(am, addr, reg); -+} -+ -+static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val) -+{ -+ struct ag71xx_mdio *am = bus->priv; -+ -+ if (am->pdata->builtin_switch) -+ ar7240sw_phy_write(bus, addr, reg, val); -+ else -+ ag71xx_mdio_mii_write(am, addr, reg, val); -+ return 0; -+} -+ -+static int ag71xx_mdio_probe(struct platform_device *pdev) -+{ -+ struct ag71xx_mdio_platform_data *pdata; -+ struct ag71xx_mdio *am; -+ struct resource *res; -+ int i; -+ int err; -+ -+ pdata = pdev->dev.platform_data; -+ if (!pdata) { -+ dev_err(&pdev->dev, "no platform data specified\n"); -+ return -EINVAL; -+ } -+ -+ am = kzalloc(sizeof(*am), GFP_KERNEL); -+ if (!am) { -+ err = -ENOMEM; -+ goto err_out; -+ } -+ -+ am->pdata = pdata; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "no iomem resource found\n"); -+ err = -ENXIO; -+ goto err_free_mdio; -+ } -+ -+ am->mdio_base = ioremap_nocache(res->start, res->end - res->start + 1); -+ if (!am->mdio_base) { -+ dev_err(&pdev->dev, "unable to ioremap registers\n"); -+ err = -ENOMEM; -+ goto err_free_mdio; -+ } -+ -+ am->mii_bus = mdiobus_alloc(); -+ if (am->mii_bus == NULL) { -+ err = -ENOMEM; -+ goto err_iounmap; -+ } -+ -+ am->mii_bus->name = "ag71xx_mdio"; -+ am->mii_bus->read = ag71xx_mdio_read; -+ am->mii_bus->write = ag71xx_mdio_write; -+ am->mii_bus->reset = ag71xx_mdio_reset; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) -+ am->mii_bus->irq = am->mii_irq; -+#endif -+ am->mii_bus->priv = am; -+ am->mii_bus->parent = &pdev->dev; -+ snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev)); -+ am->mii_bus->phy_mask = pdata->phy_mask; -+ -+ for (i = 0; i < PHY_MAX_ADDR; i++) -+ am->mii_bus->irq[i] = PHY_POLL; -+ -+ ag71xx_mdio_wr(am, AG71XX_REG_MAC_CFG1, 0); -+ -+ err = mdiobus_register(am->mii_bus); -+ if (err) -+ goto err_free_bus; -+ -+ ag71xx_mdio_dump_regs(am); -+ -+ platform_set_drvdata(pdev, am); -+ return 0; -+ -+err_free_bus: -+ mdiobus_free(am->mii_bus); -+err_iounmap: -+ iounmap(am->mdio_base); -+err_free_mdio: -+ kfree(am); -+err_out: -+ return err; -+} -+ -+static int ag71xx_mdio_remove(struct platform_device *pdev) -+{ -+ struct ag71xx_mdio *am = platform_get_drvdata(pdev); -+ -+ if (am) { -+ mdiobus_unregister(am->mii_bus); -+ mdiobus_free(am->mii_bus); -+ iounmap(am->mdio_base); -+ kfree(am); -+ platform_set_drvdata(pdev, NULL); -+ } -+ -+ return 0; -+} -+ -+static struct platform_driver ag71xx_mdio_driver = { -+ .probe = ag71xx_mdio_probe, -+ .remove = ag71xx_mdio_remove, -+ .driver = { -+ .name = "ag71xx-mdio", -+ } -+}; -+ -+int __init ag71xx_mdio_driver_init(void) -+{ -+ return platform_driver_register(&ag71xx_mdio_driver); -+} -+ -+void ag71xx_mdio_driver_exit(void) -+{ -+ platform_driver_unregister(&ag71xx_mdio_driver); -+} -diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_phy.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_phy.c -new file mode 100644 -index 0000000000..336143f753 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_phy.c -@@ -0,0 +1,261 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "ag71xx.h" -+ -+static void ag71xx_phy_link_adjust(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ struct phy_device *phydev = ag->phy_dev; -+ unsigned long flags; -+ int status_change = 0; -+ -+ spin_lock_irqsave(&ag->lock, flags); -+ -+ if (phydev->link) { -+ if (ag->duplex != phydev->duplex -+ || ag->speed != phydev->speed) { -+ status_change = 1; -+ } -+ } -+ -+ if (phydev->link != ag->link) -+ status_change = 1; -+ -+ ag->link = phydev->link; -+ ag->duplex = phydev->duplex; -+ ag->speed = phydev->speed; -+ -+ if (status_change) -+ ag71xx_link_adjust(ag); -+ -+ spin_unlock_irqrestore(&ag->lock, flags); -+} -+ -+void ag71xx_phy_start(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ -+ if (ag->phy_dev) { -+ phy_start(ag->phy_dev); -+ } else if (pdata->mii_bus_dev && pdata->switch_data) { -+ ag71xx_ar7240_start(ag); -+ } else { -+ ag->link = 1; -+ ag71xx_link_adjust(ag); -+ } -+} -+ -+void ag71xx_phy_stop(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ unsigned long flags; -+ -+ if (ag->phy_dev) -+ phy_stop(ag->phy_dev); -+ else if (pdata->mii_bus_dev && pdata->switch_data) -+ ag71xx_ar7240_stop(ag); -+ -+ spin_lock_irqsave(&ag->lock, flags); -+ if (ag->link) { -+ ag->link = 0; -+ ag71xx_link_adjust(ag); -+ } -+ spin_unlock_irqrestore(&ag->lock, flags); -+} -+ -+static int ag71xx_phy_connect_fixed(struct ag71xx *ag) -+{ -+ struct device *dev = &ag->pdev->dev; -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ int ret = 0; -+ -+ /* use fixed settings */ -+ switch (pdata->speed) { -+ case SPEED_10: -+ case SPEED_100: -+ case SPEED_1000: -+ break; -+ default: -+ dev_err(dev, "invalid speed specified\n"); -+ ret = -EINVAL; -+ break; -+ } -+ -+ dev_dbg(dev, "using fixed link parameters\n"); -+ -+ ag->duplex = pdata->duplex; -+ ag->speed = pdata->speed; -+ -+ return ret; -+} -+ -+static int ag71xx_phy_connect_multi(struct ag71xx *ag) -+{ -+ struct device *dev = &ag->pdev->dev; -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ struct phy_device *phydev = NULL; -+ int phy_addr; -+ int ret = 0; -+ -+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { -+ if (!(pdata->phy_mask & (1 << phy_addr))) -+ continue; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) -+ if (ag->mii_bus->phy_map[phy_addr] == NULL) -+ continue; -+ -+ DBG("%s: PHY found at %s, uid=%08x\n", -+ dev_name(dev), -+ dev_name(&ag->mii_bus->phy_map[phy_addr]->dev), -+ ag->mii_bus->phy_map[phy_addr]->phy_id); -+ -+ if (phydev == NULL) -+ phydev = ag->mii_bus->phy_map[phy_addr]; -+#else -+ if (ag->mii_bus->mdio_map[phy_addr] == NULL) -+ continue; -+ -+ DBG("%s: PHY found at %s, uid=%08x\n", -+ dev_name(dev), -+ dev_name(&ag->mii_bus->mdio_map[phy_addr]->dev), -+ (phydev) ? phydev->phy_id : 0); -+ -+ if (phydev == NULL) -+ phydev = mdiobus_get_phy(ag->mii_bus, phy_addr); -+#endif -+ } -+ -+ if (!phydev) { -+ dev_err(dev, "no PHY found with phy_mask=%08x\n", -+ pdata->phy_mask); -+ return -ENODEV; -+ } -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) -+ ag->phy_dev = phy_connect(ag->dev, dev_name(&phydev->dev), -+#else -+ ag->phy_dev = phy_connect(ag->dev, phydev_name(phydev), -+#endif -+ &ag71xx_phy_link_adjust, -+ pdata->phy_if_mode); -+ -+ if (IS_ERR(ag->phy_dev)) { -+ dev_err(dev, "could not connect to PHY at %s\n", -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) -+ dev_name(&phydev->dev)); -+#else -+ phydev_name(phydev)); -+#endif -+ return PTR_ERR(ag->phy_dev); -+ } -+ -+ /* mask with MAC supported features */ -+ if (pdata->has_gbit) -+ phydev->supported &= PHY_GBIT_FEATURES; -+ else -+ phydev->supported &= PHY_BASIC_FEATURES; -+ -+ phydev->advertising = phydev->supported; -+ -+ dev_info(dev, "connected to PHY at %s [uid=%08x, driver=%s]\n", -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) -+ dev_name(&phydev->dev), -+#else -+ phydev_name(phydev), -+#endif -+ phydev->phy_id, phydev->drv->name); -+ -+ ag->link = 0; -+ ag->speed = 0; -+ ag->duplex = -1; -+ -+ return ret; -+} -+ -+static int dev_is_class(struct device *dev, void *class) -+{ -+ if (dev->class != NULL && !strcmp(dev->class->name, class)) -+ return 1; -+ -+ return 0; -+} -+ -+static struct device *dev_find_class(struct device *parent, char *class) -+{ -+ if (dev_is_class(parent, class)) { -+ get_device(parent); -+ return parent; -+ } -+ -+ return device_find_child(parent, class, dev_is_class); -+} -+ -+static struct mii_bus *dev_to_mii_bus(struct device *dev) -+{ -+ struct device *d; -+ -+ d = dev_find_class(dev, "mdio_bus"); -+ if (d != NULL) { -+ struct mii_bus *bus; -+ -+ bus = to_mii_bus(d); -+ put_device(d); -+ -+ return bus; -+ } -+ -+ return NULL; -+} -+ -+int ag71xx_phy_connect(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ -+ if (pdata->mii_bus_dev == NULL || -+ pdata->mii_bus_dev->bus == NULL ) -+ return ag71xx_phy_connect_fixed(ag); -+ -+ ag->mii_bus = dev_to_mii_bus(pdata->mii_bus_dev); -+ if (ag->mii_bus == NULL) { -+ dev_err(&ag->pdev->dev, "unable to find MII bus on device '%s'\n", -+ dev_name(pdata->mii_bus_dev)); -+ return -ENODEV; -+ } -+ -+ /* Reset the mdio bus explicitly */ -+ if (ag->mii_bus->reset) { -+ mutex_lock(&ag->mii_bus->mdio_lock); -+ ag->mii_bus->reset(ag->mii_bus); -+ mutex_unlock(&ag->mii_bus->mdio_lock); -+ } -+ -+ if (pdata->switch_data) -+ return ag71xx_ar7240_init(ag); -+ -+ if (pdata->phy_mask) -+ return ag71xx_phy_connect_multi(ag); -+ -+ return ag71xx_phy_connect_fixed(ag); -+} -+ -+void ag71xx_phy_disconnect(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ -+ if (pdata->switch_data) -+ ag71xx_ar7240_cleanup(ag); -+ else if (ag->phy_dev) -+ phy_disconnect(ag->phy_dev); -+} -diff --git a/target/linux/ar71xx/files/drivers/spi/spi-rb4xx-cpld.c b/target/linux/ar71xx/files/drivers/spi/spi-rb4xx-cpld.c -new file mode 100644 -index 0000000000..18af83b67c ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/spi/spi-rb4xx-cpld.c -@@ -0,0 +1,347 @@ -+/* -+ * SPI driver for the CPLD chip on the Mikrotik RB4xx boards -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This file was based on the patches for Linux 2.6.27.39 published by -+ * MikroTik for their RouterBoard 4xx series devices. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define DRV_NAME "spi-rb4xx-cpld" -+#define DRV_DESC "RB4xx CPLD driver" -+#define DRV_VERSION "0.1.0" -+ -+#define CPLD_CMD_WRITE_NAND 0x08 /* send cmd, n x send data, send indle */ -+#define CPLD_CMD_WRITE_CFG 0x09 /* send cmd, n x send cfg */ -+#define CPLD_CMD_READ_NAND 0x0a /* send cmd, send idle, n x read data */ -+#define CPLD_CMD_READ_FAST 0x0b /* send cmd, 4 x idle, n x read data */ -+#define CPLD_CMD_LED5_ON 0x0c /* send cmd */ -+#define CPLD_CMD_LED5_OFF 0x0d /* send cmd */ -+ -+struct rb4xx_cpld { -+ struct spi_device *spi; -+ struct mutex lock; -+ struct gpio_chip chip; -+ unsigned int config; -+}; -+ -+static struct rb4xx_cpld *rb4xx_cpld; -+ -+static inline struct rb4xx_cpld *gpio_to_cpld(struct gpio_chip *chip) -+{ -+ return container_of(chip, struct rb4xx_cpld, chip); -+} -+ -+static int rb4xx_cpld_write_cmd(struct rb4xx_cpld *cpld, unsigned char cmd) -+{ -+ struct spi_transfer t[1]; -+ struct spi_message m; -+ unsigned char tx_buf[1]; -+ int err; -+ -+ spi_message_init(&m); -+ memset(&t, 0, sizeof(t)); -+ -+ t[0].tx_buf = tx_buf; -+ t[0].len = sizeof(tx_buf); -+ spi_message_add_tail(&t[0], &m); -+ -+ tx_buf[0] = cmd; -+ -+ err = spi_sync(cpld->spi, &m); -+ return err; -+} -+ -+static int rb4xx_cpld_write_cfg(struct rb4xx_cpld *cpld, unsigned char config) -+{ -+ struct spi_transfer t[1]; -+ struct spi_message m; -+ unsigned char cmd[2]; -+ int err; -+ -+ spi_message_init(&m); -+ memset(&t, 0, sizeof(t)); -+ -+ t[0].tx_buf = cmd; -+ t[0].len = sizeof(cmd); -+ spi_message_add_tail(&t[0], &m); -+ -+ cmd[0] = CPLD_CMD_WRITE_CFG; -+ cmd[1] = config; -+ -+ err = spi_sync(cpld->spi, &m); -+ return err; -+} -+ -+static int __rb4xx_cpld_change_cfg(struct rb4xx_cpld *cpld, unsigned mask, -+ unsigned value) -+{ -+ unsigned int config; -+ int err; -+ -+ config = cpld->config & ~mask; -+ config |= value; -+ -+ if ((cpld->config ^ config) & 0xff) { -+ err = rb4xx_cpld_write_cfg(cpld, config); -+ if (err) -+ return err; -+ } -+ -+ if ((cpld->config ^ config) & CPLD_CFG_nLED5) { -+ err = rb4xx_cpld_write_cmd(cpld, (value) ? CPLD_CMD_LED5_ON : -+ CPLD_CMD_LED5_OFF); -+ if (err) -+ return err; -+ } -+ -+ cpld->config = config; -+ return 0; -+} -+ -+int rb4xx_cpld_change_cfg(unsigned mask, unsigned value) -+{ -+ int ret; -+ -+ if (rb4xx_cpld == NULL) -+ return -ENODEV; -+ -+ mutex_lock(&rb4xx_cpld->lock); -+ ret = __rb4xx_cpld_change_cfg(rb4xx_cpld, mask, value); -+ mutex_unlock(&rb4xx_cpld->lock); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(rb4xx_cpld_change_cfg); -+ -+int rb4xx_cpld_read(unsigned char *rx_buf, unsigned count) -+{ -+ static const unsigned char cmd[2] = { CPLD_CMD_READ_NAND, 0 }; -+ struct spi_transfer t[2] = { -+ { -+ .tx_buf = &cmd, -+ .len = 2, -+ }, { -+ .rx_buf = rx_buf, -+ .len = count, -+ }, -+ }; -+ struct spi_message m; -+ -+ if (rb4xx_cpld == NULL) -+ return -ENODEV; -+ -+ spi_message_init(&m); -+ spi_message_add_tail(&t[0], &m); -+ spi_message_add_tail(&t[1], &m); -+ return spi_sync(rb4xx_cpld->spi, &m); -+} -+EXPORT_SYMBOL_GPL(rb4xx_cpld_read); -+ -+int rb4xx_cpld_write(const unsigned char *buf, unsigned count) -+{ -+ static const unsigned char cmd = CPLD_CMD_WRITE_NAND; -+ struct spi_transfer t[3] = { -+ { -+ .tx_buf = &cmd, -+ .len = 1, -+ }, { -+ .tx_buf = buf, -+ .len = count, -+ .tx_nbits = SPI_NBITS_DUAL, -+ }, { -+ .len = 1, -+ .tx_nbits = SPI_NBITS_DUAL, -+ }, -+ }; -+ struct spi_message m; -+ -+ if (rb4xx_cpld == NULL) -+ return -ENODEV; -+ -+ spi_message_init(&m); -+ spi_message_add_tail(&t[0], &m); -+ spi_message_add_tail(&t[1], &m); -+ spi_message_add_tail(&t[2], &m); -+ return spi_sync(rb4xx_cpld->spi, &m); -+} -+EXPORT_SYMBOL_GPL(rb4xx_cpld_write); -+ -+static int rb4xx_cpld_gpio_get(struct gpio_chip *chip, unsigned offset) -+{ -+ struct rb4xx_cpld *cpld = gpio_to_cpld(chip); -+ int ret; -+ -+ mutex_lock(&cpld->lock); -+ ret = (cpld->config >> offset) & 1; -+ mutex_unlock(&cpld->lock); -+ -+ return ret; -+} -+ -+static void rb4xx_cpld_gpio_set(struct gpio_chip *chip, unsigned offset, -+ int value) -+{ -+ struct rb4xx_cpld *cpld = gpio_to_cpld(chip); -+ -+ mutex_lock(&cpld->lock); -+ __rb4xx_cpld_change_cfg(cpld, (1 << offset), !!value << offset); -+ mutex_unlock(&cpld->lock); -+} -+ -+static int rb4xx_cpld_gpio_direction_input(struct gpio_chip *chip, -+ unsigned offset) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static int rb4xx_cpld_gpio_direction_output(struct gpio_chip *chip, -+ unsigned offset, -+ int value) -+{ -+ struct rb4xx_cpld *cpld = gpio_to_cpld(chip); -+ int ret; -+ -+ mutex_lock(&cpld->lock); -+ ret = __rb4xx_cpld_change_cfg(cpld, (1 << offset), !!value << offset); -+ mutex_unlock(&cpld->lock); -+ -+ return ret; -+} -+ -+static int rb4xx_cpld_gpio_init(struct rb4xx_cpld *cpld, unsigned int base) -+{ -+ int err; -+ -+ /* init config */ -+ cpld->config = CPLD_CFG_nLED1 | CPLD_CFG_nLED2 | CPLD_CFG_nLED3 | -+ CPLD_CFG_nLED4 | CPLD_CFG_nCE; -+ rb4xx_cpld_write_cfg(cpld, cpld->config); -+ -+ /* setup GPIO chip */ -+ cpld->chip.label = DRV_NAME; -+ -+ cpld->chip.get = rb4xx_cpld_gpio_get; -+ cpld->chip.set = rb4xx_cpld_gpio_set; -+ cpld->chip.direction_input = rb4xx_cpld_gpio_direction_input; -+ cpld->chip.direction_output = rb4xx_cpld_gpio_direction_output; -+ -+ cpld->chip.base = base; -+ cpld->chip.ngpio = CPLD_NUM_GPIOS; -+ cpld->chip.can_sleep = 1; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0) -+ cpld->chip.dev = &cpld->spi->dev; -+#else -+ cpld->chip.parent = &cpld->spi->dev; -+#endif -+ cpld->chip.owner = THIS_MODULE; -+ -+ err = gpiochip_add(&cpld->chip); -+ if (err) -+ dev_err(&cpld->spi->dev, "adding GPIO chip failed, err=%d\n", -+ err); -+ -+ return err; -+} -+ -+static int rb4xx_cpld_probe(struct spi_device *spi) -+{ -+ struct rb4xx_cpld *cpld; -+ struct rb4xx_cpld_platform_data *pdata; -+ int err; -+ -+ pdata = spi->dev.platform_data; -+ if (!pdata) { -+ dev_dbg(&spi->dev, "no platform data\n"); -+ return -EINVAL; -+ } -+ -+ cpld = kzalloc(sizeof(*cpld), GFP_KERNEL); -+ if (!cpld) { -+ dev_err(&spi->dev, "no memory for private data\n"); -+ return -ENOMEM; -+ } -+ -+ mutex_init(&cpld->lock); -+ cpld->spi = spi_dev_get(spi); -+ dev_set_drvdata(&spi->dev, cpld); -+ -+ spi->mode = SPI_MODE_0 | SPI_TX_DUAL; -+ spi->bits_per_word = 8; -+ err = spi_setup(spi); -+ if (err) { -+ dev_err(&spi->dev, "spi_setup failed, err=%d\n", err); -+ goto err_drvdata; -+ } -+ -+ err = rb4xx_cpld_gpio_init(cpld, pdata->gpio_base); -+ if (err) -+ goto err_drvdata; -+ -+ rb4xx_cpld = cpld; -+ -+ return 0; -+ -+err_drvdata: -+ dev_set_drvdata(&spi->dev, NULL); -+ kfree(cpld); -+ -+ return err; -+} -+ -+static int rb4xx_cpld_remove(struct spi_device *spi) -+{ -+ struct rb4xx_cpld *cpld; -+ -+ rb4xx_cpld = NULL; -+ cpld = dev_get_drvdata(&spi->dev); -+ dev_set_drvdata(&spi->dev, NULL); -+ kfree(cpld); -+ -+ return 0; -+} -+ -+static struct spi_driver rb4xx_cpld_driver = { -+ .driver = { -+ .name = DRV_NAME, -+ .bus = &spi_bus_type, -+ .owner = THIS_MODULE, -+ }, -+ .probe = rb4xx_cpld_probe, -+ .remove = rb4xx_cpld_remove, -+}; -+ -+static int __init rb4xx_cpld_init(void) -+{ -+ return spi_register_driver(&rb4xx_cpld_driver); -+} -+module_init(rb4xx_cpld_init); -+ -+static void __exit rb4xx_cpld_exit(void) -+{ -+ spi_unregister_driver(&rb4xx_cpld_driver); -+} -+module_exit(rb4xx_cpld_exit); -+ -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -diff --git a/target/linux/ar71xx/files/drivers/spi/spi-rb4xx.c b/target/linux/ar71xx/files/drivers/spi/spi-rb4xx.c -new file mode 100644 -index 0000000000..2d95e80495 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/spi/spi-rb4xx.c -@@ -0,0 +1,430 @@ -+/* -+ * SPI controller driver for the Mikrotik RB4xx boards -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This file was based on the patches for Linux 2.6.27.39 published by -+ * MikroTik for their RouterBoard 4xx series devices. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define DRV_NAME "rb4xx-spi" -+#define DRV_DESC "Mikrotik RB4xx SPI controller driver" -+#define DRV_VERSION "0.1.0" -+ -+#define SPI_CTRL_FASTEST 0x40 -+#define SPI_FLASH_HZ 33333334 -+#define SPI_CPLD_HZ 33333334 -+ -+#define CPLD_CMD_READ_FAST 0x0b -+ -+#undef RB4XX_SPI_DEBUG -+ -+struct rb4xx_spi { -+ void __iomem *base; -+ struct spi_master *master; -+ -+ unsigned spi_ctrl_flash; -+ unsigned spi_ctrl_fread; -+ -+ struct clk *ahb_clk; -+ unsigned long ahb_freq; -+ -+ spinlock_t lock; -+ struct list_head queue; -+ int busy:1; -+ int cs_wait; -+}; -+ -+static unsigned spi_clk_low = AR71XX_SPI_IOC_CS1; -+ -+#ifdef RB4XX_SPI_DEBUG -+static inline void do_spi_delay(void) -+{ -+ ndelay(20000); -+} -+#else -+static inline void do_spi_delay(void) { } -+#endif -+ -+static inline void do_spi_init(struct spi_device *spi) -+{ -+ unsigned cs = AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1; -+ -+ if (!(spi->mode & SPI_CS_HIGH)) -+ cs ^= (spi->chip_select == 2) ? AR71XX_SPI_IOC_CS1 : -+ AR71XX_SPI_IOC_CS0; -+ -+ spi_clk_low = cs; -+} -+ -+static inline void do_spi_finish(void __iomem *base) -+{ -+ do_spi_delay(); -+ __raw_writel(AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1, -+ base + AR71XX_SPI_REG_IOC); -+} -+ -+static inline void do_spi_clk(void __iomem *base, int bit) -+{ -+ unsigned bval = spi_clk_low | ((bit & 1) ? AR71XX_SPI_IOC_DO : 0); -+ -+ do_spi_delay(); -+ __raw_writel(bval, base + AR71XX_SPI_REG_IOC); -+ do_spi_delay(); -+ __raw_writel(bval | AR71XX_SPI_IOC_CLK, base + AR71XX_SPI_REG_IOC); -+} -+ -+static void do_spi_byte(void __iomem *base, unsigned char byte) -+{ -+ do_spi_clk(base, byte >> 7); -+ do_spi_clk(base, byte >> 6); -+ do_spi_clk(base, byte >> 5); -+ do_spi_clk(base, byte >> 4); -+ do_spi_clk(base, byte >> 3); -+ do_spi_clk(base, byte >> 2); -+ do_spi_clk(base, byte >> 1); -+ do_spi_clk(base, byte); -+ -+ pr_debug("spi_byte sent 0x%02x got 0x%02x\n", -+ (unsigned)byte, -+ (unsigned char)__raw_readl(base + AR71XX_SPI_REG_RDS)); -+} -+ -+static inline void do_spi_clk_fast(void __iomem *base, unsigned bit1, -+ unsigned bit2) -+{ -+ unsigned bval = (spi_clk_low | -+ ((bit1 & 1) ? AR71XX_SPI_IOC_DO : 0) | -+ ((bit2 & 1) ? AR71XX_SPI_IOC_CS2 : 0)); -+ do_spi_delay(); -+ __raw_writel(bval, base + AR71XX_SPI_REG_IOC); -+ do_spi_delay(); -+ __raw_writel(bval | AR71XX_SPI_IOC_CLK, base + AR71XX_SPI_REG_IOC); -+} -+ -+static void do_spi_byte_fast(void __iomem *base, unsigned char byte) -+{ -+ do_spi_clk_fast(base, byte >> 7, byte >> 6); -+ do_spi_clk_fast(base, byte >> 5, byte >> 4); -+ do_spi_clk_fast(base, byte >> 3, byte >> 2); -+ do_spi_clk_fast(base, byte >> 1, byte >> 0); -+ -+ pr_debug("spi_byte_fast sent 0x%02x got 0x%02x\n", -+ (unsigned)byte, -+ (unsigned char) __raw_readl(base + AR71XX_SPI_REG_RDS)); -+} -+ -+static int rb4xx_spi_txrx(void __iomem *base, struct spi_transfer *t) -+{ -+ const unsigned char *tx_ptr = t->tx_buf; -+ unsigned char *rx_ptr = t->rx_buf; -+ unsigned i; -+ -+ pr_debug("spi_txrx len %u tx %u rx %u\n", -+ t->len, -+ (t->tx_buf ? 1 : 0), -+ (t->rx_buf ? 1 : 0)); -+ -+ for (i = 0; i < t->len; ++i) { -+ unsigned char sdata = tx_ptr ? tx_ptr[i] : 0; -+ -+ if (t->tx_nbits == SPI_NBITS_DUAL) -+ do_spi_byte_fast(base, sdata); -+ else -+ do_spi_byte(base, sdata); -+ -+ if (rx_ptr) -+ rx_ptr[i] = __raw_readl(base + AR71XX_SPI_REG_RDS) & 0xff; -+ } -+ -+ return i; -+} -+ -+static int rb4xx_spi_msg(struct rb4xx_spi *rbspi, struct spi_message *m) -+{ -+ struct spi_transfer *t = NULL; -+ void __iomem *base = rbspi->base; -+ -+ m->status = 0; -+ if (list_empty(&m->transfers)) -+ return -1; -+ -+ __raw_writel(AR71XX_SPI_FS_GPIO, base + AR71XX_SPI_REG_FS); -+ __raw_writel(SPI_CTRL_FASTEST, base + AR71XX_SPI_REG_CTRL); -+ do_spi_init(m->spi); -+ -+ list_for_each_entry(t, &m->transfers, transfer_list) { -+ int len; -+ -+ len = rb4xx_spi_txrx(base, t); -+ if (len != t->len) { -+ m->status = -EMSGSIZE; -+ break; -+ } -+ m->actual_length += len; -+ -+ if (t->cs_change) { -+ if (list_is_last(&t->transfer_list, &m->transfers)) { -+ /* wait for continuation */ -+ return m->spi->chip_select; -+ } -+ do_spi_finish(base); -+ ndelay(100); -+ } -+ } -+ -+ do_spi_finish(base); -+ __raw_writel(rbspi->spi_ctrl_flash, base + AR71XX_SPI_REG_CTRL); -+ __raw_writel(0, base + AR71XX_SPI_REG_FS); -+ return -1; -+} -+ -+static void rb4xx_spi_process_queue_locked(struct rb4xx_spi *rbspi, -+ unsigned long *flags) -+{ -+ int cs = rbspi->cs_wait; -+ -+ rbspi->busy = 1; -+ while (!list_empty(&rbspi->queue)) { -+ struct spi_message *m; -+ -+ list_for_each_entry(m, &rbspi->queue, queue) -+ if (cs < 0 || cs == m->spi->chip_select) -+ break; -+ -+ if (&m->queue == &rbspi->queue) -+ break; -+ -+ list_del_init(&m->queue); -+ spin_unlock_irqrestore(&rbspi->lock, *flags); -+ -+ cs = rb4xx_spi_msg(rbspi, m); -+ m->complete(m->context); -+ -+ spin_lock_irqsave(&rbspi->lock, *flags); -+ } -+ -+ rbspi->cs_wait = cs; -+ rbspi->busy = 0; -+ -+ if (cs >= 0) { -+ /* TODO: add timer to unlock cs after 1s inactivity */ -+ } -+} -+ -+static int rb4xx_spi_transfer(struct spi_device *spi, -+ struct spi_message *m) -+{ -+ struct rb4xx_spi *rbspi = spi_master_get_devdata(spi->master); -+ unsigned long flags; -+ -+ m->actual_length = 0; -+ m->status = -EINPROGRESS; -+ -+ spin_lock_irqsave(&rbspi->lock, flags); -+ list_add_tail(&m->queue, &rbspi->queue); -+ if (rbspi->busy || -+ (rbspi->cs_wait >= 0 && rbspi->cs_wait != m->spi->chip_select)) { -+ /* job will be done later */ -+ spin_unlock_irqrestore(&rbspi->lock, flags); -+ return 0; -+ } -+ -+ /* process job in current context */ -+ rb4xx_spi_process_queue_locked(rbspi, &flags); -+ spin_unlock_irqrestore(&rbspi->lock, flags); -+ -+ return 0; -+} -+ -+static int rb4xx_spi_setup(struct spi_device *spi) -+{ -+ struct rb4xx_spi *rbspi = spi_master_get_devdata(spi->master); -+ unsigned long flags; -+ -+ if (spi->mode & ~(SPI_CS_HIGH | SPI_TX_DUAL)) { -+ dev_err(&spi->dev, "mode %x not supported\n", -+ (unsigned) spi->mode); -+ return -EINVAL; -+ } -+ -+ if (spi->bits_per_word != 8 && spi->bits_per_word != 0) { -+ dev_err(&spi->dev, "bits_per_word %u not supported\n", -+ (unsigned) spi->bits_per_word); -+ return -EINVAL; -+ } -+ -+ spin_lock_irqsave(&rbspi->lock, flags); -+ if (rbspi->cs_wait == spi->chip_select && !rbspi->busy) { -+ rbspi->cs_wait = -1; -+ rb4xx_spi_process_queue_locked(rbspi, &flags); -+ } -+ spin_unlock_irqrestore(&rbspi->lock, flags); -+ -+ return 0; -+} -+ -+static unsigned get_spi_ctrl(struct rb4xx_spi *rbspi, unsigned hz_max, -+ const char *name) -+{ -+ unsigned div; -+ -+ div = (rbspi->ahb_freq - 1) / (2 * hz_max); -+ -+ /* -+ * CPU has a bug at (div == 0) - first bit read is random -+ */ -+ if (div == 0) -+ ++div; -+ -+ if (name) { -+ unsigned ahb_khz = (rbspi->ahb_freq + 500) / 1000; -+ unsigned div_real = 2 * (div + 1); -+ pr_debug("rb4xx: %s SPI clock %u kHz (AHB %u kHz / %u)\n", -+ name, -+ ahb_khz / div_real, -+ ahb_khz, div_real); -+ } -+ -+ return SPI_CTRL_FASTEST + div; -+} -+ -+static int rb4xx_spi_probe(struct platform_device *pdev) -+{ -+ struct spi_master *master; -+ struct rb4xx_spi *rbspi; -+ struct resource *r; -+ int err = 0; -+ -+ master = spi_alloc_master(&pdev->dev, sizeof(*rbspi)); -+ if (master == NULL) { -+ dev_err(&pdev->dev, "no memory for spi_master\n"); -+ err = -ENOMEM; -+ goto err_out; -+ } -+ -+ master->bus_num = 0; -+ master->num_chipselect = 3; -+ master->mode_bits = SPI_TX_DUAL; -+ master->setup = rb4xx_spi_setup; -+ master->transfer = rb4xx_spi_transfer; -+ -+ rbspi = spi_master_get_devdata(master); -+ -+ rbspi->ahb_clk = clk_get(&pdev->dev, "ahb"); -+ if (IS_ERR(rbspi->ahb_clk)) { -+ err = PTR_ERR(rbspi->ahb_clk); -+ goto err_put_master; -+ } -+ -+ err = clk_prepare_enable(rbspi->ahb_clk); -+ if (err) -+ goto err_clk_put; -+ -+ rbspi->ahb_freq = clk_get_rate(rbspi->ahb_clk); -+ if (!rbspi->ahb_freq) { -+ err = -EINVAL; -+ goto err_clk_disable; -+ } -+ -+ platform_set_drvdata(pdev, rbspi); -+ -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (r == NULL) { -+ err = -ENOENT; -+ goto err_clk_disable; -+ } -+ -+ rbspi->base = ioremap(r->start, r->end - r->start + 1); -+ if (!rbspi->base) { -+ err = -ENXIO; -+ goto err_clk_disable; -+ } -+ -+ rbspi->master = master; -+ rbspi->spi_ctrl_flash = get_spi_ctrl(rbspi, SPI_FLASH_HZ, "FLASH"); -+ rbspi->spi_ctrl_fread = get_spi_ctrl(rbspi, SPI_CPLD_HZ, "CPLD"); -+ rbspi->cs_wait = -1; -+ -+ spin_lock_init(&rbspi->lock); -+ INIT_LIST_HEAD(&rbspi->queue); -+ -+ err = spi_register_master(master); -+ if (err) { -+ dev_err(&pdev->dev, "failed to register SPI master\n"); -+ goto err_iounmap; -+ } -+ -+ return 0; -+ -+err_iounmap: -+ iounmap(rbspi->base); -+err_clk_disable: -+ clk_disable_unprepare(rbspi->ahb_clk); -+err_clk_put: -+ clk_put(rbspi->ahb_clk); -+err_put_master: -+ platform_set_drvdata(pdev, NULL); -+ spi_master_put(master); -+err_out: -+ return err; -+} -+ -+static int rb4xx_spi_remove(struct platform_device *pdev) -+{ -+ struct rb4xx_spi *rbspi = platform_get_drvdata(pdev); -+ -+ iounmap(rbspi->base); -+ clk_disable_unprepare(rbspi->ahb_clk); -+ clk_put(rbspi->ahb_clk); -+ platform_set_drvdata(pdev, NULL); -+ spi_master_put(rbspi->master); -+ -+ return 0; -+} -+ -+static struct platform_driver rb4xx_spi_drv = { -+ .probe = rb4xx_spi_probe, -+ .remove = rb4xx_spi_remove, -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init rb4xx_spi_init(void) -+{ -+ return platform_driver_register(&rb4xx_spi_drv); -+} -+subsys_initcall(rb4xx_spi_init); -+ -+static void __exit rb4xx_spi_exit(void) -+{ -+ platform_driver_unregister(&rb4xx_spi_drv); -+} -+ -+module_exit(rb4xx_spi_exit); -+ -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -diff --git a/target/linux/ar71xx/files/drivers/spi/spi-vsc7385.c b/target/linux/ar71xx/files/drivers/spi/spi-vsc7385.c -new file mode 100644 -index 0000000000..b712e71875 ---- /dev/null -+++ b/target/linux/ar71xx/files/drivers/spi/spi-vsc7385.c -@@ -0,0 +1,621 @@ -+/* -+ * SPI driver for the Vitesse VSC7385 ethernet switch -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * Parts of this file are based on Atheros' 2.6.15 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRV_NAME "spi-vsc7385" -+#define DRV_DESC "Vitesse VSC7385 Gbit ethernet switch driver" -+#define DRV_VERSION "0.1.0" -+ -+#define VSC73XX_BLOCK_MAC 0x1 -+#define VSC73XX_BLOCK_2 0x2 -+#define VSC73XX_BLOCK_MII 0x3 -+#define VSC73XX_BLOCK_4 0x4 -+#define VSC73XX_BLOCK_5 0x5 -+#define VSC73XX_BLOCK_SYSTEM 0x7 -+ -+#define VSC73XX_SUBBLOCK_PORT_0 0 -+#define VSC73XX_SUBBLOCK_PORT_1 1 -+#define VSC73XX_SUBBLOCK_PORT_2 2 -+#define VSC73XX_SUBBLOCK_PORT_3 3 -+#define VSC73XX_SUBBLOCK_PORT_4 4 -+#define VSC73XX_SUBBLOCK_PORT_MAC 6 -+ -+/* MAC Block registers */ -+#define VSC73XX_MAC_CFG 0x0 -+#define VSC73XX_ADVPORTM 0x19 -+#define VSC73XX_RXOCT 0x50 -+#define VSC73XX_TXOCT 0x51 -+#define VSC73XX_C_RX0 0x52 -+#define VSC73XX_C_RX1 0x53 -+#define VSC73XX_C_RX2 0x54 -+#define VSC73XX_C_TX0 0x55 -+#define VSC73XX_C_TX1 0x56 -+#define VSC73XX_C_TX2 0x57 -+#define VSC73XX_C_CFG 0x58 -+ -+/* MAC_CFG register bits */ -+#define VSC73XX_MAC_CFG_WEXC_DIS (1 << 31) -+#define VSC73XX_MAC_CFG_PORT_RST (1 << 29) -+#define VSC73XX_MAC_CFG_TX_EN (1 << 28) -+#define VSC73XX_MAC_CFG_SEED_LOAD (1 << 27) -+#define VSC73XX_MAC_CFG_FDX (1 << 18) -+#define VSC73XX_MAC_CFG_GIGE (1 << 17) -+#define VSC73XX_MAC_CFG_RX_EN (1 << 16) -+#define VSC73XX_MAC_CFG_VLAN_DBLAWR (1 << 15) -+#define VSC73XX_MAC_CFG_VLAN_AWR (1 << 14) -+#define VSC73XX_MAC_CFG_100_BASE_T (1 << 13) -+#define VSC73XX_MAC_CFG_TX_IPG(x) (((x) & 0x1f) << 6) -+#define VSC73XX_MAC_CFG_MAC_RX_RST (1 << 5) -+#define VSC73XX_MAC_CFG_MAC_TX_RST (1 << 4) -+#define VSC73XX_MAC_CFG_BIT2 (1 << 2) -+#define VSC73XX_MAC_CFG_CLK_SEL(x) ((x) & 0x3) -+ -+/* ADVPORTM register bits */ -+#define VSC73XX_ADVPORTM_IFG_PPM (1 << 7) -+#define VSC73XX_ADVPORTM_EXC_COL_CONT (1 << 6) -+#define VSC73XX_ADVPORTM_EXT_PORT (1 << 5) -+#define VSC73XX_ADVPORTM_INV_GTX (1 << 4) -+#define VSC73XX_ADVPORTM_ENA_GTX (1 << 3) -+#define VSC73XX_ADVPORTM_DDR_MODE (1 << 2) -+#define VSC73XX_ADVPORTM_IO_LOOPBACK (1 << 1) -+#define VSC73XX_ADVPORTM_HOST_LOOPBACK (1 << 0) -+ -+/* MII Block registers */ -+#define VSC73XX_MII_STAT 0x0 -+#define VSC73XX_MII_CMD 0x1 -+#define VSC73XX_MII_DATA 0x2 -+ -+/* System Block registers */ -+#define VSC73XX_ICPU_SIPAD 0x01 -+#define VSC73XX_ICPU_CLOCK_DELAY 0x05 -+#define VSC73XX_ICPU_CTRL 0x10 -+#define VSC73XX_ICPU_ADDR 0x11 -+#define VSC73XX_ICPU_SRAM 0x12 -+#define VSC73XX_ICPU_MBOX_VAL 0x15 -+#define VSC73XX_ICPU_MBOX_SET 0x16 -+#define VSC73XX_ICPU_MBOX_CLR 0x17 -+#define VSC73XX_ICPU_CHIPID 0x18 -+#define VSC73XX_ICPU_GPIO 0x34 -+ -+#define VSC73XX_ICPU_CTRL_CLK_DIV (1 << 8) -+#define VSC73XX_ICPU_CTRL_SRST_HOLD (1 << 7) -+#define VSC73XX_ICPU_CTRL_BOOT_EN (1 << 3) -+#define VSC73XX_ICPU_CTRL_EXT_ACC_EN (1 << 2) -+#define VSC73XX_ICPU_CTRL_CLK_EN (1 << 1) -+#define VSC73XX_ICPU_CTRL_SRST (1 << 0) -+ -+#define VSC73XX_ICPU_CHIPID_ID_SHIFT 12 -+#define VSC73XX_ICPU_CHIPID_ID_MASK 0xffff -+#define VSC73XX_ICPU_CHIPID_REV_SHIFT 28 -+#define VSC73XX_ICPU_CHIPID_REV_MASK 0xf -+#define VSC73XX_ICPU_CHIPID_ID_7385 0x7385 -+#define VSC73XX_ICPU_CHIPID_ID_7395 0x7395 -+ -+#define VSC73XX_CMD_MODE_READ 0 -+#define VSC73XX_CMD_MODE_WRITE 1 -+#define VSC73XX_CMD_MODE_SHIFT 4 -+#define VSC73XX_CMD_BLOCK_SHIFT 5 -+#define VSC73XX_CMD_BLOCK_MASK 0x7 -+#define VSC73XX_CMD_SUBBLOCK_MASK 0xf -+ -+#define VSC7385_CLOCK_DELAY ((3 << 4) | 3) -+#define VSC7385_CLOCK_DELAY_MASK ((3 << 4) | 3) -+ -+#define VSC73XX_ICPU_CTRL_STOP (VSC73XX_ICPU_CTRL_SRST_HOLD | \ -+ VSC73XX_ICPU_CTRL_BOOT_EN | \ -+ VSC73XX_ICPU_CTRL_EXT_ACC_EN) -+ -+#define VSC73XX_ICPU_CTRL_START (VSC73XX_ICPU_CTRL_CLK_DIV | \ -+ VSC73XX_ICPU_CTRL_BOOT_EN | \ -+ VSC73XX_ICPU_CTRL_CLK_EN | \ -+ VSC73XX_ICPU_CTRL_SRST) -+ -+#define VSC7385_ADVPORTM_MASK (VSC73XX_ADVPORTM_IFG_PPM | \ -+ VSC73XX_ADVPORTM_EXC_COL_CONT | \ -+ VSC73XX_ADVPORTM_EXT_PORT | \ -+ VSC73XX_ADVPORTM_INV_GTX | \ -+ VSC73XX_ADVPORTM_ENA_GTX | \ -+ VSC73XX_ADVPORTM_DDR_MODE | \ -+ VSC73XX_ADVPORTM_IO_LOOPBACK | \ -+ VSC73XX_ADVPORTM_HOST_LOOPBACK) -+ -+#define VSC7385_ADVPORTM_INIT (VSC73XX_ADVPORTM_EXT_PORT | \ -+ VSC73XX_ADVPORTM_ENA_GTX | \ -+ VSC73XX_ADVPORTM_DDR_MODE) -+ -+#define VSC7385_MAC_CFG_RESET (VSC73XX_MAC_CFG_PORT_RST | \ -+ VSC73XX_MAC_CFG_MAC_RX_RST | \ -+ VSC73XX_MAC_CFG_MAC_TX_RST) -+ -+#define VSC73XX_MAC_CFG_INIT (VSC73XX_MAC_CFG_TX_EN | \ -+ VSC73XX_MAC_CFG_FDX | \ -+ VSC73XX_MAC_CFG_GIGE | \ -+ VSC73XX_MAC_CFG_RX_EN) -+ -+#define VSC73XX_RESET_DELAY 100 -+ -+struct vsc7385 { -+ struct spi_device *spi; -+ struct mutex lock; -+ struct vsc7385_platform_data *pdata; -+}; -+ -+static int vsc7385_is_addr_valid(u8 block, u8 subblock) -+{ -+ switch (block) { -+ case VSC73XX_BLOCK_MAC: -+ switch (subblock) { -+ case 0 ... 4: -+ case 6: -+ return 1; -+ } -+ break; -+ -+ case VSC73XX_BLOCK_2: -+ case VSC73XX_BLOCK_SYSTEM: -+ switch (subblock) { -+ case 0: -+ return 1; -+ } -+ break; -+ -+ case VSC73XX_BLOCK_MII: -+ case VSC73XX_BLOCK_4: -+ case VSC73XX_BLOCK_5: -+ switch (subblock) { -+ case 0 ... 1: -+ return 1; -+ } -+ break; -+ } -+ -+ return 0; -+} -+ -+static inline u8 vsc7385_make_addr(u8 mode, u8 block, u8 subblock) -+{ -+ u8 ret; -+ -+ ret = (block & VSC73XX_CMD_BLOCK_MASK) << VSC73XX_CMD_BLOCK_SHIFT; -+ ret |= (mode & 1) << VSC73XX_CMD_MODE_SHIFT; -+ ret |= subblock & VSC73XX_CMD_SUBBLOCK_MASK; -+ -+ return ret; -+} -+ -+static int vsc7385_read(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg, -+ u32 *value) -+{ -+ u8 cmd[4]; -+ u8 buf[4]; -+ struct spi_transfer t[2]; -+ struct spi_message m; -+ int err; -+ -+ if (!vsc7385_is_addr_valid(block, subblock)) -+ return -EINVAL; -+ -+ spi_message_init(&m); -+ -+ memset(&t, 0, sizeof(t)); -+ -+ t[0].tx_buf = cmd; -+ t[0].len = sizeof(cmd); -+ spi_message_add_tail(&t[0], &m); -+ -+ t[1].rx_buf = buf; -+ t[1].len = sizeof(buf); -+ spi_message_add_tail(&t[1], &m); -+ -+ cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_READ, block, subblock); -+ cmd[1] = reg; -+ cmd[2] = 0; -+ cmd[3] = 0; -+ -+ mutex_lock(&vsc->lock); -+ err = spi_sync(vsc->spi, &m); -+ mutex_unlock(&vsc->lock); -+ -+ if (err) -+ return err; -+ -+ *value = (((u32) buf[0]) << 24) | (((u32) buf[1]) << 16) | -+ (((u32) buf[2]) << 8) | ((u32) buf[3]); -+ -+ return 0; -+} -+ -+ -+static int vsc7385_write(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg, -+ u32 value) -+{ -+ u8 cmd[2]; -+ u8 buf[4]; -+ struct spi_transfer t[2]; -+ struct spi_message m; -+ int err; -+ -+ if (!vsc7385_is_addr_valid(block, subblock)) -+ return -EINVAL; -+ -+ spi_message_init(&m); -+ -+ memset(&t, 0, sizeof(t)); -+ -+ t[0].tx_buf = cmd; -+ t[0].len = sizeof(cmd); -+ spi_message_add_tail(&t[0], &m); -+ -+ t[1].tx_buf = buf; -+ t[1].len = sizeof(buf); -+ spi_message_add_tail(&t[1], &m); -+ -+ cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_WRITE, block, subblock); -+ cmd[1] = reg; -+ -+ buf[0] = (value >> 24) & 0xff; -+ buf[1] = (value >> 16) & 0xff; -+ buf[2] = (value >> 8) & 0xff; -+ buf[3] = value & 0xff; -+ -+ mutex_lock(&vsc->lock); -+ err = spi_sync(vsc->spi, &m); -+ mutex_unlock(&vsc->lock); -+ -+ return err; -+} -+ -+static inline int vsc7385_write_verify(struct vsc7385 *vsc, u8 block, -+ u8 subblock, u8 reg, u32 value, -+ u32 read_mask, u32 read_val) -+{ -+ struct spi_device *spi = vsc->spi; -+ u32 t; -+ int err; -+ -+ err = vsc7385_write(vsc, block, subblock, reg, value); -+ if (err) -+ return err; -+ -+ err = vsc7385_read(vsc, block, subblock, reg, &t); -+ if (err) -+ return err; -+ -+ if ((t & read_mask) != read_val) { -+ dev_err(&spi->dev, "register write error\n"); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static inline int vsc7385_set_clock_delay(struct vsc7385 *vsc, u32 val) -+{ -+ return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, -+ VSC73XX_ICPU_CLOCK_DELAY, val); -+} -+ -+static inline int vsc7385_get_clock_delay(struct vsc7385 *vsc, u32 *val) -+{ -+ return vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0, -+ VSC73XX_ICPU_CLOCK_DELAY, val); -+} -+ -+static inline int vsc7385_icpu_stop(struct vsc7385 *vsc) -+{ -+ return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL, -+ VSC73XX_ICPU_CTRL_STOP); -+} -+ -+static inline int vsc7385_icpu_start(struct vsc7385 *vsc) -+{ -+ return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL, -+ VSC73XX_ICPU_CTRL_START); -+} -+ -+static inline int vsc7385_icpu_reset(struct vsc7385 *vsc) -+{ -+ int rc; -+ -+ rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_ADDR, -+ 0x0000); -+ if (rc) -+ dev_err(&vsc->spi->dev, -+ "could not reset microcode, err=%d\n", rc); -+ -+ return rc; -+} -+ -+static int vsc7385_upload_ucode(struct vsc7385 *vsc) -+{ -+ struct spi_device *spi = vsc->spi; -+ const struct firmware *firmware; -+ char *ucode_name; -+ unsigned char *dp; -+ unsigned int curVal; -+ int i; -+ int diffs; -+ int rc; -+ -+ ucode_name = (vsc->pdata->ucode_name) ? vsc->pdata->ucode_name -+ : "vsc7385_ucode.bin"; -+ rc = request_firmware(&firmware, ucode_name, &spi->dev); -+ if (rc) { -+ dev_err(&spi->dev, "request_firmware failed, err=%d\n", -+ rc); -+ return rc; -+ } -+ -+ rc = vsc7385_icpu_stop(vsc); -+ if (rc) -+ goto out; -+ -+ rc = vsc7385_icpu_reset(vsc); -+ if (rc) -+ goto out; -+ -+ dev_info(&spi->dev, "uploading microcode...\n"); -+ -+ dp = (unsigned char *) firmware->data; -+ for (i = 0; i < firmware->size; i++) { -+ rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, -+ VSC73XX_ICPU_SRAM, *dp++); -+ if (rc) { -+ dev_err(&spi->dev, "could not load microcode, err=%d\n", -+ rc); -+ goto out; -+ } -+ } -+ -+ rc = vsc7385_icpu_reset(vsc); -+ if (rc) -+ goto out; -+ -+ dev_info(&spi->dev, "verifying microcode...\n"); -+ -+ dp = (unsigned char *) firmware->data; -+ diffs = 0; -+ for (i = 0; i < firmware->size; i++) { -+ rc = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0, -+ VSC73XX_ICPU_SRAM, &curVal); -+ if (rc) { -+ dev_err(&spi->dev, "could not read microcode %d\n", -+ rc); -+ goto out; -+ } -+ -+ if (curVal > 0xff) { -+ dev_err(&spi->dev, "bad val read: %04x : %02x %02x\n", -+ i, *dp, curVal); -+ rc = -EIO; -+ goto out; -+ } -+ -+ if ((curVal & 0xff) != *dp) { -+ diffs++; -+ dev_err(&spi->dev, "verify error: %04x : %02x %02x\n", -+ i, *dp, curVal); -+ -+ if (diffs > 4) -+ break; -+ } -+ dp++; -+ } -+ -+ if (diffs) { -+ dev_err(&spi->dev, "microcode verification failed\n"); -+ rc = -EIO; -+ goto out; -+ } -+ -+ dev_info(&spi->dev, "microcode uploaded\n"); -+ -+ rc = vsc7385_icpu_start(vsc); -+ -+out: -+ release_firmware(firmware); -+ return rc; -+} -+ -+static int vsc7385_setup(struct vsc7385 *vsc) -+{ -+ struct vsc7385_platform_data *pdata = vsc->pdata; -+ u32 t; -+ int err; -+ -+ err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_SYSTEM, 0, -+ VSC73XX_ICPU_CLOCK_DELAY, -+ VSC7385_CLOCK_DELAY, -+ VSC7385_CLOCK_DELAY_MASK, -+ VSC7385_CLOCK_DELAY); -+ if (err) -+ goto err; -+ -+ err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_MAC, -+ VSC73XX_SUBBLOCK_PORT_MAC, VSC73XX_ADVPORTM, -+ VSC7385_ADVPORTM_INIT, -+ VSC7385_ADVPORTM_MASK, -+ VSC7385_ADVPORTM_INIT); -+ if (err) -+ goto err; -+ -+ err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC, -+ VSC73XX_MAC_CFG, VSC7385_MAC_CFG_RESET); -+ if (err) -+ goto err; -+ -+ t = VSC73XX_MAC_CFG_INIT; -+ t |= VSC73XX_MAC_CFG_TX_IPG(pdata->mac_cfg.tx_ipg); -+ t |= VSC73XX_MAC_CFG_CLK_SEL(pdata->mac_cfg.clk_sel); -+ if (pdata->mac_cfg.bit2) -+ t |= VSC73XX_MAC_CFG_BIT2; -+ -+ err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC, -+ VSC73XX_MAC_CFG, t); -+ if (err) -+ goto err; -+ -+ return 0; -+ -+err: -+ return err; -+} -+ -+static int vsc7385_detect(struct vsc7385 *vsc) -+{ -+ struct spi_device *spi = vsc->spi; -+ u32 t; -+ u32 id; -+ u32 rev; -+ int err; -+ -+ err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0, -+ VSC73XX_ICPU_MBOX_VAL, &t); -+ if (err) { -+ dev_err(&spi->dev, "unable to read mailbox, err=%d\n", err); -+ return err; -+ } -+ -+ if (t == 0xffffffff) { -+ dev_dbg(&spi->dev, "assert chip reset\n"); -+ if (vsc->pdata->reset) -+ vsc->pdata->reset(); -+ -+ } -+ -+ err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0, -+ VSC73XX_ICPU_CHIPID, &t); -+ if (err) { -+ dev_err(&spi->dev, "unable to read chip id, err=%d\n", err); -+ return err; -+ } -+ -+ id = (t >> VSC73XX_ICPU_CHIPID_ID_SHIFT) & VSC73XX_ICPU_CHIPID_ID_MASK; -+ switch (id) { -+ case VSC73XX_ICPU_CHIPID_ID_7385: -+ case VSC73XX_ICPU_CHIPID_ID_7395: -+ break; -+ default: -+ dev_err(&spi->dev, "unsupported chip, id=%04x\n", id); -+ return -ENODEV; -+ } -+ -+ rev = (t >> VSC73XX_ICPU_CHIPID_REV_SHIFT) & -+ VSC73XX_ICPU_CHIPID_REV_MASK; -+ dev_info(&spi->dev, "VSC%04X (rev. %d) switch found\n", id, rev); -+ -+ return 0; -+} -+ -+static int vsc7385_probe(struct spi_device *spi) -+{ -+ struct vsc7385 *vsc; -+ struct vsc7385_platform_data *pdata; -+ int err; -+ -+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION"\n"); -+ -+ pdata = spi->dev.platform_data; -+ if (!pdata) { -+ dev_err(&spi->dev, "no platform data specified\n"); -+ return -ENODEV; -+ } -+ -+ vsc = kzalloc(sizeof(*vsc), GFP_KERNEL); -+ if (!vsc) { -+ dev_err(&spi->dev, "no memory for private data\n"); -+ return -ENOMEM; -+ } -+ -+ mutex_init(&vsc->lock); -+ vsc->pdata = pdata; -+ vsc->spi = spi_dev_get(spi); -+ dev_set_drvdata(&spi->dev, vsc); -+ -+ spi->mode = SPI_MODE_0; -+ spi->bits_per_word = 8; -+ err = spi_setup(spi); -+ if (err) { -+ dev_err(&spi->dev, "spi_setup failed, err=%d\n", err); -+ goto err_drvdata; -+ } -+ -+ err = vsc7385_detect(vsc); -+ if (err) { -+ dev_err(&spi->dev, "no chip found, err=%d\n", err); -+ goto err_drvdata; -+ } -+ -+ err = vsc7385_upload_ucode(vsc); -+ if (err) -+ goto err_drvdata; -+ -+ err = vsc7385_setup(vsc); -+ if (err) -+ goto err_drvdata; -+ -+ return 0; -+ -+err_drvdata: -+ dev_set_drvdata(&spi->dev, NULL); -+ kfree(vsc); -+ return err; -+} -+ -+static int vsc7385_remove(struct spi_device *spi) -+{ -+ struct vsc7385_data *vsc; -+ -+ vsc = dev_get_drvdata(&spi->dev); -+ dev_set_drvdata(&spi->dev, NULL); -+ kfree(vsc); -+ -+ return 0; -+} -+ -+static struct spi_driver vsc7385_driver = { -+ .driver = { -+ .name = DRV_NAME, -+ .bus = &spi_bus_type, -+ .owner = THIS_MODULE, -+ }, -+ .probe = vsc7385_probe, -+ .remove = vsc7385_remove, -+}; -+ -+static int __init vsc7385_init(void) -+{ -+ return spi_register_driver(&vsc7385_driver); -+} -+module_init(vsc7385_init); -+ -+static void __exit vsc7385_exit(void) -+{ -+ spi_unregister_driver(&vsc7385_driver); -+} -+module_exit(vsc7385_exit); -+ -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_LICENSE("GPL v2"); -+ -diff --git a/target/linux/ar71xx/files/include/linux/leds-nu801.h b/target/linux/ar71xx/files/include/linux/leds-nu801.h -new file mode 100644 -index 0000000000..0fc310d277 ---- /dev/null -+++ b/target/linux/ar71xx/files/include/linux/leds-nu801.h -@@ -0,0 +1,38 @@ -+#ifndef __LEDS_NU801_H__ -+#define __LEDS_NU801_H__ -+ -+/* -+ * Definitions for LED driver for NU801 -+ * -+ * Kevin Paul Herbert -+ * Copyright (c) 2012, Meraki, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+ -+#include -+ -+struct led_nu801_template { -+ const char *device_name; /* Name of the platform device */ -+ const char *name; /* Name of this LED chain */ -+ int num_leds; /* Number of LEDs in the chain */ -+ unsigned cki; /* GPIO pin for CKI */ -+ unsigned sdi; /* GPIO pin for SDI */ -+ int lei; /* GPIO pin for LEI; < 0 if none */ -+ u32 ndelay; /* Delay in nanoseconds */ -+ enum led_brightness init_brightness[3]; /* Default rgb state */ -+#ifdef CONFIG_LEDS_TRIGGERS -+ const char *default_trigger; /* default trigger */ -+#endif -+ const char *led_colors[3]; /* rgb color order */ -+}; -+ -+struct led_nu801_platform_data { -+ int num_controllers; /* Numnber of controllers */ -+ struct led_nu801_template *template; /* Template per controller */ -+}; -+ -+#endif /* __LEDS_NU801_H__ */ -diff --git a/target/linux/ar71xx/files/include/linux/nxp_74hc153.h b/target/linux/ar71xx/files/include/linux/nxp_74hc153.h -new file mode 100644 -index 0000000000..20b8845e53 ---- /dev/null -+++ b/target/linux/ar71xx/files/include/linux/nxp_74hc153.h -@@ -0,0 +1,24 @@ -+/* -+ * NXP 74HC153 - Dual 4-input multiplexer defines -+ * -+ * Copyright (C) 2010 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#ifndef _NXP_74HC153_H -+#define _NXP_74HC153_H -+ -+#define NXP_74HC153_DRIVER_NAME "nxp-74hc153" -+ -+struct nxp_74hc153_platform_data { -+ unsigned gpio_base; -+ unsigned gpio_pin_s0; -+ unsigned gpio_pin_s1; -+ unsigned gpio_pin_1y; -+ unsigned gpio_pin_2y; -+}; -+ -+#endif /* _NXP_74HC153_H */ -diff --git a/target/linux/ar71xx/files/include/linux/platform/ar934x_nfc.h b/target/linux/ar71xx/files/include/linux/platform/ar934x_nfc.h -new file mode 100644 -index 0000000000..371aaee7f8 ---- /dev/null -+++ b/target/linux/ar71xx/files/include/linux/platform/ar934x_nfc.h -@@ -0,0 +1,39 @@ -+/* -+ * Platform data definition for the built-in NAND controller of the -+ * Atheros AR934x SoCs -+ * -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef _AR934X_NFC_PLATFORM_H -+#define _AR934X_NFC_PLATFORM_H -+ -+#define AR934X_NFC_DRIVER_NAME "ar934x-nfc" -+ -+struct mtd_info; -+struct mtd_partition; -+ -+enum ar934x_nfc_ecc_mode { -+ AR934X_NFC_ECC_SOFT = 0, -+ AR934X_NFC_ECC_HW, -+ AR934X_NFC_ECC_SOFT_BCH, -+}; -+ -+struct ar934x_nfc_platform_data { -+ const char *name; -+ struct mtd_partition *parts; -+ int nr_parts; -+ -+ bool swap_dma; -+ enum ar934x_nfc_ecc_mode ecc_mode; -+ -+ void (*hw_reset)(bool active); -+ void (*select_chip)(int chip_no); -+ int (*scan_fixup)(struct mtd_info *mtd); -+}; -+ -+#endif /* _AR934X_NFC_PLATFORM_H */ -diff --git a/target/linux/ar71xx/files/include/linux/platform_data/gpio-latch.h b/target/linux/ar71xx/files/include/linux/platform_data/gpio-latch.h -new file mode 100644 -index 0000000000..0450e679ec ---- /dev/null -+++ b/target/linux/ar71xx/files/include/linux/platform_data/gpio-latch.h -@@ -0,0 +1,14 @@ -+#ifndef _GPIO_LATCH_H_ -+#define _GPIO_LATCH_H_ -+ -+#define GPIO_LATCH_DRIVER_NAME "gpio-latch" -+ -+struct gpio_latch_platform_data { -+ int base; -+ int num_gpios; -+ int *gpios; -+ int le_gpio_index; -+ bool le_active_low; -+}; -+ -+#endif /* _GPIO_LATCH_H_ */ -diff --git a/target/linux/ar71xx/files/include/linux/platform_data/rb91x_nand.h b/target/linux/ar71xx/files/include/linux/platform_data/rb91x_nand.h -new file mode 100644 -index 0000000000..5f17fb8148 ---- /dev/null -+++ b/target/linux/ar71xx/files/include/linux/platform_data/rb91x_nand.h -@@ -0,0 +1,16 @@ -+#ifndef _RB91X_NAND_H_ -+#define _RB91X_NAND_H_ -+ -+#define RB91X_NAND_DRIVER_NAME "rb91x-nand" -+ -+struct rb91x_nand_platform_data { -+ int gpio_nce; /* chip enable, active low */ -+ int gpio_ale; /* address latch enable */ -+ int gpio_cle; /* command latch enable */ -+ int gpio_rdy; -+ int gpio_read; -+ int gpio_nrw; /* read/write enable, active low */ -+ int gpio_nle; /* latch enable, active low */ -+}; -+ -+#endif /* _RB91X_NAND_H_ */ -\ No newline at end of file -diff --git a/target/linux/ar71xx/files/include/linux/spi/vsc7385.h b/target/linux/ar71xx/files/include/linux/spi/vsc7385.h -new file mode 100644 -index 0000000000..1072ad7941 ---- /dev/null -+++ b/target/linux/ar71xx/files/include/linux/spi/vsc7385.h -@@ -0,0 +1,19 @@ -+/* -+ * Platform data definition for the Vitesse VSC7385 ethernet switch driver -+ * -+ * Copyright (C) 2009 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+struct vsc7385_platform_data { -+ void (*reset)(void); -+ char *ucode_name; -+ struct { -+ u32 tx_ipg:5; -+ u32 bit2:1; -+ u32 clk_sel:3; -+ } mac_cfg; -+}; -diff --git a/target/linux/ar71xx/generic/config-default b/target/linux/ar71xx/generic/config-default -new file mode 100644 -index 0000000000..25b58ae91e ---- /dev/null -+++ b/target/linux/ar71xx/generic/config-default -@@ -0,0 +1,227 @@ -+CONFIG_ATH79_DEV_AP9X_PCI=y -+CONFIG_ATH79_DEV_ETH=y -+CONFIG_ATH79_DEV_GPIO_BUTTONS=y -+CONFIG_ATH79_DEV_LEDS_GPIO=y -+CONFIG_ATH79_DEV_M25P80=y -+CONFIG_ATH79_DEV_NFC=y -+CONFIG_ATH79_DEV_SPI=y -+CONFIG_ATH79_DEV_USB=y -+CONFIG_ATH79_DEV_WMAC=y -+CONFIG_ATH79_MACH_A60=y -+CONFIG_ATH79_MACH_ALFA_AP120C=y -+CONFIG_ATH79_MACH_ALFA_AP96=y -+CONFIG_ATH79_MACH_ALFA_NX=y -+CONFIG_ATH79_MACH_ALL0258N=y -+CONFIG_ATH79_MACH_ALL0315N=y -+CONFIG_ATH79_MACH_ANTMINER_S1=y -+CONFIG_ATH79_MACH_ANTMINER_S3=y -+CONFIG_ATH79_MACH_ANTROUTER_R1=y -+CONFIG_ATH79_MACH_AP121=y -+CONFIG_ATH79_MACH_AP121F=y -+CONFIG_ATH79_MACH_AP132=y -+CONFIG_ATH79_MACH_AP136=y -+CONFIG_ATH79_MACH_AP143=y -+CONFIG_ATH79_MACH_AP147=y -+CONFIG_ATH79_MACH_AP152=y -+CONFIG_ATH79_MACH_AP531B0=y -+CONFIG_ATH79_MACH_AP90Q=y -+CONFIG_ATH79_MACH_AP91_5G=y -+CONFIG_ATH79_MACH_AP96=y -+CONFIG_ATH79_MACH_ARCHER_C25_V1=y -+CONFIG_ATH79_MACH_ARCHER_C58_V1=y -+CONFIG_ATH79_MACH_ARCHER_C59_V1=y -+CONFIG_ATH79_MACH_ARCHER_C60_V1=y -+CONFIG_ATH79_MACH_ARCHER_C60_V2=y -+CONFIG_ATH79_MACH_ARCHER_C7=y -+CONFIG_ATH79_MACH_ARDUINO_YUN=y -+CONFIG_ATH79_MACH_AW_NR580=y -+CONFIG_ATH79_MACH_BHU_BXU2000N2_A=y -+CONFIG_ATH79_MACH_BSB=y -+CONFIG_ATH79_MACH_C55=y -+CONFIG_ATH79_MACH_CAP324=y -+CONFIG_ATH79_MACH_CAP4200AG=y -+CONFIG_ATH79_MACH_CARAMBOLA2=y -+CONFIG_ATH79_MACH_CF_E316N_V2=y -+CONFIG_ATH79_MACH_CF_E320N_V2=y -+CONFIG_ATH79_MACH_CF_E355AC=y -+CONFIG_ATH79_MACH_CF_E375AC=y -+CONFIG_ATH79_MACH_CF_E380AC_V1=y -+CONFIG_ATH79_MACH_CF_E380AC_V2=y -+CONFIG_ATH79_MACH_CF_E520N=y -+CONFIG_ATH79_MACH_CF_E530N=y -+CONFIG_ATH79_MACH_CPE505N=y -+CONFIG_ATH79_MACH_CPE510=y -+CONFIG_ATH79_MACH_CPE830=y -+CONFIG_ATH79_MACH_CPE870=y -+CONFIG_ATH79_MACH_CR3000=y -+CONFIG_ATH79_MACH_CR5000=y -+CONFIG_ATH79_MACH_DAP_1330_A1=y -+CONFIG_ATH79_MACH_DAP_2695_A1=y -+CONFIG_ATH79_MACH_DB120=y -+CONFIG_ATH79_MACH_DGL_5500_A1=y -+CONFIG_ATH79_MACH_DHP_1565_A1=y -+CONFIG_ATH79_MACH_DIR_505_A1=y -+CONFIG_ATH79_MACH_DIR_825_B1=y -+CONFIG_ATH79_MACH_DIR_825_C1=y -+CONFIG_ATH79_MACH_DIR_869_A1=y -+CONFIG_ATH79_MACH_DLAN_HOTSPOT=y -+CONFIG_ATH79_MACH_DLAN_PRO_1200_AC=y -+CONFIG_ATH79_MACH_DLAN_PRO_500_WP=y -+CONFIG_ATH79_MACH_DR342=y -+CONFIG_ATH79_MACH_DR344=y -+CONFIG_ATH79_MACH_DR531=y -+CONFIG_ATH79_MACH_DRAGINO2=y -+CONFIG_ATH79_MACH_E1700AC_V2=y -+CONFIG_ATH79_MACH_E2100L=y -+CONFIG_ATH79_MACH_E558_V2=y -+CONFIG_ATH79_MACH_E600G_V2=y -+CONFIG_ATH79_MACH_E750A_V4=y -+CONFIG_ATH79_MACH_E750G_V8=y -+CONFIG_ATH79_MACH_EAP120=y -+CONFIG_ATH79_MACH_EAP300V2=y -+CONFIG_ATH79_MACH_EAP7660D=y -+CONFIG_ATH79_MACH_EL_M150=y -+CONFIG_ATH79_MACH_EL_MINI=y -+CONFIG_ATH79_MACH_EPG5000=y -+CONFIG_ATH79_MACH_ESR1750=y -+CONFIG_ATH79_MACH_ESR900=y -+CONFIG_ATH79_MACH_EW_BALIN=y -+CONFIG_ATH79_MACH_EW_DORIN=y -+CONFIG_ATH79_MACH_FRITZ300E=y -+CONFIG_ATH79_MACH_FRITZ4020=y -+CONFIG_ATH79_MACH_FRITZ450E=y -+CONFIG_ATH79_MACH_GL_AR150=y -+CONFIG_ATH79_MACH_GL_AR300=y -+CONFIG_ATH79_MACH_GL_AR300M=y -+CONFIG_ATH79_MACH_GL_AR750=y -+CONFIG_ATH79_MACH_GL_AR750S=y -+CONFIG_ATH79_MACH_GL_DOMINO=y -+CONFIG_ATH79_MACH_GL_INET=y -+CONFIG_ATH79_MACH_GL_MIFI=y -+CONFIG_ATH79_MACH_GL_USB150=y -+CONFIG_ATH79_MACH_GS_MINIBOX_V32=y -+CONFIG_ATH79_MACH_GS_OOLITE_V1=y -+CONFIG_ATH79_MACH_GS_OOLITE_V5_2=y -+CONFIG_ATH79_MACH_HIWIFI_HC6361=y -+CONFIG_ATH79_MACH_HORNET_UB=y -+CONFIG_ATH79_MACH_JA76PF=y -+CONFIG_ATH79_MACH_JWAP003=y -+CONFIG_ATH79_MACH_JWAP230=y -+CONFIG_ATH79_MACH_KOALA=y -+CONFIG_ATH79_MACH_LAN_TURTLE=y -+CONFIG_ATH79_MACH_LIMA=y -+CONFIG_ATH79_MACH_MC_MAC1200R=y -+CONFIG_ATH79_MACH_MR12=y -+CONFIG_ATH79_MACH_MR16=y -+CONFIG_ATH79_MACH_MR1750=y -+CONFIG_ATH79_MACH_MR600=y -+CONFIG_ATH79_MACH_MR900=y -+CONFIG_ATH79_MACH_MYNET_N600=y -+CONFIG_ATH79_MACH_MYNET_N750=y -+CONFIG_ATH79_MACH_MYNET_REXT=y -+CONFIG_ATH79_MACH_MZK_W04NU=y -+CONFIG_ATH79_MACH_MZK_W300NH=y -+CONFIG_ATH79_MACH_N5Q=y -+CONFIG_ATH79_MACH_NBG6716=y -+CONFIG_ATH79_MACH_OM2P=y -+CONFIG_ATH79_MACH_OM5P=y -+CONFIG_ATH79_MACH_OM5P_AC=y -+CONFIG_ATH79_MACH_OM5P_ACv2=y -+CONFIG_ATH79_MACH_OMY_G1=y -+CONFIG_ATH79_MACH_OMY_X1=y -+CONFIG_ATH79_MACH_ONION_OMEGA=y -+CONFIG_ATH79_MACH_PB42=y -+CONFIG_ATH79_MACH_PB44=y -+CONFIG_ATH79_MACH_PQI_AIR_PEN=y -+CONFIG_ATH79_MACH_QIHOO_C301=y -+CONFIG_ATH79_MACH_R36A=y -+CONFIG_ATH79_MACH_R602N=y -+CONFIG_ATH79_MACH_RE355=y -+CONFIG_ATH79_MACH_RE450=y -+CONFIG_ATH79_MACH_RME_EG200=y -+CONFIG_ATH79_MACH_RUT9XX=y -+CONFIG_ATH79_MACH_RW2458N=y -+CONFIG_ATH79_MACH_SC1750=y -+CONFIG_ATH79_MACH_SC300M=y -+CONFIG_ATH79_MACH_SC450=y -+CONFIG_ATH79_MACH_SMART_300=y -+CONFIG_ATH79_MACH_SOM9331=y -+CONFIG_ATH79_MACH_SR3200=y -+CONFIG_ATH79_MACH_T830=y -+CONFIG_ATH79_MACH_TELLSTICK_ZNET_LITE=y -+CONFIG_ATH79_MACH_TEW_673GRU=y -+CONFIG_ATH79_MACH_TEW_732BR=y -+CONFIG_ATH79_MACH_TEW_823DRU=y -+CONFIG_ATH79_MACH_TL_MR3X20=y -+CONFIG_ATH79_MACH_TL_MR6400=y -+CONFIG_ATH79_MACH_TL_WDR3500=y -+CONFIG_ATH79_MACH_TL_WDR4300=y -+CONFIG_ATH79_MACH_TL_WDR6500_V2=y -+CONFIG_ATH79_MACH_TL_WPA8630=y -+CONFIG_ATH79_MACH_TL_WR1043ND=y -+CONFIG_ATH79_MACH_TL_WR1043ND_V2=y -+CONFIG_ATH79_MACH_TL_WR1043ND_V4=y -+CONFIG_ATH79_MACH_TL_WR1043N_V5=y -+CONFIG_ATH79_MACH_TL_WR2543N=y -+CONFIG_ATH79_MACH_TL_WR703N=y -+CONFIG_ATH79_MACH_TL_WR720N_V3=y -+CONFIG_ATH79_MACH_TL_WR810N=y -+CONFIG_ATH79_MACH_TL_WR810N_V2=y -+CONFIG_ATH79_MACH_TL_WR841N_V8=y -+CONFIG_ATH79_MACH_TL_WR841N_V9=y -+CONFIG_ATH79_MACH_TL_WR902AC_V1=y -+CONFIG_ATH79_MACH_TL_WR942N_V1=y -+CONFIG_ATH79_MACH_TS_D084=y -+CONFIG_ATH79_MACH_TUBE2H=y -+CONFIG_ATH79_MACH_UBNT=y -+CONFIG_ATH79_MACH_UBNT_UNIFIAC=y -+CONFIG_ATH79_MACH_UBNT_XM=y -+CONFIG_ATH79_MACH_WAM250=y -+CONFIG_ATH79_MACH_WEIO=y -+CONFIG_ATH79_MACH_WHR_HP_G300N=y -+CONFIG_ATH79_MACH_WIFI_PINEAPPLE_NANO=y -+CONFIG_ATH79_MACH_WLAE_AG300N=y -+CONFIG_ATH79_MACH_WLR8100=y -+CONFIG_ATH79_MACH_WNDAP360=y -+CONFIG_ATH79_MACH_WNDR3700=y -+CONFIG_ATH79_MACH_WNR2200=y -+CONFIG_ATH79_MACH_WP543=y -+CONFIG_ATH79_MACH_WPE72=y -+CONFIG_ATH79_MACH_WPJ342=y -+CONFIG_ATH79_MACH_WPJ344=y -+CONFIG_ATH79_MACH_WPJ531=y -+CONFIG_ATH79_MACH_WPJ558=y -+CONFIG_ATH79_MACH_WPJ563=y -+CONFIG_ATH79_MACH_WRT160NL=y -+CONFIG_ATH79_MACH_WRT400N=y -+CONFIG_ATH79_MACH_WRTNODE2Q=y -+CONFIG_ATH79_MACH_WZR_450HP2=y -+CONFIG_ATH79_MACH_WZR_HP_AG300H=y -+CONFIG_ATH79_MACH_WZR_HP_G300NH=y -+CONFIG_ATH79_MACH_WZR_HP_G300NH2=y -+CONFIG_ATH79_MACH_WZR_HP_G450H=y -+CONFIG_ATH79_MACH_XD3200=y -+CONFIG_ATH79_MACH_ZCN_1523H=y -+CONFIG_ATH79_NVRAM=y -+CONFIG_ATH79_PCI_ATH9K_FIXUP=y -+CONFIG_BLK_MQ_PCI=y -+CONFIG_GPIO_PCA953X=y -+# CONFIG_GPIO_PCA953X_IRQ is not set -+CONFIG_HW_HAS_PCI=y -+# CONFIG_LEDS_WNDR3700_USB is not set -+CONFIG_MYLOADER=y -+CONFIG_PCI=y -+CONFIG_PCI_AR724X=y -+CONFIG_PCI_DISABLE_COMMON_QUIRKS=y -+CONFIG_PCI_DOMAINS=y -+CONFIG_SERIAL_AR933X=y -+CONFIG_SERIAL_AR933X_CONSOLE=y -+CONFIG_SERIAL_AR933X_NR_UARTS=2 -+CONFIG_SOC_AR71XX=y -+CONFIG_SOC_AR724X=y -+CONFIG_SOC_AR913X=y -+CONFIG_SOC_AR933X=y -+CONFIG_SOC_AR934X=y -+CONFIG_SOC_QCA953X=y -+CONFIG_SOC_QCA955X=y -+CONFIG_SOC_QCA956X=y -diff --git a/target/linux/ar71xx/generic/profiles/00-default.mk b/target/linux/ar71xx/generic/profiles/00-default.mk -new file mode 100644 -index 0000000000..18fd385cc3 ---- /dev/null -+++ b/target/linux/ar71xx/generic/profiles/00-default.mk -@@ -0,0 +1,18 @@ -+# -+# Copyright (C) 2009 OpenWrt.org -+# -+# This is free software, licensed under the GNU General Public License v2. -+# See /LICENSE for more information. -+# -+ -+define Profile/Default -+ NAME:=Default Profile (all drivers) -+ PACKAGES:= \ -+ kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport -+ PRIORITY := 1 -+endef -+ -+define Profile/Default/Description -+ Default package set compatible with most boards. -+endef -+$(eval $(call Profile,Default)) -diff --git a/target/linux/ar71xx/generic/target.mk b/target/linux/ar71xx/generic/target.mk -new file mode 100644 -index 0000000000..0a26110d27 ---- /dev/null -+++ b/target/linux/ar71xx/generic/target.mk -@@ -0,0 +1,10 @@ -+BOARDNAME:=Generic -+FEATURES += squashfs -+ -+DEFAULT_PACKAGES += wpad-basic -+ -+define Target/Description -+ Build firmware images for generic Atheros AR71xx/AR913x/AR934x based boards. -+endef -+ -+ -diff --git a/target/linux/ar71xx/image/Makefile b/target/linux/ar71xx/image/Makefile -new file mode 100644 -index 0000000000..dea8338ddd ---- /dev/null -+++ b/target/linux/ar71xx/image/Makefile -@@ -0,0 +1,69 @@ -+# -+# Copyright (C) 2008-2011 OpenWrt.org -+# -+# This is free software, licensed under the GNU General Public License v2. -+# See /LICENSE for more information. -+# -+ -+include $(TOPDIR)/rules.mk -+include $(INCLUDE_DIR)/image.mk -+ -+KERNEL_LOADADDR = 0x80060000 -+ -+DEVICE_VARS += BOARDNAME CMDLINE CONSOLE LOADER_TYPE -+ -+ifeq ($(SUBTARGET),generic) -+include ./generic.mk -+include ./generic-legacy-devices.mk -+include ./generic-tp-link.mk -+include ./generic-ubnt.mk -+endif -+ifeq ($(SUBTARGET),tiny) -+include ./tiny.mk -+include ./tiny-tp-link.mk -+include ./tiny-legacy-devices.mk -+include ./tiny-senao.mk -+endif -+ifeq ($(SUBTARGET),nand) -+include ./nand.mk -+endif -+ifeq ($(SUBTARGET),mikrotik) -+include ./mikrotik.mk -+endif -+include ./legacy.mk -+ -+define Build/loader-common -+ rm -rf $@.src -+ $(MAKE) -C lzma-loader \ -+ PKG_BUILD_DIR="$@.src" \ -+ TARGET_DIR="$(dir $@)" LOADER_NAME="$(notdir $@)" \ -+ BOARD="$(BOARDNAME)" \ -+ LZMA_TEXT_START=0x80a00000 LOADADDR=0x80060000 \ -+ $(1) compile loader.$(LOADER_TYPE) -+ mv "$@.$(LOADER_TYPE)" "$@" -+ rm -rf $@.src -+endef -+ -+define Build/loader-kernel -+ $(call Build/loader-common,LOADER_DATA="$@") -+endef -+ -+define Build/loader-kernel-cmdline -+ $(call Build/loader-common,LOADER_DATA="$@" KERNEL_CMDLINE="$(CMDLINE)") -+endef -+ -+define Device/Default -+ BOARDNAME := -+ DEVICE_PROFILE = $$(BOARDNAME) -+ PROFILES = Default Minimal $$(DEVICE_PROFILE) -+ MTDPARTS := -+ BLOCKSIZE := 64k -+ CONSOLE := ttyS0,115200 -+ CMDLINE = $$(if $$(BOARDNAME),board=$$(BOARDNAME)) $$(if $$(MTDPARTS),mtdparts=$$(MTDPARTS)) $$(if $$(CONSOLE),console=$$(CONSOLE)) -+ KERNEL := kernel-bin | patch-cmdline | lzma | uImage lzma -+ COMPILE := -+ IMAGES := sysupgrade.bin -+ IMAGE/sysupgrade.bin = append-kernel | pad-to $$$$(BLOCKSIZE) | append-rootfs | pad-rootfs | check-size $$$$(IMAGE_SIZE) -+endef -+ -+$(eval $(call BuildImage)) -diff --git a/target/linux/ar71xx/image/common-tp-link.mk b/target/linux/ar71xx/image/common-tp-link.mk -new file mode 100644 -index 0000000000..99acd7e584 ---- /dev/null -+++ b/target/linux/ar71xx/image/common-tp-link.mk -@@ -0,0 +1,108 @@ -+DEVICE_VARS += LOADER_FLASH_OFFS TPLINK_BOARD_ID TPLINK_FLASHLAYOUT TPLINK_HEADER_VERSION TPLINK_HWID TPLINK_HWREV -+ -+# Arguments: -+define Build/loader-okli -+ dd if=$(KDIR)/loader-$(word 1,$(1)).$(LOADER_TYPE) bs=$(word 2,$(1)) conv=sync of="$@.new" -+ cat "$@" >> "$@.new" -+ mv "$@.new" "$@" -+endef -+ -+define Build/loader-okli-compile -+ $(call Build/loader-common,FLASH_OFFS=$(LOADER_FLASH_OFFS) FLASH_MAX=0 KERNEL_CMDLINE="$(CMDLINE)") -+endef -+ -+# combine kernel and rootfs into one image -+# mktplinkfw -+# is "sysupgrade" or "factory" -+# -+# -a align the rootfs start on an bytes boundary -+# -j add jffs2 end-of-filesystem markers -+# -s strip padding from end of the image -+# -X reserve bytes in the firmware image (hexval prefixed with 0x) -+define Build/mktplinkfw -+ -$(STAGING_DIR_HOST)/bin/mktplinkfw \ -+ -H $(TPLINK_HWID) -W $(TPLINK_HWREV) -F $(TPLINK_FLASHLAYOUT) -N OpenWrt -V $(REVISION) \ -+ -m $(TPLINK_HEADER_VERSION) \ -+ -k $(IMAGE_KERNEL) \ -+ -r $@ \ -+ -o $@.new \ -+ -j -X 0x40000 \ -+ -a $(call rootfs_align,$(FILESYSTEM)) \ -+ $(wordlist 2,$(words $(1)),$(1)) \ -+ $(if $(findstring sysupgrade,$(word 1,$(1))),-s) && mv $@.new $@ || rm -f $@ -+endef -+ -+define Build/uImageArcher -+ mkimage -A $(LINUX_KARCH) \ -+ -O linux -T kernel \ -+ -C $(1) -a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \ -+ -n '$(call toupper,$(LINUX_KARCH)) OpenWrt Linux-$(LINUX_VERSION)' -d $@ $@.new -+ @mv $@.new $@ -+endef -+ -+ -+define Device/tplink -+ TPLINK_HWREV := 0x1 -+ TPLINK_HEADER_VERSION := 1 -+ IMAGES := sysupgrade.bin factory.bin -+endef -+ -+define Device/tplink-lzma -+ $(Device/tplink) -+ KERNEL := kernel-bin | patch-cmdline | lzma -+ KERNEL_INITRAMFS := kernel-bin | patch-cmdline | lzma | tplink-v1-header -+ IMAGE/sysupgrade.bin := append-rootfs | mktplinkfw sysupgrade -+ IMAGE/factory.bin := append-rootfs | mktplinkfw factory -+endef -+ -+define Device/tplink-nolzma -+ $(Device/tplink) -+ LOADER_TYPE := gz -+ LOADER_FLASH_OFFS := 0x22000 -+ COMPILE := loader-$(1).gz -+ COMPILE/loader-$(1).gz := loader-okli-compile -+ KERNEL_NAME := vmlinux.bin.lzma -+ KERNEL := kernel-bin | uImage lzma -M 0x4f4b4c49 | loader-okli $(1) 7680 -+ KERNEL_INITRAMFS_NAME := vmlinux-initramfs.bin.lzma -+ KERNEL_INITRAMFS := kernel-bin | loader-kernel-cmdline | tplink-v1-header -+ IMAGE/sysupgrade.bin := append-rootfs | mktplinkfw sysupgrade -+ IMAGE/factory.bin := append-rootfs | mktplinkfw factory -+endef -+ -+define Device/tplink-safeloader -+ $(Device/tplink) -+ KERNEL := kernel-bin | patch-cmdline | lzma | tplink-v1-header -+ IMAGE/sysupgrade.bin := append-rootfs | tplink-safeloader sysupgrade | \ -+ append-metadata | check-size $$$$(IMAGE_SIZE) -+ IMAGE/factory.bin := append-rootfs | tplink-safeloader factory -+endef -+ -+define Device/tplink-4m -+ $(Device/tplink-nolzma) -+ TPLINK_FLASHLAYOUT := 4M -+ IMAGE_SIZE := 3904k -+endef -+ -+define Device/tplink-8m -+ $(Device/tplink-nolzma) -+ TPLINK_FLASHLAYOUT := 8M -+ IMAGE_SIZE := 7936k -+endef -+ -+define Device/tplink-4mlzma -+ $(Device/tplink-lzma) -+ TPLINK_FLASHLAYOUT := 4Mlzma -+ IMAGE_SIZE := 3904k -+endef -+ -+define Device/tplink-8mlzma -+ $(Device/tplink-lzma) -+ TPLINK_FLASHLAYOUT := 8Mlzma -+ IMAGE_SIZE := 7936k -+endef -+ -+define Device/tplink-16mlzma -+ $(Device/tplink-lzma) -+ TPLINK_FLASHLAYOUT := 16Mlzma -+ IMAGE_SIZE := 15872k -+endef -diff --git a/target/linux/ar71xx/image/generic-legacy-devices.mk b/target/linux/ar71xx/image/generic-legacy-devices.mk -new file mode 100644 -index 0000000000..cbe039cd29 ---- /dev/null -+++ b/target/linux/ar71xx/image/generic-legacy-devices.mk -@@ -0,0 +1,423 @@ -+define LegacyDevice/A60 -+ DEVICE_TITLE := OpenMesh A40/A60 -+ DEVICE_PACKAGES := om-watchdog kmod-ath10k-ct ath10k-firmware-qca988x-ct \ -+ mod-usb-core kmod-usb2 -+endef -+LEGACY_DEVICES += A60 -+ -+define LegacyDevice/ALFANX -+ DEVICE_TITLE := ALFA Network N2/N5 board -+endef -+LEGACY_DEVICES += ALFANX -+ -+define LegacyDevice/HORNETUB -+ DEVICE_TITLE := ALFA Network Hornet-UB board (8MB flash, 32MB ram) -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += HORNETUB -+ -+define LegacyDevice/TUBE2H8M -+ DEVICE_TITLE := ALFA Network Tube2H board (8MB flash) -+endef -+LEGACY_DEVICES += TUBE2H8M -+ -+define LegacyDevice/AP96 -+ DEVICE_TITLE := Atheros AP96 reference board -+ DEVICE_PACKAGES := kmod-usb2 -+endef -+LEGACY_DEVICES += AP96 -+ -+define LegacyDevice/WNDAP360 -+ DEVICE_TITLE := NETGEAR WNDAP360 -+endef -+LEGACY_DEVICES += WNDAP360 -+ -+define LegacyDevice/ALFAAP120C -+ DEVICE_TITLE := ALFA Network AP120C board -+endef -+LEGACY_DEVICES += ALFAAP120C -+ -+define LegacyDevice/ALFAAP96 -+ DEVICE_TITLE := ALFA Network AP96 board -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-rtc-pcf2123 -+endef -+LEGACY_DEVICES += ALFAAP96 -+ -+define LegacyDevice/ALL0258N -+ DEVICE_TITLE := Allnet ALL0258N -+ DEVICE_PACKAGES := rssileds -+endef -+LEGACY_DEVICES += ALL0258N -+ -+define LegacyDevice/ALL0315N -+ DEVICE_TITLE := Allnet ALL0315N -+ DEVICE_PACKAGES := rssileds -+endef -+LEGACY_DEVICES += ALL0315N -+ -+define LegacyDevice/AP121_8M -+ DEVICE_TITLE := Atheros AP121 reference board (8MB flash) -+ DEVICE_PACKAGES := kmod-usb2 -+endef -+LEGACY_DEVICES += AP121_8M -+ -+define LegacyDevice/AP121_16M -+ DEVICE_TITLE := Atheros AP121 reference board (16MB flash) -+ DEVICE_PACKAGES := kmod-usb2 -+endef -+LEGACY_DEVICES += AP121_16M -+ -+define LegacyDevice/AP132 -+ DEVICE_TITLE := Atheros AP132 reference board -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage -+endef -+LEGACY_DEVICES += AP132 -+ -+define LegacyDevice/AP135 -+ DEVICE_TITLE := Atheros AP135 reference board -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage -+endef -+LEGACY_DEVICES += AP135 -+ -+define LegacyDevice/AP136_010 -+ DEVICE_TITLE := Atheros AP136-010 reference board -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage -+endef -+LEGACY_DEVICES += AP136_010 -+ -+define LegacyDevice/AP136_020 -+ DEVICE_TITLE := Atheros AP136-020 reference board -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage -+endef -+LEGACY_DEVICES += AP136_020 -+ -+define LegacyDevice/AP143_8M -+ DEVICE_TITLE := Qualcomm Atheros AP143 reference board (8MB flash) -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage -+endef -+LEGACY_DEVICES += AP143_8M -+ -+define LegacyDevice/AP143_16M -+ DEVICE_TITLE := Qualcomm Atheros AP143 reference board (16MB flash) -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage -+endef -+LEGACY_DEVICES += AP143_16M -+ -+define LegacyDevice/AP147_010 -+ DEVICE_TITLE := Qualcomm Atheros AP147-010 reference board -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage -+endef -+LEGACY_DEVICES += AP147_010 -+ -+define LegacyDevice/AP152_16M -+ DEVICE_TITLE := Qualcomm Atheros AP152 reference board (16MB flash) -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage -+endef -+LEGACY_DEVICES += AP152_16M -+ -+define LegacyDevice/BXU2000N2 -+ DEVICE_TITLE := BHU BXU2000n-2 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage -+endef -+LEGACY_DEVICES += BXU2000N2 -+ -+define LegacyDevice/CAP4200AG -+ DEVICE_TITLE := Senao CAP4200AG -+endef -+LEGACY_DEVICES += CAP4200AG -+ -+define LegacyDevice/DB120 -+ DEVICE_TITLE := Atheros DB120 reference board -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage -+endef -+LEGACY_DEVICES += DB120 -+ -+define LegacyDevice/HORNETUBx2 -+ DEVICE_TITLE := ALFA Network Hornet-UB-x2 board (16MB flash, 64MB ram) -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += HORNETUBx2 -+ -+define LegacyDevice/TUBE2H16M -+ DEVICE_TITLE := ALFA Network Tube2H board (16MB flash) -+endef -+LEGACY_DEVICES += TUBE2H16M -+ -+define LegacyDevice/DIR505A1 -+ DEVICE_TITLE := D-Link DIR-505 rev. A1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += DIR505A1 -+ -+define LegacyDevice/DGL5500A1 -+ DEVICE_TITLE := D-Link DGL-5500 rev. A1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-ath10k-ct ath10k-firmware-qca988x-ct -+endef -+LEGACY_DEVICES += DGL5500A1 -+ -+define LegacyDevice/TEW823DRU -+ DEVICE_TITLE := TRENDNet TEW-823DRU -+ DEVICE_PACKAGES := kmod-usb2 kmod-ath10k-ct ath10k-firmware-qca988x-ct -+endef -+LEGACY_DEVICES += TEW823DRU -+ -+define LegacyDevice/DHP1565A1 -+ DEVICE_TITLE := D-Link DHP-1565 rev. A1 -+ DEVICE_PACKAGES := kmod-usb2 -+endef -+LEGACY_DEVICES += DHP1565A1 -+ -+define LegacyDevice/DIR825C1 -+ DEVICE_TITLE := D-Link DIR-825 rev. C1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += DIR825C1 -+ -+define LegacyDevice/DIR835A1 -+ DEVICE_TITLE := D-Link DIR-835 rev. A1 -+ DEVICE_PACKAGES := kmod-usb2 -+endef -+LEGACY_DEVICES += DIR835A1 -+ -+define LegacyDevice/TEW732BR -+ DEVICE_TITLE := TRENDNet TEW-732BR -+endef -+LEGACY_DEVICES += TEW732BR -+ -+define LegacyDevice/WRT160NL -+ DEVICE_TITLE := Linksys WRT160NL -+ DEVICE_PACKAGES := kmod-usb2 -+endef -+LEGACY_DEVICES += WRT160NL -+ -+define LegacyDevice/MYNETREXT -+ DEVICE_TITLE := Western Digital My Net Wi-Fi Range Extender -+ DEVICE_PACKAGES := rssileds -+endef -+LEGACY_DEVICES += MYNETREXT -+ -+define LegacyDevice/DIR825B1 -+ DEVICE_TITLE := D-Link DIR-825 rev. B1 -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += DIR825B1 -+ -+define LegacyDevice/TEW673GRU -+ DEVICE_TITLE := TRENDNet TEW-673GRU -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 -+endef -+LEGACY_DEVICES += TEW673GRU -+ -+define LegacyDevice/DLRTDEV01 -+ DEVICE_TITLE := PowerCloud Systems dlrtdev01 model -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += DLRTDEV01 -+ -+define LegacyDevice/dLAN_Hotspot -+ DEVICE_TITLE := devolo dLAN Hotspot -+endef -+LEGACY_DEVICES += dLAN_Hotspot -+ -+define LegacyDevice/dLAN_pro_500_wp -+ DEVICE_TITLE := devolo dLAN pro 500 Wireless+ -+endef -+LEGACY_DEVICES += dLAN_pro_500_wp -+ -+define LegacyDevice/dLAN_pro_1200_ac -+ DEVICE_TITLE := devolo dLAN pro 1200+ WiFi ac -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca988x-ct -+endef -+LEGACY_DEVICES += dLAN_pro_1200_ac -+ -+define LegacyDevice/ESR900 -+ DEVICE_TITLE := EnGenius ESR900 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += ESR900 -+ -+define LegacyDevice/ESR1750 -+ DEVICE_TITLE := EnGenius ESR1750 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage kmod-ath10k-ct ath10k-firmware-qca988x-ct -+endef -+LEGACY_DEVICES += ESR1750 -+ -+define LegacyDevice/EPG5000 -+ DEVICE_TITLE := EnGenius EPG5000 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage kmod-ath10k-ct ath10k-firmware-qca988x-ct -+endef -+LEGACY_DEVICES += EPG5000 -+ -+define LegacyDevice/WP543_8M -+ DEVICE_TITLE := Compex WP543/WPJ543 (8MB flash) -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 -+endef -+LEGACY_DEVICES += WP543_8M -+ -+define LegacyDevice/WP543_16M -+ DEVICE_TITLE := Compex WP543/WPJ543 (16MB flash) -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 -+endef -+LEGACY_DEVICES += WP543_16M -+ -+define LegacyDevice/WPE72_8M -+ DEVICE_TITLE := Compex WPE72/WPE72NX (8MB flash) -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 -+endef -+LEGACY_DEVICES += WPE72_8M -+ -+define LegacyDevice/WPE72_16M -+ DEVICE_TITLE := Compex WPE72/WPE72NX (16MB flash) -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 -+endef -+LEGACY_DEVICES += WPE72_16M -+ -+define LegacyDevice/WNR2200 -+ DEVICE_TITLE := NETGEAR WNR2200 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += WNR2200 -+ -+define LegacyDevice/OM2P -+ DEVICE_TITLE := OpenMesh OM2P/OM2P-HS/OM2P-LC -+ DEVICE_PACKAGES := om-watchdog -+endef -+LEGACY_DEVICES += OM2P -+ -+define LegacyDevice/OM5P -+ DEVICE_TITLE := OpenMesh OM5P/OM5P-AN -+ DEVICE_PACKAGES := om-watchdog -+endef -+LEGACY_DEVICES += OM5P -+ -+define LegacyDevice/OM5PAC -+ DEVICE_TITLE := OpenMesh OM5P-AC -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca988x-ct om-watchdog -+endef -+LEGACY_DEVICES += OM5PAC -+ -+define LegacyDevice/MR600 -+ DEVICE_TITLE := OpenMesh MR600 -+ DEVICE_PACKAGES := om-watchdog -+endef -+LEGACY_DEVICES += MR600 -+ -+define LegacyDevice/MR900 -+ DEVICE_TITLE := OpenMesh MR900 -+ DEVICE_PACKAGES := om-watchdog -+endef -+LEGACY_DEVICES += MR900 -+ -+define LegacyDevice/MR1750 -+ DEVICE_TITLE := OpenMesh MR1750 -+ DEVICE_PACKAGES := om-watchdog kmod-ath10k-ct ath10k-firmware-qca988x-ct -+endef -+LEGACY_DEVICES += MR1750 -+ -+define LegacyDevice/ALL0305 -+ DEVICE_TITLE := Allnet ALL0305 -+ DEVICE_PACKAGES := fconfig kmod-ath5k -kmod-ath9k -+endef -+LEGACY_DEVICES += ALL0305 -+ -+define LegacyDevice/EAP7660D -+ DEVICE_TITLE := Senao EAP7660D -+endef -+LEGACY_DEVICES += EAP7660D -+ -+define LegacyDevice/JA76PF -+ DEVICE_TITLE := jjPlus JA76PF -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-hwmon-core kmod-i2c-core kmod-hwmon-lm75 -+endef -+LEGACY_DEVICES += JA76PF -+ -+define LegacyDevice/JA76PF2 -+ DEVICE_TITLE := jjPlus JA76PF2 -+endef -+LEGACY_DEVICES += JA76PF2 -+ -+define LegacyDevice/JWAP003 -+ DEVICE_TITLE := jjPlus JWAP003 -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 -+endef -+LEGACY_DEVICES += JWAP003 -+ -+define LegacyDevice/PB42 -+ DEVICE_TITLE := Atheros PB42 reference board -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 -+endef -+LEGACY_DEVICES += PB42 -+ -+define LegacyDevice/PB44 -+ DEVICE_TITLE := Atheros PB44 reference board -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 \ -+ vsc7385-ucode-pb44 vsc7395-ucode-pb44 -+endef -+LEGACY_DEVICES += PB44 -+ -+define LegacyDevice/MZKW04NU -+ DEVICE_TITLE := Planex MZK-W04NU -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += MZKW04NU -+ -+define LegacyDevice/MZKW300NH -+ DEVICE_TITLE := Planex MZK-W300NH -+endef -+LEGACY_DEVICES += MZKW300NH -+ -+define LegacyDevice/EAP300V2 -+ DEVICE_TITLE := EnGenius EAP300V2 -+endef -+LEGACY_DEVICES += EAP300V2 -+ -+define LegacyDevice/WRT400N -+ DEVICE_TITLE := Linksys WRT400N -+endef -+LEGACY_DEVICES += WRT400N -+ -+define LegacyDevice/WZRHPG300NH -+ DEVICE_TITLE := Buffalo WZR-HP-G300NH -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += WZRHPG300NH -+ -+define LegacyDevice/WZRHPG300NH2 -+ DEVICE_TITLE := Buffalo WZR-HP-G300NH2 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += WZRHPG300NH2 -+ -+define LegacyDevice/WZRHPAG300H -+ DEVICE_TITLE := Buffalo WZR-HP-AG300H -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += WZRHPAG300H -+ -+define LegacyDevice/WZRHPG450H -+ DEVICE_TITLE := Buffalo WZR-HP-G450H -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += WZRHPG450H -+ -+define LegacyDevice/WZR600DHP -+ DEVICE_TITLE := Buffalo WZR-600DHP -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += WZR600DHP -+ -+define LegacyDevice/WZR450HP2 -+ DEVICE_TITLE := Buffalo WZR-450HP2 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += WZR450HP2 -+ -+define LegacyDevice/ZCN1523H28 -+ DEVICE_TITLE := Zcomax ZCN-1523H-2-8 -+endef -+LEGACY_DEVICES += ZCN1523H28 -+ -+define LegacyDevice/ZCN1523H516 -+ DEVICE_TITLE := Zcomax ZCN-1523H-5-16 -+endef -+LEGACY_DEVICES += ZCN1523H516 -diff --git a/target/linux/ar71xx/image/generic-tp-link.mk b/target/linux/ar71xx/image/generic-tp-link.mk -new file mode 100644 -index 0000000000..dac5ad2850 ---- /dev/null -+++ b/target/linux/ar71xx/image/generic-tp-link.mk -@@ -0,0 +1,544 @@ -+include ./common-tp-link.mk -+ -+ -+define Device/archer-cxx -+ $(Device/tplink-safeloader) -+ KERNEL := kernel-bin | patch-cmdline | lzma | uImageArcher lzma -+endef -+ -+define Device/archer-c25-v1 -+ $(Device/archer-cxx) -+ DEVICE_TITLE := TP-LINK Archer C25 v1 -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca9887-ct -+ BOARDNAME := ARCHER-C25-V1 -+ TPLINK_BOARD_ID := ARCHER-C25-V1 -+ DEVICE_PROFILE := ARCHERC25V1 -+ IMAGE_SIZE := 7808k -+ MTDPARTS := spi0.0:128k(factory-uboot)ro,64k(u-boot)ro,7808k(firmware),128k(config)ro,64k(art)ro -+ SUPPORTED_DEVICES := archer-c25-v1 -+endef -+TARGET_DEVICES += archer-c25-v1 -+ -+define Device/archer-c58-v1 -+ $(Device/archer-cxx) -+ DEVICE_TITLE := TP-LINK Archer C58 v1 -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca9888-ct -+ BOARDNAME := ARCHER-C58-V1 -+ TPLINK_BOARD_ID := ARCHER-C58-V1 -+ DEVICE_PROFILE := ARCHERC58V1 -+ IMAGE_SIZE := 7936k -+ MTDPARTS := spi0.0:64k(u-boot)ro,64k(mac)ro,7936k(firmware),64k(tplink)ro,64k(art)ro -+ SUPPORTED_DEVICES := archer-c58-v1 -+endef -+TARGET_DEVICES += archer-c58-v1 -+ -+define Device/archer-c59-v1 -+ $(Device/archer-cxx) -+ DEVICE_TITLE := TP-LINK Archer C59 v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-ath10k-ct ath10k-firmware-qca9888-ct -+ BOARDNAME := ARCHER-C59-V1 -+ TPLINK_BOARD_ID := ARCHER-C59-V1 -+ DEVICE_PROFILE := ARCHERC59V1 -+ IMAGE_SIZE := 14528k -+ MTDPARTS := spi0.0:64k(u-boot)ro,64k(mac)ro,14528k(firmware),1664k(tplink)ro,64k(art)ro -+ SUPPORTED_DEVICES := archer-c59-v1 -+endef -+TARGET_DEVICES += archer-c59-v1 -+ -+define Device/archer-c59-v2 -+ $(Device/archer-c59-v1) -+ DEVICE_TITLE := TP-LINK Archer C59 v2 -+ BOARDNAME := ARCHER-C59-V2 -+ TPLINK_BOARD_ID := ARCHER-C59-V2 -+ DEVICE_PROFILE := ARCHERC59V2 -+ IMAGE_SIZE := 14400k -+ MTDPARTS := spi0.0:128k(factory-boot)ro,64k(u-boot)ro,64k(mac)ro,14400k(firmware),1664k(tplink)ro,64k@0xff0000(art)ro -+ SUPPORTED_DEVICES := archer-c59-v2 -+endef -+TARGET_DEVICES += archer-c59-v2 -+ -+define Device/archer-c60-v1 -+ $(Device/archer-cxx) -+ DEVICE_TITLE := TP-LINK Archer C60 v1 -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca9888-ct -+ BOARDNAME := ARCHER-C60-V1 -+ TPLINK_BOARD_ID := ARCHER-C60-V1 -+ DEVICE_PROFILE := ARCHERC60V1 -+ IMAGE_SIZE := 7936k -+ MTDPARTS := spi0.0:64k(u-boot)ro,64k(mac)ro,7936k(firmware),64k(tplink)ro,64k(art)ro -+ SUPPORTED_DEVICES := archer-c60-v1 -+endef -+TARGET_DEVICES += archer-c60-v1 -+ -+define Device/archer-c60-v2 -+ $(Device/archer-c60-v1) -+ DEVICE_TITLE := TP-LINK Archer C60 v2 -+ BOARDNAME := ARCHER-C60-V2 -+ TPLINK_BOARD_ID := ARCHER-C60-V2 -+ DEVICE_PROFILE := ARCHERC60V2 -+ IMAGE_SIZE := 7808k -+ MTDPARTS := spi0.0:192k(u-boot)ro,7808k(firmware),128k(tplink)ro,64k(art)ro -+ SUPPORTED_DEVICES := archer-c60-v2 -+endef -+TARGET_DEVICES += archer-c60-v2 -+ -+define Device/archer-c5-v1 -+ $(Device/tplink-16mlzma) -+ DEVICE_TITLE := TP-LINK Archer C5 v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ BOARDNAME := ARCHER-C5 -+ DEVICE_PROFILE := ARCHERC7 -+ TPLINK_HWID := 0xc5000001 -+endef -+TARGET_DEVICES += archer-c5-v1 -+ -+define Device/archer-c7-v1 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := TP-LINK Archer C7 v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := ARCHER-C7 -+ DEVICE_PROFILE := ARCHERC7 -+ TPLINK_HWID := 0x75000001 -+endef -+TARGET_DEVICES += archer-c7-v1 -+ -+define Device/archer-c7-v2 -+ $(Device/tplink-16mlzma) -+ DEVICE_TITLE := TP-LINK Archer C7 v2 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ BOARDNAME := ARCHER-C7-V2 -+ DEVICE_PROFILE := ARCHERC7 -+ TPLINK_HWID := 0xc7000002 -+ IMAGES := sysupgrade.bin factory.bin factory-us.bin factory-eu.bin -+ IMAGE/factory-us.bin := append-rootfs | mktplinkfw factory -C US -+ IMAGE/factory-eu.bin := append-rootfs | mktplinkfw factory -C EU -+endef -+TARGET_DEVICES += archer-c7-v2 -+ -+define Device/archer-c7-v2-il -+ $(Device/tplink-16mlzma) -+ DEVICE_TITLE := TP-LINK Archer C7 v2 (IL) -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ BOARDNAME := ARCHER-C7-V2 -+ DEVICE_PROFILE := ARCHERC7 -+ TPLINK_HWID := 0xc7000002 -+ TPLINK_HWREV := 0x494c0001 -+endef -+TARGET_DEVICES += archer-c7-v2-il -+ -+define Device/tl-wdr7500-v3 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := TP-LINK Archer C7 v3 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ BOARDNAME := ARCHER-C7 -+ DEVICE_PROFILE := ARCHERC7 -+ TPLINK_HWID := 0x75000003 -+endef -+TARGET_DEVICES += tl-wdr7500-v3 -+ -+define Device/archer-c7-v4 -+ $(Device/archer-cxx) -+ DEVICE_TITLE := TP-LINK Archer C7 v4 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ BOARDNAME := ARCHER-C7-V4 -+ TPLINK_BOARD_ID := ARCHER-C7-V4 -+ IMAGE_SIZE := 15104k -+ MTDPARTS := spi0.0:128k(factory-uboot)ro,128k(u-boot)ro,15104k(firmware),960k(config)ro,64k(art)ro -+ SUPPORTED_DEVICES := archer-c7-v4 -+endef -+TARGET_DEVICES += archer-c7-v4 -+ -+define Device/archer-c7-v5 -+ $(Device/archer-c7-v4) -+ DEVICE_TITLE := TP-LINK Archer C7 v5 -+ BOARDNAME := ARCHER-C7-V5 -+ TPLINK_BOARD_ID := ARCHER-C7-V5 -+ IMAGE_SIZE := 15360k -+ MTDPARTS := spi0.0:128k(factory-uboot)ro,128k(u-boot)ro,64k@0x50000(art)ro,128k@0x60000(info)ro,15360k@0xc0000(firmware) -+ SUPPORTED_DEVICES := archer-c7-v5 -+endef -+TARGET_DEVICES += archer-c7-v5 -+ -+define Device/cpe510-520-v1 -+ DEVICE_TITLE := TP-LINK CPE510/520 v1 -+ BOARDNAME := CPE510 -+ TPLINK_BOARD_ID := CPE510 -+ LOADER_TYPE := elf -+ LOADER_FLASH_OFFS := 0x43000 -+ COMPILE := loader-$(1).elf -+ COMPILE/loader-$(1).elf := loader-okli-compile -+ KERNEL := kernel-bin | lzma | uImage lzma -M 0x4f4b4c49 | loader-okli $(1) 12288 -+ IMAGES += factory.bin -+ IMAGE/sysupgrade.bin := append-rootfs | tplink-safeloader sysupgrade -+ IMAGE/factory.bin := append-rootfs | tplink-safeloader factory -+ DEVICE_PACKAGES := rssileds -+ MTDPARTS := spi0.0:128k(u-boot)ro,64k(partition-table)ro,64k(product-info)ro,2048k(kernel),5632k(rootfs),192k(config)ro,64k(ART)ro,7680k@0x40000(firmware) -+ IMAGE_SIZE := 7680k -+endef -+TARGET_DEVICES += cpe510-520-v1 -+ -+define Device/cpe510-v2 -+ $(Device/cpe510-520-v1) -+ DEVICE_TITLE := TP-LINK CPE510 v2 -+ BOARDNAME := CPE510V2 -+ TPLINK_BOARD_ID := CPE510V2 -+endef -+TARGET_DEVICES += cpe510-v2 -+ -+define Device/cpe210-220-v1 -+ $(Device/cpe510-520-v1) -+ DEVICE_TITLE := TP-LINK CPE210/220 v1 -+ BOARDNAME := CPE210 -+ TPLINK_BOARD_ID := CPE210 -+endef -+TARGET_DEVICES += cpe210-220-v1 -+ -+define Device/cpe210-v2 -+ $(Device/tplink-safeloader) -+ DEVICE_TITLE := TP-LINK CPE210 v2 -+ BOARDNAME := CPE210V2 -+ TPLINK_BOARD_ID := CPE210V2 -+ TPLINK_HWID := 0x0 -+ TPLINK_HWREV := 0 -+ MTDPARTS := spi0.0:128k(u-boot)ro,64k(partition-table)ro,64k(product-info)ro,7680k(firmware),192k(config)ro,64k(ART)ro -+ IMAGE_SIZE := 7680k -+ KERNEL := kernel-bin | patch-cmdline | lzma | tplink-v1-header -O -+ KERNEL_INITRAMFS := kernel-bin | patch-cmdline | lzma | tplink-v1-header -+ DEVICE_PACKAGES := rssileds -+endef -+TARGET_DEVICES += cpe210-v2 -+ -+define Device/cpe210-v3 -+ $(Device/tplink-safeloader) -+ DEVICE_TITLE := TP-LINK CPE210 v3 -+ BOARDNAME := CPE210V3 -+ TPLINK_BOARD_ID := CPE210V3 -+ TPLINK_HWID := 0x0 -+ TPLINK_HWREV := 0 -+ MTDPARTS := spi0.0:128k(u-boot)ro,64k(partition-table)ro,64k(product-info)ro,7680k(firmware),192k(config)ro,64k(ART)ro -+ IMAGE_SIZE := 7680k -+ KERNEL := kernel-bin | patch-cmdline | lzma | tplink-v1-header -O -+ KERNEL_INITRAMFS := kernel-bin | patch-cmdline | lzma | tplink-v1-header -+ DEVICE_PACKAGES := rssileds -+endef -+TARGET_DEVICES += cpe210-v3 -+ -+define Device/wbs210-v1 -+ $(Device/cpe510-520-v1) -+ DEVICE_TITLE := TP-LINK WBS210 v1 -+ BOARDNAME := WBS210 -+ TPLINK_BOARD_ID := WBS210 -+endef -+TARGET_DEVICES += wbs210-v1 -+ -+define Device/wbs510-v1 -+ $(Device/cpe510-520-v1) -+ DEVICE_TITLE := TP-LINK WBS510 v1 -+ BOARDNAME := WBS510 -+ TPLINK_BOARD_ID := WBS510 -+endef -+TARGET_DEVICES += wbs510-v1 -+ -+define Device/eap120-v1 -+ DEVICE_TITLE := TP-LINK EAP120 v1 -+ MTDPARTS := spi0.0:128k(u-boot)ro,64k(partition-table)ro,64k(product-info)ro,1536k(kernel),14336k(rootfs),192k(config)ro,64k(ART)ro,15872k@0x40000(firmware) -+ IMAGE_SIZE := 15872k -+ BOARDNAME := EAP120 -+ TPLINK_BOARD_ID := EAP120 -+ DEVICE_PROFILE := EAP120 -+ LOADER_TYPE := elf -+ KERNEL := kernel-bin | patch-cmdline | lzma | loader-kernel -+ IMAGES := sysupgrade.bin factory.bin -+ IMAGE/sysupgrade.bin := append-rootfs | tplink-safeloader sysupgrade -+ IMAGE/factory.bin := append-rootfs | tplink-safeloader factory -+endef -+TARGET_DEVICES += eap120-v1 -+ -+define Device/re355-v1 -+ $(Device/tplink-safeloader) -+ DEVICE_TITLE := TP-LINK RE355 v1 -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ MTDPARTS := spi0.0:128k(u-boot)ro,6016k(firmware),64k(partition-table)ro,64k(product-info)ro,1856k(config)ro,64k(art)ro -+ IMAGE_SIZE := 7936k -+ BOARDNAME := RE355 -+ TPLINK_BOARD_ID := RE355 -+ DEVICE_PROFILE := RE355 -+ TPLINK_HWID := 0x0 -+ TPLINK_HWREV := 0 -+ KERNEL := kernel-bin | patch-cmdline | lzma | tplink-v1-header -O -+ KERNEL_INITRAMFS := kernel-bin | patch-cmdline | lzma | tplink-v1-header -+endef -+TARGET_DEVICES += re355-v1 -+ -+define Device/re450-v1 -+ $(Device/tplink-safeloader) -+ DEVICE_TITLE := TP-LINK RE450 v1 -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ MTDPARTS := spi0.0:128k(u-boot)ro,6016k(firmware),64k(partition-table)ro,64k(product-info)ro,1856k(config)ro,64k(art)ro -+ IMAGE_SIZE := 7936k -+ BOARDNAME := RE450 -+ TPLINK_BOARD_ID := RE450 -+ DEVICE_PROFILE := RE450 -+ TPLINK_HWID := 0x0 -+ TPLINK_HWREV := 0 -+ KERNEL := kernel-bin | patch-cmdline | lzma | tplink-v1-header -O -+ KERNEL_INITRAMFS := kernel-bin | patch-cmdline | lzma | tplink-v1-header -+endef -+TARGET_DEVICES += re450-v1 -+ -+define Device/tl-mr6400-v1 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := TP-LINK TL-MR6400 v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-net kmod-usb-net-rndis kmod-usb-serial kmod-usb-serial-option adb-enablemodem -+ BOARDNAME := TL-MR6400 -+ DEVICE_PROFILE := TLMR6400 -+ TPLINK_HWID := 0x64000001 -+endef -+TARGET_DEVICES += tl-mr6400-v1 -+ -+define Device/tl-wdr3500-v1 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := TP-LINK TL-WDR3500 v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-WDR3500 -+ DEVICE_PROFILE := TLWDR4300 -+ TPLINK_HWID := 0x35000001 -+endef -+TARGET_DEVICES += tl-wdr3500-v1 -+ -+define Device/tl-wdr3600-v1 -+ $(Device/tl-wdr3500-v1) -+ DEVICE_TITLE := TP-LINK TL-WDR3600 v1 -+ BOARDNAME := TL-WDR4300 -+ TPLINK_HWID := 0x36000001 -+ IMAGE/factory.bin := append-rootfs | mktplinkfw factory -C US -+endef -+TARGET_DEVICES += tl-wdr3600-v1 -+ -+define Device/tl-wdr4300-v1 -+ $(Device/tl-wdr3600-v1) -+ DEVICE_TITLE := TP-LINK TL-WDR4300 v1 -+ TPLINK_HWID := 0x43000001 -+endef -+TARGET_DEVICES += tl-wdr4300-v1 -+ -+define Device/tl-wdr4300-v1-il -+ $(Device/tl-wdr3500-v1) -+ DEVICE_TITLE := TP-LINK TL-WDR4300 v1 (IL) -+ BOARDNAME := TL-WDR4300 -+ TPLINK_HWID := 0x43008001 -+endef -+TARGET_DEVICES += tl-wdr4300-v1-il -+ -+define Device/tl-wdr4310-v1 -+ $(Device/tl-wdr4300-v1-il) -+ DEVICE_TITLE := TP-LINK TL-WDR4310 v1 -+ TPLINK_HWID := 0x43100001 -+endef -+TARGET_DEVICES += tl-wdr4310-v1 -+ -+define Device/tl-wdr4900-v2 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := TP-LINK TL-WDR4900 v2 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-WDR4900-v2 -+ DEVICE_PROFILE := TLWDR4900V2 -+ TPLINK_HWID := 0x49000002 -+endef -+TARGET_DEVICES += tl-wdr4900-v2 -+ -+define Device/tl-wdr6500-v2 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := TP-LINK TL-WDR6500 v2 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ KERNEL := kernel-bin | patch-cmdline | lzma | uImage lzma -+ KERNEL_INITRAMFS := kernel-bin | patch-cmdline | lzma | uImage lzma | tplink-v1-header -+ BOARDNAME := TL-WDR6500-v2 -+ DEVICE_PROFILE := TLWDR6500V2 -+ TPLINK_HWID := 0x65000002 -+ TPLINK_HEADER_VERSION := 2 -+endef -+TARGET_DEVICES += tl-wdr6500-v2 -+ -+define Device/mw4530r-v1 -+ $(Device/tl-wdr4300-v1) -+ DEVICE_TITLE := Mercury MW4530R v1 -+ TPLINK_HWID := 0x45300001 -+endef -+TARGET_DEVICES += mw4530r-v1 -+ -+define Device/tl-wpa8630-v1 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := TP-LINK TL-WPA8630 v1 -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ BOARDNAME := TL-WPA8630 -+ DEVICE_PROFILE := TL-WPA8630 -+ TPLINK_HWID := 0x86300001 -+endef -+TARGET_DEVICES += tl-wpa8630-v1 -+ -+define Device/tl-wr1043n-v5 -+ $(Device/archer-cxx) -+ DEVICE_TITLE := TP-LINK TL-WR1043N v5 -+ BOARDNAME := TL-WR1043N-v5 -+ SUPPORTED_DEVICES := tl-wr1043n-v5 -+ DEVICE_PROFILE := TLWR1043 -+ MTDPARTS := spi0.0:128k(factory-uboot)ro,128k(u-boot)ro,15104k(firmware),128k(product-info)ro,640k(config)ro,64k(partition-table)ro,128k(logs)ro,64k(art)ro -+ IMAGE_SIZE := 15104k -+ TPLINK_BOARD_ID := TLWR1043NV5 -+endef -+TARGET_DEVICES += tl-wr1043n-v5 -+ -+define Device/tl-wr1043nd-v1 -+ $(Device/tplink-8m) -+ DEVICE_TITLE := TP-LINK TL-WR1043N/ND v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-WR1043ND -+ DEVICE_PROFILE := TLWR1043 -+ TPLINK_HWID := 0x10430001 -+endef -+TARGET_DEVICES += tl-wr1043nd-v1 -+ -+define Device/tl-wr1043nd-v2 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR1043N/ND v2 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-WR1043ND-v2 -+ DEVICE_PROFILE := TLWR1043 -+ TPLINK_HWID := 0x10430002 -+endef -+TARGET_DEVICES += tl-wr1043nd-v2 -+ -+define Device/tl-wr1043nd-v3 -+ $(Device/tl-wr1043nd-v2) -+ DEVICE_TITLE := TP-LINK TL-WR1043N/ND v3 -+ TPLINK_HWID := 0x10430003 -+endef -+TARGET_DEVICES += tl-wr1043nd-v3 -+ -+define Device/tl-wr1043nd-v4 -+ $(Device/tplink-safeloader) -+ DEVICE_TITLE := TP-LINK TL-WR1043N/ND v4 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-WR1043ND-v4 -+ DEVICE_PROFILE := TLWR1043 -+ TPLINK_HWID := 0x10430004 -+ MTDPARTS := spi0.0:128k(u-boot)ro,15552k(firmware),128k(product-info)ro,320k(config)ro,64k(partition-table)ro,128k(logs)ro,64k(ART)ro -+ IMAGE_SIZE := 15552k -+ TPLINK_BOARD_ID := TLWR1043NDV4 -+ KERNEL := kernel-bin | patch-cmdline | lzma | tplink-v1-header -O -+ KERNEL_INITRAMFS := kernel-bin | patch-cmdline | lzma | tplink-v1-header -+endef -+TARGET_DEVICES += tl-wr1043nd-v4 -+ -+define Device/tl-wr2543-v1 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR2543N/ND v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-WR2543N -+ DEVICE_PROFILE := TLWR2543 -+ TPLINK_HWID := 0x25430001 -+ IMAGE/sysupgrade.bin := append-rootfs | mktplinkfw sysupgrade -v 3.13.99 -+ IMAGE/factory.bin := append-rootfs | mktplinkfw factory -v 3.13.99 -+endef -+TARGET_DEVICES += tl-wr2543-v1 -+ -+define Device/tl-wr710n-v1 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR710N v1 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := TL-WR710N -+ DEVICE_PROFILE := TLWR710 -+ TPLINK_HWID := 0x07100001 -+ CONSOLE := ttyATH0,115200 -+ IMAGE/factory.bin := append-rootfs | mktplinkfw factory -C US -+endef -+TARGET_DEVICES += tl-wr710n-v1 -+ -+define Device/tl-wr710n-v2.1 -+ $(Device/tl-wr710n-v1) -+ DEVICE_TITLE := TP-LINK TL-WR710N v2.1 -+ TPLINK_HWID := 0x07100002 -+ TPLINK_HWREV := 0x00000002 -+endef -+TARGET_DEVICES += tl-wr710n-v2.1 -+ -+define Device/tl-wr810n-v1 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR810N v1 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := TL-WR810N -+ DEVICE_PROFILE := TLWR810 -+ TPLINK_HWID := 0x08100001 -+endef -+TARGET_DEVICES += tl-wr810n-v1 -+ -+define Device/tl-wr810n-v2 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR810N v2 -+ BOARDNAME := TL-WR810N-v2 -+ DEVICE_PROFILE := TLWR810 -+ TPLINK_HWID := 0x08100002 -+endef -+TARGET_DEVICES += tl-wr810n-v2 -+ -+define Device/tl-wr842n-v1 -+ $(Device/tplink-8m) -+ DEVICE_TITLE := TP-LINK TL-WR842N/ND v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-MR3420 -+ DEVICE_PROFILE := TLWR842 -+ TPLINK_HWID := 0x08420001 -+endef -+TARGET_DEVICES += tl-wr842n-v1 -+ -+define Device/tl-wr842n-v2 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR842N/ND v2 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-WR842N-v2 -+ DEVICE_PROFILE := TLWR842 -+ TPLINK_HWID := 0x8420002 -+endef -+TARGET_DEVICES += tl-wr842n-v2 -+ -+define Device/tl-wr842n-v3 -+ $(Device/tplink-16mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR842N/ND v3 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-WR842N-v3 -+ DEVICE_PROFILE := TLWR842 -+ TPLINK_HWID := 0x08420003 -+endef -+TARGET_DEVICES += tl-wr842n-v3 -+ -+define Device/tl-wr902ac-v1 -+ $(Device/tplink-safeloader) -+ DEVICE_TITLE := TP-LINK TL-WR902AC v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport \ -+ kmod-ath10k-ct ath10k-firmware-qca9887-ct -swconfig -uboot-envtools -+ BOARDNAME := TL-WR902AC-V1 -+ DEVICE_PROFILE := TLWR902 -+ TPLINK_BOARD_ID := TL-WR902AC-V1 -+ TPLINK_HWID := 0x0 -+ TPLINK_HWREV := 0 -+ SUPPORTED_DEVICES := tl-wr902ac-v1 -+ IMAGE_SIZE := 7360k -+ MTDPARTS := spi0.0:128k(u-boot)ro,7360k(firmware),640k(tplink)ro,64k(art)ro -+ KERNEL := kernel-bin | patch-cmdline | lzma | tplink-v1-header -O -+ KERNEL_INITRAMFS := kernel-bin | patch-cmdline | lzma | tplink-v1-header -+endef -+TARGET_DEVICES += tl-wr902ac-v1 -+ -+define Device/tl-wr942n-v1 -+ $(Device/archer-cxx) -+ DEVICE_TITLE := TP-LINK TL-WR942N v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-WR942N-V1 -+ TPLINK_BOARD_ID := TLWR942NV1 -+ DEVICE_PROFILE := TLWR942 -+ IMAGE_SIZE := 14464k -+ MTDPARTS := spi0.0:128k(u-boot)ro,14464k(firmware),64k(product-info)ro,64k(partition-table)ro,256k(oem-config)ro,1344k(oem-vars)ro,64k(ART)ro -+ SUPPORTED_DEVICES := tl-wr942n-v1 -+endef -+TARGET_DEVICES += tl-wr942n-v1 -diff --git a/target/linux/ar71xx/image/generic-ubnt.mk b/target/linux/ar71xx/image/generic-ubnt.mk -new file mode 100644 -index 0000000000..539f0d82b3 ---- /dev/null -+++ b/target/linux/ar71xx/image/generic-ubnt.mk -@@ -0,0 +1,319 @@ -+DEVICE_VARS += UBNT_BOARD UBNT_CHIP UBNT_TYPE UBNT_VERSION UBNT_REVISION -+ -+# On M (XW) devices the U-Boot as of version 1.1.4-s1039 doesn't like -+# VERSION_DIST being on the place of major(?) version number, so we need to -+# use some number. -+UBNT_REVISION := $(VERSION_DIST)-$(REVISION) -+ -+# mkubntimage is using the kernel image direct -+# routerboard creates partitions out of the ubnt header -+define Build/mkubntimage -+ -$(STAGING_DIR_HOST)/bin/mkfwimage \ -+ -B $(UBNT_BOARD) -v $(UBNT_TYPE).$(UBNT_CHIP).v6.0.0-$(VERSION_DIST)-$(REVISION) \ -+ -k $(IMAGE_KERNEL) \ -+ -r $@ \ -+ -o $@ -+endef -+ -+# all UBNT XM device expect the kernel image to have 1024k while flash, when -+# booting the image, the size doesn't matter. -+define Build/mkubntimage-split -+ -[ -f $@ ] && ( \ -+ dd if=$@ of=$@.old1 bs=1024k count=1; \ -+ dd if=$@ of=$@.old2 bs=1024k skip=1; \ -+ $(STAGING_DIR_HOST)/bin/mkfwimage \ -+ -B $(UBNT_BOARD) -v $(UBNT_TYPE).$(UBNT_CHIP).v$(UBNT_VERSION)-$(UBNT_REVISION) \ -+ -k $@.old1 \ -+ -r $@.old2 \ -+ -o $@; \ -+ rm $@.old1 $@.old2 ) -+endef -+ -+define Build/mkubntimage2 -+ -$(STAGING_DIR_HOST)/bin/mkfwimage2 -f 0x9f000000 \ -+ -v $(UBNT_TYPE).$(UBNT_CHIP).v6.0.0-$(VERSION_DIST)-$(REVISION) \ -+ -p jffs2:0x50000:0xf60000:0:0:$@ \ -+ -o $@.new -+ @mv $@.new $@ -+endef -+ -+ -+# UBNT_BOARD e.g. one of (XS2, XS5, RS, XM) -+# UBNT_TYPE e.g. one of (BZ, XM, XW) -+# UBNT_CHIP e.g. one of (ar7240, ar933x, ar934x) -+# UBNT_VERSION e.g. one of (6.0.0, 8.5.0) -+define Device/ubnt -+ DEVICE_PACKAGES := kmod-usb2 -+ DEVICE_PROFILE := UBNT -+ IMAGE_SIZE := 7552k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,7552k(firmware),256k(cfg)ro,64k(EEPROM)ro -+ UBNT_BOARD := XM -+ UBNT_VERSION := 6.0.0 -+ IMAGES := sysupgrade.bin factory.bin -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | append-rootfs | pad-rootfs | check-size $$$$(IMAGE_SIZE) -+ IMAGE/factory.bin := $$(IMAGE/sysupgrade.bin) | mkubntimage-split -+endef -+ -+define Device/ubnt-xm -+ $(Device/ubnt) -+ DEVICE_PACKAGES += kmod-usb-ohci -+ UBNT_TYPE := XM -+ UBNT_CHIP := ar7240 -+ KERNEL := kernel-bin | patch-cmdline | relocate-kernel | lzma | uImage lzma -+endef -+ -+define Device/ubnt-xw -+ $(Device/ubnt) -+ UBNT_TYPE := XW -+ UBNT_CHIP := ar934x -+ UBNT_VERSION := 6.0.4 -+ UBNT_REVISION := 42.$(UBNT_REVISION) -+endef -+ -+define Device/ubnt-bz -+ $(Device/ubnt) -+ UBNT_TYPE := BZ -+ UBNT_CHIP := ar7240 -+endef -+ -+define Device/rw2458n -+ $(Device/ubnt-xm) -+ DEVICE_TITLE := Ubiquiti RW2458N -+ BOARDNAME := RW2458N -+endef -+TARGET_DEVICES += rw2458n -+ -+define Device/ubnt-airrouter -+ $(Device/ubnt-xm) -+ DEVICE_TITLE := Ubiquiti AirRouter -+ BOARDNAME := UBNT-AR -+endef -+TARGET_DEVICES += ubnt-airrouter -+ -+define Device/ubnt-bullet-m -+ $(Device/ubnt-xm) -+ DEVICE_TITLE := Ubiquiti Bullet-M -+ DEVICE_PACKAGES += rssileds -+ BOARDNAME := UBNT-BM -+endef -+TARGET_DEVICES += ubnt-bullet-m -+ -+define Device/ubnt-rocket-m -+ $(Device/ubnt-xm) -+ DEVICE_TITLE := Ubiquiti Rocket-M -+ DEVICE_PACKAGES += rssileds -+ BOARDNAME := UBNT-RM -+endef -+TARGET_DEVICES += ubnt-rocket-m -+ -+define Device/ubnt-nano-m -+ $(Device/ubnt-xm) -+ DEVICE_TITLE := Ubiquiti Nano-M -+ DEVICE_PACKAGES += rssileds -+ BOARDNAME := UBNT-NM -+endef -+TARGET_DEVICES += ubnt-nano-m -+ -+define Device/ubnt-unifi -+ $(Device/ubnt-bz) -+ DEVICE_TITLE := Ubiquiti UniFi -+ BOARDNAME := UBNT-UF -+ DEVICE_PROFILE += UBNTUNIFI -+endef -+TARGET_DEVICES += ubnt-unifi -+ -+define Device/ubnt-unifiac -+ DEVICE_PACKAGES := kmod-usb2 -+ DEVICE_PROFILE := UBNT -+ IMAGE_SIZE := 7744k -+ MTDPARTS := spi0.0:384k(u-boot)ro,64k(u-boot-env)ro,7744k(firmware),7744k(ubnt-airos)ro,128k(bs),256k(cfg)ro,64k(EEPROM)ro -+ IMAGES := sysupgrade.bin -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | append-rootfs | pad-rootfs | check-size $$$$(IMAGE_SIZE) -+endef -+ -+define Device/ubnt-unifiac-lite -+ $(Device/ubnt-unifiac) -+ DEVICE_TITLE := Ubiquiti UniFi AC-Lite -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ DEVICE_PROFILE += UBNTUNIFIACLITE -+ BOARDNAME := UBNT-UF-AC-LITE -+endef -+TARGET_DEVICES += ubnt-unifiac-lite -+ -+define Device/ubnt-unifiac-lr -+ $(Device/ubnt-unifiac-lite) -+ DEVICE_TITLE := Ubiquiti UniFi AC-LR -+endef -+TARGET_DEVICES += ubnt-unifiac-lr -+ -+define Device/ubnt-unifiac-mesh -+ $(Device/ubnt-unifiac-lite) -+ DEVICE_TITLE := Ubiquiti UniFi AC-Mesh -+endef -+TARGET_DEVICES += ubnt-unifiac-mesh -+ -+define Device/ubnt-unifiac-pro -+ $(Device/ubnt-unifiac) -+ DEVICE_TITLE := Ubiquiti UniFi AC-Pro -+ DEVICE_PACKAGES += kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ DEVICE_PROFILE += UBNTUNIFIACPRO -+ BOARDNAME := UBNT-UF-AC-PRO -+endef -+TARGET_DEVICES += ubnt-unifiac-pro -+ -+define Device/ubnt-unifiac-mesh-pro -+ $(Device/ubnt-unifiac-pro) -+ DEVICE_TITLE := Ubiquiti UniFi AC-Mesh-Pro -+endef -+TARGET_DEVICES += ubnt-unifiac-mesh-pro -+ -+define Device/ubnt-unifi-outdoor -+ $(Device/ubnt-bz) -+ DEVICE_TITLE := Ubiquiti UniFi Outdoor -+ BOARDNAME := UBNT-U20 -+ DEVICE_PROFILE += UBNTUNIFIOUTDOOR -+endef -+TARGET_DEVICES += ubnt-unifi-outdoor -+ -+define Device/ubnt-nano-m-xw -+ $(Device/ubnt-xw) -+ DEVICE_TITLE := Ubiquiti Nano M XW -+ DEVICE_PACKAGES += rssileds -+ BOARDNAME := UBNT-NM-XW -+endef -+TARGET_DEVICES += ubnt-nano-m-xw -+ -+define Device/ubnt-lbe-m5 -+ $(Device/ubnt-xw) -+ DEVICE_TITLE := Ubiquiti Litebeam M5 -+ BOARDNAME := UBNT-LBE-M5 -+endef -+TARGET_DEVICES += ubnt-lbe-m5 -+ -+define Device/ubnt-loco-m-xw -+ $(Device/ubnt-xw) -+ DEVICE_TITLE := Ubiquiti Loco XW -+ DEVICE_PACKAGES += rssileds -+ BOARDNAME := UBNT-LOCO-XW -+endef -+TARGET_DEVICES += ubnt-loco-m-xw -+ -+define Device/ubnt-bullet-m-xw -+ $(Device/ubnt-xw) -+ DEVICE_TITLE := Ubiquiti Bullet-M XW -+ DEVICE_PACKAGES += rssileds -+ BOARDNAME := UBNT-BM-XW -+endef -+TARGET_DEVICES += ubnt-bullet-m-xw -+ -+define Device/ubnt-rocket-m-xw -+ $(Device/ubnt-xw) -+ DEVICE_TITLE := Ubiquiti Rocket M XW -+ DEVICE_PACKAGES += rssileds -+ BOARDNAME := UBNT-RM-XW -+endef -+TARGET_DEVICES += ubnt-rocket-m-xw -+ -+define Device/ubnt-rocket-m-ti -+ $(Device/ubnt-xw) -+ DEVICE_TITLE := Ubiquiti Rocket M TI -+ DEVICE_PACKAGES += rssileds -+ BOARDNAME := UBNT-RM-TI -+ UBNT_TYPE := TI -+endef -+TARGET_DEVICES += ubnt-rocket-m-ti -+ -+define Device/ubnt-air-gateway -+ $(Device/ubnt-xm) -+ DEVICE_TITLE := Ubiquiti Air Gateway -+ BOARDNAME := UBNT-AGW -+ UBNT_TYPE := AirGW -+ UBNT_CHIP := ar933x -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += ubnt-air-gateway -+ -+define Device/ubnt-air-gateway-pro -+ $(Device/ubnt-xm) -+ DEVICE_TITLE := Ubiquiti Air Gateway Pro -+ BOARDNAME := UBNT-AGWP -+ UBNT_TYPE := AirGWP -+ UBNT_CHIP := ar934x -+endef -+TARGET_DEVICES += ubnt-air-gateway-pro -+ -+define Device/ubdev01 -+ $(Device/ubnt-xm) -+ DEVICE_TITLE := Ubiquiti ubDEV01 -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,7488k(firmware),64k(certs),256k(cfg)ro,64k(EEPROM)ro -+ BOARDNAME := UBNT-UF -+ UBNT_BOARD := UBDEV01 -+endef -+TARGET_DEVICES += ubdev01 -+ -+define Device/ubnt-routerstation -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 -+ DEVICE_PROFILE := UBNT -+ IMAGE_SIZE := 16128k -+ IMAGES := sysupgrade.bin factory.bin -+ IMAGE/factory.bin := append-rootfs | pad-rootfs | mkubntimage -+ IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | combined-image | check-size $$$$(IMAGE_SIZE) -+ KERNEL := kernel-bin | patch-cmdline | lzma | pad-to $$(BLOCKSIZE) -+endef -+ -+define Device/ubnt-rs -+ $(Device/ubnt-routerstation) -+ DEVICE_TITLE := Ubiquiti RouterStation -+ BOARDNAME := UBNT-RS -+ DEVICE_PROFILE += UBNTRS -+ UBNT_BOARD := RS -+ UBNT_TYPE := RSx -+ UBNT_CHIP := ar7100 -+endef -+TARGET_DEVICES += ubnt-rs -+ -+define Device/ubnt-rspro -+ $(Device/ubnt-routerstation) -+ DEVICE_TITLE := Ubiquiti RouterStation Pro -+ BOARDNAME := UBNT-RSPRO -+ DEVICE_PROFILE += UBNTRSPRO -+ UBNT_BOARD := RSPRO -+ UBNT_TYPE := RSPRO -+ UBNT_CHIP := ar7100pro -+endef -+TARGET_DEVICES += ubnt-rspro -+ -+define Device/ubnt-ls-sr71 -+ $(Device/ubnt-routerstation) -+ DEVICE_TITLE := Ubiquiti LS-SR71 -+ BOARDNAME := UBNT-LS-SR71 -+ UBNT_BOARD := LS-SR71 -+ UBNT_TYPE := LS-SR71 -+ UBNT_CHIP := ar7100 -+endef -+TARGET_DEVICES += ubnt-ls-sr71 -+ -+define Device/ubnt-uap-pro -+ DEVICE_TITLE := Ubiquiti UAP Pro -+ KERNEL_SIZE := 2048k -+ IMAGE_SIZE := 15744k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,2048k(kernel),13696k(rootfs),256k(cfg)ro,64k(EEPROM)ro,15744k@0x50000(firmware) -+ UBNT_TYPE := BZ -+ UBNT_CHIP := ar934x -+ BOARDNAME := UAP-PRO -+ DEVICE_PROFILE := UBNT UAPPRO -+ KERNEL := kernel-bin | patch-cmdline | lzma | uImage lzma | jffs2 kernel0 -+ IMAGES := sysupgrade.bin factory.bin -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | check-size $$$$(IMAGE_SIZE) -+ IMAGE/factory.bin := $$(IMAGE/sysupgrade.bin) | mkubntimage2 -+endef -+TARGET_DEVICES += ubnt-uap-pro -+ -+define Device/ubnt-unifi-outdoor-plus -+ $(Device/ubnt-uap-pro) -+ DEVICE_TITLE := Ubiquiti UniFi Outdoor Plus -+ UBNT_CHIP := ar7240 -+ BOARDNAME := UBNT-UOP -+ DEVICE_PROFILE := UBNT -+endef -+TARGET_DEVICES += ubnt-unifi-outdoor-plus -diff --git a/target/linux/ar71xx/image/generic.mk b/target/linux/ar71xx/image/generic.mk -new file mode 100644 -index 0000000000..27e2a5fc22 ---- /dev/null -+++ b/target/linux/ar71xx/image/generic.mk -@@ -0,0 +1,1352 @@ -+DEVICE_VARS += DAP_SIGNATURE NETGEAR_BOARD_ID NETGEAR_HW_ID NETGEAR_KERNEL_MAGIC ROOTFS_SIZE -+DEVICE_VARS += SEAMA_SIGNATURE SEAMA_MTDBLOCK -+ -+define Build/alfa-network-rootfs-header -+ mkimage \ -+ -A mips -O linux -T filesystem -C lzma -a 0 -e 0 \ -+ -n 'RootfsImage' -d $@ $@.new -+ @mv $@.new $@ -+endef -+ -+define Build/append-md5sum-bin -+ $(STAGING_DIR_HOST)/bin/mkhash md5 $@ | sed 's/../\\\\x&/g' |\ -+ xargs echo -ne >> $@ -+endef -+ -+define Build/mkwrggimg -+ $(STAGING_DIR_HOST)/bin/mkwrggimg -b \ -+ -i $@ -o $@.imghdr -d /dev/mtdblock/1 \ -+ -m $(BOARDNAME) -s $(DAP_SIGNATURE) \ -+ -v $(VERSION_DIST) -B $(REVISION) -+ mv $@.imghdr $@ -+endef -+ -+define Build/mkdapimg2 -+ $(STAGING_DIR_HOST)/bin/mkdapimg2 \ -+ -i $@ -o $@.new \ -+ -s $(DAP_SIGNATURE) \ -+ -v $(VERSION_DIST)-$(firstword $(subst +, ,$(firstword $(subst -, ,$(REVISION))))) \ -+ -r Default \ -+ $(if $(1),-k $(1)) -+ mv $@.new $@ -+endef -+ -+define Build/netgear-squashfs -+ rm -rf $@.fs $@.squashfs -+ mkdir -p $@.fs/image -+ cp $@ $@.fs/image/uImage -+ $(STAGING_DIR_HOST)/bin/mksquashfs-lzma \ -+ $@.fs $@.squashfs \ -+ -noappend -root-owned -be -b 65536 \ -+ $(if $(SOURCE_DATE_EPOCH),-fixed-time $(SOURCE_DATE_EPOCH)) -+ -+ dd if=/dev/zero bs=1k count=1 >> $@.squashfs -+ mkimage \ -+ -A mips -O linux -T filesystem -C none \ -+ -M $(NETGEAR_KERNEL_MAGIC) \ -+ -a 0xbf070000 -e 0xbf070000 \ -+ -n 'MIPS $(VERSION_DIST) Linux-$(LINUX_VERSION)' \ -+ -d $@.squashfs $@ -+ rm -rf $@.squashfs $@.fs -+endef -+ -+define Build/netgear-uImage -+ $(call Build/uImage,$(1) -M $(NETGEAR_KERNEL_MAGIC)) -+endef -+ -+define Build/relocate-kernel -+ rm -rf $@.relocate -+ $(CP) ../../generic/image/relocate $@.relocate -+ $(MAKE) -j1 -C $@.relocate KERNEL_ADDR=$(KERNEL_LOADADDR) CROSS_COMPILE=$(TARGET_CROSS) -+ ( \ -+ dd if=$@.relocate/loader.bin bs=32 conv=sync && \ -+ perl -e '@s = stat("$@"); print pack("N", @s[7])' && \ -+ cat "$@" \ -+ ) > "$@.new" -+ mv "$@.new" "$@" -+ rm -rf $@.relocate -+endef -+ -+define Build/teltonika-fw-fake-checksum -+ # Teltonika U-Boot web based firmware upgrade/recovery routine compares -+ # 16 bytes from md5sum1[16] field in TP-Link v1 header (offset: 76 bytes -+ # from begin of the firmware file) with 16 bytes stored just before -+ # 0xdeadc0de marker. Values are only compared, MD5 sum is not verified. -+ let \ -+ offs="$$(stat -c%s $@) - 20"; \ -+ dd if=$@ bs=1 count=16 skip=76 |\ -+ dd of=$@ bs=1 count=16 seek=$$offs conv=notrunc -+endef -+ -+define Build/uImageHiWiFi -+ # Field ih_name needs to start with "tw150v1" -+ mkimage -A $(LINUX_KARCH) \ -+ -O linux -T kernel \ -+ -C $(1) -a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \ -+ -n 'tw150v1 $(call toupper,$(LINUX_KARCH)) $(VERSION_DIST) Linux-$(LINUX_VERSION)' -d $@ $@.new -+ @mv $@.new $@ -+endef -+ -+define Build/wrgg-pad-rootfs -+ $(STAGING_DIR_HOST)/bin/padjffs2 $(IMAGE_ROOTFS) -c 64 >>$@ -+endef -+ -+ -+define Device/ap121f -+ DEVICE_TITLE := ALFA Network AP121F -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage -swconfig -+ BOARDNAME := AP121F -+ IMAGE_SIZE := 16064k -+ CONSOLE := ttyATH0,115200 -+ MTDPARTS := spi0.0:192k(u-boot)ro,64k(u-boot-env),64k(art)ro,-(firmware) -+ SUPPORTED_DEVICES := ap121f -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | \ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += ap121f -+ -+define Device/ap531b0 -+ DEVICE_TITLE := Rockeetech AP531B0 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := AP531B0 -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += ap531b0 -+ -+define Device/ap90q -+ DEVICE_TITLE := YunCore AP80Q/AP90Q -+ BOARDNAME := AP90Q -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += ap90q -+ -+define Device/ap91-5g -+ DEVICE_TITLE := ALFA Network AP91-5G -+ DEVICE_PACKAGES := rssileds -swconfig -+ BOARDNAME := AP91-5G -+ IMAGE_SIZE := 7744k -+ KERNEL_SIZE := 1600k -+ ROOTFS_SIZE := 6144k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),6144k(rootfs),1600k(kernel),64k(config)ro,64k(art)ro,7744k@0x50000(firmware) -+ IMAGES := sysupgrade.bin factory.bin -+ IMAGE/factory.bin := append-rootfs | pad-rootfs |\ -+ alfa-network-rootfs-header | append-kernel | check-size $$$$(IMAGE_SIZE) -+ IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs |\ -+ pad-to $$$$(ROOTFS_SIZE) | append-kernel | check-size $$$$(IMAGE_SIZE) -+endef -+ -+define Device/arduino-yun -+ DEVICE_TITLE := Arduino Yun -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := Yun -+ IMAGE_SIZE := 15936k -+ CONSOLE := ttyATH0,250000 -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),15936k(firmware),64k(nvram),64k(art)ro -+endef -+TARGET_DEVICES += arduino-yun -+ -+define Device/bsb -+ DEVICE_TITLE := Smart Electronics Black Swift board -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := BSB -+ IMAGE_SIZE := 16000k -+ CONSOLE := ttyATH0,115200 -+ MTDPARTS := spi0.0:128k(u-boot)ro,64k(u-boot-env)ro,16128k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += bsb -+ -+define Device/carambola2 -+ DEVICE_TITLE := 8devices Carambola2 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := CARAMBOLA2 -+ IMAGE_SIZE := 16000k -+ CONSOLE := ttyATH0,115200 -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += carambola2 -+ -+define Device/cf-e316n-v2 -+ DEVICE_TITLE := COMFAST CF-E316N v2 -+ DEVICE_PACKAGES := -swconfig -uboot-envtools -+ BOARDNAME := CF-E316N-V2 -+ IMAGE_SIZE := 16192k -+ MTDPARTS := spi0.0:64k(u-boot)ro,64k(art)ro,16192k(firmware),64k(art-backup)ro -+endef -+TARGET_DEVICES += cf-e316n-v2 -+ -+define Device/cf-e320n-v2 -+ $(Device/cf-e316n-v2) -+ DEVICE_TITLE := COMFAST CF-E320N v2 -+ DEVICE_PACKAGES += kmod-usb2 -+ BOARDNAME := CF-E320N-V2 -+endef -+TARGET_DEVICES += cf-e320n-v2 -+ -+define Device/cf-e355ac-v1 -+ DEVICE_TITLE := COMFAST CF-E355AC v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-ath10k-ct ath10k-firmware-qca988x-ct \ -+ -swconfig -uboot-envtools -+ BOARDNAME := CF-E355AC-V1 -+ IMAGE_SIZE := 16192k -+ MTDPARTS := spi0.0:64k(u-boot)ro,64k(art)ro,16192k(firmware),64k(art-backup)ro -+endef -+TARGET_DEVICES += cf-e355ac-v1 -+ -+define Device/cf-e355ac-v2 -+ $(Device/cf-e355ac-v1) -+ DEVICE_TITLE := COMFAST CF-E355AC v2 -+ DEVICE_PACKAGES := kmod-usb2 kmod-ath10k-ct ath10k-firmware-qca9888-ct \ -+ -swconfig -uboot-envtools -+ BOARDNAME := CF-E355AC-V2 -+endef -+TARGET_DEVICES += cf-e355ac-v2 -+ -+define Device/cf-e375ac -+ DEVICE_TITLE := COMFAST CF-E375AC -+ DEVICE_PACKAGES := kmod-usb2 kmod-ath10k-ct ath10k-firmware-qca9888-ct \ -+ -uboot-envtools -+ BOARDNAME := CF-E375AC -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(art)ro,16000k(firmware),64k(art-backup)ro -+endef -+TARGET_DEVICES += cf-e375ac -+ -+define Device/cf-e380ac-v1 -+ DEVICE_TITLE := COMFAST CF-E380AC v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-ath10k-ct ath10k-firmware-qca988x-ct \ -+ -swconfig -uboot-envtools -+ BOARDNAME := CF-E380AC-V1 -+ IMAGE_SIZE := 16128k -+ MTDPARTS := spi0.0:128k(u-boot)ro,64k(art)ro,16128k(firmware),64k(art-backup)ro -+endef -+TARGET_DEVICES += cf-e380ac-v1 -+ -+define Device/cf-e380ac-v2 -+ $(Device/cf-e380ac-v1) -+ DEVICE_TITLE := COMFAST CF-E380AC v2 -+ BOARDNAME := CF-E380AC-V2 -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(art)ro,16000k(firmware),64k(art-backup)ro -+endef -+TARGET_DEVICES += cf-e380ac-v2 -+ -+define Device/cf-e385ac -+ DEVICE_TITLE := COMFAST CF-E385AC -+ DEVICE_PACKAGES := kmod-usb2 kmod-ath10k-ct ath10k-firmware-qca9984-ct \ -+ -uboot-envtools -+ BOARDNAME := CF-E385AC -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(art)ro,16000k(firmware),64k(art-backup)ro -+endef -+TARGET_DEVICES += cf-e385ac -+ -+define Device/cf-e520n -+ DEVICE_TITLE := COMFAST CF-E520N -+ DEVICE_PACKAGES := kmod-usb2 -swconfig -uboot-envtools -+ BOARDNAME := CF-E520N -+ IMAGE_SIZE := 8000k -+ MTDPARTS := spi0.0:64k(u-boot)ro,64k(art)ro,8000k(firmware),64k(art-backup)ro -+endef -+TARGET_DEVICES += cf-e520n -+ -+define Device/cf-e530n -+ $(Device/cf-e520n) -+ DEVICE_TITLE := COMFAST CF-E530N -+ BOARDNAME := CF-E530N -+endef -+TARGET_DEVICES += cf-e530n -+ -+define Device/cpe505n -+ DEVICE_TITLE := P&W CPE505N -+ BOARDNAME := CPE505N -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += cpe505n -+ -+define Device/cpe830 -+ $(Device/ap90q) -+ DEVICE_TITLE := YunCore CPE830 -+ DEVICE_PACKAGES := rssileds -+ BOARDNAME := CPE830 -+endef -+TARGET_DEVICES += cpe830 -+ -+define Device/cpe870 -+ DEVICE_TITLE := YunCore CPE870 -+ DEVICE_PACKAGES := rssileds -+ BOARDNAME := CPE870 -+ IMAGE_SIZE := 7936k -+ MTDPARTS := spi0.0:64k(u-boot)ro,64k(u-boot-env),7936k(firmware),64k(config)ro,64k(art)ro -+endef -+TARGET_DEVICES += cpe870 -+ -+define Device/dragino2 -+ BOARDNAME := DRAGINO2 -+ CONSOLE := ttyATH0,115200 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ DEVICE_TITLE := Dragino 2 (MS14) -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,16000k(firmware),64k(config)ro,64k(art)ro -+endef -+TARGET_DEVICES += dragino2 -+ -+define Device/e1700ac-v2-16M -+ DEVICE_TITLE := Qxwlan E1700AC v2 (16MB flash) -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca988x-ct \ -+ kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := E1700AC-V2 -+ SUPPORTED_DEVICES := e1700ac-v2 -+ IMAGE_SIZE := 15936k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),64k(pri-data)ro,64k(art)ro,-(firmware) -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) |\ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += e1700ac-v2-16M -+ -+define Device/e1700ac-v2-8M -+ $(Device/e1700ac-v2-16M) -+ DEVICE_TITLE := Qxwlan E1700AC v2 (8MB flash) -+ IMAGE_SIZE := 7744k -+endef -+TARGET_DEVICES += e1700ac-v2-8M -+ -+define Device/e558-v2-16M -+ DEVICE_TITLE := Qxwlan E558 v2 (16MB flash) -+ DEVICE_PACKAGES := kmod-usb2 -swconfig -+ BOARDNAME := E558-V2 -+ SUPPORTED_DEVICES := e558-v2 -+ IMAGE_SIZE := 15936k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),64k(pri-data)ro,64k(art),-(firmware) -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) |\ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += e558-v2-16M -+ -+define Device/e558-v2-8M -+ $(Device/e558-v2-16M) -+ DEVICE_TITLE := Qxwlan E558 v2 (8MB flash) -+ IMAGE_SIZE := 7744k -+endef -+TARGET_DEVICES += e558-v2-8M -+ -+define Device/e600g-v2-16M -+ DEVICE_TITLE := Qxwlan E600G v2 (16MB flash) -+ DEVICE_PACKAGES := kmod-usb2 -swconfig -+ BOARDNAME := E600G-V2 -+ SUPPORTED_DEVICES := e600g-v2 -+ IMAGE_SIZE := 15936k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),64k(pri-data)ro,64k(art)ro,-(firmware) -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) |\ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += e600g-v2-16M -+ -+define Device/e600g-v2-8M -+ $(Device/e600g-v2-16M) -+ DEVICE_TITLE := Qxwlan E600G v2 (8MB flash) -+ IMAGE_SIZE := 7744k -+endef -+TARGET_DEVICES += e600g-v2-8M -+ -+define Device/e600gac-v2-16M -+ DEVICE_TITLE := Qxwlan E600GAC v2 (16MB flash) -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca9887-ct \ -+ kmod-usb2 -swconfig -+ BOARDNAME := E600GAC-V2 -+ SUPPORTED_DEVICES := e600gac-v2 -+ IMAGE_SIZE := 15936k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),64k(pri-data)ro,64k(art)ro,-(firmware) -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) |\ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += e600gac-v2-16M -+ -+define Device/e600gac-v2-8M -+ $(Device/e600gac-v2-16M) -+ DEVICE_TITLE := Qxwlan E600GAC v2 (8MB flash) -+ IMAGE_SIZE := 7744k -+endef -+TARGET_DEVICES += e600gac-v2-8M -+ -+define Device/e750a-v4-16M -+ DEVICE_TITLE := Qxwlan E750A v4 (16MB flash) -+ DEVICE_PACKAGES := kmod-usb2 -swconfig -+ BOARDNAME := E750A-V4 -+ SUPPORTED_DEVICES := e750a-v4 -+ IMAGE_SIZE := 15936k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),64k(pri-data)ro,64k(art),-(firmware) -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) |\ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += e750a-v4-16M -+ -+define Device/e750a-v4-8M -+ $(Device/e750a-v4-16M) -+ DEVICE_TITLE := Qxwlan E750A v4 (8MB flash) -+ IMAGE_SIZE := 7744k -+endef -+TARGET_DEVICES += e750a-v4-8M -+ -+define Device/e750g-v8-16M -+ DEVICE_TITLE := Qxwlan E750G v8 (16MB flash) -+ DEVICE_PACKAGES := kmod-usb2 -swconfig -+ BOARDNAME := E750G-V8 -+ SUPPORTED_DEVICES := e750g-v8 -+ IMAGE_SIZE := 15936k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),64k(pri-data)ro,64k(art),-(firmware) -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) |\ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += e750g-v8-16M -+ -+define Device/e750g-v8-8M -+ $(Device/e750g-v8-16M) -+ DEVICE_TITLE := Qxwlan E750G v8 (8MB flash) -+ IMAGE_SIZE := 7744k -+endef -+TARGET_DEVICES += e750g-v8-8M -+ -+define Device/ew-balin -+ DEVICE_TITLE := Embedded Wireless Balin Platform -+ DEVICE_PACKAGES := kmod-usb-chipidea -+ BOARDNAME := EW-BALIN -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += ew-balin -+ -+define Device/ew-dorin -+ $(Device/ew-balin) -+ DEVICE_TITLE := Embedded Wireless Dorin Platform -+ BOARDNAME := EW-DORIN -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += ew-dorin -+ -+define Device/ew-dorin-router -+ $(Device/ew-dorin) -+ DEVICE_TITLE := Embedded Wireless Dorin Router Platform -+ BOARDNAME := EW-DORIN-ROUTER -+endef -+TARGET_DEVICES += ew-dorin-router -+ -+define Device/rme-eg200 -+ DEVICE_TITLE := eTactica EG-200 -+ DEVICE_PACKAGES := kmod-usb2 kmod-ledtrig-oneshot \ -+ kmod-usb-serial kmod-usb-serial-ftdi \ -+ kmod-usb-storage \ -+ kmod-fs-ext4 -+ BOARDNAME := RME-EG200 -+ IMAGE_SIZE := 16000k -+ CONSOLE := ttyATH0,115200 -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += rme-eg200 -+ -+define Device/weio -+ DEVICE_TITLE := WeIO -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := WEIO -+ IMAGE_SIZE := 16000k -+ CONSOLE := ttyATH0,115200 -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += weio -+ -+define Device/gl-ar150 -+ DEVICE_TITLE := GL.iNet GL-AR150 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := GL-AR150 -+ IMAGE_SIZE := 16000k -+ CONSOLE := ttyATH0,115200 -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += gl-ar150 -+ -+define Device/gl-ar300 -+ DEVICE_TITLE := GL.iNet GL-AR300 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := GL-AR300 -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += gl-ar300 -+ -+define Device/gl-ar300m -+ DEVICE_TITLE := GL.iNet GL-AR300M -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := GL-AR300M -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += gl-ar300m -+ -+define Device/gl-ar750 -+ DEVICE_TITLE := GL.iNet GL-AR750 -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca9887-ct \ -+ kmod-usb2 kmod-usb-storage -+ BOARDNAME := GL-AR750 -+ SUPPORTED_DEVICES := gl-ar750 -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),64k(art)ro,-(firmware) -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | \ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += gl-ar750 -+ -+define Device/gl-ar750s -+ DEVICE_TITLE := GL.iNet GL-AR750S -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca9887-ct \ -+ kmod-usb2 kmod-usb-storage -+ BOARDNAME := GL-AR750S -+ SUPPORTED_DEVICES := gl-ar750s -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),64k(art)ro,-(firmware) -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | \ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += gl-ar750s -+ -+define Device/gl-domino -+ DEVICE_TITLE := GL.iNet Domino Pi -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := DOMINO -+ IMAGE_SIZE := 16000k -+ CONSOLE := ttyATH0,115200 -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += gl-domino -+ -+define Device/gl-mifi -+ DEVICE_TITLE := GL.iNet GL-MiFi -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := GL-MIFI -+ IMAGE_SIZE := 16000k -+ CONSOLE := ttyATH0,115200 -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += gl-mifi -+ -+define Device/gl-usb150 -+ DEVICE_TITLE := GL.iNet GL-USB150 -+ DEVICE_PACKAGES := -swconfig -+ BOARDNAME := GL-USB150 -+ IMAGE_SIZE := 16000k -+ CONSOLE := ttyATH0,115200 -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,16000k(firmware),64k(art)ro -+ SUPPORTED_DEVICES := gl-usb150 -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | \ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += gl-usb150 -+ -+define Device/lan-turtle -+ $(Device/tplink-16mlzma) -+ DEVICE_TITLE := Hak5 LAN Turtle -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage \ -+ -kmod-ath9k -swconfig -uboot-envtools -wpad-basic -+ BOARDNAME := LAN-TURTLE -+ DEVICE_PROFILE := LANTURTLE -+ TPLINK_HWID := 0x5348334c -+ CONSOLE := ttyATH0,115200 -+ IMAGES := sysupgrade.bin -+endef -+TARGET_DEVICES += lan-turtle -+ -+define Device/lima -+ DEVICE_TITLE := 8devices Lima -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := LIMA -+ IMAGE_SIZE := 15616k -+ MTDPARTS := spi0.0:256k(u-boot)ro,256k(u-boot-env)ro,256k(art)ro,-(firmware) -+endef -+TARGET_DEVICES += lima -+ -+define Device/mr12 -+ DEVICE_TITLE := Meraki MR12 -+ DEVICE_PACKAGES := kmod-spi-gpio -+ BOARDNAME := MR12 -+ ROOTFS_SIZE := 13440k -+ IMAGE_SIZE := 15680k -+ MTDPARTS := spi0.0:256k(u-boot)ro,256k(u-boot-env)ro,13440k(rootfs),2240k(kernel),64k(mac),128k(art)ro,15680k@0x80000(firmware) -+ IMAGE/kernel.bin := append-kernel -+ IMAGE/rootfs.bin := append-rootfs | pad-rootfs -+ IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | pad-to $$$$(ROOTFS_SIZE) | append-kernel | check-size $$$$(IMAGE_SIZE) -+ IMAGES := kernel.bin rootfs.bin sysupgrade.bin -+endef -+TARGET_DEVICES += mr12 -+ -+define Device/mr16 -+ $(Device/mr12) -+ DEVICE_TITLE := Meraki MR16 -+ BOARDNAME := MR16 -+endef -+TARGET_DEVICES += mr16 -+ -+define Device/dr342 -+ DEVICE_TITLE := Wallys DR342 -+ DEVICE_PACKAGES := kmod-usb2 -swconfig -+ BOARDNAME := DR342 -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:192k(u-boot)ro,64k(u-boot-env),64k(partition-table)ro,16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += dr342 -+ -+define Device/dr344 -+ DEVICE_TITLE := Wallys DR344 -+ BOARDNAME := DR344 -+ KERNEL_SIZE := 1408k -+ ROOTFS_SIZE := 6336k -+ IMAGE_SIZE := 7744k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6336k(rootfs),1408k(kernel),64k(nvram),64k(art)ro,7744k@0x50000(firmware) -+ IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | pad-to $$$$(ROOTFS_SIZE) | append-kernel | check-size $$$$(IMAGE_SIZE) -+endef -+ -+define Device/dr531 -+ DEVICE_TITLE := Wallys DR531 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := DR531 -+ IMAGE_SIZE := 7808k -+ MTDPARTS := spi0.0:192k(u-boot)ro,64k(u-boot-env),64k(partition-table)ro,7808k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += dr531 -+ -+define Device/wndr3700 -+ DEVICE_TITLE := NETGEAR WNDR3700 -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport kmod-leds-wndr3700-usb -+ BOARDNAME := WNDR3700 -+ NETGEAR_KERNEL_MAGIC := 0x33373030 -+ NETGEAR_BOARD_ID := WNDR3700 -+ IMAGE_SIZE := 7680k -+ MTDPARTS := spi0.0:320k(u-boot)ro,128k(u-boot-env)ro,7680k(firmware),64k(art)ro -+ IMAGES := sysupgrade.bin factory.img factory-NA.img -+ KERNEL := kernel-bin | patch-cmdline | lzma -d20 | netgear-uImage lzma -+ IMAGE/default := append-kernel | pad-to $$$$(BLOCKSIZE) | netgear-squashfs | append-rootfs | pad-rootfs -+ IMAGE/sysupgrade.bin := $$(IMAGE/default) | check-size $$$$(IMAGE_SIZE) -+ IMAGE/factory.img := $$(IMAGE/default) | netgear-dni | check-size $$$$(IMAGE_SIZE) -+ IMAGE/factory-NA.img := $$(IMAGE/default) | netgear-dni NA | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += wndr3700 -+ -+define Device/wndr3700v2 -+ $(Device/wndr3700) -+ DEVICE_TITLE := NETGEAR WNDR3700 v2 -+ NETGEAR_BOARD_ID := WNDR3700v2 -+ NETGEAR_KERNEL_MAGIC := 0x33373031 -+ NETGEAR_HW_ID := 29763654+16+64 -+ IMAGE_SIZE := 15872k -+ MTDPARTS := spi0.0:320k(u-boot)ro,128k(u-boot-env)ro,15872k(firmware),64k(art)ro -+ IMAGES := sysupgrade.bin factory.img -+endef -+TARGET_DEVICES += wndr3700v2 -+ -+define Device/wndr3800 -+ $(Device/wndr3700v2) -+ DEVICE_TITLE := NETGEAR WNDR3800 -+ NETGEAR_BOARD_ID := WNDR3800 -+ NETGEAR_HW_ID := 29763654+16+128 -+endef -+TARGET_DEVICES += wndr3800 -+ -+define Device/wndr3800ch -+ $(Device/wndr3800) -+ DEVICE_TITLE := NETGEAR WNDR3800 (Ch) -+ NETGEAR_BOARD_ID := WNDR3800CH -+endef -+TARGET_DEVICES += wndr3800ch -+ -+define Device/wndrmac -+ $(Device/wndr3700v2) -+ DEVICE_TITLE := NETGEAR WNDRMAC -+ NETGEAR_BOARD_ID := WNDRMAC -+endef -+TARGET_DEVICES += wndrmac -+ -+define Device/wndrmacv2 -+ $(Device/wndr3800) -+ DEVICE_TITLE := NETGEAR WNDRMAC v2 -+ NETGEAR_BOARD_ID := WNDRMACv2 -+endef -+TARGET_DEVICES += wndrmacv2 -+ -+define Device/cap324 -+ DEVICE_TITLE := PowerCloud Systems CAP324 -+ BOARDNAME := CAP324 -+ DEVICE_PROFILE := CAP324 -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += cap324 -+ -+define Device/cr3000 -+ DEVICE_TITLE := PowerCloud Systems CR3000 -+ BOARDNAME := CR3000 -+ DEVICE_PROFILE := CR3000 -+ IMAGE_SIZE := 7808k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,7808k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += cr3000 -+ -+define Device/cr5000 -+ DEVICE_TITLE := PowerCloud Systems CR5000 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := CR5000 -+ DEVICE_PROFILE := CR5000 -+ IMAGE_SIZE := 7808k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,7808k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += cr5000 -+ -+define Device/packet-squirrel -+ $(Device/tplink-16mlzma) -+ DEVICE_TITLE := Hak5 Packet Squirrel -+ DEVICE_PACKAGES := kmod-usb2 \ -+ -kmod-ath9k -swconfig -uboot-envtools -wpad-basic -+ BOARDNAME := PACKET-SQUIRREL -+ DEVICE_PROFILE := PACKETSQUIRREL -+ TPLINK_HWID := 0x5351524c -+ CONSOLE := ttyATH0,115200 -+ IMAGES := sysupgrade.bin -+endef -+TARGET_DEVICES += packet-squirrel -+ -+define Device/pqi-air-pen -+ DEVICE_TITLE := PQI Air Pen -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage -+ BOARDNAME := PQI-AIR-PEN -+ IMAGE_SIZE := 7744k -+ CONSOLE := ttyATH0,115200 -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,64k(art)ro,64k(NVRAM)ro,7680k(firmware),64k(CONF) -+endef -+TARGET_DEVICES += pqi-air-pen -+ -+define Device/antminer-s1 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := Antminer-S1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-crypto-manager kmod-i2c-gpio-custom kmod-usb-hid -+ BOARDNAME := ANTMINER-S1 -+ DEVICE_PROFILE := ANTMINERS1 -+ TPLINK_HWID := 0x04440101 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += antminer-s1 -+ -+define Device/antminer-s3 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := Antminer-S3 -+ DEVICE_PACKAGES := kmod-usb2 kmod-crypto-manager kmod-i2c-gpio-custom kmod-usb-hid -+ BOARDNAME := ANTMINER-S3 -+ DEVICE_PROFILE := ANTMINERS3 -+ TPLINK_HWID := 0x04440301 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += antminer-s3 -+ -+define Device/antrouter-r1 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := Antrouter-R1 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := ANTROUTER-R1 -+ DEVICE_PROFILE := ANTROUTERR1 -+ TPLINK_HWID := 0x44440101 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += antrouter-r1 -+ -+define Device/el-m150 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := EasyLink EL-M150 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := EL-M150 -+ DEVICE_PROFILE := ELM150 -+ TPLINK_HWID := 0x01500101 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += el-m150 -+ -+define Device/el-mini -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := EasyLink EL-MINI -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := EL-MINI -+ DEVICE_PROFILE := ELMINI -+ TPLINK_HWID := 0x01530001 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += el-mini -+ -+define Device/gl-inet-6408A-v1 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := GL.iNet 6408 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := GL-INET -+ DEVICE_PROFILE := GLINET -+ TPLINK_HWID := 0x08000001 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += gl-inet-6408A-v1 -+ -+define Device/gl-inet-6416A-v1 -+ $(Device/tplink-16mlzma) -+ DEVICE_TITLE := GL.iNet 6416 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := GL-INET -+ DEVICE_PROFILE := GLINET -+ TPLINK_HWID := 0x08000001 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += gl-inet-6416A-v1 -+ -+define Device/jwap230 -+ DEVICE_TITLE := jjPlus JWAP230 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := JWAP230 -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += jwap230 -+ -+define Device/koala -+ DEVICE_TITLE := OCEDO Koala -+ BOARDNAME := KOALA -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ IMAGE_SIZE := 7424k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),7424k(firmware),1536k(kernel2),5888k(rootfs2),1088k(data)ro,64k(id)ro,64k(art)ro -+endef -+TARGET_DEVICES += koala -+ -+define Device/r36a -+ DEVICE_TITLE := ALFA Network R36A -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -swconfig -+ BOARDNAME := R36A -+ SUPPORTED_DEVICES := r36a -+ IMAGE_SIZE := 15872k -+ MTDPARTS := spi0.0:384k(u-boot)ro,64k(u-boot-env),64k(art)ro,-(firmware) -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | \ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += r36a -+ -+define Device/r602n -+ DEVICE_TITLE := P&W R602N -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := R602N -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += r602n -+ -+define Device/rut900 -+ DEVICE_TITLE := Teltonika RUT900 -+ DEVICE_PACKAGES := kmod-usb2 -uboot-envtools -+ BOARDNAME := RUT900 -+ SUPPORTED_DEVICES := rut900 -+ IMAGE_SIZE := 15552k -+ MTDPARTS := spi0.0:128k(u-boot)ro,64k(config)ro,64k(art)ro,15552k(firmware),576k(event-log)ro -+ TPLINK_HWID := 0x35000001 -+ TPLINK_HWREV := 0x1 -+ TPLINK_HEADER_VERSION := 1 -+ KERNEL := kernel-bin | patch-cmdline | lzma | tplink-v1-header -+ KERNEL_INITRAMFS := kernel-bin | patch-cmdline | lzma | uImage lzma -+ IMAGES := sysupgrade.bin factory.bin -+ IMAGE/factory.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | append-rootfs |\ -+ pad-rootfs | teltonika-fw-fake-checksum | append-string master |\ -+ append-md5sum-bin | check-size $$$$(IMAGE_SIZE) -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) |\ -+ append-rootfs | pad-rootfs | append-metadata |\ -+ check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += rut900 -+ -+define Device/mc-mac1200r -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := Mercury MAC1200R -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ BOARDNAME := MC-MAC1200R -+ DEVICE_PROFILE := MAC1200R -+ TPLINK_HWID := 0x12000001 -+endef -+TARGET_DEVICES += mc-mac1200r -+ -+define Device/minibox-v1 -+ $(Device/tplink-16mlzma) -+ DEVICE_TITLE := GainStrong MiniBox V1.0 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := MINIBOX-V1 -+ DEVICE_PROFILE := MINIBOXV1 -+ TPLINK_HWID := 0x3C000201 -+ CONSOLE := ttyATH0,115200 -+ IMAGES := sysupgrade.bin -+endef -+TARGET_DEVICES += minibox-v1 -+ -+define Device/minibox-v3.2 -+ $(Device/tplink-16mlzma) -+ DEVICE_TITLE := Gainstrong MiniBox V3.2 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-ath10k-ct ath10k-firmware-qca9887-ct -swconfig -+ BOARDNAME := MINIBOX-V3.2 -+ DEVICE_PROFILE := MINIBOXV32 -+ TPLINK_HWID := 0x3C00010C -+endef -+TARGET_DEVICES += minibox-v3.2 -+ -+define Device/oolite-v1 -+ $(Device/minibox-v1) -+ DEVICE_TITLE := GainStrong Oolite V1.0 -+ BOARDNAME := OOLITE-V1 -+ DEVICE_PROFILE := OOLITEV1 -+ TPLINK_HWID := 0x3C000101 -+endef -+TARGET_DEVICES += oolite-v1 -+ -+define Device/oolite-v5.2 -+ $(Device/tplink-16mlzma) -+ DEVICE_TITLE := GainStrong Oolite V5.2 -+ DEVICE_PACKAGES := ath10k-firmware-qca9887-ct kmod-ath10k-ct kmod-usb2 -+ BOARDNAME := OOLITE-V5-2 -+ DEVICE_PROFILE := OOLITEV52 -+ TPLINK_HWID := 0x3C00010B -+ IMAGES := sysupgrade.bin -+endef -+TARGET_DEVICES += oolite-v5.2 -+ -+define Device/oolite-v5.2-dev -+ $(Device/oolite-v5.2) -+ DEVICE_TITLE := GainStrong Oolite V5.2-Dev (development board) -+ BOARDNAME := OOLITE-V5-2-DEV -+ DEVICE_PROFILE := OOLITEV52DEV -+endef -+TARGET_DEVICES += oolite-v5.2-dev -+ -+define Device/omy-g1 -+ $(Device/tplink-16mlzma) -+ DEVICE_TITLE := OMYlink OMY-G1 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := OMY-G1 -+ DEVICE_PROFILE := OMYG1 -+ TPLINK_HWID := 0x06660101 -+endef -+TARGET_DEVICES += omy-g1 -+ -+define Device/omy-x1 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := OMYlink OMY-X1 -+ BOARDNAME := OMY-X1 -+ DEVICE_PROFILE := OMYX1 -+ TPLINK_HWID := 0x06660201 -+endef -+TARGET_DEVICES += omy-x1 -+ -+define Device/onion-omega -+ $(Device/tplink-16mlzma) -+ DEVICE_TITLE := Onion Omega -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage kmod-i2c-core kmod-i2c-gpio-custom kmod-spi-bitbang kmod-spi-dev kmod-spi-gpio kmod-spi-gpio-custom kmod-usb-serial -+ BOARDNAME := ONION-OMEGA -+ DEVICE_PROFILE := OMEGA -+ TPLINK_HWID := 0x04700001 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += onion-omega -+ -+define Device/sc1750 -+ DEVICE_TITLE := Abicom SC1750 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := SC1750 -+ IMAGE_SIZE := 15744k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),15744k(firmware),128k(APConfig),128k(kplog),64k(ART) -+endef -+TARGET_DEVICES += sc1750 -+ -+define Device/sc300m -+ DEVICE_TITLE := Abicom SC300M -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := SC300M -+ IMAGE_SIZE := 15744k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),15744k(firmware),128k(APConfig),128k(kplog),64k(ART) -+endef -+TARGET_DEVICES += sc300m -+ -+define Device/sc450 -+ DEVICE_TITLE := Abicom SC450 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := SC450 -+ IMAGE_SIZE := 15744k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),15744k(firmware),128k(APConfig),128k(kplog),64k(ART) -+endef -+TARGET_DEVICES += sc450 -+ -+define Device/smart-300 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := NC-LINK SMART-300 -+ BOARDNAME := SMART-300 -+ DEVICE_PROFILE := SMART-300 -+ TPLINK_HWID := 0x93410001 -+endef -+TARGET_DEVICES += smart-300 -+ -+define Device/som9331 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := OpenEmbed SOM9331 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage kmod-i2c-core kmod-i2c-gpio-custom kmod-spi-bitbang kmod-spi-dev kmod-spi-gpio kmod-spi-gpio-custom kmod-usb-serial -+ BOARDNAME := SOM9331 -+ DEVICE_PROFILE := SOM9331 -+ TPLINK_HWID := 0x04800054 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += som9331 -+ -+define Device/sr3200 -+ DEVICE_TITLE := YunCore SR3200 -+ DEVICE_PACKAGES := kmod-usb2 kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ BOARDNAME := SR3200 -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),16000k(firmware),64k(art)ro -+endef -+TARGET_DEVICES += sr3200 -+ -+define Device/xd3200 -+ $(Device/sr3200) -+ DEVICE_TITLE := YunCore XD3200 -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ BOARDNAME := XD3200 -+endef -+TARGET_DEVICES += xd3200 -+ -+define Device/t830 -+ DEVICE_TITLE := YunCore T830 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := T830 -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),16000k(firmware),64k(art)ro -+ SUPPORTED_DEVICES := t830 -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) |\ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += t830 -+ -+define Device/tellstick-znet-lite -+ $(Device/tplink-16mlzma) -+ DEVICE_TITLE := TellStick ZNet Lite -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-acm kmod-usb-serial kmod-usb-serial-pl2303 -+ BOARDNAME := TELLSTICK-ZNET-LITE -+ DEVICE_PROFILE := TELLSTICKZNETLITE -+ TPLINK_HWID := 0x00726001 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += tellstick-znet-lite -+ -+define Device/ts-d084 -+ $(Device/tplink-8mlzma) -+ DEVICE_TITLE := PISEN TS-D084 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := TS-D084 -+ DEVICE_PROFILE := TSD084 -+ TPLINK_HWID := 0x07030101 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += ts-d084 -+ -+define Device/n5q -+ DEVICE_TITLE := ALFA Network N5Q -+ DEVICE_PACKAGES := rssileds -swconfig -+ BOARDNAME := N5Q -+ SUPPORTED_DEVICES := n5q -+ IMAGE_SIZE := 15872k -+ MTDPARTS := spi0.0:384k(u-boot)ro,64k(u-boot-env),64k(art)ro,-(firmware) -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | \ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += n5q -+ -+define Device/NBG6616 -+ DEVICE_TITLE := ZyXEL NBG6616 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-usb-storage kmod-rtc-pcf8563 kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ BOARDNAME := NBG6616 -+ KERNEL_SIZE := 2048k -+ IMAGE_SIZE := 15323k -+ MTDPARTS := spi0.0:192k(u-boot)ro,64k(env),64k(RFdata)ro,384k(zyxel_rfsd),384k(romd),64k(header),2048k(kernel),13184k(rootfs),15232k@0x120000(firmware) -+ CMDLINE += mem=128M -+ RAS_BOARD := NBG6616 -+ RAS_ROOTFS_SIZE := 14464k -+ RAS_VERSION := "$(VERSION_DIST) $(REVISION)" -+ IMAGES := factory.bin sysupgrade.bin -+ KERNEL := kernel-bin | patch-cmdline | lzma | uImage lzma | jffs2 boot/vmlinux.lzma.uImage -+ IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | pad-to 64k | check-size $$$$(IMAGE_SIZE) | zyxel-ras-image -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | check-size $$$$(IMAGE_SIZE) -+ # We cannot currently build a factory image. It is the sysupgrade image -+ # prefixed with a header (which is actually written into the MTD device). -+ # The header is 2kiB and is filled with 0xff. The format seems to be: -+ # 2 bytes: 0x0000 -+ # 2 bytes: checksum of the data partition (big endian) -+ # 4 bytes: length of the contained image file (big endian) -+ # 32 bytes: Firmware Version string (NUL terminated, 0xff padded) -+ # 2 bytes: 0x0000 -+ # 2 bytes: checksum over the header partition (big endian) -+ # 32 bytes: Model (e.g. "NBG6616", NUL termiated, 0xff padded) -+ # rest: 0xff padding -+ # -+ # The checksums are calculated by adding up all bytes and if a 16bit -+ # overflow occurs, one is added and the sum is masked to 16 bit: -+ # csum = csum + databyte; if (csum > 0xffff) { csum += 1; csum &= 0xffff }; -+ # Should the file have an odd number of bytes then the byte len-0x800 is -+ # used additionally. -+ # The checksum for the header is calcualted over the first 2048 bytes with -+ # the firmware checksum as the placeholder during calculation. -+ # -+ # The header is padded with 0xff to the erase block size of the device. -+endef -+TARGET_DEVICES += NBG6616 -+ -+define Device/c-55 -+ DEVICE_TITLE := AirTight Networks C-55 -+ DEVICE_PACKAGES := kmod-ath9k -+ BOARDNAME := C-55 -+ KERNEL_SIZE := 2048k -+ IMAGE_SIZE := 15872k -+ MTDPARTS := spi0.0:256k(u-boot)ro,128k(u-boot-env)ro,2048k(kernel),13824k(rootfs),13824k(opt)ro,2624k(failsafe)ro,64k(art)ro,15872k@0x60000(firmware) -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += c-55 -+ -+define Device/hiwifi-hc6361 -+ DEVICE_TITLE := HiWiFi HC6361 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage \ -+ kmod-fs-ext4 kmod-nls-iso8859-1 e2fsprogs -+ BOARDNAME := HiWiFi-HC6361 -+ DEVICE_PROFILE := HIWIFI_HC6361 -+ IMAGE_SIZE := 16128k -+ KERNEL := kernel-bin | patch-cmdline | lzma | uImageHiWiFi lzma -+ CONSOLE := ttyATH0,115200 -+ MTDPARTS := spi0.0:64k(u-boot)ro,64k(bdinfo)ro,16128k(firmware),64k(backup)ro,64k(art)ro -+endef -+TARGET_DEVICES += hiwifi-hc6361 -+ -+define Device/seama -+ LOADER_TYPE := bin -+ BLOCKSIZE := 64k -+ KERNEL := kernel-bin | patch-cmdline | relocate-kernel | lzma -+ KERNEL_INITRAMFS := kernel-bin | patch-cmdline | lzma | seama -+ KERNEL_INITRAMFS_SUFFIX = $$(KERNEL_SUFFIX).seama -+ SEAMA_MTDBLOCK := 1 -+ IMAGES := sysupgrade.bin factory.bin -+ -+ # 64 bytes offset: -+ # - 28 bytes seama_header -+ # - 36 bytes of META data (4-bytes aligned) -+ IMAGE/default := append-kernel | pad-offset $$$$(BLOCKSIZE) 64 | append-rootfs -+ IMAGE/sysupgrade.bin := \ -+ $$(IMAGE/default) | seama | pad-rootfs | \ -+ check-size $$$$(IMAGE_SIZE) -+ IMAGE/factory.bin := \ -+ $$(IMAGE/default) | seama | pad-rootfs | \ -+ seama-seal | check-size $$$$(IMAGE_SIZE) -+ SEAMA_SIGNATURE := -+endef -+ -+define Device/dir-869-a1 -+ $(Device/seama) -+ DEVICE_TITLE := D-Link DIR-869 rev. A1 -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ BOARDNAME := DIR-869-A1 -+ IMAGE_SIZE := 15872k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,64k(devdata)ro,64k(devconf)ro,15872k(firmware),64k(radiocfg)ro -+ SEAMA_SIGNATURE := wrgac54_dlink.2015_dir869 -+ IMAGE/factory.bin := \ -+ $$(IMAGE/default) | pad-rootfs -x 64 | \ -+ seama | seama-seal -m "signature=$$$$(SEAMA_SIGNATURE)" | \ -+ check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += dir-869-a1 -+ -+define Device/mynet-n600 -+ $(Device/seama) -+ DEVICE_TITLE := Western Digital My Net N600 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := MYNET-N600 -+ IMAGE_SIZE := 15808k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,64k(devdata)ro,64k(devconf)ro,15872k(firmware),64k(radiocfg)ro -+ SEAMA_SIGNATURE := wrgnd16_wd_db600 -+endef -+TARGET_DEVICES += mynet-n600 -+ -+define Device/mynet-n750 -+ $(Device/seama) -+ DEVICE_TITLE := Western Digital My Net N750 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := MYNET-N750 -+ IMAGE_SIZE := 15808k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,64k(devdata)ro,64k(devconf)ro,15872k(firmware),64k(radiocfg)ro -+ SEAMA_SIGNATURE := wrgnd13_wd_av -+endef -+TARGET_DEVICES += mynet-n750 -+ -+define Device/qihoo-c301 -+ $(Device/seama) -+ DEVICE_TITLE := Qihoo C301 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ BOARDNAME := QIHOO-C301 -+ IMAGE_SIZE := 15744k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),64k(devdata),64k(devconf),15744k(firmware),64k(warm_start),64k(action_image_config),64k(radiocfg)ro;spi0.1:15360k(upgrade2),1024k(privatedata) -+ SEAMA_SIGNATURE := wrgac26_qihoo360_360rg -+endef -+TARGET_DEVICES += qihoo-c301 -+ -+define Device/dap-1330-a1 -+ DEVICE_TITLE := D-Link DAP-1330 rev. A1 -+ DEVICE_PACKAGES := rssileds -+ BOARDNAME := DAP-1330-A1 -+ IMAGES := factory.img sysupgrade.bin -+ IMAGE_SIZE := 7936k -+ IMAGE/factory.img := append-kernel | pad-to $$$$(BLOCKSIZE) | append-rootfs | pad-rootfs | check-size $$$$(IMAGE_SIZE) | mkdapimg2 917504 -+ MTDPARTS := spi0.0:64k(u-boot)ro,64k(art)ro,64k(mp)ro,64k(config)ro,7936k(firmware) -+ DAP_SIGNATURE := HONEYBEE-FIRMWARE-DAP-1330 -+endef -+TARGET_DEVICES += dap-1330-a1 -+ -+define Device/dap-2695-a1 -+ DEVICE_TITLE := D-Link DAP-2695 rev. A1 -+ DEVICE_PACKAGES := ath10k-firmware-qca988x-ct kmod-ath10k-ct -+ BOARDNAME := DAP-2695-A1 -+ IMAGES := factory.img sysupgrade.bin -+ IMAGE_SIZE := 15360k -+ IMAGE/factory.img := append-kernel | pad-offset 65536 160 | append-rootfs | wrgg-pad-rootfs | mkwrggimg | check-size $$$$(IMAGE_SIZE) -+ IMAGE/sysupgrade.bin := append-kernel | pad-offset 65536 160 | mkwrggimg | append-rootfs | wrgg-pad-rootfs | check-size $$$$(IMAGE_SIZE) -+ KERNEL := kernel-bin | patch-cmdline | relocate-kernel | lzma -+ KERNEL_INITRAMFS := $$(KERNEL) | mkwrggimg -+ MTDPARTS := spi0.0:256k(bootloader)ro,64k(bdcfg)ro,64k(rgdb)ro,64k(langpack)ro,15360k(firmware),448k(captival)ro,64k(certificate)ro,64k(radiocfg)ro -+ DAP_SIGNATURE := wapac02_dkbs_dap2695 -+endef -+TARGET_DEVICES += dap-2695-a1 -+ -+define Device/wam250 -+ DEVICE_TITLE := Samsung WAM250 -+ DEVICE_PACKAGES := kmod-usb2 -swconfig -+ BOARDNAME := WAM250 -+ IMAGE_SIZE := 15872k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),128k(nvram)ro,15872k(firmware),64k(art)ro -+ SUPPORTED_DEVICES := wam250 -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) |\ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += wam250 -+ -+define Device/wifi-pineapple-nano -+ $(Device/tplink-16mlzma) -+ DEVICE_TITLE := Hak5 WiFi Pineapple NANO -+ DEVICE_PACKAGES := kmod-ath9k-htc kmod-usb2 kmod-usb-storage \ -+ -swconfig -uboot-envtools -+ BOARDNAME := WIFI-PINEAPPLE-NANO -+ DEVICE_PROFILE := WIFIPINEAPPLENANO -+ TPLINK_HWID := 0x4e414e4f -+ CONSOLE := ttyATH0,115200 -+ IMAGES := sysupgrade.bin -+endef -+TARGET_DEVICES += wifi-pineapple-nano -+ -+define Device/wlr8100 -+ DEVICE_TITLE := Sitecom WLR-8100 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-usb3 \ -+ kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ BOARDNAME := WLR8100 -+ IMAGE_SIZE := 15424k -+ MTDPARTS := spi0.0:192k(u-boot)ro,64k(u-boot-env)ro,15424k(firmware),256k(manufacture)ro,64k(backup)ro,320k(storage)ro,64k(art)ro -+endef -+TARGET_DEVICES += wlr8100 -+ -+define Device/wpj-16m -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ MTDPARTS := spi0.0:192k(u-boot)ro,16128k(firmware),64k(art)ro -+ IMAGE_SIZE := 16128k -+endef -+ -+define Device/wpj342 -+ $(Device/wpj-16m) -+ DEVICE_TITLE := Compex WPJ342 (16MB flash) -+ BOARDNAME := WPJ342 -+endef -+TARGET_DEVICES += wpj342 -+ -+define Device/wpj344 -+ $(Device/wpj-16m) -+ DEVICE_TITLE := Compex WPJ344 (16MB flash) -+ BOARDNAME := WPJ344 -+ SUPPORTED_DEVICES := wpj344 -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | \ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += wpj344 -+ -+define Device/wpj531 -+ $(Device/wpj-16m) -+ DEVICE_TITLE := Compex WPJ531 (16MB flash) -+ BOARDNAME := WPJ531 -+endef -+TARGET_DEVICES += wpj531 -+ -+define Device/wpj558 -+ $(Device/wpj-16m) -+ DEVICE_TITLE := Compex WPJ558 (16MB flash) -+ BOARDNAME := WPJ558 -+ SUPPORTED_DEVICES := wpj558 -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | \ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += wpj558 -+ -+define Device/wpj563 -+ $(Device/wpj-16m) -+ DEVICE_TITLE := Compex WPJ563 (16MB flash) -+ BOARDNAME := WPJ563 -+endef -+TARGET_DEVICES += wpj563 -+ -+define Device/wrtnode2q -+ DEVICE_TITLE := WRTnode2Q -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage -+ BOARDNAME := WRTNODE2Q -+ IMAGE_SIZE := 16064k -+ MTDPARTS := spi0.0:192k(u-boot)ro,64k(u-boot-env),64k(art)ro,16064k(firmware),16384k@0x0(fullflash) -+endef -+TARGET_DEVICES += wrtnode2q -+ -+define Device/AVM -+ DEVICE_PACKAGES := fritz-tffs -uboot-envtools -+ KERNEL := kernel-bin | patch-cmdline | lzma | eva-image -+ KERNEL_INITRAMFS := $$(KERNEL) -+ IMAGE/sysupgrade.bin := append-kernel | pad-to 64k | \ -+ append-squashfs-fakeroot-be | pad-to 256 | \ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+ -+define Device/fritz300e -+ $(call Device/AVM) -+ DEVICE_TITLE := AVM FRITZ!WLAN Repeater 300E -+ DEVICE_PACKAGES += rssileds -swconfig -+ BOARDNAME := FRITZ300E -+ SUPPORTED_DEVICES := fritz300e -+ IMAGE_SIZE := 15232k -+endef -+TARGET_DEVICES += fritz300e -+ -+define Device/fritz4020 -+ $(call Device/AVM) -+ DEVICE_TITLE := AVM FRITZ!Box 4020 -+ DEVICE_PACKAGES += kmod-usb2 kmod-usb-storage -+ BOARDNAME := FRITZ4020 -+ SUPPORTED_DEVICES := fritz4020 -+ IMAGE_SIZE := 15232k -+endef -+TARGET_DEVICES += fritz4020 -+ -+define Device/fritz450e -+ $(call Device/AVM) -+ DEVICE_TITLE := AVM FRITZ!WLAN Repeater 450E -+ DEVICE_PACKAGES += -swconfig -+ BOARDNAME := FRITZ450E -+ SUPPORTED_DEVICES := fritz450e -+ IMAGE_SIZE := 15232k -+endef -+TARGET_DEVICES += fritz450e -diff --git a/target/linux/ar71xx/image/legacy.mk b/target/linux/ar71xx/image/legacy.mk -new file mode 100644 -index 0000000000..926ce780b4 ---- /dev/null -+++ b/target/linux/ar71xx/image/legacy.mk -@@ -0,0 +1,1059 @@ -+rootfs_type=$(patsubst squashfs-%,squashfs,$(1)) -+ -+# $(1): rootfs type. -+# $(2): board name. -+define imgname -+$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(call rootfs_type,$(1)) -+endef -+ -+define rootfs_align -+$(patsubst %-256k,0x40000,$(patsubst %-128k,0x20000,$(patsubst %-64k,0x10000,$(patsubst squashfs%,0x4,$(patsubst root.%,%,$(1)))))) -+endef -+ -+define sysupname -+$(call imgname,$(1),$(2))-sysupgrade.bin -+endef -+ -+define factoryname -+$(call imgname,$(1),$(2))-factory.bin -+endef -+ -+COMMA:=, -+ -+define mkcmdline -+$(if $(1),board=$(1) )$(if $(2),console=$(2)$(COMMA)$(3)) -+endef -+ -+define mtdpartsize -+$(shell sz=`echo '$(2)' | sed -ne 's/.*[:$(COMMA)]\([0-9]*\)k[@]*[0-9a-zx]*($(1)).*/\1/p'`; [ -n "$$sz" ] && echo $$(($$sz * 1024))) -+endef -+ -+# $(1) : name of image build method to be used, e.g., AthLzma. -+# $(2) : name of the build template to be used, e.g. 64k, 64kraw, 128k, etc. -+# $(3) : name of the profile to be defined. -+# $(4) : board name. -+# $(5)~$(7) : arguments for $(mkcmdline) -+# board=$(1) console=$(2),$(3) -+# $(8)~$(14): extra arguments. -+define SingleProfile -+ # $(1): action name, e.g. loader, buildkernel, squashfs, etc. -+ define Image/Build/Profile/$(3) -+ $$(call Image/Build/Template/$(2)/$$(1),$(1),$(4),$$(call mkcmdline,$(5),$(6),$(7)),$(8),$(9),$(10),$(11),$(12),$(13),$(14)) -+ endef -+endef -+ -+LOADER_MAKE := $(NO_TRACE_MAKE) -C lzma-loader KDIR=$(KDIR) -+ -+VMLINUX:=$(BIN_DIR)/$(IMG_PREFIX)-vmlinux -+UIMAGE:=$(BIN_DIR)/$(IMG_PREFIX)-uImage -+ -+# $(1): input file. -+# $(2): output file. -+# $(3): extra arguments for lzma. -+define CompressLzma -+ $(STAGING_DIR_HOST)/bin/lzma e $(1) -lc1 -lp2 -pb2 $(3) $(2) -+endef -+ -+define PatchKernel -+ cp $(KDIR)/vmlinux$(3) $(KDIR_TMP)/vmlinux$(3)-$(1) -+ $(STAGING_DIR_HOST)/bin/patch-cmdline $(KDIR_TMP)/vmlinux$(3)-$(1) "$(strip $(2))" -+endef -+ -+define PatchKernel/initramfs -+ $(call PatchKernel,$(1),$(2),-initramfs) -+ cp $(KDIR_TMP)/vmlinux-initramfs-$(1) $(call imgname,initramfs,$(1)).bin -+endef -+ -+# $(1): board name. -+# $(2): kernel command line. -+# $(3): extra argumetns for lzma. -+# $(4): name suffix, e.g. "-initramfs". -+define PatchKernelLzma -+ cp $(KDIR)/vmlinux$(4) $(KDIR_TMP)/vmlinux$(4)-$(1) -+ $(STAGING_DIR_HOST)/bin/patch-cmdline $(KDIR_TMP)/vmlinux$(4)-$(1) "$(strip $(2))" -+ $(call CompressLzma,$(KDIR_TMP)/vmlinux$(4)-$(1),$(KDIR_TMP)/vmlinux$(4)-$(1).bin.lzma,$(3)) -+endef -+ -+define PatchKernelGzip -+ cp $(KDIR)/vmlinux$(3) $(KDIR_TMP)/vmlinux$(3)-$(1) -+ $(STAGING_DIR_HOST)/bin/patch-cmdline $(KDIR_TMP)/vmlinux$(3)-$(1) "$(strip $(2))" -+ gzip -9n -c $(KDIR_TMP)/vmlinux$(3)-$(1) > $(KDIR_TMP)/vmlinux$(3)-$(1).bin.gz -+endef -+ -+ifneq ($(SUBTARGET),mikrotik) -+# $(1): compression method of the data. -+# $(2): extra arguments. -+# $(3): input data file. -+# $(4): output file. -+define MkuImage -+ mkimage -A mips -O linux -T kernel -a 0x80060000 -C $(1) $(2) \ -+ -e 0x80060000 -n 'MIPS $(VERSION_DIST) Linux-$(LINUX_VERSION)' \ -+ -d $(3) $(4) -+endef -+ -+# $(1): board name. -+# $(2): kernel command line. -+# $(3): extra arguments for lzma. -+# $(4): name suffix, e.g. "-initramfs". -+# $(5): extra arguments for mkimage. -+define MkuImageLzma -+ $(call PatchKernelLzma,$(1),$(2),$(3),$(4)) -+ $(call MkuImage,lzma,$(5),$(KDIR_TMP)/vmlinux$(4)-$(1).bin.lzma,$(KDIR_TMP)/vmlinux$(4)-$(1).uImage) -+endef -+ -+define MkuImageLzma/initramfs -+ $(call PatchKernelLzma,$(1),$(2),$(3),-initramfs) -+ $(call MkuImage,lzma,$(4),$(KDIR_TMP)/vmlinux-initramfs-$(1).bin.lzma,$(call imgname,initramfs,$(1))-uImage.bin) -+endef -+ -+define MkuImageGzip -+ $(call PatchKernelGzip,$(1),$(2)) -+ $(call MkuImage,gzip,,$(KDIR_TMP)/vmlinux-$(1).bin.gz,$(KDIR_TMP)/vmlinux-$(1).uImage) -+endef -+ -+define MkuImageGzip/initramfs -+ $(call PatchKernelGzip,$(1),$(2),-initramfs) -+ $(call MkuImage,gzip,,$(KDIR_TMP)/vmlinux-initramfs-$(1).bin.gz,$(call imgname,initramfs,$(1))-uImage.bin) -+endef -+ -+define MkuImageOKLI -+ $(call MkuImage,lzma,-M 0x4f4b4c49,$(KDIR)/vmlinux.bin.lzma,$(KDIR_TMP)/vmlinux-$(1).okli) -+endef -+endif -+ -+# $(1): name of the 1st file. -+# $(2): size limit of the 1st file if it is greater than 262144, or -+# the erase size of the flash if it is greater than zero and less -+# than 262144 -+# $(3): name of the 2nd file. -+# $(4): size limit of the 2nd file if $(2) is greater than 262144, otherwise -+# it is the size limit of the output file -+# $(5): name of the output file. -+# $(6): padding size. -+define CatFiles -+ if [ $(2) -eq 0 ]; then \ -+ filename="$(3)"; fstype=$${filename##*\.}; \ -+ case "$${fstype}" in \ -+ *) bs=`stat -c%s $(1)`;; \ -+ esac; \ -+ ( dd if=$(1) bs=$${bs} conv=sync; cat $(3) ) > $(5); \ -+ if [ -n "$(6)" ]; then \ -+ case "$${fstype}" in \ -+ squashfs*) \ -+ padjffs2 $(5) $(6); \ -+ ;; \ -+ esac; \ -+ fi; \ -+ if [ `stat -c%s $(5)` -gt $(4) ]; then \ -+ echo "Warning: $(5) is too big (> $(4) bytes)" >&2; \ -+ rm -f $(5); \ -+ fi; \ -+ else if [ $(2) -gt 262144 ]; then \ -+ if [ `stat -c%s "$(1)"` -gt $(2) ]; then \ -+ echo "Warning: $(1) is too big (> $(2) bytes)" >&2; \ -+ else if [ `stat -c%s $(3)` -gt $(4) ]; then \ -+ echo "Warning: $(3) is too big (> $(4) bytes)" >&2; \ -+ else \ -+ ( dd if=$(1) bs=$(2) conv=sync; dd if=$(3) ) > $(5); \ -+ fi; fi; \ -+ else \ -+ ( dd if=$(1) bs=$(2) conv=sync; dd if=$(3) ) > $(5); \ -+ if [ `stat -c%s $(5)` -gt $(4) ]; then \ -+ echo "Warning: $(5) is too big (> $(4) bytes)" >&2; \ -+ rm -f $(5); \ -+ fi; \ -+ fi; fi -+endef -+ -+# $(1): rootfs type. -+# $(2): board name. -+# $(3): kernel image size limit. -+# $(4): rootfs image size limit. -+# $(5): padding argument for padjffs2. -+Sysupgrade/KR=$(call CatFiles,$(2),$(3),$(KDIR)/root.$(1),$(4),$(call sysupname,$(1),$(5))) -+Sysupgrade/KRuImage=$(call CatFiles,$(KDIR_TMP)/vmlinux-$(2).uImage,$(3),$(KDIR)/root.$(1),$(4),$(call sysupname,$(1),$(2)),$(5)) -+Sysupgrade/RKuImage=$(call CatFiles,$(KDIR)/root.$(1),$(4),$(KDIR_TMP)/vmlinux-$(2).uImage,$(3),$(call sysupname,$(1),$(2))) -+ -+# $(1): ubinize ini file -+# $(2): working directory -+# $(3): output file -+# $(4): physical erase block size -+# $(5): minimum I/O unit size -+# $(6): custom options -+define ubinize -+ $(CP) $(1) $(2) -+ ( cd $(2); $(STAGING_DIR_HOST)/bin/ubinize -o $(3) -p $(4) -m $(5) $(6) $(1)) -+endef -+ -+# -+# Embed lzma-compressed kernel inside lzma-loader. -+# -+# $(1), suffix of output filename, e.g. generic, lowercase board name, etc. -+# $(2), suffix of target file to build, e.g. bin, gz, elf -+# $(3), kernel command line to pass from lzma-loader to kernel -+# $(4), unused here -+# $(5), suffix of kernel filename, e.g. -initramfs, or empty -+define Image/BuildLoader -+ -rm -rf $(KDIR)/lzma-loader -+ $(LOADER_MAKE) LOADER=loader-$(1).$(2) KERNEL_CMDLINE="$(3)"\ -+ LZMA_TEXT_START=0x80a00000 LOADADDR=0x80060000 \ -+ LOADER_DATA="$(KDIR)/vmlinux$(5).bin.lzma" BOARD="$(1)" \ -+ compile loader.$(2) -+ -$(if $(5),$(CP) $(KDIR)/loader-$(1).$(2) $(KDIR)/loader-$(1)$(5).$(2)) -+endef -+ -+# -+# Build lzma-loader alone which will search for lzma-compressed kernel identified by -+# uImage header with magic "OKLI" at boot time. -+# -+# $(4), offset into the flash space to start searching uImage magic "OKLI". -+# $(5), size of search range starting at $(4). With 0 as the value, uImage -+# header is expected to be at precisely $(4) -+define Image/BuildLoaderAlone -+ -rm -rf $(KDIR)/lzma-loader -+ $(LOADER_MAKE) LOADER=loader-$(1).$(2) KERNEL_CMDLINE="$(3)" \ -+ LZMA_TEXT_START=0x80a00000 LOADADDR=0x80060000 \ -+ BOARD="$(1)" FLASH_OFFS=$(4) FLASH_MAX=$(5) \ -+ compile loader.$(2) -+endef -+ -+define Build/Clean -+ $(LOADER_MAKE) clean -+endef -+ -+alfa_ap120c_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,13312k(rootfs),1536k(kernel),1152k(unknown)ro,64k(art)ro;spi0.1:-(unknown) -+alfa_ap96_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,256k(u-boot-env)ro,13312k(rootfs),2048k(kernel),512k(caldata)ro,15360k@0x80000(firmware) -+alfa_mtdlayout_8M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6144k(rootfs),1600k(kernel),64k(nvram),64k(art)ro,7744k@0x50000(firmware) -+alfa_mtdlayout_16M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,15936k(firmware),64k(nvram),64k(art)ro -+all0258n_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env),6272k(firmware),1536k(failsafe),64k(art)ro -+all0315n_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,256k(u-boot-env),13568k(firmware),2048k(failsafe),256k(art)ro -+ap96_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(u-boot-env)ro,6144k(rootfs),1728k(kernel),64k(art)ro,7872k@0x40000(firmware) -+ap121_mtdlayout_8M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6144k(rootfs),1600k(kernel),64k(nvram),64k(art)ro,7744k@0x50000(firmware) -+ap121_mtdlayout_16M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,10944k(rootfs),4992k(kernel),64k(nvram),64k(art)ro,15936k@0x50000(firmware) -+ap132_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,1408k(kernel),6400k(rootfs),64k(art)ro,7808k@0x50000(firmware) -+ap135_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,14528k(rootfs),1472k(kernel),64k(art)ro,16000k@0x50000(firmware) -+ap136_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6336k(rootfs),1408k(kernel),64k(mib0),64k(art)ro,7744k@0x50000(firmware) -+ap143_mtdlayout_8M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6336k(rootfs),1472k(kernel),64k(art)ro,7744k@0x50000(firmware) -+ap143_mtdlayout_16M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,14528k(rootfs),1472k(kernel),64k(art)ro,16000k@0x50000(firmware) -+ap147_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,14528k(rootfs),1472k(kernel),64k(art)ro,16000k@0x50000(firmware) -+ap152_mtdlayout_16M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,14528k(rootfs),1472k(kernel),64k(art)ro,16000k@0x50000(firmware) -+bxu2000n2_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,1408k(kernel),8448k(rootfs),6016k(user),64k(cfg),64k(oem),64k(art)ro -+cameo_ap81_mtdlayout=mtdparts=spi0.0:128k(u-boot)ro,64k(config)ro,3840k(firmware),64k(art)ro -+cameo_ap91_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(nvram)ro,3712k(firmware),64k(mac)ro,64k(art)ro -+cameo_ap99_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(nvram)ro,3520k(firmware),64k(mac)ro,192k(lp)ro,64k(art)ro -+cameo_ap121_mtdlayout=mtdparts=spi0.0:64k(u-boot)ro,64k(art)ro,64k(mac)ro,64k(nvram)ro,192k(language)ro,3648k(firmware) -+cameo_ap121_mtdlayout_8M=mtdparts=spi0.0:64k(u-boot)ro,64k(art)ro,64k(mac)ro,64k(nvram)ro,256k(language)ro,7680k@0x80000(firmware) -+cameo_ap123_mtdlayout_4M=mtdparts=spi0.0:64k(u-boot)ro,64k(nvram)ro,3712k(firmware),192k(lang)ro,64k(art)ro -+cameo_db120_mtdlayout=mtdparts=spi0.0:64k(uboot)ro,64k(nvram)ro,15936k(firmware),192k(lang)ro,64k(mac)ro,64k(art)ro -+cameo_db120_mtdlayout_8M=mtdparts=spi0.0:64k(uboot)ro,64k(nvram)ro,7872k(firmware),128k(lang)ro,64k(art)ro -+cap4200ag_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env),320k(custom)ro,1536k(kernel),12096k(rootfs),2048k(failsafe),64k(art)ro,13632k@0xa0000(firmware) -+eap300v2_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env),320k(custom),13632k(firmware),2048k(failsafe),64k(art)ro -+db120_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6336k(rootfs),1408k(kernel),64k(nvram),64k(art)ro,7744k@0x50000(firmware) -+dgl_5500_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(nvram)ro,15296k(firmware),192k(lang)ro,512k(my-dlink)ro,64k(mac)ro,64k(art)ro -+dlan_hotspot_mtdlayout=mtdparts=spi0.0:128k(u-boot)ro,64k(Config1)ro,64k(Config2)ro,7872k@0x40000(firmware),64k(art)ro -+dlan_pro_500_wp_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,64k(Config1)ro,64k(Config2)ro,7680k@0x70000(firmware),64k(art)ro -+dlan_pro_1200_ac_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,64k(Config1)ro,64k(Config2)ro,15872k@0x70000(firmware),64k(art)ro -+cameo_ap94_mtdlayout=mtdparts=spi0.0:256k(uboot)ro,64k(config)ro,6208k(firmware),64k(caldata)ro,1600k(unknown)ro,64k@0x7f0000(caldata_copy) -+cameo_ap94_mtdlayout_fat=mtdparts=spi0.0:256k(uboot)ro,64k(config)ro,7808k(firmware),64k(caldata)ro,64k@0x660000(caldata_orig),6208k@0x50000(firmware_orig) -+esr900_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(u-boot-env)ro,1408k(kernel),13248k(rootfs),1024k(manufacture)ro,64k(backup)ro,320k(storage)ro,64k(caldata)ro,14656k@0x40000(firmware) -+esr1750_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(u-boot-env)ro,1408k(kernel),13248k(rootfs),1024k(manufacture)ro,64k(backup)ro,320k(storage)ro,64k(caldata)ro,14656k@0x40000(firmware) -+epg5000_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(u-boot-env)ro,1408k(kernel),13248k(rootfs),1024k(manufacture)ro,64k(backup)ro,320k(storage)ro,64k(caldata)ro,14656k@0x40000(firmware) -+f9k1115v2_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env),14464k(rootfs),1408k(kernel),64k(nvram)ro,64k(envram)ro,64k(art)ro,15872k@0x50000(firmware) -+dlrtdev_mtdlayout=mtdparts=spi0.0:256k(uboot)ro,64k(config)ro,6208k(firmware),64k(caldata)ro,640k(certs),960k(unknown)ro,64k@0x7f0000(caldata_copy) -+dlrtdev_mtdlayout_fat=mtdparts=spi0.0:256k(uboot)ro,64k(config)ro,7168k(firmware),640k(certs),64k(caldata)ro,64k@0x660000(caldata_orig),6208k@0x50000(firmware_orig) -+planex_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,7744k(firmware),128k(art)ro -+whrhpg300n_mtdlayout=mtdparts=spi0.0:248k(u-boot)ro,8k(u-boot-env)ro,3712k(firmware),64k(art)ro -+wndap360_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,7744k(firmware),64k(nvram)ro,64k(art)ro -+wnr2200_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,7808k(firmware),64k(art)ro -+wnr2000_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,3712k(firmware),64k(art)ro -+wnr2000v3_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,3712k(firmware),64k(art)ro -+wnr2000v4_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(u-boot-env)ro,3776k(firmware),64k(art)ro -+r6100_mtdlayout=mtdparts=ar934x-nfc:128k(u-boot)ro,256k(caldata)ro,256k(caldata-backup),512k(config),512k(pot),2048k(kernel),122240k(ubi),25600k@0x1a0000(firmware),2048k(language),3072k(traffic_meter) -+tew823dru_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(nvram)ro,15296k(firmware),192k(lang)ro,512k(my-dlink)ro,64k(mac)ro,64k(art)ro -+wndr4300_mtdlayout=mtdparts=ar934x-nfc:256k(u-boot)ro,256k(u-boot-env)ro,256k(caldata)ro,512k(pot),2048k(language),512k(config),3072k(traffic_meter),2048k(kernel),23552k(ubi),25600k@0x6c0000(firmware),256k(caldata_backup),-(reserved) -+zcn1523h_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6208k(rootfs),1472k(kernel),64k(configure)ro,64k(mfg)ro,64k(art)ro,7680k@0x50000(firmware) -+mynet_rext_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,7808k(firmware),64k(nvram)ro,64k(ART)ro -+zyx_nbg6716_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(env)ro,64k(RFdata)ro,-(nbu);ar934x-nfc:2048k@0x0(zyxel_rfsd),2048k@0x200000(romd),1024k@0x400000(header),2048k@0x500000(kernel),125952k@0x500000(firmware),-@0x700000(ubi) -+ -+define Image/BuildKernel -+ cp $(KDIR)/vmlinux.elf $(VMLINUX).elf -+ cp $(KDIR)/vmlinux $(VMLINUX).bin -+ dd if=$(KDIR)/vmlinux.bin.lzma of=$(VMLINUX).lzma bs=65536 conv=sync -+ $(call MkuImage,lzma,,$(KDIR)/vmlinux.bin.lzma,$(UIMAGE)-lzma.bin) -+ cp $(KDIR)/loader-generic.elf $(VMLINUX)-lzma.elf -+ -mkdir -p $(KDIR_TMP) -+endef -+ -+define Image/BuildKernel/Initramfs -+ cp $(KDIR)/vmlinux-initramfs.elf $(VMLINUX)-initramfs.elf -+ cp $(KDIR)/vmlinux-initramfs $(VMLINUX)-initramfs.bin -+ dd if=$(KDIR)/vmlinux-initramfs.bin.lzma of=$(VMLINUX)-initramfs.lzma bs=65536 conv=sync -+ $(call MkuImage,lzma,,$(KDIR)/vmlinux-initramfs.bin.lzma,$(UIMAGE)-initramfs-lzma.bin) -+ cp $(KDIR)/loader-generic-initramfs.elf $(VMLINUX)-initramfs-lzma.elf -+ $(call Image/Build/Initramfs) -+endef -+ -+Image/Build/WRT400N/buildkernel=$(call MkuImageLzma,$(2),$(3)) -+ -+define Image/Build/WRT400N -+ $(call Sysupgrade/KRuImage,$(1),$(2),1310720,6488064) -+ if [ -e "$(call sysupname,$(1),$(2))" ]; then \ -+ wrt400n $(KDIR_TMP)/vmlinux-$(2).uImage $(KDIR)/root.$(1) $(call factoryname,$(1),$(2)); \ -+ fi -+endef -+ -+ -+define Image/Build/CameoAP94/buildkernel -+ $(call MkuImageLzma,$(2),$(3) $(4)) -+ $(call MkuImageLzma,$(2)-fat,$(3) $(5)) -+endef -+ -+define Image/Build/CameoAP94 -+ $(eval fwsize=$(call mtdpartsize,firmware,$(4))) -+ $(eval fwsize_fat=$(call mtdpartsize,firmware,$(5))) -+ $(call Sysupgrade/KRuImage,$(1),$(2),0,$$(($(fwsize)-4*64*1024)),64) -+ if [ -e "$(call sysupname,$(1),$(2))" ]; then \ -+ ( \ -+ dd if=$(call sysupname,$(1),$(2)); \ -+ echo -n "$(6)"; \ -+ ) > $(call imgname,$(1),$(2))-backup-loader.bin; \ -+ if [ `stat -c%s $(call sysupname,$(1),$(2))` -gt 4194304 ]; then \ -+ echo "Warning: $(call sysupname,$(1),$(2)) is too big" >&2; \ -+ else \ -+ ( \ -+ dd if=$(call sysupname,$(1),$(2)) bs=4096k conv=sync; \ -+ echo -n "$(7)"; \ -+ ) > $(call factoryname,$(1),$(2)); \ -+ fi; \ -+ fi -+ $(call CatFiles,$(KDIR_TMP)/vmlinux-$(2)-fat.uImage,0,$(KDIR)/root.$(1),$$(($(fwsize_fat)-4*64*1024)),$(KDIR_TMP)/$(2)-fat.bin,64) -+ if [ -e "$(KDIR_TMP)/$(2)-fat.bin" ]; then \ -+ echo -n "" > $(KDIR_TMP)/$(2)-fat.dummy; \ -+ sh $(TOPDIR)/scripts/combined-image.sh \ -+ "$(KDIR_TMP)/$(2)-fat.bin" \ -+ "$(KDIR_TMP)/$(2)-fat.dummy" \ -+ $(call sysupname,$(1),$(2)-fat); \ -+ fi -+endef -+ -+define Image/Build/WZRHP -+ $(call Sysupgrade/KRuImage,$(1),$(2),0,$$(($(3)-4*$(4)*1024)),$(4)) -+ if [ -e "$(call sysupname,$(1),$(2))" ]; then \ -+ ( \ -+ echo -n -e "# Airstation Public Fmt1\x00\x00\x00\x00\x00\x00\x00\x00"; \ -+ dd if=$(call sysupname,$(1),$(2)); \ -+ ) > $(call imgname,$(1),$(2))-tftp.bin; \ -+ buffalo-enc -p $(5) -v 1.99 \ -+ -i $(call sysupname,$(1),$(2)) \ -+ -o $(KDIR_TMP)/$(2).enc; \ -+ buffalo-tag -b $(5) -p $(5) -a ath -v 1.99 -m 1.01 -l mlang8 \ -+ -w 3 -c 0x80041000 -d 0x801e8000 -f 1 -r M_ \ -+ -i $(KDIR_TMP)/$(2).enc \ -+ -o $(call factoryname,$(1),$(2)); \ -+ fi -+endef -+ -+Image/Build/WZRHP64K/buildkernel=$(call MkuImageLzma,$(2),$(3)) -+Image/Build/WZRHP64K/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) -+Image/Build/WZRHP64K=$(call Image/Build/WZRHP,$(1),$(2),33095680,64,$(4)) -+ -+Image/Build/WZRHP128K/buildkernel=$(call MkuImageLzma,$(2),$(3)) -+Image/Build/WZRHP128K/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) -+Image/Build/WZRHP128K=$(call Image/Build/WZRHP,$(1),$(2),33030144,128,$(4)) -+ -+ -+Image/Build/WHRHPG300N/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -+Image/Build/WHRHPG300N/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) -+ -+define Image/Build/WHRHPG300N -+ $(eval fwsize=$(call mtdpartsize,firmware,$(4))) -+ $(call Sysupgrade/KRuImage,$(1),$(2),0,$$(($(fwsize)-4*64*1024)),64) -+ if [ -e "$(call sysupname,$(1),$(2))" ]; then \ -+ ( \ -+ echo -n -e "# Airstation Public Fmt1\x00\x00\x00\x00\x00\x00\x00\x00"; \ -+ dd if=$(call sysupname,$(1),$(2)); \ -+ ) > $(call imgname,$(1),$(2))-tftp.bin; \ -+ buffalo-enc -p $(5) -v 1.99 \ -+ -i $(call sysupname,$(1),$(2)) \ -+ -o $(KDIR_TMP)/$(2).enc; \ -+ buffalo-tag -b $(5) -p $(5) -a ath -v 1.99 -m 1.01 -l mlang8 \ -+ -w 3 -c 0x80041000 -d 0x801e8000 -f 1 -r M_ \ -+ -i $(KDIR_TMP)/$(2).enc \ -+ -o $(call factoryname,$(1),$(2)); \ -+ fi -+endef -+ -+ -+define Image/Build/Cameo -+ $(eval fwsize=$(call mtdpartsize,firmware,$(4))) -+ $(call Sysupgrade/KRuImage,$(1),$(2),0,$$(($(fwsize)-4*64*1024)),64) -+ if [ -e "$(call sysupname,$(1),$(2))" ]; then \ -+ factory_size=$$(($(fwsize) - $(6))); \ -+ ( \ -+ dd if=$(call sysupname,$(1),$(2)) bs=$${factory_size} conv=sync; \ -+ echo -n $(5); \ -+ ) > $(call factoryname,$(1),$(2)); \ -+ fi -+endef -+ -+Image/Build/CameoAP81/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_ap81_mtdlayout)) -+Image/Build/CameoAP81=$(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo_ap81_mtdlayout),$(4),65536) -+Image/Build/CameoAP81/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_ap81_mtdlayout)) -+ -+Image/Build/CameoAP91/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_ap91_mtdlayout)) -+Image/Build/CameoAP91=$(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo_ap91_mtdlayout),$(4),65536) -+Image/Build/CameoAP91/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_ap91_mtdlayout)) -+ -+Image/Build/CameoAP99/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_ap99_mtdlayout)) -+Image/Build/CameoAP99=$(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo_ap99_mtdlayout),$(4),65536) -+Image/Build/CameoAP99/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_ap99_mtdlayout)) -+ -+Image/Build/CameoAP123_4M/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_ap123_mtdlayout_4M)) -+Image/Build/CameoAP123_4M=$(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo_ap123_mtdlayout_4M),$(4),26) -+Image/Build/CameoAP123_4M/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_ap123_mtdlayout_4M)) -+ -+Image/Build/CameoAP135/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -+Image/Build/CameoAP135=$(call Image/Build/Cameo,$(1),$(2),$(3),$(4),$(5),26) -+Image/Build/CameoAP135/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) -+ -+Image/Build/CameoDB120/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_db120_mtdlayout)) -+Image/Build/CameoDB120=$(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo_db120_mtdlayout),$(4),26) -+Image/Build/CameoDB120/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_db120_mtdlayout)) -+ -+Image/Build/CameoDB120_8M/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_db120_mtdlayout_8M)) -+Image/Build/CameoDB120_8M=$(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo_db120_mtdlayout_8M),$(4),26) -+Image/Build/CameoDB120_8M/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_db120_mtdlayout_8M)) -+ -+define Image/Build/CameoHornet -+ $(eval fwsize=$(call mtdpartsize,firmware,$(4))) -+ $(call Sysupgrade/KRuImage,$(1),$(2),0,$$(($(fwsize)-4*64*1024)),64) -+ if [ -e "$(call sysupname,$(1),$(2))" ]; then \ -+ for r in $(7); do \ -+ [ -n "$$r" ] && dashr="-$$r" || dashr=; \ -+ [ -z "$$r" ] && r="DEF"; \ -+ mkcameofw -M HORNET -R "$$r" -S $(5) -V $(6) -c \ -+ -K $(8) -I $(fwsize) \ -+ -k "$(call sysupname,$(1),$(2))" \ -+ -o $(call imgname,$(1),$(2))-factory$$dashr.bin; \ -+ true; \ -+ done; \ -+ fi -+endef -+ -+Image/Build/CameoAP121/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_ap121_mtdlayout)) -+Image/Build/CameoAP121=$(call Image/Build/CameoHornet,$(1),$(2),$(3),$(cameo_ap121_mtdlayout),$(4),$(5),$(6),0xe0000) -+Image/Build/CameoAP121/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_ap121_mtdlayout)) -+ -+Image/Build/CameoAP121_8M/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_ap121_mtdlayout_8M)) -+Image/Build/CameoAP121_8M=$(call Image/Build/CameoHornet,$(1),$(2),$(3),$(cameo_ap121_mtdlayout_8M),$(4),$(5),$(6),0x100000) -+Image/Build/CameoAP121_8M/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_ap121_mtdlayout_8M)) -+ -+define Image/Build/dLAN -+ $(eval fwsize=$(call mtdpartsize,firmware,$(4))) -+ $(eval rootsize=$(call mtdpartsize,rootfs,$(4))) -+ $(eval kernsize=$(call mtdpartsize,kernel,$(4))) -+ $(call Sysupgrade/$(5),$(1),$(2),$(if $(6),$(6),$(kernsize)),$(if $(rootsize),$(rootsize),$(fwsize))) -+endef -+ -+Image/Build/dLANLzma/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -+Image/Build/dLANLzma=$(call Image/Build/dLAN,$(1),$(2),$(3),$(4),$(5),$(6),$(7)) -+Image/Build/dLANLzma/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) -+ -+define Image/Build/Ath -+ $(eval fwsize=$(call mtdpartsize,firmware,$(4))) -+ $(eval rootsize=$(call mtdpartsize,rootfs,$(4))) -+ $(eval kernsize=$(call mtdpartsize,kernel,$(4))) -+ $(call Sysupgrade/$(5),$(1),$(2),$(if $(6),$(6),$(kernsize)),$(if $(rootsize),$(rootsize),$(fwsize))) -+endef -+ -+Image/Build/AthGzip/buildkernel=$(call MkuImageGzip,$(2),$(3) $(4)) -+Image/Build/AthGzip=$(call Image/Build/Ath,$(1),$(2),$(3),$(4),$(5),$(6),$(7)) -+Image/Build/AthGzip/initramfs=$(call MkuImageGzip/initramfs,$(2),$(3) $(4)) -+ -+Image/Build/AthLzma/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -+Image/Build/AthLzma=$(call Image/Build/Ath,$(1),$(2),$(3),$(4),$(5),$(6),$(7)) -+Image/Build/AthLzma/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) -+ -+ -+Image/Build/Belkin/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -+Image/Build/Belkin/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) -+ -+define Image/Build/Belkin -+ $(eval fwsize=$(call mtdpartsize,firmware,$(4))) -+ $(eval kernsize=$(call mtdpartsize,kernel,$(4))) -+ $(eval rootsize=$(call mtdpartsize,rootfs,$(4))) -+ $(call Sysupgrade/RKuImage,$(1),$(2),$(kernsize),$(rootsize)) -+ if [ -e "$(call sysupname,$(1),$(2))" ]; then \ -+ edimax_fw_header -m $(5) -v "$(shell echo -n $(VERSION_DIST)$(REVISION) | cut -c -13)" \ -+ -n "uImage" \ -+ -i $(KDIR_TMP)/vmlinux-$(2).uImage \ -+ -o $(KDIR_TMP)/$(2)-uImage; \ -+ edimax_fw_header -m $(5) -v "$(shell echo -n $(VERSION_DIST)$(REVISION) | cut -c -13)" \ -+ -n "rootfs" \ -+ -i $(KDIR)/root.$(1) \ -+ -o $(KDIR_TMP)/$(2)-rootfs; \ -+ ( \ -+ dd if=$(KDIR_TMP)/$(2)-rootfs; \ -+ dd if=$(KDIR_TMP)/$(2)-uImage; \ -+ ) > "$(call factoryname,$(1),$(2))"; \ -+ fi -+endef -+ -+define Image/Build/EnGenius -+ $(eval fwsize=$(call mtdpartsize,firmware,$(4))) -+ $(eval rootsize=$(call mtdpartsize,rootfs,$(4))) -+ $(eval kernsize=$(call mtdpartsize,kernel,$(4))) -+ $(call Sysupgrade/$(5),$(1),$(2),$(if $(6),$(6),$(kernsize)),$(if $(rootsize),$(rootsize),$(fwsize))) -+ if [ -e "$(call sysupname,$(1),$(2))" ]; then \ -+ mksenaofw -e $(call sysupname,$(1),$(2)) \ -+ -o $(call imgname,$(1),$(2))-factory.dlf \ -+ -r 0x101 -p $(7) -t 2; \ -+ fi -+endef -+ -+Image/Build/EnGenius/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -+Image/Build/EnGenius/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) -+ -+ -+Image/Build/PB4X/buildkernel=$(call PatchKernelLzma,$(2),$(3)) -+ -+define Image/Build/PB4X -+ dd if=$(KDIR_TMP)/vmlinux-$(2).bin.lzma \ -+ of=$(call imgname,kernel,$(2)).bin bs=64k conv=sync -+ dd if=$(KDIR)/root.$(1) \ -+ of=$(call imgname,$(1),$(2)-rootfs).bin bs=128k conv=sync -+ -sh $(TOPDIR)/scripts/combined-image.sh \ -+ "$(call imgname,kernel,$(2)).bin" \ -+ "$(call imgname,$(1),$(2)-rootfs).bin" \ -+ $(call sysupname,$(1),$(2)) -+endef -+ -+ -+Image/Build/MyLoader/buildkernel=$(call PatchKernelLzma,$(2),$(3)) -+Image/Build/MyLoader/initramfs=$(call PatchKernel/initramfs,$(2),$(3)) -+ -+define Image/Build/MyLoader -+ $(eval fwsize=$(shell echo $$(($(4)-0x30000-4*64*1024)))) -+ $(eval fwimage=$(KDIR_TMP)/$(2)-$(5)-firmware.bin) -+ $(call CatFiles,$(KDIR_TMP)/vmlinux-$(2).bin.lzma,65536,$(KDIR)/root.$(1),$(fwsize),$(fwimage)) -+ if [ -e "$(fwimage)" ]; then \ -+ $(STAGING_DIR_HOST)/bin/mkmylofw -B $(2) -s $(4) -v \ -+ -p0x00030000:0:al:0x80060000:firmware:$(fwimage) \ -+ $(call imgname,$(1),$(2))-$(5)-factory.img; \ -+ echo -n "" > $(KDIR_TMP)/empty.bin; \ -+ sh $(TOPDIR)/scripts/combined-image.sh \ -+ $(fwimage) $(KDIR_TMP)/empty.bin \ -+ $(call imgname,$(1),$(2))-$(5)-sysupgrade.bin; \ -+ fi -+endef -+ -+Image/Build/Planex/initramfs=$(call MkuImageGzip/initramfs,$(2),$(3) $(planex_mtdlayout)) -+Image/Build/Planex/loader=$(call Image/BuildLoaderAlone,$(1),gz,$(2) $(planex_mtdlayout),0x52000,0) -+ -+define Image/Build/Planex/buildkernel -+ [ -e "$(KDIR)/loader-$(2).gz" ] -+ $(call MkuImageOKLI,$(2)) -+ ( \ -+ dd if=$(KDIR)/loader-$(2).gz bs=8128 count=1 conv=sync; \ -+ dd if=$(KDIR_TMP)/vmlinux-$(2).okli; \ -+ ) > $(KDIR_TMP)/kernel-$(2).bin -+ $(call MkuImage,gzip,,$(KDIR_TMP)/kernel-$(2).bin,$(KDIR_TMP)/vmlinux-$(2).uImage) -+endef -+ -+define Image/Build/Planex -+ $(eval fwsize=$(call mtdpartsize,firmware,$(planex_mtdlayout))) -+ $(call Sysupgrade/KRuImage,$(1),$(2),0,$$(($(fwsize)-4*64*1024)),64) -+ if [ -e "$(call sysupname,$(1),$(2))" ]; then \ -+ $(STAGING_DIR_HOST)/bin/mkplanexfw \ -+ -B $(2) \ -+ -v 2.00.00 \ -+ -i $(call sysupname,$(1),$(2)) \ -+ -o $(call factoryname,$(1),$(2)); \ -+ fi -+endef -+ -+ -+Image/Build/ALFA/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -+Image/Build/ALFA/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) -+ -+define Image/Build/ALFA -+ $(call Sysupgrade/RKuImage,$(1),$(2),$(5),$(6)) -+ if [ -e "$(call sysupname,$(1),$(2))" ]; then \ -+ rm -rf $(KDIR)/$(1); \ -+ mkdir -p $(KDIR)/$(1); \ -+ cd $(KDIR)/$(1); \ -+ cp $(KDIR_TMP)/vmlinux-$(2).uImage $(KDIR)/$(1)/$(7); \ -+ cp $(KDIR)/root.$(1) $(KDIR)/$(1)/$(8); \ -+ $(TAR) c \ -+ $(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \ -+ -C $(KDIR)/$(1) $(7) $(8) \ -+ | gzip -9nc > $(call factoryname,$(1),$(2)); \ -+ ( \ -+ echo WRM7222C | dd bs=32 count=1 conv=sync; \ -+ echo -ne '\xfe'; \ -+ ) >> $(call factoryname,$(1),$(2)); \ -+ fi -+endef -+ -+ -+Image/Build/Senao/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -+Image/Build/Senao/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) -+ -+define Image/Build/Senao -+ mkdir -p $(KDIR_TMP)/$(2)/ -+ touch $(KDIR_TMP)/$(2)/FWINFO-OpenWrt-$(REVISION)-$(2) -+ -$(CP) ./$(2)/* $(KDIR_TMP)/$(2)/ -+ dd if=$(KDIR_TMP)/vmlinux-$(2).uImage \ -+ of=$(KDIR_TMP)/$(2)/openwrt-senao-$(2)-uImage-lzma.bin bs=64k conv=sync -+ dd if=$(KDIR)/root.$(1) \ -+ of=$(KDIR_TMP)/$(2)/openwrt-senao-$(2)-root.$(1) bs=64k conv=sync -+ ( \ -+ cd $(KDIR_TMP)/$(2)/; \ -+ $(TAR) -c \ -+ $(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \ -+ * | gzip -9nc > $(call factoryname,$(1),$(2)) \ -+ ) -+ -rm -rf $(KDIR_TMP)/$(2)/ -+ -sh $(TOPDIR)/scripts/combined-image.sh \ -+ $(KDIR_TMP)/vmlinux-$(2).uImage \ -+ $(KDIR)/root.$(1) \ -+ $(call sysupname,$(1),$(2)) -+endef -+ -+define Image/Build/CyberTAN -+ echo -n '' > $(KDIR_TMP)/empty.bin -+ -$(STAGING_DIR_HOST)/bin/trx -o $(KDIR)/image.tmp \ -+ -f $(KDIR_TMP)/vmlinux-$(2).uImage -F $(KDIR_TMP)/empty.bin \ -+ -x 32 -a 0x10000 -x -32 -f $(KDIR)/root.$(1) && \ -+ $(STAGING_DIR_HOST)/bin/addpattern -B $(2) -v v$(5) \ -+ -i $(KDIR)/image.tmp \ -+ -o $(call sysupname,$(1),$(2)) -+ -$(STAGING_DIR_HOST)/bin/trx -o $(KDIR)/image.tmp -f $(KDIR_TMP)/vmlinux-$(2).uImage \ -+ -x 32 -a 0x10000 -x -32 -f $(KDIR)/root.$(1) && \ -+ $(STAGING_DIR_HOST)/bin/addpattern -B $(2) -v v$(5) -g \ -+ -i $(KDIR)/image.tmp \ -+ -o $(call factoryname,$(1),$(2)) -+ -rm $(KDIR)/image.tmp -+endef -+ -+Image/Build/CyberTANGZIP/loader=$(call Image/BuildLoader,$(1),gz,$(2),0x80060000) -+Image/Build/CyberTANGZIP/buildkernel=$(call MkuImage,gzip,,$(KDIR)/loader-$(2).gz,$(KDIR_TMP)/vmlinux-$(2).uImage) -+Image/Build/CyberTANGZIP=$(call Image/Build/CyberTAN,$(1),$(2),$(3),$(4),$(5)) -+ -+Image/Build/CyberTANLZMA/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -+Image/Build/CyberTANLZMA=$(call Image/Build/CyberTAN,$(1),$(2),$(3),$(4),$(5)) -+ -+ -+Image/Build/Netgear/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4),,-M $(5)) -+ -+define Image/Build/Netgear/buildkernel -+ $(call MkuImageLzma,$(2),$(3) $(4),-d20,,-M $(5)) -+ -rm -rf $(KDIR_TMP)/$(2) -+ mkdir -p $(KDIR_TMP)/$(2)/image -+ cat $(KDIR_TMP)/vmlinux-$(2).uImage > $(KDIR_TMP)/$(2)/image/uImage -+ $(STAGING_DIR_HOST)/bin/mksquashfs-lzma \ -+ $(KDIR_TMP)/$(2) $(KDIR_TMP)/vmlinux-$(2).uImage.squashfs.tmp1 \ -+ -noappend -root-owned -be -b 65536 \ -+ $(if $(SOURCE_DATE_EPOCH),-fixed-time $(SOURCE_DATE_EPOCH)) -+ ( \ -+ cat $(KDIR_TMP)/vmlinux-$(2).uImage.squashfs.tmp1; \ -+ dd if=/dev/zero bs=1k count=1 \ -+ ) > $(KDIR_TMP)/vmlinux-$(2).uImage.squashfs.tmp2 -+ mkimage -A mips -O linux -T filesystem -C none -M $(5) \ -+ -a 0xbf070000 -e 0xbf070000 \ -+ -n 'MIPS $(VERSION_DIST) Linux-$(LINUX_VERSION)' \ -+ -d $(KDIR_TMP)/vmlinux-$(2).uImage.squashfs.tmp2 \ -+ $(KDIR_TMP)/vmlinux-$(2).uImage.squashfs -+endef -+ -+define Image/Build/Netgear -+ $(eval fwsize=$(call mtdpartsize,firmware,$(4))) -+ $(call CatFiles,$(KDIR_TMP)/vmlinux-$(2).uImage.squashfs,0,$(KDIR)/root.$(1),$(fwsize),$(call sysupname,$(1),$(2)),64) -+ if [ -e $(call sysupname,$(1),$(2)) ]; then \ -+ for r in $(7) ; do \ -+ [ -n "$$r" ] && dashr="-$$r" || dashr= ; \ -+ $(STAGING_DIR_HOST)/bin/mkdniimg \ -+ -B $(6) -v $(VERSION_DIST).$(REVISION) -r "$$r" $(8) \ -+ -i $(call sysupname,$(1),$(2)) \ -+ -o $(call imgname,$(1),$(2))-factory$$dashr.img; \ -+ done; \ -+ fi -+ if [ "$2" = "wnr2000" ]; then \ -+ dd if=$(KDIR)/root.$(1) \ -+ of=$(call imgname,$(1),$(2)-rootfs).bin bs=128k conv=sync; \ -+ fi -+endef -+ -+ -+Image/Build/NetgearLzma/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4),,-M $(5)) -+Image/Build/NetgearLzma/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4),-d20,,-M $(5)) -+ -+define Image/Build/NetgearLzma -+ $(eval fwsize=$(call mtdpartsize,firmware,$(4))) -+ $(call CatFiles,$(KDIR_TMP)/vmlinux-$(2).uImage,0,$(KDIR)/root.$(1),$(fwsize),$(call sysupname,$(1),$(2)),64) -+endef -+ -+ -+Image/Build/NetgearNAND/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4),,-M $(5)) -+ -+# $(1): (empty) -+# $(2): Board name (small caps) -+# $(3): Kernel board specific cmdline -+# $(4): Kernel mtdparts definition -+# $(5): U-Boot magic -+define Image/Build/NetgearNAND/buildkernel -+ $(eval kernelsize=$(call mtdpartsize,kernel,$(4))) -+ $(call PatchKernelLzma,$(2),$(3) $(4),-d20) -+ dd if=$(KDIR_TMP)/vmlinux-$(2).bin.lzma \ -+ of=$(KDIR_TMP)/vmlinux-$(2).bin.tmp \ -+ bs=$$(($(kernelsize)-131072-2*64-1)) \ -+ count=1 conv=sync -+ $(call MkuImage,lzma,-M $(5),$(KDIR_TMP)/vmlinux-$(2).bin.tmp,$(KDIR_TMP)/vmlinux-$(2).uImage) -+ echo -ne '\xff' >> $(KDIR_TMP)/vmlinux-$(2).uImage -+ # create a fake rootfs image -+ dd if=/dev/zero of=$(KDIR_TMP)/fakeroot-$(2) bs=131072 count=1 -+ mkimage -A mips -O linux -T filesystem -C none \ -+ -a 0xbf070000 -e 0xbf070000 \ -+ -n 'MIPS $(VERSION_DIST) fakeroot' \ -+ -d $(KDIR_TMP)/fakeroot-$(2) \ -+ -M $(5) \ -+ $(KDIR_TMP)/fakeroot-$(2).uImage -+ # append the fake rootfs image to the kernel, it will reside in the last -+ # erase block of the kernel partition -+ cat $(KDIR_TMP)/fakeroot-$(2).uImage >> $(KDIR_TMP)/vmlinux-$(2).uImage -+endef -+ -+ -+# $(1): rootfs image suffix -+# $(2): Board name (small caps) -+# $(3): Kernel board specific cmdline -+# $(4): Kernel mtdparts definition -+# $(5): U-Boot magic -+# $(6): Board name (upper caps) -+# $(7): firmware region code (not used yet) -+# $(8): DNI Hardware version -+# $(9): suffix of the configuration file for ubinize -+define Image/Build/NetgearNAND -+ $(eval firmwaresize=$(call mtdpartsize,firmware,$(4))) -+ $(eval kernelsize=$(call mtdpartsize,kernel,$(4))) -+ $(eval imageraw=$(KDIR_TMP)/$(2)-raw.img) -+ $(CP) $(KDIR)/root.squashfs-raw $(KDIR_TMP)/root.squashfs -+ echo -ne '\xde\xad\xc0\xde' > $(KDIR_TMP)/jffs2.eof -+ $(call ubinize,ubinize-$(9).ini,$(KDIR_TMP),$(KDIR_TMP)/$(2)-root.ubi,128KiB,2048,-E 5) -+ ( \ -+ dd if=$(KDIR_TMP)/vmlinux-$(2).uImage; \ -+ dd if=$(KDIR_TMP)/$(2)-root.ubi \ -+ ) > $(imageraw) -+ $(STAGING_DIR_HOST)/bin/mkdniimg \ -+ -B $(6) -v $(VERSION_DIST).$(REVISION) -r "$$r" $(8) \ -+ -i $(imageraw) \ -+ -o $(call imgname,ubi,$(2))-factory.img -+ -+ $(call Image/Build/SysupgradeNAND,$(2),squashfs,$(KDIR_TMP)/vmlinux-$(2).uImage) -+endef -+ -+ZYXEL_UBOOT = $(KDIR)/u-boot-nbg460n_550n_550nh.bin -+ZYXEL_UBOOT_BIN = $(wildcard $(BIN_DIR)/u-boot-nbg460n_550n_550nh/u-boot.bin) -+ -+Image/Build/ZyXEL/buildkernel=$(call MkuImageLzma,$(2),$(3)) -+ -+define Image/Build/ZyXEL -+ $(call Sysupgrade/KRuImage,$(1),$(2),917504,2752512) -+ if [ -e "$(call sysupname,$(1),$(2))" ]; then \ -+ if [ ! -f $(ZYXEL_UBOOT) ]; then \ -+ echo "Warning: $(ZYXEL_UBOOT) not found" >&2; \ -+ else \ -+ $(STAGING_DIR_HOST)/bin/mkzynfw \ -+ -B $(4) \ -+ -b $(ZYXEL_UBOOT) \ -+ -r $(call sysupname,$(1),$(2)):0x10000 \ -+ -o $(call factoryname,$(1),$(2)); \ -+ fi; fi -+endef -+ -+# attention: only zlib compression is allowed for the boot fs -+define Image/Build/ZyXELNAND/buildkernel -+ $(eval kernelsize=$(call mtdpartsize,kernel,$(5))) -+ $(call MkuImageLzma,$(2),$(3) $(5) $(6)) -+ mkdir -p $(KDIR_TMP)/$(2)/image/boot -+ cp $(KDIR_TMP)/vmlinux-$(2).uImage $(KDIR_TMP)/$(2)/image/boot/vmlinux.lzma.uImage -+ $(STAGING_DIR_HOST)/bin/mkfs.jffs2 \ -+ --pad=$(kernelsize) --big-endian --squash-uids -v -e 128KiB -q -f -n -x lzma -x rtime \ -+ -o $(KDIR_TMP)/$(2)-kernel.jffs2 \ -+ -d $(KDIR_TMP)/$(2)/image \ -+ 2>&1 1>/dev/null | awk '/^.+$$/' -+ -rm -rf $(KDIR_TMP)/$(2) -+endef -+ -+define Image/Build/ZyXELNAND -+ if [ "$(1)" != "squashfs" ]; then \ -+ echo Only squashfs is supported; \ -+ return 0; \ -+ fi -+ $(eval firmwaresize=$(call mtdpartsize,firmware,$(4))) -+ $(eval kernelsize=$(call mtdpartsize,kernel,$(4))) -+ $(eval imageraw=$(KDIR_TMP)/$(2)-raw.img) -+ $(CP) $(KDIR)/root.$(1) $(KDIR_TMP)/ubi_root.img -+ $(call ubinize,ubinize-$(2).ini,$(KDIR_TMP),$(KDIR_TMP)/$(2)-root.ubi,128KiB,2048,-E 5) -+ ( \ -+ dd if=$(KDIR_TMP)/$(2)-kernel.jffs2; \ -+ dd if=$(KDIR_TMP)/$(2)-root.ubi \ -+ ) > $(imageraw) -+ dd if=$(imageraw) of=$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory.bin \ -+ bs=128k conv=sync -+ $(call Image/Build/SysupgradeNAND,$(2),squashfs,$(KDIR_TMP)/$(2)-kernel.jffs2) -+endef -+ -+ -+Image/Build/OpenMesh/buildkernel=$(call MkuImageLzma,$(2)) -+Image/Build/OpenMesh/initramfs=$(call MkuImageLzma/initramfs,$(2),) -+ -+define Image/Build/OpenMesh -+ -sh $(TOPDIR)/scripts/om-fwupgradecfg-gen.sh \ -+ "$(4)" \ -+ "$(BUILD_DIR)/fwupgrade.cfg-$(4)" \ -+ "$(KDIR_TMP)/vmlinux-$(2).uImage" \ -+ "$(KDIR)/root.$(1)" -+ -sh $(TOPDIR)/scripts/combined-ext-image.sh \ -+ "$(4)" "$(call factoryname,$(1),$(2))" \ -+ "$(BUILD_DIR)/fwupgrade.cfg-$(4)" "fwupgrade.cfg" \ -+ "$(KDIR_TMP)/vmlinux-$(2).uImage" "kernel" \ -+ "$(KDIR)/root.$(1)" "rootfs" -+ if [ -e "$(call factoryname,$(1),$(2))" ]; then \ -+ cp "$(call factoryname,$(1),$(2))" "$(call sysupname,$(1),$(2))"; \ -+ fi -+endef -+ -+ -+Image/Build/Zcomax/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) -+Image/Build/Zcomax/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4)) -+ -+define Image/Build/Zcomax -+ $(call Sysupgrade/RKuImage,$(1),$(2),1507328,6356992) -+ if [ -e "$(call sysupname,$(1),$(2))" ]; then \ -+ $(STAGING_DIR_HOST)/bin/mkzcfw \ -+ -B $(2) \ -+ -k $(KDIR_TMP)/vmlinux-$(2).uImage \ -+ -r $(KDIR)/root.$(1) \ -+ -o $(call imgname,$(1),$(2))-factory.img; \ -+ fi -+endef -+ -+ -+# $(1): template name to be defined. -+# $(2): squashfs suffix to be used. -+define BuildTemplate -+ # $(1) : name of build method. -+ # $(2) : board name. -+ # $(3) : kernel command line. -+ # $(4)~$(8): extra arguments. -+ define Image/Build/Template/$(1)/initramfs -+ $$(call Image/Build/$$(1)/initramfs,initramfs,$$(2),$$(3),$$(4),$$(5),$$(6),$$(7),$$(8),$$(9),$$(10)) -+ endef -+ define Image/Build/Template/$(1)/loader -+ $$(call Image/Build/$$(1)/loader,$$(2),$$(3),$$(4),$$(5),$$(6),$$(7),$$(8),$$(9),$$(10)) -+ endef -+ define Image/Build/Template/$(1)/buildkernel -+ $$(call Image/Build/$$(1)/buildkernel,,$$(2),$$(3),$$(4),$$(5),$$(6),$$(7),$$(8),$$(9),$$(10)) -+ endef -+ define Image/Build/Template/$(1)/squashfs -+ $$(call Image/Build/$$(1),squashfs$(2),$$(2),$$(3),$$(4),$$(5),$$(6),$$(7),$$(8),$$(9),$$(10)) -+ endef -+endef -+ -+$(eval $(call BuildTemplate,squashfs-only)) -+$(eval $(call BuildTemplate,64k,-64k)) -+$(eval $(call BuildTemplate,64kraw,-raw)) -+$(eval $(call BuildTemplate,64kraw-nojffs,-raw)) -+$(eval $(call BuildTemplate,128k)) -+$(eval $(call BuildTemplate,128kraw,-raw)) -+$(eval $(call BuildTemplate,256k)) -+$(eval $(call BuildTemplate,all)) -+ -+ifeq ($(SUBTARGET),generic) -+$(eval $(call SingleProfile,ALFA,64k,ALFANX,alfa-nx,ALFA-NX,ttyS0,115200,$$(alfa_mtdlayout_8M),1638400,6291456,vmlinux.gz.uImage,pb9x-2.6.31-jffs2)) -+$(eval $(call SingleProfile,ALFA,64k,HORNETUB,hornet-ub,HORNET-UB,ttyATH0,115200,$$(alfa_mtdlayout_8M),1638400,6291456,kernel_image,rootfs_image)) -+$(eval $(call SingleProfile,ALFA,64k,TUBE2H8M,tube2h-8M,TUBE2H,ttyATH0,115200,$$(alfa_mtdlayout_8M),1638400,6291456,kernel.image,rootfs.image)) -+ -+$(eval $(call SingleProfile,AthGzip,64k,AP96,ap96,AP96,ttyS0,115200,$$(ap96_mtdlayout),RKuImage)) -+$(eval $(call SingleProfile,AthGzip,64k,WNDAP360,wndap360,WNDAP360,ttyS0,9600,$$(wndap360_mtdlayout),KRuImage,65536)) -+ -+$(eval $(call SingleProfile,AthLzma,64k,ALFAAP120C,alfa-ap120c,ALFA-AP120C,ttyS0,115200,$$(alfa_ap120c_mtdlayout),RKuImage)) -+$(eval $(call SingleProfile,AthLzma,64k,ALFAAP96,alfa-ap96,ALFA-AP96,ttyS0,115200,$$(alfa_ap96_mtdlayout),RKuImage)) -+$(eval $(call SingleProfile,AthLzma,64k,ALL0258N,all0258n,ALL0258N,ttyS0,115200,$$(all0258n_mtdlayout),KRuImage,65536)) -+$(eval $(call SingleProfile,AthLzma,256k,ALL0315N,all0315n,ALL0315N,ttyS0,115200,$$(all0315n_mtdlayout),KRuImage,262144)) -+$(eval $(call SingleProfile,AthLzma,64k,AP121_8M,ap121-8M,AP121,ttyATH0,115200,$$(ap121_mtdlayout_8M),RKuImage)) -+$(eval $(call SingleProfile,AthLzma,64k,AP121_16M,ap121-16M,AP121,ttyATH0,115200,$$(ap121_mtdlayout_16M),RKuImage)) -+$(eval $(call SingleProfile,AthLzma,64k,AP132,ap132,AP132,ttyS0,115200,$$(ap132_mtdlayout),KRuImage)) -+$(eval $(call SingleProfile,AthLzma,64k,AP135,ap135-020,AP135-020,ttyS0,115200,$$(ap135_mtdlayout),RKuImage)) -+$(eval $(call SingleProfile,AthLzma,64k,AP136_010,ap136-010,AP136-010,ttyS0,115200,$$(ap136_mtdlayout),RKuImage)) -+$(eval $(call SingleProfile,AthLzma,64k,AP136_020,ap136-020,AP136-020,ttyS0,115200,$$(ap136_mtdlayout),RKuImage)) -+$(eval $(call SingleProfile,AthLzma,64k,AP143_8M,ap143-8M,AP143,ttyS0,115200,$$(ap143_mtdlayout_8M),RKuImage)) -+$(eval $(call SingleProfile,AthLzma,64k,AP143_16M,ap143-16M,AP143,ttyS0,115200,$$(ap143_mtdlayout_16M),RKuImage)) -+$(eval $(call SingleProfile,AthLzma,64k,AP147_010,ap147-010,AP147-010,ttyS0,115200,$$(ap147_mtdlayout),RKuImage)) -+$(eval $(call SingleProfile,AthLzma,64k,AP152_16M,ap152-16M,AP152,ttyS0,115200,$$(ap152_mtdlayout_16M),RKuImage)) -+$(eval $(call SingleProfile,AthLzma,64k,BXU2000N2,bxu2000n-2-a1,BXU2000n-2-A1,ttyS0,115200,$$(bxu2000n2_mtdlayout),RKuImage)) -+$(eval $(call SingleProfile,AthLzma,64k,CAP4200AG,cap4200ag,CAP4200AG,ttyS0,115200,$$(cap4200ag_mtdlayout),KRuImage)) -+$(eval $(call SingleProfile,AthLzma,64k,DB120,db120,DB120,ttyS0,115200,$$(db120_mtdlayout),RKuImage)) -+$(eval $(call SingleProfile,AthLzma,64k,HORNETUBx2,hornet-ub-x2,HORNET-UB,ttyATH0,115200,$$(alfa_mtdlayout_16M),KRuImage,65536)) -+$(eval $(call SingleProfile,AthLzma,64k,TUBE2H16M,tube2h-16M,TUBE2H,ttyATH0,115200,$$(alfa_mtdlayout_16M),KRuImage,65536)) -+ -+$(eval $(call SingleProfile,CameoAP121_8M,64kraw-nojffs,DIR505A1,dir-505-a1,DIR-505-A1,ttyATH0,115200,"HORNET-PACKET-DIR505A1-3",1.99.99,"")) -+ -+$(eval $(call SingleProfile,CameoAP135,64kraw,DGL5500A1,dgl-5500-a1,DGL-5500-A1,ttyS0,115200,$$(dgl_5500_mtdlayout),"00AP135AR9558-RT-130508-00")) -+$(eval $(call SingleProfile,CameoAP135,64kraw,TEW823DRU,tew-823dru,TEW-823DRU,ttyS0,115200,$$(tew823dru_mtdlayout) mem=256M,"00AP135AR9558-RT-131129-00")) -+ -+$(eval $(call SingleProfile,CameoDB120,64kraw,DHP1565A1,dhp-1565-a1,DHP-1565-A1,ttyS0,115200,"00DB120AR9344-RT-101214-00")) -+$(eval $(call SingleProfile,CameoDB120,64kraw,DIR825C1,dir-825-c1,DIR-825-C1,ttyS0,115200,"00DB120AR9344-RT-101214-00")) -+$(eval $(call SingleProfile,CameoDB120,64kraw,DIR835A1,dir-835-a1,DIR-835-A1,ttyS0,115200,"00DB120AR9344-RT-101214-00")) -+ -+$(eval $(call SingleProfile,CameoDB120_8M,64kraw,TEW732BR,tew-732br,TEW-732BR,ttyS0,115200,"00DB120AR9341-RT-120906-NA")) -+ -+$(eval $(call SingleProfile,CyberTANGZIP,64k,E2100L,e2100l,E2100L,ttyS0,115200,,1.00.01)) -+$(eval $(call SingleProfile,CyberTANGZIP,64k,WRT160NL,wrt160nl,WRT160NL,ttyS0,115200,,1.00.01)) -+ -+$(eval $(call SingleProfile,CyberTANLZMA,64k,MYNETREXT,mynet-rext,MYNET-REXT,ttyS0,115200,$$(mynet_rext_mtdlayout) root=31:2,1.00.01)) -+ -+$(eval $(call SingleProfile,CameoAP94,64kraw,DIR825B1,dir-825-b1,DIR-825-B1,ttyS0,115200,$$(cameo_ap94_mtdlayout),$$(cameo_ap94_mtdlayout_fat),01AP94-AR7161-RT-080619-00,00AP94-AR7161-RT-080619-00)) -+$(eval $(call SingleProfile,CameoAP94,64kraw,TEW673GRU,tew-673gru,TEW-673GRU,ttyS0,115200,$$(cameo_ap94_mtdlayout),$$(cameo_ap94_mtdlayout_fat),01AP94-AR7161-RT-080619-01,00AP94-AR7161-RT-080619-01)) -+$(eval $(call SingleProfile,CameoAP94,64kraw,DLRTDEV01,dlrtdev01,DIR-825-B1,ttyS0,115200,$$(dlrtdev_mtdlayout),$$(dlrtdev_mtdlayout_fat),01AP94-AR7161-RT-080619-00,00AP94-AR7161-RT-080619-00)) -+ -+$(eval $(call SingleProfile,dLANLzma,64k,dLAN_Hotspot,dlan-hotspot,dLAN-Hotspot,ttyATH0,115200,$$(dlan_hotspot_mtdlayout) mem=64M,KRuImage,65536)) -+$(eval $(call SingleProfile,dLANLzma,64k,dLAN_pro_500_wp,dlan-pro-500-wp,dLAN-pro-500-wp,ttyS0,115200,$$(dlan_pro_500_wp_mtdlayout) mem=128M,KRuImage,65536)) -+$(eval $(call SingleProfile,dLANLzma,64k,dLAN_pro_1200_ac,dlan-pro-1200-ac,dLAN-pro-1200-ac,ttyS0,115200,$$(dlan_pro_1200_ac_mtdlayout) mem=128M,KRuImage,65536)) -+ -+$(eval $(call SingleProfile,EnGenius,64k,ESR900,esr900,ESR900,ttyS0,115200,$$(esr900_mtdlayout),KRuImage,,0x4e)) -+$(eval $(call SingleProfile,EnGenius,64k,ESR1750,esr1750,ESR1750,ttyS0,115200,$$(esr1750_mtdlayout),KRuImage,,0x61)) -+$(eval $(call SingleProfile,EnGenius,64k,EPG5000,epg5000,EPG5000,ttyS0,115200,$$(epg5000_mtdlayout),KRuImage,,0x71)) -+ -+$(eval $(call SingleProfile,MyLoader,64k,WP543_8M,wp543,,ttyS0,115200,0x800000,8M)) -+$(eval $(call SingleProfile,MyLoader,64k,WP543_16M,wp543,,ttyS0,115200,0x1000000,16M)) -+$(eval $(call SingleProfile,MyLoader,64k,WPE72_8M,wpe72,,ttyS0,115200,0x800000,8M)) -+$(eval $(call SingleProfile,MyLoader,64k,WPE72_16M,wpe72,,ttyS0,115200,0x1000000,16M)) -+ -+$(eval $(call SingleProfile,Netgear,64kraw,WNR2200,wnr2200,WNR2200,ttyS0,115200,$$(wnr2200_mtdlayout),0x32323030,wnr2200,"" NA,)) -+ -+$(eval $(call SingleProfile,OpenMesh,squashfs-only,A60,a60,,,,A60)) -+$(eval $(call SingleProfile,OpenMesh,squashfs-only,OM2P,om2p,,,,OM2P)) -+$(eval $(call SingleProfile,OpenMesh,squashfs-only,OM5P,om5p,,,,OM5P)) -+$(eval $(call SingleProfile,OpenMesh,squashfs-only,OM5PAC,om5pac,,,,OM5PAC)) -+$(eval $(call SingleProfile,OpenMesh,squashfs-only,MR600,mr600,,,,MR600)) -+$(eval $(call SingleProfile,OpenMesh,squashfs-only,MR900,mr900,,,,MR900)) -+$(eval $(call SingleProfile,OpenMesh,squashfs-only,MR1750,mr1750,,,,MR1750)) -+ -+$(eval $(call SingleProfile,PB4X,128k,ALL0305,all0305,ALL0305,ttyS0,115200)) -+$(eval $(call SingleProfile,PB4X,128k,EAP7660D,eap7660d,EAP7660D,ttyS0,115200)) -+$(eval $(call SingleProfile,PB4X,64k,JA76PF,ja76pf,JA76PF,ttyS0,115200)) -+$(eval $(call SingleProfile,PB4X,64k,JA76PF2,ja76pf2,JA76PF2,ttyS0,115200)) -+$(eval $(call SingleProfile,PB4X,64k,JWAP003,jwap003,JWAP003,ttyS0,115200)) -+$(eval $(call SingleProfile,PB4X,64k,PB42,pb42,PB42,ttyS0,115200)) -+$(eval $(call SingleProfile,PB4X,64k,PB44,pb44,PB44,ttyS0,115200)) -+ -+$(eval $(call SingleProfile,Planex,64kraw,MZKW04NU,mzk-w04nu,MZK-W04NU,ttyS0,115200)) -+$(eval $(call SingleProfile,Planex,64kraw,MZKW300NH,mzk-w300nh,MZK-W300NH,ttyS0,115200)) -+ -+$(eval $(call SingleProfile,Senao,squashfs-only,EAP300V2,eap300v2,EAP300V2,ttyS0,115200,$$(eap300v2_mtdlayout))) -+ -+$(eval $(call SingleProfile,WRT400N,64k,WRT400N,wrt400n,WRT400N,ttyS0,115200)) -+ -+$(eval $(call SingleProfile,WZRHP128K,128kraw,WZRHPG300NH,wzr-hp-g300nh,WZR-HP-G300NH,ttyS0,115200,WZR-HP-G300NH)) -+$(eval $(call SingleProfile,WZRHP64K,64kraw,WZRHPG300NH2,wzr-hp-g300nh2,WZR-HP-G300NH2,ttyS0,115200,WZR-HP-G300NH2)) -+$(eval $(call SingleProfile,WZRHP64K,64kraw,WZRHPAG300H,wzr-hp-ag300h,WZR-HP-AG300H,ttyS0,115200,WZR-HP-AG300H)) -+$(eval $(call SingleProfile,WZRHP64K,64kraw,WZRHPG450H,wzr-hp-g450h,WZR-HP-G450H,ttyS0,115200,WZR-HP-AG450H)) -+$(eval $(call SingleProfile,WZRHP64K,64kraw,WZR600DHP,wzr-600dhp,WZR-HP-AG300H,ttyS0,115200,WZR-600DHP)) -+$(eval $(call SingleProfile,WZRHP64K,64kraw,WZR450HP2,wzr-450hp2,WZR-450HP2,ttyS0,115200,WZR-450HP2)) -+ -+$(eval $(call SingleProfile,Zcomax,64k,ZCN1523H28,zcn-1523h-2-8,ZCN-1523H-2,ttyS0,115200,$$(zcn1523h_mtdlayout))) -+$(eval $(call SingleProfile,Zcomax,64k,ZCN1523H516,zcn-1523h-5-16,ZCN-1523H-5,ttyS0,115200,$$(zcn1523h_mtdlayout))) -+ -+endif # ifeq ($(SUBTARGET),generic) -+ -+ -+ifeq ($(SUBTARGET),tiny) -+ -+$(eval $(call SingleProfile,Belkin,64k,F9K1115V2,f9k1115v2,F9K1115V2,ttyS0,115200,$$(f9k1115v2_mtdlayout),BR-6679BAC)) -+ -+$(eval $(call SingleProfile,CameoAP91,64kraw,DIR600A1,dir-600-a1,DIR-600-A1,ttyS0,115200,"AP91-AR7240-RT-090223-00")) -+$(eval $(call SingleProfile,CameoAP91,64kraw,DIR601A1,dir-601-a1,DIR-600-A1,ttyS0,115200,"AP91-AR7240-RT-090223-02")) -+$(eval $(call SingleProfile,CameoAP91,64kraw,FR54RTR,fr-54rtr,DIR-600-A1,ttyS0,115200,"AP91-AR7240-RT-090223-01")) -+ -+$(eval $(call SingleProfile,CameoAP99,64kraw,EBR2310C1,ebr-2310-c1,EBR-2310-C1,ttyS0,115200,"AP91-AR7240-RT-090223-03")) -+$(eval $(call SingleProfile,CameoAP99,64kraw,DIR615E1,dir-615-e1,DIR-615-E1,ttyS0,115200,"AP93-AR7240-RT-081028-00")) -+$(eval $(call SingleProfile,CameoAP99,64kraw,DIR615E4,dir-615-e4,DIR-615-E4,ttyS0,115200,"AP99-AR7240-RT-091105-05")) -+ -+$(eval $(call SingleProfile,CameoAP123_4M,64kraw,DIR615I1,dir-615-i1,DIR-615-I1,ttyS0,115200,"00DB120AR9341-RT-1012I1-00")) -+$(eval $(call SingleProfile,CameoAP123_4M,64kraw,DIR615I3,dir-615-i3,DIR-615-I1,ttyS0,115200,"00DB120AR9341-RT-101214-00")) -+ -+$(eval $(call SingleProfile,CameoAP81,64kraw-nojffs,A02RBW300N,a02-rb-w300n,TEW-632BRP,ttyS0,115200,"AP81-AR9130-RT-070614-03")) -+$(eval $(call SingleProfile,CameoAP81,64kraw-nojffs,DIR615C1,dir-615-c1,DIR-615-C1,ttyS0,115200,"AP81-AR9130-RT-070614-02")) -+$(eval $(call SingleProfile,CameoAP81,64kraw-nojffs,TEW632BRP,tew-632brp,TEW-632BRP,ttyS0,115200,"AP81-AR9130-RT-070614-00")) -+$(eval $(call SingleProfile,CameoAP81,64kraw-nojffs,TEW652BRP_FW,tew-652brp,TEW-632BRP,ttyS0,115200,"AP81-AR9130-RT-080609-05")) -+$(eval $(call SingleProfile,CameoAP81,64kraw-nojffs,TEW652BRP_RECOVERY,tew-652brp-recovery,TEW-632BRP,ttyS0,115200,"AP81-AR9130-RT-070614-02")) -+ -+$(eval $(call SingleProfile,CameoAP121,64kraw-nojffs,TEW712BR,tew-712br,TEW-712BR,ttyATH0,115200,"HORNET-RT-TEW712BR-3",1.99,"")) -+$(eval $(call SingleProfile,CameoAP121,64kraw-nojffs,DIR601B1,dir-601-b1,TEW-712BR,ttyATH0,115200,"HORNET-RT-DIR601B1-3",2.99.99,"" "NA")) -+ -+$(eval $(call SingleProfile,MyLoader,64k,WP543_4M,wp543,,ttyS0,115200,0x400000,4M)) -+$(eval $(call SingleProfile,MyLoader,64k,WPE72_4M,wpe72,,ttyS0,115200,0x400000,4M)) -+ -+$(eval $(call SingleProfile,Netgear,64kraw,WNR2000V3,wnr2000v3,WNR2000V3,ttyS0,115200,$$(wnr2000v3_mtdlayout),0x32303033,WNR2000V3,"" NA,-H 29763551+04+32)) -+$(eval $(call SingleProfile,NetgearLzma,64kraw,WNR2000V4,wnr2000v4,WNR2000V4,ttyS0,115200,$$(wnr2000v4_mtdlayout),0x32303034,WNR2000V4,"" NA,)) -+$(eval $(call SingleProfile,Netgear,64kraw,WNR2000,wnr2000,WNR2000,ttyS0,115200,$$(wnr2000_mtdlayout),0x32303031,WNR2000,"" NA,)) -+$(eval $(call SingleProfile,Netgear,64kraw,REALWNR612V2,wnr612v2,WNR612V2,ttyS0,115200,$$(wnr2000v3_mtdlayout),0x32303631,WNR612V2,"",)) -+$(eval $(call SingleProfile,Netgear,64kraw,N150R,n150r,WNR612V2,ttyS0,115200,$$(wnr2000v3_mtdlayout),0x32303631,N150R,"",)) -+$(eval $(call SingleProfile,Netgear,64kraw,REALWNR1000V2,wnr1000v2,WNR1000V2,ttyS0,115200,$$(wnr2000v3_mtdlayout),0x31303031,WNR1000V2,"",)) -+$(eval $(call SingleProfile,Netgear,64kraw,WNR1000V2_VC,wnr1000v2-vc,WNR1000V2,ttyS0,115200,$$(wnr2000v3_mtdlayout),0x31303030,WNR1000V2-VC,"",)) -+$(eval $(call SingleProfile,Netgear,64kraw,WPN824N,wpn824n,WPN824N,ttyS0,115200,$$(wnr2000v3_mtdlayout),0x31313030,WPN824N,"" NA,)) -+ -+$(eval $(call SingleProfile,WHRHPG300N,64kraw,WHRG301N,whr-g301n,WHR-G301N,ttyS0,115200,$$(whrhpg300n_mtdlayout),WHR-G301N)) -+$(eval $(call SingleProfile,WHRHPG300N,64kraw,WHRHPG300N,whr-hp-g300n,WHR-HP-G300N,ttyS0,115200,$$(whrhpg300n_mtdlayout),WHR-HP-G300N)) -+$(eval $(call SingleProfile,WHRHPG300N,64kraw,WHRHPGN,whr-hp-gn,WHR-HP-GN,ttyS0,115200,$$(whrhpg300n_mtdlayout),WHR-HP-GN)) -+$(eval $(call SingleProfile,WHRHPG300N,64kraw,WLAEAG300N,wlae-ag300n,WLAE-AG300N,ttyS0,115200,$$(whrhpg300n_mtdlayout),WLAE-AG300N)) -+ -+$(eval $(call SingleProfile,ZyXEL,64k,NBG_460N_550N_550NH,nbg460n_550n_550nh,NBG460N,ttyS0,115200,NBG-460N)) -+ -+endif # ifeq ($(SUBTARGET),tiny) -+ -+ -+ifeq ($(SUBTARGET),nand) -+ -+$(eval $(call SingleProfile,NetgearNAND,64k,WNDR3700V4,wndr3700v4,WNDR3700_V4,ttyS0,115200,$$(wndr4300_mtdlayout),0x33373033,WNDR3700v4,"",-H 29763948+128+128,wndr4300)) -+$(eval $(call SingleProfile,NetgearNAND,64k,WNDR4300V1,wndr4300,WNDR4300,ttyS0,115200,$$(wndr4300_mtdlayout),0x33373033,WNDR4300,"",-H 29763948+0+128+128+2x2+3x3,wndr4300)) -+$(eval $(call SingleProfile,NetgearNAND,64k,R6100,r6100,R6100,ttyS0,115200,$$(r6100_mtdlayout),0x36303030,R6100,"",-H 29764434+0+128+128+2x2+2x2,wndr4300)) -+ -+$(eval $(call SingleProfile,ZyXELNAND,128k,NBG6716,nbg6716,NBG6716,ttyS0,115200,NBG6716,$$(zyx_nbg6716_mtdlayout),mem=256M)) -+ -+endif # ifeq ($(SUBTARGET),nand) -+ -+define Image/Build/squashfs -+ cp $(KDIR)/root.squashfs $(KDIR)/root.squashfs-raw -+ cp $(KDIR)/root.squashfs $(KDIR)/root.squashfs-64k -+ $(STAGING_DIR_HOST)/bin/padjffs2 $(KDIR)/root.squashfs-64k 64 -+ $(call prepare_generic_squashfs,$(KDIR)/root.squashfs) -+ dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-root.$(1) bs=128k conv=sync -+endef -+ -+define Image/Prepare -+ $(if $(wildcard $(ZYXEL_UBOOT_BIN)),cp $(ZYXEL_UBOOT_BIN) $(ZYXEL_UBOOT)) -+ $(call CompressLzma,$(KDIR)/vmlinux,$(KDIR)/vmlinux.bin.lzma) -+ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),) -+ $(call CompressLzma,$(KDIR)/vmlinux-initramfs,$(KDIR)/vmlinux-initramfs.bin.lzma) -+ $(call Image/BuildLoader,generic,elf,,,-initramfs) -+endif -+ $(call Image/BuildLoader,generic,elf) -+endef -+ -+define Image/Prepare/Profile -+ $(call Image/Build/Profile/$(1),loader) -+endef -+ -+define Image/Build/Profile -+ $(call Image/Build/Profile/$(1),buildkernel) -+ $(if $(CONFIG_TARGET_ROOTFS_INITRAMFS),$(call Image/Build/Profile/$(1),initramfs)) -+ $(call Image/Build/Profile/$(1),$(2)) -+endef -+ -+# $(1): filesystem type. -+define Image/Build -+ $(call Image/Build/$(call rootfs_type,$(1)),$(1)) -+endef -diff --git a/target/linux/ar71xx/image/lzma-loader/Makefile b/target/linux/ar71xx/image/lzma-loader/Makefile -new file mode 100644 -index 0000000000..738093a958 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/Makefile -@@ -0,0 +1,70 @@ -+# -+# Copyright (C) 2011 OpenWrt.org -+# Copyright (C) 2011 Gabor Juhos -+# -+# This is free software, licensed under the GNU General Public License v2. -+# See /LICENSE for more information. -+# -+ -+include $(TOPDIR)/rules.mk -+ -+LZMA_TEXT_START := 0x80a00000 -+LOADADDR := 0x80060000 -+LOADER := loader.bin -+LOADER_NAME := $(basename $(notdir $(LOADER))) -+LOADER_DATA := -+TARGET_DIR := -+FLASH_OFFS := -+FLASH_MAX := -+BOARD := -+ -+ifeq ($(TARGET_DIR),) -+TARGET_DIR := $(KDIR) -+endif -+ -+LOADER_BIN := $(TARGET_DIR)/$(LOADER_NAME).bin -+LOADER_GZ := $(TARGET_DIR)/$(LOADER_NAME).gz -+LOADER_ELF := $(TARGET_DIR)/$(LOADER_NAME).elf -+ -+PKG_NAME := lzma-loader -+PKG_BUILD_DIR := $(KDIR)/$(PKG_NAME) -+ -+.PHONY : loader-compile loader.bin loader.elf loader.gz -+ -+$(PKG_BUILD_DIR)/.prepared: -+ mkdir $(PKG_BUILD_DIR) -+ $(CP) ./src/* $(PKG_BUILD_DIR)/ -+ touch $@ -+ -+loader-compile: $(PKG_BUILD_DIR)/.prepared -+ $(MAKE) -C $(PKG_BUILD_DIR) CROSS_COMPILE="$(TARGET_CROSS)" \ -+ LZMA_TEXT_START=$(LZMA_TEXT_START) \ -+ LOADADDR=$(LOADADDR) \ -+ LOADER_DATA=$(LOADER_DATA) \ -+ FLASH_OFFS=$(FLASH_OFFS) \ -+ FLASH_MAX=$(FLASH_MAX) \ -+ BOARD="$(BOARD)" \ -+ clean all -+ -+loader.gz: $(PKG_BUILD_DIR)/loader.bin -+ # Workaround for buggy bootloaders: Some devices -+ # (TP-Link TL-WR1043ND v1) don't work correctly when -+ # the uncompressed loader is too small (probably a cache -+ # invalidation issue) -+ dd if=$< bs=512K conv=sync | gzip -nc9 > $(LOADER_GZ) -+ -+loader.elf: $(PKG_BUILD_DIR)/loader.elf -+ $(CP) $< $(LOADER_ELF) -+ -+loader.bin: $(PKG_BUILD_DIR)/loader.bin -+ $(CP) $< $(LOADER_BIN) -+ -+download: -+prepare: $(PKG_BUILD_DIR)/.prepared -+compile: loader-compile -+ -+install: -+ -+clean: -+ rm -rf $(PKG_BUILD_DIR) -+ -diff --git a/target/linux/ar71xx/image/lzma-loader/src/LzmaDecode.c b/target/linux/ar71xx/image/lzma-loader/src/LzmaDecode.c -new file mode 100644 -index 0000000000..cb8345377e ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/LzmaDecode.c -@@ -0,0 +1,584 @@ -+/* -+ LzmaDecode.c -+ LZMA Decoder (optimized for Speed version) -+ -+ LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) -+ http://www.7-zip.org/ -+ -+ LZMA SDK is licensed under two licenses: -+ 1) GNU Lesser General Public License (GNU LGPL) -+ 2) Common Public License (CPL) -+ It means that you can select one of these two licenses and -+ follow rules of that license. -+ -+ SPECIAL EXCEPTION: -+ Igor Pavlov, as the author of this Code, expressly permits you to -+ statically or dynamically link your Code (or bind by name) to the -+ interfaces of this file without subjecting your linked Code to the -+ terms of the CPL or GNU LGPL. Any modifications or additions -+ to this file, however, are subject to the LGPL or CPL terms. -+*/ -+ -+#include "LzmaDecode.h" -+ -+#define kNumTopBits 24 -+#define kTopValue ((UInt32)1 << kNumTopBits) -+ -+#define kNumBitModelTotalBits 11 -+#define kBitModelTotal (1 << kNumBitModelTotalBits) -+#define kNumMoveBits 5 -+ -+#define RC_READ_BYTE (*Buffer++) -+ -+#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ -+ { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} -+ -+#ifdef _LZMA_IN_CB -+ -+#define RC_TEST { if (Buffer == BufferLim) \ -+ { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \ -+ BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }} -+ -+#define RC_INIT Buffer = BufferLim = 0; RC_INIT2 -+ -+#else -+ -+#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; } -+ -+#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 -+ -+#endif -+ -+#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } -+ -+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) -+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; -+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; -+ -+#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ -+ { UpdateBit0(p); mi <<= 1; A0; } else \ -+ { UpdateBit1(p); mi = (mi + mi) + 1; A1; } -+ -+#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;) -+ -+#define RangeDecoderBitTreeDecode(probs, numLevels, res) \ -+ { int i = numLevels; res = 1; \ -+ do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \ -+ res -= (1 << numLevels); } -+ -+ -+#define kNumPosBitsMax 4 -+#define kNumPosStatesMax (1 << kNumPosBitsMax) -+ -+#define kLenNumLowBits 3 -+#define kLenNumLowSymbols (1 << kLenNumLowBits) -+#define kLenNumMidBits 3 -+#define kLenNumMidSymbols (1 << kLenNumMidBits) -+#define kLenNumHighBits 8 -+#define kLenNumHighSymbols (1 << kLenNumHighBits) -+ -+#define LenChoice 0 -+#define LenChoice2 (LenChoice + 1) -+#define LenLow (LenChoice2 + 1) -+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) -+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) -+ -+ -+#define kNumStates 12 -+#define kNumLitStates 7 -+ -+#define kStartPosModelIndex 4 -+#define kEndPosModelIndex 14 -+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) -+ -+#define kNumPosSlotBits 6 -+#define kNumLenToPosStates 4 -+ -+#define kNumAlignBits 4 -+#define kAlignTableSize (1 << kNumAlignBits) -+ -+#define kMatchMinLen 2 -+ -+#define IsMatch 0 -+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) -+#define IsRepG0 (IsRep + kNumStates) -+#define IsRepG1 (IsRepG0 + kNumStates) -+#define IsRepG2 (IsRepG1 + kNumStates) -+#define IsRep0Long (IsRepG2 + kNumStates) -+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -+#define LenCoder (Align + kAlignTableSize) -+#define RepLenCoder (LenCoder + kNumLenProbs) -+#define Literal (RepLenCoder + kNumLenProbs) -+ -+#if Literal != LZMA_BASE_SIZE -+StopCompilingDueBUG -+#endif -+ -+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) -+{ -+ unsigned char prop0; -+ if (size < LZMA_PROPERTIES_SIZE) -+ return LZMA_RESULT_DATA_ERROR; -+ prop0 = propsData[0]; -+ if (prop0 >= (9 * 5 * 5)) -+ return LZMA_RESULT_DATA_ERROR; -+ { -+ for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); -+ for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); -+ propsRes->lc = prop0; -+ /* -+ unsigned char remainder = (unsigned char)(prop0 / 9); -+ propsRes->lc = prop0 % 9; -+ propsRes->pb = remainder / 5; -+ propsRes->lp = remainder % 5; -+ */ -+ } -+ -+ #ifdef _LZMA_OUT_READ -+ { -+ int i; -+ propsRes->DictionarySize = 0; -+ for (i = 0; i < 4; i++) -+ propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); -+ if (propsRes->DictionarySize == 0) -+ propsRes->DictionarySize = 1; -+ } -+ #endif -+ return LZMA_RESULT_OK; -+} -+ -+#define kLzmaStreamWasFinishedId (-1) -+ -+int LzmaDecode(CLzmaDecoderState *vs, -+ #ifdef _LZMA_IN_CB -+ ILzmaInCallback *InCallback, -+ #else -+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, -+ #endif -+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) -+{ -+ CProb *p = vs->Probs; -+ SizeT nowPos = 0; -+ Byte previousByte = 0; -+ UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; -+ UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; -+ int lc = vs->Properties.lc; -+ -+ #ifdef _LZMA_OUT_READ -+ -+ UInt32 Range = vs->Range; -+ UInt32 Code = vs->Code; -+ #ifdef _LZMA_IN_CB -+ const Byte *Buffer = vs->Buffer; -+ const Byte *BufferLim = vs->BufferLim; -+ #else -+ const Byte *Buffer = inStream; -+ const Byte *BufferLim = inStream + inSize; -+ #endif -+ int state = vs->State; -+ UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; -+ int len = vs->RemainLen; -+ UInt32 globalPos = vs->GlobalPos; -+ UInt32 distanceLimit = vs->DistanceLimit; -+ -+ Byte *dictionary = vs->Dictionary; -+ UInt32 dictionarySize = vs->Properties.DictionarySize; -+ UInt32 dictionaryPos = vs->DictionaryPos; -+ -+ Byte tempDictionary[4]; -+ -+ #ifndef _LZMA_IN_CB -+ *inSizeProcessed = 0; -+ #endif -+ *outSizeProcessed = 0; -+ if (len == kLzmaStreamWasFinishedId) -+ return LZMA_RESULT_OK; -+ -+ if (dictionarySize == 0) -+ { -+ dictionary = tempDictionary; -+ dictionarySize = 1; -+ tempDictionary[0] = vs->TempDictionary[0]; -+ } -+ -+ if (len == kLzmaNeedInitId) -+ { -+ { -+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); -+ UInt32 i; -+ for (i = 0; i < numProbs; i++) -+ p[i] = kBitModelTotal >> 1; -+ rep0 = rep1 = rep2 = rep3 = 1; -+ state = 0; -+ globalPos = 0; -+ distanceLimit = 0; -+ dictionaryPos = 0; -+ dictionary[dictionarySize - 1] = 0; -+ #ifdef _LZMA_IN_CB -+ RC_INIT; -+ #else -+ RC_INIT(inStream, inSize); -+ #endif -+ } -+ len = 0; -+ } -+ while(len != 0 && nowPos < outSize) -+ { -+ UInt32 pos = dictionaryPos - rep0; -+ if (pos >= dictionarySize) -+ pos += dictionarySize; -+ outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; -+ if (++dictionaryPos == dictionarySize) -+ dictionaryPos = 0; -+ len--; -+ } -+ if (dictionaryPos == 0) -+ previousByte = dictionary[dictionarySize - 1]; -+ else -+ previousByte = dictionary[dictionaryPos - 1]; -+ -+ #else /* if !_LZMA_OUT_READ */ -+ -+ int state = 0; -+ UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; -+ int len = 0; -+ const Byte *Buffer; -+ const Byte *BufferLim; -+ UInt32 Range; -+ UInt32 Code; -+ -+ #ifndef _LZMA_IN_CB -+ *inSizeProcessed = 0; -+ #endif -+ *outSizeProcessed = 0; -+ -+ { -+ UInt32 i; -+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); -+ for (i = 0; i < numProbs; i++) -+ p[i] = kBitModelTotal >> 1; -+ } -+ -+ #ifdef _LZMA_IN_CB -+ RC_INIT; -+ #else -+ RC_INIT(inStream, inSize); -+ #endif -+ -+ #endif /* _LZMA_OUT_READ */ -+ -+ while(nowPos < outSize) -+ { -+ CProb *prob; -+ UInt32 bound; -+ int posState = (int)( -+ (nowPos -+ #ifdef _LZMA_OUT_READ -+ + globalPos -+ #endif -+ ) -+ & posStateMask); -+ -+ prob = p + IsMatch + (state << kNumPosBitsMax) + posState; -+ IfBit0(prob) -+ { -+ int symbol = 1; -+ UpdateBit0(prob) -+ prob = p + Literal + (LZMA_LIT_SIZE * -+ ((( -+ (nowPos -+ #ifdef _LZMA_OUT_READ -+ + globalPos -+ #endif -+ ) -+ & literalPosMask) << lc) + (previousByte >> (8 - lc)))); -+ -+ if (state >= kNumLitStates) -+ { -+ int matchByte; -+ #ifdef _LZMA_OUT_READ -+ UInt32 pos = dictionaryPos - rep0; -+ if (pos >= dictionarySize) -+ pos += dictionarySize; -+ matchByte = dictionary[pos]; -+ #else -+ matchByte = outStream[nowPos - rep0]; -+ #endif -+ do -+ { -+ int bit; -+ CProb *probLit; -+ matchByte <<= 1; -+ bit = (matchByte & 0x100); -+ probLit = prob + 0x100 + bit + symbol; -+ RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) -+ } -+ while (symbol < 0x100); -+ } -+ while (symbol < 0x100) -+ { -+ CProb *probLit = prob + symbol; -+ RC_GET_BIT(probLit, symbol) -+ } -+ previousByte = (Byte)symbol; -+ -+ outStream[nowPos++] = previousByte; -+ #ifdef _LZMA_OUT_READ -+ if (distanceLimit < dictionarySize) -+ distanceLimit++; -+ -+ dictionary[dictionaryPos] = previousByte; -+ if (++dictionaryPos == dictionarySize) -+ dictionaryPos = 0; -+ #endif -+ if (state < 4) state = 0; -+ else if (state < 10) state -= 3; -+ else state -= 6; -+ } -+ else -+ { -+ UpdateBit1(prob); -+ prob = p + IsRep + state; -+ IfBit0(prob) -+ { -+ UpdateBit0(prob); -+ rep3 = rep2; -+ rep2 = rep1; -+ rep1 = rep0; -+ state = state < kNumLitStates ? 0 : 3; -+ prob = p + LenCoder; -+ } -+ else -+ { -+ UpdateBit1(prob); -+ prob = p + IsRepG0 + state; -+ IfBit0(prob) -+ { -+ UpdateBit0(prob); -+ prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; -+ IfBit0(prob) -+ { -+ #ifdef _LZMA_OUT_READ -+ UInt32 pos; -+ #endif -+ UpdateBit0(prob); -+ -+ #ifdef _LZMA_OUT_READ -+ if (distanceLimit == 0) -+ #else -+ if (nowPos == 0) -+ #endif -+ return LZMA_RESULT_DATA_ERROR; -+ -+ state = state < kNumLitStates ? 9 : 11; -+ #ifdef _LZMA_OUT_READ -+ pos = dictionaryPos - rep0; -+ if (pos >= dictionarySize) -+ pos += dictionarySize; -+ previousByte = dictionary[pos]; -+ dictionary[dictionaryPos] = previousByte; -+ if (++dictionaryPos == dictionarySize) -+ dictionaryPos = 0; -+ #else -+ previousByte = outStream[nowPos - rep0]; -+ #endif -+ outStream[nowPos++] = previousByte; -+ #ifdef _LZMA_OUT_READ -+ if (distanceLimit < dictionarySize) -+ distanceLimit++; -+ #endif -+ -+ continue; -+ } -+ else -+ { -+ UpdateBit1(prob); -+ } -+ } -+ else -+ { -+ UInt32 distance; -+ UpdateBit1(prob); -+ prob = p + IsRepG1 + state; -+ IfBit0(prob) -+ { -+ UpdateBit0(prob); -+ distance = rep1; -+ } -+ else -+ { -+ UpdateBit1(prob); -+ prob = p + IsRepG2 + state; -+ IfBit0(prob) -+ { -+ UpdateBit0(prob); -+ distance = rep2; -+ } -+ else -+ { -+ UpdateBit1(prob); -+ distance = rep3; -+ rep3 = rep2; -+ } -+ rep2 = rep1; -+ } -+ rep1 = rep0; -+ rep0 = distance; -+ } -+ state = state < kNumLitStates ? 8 : 11; -+ prob = p + RepLenCoder; -+ } -+ { -+ int numBits, offset; -+ CProb *probLen = prob + LenChoice; -+ IfBit0(probLen) -+ { -+ UpdateBit0(probLen); -+ probLen = prob + LenLow + (posState << kLenNumLowBits); -+ offset = 0; -+ numBits = kLenNumLowBits; -+ } -+ else -+ { -+ UpdateBit1(probLen); -+ probLen = prob + LenChoice2; -+ IfBit0(probLen) -+ { -+ UpdateBit0(probLen); -+ probLen = prob + LenMid + (posState << kLenNumMidBits); -+ offset = kLenNumLowSymbols; -+ numBits = kLenNumMidBits; -+ } -+ else -+ { -+ UpdateBit1(probLen); -+ probLen = prob + LenHigh; -+ offset = kLenNumLowSymbols + kLenNumMidSymbols; -+ numBits = kLenNumHighBits; -+ } -+ } -+ RangeDecoderBitTreeDecode(probLen, numBits, len); -+ len += offset; -+ } -+ -+ if (state < 4) -+ { -+ int posSlot; -+ state += kNumLitStates; -+ prob = p + PosSlot + -+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << -+ kNumPosSlotBits); -+ RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); -+ if (posSlot >= kStartPosModelIndex) -+ { -+ int numDirectBits = ((posSlot >> 1) - 1); -+ rep0 = (2 | ((UInt32)posSlot & 1)); -+ if (posSlot < kEndPosModelIndex) -+ { -+ rep0 <<= numDirectBits; -+ prob = p + SpecPos + rep0 - posSlot - 1; -+ } -+ else -+ { -+ numDirectBits -= kNumAlignBits; -+ do -+ { -+ RC_NORMALIZE -+ Range >>= 1; -+ rep0 <<= 1; -+ if (Code >= Range) -+ { -+ Code -= Range; -+ rep0 |= 1; -+ } -+ } -+ while (--numDirectBits != 0); -+ prob = p + Align; -+ rep0 <<= kNumAlignBits; -+ numDirectBits = kNumAlignBits; -+ } -+ { -+ int i = 1; -+ int mi = 1; -+ do -+ { -+ CProb *prob3 = prob + mi; -+ RC_GET_BIT2(prob3, mi, ; , rep0 |= i); -+ i <<= 1; -+ } -+ while(--numDirectBits != 0); -+ } -+ } -+ else -+ rep0 = posSlot; -+ if (++rep0 == (UInt32)(0)) -+ { -+ /* it's for stream version */ -+ len = kLzmaStreamWasFinishedId; -+ break; -+ } -+ } -+ -+ len += kMatchMinLen; -+ #ifdef _LZMA_OUT_READ -+ if (rep0 > distanceLimit) -+ #else -+ if (rep0 > nowPos) -+ #endif -+ return LZMA_RESULT_DATA_ERROR; -+ -+ #ifdef _LZMA_OUT_READ -+ if (dictionarySize - distanceLimit > (UInt32)len) -+ distanceLimit += len; -+ else -+ distanceLimit = dictionarySize; -+ #endif -+ -+ do -+ { -+ #ifdef _LZMA_OUT_READ -+ UInt32 pos = dictionaryPos - rep0; -+ if (pos >= dictionarySize) -+ pos += dictionarySize; -+ previousByte = dictionary[pos]; -+ dictionary[dictionaryPos] = previousByte; -+ if (++dictionaryPos == dictionarySize) -+ dictionaryPos = 0; -+ #else -+ previousByte = outStream[nowPos - rep0]; -+ #endif -+ len--; -+ outStream[nowPos++] = previousByte; -+ } -+ while(len != 0 && nowPos < outSize); -+ } -+ } -+ RC_NORMALIZE; -+ -+ #ifdef _LZMA_OUT_READ -+ vs->Range = Range; -+ vs->Code = Code; -+ vs->DictionaryPos = dictionaryPos; -+ vs->GlobalPos = globalPos + (UInt32)nowPos; -+ vs->DistanceLimit = distanceLimit; -+ vs->Reps[0] = rep0; -+ vs->Reps[1] = rep1; -+ vs->Reps[2] = rep2; -+ vs->Reps[3] = rep3; -+ vs->State = state; -+ vs->RemainLen = len; -+ vs->TempDictionary[0] = tempDictionary[0]; -+ #endif -+ -+ #ifdef _LZMA_IN_CB -+ vs->Buffer = Buffer; -+ vs->BufferLim = BufferLim; -+ #else -+ *inSizeProcessed = (SizeT)(Buffer - inStream); -+ #endif -+ *outSizeProcessed = nowPos; -+ return LZMA_RESULT_OK; -+} -diff --git a/target/linux/ar71xx/image/lzma-loader/src/LzmaDecode.h b/target/linux/ar71xx/image/lzma-loader/src/LzmaDecode.h -new file mode 100644 -index 0000000000..2870eeb9c9 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/LzmaDecode.h -@@ -0,0 +1,113 @@ -+/* -+ LzmaDecode.h -+ LZMA Decoder interface -+ -+ LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) -+ http://www.7-zip.org/ -+ -+ LZMA SDK is licensed under two licenses: -+ 1) GNU Lesser General Public License (GNU LGPL) -+ 2) Common Public License (CPL) -+ It means that you can select one of these two licenses and -+ follow rules of that license. -+ -+ SPECIAL EXCEPTION: -+ Igor Pavlov, as the author of this code, expressly permits you to -+ statically or dynamically link your code (or bind by name) to the -+ interfaces of this file without subjecting your linked code to the -+ terms of the CPL or GNU LGPL. Any modifications or additions -+ to this file, however, are subject to the LGPL or CPL terms. -+*/ -+ -+#ifndef __LZMADECODE_H -+#define __LZMADECODE_H -+ -+#include "LzmaTypes.h" -+ -+/* #define _LZMA_IN_CB */ -+/* Use callback for input data */ -+ -+/* #define _LZMA_OUT_READ */ -+/* Use read function for output data */ -+ -+/* #define _LZMA_PROB32 */ -+/* It can increase speed on some 32-bit CPUs, -+ but memory usage will be doubled in that case */ -+ -+/* #define _LZMA_LOC_OPT */ -+/* Enable local speed optimizations inside code */ -+ -+#ifdef _LZMA_PROB32 -+#define CProb UInt32 -+#else -+#define CProb UInt16 -+#endif -+ -+#define LZMA_RESULT_OK 0 -+#define LZMA_RESULT_DATA_ERROR 1 -+ -+#ifdef _LZMA_IN_CB -+typedef struct _ILzmaInCallback -+{ -+ int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize); -+} ILzmaInCallback; -+#endif -+ -+#define LZMA_BASE_SIZE 1846 -+#define LZMA_LIT_SIZE 768 -+ -+#define LZMA_PROPERTIES_SIZE 5 -+ -+typedef struct _CLzmaProperties -+{ -+ int lc; -+ int lp; -+ int pb; -+ #ifdef _LZMA_OUT_READ -+ UInt32 DictionarySize; -+ #endif -+}CLzmaProperties; -+ -+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size); -+ -+#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp))) -+ -+#define kLzmaNeedInitId (-2) -+ -+typedef struct _CLzmaDecoderState -+{ -+ CLzmaProperties Properties; -+ CProb *Probs; -+ -+ #ifdef _LZMA_IN_CB -+ const unsigned char *Buffer; -+ const unsigned char *BufferLim; -+ #endif -+ -+ #ifdef _LZMA_OUT_READ -+ unsigned char *Dictionary; -+ UInt32 Range; -+ UInt32 Code; -+ UInt32 DictionaryPos; -+ UInt32 GlobalPos; -+ UInt32 DistanceLimit; -+ UInt32 Reps[4]; -+ int State; -+ int RemainLen; -+ unsigned char TempDictionary[4]; -+ #endif -+} CLzmaDecoderState; -+ -+#ifdef _LZMA_OUT_READ -+#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; } -+#endif -+ -+int LzmaDecode(CLzmaDecoderState *vs, -+ #ifdef _LZMA_IN_CB -+ ILzmaInCallback *inCallback, -+ #else -+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, -+ #endif -+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed); -+ -+#endif -diff --git a/target/linux/ar71xx/image/lzma-loader/src/LzmaTypes.h b/target/linux/ar71xx/image/lzma-loader/src/LzmaTypes.h -new file mode 100644 -index 0000000000..9c27290757 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/LzmaTypes.h -@@ -0,0 +1,45 @@ -+/* -+LzmaTypes.h -+ -+Types for LZMA Decoder -+ -+This file written and distributed to public domain by Igor Pavlov. -+This file is part of LZMA SDK 4.40 (2006-05-01) -+*/ -+ -+#ifndef __LZMATYPES_H -+#define __LZMATYPES_H -+ -+#ifndef _7ZIP_BYTE_DEFINED -+#define _7ZIP_BYTE_DEFINED -+typedef unsigned char Byte; -+#endif -+ -+#ifndef _7ZIP_UINT16_DEFINED -+#define _7ZIP_UINT16_DEFINED -+typedef unsigned short UInt16; -+#endif -+ -+#ifndef _7ZIP_UINT32_DEFINED -+#define _7ZIP_UINT32_DEFINED -+#ifdef _LZMA_UINT32_IS_ULONG -+typedef unsigned long UInt32; -+#else -+typedef unsigned int UInt32; -+#endif -+#endif -+ -+/* #define _LZMA_NO_SYSTEM_SIZE_T */ -+/* You can use it, if you don't want */ -+ -+#ifndef _7ZIP_SIZET_DEFINED -+#define _7ZIP_SIZET_DEFINED -+#ifdef _LZMA_NO_SYSTEM_SIZE_T -+typedef UInt32 SizeT; -+#else -+#include -+typedef size_t SizeT; -+#endif -+#endif -+ -+#endif -diff --git a/target/linux/ar71xx/image/lzma-loader/src/Makefile b/target/linux/ar71xx/image/lzma-loader/src/Makefile -new file mode 100644 -index 0000000000..7773f027a2 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/Makefile -@@ -0,0 +1,108 @@ -+# -+# Makefile for the LZMA compressed kernel loader for -+# Atheros AR7XXX/AR9XXX based boards -+# -+# Copyright (C) 2011 Gabor Juhos -+# -+# Some parts of this file was based on the OpenWrt specific lzma-loader -+# for the BCM47xx and ADM5120 based boards: -+# Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) -+# Copyright (C) 2005 Mineharu Takahara -+# Copyright (C) 2005 by Oleg I. Vdovikin -+# -+# This program is free software; you can redistribute it and/or modify it -+# under the terms of the GNU General Public License version 2 as published -+# by the Free Software Foundation. -+# -+ -+LOADADDR := -+LZMA_TEXT_START := 0x80a00000 -+LOADER_DATA := -+BOARD := -+FLASH_OFFS := -+FLASH_MAX := -+ -+CC := $(CROSS_COMPILE)gcc -+LD := $(CROSS_COMPILE)ld -+OBJCOPY := $(CROSS_COMPILE)objcopy -+OBJDUMP := $(CROSS_COMPILE)objdump -+ -+BIN_FLAGS := -O binary -R .reginfo -R .note -R .comment -R .mdebug \ -+ -R .MIPS.abiflags -S -+ -+CFLAGS = -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -Os \ -+ -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 \ -+ -mno-abicalls -fno-pic -ffunction-sections -pipe -mlong-calls \ -+ -fno-common -ffreestanding -fhonour-copts -nostartfiles \ -+ -mabi=32 -march=mips32r2 \ -+ -Wa,-32 -Wa,-march=mips32r2 -Wa,-mips32r2 -Wa,--trap -+CFLAGS += -D_LZMA_PROB32 -+CFLAGS += -flto -+ -+ASFLAGS = $(CFLAGS) -D__ASSEMBLY__ -+ -+LDFLAGS = -static -Wl,--gc-sections -Wl,-no-warn-mismatch -+LDFLAGS += -Wl,-e,startup -T loader.lds -Wl,-Ttext,$(LZMA_TEXT_START) -+LDFLAGS += -flto -fwhole-program -+ -+O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32) -+ -+OBJECTS := head.o loader.o cache.o board.o printf.o LzmaDecode.o -+ -+ifneq ($(strip $(LOADER_DATA)),) -+OBJECTS += data.o -+CFLAGS += -DLZMA_WRAPPER=1 -DLOADADDR=$(LOADADDR) -+endif -+ -+ifneq ($(strip $(KERNEL_CMDLINE)),) -+CFLAGS += -DCONFIG_KERNEL_CMDLINE='"$(KERNEL_CMDLINE)"' -+endif -+ -+ifneq ($(strip $(FLASH_OFFS)),) -+CFLAGS += -DCONFIG_FLASH_OFFS=$(FLASH_OFFS) -+endif -+ -+ifneq ($(strip $(FLASH_MAX)),) -+CFLAGS += -DCONFIG_FLASH_MAX=$(FLASH_MAX) -+endif -+ -+BOARD_DEF := $(shell echo $(strip $(BOARD)) | tr a-z A-Z | tr - _) -+ifneq ($(BOARD_DEF),) -+CFLAGS += -DCONFIG_BOARD_$(BOARD_DEF) -+endif -+ -+all: loader.elf -+ -+# Don't build dependencies, this may die if $(CC) isn't gcc -+dep: -+ -+install: -+ -+%.o : %.c -+ $(CC) $(CFLAGS) -c -o $@ $< -+ -+%.o : %.S -+ $(CC) $(ASFLAGS) -c -o $@ $< -+ -+data.o: $(LOADER_DATA) -+ $(LD) -r -b binary --oformat $(O_FORMAT) -T lzma-data.lds -o $@ $< -+ -+loader: $(OBJECTS) -+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) -+ -+loader.bin: loader -+ $(OBJCOPY) $(BIN_FLAGS) $< $@ -+ -+loader2.o: loader.bin -+ $(LD) -r -b binary --oformat $(O_FORMAT) -o $@ $< -+ -+loader.elf: loader2.o -+ $(LD) -z max-page-size=0x1000 -e startup -T loader2.lds -Ttext $(LOADADDR) -o $@ $< -+ -+mrproper: clean -+ -+clean: -+ rm -f loader *.elf *.bin *.o -+ -+ -+ -diff --git a/target/linux/ar71xx/image/lzma-loader/src/ar71xx_regs.h b/target/linux/ar71xx/image/lzma-loader/src/ar71xx_regs.h -new file mode 100644 -index 0000000000..19a4785bb4 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/ar71xx_regs.h -@@ -0,0 +1,725 @@ -+/* -+ * Atheros AR71XX/AR724X/AR913X SoC register definitions -+ * -+ * Copyright (C) 2010-2011 Jaiganesh Narayanan -+ * Copyright (C) 2008-2010 Gabor Juhos -+ * Copyright (C) 2008 Imre Kaloz -+ * -+ * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#ifndef __ASM_MACH_AR71XX_REGS_H -+#define __ASM_MACH_AR71XX_REGS_H -+ -+#define BIT(_x) (1UL << (_x)) -+ -+#define AR71XX_APB_BASE 0x18000000 -+#define AR71XX_GE0_BASE 0x19000000 -+#define AR71XX_GE0_SIZE 0x10000 -+#define AR71XX_GE1_BASE 0x1a000000 -+#define AR71XX_GE1_SIZE 0x10000 -+#define AR71XX_EHCI_BASE 0x1b000000 -+#define AR71XX_EHCI_SIZE 0x1000 -+#define AR71XX_OHCI_BASE 0x1c000000 -+#define AR71XX_OHCI_SIZE 0x1000 -+#define AR71XX_SPI_BASE 0x1f000000 -+#define AR71XX_SPI_SIZE 0x01000000 -+ -+#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000) -+#define AR71XX_DDR_CTRL_SIZE 0x100 -+#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000) -+#define AR71XX_UART_SIZE 0x100 -+#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000) -+#define AR71XX_USB_CTRL_SIZE 0x100 -+#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000) -+#define AR71XX_GPIO_SIZE 0x100 -+#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000) -+#define AR71XX_PLL_SIZE 0x100 -+#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) -+#define AR71XX_RESET_SIZE 0x100 -+#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000) -+#define AR71XX_MII_SIZE 0x100 -+ -+#define AR71XX_PCI_MEM_BASE 0x10000000 -+#define AR71XX_PCI_MEM_SIZE 0x07000000 -+ -+#define AR71XX_PCI_WIN0_OFFS 0x10000000 -+#define AR71XX_PCI_WIN1_OFFS 0x11000000 -+#define AR71XX_PCI_WIN2_OFFS 0x12000000 -+#define AR71XX_PCI_WIN3_OFFS 0x13000000 -+#define AR71XX_PCI_WIN4_OFFS 0x14000000 -+#define AR71XX_PCI_WIN5_OFFS 0x15000000 -+#define AR71XX_PCI_WIN6_OFFS 0x16000000 -+#define AR71XX_PCI_WIN7_OFFS 0x07000000 -+ -+#define AR71XX_PCI_CFG_BASE \ -+ (AR71XX_PCI_MEM_BASE + AR71XX_PCI_WIN7_OFFS + 0x10000) -+#define AR71XX_PCI_CFG_SIZE 0x100 -+ -+#define AR7240_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000) -+#define AR7240_USB_CTRL_SIZE 0x100 -+#define AR7240_OHCI_BASE 0x1b000000 -+#define AR7240_OHCI_SIZE 0x1000 -+ -+#define AR724X_PCI_MEM_BASE 0x10000000 -+#define AR724X_PCI_MEM_SIZE 0x04000000 -+ -+#define AR724X_PCI_CFG_BASE 0x14000000 -+#define AR724X_PCI_CFG_SIZE 0x1000 -+#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000c0000) -+#define AR724X_PCI_CRP_SIZE 0x1000 -+#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000f0000) -+#define AR724X_PCI_CTRL_SIZE 0x100 -+ -+#define AR724X_EHCI_BASE 0x1b000000 -+#define AR724X_EHCI_SIZE 0x1000 -+ -+#define AR913X_EHCI_BASE 0x1b000000 -+#define AR913X_EHCI_SIZE 0x1000 -+#define AR913X_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000) -+#define AR913X_WMAC_SIZE 0x30000 -+ -+#define AR933X_UART_BASE (AR71XX_APB_BASE + 0x00020000) -+#define AR933X_UART_SIZE 0x14 -+#define AR933X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) -+#define AR933X_GMAC_SIZE 0x04 -+#define AR933X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) -+#define AR933X_WMAC_SIZE 0x20000 -+#define AR933X_EHCI_BASE 0x1b000000 -+#define AR933X_EHCI_SIZE 0x1000 -+ -+#define AR934X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) -+#define AR934X_GMAC_SIZE 0x14 -+#define AR934X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) -+#define AR934X_WMAC_SIZE 0x20000 -+#define AR934X_EHCI_BASE 0x1b000000 -+#define AR934X_EHCI_SIZE 0x200 -+ -+#define QCA955X_PCI_MEM_BASE0 0x10000000 -+#define QCA955X_PCI_MEM_BASE1 0x12000000 -+#define QCA955X_PCI_MEM_SIZE 0x02000000 -+#define QCA955X_PCI_CFG_BASE0 0x14000000 -+#define QCA955X_PCI_CFG_BASE1 0x16000000 -+#define QCA955X_PCI_CFG_SIZE 0x1000 -+#define QCA955X_PCI_CRP_BASE0 (AR71XX_APB_BASE + 0x000c0000) -+#define QCA955X_PCI_CRP_BASE1 (AR71XX_APB_BASE + 0x00250000) -+#define QCA955X_PCI_CRP_SIZE 0x1000 -+#define QCA955X_PCI_CTRL_BASE0 (AR71XX_APB_BASE + 0x000f0000) -+#define QCA955X_PCI_CTRL_BASE1 (AR71XX_APB_BASE + 0x00280000) -+#define QCA955X_PCI_CTRL_SIZE 0x100 -+ -+#define QCA955X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) -+#define QCA955X_WMAC_SIZE 0x20000 -+#define QCA955X_EHCI0_BASE 0x1b000000 -+#define QCA955X_EHCI1_BASE 0x1b400000 -+#define QCA955X_EHCI_SIZE 0x1000 -+#define QCA955X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) -+#define QCA955X_GMAC_SIZE 0x40 -+ -+#define AR9300_OTP_BASE 0x14000 -+#define AR9300_OTP_STATUS 0x15f18 -+#define AR9300_OTP_STATUS_TYPE 0x7 -+#define AR9300_OTP_STATUS_VALID 0x4 -+#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2 -+#define AR9300_OTP_STATUS_SM_BUSY 0x1 -+#define AR9300_OTP_READ_DATA 0x15f1c -+ -+/* -+ * DDR_CTRL block -+ */ -+#define AR71XX_DDR_REG_PCI_WIN0 0x7c -+#define AR71XX_DDR_REG_PCI_WIN1 0x80 -+#define AR71XX_DDR_REG_PCI_WIN2 0x84 -+#define AR71XX_DDR_REG_PCI_WIN3 0x88 -+#define AR71XX_DDR_REG_PCI_WIN4 0x8c -+#define AR71XX_DDR_REG_PCI_WIN5 0x90 -+#define AR71XX_DDR_REG_PCI_WIN6 0x94 -+#define AR71XX_DDR_REG_PCI_WIN7 0x98 -+#define AR71XX_DDR_REG_FLUSH_GE0 0x9c -+#define AR71XX_DDR_REG_FLUSH_GE1 0xa0 -+#define AR71XX_DDR_REG_FLUSH_USB 0xa4 -+#define AR71XX_DDR_REG_FLUSH_PCI 0xa8 -+ -+#define AR724X_DDR_REG_FLUSH_GE0 0x7c -+#define AR724X_DDR_REG_FLUSH_GE1 0x80 -+#define AR724X_DDR_REG_FLUSH_USB 0x84 -+#define AR724X_DDR_REG_FLUSH_PCIE 0x88 -+ -+#define AR913X_DDR_REG_FLUSH_GE0 0x7c -+#define AR913X_DDR_REG_FLUSH_GE1 0x80 -+#define AR913X_DDR_REG_FLUSH_USB 0x84 -+#define AR913X_DDR_REG_FLUSH_WMAC 0x88 -+ -+#define AR933X_DDR_REG_FLUSH_GE0 0x7c -+#define AR933X_DDR_REG_FLUSH_GE1 0x80 -+#define AR933X_DDR_REG_FLUSH_USB 0x84 -+#define AR933X_DDR_REG_FLUSH_WMAC 0x88 -+ -+#define AR934X_DDR_REG_FLUSH_GE0 0x9c -+#define AR934X_DDR_REG_FLUSH_GE1 0xa0 -+#define AR934X_DDR_REG_FLUSH_USB 0xa4 -+#define AR934X_DDR_REG_FLUSH_PCIE 0xa8 -+#define AR934X_DDR_REG_FLUSH_WMAC 0xac -+ -+/* -+ * PLL block -+ */ -+#define AR71XX_PLL_REG_CPU_CONFIG 0x00 -+#define AR71XX_PLL_REG_SEC_CONFIG 0x04 -+#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10 -+#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14 -+ -+#define AR71XX_PLL_DIV_SHIFT 3 -+#define AR71XX_PLL_DIV_MASK 0x1f -+#define AR71XX_CPU_DIV_SHIFT 16 -+#define AR71XX_CPU_DIV_MASK 0x3 -+#define AR71XX_DDR_DIV_SHIFT 18 -+#define AR71XX_DDR_DIV_MASK 0x3 -+#define AR71XX_AHB_DIV_SHIFT 20 -+#define AR71XX_AHB_DIV_MASK 0x7 -+ -+#define AR71XX_ETH0_PLL_SHIFT 17 -+#define AR71XX_ETH1_PLL_SHIFT 19 -+ -+#define AR724X_PLL_REG_CPU_CONFIG 0x00 -+#define AR724X_PLL_REG_PCIE_CONFIG 0x18 -+ -+#define AR724X_PLL_DIV_SHIFT 0 -+#define AR724X_PLL_DIV_MASK 0x3ff -+#define AR724X_PLL_REF_DIV_SHIFT 10 -+#define AR724X_PLL_REF_DIV_MASK 0xf -+#define AR724X_AHB_DIV_SHIFT 19 -+#define AR724X_AHB_DIV_MASK 0x1 -+#define AR724X_DDR_DIV_SHIFT 22 -+#define AR724X_DDR_DIV_MASK 0x3 -+ -+#define AR7242_PLL_REG_ETH0_INT_CLOCK 0x2c -+ -+#define AR913X_PLL_REG_CPU_CONFIG 0x00 -+#define AR913X_PLL_REG_ETH_CONFIG 0x04 -+#define AR913X_PLL_REG_ETH0_INT_CLOCK 0x14 -+#define AR913X_PLL_REG_ETH1_INT_CLOCK 0x18 -+ -+#define AR913X_PLL_DIV_SHIFT 0 -+#define AR913X_PLL_DIV_MASK 0x3ff -+#define AR913X_DDR_DIV_SHIFT 22 -+#define AR913X_DDR_DIV_MASK 0x3 -+#define AR913X_AHB_DIV_SHIFT 19 -+#define AR913X_AHB_DIV_MASK 0x1 -+ -+#define AR913X_ETH0_PLL_SHIFT 20 -+#define AR913X_ETH1_PLL_SHIFT 22 -+ -+#define AR933X_PLL_CPU_CONFIG_REG 0x00 -+#define AR933X_PLL_CLOCK_CTRL_REG 0x08 -+ -+#define AR933X_PLL_CPU_CONFIG_NINT_SHIFT 10 -+#define AR933X_PLL_CPU_CONFIG_NINT_MASK 0x3f -+#define AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT 16 -+#define AR933X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f -+#define AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT 23 -+#define AR933X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7 -+ -+#define AR933X_PLL_CLOCK_CTRL_BYPASS BIT(2) -+#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT 5 -+#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK 0x3 -+#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT 10 -+#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK 0x3 -+#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT 15 -+#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK 0x7 -+ -+#define AR934X_PLL_CPU_CONFIG_REG 0x00 -+#define AR934X_PLL_DDR_CONFIG_REG 0x04 -+#define AR934X_PLL_CPU_DDR_CLK_CTRL_REG 0x08 -+#define AR934X_PLL_ETH_XMII_CONTROL_REG 0x2c -+ -+#define AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT 0 -+#define AR934X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f -+#define AR934X_PLL_CPU_CONFIG_NINT_SHIFT 6 -+#define AR934X_PLL_CPU_CONFIG_NINT_MASK 0x3f -+#define AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT 12 -+#define AR934X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f -+#define AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19 -+#define AR934X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3 -+ -+#define AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT 0 -+#define AR934X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff -+#define AR934X_PLL_DDR_CONFIG_NINT_SHIFT 10 -+#define AR934X_PLL_DDR_CONFIG_NINT_MASK 0x3f -+#define AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT 16 -+#define AR934X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f -+#define AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23 -+#define AR934X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7 -+ -+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS BIT(2) -+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS BIT(3) -+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS BIT(4) -+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT 5 -+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK 0x1f -+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT 10 -+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK 0x1f -+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT 15 -+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK 0x1f -+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20) -+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21) -+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) -+ -+#define QCA955X_PLL_CPU_CONFIG_REG 0x00 -+#define QCA955X_PLL_DDR_CONFIG_REG 0x04 -+#define QCA955X_PLL_CLK_CTRL_REG 0x08 -+ -+#define QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT 0 -+#define QCA955X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f -+#define QCA955X_PLL_CPU_CONFIG_NINT_SHIFT 6 -+#define QCA955X_PLL_CPU_CONFIG_NINT_MASK 0x3f -+#define QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT 12 -+#define QCA955X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f -+#define QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19 -+#define QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3 -+ -+#define QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT 0 -+#define QCA955X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff -+#define QCA955X_PLL_DDR_CONFIG_NINT_SHIFT 10 -+#define QCA955X_PLL_DDR_CONFIG_NINT_MASK 0x3f -+#define QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT 16 -+#define QCA955X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f -+#define QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23 -+#define QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7 -+ -+#define QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2) -+#define QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3) -+#define QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS BIT(4) -+#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT 5 -+#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK 0x1f -+#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT 10 -+#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK 0x1f -+#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT 15 -+#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK 0x1f -+#define QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20) -+#define QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21) -+#define QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) -+ -+/* -+ * USB_CONFIG block -+ */ -+#define AR71XX_USB_CTRL_REG_FLADJ 0x00 -+#define AR71XX_USB_CTRL_REG_CONFIG 0x04 -+ -+/* -+ * RESET block -+ */ -+#define AR71XX_RESET_REG_TIMER 0x00 -+#define AR71XX_RESET_REG_TIMER_RELOAD 0x04 -+#define AR71XX_RESET_REG_WDOG_CTRL 0x08 -+#define AR71XX_RESET_REG_WDOG 0x0c -+#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10 -+#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14 -+#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18 -+#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c -+#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20 -+#define AR71XX_RESET_REG_RESET_MODULE 0x24 -+#define AR71XX_RESET_REG_PERFC_CTRL 0x2c -+#define AR71XX_RESET_REG_PERFC0 0x30 -+#define AR71XX_RESET_REG_PERFC1 0x34 -+#define AR71XX_RESET_REG_REV_ID 0x90 -+ -+#define AR913X_RESET_REG_GLOBAL_INT_STATUS 0x18 -+#define AR913X_RESET_REG_RESET_MODULE 0x1c -+#define AR913X_RESET_REG_PERF_CTRL 0x20 -+#define AR913X_RESET_REG_PERFC0 0x24 -+#define AR913X_RESET_REG_PERFC1 0x28 -+ -+#define AR724X_RESET_REG_RESET_MODULE 0x1c -+ -+#define AR933X_RESET_REG_RESET_MODULE 0x1c -+#define AR933X_RESET_REG_BOOTSTRAP 0xac -+ -+#define AR934X_RESET_REG_RESET_MODULE 0x1c -+#define AR934X_RESET_REG_BOOTSTRAP 0xb0 -+#define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac -+ -+#define QCA955X_RESET_REG_BOOTSTRAP 0xb0 -+#define QCA955X_RESET_REG_EXT_INT_STATUS 0xac -+ -+#define MISC_INT_ETHSW BIT(12) -+#define MISC_INT_TIMER4 BIT(10) -+#define MISC_INT_TIMER3 BIT(9) -+#define MISC_INT_TIMER2 BIT(8) -+#define MISC_INT_DMA BIT(7) -+#define MISC_INT_OHCI BIT(6) -+#define MISC_INT_PERFC BIT(5) -+#define MISC_INT_WDOG BIT(4) -+#define MISC_INT_UART BIT(3) -+#define MISC_INT_GPIO BIT(2) -+#define MISC_INT_ERROR BIT(1) -+#define MISC_INT_TIMER BIT(0) -+ -+#define AR71XX_RESET_EXTERNAL BIT(28) -+#define AR71XX_RESET_FULL_CHIP BIT(24) -+#define AR71XX_RESET_CPU_NMI BIT(21) -+#define AR71XX_RESET_CPU_COLD BIT(20) -+#define AR71XX_RESET_DMA BIT(19) -+#define AR71XX_RESET_SLIC BIT(18) -+#define AR71XX_RESET_STEREO BIT(17) -+#define AR71XX_RESET_DDR BIT(16) -+#define AR71XX_RESET_GE1_MAC BIT(13) -+#define AR71XX_RESET_GE1_PHY BIT(12) -+#define AR71XX_RESET_USBSUS_OVERRIDE BIT(10) -+#define AR71XX_RESET_GE0_MAC BIT(9) -+#define AR71XX_RESET_GE0_PHY BIT(8) -+#define AR71XX_RESET_USB_OHCI_DLL BIT(6) -+#define AR71XX_RESET_USB_HOST BIT(5) -+#define AR71XX_RESET_USB_PHY BIT(4) -+#define AR71XX_RESET_PCI_BUS BIT(1) -+#define AR71XX_RESET_PCI_CORE BIT(0) -+ -+#define AR7240_RESET_USB_HOST BIT(5) -+#define AR7240_RESET_OHCI_DLL BIT(3) -+ -+#define AR724X_RESET_GE1_MDIO BIT(23) -+#define AR724X_RESET_GE0_MDIO BIT(22) -+#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10) -+#define AR724X_RESET_PCIE_PHY BIT(7) -+#define AR724X_RESET_PCIE BIT(6) -+#define AR724X_RESET_USB_HOST BIT(5) -+#define AR724X_RESET_USB_PHY BIT(4) -+#define AR724X_RESET_USBSUS_OVERRIDE BIT(3) -+ -+#define AR913X_RESET_AMBA2WMAC BIT(22) -+#define AR913X_RESET_USBSUS_OVERRIDE BIT(10) -+#define AR913X_RESET_USB_HOST BIT(5) -+#define AR913X_RESET_USB_PHY BIT(4) -+ -+#define AR933X_RESET_GE1_MDIO BIT(23) -+#define AR933X_RESET_GE0_MDIO BIT(22) -+#define AR933X_RESET_GE1_MAC BIT(13) -+#define AR933X_RESET_WMAC BIT(11) -+#define AR933X_RESET_GE0_MAC BIT(9) -+#define AR933X_RESET_USB_HOST BIT(5) -+#define AR933X_RESET_USB_PHY BIT(4) -+#define AR933X_RESET_USBSUS_OVERRIDE BIT(3) -+ -+#define AR934X_RESET_HOST BIT(31) -+#define AR934X_RESET_SLIC BIT(30) -+#define AR934X_RESET_HDMA BIT(29) -+#define AR934X_RESET_EXTERNAL BIT(28) -+#define AR934X_RESET_RTC BIT(27) -+#define AR934X_RESET_PCIE_EP_INT BIT(26) -+#define AR934X_RESET_CHKSUM_ACC BIT(25) -+#define AR934X_RESET_FULL_CHIP BIT(24) -+#define AR934X_RESET_GE1_MDIO BIT(23) -+#define AR934X_RESET_GE0_MDIO BIT(22) -+#define AR934X_RESET_CPU_NMI BIT(21) -+#define AR934X_RESET_CPU_COLD BIT(20) -+#define AR934X_RESET_HOST_RESET_INT BIT(19) -+#define AR934X_RESET_PCIE_EP BIT(18) -+#define AR934X_RESET_UART1 BIT(17) -+#define AR934X_RESET_DDR BIT(16) -+#define AR934X_RESET_USB_PHY_PLL_PWD_EXT BIT(15) -+#define AR934X_RESET_NANDF BIT(14) -+#define AR934X_RESET_GE1_MAC BIT(13) -+#define AR934X_RESET_ETH_SWITCH_ANALOG BIT(12) -+#define AR934X_RESET_USB_PHY_ANALOG BIT(11) -+#define AR934X_RESET_HOST_DMA_INT BIT(10) -+#define AR934X_RESET_GE0_MAC BIT(9) -+#define AR934X_RESET_ETH_SWITCH BIT(8) -+#define AR934X_RESET_PCIE_PHY BIT(7) -+#define AR934X_RESET_PCIE BIT(6) -+#define AR934X_RESET_USB_HOST BIT(5) -+#define AR934X_RESET_USB_PHY BIT(4) -+#define AR934X_RESET_USBSUS_OVERRIDE BIT(3) -+#define AR934X_RESET_LUT BIT(2) -+#define AR934X_RESET_MBOX BIT(1) -+#define AR934X_RESET_I2S BIT(0) -+ -+#define AR933X_BOOTSTRAP_MDIO_GPIO_EN BIT(18) -+#define AR933X_BOOTSTRAP_EEPBUSY BIT(4) -+#define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0) -+ -+#define AR934X_BOOTSTRAP_SW_OPTION8 BIT(23) -+#define AR934X_BOOTSTRAP_SW_OPTION7 BIT(22) -+#define AR934X_BOOTSTRAP_SW_OPTION6 BIT(21) -+#define AR934X_BOOTSTRAP_SW_OPTION5 BIT(20) -+#define AR934X_BOOTSTRAP_SW_OPTION4 BIT(19) -+#define AR934X_BOOTSTRAP_SW_OPTION3 BIT(18) -+#define AR934X_BOOTSTRAP_SW_OPTION2 BIT(17) -+#define AR934X_BOOTSTRAP_SW_OPTION1 BIT(16) -+#define AR934X_BOOTSTRAP_USB_MODE_DEVICE BIT(7) -+#define AR934X_BOOTSTRAP_PCIE_RC BIT(6) -+#define AR934X_BOOTSTRAP_EJTAG_MODE BIT(5) -+#define AR934X_BOOTSTRAP_REF_CLK_40 BIT(4) -+#define AR934X_BOOTSTRAP_BOOT_FROM_SPI BIT(2) -+#define AR934X_BOOTSTRAP_SDRAM_DISABLED BIT(1) -+#define AR934X_BOOTSTRAP_DDR1 BIT(0) -+ -+#define QCA955X_BOOTSTRAP_REF_CLK_40 BIT(4) -+ -+#define AR934X_PCIE_WMAC_INT_WMAC_MISC BIT(0) -+#define AR934X_PCIE_WMAC_INT_WMAC_TX BIT(1) -+#define AR934X_PCIE_WMAC_INT_WMAC_RXLP BIT(2) -+#define AR934X_PCIE_WMAC_INT_WMAC_RXHP BIT(3) -+#define AR934X_PCIE_WMAC_INT_PCIE_RC BIT(4) -+#define AR934X_PCIE_WMAC_INT_PCIE_RC0 BIT(5) -+#define AR934X_PCIE_WMAC_INT_PCIE_RC1 BIT(6) -+#define AR934X_PCIE_WMAC_INT_PCIE_RC2 BIT(7) -+#define AR934X_PCIE_WMAC_INT_PCIE_RC3 BIT(8) -+#define AR934X_PCIE_WMAC_INT_WMAC_ALL \ -+ (AR934X_PCIE_WMAC_INT_WMAC_MISC | AR934X_PCIE_WMAC_INT_WMAC_TX | \ -+ AR934X_PCIE_WMAC_INT_WMAC_RXLP | AR934X_PCIE_WMAC_INT_WMAC_RXHP) -+ -+#define AR934X_PCIE_WMAC_INT_PCIE_ALL \ -+ (AR934X_PCIE_WMAC_INT_PCIE_RC | AR934X_PCIE_WMAC_INT_PCIE_RC0 | \ -+ AR934X_PCIE_WMAC_INT_PCIE_RC1 | AR934X_PCIE_WMAC_INT_PCIE_RC2 | \ -+ AR934X_PCIE_WMAC_INT_PCIE_RC3) -+ -+#define QCA955X_EXT_INT_WMAC_MISC BIT(0) -+#define QCA955X_EXT_INT_WMAC_TX BIT(1) -+#define QCA955X_EXT_INT_WMAC_RXLP BIT(2) -+#define QCA955X_EXT_INT_WMAC_RXHP BIT(3) -+#define QCA955X_EXT_INT_PCIE_RC1 BIT(4) -+#define QCA955X_EXT_INT_PCIE_RC1_INT0 BIT(5) -+#define QCA955X_EXT_INT_PCIE_RC1_INT1 BIT(6) -+#define QCA955X_EXT_INT_PCIE_RC1_INT2 BIT(7) -+#define QCA955X_EXT_INT_PCIE_RC1_INT3 BIT(8) -+#define QCA955X_EXT_INT_PCIE_RC2 BIT(12) -+#define QCA955X_EXT_INT_PCIE_RC2_INT0 BIT(13) -+#define QCA955X_EXT_INT_PCIE_RC2_INT1 BIT(14) -+#define QCA955X_EXT_INT_PCIE_RC2_INT2 BIT(15) -+#define QCA955X_EXT_INT_PCIE_RC2_INT3 BIT(16) -+#define QCA955X_EXT_INT_USB1 BIT(24) -+#define QCA955X_EXT_INT_USB2 BIT(28) -+ -+#define QCA955X_EXT_INT_WMAC_ALL \ -+ (QCA955X_EXT_INT_WMAC_MISC | QCA955X_EXT_INT_WMAC_TX | \ -+ QCA955X_EXT_INT_WMAC_RXLP | QCA955X_EXT_INT_WMAC_RXHP) -+ -+#define QCA955X_EXT_INT_PCIE_RC1_ALL \ -+ (QCA955X_EXT_INT_PCIE_RC1 | QCA955X_EXT_INT_PCIE_RC1_INT0 | \ -+ QCA955X_EXT_INT_PCIE_RC1_INT1 | QCA955X_EXT_INT_PCIE_RC1_INT2 | \ -+ QCA955X_EXT_INT_PCIE_RC1_INT3) -+ -+#define QCA955X_EXT_INT_PCIE_RC2_ALL \ -+ (QCA955X_EXT_INT_PCIE_RC2 | QCA955X_EXT_INT_PCIE_RC2_INT0 | \ -+ QCA955X_EXT_INT_PCIE_RC2_INT1 | QCA955X_EXT_INT_PCIE_RC2_INT2 | \ -+ QCA955X_EXT_INT_PCIE_RC2_INT3) -+ -+#define REV_ID_MAJOR_MASK 0xfff0 -+#define REV_ID_MAJOR_AR71XX 0x00a0 -+#define REV_ID_MAJOR_AR913X 0x00b0 -+#define REV_ID_MAJOR_AR7240 0x00c0 -+#define REV_ID_MAJOR_AR7241 0x0100 -+#define REV_ID_MAJOR_AR7242 0x1100 -+#define REV_ID_MAJOR_AR9330 0x0110 -+#define REV_ID_MAJOR_AR9331 0x1110 -+#define REV_ID_MAJOR_AR9341 0x0120 -+#define REV_ID_MAJOR_AR9342 0x1120 -+#define REV_ID_MAJOR_AR9344 0x2120 -+#define REV_ID_MAJOR_QCA9558 0x1130 -+ -+#define AR71XX_REV_ID_MINOR_MASK 0x3 -+#define AR71XX_REV_ID_MINOR_AR7130 0x0 -+#define AR71XX_REV_ID_MINOR_AR7141 0x1 -+#define AR71XX_REV_ID_MINOR_AR7161 0x2 -+#define AR71XX_REV_ID_REVISION_MASK 0x3 -+#define AR71XX_REV_ID_REVISION_SHIFT 2 -+ -+#define AR913X_REV_ID_MINOR_MASK 0x3 -+#define AR913X_REV_ID_MINOR_AR9130 0x0 -+#define AR913X_REV_ID_MINOR_AR9132 0x1 -+#define AR913X_REV_ID_REVISION_MASK 0x3 -+#define AR913X_REV_ID_REVISION_SHIFT 2 -+ -+#define AR933X_REV_ID_REVISION_MASK 0x3 -+ -+#define AR724X_REV_ID_REVISION_MASK 0x3 -+ -+#define AR934X_REV_ID_REVISION_MASK 0xf -+ -+#define AR944X_REV_ID_REVISION_MASK 0xf -+ -+/* -+ * SPI block -+ */ -+#define AR71XX_SPI_REG_FS 0x00 /* Function Select */ -+#define AR71XX_SPI_REG_CTRL 0x04 /* SPI Control */ -+#define AR71XX_SPI_REG_IOC 0x08 /* SPI I/O Control */ -+#define AR71XX_SPI_REG_RDS 0x0c /* Read Data Shift */ -+ -+#define AR71XX_SPI_FS_GPIO BIT(0) /* Enable GPIO mode */ -+ -+#define AR71XX_SPI_CTRL_RD BIT(6) /* Remap Disable */ -+#define AR71XX_SPI_CTRL_DIV_MASK 0x3f -+ -+#define AR71XX_SPI_IOC_DO BIT(0) /* Data Out pin */ -+#define AR71XX_SPI_IOC_CLK BIT(8) /* CLK pin */ -+#define AR71XX_SPI_IOC_CS(n) BIT(16 + (n)) -+#define AR71XX_SPI_IOC_CS0 AR71XX_SPI_IOC_CS(0) -+#define AR71XX_SPI_IOC_CS1 AR71XX_SPI_IOC_CS(1) -+#define AR71XX_SPI_IOC_CS2 AR71XX_SPI_IOC_CS(2) -+#define AR71XX_SPI_IOC_CS_ALL (AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1 | \ -+ AR71XX_SPI_IOC_CS2) -+ -+/* -+ * GPIO block -+ */ -+#define AR71XX_GPIO_REG_OE 0x00 -+#define AR71XX_GPIO_REG_IN 0x04 -+#define AR71XX_GPIO_REG_OUT 0x08 -+#define AR71XX_GPIO_REG_SET 0x0c -+#define AR71XX_GPIO_REG_CLEAR 0x10 -+#define AR71XX_GPIO_REG_INT_MODE 0x14 -+#define AR71XX_GPIO_REG_INT_TYPE 0x18 -+#define AR71XX_GPIO_REG_INT_POLARITY 0x1c -+#define AR71XX_GPIO_REG_INT_PENDING 0x20 -+#define AR71XX_GPIO_REG_INT_ENABLE 0x24 -+#define AR71XX_GPIO_REG_FUNC 0x28 -+ -+#define AR934X_GPIO_REG_OUT_FUNC0 0x2c -+#define AR934X_GPIO_REG_OUT_FUNC1 0x30 -+#define AR934X_GPIO_REG_OUT_FUNC2 0x34 -+#define AR934X_GPIO_REG_OUT_FUNC3 0x38 -+#define AR934X_GPIO_REG_OUT_FUNC4 0x3c -+#define AR934X_GPIO_REG_OUT_FUNC5 0x40 -+#define AR934X_GPIO_REG_FUNC 0x6c -+ -+#define AR71XX_GPIO_COUNT 16 -+#define AR724X_GPIO_COUNT 18 -+#define AR913X_GPIO_COUNT 22 -+#define AR933X_GPIO_COUNT 30 -+#define AR934X_GPIO_COUNT 23 -+#define QCA955X_GPIO_COUNT 24 -+ -+#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17) -+#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16) -+#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13) -+#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12) -+#define AR71XX_GPIO_FUNC_UART_EN BIT(8) -+#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4) -+#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0) -+ -+#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19) -+#define AR724X_GPIO_FUNC_SPI_EN BIT(18) -+#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14) -+#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13) -+#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12) -+#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11) -+#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10) -+#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9) -+#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8) -+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7) -+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6) -+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5) -+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4) -+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3) -+#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2) -+#define AR724X_GPIO_FUNC_UART_EN BIT(1) -+#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0) -+ -+#define AR913X_GPIO_FUNC_WMAC_LED_EN BIT(22) -+#define AR913X_GPIO_FUNC_EXP_PORT_CS_EN BIT(21) -+#define AR913X_GPIO_FUNC_I2S_REFCLKEN BIT(20) -+#define AR913X_GPIO_FUNC_I2S_MCKEN BIT(19) -+#define AR913X_GPIO_FUNC_I2S1_EN BIT(18) -+#define AR913X_GPIO_FUNC_I2S0_EN BIT(17) -+#define AR913X_GPIO_FUNC_SLIC_EN BIT(16) -+#define AR913X_GPIO_FUNC_UART_RTSCTS_EN BIT(9) -+#define AR913X_GPIO_FUNC_UART_EN BIT(8) -+#define AR913X_GPIO_FUNC_USB_CLK_EN BIT(4) -+ -+#define AR933X_GPIO_FUNC_SPDIF2TCK BIT(31) -+#define AR933X_GPIO_FUNC_SPDIF_EN BIT(30) -+#define AR933X_GPIO_FUNC_I2SO_22_18_EN BIT(29) -+#define AR933X_GPIO_FUNC_I2S_MCK_EN BIT(27) -+#define AR933X_GPIO_FUNC_I2SO_EN BIT(26) -+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_DUPL BIT(25) -+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_COLL BIT(24) -+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_ACT BIT(23) -+#define AR933X_GPIO_FUNC_SPI_EN BIT(18) -+#define AR933X_GPIO_FUNC_SPI_CS_EN2 BIT(14) -+#define AR933X_GPIO_FUNC_SPI_CS_EN1 BIT(13) -+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7) -+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6) -+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5) -+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4) -+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3) -+#define AR933X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2) -+#define AR933X_GPIO_FUNC_UART_EN BIT(1) -+#define AR933X_GPIO_FUNC_JTAG_DISABLE BIT(0) -+ -+#define AR934X_GPIO_FUNC_DDR_DQOE_EN BIT(17) -+#define AR934X_GPIO_FUNC_SPI_CS_1_EN BIT(14) -+#define AR934X_GPIO_FUNC_SPI_CS_0_EN BIT(13) -+ -+#define AR934X_GPIO_OUT_GPIO 0x00 -+ -+/* -+ * MII_CTRL block -+ */ -+#define AR71XX_MII_REG_MII0_CTRL 0x00 -+#define AR71XX_MII_REG_MII1_CTRL 0x04 -+ -+#define AR71XX_MII_CTRL_IF_MASK 3 -+#define AR71XX_MII_CTRL_SPEED_SHIFT 4 -+#define AR71XX_MII_CTRL_SPEED_MASK 3 -+#define AR71XX_MII_CTRL_SPEED_10 0 -+#define AR71XX_MII_CTRL_SPEED_100 1 -+#define AR71XX_MII_CTRL_SPEED_1000 2 -+ -+#define AR71XX_MII0_CTRL_IF_GMII 0 -+#define AR71XX_MII0_CTRL_IF_MII 1 -+#define AR71XX_MII0_CTRL_IF_RGMII 2 -+#define AR71XX_MII0_CTRL_IF_RMII 3 -+ -+#define AR71XX_MII1_CTRL_IF_RGMII 0 -+#define AR71XX_MII1_CTRL_IF_RMII 1 -+ -+/* -+ * AR933X GMAC interface -+ */ -+#define AR933X_GMAC_REG_ETH_CFG 0x00 -+ -+#define AR933X_ETH_CFG_RGMII_GE0 BIT(0) -+#define AR933X_ETH_CFG_MII_GE0 BIT(1) -+#define AR933X_ETH_CFG_GMII_GE0 BIT(2) -+#define AR933X_ETH_CFG_MII_GE0_MASTER BIT(3) -+#define AR933X_ETH_CFG_MII_GE0_SLAVE BIT(4) -+#define AR933X_ETH_CFG_MII_GE0_ERR_EN BIT(5) -+#define AR933X_ETH_CFG_SW_PHY_SWAP BIT(7) -+#define AR933X_ETH_CFG_SW_PHY_ADDR_SWAP BIT(8) -+#define AR933X_ETH_CFG_RMII_GE0 BIT(9) -+#define AR933X_ETH_CFG_RMII_GE0_SPD_10 0 -+#define AR933X_ETH_CFG_RMII_GE0_SPD_100 BIT(10) -+ -+/* -+ * AR934X GMAC Interface -+ */ -+#define AR934X_GMAC_REG_ETH_CFG 0x00 -+ -+#define AR934X_ETH_CFG_RGMII_GMAC0 BIT(0) -+#define AR934X_ETH_CFG_MII_GMAC0 BIT(1) -+#define AR934X_ETH_CFG_GMII_GMAC0 BIT(2) -+#define AR934X_ETH_CFG_MII_GMAC0_MASTER BIT(3) -+#define AR934X_ETH_CFG_MII_GMAC0_SLAVE BIT(4) -+#define AR934X_ETH_CFG_MII_GMAC0_ERR_EN BIT(5) -+#define AR934X_ETH_CFG_SW_ONLY_MODE BIT(6) -+#define AR934X_ETH_CFG_SW_PHY_SWAP BIT(7) -+#define AR934X_ETH_CFG_SW_APB_ACCESS BIT(9) -+#define AR934X_ETH_CFG_RMII_GMAC0 BIT(10) -+#define AR933X_ETH_CFG_MII_CNTL_SPEED BIT(11) -+#define AR934X_ETH_CFG_RMII_GMAC0_MASTER BIT(12) -+#define AR933X_ETH_CFG_SW_ACC_MSB_FIRST BIT(13) -+ -+/* -+ * QCA955X GMAC Interface -+ */ -+ -+#define QCA955X_GMAC_REG_ETH_CFG 0x00 -+ -+#define QCA955X_ETH_CFG_RGMII_GMAC0 BIT(0) -+#define QCA955X_ETH_CFG_SGMII_GMAC0 BIT(6) -+ -+#endif /* __ASM_MACH_AR71XX_REGS_H */ -diff --git a/target/linux/ar71xx/image/lzma-loader/src/board.c b/target/linux/ar71xx/image/lzma-loader/src/board.c -new file mode 100644 -index 0000000000..2f4dd6b1f6 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/board.c -@@ -0,0 +1,56 @@ -+/* -+ * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards -+ * -+ * Copyright (C) 2011 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include "config.h" -+#include "ar71xx_regs.h" -+ -+#define READREG(r) *(volatile unsigned int *)(r) -+#define WRITEREG(r,v) *(volatile unsigned int *)(r) = v -+ -+#define KSEG1ADDR(_x) (((_x) & 0x1fffffff) | 0xa0000000) -+ -+#define UART_BASE 0xb8020000 -+ -+#define UART_TX 0 -+#define UART_LSR 5 -+ -+#define UART_LSR_THRE 0x20 -+ -+#define UART_READ(r) READREG(UART_BASE + 4 * (r)) -+#define UART_WRITE(r,v) WRITEREG(UART_BASE + 4 * (r), (v)) -+ -+void board_putc(int ch) -+{ -+ while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0); -+ UART_WRITE(UART_TX, ch); -+ while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0); -+} -+ -+#ifdef CONFIG_BOARD_TL_WR1043ND_V1 -+static void tlwr1043nd_init(void) -+{ -+ unsigned int reg = KSEG1ADDR(AR71XX_RESET_BASE); -+ unsigned int t; -+ -+ t = READREG(reg + AR913X_RESET_REG_RESET_MODULE); -+ t |= AR71XX_RESET_GE0_PHY; -+ WRITEREG(reg + AR913X_RESET_REG_RESET_MODULE, t); -+ /* flush write */ -+ t = READREG(reg + AR913X_RESET_REG_RESET_MODULE); -+} -+#else -+static inline void tlwr1043nd_init(void) {} -+#endif -+ -+void board_init(void) -+{ -+ tlwr1043nd_init(); -+} -diff --git a/target/linux/ar71xx/image/lzma-loader/src/cache.c b/target/linux/ar71xx/image/lzma-loader/src/cache.c -new file mode 100644 -index 0000000000..28cc848333 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/cache.c -@@ -0,0 +1,43 @@ -+/* -+ * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards -+ * -+ * Copyright (C) 2011 Gabor Juhos -+ * -+ * The cache manipulation routine has been taken from the U-Boot project. -+ * (C) Copyright 2003 -+ * Wolfgang Denk, DENX Software Engineering, -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#include "cache.h" -+#include "cacheops.h" -+#include "config.h" -+ -+#define cache_op(op,addr) \ -+ __asm__ __volatile__( \ -+ " .set push \n" \ -+ " .set noreorder \n" \ -+ " .set mips3\n\t \n" \ -+ " cache %0, %1 \n" \ -+ " .set pop \n" \ -+ : \ -+ : "i" (op), "R" (*(unsigned char *)(addr))) -+ -+void flush_cache(unsigned long start_addr, unsigned long size) -+{ -+ unsigned long lsize = CONFIG_CACHELINE_SIZE; -+ unsigned long addr = start_addr & ~(lsize - 1); -+ unsigned long aend = (start_addr + size - 1) & ~(lsize - 1); -+ -+ while (1) { -+ cache_op(Hit_Writeback_Inv_D, addr); -+ cache_op(Hit_Invalidate_I, addr); -+ if (addr == aend) -+ break; -+ addr += lsize; -+ } -+} -diff --git a/target/linux/ar71xx/image/lzma-loader/src/cache.h b/target/linux/ar71xx/image/lzma-loader/src/cache.h -new file mode 100644 -index 0000000000..506a235884 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/cache.h -@@ -0,0 +1,17 @@ -+/* -+ * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards -+ * -+ * Copyright (C) 2011 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#ifndef __CACHE_H -+#define __CACHE_H -+ -+void flush_cache(unsigned long start_addr, unsigned long size); -+ -+#endif /* __CACHE_H */ -diff --git a/target/linux/ar71xx/image/lzma-loader/src/cacheops.h b/target/linux/ar71xx/image/lzma-loader/src/cacheops.h -new file mode 100644 -index 0000000000..70bcad7694 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/cacheops.h -@@ -0,0 +1,85 @@ -+/* -+ * Cache operations for the cache instruction. -+ * -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * (C) Copyright 1996, 97, 99, 2002, 03 Ralf Baechle -+ * (C) Copyright 1999 Silicon Graphics, Inc. -+ */ -+#ifndef __ASM_CACHEOPS_H -+#define __ASM_CACHEOPS_H -+ -+/* -+ * Cache Operations available on all MIPS processors with R4000-style caches -+ */ -+#define Index_Invalidate_I 0x00 -+#define Index_Writeback_Inv_D 0x01 -+#define Index_Load_Tag_I 0x04 -+#define Index_Load_Tag_D 0x05 -+#define Index_Store_Tag_I 0x08 -+#define Index_Store_Tag_D 0x09 -+#if defined(CONFIG_CPU_LOONGSON2) -+#define Hit_Invalidate_I 0x00 -+#else -+#define Hit_Invalidate_I 0x10 -+#endif -+#define Hit_Invalidate_D 0x11 -+#define Hit_Writeback_Inv_D 0x15 -+ -+/* -+ * R4000-specific cacheops -+ */ -+#define Create_Dirty_Excl_D 0x0d -+#define Fill 0x14 -+#define Hit_Writeback_I 0x18 -+#define Hit_Writeback_D 0x19 -+ -+/* -+ * R4000SC and R4400SC-specific cacheops -+ */ -+#define Index_Invalidate_SI 0x02 -+#define Index_Writeback_Inv_SD 0x03 -+#define Index_Load_Tag_SI 0x06 -+#define Index_Load_Tag_SD 0x07 -+#define Index_Store_Tag_SI 0x0A -+#define Index_Store_Tag_SD 0x0B -+#define Create_Dirty_Excl_SD 0x0f -+#define Hit_Invalidate_SI 0x12 -+#define Hit_Invalidate_SD 0x13 -+#define Hit_Writeback_Inv_SD 0x17 -+#define Hit_Writeback_SD 0x1b -+#define Hit_Set_Virtual_SI 0x1e -+#define Hit_Set_Virtual_SD 0x1f -+ -+/* -+ * R5000-specific cacheops -+ */ -+#define R5K_Page_Invalidate_S 0x17 -+ -+/* -+ * RM7000-specific cacheops -+ */ -+#define Page_Invalidate_T 0x16 -+ -+/* -+ * R10000-specific cacheops -+ * -+ * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused. -+ * Most of the _S cacheops are identical to the R4000SC _SD cacheops. -+ */ -+#define Index_Writeback_Inv_S 0x03 -+#define Index_Load_Tag_S 0x07 -+#define Index_Store_Tag_S 0x0B -+#define Hit_Invalidate_S 0x13 -+#define Cache_Barrier 0x14 -+#define Hit_Writeback_Inv_S 0x17 -+#define Index_Load_Data_I 0x18 -+#define Index_Load_Data_D 0x19 -+#define Index_Load_Data_S 0x1b -+#define Index_Store_Data_I 0x1c -+#define Index_Store_Data_D 0x1d -+#define Index_Store_Data_S 0x1f -+ -+#endif /* __ASM_CACHEOPS_H */ -diff --git a/target/linux/ar71xx/image/lzma-loader/src/config.h b/target/linux/ar71xx/image/lzma-loader/src/config.h -new file mode 100644 -index 0000000000..287392b340 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/config.h -@@ -0,0 +1,31 @@ -+/* -+ * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards -+ * -+ * Copyright (C) 2011 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ */ -+ -+#ifndef _CONFIG_H_ -+#define _CONFIG_H_ -+ -+#define CONFIG_ICACHE_SIZE (32 * 1024) -+#define CONFIG_DCACHE_SIZE (64 * 1024) -+#define CONFIG_CACHELINE_SIZE 32 -+ -+#ifndef CONFIG_FLASH_OFFS -+#define CONFIG_FLASH_OFFS 0 -+#endif -+ -+#ifndef CONFIG_FLASH_MAX -+#define CONFIG_FLASH_MAX 0 -+#endif -+ -+#ifndef CONFIG_FLASH_STEP -+#define CONFIG_FLASH_STEP 0x1000 -+#endif -+ -+#endif /* _CONFIG_H_ */ -diff --git a/target/linux/ar71xx/image/lzma-loader/src/cp0regdef.h b/target/linux/ar71xx/image/lzma-loader/src/cp0regdef.h -new file mode 100644 -index 0000000000..c1188ad8c8 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/cp0regdef.h -@@ -0,0 +1,39 @@ -+/* -+ * Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001 by Ralf Baechle -+ * -+ * Copyright (C) 2001, Monta Vista Software -+ * Author: jsun@mvista.com or jsun@junsun.net -+ */ -+#ifndef _cp0regdef_h_ -+#define _cp0regdef_h_ -+ -+#define CP0_INDEX $0 -+#define CP0_RANDOM $1 -+#define CP0_ENTRYLO0 $2 -+#define CP0_ENTRYLO1 $3 -+#define CP0_CONTEXT $4 -+#define CP0_PAGEMASK $5 -+#define CP0_WIRED $6 -+#define CP0_BADVADDR $8 -+#define CP0_COUNT $9 -+#define CP0_ENTRYHI $10 -+#define CP0_COMPARE $11 -+#define CP0_STATUS $12 -+#define CP0_CAUSE $13 -+#define CP0_EPC $14 -+#define CP0_PRID $15 -+#define CP0_CONFIG $16 -+#define CP0_LLADDR $17 -+#define CP0_WATCHLO $18 -+#define CP0_WATCHHI $19 -+#define CP0_XCONTEXT $20 -+#define CP0_FRAMEMASK $21 -+#define CP0_DIAGNOSTIC $22 -+#define CP0_PERFORMANCE $25 -+#define CP0_ECC $26 -+#define CP0_CACHEERR $27 -+#define CP0_TAGLO $28 -+#define CP0_TAGHI $29 -+#define CP0_ERROREPC $30 -+ -+#endif -diff --git a/target/linux/ar71xx/image/lzma-loader/src/head.S b/target/linux/ar71xx/image/lzma-loader/src/head.S -new file mode 100644 -index 0000000000..d414b14d11 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/head.S -@@ -0,0 +1,134 @@ -+/* -+ * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards -+ * -+ * Copyright (C) 2011 Gabor Juhos -+ * -+ * Some parts of this code was based on the OpenWrt specific lzma-loader -+ * for the BCM47xx and ADM5120 based boards: -+ * Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) -+ * Copyright (C) 2005 by Oleg I. Vdovikin -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include "cp0regdef.h" -+#include "cacheops.h" -+#include "config.h" -+ -+#define KSEG0 0x80000000 -+ -+ .macro ehb -+ sll zero, 3 -+ .endm -+ -+ .text -+ -+LEAF(startup) -+ .set noreorder -+ .set mips32 -+ -+ mtc0 zero, CP0_WATCHLO # clear watch registers -+ mtc0 zero, CP0_WATCHHI -+ mtc0 zero, CP0_CAUSE # clear before writing status register -+ -+ mfc0 t0, CP0_STATUS -+ li t1, 0x1000001f -+ or t0, t1 -+ xori t0, 0x1f -+ mtc0 t0, CP0_STATUS -+ ehb -+ -+ /* -+ * Some bootloaders set the 'Kseg0 coherency algorithm' to -+ * 'Cacheable, noncoherent, write-through, no write allocate' -+ * and this cause performance issues. Let's go and change it to -+ * 'Cacheable, noncoherent, write-back, write allocate' -+ */ -+ mfc0 t0, CP0_CONFIG -+ li t1, ~7 #~CONF_CM_CMASK -+ and t0, t1 -+ ori t0, 3 #CONF_CM_CACHABLE_NONCOHERENT -+ mtc0 t0, CP0_CONFIG -+ nop -+ -+ mtc0 zero, CP0_COUNT -+ mtc0 zero, CP0_COMPARE -+ ehb -+ -+ la t0, __reloc_label # get linked address of label -+ bal __reloc_label # branch and link to label to -+ nop # get actual address -+__reloc_label: -+ subu t0, ra, t0 # get reloc_delta -+ -+ beqz t0, __reloc_done # if delta is 0 we are in the right place -+ nop -+ -+ /* Copy our code to the right place */ -+ la t1, _code_start # get linked address of _code_start -+ la t2, _code_end # get linked address of _code_end -+ addu t0, t0, t1 # calculate actual address of _code_start -+ -+__reloc_copy: -+ lw t3, 0(t0) -+ sw t3, 0(t1) -+ add t1, 4 -+ blt t1, t2, __reloc_copy -+ add t0, 4 -+ -+ /* flush cache */ -+ la t0, _code_start -+ la t1, _code_end -+ -+ li t2, ~(CONFIG_CACHELINE_SIZE - 1) -+ and t0, t2 -+ and t1, t2 -+ li t2, CONFIG_CACHELINE_SIZE -+ -+ b __flush_check -+ nop -+ -+__flush_line: -+ cache Hit_Writeback_Inv_D, 0(t0) -+ cache Hit_Invalidate_I, 0(t0) -+ add t0, t2 -+ -+__flush_check: -+ bne t0, t1, __flush_line -+ nop -+ -+ sync -+ -+__reloc_done: -+ -+ /* clear bss */ -+ la t0, _bss_start -+ la t1, _bss_end -+ b __bss_check -+ nop -+ -+__bss_fill: -+ sw zero, 0(t0) -+ addi t0, 4 -+ -+__bss_check: -+ bne t0, t1, __bss_fill -+ nop -+ -+ /* Setup new "C" stack */ -+ la sp, _stack -+ -+ /* reserve stack space for a0-a3 registers */ -+ subu sp, 16 -+ -+ /* jump to the decompressor routine */ -+ la t0, loader_main -+ jr t0 -+ nop -+ -+ .set reorder -+END(startup) -diff --git a/target/linux/ar71xx/image/lzma-loader/src/loader.c b/target/linux/ar71xx/image/lzma-loader/src/loader.c -new file mode 100644 -index 0000000000..794c4b6285 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/loader.c -@@ -0,0 +1,264 @@ -+/* -+ * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards -+ * -+ * Copyright (C) 2011 Gabor Juhos -+ * -+ * Some parts of this code was based on the OpenWrt specific lzma-loader -+ * for the BCM47xx and ADM5120 based boards: -+ * Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) -+ * Copyright (C) 2005 Mineharu Takahara -+ * Copyright (C) 2005 by Oleg I. Vdovikin -+ * -+ * The image_header structure has been taken from the U-Boot project. -+ * (C) Copyright 2008 Semihalf -+ * (C) Copyright 2000-2005 -+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include "config.h" -+#include "cache.h" -+#include "printf.h" -+#include "LzmaDecode.h" -+ -+#define AR71XX_FLASH_START 0x1f000000 -+#define AR71XX_FLASH_END 0x1fe00000 -+ -+#define KSEG0 0x80000000 -+#define KSEG1 0xa0000000 -+ -+#define KSEG1ADDR(a) ((((unsigned)(a)) & 0x1fffffffU) | KSEG1) -+ -+#undef LZMA_DEBUG -+ -+#ifdef LZMA_DEBUG -+# define DBG(f, a...) printf(f, ## a) -+#else -+# define DBG(f, a...) do {} while (0) -+#endif -+ -+#define IH_MAGIC_OKLI 0x4f4b4c49 /* 'OKLI' */ -+ -+#define IH_NMLEN 32 /* Image Name Length */ -+ -+typedef struct image_header { -+ uint32_t ih_magic; /* Image Header Magic Number */ -+ uint32_t ih_hcrc; /* Image Header CRC Checksum */ -+ uint32_t ih_time; /* Image Creation Timestamp */ -+ uint32_t ih_size; /* Image Data Size */ -+ uint32_t ih_load; /* Data Load Address */ -+ uint32_t ih_ep; /* Entry Point Address */ -+ uint32_t ih_dcrc; /* Image Data CRC Checksum */ -+ uint8_t ih_os; /* Operating System */ -+ uint8_t ih_arch; /* CPU architecture */ -+ uint8_t ih_type; /* Image Type */ -+ uint8_t ih_comp; /* Compression Type */ -+ uint8_t ih_name[IH_NMLEN]; /* Image Name */ -+} image_header_t; -+ -+/* beyond the image end, size not known in advance */ -+extern unsigned char workspace[]; -+extern void board_init(void); -+ -+static CLzmaDecoderState lzma_state; -+static unsigned char *lzma_data; -+static unsigned long lzma_datasize; -+static unsigned long lzma_outsize; -+static unsigned long kernel_la; -+ -+#ifdef CONFIG_KERNEL_CMDLINE -+#define kernel_argc 2 -+static const char kernel_cmdline[] = CONFIG_KERNEL_CMDLINE; -+static const char *const kernel_argv[] = { -+ NULL, -+ kernel_cmdline, -+ NULL, -+}; -+#endif /* CONFIG_KERNEL_CMDLINE */ -+ -+static void halt(void) -+{ -+ printf("\nSystem halted!\n"); -+ for(;;); -+} -+ -+static __inline__ unsigned long get_be32(void *buf) -+{ -+ unsigned char *p = buf; -+ -+ return (((unsigned long) p[0] << 24) + -+ ((unsigned long) p[1] << 16) + -+ ((unsigned long) p[2] << 8) + -+ (unsigned long) p[3]); -+} -+ -+static __inline__ unsigned char lzma_get_byte(void) -+{ -+ unsigned char c; -+ -+ lzma_datasize--; -+ c = *lzma_data++; -+ -+ return c; -+} -+ -+static int lzma_init_props(void) -+{ -+ unsigned char props[LZMA_PROPERTIES_SIZE]; -+ int res; -+ int i; -+ -+ /* read lzma properties */ -+ for (i = 0; i < LZMA_PROPERTIES_SIZE; i++) -+ props[i] = lzma_get_byte(); -+ -+ /* read the lower half of uncompressed size in the header */ -+ lzma_outsize = ((SizeT) lzma_get_byte()) + -+ ((SizeT) lzma_get_byte() << 8) + -+ ((SizeT) lzma_get_byte() << 16) + -+ ((SizeT) lzma_get_byte() << 24); -+ -+ /* skip rest of the header (upper half of uncompressed size) */ -+ for (i = 0; i < 4; i++) -+ lzma_get_byte(); -+ -+ res = LzmaDecodeProperties(&lzma_state.Properties, props, -+ LZMA_PROPERTIES_SIZE); -+ return res; -+} -+ -+static int lzma_decompress(unsigned char *outStream) -+{ -+ SizeT ip, op; -+ int ret; -+ -+ lzma_state.Probs = (CProb *) workspace; -+ -+ ret = LzmaDecode(&lzma_state, lzma_data, lzma_datasize, &ip, outStream, -+ lzma_outsize, &op); -+ -+ if (ret != LZMA_RESULT_OK) { -+ int i; -+ -+ DBG("LzmaDecode error %d at %08x, osize:%d ip:%d op:%d\n", -+ ret, lzma_data + ip, lzma_outsize, ip, op); -+ -+ for (i = 0; i < 16; i++) -+ DBG("%02x ", lzma_data[ip + i]); -+ -+ DBG("\n"); -+ } -+ -+ return ret; -+} -+ -+#if (LZMA_WRAPPER) -+static void lzma_init_data(void) -+{ -+ extern unsigned char _lzma_data_start[]; -+ extern unsigned char _lzma_data_end[]; -+ -+ kernel_la = LOADADDR; -+ lzma_data = _lzma_data_start; -+ lzma_datasize = _lzma_data_end - _lzma_data_start; -+} -+#else -+static void lzma_init_data(void) -+{ -+ struct image_header *hdr = NULL; -+ unsigned char *flash_base; -+ unsigned long flash_ofs; -+ unsigned long kernel_ofs; -+ unsigned long kernel_size; -+ -+ flash_base = (unsigned char *) KSEG1ADDR(AR71XX_FLASH_START); -+ -+ printf("Looking for OpenWrt image... "); -+ -+ for (flash_ofs = CONFIG_FLASH_OFFS; -+ flash_ofs <= (CONFIG_FLASH_OFFS + CONFIG_FLASH_MAX); -+ flash_ofs += CONFIG_FLASH_STEP) { -+ unsigned long magic; -+ unsigned char *p; -+ -+ p = flash_base + flash_ofs; -+ magic = get_be32(p); -+ if (magic == IH_MAGIC_OKLI) { -+ hdr = (struct image_header *) p; -+ break; -+ } -+ } -+ -+ if (hdr == NULL) { -+ printf("not found!\n"); -+ halt(); -+ } -+ -+ printf("found at 0x%08x\n", flash_base + flash_ofs); -+ -+ kernel_ofs = sizeof(struct image_header); -+ kernel_size = get_be32(&hdr->ih_size); -+ kernel_la = get_be32(&hdr->ih_load); -+ -+ lzma_data = flash_base + flash_ofs + kernel_ofs; -+ lzma_datasize = kernel_size; -+} -+#endif /* (LZMA_WRAPPER) */ -+ -+void loader_main(unsigned long reg_a0, unsigned long reg_a1, -+ unsigned long reg_a2, unsigned long reg_a3) -+{ -+ void (*kernel_entry) (unsigned long, unsigned long, unsigned long, -+ unsigned long); -+ int res; -+ -+ board_init(); -+ -+ printf("\n\nOpenWrt kernel loader for AR7XXX/AR9XXX\n"); -+ printf("Copyright (C) 2011 Gabor Juhos \n"); -+ -+ lzma_init_data(); -+ -+ res = lzma_init_props(); -+ if (res != LZMA_RESULT_OK) { -+ printf("Incorrect LZMA stream properties!\n"); -+ halt(); -+ } -+ -+ printf("Decompressing kernel... "); -+ -+ res = lzma_decompress((unsigned char *) kernel_la); -+ if (res != LZMA_RESULT_OK) { -+ printf("failed, "); -+ switch (res) { -+ case LZMA_RESULT_DATA_ERROR: -+ printf("data error!\n"); -+ break; -+ default: -+ printf("unknown error %d!\n", res); -+ } -+ halt(); -+ } else { -+ printf("done!\n"); -+ } -+ -+ flush_cache(kernel_la, lzma_outsize); -+ -+ printf("Starting kernel at %08x...\n\n", kernel_la); -+ -+#ifdef CONFIG_KERNEL_CMDLINE -+ reg_a0 = kernel_argc; -+ reg_a1 = (unsigned long) kernel_argv; -+ reg_a2 = 0; -+ reg_a3 = 0; -+#endif -+ -+ kernel_entry = (void *) kernel_la; -+ kernel_entry(reg_a0, reg_a1, reg_a2, reg_a3); -+} -diff --git a/target/linux/ar71xx/image/lzma-loader/src/loader.lds b/target/linux/ar71xx/image/lzma-loader/src/loader.lds -new file mode 100644 -index 0000000000..01ff852361 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/loader.lds -@@ -0,0 +1,34 @@ -+OUTPUT_ARCH(mips) -+SECTIONS { -+ .text : { -+ _code_start = .; -+ *(.text) -+ *(.text.*) -+ *(.rodata) -+ *(.rodata.*) -+ *(.data.lzma) -+ } -+ -+ . = ALIGN(32); -+ .data : { -+ *(.data) -+ *(.data.*) -+ } -+ -+ . = ALIGN(32); -+ _code_end = .; -+ -+ _bss_start = .; -+ .bss : { -+ *(.bss) -+ *(.bss.*) -+ } -+ -+ . = ALIGN(32); -+ _bss_end = .; -+ -+ . = . + 8192; -+ _stack = .; -+ -+ workspace = .; -+} -diff --git a/target/linux/ar71xx/image/lzma-loader/src/loader2.lds b/target/linux/ar71xx/image/lzma-loader/src/loader2.lds -new file mode 100644 -index 0000000000..db0bb46424 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/loader2.lds -@@ -0,0 +1,10 @@ -+OUTPUT_ARCH(mips) -+SECTIONS { -+ .text : { -+ startup = .; -+ *(.text) -+ *(.text.*) -+ *(.data) -+ *(.data.*) -+ } -+} -diff --git a/target/linux/ar71xx/image/lzma-loader/src/lzma-data.lds b/target/linux/ar71xx/image/lzma-loader/src/lzma-data.lds -new file mode 100644 -index 0000000000..abf756ba13 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/lzma-data.lds -@@ -0,0 +1,8 @@ -+OUTPUT_ARCH(mips) -+SECTIONS { -+ .data.lzma : { -+ _lzma_data_start = .; -+ *(.data) -+ _lzma_data_end = .; -+ } -+} -diff --git a/target/linux/ar71xx/image/lzma-loader/src/printf.c b/target/linux/ar71xx/image/lzma-loader/src/printf.c -new file mode 100644 -index 0000000000..7bb5a86e18 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/printf.c -@@ -0,0 +1,350 @@ -+/* -+ * Copyright (C) 2001 MontaVista Software Inc. -+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ */ -+ -+#include "printf.h" -+ -+extern void board_putc(int ch); -+ -+/* this is the maximum width for a variable */ -+#define LP_MAX_BUF 256 -+ -+/* macros */ -+#define IsDigit(x) ( ((x) >= '0') && ((x) <= '9') ) -+#define Ctod(x) ( (x) - '0') -+ -+/* forward declaration */ -+static int PrintChar(char *, char, int, int); -+static int PrintString(char *, char *, int, int); -+static int PrintNum(char *, unsigned long, int, int, int, int, char, int); -+ -+/* private variable */ -+static const char theFatalMsg[] = "fatal error in lp_Print!"; -+ -+/* -*- -+ * A low level printf() function. -+ */ -+static void -+lp_Print(void (*output)(void *, char *, int), -+ void * arg, -+ char *fmt, -+ va_list ap) -+{ -+ -+#define OUTPUT(arg, s, l) \ -+ { if (((l) < 0) || ((l) > LP_MAX_BUF)) { \ -+ (*output)(arg, (char*)theFatalMsg, sizeof(theFatalMsg)-1); for(;;); \ -+ } else { \ -+ (*output)(arg, s, l); \ -+ } \ -+ } -+ -+ char buf[LP_MAX_BUF]; -+ -+ char c; -+ char *s; -+ long int num; -+ -+ int longFlag; -+ int negFlag; -+ int width; -+ int prec; -+ int ladjust; -+ char padc; -+ -+ int length; -+ -+ for(;;) { -+ { -+ /* scan for the next '%' */ -+ char *fmtStart = fmt; -+ while ( (*fmt != '\0') && (*fmt != '%')) { -+ fmt ++; -+ } -+ -+ /* flush the string found so far */ -+ OUTPUT(arg, fmtStart, fmt-fmtStart); -+ -+ /* are we hitting the end? */ -+ if (*fmt == '\0') break; -+ } -+ -+ /* we found a '%' */ -+ fmt ++; -+ -+ /* check for long */ -+ if (*fmt == 'l') { -+ longFlag = 1; -+ fmt ++; -+ } else { -+ longFlag = 0; -+ } -+ -+ /* check for other prefixes */ -+ width = 0; -+ prec = -1; -+ ladjust = 0; -+ padc = ' '; -+ -+ if (*fmt == '-') { -+ ladjust = 1; -+ fmt ++; -+ } -+ -+ if (*fmt == '0') { -+ padc = '0'; -+ fmt++; -+ } -+ -+ if (IsDigit(*fmt)) { -+ while (IsDigit(*fmt)) { -+ width = 10 * width + Ctod(*fmt++); -+ } -+ } -+ -+ if (*fmt == '.') { -+ fmt ++; -+ if (IsDigit(*fmt)) { -+ prec = 0; -+ while (IsDigit(*fmt)) { -+ prec = prec*10 + Ctod(*fmt++); -+ } -+ } -+ } -+ -+ -+ /* check format flag */ -+ negFlag = 0; -+ switch (*fmt) { -+ case 'b': -+ if (longFlag) { -+ num = va_arg(ap, long int); -+ } else { -+ num = va_arg(ap, int); -+ } -+ length = PrintNum(buf, num, 2, 0, width, ladjust, padc, 0); -+ OUTPUT(arg, buf, length); -+ break; -+ -+ case 'd': -+ case 'D': -+ if (longFlag) { -+ num = va_arg(ap, long int); -+ } else { -+ num = va_arg(ap, int); -+ } -+ if (num < 0) { -+ num = - num; -+ negFlag = 1; -+ } -+ length = PrintNum(buf, num, 10, negFlag, width, ladjust, padc, 0); -+ OUTPUT(arg, buf, length); -+ break; -+ -+ case 'o': -+ case 'O': -+ if (longFlag) { -+ num = va_arg(ap, long int); -+ } else { -+ num = va_arg(ap, int); -+ } -+ length = PrintNum(buf, num, 8, 0, width, ladjust, padc, 0); -+ OUTPUT(arg, buf, length); -+ break; -+ -+ case 'u': -+ case 'U': -+ if (longFlag) { -+ num = va_arg(ap, long int); -+ } else { -+ num = va_arg(ap, int); -+ } -+ length = PrintNum(buf, num, 10, 0, width, ladjust, padc, 0); -+ OUTPUT(arg, buf, length); -+ break; -+ -+ case 'x': -+ if (longFlag) { -+ num = va_arg(ap, long int); -+ } else { -+ num = va_arg(ap, int); -+ } -+ length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 0); -+ OUTPUT(arg, buf, length); -+ break; -+ -+ case 'X': -+ if (longFlag) { -+ num = va_arg(ap, long int); -+ } else { -+ num = va_arg(ap, int); -+ } -+ length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 1); -+ OUTPUT(arg, buf, length); -+ break; -+ -+ case 'c': -+ c = (char)va_arg(ap, int); -+ length = PrintChar(buf, c, width, ladjust); -+ OUTPUT(arg, buf, length); -+ break; -+ -+ case 's': -+ s = (char*)va_arg(ap, char *); -+ length = PrintString(buf, s, width, ladjust); -+ OUTPUT(arg, buf, length); -+ break; -+ -+ case '\0': -+ fmt --; -+ break; -+ -+ default: -+ /* output this char as it is */ -+ OUTPUT(arg, fmt, 1); -+ } /* switch (*fmt) */ -+ -+ fmt ++; -+ } /* for(;;) */ -+ -+ /* special termination call */ -+ OUTPUT(arg, "\0", 1); -+} -+ -+ -+/* --------------- local help functions --------------------- */ -+static int -+PrintChar(char * buf, char c, int length, int ladjust) -+{ -+ int i; -+ -+ if (length < 1) length = 1; -+ if (ladjust) { -+ *buf = c; -+ for (i=1; i< length; i++) buf[i] = ' '; -+ } else { -+ for (i=0; i< length-1; i++) buf[i] = ' '; -+ buf[length - 1] = c; -+ } -+ return length; -+} -+ -+static int -+PrintString(char * buf, char* s, int length, int ladjust) -+{ -+ int i; -+ int len=0; -+ char* s1 = s; -+ while (*s1++) len++; -+ if (length < len) length = len; -+ -+ if (ladjust) { -+ for (i=0; i< len; i++) buf[i] = s[i]; -+ for (i=len; i< length; i++) buf[i] = ' '; -+ } else { -+ for (i=0; i< length-len; i++) buf[i] = ' '; -+ for (i=length-len; i < length; i++) buf[i] = s[i-length+len]; -+ } -+ return length; -+} -+ -+static int -+PrintNum(char * buf, unsigned long u, int base, int negFlag, -+ int length, int ladjust, char padc, int upcase) -+{ -+ /* algorithm : -+ * 1. prints the number from left to right in reverse form. -+ * 2. fill the remaining spaces with padc if length is longer than -+ * the actual length -+ * TRICKY : if left adjusted, no "0" padding. -+ * if negtive, insert "0" padding between "0" and number. -+ * 3. if (!ladjust) we reverse the whole string including paddings -+ * 4. otherwise we only reverse the actual string representing the num. -+ */ -+ -+ int actualLength =0; -+ char *p = buf; -+ int i; -+ -+ do { -+ int tmp = u %base; -+ if (tmp <= 9) { -+ *p++ = '0' + tmp; -+ } else if (upcase) { -+ *p++ = 'A' + tmp - 10; -+ } else { -+ *p++ = 'a' + tmp - 10; -+ } -+ u /= base; -+ } while (u != 0); -+ -+ if (negFlag) { -+ *p++ = '-'; -+ } -+ -+ /* figure out actual length and adjust the maximum length */ -+ actualLength = p - buf; -+ if (length < actualLength) length = actualLength; -+ -+ /* add padding */ -+ if (ladjust) { -+ padc = ' '; -+ } -+ if (negFlag && !ladjust && (padc == '0')) { -+ for (i = actualLength-1; i< length-1; i++) buf[i] = padc; -+ buf[length -1] = '-'; -+ } else { -+ for (i = actualLength; i< length; i++) buf[i] = padc; -+ } -+ -+ -+ /* prepare to reverse the string */ -+ { -+ int begin = 0; -+ int end; -+ if (ladjust) { -+ end = actualLength - 1; -+ } else { -+ end = length -1; -+ } -+ -+ while (end > begin) { -+ char tmp = buf[begin]; -+ buf[begin] = buf[end]; -+ buf[end] = tmp; -+ begin ++; -+ end --; -+ } -+ } -+ -+ /* adjust the string pointer */ -+ return length; -+} -+ -+static void printf_output(void *arg, char *s, int l) -+{ -+ int i; -+ -+ // special termination call -+ if ((l==1) && (s[0] == '\0')) return; -+ -+ for (i=0; i< l; i++) { -+ board_putc(s[i]); -+ if (s[i] == '\n') board_putc('\r'); -+ } -+} -+ -+void printf(char *fmt, ...) -+{ -+ va_list ap; -+ va_start(ap, fmt); -+ lp_Print(printf_output, 0, fmt, ap); -+ va_end(ap); -+} -diff --git a/target/linux/ar71xx/image/lzma-loader/src/printf.h b/target/linux/ar71xx/image/lzma-loader/src/printf.h -new file mode 100644 -index 0000000000..9b1c1df232 ---- /dev/null -+++ b/target/linux/ar71xx/image/lzma-loader/src/printf.h -@@ -0,0 +1,18 @@ -+/* -+ * Copyright (C) 2001 MontaVista Software Inc. -+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef _printf_h_ -+#define _printf_h_ -+ -+#include -+void printf(char *fmt, ...); -+ -+#endif /* _printf_h_ */ -diff --git a/target/linux/ar71xx/image/mikrotik.mk b/target/linux/ar71xx/image/mikrotik.mk -new file mode 100644 -index 0000000000..871f4c5352 ---- /dev/null -+++ b/target/linux/ar71xx/image/mikrotik.mk -@@ -0,0 +1,61 @@ -+define Device/mikrotik -+ PROFILES := Default -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARD_NAME := routerboard -+ LOADER_TYPE := elf -+ KERNEL_NAME := vmlinux.bin.lzma -+ KERNEL := kernel-bin | loader-kernel -+ KERNEL_INITRAMFS_NAME := vmlinux-initramfs.bin.lzma -+ MIKROTIK_CHUNKSIZE := -+ IMAGE/sysupgrade.bin/squashfs := -+endef -+DEVICE_VARS += MIKROTIK_CHUNKSIZE -+ -+define Device/mikrotik-nand -+ $(Device/mikrotik) -+ IMAGE/sysupgrade.bin/squashfs = append-kernel | \ -+ kernel2minor -s $$(MIKROTIK_CHUNKSIZE) -e -c | sysupgrade-tar kernel=$$$$@ -+endef -+ -+define Device/nand-64m -+ $(Device/mikrotik-nand) -+ MIKROTIK_CHUNKSIZE := 512 -+ DEVICE_TITLE := MikroTik RouterBoard (64 MB NAND) -+endef -+TARGET_DEVICES += nand-64m -+ -+define Device/nand-large -+ $(Device/mikrotik-nand) -+ MIKROTIK_CHUNKSIZE := 2048 -+ DEVICE_TITLE := MikroTik RouterBoard (>= 128 MB NAND) -+endef -+TARGET_DEVICES += nand-large -+ -+define Device/nand-large-ac -+ $(Device/mikrotik-nand) -+ MIKROTIK_CHUNKSIZE := 2048 -+ DEVICE_TITLE := MikroTik RouterBoard (>= 128 MB NAND, 802.11ac) -+ DEVICE_PACKAGES += kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ SUPPORTED_DEVICES := rb-921gs-5hpacd-r2 rb-922uags-5hpacd -+endef -+TARGET_DEVICES += nand-large-ac -+ -+define Device/rb-nor-flash-16M -+ $(Device/mikrotik) -+ DEVICE_TITLE := MikroTik RouterBoard (16 MB SPI NOR) -+ DEVICE_PACKAGES := rssileds -nand-utils kmod-ledtrig-gpio -+ IMAGE_SIZE := 16000k -+ KERNEL_INSTALL := 1 -+ SUPPORTED_DEVICES := rb-750-r2 rb-750up-r2 rb-750p-pbr2 rb-911-2hn rb-911-5hn rb-931-2nd rb-941-2nd rb-951ui-2nd rb-952ui-5ac2nd rb-962uigs-5hact2hnt rb-lhg-5nd rb-map-2nd rb-mapl-2nd rb-wap-2nd rb-wapr-2nd rb-sxt-2nd-r3 -+ IMAGE/sysupgrade.bin := append-kernel | kernel2minor -s 1024 -e | pad-to $$$$(BLOCKSIZE) | \ -+ append-rootfs | pad-rootfs | append-metadata | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += rb-nor-flash-16M -+ -+define Device/rb-nor-flash-16M-ac -+ $(Device/rb-nor-flash-16M) -+ DEVICE_TITLE := MikroTik RouterBoard (16 MB SPI NOR, 802.11ac) -+ DEVICE_PACKAGES += kmod-ath10k-ct-smallbuffers ath10k-firmware-qca988x-ct ath10k-firmware-qca9887-ct kmod-usb-ehci -+ SUPPORTED_DEVICES += rb-wapg-5hact2hnd -+endef -+TARGET_DEVICES += rb-nor-flash-16M-ac -diff --git a/target/linux/ar71xx/image/nand.mk b/target/linux/ar71xx/image/nand.mk -new file mode 100644 -index 0000000000..8cf2e98234 ---- /dev/null -+++ b/target/linux/ar71xx/image/nand.mk -@@ -0,0 +1,137 @@ -+define Build/MerakiNAND -+ -$(STAGING_DIR_HOST)/bin/mkmerakifw \ -+ -B $(BOARDNAME) -s \ -+ -i $@ \ -+ -o $@.new -+ @mv $@.new $@ -+endef -+ -+define Build/MerakiNAND-old -+ -$(STAGING_DIR_HOST)/bin/mkmerakifw-old \ -+ -B $(BOARDNAME) -s \ -+ -i $@ \ -+ -o $@.new -+ @mv $@.new $@ -+endef -+ -+ -+define Device/c-60 -+ DEVICE_TITLE := AirTight C-60 -+ DEVICE_PACKAGES := kmod-spi-gpio kmod-usb2 kmod-ath9k -+ BOARDNAME := C-60 -+ BLOCKSIZE := 64k -+ KERNEL_SIZE := 3648k -+ IMAGE_SIZE := 32m -+ IMAGES := sysupgrade.tar -+ MTDPARTS := spi0.0:256k(u-boot)ro,128k(u-boot-env)ro,3648k(kernel),64k(art)ro;ar934x-nfc:32m(ubi) -+ KERNEL := kernel-bin | patch-cmdline | lzma | uImage lzma -+ IMAGE/sysupgrade.tar := sysupgrade-tar -+endef -+TARGET_DEVICES += c-60 -+ -+define Device/domywifi-dw33d -+ DEVICE_TITLE := DomyWifi DW33D -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage kmod-usb-ledtrig-usbport kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ BOARDNAME := DW33D -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,14528k(rootfs),1472k(kernel),64k(art)ro,16000k@0x50000(firmware);ar934x-nfc:96m(rootfs_data),32m(backup)ro -+ IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | pad-to 14528k | append-kernel | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += domywifi-dw33d -+ -+define Device/hiveap-121 -+ DEVICE_TITLE := Aerohive HiveAP-121 -+ DEVICE_PACKAGES := kmod-usb2 kmod-i2c-gpio-custom kmod-spi-gpio kmod-ath9k kmod-tpm-i2c-atmel -+ BOARDNAME := HiveAP-121 -+ BLOCKSIZE := 128k -+ PAGESIZE := 2048 -+ IMAGE_SIZE := 115m -+ KERNEL_SIZE := 5120k -+ UBINIZE_OPTS := -E 5 -+ CONSOLE := ttyS0,9600 -+ MTDPARTS := spi0.0:512k(u-boot)ro,64k(u-boot-env),64k(hw-info)ro,64k(boot-info)ro,64k(boot-sinfo)ro;ar934x-nfc:4096k(u-boot-1),4096k(u-boot-env-1),5m(kernel),111m(ubi),4096k(wifi-info)ro -+ IMAGES := sysupgrade.tar factory.bin -+ KERNEL := kernel-bin | patch-cmdline | lzma | uImage lzma -+ IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi | check-size $$$$(IMAGE_SIZE) -+ IMAGE/sysupgrade.tar := sysupgrade-tar -+endef -+TARGET_DEVICES += hiveap-121 -+ -+define Device/mr18 -+ DEVICE_TITLE := Meraki MR18 -+ DEVICE_PACKAGES := kmod-spi-gpio kmod-ath9k -+ BOARDNAME := MR18 -+ BLOCKSIZE := 64k -+ MTDPARTS := ar934x-nfc:512k(nandloader)ro,8M(kernel),8M(recovery),113664k(ubi),128k@130944k(odm-caldata)ro -+ IMAGES := sysupgrade.tar -+ KERNEL := kernel-bin | patch-cmdline | MerakiNAND -+ KERNEL_INITRAMFS := kernel-bin | patch-cmdline | MerakiNAND -+ IMAGE/sysupgrade.tar := sysupgrade-tar -+endef -+TARGET_DEVICES += mr18 -+ -+define Device/rambutan -+ DEVICE_TITLE := 8devices Rambutan -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := RAMBUTAN -+ BLOCKSIZE := 128KiB -+ MTDPARTS := ar934x-nfc:3M(u-boot)ro,2M(u-boot-env),1M(art),122M(ubi) -+ PAGESIZE := 2048 -+ KERNEL_IN_UBI := 1 -+ IMAGES := factory.ubi sysupgrade.tar -+ IMAGE/sysupgrade.tar := sysupgrade-tar -+ IMAGE/factory.ubi := append-ubi -+endef -+TARGET_DEVICES += rambutan -+ -+define Device/wi2a-ac200i -+ SUPPORTED_DEVICES = $(1) -+ DEVICE_TITLE := Nokia WI2A-AC200i -+ DEVICE_PACKAGES := kmod-usb2 kmod-ath9k kmod-ath10k-ct ath10k-firmware-qca988x-ct -+ BOARDNAME := WI2A-AC200i -+ BLOCKSIZE := 64k -+ KERNEL_SIZE := 3648k -+ IMAGE_SIZE := 32m -+ IMAGES := sysupgrade.tar -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(envFacA)ro,64k(envFacB)ro,64k(ART)ro,128k(u-boot-env) -+ KERNEL := kernel-bin | patch-cmdline | lzma | uImage lzma -+ IMAGE/sysupgrade.tar := sysupgrade-tar | append-metadata -+endef -+TARGET_DEVICES += wi2a-ac200i -+ -+define Device/z1 -+ DEVICE_TITLE := Meraki Z1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-spi-gpio kmod-ath9k kmod-owl-loader -+ BOARDNAME := Z1 -+ BLOCKSIZE := 64k -+ MTDPARTS := ar934x-nfc:128K(loader1)ro,8064K(kernel),128K(loader2)ro,8064K(recovery),114560K(ubi),128K(origcaldata)ro -+ IMAGES := sysupgrade.tar -+ KERNEL := kernel-bin | patch-cmdline | MerakiNAND-old -+ KERNEL_INITRAMFS := kernel-bin | patch-cmdline | MerakiNAND-old -+ IMAGE/sysupgrade.tar := sysupgrade-tar -+endef -+TARGET_DEVICES += z1 -+ -+define LegacyDevice/R6100 -+ DEVICE_TITLE := NETGEAR R6100 -+ DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca988x-ct kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += R6100 -+ -+define LegacyDevice/WNDR3700V4 -+ DEVICE_TITLE := NETGEAR WNDR3700v4 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += WNDR3700V4 -+ -+define LegacyDevice/WNDR4300V1 -+ DEVICE_TITLE := NETGEAR WNDR4300v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += WNDR4300V1 -+ -+define LegacyDevice/NBG6716 -+ DEVICE_TITLE := Zyxel NBG 6716 -+ DEVICE_PACKAGES := kmod-rtc-pcf8563 kmod-ath10k-ct ath10k-firmware-qca988x-ct -+endef -+LEGACY_DEVICES += NBG6716 -diff --git a/target/linux/ar71xx/image/tiny-legacy-devices.mk b/target/linux/ar71xx/image/tiny-legacy-devices.mk -new file mode 100644 -index 0000000000..7f63d19de0 ---- /dev/null -+++ b/target/linux/ar71xx/image/tiny-legacy-devices.mk -@@ -0,0 +1,161 @@ -+define LegacyDevice/F9K1115V2 -+ DEVICE_TITLE := Belkin AC1750DB (F9K1115V2) -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb3 kmod-usb-ledtrig-usbport \ -+ kmod-ath10k-ct ath10k-firmware-qca988x-ct -+endef -+LEGACY_DEVICES += F9K1115V2 -+ -+define LegacyDevice/DIR600A1 -+ DEVICE_TITLE := D-Link DIR-600 rev. A1 -+endef -+LEGACY_DEVICES += DIR600A1 -+ -+define LegacyDevice/DIR601A1 -+ DEVICE_TITLE := D-Link DIR-601 rev. A1 -+endef -+LEGACY_DEVICES += DIR601A1 -+ -+define LegacyDevice/FR54RTR -+ DEVICE_TITLE := Frys FR-54RTR -+endef -+LEGACY_DEVICES += FR54RTR -+ -+define LegacyDevice/EBR2310C1 -+ DEVICE_TITLE := D-Link EBR-2310 rev. C1 -+endef -+LEGACY_DEVICES += EBR2310C1 -+ -+define LegacyDevice/DIR615E1 -+ DEVICE_TITLE := D-Link DIR-615 rev. E1 -+endef -+LEGACY_DEVICES += DIR615E1 -+ -+define LegacyDevice/DIR615E4 -+ DEVICE_TITLE := D-Link DIR-615 rev. E4 -+endef -+LEGACY_DEVICES += DIR615E4 -+ -+define LegacyDevice/DIR615I1 -+ DEVICE_TITLE := D-Link DIR-615 rev. I1 -+endef -+LEGACY_DEVICES += DIR615I1 -+ -+define LegacyDevice/DIR615I3 -+ DEVICE_TITLE := D-Link DIR-615 rev. I3 -+endef -+LEGACY_DEVICES += DIR615I3 -+ -+define LegacyDevice/A02RBW300N -+ DEVICE_TITLE := Atlantis-Land A02-RB-W300N -+endef -+LEGACY_DEVICES += A02RBW300N -+ -+define LegacyDevice/DIR615C1 -+ DEVICE_TITLE := D-Link DIR-615 rev. C1 -+endef -+LEGACY_DEVICES += DIR615C1 -+ -+define LegacyDevice/TEW632BRP -+ DEVICE_TITLE := TRENDNet TEW-632BRP -+endef -+LEGACY_DEVICES += TEW632BRP -+ -+define LegacyDevice/TEW652BRP_FW -+ DEVICE_TITLE := TRENDNet TEW-652BRP -+endef -+LEGACY_DEVICES += TEW652BRP_FW -+ -+define LegacyDevice/TEW652BRP_RECOVERY -+ DEVICE_TITLE := TRENDNet TEW-652BRP (recovery) -+endef -+LEGACY_DEVICES += TEW652BRP_RECOVERY -+ -+define LegacyDevice/TEW712BR -+ DEVICE_TITLE := TRENDNet TEW-712BR -+endef -+LEGACY_DEVICES += TEW712BR -+ -+define LegacyDevice/DIR601B1 -+ DEVICE_TITLE := D-Link DIR-601 rev. B1 -+endef -+LEGACY_DEVICES += DIR601B1 -+ -+define LegacyDevice/WP543_4M -+ DEVICE_TITLE := Compex WP543/WPJ543 (4MB flash) -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 -+endef -+LEGACY_DEVICES += WP543_4M -+ -+define LegacyDevice/WPE72_4M -+ DEVICE_TITLE := Compex WPE72/WPE72NX (4MB flash) -+ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 -+endef -+LEGACY_DEVICES += WPE72_4M -+ -+define LegacyDevice/WNR2000 -+ DEVICE_TITLE := NETGEAR WNR2000V1 -+endef -+LEGACY_DEVICES += WNR2000 -+ -+define LegacyDevice/WNR2000V3 -+ DEVICE_TITLE := NETGEAR WNR2000V3 -+endef -+LEGACY_DEVICES += WNR2000V3 -+ -+define LegacyDevice/WNR2000V4 -+ DEVICE_TITLE := NETGEAR WNR2000V4 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+endef -+LEGACY_DEVICES += WNR2000V4 -+ -+define LegacyDevice/REALWNR612V2 -+ DEVICE_TITLE := NETGEAR WNR612V2 -+endef -+LEGACY_DEVICES += REALWNR612V2 -+ -+define LegacyDevice/N150R -+ DEVICE_TITLE := On Networks N150 -+endef -+LEGACY_DEVICES += N150R -+ -+define LegacyDevice/REALWNR1000V2 -+ DEVICE_TITLE := NETGEAR WNR1000V2 -+endef -+LEGACY_DEVICES += REALWNR1000V2 -+ -+define LegacyDevice/WNR1000V2_VC -+ DEVICE_TITLE := NETGEAR WNR1000V2-VC -+endef -+LEGACY_DEVICES += WNR1000V2_VC -+ -+define LegacyDevice/WPN824N -+ DEVICE_TITLE := NETGEAR WPN824N -+endef -+LEGACY_DEVICES += WPN824N -+ -+define LegacyDevice/WHRG301N -+ DEVICE_TITLE := Buffalo WHR-G301N -+endef -+LEGACY_DEVICES += WHRG301N -+ -+define LegacyDevice/WHRHPG300N -+ DEVICE_TITLE := Buffalo WHR-HP-G300N -+endef -+LEGACY_DEVICES += WHRHPG300N -+ -+define LegacyDevice/WHRHPGN -+ DEVICE_TITLE := Buffalo WHR-HP-GN -+endef -+LEGACY_DEVICES += WHRHPGN -+ -+define LegacyDevice/WLAEAG300N -+ DEVICE_TITLE := Buffalo WLAE-AG300N -+ DEVICE_PACKAGES := kmod-ledtrig-netdev -+endef -+LEGACY_DEVICES += WLAEAG300N -+ -+define LegacyDevice/NBG_460N_550N_550NH -+ DEVICE_TITLE := ZyXEL NBG 460N/550N/550NH -+ DEVICE_PACKAGES := kmod-rtc-pcf8563 -+endef -+LEGACY_DEVICES += NBG_460N_550N_550NH -diff --git a/target/linux/ar71xx/image/tiny-senao.mk b/target/linux/ar71xx/image/tiny-senao.mk -new file mode 100644 -index 0000000000..3a7f6776b3 ---- /dev/null -+++ b/target/linux/ar71xx/image/tiny-senao.mk -@@ -0,0 +1,28 @@ -+define Build/senao-factory-image -+ mkdir -p $@.senao -+ -+ touch $@.senao/FWINFO-OpenWrt-$(REVISION)-$(1) -+ $(CP) $(IMAGE_KERNEL) $@.senao/openwrt-senao-$(1)-uImage-lzma.bin -+ $(CP) $@ $@.senao/openwrt-senao-$(1)-root.squashfs -+ -+ $(TAR) -c \ -+ --numeric-owner --owner=0 --group=0 --sort=name \ -+ $(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \ -+ -C $@.senao . | gzip -9nc > $@ -+ -+ rm -rf $@.senao -+endef -+ -+ -+define Device/ens202ext -+ DEVICE_TITLE := EnGenius ENS202EXT -+ BOARDNAME := ENS202EXT -+ DEVICE_PACKAGES := rssileds -+ KERNEL_SIZE := 1536k -+ IMAGE_SIZE := 13632k -+ IMAGES += factory.bin -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env),320k(custom)ro,1536k(kernel),12096k(rootfs),2048k(failsafe)ro,64k(art)ro,13632k@0xa0000(firmware) -+ IMAGE/factory.bin := append-rootfs | pad-rootfs | senao-factory-image ens202ext -+ IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | check-size $$$$(IMAGE_SIZE) -+endef -+TARGET_DEVICES += ens202ext -diff --git a/target/linux/ar71xx/image/tiny-tp-link.mk b/target/linux/ar71xx/image/tiny-tp-link.mk -new file mode 100644 -index 0000000000..5874808d21 ---- /dev/null -+++ b/target/linux/ar71xx/image/tiny-tp-link.mk -@@ -0,0 +1,695 @@ -+include ./common-tp-link.mk -+ -+ -+define Device/tl-mr10u-v1 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-MR10U v1 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := TL-MR10U -+ DEVICE_PROFILE := TLMR10U -+ TPLINK_HWID := 0x00100101 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += tl-mr10u-v1 -+ -+define Device/tl-mr11u-v1 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-MR11U v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-MR11U -+ DEVICE_PROFILE := TLMR11U -+ TPLINK_HWID := 0x00110101 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += tl-mr11u-v1 -+ -+define Device/tl-mr11u-v2 -+ $(Device/tl-mr11u-v1) -+ DEVICE_TITLE := TP-LINK TL-MR11U v2 -+ TPLINK_HWID := 0x00110102 -+endef -+TARGET_DEVICES += tl-mr11u-v2 -+ -+define Device/tl-mr12u-v1 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-MR12U v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-MR13U -+ DEVICE_PROFILE := TLMR12U -+ TPLINK_HWID := 0x00120101 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += tl-mr12u-v1 -+ -+define Device/tl-mr13u-v1 -+ $(Device/tl-mr12u-v1) -+ DEVICE_TITLE := TP-LINK TL-MR13U v1 -+ DEVICE_PROFILE := TLMR13U -+ TPLINK_HWID := 0x00130101 -+endef -+TARGET_DEVICES += tl-mr13u-v1 -+ -+define Device/tl-mr3020-v1 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-MR3020 v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-MR3020 -+ DEVICE_PROFILE := TLMR3020 -+ TPLINK_HWID := 0x30200001 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += tl-mr3020-v1 -+ -+define Device/tl-mr3040-v1 -+ $(Device/tl-mr3020-v1) -+ DEVICE_TITLE := TP-LINK TL-MR3040 v1 -+ BOARDNAME := TL-MR3040 -+ DEVICE_PROFILE := TLMR3040 -+ TPLINK_HWID := 0x30400001 -+endef -+TARGET_DEVICES += tl-mr3040-v1 -+ -+define Device/tl-mr3040-v2 -+ $(Device/tl-mr3040-v1) -+ DEVICE_TITLE := TP-LINK TL-MR3040 v2 -+ BOARDNAME := TL-MR3040-v2 -+ TPLINK_HWID := 0x30400002 -+endef -+TARGET_DEVICES += tl-mr3040-v2 -+ -+define Device/tl-mr3220-v1 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-MR3220 v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-MR3220 -+ DEVICE_PROFILE := TLMR3220 -+ TPLINK_HWID := 0x32200001 -+endef -+TARGET_DEVICES += tl-mr3220-v1 -+ -+define Device/tl-mr3220-v2 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-MR3220 v2 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-MR3220-v2 -+ DEVICE_PROFILE := TLMR3220 -+ TPLINK_HWID := 0x32200002 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += tl-mr3220-v2 -+ -+define Device/tl-mr3420-v1 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-MR3420 v1 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-MR3420 -+ DEVICE_PROFILE := TLMR3420 -+ TPLINK_HWID := 0x34200001 -+endef -+TARGET_DEVICES += tl-mr3420-v1 -+ -+define Device/tl-mr3420-v2 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-MR3420 v2 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-MR3420-v2 -+ DEVICE_PROFILE := TLMR3420 -+ TPLINK_HWID := 0x34200002 -+endef -+TARGET_DEVICES += tl-mr3420-v2 -+ -+define Device/tl-wa701nd-v1 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-WA701N/ND v1 -+ BOARDNAME := TL-WA901ND -+ DEVICE_PROFILE := TLWA701 -+ TPLINK_HWID := 0x07010001 -+endef -+TARGET_DEVICES += tl-wa701nd-v1 -+ -+define Device/tl-wa701nd-v2 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WA701N/ND v2 -+ BOARDNAME := TL-WA701ND-v2 -+ DEVICE_PROFILE := TLWA701 -+ TPLINK_HWID := 0x07010002 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += tl-wa701nd-v2 -+ -+define Device/tl-wa7210n-v2 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WA7210N v2 -+ DEVICE_PACKAGES := rssileds kmod-ledtrig-netdev -+ BOARDNAME := TL-WA7210N-v2 -+ DEVICE_PROFILE := TLWA7210 -+ TPLINK_HWID := 0x72100002 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += tl-wa7210n-v2 -+ -+define Device/tl-wa730re-v1 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-WA730RE v1 -+ BOARDNAME := TL-WA901ND -+ DEVICE_PROFILE := TLWA730RE -+ TPLINK_HWID := 0x07300001 -+endef -+TARGET_DEVICES += tl-wa730re-v1 -+ -+define Device/tl-wa750re-v1 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WA750RE v1 -+ DEVICE_PACKAGES := rssileds -+ BOARDNAME := TL-WA750RE -+ DEVICE_PROFILE := TLWA750 -+ TPLINK_HWID := 0x07500001 -+endef -+TARGET_DEVICES += tl-wa750re-v1 -+ -+define Device/tl-wa7510n-v1 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-WA7510N v1 -+ BOARDNAME := TL-WA7510N -+ DEVICE_PROFILE := TLWA7510 -+ TPLINK_HWID := 0x75100001 -+endef -+TARGET_DEVICES += tl-wa7510n-v1 -+ -+define Device/tl-wa801nd-v1 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-WA801N/ND v1 -+ BOARDNAME := TL-WA901ND -+ DEVICE_PROFILE := TLWA801 -+ TPLINK_HWID := 0x08010001 -+endef -+TARGET_DEVICES += tl-wa801nd-v1 -+ -+define Device/tl-wa801nd-v2 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WA801N/ND v2 -+ BOARDNAME := TL-WA801ND-v2 -+ DEVICE_PROFILE := TLWA801 -+ TPLINK_HWID := 0x08010002 -+endef -+TARGET_DEVICES += tl-wa801nd-v2 -+ -+define Device/tl-wa801nd-v3 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WA801N/ND v3 -+ BOARDNAME := TL-WA801ND-v3 -+ DEVICE_PROFILE := TLWA801 -+ TPLINK_HWID := 0x08010003 -+endef -+TARGET_DEVICES += tl-wa801nd-v3 -+ -+define Device/tl-wa801nd-v4 -+ $(Device/tl-wa801nd-v3) -+ DEVICE_TITLE := TP-LINK TL-WA801N/ND v4 -+ TPLINK_HWID := 0x08010004 -+endef -+TARGET_DEVICES += tl-wa801nd-v4 -+ -+define Device/tl-wa830re-v1 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-WA830RE v1 -+ BOARDNAME := TL-WA901ND -+ DEVICE_PROFILE := TLWA830 -+ TPLINK_HWID := 0x08300010 -+endef -+TARGET_DEVICES += tl-wa830re-v1 -+ -+define Device/tl-wa830re-v2 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WA830RE v2 -+ BOARDNAME := TL-WA830RE-v2 -+ DEVICE_PROFILE := TLWA830 -+ TPLINK_HWID := 0x08300002 -+endef -+TARGET_DEVICES += tl-wa830re-v2 -+ -+define Device/tl-wa850re-v1 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WA850RE v1 -+ DEVICE_PACKAGES := rssileds -+ BOARDNAME := TL-WA850RE -+ DEVICE_PROFILE := TLWA850 -+ TPLINK_HWID := 0x08500001 -+endef -+TARGET_DEVICES += tl-wa850re-v1 -+ -+define Device/tl-wa850re-v2 -+ $(Device/tplink-safeloader) -+ DEVICE_TITLE := TP-LINK TL-WA850RE v2 -+ DEVICE_PACKAGES := rssileds -+ BOARDNAME := TL-WA850RE-V2 -+ DEVICE_PROFILE := TLWA850 -+ TPLINK_BOARD_ID := TLWA850REV2 -+ TPLINK_HWID := 0x08500002 -+ TPLINK_HWREV := 0 -+ IMAGE_SIZE := 3648k -+ MTDPARTS := spi0.0:128k(u-boot)ro,3648k(firmware),256k(config)ro,64k(art)ro -+endef -+TARGET_DEVICES += tl-wa850re-v2 -+ -+define Device/tl-wa855re-v1 -+ $(Device/tplink-safeloader) -+ DEVICE_TITLE := TP-LINK TL-WA855RE v1 -+ BOARDNAME := TL-WA855RE-v1 -+ DEVICE_PROFILE := TLWA855RE -+ TPLINK_HWID := 0x08550001 -+ TPLINK_BOARD_ID := TLWA855REV1 -+ TPLINK_HWREV := 0 -+ IMAGE_SIZE := 3648k -+ MTDPARTS := spi0.0:128k(u-boot)ro,1344k(kernel),2304k(rootfs),256k(config)ro,64k(art)ro,3648k@0x20000(firmware) -+endef -+TARGET_DEVICES += tl-wa855re-v1 -+ -+define Device/tl-wa860re-v1 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WA860RE v1 -+ BOARDNAME := TL-WA860RE -+ DEVICE_PROFILE := TLWA860 -+ TPLINK_HWID := 0x08600001 -+endef -+TARGET_DEVICES += tl-wa860re-v1 -+ -+define Device/tl-wa901nd-v1 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-WA901N/ND v1 -+ BOARDNAME := TL-WA901ND -+ DEVICE_PROFILE := TLWA901 -+ TPLINK_HWID := 0x09010001 -+endef -+TARGET_DEVICES += tl-wa901nd-v1 -+ -+define Device/tl-wa901nd-v2 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-WA901N/ND v2 -+ BOARDNAME := TL-WA901ND-v2 -+ DEVICE_PROFILE := TLWA901 -+ TPLINK_HWID := 0x09010002 -+endef -+TARGET_DEVICES += tl-wa901nd-v2 -+ -+define Device/tl-wa901nd-v3 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WA901N/ND v3 -+ BOARDNAME := TL-WA901ND-v3 -+ DEVICE_PROFILE := TLWA901 -+ TPLINK_HWID := 0x09010003 -+endef -+TARGET_DEVICES += tl-wa901nd-v3 -+ -+define Device/tl-wa901nd-v4 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WA901N/ND v4 -+ BOARDNAME := TL-WA901ND-v4 -+ DEVICE_PROFILE := TLWA901 -+ TPLINK_HWID := 0x09010004 -+ IMAGE/factory.bin := append-rootfs | mktplinkfw factory -C EU -+endef -+TARGET_DEVICES += tl-wa901nd-v4 -+ -+define Device/tl-wa901nd-v5 -+ $(Device/tl-wa901nd-v4) -+ DEVICE_TITLE := TP-LINK TL-WA901N/ND v5 -+ BOARDNAME := TL-WA901ND-v5 -+ TPLINK_HWID := 0x09010005 -+endef -+TARGET_DEVICES += tl-wa901nd-v5 -+ -+define Device/tl-wdr3320-v2 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WDR3320 v2 -+ DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport -+ BOARDNAME := TL-WDR3320-v2 -+ DEVICE_PROFILE := TLWDR3320V2 -+ TPLINK_HWID := 0x33200002 -+ TPLINK_HEADER_VERSION := 2 -+endef -+TARGET_DEVICES += tl-wdr3320-v2 -+ -+define Device/tl-wr1041n-v2 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR1041N v2 -+ BOARDNAME := TL-WR1041N-v2 -+ DEVICE_PROFILE := TLWR1041 -+ TPLINK_HWID := 0x10410002 -+endef -+TARGET_DEVICES += tl-wr1041n-v2 -+ -+define Device/tl-wr703n-v1 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR703N v1 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := TL-WR703N -+ DEVICE_PROFILE := TLWR703 -+ TPLINK_HWID := 0x07030101 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += tl-wr703n-v1 -+ -+define Device/tl-wr710n-v2 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR710N v2 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := TL-WR710N -+ DEVICE_PROFILE := TLWR710 -+ TPLINK_HWID := 0x07100002 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += tl-wr710n-v2 -+ -+define Device/tl-wr720n-v3 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR720N v3 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := TL-WR720N-v3 -+ DEVICE_PROFILE := TLWR720 -+ TPLINK_HWID := 0x07200103 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += tl-wr720n-v3 -+ -+define Device/tl-wr720n-v4 -+ $(Device/tl-wr720n-v3) -+ DEVICE_TITLE := TP-LINK TL-WR720N v4 -+ TPLINK_HWID := 0x07200104 -+endef -+TARGET_DEVICES += tl-wr720n-v4 -+ -+define Device/tl-wr740n-v1 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-WR740N/ND v1 -+ BOARDNAME := TL-WR741ND -+ DEVICE_PROFILE := TLWR740 -+ TPLINK_HWID := 0x07400001 -+endef -+TARGET_DEVICES += tl-wr740n-v1 -+ -+define Device/tl-wr740n-v3 -+ $(Device/tl-wr740n-v1) -+ DEVICE_TITLE := TP-LINK TL-WR740N/ND v3 -+ TPLINK_HWID := 0x07400003 -+endef -+TARGET_DEVICES += tl-wr740n-v3 -+ -+define Device/tl-wr740n-v4 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR740N/ND v4 -+ BOARDNAME := TL-WR741ND-v4 -+ DEVICE_PROFILE := TLWR740 -+ TPLINK_HWID := 0x07400004 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += tl-wr740n-v4 -+ -+define Device/tl-wr740n-v5 -+ $(Device/tl-wr740n-v4) -+ DEVICE_TITLE := TP-LINK TL-WR740N/ND v5 -+ TPLINK_HWID := 0x07400005 -+endef -+TARGET_DEVICES += tl-wr740n-v5 -+ -+define Device/tl-wr740n-v6 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR740N/ND v6 -+ BOARDNAME := TL-WR740N-v6 -+ DEVICE_PROFILE := TLWR740 -+ TPLINK_HWID := 0x07400006 -+endef -+TARGET_DEVICES += tl-wr740n-v6 -+ -+define Device/tl-wr741nd-v1 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-WR741N/ND v1 -+ BOARDNAME := TL-WR741ND -+ DEVICE_PROFILE := TLWR741 -+ TPLINK_HWID := 0x07410001 -+endef -+TARGET_DEVICES += tl-wr741nd-v1 -+ -+define Device/tl-wr741nd-v2 -+ $(Device/tl-wr741nd-v1) -+ DEVICE_TITLE := TP-LINK TL-WR741N/ND v2 -+endef -+TARGET_DEVICES += tl-wr741nd-v2 -+ -+define Device/tl-wr741nd-v4 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR741N/ND v4 -+ BOARDNAME := TL-WR741ND-v4 -+ DEVICE_PROFILE := TLWR741 -+ TPLINK_HWID := 0x07410004 -+ CONSOLE := ttyATH0,115200 -+endef -+TARGET_DEVICES += tl-wr741nd-v4 -+ -+define Device/tl-wr741nd-v5 -+ $(Device/tl-wr741nd-v4) -+ DEVICE_TITLE := TP-LINK TL-WR741N/ND v5 -+ TPLINK_HWID := 0x07400005 -+endef -+TARGET_DEVICES += tl-wr741nd-v5 -+ -+define Device/tl-wr743nd-v1 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-WR743N/ND v1 -+ BOARDNAME := TL-WR741ND -+ DEVICE_PROFILE := TLWR743 -+ TPLINK_HWID := 0x07430001 -+endef -+TARGET_DEVICES += tl-wr743nd-v1 -+ -+define Device/tl-wr743nd-v2 -+ $(Device/tl-wr741nd-v4) -+ DEVICE_TITLE := TP-LINK TL-WR743N/ND v2 -+ DEVICE_PROFILE := TLWR743 -+ TPLINK_HWID := 0x07430002 -+endef -+TARGET_DEVICES += tl-wr743nd-v2 -+ -+define Device/tl-wr802n-v1 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR802N v1 -+ BOARDNAME := TL-WR802N-v1 -+ DEVICE_PROFILE := TLWR802 -+ TPLINK_HWID := 0x08020001 -+ TPLINK_HWREV := 1 -+endef -+TARGET_DEVICES += tl-wr802n-v1 -+ -+define Device/tl-wr802n-v2 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR802N v2 -+ BOARDNAME := TL-WR802N-v2 -+ DEVICE_PROFILE := TLWR802 -+ TPLINK_HWID := 0x08020002 -+ TPLINK_HWREV := 2 -+ IMAGES += factory-us.bin factory-eu.bin -+ IMAGE/factory-us.bin := append-rootfs | mktplinkfw factory -C US -+ IMAGE/factory-eu.bin := append-rootfs | mktplinkfw factory -C EU -+endef -+TARGET_DEVICES += tl-wr802n-v2 -+ -+define Device/tl-wr840n-v2 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR840N v2 -+ BOARDNAME := TL-WR840N-v2 -+ DEVICE_PROFILE := TLWR840 -+ TPLINK_HWID := 0x08400002 -+ IMAGES += factory-eu.bin -+ IMAGE/factory-eu.bin := append-rootfs | mktplinkfw factory -C EU -+endef -+TARGET_DEVICES += tl-wr840n-v2 -+ -+define Device/tl-wr840n-v3 -+ $(Device/tl-wr840n-v2) -+ DEVICE_TITLE := TP-LINK TL-WR840N v3 -+ BOARDNAME := TL-WR840N-v3 -+ TPLINK_HWID := 0x08400003 -+endef -+TARGET_DEVICES += tl-wr840n-v3 -+ -+define Device/tl-wr841-v1.5 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-WR841N/ND v1.5 -+ BOARDNAME := TL-WR841N-v1.5 -+ DEVICE_PROFILE := TLWR841 -+ TPLINK_HWID := 0x08410002 -+ TPLINK_HWREV := 2 -+endef -+TARGET_DEVICES += tl-wr841-v1.5 -+ -+define Device/tl-wr841-v3 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-WR841N/ND v3 -+ BOARDNAME := TL-WR941ND -+ DEVICE_PROFILE := TLWR841 -+ TPLINK_HWID := 0x08410003 -+ TPLINK_HWREV := 3 -+endef -+TARGET_DEVICES += tl-wr841-v3 -+ -+define Device/tl-wr841-v5 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-WR841N/ND v5 -+ BOARDNAME := TL-WR741ND -+ DEVICE_PROFILE := TLWR841 -+ TPLINK_HWID := 0x08410005 -+endef -+TARGET_DEVICES += tl-wr841-v5 -+ -+define Device/tl-wr841-v7 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-WR841N/ND v7 -+ BOARDNAME := TL-WR841N-v7 -+ DEVICE_PROFILE := TLWR841 -+ TPLINK_HWID := 0x08410007 -+endef -+TARGET_DEVICES += tl-wr841-v7 -+ -+define Device/tl-wr841-v8 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR841N/ND v8 -+ BOARDNAME := TL-WR841N-v8 -+ DEVICE_PROFILE := TLWR841 -+ TPLINK_HWID := 0x08410008 -+endef -+TARGET_DEVICES += tl-wr841-v8 -+ -+define Device/tl-wr841-v9 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR841N/ND v9 -+ BOARDNAME := TL-WR841N-v9 -+ DEVICE_PROFILE := TLWR841 -+ TPLINK_HWID := 0x08410009 -+endef -+TARGET_DEVICES += tl-wr841-v9 -+ -+define Device/tl-wr841-v10 -+ $(Device/tl-wr841-v9) -+ DEVICE_TITLE := TP-LINK TL-WR841N/ND v10 -+ TPLINK_HWID := 0x08410010 -+endef -+TARGET_DEVICES += tl-wr841-v10 -+ -+define Device/tl-wr841-v11 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR841N/ND v11 -+ BOARDNAME := TL-WR841N-v11 -+ DEVICE_PROFILE := TLWR841 -+ TPLINK_HWID := 0x08410011 -+ IMAGES += factory-us.bin factory-eu.bin -+ IMAGE/factory-us.bin := append-rootfs | mktplinkfw factory -C US -+ IMAGE/factory-eu.bin := append-rootfs | mktplinkfw factory -C EU -+endef -+TARGET_DEVICES += tl-wr841-v11 -+ -+define Device/tl-wr841-v12 -+ $(Device/tl-wr841-v11) -+ DEVICE_TITLE := TP-LINK TL-WR841N/ND v12 -+ TPLINK_HWID := 0x08410012 -+endef -+TARGET_DEVICES += tl-wr841-v12 -+ -+define Device/tl-wr843nd-v1 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR843N/ND v1 -+ BOARDNAME := TL-WR841N-v8 -+ DEVICE_PROFILE := TLWR843 -+ TPLINK_HWID := 0x08430001 -+endef -+TARGET_DEVICES += tl-wr843nd-v1 -+ -+define Device/tl-wr847n-v8 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR847N/ND v8 -+ BOARDNAME := TL-WR841N-v8 -+ DEVICE_PROFILE := TLWR841 -+ TPLINK_HWID := 0x08470008 -+endef -+TARGET_DEVICES += tl-wr847n-v8 -+ -+define Device/tl-wr940n-v4 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR940N v4 -+ BOARDNAME := TL-WR940N-v4 -+ DEVICE_PROFILE := TLWR941 -+ TPLINK_HWID := 0x09400004 -+ IMAGES += factory-us.bin factory-eu.bin factory-br.bin -+ IMAGE/factory-us.bin := append-rootfs | mktplinkfw factory -C US -+ IMAGE/factory-eu.bin := append-rootfs | mktplinkfw factory -C EU -+ IMAGE/factory-br.bin := append-rootfs | mktplinkfw factory -C BR -+endef -+TARGET_DEVICES += tl-wr940n-v4 -+ -+define Device/tl-wr940n-v6 -+ $(Device/tl-wr940n-v4) -+ DEVICE_TITLE := TP-LINK TL-WR940N v6 -+ BOARDNAME := TL-WR940N-v6 -+ TPLINK_HWID := 0x09400006 -+endef -+TARGET_DEVICES += tl-wr940n-v6 -+ -+define Device/tl-wr941nd-v2 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-WR941N/ND v2 -+ BOARDNAME := TL-WR941ND -+ DEVICE_PROFILE := TLWR941 -+ TPLINK_HWID := 0x09410002 -+ TPLINK_HWREV := 2 -+endef -+TARGET_DEVICES += tl-wr941nd-v2 -+ -+define Device/tl-wr941nd-v3 -+ $(Device/tl-wr941nd-v2) -+ DEVICE_TITLE := TP-LINK TL-WR941N/ND v3 -+endef -+TARGET_DEVICES += tl-wr941nd-v3 -+ -+define Device/rnx-n360rt -+ $(Device/tl-wr941nd-v2) -+ DEVICE_TITLE := Rosewill RNX-N360RT -+ DEVICE_PROFILE := RNXN360RT -+ TPLINK_HWREV := 0x00420001 -+endef -+TARGET_DEVICES += rnx-n360rt -+ -+define Device/tl-wr941nd-v4 -+ $(Device/tplink-4m) -+ DEVICE_TITLE := TP-LINK TL-WR941N/ND v4 -+ BOARDNAME := TL-WR741ND -+ DEVICE_PROFILE := TLWR941 -+ TPLINK_HWID := 0x09410004 -+endef -+TARGET_DEVICES += tl-wr941nd-v4 -+ -+define Device/tl-wr941nd-v5 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR941N/ND v5 -+ BOARDNAME := TL-WR941ND-v5 -+ DEVICE_PROFILE := TLWR941 -+ TPLINK_HWID := 0x09410005 -+endef -+TARGET_DEVICES += tl-wr941nd-v5 -+ -+define Device/tl-wr941nd-v6 -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR941N/ND v6 -+ BOARDNAME := TL-WR941ND-v6 -+ DEVICE_PROFILE := TLWR941 -+ TPLINK_HWID := 0x09410006 -+endef -+TARGET_DEVICES += tl-wr941nd-v6 -+ -+# Chinese version (unlike European) is similar to the TL-WDR3500 -+define Device/tl-wr941nd-v6-cn -+ $(Device/tplink-4mlzma) -+ DEVICE_TITLE := TP-LINK TL-WR941N/ND v6 (CN) -+ BOARDNAME := TL-WDR3500 -+ DEVICE_PROFILE := TLWR941 -+ TPLINK_HWID := 0x09410006 -+endef -+TARGET_DEVICES += tl-wr941nd-v6-cn -diff --git a/target/linux/ar71xx/image/tiny.mk b/target/linux/ar71xx/image/tiny.mk -new file mode 100644 -index 0000000000..f89d9df83c ---- /dev/null -+++ b/target/linux/ar71xx/image/tiny.mk -@@ -0,0 +1,31 @@ -+define Build/mkbuffaloimg -+ $(STAGING_DIR_HOST)/bin/mkbuffaloimg -B $(BOARDNAME) \ -+ -R $$(($(subst k, * 1024,$(ROOTFS_SIZE)))) \ -+ -K $$(($(subst k, * 1024,$(KERNEL_SIZE)))) \ -+ -i $@ -o $@.new -+ mv $@.new $@ -+endef -+ -+ -+define Device/bhr-4grv2 -+ DEVICE_TITLE := Buffalo BHR-4GRV2 -+ BOARDNAME := BHR-4GRV2 -+ ROOTFS_SIZE := 14528k -+ KERNEL_SIZE := 1472k -+ IMAGE_SIZE := 16000k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,14528k(rootfs),1472k(kernel),64k(art)ro,16000k@0x50000(firmware) -+ IMAGES := sysupgrade.bin factory.bin -+ IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | pad-to $$$$(ROOTFS_SIZE) | append-kernel | check-size $$$$(IMAGE_SIZE) -+ IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | mkbuffaloimg -+endef -+ -+define Device/zbt-we1526 -+ DEVICE_TITLE := Zbtlink ZBT-WE1526 -+ DEVICE_PACKAGES := kmod-usb2 -+ BOARDNAME := ZBT-WE1526 -+ IMAGE_SIZE := 16000k -+ KERNEL_SIZE := 1472k -+ ROOTFS_SIZE := 14528k -+ MTDPARTS := spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,14528k(rootfs),1472k(kernel),64k(art)ro,16000k@0x50000(firmware) -+ IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | pad-to $$$$(ROOTFS_SIZE) | append-kernel | check-size $$$$(IMAGE_SIZE) -+endef -diff --git a/target/linux/ar71xx/image/ubinize-nbg6716.ini b/target/linux/ar71xx/image/ubinize-nbg6716.ini -new file mode 100644 -index 0000000000..814b0fbcc8 ---- /dev/null -+++ b/target/linux/ar71xx/image/ubinize-nbg6716.ini -@@ -0,0 +1,24 @@ -+[rootfs] -+# Volume mode (other option is static) -+mode=ubi -+# Source image -+image=ubi_root.img -+# Volume ID in UBI image -+vol_id=0 -+# Allow for dynamic resize -+vol_type=dynamic -+# Volume name -+vol_name=rootfs -+ -+[rootfs_data] -+# Volume mode (other option is static) -+mode=ubi -+# Volume ID in UBI image -+vol_id=1 -+# Allow for dynamic resize -+vol_type=dynamic -+# Volume name -+vol_name=rootfs_data -+# Autoresize volume at first mount -+vol_size=1MiB -+vol_flags=autoresize -diff --git a/target/linux/ar71xx/image/ubinize-wndr4300.ini b/target/linux/ar71xx/image/ubinize-wndr4300.ini -new file mode 100644 -index 0000000000..5bff906ae8 ---- /dev/null -+++ b/target/linux/ar71xx/image/ubinize-wndr4300.ini -@@ -0,0 +1,26 @@ -+[rootfs] -+# Volume mode (other option is static) -+mode=ubi -+# Source image -+image=root.squashfs -+# Volume ID in UBI image -+vol_id=0 -+# Allow for dynamic resize -+vol_type=dynamic -+# Volume name -+vol_name=rootfs -+# Autoresize volume at first mount -+# vol_flags=autoresize -+ -+[rootfs_data] -+# Volume mode (other option is static) -+mode=ubi -+# Volume ID in UBI image -+vol_id=1 -+# Allow for dynamic resize -+vol_type=dynamic -+# Volume name -+vol_name=rootfs_data -+# Autoresize volume at first mount -+vol_flags=autoresize -+vol_size=1MiB -diff --git a/target/linux/ar71xx/mikrotik/config-default b/target/linux/ar71xx/mikrotik/config-default -new file mode 100644 -index 0000000000..eb2f362034 ---- /dev/null -+++ b/target/linux/ar71xx/mikrotik/config-default -@@ -0,0 +1,79 @@ -+CONFIG_ATH79_DEV_AP9X_PCI=y -+CONFIG_ATH79_DEV_ETH=y -+CONFIG_ATH79_DEV_GPIO_BUTTONS=y -+CONFIG_ATH79_DEV_LEDS_GPIO=y -+CONFIG_ATH79_DEV_M25P80=y -+CONFIG_ATH79_DEV_NFC=y -+CONFIG_ATH79_DEV_SPI=y -+CONFIG_ATH79_DEV_USB=y -+CONFIG_ATH79_DEV_WMAC=y -+CONFIG_ATH79_MACH_RB2011=y -+CONFIG_ATH79_MACH_RB4XX=y -+CONFIG_ATH79_MACH_RB750=y -+CONFIG_ATH79_MACH_RB91X=y -+CONFIG_ATH79_MACH_RB922=y -+CONFIG_ATH79_MACH_RB95X=y -+CONFIG_ATH79_MACH_RBSPI=y -+CONFIG_ATH79_MACH_RBSXTLITE=y -+CONFIG_ATH79_PCI_ATH9K_FIXUP=y -+CONFIG_ATH79_ROUTERBOOT=y -+CONFIG_BLK_MQ_PCI=y -+CONFIG_CRC16=y -+CONFIG_CRYPTO_DEFLATE=y -+CONFIG_GPIO_LATCH=y -+CONFIG_HW_HAS_PCI=y -+# CONFIG_INTEL_XWAY_PHY is not set -+CONFIG_LEDS_RB750=y -+CONFIG_LZO_DECOMPRESS=y -+# CONFIG_MARVELL_PHY is not set -+CONFIG_MIKROTIK=y -+CONFIG_MIKROTIK_RB_SYSFS=y -+# CONFIG_MTD_CFI is not set -+CONFIG_MTD_CFI_I2=y -+# CONFIG_MTD_CMDLINE_PARTS is not set -+# CONFIG_MTD_CYBERTAN_PARTS is not set -+CONFIG_MTD_MAP_BANK_WIDTH_1=y -+CONFIG_MTD_MAP_BANK_WIDTH_4=y -+# CONFIG_MTD_MYLOADER_PARTS is not set -+CONFIG_MTD_NAND=y -+CONFIG_MTD_NAND_AR934X=y -+CONFIG_MTD_NAND_ECC=y -+CONFIG_MTD_NAND_RB4XX=y -+CONFIG_MTD_NAND_RB750=y -+CONFIG_MTD_NAND_RB91X=y -+# CONFIG_MTD_REDBOOT_PARTS is not set -+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y -+# CONFIG_MTD_SPLIT_EVA_FW is not set -+# CONFIG_MTD_SPLIT_LZMA_FW is not set -+# CONFIG_MTD_SPLIT_SEAMA_FW is not set -+# CONFIG_MTD_SPLIT_TPLINK_FW is not set -+# CONFIG_MTD_SPLIT_UIMAGE_FW is not set -+# CONFIG_MTD_SPLIT_WRGG_FW is not set -+# CONFIG_MTD_TPLINK_PARTS is not set -+CONFIG_MTD_UBI=y -+CONFIG_MTD_UBI_BEB_LIMIT=20 -+CONFIG_MTD_UBI_BLOCK=y -+# CONFIG_MTD_UBI_FASTMAP is not set -+# CONFIG_MTD_UBI_GLUEBI is not set -+CONFIG_MTD_UBI_WL_THRESHOLD=4096 -+# CONFIG_NET_DSA is not set -+CONFIG_PCI=y -+CONFIG_PCI_AR724X=y -+CONFIG_PCI_DISABLE_COMMON_QUIRKS=y -+CONFIG_PCI_DOMAINS=y -+CONFIG_RLE_DECOMPRESS=y -+# CONFIG_RTL8306_PHY is not set -+# CONFIG_RTL8366_SMI is not set -+CONFIG_SOC_AR71XX=y -+CONFIG_SOC_AR724X=y -+CONFIG_SOC_AR934X=y -+CONFIG_SOC_QCA953X=y -+CONFIG_SOC_QCA955X=y -+CONFIG_SPI_RB4XX=y -+CONFIG_SPI_RB4XX_CPLD=y -+CONFIG_UBIFS_FS=y -+CONFIG_UBIFS_FS_ADVANCED_COMPR=y -+# CONFIG_UBIFS_FS_LZO is not set -+CONFIG_UBIFS_FS_ZLIB=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_ZLIB_INFLATE=y -diff --git a/target/linux/ar71xx/mikrotik/profiles/00-default.mk b/target/linux/ar71xx/mikrotik/profiles/00-default.mk -new file mode 100644 -index 0000000000..1dfc62dbb3 ---- /dev/null -+++ b/target/linux/ar71xx/mikrotik/profiles/00-default.mk -@@ -0,0 +1,18 @@ -+# -+# Copyright (C) 2009 OpenWrt.org -+# -+# This is free software, licensed under the GNU General Public License v2. -+# See /LICENSE for more information. -+# -+ -+define Profile/Default -+ NAME:=Default Profile -+ PACKAGES:= \ -+ kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport nand-utils -+ PRIORITY := 1 -+endef -+ -+define Profile/Default/Description -+ Default package set compatible with most boards. -+endef -+$(eval $(call Profile,Default)) -diff --git a/target/linux/ar71xx/mikrotik/target.mk b/target/linux/ar71xx/mikrotik/target.mk -new file mode 100644 -index 0000000000..5ae57fadb3 ---- /dev/null -+++ b/target/linux/ar71xx/mikrotik/target.mk -@@ -0,0 +1,11 @@ -+BOARDNAME:=Mikrotik devices with NAND/NOR flash -+FEATURES += squashfs ramdisk minor nand -+ -+DEFAULT_PACKAGES += nand-utils wpad-basic -+ -+define Target/Description -+ Build firmware images for Atheros AR71xx/AR913x based Mikrotik boards. -+ e.g. MikroTik RB-4xx or RB-750 -+endef -+ -+ -diff --git a/target/linux/ar71xx/modules.mk b/target/linux/ar71xx/modules.mk -new file mode 100644 -index 0000000000..9ead8b451c ---- /dev/null -+++ b/target/linux/ar71xx/modules.mk -@@ -0,0 +1,69 @@ -+# -+# Copyright (C) 2006-2011 OpenWrt.org -+# -+# This is free software, licensed under the GNU General Public License v2. -+# See /LICENSE for more information. -+# -+ -+define KernelPackage/leds-nu801 -+ SUBMENU:=$(LEDS_MENU) -+ TITLE:=Meraki MR18 LED support -+ DEPENDS:=@TARGET_ar71xx -+ KCONFIG:=CONFIG_LEDS_NU801 -+ FILES:=$(LINUX_DIR)/drivers/leds/leds-nu801.ko -+ AUTOLOAD:=$(call AutoLoad,60,leds-nu801) -+endef -+ -+define KernelPackage/leds-nu801/description -+ Kernel module for the nu801 LED driver used on the Meraki MR18. -+endef -+ -+$(eval $(call KernelPackage,leds-nu801)) -+ -+ -+define KernelPackage/leds-rb750 -+ SUBMENU:=$(LEDS_MENU) -+ TITLE:=RouterBOARD 750 LED support -+ DEPENDS:=@TARGET_ar71xx -+ KCONFIG:=CONFIG_LEDS_RB750 -+ FILES:=$(LINUX_DIR)/drivers/leds/leds-rb750.ko -+ AUTOLOAD:=$(call AutoLoad,60,leds-rb750) -+endef -+ -+define KernelPackage/leds-rb750/description -+ Kernel module for the LEDs on the MikroTik RouterBOARD 750. -+endef -+ -+$(eval $(call KernelPackage,leds-rb750)) -+ -+ -+define KernelPackage/leds-wndr3700-usb -+ SUBMENU:=$(LEDS_MENU) -+ TITLE:=WNDR3700 USB LED support -+ DEPENDS:=@TARGET_ar71xx -+ KCONFIG:=CONFIG_LEDS_WNDR3700_USB -+ FILES:=$(LINUX_DIR)/drivers/leds/leds-wndr3700-usb.ko -+ AUTOLOAD:=$(call AutoLoad,60,leds-wndr3700-usb) -+endef -+ -+define KernelPackage/leds-wndr3700-usb/description -+ Kernel module for the USB LED on the NETGEAR WNDR3700 board. -+endef -+ -+$(eval $(call KernelPackage,leds-wndr3700-usb)) -+ -+ -+define KernelPackage/spi-vsc7385 -+ SUBMENU:=$(SPI_MENU) -+ TITLE:=Vitesse VSC7385 ethernet switch driver -+ DEPENDS:=@TARGET_ar71xx -+ KCONFIG:=CONFIG_SPI_VSC7385 -+ FILES:=$(LINUX_DIR)/drivers/spi/spi-vsc7385.ko -+ AUTOLOAD:=$(call AutoLoad,93,spi-vsc7385) -+endef -+ -+define KernelPackage/spi-vsc7385/description -+ This package contains the SPI driver for the Vitesse VSC7385 ethernet switch. -+endef -+ -+$(eval $(call KernelPackage,spi-vsc7385)) -diff --git a/target/linux/ar71xx/nand/config-default b/target/linux/ar71xx/nand/config-default -new file mode 100644 -index 0000000000..39b1ca4995 ---- /dev/null -+++ b/target/linux/ar71xx/nand/config-default -@@ -0,0 +1,70 @@ -+CONFIG_ATH79_DEV_AP9X_PCI=y -+CONFIG_ATH79_DEV_ETH=y -+CONFIG_ATH79_DEV_GPIO_BUTTONS=y -+CONFIG_ATH79_DEV_LEDS_GPIO=y -+CONFIG_ATH79_DEV_M25P80=y -+CONFIG_ATH79_DEV_NFC=y -+CONFIG_ATH79_DEV_SPI=y -+CONFIG_ATH79_DEV_USB=y -+CONFIG_ATH79_DEV_WMAC=y -+CONFIG_ATH79_MACH_C60=y -+CONFIG_ATH79_MACH_DOMYWIFI_DW33D=y -+CONFIG_ATH79_MACH_HIVEAP_121=y -+CONFIG_ATH79_MACH_MR18=y -+CONFIG_ATH79_MACH_NBG6716=y -+CONFIG_ATH79_MACH_R6100=y -+CONFIG_ATH79_MACH_RAMBUTAN=y -+CONFIG_ATH79_MACH_WI2A_AC200I=y -+CONFIG_ATH79_MACH_WNDR4300=y -+CONFIG_ATH79_MACH_Z1=y -+CONFIG_ATH79_NVRAM=y -+CONFIG_ATH79_PCI_ATH9K_FIXUP=y -+CONFIG_BCH=y -+CONFIG_BLK_MQ_PCI=y -+CONFIG_CRC16=y -+CONFIG_CRYPTO_DEFLATE=y -+CONFIG_CRYPTO_LZO=y -+CONFIG_HW_HAS_PCI=y -+# CONFIG_INTEL_XWAY_PHY is not set -+# CONFIG_IP17XX_PHY is not set -+CONFIG_LEDS_NU801=y -+CONFIG_LZO_COMPRESS=y -+CONFIG_LZO_DECOMPRESS=y -+# CONFIG_MARVELL_PHY is not set -+# CONFIG_MICREL_PHY is not set -+# CONFIG_MTD_CFI is not set -+CONFIG_MTD_CFI_I2=y -+CONFIG_MTD_MAP_BANK_WIDTH_1=y -+CONFIG_MTD_MAP_BANK_WIDTH_4=y -+# CONFIG_MTD_MYLOADER_PARTS is not set -+CONFIG_MTD_NAND=y -+CONFIG_MTD_NAND_AR934X=y -+CONFIG_MTD_NAND_AR934X_HW_ECC=y -+CONFIG_MTD_NAND_BCH=y -+CONFIG_MTD_NAND_ECC=y -+CONFIG_MTD_NAND_ECC_BCH=y -+# CONFIG_MTD_REDBOOT_PARTS is not set -+# CONFIG_MTD_SPLIT_EVA_FW is not set -+# CONFIG_MTD_SPLIT_SEAMA_FW is not set -+# CONFIG_MTD_SPLIT_TPLINK_FW is not set -+# CONFIG_MTD_TPLINK_PARTS is not set -+CONFIG_MTD_UBI=y -+CONFIG_MTD_UBI_BEB_LIMIT=20 -+CONFIG_MTD_UBI_BLOCK=y -+# CONFIG_MTD_UBI_FASTMAP is not set -+# CONFIG_MTD_UBI_GLUEBI is not set -+CONFIG_MTD_UBI_WL_THRESHOLD=4096 -+CONFIG_PCI=y -+CONFIG_PCI_AR724X=y -+CONFIG_PCI_DISABLE_COMMON_QUIRKS=y -+CONFIG_PCI_DOMAINS=y -+# CONFIG_RTL8306_PHY is not set -+# CONFIG_RTL8366_SMI is not set -+CONFIG_SOC_AR934X=y -+CONFIG_SOC_QCA955X=y -+CONFIG_UBIFS_FS=y -+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -+CONFIG_UBIFS_FS_LZO=y -+CONFIG_UBIFS_FS_ZLIB=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_ZLIB_INFLATE=y -diff --git a/target/linux/ar71xx/nand/profiles/00-default.mk b/target/linux/ar71xx/nand/profiles/00-default.mk -new file mode 100644 -index 0000000000..6e618113a5 ---- /dev/null -+++ b/target/linux/ar71xx/nand/profiles/00-default.mk -@@ -0,0 +1,18 @@ -+# -+# Copyright (C) 2009 OpenWrt.org -+# -+# This is free software, licensed under the GNU General Public License v2. -+# See /LICENSE for more information. -+# -+ -+define Profile/Default -+ NAME:=Default Profile -+ PACKAGES:= \ -+ kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport -+ PRIORITY := 1 -+endef -+ -+define Profile/Default/Description -+ Default package set compatible with most boards. -+endef -+$(eval $(call Profile,Default)) -diff --git a/target/linux/ar71xx/nand/target.mk b/target/linux/ar71xx/nand/target.mk -new file mode 100644 -index 0000000000..d5191b2260 ---- /dev/null -+++ b/target/linux/ar71xx/nand/target.mk -@@ -0,0 +1,9 @@ -+BOARDNAME := Generic devices with NAND flash -+FEATURES += squashfs nand rtc -+ -+DEFAULT_PACKAGES += wpad-basic -+ -+define Target/Description -+ Build firmware images for Atheros AR71xx/AR913x based boards with -+ NAND flash, e.g. Netgear WNDR4300. -+endef -diff --git a/target/linux/ar71xx/patches-4.14/001-spi-cs-gpio.patch b/target/linux/ar71xx/patches-4.14/001-spi-cs-gpio.patch -new file mode 100644 -index 0000000000..7a0b669e43 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/001-spi-cs-gpio.patch -@@ -0,0 +1,20 @@ -+--- a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h -++++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h -+@@ -14,6 +14,7 @@ -+ struct ath79_spi_platform_data { -+ unsigned bus_num; -+ unsigned num_chipselect; -++ int *cs_gpios; -+ }; -+ -+ #endif /* _ATH79_SPI_PLATFORM_H */ -+--- a/drivers/spi/spi-ath79.c -++++ b/drivers/spi/spi-ath79.c -+@@ -231,6 +231,7 @@ static int ath79_spi_probe(struct platfo -+ if (pdata) { -+ master->bus_num = pdata->bus_num; -+ master->num_chipselect = pdata->num_chipselect; -++ master->cs_gpios = pdata->cs_gpios; -+ } -+ -+ sp->bitbang.master = master; -diff --git a/target/linux/ar71xx/patches-4.14/002-add_back_gpio_function_select.patch b/target/linux/ar71xx/patches-4.14/002-add_back_gpio_function_select.patch -new file mode 100644 -index 0000000000..5b26a640eb ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/002-add_back_gpio_function_select.patch -@@ -0,0 +1,92 @@ -+--- /dev/null -++++ b/arch/mips/ath79/gpio.c -+@@ -0,0 +1,59 @@ -++/* -++ * Atheros AR71XX/AR724X/AR913X GPIO API support -++ * -++ * Copyright (C) 2010-2011 Jaiganesh Narayanan -++ * Copyright (C) 2008-2011 Gabor Juhos -++ * Copyright (C) 2008 Imre Kaloz -++ * -++ * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP -++ * -++ * This program is free software; you can redistribute it and/or modify it -++ * under the terms of the GNU General Public License version 2 as published -++ * by the Free Software Foundation. -++ */ -++#include -++#include -++#include -++#include -++#include -++#include -++#include "common.h" -++ -++void __iomem *ath79_gpio_base; -++EXPORT_SYMBOL_GPL(ath79_gpio_base); -++ -++static void __iomem *ath79_gpio_get_function_reg(void) -++{ -++ u32 reg = 0; -++ -++ if (soc_is_ar71xx() || -++ soc_is_ar724x() || -++ soc_is_ar913x() || -++ soc_is_ar933x()) -++ reg = AR71XX_GPIO_REG_FUNC; -++ else if (soc_is_ar934x()) -++ reg = AR934X_GPIO_REG_FUNC; -++ else -++ BUG(); -++ -++ return ath79_gpio_base + reg; -++} -++ -++void ath79_gpio_function_setup(u32 set, u32 clear) -++{ -++ void __iomem *reg = ath79_gpio_get_function_reg(); -++ -++ __raw_writel((__raw_readl(reg) & ~clear) | set, reg); -++ /* flush write */ -++ __raw_readl(reg); -++} -++ -++void ath79_gpio_function_enable(u32 mask) -++{ -++ ath79_gpio_function_setup(mask, 0); -++} -++ -++void ath79_gpio_function_disable(u32 mask) -++{ -++ ath79_gpio_function_setup(0, mask); -++} -+--- a/arch/mips/include/asm/mach-ath79/ath79.h -++++ b/arch/mips/include/asm/mach-ath79/ath79.h -+@@ -118,6 +118,7 @@ static inline int soc_is_qca955x(void) -+ void ath79_ddr_wb_flush(unsigned int reg); -+ void ath79_ddr_set_pci_windows(void); -+ -++extern void __iomem *ath79_gpio_base; -+ extern void __iomem *ath79_pll_base; -+ extern void __iomem *ath79_reset_base; -+ -+--- a/arch/mips/ath79/dev-common.c -++++ b/arch/mips/ath79/dev-common.c -+@@ -156,4 +156,5 @@ void __init ath79_gpio_init(void) -+ } -+ -+ platform_device_register(&ath79_gpio_device); -++ ath79_gpio_base = ioremap(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); -+ } -+--- a/arch/mips/ath79/common.h -++++ b/arch/mips/ath79/common.h -+@@ -24,6 +24,9 @@ unsigned long ath79_get_sys_clk_rate(con -+ -+ void ath79_ddr_ctrl_init(void); -+ -++void ath79_gpio_function_enable(u32 mask); -++void ath79_gpio_function_disable(u32 mask); -++void ath79_gpio_function_setup(u32 set, u32 clear); -+ void ath79_gpio_init(void); -+ -+ #endif /* __ATH79_COMMON_H */ -diff --git a/target/linux/ar71xx/patches-4.14/004-register_gpio_driver_earlier.patch b/target/linux/ar71xx/patches-4.14/004-register_gpio_driver_earlier.patch -new file mode 100644 -index 0000000000..cc30e2d91e ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/004-register_gpio_driver_earlier.patch -@@ -0,0 +1,18 @@ -+HACK: register the GPIO driver earlier to ensure that gpio_request calls -+from mach files succeed. -+ -+--- a/drivers/gpio/gpio-ath79.c -++++ b/drivers/gpio/gpio-ath79.c -+@@ -322,7 +322,11 @@ static struct platform_driver ath79_gpio -+ .remove = ath79_gpio_remove, -+ }; -+ -+-module_platform_driver(ath79_gpio_driver); -++static int __init ath79_gpio_init(void) -++{ -++ return platform_driver_register(&ath79_gpio_driver); -++} -++postcore_initcall(ath79_gpio_init); -+ -+ MODULE_DESCRIPTION("Atheros AR71XX/AR724X/AR913X GPIO API support"); -+ MODULE_LICENSE("GPL v2"); -diff --git a/target/linux/ar71xx/patches-4.14/100-MIPS-ath79-Avoid-using-unitialized-reg-variable.patch b/target/linux/ar71xx/patches-4.14/100-MIPS-ath79-Avoid-using-unitialized-reg-variable.patch -new file mode 100644 -index 0000000000..8d5b089986 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/100-MIPS-ath79-Avoid-using-unitialized-reg-variable.patch -@@ -0,0 +1,42 @@ -+From 8b7a76e72fc819753878cd5684e243f33f847c79 Mon Sep 17 00:00:00 2001 -+From: Markos Chandras -+Date: Wed, 21 Aug 2013 11:47:22 +0100 -+Subject: [PATCH] MIPS: ath79: Avoid using unitialized 'reg' variable -+ -+Fixes the following build error: -+arch/mips/include/asm/mach-ath79/ath79.h:139:20: error: 'reg' may be used -+uninitialized in this function [-Werror=maybe-uninitialized] -+arch/mips/ath79/common.c:62:6: note: 'reg' was declared here -+In file included from arch/mips/ath79/common.c:20:0: -+arch/mips/ath79/common.c: In function 'ath79_device_reset_clear': -+arch/mips/include/asm/mach-ath79/ath79.h:139:20: -+error: 'reg' may be used uninitialized in this function -+[-Werror=maybe-uninitialized] -+arch/mips/ath79/common.c:90:6: note: 'reg' was declared here -+ -+Signed-off-by: Markos Chandras -+Acked-by: Gabor Juhos -+--- -+ arch/mips/ath79/common.c | 4 ++-- -+ 1 file changed, 2 insertions(+), 2 deletions(-) -+ -+--- a/arch/mips/ath79/common.c -++++ b/arch/mips/ath79/common.c -+@@ -106,7 +106,7 @@ void ath79_device_reset_set(u32 mask) -+ else if (soc_is_qca955x()) -+ reg = QCA955X_RESET_REG_RESET_MODULE; -+ else -+- BUG(); -++ panic("Reset register not defined for this SOC"); -+ -+ spin_lock_irqsave(&ath79_device_reset_lock, flags); -+ t = ath79_reset_rr(reg); -+@@ -134,7 +134,7 @@ void ath79_device_reset_clear(u32 mask) -+ else if (soc_is_qca955x()) -+ reg = QCA955X_RESET_REG_RESET_MODULE; -+ else -+- BUG(); -++ panic("Reset register not defined for this SOC"); -+ -+ spin_lock_irqsave(&ath79_device_reset_lock, flags); -+ t = ath79_reset_rr(reg); -diff --git a/target/linux/ar71xx/patches-4.14/106-02-MIPS-ath79-do-AR724x-PCIe-root-complex-init.patch b/target/linux/ar71xx/patches-4.14/106-02-MIPS-ath79-do-AR724x-PCIe-root-complex-init.patch -new file mode 100644 -index 0000000000..3af99bf3b5 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/106-02-MIPS-ath79-do-AR724x-PCIe-root-complex-init.patch -@@ -0,0 +1,113 @@ -+From 460f382c278fe66059a773c41cbcd0db86d53983 Mon Sep 17 00:00:00 2001 -+From: Mathias Kresin -+Date: Thu, 13 Apr 2017 09:47:42 +0200 -+Subject: [PATCH] MIPS: pci-ar724x: get PCIe controller out of reset -+ -+The ar724x pci driver expects the PCIe controller to be brought out of -+reset by the bootloader. -+ -+At least the AVM Fritz 300E bootloader doesn't take care of releasing -+the different PCIe controller related resets which causes an endless -+hang as soon as either the PCIE Reset register (0x180f0018) or the PCI -+Application Control register (0x180f0000) is read from. -+ -+Do the full "PCIE Root Complex Initialization Sequence" if the PCIe -+host controller is still in reset during probing. -+ -+The QCA u-boot sleeps 10ms after the PCIE Application Control bit is -+set to ready. It has been shown that 10ms might not be enough time if -+PCIe should be used right after setting the bit. During my tests it -+took up to 20ms till the link was up. Giving the link up to 100ms -+should work for all cases. -+ -+Signed-off-by: Mathias Kresin -+--- -+ arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 3 ++ -+ arch/mips/pci/pci-ar724x.c | 42 ++++++++++++++++++++++++++ -+ 2 files changed, 45 insertions(+) -+ -+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -+@@ -169,6 +169,9 @@ -+ #define AR724X_PLL_REG_CPU_CONFIG 0x00 -+ #define AR724X_PLL_REG_PCIE_CONFIG 0x10 -+ -++#define AR724X_PLL_REG_PCIE_CONFIG_PPL_BYPASS BIT(16) -++#define AR724X_PLL_REG_PCIE_CONFIG_PPL_RESET BIT(25) -++ -+ #define AR724X_PLL_FB_SHIFT 0 -+ #define AR724X_PLL_FB_MASK 0x3ff -+ #define AR724X_PLL_REF_DIV_SHIFT 10 -+--- a/arch/mips/pci/pci-ar724x.c -++++ b/arch/mips/pci/pci-ar724x.c -+@@ -12,14 +12,18 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ #include -+ -++#define AR724X_PCI_REG_APP 0x0 -+ #define AR724X_PCI_REG_RESET 0x18 -+ #define AR724X_PCI_REG_INT_STATUS 0x4c -+ #define AR724X_PCI_REG_INT_MASK 0x50 -+ -++#define AR724X_PCI_APP_LTSSM_ENABLE BIT(0) -++ -+ #define AR724X_PCI_RESET_LINK_UP BIT(0) -+ -+ #define AR724X_PCI_INT_DEV0 BIT(14) -+@@ -325,6 +329,37 @@ static void ar724x_pci_irq_init(struct a -+ apc); -+ } -+ -++static void ar724x_pci_hw_init(struct ar724x_pci_controller *apc) -++{ -++ u32 ppl, app; -++ int wait = 0; -++ -++ /* deassert PCIe host controller and PCIe PHY reset */ -++ ath79_device_reset_clear(AR724X_RESET_PCIE); -++ ath79_device_reset_clear(AR724X_RESET_PCIE_PHY); -++ -++ /* remove the reset of the PCIE PLL */ -++ ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG); -++ ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_RESET; -++ ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl); -++ -++ /* deassert bypass for the PCIE PLL */ -++ ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG); -++ ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_BYPASS; -++ ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl); -++ -++ /* set PCIE Application Control to ready */ -++ app = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_APP); -++ app |= AR724X_PCI_APP_LTSSM_ENABLE; -++ __raw_writel(app, apc->ctrl_base + AR724X_PCI_REG_APP); -++ -++ /* wait up to 100ms for PHY link up */ -++ do { -++ mdelay(10); -++ wait++; -++ } while (wait < 10 && !ar724x_pci_check_link(apc)); -++} -++ -+ static int ar724x_pci_probe(struct platform_device *pdev) -+ { -+ struct ar724x_pci_controller *apc; -+@@ -383,6 +418,13 @@ static int ar724x_pci_probe(struct platf -+ apc->pci_controller.io_resource = &apc->io_res; -+ apc->pci_controller.mem_resource = &apc->mem_res; -+ -++ /* -++ * Do the full PCIE Root Complex Initialization Sequence if the PCIe -++ * host controller is in reset. -++ */ -++ if (ath79_reset_rr(AR724X_RESET_REG_RESET_MODULE) & AR724X_RESET_PCIE) -++ ar724x_pci_hw_init(apc); -++ -+ apc->link_up = ar724x_pci_check_link(apc); -+ if (!apc->link_up) -+ dev_warn(&pdev->dev, "PCIe link is down\n"); -diff --git a/target/linux/ar71xx/patches-4.14/200-MIPS-ath79-fix-ar933x-wmac-reset.patch b/target/linux/ar71xx/patches-4.14/200-MIPS-ath79-fix-ar933x-wmac-reset.patch -new file mode 100644 -index 0000000000..b7ae0ce649 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/200-MIPS-ath79-fix-ar933x-wmac-reset.patch -@@ -0,0 +1,30 @@ -+--- a/arch/mips/ath79/dev-wmac.c -++++ b/arch/mips/ath79/dev-wmac.c -+@@ -62,10 +62,26 @@ static void __init ar913x_wmac_setup(voi -+ -+ static int ar933x_wmac_reset(void) -+ { -++ int retries = 20; -++ -+ ath79_device_reset_set(AR933X_RESET_WMAC); -+ ath79_device_reset_clear(AR933X_RESET_WMAC); -+ -+- return 0; -++ while (1) { -++ u32 bootstrap; -++ -++ bootstrap = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); -++ if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0) -++ return 0; -++ -++ if (retries-- == 0) -++ break; -++ -++ udelay(10000); -++ } -++ -++ pr_err("ar933x: WMAC reset timed out"); -++ return -ETIMEDOUT; -+ } -+ -+ static int ar933x_r1_get_wmac_revision(void) -diff --git a/target/linux/ar71xx/patches-4.14/201-ar913x_wmac_external_reset.patch b/target/linux/ar71xx/patches-4.14/201-ar913x_wmac_external_reset.patch -new file mode 100644 -index 0000000000..9b704a3c47 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/201-ar913x_wmac_external_reset.patch -@@ -0,0 +1,31 @@ -+--- a/arch/mips/ath79/dev-wmac.c -++++ b/arch/mips/ath79/dev-wmac.c -+@@ -44,7 +44,7 @@ static struct platform_device ath79_wmac -+ }, -+ }; -+ -+-static void __init ar913x_wmac_setup(void) -++static int ar913x_wmac_reset(void) -+ { -+ /* reset the WMAC */ -+ ath79_device_reset_set(AR913X_RESET_AMBA2WMAC); -+@@ -53,10 +53,19 @@ static void __init ar913x_wmac_setup(voi -+ ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC); -+ mdelay(10); -+ -++ return 0; -++} -++ -++static void __init ar913x_wmac_setup(void) -++{ -++ ar913x_wmac_reset(); -++ -+ ath79_wmac_resources[0].start = AR913X_WMAC_BASE; -+ ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1; -+ ath79_wmac_resources[1].start = ATH79_CPU_IRQ(2); -+ ath79_wmac_resources[1].end = ATH79_CPU_IRQ(2); -++ -++ ath79_wmac_data.external_reset = ar913x_wmac_reset; -+ } -+ -+ -diff --git a/target/linux/ar71xx/patches-4.14/202-MIPS-ath79-ar934x-wmac-revision.patch b/target/linux/ar71xx/patches-4.14/202-MIPS-ath79-ar934x-wmac-revision.patch -new file mode 100644 -index 0000000000..0f8016f847 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/202-MIPS-ath79-ar934x-wmac-revision.patch -@@ -0,0 +1,11 @@ -+--- a/arch/mips/ath79/dev-wmac.c -++++ b/arch/mips/ath79/dev-wmac.c -+@@ -139,6 +139,8 @@ static void ar934x_wmac_setup(void) -+ ath79_wmac_data.is_clk_25mhz = false; -+ else -+ ath79_wmac_data.is_clk_25mhz = true; -++ -++ ath79_wmac_data.get_mac_revision = ar93xx_get_soc_revision; -+ } -+ -+ static void qca955x_wmac_setup(void) -diff --git a/target/linux/ar71xx/patches-4.14/220-add_cpu_feature_overrides.patch b/target/linux/ar71xx/patches-4.14/220-add_cpu_feature_overrides.patch -new file mode 100644 -index 0000000000..d925f92624 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/220-add_cpu_feature_overrides.patch -@@ -0,0 +1,28 @@ -+--- a/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h -++++ b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h -+@@ -36,6 +36,7 @@ -+ #define cpu_has_mdmx 0 -+ #define cpu_has_mips3d 0 -+ #define cpu_has_smartmips 0 -++#define cpu_has_rixi 0 -+ -+ #define cpu_has_mips32r1 1 -+ #define cpu_has_mips32r2 1 -+@@ -43,6 +44,7 @@ -+ #define cpu_has_mips64r2 0 -+ -+ #define cpu_has_mipsmt 0 -++#define cpu_has_userlocal 0 -+ -+ #define cpu_has_64bits 0 -+ #define cpu_has_64bit_zero_reg 0 -+@@ -51,5 +53,9 @@ -+ -+ #define cpu_dcache_line_size() 32 -+ #define cpu_icache_line_size() 32 -++#define cpu_has_vtag_icache 0 -++#define cpu_has_dc_aliases 1 -++#define cpu_has_ic_fills_f_dc 0 -++#define cpu_has_pindexed_dcache 0 -+ -+ #endif /* __ASM_MACH_ATH79_CPU_FEATURE_OVERRIDES_H */ -diff --git a/target/linux/ar71xx/patches-4.14/300-MIPS-add-MIPS_MACHINE_NONAME-macro.patch b/target/linux/ar71xx/patches-4.14/300-MIPS-add-MIPS_MACHINE_NONAME-macro.patch -new file mode 100644 -index 0000000000..0bc64b7a17 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/300-MIPS-add-MIPS_MACHINE_NONAME-macro.patch -@@ -0,0 +1,21 @@ -+--- a/arch/mips/include/asm/mips_machine.h -++++ b/arch/mips/include/asm/mips_machine.h -+@@ -36,6 +36,18 @@ static struct mips_machine machine_##_ty -+ .mach_setup = _setup, \ -+ }; -+ -++#define MIPS_MACHINE_NONAME(_type, _id, _setup) \ -++static const char machine_id_##_type[] __initconst \ -++ __aligned(1) = _id; \ -++static struct mips_machine machine_##_type \ -++ __used __section(.mips.machines.init) = \ -++{ \ -++ .mach_type = _type, \ -++ .mach_id = machine_id_##_type, \ -++ .mach_name = NULL, \ -++ .mach_setup = _setup, \ -++}; -++ -+ extern long __mips_machines_start; -+ extern long __mips_machines_end; -+ -diff --git a/target/linux/ar71xx/patches-4.14/310-lib-add-rle-decompression.patch b/target/linux/ar71xx/patches-4.14/310-lib-add-rle-decompression.patch -new file mode 100644 -index 0000000000..727f4d8343 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/310-lib-add-rle-decompression.patch -@@ -0,0 +1,124 @@ -+--- a/lib/Kconfig -++++ b/lib/Kconfig -+@@ -265,6 +265,9 @@ config LZMA_COMPRESS -+ config LZMA_DECOMPRESS -+ tristate -+ -++config RLE_DECOMPRESS -++ tristate -++ -+ # -+ # These all provide a common interface (hence the apparent duplication with -+ # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.) -+--- a/lib/Makefile -++++ b/lib/Makefile -+@@ -146,6 +146,7 @@ obj-$(CONFIG_XZ_DEC) += xz/ -+ obj-$(CONFIG_RAID6_PQ) += raid6/ -+ obj-$(CONFIG_LZMA_COMPRESS) += lzma/ -+ obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/ -++obj-$(CONFIG_RLE_DECOMPRESS) += rle.o -+ -+ lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o -+ lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o -+--- /dev/null -++++ b/include/linux/rle.h -+@@ -0,0 +1,18 @@ -++#ifndef _RLE_H_ -++#define _RLE_H_ -++ -++#ifdef CONFIG_RLE_DECOMPRESS -++int rle_decode(const unsigned char *src, size_t srclen, -++ unsigned char *dst, size_t dstlen, -++ size_t *src_done, size_t *dst_done); -++#else -++static inline int -++rle_decode(const unsigned char *src, size_t srclen, -++ unsigned char *dst, size_t dstlen, -++ size_t *src_done, size_t *dst_done) -++{ -++ return -ENOTSUPP; -++} -++#endif /* CONFIG_RLE_DECOMPRESS */ -++ -++#endif /* _RLE_H_ */ -+--- /dev/null -++++ b/lib/rle.c -+@@ -0,0 +1,78 @@ -++/* -++ * RLE decoding routine -++ * -++ * Copyright (C) 2012 Gabor Juhos -++ * -++ * This program is free software; you can redistribute it and/or modify it -++ * under the terms of the GNU General Public License version 2 as published -++ * by the Free Software Foundation. -++ */ -++ -++#include -++#include -++#include -++ -++int rle_decode(const unsigned char *src, size_t srclen, -++ unsigned char *dst, size_t dstlen, -++ size_t *src_done, size_t *dst_done) -++{ -++ size_t srcpos, dstpos; -++ int ret; -++ -++ srcpos = 0; -++ dstpos = 0; -++ ret = -EINVAL; -++ -++ /* sanity checks */ -++ if (!src || !srclen || !dst || !dstlen) -++ goto out; -++ -++ while (1) { -++ char count; -++ -++ if (srcpos >= srclen) -++ break; -++ -++ count = (char) src[srcpos++]; -++ if (count == 0) { -++ ret = 0; -++ break; -++ } -++ -++ if (count > 0) { -++ unsigned char c; -++ -++ if (srcpos >= srclen) -++ break; -++ -++ c = src[srcpos++]; -++ -++ while (count--) { -++ if (dstpos >= dstlen) -++ break; -++ -++ dst[dstpos++] = c; -++ } -++ } else { -++ count *= -1; -++ -++ while (count--) { -++ if (srcpos >= srclen) -++ break; -++ if (dstpos >= dstlen) -++ break; -++ dst[dstpos++] = src[srcpos++]; -++ } -++ } -++ } -++ -++out: -++ if (src_done) -++ *src_done = srcpos; -++ if (dst_done) -++ *dst_done = dstpos; -++ -++ return ret; -++} -++ -++EXPORT_SYMBOL_GPL(rle_decode); -diff --git a/target/linux/ar71xx/patches-4.14/343-MIPS-ath79-Fix-potentially-missed-IRQ-handling-durin.patch b/target/linux/ar71xx/patches-4.14/343-MIPS-ath79-Fix-potentially-missed-IRQ-handling-durin.patch -new file mode 100644 -index 0000000000..05a1d7ef0c ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/343-MIPS-ath79-Fix-potentially-missed-IRQ-handling-durin.patch -@@ -0,0 +1,52 @@ -+From 3fe7841bf5a582dc7fd198e5bf70162ea418a22a Mon Sep 17 00:00:00 2001 -+From: Koen Vandeputte -+Date: Wed, 11 Sep 2019 11:02:19 +0200 -+Subject: [PATCH] MIPS: ath79: Fix potentially missed IRQ handling during -+ dispatch -+ -+If both interrupts are set in the current implementation -+only the 1st will be handled and the 2nd will be skipped -+due to the "if else" condition. -+ -+Fix this by using the same approach as done for QCA955x -+just below it. -+ -+Fixes: fce5cc6e0ddc ("MIPS: ath79: add IRQ handling code for AR934X") -+Signed-off-by: Koen Vandeputte -+CC: Felix Fietkau -+CC: Gabor Juhos -+CC: James Hogan -+CC: Paul Burton -+CC: Ralf Baechle -+CC: stable@vger.kernel.org # v3.2+ -+--- -+ arch/mips/ath79/irq.c | 12 +++++++++--- -+ 1 file changed, 9 insertions(+), 3 deletions(-) -+ -+--- a/arch/mips/ath79/irq.c -++++ b/arch/mips/ath79/irq.c -+@@ -32,15 +32,21 @@ static void ar934x_ip2_irq_dispatch(stru -+ u32 status; -+ -+ status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS); -++ status &= AR934X_PCIE_WMAC_INT_PCIE_ALL | AR934X_PCIE_WMAC_INT_WMAC_ALL; -++ -++ if (status == 0) { -++ spurious_interrupt(); -++ return; -++ } -+ -+ if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) { -+ ath79_ddr_wb_flush(3); -+ generic_handle_irq(ATH79_IP2_IRQ(0)); -+- } else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) { -++ } -++ -++ if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) { -+ ath79_ddr_wb_flush(4); -+ generic_handle_irq(ATH79_IP2_IRQ(1)); -+- } else { -+- spurious_interrupt(); -+ } -+ } -+ -diff --git a/target/linux/ar71xx/patches-4.14/401-mtd-physmap-add-lock-unlock.patch b/target/linux/ar71xx/patches-4.14/401-mtd-physmap-add-lock-unlock.patch -new file mode 100644 -index 0000000000..db7b3ca83d ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/401-mtd-physmap-add-lock-unlock.patch -@@ -0,0 +1,94 @@ -+--- a/drivers/mtd/maps/physmap.c -++++ b/drivers/mtd/maps/physmap.c -+@@ -31,6 +31,66 @@ struct physmap_flash_info { -+ int vpp_refcnt; -+ }; -+ -++static struct platform_device *physmap_map2pdev(struct map_info *map) -++{ -++ return (struct platform_device *) map->map_priv_1; -++} -++ -++static void physmap_lock(struct map_info *map) -++{ -++ struct platform_device *pdev; -++ struct physmap_flash_data *physmap_data; -++ -++ pdev = physmap_map2pdev(map); -++ physmap_data = pdev->dev.platform_data; -++ physmap_data->lock(pdev); -++} -++ -++static void physmap_unlock(struct map_info *map) -++{ -++ struct platform_device *pdev; -++ struct physmap_flash_data *physmap_data; -++ -++ pdev = physmap_map2pdev(map); -++ physmap_data = pdev->dev.platform_data; -++ physmap_data->unlock(pdev); -++} -++ -++static map_word physmap_flash_read_lock(struct map_info *map, unsigned long ofs) -++{ -++ map_word ret; -++ -++ physmap_lock(map); -++ ret = inline_map_read(map, ofs); -++ physmap_unlock(map); -++ -++ return ret; -++} -++ -++static void physmap_flash_write_lock(struct map_info *map, map_word d, -++ unsigned long ofs) -++{ -++ physmap_lock(map); -++ inline_map_write(map, d, ofs); -++ physmap_unlock(map); -++} -++ -++static void physmap_flash_copy_from_lock(struct map_info *map, void *to, -++ unsigned long from, ssize_t len) -++{ -++ physmap_lock(map); -++ inline_map_copy_from(map, to, from, len); -++ physmap_unlock(map); -++} -++ -++static void physmap_flash_copy_to_lock(struct map_info *map, unsigned long to, -++ const void *from, ssize_t len) -++{ -++ physmap_lock(map); -++ inline_map_copy_to(map, to, from, len); -++ physmap_unlock(map); -++} -++ -+ static int physmap_flash_remove(struct platform_device *dev) -+ { -+ struct physmap_flash_info *info; -+@@ -153,6 +213,13 @@ static int physmap_flash_probe(struct pl -+ -+ simple_map_init(&info->map[i]); -+ -++ if (physmap_data->lock && physmap_data->unlock) { -++ info->map[i].read = physmap_flash_read_lock; -++ info->map[i].write = physmap_flash_write_lock; -++ info->map[i].copy_from = physmap_flash_copy_from_lock; -++ info->map[i].copy_to = physmap_flash_copy_to_lock; -++ } -++ -+ probe_type = rom_probe_types; -+ if (physmap_data->probe_type == NULL) { -+ for (; info->mtd[i] == NULL && *probe_type != NULL; probe_type++) -+--- a/include/linux/mtd/physmap.h -++++ b/include/linux/mtd/physmap.h -+@@ -25,6 +25,8 @@ struct physmap_flash_data { -+ unsigned int width; -+ int (*init)(struct platform_device *); -+ void (*exit)(struct platform_device *); -++ void (*lock)(struct platform_device *); -++ void (*unlock)(struct platform_device *); -+ void (*set_vpp)(struct platform_device *, int); -+ unsigned int nr_parts; -+ unsigned int pfow_base; -diff --git a/target/linux/ar71xx/patches-4.14/402-mtd-SST39VF6401B-support.patch b/target/linux/ar71xx/patches-4.14/402-mtd-SST39VF6401B-support.patch -new file mode 100644 -index 0000000000..0d483ab1a4 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/402-mtd-SST39VF6401B-support.patch -@@ -0,0 +1,29 @@ -+--- a/drivers/mtd/chips/jedec_probe.c -++++ b/drivers/mtd/chips/jedec_probe.c -+@@ -148,6 +148,7 @@ -+ #define SST39LF160 0x2782 -+ #define SST39VF1601 0x234b -+ #define SST39VF3201 0x235b -++#define SST39VF6401B 0x236d -+ #define SST39WF1601 0x274b -+ #define SST39WF1602 0x274a -+ #define SST39LF512 0x00D4 -+@@ -1569,6 +1570,18 @@ static const struct amd_flash_info jedec -+ ERASEINFO(0x10000,64), -+ } -+ }, { -++ .mfr_id = CFI_MFR_SST, -++ .dev_id = SST39VF6401B, -++ .name = "SST 39VF6401B", -++ .devtypes = CFI_DEVICETYPE_X16, -++ .uaddr = MTD_UADDR_0xAAAA_0x5555, -++ .dev_size = SIZE_8MiB, -++ .cmd_set = P_ID_AMD_STD, -++ .nr_regions = 1, -++ .regions = { -++ ERASEINFO(0x10000,128) -++ } -++ }, { -+ .mfr_id = CFI_MFR_ST, -+ .dev_id = M29F800AB, -+ .name = "ST M29F800AB", -diff --git a/target/linux/ar71xx/patches-4.14/404-mtd-cybertan-trx-parser.patch b/target/linux/ar71xx/patches-4.14/404-mtd-cybertan-trx-parser.patch -new file mode 100644 -index 0000000000..4b59abe16b ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/404-mtd-cybertan-trx-parser.patch -@@ -0,0 +1,25 @@ -+--- a/drivers/mtd/Kconfig -++++ b/drivers/mtd/Kconfig -+@@ -178,6 +178,12 @@ menu "Partition parsers" -+ source "drivers/mtd/parsers/Kconfig" -+ endmenu -+ -++config MTD_CYBERTAN_PARTS -++ tristate "Cybertan partitioning support" -++ depends on ATH79 -++ ---help--- -++ Cybertan partitioning support -++ -+ config MTD_MYLOADER_PARTS -+ tristate "MyLoader partition parsing" -+ depends on ADM5120 || ATH25 || ATH79 -+--- a/drivers/mtd/Makefile -++++ b/drivers/mtd/Makefile -+@@ -18,6 +18,7 @@ obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63 -+ obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o -+ obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o -+ obj-y += parsers/ -++obj-$(CONFIG_MTD_CYBERTAN_PARTS) += cybertan_part.o -+ -+ # 'Users' - code which presents functionality to userspace. -+ obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o -diff --git a/target/linux/ar71xx/patches-4.14/405-mtd-tp-link-partition-parser.patch b/target/linux/ar71xx/patches-4.14/405-mtd-tp-link-partition-parser.patch -new file mode 100644 -index 0000000000..899ab893f0 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/405-mtd-tp-link-partition-parser.patch -@@ -0,0 +1,25 @@ -+--- a/drivers/mtd/Kconfig -++++ b/drivers/mtd/Kconfig -+@@ -200,6 +200,12 @@ config MTD_MYLOADER_PARTS -+ You will still need the parsing functions to be called by the driver -+ for your particular device. It won't happen automatically. -+ -++config MTD_TPLINK_PARTS -++ tristate "TP-Link AR7XXX/AR9XXX partitioning support" -++ depends on ATH79 -++ ---help--- -++ TBD. -++ -+ comment "User Modules And Translation Layers" -+ -+ # -+--- a/drivers/mtd/Makefile -++++ b/drivers/mtd/Makefile -+@@ -18,6 +18,7 @@ obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63 -+ obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o -+ obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o -+ obj-y += parsers/ -++obj-$(CONFIG_MTD_TPLINK_PARTS) += tplinkpart.o -+ obj-$(CONFIG_MTD_CYBERTAN_PARTS) += cybertan_part.o -+ -+ # 'Users' - code which presents functionality to userspace. -diff --git a/target/linux/ar71xx/patches-4.14/407-mtd-m25p80-allow-to-pass-probe-types-via-platform-data.patch b/target/linux/ar71xx/patches-4.14/407-mtd-m25p80-allow-to-pass-probe-types-via-platform-data.patch -new file mode 100644 -index 0000000000..13999064cb ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/407-mtd-m25p80-allow-to-pass-probe-types-via-platform-data.patch -@@ -0,0 +1,34 @@ -+--- a/drivers/mtd/devices/m25p80.c -++++ b/drivers/mtd/devices/m25p80.c -+@@ -235,6 +235,7 @@ static ssize_t m25p80_read(struct spi_no -+ */ -+ static int m25p_probe(struct spi_device *spi) -+ { -++ struct mtd_part_parser_data ppdata = {0,}; -+ struct flash_platform_data *data; -+ struct m25p *flash; -+ struct spi_nor *nor; -+@@ -300,8 +301,11 @@ static int m25p_probe(struct spi_device -+ if (ret) -+ return ret; -+ -+- return mtd_device_register(&nor->mtd, data ? data->parts : NULL, -+- data ? data->nr_parts : 0); -++ return mtd_device_parse_register(&nor->mtd, -++ data ? data->part_probes : NULL, -++ &ppdata, -++ data ? data->parts : NULL, -++ data ? data->nr_parts : 0); -+ } -+ -+ -+--- a/include/linux/spi/flash.h -++++ b/include/linux/spi/flash.h -+@@ -25,6 +25,7 @@ struct flash_platform_data { -+ unsigned int nr_parts; -+ -+ char *type; -++ const char **part_probes; -+ -+ /* we'll likely add more ... use JEDEC IDs, etc */ -+ }; -diff --git a/target/linux/ar71xx/patches-4.14/408-mtd-redboot_partition_scan.patch b/target/linux/ar71xx/patches-4.14/408-mtd-redboot_partition_scan.patch -new file mode 100644 -index 0000000000..cd41e7ceb2 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/408-mtd-redboot_partition_scan.patch -@@ -0,0 +1,44 @@ -+--- a/drivers/mtd/redboot.c -++++ b/drivers/mtd/redboot.c -+@@ -76,12 +76,18 @@ static int parse_redboot_partitions(stru -+ static char nullstring[] = "unallocated"; -+ #endif -+ -++ buf = vmalloc(master->erasesize); -++ if (!buf) -++ return -ENOMEM; -++ -++ restart: -+ if ( directory < 0 ) { -+ offset = master->size + directory * master->erasesize; -+ while (mtd_block_isbad(master, offset)) { -+ if (!offset) { -+ nogood: -+ printk(KERN_NOTICE "Failed to find a non-bad block to check for RedBoot partition table\n"); -++ vfree(buf); -+ return -EIO; -+ } -+ offset -= master->erasesize; -+@@ -94,10 +100,6 @@ static int parse_redboot_partitions(stru -+ goto nogood; -+ } -+ } -+- buf = vmalloc(master->erasesize); -+- -+- if (!buf) -+- return -ENOMEM; -+ -+ printk(KERN_NOTICE "Searching for RedBoot partition table in %s at offset 0x%lx\n", -+ master->name, offset); -+@@ -170,6 +172,11 @@ static int parse_redboot_partitions(stru -+ } -+ if (i == numslots) { -+ /* Didn't find it */ -++ if (offset + master->erasesize < master->size) { -++ /* not at the end of the flash yet, maybe next block :) */ -++ directory++; -++ goto restart; -++ } -+ printk(KERN_NOTICE "No RedBoot partition table detected in %s\n", -+ master->name); -+ ret = 0; -diff --git a/target/linux/ar71xx/patches-4.14/409-mtd-rb4xx_nand_driver.patch b/target/linux/ar71xx/patches-4.14/409-mtd-rb4xx_nand_driver.patch -new file mode 100644 -index 0000000000..c4b26ecb72 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/409-mtd-rb4xx_nand_driver.patch -@@ -0,0 +1,21 @@ -+--- a/drivers/mtd/nand/Kconfig -++++ b/drivers/mtd/nand/Kconfig -+@@ -563,4 +563,8 @@ config MTD_NAND_MTK -+ Enables support for NAND controller on MTK SoCs. -+ This controller is found on mt27xx, mt81xx, mt65xx SoCs. -+ -++config MTD_NAND_RB4XX -++ tristate "NAND flash driver for RouterBoard 4xx series" -++ depends on MTD_NAND && ATH79_MACH_RB4XX -++ -+ endif # MTD_NAND -+--- a/drivers/mtd/nand/Makefile -++++ b/drivers/mtd/nand/Makefile -+@@ -34,6 +34,7 @@ obj-$(CONFIG_MTD_NAND_CM_X270) += cmx27 -+ obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o -+ obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o -+ obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o -++obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o -+ obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o -+ obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o -+ obj-$(CONFIG_MTD_NAND_OXNAS) += oxnas_nand.o -diff --git a/target/linux/ar71xx/patches-4.14/410-mtd-rb750-nand-driver.patch b/target/linux/ar71xx/patches-4.14/410-mtd-rb750-nand-driver.patch -new file mode 100644 -index 0000000000..08960f4358 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/410-mtd-rb750-nand-driver.patch -@@ -0,0 +1,21 @@ -+--- a/drivers/mtd/nand/Kconfig -++++ b/drivers/mtd/nand/Kconfig -+@@ -567,4 +567,8 @@ config MTD_NAND_RB4XX -+ tristate "NAND flash driver for RouterBoard 4xx series" -+ depends on MTD_NAND && ATH79_MACH_RB4XX -+ -++config MTD_NAND_RB750 -++ tristate "NAND flash driver for the RouterBoard 750" -++ depends on MTD_NAND && ATH79_MACH_RB750 -++ -+ endif # MTD_NAND -+--- a/drivers/mtd/nand/Makefile -++++ b/drivers/mtd/nand/Makefile -+@@ -35,6 +35,7 @@ obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx -+ obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o -+ obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o -+ obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o -++obj-$(CONFIG_MTD_NAND_RB750) += rb750_nand.o -+ obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o -+ obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o -+ obj-$(CONFIG_MTD_NAND_OXNAS) += oxnas_nand.o -diff --git a/target/linux/ar71xx/patches-4.14/411-mtd-cfi_cmdset_0002-force-word-write.patch b/target/linux/ar71xx/patches-4.14/411-mtd-cfi_cmdset_0002-force-word-write.patch -new file mode 100644 -index 0000000000..5a5320968f ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/411-mtd-cfi_cmdset_0002-force-word-write.patch -@@ -0,0 +1,61 @@ -+--- a/drivers/mtd/chips/cfi_cmdset_0002.c -++++ b/drivers/mtd/chips/cfi_cmdset_0002.c -+@@ -40,7 +40,7 @@ -+ #include -+ -+ #define AMD_BOOTLOC_BUG -+-#define FORCE_WORD_WRITE 0 -++#define FORCE_WORD_WRITE 1 -+ -+ #define MAX_RETRIES 3 -+ -+@@ -51,7 +51,9 @@ -+ -+ static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); -+ static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); -++#if !FORCE_WORD_WRITE -+ static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); -++#endif -+ static int cfi_amdstd_erase_chip(struct mtd_info *, struct erase_info *); -+ static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *); -+ static void cfi_amdstd_sync (struct mtd_info *); -+@@ -202,6 +204,7 @@ static void fixup_amd_bootblock(struct m -+ } -+ #endif -+ -++#if !FORCE_WORD_WRITE -+ static void fixup_use_write_buffers(struct mtd_info *mtd) -+ { -+ struct map_info *map = mtd->priv; -+@@ -211,6 +214,7 @@ static void fixup_use_write_buffers(stru -+ mtd->_write = cfi_amdstd_write_buffers; -+ } -+ } -++#endif /* !FORCE_WORD_WRITE */ -+ -+ /* Atmel chips don't use the same PRI format as AMD chips */ -+ static void fixup_convert_atmel_pri(struct mtd_info *mtd) -+@@ -1798,6 +1802,7 @@ static int cfi_amdstd_write_words(struct -+ /* -+ * FIXME: interleaved mode not tested, and probably not supported! -+ */ -++#if !FORCE_WORD_WRITE -+ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, -+ unsigned long adr, const u_char *buf, -+ int len) -+@@ -1930,7 +1935,6 @@ static int __xipram do_write_buffer(stru -+ return ret; -+ } -+ -+- -+ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, -+ size_t *retlen, const u_char *buf) -+ { -+@@ -2005,6 +2009,7 @@ static int cfi_amdstd_write_buffers(stru -+ -+ return 0; -+ } -++#endif /* !FORCE_WORD_WRITE */ -+ -+ /* -+ * Wait for the flash chip to become ready to write data -diff --git a/target/linux/ar71xx/patches-4.14/413-mtd-ar934x-nand-driver.patch b/target/linux/ar71xx/patches-4.14/413-mtd-ar934x-nand-driver.patch -new file mode 100644 -index 0000000000..a2f34f6776 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/413-mtd-ar934x-nand-driver.patch -@@ -0,0 +1,25 @@ -+--- a/drivers/mtd/nand/Kconfig -++++ b/drivers/mtd/nand/Kconfig -+@@ -571,4 +571,12 @@ config MTD_NAND_RB750 -+ tristate "NAND flash driver for the RouterBoard 750" -+ depends on MTD_NAND && ATH79_MACH_RB750 -+ -++config MTD_NAND_AR934X -++ tristate "NAND flash driver for the Qualcomm Atheros AR934x/QCA955x SoCs" -++ depends on (SOC_AR934X || SOC_QCA955X) -++ -++config MTD_NAND_AR934X_HW_ECC -++ bool "Hardware ECC support for the AR934X NAND Controller (EXPERIMENTAL)" -++ depends on MTD_NAND_AR934X -++ -+ endif # MTD_NAND -+--- a/drivers/mtd/nand/Makefile -++++ b/drivers/mtd/nand/Makefile -+@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams- -+ obj-$(CONFIG_MTD_NAND_DENALI) += denali.o -+ obj-$(CONFIG_MTD_NAND_DENALI_PCI) += denali_pci.o -+ obj-$(CONFIG_MTD_NAND_DENALI_DT) += denali_dt.o -++obj-$(CONFIG_MTD_NAND_AR934X) += ar934x_nfc.o -+ obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o -+ obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o -+ obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o -diff --git a/target/linux/ar71xx/patches-4.14/414-mtd-rb91x-nand-driver.patch b/target/linux/ar71xx/patches-4.14/414-mtd-rb91x-nand-driver.patch -new file mode 100644 -index 0000000000..f9784a2d13 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/414-mtd-rb91x-nand-driver.patch -@@ -0,0 +1,23 @@ -+--- a/drivers/mtd/nand/Kconfig -++++ b/drivers/mtd/nand/Kconfig -+@@ -571,6 +571,10 @@ config MTD_NAND_RB750 -+ tristate "NAND flash driver for the RouterBoard 750" -+ depends on MTD_NAND && ATH79_MACH_RB750 -+ -++config MTD_NAND_RB91X -++ tristate "NAND flash driver for the RouterBOARD 91x series" -++ depends on MTD_NAND && ATH79_MACH_RB91X -++ -+ config MTD_NAND_AR934X -+ tristate "NAND flash driver for the Qualcomm Atheros AR934x/QCA955x SoCs" -+ depends on (SOC_AR934X || SOC_QCA955X) -+--- a/drivers/mtd/nand/Makefile -++++ b/drivers/mtd/nand/Makefile -+@@ -37,6 +37,7 @@ obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nan -+ obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o -+ obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o -+ obj-$(CONFIG_MTD_NAND_RB750) += rb750_nand.o -++obj-$(CONFIG_MTD_NAND_RB91X) += rb91x_nand.o -+ obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o -+ obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o -+ obj-$(CONFIG_MTD_NAND_OXNAS) += oxnas_nand.o -diff --git a/target/linux/ar71xx/patches-4.14/420-net-ar71xx_mac_driver.patch b/target/linux/ar71xx/patches-4.14/420-net-ar71xx_mac_driver.patch -new file mode 100644 -index 0000000000..6377db0ac2 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/420-net-ar71xx_mac_driver.patch -@@ -0,0 +1,28 @@ -+--- a/drivers/net/ethernet/atheros/Kconfig -++++ b/drivers/net/ethernet/atheros/Kconfig -+@@ -5,7 +5,7 @@ -+ config NET_VENDOR_ATHEROS -+ bool "Atheros devices" -+ default y -+- depends on PCI -++ depends on (PCI || ATH79) -+ ---help--- -+ If you have a network (Ethernet) card belonging to this class, say Y. -+ -+@@ -78,4 +78,6 @@ config ALX -+ To compile this driver as a module, choose M here. The module -+ will be called alx. -+ -++source drivers/net/ethernet/atheros/ag71xx/Kconfig -++ -+ endif # NET_VENDOR_ATHEROS -+--- a/drivers/net/ethernet/atheros/Makefile -++++ b/drivers/net/ethernet/atheros/Makefile -+@@ -3,6 +3,7 @@ -+ # Makefile for the Atheros network device drivers. -+ # -+ -++obj-$(CONFIG_AG71XX) += ag71xx/ -+ obj-$(CONFIG_ATL1) += atlx/ -+ obj-$(CONFIG_ATL2) += atlx/ -+ obj-$(CONFIG_ATL1E) += atl1e/ -diff --git a/target/linux/ar71xx/patches-4.14/423-dsa-add-88e6063-driver.patch b/target/linux/ar71xx/patches-4.14/423-dsa-add-88e6063-driver.patch -new file mode 100644 -index 0000000000..94172d01b7 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/423-dsa-add-88e6063-driver.patch -@@ -0,0 +1,27 @@ -+--- a/drivers/net/dsa/Kconfig -++++ b/drivers/net/dsa/Kconfig -+@@ -3,6 +3,14 @@ menu "Distributed Switch Architecture dr -+ -+ source "drivers/net/dsa/b53/Kconfig" -+ -++config NET_DSA_MV88E6063 -++ bool "Marvell 88E6063 ethernet switch chip support" -++ depends on NET_DSA -++ select NET_DSA_TAG_TRAILER -++ ---help--- -++ This enables support for the Marvell 88E6063 ethernet switch -++ chip -++ -+ config NET_DSA_BCM_SF2 -+ tristate "Broadcom Starfighter 2 Ethernet switch support" -+ depends on HAS_IOMEM && NET_DSA && OF_MDIO -+--- a/drivers/net/dsa/Makefile -++++ b/drivers/net/dsa/Makefile -+@@ -7,6 +7,7 @@ obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdi -+ endif -+ obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o -+ obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o -++obj-$(CONFIG_NET_DSA_MV88E6063) += mv88e6063.o -+ obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o -+ obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o -+ obj-$(CONFIG_NET_DSA_SMSC_LAN9303_I2C) += lan9303_i2c.o -diff --git a/target/linux/ar71xx/patches-4.14/430-drivers-link-spi-before-mtd.patch b/target/linux/ar71xx/patches-4.14/430-drivers-link-spi-before-mtd.patch -new file mode 100644 -index 0000000000..2f1549710b ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/430-drivers-link-spi-before-mtd.patch -@@ -0,0 +1,12 @@ -+--- a/drivers/Makefile -++++ b/drivers/Makefile -+@@ -83,8 +83,8 @@ obj-$(CONFIG_SCSI) += scsi/ -+ obj-y += nvme/ -+ obj-$(CONFIG_ATA) += ata/ -+ obj-$(CONFIG_TARGET_CORE) += target/ -+-obj-$(CONFIG_MTD) += mtd/ -+ obj-$(CONFIG_SPI) += spi/ -++obj-$(CONFIG_MTD) += mtd/ -+ obj-$(CONFIG_SPMI) += spmi/ -+ obj-$(CONFIG_HSI) += hsi/ -+ obj-y += net/ -diff --git a/target/linux/ar71xx/patches-4.14/432-spi-rb4xx-spi-driver.patch b/target/linux/ar71xx/patches-4.14/432-spi-rb4xx-spi-driver.patch -new file mode 100644 -index 0000000000..9b0148998f ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/432-spi-rb4xx-spi-driver.patch -@@ -0,0 +1,25 @@ -+--- a/drivers/spi/Kconfig -++++ b/drivers/spi/Kconfig -+@@ -563,6 +563,12 @@ config SPI_QUP -+ This driver can also be built as a module. If so, the module -+ will be called spi_qup. -+ -++config SPI_RB4XX -++ tristate "Mikrotik RB4XX SPI master" -++ depends on SPI_MASTER && ATH79_MACH_RB4XX -++ help -++ SPI controller driver for the Mikrotik RB4xx series boards. -++ -+ config SPI_S3C24XX -+ tristate "Samsung S3C24XX series SPI" -+ depends on ARCH_S3C24XX -+--- a/drivers/spi/Makefile -++++ b/drivers/spi/Makefile -+@@ -77,6 +77,7 @@ obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx. -+ spi-pxa2xx-platform-objs := spi-pxa2xx.o spi-pxa2xx-dma.o -+ obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx-platform.o -+ obj-$(CONFIG_SPI_PXA2XX_PCI) += spi-pxa2xx-pci.o -++obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o -+ obj-$(CONFIG_SPI_QUP) += spi-qup.o -+ obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockchip.o -+ obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o -diff --git a/target/linux/ar71xx/patches-4.14/433-spi-rb4xx-cpld-driver.patch b/target/linux/ar71xx/patches-4.14/433-spi-rb4xx-cpld-driver.patch -new file mode 100644 -index 0000000000..02c30c6631 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/433-spi-rb4xx-cpld-driver.patch -@@ -0,0 +1,26 @@ -+--- a/drivers/spi/Kconfig -++++ b/drivers/spi/Kconfig -+@@ -801,6 +801,13 @@ config SPI_TLE62X0 -+ sysfs interface, with each line presented as a kind of GPIO -+ exposing both switch control and diagnostic feedback. -+ -++config SPI_RB4XX_CPLD -++ tristate "MikroTik RB4XX CPLD driver" -++ depends on ATH79_MACH_RB4XX -++ help -++ SPI driver for the Xilinx CPLD chip present on the -++ MikroTik RB4xx boards. -++ -+ # -+ # Add new SPI protocol masters in alphabetical order above this line -+ # -+--- a/drivers/spi/Makefile -++++ b/drivers/spi/Makefile -+@@ -78,6 +78,7 @@ spi-pxa2xx-platform-objs := spi-pxa2xx. -+ obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx-platform.o -+ obj-$(CONFIG_SPI_PXA2XX_PCI) += spi-pxa2xx-pci.o -+ obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o -++obj-$(CONFIG_SPI_RB4XX_CPLD) += spi-rb4xx-cpld.o -+ obj-$(CONFIG_SPI_QUP) += spi-qup.o -+ obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockchip.o -+ obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o -diff --git a/target/linux/ar71xx/patches-4.14/435-spi-vsc7385_driver.patch b/target/linux/ar71xx/patches-4.14/435-spi-vsc7385_driver.patch -new file mode 100644 -index 0000000000..bef0c86761 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/435-spi-vsc7385_driver.patch -@@ -0,0 +1,24 @@ -+--- a/drivers/spi/Kconfig -++++ b/drivers/spi/Kconfig -+@@ -808,6 +808,11 @@ config SPI_RB4XX_CPLD -+ SPI driver for the Xilinx CPLD chip present on the -+ MikroTik RB4xx boards. -+ -++config SPI_VSC7385 -++ tristate "Vitesse VSC7385 ethernet switch driver" -++ help -++ SPI driver for the Vitesse VSC7385 ethernet switch. -++ -+ # -+ # Add new SPI protocol masters in alphabetical order above this line -+ # -+--- a/drivers/spi/Makefile -++++ b/drivers/spi/Makefile -+@@ -105,6 +105,7 @@ spi-thunderx-objs := spi-cavium.o spi- -+ obj-$(CONFIG_SPI_THUNDERX) += spi-thunderx.o -+ obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o -+ obj-$(CONFIG_SPI_TXX9) += spi-txx9.o -++obj-$(CONFIG_SPI_VSC7385) += spi-vsc7385.o -+ obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o -+ obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o -+ obj-$(CONFIG_SPI_XLP) += spi-xlp.o -diff --git a/target/linux/ar71xx/patches-4.14/440-leds-wndr3700-usb-led-driver.patch b/target/linux/ar71xx/patches-4.14/440-leds-wndr3700-usb-led-driver.patch -new file mode 100644 -index 0000000000..e5f7cc5c00 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/440-leds-wndr3700-usb-led-driver.patch -@@ -0,0 +1,26 @@ -+--- a/drivers/leds/Kconfig -++++ b/drivers/leds/Kconfig -+@@ -696,6 +696,13 @@ config LEDS_NIC78BX -+ To compile this driver as a module, choose M here: the module -+ will be called leds-nic78bx. -+ -++config LEDS_WNDR3700_USB -++ tristate "NETGEAR WNDR3700 USB LED driver" -++ depends on LEDS_CLASS && ATH79_MACH_WNDR3700 -++ help -++ This option enables support for the USB LED found on the -++ NETGEAR WNDR3700 board. -++ -+ comment "LED Triggers" -+ source "drivers/leds/trigger/Kconfig" -+ -+--- a/drivers/leds/Makefile -++++ b/drivers/leds/Makefile -+@@ -51,6 +51,7 @@ obj-$(CONFIG_LEDS_DA9052) += leds-da905 -+ obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o -+ obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o -+ obj-$(CONFIG_LEDS_PWM) += leds-pwm.o -++obj-${CONFIG_LEDS_WNDR3700_USB} += leds-wndr3700-usb.o -+ obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o -+ obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o -+ obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o -diff --git a/target/linux/ar71xx/patches-4.14/441-leds-rb750-led-driver.patch b/target/linux/ar71xx/patches-4.14/441-leds-rb750-led-driver.patch -new file mode 100644 -index 0000000000..012e6b4380 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/441-leds-rb750-led-driver.patch -@@ -0,0 +1,23 @@ -+--- a/drivers/leds/Kconfig -++++ b/drivers/leds/Kconfig -+@@ -703,6 +703,10 @@ config LEDS_WNDR3700_USB -+ This option enables support for the USB LED found on the -+ NETGEAR WNDR3700 board. -+ -++config LEDS_RB750 -++ tristate "LED driver for the Mikrotik RouterBOARD 750" -++ depends on LEDS_CLASS && ATH79_MACH_RB750 -++ -+ comment "LED Triggers" -+ source "drivers/leds/trigger/Kconfig" -+ -+--- a/drivers/leds/Makefile -++++ b/drivers/leds/Makefile -+@@ -57,6 +57,7 @@ obj-$(CONFIG_LEDS_INTEL_SS4200) += leds -+ obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o -+ obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o -+ obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o -++obj-$(CONFIG_LEDS_RB750) += leds-rb750.o -+ obj-$(CONFIG_LEDS_NS2) += leds-ns2.o -+ obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o -+ obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o -diff --git a/target/linux/ar71xx/patches-4.14/442-leds-gpio-allow-to-use-OPEN_-DRAIN-SOURCE-flags-with.patch b/target/linux/ar71xx/patches-4.14/442-leds-gpio-allow-to-use-OPEN_-DRAIN-SOURCE-flags-with.patch -new file mode 100644 -index 0000000000..3dbf68b1ed ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/442-leds-gpio-allow-to-use-OPEN_-DRAIN-SOURCE-flags-with.patch -@@ -0,0 +1,45 @@ -+From 183148e0789bee1cd5c46ba49afcb211f636f8a2 Mon Sep 17 00:00:00 2001 -+From: Gabor Juhos -+Date: Mon, 15 Jan 2018 15:01:14 +0100 -+Subject: [PATCH] leds: gpio: allow to use OPEN_{DRAIN,SOURCE} flags with -+ legacy GPIOs -+ -+LEDs which are connected to open-source or open-drain type of GPIO lines -+can be used only, if those are defined via devicetree. -+Add two new fields to 'struct gpio_led' in order to make it possible to -+specify this type of GPIO lines to the leds-gpio driver via platform data. -+Also update the create_gpio_led() function to set the GPIOF_OPEN_DRAIN and -+GPIOF_OPEN_SOURCE flags for the given GPIO line. -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/leds/leds-gpio.c | 6 ++++++ -+ include/linux/leds.h | 2 ++ -+ 2 files changed, 8 insertions(+) -+ -+--- a/drivers/leds/leds-gpio.c -++++ b/drivers/leds/leds-gpio.c -+@@ -100,6 +100,12 @@ static int create_gpio_led(const struct -+ if (template->active_low) -+ flags |= GPIOF_ACTIVE_LOW; -+ -++ if (template->open_drain) -++ flags |= GPIOF_OPEN_DRAIN; -++ -++ if (template->open_source) -++ flags |= GPIOF_OPEN_SOURCE; -++ -+ ret = devm_gpio_request_one(parent, template->gpio, flags, -+ template->name); -+ if (ret < 0) -+--- a/include/linux/leds.h -++++ b/include/linux/leds.h -+@@ -395,6 +395,8 @@ struct gpio_led { -+ unsigned default_state : 2; -+ unsigned retain_state_shutdown : 1; -+ /* default_state should be one of LEDS_GPIO_DEFSTATE_(ON|OFF|KEEP) */ -++ unsigned open_drain : 1; -++ unsigned open_source : 1; -+ struct gpio_desc *gpiod; -+ }; -+ #define LEDS_GPIO_DEFSTATE_OFF 0 -diff --git a/target/linux/ar71xx/patches-4.14/450-gpio-nxp-74hc153-gpio-chip-driver.patch b/target/linux/ar71xx/patches-4.14/450-gpio-nxp-74hc153-gpio-chip-driver.patch -new file mode 100644 -index 0000000000..48a36cc4ec ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/450-gpio-nxp-74hc153-gpio-chip-driver.patch -@@ -0,0 +1,25 @@ -+--- a/drivers/gpio/Kconfig -++++ b/drivers/gpio/Kconfig -+@@ -1300,4 +1300,12 @@ config GPIO_VIPERBOARD -+ -+ endmenu -+ -++comment "Other GPIO expanders" -++ -++config GPIO_NXP_74HC153 -++ tristate "NXP 74HC153 Dual 4-input multiplexer" -++ help -++ Platform driver for NXP 74HC153 Dual 4-input Multiplexer. This -++ provides a GPIO interface supporting input mode only. -++ -+ endif -+--- a/drivers/gpio/Makefile -++++ b/drivers/gpio/Makefile -+@@ -89,6 +89,7 @@ obj-$(CONFIG_GPIO_MSIC) += gpio-msic.o -+ obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o -+ obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o -+ obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o -++obj-$(CONFIG_GPIO_NXP_74HC153) += gpio-nxp-74hc153.o -+ obj-$(CONFIG_GPIO_OCTEON) += gpio-octeon.o -+ obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o -+ obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o -diff --git a/target/linux/ar71xx/patches-4.14/451-gpio-74x164-improve-platform-device-support.patch b/target/linux/ar71xx/patches-4.14/451-gpio-74x164-improve-platform-device-support.patch -new file mode 100644 -index 0000000000..b3c990ccec ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/451-gpio-74x164-improve-platform-device-support.patch -@@ -0,0 +1,119 @@ -+--- a/drivers/gpio/gpio-74x164.c -++++ b/drivers/gpio/gpio-74x164.c -+@@ -13,6 +13,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ #include -+@@ -105,9 +106,16 @@ static int gen_74x164_direction_output(s -+ static int gen_74x164_probe(struct spi_device *spi) -+ { -+ struct gen_74x164_chip *chip; -++ struct gen_74x164_chip_platform_data *pdata = spi->dev.platform_data; -++ struct device_node *np = spi->dev.of_node; -+ u32 nregs; -+ int ret; -+ -++ if (!np && !pdata) { -++ dev_err(&spi->dev, "No configuration data available.\n"); -++ return -EINVAL; -++ } -++ -+ /* -+ * bits_per_word cannot be configured in platform data -+ */ -+@@ -117,12 +125,15 @@ static int gen_74x164_probe(struct spi_d -+ if (ret < 0) -+ return ret; -+ -+- if (of_property_read_u32(spi->dev.of_node, "registers-number", -+- &nregs)) { -+- dev_err(&spi->dev, -+- "Missing registers-number property in the DT.\n"); -+- return -EINVAL; -+- } -++ if (np) { -++ if (of_property_read_u32(np, "registers-number", &nregs)) { -++ dev_err(&spi->dev, -++ "Missing registers-number property in the DT.\n"); -++ return -EINVAL; -++ } -++ } else if (pdata) { -++ nregs = pdata->num_registers; -++ } -+ -+ chip = devm_kzalloc(&spi->dev, sizeof(*chip) + nregs, GFP_KERNEL); -+ if (!chip) -+@@ -142,7 +153,11 @@ static int gen_74x164_probe(struct spi_d -+ chip->gpio_chip.get = gen_74x164_get_value; -+ chip->gpio_chip.set = gen_74x164_set_value; -+ chip->gpio_chip.set_multiple = gen_74x164_set_multiple; -+- chip->gpio_chip.base = -1; -++ if (np) -++ chip->gpio_chip.base = -1; -++ else if (pdata) -++ chip->gpio_chip.base = pdata->base; -++ -+ -+ chip->registers = nregs; -+ chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers; -+@@ -151,6 +166,9 @@ static int gen_74x164_probe(struct spi_d -+ chip->gpio_chip.parent = &spi->dev; -+ chip->gpio_chip.owner = THIS_MODULE; -+ -++ if (pdata && pdata->init_data) -++ memcpy(chip->buffer, pdata->init_data, chip->registers); -++ -+ mutex_init(&chip->lock); -+ -+ ret = __gen_74x164_write_config(chip); -+@@ -180,17 +198,19 @@ static int gen_74x164_remove(struct spi_ -+ return 0; -+ } -+ -++#ifdef CONFIG_OF -+ static const struct of_device_id gen_74x164_dt_ids[] = { -+ { .compatible = "fairchild,74hc595" }, -+ { .compatible = "nxp,74lvc594" }, -+ {}, -+ }; -+ MODULE_DEVICE_TABLE(of, gen_74x164_dt_ids); -++#endif -+ -+ static struct spi_driver gen_74x164_driver = { -+ .driver = { -+ .name = "74x164", -+- .of_match_table = gen_74x164_dt_ids, -++ .of_match_table = of_match_ptr(gen_74x164_dt_ids), -+ }, -+ .probe = gen_74x164_probe, -+ .remove = gen_74x164_remove, -+--- /dev/null -++++ b/include/linux/spi/74x164.h -+@@ -0,0 +1,13 @@ -++#ifndef LINUX_SPI_74X164_H -++#define LINUX_SPI_74X164_H -++ -++struct gen_74x164_chip_platform_data { -++ /* number assigned to the first GPIO */ -++ unsigned base; -++ /* number of chained registers */ -++ unsigned num_registers; -++ /* address of a buffer containing initial data */ -++ u8 *init_data; -++}; -++ -++#endif -+--- a/drivers/gpio/Kconfig -++++ b/drivers/gpio/Kconfig -+@@ -1252,7 +1252,6 @@ menu "SPI GPIO expanders" -+ -+ config GPIO_74X164 -+ tristate "74x164 serial-in/parallel-out 8-bits shift register" -+- depends on OF_GPIO -+ help -+ Driver for 74x164 compatible serial-in/parallel-out 8-outputs -+ shift registers. This driver can be used to provide access -diff --git a/target/linux/ar71xx/patches-4.14/452-gpio-add-gpio-latch-driver.patch b/target/linux/ar71xx/patches-4.14/452-gpio-add-gpio-latch-driver.patch -new file mode 100644 -index 0000000000..98e9123ce7 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/452-gpio-add-gpio-latch-driver.patch -@@ -0,0 +1,22 @@ -+--- a/drivers/gpio/Kconfig -++++ b/drivers/gpio/Kconfig -+@@ -1307,4 +1307,9 @@ config GPIO_NXP_74HC153 -+ Platform driver for NXP 74HC153 Dual 4-input Multiplexer. This -+ provides a GPIO interface supporting input mode only. -+ -++config GPIO_LATCH -++ tristate "GPIO latch driver" -++ help -++ Say yes here to enable a GPIO latch driver. -++ -+ endif -+--- a/drivers/gpio/Makefile -++++ b/drivers/gpio/Makefile -+@@ -63,6 +63,7 @@ obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz -+ obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o -+ obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o -+ obj-$(CONFIG_GPIO_INTEL_MID) += gpio-intel-mid.o -++obj-$(CONFIG_GPIO_LATCH) += gpio-latch.o -+ obj-$(CONFIG_GPIO_LOONGSON) += gpio-loongson.o -+ obj-$(CONFIG_GPIO_LP3943) += gpio-lp3943.o -+ obj-$(CONFIG_GPIO_LPC18XX) += gpio-lpc18xx.o -diff --git a/target/linux/ar71xx/patches-4.14/461-spi-ath79-add-fast-flash-read.patch b/target/linux/ar71xx/patches-4.14/461-spi-ath79-add-fast-flash-read.patch -new file mode 100644 -index 0000000000..45f6dfbf1b ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/461-spi-ath79-add-fast-flash-read.patch -@@ -0,0 +1,60 @@ -+--- a/drivers/spi/spi-ath79.c -++++ b/drivers/spi/spi-ath79.c -+@@ -102,9 +102,6 @@ static void ath79_spi_enable(struct ath7 -+ /* save CTRL register */ -+ sp->reg_ctrl = ath79_spi_rr(sp, AR71XX_SPI_REG_CTRL); -+ sp->ioc_base = ath79_spi_rr(sp, AR71XX_SPI_REG_IOC); -+- -+- /* TODO: setup speed? */ -+- ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43); -+ } -+ -+ static void ath79_spi_disable(struct ath79_spi *sp) -+@@ -204,6 +201,38 @@ static u32 ath79_spi_txrx_mode0(struct s -+ return ath79_spi_rr(sp, AR71XX_SPI_REG_RDS); -+ } -+ -++static bool ath79_spi_flash_read_supported(struct spi_device *spi) -++{ -++ if (spi->chip_select || gpio_is_valid(spi->cs_gpio)) -++ return false; -++ -++ return true; -++} -++ -++static int ath79_spi_read_flash_data(struct spi_device *spi, -++ struct spi_flash_read_message *msg) -++{ -++ struct ath79_spi *sp = ath79_spidev_to_sp(spi); -++ -++ if (msg->addr_width > 3) -++ return -EOPNOTSUPP; -++ -++ /* disable GPIO mode */ -++ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0); -++ -++ memcpy_fromio(msg->buf, sp->base + msg->from, msg->len); -++ -++ /* enable GPIO mode */ -++ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO); -++ -++ /* restore IOC register */ -++ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base); -++ -++ msg->retlen = msg->len; -++ -++ return 0; -++} -++ -+ static int ath79_spi_probe(struct platform_device *pdev) -+ { -+ struct spi_master *master; -+@@ -233,6 +262,8 @@ static int ath79_spi_probe(struct platfo -+ master->num_chipselect = pdata->num_chipselect; -+ master->cs_gpios = pdata->cs_gpios; -+ } -++ master->spi_flash_read = ath79_spi_read_flash_data; -++ master->flash_read_supported = ath79_spi_flash_read_supported; -+ -+ sp->bitbang.master = master; -+ sp->bitbang.chipselect = ath79_spi_chipselect; -diff --git a/target/linux/ar71xx/patches-4.14/470-MIPS-ath79-swizzle-pci-address-for-ar71xx.patch b/target/linux/ar71xx/patches-4.14/470-MIPS-ath79-swizzle-pci-address-for-ar71xx.patch -new file mode 100644 -index 0000000000..efd7d8d82b ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/470-MIPS-ath79-swizzle-pci-address-for-ar71xx.patch -@@ -0,0 +1,111 @@ -+--- /dev/null -++++ b/arch/mips/include/asm/mach-ath79/mangle-port.h -+@@ -0,0 +1,37 @@ -++/* -++ * Copyright (C) 2012 Gabor Juhos -++ * -++ * This file was derived from: inlude/asm-mips/mach-generic/mangle-port.h -++ * Copyright (C) 2003, 2004 Ralf Baechle -++ * -++ * This program is free software; you can redistribute it and/or modify it -++ * under the terms of the GNU General Public License version 2 as published -++ * by the Free Software Foundation. -++ */ -++ -++#ifndef __ASM_MACH_ATH79_MANGLE_PORT_H -++#define __ASM_MACH_ATH79_MANGLE_PORT_H -++ -++#ifdef CONFIG_PCI -++extern unsigned long (ath79_pci_swizzle_b)(unsigned long port); -++extern unsigned long (ath79_pci_swizzle_w)(unsigned long port); -++#else -++#define ath79_pci_swizzle_b(port) (port) -++#define ath79_pci_swizzle_w(port) (port) -++#endif -++ -++#define __swizzle_addr_b(port) ath79_pci_swizzle_b(port) -++#define __swizzle_addr_w(port) ath79_pci_swizzle_w(port) -++#define __swizzle_addr_l(port) (port) -++#define __swizzle_addr_q(port) (port) -++ -++# define ioswabb(a, x) (x) -++# define __mem_ioswabb(a, x) (x) -++# define ioswabw(a, x) (x) -++# define __mem_ioswabw(a, x) cpu_to_le16(x) -++# define ioswabl(a, x) (x) -++# define __mem_ioswabl(a, x) cpu_to_le32(x) -++# define ioswabq(a, x) (x) -++# define __mem_ioswabq(a, x) cpu_to_le64(x) -++ -++#endif /* __ASM_MACH_ATH79_MANGLE_PORT_H */ -+--- a/arch/mips/ath79/pci.c -++++ b/arch/mips/ath79/pci.c -+@@ -13,6 +13,7 @@ -+ */ -+ -+ #include -++#include -+ #include -+ #include -+ #include -+@@ -25,6 +26,9 @@ static int (*ath79_pci_plat_dev_init)(st -+ static const struct ath79_pci_irq *ath79_pci_irq_map; -+ static unsigned ath79_pci_nr_irqs; -+ -++static unsigned long (*__ath79_pci_swizzle_b)(unsigned long port); -++static unsigned long (*__ath79_pci_swizzle_w)(unsigned long port); -++ -+ static const struct ath79_pci_irq ar71xx_pci_irq_map[] = { -+ { -+ .slot = 17, -+@@ -212,12 +216,50 @@ ath79_register_pci_ar724x(int id, -+ return pdev; -+ } -+ -++static inline bool ar71xx_is_pci_addr(unsigned long port) -++{ -++ unsigned long phys = CPHYSADDR(port); -++ -++ return (phys >= AR71XX_PCI_MEM_BASE && -++ phys < AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE); -++} -++ -++static unsigned long ar71xx_pci_swizzle_b(unsigned long port) -++{ -++ return ar71xx_is_pci_addr(port) ? port ^ 3 : port; -++} -++ -++static unsigned long ar71xx_pci_swizzle_w(unsigned long port) -++{ -++ return ar71xx_is_pci_addr(port) ? port ^ 2 : port; -++} -++ -++unsigned long ath79_pci_swizzle_b(unsigned long port) -++{ -++ if (__ath79_pci_swizzle_b) -++ return __ath79_pci_swizzle_b(port); -++ -++ return port; -++} -++EXPORT_SYMBOL(ath79_pci_swizzle_b); -++ -++unsigned long ath79_pci_swizzle_w(unsigned long port) -++{ -++ if (__ath79_pci_swizzle_w) -++ return __ath79_pci_swizzle_w(port); -++ -++ return port; -++} -++EXPORT_SYMBOL(ath79_pci_swizzle_w); -++ -+ int __init ath79_register_pci(void) -+ { -+ struct platform_device *pdev = NULL; -+ -+ if (soc_is_ar71xx()) { -+ pdev = ath79_register_pci_ar71xx(); -++ __ath79_pci_swizzle_b = ar71xx_pci_swizzle_b; -++ __ath79_pci_swizzle_w = ar71xx_pci_swizzle_w; -+ } else if (soc_is_ar724x()) { -+ pdev = ath79_register_pci_ar724x(-1, -+ AR724X_PCI_CFG_BASE, -diff --git a/target/linux/ar71xx/patches-4.14/490-usb-ehci-add-quirks-for-qca-socs.patch b/target/linux/ar71xx/patches-4.14/490-usb-ehci-add-quirks-for-qca-socs.patch -new file mode 100644 -index 0000000000..f9ee417bb4 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/490-usb-ehci-add-quirks-for-qca-socs.patch -@@ -0,0 +1,103 @@ -+--- a/drivers/usb/host/ehci-hcd.c -++++ b/drivers/usb/host/ehci-hcd.c -+@@ -252,6 +252,37 @@ int ehci_reset(struct ehci_hcd *ehci) -+ command |= CMD_RESET; -+ dbg_cmd (ehci, "reset", command); -+ ehci_writel(ehci, command, &ehci->regs->command); -++ -++ if (ehci->qca_force_host_mode) { -++ u32 usbmode; -++ -++ udelay(1000); -++ -++ usbmode = ehci_readl(ehci, &ehci->regs->usbmode); -++ usbmode |= USBMODE_CM_HC | (1 << 4); -++ ehci_writel(ehci, usbmode, &ehci->regs->usbmode); -++ -++ ehci_dbg(ehci, "forced host mode, usbmode: %08x\n", -++ ehci_readl(ehci, &ehci->regs->usbmode)); -++ } -++ -++ if (ehci->qca_force_16bit_ptw) { -++ u32 port_status; -++ -++ udelay(1000); -++ -++ /* enable 16-bit UTMI interface */ -++ port_status = ehci_readl(ehci, &ehci->regs->port_status[0]); -++ port_status |= BIT(28); -++ ehci_writel(ehci, port_status, &ehci->regs->port_status[0]); -++ -++ ehci_dbg(ehci, "16-bit UTMI interface enabled, status: %08x\n", -++ ehci_readl(ehci, &ehci->regs->port_status[0])); -++ } -++ -++ if (ehci->reset_notifier) -++ ehci->reset_notifier(ehci_to_hcd(ehci)); -++ -+ ehci->rh_state = EHCI_RH_HALTED; -+ ehci->next_statechange = jiffies; -+ retval = ehci_handshake(ehci, &ehci->regs->command, -+--- a/drivers/usb/host/ehci.h -++++ b/drivers/usb/host/ehci.h -+@@ -232,6 +232,10 @@ struct ehci_hcd { /* one per controlle -+ unsigned need_oc_pp_cycle:1; /* MPC834X port power */ -+ unsigned imx28_write_fix:1; /* For Freescale i.MX28 */ -+ unsigned ignore_oc:1; -++ unsigned qca_force_host_mode:1; -++ unsigned qca_force_16bit_ptw:1; /* force 16 bit UTMI */ -++ -++ void (*reset_notifier)(struct usb_hcd *hcd); -+ -+ /* required for usb32 quirk */ -+ #define OHCI_CTRL_HCFS (3 << 6) -+--- a/include/linux/usb/ehci_pdriver.h -++++ b/include/linux/usb/ehci_pdriver.h -+@@ -50,6 +50,8 @@ struct usb_ehci_pdata { -+ unsigned reset_on_resume:1; -+ unsigned dma_mask_64:1; -+ unsigned ignore_oc:1; -++ unsigned qca_force_host_mode:1; -++ unsigned qca_force_16bit_ptw:1; -+ -+ /* Turn on all power and clocks */ -+ int (*power_on)(struct platform_device *pdev); -+@@ -59,6 +61,7 @@ struct usb_ehci_pdata { -+ * turn off everything else */ -+ void (*power_suspend)(struct platform_device *pdev); -+ int (*pre_setup)(struct usb_hcd *hcd); -++ void (*reset_notifier)(struct platform_device *pdev); -+ }; -+ -+ #endif /* __USB_CORE_EHCI_PDRIVER_H */ -+--- a/drivers/usb/host/ehci-platform.c -++++ b/drivers/usb/host/ehci-platform.c -+@@ -53,6 +53,14 @@ struct ehci_platform_priv { -+ -+ static const char hcd_name[] = "ehci-platform"; -+ -++static void ehci_platform_reset_notifier(struct usb_hcd *hcd) -++{ -++ struct platform_device *pdev = to_platform_device(hcd->self.controller); -++ struct usb_ehci_pdata *pdata = pdev->dev.platform_data; -++ -++ pdata->reset_notifier(pdev); -++} -++ -+ static int ehci_platform_reset(struct usb_hcd *hcd) -+ { -+ struct platform_device *pdev = to_platform_device(hcd->self.controller); -+@@ -265,6 +273,13 @@ static int ehci_platform_probe(struct pl -+ priv->reset_on_resume = true; -+ if (pdata->ignore_oc) -+ ehci->ignore_oc = 1; -++ if (pdata->qca_force_host_mode) -++ ehci->qca_force_host_mode = 1; -++ if (pdata->qca_force_16bit_ptw) -++ ehci->qca_force_16bit_ptw = 1; -++ -++ if (pdata->reset_notifier) -++ ehci->reset_notifier = ehci_platform_reset_notifier; -+ -+ #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO -+ if (ehci->big_endian_mmio) { -diff --git a/target/linux/ar71xx/patches-4.14/500-MIPS-fw-myloader.patch b/target/linux/ar71xx/patches-4.14/500-MIPS-fw-myloader.patch -new file mode 100644 -index 0000000000..1fdd05a4d9 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/500-MIPS-fw-myloader.patch -@@ -0,0 +1,22 @@ -+--- a/arch/mips/Makefile -++++ b/arch/mips/Makefile -+@@ -228,6 +228,7 @@ cflags-$(toolchain-virt) += -DTOOLCHAIN -+ # -+ libs-$(CONFIG_FW_ARC) += arch/mips/fw/arc/ -+ libs-$(CONFIG_FW_CFE) += arch/mips/fw/cfe/ -++libs-$(CONFIG_MYLOADER) += arch/mips/fw/myloader/ -+ libs-$(CONFIG_FW_SNIPROM) += arch/mips/fw/sni/ -+ libs-y += arch/mips/fw/lib/ -+ -+--- a/arch/mips/Kconfig -++++ b/arch/mips/Kconfig -+@@ -1153,6 +1153,9 @@ config MIPS_MSC -+ config MIPS_NILE4 -+ bool -+ -++config MYLOADER -++ bool -++ -+ config SYNC_R4K -+ bool -+ -diff --git a/target/linux/ar71xx/patches-4.14/501-MIPS-ath79-add-mac-argument-to-ath79_register_wmac.patch b/target/linux/ar71xx/patches-4.14/501-MIPS-ath79-add-mac-argument-to-ath79_register_wmac.patch -new file mode 100644 -index 0000000000..12ab3b50d6 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/501-MIPS-ath79-add-mac-argument-to-ath79_register_wmac.patch -@@ -0,0 +1,70 @@ -+--- a/arch/mips/ath79/dev-wmac.c -++++ b/arch/mips/ath79/dev-wmac.c -+@@ -15,6 +15,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ -+@@ -22,6 +23,7 @@ -+ #include -+ #include "dev-wmac.h" -+ -++static u8 ath79_wmac_mac[ETH_ALEN]; -+ static struct ath9k_platform_data ath79_wmac_data; -+ -+ static struct resource ath79_wmac_resources[] = { -+@@ -161,7 +163,7 @@ static void qca955x_wmac_setup(void) -+ ath79_wmac_data.is_clk_25mhz = true; -+ } -+ -+-void __init ath79_register_wmac(u8 *cal_data) -++void __init ath79_register_wmac(u8 *cal_data, u8 *mac_addr) -+ { -+ if (soc_is_ar913x()) -+ ar913x_wmac_setup(); -+@@ -178,5 +180,10 @@ void __init ath79_register_wmac(u8 *cal_ -+ memcpy(ath79_wmac_data.eeprom_data, cal_data, -+ sizeof(ath79_wmac_data.eeprom_data)); -+ -++ if (mac_addr) { -++ memcpy(ath79_wmac_mac, mac_addr, sizeof(ath79_wmac_mac)); -++ ath79_wmac_data.macaddr = ath79_wmac_mac; -++ } -++ -+ platform_device_register(&ath79_wmac_device); -+ } -+--- a/arch/mips/ath79/dev-wmac.h -++++ b/arch/mips/ath79/dev-wmac.h -+@@ -12,6 +12,6 @@ -+ #ifndef _ATH79_DEV_WMAC_H -+ #define _ATH79_DEV_WMAC_H -+ -+-void ath79_register_wmac(u8 *cal_data); -++void ath79_register_wmac(u8 *cal_data, u8 *mac_addr); -+ -+ #endif /* _ATH79_DEV_WMAC_H */ -+--- a/arch/mips/ath79/mach-db120.c -++++ b/arch/mips/ath79/mach-db120.c -+@@ -128,7 +128,7 @@ static void __init db120_setup(void) -+ ath79_register_spi(&db120_spi_data, db120_spi_info, -+ ARRAY_SIZE(db120_spi_info)); -+ ath79_register_usb(); -+- ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET); -++ ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET, NULL); -+ db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET); -+ } -+ -+--- a/arch/mips/ath79/mach-ap121.c -++++ b/arch/mips/ath79/mach-ap121.c -+@@ -85,7 +85,7 @@ static void __init ap121_setup(void) -+ ath79_register_spi(&ap121_spi_data, ap121_spi_info, -+ ARRAY_SIZE(ap121_spi_info)); -+ ath79_register_usb(); -+- ath79_register_wmac(cal_data); -++ ath79_register_wmac(cal_data, NULL); -+ } -+ -+ MIPS_MACHINE(ATH79_MACH_AP121, "AP121", "Atheros AP121 reference board", -diff --git a/target/linux/ar71xx/patches-4.14/504-MIPS-ath79-add-ath79_device_reset_get.patch b/target/linux/ar71xx/patches-4.14/504-MIPS-ath79-add-ath79_device_reset_get.patch -new file mode 100644 -index 0000000000..c0e96b2729 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/504-MIPS-ath79-add-ath79_device_reset_get.patch -@@ -0,0 +1,42 @@ -+--- a/arch/mips/include/asm/mach-ath79/ath79.h -++++ b/arch/mips/include/asm/mach-ath79/ath79.h -+@@ -145,6 +145,7 @@ static inline u32 ath79_reset_rr(unsigne -+ -+ void ath79_device_reset_set(u32 mask); -+ void ath79_device_reset_clear(u32 mask); -++u32 ath79_device_reset_get(u32 mask); -+ -+ void ath79_cpu_irq_init(unsigned irq_wb_chan2, unsigned irq_wb_chan3); -+ void ath79_misc_irq_init(void __iomem *regs, int irq, -+--- a/arch/mips/ath79/common.c -++++ b/arch/mips/ath79/common.c -+@@ -142,3 +142,29 @@ void ath79_device_reset_clear(u32 mask) -+ spin_unlock_irqrestore(&ath79_device_reset_lock, flags); -+ } -+ EXPORT_SYMBOL_GPL(ath79_device_reset_clear); -++ -++u32 ath79_device_reset_get(u32 mask) -++{ -++ unsigned long flags; -++ u32 reg; -++ u32 ret; -++ -++ if (soc_is_ar71xx()) -++ reg = AR71XX_RESET_REG_RESET_MODULE; -++ else if (soc_is_ar724x()) -++ reg = AR724X_RESET_REG_RESET_MODULE; -++ else if (soc_is_ar913x()) -++ reg = AR913X_RESET_REG_RESET_MODULE; -++ else if (soc_is_ar933x()) -++ reg = AR933X_RESET_REG_RESET_MODULE; -++ else if (soc_is_ar934x()) -++ reg = AR934X_RESET_REG_RESET_MODULE; -++ else -++ BUG(); -++ -++ spin_lock_irqsave(&ath79_device_reset_lock, flags); -++ ret = ath79_reset_rr(reg); -++ spin_unlock_irqrestore(&ath79_device_reset_lock, flags); -++ return ret; -++} -++EXPORT_SYMBOL_GPL(ath79_device_reset_get); -diff --git a/target/linux/ar71xx/patches-4.14/505-MIPS-ath79-add-ath79_gpio_function_select.patch b/target/linux/ar71xx/patches-4.14/505-MIPS-ath79-add-ath79_gpio_function_select.patch -new file mode 100644 -index 0000000000..278e781539 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/505-MIPS-ath79-add-ath79_gpio_function_select.patch -@@ -0,0 +1,39 @@ -+--- a/arch/mips/ath79/common.h -++++ b/arch/mips/ath79/common.h -+@@ -27,6 +27,7 @@ void ath79_ddr_ctrl_init(void); -+ void ath79_gpio_function_enable(u32 mask); -+ void ath79_gpio_function_disable(u32 mask); -+ void ath79_gpio_function_setup(u32 set, u32 clear); -++void ath79_gpio_output_select(unsigned gpio, u8 val); -+ void ath79_gpio_init(void); -+ -+ #endif /* __ATH79_COMMON_H */ -+--- a/arch/mips/ath79/gpio.c -++++ b/arch/mips/ath79/gpio.c -+@@ -57,3 +57,26 @@ void ath79_gpio_function_disable(u32 mas -+ { -+ ath79_gpio_function_setup(0, mask); -+ } -++ -++void __init ath79_gpio_output_select(unsigned gpio, u8 val) -++{ -++ void __iomem *base = ath79_gpio_base; -++ unsigned int reg; -++ u32 t, s; -++ -++ BUG_ON(!soc_is_ar934x()); -++ -++ if (gpio >= AR934X_GPIO_COUNT) -++ return; -++ -++ reg = AR934X_GPIO_REG_OUT_FUNC0 + 4 * (gpio / 4); -++ s = 8 * (gpio % 4); -++ -++ t = __raw_readl(base + reg); -++ t &= ~(0xff << s); -++ t |= val << s; -++ __raw_writel(t, base + reg); -++ -++ /* flush write */ -++ (void) __raw_readl(base + reg); -++} -diff --git a/target/linux/ar71xx/patches-4.14/506-MIPS-ath79-prom-parse-redboot-args.patch b/target/linux/ar71xx/patches-4.14/506-MIPS-ath79-prom-parse-redboot-args.patch -new file mode 100644 -index 0000000000..46beeffeea ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/506-MIPS-ath79-prom-parse-redboot-args.patch -@@ -0,0 +1,42 @@ -+--- a/arch/mips/ath79/prom.c -++++ b/arch/mips/ath79/prom.c -+@@ -22,10 +22,39 @@ -+ -+ #include "common.h" -+ -++static char ath79_cmdline_buf[COMMAND_LINE_SIZE] __initdata; -++ -++static void __init ath79_prom_append_cmdline(const char *name, -++ const char *value) -++{ -++ snprintf(ath79_cmdline_buf, sizeof(ath79_cmdline_buf), -++ " %s=%s", name, value); -++ strlcat(arcs_cmdline, ath79_cmdline_buf, sizeof(arcs_cmdline)); -++} -++ -+ void __init prom_init(void) -+ { -++ const char *env; -++ -+ fw_init_cmdline(); -+ -++ env = fw_getenv("ethaddr"); -++ if (env) -++ ath79_prom_append_cmdline("ethaddr", env); -++ -++ env = fw_getenv("board"); -++ if (env) { -++ /* Workaround for buggy bootloaders */ -++ if (strcmp(env, "RouterStation") == 0 || -++ strcmp(env, "Ubiquiti AR71xx-based board") == 0) -++ env = "UBNT-RS"; -++ -++ if (strcmp(env, "RouterStation PRO") == 0) -++ env = "UBNT-RSPRO"; -++ -++ ath79_prom_append_cmdline("board", env); -++ } -++ -+ #ifdef CONFIG_BLK_DEV_INITRD -+ /* Read the initrd address from the firmware environment */ -+ initrd_start = fw_getenvl("initrd_start"); -diff --git a/target/linux/ar71xx/patches-4.14/507-MIPS-ath79-prom-add-myloader-support.patch b/target/linux/ar71xx/patches-4.14/507-MIPS-ath79-prom-add-myloader-support.patch -new file mode 100644 -index 0000000000..17a97335d2 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/507-MIPS-ath79-prom-add-myloader-support.patch -@@ -0,0 +1,55 @@ -+--- a/arch/mips/ath79/prom.c -++++ b/arch/mips/ath79/prom.c -+@@ -19,6 +19,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "common.h" -+ -+@@ -32,10 +33,44 @@ static void __init ath79_prom_append_cmd -+ strlcat(arcs_cmdline, ath79_cmdline_buf, sizeof(arcs_cmdline)); -+ } -+ -++static int __init ath79_prom_init_myloader(void) -++{ -++ struct myloader_info *mylo; -++ char mac_buf[32]; -++ unsigned char *mac; -++ -++ mylo = myloader_get_info(); -++ if (!mylo) -++ return 0; -++ -++ switch (mylo->did) { -++ case DEVID_COMPEX_WP543: -++ ath79_prom_append_cmdline("board", "WP543"); -++ break; -++ case DEVID_COMPEX_WPE72: -++ ath79_prom_append_cmdline("board", "WPE72"); -++ break; -++ default: -++ pr_warn("prom: unknown device id: %x\n", mylo->did); -++ return 0; -++ } -++ -++ mac = mylo->macs[0]; -++ snprintf(mac_buf, sizeof(mac_buf), "%02x:%02x:%02x:%02x:%02x:%02x", -++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); -++ -++ ath79_prom_append_cmdline("ethaddr", mac_buf); -++ -++ return 1; -++} -++ -+ void __init prom_init(void) -+ { -+ const char *env; -+ -++ if (ath79_prom_init_myloader()) -++ return; -++ -+ fw_init_cmdline(); -+ -+ env = fw_getenv("ethaddr"); -diff --git a/target/linux/ar71xx/patches-4.14/508-MIPS-ath79-prom-image-command-line-hack.patch b/target/linux/ar71xx/patches-4.14/508-MIPS-ath79-prom-image-command-line-hack.patch -new file mode 100644 -index 0000000000..cfa5e72eec ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/508-MIPS-ath79-prom-image-command-line-hack.patch -@@ -0,0 +1,73 @@ -+--- a/arch/mips/ath79/prom.c -++++ b/arch/mips/ath79/prom.c -+@@ -33,6 +33,41 @@ static void __init ath79_prom_append_cmd -+ strlcat(arcs_cmdline, ath79_cmdline_buf, sizeof(arcs_cmdline)); -+ } -+ -++#ifdef CONFIG_IMAGE_CMDLINE_HACK -++extern char __image_cmdline[]; -++ -++static int __init ath79_use_image_cmdline(void) -++{ -++ char *p = __image_cmdline; -++ int replace = 0; -++ -++ if (*p == '-') { -++ replace = 1; -++ p++; -++ } -++ -++ if (*p == '\0') -++ return 0; -++ -++ if (replace) { -++ strlcpy(arcs_cmdline, p, sizeof(arcs_cmdline)); -++ } else { -++ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); -++ strlcat(arcs_cmdline, p, sizeof(arcs_cmdline)); -++ } -++ -++ /* Validate and setup environment pointer */ -++ if (fw_arg2 < CKSEG0) -++ _fw_envp = NULL; -++ else -++ _fw_envp = (int *)fw_arg2; -++ -++ return 1; -++} -++#else -++static inline int ath79_use_image_cmdline(void) { return 0; } -++#endif -++ -+ static int __init ath79_prom_init_myloader(void) -+ { -+ struct myloader_info *mylo; -+@@ -61,6 +96,8 @@ static int __init ath79_prom_init_myload -+ -+ ath79_prom_append_cmdline("ethaddr", mac_buf); -+ -++ ath79_use_image_cmdline(); -++ -+ return 1; -+ } -+ -+@@ -71,7 +108,8 @@ void __init prom_init(void) -+ if (ath79_prom_init_myloader()) -+ return; -+ -+- fw_init_cmdline(); -++ if (!ath79_use_image_cmdline()) -++ fw_init_cmdline(); -+ -+ env = fw_getenv("ethaddr"); -+ if (env) -+--- a/arch/mips/fw/lib/cmdline.c -++++ b/arch/mips/fw/lib/cmdline.c -+@@ -35,6 +35,7 @@ void __init fw_init_cmdline(void) -+ else -+ _fw_envp = (int *)fw_arg2; -+ -++ arcs_cmdline[0] = '\0'; -+ for (i = 1; i < fw_argc; i++) { -+ strlcat(arcs_cmdline, fw_argv(i), COMMAND_LINE_SIZE); -+ if (i < (fw_argc - 1)) -diff --git a/target/linux/ar71xx/patches-4.14/509-MIPS-ath79-process-board-kernel-option.patch b/target/linux/ar71xx/patches-4.14/509-MIPS-ath79-process-board-kernel-option.patch -new file mode 100644 -index 0000000000..139b09c1b0 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/509-MIPS-ath79-process-board-kernel-option.patch -@@ -0,0 +1,11 @@ -+--- a/arch/mips/ath79/setup.c -++++ b/arch/mips/ath79/setup.c -+@@ -277,6 +277,8 @@ void __init plat_time_init(void) -+ mips_hpt_frequency = cpu_clk_rate / 2; -+ } -+ -++__setup("board=", mips_machtype_setup); -++ -+ static int __init ath79_setup(void) -+ { -+ if (mips_machtype == ATH79_MACH_GENERIC_OF) -diff --git a/target/linux/ar71xx/patches-4.14/510-MIPS-ath79-init-gpio-pin-of-wmac-device.patch b/target/linux/ar71xx/patches-4.14/510-MIPS-ath79-init-gpio-pin-of-wmac-device.patch -new file mode 100644 -index 0000000000..2d2235e292 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/510-MIPS-ath79-init-gpio-pin-of-wmac-device.patch -@@ -0,0 +1,14 @@ -+--- a/arch/mips/ath79/dev-wmac.c -++++ b/arch/mips/ath79/dev-wmac.c -+@@ -24,7 +24,10 @@ -+ #include "dev-wmac.h" -+ -+ static u8 ath79_wmac_mac[ETH_ALEN]; -+-static struct ath9k_platform_data ath79_wmac_data; -++ -++static struct ath9k_platform_data ath79_wmac_data = { -++ .led_pin = -1, -++}; -+ -+ static struct resource ath79_wmac_resources[] = { -+ { -diff --git a/target/linux/ar71xx/patches-4.14/520-MIPS-ath79-enable-UART-function.patch b/target/linux/ar71xx/patches-4.14/520-MIPS-ath79-enable-UART-function.patch -new file mode 100644 -index 0000000000..c8649b7494 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/520-MIPS-ath79-enable-UART-function.patch -@@ -0,0 +1,18 @@ -+--- a/arch/mips/ath79/dev-common.c -++++ b/arch/mips/ath79/dev-common.c -+@@ -81,6 +81,15 @@ void __init ath79_register_uart(void) -+ -+ uart_clk_rate = ath79_get_sys_clk_rate("uart"); -+ -++ if (soc_is_ar71xx()) -++ ath79_gpio_function_enable(AR71XX_GPIO_FUNC_UART_EN); -++ else if (soc_is_ar724x()) -++ ath79_gpio_function_enable(AR724X_GPIO_FUNC_UART_EN); -++ else if (soc_is_ar913x()) -++ ath79_gpio_function_enable(AR913X_GPIO_FUNC_UART_EN); -++ else if (soc_is_ar933x()) -++ ath79_gpio_function_enable(AR933X_GPIO_FUNC_UART_EN); -++ -+ if (soc_is_ar71xx() || -+ soc_is_ar724x() || -+ soc_is_ar913x() || -diff --git a/target/linux/ar71xx/patches-4.14/521-MIPS-ath79-enable-UART-for-early_serial.patch b/target/linux/ar71xx/patches-4.14/521-MIPS-ath79-enable-UART-for-early_serial.patch -new file mode 100644 -index 0000000000..e546ff26fe ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/521-MIPS-ath79-enable-UART-for-early_serial.patch -@@ -0,0 +1,61 @@ -+--- a/arch/mips/ath79/early_printk.c -++++ b/arch/mips/ath79/early_printk.c -+@@ -58,6 +58,46 @@ static void prom_putchar_dummy(unsigned -+ /* nothing to do */ -+ } -+ -++static void prom_enable_uart(u32 id) -++{ -++ void __iomem *gpio_base; -++ u32 uart_en; -++ u32 t; -++ -++ switch (id) { -++ case REV_ID_MAJOR_AR71XX: -++ uart_en = AR71XX_GPIO_FUNC_UART_EN; -++ break; -++ -++ case REV_ID_MAJOR_AR7240: -++ case REV_ID_MAJOR_AR7241: -++ case REV_ID_MAJOR_AR7242: -++ uart_en = AR724X_GPIO_FUNC_UART_EN; -++ break; -++ -++ case REV_ID_MAJOR_AR913X: -++ uart_en = AR913X_GPIO_FUNC_UART_EN; -++ break; -++ -++ case REV_ID_MAJOR_AR9330: -++ case REV_ID_MAJOR_AR9331: -++ uart_en = AR933X_GPIO_FUNC_UART_EN; -++ break; -++ -++ case REV_ID_MAJOR_AR9341: -++ case REV_ID_MAJOR_AR9342: -++ case REV_ID_MAJOR_AR9344: -++ /* TODO */ -++ default: -++ return; -++ } -++ -++ gpio_base = (void __iomem *)(KSEG1ADDR(AR71XX_GPIO_BASE)); -++ t = __raw_readl(gpio_base + AR71XX_GPIO_REG_FUNC); -++ t |= uart_en; -++ __raw_writel(t, gpio_base + AR71XX_GPIO_REG_FUNC); -++} -++ -+ static void prom_putchar_init(void) -+ { -+ void __iomem *base; -+@@ -88,8 +128,10 @@ static void prom_putchar_init(void) -+ -+ default: -+ _prom_putchar = prom_putchar_dummy; -+- break; -++ return; -+ } -++ -++ prom_enable_uart(id); -+ } -+ -+ void prom_putchar(unsigned char ch) -diff --git a/target/linux/ar71xx/patches-4.14/522-MIPS-ath79-add-ath79_wmac_register_simple-helper.patch b/target/linux/ar71xx/patches-4.14/522-MIPS-ath79-add-ath79_wmac_register_simple-helper.patch -new file mode 100644 -index 0000000000..2d5559cb9d ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/522-MIPS-ath79-add-ath79_wmac_register_simple-helper.patch -@@ -0,0 +1,21 @@ -+--- a/arch/mips/ath79/dev-wmac.c -++++ b/arch/mips/ath79/dev-wmac.c -+@@ -190,3 +190,9 @@ void __init ath79_register_wmac(u8 *cal_ -+ -+ platform_device_register(&ath79_wmac_device); -+ } -++ -++void __init ath79_register_wmac_simple(void) -++{ -++ ath79_register_wmac(NULL, NULL); -++ ath79_wmac_data.eeprom_name = "soc_wmac.eeprom"; -++} -+--- a/arch/mips/ath79/dev-wmac.h -++++ b/arch/mips/ath79/dev-wmac.h -+@@ -13,5 +13,6 @@ -+ #define _ATH79_DEV_WMAC_H -+ -+ void ath79_register_wmac(u8 *cal_data, u8 *mac_addr); -++void ath79_register_wmac_simple(void); -+ -+ #endif /* _ATH79_DEV_WMAC_H */ -diff --git a/target/linux/ar71xx/patches-4.14/523-MIPS-ath79-OTP-support.patch b/target/linux/ar71xx/patches-4.14/523-MIPS-ath79-OTP-support.patch -new file mode 100644 -index 0000000000..d11d418f17 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/523-MIPS-ath79-OTP-support.patch -@@ -0,0 +1,192 @@ -+--- a/arch/mips/ath79/dev-wmac.c -++++ b/arch/mips/ath79/dev-wmac.c -+@@ -166,6 +166,149 @@ static void qca955x_wmac_setup(void) -+ ath79_wmac_data.is_clk_25mhz = true; -+ } -+ -++#define AR93XX_WMAC_SIZE \ -++ (soc_is_ar934x() ? AR934X_WMAC_SIZE : AR933X_WMAC_SIZE) -++#define AR93XX_WMAC_BASE \ -++ (soc_is_ar934x() ? AR934X_WMAC_BASE : AR933X_WMAC_BASE) -++ -++#define AR93XX_OTP_BASE \ -++ (soc_is_ar934x() ? AR934X_OTP_BASE : AR9300_OTP_BASE) -++#define AR93XX_OTP_STATUS \ -++ (soc_is_ar934x() ? AR934X_OTP_STATUS : AR9300_OTP_STATUS) -++#define AR93XX_OTP_READ_DATA \ -++ (soc_is_ar934x() ? AR934X_OTP_READ_DATA : AR9300_OTP_READ_DATA) -++ -++static bool __init -++ar93xx_wmac_otp_read_word(void __iomem *base, int addr, u32 *data) -++{ -++ int timeout = 1000; -++ u32 val; -++ -++ __raw_readl(base + AR93XX_OTP_BASE + (4 * addr)); -++ while (timeout--) { -++ val = __raw_readl(base + AR93XX_OTP_STATUS); -++ if ((val & AR9300_OTP_STATUS_TYPE) == AR9300_OTP_STATUS_VALID) -++ break; -++ -++ udelay(10); -++ } -++ -++ if (!timeout) -++ return false; -++ -++ *data = __raw_readl(base + AR93XX_OTP_READ_DATA); -++ return true; -++} -++ -++static bool __init -++ar93xx_wmac_otp_read(void __iomem *base, int addr, u8 *dest, int len) -++{ -++ u32 data; -++ int i; -++ -++ for (i = 0; i < len; i++) { -++ int offset = 8 * ((addr - i) % 4); -++ -++ if (!ar93xx_wmac_otp_read_word(base, (addr - i) / 4, &data)) -++ return false; -++ -++ dest[i] = (data >> offset) & 0xff; -++ } -++ -++ return true; -++} -++ -++static bool __init -++ar93xx_wmac_otp_uncompress(void __iomem *base, int addr, int len, u8 *dest, -++ int dest_start, int dest_len) -++{ -++ int dest_bytes = 0; -++ int offset = 0; -++ int end = addr - len; -++ u8 hdr[2]; -++ -++ while (addr > end) { -++ if (!ar93xx_wmac_otp_read(base, addr, hdr, 2)) -++ return false; -++ -++ addr -= 2; -++ offset += hdr[0]; -++ -++ if (offset <= dest_start + dest_len && -++ offset + len >= dest_start) { -++ int data_offset = 0; -++ int dest_offset = 0; -++ int copy_len; -++ -++ if (offset < dest_start) -++ data_offset = dest_start - offset; -++ else -++ dest_offset = offset - dest_start; -++ -++ copy_len = len - data_offset; -++ if (copy_len > dest_len - dest_offset) -++ copy_len = dest_len - dest_offset; -++ -++ ar93xx_wmac_otp_read(base, addr - data_offset, -++ dest + dest_offset, -++ copy_len); -++ -++ dest_bytes += copy_len; -++ } -++ addr -= hdr[1]; -++ } -++ return !!dest_bytes; -++} -++ -++bool __init ar93xx_wmac_read_mac_address(u8 *dest) -++{ -++ void __iomem *base; -++ bool ret = false; -++ int addr = 0x1ff; -++ unsigned int len; -++ u32 hdr_u32; -++ u8 *hdr = (u8 *) &hdr_u32; -++ u8 mac[6] = { 0x00, 0x02, 0x03, 0x04, 0x05, 0x06 }; -++ int mac_start = 2, mac_end = 8; -++ -++ BUG_ON(!soc_is_ar933x() && !soc_is_ar934x()); -++ base = ioremap_nocache(AR93XX_WMAC_BASE, AR93XX_WMAC_SIZE); -++ while (addr > sizeof(hdr_u32)) { -++ if (!ar93xx_wmac_otp_read(base, addr, hdr, sizeof(hdr_u32))) -++ break; -++ -++ if (hdr_u32 == 0 || hdr_u32 == ~0) -++ break; -++ -++ len = (hdr[1] << 4) | (hdr[2] >> 4); -++ addr -= 4; -++ -++ switch (hdr[0] >> 5) { -++ case 0: -++ if (len < mac_end) -++ break; -++ -++ ar93xx_wmac_otp_read(base, addr - mac_start, mac, 6); -++ ret = true; -++ break; -++ case 3: -++ ret |= ar93xx_wmac_otp_uncompress(base, addr, len, mac, -++ mac_start, 6); -++ break; -++ default: -++ break; -++ } -++ -++ addr -= len + 2; -++ } -++ -++ iounmap(base); -++ if (ret) -++ memcpy(dest, mac, 6); -++ -++ return ret; -++} -++ -+ void __init ath79_register_wmac(u8 *cal_data, u8 *mac_addr) -+ { -+ if (soc_is_ar913x()) -+--- a/arch/mips/ath79/dev-wmac.h -++++ b/arch/mips/ath79/dev-wmac.h -+@@ -14,5 +14,6 @@ -+ -+ void ath79_register_wmac(u8 *cal_data, u8 *mac_addr); -+ void ath79_register_wmac_simple(void); -++bool ar93xx_wmac_read_mac_address(u8 *dest); -+ -+ #endif /* _ATH79_DEV_WMAC_H */ -+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -+@@ -112,6 +112,14 @@ -+ #define QCA955X_EHCI1_BASE 0x1b400000 -+ #define QCA955X_EHCI_SIZE 0x1000 -+ -++#define AR9300_OTP_BASE 0x14000 -++#define AR9300_OTP_STATUS 0x15f18 -++#define AR9300_OTP_STATUS_TYPE 0x7 -++#define AR9300_OTP_STATUS_VALID 0x4 -++#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2 -++#define AR9300_OTP_STATUS_SM_BUSY 0x1 -++#define AR9300_OTP_READ_DATA 0x15f1c -++ -+ /* -+ * DDR_CTRL block -+ */ -+@@ -149,6 +157,13 @@ -+ #define AR934X_DDR_REG_FLUSH_PCIE 0xa8 -+ #define AR934X_DDR_REG_FLUSH_WMAC 0xac -+ -++#define AR934X_OTP_BASE 0x30000 -++#define AR934X_OTP_STATUS 0x31018 -++#define AR934X_OTP_READ_DATA 0x3101c -++#define AR934X_OTP_INTF2_ADDRESS 0x31008 -++#define AR934X_OTP_INTF3_ADDRESS 0x3100c -++#define AR934X_OTP_PGENB_SETUP_HOLD_TIME_ADDRESS 0x31034 -++ -+ /* -+ * PLL block -+ */ -diff --git a/target/linux/ar71xx/patches-4.14/524-MIPS-ath79-add-ath79_wmac_disable_25ghz-helpers.patch b/target/linux/ar71xx/patches-4.14/524-MIPS-ath79-add-ath79_wmac_disable_25ghz-helpers.patch -new file mode 100644 -index 0000000000..91e037e247 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/524-MIPS-ath79-add-ath79_wmac_disable_25ghz-helpers.patch -@@ -0,0 +1,31 @@ -+--- a/arch/mips/ath79/dev-wmac.c -++++ b/arch/mips/ath79/dev-wmac.c -+@@ -309,6 +309,16 @@ bool __init ar93xx_wmac_read_mac_address -+ return ret; -+ } -+ -++void __init ath79_wmac_disable_2ghz(void) -++{ -++ ath79_wmac_data.disable_2ghz = true; -++} -++ -++void __init ath79_wmac_disable_5ghz(void) -++{ -++ ath79_wmac_data.disable_5ghz = true; -++} -++ -+ void __init ath79_register_wmac(u8 *cal_data, u8 *mac_addr) -+ { -+ if (soc_is_ar913x()) -+--- a/arch/mips/ath79/dev-wmac.h -++++ b/arch/mips/ath79/dev-wmac.h -+@@ -14,6 +14,9 @@ -+ -+ void ath79_register_wmac(u8 *cal_data, u8 *mac_addr); -+ void ath79_register_wmac_simple(void); -++void ath79_wmac_disable_2ghz(void); -++void ath79_wmac_disable_5ghz(void); -++ -+ bool ar93xx_wmac_read_mac_address(u8 *dest); -+ -+ #endif /* _ATH79_DEV_WMAC_H */ -diff --git a/target/linux/ar71xx/patches-4.14/525-MIPS-ath79-enable-qca-usb-quirks.patch b/target/linux/ar71xx/patches-4.14/525-MIPS-ath79-enable-qca-usb-quirks.patch -new file mode 100644 -index 0000000000..3cafbe290c ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/525-MIPS-ath79-enable-qca-usb-quirks.patch -@@ -0,0 +1,101 @@ -+--- a/arch/mips/ath79/dev-usb.c -++++ b/arch/mips/ath79/dev-usb.c -+@@ -37,6 +37,8 @@ static struct usb_ehci_pdata ath79_ehci_ -+ static struct usb_ehci_pdata ath79_ehci_pdata_v2 = { -+ .caps_offset = 0x100, -+ .has_tt = 1, -++ .qca_force_host_mode = 1, -++ .qca_force_16bit_ptw = 1, -+ }; -+ -+ static void __init ath79_usb_register(const char *name, int id, -+@@ -159,6 +161,9 @@ static void __init ar913x_usb_setup(void -+ ath79_device_reset_clear(AR913X_RESET_USB_PHY); -+ mdelay(10); -+ -++ ath79_ehci_pdata_v2.qca_force_host_mode = 0; -++ ath79_ehci_pdata_v2.qca_force_16bit_ptw = 0; -++ -+ ath79_usb_register("ehci-platform", -1, -+ AR913X_EHCI_BASE, AR913X_EHCI_SIZE, -+ ATH79_CPU_IRQ(3), -+@@ -182,14 +187,34 @@ static void __init ar933x_usb_setup(void -+ &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); -+ } -+ -+-static void __init ar934x_usb_setup(void) -++static void enable_tx_tx_idp_violation_fix(unsigned base) -+ { -+- u32 bootstrap; -++ void __iomem *phy_reg; -++ u32 t; -++ -++ phy_reg = ioremap(base, 4); -++ if (!phy_reg) -++ return; -++ -++ t = ioread32(phy_reg); -++ t &= ~0xff; -++ t |= 0x58; -++ iowrite32(t, phy_reg); -++ -++ iounmap(phy_reg); -++} -+ -+- bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); -+- if (bootstrap & AR934X_BOOTSTRAP_USB_MODE_DEVICE) -++static void ar934x_usb_reset_notifier(struct platform_device *pdev) -++{ -++ if (pdev->id != -1) -+ return; -+ -++ enable_tx_tx_idp_violation_fix(0x18116c94); -++ dev_info(&pdev->dev, "TX-TX IDP fix enabled\n"); -++} -++ -++static void __init ar934x_usb_setup(void) -++{ -+ ath79_device_reset_set(AR934X_RESET_USBSUS_OVERRIDE); -+ udelay(1000); -+ -+@@ -202,14 +227,40 @@ static void __init ar934x_usb_setup(void -+ ath79_device_reset_clear(AR934X_RESET_USB_HOST); -+ udelay(1000); -+ -++ if (ath79_soc_rev >= 3) -++ ath79_ehci_pdata_v2.reset_notifier = ar934x_usb_reset_notifier; -++ -+ ath79_usb_register("ehci-platform", -1, -+ AR934X_EHCI_BASE, AR934X_EHCI_SIZE, -+ ATH79_CPU_IRQ(3), -+ &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); -+ } -+ -++static void qca955x_usb_reset_notifier(struct platform_device *pdev) -++{ -++ u32 base; -++ -++ switch (pdev->id) { -++ case 0: -++ base = 0x18116d94; -++ break; -++ -++ case 1: -++ base = 0x18116e54; -++ break; -++ -++ default: -++ return; -++ } -++ -++ enable_tx_tx_idp_violation_fix(base); -++ dev_info(&pdev->dev, "TX-TX IDP fix enabled\n"); -++} -++ -+ static void __init qca955x_usb_setup(void) -+ { -++ ath79_ehci_pdata_v2.reset_notifier = qca955x_usb_reset_notifier; -++ -+ ath79_usb_register("ehci-platform", 0, -+ QCA955X_EHCI0_BASE, QCA955X_EHCI_SIZE, -+ ATH79_IP3_IRQ(0), -diff --git a/target/linux/ar71xx/patches-4.14/601-MIPS-ath79-add-more-register-defines.patch b/target/linux/ar71xx/patches-4.14/601-MIPS-ath79-add-more-register-defines.patch -new file mode 100644 -index 0000000000..d0f5b78901 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/601-MIPS-ath79-add-more-register-defines.patch -@@ -0,0 +1,455 @@ -+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -+@@ -20,6 +20,10 @@ -+ #include -+ -+ #define AR71XX_APB_BASE 0x18000000 -++#define AR71XX_GE0_BASE 0x19000000 -++#define AR71XX_GE0_SIZE 0x10000 -++#define AR71XX_GE1_BASE 0x1a000000 -++#define AR71XX_GE1_SIZE 0x10000 -+ #define AR71XX_EHCI_BASE 0x1b000000 -+ #define AR71XX_EHCI_SIZE 0x1000 -+ #define AR71XX_OHCI_BASE 0x1c000000 -+@@ -39,6 +43,8 @@ -+ #define AR71XX_PLL_SIZE 0x100 -+ #define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) -+ #define AR71XX_RESET_SIZE 0x100 -++#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000) -++#define AR71XX_MII_SIZE 0x100 -+ -+ #define AR71XX_PCI_MEM_BASE 0x10000000 -+ #define AR71XX_PCI_MEM_SIZE 0x07000000 -+@@ -81,15 +87,21 @@ -+ -+ #define AR933X_UART_BASE (AR71XX_APB_BASE + 0x00020000) -+ #define AR933X_UART_SIZE 0x14 -++#define AR933X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) -++#define AR933X_GMAC_SIZE 0x04 -+ #define AR933X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) -+ #define AR933X_WMAC_SIZE 0x20000 -+ #define AR933X_EHCI_BASE 0x1b000000 -+ #define AR933X_EHCI_SIZE 0x1000 -+ -++#define AR934X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) -++#define AR934X_GMAC_SIZE 0x14 -+ #define AR934X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) -+ #define AR934X_WMAC_SIZE 0x20000 -+ #define AR934X_EHCI_BASE 0x1b000000 -+ #define AR934X_EHCI_SIZE 0x200 -++#define AR934X_NFC_BASE 0x1b000200 -++#define AR934X_NFC_SIZE 0xb8 -+ #define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000) -+ #define AR934X_SRIF_SIZE 0x1000 -+ -+@@ -106,11 +118,15 @@ -+ #define QCA955X_PCI_CTRL_BASE1 (AR71XX_APB_BASE + 0x00280000) -+ #define QCA955X_PCI_CTRL_SIZE 0x100 -+ -++#define QCA955X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) -++#define QCA955X_GMAC_SIZE 0x40 -+ #define QCA955X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) -+ #define QCA955X_WMAC_SIZE 0x20000 -+ #define QCA955X_EHCI0_BASE 0x1b000000 -+ #define QCA955X_EHCI1_BASE 0x1b400000 -+ #define QCA955X_EHCI_SIZE 0x1000 -++#define QCA955X_NFC_BASE 0x1b800200 -++#define QCA955X_NFC_SIZE 0xb8 -+ -+ #define AR9300_OTP_BASE 0x14000 -+ #define AR9300_OTP_STATUS 0x15f18 -+@@ -181,6 +197,9 @@ -+ #define AR71XX_AHB_DIV_SHIFT 20 -+ #define AR71XX_AHB_DIV_MASK 0x7 -+ -++#define AR71XX_ETH0_PLL_SHIFT 17 -++#define AR71XX_ETH1_PLL_SHIFT 19 -++ -+ #define AR724X_PLL_REG_CPU_CONFIG 0x00 -+ #define AR724X_PLL_REG_PCIE_CONFIG 0x10 -+ -+@@ -196,6 +215,8 @@ -+ #define AR724X_DDR_DIV_SHIFT 22 -+ #define AR724X_DDR_DIV_MASK 0x3 -+ -++#define AR7242_PLL_REG_ETH0_INT_CLOCK 0x2c -++ -+ #define AR913X_PLL_REG_CPU_CONFIG 0x00 -+ #define AR913X_PLL_REG_ETH_CONFIG 0x04 -+ #define AR913X_PLL_REG_ETH0_INT_CLOCK 0x14 -+@@ -208,6 +229,9 @@ -+ #define AR913X_AHB_DIV_SHIFT 19 -+ #define AR913X_AHB_DIV_MASK 0x1 -+ -++#define AR913X_ETH0_PLL_SHIFT 20 -++#define AR913X_ETH1_PLL_SHIFT 22 -++ -+ #define AR933X_PLL_CPU_CONFIG_REG 0x00 -+ #define AR933X_PLL_CLOCK_CTRL_REG 0x08 -+ -+@@ -229,6 +253,8 @@ -+ #define AR934X_PLL_CPU_CONFIG_REG 0x00 -+ #define AR934X_PLL_DDR_CONFIG_REG 0x04 -+ #define AR934X_PLL_CPU_DDR_CLK_CTRL_REG 0x08 -++#define AR934X_PLL_SWITCH_CLOCK_CONTROL_REG 0x24 -++#define AR934X_PLL_ETH_XMII_CONTROL_REG 0x2c -+ -+ #define AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT 0 -+ #define AR934X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f -+@@ -261,9 +287,13 @@ -+ #define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21) -+ #define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) -+ -++#define AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL BIT(6) -++ -+ #define QCA955X_PLL_CPU_CONFIG_REG 0x00 -+ #define QCA955X_PLL_DDR_CONFIG_REG 0x04 -+ #define QCA955X_PLL_CLK_CTRL_REG 0x08 -++#define QCA955X_PLL_ETH_XMII_CONTROL_REG 0x28 -++#define QCA955X_PLL_ETH_SGMII_CONTROL_REG 0x48 -+ -+ #define QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT 0 -+ #define QCA955X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f -+@@ -388,16 +418,83 @@ -+ #define AR913X_RESET_USB_HOST BIT(5) -+ #define AR913X_RESET_USB_PHY BIT(4) -+ -++#define AR933X_RESET_GE1_MDIO BIT(23) -++#define AR933X_RESET_GE0_MDIO BIT(22) -++#define AR933X_RESET_GE1_MAC BIT(13) -+ #define AR933X_RESET_WMAC BIT(11) -++#define AR933X_RESET_GE0_MAC BIT(9) -+ #define AR933X_RESET_USB_HOST BIT(5) -+ #define AR933X_RESET_USB_PHY BIT(4) -+ #define AR933X_RESET_USBSUS_OVERRIDE BIT(3) -+ -++#define AR934X_RESET_HOST BIT(31) -++#define AR934X_RESET_SLIC BIT(30) -++#define AR934X_RESET_HDMA BIT(29) -++#define AR934X_RESET_EXTERNAL BIT(28) -++#define AR934X_RESET_RTC BIT(27) -++#define AR934X_RESET_PCIE_EP_INT BIT(26) -++#define AR934X_RESET_CHKSUM_ACC BIT(25) -++#define AR934X_RESET_FULL_CHIP BIT(24) -++#define AR934X_RESET_GE1_MDIO BIT(23) -++#define AR934X_RESET_GE0_MDIO BIT(22) -++#define AR934X_RESET_CPU_NMI BIT(21) -++#define AR934X_RESET_CPU_COLD BIT(20) -++#define AR934X_RESET_HOST_RESET_INT BIT(19) -++#define AR934X_RESET_PCIE_EP BIT(18) -++#define AR934X_RESET_UART1 BIT(17) -++#define AR934X_RESET_DDR BIT(16) -++#define AR934X_RESET_USB_PHY_PLL_PWD_EXT BIT(15) -++#define AR934X_RESET_NANDF BIT(14) -++#define AR934X_RESET_GE1_MAC BIT(13) -++#define AR934X_RESET_ETH_SWITCH_ANALOG BIT(12) -+ #define AR934X_RESET_USB_PHY_ANALOG BIT(11) -++#define AR934X_RESET_HOST_DMA_INT BIT(10) -++#define AR934X_RESET_GE0_MAC BIT(9) -++#define AR934X_RESET_ETH_SWITCH BIT(8) -++#define AR934X_RESET_PCIE_PHY BIT(7) -++#define AR934X_RESET_PCIE BIT(6) -+ #define AR934X_RESET_USB_HOST BIT(5) -+ #define AR934X_RESET_USB_PHY BIT(4) -+ #define AR934X_RESET_USBSUS_OVERRIDE BIT(3) -++#define AR934X_RESET_LUT BIT(2) -++#define AR934X_RESET_MBOX BIT(1) -++#define AR934X_RESET_I2S BIT(0) -++ -++#define QCA955X_RESET_HOST BIT(31) -++#define QCA955X_RESET_SLIC BIT(30) -++#define QCA955X_RESET_HDMA BIT(29) -++#define QCA955X_RESET_EXTERNAL BIT(28) -++#define QCA955X_RESET_RTC BIT(27) -++#define QCA955X_RESET_PCIE_EP_INT BIT(26) -++#define QCA955X_RESET_CHKSUM_ACC BIT(25) -++#define QCA955X_RESET_FULL_CHIP BIT(24) -++#define QCA955X_RESET_GE1_MDIO BIT(23) -++#define QCA955X_RESET_GE0_MDIO BIT(22) -++#define QCA955X_RESET_CPU_NMI BIT(21) -++#define QCA955X_RESET_CPU_COLD BIT(20) -++#define QCA955X_RESET_HOST_RESET_INT BIT(19) -++#define QCA955X_RESET_PCIE_EP BIT(18) -++#define QCA955X_RESET_UART1 BIT(17) -++#define QCA955X_RESET_DDR BIT(16) -++#define QCA955X_RESET_USB_PHY_PLL_PWD_EXT BIT(15) -++#define QCA955X_RESET_NANDF BIT(14) -++#define QCA955X_RESET_GE1_MAC BIT(13) -++#define QCA955X_RESET_SGMII_ANALOG BIT(12) -++#define QCA955X_RESET_USB_PHY_ANALOG BIT(11) -++#define QCA955X_RESET_HOST_DMA_INT BIT(10) -++#define QCA955X_RESET_GE0_MAC BIT(9) -++#define QCA955X_RESET_SGMII BIT(8) -++#define QCA955X_RESET_PCIE_PHY BIT(7) -++#define QCA955X_RESET_PCIE BIT(6) -++#define QCA955X_RESET_USB_HOST BIT(5) -++#define QCA955X_RESET_USB_PHY BIT(4) -++#define QCA955X_RESET_USBSUS_OVERRIDE BIT(3) -++#define QCA955X_RESET_LUT BIT(2) -++#define QCA955X_RESET_MBOX BIT(1) -++#define QCA955X_RESET_I2S BIT(0) -+ -++#define AR933X_BOOTSTRAP_MDIO_GPIO_EN BIT(18) -++#define AR933X_BOOTSTRAP_EEPBUSY BIT(4) -+ #define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0) -+ -+ #define AR934X_BOOTSTRAP_SW_OPTION8 BIT(23) -+@@ -539,8 +636,22 @@ -+ #define AR71XX_GPIO_REG_INT_ENABLE 0x24 -+ #define AR71XX_GPIO_REG_FUNC 0x28 -+ -++#define AR934X_GPIO_REG_OUT_FUNC0 0x2c -++#define AR934X_GPIO_REG_OUT_FUNC1 0x30 -++#define AR934X_GPIO_REG_OUT_FUNC2 0x34 -++#define AR934X_GPIO_REG_OUT_FUNC3 0x38 -++#define AR934X_GPIO_REG_OUT_FUNC4 0x3c -++#define AR934X_GPIO_REG_OUT_FUNC5 0x40 -+ #define AR934X_GPIO_REG_FUNC 0x6c -+ -++#define QCA955X_GPIO_REG_OUT_FUNC0 0x2c -++#define QCA955X_GPIO_REG_OUT_FUNC1 0x30 -++#define QCA955X_GPIO_REG_OUT_FUNC2 0x34 -++#define QCA955X_GPIO_REG_OUT_FUNC3 0x38 -++#define QCA955X_GPIO_REG_OUT_FUNC4 0x3c -++#define QCA955X_GPIO_REG_OUT_FUNC5 0x40 -++#define QCA955X_GPIO_REG_FUNC 0x6c -++ -+ #define AR71XX_GPIO_COUNT 16 -+ #define AR7240_GPIO_COUNT 18 -+ #define AR7241_GPIO_COUNT 20 -+@@ -570,4 +681,235 @@ -+ #define AR934X_SRIF_DPLL2_OUTDIV_SHIFT 13 -+ #define AR934X_SRIF_DPLL2_OUTDIV_MASK 0x7 -+ -++#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17) -++#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16) -++#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13) -++#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12) -++#define AR71XX_GPIO_FUNC_UART_EN BIT(8) -++#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4) -++#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0) -++ -++#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19) -++#define AR724X_GPIO_FUNC_SPI_EN BIT(18) -++#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14) -++#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13) -++#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12) -++#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11) -++#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10) -++#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9) -++#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8) -++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7) -++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6) -++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5) -++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4) -++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3) -++#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2) -++#define AR724X_GPIO_FUNC_UART_EN BIT(1) -++#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0) -++ -++#define AR913X_GPIO_FUNC_WMAC_LED_EN BIT(22) -++#define AR913X_GPIO_FUNC_EXP_PORT_CS_EN BIT(21) -++#define AR913X_GPIO_FUNC_I2S_REFCLKEN BIT(20) -++#define AR913X_GPIO_FUNC_I2S_MCKEN BIT(19) -++#define AR913X_GPIO_FUNC_I2S1_EN BIT(18) -++#define AR913X_GPIO_FUNC_I2S0_EN BIT(17) -++#define AR913X_GPIO_FUNC_SLIC_EN BIT(16) -++#define AR913X_GPIO_FUNC_UART_RTSCTS_EN BIT(9) -++#define AR913X_GPIO_FUNC_UART_EN BIT(8) -++#define AR913X_GPIO_FUNC_USB_CLK_EN BIT(4) -++ -++#define AR933X_GPIO_FUNC_SPDIF2TCK BIT(31) -++#define AR933X_GPIO_FUNC_SPDIF_EN BIT(30) -++#define AR933X_GPIO_FUNC_I2SO_22_18_EN BIT(29) -++#define AR933X_GPIO_FUNC_I2S_MCK_EN BIT(27) -++#define AR933X_GPIO_FUNC_I2SO_EN BIT(26) -++#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_DUPL BIT(25) -++#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_COLL BIT(24) -++#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_ACT BIT(23) -++#define AR933X_GPIO_FUNC_SPI_EN BIT(18) -++#define AR933X_GPIO_FUNC_SPI_CS_EN2 BIT(14) -++#define AR933X_GPIO_FUNC_SPI_CS_EN1 BIT(13) -++#define AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7) -++#define AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6) -++#define AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5) -++#define AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4) -++#define AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3) -++#define AR933X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2) -++#define AR933X_GPIO_FUNC_UART_EN BIT(1) -++#define AR933X_GPIO_FUNC_JTAG_DISABLE BIT(0) -++ -++#define AR934X_GPIO_FUNC_CLK_OBS7_EN BIT(9) -++#define AR934X_GPIO_FUNC_CLK_OBS6_EN BIT(8) -++#define AR934X_GPIO_FUNC_CLK_OBS5_EN BIT(7) -++#define AR934X_GPIO_FUNC_CLK_OBS4_EN BIT(6) -++#define AR934X_GPIO_FUNC_CLK_OBS3_EN BIT(5) -++#define AR934X_GPIO_FUNC_CLK_OBS2_EN BIT(4) -++#define AR934X_GPIO_FUNC_CLK_OBS1_EN BIT(3) -++#define AR934X_GPIO_FUNC_CLK_OBS0_EN BIT(2) -++#define AR934X_GPIO_FUNC_JTAG_DISABLE BIT(1) -++ -++#define AR934X_GPIO_OUT_GPIO 0 -++#define AR934X_GPIO_OUT_SPI_CS1 7 -++#define AR934X_GPIO_OUT_LED_LINK0 41 -++#define AR934X_GPIO_OUT_LED_LINK1 42 -++#define AR934X_GPIO_OUT_LED_LINK2 43 -++#define AR934X_GPIO_OUT_LED_LINK3 44 -++#define AR934X_GPIO_OUT_LED_LINK4 45 -++#define AR934X_GPIO_OUT_EXT_LNA0 46 -++#define AR934X_GPIO_OUT_EXT_LNA1 47 -++ -++#define QCA955X_GPIO_FUNC_CLK_OBS7_EN BIT(9) -++#define QCA955X_GPIO_FUNC_CLK_OBS6_EN BIT(8) -++#define QCA955X_GPIO_FUNC_CLK_OBS5_EN BIT(7) -++#define QCA955X_GPIO_FUNC_CLK_OBS4_EN BIT(6) -++#define QCA955X_GPIO_FUNC_CLK_OBS3_EN BIT(5) -++#define QCA955X_GPIO_FUNC_CLK_OBS2_EN BIT(4) -++#define QCA955X_GPIO_FUNC_CLK_OBS1_EN BIT(3) -++#define QCA955X_GPIO_FUNC_JTAG_DISABLE BIT(1) -++ -++#define QCA955X_GPIO_OUT_GPIO 0 -++#define QCA955X_MII_EXT_MDI 1 -++#define QCA955X_SLIC_DATA_OUT 3 -++#define QCA955X_SLIC_PCM_FS 4 -++#define QCA955X_SLIC_PCM_CLK 5 -++#define QCA955X_SPI_CLK 8 -++#define QCA955X_SPI_CS_0 9 -++#define QCA955X_SPI_CS_1 10 -++#define QCA955X_SPI_CS_2 11 -++#define QCA955X_SPI_MISO 12 -++#define QCA955X_I2S_CLK 13 -++#define QCA955X_I2S_WS 14 -++#define QCA955X_I2S_SD 15 -++#define QCA955X_I2S_MCK 16 -++#define QCA955X_SPDIF_OUT 17 -++#define QCA955X_UART1_TD 18 -++#define QCA955X_UART1_RTS 19 -++#define QCA955X_UART1_RD 20 -++#define QCA955X_UART1_CTS 21 -++#define QCA955X_UART0_SOUT 22 -++#define QCA955X_SPDIF2_OUT 23 -++#define QCA955X_LED_SGMII_SPEED0 24 -++#define QCA955X_LED_SGMII_SPEED1 25 -++#define QCA955X_LED_SGMII_DUPLEX 26 -++#define QCA955X_LED_SGMII_LINK_UP 27 -++#define QCA955X_SGMII_SPEED0_INVERT 28 -++#define QCA955X_SGMII_SPEED1_INVERT 29 -++#define QCA955X_SGMII_DUPLEX_INVERT 30 -++#define QCA955X_SGMII_LINK_UP_INVERT 31 -++#define QCA955X_GE1_MII_MDO 32 -++#define QCA955X_GE1_MII_MDC 33 -++#define QCA955X_SWCOM2 38 -++#define QCA955X_SWCOM3 39 -++#define QCA955X_MAC2_GPIO 40 -++#define QCA955X_MAC3_GPIO 41 -++#define QCA955X_ATT_LED 42 -++#define QCA955X_PWR_LED 43 -++#define QCA955X_TX_FRAME 44 -++#define QCA955X_RX_CLEAR_EXTERNAL 45 -++#define QCA955X_LED_NETWORK_EN 46 -++#define QCA955X_LED_POWER_EN 47 -++#define QCA955X_WMAC_GLUE_WOW 68 -++#define QCA955X_RX_CLEAR_EXTENSION 70 -++#define QCA955X_CP_NAND_CS1 73 -++#define QCA955X_USB_SUSPEND 74 -++#define QCA955X_ETH_TX_ERR 75 -++#define QCA955X_DDR_DQ_OE 76 -++#define QCA955X_CLKREQ_N_EP 77 -++#define QCA955X_CLKREQ_N_RC 78 -++#define QCA955X_CLK_OBS0 79 -++#define QCA955X_CLK_OBS1 80 -++#define QCA955X_CLK_OBS2 81 -++#define QCA955X_CLK_OBS3 82 -++#define QCA955X_CLK_OBS4 83 -++#define QCA955X_CLK_OBS5 84 -++ -++/* -++ * MII_CTRL block -++ */ -++#define AR71XX_MII_REG_MII0_CTRL 0x00 -++#define AR71XX_MII_REG_MII1_CTRL 0x04 -++ -++#define AR71XX_MII_CTRL_IF_MASK 3 -++#define AR71XX_MII_CTRL_SPEED_SHIFT 4 -++#define AR71XX_MII_CTRL_SPEED_MASK 3 -++#define AR71XX_MII_CTRL_SPEED_10 0 -++#define AR71XX_MII_CTRL_SPEED_100 1 -++#define AR71XX_MII_CTRL_SPEED_1000 2 -++ -++#define AR71XX_MII0_CTRL_IF_GMII 0 -++#define AR71XX_MII0_CTRL_IF_MII 1 -++#define AR71XX_MII0_CTRL_IF_RGMII 2 -++#define AR71XX_MII0_CTRL_IF_RMII 3 -++ -++#define AR71XX_MII1_CTRL_IF_RGMII 0 -++#define AR71XX_MII1_CTRL_IF_RMII 1 -++ -++/* -++ * AR933X GMAC interface -++ */ -++#define AR933X_GMAC_REG_ETH_CFG 0x00 -++ -++#define AR933X_ETH_CFG_RGMII_GE0 BIT(0) -++#define AR933X_ETH_CFG_MII_GE0 BIT(1) -++#define AR933X_ETH_CFG_GMII_GE0 BIT(2) -++#define AR933X_ETH_CFG_MII_GE0_MASTER BIT(3) -++#define AR933X_ETH_CFG_MII_GE0_SLAVE BIT(4) -++#define AR933X_ETH_CFG_MII_GE0_ERR_EN BIT(5) -++#define AR933X_ETH_CFG_SW_PHY_SWAP BIT(7) -++#define AR933X_ETH_CFG_SW_PHY_ADDR_SWAP BIT(8) -++#define AR933X_ETH_CFG_RMII_GE0 BIT(9) -++#define AR933X_ETH_CFG_RMII_GE0_SPD_10 0 -++#define AR933X_ETH_CFG_RMII_GE0_SPD_100 BIT(10) -++ -++/* -++ * AR934X GMAC Interface -++ */ -++#define AR934X_GMAC_REG_ETH_CFG 0x00 -++ -++#define AR934X_ETH_CFG_RGMII_GMAC0 BIT(0) -++#define AR934X_ETH_CFG_MII_GMAC0 BIT(1) -++#define AR934X_ETH_CFG_GMII_GMAC0 BIT(2) -++#define AR934X_ETH_CFG_MII_GMAC0_MASTER BIT(3) -++#define AR934X_ETH_CFG_MII_GMAC0_SLAVE BIT(4) -++#define AR934X_ETH_CFG_MII_GMAC0_ERR_EN BIT(5) -++#define AR934X_ETH_CFG_SW_ONLY_MODE BIT(6) -++#define AR934X_ETH_CFG_SW_PHY_SWAP BIT(7) -++#define AR934X_ETH_CFG_SW_APB_ACCESS BIT(9) -++#define AR934X_ETH_CFG_RMII_GMAC0 BIT(10) -++#define AR933X_ETH_CFG_MII_CNTL_SPEED BIT(11) -++#define AR934X_ETH_CFG_RMII_GMAC0_MASTER BIT(12) -++#define AR933X_ETH_CFG_SW_ACC_MSB_FIRST BIT(13) -++#define AR934X_ETH_CFG_RXD_DELAY BIT(14) -++#define AR934X_ETH_CFG_RXD_DELAY_MASK 0x3 -++#define AR934X_ETH_CFG_RXD_DELAY_SHIFT 14 -++#define AR934X_ETH_CFG_RDV_DELAY BIT(16) -++#define AR934X_ETH_CFG_RDV_DELAY_MASK 0x3 -++#define AR934X_ETH_CFG_RDV_DELAY_SHIFT 16 -++ -++/* -++ * QCA955X GMAC Interface -++ */ -++ -++#define QCA955X_GMAC_REG_ETH_CFG 0x00 -++ -++#define QCA955X_ETH_CFG_RGMII_EN BIT(0) -++#define QCA955X_ETH_CFG_MII_GE0 BIT(1) -++#define QCA955X_ETH_CFG_GMII_GE0 BIT(2) -++#define QCA955X_ETH_CFG_MII_GE0_MASTER BIT(3) -++#define QCA955X_ETH_CFG_MII_GE0_SLAVE BIT(4) -++#define QCA955X_ETH_CFG_GE0_ERR_EN BIT(5) -++#define QCA955X_ETH_CFG_GE0_SGMII BIT(6) -++#define QCA955X_ETH_CFG_RMII_GE0 BIT(10) -++#define QCA955X_ETH_CFG_MII_CNTL_SPEED BIT(11) -++#define QCA955X_ETH_CFG_RMII_GE0_MASTER BIT(12) -++#define QCA955X_ETH_CFG_RXD_DELAY_MASK 0x3 -++#define QCA955X_ETH_CFG_RXD_DELAY_SHIFT 14 -++#define QCA955X_ETH_CFG_RDV_DELAY BIT(16) -++#define QCA955X_ETH_CFG_RDV_DELAY_MASK 0x3 -++#define QCA955X_ETH_CFG_RDV_DELAY_SHIFT 16 -++#define QCA955X_ETH_CFG_TXD_DELAY_MASK 0x3 -++#define QCA955X_ETH_CFG_TXD_DELAY_SHIFT 18 -++#define QCA955X_ETH_CFG_TXE_DELAY_MASK 0x3 -++#define QCA955X_ETH_CFG_TXE_DELAY_SHIFT 20 -++ -+ #endif /* __ASM_MACH_AR71XX_REGS_H */ -diff --git a/target/linux/ar71xx/patches-4.14/602-MIPS-ath79-add-openwrt-stuff.patch b/target/linux/ar71xx/patches-4.14/602-MIPS-ath79-add-openwrt-stuff.patch -new file mode 100644 -index 0000000000..047be0c7fd ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/602-MIPS-ath79-add-openwrt-stuff.patch -@@ -0,0 +1,49 @@ -+--- a/arch/mips/ath79/Kconfig -++++ b/arch/mips/ath79/Kconfig -+@@ -99,6 +99,20 @@ config SOC_QCA955X -+ select PCI_AR724X if PCI -+ def_bool n -+ -++config ATH79_DEV_M25P80 -++ select ATH79_DEV_SPI -++ def_bool n -++ -++config ATH79_DEV_AP9X_PCI -++ select ATH79_PCI_ATH9K_FIXUP -++ def_bool n -++ -++config ATH79_DEV_DSA -++ def_bool n -++ -++config ATH79_DEV_ETH -++ def_bool n -++ -+ config PCI_AR724X -+ def_bool n -+ -+@@ -108,6 +122,10 @@ config ATH79_DEV_GPIO_BUTTONS -+ config ATH79_DEV_LEDS_GPIO -+ def_bool n -+ -++config ATH79_DEV_NFC -++ depends on (SOC_AR934X || SOC_QCA955X) -++ def_bool n -++ -+ config ATH79_DEV_SPI -+ def_bool n -+ -+@@ -118,4 +136,14 @@ config ATH79_DEV_WMAC -+ depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA955X) -+ def_bool n -+ -++config ATH79_NVRAM -++ def_bool n -++ -++config ATH79_PCI_ATH9K_FIXUP -++ def_bool n -++ -++config ATH79_ROUTERBOOT -++ select LZO_DECOMPRESS -++ def_bool n -++ -+ endif -diff --git a/target/linux/ar71xx/patches-4.14/603-MIPS-ath79-ap121-fixes.patch b/target/linux/ar71xx/patches-4.14/603-MIPS-ath79-ap121-fixes.patch -new file mode 100644 -index 0000000000..672f38e938 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/603-MIPS-ath79-ap121-fixes.patch -@@ -0,0 +1,149 @@ -+--- a/arch/mips/ath79/mach-ap121.c -++++ b/arch/mips/ath79/mach-ap121.c -+@@ -1,19 +1,21 @@ -+ /* -+ * Atheros AP121 board support -+ * -+- * Copyright (C) 2011 Gabor Juhos -++ * Copyright (C) 2011-2012 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+-#include "machtypes.h" -++#include "dev-eth.h" -+ #include "dev-gpio-buttons.h" -+ #include "dev-leds-gpio.h" -++#include "dev-m25p80.h" -+ #include "dev-spi.h" -+ #include "dev-usb.h" -+ #include "dev-wmac.h" -++#include "machtypes.h" -+ -+ #define AP121_GPIO_LED_WLAN 0 -+ #define AP121_GPIO_LED_USB 1 -+@@ -24,7 +26,14 @@ -+ #define AP121_KEYS_POLL_INTERVAL 20 /* msecs */ -+ #define AP121_KEYS_DEBOUNCE_INTERVAL (3 * AP121_KEYS_POLL_INTERVAL) -+ -+-#define AP121_CAL_DATA_ADDR 0x1fff1000 -++#define AP121_MAC0_OFFSET 0x0000 -++#define AP121_MAC1_OFFSET 0x0006 -++#define AP121_CALDATA_OFFSET 0x1000 -++#define AP121_WMAC_MAC_OFFSET 0x1002 -++ -++#define AP121_MINI_GPIO_LED_WLAN 0 -++#define AP121_MINI_GPIO_BTN_JUMPSTART 12 -++#define AP121_MINI_GPIO_BTN_RESET 11 -+ -+ static struct gpio_led ap121_leds_gpio[] __initdata = { -+ { -+@@ -58,35 +67,78 @@ static struct gpio_keys_button ap121_gpi -+ } -+ }; -+ -+-static struct spi_board_info ap121_spi_info[] = { -++static struct gpio_led ap121_mini_leds_gpio[] __initdata = { -+ { -+- .bus_num = 0, -+- .chip_select = 0, -+- .max_speed_hz = 25000000, -+- .modalias = "mx25l1606e", -+- } -++ .name = "ap121:green:wlan", -++ .gpio = AP121_MINI_GPIO_LED_WLAN, -++ .active_low = 0, -++ }, -+ }; -+ -+-static struct ath79_spi_platform_data ap121_spi_data = { -+- .bus_num = 0, -+- .num_chipselect = 1, -++static struct gpio_keys_button ap121_mini_gpio_keys[] __initdata = { -++ { -++ .desc = "jumpstart button", -++ .type = EV_KEY, -++ .code = KEY_WPS_BUTTON, -++ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, -++ .gpio = AP121_MINI_GPIO_BTN_JUMPSTART, -++ .active_low = 1, -++ }, -++ { -++ .desc = "reset button", -++ .type = EV_KEY, -++ .code = KEY_RESTART, -++ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, -++ .gpio = AP121_MINI_GPIO_BTN_RESET, -++ .active_low = 1, -++ } -+ }; -+ -++static void __init ap121_common_setup(void) -++{ -++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -++ -++ ath79_register_m25p80(NULL); -++ ath79_register_wmac(art + AP121_CALDATA_OFFSET, -++ art + AP121_WMAC_MAC_OFFSET); -++ -++ ath79_init_mac(ath79_eth0_data.mac_addr, art + AP121_MAC0_OFFSET, 0); -++ ath79_init_mac(ath79_eth1_data.mac_addr, art + AP121_MAC1_OFFSET, 0); -++ -++ ath79_register_mdio(0, 0x0); -++ -++ /* LAN ports */ -++ ath79_register_eth(1); -++ -++ /* WAN port */ -++ ath79_register_eth(0); -++} -++ -+ static void __init ap121_setup(void) -+ { -+- u8 *cal_data = (u8 *) KSEG1ADDR(AP121_CAL_DATA_ADDR); -++ ap121_common_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap121_leds_gpio), -+ ap121_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(ap121_gpio_keys), -+ ap121_gpio_keys); -+- -+- ath79_register_spi(&ap121_spi_data, ap121_spi_info, -+- ARRAY_SIZE(ap121_spi_info)); -+ ath79_register_usb(); -+- ath79_register_wmac(cal_data, NULL); -+ } -+ -+ MIPS_MACHINE(ATH79_MACH_AP121, "AP121", "Atheros AP121 reference board", -+ ap121_setup); -++ -++static void __init ap121_mini_setup(void) -++{ -++ ap121_common_setup(); -++ -++ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap121_mini_leds_gpio), -++ ap121_mini_leds_gpio); -++ ath79_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL, -++ ARRAY_SIZE(ap121_mini_gpio_keys), -++ ap121_mini_gpio_keys); -++} -++ -++MIPS_MACHINE(ATH79_MACH_AP121_MINI, "AP121-MINI", "Atheros AP121-MINI", -++ ap121_mini_setup); -+--- a/arch/mips/ath79/Kconfig -++++ b/arch/mips/ath79/Kconfig -+@@ -6,9 +6,10 @@ menu "Atheros AR71XX/AR724X/AR913X machi -+ config ATH79_MACH_AP121 -+ bool "Atheros AP121 reference board" -+ select SOC_AR933X -++ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+- select ATH79_DEV_SPI -++ select ATH79_DEV_M25P80 -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ help -diff --git a/target/linux/ar71xx/patches-4.14/604-MIPS-ath79-no-of.patch b/target/linux/ar71xx/patches-4.14/604-MIPS-ath79-no-of.patch -new file mode 100644 -index 0000000000..2e7d5d8232 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/604-MIPS-ath79-no-of.patch -@@ -0,0 +1,70 @@ -+--- a/arch/mips/Kconfig -++++ b/arch/mips/Kconfig -+@@ -203,7 +203,6 @@ config ATH79 -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_MIPS16 -+ select SYS_SUPPORTS_ZBOOT_UART_PROM -+- select USE_OF -+ help -+ Support for the Atheros AR71XX/AR724X/AR913X SoCs. -+ -+--- a/arch/mips/ath79/setup.c -++++ b/arch/mips/ath79/setup.c -+@@ -190,16 +190,20 @@ unsigned int get_c0_compare_int(void) -+ -+ void __init plat_mem_setup(void) -+ { -++#ifdef CONFIG_OF -+ unsigned long fdt_start; -++#endif -+ -+ set_io_port_base(KSEG1); -+ -++#ifdef CONFIG_OF -+ /* Get the position of the FDT passed by the bootloader */ -+ fdt_start = fw_getenvl("fdt_start"); -+ if (fdt_start) -+ __dt_setup_arch((void *)KSEG0ADDR(fdt_start)); -+ else if (fw_passed_dtb) -+ __dt_setup_arch((void *)KSEG0ADDR(fw_passed_dtb)); -++#endif -+ -+ if (mips_machtype != ATH79_MACH_GENERIC_OF) { -+ ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE, -+@@ -295,17 +299,21 @@ static int __init ath79_setup(void) -+ -+ arch_initcall(ath79_setup); -+ -++#ifdef CONFIG_OF -+ void __init device_tree_init(void) -+ { -+ unflatten_and_copy_device_tree(); -+ } -++#endif -+ -+ MIPS_MACHINE(ATH79_MACH_GENERIC, -+ "Generic", -+ "Generic AR71XX/AR724X/AR913X based board", -+ NULL); -+ -++#ifdef CONFIG_OF -+ MIPS_MACHINE(ATH79_MACH_GENERIC_OF, -+ "DTB", -+ "Generic AR71XX/AR724X/AR913X based board (DT)", -+ NULL); -++#endif -+--- a/arch/mips/ath79/clock.c -++++ b/arch/mips/ath79/clock.c -+@@ -32,10 +32,12 @@ -+ #define AR724X_BASE_FREQ 40000000 -+ -+ static struct clk *clks[ATH79_CLK_END]; -++#ifdef CONFIG_OF -+ static struct clk_onecell_data clk_data = { -+ .clks = clks, -+ .clk_num = ARRAY_SIZE(clks), -+ }; -++#endif -+ -+ static struct clk *__init ath79_add_sys_clkdev( -+ const char *id, unsigned long rate) -diff --git a/target/linux/ar71xx/patches-4.14/605-MIPS-ath79-db120-fixes.patch b/target/linux/ar71xx/patches-4.14/605-MIPS-ath79-db120-fixes.patch -new file mode 100644 -index 0000000000..44335f2ff7 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/605-MIPS-ath79-db120-fixes.patch -@@ -0,0 +1,204 @@ -+--- a/arch/mips/ath79/mach-db120.c -++++ b/arch/mips/ath79/mach-db120.c -+@@ -2,7 +2,7 @@ -+ * Atheros DB120 reference board support -+ * -+ * Copyright (c) 2011 Qualcomm Atheros -+- * Copyright (c) 2011 Gabor Juhos -++ * Copyright (c) 2011-2012 Gabor Juhos -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+@@ -19,16 +19,26 @@ -+ */ -+ -+ #include -++#include -++#include -+ #include -++#include -+ -+-#include "machtypes.h" -++#include -++ -++#include "common.h" -++#include "dev-ap9x-pci.h" -++#include "dev-eth.h" -+ #include "dev-gpio-buttons.h" -+ #include "dev-leds-gpio.h" -++#include "dev-m25p80.h" -++#include "dev-nfc.h" -+ #include "dev-spi.h" -+ #include "dev-usb.h" -+ #include "dev-wmac.h" -+-#include "pci.h" -++#include "machtypes.h" -+ -++#define DB120_GPIO_LED_USB 11 -+ #define DB120_GPIO_LED_WLAN_5G 12 -+ #define DB120_GPIO_LED_WLAN_2G 13 -+ #define DB120_GPIO_LED_STATUS 14 -+@@ -39,8 +49,10 @@ -+ #define DB120_KEYS_POLL_INTERVAL 20 /* msecs */ -+ #define DB120_KEYS_DEBOUNCE_INTERVAL (3 * DB120_KEYS_POLL_INTERVAL) -+ -+-#define DB120_WMAC_CALDATA_OFFSET 0x1000 -+-#define DB120_PCIE_CALDATA_OFFSET 0x5000 -++#define DB120_MAC0_OFFSET 0 -++#define DB120_MAC1_OFFSET 6 -++#define DB120_WMAC_CALDATA_OFFSET 0x1000 -++#define DB120_PCIE_CALDATA_OFFSET 0x5000 -+ -+ static struct gpio_led db120_leds_gpio[] __initdata = { -+ { -+@@ -63,6 +75,11 @@ static struct gpio_led db120_leds_gpio[] -+ .gpio = DB120_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ }, -++ { -++ .name = "db120:green:usb", -++ .gpio = DB120_GPIO_LED_USB, -++ .active_low = 1, -++ } -+ }; -+ -+ static struct gpio_keys_button db120_gpio_keys[] __initdata = { -+@@ -76,60 +93,85 @@ static struct gpio_keys_button db120_gpi -+ }, -+ }; -+ -+-static struct spi_board_info db120_spi_info[] = { -+- { -+- .bus_num = 0, -+- .chip_select = 0, -+- .max_speed_hz = 25000000, -+- .modalias = "s25sl064a", -+- } -++static struct ar8327_pad_cfg db120_ar8327_pad0_cfg = { -++ .mode = AR8327_PAD_MAC_RGMII, -++ .txclk_delay_en = true, -++ .rxclk_delay_en = true, -++ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, -++ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, -+ }; -+ -+-static struct ath79_spi_platform_data db120_spi_data = { -+- .bus_num = 0, -+- .num_chipselect = 1, -++static struct ar8327_led_cfg db120_ar8327_led_cfg = { -++ .led_ctrl0 = 0x00000000, -++ .led_ctrl1 = 0xc737c737, -++ .led_ctrl2 = 0x00000000, -++ .led_ctrl3 = 0x00c30c00, -++ .open_drain = true, -+ }; -+ -+-#ifdef CONFIG_PCI -+-static struct ath9k_platform_data db120_ath9k_data; -+- -+-static int db120_pci_plat_dev_init(struct pci_dev *dev) -+-{ -+- switch (PCI_SLOT(dev->devfn)) { -+- case 0: -+- dev->dev.platform_data = &db120_ath9k_data; -+- break; -+- } -+- -+- return 0; -+-} -+- -+-static void __init db120_pci_init(u8 *eeprom) -+-{ -+- memcpy(db120_ath9k_data.eeprom_data, eeprom, -+- sizeof(db120_ath9k_data.eeprom_data)); -++static struct ar8327_platform_data db120_ar8327_data = { -++ .pad0_cfg = &db120_ar8327_pad0_cfg, -++ .port0_cfg = { -++ .force_link = 1, -++ .speed = AR8327_PORT_SPEED_1000, -++ .duplex = 1, -++ .txpause = 1, -++ .rxpause = 1, -++ }, -++ .led_cfg = &db120_ar8327_led_cfg, -++}; -+ -+- ath79_pci_set_plat_dev_init(db120_pci_plat_dev_init); -+- ath79_register_pci(); -+-} -+-#else -+-static inline void db120_pci_init(u8 *eeprom) {} -+-#endif /* CONFIG_PCI */ -++static struct mdio_board_info db120_mdio0_info[] = { -++ { -++ .bus_id = "ag71xx-mdio.0", -++ .mdio_addr = 0, -++ .platform_data = &db120_ar8327_data, -++ }, -++}; -+ -+ static void __init db120_setup(void) -+ { -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -++ ath79_gpio_output_select(DB120_GPIO_LED_USB, AR934X_GPIO_OUT_GPIO); -++ ath79_register_m25p80(NULL); -++ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(db120_leds_gpio), -+ db120_leds_gpio); -+ ath79_register_gpio_keys_polled(-1, DB120_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(db120_gpio_keys), -+ db120_gpio_keys); -+- ath79_register_spi(&db120_spi_data, db120_spi_info, -+- ARRAY_SIZE(db120_spi_info)); -+ ath79_register_usb(); -+ ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET, NULL); -+- db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET); -++ ap91_pci_init(art + DB120_PCIE_CALDATA_OFFSET, NULL); -++ -++ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 | -++ AR934X_ETH_CFG_SW_ONLY_MODE); -++ -++ ath79_register_mdio(1, 0x0); -++ ath79_register_mdio(0, 0x0); -++ -++ ath79_init_mac(ath79_eth0_data.mac_addr, art + DB120_MAC0_OFFSET, 0); -++ -++ mdiobus_register_board_info(db120_mdio0_info, -++ ARRAY_SIZE(db120_mdio0_info)); -++ -++ /* GMAC0 is connected to an AR8327 switch */ -++ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -++ ath79_eth0_data.phy_mask = BIT(0); -++ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -++ ath79_eth0_pll_data.pll_1000 = 0x06000000; -++ ath79_register_eth(0); -++ -++ /* GMAC1 is connected to the internal switch */ -++ ath79_init_mac(ath79_eth1_data.mac_addr, art + DB120_MAC1_OFFSET, 0); -++ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -++ ath79_eth1_data.speed = SPEED_1000; -++ ath79_eth1_data.duplex = DUPLEX_FULL; -++ -++ ath79_register_eth(1); -++ -++ ath79_register_nfc(); -+ } -+ -+ MIPS_MACHINE(ATH79_MACH_DB120, "DB120", "Atheros DB120 reference board", -+--- a/arch/mips/ath79/Kconfig -++++ b/arch/mips/ath79/Kconfig -+@@ -43,9 +43,12 @@ config ATH79_MACH_AP81 -+ config ATH79_MACH_DB120 -+ bool "Atheros DB120 reference board" -+ select SOC_AR934X -++ select ATH79_DEV_AP9X_PCI if PCI -++ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+- select ATH79_DEV_SPI -++ select ATH79_DEV_M25P80 -++ select ATH79_DEV_NFC -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ help -diff --git a/target/linux/ar71xx/patches-4.14/606-MIPS-ath79-pb44-fixes.patch b/target/linux/ar71xx/patches-4.14/606-MIPS-ath79-pb44-fixes.patch -new file mode 100644 -index 0000000000..c9cb7e5c00 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/606-MIPS-ath79-pb44-fixes.patch -@@ -0,0 +1,144 @@ -+--- a/arch/mips/ath79/mach-pb44.c -++++ b/arch/mips/ath79/mach-pb44.c -+@@ -8,23 +8,47 @@ -+ * by the Free Software Foundation. -+ */ -+ -++#include -+ #include -+ #include -+ #include -+ #include -+ #include -++#include -++#include -+ -+ #include "machtypes.h" -++#include -++#include -++#include "dev-eth.h" -+ #include "dev-gpio-buttons.h" -+ #include "dev-leds-gpio.h" -+ #include "dev-spi.h" -+ #include "dev-usb.h" -++#include "machtypes.h" -+ #include "pci.h" -+ -+ #define PB44_GPIO_I2C_SCL 0 -+ #define PB44_GPIO_I2C_SDA 1 -+ -++#define PB44_PCF8757_VSC7395_CS 0 -++#define PB44_PCF8757_STEREO_CS 1 -++#define PB44_PCF8757_SLIC_CS0 2 -++#define PB44_PCF8757_SLIC_TEST 3 -++#define PB44_PCF8757_SLIC_INT0 4 -++#define PB44_PCF8757_SLIC_INT1 5 -++#define PB44_PCF8757_SW_RESET 6 -++#define PB44_PCF8757_SW_JUMP 8 -++#define PB44_PCF8757_LED_JUMP1 9 -++#define PB44_PCF8757_LED_JUMP2 10 -++#define PB44_PCF8757_TP24 11 -++#define PB44_PCF8757_TP25 12 -++#define PB44_PCF8757_TP26 13 -++#define PB44_PCF8757_TP27 14 -++#define PB44_PCF8757_TP28 15 -++ -+ #define PB44_GPIO_EXP_BASE 16 -++#define PB44_GPIO_VSC7395_CS (PB44_GPIO_EXP_BASE + PB44_PCF8757_VSC7395_CS) -+ #define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + 6) -+ #define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + 8) -+ #define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + 9) -+@@ -87,20 +111,59 @@ static struct gpio_keys_button pb44_gpio -+ } -+ }; -+ -++static void pb44_vsc7395_reset(void) -++{ -++ ath79_device_reset_set(AR71XX_RESET_GE1_PHY); -++ udelay(10); -++ ath79_device_reset_clear(AR71XX_RESET_GE1_PHY); -++ mdelay(50); -++} -++ -++static struct vsc7385_platform_data pb44_vsc7395_data = { -++ .reset = pb44_vsc7395_reset, -++ .ucode_name = "vsc7395_ucode_pb44.bin", -++ .mac_cfg = { -++ .tx_ipg = 6, -++ .bit2 = 1, -++ .clk_sel = 0, -++ }, -++}; -++ -++static const char *pb44_part_probes[] = { -++ "RedBoot", -++ NULL, -++}; -++ -++static struct flash_platform_data pb44_flash_data = { -++ .part_probes = pb44_part_probes, -++}; -++ -+ static struct spi_board_info pb44_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p64", -++ .platform_data = &pb44_flash_data, -+ }, -++ { -++ .bus_num = 0, -++ .chip_select = 1, -++ .max_speed_hz = 25000000, -++ .modalias = "spi-vsc7385", -++ .platform_data = &pb44_vsc7395_data, -++ } -+ }; -+ -+ static struct ath79_spi_platform_data pb44_spi_data = { -+ .bus_num = 0, -+- .num_chipselect = 1, -++ .num_chipselect = 2, -+ }; -+ -++#define PB44_WAN_PHYMASK BIT(0) -++#define PB44_LAN_PHYMASK 0 -++#define PB44_MDIO_PHYMASK (PB44_LAN_PHYMASK | PB44_WAN_PHYMASK) -++ -+ static void __init pb44_init(void) -+ { -+ i2c_register_board_info(0, pb44_i2c_board_info, -+@@ -116,6 +179,22 @@ static void __init pb44_init(void) -+ ARRAY_SIZE(pb44_spi_info)); -+ ath79_register_usb(); -+ ath79_register_pci(); -++ -++ ath79_register_mdio(0, ~PB44_MDIO_PHYMASK); -++ -++ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); -++ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -++ ath79_eth0_data.phy_mask = PB44_WAN_PHYMASK; -++ -++ ath79_register_eth(0); -++ -++ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); -++ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -++ ath79_eth1_data.speed = SPEED_1000; -++ ath79_eth1_data.duplex = DUPLEX_FULL; -++ ath79_eth1_pll_data.pll_1000 = 0x110000; -++ -++ ath79_register_eth(1); -+ } -+ -+ MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board", -+--- a/arch/mips/ath79/Kconfig -++++ b/arch/mips/ath79/Kconfig -+@@ -58,6 +58,7 @@ config ATH79_MACH_DB120 -+ config ATH79_MACH_PB44 -+ bool "Atheros PB44 reference board" -+ select SOC_AR71XX -++ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_SPI -diff --git a/target/linux/ar71xx/patches-4.14/607-MIPS-ath79-ubnt-xm-fixes.patch b/target/linux/ar71xx/patches-4.14/607-MIPS-ath79-ubnt-xm-fixes.patch -new file mode 100644 -index 0000000000..4699c82746 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/607-MIPS-ath79-ubnt-xm-fixes.patch -@@ -0,0 +1,14 @@ -+--- a/arch/mips/ath79/Kconfig -++++ b/arch/mips/ath79/Kconfig -+@@ -70,9 +70,10 @@ config ATH79_MACH_PB44 -+ config ATH79_MACH_UBNT_XM -+ bool "Ubiquiti Networks XM (rev 1.0) board" -+ select SOC_AR724X -++ select ATH79_DEV_AP9X_PCI if PCI -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+- select ATH79_DEV_SPI -++ select ATH79_DEV_M25P80 -+ help -+ Say 'Y' here if you want your kernel to support the -+ Ubiquiti Networks XM (rev 1.0) board. -diff --git a/target/linux/ar71xx/patches-4.14/608-MIPS-ath79-ubnt-xm-add-more-boards.patch b/target/linux/ar71xx/patches-4.14/608-MIPS-ath79-ubnt-xm-add-more-boards.patch -new file mode 100644 -index 0000000000..b33db4dd0d ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/608-MIPS-ath79-ubnt-xm-add-more-boards.patch -@@ -0,0 +1,20 @@ -+--- a/arch/mips/ath79/Kconfig -++++ b/arch/mips/ath79/Kconfig -+@@ -68,12 +68,16 @@ config ATH79_MACH_PB44 -+ Atheros PB44 reference board. -+ -+ config ATH79_MACH_UBNT_XM -+- bool "Ubiquiti Networks XM (rev 1.0) board" -++ bool "Ubiquiti Networks XM/UniFi boards" -+ select SOC_AR724X -++ select SOC_AR934X -+ select ATH79_DEV_AP9X_PCI if PCI -++ select ATH79_DEV_ETH -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -+ select ATH79_DEV_M25P80 -++ select ATH79_DEV_USB -++ select ATH79_DEV_WMAC -+ help -+ Say 'Y' here if you want your kernel to support the -+ Ubiquiti Networks XM (rev 1.0) board. -diff --git a/target/linux/ar71xx/patches-4.14/609-MIPS-ath79-ap136-fixes.patch b/target/linux/ar71xx/patches-4.14/609-MIPS-ath79-ap136-fixes.patch -new file mode 100644 -index 0000000000..7f3a242cad ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/609-MIPS-ath79-ap136-fixes.patch -@@ -0,0 +1,300 @@ -+--- a/arch/mips/ath79/mach-ap136.c -++++ b/arch/mips/ath79/mach-ap136.c -+@@ -18,23 +18,29 @@ -+ * -+ */ -+ -+-#include -+-#include -++#include -++#include -+ -+-#include "machtypes.h" -++#include -++ -++#include "common.h" -++#include "pci.h" -++#include "dev-ap9x-pci.h" -+ #include "dev-gpio-buttons.h" -++#include "dev-eth.h" -+ #include "dev-leds-gpio.h" -+-#include "dev-spi.h" -++#include "dev-m25p80.h" -++#include "dev-nfc.h" -+ #include "dev-usb.h" -+ #include "dev-wmac.h" -+-#include "pci.h" -++#include "machtypes.h" -+ -+-#define AP136_GPIO_LED_STATUS_RED 14 -+-#define AP136_GPIO_LED_STATUS_GREEN 19 -+ #define AP136_GPIO_LED_USB 4 -+-#define AP136_GPIO_LED_WLAN_2G 13 -+ #define AP136_GPIO_LED_WLAN_5G 12 -++#define AP136_GPIO_LED_WLAN_2G 13 -++#define AP136_GPIO_LED_STATUS_RED 14 -+ #define AP136_GPIO_LED_WPS_RED 15 -++#define AP136_GPIO_LED_STATUS_GREEN 19 -+ #define AP136_GPIO_LED_WPS_GREEN 20 -+ -+ #define AP136_GPIO_BTN_WPS 16 -+@@ -43,37 +49,39 @@ -+ #define AP136_KEYS_POLL_INTERVAL 20 /* msecs */ -+ #define AP136_KEYS_DEBOUNCE_INTERVAL (3 * AP136_KEYS_POLL_INTERVAL) -+ -+-#define AP136_WMAC_CALDATA_OFFSET 0x1000 -+-#define AP136_PCIE_CALDATA_OFFSET 0x5000 -++#define AP136_MAC0_OFFSET 0 -++#define AP136_MAC1_OFFSET 6 -++#define AP136_WMAC_CALDATA_OFFSET 0x1000 -++#define AP136_PCIE_CALDATA_OFFSET 0x5000 -+ -+ static struct gpio_led ap136_leds_gpio[] __initdata = { -+ { -+- .name = "qca:green:status", -++ .name = "ap136:green:status", -+ .gpio = AP136_GPIO_LED_STATUS_GREEN, -+ .active_low = 1, -+ }, -+ { -+- .name = "qca:red:status", -++ .name = "ap136:red:status", -+ .gpio = AP136_GPIO_LED_STATUS_RED, -+ .active_low = 1, -+ }, -+ { -+- .name = "qca:green:wps", -++ .name = "ap136:green:wps", -+ .gpio = AP136_GPIO_LED_WPS_GREEN, -+ .active_low = 1, -+ }, -+ { -+- .name = "qca:red:wps", -++ .name = "ap136:red:wps", -+ .gpio = AP136_GPIO_LED_WPS_RED, -+ .active_low = 1, -+ }, -+ { -+- .name = "qca:red:wlan-2g", -++ .name = "ap136:red:wlan-2g", -+ .gpio = AP136_GPIO_LED_WLAN_2G, -+ .active_low = 1, -+ }, -+ { -+- .name = "qca:red:usb", -++ .name = "ap136:red:usb", -+ .gpio = AP136_GPIO_LED_USB, -+ .active_low = 1, -+ } -+@@ -98,59 +106,151 @@ static struct gpio_keys_button ap136_gpi -+ }, -+ }; -+ -+-static struct spi_board_info ap136_spi_info[] = { -+- { -+- .bus_num = 0, -+- .chip_select = 0, -+- .max_speed_hz = 25000000, -+- .modalias = "mx25l6405d", -+- } -++static struct ar8327_pad_cfg ap136_ar8327_pad0_cfg; -++static struct ar8327_pad_cfg ap136_ar8327_pad6_cfg; -++ -++static struct ar8327_platform_data ap136_ar8327_data = { -++ .pad0_cfg = &ap136_ar8327_pad0_cfg, -++ .pad6_cfg = &ap136_ar8327_pad6_cfg, -++ .port0_cfg = { -++ .force_link = 1, -++ .speed = AR8327_PORT_SPEED_1000, -++ .duplex = 1, -++ .txpause = 1, -++ .rxpause = 1, -++ }, -++ .port6_cfg = { -++ .force_link = 1, -++ .speed = AR8327_PORT_SPEED_1000, -++ .duplex = 1, -++ .txpause = 1, -++ .rxpause = 1, -++ }, -+ }; -+ -+-static struct ath79_spi_platform_data ap136_spi_data = { -+- .bus_num = 0, -+- .num_chipselect = 1, -++static struct mdio_board_info ap136_mdio0_info[] = { -++ { -++ .bus_id = "ag71xx-mdio.0", -++ .mdio_addr = 0, -++ .platform_data = &ap136_ar8327_data, -++ }, -+ }; -+ -+-#ifdef CONFIG_PCI -+-static struct ath9k_platform_data ap136_ath9k_data; -++static void __init ap136_common_setup(void) -++{ -++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -++ -++ ath79_register_m25p80(NULL); -++ -++ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap136_leds_gpio), -++ ap136_leds_gpio); -++ ath79_register_gpio_keys_polled(-1, AP136_KEYS_POLL_INTERVAL, -++ ARRAY_SIZE(ap136_gpio_keys), -++ ap136_gpio_keys); -++ -++ ath79_register_usb(); -++ ath79_register_nfc(); -++ -++ ath79_register_wmac(art + AP136_WMAC_CALDATA_OFFSET, NULL); -++ -++ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN); -+ -+-static int ap136_pci_plat_dev_init(struct pci_dev *dev) -++ ath79_register_mdio(0, 0x0); -++ ath79_init_mac(ath79_eth0_data.mac_addr, art + AP136_MAC0_OFFSET, 0); -++ -++ mdiobus_register_board_info(ap136_mdio0_info, -++ ARRAY_SIZE(ap136_mdio0_info)); -++ -++ /* GMAC0 is connected to the RMGII interface */ -++ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; -++ ath79_eth0_data.phy_mask = BIT(0); -++ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -++ -++ ath79_register_eth(0); -++ -++ /* GMAC1 is connected tot eh SGMII interface */ -++ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII; -++ ath79_eth1_data.speed = SPEED_1000; -++ ath79_eth1_data.duplex = DUPLEX_FULL; -++ -++ ath79_register_eth(1); -++} -++ -++static void __init ap136_010_setup(void) -+ { -+- if (dev->bus->number == 1 && (PCI_SLOT(dev->devfn)) == 0) -+- dev->dev.platform_data = &ap136_ath9k_data; -++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+- return 0; -++ /* GMAC0 of the AR8327 switch is connected to GMAC0 via RGMII */ -++ ap136_ar8327_pad0_cfg.mode = AR8327_PAD_MAC_RGMII; -++ ap136_ar8327_pad0_cfg.txclk_delay_en = true; -++ ap136_ar8327_pad0_cfg.rxclk_delay_en = true; -++ ap136_ar8327_pad0_cfg.txclk_delay_sel = AR8327_CLK_DELAY_SEL1; -++ ap136_ar8327_pad0_cfg.rxclk_delay_sel = AR8327_CLK_DELAY_SEL2; -++ -++ /* GMAC6 of the AR8327 switch is connected to GMAC1 via SGMII */ -++ ap136_ar8327_pad6_cfg.mode = AR8327_PAD_MAC_SGMII; -++ ap136_ar8327_pad6_cfg.rxclk_delay_en = true; -++ ap136_ar8327_pad6_cfg.rxclk_delay_sel = AR8327_CLK_DELAY_SEL0; -++ -++ ath79_eth0_pll_data.pll_1000 = 0xa6000000; -++ ath79_eth1_pll_data.pll_1000 = 0x03000101; -++ -++ ap136_common_setup(); -++ ap91_pci_init(art + AP136_PCIE_CALDATA_OFFSET, NULL); -+ } -+ -+-static void __init ap136_pci_init(u8 *eeprom) -++MIPS_MACHINE(ATH79_MACH_AP136_010, "AP136-010", -++ "Atheros AP136-010 reference board", -++ ap136_010_setup); -++ -++static void __init ap136_020_common_setup(void) -+ { -+- memcpy(ap136_ath9k_data.eeprom_data, eeprom, -+- sizeof(ap136_ath9k_data.eeprom_data)); -++ /* GMAC0 of the AR8327 switch is connected to GMAC1 via SGMII */ -++ ap136_ar8327_pad0_cfg.mode = AR8327_PAD_MAC_SGMII; -++ ap136_ar8327_pad0_cfg.sgmii_delay_en = true; -++ -++ /* GMAC6 of the AR8327 switch is connected to GMAC0 via RGMII */ -++ ap136_ar8327_pad6_cfg.mode = AR8327_PAD_MAC_RGMII; -++ ap136_ar8327_pad6_cfg.txclk_delay_en = true; -++ ap136_ar8327_pad6_cfg.rxclk_delay_en = true; -++ ap136_ar8327_pad6_cfg.txclk_delay_sel = AR8327_CLK_DELAY_SEL1; -++ ap136_ar8327_pad6_cfg.rxclk_delay_sel = AR8327_CLK_DELAY_SEL2; -+ -+- ath79_pci_set_plat_dev_init(ap136_pci_plat_dev_init); -+- ath79_register_pci(); -++ ath79_eth0_pll_data.pll_1000 = 0x56000000; -++ ath79_eth1_pll_data.pll_1000 = 0x03000101; -++ -++ ap136_common_setup(); -+ } -+-#else -+-static inline void ap136_pci_init(u8 *eeprom) {} -+-#endif /* CONFIG_PCI */ -+ -+-static void __init ap136_setup(void) -++static void __init ap136_020_setup(void) -+ { -+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); -+ -+- ath79_register_leds_gpio(-1, ARRAY_SIZE(ap136_leds_gpio), -+- ap136_leds_gpio); -+- ath79_register_gpio_keys_polled(-1, AP136_KEYS_POLL_INTERVAL, -+- ARRAY_SIZE(ap136_gpio_keys), -+- ap136_gpio_keys); -+- ath79_register_spi(&ap136_spi_data, ap136_spi_info, -+- ARRAY_SIZE(ap136_spi_info)); -+- ath79_register_usb(); -+- ath79_register_wmac(art + AP136_WMAC_CALDATA_OFFSET); -+- ap136_pci_init(art + AP136_PCIE_CALDATA_OFFSET); -++ ap136_020_common_setup(); -++ ap91_pci_init(art + AP136_PCIE_CALDATA_OFFSET, NULL); -+ } -+ -+-MIPS_MACHINE(ATH79_MACH_AP136_010, "AP136-010", -+- "Atheros AP136-010 reference board", -+- ap136_setup); -++MIPS_MACHINE(ATH79_MACH_AP136_020, "AP136-020", -++ "Atheros AP136-020 reference board", -++ ap136_020_setup); -++ -++/* -++ * AP135-020 is similar to AP136-020, any future AP135 specific init -++ * code can be added here. -++ */ -++static void __init ap135_020_setup(void) -++{ -++ ap136_leds_gpio[0].name = "ap135:green:status"; -++ ap136_leds_gpio[1].name = "ap135:red:status"; -++ ap136_leds_gpio[2].name = "ap135:green:wps"; -++ ap136_leds_gpio[3].name = "ap135:red:wps"; -++ ap136_leds_gpio[4].name = "ap135:red:wlan-2g"; -++ ap136_leds_gpio[5].name = "ap135:red:usb"; -++ -++ ap136_020_common_setup(); -++ ath79_register_pci(); -++} -++ -++MIPS_MACHINE(ATH79_MACH_AP135_020, "AP135-020", -++ "Atheros AP135-020 reference board", -++ ap135_020_setup); -+--- a/arch/mips/ath79/Kconfig -++++ b/arch/mips/ath79/Kconfig -+@@ -17,16 +17,17 @@ config ATH79_MACH_AP121 -+ Atheros AP121 reference board. -+ -+ config ATH79_MACH_AP136 -+- bool "Atheros AP136 reference board" -++ bool "Atheros AP136/AP135 reference board" -+ select SOC_QCA955X -+ select ATH79_DEV_GPIO_BUTTONS -+ select ATH79_DEV_LEDS_GPIO -++ select ATH79_DEV_NFC -+ select ATH79_DEV_SPI -+ select ATH79_DEV_USB -+ select ATH79_DEV_WMAC -+ help -+ Say 'Y' here if you want your kernel to support the -+- Atheros AP136 reference board. -++ Atheros AP136 or AP135 reference boards. -+ -+ config ATH79_MACH_AP81 -+ bool "Atheros AP81 reference board" -diff --git a/target/linux/ar71xx/patches-4.14/611-MIPS-ath79-wdt-timeout.patch b/target/linux/ar71xx/patches-4.14/611-MIPS-ath79-wdt-timeout.patch -new file mode 100644 -index 0000000000..0927d5a977 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/611-MIPS-ath79-wdt-timeout.patch -@@ -0,0 +1,25 @@ -+MIPS: ath79: fix maximum timeout -+ -+If the userland tries to set a timeout higher than the max_timeout, then we should fallback to max_timeout. -+ -+Signed-off-by: John Crispin -+ -+--- a/drivers/watchdog/ath79_wdt.c -++++ b/drivers/watchdog/ath79_wdt.c -+@@ -115,10 +115,14 @@ static inline void ath79_wdt_disable(voi -+ -+ static int ath79_wdt_set_timeout(int val) -+ { -+- if (val < 1 || val > max_timeout) -++ if (val < 1) -+ return -EINVAL; -+ -+- timeout = val; -++ if (val > max_timeout) -++ timeout = max_timeout; -++ else -++ timeout = val; -++ -+ ath79_wdt_keepalive(); -+ -+ return 0; -diff --git a/target/linux/ar71xx/patches-4.14/612-MIPS-ath79-set-buffalo-txgain.patch b/target/linux/ar71xx/patches-4.14/612-MIPS-ath79-set-buffalo-txgain.patch -new file mode 100644 -index 0000000000..3d100e0549 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/612-MIPS-ath79-set-buffalo-txgain.patch -@@ -0,0 +1,24 @@ -+--- a/arch/mips/ath79/dev-wmac.c -++++ b/arch/mips/ath79/dev-wmac.c -+@@ -319,6 +319,11 @@ void __init ath79_wmac_disable_5ghz(void -+ ath79_wmac_data.disable_5ghz = true; -+ } -+ -++void __init ath79_wmac_set_tx_gain_buffalo(void) -++{ -++ ath79_wmac_data.tx_gain_buffalo = true; -++} -++ -+ void __init ath79_register_wmac(u8 *cal_data, u8 *mac_addr) -+ { -+ if (soc_is_ar913x()) -+--- a/arch/mips/ath79/dev-wmac.h -++++ b/arch/mips/ath79/dev-wmac.h -+@@ -16,6 +16,7 @@ void ath79_register_wmac(u8 *cal_data, u -+ void ath79_register_wmac_simple(void); -+ void ath79_wmac_disable_2ghz(void); -+ void ath79_wmac_disable_5ghz(void); -++void ath79_wmac_set_tx_gain_buffalo(void); -+ -+ bool ar93xx_wmac_read_mac_address(u8 *dest); -+ -diff --git a/target/linux/ar71xx/patches-4.14/613-MIPS-ath79-add-ath79_wmac_setup_ext_lna_gpio-helper.patch b/target/linux/ar71xx/patches-4.14/613-MIPS-ath79-add-ath79_wmac_setup_ext_lna_gpio-helper.patch -new file mode 100644 -index 0000000000..5c1205d59f ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/613-MIPS-ath79-add-ath79_wmac_setup_ext_lna_gpio-helper.patch -@@ -0,0 +1,76 @@ -+--- a/arch/mips/ath79/dev-wmac.c -++++ b/arch/mips/ath79/dev-wmac.c -+@@ -18,9 +18,11 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include -+ #include -++#include "common.h" -+ #include "dev-wmac.h" -+ -+ static u8 ath79_wmac_mac[ETH_ALEN]; -+@@ -324,6 +326,51 @@ void __init ath79_wmac_set_tx_gain_buffa -+ ath79_wmac_data.tx_gain_buffalo = true; -+ } -+ -++static int ath79_request_ext_lna_gpio(unsigned chain, int gpio) -++{ -++ char *label; -++ int err; -++ -++ label = kasprintf(GFP_KERNEL, "external LNA%u", chain); -++ if (!label) -++ return -ENOMEM; -++ -++ err = gpio_request_one(gpio, GPIOF_DIR_OUT | GPIOF_INIT_LOW, label); -++ if (err) { -++ pr_err("unable to request GPIO%d for external LNA%u\n", -++ gpio, chain); -++ kfree(label); -++ } -++ -++ return err; -++} -++ -++static void ar934x_set_ext_lna_gpio(unsigned chain, int gpio) -++{ -++ unsigned int sel; -++ int err; -++ -++ if (WARN_ON(chain > 1)) -++ return; -++ -++ err = ath79_request_ext_lna_gpio(chain, gpio); -++ if (err) -++ return; -++ -++ if (chain == 0) -++ sel = AR934X_GPIO_OUT_EXT_LNA0; -++ else -++ sel = AR934X_GPIO_OUT_EXT_LNA1; -++ -++ ath79_gpio_output_select(gpio, sel); -++} -++ -++void __init ath79_wmac_set_ext_lna_gpio(unsigned chain, int gpio) -++{ -++ if (soc_is_ar934x()) -++ ar934x_set_ext_lna_gpio(chain, gpio); -++} -++ -+ void __init ath79_register_wmac(u8 *cal_data, u8 *mac_addr) -+ { -+ if (soc_is_ar913x()) -+--- a/arch/mips/ath79/dev-wmac.h -++++ b/arch/mips/ath79/dev-wmac.h -+@@ -17,6 +17,7 @@ void ath79_register_wmac_simple(void); -+ void ath79_wmac_disable_2ghz(void); -+ void ath79_wmac_disable_5ghz(void); -+ void ath79_wmac_set_tx_gain_buffalo(void); -++void ath79_wmac_set_ext_lna_gpio(unsigned chain, int gpio); -+ -+ bool ar93xx_wmac_read_mac_address(u8 *dest); -+ -diff --git a/target/linux/ar71xx/patches-4.14/620-MIPS-ath79-add-support-for-QCA953x-SoC.patch b/target/linux/ar71xx/patches-4.14/620-MIPS-ath79-add-support-for-QCA953x-SoC.patch -new file mode 100644 -index 0000000000..722d127ec5 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/620-MIPS-ath79-add-support-for-QCA953x-SoC.patch -@@ -0,0 +1,696 @@ -+From 5300a7cd7ed2f88488ddba62947b9c6bb9663777 Mon Sep 17 00:00:00 2001 -+Message-Id: <5300a7cd7ed2f88488ddba62947b9c6bb9663777.1396122227.git.mschiffer@universe-factory.net> -+From: Matthias Schiffer -+Date: Sat, 29 Mar 2014 20:26:08 +0100 -+Subject: [PATCH 1/2] MIPS: ath79: add support for QCA953x SoC -+ -+Note that the clock calculation looks very similar to the QCA955x, but the -+meaning of the bits CPUCLK_FROM_CPUPLL and DDRCLK_FROM_DDRPLL is reversed. -+--- -+ arch/mips/ath79/Kconfig | 6 +- -+ arch/mips/ath79/clock.c | 78 ++++++++++++++++++++++++++ -+ arch/mips/ath79/common.c | 4 ++ -+ arch/mips/ath79/dev-common.c | 1 + -+ arch/mips/ath79/dev-wmac.c | 20 +++++++ -+ arch/mips/ath79/early_printk.c | 1 + -+ arch/mips/ath79/gpio.c | 4 +- -+ arch/mips/ath79/irq.c | 4 ++ -+ arch/mips/ath79/setup.c | 8 ++- -+ arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 48 ++++++++++++++++ -+ arch/mips/include/asm/mach-ath79/ath79.h | 11 ++++ -+ 11 files changed, 182 insertions(+), 3 deletions(-) -+ -+--- a/arch/mips/ath79/Kconfig -++++ b/arch/mips/ath79/Kconfig -+@@ -105,6 +105,10 @@ config SOC_AR934X -+ select PCI_AR724X if PCI -+ def_bool n -+ -++config SOC_QCA953X -++ select USB_ARCH_HAS_EHCI -++ def_bool n -++ -+ config SOC_QCA955X -+ select HW_HAS_PCI -+ select PCI_AR724X if PCI -+@@ -144,7 +148,7 @@ config ATH79_DEV_USB -+ def_bool n -+ -+ config ATH79_DEV_WMAC -+- depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA955X) -++ depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA953X || SOC_QCA955X) -+ def_bool n -+ -+ config ATH79_NVRAM -+--- a/arch/mips/ath79/clock.c -++++ b/arch/mips/ath79/clock.c -+@@ -357,6 +357,87 @@ static void __init ar934x_clocks_init(vo -+ iounmap(dpll_base); -+ } -+ -++static void __init qca953x_clocks_init(void) -++{ -++ unsigned long ref_rate; -++ unsigned long cpu_rate; -++ unsigned long ddr_rate; -++ unsigned long ahb_rate; -++ u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; -++ u32 cpu_pll, ddr_pll; -++ -++ /* QCA953X only supports 25MHz ref_clk */ -++ ref_rate = 25 * 1000 * 1000; -++ -++ pll = ath79_pll_rr(QCA953X_PLL_CPU_CONFIG_REG); -++ out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & -++ QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK; -++ ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) & -++ QCA953X_PLL_CPU_CONFIG_REFDIV_MASK; -++ nint = (pll >> QCA953X_PLL_CPU_CONFIG_NINT_SHIFT) & -++ QCA953X_PLL_CPU_CONFIG_NINT_MASK; -++ frac = (pll >> QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT) & -++ QCA953X_PLL_CPU_CONFIG_NFRAC_MASK; -++ -++ cpu_pll = nint * ref_rate / ref_div; -++ cpu_pll += frac * (ref_rate >> 6) / ref_div; -++ cpu_pll /= (1 << out_div); -++ -++ pll = ath79_pll_rr(QCA953X_PLL_DDR_CONFIG_REG); -++ out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & -++ QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK; -++ ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) & -++ QCA953X_PLL_DDR_CONFIG_REFDIV_MASK; -++ nint = (pll >> QCA953X_PLL_DDR_CONFIG_NINT_SHIFT) & -++ QCA953X_PLL_DDR_CONFIG_NINT_MASK; -++ frac = (pll >> QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT) & -++ QCA953X_PLL_DDR_CONFIG_NFRAC_MASK; -++ -++ ddr_pll = nint * ref_rate / ref_div; -++ ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4); -++ ddr_pll /= (1 << out_div); -++ -++ clk_ctrl = ath79_pll_rr(QCA953X_PLL_CLK_CTRL_REG); -++ -++ postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & -++ QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; -++ -++ if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS) -++ cpu_rate = ref_rate; -++ else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) -++ cpu_rate = cpu_pll / (postdiv + 1); -++ else -++ cpu_rate = ddr_pll / (postdiv + 1); -++ -++ postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & -++ QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; -++ -++ if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS) -++ ddr_rate = ref_rate; -++ else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) -++ ddr_rate = ddr_pll / (postdiv + 1); -++ else -++ ddr_rate = cpu_pll / (postdiv + 1); -++ -++ postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & -++ QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; -++ -++ if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS) -++ ahb_rate = ref_rate; -++ else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) -++ ahb_rate = ddr_pll / (postdiv + 1); -++ else -++ ahb_rate = cpu_pll / (postdiv + 1); -++ -++ ath79_add_sys_clkdev("ref", ref_rate); -++ ath79_add_sys_clkdev("cpu", cpu_rate); -++ ath79_add_sys_clkdev("ddr", ddr_rate); -++ ath79_add_sys_clkdev("ahb", ahb_rate); -++ -++ clk_add_alias("wdt", NULL, "ref", NULL); -++ clk_add_alias("uart", NULL, "ref", NULL); -++} -++ -+ static void __init qca955x_clocks_init(void) -+ { -+ unsigned long ref_rate; -+@@ -452,6 +533,8 @@ void __init ath79_clocks_init(void) -+ ar933x_clocks_init(); -+ else if (soc_is_ar934x()) -+ ar934x_clocks_init(); -++ else if (soc_is_qca953x()) -++ qca953x_clocks_init(); -+ else if (soc_is_qca955x()) -+ qca955x_clocks_init(); -+ else -+--- a/arch/mips/ath79/common.c -++++ b/arch/mips/ath79/common.c -+@@ -103,6 +103,8 @@ void ath79_device_reset_set(u32 mask) -+ reg = AR933X_RESET_REG_RESET_MODULE; -+ else if (soc_is_ar934x()) -+ reg = AR934X_RESET_REG_RESET_MODULE; -++ else if (soc_is_qca953x()) -++ reg = QCA953X_RESET_REG_RESET_MODULE; -+ else if (soc_is_qca955x()) -+ reg = QCA955X_RESET_REG_RESET_MODULE; -+ else -+@@ -131,6 +133,8 @@ void ath79_device_reset_clear(u32 mask) -+ reg = AR933X_RESET_REG_RESET_MODULE; -+ else if (soc_is_ar934x()) -+ reg = AR934X_RESET_REG_RESET_MODULE; -++ else if (soc_is_qca953x()) -++ reg = QCA953X_RESET_REG_RESET_MODULE; -+ else if (soc_is_qca955x()) -+ reg = QCA955X_RESET_REG_RESET_MODULE; -+ else -+--- a/arch/mips/ath79/dev-common.c -++++ b/arch/mips/ath79/dev-common.c -+@@ -94,6 +94,7 @@ void __init ath79_register_uart(void) -+ soc_is_ar724x() || -+ soc_is_ar913x() || -+ soc_is_ar934x() || -++ soc_is_qca953x() || -+ soc_is_qca955x()) { -+ ath79_uart_data[0].uartclk = uart_clk_rate; -+ platform_device_register(&ath79_uart_device); -+@@ -157,6 +158,9 @@ void __init ath79_gpio_init(void) -+ } else if (soc_is_ar934x()) { -+ ath79_gpio_pdata.ngpios = AR934X_GPIO_COUNT; -+ ath79_gpio_pdata.oe_inverted = 1; -++ } else if (soc_is_qca953x()) { -++ ath79_gpio_pdata.ngpios = QCA953X_GPIO_COUNT; -++ ath79_gpio_pdata.oe_inverted = 1; -+ } else if (soc_is_qca955x()) { -+ ath79_gpio_pdata.ngpios = QCA955X_GPIO_COUNT; -+ ath79_gpio_pdata.oe_inverted = 1; -+--- a/arch/mips/ath79/dev-usb.c -++++ b/arch/mips/ath79/dev-usb.c -+@@ -236,6 +236,30 @@ static void __init ar934x_usb_setup(void -+ &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); -+ } -+ -++static void __init qca953x_usb_setup(void) -++{ -++ u32 bootstrap; -++ -++ bootstrap = ath79_reset_rr(QCA953X_RESET_REG_BOOTSTRAP); -++ -++ ath79_device_reset_set(QCA953X_RESET_USBSUS_OVERRIDE); -++ udelay(1000); -++ -++ ath79_device_reset_clear(QCA953X_RESET_USB_PHY); -++ udelay(1000); -++ -++ ath79_device_reset_clear(QCA953X_RESET_USB_PHY_ANALOG); -++ udelay(1000); -++ -++ ath79_device_reset_clear(QCA953X_RESET_USB_HOST); -++ udelay(1000); -++ -++ ath79_usb_register("ehci-platform", -1, -++ QCA953X_EHCI_BASE, QCA953X_EHCI_SIZE, -++ ATH79_CPU_IRQ(3), -++ &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); -++} -++ -+ static void qca955x_usb_reset_notifier(struct platform_device *pdev) -+ { -+ u32 base; -+@@ -286,6 +310,8 @@ void __init ath79_register_usb(void) -+ ar933x_usb_setup(); -+ else if (soc_is_ar934x()) -+ ar934x_usb_setup(); -++ else if (soc_is_qca953x()) -++ qca953x_usb_setup(); -+ else if (soc_is_qca955x()) -+ qca955x_usb_setup(); -+ else -+--- a/arch/mips/ath79/dev-wmac.c -++++ b/arch/mips/ath79/dev-wmac.c -+@@ -100,7 +100,7 @@ static int ar933x_wmac_reset(void) -+ return -ETIMEDOUT; -+ } -+ -+-static int ar933x_r1_get_wmac_revision(void) -++static int ar93xx_get_soc_revision(void) -+ { -+ return ath79_soc_rev; -+ } -+@@ -125,7 +125,7 @@ static void __init ar933x_wmac_setup(voi -+ ath79_wmac_data.is_clk_25mhz = true; -+ -+ if (ath79_soc_rev == 1) -+- ath79_wmac_data.get_mac_revision = ar933x_r1_get_wmac_revision; -++ ath79_wmac_data.get_mac_revision = ar93xx_get_soc_revision; -+ -+ ath79_wmac_data.external_reset = ar933x_wmac_reset; -+ } -+@@ -150,6 +150,21 @@ static void ar934x_wmac_setup(void) -+ ath79_wmac_data.get_mac_revision = ar93xx_get_soc_revision; -+ } -+ -++static void qca953x_wmac_setup(void) -++{ -++ ath79_wmac_device.name = "qca953x_wmac"; -++ -++ ath79_wmac_resources[0].start = QCA953X_WMAC_BASE; -++ ath79_wmac_resources[0].end = QCA953X_WMAC_BASE + QCA953X_WMAC_SIZE - 1; -++ ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1); -++ ath79_wmac_resources[1].end = ATH79_IP2_IRQ(1); -++ -++ /* QCA953X only supports 25MHz ref_clk */ -++ ath79_wmac_data.is_clk_25mhz = true; -++ -++ ath79_wmac_data.get_mac_revision = ar93xx_get_soc_revision; -++} -++ -+ static void qca955x_wmac_setup(void) -+ { -+ u32 t; -+@@ -379,6 +394,8 @@ void __init ath79_register_wmac(u8 *cal_ -+ ar933x_wmac_setup(); -+ else if (soc_is_ar934x()) -+ ar934x_wmac_setup(); -++ else if (soc_is_qca953x()) -++ qca953x_wmac_setup(); -+ else if (soc_is_qca955x()) -+ qca955x_wmac_setup(); -+ else -+--- a/arch/mips/ath79/early_printk.c -++++ b/arch/mips/ath79/early_printk.c -+@@ -116,6 +116,8 @@ static void prom_putchar_init(void) -+ case REV_ID_MAJOR_AR9341: -+ case REV_ID_MAJOR_AR9342: -+ case REV_ID_MAJOR_AR9344: -++ case REV_ID_MAJOR_QCA9533: -++ case REV_ID_MAJOR_QCA9533_V2: -+ case REV_ID_MAJOR_QCA9556: -+ case REV_ID_MAJOR_QCA9558: -+ _prom_putchar = prom_putchar_ar71xx; -+--- a/arch/mips/ath79/gpio.c -++++ b/arch/mips/ath79/gpio.c -+@@ -31,7 +31,7 @@ static void __iomem *ath79_gpio_get_func -+ soc_is_ar913x() || -+ soc_is_ar933x()) -+ reg = AR71XX_GPIO_REG_FUNC; -+- else if (soc_is_ar934x()) -++ else if (soc_is_ar934x() || soc_is_qca953x()) -+ reg = AR934X_GPIO_REG_FUNC; -+ else -+ BUG(); -+@@ -64,7 +64,7 @@ void __init ath79_gpio_output_select(uns -+ unsigned int reg; -+ u32 t, s; -+ -+- BUG_ON(!soc_is_ar934x()); -++ BUG_ON(!soc_is_ar934x() && !soc_is_qca953x()); -+ -+ if (gpio >= AR934X_GPIO_COUNT) -+ return; -+--- a/arch/mips/ath79/irq.c -++++ b/arch/mips/ath79/irq.c -+@@ -62,6 +62,34 @@ static void ar934x_ip2_irq_init(void) -+ irq_set_chained_handler(ATH79_CPU_IRQ(2), ar934x_ip2_irq_dispatch); -+ } -+ -++static void qca953x_ip2_irq_dispatch(struct irq_desc *desc) -++{ -++ u32 status; -++ -++ status = ath79_reset_rr(QCA953X_RESET_REG_PCIE_WMAC_INT_STATUS); -++ -++ if (status & QCA953X_PCIE_WMAC_INT_PCIE_ALL) { -++ ath79_ddr_wb_flush(3); -++ generic_handle_irq(ATH79_IP2_IRQ(0)); -++ } else if (status & QCA953X_PCIE_WMAC_INT_WMAC_ALL) { -++ ath79_ddr_wb_flush(4); -++ generic_handle_irq(ATH79_IP2_IRQ(1)); -++ } else { -++ spurious_interrupt(); -++ } -++} -++ -++static void qca953x_irq_init(void) -++{ -++ int i; -++ -++ for (i = ATH79_IP2_IRQ_BASE; -++ i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) -++ irq_set_chip_and_handler(i, &dummy_irq_chip, handle_level_irq); -++ -++ irq_set_chained_handler(ATH79_CPU_IRQ(2), qca953x_ip2_irq_dispatch); -++} -++ -+ static void qca955x_ip2_irq_dispatch(struct irq_desc *desc) -+ { -+ u32 status; -+@@ -149,7 +177,7 @@ void __init arch_init_irq(void) -+ soc_is_ar913x() || soc_is_ar933x()) { -+ irq_wb_chan2 = 3; -+ irq_wb_chan3 = 2; -+- } else if (soc_is_ar934x()) { -++ } else if (soc_is_ar934x() || soc_is_qca953x()) { -+ irq_wb_chan3 = 2; -+ } -+ -+@@ -160,6 +188,7 @@ void __init arch_init_irq(void) -+ else if (soc_is_ar724x() || -+ soc_is_ar933x() || -+ soc_is_ar934x() || -++ soc_is_qca953x() || -+ soc_is_qca955x()) -+ misc_is_ar71xx = false; -+ else -+@@ -170,6 +199,8 @@ void __init arch_init_irq(void) -+ -+ if (soc_is_ar934x()) -+ ar934x_ip2_irq_init(); -++ else if (soc_is_qca953x()) -++ qca953x_irq_init(); -+ else if (soc_is_qca955x()) -+ qca955x_irq_init(); -+ } -+--- a/arch/mips/ath79/setup.c -++++ b/arch/mips/ath79/setup.c -+@@ -60,6 +60,7 @@ static void __init ath79_detect_sys_type -+ u32 major; -+ u32 minor; -+ u32 rev = 0; -++ u32 ver = 1; -+ -+ id = ath79_reset_rr(AR71XX_RESET_REG_REV_ID); -+ major = id & REV_ID_MAJOR_MASK; -+@@ -152,6 +153,17 @@ static void __init ath79_detect_sys_type -+ rev = id & AR934X_REV_ID_REVISION_MASK; -+ break; -+ -++ case REV_ID_MAJOR_QCA9533_V2: -++ ver = 2; -++ ath79_soc_rev = 2; -++ /* drop through */ -++ -++ case REV_ID_MAJOR_QCA9533: -++ ath79_soc = ATH79_SOC_QCA9533; -++ chip = "9533"; -++ rev = id & QCA953X_REV_ID_REVISION_MASK; -++ break; -++ -+ case REV_ID_MAJOR_QCA9556: -+ ath79_soc = ATH79_SOC_QCA9556; -+ chip = "9556"; -+@@ -168,11 +180,12 @@ static void __init ath79_detect_sys_type -+ panic("ath79: unknown SoC, id:0x%08x", id); -+ } -+ -+- ath79_soc_rev = rev; -++ if (ver == 1) -++ ath79_soc_rev = rev; -+ -+- if (soc_is_qca955x()) -+- sprintf(ath79_sys_type, "Qualcomm Atheros QCA%s rev %u", -+- chip, rev); -++ if (soc_is_qca953x() || soc_is_qca955x()) -++ sprintf(ath79_sys_type, "Qualcomm Atheros QCA%s ver %u rev %u", -++ chip, ver, rev); -+ else -+ sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev); -+ pr_info("SoC: %s\n", ath79_sys_type); -+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -+@@ -105,6 +105,21 @@ -+ #define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000) -+ #define AR934X_SRIF_SIZE 0x1000 -+ -++#define QCA953X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) -++#define QCA953X_GMAC_SIZE 0x14 -++#define QCA953X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) -++#define QCA953X_WMAC_SIZE 0x20000 -++#define QCA953X_EHCI_BASE 0x1b000000 -++#define QCA953X_EHCI_SIZE 0x200 -++#define QCA953X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000) -++#define QCA953X_SRIF_SIZE 0x1000 -++ -++#define QCA953X_PCI_CFG_BASE0 0x14000000 -++#define QCA953X_PCI_CTRL_BASE0 (AR71XX_APB_BASE + 0x000f0000) -++#define QCA953X_PCI_CRP_BASE0 (AR71XX_APB_BASE + 0x000c0000) -++#define QCA953X_PCI_MEM_BASE0 0x10000000 -++#define QCA953X_PCI_MEM_SIZE 0x02000000 -++ -+ #define QCA955X_PCI_MEM_BASE0 0x10000000 -+ #define QCA955X_PCI_MEM_BASE1 0x12000000 -+ #define QCA955X_PCI_MEM_SIZE 0x02000000 -+@@ -180,6 +195,12 @@ -+ #define AR934X_OTP_INTF3_ADDRESS 0x3100c -+ #define AR934X_OTP_PGENB_SETUP_HOLD_TIME_ADDRESS 0x31034 -+ -++#define QCA953X_DDR_REG_FLUSH_GE0 0x9c -++#define QCA953X_DDR_REG_FLUSH_GE1 0xa0 -++#define QCA953X_DDR_REG_FLUSH_USB 0xa4 -++#define QCA953X_DDR_REG_FLUSH_PCIE 0xa8 -++#define QCA953X_DDR_REG_FLUSH_WMAC 0xac -++ -+ /* -+ * PLL block -+ */ -+@@ -289,6 +310,44 @@ -+ -+ #define AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL BIT(6) -+ -++#define QCA953X_PLL_CPU_CONFIG_REG 0x00 -++#define QCA953X_PLL_DDR_CONFIG_REG 0x04 -++#define QCA953X_PLL_CLK_CTRL_REG 0x08 -++#define QCA953X_PLL_SWITCH_CLOCK_CONTROL_REG 0x24 -++#define QCA953X_PLL_ETH_XMII_CONTROL_REG 0x2c -++#define QCA953X_PLL_ETH_SGMII_CONTROL_REG 0x48 -++ -++#define QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT 0 -++#define QCA953X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f -++#define QCA953X_PLL_CPU_CONFIG_NINT_SHIFT 6 -++#define QCA953X_PLL_CPU_CONFIG_NINT_MASK 0x3f -++#define QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT 12 -++#define QCA953X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f -++#define QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19 -++#define QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7 -++ -++#define QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT 0 -++#define QCA953X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff -++#define QCA953X_PLL_DDR_CONFIG_NINT_SHIFT 10 -++#define QCA953X_PLL_DDR_CONFIG_NINT_MASK 0x3f -++#define QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT 16 -++#define QCA953X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f -++#define QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23 -++#define QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7 -++ -++#define QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2) -++#define QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3) -++#define QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS BIT(4) -++#define QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT 5 -++#define QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK 0x1f -++#define QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT 10 -++#define QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK 0x1f -++#define QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT 15 -++#define QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK 0x1f -++#define QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20) -++#define QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21) -++#define QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) -++ -+ #define QCA955X_PLL_CPU_CONFIG_REG 0x00 -+ #define QCA955X_PLL_DDR_CONFIG_REG 0x04 -+ #define QCA955X_PLL_CLK_CTRL_REG 0x08 -+@@ -365,6 +424,10 @@ -+ #define AR934X_RESET_REG_BOOTSTRAP 0xb0 -+ #define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac -+ -++#define QCA953X_RESET_REG_RESET_MODULE 0x1c -++#define QCA953X_RESET_REG_BOOTSTRAP 0xb0 -++#define QCA953X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac -++ -+ #define QCA955X_RESET_REG_RESET_MODULE 0x1c -+ #define QCA955X_RESET_REG_BOOTSTRAP 0xb0 -+ #define QCA955X_RESET_REG_EXT_INT_STATUS 0xac -+@@ -460,6 +523,27 @@ -+ #define AR934X_RESET_MBOX BIT(1) -+ #define AR934X_RESET_I2S BIT(0) -+ -++#define QCA953X_RESET_USB_EXT_PWR BIT(29) -++#define QCA953X_RESET_EXTERNAL BIT(28) -++#define QCA953X_RESET_RTC BIT(27) -++#define QCA953X_RESET_FULL_CHIP BIT(24) -++#define QCA953X_RESET_GE1_MDIO BIT(23) -++#define QCA953X_RESET_GE0_MDIO BIT(22) -++#define QCA953X_RESET_CPU_NMI BIT(21) -++#define QCA953X_RESET_CPU_COLD BIT(20) -++#define QCA953X_RESET_DDR BIT(16) -++#define QCA953X_RESET_USB_PHY_PLL_PWD_EXT BIT(15) -++#define QCA953X_RESET_GE1_MAC BIT(13) -++#define QCA953X_RESET_ETH_SWITCH_ANALOG BIT(12) -++#define QCA953X_RESET_USB_PHY_ANALOG BIT(11) -++#define QCA953X_RESET_GE0_MAC BIT(9) -++#define QCA953X_RESET_ETH_SWITCH BIT(8) -++#define QCA953X_RESET_PCIE_PHY BIT(7) -++#define QCA953X_RESET_PCIE BIT(6) -++#define QCA953X_RESET_USB_HOST BIT(5) -++#define QCA953X_RESET_USB_PHY BIT(4) -++#define QCA953X_RESET_USBSUS_OVERRIDE BIT(3) -++ -+ #define QCA955X_RESET_HOST BIT(31) -+ #define QCA955X_RESET_SLIC BIT(30) -+ #define QCA955X_RESET_HDMA BIT(29) -+@@ -513,6 +597,13 @@ -+ #define AR934X_BOOTSTRAP_SDRAM_DISABLED BIT(1) -+ #define AR934X_BOOTSTRAP_DDR1 BIT(0) -+ -++#define QCA953X_BOOTSTRAP_SW_OPTION2 BIT(12) -++#define QCA953X_BOOTSTRAP_SW_OPTION1 BIT(11) -++#define QCA953X_BOOTSTRAP_EJTAG_MODE BIT(5) -++#define QCA953X_BOOTSTRAP_REF_CLK BIT(4) -++#define QCA953X_BOOTSTRAP_SDRAM_DISABLED BIT(1) -++#define QCA953X_BOOTSTRAP_DDR1 BIT(0) -++ -+ #define QCA955X_BOOTSTRAP_REF_CLK_40 BIT(4) -+ -+ #define AR934X_PCIE_WMAC_INT_WMAC_MISC BIT(0) -+@@ -533,6 +624,24 @@ -+ AR934X_PCIE_WMAC_INT_PCIE_RC1 | AR934X_PCIE_WMAC_INT_PCIE_RC2 | \ -+ AR934X_PCIE_WMAC_INT_PCIE_RC3) -+ -++#define QCA953X_PCIE_WMAC_INT_WMAC_MISC BIT(0) -++#define QCA953X_PCIE_WMAC_INT_WMAC_TX BIT(1) -++#define QCA953X_PCIE_WMAC_INT_WMAC_RXLP BIT(2) -++#define QCA953X_PCIE_WMAC_INT_WMAC_RXHP BIT(3) -++#define QCA953X_PCIE_WMAC_INT_PCIE_RC BIT(4) -++#define QCA953X_PCIE_WMAC_INT_PCIE_RC0 BIT(5) -++#define QCA953X_PCIE_WMAC_INT_PCIE_RC1 BIT(6) -++#define QCA953X_PCIE_WMAC_INT_PCIE_RC2 BIT(7) -++#define QCA953X_PCIE_WMAC_INT_PCIE_RC3 BIT(8) -++#define QCA953X_PCIE_WMAC_INT_WMAC_ALL \ -++ (QCA953X_PCIE_WMAC_INT_WMAC_MISC | QCA953X_PCIE_WMAC_INT_WMAC_TX | \ -++ QCA953X_PCIE_WMAC_INT_WMAC_RXLP | QCA953X_PCIE_WMAC_INT_WMAC_RXHP) -++ -++#define QCA953X_PCIE_WMAC_INT_PCIE_ALL \ -++ (QCA953X_PCIE_WMAC_INT_PCIE_RC | QCA953X_PCIE_WMAC_INT_PCIE_RC0 | \ -++ QCA953X_PCIE_WMAC_INT_PCIE_RC1 | QCA953X_PCIE_WMAC_INT_PCIE_RC2 | \ -++ QCA953X_PCIE_WMAC_INT_PCIE_RC3) -++ -+ #define QCA955X_EXT_INT_WMAC_MISC BIT(0) -+ #define QCA955X_EXT_INT_WMAC_TX BIT(1) -+ #define QCA955X_EXT_INT_WMAC_RXLP BIT(2) -+@@ -575,6 +684,8 @@ -+ #define REV_ID_MAJOR_AR9341 0x0120 -+ #define REV_ID_MAJOR_AR9342 0x1120 -+ #define REV_ID_MAJOR_AR9344 0x2120 -++#define REV_ID_MAJOR_QCA9533 0x0140 -++#define REV_ID_MAJOR_QCA9533_V2 0x0160 -+ #define REV_ID_MAJOR_QCA9556 0x0130 -+ #define REV_ID_MAJOR_QCA9558 0x1130 -+ -+@@ -597,6 +708,8 @@ -+ -+ #define AR934X_REV_ID_REVISION_MASK 0xf -+ -++#define QCA953X_REV_ID_REVISION_MASK 0xf -++ -+ #define QCA955X_REV_ID_REVISION_MASK 0xf -+ -+ /* -+@@ -644,6 +757,25 @@ -+ #define AR934X_GPIO_REG_OUT_FUNC5 0x40 -+ #define AR934X_GPIO_REG_FUNC 0x6c -+ -++#define QCA953X_GPIO_REG_OUT_FUNC0 0x2c -++#define QCA953X_GPIO_REG_OUT_FUNC1 0x30 -++#define QCA953X_GPIO_REG_OUT_FUNC2 0x34 -++#define QCA953X_GPIO_REG_OUT_FUNC3 0x38 -++#define QCA953X_GPIO_REG_OUT_FUNC4 0x3c -++#define QCA953X_GPIO_REG_IN_ENABLE0 0x44 -++#define QCA953X_GPIO_REG_FUNC 0x6c -++ -++#define QCA953X_GPIO_OUT_MUX_SPI_CS1 10 -++#define QCA953X_GPIO_OUT_MUX_SPI_CS2 11 -++#define QCA953X_GPIO_OUT_MUX_SPI_CS0 9 -++#define QCA953X_GPIO_OUT_MUX_SPI_CLK 8 -++#define QCA953X_GPIO_OUT_MUX_SPI_MOSI 12 -++#define QCA953X_GPIO_OUT_MUX_LED_LINK1 41 -++#define QCA953X_GPIO_OUT_MUX_LED_LINK2 42 -++#define QCA953X_GPIO_OUT_MUX_LED_LINK3 43 -++#define QCA953X_GPIO_OUT_MUX_LED_LINK4 44 -++#define QCA953X_GPIO_OUT_MUX_LED_LINK5 45 -++ -+ #define QCA955X_GPIO_REG_OUT_FUNC0 0x2c -+ #define QCA955X_GPIO_REG_OUT_FUNC1 0x30 -+ #define QCA955X_GPIO_REG_OUT_FUNC2 0x34 -+@@ -658,6 +790,7 @@ -+ #define AR913X_GPIO_COUNT 22 -+ #define AR933X_GPIO_COUNT 30 -+ #define AR934X_GPIO_COUNT 23 -++#define QCA953X_GPIO_COUNT 18 -+ #define QCA955X_GPIO_COUNT 24 -+ -+ /* -+@@ -681,6 +814,24 @@ -+ #define AR934X_SRIF_DPLL2_OUTDIV_SHIFT 13 -+ #define AR934X_SRIF_DPLL2_OUTDIV_MASK 0x7 -+ -++#define QCA953X_SRIF_CPU_DPLL1_REG 0x1c0 -++#define QCA953X_SRIF_CPU_DPLL2_REG 0x1c4 -++#define QCA953X_SRIF_CPU_DPLL3_REG 0x1c8 -++ -++#define QCA953X_SRIF_DDR_DPLL1_REG 0x240 -++#define QCA953X_SRIF_DDR_DPLL2_REG 0x244 -++#define QCA953X_SRIF_DDR_DPLL3_REG 0x248 -++ -++#define QCA953X_SRIF_DPLL1_REFDIV_SHIFT 27 -++#define QCA953X_SRIF_DPLL1_REFDIV_MASK 0x1f -++#define QCA953X_SRIF_DPLL1_NINT_SHIFT 18 -++#define QCA953X_SRIF_DPLL1_NINT_MASK 0x1ff -++#define QCA953X_SRIF_DPLL1_NFRAC_MASK 0x0003ffff -++ -++#define QCA953X_SRIF_DPLL2_LOCAL_PLL BIT(30) -++#define QCA953X_SRIF_DPLL2_OUTDIV_SHIFT 13 -++#define QCA953X_SRIF_DPLL2_OUTDIV_MASK 0x7 -++ -+ #define AR71XX_GPIO_FUNC_STEREO_EN BIT(17) -+ #define AR71XX_GPIO_FUNC_SLIC_EN BIT(16) -+ #define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13) -+@@ -887,6 +1038,16 @@ -+ #define AR934X_ETH_CFG_RDV_DELAY_SHIFT 16 -+ -+ /* -++ * QCA953X GMAC Interface -++ */ -++#define QCA953X_GMAC_REG_ETH_CFG 0x00 -++ -++#define QCA953X_ETH_CFG_SW_ONLY_MODE BIT(6) -++#define QCA953X_ETH_CFG_SW_PHY_SWAP BIT(7) -++#define QCA953X_ETH_CFG_SW_APB_ACCESS BIT(9) -++#define QCA953X_ETH_CFG_SW_ACC_MSB_FIRST BIT(13) -++ -++/* -+ * QCA955X GMAC Interface -+ */ -+ -+--- a/arch/mips/include/asm/mach-ath79/ath79.h -++++ b/arch/mips/include/asm/mach-ath79/ath79.h -+@@ -32,6 +32,7 @@ enum ath79_soc_type { -+ ATH79_SOC_AR9341, -+ ATH79_SOC_AR9342, -+ ATH79_SOC_AR9344, -++ ATH79_SOC_QCA9533, -+ ATH79_SOC_QCA9556, -+ ATH79_SOC_QCA9558, -+ }; -+@@ -100,6 +101,16 @@ static inline int soc_is_ar934x(void) -+ return soc_is_ar9341() || soc_is_ar9342() || soc_is_ar9344(); -+ } -+ -++static inline int soc_is_qca9533(void) -++{ -++ return ath79_soc == ATH79_SOC_QCA9533; -++} -++ -++static inline int soc_is_qca953x(void) -++{ -++ return soc_is_qca9533(); -++} -++ -+ static inline int soc_is_qca9556(void) -+ { -+ return ath79_soc == ATH79_SOC_QCA9556; -diff --git a/target/linux/ar71xx/patches-4.14/621-MIPS-ath79-add-support-for-QCA956x-SoC.patch b/target/linux/ar71xx/patches-4.14/621-MIPS-ath79-add-support-for-QCA956x-SoC.patch -new file mode 100644 -index 0000000000..670f7bef0a ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/621-MIPS-ath79-add-support-for-QCA956x-SoC.patch -@@ -0,0 +1,717 @@ -+--- a/arch/mips/ath79/Kconfig -++++ b/arch/mips/ath79/Kconfig -+@@ -114,6 +114,12 @@ config SOC_QCA955X -+ select PCI_AR724X if PCI -+ def_bool n -+ -++config SOC_QCA956X -++ select USB_ARCH_HAS_EHCI -++ select HW_HAS_PCI -++ select PCI_AR724X if PCI -++ def_bool n -++ -+ config ATH79_DEV_M25P80 -+ select ATH79_DEV_SPI -+ def_bool n -+@@ -148,7 +154,7 @@ config ATH79_DEV_USB -+ def_bool n -+ -+ config ATH79_DEV_WMAC -+- depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA953X || SOC_QCA955X) -++ depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA953X || SOC_QCA955X || SOC_QCA956X) -+ def_bool n -+ -+ config ATH79_NVRAM -+--- a/arch/mips/ath79/clock.c -++++ b/arch/mips/ath79/clock.c -+@@ -523,6 +523,100 @@ static void __init qca955x_clocks_init(v -+ clk_add_alias("uart", NULL, "ref", NULL); -+ } -+ -++static void __init qca956x_clocks_init(void) -++{ -++ unsigned long ref_rate; -++ unsigned long cpu_rate; -++ unsigned long ddr_rate; -++ unsigned long ahb_rate; -++ u32 pll, out_div, ref_div, nint, hfrac, lfrac, clk_ctrl, postdiv; -++ u32 cpu_pll, ddr_pll; -++ u32 bootstrap; -++ -++ bootstrap = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP); -++ if (bootstrap & QCA956X_BOOTSTRAP_REF_CLK_40) -++ ref_rate = 40 * 1000 * 1000; -++ else -++ ref_rate = 25 * 1000 * 1000; -++ -++ pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG_REG); -++ out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & -++ QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK; -++ ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) & -++ QCA956X_PLL_CPU_CONFIG_REFDIV_MASK; -++ -++ pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG1_REG); -++ nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) & -++ QCA956X_PLL_CPU_CONFIG1_NINT_MASK; -++ hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) & -++ QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK; -++ lfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT) & -++ QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK; -++ -++ cpu_pll = nint * ref_rate / ref_div; -++ cpu_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); -++ cpu_pll += (hfrac >> 13) * ref_rate / ref_div; -++ cpu_pll /= (1 << out_div); -++ -++ pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG_REG); -++ out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & -++ QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK; -++ ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) & -++ QCA956X_PLL_DDR_CONFIG_REFDIV_MASK; -++ pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG1_REG); -++ nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) & -++ QCA956X_PLL_DDR_CONFIG1_NINT_MASK; -++ hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) & -++ QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK; -++ lfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT) & -++ QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK; -++ -++ ddr_pll = nint * ref_rate / ref_div; -++ ddr_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); -++ ddr_pll += (hfrac >> 13) * ref_rate / ref_div; -++ ddr_pll /= (1 << out_div); -++ -++ clk_ctrl = ath79_pll_rr(QCA956X_PLL_CLK_CTRL_REG); -++ -++ postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & -++ QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; -++ -++ if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS) -++ cpu_rate = ref_rate; -++ else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL) -++ cpu_rate = ddr_pll / (postdiv + 1); -++ else -++ cpu_rate = cpu_pll / (postdiv + 1); -++ -++ postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & -++ QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; -++ -++ if (clk_ctrl & QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS) -++ ddr_rate = ref_rate; -++ else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL) -++ ddr_rate = cpu_pll / (postdiv + 1); -++ else -++ ddr_rate = ddr_pll / (postdiv + 1); -++ -++ postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & -++ QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; -++ -++ if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS) -++ ahb_rate = ref_rate; -++ else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) -++ ahb_rate = ddr_pll / (postdiv + 1); -++ else -++ ahb_rate = cpu_pll / (postdiv + 1); -++ -++ ath79_add_sys_clkdev("ref", ref_rate); -++ ath79_add_sys_clkdev("cpu", cpu_rate); -++ ath79_add_sys_clkdev("ddr", ddr_rate); -++ ath79_add_sys_clkdev("ahb", ahb_rate); -++ -++ clk_add_alias("wdt", NULL, "ref", NULL); -++ clk_add_alias("uart", NULL, "ref", NULL); -++} -++ -+ void __init ath79_clocks_init(void) -+ { -+ if (soc_is_ar71xx()) -+@@ -537,6 +631,8 @@ void __init ath79_clocks_init(void) -+ qca953x_clocks_init(); -+ else if (soc_is_qca955x()) -+ qca955x_clocks_init(); -++ else if (soc_is_qca956x() || soc_is_tp9343()) -++ qca956x_clocks_init(); -+ else -+ BUG(); -+ } -+--- a/arch/mips/ath79/common.c -++++ b/arch/mips/ath79/common.c -+@@ -107,6 +107,8 @@ void ath79_device_reset_set(u32 mask) -+ reg = QCA953X_RESET_REG_RESET_MODULE; -+ else if (soc_is_qca955x()) -+ reg = QCA955X_RESET_REG_RESET_MODULE; -++ else if (soc_is_qca956x() || soc_is_tp9343()) -++ reg = QCA956X_RESET_REG_RESET_MODULE; -+ else -+ panic("Reset register not defined for this SOC"); -+ -+@@ -137,6 +139,8 @@ void ath79_device_reset_clear(u32 mask) -+ reg = QCA953X_RESET_REG_RESET_MODULE; -+ else if (soc_is_qca955x()) -+ reg = QCA955X_RESET_REG_RESET_MODULE; -++ else if (soc_is_qca956x() || soc_is_tp9343()) -++ reg = QCA956X_RESET_REG_RESET_MODULE; -+ else -+ panic("Reset register not defined for this SOC"); -+ -+@@ -163,6 +167,8 @@ u32 ath79_device_reset_get(u32 mask) -+ reg = AR933X_RESET_REG_RESET_MODULE; -+ else if (soc_is_ar934x()) -+ reg = AR934X_RESET_REG_RESET_MODULE; -++ else if (soc_is_qca956x() || soc_is_tp9343()) -++ reg = QCA956X_RESET_REG_RESET_MODULE; -+ else -+ BUG(); -+ -+--- a/arch/mips/ath79/dev-common.c -++++ b/arch/mips/ath79/dev-common.c -+@@ -95,7 +95,9 @@ void __init ath79_register_uart(void) -+ soc_is_ar913x() || -+ soc_is_ar934x() || -+ soc_is_qca953x() || -+- soc_is_qca955x()) { -++ soc_is_qca955x() || -++ soc_is_qca956x() || -++ soc_is_tp9343()) { -+ ath79_uart_data[0].uartclk = uart_clk_rate; -+ platform_device_register(&ath79_uart_device); -+ } else if (soc_is_ar933x()) { -+@@ -164,6 +166,9 @@ void __init ath79_gpio_init(void) -+ } else if (soc_is_qca955x()) { -+ ath79_gpio_pdata.ngpios = QCA955X_GPIO_COUNT; -+ ath79_gpio_pdata.oe_inverted = 1; -++ } else if (soc_is_qca956x() || soc_is_tp9343()) { -++ ath79_gpio_pdata.ngpios = QCA956X_GPIO_COUNT; -++ ath79_gpio_pdata.oe_inverted = 1; -+ } else { -+ BUG(); -+ } -+--- a/arch/mips/ath79/dev-usb.c -++++ b/arch/mips/ath79/dev-usb.c -+@@ -296,6 +296,19 @@ static void __init qca955x_usb_setup(voi -+ &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); -+ } -+ -++static void __init qca956x_usb_setup(void) -++{ -++ ath79_usb_register("ehci-platform", 0, -++ QCA956X_EHCI0_BASE, QCA956X_EHCI_SIZE, -++ ATH79_IP3_IRQ(0), -++ &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); -++ -++ ath79_usb_register("ehci-platform", 1, -++ QCA956X_EHCI1_BASE, QCA956X_EHCI_SIZE, -++ ATH79_IP3_IRQ(1), -++ &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); -++} -++ -+ void __init ath79_register_usb(void) -+ { -+ if (soc_is_ar71xx()) -+@@ -314,6 +327,8 @@ void __init ath79_register_usb(void) -+ qca953x_usb_setup(); -+ else if (soc_is_qca955x()) -+ qca955x_usb_setup(); -++ else if (soc_is_qca956x()) -++ qca956x_usb_setup(); -+ else -+ BUG(); -+ } -+--- a/arch/mips/ath79/dev-wmac.c -++++ b/arch/mips/ath79/dev-wmac.c -+@@ -195,6 +195,26 @@ static void qca955x_wmac_setup(void) -+ #define AR93XX_OTP_READ_DATA \ -+ (soc_is_ar934x() ? AR934X_OTP_READ_DATA : AR9300_OTP_READ_DATA) -+ -++static void qca956x_wmac_setup(void) -++{ -++ u32 t; -++ -++ ath79_wmac_device.name = "qca956x_wmac"; -++ -++ ath79_wmac_resources[0].start = QCA956X_WMAC_BASE; -++ ath79_wmac_resources[0].end = QCA956X_WMAC_BASE + QCA956X_WMAC_SIZE - 1; -++ ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1); -++ ath79_wmac_resources[1].end = ATH79_IP2_IRQ(1); -++ -++ t = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP); -++ if (t & QCA956X_BOOTSTRAP_REF_CLK_40) -++ ath79_wmac_data.is_clk_25mhz = false; -++ else -++ ath79_wmac_data.is_clk_25mhz = true; -++ -++ ath79_wmac_data.get_mac_revision = ar93xx_get_soc_revision; -++} -++ -+ static bool __init -+ ar93xx_wmac_otp_read_word(void __iomem *base, int addr, u32 *data) -+ { -+@@ -398,6 +418,8 @@ void __init ath79_register_wmac(u8 *cal_ -+ qca953x_wmac_setup(); -+ else if (soc_is_qca955x()) -+ qca955x_wmac_setup(); -++ else if (soc_is_qca956x() || soc_is_tp9343()) -++ qca956x_wmac_setup(); -+ else -+ BUG(); -+ -+--- a/arch/mips/ath79/early_printk.c -++++ b/arch/mips/ath79/early_printk.c -+@@ -120,6 +120,8 @@ static void prom_putchar_init(void) -+ case REV_ID_MAJOR_QCA9533_V2: -+ case REV_ID_MAJOR_QCA9556: -+ case REV_ID_MAJOR_QCA9558: -++ case REV_ID_MAJOR_TP9343: -++ case REV_ID_MAJOR_QCA956X: -+ _prom_putchar = prom_putchar_ar71xx; -+ break; -+ -+--- a/arch/mips/ath79/gpio.c -++++ b/arch/mips/ath79/gpio.c -+@@ -31,7 +31,10 @@ static void __iomem *ath79_gpio_get_func -+ soc_is_ar913x() || -+ soc_is_ar933x()) -+ reg = AR71XX_GPIO_REG_FUNC; -+- else if (soc_is_ar934x() || soc_is_qca953x()) -++ else if (soc_is_ar934x() || -++ soc_is_qca953x() || -++ soc_is_qca956x() || -++ soc_is_tp9343()) -+ reg = AR934X_GPIO_REG_FUNC; -+ else -+ BUG(); -+@@ -64,7 +67,7 @@ void __init ath79_gpio_output_select(uns -+ unsigned int reg; -+ u32 t, s; -+ -+- BUG_ON(!soc_is_ar934x() && !soc_is_qca953x()); -++ BUG_ON(!soc_is_ar934x() && !soc_is_qca953x() && !soc_is_qca956x()); -+ -+ if (gpio >= AR934X_GPIO_COUNT) -+ return; -+--- a/arch/mips/ath79/irq.c -++++ b/arch/mips/ath79/irq.c -+@@ -162,6 +162,87 @@ static void qca955x_irq_init(void) -+ irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch); -+ } -+ -++static void qca956x_ip2_irq_dispatch(struct irq_desc *desc) -++{ -++ u32 status; -++ -++ status = ath79_reset_rr(QCA956X_RESET_REG_EXT_INT_STATUS); -++ status &= QCA956X_EXT_INT_PCIE_RC1_ALL | QCA956X_EXT_INT_WMAC_ALL; -++ -++ if (status == 0) { -++ spurious_interrupt(); -++ return; -++ } -++ -++ if (status & QCA956X_EXT_INT_PCIE_RC1_ALL) { -++ /* TODO: flush DDR? */ -++ generic_handle_irq(ATH79_IP2_IRQ(0)); -++ } -++ -++ if (status & QCA956X_EXT_INT_WMAC_ALL) { -++ /* TODO: flsuh DDR? */ -++ generic_handle_irq(ATH79_IP2_IRQ(1)); -++ } -++} -++ -++static void qca956x_ip3_irq_dispatch(struct irq_desc *desc) -++{ -++ u32 status; -++ -++ status = ath79_reset_rr(QCA956X_RESET_REG_EXT_INT_STATUS); -++ status &= QCA956X_EXT_INT_PCIE_RC2_ALL | -++ QCA956X_EXT_INT_USB1 | QCA956X_EXT_INT_USB2; -++ -++ if (status == 0) { -++ spurious_interrupt(); -++ return; -++ } -++ -++ if (status & QCA956X_EXT_INT_USB1) { -++ /* TODO: flush DDR? */ -++ generic_handle_irq(ATH79_IP3_IRQ(0)); -++ } -++ -++ if (status & QCA956X_EXT_INT_USB2) { -++ /* TODO: flush DDR? */ -++ generic_handle_irq(ATH79_IP3_IRQ(1)); -++ } -++ -++ if (status & QCA956X_EXT_INT_PCIE_RC2_ALL) { -++ /* TODO: flush DDR? */ -++ generic_handle_irq(ATH79_IP3_IRQ(2)); -++ } -++} -++ -++static void qca956x_enable_timer_cb(void) { -++ u32 misc; -++ -++ misc = ath79_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE); -++ misc |= MISC_INT_MIPS_SI_TIMERINT_MASK; -++ ath79_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE, misc); -++} -++ -++static void qca956x_irq_init(void) -++{ -++ int i; -++ -++ for (i = ATH79_IP2_IRQ_BASE; -++ i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) -++ irq_set_chip_and_handler(i, &dummy_irq_chip, handle_level_irq); -++ -++ irq_set_chained_handler(ATH79_CPU_IRQ(2), qca956x_ip2_irq_dispatch); -++ -++ for (i = ATH79_IP3_IRQ_BASE; -++ i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++) -++ irq_set_chip_and_handler(i, &dummy_irq_chip, handle_level_irq); -++ -++ irq_set_chained_handler(ATH79_CPU_IRQ(3), qca956x_ip3_irq_dispatch); -++ -++ /* QCA956x timer init workaround has to be applied right before setting -++ * up the clock. Else, there will be no jiffies */ -++ late_time_init = &qca956x_enable_timer_cb; -++} -++ -+ void __init arch_init_irq(void) -+ { -+ unsigned irq_wb_chan2 = -1; -+@@ -189,7 +270,9 @@ void __init arch_init_irq(void) -+ soc_is_ar933x() || -+ soc_is_ar934x() || -+ soc_is_qca953x() || -+- soc_is_qca955x()) -++ soc_is_qca955x() || -++ soc_is_qca956x() || -++ soc_is_tp9343()) -+ misc_is_ar71xx = false; -+ else -+ BUG(); -+@@ -203,4 +286,6 @@ void __init arch_init_irq(void) -+ qca953x_irq_init(); -+ else if (soc_is_qca955x()) -+ qca955x_irq_init(); -++ else if (soc_is_qca956x() || soc_is_tp9343()) -++ qca956x_irq_init(); -+ } -+--- a/arch/mips/ath79/pci.c -++++ b/arch/mips/ath79/pci.c -+@@ -68,6 +68,21 @@ static const struct ath79_pci_irq qca955 -+ }, -+ }; -+ -++static const struct ath79_pci_irq qca956x_pci_irq_map[] = { -++ { -++ .bus = 0, -++ .slot = 0, -++ .pin = 1, -++ .irq = ATH79_PCI_IRQ(0), -++ }, -++ { -++ .bus = 1, -++ .slot = 0, -++ .pin = 1, -++ .irq = ATH79_PCI_IRQ(1), -++ }, -++}; -++ -+ int pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) -+ { -+ int irq = -1; -+@@ -86,6 +101,9 @@ int pcibios_map_irq(const struct pci_dev -+ } else if (soc_is_qca955x()) { -+ ath79_pci_irq_map = qca955x_pci_irq_map; -+ ath79_pci_nr_irqs = ARRAY_SIZE(qca955x_pci_irq_map); -++ } else if (soc_is_qca956x()) { -++ ath79_pci_irq_map = qca956x_pci_irq_map; -++ ath79_pci_nr_irqs = ARRAY_SIZE(qca956x_pci_irq_map); -+ } else { -+ pr_crit("pci %s: invalid irq map\n", -+ pci_name((struct pci_dev *) dev)); -+@@ -303,6 +321,15 @@ int __init ath79_register_pci(void) -+ QCA955X_PCI_MEM_SIZE, -+ 1, -+ ATH79_IP3_IRQ(2)); -++ } else if (soc_is_qca956x()) { -++ pdev = ath79_register_pci_ar724x(0, -++ QCA956X_PCI_CFG_BASE1, -++ QCA956X_PCI_CTRL_BASE1, -++ QCA956X_PCI_CRP_BASE1, -++ QCA956X_PCI_MEM_BASE1, -++ QCA956X_PCI_MEM_SIZE, -++ 1, -++ ATH79_IP3_IRQ(2)); -+ } else { -+ /* No PCI support */ -+ return -ENODEV; -+--- a/arch/mips/ath79/setup.c -++++ b/arch/mips/ath79/setup.c -+@@ -176,6 +176,18 @@ static void __init ath79_detect_sys_type -+ rev = id & QCA955X_REV_ID_REVISION_MASK; -+ break; -+ -++ case REV_ID_MAJOR_QCA956X: -++ ath79_soc = ATH79_SOC_QCA956X; -++ chip = "956X"; -++ rev = id & QCA956X_REV_ID_REVISION_MASK; -++ break; -++ -++ case REV_ID_MAJOR_TP9343: -++ ath79_soc = ATH79_SOC_TP9343; -++ chip = "9343"; -++ rev = id & QCA956X_REV_ID_REVISION_MASK; -++ break; -++ -+ default: -+ panic("ath79: unknown SoC, id:0x%08x", id); -+ } -+@@ -183,9 +195,12 @@ static void __init ath79_detect_sys_type -+ if (ver == 1) -+ ath79_soc_rev = rev; -+ -+- if (soc_is_qca953x() || soc_is_qca955x()) -++ if (soc_is_qca953x() || soc_is_qca955x() || soc_is_qca956x()) -+ sprintf(ath79_sys_type, "Qualcomm Atheros QCA%s ver %u rev %u", -+ chip, ver, rev); -++ else if (soc_is_tp9343()) -++ sprintf(ath79_sys_type, "Qualcomm Atheros TP%s rev %u", -++ chip, rev); -+ else -+ sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev); -+ pr_info("SoC: %s\n", ath79_sys_type); -+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -+@@ -143,6 +143,23 @@ -+ #define QCA955X_NFC_BASE 0x1b800200 -+ #define QCA955X_NFC_SIZE 0xb8 -+ -++#define QCA956X_PCI_MEM_BASE1 0x12000000 -++#define QCA956X_PCI_MEM_SIZE 0x02000000 -++#define QCA956X_PCI_CFG_BASE1 0x16000000 -++#define QCA956X_PCI_CFG_SIZE 0x1000 -++#define QCA956X_PCI_CRP_BASE1 (AR71XX_APB_BASE + 0x00250000) -++#define QCA956X_PCI_CRP_SIZE 0x1000 -++#define QCA956X_PCI_CTRL_BASE1 (AR71XX_APB_BASE + 0x00280000) -++#define QCA956X_PCI_CTRL_SIZE 0x100 -++ -++#define QCA956X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) -++#define QCA956X_WMAC_SIZE 0x20000 -++#define QCA956X_EHCI0_BASE 0x1b000000 -++#define QCA956X_EHCI1_BASE 0x1b400000 -++#define QCA956X_EHCI_SIZE 0x200 -++#define QCA956X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) -++#define QCA956X_GMAC_SIZE 0x64 -++ -+ #define AR9300_OTP_BASE 0x14000 -+ #define AR9300_OTP_STATUS 0x15f18 -+ #define AR9300_OTP_STATUS_TYPE 0x7 -+@@ -152,6 +169,13 @@ -+ #define AR9300_OTP_READ_DATA 0x15f1c -+ -+ /* -++ * Hidden Registers -++ */ -++#define QCA956X_DAM_RESET_OFFSET 0xb90001bc -++#define QCA956X_DAM_RESET_SIZE 0x4 -++#define QCA956X_INLINE_CHKSUM_ENG BIT(27) -++ -++/* -+ * DDR_CTRL block -+ */ -+ #define AR71XX_DDR_REG_PCI_WIN0 0x7c -+@@ -385,6 +409,49 @@ -+ #define QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21) -+ #define QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) -+ -++#define QCA956X_PLL_CPU_CONFIG_REG 0x00 -++#define QCA956X_PLL_CPU_CONFIG1_REG 0x04 -++#define QCA956X_PLL_DDR_CONFIG_REG 0x08 -++#define QCA956X_PLL_DDR_CONFIG1_REG 0x0c -++#define QCA956X_PLL_CLK_CTRL_REG 0x10 -++ -++#define QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT 12 -++#define QCA956X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f -++#define QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19 -++#define QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7 -++ -++#define QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT 0 -++#define QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK 0x1f -++#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT 5 -++#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK 0x1fff -++#define QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT 18 -++#define QCA956X_PLL_CPU_CONFIG1_NINT_MASK 0x1ff -++ -++#define QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT 16 -++#define QCA956X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f -++#define QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23 -++#define QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7 -++ -++#define QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT 0 -++#define QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK 0x1f -++#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT 5 -++#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK 0x1fff -++#define QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT 18 -++#define QCA956X_PLL_DDR_CONFIG1_NINT_MASK 0x1ff -++ -++#define QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2) -++#define QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3) -++#define QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS BIT(4) -++#define QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT 5 -++#define QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK 0x1f -++#define QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT 10 -++#define QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK 0x1f -++#define QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT 15 -++#define QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK 0x1f -++#define QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL BIT(20) -++#define QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL BIT(21) -++#define QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) -++ -+ /* -+ * USB_CONFIG block -+ */ -+@@ -432,6 +499,11 @@ -+ #define QCA955X_RESET_REG_BOOTSTRAP 0xb0 -+ #define QCA955X_RESET_REG_EXT_INT_STATUS 0xac -+ -++#define QCA956X_RESET_REG_RESET_MODULE 0x1c -++#define QCA956X_RESET_REG_BOOTSTRAP 0xb0 -++#define QCA956X_RESET_REG_EXT_INT_STATUS 0xac -++ -++#define MISC_INT_MIPS_SI_TIMERINT_MASK BIT(28) -+ #define MISC_INT_ETHSW BIT(12) -+ #define MISC_INT_TIMER4 BIT(10) -+ #define MISC_INT_TIMER3 BIT(9) -+@@ -606,6 +678,8 @@ -+ -+ #define QCA955X_BOOTSTRAP_REF_CLK_40 BIT(4) -+ -++#define QCA956X_BOOTSTRAP_REF_CLK_40 BIT(2) -++ -+ #define AR934X_PCIE_WMAC_INT_WMAC_MISC BIT(0) -+ #define AR934X_PCIE_WMAC_INT_WMAC_TX BIT(1) -+ #define AR934X_PCIE_WMAC_INT_WMAC_RXLP BIT(2) -+@@ -673,6 +747,37 @@ -+ QCA955X_EXT_INT_PCIE_RC2_INT1 | QCA955X_EXT_INT_PCIE_RC2_INT2 | \ -+ QCA955X_EXT_INT_PCIE_RC2_INT3) -+ -++#define QCA956X_EXT_INT_WMAC_MISC BIT(0) -++#define QCA956X_EXT_INT_WMAC_TX BIT(1) -++#define QCA956X_EXT_INT_WMAC_RXLP BIT(2) -++#define QCA956X_EXT_INT_WMAC_RXHP BIT(3) -++#define QCA956X_EXT_INT_PCIE_RC1 BIT(4) -++#define QCA956X_EXT_INT_PCIE_RC1_INT0 BIT(5) -++#define QCA956X_EXT_INT_PCIE_RC1_INT1 BIT(6) -++#define QCA956X_EXT_INT_PCIE_RC1_INT2 BIT(7) -++#define QCA956X_EXT_INT_PCIE_RC1_INT3 BIT(8) -++#define QCA956X_EXT_INT_PCIE_RC2 BIT(12) -++#define QCA956X_EXT_INT_PCIE_RC2_INT0 BIT(13) -++#define QCA956X_EXT_INT_PCIE_RC2_INT1 BIT(14) -++#define QCA956X_EXT_INT_PCIE_RC2_INT2 BIT(15) -++#define QCA956X_EXT_INT_PCIE_RC2_INT3 BIT(16) -++#define QCA956X_EXT_INT_USB1 BIT(24) -++#define QCA956X_EXT_INT_USB2 BIT(28) -++ -++#define QCA956X_EXT_INT_WMAC_ALL \ -++ (QCA956X_EXT_INT_WMAC_MISC | QCA956X_EXT_INT_WMAC_TX | \ -++ QCA956X_EXT_INT_WMAC_RXLP | QCA956X_EXT_INT_WMAC_RXHP) -++ -++#define QCA956X_EXT_INT_PCIE_RC1_ALL \ -++ (QCA956X_EXT_INT_PCIE_RC1 | QCA956X_EXT_INT_PCIE_RC1_INT0 | \ -++ QCA956X_EXT_INT_PCIE_RC1_INT1 | QCA956X_EXT_INT_PCIE_RC1_INT2 | \ -++ QCA956X_EXT_INT_PCIE_RC1_INT3) -++ -++#define QCA956X_EXT_INT_PCIE_RC2_ALL \ -++ (QCA956X_EXT_INT_PCIE_RC2 | QCA956X_EXT_INT_PCIE_RC2_INT0 | \ -++ QCA956X_EXT_INT_PCIE_RC2_INT1 | QCA956X_EXT_INT_PCIE_RC2_INT2 | \ -++ QCA956X_EXT_INT_PCIE_RC2_INT3) -++ -+ #define REV_ID_MAJOR_MASK 0xfff0 -+ #define REV_ID_MAJOR_AR71XX 0x00a0 -+ #define REV_ID_MAJOR_AR913X 0x00b0 -+@@ -688,6 +793,8 @@ -+ #define REV_ID_MAJOR_QCA9533_V2 0x0160 -+ #define REV_ID_MAJOR_QCA9556 0x0130 -+ #define REV_ID_MAJOR_QCA9558 0x1130 -++#define REV_ID_MAJOR_TP9343 0x0150 -++#define REV_ID_MAJOR_QCA956X 0x1150 -+ -+ #define AR71XX_REV_ID_MINOR_MASK 0x3 -+ #define AR71XX_REV_ID_MINOR_AR7130 0x0 -+@@ -712,6 +819,8 @@ -+ -+ #define QCA955X_REV_ID_REVISION_MASK 0xf -+ -++#define QCA956X_REV_ID_REVISION_MASK 0xf -++ -+ /* -+ * SPI block -+ */ -+@@ -784,6 +893,19 @@ -+ #define QCA955X_GPIO_REG_OUT_FUNC5 0x40 -+ #define QCA955X_GPIO_REG_FUNC 0x6c -+ -++#define QCA956X_GPIO_REG_OUT_FUNC0 0x2c -++#define QCA956X_GPIO_REG_OUT_FUNC1 0x30 -++#define QCA956X_GPIO_REG_OUT_FUNC2 0x34 -++#define QCA956X_GPIO_REG_OUT_FUNC3 0x38 -++#define QCA956X_GPIO_REG_OUT_FUNC4 0x3c -++#define QCA956X_GPIO_REG_OUT_FUNC5 0x40 -++#define QCA956X_GPIO_REG_IN_ENABLE0 0x44 -++#define QCA956X_GPIO_REG_IN_ENABLE3 0x50 -++#define QCA956X_GPIO_REG_FUNC 0x6c -++ -++#define QCA956X_GPIO_OUT_MUX_GE0_MDO 32 -++#define QCA956X_GPIO_OUT_MUX_GE0_MDC 33 -++ -+ #define AR71XX_GPIO_COUNT 16 -+ #define AR7240_GPIO_COUNT 18 -+ #define AR7241_GPIO_COUNT 20 -+@@ -792,6 +914,7 @@ -+ #define AR934X_GPIO_COUNT 23 -+ #define QCA953X_GPIO_COUNT 18 -+ #define QCA955X_GPIO_COUNT 24 -++#define QCA956X_GPIO_COUNT 23 -+ -+ /* -+ * SRIF block -+--- a/arch/mips/include/asm/mach-ath79/ath79.h -++++ b/arch/mips/include/asm/mach-ath79/ath79.h -+@@ -35,6 +35,8 @@ enum ath79_soc_type { -+ ATH79_SOC_QCA9533, -+ ATH79_SOC_QCA9556, -+ ATH79_SOC_QCA9558, -++ ATH79_SOC_TP9343, -++ ATH79_SOC_QCA956X, -+ }; -+ -+ extern enum ath79_soc_type ath79_soc; -+@@ -126,6 +128,26 @@ static inline int soc_is_qca955x(void) -+ return soc_is_qca9556() || soc_is_qca9558(); -+ } -+ -++static inline int soc_is_tp9343(void) -++{ -++ return ath79_soc == ATH79_SOC_TP9343; -++} -++ -++static inline int soc_is_qca9561(void) -++{ -++ return ath79_soc == ATH79_SOC_QCA956X; -++} -++ -++static inline int soc_is_qca9563(void) -++{ -++ return ath79_soc == ATH79_SOC_QCA956X; -++} -++ -++static inline int soc_is_qca956x(void) -++{ -++ return soc_is_qca9561() || soc_is_qca9563(); -++} -++ -+ void ath79_ddr_wb_flush(unsigned int reg); -+ void ath79_ddr_set_pci_windows(void); -+ -diff --git a/target/linux/ar71xx/patches-4.14/622-MIPS-ath79-add-more-register-defines-for-QCA956x-SoC.patch b/target/linux/ar71xx/patches-4.14/622-MIPS-ath79-add-more-register-defines-for-QCA956x-SoC.patch -new file mode 100644 -index 0000000000..cab2f6f9cb ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/622-MIPS-ath79-add-more-register-defines-for-QCA956x-SoC.patch -@@ -0,0 +1,38 @@ -+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -+@@ -157,6 +157,10 @@ -+ #define QCA956X_EHCI0_BASE 0x1b000000 -+ #define QCA956X_EHCI1_BASE 0x1b400000 -+ #define QCA956X_EHCI_SIZE 0x200 -++#define QCA956X_GMAC_SGMII_BASE (AR71XX_APB_BASE + 0x00070000) -++#define QCA956X_GMAC_SGMII_SIZE 0x64 -++#define QCA956X_PLL_BASE (AR71XX_APB_BASE + 0x00050000) -++#define QCA956X_PLL_SIZE 0x50 -+ #define QCA956X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) -+ #define QCA956X_GMAC_SIZE 0x64 -+ -+@@ -414,6 +418,7 @@ -+ #define QCA956X_PLL_DDR_CONFIG_REG 0x08 -+ #define QCA956X_PLL_DDR_CONFIG1_REG 0x0c -+ #define QCA956X_PLL_CLK_CTRL_REG 0x10 -++#define QCA956X_PLL_ETH_XMII_CONTROL_REG 0x30 -+ -+ #define QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT 12 -+ #define QCA956X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f -+@@ -1196,4 +1201,16 @@ -+ #define QCA955X_ETH_CFG_TXE_DELAY_MASK 0x3 -+ #define QCA955X_ETH_CFG_TXE_DELAY_SHIFT 20 -+ -++/* -++ * QCA956X GMAC Interface -++ */ -++ -++#define QCA956X_GMAC_REG_ETH_CFG 0x00 -++ -++#define QCA956X_ETH_CFG_SW_ONLY_MODE BIT(7) -++#define QCA956X_ETH_CFG_SW_PHY_SWAP BIT(8) -++#define QCA956X_ETH_CFG_SW_PHY_ADDR_SWAP BIT(9) -++#define QCA956X_ETH_CFG_SW_APB_ACCESS BIT(10) -++#define QCA956X_ETH_CFG_SW_ACC_MSB_FIRST BIT(13) -++ -+ #endif /* __ASM_MACH_AR71XX_REGS_H */ -diff --git a/target/linux/ar71xx/patches-4.14/630-MIPS-ath79-fix-chained-irq-disable.patch b/target/linux/ar71xx/patches-4.14/630-MIPS-ath79-fix-chained-irq-disable.patch -new file mode 100644 -index 0000000000..a74eb4f43e ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/630-MIPS-ath79-fix-chained-irq-disable.patch -@@ -0,0 +1,106 @@ -+--- a/arch/mips/ath79/irq.c -++++ b/arch/mips/ath79/irq.c -+@@ -27,6 +27,9 @@ -+ #include "machtypes.h" -+ -+ -++static struct irq_chip ip2_chip; -++static struct irq_chip ip3_chip; -++ -+ static void ar934x_ip2_irq_dispatch(struct irq_desc *desc) -+ { -+ u32 status; -+@@ -56,8 +59,7 @@ static void ar934x_ip2_irq_init(void) -+ -+ for (i = ATH79_IP2_IRQ_BASE; -+ i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) -+- irq_set_chip_and_handler(i, &dummy_irq_chip, -+- handle_level_irq); -++ irq_set_chip_and_handler(i, &ip2_chip, handle_level_irq); -+ -+ irq_set_chained_handler(ATH79_CPU_IRQ(2), ar934x_ip2_irq_dispatch); -+ } -+@@ -85,7 +87,7 @@ static void qca953x_irq_init(void) -+ -+ for (i = ATH79_IP2_IRQ_BASE; -+ i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) -+- irq_set_chip_and_handler(i, &dummy_irq_chip, handle_level_irq); -++ irq_set_chip_and_handler(i, &ip2_chip, handle_level_irq); -+ -+ irq_set_chained_handler(ATH79_CPU_IRQ(2), qca953x_ip2_irq_dispatch); -+ } -+@@ -149,15 +151,13 @@ static void qca955x_irq_init(void) -+ -+ for (i = ATH79_IP2_IRQ_BASE; -+ i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) -+- irq_set_chip_and_handler(i, &dummy_irq_chip, -+- handle_level_irq); -++ irq_set_chip_and_handler(i, &ip2_chip, handle_level_irq); -+ -+ irq_set_chained_handler(ATH79_CPU_IRQ(2), qca955x_ip2_irq_dispatch); -+ -+ for (i = ATH79_IP3_IRQ_BASE; -+ i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++) -+- irq_set_chip_and_handler(i, &dummy_irq_chip, -+- handle_level_irq); -++ irq_set_chip_and_handler(i, &ip3_chip, handle_level_irq); -+ -+ irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch); -+ } -+@@ -228,13 +228,13 @@ static void qca956x_irq_init(void) -+ -+ for (i = ATH79_IP2_IRQ_BASE; -+ i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) -+- irq_set_chip_and_handler(i, &dummy_irq_chip, handle_level_irq); -++ irq_set_chip_and_handler(i, &ip2_chip, handle_level_irq); -+ -+ irq_set_chained_handler(ATH79_CPU_IRQ(2), qca956x_ip2_irq_dispatch); -+ -+ for (i = ATH79_IP3_IRQ_BASE; -+ i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++) -+- irq_set_chip_and_handler(i, &dummy_irq_chip, handle_level_irq); -++ irq_set_chip_and_handler(i, &ip3_chip, handle_level_irq); -+ -+ irq_set_chained_handler(ATH79_CPU_IRQ(3), qca956x_ip3_irq_dispatch); -+ -+@@ -243,12 +243,40 @@ static void qca956x_irq_init(void) -+ late_time_init = &qca956x_enable_timer_cb; -+ } -+ -++static void ath79_ip2_disable(struct irq_data *data) -++{ -++ disable_irq(ATH79_CPU_IRQ(2)); -++} -++ -++static void ath79_ip2_enable(struct irq_data *data) -++{ -++ enable_irq(ATH79_CPU_IRQ(2)); -++} -++ -++static void ath79_ip3_disable(struct irq_data *data) -++{ -++ disable_irq(ATH79_CPU_IRQ(3)); -++} -++ -++static void ath79_ip3_enable(struct irq_data *data) -++{ -++ enable_irq(ATH79_CPU_IRQ(3)); -++} -++ -+ void __init arch_init_irq(void) -+ { -+ unsigned irq_wb_chan2 = -1; -+ unsigned irq_wb_chan3 = -1; -+ bool misc_is_ar71xx; -+ -++ ip2_chip = dummy_irq_chip; -++ ip2_chip.irq_disable = ath79_ip2_disable; -++ ip2_chip.irq_enable = ath79_ip2_enable; -++ -++ ip3_chip = dummy_irq_chip; -++ ip3_chip.irq_disable = ath79_ip3_disable; -++ ip3_chip.irq_enable = ath79_ip3_enable; -++ -+ if (mips_machtype == ATH79_MACH_GENERIC_OF) { -+ irqchip_init(); -+ return; -diff --git a/target/linux/ar71xx/patches-4.14/631-MIPS-ath79-wmac-enable-set-led-pin.patch b/target/linux/ar71xx/patches-4.14/631-MIPS-ath79-wmac-enable-set-led-pin.patch -new file mode 100644 -index 0000000000..a312217711 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/631-MIPS-ath79-wmac-enable-set-led-pin.patch -@@ -0,0 +1,24 @@ -+--- a/arch/mips/ath79/dev-wmac.c -++++ b/arch/mips/ath79/dev-wmac.c -+@@ -406,6 +406,11 @@ void __init ath79_wmac_set_ext_lna_gpio( -+ ar934x_set_ext_lna_gpio(chain, gpio); -+ } -+ -++void __init ath79_wmac_set_led_pin(int gpio) -++{ -++ ath79_wmac_data.led_pin = gpio; -++} -++ -+ void __init ath79_register_wmac(u8 *cal_data, u8 *mac_addr) -+ { -+ if (soc_is_ar913x()) -+--- a/arch/mips/ath79/dev-wmac.h -++++ b/arch/mips/ath79/dev-wmac.h -+@@ -18,6 +18,7 @@ void ath79_wmac_disable_2ghz(void); -+ void ath79_wmac_disable_5ghz(void); -+ void ath79_wmac_set_tx_gain_buffalo(void); -+ void ath79_wmac_set_ext_lna_gpio(unsigned chain, int gpio); -++void ath79_wmac_set_led_pin(int gpio); -+ -+ bool ar93xx_wmac_read_mac_address(u8 *dest); -+ -diff --git a/target/linux/ar71xx/patches-4.14/632-MIPS-ath79-gpio-enable-set-direction.patch b/target/linux/ar71xx/patches-4.14/632-MIPS-ath79-gpio-enable-set-direction.patch -new file mode 100644 -index 0000000000..4cf36325e1 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/632-MIPS-ath79-gpio-enable-set-direction.patch -@@ -0,0 +1,32 @@ -+--- a/arch/mips/ath79/common.h -++++ b/arch/mips/ath79/common.h -+@@ -28,6 +28,7 @@ void ath79_gpio_function_enable(u32 mask -+ void ath79_gpio_function_disable(u32 mask); -+ void ath79_gpio_function_setup(u32 set, u32 clear); -+ void ath79_gpio_output_select(unsigned gpio, u8 val); -++int ath79_gpio_direction_select(unsigned gpio, bool oe); -+ void ath79_gpio_init(void); -+ -+ #endif /* __ATH79_COMMON_H */ -+--- a/arch/mips/ath79/gpio.c -++++ b/arch/mips/ath79/gpio.c -+@@ -83,3 +83,19 @@ void __init ath79_gpio_output_select(uns -+ /* flush write */ -+ (void) __raw_readl(base + reg); -+ } -++ -++int ath79_gpio_direction_select(unsigned gpio, bool oe) -++{ -++ void __iomem *base = ath79_gpio_base; -++ bool ieq_1 = (soc_is_ar934x() || -++ soc_is_qca953x()); -++ -++ if ((ieq_1 && oe) || (!ieq_1 && !oe)) -++ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << gpio), -++ base + AR71XX_GPIO_REG_OE); -++ else -++ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << gpio), -++ base + AR71XX_GPIO_REG_OE); -++ -++ return 0; -++} -diff --git a/target/linux/ar71xx/patches-4.14/640-MIPS-ath79-add-QCA955x-wmac-reset.patch b/target/linux/ar71xx/patches-4.14/640-MIPS-ath79-add-QCA955x-wmac-reset.patch -new file mode 100644 -index 0000000000..bb315a1e65 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/640-MIPS-ath79-add-QCA955x-wmac-reset.patch -@@ -0,0 +1,82 @@ -+--- a/arch/mips/ath79/common.c -++++ b/arch/mips/ath79/common.c -+@@ -38,7 +38,7 @@ unsigned int ath79_soc_rev; -+ void __iomem *ath79_pll_base; -+ void __iomem *ath79_reset_base; -+ EXPORT_SYMBOL_GPL(ath79_reset_base); -+-static void __iomem *ath79_ddr_base; -++void __iomem *ath79_ddr_base; -+ static void __iomem *ath79_ddr_wb_flush_base; -+ static void __iomem *ath79_ddr_pci_win_base; -+ -+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -+@@ -32,7 +32,7 @@ -+ #define AR71XX_SPI_SIZE 0x01000000 -+ -+ #define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000) -+-#define AR71XX_DDR_CTRL_SIZE 0x100 -++#define AR71XX_DDR_CTRL_SIZE 0x200 -+ #define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000) -+ #define AR71XX_UART_SIZE 0x100 -+ #define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000) -+@@ -229,6 +229,9 @@ -+ #define QCA953X_DDR_REG_FLUSH_PCIE 0xa8 -+ #define QCA953X_DDR_REG_FLUSH_WMAC 0xac -+ -++#define QCA955X_DDR_CTL_CONFIG 0x108 -++#define QCA955X_DDR_CTL_CONFIG_ACT_WMAC BIT(23) -++ -+ /* -+ * PLL block -+ */ -+--- a/arch/mips/ath79/dev-wmac.c -++++ b/arch/mips/ath79/dev-wmac.c -+@@ -165,6 +165,27 @@ static void qca953x_wmac_setup(void) -+ ath79_wmac_data.get_mac_revision = ar93xx_get_soc_revision; -+ } -+ -++static int ar955x_wmac_reset(void) -++{ -++ int i; -++ -++ /* Try to wait for WMAC DDR activity to stop */ -++ for (i = 0; i < 10; i++) { -++ if (!(__raw_readl(ath79_ddr_base + QCA955X_DDR_CTL_CONFIG) & -++ QCA955X_DDR_CTL_CONFIG_ACT_WMAC)) -++ break; -++ -++ udelay(10); -++ } -++ -++ ath79_device_reset_set(QCA955X_RESET_RTC); -++ udelay(10); -++ ath79_device_reset_clear(QCA955X_RESET_RTC); -++ udelay(10); -++ -++ return 0; -++} -++ -+ static void qca955x_wmac_setup(void) -+ { -+ u32 t; -+@@ -181,6 +202,8 @@ static void qca955x_wmac_setup(void) -+ ath79_wmac_data.is_clk_25mhz = false; -+ else -+ ath79_wmac_data.is_clk_25mhz = true; -++ -++ ath79_wmac_data.external_reset = ar955x_wmac_reset; -+ } -+ -+ #define AR93XX_WMAC_SIZE \ -+--- a/arch/mips/ath79/common.h -++++ b/arch/mips/ath79/common.h -+@@ -19,6 +19,8 @@ -+ #define ATH79_MEM_SIZE_MIN (2 * 1024 * 1024) -+ #define ATH79_MEM_SIZE_MAX (256 * 1024 * 1024) -+ -++extern void __iomem *ath79_ddr_base; -++ -+ void ath79_clocks_init(void); -+ unsigned long ath79_get_sys_clk_rate(const char *id); -+ -diff --git a/target/linux/ar71xx/patches-4.14/700-MIPS-ath79-add-openwrt-Kconfig.patch b/target/linux/ar71xx/patches-4.14/700-MIPS-ath79-add-openwrt-Kconfig.patch -new file mode 100644 -index 0000000000..093def8d11 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/700-MIPS-ath79-add-openwrt-Kconfig.patch -@@ -0,0 +1,11 @@ -+--- a/arch/mips/ath79/Kconfig -++++ b/arch/mips/ath79/Kconfig -+@@ -83,6 +83,8 @@ config ATH79_MACH_UBNT_XM -+ Say 'Y' here if you want your kernel to support the -+ Ubiquiti Networks XM (rev 1.0) board. -+ -++source "arch/mips/ath79/Kconfig.openwrt" -++ -+ endmenu -+ -+ config SOC_AR71XX -diff --git a/target/linux/ar71xx/patches-4.14/701-MIPS-ath79-add-routerboard-detection.patch b/target/linux/ar71xx/patches-4.14/701-MIPS-ath79-add-routerboard-detection.patch -new file mode 100644 -index 0000000000..ae9e7772b5 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/701-MIPS-ath79-add-routerboard-detection.patch -@@ -0,0 +1,35 @@ -+--- a/arch/mips/ath79/prom.c -++++ b/arch/mips/ath79/prom.c -+@@ -136,6 +136,32 @@ void __init prom_init(void) -+ initrd_end = initrd_start + fw_getenvl("initrd_size"); -+ } -+ #endif -++ -++ if (strstr(arcs_cmdline, "board=750Gr3") || -++ strstr(arcs_cmdline, "board=750i") || -++ strstr(arcs_cmdline, "board=750-hb") || -++ strstr(arcs_cmdline, "board=411") || -++ strstr(arcs_cmdline, "board=433") || -++ strstr(arcs_cmdline, "board=435") || -++ strstr(arcs_cmdline, "board=450") || -++ strstr(arcs_cmdline, "board=493") || -++ strstr(arcs_cmdline, "board=951G") || -++ strstr(arcs_cmdline, "board=H951L") || -++ strstr(arcs_cmdline, "board=952-hb") || -++ strstr(arcs_cmdline, "board=953gs") || -++ strstr(arcs_cmdline, "board=962") || -++ strstr(arcs_cmdline, "board=lhg") || -++ strstr(arcs_cmdline, "board=map-hb") || -++ strstr(arcs_cmdline, "board=map2-hb") || -++ strstr(arcs_cmdline, "board=wap-hb") || -++ strstr(arcs_cmdline, "board=wap-lte") || -++ strstr(arcs_cmdline, "board=wapg-sc") || -++ strstr(arcs_cmdline, "board=2011L") || -++ strstr(arcs_cmdline, "board=2011r") || -++ strstr(arcs_cmdline, "board=711Gr100") || -++ strstr(arcs_cmdline, "board=911L") || -++ strstr(arcs_cmdline, "board=922gs")) -++ ath79_prom_append_cmdline("console", "ttyS0,115200"); -+ } -+ -+ void __init prom_free_prom_memory(void) -diff --git a/target/linux/ar71xx/patches-4.14/702-MIPS-ath79-fixup-routerboot-board-parameter.patch b/target/linux/ar71xx/patches-4.14/702-MIPS-ath79-fixup-routerboot-board-parameter.patch -new file mode 100644 -index 0000000000..b8715bba9e ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/702-MIPS-ath79-fixup-routerboot-board-parameter.patch -@@ -0,0 +1,43 @@ -+From: Gabor Juhos -+Date: Sat, 2 Dec 2017 19:15:29 +0100 -+Subject: [PATCH] MIPS: ath79: fix board detection with newer RouterBOOT versions -+ -+Recent RouterBOOT version (at least version 3.41 on RB911G-5HPacD) -+use "Board=" kernel parameter instead of "board=" to pass the board -+name to the kernel. Due to this change the board detection code is -+not working on the devices shipped with the new RouterBOOT version. -+Because the kernel is unable to identify these boards they become -+unusable despite that they are supported by the current code. -+ -+Update the prom_init code to convert the 'Board' kernel parameter to -+'board'. After this change, the board detection works also with the -+new RouterBOOT versions. -+ -+Signed-off-by: Gabor Juhos -+--- -+--- a/arch/mips/ath79/prom.c -++++ b/arch/mips/ath79/prom.c -+@@ -104,6 +104,7 @@ static int __init ath79_prom_init_myload -+ void __init prom_init(void) -+ { -+ const char *env; -++ char *c; -+ -+ if (ath79_prom_init_myloader()) -+ return; -+@@ -137,6 +138,15 @@ void __init prom_init(void) -+ } -+ #endif -+ -++ /* -++ * RouterBOOT uses "Board" kernel parameter instead of "board" since -++ * version 3.41 (or so). Replace the first character of the parameter -++ * to keep board detection working. -++ */ -++ c = strstr(arcs_cmdline, "Board="); -++ if (c) -++ c[0] = 'b'; -++ -+ if (strstr(arcs_cmdline, "board=750Gr3") || -+ strstr(arcs_cmdline, "board=750i") || -+ strstr(arcs_cmdline, "board=750-hb") || -diff --git a/target/linux/ar71xx/patches-4.14/739-MIPS-ath79-add-gpio-func-register-for-QCA955x-SoC.patch b/target/linux/ar71xx/patches-4.14/739-MIPS-ath79-add-gpio-func-register-for-QCA955x-SoC.patch -new file mode 100644 -index 0000000000..a65f7d993f ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/739-MIPS-ath79-add-gpio-func-register-for-QCA955x-SoC.patch -@@ -0,0 +1,38 @@ -+--- a/arch/mips/ath79/gpio.c -++++ b/arch/mips/ath79/gpio.c -+@@ -33,6 +33,7 @@ static void __iomem *ath79_gpio_get_func -+ reg = AR71XX_GPIO_REG_FUNC; -+ else if (soc_is_ar934x() || -+ soc_is_qca953x() || -++ soc_is_qca955x() || -+ soc_is_qca956x() || -+ soc_is_tp9343()) -+ reg = AR934X_GPIO_REG_FUNC; -+@@ -64,15 +65,21 @@ void ath79_gpio_function_disable(u32 mas -+ void __init ath79_gpio_output_select(unsigned gpio, u8 val) -+ { -+ void __iomem *base = ath79_gpio_base; -+- unsigned int reg; -++ unsigned int reg, reg_base; -+ u32 t, s; -+ -+- BUG_ON(!soc_is_ar934x() && !soc_is_qca953x() && !soc_is_qca956x()); -+- -+- if (gpio >= AR934X_GPIO_COUNT) -+- return; -++ if (soc_is_ar934x()) -++ reg_base = AR934X_GPIO_REG_OUT_FUNC0; -++ else if (soc_is_qca953x()) -++ reg_base = QCA953X_GPIO_REG_OUT_FUNC0; -++ else if (soc_is_qca955x()) -++ reg_base = QCA955X_GPIO_REG_OUT_FUNC0; -++ else if (soc_is_qca956x()) -++ reg_base = QCA956X_GPIO_REG_OUT_FUNC0; -++ else -++ BUG(); -+ -+- reg = AR934X_GPIO_REG_OUT_FUNC0 + 4 * (gpio / 4); -++ reg = reg_base + 4 * (gpio / 4); -+ s = 8 * (gpio % 4); -+ -+ t = __raw_readl(base + reg); -diff --git a/target/linux/ar71xx/patches-4.14/740-MIPS-ath79-add-PCI-for-QCA953x-SoC.patch b/target/linux/ar71xx/patches-4.14/740-MIPS-ath79-add-PCI-for-QCA953x-SoC.patch -new file mode 100644 -index 0000000000..659f74451c ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/740-MIPS-ath79-add-PCI-for-QCA953x-SoC.patch -@@ -0,0 +1,44 @@ -+--- a/arch/mips/ath79/pci.c -++++ b/arch/mips/ath79/pci.c -+@@ -53,6 +53,15 @@ static const struct ath79_pci_irq ar724x -+ } -+ }; -+ -++static const struct ath79_pci_irq qca953x_pci_irq_map[] = { -++ { -++ .bus = 0, -++ .slot = 0, -++ .pin = 1, -++ .irq = ATH79_PCI_IRQ(0), -++ }, -++}; -++ -+ static const struct ath79_pci_irq qca955x_pci_irq_map[] = { -+ { -+ .bus = 0, -+@@ -98,6 +107,9 @@ int pcibios_map_irq(const struct pci_dev -+ soc_is_ar9344()) { -+ ath79_pci_irq_map = ar724x_pci_irq_map; -+ ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map); -++ } else if (soc_is_qca953x()) { -++ ath79_pci_irq_map = qca953x_pci_irq_map; -++ ath79_pci_nr_irqs = ARRAY_SIZE(qca953x_pci_irq_map); -+ } else if (soc_is_qca955x()) { -+ ath79_pci_irq_map = qca955x_pci_irq_map; -+ ath79_pci_nr_irqs = ARRAY_SIZE(qca955x_pci_irq_map); -+@@ -303,6 +315,15 @@ int __init ath79_register_pci(void) -+ AR724X_PCI_MEM_SIZE, -+ 0, -+ ATH79_IP2_IRQ(0)); -++ } else if (soc_is_qca9533()) { -++ pdev = ath79_register_pci_ar724x(0, -++ QCA953X_PCI_CFG_BASE0, -++ QCA953X_PCI_CTRL_BASE0, -++ QCA953X_PCI_CRP_BASE0, -++ QCA953X_PCI_MEM_BASE0, -++ QCA953X_PCI_MEM_SIZE, -++ 0, -++ ATH79_IP2_IRQ(0)); -+ } else if (soc_is_qca9558()) { -+ pdev = ath79_register_pci_ar724x(0, -+ QCA955X_PCI_CFG_BASE0, -diff --git a/target/linux/ar71xx/patches-4.14/741-MIPS-ath79-add-PCI-for-QCA9556-SoC.patch b/target/linux/ar71xx/patches-4.14/741-MIPS-ath79-add-PCI-for-QCA9556-SoC.patch -new file mode 100644 -index 0000000000..5ca0784253 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/741-MIPS-ath79-add-PCI-for-QCA9556-SoC.patch -@@ -0,0 +1,12 @@ -+--- a/arch/mips/ath79/pci.c -++++ b/arch/mips/ath79/pci.c -+@@ -324,7 +324,8 @@ int __init ath79_register_pci(void) -+ QCA953X_PCI_MEM_SIZE, -+ 0, -+ ATH79_IP2_IRQ(0)); -+- } else if (soc_is_qca9558()) { -++ } else if (soc_is_qca9558() || -++ soc_is_qca9556()) { -+ pdev = ath79_register_pci_ar724x(0, -+ QCA955X_PCI_CFG_BASE0, -+ QCA955X_PCI_CTRL_BASE0, -diff --git a/target/linux/ar71xx/patches-4.14/818-MIPS-ath79-add-nu801-led-driver.patch b/target/linux/ar71xx/patches-4.14/818-MIPS-ath79-add-nu801-led-driver.patch -new file mode 100644 -index 0000000000..349c43d9fb ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/818-MIPS-ath79-add-nu801-led-driver.patch -@@ -0,0 +1,26 @@ -+--- a/drivers/leds/Kconfig -++++ b/drivers/leds/Kconfig -+@@ -632,6 +632,13 @@ config LEDS_IS31FL32XX -+ -+ comment "LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM)" -+ -++config LEDS_NU801 -++ tristate "LED driver for NU801 RGB LED" -++ depends on LEDS_CLASS && (ATH79_MACH_MR18 || ATH79_MACH_Z1) -++ help -++ This option enables support for NU801 RGB LED driver chips -++ accessed via GPIO. -++ -+ config LEDS_BLINKM -+ tristate "LED support for the BlinkM I2C RGB LED" -+ depends on LEDS_CLASS -+--- a/drivers/leds/Makefile -++++ b/drivers/leds/Makefile -+@@ -58,6 +58,7 @@ obj-$(CONFIG_LEDS_LT3593) += leds-lt359 -+ obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o -+ obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o -+ obj-$(CONFIG_LEDS_RB750) += leds-rb750.o -++obj-$(CONFIG_LEDS_NU801) += leds-nu801.o -+ obj-$(CONFIG_LEDS_NS2) += leds-ns2.o -+ obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o -+ obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o -diff --git a/target/linux/ar71xx/patches-4.14/820-MIPS-ath79-add_gpio_function2_setup.patch b/target/linux/ar71xx/patches-4.14/820-MIPS-ath79-add_gpio_function2_setup.patch -new file mode 100644 -index 0000000000..afa7b69b43 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/820-MIPS-ath79-add_gpio_function2_setup.patch -@@ -0,0 +1,67 @@ -+Add access to the function2 gpio register. This probably has to be -+converted into a pimux driver later on. This is needed for some setup -+functions on the Arduino Yun. -+ -+--- a/arch/mips/ath79/common.h -++++ b/arch/mips/ath79/common.h -+@@ -29,6 +29,7 @@ void ath79_ddr_ctrl_init(void); -+ void ath79_gpio_function_enable(u32 mask); -+ void ath79_gpio_function_disable(u32 mask); -+ void ath79_gpio_function_setup(u32 set, u32 clear); -++void ath79_gpio_function2_setup(u32 set, u32 clear); -+ void ath79_gpio_output_select(unsigned gpio, u8 val); -+ int ath79_gpio_direction_select(unsigned gpio, bool oe); -+ void ath79_gpio_init(void); -+--- a/arch/mips/ath79/gpio.c -++++ b/arch/mips/ath79/gpio.c -+@@ -43,6 +43,31 @@ static void __iomem *ath79_gpio_get_func -+ return ath79_gpio_base + reg; -+ } -+ -++static void __iomem *ath79_gpio_get_function2_reg(void) -++{ -++ u32 reg = 0; -++ -++ if (soc_is_ar71xx() || -++ soc_is_ar724x() || -++ soc_is_ar913x() || -++ soc_is_ar933x()) -++ reg = AR71XX_GPIO_REG_FUNC_2; -++ else -++ BUG(); -++ -++ return ath79_gpio_base + reg; -++} -++ -++ -++void ath79_gpio_function2_setup(u32 set, u32 clear) -++{ -++ void __iomem *reg = ath79_gpio_get_function2_reg(); -++ -++ __raw_writel((__raw_readl(reg) & ~clear) | set, reg); -++ /* flush write */ -++ __raw_readl(reg); -++} -++ -+ void ath79_gpio_function_setup(u32 set, u32 clear) -+ { -+ void __iomem *reg = ath79_gpio_get_function_reg(); -+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -+@@ -865,6 +865,7 @@ -+ #define AR71XX_GPIO_REG_INT_PENDING 0x20 -+ #define AR71XX_GPIO_REG_INT_ENABLE 0x24 -+ #define AR71XX_GPIO_REG_FUNC 0x28 -++#define AR71XX_GPIO_REG_FUNC_2 0x30 -+ -+ #define AR934X_GPIO_REG_OUT_FUNC0 0x2c -+ #define AR934X_GPIO_REG_OUT_FUNC1 0x30 -+@@ -989,6 +990,8 @@ -+ #define AR724X_GPIO_FUNC_UART_EN BIT(1) -+ #define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0) -+ -++#define AR933X_GPIO_FUNC2_JUMPSTART_DISABLE BIT(9) -++ -+ #define AR913X_GPIO_FUNC_WMAC_LED_EN BIT(22) -+ #define AR913X_GPIO_FUNC_EXP_PORT_CS_EN BIT(21) -+ #define AR913X_GPIO_FUNC_I2S_REFCLKEN BIT(20) -diff --git a/target/linux/ar71xx/patches-4.14/821-serial-core-add-support-for-boot-console-with-arbitr.patch b/target/linux/ar71xx/patches-4.14/821-serial-core-add-support-for-boot-console-with-arbitr.patch -new file mode 100644 -index 0000000000..23b6d73959 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/821-serial-core-add-support-for-boot-console-with-arbitr.patch -@@ -0,0 +1,54 @@ -+From 4d3c17975c7814884a721fe693b3adf5c426d759 Mon Sep 17 00:00:00 2001 -+From: Hauke Mehrtens -+Date: Tue, 10 Nov 2015 22:18:39 +0100 -+Subject: [RFC] serial: core: add support for boot console with arbitrary -+ baud rates -+ -+The Arduino Yun uses a baud rate of 250000 by default. The serial is -+going over the Atmel ATmega and is used to connect to this chip. -+Without this patch Linux wants to switch the console to 9600 Baud. -+ -+With this patch Linux will use the configured baud rate and not a -+default one specified in uart_register_driver(). -+ -+Signed-off-by: Hauke Mehrtens -+[rebased to 4.14, slightly reworded commit message] -+Signed-off-by: Sungbo Eo -+--- -+ drivers/tty/serial/serial_core.c | 6 +++++- -+ include/linux/console.h | 1 + -+ 2 files changed, 6 insertions(+), 1 deletions(-) -+ -+--- a/drivers/tty/serial/serial_core.c -++++ b/drivers/tty/serial/serial_core.c -+@@ -232,6 +232,8 @@ static int uart_port_startup(struct tty_ -+ if (retval == 0) { -+ if (uart_console(uport) && uport->cons->cflag) { -+ tty->termios.c_cflag = uport->cons->cflag; -++ tty->termios.c_ospeed = uport->cons->baud; -++ tty->termios.c_ispeed = uport->cons->baud; -+ uport->cons->cflag = 0; -+ } -+ /* -+@@ -2072,8 +2074,10 @@ uart_set_options(struct uart_port *port, -+ * Allow the setting of the UART parameters with a NULL console -+ * too: -+ */ -+- if (co) -++ if (co) { -+ co->cflag = termios.c_cflag; -++ co->baud = baud; -++ } -+ -+ return 0; -+ } -+--- a/include/linux/console.h -++++ b/include/linux/console.h -+@@ -145,6 +145,7 @@ struct console { -+ short flags; -+ short index; -+ int cflag; -++ int baud; -+ void *data; -+ struct console *next; -+ }; -diff --git a/target/linux/ar71xx/patches-4.14/900-mdio_bitbang_ignore_ta_value.patch b/target/linux/ar71xx/patches-4.14/900-mdio_bitbang_ignore_ta_value.patch -new file mode 100644 -index 0000000000..8f8f349a66 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/900-mdio_bitbang_ignore_ta_value.patch -@@ -0,0 +1,32 @@ -+--- a/drivers/net/phy/mdio-bitbang.c -++++ b/drivers/net/phy/mdio-bitbang.c -+@@ -155,7 +155,7 @@ static int mdiobb_cmd_addr(struct mdiobb -+ static int mdiobb_read(struct mii_bus *bus, int phy, int reg) -+ { -+ struct mdiobb_ctrl *ctrl = bus->priv; -+- int ret, i; -++ int ret; -+ -+ if (reg & MII_ADDR_C45) { -+ reg = mdiobb_cmd_addr(ctrl, phy, reg); -+@@ -165,19 +165,7 @@ static int mdiobb_read(struct mii_bus *b -+ -+ ctrl->ops->set_mdio_dir(ctrl, 0); -+ -+- /* check the turnaround bit: the PHY should be driving it to zero, if this -+- * PHY is listed in phy_ignore_ta_mask as having broken TA, skip that -+- */ -+- if (mdiobb_get_bit(ctrl) != 0 && -+- !(bus->phy_ignore_ta_mask & (1 << phy))) { -+- /* PHY didn't drive TA low -- flush any bits it -+- * may be trying to send. -+- */ -+- for (i = 0; i < 32; i++) -+- mdiobb_get_bit(ctrl); -+- -+- return 0xffff; -+- } -++ mdiobb_get_bit(ctrl); -+ -+ ret = mdiobb_get_num(ctrl, 16); -+ mdiobb_get_bit(ctrl); -diff --git a/target/linux/ar71xx/patches-4.14/901-phy-mdio-bitbang-prevent-rescheduling-during-command.patch b/target/linux/ar71xx/patches-4.14/901-phy-mdio-bitbang-prevent-rescheduling-during-command.patch -new file mode 100644 -index 0000000000..a830346a31 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/901-phy-mdio-bitbang-prevent-rescheduling-during-command.patch -@@ -0,0 +1,61 @@ -+From 66e584435ac0de6e0abeb6d7166fe4fe25d6bb73 Mon Sep 17 00:00:00 2001 -+From: Jonas Gorski -+Date: Tue, 16 Jun 2015 13:15:08 +0200 -+Subject: [PATCH] phy/mdio-bitbang: prevent rescheduling during command -+ -+It seems some phys have some maximum timings for accessing the MDIO line, -+resulting in bit errors under cpu stress. Prevent this from happening by -+disabling interrupts when sending commands. -+ -+Signed-off-by: Jonas Gorski -+--- -+ drivers/net/phy/mdio-bitbang.c | 9 +++++++++ -+ 1 file changed, 9 insertions(+) -+ -+--- a/drivers/net/phy/mdio-bitbang.c -++++ b/drivers/net/phy/mdio-bitbang.c -+@@ -17,6 +17,7 @@ -+ * kind, whether express or implied. -+ */ -+ -++#include -+ #include -+ #include -+ #include -+@@ -156,7 +157,9 @@ static int mdiobb_read(struct mii_bus *b -+ { -+ struct mdiobb_ctrl *ctrl = bus->priv; -+ int ret; -++ unsigned long flags; -+ -++ local_irq_save(flags); -+ if (reg & MII_ADDR_C45) { -+ reg = mdiobb_cmd_addr(ctrl, phy, reg); -+ mdiobb_cmd(ctrl, MDIO_C45_READ, phy, reg); -+@@ -169,13 +172,17 @@ static int mdiobb_read(struct mii_bus *b -+ -+ ret = mdiobb_get_num(ctrl, 16); -+ mdiobb_get_bit(ctrl); -++ local_irq_restore(flags); -++ -+ return ret; -+ } -+ -+ static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val) -+ { -+ struct mdiobb_ctrl *ctrl = bus->priv; -++ unsigned long flags; -+ -++ local_irq_save(flags); -+ if (reg & MII_ADDR_C45) { -+ reg = mdiobb_cmd_addr(ctrl, phy, reg); -+ mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, reg); -+@@ -190,6 +197,8 @@ static int mdiobb_write(struct mii_bus * -+ -+ ctrl->ops->set_mdio_dir(ctrl, 0); -+ mdiobb_get_bit(ctrl); -++ local_irq_restore(flags); -++ -+ return 0; -+ } -+ -diff --git a/target/linux/ar71xx/patches-4.14/902-at803x-add-reset-gpio-pdata.patch b/target/linux/ar71xx/patches-4.14/902-at803x-add-reset-gpio-pdata.patch -new file mode 100644 -index 0000000000..e4e51963bb ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/902-at803x-add-reset-gpio-pdata.patch -@@ -0,0 +1,68 @@ -+Add support for configuring AT803x GPIO reset via platform data. -+This is necessary, because ath79 is not converted to device tree yet. -+ -+Signed-off-by: Felix Fietkau -+ -+--- a/include/linux/platform_data/phy-at803x.h -++++ b/include/linux/platform_data/phy-at803x.h -+@@ -6,6 +6,8 @@ struct at803x_platform_data { -+ int enable_rgmii_tx_delay:1; -+ int enable_rgmii_rx_delay:1; -+ int fixup_rgmii_tx_delay:1; -++ int has_reset_gpio:1; -++ int reset_gpio; -+ }; -+ -+ #endif /* _PHY_AT803X_PDATA_H */ -+--- a/drivers/net/phy/at803x.c -++++ b/drivers/net/phy/at803x.c -+@@ -259,6 +259,7 @@ static int at803x_resume(struct phy_devi -+ -+ static int at803x_probe(struct phy_device *phydev) -+ { -++ struct at803x_platform_data *pdata; -+ struct device *dev = &phydev->mdio.dev; -+ struct at803x_priv *priv; -+ struct gpio_desc *gpiod_reset; -+@@ -271,6 +272,12 @@ static int at803x_probe(struct phy_devic -+ phydev->drv->phy_id != ATH8032_PHY_ID) -+ goto does_not_require_reset_workaround; -+ -++ pdata = dev_get_platdata(dev); -++ if (pdata && pdata->has_reset_gpio) { -++ devm_gpio_request(dev, pdata->reset_gpio, "reset"); -++ gpio_direction_output(pdata->reset_gpio, 1); -++ } -++ -+ gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); -+ if (IS_ERR(gpiod_reset)) -+ return PTR_ERR(gpiod_reset); -+@@ -402,15 +409,23 @@ static void at803x_link_change_notify(st -+ * cannot recover from by software. -+ */ -+ if (phydev->state == PHY_NOLINK) { -+- if (priv->gpiod_reset && !priv->phy_reset) { -++ if ((priv->gpiod_reset || (pdata && pdata->has_reset_gpio)) && -++ !priv->phy_reset) { -+ struct at803x_context context; -+ -+ at803x_context_save(phydev, &context); -+ -+- gpiod_set_value(priv->gpiod_reset, 1); -+- msleep(1); -+- gpiod_set_value(priv->gpiod_reset, 0); -+- msleep(1); -++ if (pdata && pdata->has_reset_gpio) { -++ gpio_set_value_cansleep(pdata->reset_gpio, 0); -++ msleep(1); -++ gpio_set_value_cansleep(pdata->reset_gpio, 1); -++ msleep(1); -++ } else { -++ gpiod_set_value(priv->gpiod_reset, 1); -++ msleep(1); -++ gpiod_set_value(priv->gpiod_reset, 0); -++ msleep(1); -++ } -+ -+ at803x_context_restore(phydev, &context); -+ -diff --git a/target/linux/ar71xx/patches-4.14/903-at803x-add-sgmii-aneg-override-pdata.patch b/target/linux/ar71xx/patches-4.14/903-at803x-add-sgmii-aneg-override-pdata.patch -new file mode 100644 -index 0000000000..600f8ff6de ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/903-at803x-add-sgmii-aneg-override-pdata.patch -@@ -0,0 +1,38 @@ -+--- a/drivers/net/phy/at803x.c -++++ b/drivers/net/phy/at803x.c -+@@ -458,12 +458,15 @@ static void at803x_link_change_notify(st -+ -+ static int at803x_aneg_done(struct phy_device *phydev) -+ { -++ struct at803x_platform_data *pdata; -+ int ccr; -+ -+ int aneg_done = genphy_aneg_done(phydev); -+ if (aneg_done != BMSR_ANEGCOMPLETE) -+ return aneg_done; -+ -++ pdata = dev_get_platdata(&phydev->mdio.dev); -++ -+ /* -+ * in SGMII mode, if copper side autoneg is successful, -+ * also check SGMII side autoneg result -+@@ -478,7 +481,8 @@ static int at803x_aneg_done(struct phy_d -+ /* check if the SGMII link is OK. */ -+ if (!(phy_read(phydev, AT803X_PSSR) & AT803X_PSSR_MR_AN_COMPLETE)) { -+ pr_warn("803x_aneg_done: SGMII link is not ok\n"); -+- aneg_done = 0; -++ if (!pdata || !pdata->override_sgmii_aneg) -++ aneg_done = 0; -+ } -+ /* switch back to copper page */ -+ phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr | AT803X_BT_BX_REG_SEL); -+--- a/include/linux/platform_data/phy-at803x.h -++++ b/include/linux/platform_data/phy-at803x.h -+@@ -7,6 +7,7 @@ struct at803x_platform_data { -+ int enable_rgmii_rx_delay:1; -+ int fixup_rgmii_tx_delay:1; -+ int has_reset_gpio:1; -++ int override_sgmii_aneg:1; -+ int reset_gpio; -+ }; -+ -diff --git a/target/linux/ar71xx/patches-4.14/910-unaligned_access_hacks.patch b/target/linux/ar71xx/patches-4.14/910-unaligned_access_hacks.patch -new file mode 100644 -index 0000000000..6938f96551 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/910-unaligned_access_hacks.patch -@@ -0,0 +1,942 @@ -+--- a/arch/mips/include/asm/checksum.h -++++ b/arch/mips/include/asm/checksum.h -+@@ -134,26 +134,30 @@ static inline __sum16 ip_fast_csum(const -+ const unsigned int *stop = word + ihl; -+ unsigned int csum; -+ int carry; -++ unsigned int w; -+ -+- csum = word[0]; -+- csum += word[1]; -+- carry = (csum < word[1]); -++ csum = net_hdr_word(word++); -++ -++ w = net_hdr_word(word++); -++ csum += w; -++ carry = (csum < w); -+ csum += carry; -+ -+- csum += word[2]; -+- carry = (csum < word[2]); -++ w = net_hdr_word(word++); -++ csum += w; -++ carry = (csum < w); -+ csum += carry; -+ -+- csum += word[3]; -+- carry = (csum < word[3]); -++ w = net_hdr_word(word++); -++ csum += w; -++ carry = (csum < w); -+ csum += carry; -+ -+- word += 4; -+ do { -+- csum += *word; -+- carry = (csum < *word); -++ w = net_hdr_word(word++); -++ csum += w; -++ carry = (csum < w); -+ csum += carry; -+- word++; -+ } while (word != stop); -+ -+ return csum_fold(csum); -+@@ -214,73 +218,6 @@ static inline __sum16 ip_compute_csum(co -+ return csum_fold(csum_partial(buff, len, 0)); -+ } -+ -+-#define _HAVE_ARCH_IPV6_CSUM -+-static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, -+- const struct in6_addr *daddr, -+- __u32 len, __u8 proto, -+- __wsum sum) -+-{ -+- __wsum tmp; -+- -+- __asm__( -+- " .set push # csum_ipv6_magic\n" -+- " .set noreorder \n" -+- " .set noat \n" -+- " addu %0, %5 # proto (long in network byte order)\n" -+- " sltu $1, %0, %5 \n" -+- " addu %0, $1 \n" -+- -+- " addu %0, %6 # csum\n" -+- " sltu $1, %0, %6 \n" -+- " lw %1, 0(%2) # four words source address\n" -+- " addu %0, $1 \n" -+- " addu %0, %1 \n" -+- " sltu $1, %0, %1 \n" -+- -+- " lw %1, 4(%2) \n" -+- " addu %0, $1 \n" -+- " addu %0, %1 \n" -+- " sltu $1, %0, %1 \n" -+- -+- " lw %1, 8(%2) \n" -+- " addu %0, $1 \n" -+- " addu %0, %1 \n" -+- " sltu $1, %0, %1 \n" -+- -+- " lw %1, 12(%2) \n" -+- " addu %0, $1 \n" -+- " addu %0, %1 \n" -+- " sltu $1, %0, %1 \n" -+- -+- " lw %1, 0(%3) \n" -+- " addu %0, $1 \n" -+- " addu %0, %1 \n" -+- " sltu $1, %0, %1 \n" -+- -+- " lw %1, 4(%3) \n" -+- " addu %0, $1 \n" -+- " addu %0, %1 \n" -+- " sltu $1, %0, %1 \n" -+- -+- " lw %1, 8(%3) \n" -+- " addu %0, $1 \n" -+- " addu %0, %1 \n" -+- " sltu $1, %0, %1 \n" -+- -+- " lw %1, 12(%3) \n" -+- " addu %0, $1 \n" -+- " addu %0, %1 \n" -+- " sltu $1, %0, %1 \n" -+- -+- " addu %0, $1 # Add final carry\n" -+- " .set pop" -+- : "=&r" (sum), "=&r" (tmp) -+- : "r" (saddr), "r" (daddr), -+- "0" (htonl(len)), "r" (htonl(proto)), "r" (sum)); -+- -+- return csum_fold(sum); -+-} -+- -+ #include -+ #endif /* CONFIG_GENERIC_CSUM */ -+ -+--- a/include/uapi/linux/ip.h -++++ b/include/uapi/linux/ip.h -+@@ -103,7 +103,7 @@ struct iphdr { -+ __be32 saddr; -+ __be32 daddr; -+ /*The options start here. */ -+-}; -++} __attribute__((packed, aligned(2))); -+ -+ -+ struct ip_auth_hdr { -+--- a/include/uapi/linux/ipv6.h -++++ b/include/uapi/linux/ipv6.h -+@@ -104,7 +104,7 @@ struct ipv6_destopt_hao { -+ __u8 type; -+ __u8 length; -+ struct in6_addr addr; -+-} __attribute__((packed)); -++} __attribute__((packed, aligned(2))); -+ -+ /* -+ * IPv6 fixed header -+@@ -131,7 +131,7 @@ struct ipv6hdr { -+ -+ struct in6_addr saddr; -+ struct in6_addr daddr; -+-}; -++} __attribute__((packed, aligned(2))); -+ -+ -+ /* index values for the variables in ipv6_devconf */ -+--- a/include/uapi/linux/tcp.h -++++ b/include/uapi/linux/tcp.h -+@@ -55,7 +55,7 @@ struct tcphdr { -+ __be16 window; -+ __sum16 check; -+ __be16 urg_ptr; -+-}; -++} __attribute__((packed, aligned(2))); -+ -+ /* -+ * The union cast uses a gcc extension to avoid aliasing problems -+@@ -65,7 +65,7 @@ struct tcphdr { -+ union tcp_word_hdr { -+ struct tcphdr hdr; -+ __be32 words[5]; -+-}; -++} __attribute__((packed, aligned(2))); -+ -+ #define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3]) -+ -+--- a/include/uapi/linux/udp.h -++++ b/include/uapi/linux/udp.h -+@@ -25,7 +25,7 @@ struct udphdr { -+ __be16 dest; -+ __be16 len; -+ __sum16 check; -+-}; -++} __attribute__((packed, aligned(2))); -+ -+ /* UDP socket options */ -+ #define UDP_CORK 1 /* Never send partially complete segments */ -+--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c -++++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c -+@@ -48,8 +48,8 @@ static bool ipv4_pkt_to_tuple(const stru -+ if (ap == NULL) -+ return false; -+ -+- tuple->src.u3.ip = ap[0]; -+- tuple->dst.u3.ip = ap[1]; -++ tuple->src.u3.ip = net_hdr_word(ap++); -++ tuple->dst.u3.ip = net_hdr_word(ap); -+ -+ return true; -+ } -+--- a/include/uapi/linux/icmp.h -++++ b/include/uapi/linux/icmp.h -+@@ -82,7 +82,7 @@ struct icmphdr { -+ } frag; -+ __u8 reserved[4]; -+ } un; -+-}; -++} __attribute__((packed, aligned(2))); -+ -+ -+ /* -+--- a/include/uapi/linux/in6.h -++++ b/include/uapi/linux/in6.h -+@@ -43,7 +43,7 @@ struct in6_addr { -+ #define s6_addr16 in6_u.u6_addr16 -+ #define s6_addr32 in6_u.u6_addr32 -+ #endif -+-}; -++} __attribute__((packed, aligned(2))); -+ #endif /* __UAPI_DEF_IN6_ADDR */ -+ -+ #if __UAPI_DEF_SOCKADDR_IN6 -+--- a/net/ipv6/tcp_ipv6.c -++++ b/net/ipv6/tcp_ipv6.c -+@@ -39,6 +39,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ #include -+@@ -819,10 +820,10 @@ static void tcp_v6_send_response(const s -+ topt = (__be32 *)(t1 + 1); -+ -+ if (tsecr) { -+- *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | -+- (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); -+- *topt++ = htonl(tsval); -+- *topt++ = htonl(tsecr); -++ put_unaligned_be32((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | -++ (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP, topt++); -++ put_unaligned_be32(tsval, topt++); -++ put_unaligned_be32(tsecr, topt++); -+ } -+ -+ #ifdef CONFIG_TCP_MD5SIG -+--- a/include/linux/ipv6.h -++++ b/include/linux/ipv6.h -+@@ -6,6 +6,7 @@ -+ -+ #define ipv6_optlen(p) (((p)->hdrlen+1) << 3) -+ #define ipv6_authlen(p) (((p)->hdrlen+2) << 2) -++ -+ /* -+ * This structure contains configuration options per IPv6 link. -+ */ -+--- a/net/ipv6/datagram.c -++++ b/net/ipv6/datagram.c -+@@ -486,7 +486,7 @@ int ipv6_recv_error(struct sock *sk, str -+ ipv6_iface_scope_id(&sin->sin6_addr, -+ IP6CB(skb)->iif); -+ } else { -+- ipv6_addr_set_v4mapped(*(__be32 *)(nh + serr->addr_offset), -++ ipv6_addr_set_v4mapped(net_hdr_word(nh + serr->addr_offset), -+ &sin->sin6_addr); -+ sin->sin6_scope_id = 0; -+ } -+@@ -835,12 +835,12 @@ int ip6_datagram_send_ctl(struct net *ne -+ } -+ -+ if (fl6->flowlabel&IPV6_FLOWINFO_MASK) { -+- if ((fl6->flowlabel^*(__be32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) { -++ if ((fl6->flowlabel^net_hdr_word(CMSG_DATA(cmsg)))&~IPV6_FLOWINFO_MASK) { -+ err = -EINVAL; -+ goto exit_f; -+ } -+ } -+- fl6->flowlabel = IPV6_FLOWINFO_MASK & *(__be32 *)CMSG_DATA(cmsg); -++ fl6->flowlabel = IPV6_FLOWINFO_MASK & net_hdr_word(CMSG_DATA(cmsg)); -+ break; -+ -+ case IPV6_2292HOPOPTS: -+--- a/net/ipv6/ip6_gre.c -++++ b/net/ipv6/ip6_gre.c -+@@ -400,7 +400,7 @@ static void ip6gre_err(struct sk_buff *s -+ return; -+ ipv6h = (const struct ipv6hdr *)skb->data; -+ greh = (const struct gre_base_hdr *)(skb->data + offset); -+- key = key_off ? *(__be32 *)(skb->data + key_off) : 0; -++ key = key_off ? net_hdr_word((__be32 *)(skb->data + key_off)) : 0; -+ -+ t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr, -+ key, greh->protocol); -+--- a/net/ipv6/exthdrs.c -++++ b/net/ipv6/exthdrs.c -+@@ -733,7 +733,7 @@ static bool ipv6_hop_jumbo(struct sk_buf -+ goto drop; -+ } -+ -+- pkt_len = ntohl(*(__be32 *)(nh + optoff + 2)); -++ pkt_len = ntohl(net_hdr_word(nh + optoff + 2)); -+ if (pkt_len <= IPV6_MAXPLEN) { -+ __IP6_INC_STATS(net, ipv6_skb_idev(skb), -+ IPSTATS_MIB_INHDRERRORS); -+--- a/include/linux/types.h -++++ b/include/linux/types.h -+@@ -229,5 +229,11 @@ struct callback_head { -+ typedef void (*rcu_callback_t)(struct rcu_head *head); -+ typedef void (*call_rcu_func_t)(struct rcu_head *head, rcu_callback_t func); -+ -++struct net_hdr_word { -++ u32 words[1]; -++} __attribute__((packed, aligned(2))); -++ -++#define net_hdr_word(_p) (((struct net_hdr_word *) (_p))->words[0]) -++ -+ #endif /* __ASSEMBLY__ */ -+ #endif /* _LINUX_TYPES_H */ -+--- a/net/ipv4/af_inet.c -++++ b/net/ipv4/af_inet.c -+@@ -1352,8 +1352,8 @@ struct sk_buff **inet_gro_receive(struct -+ if (unlikely(ip_fast_csum((u8 *)iph, 5))) -+ goto out_unlock; -+ -+- id = ntohl(*(__be32 *)&iph->id); -+- flush = (u16)((ntohl(*(__be32 *)iph) ^ skb_gro_len(skb)) | (id & ~IP_DF)); -++ id = ntohl(net_hdr_word(&iph->id)); -++ flush = (u16)((ntohl(net_hdr_word(iph)) ^ skb_gro_len(skb)) | (id & ~IP_DF)); -+ id >>= 16; -+ -+ for (p = *head; p; p = p->next) { -+--- a/net/ipv4/route.c -++++ b/net/ipv4/route.c -+@@ -464,7 +464,7 @@ static struct neighbour *ipv4_neigh_look -+ else if (skb) -+ pkey = &ip_hdr(skb)->daddr; -+ -+- n = __ipv4_neigh_lookup(dev, *(__force u32 *)pkey); -++ n = __ipv4_neigh_lookup(dev, net_hdr_word(pkey)); -+ if (n) -+ return n; -+ return neigh_create(&arp_tbl, pkey, dev); -+--- a/net/ipv4/tcp_output.c -++++ b/net/ipv4/tcp_output.c -+@@ -454,48 +454,53 @@ static void tcp_options_write(__be32 *pt -+ u16 options = opts->options; /* mungable copy */ -+ -+ if (unlikely(OPTION_MD5 & options)) { -+- *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | -+- (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG); -++ net_hdr_word(ptr++) = -++ htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | -++ (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG); -+ /* overload cookie hash location */ -+ opts->hash_location = (__u8 *)ptr; -+ ptr += 4; -+ } -+ -+ if (unlikely(opts->mss)) { -+- *ptr++ = htonl((TCPOPT_MSS << 24) | -+- (TCPOLEN_MSS << 16) | -+- opts->mss); -++ net_hdr_word(ptr++) = -++ htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | -++ opts->mss); -+ } -+ -+ if (likely(OPTION_TS & options)) { -+ if (unlikely(OPTION_SACK_ADVERTISE & options)) { -+- *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | -+- (TCPOLEN_SACK_PERM << 16) | -+- (TCPOPT_TIMESTAMP << 8) | -+- TCPOLEN_TIMESTAMP); -++ net_hdr_word(ptr++) = -++ htonl((TCPOPT_SACK_PERM << 24) | -++ (TCPOLEN_SACK_PERM << 16) | -++ (TCPOPT_TIMESTAMP << 8) | -++ TCPOLEN_TIMESTAMP); -+ options &= ~OPTION_SACK_ADVERTISE; -+ } else { -+- *ptr++ = htonl((TCPOPT_NOP << 24) | -+- (TCPOPT_NOP << 16) | -+- (TCPOPT_TIMESTAMP << 8) | -+- TCPOLEN_TIMESTAMP); -++ net_hdr_word(ptr++) = -++ htonl((TCPOPT_NOP << 24) | -++ (TCPOPT_NOP << 16) | -++ (TCPOPT_TIMESTAMP << 8) | -++ TCPOLEN_TIMESTAMP); -+ } -+- *ptr++ = htonl(opts->tsval); -+- *ptr++ = htonl(opts->tsecr); -++ net_hdr_word(ptr++) = htonl(opts->tsval); -++ net_hdr_word(ptr++) = htonl(opts->tsecr); -+ } -+ -+ if (unlikely(OPTION_SACK_ADVERTISE & options)) { -+- *ptr++ = htonl((TCPOPT_NOP << 24) | -+- (TCPOPT_NOP << 16) | -+- (TCPOPT_SACK_PERM << 8) | -+- TCPOLEN_SACK_PERM); -++ net_hdr_word(ptr++) = -++ htonl((TCPOPT_NOP << 24) | -++ (TCPOPT_NOP << 16) | -++ (TCPOPT_SACK_PERM << 8) | -++ TCPOLEN_SACK_PERM); -+ } -+ -+ if (unlikely(OPTION_WSCALE & options)) { -+- *ptr++ = htonl((TCPOPT_NOP << 24) | -+- (TCPOPT_WINDOW << 16) | -+- (TCPOLEN_WINDOW << 8) | -+- opts->ws); -++ net_hdr_word(ptr++) = -++ htonl((TCPOPT_NOP << 24) | -++ (TCPOPT_WINDOW << 16) | -++ (TCPOLEN_WINDOW << 8) | -++ opts->ws); -+ } -+ -+ if (unlikely(opts->num_sack_blocks)) { -+@@ -503,16 +508,17 @@ static void tcp_options_write(__be32 *pt -+ tp->duplicate_sack : tp->selective_acks; -+ int this_sack; -+ -+- *ptr++ = htonl((TCPOPT_NOP << 24) | -+- (TCPOPT_NOP << 16) | -+- (TCPOPT_SACK << 8) | -+- (TCPOLEN_SACK_BASE + (opts->num_sack_blocks * -++ net_hdr_word(ptr++) = -++ htonl((TCPOPT_NOP << 24) | -++ (TCPOPT_NOP << 16) | -++ (TCPOPT_SACK << 8) | -++ (TCPOLEN_SACK_BASE + (opts->num_sack_blocks * -+ TCPOLEN_SACK_PERBLOCK))); -+ -+ for (this_sack = 0; this_sack < opts->num_sack_blocks; -+ ++this_sack) { -+- *ptr++ = htonl(sp[this_sack].start_seq); -+- *ptr++ = htonl(sp[this_sack].end_seq); -++ net_hdr_word(ptr++) = htonl(sp[this_sack].start_seq); -++ net_hdr_word(ptr++) = htonl(sp[this_sack].end_seq); -+ } -+ -+ tp->rx_opt.dsack = 0; -+@@ -525,13 +531,14 @@ static void tcp_options_write(__be32 *pt -+ -+ if (foc->exp) { -+ len = TCPOLEN_EXP_FASTOPEN_BASE + foc->len; -+- *ptr = htonl((TCPOPT_EXP << 24) | (len << 16) | -++ net_hdr_word(ptr) = -++ htonl((TCPOPT_EXP << 24) | (len << 16) | -+ TCPOPT_FASTOPEN_MAGIC); -+ p += TCPOLEN_EXP_FASTOPEN_BASE; -+ } else { -+ len = TCPOLEN_FASTOPEN_BASE + foc->len; -+- *p++ = TCPOPT_FASTOPEN; -+- *p++ = len; -++ net_hdr_word(p++) = TCPOPT_FASTOPEN; -++ net_hdr_word(p++) = len; -+ } -+ -+ memcpy(p, foc->val, foc->len); -+--- a/net/ipv4/igmp.c -++++ b/net/ipv4/igmp.c -+@@ -548,7 +548,7 @@ static struct sk_buff *add_grec(struct s -+ if (!skb) -+ return NULL; -+ psrc = skb_put(skb, sizeof(__be32)); -+- *psrc = psf->sf_inaddr; -++ net_hdr_word(psrc) = psf->sf_inaddr; -+ scount++; stotal++; -+ if ((type == IGMPV3_ALLOW_NEW_SOURCES || -+ type == IGMPV3_BLOCK_OLD_SOURCES) && psf->sf_crcount) { -+--- a/include/uapi/linux/igmp.h -++++ b/include/uapi/linux/igmp.h -+@@ -33,7 +33,7 @@ struct igmphdr { -+ __u8 code; /* For newer IGMP */ -+ __sum16 csum; -+ __be32 group; -+-}; -++} __attribute__((packed, aligned(2))); -+ -+ /* V3 group record types [grec_type] */ -+ #define IGMPV3_MODE_IS_INCLUDE 1 -+@@ -49,7 +49,7 @@ struct igmpv3_grec { -+ __be16 grec_nsrcs; -+ __be32 grec_mca; -+ __be32 grec_src[0]; -+-}; -++} __attribute__((packed, aligned(2))); -+ -+ struct igmpv3_report { -+ __u8 type; -+@@ -58,7 +58,7 @@ struct igmpv3_report { -+ __be16 resv2; -+ __be16 ngrec; -+ struct igmpv3_grec grec[0]; -+-}; -++} __attribute__((packed, aligned(2))); -+ -+ struct igmpv3_query { -+ __u8 type; -+@@ -79,7 +79,7 @@ struct igmpv3_query { -+ __u8 qqic; -+ __be16 nsrcs; -+ __be32 srcs[0]; -+-}; -++} __attribute__((packed, aligned(2))); -+ -+ #define IGMP_HOST_MEMBERSHIP_QUERY 0x11 /* From RFC1112 */ -+ #define IGMP_HOST_MEMBERSHIP_REPORT 0x12 /* Ditto */ -+--- a/net/core/flow_dissector.c -++++ b/net/core/flow_dissector.c -+@@ -109,7 +109,7 @@ __be32 __skb_flow_get_ports(const struct -+ ports = __skb_header_pointer(skb, thoff + poff, -+ sizeof(_ports), data, hlen, &_ports); -+ if (ports) -+- return *ports; -++ return (__be32)net_hdr_word(ports); -+ } -+ -+ return 0; -+--- a/include/uapi/linux/icmpv6.h -++++ b/include/uapi/linux/icmpv6.h -+@@ -77,7 +77,7 @@ struct icmp6hdr { -+ #define icmp6_addrconf_other icmp6_dataun.u_nd_ra.other -+ #define icmp6_rt_lifetime icmp6_dataun.u_nd_ra.rt_lifetime -+ #define icmp6_router_pref icmp6_dataun.u_nd_ra.router_pref -+-}; -++} __attribute__((packed, aligned(2))); -+ -+ -+ #define ICMPV6_ROUTER_PREF_LOW 0x3 -+--- a/include/net/ndisc.h -++++ b/include/net/ndisc.h -+@@ -89,7 +89,7 @@ struct ra_msg { -+ struct icmp6hdr icmph; -+ __be32 reachable_time; -+ __be32 retrans_timer; -+-}; -++} __attribute__((packed, aligned(2))); -+ -+ struct rd_msg { -+ struct icmp6hdr icmph; -+@@ -368,10 +368,10 @@ static inline u32 ndisc_hashfn(const voi -+ { -+ const u32 *p32 = pkey; -+ -+- return (((p32[0] ^ hash32_ptr(dev)) * hash_rnd[0]) + -+- (p32[1] * hash_rnd[1]) + -+- (p32[2] * hash_rnd[2]) + -+- (p32[3] * hash_rnd[3])); -++ return (((net_hdr_word(&p32[0]) ^ hash32_ptr(dev)) * hash_rnd[0]) + -++ (net_hdr_word(&p32[1]) * hash_rnd[1]) + -++ (net_hdr_word(&p32[2]) * hash_rnd[2]) + -++ (net_hdr_word(&p32[3]) * hash_rnd[3])); -+ } -+ -+ static inline struct neighbour *__ipv6_neigh_lookup_noref(struct net_device *dev, const void *pkey) -+--- a/net/sched/cls_u32.c -++++ b/net/sched/cls_u32.c -+@@ -165,7 +165,7 @@ next_knode: -+ data = skb_header_pointer(skb, toff, 4, &hdata); -+ if (!data) -+ goto out; -+- if ((*data ^ key->val) & key->mask) { -++ if ((net_hdr_word(data) ^ key->val) & key->mask) { -+ n = rcu_dereference_bh(n->next); -+ goto next_knode; -+ } -+@@ -218,8 +218,8 @@ check_terminal: -+ &hdata); -+ if (!data) -+ goto out; -+- sel = ht->divisor & u32_hash_fold(*data, &n->sel, -+- n->fshift); -++ sel = ht->divisor & u32_hash_fold(net_hdr_word(data), -++ &n->sel, n->fshift); -+ } -+ if (!(n->sel.flags & (TC_U32_VAROFFSET | TC_U32_OFFSET | TC_U32_EAT))) -+ goto next_ht; -+--- a/net/ipv6/ip6_offload.c -++++ b/net/ipv6/ip6_offload.c -+@@ -221,7 +221,7 @@ static struct sk_buff **ipv6_gro_receive -+ continue; -+ -+ iph2 = (struct ipv6hdr *)(p->data + off); -+- first_word = *(__be32 *)iph ^ *(__be32 *)iph2; -++ first_word = net_hdr_word(iph) ^ net_hdr_word(iph2); -+ -+ /* All fields must match except length and Traffic Class. -+ * XXX skbs on the gro_list have all been parsed and pulled -+--- a/include/net/addrconf.h -++++ b/include/net/addrconf.h -+@@ -47,7 +47,7 @@ struct prefix_info { -+ __be32 reserved2; -+ -+ struct in6_addr prefix; -+-}; -++} __attribute__((packed, aligned(2))); -+ -+ #include -+ #include -+--- a/include/net/inet_ecn.h -++++ b/include/net/inet_ecn.h -+@@ -125,9 +125,9 @@ static inline int IP6_ECN_set_ce(struct -+ if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph))) -+ return 0; -+ -+- from = *(__be32 *)iph; -++ from = net_hdr_word(iph); -+ to = from | htonl(INET_ECN_CE << 20); -+- *(__be32 *)iph = to; -++ net_hdr_word(iph) = to; -+ if (skb->ip_summed == CHECKSUM_COMPLETE) -+ skb->csum = csum_add(csum_sub(skb->csum, (__force __wsum)from), -+ (__force __wsum)to); -+@@ -136,7 +136,7 @@ static inline int IP6_ECN_set_ce(struct -+ -+ static inline void IP6_ECN_clear(struct ipv6hdr *iph) -+ { -+- *(__be32*)iph &= ~htonl(INET_ECN_MASK << 20); -++ net_hdr_word(iph) &= ~htonl(INET_ECN_MASK << 20); -+ } -+ -+ static inline void ipv6_copy_dscp(unsigned int dscp, struct ipv6hdr *inner) -+--- a/include/net/ipv6.h -++++ b/include/net/ipv6.h -+@@ -108,7 +108,7 @@ struct frag_hdr { -+ __u8 reserved; -+ __be16 frag_off; -+ __be32 identification; -+-}; -++} __attribute__((packed, aligned(2))); -+ -+ #define IP6_MF 0x0001 -+ #define IP6_OFFSET 0xFFF8 -+@@ -437,8 +437,8 @@ static inline void __ipv6_addr_set_half( -+ } -+ #endif -+ #endif -+- addr[0] = wh; -+- addr[1] = wl; -++ net_hdr_word(&addr[0]) = wh; -++ net_hdr_word(&addr[1]) = wl; -+ } -+ -+ static inline void ipv6_addr_set(struct in6_addr *addr, -+@@ -497,6 +497,8 @@ static inline bool ipv6_prefix_equal(con -+ const __be32 *a1 = addr1->s6_addr32; -+ const __be32 *a2 = addr2->s6_addr32; -+ unsigned int pdw, pbi; -++ /* Used for last <32-bit fraction of prefix */ -++ u32 pbia1, pbia2; -+ -+ /* check complete u32 in prefix */ -+ pdw = prefixlen >> 5; -+@@ -505,7 +507,9 @@ static inline bool ipv6_prefix_equal(con -+ -+ /* check incomplete u32 in prefix */ -+ pbi = prefixlen & 0x1f; -+- if (pbi && ((a1[pdw] ^ a2[pdw]) & htonl((0xffffffff) << (32 - pbi)))) -++ pbia1 = net_hdr_word(&a1[pdw]); -++ pbia2 = net_hdr_word(&a2[pdw]); -++ if (pbi && ((pbia1 ^ pbia2) & htonl((0xffffffff) << (32 - pbi)))) -+ return false; -+ -+ return true; -+@@ -605,13 +609,13 @@ static inline void ipv6_addr_set_v4mappe -+ */ -+ static inline int __ipv6_addr_diff32(const void *token1, const void *token2, int addrlen) -+ { -+- const __be32 *a1 = token1, *a2 = token2; -++ const struct in6_addr *a1 = token1, *a2 = token2; -+ int i; -+ -+ addrlen >>= 2; -+ -+ for (i = 0; i < addrlen; i++) { -+- __be32 xb = a1[i] ^ a2[i]; -++ __be32 xb = a1->s6_addr32[i] ^ a2->s6_addr32[i]; -+ if (xb) -+ return i * 32 + 31 - __fls(ntohl(xb)); -+ } -+@@ -780,17 +784,18 @@ static inline int ip6_default_np_autolab -+ static inline void ip6_flow_hdr(struct ipv6hdr *hdr, unsigned int tclass, -+ __be32 flowlabel) -+ { -+- *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | flowlabel; -++ net_hdr_word((__be32 *)hdr) = -++ htonl(0x60000000 | (tclass << 20)) | flowlabel; -+ } -+ -+ static inline __be32 ip6_flowinfo(const struct ipv6hdr *hdr) -+ { -+- return *(__be32 *)hdr & IPV6_FLOWINFO_MASK; -++ return net_hdr_word((__be32 *)hdr) & IPV6_FLOWINFO_MASK; -+ } -+ -+ static inline __be32 ip6_flowlabel(const struct ipv6hdr *hdr) -+ { -+- return *(__be32 *)hdr & IPV6_FLOWLABEL_MASK; -++ return net_hdr_word((__be32 *)hdr) & IPV6_FLOWLABEL_MASK; -+ } -+ -+ static inline u8 ip6_tclass(__be32 flowinfo) -+--- a/include/net/secure_seq.h -++++ b/include/net/secure_seq.h -+@@ -3,6 +3,7 @@ -+ #define _NET_SECURE_SEQ -+ -+ #include -++#include -+ -+ u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); -+ u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, -+--- a/include/uapi/linux/in.h -++++ b/include/uapi/linux/in.h -+@@ -84,7 +84,7 @@ enum { -+ /* Internet address. */ -+ struct in_addr { -+ __be32 s_addr; -+-}; -++} __attribute__((packed, aligned(2))); -+ #endif -+ -+ #define IP_TOS 1 -+--- a/net/ipv6/ip6_fib.c -++++ b/net/ipv6/ip6_fib.c -+@@ -137,7 +137,7 @@ static __be32 addr_bit_set(const void *t -+ * See include/asm-generic/bitops/le.h. -+ */ -+ return (__force __be32)(1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)) & -+- addr[fn_bit >> 5]; -++ net_hdr_word(&addr[fn_bit >> 5]); -+ } -+ -+ static struct fib6_node *node_alloc(void) -+--- a/net/netfilter/nf_conntrack_proto_tcp.c -++++ b/net/netfilter/nf_conntrack_proto_tcp.c -+@@ -447,7 +447,7 @@ static void tcp_sack(const struct sk_buf -+ -+ /* Fast path for timestamp-only option */ -+ if (length == TCPOLEN_TSTAMP_ALIGNED -+- && *(__be32 *)ptr == htonl((TCPOPT_NOP << 24) -++ && net_hdr_word(ptr) == htonl((TCPOPT_NOP << 24) -+ | (TCPOPT_NOP << 16) -+ | (TCPOPT_TIMESTAMP << 8) -+ | TCPOLEN_TIMESTAMP)) -+--- a/net/xfrm/xfrm_input.c -++++ b/net/xfrm/xfrm_input.c -+@@ -193,8 +193,8 @@ int xfrm_parse_spi(struct sk_buff *skb, -+ if (!pskb_may_pull(skb, hlen)) -+ return -EINVAL; -+ -+- *spi = *(__be32 *)(skb_transport_header(skb) + offset); -+- *seq = *(__be32 *)(skb_transport_header(skb) + offset_seq); -++ *spi = net_hdr_word(skb_transport_header(skb) + offset); -++ *seq = net_hdr_word(skb_transport_header(skb) + offset_seq); -+ return 0; -+ } -+ EXPORT_SYMBOL(xfrm_parse_spi); -+--- a/net/ipv4/tcp_input.c -++++ b/net/ipv4/tcp_input.c -+@@ -3879,14 +3879,16 @@ static bool tcp_parse_aligned_timestamp( -+ { -+ const __be32 *ptr = (const __be32 *)(th + 1); -+ -+- if (*ptr == htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) -+- | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) { -++ if (net_hdr_word(ptr) == -++ htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | -++ (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) { -+ tp->rx_opt.saw_tstamp = 1; -+ ++ptr; -+- tp->rx_opt.rcv_tsval = ntohl(*ptr); -++ tp->rx_opt.rcv_tsval = get_unaligned_be32(ptr); -+ ++ptr; -+- if (*ptr) -+- tp->rx_opt.rcv_tsecr = ntohl(*ptr) - tp->tsoffset; -++ if (net_hdr_word(ptr)) -++ tp->rx_opt.rcv_tsecr = get_unaligned_be32(ptr) - -++ tp->tsoffset; -+ else -+ tp->rx_opt.rcv_tsecr = 0; -+ return true; -+--- a/include/uapi/linux/if_pppox.h -++++ b/include/uapi/linux/if_pppox.h -+@@ -51,6 +51,7 @@ struct pppoe_addr { -+ */ -+ struct pptp_addr { -+ __u16 call_id; -++ __u16 pad; -+ struct in_addr sin_addr; -+ }; -+ -+--- a/net/ipv6/netfilter/nf_log_ipv6.c -++++ b/net/ipv6/netfilter/nf_log_ipv6.c -+@@ -66,9 +66,9 @@ static void dump_ipv6_packet(struct nf_l -+ /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */ -+ nf_log_buf_add(m, "LEN=%zu TC=%u HOPLIMIT=%u FLOWLBL=%u ", -+ ntohs(ih->payload_len) + sizeof(struct ipv6hdr), -+- (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20, -++ (ntohl(net_hdr_word(ih)) & 0x0ff00000) >> 20, -+ ih->hop_limit, -+- (ntohl(*(__be32 *)ih) & 0x000fffff)); -++ (ntohl(net_hdr_word(ih)) & 0x000fffff)); -+ -+ fragment = 0; -+ ptr = ip6hoff + sizeof(struct ipv6hdr); -+--- a/include/net/neighbour.h -++++ b/include/net/neighbour.h -+@@ -265,8 +265,10 @@ static inline bool neigh_key_eq128(const -+ const u32 *n32 = (const u32 *)n->primary_key; -+ const u32 *p32 = pkey; -+ -+- return ((n32[0] ^ p32[0]) | (n32[1] ^ p32[1]) | -+- (n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0; -++ return ((n32[0] ^ net_hdr_word(&p32[0])) | -++ (n32[1] ^ net_hdr_word(&p32[1])) | -++ (n32[2] ^ net_hdr_word(&p32[2])) | -++ (n32[3] ^ net_hdr_word(&p32[3]))) == 0; -+ } -+ -+ static inline struct neighbour *___neigh_lookup_noref( -+--- a/include/uapi/linux/netfilter_arp/arp_tables.h -++++ b/include/uapi/linux/netfilter_arp/arp_tables.h -+@@ -70,7 +70,7 @@ struct arpt_arp { -+ __u8 flags; -+ /* Inverse flags */ -+ __u16 invflags; -+-}; -++} __attribute__((aligned(4))); -+ -+ /* Values for "flag" field in struct arpt_ip (general arp structure). -+ * No flags defined yet. -+--- a/net/core/utils.c -++++ b/net/core/utils.c -+@@ -441,8 +441,14 @@ void inet_proto_csum_replace16(__sum16 * -+ bool pseudohdr) -+ { -+ __be32 diff[] = { -+- ~from[0], ~from[1], ~from[2], ~from[3], -+- to[0], to[1], to[2], to[3], -++ ~net_hdr_word(&from[0]), -++ ~net_hdr_word(&from[1]), -++ ~net_hdr_word(&from[2]), -++ ~net_hdr_word(&from[3]), -++ net_hdr_word(&to[0]), -++ net_hdr_word(&to[1]), -++ net_hdr_word(&to[2]), -++ net_hdr_word(&to[3]), -+ }; -+ if (skb->ip_summed != CHECKSUM_PARTIAL) { -+ *sum = csum_fold(csum_partial(diff, sizeof(diff), -+--- a/drivers/net/vxlan.c -++++ b/drivers/net/vxlan.c -+@@ -1872,15 +1872,15 @@ static int vxlan_build_skb(struct sk_buf -+ return err; -+ -+ vxh = __skb_push(skb, sizeof(*vxh)); -+- vxh->vx_flags = VXLAN_HF_VNI; -+- vxh->vx_vni = vxlan_vni_field(vni); -++ net_hdr_word(&vxh->vx_flags) = VXLAN_HF_VNI; -++ net_hdr_word(&vxh->vx_vni) = vxlan_vni_field(vni); -+ -+ if (type & SKB_GSO_TUNNEL_REMCSUM) { -+ unsigned int start; -+ -+ start = skb_checksum_start_offset(skb) - sizeof(struct vxlanhdr); -+- vxh->vx_vni |= vxlan_compute_rco(start, skb->csum_offset); -+- vxh->vx_flags |= VXLAN_HF_RCO; -++ net_hdr_word(&vxh->vx_vni) |= vxlan_compute_rco(start, skb->csum_offset); -++ net_hdr_word(&vxh->vx_flags) |= VXLAN_HF_RCO; -+ -+ if (!skb_is_gso(skb)) { -+ skb->ip_summed = CHECKSUM_NONE; -+--- a/include/linux/etherdevice.h -++++ b/include/linux/etherdevice.h -+@@ -480,7 +480,7 @@ static inline bool is_etherdev_addr(cons -+ * @b: Pointer to Ethernet header -+ * -+ * Compare two Ethernet headers, returns 0 if equal. -+- * This assumes that the network header (i.e., IP header) is 4-byte -++ * This assumes that the network header (i.e., IP header) is 2-byte -+ * aligned OR the platform can handle unaligned access. This is the -+ * case for all packets coming into netif_receive_skb or similar -+ * entry points. -+@@ -503,11 +503,12 @@ static inline unsigned long compare_ethe -+ fold |= *(unsigned long *)(a + 6) ^ *(unsigned long *)(b + 6); -+ return fold; -+ #else -+- u32 *a32 = (u32 *)((u8 *)a + 2); -+- u32 *b32 = (u32 *)((u8 *)b + 2); -++ const u16 *a16 = a; -++ const u16 *b16 = b; -+ -+- return (*(u16 *)a ^ *(u16 *)b) | (a32[0] ^ b32[0]) | -+- (a32[1] ^ b32[1]) | (a32[2] ^ b32[2]); -++ return (a16[0] ^ b16[0]) | (a16[1] ^ b16[1]) | (a16[2] ^ b16[2]) | -++ (a16[3] ^ b16[3]) | (a16[4] ^ b16[4]) | (a16[5] ^ b16[5]) | -++ (a16[6] ^ b16[6]); -+ #endif -+ } -+ -+--- a/net/ipv4/tcp_offload.c -++++ b/net/ipv4/tcp_offload.c -+@@ -226,7 +226,7 @@ struct sk_buff **tcp_gro_receive(struct -+ -+ th2 = tcp_hdr(p); -+ -+- if (*(u32 *)&th->source ^ *(u32 *)&th2->source) { -++ if (net_hdr_word(&th->source) ^ net_hdr_word(&th2->source)) { -+ NAPI_GRO_CB(p)->same_flow = 0; -+ continue; -+ } -+@@ -244,8 +244,8 @@ found: -+ ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH)); -+ flush |= (__force int)(th->ack_seq ^ th2->ack_seq); -+ for (i = sizeof(*th); i < thlen; i += 4) -+- flush |= *(u32 *)((u8 *)th + i) ^ -+- *(u32 *)((u8 *)th2 + i); -++ flush |= net_hdr_word((u8 *)th + i) ^ -++ net_hdr_word((u8 *)th2 + i); -+ -+ /* When we receive our second frame we can made a decision on if we -+ * continue this flow as an atomic flow with a fixed ID or if we use -+--- a/net/ipv6/netfilter/ip6table_mangle.c -++++ b/net/ipv6/netfilter/ip6table_mangle.c -+@@ -50,7 +50,7 @@ ip6t_mangle_out(struct sk_buff *skb, con -+ hop_limit = ipv6_hdr(skb)->hop_limit; -+ -+ /* flowlabel and prio (includes version, which shouldn't change either */ -+- flowlabel = *((u_int32_t *)ipv6_hdr(skb)); -++ flowlabel = net_hdr_word(ipv6_hdr(skb)); -+ -+ ret = ip6t_do_table(skb, state, state->net->ipv6.ip6table_mangle); -+ -+@@ -59,7 +59,7 @@ ip6t_mangle_out(struct sk_buff *skb, con -+ !ipv6_addr_equal(&ipv6_hdr(skb)->daddr, &daddr) || -+ skb->mark != mark || -+ ipv6_hdr(skb)->hop_limit != hop_limit || -+- flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) { -++ flowlabel != net_hdr_word(ipv6_hdr(skb)))) { -+ err = ip6_route_me_harder(state->net, skb); -+ if (err < 0) -+ ret = NF_DROP_ERR(err); -diff --git a/target/linux/ar71xx/patches-4.14/920-usb-chipidea-AR933x-platform-support.patch b/target/linux/ar71xx/patches-4.14/920-usb-chipidea-AR933x-platform-support.patch -new file mode 100644 -index 0000000000..b0e69af9c1 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/920-usb-chipidea-AR933x-platform-support.patch -@@ -0,0 +1,124 @@ -+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -+@@ -659,6 +659,7 @@ -+ -+ #define AR933X_BOOTSTRAP_MDIO_GPIO_EN BIT(18) -+ #define AR933X_BOOTSTRAP_EEPBUSY BIT(4) -++#define AR933X_BOOTSTRAP_USB_MODE_HOST BIT(3) -+ #define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0) -+ -+ #define AR934X_BOOTSTRAP_SW_OPTION8 BIT(23) -+@@ -688,6 +689,8 @@ -+ -+ #define QCA956X_BOOTSTRAP_REF_CLK_40 BIT(2) -+ -++#define AR933X_USB_CONFIG_HOST_ONLY BIT(8) -++ -+ #define AR934X_PCIE_WMAC_INT_WMAC_MISC BIT(0) -+ #define AR934X_PCIE_WMAC_INT_WMAC_TX BIT(1) -+ #define AR934X_PCIE_WMAC_INT_WMAC_RXLP BIT(2) -+--- a/arch/mips/ath79/dev-usb.c -++++ b/arch/mips/ath79/dev-usb.c -+@@ -19,6 +19,9 @@ -+ #include -+ #include -+ #include -++#include -++#include -++#include -+ -+ #include -+ #include -+@@ -170,6 +173,44 @@ static void __init ar913x_usb_setup(void -+ &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); -+ } -+ -++static void __init ar9xxx_ci_usb_setup(int bus_id, int irq) -++{ -++ struct ci_hdrc_platform_data ci_pdata; -++ bool host_mode = true; -++ -++ if (soc_is_ar933x()) -++ host_mode = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP) & -++ AR933X_BOOTSTRAP_USB_MODE_HOST; -++ else -++ host_mode = !(ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP) & -++ AR934X_BOOTSTRAP_USB_MODE_DEVICE); -++ -++ if (host_mode) { -++ ath79_usb_register("ehci-platform", bus_id, -++ AR934X_EHCI_BASE, AR934X_EHCI_SIZE, -++ irq, &ath79_ehci_pdata_v2, -++ sizeof(ath79_ehci_pdata_v2)); -++ -++ return; -++ } -++ -++ memset(&ci_pdata, 0, sizeof(ci_pdata)); -++ ci_pdata.name = "ci_hdrc_ar9xxx"; -++ ci_pdata.capoffset = DEF_CAPOFFSET; -++ ci_pdata.dr_mode = USB_DR_MODE_PERIPHERAL; -++ ci_pdata.flags = CI_HDRC_DUAL_ROLE_NOT_OTG | CI_HDRC_DP_ALWAYS_PULLUP; -++ ci_pdata.vbus_extcon.edev = ERR_PTR(-ENODEV); -++ ci_pdata.id_extcon.edev = ERR_PTR(-ENODEV); -++ ci_pdata.itc_setting = 1; -++ -++ platform_device_register_simple("usb_phy_generic", -++ PLATFORM_DEVID_AUTO, NULL, 0); -++ -++ ath79_usb_register("ci_hdrc", -1, -++ AR934X_EHCI_BASE, AR934X_EHCI_SIZE, -++ irq, &ci_pdata, sizeof(ci_pdata)); -++} -++ -+ static void __init ar933x_usb_setup(void) -+ { -+ ath79_device_reset_set(AR933X_RESET_USBSUS_OVERRIDE); -+@@ -181,10 +222,7 @@ static void __init ar933x_usb_setup(void -+ ath79_device_reset_clear(AR933X_RESET_USB_PHY); -+ mdelay(10); -+ -+- ath79_usb_register("ehci-platform", -1, -+- AR933X_EHCI_BASE, AR933X_EHCI_SIZE, -+- ATH79_CPU_IRQ(3), -+- &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); -++ ar9xxx_ci_usb_setup(-1, ATH79_CPU_IRQ(3)); -+ } -+ -+ static void enable_tx_tx_idp_violation_fix(unsigned base) -+@@ -230,10 +268,7 @@ static void __init ar934x_usb_setup(void -+ if (ath79_soc_rev >= 3) -+ ath79_ehci_pdata_v2.reset_notifier = ar934x_usb_reset_notifier; -+ -+- ath79_usb_register("ehci-platform", -1, -+- AR934X_EHCI_BASE, AR934X_EHCI_SIZE, -+- ATH79_CPU_IRQ(3), -+- &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); -++ ar9xxx_ci_usb_setup(-1, ATH79_CPU_IRQ(3)); -+ } -+ -+ static void __init qca953x_usb_setup(void) -+@@ -254,10 +289,7 @@ static void __init qca953x_usb_setup(voi -+ ath79_device_reset_clear(QCA953X_RESET_USB_HOST); -+ udelay(1000); -+ -+- ath79_usb_register("ehci-platform", -1, -+- QCA953X_EHCI_BASE, QCA953X_EHCI_SIZE, -+- ATH79_CPU_IRQ(3), -+- &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); -++ ar9xxx_ci_usb_setup(-1, ATH79_CPU_IRQ(3)); -+ } -+ -+ static void qca955x_usb_reset_notifier(struct platform_device *pdev) -+@@ -285,10 +317,7 @@ static void __init qca955x_usb_setup(voi -+ { -+ ath79_ehci_pdata_v2.reset_notifier = qca955x_usb_reset_notifier; -+ -+- ath79_usb_register("ehci-platform", 0, -+- QCA955X_EHCI0_BASE, QCA955X_EHCI_SIZE, -+- ATH79_IP3_IRQ(0), -+- &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); -++ ar9xxx_ci_usb_setup(0, ATH79_IP3_IRQ(0)); -+ -+ ath79_usb_register("ehci-platform", 1, -+ QCA955X_EHCI1_BASE, QCA955X_EHCI_SIZE, -diff --git a/target/linux/ar71xx/patches-4.14/921-MIPS-ath79-add-even-more-register-defines-for-QCA956x-SoC.patch b/target/linux/ar71xx/patches-4.14/921-MIPS-ath79-add-even-more-register-defines-for-QCA956x-SoC.patch -new file mode 100644 -index 0000000000..a4608ea48d ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/921-MIPS-ath79-add-even-more-register-defines-for-QCA956x-SoC.patch -@@ -0,0 +1,194 @@ -+Add more registers for QCA955x and QCA956x. -+ -+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -+@@ -175,6 +175,35 @@ -+ /* -+ * Hidden Registers -+ */ -++#define QCA956X_MAC_CFG_BASE 0xb9000000 -++#define QCA956X_MAC_CFG_SIZE 0x64 -++ -++#define QCA956X_MAC_CFG1_REG 0x00 -++#define QCA956X_MAC_CFG1_SOFT_RST BIT(31) -++#define QCA956X_MAC_CFG1_RX_RST BIT(19) -++#define QCA956X_MAC_CFG1_TX_RST BIT(18) -++#define QCA956X_MAC_CFG1_LOOPBACK BIT(8) -++#define QCA956X_MAC_CFG1_RX_EN BIT(2) -++#define QCA956X_MAC_CFG1_TX_EN BIT(0) -++ -++#define QCA956X_MAC_CFG2_REG 0x04 -++#define QCA956X_MAC_CFG2_IF_1000 BIT(9) -++#define QCA956X_MAC_CFG2_IF_10_100 BIT(8) -++#define QCA956X_MAC_CFG2_HUGE_FRAME_EN BIT(5) -++#define QCA956X_MAC_CFG2_LEN_CHECK BIT(4) -++#define QCA956X_MAC_CFG2_PAD_CRC_EN BIT(2) -++#define QCA956X_MAC_CFG2_FDX BIT(0) -++ -++#define QCA956X_MAC_MII_MGMT_CFG_REG 0x20 -++#define QCA956X_MGMT_CFG_CLK_DIV_20 0x07 -++ -++#define QCA956X_MAC_FIFO_CFG0_REG 0x48 -++#define QCA956X_MAC_FIFO_CFG1_REG 0x4c -++#define QCA956X_MAC_FIFO_CFG2_REG 0x50 -++#define QCA956X_MAC_FIFO_CFG3_REG 0x54 -++#define QCA956X_MAC_FIFO_CFG4_REG 0x58 -++#define QCA956X_MAC_FIFO_CFG5_REG 0x5c -++ -+ #define QCA956X_DAM_RESET_OFFSET 0xb90001bc -+ #define QCA956X_DAM_RESET_SIZE 0x4 -+ #define QCA956X_INLINE_CHKSUM_ENG BIT(27) -+@@ -384,6 +413,7 @@ -+ #define QCA955X_PLL_CLK_CTRL_REG 0x08 -+ #define QCA955X_PLL_ETH_XMII_CONTROL_REG 0x28 -+ #define QCA955X_PLL_ETH_SGMII_CONTROL_REG 0x48 -++#define QCA955X_PLL_ETH_SGMII_SERDES_REG 0x4c -+ -+ #define QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT 0 -+ #define QCA955X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f -+@@ -416,12 +446,18 @@ -+ #define QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21) -+ #define QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) -+ -++#define QCA955X_PLL_ETH_SGMII_SERDES_LOCK_DETECT BIT(2) -++#define QCA955X_PLL_ETH_SGMII_SERDES_PLL_REFCLK BIT(1) -++#define QCA955X_PLL_ETH_SGMII_SERDES_EN_PLL BIT(0) -++ -+ #define QCA956X_PLL_CPU_CONFIG_REG 0x00 -+ #define QCA956X_PLL_CPU_CONFIG1_REG 0x04 -+ #define QCA956X_PLL_DDR_CONFIG_REG 0x08 -+ #define QCA956X_PLL_DDR_CONFIG1_REG 0x0c -+ #define QCA956X_PLL_CLK_CTRL_REG 0x10 -++#define QCA956X_PLL_SWITCH_CLOCK_CONTROL_REG 0x28 -+ #define QCA956X_PLL_ETH_XMII_CONTROL_REG 0x30 -++#define QCA956X_PLL_ETH_SGMII_SERDES_REG 0x4c -+ -+ #define QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT 12 -+ #define QCA956X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f -+@@ -460,6 +496,31 @@ -+ #define QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL BIT(21) -+ #define QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) -+ -++#define QCA956X_PLL_SWITCH_CLOCK_SPARE_I2C_CLK_SELB BIT(5) -++#define QCA956X_PLL_SWITCH_CLOCK_SPARE_MDIO_CLK_SEL0_1 BIT(6) -++#define QCA956X_PLL_SWITCH_CLOCK_SPARE_UART1_CLK_SEL BIT(7) -++#define QCA956X_PLL_SWITCH_CLOCK_SPARE_USB_REFCLK_FREQ_SEL_SHIFT 8 -++#define QCA956X_PLL_SWITCH_CLOCK_SPARE_USB_REFCLK_FREQ_SEL_MASK 0xf -++#define QCA956X_PLL_SWITCH_CLOCK_SPARE_EN_PLL_TOP BIT(12) -++#define QCA956X_PLL_SWITCH_CLOCK_SPARE_MDIO_CLK_SEL0_2 BIT(13) -++#define QCA956X_PLL_SWITCH_CLOCK_SPARE_MDIO_CLK_SEL1_1 BIT(14) -++#define QCA956X_PLL_SWITCH_CLOCK_SPARE_MDIO_CLK_SEL1_2 BIT(15) -++#define QCA956X_PLL_SWITCH_CLOCK_SPARE_SWITCH_FUNC_TST_MODE BIT(16) -++#define QCA956X_PLL_SWITCH_CLOCK_SPARE_EEE_ENABLE BIT(17) -++#define QCA956X_PLL_SWITCH_CLOCK_SPARE_OEN_CLK125M_PLL BIT(18) -++#define QCA956X_PLL_SWITCH_CLOCK_SPARE_SWITCHCLK_SEL BIT(19) -++ -++#define QCA956X_PLL_ETH_XMII_TX_INVERT BIT(1) -++#define QCA956X_PLL_ETH_XMII_GIGE BIT(25) -++#define QCA956X_PLL_ETH_XMII_RX_DELAY_SHIFT 28 -++#define QCA956X_PLL_ETH_XMII_RX_DELAY_MASK 0x3 -++#define QCA956X_PLL_ETH_XMII_TX_DELAY_SHIFT 26 -++#define QCA956X_PLL_ETH_XMII_TX_DELAY_MASK 3 -++ -++#define QCA956X_PLL_ETH_SGMII_SERDES_LOCK_DETECT BIT(2) -++#define QCA956X_PLL_ETH_SGMII_SERDES_PLL_REFCLK BIT(1) -++#define QCA956X_PLL_ETH_SGMII_SERDES_EN_PLL BIT(0) -++ -+ /* -+ * USB_CONFIG block -+ */ -+@@ -657,6 +718,25 @@ -+ #define QCA955X_RESET_MBOX BIT(1) -+ #define QCA955X_RESET_I2S BIT(0) -+ -++#define QCA956X_RESET_EXTERNAL BIT(28) -++#define QCA956X_RESET_FULL_CHIP BIT(24) -++#define QCA956X_RESET_GE1_MDIO BIT(23) -++#define QCA956X_RESET_GE0_MDIO BIT(22) -++#define QCA956X_RESET_CPU_NMI BIT(21) -++#define QCA956X_RESET_CPU_COLD BIT(20) -++#define QCA956X_RESET_DMA BIT(19) -++#define QCA956X_RESET_DDR BIT(16) -++#define QCA956X_RESET_GE1_MAC BIT(13) -++#define QCA956X_RESET_SGMII_ANALOG BIT(12) -++#define QCA956X_RESET_USB_PHY_ANALOG BIT(11) -++#define QCA956X_RESET_GE0_MAC BIT(9) -++#define QCA956X_RESET_SGMII BIT(8) -++#define QCA956X_RESET_USB_HOST BIT(5) -++#define QCA956X_RESET_USB_PHY BIT(4) -++#define QCA956X_RESET_USBSUS_OVERRIDE BIT(3) -++#define QCA956X_RESET_SWITCH_ANALOG BIT(2) -++#define QCA956X_RESET_SWITCH BIT(0) -++ -+ #define AR933X_BOOTSTRAP_MDIO_GPIO_EN BIT(18) -+ #define AR933X_BOOTSTRAP_EEPBUSY BIT(4) -+ #define AR933X_BOOTSTRAP_USB_MODE_HOST BIT(3) -+@@ -1189,6 +1269,7 @@ -+ */ -+ -+ #define QCA955X_GMAC_REG_ETH_CFG 0x00 -++#define QCA955X_GMAC_REG_SGMII_SERDES 0x18 -+ -+ #define QCA955X_ETH_CFG_RGMII_EN BIT(0) -+ #define QCA955X_ETH_CFG_MII_GE0 BIT(1) -+@@ -1210,16 +1291,58 @@ -+ #define QCA955X_ETH_CFG_TXE_DELAY_MASK 0x3 -+ #define QCA955X_ETH_CFG_TXE_DELAY_SHIFT 20 -+ -++#define QCA955X_SGMII_SERDES_LOCK_DETECT_STATUS BIT(15) -++#define QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT 23 -++#define QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK 0xf -+ /* -+ * QCA956X GMAC Interface -+ */ -+ -+-#define QCA956X_GMAC_REG_ETH_CFG 0x00 -++#define QCA956X_GMAC_REG_ETH_CFG 0x00 -++#define QCA956X_GMAC_REG_SGMII_RESET 0x14 -++#define QCA956X_GMAC_REG_SGMII_SERDES 0x18 -++#define QCA956X_GMAC_REG_MR_AN_CONTROL 0x1c -++#define QCA956X_GMAC_REG_SGMII_CONFIG 0x34 -++#define QCA956X_GMAC_REG_SGMII_DEBUG 0x58 -+ -++#define QCA956X_ETH_CFG_RGMII_EN BIT(0) -++#define QCA956X_ETH_CFG_GE0_SGMII BIT(6) -+ #define QCA956X_ETH_CFG_SW_ONLY_MODE BIT(7) -+-#define QCA956X_ETH_CFG_SW_PHY_SWAP BIT(8) -++#define QCA956X_ETH_CFG_SW_PHY_SWAP BIT(8) -+ #define QCA956X_ETH_CFG_SW_PHY_ADDR_SWAP BIT(9) -+ #define QCA956X_ETH_CFG_SW_APB_ACCESS BIT(10) -+ #define QCA956X_ETH_CFG_SW_ACC_MSB_FIRST BIT(13) -++#define QCA956X_ETH_CFG_RXD_DELAY_MASK 0x3 -++#define QCA956X_ETH_CFG_RXD_DELAY_SHIFT 14 -++#define QCA956X_ETH_CFG_RDV_DELAY_MASK 0x3 -++#define QCA956X_ETH_CFG_RDV_DELAY_SHIFT 16 -++ -++#define QCA956X_SGMII_RESET_RX_CLK_N_RESET 0x0 -++#define QCA956X_SGMII_RESET_RX_CLK_N BIT(0) -++#define QCA956X_SGMII_RESET_TX_CLK_N BIT(1) -++#define QCA956X_SGMII_RESET_RX_125M_N BIT(2) -++#define QCA956X_SGMII_RESET_TX_125M_N BIT(3) -++#define QCA956X_SGMII_RESET_HW_RX_125M_N BIT(4) -++ -++#define QCA956X_SGMII_SERDES_CDR_BW_MASK 0x3 -++#define QCA956X_SGMII_SERDES_CDR_BW_SHIFT 1 -++#define QCA956X_SGMII_SERDES_TX_DR_CTRL_MASK 0x7 -++#define QCA956X_SGMII_SERDES_TX_DR_CTRL_SHIFT 4 -++#define QCA956X_SGMII_SERDES_PLL_BW BIT(8) -++#define QCA956X_SGMII_SERDES_VCO_FAST BIT(9) -++#define QCA956X_SGMII_SERDES_VCO_SLOW BIT(10) -++#define QCA956X_SGMII_SERDES_LOCK_DETECT_STATUS BIT(15) -++#define QCA956X_SGMII_SERDES_EN_SIGNAL_DETECT BIT(16) -++#define QCA956X_SGMII_SERDES_FIBER_SDO BIT(17) -++#define QCA956X_SGMII_SERDES_RES_CALIBRATION_SHIFT 23 -++#define QCA956X_SGMII_SERDES_RES_CALIBRATION_MASK 0xf -++#define QCA956X_SGMII_SERDES_VCO_REG_SHIFT 27 -++#define QCA956X_SGMII_SERDES_VCO_REG_MASK 0xf -++ -++#define QCA956X_MR_AN_CONTROL_AN_ENABLE BIT(12) -++#define QCA956X_MR_AN_CONTROL_PHY_RESET BIT(15) -++ -++#define QCA956X_SGMII_CONFIG_MODE_CTRL_SHIFT 0 -++#define QCA956X_SGMII_CONFIG_MODE_CTRL_MASK 0x7 -+ -+ #endif /* __ASM_MACH_AR71XX_REGS_H */ -diff --git a/target/linux/ar71xx/patches-4.14/930-chipidea-pullup.patch b/target/linux/ar71xx/patches-4.14/930-chipidea-pullup.patch -new file mode 100644 -index 0000000000..2e9a878630 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/930-chipidea-pullup.patch -@@ -0,0 +1,72 @@ -+--- a/drivers/usb/chipidea/ci.h -++++ b/drivers/usb/chipidea/ci.h -+@@ -205,6 +205,7 @@ struct hw_bank { -+ * @in_lpm: if the core in low power mode -+ * @wakeup_int: if wakeup interrupt occur -+ * @rev: The revision number for controller -++ * @dp_always_pullup: keep dp always pullup at device mode -+ */ -+ struct ci_hdrc { -+ struct device *dev; -+@@ -259,6 +260,7 @@ struct ci_hdrc { -+ bool in_lpm; -+ bool wakeup_int; -+ enum ci_revision rev; -++ bool dp_always_pullup; -+ }; -+ -+ static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci) -+--- a/drivers/usb/chipidea/core.c -++++ b/drivers/usb/chipidea/core.c -+@@ -818,7 +818,7 @@ static inline void ci_role_destroy(struc -+ { -+ ci_hdrc_gadget_destroy(ci); -+ ci_hdrc_host_destroy(ci); -+- if (ci->is_otg && ci->roles[CI_ROLE_GADGET]) -++ if (!ci->dp_always_pullup && ci->roles[CI_ROLE_GADGET]) -+ ci_hdrc_otg_destroy(ci); -+ } -+ -+@@ -923,6 +923,9 @@ static int ci_hdrc_probe(struct platform -+ CI_HDRC_SUPPORTS_RUNTIME_PM); -+ platform_set_drvdata(pdev, ci); -+ -++ ci->dp_always_pullup = !!(ci->platdata->flags & -++ CI_HDRC_DP_ALWAYS_PULLUP); -++ -+ ret = hw_device_init(ci, base); -+ if (ret < 0) { -+ dev_err(dev, "can't initialize hardware\n"); -+@@ -1011,7 +1014,7 @@ static int ci_hdrc_probe(struct platform -+ goto deinit_gadget; -+ } -+ -+- if (ci->is_otg && ci->roles[CI_ROLE_GADGET]) { -++ if (!ci->dp_always_pullup && ci->roles[CI_ROLE_GADGET]) { -+ ret = ci_hdrc_otg_init(ci); -+ if (ret) { -+ dev_err(dev, "init otg fails, ret = %d\n", ret); -+--- a/drivers/usb/chipidea/otg.c -++++ b/drivers/usb/chipidea/otg.c -+@@ -131,8 +131,10 @@ enum ci_role ci_otg_role(struct ci_hdrc -+ -+ void ci_handle_vbus_change(struct ci_hdrc *ci) -+ { -+- if (!ci->is_otg) -++ if (ci->dp_always_pullup) { -++ usb_gadget_vbus_connect(&ci->gadget); -+ return; -++ } -+ -+ if (hw_read_otgsc(ci, OTGSC_BSV) && !ci->vbus_active) -+ usb_gadget_vbus_connect(&ci->gadget); -+--- a/include/linux/usb/chipidea.h -++++ b/include/linux/usb/chipidea.h -+@@ -60,6 +60,7 @@ struct ci_hdrc_platform_data { -+ #define CI_HDRC_OVERRIDE_RX_BURST BIT(11) -+ #define CI_HDRC_OVERRIDE_PHY_CONTROL BIT(12) /* Glue layer manages phy */ -+ #define CI_HDRC_REQUIRES_ALIGNED_DMA BIT(13) -++#define CI_HDRC_DP_ALWAYS_PULLUP BIT(14) -+ enum usb_dr_mode dr_mode; -+ #define CI_HDRC_CONTROLLER_RESET_EVENT 0 -+ #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 -diff --git a/target/linux/ar71xx/patches-4.14/940-qca955x-add-more-registers.patch b/target/linux/ar71xx/patches-4.14/940-qca955x-add-more-registers.patch -new file mode 100644 -index 0000000000..ff72308465 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/940-qca955x-add-more-registers.patch -@@ -0,0 +1,42 @@ -+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -+@@ -134,7 +134,7 @@ -+ #define QCA955X_PCI_CTRL_SIZE 0x100 -+ -+ #define QCA955X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) -+-#define QCA955X_GMAC_SIZE 0x40 -++#define QCA955X_GMAC_SIZE 0x64 -+ #define QCA955X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) -+ #define QCA955X_WMAC_SIZE 0x20000 -+ #define QCA955X_EHCI0_BASE 0x1b000000 -+@@ -1269,7 +1269,11 @@ -+ */ -+ -+ #define QCA955X_GMAC_REG_ETH_CFG 0x00 -++#define QCA955X_GMAC_REG_SGMII_RESET 0x14 -+ #define QCA955X_GMAC_REG_SGMII_SERDES 0x18 -++#define QCA955X_GMAC_REG_MR_AN_CONTROL 0x1c -++#define QCA955X_GMAC_REG_MR_AN_STATUS 0x20 -++#define QCA955X_GMAC_REG_SGMII_DEBUG 0x58 -+ -+ #define QCA955X_ETH_CFG_RGMII_EN BIT(0) -+ #define QCA955X_ETH_CFG_MII_GE0 BIT(1) -+@@ -1291,6 +1295,18 @@ -+ #define QCA955X_ETH_CFG_TXE_DELAY_MASK 0x3 -+ #define QCA955X_ETH_CFG_TXE_DELAY_SHIFT 20 -+ -++#define QCA955X_SGMII_RESET_RX_CLK_N_RESET 0x0 -++#define QCA955X_SGMII_RESET_RX_CLK_N BIT(0) -++#define QCA955X_SGMII_RESET_TX_CLK_N BIT(1) -++#define QCA955X_SGMII_RESET_RX_125M_N BIT(2) -++#define QCA955X_SGMII_RESET_TX_125M_N BIT(3) -++#define QCA955X_SGMII_RESET_HW_RX_125M_N BIT(4) -++ -++#define QCA955X_MR_AN_CONTROL_PHY_RESET BIT(15) -++#define QCA955X_MR_AN_CONTROL_AN_ENABLE BIT(12) -++ -++#define QCA955X_MR_AN_STATUS_AN_ABILITY BIT(3) -++ -+ #define QCA955X_SGMII_SERDES_LOCK_DETECT_STATUS BIT(15) -+ #define QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT 23 -+ #define QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK 0xf -diff --git a/target/linux/ar71xx/patches-4.14/950-add-boardinfo-platform-data.patch b/target/linux/ar71xx/patches-4.14/950-add-boardinfo-platform-data.patch -new file mode 100644 -index 0000000000..edeac838d9 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/950-add-boardinfo-platform-data.patch -@@ -0,0 +1,67 @@ -+--- a/drivers/net/phy/mdio-boardinfo.c -++++ b/drivers/net/phy/mdio-boardinfo.c -+@@ -15,8 +15,11 @@ -+ -+ #include "mdio-boardinfo.h" -+ -+-static LIST_HEAD(mdio_board_list); -+-static DEFINE_MUTEX(mdio_board_lock); -++LIST_HEAD(mdio_board_list); -++EXPORT_SYMBOL_GPL(mdio_board_list); -++ -++DEFINE_MUTEX(mdio_board_lock); -++EXPORT_SYMBOL_GPL(mdio_board_lock); -+ -+ /** -+ * mdiobus_setup_mdiodev_from_board_info - create and setup MDIO devices -+--- a/drivers/net/phy/mdio-boardinfo.h -++++ b/drivers/net/phy/mdio-boardinfo.h -+@@ -20,4 +20,7 @@ void mdiobus_setup_mdiodev_from_board_in -+ (struct mii_bus *bus, -+ struct mdio_board_info *bi)); -+ -++extern struct mutex mdio_board_lock; -++extern struct list_head mdio_board_list; -++ -+ #endif /* __MDIO_BOARD_INFO_H */ -+--- a/drivers/net/phy/mdio_bus.c -++++ b/drivers/net/phy/mdio_bus.c -+@@ -455,6 +455,17 @@ void mdiobus_free(struct mii_bus *bus) -+ } -+ EXPORT_SYMBOL(mdiobus_free); -+ -++static void mdiobus_setup_phydev_from_boardinfo(struct mii_bus *bus, -++ struct phy_device *phydev, -++ struct mdio_board_info *bi) -++{ -++ if (strcmp(bus->id, bi->bus_id) || -++ bi->mdio_addr != phydev->mdio.addr) -++ return; -++ -++ phydev->mdio.dev.platform_data = (void *) bi->platform_data; -++} -++ -+ /** -+ * mdiobus_scan - scan a bus for MDIO devices. -+ * @bus: mii_bus to scan -+@@ -470,6 +481,7 @@ EXPORT_SYMBOL(mdiobus_free); -+ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr) -+ { -+ struct phy_device *phydev; -++ struct mdio_board_entry *be; -+ int err; -+ -+ phydev = get_phy_device(bus, addr, false); -+@@ -482,6 +494,12 @@ struct phy_device *mdiobus_scan(struct m -+ */ -+ of_mdiobus_link_mdiodev(bus, &phydev->mdio); -+ -++ mutex_lock(&mdio_board_lock); -++ list_for_each_entry(be, &mdio_board_list, list) -++ mdiobus_setup_phydev_from_boardinfo(bus, phydev, -++ &be->board_info); -++ mutex_unlock(&mdio_board_lock); -++ -+ err = phy_device_register(phydev); -+ if (err) { -+ phy_device_free(phydev); -diff --git a/target/linux/ar71xx/patches-4.14/952-qca955x-enable-ddr-wb-flush.patch b/target/linux/ar71xx/patches-4.14/952-qca955x-enable-ddr-wb-flush.patch -new file mode 100644 -index 0000000000..16d17b8a0e ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/952-qca955x-enable-ddr-wb-flush.patch -@@ -0,0 +1,49 @@ -+--- a/arch/mips/ath79/common.c -++++ b/arch/mips/ath79/common.c -+@@ -49,6 +49,8 @@ void ath79_ddr_ctrl_init(void) -+ if (soc_is_ar913x() || soc_is_ar724x() || soc_is_ar933x()) { -+ ath79_ddr_wb_flush_base = ath79_ddr_base + 0x7c; -+ ath79_ddr_pci_win_base = 0; -++ } else if (soc_is_qca953x() || soc_is_qca955x()) { -++ ath79_ddr_wb_flush_base = ath79_ddr_base + 0x9c; -+ } else { -+ ath79_ddr_wb_flush_base = ath79_ddr_base + 0x9c; -+ ath79_ddr_pci_win_base = ath79_ddr_base + 0x7c; -+--- a/arch/mips/ath79/irq.c -++++ b/arch/mips/ath79/irq.c -+@@ -105,12 +105,12 @@ static void qca955x_ip2_irq_dispatch(str -+ } -+ -+ if (status & QCA955X_EXT_INT_PCIE_RC1_ALL) { -+- /* TODO: flush DDR? */ -++ ath79_ddr_wb_flush(3); -+ generic_handle_irq(ATH79_IP2_IRQ(0)); -+ } -+ -+ if (status & QCA955X_EXT_INT_WMAC_ALL) { -+- /* TODO: flush DDR? */ -++ ath79_ddr_wb_flush(4); -+ generic_handle_irq(ATH79_IP2_IRQ(1)); -+ } -+ } -+@@ -130,17 +130,17 @@ static void qca955x_ip3_irq_dispatch(str -+ } -+ -+ if (status & QCA955X_EXT_INT_USB1) { -+- /* TODO: flush DDR? */ -++ ath79_ddr_wb_flush(2); -+ generic_handle_irq(ATH79_IP3_IRQ(0)); -+ } -+ -+ if (status & QCA955X_EXT_INT_USB2) { -+- /* TODO: flush DDR? */ -++ ath79_ddr_wb_flush(2); -+ generic_handle_irq(ATH79_IP3_IRQ(1)); -+ } -+ -+ if (status & QCA955X_EXT_INT_PCIE_RC2_ALL) { -+- /* TODO: flush DDR? */ -++ ath79_ddr_wb_flush(3); -+ generic_handle_irq(ATH79_IP3_IRQ(2)); -+ } -+ } -diff --git a/target/linux/ar71xx/patches-4.14/953-qca955x-pci-reset-fixes.patch b/target/linux/ar71xx/patches-4.14/953-qca955x-pci-reset-fixes.patch -new file mode 100644 -index 0000000000..0acca2a08f ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/953-qca955x-pci-reset-fixes.patch -@@ -0,0 +1,120 @@ -+--- a/arch/mips/ath79/common.c -++++ b/arch/mips/ath79/common.c -+@@ -153,6 +153,24 @@ void ath79_device_reset_clear(u32 mask) -+ } -+ EXPORT_SYMBOL_GPL(ath79_device_reset_clear); -+ -++void ath79_device_reset2_clear(u32 mask) -++{ -++ unsigned long flags; -++ u32 reg; -++ u32 t; -++ -++ if (soc_is_qca955x()) -++ reg = QCA955X_RESET_REG_RESET2_MODULE; -++ else -++ panic("Reset register not defined for this SOC"); -++ -++ spin_lock_irqsave(&ath79_device_reset_lock, flags); -++ t = ath79_reset_rr(reg); -++ ath79_reset_wr(reg, t & ~mask); -++ spin_unlock_irqrestore(&ath79_device_reset_lock, flags); -++} -++EXPORT_SYMBOL_GPL(ath79_device_reset2_clear); -++ -+ u32 ath79_device_reset_get(u32 mask) -+ { -+ unsigned long flags; -+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -+@@ -411,6 +411,7 @@ -+ #define QCA955X_PLL_CPU_CONFIG_REG 0x00 -+ #define QCA955X_PLL_DDR_CONFIG_REG 0x04 -+ #define QCA955X_PLL_CLK_CTRL_REG 0x08 -++#define QCA955X_PLL_PCIE_CONFIG_REG 0x0c -+ #define QCA955X_PLL_ETH_XMII_CONTROL_REG 0x28 -+ #define QCA955X_PLL_ETH_SGMII_CONTROL_REG 0x48 -+ #define QCA955X_PLL_ETH_SGMII_SERDES_REG 0x4c -+@@ -565,6 +566,7 @@ -+ #define QCA953X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac -+ -+ #define QCA955X_RESET_REG_RESET_MODULE 0x1c -++#define QCA955X_RESET_REG_RESET2_MODULE 0xc4 -+ #define QCA955X_RESET_REG_BOOTSTRAP 0xb0 -+ #define QCA955X_RESET_REG_EXT_INT_STATUS 0xac -+ -+--- a/arch/mips/include/asm/mach-ath79/ath79.h -++++ b/arch/mips/include/asm/mach-ath79/ath79.h -+@@ -178,6 +178,7 @@ static inline u32 ath79_reset_rr(unsigne -+ -+ void ath79_device_reset_set(u32 mask); -+ void ath79_device_reset_clear(u32 mask); -++void ath79_device_reset2_clear(u32 mask); -+ u32 ath79_device_reset_get(u32 mask); -+ -+ void ath79_cpu_irq_init(unsigned irq_wb_chan2, unsigned irq_wb_chan3); -+--- a/arch/mips/pci/pci-ar724x.c -++++ b/arch/mips/pci/pci-ar724x.c -+@@ -335,18 +335,37 @@ static void ar724x_pci_hw_init(struct ar -+ int wait = 0; -+ -+ /* deassert PCIe host controller and PCIe PHY reset */ -+- ath79_device_reset_clear(AR724X_RESET_PCIE); -+- ath79_device_reset_clear(AR724X_RESET_PCIE_PHY); -++ if (soc_is_qca955x()) { -++ ath79_device_reset_clear(QCA955X_RESET_PCIE); -++ mdelay(10); -++ ath79_device_reset_clear(QCA955X_RESET_PCIE_PHY); -++ mdelay(10); -++ ath79_device_reset2_clear(QCA955X_RESET_PCIE); -++ mdelay(10); -++ ath79_device_reset2_clear(QCA955X_RESET_PCIE_PHY); -++ mdelay(10); -++ } else { -++ ath79_device_reset_clear(AR724X_RESET_PCIE); -++ ath79_device_reset_clear(AR724X_RESET_PCIE_PHY); -++ } -+ -+ /* remove the reset of the PCIE PLL */ -+- ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG); -+- ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_RESET; -+- ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl); -++ if (!soc_is_qca955x()) { -++ ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG); -++ ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_RESET; -++ ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl); -++ } -+ -+ /* deassert bypass for the PCIE PLL */ -+- ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG); -+- ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_BYPASS; -+- ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl); -++ if (soc_is_qca955x()) { -++ ppl = ath79_pll_rr(QCA955X_PLL_PCIE_CONFIG_REG); -++ ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_BYPASS; -++ ath79_pll_wr(QCA955X_PLL_PCIE_CONFIG_REG, ppl); -++ } else { -++ ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG); -++ ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_BYPASS; -++ ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl); -++ } -+ -+ /* set PCIE Application Control to ready */ -+ app = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_APP); -+@@ -422,8 +441,14 @@ static int ar724x_pci_probe(struct platf -+ * Do the full PCIE Root Complex Initialization Sequence if the PCIe -+ * host controller is in reset. -+ */ -+- if (ath79_reset_rr(AR724X_RESET_REG_RESET_MODULE) & AR724X_RESET_PCIE) -+- ar724x_pci_hw_init(apc); -++ if (soc_is_qca955x()) { -++ if (ath79_reset_rr(QCA955X_RESET_REG_RESET_MODULE) & QCA955X_RESET_PCIE || -++ ath79_reset_rr(QCA955X_RESET_REG_RESET2_MODULE) & QCA955X_RESET_PCIE) -++ ar724x_pci_hw_init(apc); -++ } else { -++ if (ath79_reset_rr(AR724X_RESET_REG_RESET_MODULE) & AR724X_RESET_PCIE) -++ ar724x_pci_hw_init(apc); -++ } -+ -+ apc->link_up = ar724x_pci_check_link(apc); -+ if (!apc->link_up) -diff --git a/target/linux/ar71xx/patches-4.14/955-qca953x-fix-potential-missing-irq-dispatch.patch b/target/linux/ar71xx/patches-4.14/955-qca953x-fix-potential-missing-irq-dispatch.patch -new file mode 100644 -index 0000000000..5174029989 ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/955-qca953x-fix-potential-missing-irq-dispatch.patch -@@ -0,0 +1,27 @@ -+--- a/arch/mips/ath79/irq.c -++++ b/arch/mips/ath79/irq.c -+@@ -69,15 +69,21 @@ static void qca953x_ip2_irq_dispatch(str -+ u32 status; -+ -+ status = ath79_reset_rr(QCA953X_RESET_REG_PCIE_WMAC_INT_STATUS); -++ status &= QCA953X_PCIE_WMAC_INT_PCIE_ALL | QCA953X_PCIE_WMAC_INT_WMAC_ALL; -++ -++ if (status == 0) { -++ spurious_interrupt(); -++ return; -++ } -+ -+ if (status & QCA953X_PCIE_WMAC_INT_PCIE_ALL) { -+ ath79_ddr_wb_flush(3); -+ generic_handle_irq(ATH79_IP2_IRQ(0)); -+- } else if (status & QCA953X_PCIE_WMAC_INT_WMAC_ALL) { -++ } -++ -++ if (status & QCA953X_PCIE_WMAC_INT_WMAC_ALL) { -+ ath79_ddr_wb_flush(4); -+ generic_handle_irq(ATH79_IP2_IRQ(1)); -+- } else { -+- spurious_interrupt(); -+ } -+ } -+ -diff --git a/target/linux/ar71xx/patches-4.14/999-backport-fixes.patch b/target/linux/ar71xx/patches-4.14/999-backport-fixes.patch -new file mode 100644 -index 0000000000..a78519ccaf ---- /dev/null -+++ b/target/linux/ar71xx/patches-4.14/999-backport-fixes.patch -@@ -0,0 +1,191 @@ -+Index: linux-4.14.193/drivers/mtd/mtdsplit/mtdsplit_squashfs.c -+=================================================================== -+--- linux-4.14.193.orig/drivers/mtd/mtdsplit/mtdsplit_squashfs.c -++++ linux-4.14.193/drivers/mtd/mtdsplit/mtdsplit_squashfs.c -+@@ -36,7 +36,7 @@ mtdsplit_parse_squashfs(struct mtd_info -+ if (err) -+ return err; -+ -+- parent_mtd = mtd_get_master(master); -++ parent_mtd = mtdpart_get_master(master); -+ part_offset = mtdpart_get_offset(master); -+ -+ part = kzalloc(sizeof(*part), GFP_KERNEL); -+Index: linux-4.14.193/drivers/net/phy/swconfig.c -+=================================================================== -+--- linux-4.14.193.orig/drivers/net/phy/swconfig.c -++++ linux-4.14.193/drivers/net/phy/swconfig.c -+@@ -591,8 +591,13 @@ swconfig_parse_ports(struct sk_buff *msg -+ -+ port = &val->value.ports[val->len]; -+ -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0) -+ if (nla_parse_nested_deprecated(tb, SWITCH_PORT_ATTR_MAX, nla, -+ port_policy, NULL)) -++#else -++ if (nla_parse_nested(tb, SWITCH_PORT_ATTR_MAX, nla, -++ port_policy, NULL)) -++#endif -+ return -EINVAL; -+ -+ if (!tb[SWITCH_PORT_ID]) -+@@ -613,7 +618,11 @@ swconfig_parse_link(struct sk_buff *msg, -+ { -+ struct nlattr *tb[SWITCH_LINK_ATTR_MAX + 1]; -+ -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0) -+ if (nla_parse_nested_deprecated(tb, SWITCH_LINK_ATTR_MAX, nla, link_policy, NULL)) -++#else -++ if (nla_parse_nested(tb, SWITCH_LINK_ATTR_MAX, nla, link_policy, NULL)) -++#endif -+ return -EINVAL; -+ -+ link->duplex = !!tb[SWITCH_LINK_FLAG_DUPLEX]; -+@@ -991,56 +1000,106 @@ swconfig_done(struct netlink_callback *c -+ static struct genl_ops swconfig_ops[] = { -+ { -+ .cmd = SWITCH_CMD_LIST_GLOBAL, -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0) -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -++#endif -+ .doit = swconfig_list_attrs, -++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) -++ .policy = switch_policy, -++#endif -+ }, -+ { -+ .cmd = SWITCH_CMD_LIST_VLAN, -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0) -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -++#endif -+ .doit = swconfig_list_attrs, -++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) -++ .policy = switch_policy, -++#endif -+ }, -+ { -+ .cmd = SWITCH_CMD_LIST_PORT, -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0) -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -++#endif -+ .doit = swconfig_list_attrs, -++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) -++ .policy = switch_policy, -++#endif -+ }, -+ { -+ .cmd = SWITCH_CMD_GET_GLOBAL, -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0) -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -++#endif -+ .doit = swconfig_get_attr, -++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) -++ .policy = switch_policy, -++#endif -+ }, -+ { -+ .cmd = SWITCH_CMD_GET_VLAN, -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0) -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -++#endif -+ .doit = swconfig_get_attr, -++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) -++ .policy = switch_policy, -++#endif -+ }, -+ { -+ .cmd = SWITCH_CMD_GET_PORT, -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0) -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -++#endif -+ .doit = swconfig_get_attr, -++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) -++ .policy = switch_policy, -++#endif -+ }, -+ { -+ .cmd = SWITCH_CMD_SET_GLOBAL, -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0) -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -++#endif -+ .flags = GENL_ADMIN_PERM, -+ .doit = swconfig_set_attr, -++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) -++ .policy = switch_policy, -++#endif -+ }, -+ { -+ .cmd = SWITCH_CMD_SET_VLAN, -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0) -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -++#endif -+ .flags = GENL_ADMIN_PERM, -+ .doit = swconfig_set_attr, -++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) -++ .policy = switch_policy, -++#endif -+ }, -+ { -+ .cmd = SWITCH_CMD_SET_PORT, -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0) -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -++#endif -+ .flags = GENL_ADMIN_PERM, -+ .doit = swconfig_set_attr, -++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) -++ .policy = switch_policy, -++#endif -+ }, -+ { -+ .cmd = SWITCH_CMD_GET_SWITCH, -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0) -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -++#endif -+ .dumpit = swconfig_dump_switches, -++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) -++ .policy = switch_policy, -++#endif -+ .done = swconfig_done, -+ } -+ }; -+@@ -1050,7 +1109,9 @@ static struct genl_family switch_fam = { -+ .hdrsize = 0, -+ .version = 1, -+ .maxattr = SWITCH_ATTR_MAX, -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) -+ .policy = switch_policy, -++#endif -+ .module = THIS_MODULE, -+ .ops = swconfig_ops, -+ .n_ops = ARRAY_SIZE(swconfig_ops), -+Index: linux-4.14.193/drivers/net/phy/swconfig_leds.c -+=================================================================== -+--- linux-4.14.193.orig/drivers/net/phy/swconfig_leds.c -++++ linux-4.14.193/drivers/net/phy/swconfig_leds.c -+@@ -321,6 +321,14 @@ err_free: -+ return err; -+ } -+ -++#if LINUX_VERSION_CODE < KERNEL_VERSION(4,19,0) -++static void -++swconfig_trig_activate_void(struct led_classdev *led_cdev) -++{ -++ swconfig_trig_activate(led_cdev); -++} -++#endif -++ -+ static void -+ swconfig_trig_deactivate(struct led_classdev *led_cdev) -+ { -+@@ -515,7 +523,11 @@ swconfig_create_led_trigger(struct switc -+ -+ sw_trig->swdev = swdev; -+ sw_trig->trig.name = swdev->devname; -++#if LINUX_VERSION_CODE < KERNEL_VERSION(4,19,0) -++ sw_trig->trig.activate = swconfig_trig_activate_void; -++#else -+ sw_trig->trig.activate = swconfig_trig_activate; -++#endif -+ sw_trig->trig.deactivate = swconfig_trig_deactivate; -+ -+ INIT_DELAYED_WORK(&sw_trig->sw_led_work, swconfig_led_work_func); -diff --git a/target/linux/ar71xx/tiny/config-default b/target/linux/ar71xx/tiny/config-default -new file mode 100644 -index 0000000000..1148d8c451 ---- /dev/null -+++ b/target/linux/ar71xx/tiny/config-default -@@ -0,0 +1,76 @@ -+CONFIG_ATH79_DEV_AP9X_PCI=y -+CONFIG_ATH79_DEV_DSA=y -+CONFIG_ATH79_DEV_ETH=y -+CONFIG_ATH79_DEV_GPIO_BUTTONS=y -+CONFIG_ATH79_DEV_LEDS_GPIO=y -+CONFIG_ATH79_DEV_M25P80=y -+# CONFIG_ATH79_DEV_NFC is not set -+CONFIG_ATH79_DEV_SPI=y -+CONFIG_ATH79_DEV_USB=y -+CONFIG_ATH79_DEV_WMAC=y -+CONFIG_ATH79_MACH_BHR_4GRV2=y -+CONFIG_ATH79_MACH_DIR_600_A1=y -+CONFIG_ATH79_MACH_DIR_615_C1=y -+CONFIG_ATH79_MACH_DIR_615_I1=y -+CONFIG_ATH79_MACH_ENS202EXT=y -+CONFIG_ATH79_MACH_F9K1115V2=y -+CONFIG_ATH79_MACH_NBG460N=y -+CONFIG_ATH79_MACH_TEW_632BRP=y -+CONFIG_ATH79_MACH_TEW_712BR=y -+CONFIG_ATH79_MACH_TL_MR11U=y -+CONFIG_ATH79_MACH_TL_MR13U=y -+CONFIG_ATH79_MACH_TL_MR3020=y -+CONFIG_ATH79_MACH_TL_MR3X20=y -+CONFIG_ATH79_MACH_TL_WA701ND_V2=y -+CONFIG_ATH79_MACH_TL_WA7210N_V2=y -+CONFIG_ATH79_MACH_TL_WA801ND_V3=y -+CONFIG_ATH79_MACH_TL_WA830RE_V2=y -+CONFIG_ATH79_MACH_TL_WA850RE_V2=y -+CONFIG_ATH79_MACH_TL_WA855RE_V1=y -+CONFIG_ATH79_MACH_TL_WA901ND=y -+CONFIG_ATH79_MACH_TL_WA901ND_V2=y -+CONFIG_ATH79_MACH_TL_WA901ND_V4=y -+CONFIG_ATH79_MACH_TL_WAX50RE=y -+CONFIG_ATH79_MACH_TL_WDR3320_V2=y -+CONFIG_ATH79_MACH_TL_WDR3500=y -+CONFIG_ATH79_MACH_TL_WR1041N_V2=y -+CONFIG_ATH79_MACH_TL_WR703N=y -+CONFIG_ATH79_MACH_TL_WR720N_V3=y -+CONFIG_ATH79_MACH_TL_WR741ND=y -+CONFIG_ATH79_MACH_TL_WR741ND_V4=y -+CONFIG_ATH79_MACH_TL_WR802N_V1=y -+CONFIG_ATH79_MACH_TL_WR802N_V2=y -+CONFIG_ATH79_MACH_TL_WR840N_V2=y -+CONFIG_ATH79_MACH_TL_WR841N_V1=y -+CONFIG_ATH79_MACH_TL_WR841N_V8=y -+CONFIG_ATH79_MACH_TL_WR841N_V9=y -+CONFIG_ATH79_MACH_TL_WR940N_V4=y -+CONFIG_ATH79_MACH_TL_WR941ND=y -+CONFIG_ATH79_MACH_TL_WR941ND_V6=y -+CONFIG_ATH79_MACH_WHR_HP_G300N=y -+CONFIG_ATH79_MACH_WLAE_AG300N=y -+CONFIG_ATH79_MACH_WNR2000=y -+CONFIG_ATH79_MACH_WNR2000_V3=y -+CONFIG_ATH79_MACH_WNR2000_V4=y -+CONFIG_ATH79_MACH_WP543=y -+CONFIG_ATH79_MACH_WPE72=y -+CONFIG_ATH79_MACH_ZBT_WE1526=y -+CONFIG_ATH79_NVRAM=y -+CONFIG_ATH79_PCI_ATH9K_FIXUP=y -+CONFIG_BLK_MQ_PCI=y -+CONFIG_HW_HAS_PCI=y -+CONFIG_MYLOADER=y -+CONFIG_PCI=y -+CONFIG_PCI_AR724X=y -+CONFIG_PCI_DISABLE_COMMON_QUIRKS=y -+CONFIG_PCI_DOMAINS=y -+CONFIG_SERIAL_AR933X=y -+CONFIG_SERIAL_AR933X_CONSOLE=y -+CONFIG_SERIAL_AR933X_NR_UARTS=2 -+CONFIG_SOC_AR71XX=y -+CONFIG_SOC_AR724X=y -+CONFIG_SOC_AR913X=y -+CONFIG_SOC_AR933X=y -+CONFIG_SOC_AR934X=y -+CONFIG_SOC_QCA953X=y -+CONFIG_SOC_QCA956X=y -diff --git a/target/linux/ar71xx/tiny/profiles/00-default.mk b/target/linux/ar71xx/tiny/profiles/00-default.mk -new file mode 100644 -index 0000000000..edddeb3bf6 ---- /dev/null -+++ b/target/linux/ar71xx/tiny/profiles/00-default.mk -@@ -0,0 +1,11 @@ -+define Profile/Default -+ NAME:=Default Profile (all drivers) -+ PACKAGES:= \ -+ kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport -+ PRIORITY := 1 -+endef -+ -+define Profile/Default/Description -+ Default package set compatible with most boards. -+endef -+$(eval $(call Profile,Default)) -diff --git a/target/linux/ar71xx/tiny/target.mk b/target/linux/ar71xx/tiny/target.mk -new file mode 100644 -index 0000000000..89d4447e1e ---- /dev/null -+++ b/target/linux/ar71xx/tiny/target.mk -@@ -0,0 +1,10 @@ -+BOARDNAME:=Devices with small flash -+FEATURES += squashfs small_flash -+ -+DEFAULT_PACKAGES += wpad-mini -+ -+define Target/Description -+ Build firmware images for Atheros AR71xx/AR913x/AR934x based boards with small NOR flash. -+endef -+ -+ -diff --git a/target/linux/generic/backport-4.14/010-Kbuild-don-t-hardcode-path-to-awk-in-scripts-ld-vers.patch b/target/linux/generic/backport-4.14/010-Kbuild-don-t-hardcode-path-to-awk-in-scripts-ld-vers.patch -new file mode 100644 -index 0000000000..7ac4f9d240 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/010-Kbuild-don-t-hardcode-path-to-awk-in-scripts-ld-vers.patch -@@ -0,0 +1,30 @@ -+From 13b1ecc3401653a355798eb1dee10cc1608202f4 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Mon, 18 Jan 2016 12:27:49 +0100 -+Subject: [PATCH 33/34] Kbuild: don't hardcode path to awk in -+ scripts/ld-version.sh -+ -+On some systems /usr/bin/awk does not exist, or is broken. Find it via -+$PATH instead. -+ -+Signed-off-by: Felix Fietkau -+--- -+ scripts/ld-version.sh | 4 +++- -+ 1 file changed, 3 insertions(+), 1 deletion(-) -+ -+--- a/scripts/ld-version.sh -++++ b/scripts/ld-version.sh -+@@ -1,6 +1,7 @@ -+-#!/usr/bin/awk -f -++#!/bin/sh -+ # SPDX-License-Identifier: GPL-2.0 -+ # extract linker version number from stdin and turn into single number -++exec awk ' -+ { -+ gsub(".*\\)", ""); -+ gsub(".*version ", ""); -+@@ -9,3 +10,4 @@ -+ print a[1]*100000000 + a[2]*1000000 + a[3]*10000; -+ exit -+ } -++' -diff --git a/target/linux/generic/backport-4.14/011-kbuild-export-SUBARCH.patch b/target/linux/generic/backport-4.14/011-kbuild-export-SUBARCH.patch -new file mode 100644 -index 0000000000..1c82a9576a ---- /dev/null -+++ b/target/linux/generic/backport-4.14/011-kbuild-export-SUBARCH.patch -@@ -0,0 +1,23 @@ -+From 173019b66dcc9d68ad9333aa744dad1e369b5aa8 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Sun, 9 Jul 2017 00:26:53 +0200 -+Subject: [PATCH 34/34] kernel: add compile fix for linux 4.9 on x86 -+ -+Signed-off-by: Felix Fietkau -+--- -+ Makefile | 4 ++-- -+ 1 file changed, 2 insertions(+), 2 deletions(-) -+ -+--- a/Makefile -++++ b/Makefile -+@@ -429,8 +429,8 @@ KBUILD_LDFLAGS_MODULE := -T $(srctree)/s -+ GCC_PLUGINS_CFLAGS := -+ CLANG_FLAGS := -+ -+-export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC -+-export CPP AR NM STRIP OBJCOPY OBJDUMP HOSTLDFLAGS HOST_LOADLIBES -++export ARCH SRCARCH SUBARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD -++export CC CPP AR NM STRIP OBJCOPY OBJDUMP HOSTLDFLAGS HOST_LOADLIBES -+ export MAKE AWK GENKSYMS INSTALLKERNEL PERL PYTHON UTS_MACHINE -+ export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS -+ -diff --git a/target/linux/generic/backport-4.14/012-kbuild-add-macro-for-controlling-warnings-to-linux-c.patch b/target/linux/generic/backport-4.14/012-kbuild-add-macro-for-controlling-warnings-to-linux-c.patch -new file mode 100644 -index 0000000000..8993b6376c ---- /dev/null -+++ b/target/linux/generic/backport-4.14/012-kbuild-add-macro-for-controlling-warnings-to-linux-c.patch -@@ -0,0 +1,142 @@ -+From: Arnd Bergmann -+Date: Tue, 19 Jun 2018 13:14:56 -0700 -+Subject: [PATCH] kbuild: add macro for controlling warnings to -+ linux/compiler.h -+ -+I have occasionally run into a situation where it would make sense to -+control a compiler warning from a source file rather than doing so from -+a Makefile using the $(cc-disable-warning, ...) or $(cc-option, ...) -+helpers. -+ -+The approach here is similar to what glibc uses, using __diag() and -+related macros to encapsulate a _Pragma("GCC diagnostic ...") statement -+that gets turned into the respective "#pragma GCC diagnostic ..." by -+the preprocessor when the macro gets expanded. -+ -+Like glibc, I also have an argument to pass the affected compiler -+version, but decided to actually evaluate that one. For now, this -+supports GCC_4_6, GCC_4_7, GCC_4_8, GCC_4_9, GCC_5, GCC_6, GCC_7, -+GCC_8 and GCC_9. Adding support for CLANG_5 and other interesting -+versions is straightforward here. GNU compilers starting with gcc-4.2 -+could support it in principle, but "#pragma GCC diagnostic push" -+was only added in gcc-4.6, so it seems simpler to not deal with those -+at all. The same versions show a large number of warnings already, -+so it seems easier to just leave it at that and not do a more -+fine-grained control for them. -+ -+The use cases I found so far include: -+ -+- turning off the gcc-8 -Wattribute-alias warning inside of the -+ SYSCALL_DEFINEx() macro without having to do it globally. -+ -+- Reducing the build time for a simple re-make after a change, -+ once we move the warnings from ./Makefile and -+ ./scripts/Makefile.extrawarn into linux/compiler.h -+ -+- More control over the warnings based on other configurations, -+ using preprocessor syntax instead of Makefile syntax. This should make -+ it easier for the average developer to understand and change things. -+ -+- Adding an easy way to turn the W=1 option on unconditionally -+ for a subdirectory or a specific file. This has been requested -+ by several developers in the past that want to have their subsystems -+ W=1 clean. -+ -+- Integrating clang better into the build systems. Clang supports -+ more warnings than GCC, and we probably want to classify them -+ as default, W=1, W=2 etc, but there are cases in which the -+ warnings should be classified differently due to excessive false -+ positives from one or the other compiler. -+ -+- Adding a way to turn the default warnings into errors (e.g. using -+ a new "make E=0" tag) while not also turning the W=1 warnings into -+ errors. -+ -+This patch for now just adds the minimal infrastructure in order to -+do the first of the list above. As the #pragma GCC diagnostic -+takes precedence over command line options, the next step would be -+to convert a lot of the individual Makefiles that set nonstandard -+options to use __diag() instead. -+ -+[paul.burton@mips.com: -+ - Rebase atop current master. -+ - Add __diag_GCC, or more generally __diag_, abstraction to -+ avoid code outside of linux/compiler-gcc.h needing to duplicate -+ knowledge about different GCC versions. -+ - Add a comment argument to __diag_{ignore,warn,error} which isn't -+ used in the expansion of the macros but serves to push people to -+ document the reason for using them - per feedback from Kees Cook. -+ - Translate severity to GCC-specific pragmas in linux/compiler-gcc.h -+ rather than using GCC-specific in linux/compiler_types.h. -+ - Drop all but GCC 8 macros, since we only need to define macros for -+ versions that we need to introduce pragmas for, and as of this -+ series that's just GCC 8. -+ - Capitalize comments in linux/compiler-gcc.h to match the style of -+ the rest of the file. -+ - Line up macro definitions with tabs in linux/compiler-gcc.h.] -+ -+Signed-off-by: Arnd Bergmann -+Signed-off-by: Paul Burton -+Tested-by: Christophe Leroy -+Tested-by: Stafford Horne -+Signed-off-by: Masahiro Yamada -+--- -+ -+--- a/include/linux/compiler-gcc.h -++++ b/include/linux/compiler-gcc.h -+@@ -366,3 +366,30 @@ -+ #if GCC_VERSION >= 50100 -+ #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1 -+ #endif -++ -++ -++/* -++ * Turn individual warnings and errors on and off locally, depending -++ * on version. -++ */ -++#define __diag_GCC(version, severity, s) \ -++ __diag_GCC_ ## version(__diag_GCC_ ## severity s) -++ -++/* Severity used in pragma directives */ -++#define __diag_GCC_ignore ignored -++#define __diag_GCC_warn warning -++#define __diag_GCC_error error -++ -++/* Compilers before gcc-4.6 do not understand "#pragma GCC diagnostic push" */ -++#if GCC_VERSION >= 40600 -++#define __diag_str1(s) #s -++#define __diag_str(s) __diag_str1(s) -++#define __diag(s) _Pragma(__diag_str(GCC diagnostic s)) -++#endif -++ -++#if GCC_VERSION >= 80000 -++#define __diag_GCC_8(s) __diag(s) -++#else -++#define __diag_GCC_8(s) -++#endif -++ -+--- a/include/linux/compiler_types.h -++++ b/include/linux/compiler_types.h -+@@ -287,4 +287,22 @@ struct ftrace_likely_data { -+ # define __native_word(t) (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) -+ #endif -+ -++#ifndef __diag -++#define __diag(string) -++#endif -++ -++#ifndef __diag_GCC -++#define __diag_GCC(version, severity, string) -++#endif -++ -++#define __diag_push() __diag(push) -++#define __diag_pop() __diag(pop) -++ -++#define __diag_ignore(compiler, version, option, comment) \ -++ __diag_ ## compiler(version, ignore, option) -++#define __diag_warn(compiler, version, option, comment) \ -++ __diag_ ## compiler(version, warn, option) -++#define __diag_error(compiler, version, option, comment) \ -++ __diag_ ## compiler(version, error, option) -++ -+ #endif /* __LINUX_COMPILER_TYPES_H */ -diff --git a/target/linux/generic/backport-4.14/013-disable-Wattribute-alias-warning-for-SYSCALL_DEFINEx.patch b/target/linux/generic/backport-4.14/013-disable-Wattribute-alias-warning-for-SYSCALL_DEFINEx.patch -new file mode 100644 -index 0000000000..2440ed8c0d ---- /dev/null -+++ b/target/linux/generic/backport-4.14/013-disable-Wattribute-alias-warning-for-SYSCALL_DEFINEx.patch -@@ -0,0 +1,88 @@ -+From: Arnd Bergmann -+Date: Tue, 19 Jun 2018 13:14:57 -0700 -+Subject: [PATCH] disable -Wattribute-alias warning for SYSCALL_DEFINEx() -+ -+gcc-8 warns for every single definition of a system call entry -+point, e.g.: -+ -+include/linux/compat.h:56:18: error: 'compat_sys_rt_sigprocmask' alias between functions of incompatible types 'long int(int, compat_sigset_t *, compat_sigset_t *, compat_size_t)' {aka 'long int(int, struct *, struct *, unsigned int)'} and 'long int(long int, long int, long int, long int)' [-Werror=attribute-alias] -+ asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\ -+ ^~~~~~~~~~ -+include/linux/compat.h:45:2: note: in expansion of macro 'COMPAT_SYSCALL_DEFINEx' -+ COMPAT_SYSCALL_DEFINEx(4, _##name, __VA_ARGS__) -+ ^~~~~~~~~~~~~~~~~~~~~~ -+kernel/signal.c:2601:1: note: in expansion of macro 'COMPAT_SYSCALL_DEFINE4' -+ COMPAT_SYSCALL_DEFINE4(rt_sigprocmask, int, how, compat_sigset_t __user *, nset, -+ ^~~~~~~~~~~~~~~~~~~~~~ -+include/linux/compat.h:60:18: note: aliased declaration here -+ asmlinkage long compat_SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__))\ -+ ^~~~~~~~~~ -+ -+The new warning seems reasonable in principle, but it doesn't -+help us here, since we rely on the type mismatch to sanitize the -+system call arguments. After I reported this as GCC PR82435, a new -+-Wno-attribute-alias option was added that could be used to turn the -+warning off globally on the command line, but I'd prefer to do it a -+little more fine-grained. -+ -+Interestingly, turning a warning off and on again inside of -+a single macro doesn't always work, in this case I had to add -+an extra statement inbetween and decided to copy the __SC_TEST -+one from the native syscall to the compat syscall macro. See -+https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83256 for more details -+about this. -+ -+[paul.burton@mips.com: -+ - Rebase atop current master. -+ - Split GCC & version arguments to __diag_ignore() in order to match -+ changes to the preceding patch. -+ - Add the comment argument to match the preceding patch.] -+ -+Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82435 -+Signed-off-by: Arnd Bergmann -+Signed-off-by: Paul Burton -+Tested-by: Christophe Leroy -+Tested-by: Stafford Horne -+Signed-off-by: Masahiro Yamada -+--- -+ -+--- a/include/linux/compat.h -++++ b/include/linux/compat.h -+@@ -48,6 +48,9 @@ -+ COMPAT_SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) -+ -+ #define COMPAT_SYSCALL_DEFINEx(x, name, ...) \ -++ __diag_push(); \ -++ __diag_ignore(GCC, 8, "-Wattribute-alias", \ -++ "Type aliasing is used to sanitize syscall arguments");\ -+ asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\ -+ __attribute__((alias(__stringify(compat_SyS##name)))); \ -+ static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ -+@@ -56,6 +59,7 @@ -+ { \ -+ return C_SYSC##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__)); \ -+ } \ -++ __diag_pop(); \ -+ static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)) -+ -+ #ifndef compat_user_stack_pointer -+--- a/include/linux/syscalls.h -++++ b/include/linux/syscalls.h -+@@ -208,6 +208,9 @@ static inline int is_syscall_trace_event -+ -+ #define __PROTECT(...) asmlinkage_protect(__VA_ARGS__) -+ #define __SYSCALL_DEFINEx(x, name, ...) \ -++ __diag_push(); \ -++ __diag_ignore(GCC, 8, "-Wattribute-alias", \ -++ "Type aliasing is used to sanitize syscall arguments");\ -+ asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ -+ __attribute__((alias(__stringify(SyS##name)))); \ -+ static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ -+@@ -219,6 +222,7 @@ static inline int is_syscall_trace_event -+ __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \ -+ return ret; \ -+ } \ -++ __diag_pop(); \ -+ static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)) -+ -+ /* -diff --git a/target/linux/generic/backport-4.14/020-backport_netfilter_rtcache.patch b/target/linux/generic/backport-4.14/020-backport_netfilter_rtcache.patch -new file mode 100644 -index 0000000000..88e5386c1f ---- /dev/null -+++ b/target/linux/generic/backport-4.14/020-backport_netfilter_rtcache.patch -@@ -0,0 +1,558 @@ -+From 1bb0c3ec899827cfa4668bb63a08713a40744d21 Mon Sep 17 00:00:00 2001 -+From: Florian Westphal -+Date: Sun, 9 Jul 2017 08:58:30 +0200 -+Subject: [PATCH] netfilter: conntrack: cache route for forwarded connections -+ -+... to avoid per-packet FIB lookup if possible. -+ -+The cached dst is re-used provided the input interface -+is the same as that of the previous packet in the same direction. -+ -+If not, the cached dst is invalidated. -+ -+For ipv6 we also need to store sernum, else dst_check doesn't work, -+pointed out by Eric Dumazet. -+ -+This should speed up forwarding when conntrack is already in use -+anyway, especially when using reverse path filtering -- active RPF -+enforces two FIB lookups for each packet. -+ -+Before the routing cache removal this didn't matter since RPF was performed -+only when route cache didn't yield a result; but without route cache it -+comes at higher price. -+ -+Julian Anastasov suggested to add NETDEV_UNREGISTER handler to -+avoid holding on to dsts of 'frozen' conntracks. -+ -+Signed-off-by: Florian Westphal -+--- -+ include/net/netfilter/nf_conntrack_extend.h | 4 + -+ include/net/netfilter/nf_conntrack_rtcache.h | 34 +++ -+ net/netfilter/Kconfig | 12 + -+ net/netfilter/Makefile | 3 + -+ net/netfilter/nf_conntrack_rtcache.c | 428 +++++++++++++++++++++++++++ -+ 5 files changed, 481 insertions(+) -+ create mode 100644 include/net/netfilter/nf_conntrack_rtcache.h -+ create mode 100644 net/netfilter/nf_conntrack_rtcache.c -+ -+--- a/include/net/netfilter/nf_conntrack_extend.h -++++ b/include/net/netfilter/nf_conntrack_extend.h -+@@ -28,6 +28,9 @@ enum nf_ct_ext_id { -+ #if IS_ENABLED(CONFIG_NETFILTER_SYNPROXY) -+ NF_CT_EXT_SYNPROXY, -+ #endif -++#if IS_ENABLED(CONFIG_NF_CONNTRACK_RTCACHE) -++ NF_CT_EXT_RTCACHE, -++#endif -+ NF_CT_EXT_NUM, -+ }; -+ -+@@ -40,6 +43,7 @@ enum nf_ct_ext_id { -+ #define NF_CT_EXT_TIMEOUT_TYPE struct nf_conn_timeout -+ #define NF_CT_EXT_LABELS_TYPE struct nf_conn_labels -+ #define NF_CT_EXT_SYNPROXY_TYPE struct nf_conn_synproxy -++#define NF_CT_EXT_RTCACHE_TYPE struct nf_conn_rtcache -+ -+ /* Extensions: optional stuff which isn't permanently in struct. */ -+ struct nf_ct_ext { -+--- /dev/null -++++ b/include/net/netfilter/nf_conntrack_rtcache.h -+@@ -0,0 +1,34 @@ -++#include -++#include -++#include -++ -++struct dst_entry; -++ -++struct nf_conn_dst_cache { -++ struct dst_entry *dst; -++ int iif; -++#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -++ u32 cookie; -++#endif -++ -++}; -++ -++struct nf_conn_rtcache { -++ struct nf_conn_dst_cache cached_dst[IP_CT_DIR_MAX]; -++}; -++ -++static inline -++struct nf_conn_rtcache *nf_ct_rtcache_find(const struct nf_conn *ct) -++{ -++#if IS_ENABLED(CONFIG_NF_CONNTRACK_RTCACHE) -++ return nf_ct_ext_find(ct, NF_CT_EXT_RTCACHE); -++#else -++ return NULL; -++#endif -++} -++ -++static inline int nf_conn_rtcache_iif_get(const struct nf_conn_rtcache *rtc, -++ enum ip_conntrack_dir dir) -++{ -++ return rtc->cached_dst[dir].iif; -++} -+--- a/net/netfilter/Kconfig -++++ b/net/netfilter/Kconfig -+@@ -118,6 +118,18 @@ config NF_CONNTRACK_EVENTS -+ -+ If unsure, say `N'. -+ -++config NF_CONNTRACK_RTCACHE -++ tristate "Cache route entries in conntrack objects" -++ depends on NETFILTER_ADVANCED -++ depends on NF_CONNTRACK -++ help -++ If this option is enabled, the connection tracking code will -++ cache routing information for each connection that is being -++ forwarded, at a cost of 32 bytes per conntrack object. -++ -++ To compile it as a module, choose M here. If unsure, say N. -++ The module will be called nf_conntrack_rtcache. -++ -+ config NF_CONNTRACK_TIMEOUT -+ bool 'Connection tracking timeout' -+ depends on NETFILTER_ADVANCED -+--- a/net/netfilter/Makefile -++++ b/net/netfilter/Makefile -+@@ -19,6 +19,9 @@ obj-$(CONFIG_NETFILTER_NETLINK_LOG) += n -+ # connection tracking -+ obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o -+ -++# optional conntrack route cache extension -++obj-$(CONFIG_NF_CONNTRACK_RTCACHE) += nf_conntrack_rtcache.o -++ -+ obj-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o -+ -+ # netlink interface for nf_conntrack -+--- /dev/null -++++ b/net/netfilter/nf_conntrack_rtcache.c -+@@ -0,0 +1,428 @@ -++/* route cache for netfilter. -++ * -++ * (C) 2014 Red Hat GmbH -++ * -++ * This program is free software; you can redistribute it and/or modify -++ * it under the terms of the GNU General Public License version 2 as -++ * published by the Free Software Foundation. -++ */ -++ -++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include -++ -++#include -++#include -++#include -++#include -++ -++#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -++#include -++#endif -++ -++static void __nf_conn_rtcache_destroy(struct nf_conn_rtcache *rtc, -++ enum ip_conntrack_dir dir) -++{ -++ struct dst_entry *dst = rtc->cached_dst[dir].dst; -++ -++ dst_release(dst); -++} -++ -++static void nf_conn_rtcache_destroy(struct nf_conn *ct) -++{ -++ struct nf_conn_rtcache *rtc = nf_ct_rtcache_find(ct); -++ -++ if (!rtc) -++ return; -++ -++ __nf_conn_rtcache_destroy(rtc, IP_CT_DIR_ORIGINAL); -++ __nf_conn_rtcache_destroy(rtc, IP_CT_DIR_REPLY); -++} -++ -++static void nf_ct_rtcache_ext_add(struct nf_conn *ct) -++{ -++ struct nf_conn_rtcache *rtc; -++ -++ rtc = nf_ct_ext_add(ct, NF_CT_EXT_RTCACHE, GFP_ATOMIC); -++ if (rtc) { -++ rtc->cached_dst[IP_CT_DIR_ORIGINAL].iif = -1; -++ rtc->cached_dst[IP_CT_DIR_ORIGINAL].dst = NULL; -++ rtc->cached_dst[IP_CT_DIR_REPLY].iif = -1; -++ rtc->cached_dst[IP_CT_DIR_REPLY].dst = NULL; -++ } -++} -++ -++static struct nf_conn_rtcache *nf_ct_rtcache_find_usable(struct nf_conn *ct) -++{ -++ return nf_ct_rtcache_find(ct); -++} -++ -++static struct dst_entry * -++nf_conn_rtcache_dst_get(const struct nf_conn_rtcache *rtc, -++ enum ip_conntrack_dir dir) -++{ -++ return rtc->cached_dst[dir].dst; -++} -++ -++static u32 nf_rtcache_get_cookie(int pf, const struct dst_entry *dst) -++{ -++#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -++ if (pf == NFPROTO_IPV6) { -++ const struct rt6_info *rt = (const struct rt6_info *)dst; -++ -++ if (rt->rt6i_node) -++ return (u32)rt->rt6i_node->fn_sernum; -++ } -++#endif -++ return 0; -++} -++ -++static void nf_conn_rtcache_dst_set(int pf, -++ struct nf_conn_rtcache *rtc, -++ struct dst_entry *dst, -++ enum ip_conntrack_dir dir, int iif) -++{ -++ if (rtc->cached_dst[dir].iif != iif) -++ rtc->cached_dst[dir].iif = iif; -++ -++ if (rtc->cached_dst[dir].dst != dst) { -++ struct dst_entry *old; -++ -++ dst_hold(dst); -++ -++ old = xchg(&rtc->cached_dst[dir].dst, dst); -++ dst_release(old); -++ -++#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -++ if (pf == NFPROTO_IPV6) -++ rtc->cached_dst[dir].cookie = -++ nf_rtcache_get_cookie(pf, dst); -++#endif -++ } -++} -++ -++static void nf_conn_rtcache_dst_obsolete(struct nf_conn_rtcache *rtc, -++ enum ip_conntrack_dir dir) -++{ -++ struct dst_entry *old; -++ -++ pr_debug("Invalidate iif %d for dir %d on cache %p\n", -++ rtc->cached_dst[dir].iif, dir, rtc); -++ -++ old = xchg(&rtc->cached_dst[dir].dst, NULL); -++ dst_release(old); -++ rtc->cached_dst[dir].iif = -1; -++} -++ -++static unsigned int nf_rtcache_in(u_int8_t pf, -++ struct sk_buff *skb, -++ const struct nf_hook_state *state) -++{ -++ struct nf_conn_rtcache *rtc; -++ enum ip_conntrack_info ctinfo; -++ enum ip_conntrack_dir dir; -++ struct dst_entry *dst; -++ struct nf_conn *ct; -++ int iif; -++ u32 cookie; -++ -++ if (skb_dst(skb) || skb->sk) -++ return NF_ACCEPT; -++ -++ ct = nf_ct_get(skb, &ctinfo); -++ if (!ct) -++ return NF_ACCEPT; -++ -++ rtc = nf_ct_rtcache_find_usable(ct); -++ if (!rtc) -++ return NF_ACCEPT; -++ -++ /* if iif changes, don't use cache and let ip stack -++ * do route lookup. -++ * -++ * If rp_filter is enabled it might toss skb, so -++ * we don't want to avoid these checks. -++ */ -++ dir = CTINFO2DIR(ctinfo); -++ iif = nf_conn_rtcache_iif_get(rtc, dir); -++ if (state->in->ifindex != iif) { -++ pr_debug("ct %p, iif %d, cached iif %d, skip cached entry\n", -++ ct, iif, state->in->ifindex); -++ return NF_ACCEPT; -++ } -++ dst = nf_conn_rtcache_dst_get(rtc, dir); -++ if (dst == NULL) -++ return NF_ACCEPT; -++ -++ cookie = nf_rtcache_get_cookie(pf, dst); -++ -++ dst = dst_check(dst, cookie); -++ pr_debug("obtained dst %p for skb %p, cookie %d\n", dst, skb, cookie); -++ if (likely(dst)) -++ skb_dst_set_noref(skb, dst); -++ else -++ nf_conn_rtcache_dst_obsolete(rtc, dir); -++ -++ return NF_ACCEPT; -++} -++ -++static unsigned int nf_rtcache_forward(u_int8_t pf, -++ struct sk_buff *skb, -++ const struct nf_hook_state *state) -++{ -++ struct nf_conn_rtcache *rtc; -++ enum ip_conntrack_info ctinfo; -++ enum ip_conntrack_dir dir; -++ struct nf_conn *ct; -++ struct dst_entry *dst = skb_dst(skb); -++ int iif; -++ -++ ct = nf_ct_get(skb, &ctinfo); -++ if (!ct) -++ return NF_ACCEPT; -++ -++ if (dst && dst_xfrm(dst)) -++ return NF_ACCEPT; -++ -++ if (!nf_ct_is_confirmed(ct)) { -++ if (WARN_ON(nf_ct_rtcache_find(ct))) -++ return NF_ACCEPT; -++ nf_ct_rtcache_ext_add(ct); -++ return NF_ACCEPT; -++ } -++ -++ rtc = nf_ct_rtcache_find_usable(ct); -++ if (!rtc) -++ return NF_ACCEPT; -++ -++ dir = CTINFO2DIR(ctinfo); -++ iif = nf_conn_rtcache_iif_get(rtc, dir); -++ pr_debug("ct %p, skb %p, dir %d, iif %d, cached iif %d\n", -++ ct, skb, dir, iif, state->in->ifindex); -++ if (likely(state->in->ifindex == iif)) -++ return NF_ACCEPT; -++ -++ nf_conn_rtcache_dst_set(pf, rtc, skb_dst(skb), dir, state->in->ifindex); -++ return NF_ACCEPT; -++} -++ -++static unsigned int nf_rtcache_in4(void *priv, -++ struct sk_buff *skb, -++ const struct nf_hook_state *state) -++{ -++ return nf_rtcache_in(NFPROTO_IPV4, skb, state); -++} -++ -++static unsigned int nf_rtcache_forward4(void *priv, -++ struct sk_buff *skb, -++ const struct nf_hook_state *state) -++{ -++ return nf_rtcache_forward(NFPROTO_IPV4, skb, state); -++} -++ -++#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -++static unsigned int nf_rtcache_in6(void *priv, -++ struct sk_buff *skb, -++ const struct nf_hook_state *state) -++{ -++ return nf_rtcache_in(NFPROTO_IPV6, skb, state); -++} -++ -++static unsigned int nf_rtcache_forward6(void *priv, -++ struct sk_buff *skb, -++ const struct nf_hook_state *state) -++{ -++ return nf_rtcache_forward(NFPROTO_IPV6, skb, state); -++} -++#endif -++ -++static int nf_rtcache_dst_remove(struct nf_conn *ct, void *data) -++{ -++ struct nf_conn_rtcache *rtc = nf_ct_rtcache_find(ct); -++ struct net_device *dev = data; -++ -++ if (!rtc) -++ return 0; -++ -++ if (dev->ifindex == rtc->cached_dst[IP_CT_DIR_ORIGINAL].iif || -++ dev->ifindex == rtc->cached_dst[IP_CT_DIR_REPLY].iif) { -++ nf_conn_rtcache_dst_obsolete(rtc, IP_CT_DIR_ORIGINAL); -++ nf_conn_rtcache_dst_obsolete(rtc, IP_CT_DIR_REPLY); -++ } -++ -++ return 0; -++} -++ -++static int nf_rtcache_netdev_event(struct notifier_block *this, -++ unsigned long event, void *ptr) -++{ -++ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -++ struct net *net = dev_net(dev); -++ -++ if (event == NETDEV_DOWN) -++ nf_ct_iterate_cleanup_net(net, nf_rtcache_dst_remove, dev, 0, 0); -++ -++ return NOTIFY_DONE; -++} -++ -++static struct notifier_block nf_rtcache_notifier = { -++ .notifier_call = nf_rtcache_netdev_event, -++}; -++ -++static struct nf_hook_ops rtcache_ops[] = { -++ { -++ .hook = nf_rtcache_in4, -++ .pf = NFPROTO_IPV4, -++ .hooknum = NF_INET_PRE_ROUTING, -++ .priority = NF_IP_PRI_LAST, -++ }, -++ { -++ .hook = nf_rtcache_forward4, -++ .pf = NFPROTO_IPV4, -++ .hooknum = NF_INET_FORWARD, -++ .priority = NF_IP_PRI_LAST, -++ }, -++#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -++ { -++ .hook = nf_rtcache_in6, -++ .pf = NFPROTO_IPV6, -++ .hooknum = NF_INET_PRE_ROUTING, -++ .priority = NF_IP_PRI_LAST, -++ }, -++ { -++ .hook = nf_rtcache_forward6, -++ .pf = NFPROTO_IPV6, -++ .hooknum = NF_INET_FORWARD, -++ .priority = NF_IP_PRI_LAST, -++ }, -++#endif -++}; -++ -++static struct nf_ct_ext_type rtcache_extend __read_mostly = { -++ .len = sizeof(struct nf_conn_rtcache), -++ .align = __alignof__(struct nf_conn_rtcache), -++ .id = NF_CT_EXT_RTCACHE, -++ .destroy = nf_conn_rtcache_destroy, -++}; -++ -++static int __net_init rtcache_net_init(struct net *net) -++{ -++ return nf_register_net_hooks(net, rtcache_ops, ARRAY_SIZE(rtcache_ops)); -++} -++ -++static void __net_exit rtcache_net_exit(struct net *net) -++{ -++ /* remove hooks so no new connections get rtcache extension */ -++ nf_unregister_net_hooks(net, rtcache_ops, ARRAY_SIZE(rtcache_ops)); -++} -++ -++static struct pernet_operations rtcache_ops_net_ops = { -++ .init = rtcache_net_init, -++ .exit = rtcache_net_exit, -++}; -++ -++static int __init nf_conntrack_rtcache_init(void) -++{ -++ int ret = nf_ct_extend_register(&rtcache_extend); -++ -++ if (ret < 0) { -++ pr_err("nf_conntrack_rtcache: Unable to register extension\n"); -++ return ret; -++ } -++ -++ ret = register_pernet_subsys(&rtcache_ops_net_ops); -++ if (ret) { -++ nf_ct_extend_unregister(&rtcache_extend); -++ return ret; -++ } -++ -++ ret = register_netdevice_notifier(&nf_rtcache_notifier); -++ if (ret) { -++ nf_ct_extend_unregister(&rtcache_extend); -++ unregister_pernet_subsys(&rtcache_ops_net_ops); -++ } -++ -++ return ret; -++} -++ -++static int nf_rtcache_ext_remove(struct nf_conn *ct, void *data) -++{ -++ struct nf_conn_rtcache *rtc = nf_ct_rtcache_find(ct); -++ -++ return rtc != NULL; -++} -++ -++static bool __exit nf_conntrack_rtcache_wait_for_dying(struct net *net) -++{ -++ bool wait = false; -++ int cpu; -++ -++ for_each_possible_cpu(cpu) { -++ struct nf_conntrack_tuple_hash *h; -++ struct hlist_nulls_node *n; -++ struct nf_conn *ct; -++ struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu); -++ -++ rcu_read_lock(); -++ spin_lock_bh(&pcpu->lock); -++ -++ hlist_nulls_for_each_entry(h, n, &pcpu->dying, hnnode) { -++ ct = nf_ct_tuplehash_to_ctrack(h); -++ if (nf_ct_rtcache_find(ct) != NULL) { -++ wait = true; -++ break; -++ } -++ } -++ spin_unlock_bh(&pcpu->lock); -++ rcu_read_unlock(); -++ } -++ -++ return wait; -++} -++ -++static void __exit nf_conntrack_rtcache_fini(void) -++{ -++ struct net *net; -++ int count = 0; -++ -++ synchronize_net(); -++ -++ unregister_netdevice_notifier(&nf_rtcache_notifier); -++ unregister_pernet_subsys(&rtcache_ops_net_ops); -++ -++ synchronize_net(); -++ -++ rtnl_lock(); -++ -++ /* zap all conntracks with rtcache extension */ -++ for_each_net(net) -++ nf_ct_iterate_cleanup_net(net, nf_rtcache_ext_remove, NULL, 0, 0); -++ -++ for_each_net(net) { -++ /* .. and make sure they're gone from dying list, too */ -++ while (nf_conntrack_rtcache_wait_for_dying(net)) { -++ msleep(200); -++ WARN_ONCE(++count > 25, "Waiting for all rtcache conntracks to go away\n"); -++ } -++ } -++ -++ rtnl_unlock(); -++ -++ synchronize_net(); -++ nf_ct_extend_unregister(&rtcache_extend); -++} -++module_init(nf_conntrack_rtcache_init); -++module_exit(nf_conntrack_rtcache_fini); -++ -++MODULE_LICENSE("GPL"); -++MODULE_AUTHOR("Florian Westphal "); -++MODULE_DESCRIPTION("Conntrack route cache extension"); -diff --git a/target/linux/generic/backport-4.14/025-tcp-allow-drivers-to-tweak-TSQ-logic.patch b/target/linux/generic/backport-4.14/025-tcp-allow-drivers-to-tweak-TSQ-logic.patch -new file mode 100644 -index 0000000000..4f6f5d2cfa ---- /dev/null -+++ b/target/linux/generic/backport-4.14/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 -+@@ -267,6 +267,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 -+@@ -446,6 +447,8 @@ struct sock { -+ sk_type : 16; -+ #define SK_PROTOCOL_MAX U8_MAX -+ 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 -+@@ -2750,6 +2750,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 -+@@ -1699,7 +1699,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, -+@@ -2217,7 +2217,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.14/030-USB-serial-option-fix-dwm-158-3g-modem-interface.patch b/target/linux/generic/backport-4.14/030-USB-serial-option-fix-dwm-158-3g-modem-interface.patch -new file mode 100644 -index 0000000000..0e6aa87f9d ---- /dev/null -+++ b/target/linux/generic/backport-4.14/030-USB-serial-option-fix-dwm-158-3g-modem-interface.patch -@@ -0,0 +1,42 @@ -+From 4d304a6fe93538ce356b4593dc43476b50c023e7 Mon Sep 17 00:00:00 2001 -+From: Giuseppe Lippolis -+Date: Mon, 23 Apr 2018 09:03:06 +0200 -+Subject: USB: serial: option: blacklist unused dwm-158 interfaces -+ -+The dwm-158 interface 4 and 5 doesn't answer to the AT commands -+and doesn't appears a option interface. -+Tested on openwrt distribution (kernel 4.14 using the old blacklist -+definitions). -+ -+Lars Melin also writes: -+ -+ Blacklisting interface 4 and 5 is correct because: -+ -+ MI_00 D-Link Mobile Broadband Device (cdc_ether) -+ MI_02 D-Link HSPA+DataCard Diagnostics Interface (also ppp modem) -+ MI_03 D-Link HSPA+DataCard NMEA Device -+ MI_04 D-Link HSPA+DataCard Speech Port -+ MI_05 D-Link HSPA+DataCard Debug Port -+ MI_06 USB Mass Storage Device -+ -+Signed-off-by: Giuseppe Lippolis -+[ johan: add Lars's comment on the interface layout and reword summary ] -+Cc: Lars Melin -+Cc: Dan Williams -+Signed-off-by: Johan Hovold -+--- -+ drivers/usb/serial/option.c | 3 ++- -+ 1 file changed, 2 insertions(+), 1 deletion(-) -+ -+--- a/drivers/usb/serial/option.c -++++ b/drivers/usb/serial/option.c -+@@ -1990,7 +1990,8 @@ static const struct usb_device_id option -+ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d01, 0xff) }, /* D-Link DWM-156 (variant) */ -+ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d02, 0xff) }, -+ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d03, 0xff) }, -+- { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) }, /* D-Link DWM-158 */ -++ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff), /* D-Link DWM-158 */ -++ .driver_info = RSVD(4) | RSVD(5) }, -+ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d0e, 0xff) }, /* D-Link DWM-157 C1 */ -+ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */ -+ .driver_info = RSVD(4) }, -diff --git a/target/linux/generic/backport-4.14/030-v4.17-0001-usb-dwc2-add-support-for-host-mode-external-vbus-sup.patch b/target/linux/generic/backport-4.14/030-v4.17-0001-usb-dwc2-add-support-for-host-mode-external-vbus-sup.patch -new file mode 100644 -index 0000000000..4d029ebfe2 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/030-v4.17-0001-usb-dwc2-add-support-for-host-mode-external-vbus-sup.patch -@@ -0,0 +1,109 @@ -+From 531ef5ebea96394ddb7f554d4d88e017dde30a59 Mon Sep 17 00:00:00 2001 -+From: Amelie Delaunay -+Date: Tue, 13 Feb 2018 09:28:12 +0100 -+Subject: [PATCH] usb: dwc2: add support for host mode external vbus supply -+ -+This patch adds a way to enable an external vbus supply in host mode, -+when dwc2 drvvbus signal is not used. -+ -+This patch is very similar to the one done in U-Boot dwc2 driver [1]. It -+also adds dynamic vbus supply management depending on the role and state -+of the core. -+ -+[1] https://lists.denx.de/pipermail/u-boot/2017-March/283434.html -+ -+Signed-off-by: Amelie Delaunay -+Signed-off-by: Felipe Balbi -+--- -+ drivers/usb/dwc2/core.h | 2 ++ -+ drivers/usb/dwc2/hcd.c | 26 ++++++++++++++++++++++++++ -+ 2 files changed, 28 insertions(+) -+ -+--- a/drivers/usb/dwc2/core.h -++++ b/drivers/usb/dwc2/core.h -+@@ -777,6 +777,7 @@ struct dwc2_hregs_backup { -+ * @plat: The platform specific configuration data. This can be -+ * removed once all SoCs support usb transceiver. -+ * @supplies: Definition of USB power supplies -++ * @vbus_supply: Regulator supplying vbus. -+ * @phyif: PHY interface width -+ * @lock: Spinlock that protects all the driver data structures -+ * @priv: Stores a pointer to the struct usb_hcd -+@@ -914,6 +915,7 @@ struct dwc2_hsotg { -+ struct usb_phy *uphy; -+ struct dwc2_hsotg_plat *plat; -+ struct regulator_bulk_data supplies[DWC2_NUM_SUPPLIES]; -++ struct regulator *vbus_supply; -+ u32 phyif; -+ -+ spinlock_t lock; -+--- a/drivers/usb/dwc2/hcd.c -++++ b/drivers/usb/dwc2/hcd.c -+@@ -359,6 +359,23 @@ static void dwc2_gusbcfg_init(struct dwc -+ dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); -+ } -+ -++static int dwc2_vbus_supply_init(struct dwc2_hsotg *hsotg) -++{ -++ hsotg->vbus_supply = devm_regulator_get_optional(hsotg->dev, "vbus"); -++ if (IS_ERR(hsotg->vbus_supply)) -++ return 0; -++ -++ return regulator_enable(hsotg->vbus_supply); -++} -++ -++static int dwc2_vbus_supply_exit(struct dwc2_hsotg *hsotg) -++{ -++ if (hsotg->vbus_supply) -++ return regulator_disable(hsotg->vbus_supply); -++ -++ return 0; -++} -++ -+ /** -+ * dwc2_enable_host_interrupts() - Enables the Host mode interrupts -+ * -+@@ -3346,6 +3363,7 @@ static void dwc2_conn_id_status_change(s -+ -+ /* B-Device connector (Device Mode) */ -+ if (gotgctl & GOTGCTL_CONID_B) { -++ dwc2_vbus_supply_exit(hsotg); -+ /* Wait for switch to device mode */ -+ dev_dbg(hsotg->dev, "connId B\n"); -+ if (hsotg->bus_suspended) { -+@@ -4455,6 +4473,9 @@ static int _dwc2_hcd_start(struct usb_hc -+ } -+ -+ spin_unlock_irqrestore(&hsotg->lock, flags); -++ -++ dwc2_vbus_supply_init(hsotg); -++ -+ return 0; -+ } -+ -+@@ -4482,6 +4503,8 @@ static void _dwc2_hcd_stop(struct usb_hc -+ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); -+ spin_unlock_irqrestore(&hsotg->lock, flags); -+ -++ dwc2_vbus_supply_exit(hsotg); -++ -+ usleep_range(1000, 3000); -+ } -+ -+@@ -4518,6 +4541,7 @@ static int _dwc2_hcd_suspend(struct usb_ -+ hprt0 |= HPRT0_SUSP; -+ hprt0 &= ~HPRT0_PWR; -+ dwc2_writel(hprt0, hsotg->regs + HPRT0); -++ dwc2_vbus_supply_exit(hsotg); -+ } -+ -+ /* Enter hibernation */ -+@@ -4598,6 +4622,8 @@ static int _dwc2_hcd_resume(struct usb_h -+ spin_unlock_irqrestore(&hsotg->lock, flags); -+ dwc2_port_resume(hsotg); -+ } else { -++ dwc2_vbus_supply_init(hsotg); -++ -+ /* Wait for controller to correctly update D+/D- level */ -+ usleep_range(3000, 5000); -+ -diff --git a/target/linux/generic/backport-4.14/030-v4.17-0002-usb-dwc2-dwc2_vbus_supply_init-fix-error-check.patch b/target/linux/generic/backport-4.14/030-v4.17-0002-usb-dwc2-dwc2_vbus_supply_init-fix-error-check.patch -new file mode 100644 -index 0000000000..02b61fe84f ---- /dev/null -+++ b/target/linux/generic/backport-4.14/030-v4.17-0002-usb-dwc2-dwc2_vbus_supply_init-fix-error-check.patch -@@ -0,0 +1,55 @@ -+From 438fea2a6325933868aebc20279e2669c9a21207 Mon Sep 17 00:00:00 2001 -+From: Tomeu Vizoso -+Date: Mon, 26 Mar 2018 11:00:01 +0200 -+Subject: [PATCH] usb: dwc2: dwc2_vbus_supply_init: fix error check -+ -+devm_regulator_get_optional returns -ENODEV if the regulator isn't -+there, so if that's the case we have to make sure not to leave -ENODEV -+in the regulator pointer. -+ -+Also, make sure we return 0 in that case, but correctly propagate any -+other errors. Also propagate the error from _dwc2_hcd_start. -+ -+Fixes: 531ef5ebea96 ("usb: dwc2: add support for host mode external vbus supply") -+Cc: Amelie Delaunay -+Reviewed-by: Amelie Delaunay -+Reviewed-by: Heiko Stuebner -+Reviewed-by: Grigor Tovmasyan -+Tested-by: Heiko Stuebner -+Acked-by: Minas Harutyunyan -+Signed-off-by: Tomeu Vizoso -+Signed-off-by: Felipe Balbi -+--- -+ drivers/usb/dwc2/hcd.c | 13 ++++++++----- -+ 1 file changed, 8 insertions(+), 5 deletions(-) -+ -+--- a/drivers/usb/dwc2/hcd.c -++++ b/drivers/usb/dwc2/hcd.c -+@@ -361,9 +361,14 @@ static void dwc2_gusbcfg_init(struct dwc -+ -+ static int dwc2_vbus_supply_init(struct dwc2_hsotg *hsotg) -+ { -++ int ret; -++ -+ hsotg->vbus_supply = devm_regulator_get_optional(hsotg->dev, "vbus"); -+- if (IS_ERR(hsotg->vbus_supply)) -+- return 0; -++ if (IS_ERR(hsotg->vbus_supply)) { -++ ret = PTR_ERR(hsotg->vbus_supply); -++ hsotg->vbus_supply = NULL; -++ return ret == -ENODEV ? 0 : ret; -++ } -+ -+ return regulator_enable(hsotg->vbus_supply); -+ } -+@@ -4474,9 +4479,7 @@ static int _dwc2_hcd_start(struct usb_hc -+ -+ spin_unlock_irqrestore(&hsotg->lock, flags); -+ -+- dwc2_vbus_supply_init(hsotg); -+- -+- return 0; -++ return dwc2_vbus_supply_init(hsotg); -+ } -+ -+ /* -diff --git a/target/linux/generic/backport-4.14/040-v4.17-0001-mtd-move-code-adding-master-MTD-out-of-mtd_add_devic.patch b/target/linux/generic/backport-4.14/040-v4.17-0001-mtd-move-code-adding-master-MTD-out-of-mtd_add_devic.patch -new file mode 100644 -index 0000000000..df6429776f ---- /dev/null -+++ b/target/linux/generic/backport-4.14/040-v4.17-0001-mtd-move-code-adding-master-MTD-out-of-mtd_add_devic.patch -@@ -0,0 +1,74 @@ -+From 2c77c57d22adb05b21cdb333a0c42bdfa0e19835 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Tue, 16 Jan 2018 16:45:41 +0100 -+Subject: [PATCH] mtd: move code adding master MTD out of -+ mtd_add_device_partitions() -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This change is a small cleanup of mtd_device_parse_register(). When -+using MTD_PARTITIONED_MASTER it makes sure a master MTD is registered -+before dealing with partitions. The advantage of this is not mixing -+code handling master MTD with code handling partitions. -+ -+This commit doesn't change any behavior except from a slightly different -+failure code path. The new code may need to call del_mtd_device when -+something goes wrong. -+ -+Signed-off-by: Rafał Miłecki -+Signed-off-by: Boris Brezillon -+--- -+ drivers/mtd/mtdcore.c | 25 +++++++++++++------------ -+ 1 file changed, 13 insertions(+), 12 deletions(-) -+ -+--- a/drivers/mtd/mtdcore.c -++++ b/drivers/mtd/mtdcore.c -+@@ -641,20 +641,12 @@ static int mtd_add_device_partitions(str -+ { -+ const struct mtd_partition *real_parts = parts->parts; -+ int nbparts = parts->nr_parts; -+- int ret; -+ -+- if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) { -+- ret = add_mtd_device(mtd); -+- if (ret) -+- return ret; -+- } -++ if (!nbparts && !device_is_registered(&mtd->dev)) -++ return add_mtd_device(mtd); -+ -+- if (nbparts > 0) { -+- ret = add_mtd_partitions(mtd, real_parts, nbparts); -+- if (ret && IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) -+- del_mtd_device(mtd); -+- return ret; -+- } -++ if (nbparts > 0) -++ return add_mtd_partitions(mtd, real_parts, nbparts); -+ -+ return 0; -+ } -+@@ -714,6 +706,12 @@ int mtd_device_parse_register(struct mtd -+ -+ mtd_set_dev_defaults(mtd); -+ -++ if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) { -++ ret = add_mtd_device(mtd); -++ if (ret) -++ return ret; -++ } -++ -+ memset(&parsed, 0, sizeof(parsed)); -+ -+ ret = parse_mtd_partitions(mtd, types, &parsed, parser_data); -+@@ -753,6 +751,9 @@ int mtd_device_parse_register(struct mtd -+ out: -+ /* Cleanup any parsed partitions */ -+ mtd_part_parser_cleanup(&parsed); -++ if (ret && device_is_registered(&mtd->dev)) -++ del_mtd_device(mtd); -++ -+ return ret; -+ } -+ EXPORT_SYMBOL_GPL(mtd_device_parse_register); -diff --git a/target/linux/generic/backport-4.14/040-v4.17-0002-mtd-get-rid-of-the-mtd_add_device_partitions.patch b/target/linux/generic/backport-4.14/040-v4.17-0002-mtd-get-rid-of-the-mtd_add_device_partitions.patch -new file mode 100644 -index 0000000000..1042e674c3 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/040-v4.17-0002-mtd-get-rid-of-the-mtd_add_device_partitions.patch -@@ -0,0 +1,93 @@ -+From 0dbe4ea78d69756efeb0bba0764f6bd4a9ee9567 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Tue, 16 Jan 2018 16:45:42 +0100 -+Subject: [PATCH] mtd: get rid of the mtd_add_device_partitions() -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This simplifies code a bit by: -+1) Avoiding an extra (tiny) function -+2) Checking for amount of parsed (found) partitions just once -+3) Avoiding clearing/filling struct mtd_partitions manually -+ -+With this commit proper functions are called directly from the -+mtd_device_parse_register(). It doesn't need to use minor tricks like -+memsetting struct to 0 to trigger an expected -+mtd_add_device_partitions() behavior. -+ -+Signed-off-by: Rafał Miłecki -+Signed-off-by: Boris Brezillon -+--- -+ drivers/mtd/mtdcore.c | 43 ++++++++++++------------------------------- -+ 1 file changed, 12 insertions(+), 31 deletions(-) -+ -+--- a/drivers/mtd/mtdcore.c -++++ b/drivers/mtd/mtdcore.c -+@@ -636,21 +636,6 @@ out_error: -+ return ret; -+ } -+ -+-static int mtd_add_device_partitions(struct mtd_info *mtd, -+- struct mtd_partitions *parts) -+-{ -+- const struct mtd_partition *real_parts = parts->parts; -+- int nbparts = parts->nr_parts; -+- -+- if (!nbparts && !device_is_registered(&mtd->dev)) -+- return add_mtd_device(mtd); -+- -+- if (nbparts > 0) -+- return add_mtd_partitions(mtd, real_parts, nbparts); -+- -+- return 0; -+-} -+- -+ /* -+ * Set a few defaults based on the parent devices, if not provided by the -+ * driver -+@@ -701,7 +686,7 @@ int mtd_device_parse_register(struct mtd -+ const struct mtd_partition *parts, -+ int nr_parts) -+ { -+- struct mtd_partitions parsed; -++ struct mtd_partitions parsed = { }; -+ int ret; -+ -+ mtd_set_dev_defaults(mtd); -+@@ -712,24 +697,20 @@ int mtd_device_parse_register(struct mtd -+ return ret; -+ } -+ -+- memset(&parsed, 0, sizeof(parsed)); -+- -++ /* Prefer parsed partitions over driver-provided fallback */ -+ ret = parse_mtd_partitions(mtd, types, &parsed, parser_data); -+- if ((ret < 0 || parsed.nr_parts == 0) && parts && nr_parts) { -+- /* Fall back to driver-provided partitions */ -+- parsed = (struct mtd_partitions){ -+- .parts = parts, -+- .nr_parts = nr_parts, -+- }; -+- } else if (ret < 0) { -+- /* Didn't come up with parsed OR fallback partitions */ -+- pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n", -+- ret); -+- /* Don't abort on errors; we can still use unpartitioned MTD */ -+- memset(&parsed, 0, sizeof(parsed)); -++ if (!ret && parsed.nr_parts) { -++ parts = parsed.parts; -++ nr_parts = parsed.nr_parts; -+ } -+ -+- ret = mtd_add_device_partitions(mtd, &parsed); -++ if (nr_parts) -++ ret = add_mtd_partitions(mtd, parts, nr_parts); -++ else if (!device_is_registered(&mtd->dev)) -++ ret = add_mtd_device(mtd); -++ else -++ ret = 0; -++ -+ if (ret) -+ goto out; -+ -diff --git a/target/linux/generic/backport-4.14/041-v4.17-0001-mtd-partitions-add-of_match_table-parser-matching-fo.patch b/target/linux/generic/backport-4.14/041-v4.17-0001-mtd-partitions-add-of_match_table-parser-matching-fo.patch -new file mode 100644 -index 0000000000..765b6b95df ---- /dev/null -+++ b/target/linux/generic/backport-4.14/041-v4.17-0001-mtd-partitions-add-of_match_table-parser-matching-fo.patch -@@ -0,0 +1,200 @@ -+From 5b644aa012f67fd211138a067b9f351f30bdcc60 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Wed, 14 Mar 2018 13:10:42 +0100 -+Subject: [PATCH] mtd: partitions: add of_match_table parser matching for the -+ "ofpart" type -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+In order to properly support compatibility strings as described in the -+bindings/mtd/partition.txt "ofpart" type should be treated as an -+indication for looking into OF. MTD should check "compatible" property -+and search for a matching parser rather than blindly trying the one -+supporting "fixed-partitions". -+ -+It also means that existing "fixed-partitions" parser should get renamed -+to use a more meaningful name. -+ -+This commit achievies that aim by introducing a new mtd_part_of_parse(). -+It works by looking for a matching parser for every string in the -+"compatibility" property (starting with the most specific one). -+ -+Please note that driver-specified parsers still take a precedence. It's -+assumed that driver providing a parser type has a good reason for that -+(e.g. having platform data with device-specific info). Also doing -+otherwise could break existing setups. The same applies to using default -+parsers (including "cmdlinepart") as some overwrite DT data with cmdline -+argument. -+ -+Partition parsers can now provide an of_match_table to enable -+flash<-->parser matching via device tree as documented in the -+mtd/partition.txt. -+ -+This support is currently limited to built-in parsers as it uses -+request_module() and friends. This should be sufficient for most cases -+though as compiling parsers as modules isn't a common choice. -+ -+Signed-off-by: Brian Norris -+Signed-off-by: Rafał Miłecki -+Tested-by: Peter Rosin -+Reviewed-by: Richard Weinberger -+Signed-off-by: Boris Brezillon -+--- -+ drivers/mtd/mtdpart.c | 116 +++++++++++++++++++++++++++++++++++++---- -+ include/linux/mtd/partitions.h | 1 + -+ 2 files changed, 108 insertions(+), 9 deletions(-) -+ -+--- a/drivers/mtd/mtdpart.c -++++ b/drivers/mtd/mtdpart.c -+@@ -30,6 +30,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "mtdcore.h" -+ -+@@ -919,6 +920,92 @@ static int mtd_part_do_parse(struct mtd_ -+ } -+ -+ /** -++ * mtd_part_get_compatible_parser - find MTD parser by a compatible string -++ * -++ * @compat: compatible string describing partitions in a device tree -++ * -++ * MTD parsers can specify supported partitions by providing a table of -++ * compatibility strings. This function finds a parser that advertises support -++ * for a passed value of "compatible". -++ */ -++static struct mtd_part_parser *mtd_part_get_compatible_parser(const char *compat) -++{ -++ struct mtd_part_parser *p, *ret = NULL; -++ -++ spin_lock(&part_parser_lock); -++ -++ list_for_each_entry(p, &part_parsers, list) { -++ const struct of_device_id *matches; -++ -++ matches = p->of_match_table; -++ if (!matches) -++ continue; -++ -++ for (; matches->compatible[0]; matches++) { -++ if (!strcmp(matches->compatible, compat) && -++ try_module_get(p->owner)) { -++ ret = p; -++ break; -++ } -++ } -++ -++ if (ret) -++ break; -++ } -++ -++ spin_unlock(&part_parser_lock); -++ -++ return ret; -++} -++ -++static int mtd_part_of_parse(struct mtd_info *master, -++ struct mtd_partitions *pparts) -++{ -++ struct mtd_part_parser *parser; -++ struct device_node *np; -++ struct property *prop; -++ const char *compat; -++ const char *fixed = "ofpart"; -++ int ret, err = 0; -++ -++ np = of_get_child_by_name(mtd_get_of_node(master), "partitions"); -++ of_property_for_each_string(np, "compatible", prop, compat) { -++ parser = mtd_part_get_compatible_parser(compat); -++ if (!parser) -++ continue; -++ ret = mtd_part_do_parse(parser, master, pparts, NULL); -++ if (ret > 0) { -++ of_node_put(np); -++ return ret; -++ } -++ mtd_part_parser_put(parser); -++ if (ret < 0 && !err) -++ err = ret; -++ } -++ of_node_put(np); -++ -++ /* -++ * For backward compatibility we have to try the "ofpart" -++ * parser. It supports old DT format with partitions specified as a -++ * direct subnodes of a flash device DT node without any compatibility -++ * specified we could match. -++ */ -++ parser = mtd_part_parser_get(fixed); -++ if (!parser && !request_module("%s", fixed)) -++ parser = mtd_part_parser_get(fixed); -++ if (parser) { -++ ret = mtd_part_do_parse(parser, master, pparts, NULL); -++ if (ret > 0) -++ return ret; -++ mtd_part_parser_put(parser); -++ if (ret < 0 && !err) -++ err = ret; -++ } -++ -++ return err; -++} -++ -++/** -+ * parse_mtd_partitions - parse MTD partitions -+ * @master: the master partition (describes whole MTD device) -+ * @types: names of partition parsers to try or %NULL -+@@ -950,19 +1037,30 @@ int parse_mtd_partitions(struct mtd_info -+ types = default_mtd_part_types; -+ -+ for ( ; *types; types++) { -+- pr_debug("%s: parsing partitions %s\n", master->name, *types); -+- parser = mtd_part_parser_get(*types); -+- if (!parser && !request_module("%s", *types)) -++ /* -++ * ofpart is a special type that means OF partitioning info -++ * should be used. It requires a bit different logic so it is -++ * handled in a separated function. -++ */ -++ if (!strcmp(*types, "ofpart")) { -++ ret = mtd_part_of_parse(master, pparts); -++ } else { -++ pr_debug("%s: parsing partitions %s\n", master->name, -++ *types); -+ parser = mtd_part_parser_get(*types); -+- pr_debug("%s: got parser %s\n", master->name, -+- parser ? parser->name : NULL); -+- if (!parser) -+- continue; -+- ret = mtd_part_do_parse(parser, master, pparts, data); -++ if (!parser && !request_module("%s", *types)) -++ parser = mtd_part_parser_get(*types); -++ pr_debug("%s: got parser %s\n", master->name, -++ parser ? parser->name : NULL); -++ if (!parser) -++ continue; -++ ret = mtd_part_do_parse(parser, master, pparts, data); -++ if (ret <= 0) -++ mtd_part_parser_put(parser); -++ } -+ /* Found partitions! */ -+ if (ret > 0) -+ return 0; -+- mtd_part_parser_put(parser); -+ /* -+ * Stash the first error we see; only report it if no parser -+ * succeeds -+--- a/include/linux/mtd/partitions.h -++++ b/include/linux/mtd/partitions.h -+@@ -77,6 +77,7 @@ struct mtd_part_parser { -+ struct list_head list; -+ struct module *owner; -+ const char *name; -++ const struct of_device_id *of_match_table; -+ int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, -+ struct mtd_part_parser_data *); -+ void (*cleanup)(const struct mtd_partition *pparts, int nr_parts); -diff --git a/target/linux/generic/backport-4.14/041-v4.17-0002-mtd-rename-ofpart-parser-to-fixed-partitions-as-it-f.patch b/target/linux/generic/backport-4.14/041-v4.17-0002-mtd-rename-ofpart-parser-to-fixed-partitions-as-it-f.patch -new file mode 100644 -index 0000000000..22ad40bf44 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/041-v4.17-0002-mtd-rename-ofpart-parser-to-fixed-partitions-as-it-f.patch -@@ -0,0 +1,74 @@ -+From c0faf43482e7f7dfb6d61847cb93d17748560b24 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Wed, 14 Mar 2018 13:10:43 +0100 -+Subject: [PATCH] mtd: rename "ofpart" parser to "fixed-partitions" as it fits -+ it better -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+Type "ofpart" means that OF should be used to get partitioning info and -+this driver supports "fixed-partitions" binding only. Renaming it should -+lead to less confusion especially when parsers for new compatibility -+strings start to appear. -+ -+Signed-off-by: Rafał Miłecki -+Reviewed-by: Richard Weinberger -+Signed-off-by: Boris Brezillon -+--- -+ drivers/mtd/mtdpart.c | 4 ++-- -+ drivers/mtd/ofpart.c | 11 ++++++----- -+ 2 files changed, 8 insertions(+), 7 deletions(-) -+ -+--- a/drivers/mtd/mtdpart.c -++++ b/drivers/mtd/mtdpart.c -+@@ -965,7 +965,7 @@ static int mtd_part_of_parse(struct mtd_ -+ struct device_node *np; -+ struct property *prop; -+ const char *compat; -+- const char *fixed = "ofpart"; -++ const char *fixed = "fixed-partitions"; -+ int ret, err = 0; -+ -+ np = of_get_child_by_name(mtd_get_of_node(master), "partitions"); -+@@ -985,7 +985,7 @@ static int mtd_part_of_parse(struct mtd_ -+ of_node_put(np); -+ -+ /* -+- * For backward compatibility we have to try the "ofpart" -++ * For backward compatibility we have to try the "fixed-partitions" -+ * parser. It supports old DT format with partitions specified as a -+ * direct subnodes of a flash device DT node without any compatibility -+ * specified we could match. -+--- a/drivers/mtd/ofpart.c -++++ b/drivers/mtd/ofpart.c -+@@ -25,9 +25,9 @@ static bool node_has_compatible(struct d -+ return of_get_property(pp, "compatible", NULL); -+ } -+ -+-static int parse_ofpart_partitions(struct mtd_info *master, -+- const struct mtd_partition **pparts, -+- struct mtd_part_parser_data *data) -++static int parse_fixed_partitions(struct mtd_info *master, -++ const struct mtd_partition **pparts, -++ struct mtd_part_parser_data *data) -+ { -+ struct mtd_partition *parts; -+ struct device_node *mtd_node; -+@@ -141,8 +141,8 @@ ofpart_none: -+ } -+ -+ static struct mtd_part_parser ofpart_parser = { -+- .parse_fn = parse_ofpart_partitions, -+- .name = "ofpart", -++ .parse_fn = parse_fixed_partitions, -++ .name = "fixed-partitions", -+ }; -+ -+ static int parse_ofoldpart_partitions(struct mtd_info *master, -+@@ -229,4 +229,5 @@ MODULE_AUTHOR("Vitaly Wool, David Gibson -+ * with the same name. Since we provide the ofoldpart parser, we should have -+ * the corresponding alias. -+ */ -++MODULE_ALIAS("fixed-partitions"); -+ MODULE_ALIAS("ofoldpart"); -diff --git a/target/linux/generic/backport-4.14/041-v4.17-0003-mtd-ofpart-add-of_match_table-with-fixed-partitions.patch b/target/linux/generic/backport-4.14/041-v4.17-0003-mtd-ofpart-add-of_match_table-with-fixed-partitions.patch -new file mode 100644 -index 0000000000..d6958c3eac ---- /dev/null -+++ b/target/linux/generic/backport-4.14/041-v4.17-0003-mtd-ofpart-add-of_match_table-with-fixed-partitions.patch -@@ -0,0 +1,44 @@ -+From 97b0c7c0df3efd7048ed39d7e2dee34cafd55887 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Wed, 14 Mar 2018 13:10:44 +0100 -+Subject: [PATCH] mtd: ofpart: add of_match_table with "fixed-partitions" -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This allows using this parser with any flash driver that takes care of -+setting of_node (using mtd_set_of_node helper) correctly. Up to now -+support for "fixed-partitions" DT compatibility string was working only -+with flash drivers that were specifying "ofpart" (manually or by letting -+mtd use the default set of parsers). -+ -+This matches existing bindings documentation. -+ -+Signed-off-by: Rafał Miłecki -+Reviewed-by: Brian Norris -+Tested-by: Brian Norris -+Reviewed-by: Richard Weinberger -+Signed-off-by: Boris Brezillon -+--- -+ drivers/mtd/ofpart.c | 7 +++++++ -+ 1 file changed, 7 insertions(+) -+ -+--- a/drivers/mtd/ofpart.c -++++ b/drivers/mtd/ofpart.c -+@@ -140,9 +140,16 @@ ofpart_none: -+ return ret; -+ } -+ -++static const struct of_device_id parse_ofpart_match_table[] = { -++ { .compatible = "fixed-partitions" }, -++ {}, -++}; -++MODULE_DEVICE_TABLE(of, parse_ofpart_match_table); -++ -+ static struct mtd_part_parser ofpart_parser = { -+ .parse_fn = parse_fixed_partitions, -+ .name = "fixed-partitions", -++ .of_match_table = parse_ofpart_match_table, -+ }; -+ -+ static int parse_ofoldpart_partitions(struct mtd_info *master, -diff --git a/target/linux/generic/backport-4.14/042-v4.18-0001-mtd-move-code-adding-registering-partitions-to-the-p.patch b/target/linux/generic/backport-4.14/042-v4.18-0001-mtd-move-code-adding-registering-partitions-to-the-p.patch -new file mode 100644 -index 0000000000..d017fd452b ---- /dev/null -+++ b/target/linux/generic/backport-4.14/042-v4.18-0001-mtd-move-code-adding-registering-partitions-to-the-p.patch -@@ -0,0 +1,168 @@ -+From 5ac67ce36cfe38b4c104a42ce52c5c8d526f1c95 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Tue, 27 Mar 2018 22:35:41 +0200 -+Subject: [PATCH] mtd: move code adding (registering) partitions to the -+ parse_mtd_partitions() -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This commit slightly simplifies the code. Every parse_mtd_partitions() -+caller (out of two existing ones) had to add partitions & cleanup parser -+on its own. This moves that responsibility into the function. -+ -+That change also allows dropping struct mtd_partitions argument. -+ -+There is one minor behavior change caused by this cleanup. If -+parse_mtd_partitions() fails to add partitions (add_mtd_partitions() -+return an error) then mtd_device_parse_register() will still try to -+add (register) fallback partitions. It's a real corner case affecting -+one of uncommon error paths and shouldn't cause any harm. -+ -+Signed-off-by: Rafał Miłecki -+Signed-off-by: Boris Brezillon -+--- -+ drivers/mtd/mtdcore.c | 14 ++++---------- -+ drivers/mtd/mtdcore.h | 1 - -+ drivers/mtd/mtdpart.c | 44 ++++++++++++++++---------------------------- -+ 3 files changed, 20 insertions(+), 39 deletions(-) -+ -+--- a/drivers/mtd/mtdcore.c -++++ b/drivers/mtd/mtdcore.c -+@@ -686,7 +686,6 @@ int mtd_device_parse_register(struct mtd -+ const struct mtd_partition *parts, -+ int nr_parts) -+ { -+- struct mtd_partitions parsed = { }; -+ int ret; -+ -+ mtd_set_dev_defaults(mtd); -+@@ -698,13 +697,10 @@ int mtd_device_parse_register(struct mtd -+ } -+ -+ /* Prefer parsed partitions over driver-provided fallback */ -+- ret = parse_mtd_partitions(mtd, types, &parsed, parser_data); -+- if (!ret && parsed.nr_parts) { -+- parts = parsed.parts; -+- nr_parts = parsed.nr_parts; -+- } -+- -+- if (nr_parts) -++ ret = parse_mtd_partitions(mtd, types, parser_data); -++ if (ret > 0) -++ ret = 0; -++ else if (nr_parts) -+ ret = add_mtd_partitions(mtd, parts, nr_parts); -+ else if (!device_is_registered(&mtd->dev)) -+ ret = add_mtd_device(mtd); -+@@ -730,8 +726,6 @@ int mtd_device_parse_register(struct mtd -+ } -+ -+ out: -+- /* Cleanup any parsed partitions */ -+- mtd_part_parser_cleanup(&parsed); -+ if (ret && device_is_registered(&mtd->dev)) -+ del_mtd_device(mtd); -+ -+--- a/drivers/mtd/mtdcore.h -++++ b/drivers/mtd/mtdcore.h -+@@ -15,7 +15,6 @@ int del_mtd_partitions(struct mtd_info * -+ struct mtd_partitions; -+ -+ int parse_mtd_partitions(struct mtd_info *master, const char * const *types, -+- struct mtd_partitions *pparts, -+ struct mtd_part_parser_data *data); -+ -+ void mtd_part_parser_cleanup(struct mtd_partitions *parts); -+--- a/drivers/mtd/mtdpart.c -++++ b/drivers/mtd/mtdpart.c -+@@ -383,20 +383,7 @@ static inline void free_partition(struct -+ */ -+ static int mtd_parse_part(struct mtd_part *slave, const char *const *types) -+ { -+- struct mtd_partitions parsed; -+- int err; -+- -+- err = parse_mtd_partitions(&slave->mtd, types, &parsed, NULL); -+- if (err) -+- return err; -+- else if (!parsed.nr_parts) -+- return -ENOENT; -+- -+- err = add_mtd_partitions(&slave->mtd, parsed.parts, parsed.nr_parts); -+- -+- mtd_part_parser_cleanup(&parsed); -+- -+- return err; -++ return parse_mtd_partitions(&slave->mtd, types, NULL); -+ } -+ -+ static struct mtd_part *allocate_partition(struct mtd_info *parent, -+@@ -1006,30 +993,27 @@ static int mtd_part_of_parse(struct mtd_ -+ } -+ -+ /** -+- * parse_mtd_partitions - parse MTD partitions -++ * parse_mtd_partitions - parse and register MTD partitions -++ * -+ * @master: the master partition (describes whole MTD device) -+ * @types: names of partition parsers to try or %NULL -+- * @pparts: info about partitions found is returned here -+ * @data: MTD partition parser-specific data -+ * -+- * This function tries to find partition on MTD device @master. It uses MTD -+- * partition parsers, specified in @types. However, if @types is %NULL, then -+- * the default list of parsers is used. The default list contains only the -++ * This function tries to find & register partitions on MTD device @master. It -++ * uses MTD partition parsers, specified in @types. However, if @types is %NULL, -++ * then the default list of parsers is used. The default list contains only the -+ * "cmdlinepart" and "ofpart" parsers ATM. -+ * Note: If there are more then one parser in @types, the kernel only takes the -+ * partitions parsed out by the first parser. -+ * -+ * This function may return: -+ * o a negative error code in case of failure -+- * o zero otherwise, and @pparts will describe the partitions, number of -+- * partitions, and the parser which parsed them. Caller must release -+- * resources with mtd_part_parser_cleanup() when finished with the returned -+- * data. -++ * o number of found partitions otherwise -+ */ -+ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, -+- struct mtd_partitions *pparts, -+ struct mtd_part_parser_data *data) -+ { -++ struct mtd_partitions pparts = { }; -+ struct mtd_part_parser *parser; -+ int ret, err = 0; -+ -+@@ -1043,7 +1027,7 @@ int parse_mtd_partitions(struct mtd_info -+ * handled in a separated function. -+ */ -+ if (!strcmp(*types, "ofpart")) { -+- ret = mtd_part_of_parse(master, pparts); -++ ret = mtd_part_of_parse(master, &pparts); -+ } else { -+ pr_debug("%s: parsing partitions %s\n", master->name, -+ *types); -+@@ -1054,13 +1038,17 @@ int parse_mtd_partitions(struct mtd_info -+ parser ? parser->name : NULL); -+ if (!parser) -+ continue; -+- ret = mtd_part_do_parse(parser, master, pparts, data); -++ ret = mtd_part_do_parse(parser, master, &pparts, data); -+ if (ret <= 0) -+ mtd_part_parser_put(parser); -+ } -+ /* Found partitions! */ -+- if (ret > 0) -+- return 0; -++ if (ret > 0) { -++ err = add_mtd_partitions(master, pparts.parts, -++ pparts.nr_parts); -++ mtd_part_parser_cleanup(&pparts); -++ return err ? err : pparts.nr_parts; -++ } -+ /* -+ * Stash the first error we see; only report it if no parser -+ * succeeds -diff --git a/target/linux/generic/backport-4.14/043-v4.18-mtd-bcm47xxpart-improve-handling-TRX-partition-size.patch b/target/linux/generic/backport-4.14/043-v4.18-mtd-bcm47xxpart-improve-handling-TRX-partition-size.patch -new file mode 100644 -index 0000000000..e08f8dad32 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/043-v4.18-mtd-bcm47xxpart-improve-handling-TRX-partition-size.patch -@@ -0,0 +1,70 @@ -+From 237ea0d4762cc14d0fc80e80d61f0f08e1050c7f Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Thu, 12 Apr 2018 07:24:52 +0200 -+Subject: [PATCH] mtd: bcm47xxpart: improve handling TRX partition size -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+When bcm47xxpart finds a TRX partition (container) it's supposed to jump -+to the end of it and keep looking for more partitions. TRX and its -+subpartitions are handled by a separate parser. -+ -+The problem with old code was relying on the length specified in a TRX -+header. That isn't reliable as TRX is commonly modified to have checksum -+cover only non-changing subpartitions. Otherwise modifying e.g. a rootfs -+would result in CRC32 mismatch and bootloader refusing to boot a -+firmware. -+ -+Fix it by trying better to figure out a real TRX size. We can securely -+assume that TRX has to cover all subpartitions and the last one is at -+least of a block size in size. Then compare it with a length field. -+ -+This makes code more optimal & reliable thanks to skipping data that -+shouldn't be parsed. -+ -+Signed-off-by: Rafał Miłecki -+Signed-off-by: Boris Brezillon -+--- -+ drivers/mtd/bcm47xxpart.c | 22 ++++++++++++++++++---- -+ 1 file changed, 18 insertions(+), 4 deletions(-) -+ -+--- a/drivers/mtd/bcm47xxpart.c -++++ b/drivers/mtd/bcm47xxpart.c -+@@ -186,6 +186,8 @@ static int bcm47xxpart_parse(struct mtd_ -+ /* TRX */ -+ if (buf[0x000 / 4] == TRX_MAGIC) { -+ struct trx_header *trx; -++ uint32_t last_subpart; -++ uint32_t trx_size; -+ -+ if (trx_num >= ARRAY_SIZE(trx_parts)) -+ pr_warn("No enough space to store another TRX found at 0x%X\n", -+@@ -195,11 +197,23 @@ static int bcm47xxpart_parse(struct mtd_ -+ bcm47xxpart_add_part(&parts[curr_part++], "firmware", -+ offset, 0); -+ -+- /* Jump to the end of TRX */ -++ /* -++ * Try to find TRX size. The "length" field isn't fully -++ * reliable as it could be decreased to make CRC32 cover -++ * only part of TRX data. It's commonly used as checksum -++ * can't cover e.g. ever-changing rootfs partition. -++ * Use offsets as helpers for assuming min TRX size. -++ */ -+ trx = (struct trx_header *)buf; -+- offset = roundup(offset + trx->length, blocksize); -+- /* Next loop iteration will increase the offset */ -+- offset -= blocksize; -++ last_subpart = max3(trx->offset[0], trx->offset[1], -++ trx->offset[2]); -++ trx_size = max(trx->length, last_subpart + blocksize); -++ -++ /* -++ * Skip the TRX data. Decrease offset by block size as -++ * the next loop iteration will increase it. -++ */ -++ offset += roundup(trx_size, blocksize) - blocksize; -+ continue; -+ } -+ -diff --git a/target/linux/generic/backport-4.14/044-v4.18-mtd-bcm47xxpart-add-of_match_table-with-a-new-DT-bin.patch b/target/linux/generic/backport-4.14/044-v4.18-mtd-bcm47xxpart-add-of_match_table-with-a-new-DT-bin.patch -new file mode 100644 -index 0000000000..de0ff1f818 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/044-v4.18-mtd-bcm47xxpart-add-of_match_table-with-a-new-DT-bin.patch -@@ -0,0 +1,39 @@ -+From cf589ce71e84d3b8811c65740645af254c5248c0 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Wed, 9 May 2018 10:17:29 +0200 -+Subject: [PATCH] mtd: bcm47xxpart: add of_match_table with a new DT binding -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This allows using bcm47xxpart parser to find partitions on flash -+described in DT using the "brcm,bcm947xx-cfe-partitions" compatible -+property. It means this parser doesn't have to be explicitly selected by -+a flash driver anymore. It can be used e.g. together with a generic -+m25p80 / spi-nor if device is just properly described. -+ -+Signed-off-by: Rafał Miłecki -+Signed-off-by: Boris Brezillon -+--- -+ drivers/mtd/bcm47xxpart.c | 7 +++++++ -+ 1 file changed, 7 insertions(+) -+ -+--- a/drivers/mtd/bcm47xxpart.c -++++ b/drivers/mtd/bcm47xxpart.c -+@@ -304,9 +304,16 @@ static int bcm47xxpart_parse(struct mtd_ -+ return curr_part; -+ }; -+ -++static const struct of_device_id bcm47xxpart_of_match_table[] = { -++ { .compatible = "brcm,bcm947xx-cfe-partitions" }, -++ {}, -++}; -++MODULE_DEVICE_TABLE(of, bcm47xxpart_of_match_table); -++ -+ static struct mtd_part_parser bcm47xxpart_mtd_parser = { -+ .parse_fn = bcm47xxpart_parse, -+ .name = "bcm47xxpart", -++ .of_match_table = bcm47xxpart_of_match_table, -+ }; -+ module_mtd_part_parser(bcm47xxpart_mtd_parser); -+ -diff --git a/target/linux/generic/backport-4.14/045-v4.19-mtd-parsers-trx-add-of_match_table-with-the-new-DT-b.patch b/target/linux/generic/backport-4.14/045-v4.19-mtd-parsers-trx-add-of_match_table-with-the-new-DT-b.patch -new file mode 100644 -index 0000000000..5841dd55f3 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/045-v4.19-mtd-parsers-trx-add-of_match_table-with-the-new-DT-b.patch -@@ -0,0 +1,37 @@ -+From 98534a58c8a40cdc9e3bcb04d74719fbcedfeb52 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Tue, 26 Jun 2018 00:05:08 +0200 -+Subject: [PATCH] mtd: parsers: trx: add of_match_table with the new DT binding -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This allows using TRX parser to find TRX partitions on flash device -+described in DT using a proper binding. It's useful for devices storing -+firmware on a separated flash and having rootfs partition in it. -+ -+Signed-off-by: Rafał Miłecki -+Signed-off-by: Boris Brezillon -+--- -+ drivers/mtd/parsers/parser_trx.c | 7 +++++++ -+ 1 file changed, 7 insertions(+) -+ -+--- a/drivers/mtd/parsers/parser_trx.c -++++ b/drivers/mtd/parsers/parser_trx.c -+@@ -116,9 +116,16 @@ static int parser_trx_parse(struct mtd_i -+ return i; -+ }; -+ -++static const struct of_device_id mtd_parser_trx_of_match_table[] = { -++ { .compatible = "brcm,trx" }, -++ {}, -++}; -++MODULE_DEVICE_TABLE(of, mtd_parser_trx_of_match_table); -++ -+ static struct mtd_part_parser mtd_parser_trx = { -+ .parse_fn = parser_trx_parse, -+ .name = "trx", -++ .of_match_table = mtd_parser_trx_of_match_table, -+ }; -+ module_mtd_part_parser(mtd_parser_trx); -+ -diff --git a/target/linux/generic/backport-4.14/046-v4.19-mtd-partitions-use-DT-info-for-parsing-partitions-wi.patch b/target/linux/generic/backport-4.14/046-v4.19-mtd-partitions-use-DT-info-for-parsing-partitions-wi.patch -new file mode 100644 -index 0000000000..eff1a01692 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/046-v4.19-mtd-partitions-use-DT-info-for-parsing-partitions-wi.patch -@@ -0,0 +1,102 @@ -+From 76a832254ab05502c9394cc51ded6f0abe0e0bee Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Fri, 13 Jul 2018 16:32:21 +0200 -+Subject: [PATCH] mtd: partitions: use DT info for parsing partitions with -+ "compatible" prop -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+So far only flash devices could be described in DT regarding partitions -+parsing. That could be done with "partitions" subnode and a proper -+"compatible" string. -+ -+Some devices may use hierarchical (multi-level) layouts and may mix used -+layouts (fixed and dynamic). Describing that in DT is done by specifying -+"compatible" for DT-represented partition plus optionally more -+properties and/or subnodes. -+ -+To support such layouts each DT partition has to be checked for -+additional description. -+ -+Please note this implementation will work in parallel with support for -+partition type specified for non-DT setups. That already works since -+commit 1a0915be1926 ("mtd: partitions: add support for partition -+parsers"). -+ -+Signed-off-by: Rafał Miłecki -+Signed-off-by: Boris Brezillon -+--- -+ drivers/mtd/mtdpart.c | 33 +++++++++++++-------------------- -+ 1 file changed, 13 insertions(+), 20 deletions(-) -+ -+--- a/drivers/mtd/mtdpart.c -++++ b/drivers/mtd/mtdpart.c -+@@ -370,22 +370,6 @@ static inline void free_partition(struct -+ kfree(p); -+ } -+ -+-/** -+- * mtd_parse_part - parse MTD partition looking for subpartitions -+- * -+- * @slave: part that is supposed to be a container and should be parsed -+- * @types: NULL-terminated array with names of partition parsers to try -+- * -+- * Some partitions are kind of containers with extra subpartitions (volumes). -+- * There can be various formats of such containers. This function tries to use -+- * specified parsers to analyze given partition and registers found -+- * subpartitions on success. -+- */ -+-static int mtd_parse_part(struct mtd_part *slave, const char *const *types) -+-{ -+- return parse_mtd_partitions(&slave->mtd, types, NULL); -+-} -+- -+ static struct mtd_part *allocate_partition(struct mtd_info *parent, -+ const struct mtd_partition *part, int partno, -+ uint64_t cur_offset) -+@@ -803,8 +787,8 @@ int add_mtd_partitions(struct mtd_info * -+ } -+ -+ mtd_add_partition_attrs(slave); -+- if (parts[i].types) -+- mtd_parse_part(slave, parts[i].types); -++ /* Look for subpartitions */ -++ parse_mtd_partitions(&slave->mtd, parts[i].types, NULL); -+ -+ cur_offset = slave->offset + slave->mtd.size; -+ } -+@@ -885,6 +869,12 @@ static const char * const default_mtd_pa -+ NULL -+ }; -+ -++/* Check DT only when looking for subpartitions. */ -++static const char * const default_subpartition_types[] = { -++ "ofpart", -++ NULL -++}; -++ -+ static int mtd_part_do_parse(struct mtd_part_parser *parser, -+ struct mtd_info *master, -+ struct mtd_partitions *pparts, -+@@ -955,7 +945,9 @@ static int mtd_part_of_parse(struct mtd_ -+ const char *fixed = "fixed-partitions"; -+ int ret, err = 0; -+ -+- np = of_get_child_by_name(mtd_get_of_node(master), "partitions"); -++ np = mtd_get_of_node(master); -++ if (!mtd_is_partition(master)) -++ np = of_get_child_by_name(np, "partitions"); -+ of_property_for_each_string(np, "compatible", prop, compat) { -+ parser = mtd_part_get_compatible_parser(compat); -+ if (!parser) -+@@ -1018,7 +1010,8 @@ int parse_mtd_partitions(struct mtd_info -+ int ret, err = 0; -+ -+ if (!types) -+- types = default_mtd_part_types; -++ types = mtd_is_partition(master) ? default_subpartition_types : -++ default_mtd_part_types; -+ -+ for ( ; *types; types++) { -+ /* -diff --git a/target/linux/generic/backport-4.14/047-v4.21-mtd-keep-original-flags-for-every-struct-mtd_info.patch b/target/linux/generic/backport-4.14/047-v4.21-mtd-keep-original-flags-for-every-struct-mtd_info.patch -new file mode 100644 -index 0000000000..7f90cf946a ---- /dev/null -+++ b/target/linux/generic/backport-4.14/047-v4.21-mtd-keep-original-flags-for-every-struct-mtd_info.patch -@@ -0,0 +1,58 @@ -+From 1186af457cc186c5ed01708da71b1ffbdf0a2638 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Tue, 20 Nov 2018 09:55:45 +0100 -+Subject: [PATCH] mtd: keep original flags for every struct mtd_info -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+When allocating a new partition mtd subsystem runs internal tests in the -+allocate_partition(). They may result in modifying specified flags (e.g. -+dropping some /features/ like write access). -+ -+Those constraints don't have to be necessary true for subpartitions. It -+may happen parent partition isn't block aligned (effectively disabling -+write access) while subpartition may fit blocks nicely. In such case all -+checks should be run again (starting with original flags value). -+ -+Signed-off-by: Rafał Miłecki -+Signed-off-by: Boris Brezillon -+--- -+ drivers/mtd/mtdcore.c | 2 ++ -+ drivers/mtd/mtdpart.c | 3 ++- -+ include/linux/mtd/mtd.h | 1 + -+ 3 files changed, 5 insertions(+), 1 deletion(-) -+ -+--- a/drivers/mtd/mtdcore.c -++++ b/drivers/mtd/mtdcore.c -+@@ -650,6 +650,8 @@ static void mtd_set_dev_defaults(struct -+ } else { -+ pr_debug("mtd device won't show a device symlink in sysfs\n"); -+ } -++ -++ mtd->orig_flags = mtd->flags; -+ } -+ -+ /** -+--- a/drivers/mtd/mtdpart.c -++++ b/drivers/mtd/mtdpart.c -+@@ -394,7 +394,8 @@ static struct mtd_part *allocate_partiti -+ -+ /* set up the MTD object for this partition */ -+ slave->mtd.type = parent->type; -+- slave->mtd.flags = parent->flags & ~part->mask_flags; -++ slave->mtd.flags = parent->orig_flags & ~part->mask_flags; -++ slave->mtd.orig_flags = slave->mtd.flags; -+ slave->mtd.size = part->size; -+ slave->mtd.writesize = parent->writesize; -+ slave->mtd.writebufsize = parent->writebufsize; -+--- a/include/linux/mtd/mtd.h -++++ b/include/linux/mtd/mtd.h -+@@ -218,6 +218,7 @@ struct mtd_debug_info { -+ struct mtd_info { -+ u_char type; -+ uint32_t flags; -++ uint32_t orig_flags; /* Flags as before running mtd checks */ -+ uint64_t size; // Total size of the MTD -+ -+ /* "Major" erase size for the device. Naïve users may take this -diff --git a/target/linux/generic/backport-4.14/048-v4.21-mtd-improve-calculating-partition-boundaries-when-ch.patch b/target/linux/generic/backport-4.14/048-v4.21-mtd-improve-calculating-partition-boundaries-when-ch.patch -new file mode 100644 -index 0000000000..58163e6935 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/048-v4.21-mtd-improve-calculating-partition-boundaries-when-ch.patch -@@ -0,0 +1,55 @@ -+From 6750f61a13a0197c40e4a40739117493b15f19e8 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Tue, 20 Nov 2018 10:24:09 +0100 -+Subject: [PATCH] mtd: improve calculating partition boundaries when checking -+ for alignment -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+When checking for alignment mtd should check absolute offsets. It's -+important for subpartitions as it doesn't make sense to check their -+relative addresses. -+ -+Signed-off-by: Rafał Miłecki -+Signed-off-by: Boris Brezillon -+--- -+ drivers/mtd/mtdpart.c | 13 +++++++++++-- -+ 1 file changed, 11 insertions(+), 2 deletions(-) -+ -+--- a/drivers/mtd/mtdpart.c -++++ b/drivers/mtd/mtdpart.c -+@@ -61,6 +61,15 @@ static inline struct mtd_part *mtd_to_pa -+ return container_of(mtd, struct mtd_part, mtd); -+ } -+ -++static u64 part_absolute_offset(struct mtd_info *mtd) -++{ -++ struct mtd_part *part = mtd_to_part(mtd); -++ -++ if (!mtd_is_partition(mtd)) -++ return 0; -++ -++ return part_absolute_offset(part->parent) + part->offset; -++} -+ -+ /* -+ * MTD methods which simply translate the effective address and pass through -+@@ -562,7 +571,7 @@ static struct mtd_part *allocate_partiti -+ if (!(slave->mtd.flags & MTD_NO_ERASE)) -+ wr_alignment = slave->mtd.erasesize; -+ -+- tmp = slave->offset; -++ tmp = part_absolute_offset(parent) + slave->offset; -+ remainder = do_div(tmp, wr_alignment); -+ if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) { -+ /* Doesn't start on a boundary of major erase size */ -+@@ -573,7 +582,7 @@ static struct mtd_part *allocate_partiti -+ part->name); -+ } -+ -+- tmp = slave->mtd.size; -++ tmp = part_absolute_offset(parent) + slave->mtd.size; -+ remainder = do_div(tmp, wr_alignment); -+ if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) { -+ slave->mtd.flags &= ~MTD_WRITEABLE; -diff --git a/target/linux/generic/backport-4.14/050-v4.19-f2fs-skip-verifying-block-address-non-regular-inode.patch b/target/linux/generic/backport-4.14/050-v4.19-f2fs-skip-verifying-block-address-non-regular-inode.patch -new file mode 100644 -index 0000000000..65ab16a97a ---- /dev/null -+++ b/target/linux/generic/backport-4.14/050-v4.19-f2fs-skip-verifying-block-address-non-regular-inode.patch -@@ -0,0 +1,69 @@ -+From dda9f4b9cac6bdd2a96253b4444d7a6ce5132edb Mon Sep 17 00:00:00 2001 -+From: Chao Yu -+Date: Sat, 11 Aug 2018 23:42:09 +0800 -+Subject: f2fs: fix to skip verifying block address for non-regular inode -+ -+generic/184 1s ... [failed, exit status 1]- output mismatch -+ --- tests/generic/184.out 2015-01-11 16:52:27.643681072 +0800 -+ QA output created by 184 - silence is golden -+ +rm: cannot remove '/mnt/f2fs/null': Bad address -+ +mknod: '/mnt/f2fs/null': Bad address -+ +chmod: cannot access '/mnt/f2fs/null': Bad address -+ +./tests/generic/184: line 36: /mnt/f2fs/null: Bad address -+ ... -+ -+F2FS-fs (zram0): access invalid blkaddr:259 -+EIP: f2fs_is_valid_blkaddr+0x14b/0x1b0 [f2fs] -+ f2fs_iget+0x927/0x1010 [f2fs] -+ f2fs_lookup+0x26e/0x630 [f2fs] -+ __lookup_slow+0xb3/0x140 -+ lookup_slow+0x31/0x50 -+ walk_component+0x185/0x1f0 -+ path_lookupat+0x51/0x190 -+ filename_lookup+0x7f/0x140 -+ user_path_at_empty+0x36/0x40 -+ vfs_statx+0x61/0xc0 -+ __do_sys_stat64+0x29/0x40 -+ sys_stat64+0x13/0x20 -+ do_fast_syscall_32+0xaa/0x22c -+ entry_SYSENTER_32+0x53/0x86 -+ -+In f2fs_iget(), we will check inode's first block address, if it is valid, -+we will set FI_FIRST_BLOCK_WRITTEN flag in inode. -+ -+But we should only do this for regular inode, otherwise, like special -+inode, i_addr[0] is used for storing device info instead of block address, -+it will fail checking flow obviously. -+ -+So for non-regular inode, let's skip verifying address and setting flag. -+ -+Signed-off-by: Chao Yu -+Signed-off-by: Jaegeuk Kim -+--- -+ fs/f2fs/inode.c | 14 ++++++++------ -+ 1 file changed, 8 insertions(+), 6 deletions(-) -+ -+--- a/fs/f2fs/inode.c -++++ b/fs/f2fs/inode.c -+@@ -310,13 +310,15 @@ static int do_read_inode(struct inode *i -+ /* get rdev by using inline_info */ -+ __get_inode_rdev(inode, ri); -+ -+- err = __written_first_block(sbi, ri); -+- if (err < 0) { -+- f2fs_put_page(node_page, 1); -+- return err; -++ if (S_ISREG(inode->i_mode)) { -++ err = __written_first_block(sbi, ri); -++ if (err < 0) { -++ f2fs_put_page(node_page, 1); -++ return err; -++ } -++ if (!err) -++ set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN); -+ } -+- if (!err) -+- set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN); -+ -+ if (!need_inode_block_update(sbi, inode->i_ino)) -+ fi->last_disk_size = inode->i_size; -diff --git a/target/linux/generic/backport-4.14/071-v4.15-0001-net-bgmac-enable-master-mode-for-BCM54210E-and-B5021.patch b/target/linux/generic/backport-4.14/071-v4.15-0001-net-bgmac-enable-master-mode-for-BCM54210E-and-B5021.patch -new file mode 100644 -index 0000000000..db239e0a00 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/071-v4.15-0001-net-bgmac-enable-master-mode-for-BCM54210E-and-B5021.patch -@@ -0,0 +1,50 @@ -+From 12acd136913ccdf394eeb2bc8686ff5505368119 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Thu, 12 Oct 2017 10:21:26 +0200 -+Subject: [PATCH] net: bgmac: enable master mode for BCM54210E and B50212E PHYs -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+There are 4 very similar PHYs: -+0x600d84a1: BCM54210E (rev B0) -+0x600d84a2: BCM54210E (rev B1) -+0x600d84a5: B50212E (rev B0) -+0x600d84a6: B50212E (rev B1) -+that need setting master mode manually. It's because they run in slave -+mode by default with Automatic Slave/Master configuration disabled which -+can lead to unreliable connection with massive ping loss. -+ -+So far it was reported for a board with BCM47189 SoC and B50212E B1 PHY -+connected to the bgmac supported ethernet device. Telling PHY driver to -+setup PHY properly solves this issue. -+ -+Signed-off-by: Rafał Miłecki -+Signed-off-by: David S. Miller -+--- -+ drivers/net/ethernet/broadcom/bgmac-bcma.c | 8 +++++++- -+ 1 file changed, 7 insertions(+), 1 deletion(-) -+ -+--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c -++++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c -+@@ -184,13 +184,19 @@ static int bgmac_probe(struct bcma_devic -+ -+ if (!bgmac_is_bcm4707_family(core) && -+ !(ci->id == BCMA_CHIP_ID_BCM53573 && core->core_unit == 1)) { -++ struct phy_device *phydev; -++ -+ mii_bus = bcma_mdio_mii_register(bgmac); -+ if (IS_ERR(mii_bus)) { -+ err = PTR_ERR(mii_bus); -+ goto err; -+ } -+- -+ bgmac->mii_bus = mii_bus; -++ -++ phydev = mdiobus_get_phy(bgmac->mii_bus, bgmac->phyaddr); -++ if (ci->id == BCMA_CHIP_ID_BCM53573 && phydev && -++ (phydev->drv->phy_id & phydev->drv->phy_id_mask) == PHY_ID_BCM54210E) -++ phydev->dev_flags |= PHY_BRCM_EN_MASTER_MODE; -+ } -+ -+ if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) { -diff --git a/target/linux/generic/backport-4.14/076-v4.15-0001-net-phy-broadcom-support-new-device-flag-for-setting.patch b/target/linux/generic/backport-4.14/076-v4.15-0001-net-phy-broadcom-support-new-device-flag-for-setting.patch -new file mode 100644 -index 0000000000..a22d272656 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/076-v4.15-0001-net-phy-broadcom-support-new-device-flag-for-setting.patch -@@ -0,0 +1,54 @@ -+From 2355a6546a053b1c16ebefd6ce1f0cccc00e1da5 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Thu, 12 Oct 2017 10:21:25 +0200 -+Subject: [PATCH] net: phy: broadcom: support new device flag for setting -+ master mode -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+Some of Broadcom's PHYs run by default in slave mode with Automatic -+Slave/Master configuration disabled. It stops them from working properly -+with some devices. -+ -+So far it has been verified for BCM54210E and BCM50212E which don't -+work well with Intel's I217-LM and I218-LM: -+http://ark.intel.com/products/60019/Intel-Ethernet-Connection-I217-LM -+http://ark.intel.com/products/71307/Intel-Ethernet-Connection-I218-LM -+I was told there is massive ping loss. -+ -+This commit adds support for a new flag which can be set by an ethernet -+driver to fixup PHY setup. -+ -+Signed-off-by: Rafał Miłecki -+Signed-off-by: David S. Miller -+--- -+ drivers/net/phy/broadcom.c | 6 ++++++ -+ include/linux/brcmphy.h | 1 + -+ 2 files changed, 7 insertions(+) -+ -+--- a/drivers/net/phy/broadcom.c -++++ b/drivers/net/phy/broadcom.c -+@@ -43,6 +43,12 @@ static int bcm54210e_config_init(struct -+ val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN; -+ bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val); -+ -++ if (phydev->dev_flags & PHY_BRCM_EN_MASTER_MODE) { -++ val = phy_read(phydev, MII_CTRL1000); -++ val |= CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER; -++ phy_write(phydev, MII_CTRL1000, val); -++ } -++ -+ return 0; -+ } -+ -+--- a/include/linux/brcmphy.h -++++ b/include/linux/brcmphy.h -+@@ -64,6 +64,7 @@ -+ #define PHY_BRCM_EXT_IBND_TX_ENABLE 0x00002000 -+ #define PHY_BRCM_CLEAR_RGMII_MODE 0x00004000 -+ #define PHY_BRCM_DIS_TXCRXC_NOENRGY 0x00008000 -++#define PHY_BRCM_EN_MASTER_MODE 0x00010000 -+ -+ /* Broadcom BCM7xxx specific workarounds */ -+ #define PHY_BRCM_7XXX_REV(x) (((x) >> 8) & 0xff) -diff --git a/target/linux/generic/backport-4.14/080-v5.1-0001-bcma-keep-a-direct-pointer-to-the-struct-device.patch b/target/linux/generic/backport-4.14/080-v5.1-0001-bcma-keep-a-direct-pointer-to-the-struct-device.patch -new file mode 100644 -index 0000000000..cc32aee17b ---- /dev/null -+++ b/target/linux/generic/backport-4.14/080-v5.1-0001-bcma-keep-a-direct-pointer-to-the-struct-device.patch -@@ -0,0 +1,199 @@ -+From 5a1c18b761ddb299a06746948b9ec2814b04fa92 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Wed, 2 Jan 2019 00:00:01 +0100 -+Subject: [PATCH] bcma: keep a direct pointer to the struct device -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+Accessing struct device is pretty useful/common so having a direct -+pointer: -+1) Simplifies some code -+2) Makes bcma_bus_get_host_dev() unneeded -+3) Allows further improvements like using dev_* printing helpers -+ -+Signed-off-by: Rafał Miłecki -+Signed-off-by: Kalle Valo -+--- -+ drivers/bcma/bcma_private.h | 1 - -+ drivers/bcma/driver_gpio.c | 2 +- -+ drivers/bcma/host_pci.c | 2 ++ -+ drivers/bcma/host_soc.c | 4 ++-- -+ drivers/bcma/main.c | 45 +++++++++---------------------------- -+ include/linux/bcma/bcma.h | 11 +++------ -+ 6 files changed, 18 insertions(+), 47 deletions(-) -+ -+--- a/drivers/bcma/bcma_private.h -++++ b/drivers/bcma/bcma_private.h -+@@ -33,7 +33,6 @@ int __init bcma_bus_early_register(struc -+ int bcma_bus_suspend(struct bcma_bus *bus); -+ int bcma_bus_resume(struct bcma_bus *bus); -+ #endif -+-struct device *bcma_bus_get_host_dev(struct bcma_bus *bus); -+ -+ /* scan.c */ -+ void bcma_detect_chip(struct bcma_bus *bus); -+--- a/drivers/bcma/driver_gpio.c -++++ b/drivers/bcma/driver_gpio.c -+@@ -183,7 +183,7 @@ int bcma_gpio_init(struct bcma_drv_cc *c -+ chip->direction_input = bcma_gpio_direction_input; -+ chip->direction_output = bcma_gpio_direction_output; -+ chip->owner = THIS_MODULE; -+- chip->parent = bcma_bus_get_host_dev(bus); -++ chip->parent = bus->dev; -+ #if IS_BUILTIN(CONFIG_OF) -+ chip->of_node = cc->core->dev.of_node; -+ #endif -+--- a/drivers/bcma/host_pci.c -++++ b/drivers/bcma/host_pci.c -+@@ -196,6 +196,8 @@ static int bcma_host_pci_probe(struct pc -+ goto err_pci_release_regions; -+ } -+ -++ bus->dev = &dev->dev; -++ -+ /* Map MMIO */ -+ err = -ENOMEM; -+ bus->mmio = pci_iomap(dev, 0, ~0UL); -+--- a/drivers/bcma/host_soc.c -++++ b/drivers/bcma/host_soc.c -+@@ -179,7 +179,6 @@ int __init bcma_host_soc_register(struct -+ /* Host specific */ -+ bus->hosttype = BCMA_HOSTTYPE_SOC; -+ bus->ops = &bcma_host_soc_ops; -+- bus->host_pdev = NULL; -+ -+ /* Initialize struct, detect chip */ -+ bcma_init_bus(bus); -+@@ -213,6 +212,8 @@ static int bcma_host_soc_probe(struct pl -+ if (!bus) -+ return -ENOMEM; -+ -++ bus->dev = dev; -++ -+ /* Map MMIO */ -+ bus->mmio = of_iomap(np, 0); -+ if (!bus->mmio) -+@@ -221,7 +222,6 @@ static int bcma_host_soc_probe(struct pl -+ /* Host specific */ -+ bus->hosttype = BCMA_HOSTTYPE_SOC; -+ bus->ops = &bcma_host_soc_ops; -+- bus->host_pdev = pdev; -+ -+ /* Initialize struct, detect chip */ -+ bcma_init_bus(bus); -+--- a/drivers/bcma/main.c -++++ b/drivers/bcma/main.c -+@@ -223,8 +223,8 @@ unsigned int bcma_core_irq(struct bcma_d -+ mips_irq = bcma_core_mips_irq(core); -+ return mips_irq <= 4 ? mips_irq + 2 : 0; -+ } -+- if (bus->host_pdev) -+- return bcma_of_get_irq(&bus->host_pdev->dev, core, num); -++ if (bus->dev) -++ return bcma_of_get_irq(bus->dev, core, num); -+ return 0; -+ case BCMA_HOSTTYPE_SDIO: -+ return 0; -+@@ -239,18 +239,18 @@ void bcma_prepare_core(struct bcma_bus * -+ core->dev.release = bcma_release_core_dev; -+ core->dev.bus = &bcma_bus_type; -+ dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index); -+- core->dev.parent = bcma_bus_get_host_dev(bus); -+- if (core->dev.parent) -+- bcma_of_fill_device(core->dev.parent, core); -++ core->dev.parent = bus->dev; -++ if (bus->dev) -++ bcma_of_fill_device(bus->dev, core); -+ -+ switch (bus->hosttype) { -+ case BCMA_HOSTTYPE_PCI: -+- core->dma_dev = &bus->host_pci->dev; -++ core->dma_dev = bus->dev; -+ core->irq = bus->host_pci->irq; -+ break; -+ case BCMA_HOSTTYPE_SOC: -+- if (IS_ENABLED(CONFIG_OF) && bus->host_pdev) { -+- core->dma_dev = &bus->host_pdev->dev; -++ if (IS_ENABLED(CONFIG_OF) && bus->dev) { -++ core->dma_dev = bus->dev; -+ } else { -+ core->dev.dma_mask = &core->dev.coherent_dma_mask; -+ core->dma_dev = &core->dev; -+@@ -261,28 +261,6 @@ void bcma_prepare_core(struct bcma_bus * -+ } -+ } -+ -+-struct device *bcma_bus_get_host_dev(struct bcma_bus *bus) -+-{ -+- switch (bus->hosttype) { -+- case BCMA_HOSTTYPE_PCI: -+- if (bus->host_pci) -+- return &bus->host_pci->dev; -+- else -+- return NULL; -+- case BCMA_HOSTTYPE_SOC: -+- if (bus->host_pdev) -+- return &bus->host_pdev->dev; -+- else -+- return NULL; -+- case BCMA_HOSTTYPE_SDIO: -+- if (bus->host_sdio) -+- return &bus->host_sdio->dev; -+- else -+- return NULL; -+- } -+- return NULL; -+-} -+- -+ void bcma_init_bus(struct bcma_bus *bus) -+ { -+ mutex_lock(&bcma_buses_mutex); -+@@ -402,7 +380,6 @@ int bcma_bus_register(struct bcma_bus *b -+ { -+ int err; -+ struct bcma_device *core; -+- struct device *dev; -+ -+ /* Scan for devices (cores) */ -+ err = bcma_bus_scan(bus); -+@@ -425,10 +402,8 @@ int bcma_bus_register(struct bcma_bus *b -+ bcma_core_pci_early_init(&bus->drv_pci[0]); -+ } -+ -+- dev = bcma_bus_get_host_dev(bus); -+- if (dev) { -+- of_platform_default_populate(dev->of_node, NULL, dev); -+- } -++ if (bus->dev) -++ of_platform_default_populate(bus->dev->of_node, NULL, bus->dev); -+ -+ /* Cores providing flash access go before SPROM init */ -+ list_for_each_entry(core, &bus->cores, list) { -+--- a/include/linux/bcma/bcma.h -++++ b/include/linux/bcma/bcma.h -+@@ -332,6 +332,8 @@ extern int bcma_arch_register_fallback_s -+ struct ssb_sprom *out)); -+ -+ struct bcma_bus { -++ struct device *dev; -++ -+ /* The MMIO area. */ -+ void __iomem *mmio; -+ -+@@ -339,14 +341,7 @@ struct bcma_bus { -+ -+ enum bcma_hosttype hosttype; -+ bool host_is_pcie2; /* Used for BCMA_HOSTTYPE_PCI only */ -+- union { -+- /* Pointer to the PCI bus (only for BCMA_HOSTTYPE_PCI) */ -+- struct pci_dev *host_pci; -+- /* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */ -+- struct sdio_func *host_sdio; -+- /* Pointer to platform device (only for BCMA_HOSTTYPE_SOC) */ -+- struct platform_device *host_pdev; -+- }; -++ struct pci_dev *host_pci; /* PCI bus pointer (BCMA_HOSTTYPE_PCI only) */ -+ -+ struct bcma_chipinfo chipinfo; -+ -diff --git a/target/linux/generic/backport-4.14/080-v5.1-0002-bcma-use-dev_-printing-functions.patch b/target/linux/generic/backport-4.14/080-v5.1-0002-bcma-use-dev_-printing-functions.patch -new file mode 100644 -index 0000000000..7ce8ba8967 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/080-v5.1-0002-bcma-use-dev_-printing-functions.patch -@@ -0,0 +1,36 @@ -+From 777bc4801a6868fcbff09ffb6e30f023e7c5ed38 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Wed, 2 Jan 2019 00:00:02 +0100 -+Subject: [PATCH] bcma: use dev_* printing functions -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+It provides more meaningful messages. -+ -+Signed-off-by: Rafał Miłecki -+Signed-off-by: Kalle Valo -+--- -+ drivers/bcma/bcma_private.h | 8 ++++---- -+ 1 file changed, 4 insertions(+), 4 deletions(-) -+ -+--- a/drivers/bcma/bcma_private.h -++++ b/drivers/bcma/bcma_private.h -+@@ -10,13 +10,13 @@ -+ #include -+ -+ #define bcma_err(bus, fmt, ...) \ -+- pr_err("bus%d: " fmt, (bus)->num, ##__VA_ARGS__) -++ dev_err((bus)->dev, "bus%d: " fmt, (bus)->num, ##__VA_ARGS__) -+ #define bcma_warn(bus, fmt, ...) \ -+- pr_warn("bus%d: " fmt, (bus)->num, ##__VA_ARGS__) -++ dev_warn((bus)->dev, "bus%d: " fmt, (bus)->num, ##__VA_ARGS__) -+ #define bcma_info(bus, fmt, ...) \ -+- pr_info("bus%d: " fmt, (bus)->num, ##__VA_ARGS__) -++ dev_info((bus)->dev, "bus%d: " fmt, (bus)->num, ##__VA_ARGS__) -+ #define bcma_debug(bus, fmt, ...) \ -+- pr_debug("bus%d: " fmt, (bus)->num, ##__VA_ARGS__) -++ dev_dbg((bus)->dev, "bus%d: " fmt, (bus)->num, ##__VA_ARGS__) -+ -+ struct bcma_bus; -+ -diff --git a/target/linux/generic/backport-4.14/085-v4.16-0001-i2c-gpio-Enable-working-over-slow-can_sleep-GPIOs.patch b/target/linux/generic/backport-4.14/085-v4.16-0001-i2c-gpio-Enable-working-over-slow-can_sleep-GPIOs.patch -new file mode 100644 -index 0000000000..ead6675e0b ---- /dev/null -+++ b/target/linux/generic/backport-4.14/085-v4.16-0001-i2c-gpio-Enable-working-over-slow-can_sleep-GPIOs.patch -@@ -0,0 +1,84 @@ -+From f11a04464ae57e8db1bb7634547842b43e36a898 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= -+Date: Fri, 22 Dec 2017 22:47:16 +0100 -+Subject: i2c: gpio: Enable working over slow can_sleep GPIOs -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+"Slow" GPIOs (usually those connected over an SPI or an I2C bus) are, -+well, slow in their operation. It is generally a good idea to avoid -+using them for time-critical operation, but sometimes the hardware just -+sucks, and the software has to cope. In addition to that, the I2C bus -+itself does not actually define any strict timing limits; the bus is -+free to go all the way down to DC. The timeouts (and therefore the -+slowest acceptable frequency) are present only in SMBus. -+ -+The `can_sleep` is IMHO a wrong concept to use here. My SPI-to-quad-UART -+chip (MAX14830) is connected via a 26MHz SPI bus, and it happily drives -+SCL at 200kHz (5µs pulses) during my benchmarks. That's faster than the -+maximal allowed speed of the traditional I2C. -+ -+The previous version of this code did not really block operation over -+slow GPIO pins, anyway. Instead, it just resorted to printing a warning -+with a backtrace each time a GPIO pin was accessed, thereby slowing -+things down even more. -+ -+Finally, it's not just me. A similar patch was originally submitted in -+2015 [1]. -+ -+[1] https://patchwork.ozlabs.org/patch/450956/ -+ -+Signed-off-by: Jan Kundrát -+Acked-by: Uwe Kleine-König -+Signed-off-by: Wolfram Sang -+--- -+ drivers/i2c/busses/i2c-gpio.c | 11 +++++++---- -+ 1 file changed, 7 insertions(+), 4 deletions(-) -+ -+--- a/drivers/i2c/busses/i2c-gpio.c -++++ b/drivers/i2c/busses/i2c-gpio.c -+@@ -44,7 +44,7 @@ static void i2c_gpio_setsda_val(void *da -+ { -+ struct i2c_gpio_platform_data *pdata = data; -+ -+- gpio_set_value(pdata->sda_pin, state); -++ gpio_set_value_cansleep(pdata->sda_pin, state); -+ } -+ -+ /* Toggle SCL by changing the direction of the pin. */ -+@@ -68,21 +68,21 @@ static void i2c_gpio_setscl_val(void *da -+ { -+ struct i2c_gpio_platform_data *pdata = data; -+ -+- gpio_set_value(pdata->scl_pin, state); -++ gpio_set_value_cansleep(pdata->scl_pin, state); -+ } -+ -+ static int i2c_gpio_getsda(void *data) -+ { -+ struct i2c_gpio_platform_data *pdata = data; -+ -+- return gpio_get_value(pdata->sda_pin); -++ return gpio_get_value_cansleep(pdata->sda_pin); -+ } -+ -+ static int i2c_gpio_getscl(void *data) -+ { -+ struct i2c_gpio_platform_data *pdata = data; -+ -+- return gpio_get_value(pdata->scl_pin); -++ return gpio_get_value_cansleep(pdata->scl_pin); -+ } -+ -+ static int of_i2c_gpio_get_pins(struct device_node *np, -+@@ -175,6 +175,9 @@ static int i2c_gpio_probe(struct platfor -+ memcpy(pdata, dev_get_platdata(&pdev->dev), sizeof(*pdata)); -+ } -+ -++ if (gpiod_cansleep(gpio_to_desc(pdata->sda_pin)) || gpiod_cansleep(gpio_to_desc(pdata->scl_pin))) -++ dev_warn(&pdev->dev, "Slow GPIO pins might wreak havoc into I2C/SMBus bus timing"); -++ -+ if (pdata->sda_is_open_drain) { -+ gpio_direction_output(pdata->sda_pin, 1); -+ bit_data->setsda = i2c_gpio_setsda_val; -diff --git a/target/linux/generic/backport-4.14/090-net-bridge-add-support-for-port-isolation.patch b/target/linux/generic/backport-4.14/090-net-bridge-add-support-for-port-isolation.patch -new file mode 100644 -index 0000000000..6237177a45 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/090-net-bridge-add-support-for-port-isolation.patch -@@ -0,0 +1,145 @@ -+From: Nikolay Aleksandrov -+Date: Thu, 24 May 2018 11:56:48 +0300 -+Subject: [PATCH] net: bridge: add support for port isolation -+ -+This patch adds support for a new port flag - BR_ISOLATED. If it is set -+then isolated ports cannot communicate between each other, but they can -+still communicate with non-isolated ports. The same can be achieved via -+ACLs but they can't scale with large number of ports and also the -+complexity of the rules grows. This feature can be used to achieve -+isolated vlan functionality (similar to pvlan) as well, though currently -+it will be port-wide (for all vlans on the port). The new test in -+should_deliver uses data that is already cache hot and the new boolean -+is used to avoid an additional source port test in should_deliver. -+ -+Signed-off-by: Nikolay Aleksandrov -+Reviewed-by: Toshiaki Makita -+Signed-off-by: David S. Miller -+--- -+ -+--- a/include/uapi/linux/if_link.h -++++ b/include/uapi/linux/if_link.h -+@@ -326,6 +326,8 @@ enum { -+ IFLA_BRPORT_MCAST_TO_UCAST, -+ IFLA_BRPORT_VLAN_TUNNEL, -+ IFLA_BRPORT_BCAST_FLOOD, -++ IFLA_BRPORT_NEIGH_SUPPRESS, -++ IFLA_BRPORT_ISOLATED, -+ __IFLA_BRPORT_MAX -+ }; -+ #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) -+--- a/net/bridge/br_forward.c -++++ b/net/bridge/br_forward.c -+@@ -30,7 +30,8 @@ static inline int should_deliver(const s -+ vg = nbp_vlan_group_rcu(p); -+ return ((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) && -+ br_allowed_egress(vg, skb) && p->state == BR_STATE_FORWARDING && -+- nbp_switchdev_allowed_egress(p, skb); -++ nbp_switchdev_allowed_egress(p, skb) && -++ !br_skb_isolated(p, skb); -+ } -+ -+ int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb) -+--- a/net/bridge/br_input.c -++++ b/net/bridge/br_input.c -+@@ -170,6 +170,7 @@ int br_handle_frame_finish(struct net *n -+ goto drop; -+ -+ BR_INPUT_SKB_CB(skb)->brdev = br->dev; -++ BR_INPUT_SKB_CB(skb)->src_port_isolated = !!(p->flags & BR_ISOLATED); -+ -+ if (IS_ENABLED(CONFIG_INET) && skb->protocol == htons(ETH_P_ARP)) -+ br_do_proxy_arp(skb, br, vid, p); -+--- a/net/bridge/br_netlink.c -++++ b/net/bridge/br_netlink.c -+@@ -138,6 +138,7 @@ static inline size_t br_port_info_size(v -+ + nla_total_size(1) /* IFLA_BRPORT_PROXYARP */ -+ + nla_total_size(1) /* IFLA_BRPORT_PROXYARP_WIFI */ -+ + nla_total_size(1) /* IFLA_BRPORT_VLAN_TUNNEL */ -++ + nla_total_size(1) /* IFLA_BRPORT_ISOLATED */ -+ + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_ROOT_ID */ -+ + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_BRIDGE_ID */ -+ + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_DESIGNATED_PORT */ -+@@ -208,7 +209,8 @@ static int br_port_fill_attrs(struct sk_ -+ p->topology_change_ack) || -+ nla_put_u8(skb, IFLA_BRPORT_CONFIG_PENDING, p->config_pending) || -+ nla_put_u8(skb, IFLA_BRPORT_VLAN_TUNNEL, !!(p->flags & -+- BR_VLAN_TUNNEL))) -++ BR_VLAN_TUNNEL)) || -++ nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED))) -+ return -EMSGSIZE; -+ -+ timerval = br_timer_value(&p->message_age_timer); -+@@ -637,6 +639,7 @@ static const struct nla_policy br_port_p -+ [IFLA_BRPORT_MCAST_TO_UCAST] = { .type = NLA_U8 }, -+ [IFLA_BRPORT_MCAST_FLOOD] = { .type = NLA_U8 }, -+ [IFLA_BRPORT_BCAST_FLOOD] = { .type = NLA_U8 }, -++ [IFLA_BRPORT_ISOLATED] = { .type = NLA_U8 }, -+ }; -+ -+ /* Change the state of the port and notify spanning tree */ -+@@ -773,6 +776,11 @@ static int br_setport(struct net_bridge_ -+ return err; -+ } -+ #endif -++ -++ err = br_set_port_flag(p, tb, IFLA_BRPORT_ISOLATED, BR_ISOLATED); -++ if (err) -++ return err; -++ -+ br_port_flags_change(p, old_flags ^ p->flags); -+ return 0; -+ } -+--- a/net/bridge/br_private.h -++++ b/net/bridge/br_private.h -+@@ -407,6 +407,7 @@ struct br_input_skb_cb { -+ #endif -+ -+ bool proxyarp_replied; -++ bool src_port_isolated; -+ -+ #ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ bool vlan_filtered; -+@@ -554,6 +555,14 @@ int br_forward_finish(struct net *net, s -+ void br_flood(struct net_bridge *br, struct sk_buff *skb, -+ enum br_pkt_type pkt_type, bool local_rcv, bool local_orig); -+ -++/* return true if both source port and dest port are isolated */ -++static inline bool br_skb_isolated(const struct net_bridge_port *to, -++ const struct sk_buff *skb) -++{ -++ return BR_INPUT_SKB_CB(skb)->src_port_isolated && -++ (to->flags & BR_ISOLATED); -++} -++ -+ /* br_if.c */ -+ void br_port_carrier_check(struct net_bridge_port *p); -+ int br_add_bridge(struct net *net, const char *name); -+--- a/net/bridge/br_sysfs_if.c -++++ b/net/bridge/br_sysfs_if.c -+@@ -174,6 +174,7 @@ BRPORT_ATTR_FLAG(proxyarp, BR_PROXYARP); -+ BRPORT_ATTR_FLAG(proxyarp_wifi, BR_PROXYARP_WIFI); -+ BRPORT_ATTR_FLAG(multicast_flood, BR_MCAST_FLOOD); -+ BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD); -++BRPORT_ATTR_FLAG(isolated, BR_ISOLATED); -+ -+ #ifdef CONFIG_BRIDGE_IGMP_SNOOPING -+ static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) -+@@ -223,6 +224,7 @@ static const struct brport_attribute *br -+ &brport_attr_proxyarp_wifi, -+ &brport_attr_multicast_flood, -+ &brport_attr_broadcast_flood, -++ &brport_attr_isolated, -+ NULL -+ }; -+ -+--- a/include/linux/if_bridge.h -++++ b/include/linux/if_bridge.h -+@@ -49,6 +49,7 @@ struct br_ip_list { -+ #define BR_MULTICAST_TO_UNICAST BIT(12) -+ #define BR_VLAN_TUNNEL BIT(13) -+ #define BR_BCAST_FLOOD BIT(14) -++#define BR_ISOLATED BIT(16) -+ -+ #define BR_DEFAULT_AGEING_TIME (300 * HZ) -+ -diff --git a/target/linux/generic/backport-4.14/095-Allow-class-e-address-assignment-via-ifconfig-ioctl.patch b/target/linux/generic/backport-4.14/095-Allow-class-e-address-assignment-via-ifconfig-ioctl.patch -new file mode 100644 -index 0000000000..e2698dd02e ---- /dev/null -+++ b/target/linux/generic/backport-4.14/095-Allow-class-e-address-assignment-via-ifconfig-ioctl.patch -@@ -0,0 +1,79 @@ -+From 46bf067870156abd61fe24d14c2486d15b8b502c Mon Sep 17 00:00:00 2001 -+From: Dave Taht -+Date: Fri, 14 Dec 2018 18:38:40 +0000 -+Subject: [PATCH 1/1] Allow class-e address assignment in ifconfig and early -+ boot -+ -+While the linux kernel became mostly "class-e clean" a decade ago, -+and most distributions long ago switched to the iproute2 suite -+of utilities, which allow class-e (240.0.0.0/4) address assignment, -+distributions relying on busybox, toybox and other forms of -+ifconfig cannot assign class-e addresses without this kernel patch. -+ -+With this patch, also, a boot command line on these addresses is feasible: -+(ip=248.0.1.2::248.0.1.1:255.255.255.0). -+ -+While CIDR has been obsolete for 2 decades, and a survey of all the -+userspace open source code in the world shows most IN_whatever macros -+are also obsolete... rather than obsolete CIDR from this ioctl entirely, -+this patch merely enables class-e assignment, sanely. -+ -+H/T to Vince Fuller and his original patch here: -+ https://lkml.org/lkml/2008/1/7/370 -+ -+Signed-off-by: Dave Taht -+Reviewed-by: John Gilmore -+--- -+ include/uapi/linux/in.h | 8 ++++++-- -+ net/ipv4/devinet.c | 4 +++- -+ net/ipv4/ipconfig.c | 2 ++ -+ 3 files changed, 11 insertions(+), 3 deletions(-) -+ -+--- a/include/uapi/linux/in.h -++++ b/include/uapi/linux/in.h -+@@ -268,8 +268,12 @@ struct sockaddr_in { -+ #define IN_MULTICAST(a) IN_CLASSD(a) -+ #define IN_MULTICAST_NET 0xF0000000 -+ -+-#define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000) -+-#define IN_BADCLASS(a) IN_EXPERIMENTAL((a)) -++#define IN_BADCLASS(a) (((long int) (a) ) == (long int)0xffffffff) -++#define IN_EXPERIMENTAL(a) IN_BADCLASS((a)) -++ -++#define IN_CLASSE(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000) -++#define IN_CLASSE_NET 0xffffffff -++#define IN_CLASSE_NSHIFT 0 -+ -+ /* Address to accept any incoming messages. */ -+ #define INADDR_ANY ((unsigned long int) 0x00000000) -+--- a/net/ipv4/devinet.c -++++ b/net/ipv4/devinet.c -+@@ -935,7 +935,7 @@ static int inet_abc_len(__be32 addr) -+ { -+ int rc = -1; /* Something else, probably a multicast. */ -+ -+- if (ipv4_is_zeronet(addr)) -++ if (ipv4_is_zeronet(addr) || ipv4_is_lbcast(addr)) -+ rc = 0; -+ else { -+ __u32 haddr = ntohl(addr); -+@@ -946,6 +946,8 @@ static int inet_abc_len(__be32 addr) -+ rc = 16; -+ else if (IN_CLASSC(haddr)) -+ rc = 24; -++ else if (IN_CLASSE(haddr)) -++ rc = 32; -+ } -+ -+ return rc; -+--- a/net/ipv4/ipconfig.c -++++ b/net/ipv4/ipconfig.c -+@@ -457,6 +457,8 @@ static int __init ic_defaults(void) -+ ic_netmask = htonl(IN_CLASSB_NET); -+ else if (IN_CLASSC(ntohl(ic_myaddr))) -+ ic_netmask = htonl(IN_CLASSC_NET); -++ else if (IN_CLASSE(ntohl(ic_myaddr))) -++ ic_netmask = htonl(IN_CLASSE_NET); -+ else { -+ pr_err("IP-Config: Unable to guess netmask for address %pI4\n", -+ &ic_myaddr); -diff --git a/target/linux/generic/backport-4.14/101-arm-cns3xxx-use-actual-size-reads-for-PCIe.patch b/target/linux/generic/backport-4.14/101-arm-cns3xxx-use-actual-size-reads-for-PCIe.patch -new file mode 100644 -index 0000000000..2b3384391a ---- /dev/null -+++ b/target/linux/generic/backport-4.14/101-arm-cns3xxx-use-actual-size-reads-for-PCIe.patch -@@ -0,0 +1,46 @@ -+From 4cc30de79d293f1e8c5f50ae3a9c005def9564a0 Mon Sep 17 00:00:00 2001 -+From: Koen Vandeputte -+Date: Mon, 7 Jan 2019 14:14:27 +0100 -+Subject: [PATCH 2/2] arm: cns3xxx: use actual size reads for PCIe -+ -+commit 802b7c06adc7 ("ARM: cns3xxx: Convert PCI to use generic config accessors") -+reimplemented cns3xxx_pci_read_config() using pci_generic_config_read32(), -+which preserved the property of only doing 32-bit reads. -+ -+It also replaced cns3xxx_pci_write_config() with pci_generic_config_write(), -+so it changed writes from always being 32 bits to being the actual size, -+which works just fine. -+ -+Due to: -+- The documentation does not mention that only 32 bit access is allowed. -+- Writes are already executed using the actual size -+- Extensive testing shows that 8b, 16b and 32b reads work as intended -+ -+It makes perfectly sense to also swap 32 bit reading in favor of actual size. -+ -+Fixes: 802b7c06adc7 ("ARM: cns3xxx: Convert PCI to use generic config accessors") -+Suggested-by: Bjorn Helgaas -+Signed-off-by: Koen Vandeputte -+CC: Arnd Bergmann -+CC: Krzysztof Halasa -+CC: Olof Johansson -+CC: Robin Leblon -+CC: Rob Herring -+CC: Russell King -+CC: Tim Harvey -+CC: stable@vger.kernel.org # v4.0+ -+--- -+ arch/arm/mach-cns3xxx/pcie.c | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/arch/arm/mach-cns3xxx/pcie.c -++++ b/arch/arm/mach-cns3xxx/pcie.c -+@@ -93,7 +93,7 @@ static int cns3xxx_pci_read_config(struc -+ u32 mask = (0x1ull << (size * 8)) - 1; -+ int shift = (where % 4) * 8; -+ -+- ret = pci_generic_config_read32(bus, devfn, where, size, val); -++ ret = pci_generic_config_read(bus, devfn, where, size, val); -+ -+ if (ret == PCIBIOS_SUCCESSFUL && !bus->number && !devfn && -+ (where & 0xffc) == PCI_CLASS_REVISION) -diff --git a/target/linux/generic/backport-4.14/183-net-qmi_wwan-add-Wistron-Neweb-D19Q1.patch b/target/linux/generic/backport-4.14/183-net-qmi_wwan-add-Wistron-Neweb-D19Q1.patch -new file mode 100644 -index 0000000000..078c9aaa50 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/183-net-qmi_wwan-add-Wistron-Neweb-D19Q1.patch -@@ -0,0 +1,54 @@ -+From eb5a26bcaddb35fd42a978ad37831e58b1118853 Mon Sep 17 00:00:00 2001 -+From: Pawel Dembicki -+Date: Tue, 17 Apr 2018 19:53:59 +0200 -+Subject: [PATCH] net: qmi_wwan: add Wistron Neweb D19Q1 -+ -+This modem is embedded on dlink dwr-960 router. -+The oem configuration states: -+ -+T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 -+D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 -+P: Vendor=1435 ProdID=d191 Rev=ff.ff -+S: Manufacturer=Android -+S: Product=Android -+S: SerialNumber=0123456789ABCDEF -+C:* #Ifs= 6 Cfg#= 1 Atr=80 MxPwr=500mA -+I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) -+E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms -+E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms -+I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) -+E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms -+E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms -+I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none) -+E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms -+E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms -+E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms -+I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none) -+E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms -+E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms -+E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms -+I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan -+E: Ad=88(I) Atr=03(Int.) MxPS= 8 Ivl=32ms -+E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms -+E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms -+I:* If#= 5 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none) -+E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms -+E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=125us -+ -+Tested on openwrt distribution -+ -+Signed-off-by: Pawel Dembicki -+--- -+ drivers/net/usb/qmi_wwan.c | 1 + -+ 1 file changed, 1 insertion(+) -+ -+--- a/drivers/net/usb/qmi_wwan.c -++++ b/drivers/net/usb/qmi_wwan.c -+@@ -1138,6 +1138,7 @@ static const struct usb_device_id produc -+ {QMI_FIXED_INTF(0x1435, 0xd181, 3)}, /* Wistron NeWeb D18Q1 */ -+ {QMI_FIXED_INTF(0x1435, 0xd181, 4)}, /* Wistron NeWeb D18Q1 */ -+ {QMI_FIXED_INTF(0x1435, 0xd181, 5)}, /* Wistron NeWeb D18Q1 */ -++ {QMI_FIXED_INTF(0x1435, 0xd191, 4)}, /* Wistron NeWeb D19Q1 */ -+ {QMI_QUIRK_SET_DTR(0x1508, 0x1001, 4)}, /* Fibocom NL668 series */ -+ {QMI_FIXED_INTF(0x1690, 0x7588, 4)}, /* ASKEY WWHC050 */ -+ {QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */ -diff --git a/target/linux/generic/backport-4.14/270-batman-adv-Let-packet.h-include-its-headers-directly.patch b/target/linux/generic/backport-4.14/270-batman-adv-Let-packet.h-include-its-headers-directly.patch -new file mode 100644 -index 0000000000..9b3dfc1fd3 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/270-batman-adv-Let-packet.h-include-its-headers-directly.patch -@@ -0,0 +1,36 @@ -+From: Sven Eckelmann -+Date: Thu, 21 Dec 2017 10:17:38 +0100 -+Subject: [PATCH] batman-adv: Let packet.h include its headers directly -+ -+The headers used by packet.h should also be included by it directly. main.h -+is currently dealing with it in batman-adv, but this will no longer work -+when this header is moved to include/uapi/linux/. -+ -+Signed-off-by: Sven Eckelmann -+Signed-off-by: David S. Miller -+--- -+ -+--- a/net/batman-adv/main.h -++++ b/net/batman-adv/main.h -+@@ -184,10 +184,8 @@ enum batadv_uev_type { -+ -+ /* Kernel headers */ -+ -+-#include /* for packet.h */ -+ #include -+ #include -+-#include /* for packet.h */ -+ #include -+ #include -+ #include -+--- a/net/batman-adv/packet.h -++++ b/net/batman-adv/packet.h -+@@ -19,6 +19,8 @@ -+ #define _NET_BATMAN_ADV_PACKET_H_ -+ -+ #include -++#include -++#include -+ #include -+ -+ #define batadv_tp_is_error(n) ((u8)(n) > 127 ? 1 : 0) -diff --git a/target/linux/generic/backport-4.14/271-batman-adv-Remove-usage-of-BIT-x-in-packet.h.patch b/target/linux/generic/backport-4.14/271-batman-adv-Remove-usage-of-BIT-x-in-packet.h.patch -new file mode 100644 -index 0000000000..5466d234d8 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/271-batman-adv-Remove-usage-of-BIT-x-in-packet.h.patch -@@ -0,0 +1,72 @@ -+From: Sven Eckelmann -+Date: Thu, 21 Dec 2017 10:17:39 +0100 -+Subject: [PATCH] batman-adv: Remove usage of BIT(x) in packet.h -+ -+The BIT(x) macro is no longer available for uapi headers because it is -+defined outside of it (linux/bitops.h). The use of it must therefore be -+avoided and replaced by an appropriate other representation. -+ -+Signed-off-by: Sven Eckelmann -+Signed-off-by: David S. Miller -+--- -+ -+--- a/net/batman-adv/packet.h -++++ b/net/batman-adv/packet.h -+@@ -19,7 +19,6 @@ -+ #define _NET_BATMAN_ADV_PACKET_H_ -+ -+ #include -+-#include -+ #include -+ #include -+ -+@@ -85,9 +84,9 @@ enum batadv_subtype { -+ * one hop neighbor on the interface where it was originally received. -+ */ -+ enum batadv_iv_flags { -+- BATADV_NOT_BEST_NEXT_HOP = BIT(0), -+- BATADV_PRIMARIES_FIRST_HOP = BIT(1), -+- BATADV_DIRECTLINK = BIT(2), -++ BATADV_NOT_BEST_NEXT_HOP = 1UL << 0, -++ BATADV_PRIMARIES_FIRST_HOP = 1UL << 1, -++ BATADV_DIRECTLINK = 1UL << 2, -+ }; -+ -+ /* ICMP message types */ -+@@ -108,9 +107,9 @@ enum batadv_icmp_packettype { -+ * @BATADV_MCAST_WANT_ALL_IPV6: we want all IPv6 multicast packets -+ */ -+ enum batadv_mcast_flags { -+- BATADV_MCAST_WANT_ALL_UNSNOOPABLES = BIT(0), -+- BATADV_MCAST_WANT_ALL_IPV4 = BIT(1), -+- BATADV_MCAST_WANT_ALL_IPV6 = BIT(2), -++ BATADV_MCAST_WANT_ALL_UNSNOOPABLES = 1UL << 0, -++ BATADV_MCAST_WANT_ALL_IPV4 = 1UL << 1, -++ BATADV_MCAST_WANT_ALL_IPV6 = 1UL << 2, -+ }; -+ -+ /* tt data subtypes */ -+@@ -124,10 +123,10 @@ enum batadv_mcast_flags { -+ * @BATADV_TT_FULL_TABLE: contains full table to replace existing table -+ */ -+ enum batadv_tt_data_flags { -+- BATADV_TT_OGM_DIFF = BIT(0), -+- BATADV_TT_REQUEST = BIT(1), -+- BATADV_TT_RESPONSE = BIT(2), -+- BATADV_TT_FULL_TABLE = BIT(4), -++ BATADV_TT_OGM_DIFF = 1UL << 0, -++ BATADV_TT_REQUEST = 1UL << 1, -++ BATADV_TT_RESPONSE = 1UL << 2, -++ BATADV_TT_FULL_TABLE = 1UL << 4, -+ }; -+ -+ /** -+@@ -135,7 +134,7 @@ enum batadv_tt_data_flags { -+ * @BATADV_VLAN_HAS_TAG: whether the field contains a valid vlan tag or not -+ */ -+ enum batadv_vlan_flags { -+- BATADV_VLAN_HAS_TAG = BIT(15), -++ BATADV_VLAN_HAS_TAG = 1UL << 15, -+ }; -+ -+ /* claim frame types for the bridge loop avoidance */ -diff --git a/target/linux/generic/backport-4.14/272-batman-adv-Remove-kernel-fixed-width-types-in-packet.patch b/target/linux/generic/backport-4.14/272-batman-adv-Remove-kernel-fixed-width-types-in-packet.patch -new file mode 100644 -index 0000000000..c46a8f74c7 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/272-batman-adv-Remove-kernel-fixed-width-types-in-packet.patch -@@ -0,0 +1,386 @@ -+From: Sven Eckelmann -+Date: Thu, 21 Dec 2017 10:17:40 +0100 -+Subject: [PATCH] batman-adv: Remove kernel fixed width types in packet.h -+ -+The uapi headers use the __u8/__u16/... version of the fixed width types -+instead of u8/u16/... The use of the latter must be avoided before -+packet.h is copied to include/uapi/linux/. -+ -+Signed-off-by: Sven Eckelmann -+Signed-off-by: David S. Miller -+--- -+ -+--- a/net/batman-adv/packet.h -++++ b/net/batman-adv/packet.h -+@@ -22,7 +22,7 @@ -+ #include -+ #include -+ -+-#define batadv_tp_is_error(n) ((u8)(n) > 127 ? 1 : 0) -++#define batadv_tp_is_error(n) ((__u8)(n) > 127 ? 1 : 0) -+ -+ /** -+ * enum batadv_packettype - types for batman-adv encapsulated packets -+@@ -169,8 +169,8 @@ enum batadv_tvlv_type { -+ * transport the claim type and the group id -+ */ -+ struct batadv_bla_claim_dst { -+- u8 magic[3]; /* FF:43:05 */ -+- u8 type; /* bla_claimframe */ -++ __u8 magic[3]; /* FF:43:05 */ -++ __u8 type; /* bla_claimframe */ -+ __be16 group; /* group id */ -+ }; -+ -+@@ -190,15 +190,15 @@ struct batadv_bla_claim_dst { -+ * @tvlv_len: length of tvlv data following the ogm header -+ */ -+ struct batadv_ogm_packet { -+- u8 packet_type; -+- u8 version; -+- u8 ttl; -+- u8 flags; -++ __u8 packet_type; -++ __u8 version; -++ __u8 ttl; -++ __u8 flags; -+ __be32 seqno; -+- u8 orig[ETH_ALEN]; -+- u8 prev_sender[ETH_ALEN]; -+- u8 reserved; -+- u8 tq; -++ __u8 orig[ETH_ALEN]; -++ __u8 prev_sender[ETH_ALEN]; -++ __u8 reserved; -++ __u8 tq; -+ __be16 tvlv_len; -+ /* __packed is not needed as the struct size is divisible by 4, -+ * and the largest data type in this struct has a size of 4. -+@@ -219,12 +219,12 @@ struct batadv_ogm_packet { -+ * @throughput: the currently flooded path throughput -+ */ -+ struct batadv_ogm2_packet { -+- u8 packet_type; -+- u8 version; -+- u8 ttl; -+- u8 flags; -++ __u8 packet_type; -++ __u8 version; -++ __u8 ttl; -++ __u8 flags; -+ __be32 seqno; -+- u8 orig[ETH_ALEN]; -++ __u8 orig[ETH_ALEN]; -+ __be16 tvlv_len; -+ __be32 throughput; -+ /* __packed is not needed as the struct size is divisible by 4, -+@@ -243,9 +243,9 @@ struct batadv_ogm2_packet { -+ * @elp_interval: currently used ELP sending interval in ms -+ */ -+ struct batadv_elp_packet { -+- u8 packet_type; -+- u8 version; -+- u8 orig[ETH_ALEN]; -++ __u8 packet_type; -++ __u8 version; -++ __u8 orig[ETH_ALEN]; -+ __be32 seqno; -+ __be32 elp_interval; -+ }; -+@@ -268,14 +268,14 @@ struct batadv_elp_packet { -+ * members are padded the same way as they are in real packets. -+ */ -+ struct batadv_icmp_header { -+- u8 packet_type; -+- u8 version; -+- u8 ttl; -+- u8 msg_type; /* see ICMP message types above */ -+- u8 dst[ETH_ALEN]; -+- u8 orig[ETH_ALEN]; -+- u8 uid; -+- u8 align[3]; -++ __u8 packet_type; -++ __u8 version; -++ __u8 ttl; -++ __u8 msg_type; /* see ICMP message types above */ -++ __u8 dst[ETH_ALEN]; -++ __u8 orig[ETH_ALEN]; -++ __u8 uid; -++ __u8 align[3]; -+ }; -+ -+ /** -+@@ -291,14 +291,14 @@ struct batadv_icmp_header { -+ * @seqno: ICMP sequence number -+ */ -+ struct batadv_icmp_packet { -+- u8 packet_type; -+- u8 version; -+- u8 ttl; -+- u8 msg_type; /* see ICMP message types above */ -+- u8 dst[ETH_ALEN]; -+- u8 orig[ETH_ALEN]; -+- u8 uid; -+- u8 reserved; -++ __u8 packet_type; -++ __u8 version; -++ __u8 ttl; -++ __u8 msg_type; /* see ICMP message types above */ -++ __u8 dst[ETH_ALEN]; -++ __u8 orig[ETH_ALEN]; -++ __u8 uid; -++ __u8 reserved; -+ __be16 seqno; -+ }; -+ -+@@ -320,15 +320,15 @@ struct batadv_icmp_packet { -+ * store it using network order -+ */ -+ struct batadv_icmp_tp_packet { -+- u8 packet_type; -+- u8 version; -+- u8 ttl; -+- u8 msg_type; /* see ICMP message types above */ -+- u8 dst[ETH_ALEN]; -+- u8 orig[ETH_ALEN]; -+- u8 uid; -+- u8 subtype; -+- u8 session[2]; -++ __u8 packet_type; -++ __u8 version; -++ __u8 ttl; -++ __u8 msg_type; /* see ICMP message types above */ -++ __u8 dst[ETH_ALEN]; -++ __u8 orig[ETH_ALEN]; -++ __u8 uid; -++ __u8 subtype; -++ __u8 session[2]; -+ __be32 seqno; -+ __be32 timestamp; -+ }; -+@@ -359,16 +359,16 @@ enum batadv_icmp_tp_subtype { -+ * @rr: route record array -+ */ -+ struct batadv_icmp_packet_rr { -+- u8 packet_type; -+- u8 version; -+- u8 ttl; -+- u8 msg_type; /* see ICMP message types above */ -+- u8 dst[ETH_ALEN]; -+- u8 orig[ETH_ALEN]; -+- u8 uid; -+- u8 rr_cur; -++ __u8 packet_type; -++ __u8 version; -++ __u8 ttl; -++ __u8 msg_type; /* see ICMP message types above */ -++ __u8 dst[ETH_ALEN]; -++ __u8 orig[ETH_ALEN]; -++ __u8 uid; -++ __u8 rr_cur; -+ __be16 seqno; -+- u8 rr[BATADV_RR_LEN][ETH_ALEN]; -++ __u8 rr[BATADV_RR_LEN][ETH_ALEN]; -+ }; -+ -+ #define BATADV_ICMP_MAX_PACKET_SIZE sizeof(struct batadv_icmp_packet_rr) -+@@ -394,11 +394,11 @@ struct batadv_icmp_packet_rr { -+ * @dest: originator destination of the unicast packet -+ */ -+ struct batadv_unicast_packet { -+- u8 packet_type; -+- u8 version; -+- u8 ttl; -+- u8 ttvn; /* destination translation table version number */ -+- u8 dest[ETH_ALEN]; -++ __u8 packet_type; -++ __u8 version; -++ __u8 ttl; -++ __u8 ttvn; /* destination translation table version number */ -++ __u8 dest[ETH_ALEN]; -+ /* "4 bytes boundary + 2 bytes" long to make the payload after the -+ * following ethernet header again 4 bytes boundary aligned -+ */ -+@@ -413,9 +413,9 @@ struct batadv_unicast_packet { -+ */ -+ struct batadv_unicast_4addr_packet { -+ struct batadv_unicast_packet u; -+- u8 src[ETH_ALEN]; -+- u8 subtype; -+- u8 reserved; -++ __u8 src[ETH_ALEN]; -++ __u8 subtype; -++ __u8 reserved; -+ /* "4 bytes boundary + 2 bytes" long to make the payload after the -+ * following ethernet header again 4 bytes boundary aligned -+ */ -+@@ -435,22 +435,22 @@ struct batadv_unicast_4addr_packet { -+ * @total_size: size of the merged packet -+ */ -+ struct batadv_frag_packet { -+- u8 packet_type; -+- u8 version; /* batman version field */ -+- u8 ttl; -++ __u8 packet_type; -++ __u8 version; /* batman version field */ -++ __u8 ttl; -+ #if defined(__BIG_ENDIAN_BITFIELD) -+- u8 no:4; -+- u8 priority:3; -+- u8 reserved:1; -++ __u8 no:4; -++ __u8 priority:3; -++ __u8 reserved:1; -+ #elif defined(__LITTLE_ENDIAN_BITFIELD) -+- u8 reserved:1; -+- u8 priority:3; -+- u8 no:4; -++ __u8 reserved:1; -++ __u8 priority:3; -++ __u8 no:4; -+ #else -+ #error "unknown bitfield endianness" -+ #endif -+- u8 dest[ETH_ALEN]; -+- u8 orig[ETH_ALEN]; -++ __u8 dest[ETH_ALEN]; -++ __u8 orig[ETH_ALEN]; -+ __be16 seqno; -+ __be16 total_size; -+ }; -+@@ -465,12 +465,12 @@ struct batadv_frag_packet { -+ * @orig: originator of the broadcast packet -+ */ -+ struct batadv_bcast_packet { -+- u8 packet_type; -+- u8 version; /* batman version field */ -+- u8 ttl; -+- u8 reserved; -++ __u8 packet_type; -++ __u8 version; /* batman version field */ -++ __u8 ttl; -++ __u8 reserved; -+ __be32 seqno; -+- u8 orig[ETH_ALEN]; -++ __u8 orig[ETH_ALEN]; -+ /* "4 bytes boundary + 2 bytes" long to make the payload after the -+ * following ethernet header again 4 bytes boundary aligned -+ */ -+@@ -494,19 +494,19 @@ struct batadv_bcast_packet { -+ * @coded_len: length of network coded part of the payload -+ */ -+ struct batadv_coded_packet { -+- u8 packet_type; -+- u8 version; /* batman version field */ -+- u8 ttl; -+- u8 first_ttvn; -+- /* u8 first_dest[ETH_ALEN]; - saved in mac header destination */ -+- u8 first_source[ETH_ALEN]; -+- u8 first_orig_dest[ETH_ALEN]; -++ __u8 packet_type; -++ __u8 version; /* batman version field */ -++ __u8 ttl; -++ __u8 first_ttvn; -++ /* __u8 first_dest[ETH_ALEN]; - saved in mac header destination */ -++ __u8 first_source[ETH_ALEN]; -++ __u8 first_orig_dest[ETH_ALEN]; -+ __be32 first_crc; -+- u8 second_ttl; -+- u8 second_ttvn; -+- u8 second_dest[ETH_ALEN]; -+- u8 second_source[ETH_ALEN]; -+- u8 second_orig_dest[ETH_ALEN]; -++ __u8 second_ttl; -++ __u8 second_ttvn; -++ __u8 second_dest[ETH_ALEN]; -++ __u8 second_source[ETH_ALEN]; -++ __u8 second_orig_dest[ETH_ALEN]; -+ __be32 second_crc; -+ __be16 coded_len; -+ }; -+@@ -525,14 +525,14 @@ struct batadv_coded_packet { -+ * @align: 2 bytes to align the header to a 4 byte boundary -+ */ -+ struct batadv_unicast_tvlv_packet { -+- u8 packet_type; -+- u8 version; /* batman version field */ -+- u8 ttl; -+- u8 reserved; -+- u8 dst[ETH_ALEN]; -+- u8 src[ETH_ALEN]; -++ __u8 packet_type; -++ __u8 version; /* batman version field */ -++ __u8 ttl; -++ __u8 reserved; -++ __u8 dst[ETH_ALEN]; -++ __u8 src[ETH_ALEN]; -+ __be16 tvlv_len; -+- u16 align; -++ __u16 align; -+ }; -+ -+ /** -+@@ -542,8 +542,8 @@ struct batadv_unicast_tvlv_packet { -+ * @len: tvlv container length -+ */ -+ struct batadv_tvlv_hdr { -+- u8 type; -+- u8 version; -++ __u8 type; -++ __u8 version; -+ __be16 len; -+ }; -+ -+@@ -566,8 +566,8 @@ struct batadv_tvlv_gateway_data { -+ * one batadv_tvlv_tt_vlan_data object per announced vlan -+ */ -+ struct batadv_tvlv_tt_data { -+- u8 flags; -+- u8 ttvn; -++ __u8 flags; -++ __u8 ttvn; -+ __be16 num_vlan; -+ }; -+ -+@@ -581,7 +581,7 @@ struct batadv_tvlv_tt_data { -+ struct batadv_tvlv_tt_vlan_data { -+ __be32 crc; -+ __be16 vid; -+- u16 reserved; -++ __u16 reserved; -+ }; -+ -+ /** -+@@ -593,9 +593,9 @@ struct batadv_tvlv_tt_vlan_data { -+ * @vid: VLAN identifier -+ */ -+ struct batadv_tvlv_tt_change { -+- u8 flags; -+- u8 reserved[3]; -+- u8 addr[ETH_ALEN]; -++ __u8 flags; -++ __u8 reserved[3]; -++ __u8 addr[ETH_ALEN]; -+ __be16 vid; -+ }; -+ -+@@ -605,7 +605,7 @@ struct batadv_tvlv_tt_change { -+ * @vid: VLAN identifier -+ */ -+ struct batadv_tvlv_roam_adv { -+- u8 client[ETH_ALEN]; -++ __u8 client[ETH_ALEN]; -+ __be16 vid; -+ }; -+ -+@@ -615,8 +615,8 @@ struct batadv_tvlv_roam_adv { -+ * @reserved: reserved field -+ */ -+ struct batadv_tvlv_mcast_data { -+- u8 flags; -+- u8 reserved[3]; -++ __u8 flags; -++ __u8 reserved[3]; -+ }; -+ -+ #endif /* _NET_BATMAN_ADV_PACKET_H_ */ -diff --git a/target/linux/generic/backport-4.14/273-batman-adv-Convert-packet.h-to-uapi-header.patch b/target/linux/generic/backport-4.14/273-batman-adv-Convert-packet.h-to-uapi-header.patch -new file mode 100644 -index 0000000000..a9f744fd13 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/273-batman-adv-Convert-packet.h-to-uapi-header.patch -@@ -0,0 +1,1665 @@ -+From: Sven Eckelmann -+Date: Thu, 21 Dec 2017 10:17:41 +0100 -+Subject: [PATCH] batman-adv: Convert packet.h to uapi header -+ -+The header file is used by different userspace programs to inject packets -+or to decode sniffed packets. It should therefore be available to them as -+userspace header. -+ -+Also other components in the kernel (like the flow dissector) require -+access to the packet definitions to be able to decode ETH_P_BATMAN ethernet -+packets. -+ -+Signed-off-by: Sven Eckelmann -+Signed-off-by: David S. Miller -+--- -+ rename net/batman-adv/packet.h => include/uapi/linux/batadv_packet.h (99%) -+ -+--- a/MAINTAINERS -++++ b/MAINTAINERS -+@@ -2551,6 +2551,7 @@ S: Maintained -+ F: Documentation/ABI/testing/sysfs-class-net-batman-adv -+ F: Documentation/ABI/testing/sysfs-class-net-mesh -+ F: Documentation/networking/batman-adv.rst -++F: include/uapi/linux/batadv_packet.h -+ F: include/uapi/linux/batman_adv.h -+ F: net/batman-adv/ -+ -+--- a/net/batman-adv/bat_iv_ogm.c -++++ b/net/batman-adv/bat_iv_ogm.c -+@@ -52,6 +52,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ -+ #include "bat_algo.h" -+@@ -63,7 +64,6 @@ -+ #include "netlink.h" -+ #include "network-coding.h" -+ #include "originator.h" -+-#include "packet.h" -+ #include "routing.h" -+ #include "send.h" -+ #include "translation-table.h" -+--- a/net/batman-adv/bat_v.c -++++ b/net/batman-adv/bat_v.c -+@@ -36,6 +36,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ -+ #include "bat_algo.h" -+@@ -48,7 +49,6 @@ -+ #include "log.h" -+ #include "netlink.h" -+ #include "originator.h" -+-#include "packet.h" -+ -+ struct sk_buff; -+ -+--- a/net/batman-adv/bat_v_elp.c -++++ b/net/batman-adv/bat_v_elp.c -+@@ -41,13 +41,13 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "bat_algo.h" -+ #include "bat_v_ogm.h" -+ #include "hard-interface.h" -+ #include "log.h" -+ #include "originator.h" -+-#include "packet.h" -+ #include "routing.h" -+ #include "send.h" -+ -+--- a/net/batman-adv/bat_v_ogm.c -++++ b/net/batman-adv/bat_v_ogm.c -+@@ -40,13 +40,13 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "bat_algo.h" -+ #include "hard-interface.h" -+ #include "hash.h" -+ #include "log.h" -+ #include "originator.h" -+-#include "packet.h" -+ #include "routing.h" -+ #include "send.h" -+ #include "translation-table.h" -+--- a/net/batman-adv/bridge_loop_avoidance.c -++++ b/net/batman-adv/bridge_loop_avoidance.c -+@@ -49,6 +49,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ -+ #include "hard-interface.h" -+@@ -56,7 +57,6 @@ -+ #include "log.h" -+ #include "netlink.h" -+ #include "originator.h" -+-#include "packet.h" -+ #include "soft-interface.h" -+ #include "sysfs.h" -+ #include "translation-table.h" -+--- a/net/batman-adv/distributed-arp-table.h -++++ b/net/batman-adv/distributed-arp-table.h -+@@ -23,9 +23,9 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "originator.h" -+-#include "packet.h" -+ -+ struct seq_file; -+ struct sk_buff; -+--- a/net/batman-adv/fragmentation.c -++++ b/net/batman-adv/fragmentation.c -+@@ -32,10 +32,10 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "hard-interface.h" -+ #include "originator.h" -+-#include "packet.h" -+ #include "routing.h" -+ #include "send.h" -+ #include "soft-interface.h" -+--- a/net/batman-adv/gateway_client.c -++++ b/net/batman-adv/gateway_client.c -+@@ -43,6 +43,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ -+ #include "gateway_common.h" -+@@ -50,7 +51,6 @@ -+ #include "log.h" -+ #include "netlink.h" -+ #include "originator.h" -+-#include "packet.h" -+ #include "routing.h" -+ #include "soft-interface.h" -+ #include "sysfs.h" -+--- a/net/batman-adv/gateway_common.c -++++ b/net/batman-adv/gateway_common.c -+@@ -26,10 +26,10 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "gateway_client.h" -+ #include "log.h" -+-#include "packet.h" -+ #include "tvlv.h" -+ -+ /** -+--- a/net/batman-adv/hard-interface.c -++++ b/net/batman-adv/hard-interface.c -+@@ -37,6 +37,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "bat_v.h" -+ #include "bridge_loop_avoidance.h" -+@@ -45,7 +46,6 @@ -+ #include "gateway_client.h" -+ #include "log.h" -+ #include "originator.h" -+-#include "packet.h" -+ #include "send.h" -+ #include "soft-interface.h" -+ #include "sysfs.h" -+--- a/net/batman-adv/icmp_socket.c -++++ b/net/batman-adv/icmp_socket.c -+@@ -42,11 +42,11 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "hard-interface.h" -+ #include "log.h" -+ #include "originator.h" -+-#include "packet.h" -+ #include "send.h" -+ -+ static struct batadv_socket_client *batadv_socket_client_hash[256]; -+--- a/net/batman-adv/main.c -++++ b/net/batman-adv/main.c -+@@ -45,6 +45,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ -+ #include "bat_algo.h" -+@@ -62,7 +63,6 @@ -+ #include "netlink.h" -+ #include "network-coding.h" -+ #include "originator.h" -+-#include "packet.h" -+ #include "routing.h" -+ #include "send.h" -+ #include "soft-interface.h" -+--- a/net/batman-adv/main.h -++++ b/net/batman-adv/main.h -+@@ -190,8 +190,8 @@ enum batadv_uev_type { -+ #include -+ #include -+ #include -++#include -+ -+-#include "packet.h" -+ #include "types.h" -+ -+ struct net_device; -+--- a/net/batman-adv/multicast.c -++++ b/net/batman-adv/multicast.c -+@@ -54,11 +54,11 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "hard-interface.h" -+ #include "hash.h" -+ #include "log.h" -+-#include "packet.h" -+ #include "translation-table.h" -+ #include "tvlv.h" -+ -+--- a/net/batman-adv/netlink.c -++++ b/net/batman-adv/netlink.c -+@@ -39,6 +39,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ -+ #include "bat_algo.h" -+@@ -46,7 +47,6 @@ -+ #include "gateway_client.h" -+ #include "hard-interface.h" -+ #include "originator.h" -+-#include "packet.h" -+ #include "soft-interface.h" -+ #include "tp_meter.h" -+ #include "translation-table.h" -+--- a/net/batman-adv/network-coding.c -++++ b/net/batman-adv/network-coding.c -+@@ -47,12 +47,12 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "hard-interface.h" -+ #include "hash.h" -+ #include "log.h" -+ #include "originator.h" -+-#include "packet.h" -+ #include "routing.h" -+ #include "send.h" -+ #include "tvlv.h" -+--- a/net/batman-adv/packet.h -++++ /dev/null -+@@ -1,622 +0,0 @@ -+-/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: -+- * -+- * Marek Lindner, Simon Wunderlich -+- * -+- * This program is free software; you can redistribute it and/or -+- * modify it under the terms of version 2 of the GNU General Public -+- * License as published by the Free Software Foundation. -+- * -+- * This program is distributed in the hope that it will be useful, but -+- * WITHOUT ANY WARRANTY; without even the implied warranty of -+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+- * General Public License for more details. -+- * -+- * You should have received a copy of the GNU General Public License -+- * along with this program; if not, see . -+- */ -+- -+-#ifndef _NET_BATMAN_ADV_PACKET_H_ -+-#define _NET_BATMAN_ADV_PACKET_H_ -+- -+-#include -+-#include -+-#include -+- -+-#define batadv_tp_is_error(n) ((__u8)(n) > 127 ? 1 : 0) -+- -+-/** -+- * enum batadv_packettype - types for batman-adv encapsulated packets -+- * @BATADV_IV_OGM: originator messages for B.A.T.M.A.N. IV -+- * @BATADV_BCAST: broadcast packets carrying broadcast payload -+- * @BATADV_CODED: network coded packets -+- * @BATADV_ELP: echo location packets for B.A.T.M.A.N. V -+- * @BATADV_OGM2: originator messages for B.A.T.M.A.N. V -+- * -+- * @BATADV_UNICAST: unicast packets carrying unicast payload traffic -+- * @BATADV_UNICAST_FRAG: unicast packets carrying a fragment of the original -+- * payload packet -+- * @BATADV_UNICAST_4ADDR: unicast packet including the originator address of -+- * the sender -+- * @BATADV_ICMP: unicast packet like IP ICMP used for ping or traceroute -+- * @BATADV_UNICAST_TVLV: unicast packet carrying TVLV containers -+- */ -+-enum batadv_packettype { -+- /* 0x00 - 0x3f: local packets or special rules for handling */ -+- BATADV_IV_OGM = 0x00, -+- BATADV_BCAST = 0x01, -+- BATADV_CODED = 0x02, -+- BATADV_ELP = 0x03, -+- BATADV_OGM2 = 0x04, -+- /* 0x40 - 0x7f: unicast */ -+-#define BATADV_UNICAST_MIN 0x40 -+- BATADV_UNICAST = 0x40, -+- BATADV_UNICAST_FRAG = 0x41, -+- BATADV_UNICAST_4ADDR = 0x42, -+- BATADV_ICMP = 0x43, -+- BATADV_UNICAST_TVLV = 0x44, -+-#define BATADV_UNICAST_MAX 0x7f -+- /* 0x80 - 0xff: reserved */ -+-}; -+- -+-/** -+- * enum batadv_subtype - packet subtype for unicast4addr -+- * @BATADV_P_DATA: user payload -+- * @BATADV_P_DAT_DHT_GET: DHT request message -+- * @BATADV_P_DAT_DHT_PUT: DHT store message -+- * @BATADV_P_DAT_CACHE_REPLY: ARP reply generated by DAT -+- */ -+-enum batadv_subtype { -+- BATADV_P_DATA = 0x01, -+- BATADV_P_DAT_DHT_GET = 0x02, -+- BATADV_P_DAT_DHT_PUT = 0x03, -+- BATADV_P_DAT_CACHE_REPLY = 0x04, -+-}; -+- -+-/* this file is included by batctl which needs these defines */ -+-#define BATADV_COMPAT_VERSION 15 -+- -+-/** -+- * enum batadv_iv_flags - flags used in B.A.T.M.A.N. IV OGM packets -+- * @BATADV_NOT_BEST_NEXT_HOP: flag is set when ogm packet is forwarded and was -+- * previously received from someone else than the best neighbor. -+- * @BATADV_PRIMARIES_FIRST_HOP: flag unused. -+- * @BATADV_DIRECTLINK: flag is for the first hop or if rebroadcasted from a -+- * one hop neighbor on the interface where it was originally received. -+- */ -+-enum batadv_iv_flags { -+- BATADV_NOT_BEST_NEXT_HOP = 1UL << 0, -+- BATADV_PRIMARIES_FIRST_HOP = 1UL << 1, -+- BATADV_DIRECTLINK = 1UL << 2, -+-}; -+- -+-/* ICMP message types */ -+-enum batadv_icmp_packettype { -+- BATADV_ECHO_REPLY = 0, -+- BATADV_DESTINATION_UNREACHABLE = 3, -+- BATADV_ECHO_REQUEST = 8, -+- BATADV_TTL_EXCEEDED = 11, -+- BATADV_PARAMETER_PROBLEM = 12, -+- BATADV_TP = 15, -+-}; -+- -+-/** -+- * enum batadv_mcast_flags - flags for multicast capabilities and settings -+- * @BATADV_MCAST_WANT_ALL_UNSNOOPABLES: we want all packets destined for -+- * 224.0.0.0/24 or ff02::1 -+- * @BATADV_MCAST_WANT_ALL_IPV4: we want all IPv4 multicast packets -+- * @BATADV_MCAST_WANT_ALL_IPV6: we want all IPv6 multicast packets -+- */ -+-enum batadv_mcast_flags { -+- BATADV_MCAST_WANT_ALL_UNSNOOPABLES = 1UL << 0, -+- BATADV_MCAST_WANT_ALL_IPV4 = 1UL << 1, -+- BATADV_MCAST_WANT_ALL_IPV6 = 1UL << 2, -+-}; -+- -+-/* tt data subtypes */ -+-#define BATADV_TT_DATA_TYPE_MASK 0x0F -+- -+-/** -+- * enum batadv_tt_data_flags - flags for tt data tvlv -+- * @BATADV_TT_OGM_DIFF: TT diff propagated through OGM -+- * @BATADV_TT_REQUEST: TT request message -+- * @BATADV_TT_RESPONSE: TT response message -+- * @BATADV_TT_FULL_TABLE: contains full table to replace existing table -+- */ -+-enum batadv_tt_data_flags { -+- BATADV_TT_OGM_DIFF = 1UL << 0, -+- BATADV_TT_REQUEST = 1UL << 1, -+- BATADV_TT_RESPONSE = 1UL << 2, -+- BATADV_TT_FULL_TABLE = 1UL << 4, -+-}; -+- -+-/** -+- * enum batadv_vlan_flags - flags for the four MSB of any vlan ID field -+- * @BATADV_VLAN_HAS_TAG: whether the field contains a valid vlan tag or not -+- */ -+-enum batadv_vlan_flags { -+- BATADV_VLAN_HAS_TAG = 1UL << 15, -+-}; -+- -+-/* claim frame types for the bridge loop avoidance */ -+-enum batadv_bla_claimframe { -+- BATADV_CLAIM_TYPE_CLAIM = 0x00, -+- BATADV_CLAIM_TYPE_UNCLAIM = 0x01, -+- BATADV_CLAIM_TYPE_ANNOUNCE = 0x02, -+- BATADV_CLAIM_TYPE_REQUEST = 0x03, -+- BATADV_CLAIM_TYPE_LOOPDETECT = 0x04, -+-}; -+- -+-/** -+- * enum batadv_tvlv_type - tvlv type definitions -+- * @BATADV_TVLV_GW: gateway tvlv -+- * @BATADV_TVLV_DAT: distributed arp table tvlv -+- * @BATADV_TVLV_NC: network coding tvlv -+- * @BATADV_TVLV_TT: translation table tvlv -+- * @BATADV_TVLV_ROAM: roaming advertisement tvlv -+- * @BATADV_TVLV_MCAST: multicast capability tvlv -+- */ -+-enum batadv_tvlv_type { -+- BATADV_TVLV_GW = 0x01, -+- BATADV_TVLV_DAT = 0x02, -+- BATADV_TVLV_NC = 0x03, -+- BATADV_TVLV_TT = 0x04, -+- BATADV_TVLV_ROAM = 0x05, -+- BATADV_TVLV_MCAST = 0x06, -+-}; -+- -+-#pragma pack(2) -+-/* the destination hardware field in the ARP frame is used to -+- * transport the claim type and the group id -+- */ -+-struct batadv_bla_claim_dst { -+- __u8 magic[3]; /* FF:43:05 */ -+- __u8 type; /* bla_claimframe */ -+- __be16 group; /* group id */ -+-}; -+- -+-#pragma pack() -+- -+-/** -+- * struct batadv_ogm_packet - ogm (routing protocol) packet -+- * @packet_type: batman-adv packet type, part of the general header -+- * @version: batman-adv protocol version, part of the genereal header -+- * @ttl: time to live for this packet, part of the genereal header -+- * @flags: contains routing relevant flags - see enum batadv_iv_flags -+- * @seqno: sequence identification -+- * @orig: address of the source node -+- * @prev_sender: address of the previous sender -+- * @reserved: reserved byte for alignment -+- * @tq: transmission quality -+- * @tvlv_len: length of tvlv data following the ogm header -+- */ -+-struct batadv_ogm_packet { -+- __u8 packet_type; -+- __u8 version; -+- __u8 ttl; -+- __u8 flags; -+- __be32 seqno; -+- __u8 orig[ETH_ALEN]; -+- __u8 prev_sender[ETH_ALEN]; -+- __u8 reserved; -+- __u8 tq; -+- __be16 tvlv_len; -+- /* __packed is not needed as the struct size is divisible by 4, -+- * and the largest data type in this struct has a size of 4. -+- */ -+-}; -+- -+-#define BATADV_OGM_HLEN sizeof(struct batadv_ogm_packet) -+- -+-/** -+- * struct batadv_ogm2_packet - ogm2 (routing protocol) packet -+- * @packet_type: batman-adv packet type, part of the general header -+- * @version: batman-adv protocol version, part of the general header -+- * @ttl: time to live for this packet, part of the general header -+- * @flags: reseved for routing relevant flags - currently always 0 -+- * @seqno: sequence number -+- * @orig: originator mac address -+- * @tvlv_len: length of the appended tvlv buffer (in bytes) -+- * @throughput: the currently flooded path throughput -+- */ -+-struct batadv_ogm2_packet { -+- __u8 packet_type; -+- __u8 version; -+- __u8 ttl; -+- __u8 flags; -+- __be32 seqno; -+- __u8 orig[ETH_ALEN]; -+- __be16 tvlv_len; -+- __be32 throughput; -+- /* __packed is not needed as the struct size is divisible by 4, -+- * and the largest data type in this struct has a size of 4. -+- */ -+-}; -+- -+-#define BATADV_OGM2_HLEN sizeof(struct batadv_ogm2_packet) -+- -+-/** -+- * struct batadv_elp_packet - elp (neighbor discovery) packet -+- * @packet_type: batman-adv packet type, part of the general header -+- * @version: batman-adv protocol version, part of the genereal header -+- * @orig: originator mac address -+- * @seqno: sequence number -+- * @elp_interval: currently used ELP sending interval in ms -+- */ -+-struct batadv_elp_packet { -+- __u8 packet_type; -+- __u8 version; -+- __u8 orig[ETH_ALEN]; -+- __be32 seqno; -+- __be32 elp_interval; -+-}; -+- -+-#define BATADV_ELP_HLEN sizeof(struct batadv_elp_packet) -+- -+-/** -+- * struct batadv_icmp_header - common members among all the ICMP packets -+- * @packet_type: batman-adv packet type, part of the general header -+- * @version: batman-adv protocol version, part of the genereal header -+- * @ttl: time to live for this packet, part of the genereal header -+- * @msg_type: ICMP packet type -+- * @dst: address of the destination node -+- * @orig: address of the source node -+- * @uid: local ICMP socket identifier -+- * @align: not used - useful for alignment purposes only -+- * -+- * This structure is used for ICMP packets parsing only and it is never sent -+- * over the wire. The alignment field at the end is there to ensure that -+- * members are padded the same way as they are in real packets. -+- */ -+-struct batadv_icmp_header { -+- __u8 packet_type; -+- __u8 version; -+- __u8 ttl; -+- __u8 msg_type; /* see ICMP message types above */ -+- __u8 dst[ETH_ALEN]; -+- __u8 orig[ETH_ALEN]; -+- __u8 uid; -+- __u8 align[3]; -+-}; -+- -+-/** -+- * struct batadv_icmp_packet - ICMP packet -+- * @packet_type: batman-adv packet type, part of the general header -+- * @version: batman-adv protocol version, part of the genereal header -+- * @ttl: time to live for this packet, part of the genereal header -+- * @msg_type: ICMP packet type -+- * @dst: address of the destination node -+- * @orig: address of the source node -+- * @uid: local ICMP socket identifier -+- * @reserved: not used - useful for alignment -+- * @seqno: ICMP sequence number -+- */ -+-struct batadv_icmp_packet { -+- __u8 packet_type; -+- __u8 version; -+- __u8 ttl; -+- __u8 msg_type; /* see ICMP message types above */ -+- __u8 dst[ETH_ALEN]; -+- __u8 orig[ETH_ALEN]; -+- __u8 uid; -+- __u8 reserved; -+- __be16 seqno; -+-}; -+- -+-/** -+- * struct batadv_icmp_tp_packet - ICMP TP Meter packet -+- * @packet_type: batman-adv packet type, part of the general header -+- * @version: batman-adv protocol version, part of the genereal header -+- * @ttl: time to live for this packet, part of the genereal header -+- * @msg_type: ICMP packet type -+- * @dst: address of the destination node -+- * @orig: address of the source node -+- * @uid: local ICMP socket identifier -+- * @subtype: TP packet subtype (see batadv_icmp_tp_subtype) -+- * @session: TP session identifier -+- * @seqno: the TP sequence number -+- * @timestamp: time when the packet has been sent. This value is filled in a -+- * TP_MSG and echoed back in the next TP_ACK so that the sender can compute the -+- * RTT. Since it is read only by the host which wrote it, there is no need to -+- * store it using network order -+- */ -+-struct batadv_icmp_tp_packet { -+- __u8 packet_type; -+- __u8 version; -+- __u8 ttl; -+- __u8 msg_type; /* see ICMP message types above */ -+- __u8 dst[ETH_ALEN]; -+- __u8 orig[ETH_ALEN]; -+- __u8 uid; -+- __u8 subtype; -+- __u8 session[2]; -+- __be32 seqno; -+- __be32 timestamp; -+-}; -+- -+-/** -+- * enum batadv_icmp_tp_subtype - ICMP TP Meter packet subtypes -+- * @BATADV_TP_MSG: Msg from sender to receiver -+- * @BATADV_TP_ACK: acknowledgment from receiver to sender -+- */ -+-enum batadv_icmp_tp_subtype { -+- BATADV_TP_MSG = 0, -+- BATADV_TP_ACK, -+-}; -+- -+-#define BATADV_RR_LEN 16 -+- -+-/** -+- * struct batadv_icmp_packet_rr - ICMP RouteRecord packet -+- * @packet_type: batman-adv packet type, part of the general header -+- * @version: batman-adv protocol version, part of the genereal header -+- * @ttl: time to live for this packet, part of the genereal header -+- * @msg_type: ICMP packet type -+- * @dst: address of the destination node -+- * @orig: address of the source node -+- * @uid: local ICMP socket identifier -+- * @rr_cur: number of entries the rr array -+- * @seqno: ICMP sequence number -+- * @rr: route record array -+- */ -+-struct batadv_icmp_packet_rr { -+- __u8 packet_type; -+- __u8 version; -+- __u8 ttl; -+- __u8 msg_type; /* see ICMP message types above */ -+- __u8 dst[ETH_ALEN]; -+- __u8 orig[ETH_ALEN]; -+- __u8 uid; -+- __u8 rr_cur; -+- __be16 seqno; -+- __u8 rr[BATADV_RR_LEN][ETH_ALEN]; -+-}; -+- -+-#define BATADV_ICMP_MAX_PACKET_SIZE sizeof(struct batadv_icmp_packet_rr) -+- -+-/* All packet headers in front of an ethernet header have to be completely -+- * divisible by 2 but not by 4 to make the payload after the ethernet -+- * header again 4 bytes boundary aligned. -+- * -+- * A packing of 2 is necessary to avoid extra padding at the end of the struct -+- * caused by a structure member which is larger than two bytes. Otherwise -+- * the structure would not fulfill the previously mentioned rule to avoid the -+- * misalignment of the payload after the ethernet header. It may also lead to -+- * leakage of information when the padding it not initialized before sending. -+- */ -+-#pragma pack(2) -+- -+-/** -+- * struct batadv_unicast_packet - unicast packet for network payload -+- * @packet_type: batman-adv packet type, part of the general header -+- * @version: batman-adv protocol version, part of the genereal header -+- * @ttl: time to live for this packet, part of the genereal header -+- * @ttvn: translation table version number -+- * @dest: originator destination of the unicast packet -+- */ -+-struct batadv_unicast_packet { -+- __u8 packet_type; -+- __u8 version; -+- __u8 ttl; -+- __u8 ttvn; /* destination translation table version number */ -+- __u8 dest[ETH_ALEN]; -+- /* "4 bytes boundary + 2 bytes" long to make the payload after the -+- * following ethernet header again 4 bytes boundary aligned -+- */ -+-}; -+- -+-/** -+- * struct batadv_unicast_4addr_packet - extended unicast packet -+- * @u: common unicast packet header -+- * @src: address of the source -+- * @subtype: packet subtype -+- * @reserved: reserved byte for alignment -+- */ -+-struct batadv_unicast_4addr_packet { -+- struct batadv_unicast_packet u; -+- __u8 src[ETH_ALEN]; -+- __u8 subtype; -+- __u8 reserved; -+- /* "4 bytes boundary + 2 bytes" long to make the payload after the -+- * following ethernet header again 4 bytes boundary aligned -+- */ -+-}; -+- -+-/** -+- * struct batadv_frag_packet - fragmented packet -+- * @packet_type: batman-adv packet type, part of the general header -+- * @version: batman-adv protocol version, part of the genereal header -+- * @ttl: time to live for this packet, part of the genereal header -+- * @dest: final destination used when routing fragments -+- * @orig: originator of the fragment used when merging the packet -+- * @no: fragment number within this sequence -+- * @priority: priority of frame, from ToS IP precedence or 802.1p -+- * @reserved: reserved byte for alignment -+- * @seqno: sequence identification -+- * @total_size: size of the merged packet -+- */ -+-struct batadv_frag_packet { -+- __u8 packet_type; -+- __u8 version; /* batman version field */ -+- __u8 ttl; -+-#if defined(__BIG_ENDIAN_BITFIELD) -+- __u8 no:4; -+- __u8 priority:3; -+- __u8 reserved:1; -+-#elif defined(__LITTLE_ENDIAN_BITFIELD) -+- __u8 reserved:1; -+- __u8 priority:3; -+- __u8 no:4; -+-#else -+-#error "unknown bitfield endianness" -+-#endif -+- __u8 dest[ETH_ALEN]; -+- __u8 orig[ETH_ALEN]; -+- __be16 seqno; -+- __be16 total_size; -+-}; -+- -+-/** -+- * struct batadv_bcast_packet - broadcast packet for network payload -+- * @packet_type: batman-adv packet type, part of the general header -+- * @version: batman-adv protocol version, part of the genereal header -+- * @ttl: time to live for this packet, part of the genereal header -+- * @reserved: reserved byte for alignment -+- * @seqno: sequence identification -+- * @orig: originator of the broadcast packet -+- */ -+-struct batadv_bcast_packet { -+- __u8 packet_type; -+- __u8 version; /* batman version field */ -+- __u8 ttl; -+- __u8 reserved; -+- __be32 seqno; -+- __u8 orig[ETH_ALEN]; -+- /* "4 bytes boundary + 2 bytes" long to make the payload after the -+- * following ethernet header again 4 bytes boundary aligned -+- */ -+-}; -+- -+-/** -+- * struct batadv_coded_packet - network coded packet -+- * @packet_type: batman-adv packet type, part of the general header -+- * @version: batman-adv protocol version, part of the genereal header -+- * @ttl: time to live for this packet, part of the genereal header -+- * @first_source: original source of first included packet -+- * @first_orig_dest: original destinal of first included packet -+- * @first_crc: checksum of first included packet -+- * @first_ttvn: tt-version number of first included packet -+- * @second_ttl: ttl of second packet -+- * @second_dest: second receiver of this coded packet -+- * @second_source: original source of second included packet -+- * @second_orig_dest: original destination of second included packet -+- * @second_crc: checksum of second included packet -+- * @second_ttvn: tt version number of second included packet -+- * @coded_len: length of network coded part of the payload -+- */ -+-struct batadv_coded_packet { -+- __u8 packet_type; -+- __u8 version; /* batman version field */ -+- __u8 ttl; -+- __u8 first_ttvn; -+- /* __u8 first_dest[ETH_ALEN]; - saved in mac header destination */ -+- __u8 first_source[ETH_ALEN]; -+- __u8 first_orig_dest[ETH_ALEN]; -+- __be32 first_crc; -+- __u8 second_ttl; -+- __u8 second_ttvn; -+- __u8 second_dest[ETH_ALEN]; -+- __u8 second_source[ETH_ALEN]; -+- __u8 second_orig_dest[ETH_ALEN]; -+- __be32 second_crc; -+- __be16 coded_len; -+-}; -+- -+-#pragma pack() -+- -+-/** -+- * struct batadv_unicast_tvlv_packet - generic unicast packet with tvlv payload -+- * @packet_type: batman-adv packet type, part of the general header -+- * @version: batman-adv protocol version, part of the genereal header -+- * @ttl: time to live for this packet, part of the genereal header -+- * @reserved: reserved field (for packet alignment) -+- * @src: address of the source -+- * @dst: address of the destination -+- * @tvlv_len: length of tvlv data following the unicast tvlv header -+- * @align: 2 bytes to align the header to a 4 byte boundary -+- */ -+-struct batadv_unicast_tvlv_packet { -+- __u8 packet_type; -+- __u8 version; /* batman version field */ -+- __u8 ttl; -+- __u8 reserved; -+- __u8 dst[ETH_ALEN]; -+- __u8 src[ETH_ALEN]; -+- __be16 tvlv_len; -+- __u16 align; -+-}; -+- -+-/** -+- * struct batadv_tvlv_hdr - base tvlv header struct -+- * @type: tvlv container type (see batadv_tvlv_type) -+- * @version: tvlv container version -+- * @len: tvlv container length -+- */ -+-struct batadv_tvlv_hdr { -+- __u8 type; -+- __u8 version; -+- __be16 len; -+-}; -+- -+-/** -+- * struct batadv_tvlv_gateway_data - gateway data propagated through gw tvlv -+- * container -+- * @bandwidth_down: advertised uplink download bandwidth -+- * @bandwidth_up: advertised uplink upload bandwidth -+- */ -+-struct batadv_tvlv_gateway_data { -+- __be32 bandwidth_down; -+- __be32 bandwidth_up; -+-}; -+- -+-/** -+- * struct batadv_tvlv_tt_data - tt data propagated through the tt tvlv container -+- * @flags: translation table flags (see batadv_tt_data_flags) -+- * @ttvn: translation table version number -+- * @num_vlan: number of announced VLANs. In the TVLV this struct is followed by -+- * one batadv_tvlv_tt_vlan_data object per announced vlan -+- */ -+-struct batadv_tvlv_tt_data { -+- __u8 flags; -+- __u8 ttvn; -+- __be16 num_vlan; -+-}; -+- -+-/** -+- * struct batadv_tvlv_tt_vlan_data - vlan specific tt data propagated through -+- * the tt tvlv container -+- * @crc: crc32 checksum of the entries belonging to this vlan -+- * @vid: vlan identifier -+- * @reserved: unused, useful for alignment purposes -+- */ -+-struct batadv_tvlv_tt_vlan_data { -+- __be32 crc; -+- __be16 vid; -+- __u16 reserved; -+-}; -+- -+-/** -+- * struct batadv_tvlv_tt_change - translation table diff data -+- * @flags: status indicators concerning the non-mesh client (see -+- * batadv_tt_client_flags) -+- * @reserved: reserved field - useful for alignment purposes only -+- * @addr: mac address of non-mesh client that triggered this tt change -+- * @vid: VLAN identifier -+- */ -+-struct batadv_tvlv_tt_change { -+- __u8 flags; -+- __u8 reserved[3]; -+- __u8 addr[ETH_ALEN]; -+- __be16 vid; -+-}; -+- -+-/** -+- * struct batadv_tvlv_roam_adv - roaming advertisement -+- * @client: mac address of roaming client -+- * @vid: VLAN identifier -+- */ -+-struct batadv_tvlv_roam_adv { -+- __u8 client[ETH_ALEN]; -+- __be16 vid; -+-}; -+- -+-/** -+- * struct batadv_tvlv_mcast_data - payload of a multicast tvlv -+- * @flags: multicast flags announced by the orig node -+- * @reserved: reserved field -+- */ -+-struct batadv_tvlv_mcast_data { -+- __u8 flags; -+- __u8 reserved[3]; -+-}; -+- -+-#endif /* _NET_BATMAN_ADV_PACKET_H_ */ -+--- a/net/batman-adv/routing.c -++++ b/net/batman-adv/routing.c -+@@ -33,6 +33,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "bitarray.h" -+ #include "bridge_loop_avoidance.h" -+@@ -43,7 +44,6 @@ -+ #include "log.h" -+ #include "network-coding.h" -+ #include "originator.h" -+-#include "packet.h" -+ #include "send.h" -+ #include "soft-interface.h" -+ #include "tp_meter.h" -+--- a/net/batman-adv/send.h -++++ b/net/batman-adv/send.h -+@@ -23,8 +23,7 @@ -+ #include -+ #include -+ #include -+- -+-#include "packet.h" -++#include -+ -+ struct sk_buff; -+ -+--- a/net/batman-adv/soft-interface.c -++++ b/net/batman-adv/soft-interface.c -+@@ -48,6 +48,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "bat_algo.h" -+ #include "bridge_loop_avoidance.h" -+@@ -59,7 +60,6 @@ -+ #include "multicast.h" -+ #include "network-coding.h" -+ #include "originator.h" -+-#include "packet.h" -+ #include "send.h" -+ #include "sysfs.h" -+ #include "translation-table.h" -+--- a/net/batman-adv/sysfs.c -++++ b/net/batman-adv/sysfs.c -+@@ -37,6 +37,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "bridge_loop_avoidance.h" -+ #include "distributed-arp-table.h" -+@@ -45,7 +46,6 @@ -+ #include "hard-interface.h" -+ #include "log.h" -+ #include "network-coding.h" -+-#include "packet.h" -+ #include "soft-interface.h" -+ -+ static struct net_device *batadv_kobj_to_netdev(struct kobject *obj) -+--- a/net/batman-adv/tp_meter.c -++++ b/net/batman-adv/tp_meter.c -+@@ -48,13 +48,13 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ -+ #include "hard-interface.h" -+ #include "log.h" -+ #include "netlink.h" -+ #include "originator.h" -+-#include "packet.h" -+ #include "send.h" -+ -+ /** -+--- a/net/batman-adv/translation-table.c -++++ b/net/batman-adv/translation-table.c -+@@ -50,6 +50,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ -+ #include "bridge_loop_avoidance.h" -+@@ -58,7 +59,6 @@ -+ #include "log.h" -+ #include "netlink.h" -+ #include "originator.h" -+-#include "packet.h" -+ #include "soft-interface.h" -+ #include "tvlv.h" -+ -+--- a/net/batman-adv/tvlv.c -++++ b/net/batman-adv/tvlv.c -+@@ -35,9 +35,9 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "originator.h" -+-#include "packet.h" -+ #include "send.h" -+ #include "tvlv.h" -+ -+--- a/net/batman-adv/types.h -++++ b/net/batman-adv/types.h -+@@ -35,10 +35,9 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ -+-#include "packet.h" -+- -+ struct seq_file; -+ -+ #ifdef CONFIG_BATMAN_ADV_DAT -+--- /dev/null -++++ b/include/uapi/linux/batadv_packet.h -+@@ -0,0 +1,623 @@ -++/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) */ -++/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: -++ * -++ * Marek Lindner, Simon Wunderlich -++ * -++ * This program is free software; you can redistribute it and/or -++ * modify it under the terms of version 2 of the GNU General Public -++ * License as published by the Free Software Foundation. -++ * -++ * This program is distributed in the hope that it will be useful, but -++ * WITHOUT ANY WARRANTY; without even the implied warranty of -++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -++ * General Public License for more details. -++ * -++ * You should have received a copy of the GNU General Public License -++ * along with this program; if not, see . -++ */ -++ -++#ifndef _UAPI_LINUX_BATADV_PACKET_H_ -++#define _UAPI_LINUX_BATADV_PACKET_H_ -++ -++#include -++#include -++#include -++ -++#define batadv_tp_is_error(n) ((__u8)(n) > 127 ? 1 : 0) -++ -++/** -++ * enum batadv_packettype - types for batman-adv encapsulated packets -++ * @BATADV_IV_OGM: originator messages for B.A.T.M.A.N. IV -++ * @BATADV_BCAST: broadcast packets carrying broadcast payload -++ * @BATADV_CODED: network coded packets -++ * @BATADV_ELP: echo location packets for B.A.T.M.A.N. V -++ * @BATADV_OGM2: originator messages for B.A.T.M.A.N. V -++ * -++ * @BATADV_UNICAST: unicast packets carrying unicast payload traffic -++ * @BATADV_UNICAST_FRAG: unicast packets carrying a fragment of the original -++ * payload packet -++ * @BATADV_UNICAST_4ADDR: unicast packet including the originator address of -++ * the sender -++ * @BATADV_ICMP: unicast packet like IP ICMP used for ping or traceroute -++ * @BATADV_UNICAST_TVLV: unicast packet carrying TVLV containers -++ */ -++enum batadv_packettype { -++ /* 0x00 - 0x3f: local packets or special rules for handling */ -++ BATADV_IV_OGM = 0x00, -++ BATADV_BCAST = 0x01, -++ BATADV_CODED = 0x02, -++ BATADV_ELP = 0x03, -++ BATADV_OGM2 = 0x04, -++ /* 0x40 - 0x7f: unicast */ -++#define BATADV_UNICAST_MIN 0x40 -++ BATADV_UNICAST = 0x40, -++ BATADV_UNICAST_FRAG = 0x41, -++ BATADV_UNICAST_4ADDR = 0x42, -++ BATADV_ICMP = 0x43, -++ BATADV_UNICAST_TVLV = 0x44, -++#define BATADV_UNICAST_MAX 0x7f -++ /* 0x80 - 0xff: reserved */ -++}; -++ -++/** -++ * enum batadv_subtype - packet subtype for unicast4addr -++ * @BATADV_P_DATA: user payload -++ * @BATADV_P_DAT_DHT_GET: DHT request message -++ * @BATADV_P_DAT_DHT_PUT: DHT store message -++ * @BATADV_P_DAT_CACHE_REPLY: ARP reply generated by DAT -++ */ -++enum batadv_subtype { -++ BATADV_P_DATA = 0x01, -++ BATADV_P_DAT_DHT_GET = 0x02, -++ BATADV_P_DAT_DHT_PUT = 0x03, -++ BATADV_P_DAT_CACHE_REPLY = 0x04, -++}; -++ -++/* this file is included by batctl which needs these defines */ -++#define BATADV_COMPAT_VERSION 15 -++ -++/** -++ * enum batadv_iv_flags - flags used in B.A.T.M.A.N. IV OGM packets -++ * @BATADV_NOT_BEST_NEXT_HOP: flag is set when ogm packet is forwarded and was -++ * previously received from someone else than the best neighbor. -++ * @BATADV_PRIMARIES_FIRST_HOP: flag unused. -++ * @BATADV_DIRECTLINK: flag is for the first hop or if rebroadcasted from a -++ * one hop neighbor on the interface where it was originally received. -++ */ -++enum batadv_iv_flags { -++ BATADV_NOT_BEST_NEXT_HOP = 1UL << 0, -++ BATADV_PRIMARIES_FIRST_HOP = 1UL << 1, -++ BATADV_DIRECTLINK = 1UL << 2, -++}; -++ -++/* ICMP message types */ -++enum batadv_icmp_packettype { -++ BATADV_ECHO_REPLY = 0, -++ BATADV_DESTINATION_UNREACHABLE = 3, -++ BATADV_ECHO_REQUEST = 8, -++ BATADV_TTL_EXCEEDED = 11, -++ BATADV_PARAMETER_PROBLEM = 12, -++ BATADV_TP = 15, -++}; -++ -++/** -++ * enum batadv_mcast_flags - flags for multicast capabilities and settings -++ * @BATADV_MCAST_WANT_ALL_UNSNOOPABLES: we want all packets destined for -++ * 224.0.0.0/24 or ff02::1 -++ * @BATADV_MCAST_WANT_ALL_IPV4: we want all IPv4 multicast packets -++ * @BATADV_MCAST_WANT_ALL_IPV6: we want all IPv6 multicast packets -++ */ -++enum batadv_mcast_flags { -++ BATADV_MCAST_WANT_ALL_UNSNOOPABLES = 1UL << 0, -++ BATADV_MCAST_WANT_ALL_IPV4 = 1UL << 1, -++ BATADV_MCAST_WANT_ALL_IPV6 = 1UL << 2, -++}; -++ -++/* tt data subtypes */ -++#define BATADV_TT_DATA_TYPE_MASK 0x0F -++ -++/** -++ * enum batadv_tt_data_flags - flags for tt data tvlv -++ * @BATADV_TT_OGM_DIFF: TT diff propagated through OGM -++ * @BATADV_TT_REQUEST: TT request message -++ * @BATADV_TT_RESPONSE: TT response message -++ * @BATADV_TT_FULL_TABLE: contains full table to replace existing table -++ */ -++enum batadv_tt_data_flags { -++ BATADV_TT_OGM_DIFF = 1UL << 0, -++ BATADV_TT_REQUEST = 1UL << 1, -++ BATADV_TT_RESPONSE = 1UL << 2, -++ BATADV_TT_FULL_TABLE = 1UL << 4, -++}; -++ -++/** -++ * enum batadv_vlan_flags - flags for the four MSB of any vlan ID field -++ * @BATADV_VLAN_HAS_TAG: whether the field contains a valid vlan tag or not -++ */ -++enum batadv_vlan_flags { -++ BATADV_VLAN_HAS_TAG = 1UL << 15, -++}; -++ -++/* claim frame types for the bridge loop avoidance */ -++enum batadv_bla_claimframe { -++ BATADV_CLAIM_TYPE_CLAIM = 0x00, -++ BATADV_CLAIM_TYPE_UNCLAIM = 0x01, -++ BATADV_CLAIM_TYPE_ANNOUNCE = 0x02, -++ BATADV_CLAIM_TYPE_REQUEST = 0x03, -++ BATADV_CLAIM_TYPE_LOOPDETECT = 0x04, -++}; -++ -++/** -++ * enum batadv_tvlv_type - tvlv type definitions -++ * @BATADV_TVLV_GW: gateway tvlv -++ * @BATADV_TVLV_DAT: distributed arp table tvlv -++ * @BATADV_TVLV_NC: network coding tvlv -++ * @BATADV_TVLV_TT: translation table tvlv -++ * @BATADV_TVLV_ROAM: roaming advertisement tvlv -++ * @BATADV_TVLV_MCAST: multicast capability tvlv -++ */ -++enum batadv_tvlv_type { -++ BATADV_TVLV_GW = 0x01, -++ BATADV_TVLV_DAT = 0x02, -++ BATADV_TVLV_NC = 0x03, -++ BATADV_TVLV_TT = 0x04, -++ BATADV_TVLV_ROAM = 0x05, -++ BATADV_TVLV_MCAST = 0x06, -++}; -++ -++#pragma pack(2) -++/* the destination hardware field in the ARP frame is used to -++ * transport the claim type and the group id -++ */ -++struct batadv_bla_claim_dst { -++ __u8 magic[3]; /* FF:43:05 */ -++ __u8 type; /* bla_claimframe */ -++ __be16 group; /* group id */ -++}; -++ -++#pragma pack() -++ -++/** -++ * struct batadv_ogm_packet - ogm (routing protocol) packet -++ * @packet_type: batman-adv packet type, part of the general header -++ * @version: batman-adv protocol version, part of the genereal header -++ * @ttl: time to live for this packet, part of the genereal header -++ * @flags: contains routing relevant flags - see enum batadv_iv_flags -++ * @seqno: sequence identification -++ * @orig: address of the source node -++ * @prev_sender: address of the previous sender -++ * @reserved: reserved byte for alignment -++ * @tq: transmission quality -++ * @tvlv_len: length of tvlv data following the ogm header -++ */ -++struct batadv_ogm_packet { -++ __u8 packet_type; -++ __u8 version; -++ __u8 ttl; -++ __u8 flags; -++ __be32 seqno; -++ __u8 orig[ETH_ALEN]; -++ __u8 prev_sender[ETH_ALEN]; -++ __u8 reserved; -++ __u8 tq; -++ __be16 tvlv_len; -++ /* __packed is not needed as the struct size is divisible by 4, -++ * and the largest data type in this struct has a size of 4. -++ */ -++}; -++ -++#define BATADV_OGM_HLEN sizeof(struct batadv_ogm_packet) -++ -++/** -++ * struct batadv_ogm2_packet - ogm2 (routing protocol) packet -++ * @packet_type: batman-adv packet type, part of the general header -++ * @version: batman-adv protocol version, part of the general header -++ * @ttl: time to live for this packet, part of the general header -++ * @flags: reseved for routing relevant flags - currently always 0 -++ * @seqno: sequence number -++ * @orig: originator mac address -++ * @tvlv_len: length of the appended tvlv buffer (in bytes) -++ * @throughput: the currently flooded path throughput -++ */ -++struct batadv_ogm2_packet { -++ __u8 packet_type; -++ __u8 version; -++ __u8 ttl; -++ __u8 flags; -++ __be32 seqno; -++ __u8 orig[ETH_ALEN]; -++ __be16 tvlv_len; -++ __be32 throughput; -++ /* __packed is not needed as the struct size is divisible by 4, -++ * and the largest data type in this struct has a size of 4. -++ */ -++}; -++ -++#define BATADV_OGM2_HLEN sizeof(struct batadv_ogm2_packet) -++ -++/** -++ * struct batadv_elp_packet - elp (neighbor discovery) packet -++ * @packet_type: batman-adv packet type, part of the general header -++ * @version: batman-adv protocol version, part of the genereal header -++ * @orig: originator mac address -++ * @seqno: sequence number -++ * @elp_interval: currently used ELP sending interval in ms -++ */ -++struct batadv_elp_packet { -++ __u8 packet_type; -++ __u8 version; -++ __u8 orig[ETH_ALEN]; -++ __be32 seqno; -++ __be32 elp_interval; -++}; -++ -++#define BATADV_ELP_HLEN sizeof(struct batadv_elp_packet) -++ -++/** -++ * struct batadv_icmp_header - common members among all the ICMP packets -++ * @packet_type: batman-adv packet type, part of the general header -++ * @version: batman-adv protocol version, part of the genereal header -++ * @ttl: time to live for this packet, part of the genereal header -++ * @msg_type: ICMP packet type -++ * @dst: address of the destination node -++ * @orig: address of the source node -++ * @uid: local ICMP socket identifier -++ * @align: not used - useful for alignment purposes only -++ * -++ * This structure is used for ICMP packets parsing only and it is never sent -++ * over the wire. The alignment field at the end is there to ensure that -++ * members are padded the same way as they are in real packets. -++ */ -++struct batadv_icmp_header { -++ __u8 packet_type; -++ __u8 version; -++ __u8 ttl; -++ __u8 msg_type; /* see ICMP message types above */ -++ __u8 dst[ETH_ALEN]; -++ __u8 orig[ETH_ALEN]; -++ __u8 uid; -++ __u8 align[3]; -++}; -++ -++/** -++ * struct batadv_icmp_packet - ICMP packet -++ * @packet_type: batman-adv packet type, part of the general header -++ * @version: batman-adv protocol version, part of the genereal header -++ * @ttl: time to live for this packet, part of the genereal header -++ * @msg_type: ICMP packet type -++ * @dst: address of the destination node -++ * @orig: address of the source node -++ * @uid: local ICMP socket identifier -++ * @reserved: not used - useful for alignment -++ * @seqno: ICMP sequence number -++ */ -++struct batadv_icmp_packet { -++ __u8 packet_type; -++ __u8 version; -++ __u8 ttl; -++ __u8 msg_type; /* see ICMP message types above */ -++ __u8 dst[ETH_ALEN]; -++ __u8 orig[ETH_ALEN]; -++ __u8 uid; -++ __u8 reserved; -++ __be16 seqno; -++}; -++ -++/** -++ * struct batadv_icmp_tp_packet - ICMP TP Meter packet -++ * @packet_type: batman-adv packet type, part of the general header -++ * @version: batman-adv protocol version, part of the genereal header -++ * @ttl: time to live for this packet, part of the genereal header -++ * @msg_type: ICMP packet type -++ * @dst: address of the destination node -++ * @orig: address of the source node -++ * @uid: local ICMP socket identifier -++ * @subtype: TP packet subtype (see batadv_icmp_tp_subtype) -++ * @session: TP session identifier -++ * @seqno: the TP sequence number -++ * @timestamp: time when the packet has been sent. This value is filled in a -++ * TP_MSG and echoed back in the next TP_ACK so that the sender can compute the -++ * RTT. Since it is read only by the host which wrote it, there is no need to -++ * store it using network order -++ */ -++struct batadv_icmp_tp_packet { -++ __u8 packet_type; -++ __u8 version; -++ __u8 ttl; -++ __u8 msg_type; /* see ICMP message types above */ -++ __u8 dst[ETH_ALEN]; -++ __u8 orig[ETH_ALEN]; -++ __u8 uid; -++ __u8 subtype; -++ __u8 session[2]; -++ __be32 seqno; -++ __be32 timestamp; -++}; -++ -++/** -++ * enum batadv_icmp_tp_subtype - ICMP TP Meter packet subtypes -++ * @BATADV_TP_MSG: Msg from sender to receiver -++ * @BATADV_TP_ACK: acknowledgment from receiver to sender -++ */ -++enum batadv_icmp_tp_subtype { -++ BATADV_TP_MSG = 0, -++ BATADV_TP_ACK, -++}; -++ -++#define BATADV_RR_LEN 16 -++ -++/** -++ * struct batadv_icmp_packet_rr - ICMP RouteRecord packet -++ * @packet_type: batman-adv packet type, part of the general header -++ * @version: batman-adv protocol version, part of the genereal header -++ * @ttl: time to live for this packet, part of the genereal header -++ * @msg_type: ICMP packet type -++ * @dst: address of the destination node -++ * @orig: address of the source node -++ * @uid: local ICMP socket identifier -++ * @rr_cur: number of entries the rr array -++ * @seqno: ICMP sequence number -++ * @rr: route record array -++ */ -++struct batadv_icmp_packet_rr { -++ __u8 packet_type; -++ __u8 version; -++ __u8 ttl; -++ __u8 msg_type; /* see ICMP message types above */ -++ __u8 dst[ETH_ALEN]; -++ __u8 orig[ETH_ALEN]; -++ __u8 uid; -++ __u8 rr_cur; -++ __be16 seqno; -++ __u8 rr[BATADV_RR_LEN][ETH_ALEN]; -++}; -++ -++#define BATADV_ICMP_MAX_PACKET_SIZE sizeof(struct batadv_icmp_packet_rr) -++ -++/* All packet headers in front of an ethernet header have to be completely -++ * divisible by 2 but not by 4 to make the payload after the ethernet -++ * header again 4 bytes boundary aligned. -++ * -++ * A packing of 2 is necessary to avoid extra padding at the end of the struct -++ * caused by a structure member which is larger than two bytes. Otherwise -++ * the structure would not fulfill the previously mentioned rule to avoid the -++ * misalignment of the payload after the ethernet header. It may also lead to -++ * leakage of information when the padding it not initialized before sending. -++ */ -++#pragma pack(2) -++ -++/** -++ * struct batadv_unicast_packet - unicast packet for network payload -++ * @packet_type: batman-adv packet type, part of the general header -++ * @version: batman-adv protocol version, part of the genereal header -++ * @ttl: time to live for this packet, part of the genereal header -++ * @ttvn: translation table version number -++ * @dest: originator destination of the unicast packet -++ */ -++struct batadv_unicast_packet { -++ __u8 packet_type; -++ __u8 version; -++ __u8 ttl; -++ __u8 ttvn; /* destination translation table version number */ -++ __u8 dest[ETH_ALEN]; -++ /* "4 bytes boundary + 2 bytes" long to make the payload after the -++ * following ethernet header again 4 bytes boundary aligned -++ */ -++}; -++ -++/** -++ * struct batadv_unicast_4addr_packet - extended unicast packet -++ * @u: common unicast packet header -++ * @src: address of the source -++ * @subtype: packet subtype -++ * @reserved: reserved byte for alignment -++ */ -++struct batadv_unicast_4addr_packet { -++ struct batadv_unicast_packet u; -++ __u8 src[ETH_ALEN]; -++ __u8 subtype; -++ __u8 reserved; -++ /* "4 bytes boundary + 2 bytes" long to make the payload after the -++ * following ethernet header again 4 bytes boundary aligned -++ */ -++}; -++ -++/** -++ * struct batadv_frag_packet - fragmented packet -++ * @packet_type: batman-adv packet type, part of the general header -++ * @version: batman-adv protocol version, part of the genereal header -++ * @ttl: time to live for this packet, part of the genereal header -++ * @dest: final destination used when routing fragments -++ * @orig: originator of the fragment used when merging the packet -++ * @no: fragment number within this sequence -++ * @priority: priority of frame, from ToS IP precedence or 802.1p -++ * @reserved: reserved byte for alignment -++ * @seqno: sequence identification -++ * @total_size: size of the merged packet -++ */ -++struct batadv_frag_packet { -++ __u8 packet_type; -++ __u8 version; /* batman version field */ -++ __u8 ttl; -++#if defined(__BIG_ENDIAN_BITFIELD) -++ __u8 no:4; -++ __u8 priority:3; -++ __u8 reserved:1; -++#elif defined(__LITTLE_ENDIAN_BITFIELD) -++ __u8 reserved:1; -++ __u8 priority:3; -++ __u8 no:4; -++#else -++#error "unknown bitfield endianness" -++#endif -++ __u8 dest[ETH_ALEN]; -++ __u8 orig[ETH_ALEN]; -++ __be16 seqno; -++ __be16 total_size; -++}; -++ -++/** -++ * struct batadv_bcast_packet - broadcast packet for network payload -++ * @packet_type: batman-adv packet type, part of the general header -++ * @version: batman-adv protocol version, part of the genereal header -++ * @ttl: time to live for this packet, part of the genereal header -++ * @reserved: reserved byte for alignment -++ * @seqno: sequence identification -++ * @orig: originator of the broadcast packet -++ */ -++struct batadv_bcast_packet { -++ __u8 packet_type; -++ __u8 version; /* batman version field */ -++ __u8 ttl; -++ __u8 reserved; -++ __be32 seqno; -++ __u8 orig[ETH_ALEN]; -++ /* "4 bytes boundary + 2 bytes" long to make the payload after the -++ * following ethernet header again 4 bytes boundary aligned -++ */ -++}; -++ -++/** -++ * struct batadv_coded_packet - network coded packet -++ * @packet_type: batman-adv packet type, part of the general header -++ * @version: batman-adv protocol version, part of the genereal header -++ * @ttl: time to live for this packet, part of the genereal header -++ * @first_source: original source of first included packet -++ * @first_orig_dest: original destinal of first included packet -++ * @first_crc: checksum of first included packet -++ * @first_ttvn: tt-version number of first included packet -++ * @second_ttl: ttl of second packet -++ * @second_dest: second receiver of this coded packet -++ * @second_source: original source of second included packet -++ * @second_orig_dest: original destination of second included packet -++ * @second_crc: checksum of second included packet -++ * @second_ttvn: tt version number of second included packet -++ * @coded_len: length of network coded part of the payload -++ */ -++struct batadv_coded_packet { -++ __u8 packet_type; -++ __u8 version; /* batman version field */ -++ __u8 ttl; -++ __u8 first_ttvn; -++ /* __u8 first_dest[ETH_ALEN]; - saved in mac header destination */ -++ __u8 first_source[ETH_ALEN]; -++ __u8 first_orig_dest[ETH_ALEN]; -++ __be32 first_crc; -++ __u8 second_ttl; -++ __u8 second_ttvn; -++ __u8 second_dest[ETH_ALEN]; -++ __u8 second_source[ETH_ALEN]; -++ __u8 second_orig_dest[ETH_ALEN]; -++ __be32 second_crc; -++ __be16 coded_len; -++}; -++ -++#pragma pack() -++ -++/** -++ * struct batadv_unicast_tvlv_packet - generic unicast packet with tvlv payload -++ * @packet_type: batman-adv packet type, part of the general header -++ * @version: batman-adv protocol version, part of the genereal header -++ * @ttl: time to live for this packet, part of the genereal header -++ * @reserved: reserved field (for packet alignment) -++ * @src: address of the source -++ * @dst: address of the destination -++ * @tvlv_len: length of tvlv data following the unicast tvlv header -++ * @align: 2 bytes to align the header to a 4 byte boundary -++ */ -++struct batadv_unicast_tvlv_packet { -++ __u8 packet_type; -++ __u8 version; /* batman version field */ -++ __u8 ttl; -++ __u8 reserved; -++ __u8 dst[ETH_ALEN]; -++ __u8 src[ETH_ALEN]; -++ __be16 tvlv_len; -++ __u16 align; -++}; -++ -++/** -++ * struct batadv_tvlv_hdr - base tvlv header struct -++ * @type: tvlv container type (see batadv_tvlv_type) -++ * @version: tvlv container version -++ * @len: tvlv container length -++ */ -++struct batadv_tvlv_hdr { -++ __u8 type; -++ __u8 version; -++ __be16 len; -++}; -++ -++/** -++ * struct batadv_tvlv_gateway_data - gateway data propagated through gw tvlv -++ * container -++ * @bandwidth_down: advertised uplink download bandwidth -++ * @bandwidth_up: advertised uplink upload bandwidth -++ */ -++struct batadv_tvlv_gateway_data { -++ __be32 bandwidth_down; -++ __be32 bandwidth_up; -++}; -++ -++/** -++ * struct batadv_tvlv_tt_data - tt data propagated through the tt tvlv container -++ * @flags: translation table flags (see batadv_tt_data_flags) -++ * @ttvn: translation table version number -++ * @num_vlan: number of announced VLANs. In the TVLV this struct is followed by -++ * one batadv_tvlv_tt_vlan_data object per announced vlan -++ */ -++struct batadv_tvlv_tt_data { -++ __u8 flags; -++ __u8 ttvn; -++ __be16 num_vlan; -++}; -++ -++/** -++ * struct batadv_tvlv_tt_vlan_data - vlan specific tt data propagated through -++ * the tt tvlv container -++ * @crc: crc32 checksum of the entries belonging to this vlan -++ * @vid: vlan identifier -++ * @reserved: unused, useful for alignment purposes -++ */ -++struct batadv_tvlv_tt_vlan_data { -++ __be32 crc; -++ __be16 vid; -++ __u16 reserved; -++}; -++ -++/** -++ * struct batadv_tvlv_tt_change - translation table diff data -++ * @flags: status indicators concerning the non-mesh client (see -++ * batadv_tt_client_flags) -++ * @reserved: reserved field - useful for alignment purposes only -++ * @addr: mac address of non-mesh client that triggered this tt change -++ * @vid: VLAN identifier -++ */ -++struct batadv_tvlv_tt_change { -++ __u8 flags; -++ __u8 reserved[3]; -++ __u8 addr[ETH_ALEN]; -++ __be16 vid; -++}; -++ -++/** -++ * struct batadv_tvlv_roam_adv - roaming advertisement -++ * @client: mac address of roaming client -++ * @vid: VLAN identifier -++ */ -++struct batadv_tvlv_roam_adv { -++ __u8 client[ETH_ALEN]; -++ __be16 vid; -++}; -++ -++/** -++ * struct batadv_tvlv_mcast_data - payload of a multicast tvlv -++ * @flags: multicast flags announced by the orig node -++ * @reserved: reserved field -++ */ -++struct batadv_tvlv_mcast_data { -++ __u8 flags; -++ __u8 reserved[3]; -++}; -++ -++#endif /* _UAPI_LINUX_BATADV_PACKET_H_ */ -diff --git a/target/linux/generic/backport-4.14/274-flow_dissector-Parse-batman-adv-unicast-headers.patch b/target/linux/generic/backport-4.14/274-flow_dissector-Parse-batman-adv-unicast-headers.patch -new file mode 100644 -index 0000000000..a9b2fc40a3 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/274-flow_dissector-Parse-batman-adv-unicast-headers.patch -@@ -0,0 +1,108 @@ -+From: Sven Eckelmann -+Date: Thu, 21 Dec 2017 10:17:42 +0100 -+Subject: [PATCH] flow_dissector: Parse batman-adv unicast headers -+ -+The batman-adv unicast packets contain a full layer 2 frame in encapsulated -+form. The flow dissector must therefore be able to parse the batman-adv -+unicast header to reach the layer 2+3 information. -+ -+ +--------------------+ -+ | ip(v6)hdr | -+ +--------------------+ -+ | inner ethhdr | -+ +--------------------+ -+ | batadv unicast hdr | -+ +--------------------+ -+ | outer ethhdr | -+ +--------------------+ -+ -+The obtained information from the upper layer can then be used by RPS to -+schedule the processing on separate cores. This allows better distribution -+of multiple flows from the same neighbor to different cores. -+ -+Signed-off-by: Sven Eckelmann -+Reviewed-by: Jiri Pirko -+Acked-by: Willem de Bruijn -+Signed-off-by: David S. Miller -+--- -+ -+--- a/net/core/flow_dissector.c -++++ b/net/core/flow_dissector.c -+@@ -22,6 +22,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ static void dissector_set_key(struct flow_dissector *flow_dissector, -+ enum flow_dissector_key_id key_id) -+@@ -338,6 +339,57 @@ __skb_flow_dissect_gre(const struct sk_b -+ return FLOW_DISSECT_RET_PROTO_AGAIN; -+ } -+ -++/** -++ * __skb_flow_dissect_batadv() - dissect batman-adv header -++ * @skb: sk_buff to with the batman-adv header -++ * @key_control: flow dissectors control key -++ * @data: raw buffer pointer to the packet, if NULL use skb->data -++ * @p_proto: pointer used to update the protocol to process next -++ * @p_nhoff: pointer used to update inner network header offset -++ * @hlen: packet header length -++ * @flags: any combination of FLOW_DISSECTOR_F_* -++ * -++ * ETH_P_BATMAN packets are tried to be dissected. Only -++ * &struct batadv_unicast packets are actually processed because they contain an -++ * inner ethernet header and are usually followed by actual network header. This -++ * allows the flow dissector to continue processing the packet. -++ * -++ * Return: FLOW_DISSECT_RET_PROTO_AGAIN when &struct batadv_unicast was found, -++ * FLOW_DISSECT_RET_OUT_GOOD when dissector should stop after encapsulation, -++ * otherwise FLOW_DISSECT_RET_OUT_BAD -++ */ -++static enum flow_dissect_ret -++__skb_flow_dissect_batadv(const struct sk_buff *skb, -++ struct flow_dissector_key_control *key_control, -++ void *data, __be16 *p_proto, int *p_nhoff, int hlen, -++ unsigned int flags) -++{ -++ struct { -++ struct batadv_unicast_packet batadv_unicast; -++ struct ethhdr eth; -++ } *hdr, _hdr; -++ -++ hdr = __skb_header_pointer(skb, *p_nhoff, sizeof(_hdr), data, hlen, -++ &_hdr); -++ if (!hdr) -++ return FLOW_DISSECT_RET_OUT_BAD; -++ -++ if (hdr->batadv_unicast.version != BATADV_COMPAT_VERSION) -++ return FLOW_DISSECT_RET_OUT_BAD; -++ -++ if (hdr->batadv_unicast.packet_type != BATADV_UNICAST) -++ return FLOW_DISSECT_RET_OUT_BAD; -++ -++ *p_proto = hdr->eth.h_proto; -++ *p_nhoff += sizeof(*hdr); -++ -++ key_control->flags |= FLOW_DIS_ENCAPSULATION; -++ if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) -++ return FLOW_DISSECT_RET_OUT_GOOD; -++ -++ return FLOW_DISSECT_RET_PROTO_AGAIN; -++} -++ -+ static void -+ __skb_flow_dissect_tcp(const struct sk_buff *skb, -+ struct flow_dissector *flow_dissector, -+@@ -718,6 +770,11 @@ proto_again: -+ nhoff, hlen); -+ break; -+ -++ case htons(ETH_P_BATMAN): -++ fdret = __skb_flow_dissect_batadv(skb, key_control, data, -++ &proto, &nhoff, hlen, flags); -++ break; -++ -+ default: -+ fdret = FLOW_DISSECT_RET_OUT_BAD; -+ break; -diff --git a/target/linux/generic/backport-4.14/289-v4.16-netfilter-add-defines-for-arp-decnet-max-hooks.patch b/target/linux/generic/backport-4.14/289-v4.16-netfilter-add-defines-for-arp-decnet-max-hooks.patch -new file mode 100644 -index 0000000000..f7898d4f30 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/289-v4.16-netfilter-add-defines-for-arp-decnet-max-hooks.patch -@@ -0,0 +1,67 @@ -+From e58f33cc84bc089c430ac955f3cad6380ae98591 Mon Sep 17 00:00:00 2001 -+From: Florian Westphal -+Date: Thu, 7 Dec 2017 16:28:23 +0100 -+Subject: [PATCH] netfilter: add defines for arp/decnet max hooks -+ -+The kernel already has defines for this, but they are in uapi exposed -+headers. -+ -+Including these from netns.h causes build errors and also adds unneeded -+dependencies on heads that we don't need. -+ -+So move these defines to netfilter_defs.h and place the uapi ones -+in ifndef __KERNEL__ to keep them for userspace. -+ -+Signed-off-by: Florian Westphal -+Signed-off-by: Pablo Neira Ayuso -+--- -+ include/linux/netfilter_defs.h | 6 ++++++ -+ include/uapi/linux/netfilter_arp.h | 3 +++ -+ include/uapi/linux/netfilter_decnet.h | 4 +++- -+ 3 files changed, 12 insertions(+), 1 deletion(-) -+ -+--- a/include/linux/netfilter_defs.h -++++ b/include/linux/netfilter_defs.h -+@@ -7,4 +7,10 @@ -+ /* Largest hook number + 1, see uapi/linux/netfilter_decnet.h */ -+ #define NF_MAX_HOOKS 8 -+ -++/* in/out/forward only */ -++#define NF_ARP_NUMHOOKS 3 -++ -++/* max hook is NF_DN_ROUTE (6), also see uapi/linux/netfilter_decnet.h */ -++#define NF_DN_NUMHOOKS 7 -++ -+ #endif -+--- a/include/uapi/linux/netfilter_arp.h -++++ b/include/uapi/linux/netfilter_arp.h -+@@ -15,6 +15,9 @@ -+ #define NF_ARP_IN 0 -+ #define NF_ARP_OUT 1 -+ #define NF_ARP_FORWARD 2 -++ -++#ifndef __KERNEL__ -+ #define NF_ARP_NUMHOOKS 3 -++#endif -+ -+ #endif /* __LINUX_ARP_NETFILTER_H */ -+--- a/include/uapi/linux/netfilter_decnet.h -++++ b/include/uapi/linux/netfilter_decnet.h -+@@ -24,6 +24,9 @@ -+ #define NFC_DN_IF_IN 0x0004 -+ /* Output device. */ -+ #define NFC_DN_IF_OUT 0x0008 -++ -++/* kernel define is in netfilter_defs.h */ -++#define NF_DN_NUMHOOKS 7 -+ #endif /* ! __KERNEL__ */ -+ -+ /* DECnet Hooks */ -+@@ -41,7 +44,6 @@ -+ #define NF_DN_HELLO 5 -+ /* Input Routing Packets */ -+ #define NF_DN_ROUTE 6 -+-#define NF_DN_NUMHOOKS 7 -+ -+ enum nf_dn_hook_priorities { -+ NF_DN_PRI_FIRST = INT_MIN, -diff --git a/target/linux/generic/backport-4.14/290-v4.16-netfilter-core-make-nf_unregister_net_hooks-simple-w.patch b/target/linux/generic/backport-4.14/290-v4.16-netfilter-core-make-nf_unregister_net_hooks-simple-w.patch -new file mode 100644 -index 0000000000..35800c4acf ---- /dev/null -+++ b/target/linux/generic/backport-4.14/290-v4.16-netfilter-core-make-nf_unregister_net_hooks-simple-w.patch -@@ -0,0 +1,91 @@ -+From 4e645b47c4f000a503b9c90163ad905786b9bc1d Mon Sep 17 00:00:00 2001 -+From: Florian Westphal -+Date: Fri, 1 Dec 2017 00:21:02 +0100 -+Subject: [PATCH 02/11] netfilter: core: make nf_unregister_net_hooks simple -+ wrapper again -+ -+This reverts commit d3ad2c17b4047 -+("netfilter: core: batch nf_unregister_net_hooks synchronize_net calls"). -+ -+Nothing wrong with it. However, followup patch will delay freeing of hooks -+with call_rcu, so all synchronize_net() calls become obsolete and there -+is no need anymore for this batching. -+ -+This revert causes a temporary performance degradation when destroying -+network namespace, but its resolved with the upcoming call_rcu conversion. -+ -+Signed-off-by: Florian Westphal -+Signed-off-by: Pablo Neira Ayuso -+--- -+ net/netfilter/core.c | 59 +++------------------------------------------------- -+ 1 file changed, 3 insertions(+), 56 deletions(-) -+ -+--- a/net/netfilter/core.c -++++ b/net/netfilter/core.c -+@@ -395,63 +395,10 @@ EXPORT_SYMBOL(nf_register_net_hooks); -+ void nf_unregister_net_hooks(struct net *net, const struct nf_hook_ops *reg, -+ unsigned int hookcount) -+ { -+- struct nf_hook_entries *to_free[16], *p; -+- struct nf_hook_entries __rcu **pp; -+- unsigned int i, j, n; -++ unsigned int i; -+ -+- mutex_lock(&nf_hook_mutex); -+- for (i = 0; i < hookcount; i++) { -+- pp = nf_hook_entry_head(net, ®[i]); -+- if (!pp) -+- continue; -+- -+- p = nf_entry_dereference(*pp); -+- if (WARN_ON_ONCE(!p)) -+- continue; -+- __nf_unregister_net_hook(p, ®[i]); -+- } -+- mutex_unlock(&nf_hook_mutex); -+- -+- do { -+- n = min_t(unsigned int, hookcount, ARRAY_SIZE(to_free)); -+- -+- mutex_lock(&nf_hook_mutex); -+- -+- for (i = 0, j = 0; i < hookcount && j < n; i++) { -+- pp = nf_hook_entry_head(net, ®[i]); -+- if (!pp) -+- continue; -+- -+- p = nf_entry_dereference(*pp); -+- if (!p) -+- continue; -+- -+- to_free[j] = __nf_hook_entries_try_shrink(pp); -+- if (to_free[j]) -+- ++j; -+- } -+- -+- mutex_unlock(&nf_hook_mutex); -+- -+- if (j) { -+- unsigned int nfq; -+- -+- synchronize_net(); -+- -+- /* need 2nd synchronize_net() if nfqueue is used, skb -+- * can get reinjected right before nf_queue_hook_drop() -+- */ -+- nfq = nf_queue_nf_hook_drop(net); -+- if (nfq) -+- synchronize_net(); -+- -+- for (i = 0; i < j; i++) -+- kvfree(to_free[i]); -+- } -+- -+- reg += n; -+- hookcount -= n; -+- } while (hookcount > 0); -++ for (i = 0; i < hookcount; i++) -++ nf_unregister_net_hook(net, ®[i]); -+ } -+ EXPORT_SYMBOL(nf_unregister_net_hooks); -+ -diff --git a/target/linux/generic/backport-4.14/291-v4.16-netfilter-core-remove-synchronize_net-call-if-nfqueu.patch b/target/linux/generic/backport-4.14/291-v4.16-netfilter-core-remove-synchronize_net-call-if-nfqueu.patch -new file mode 100644 -index 0000000000..0ac5783624 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/291-v4.16-netfilter-core-remove-synchronize_net-call-if-nfqueu.patch -@@ -0,0 +1,116 @@ -+From 26888dfd7e7454686b8d3ea9ba5045d5f236e4d7 Mon Sep 17 00:00:00 2001 -+From: Florian Westphal -+Date: Fri, 1 Dec 2017 00:21:03 +0100 -+Subject: [PATCH 03/11] netfilter: core: remove synchronize_net call if nfqueue -+ is used -+ -+since commit 960632ece6949b ("netfilter: convert hook list to an array") -+nfqueue no longer stores a pointer to the hook that caused the packet -+to be queued. Therefore no extra synchronize_net() call is needed after -+dropping the packets enqueued by the old rule blob. -+ -+Signed-off-by: Florian Westphal -+Signed-off-by: Pablo Neira Ayuso -+--- -+ include/net/netfilter/nf_queue.h | 2 +- -+ net/netfilter/core.c | 6 +----- -+ net/netfilter/nf_internals.h | 2 +- -+ net/netfilter/nf_queue.c | 7 ++----- -+ net/netfilter/nfnetlink_queue.c | 9 ++------- -+ 5 files changed, 7 insertions(+), 19 deletions(-) -+ -+--- a/include/net/netfilter/nf_queue.h -++++ b/include/net/netfilter/nf_queue.h -+@@ -25,7 +25,7 @@ struct nf_queue_entry { -+ struct nf_queue_handler { -+ int (*outfn)(struct nf_queue_entry *entry, -+ unsigned int queuenum); -+- unsigned int (*nf_hook_drop)(struct net *net); -++ void (*nf_hook_drop)(struct net *net); -+ }; -+ -+ void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh); -+--- a/net/netfilter/core.c -++++ b/net/netfilter/core.c -+@@ -341,7 +341,6 @@ void nf_unregister_net_hook(struct net * -+ { -+ struct nf_hook_entries __rcu **pp; -+ struct nf_hook_entries *p; -+- unsigned int nfq; -+ -+ pp = nf_hook_entry_head(net, reg); -+ if (!pp) -+@@ -364,10 +363,7 @@ void nf_unregister_net_hook(struct net * -+ -+ synchronize_net(); -+ -+- /* other cpu might still process nfqueue verdict that used reg */ -+- nfq = nf_queue_nf_hook_drop(net); -+- if (nfq) -+- synchronize_net(); -++ nf_queue_nf_hook_drop(net); -+ kvfree(p); -+ } -+ EXPORT_SYMBOL(nf_unregister_net_hook); -+--- a/net/netfilter/nf_internals.h -++++ b/net/netfilter/nf_internals.h -+@@ -10,7 +10,7 @@ -+ int nf_queue(struct sk_buff *skb, struct nf_hook_state *state, -+ const struct nf_hook_entries *entries, unsigned int index, -+ unsigned int verdict); -+-unsigned int nf_queue_nf_hook_drop(struct net *net); -++void nf_queue_nf_hook_drop(struct net *net); -+ -+ /* nf_log.c */ -+ int __init netfilter_log_init(void); -+--- a/net/netfilter/nf_queue.c -++++ b/net/netfilter/nf_queue.c -+@@ -96,18 +96,15 @@ void nf_queue_entry_get_refs(struct nf_q -+ } -+ EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs); -+ -+-unsigned int nf_queue_nf_hook_drop(struct net *net) -++void nf_queue_nf_hook_drop(struct net *net) -+ { -+ const struct nf_queue_handler *qh; -+- unsigned int count = 0; -+ -+ rcu_read_lock(); -+ qh = rcu_dereference(net->nf.queue_handler); -+ if (qh) -+- count = qh->nf_hook_drop(net); -++ qh->nf_hook_drop(net); -+ rcu_read_unlock(); -+- -+- return count; -+ } -+ EXPORT_SYMBOL_GPL(nf_queue_nf_hook_drop); -+ -+--- a/net/netfilter/nfnetlink_queue.c -++++ b/net/netfilter/nfnetlink_queue.c -+@@ -941,23 +941,18 @@ static struct notifier_block nfqnl_dev_n -+ .notifier_call = nfqnl_rcv_dev_event, -+ }; -+ -+-static unsigned int nfqnl_nf_hook_drop(struct net *net) -++static void nfqnl_nf_hook_drop(struct net *net) -+ { -+ struct nfnl_queue_net *q = nfnl_queue_pernet(net); -+- unsigned int instances = 0; -+ int i; -+ -+ for (i = 0; i < INSTANCE_BUCKETS; i++) { -+ struct nfqnl_instance *inst; -+ struct hlist_head *head = &q->instance_table[i]; -+ -+- hlist_for_each_entry_rcu(inst, head, hlist) { -++ hlist_for_each_entry_rcu(inst, head, hlist) -+ nfqnl_flush(inst, NULL, 0); -+- instances++; -+- } -+ } -+- -+- return instances; -+ } -+ -+ static int -diff --git a/target/linux/generic/backport-4.14/292-v4.16-netfilter-core-free-hooks-with-call_rcu.patch b/target/linux/generic/backport-4.14/292-v4.16-netfilter-core-free-hooks-with-call_rcu.patch -new file mode 100644 -index 0000000000..5eca73552b ---- /dev/null -+++ b/target/linux/generic/backport-4.14/292-v4.16-netfilter-core-free-hooks-with-call_rcu.patch -@@ -0,0 +1,132 @@ -+From 8c873e2199700c2de7dbd5eedb9d90d5f109462b Mon Sep 17 00:00:00 2001 -+From: Florian Westphal -+Date: Fri, 1 Dec 2017 00:21:04 +0100 -+Subject: [PATCH 04/11] netfilter: core: free hooks with call_rcu -+ -+Giuseppe Scrivano says: -+ "SELinux, if enabled, registers for each new network namespace 6 -+ netfilter hooks." -+ -+Cost for this is high. With synchronize_net() removed: -+ "The net benefit on an SMP machine with two cores is that creating a -+ new network namespace takes -40% of the original time." -+ -+This patch replaces synchronize_net+kvfree with call_rcu(). -+We store rcu_head at the tail of a structure that has no fixed layout, -+i.e. we cannot use offsetof() to compute the start of the original -+allocation. Thus store this information right after the rcu head. -+ -+We could simplify this by just placing the rcu_head at the start -+of struct nf_hook_entries. However, this structure is used in -+packet processing hotpath, so only place what is needed for that -+at the beginning of the struct. -+ -+Reported-by: Giuseppe Scrivano -+Signed-off-by: Florian Westphal -+Signed-off-by: Pablo Neira Ayuso -+--- -+ include/linux/netfilter.h | 19 +++++++++++++++---- -+ net/netfilter/core.c | 34 ++++++++++++++++++++++++++++------ -+ 2 files changed, 43 insertions(+), 10 deletions(-) -+ -+--- a/include/linux/netfilter.h -++++ b/include/linux/netfilter.h -+@@ -77,17 +77,28 @@ struct nf_hook_entry { -+ void *priv; -+ }; -+ -++struct nf_hook_entries_rcu_head { -++ struct rcu_head head; -++ void *allocation; -++}; -++ -+ struct nf_hook_entries { -+ u16 num_hook_entries; -+ /* padding */ -+ struct nf_hook_entry hooks[]; -+ -+- /* trailer: pointers to original orig_ops of each hook. -+- * -+- * This is not part of struct nf_hook_entry since its only -+- * needed in slow path (hook register/unregister). -++ /* trailer: pointers to original orig_ops of each hook, -++ * followed by rcu_head and scratch space used for freeing -++ * the structure via call_rcu. -+ * -++ * This is not part of struct nf_hook_entry since its only -++ * needed in slow path (hook register/unregister): -+ * const struct nf_hook_ops *orig_ops[] -++ * -++ * For the same reason, we store this at end -- its -++ * only needed when a hook is deleted, not during -++ * packet path processing: -++ * struct nf_hook_entries_rcu_head head -+ */ -+ }; -+ -+--- a/net/netfilter/core.c -++++ b/net/netfilter/core.c -+@@ -74,7 +74,8 @@ static struct nf_hook_entries *allocate_ -+ struct nf_hook_entries *e; -+ size_t alloc = sizeof(*e) + -+ sizeof(struct nf_hook_entry) * num + -+- sizeof(struct nf_hook_ops *) * num; -++ sizeof(struct nf_hook_ops *) * num + -++ sizeof(struct nf_hook_entries_rcu_head); -+ -+ if (num == 0) -+ return NULL; -+@@ -85,6 +86,30 @@ static struct nf_hook_entries *allocate_ -+ return e; -+ } -+ -++static void __nf_hook_entries_free(struct rcu_head *h) -++{ -++ struct nf_hook_entries_rcu_head *head; -++ -++ head = container_of(h, struct nf_hook_entries_rcu_head, head); -++ kvfree(head->allocation); -++} -++ -++static void nf_hook_entries_free(struct nf_hook_entries *e) -++{ -++ struct nf_hook_entries_rcu_head *head; -++ struct nf_hook_ops **ops; -++ unsigned int num; -++ -++ if (!e) -++ return; -++ -++ num = e->num_hook_entries; -++ ops = nf_hook_entries_get_hook_ops(e); -++ head = (void *)&ops[num]; -++ head->allocation = e; -++ call_rcu(&head->head, __nf_hook_entries_free); -++} -++ -+ static unsigned int accept_all(void *priv, -+ struct sk_buff *skb, -+ const struct nf_hook_state *state) -+@@ -291,9 +316,8 @@ int nf_register_net_hook(struct net *net -+ #ifdef HAVE_JUMP_LABEL -+ static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]); -+ #endif -+- synchronize_net(); -+ BUG_ON(p == new_hooks); -+- kvfree(p); -++ nf_hook_entries_free(p); -+ return 0; -+ } -+ EXPORT_SYMBOL(nf_register_net_hook); -+@@ -361,10 +385,8 @@ void nf_unregister_net_hook(struct net * -+ if (!p) -+ return; -+ -+- synchronize_net(); -+- -+ nf_queue_nf_hook_drop(net); -+- kvfree(p); -++ nf_hook_entries_free(p); -+ } -+ EXPORT_SYMBOL(nf_unregister_net_hook); -+ -diff --git a/target/linux/generic/backport-4.14/293-v4.16-netfilter-reduce-size-of-hook-entry-point-locations.patch b/target/linux/generic/backport-4.14/293-v4.16-netfilter-reduce-size-of-hook-entry-point-locations.patch -new file mode 100644 -index 0000000000..4b889120bf ---- /dev/null -+++ b/target/linux/generic/backport-4.14/293-v4.16-netfilter-reduce-size-of-hook-entry-point-locations.patch -@@ -0,0 +1,200 @@ -+From b0f38338aef2dae5ade3c16acf713737e3b15a73 Mon Sep 17 00:00:00 2001 -+From: Florian Westphal -+Date: Sun, 3 Dec 2017 00:58:47 +0100 -+Subject: [PATCH 05/11] netfilter: reduce size of hook entry point locations -+ -+struct net contains: -+ -+struct nf_hook_entries __rcu *hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; -+ -+which store the hook entry point locations for the various protocol -+families and the hooks. -+ -+Using array results in compact c code when doing accesses, i.e. -+ x = rcu_dereference(net->nf.hooks[pf][hook]); -+ -+but its also wasting a lot of memory, as most families are -+not used. -+ -+So split the array into those families that are used, which -+are only 5 (instead of 13). In most cases, the 'pf' argument is -+constant, i.e. gcc removes switch statement. -+ -+struct net before: -+ /* size: 5184, cachelines: 81, members: 46 */ -+after: -+ /* size: 4672, cachelines: 73, members: 46 */ -+ -+Signed-off-by: Florian Westphal -+Signed-off-by: Pablo Neira Ayuso -+--- -+ include/linux/netfilter.h | 24 ++++++++++++++++++++++-- -+ include/net/netns/netfilter.h | 6 +++++- -+ net/bridge/br_netfilter_hooks.c | 2 +- -+ net/netfilter/core.c | 38 ++++++++++++++++++++++++++++++-------- -+ net/netfilter/nf_queue.c | 21 +++++++++++++++++++-- -+ 5 files changed, 77 insertions(+), 14 deletions(-) -+ -+--- a/include/linux/netfilter.h -++++ b/include/linux/netfilter.h -+@@ -195,7 +195,7 @@ static inline int nf_hook(u_int8_t pf, u -+ struct net_device *indev, struct net_device *outdev, -+ int (*okfn)(struct net *, struct sock *, struct sk_buff *)) -+ { -+- struct nf_hook_entries *hook_head; -++ struct nf_hook_entries *hook_head = NULL; -+ int ret = 1; -+ -+ #ifdef HAVE_JUMP_LABEL -+@@ -206,7 +206,27 @@ static inline int nf_hook(u_int8_t pf, u -+ #endif -+ -+ rcu_read_lock(); -+- hook_head = rcu_dereference(net->nf.hooks[pf][hook]); -++ switch (pf) { -++ case NFPROTO_IPV4: -++ hook_head = rcu_dereference(net->nf.hooks_ipv4[hook]); -++ break; -++ case NFPROTO_IPV6: -++ hook_head = rcu_dereference(net->nf.hooks_ipv6[hook]); -++ break; -++ case NFPROTO_ARP: -++ hook_head = rcu_dereference(net->nf.hooks_arp[hook]); -++ break; -++ case NFPROTO_BRIDGE: -++ hook_head = rcu_dereference(net->nf.hooks_bridge[hook]); -++ break; -++ case NFPROTO_DECNET: -++ hook_head = rcu_dereference(net->nf.hooks_decnet[hook]); -++ break; -++ default: -++ WARN_ON_ONCE(1); -++ break; -++ } -++ -+ if (hook_head) { -+ struct nf_hook_state state; -+ -+--- a/include/net/netns/netfilter.h -++++ b/include/net/netns/netfilter.h -+@@ -17,7 +17,11 @@ struct netns_nf { -+ #ifdef CONFIG_SYSCTL -+ struct ctl_table_header *nf_log_dir_header; -+ #endif -+- struct nf_hook_entries __rcu *hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; -++ struct nf_hook_entries __rcu *hooks_ipv4[NF_MAX_HOOKS]; -++ struct nf_hook_entries __rcu *hooks_ipv6[NF_MAX_HOOKS]; -++ struct nf_hook_entries __rcu *hooks_arp[NF_MAX_HOOKS]; -++ struct nf_hook_entries __rcu *hooks_bridge[NF_MAX_HOOKS]; -++ struct nf_hook_entries __rcu *hooks_decnet[NF_MAX_HOOKS]; -+ #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) -+ bool defrag_ipv4; -+ #endif -+--- a/net/bridge/br_netfilter_hooks.c -++++ b/net/bridge/br_netfilter_hooks.c -+@@ -991,7 +991,7 @@ int br_nf_hook_thresh(unsigned int hook, -+ unsigned int i; -+ int ret; -+ -+- e = rcu_dereference(net->nf.hooks[NFPROTO_BRIDGE][hook]); -++ e = rcu_dereference(net->nf.hooks_bridge[hook]); -+ if (!e) -+ return okfn(net, sk, skb); -+ -+--- a/net/netfilter/core.c -++++ b/net/netfilter/core.c -+@@ -264,8 +264,23 @@ out_assign: -+ -+ static struct nf_hook_entries __rcu **nf_hook_entry_head(struct net *net, const struct nf_hook_ops *reg) -+ { -+- if (reg->pf != NFPROTO_NETDEV) -+- return net->nf.hooks[reg->pf]+reg->hooknum; -++ switch (reg->pf) { -++ case NFPROTO_NETDEV: -++ break; -++ case NFPROTO_ARP: -++ return net->nf.hooks_arp + reg->hooknum; -++ case NFPROTO_BRIDGE: -++ return net->nf.hooks_bridge + reg->hooknum; -++ case NFPROTO_IPV4: -++ return net->nf.hooks_ipv4 + reg->hooknum; -++ case NFPROTO_IPV6: -++ return net->nf.hooks_ipv6 + reg->hooknum; -++ case NFPROTO_DECNET: -++ return net->nf.hooks_decnet + reg->hooknum; -++ default: -++ WARN_ON_ONCE(1); -++ return NULL; -++ } -+ -+ #ifdef CONFIG_NETFILTER_INGRESS -+ if (reg->hooknum == NF_NETDEV_INGRESS) { -+@@ -534,14 +549,21 @@ void (*nf_nat_decode_session_hook)(struc -+ EXPORT_SYMBOL(nf_nat_decode_session_hook); -+ #endif -+ -+-static int __net_init netfilter_net_init(struct net *net) -++static void __net_init __netfilter_net_init(struct nf_hook_entries *e[NF_MAX_HOOKS]) -+ { -+- int i, h; -++ int h; -+ -+- for (i = 0; i < ARRAY_SIZE(net->nf.hooks); i++) { -+- for (h = 0; h < NF_MAX_HOOKS; h++) -+- RCU_INIT_POINTER(net->nf.hooks[i][h], NULL); -+- } -++ for (h = 0; h < NF_MAX_HOOKS; h++) -++ RCU_INIT_POINTER(e[h], NULL); -++} -++ -++static int __net_init netfilter_net_init(struct net *net) -++{ -++ __netfilter_net_init(net->nf.hooks_ipv4); -++ __netfilter_net_init(net->nf.hooks_ipv6); -++ __netfilter_net_init(net->nf.hooks_arp); -++ __netfilter_net_init(net->nf.hooks_bridge); -++ __netfilter_net_init(net->nf.hooks_decnet); -+ -+ #ifdef CONFIG_PROC_FS -+ net->nf.proc_netfilter = proc_net_mkdir(net, "netfilter", -+--- a/net/netfilter/nf_queue.c -++++ b/net/netfilter/nf_queue.c -+@@ -206,6 +206,23 @@ repeat: -+ return NF_ACCEPT; -+ } -+ -++static struct nf_hook_entries *nf_hook_entries_head(const struct net *net, u8 pf, u8 hooknum) -++{ -++ switch (pf) { -++ case NFPROTO_BRIDGE: -++ return rcu_dereference(net->nf.hooks_bridge[hooknum]); -++ case NFPROTO_IPV4: -++ return rcu_dereference(net->nf.hooks_ipv4[hooknum]); -++ case NFPROTO_IPV6: -++ return rcu_dereference(net->nf.hooks_ipv6[hooknum]); -++ default: -++ WARN_ON_ONCE(1); -++ return NULL; -++ } -++ -++ return NULL; -++} -++ -+ /* Caller must hold rcu read-side lock */ -+ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) -+ { -+@@ -221,12 +238,12 @@ void nf_reinject(struct nf_queue_entry * -+ net = entry->state.net; -+ pf = entry->state.pf; -+ -+- hooks = rcu_dereference(net->nf.hooks[pf][entry->state.hook]); -++ hooks = nf_hook_entries_head(net, pf, entry->state.hook); -+ -+ nf_queue_entry_release_refs(entry); -+ -+ i = entry->hook_index; -+- if (WARN_ON_ONCE(i >= hooks->num_hook_entries)) { -++ if (WARN_ON_ONCE(!hooks || i >= hooks->num_hook_entries)) { -+ kfree_skb(skb); -+ kfree(entry); -+ return; -diff --git a/target/linux/generic/backport-4.14/294-v4.16-netfilter-reduce-hook-array-sizes-to-what-is-needed.patch b/target/linux/generic/backport-4.14/294-v4.16-netfilter-reduce-hook-array-sizes-to-what-is-needed.patch -new file mode 100644 -index 0000000000..d9009b8e1f ---- /dev/null -+++ b/target/linux/generic/backport-4.14/294-v4.16-netfilter-reduce-hook-array-sizes-to-what-is-needed.patch -@@ -0,0 +1,95 @@ -+From ef57170bbfdd6958281011332b1fd237712f69f0 Mon Sep 17 00:00:00 2001 -+From: Florian Westphal -+Date: Thu, 7 Dec 2017 16:28:24 +0100 -+Subject: [PATCH 06/11] netfilter: reduce hook array sizes to what is needed -+ -+Not all families share the same hook count, adjust sizes to what is -+needed. -+ -+struct net before: -+/* size: 6592, cachelines: 103, members: 46 */ -+after: -+/* size: 5952, cachelines: 93, members: 46 */ -+ -+Signed-off-by: Florian Westphal -+Signed-off-by: Pablo Neira Ayuso -+--- -+ include/net/netns/netfilter.h | 10 +++++----- -+ net/netfilter/core.c | 24 +++++++++++++++++------- -+ 2 files changed, 22 insertions(+), 12 deletions(-) -+ -+--- a/include/net/netns/netfilter.h -++++ b/include/net/netns/netfilter.h -+@@ -17,11 +17,11 @@ struct netns_nf { -+ #ifdef CONFIG_SYSCTL -+ struct ctl_table_header *nf_log_dir_header; -+ #endif -+- struct nf_hook_entries __rcu *hooks_ipv4[NF_MAX_HOOKS]; -+- struct nf_hook_entries __rcu *hooks_ipv6[NF_MAX_HOOKS]; -+- struct nf_hook_entries __rcu *hooks_arp[NF_MAX_HOOKS]; -+- struct nf_hook_entries __rcu *hooks_bridge[NF_MAX_HOOKS]; -+- struct nf_hook_entries __rcu *hooks_decnet[NF_MAX_HOOKS]; -++ struct nf_hook_entries __rcu *hooks_ipv4[NF_INET_NUMHOOKS]; -++ struct nf_hook_entries __rcu *hooks_ipv6[NF_INET_NUMHOOKS]; -++ struct nf_hook_entries __rcu *hooks_arp[NF_ARP_NUMHOOKS]; -++ struct nf_hook_entries __rcu *hooks_bridge[NF_INET_NUMHOOKS]; -++ struct nf_hook_entries __rcu *hooks_decnet[NF_DN_NUMHOOKS]; -+ #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) -+ bool defrag_ipv4; -+ #endif -+--- a/net/netfilter/core.c -++++ b/net/netfilter/core.c -+@@ -268,14 +268,24 @@ static struct nf_hook_entries __rcu **nf -+ case NFPROTO_NETDEV: -+ break; -+ case NFPROTO_ARP: -++ if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_arp) <= reg->hooknum)) -++ return NULL; -+ return net->nf.hooks_arp + reg->hooknum; -+ case NFPROTO_BRIDGE: -++ if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_bridge) <= reg->hooknum)) -++ return NULL; -+ return net->nf.hooks_bridge + reg->hooknum; -+ case NFPROTO_IPV4: -++ if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv4) <= reg->hooknum)) -++ return NULL; -+ return net->nf.hooks_ipv4 + reg->hooknum; -+ case NFPROTO_IPV6: -++ if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv6) <= reg->hooknum)) -++ return NULL; -+ return net->nf.hooks_ipv6 + reg->hooknum; -+ case NFPROTO_DECNET: -++ if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_decnet) <= reg->hooknum)) -++ return NULL; -+ return net->nf.hooks_decnet + reg->hooknum; -+ default: -+ WARN_ON_ONCE(1); -+@@ -549,21 +559,21 @@ void (*nf_nat_decode_session_hook)(struc -+ EXPORT_SYMBOL(nf_nat_decode_session_hook); -+ #endif -+ -+-static void __net_init __netfilter_net_init(struct nf_hook_entries *e[NF_MAX_HOOKS]) -++static void __net_init __netfilter_net_init(struct nf_hook_entries **e, int max) -+ { -+ int h; -+ -+- for (h = 0; h < NF_MAX_HOOKS; h++) -++ for (h = 0; h < max; h++) -+ RCU_INIT_POINTER(e[h], NULL); -+ } -+ -+ static int __net_init netfilter_net_init(struct net *net) -+ { -+- __netfilter_net_init(net->nf.hooks_ipv4); -+- __netfilter_net_init(net->nf.hooks_ipv6); -+- __netfilter_net_init(net->nf.hooks_arp); -+- __netfilter_net_init(net->nf.hooks_bridge); -+- __netfilter_net_init(net->nf.hooks_decnet); -++ __netfilter_net_init(net->nf.hooks_ipv4, ARRAY_SIZE(net->nf.hooks_ipv4)); -++ __netfilter_net_init(net->nf.hooks_ipv6, ARRAY_SIZE(net->nf.hooks_ipv6)); -++ __netfilter_net_init(net->nf.hooks_arp, ARRAY_SIZE(net->nf.hooks_arp)); -++ __netfilter_net_init(net->nf.hooks_bridge, ARRAY_SIZE(net->nf.hooks_bridge)); -++ __netfilter_net_init(net->nf.hooks_decnet, ARRAY_SIZE(net->nf.hooks_decnet)); -+ -+ #ifdef CONFIG_PROC_FS -+ net->nf.proc_netfilter = proc_net_mkdir(net, "netfilter", -diff --git a/target/linux/generic/backport-4.14/295-v4.16-netfilter-don-t-allocate-space-for-decnet-hooks-unle.patch b/target/linux/generic/backport-4.14/295-v4.16-netfilter-don-t-allocate-space-for-decnet-hooks-unle.patch -new file mode 100644 -index 0000000000..26a93c40ae ---- /dev/null -+++ b/target/linux/generic/backport-4.14/295-v4.16-netfilter-don-t-allocate-space-for-decnet-hooks-unle.patch -@@ -0,0 +1,67 @@ -+From bb4badf3a3dc81190f7c1c1fa063cdefb18df45f Mon Sep 17 00:00:00 2001 -+From: Florian Westphal -+Date: Thu, 7 Dec 2017 16:28:25 +0100 -+Subject: [PATCH 07/11] netfilter: don't allocate space for decnet hooks unless -+ needed -+ -+no need to define hook points if the family isn't supported. -+ -+Signed-off-by: Florian Westphal -+Signed-off-by: Pablo Neira Ayuso -+--- -+ include/linux/netfilter.h | 2 ++ -+ include/net/netns/netfilter.h | 2 ++ -+ net/netfilter/core.c | 4 ++++ -+ 3 files changed, 8 insertions(+) -+ -+--- a/include/linux/netfilter.h -++++ b/include/linux/netfilter.h -+@@ -219,9 +219,11 @@ static inline int nf_hook(u_int8_t pf, u -+ case NFPROTO_BRIDGE: -+ hook_head = rcu_dereference(net->nf.hooks_bridge[hook]); -+ break; -++#if IS_ENABLED(CONFIG_DECNET) -+ case NFPROTO_DECNET: -+ hook_head = rcu_dereference(net->nf.hooks_decnet[hook]); -+ break; -++#endif -+ default: -+ WARN_ON_ONCE(1); -+ break; -+--- a/include/net/netns/netfilter.h -++++ b/include/net/netns/netfilter.h -+@@ -21,7 +21,9 @@ struct netns_nf { -+ struct nf_hook_entries __rcu *hooks_ipv6[NF_INET_NUMHOOKS]; -+ struct nf_hook_entries __rcu *hooks_arp[NF_ARP_NUMHOOKS]; -+ struct nf_hook_entries __rcu *hooks_bridge[NF_INET_NUMHOOKS]; -++#if IS_ENABLED(CONFIG_DECNET) -+ struct nf_hook_entries __rcu *hooks_decnet[NF_DN_NUMHOOKS]; -++#endif -+ #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) -+ bool defrag_ipv4; -+ #endif -+--- a/net/netfilter/core.c -++++ b/net/netfilter/core.c -+@@ -283,10 +283,12 @@ static struct nf_hook_entries __rcu **nf -+ if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv6) <= reg->hooknum)) -+ return NULL; -+ return net->nf.hooks_ipv6 + reg->hooknum; -++#if IS_ENABLED(CONFIG_DECNET) -+ case NFPROTO_DECNET: -+ if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_decnet) <= reg->hooknum)) -+ return NULL; -+ return net->nf.hooks_decnet + reg->hooknum; -++#endif -+ default: -+ WARN_ON_ONCE(1); -+ return NULL; -+@@ -573,7 +575,9 @@ static int __net_init netfilter_net_init -+ __netfilter_net_init(net->nf.hooks_ipv6, ARRAY_SIZE(net->nf.hooks_ipv6)); -+ __netfilter_net_init(net->nf.hooks_arp, ARRAY_SIZE(net->nf.hooks_arp)); -+ __netfilter_net_init(net->nf.hooks_bridge, ARRAY_SIZE(net->nf.hooks_bridge)); -++#if IS_ENABLED(CONFIG_DECNET) -+ __netfilter_net_init(net->nf.hooks_decnet, ARRAY_SIZE(net->nf.hooks_decnet)); -++#endif -+ -+ #ifdef CONFIG_PROC_FS -+ net->nf.proc_netfilter = proc_net_mkdir(net, "netfilter", -diff --git a/target/linux/generic/backport-4.14/296-v4.16-netfilter-don-t-allocate-space-for-arp-bridge-hooks-.patch b/target/linux/generic/backport-4.14/296-v4.16-netfilter-don-t-allocate-space-for-arp-bridge-hooks-.patch -new file mode 100644 -index 0000000000..41675c3494 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/296-v4.16-netfilter-don-t-allocate-space-for-arp-bridge-hooks-.patch -@@ -0,0 +1,165 @@ -+From 2a95183a5e0375df756efb2ca37602d71e8455f9 Mon Sep 17 00:00:00 2001 -+From: Florian Westphal -+Date: Thu, 7 Dec 2017 16:28:26 +0100 -+Subject: [PATCH 08/11] netfilter: don't allocate space for arp/bridge hooks -+ unless needed -+ -+no need to define hook points if the family isn't supported. -+Because we need these hooks for either nftables, arp/ebtables -+or the 'call-iptables' hack we have in the bridge layer add two -+new dependencies, NETFILTER_FAMILY_{ARP,BRIDGE}, and have the -+users select them. -+ -+Signed-off-by: Florian Westphal -+Signed-off-by: Pablo Neira Ayuso -+--- -+ include/linux/netfilter.h | 4 ++++ -+ include/net/netns/netfilter.h | 4 ++++ -+ net/Kconfig | 1 + -+ net/bridge/netfilter/Kconfig | 2 ++ -+ net/ipv4/netfilter/Kconfig | 2 ++ -+ net/netfilter/Kconfig | 6 ++++++ -+ net/netfilter/core.c | 8 ++++++++ -+ net/netfilter/nf_queue.c | 2 ++ -+ 8 files changed, 29 insertions(+) -+ -+--- a/include/linux/netfilter.h -++++ b/include/linux/netfilter.h -+@@ -214,10 +214,14 @@ static inline int nf_hook(u_int8_t pf, u -+ hook_head = rcu_dereference(net->nf.hooks_ipv6[hook]); -+ break; -+ case NFPROTO_ARP: -++#ifdef CONFIG_NETFILTER_FAMILY_ARP -+ hook_head = rcu_dereference(net->nf.hooks_arp[hook]); -++#endif -+ break; -+ case NFPROTO_BRIDGE: -++#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE -+ hook_head = rcu_dereference(net->nf.hooks_bridge[hook]); -++#endif -+ break; -+ #if IS_ENABLED(CONFIG_DECNET) -+ case NFPROTO_DECNET: -+--- a/include/net/netns/netfilter.h -++++ b/include/net/netns/netfilter.h -+@@ -19,8 +19,12 @@ struct netns_nf { -+ #endif -+ struct nf_hook_entries __rcu *hooks_ipv4[NF_INET_NUMHOOKS]; -+ struct nf_hook_entries __rcu *hooks_ipv6[NF_INET_NUMHOOKS]; -++#ifdef CONFIG_NETFILTER_FAMILY_ARP -+ struct nf_hook_entries __rcu *hooks_arp[NF_ARP_NUMHOOKS]; -++#endif -++#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE -+ struct nf_hook_entries __rcu *hooks_bridge[NF_INET_NUMHOOKS]; -++#endif -+ #if IS_ENABLED(CONFIG_DECNET) -+ struct nf_hook_entries __rcu *hooks_decnet[NF_DN_NUMHOOKS]; -+ #endif -+--- a/net/Kconfig -++++ b/net/Kconfig -+@@ -182,6 +182,7 @@ config BRIDGE_NETFILTER -+ depends on BRIDGE -+ depends on NETFILTER && INET -+ depends on NETFILTER_ADVANCED -++ select NETFILTER_FAMILY_BRIDGE -+ default m -+ ---help--- -+ Enabling this option will let arptables resp. iptables see bridged -+--- a/net/bridge/netfilter/Kconfig -++++ b/net/bridge/netfilter/Kconfig -+@@ -4,6 +4,7 @@ -+ # -+ menuconfig NF_TABLES_BRIDGE -+ depends on BRIDGE && NETFILTER && NF_TABLES -++ select NETFILTER_FAMILY_BRIDGE -+ tristate "Ethernet Bridge nf_tables support" -+ -+ if NF_TABLES_BRIDGE -+@@ -29,6 +30,7 @@ endif # NF_TABLES_BRIDGE -+ menuconfig BRIDGE_NF_EBTABLES -+ tristate "Ethernet Bridge tables (ebtables) support" -+ depends on BRIDGE && NETFILTER && NETFILTER_XTABLES -++ select NETFILTER_FAMILY_BRIDGE -+ help -+ ebtables is a general, extensible frame/packet identification -+ framework. Say 'Y' or 'M' here if you want to do Ethernet -+--- a/net/ipv4/netfilter/Kconfig -++++ b/net/ipv4/netfilter/Kconfig -+@@ -72,6 +72,7 @@ endif # NF_TABLES_IPV4 -+ -+ config NF_TABLES_ARP -+ tristate "ARP nf_tables support" -++ select NETFILTER_FAMILY_ARP -+ help -+ This option enables the ARP support for nf_tables. -+ -+@@ -392,6 +393,7 @@ endif # IP_NF_IPTABLES -+ config IP_NF_ARPTABLES -+ tristate "ARP tables support" -+ select NETFILTER_XTABLES -++ select NETFILTER_FAMILY_ARP -+ depends on NETFILTER_ADVANCED -+ help -+ arptables is a general, extensible packet identification framework. -+--- a/net/netfilter/Kconfig -++++ b/net/netfilter/Kconfig -+@@ -12,6 +12,12 @@ config NETFILTER_INGRESS -+ config NETFILTER_NETLINK -+ tristate -+ -++config NETFILTER_FAMILY_BRIDGE -++ bool -++ -++config NETFILTER_FAMILY_ARP -++ bool -++ -+ config NETFILTER_NETLINK_ACCT -+ tristate "Netfilter NFACCT over NFNETLINK interface" -+ depends on NETFILTER_ADVANCED -+--- a/net/netfilter/core.c -++++ b/net/netfilter/core.c -+@@ -267,14 +267,18 @@ static struct nf_hook_entries __rcu **nf -+ switch (reg->pf) { -+ case NFPROTO_NETDEV: -+ break; -++#ifdef CONFIG_NETFILTER_FAMILY_ARP -+ case NFPROTO_ARP: -+ if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_arp) <= reg->hooknum)) -+ return NULL; -+ return net->nf.hooks_arp + reg->hooknum; -++#endif -++#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE -+ case NFPROTO_BRIDGE: -+ if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_bridge) <= reg->hooknum)) -+ return NULL; -+ return net->nf.hooks_bridge + reg->hooknum; -++#endif -+ case NFPROTO_IPV4: -+ if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv4) <= reg->hooknum)) -+ return NULL; -+@@ -573,8 +577,12 @@ static int __net_init netfilter_net_init -+ { -+ __netfilter_net_init(net->nf.hooks_ipv4, ARRAY_SIZE(net->nf.hooks_ipv4)); -+ __netfilter_net_init(net->nf.hooks_ipv6, ARRAY_SIZE(net->nf.hooks_ipv6)); -++#ifdef CONFIG_NETFILTER_FAMILY_ARP -+ __netfilter_net_init(net->nf.hooks_arp, ARRAY_SIZE(net->nf.hooks_arp)); -++#endif -++#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE -+ __netfilter_net_init(net->nf.hooks_bridge, ARRAY_SIZE(net->nf.hooks_bridge)); -++#endif -+ #if IS_ENABLED(CONFIG_DECNET) -+ __netfilter_net_init(net->nf.hooks_decnet, ARRAY_SIZE(net->nf.hooks_decnet)); -+ #endif -+--- a/net/netfilter/nf_queue.c -++++ b/net/netfilter/nf_queue.c -+@@ -209,8 +209,10 @@ repeat: -+ static struct nf_hook_entries *nf_hook_entries_head(const struct net *net, u8 pf, u8 hooknum) -+ { -+ switch (pf) { -++#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE -+ case NFPROTO_BRIDGE: -+ return rcu_dereference(net->nf.hooks_bridge[hooknum]); -++#endif -+ case NFPROTO_IPV4: -+ return rcu_dereference(net->nf.hooks_ipv4[hooknum]); -+ case NFPROTO_IPV6: -diff --git a/target/linux/generic/backport-4.14/297-v4.16-netfilter-core-pass-hook-number-family-and-device-to.patch b/target/linux/generic/backport-4.14/297-v4.16-netfilter-core-pass-hook-number-family-and-device-to.patch -new file mode 100644 -index 0000000000..7d450f95f0 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/297-v4.16-netfilter-core-pass-hook-number-family-and-device-to.patch -@@ -0,0 +1,98 @@ -+From 62a0fe46e2aaba1812d3cbcae014a41539f9eb09 Mon Sep 17 00:00:00 2001 -+From: Pablo Neira Ayuso -+Date: Sat, 9 Dec 2017 15:23:51 +0100 -+Subject: [PATCH 09/11] netfilter: core: pass hook number, family and device to -+ nf_find_hook_list() -+ -+Instead of passing struct nf_hook_ops, this is needed by follow up -+patches to handle NFPROTO_INET from the core. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ net/netfilter/core.c | 36 +++++++++++++++++++----------------- -+ 1 file changed, 19 insertions(+), 17 deletions(-) -+ -+--- a/net/netfilter/core.c -++++ b/net/netfilter/core.c -+@@ -262,36 +262,38 @@ out_assign: -+ return old; -+ } -+ -+-static struct nf_hook_entries __rcu **nf_hook_entry_head(struct net *net, const struct nf_hook_ops *reg) -++static struct nf_hook_entries __rcu ** -++nf_hook_entry_head(struct net *net, int pf, unsigned int hooknum, -++ struct net_device *dev) -+ { -+- switch (reg->pf) { -++ switch (pf) { -+ case NFPROTO_NETDEV: -+ break; -+ #ifdef CONFIG_NETFILTER_FAMILY_ARP -+ case NFPROTO_ARP: -+- if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_arp) <= reg->hooknum)) -++ if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_arp) <= hooknum)) -+ return NULL; -+- return net->nf.hooks_arp + reg->hooknum; -++ return net->nf.hooks_arp + hooknum; -+ #endif -+ #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE -+ case NFPROTO_BRIDGE: -+- if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_bridge) <= reg->hooknum)) -++ if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_bridge) <= hooknum)) -+ return NULL; -+- return net->nf.hooks_bridge + reg->hooknum; -++ return net->nf.hooks_bridge + hooknum; -+ #endif -+ case NFPROTO_IPV4: -+- if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv4) <= reg->hooknum)) -++ if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv4) <= hooknum)) -+ return NULL; -+- return net->nf.hooks_ipv4 + reg->hooknum; -++ return net->nf.hooks_ipv4 + hooknum; -+ case NFPROTO_IPV6: -+- if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv6) <= reg->hooknum)) -++ if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv6) <= hooknum)) -+ return NULL; -+- return net->nf.hooks_ipv6 + reg->hooknum; -++ return net->nf.hooks_ipv6 + hooknum; -+ #if IS_ENABLED(CONFIG_DECNET) -+ case NFPROTO_DECNET: -+- if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_decnet) <= reg->hooknum)) -++ if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_decnet) <= hooknum)) -+ return NULL; -+- return net->nf.hooks_decnet + reg->hooknum; -++ return net->nf.hooks_decnet + hooknum; -+ #endif -+ default: -+ WARN_ON_ONCE(1); -+@@ -299,9 +301,9 @@ static struct nf_hook_entries __rcu **nf -+ } -+ -+ #ifdef CONFIG_NETFILTER_INGRESS -+- if (reg->hooknum == NF_NETDEV_INGRESS) { -+- if (reg->dev && dev_net(reg->dev) == net) -+- return ®->dev->nf_hooks_ingress; -++ if (hooknum == NF_NETDEV_INGRESS) { -++ if (dev && dev_net(dev) == net) -++ return &dev->nf_hooks_ingress; -+ } -+ #endif -+ WARN_ON_ONCE(1); -+@@ -323,7 +325,7 @@ int nf_register_net_hook(struct net *net -+ return -EINVAL; -+ } -+ -+- pp = nf_hook_entry_head(net, reg); -++ pp = nf_hook_entry_head(net, reg->pf, reg->hooknum, reg->dev); -+ if (!pp) -+ return -EINVAL; -+ -+@@ -397,7 +399,7 @@ void nf_unregister_net_hook(struct net * -+ struct nf_hook_entries __rcu **pp; -+ struct nf_hook_entries *p; -+ -+- pp = nf_hook_entry_head(net, reg); -++ pp = nf_hook_entry_head(net, reg->pf, reg->hooknum, reg->dev); -+ if (!pp) -+ return; -+ -diff --git a/target/linux/generic/backport-4.14/298-v4.16-netfilter-core-add-nf_remove_net_hook.patch b/target/linux/generic/backport-4.14/298-v4.16-netfilter-core-add-nf_remove_net_hook.patch -new file mode 100644 -index 0000000000..8fea44b359 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/298-v4.16-netfilter-core-add-nf_remove_net_hook.patch -@@ -0,0 +1,44 @@ -+From 3d3cdc38e8c265a9f9d3825e823e772872bca1b8 Mon Sep 17 00:00:00 2001 -+From: Pablo Neira Ayuso -+Date: Sat, 9 Dec 2017 15:19:14 +0100 -+Subject: [PATCH 01/11] netfilter: core: add nf_remove_net_hook -+ -+Just a cleanup, __nf_unregister_net_hook() is used by a follow up patch -+when handling NFPROTO_INET as a real family from the core. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ net/netfilter/core.c | 8 ++++---- -+ 1 file changed, 4 insertions(+), 4 deletions(-) -+ -+--- a/net/netfilter/core.c -++++ b/net/netfilter/core.c -+@@ -356,7 +356,7 @@ int nf_register_net_hook(struct net *net -+ EXPORT_SYMBOL(nf_register_net_hook); -+ -+ /* -+- * __nf_unregister_net_hook - remove a hook from blob -++ * nf_remove_net_hook - remove a hook from blob -+ * -+ * @oldp: current address of hook blob -+ * @unreg: hook to unregister -+@@ -364,8 +364,8 @@ EXPORT_SYMBOL(nf_register_net_hook); -+ * This cannot fail, hook unregistration must always succeed. -+ * Therefore replace the to-be-removed hook with a dummy hook. -+ */ -+-static void __nf_unregister_net_hook(struct nf_hook_entries *old, -+- const struct nf_hook_ops *unreg) -++static void nf_remove_net_hook(struct nf_hook_entries *old, -++ const struct nf_hook_ops *unreg) -+ { -+ struct nf_hook_ops **orig_ops; -+ bool found = false; -+@@ -411,7 +411,7 @@ void nf_unregister_net_hook(struct net * -+ return; -+ } -+ -+- __nf_unregister_net_hook(p, reg); -++ nf_remove_net_hook(p, reg); -+ -+ p = __nf_hook_entries_try_shrink(pp); -+ mutex_unlock(&nf_hook_mutex); -diff --git a/target/linux/generic/backport-4.14/298-v4.16-netfilter-core-pass-family-as-parameter-to-nf_remove.patch b/target/linux/generic/backport-4.14/298-v4.16-netfilter-core-pass-family-as-parameter-to-nf_remove.patch -new file mode 100644 -index 0000000000..4c52635c13 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/298-v4.16-netfilter-core-pass-family-as-parameter-to-nf_remove.patch -@@ -0,0 +1,51 @@ -+From 30259408118f550f5969fda19c0d67020d21eda8 Mon Sep 17 00:00:00 2001 -+From: Pablo Neira Ayuso -+Date: Sat, 9 Dec 2017 15:26:37 +0100 -+Subject: [PATCH 10/11] netfilter: core: pass family as parameter to -+ nf_remove_net_hook() -+ -+So static_key_slow_dec applies to the family behind NFPROTO_INET. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ net/netfilter/core.c | 10 +++++----- -+ 1 file changed, 5 insertions(+), 5 deletions(-) -+ -+--- a/net/netfilter/core.c -++++ b/net/netfilter/core.c -+@@ -365,7 +365,7 @@ EXPORT_SYMBOL(nf_register_net_hook); -+ * Therefore replace the to-be-removed hook with a dummy hook. -+ */ -+ static void nf_remove_net_hook(struct nf_hook_entries *old, -+- const struct nf_hook_ops *unreg) -++ const struct nf_hook_ops *unreg, int pf) -+ { -+ struct nf_hook_ops **orig_ops; -+ bool found = false; -+@@ -383,14 +383,14 @@ static void nf_remove_net_hook(struct nf -+ -+ if (found) { -+ #ifdef CONFIG_NETFILTER_INGRESS -+- if (unreg->pf == NFPROTO_NETDEV && unreg->hooknum == NF_NETDEV_INGRESS) -++ if (pf == NFPROTO_NETDEV && unreg->hooknum == NF_NETDEV_INGRESS) -+ net_dec_ingress_queue(); -+ #endif -+ #ifdef HAVE_JUMP_LABEL -+- static_key_slow_dec(&nf_hooks_needed[unreg->pf][unreg->hooknum]); -++ static_key_slow_dec(&nf_hooks_needed[pf][unreg->hooknum]); -+ #endif -+ } else { -+- WARN_ONCE(1, "hook not found, pf %d num %d", unreg->pf, unreg->hooknum); -++ WARN_ONCE(1, "hook not found, pf %d num %d", pf, unreg->hooknum); -+ } -+ } -+ -+@@ -411,7 +411,7 @@ void nf_unregister_net_hook(struct net * -+ return; -+ } -+ -+- nf_remove_net_hook(p, reg); -++ nf_remove_net_hook(p, reg, reg->pf); -+ -+ p = __nf_hook_entries_try_shrink(pp); -+ mutex_unlock(&nf_hook_mutex); -diff --git a/target/linux/generic/backport-4.14/299-v4.16-netfilter-core-support-for-NFPROTO_INET-hook-registr.patch b/target/linux/generic/backport-4.14/299-v4.16-netfilter-core-support-for-NFPROTO_INET-hook-registr.patch -new file mode 100644 -index 0000000000..b112855132 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/299-v4.16-netfilter-core-support-for-NFPROTO_INET-hook-registr.patch -@@ -0,0 +1,129 @@ -+From cb7ccd835ebb333669e400f99c650e4f3abf11c0 Mon Sep 17 00:00:00 2001 -+From: Pablo Neira Ayuso -+Date: Sat, 9 Dec 2017 15:30:26 +0100 -+Subject: [PATCH 11/11] netfilter: core: support for NFPROTO_INET hook -+ registration -+ -+Expand NFPROTO_INET in two hook registrations, one for NFPROTO_IPV4 and -+another for NFPROTO_IPV6. Hence, we handle NFPROTO_INET from the core. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ net/netfilter/core.c | 53 +++++++++++++++++++++++++++++++++++++++++++--------- -+ 1 file changed, 44 insertions(+), 9 deletions(-) -+ -+--- a/net/netfilter/core.c -++++ b/net/netfilter/core.c -+@@ -310,12 +310,13 @@ nf_hook_entry_head(struct net *net, int -+ return NULL; -+ } -+ -+-int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg) -++static int __nf_register_net_hook(struct net *net, int pf, -++ const struct nf_hook_ops *reg) -+ { -+ struct nf_hook_entries *p, *new_hooks; -+ struct nf_hook_entries __rcu **pp; -+ -+- if (reg->pf == NFPROTO_NETDEV) { -++ if (pf == NFPROTO_NETDEV) { -+ #ifndef CONFIG_NETFILTER_INGRESS -+ if (reg->hooknum == NF_NETDEV_INGRESS) -+ return -EOPNOTSUPP; -+@@ -325,7 +326,7 @@ int nf_register_net_hook(struct net *net -+ return -EINVAL; -+ } -+ -+- pp = nf_hook_entry_head(net, reg->pf, reg->hooknum, reg->dev); -++ pp = nf_hook_entry_head(net, pf, reg->hooknum, reg->dev); -+ if (!pp) -+ return -EINVAL; -+ -+@@ -343,17 +344,16 @@ int nf_register_net_hook(struct net *net -+ -+ hooks_validate(new_hooks); -+ #ifdef CONFIG_NETFILTER_INGRESS -+- if (reg->pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS) -++ if (pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS) -+ net_inc_ingress_queue(); -+ #endif -+ #ifdef HAVE_JUMP_LABEL -+- static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]); -++ static_key_slow_inc(&nf_hooks_needed[pf][reg->hooknum]); -+ #endif -+ BUG_ON(p == new_hooks); -+ nf_hook_entries_free(p); -+ return 0; -+ } -+-EXPORT_SYMBOL(nf_register_net_hook); -+ -+ /* -+ * nf_remove_net_hook - remove a hook from blob -+@@ -394,12 +394,13 @@ static void nf_remove_net_hook(struct nf -+ } -+ } -+ -+-void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg) -++void __nf_unregister_net_hook(struct net *net, int pf, -++ const struct nf_hook_ops *reg) -+ { -+ struct nf_hook_entries __rcu **pp; -+ struct nf_hook_entries *p; -+ -+- pp = nf_hook_entry_head(net, reg->pf, reg->hooknum, reg->dev); -++ pp = nf_hook_entry_head(net, pf, reg->hooknum, reg->dev); -+ if (!pp) -+ return; -+ -+@@ -411,7 +412,7 @@ void nf_unregister_net_hook(struct net * -+ return; -+ } -+ -+- nf_remove_net_hook(p, reg, reg->pf); -++ nf_remove_net_hook(p, reg, pf); -+ -+ p = __nf_hook_entries_try_shrink(pp); -+ mutex_unlock(&nf_hook_mutex); -+@@ -421,8 +422,42 @@ void nf_unregister_net_hook(struct net * -+ nf_queue_nf_hook_drop(net); -+ nf_hook_entries_free(p); -+ } -++ -++void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg) -++{ -++ if (reg->pf == NFPROTO_INET) { -++ __nf_unregister_net_hook(net, NFPROTO_IPV4, reg); -++ __nf_unregister_net_hook(net, NFPROTO_IPV6, reg); -++ } else { -++ __nf_unregister_net_hook(net, reg->pf, reg); -++ } -++} -+ EXPORT_SYMBOL(nf_unregister_net_hook); -+ -++int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg) -++{ -++ int err; -++ -++ if (reg->pf == NFPROTO_INET) { -++ err = __nf_register_net_hook(net, NFPROTO_IPV4, reg); -++ if (err < 0) -++ return err; -++ -++ err = __nf_register_net_hook(net, NFPROTO_IPV6, reg); -++ if (err < 0) { -++ __nf_unregister_net_hook(net, NFPROTO_IPV4, reg); -++ return err; -++ } -++ } else { -++ err = __nf_register_net_hook(net, reg->pf, reg); -++ if (err < 0) -++ return err; -++ } -++ -++ return 0; -++} -++EXPORT_SYMBOL(nf_register_net_hook); -++ -+ int nf_register_net_hooks(struct net *net, const struct nf_hook_ops *reg, -+ unsigned int n) -+ { -diff --git a/target/linux/generic/backport-4.14/300-v4.16-netfilter-nf_tables-explicit-nft_set_pktinfo-call-fr.patch b/target/linux/generic/backport-4.14/300-v4.16-netfilter-nf_tables-explicit-nft_set_pktinfo-call-fr.patch -new file mode 100644 -index 0000000000..c0cb5bbeba ---- /dev/null -+++ b/target/linux/generic/backport-4.14/300-v4.16-netfilter-nf_tables-explicit-nft_set_pktinfo-call-fr.patch -@@ -0,0 +1,291 @@ -+From: Pablo Neira Ayuso -+Date: Sun, 10 Dec 2017 01:43:14 +0100 -+Subject: [PATCH] netfilter: nf_tables: explicit nft_set_pktinfo() call from -+ hook path -+ -+Instead of calling this function from the family specific variant, this -+reduces the code size in the fast path for the netdev, bridge and inet -+families. After this change, we must call nft_set_pktinfo() upfront from -+the chain hook indirection. -+ -+Before: -+ -+ text data bss dec hex filename -+ 2145 208 0 2353 931 net/netfilter/nf_tables_netdev.o -+ -+After: -+ -+ text data bss dec hex filename -+ 2125 208 0 2333 91d net/netfilter/nf_tables_netdev.o -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/net/netfilter/nf_tables.h -++++ b/include/net/netfilter/nf_tables.h -+@@ -54,8 +54,8 @@ static inline void nft_set_pktinfo(struc -+ pkt->xt.state = state; -+ } -+ -+-static inline void nft_set_pktinfo_proto_unspec(struct nft_pktinfo *pkt, -+- struct sk_buff *skb) -++static inline void nft_set_pktinfo_unspec(struct nft_pktinfo *pkt, -++ struct sk_buff *skb) -+ { -+ pkt->tprot_set = false; -+ pkt->tprot = 0; -+@@ -63,14 +63,6 @@ static inline void nft_set_pktinfo_proto -+ pkt->xt.fragoff = 0; -+ } -+ -+-static inline void nft_set_pktinfo_unspec(struct nft_pktinfo *pkt, -+- struct sk_buff *skb, -+- const struct nf_hook_state *state) -+-{ -+- nft_set_pktinfo(pkt, skb, state); -+- nft_set_pktinfo_proto_unspec(pkt, skb); -+-} -+- -+ /** -+ * struct nft_verdict - nf_tables verdict -+ * -+--- a/include/net/netfilter/nf_tables_ipv4.h -++++ b/include/net/netfilter/nf_tables_ipv4.h -+@@ -5,15 +5,11 @@ -+ #include -+ #include -+ -+-static inline void -+-nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt, -+- struct sk_buff *skb, -+- const struct nf_hook_state *state) -++static inline void nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt, -++ struct sk_buff *skb) -+ { -+ struct iphdr *ip; -+ -+- nft_set_pktinfo(pkt, skb, state); -+- -+ ip = ip_hdr(pkt->skb); -+ pkt->tprot_set = true; -+ pkt->tprot = ip->protocol; -+@@ -21,10 +17,8 @@ nft_set_pktinfo_ipv4(struct nft_pktinfo -+ pkt->xt.fragoff = ntohs(ip->frag_off) & IP_OFFSET; -+ } -+ -+-static inline int -+-__nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt, -+- struct sk_buff *skb, -+- const struct nf_hook_state *state) -++static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt, -++ struct sk_buff *skb) -+ { -+ struct iphdr *iph, _iph; -+ u32 len, thoff; -+@@ -52,14 +46,11 @@ __nft_set_pktinfo_ipv4_validate(struct n -+ return 0; -+ } -+ -+-static inline void -+-nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt, -+- struct sk_buff *skb, -+- const struct nf_hook_state *state) -++static inline void nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt, -++ struct sk_buff *skb) -+ { -+- nft_set_pktinfo(pkt, skb, state); -+- if (__nft_set_pktinfo_ipv4_validate(pkt, skb, state) < 0) -+- nft_set_pktinfo_proto_unspec(pkt, skb); -++ if (__nft_set_pktinfo_ipv4_validate(pkt, skb) < 0) -++ nft_set_pktinfo_unspec(pkt, skb); -+ } -+ -+ extern struct nft_af_info nft_af_ipv4; -+--- a/include/net/netfilter/nf_tables_ipv6.h -++++ b/include/net/netfilter/nf_tables_ipv6.h -+@@ -5,20 +5,16 @@ -+ #include -+ #include -+ -+-static inline void -+-nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt, -+- struct sk_buff *skb, -+- const struct nf_hook_state *state) -++static inline void nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt, -++ struct sk_buff *skb) -+ { -+ unsigned int flags = IP6_FH_F_AUTH; -+ int protohdr, thoff = 0; -+ unsigned short frag_off; -+ -+- nft_set_pktinfo(pkt, skb, state); -+- -+ protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, &flags); -+ if (protohdr < 0) { -+- nft_set_pktinfo_proto_unspec(pkt, skb); -++ nft_set_pktinfo_unspec(pkt, skb); -+ return; -+ } -+ -+@@ -28,10 +24,8 @@ nft_set_pktinfo_ipv6(struct nft_pktinfo -+ pkt->xt.fragoff = frag_off; -+ } -+ -+-static inline int -+-__nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt, -+- struct sk_buff *skb, -+- const struct nf_hook_state *state) -++static inline int __nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt, -++ struct sk_buff *skb) -+ { -+ #if IS_ENABLED(CONFIG_IPV6) -+ unsigned int flags = IP6_FH_F_AUTH; -+@@ -68,14 +62,11 @@ __nft_set_pktinfo_ipv6_validate(struct n -+ #endif -+ } -+ -+-static inline void -+-nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt, -+- struct sk_buff *skb, -+- const struct nf_hook_state *state) -++static inline void nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt, -++ struct sk_buff *skb) -+ { -+- nft_set_pktinfo(pkt, skb, state); -+- if (__nft_set_pktinfo_ipv6_validate(pkt, skb, state) < 0) -+- nft_set_pktinfo_proto_unspec(pkt, skb); -++ if (__nft_set_pktinfo_ipv6_validate(pkt, skb) < 0) -++ nft_set_pktinfo_unspec(pkt, skb); -+ } -+ -+ extern struct nft_af_info nft_af_ipv6; -+--- a/net/bridge/netfilter/nf_tables_bridge.c -++++ b/net/bridge/netfilter/nf_tables_bridge.c -+@@ -25,15 +25,17 @@ nft_do_chain_bridge(void *priv, -+ { -+ struct nft_pktinfo pkt; -+ -++ nft_set_pktinfo(&pkt, skb, state); -++ -+ switch (eth_hdr(skb)->h_proto) { -+ case htons(ETH_P_IP): -+- nft_set_pktinfo_ipv4_validate(&pkt, skb, state); -++ nft_set_pktinfo_ipv4_validate(&pkt, skb); -+ break; -+ case htons(ETH_P_IPV6): -+- nft_set_pktinfo_ipv6_validate(&pkt, skb, state); -++ nft_set_pktinfo_ipv6_validate(&pkt, skb); -+ break; -+ default: -+- nft_set_pktinfo_unspec(&pkt, skb, state); -++ nft_set_pktinfo_unspec(&pkt, skb); -+ break; -+ } -+ -+--- a/net/ipv4/netfilter/nf_tables_arp.c -++++ b/net/ipv4/netfilter/nf_tables_arp.c -+@@ -21,7 +21,8 @@ nft_do_chain_arp(void *priv, -+ { -+ struct nft_pktinfo pkt; -+ -+- nft_set_pktinfo_unspec(&pkt, skb, state); -++ nft_set_pktinfo(&pkt, skb, state); -++ nft_set_pktinfo_unspec(&pkt, skb); -+ -+ return nft_do_chain(&pkt, priv); -+ } -+--- a/net/ipv4/netfilter/nf_tables_ipv4.c -++++ b/net/ipv4/netfilter/nf_tables_ipv4.c -+@@ -24,7 +24,8 @@ static unsigned int nft_do_chain_ipv4(vo -+ { -+ struct nft_pktinfo pkt; -+ -+- nft_set_pktinfo_ipv4(&pkt, skb, state); -++ nft_set_pktinfo(&pkt, skb, state); -++ nft_set_pktinfo_ipv4(&pkt, skb); -+ -+ return nft_do_chain(&pkt, priv); -+ } -+--- a/net/ipv4/netfilter/nft_chain_nat_ipv4.c -++++ b/net/ipv4/netfilter/nft_chain_nat_ipv4.c -+@@ -33,7 +33,8 @@ static unsigned int nft_nat_do_chain(voi -+ { -+ struct nft_pktinfo pkt; -+ -+- nft_set_pktinfo_ipv4(&pkt, skb, state); -++ nft_set_pktinfo(&pkt, skb, state); -++ nft_set_pktinfo_ipv4(&pkt, skb); -+ -+ return nft_do_chain(&pkt, priv); -+ } -+--- a/net/ipv4/netfilter/nft_chain_route_ipv4.c -++++ b/net/ipv4/netfilter/nft_chain_route_ipv4.c -+@@ -38,7 +38,8 @@ static unsigned int nf_route_table_hook( -+ ip_hdrlen(skb) < sizeof(struct iphdr)) -+ return NF_ACCEPT; -+ -+- nft_set_pktinfo_ipv4(&pkt, skb, state); -++ nft_set_pktinfo(&pkt, skb, state); -++ nft_set_pktinfo_ipv4(&pkt, skb); -+ -+ mark = skb->mark; -+ iph = ip_hdr(skb); -+--- a/net/ipv6/netfilter/nf_tables_ipv6.c -++++ b/net/ipv6/netfilter/nf_tables_ipv6.c -+@@ -22,7 +22,8 @@ static unsigned int nft_do_chain_ipv6(vo -+ { -+ struct nft_pktinfo pkt; -+ -+- nft_set_pktinfo_ipv6(&pkt, skb, state); -++ nft_set_pktinfo(&pkt, skb, state); -++ nft_set_pktinfo_ipv6(&pkt, skb); -+ -+ return nft_do_chain(&pkt, priv); -+ } -+--- a/net/ipv6/netfilter/nft_chain_nat_ipv6.c -++++ b/net/ipv6/netfilter/nft_chain_nat_ipv6.c -+@@ -31,7 +31,8 @@ static unsigned int nft_nat_do_chain(voi -+ { -+ struct nft_pktinfo pkt; -+ -+- nft_set_pktinfo_ipv6(&pkt, skb, state); -++ nft_set_pktinfo(&pkt, skb, state); -++ nft_set_pktinfo_ipv6(&pkt, skb); -+ -+ return nft_do_chain(&pkt, priv); -+ } -+--- a/net/ipv6/netfilter/nft_chain_route_ipv6.c -++++ b/net/ipv6/netfilter/nft_chain_route_ipv6.c -+@@ -33,7 +33,8 @@ static unsigned int nf_route_table_hook( -+ u32 mark, flowlabel; -+ int err; -+ -+- nft_set_pktinfo_ipv6(&pkt, skb, state); -++ nft_set_pktinfo(&pkt, skb, state); -++ nft_set_pktinfo_ipv6(&pkt, skb); -+ -+ /* save source/dest address, mark, hoplimit, flowlabel, priority */ -+ memcpy(&saddr, &ipv6_hdr(skb)->saddr, sizeof(saddr)); -+--- a/net/netfilter/nf_tables_netdev.c -++++ b/net/netfilter/nf_tables_netdev.c -+@@ -21,15 +21,17 @@ nft_do_chain_netdev(void *priv, struct s -+ { -+ struct nft_pktinfo pkt; -+ -++ nft_set_pktinfo(&pkt, skb, state); -++ -+ switch (skb->protocol) { -+ case htons(ETH_P_IP): -+- nft_set_pktinfo_ipv4_validate(&pkt, skb, state); -++ nft_set_pktinfo_ipv4_validate(&pkt, skb); -+ break; -+ case htons(ETH_P_IPV6): -+- nft_set_pktinfo_ipv6_validate(&pkt, skb, state); -++ nft_set_pktinfo_ipv6_validate(&pkt, skb); -+ break; -+ default: -+- nft_set_pktinfo_unspec(&pkt, skb, state); -++ nft_set_pktinfo_unspec(&pkt, skb); -+ break; -+ } -+ -diff --git a/target/linux/generic/backport-4.14/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch b/target/linux/generic/backport-4.14/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch -new file mode 100644 -index 0000000000..80fd3678af ---- /dev/null -+++ b/target/linux/generic/backport-4.14/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch -@@ -0,0 +1,146 @@ -+From: Florian Westphal -+Date: Fri, 8 Dec 2017 17:01:54 +0100 -+Subject: [PATCH] netfilter: core: only allow one nat hook per hook point -+ -+The netfilter NAT core cannot deal with more than one NAT hook per hook -+location (prerouting, input ...), because the NAT hooks install a NAT null -+binding in case the iptables nat table (iptable_nat hooks) or the -+corresponding nftables chain (nft nat hooks) doesn't specify a nat -+transformation. -+ -+Null bindings are needed to detect port collsisions between NAT-ed and -+non-NAT-ed connections. -+ -+This causes nftables NAT rules to not work when iptable_nat module is -+loaded, and vice versa because nat binding has already been attached -+when the second nat hook is consulted. -+ -+The netfilter core is not really the correct location to handle this -+(hooks are just hooks, the core has no notion of what kinds of side -+ effects a hook implements), but its the only place where we can check -+for conflicts between both iptables hooks and nftables hooks without -+adding dependencies. -+ -+So add nat annotation to hook_ops to describe those hooks that will -+add NAT bindings and then make core reject if such a hook already exists. -+The annotation fills a padding hole, in case further restrictions appar -+we might change this to a 'u8 type' instead of bool. -+ -+iptables error if nft nat hook active: -+iptables -t nat -A POSTROUTING -j MASQUERADE -+iptables v1.4.21: can't initialize iptables table `nat': File exists -+Perhaps iptables or your kernel needs to be upgraded. -+ -+nftables error if iptables nat table present: -+nft -f /etc/nftables/ipv4-nat -+/usr/etc/nftables/ipv4-nat:3:1-2: Error: Could not process rule: File exists -+table nat { -+^^ -+ -+Signed-off-by: Florian Westphal -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/linux/netfilter.h -++++ b/include/linux/netfilter.h -+@@ -67,6 +67,7 @@ struct nf_hook_ops { -+ struct net_device *dev; -+ void *priv; -+ u_int8_t pf; -++ bool nat_hook; -+ unsigned int hooknum; -+ /* Hooks are ordered in ascending priority. */ -+ int priority; -+--- a/net/ipv4/netfilter/iptable_nat.c -++++ b/net/ipv4/netfilter/iptable_nat.c -+@@ -72,6 +72,7 @@ static const struct nf_hook_ops nf_nat_i -+ { -+ .hook = iptable_nat_ipv4_in, -+ .pf = NFPROTO_IPV4, -++ .nat_hook = true, -+ .hooknum = NF_INET_PRE_ROUTING, -+ .priority = NF_IP_PRI_NAT_DST, -+ }, -+@@ -79,6 +80,7 @@ static const struct nf_hook_ops nf_nat_i -+ { -+ .hook = iptable_nat_ipv4_out, -+ .pf = NFPROTO_IPV4, -++ .nat_hook = true, -+ .hooknum = NF_INET_POST_ROUTING, -+ .priority = NF_IP_PRI_NAT_SRC, -+ }, -+@@ -86,6 +88,7 @@ static const struct nf_hook_ops nf_nat_i -+ { -+ .hook = iptable_nat_ipv4_local_fn, -+ .pf = NFPROTO_IPV4, -++ .nat_hook = true, -+ .hooknum = NF_INET_LOCAL_OUT, -+ .priority = NF_IP_PRI_NAT_DST, -+ }, -+@@ -93,6 +96,7 @@ static const struct nf_hook_ops nf_nat_i -+ { -+ .hook = iptable_nat_ipv4_fn, -+ .pf = NFPROTO_IPV4, -++ .nat_hook = true, -+ .hooknum = NF_INET_LOCAL_IN, -+ .priority = NF_IP_PRI_NAT_SRC, -+ }, -+--- a/net/ipv6/netfilter/ip6table_nat.c -++++ b/net/ipv6/netfilter/ip6table_nat.c -+@@ -74,6 +74,7 @@ static const struct nf_hook_ops nf_nat_i -+ { -+ .hook = ip6table_nat_in, -+ .pf = NFPROTO_IPV6, -++ .nat_hook = true, -+ .hooknum = NF_INET_PRE_ROUTING, -+ .priority = NF_IP6_PRI_NAT_DST, -+ }, -+@@ -81,6 +82,7 @@ static const struct nf_hook_ops nf_nat_i -+ { -+ .hook = ip6table_nat_out, -+ .pf = NFPROTO_IPV6, -++ .nat_hook = true, -+ .hooknum = NF_INET_POST_ROUTING, -+ .priority = NF_IP6_PRI_NAT_SRC, -+ }, -+@@ -88,12 +90,14 @@ static const struct nf_hook_ops nf_nat_i -+ { -+ .hook = ip6table_nat_local_fn, -+ .pf = NFPROTO_IPV6, -++ .nat_hook = true, -+ .hooknum = NF_INET_LOCAL_OUT, -+ .priority = NF_IP6_PRI_NAT_DST, -+ }, -+ /* After packet filtering, change source */ -+ { -+ .hook = ip6table_nat_fn, -++ .nat_hook = true, -+ .pf = NFPROTO_IPV6, -+ .hooknum = NF_INET_LOCAL_IN, -+ .priority = NF_IP6_PRI_NAT_SRC, -+--- a/net/netfilter/core.c -++++ b/net/netfilter/core.c -+@@ -160,6 +160,12 @@ nf_hook_entries_grow(const struct nf_hoo -+ ++i; -+ continue; -+ } -++ -++ if (reg->nat_hook && orig_ops[i]->nat_hook) { -++ kvfree(new); -++ return ERR_PTR(-EEXIST); -++ } -++ -+ if (inserted || reg->priority > orig_ops[i]->priority) { -+ new_ops[nhooks] = (void *)orig_ops[i]; -+ new->hooks[nhooks] = old->hooks[i]; -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -1446,6 +1446,8 @@ static int nf_tables_addchain(struct nft -+ ops->hook = hookfn; -+ if (afi->hook_ops_init) -+ afi->hook_ops_init(ops, i); -++ if (basechain->type->type == NFT_CHAIN_T_NAT) -++ ops->nat_hook = true; -+ } -+ -+ chain->flags |= NFT_BASE_CHAIN; -diff --git a/target/linux/generic/backport-4.14/302-v4.16-netfilter-nf_tables_inet-don-t-use-multihook-infrast.patch b/target/linux/generic/backport-4.14/302-v4.16-netfilter-nf_tables_inet-don-t-use-multihook-infrast.patch -new file mode 100644 -index 0000000000..17d8b21a0f ---- /dev/null -+++ b/target/linux/generic/backport-4.14/302-v4.16-netfilter-nf_tables_inet-don-t-use-multihook-infrast.patch -@@ -0,0 +1,161 @@ -+From: Pablo Neira Ayuso -+Date: Sat, 9 Dec 2017 15:36:24 +0100 -+Subject: [PATCH] netfilter: nf_tables_inet: don't use multihook infrastructure -+ anymore -+ -+Use new native NFPROTO_INET support in netfilter core, this gets rid of -+ad-hoc code in the nf_tables API codebase. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/net/netfilter/nf_tables_ipv4.h -++++ b/include/net/netfilter/nf_tables_ipv4.h -+@@ -53,6 +53,4 @@ static inline void nft_set_pktinfo_ipv4_ -+ nft_set_pktinfo_unspec(pkt, skb); -+ } -+ -+-extern struct nft_af_info nft_af_ipv4; -+- -+ #endif -+--- a/include/net/netfilter/nf_tables_ipv6.h -++++ b/include/net/netfilter/nf_tables_ipv6.h -+@@ -69,6 +69,4 @@ static inline void nft_set_pktinfo_ipv6_ -+ nft_set_pktinfo_unspec(pkt, skb); -+ } -+ -+-extern struct nft_af_info nft_af_ipv6; -+- -+ #endif -+--- a/net/ipv4/netfilter/nf_tables_ipv4.c -++++ b/net/ipv4/netfilter/nf_tables_ipv4.c -+@@ -45,7 +45,7 @@ static unsigned int nft_ipv4_output(void -+ return nft_do_chain_ipv4(priv, skb, state); -+ } -+ -+-struct nft_af_info nft_af_ipv4 __read_mostly = { -++static struct nft_af_info nft_af_ipv4 __read_mostly = { -+ .family = NFPROTO_IPV4, -+ .nhooks = NF_INET_NUMHOOKS, -+ .owner = THIS_MODULE, -+@@ -58,7 +58,6 @@ struct nft_af_info nft_af_ipv4 __read_mo -+ [NF_INET_POST_ROUTING] = nft_do_chain_ipv4, -+ }, -+ }; -+-EXPORT_SYMBOL_GPL(nft_af_ipv4); -+ -+ static int nf_tables_ipv4_init_net(struct net *net) -+ { -+--- a/net/ipv6/netfilter/nf_tables_ipv6.c -++++ b/net/ipv6/netfilter/nf_tables_ipv6.c -+@@ -42,7 +42,7 @@ static unsigned int nft_ipv6_output(void -+ return nft_do_chain_ipv6(priv, skb, state); -+ } -+ -+-struct nft_af_info nft_af_ipv6 __read_mostly = { -++static struct nft_af_info nft_af_ipv6 __read_mostly = { -+ .family = NFPROTO_IPV6, -+ .nhooks = NF_INET_NUMHOOKS, -+ .owner = THIS_MODULE, -+@@ -55,7 +55,6 @@ struct nft_af_info nft_af_ipv6 __read_mo -+ [NF_INET_POST_ROUTING] = nft_do_chain_ipv6, -+ }, -+ }; -+-EXPORT_SYMBOL_GPL(nft_af_ipv6); -+ -+ static int nf_tables_ipv6_init_net(struct net *net) -+ { -+--- a/net/netfilter/nf_tables_inet.c -++++ b/net/netfilter/nf_tables_inet.c -+@@ -9,6 +9,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ #include -+@@ -16,26 +17,71 @@ -+ #include -+ #include -+ -+-static void nft_inet_hook_ops_init(struct nf_hook_ops *ops, unsigned int n) -++static unsigned int nft_do_chain_inet(void *priv, struct sk_buff *skb, -++ const struct nf_hook_state *state) -+ { -+- struct nft_af_info *afi; -++ struct nft_pktinfo pkt; -+ -+- if (n == 1) -+- afi = &nft_af_ipv4; -+- else -+- afi = &nft_af_ipv6; -+- -+- ops->pf = afi->family; -+- if (afi->hooks[ops->hooknum]) -+- ops->hook = afi->hooks[ops->hooknum]; -++ nft_set_pktinfo(&pkt, skb, state); -++ -++ switch (state->pf) { -++ case NFPROTO_IPV4: -++ nft_set_pktinfo_ipv4(&pkt, skb); -++ break; -++ case NFPROTO_IPV6: -++ nft_set_pktinfo_ipv6(&pkt, skb); -++ break; -++ default: -++ break; -++ } -++ -++ return nft_do_chain(&pkt, priv); -++} -++ -++static unsigned int nft_inet_output(void *priv, struct sk_buff *skb, -++ const struct nf_hook_state *state) -++{ -++ struct nft_pktinfo pkt; -++ -++ nft_set_pktinfo(&pkt, skb, state); -++ -++ switch (state->pf) { -++ case NFPROTO_IPV4: -++ if (unlikely(skb->len < sizeof(struct iphdr) || -++ ip_hdr(skb)->ihl < sizeof(struct iphdr) / 4)) { -++ if (net_ratelimit()) -++ pr_info("ignoring short SOCK_RAW packet\n"); -++ return NF_ACCEPT; -++ } -++ nft_set_pktinfo_ipv4(&pkt, skb); -++ break; -++ case NFPROTO_IPV6: -++ if (unlikely(skb->len < sizeof(struct ipv6hdr))) { -++ if (net_ratelimit()) -++ pr_info("ignoring short SOCK_RAW packet\n"); -++ return NF_ACCEPT; -++ } -++ nft_set_pktinfo_ipv6(&pkt, skb); -++ break; -++ default: -++ break; -++ } -++ -++ return nft_do_chain(&pkt, priv); -+ } -+ -+ static struct nft_af_info nft_af_inet __read_mostly = { -+ .family = NFPROTO_INET, -+ .nhooks = NF_INET_NUMHOOKS, -+ .owner = THIS_MODULE, -+- .nops = 2, -+- .hook_ops_init = nft_inet_hook_ops_init, -++ .nops = 1, -++ .hooks = { -++ [NF_INET_LOCAL_IN] = nft_do_chain_inet, -++ [NF_INET_LOCAL_OUT] = nft_inet_output, -++ [NF_INET_FORWARD] = nft_do_chain_inet, -++ [NF_INET_PRE_ROUTING] = nft_do_chain_inet, -++ [NF_INET_POST_ROUTING] = nft_do_chain_inet, -++ }, -+ }; -+ -+ static int __net_init nf_tables_inet_init_net(struct net *net) -diff --git a/target/linux/generic/backport-4.14/303-v4.16-netfilter-nf_tables-remove-multihook-chains-and-fami.patch b/target/linux/generic/backport-4.14/303-v4.16-netfilter-nf_tables-remove-multihook-chains-and-fami.patch -new file mode 100644 -index 0000000000..f43456a99e ---- /dev/null -+++ b/target/linux/generic/backport-4.14/303-v4.16-netfilter-nf_tables-remove-multihook-chains-and-fami.patch -@@ -0,0 +1,390 @@ -+From: Pablo Neira Ayuso -+Date: Sat, 9 Dec 2017 15:40:25 +0100 -+Subject: [PATCH] netfilter: nf_tables: remove multihook chains and families -+ -+Since NFPROTO_INET is handled from the core, we don't need to maintain -+extra infrastructure in nf_tables to handle the double hook -+registration, one for IPv4 and another for IPv6. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/net/netfilter/nf_tables.h -++++ b/include/net/netfilter/nf_tables.h -+@@ -898,8 +898,6 @@ struct nft_stats { -+ struct u64_stats_sync syncp; -+ }; -+ -+-#define NFT_HOOK_OPS_MAX 2 -+- -+ /** -+ * struct nft_base_chain - nf_tables base chain -+ * -+@@ -911,7 +909,7 @@ struct nft_stats { -+ * @dev_name: device name that this base chain is attached to (if any) -+ */ -+ struct nft_base_chain { -+- struct nf_hook_ops ops[NFT_HOOK_OPS_MAX]; -++ struct nf_hook_ops ops; -+ const struct nf_chain_type *type; -+ u8 policy; -+ u8 flags; -+@@ -972,8 +970,6 @@ enum nft_af_flags { -+ * @owner: module owner -+ * @tables: used internally -+ * @flags: family flags -+- * @nops: number of hook ops in this family -+- * @hook_ops_init: initialization function for chain hook ops -+ * @hooks: hookfn overrides for packet validation -+ */ -+ struct nft_af_info { -+@@ -983,9 +979,6 @@ struct nft_af_info { -+ struct module *owner; -+ struct list_head tables; -+ u32 flags; -+- unsigned int nops; -+- void (*hook_ops_init)(struct nf_hook_ops *, -+- unsigned int); -+ nf_hookfn *hooks[NF_MAX_HOOKS]; -+ }; -+ -+--- a/net/bridge/netfilter/nf_tables_bridge.c -++++ b/net/bridge/netfilter/nf_tables_bridge.c -+@@ -46,7 +46,6 @@ static struct nft_af_info nft_af_bridge -+ .family = NFPROTO_BRIDGE, -+ .nhooks = NF_BR_NUMHOOKS, -+ .owner = THIS_MODULE, -+- .nops = 1, -+ .hooks = { -+ [NF_BR_PRE_ROUTING] = nft_do_chain_bridge, -+ [NF_BR_LOCAL_IN] = nft_do_chain_bridge, -+--- a/net/ipv4/netfilter/nf_tables_arp.c -++++ b/net/ipv4/netfilter/nf_tables_arp.c -+@@ -31,7 +31,6 @@ static struct nft_af_info nft_af_arp __r -+ .family = NFPROTO_ARP, -+ .nhooks = NF_ARP_NUMHOOKS, -+ .owner = THIS_MODULE, -+- .nops = 1, -+ .hooks = { -+ [NF_ARP_IN] = nft_do_chain_arp, -+ [NF_ARP_OUT] = nft_do_chain_arp, -+--- a/net/ipv4/netfilter/nf_tables_ipv4.c -++++ b/net/ipv4/netfilter/nf_tables_ipv4.c -+@@ -49,7 +49,6 @@ static struct nft_af_info nft_af_ipv4 __ -+ .family = NFPROTO_IPV4, -+ .nhooks = NF_INET_NUMHOOKS, -+ .owner = THIS_MODULE, -+- .nops = 1, -+ .hooks = { -+ [NF_INET_LOCAL_IN] = nft_do_chain_ipv4, -+ [NF_INET_LOCAL_OUT] = nft_ipv4_output, -+--- a/net/ipv6/netfilter/nf_tables_ipv6.c -++++ b/net/ipv6/netfilter/nf_tables_ipv6.c -+@@ -46,7 +46,6 @@ static struct nft_af_info nft_af_ipv6 __ -+ .family = NFPROTO_IPV6, -+ .nhooks = NF_INET_NUMHOOKS, -+ .owner = THIS_MODULE, -+- .nops = 1, -+ .hooks = { -+ [NF_INET_LOCAL_IN] = nft_do_chain_ipv6, -+ [NF_INET_LOCAL_OUT] = nft_ipv6_output, -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -139,29 +139,26 @@ static void nft_trans_destroy(struct nft -+ kfree(trans); -+ } -+ -+-static int nf_tables_register_hooks(struct net *net, -+- const struct nft_table *table, -+- struct nft_chain *chain, -+- unsigned int hook_nops) -++static int nf_tables_register_hook(struct net *net, -++ const struct nft_table *table, -++ struct nft_chain *chain) -+ { -+ if (table->flags & NFT_TABLE_F_DORMANT || -+ !nft_is_base_chain(chain)) -+ return 0; -+ -+- return nf_register_net_hooks(net, nft_base_chain(chain)->ops, -+- hook_nops); -++ return nf_register_net_hook(net, &nft_base_chain(chain)->ops); -+ } -+ -+-static void nf_tables_unregister_hooks(struct net *net, -+- const struct nft_table *table, -+- struct nft_chain *chain, -+- unsigned int hook_nops) -++static void nf_tables_unregister_hook(struct net *net, -++ const struct nft_table *table, -++ struct nft_chain *chain) -+ { -+ if (table->flags & NFT_TABLE_F_DORMANT || -+ !nft_is_base_chain(chain)) -+ return; -+ -+- nf_unregister_net_hooks(net, nft_base_chain(chain)->ops, hook_nops); -++ nf_unregister_net_hook(net, &nft_base_chain(chain)->ops); -+ } -+ -+ static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type) -+@@ -639,8 +636,7 @@ static void _nf_tables_table_disable(str -+ if (cnt && i++ == cnt) -+ break; -+ -+- nf_unregister_net_hooks(net, nft_base_chain(chain)->ops, -+- afi->nops); -++ nf_unregister_net_hook(net, &nft_base_chain(chain)->ops); -+ } -+ } -+ -+@@ -657,8 +653,7 @@ static int nf_tables_table_enable(struct -+ if (!nft_is_base_chain(chain)) -+ continue; -+ -+- err = nf_register_net_hooks(net, nft_base_chain(chain)->ops, -+- afi->nops); -++ err = nf_register_net_hook(net, &nft_base_chain(chain)->ops); -+ if (err < 0) -+ goto err; -+ -+@@ -1070,7 +1065,7 @@ static int nf_tables_fill_chain_info(str -+ -+ if (nft_is_base_chain(chain)) { -+ const struct nft_base_chain *basechain = nft_base_chain(chain); -+- const struct nf_hook_ops *ops = &basechain->ops[0]; -++ const struct nf_hook_ops *ops = &basechain->ops; -+ struct nlattr *nest; -+ -+ nest = nla_nest_start(skb, NFTA_CHAIN_HOOK); -+@@ -1298,8 +1293,8 @@ static void nf_tables_chain_destroy(stru -+ free_percpu(basechain->stats); -+ if (basechain->stats) -+ static_branch_dec(&nft_counters_enabled); -+- if (basechain->ops[0].dev != NULL) -+- dev_put(basechain->ops[0].dev); -++ if (basechain->ops.dev != NULL) -++ dev_put(basechain->ops.dev); -+ kfree(chain->name); -+ kfree(basechain); -+ } else { -+@@ -1395,7 +1390,6 @@ static int nf_tables_addchain(struct nft -+ struct nft_stats __percpu *stats; -+ struct net *net = ctx->net; -+ struct nft_chain *chain; -+- unsigned int i; -+ int err; -+ -+ if (table->use == UINT_MAX) -+@@ -1434,21 +1428,18 @@ static int nf_tables_addchain(struct nft -+ basechain->type = hook.type; -+ chain = &basechain->chain; -+ -+- for (i = 0; i < afi->nops; i++) { -+- ops = &basechain->ops[i]; -+- ops->pf = family; -+- ops->hooknum = hook.num; -+- ops->priority = hook.priority; -+- ops->priv = chain; -+- ops->hook = afi->hooks[ops->hooknum]; -+- ops->dev = hook.dev; -+- if (hookfn) -+- ops->hook = hookfn; -+- if (afi->hook_ops_init) -+- afi->hook_ops_init(ops, i); -+- if (basechain->type->type == NFT_CHAIN_T_NAT) -+- ops->nat_hook = true; -+- } -++ ops = &basechain->ops; -++ ops->pf = family; -++ ops->hooknum = hook.num; -++ ops->priority = hook.priority; -++ ops->priv = chain; -++ ops->hook = afi->hooks[ops->hooknum]; -++ ops->dev = hook.dev; -++ if (hookfn) -++ ops->hook = hookfn; -++ -++ if (basechain->type->type == NFT_CHAIN_T_NAT) -++ ops->nat_hook = true; -+ -+ chain->flags |= NFT_BASE_CHAIN; -+ basechain->policy = policy; -+@@ -1466,7 +1457,7 @@ static int nf_tables_addchain(struct nft -+ goto err1; -+ } -+ -+- err = nf_tables_register_hooks(net, table, chain, afi->nops); -++ err = nf_tables_register_hook(net, table, chain); -+ if (err < 0) -+ goto err1; -+ -+@@ -1480,7 +1471,7 @@ static int nf_tables_addchain(struct nft -+ -+ return 0; -+ err2: -+- nf_tables_unregister_hooks(net, table, chain, afi->nops); -++ nf_tables_unregister_hook(net, table, chain); -+ err1: -+ nf_tables_chain_destroy(chain); -+ -+@@ -1493,13 +1484,12 @@ static int nf_tables_updchain(struct nft -+ const struct nlattr * const *nla = ctx->nla; -+ struct nft_table *table = ctx->table; -+ struct nft_chain *chain = ctx->chain; -+- struct nft_af_info *afi = ctx->afi; -+ struct nft_base_chain *basechain; -+ struct nft_stats *stats = NULL; -+ struct nft_chain_hook hook; -+ struct nf_hook_ops *ops; -+ struct nft_trans *trans; -+- int err, i; -++ int err; -+ -+ if (nla[NFTA_CHAIN_HOOK]) { -+ if (!nft_is_base_chain(chain)) -+@@ -1516,14 +1506,12 @@ static int nf_tables_updchain(struct nft -+ return -EBUSY; -+ } -+ -+- for (i = 0; i < afi->nops; i++) { -+- ops = &basechain->ops[i]; -+- if (ops->hooknum != hook.num || -+- ops->priority != hook.priority || -+- ops->dev != hook.dev) { -+- nft_chain_release_hook(&hook); -+- return -EBUSY; -+- } -++ ops = &basechain->ops; -++ if (ops->hooknum != hook.num || -++ ops->priority != hook.priority || -++ ops->dev != hook.dev) { -++ nft_chain_release_hook(&hook); -++ return -EBUSY; -+ } -+ nft_chain_release_hook(&hook); -+ } -+@@ -5162,10 +5150,9 @@ static int nf_tables_commit(struct net * -+ case NFT_MSG_DELCHAIN: -+ list_del_rcu(&trans->ctx.chain->list); -+ nf_tables_chain_notify(&trans->ctx, NFT_MSG_DELCHAIN); -+- nf_tables_unregister_hooks(trans->ctx.net, -+- trans->ctx.table, -+- trans->ctx.chain, -+- trans->ctx.afi->nops); -++ nf_tables_unregister_hook(trans->ctx.net, -++ trans->ctx.table, -++ trans->ctx.chain); -+ break; -+ case NFT_MSG_NEWRULE: -+ nft_clear(trans->ctx.net, nft_trans_rule(trans)); -+@@ -5302,10 +5289,9 @@ static int nf_tables_abort(struct net *n -+ } else { -+ trans->ctx.table->use--; -+ list_del_rcu(&trans->ctx.chain->list); -+- nf_tables_unregister_hooks(trans->ctx.net, -+- trans->ctx.table, -+- trans->ctx.chain, -+- trans->ctx.afi->nops); -++ nf_tables_unregister_hook(trans->ctx.net, -++ trans->ctx.table, -++ trans->ctx.chain); -+ } -+ break; -+ case NFT_MSG_DELCHAIN: -+@@ -5408,7 +5394,7 @@ int nft_chain_validate_hooks(const struc -+ if (nft_is_base_chain(chain)) { -+ basechain = nft_base_chain(chain); -+ -+- if ((1 << basechain->ops[0].hooknum) & hook_flags) -++ if ((1 << basechain->ops.hooknum) & hook_flags) -+ return 0; -+ -+ return -EOPNOTSUPP; -+@@ -5890,8 +5876,7 @@ int __nft_release_basechain(struct nft_c -+ -+ BUG_ON(!nft_is_base_chain(ctx->chain)); -+ -+- nf_tables_unregister_hooks(ctx->net, ctx->chain->table, ctx->chain, -+- ctx->afi->nops); -++ nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain); -+ list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) { -+ list_del(&rule->list); -+ ctx->chain->use--; -+@@ -5920,8 +5905,7 @@ static void __nft_release_afinfo(struct -+ -+ list_for_each_entry_safe(table, nt, &afi->tables, list) { -+ list_for_each_entry(chain, &table->chains, list) -+- nf_tables_unregister_hooks(net, table, chain, -+- afi->nops); -++ nf_tables_unregister_hook(net, table, chain); -+ /* No packets are walking on these chains anymore. */ -+ ctx.table = table; -+ list_for_each_entry(chain, &table->chains, list) { -+--- a/net/netfilter/nf_tables_inet.c -++++ b/net/netfilter/nf_tables_inet.c -+@@ -74,7 +74,6 @@ static struct nft_af_info nft_af_inet __ -+ .family = NFPROTO_INET, -+ .nhooks = NF_INET_NUMHOOKS, -+ .owner = THIS_MODULE, -+- .nops = 1, -+ .hooks = { -+ [NF_INET_LOCAL_IN] = nft_do_chain_inet, -+ [NF_INET_LOCAL_OUT] = nft_inet_output, -+--- a/net/netfilter/nf_tables_netdev.c -++++ b/net/netfilter/nf_tables_netdev.c -+@@ -43,7 +43,6 @@ static struct nft_af_info nft_af_netdev -+ .nhooks = NF_NETDEV_NUMHOOKS, -+ .owner = THIS_MODULE, -+ .flags = NFT_AF_NEEDS_DEV, -+- .nops = 1, -+ .hooks = { -+ [NF_NETDEV_INGRESS] = nft_do_chain_netdev, -+ }, -+@@ -98,7 +97,7 @@ static void nft_netdev_event(unsigned lo -+ __nft_release_basechain(ctx); -+ break; -+ case NETDEV_CHANGENAME: -+- if (dev->ifindex != basechain->ops[0].dev->ifindex) -++ if (dev->ifindex != basechain->ops.dev->ifindex) -+ return; -+ -+ strncpy(basechain->dev_name, dev->name, IFNAMSIZ); -+--- a/net/netfilter/nft_compat.c -++++ b/net/netfilter/nft_compat.c -+@@ -186,7 +186,7 @@ nft_target_set_tgchk_param(struct xt_tgc -+ if (nft_is_base_chain(ctx->chain)) { -+ const struct nft_base_chain *basechain = -+ nft_base_chain(ctx->chain); -+- const struct nf_hook_ops *ops = &basechain->ops[0]; -++ const struct nf_hook_ops *ops = &basechain->ops; -+ -+ par->hook_mask = 1 << ops->hooknum; -+ } else { -+@@ -337,7 +337,7 @@ static int nft_target_validate(const str -+ if (nft_is_base_chain(ctx->chain)) { -+ const struct nft_base_chain *basechain = -+ nft_base_chain(ctx->chain); -+- const struct nf_hook_ops *ops = &basechain->ops[0]; -++ const struct nf_hook_ops *ops = &basechain->ops; -+ -+ hook_mask = 1 << ops->hooknum; -+ if (target->hooks && !(hook_mask & target->hooks)) -+@@ -434,7 +434,7 @@ nft_match_set_mtchk_param(struct xt_mtch -+ if (nft_is_base_chain(ctx->chain)) { -+ const struct nft_base_chain *basechain = -+ nft_base_chain(ctx->chain); -+- const struct nf_hook_ops *ops = &basechain->ops[0]; -++ const struct nf_hook_ops *ops = &basechain->ops; -+ -+ par->hook_mask = 1 << ops->hooknum; -+ } else { -+@@ -586,7 +586,7 @@ static int nft_match_validate(const stru -+ if (nft_is_base_chain(ctx->chain)) { -+ const struct nft_base_chain *basechain = -+ nft_base_chain(ctx->chain); -+- const struct nf_hook_ops *ops = &basechain->ops[0]; -++ const struct nf_hook_ops *ops = &basechain->ops; -+ -+ hook_mask = 1 << ops->hooknum; -+ if (match->hooks && !(hook_mask & match->hooks)) -diff --git a/target/linux/generic/backport-4.14/304-v4.16-netfilter-move-checksum-indirection-to-struct-nf_ipv.patch b/target/linux/generic/backport-4.14/304-v4.16-netfilter-move-checksum-indirection-to-struct-nf_ipv.patch -new file mode 100644 -index 0000000000..07202fe591 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/304-v4.16-netfilter-move-checksum-indirection-to-struct-nf_ipv.patch -@@ -0,0 +1,171 @@ -+From: Pablo Neira Ayuso -+Date: Mon, 27 Nov 2017 21:55:14 +0100 -+Subject: [PATCH] netfilter: move checksum indirection to struct nf_ipv6_ops -+ -+We cannot make a direct call to nf_ip6_checksum() because that would -+result in autoloading the 'ipv6' module because of symbol dependencies. -+Therefore, define checksum indirection in nf_ipv6_ops where this really -+belongs to. -+ -+For IPv4, we can indeed make a direct function call, which is faster, -+given IPv4 is built-in in the networking code by default. Still, -+CONFIG_INET=n and CONFIG_NETFILTER=y is possible, so define empty inline -+stub for IPv4 in such case. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ create mode 100644 net/netfilter/utils.c -+ -+--- a/include/linux/netfilter.h -++++ b/include/linux/netfilter.h -+@@ -311,8 +311,6 @@ struct nf_queue_entry; -+ -+ struct nf_afinfo { -+ unsigned short family; -+- __sum16 (*checksum)(struct sk_buff *skb, unsigned int hook, -+- unsigned int dataoff, u_int8_t protocol); -+ __sum16 (*checksum_partial)(struct sk_buff *skb, -+ unsigned int hook, -+ unsigned int dataoff, -+@@ -333,20 +331,9 @@ static inline const struct nf_afinfo *nf -+ return rcu_dereference(nf_afinfo[family]); -+ } -+ -+-static inline __sum16 -+-nf_checksum(struct sk_buff *skb, unsigned int hook, unsigned int dataoff, -+- u_int8_t protocol, unsigned short family) -+-{ -+- const struct nf_afinfo *afinfo; -+- __sum16 csum = 0; -+- -+- rcu_read_lock(); -+- afinfo = nf_get_afinfo(family); -+- if (afinfo) -+- csum = afinfo->checksum(skb, hook, dataoff, protocol); -+- rcu_read_unlock(); -+- return csum; -+-} -++__sum16 nf_checksum(struct sk_buff *skb, unsigned int hook, -++ unsigned int dataoff, u_int8_t protocol, -++ unsigned short family); -+ -+ static inline __sum16 -+ nf_checksum_partial(struct sk_buff *skb, unsigned int hook, -+--- a/include/linux/netfilter_ipv4.h -++++ b/include/linux/netfilter_ipv4.h -+@@ -7,6 +7,16 @@ -+ #include -+ -+ int ip_route_me_harder(struct net *net, struct sk_buff *skb, unsigned addr_type); -++ -++#ifdef CONFIG_INET -+ __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook, -+ unsigned int dataoff, u_int8_t protocol); -++#else -++static inline __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook, -++ unsigned int dataoff, u_int8_t protocol) -++{ -++ return 0; -++} -++#endif /* CONFIG_INET */ -++ -+ #endif /*__LINUX_IP_NETFILTER_H*/ -+--- a/include/linux/netfilter_ipv6.h -++++ b/include/linux/netfilter_ipv6.h -+@@ -19,6 +19,8 @@ struct nf_ipv6_ops { -+ void (*route_input)(struct sk_buff *skb); -+ int (*fragment)(struct net *net, struct sock *sk, struct sk_buff *skb, -+ int (*output)(struct net *, struct sock *, struct sk_buff *)); -++ __sum16 (*checksum)(struct sk_buff *skb, unsigned int hook, -++ unsigned int dataoff, u_int8_t protocol); -+ }; -+ -+ #ifdef CONFIG_NETFILTER -+--- a/net/bridge/netfilter/nf_tables_bridge.c -++++ b/net/bridge/netfilter/nf_tables_bridge.c -+@@ -106,12 +106,6 @@ static int nf_br_reroute(struct net *net -+ return 0; -+ } -+ -+-static __sum16 nf_br_checksum(struct sk_buff *skb, unsigned int hook, -+- unsigned int dataoff, u_int8_t protocol) -+-{ -+- return 0; -+-} -+- -+ static __sum16 nf_br_checksum_partial(struct sk_buff *skb, unsigned int hook, -+ unsigned int dataoff, unsigned int len, -+ u_int8_t protocol) -+@@ -127,7 +121,6 @@ static int nf_br_route(struct net *net, -+ -+ static const struct nf_afinfo nf_br_afinfo = { -+ .family = AF_BRIDGE, -+- .checksum = nf_br_checksum, -+ .checksum_partial = nf_br_checksum_partial, -+ .route = nf_br_route, -+ .saveroute = nf_br_saveroute, -+--- a/net/ipv4/netfilter.c -++++ b/net/ipv4/netfilter.c -+@@ -188,7 +188,6 @@ static int nf_ip_route(struct net *net, -+ -+ static const struct nf_afinfo nf_ip_afinfo = { -+ .family = AF_INET, -+- .checksum = nf_ip_checksum, -+ .checksum_partial = nf_ip_checksum_partial, -+ .route = nf_ip_route, -+ .saveroute = nf_ip_saveroute, -+--- a/net/ipv6/netfilter.c -++++ b/net/ipv6/netfilter.c -+@@ -196,12 +196,12 @@ static __sum16 nf_ip6_checksum_partial(s -+ static const struct nf_ipv6_ops ipv6ops = { -+ .chk_addr = ipv6_chk_addr, -+ .route_input = ip6_route_input, -+- .fragment = ip6_fragment -++ .fragment = ip6_fragment, -++ .checksum = nf_ip6_checksum, -+ }; -+ -+ static const struct nf_afinfo nf_ip6_afinfo = { -+ .family = AF_INET6, -+- .checksum = nf_ip6_checksum, -+ .checksum_partial = nf_ip6_checksum_partial, -+ .route = nf_ip6_route, -+ .saveroute = nf_ip6_saveroute, -+--- a/net/netfilter/Makefile -++++ b/net/netfilter/Makefile -+@@ -1,5 +1,5 @@ -+ # SPDX-License-Identifier: GPL-2.0 -+-netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o -++netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o utils.o -+ -+ nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o nf_conntrack_extend.o nf_conntrack_acct.o nf_conntrack_seqadj.o -+ nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMEOUT) += nf_conntrack_timeout.o -+--- /dev/null -++++ b/net/netfilter/utils.c -+@@ -0,0 +1,26 @@ -++#include -++#include -++#include -++#include -++ -++__sum16 nf_checksum(struct sk_buff *skb, unsigned int hook, -++ unsigned int dataoff, u_int8_t protocol, -++ unsigned short family) -++{ -++ const struct nf_ipv6_ops *v6ops; -++ __sum16 csum = 0; -++ -++ switch (family) { -++ case AF_INET: -++ csum = nf_ip_checksum(skb, hook, dataoff, protocol); -++ break; -++ case AF_INET6: -++ v6ops = rcu_dereference(nf_ipv6_ops); -++ if (v6ops) -++ csum = v6ops->checksum(skb, hook, dataoff, protocol); -++ break; -++ } -++ -++ return csum; -++} -++EXPORT_SYMBOL_GPL(nf_checksum); -diff --git a/target/linux/generic/backport-4.14/305-v4.16-netfilter-move-checksum_partial-indirection-to-struc.patch b/target/linux/generic/backport-4.14/305-v4.16-netfilter-move-checksum_partial-indirection-to-struc.patch -new file mode 100644 -index 0000000000..39f5564404 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/305-v4.16-netfilter-move-checksum_partial-indirection-to-struc.patch -@@ -0,0 +1,204 @@ -+From: Pablo Neira Ayuso -+Date: Wed, 20 Dec 2017 16:04:18 +0100 -+Subject: [PATCH] netfilter: move checksum_partial indirection to struct -+ nf_ipv6_ops -+ -+We cannot make a direct call to nf_ip6_checksum_partial() because that -+would result in autoloading the 'ipv6' module because of symbol -+dependencies. Therefore, define checksum_partial indirection in -+nf_ipv6_ops where this really belongs to. -+ -+For IPv4, we can indeed make a direct function call, which is faster, -+given IPv4 is built-in in the networking code by default. Still, -+CONFIG_INET=n and CONFIG_NETFILTER=y is possible, so define empty inline -+stub for IPv4 in such case. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/linux/netfilter.h -++++ b/include/linux/netfilter.h -+@@ -311,11 +311,6 @@ struct nf_queue_entry; -+ -+ struct nf_afinfo { -+ unsigned short family; -+- __sum16 (*checksum_partial)(struct sk_buff *skb, -+- unsigned int hook, -+- unsigned int dataoff, -+- unsigned int len, -+- u_int8_t protocol); -+ int (*route)(struct net *net, struct dst_entry **dst, -+ struct flowi *fl, bool strict); -+ void (*saveroute)(const struct sk_buff *skb, -+@@ -335,22 +330,9 @@ __sum16 nf_checksum(struct sk_buff *skb, -+ unsigned int dataoff, u_int8_t protocol, -+ unsigned short family); -+ -+-static inline __sum16 -+-nf_checksum_partial(struct sk_buff *skb, unsigned int hook, -+- unsigned int dataoff, unsigned int len, -+- u_int8_t protocol, unsigned short family) -+-{ -+- const struct nf_afinfo *afinfo; -+- __sum16 csum = 0; -+- -+- rcu_read_lock(); -+- afinfo = nf_get_afinfo(family); -+- if (afinfo) -+- csum = afinfo->checksum_partial(skb, hook, dataoff, len, -+- protocol); -+- rcu_read_unlock(); -+- return csum; -+-} -++__sum16 nf_checksum_partial(struct sk_buff *skb, unsigned int hook, -++ unsigned int dataoff, unsigned int len, -++ u_int8_t protocol, unsigned short family); -+ -+ int nf_register_afinfo(const struct nf_afinfo *afinfo); -+ void nf_unregister_afinfo(const struct nf_afinfo *afinfo); -+--- a/include/linux/netfilter_ipv4.h -++++ b/include/linux/netfilter_ipv4.h -+@@ -11,12 +11,23 @@ int ip_route_me_harder(struct net *net, -+ #ifdef CONFIG_INET -+ __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook, -+ unsigned int dataoff, u_int8_t protocol); -++__sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook, -++ unsigned int dataoff, unsigned int len, -++ u_int8_t protocol); -+ #else -+ static inline __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook, -+ unsigned int dataoff, u_int8_t protocol) -+ { -+ return 0; -+ } -++static inline __sum16 nf_ip_checksum_partial(struct sk_buff *skb, -++ unsigned int hook, -++ unsigned int dataoff, -++ unsigned int len, -++ u_int8_t protocol) -++{ -++ return 0; -++} -+ #endif /* CONFIG_INET */ -+ -+ #endif /*__LINUX_IP_NETFILTER_H*/ -+--- a/include/linux/netfilter_ipv6.h -++++ b/include/linux/netfilter_ipv6.h -+@@ -21,6 +21,9 @@ struct nf_ipv6_ops { -+ int (*output)(struct net *, struct sock *, struct sk_buff *)); -+ __sum16 (*checksum)(struct sk_buff *skb, unsigned int hook, -+ unsigned int dataoff, u_int8_t protocol); -++ __sum16 (*checksum_partial)(struct sk_buff *skb, unsigned int hook, -++ unsigned int dataoff, unsigned int len, -++ u_int8_t protocol); -+ }; -+ -+ #ifdef CONFIG_NETFILTER -+--- a/net/bridge/netfilter/nf_tables_bridge.c -++++ b/net/bridge/netfilter/nf_tables_bridge.c -+@@ -106,13 +106,6 @@ static int nf_br_reroute(struct net *net -+ return 0; -+ } -+ -+-static __sum16 nf_br_checksum_partial(struct sk_buff *skb, unsigned int hook, -+- unsigned int dataoff, unsigned int len, -+- u_int8_t protocol) -+-{ -+- return 0; -+-} -+- -+ static int nf_br_route(struct net *net, struct dst_entry **dst, -+ struct flowi *fl, bool strict __always_unused) -+ { -+@@ -121,7 +114,6 @@ static int nf_br_route(struct net *net, -+ -+ static const struct nf_afinfo nf_br_afinfo = { -+ .family = AF_BRIDGE, -+- .checksum_partial = nf_br_checksum_partial, -+ .route = nf_br_route, -+ .saveroute = nf_br_saveroute, -+ .reroute = nf_br_reroute, -+--- a/net/ipv4/netfilter.c -++++ b/net/ipv4/netfilter.c -+@@ -155,9 +155,9 @@ __sum16 nf_ip_checksum(struct sk_buff *s -+ } -+ EXPORT_SYMBOL(nf_ip_checksum); -+ -+-static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook, -+- unsigned int dataoff, unsigned int len, -+- u_int8_t protocol) -++__sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook, -++ unsigned int dataoff, unsigned int len, -++ u_int8_t protocol) -+ { -+ const struct iphdr *iph = ip_hdr(skb); -+ __sum16 csum = 0; -+@@ -175,6 +175,7 @@ static __sum16 nf_ip_checksum_partial(st -+ } -+ return csum; -+ } -++EXPORT_SYMBOL_GPL(nf_ip_checksum_partial); -+ -+ static int nf_ip_route(struct net *net, struct dst_entry **dst, -+ struct flowi *fl, bool strict __always_unused) -+@@ -188,7 +189,6 @@ static int nf_ip_route(struct net *net, -+ -+ static const struct nf_afinfo nf_ip_afinfo = { -+ .family = AF_INET, -+- .checksum_partial = nf_ip_checksum_partial, -+ .route = nf_ip_route, -+ .saveroute = nf_ip_saveroute, -+ .reroute = nf_ip_reroute, -+--- a/net/ipv6/netfilter.c -++++ b/net/ipv6/netfilter.c -+@@ -194,15 +194,15 @@ static __sum16 nf_ip6_checksum_partial(s -+ }; -+ -+ static const struct nf_ipv6_ops ipv6ops = { -+- .chk_addr = ipv6_chk_addr, -+- .route_input = ip6_route_input, -+- .fragment = ip6_fragment, -+- .checksum = nf_ip6_checksum, -++ .chk_addr = ipv6_chk_addr, -++ .route_input = ip6_route_input, -++ .fragment = ip6_fragment, -++ .checksum = nf_ip6_checksum, -++ .checksum_partial = nf_ip6_checksum_partial, -+ }; -+ -+ static const struct nf_afinfo nf_ip6_afinfo = { -+ .family = AF_INET6, -+- .checksum_partial = nf_ip6_checksum_partial, -+ .route = nf_ip6_route, -+ .saveroute = nf_ip6_saveroute, -+ .reroute = nf_ip6_reroute, -+--- a/net/netfilter/utils.c -++++ b/net/netfilter/utils.c -+@@ -24,3 +24,27 @@ __sum16 nf_checksum(struct sk_buff *skb, -+ return csum; -+ } -+ EXPORT_SYMBOL_GPL(nf_checksum); -++ -++__sum16 nf_checksum_partial(struct sk_buff *skb, unsigned int hook, -++ unsigned int dataoff, unsigned int len, -++ u_int8_t protocol, unsigned short family) -++{ -++ const struct nf_ipv6_ops *v6ops; -++ __sum16 csum = 0; -++ -++ switch (family) { -++ case AF_INET: -++ csum = nf_ip_checksum_partial(skb, hook, dataoff, len, -++ protocol); -++ break; -++ case AF_INET6: -++ v6ops = rcu_dereference(nf_ipv6_ops); -++ if (v6ops) -++ csum = v6ops->checksum_partial(skb, hook, dataoff, len, -++ protocol); -++ break; -++ } -++ -++ return csum; -++} -++EXPORT_SYMBOL_GPL(nf_checksum_partial); -diff --git a/target/linux/generic/backport-4.14/306-v4.16-netfilter-remove-saveroute-indirection-in-struct-nf_.patch b/target/linux/generic/backport-4.14/306-v4.16-netfilter-remove-saveroute-indirection-in-struct-nf_.patch -new file mode 100644 -index 0000000000..943b3eed30 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/306-v4.16-netfilter-remove-saveroute-indirection-in-struct-nf_.patch -@@ -0,0 +1,232 @@ -+From: Pablo Neira Ayuso -+Date: Wed, 20 Dec 2017 16:12:55 +0100 -+Subject: [PATCH] netfilter: remove saveroute indirection in struct nf_afinfo -+ -+This is only used by nf_queue.c and this function comes with no symbol -+dependencies with IPv6, it just refers to structure layouts. Therefore, -+we can replace it by a direct function call from where it belongs. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/linux/netfilter.h -++++ b/include/linux/netfilter.h -+@@ -313,8 +313,6 @@ struct nf_afinfo { -+ unsigned short family; -+ int (*route)(struct net *net, struct dst_entry **dst, -+ struct flowi *fl, bool strict); -+- void (*saveroute)(const struct sk_buff *skb, -+- struct nf_queue_entry *entry); -+ int (*reroute)(struct net *net, struct sk_buff *skb, -+ const struct nf_queue_entry *entry); -+ int route_key_size; -+--- a/include/linux/netfilter_ipv4.h -++++ b/include/linux/netfilter_ipv4.h -+@@ -6,6 +6,16 @@ -+ -+ #include -+ -++/* Extra routing may needed on local out, as the QUEUE target never returns -++ * control to the table. -++ */ -++struct ip_rt_info { -++ __be32 daddr; -++ __be32 saddr; -++ u_int8_t tos; -++ u_int32_t mark; -++}; -++ -+ int ip_route_me_harder(struct net *net, struct sk_buff *skb, unsigned addr_type); -+ -+ #ifdef CONFIG_INET -+--- a/include/linux/netfilter_ipv6.h -++++ b/include/linux/netfilter_ipv6.h -+@@ -9,6 +9,15 @@ -+ -+ #include -+ -++/* Extra routing may needed on local out, as the QUEUE target never returns -++ * control to the table. -++ */ -++struct ip6_rt_info { -++ struct in6_addr daddr; -++ struct in6_addr saddr; -++ u_int32_t mark; -++}; -++ -+ /* -+ * Hook functions for ipv6 to allow xt_* modules to be built-in even -+ * if IPv6 is a module. -+--- a/net/bridge/netfilter/nf_tables_bridge.c -++++ b/net/bridge/netfilter/nf_tables_bridge.c -+@@ -95,11 +95,6 @@ static const struct nf_chain_type filter -+ (1 << NF_BR_POST_ROUTING), -+ }; -+ -+-static void nf_br_saveroute(const struct sk_buff *skb, -+- struct nf_queue_entry *entry) -+-{ -+-} -+- -+ static int nf_br_reroute(struct net *net, struct sk_buff *skb, -+ const struct nf_queue_entry *entry) -+ { -+@@ -115,7 +110,6 @@ static int nf_br_route(struct net *net, -+ static const struct nf_afinfo nf_br_afinfo = { -+ .family = AF_BRIDGE, -+ .route = nf_br_route, -+- .saveroute = nf_br_saveroute, -+ .reroute = nf_br_reroute, -+ .route_key_size = 0, -+ }; -+--- a/net/ipv4/netfilter.c -++++ b/net/ipv4/netfilter.c -+@@ -80,33 +80,6 @@ int ip_route_me_harder(struct net *net, -+ } -+ EXPORT_SYMBOL(ip_route_me_harder); -+ -+-/* -+- * Extra routing may needed on local out, as the QUEUE target never -+- * returns control to the table. -+- */ -+- -+-struct ip_rt_info { -+- __be32 daddr; -+- __be32 saddr; -+- u_int8_t tos; -+- u_int32_t mark; -+-}; -+- -+-static void nf_ip_saveroute(const struct sk_buff *skb, -+- struct nf_queue_entry *entry) -+-{ -+- struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry); -+- -+- if (entry->state.hook == NF_INET_LOCAL_OUT) { -+- const struct iphdr *iph = ip_hdr(skb); -+- -+- rt_info->tos = iph->tos; -+- rt_info->daddr = iph->daddr; -+- rt_info->saddr = iph->saddr; -+- rt_info->mark = skb->mark; -+- } -+-} -+- -+ static int nf_ip_reroute(struct net *net, struct sk_buff *skb, -+ const struct nf_queue_entry *entry) -+ { -+@@ -190,7 +163,6 @@ static int nf_ip_route(struct net *net, -+ static const struct nf_afinfo nf_ip_afinfo = { -+ .family = AF_INET, -+ .route = nf_ip_route, -+- .saveroute = nf_ip_saveroute, -+ .reroute = nf_ip_reroute, -+ .route_key_size = sizeof(struct ip_rt_info), -+ }; -+--- a/net/ipv6/netfilter.c -++++ b/net/ipv6/netfilter.c -+@@ -72,31 +72,6 @@ int ip6_route_me_harder(struct net *net, -+ } -+ EXPORT_SYMBOL(ip6_route_me_harder); -+ -+-/* -+- * Extra routing may needed on local out, as the QUEUE target never -+- * returns control to the table. -+- */ -+- -+-struct ip6_rt_info { -+- struct in6_addr daddr; -+- struct in6_addr saddr; -+- u_int32_t mark; -+-}; -+- -+-static void nf_ip6_saveroute(const struct sk_buff *skb, -+- struct nf_queue_entry *entry) -+-{ -+- struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry); -+- -+- if (entry->state.hook == NF_INET_LOCAL_OUT) { -+- const struct ipv6hdr *iph = ipv6_hdr(skb); -+- -+- rt_info->daddr = iph->daddr; -+- rt_info->saddr = iph->saddr; -+- rt_info->mark = skb->mark; -+- } -+-} -+- -+ static int nf_ip6_reroute(struct net *net, struct sk_buff *skb, -+ const struct nf_queue_entry *entry) -+ { -+@@ -204,7 +179,6 @@ static const struct nf_ipv6_ops ipv6ops -+ static const struct nf_afinfo nf_ip6_afinfo = { -+ .family = AF_INET6, -+ .route = nf_ip6_route, -+- .saveroute = nf_ip6_saveroute, -+ .reroute = nf_ip6_reroute, -+ .route_key_size = sizeof(struct ip6_rt_info), -+ }; -+--- a/net/netfilter/nf_queue.c -++++ b/net/netfilter/nf_queue.c -+@@ -10,6 +10,8 @@ -+ #include -+ #include -+ #include -++#include -++#include -+ #include -+ #include -+ #include -+@@ -108,6 +110,35 @@ void nf_queue_nf_hook_drop(struct net *n -+ } -+ EXPORT_SYMBOL_GPL(nf_queue_nf_hook_drop); -+ -++static void nf_ip_saveroute(const struct sk_buff *skb, -++ struct nf_queue_entry *entry) -++{ -++ struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry); -++ -++ if (entry->state.hook == NF_INET_LOCAL_OUT) { -++ const struct iphdr *iph = ip_hdr(skb); -++ -++ rt_info->tos = iph->tos; -++ rt_info->daddr = iph->daddr; -++ rt_info->saddr = iph->saddr; -++ rt_info->mark = skb->mark; -++ } -++} -++ -++static void nf_ip6_saveroute(const struct sk_buff *skb, -++ struct nf_queue_entry *entry) -++{ -++ struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry); -++ -++ if (entry->state.hook == NF_INET_LOCAL_OUT) { -++ const struct ipv6hdr *iph = ipv6_hdr(skb); -++ -++ rt_info->daddr = iph->daddr; -++ rt_info->saddr = iph->saddr; -++ rt_info->mark = skb->mark; -++ } -++} -++ -+ static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state, -+ const struct nf_hook_entries *entries, -+ unsigned int index, unsigned int queuenum) -+@@ -148,7 +179,16 @@ static int __nf_queue(struct sk_buff *sk -+ }; -+ -+ nf_queue_entry_get_refs(entry); -+- afinfo->saveroute(skb, entry); -++ -++ switch (entry->state.pf) { -++ case AF_INET: -++ nf_ip_saveroute(skb, entry); -++ break; -++ case AF_INET6: -++ nf_ip6_saveroute(skb, entry); -++ break; -++ } -++ -+ status = qh->outfn(entry, queuenum); -+ -+ if (status < 0) { -diff --git a/target/linux/generic/backport-4.14/307-v4.16-netfilter-move-route-indirection-to-struct-nf_ipv6_o.patch b/target/linux/generic/backport-4.14/307-v4.16-netfilter-move-route-indirection-to-struct-nf_ipv6_o.patch -new file mode 100644 -index 0000000000..a594f87cd9 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/307-v4.16-netfilter-move-route-indirection-to-struct-nf_ipv6_o.patch -@@ -0,0 +1,349 @@ -+From: Pablo Neira Ayuso -+Date: Mon, 27 Nov 2017 22:29:52 +0100 -+Subject: [PATCH] netfilter: move route indirection to struct nf_ipv6_ops -+ -+We cannot make a direct call to nf_ip6_route() because that would result -+in autoloading the 'ipv6' module because of symbol dependencies. -+Therefore, define route indirection in nf_ipv6_ops where this really -+belongs to. -+ -+For IPv4, we can indeed make a direct function call, which is faster, -+given IPv4 is built-in in the networking code by default. Still, -+CONFIG_INET=n and CONFIG_NETFILTER=y is possible, so define empty inline -+stub for IPv4 in such case. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/linux/netfilter.h -++++ b/include/linux/netfilter.h -+@@ -311,8 +311,6 @@ struct nf_queue_entry; -+ -+ struct nf_afinfo { -+ unsigned short family; -+- int (*route)(struct net *net, struct dst_entry **dst, -+- struct flowi *fl, bool strict); -+ int (*reroute)(struct net *net, struct sk_buff *skb, -+ const struct nf_queue_entry *entry); -+ int route_key_size; -+@@ -331,6 +329,8 @@ __sum16 nf_checksum(struct sk_buff *skb, -+ __sum16 nf_checksum_partial(struct sk_buff *skb, unsigned int hook, -+ unsigned int dataoff, unsigned int len, -+ u_int8_t protocol, unsigned short family); -++int nf_route(struct net *net, struct dst_entry **dst, struct flowi *fl, -++ bool strict, unsigned short family); -+ -+ int nf_register_afinfo(const struct nf_afinfo *afinfo); -+ void nf_unregister_afinfo(const struct nf_afinfo *afinfo); -+--- a/include/linux/netfilter_ipv4.h -++++ b/include/linux/netfilter_ipv4.h -+@@ -24,6 +24,8 @@ __sum16 nf_ip_checksum(struct sk_buff *s -+ __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook, -+ unsigned int dataoff, unsigned int len, -+ u_int8_t protocol); -++int nf_ip_route(struct net *net, struct dst_entry **dst, struct flowi *fl, -++ bool strict); -+ #else -+ static inline __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook, -+ unsigned int dataoff, u_int8_t protocol) -+@@ -38,6 +40,11 @@ static inline __sum16 nf_ip_checksum_par -+ { -+ return 0; -+ } -++static inline int nf_ip_route(struct net *net, struct dst_entry **dst, -++ struct flowi *fl, bool strict) -++{ -++ return -EOPNOTSUPP; -++} -+ #endif /* CONFIG_INET */ -+ -+ #endif /*__LINUX_IP_NETFILTER_H*/ -+--- a/include/linux/netfilter_ipv6.h -++++ b/include/linux/netfilter_ipv6.h -+@@ -33,6 +33,8 @@ struct nf_ipv6_ops { -+ __sum16 (*checksum_partial)(struct sk_buff *skb, unsigned int hook, -+ unsigned int dataoff, unsigned int len, -+ u_int8_t protocol); -++ int (*route)(struct net *net, struct dst_entry **dst, struct flowi *fl, -++ bool strict); -+ }; -+ -+ #ifdef CONFIG_NETFILTER -+--- a/net/bridge/netfilter/nf_tables_bridge.c -++++ b/net/bridge/netfilter/nf_tables_bridge.c -+@@ -101,15 +101,8 @@ static int nf_br_reroute(struct net *net -+ return 0; -+ } -+ -+-static int nf_br_route(struct net *net, struct dst_entry **dst, -+- struct flowi *fl, bool strict __always_unused) -+-{ -+- return 0; -+-} -+- -+ static const struct nf_afinfo nf_br_afinfo = { -+ .family = AF_BRIDGE, -+- .route = nf_br_route, -+ .reroute = nf_br_reroute, -+ .route_key_size = 0, -+ }; -+--- a/net/ipv4/netfilter.c -++++ b/net/ipv4/netfilter.c -+@@ -150,8 +150,8 @@ __sum16 nf_ip_checksum_partial(struct sk -+ } -+ EXPORT_SYMBOL_GPL(nf_ip_checksum_partial); -+ -+-static int nf_ip_route(struct net *net, struct dst_entry **dst, -+- struct flowi *fl, bool strict __always_unused) -++int nf_ip_route(struct net *net, struct dst_entry **dst, struct flowi *fl, -++ bool strict __always_unused) -+ { -+ struct rtable *rt = ip_route_output_key(net, &fl->u.ip4); -+ if (IS_ERR(rt)) -+@@ -159,10 +159,10 @@ static int nf_ip_route(struct net *net, -+ *dst = &rt->dst; -+ return 0; -+ } -++EXPORT_SYMBOL_GPL(nf_ip_route); -+ -+ static const struct nf_afinfo nf_ip_afinfo = { -+ .family = AF_INET, -+- .route = nf_ip_route, -+ .reroute = nf_ip_reroute, -+ .route_key_size = sizeof(struct ip_rt_info), -+ }; -+--- a/net/ipv6/netfilter.c -++++ b/net/ipv6/netfilter.c -+@@ -174,11 +174,11 @@ static const struct nf_ipv6_ops ipv6ops -+ .fragment = ip6_fragment, -+ .checksum = nf_ip6_checksum, -+ .checksum_partial = nf_ip6_checksum_partial, -++ .route = nf_ip6_route, -+ }; -+ -+ static const struct nf_afinfo nf_ip6_afinfo = { -+ .family = AF_INET6, -+- .route = nf_ip6_route, -+ .reroute = nf_ip6_reroute, -+ .route_key_size = sizeof(struct ip6_rt_info), -+ }; -+--- a/net/ipv6/netfilter/nft_fib_ipv6.c -++++ b/net/ipv6/netfilter/nft_fib_ipv6.c -+@@ -60,7 +60,6 @@ static u32 __nft_fib6_eval_type(const st -+ { -+ const struct net_device *dev = NULL; -+ const struct nf_ipv6_ops *v6ops; -+- const struct nf_afinfo *afinfo; -+ int route_err, addrtype; -+ struct rt6_info *rt; -+ struct flowi6 fl6 = { -+@@ -69,8 +68,8 @@ static u32 __nft_fib6_eval_type(const st -+ }; -+ u32 ret = 0; -+ -+- afinfo = nf_get_afinfo(NFPROTO_IPV6); -+- if (!afinfo) -++ v6ops = nf_get_ipv6_ops(); -++ if (!v6ops) -+ return RTN_UNREACHABLE; -+ -+ if (priv->flags & NFTA_FIB_F_IIF) -+@@ -80,12 +79,11 @@ static u32 __nft_fib6_eval_type(const st -+ -+ nft_fib6_flowi_init(&fl6, priv, pkt, dev, iph); -+ -+- v6ops = nf_get_ipv6_ops(); -+- if (dev && v6ops && v6ops->chk_addr(nft_net(pkt), &fl6.daddr, dev, true)) -++ if (dev && v6ops->chk_addr(nft_net(pkt), &fl6.daddr, dev, true)) -+ ret = RTN_LOCAL; -+ -+- route_err = afinfo->route(nft_net(pkt), (struct dst_entry **)&rt, -+- flowi6_to_flowi(&fl6), false); -++ route_err = v6ops->route(nft_net(pkt), (struct dst_entry **)&rt, -++ flowi6_to_flowi(&fl6), false); -+ if (route_err) -+ goto err; -+ -+--- a/net/netfilter/nf_conntrack_h323_main.c -++++ b/net/netfilter/nf_conntrack_h323_main.c -+@@ -24,6 +24,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include -+ #include -+@@ -732,14 +733,8 @@ static int callforward_do_filter(struct -+ const union nf_inet_addr *dst, -+ u_int8_t family) -+ { -+- const struct nf_afinfo *afinfo; -+ int ret = 0; -+ -+- /* rcu_read_lock()ed by nf_hook_thresh */ -+- afinfo = nf_get_afinfo(family); -+- if (!afinfo) -+- return 0; -+- -+ switch (family) { -+ case AF_INET: { -+ struct flowi4 fl1, fl2; -+@@ -750,10 +745,10 @@ static int callforward_do_filter(struct -+ -+ memset(&fl2, 0, sizeof(fl2)); -+ fl2.daddr = dst->ip; -+- if (!afinfo->route(net, (struct dst_entry **)&rt1, -+- flowi4_to_flowi(&fl1), false)) { -+- if (!afinfo->route(net, (struct dst_entry **)&rt2, -+- flowi4_to_flowi(&fl2), false)) { -++ if (!nf_ip_route(net, (struct dst_entry **)&rt1, -++ flowi4_to_flowi(&fl1), false)) { -++ if (!nf_ip_route(net, (struct dst_entry **)&rt2, -++ flowi4_to_flowi(&fl2), false)) { -+ if (rt_nexthop(rt1, fl1.daddr) == -+ rt_nexthop(rt2, fl2.daddr) && -+ rt1->dst.dev == rt2->dst.dev) -+@@ -766,18 +761,23 @@ static int callforward_do_filter(struct -+ } -+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) -+ case AF_INET6: { -+- struct flowi6 fl1, fl2; -++ const struct nf_ipv6_ops *v6ops; -+ struct rt6_info *rt1, *rt2; -++ struct flowi6 fl1, fl2; -++ -++ v6ops = nf_get_ipv6_ops(); -++ if (!v6ops) -++ return 0; -+ -+ memset(&fl1, 0, sizeof(fl1)); -+ fl1.daddr = src->in6; -+ -+ memset(&fl2, 0, sizeof(fl2)); -+ fl2.daddr = dst->in6; -+- if (!afinfo->route(net, (struct dst_entry **)&rt1, -+- flowi6_to_flowi(&fl1), false)) { -+- if (!afinfo->route(net, (struct dst_entry **)&rt2, -+- flowi6_to_flowi(&fl2), false)) { -++ if (!v6ops->route(net, (struct dst_entry **)&rt1, -++ flowi6_to_flowi(&fl1), false)) { -++ if (!v6ops->route(net, (struct dst_entry **)&rt2, -++ flowi6_to_flowi(&fl2), false)) { -+ if (ipv6_addr_equal(rt6_nexthop(rt1, &fl1.daddr), -+ rt6_nexthop(rt2, &fl2.daddr)) && -+ rt1->dst.dev == rt2->dst.dev) -+--- a/net/netfilter/nft_rt.c -++++ b/net/netfilter/nft_rt.c -+@@ -27,7 +27,7 @@ static u16 get_tcpmss(const struct nft_p -+ { -+ u32 minlen = sizeof(struct ipv6hdr), mtu = dst_mtu(skbdst); -+ const struct sk_buff *skb = pkt->skb; -+- const struct nf_afinfo *ai; -++ struct dst_entry *dst = NULL; -+ struct flowi fl; -+ -+ memset(&fl, 0, sizeof(fl)); -+@@ -43,15 +43,10 @@ static u16 get_tcpmss(const struct nft_p -+ break; -+ } -+ -+- ai = nf_get_afinfo(nft_pf(pkt)); -+- if (ai) { -+- struct dst_entry *dst = NULL; -+- -+- ai->route(nft_net(pkt), &dst, &fl, false); -+- if (dst) { -+- mtu = min(mtu, dst_mtu(dst)); -+- dst_release(dst); -+- } -++ nf_route(nft_net(pkt), &dst, &fl, false, nft_pf(pkt)); -++ if (dst) { -++ mtu = min(mtu, dst_mtu(dst)); -++ dst_release(dst); -+ } -+ -+ if (mtu <= minlen || mtu > 0xffff) -+--- a/net/netfilter/utils.c -++++ b/net/netfilter/utils.c -+@@ -48,3 +48,24 @@ __sum16 nf_checksum_partial(struct sk_bu -+ return csum; -+ } -+ EXPORT_SYMBOL_GPL(nf_checksum_partial); -++ -++int nf_route(struct net *net, struct dst_entry **dst, struct flowi *fl, -++ bool strict, unsigned short family) -++{ -++ const struct nf_ipv6_ops *v6ops; -++ int ret = 0; -++ -++ switch (family) { -++ case AF_INET: -++ ret = nf_ip_route(net, dst, fl, strict); -++ break; -++ case AF_INET6: -++ v6ops = rcu_dereference(nf_ipv6_ops); -++ if (v6ops) -++ ret = v6ops->route(net, dst, fl, strict); -++ break; -++ } -++ -++ return ret; -++} -++EXPORT_SYMBOL_GPL(nf_route); -+--- a/net/netfilter/xt_TCPMSS.c -++++ b/net/netfilter/xt_TCPMSS.c -+@@ -48,7 +48,6 @@ static u_int32_t tcpmss_reverse_mtu(stru -+ unsigned int family) -+ { -+ struct flowi fl; -+- const struct nf_afinfo *ai; -+ struct rtable *rt = NULL; -+ u_int32_t mtu = ~0U; -+ -+@@ -62,10 +61,8 @@ static u_int32_t tcpmss_reverse_mtu(stru -+ memset(fl6, 0, sizeof(*fl6)); -+ fl6->daddr = ipv6_hdr(skb)->saddr; -+ } -+- ai = nf_get_afinfo(family); -+- if (ai != NULL) -+- ai->route(net, (struct dst_entry **)&rt, &fl, false); -+ -++ nf_route(net, (struct dst_entry **)&rt, &fl, false, family); -+ if (rt != NULL) { -+ mtu = dst_mtu(&rt->dst); -+ dst_release(&rt->dst); -+--- a/net/netfilter/xt_addrtype.c -++++ b/net/netfilter/xt_addrtype.c -+@@ -36,7 +36,7 @@ MODULE_ALIAS("ip6t_addrtype"); -+ static u32 match_lookup_rt6(struct net *net, const struct net_device *dev, -+ const struct in6_addr *addr, u16 mask) -+ { -+- const struct nf_afinfo *afinfo; -++ const struct nf_ipv6_ops *v6ops; -+ struct flowi6 flow; -+ struct rt6_info *rt; -+ u32 ret = 0; -+@@ -47,17 +47,14 @@ static u32 match_lookup_rt6(struct net * -+ if (dev) -+ flow.flowi6_oif = dev->ifindex; -+ -+- afinfo = nf_get_afinfo(NFPROTO_IPV6); -+- if (afinfo != NULL) { -+- const struct nf_ipv6_ops *v6ops; -+- -++ v6ops = nf_get_ipv6_ops(); -++ if (v6ops) { -+ if (dev && (mask & XT_ADDRTYPE_LOCAL)) { -+- v6ops = nf_get_ipv6_ops(); -+- if (v6ops && v6ops->chk_addr(net, addr, dev, true)) -++ if (v6ops->chk_addr(net, addr, dev, true)) -+ ret = XT_ADDRTYPE_LOCAL; -+ } -+- route_err = afinfo->route(net, (struct dst_entry **)&rt, -+- flowi6_to_flowi(&flow), false); -++ route_err = v6ops->route(net, (struct dst_entry **)&rt, -++ flowi6_to_flowi(&flow), false); -+ } else { -+ route_err = 1; -+ } -diff --git a/target/linux/generic/backport-4.14/308-v4.16-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch b/target/linux/generic/backport-4.14/308-v4.16-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch -new file mode 100644 -index 0000000000..810f57ca19 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/308-v4.16-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch -@@ -0,0 +1,223 @@ -+From: Pablo Neira Ayuso -+Date: Mon, 27 Nov 2017 22:50:26 +0100 -+Subject: [PATCH] netfilter: move reroute indirection to struct nf_ipv6_ops -+ -+We cannot make a direct call to nf_ip6_reroute() because that would result -+in autoloading the 'ipv6' module because of symbol dependencies. -+Therefore, define reroute indirection in nf_ipv6_ops where this really -+belongs to. -+ -+For IPv4, we can indeed make a direct function call, which is faster, -+given IPv4 is built-in in the networking code by default. Still, -+CONFIG_INET=n and CONFIG_NETFILTER=y is possible, so define empty inline -+stub for IPv4 in such case. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/linux/netfilter.h -++++ b/include/linux/netfilter.h -+@@ -311,8 +311,6 @@ struct nf_queue_entry; -+ -+ struct nf_afinfo { -+ unsigned short family; -+- int (*reroute)(struct net *net, struct sk_buff *skb, -+- const struct nf_queue_entry *entry); -+ int route_key_size; -+ }; -+ -+@@ -331,6 +329,7 @@ __sum16 nf_checksum_partial(struct sk_bu -+ u_int8_t protocol, unsigned short family); -+ int nf_route(struct net *net, struct dst_entry **dst, struct flowi *fl, -+ bool strict, unsigned short family); -++int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry); -+ -+ int nf_register_afinfo(const struct nf_afinfo *afinfo); -+ void nf_unregister_afinfo(const struct nf_afinfo *afinfo); -+--- a/include/linux/netfilter_ipv4.h -++++ b/include/linux/netfilter_ipv4.h -+@@ -18,6 +18,8 @@ struct ip_rt_info { -+ -+ int ip_route_me_harder(struct net *net, struct sk_buff *skb, unsigned addr_type); -+ -++struct nf_queue_entry; -++ -+ #ifdef CONFIG_INET -+ __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook, -+ unsigned int dataoff, u_int8_t protocol); -+@@ -26,6 +28,7 @@ __sum16 nf_ip_checksum_partial(struct sk -+ u_int8_t protocol); -+ int nf_ip_route(struct net *net, struct dst_entry **dst, struct flowi *fl, -+ bool strict); -++int nf_ip_reroute(struct sk_buff *skb, const struct nf_queue_entry *entry); -+ #else -+ static inline __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook, -+ unsigned int dataoff, u_int8_t protocol) -+@@ -45,6 +48,11 @@ static inline int nf_ip_route(struct net -+ { -+ return -EOPNOTSUPP; -+ } -++static inline int nf_ip_reroute(struct sk_buff *skb, -++ const struct nf_queue_entry *entry) -++{ -++ return -EOPNOTSUPP; -++} -+ #endif /* CONFIG_INET */ -+ -+ #endif /*__LINUX_IP_NETFILTER_H*/ -+--- a/include/linux/netfilter_ipv6.h -++++ b/include/linux/netfilter_ipv6.h -+@@ -18,6 +18,8 @@ struct ip6_rt_info { -+ u_int32_t mark; -+ }; -+ -++struct nf_queue_entry; -++ -+ /* -+ * Hook functions for ipv6 to allow xt_* modules to be built-in even -+ * if IPv6 is a module. -+@@ -35,6 +37,7 @@ struct nf_ipv6_ops { -+ u_int8_t protocol); -+ int (*route)(struct net *net, struct dst_entry **dst, struct flowi *fl, -+ bool strict); -++ int (*reroute)(struct sk_buff *skb, const struct nf_queue_entry *entry); -+ }; -+ -+ #ifdef CONFIG_NETFILTER -+--- a/net/bridge/netfilter/nf_tables_bridge.c -++++ b/net/bridge/netfilter/nf_tables_bridge.c -+@@ -95,15 +95,8 @@ static const struct nf_chain_type filter -+ (1 << NF_BR_POST_ROUTING), -+ }; -+ -+-static int nf_br_reroute(struct net *net, struct sk_buff *skb, -+- const struct nf_queue_entry *entry) -+-{ -+- return 0; -+-} -+- -+ static const struct nf_afinfo nf_br_afinfo = { -+ .family = AF_BRIDGE, -+- .reroute = nf_br_reroute, -+ .route_key_size = 0, -+ }; -+ -+--- a/net/ipv4/netfilter.c -++++ b/net/ipv4/netfilter.c -+@@ -80,8 +80,7 @@ int ip_route_me_harder(struct net *net, -+ } -+ EXPORT_SYMBOL(ip_route_me_harder); -+ -+-static int nf_ip_reroute(struct net *net, struct sk_buff *skb, -+- const struct nf_queue_entry *entry) -++int nf_ip_reroute(struct sk_buff *skb, const struct nf_queue_entry *entry) -+ { -+ const struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry); -+ -+@@ -92,10 +91,12 @@ static int nf_ip_reroute(struct net *net -+ skb->mark == rt_info->mark && -+ iph->daddr == rt_info->daddr && -+ iph->saddr == rt_info->saddr)) -+- return ip_route_me_harder(net, skb, RTN_UNSPEC); -++ return ip_route_me_harder(entry->state.net, skb, -++ RTN_UNSPEC); -+ } -+ return 0; -+ } -++EXPORT_SYMBOL_GPL(nf_ip_reroute); -+ -+ __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook, -+ unsigned int dataoff, u_int8_t protocol) -+@@ -163,7 +164,6 @@ EXPORT_SYMBOL_GPL(nf_ip_route); -+ -+ static const struct nf_afinfo nf_ip_afinfo = { -+ .family = AF_INET, -+- .reroute = nf_ip_reroute, -+ .route_key_size = sizeof(struct ip_rt_info), -+ }; -+ -+--- a/net/ipv6/netfilter.c -++++ b/net/ipv6/netfilter.c -+@@ -72,7 +72,7 @@ int ip6_route_me_harder(struct net *net, -+ } -+ EXPORT_SYMBOL(ip6_route_me_harder); -+ -+-static int nf_ip6_reroute(struct net *net, struct sk_buff *skb, -++static int nf_ip6_reroute(struct sk_buff *skb, -+ const struct nf_queue_entry *entry) -+ { -+ struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry); -+@@ -82,7 +82,7 @@ static int nf_ip6_reroute(struct net *ne -+ if (!ipv6_addr_equal(&iph->daddr, &rt_info->daddr) || -+ !ipv6_addr_equal(&iph->saddr, &rt_info->saddr) || -+ skb->mark != rt_info->mark) -+- return ip6_route_me_harder(net, skb); -++ return ip6_route_me_harder(entry->state.net, skb); -+ } -+ return 0; -+ } -+@@ -175,11 +175,11 @@ static const struct nf_ipv6_ops ipv6ops -+ .checksum = nf_ip6_checksum, -+ .checksum_partial = nf_ip6_checksum_partial, -+ .route = nf_ip6_route, -++ .reroute = nf_ip6_reroute, -+ }; -+ -+ static const struct nf_afinfo nf_ip6_afinfo = { -+ .family = AF_INET6, -+- .reroute = nf_ip6_reroute, -+ .route_key_size = sizeof(struct ip6_rt_info), -+ }; -+ -+--- a/net/netfilter/nf_queue.c -++++ b/net/netfilter/nf_queue.c -+@@ -271,7 +271,6 @@ void nf_reinject(struct nf_queue_entry * -+ const struct nf_hook_entry *hook_entry; -+ const struct nf_hook_entries *hooks; -+ struct sk_buff *skb = entry->skb; -+- const struct nf_afinfo *afinfo; -+ const struct net *net; -+ unsigned int i; -+ int err; -+@@ -298,8 +297,7 @@ void nf_reinject(struct nf_queue_entry * -+ verdict = nf_hook_entry_hookfn(hook_entry, skb, &entry->state); -+ -+ if (verdict == NF_ACCEPT) { -+- afinfo = nf_get_afinfo(entry->state.pf); -+- if (!afinfo || afinfo->reroute(entry->state.net, skb, entry) < 0) -++ if (nf_reroute(skb, entry) < 0) -+ verdict = NF_DROP; -+ } -+ -+--- a/net/netfilter/utils.c -++++ b/net/netfilter/utils.c -+@@ -2,6 +2,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ __sum16 nf_checksum(struct sk_buff *skb, unsigned int hook, -+ unsigned int dataoff, u_int8_t protocol, -+@@ -69,3 +70,21 @@ int nf_route(struct net *net, struct dst -+ return ret; -+ } -+ EXPORT_SYMBOL_GPL(nf_route); -++ -++int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry) -++{ -++ const struct nf_ipv6_ops *v6ops; -++ int ret = 0; -++ -++ switch (entry->state.pf) { -++ case AF_INET: -++ ret = nf_ip_reroute(skb, entry); -++ break; -++ case AF_INET6: -++ v6ops = rcu_dereference(nf_ipv6_ops); -++ if (v6ops) -++ ret = v6ops->reroute(skb, entry); -++ break; -++ } -++ return ret; -++} -diff --git a/target/linux/generic/backport-4.14/309-v4.16-netfilter-remove-route_key_size-field-in-struct-nf_a.patch b/target/linux/generic/backport-4.14/309-v4.16-netfilter-remove-route_key_size-field-in-struct-nf_a.patch -new file mode 100644 -index 0000000000..20820e40ca ---- /dev/null -+++ b/target/linux/generic/backport-4.14/309-v4.16-netfilter-remove-route_key_size-field-in-struct-nf_a.patch -@@ -0,0 +1,94 @@ -+From: Pablo Neira Ayuso -+Date: Mon, 27 Nov 2017 22:58:37 +0100 -+Subject: [PATCH] netfilter: remove route_key_size field in struct nf_afinfo -+ -+This is only needed by nf_queue, place this code where it belongs. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/linux/netfilter.h -++++ b/include/linux/netfilter.h -+@@ -311,7 +311,6 @@ struct nf_queue_entry; -+ -+ struct nf_afinfo { -+ unsigned short family; -+- int route_key_size; -+ }; -+ -+ extern const struct nf_afinfo __rcu *nf_afinfo[NFPROTO_NUMPROTO]; -+--- a/net/ipv4/netfilter.c -++++ b/net/ipv4/netfilter.c -+@@ -164,7 +164,6 @@ EXPORT_SYMBOL_GPL(nf_ip_route); -+ -+ static const struct nf_afinfo nf_ip_afinfo = { -+ .family = AF_INET, -+- .route_key_size = sizeof(struct ip_rt_info), -+ }; -+ -+ static int __init ipv4_netfilter_init(void) -+--- a/net/ipv6/netfilter.c -++++ b/net/ipv6/netfilter.c -+@@ -180,7 +180,6 @@ static const struct nf_ipv6_ops ipv6ops -+ -+ static const struct nf_afinfo nf_ip6_afinfo = { -+ .family = AF_INET6, -+- .route_key_size = sizeof(struct ip6_rt_info), -+ }; -+ -+ int __init ipv6_netfilter_init(void) -+--- a/net/netfilter/nf_queue.c -++++ b/net/netfilter/nf_queue.c -+@@ -15,6 +15,8 @@ -+ #include -+ #include -+ #include -++#include -++#include -+ #include -+ #include -+ #include -+@@ -145,9 +147,9 @@ static int __nf_queue(struct sk_buff *sk -+ { -+ int status = -ENOENT; -+ struct nf_queue_entry *entry = NULL; -+- const struct nf_afinfo *afinfo; -+ const struct nf_queue_handler *qh; -+ struct net *net = state->net; -++ unsigned int route_key_size; -+ -+ /* QUEUE == DROP if no one is waiting, to be safe. */ -+ qh = rcu_dereference(net->nf.queue_handler); -+@@ -156,11 +158,19 @@ static int __nf_queue(struct sk_buff *sk -+ goto err; -+ } -+ -+- afinfo = nf_get_afinfo(state->pf); -+- if (!afinfo) -+- goto err; -++ switch (state->pf) { -++ case AF_INET: -++ route_key_size = sizeof(struct ip_rt_info); -++ break; -++ case AF_INET6: -++ route_key_size = sizeof(struct ip6_rt_info); -++ break; -++ default: -++ route_key_size = 0; -++ break; -++ } -+ -+- entry = kmalloc(sizeof(*entry) + afinfo->route_key_size, GFP_ATOMIC); -++ entry = kmalloc(sizeof(*entry) + route_key_size, GFP_ATOMIC); -+ if (!entry) { -+ status = -ENOMEM; -+ goto err; -+@@ -175,7 +185,7 @@ static int __nf_queue(struct sk_buff *sk -+ .skb = skb, -+ .state = *state, -+ .hook_index = index, -+- .size = sizeof(*entry) + afinfo->route_key_size, -++ .size = sizeof(*entry) + route_key_size, -+ }; -+ -+ nf_queue_entry_get_refs(entry); -diff --git a/target/linux/generic/backport-4.14/310-v4.16-netfilter-remove-struct-nf_afinfo-and-its-helper-fun.patch b/target/linux/generic/backport-4.14/310-v4.16-netfilter-remove-struct-nf_afinfo-and-its-helper-fun.patch -new file mode 100644 -index 0000000000..be3f7336bd ---- /dev/null -+++ b/target/linux/generic/backport-4.14/310-v4.16-netfilter-remove-struct-nf_afinfo-and-its-helper-fun.patch -@@ -0,0 +1,173 @@ -+From: Pablo Neira Ayuso -+Date: Sat, 9 Dec 2017 17:05:53 +0100 -+Subject: [PATCH] netfilter: remove struct nf_afinfo and its helper functions -+ -+This abstraction has no clients anymore, remove it. -+ -+This is what remains from previous authors, so correct copyright -+statement after recent modifications and code removal. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/linux/netfilter.h -++++ b/include/linux/netfilter.h -+@@ -309,16 +309,6 @@ int skb_make_writable(struct sk_buff *sk -+ struct flowi; -+ struct nf_queue_entry; -+ -+-struct nf_afinfo { -+- unsigned short family; -+-}; -+- -+-extern const struct nf_afinfo __rcu *nf_afinfo[NFPROTO_NUMPROTO]; -+-static inline const struct nf_afinfo *nf_get_afinfo(unsigned short family) -+-{ -+- return rcu_dereference(nf_afinfo[family]); -+-} -+- -+ __sum16 nf_checksum(struct sk_buff *skb, unsigned int hook, -+ unsigned int dataoff, u_int8_t protocol, -+ unsigned short family); -+@@ -330,9 +320,6 @@ int nf_route(struct net *net, struct dst -+ bool strict, unsigned short family); -+ int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry); -+ -+-int nf_register_afinfo(const struct nf_afinfo *afinfo); -+-void nf_unregister_afinfo(const struct nf_afinfo *afinfo); -+- -+ #include -+ extern void (*nf_nat_decode_session_hook)(struct sk_buff *, struct flowi *); -+ -+--- a/net/bridge/netfilter/nf_tables_bridge.c -++++ b/net/bridge/netfilter/nf_tables_bridge.c -+@@ -95,30 +95,23 @@ static const struct nf_chain_type filter -+ (1 << NF_BR_POST_ROUTING), -+ }; -+ -+-static const struct nf_afinfo nf_br_afinfo = { -+- .family = AF_BRIDGE, -+- .route_key_size = 0, -+-}; -+- -+ static int __init nf_tables_bridge_init(void) -+ { -+ int ret; -+ -+- nf_register_afinfo(&nf_br_afinfo); -+ ret = nft_register_chain_type(&filter_bridge); -+ if (ret < 0) -+- goto err1; -++ return ret; -+ -+ ret = register_pernet_subsys(&nf_tables_bridge_net_ops); -+ if (ret < 0) -+- goto err2; -++ goto err_register_subsys; -+ -+ return ret; -+ -+-err2: -++err_register_subsys: -+ nft_unregister_chain_type(&filter_bridge); -+-err1: -+- nf_unregister_afinfo(&nf_br_afinfo); -++ -+ return ret; -+ } -+ -+@@ -126,7 +119,6 @@ static void __exit nf_tables_bridge_exit -+ { -+ unregister_pernet_subsys(&nf_tables_bridge_net_ops); -+ nft_unregister_chain_type(&filter_bridge); -+- nf_unregister_afinfo(&nf_br_afinfo); -+ } -+ -+ module_init(nf_tables_bridge_init); -+--- a/net/ipv4/netfilter.c -++++ b/net/ipv4/netfilter.c -+@@ -161,13 +161,3 @@ int nf_ip_route(struct net *net, struct -+ return 0; -+ } -+ EXPORT_SYMBOL_GPL(nf_ip_route); -+- -+-static const struct nf_afinfo nf_ip_afinfo = { -+- .family = AF_INET, -+-}; -+- -+-static int __init ipv4_netfilter_init(void) -+-{ -+- return nf_register_afinfo(&nf_ip_afinfo); -+-} -+-subsys_initcall(ipv4_netfilter_init); -+--- a/net/ipv6/netfilter.c -++++ b/net/ipv6/netfilter.c -+@@ -178,14 +178,10 @@ static const struct nf_ipv6_ops ipv6ops -+ .reroute = nf_ip6_reroute, -+ }; -+ -+-static const struct nf_afinfo nf_ip6_afinfo = { -+- .family = AF_INET6, -+-}; -+- -+ int __init ipv6_netfilter_init(void) -+ { -+ RCU_INIT_POINTER(nf_ipv6_ops, &ipv6ops); -+- return nf_register_afinfo(&nf_ip6_afinfo); -++ return 0; -+ } -+ -+ /* This can be called from inet6_init() on errors, so it cannot -+@@ -194,5 +190,4 @@ int __init ipv6_netfilter_init(void) -+ void ipv6_netfilter_fini(void) -+ { -+ RCU_INIT_POINTER(nf_ipv6_ops, NULL); -+- nf_unregister_afinfo(&nf_ip6_afinfo); -+ } -+--- a/net/netfilter/core.c -++++ b/net/netfilter/core.c -+@@ -4,8 +4,7 @@ -+ * Thanks to Rob `CmdrTaco' Malda for not influencing this code in any -+ * way. -+ * -+- * Rusty Russell (C)2000 -- This code is GPL. -+- * Patrick McHardy (c) 2006-2012 -++ * This code is GPL. -+ */ -+ #include -+ #include -+@@ -28,34 +27,12 @@ -+ -+ #include "nf_internals.h" -+ -+-static DEFINE_MUTEX(afinfo_mutex); -+- -+-const struct nf_afinfo __rcu *nf_afinfo[NFPROTO_NUMPROTO] __read_mostly; -+-EXPORT_SYMBOL(nf_afinfo); -+ const struct nf_ipv6_ops __rcu *nf_ipv6_ops __read_mostly; -+ EXPORT_SYMBOL_GPL(nf_ipv6_ops); -+ -+ DEFINE_PER_CPU(bool, nf_skb_duplicated); -+ EXPORT_SYMBOL_GPL(nf_skb_duplicated); -+ -+-int nf_register_afinfo(const struct nf_afinfo *afinfo) -+-{ -+- mutex_lock(&afinfo_mutex); -+- RCU_INIT_POINTER(nf_afinfo[afinfo->family], afinfo); -+- mutex_unlock(&afinfo_mutex); -+- return 0; -+-} -+-EXPORT_SYMBOL_GPL(nf_register_afinfo); -+- -+-void nf_unregister_afinfo(const struct nf_afinfo *afinfo) -+-{ -+- mutex_lock(&afinfo_mutex); -+- RCU_INIT_POINTER(nf_afinfo[afinfo->family], NULL); -+- mutex_unlock(&afinfo_mutex); -+- synchronize_rcu(); -+-} -+-EXPORT_SYMBOL_GPL(nf_unregister_afinfo); -+- -+ #ifdef HAVE_JUMP_LABEL -+ struct static_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; -+ EXPORT_SYMBOL(nf_hooks_needed); -diff --git a/target/linux/generic/backport-4.14/311-v4.16-netfilter-nf_tables_arp-don-t-set-forward-chain.patch b/target/linux/generic/backport-4.14/311-v4.16-netfilter-nf_tables_arp-don-t-set-forward-chain.patch -new file mode 100644 -index 0000000000..10ce26dc8e ---- /dev/null -+++ b/target/linux/generic/backport-4.14/311-v4.16-netfilter-nf_tables_arp-don-t-set-forward-chain.patch -@@ -0,0 +1,20 @@ -+From: Pablo Neira Ayuso -+Date: Sun, 10 Dec 2017 01:42:58 +0100 -+Subject: [PATCH] netfilter: nf_tables_arp: don't set forward chain -+ -+46928a0b49f3 ("netfilter: nf_tables: remove multihook chains and -+families") already removed this, this is a leftover. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/net/ipv4/netfilter/nf_tables_arp.c -++++ b/net/ipv4/netfilter/nf_tables_arp.c -+@@ -34,7 +34,6 @@ static struct nft_af_info nft_af_arp __r -+ .hooks = { -+ [NF_ARP_IN] = nft_do_chain_arp, -+ [NF_ARP_OUT] = nft_do_chain_arp, -+- [NF_ARP_FORWARD] = nft_do_chain_arp, -+ }, -+ }; -+ -diff --git a/target/linux/generic/backport-4.14/312-v4.16-netfilter-nf_tables-remove-hooks-from-family-definit.patch b/target/linux/generic/backport-4.14/312-v4.16-netfilter-nf_tables-remove-hooks-from-family-definit.patch -new file mode 100644 -index 0000000000..a12679db43 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/312-v4.16-netfilter-nf_tables-remove-hooks-from-family-definit.patch -@@ -0,0 +1,233 @@ -+From: Pablo Neira Ayuso -+Date: Sat, 9 Dec 2017 15:43:17 +0100 -+Subject: [PATCH] netfilter: nf_tables: remove hooks from family definition -+ -+They don't belong to the family definition, move them to the filter -+chain type definition instead. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/net/netfilter/nf_tables.h -++++ b/include/net/netfilter/nf_tables.h -+@@ -876,7 +876,7 @@ enum nft_chain_type { -+ * @family: address family -+ * @owner: module owner -+ * @hook_mask: mask of valid hooks -+- * @hooks: hookfn overrides -++ * @hooks: array of hook functions -+ */ -+ struct nf_chain_type { -+ const char *name; -+@@ -970,7 +970,6 @@ enum nft_af_flags { -+ * @owner: module owner -+ * @tables: used internally -+ * @flags: family flags -+- * @hooks: hookfn overrides for packet validation -+ */ -+ struct nft_af_info { -+ struct list_head list; -+@@ -979,7 +978,6 @@ struct nft_af_info { -+ struct module *owner; -+ struct list_head tables; -+ u32 flags; -+- nf_hookfn *hooks[NF_MAX_HOOKS]; -+ }; -+ -+ int nft_register_afinfo(struct net *, struct nft_af_info *); -+--- a/net/bridge/netfilter/nf_tables_bridge.c -++++ b/net/bridge/netfilter/nf_tables_bridge.c -+@@ -46,13 +46,6 @@ static struct nft_af_info nft_af_bridge -+ .family = NFPROTO_BRIDGE, -+ .nhooks = NF_BR_NUMHOOKS, -+ .owner = THIS_MODULE, -+- .hooks = { -+- [NF_BR_PRE_ROUTING] = nft_do_chain_bridge, -+- [NF_BR_LOCAL_IN] = nft_do_chain_bridge, -+- [NF_BR_FORWARD] = nft_do_chain_bridge, -+- [NF_BR_LOCAL_OUT] = nft_do_chain_bridge, -+- [NF_BR_POST_ROUTING] = nft_do_chain_bridge, -+- }, -+ }; -+ -+ static int nf_tables_bridge_init_net(struct net *net) -+@@ -93,6 +86,13 @@ static const struct nf_chain_type filter -+ (1 << NF_BR_FORWARD) | -+ (1 << NF_BR_LOCAL_OUT) | -+ (1 << NF_BR_POST_ROUTING), -++ .hooks = { -++ [NF_BR_PRE_ROUTING] = nft_do_chain_bridge, -++ [NF_BR_LOCAL_IN] = nft_do_chain_bridge, -++ [NF_BR_FORWARD] = nft_do_chain_bridge, -++ [NF_BR_LOCAL_OUT] = nft_do_chain_bridge, -++ [NF_BR_POST_ROUTING] = nft_do_chain_bridge, -++ }, -+ }; -+ -+ static int __init nf_tables_bridge_init(void) -+--- a/net/ipv4/netfilter/nf_tables_arp.c -++++ b/net/ipv4/netfilter/nf_tables_arp.c -+@@ -31,10 +31,6 @@ static struct nft_af_info nft_af_arp __r -+ .family = NFPROTO_ARP, -+ .nhooks = NF_ARP_NUMHOOKS, -+ .owner = THIS_MODULE, -+- .hooks = { -+- [NF_ARP_IN] = nft_do_chain_arp, -+- [NF_ARP_OUT] = nft_do_chain_arp, -+- }, -+ }; -+ -+ static int nf_tables_arp_init_net(struct net *net) -+@@ -72,6 +68,10 @@ static const struct nf_chain_type filter -+ .owner = THIS_MODULE, -+ .hook_mask = (1 << NF_ARP_IN) | -+ (1 << NF_ARP_OUT), -++ .hooks = { -++ [NF_ARP_IN] = nft_do_chain_arp, -++ [NF_ARP_OUT] = nft_do_chain_arp, -++ }, -+ }; -+ -+ static int __init nf_tables_arp_init(void) -+--- a/net/ipv4/netfilter/nf_tables_ipv4.c -++++ b/net/ipv4/netfilter/nf_tables_ipv4.c -+@@ -49,13 +49,6 @@ static struct nft_af_info nft_af_ipv4 __ -+ .family = NFPROTO_IPV4, -+ .nhooks = NF_INET_NUMHOOKS, -+ .owner = THIS_MODULE, -+- .hooks = { -+- [NF_INET_LOCAL_IN] = nft_do_chain_ipv4, -+- [NF_INET_LOCAL_OUT] = nft_ipv4_output, -+- [NF_INET_FORWARD] = nft_do_chain_ipv4, -+- [NF_INET_PRE_ROUTING] = nft_do_chain_ipv4, -+- [NF_INET_POST_ROUTING] = nft_do_chain_ipv4, -+- }, -+ }; -+ -+ static int nf_tables_ipv4_init_net(struct net *net) -+@@ -96,6 +89,13 @@ static const struct nf_chain_type filter -+ (1 << NF_INET_FORWARD) | -+ (1 << NF_INET_PRE_ROUTING) | -+ (1 << NF_INET_POST_ROUTING), -++ .hooks = { -++ [NF_INET_LOCAL_IN] = nft_do_chain_ipv4, -++ [NF_INET_LOCAL_OUT] = nft_ipv4_output, -++ [NF_INET_FORWARD] = nft_do_chain_ipv4, -++ [NF_INET_PRE_ROUTING] = nft_do_chain_ipv4, -++ [NF_INET_POST_ROUTING] = nft_do_chain_ipv4, -++ }, -+ }; -+ -+ static int __init nf_tables_ipv4_init(void) -+--- a/net/ipv6/netfilter/nf_tables_ipv6.c -++++ b/net/ipv6/netfilter/nf_tables_ipv6.c -+@@ -46,13 +46,6 @@ static struct nft_af_info nft_af_ipv6 __ -+ .family = NFPROTO_IPV6, -+ .nhooks = NF_INET_NUMHOOKS, -+ .owner = THIS_MODULE, -+- .hooks = { -+- [NF_INET_LOCAL_IN] = nft_do_chain_ipv6, -+- [NF_INET_LOCAL_OUT] = nft_ipv6_output, -+- [NF_INET_FORWARD] = nft_do_chain_ipv6, -+- [NF_INET_PRE_ROUTING] = nft_do_chain_ipv6, -+- [NF_INET_POST_ROUTING] = nft_do_chain_ipv6, -+- }, -+ }; -+ -+ static int nf_tables_ipv6_init_net(struct net *net) -+@@ -93,6 +86,13 @@ static const struct nf_chain_type filter -+ (1 << NF_INET_FORWARD) | -+ (1 << NF_INET_PRE_ROUTING) | -+ (1 << NF_INET_POST_ROUTING), -++ .hooks = { -++ [NF_INET_LOCAL_IN] = nft_do_chain_ipv6, -++ [NF_INET_LOCAL_OUT] = nft_ipv6_output, -++ [NF_INET_FORWARD] = nft_do_chain_ipv6, -++ [NF_INET_PRE_ROUTING] = nft_do_chain_ipv6, -++ [NF_INET_POST_ROUTING] = nft_do_chain_ipv6, -++ }, -+ }; -+ -+ static int __init nf_tables_ipv6_init(void) -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -1398,7 +1398,6 @@ static int nf_tables_addchain(struct nft -+ if (nla[NFTA_CHAIN_HOOK]) { -+ struct nft_chain_hook hook; -+ struct nf_hook_ops *ops; -+- nf_hookfn *hookfn; -+ -+ err = nft_chain_parse_hook(net, nla, afi, &hook, create); -+ if (err < 0) -+@@ -1424,7 +1423,6 @@ static int nf_tables_addchain(struct nft -+ static_branch_inc(&nft_counters_enabled); -+ } -+ -+- hookfn = hook.type->hooks[hook.num]; -+ basechain->type = hook.type; -+ chain = &basechain->chain; -+ -+@@ -1433,10 +1431,8 @@ static int nf_tables_addchain(struct nft -+ ops->hooknum = hook.num; -+ ops->priority = hook.priority; -+ ops->priv = chain; -+- ops->hook = afi->hooks[ops->hooknum]; -++ ops->hook = hook.type->hooks[ops->hooknum]; -+ ops->dev = hook.dev; -+- if (hookfn) -+- ops->hook = hookfn; -+ -+ if (basechain->type->type == NFT_CHAIN_T_NAT) -+ ops->nat_hook = true; -+--- a/net/netfilter/nf_tables_inet.c -++++ b/net/netfilter/nf_tables_inet.c -+@@ -74,13 +74,6 @@ static struct nft_af_info nft_af_inet __ -+ .family = NFPROTO_INET, -+ .nhooks = NF_INET_NUMHOOKS, -+ .owner = THIS_MODULE, -+- .hooks = { -+- [NF_INET_LOCAL_IN] = nft_do_chain_inet, -+- [NF_INET_LOCAL_OUT] = nft_inet_output, -+- [NF_INET_FORWARD] = nft_do_chain_inet, -+- [NF_INET_PRE_ROUTING] = nft_do_chain_inet, -+- [NF_INET_POST_ROUTING] = nft_do_chain_inet, -+- }, -+ }; -+ -+ static int __net_init nf_tables_inet_init_net(struct net *net) -+@@ -121,6 +114,13 @@ static const struct nf_chain_type filter -+ (1 << NF_INET_FORWARD) | -+ (1 << NF_INET_PRE_ROUTING) | -+ (1 << NF_INET_POST_ROUTING), -++ .hooks = { -++ [NF_INET_LOCAL_IN] = nft_do_chain_inet, -++ [NF_INET_LOCAL_OUT] = nft_inet_output, -++ [NF_INET_FORWARD] = nft_do_chain_inet, -++ [NF_INET_PRE_ROUTING] = nft_do_chain_inet, -++ [NF_INET_POST_ROUTING] = nft_do_chain_inet, -++ }, -+ }; -+ -+ static int __init nf_tables_inet_init(void) -+--- a/net/netfilter/nf_tables_netdev.c -++++ b/net/netfilter/nf_tables_netdev.c -+@@ -43,9 +43,6 @@ static struct nft_af_info nft_af_netdev -+ .nhooks = NF_NETDEV_NUMHOOKS, -+ .owner = THIS_MODULE, -+ .flags = NFT_AF_NEEDS_DEV, -+- .hooks = { -+- [NF_NETDEV_INGRESS] = nft_do_chain_netdev, -+- }, -+ }; -+ -+ static int nf_tables_netdev_init_net(struct net *net) -+@@ -82,6 +79,9 @@ static const struct nf_chain_type nft_fi -+ .family = NFPROTO_NETDEV, -+ .owner = THIS_MODULE, -+ .hook_mask = (1 << NF_NETDEV_INGRESS), -++ .hooks = { -++ [NF_NETDEV_INGRESS] = nft_do_chain_netdev, -++ }, -+ }; -+ -+ static void nft_netdev_event(unsigned long event, struct net_device *dev, -diff --git a/target/linux/generic/backport-4.14/313-v4.16-netfilter-remove-defensive-check-on-malformed-packet.patch b/target/linux/generic/backport-4.14/313-v4.16-netfilter-remove-defensive-check-on-malformed-packet.patch -new file mode 100644 -index 0000000000..5e56d0dc49 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/313-v4.16-netfilter-remove-defensive-check-on-malformed-packet.patch -@@ -0,0 +1,302 @@ -+From: Pablo Neira Ayuso -+Date: Sat, 30 Dec 2017 22:41:46 +0100 -+Subject: [PATCH] netfilter: remove defensive check on malformed packets from -+ raw sockets -+ -+Users cannot forge malformed IPv4/IPv6 headers via raw sockets that they -+can inject into the stack. Specifically, not for IPv4 since 55888dfb6ba7 -+("AF_RAW: Augment raw_send_hdrinc to expand skb to fit iphdr->ihl -+(v2)"). IPv6 raw sockets also ensure that packets have a well-formed -+IPv6 header available in the skbuff. -+ -+At quick glance, br_netfilter also validates layer 3 headers and it -+drops malformed both IPv4 and IPv6 packets. -+ -+Therefore, let's remove this defensive check all over the place. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/net/ipv4/netfilter/iptable_filter.c -++++ b/net/ipv4/netfilter/iptable_filter.c -+@@ -38,12 +38,6 @@ static unsigned int -+ iptable_filter_hook(void *priv, struct sk_buff *skb, -+ const struct nf_hook_state *state) -+ { -+- if (state->hook == NF_INET_LOCAL_OUT && -+- (skb->len < sizeof(struct iphdr) || -+- ip_hdrlen(skb) < sizeof(struct iphdr))) -+- /* root is playing with raw sockets. */ -+- return NF_ACCEPT; -+- -+ return ipt_do_table(skb, state, state->net->ipv4.iptable_filter); -+ } -+ -+--- a/net/ipv4/netfilter/iptable_mangle.c -++++ b/net/ipv4/netfilter/iptable_mangle.c -+@@ -49,11 +49,6 @@ ipt_mangle_out(struct sk_buff *skb, cons -+ u_int32_t mark; -+ int err; -+ -+- /* root is playing with raw sockets. */ -+- if (skb->len < sizeof(struct iphdr) || -+- ip_hdrlen(skb) < sizeof(struct iphdr)) -+- return NF_ACCEPT; -+- -+ /* Save things which could affect route */ -+ mark = skb->mark; -+ iph = ip_hdr(skb); -+--- a/net/ipv4/netfilter/iptable_raw.c -++++ b/net/ipv4/netfilter/iptable_raw.c -+@@ -26,12 +26,6 @@ static unsigned int -+ iptable_raw_hook(void *priv, struct sk_buff *skb, -+ const struct nf_hook_state *state) -+ { -+- if (state->hook == NF_INET_LOCAL_OUT && -+- (skb->len < sizeof(struct iphdr) || -+- ip_hdrlen(skb) < sizeof(struct iphdr))) -+- /* root is playing with raw sockets. */ -+- return NF_ACCEPT; -+- -+ return ipt_do_table(skb, state, state->net->ipv4.iptable_raw); -+ } -+ -+--- a/net/ipv4/netfilter/iptable_security.c -++++ b/net/ipv4/netfilter/iptable_security.c -+@@ -43,12 +43,6 @@ static unsigned int -+ iptable_security_hook(void *priv, struct sk_buff *skb, -+ const struct nf_hook_state *state) -+ { -+- if (state->hook == NF_INET_LOCAL_OUT && -+- (skb->len < sizeof(struct iphdr) || -+- ip_hdrlen(skb) < sizeof(struct iphdr))) -+- /* Somebody is playing with raw sockets. */ -+- return NF_ACCEPT; -+- -+ return ipt_do_table(skb, state, state->net->ipv4.iptable_security); -+ } -+ -+--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c -++++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c -+@@ -154,11 +154,6 @@ static unsigned int ipv4_conntrack_local -+ struct sk_buff *skb, -+ const struct nf_hook_state *state) -+ { -+- /* root is playing with raw sockets. */ -+- if (skb->len < sizeof(struct iphdr) || -+- ip_hdrlen(skb) < sizeof(struct iphdr)) -+- return NF_ACCEPT; -+- -+ if (ip_is_fragment(ip_hdr(skb))) { /* IP_NODEFRAG setsockopt set */ -+ enum ip_conntrack_info ctinfo; -+ struct nf_conn *tmpl; -+--- a/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c -++++ b/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c -+@@ -355,11 +355,6 @@ nf_nat_ipv4_out(void *priv, struct sk_bu -+ #endif -+ unsigned int ret; -+ -+- /* root is playing with raw sockets. */ -+- if (skb->len < sizeof(struct iphdr) || -+- ip_hdrlen(skb) < sizeof(struct iphdr)) -+- return NF_ACCEPT; -+- -+ ret = nf_nat_ipv4_fn(priv, skb, state, do_chain); -+ #ifdef CONFIG_XFRM -+ if (ret != NF_DROP && ret != NF_STOLEN && -+@@ -395,11 +390,6 @@ nf_nat_ipv4_local_fn(void *priv, struct -+ unsigned int ret; -+ int err; -+ -+- /* root is playing with raw sockets. */ -+- if (skb->len < sizeof(struct iphdr) || -+- ip_hdrlen(skb) < sizeof(struct iphdr)) -+- return NF_ACCEPT; -+- -+ ret = nf_nat_ipv4_fn(priv, skb, state, do_chain); -+ if (ret != NF_DROP && ret != NF_STOLEN && -+ (ct = nf_ct_get(skb, &ctinfo)) != NULL) { -+--- a/net/ipv4/netfilter/nf_tables_ipv4.c -++++ b/net/ipv4/netfilter/nf_tables_ipv4.c -+@@ -30,21 +30,6 @@ static unsigned int nft_do_chain_ipv4(vo -+ return nft_do_chain(&pkt, priv); -+ } -+ -+-static unsigned int nft_ipv4_output(void *priv, -+- struct sk_buff *skb, -+- const struct nf_hook_state *state) -+-{ -+- if (unlikely(skb->len < sizeof(struct iphdr) || -+- ip_hdr(skb)->ihl < sizeof(struct iphdr) / 4)) { -+- if (net_ratelimit()) -+- pr_info("nf_tables_ipv4: ignoring short SOCK_RAW " -+- "packet\n"); -+- return NF_ACCEPT; -+- } -+- -+- return nft_do_chain_ipv4(priv, skb, state); -+-} -+- -+ static struct nft_af_info nft_af_ipv4 __read_mostly = { -+ .family = NFPROTO_IPV4, -+ .nhooks = NF_INET_NUMHOOKS, -+@@ -91,7 +76,7 @@ static const struct nf_chain_type filter -+ (1 << NF_INET_POST_ROUTING), -+ .hooks = { -+ [NF_INET_LOCAL_IN] = nft_do_chain_ipv4, -+- [NF_INET_LOCAL_OUT] = nft_ipv4_output, -++ [NF_INET_LOCAL_OUT] = nft_do_chain_ipv4, -+ [NF_INET_FORWARD] = nft_do_chain_ipv4, -+ [NF_INET_PRE_ROUTING] = nft_do_chain_ipv4, -+ [NF_INET_POST_ROUTING] = nft_do_chain_ipv4, -+--- a/net/ipv4/netfilter/nft_chain_route_ipv4.c -++++ b/net/ipv4/netfilter/nft_chain_route_ipv4.c -+@@ -33,11 +33,6 @@ static unsigned int nf_route_table_hook( -+ const struct iphdr *iph; -+ int err; -+ -+- /* root is playing with raw sockets. */ -+- if (skb->len < sizeof(struct iphdr) || -+- ip_hdrlen(skb) < sizeof(struct iphdr)) -+- return NF_ACCEPT; -+- -+ nft_set_pktinfo(&pkt, skb, state); -+ nft_set_pktinfo_ipv4(&pkt, skb); -+ -+--- a/net/ipv6/netfilter/ip6table_mangle.c -++++ b/net/ipv6/netfilter/ip6table_mangle.c -+@@ -42,14 +42,6 @@ ip6t_mangle_out(struct sk_buff *skb, con -+ u_int8_t hop_limit; -+ u_int32_t flowlabel, mark; -+ int err; -+-#if 0 -+- /* root is playing with raw sockets. */ -+- if (skb->len < sizeof(struct iphdr) || -+- ip_hdrlen(skb) < sizeof(struct iphdr)) { -+- net_warn_ratelimited("ip6t_hook: happy cracking\n"); -+- return NF_ACCEPT; -+- } -+-#endif -+ -+ /* save source/dest address, mark, hoplimit, flowlabel, priority, */ -+ memcpy(&saddr, &ipv6_hdr(skb)->saddr, sizeof(saddr)); -+--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c -++++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c -+@@ -176,11 +176,6 @@ static unsigned int ipv6_conntrack_local -+ struct sk_buff *skb, -+ const struct nf_hook_state *state) -+ { -+- /* root is playing with raw sockets. */ -+- if (skb->len < sizeof(struct ipv6hdr)) { -+- net_notice_ratelimited("ipv6_conntrack_local: packet too short\n"); -+- return NF_ACCEPT; -+- } -+ return nf_conntrack_in(state->net, PF_INET6, state->hook, skb); -+ } -+ -+--- a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c -++++ b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c -+@@ -372,10 +372,6 @@ nf_nat_ipv6_out(void *priv, struct sk_bu -+ #endif -+ unsigned int ret; -+ -+- /* root is playing with raw sockets. */ -+- if (skb->len < sizeof(struct ipv6hdr)) -+- return NF_ACCEPT; -+- -+ ret = nf_nat_ipv6_fn(priv, skb, state, do_chain); -+ #ifdef CONFIG_XFRM -+ if (ret != NF_DROP && ret != NF_STOLEN && -+@@ -411,10 +407,6 @@ nf_nat_ipv6_local_fn(void *priv, struct -+ unsigned int ret; -+ int err; -+ -+- /* root is playing with raw sockets. */ -+- if (skb->len < sizeof(struct ipv6hdr)) -+- return NF_ACCEPT; -+- -+ ret = nf_nat_ipv6_fn(priv, skb, state, do_chain); -+ if (ret != NF_DROP && ret != NF_STOLEN && -+ (ct = nf_ct_get(skb, &ctinfo)) != NULL) { -+--- a/net/ipv6/netfilter/nf_tables_ipv6.c -++++ b/net/ipv6/netfilter/nf_tables_ipv6.c -+@@ -28,20 +28,6 @@ static unsigned int nft_do_chain_ipv6(vo -+ return nft_do_chain(&pkt, priv); -+ } -+ -+-static unsigned int nft_ipv6_output(void *priv, -+- struct sk_buff *skb, -+- const struct nf_hook_state *state) -+-{ -+- if (unlikely(skb->len < sizeof(struct ipv6hdr))) { -+- if (net_ratelimit()) -+- pr_info("nf_tables_ipv6: ignoring short SOCK_RAW " -+- "packet\n"); -+- return NF_ACCEPT; -+- } -+- -+- return nft_do_chain_ipv6(priv, skb, state); -+-} -+- -+ static struct nft_af_info nft_af_ipv6 __read_mostly = { -+ .family = NFPROTO_IPV6, -+ .nhooks = NF_INET_NUMHOOKS, -+@@ -88,7 +74,7 @@ static const struct nf_chain_type filter -+ (1 << NF_INET_POST_ROUTING), -+ .hooks = { -+ [NF_INET_LOCAL_IN] = nft_do_chain_ipv6, -+- [NF_INET_LOCAL_OUT] = nft_ipv6_output, -++ [NF_INET_LOCAL_OUT] = nft_do_chain_ipv6, -+ [NF_INET_FORWARD] = nft_do_chain_ipv6, -+ [NF_INET_PRE_ROUTING] = nft_do_chain_ipv6, -+ [NF_INET_POST_ROUTING] = nft_do_chain_ipv6, -+--- a/net/netfilter/nf_tables_inet.c -++++ b/net/netfilter/nf_tables_inet.c -+@@ -38,38 +38,6 @@ static unsigned int nft_do_chain_inet(vo -+ return nft_do_chain(&pkt, priv); -+ } -+ -+-static unsigned int nft_inet_output(void *priv, struct sk_buff *skb, -+- const struct nf_hook_state *state) -+-{ -+- struct nft_pktinfo pkt; -+- -+- nft_set_pktinfo(&pkt, skb, state); -+- -+- switch (state->pf) { -+- case NFPROTO_IPV4: -+- if (unlikely(skb->len < sizeof(struct iphdr) || -+- ip_hdr(skb)->ihl < sizeof(struct iphdr) / 4)) { -+- if (net_ratelimit()) -+- pr_info("ignoring short SOCK_RAW packet\n"); -+- return NF_ACCEPT; -+- } -+- nft_set_pktinfo_ipv4(&pkt, skb); -+- break; -+- case NFPROTO_IPV6: -+- if (unlikely(skb->len < sizeof(struct ipv6hdr))) { -+- if (net_ratelimit()) -+- pr_info("ignoring short SOCK_RAW packet\n"); -+- return NF_ACCEPT; -+- } -+- nft_set_pktinfo_ipv6(&pkt, skb); -+- break; -+- default: -+- break; -+- } -+- -+- return nft_do_chain(&pkt, priv); -+-} -+- -+ static struct nft_af_info nft_af_inet __read_mostly = { -+ .family = NFPROTO_INET, -+ .nhooks = NF_INET_NUMHOOKS, -+@@ -116,7 +84,7 @@ static const struct nf_chain_type filter -+ (1 << NF_INET_POST_ROUTING), -+ .hooks = { -+ [NF_INET_LOCAL_IN] = nft_do_chain_inet, -+- [NF_INET_LOCAL_OUT] = nft_inet_output, -++ [NF_INET_LOCAL_OUT] = nft_do_chain_inet, -+ [NF_INET_FORWARD] = nft_do_chain_inet, -+ [NF_INET_PRE_ROUTING] = nft_do_chain_inet, -+ [NF_INET_POST_ROUTING] = nft_do_chain_inet, -diff --git a/target/linux/generic/backport-4.14/314-v4.16-netfilter-meta-secpath-support.patch b/target/linux/generic/backport-4.14/314-v4.16-netfilter-meta-secpath-support.patch -new file mode 100644 -index 0000000000..7aab67fc2c ---- /dev/null -+++ b/target/linux/generic/backport-4.14/314-v4.16-netfilter-meta-secpath-support.patch -@@ -0,0 +1,101 @@ -+From: Florian Westphal -+Date: Wed, 6 Dec 2017 16:18:16 +0100 -+Subject: [PATCH] netfilter: meta: secpath support -+ -+replacement for iptables "-m policy --dir in --policy {ipsec,none}". -+ -+Signed-off-by: Florian Westphal -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/uapi/linux/netfilter/nf_tables.h -++++ b/include/uapi/linux/netfilter/nf_tables.h -+@@ -777,6 +777,7 @@ enum nft_exthdr_attributes { -+ * @NFT_META_OIFGROUP: packet output interface group -+ * @NFT_META_CGROUP: socket control group (skb->sk->sk_classid) -+ * @NFT_META_PRANDOM: a 32bit pseudo-random number -++ * @NFT_META_SECPATH: boolean, secpath_exists (!!skb->sp) -+ */ -+ enum nft_meta_keys { -+ NFT_META_LEN, -+@@ -804,6 +805,7 @@ enum nft_meta_keys { -+ NFT_META_OIFGROUP, -+ NFT_META_CGROUP, -+ NFT_META_PRANDOM, -++ NFT_META_SECPATH, -+ }; -+ -+ /** -+--- a/net/netfilter/nft_meta.c -++++ b/net/netfilter/nft_meta.c -+@@ -210,6 +210,11 @@ void nft_meta_get_eval(const struct nft_ -+ *dest = prandom_u32_state(state); -+ break; -+ } -++#ifdef CONFIG_XFRM -++ case NFT_META_SECPATH: -++ nft_reg_store8(dest, !!skb->sp); -++ break; -++#endif -+ default: -+ WARN_ON(1); -+ goto err; -+@@ -310,6 +315,11 @@ int nft_meta_get_init(const struct nft_c -+ prandom_init_once(&nft_prandom_state); -+ len = sizeof(u32); -+ break; -++#ifdef CONFIG_XFRM -++ case NFT_META_SECPATH: -++ len = sizeof(u8); -++ break; -++#endif -+ default: -+ return -EOPNOTSUPP; -+ } -+@@ -320,6 +330,38 @@ int nft_meta_get_init(const struct nft_c -+ } -+ EXPORT_SYMBOL_GPL(nft_meta_get_init); -+ -++static int nft_meta_get_validate(const struct nft_ctx *ctx, -++ const struct nft_expr *expr, -++ const struct nft_data **data) -++{ -++#ifdef CONFIG_XFRM -++ const struct nft_meta *priv = nft_expr_priv(expr); -++ unsigned int hooks; -++ -++ if (priv->key != NFT_META_SECPATH) -++ return 0; -++ -++ switch (ctx->afi->family) { -++ case NFPROTO_NETDEV: -++ hooks = 1 << NF_NETDEV_INGRESS; -++ break; -++ case NFPROTO_IPV4: -++ case NFPROTO_IPV6: -++ case NFPROTO_INET: -++ hooks = (1 << NF_INET_PRE_ROUTING) | -++ (1 << NF_INET_LOCAL_IN) | -++ (1 << NF_INET_FORWARD); -++ break; -++ default: -++ return -EOPNOTSUPP; -++ } -++ -++ return nft_chain_validate_hooks(ctx->chain, hooks); -++#else -++ return 0; -++#endif -++} -++ -+ int nft_meta_set_validate(const struct nft_ctx *ctx, -+ const struct nft_expr *expr, -+ const struct nft_data **data) -+@@ -436,6 +478,7 @@ static const struct nft_expr_ops nft_met -+ .eval = nft_meta_get_eval, -+ .init = nft_meta_get_init, -+ .dump = nft_meta_get_dump, -++ .validate = nft_meta_get_validate, -+ }; -+ -+ static const struct nft_expr_ops nft_meta_set_ops = { -diff --git a/target/linux/generic/backport-4.14/315-v4.15-netfilter-conntrack-move-nf_ct_netns_-get-put-to-cor.patch b/target/linux/generic/backport-4.14/315-v4.15-netfilter-conntrack-move-nf_ct_netns_-get-put-to-cor.patch -new file mode 100644 -index 0000000000..7f6e90470a ---- /dev/null -+++ b/target/linux/generic/backport-4.14/315-v4.15-netfilter-conntrack-move-nf_ct_netns_-get-put-to-cor.patch -@@ -0,0 +1,142 @@ -+From: Pablo Neira Ayuso -+Date: Fri, 3 Nov 2017 16:26:32 +0100 -+Subject: [PATCH] netfilter: conntrack: move nf_ct_netns_{get,put}() to core -+ -+So we can call this from other expression that need conntrack in place -+to work. -+ -+Signed-off-by: Pablo Neira Ayuso -+Acked-by: Florian Westphal -+--- -+ -+--- a/net/netfilter/nf_conntrack_proto.c -++++ b/net/netfilter/nf_conntrack_proto.c -+@@ -125,7 +125,7 @@ void nf_ct_l3proto_module_put(unsigned s -+ } -+ EXPORT_SYMBOL_GPL(nf_ct_l3proto_module_put); -+ -+-int nf_ct_netns_get(struct net *net, u8 nfproto) -++static int nf_ct_netns_do_get(struct net *net, u8 nfproto) -+ { -+ const struct nf_conntrack_l3proto *l3proto; -+ int ret; -+@@ -150,9 +150,33 @@ int nf_ct_netns_get(struct net *net, u8 -+ -+ return ret; -+ } -++ -++int nf_ct_netns_get(struct net *net, u8 nfproto) -++{ -++ int err; -++ -++ if (nfproto == NFPROTO_INET) { -++ err = nf_ct_netns_do_get(net, NFPROTO_IPV4); -++ if (err < 0) -++ goto err1; -++ err = nf_ct_netns_do_get(net, NFPROTO_IPV6); -++ if (err < 0) -++ goto err2; -++ } else { -++ err = nf_ct_netns_do_get(net, nfproto); -++ if (err < 0) -++ goto err1; -++ } -++ return 0; -++ -++err2: -++ nf_ct_netns_put(net, NFPROTO_IPV4); -++err1: -++ return err; -++} -+ EXPORT_SYMBOL_GPL(nf_ct_netns_get); -+ -+-void nf_ct_netns_put(struct net *net, u8 nfproto) -++static void nf_ct_netns_do_put(struct net *net, u8 nfproto) -+ { -+ const struct nf_conntrack_l3proto *l3proto; -+ -+@@ -171,6 +195,15 @@ void nf_ct_netns_put(struct net *net, u8 -+ -+ nf_ct_l3proto_module_put(nfproto); -+ } -++ -++void nf_ct_netns_put(struct net *net, uint8_t nfproto) -++{ -++ if (nfproto == NFPROTO_INET) { -++ nf_ct_netns_do_put(net, NFPROTO_IPV4); -++ nf_ct_netns_do_put(net, NFPROTO_IPV6); -++ } else -++ nf_ct_netns_do_put(net, nfproto); -++} -+ EXPORT_SYMBOL_GPL(nf_ct_netns_put); -+ -+ const struct nf_conntrack_l4proto * -+--- a/net/netfilter/nft_ct.c -++++ b/net/netfilter/nft_ct.c -+@@ -312,39 +312,6 @@ static const struct nla_policy nft_ct_po -+ [NFTA_CT_SREG] = { .type = NLA_U32 }, -+ }; -+ -+-static int nft_ct_netns_get(struct net *net, uint8_t family) -+-{ -+- int err; -+- -+- if (family == NFPROTO_INET) { -+- err = nf_ct_netns_get(net, NFPROTO_IPV4); -+- if (err < 0) -+- goto err1; -+- err = nf_ct_netns_get(net, NFPROTO_IPV6); -+- if (err < 0) -+- goto err2; -+- } else { -+- err = nf_ct_netns_get(net, family); -+- if (err < 0) -+- goto err1; -+- } -+- return 0; -+- -+-err2: -+- nf_ct_netns_put(net, NFPROTO_IPV4); -+-err1: -+- return err; -+-} -+- -+-static void nft_ct_netns_put(struct net *net, uint8_t family) -+-{ -+- if (family == NFPROTO_INET) { -+- nf_ct_netns_put(net, NFPROTO_IPV4); -+- nf_ct_netns_put(net, NFPROTO_IPV6); -+- } else -+- nf_ct_netns_put(net, family); -+-} -+- -+ #ifdef CONFIG_NF_CONNTRACK_ZONES -+ static void nft_ct_tmpl_put_pcpu(void) -+ { -+@@ -489,7 +456,7 @@ static int nft_ct_get_init(const struct -+ if (err < 0) -+ return err; -+ -+- err = nft_ct_netns_get(ctx->net, ctx->afi->family); -++ err = nf_ct_netns_get(ctx->net, ctx->afi->family); -+ if (err < 0) -+ return err; -+ -+@@ -583,7 +550,7 @@ static int nft_ct_set_init(const struct -+ if (err < 0) -+ goto err1; -+ -+- err = nft_ct_netns_get(ctx->net, ctx->afi->family); -++ err = nf_ct_netns_get(ctx->net, ctx->afi->family); -+ if (err < 0) -+ goto err1; -+ -+@@ -606,7 +573,7 @@ static void nft_ct_set_destroy(const str -+ struct nft_ct *priv = nft_expr_priv(expr); -+ -+ __nft_ct_set_destroy(ctx, priv); -+- nft_ct_netns_put(ctx->net, ctx->afi->family); -++ nf_ct_netns_put(ctx->net, ctx->afi->family); -+ } -+ -+ static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr) -diff --git a/target/linux/generic/backport-4.14/320-v4.16-netfilter-nf_conntrack-add-IPS_OFFLOAD-status-bit.patch b/target/linux/generic/backport-4.14/320-v4.16-netfilter-nf_conntrack-add-IPS_OFFLOAD-status-bit.patch -new file mode 100644 -index 0000000000..885d632d22 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/320-v4.16-netfilter-nf_conntrack-add-IPS_OFFLOAD-status-bit.patch -@@ -0,0 +1,169 @@ -+From: Pablo Neira Ayuso -+Date: Sun, 7 Jan 2018 01:03:56 +0100 -+Subject: [PATCH] netfilter: nf_conntrack: add IPS_OFFLOAD status bit -+ -+This new bit tells us that the conntrack entry is owned by the flow -+table offload infrastructure. -+ -+ # cat /proc/net/nf_conntrack -+ ipv4 2 tcp 6 src=10.141.10.2 dst=147.75.205.195 sport=36392 dport=443 src=147.75.205.195 dst=192.168.2.195 sport=443 dport=36392 [OFFLOAD] mark=0 zone=0 use=2 -+ -+Note the [OFFLOAD] tag in the listing. -+ -+The timer of such conntrack entries look like stopped from userspace. -+In practise, to make sure the conntrack entry does not go away, the -+conntrack timer is periodically set to an arbitrary large value that -+gets refreshed on every iteration from the garbage collector, so it -+never expires- and they display no internal state in the case of TCP -+flows. This allows us to save a bitcheck from the packet path via -+nf_ct_is_expired(). -+ -+Conntrack entries that have been offloaded to the flow table -+infrastructure cannot be deleted/flushed via ctnetlink. The flow table -+infrastructure is also responsible for releasing this conntrack entry. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/uapi/linux/netfilter/nf_conntrack_common.h -++++ b/include/uapi/linux/netfilter/nf_conntrack_common.h -+@@ -101,12 +101,16 @@ enum ip_conntrack_status { -+ IPS_HELPER_BIT = 13, -+ IPS_HELPER = (1 << IPS_HELPER_BIT), -+ -++ /* Conntrack has been offloaded to flow table. */ -++ IPS_OFFLOAD_BIT = 14, -++ IPS_OFFLOAD = (1 << IPS_OFFLOAD_BIT), -++ -+ /* Be careful here, modifying these bits can make things messy, -+ * so don't let users modify them directly. -+ */ -+ IPS_UNCHANGEABLE_MASK = (IPS_NAT_DONE_MASK | IPS_NAT_MASK | -+ IPS_EXPECTED | IPS_CONFIRMED | IPS_DYING | -+- IPS_SEQ_ADJUST | IPS_TEMPLATE), -++ IPS_SEQ_ADJUST | IPS_TEMPLATE | IPS_OFFLOAD), -+ -+ __IPS_MAX_BIT = 14, -+ }; -+--- a/net/netfilter/nf_conntrack_core.c -++++ b/net/netfilter/nf_conntrack_core.c -+@@ -974,6 +974,9 @@ static unsigned int early_drop_list(stru -+ hlist_nulls_for_each_entry_rcu(h, n, head, hnnode) { -+ tmp = nf_ct_tuplehash_to_ctrack(h); -+ -++ if (test_bit(IPS_OFFLOAD_BIT, &tmp->status)) -++ continue; -++ -+ if (nf_ct_is_expired(tmp)) { -+ nf_ct_gc_expired(tmp); -+ continue; -+@@ -1051,6 +1054,18 @@ static bool gc_worker_can_early_drop(con -+ return false; -+ } -+ -++#define DAY (86400 * HZ) -++ -++/* Set an arbitrary timeout large enough not to ever expire, this save -++ * us a check for the IPS_OFFLOAD_BIT from the packet path via -++ * nf_ct_is_expired(). -++ */ -++static void nf_ct_offload_timeout(struct nf_conn *ct) -++{ -++ if (nf_ct_expires(ct) < DAY / 2) -++ ct->timeout = nfct_time_stamp + DAY; -++} -++ -+ static void gc_worker(struct work_struct *work) -+ { -+ unsigned int min_interval = max(HZ / GC_MAX_BUCKETS_DIV, 1u); -+@@ -1087,6 +1102,11 @@ static void gc_worker(struct work_struct -+ tmp = nf_ct_tuplehash_to_ctrack(h); -+ -+ scanned++; -++ if (test_bit(IPS_OFFLOAD_BIT, &tmp->status)) { -++ nf_ct_offload_timeout(tmp); -++ continue; -++ } -++ -+ if (nf_ct_is_expired(tmp)) { -+ nf_ct_gc_expired(tmp); -+ expired_count++; -+--- a/net/netfilter/nf_conntrack_netlink.c -++++ b/net/netfilter/nf_conntrack_netlink.c -+@@ -1123,6 +1123,14 @@ static const struct nla_policy ct_nla_po -+ .len = NF_CT_LABELS_MAX_SIZE }, -+ }; -+ -++static int ctnetlink_flush_iterate(struct nf_conn *ct, void *data) -++{ -++ if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) -++ return 0; -++ -++ return ctnetlink_filter_match(ct, data); -++} -++ -+ static int ctnetlink_flush_conntrack(struct net *net, -+ const struct nlattr * const cda[], -+ u32 portid, int report) -+@@ -1135,7 +1143,7 @@ static int ctnetlink_flush_conntrack(str -+ return PTR_ERR(filter); -+ } -+ -+- nf_ct_iterate_cleanup_net(net, ctnetlink_filter_match, filter, -++ nf_ct_iterate_cleanup_net(net, ctnetlink_flush_iterate, filter, -+ portid, report); -+ kfree(filter); -+ -+@@ -1181,6 +1189,11 @@ static int ctnetlink_del_conntrack(struc -+ -+ ct = nf_ct_tuplehash_to_ctrack(h); -+ -++ if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) { -++ nf_ct_put(ct); -++ return -EBUSY; -++ } -++ -+ if (cda[CTA_ID]) { -+ __be32 id = nla_get_be32(cda[CTA_ID]); -+ -+--- a/net/netfilter/nf_conntrack_proto_tcp.c -++++ b/net/netfilter/nf_conntrack_proto_tcp.c -+@@ -305,6 +305,9 @@ static bool tcp_invert_tuple(struct nf_c -+ /* Print out the private part of the conntrack. */ -+ static void tcp_print_conntrack(struct seq_file *s, struct nf_conn *ct) -+ { -++ if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) -++ return; -++ -+ seq_printf(s, "%s ", tcp_conntrack_names[ct->proto.tcp.state]); -+ } -+ #endif -+--- a/net/netfilter/nf_conntrack_standalone.c -++++ b/net/netfilter/nf_conntrack_standalone.c -+@@ -309,10 +309,12 @@ static int ct_seq_show(struct seq_file * -+ WARN_ON(!l4proto); -+ -+ ret = -ENOSPC; -+- seq_printf(s, "%-8s %u %-8s %u %ld ", -++ seq_printf(s, "%-8s %u %-8s %u ", -+ l3proto_name(l3proto->l3proto), nf_ct_l3num(ct), -+- l4proto_name(l4proto->l4proto), nf_ct_protonum(ct), -+- nf_ct_expires(ct) / HZ); -++ l4proto_name(l4proto->l4proto), nf_ct_protonum(ct)); -++ -++ if (!test_bit(IPS_OFFLOAD_BIT, &ct->status)) -++ seq_printf(s, "%ld ", nf_ct_expires(ct) / HZ); -+ -+ if (l4proto->print_conntrack) -+ l4proto->print_conntrack(s, ct); -+@@ -339,7 +341,9 @@ static int ct_seq_show(struct seq_file * -+ if (seq_print_acct(s, ct, IP_CT_DIR_REPLY)) -+ goto release; -+ -+- if (test_bit(IPS_ASSURED_BIT, &ct->status)) -++ if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) -++ seq_puts(s, "[OFFLOAD] "); -++ else if (test_bit(IPS_ASSURED_BIT, &ct->status)) -+ seq_puts(s, "[ASSURED] "); -+ -+ if (seq_has_overflowed(s)) -diff --git a/target/linux/generic/backport-4.14/321-v4.16-netfilter-nf_tables-add-flow-table-netlink-frontend.patch b/target/linux/generic/backport-4.14/321-v4.16-netfilter-nf_tables-add-flow-table-netlink-frontend.patch -new file mode 100644 -index 0000000000..f0109e4823 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/321-v4.16-netfilter-nf_tables-add-flow-table-netlink-frontend.patch -@@ -0,0 +1,1079 @@ -+From: Pablo Neira Ayuso -+Date: Sun, 7 Jan 2018 01:04:07 +0100 -+Subject: [PATCH] netfilter: nf_tables: add flow table netlink frontend -+ -+This patch introduces a netlink control plane to create, delete and dump -+flow tables. Flow tables are identified by name, this name is used from -+rules to refer to an specific flow table. Flow tables use the rhashtable -+class and a generic garbage collector to remove expired entries. -+ -+This also adds the infrastructure to add different flow table types, so -+we can add one for each layer 3 protocol family. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ create mode 100644 include/net/netfilter/nf_flow_table.h -+ -+--- /dev/null -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -0,0 +1,23 @@ -++#ifndef _NF_FLOW_TABLE_H -++#define _NF_FLOW_TABLE_H -++ -++#include -++ -++struct nf_flowtable; -++ -++struct nf_flowtable_type { -++ struct list_head list; -++ int family; -++ void (*gc)(struct work_struct *work); -++ const struct rhashtable_params *params; -++ nf_hookfn *hook; -++ struct module *owner; -++}; -++ -++struct nf_flowtable { -++ struct rhashtable rhashtable; -++ const struct nf_flowtable_type *type; -++ struct delayed_work gc_work; -++}; -++ -++#endif /* _FLOW_OFFLOAD_H */ -+--- a/include/net/netfilter/nf_tables.h -++++ b/include/net/netfilter/nf_tables.h -+@@ -9,6 +9,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ -+ #define NFT_JUMP_STACK_SIZE 16 -+@@ -939,6 +940,7 @@ unsigned int nft_do_chain(struct nft_pkt -+ * @chains: chains in the table -+ * @sets: sets in the table -+ * @objects: stateful objects in the table -++ * @flowtables: flow tables in the table -+ * @hgenerator: handle generator state -+ * @use: number of chain references to this table -+ * @flags: table flag (see enum nft_table_flags) -+@@ -950,6 +952,7 @@ struct nft_table { -+ struct list_head chains; -+ struct list_head sets; -+ struct list_head objects; -++ struct list_head flowtables; -+ u64 hgenerator; -+ u32 use; -+ u16 flags:14, -+@@ -1081,6 +1084,44 @@ int nft_register_obj(struct nft_object_t -+ void nft_unregister_obj(struct nft_object_type *obj_type); -+ -+ /** -++ * struct nft_flowtable - nf_tables flow table -++ * -++ * @list: flow table list node in table list -++ * @table: the table the flow table is contained in -++ * @name: name of this flow table -++ * @hooknum: hook number -++ * @priority: hook priority -++ * @ops_len: number of hooks in array -++ * @genmask: generation mask -++ * @use: number of references to this flow table -++ * @data: rhashtable and garbage collector -++ * @ops: array of hooks -++ */ -++struct nft_flowtable { -++ struct list_head list; -++ struct nft_table *table; -++ char *name; -++ int hooknum; -++ int priority; -++ int ops_len; -++ u32 genmask:2, -++ use:30; -++ /* runtime data below here */ -++ struct nf_hook_ops *ops ____cacheline_aligned; -++ struct nf_flowtable data; -++}; -++ -++struct nft_flowtable *nf_tables_flowtable_lookup(const struct nft_table *table, -++ const struct nlattr *nla, -++ u8 genmask); -++void nft_flow_table_iterate(struct net *net, -++ void (*iter)(struct nf_flowtable *flowtable, void *data), -++ void *data); -++ -++void nft_register_flowtable_type(struct nf_flowtable_type *type); -++void nft_unregister_flowtable_type(struct nf_flowtable_type *type); -++ -++/** -+ * struct nft_traceinfo - nft tracing information and state -+ * -+ * @pkt: pktinfo currently processed -+@@ -1316,4 +1357,11 @@ struct nft_trans_obj { -+ #define nft_trans_obj(trans) \ -+ (((struct nft_trans_obj *)trans->data)->obj) -+ -++struct nft_trans_flowtable { -++ struct nft_flowtable *flowtable; -++}; -++ -++#define nft_trans_flowtable(trans) \ -++ (((struct nft_trans_flowtable *)trans->data)->flowtable) -++ -+ #endif /* _NET_NF_TABLES_H */ -+--- a/include/uapi/linux/netfilter/nf_tables.h -++++ b/include/uapi/linux/netfilter/nf_tables.h -+@@ -92,6 +92,9 @@ enum nft_verdicts { -+ * @NFT_MSG_GETOBJ: get a stateful object (enum nft_obj_attributes) -+ * @NFT_MSG_DELOBJ: delete a stateful object (enum nft_obj_attributes) -+ * @NFT_MSG_GETOBJ_RESET: get and reset a stateful object (enum nft_obj_attributes) -++ * @NFT_MSG_NEWFLOWTABLE: add new flow table (enum nft_flowtable_attributes) -++ * @NFT_MSG_GETFLOWTABLE: get flow table (enum nft_flowtable_attributes) -++ * @NFT_MSG_DELFLOWTABLE: delete flow table (enum nft_flowtable_attributes) -+ */ -+ enum nf_tables_msg_types { -+ NFT_MSG_NEWTABLE, -+@@ -116,6 +119,9 @@ enum nf_tables_msg_types { -+ NFT_MSG_GETOBJ, -+ NFT_MSG_DELOBJ, -+ NFT_MSG_GETOBJ_RESET, -++ NFT_MSG_NEWFLOWTABLE, -++ NFT_MSG_GETFLOWTABLE, -++ NFT_MSG_DELFLOWTABLE, -+ NFT_MSG_MAX, -+ }; -+ -+@@ -1310,6 +1316,53 @@ enum nft_object_attributes { -+ #define NFTA_OBJ_MAX (__NFTA_OBJ_MAX - 1) -+ -+ /** -++ * enum nft_flowtable_attributes - nf_tables flow table netlink attributes -++ * -++ * @NFTA_FLOWTABLE_TABLE: name of the table containing the expression (NLA_STRING) -++ * @NFTA_FLOWTABLE_NAME: name of this flow table (NLA_STRING) -++ * @NFTA_FLOWTABLE_HOOK: netfilter hook configuration(NLA_U32) -++ * @NFTA_FLOWTABLE_USE: number of references to this flow table (NLA_U32) -++ */ -++enum nft_flowtable_attributes { -++ NFTA_FLOWTABLE_UNSPEC, -++ NFTA_FLOWTABLE_TABLE, -++ NFTA_FLOWTABLE_NAME, -++ NFTA_FLOWTABLE_HOOK, -++ NFTA_FLOWTABLE_USE, -++ __NFTA_FLOWTABLE_MAX -++}; -++#define NFTA_FLOWTABLE_MAX (__NFTA_FLOWTABLE_MAX - 1) -++ -++/** -++ * enum nft_flowtable_hook_attributes - nf_tables flow table hook netlink attributes -++ * -++ * @NFTA_FLOWTABLE_HOOK_NUM: netfilter hook number (NLA_U32) -++ * @NFTA_FLOWTABLE_HOOK_PRIORITY: netfilter hook priority (NLA_U32) -++ * @NFTA_FLOWTABLE_HOOK_DEVS: input devices this flow table is bound to (NLA_NESTED) -++ */ -++enum nft_flowtable_hook_attributes { -++ NFTA_FLOWTABLE_HOOK_UNSPEC, -++ NFTA_FLOWTABLE_HOOK_NUM, -++ NFTA_FLOWTABLE_HOOK_PRIORITY, -++ NFTA_FLOWTABLE_HOOK_DEVS, -++ __NFTA_FLOWTABLE_HOOK_MAX -++}; -++#define NFTA_FLOWTABLE_HOOK_MAX (__NFTA_FLOWTABLE_HOOK_MAX - 1) -++ -++/** -++ * enum nft_device_attributes - nf_tables device netlink attributes -++ * -++ * @NFTA_DEVICE_NAME: name of this device (NLA_STRING) -++ */ -++enum nft_devices_attributes { -++ NFTA_DEVICE_UNSPEC, -++ NFTA_DEVICE_NAME, -++ __NFTA_DEVICE_MAX -++}; -++#define NFTA_DEVICE_MAX (__NFTA_DEVICE_MAX - 1) -++ -++ -++/** -+ * enum nft_trace_attributes - nf_tables trace netlink attributes -+ * -+ * @NFTA_TRACE_TABLE: name of the table (NLA_STRING) -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -17,6 +17,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ #include -+@@ -24,6 +25,7 @@ -+ -+ static LIST_HEAD(nf_tables_expressions); -+ static LIST_HEAD(nf_tables_objects); -++static LIST_HEAD(nf_tables_flowtables); -+ -+ /** -+ * nft_register_afinfo - register nf_tables address family info -+@@ -389,6 +391,40 @@ static int nft_delobj(struct nft_ctx *ct -+ return err; -+ } -+ -++static int nft_trans_flowtable_add(struct nft_ctx *ctx, int msg_type, -++ struct nft_flowtable *flowtable) -++{ -++ struct nft_trans *trans; -++ -++ trans = nft_trans_alloc(ctx, msg_type, -++ sizeof(struct nft_trans_flowtable)); -++ if (trans == NULL) -++ return -ENOMEM; -++ -++ if (msg_type == NFT_MSG_NEWFLOWTABLE) -++ nft_activate_next(ctx->net, flowtable); -++ -++ nft_trans_flowtable(trans) = flowtable; -++ list_add_tail(&trans->list, &ctx->net->nft.commit_list); -++ -++ return 0; -++} -++ -++static int nft_delflowtable(struct nft_ctx *ctx, -++ struct nft_flowtable *flowtable) -++{ -++ int err; -++ -++ err = nft_trans_flowtable_add(ctx, NFT_MSG_DELFLOWTABLE, flowtable); -++ if (err < 0) -++ return err; -++ -++ nft_deactivate_next(ctx->net, flowtable); -++ ctx->table->use--; -++ -++ return err; -++} -++ -+ /* -+ * Tables -+ */ -+@@ -772,6 +808,7 @@ static int nf_tables_newtable(struct net -+ INIT_LIST_HEAD(&table->chains); -+ INIT_LIST_HEAD(&table->sets); -+ INIT_LIST_HEAD(&table->objects); -++ INIT_LIST_HEAD(&table->flowtables); -+ table->flags = flags; -+ -+ nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla); -+@@ -793,10 +830,11 @@ err1: -+ -+ static int nft_flush_table(struct nft_ctx *ctx) -+ { -+- int err; -++ struct nft_flowtable *flowtable, *nft; -+ struct nft_chain *chain, *nc; -+ struct nft_object *obj, *ne; -+ struct nft_set *set, *ns; -++ int err; -+ -+ list_for_each_entry(chain, &ctx->table->chains, list) { -+ if (!nft_is_active_next(ctx->net, chain)) -+@@ -822,6 +860,12 @@ static int nft_flush_table(struct nft_ct -+ goto out; -+ } -+ -++ list_for_each_entry_safe(flowtable, nft, &ctx->table->flowtables, list) { -++ err = nft_delflowtable(ctx, flowtable); -++ if (err < 0) -++ goto out; -++ } -++ -+ list_for_each_entry_safe(obj, ne, &ctx->table->objects, list) { -+ err = nft_delobj(ctx, obj); -+ if (err < 0) -+@@ -4862,6 +4906,605 @@ static void nf_tables_obj_notify(const s -+ ctx->afi->family, ctx->report, GFP_KERNEL); -+ } -+ -++/* -++ * Flow tables -++ */ -++void nft_register_flowtable_type(struct nf_flowtable_type *type) -++{ -++ nfnl_lock(NFNL_SUBSYS_NFTABLES); -++ list_add_tail_rcu(&type->list, &nf_tables_flowtables); -++ nfnl_unlock(NFNL_SUBSYS_NFTABLES); -++} -++EXPORT_SYMBOL_GPL(nft_register_flowtable_type); -++ -++void nft_unregister_flowtable_type(struct nf_flowtable_type *type) -++{ -++ nfnl_lock(NFNL_SUBSYS_NFTABLES); -++ list_del_rcu(&type->list); -++ nfnl_unlock(NFNL_SUBSYS_NFTABLES); -++} -++EXPORT_SYMBOL_GPL(nft_unregister_flowtable_type); -++ -++static const struct nla_policy nft_flowtable_policy[NFTA_FLOWTABLE_MAX + 1] = { -++ [NFTA_FLOWTABLE_TABLE] = { .type = NLA_STRING, -++ .len = NFT_NAME_MAXLEN - 1 }, -++ [NFTA_FLOWTABLE_NAME] = { .type = NLA_STRING, -++ .len = NFT_NAME_MAXLEN - 1 }, -++ [NFTA_FLOWTABLE_HOOK] = { .type = NLA_NESTED }, -++}; -++ -++struct nft_flowtable *nf_tables_flowtable_lookup(const struct nft_table *table, -++ const struct nlattr *nla, -++ u8 genmask) -++{ -++ struct nft_flowtable *flowtable; -++ -++ list_for_each_entry(flowtable, &table->flowtables, list) { -++ if (!nla_strcmp(nla, flowtable->name) && -++ nft_active_genmask(flowtable, genmask)) -++ return flowtable; -++ } -++ return ERR_PTR(-ENOENT); -++} -++EXPORT_SYMBOL_GPL(nf_tables_flowtable_lookup); -++ -++#define NFT_FLOWTABLE_DEVICE_MAX 8 -++ -++static int nf_tables_parse_devices(const struct nft_ctx *ctx, -++ const struct nlattr *attr, -++ struct net_device *dev_array[], int *len) -++{ -++ const struct nlattr *tmp; -++ struct net_device *dev; -++ char ifname[IFNAMSIZ]; -++ int rem, n = 0, err; -++ -++ nla_for_each_nested(tmp, attr, rem) { -++ if (nla_type(tmp) != NFTA_DEVICE_NAME) { -++ err = -EINVAL; -++ goto err1; -++ } -++ -++ nla_strlcpy(ifname, tmp, IFNAMSIZ); -++ dev = dev_get_by_name(ctx->net, ifname); -++ if (!dev) { -++ err = -ENOENT; -++ goto err1; -++ } -++ -++ dev_array[n++] = dev; -++ if (n == NFT_FLOWTABLE_DEVICE_MAX) { -++ err = -EFBIG; -++ goto err1; -++ } -++ } -++ if (!len) -++ return -EINVAL; -++ -++ err = 0; -++err1: -++ *len = n; -++ return err; -++} -++ -++static const struct nla_policy nft_flowtable_hook_policy[NFTA_FLOWTABLE_HOOK_MAX + 1] = { -++ [NFTA_FLOWTABLE_HOOK_NUM] = { .type = NLA_U32 }, -++ [NFTA_FLOWTABLE_HOOK_PRIORITY] = { .type = NLA_U32 }, -++ [NFTA_FLOWTABLE_HOOK_DEVS] = { .type = NLA_NESTED }, -++}; -++ -++static int nf_tables_flowtable_parse_hook(const struct nft_ctx *ctx, -++ const struct nlattr *attr, -++ struct nft_flowtable *flowtable) -++{ -++ struct net_device *dev_array[NFT_FLOWTABLE_DEVICE_MAX]; -++ struct nlattr *tb[NFTA_FLOWTABLE_HOOK_MAX + 1]; -++ struct nf_hook_ops *ops; -++ int hooknum, priority; -++ int err, n = 0, i; -++ -++ err = nla_parse_nested(tb, NFTA_FLOWTABLE_HOOK_MAX, attr, -++ nft_flowtable_hook_policy, NULL); -++ if (err < 0) -++ return err; -++ -++ if (!tb[NFTA_FLOWTABLE_HOOK_NUM] || -++ !tb[NFTA_FLOWTABLE_HOOK_PRIORITY] || -++ !tb[NFTA_FLOWTABLE_HOOK_DEVS]) -++ return -EINVAL; -++ -++ hooknum = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_NUM])); -++ if (hooknum >= ctx->afi->nhooks) -++ return -EINVAL; -++ -++ priority = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_PRIORITY])); -++ -++ err = nf_tables_parse_devices(ctx, tb[NFTA_FLOWTABLE_HOOK_DEVS], -++ dev_array, &n); -++ if (err < 0) -++ goto err1; -++ -++ ops = kzalloc(sizeof(struct nf_hook_ops) * n, GFP_KERNEL); -++ if (!ops) { -++ err = -ENOMEM; -++ goto err1; -++ } -++ -++ flowtable->ops = ops; -++ flowtable->ops_len = n; -++ -++ for (i = 0; i < n; i++) { -++ flowtable->ops[i].pf = NFPROTO_NETDEV; -++ flowtable->ops[i].hooknum = hooknum; -++ flowtable->ops[i].priority = priority; -++ flowtable->ops[i].priv = &flowtable->data.rhashtable; -++ flowtable->ops[i].hook = flowtable->data.type->hook; -++ flowtable->ops[i].dev = dev_array[i]; -++ } -++ -++ err = 0; -++err1: -++ for (i = 0; i < n; i++) -++ dev_put(dev_array[i]); -++ -++ return err; -++} -++ -++static const struct nf_flowtable_type * -++__nft_flowtable_type_get(const struct nft_af_info *afi) -++{ -++ const struct nf_flowtable_type *type; -++ -++ list_for_each_entry(type, &nf_tables_flowtables, list) { -++ if (afi->family == type->family) -++ return type; -++ } -++ return NULL; -++} -++ -++static const struct nf_flowtable_type * -++nft_flowtable_type_get(const struct nft_af_info *afi) -++{ -++ const struct nf_flowtable_type *type; -++ -++ type = __nft_flowtable_type_get(afi); -++ if (type != NULL && try_module_get(type->owner)) -++ return type; -++ -++#ifdef CONFIG_MODULES -++ if (type == NULL) { -++ nfnl_unlock(NFNL_SUBSYS_NFTABLES); -++ request_module("nf-flowtable-%u", afi->family); -++ nfnl_lock(NFNL_SUBSYS_NFTABLES); -++ if (__nft_flowtable_type_get(afi)) -++ return ERR_PTR(-EAGAIN); -++ } -++#endif -++ return ERR_PTR(-ENOENT); -++} -++ -++void nft_flow_table_iterate(struct net *net, -++ void (*iter)(struct nf_flowtable *flowtable, void *data), -++ void *data) -++{ -++ struct nft_flowtable *flowtable; -++ const struct nft_af_info *afi; -++ const struct nft_table *table; -++ -++ rcu_read_lock(); -++ list_for_each_entry_rcu(afi, &net->nft.af_info, list) { -++ list_for_each_entry_rcu(table, &afi->tables, list) { -++ list_for_each_entry_rcu(flowtable, &table->flowtables, list) { -++ iter(&flowtable->data, data); -++ } -++ } -++ } -++ rcu_read_unlock(); -++} -++EXPORT_SYMBOL_GPL(nft_flow_table_iterate); -++ -++static void nft_unregister_flowtable_net_hooks(struct net *net, -++ struct nft_flowtable *flowtable) -++{ -++ int i; -++ -++ for (i = 0; i < flowtable->ops_len; i++) { -++ if (!flowtable->ops[i].dev) -++ continue; -++ -++ nf_unregister_net_hook(net, &flowtable->ops[i]); -++ } -++} -++ -++static int nf_tables_newflowtable(struct net *net, struct sock *nlsk, -++ struct sk_buff *skb, -++ const struct nlmsghdr *nlh, -++ const struct nlattr * const nla[], -++ struct netlink_ext_ack *extack) -++{ -++ const struct nfgenmsg *nfmsg = nlmsg_data(nlh); -++ const struct nf_flowtable_type *type; -++ u8 genmask = nft_genmask_next(net); -++ int family = nfmsg->nfgen_family; -++ struct nft_flowtable *flowtable; -++ struct nft_af_info *afi; -++ struct nft_table *table; -++ struct nft_ctx ctx; -++ int err, i, k; -++ -++ if (!nla[NFTA_FLOWTABLE_TABLE] || -++ !nla[NFTA_FLOWTABLE_NAME] || -++ !nla[NFTA_FLOWTABLE_HOOK]) -++ return -EINVAL; -++ -++ afi = nf_tables_afinfo_lookup(net, family, true); -++ if (IS_ERR(afi)) -++ return PTR_ERR(afi); -++ -++ table = nf_tables_table_lookup(afi, nla[NFTA_FLOWTABLE_TABLE], genmask); -++ if (IS_ERR(table)) -++ return PTR_ERR(table); -++ -++ flowtable = nf_tables_flowtable_lookup(table, nla[NFTA_FLOWTABLE_NAME], -++ genmask); -++ if (IS_ERR(flowtable)) { -++ err = PTR_ERR(flowtable); -++ if (err != -ENOENT) -++ return err; -++ } else { -++ if (nlh->nlmsg_flags & NLM_F_EXCL) -++ return -EEXIST; -++ -++ return 0; -++ } -++ -++ nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla); -++ -++ flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL); -++ if (!flowtable) -++ return -ENOMEM; -++ -++ flowtable->table = table; -++ flowtable->name = nla_strdup(nla[NFTA_FLOWTABLE_NAME], GFP_KERNEL); -++ if (!flowtable->name) { -++ err = -ENOMEM; -++ goto err1; -++ } -++ -++ type = nft_flowtable_type_get(afi); -++ if (IS_ERR(type)) { -++ err = PTR_ERR(type); -++ goto err2; -++ } -++ -++ flowtable->data.type = type; -++ err = rhashtable_init(&flowtable->data.rhashtable, type->params); -++ if (err < 0) -++ goto err3; -++ -++ err = nf_tables_flowtable_parse_hook(&ctx, nla[NFTA_FLOWTABLE_HOOK], -++ flowtable); -++ if (err < 0) -++ goto err3; -++ -++ for (i = 0; i < flowtable->ops_len; i++) { -++ err = nf_register_net_hook(net, &flowtable->ops[i]); -++ if (err < 0) -++ goto err4; -++ } -++ -++ err = nft_trans_flowtable_add(&ctx, NFT_MSG_NEWFLOWTABLE, flowtable); -++ if (err < 0) -++ goto err5; -++ -++ INIT_DEFERRABLE_WORK(&flowtable->data.gc_work, type->gc); -++ queue_delayed_work(system_power_efficient_wq, -++ &flowtable->data.gc_work, HZ); -++ -++ list_add_tail_rcu(&flowtable->list, &table->flowtables); -++ table->use++; -++ -++ return 0; -++err5: -++ i = flowtable->ops_len; -++err4: -++ for (k = i - 1; k >= 0; k--) -++ nf_unregister_net_hook(net, &flowtable->ops[i]); -++ -++ kfree(flowtable->ops); -++err3: -++ module_put(type->owner); -++err2: -++ kfree(flowtable->name); -++err1: -++ kfree(flowtable); -++ return err; -++} -++ -++static int nf_tables_delflowtable(struct net *net, struct sock *nlsk, -++ struct sk_buff *skb, -++ const struct nlmsghdr *nlh, -++ const struct nlattr * const nla[], -++ struct netlink_ext_ack *extack) -++{ -++ const struct nfgenmsg *nfmsg = nlmsg_data(nlh); -++ u8 genmask = nft_genmask_next(net); -++ int family = nfmsg->nfgen_family; -++ struct nft_flowtable *flowtable; -++ struct nft_af_info *afi; -++ struct nft_table *table; -++ struct nft_ctx ctx; -++ -++ afi = nf_tables_afinfo_lookup(net, family, true); -++ if (IS_ERR(afi)) -++ return PTR_ERR(afi); -++ -++ table = nf_tables_table_lookup(afi, nla[NFTA_FLOWTABLE_TABLE], genmask); -++ if (IS_ERR(table)) -++ return PTR_ERR(table); -++ -++ flowtable = nf_tables_flowtable_lookup(table, nla[NFTA_FLOWTABLE_NAME], -++ genmask); -++ if (IS_ERR(flowtable)) -++ return PTR_ERR(flowtable); -++ if (flowtable->use > 0) -++ return -EBUSY; -++ -++ nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla); -++ -++ return nft_delflowtable(&ctx, flowtable); -++} -++ -++static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net, -++ u32 portid, u32 seq, int event, -++ u32 flags, int family, -++ struct nft_flowtable *flowtable) -++{ -++ struct nlattr *nest, *nest_devs; -++ struct nfgenmsg *nfmsg; -++ struct nlmsghdr *nlh; -++ int i; -++ -++ event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event); -++ nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags); -++ if (nlh == NULL) -++ goto nla_put_failure; -++ -++ nfmsg = nlmsg_data(nlh); -++ nfmsg->nfgen_family = family; -++ nfmsg->version = NFNETLINK_V0; -++ nfmsg->res_id = htons(net->nft.base_seq & 0xffff); -++ -++ if (nla_put_string(skb, NFTA_FLOWTABLE_TABLE, flowtable->table->name) || -++ nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) || -++ nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use))) -++ goto nla_put_failure; -++ -++ nest = nla_nest_start(skb, NFTA_FLOWTABLE_HOOK); -++ if (nla_put_be32(skb, NFTA_FLOWTABLE_HOOK_NUM, htonl(flowtable->hooknum)) || -++ nla_put_be32(skb, NFTA_FLOWTABLE_HOOK_PRIORITY, htonl(flowtable->priority))) -++ goto nla_put_failure; -++ -++ nest_devs = nla_nest_start(skb, NFTA_FLOWTABLE_HOOK_DEVS); -++ if (!nest_devs) -++ goto nla_put_failure; -++ -++ for (i = 0; i < flowtable->ops_len; i++) { -++ if (flowtable->ops[i].dev && -++ nla_put_string(skb, NFTA_DEVICE_NAME, -++ flowtable->ops[i].dev->name)) -++ goto nla_put_failure; -++ } -++ nla_nest_end(skb, nest_devs); -++ nla_nest_end(skb, nest); -++ -++ nlmsg_end(skb, nlh); -++ return 0; -++ -++nla_put_failure: -++ nlmsg_trim(skb, nlh); -++ return -1; -++} -++ -++struct nft_flowtable_filter { -++ char *table; -++}; -++ -++static int nf_tables_dump_flowtable(struct sk_buff *skb, -++ struct netlink_callback *cb) -++{ -++ const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh); -++ struct nft_flowtable_filter *filter = cb->data; -++ unsigned int idx = 0, s_idx = cb->args[0]; -++ struct net *net = sock_net(skb->sk); -++ int family = nfmsg->nfgen_family; -++ struct nft_flowtable *flowtable; -++ const struct nft_af_info *afi; -++ const struct nft_table *table; -++ -++ rcu_read_lock(); -++ cb->seq = net->nft.base_seq; -++ -++ list_for_each_entry_rcu(afi, &net->nft.af_info, list) { -++ if (family != NFPROTO_UNSPEC && family != afi->family) -++ continue; -++ -++ list_for_each_entry_rcu(table, &afi->tables, list) { -++ list_for_each_entry_rcu(flowtable, &table->flowtables, list) { -++ if (!nft_is_active(net, flowtable)) -++ goto cont; -++ if (idx < s_idx) -++ goto cont; -++ if (idx > s_idx) -++ memset(&cb->args[1], 0, -++ sizeof(cb->args) - sizeof(cb->args[0])); -++ if (filter && filter->table[0] && -++ strcmp(filter->table, table->name)) -++ goto cont; -++ -++ if (nf_tables_fill_flowtable_info(skb, net, NETLINK_CB(cb->skb).portid, -++ cb->nlh->nlmsg_seq, -++ NFT_MSG_NEWFLOWTABLE, -++ NLM_F_MULTI | NLM_F_APPEND, -++ afi->family, flowtable) < 0) -++ goto done; -++ -++ nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -++cont: -++ idx++; -++ } -++ } -++ } -++done: -++ rcu_read_unlock(); -++ -++ cb->args[0] = idx; -++ return skb->len; -++} -++ -++static int nf_tables_dump_flowtable_done(struct netlink_callback *cb) -++{ -++ struct nft_flowtable_filter *filter = cb->data; -++ -++ if (!filter) -++ return 0; -++ -++ kfree(filter->table); -++ kfree(filter); -++ -++ return 0; -++} -++ -++static struct nft_flowtable_filter * -++nft_flowtable_filter_alloc(const struct nlattr * const nla[]) -++{ -++ struct nft_flowtable_filter *filter; -++ -++ filter = kzalloc(sizeof(*filter), GFP_KERNEL); -++ if (!filter) -++ return ERR_PTR(-ENOMEM); -++ -++ if (nla[NFTA_FLOWTABLE_TABLE]) { -++ filter->table = nla_strdup(nla[NFTA_FLOWTABLE_TABLE], -++ GFP_KERNEL); -++ if (!filter->table) { -++ kfree(filter); -++ return ERR_PTR(-ENOMEM); -++ } -++ } -++ return filter; -++} -++ -++static int nf_tables_getflowtable(struct net *net, struct sock *nlsk, -++ struct sk_buff *skb, -++ const struct nlmsghdr *nlh, -++ const struct nlattr * const nla[], -++ struct netlink_ext_ack *extack) -++{ -++ const struct nfgenmsg *nfmsg = nlmsg_data(nlh); -++ u8 genmask = nft_genmask_cur(net); -++ int family = nfmsg->nfgen_family; -++ struct nft_flowtable *flowtable; -++ const struct nft_af_info *afi; -++ const struct nft_table *table; -++ struct sk_buff *skb2; -++ int err; -++ -++ if (nlh->nlmsg_flags & NLM_F_DUMP) { -++ struct netlink_dump_control c = { -++ .dump = nf_tables_dump_flowtable, -++ .done = nf_tables_dump_flowtable_done, -++ }; -++ -++ if (nla[NFTA_FLOWTABLE_TABLE]) { -++ struct nft_flowtable_filter *filter; -++ -++ filter = nft_flowtable_filter_alloc(nla); -++ if (IS_ERR(filter)) -++ return -ENOMEM; -++ -++ c.data = filter; -++ } -++ return netlink_dump_start(nlsk, skb, nlh, &c); -++ } -++ -++ if (!nla[NFTA_FLOWTABLE_NAME]) -++ return -EINVAL; -++ -++ afi = nf_tables_afinfo_lookup(net, family, false); -++ if (IS_ERR(afi)) -++ return PTR_ERR(afi); -++ -++ table = nf_tables_table_lookup(afi, nla[NFTA_FLOWTABLE_TABLE], genmask); -++ if (IS_ERR(table)) -++ return PTR_ERR(table); -++ -++ flowtable = nf_tables_flowtable_lookup(table, nla[NFTA_FLOWTABLE_NAME], -++ genmask); -++ if (IS_ERR(table)) -++ return PTR_ERR(flowtable); -++ -++ skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); -++ if (!skb2) -++ return -ENOMEM; -++ -++ err = nf_tables_fill_flowtable_info(skb2, net, NETLINK_CB(skb).portid, -++ nlh->nlmsg_seq, -++ NFT_MSG_NEWFLOWTABLE, 0, family, -++ flowtable); -++ if (err < 0) -++ goto err; -++ -++ return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid); -++err: -++ kfree_skb(skb2); -++ return err; -++} -++ -++static void nf_tables_flowtable_notify(struct nft_ctx *ctx, -++ struct nft_flowtable *flowtable, -++ int event) -++{ -++ struct sk_buff *skb; -++ int err; -++ -++ if (ctx->report && -++ !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES)) -++ return; -++ -++ skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); -++ if (skb == NULL) -++ goto err; -++ -++ err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid, -++ ctx->seq, event, 0, -++ ctx->afi->family, flowtable); -++ if (err < 0) { -++ kfree_skb(skb); -++ goto err; -++ } -++ -++ nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES, -++ ctx->report, GFP_KERNEL); -++ return; -++err: -++ nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS); -++} -++ -++static void nft_flowtable_destroy(void *ptr, void *arg) -++{ -++ kfree(ptr); -++} -++ -++static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable) -++{ -++ cancel_delayed_work_sync(&flowtable->data.gc_work); -++ kfree(flowtable->name); -++ rhashtable_free_and_destroy(&flowtable->data.rhashtable, -++ nft_flowtable_destroy, NULL); -++ module_put(flowtable->data.type->owner); -++} -++ -+ static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net, -+ u32 portid, u32 seq) -+ { -+@@ -4892,6 +5535,49 @@ nla_put_failure: -+ return -EMSGSIZE; -+ } -+ -++static void nft_flowtable_event(unsigned long event, struct net_device *dev, -++ struct nft_flowtable *flowtable) -++{ -++ int i; -++ -++ for (i = 0; i < flowtable->ops_len; i++) { -++ if (flowtable->ops[i].dev != dev) -++ continue; -++ -++ nf_unregister_net_hook(dev_net(dev), &flowtable->ops[i]); -++ flowtable->ops[i].dev = NULL; -++ break; -++ } -++} -++ -++static int nf_tables_flowtable_event(struct notifier_block *this, -++ unsigned long event, void *ptr) -++{ -++ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -++ struct nft_flowtable *flowtable; -++ struct nft_table *table; -++ struct nft_af_info *afi; -++ -++ if (event != NETDEV_UNREGISTER) -++ return 0; -++ -++ nfnl_lock(NFNL_SUBSYS_NFTABLES); -++ list_for_each_entry(afi, &dev_net(dev)->nft.af_info, list) { -++ list_for_each_entry(table, &afi->tables, list) { -++ list_for_each_entry(flowtable, &table->flowtables, list) { -++ nft_flowtable_event(event, dev, flowtable); -++ } -++ } -++ } -++ nfnl_unlock(NFNL_SUBSYS_NFTABLES); -++ -++ return NOTIFY_DONE; -++} -++ -++static struct notifier_block nf_tables_flowtable_notifier = { -++ .notifier_call = nf_tables_flowtable_event, -++}; -++ -+ static void nf_tables_gen_notify(struct net *net, struct sk_buff *skb, -+ int event) -+ { -+@@ -5044,6 +5730,21 @@ static const struct nfnl_callback nf_tab -+ .attr_count = NFTA_OBJ_MAX, -+ .policy = nft_obj_policy, -+ }, -++ [NFT_MSG_NEWFLOWTABLE] = { -++ .call_batch = nf_tables_newflowtable, -++ .attr_count = NFTA_FLOWTABLE_MAX, -++ .policy = nft_flowtable_policy, -++ }, -++ [NFT_MSG_GETFLOWTABLE] = { -++ .call = nf_tables_getflowtable, -++ .attr_count = NFTA_FLOWTABLE_MAX, -++ .policy = nft_flowtable_policy, -++ }, -++ [NFT_MSG_DELFLOWTABLE] = { -++ .call_batch = nf_tables_delflowtable, -++ .attr_count = NFTA_FLOWTABLE_MAX, -++ .policy = nft_flowtable_policy, -++ }, -+ }; -+ -+ static void nft_chain_commit_update(struct nft_trans *trans) -+@@ -5092,6 +5793,9 @@ static void nf_tables_commit_release(str -+ case NFT_MSG_DELOBJ: -+ nft_obj_destroy(nft_trans_obj(trans)); -+ break; -++ case NFT_MSG_DELFLOWTABLE: -++ nf_tables_flowtable_destroy(nft_trans_flowtable(trans)); -++ break; -+ } -+ kfree(trans); -+ } -+@@ -5211,6 +5915,21 @@ static int nf_tables_commit(struct net * -+ nf_tables_obj_notify(&trans->ctx, nft_trans_obj(trans), -+ NFT_MSG_DELOBJ); -+ break; -++ case NFT_MSG_NEWFLOWTABLE: -++ nft_clear(net, nft_trans_flowtable(trans)); -++ nf_tables_flowtable_notify(&trans->ctx, -++ nft_trans_flowtable(trans), -++ NFT_MSG_NEWFLOWTABLE); -++ nft_trans_destroy(trans); -++ break; -++ case NFT_MSG_DELFLOWTABLE: -++ list_del_rcu(&nft_trans_flowtable(trans)->list); -++ nf_tables_flowtable_notify(&trans->ctx, -++ nft_trans_flowtable(trans), -++ NFT_MSG_DELFLOWTABLE); -++ nft_unregister_flowtable_net_hooks(net, -++ nft_trans_flowtable(trans)); -++ break; -+ } -+ } -+ -+@@ -5248,6 +5967,9 @@ static void nf_tables_abort_release(stru -+ case NFT_MSG_NEWOBJ: -+ nft_obj_destroy(nft_trans_obj(trans)); -+ break; -++ case NFT_MSG_NEWFLOWTABLE: -++ nf_tables_flowtable_destroy(nft_trans_flowtable(trans)); -++ break; -+ } -+ kfree(trans); -+ } -+@@ -5339,6 +6061,17 @@ static int nf_tables_abort(struct net *n -+ nft_clear(trans->ctx.net, nft_trans_obj(trans)); -+ nft_trans_destroy(trans); -+ break; -++ case NFT_MSG_NEWFLOWTABLE: -++ trans->ctx.table->use--; -++ list_del_rcu(&nft_trans_flowtable(trans)->list); -++ nft_unregister_flowtable_net_hooks(net, -++ nft_trans_flowtable(trans)); -++ break; -++ case NFT_MSG_DELFLOWTABLE: -++ trans->ctx.table->use++; -++ nft_clear(trans->ctx.net, nft_trans_flowtable(trans)); -++ nft_trans_destroy(trans); -++ break; -+ } -+ } -+ -+@@ -5889,6 +6622,7 @@ EXPORT_SYMBOL_GPL(__nft_release_basechai -+ /* Called by nft_unregister_afinfo() from __net_exit path, nfnl_lock is held. */ -+ static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi) -+ { -++ struct nft_flowtable *flowtable, *nf; -+ struct nft_table *table, *nt; -+ struct nft_chain *chain, *nc; -+ struct nft_object *obj, *ne; -+@@ -5902,6 +6636,9 @@ static void __nft_release_afinfo(struct -+ list_for_each_entry_safe(table, nt, &afi->tables, list) { -+ list_for_each_entry(chain, &table->chains, list) -+ nf_tables_unregister_hook(net, table, chain); -++ list_for_each_entry(flowtable, &table->flowtables, list) -++ nf_unregister_net_hooks(net, flowtable->ops, -++ flowtable->ops_len); -+ /* No packets are walking on these chains anymore. */ -+ ctx.table = table; -+ list_for_each_entry(chain, &table->chains, list) { -+@@ -5912,6 +6649,11 @@ static void __nft_release_afinfo(struct -+ nf_tables_rule_release(&ctx, rule); -+ } -+ } -++ list_for_each_entry_safe(flowtable, nf, &table->flowtables, list) { -++ list_del(&flowtable->list); -++ table->use--; -++ nf_tables_flowtable_destroy(flowtable); -++ } -+ list_for_each_entry_safe(set, ns, &table->sets, list) { -+ list_del(&set->list); -+ table->use--; -+@@ -5955,6 +6697,8 @@ static int __init nf_tables_module_init( -+ if (err < 0) -+ goto err3; -+ -++ register_netdevice_notifier(&nf_tables_flowtable_notifier); -++ -+ pr_info("nf_tables: (c) 2007-2009 Patrick McHardy \n"); -+ return register_pernet_subsys(&nf_tables_net_ops); -+ err3: -+@@ -5969,6 +6713,7 @@ static void __exit nf_tables_module_exit -+ { -+ unregister_pernet_subsys(&nf_tables_net_ops); -+ nfnetlink_subsys_unregister(&nf_tables_subsys); -++ unregister_netdevice_notifier(&nf_tables_flowtable_notifier); -+ rcu_barrier(); -+ nf_tables_core_module_exit(); -+ kfree(info); -diff --git a/target/linux/generic/backport-4.14/322-v4.16-netfilter-add-generic-flow-table-infrastructure.patch b/target/linux/generic/backport-4.14/322-v4.16-netfilter-add-generic-flow-table-infrastructure.patch -new file mode 100644 -index 0000000000..16de9571a8 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/322-v4.16-netfilter-add-generic-flow-table-infrastructure.patch -@@ -0,0 +1,586 @@ -+From: Pablo Neira Ayuso -+Date: Sun, 7 Jan 2018 01:04:11 +0100 -+Subject: [PATCH] netfilter: add generic flow table infrastructure -+ -+This patch defines the API to interact with flow tables, this allows to -+add, delete and lookup for entries in the flow table. This also adds the -+generic garbage code that removes entries that have expired, ie. no -+traffic has been seen for a while. -+ -+Users of the flow table infrastructure can delete entries via -+flow_offload_dead(), which sets the dying bit, this signals the garbage -+collector to release an entry from user context. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ create mode 100644 net/netfilter/nf_flow_table.c -+ -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -1,7 +1,12 @@ -+ #ifndef _NF_FLOW_TABLE_H -+ #define _NF_FLOW_TABLE_H -+ -++#include -++#include -++#include -+ #include -++#include -++#include -+ -+ struct nf_flowtable; -+ -+@@ -20,4 +25,93 @@ struct nf_flowtable { -+ struct delayed_work gc_work; -+ }; -+ -++enum flow_offload_tuple_dir { -++ FLOW_OFFLOAD_DIR_ORIGINAL, -++ FLOW_OFFLOAD_DIR_REPLY, -++ __FLOW_OFFLOAD_DIR_MAX = FLOW_OFFLOAD_DIR_REPLY, -++}; -++#define FLOW_OFFLOAD_DIR_MAX (__FLOW_OFFLOAD_DIR_MAX + 1) -++ -++struct flow_offload_tuple { -++ union { -++ struct in_addr src_v4; -++ struct in6_addr src_v6; -++ }; -++ union { -++ struct in_addr dst_v4; -++ struct in6_addr dst_v6; -++ }; -++ struct { -++ __be16 src_port; -++ __be16 dst_port; -++ }; -++ -++ int iifidx; -++ -++ u8 l3proto; -++ u8 l4proto; -++ u8 dir; -++ -++ int oifidx; -++ -++ struct dst_entry *dst_cache; -++}; -++ -++struct flow_offload_tuple_rhash { -++ struct rhash_head node; -++ struct flow_offload_tuple tuple; -++}; -++ -++#define FLOW_OFFLOAD_SNAT 0x1 -++#define FLOW_OFFLOAD_DNAT 0x2 -++#define FLOW_OFFLOAD_DYING 0x4 -++ -++struct flow_offload { -++ struct flow_offload_tuple_rhash tuplehash[FLOW_OFFLOAD_DIR_MAX]; -++ u32 flags; -++ union { -++ /* Your private driver data here. */ -++ u32 timeout; -++ }; -++}; -++ -++#define NF_FLOW_TIMEOUT (30 * HZ) -++ -++struct nf_flow_route { -++ struct { -++ struct dst_entry *dst; -++ int ifindex; -++ } tuple[FLOW_OFFLOAD_DIR_MAX]; -++}; -++ -++struct flow_offload *flow_offload_alloc(struct nf_conn *ct, -++ struct nf_flow_route *route); -++void flow_offload_free(struct flow_offload *flow); -++ -++int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow); -++void flow_offload_del(struct nf_flowtable *flow_table, struct flow_offload *flow); -++struct flow_offload_tuple_rhash *flow_offload_lookup(struct nf_flowtable *flow_table, -++ struct flow_offload_tuple *tuple); -++int nf_flow_table_iterate(struct nf_flowtable *flow_table, -++ void (*iter)(struct flow_offload *flow, void *data), -++ void *data); -++void nf_flow_offload_work_gc(struct work_struct *work); -++extern const struct rhashtable_params nf_flow_offload_rhash_params; -++ -++void flow_offload_dead(struct flow_offload *flow); -++ -++int nf_flow_snat_port(const struct flow_offload *flow, -++ struct sk_buff *skb, unsigned int thoff, -++ u8 protocol, enum flow_offload_tuple_dir dir); -++int nf_flow_dnat_port(const struct flow_offload *flow, -++ struct sk_buff *skb, unsigned int thoff, -++ u8 protocol, enum flow_offload_tuple_dir dir); -++ -++struct flow_ports { -++ __be16 source, dest; -++}; -++ -++#define MODULE_ALIAS_NF_FLOWTABLE(family) \ -++ MODULE_ALIAS("nf-flowtable-" __stringify(family)) -++ -+ #endif /* _FLOW_OFFLOAD_H */ -+--- a/net/netfilter/Kconfig -++++ b/net/netfilter/Kconfig -+@@ -667,6 +667,13 @@ endif # NF_TABLES_NETDEV -+ -+ endif # NF_TABLES -+ -++config NF_FLOW_TABLE -++ tristate "Netfilter flow table module" -++ help -++ This option adds the flow table core infrastructure. -++ -++ To compile it as a module, choose M here. -++ -+ config NETFILTER_XTABLES -+ tristate "Netfilter Xtables support (required for ip_tables)" -+ default m if NETFILTER_ADVANCED=n -+--- a/net/netfilter/Makefile -++++ b/net/netfilter/Makefile -+@@ -110,6 +110,9 @@ obj-$(CONFIG_NFT_FIB_NETDEV) += nft_fib_ -+ obj-$(CONFIG_NFT_DUP_NETDEV) += nft_dup_netdev.o -+ obj-$(CONFIG_NFT_FWD_NETDEV) += nft_fwd_netdev.o -+ -++# flow table infrastructure -++obj-$(CONFIG_NF_FLOW_TABLE) += nf_flow_table.o -++ -+ # generic X tables -+ obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o -+ -+--- /dev/null -++++ b/net/netfilter/nf_flow_table.c -+@@ -0,0 +1,429 @@ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++struct flow_offload_entry { -++ struct flow_offload flow; -++ struct nf_conn *ct; -++ struct rcu_head rcu_head; -++}; -++ -++struct flow_offload * -++flow_offload_alloc(struct nf_conn *ct, struct nf_flow_route *route) -++{ -++ struct flow_offload_entry *entry; -++ struct flow_offload *flow; -++ -++ if (unlikely(nf_ct_is_dying(ct) || -++ !atomic_inc_not_zero(&ct->ct_general.use))) -++ return NULL; -++ -++ entry = kzalloc(sizeof(*entry), GFP_ATOMIC); -++ if (!entry) -++ goto err_ct_refcnt; -++ -++ flow = &entry->flow; -++ -++ if (!dst_hold_safe(route->tuple[FLOW_OFFLOAD_DIR_ORIGINAL].dst)) -++ goto err_dst_cache_original; -++ -++ if (!dst_hold_safe(route->tuple[FLOW_OFFLOAD_DIR_REPLY].dst)) -++ goto err_dst_cache_reply; -++ -++ entry->ct = ct; -++ -++ switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num) { -++ case NFPROTO_IPV4: -++ flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_v4 = -++ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.in; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_v4 = -++ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.in; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_v4 = -++ ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.in; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_v4 = -++ ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.in; -++ break; -++ case NFPROTO_IPV6: -++ flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_v6 = -++ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.in6; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_v6 = -++ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.in6; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_v6 = -++ ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.in6; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_v6 = -++ ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.in6; -++ break; -++ } -++ -++ flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.l3proto = -++ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.l4proto = -++ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.l3proto = -++ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.l4proto = -++ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; -++ -++ flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_cache = -++ route->tuple[FLOW_OFFLOAD_DIR_ORIGINAL].dst; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_cache = -++ route->tuple[FLOW_OFFLOAD_DIR_REPLY].dst; -++ -++ flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_port = -++ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.tcp.port; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_port = -++ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.tcp.port; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_port = -++ ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.tcp.port; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_port = -++ ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.tcp.port; -++ -++ flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dir = -++ FLOW_OFFLOAD_DIR_ORIGINAL; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dir = -++ FLOW_OFFLOAD_DIR_REPLY; -++ -++ flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.iifidx = -++ route->tuple[FLOW_OFFLOAD_DIR_ORIGINAL].ifindex; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.oifidx = -++ route->tuple[FLOW_OFFLOAD_DIR_REPLY].ifindex; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.iifidx = -++ route->tuple[FLOW_OFFLOAD_DIR_REPLY].ifindex; -++ flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.oifidx = -++ route->tuple[FLOW_OFFLOAD_DIR_ORIGINAL].ifindex; -++ -++ if (ct->status & IPS_SRC_NAT) -++ flow->flags |= FLOW_OFFLOAD_SNAT; -++ else if (ct->status & IPS_DST_NAT) -++ flow->flags |= FLOW_OFFLOAD_DNAT; -++ -++ return flow; -++ -++err_dst_cache_reply: -++ dst_release(route->tuple[FLOW_OFFLOAD_DIR_ORIGINAL].dst); -++err_dst_cache_original: -++ kfree(entry); -++err_ct_refcnt: -++ nf_ct_put(ct); -++ -++ return NULL; -++} -++EXPORT_SYMBOL_GPL(flow_offload_alloc); -++ -++void flow_offload_free(struct flow_offload *flow) -++{ -++ struct flow_offload_entry *e; -++ -++ dst_release(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_cache); -++ dst_release(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_cache); -++ e = container_of(flow, struct flow_offload_entry, flow); -++ kfree(e); -++} -++EXPORT_SYMBOL_GPL(flow_offload_free); -++ -++void flow_offload_dead(struct flow_offload *flow) -++{ -++ flow->flags |= FLOW_OFFLOAD_DYING; -++} -++EXPORT_SYMBOL_GPL(flow_offload_dead); -++ -++int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow) -++{ -++ flow->timeout = (u32)jiffies; -++ -++ rhashtable_insert_fast(&flow_table->rhashtable, -++ &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node, -++ *flow_table->type->params); -++ rhashtable_insert_fast(&flow_table->rhashtable, -++ &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].node, -++ *flow_table->type->params); -++ return 0; -++} -++EXPORT_SYMBOL_GPL(flow_offload_add); -++ -++void flow_offload_del(struct nf_flowtable *flow_table, -++ struct flow_offload *flow) -++{ -++ struct flow_offload_entry *e; -++ -++ rhashtable_remove_fast(&flow_table->rhashtable, -++ &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node, -++ *flow_table->type->params); -++ rhashtable_remove_fast(&flow_table->rhashtable, -++ &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].node, -++ *flow_table->type->params); -++ -++ e = container_of(flow, struct flow_offload_entry, flow); -++ kfree_rcu(e, rcu_head); -++} -++EXPORT_SYMBOL_GPL(flow_offload_del); -++ -++struct flow_offload_tuple_rhash * -++flow_offload_lookup(struct nf_flowtable *flow_table, -++ struct flow_offload_tuple *tuple) -++{ -++ return rhashtable_lookup_fast(&flow_table->rhashtable, tuple, -++ *flow_table->type->params); -++} -++EXPORT_SYMBOL_GPL(flow_offload_lookup); -++ -++static void nf_flow_release_ct(const struct flow_offload *flow) -++{ -++ struct flow_offload_entry *e; -++ -++ e = container_of(flow, struct flow_offload_entry, flow); -++ nf_ct_delete(e->ct, 0, 0); -++ nf_ct_put(e->ct); -++} -++ -++int nf_flow_table_iterate(struct nf_flowtable *flow_table, -++ void (*iter)(struct flow_offload *flow, void *data), -++ void *data) -++{ -++ struct flow_offload_tuple_rhash *tuplehash; -++ struct rhashtable_iter hti; -++ struct flow_offload *flow; -++ int err; -++ -++ err = rhashtable_walk_init(&flow_table->rhashtable, &hti, GFP_KERNEL); -++ if (err) -++ return err; -++ -++ rhashtable_walk_start(&hti); -++ -++ while ((tuplehash = rhashtable_walk_next(&hti))) { -++ if (IS_ERR(tuplehash)) { -++ err = PTR_ERR(tuplehash); -++ if (err != -EAGAIN) -++ goto out; -++ -++ continue; -++ } -++ if (tuplehash->tuple.dir) -++ continue; -++ -++ flow = container_of(tuplehash, struct flow_offload, tuplehash[0]); -++ -++ iter(flow, data); -++ } -++out: -++ rhashtable_walk_stop(&hti); -++ rhashtable_walk_exit(&hti); -++ -++ return err; -++} -++EXPORT_SYMBOL_GPL(nf_flow_table_iterate); -++ -++static inline bool nf_flow_has_expired(const struct flow_offload *flow) -++{ -++ return (__s32)(flow->timeout - (u32)jiffies) <= 0; -++} -++ -++static inline bool nf_flow_is_dying(const struct flow_offload *flow) -++{ -++ return flow->flags & FLOW_OFFLOAD_DYING; -++} -++ -++void nf_flow_offload_work_gc(struct work_struct *work) -++{ -++ struct flow_offload_tuple_rhash *tuplehash; -++ struct nf_flowtable *flow_table; -++ struct rhashtable_iter hti; -++ struct flow_offload *flow; -++ int err; -++ -++ flow_table = container_of(work, struct nf_flowtable, gc_work.work); -++ -++ err = rhashtable_walk_init(&flow_table->rhashtable, &hti, GFP_KERNEL); -++ if (err) -++ goto schedule; -++ -++ rhashtable_walk_start(&hti); -++ -++ while ((tuplehash = rhashtable_walk_next(&hti))) { -++ if (IS_ERR(tuplehash)) { -++ err = PTR_ERR(tuplehash); -++ if (err != -EAGAIN) -++ goto out; -++ -++ continue; -++ } -++ if (tuplehash->tuple.dir) -++ continue; -++ -++ flow = container_of(tuplehash, struct flow_offload, tuplehash[0]); -++ -++ if (nf_flow_has_expired(flow) || -++ nf_flow_is_dying(flow)) { -++ flow_offload_del(flow_table, flow); -++ nf_flow_release_ct(flow); -++ } -++ } -++out: -++ rhashtable_walk_stop(&hti); -++ rhashtable_walk_exit(&hti); -++schedule: -++ queue_delayed_work(system_power_efficient_wq, &flow_table->gc_work, HZ); -++} -++EXPORT_SYMBOL_GPL(nf_flow_offload_work_gc); -++ -++static u32 flow_offload_hash(const void *data, u32 len, u32 seed) -++{ -++ const struct flow_offload_tuple *tuple = data; -++ -++ return jhash(tuple, offsetof(struct flow_offload_tuple, dir), seed); -++} -++ -++static u32 flow_offload_hash_obj(const void *data, u32 len, u32 seed) -++{ -++ const struct flow_offload_tuple_rhash *tuplehash = data; -++ -++ return jhash(&tuplehash->tuple, offsetof(struct flow_offload_tuple, dir), seed); -++} -++ -++static int flow_offload_hash_cmp(struct rhashtable_compare_arg *arg, -++ const void *ptr) -++{ -++ const struct flow_offload_tuple *tuple = arg->key; -++ const struct flow_offload_tuple_rhash *x = ptr; -++ -++ if (memcmp(&x->tuple, tuple, offsetof(struct flow_offload_tuple, dir))) -++ return 1; -++ -++ return 0; -++} -++ -++const struct rhashtable_params nf_flow_offload_rhash_params = { -++ .head_offset = offsetof(struct flow_offload_tuple_rhash, node), -++ .hashfn = flow_offload_hash, -++ .obj_hashfn = flow_offload_hash_obj, -++ .obj_cmpfn = flow_offload_hash_cmp, -++ .automatic_shrinking = true, -++}; -++EXPORT_SYMBOL_GPL(nf_flow_offload_rhash_params); -++ -++static int nf_flow_nat_port_tcp(struct sk_buff *skb, unsigned int thoff, -++ __be16 port, __be16 new_port) -++{ -++ struct tcphdr *tcph; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*tcph)) || -++ skb_try_make_writable(skb, thoff + sizeof(*tcph))) -++ return -1; -++ -++ tcph = (void *)(skb_network_header(skb) + thoff); -++ inet_proto_csum_replace2(&tcph->check, skb, port, new_port, true); -++ -++ return 0; -++} -++ -++static int nf_flow_nat_port_udp(struct sk_buff *skb, unsigned int thoff, -++ __be16 port, __be16 new_port) -++{ -++ struct udphdr *udph; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*udph)) || -++ skb_try_make_writable(skb, thoff + sizeof(*udph))) -++ return -1; -++ -++ udph = (void *)(skb_network_header(skb) + thoff); -++ if (udph->check || skb->ip_summed == CHECKSUM_PARTIAL) { -++ inet_proto_csum_replace2(&udph->check, skb, port, -++ new_port, true); -++ if (!udph->check) -++ udph->check = CSUM_MANGLED_0; -++ } -++ -++ return 0; -++} -++ -++static int nf_flow_nat_port(struct sk_buff *skb, unsigned int thoff, -++ u8 protocol, __be16 port, __be16 new_port) -++{ -++ switch (protocol) { -++ case IPPROTO_TCP: -++ if (nf_flow_nat_port_tcp(skb, thoff, port, new_port) < 0) -++ return NF_DROP; -++ break; -++ case IPPROTO_UDP: -++ if (nf_flow_nat_port_udp(skb, thoff, port, new_port) < 0) -++ return NF_DROP; -++ break; -++ } -++ -++ return 0; -++} -++ -++int nf_flow_snat_port(const struct flow_offload *flow, -++ struct sk_buff *skb, unsigned int thoff, -++ u8 protocol, enum flow_offload_tuple_dir dir) -++{ -++ struct flow_ports *hdr; -++ __be16 port, new_port; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*hdr)) || -++ skb_try_make_writable(skb, thoff + sizeof(*hdr))) -++ return -1; -++ -++ hdr = (void *)(skb_network_header(skb) + thoff); -++ -++ switch (dir) { -++ case FLOW_OFFLOAD_DIR_ORIGINAL: -++ port = hdr->source; -++ new_port = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_port; -++ hdr->source = new_port; -++ break; -++ case FLOW_OFFLOAD_DIR_REPLY: -++ port = hdr->dest; -++ new_port = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_port; -++ hdr->dest = new_port; -++ break; -++ default: -++ return -1; -++ } -++ -++ return nf_flow_nat_port(skb, thoff, protocol, port, new_port); -++} -++EXPORT_SYMBOL_GPL(nf_flow_snat_port); -++ -++int nf_flow_dnat_port(const struct flow_offload *flow, -++ struct sk_buff *skb, unsigned int thoff, -++ u8 protocol, enum flow_offload_tuple_dir dir) -++{ -++ struct flow_ports *hdr; -++ __be16 port, new_port; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*hdr)) || -++ skb_try_make_writable(skb, thoff + sizeof(*hdr))) -++ return -1; -++ -++ hdr = (void *)(skb_network_header(skb) + thoff); -++ -++ switch (dir) { -++ case FLOW_OFFLOAD_DIR_ORIGINAL: -++ port = hdr->dest; -++ new_port = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_port; -++ hdr->dest = new_port; -++ break; -++ case FLOW_OFFLOAD_DIR_REPLY: -++ port = hdr->source; -++ new_port = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_port; -++ hdr->source = new_port; -++ break; -++ default: -++ return -1; -++ } -++ -++ return nf_flow_nat_port(skb, thoff, protocol, port, new_port); -++} -++EXPORT_SYMBOL_GPL(nf_flow_dnat_port); -++ -++MODULE_LICENSE("GPL"); -++MODULE_AUTHOR("Pablo Neira Ayuso "); -diff --git a/target/linux/generic/backport-4.14/323-v4.16-netfilter-flow-table-support-for-IPv4.patch b/target/linux/generic/backport-4.14/323-v4.16-netfilter-flow-table-support-for-IPv4.patch -new file mode 100644 -index 0000000000..50d9039c12 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/323-v4.16-netfilter-flow-table-support-for-IPv4.patch -@@ -0,0 +1,334 @@ -+From: Pablo Neira Ayuso -+Date: Sun, 7 Jan 2018 01:04:15 +0100 -+Subject: [PATCH] netfilter: flow table support for IPv4 -+ -+This patch adds the IPv4 flow table type, that implements the datapath -+flow table to forward IPv4 traffic. Rationale is: -+ -+1) Look up for the packet in the flow table, from the ingress hook. -+2) If there's a hit, decrement ttl and pass it on to the neighbour layer -+ for transmission. -+3) If there's a miss, packet is passed up to the classic forwarding -+ path. -+ -+This patch also supports layer 3 source and destination NAT. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ create mode 100644 net/ipv4/netfilter/nf_flow_table_ipv4.c -+ -+--- a/net/ipv4/netfilter/Kconfig -++++ b/net/ipv4/netfilter/Kconfig -+@@ -78,6 +78,14 @@ config NF_TABLES_ARP -+ -+ endif # NF_TABLES -+ -++config NF_FLOW_TABLE_IPV4 -++ select NF_FLOW_TABLE -++ tristate "Netfilter flow table IPv4 module" -++ help -++ This option adds the flow table IPv4 support. -++ -++ To compile it as a module, choose M here. -++ -+ config NF_DUP_IPV4 -+ tristate "Netfilter IPv4 packet duplication to alternate destination" -+ depends on !NF_CONNTRACK || NF_CONNTRACK -+--- a/net/ipv4/netfilter/Makefile -++++ b/net/ipv4/netfilter/Makefile -+@@ -43,6 +43,9 @@ obj-$(CONFIG_NFT_REDIR_IPV4) += nft_redi -+ obj-$(CONFIG_NFT_DUP_IPV4) += nft_dup_ipv4.o -+ obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o -+ -++# flow table support -++obj-$(CONFIG_NF_FLOW_TABLE_IPV4) += nf_flow_table_ipv4.o -++ -+ # generic IP tables -+ obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o -+ -+--- /dev/null -++++ b/net/ipv4/netfilter/nf_flow_table_ipv4.c -+@@ -0,0 +1,283 @@ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++/* For layer 4 checksum field offset. */ -++#include -++#include -++ -++static int nf_flow_nat_ip_tcp(struct sk_buff *skb, unsigned int thoff, -++ __be32 addr, __be32 new_addr) -++{ -++ struct tcphdr *tcph; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*tcph)) || -++ skb_try_make_writable(skb, thoff + sizeof(*tcph))) -++ return -1; -++ -++ tcph = (void *)(skb_network_header(skb) + thoff); -++ inet_proto_csum_replace4(&tcph->check, skb, addr, new_addr, true); -++ -++ return 0; -++} -++ -++static int nf_flow_nat_ip_udp(struct sk_buff *skb, unsigned int thoff, -++ __be32 addr, __be32 new_addr) -++{ -++ struct udphdr *udph; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*udph)) || -++ skb_try_make_writable(skb, thoff + sizeof(*udph))) -++ return -1; -++ -++ udph = (void *)(skb_network_header(skb) + thoff); -++ if (udph->check || skb->ip_summed == CHECKSUM_PARTIAL) { -++ inet_proto_csum_replace4(&udph->check, skb, addr, -++ new_addr, true); -++ if (!udph->check) -++ udph->check = CSUM_MANGLED_0; -++ } -++ -++ return 0; -++} -++ -++static int nf_flow_nat_ip_l4proto(struct sk_buff *skb, struct iphdr *iph, -++ unsigned int thoff, __be32 addr, -++ __be32 new_addr) -++{ -++ switch (iph->protocol) { -++ case IPPROTO_TCP: -++ if (nf_flow_nat_ip_tcp(skb, thoff, addr, new_addr) < 0) -++ return NF_DROP; -++ break; -++ case IPPROTO_UDP: -++ if (nf_flow_nat_ip_udp(skb, thoff, addr, new_addr) < 0) -++ return NF_DROP; -++ break; -++ } -++ -++ return 0; -++} -++ -++static int nf_flow_snat_ip(const struct flow_offload *flow, struct sk_buff *skb, -++ struct iphdr *iph, unsigned int thoff, -++ enum flow_offload_tuple_dir dir) -++{ -++ __be32 addr, new_addr; -++ -++ switch (dir) { -++ case FLOW_OFFLOAD_DIR_ORIGINAL: -++ addr = iph->saddr; -++ new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_v4.s_addr; -++ iph->saddr = new_addr; -++ break; -++ case FLOW_OFFLOAD_DIR_REPLY: -++ addr = iph->daddr; -++ new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_v4.s_addr; -++ iph->daddr = new_addr; -++ break; -++ default: -++ return -1; -++ } -++ csum_replace4(&iph->check, addr, new_addr); -++ -++ return nf_flow_nat_ip_l4proto(skb, iph, thoff, addr, new_addr); -++} -++ -++static int nf_flow_dnat_ip(const struct flow_offload *flow, struct sk_buff *skb, -++ struct iphdr *iph, unsigned int thoff, -++ enum flow_offload_tuple_dir dir) -++{ -++ __be32 addr, new_addr; -++ -++ switch (dir) { -++ case FLOW_OFFLOAD_DIR_ORIGINAL: -++ addr = iph->daddr; -++ new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_v4.s_addr; -++ iph->daddr = new_addr; -++ break; -++ case FLOW_OFFLOAD_DIR_REPLY: -++ addr = iph->saddr; -++ new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_v4.s_addr; -++ iph->saddr = new_addr; -++ break; -++ default: -++ return -1; -++ } -++ -++ return nf_flow_nat_ip_l4proto(skb, iph, thoff, addr, new_addr); -++} -++ -++static int nf_flow_nat_ip(const struct flow_offload *flow, struct sk_buff *skb, -++ enum flow_offload_tuple_dir dir) -++{ -++ struct iphdr *iph = ip_hdr(skb); -++ unsigned int thoff = iph->ihl * 4; -++ -++ if (flow->flags & FLOW_OFFLOAD_SNAT && -++ (nf_flow_snat_port(flow, skb, thoff, iph->protocol, dir) < 0 || -++ nf_flow_snat_ip(flow, skb, iph, thoff, dir) < 0)) -++ return -1; -++ if (flow->flags & FLOW_OFFLOAD_DNAT && -++ (nf_flow_dnat_port(flow, skb, thoff, iph->protocol, dir) < 0 || -++ nf_flow_dnat_ip(flow, skb, iph, thoff, dir) < 0)) -++ return -1; -++ -++ return 0; -++} -++ -++static bool ip_has_options(unsigned int thoff) -++{ -++ return thoff != sizeof(struct iphdr); -++} -++ -++static int nf_flow_tuple_ip(struct sk_buff *skb, const struct net_device *dev, -++ struct flow_offload_tuple *tuple) -++{ -++ struct flow_ports *ports; -++ unsigned int thoff; -++ struct iphdr *iph; -++ -++ if (!pskb_may_pull(skb, sizeof(*iph))) -++ return -1; -++ -++ iph = ip_hdr(skb); -++ thoff = iph->ihl * 4; -++ -++ if (ip_is_fragment(iph) || -++ unlikely(ip_has_options(thoff))) -++ return -1; -++ -++ if (iph->protocol != IPPROTO_TCP && -++ iph->protocol != IPPROTO_UDP) -++ return -1; -++ -++ thoff = iph->ihl * 4; -++ if (!pskb_may_pull(skb, thoff + sizeof(*ports))) -++ return -1; -++ -++ ports = (struct flow_ports *)(skb_network_header(skb) + thoff); -++ -++ tuple->src_v4.s_addr = iph->saddr; -++ tuple->dst_v4.s_addr = iph->daddr; -++ tuple->src_port = ports->source; -++ tuple->dst_port = ports->dest; -++ tuple->l3proto = AF_INET; -++ tuple->l4proto = iph->protocol; -++ tuple->iifidx = dev->ifindex; -++ -++ return 0; -++} -++ -++/* Based on ip_exceeds_mtu(). */ -++static bool __nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) -++{ -++ if (skb->len <= mtu) -++ return false; -++ -++ if ((ip_hdr(skb)->frag_off & htons(IP_DF)) == 0) -++ return false; -++ -++ if (skb_is_gso(skb) && skb_gso_validate_mtu(skb, mtu)) -++ return false; -++ -++ return true; -++} -++ -++static bool nf_flow_exceeds_mtu(struct sk_buff *skb, const struct rtable *rt) -++{ -++ u32 mtu; -++ -++ mtu = ip_dst_mtu_maybe_forward(&rt->dst, true); -++ if (__nf_flow_exceeds_mtu(skb, mtu)) -++ return true; -++ -++ return false; -++} -++ -++static unsigned int -++nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, -++ const struct nf_hook_state *state) -++{ -++ struct flow_offload_tuple_rhash *tuplehash; -++ struct nf_flowtable *flow_table = priv; -++ struct flow_offload_tuple tuple = {}; -++ enum flow_offload_tuple_dir dir; -++ struct flow_offload *flow; -++ struct net_device *outdev; -++ const struct rtable *rt; -++ struct iphdr *iph; -++ __be32 nexthop; -++ -++ if (skb->protocol != htons(ETH_P_IP)) -++ return NF_ACCEPT; -++ -++ if (nf_flow_tuple_ip(skb, state->in, &tuple) < 0) -++ return NF_ACCEPT; -++ -++ tuplehash = flow_offload_lookup(flow_table, &tuple); -++ if (tuplehash == NULL) -++ return NF_ACCEPT; -++ -++ outdev = dev_get_by_index_rcu(state->net, tuplehash->tuple.oifidx); -++ if (!outdev) -++ return NF_ACCEPT; -++ -++ dir = tuplehash->tuple.dir; -++ flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); -++ -++ rt = (const struct rtable *)flow->tuplehash[dir].tuple.dst_cache; -++ if (unlikely(nf_flow_exceeds_mtu(skb, rt))) -++ return NF_ACCEPT; -++ -++ if (skb_try_make_writable(skb, sizeof(*iph))) -++ return NF_DROP; -++ -++ if (flow->flags & (FLOW_OFFLOAD_SNAT | FLOW_OFFLOAD_DNAT) && -++ nf_flow_nat_ip(flow, skb, dir) < 0) -++ return NF_DROP; -++ -++ flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT; -++ iph = ip_hdr(skb); -++ ip_decrease_ttl(iph); -++ -++ skb->dev = outdev; -++ nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr); -++ neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb); -++ -++ return NF_STOLEN; -++} -++ -++static struct nf_flowtable_type flowtable_ipv4 = { -++ .family = NFPROTO_IPV4, -++ .params = &nf_flow_offload_rhash_params, -++ .gc = nf_flow_offload_work_gc, -++ .hook = nf_flow_offload_ip_hook, -++ .owner = THIS_MODULE, -++}; -++ -++static int __init nf_flow_ipv4_module_init(void) -++{ -++ nft_register_flowtable_type(&flowtable_ipv4); -++ -++ return 0; -++} -++ -++static void __exit nf_flow_ipv4_module_exit(void) -++{ -++ nft_unregister_flowtable_type(&flowtable_ipv4); -++} -++ -++module_init(nf_flow_ipv4_module_init); -++module_exit(nf_flow_ipv4_module_exit); -++ -++MODULE_LICENSE("GPL"); -++MODULE_AUTHOR("Pablo Neira Ayuso "); -++MODULE_ALIAS_NF_FLOWTABLE(AF_INET); -diff --git a/target/linux/generic/backport-4.14/324-v4.16-netfilter-flow-table-support-for-IPv6.patch b/target/linux/generic/backport-4.14/324-v4.16-netfilter-flow-table-support-for-IPv6.patch -new file mode 100644 -index 0000000000..8e776383d1 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/324-v4.16-netfilter-flow-table-support-for-IPv6.patch -@@ -0,0 +1,354 @@ -+From: Pablo Neira Ayuso -+Date: Sun, 7 Jan 2018 01:04:19 +0100 -+Subject: [PATCH] netfilter: flow table support for IPv6 -+ -+This patch adds the IPv6 flow table type, that implements the datapath -+flow table to forward IPv6 traffic. -+ -+This patch exports ip6_dst_mtu_forward() that is required to check for -+mtu to pass up packets that need PMTUD handling to the classic -+forwarding path. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ create mode 100644 net/ipv6/netfilter/nf_flow_table_ipv6.c -+ -+--- a/include/net/ipv6.h -++++ b/include/net/ipv6.h -+@@ -860,6 +860,8 @@ static inline struct sk_buff *ip6_finish -+ &inet6_sk(sk)->cork); -+ } -+ -++unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst); -++ -+ int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst, -+ struct flowi6 *fl6); -+ struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, struct flowi6 *fl6, -+--- a/net/ipv6/ip6_output.c -++++ b/net/ipv6/ip6_output.c -+@@ -381,7 +381,7 @@ static inline int ip6_forward_finish(str -+ return dst_output(net, sk, skb); -+ } -+ -+-static unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst) -++unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst) -+ { -+ unsigned int mtu; -+ struct inet6_dev *idev; -+@@ -401,6 +401,7 @@ static unsigned int ip6_dst_mtu_forward( -+ -+ return mtu; -+ } -++EXPORT_SYMBOL_GPL(ip6_dst_mtu_forward); -+ -+ static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu) -+ { -+--- a/net/ipv6/netfilter/Kconfig -++++ b/net/ipv6/netfilter/Kconfig -+@@ -99,6 +99,14 @@ config NFT_FIB_IPV6 -+ endif # NF_TABLES_IPV6 -+ endif # NF_TABLES -+ -++config NF_FLOW_TABLE_IPV6 -++ select NF_FLOW_TABLE -++ tristate "Netfilter flow table IPv6 module" -++ help -++ This option adds the flow table IPv6 support. -++ -++ To compile it as a module, choose M here. -++ -+ config NF_DUP_IPV6 -+ tristate "Netfilter IPv6 packet duplication to alternate destination" -+ depends on !NF_CONNTRACK || NF_CONNTRACK -+--- a/net/ipv6/netfilter/Makefile -++++ b/net/ipv6/netfilter/Makefile -+@@ -45,6 +45,9 @@ obj-$(CONFIG_NFT_REDIR_IPV6) += nft_redi -+ obj-$(CONFIG_NFT_DUP_IPV6) += nft_dup_ipv6.o -+ obj-$(CONFIG_NFT_FIB_IPV6) += nft_fib_ipv6.o -+ -++# flow table support -++obj-$(CONFIG_NF_FLOW_TABLE_IPV6) += nf_flow_table_ipv6.o -++ -+ # matches -+ obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o -+ obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o -+--- /dev/null -++++ b/net/ipv6/netfilter/nf_flow_table_ipv6.c -+@@ -0,0 +1,277 @@ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++/* For layer 4 checksum field offset. */ -++#include -++#include -++ -++static int nf_flow_nat_ipv6_tcp(struct sk_buff *skb, unsigned int thoff, -++ struct in6_addr *addr, -++ struct in6_addr *new_addr) -++{ -++ struct tcphdr *tcph; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*tcph)) || -++ skb_try_make_writable(skb, thoff + sizeof(*tcph))) -++ return -1; -++ -++ tcph = (void *)(skb_network_header(skb) + thoff); -++ inet_proto_csum_replace16(&tcph->check, skb, addr->s6_addr32, -++ new_addr->s6_addr32, true); -++ -++ return 0; -++} -++ -++static int nf_flow_nat_ipv6_udp(struct sk_buff *skb, unsigned int thoff, -++ struct in6_addr *addr, -++ struct in6_addr *new_addr) -++{ -++ struct udphdr *udph; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*udph)) || -++ skb_try_make_writable(skb, thoff + sizeof(*udph))) -++ return -1; -++ -++ udph = (void *)(skb_network_header(skb) + thoff); -++ if (udph->check || skb->ip_summed == CHECKSUM_PARTIAL) { -++ inet_proto_csum_replace16(&udph->check, skb, addr->s6_addr32, -++ new_addr->s6_addr32, true); -++ if (!udph->check) -++ udph->check = CSUM_MANGLED_0; -++ } -++ -++ return 0; -++} -++ -++static int nf_flow_nat_ipv6_l4proto(struct sk_buff *skb, struct ipv6hdr *ip6h, -++ unsigned int thoff, struct in6_addr *addr, -++ struct in6_addr *new_addr) -++{ -++ switch (ip6h->nexthdr) { -++ case IPPROTO_TCP: -++ if (nf_flow_nat_ipv6_tcp(skb, thoff, addr, new_addr) < 0) -++ return NF_DROP; -++ break; -++ case IPPROTO_UDP: -++ if (nf_flow_nat_ipv6_udp(skb, thoff, addr, new_addr) < 0) -++ return NF_DROP; -++ break; -++ } -++ -++ return 0; -++} -++ -++static int nf_flow_snat_ipv6(const struct flow_offload *flow, -++ struct sk_buff *skb, struct ipv6hdr *ip6h, -++ unsigned int thoff, -++ enum flow_offload_tuple_dir dir) -++{ -++ struct in6_addr addr, new_addr; -++ -++ switch (dir) { -++ case FLOW_OFFLOAD_DIR_ORIGINAL: -++ addr = ip6h->saddr; -++ new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_v6; -++ ip6h->saddr = new_addr; -++ break; -++ case FLOW_OFFLOAD_DIR_REPLY: -++ addr = ip6h->daddr; -++ new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_v6; -++ ip6h->daddr = new_addr; -++ break; -++ default: -++ return -1; -++ } -++ -++ return nf_flow_nat_ipv6_l4proto(skb, ip6h, thoff, &addr, &new_addr); -++} -++ -++static int nf_flow_dnat_ipv6(const struct flow_offload *flow, -++ struct sk_buff *skb, struct ipv6hdr *ip6h, -++ unsigned int thoff, -++ enum flow_offload_tuple_dir dir) -++{ -++ struct in6_addr addr, new_addr; -++ -++ switch (dir) { -++ case FLOW_OFFLOAD_DIR_ORIGINAL: -++ addr = ip6h->daddr; -++ new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_v6; -++ ip6h->daddr = new_addr; -++ break; -++ case FLOW_OFFLOAD_DIR_REPLY: -++ addr = ip6h->saddr; -++ new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_v6; -++ ip6h->saddr = new_addr; -++ break; -++ default: -++ return -1; -++ } -++ -++ return nf_flow_nat_ipv6_l4proto(skb, ip6h, thoff, &addr, &new_addr); -++} -++ -++static int nf_flow_nat_ipv6(const struct flow_offload *flow, -++ struct sk_buff *skb, -++ enum flow_offload_tuple_dir dir) -++{ -++ struct ipv6hdr *ip6h = ipv6_hdr(skb); -++ unsigned int thoff = sizeof(*ip6h); -++ -++ if (flow->flags & FLOW_OFFLOAD_SNAT && -++ (nf_flow_snat_port(flow, skb, thoff, ip6h->nexthdr, dir) < 0 || -++ nf_flow_snat_ipv6(flow, skb, ip6h, thoff, dir) < 0)) -++ return -1; -++ if (flow->flags & FLOW_OFFLOAD_DNAT && -++ (nf_flow_dnat_port(flow, skb, thoff, ip6h->nexthdr, dir) < 0 || -++ nf_flow_dnat_ipv6(flow, skb, ip6h, thoff, dir) < 0)) -++ return -1; -++ -++ return 0; -++} -++ -++static int nf_flow_tuple_ipv6(struct sk_buff *skb, const struct net_device *dev, -++ struct flow_offload_tuple *tuple) -++{ -++ struct flow_ports *ports; -++ struct ipv6hdr *ip6h; -++ unsigned int thoff; -++ -++ if (!pskb_may_pull(skb, sizeof(*ip6h))) -++ return -1; -++ -++ ip6h = ipv6_hdr(skb); -++ -++ if (ip6h->nexthdr != IPPROTO_TCP && -++ ip6h->nexthdr != IPPROTO_UDP) -++ return -1; -++ -++ thoff = sizeof(*ip6h); -++ if (!pskb_may_pull(skb, thoff + sizeof(*ports))) -++ return -1; -++ -++ ports = (struct flow_ports *)(skb_network_header(skb) + thoff); -++ -++ tuple->src_v6 = ip6h->saddr; -++ tuple->dst_v6 = ip6h->daddr; -++ tuple->src_port = ports->source; -++ tuple->dst_port = ports->dest; -++ tuple->l3proto = AF_INET6; -++ tuple->l4proto = ip6h->nexthdr; -++ tuple->iifidx = dev->ifindex; -++ -++ return 0; -++} -++ -++/* Based on ip_exceeds_mtu(). */ -++static bool __nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) -++{ -++ if (skb->len <= mtu) -++ return false; -++ -++ if (skb_is_gso(skb) && skb_gso_validate_mtu(skb, mtu)) -++ return false; -++ -++ return true; -++} -++ -++static bool nf_flow_exceeds_mtu(struct sk_buff *skb, const struct rt6_info *rt) -++{ -++ u32 mtu; -++ -++ mtu = ip6_dst_mtu_forward(&rt->dst); -++ if (__nf_flow_exceeds_mtu(skb, mtu)) -++ return true; -++ -++ return false; -++} -++ -++static unsigned int -++nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, -++ const struct nf_hook_state *state) -++{ -++ struct flow_offload_tuple_rhash *tuplehash; -++ struct nf_flowtable *flow_table = priv; -++ struct flow_offload_tuple tuple = {}; -++ enum flow_offload_tuple_dir dir; -++ struct flow_offload *flow; -++ struct net_device *outdev; -++ struct in6_addr *nexthop; -++ struct ipv6hdr *ip6h; -++ struct rt6_info *rt; -++ -++ if (skb->protocol != htons(ETH_P_IPV6)) -++ return NF_ACCEPT; -++ -++ if (nf_flow_tuple_ipv6(skb, state->in, &tuple) < 0) -++ return NF_ACCEPT; -++ -++ tuplehash = flow_offload_lookup(flow_table, &tuple); -++ if (tuplehash == NULL) -++ return NF_ACCEPT; -++ -++ outdev = dev_get_by_index_rcu(state->net, tuplehash->tuple.oifidx); -++ if (!outdev) -++ return NF_ACCEPT; -++ -++ dir = tuplehash->tuple.dir; -++ flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); -++ -++ rt = (struct rt6_info *)flow->tuplehash[dir].tuple.dst_cache; -++ if (unlikely(nf_flow_exceeds_mtu(skb, rt))) -++ return NF_ACCEPT; -++ -++ if (skb_try_make_writable(skb, sizeof(*ip6h))) -++ return NF_DROP; -++ -++ if (flow->flags & (FLOW_OFFLOAD_SNAT | FLOW_OFFLOAD_DNAT) && -++ nf_flow_nat_ipv6(flow, skb, dir) < 0) -++ return NF_DROP; -++ -++ flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT; -++ ip6h = ipv6_hdr(skb); -++ ip6h->hop_limit--; -++ -++ skb->dev = outdev; -++ nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6); -++ neigh_xmit(NEIGH_ND_TABLE, outdev, nexthop, skb); -++ -++ return NF_STOLEN; -++} -++ -++static struct nf_flowtable_type flowtable_ipv6 = { -++ .family = NFPROTO_IPV6, -++ .params = &nf_flow_offload_rhash_params, -++ .gc = nf_flow_offload_work_gc, -++ .hook = nf_flow_offload_ipv6_hook, -++ .owner = THIS_MODULE, -++}; -++ -++static int __init nf_flow_ipv6_module_init(void) -++{ -++ nft_register_flowtable_type(&flowtable_ipv6); -++ -++ return 0; -++} -++ -++static void __exit nf_flow_ipv6_module_exit(void) -++{ -++ nft_unregister_flowtable_type(&flowtable_ipv6); -++} -++ -++module_init(nf_flow_ipv6_module_init); -++module_exit(nf_flow_ipv6_module_exit); -++ -++MODULE_LICENSE("GPL"); -++MODULE_AUTHOR("Pablo Neira Ayuso "); -++MODULE_ALIAS_NF_FLOWTABLE(AF_INET6); -diff --git a/target/linux/generic/backport-4.14/325-v4.16-netfilter-flow-table-support-for-the-mixed-IPv4-IPv6.patch b/target/linux/generic/backport-4.14/325-v4.16-netfilter-flow-table-support-for-the-mixed-IPv4-IPv6.patch -new file mode 100644 -index 0000000000..04948d88ab ---- /dev/null -+++ b/target/linux/generic/backport-4.14/325-v4.16-netfilter-flow-table-support-for-the-mixed-IPv4-IPv6.patch -@@ -0,0 +1,141 @@ -+From: Pablo Neira Ayuso -+Date: Sun, 7 Jan 2018 01:04:22 +0100 -+Subject: [PATCH] netfilter: flow table support for the mixed IPv4/IPv6 family -+ -+This patch adds the IPv6 flow table type, that implements the datapath -+flow table to forward IPv6 traffic. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ create mode 100644 net/netfilter/nf_flow_table_inet.c -+ -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -111,6 +111,11 @@ struct flow_ports { -+ __be16 source, dest; -+ }; -+ -++unsigned int nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, -++ const struct nf_hook_state *state); -++unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, -++ const struct nf_hook_state *state); -++ -+ #define MODULE_ALIAS_NF_FLOWTABLE(family) \ -+ MODULE_ALIAS("nf-flowtable-" __stringify(family)) -+ -+--- a/net/ipv4/netfilter/nf_flow_table_ipv4.c -++++ b/net/ipv4/netfilter/nf_flow_table_ipv4.c -+@@ -202,7 +202,7 @@ static bool nf_flow_exceeds_mtu(struct s -+ return false; -+ } -+ -+-static unsigned int -++unsigned int -+ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, -+ const struct nf_hook_state *state) -+ { -+@@ -254,6 +254,7 @@ nf_flow_offload_ip_hook(void *priv, stru -+ -+ return NF_STOLEN; -+ } -++EXPORT_SYMBOL_GPL(nf_flow_offload_ip_hook); -+ -+ static struct nf_flowtable_type flowtable_ipv4 = { -+ .family = NFPROTO_IPV4, -+--- a/net/ipv6/netfilter/nf_flow_table_ipv6.c -++++ b/net/ipv6/netfilter/nf_flow_table_ipv6.c -+@@ -196,7 +196,7 @@ static bool nf_flow_exceeds_mtu(struct s -+ return false; -+ } -+ -+-static unsigned int -++unsigned int -+ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, -+ const struct nf_hook_state *state) -+ { -+@@ -248,6 +248,7 @@ nf_flow_offload_ipv6_hook(void *priv, st -+ -+ return NF_STOLEN; -+ } -++EXPORT_SYMBOL_GPL(nf_flow_offload_ipv6_hook); -+ -+ static struct nf_flowtable_type flowtable_ipv6 = { -+ .family = NFPROTO_IPV6, -+--- a/net/netfilter/Kconfig -++++ b/net/netfilter/Kconfig -+@@ -667,6 +667,14 @@ endif # NF_TABLES_NETDEV -+ -+ endif # NF_TABLES -+ -++config NF_FLOW_TABLE_INET -++ select NF_FLOW_TABLE -++ tristate "Netfilter flow table mixed IPv4/IPv6 module" -++ help -++ This option adds the flow table mixed IPv4/IPv6 support. -++ -++ To compile it as a module, choose M here. -++ -+ config NF_FLOW_TABLE -+ tristate "Netfilter flow table module" -+ help -+--- a/net/netfilter/Makefile -++++ b/net/netfilter/Makefile -+@@ -112,6 +112,7 @@ obj-$(CONFIG_NFT_FWD_NETDEV) += nft_fwd_ -+ -+ # flow table infrastructure -+ obj-$(CONFIG_NF_FLOW_TABLE) += nf_flow_table.o -++obj-$(CONFIG_NF_FLOW_TABLE_INET) += nf_flow_table_inet.o -+ -+ # generic X tables -+ obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o -+--- /dev/null -++++ b/net/netfilter/nf_flow_table_inet.c -+@@ -0,0 +1,48 @@ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++static unsigned int -++nf_flow_offload_inet_hook(void *priv, struct sk_buff *skb, -++ const struct nf_hook_state *state) -++{ -++ switch (skb->protocol) { -++ case htons(ETH_P_IP): -++ return nf_flow_offload_ip_hook(priv, skb, state); -++ case htons(ETH_P_IPV6): -++ return nf_flow_offload_ipv6_hook(priv, skb, state); -++ } -++ -++ return NF_ACCEPT; -++} -++ -++static struct nf_flowtable_type flowtable_inet = { -++ .family = NFPROTO_INET, -++ .params = &nf_flow_offload_rhash_params, -++ .gc = nf_flow_offload_work_gc, -++ .hook = nf_flow_offload_inet_hook, -++ .owner = THIS_MODULE, -++}; -++ -++static int __init nf_flow_inet_module_init(void) -++{ -++ nft_register_flowtable_type(&flowtable_inet); -++ -++ return 0; -++} -++ -++static void __exit nf_flow_inet_module_exit(void) -++{ -++ nft_unregister_flowtable_type(&flowtable_inet); -++} -++ -++module_init(nf_flow_inet_module_init); -++module_exit(nf_flow_inet_module_exit); -++ -++MODULE_LICENSE("GPL"); -++MODULE_AUTHOR("Pablo Neira Ayuso "); -++MODULE_ALIAS_NF_FLOWTABLE(1); /* NFPROTO_INET */ -diff --git a/target/linux/generic/backport-4.14/326-v4.16-netfilter-nf_tables-flow-offload-expression.patch b/target/linux/generic/backport-4.14/326-v4.16-netfilter-nf_tables-flow-offload-expression.patch -new file mode 100644 -index 0000000000..0decc34105 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/326-v4.16-netfilter-nf_tables-flow-offload-expression.patch -@@ -0,0 +1,332 @@ -+From: Pablo Neira Ayuso -+Date: Sun, 7 Jan 2018 01:04:26 +0100 -+Subject: [PATCH] netfilter: nf_tables: flow offload expression -+ -+Add new instruction for the nf_tables VM that allows us to specify what -+flows are offloaded into a given flow table via name. This new -+instruction creates the flow entry and adds it to the flow table. -+ -+Only established flows, ie. we have seen traffic in both directions, are -+added to the flow table. You can still decide to offload entries at a -+later stage via packet counting or checking the ct status in case you -+want to offload assured conntracks. -+ -+This new extension depends on the conntrack subsystem. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ create mode 100644 net/netfilter/nft_flow_offload.c -+ -+--- a/include/uapi/linux/netfilter/nf_tables.h -++++ b/include/uapi/linux/netfilter/nf_tables.h -+@@ -957,6 +957,17 @@ enum nft_ct_attributes { -+ }; -+ #define NFTA_CT_MAX (__NFTA_CT_MAX - 1) -+ -++/** -++ * enum nft_flow_attributes - ct offload expression attributes -++ * @NFTA_FLOW_TABLE_NAME: flow table name (NLA_STRING) -++ */ -++enum nft_offload_attributes { -++ NFTA_FLOW_UNSPEC, -++ NFTA_FLOW_TABLE_NAME, -++ __NFTA_FLOW_MAX, -++}; -++#define NFTA_FLOW_MAX (__NFTA_FLOW_MAX - 1) -++ -+ enum nft_limit_type { -+ NFT_LIMIT_PKTS, -+ NFT_LIMIT_PKT_BYTES -+--- a/net/netfilter/Kconfig -++++ b/net/netfilter/Kconfig -+@@ -515,6 +515,13 @@ config NFT_CT -+ This option adds the "ct" expression that you can use to match -+ connection tracking information such as the flow state. -+ -++config NFT_FLOW_OFFLOAD -++ depends on NF_CONNTRACK -++ tristate "Netfilter nf_tables hardware flow offload module" -++ help -++ This option adds the "flow_offload" expression that you can use to -++ choose what flows are placed into the hardware. -++ -+ config NFT_SET_RBTREE -+ tristate "Netfilter nf_tables rbtree set module" -+ help -+--- a/net/netfilter/Makefile -++++ b/net/netfilter/Makefile -+@@ -87,6 +87,7 @@ obj-$(CONFIG_NFT_META) += nft_meta.o -+ obj-$(CONFIG_NFT_RT) += nft_rt.o -+ obj-$(CONFIG_NFT_NUMGEN) += nft_numgen.o -+ obj-$(CONFIG_NFT_CT) += nft_ct.o -++obj-$(CONFIG_NFT_FLOW_OFFLOAD) += nft_flow_offload.o -+ obj-$(CONFIG_NFT_LIMIT) += nft_limit.o -+ obj-$(CONFIG_NFT_NAT) += nft_nat.o -+ obj-$(CONFIG_NFT_OBJREF) += nft_objref.o -+--- /dev/null -++++ b/net/netfilter/nft_flow_offload.c -+@@ -0,0 +1,264 @@ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include /* for ipv4 options. */ -++#include -++#include -++#include -++#include -++#include -++ -++struct nft_flow_offload { -++ struct nft_flowtable *flowtable; -++}; -++ -++static int nft_flow_route(const struct nft_pktinfo *pkt, -++ const struct nf_conn *ct, -++ struct nf_flow_route *route, -++ enum ip_conntrack_dir dir) -++{ -++ struct dst_entry *this_dst = skb_dst(pkt->skb); -++ struct dst_entry *other_dst = NULL; -++ struct flowi fl; -++ -++ memset(&fl, 0, sizeof(fl)); -++ switch (nft_pf(pkt)) { -++ case NFPROTO_IPV4: -++ fl.u.ip4.daddr = ct->tuplehash[!dir].tuple.dst.u3.ip; -++ break; -++ case NFPROTO_IPV6: -++ fl.u.ip6.daddr = ct->tuplehash[!dir].tuple.dst.u3.in6; -++ break; -++ } -++ -++ nf_route(nft_net(pkt), &other_dst, &fl, false, nft_pf(pkt)); -++ if (!other_dst) -++ return -ENOENT; -++ -++ route->tuple[dir].dst = this_dst; -++ route->tuple[dir].ifindex = nft_in(pkt)->ifindex; -++ route->tuple[!dir].dst = other_dst; -++ route->tuple[!dir].ifindex = nft_out(pkt)->ifindex; -++ -++ return 0; -++} -++ -++static bool nft_flow_offload_skip(struct sk_buff *skb) -++{ -++ struct ip_options *opt = &(IPCB(skb)->opt); -++ -++ if (unlikely(opt->optlen)) -++ return true; -++ if (skb_sec_path(skb)) -++ return true; -++ -++ return false; -++} -++ -++static void nft_flow_offload_eval(const struct nft_expr *expr, -++ struct nft_regs *regs, -++ const struct nft_pktinfo *pkt) -++{ -++ struct nft_flow_offload *priv = nft_expr_priv(expr); -++ struct nf_flowtable *flowtable = &priv->flowtable->data; -++ enum ip_conntrack_info ctinfo; -++ struct nf_flow_route route; -++ struct flow_offload *flow; -++ enum ip_conntrack_dir dir; -++ struct nf_conn *ct; -++ int ret; -++ -++ if (nft_flow_offload_skip(pkt->skb)) -++ goto out; -++ -++ ct = nf_ct_get(pkt->skb, &ctinfo); -++ if (!ct) -++ goto out; -++ -++ switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) { -++ case IPPROTO_TCP: -++ case IPPROTO_UDP: -++ break; -++ default: -++ goto out; -++ } -++ -++ if (test_bit(IPS_HELPER_BIT, &ct->status)) -++ goto out; -++ -++ if (ctinfo == IP_CT_NEW || -++ ctinfo == IP_CT_RELATED) -++ goto out; -++ -++ if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status)) -++ goto out; -++ -++ dir = CTINFO2DIR(ctinfo); -++ if (nft_flow_route(pkt, ct, &route, dir) < 0) -++ goto err_flow_route; -++ -++ flow = flow_offload_alloc(ct, &route); -++ if (!flow) -++ goto err_flow_alloc; -++ -++ ret = flow_offload_add(flowtable, flow); -++ if (ret < 0) -++ goto err_flow_add; -++ -++ return; -++ -++err_flow_add: -++ flow_offload_free(flow); -++err_flow_alloc: -++ dst_release(route.tuple[!dir].dst); -++err_flow_route: -++ clear_bit(IPS_OFFLOAD_BIT, &ct->status); -++out: -++ regs->verdict.code = NFT_BREAK; -++} -++ -++static int nft_flow_offload_validate(const struct nft_ctx *ctx, -++ const struct nft_expr *expr, -++ const struct nft_data **data) -++{ -++ unsigned int hook_mask = (1 << NF_INET_FORWARD); -++ -++ return nft_chain_validate_hooks(ctx->chain, hook_mask); -++} -++ -++static int nft_flow_offload_init(const struct nft_ctx *ctx, -++ const struct nft_expr *expr, -++ const struct nlattr * const tb[]) -++{ -++ struct nft_flow_offload *priv = nft_expr_priv(expr); -++ u8 genmask = nft_genmask_next(ctx->net); -++ struct nft_flowtable *flowtable; -++ -++ if (!tb[NFTA_FLOW_TABLE_NAME]) -++ return -EINVAL; -++ -++ flowtable = nf_tables_flowtable_lookup(ctx->table, -++ tb[NFTA_FLOW_TABLE_NAME], -++ genmask); -++ if (IS_ERR(flowtable)) -++ return PTR_ERR(flowtable); -++ -++ priv->flowtable = flowtable; -++ flowtable->use++; -++ -++ return nf_ct_netns_get(ctx->net, ctx->afi->family); -++} -++ -++static void nft_flow_offload_destroy(const struct nft_ctx *ctx, -++ const struct nft_expr *expr) -++{ -++ struct nft_flow_offload *priv = nft_expr_priv(expr); -++ -++ priv->flowtable->use--; -++ nf_ct_netns_put(ctx->net, ctx->afi->family); -++} -++ -++static int nft_flow_offload_dump(struct sk_buff *skb, const struct nft_expr *expr) -++{ -++ struct nft_flow_offload *priv = nft_expr_priv(expr); -++ -++ if (nla_put_string(skb, NFTA_FLOW_TABLE_NAME, priv->flowtable->name)) -++ goto nla_put_failure; -++ -++ return 0; -++ -++nla_put_failure: -++ return -1; -++} -++ -++static struct nft_expr_type nft_flow_offload_type; -++static const struct nft_expr_ops nft_flow_offload_ops = { -++ .type = &nft_flow_offload_type, -++ .size = NFT_EXPR_SIZE(sizeof(struct nft_flow_offload)), -++ .eval = nft_flow_offload_eval, -++ .init = nft_flow_offload_init, -++ .destroy = nft_flow_offload_destroy, -++ .validate = nft_flow_offload_validate, -++ .dump = nft_flow_offload_dump, -++}; -++ -++static struct nft_expr_type nft_flow_offload_type __read_mostly = { -++ .name = "flow_offload", -++ .ops = &nft_flow_offload_ops, -++ .maxattr = NFTA_FLOW_MAX, -++ .owner = THIS_MODULE, -++}; -++ -++static void flow_offload_iterate_cleanup(struct flow_offload *flow, void *data) -++{ -++ struct net_device *dev = data; -++ -++ if (dev && flow->tuplehash[0].tuple.iifidx != dev->ifindex) -++ return; -++ -++ flow_offload_dead(flow); -++} -++ -++static void nft_flow_offload_iterate_cleanup(struct nf_flowtable *flowtable, -++ void *data) -++{ -++ nf_flow_table_iterate(flowtable, flow_offload_iterate_cleanup, data); -++} -++ -++static int flow_offload_netdev_event(struct notifier_block *this, -++ unsigned long event, void *ptr) -++{ -++ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -++ -++ if (event != NETDEV_DOWN) -++ return NOTIFY_DONE; -++ -++ nft_flow_table_iterate(dev_net(dev), nft_flow_offload_iterate_cleanup, dev); -++ -++ return NOTIFY_DONE; -++} -++ -++static struct notifier_block flow_offload_netdev_notifier = { -++ .notifier_call = flow_offload_netdev_event, -++}; -++ -++static int __init nft_flow_offload_module_init(void) -++{ -++ int err; -++ -++ register_netdevice_notifier(&flow_offload_netdev_notifier); -++ -++ err = nft_register_expr(&nft_flow_offload_type); -++ if (err < 0) -++ goto register_expr; -++ -++ return 0; -++ -++register_expr: -++ unregister_netdevice_notifier(&flow_offload_netdev_notifier); -++ return err; -++} -++ -++static void __exit nft_flow_offload_module_exit(void) -++{ -++ struct net *net; -++ -++ nft_unregister_expr(&nft_flow_offload_type); -++ unregister_netdevice_notifier(&flow_offload_netdev_notifier); -++ rtnl_lock(); -++ for_each_net(net) -++ nft_flow_table_iterate(net, nft_flow_offload_iterate_cleanup, NULL); -++ rtnl_unlock(); -++} -++ -++module_init(nft_flow_offload_module_init); -++module_exit(nft_flow_offload_module_exit); -++ -++MODULE_LICENSE("GPL"); -++MODULE_AUTHOR("Pablo Neira Ayuso "); -++MODULE_ALIAS_NFT_EXPR("flow_offload"); -diff --git a/target/linux/generic/backport-4.14/327-v4.16-netfilter-nf_tables-remove-nhooks-field-from-struct-.patch b/target/linux/generic/backport-4.14/327-v4.16-netfilter-nf_tables-remove-nhooks-field-from-struct-.patch -new file mode 100644 -index 0000000000..188ee11b84 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/327-v4.16-netfilter-nf_tables-remove-nhooks-field-from-struct-.patch -@@ -0,0 +1,113 @@ -+From: Pablo Neira Ayuso -+Date: Tue, 19 Dec 2017 13:53:45 +0100 -+Subject: [PATCH] netfilter: nf_tables: remove nhooks field from struct -+ nft_af_info -+ -+We already validate the hook through bitmask, so this check is -+superfluous. When removing this, this patch is also fixing a bug in the -+new flowtable codebase, since ctx->afi points to the table family -+instead of the netdev family which is where the flowtable is really -+hooked in. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/net/netfilter/nf_tables.h -++++ b/include/net/netfilter/nf_tables.h -+@@ -969,7 +969,6 @@ enum nft_af_flags { -+ * -+ * @list: used internally -+ * @family: address family -+- * @nhooks: number of hooks in this family -+ * @owner: module owner -+ * @tables: used internally -+ * @flags: family flags -+@@ -977,7 +976,6 @@ enum nft_af_flags { -+ struct nft_af_info { -+ struct list_head list; -+ int family; -+- unsigned int nhooks; -+ struct module *owner; -+ struct list_head tables; -+ u32 flags; -+--- a/net/bridge/netfilter/nf_tables_bridge.c -++++ b/net/bridge/netfilter/nf_tables_bridge.c -+@@ -44,7 +44,6 @@ nft_do_chain_bridge(void *priv, -+ -+ static struct nft_af_info nft_af_bridge __read_mostly = { -+ .family = NFPROTO_BRIDGE, -+- .nhooks = NF_BR_NUMHOOKS, -+ .owner = THIS_MODULE, -+ }; -+ -+--- a/net/ipv4/netfilter/nf_tables_arp.c -++++ b/net/ipv4/netfilter/nf_tables_arp.c -+@@ -29,7 +29,6 @@ nft_do_chain_arp(void *priv, -+ -+ static struct nft_af_info nft_af_arp __read_mostly = { -+ .family = NFPROTO_ARP, -+- .nhooks = NF_ARP_NUMHOOKS, -+ .owner = THIS_MODULE, -+ }; -+ -+--- a/net/ipv4/netfilter/nf_tables_ipv4.c -++++ b/net/ipv4/netfilter/nf_tables_ipv4.c -+@@ -32,7 +32,6 @@ static unsigned int nft_do_chain_ipv4(vo -+ -+ static struct nft_af_info nft_af_ipv4 __read_mostly = { -+ .family = NFPROTO_IPV4, -+- .nhooks = NF_INET_NUMHOOKS, -+ .owner = THIS_MODULE, -+ }; -+ -+--- a/net/ipv6/netfilter/nf_tables_ipv6.c -++++ b/net/ipv6/netfilter/nf_tables_ipv6.c -+@@ -30,7 +30,6 @@ static unsigned int nft_do_chain_ipv6(vo -+ -+ static struct nft_af_info nft_af_ipv6 __read_mostly = { -+ .family = NFPROTO_IPV6, -+- .nhooks = NF_INET_NUMHOOKS, -+ .owner = THIS_MODULE, -+ }; -+ -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -1374,9 +1374,6 @@ static int nft_chain_parse_hook(struct n -+ return -EINVAL; -+ -+ hook->num = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM])); -+- if (hook->num >= afi->nhooks) -+- return -EINVAL; -+- -+ hook->priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY])); -+ -+ type = chain_type[afi->family][NFT_CHAIN_T_DEFAULT]; -+@@ -5014,7 +5011,7 @@ static int nf_tables_flowtable_parse_hoo -+ return -EINVAL; -+ -+ hooknum = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_NUM])); -+- if (hooknum >= ctx->afi->nhooks) -++ if (hooknum != NF_NETDEV_INGRESS) -+ return -EINVAL; -+ -+ priority = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_PRIORITY])); -+--- a/net/netfilter/nf_tables_inet.c -++++ b/net/netfilter/nf_tables_inet.c -+@@ -40,7 +40,6 @@ static unsigned int nft_do_chain_inet(vo -+ -+ static struct nft_af_info nft_af_inet __read_mostly = { -+ .family = NFPROTO_INET, -+- .nhooks = NF_INET_NUMHOOKS, -+ .owner = THIS_MODULE, -+ }; -+ -+--- a/net/netfilter/nf_tables_netdev.c -++++ b/net/netfilter/nf_tables_netdev.c -+@@ -40,7 +40,6 @@ nft_do_chain_netdev(void *priv, struct s -+ -+ static struct nft_af_info nft_af_netdev __read_mostly = { -+ .family = NFPROTO_NETDEV, -+- .nhooks = NF_NETDEV_NUMHOOKS, -+ .owner = THIS_MODULE, -+ .flags = NFT_AF_NEEDS_DEV, -+ }; -diff --git a/target/linux/generic/backport-4.14/328-v4.16-netfilter-nf_tables-fix-a-typo-in-nf_tables_getflowt.patch b/target/linux/generic/backport-4.14/328-v4.16-netfilter-nf_tables-fix-a-typo-in-nf_tables_getflowt.patch -new file mode 100644 -index 0000000000..1f0a5a2bb3 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/328-v4.16-netfilter-nf_tables-fix-a-typo-in-nf_tables_getflowt.patch -@@ -0,0 +1,22 @@ -+From: Wei Yongjun -+Date: Wed, 10 Jan 2018 07:04:54 +0000 -+Subject: [PATCH] netfilter: nf_tables: fix a typo in nf_tables_getflowtable() -+ -+Fix a typo, we should check 'flowtable' instead of 'table'. -+ -+Fixes: 3b49e2e94e6e ("netfilter: nf_tables: add flow table netlink frontend") -+Signed-off-by: Wei Yongjun -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -5438,7 +5438,7 @@ static int nf_tables_getflowtable(struct -+ -+ flowtable = nf_tables_flowtable_lookup(table, nla[NFTA_FLOWTABLE_NAME], -+ genmask); -+- if (IS_ERR(table)) -++ if (IS_ERR(flowtable)) -+ return PTR_ERR(flowtable); -+ -+ skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); -diff --git a/target/linux/generic/backport-4.14/329-v4.16-netfilter-improve-flow-table-Kconfig-dependencies.patch b/target/linux/generic/backport-4.14/329-v4.16-netfilter-improve-flow-table-Kconfig-dependencies.patch -new file mode 100644 -index 0000000000..0d5cd3bb4f ---- /dev/null -+++ b/target/linux/generic/backport-4.14/329-v4.16-netfilter-improve-flow-table-Kconfig-dependencies.patch -@@ -0,0 +1,106 @@ -+From: Arnd Bergmann -+Date: Wed, 10 Jan 2018 18:10:59 +0100 -+Subject: [PATCH] netfilter: improve flow table Kconfig dependencies -+ -+The newly added NF_FLOW_TABLE options cause some build failures in -+randconfig kernels: -+ -+- when CONFIG_NF_CONNTRACK is disabled, or is a loadable module but -+ NF_FLOW_TABLE is built-in: -+ -+ In file included from net/netfilter/nf_flow_table.c:8:0: -+ include/net/netfilter/nf_conntrack.h:59:22: error: field 'ct_general' has incomplete type -+ struct nf_conntrack ct_general; -+ include/net/netfilter/nf_conntrack.h: In function 'nf_ct_get': -+ include/net/netfilter/nf_conntrack.h:148:15: error: 'const struct sk_buff' has no member named '_nfct' -+ include/net/netfilter/nf_conntrack.h: In function 'nf_ct_put': -+ include/net/netfilter/nf_conntrack.h:157:2: error: implicit declaration of function 'nf_conntrack_put'; did you mean 'nf_ct_put'? [-Werror=implicit-function-declaration] -+ -+ net/netfilter/nf_flow_table.o: In function `nf_flow_offload_work_gc': -+ (.text+0x1540): undefined reference to `nf_ct_delete' -+ -+- when CONFIG_NF_TABLES is disabled: -+ -+ In file included from net/ipv6/netfilter/nf_flow_table_ipv6.c:13:0: -+ include/net/netfilter/nf_tables.h: In function 'nft_gencursor_next': -+ include/net/netfilter/nf_tables.h:1189:14: error: 'const struct net' has no member named 'nft'; did you mean 'nf'? -+ -+ - when CONFIG_NF_FLOW_TABLE_INET is enabled, but NF_FLOW_TABLE_IPV4 -+ or NF_FLOW_TABLE_IPV6 are not, or are loadable modules -+ -+ net/netfilter/nf_flow_table_inet.o: In function `nf_flow_offload_inet_hook': -+ nf_flow_table_inet.c:(.text+0x94): undefined reference to `nf_flow_offload_ipv6_hook' -+ nf_flow_table_inet.c:(.text+0x40): undefined reference to `nf_flow_offload_ip_hook' -+ -+- when CONFIG_NF_FLOW_TABLES is disabled, but the other options are -+ enabled: -+ -+ net/netfilter/nf_flow_table_inet.o: In function `nf_flow_offload_inet_hook': -+ nf_flow_table_inet.c:(.text+0x6c): undefined reference to `nf_flow_offload_ipv6_hook' -+ net/netfilter/nf_flow_table_inet.o: In function `nf_flow_inet_module_exit': -+ nf_flow_table_inet.c:(.exit.text+0x8): undefined reference to `nft_unregister_flowtable_type' -+ net/netfilter/nf_flow_table_inet.o: In function `nf_flow_inet_module_init': -+ nf_flow_table_inet.c:(.init.text+0x8): undefined reference to `nft_register_flowtable_type' -+ net/ipv4/netfilter/nf_flow_table_ipv4.o: In function `nf_flow_ipv4_module_exit': -+ nf_flow_table_ipv4.c:(.exit.text+0x8): undefined reference to `nft_unregister_flowtable_type' -+ net/ipv4/netfilter/nf_flow_table_ipv4.o: In function `nf_flow_ipv4_module_init': -+ nf_flow_table_ipv4.c:(.init.text+0x8): undefined reference to `nft_register_flowtable_type' -+ -+This adds additional Kconfig dependencies to ensure that NF_CONNTRACK and NF_TABLES -+are always visible from NF_FLOW_TABLE, and that the internal dependencies between -+the four new modules are met. -+ -+Fixes: 7c23b629a808 ("netfilter: flow table support for the mixed IPv4/IPv6 family") -+Fixes: 0995210753a2 ("netfilter: flow table support for IPv6") -+Fixes: 97add9f0d66d ("netfilter: flow table support for IPv4") -+Signed-off-by: Arnd Bergmann -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/net/ipv4/netfilter/Kconfig -++++ b/net/ipv4/netfilter/Kconfig -+@@ -79,8 +79,9 @@ config NF_TABLES_ARP -+ endif # NF_TABLES -+ -+ config NF_FLOW_TABLE_IPV4 -+- select NF_FLOW_TABLE -+ tristate "Netfilter flow table IPv4 module" -++ depends on NF_CONNTRACK && NF_TABLES -++ select NF_FLOW_TABLE -+ help -+ This option adds the flow table IPv4 support. -+ -+--- a/net/ipv6/netfilter/Kconfig -++++ b/net/ipv6/netfilter/Kconfig -+@@ -100,8 +100,9 @@ endif # NF_TABLES_IPV6 -+ endif # NF_TABLES -+ -+ config NF_FLOW_TABLE_IPV6 -+- select NF_FLOW_TABLE -+ tristate "Netfilter flow table IPv6 module" -++ depends on NF_CONNTRACK && NF_TABLES -++ select NF_FLOW_TABLE -+ help -+ This option adds the flow table IPv6 support. -+ -+--- a/net/netfilter/Kconfig -++++ b/net/netfilter/Kconfig -+@@ -675,8 +675,9 @@ endif # NF_TABLES_NETDEV -+ endif # NF_TABLES -+ -+ config NF_FLOW_TABLE_INET -+- select NF_FLOW_TABLE -+ tristate "Netfilter flow table mixed IPv4/IPv6 module" -++ depends on NF_FLOW_TABLE_IPV4 && NF_FLOW_TABLE_IPV6 -++ select NF_FLOW_TABLE -+ help -+ This option adds the flow table mixed IPv4/IPv6 support. -+ -+@@ -684,6 +685,7 @@ config NF_FLOW_TABLE_INET -+ -+ config NF_FLOW_TABLE -+ tristate "Netfilter flow table module" -++ depends on NF_CONNTRACK && NF_TABLES -+ help -+ This option adds the flow table core infrastructure. -+ -diff --git a/target/linux/generic/backport-4.14/330-v4.16-netfilter-nf_tables-remove-flag-field-from-struct-nf.patch b/target/linux/generic/backport-4.14/330-v4.16-netfilter-nf_tables-remove-flag-field-from-struct-nf.patch -new file mode 100644 -index 0000000000..8f82effa79 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/330-v4.16-netfilter-nf_tables-remove-flag-field-from-struct-nf.patch -@@ -0,0 +1,59 @@ -+From: Pablo Neira Ayuso -+Date: Tue, 19 Dec 2017 14:07:52 +0100 -+Subject: [PATCH] netfilter: nf_tables: remove flag field from struct -+ nft_af_info -+ -+Replace it by a direct check for the netdev protocol family. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/net/netfilter/nf_tables.h -++++ b/include/net/netfilter/nf_tables.h -+@@ -960,10 +960,6 @@ struct nft_table { -+ char *name; -+ }; -+ -+-enum nft_af_flags { -+- NFT_AF_NEEDS_DEV = (1 << 0), -+-}; -+- -+ /** -+ * struct nft_af_info - nf_tables address family info -+ * -+@@ -971,14 +967,12 @@ enum nft_af_flags { -+ * @family: address family -+ * @owner: module owner -+ * @tables: used internally -+- * @flags: family flags -+ */ -+ struct nft_af_info { -+ struct list_head list; -+ int family; -+ struct module *owner; -+ struct list_head tables; -+- u32 flags; -+ }; -+ -+ int nft_register_afinfo(struct net *, struct nft_af_info *); -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -1391,7 +1391,7 @@ static int nft_chain_parse_hook(struct n -+ hook->type = type; -+ -+ hook->dev = NULL; -+- if (afi->flags & NFT_AF_NEEDS_DEV) { -++ if (afi->family == NFPROTO_NETDEV) { -+ char ifname[IFNAMSIZ]; -+ -+ if (!ha[NFTA_HOOK_DEV]) { -+--- a/net/netfilter/nf_tables_netdev.c -++++ b/net/netfilter/nf_tables_netdev.c -+@@ -41,7 +41,6 @@ nft_do_chain_netdev(void *priv, struct s -+ static struct nft_af_info nft_af_netdev __read_mostly = { -+ .family = NFPROTO_NETDEV, -+ .owner = THIS_MODULE, -+- .flags = NFT_AF_NEEDS_DEV, -+ }; -+ -+ static int nf_tables_netdev_init_net(struct net *net) -diff --git a/target/linux/generic/backport-4.14/331-v4.16-netfilter-nf_tables-no-need-for-struct-nft_af_info-t.patch b/target/linux/generic/backport-4.14/331-v4.16-netfilter-nf_tables-no-need-for-struct-nft_af_info-t.patch -new file mode 100644 -index 0000000000..f7e7eeaa05 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/331-v4.16-netfilter-nf_tables-no-need-for-struct-nft_af_info-t.patch -@@ -0,0 +1,80 @@ -+From: Pablo Neira Ayuso -+Date: Tue, 19 Dec 2017 12:17:52 +0100 -+Subject: [PATCH] netfilter: nf_tables: no need for struct nft_af_info to -+ enable/disable table -+ -+nf_tables_table_enable() and nf_tables_table_disable() take a pointer to -+struct nft_af_info that is never used, remove it. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -655,10 +655,7 @@ err: -+ return err; -+ } -+ -+-static void _nf_tables_table_disable(struct net *net, -+- const struct nft_af_info *afi, -+- struct nft_table *table, -+- u32 cnt) -++static void nft_table_disable(struct net *net, struct nft_table *table, u32 cnt) -+ { -+ struct nft_chain *chain; -+ u32 i = 0; -+@@ -676,9 +673,7 @@ static void _nf_tables_table_disable(str -+ } -+ } -+ -+-static int nf_tables_table_enable(struct net *net, -+- const struct nft_af_info *afi, -+- struct nft_table *table) -++static int nf_tables_table_enable(struct net *net, struct nft_table *table) -+ { -+ struct nft_chain *chain; -+ int err, i = 0; -+@@ -698,15 +693,13 @@ static int nf_tables_table_enable(struct -+ return 0; -+ err: -+ if (i) -+- _nf_tables_table_disable(net, afi, table, i); -++ nft_table_disable(net, table, i); -+ return err; -+ } -+ -+-static void nf_tables_table_disable(struct net *net, -+- const struct nft_af_info *afi, -+- struct nft_table *table) -++static void nf_tables_table_disable(struct net *net, struct nft_table *table) -+ { -+- _nf_tables_table_disable(net, afi, table, 0); -++ nft_table_disable(net, table, 0); -+ } -+ -+ static int nf_tables_updtable(struct nft_ctx *ctx) -+@@ -735,7 +728,7 @@ static int nf_tables_updtable(struct nft -+ nft_trans_table_enable(trans) = false; -+ } else if (!(flags & NFT_TABLE_F_DORMANT) && -+ ctx->table->flags & NFT_TABLE_F_DORMANT) { -+- ret = nf_tables_table_enable(ctx->net, ctx->afi, ctx->table); -++ ret = nf_tables_table_enable(ctx->net, ctx->table); -+ if (ret >= 0) { -+ ctx->table->flags &= ~NFT_TABLE_F_DORMANT; -+ nft_trans_table_enable(trans) = true; -+@@ -5819,7 +5812,6 @@ static int nf_tables_commit(struct net * -+ if (nft_trans_table_update(trans)) { -+ if (!nft_trans_table_enable(trans)) { -+ nf_tables_table_disable(net, -+- trans->ctx.afi, -+ trans->ctx.table); -+ trans->ctx.table->flags |= NFT_TABLE_F_DORMANT; -+ } -+@@ -5983,7 +5975,6 @@ static int nf_tables_abort(struct net *n -+ if (nft_trans_table_update(trans)) { -+ if (nft_trans_table_enable(trans)) { -+ nf_tables_table_disable(net, -+- trans->ctx.afi, -+ trans->ctx.table); -+ trans->ctx.table->flags |= NFT_TABLE_F_DORMANT; -+ } -diff --git a/target/linux/generic/backport-4.14/332-v4.16-netfilter-nf_tables-remove-struct-nft_af_info-parame.patch b/target/linux/generic/backport-4.14/332-v4.16-netfilter-nf_tables-remove-struct-nft_af_info-parame.patch -new file mode 100644 -index 0000000000..0ce65dc141 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/332-v4.16-netfilter-nf_tables-remove-struct-nft_af_info-parame.patch -@@ -0,0 +1,60 @@ -+From: Pablo Neira Ayuso -+Date: Tue, 19 Dec 2017 13:40:22 +0100 -+Subject: [PATCH] netfilter: nf_tables: remove struct nft_af_info parameter in -+ nf_tables_chain_type_lookup() -+ -+Pass family number instead, this comes in preparation for the removal of -+struct nft_af_info. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -467,7 +467,7 @@ static inline u64 nf_tables_alloc_handle -+ static const struct nf_chain_type *chain_type[NFPROTO_NUMPROTO][NFT_CHAIN_T_MAX]; -+ -+ static const struct nf_chain_type * -+-__nf_tables_chain_type_lookup(int family, const struct nlattr *nla) -++__nf_tables_chain_type_lookup(const struct nlattr *nla, u8 family) -+ { -+ int i; -+ -+@@ -480,22 +480,20 @@ __nf_tables_chain_type_lookup(int family -+ } -+ -+ static const struct nf_chain_type * -+-nf_tables_chain_type_lookup(const struct nft_af_info *afi, -+- const struct nlattr *nla, -+- bool autoload) -++nf_tables_chain_type_lookup(const struct nlattr *nla, u8 family, bool autoload) -+ { -+ const struct nf_chain_type *type; -+ -+- type = __nf_tables_chain_type_lookup(afi->family, nla); -++ type = __nf_tables_chain_type_lookup(nla, family); -+ if (type != NULL) -+ return type; -+ #ifdef CONFIG_MODULES -+ if (autoload) { -+ nfnl_unlock(NFNL_SUBSYS_NFTABLES); -+- request_module("nft-chain-%u-%.*s", afi->family, -++ request_module("nft-chain-%u-%.*s", family, -+ nla_len(nla), (const char *)nla_data(nla)); -+ nfnl_lock(NFNL_SUBSYS_NFTABLES); -+- type = __nf_tables_chain_type_lookup(afi->family, nla); -++ type = __nf_tables_chain_type_lookup(nla, family); -+ if (type != NULL) -+ return ERR_PTR(-EAGAIN); -+ } -+@@ -1371,8 +1369,8 @@ static int nft_chain_parse_hook(struct n -+ -+ type = chain_type[afi->family][NFT_CHAIN_T_DEFAULT]; -+ if (nla[NFTA_CHAIN_TYPE]) { -+- type = nf_tables_chain_type_lookup(afi, nla[NFTA_CHAIN_TYPE], -+- create); -++ type = nf_tables_chain_type_lookup(nla[NFTA_CHAIN_TYPE], -++ afi->family, create); -+ if (IS_ERR(type)) -+ return PTR_ERR(type); -+ } -diff --git a/target/linux/generic/backport-4.14/334-v4.15-netfilter-nf_tables-fix-potential-NULL-ptr-deref-in-.patch b/target/linux/generic/backport-4.14/334-v4.15-netfilter-nf_tables-fix-potential-NULL-ptr-deref-in-.patch -new file mode 100644 -index 0000000000..f6e1ef0823 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/334-v4.15-netfilter-nf_tables-fix-potential-NULL-ptr-deref-in-.patch -@@ -0,0 +1,30 @@ -+From: Hangbin Liu -+Date: Mon, 25 Dec 2017 11:34:54 +0800 -+Subject: [PATCH] netfilter: nf_tables: fix potential NULL-ptr deref in -+ nf_tables_dump_obj_done() -+ -+If there is no NFTA_OBJ_TABLE and NFTA_OBJ_TYPE, the c.data will be NULL in -+nf_tables_getobj(). So before free filter->table in nf_tables_dump_obj_done(), -+we need to check if filter is NULL first. -+ -+Fixes: e46abbcc05aa ("netfilter: nf_tables: Allow table names of up to 255 chars") -+Signed-off-by: Hangbin Liu -+Acked-by: Phil Sutter -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -5357,8 +5357,10 @@ static int nf_tables_dump_flowtable_done -+ if (!filter) -+ return 0; -+ -+- kfree(filter->table); -+- kfree(filter); -++ if (filter) { -++ kfree(filter->table); -++ kfree(filter); -++ } -+ -+ return 0; -+ } -diff --git a/target/linux/generic/backport-4.14/335-v4.16-netfilter-nf_tables-add-single-table-list-for-all-fa.patch b/target/linux/generic/backport-4.14/335-v4.16-netfilter-nf_tables-add-single-table-list-for-all-fa.patch -new file mode 100644 -index 0000000000..340d7167ea ---- /dev/null -+++ b/target/linux/generic/backport-4.14/335-v4.16-netfilter-nf_tables-add-single-table-list-for-all-fa.patch -@@ -0,0 +1,1450 @@ -+From: Pablo Neira Ayuso -+Date: Tue, 9 Jan 2018 02:38:03 +0100 -+Subject: [PATCH] netfilter: nf_tables: add single table list for all families -+ -+Place all existing user defined tables in struct net *, instead of -+having one list per family. This saves us from one level of indentation -+in netlink dump functions. -+ -+Place pointer to struct nft_af_info in struct nft_table temporarily, as -+we still need this to put back reference module reference counter on -+table removal. -+ -+This patch comes in preparation for the removal of struct nft_af_info. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/net/netfilter/nf_tables.h -++++ b/include/net/netfilter/nf_tables.h -+@@ -143,22 +143,22 @@ static inline void nft_data_debug(const -+ * struct nft_ctx - nf_tables rule/set context -+ * -+ * @net: net namespace -+- * @afi: address family info -+ * @table: the table the chain is contained in -+ * @chain: the chain the rule is contained in -+ * @nla: netlink attributes -+ * @portid: netlink portID of the original message -+ * @seq: netlink sequence number -++ * @family: protocol family -+ * @report: notify via unicast netlink message -+ */ -+ struct nft_ctx { -+ struct net *net; -+- struct nft_af_info *afi; -+ struct nft_table *table; -+ struct nft_chain *chain; -+ const struct nlattr * const *nla; -+ u32 portid; -+ u32 seq; -++ u8 family; -+ bool report; -+ }; -+ -+@@ -945,6 +945,7 @@ unsigned int nft_do_chain(struct nft_pkt -+ * @use: number of chain references to this table -+ * @flags: table flag (see enum nft_table_flags) -+ * @genmask: generation mask -++ * @afinfo: address family info -+ * @name: name of the table -+ */ -+ struct nft_table { -+@@ -957,6 +958,7 @@ struct nft_table { -+ u32 use; -+ u16 flags:14, -+ genmask:2; -++ struct nft_af_info *afi; -+ char *name; -+ }; -+ -+@@ -966,13 +968,11 @@ struct nft_table { -+ * @list: used internally -+ * @family: address family -+ * @owner: module owner -+- * @tables: used internally -+ */ -+ struct nft_af_info { -+ struct list_head list; -+ int family; -+ struct module *owner; -+- struct list_head tables; -+ }; -+ -+ int nft_register_afinfo(struct net *, struct nft_af_info *); -+--- a/include/net/netns/nftables.h -++++ b/include/net/netns/nftables.h -+@@ -8,6 +8,7 @@ struct nft_af_info; -+ -+ struct netns_nftables { -+ struct list_head af_info; -++ struct list_head tables; -+ struct list_head commit_list; -+ struct nft_af_info *ipv4; -+ struct nft_af_info *ipv6; -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -37,7 +37,6 @@ static LIST_HEAD(nf_tables_flowtables); -+ */ -+ int nft_register_afinfo(struct net *net, struct nft_af_info *afi) -+ { -+- INIT_LIST_HEAD(&afi->tables); -+ nfnl_lock(NFNL_SUBSYS_NFTABLES); -+ list_add_tail_rcu(&afi->list, &net->nft.af_info); -+ nfnl_unlock(NFNL_SUBSYS_NFTABLES); -+@@ -99,13 +98,13 @@ static void nft_ctx_init(struct nft_ctx -+ struct net *net, -+ const struct sk_buff *skb, -+ const struct nlmsghdr *nlh, -+- struct nft_af_info *afi, -++ u8 family, -+ struct nft_table *table, -+ struct nft_chain *chain, -+ const struct nlattr * const *nla) -+ { -+ ctx->net = net; -+- ctx->afi = afi; -++ ctx->family = family; -+ ctx->table = table; -+ ctx->chain = chain; -+ ctx->nla = nla; -+@@ -429,30 +428,31 @@ static int nft_delflowtable(struct nft_c -+ * Tables -+ */ -+ -+-static struct nft_table *nft_table_lookup(const struct nft_af_info *afi, -++static struct nft_table *nft_table_lookup(const struct net *net, -+ const struct nlattr *nla, -+- u8 genmask) -++ u8 family, u8 genmask) -+ { -+ struct nft_table *table; -+ -+- list_for_each_entry(table, &afi->tables, list) { -++ list_for_each_entry(table, &net->nft.tables, list) { -+ if (!nla_strcmp(nla, table->name) && -++ table->afi->family == family && -+ nft_active_genmask(table, genmask)) -+ return table; -+ } -+ return NULL; -+ } -+ -+-static struct nft_table *nf_tables_table_lookup(const struct nft_af_info *afi, -++static struct nft_table *nf_tables_table_lookup(const struct net *net, -+ const struct nlattr *nla, -+- u8 genmask) -++ u8 family, u8 genmask) -+ { -+ struct nft_table *table; -+ -+ if (nla == NULL) -+ return ERR_PTR(-EINVAL); -+ -+- table = nft_table_lookup(afi, nla, genmask); -++ table = nft_table_lookup(net, nla, family, genmask); -+ if (table != NULL) -+ return table; -+ -+@@ -551,7 +551,7 @@ static void nf_tables_table_notify(const -+ goto err; -+ -+ err = nf_tables_fill_table_info(skb, ctx->net, ctx->portid, ctx->seq, -+- event, 0, ctx->afi->family, ctx->table); -++ event, 0, ctx->family, ctx->table); -+ if (err < 0) { -+ kfree_skb(skb); -+ goto err; -+@@ -568,7 +568,6 @@ static int nf_tables_dump_tables(struct -+ struct netlink_callback *cb) -+ { -+ const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh); -+- const struct nft_af_info *afi; -+ const struct nft_table *table; -+ unsigned int idx = 0, s_idx = cb->args[0]; -+ struct net *net = sock_net(skb->sk); -+@@ -577,30 +576,27 @@ static int nf_tables_dump_tables(struct -+ rcu_read_lock(); -+ cb->seq = net->nft.base_seq; -+ -+- list_for_each_entry_rcu(afi, &net->nft.af_info, list) { -+- if (family != NFPROTO_UNSPEC && family != afi->family) -++ list_for_each_entry_rcu(table, &net->nft.tables, list) { -++ if (family != NFPROTO_UNSPEC && family != table->afi->family) -+ continue; -+ -+- list_for_each_entry_rcu(table, &afi->tables, list) { -+- if (idx < s_idx) -+- goto cont; -+- if (idx > s_idx) -+- memset(&cb->args[1], 0, -+- sizeof(cb->args) - sizeof(cb->args[0])); -+- if (!nft_is_active(net, table)) -+- continue; -+- if (nf_tables_fill_table_info(skb, net, -+- NETLINK_CB(cb->skb).portid, -+- cb->nlh->nlmsg_seq, -+- NFT_MSG_NEWTABLE, -+- NLM_F_MULTI, -+- afi->family, table) < 0) -+- goto done; -++ if (idx < s_idx) -++ goto cont; -++ if (idx > s_idx) -++ memset(&cb->args[1], 0, -++ sizeof(cb->args) - sizeof(cb->args[0])); -++ if (!nft_is_active(net, table)) -++ continue; -++ if (nf_tables_fill_table_info(skb, net, -++ NETLINK_CB(cb->skb).portid, -++ cb->nlh->nlmsg_seq, -++ NFT_MSG_NEWTABLE, NLM_F_MULTI, -++ table->afi->family, table) < 0) -++ goto done; -+ -+- nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -++ nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -+ cont: -+- idx++; -+- } -++ idx++; -+ } -+ done: -+ rcu_read_unlock(); -+@@ -632,7 +628,8 @@ static int nf_tables_gettable(struct net -+ if (IS_ERR(afi)) -+ return PTR_ERR(afi); -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME], genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], afi->family, -++ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -763,7 +760,7 @@ static int nf_tables_newtable(struct net -+ return PTR_ERR(afi); -+ -+ name = nla[NFTA_TABLE_NAME]; -+- table = nf_tables_table_lookup(afi, name, genmask); -++ table = nf_tables_table_lookup(net, name, afi->family, genmask); -+ if (IS_ERR(table)) { -+ if (PTR_ERR(table) != -ENOENT) -+ return PTR_ERR(table); -+@@ -773,7 +770,7 @@ static int nf_tables_newtable(struct net -+ if (nlh->nlmsg_flags & NLM_F_REPLACE) -+ return -EOPNOTSUPP; -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); -+ return nf_tables_updtable(&ctx); -+ } -+ -+@@ -800,14 +797,15 @@ static int nf_tables_newtable(struct net -+ INIT_LIST_HEAD(&table->sets); -+ INIT_LIST_HEAD(&table->objects); -+ INIT_LIST_HEAD(&table->flowtables); -++ table->afi = afi; -+ table->flags = flags; -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); -+ err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE); -+ if (err < 0) -+ goto err4; -+ -+- list_add_tail_rcu(&table->list, &afi->tables); -++ list_add_tail_rcu(&table->list, &net->nft.tables); -+ return 0; -+ err4: -+ kfree(table->name); -+@@ -881,30 +879,28 @@ out: -+ -+ static int nft_flush(struct nft_ctx *ctx, int family) -+ { -+- struct nft_af_info *afi; -+ struct nft_table *table, *nt; -+ const struct nlattr * const *nla = ctx->nla; -+ int err = 0; -+ -+- list_for_each_entry(afi, &ctx->net->nft.af_info, list) { -+- if (family != AF_UNSPEC && afi->family != family) -++ list_for_each_entry_safe(table, nt, &ctx->net->nft.tables, list) { -++ if (family != AF_UNSPEC && table->afi->family != family) -+ continue; -+ -+- ctx->afi = afi; -+- list_for_each_entry_safe(table, nt, &afi->tables, list) { -+- if (!nft_is_active_next(ctx->net, table)) -+- continue; -++ ctx->family = table->afi->family; -+ -+- if (nla[NFTA_TABLE_NAME] && -+- nla_strcmp(nla[NFTA_TABLE_NAME], table->name) != 0) -+- continue; -++ if (!nft_is_active_next(ctx->net, table)) -++ continue; -+ -+- ctx->table = table; -++ if (nla[NFTA_TABLE_NAME] && -++ nla_strcmp(nla[NFTA_TABLE_NAME], table->name) != 0) -++ continue; -+ -+- err = nft_flush_table(ctx); -+- if (err < 0) -+- goto out; -+- } -++ ctx->table = table; -++ -++ err = nft_flush_table(ctx); -++ if (err < 0) -++ goto out; -+ } -+ out: -+ return err; -+@@ -922,7 +918,7 @@ static int nf_tables_deltable(struct net -+ int family = nfmsg->nfgen_family; -+ struct nft_ctx ctx; -+ -+- nft_ctx_init(&ctx, net, skb, nlh, NULL, NULL, NULL, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, 0, NULL, NULL, nla); -+ if (family == AF_UNSPEC || nla[NFTA_TABLE_NAME] == NULL) -+ return nft_flush(&ctx, family); -+ -+@@ -930,7 +926,8 @@ static int nf_tables_deltable(struct net -+ if (IS_ERR(afi)) -+ return PTR_ERR(afi); -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME], genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], afi->family, -++ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -938,7 +935,7 @@ static int nf_tables_deltable(struct net -+ table->use > 0) -+ return -EBUSY; -+ -+- ctx.afi = afi; -++ ctx.family = afi->family; -+ ctx.table = table; -+ -+ return nft_flush_table(&ctx); -+@@ -950,7 +947,7 @@ static void nf_tables_table_destroy(stru -+ -+ kfree(ctx->table->name); -+ kfree(ctx->table); -+- module_put(ctx->afi->owner); -++ module_put(ctx->table->afi->owner); -+ } -+ -+ int nft_register_chain_type(const struct nf_chain_type *ctype) -+@@ -1151,7 +1148,7 @@ static void nf_tables_chain_notify(const -+ goto err; -+ -+ err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq, -+- event, 0, ctx->afi->family, ctx->table, -++ event, 0, ctx->family, ctx->table, -+ ctx->chain); -+ if (err < 0) { -+ kfree_skb(skb); -+@@ -1169,7 +1166,6 @@ static int nf_tables_dump_chains(struct -+ struct netlink_callback *cb) -+ { -+ const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh); -+- const struct nft_af_info *afi; -+ const struct nft_table *table; -+ const struct nft_chain *chain; -+ unsigned int idx = 0, s_idx = cb->args[0]; -+@@ -1179,31 +1175,30 @@ static int nf_tables_dump_chains(struct -+ rcu_read_lock(); -+ cb->seq = net->nft.base_seq; -+ -+- list_for_each_entry_rcu(afi, &net->nft.af_info, list) { -+- if (family != NFPROTO_UNSPEC && family != afi->family) -++ list_for_each_entry_rcu(table, &net->nft.tables, list) { -++ if (family != NFPROTO_UNSPEC && family != table->afi->family) -+ continue; -+ -+- list_for_each_entry_rcu(table, &afi->tables, list) { -+- list_for_each_entry_rcu(chain, &table->chains, list) { -+- if (idx < s_idx) -+- goto cont; -+- if (idx > s_idx) -+- memset(&cb->args[1], 0, -+- sizeof(cb->args) - sizeof(cb->args[0])); -+- if (!nft_is_active(net, chain)) -+- continue; -+- if (nf_tables_fill_chain_info(skb, net, -+- NETLINK_CB(cb->skb).portid, -+- cb->nlh->nlmsg_seq, -+- NFT_MSG_NEWCHAIN, -+- NLM_F_MULTI, -+- afi->family, table, chain) < 0) -+- goto done; -++ list_for_each_entry_rcu(chain, &table->chains, list) { -++ if (idx < s_idx) -++ goto cont; -++ if (idx > s_idx) -++ memset(&cb->args[1], 0, -++ sizeof(cb->args) - sizeof(cb->args[0])); -++ if (!nft_is_active(net, chain)) -++ continue; -++ if (nf_tables_fill_chain_info(skb, net, -++ NETLINK_CB(cb->skb).portid, -++ cb->nlh->nlmsg_seq, -++ NFT_MSG_NEWCHAIN, -++ NLM_F_MULTI, -++ table->afi->family, table, -++ chain) < 0) -++ goto done; -+ -+- nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -++ nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -+ cont: -+- idx++; -+- } -++ idx++; -+ } -+ } -+ done: -+@@ -1237,7 +1232,8 @@ static int nf_tables_getchain(struct net -+ if (IS_ERR(afi)) -+ return PTR_ERR(afi); -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], afi->family, -++ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -1347,8 +1343,8 @@ struct nft_chain_hook { -+ -+ static int nft_chain_parse_hook(struct net *net, -+ const struct nlattr * const nla[], -+- struct nft_af_info *afi, -+- struct nft_chain_hook *hook, bool create) -++ struct nft_chain_hook *hook, u8 family, -++ bool create) -+ { -+ struct nlattr *ha[NFTA_HOOK_MAX + 1]; -+ const struct nf_chain_type *type; -+@@ -1367,10 +1363,10 @@ static int nft_chain_parse_hook(struct n -+ hook->num = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM])); -+ hook->priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY])); -+ -+- type = chain_type[afi->family][NFT_CHAIN_T_DEFAULT]; -++ type = chain_type[family][NFT_CHAIN_T_DEFAULT]; -+ if (nla[NFTA_CHAIN_TYPE]) { -+ type = nf_tables_chain_type_lookup(nla[NFTA_CHAIN_TYPE], -+- afi->family, create); -++ family, create); -+ if (IS_ERR(type)) -+ return PTR_ERR(type); -+ } -+@@ -1382,7 +1378,7 @@ static int nft_chain_parse_hook(struct n -+ hook->type = type; -+ -+ hook->dev = NULL; -+- if (afi->family == NFPROTO_NETDEV) { -++ if (family == NFPROTO_NETDEV) { -+ char ifname[IFNAMSIZ]; -+ -+ if (!ha[NFTA_HOOK_DEV]) { -+@@ -1417,7 +1413,6 @@ static int nf_tables_addchain(struct nft -+ { -+ const struct nlattr * const *nla = ctx->nla; -+ struct nft_table *table = ctx->table; -+- struct nft_af_info *afi = ctx->afi; -+ struct nft_base_chain *basechain; -+ struct nft_stats __percpu *stats; -+ struct net *net = ctx->net; -+@@ -1431,7 +1426,7 @@ static int nf_tables_addchain(struct nft -+ struct nft_chain_hook hook; -+ struct nf_hook_ops *ops; -+ -+- err = nft_chain_parse_hook(net, nla, afi, &hook, create); -++ err = nft_chain_parse_hook(net, nla, &hook, family, create); -+ if (err < 0) -+ return err; -+ -+@@ -1523,7 +1518,7 @@ static int nf_tables_updchain(struct nft -+ if (!nft_is_base_chain(chain)) -+ return -EBUSY; -+ -+- err = nft_chain_parse_hook(ctx->net, nla, ctx->afi, &hook, -++ err = nft_chain_parse_hook(ctx->net, nla, &hook, ctx->family, -+ create); -+ if (err < 0) -+ return err; -+@@ -1633,7 +1628,8 @@ static int nf_tables_newchain(struct net -+ if (IS_ERR(afi)) -+ return PTR_ERR(afi); -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], afi->family, -++ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -1673,7 +1669,7 @@ static int nf_tables_newchain(struct net -+ } -+ } -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, chain, nla); -+ -+ if (chain != NULL) { -+ if (nlh->nlmsg_flags & NLM_F_EXCL) -+@@ -1707,7 +1703,8 @@ static int nf_tables_delchain(struct net -+ if (IS_ERR(afi)) -+ return PTR_ERR(afi); -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], afi->family, -++ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -1719,7 +1716,7 @@ static int nf_tables_delchain(struct net -+ chain->use > 0) -+ return -EBUSY; -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, chain, nla); -+ -+ use = chain->use; -+ list_for_each_entry(rule, &chain->rules, list) { -+@@ -1887,7 +1884,7 @@ static int nf_tables_expr_parse(const st -+ if (err < 0) -+ return err; -+ -+- type = nft_expr_type_get(ctx->afi->family, tb[NFTA_EXPR_NAME]); -++ type = nft_expr_type_get(ctx->family, tb[NFTA_EXPR_NAME]); -+ if (IS_ERR(type)) -+ return PTR_ERR(type); -+ -+@@ -2115,7 +2112,7 @@ static void nf_tables_rule_notify(const -+ goto err; -+ -+ err = nf_tables_fill_rule_info(skb, ctx->net, ctx->portid, ctx->seq, -+- event, 0, ctx->afi->family, ctx->table, -++ event, 0, ctx->family, ctx->table, -+ ctx->chain, rule); -+ if (err < 0) { -+ kfree_skb(skb); -+@@ -2139,7 +2136,6 @@ static int nf_tables_dump_rules(struct s -+ { -+ const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh); -+ const struct nft_rule_dump_ctx *ctx = cb->data; -+- const struct nft_af_info *afi; -+ const struct nft_table *table; -+ const struct nft_chain *chain; -+ const struct nft_rule *rule; -+@@ -2150,39 +2146,37 @@ static int nf_tables_dump_rules(struct s -+ rcu_read_lock(); -+ cb->seq = net->nft.base_seq; -+ -+- list_for_each_entry_rcu(afi, &net->nft.af_info, list) { -+- if (family != NFPROTO_UNSPEC && family != afi->family) -++ list_for_each_entry_rcu(table, &net->nft.tables, list) { -++ if (family != NFPROTO_UNSPEC && family != table->afi->family) -++ continue; -++ -++ if (ctx && ctx->table && strcmp(ctx->table, table->name) != 0) -+ continue; -+ -+- list_for_each_entry_rcu(table, &afi->tables, list) { -+- if (ctx && ctx->table && -+- strcmp(ctx->table, table->name) != 0) -++ list_for_each_entry_rcu(chain, &table->chains, list) { -++ if (ctx && ctx->chain && -++ strcmp(ctx->chain, chain->name) != 0) -+ continue; -+ -+- list_for_each_entry_rcu(chain, &table->chains, list) { -+- if (ctx && ctx->chain && -+- strcmp(ctx->chain, chain->name) != 0) -+- continue; -+- -+- list_for_each_entry_rcu(rule, &chain->rules, list) { -+- if (!nft_is_active(net, rule)) -+- goto cont; -+- if (idx < s_idx) -+- goto cont; -+- if (idx > s_idx) -+- memset(&cb->args[1], 0, -+- sizeof(cb->args) - sizeof(cb->args[0])); -+- if (nf_tables_fill_rule_info(skb, net, NETLINK_CB(cb->skb).portid, -+- cb->nlh->nlmsg_seq, -+- NFT_MSG_NEWRULE, -+- NLM_F_MULTI | NLM_F_APPEND, -+- afi->family, table, chain, rule) < 0) -+- goto done; -++ list_for_each_entry_rcu(rule, &chain->rules, list) { -++ if (!nft_is_active(net, rule)) -++ goto cont; -++ if (idx < s_idx) -++ goto cont; -++ if (idx > s_idx) -++ memset(&cb->args[1], 0, -++ sizeof(cb->args) - sizeof(cb->args[0])); -++ if (nf_tables_fill_rule_info(skb, net, NETLINK_CB(cb->skb).portid, -++ cb->nlh->nlmsg_seq, -++ NFT_MSG_NEWRULE, -++ NLM_F_MULTI | NLM_F_APPEND, -++ table->afi->family, -++ table, chain, rule) < 0) -++ goto done; -+ -+- nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -++ nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -+ cont: -+- idx++; -+- } -++ idx++; -+ } -+ } -+ } -+@@ -2260,7 +2254,8 @@ static int nf_tables_getrule(struct net -+ if (IS_ERR(afi)) -+ return PTR_ERR(afi); -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], afi->family, -++ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -2345,7 +2340,8 @@ static int nf_tables_newrule(struct net -+ if (IS_ERR(afi)) -+ return PTR_ERR(afi); -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], afi->family, -++ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -2384,7 +2380,7 @@ static int nf_tables_newrule(struct net -+ return PTR_ERR(old_rule); -+ } -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, chain, nla); -+ -+ n = 0; -+ size = 0; -+@@ -2517,7 +2513,8 @@ static int nf_tables_delrule(struct net -+ if (IS_ERR(afi)) -+ return PTR_ERR(afi); -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], afi->family, -++ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -2528,7 +2525,7 @@ static int nf_tables_delrule(struct net -+ return PTR_ERR(chain); -+ } -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, chain, nla); -+ -+ if (chain) { -+ if (nla[NFTA_RULE_HANDLE]) { -+@@ -2726,13 +2723,13 @@ static int nft_ctx_init_from_setattr(str -+ if (afi == NULL) -+ return -EAFNOSUPPORT; -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE], -+- genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_SET_TABLE], -++ afi->family, genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ } -+ -+- nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla); -++ nft_ctx_init(ctx, net, skb, nlh, afi->family, table, NULL, nla); -+ return 0; -+ } -+ -+@@ -2860,7 +2857,7 @@ static int nf_tables_fill_set(struct sk_ -+ goto nla_put_failure; -+ -+ nfmsg = nlmsg_data(nlh); -+- nfmsg->nfgen_family = ctx->afi->family; -++ nfmsg->nfgen_family = ctx->family; -+ nfmsg->version = NFNETLINK_V0; -+ nfmsg->res_id = htons(ctx->net->nft.base_seq & 0xffff); -+ -+@@ -2952,10 +2949,8 @@ static int nf_tables_dump_sets(struct sk -+ { -+ const struct nft_set *set; -+ unsigned int idx, s_idx = cb->args[0]; -+- struct nft_af_info *afi; -+ struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2]; -+ struct net *net = sock_net(skb->sk); -+- int cur_family = cb->args[3]; -+ struct nft_ctx *ctx = cb->data, ctx_set; -+ -+ if (cb->args[1]) -+@@ -2964,51 +2959,44 @@ static int nf_tables_dump_sets(struct sk -+ rcu_read_lock(); -+ cb->seq = net->nft.base_seq; -+ -+- list_for_each_entry_rcu(afi, &net->nft.af_info, list) { -+- if (ctx->afi && ctx->afi != afi) -++ list_for_each_entry_rcu(table, &net->nft.tables, list) { -++ if (ctx->family != NFPROTO_UNSPEC && -++ ctx->family != table->afi->family) -+ continue; -+ -+- if (cur_family) { -+- if (afi->family != cur_family) -+- continue; -++ if (ctx->table && ctx->table != table) -++ continue; -+ -+- cur_family = 0; -+- } -+- list_for_each_entry_rcu(table, &afi->tables, list) { -+- if (ctx->table && ctx->table != table) -++ if (cur_table) { -++ if (cur_table != table) -+ continue; -+ -+- if (cur_table) { -+- if (cur_table != table) -+- continue; -++ cur_table = NULL; -++ } -++ idx = 0; -++ list_for_each_entry_rcu(set, &table->sets, list) { -++ if (idx < s_idx) -++ goto cont; -++ if (!nft_is_active(net, set)) -++ goto cont; -+ -+- cur_table = NULL; -++ ctx_set = *ctx; -++ ctx_set.table = table; -++ ctx_set.family = table->afi->family; -++ -++ if (nf_tables_fill_set(skb, &ctx_set, set, -++ NFT_MSG_NEWSET, -++ NLM_F_MULTI) < 0) { -++ cb->args[0] = idx; -++ cb->args[2] = (unsigned long) table; -++ goto done; -+ } -+- idx = 0; -+- list_for_each_entry_rcu(set, &table->sets, list) { -+- if (idx < s_idx) -+- goto cont; -+- if (!nft_is_active(net, set)) -+- goto cont; -+- -+- ctx_set = *ctx; -+- ctx_set.table = table; -+- ctx_set.afi = afi; -+- if (nf_tables_fill_set(skb, &ctx_set, set, -+- NFT_MSG_NEWSET, -+- NLM_F_MULTI) < 0) { -+- cb->args[0] = idx; -+- cb->args[2] = (unsigned long) table; -+- cb->args[3] = afi->family; -+- goto done; -+- } -+- nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -++ nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -+ cont: -+- idx++; -+- } -+- if (s_idx) -+- s_idx = 0; -++ idx++; -+ } -++ if (s_idx) -++ s_idx = 0; -+ } -+ cb->args[1] = 1; -+ done: -+@@ -3221,11 +3209,12 @@ static int nf_tables_newset(struct net * -+ if (IS_ERR(afi)) -+ return PTR_ERR(afi); -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE], genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_SET_TABLE], afi->family, -++ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); -+ -+ set = nf_tables_set_lookup(table, nla[NFTA_SET_NAME], genmask); -+ if (IS_ERR(set)) { -+@@ -3494,12 +3483,12 @@ static int nft_ctx_init_from_elemattr(st -+ if (IS_ERR(afi)) -+ return PTR_ERR(afi); -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_SET_ELEM_LIST_TABLE], -+- genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_SET_ELEM_LIST_TABLE], -++ afi->family, genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+- nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla); -++ nft_ctx_init(ctx, net, skb, nlh, afi->family, table, NULL, nla); -+ return 0; -+ } -+ -+@@ -3604,7 +3593,6 @@ static int nf_tables_dump_set(struct sk_ -+ { -+ struct nft_set_dump_ctx *dump_ctx = cb->data; -+ struct net *net = sock_net(skb->sk); -+- struct nft_af_info *afi; -+ struct nft_table *table; -+ struct nft_set *set; -+ struct nft_set_dump_args args; -+@@ -3616,21 +3604,19 @@ static int nf_tables_dump_set(struct sk_ -+ int event; -+ -+ rcu_read_lock(); -+- list_for_each_entry_rcu(afi, &net->nft.af_info, list) { -+- if (afi != dump_ctx->ctx.afi) -++ list_for_each_entry_rcu(table, &net->nft.tables, list) { -++ if (dump_ctx->ctx.family != NFPROTO_UNSPEC && -++ dump_ctx->ctx.family != table->afi->family) -+ continue; -+ -+- list_for_each_entry_rcu(table, &afi->tables, list) { -+- if (table != dump_ctx->ctx.table) -+- continue; -++ if (table != dump_ctx->ctx.table) -++ continue; -+ -+- list_for_each_entry_rcu(set, &table->sets, list) { -+- if (set == dump_ctx->set) { -+- set_found = true; -+- break; -+- } -++ list_for_each_entry_rcu(set, &table->sets, list) { -++ if (set == dump_ctx->set) { -++ set_found = true; -++ break; -+ } -+- break; -+ } -+ break; -+ } -+@@ -3650,7 +3636,7 @@ static int nf_tables_dump_set(struct sk_ -+ goto nla_put_failure; -+ -+ nfmsg = nlmsg_data(nlh); -+- nfmsg->nfgen_family = afi->family; -++ nfmsg->nfgen_family = table->afi->family; -+ nfmsg->version = NFNETLINK_V0; -+ nfmsg->res_id = htons(net->nft.base_seq & 0xffff); -+ -+@@ -3752,7 +3738,7 @@ static int nf_tables_fill_setelem_info(s -+ goto nla_put_failure; -+ -+ nfmsg = nlmsg_data(nlh); -+- nfmsg->nfgen_family = ctx->afi->family; -++ nfmsg->nfgen_family = ctx->family; -+ nfmsg->version = NFNETLINK_V0; -+ nfmsg->res_id = htons(ctx->net->nft.base_seq & 0xffff); -+ -+@@ -4002,7 +3988,7 @@ static int nft_add_set_elem(struct nft_c -+ list_for_each_entry(binding, &set->bindings, list) { -+ struct nft_ctx bind_ctx = { -+ .net = ctx->net, -+- .afi = ctx->afi, -++ .family = ctx->family, -+ .table = ctx->table, -+ .chain = (struct nft_chain *)binding->chain, -+ }; -+@@ -4554,7 +4540,8 @@ static int nf_tables_newobj(struct net * -+ if (IS_ERR(afi)) -+ return PTR_ERR(afi); -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], afi->family, -++ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -4572,7 +4559,7 @@ static int nf_tables_newobj(struct net * -+ return 0; -+ } -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); -+ -+ type = nft_obj_type_get(objtype); -+ if (IS_ERR(type)) -+@@ -4649,7 +4636,6 @@ struct nft_obj_filter { -+ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb) -+ { -+ const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh); -+- const struct nft_af_info *afi; -+ const struct nft_table *table; -+ unsigned int idx = 0, s_idx = cb->args[0]; -+ struct nft_obj_filter *filter = cb->data; -+@@ -4664,38 +4650,37 @@ static int nf_tables_dump_obj(struct sk_ -+ rcu_read_lock(); -+ cb->seq = net->nft.base_seq; -+ -+- list_for_each_entry_rcu(afi, &net->nft.af_info, list) { -+- if (family != NFPROTO_UNSPEC && family != afi->family) -++ list_for_each_entry_rcu(table, &net->nft.tables, list) { -++ if (family != NFPROTO_UNSPEC && family != table->afi->family) -+ continue; -+ -+- list_for_each_entry_rcu(table, &afi->tables, list) { -+- list_for_each_entry_rcu(obj, &table->objects, list) { -+- if (!nft_is_active(net, obj)) -+- goto cont; -+- if (idx < s_idx) -+- goto cont; -+- if (idx > s_idx) -+- memset(&cb->args[1], 0, -+- sizeof(cb->args) - sizeof(cb->args[0])); -+- if (filter && filter->table && -+- strcmp(filter->table, table->name)) -+- goto cont; -+- if (filter && -+- filter->type != NFT_OBJECT_UNSPEC && -+- obj->ops->type->type != filter->type) -+- goto cont; -++ list_for_each_entry_rcu(obj, &table->objects, list) { -++ if (!nft_is_active(net, obj)) -++ goto cont; -++ if (idx < s_idx) -++ goto cont; -++ if (idx > s_idx) -++ memset(&cb->args[1], 0, -++ sizeof(cb->args) - sizeof(cb->args[0])); -++ if (filter && filter->table && -++ strcmp(filter->table, table->name)) -++ goto cont; -++ if (filter && -++ filter->type != NFT_OBJECT_UNSPEC && -++ obj->ops->type->type != filter->type) -++ goto cont; -+ -+- if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid, -+- cb->nlh->nlmsg_seq, -+- NFT_MSG_NEWOBJ, -+- NLM_F_MULTI | NLM_F_APPEND, -+- afi->family, table, obj, reset) < 0) -+- goto done; -++ if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid, -++ cb->nlh->nlmsg_seq, -++ NFT_MSG_NEWOBJ, -++ NLM_F_MULTI | NLM_F_APPEND, -++ table->afi->family, table, -++ obj, reset) < 0) -++ goto done; -+ -+- nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -++ nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -+ cont: -+- idx++; -+- } -++ idx++; -+ } -+ } -+ done: -+@@ -4782,7 +4767,8 @@ static int nf_tables_getobj(struct net * -+ if (IS_ERR(afi)) -+ return PTR_ERR(afi); -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], afi->family, -++ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -4842,7 +4828,8 @@ static int nf_tables_delobj(struct net * -+ if (IS_ERR(afi)) -+ return PTR_ERR(afi); -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], afi->family, -++ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -4853,7 +4840,7 @@ static int nf_tables_delobj(struct net * -+ if (obj->use > 0) -+ return -EBUSY; -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); -+ -+ return nft_delobj(&ctx, obj); -+ } -+@@ -4891,7 +4878,7 @@ static void nf_tables_obj_notify(const s -+ struct nft_object *obj, int event) -+ { -+ nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event, -+- ctx->afi->family, ctx->report, GFP_KERNEL); -++ ctx->family, ctx->report, GFP_KERNEL); -+ } -+ -+ /* -+@@ -5081,7 +5068,7 @@ void nft_flow_table_iterate(struct net * -+ -+ rcu_read_lock(); -+ list_for_each_entry_rcu(afi, &net->nft.af_info, list) { -+- list_for_each_entry_rcu(table, &afi->tables, list) { -++ list_for_each_entry_rcu(table, &net->nft.tables, list) { -+ list_for_each_entry_rcu(flowtable, &table->flowtables, list) { -+ iter(&flowtable->data, data); -+ } -+@@ -5129,7 +5116,8 @@ static int nf_tables_newflowtable(struct -+ if (IS_ERR(afi)) -+ return PTR_ERR(afi); -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_FLOWTABLE_TABLE], genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], -++ afi->family, genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -5146,7 +5134,7 @@ static int nf_tables_newflowtable(struct -+ return 0; -+ } -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); -+ -+ flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL); -+ if (!flowtable) -+@@ -5227,7 +5215,8 @@ static int nf_tables_delflowtable(struct -+ if (IS_ERR(afi)) -+ return PTR_ERR(afi); -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_FLOWTABLE_TABLE], genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], -++ afi->family, genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -5238,7 +5227,7 @@ static int nf_tables_delflowtable(struct -+ if (flowtable->use > 0) -+ return -EBUSY; -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); -+ -+ return nft_delflowtable(&ctx, flowtable); -+ } -+@@ -5307,40 +5296,37 @@ static int nf_tables_dump_flowtable(stru -+ struct net *net = sock_net(skb->sk); -+ int family = nfmsg->nfgen_family; -+ struct nft_flowtable *flowtable; -+- const struct nft_af_info *afi; -+ const struct nft_table *table; -+ -+ rcu_read_lock(); -+ cb->seq = net->nft.base_seq; -+ -+- list_for_each_entry_rcu(afi, &net->nft.af_info, list) { -+- if (family != NFPROTO_UNSPEC && family != afi->family) -++ list_for_each_entry_rcu(table, &net->nft.tables, list) { -++ if (family != NFPROTO_UNSPEC && family != table->afi->family) -+ continue; -+ -+- list_for_each_entry_rcu(table, &afi->tables, list) { -+- list_for_each_entry_rcu(flowtable, &table->flowtables, list) { -+- if (!nft_is_active(net, flowtable)) -+- goto cont; -+- if (idx < s_idx) -+- goto cont; -+- if (idx > s_idx) -+- memset(&cb->args[1], 0, -+- sizeof(cb->args) - sizeof(cb->args[0])); -+- if (filter && filter->table[0] && -+- strcmp(filter->table, table->name)) -+- goto cont; -++ list_for_each_entry_rcu(flowtable, &table->flowtables, list) { -++ if (!nft_is_active(net, flowtable)) -++ goto cont; -++ if (idx < s_idx) -++ goto cont; -++ if (idx > s_idx) -++ memset(&cb->args[1], 0, -++ sizeof(cb->args) - sizeof(cb->args[0])); -++ if (filter && filter->table && -++ strcmp(filter->table, table->name)) -++ goto cont; -+ -+- if (nf_tables_fill_flowtable_info(skb, net, NETLINK_CB(cb->skb).portid, -+- cb->nlh->nlmsg_seq, -+- NFT_MSG_NEWFLOWTABLE, -+- NLM_F_MULTI | NLM_F_APPEND, -+- afi->family, flowtable) < 0) -+- goto done; -++ if (nf_tables_fill_flowtable_info(skb, net, NETLINK_CB(cb->skb).portid, -++ cb->nlh->nlmsg_seq, -++ NFT_MSG_NEWFLOWTABLE, -++ NLM_F_MULTI | NLM_F_APPEND, -++ table->afi->family, flowtable) < 0) -++ goto done; -+ -+- nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -++ nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -+ cont: -+- idx++; -+- } -++ idx++; -+ } -+ } -+ done: -+@@ -5425,7 +5411,8 @@ static int nf_tables_getflowtable(struct -+ if (IS_ERR(afi)) -+ return PTR_ERR(afi); -+ -+- table = nf_tables_table_lookup(afi, nla[NFTA_FLOWTABLE_TABLE], genmask); -++ table = nf_tables_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], -++ afi->family, genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -5468,7 +5455,7 @@ static void nf_tables_flowtable_notify(s -+ -+ err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid, -+ ctx->seq, event, 0, -+- ctx->afi->family, flowtable); -++ ctx->family, flowtable); -+ if (err < 0) { -+ kfree_skb(skb); -+ goto err; -+@@ -5546,17 +5533,14 @@ static int nf_tables_flowtable_event(str -+ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ struct nft_flowtable *flowtable; -+ struct nft_table *table; -+- struct nft_af_info *afi; -+ -+ if (event != NETDEV_UNREGISTER) -+ return 0; -+ -+ nfnl_lock(NFNL_SUBSYS_NFTABLES); -+- list_for_each_entry(afi, &dev_net(dev)->nft.af_info, list) { -+- list_for_each_entry(table, &afi->tables, list) { -+- list_for_each_entry(flowtable, &table->flowtables, list) { -+- nft_flowtable_event(event, dev, flowtable); -+- } -++ list_for_each_entry(table, &dev_net(dev)->nft.tables, list) { -++ list_for_each_entry(flowtable, &table->flowtables, list) { -++ nft_flowtable_event(event, dev, flowtable); -+ } -+ } -+ nfnl_unlock(NFNL_SUBSYS_NFTABLES); -+@@ -6582,6 +6566,7 @@ EXPORT_SYMBOL_GPL(nft_data_dump); -+ static int __net_init nf_tables_init_net(struct net *net) -+ { -+ INIT_LIST_HEAD(&net->nft.af_info); -++ INIT_LIST_HEAD(&net->nft.tables); -+ INIT_LIST_HEAD(&net->nft.commit_list); -+ net->nft.base_seq = 1; -+ return 0; -+@@ -6618,10 +6603,10 @@ static void __nft_release_afinfo(struct -+ struct nft_set *set, *ns; -+ struct nft_ctx ctx = { -+ .net = net, -+- .afi = afi, -++ .family = afi->family, -+ }; -+ -+- list_for_each_entry_safe(table, nt, &afi->tables, list) { -++ list_for_each_entry_safe(table, nt, &net->nft.tables, list) { -+ list_for_each_entry(chain, &table->chains, list) -+ nf_tables_unregister_hook(net, table, chain); -+ list_for_each_entry(flowtable, &table->flowtables, list) -+--- a/net/netfilter/nf_tables_netdev.c -++++ b/net/netfilter/nf_tables_netdev.c -+@@ -107,7 +107,6 @@ static int nf_tables_netdev_event(struct -+ unsigned long event, void *ptr) -+ { -+ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+- struct nft_af_info *afi; -+ struct nft_table *table; -+ struct nft_chain *chain, *nr; -+ struct nft_ctx ctx = { -+@@ -119,20 +118,18 @@ static int nf_tables_netdev_event(struct -+ return NOTIFY_DONE; -+ -+ nfnl_lock(NFNL_SUBSYS_NFTABLES); -+- list_for_each_entry(afi, &dev_net(dev)->nft.af_info, list) { -+- ctx.afi = afi; -+- if (afi->family != NFPROTO_NETDEV) -++ list_for_each_entry(table, &ctx.net->nft.tables, list) { -++ if (table->afi->family != NFPROTO_NETDEV) -+ continue; -+ -+- list_for_each_entry(table, &afi->tables, list) { -+- ctx.table = table; -+- list_for_each_entry_safe(chain, nr, &table->chains, list) { -+- if (!nft_is_base_chain(chain)) -+- continue; -++ ctx.family = table->afi->family; -++ ctx.table = table; -++ list_for_each_entry_safe(chain, nr, &table->chains, list) { -++ if (!nft_is_base_chain(chain)) -++ continue; -+ -+- ctx.chain = chain; -+- nft_netdev_event(event, dev, &ctx); -+- } -++ ctx.chain = chain; -++ nft_netdev_event(event, dev, &ctx); -+ } -+ } -+ nfnl_unlock(NFNL_SUBSYS_NFTABLES); -+--- a/net/netfilter/nft_compat.c -++++ b/net/netfilter/nft_compat.c -+@@ -161,7 +161,7 @@ nft_target_set_tgchk_param(struct xt_tgc -+ { -+ par->net = ctx->net; -+ par->table = ctx->table->name; -+- switch (ctx->afi->family) { -++ switch (ctx->family) { -+ case AF_INET: -+ entry->e4.ip.proto = proto; -+ entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0; -+@@ -192,7 +192,7 @@ nft_target_set_tgchk_param(struct xt_tgc -+ } else { -+ par->hook_mask = 0; -+ } -+- par->family = ctx->afi->family; -++ par->family = ctx->family; -+ par->nft_compat = true; -+ } -+ -+@@ -283,7 +283,7 @@ nft_target_destroy(const struct nft_ctx -+ par.net = ctx->net; -+ par.target = target; -+ par.targinfo = info; -+- par.family = ctx->afi->family; -++ par.family = ctx->family; -+ if (par.target->destroy != NULL) -+ par.target->destroy(&par); -+ -+@@ -409,7 +409,7 @@ nft_match_set_mtchk_param(struct xt_mtch -+ { -+ par->net = ctx->net; -+ par->table = ctx->table->name; -+- switch (ctx->afi->family) { -++ switch (ctx->family) { -+ case AF_INET: -+ entry->e4.ip.proto = proto; -+ entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0; -+@@ -440,7 +440,7 @@ nft_match_set_mtchk_param(struct xt_mtch -+ } else { -+ par->hook_mask = 0; -+ } -+- par->family = ctx->afi->family; -++ par->family = ctx->family; -+ par->nft_compat = true; -+ } -+ -+@@ -523,7 +523,7 @@ __nft_match_destroy(const struct nft_ctx -+ par.net = ctx->net; -+ par.match = match; -+ par.matchinfo = info; -+- par.family = ctx->afi->family; -++ par.family = ctx->family; -+ if (par.match->destroy != NULL) -+ par.match->destroy(&par); -+ -+@@ -754,7 +754,7 @@ nft_match_select_ops(const struct nft_ct -+ -+ mt_name = nla_data(tb[NFTA_MATCH_NAME]); -+ rev = ntohl(nla_get_be32(tb[NFTA_MATCH_REV])); -+- family = ctx->afi->family; -++ family = ctx->family; -+ -+ /* Re-use the existing match if it's already loaded. */ -+ list_for_each_entry(nft_match, &nft_match_list, head) { -+@@ -845,7 +845,7 @@ nft_target_select_ops(const struct nft_c -+ -+ tg_name = nla_data(tb[NFTA_TARGET_NAME]); -+ rev = ntohl(nla_get_be32(tb[NFTA_TARGET_REV])); -+- family = ctx->afi->family; -++ family = ctx->family; -+ -+ if (strcmp(tg_name, XT_ERROR_TARGET) == 0 || -+ strcmp(tg_name, XT_STANDARD_TARGET) == 0 || -+--- a/net/netfilter/nft_ct.c -++++ b/net/netfilter/nft_ct.c -+@@ -405,7 +405,7 @@ static int nft_ct_get_init(const struct -+ if (tb[NFTA_CT_DIRECTION] == NULL) -+ return -EINVAL; -+ -+- switch (ctx->afi->family) { -++ switch (ctx->family) { -+ case NFPROTO_IPV4: -+ len = FIELD_SIZEOF(struct nf_conntrack_tuple, -+ src.u3.ip); -+@@ -456,7 +456,7 @@ static int nft_ct_get_init(const struct -+ if (err < 0) -+ return err; -+ -+- err = nf_ct_netns_get(ctx->net, ctx->afi->family); -++ err = nf_ct_netns_get(ctx->net, ctx->family); -+ if (err < 0) -+ return err; -+ -+@@ -550,7 +550,7 @@ static int nft_ct_set_init(const struct -+ if (err < 0) -+ goto err1; -+ -+- err = nf_ct_netns_get(ctx->net, ctx->afi->family); -++ err = nf_ct_netns_get(ctx->net, ctx->family); -+ if (err < 0) -+ goto err1; -+ -+@@ -564,7 +564,7 @@ err1: -+ static void nft_ct_get_destroy(const struct nft_ctx *ctx, -+ const struct nft_expr *expr) -+ { -+- nf_ct_netns_put(ctx->net, ctx->afi->family); -++ nf_ct_netns_put(ctx->net, ctx->family); -+ } -+ -+ static void nft_ct_set_destroy(const struct nft_ctx *ctx, -+@@ -573,7 +573,7 @@ static void nft_ct_set_destroy(const str -+ struct nft_ct *priv = nft_expr_priv(expr); -+ -+ __nft_ct_set_destroy(ctx, priv); -+- nf_ct_netns_put(ctx->net, ctx->afi->family); -++ nf_ct_netns_put(ctx->net, ctx->family); -+ } -+ -+ static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr) -+@@ -734,7 +734,7 @@ static int nft_ct_helper_obj_init(const -+ struct nft_ct_helper_obj *priv = nft_obj_data(obj); -+ struct nf_conntrack_helper *help4, *help6; -+ char name[NF_CT_HELPER_NAME_LEN]; -+- int family = ctx->afi->family; -++ int family = ctx->family; -+ -+ if (!tb[NFTA_CT_HELPER_NAME] || !tb[NFTA_CT_HELPER_L4PROTO]) -+ return -EINVAL; -+@@ -753,14 +753,14 @@ static int nft_ct_helper_obj_init(const -+ -+ switch (family) { -+ case NFPROTO_IPV4: -+- if (ctx->afi->family == NFPROTO_IPV6) -++ if (ctx->family == NFPROTO_IPV6) -+ return -EINVAL; -+ -+ help4 = nf_conntrack_helper_try_module_get(name, family, -+ priv->l4proto); -+ break; -+ case NFPROTO_IPV6: -+- if (ctx->afi->family == NFPROTO_IPV4) -++ if (ctx->family == NFPROTO_IPV4) -+ return -EINVAL; -+ -+ help6 = nf_conntrack_helper_try_module_get(name, family, -+--- a/net/netfilter/nft_flow_offload.c -++++ b/net/netfilter/nft_flow_offload.c -+@@ -151,7 +151,7 @@ static int nft_flow_offload_init(const s -+ priv->flowtable = flowtable; -+ flowtable->use++; -+ -+- return nf_ct_netns_get(ctx->net, ctx->afi->family); -++ return nf_ct_netns_get(ctx->net, ctx->family); -+ } -+ -+ static void nft_flow_offload_destroy(const struct nft_ctx *ctx, -+@@ -160,7 +160,7 @@ static void nft_flow_offload_destroy(con -+ struct nft_flow_offload *priv = nft_expr_priv(expr); -+ -+ priv->flowtable->use--; -+- nf_ct_netns_put(ctx->net, ctx->afi->family); -++ nf_ct_netns_put(ctx->net, ctx->family); -+ } -+ -+ static int nft_flow_offload_dump(struct sk_buff *skb, const struct nft_expr *expr) -+--- a/net/netfilter/nft_log.c -++++ b/net/netfilter/nft_log.c -+@@ -112,7 +112,7 @@ static int nft_log_init(const struct nft -+ break; -+ } -+ -+- err = nf_logger_find_get(ctx->afi->family, li->type); -++ err = nf_logger_find_get(ctx->family, li->type); -+ if (err < 0) -+ goto err1; -+ -+@@ -133,7 +133,7 @@ static void nft_log_destroy(const struct -+ if (priv->prefix != nft_log_null_prefix) -+ kfree(priv->prefix); -+ -+- nf_logger_put(ctx->afi->family, li->type); -++ nf_logger_put(ctx->family, li->type); -+ } -+ -+ static int nft_log_dump(struct sk_buff *skb, const struct nft_expr *expr) -+--- a/net/netfilter/nft_masq.c -++++ b/net/netfilter/nft_masq.c -+@@ -73,7 +73,7 @@ int nft_masq_init(const struct nft_ctx * -+ } -+ } -+ -+- return nf_ct_netns_get(ctx->net, ctx->afi->family); -++ return nf_ct_netns_get(ctx->net, ctx->family); -+ } -+ EXPORT_SYMBOL_GPL(nft_masq_init); -+ -+--- a/net/netfilter/nft_meta.c -++++ b/net/netfilter/nft_meta.c -+@@ -341,7 +341,7 @@ static int nft_meta_get_validate(const s -+ if (priv->key != NFT_META_SECPATH) -+ return 0; -+ -+- switch (ctx->afi->family) { -++ switch (ctx->family) { -+ case NFPROTO_NETDEV: -+ hooks = 1 << NF_NETDEV_INGRESS; -+ break; -+@@ -372,7 +372,7 @@ int nft_meta_set_validate(const struct n -+ if (priv->key != NFT_META_PKTTYPE) -+ return 0; -+ -+- switch (ctx->afi->family) { -++ switch (ctx->family) { -+ case NFPROTO_BRIDGE: -+ hooks = 1 << NF_BR_PRE_ROUTING; -+ break; -+--- a/net/netfilter/nft_nat.c -++++ b/net/netfilter/nft_nat.c -+@@ -142,7 +142,7 @@ static int nft_nat_init(const struct nft -+ return -EINVAL; -+ -+ family = ntohl(nla_get_be32(tb[NFTA_NAT_FAMILY])); -+- if (family != ctx->afi->family) -++ if (family != ctx->family) -+ return -EOPNOTSUPP; -+ -+ switch (family) { -+--- a/net/netfilter/nft_redir.c -++++ b/net/netfilter/nft_redir.c -+@@ -75,7 +75,7 @@ int nft_redir_init(const struct nft_ctx -+ return -EINVAL; -+ } -+ -+- return nf_ct_netns_get(ctx->net, ctx->afi->family); -++ return nf_ct_netns_get(ctx->net, ctx->family); -+ } -+ EXPORT_SYMBOL_GPL(nft_redir_init); -+ -diff --git a/target/linux/generic/backport-4.14/336-v4.15-netfilter-exit_net-cleanup-check-added.patch b/target/linux/generic/backport-4.14/336-v4.15-netfilter-exit_net-cleanup-check-added.patch -new file mode 100644 -index 0000000000..b00675df20 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/336-v4.15-netfilter-exit_net-cleanup-check-added.patch -@@ -0,0 +1,100 @@ -+From: Vasily Averin -+Date: Sun, 12 Nov 2017 14:32:37 +0300 -+Subject: [PATCH] netfilter: exit_net cleanup check added -+ -+Be sure that lists initialized in net_init hook was return to initial -+state. -+ -+Signed-off-by: Vasily Averin -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c -++++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c -+@@ -835,6 +835,7 @@ static void clusterip_net_exit(struct ne -+ cn->procdir = NULL; -+ #endif -+ nf_unregister_net_hook(net, &cip_arp_ops); -++ WARN_ON_ONCE(!list_empty(&cn->configs)); -+ } -+ -+ static struct pernet_operations clusterip_net_ops = { -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -6572,6 +6572,12 @@ static int __net_init nf_tables_init_net -+ return 0; -+ } -+ -++static void __net_exit nf_tables_exit_net(struct net *net) -++{ -++ WARN_ON_ONCE(!list_empty(&net->nft.af_info)); -++ WARN_ON_ONCE(!list_empty(&net->nft.commit_list)); -++} -++ -+ int __nft_release_basechain(struct nft_ctx *ctx) -+ { -+ struct nft_rule *rule, *nr; -+@@ -6649,6 +6655,7 @@ static void __nft_release_afinfo(struct -+ -+ static struct pernet_operations nf_tables_net_ops = { -+ .init = nf_tables_init_net, -++ .exit = nf_tables_exit_net, -+ }; -+ -+ static int __init nf_tables_module_init(void) -+--- a/net/netfilter/nfnetlink_log.c -++++ b/net/netfilter/nfnetlink_log.c -+@@ -1093,10 +1093,15 @@ static int __net_init nfnl_log_net_init( -+ -+ static void __net_exit nfnl_log_net_exit(struct net *net) -+ { -++ struct nfnl_log_net *log = nfnl_log_pernet(net); -++ unsigned int i; -++ -+ #ifdef CONFIG_PROC_FS -+ remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter); -+ #endif -+ nf_log_unset(net, &nfulnl_logger); -++ for (i = 0; i < INSTANCE_BUCKETS; i++) -++ WARN_ON_ONCE(!hlist_empty(&log->instance_table[i])); -+ } -+ -+ static struct pernet_operations nfnl_log_net_ops = { -+--- a/net/netfilter/nfnetlink_queue.c -++++ b/net/netfilter/nfnetlink_queue.c -+@@ -1510,10 +1510,15 @@ static int __net_init nfnl_queue_net_ini -+ -+ static void __net_exit nfnl_queue_net_exit(struct net *net) -+ { -++ struct nfnl_queue_net *q = nfnl_queue_pernet(net); -++ unsigned int i; -++ -+ nf_unregister_queue_handler(net); -+ #ifdef CONFIG_PROC_FS -+ remove_proc_entry("nfnetlink_queue", net->nf.proc_netfilter); -+ #endif -++ for (i = 0; i < INSTANCE_BUCKETS; i++) -++ WARN_ON_ONCE(!hlist_empty(&q->instance_table[i])); -+ } -+ -+ static void nfnl_queue_net_exit_batch(struct list_head *net_exit_list) -+--- a/net/netfilter/x_tables.c -++++ b/net/netfilter/x_tables.c -+@@ -1785,8 +1785,17 @@ static int __net_init xt_net_init(struct -+ return 0; -+ } -+ -++static void __net_exit xt_net_exit(struct net *net) -++{ -++ int i; -++ -++ for (i = 0; i < NFPROTO_NUMPROTO; i++) -++ WARN_ON_ONCE(!list_empty(&net->xt.tables[i])); -++} -++ -+ static struct pernet_operations xt_net_ops = { -+ .init = xt_net_init, -++ .exit = xt_net_exit, -+ }; -+ -+ static int __init xt_init(void) -diff --git a/target/linux/generic/backport-4.14/337-v4.16-netfilter-nf_tables-get-rid-of-pernet-families.patch b/target/linux/generic/backport-4.14/337-v4.16-netfilter-nf_tables-get-rid-of-pernet-families.patch -new file mode 100644 -index 0000000000..a42581a4bb ---- /dev/null -+++ b/target/linux/generic/backport-4.14/337-v4.16-netfilter-nf_tables-get-rid-of-pernet-families.patch -@@ -0,0 +1,598 @@ -+From: Pablo Neira Ayuso -+Date: Tue, 9 Jan 2018 02:42:11 +0100 -+Subject: [PATCH] netfilter: nf_tables: get rid of pernet families -+ -+Now that we have a single table list for each netns, we can get rid of -+one pointer per family and the global afinfo list, thus, shrinking -+struct netns for nftables that now becomes 64 bytes smaller. -+ -+And call __nft_release_afinfo() from __net_exit path accordingly to -+release netnamespace objects on removal. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/net/netfilter/nf_tables.h -++++ b/include/net/netfilter/nf_tables.h -+@@ -975,8 +975,8 @@ struct nft_af_info { -+ struct module *owner; -+ }; -+ -+-int nft_register_afinfo(struct net *, struct nft_af_info *); -+-void nft_unregister_afinfo(struct net *, struct nft_af_info *); -++int nft_register_afinfo(struct nft_af_info *); -++void nft_unregister_afinfo(struct nft_af_info *); -+ -+ int nft_register_chain_type(const struct nf_chain_type *); -+ void nft_unregister_chain_type(const struct nf_chain_type *); -+--- a/include/net/netns/nftables.h -++++ b/include/net/netns/nftables.h -+@@ -7,15 +7,8 @@ -+ struct nft_af_info; -+ -+ struct netns_nftables { -+- struct list_head af_info; -+ struct list_head tables; -+ struct list_head commit_list; -+- struct nft_af_info *ipv4; -+- struct nft_af_info *ipv6; -+- struct nft_af_info *inet; -+- struct nft_af_info *arp; -+- struct nft_af_info *bridge; -+- struct nft_af_info *netdev; -+ unsigned int base_seq; -+ u8 gencursor; -+ }; -+--- a/net/bridge/netfilter/nf_tables_bridge.c -++++ b/net/bridge/netfilter/nf_tables_bridge.c -+@@ -47,34 +47,6 @@ static struct nft_af_info nft_af_bridge -+ .owner = THIS_MODULE, -+ }; -+ -+-static int nf_tables_bridge_init_net(struct net *net) -+-{ -+- net->nft.bridge = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL); -+- if (net->nft.bridge == NULL) -+- return -ENOMEM; -+- -+- memcpy(net->nft.bridge, &nft_af_bridge, sizeof(nft_af_bridge)); -+- -+- if (nft_register_afinfo(net, net->nft.bridge) < 0) -+- goto err; -+- -+- return 0; -+-err: -+- kfree(net->nft.bridge); -+- return -ENOMEM; -+-} -+- -+-static void nf_tables_bridge_exit_net(struct net *net) -+-{ -+- nft_unregister_afinfo(net, net->nft.bridge); -+- kfree(net->nft.bridge); -+-} -+- -+-static struct pernet_operations nf_tables_bridge_net_ops = { -+- .init = nf_tables_bridge_init_net, -+- .exit = nf_tables_bridge_exit_net, -+-}; -+- -+ static const struct nf_chain_type filter_bridge = { -+ .name = "filter", -+ .type = NFT_CHAIN_T_DEFAULT, -+@@ -98,17 +70,17 @@ static int __init nf_tables_bridge_init( -+ { -+ int ret; -+ -+- ret = nft_register_chain_type(&filter_bridge); -++ ret = nft_register_afinfo(&nft_af_bridge); -+ if (ret < 0) -+ return ret; -+ -+- ret = register_pernet_subsys(&nf_tables_bridge_net_ops); -++ ret = nft_register_chain_type(&filter_bridge); -+ if (ret < 0) -+- goto err_register_subsys; -++ goto err_register_chain; -+ -+ return ret; -+ -+-err_register_subsys: -++err_register_chain: -+ nft_unregister_chain_type(&filter_bridge); -+ -+ return ret; -+@@ -116,8 +88,8 @@ err_register_subsys: -+ -+ static void __exit nf_tables_bridge_exit(void) -+ { -+- unregister_pernet_subsys(&nf_tables_bridge_net_ops); -+ nft_unregister_chain_type(&filter_bridge); -++ nft_unregister_afinfo(&nft_af_bridge); -+ } -+ -+ module_init(nf_tables_bridge_init); -+--- a/net/ipv4/netfilter/nf_tables_arp.c -++++ b/net/ipv4/netfilter/nf_tables_arp.c -+@@ -32,34 +32,6 @@ static struct nft_af_info nft_af_arp __r -+ .owner = THIS_MODULE, -+ }; -+ -+-static int nf_tables_arp_init_net(struct net *net) -+-{ -+- net->nft.arp = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL); -+- if (net->nft.arp== NULL) -+- return -ENOMEM; -+- -+- memcpy(net->nft.arp, &nft_af_arp, sizeof(nft_af_arp)); -+- -+- if (nft_register_afinfo(net, net->nft.arp) < 0) -+- goto err; -+- -+- return 0; -+-err: -+- kfree(net->nft.arp); -+- return -ENOMEM; -+-} -+- -+-static void nf_tables_arp_exit_net(struct net *net) -+-{ -+- nft_unregister_afinfo(net, net->nft.arp); -+- kfree(net->nft.arp); -+-} -+- -+-static struct pernet_operations nf_tables_arp_net_ops = { -+- .init = nf_tables_arp_init_net, -+- .exit = nf_tables_arp_exit_net, -+-}; -+- -+ static const struct nf_chain_type filter_arp = { -+ .name = "filter", -+ .type = NFT_CHAIN_T_DEFAULT, -+@@ -77,21 +49,26 @@ static int __init nf_tables_arp_init(voi -+ { -+ int ret; -+ -+- ret = nft_register_chain_type(&filter_arp); -++ ret = nft_register_afinfo(&nft_af_arp); -+ if (ret < 0) -+ return ret; -+ -+- ret = register_pernet_subsys(&nf_tables_arp_net_ops); -++ ret = nft_register_chain_type(&filter_arp); -+ if (ret < 0) -+- nft_unregister_chain_type(&filter_arp); -++ goto err_register_chain; -++ -++ return 0; -++ -++err_register_chain: -++ nft_unregister_chain_type(&filter_arp); -+ -+ return ret; -+ } -+ -+ static void __exit nf_tables_arp_exit(void) -+ { -+- unregister_pernet_subsys(&nf_tables_arp_net_ops); -+ nft_unregister_chain_type(&filter_arp); -++ nft_unregister_afinfo(&nft_af_arp); -+ } -+ -+ module_init(nf_tables_arp_init); -+--- a/net/ipv4/netfilter/nf_tables_ipv4.c -++++ b/net/ipv4/netfilter/nf_tables_ipv4.c -+@@ -35,34 +35,6 @@ static struct nft_af_info nft_af_ipv4 __ -+ .owner = THIS_MODULE, -+ }; -+ -+-static int nf_tables_ipv4_init_net(struct net *net) -+-{ -+- net->nft.ipv4 = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL); -+- if (net->nft.ipv4 == NULL) -+- return -ENOMEM; -+- -+- memcpy(net->nft.ipv4, &nft_af_ipv4, sizeof(nft_af_ipv4)); -+- -+- if (nft_register_afinfo(net, net->nft.ipv4) < 0) -+- goto err; -+- -+- return 0; -+-err: -+- kfree(net->nft.ipv4); -+- return -ENOMEM; -+-} -+- -+-static void nf_tables_ipv4_exit_net(struct net *net) -+-{ -+- nft_unregister_afinfo(net, net->nft.ipv4); -+- kfree(net->nft.ipv4); -+-} -+- -+-static struct pernet_operations nf_tables_ipv4_net_ops = { -+- .init = nf_tables_ipv4_init_net, -+- .exit = nf_tables_ipv4_exit_net, -+-}; -+- -+ static const struct nf_chain_type filter_ipv4 = { -+ .name = "filter", -+ .type = NFT_CHAIN_T_DEFAULT, -+@@ -86,21 +58,25 @@ static int __init nf_tables_ipv4_init(vo -+ { -+ int ret; -+ -+- ret = nft_register_chain_type(&filter_ipv4); -++ ret = nft_register_afinfo(&nft_af_ipv4); -+ if (ret < 0) -+ return ret; -+ -+- ret = register_pernet_subsys(&nf_tables_ipv4_net_ops); -++ ret = nft_register_chain_type(&filter_ipv4); -+ if (ret < 0) -+- nft_unregister_chain_type(&filter_ipv4); -++ goto err_register_chain; -++ -++ return 0; -+ -++err_register_chain: -++ nft_unregister_afinfo(&nft_af_ipv4); -+ return ret; -+ } -+ -+ static void __exit nf_tables_ipv4_exit(void) -+ { -+- unregister_pernet_subsys(&nf_tables_ipv4_net_ops); -+ nft_unregister_chain_type(&filter_ipv4); -++ nft_unregister_afinfo(&nft_af_ipv4); -+ } -+ -+ module_init(nf_tables_ipv4_init); -+--- a/net/ipv6/netfilter/nf_tables_ipv6.c -++++ b/net/ipv6/netfilter/nf_tables_ipv6.c -+@@ -33,34 +33,6 @@ static struct nft_af_info nft_af_ipv6 __ -+ .owner = THIS_MODULE, -+ }; -+ -+-static int nf_tables_ipv6_init_net(struct net *net) -+-{ -+- net->nft.ipv6 = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL); -+- if (net->nft.ipv6 == NULL) -+- return -ENOMEM; -+- -+- memcpy(net->nft.ipv6, &nft_af_ipv6, sizeof(nft_af_ipv6)); -+- -+- if (nft_register_afinfo(net, net->nft.ipv6) < 0) -+- goto err; -+- -+- return 0; -+-err: -+- kfree(net->nft.ipv6); -+- return -ENOMEM; -+-} -+- -+-static void nf_tables_ipv6_exit_net(struct net *net) -+-{ -+- nft_unregister_afinfo(net, net->nft.ipv6); -+- kfree(net->nft.ipv6); -+-} -+- -+-static struct pernet_operations nf_tables_ipv6_net_ops = { -+- .init = nf_tables_ipv6_init_net, -+- .exit = nf_tables_ipv6_exit_net, -+-}; -+- -+ static const struct nf_chain_type filter_ipv6 = { -+ .name = "filter", -+ .type = NFT_CHAIN_T_DEFAULT, -+@@ -84,20 +56,24 @@ static int __init nf_tables_ipv6_init(vo -+ { -+ int ret; -+ -+- ret = nft_register_chain_type(&filter_ipv6); -++ ret = nft_register_afinfo(&nft_af_ipv6); -+ if (ret < 0) -+ return ret; -+ -+- ret = register_pernet_subsys(&nf_tables_ipv6_net_ops); -++ ret = nft_register_chain_type(&filter_ipv6); -+ if (ret < 0) -+- nft_unregister_chain_type(&filter_ipv6); -++ goto err_register_chain; -++ -++ return 0; -+ -++err_register_chain: -++ nft_unregister_afinfo(&nft_af_ipv6); -+ return ret; -+ } -+ -+ static void __exit nf_tables_ipv6_exit(void) -+ { -+- unregister_pernet_subsys(&nf_tables_ipv6_net_ops); -++ nft_unregister_afinfo(&nft_af_ipv6); -+ nft_unregister_chain_type(&filter_ipv6); -+ } -+ -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -26,6 +26,7 @@ -+ static LIST_HEAD(nf_tables_expressions); -+ static LIST_HEAD(nf_tables_objects); -+ static LIST_HEAD(nf_tables_flowtables); -++static LIST_HEAD(nf_tables_af_info); -+ -+ /** -+ * nft_register_afinfo - register nf_tables address family info -+@@ -35,17 +36,15 @@ static LIST_HEAD(nf_tables_flowtables); -+ * Register the address family for use with nf_tables. Returns zero on -+ * success or a negative errno code otherwise. -+ */ -+-int nft_register_afinfo(struct net *net, struct nft_af_info *afi) -++int nft_register_afinfo(struct nft_af_info *afi) -+ { -+ nfnl_lock(NFNL_SUBSYS_NFTABLES); -+- list_add_tail_rcu(&afi->list, &net->nft.af_info); -++ list_add_tail_rcu(&afi->list, &nf_tables_af_info); -+ nfnl_unlock(NFNL_SUBSYS_NFTABLES); -+ return 0; -+ } -+ EXPORT_SYMBOL_GPL(nft_register_afinfo); -+ -+-static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi); -+- -+ /** -+ * nft_unregister_afinfo - unregister nf_tables address family info -+ * -+@@ -53,10 +52,9 @@ static void __nft_release_afinfo(struct -+ * -+ * Unregister the address family for use with nf_tables. -+ */ -+-void nft_unregister_afinfo(struct net *net, struct nft_af_info *afi) -++void nft_unregister_afinfo(struct nft_af_info *afi) -+ { -+ nfnl_lock(NFNL_SUBSYS_NFTABLES); -+- __nft_release_afinfo(net, afi); -+ list_del_rcu(&afi->list); -+ nfnl_unlock(NFNL_SUBSYS_NFTABLES); -+ } -+@@ -66,7 +64,7 @@ static struct nft_af_info *nft_afinfo_lo -+ { -+ struct nft_af_info *afi; -+ -+- list_for_each_entry(afi, &net->nft.af_info, list) { -++ list_for_each_entry(afi, &nf_tables_af_info, list) { -+ if (afi->family == family) -+ return afi; -+ } -+@@ -5063,15 +5061,12 @@ void nft_flow_table_iterate(struct net * -+ void *data) -+ { -+ struct nft_flowtable *flowtable; -+- const struct nft_af_info *afi; -+ const struct nft_table *table; -+ -+ rcu_read_lock(); -+- list_for_each_entry_rcu(afi, &net->nft.af_info, list) { -+- list_for_each_entry_rcu(table, &net->nft.tables, list) { -+- list_for_each_entry_rcu(flowtable, &table->flowtables, list) { -+- iter(&flowtable->data, data); -+- } -++ list_for_each_entry_rcu(table, &net->nft.tables, list) { -++ list_for_each_entry_rcu(flowtable, &table->flowtables, list) { -++ iter(&flowtable->data, data); -+ } -+ } -+ rcu_read_unlock(); -+@@ -6563,21 +6558,6 @@ int nft_data_dump(struct sk_buff *skb, i -+ } -+ EXPORT_SYMBOL_GPL(nft_data_dump); -+ -+-static int __net_init nf_tables_init_net(struct net *net) -+-{ -+- INIT_LIST_HEAD(&net->nft.af_info); -+- INIT_LIST_HEAD(&net->nft.tables); -+- INIT_LIST_HEAD(&net->nft.commit_list); -+- net->nft.base_seq = 1; -+- return 0; -+-} -+- -+-static void __net_exit nf_tables_exit_net(struct net *net) -+-{ -+- WARN_ON_ONCE(!list_empty(&net->nft.af_info)); -+- WARN_ON_ONCE(!list_empty(&net->nft.commit_list)); -+-} -+- -+ int __nft_release_basechain(struct nft_ctx *ctx) -+ { -+ struct nft_rule *rule, *nr; -+@@ -6598,8 +6578,7 @@ int __nft_release_basechain(struct nft_c -+ } -+ EXPORT_SYMBOL_GPL(__nft_release_basechain); -+ -+-/* Called by nft_unregister_afinfo() from __net_exit path, nfnl_lock is held. */ -+-static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi) -++static void __nft_release_afinfo(struct net *net) -+ { -+ struct nft_flowtable *flowtable, *nf; -+ struct nft_table *table, *nt; -+@@ -6609,10 +6588,11 @@ static void __nft_release_afinfo(struct -+ struct nft_set *set, *ns; -+ struct nft_ctx ctx = { -+ .net = net, -+- .family = afi->family, -+ }; -+ -+ list_for_each_entry_safe(table, nt, &net->nft.tables, list) { -++ ctx.family = table->afi->family; -++ -+ list_for_each_entry(chain, &table->chains, list) -+ nf_tables_unregister_hook(net, table, chain); -+ list_for_each_entry(flowtable, &table->flowtables, list) -+@@ -6653,6 +6633,21 @@ static void __nft_release_afinfo(struct -+ } -+ } -+ -++static int __net_init nf_tables_init_net(struct net *net) -++{ -++ INIT_LIST_HEAD(&net->nft.tables); -++ INIT_LIST_HEAD(&net->nft.commit_list); -++ net->nft.base_seq = 1; -++ return 0; -++} -++ -++static void __net_exit nf_tables_exit_net(struct net *net) -++{ -++ __nft_release_afinfo(net); -++ WARN_ON_ONCE(!list_empty(&net->nft.tables)); -++ WARN_ON_ONCE(!list_empty(&net->nft.commit_list)); -++} -++ -+ static struct pernet_operations nf_tables_net_ops = { -+ .init = nf_tables_init_net, -+ .exit = nf_tables_exit_net, -+--- a/net/netfilter/nf_tables_inet.c -++++ b/net/netfilter/nf_tables_inet.c -+@@ -43,34 +43,6 @@ static struct nft_af_info nft_af_inet __ -+ .owner = THIS_MODULE, -+ }; -+ -+-static int __net_init nf_tables_inet_init_net(struct net *net) -+-{ -+- net->nft.inet = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL); -+- if (net->nft.inet == NULL) -+- return -ENOMEM; -+- memcpy(net->nft.inet, &nft_af_inet, sizeof(nft_af_inet)); -+- -+- if (nft_register_afinfo(net, net->nft.inet) < 0) -+- goto err; -+- -+- return 0; -+- -+-err: -+- kfree(net->nft.inet); -+- return -ENOMEM; -+-} -+- -+-static void __net_exit nf_tables_inet_exit_net(struct net *net) -+-{ -+- nft_unregister_afinfo(net, net->nft.inet); -+- kfree(net->nft.inet); -+-} -+- -+-static struct pernet_operations nf_tables_inet_net_ops = { -+- .init = nf_tables_inet_init_net, -+- .exit = nf_tables_inet_exit_net, -+-}; -+- -+ static const struct nf_chain_type filter_inet = { -+ .name = "filter", -+ .type = NFT_CHAIN_T_DEFAULT, -+@@ -94,21 +66,24 @@ static int __init nf_tables_inet_init(vo -+ { -+ int ret; -+ -+- ret = nft_register_chain_type(&filter_inet); -+- if (ret < 0) -++ if (nft_register_afinfo(&nft_af_inet) < 0) -+ return ret; -+ -+- ret = register_pernet_subsys(&nf_tables_inet_net_ops); -++ ret = nft_register_chain_type(&filter_inet); -+ if (ret < 0) -+- nft_unregister_chain_type(&filter_inet); -++ goto err_register_chain; -++ -++ return ret; -+ -++err_register_chain: -++ nft_unregister_afinfo(&nft_af_inet); -+ return ret; -+ } -+ -+ static void __exit nf_tables_inet_exit(void) -+ { -+- unregister_pernet_subsys(&nf_tables_inet_net_ops); -+ nft_unregister_chain_type(&filter_inet); -++ nft_unregister_afinfo(&nft_af_inet); -+ } -+ -+ module_init(nf_tables_inet_init); -+--- a/net/netfilter/nf_tables_netdev.c -++++ b/net/netfilter/nf_tables_netdev.c -+@@ -43,34 +43,6 @@ static struct nft_af_info nft_af_netdev -+ .owner = THIS_MODULE, -+ }; -+ -+-static int nf_tables_netdev_init_net(struct net *net) -+-{ -+- net->nft.netdev = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL); -+- if (net->nft.netdev == NULL) -+- return -ENOMEM; -+- -+- memcpy(net->nft.netdev, &nft_af_netdev, sizeof(nft_af_netdev)); -+- -+- if (nft_register_afinfo(net, net->nft.netdev) < 0) -+- goto err; -+- -+- return 0; -+-err: -+- kfree(net->nft.netdev); -+- return -ENOMEM; -+-} -+- -+-static void nf_tables_netdev_exit_net(struct net *net) -+-{ -+- nft_unregister_afinfo(net, net->nft.netdev); -+- kfree(net->nft.netdev); -+-} -+- -+-static struct pernet_operations nf_tables_netdev_net_ops = { -+- .init = nf_tables_netdev_init_net, -+- .exit = nf_tables_netdev_exit_net, -+-}; -+- -+ static const struct nf_chain_type nft_filter_chain_netdev = { -+ .name = "filter", -+ .type = NFT_CHAIN_T_DEFAULT, -+@@ -145,32 +117,32 @@ static int __init nf_tables_netdev_init( -+ { -+ int ret; -+ -+- ret = nft_register_chain_type(&nft_filter_chain_netdev); -+- if (ret) -++ if (nft_register_afinfo(&nft_af_netdev) < 0) -+ return ret; -+ -+- ret = register_pernet_subsys(&nf_tables_netdev_net_ops); -++ ret = nft_register_chain_type(&nft_filter_chain_netdev); -+ if (ret) -+- goto err1; -++ goto err_register_chain_type; -+ -+ ret = register_netdevice_notifier(&nf_tables_netdev_notifier); -+ if (ret) -+- goto err2; -++ goto err_register_netdevice_notifier; -+ -+ return 0; -+ -+-err2: -+- unregister_pernet_subsys(&nf_tables_netdev_net_ops); -+-err1: -++err_register_netdevice_notifier: -+ nft_unregister_chain_type(&nft_filter_chain_netdev); -++err_register_chain_type: -++ nft_unregister_afinfo(&nft_af_netdev); -++ -+ return ret; -+ } -+ -+ static void __exit nf_tables_netdev_exit(void) -+ { -+ unregister_netdevice_notifier(&nf_tables_netdev_notifier); -+- unregister_pernet_subsys(&nf_tables_netdev_net_ops); -+ nft_unregister_chain_type(&nft_filter_chain_netdev); -++ nft_unregister_afinfo(&nft_af_netdev); -+ } -+ -+ module_init(nf_tables_netdev_init); -diff --git a/target/linux/generic/backport-4.14/338-v4.16-netfilter-nf_tables-get-rid-of-struct-nft_af_info-ab.patch b/target/linux/generic/backport-4.14/338-v4.16-netfilter-nf_tables-get-rid-of-struct-nft_af_info-ab.patch -new file mode 100644 -index 0000000000..7816718466 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/338-v4.16-netfilter-nf_tables-get-rid-of-struct-nft_af_info-ab.patch -@@ -0,0 +1,1204 @@ -+From: Pablo Neira Ayuso -+Date: Tue, 9 Jan 2018 02:48:47 +0100 -+Subject: [PATCH] netfilter: nf_tables: get rid of struct nft_af_info -+ abstraction -+ -+Remove the infrastructure to register/unregister nft_af_info structure, -+this structure stores no useful information anymore. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/net/netfilter/nf_tables.h -++++ b/include/net/netfilter/nf_tables.h -+@@ -956,28 +956,12 @@ struct nft_table { -+ struct list_head flowtables; -+ u64 hgenerator; -+ u32 use; -+- u16 flags:14, -++ u16 family:6, -++ flags:8, -+ genmask:2; -+- struct nft_af_info *afi; -+ char *name; -+ }; -+ -+-/** -+- * struct nft_af_info - nf_tables address family info -+- * -+- * @list: used internally -+- * @family: address family -+- * @owner: module owner -+- */ -+-struct nft_af_info { -+- struct list_head list; -+- int family; -+- struct module *owner; -+-}; -+- -+-int nft_register_afinfo(struct nft_af_info *); -+-void nft_unregister_afinfo(struct nft_af_info *); -+- -+ int nft_register_chain_type(const struct nf_chain_type *); -+ void nft_unregister_chain_type(const struct nf_chain_type *); -+ -+@@ -1145,9 +1129,6 @@ void nft_trace_notify(struct nft_tracein -+ #define nft_dereference(p) \ -+ nfnl_dereference(p, NFNL_SUBSYS_NFTABLES) -+ -+-#define MODULE_ALIAS_NFT_FAMILY(family) \ -+- MODULE_ALIAS("nft-afinfo-" __stringify(family)) -+- -+ #define MODULE_ALIAS_NFT_CHAIN(family, name) \ -+ MODULE_ALIAS("nft-chain-" __stringify(family) "-" name) -+ -+--- a/net/bridge/netfilter/nf_tables_bridge.c -++++ b/net/bridge/netfilter/nf_tables_bridge.c -+@@ -42,11 +42,6 @@ nft_do_chain_bridge(void *priv, -+ return nft_do_chain(&pkt, priv); -+ } -+ -+-static struct nft_af_info nft_af_bridge __read_mostly = { -+- .family = NFPROTO_BRIDGE, -+- .owner = THIS_MODULE, -+-}; -+- -+ static const struct nf_chain_type filter_bridge = { -+ .name = "filter", -+ .type = NFT_CHAIN_T_DEFAULT, -+@@ -68,28 +63,12 @@ static const struct nf_chain_type filter -+ -+ static int __init nf_tables_bridge_init(void) -+ { -+- int ret; -+- -+- ret = nft_register_afinfo(&nft_af_bridge); -+- if (ret < 0) -+- return ret; -+- -+- ret = nft_register_chain_type(&filter_bridge); -+- if (ret < 0) -+- goto err_register_chain; -+- -+- return ret; -+- -+-err_register_chain: -+- nft_unregister_chain_type(&filter_bridge); -+- -+- return ret; -++ return nft_register_chain_type(&filter_bridge); -+ } -+ -+ static void __exit nf_tables_bridge_exit(void) -+ { -+ nft_unregister_chain_type(&filter_bridge); -+- nft_unregister_afinfo(&nft_af_bridge); -+ } -+ -+ module_init(nf_tables_bridge_init); -+@@ -97,4 +76,4 @@ module_exit(nf_tables_bridge_exit); -+ -+ MODULE_LICENSE("GPL"); -+ MODULE_AUTHOR("Patrick McHardy "); -+-MODULE_ALIAS_NFT_FAMILY(AF_BRIDGE); -++MODULE_ALIAS_NFT_CHAIN(AF_BRIDGE, "filter"); -+--- a/net/ipv4/netfilter/nf_tables_arp.c -++++ b/net/ipv4/netfilter/nf_tables_arp.c -+@@ -27,11 +27,6 @@ nft_do_chain_arp(void *priv, -+ return nft_do_chain(&pkt, priv); -+ } -+ -+-static struct nft_af_info nft_af_arp __read_mostly = { -+- .family = NFPROTO_ARP, -+- .owner = THIS_MODULE, -+-}; -+- -+ static const struct nf_chain_type filter_arp = { -+ .name = "filter", -+ .type = NFT_CHAIN_T_DEFAULT, -+@@ -47,28 +42,12 @@ static const struct nf_chain_type filter -+ -+ static int __init nf_tables_arp_init(void) -+ { -+- int ret; -+- -+- ret = nft_register_afinfo(&nft_af_arp); -+- if (ret < 0) -+- return ret; -+- -+- ret = nft_register_chain_type(&filter_arp); -+- if (ret < 0) -+- goto err_register_chain; -+- -+- return 0; -+- -+-err_register_chain: -+- nft_unregister_chain_type(&filter_arp); -+- -+- return ret; -++ return nft_register_chain_type(&filter_arp); -+ } -+ -+ static void __exit nf_tables_arp_exit(void) -+ { -+ nft_unregister_chain_type(&filter_arp); -+- nft_unregister_afinfo(&nft_af_arp); -+ } -+ -+ module_init(nf_tables_arp_init); -+@@ -76,4 +55,4 @@ module_exit(nf_tables_arp_exit); -+ -+ MODULE_LICENSE("GPL"); -+ MODULE_AUTHOR("Patrick McHardy "); -+-MODULE_ALIAS_NFT_FAMILY(3); /* NFPROTO_ARP */ -++MODULE_ALIAS_NFT_CHAIN(3, "filter"); /* NFPROTO_ARP */ -+--- a/net/ipv4/netfilter/nf_tables_ipv4.c -++++ b/net/ipv4/netfilter/nf_tables_ipv4.c -+@@ -30,11 +30,6 @@ static unsigned int nft_do_chain_ipv4(vo -+ return nft_do_chain(&pkt, priv); -+ } -+ -+-static struct nft_af_info nft_af_ipv4 __read_mostly = { -+- .family = NFPROTO_IPV4, -+- .owner = THIS_MODULE, -+-}; -+- -+ static const struct nf_chain_type filter_ipv4 = { -+ .name = "filter", -+ .type = NFT_CHAIN_T_DEFAULT, -+@@ -56,27 +51,12 @@ static const struct nf_chain_type filter -+ -+ static int __init nf_tables_ipv4_init(void) -+ { -+- int ret; -+- -+- ret = nft_register_afinfo(&nft_af_ipv4); -+- if (ret < 0) -+- return ret; -+- -+- ret = nft_register_chain_type(&filter_ipv4); -+- if (ret < 0) -+- goto err_register_chain; -+- -+- return 0; -+- -+-err_register_chain: -+- nft_unregister_afinfo(&nft_af_ipv4); -+- return ret; -++ return nft_register_chain_type(&filter_ipv4); -+ } -+ -+ static void __exit nf_tables_ipv4_exit(void) -+ { -+ nft_unregister_chain_type(&filter_ipv4); -+- nft_unregister_afinfo(&nft_af_ipv4); -+ } -+ -+ module_init(nf_tables_ipv4_init); -+@@ -84,4 +64,4 @@ module_exit(nf_tables_ipv4_exit); -+ -+ MODULE_LICENSE("GPL"); -+ MODULE_AUTHOR("Patrick McHardy "); -+-MODULE_ALIAS_NFT_FAMILY(AF_INET); -++MODULE_ALIAS_NFT_CHAIN(AF_INET, "filter"); -+--- a/net/ipv6/netfilter/nf_tables_ipv6.c -++++ b/net/ipv6/netfilter/nf_tables_ipv6.c -+@@ -28,11 +28,6 @@ static unsigned int nft_do_chain_ipv6(vo -+ return nft_do_chain(&pkt, priv); -+ } -+ -+-static struct nft_af_info nft_af_ipv6 __read_mostly = { -+- .family = NFPROTO_IPV6, -+- .owner = THIS_MODULE, -+-}; -+- -+ static const struct nf_chain_type filter_ipv6 = { -+ .name = "filter", -+ .type = NFT_CHAIN_T_DEFAULT, -+@@ -54,26 +49,11 @@ static const struct nf_chain_type filter -+ -+ static int __init nf_tables_ipv6_init(void) -+ { -+- int ret; -+- -+- ret = nft_register_afinfo(&nft_af_ipv6); -+- if (ret < 0) -+- return ret; -+- -+- ret = nft_register_chain_type(&filter_ipv6); -+- if (ret < 0) -+- goto err_register_chain; -+- -+- return 0; -+- -+-err_register_chain: -+- nft_unregister_afinfo(&nft_af_ipv6); -+- return ret; -++ return nft_register_chain_type(&filter_ipv6); -+ } -+ -+ static void __exit nf_tables_ipv6_exit(void) -+ { -+- nft_unregister_afinfo(&nft_af_ipv6); -+ nft_unregister_chain_type(&filter_ipv6); -+ } -+ -+@@ -82,4 +62,4 @@ module_exit(nf_tables_ipv6_exit); -+ -+ MODULE_LICENSE("GPL"); -+ MODULE_AUTHOR("Patrick McHardy "); -+-MODULE_ALIAS_NFT_FAMILY(AF_INET6); -++MODULE_ALIAS_NFT_CHAIN(AF_INET6, "filter"); -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -26,71 +26,6 @@ -+ static LIST_HEAD(nf_tables_expressions); -+ static LIST_HEAD(nf_tables_objects); -+ static LIST_HEAD(nf_tables_flowtables); -+-static LIST_HEAD(nf_tables_af_info); -+- -+-/** -+- * nft_register_afinfo - register nf_tables address family info -+- * -+- * @afi: address family info to register -+- * -+- * Register the address family for use with nf_tables. Returns zero on -+- * success or a negative errno code otherwise. -+- */ -+-int nft_register_afinfo(struct nft_af_info *afi) -+-{ -+- nfnl_lock(NFNL_SUBSYS_NFTABLES); -+- list_add_tail_rcu(&afi->list, &nf_tables_af_info); -+- nfnl_unlock(NFNL_SUBSYS_NFTABLES); -+- return 0; -+-} -+-EXPORT_SYMBOL_GPL(nft_register_afinfo); -+- -+-/** -+- * nft_unregister_afinfo - unregister nf_tables address family info -+- * -+- * @afi: address family info to unregister -+- * -+- * Unregister the address family for use with nf_tables. -+- */ -+-void nft_unregister_afinfo(struct nft_af_info *afi) -+-{ -+- nfnl_lock(NFNL_SUBSYS_NFTABLES); -+- list_del_rcu(&afi->list); -+- nfnl_unlock(NFNL_SUBSYS_NFTABLES); -+-} -+-EXPORT_SYMBOL_GPL(nft_unregister_afinfo); -+- -+-static struct nft_af_info *nft_afinfo_lookup(struct net *net, int family) -+-{ -+- struct nft_af_info *afi; -+- -+- list_for_each_entry(afi, &nf_tables_af_info, list) { -+- if (afi->family == family) -+- return afi; -+- } -+- return NULL; -+-} -+- -+-static struct nft_af_info * -+-nf_tables_afinfo_lookup(struct net *net, int family, bool autoload) -+-{ -+- struct nft_af_info *afi; -+- -+- afi = nft_afinfo_lookup(net, family); -+- if (afi != NULL) -+- return afi; -+-#ifdef CONFIG_MODULES -+- if (autoload) { -+- nfnl_unlock(NFNL_SUBSYS_NFTABLES); -+- request_module("nft-afinfo-%u", family); -+- nfnl_lock(NFNL_SUBSYS_NFTABLES); -+- afi = nft_afinfo_lookup(net, family); -+- if (afi != NULL) -+- return ERR_PTR(-EAGAIN); -+- } -+-#endif -+- return ERR_PTR(-EAFNOSUPPORT); -+-} -+ -+ static void nft_ctx_init(struct nft_ctx *ctx, -+ struct net *net, -+@@ -434,7 +369,7 @@ static struct nft_table *nft_table_looku -+ -+ list_for_each_entry(table, &net->nft.tables, list) { -+ if (!nla_strcmp(nla, table->name) && -+- table->afi->family == family && -++ table->family == family && -+ nft_active_genmask(table, genmask)) -+ return table; -+ } -+@@ -575,7 +510,7 @@ static int nf_tables_dump_tables(struct -+ cb->seq = net->nft.base_seq; -+ -+ list_for_each_entry_rcu(table, &net->nft.tables, list) { -+- if (family != NFPROTO_UNSPEC && family != table->afi->family) -++ if (family != NFPROTO_UNSPEC && family != table->family) -+ continue; -+ -+ if (idx < s_idx) -+@@ -589,7 +524,7 @@ static int nf_tables_dump_tables(struct -+ NETLINK_CB(cb->skb).portid, -+ cb->nlh->nlmsg_seq, -+ NFT_MSG_NEWTABLE, NLM_F_MULTI, -+- table->afi->family, table) < 0) -++ table->family, table) < 0) -+ goto done; -+ -+ nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -+@@ -609,7 +544,6 @@ static int nf_tables_gettable(struct net -+ { -+ const struct nfgenmsg *nfmsg = nlmsg_data(nlh); -+ u8 genmask = nft_genmask_cur(net); -+- const struct nft_af_info *afi; -+ const struct nft_table *table; -+ struct sk_buff *skb2; -+ int family = nfmsg->nfgen_family; -+@@ -622,11 +556,7 @@ static int nf_tables_gettable(struct net -+ return netlink_dump_start(nlsk, skb, nlh, &c); -+ } -+ -+- afi = nf_tables_afinfo_lookup(net, family, false); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+- table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], afi->family, -++ table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], family, -+ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+@@ -746,19 +676,14 @@ static int nf_tables_newtable(struct net -+ const struct nfgenmsg *nfmsg = nlmsg_data(nlh); -+ u8 genmask = nft_genmask_next(net); -+ const struct nlattr *name; -+- struct nft_af_info *afi; -+ struct nft_table *table; -+ int family = nfmsg->nfgen_family; -+ u32 flags = 0; -+ struct nft_ctx ctx; -+ int err; -+ -+- afi = nf_tables_afinfo_lookup(net, family, true); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+ name = nla[NFTA_TABLE_NAME]; -+- table = nf_tables_table_lookup(net, name, afi->family, genmask); -++ table = nf_tables_table_lookup(net, name, family, genmask); -+ if (IS_ERR(table)) { -+ if (PTR_ERR(table) != -ENOENT) -+ return PTR_ERR(table); -+@@ -768,7 +693,7 @@ static int nf_tables_newtable(struct net -+ if (nlh->nlmsg_flags & NLM_F_REPLACE) -+ return -EOPNOTSUPP; -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla); -+ return nf_tables_updtable(&ctx); -+ } -+ -+@@ -778,40 +703,34 @@ static int nf_tables_newtable(struct net -+ return -EINVAL; -+ } -+ -+- err = -EAFNOSUPPORT; -+- if (!try_module_get(afi->owner)) -+- goto err1; -+- -+ err = -ENOMEM; -+ table = kzalloc(sizeof(*table), GFP_KERNEL); -+ if (table == NULL) -+- goto err2; -++ goto err_kzalloc; -+ -+ table->name = nla_strdup(name, GFP_KERNEL); -+ if (table->name == NULL) -+- goto err3; -++ goto err_strdup; -+ -+ INIT_LIST_HEAD(&table->chains); -+ INIT_LIST_HEAD(&table->sets); -+ INIT_LIST_HEAD(&table->objects); -+ INIT_LIST_HEAD(&table->flowtables); -+- table->afi = afi; -++ table->family = family; -+ table->flags = flags; -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla); -+ err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE); -+ if (err < 0) -+- goto err4; -++ goto err_trans; -+ -+ list_add_tail_rcu(&table->list, &net->nft.tables); -+ return 0; -+-err4: -++err_trans: -+ kfree(table->name); -+-err3: -++err_strdup: -+ kfree(table); -+-err2: -+- module_put(afi->owner); -+-err1: -++err_kzalloc: -+ return err; -+ } -+ -+@@ -882,10 +801,10 @@ static int nft_flush(struct nft_ctx *ctx -+ int err = 0; -+ -+ list_for_each_entry_safe(table, nt, &ctx->net->nft.tables, list) { -+- if (family != AF_UNSPEC && table->afi->family != family) -++ if (family != AF_UNSPEC && table->family != family) -+ continue; -+ -+- ctx->family = table->afi->family; -++ ctx->family = table->family; -+ -+ if (!nft_is_active_next(ctx->net, table)) -+ continue; -+@@ -911,7 +830,6 @@ static int nf_tables_deltable(struct net -+ { -+ const struct nfgenmsg *nfmsg = nlmsg_data(nlh); -+ u8 genmask = nft_genmask_next(net); -+- struct nft_af_info *afi; -+ struct nft_table *table; -+ int family = nfmsg->nfgen_family; -+ struct nft_ctx ctx; -+@@ -920,11 +838,7 @@ static int nf_tables_deltable(struct net -+ if (family == AF_UNSPEC || nla[NFTA_TABLE_NAME] == NULL) -+ return nft_flush(&ctx, family); -+ -+- afi = nf_tables_afinfo_lookup(net, family, false); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+- table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], afi->family, -++ table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], family, -+ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+@@ -933,7 +847,7 @@ static int nf_tables_deltable(struct net -+ table->use > 0) -+ return -EBUSY; -+ -+- ctx.family = afi->family; -++ ctx.family = family; -+ ctx.table = table; -+ -+ return nft_flush_table(&ctx); -+@@ -945,7 +859,6 @@ static void nf_tables_table_destroy(stru -+ -+ kfree(ctx->table->name); -+ kfree(ctx->table); -+- module_put(ctx->table->afi->owner); -+ } -+ -+ int nft_register_chain_type(const struct nf_chain_type *ctype) -+@@ -1174,7 +1087,7 @@ static int nf_tables_dump_chains(struct -+ cb->seq = net->nft.base_seq; -+ -+ list_for_each_entry_rcu(table, &net->nft.tables, list) { -+- if (family != NFPROTO_UNSPEC && family != table->afi->family) -++ if (family != NFPROTO_UNSPEC && family != table->family) -+ continue; -+ -+ list_for_each_entry_rcu(chain, &table->chains, list) { -+@@ -1190,7 +1103,7 @@ static int nf_tables_dump_chains(struct -+ cb->nlh->nlmsg_seq, -+ NFT_MSG_NEWCHAIN, -+ NLM_F_MULTI, -+- table->afi->family, table, -++ table->family, table, -+ chain) < 0) -+ goto done; -+ -+@@ -1212,7 +1125,6 @@ static int nf_tables_getchain(struct net -+ { -+ const struct nfgenmsg *nfmsg = nlmsg_data(nlh); -+ u8 genmask = nft_genmask_cur(net); -+- const struct nft_af_info *afi; -+ const struct nft_table *table; -+ const struct nft_chain *chain; -+ struct sk_buff *skb2; -+@@ -1226,11 +1138,7 @@ static int nf_tables_getchain(struct net -+ return netlink_dump_start(nlsk, skb, nlh, &c); -+ } -+ -+- afi = nf_tables_afinfo_lookup(net, family, false); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+- table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], afi->family, -++ table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], family, -+ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+@@ -1612,7 +1520,6 @@ static int nf_tables_newchain(struct net -+ const struct nlattr * uninitialized_var(name); -+ u8 genmask = nft_genmask_next(net); -+ int family = nfmsg->nfgen_family; -+- struct nft_af_info *afi; -+ struct nft_table *table; -+ struct nft_chain *chain; -+ u8 policy = NF_ACCEPT; -+@@ -1622,11 +1529,7 @@ static int nf_tables_newchain(struct net -+ -+ create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false; -+ -+- afi = nf_tables_afinfo_lookup(net, family, true); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+- table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], afi->family, -++ table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], family, -+ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+@@ -1667,7 +1570,7 @@ static int nf_tables_newchain(struct net -+ } -+ } -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, chain, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla); -+ -+ if (chain != NULL) { -+ if (nlh->nlmsg_flags & NLM_F_EXCL) -+@@ -1688,7 +1591,6 @@ static int nf_tables_delchain(struct net -+ { -+ const struct nfgenmsg *nfmsg = nlmsg_data(nlh); -+ u8 genmask = nft_genmask_next(net); -+- struct nft_af_info *afi; -+ struct nft_table *table; -+ struct nft_chain *chain; -+ struct nft_rule *rule; -+@@ -1697,11 +1599,7 @@ static int nf_tables_delchain(struct net -+ u32 use; -+ int err; -+ -+- afi = nf_tables_afinfo_lookup(net, family, false); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+- table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], afi->family, -++ table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], family, -+ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+@@ -1714,7 +1612,7 @@ static int nf_tables_delchain(struct net -+ chain->use > 0) -+ return -EBUSY; -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, chain, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla); -+ -+ use = chain->use; -+ list_for_each_entry(rule, &chain->rules, list) { -+@@ -2145,7 +2043,7 @@ static int nf_tables_dump_rules(struct s -+ cb->seq = net->nft.base_seq; -+ -+ list_for_each_entry_rcu(table, &net->nft.tables, list) { -+- if (family != NFPROTO_UNSPEC && family != table->afi->family) -++ if (family != NFPROTO_UNSPEC && family != table->family) -+ continue; -+ -+ if (ctx && ctx->table && strcmp(ctx->table, table->name) != 0) -+@@ -2168,7 +2066,7 @@ static int nf_tables_dump_rules(struct s -+ cb->nlh->nlmsg_seq, -+ NFT_MSG_NEWRULE, -+ NLM_F_MULTI | NLM_F_APPEND, -+- table->afi->family, -++ table->family, -+ table, chain, rule) < 0) -+ goto done; -+ -+@@ -2204,7 +2102,6 @@ static int nf_tables_getrule(struct net -+ { -+ const struct nfgenmsg *nfmsg = nlmsg_data(nlh); -+ u8 genmask = nft_genmask_cur(net); -+- const struct nft_af_info *afi; -+ const struct nft_table *table; -+ const struct nft_chain *chain; -+ const struct nft_rule *rule; -+@@ -2248,11 +2145,7 @@ static int nf_tables_getrule(struct net -+ return netlink_dump_start(nlsk, skb, nlh, &c); -+ } -+ -+- afi = nf_tables_afinfo_lookup(net, family, false); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+- table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], afi->family, -++ table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], family, -+ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+@@ -2318,7 +2211,7 @@ static int nf_tables_newrule(struct net -+ { -+ const struct nfgenmsg *nfmsg = nlmsg_data(nlh); -+ u8 genmask = nft_genmask_next(net); -+- struct nft_af_info *afi; -++ int family = nfmsg->nfgen_family; -+ struct nft_table *table; -+ struct nft_chain *chain; -+ struct nft_rule *rule, *old_rule = NULL; -+@@ -2334,11 +2227,7 @@ static int nf_tables_newrule(struct net -+ -+ create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false; -+ -+- afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, create); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+- table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], afi->family, -++ table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], family, -+ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+@@ -2378,7 +2267,7 @@ static int nf_tables_newrule(struct net -+ return PTR_ERR(old_rule); -+ } -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, chain, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla); -+ -+ n = 0; -+ size = 0; -+@@ -2500,18 +2389,13 @@ static int nf_tables_delrule(struct net -+ { -+ const struct nfgenmsg *nfmsg = nlmsg_data(nlh); -+ u8 genmask = nft_genmask_next(net); -+- struct nft_af_info *afi; -+ struct nft_table *table; -+ struct nft_chain *chain = NULL; -+ struct nft_rule *rule; -+ int family = nfmsg->nfgen_family, err = 0; -+ struct nft_ctx ctx; -+ -+- afi = nf_tables_afinfo_lookup(net, family, false); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+- table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], afi->family, -++ table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], family, -+ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+@@ -2523,7 +2407,7 @@ static int nf_tables_delrule(struct net -+ return PTR_ERR(chain); -+ } -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, chain, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla); -+ -+ if (chain) { -+ if (nla[NFTA_RULE_HANDLE]) { -+@@ -2708,26 +2592,17 @@ static int nft_ctx_init_from_setattr(str -+ u8 genmask) -+ { -+ const struct nfgenmsg *nfmsg = nlmsg_data(nlh); -+- struct nft_af_info *afi = NULL; -++ int family = nfmsg->nfgen_family; -+ struct nft_table *table = NULL; -+ -+- if (nfmsg->nfgen_family != NFPROTO_UNSPEC) { -+- afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- } -+- -+ if (nla[NFTA_SET_TABLE] != NULL) { -+- if (afi == NULL) -+- return -EAFNOSUPPORT; -+- -+ table = nf_tables_table_lookup(net, nla[NFTA_SET_TABLE], -+- afi->family, genmask); -++ family, genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ } -+ -+- nft_ctx_init(ctx, net, skb, nlh, afi->family, table, NULL, nla); -++ nft_ctx_init(ctx, net, skb, nlh, family, table, NULL, nla); -+ return 0; -+ } -+ -+@@ -2959,7 +2834,7 @@ static int nf_tables_dump_sets(struct sk -+ -+ list_for_each_entry_rcu(table, &net->nft.tables, list) { -+ if (ctx->family != NFPROTO_UNSPEC && -+- ctx->family != table->afi->family) -++ ctx->family != table->family) -+ continue; -+ -+ if (ctx->table && ctx->table != table) -+@@ -2980,7 +2855,7 @@ static int nf_tables_dump_sets(struct sk -+ -+ ctx_set = *ctx; -+ ctx_set.table = table; -+- ctx_set.family = table->afi->family; -++ ctx_set.family = table->family; -+ -+ if (nf_tables_fill_set(skb, &ctx_set, set, -+ NFT_MSG_NEWSET, -+@@ -3092,8 +2967,8 @@ static int nf_tables_newset(struct net * -+ { -+ const struct nfgenmsg *nfmsg = nlmsg_data(nlh); -+ u8 genmask = nft_genmask_next(net); -++ int family = nfmsg->nfgen_family; -+ const struct nft_set_ops *ops; -+- struct nft_af_info *afi; -+ struct nft_table *table; -+ struct nft_set *set; -+ struct nft_ctx ctx; -+@@ -3203,16 +3078,12 @@ static int nf_tables_newset(struct net * -+ -+ create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false; -+ -+- afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, create); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+- table = nf_tables_table_lookup(net, nla[NFTA_SET_TABLE], afi->family, -++ table = nf_tables_table_lookup(net, nla[NFTA_SET_TABLE], family, -+ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla); -+ -+ set = nf_tables_set_lookup(table, nla[NFTA_SET_NAME], genmask); -+ if (IS_ERR(set)) { -+@@ -3474,19 +3345,15 @@ static int nft_ctx_init_from_elemattr(st -+ u8 genmask) -+ { -+ const struct nfgenmsg *nfmsg = nlmsg_data(nlh); -+- struct nft_af_info *afi; -++ int family = nfmsg->nfgen_family; -+ struct nft_table *table; -+ -+- afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+ table = nf_tables_table_lookup(net, nla[NFTA_SET_ELEM_LIST_TABLE], -+- afi->family, genmask); -++ family, genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+- nft_ctx_init(ctx, net, skb, nlh, afi->family, table, NULL, nla); -++ nft_ctx_init(ctx, net, skb, nlh, family, table, NULL, nla); -+ return 0; -+ } -+ -+@@ -3604,7 +3471,7 @@ static int nf_tables_dump_set(struct sk_ -+ rcu_read_lock(); -+ list_for_each_entry_rcu(table, &net->nft.tables, list) { -+ if (dump_ctx->ctx.family != NFPROTO_UNSPEC && -+- dump_ctx->ctx.family != table->afi->family) -++ dump_ctx->ctx.family != table->family) -+ continue; -+ -+ if (table != dump_ctx->ctx.table) -+@@ -3634,7 +3501,7 @@ static int nf_tables_dump_set(struct sk_ -+ goto nla_put_failure; -+ -+ nfmsg = nlmsg_data(nlh); -+- nfmsg->nfgen_family = table->afi->family; -++ nfmsg->nfgen_family = table->family; -+ nfmsg->version = NFNETLINK_V0; -+ nfmsg->res_id = htons(net->nft.base_seq & 0xffff); -+ -+@@ -4522,7 +4389,6 @@ static int nf_tables_newobj(struct net * -+ const struct nft_object_type *type; -+ u8 genmask = nft_genmask_next(net); -+ int family = nfmsg->nfgen_family; -+- struct nft_af_info *afi; -+ struct nft_table *table; -+ struct nft_object *obj; -+ struct nft_ctx ctx; -+@@ -4534,11 +4400,7 @@ static int nf_tables_newobj(struct net * -+ !nla[NFTA_OBJ_DATA]) -+ return -EINVAL; -+ -+- afi = nf_tables_afinfo_lookup(net, family, true); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+- table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], afi->family, -++ table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], family, -+ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+@@ -4557,7 +4419,7 @@ static int nf_tables_newobj(struct net * -+ return 0; -+ } -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla); -+ -+ type = nft_obj_type_get(objtype); -+ if (IS_ERR(type)) -+@@ -4649,7 +4511,7 @@ static int nf_tables_dump_obj(struct sk_ -+ cb->seq = net->nft.base_seq; -+ -+ list_for_each_entry_rcu(table, &net->nft.tables, list) { -+- if (family != NFPROTO_UNSPEC && family != table->afi->family) -++ if (family != NFPROTO_UNSPEC && family != table->family) -+ continue; -+ -+ list_for_each_entry_rcu(obj, &table->objects, list) { -+@@ -4672,7 +4534,7 @@ static int nf_tables_dump_obj(struct sk_ -+ cb->nlh->nlmsg_seq, -+ NFT_MSG_NEWOBJ, -+ NLM_F_MULTI | NLM_F_APPEND, -+- table->afi->family, table, -++ table->family, table, -+ obj, reset) < 0) -+ goto done; -+ -+@@ -4730,7 +4592,6 @@ static int nf_tables_getobj(struct net * -+ const struct nfgenmsg *nfmsg = nlmsg_data(nlh); -+ u8 genmask = nft_genmask_cur(net); -+ int family = nfmsg->nfgen_family; -+- const struct nft_af_info *afi; -+ const struct nft_table *table; -+ struct nft_object *obj; -+ struct sk_buff *skb2; -+@@ -4761,11 +4622,7 @@ static int nf_tables_getobj(struct net * -+ !nla[NFTA_OBJ_TYPE]) -+ return -EINVAL; -+ -+- afi = nf_tables_afinfo_lookup(net, family, false); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+- table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], afi->family, -++ table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], family, -+ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+@@ -4812,7 +4669,6 @@ static int nf_tables_delobj(struct net * -+ const struct nfgenmsg *nfmsg = nlmsg_data(nlh); -+ u8 genmask = nft_genmask_next(net); -+ int family = nfmsg->nfgen_family; -+- struct nft_af_info *afi; -+ struct nft_table *table; -+ struct nft_object *obj; -+ struct nft_ctx ctx; -+@@ -4822,11 +4678,7 @@ static int nf_tables_delobj(struct net * -+ !nla[NFTA_OBJ_NAME]) -+ return -EINVAL; -+ -+- afi = nf_tables_afinfo_lookup(net, family, true); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+- table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], afi->family, -++ table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], family, -+ genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+@@ -4838,7 +4690,7 @@ static int nf_tables_delobj(struct net * -+ if (obj->use > 0) -+ return -EBUSY; -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla); -+ -+ return nft_delobj(&ctx, obj); -+ } -+@@ -5023,33 +4875,31 @@ err1: -+ return err; -+ } -+ -+-static const struct nf_flowtable_type * -+-__nft_flowtable_type_get(const struct nft_af_info *afi) -++static const struct nf_flowtable_type *__nft_flowtable_type_get(u8 family) -+ { -+ const struct nf_flowtable_type *type; -+ -+ list_for_each_entry(type, &nf_tables_flowtables, list) { -+- if (afi->family == type->family) -++ if (family == type->family) -+ return type; -+ } -+ return NULL; -+ } -+ -+-static const struct nf_flowtable_type * -+-nft_flowtable_type_get(const struct nft_af_info *afi) -++static const struct nf_flowtable_type *nft_flowtable_type_get(u8 family) -+ { -+ const struct nf_flowtable_type *type; -+ -+- type = __nft_flowtable_type_get(afi); -++ type = __nft_flowtable_type_get(family); -+ if (type != NULL && try_module_get(type->owner)) -+ return type; -+ -+ #ifdef CONFIG_MODULES -+ if (type == NULL) { -+ nfnl_unlock(NFNL_SUBSYS_NFTABLES); -+- request_module("nf-flowtable-%u", afi->family); -++ request_module("nf-flowtable-%u", family); -+ nfnl_lock(NFNL_SUBSYS_NFTABLES); -+- if (__nft_flowtable_type_get(afi)) -++ if (__nft_flowtable_type_get(family)) -+ return ERR_PTR(-EAGAIN); -+ } -+ #endif -+@@ -5097,7 +4947,6 @@ static int nf_tables_newflowtable(struct -+ u8 genmask = nft_genmask_next(net); -+ int family = nfmsg->nfgen_family; -+ struct nft_flowtable *flowtable; -+- struct nft_af_info *afi; -+ struct nft_table *table; -+ struct nft_ctx ctx; -+ int err, i, k; -+@@ -5107,12 +4956,8 @@ static int nf_tables_newflowtable(struct -+ !nla[NFTA_FLOWTABLE_HOOK]) -+ return -EINVAL; -+ -+- afi = nf_tables_afinfo_lookup(net, family, true); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+ table = nf_tables_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], -+- afi->family, genmask); -++ family, genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -5129,7 +4974,7 @@ static int nf_tables_newflowtable(struct -+ return 0; -+ } -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla); -+ -+ flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL); -+ if (!flowtable) -+@@ -5142,7 +4987,7 @@ static int nf_tables_newflowtable(struct -+ goto err1; -+ } -+ -+- type = nft_flowtable_type_get(afi); -++ type = nft_flowtable_type_get(family); -+ if (IS_ERR(type)) { -+ err = PTR_ERR(type); -+ goto err2; -+@@ -5202,16 +5047,11 @@ static int nf_tables_delflowtable(struct -+ u8 genmask = nft_genmask_next(net); -+ int family = nfmsg->nfgen_family; -+ struct nft_flowtable *flowtable; -+- struct nft_af_info *afi; -+ struct nft_table *table; -+ struct nft_ctx ctx; -+ -+- afi = nf_tables_afinfo_lookup(net, family, true); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+ table = nf_tables_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], -+- afi->family, genmask); -++ family, genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -5222,7 +5062,7 @@ static int nf_tables_delflowtable(struct -+ if (flowtable->use > 0) -+ return -EBUSY; -+ -+- nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); -++ nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla); -+ -+ return nft_delflowtable(&ctx, flowtable); -+ } -+@@ -5297,7 +5137,7 @@ static int nf_tables_dump_flowtable(stru -+ cb->seq = net->nft.base_seq; -+ -+ list_for_each_entry_rcu(table, &net->nft.tables, list) { -+- if (family != NFPROTO_UNSPEC && family != table->afi->family) -++ if (family != NFPROTO_UNSPEC && family != table->family) -+ continue; -+ -+ list_for_each_entry_rcu(flowtable, &table->flowtables, list) { -+@@ -5316,7 +5156,7 @@ static int nf_tables_dump_flowtable(stru -+ cb->nlh->nlmsg_seq, -+ NFT_MSG_NEWFLOWTABLE, -+ NLM_F_MULTI | NLM_F_APPEND, -+- table->afi->family, flowtable) < 0) -++ table->family, flowtable) < 0) -+ goto done; -+ -+ nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -+@@ -5376,7 +5216,6 @@ static int nf_tables_getflowtable(struct -+ u8 genmask = nft_genmask_cur(net); -+ int family = nfmsg->nfgen_family; -+ struct nft_flowtable *flowtable; -+- const struct nft_af_info *afi; -+ const struct nft_table *table; -+ struct sk_buff *skb2; -+ int err; -+@@ -5402,12 +5241,8 @@ static int nf_tables_getflowtable(struct -+ if (!nla[NFTA_FLOWTABLE_NAME]) -+ return -EINVAL; -+ -+- afi = nf_tables_afinfo_lookup(net, family, false); -+- if (IS_ERR(afi)) -+- return PTR_ERR(afi); -+- -+ table = nf_tables_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], -+- afi->family, genmask); -++ family, genmask); -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -6578,7 +6413,7 @@ int __nft_release_basechain(struct nft_c -+ } -+ EXPORT_SYMBOL_GPL(__nft_release_basechain); -+ -+-static void __nft_release_afinfo(struct net *net) -++static void __nft_release_tables(struct net *net) -+ { -+ struct nft_flowtable *flowtable, *nf; -+ struct nft_table *table, *nt; -+@@ -6591,7 +6426,7 @@ static void __nft_release_afinfo(struct -+ }; -+ -+ list_for_each_entry_safe(table, nt, &net->nft.tables, list) { -+- ctx.family = table->afi->family; -++ ctx.family = table->family; -+ -+ list_for_each_entry(chain, &table->chains, list) -+ nf_tables_unregister_hook(net, table, chain); -+@@ -6643,7 +6478,7 @@ static int __net_init nf_tables_init_net -+ -+ static void __net_exit nf_tables_exit_net(struct net *net) -+ { -+- __nft_release_afinfo(net); -++ __nft_release_tables(net); -+ WARN_ON_ONCE(!list_empty(&net->nft.tables)); -+ WARN_ON_ONCE(!list_empty(&net->nft.commit_list)); -+ } -+--- a/net/netfilter/nf_tables_inet.c -++++ b/net/netfilter/nf_tables_inet.c -+@@ -38,11 +38,6 @@ static unsigned int nft_do_chain_inet(vo -+ return nft_do_chain(&pkt, priv); -+ } -+ -+-static struct nft_af_info nft_af_inet __read_mostly = { -+- .family = NFPROTO_INET, -+- .owner = THIS_MODULE, -+-}; -+- -+ static const struct nf_chain_type filter_inet = { -+ .name = "filter", -+ .type = NFT_CHAIN_T_DEFAULT, -+@@ -64,26 +59,12 @@ static const struct nf_chain_type filter -+ -+ static int __init nf_tables_inet_init(void) -+ { -+- int ret; -+- -+- if (nft_register_afinfo(&nft_af_inet) < 0) -+- return ret; -+- -+- ret = nft_register_chain_type(&filter_inet); -+- if (ret < 0) -+- goto err_register_chain; -+- -+- return ret; -+- -+-err_register_chain: -+- nft_unregister_afinfo(&nft_af_inet); -+- return ret; -++ return nft_register_chain_type(&filter_inet); -+ } -+ -+ static void __exit nf_tables_inet_exit(void) -+ { -+ nft_unregister_chain_type(&filter_inet); -+- nft_unregister_afinfo(&nft_af_inet); -+ } -+ -+ module_init(nf_tables_inet_init); -+@@ -91,4 +72,4 @@ module_exit(nf_tables_inet_exit); -+ -+ MODULE_LICENSE("GPL"); -+ MODULE_AUTHOR("Patrick McHardy "); -+-MODULE_ALIAS_NFT_FAMILY(1); -++MODULE_ALIAS_NFT_CHAIN(1, "filter"); -+--- a/net/netfilter/nf_tables_netdev.c -++++ b/net/netfilter/nf_tables_netdev.c -+@@ -38,11 +38,6 @@ nft_do_chain_netdev(void *priv, struct s -+ return nft_do_chain(&pkt, priv); -+ } -+ -+-static struct nft_af_info nft_af_netdev __read_mostly = { -+- .family = NFPROTO_NETDEV, -+- .owner = THIS_MODULE, -+-}; -+- -+ static const struct nf_chain_type nft_filter_chain_netdev = { -+ .name = "filter", -+ .type = NFT_CHAIN_T_DEFAULT, -+@@ -91,10 +86,10 @@ static int nf_tables_netdev_event(struct -+ -+ nfnl_lock(NFNL_SUBSYS_NFTABLES); -+ list_for_each_entry(table, &ctx.net->nft.tables, list) { -+- if (table->afi->family != NFPROTO_NETDEV) -++ if (table->family != NFPROTO_NETDEV) -+ continue; -+ -+- ctx.family = table->afi->family; -++ ctx.family = table->family; -+ ctx.table = table; -+ list_for_each_entry_safe(chain, nr, &table->chains, list) { -+ if (!nft_is_base_chain(chain)) -+@@ -117,12 +112,9 @@ static int __init nf_tables_netdev_init( -+ { -+ int ret; -+ -+- if (nft_register_afinfo(&nft_af_netdev) < 0) -+- return ret; -+- -+ ret = nft_register_chain_type(&nft_filter_chain_netdev); -+ if (ret) -+- goto err_register_chain_type; -++ return ret; -+ -+ ret = register_netdevice_notifier(&nf_tables_netdev_notifier); -+ if (ret) -+@@ -132,8 +124,6 @@ static int __init nf_tables_netdev_init( -+ -+ err_register_netdevice_notifier: -+ nft_unregister_chain_type(&nft_filter_chain_netdev); -+-err_register_chain_type: -+- nft_unregister_afinfo(&nft_af_netdev); -+ -+ return ret; -+ } -+@@ -142,7 +132,6 @@ static void __exit nf_tables_netdev_exit -+ { -+ unregister_netdevice_notifier(&nf_tables_netdev_notifier); -+ nft_unregister_chain_type(&nft_filter_chain_netdev); -+- nft_unregister_afinfo(&nft_af_netdev); -+ } -+ -+ module_init(nf_tables_netdev_init); -+@@ -150,4 +139,4 @@ module_exit(nf_tables_netdev_exit); -+ -+ MODULE_LICENSE("GPL"); -+ MODULE_AUTHOR("Pablo Neira Ayuso "); -+-MODULE_ALIAS_NFT_FAMILY(5); /* NFPROTO_NETDEV */ -++MODULE_ALIAS_NFT_CHAIN(5, "filter"); /* NFPROTO_NETDEV */ -diff --git a/target/linux/generic/backport-4.14/339-v4.16-netfilter-nft_flow_offload-wait-for-garbage-collecto.patch b/target/linux/generic/backport-4.14/339-v4.16-netfilter-nft_flow_offload-wait-for-garbage-collecto.patch -new file mode 100644 -index 0000000000..5ae917ff51 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/339-v4.16-netfilter-nft_flow_offload-wait-for-garbage-collecto.patch -@@ -0,0 +1,47 @@ -+From: Pablo Neira Ayuso -+Date: Thu, 1 Feb 2018 18:49:00 +0100 -+Subject: [PATCH] netfilter: nft_flow_offload: wait for garbage collector -+ to run after cleanup -+ -+If netdevice goes down, then flowtable entries are scheduled to be -+removed. Wait for garbage collector to have a chance to run so it can -+delete them from the hashtable. -+ -+The flush call might sleep, so hold the nfnl mutex from -+nft_flow_table_iterate() instead of rcu read side lock. The use of the -+nfnl mutex is also implicitly fixing races between updates via nfnetlink -+and netdevice event. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -4913,13 +4913,13 @@ void nft_flow_table_iterate(struct net * -+ struct nft_flowtable *flowtable; -+ const struct nft_table *table; -+ -+- rcu_read_lock(); -+- list_for_each_entry_rcu(table, &net->nft.tables, list) { -+- list_for_each_entry_rcu(flowtable, &table->flowtables, list) { -++ nfnl_lock(NFNL_SUBSYS_NFTABLES); -++ list_for_each_entry(table, &net->nft.tables, list) { -++ list_for_each_entry(flowtable, &table->flowtables, list) { -+ iter(&flowtable->data, data); -+ } -+ } -+- rcu_read_unlock(); -++ nfnl_unlock(NFNL_SUBSYS_NFTABLES); -+ } -+ EXPORT_SYMBOL_GPL(nft_flow_table_iterate); -+ -+--- a/net/netfilter/nft_flow_offload.c -++++ b/net/netfilter/nft_flow_offload.c -+@@ -208,6 +208,7 @@ static void nft_flow_offload_iterate_cle -+ void *data) -+ { -+ nf_flow_table_iterate(flowtable, flow_offload_iterate_cleanup, data); -++ flush_delayed_work(&flowtable->gc_work); -+ } -+ -+ static int flow_offload_netdev_event(struct notifier_block *this, -diff --git a/target/linux/generic/backport-4.14/340-v4.16-netfilter-nft_flow_offload-no-need-to-flush-entries-.patch b/target/linux/generic/backport-4.14/340-v4.16-netfilter-nft_flow_offload-no-need-to-flush-entries-.patch -new file mode 100644 -index 0000000000..539550d542 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/340-v4.16-netfilter-nft_flow_offload-no-need-to-flush-entries-.patch -@@ -0,0 +1,29 @@ -+From: Pablo Neira Ayuso -+Date: Thu, 1 Feb 2018 18:49:01 +0100 -+Subject: [PATCH] netfilter: nft_flow_offload: no need to flush entries on -+ module removal -+ -+nft_flow_offload module removal does not require to flush existing -+flowtables, it is valid to remove this module while keeping flowtables -+around. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/net/netfilter/nft_flow_offload.c -++++ b/net/netfilter/nft_flow_offload.c -+@@ -247,14 +247,8 @@ register_expr: -+ -+ static void __exit nft_flow_offload_module_exit(void) -+ { -+- struct net *net; -+- -+ nft_unregister_expr(&nft_flow_offload_type); -+ unregister_netdevice_notifier(&flow_offload_netdev_notifier); -+- rtnl_lock(); -+- for_each_net(net) -+- nft_flow_table_iterate(net, nft_flow_offload_iterate_cleanup, NULL); -+- rtnl_unlock(); -+ } -+ -+ module_init(nft_flow_offload_module_init); -diff --git a/target/linux/generic/backport-4.14/341-v4.16-netfilter-nft_flow_offload-move-flowtable-cleanup-ro.patch b/target/linux/generic/backport-4.14/341-v4.16-netfilter-nft_flow_offload-move-flowtable-cleanup-ro.patch -new file mode 100644 -index 0000000000..9ee0ad5936 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/341-v4.16-netfilter-nft_flow_offload-move-flowtable-cleanup-ro.patch -@@ -0,0 +1,97 @@ -+From: Pablo Neira Ayuso -+Date: Tue, 23 Jan 2018 17:46:09 +0100 -+Subject: [PATCH] netfilter: nft_flow_offload: move flowtable cleanup -+ routines to nf_flow_table -+ -+Move the flowtable cleanup routines to nf_flow_table and expose the -+nf_flow_table_cleanup() helper function. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -95,6 +95,9 @@ struct flow_offload_tuple_rhash *flow_of -+ int nf_flow_table_iterate(struct nf_flowtable *flow_table, -+ void (*iter)(struct flow_offload *flow, void *data), -+ void *data); -++ -++void nf_flow_table_cleanup(struct net *net, struct net_device *dev); -++ -+ void nf_flow_offload_work_gc(struct work_struct *work); -+ extern const struct rhashtable_params nf_flow_offload_rhash_params; -+ -+--- a/net/netfilter/nf_flow_table.c -++++ b/net/netfilter/nf_flow_table.c -+@@ -4,6 +4,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ #include -+@@ -425,5 +426,28 @@ int nf_flow_dnat_port(const struct flow_ -+ } -+ EXPORT_SYMBOL_GPL(nf_flow_dnat_port); -+ -++static void nf_flow_table_do_cleanup(struct flow_offload *flow, void *data) -++{ -++ struct net_device *dev = data; -++ -++ if (dev && flow->tuplehash[0].tuple.iifidx != dev->ifindex) -++ return; -++ -++ flow_offload_dead(flow); -++} -++ -++static void nf_flow_table_iterate_cleanup(struct nf_flowtable *flowtable, -++ void *data) -++{ -++ nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, data); -++ flush_delayed_work(&flowtable->gc_work); -++} -++ -++void nf_flow_table_cleanup(struct net *net, struct net_device *dev) -++{ -++ nft_flow_table_iterate(net, nf_flow_table_iterate_cleanup, dev); -++} -++EXPORT_SYMBOL_GPL(nf_flow_table_cleanup); -++ -+ MODULE_LICENSE("GPL"); -+ MODULE_AUTHOR("Pablo Neira Ayuso "); -+--- a/net/netfilter/nft_flow_offload.c -++++ b/net/netfilter/nft_flow_offload.c -+@@ -194,23 +194,6 @@ static struct nft_expr_type nft_flow_off -+ .owner = THIS_MODULE, -+ }; -+ -+-static void flow_offload_iterate_cleanup(struct flow_offload *flow, void *data) -+-{ -+- struct net_device *dev = data; -+- -+- if (dev && flow->tuplehash[0].tuple.iifidx != dev->ifindex) -+- return; -+- -+- flow_offload_dead(flow); -+-} -+- -+-static void nft_flow_offload_iterate_cleanup(struct nf_flowtable *flowtable, -+- void *data) -+-{ -+- nf_flow_table_iterate(flowtable, flow_offload_iterate_cleanup, data); -+- flush_delayed_work(&flowtable->gc_work); -+-} -+- -+ static int flow_offload_netdev_event(struct notifier_block *this, -+ unsigned long event, void *ptr) -+ { -+@@ -219,7 +202,7 @@ static int flow_offload_netdev_event(str -+ if (event != NETDEV_DOWN) -+ return NOTIFY_DONE; -+ -+- nft_flow_table_iterate(dev_net(dev), nft_flow_offload_iterate_cleanup, dev); -++ nf_flow_table_cleanup(dev_net(dev), dev); -+ -+ return NOTIFY_DONE; -+ } -diff --git a/target/linux/generic/backport-4.14/342-v4.16-netfilter-nf_tables-fix-flowtable-free.patch b/target/linux/generic/backport-4.14/342-v4.16-netfilter-nf_tables-fix-flowtable-free.patch -new file mode 100644 -index 0000000000..b8c85fc2a7 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/342-v4.16-netfilter-nf_tables-fix-flowtable-free.patch -@@ -0,0 +1,140 @@ -+From: Pablo Neira Ayuso -+Date: Mon, 5 Feb 2018 21:44:50 +0100 -+Subject: [PATCH] netfilter: nf_tables: fix flowtable free -+ -+Every flow_offload entry is added into the table twice. Because of this, -+rhashtable_free_and_destroy can't be used, since it would call kfree for -+each flow_offload object twice. -+ -+This patch adds a call to nf_flow_table_iterate_cleanup() to schedule -+removal of entries, then there is an explicitly invocation of the -+garbage collector to clean up resources. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -14,6 +14,7 @@ struct nf_flowtable_type { -+ struct list_head list; -+ int family; -+ void (*gc)(struct work_struct *work); -++ void (*free)(struct nf_flowtable *ft); -+ const struct rhashtable_params *params; -+ nf_hookfn *hook; -+ struct module *owner; -+@@ -98,6 +99,7 @@ int nf_flow_table_iterate(struct nf_flow -+ -+ void nf_flow_table_cleanup(struct net *net, struct net_device *dev); -+ -++void nf_flow_table_free(struct nf_flowtable *flow_table); -+ void nf_flow_offload_work_gc(struct work_struct *work); -+ extern const struct rhashtable_params nf_flow_offload_rhash_params; -+ -+--- a/net/ipv4/netfilter/nf_flow_table_ipv4.c -++++ b/net/ipv4/netfilter/nf_flow_table_ipv4.c -+@@ -260,6 +260,7 @@ static struct nf_flowtable_type flowtabl -+ .family = NFPROTO_IPV4, -+ .params = &nf_flow_offload_rhash_params, -+ .gc = nf_flow_offload_work_gc, -++ .free = nf_flow_table_free, -+ .hook = nf_flow_offload_ip_hook, -+ .owner = THIS_MODULE, -+ }; -+--- a/net/ipv6/netfilter/nf_flow_table_ipv6.c -++++ b/net/ipv6/netfilter/nf_flow_table_ipv6.c -+@@ -254,6 +254,7 @@ static struct nf_flowtable_type flowtabl -+ .family = NFPROTO_IPV6, -+ .params = &nf_flow_offload_rhash_params, -+ .gc = nf_flow_offload_work_gc, -++ .free = nf_flow_table_free, -+ .hook = nf_flow_offload_ipv6_hook, -+ .owner = THIS_MODULE, -+ }; -+--- a/net/netfilter/nf_flow_table.c -++++ b/net/netfilter/nf_flow_table.c -+@@ -232,19 +232,16 @@ static inline bool nf_flow_is_dying(cons -+ return flow->flags & FLOW_OFFLOAD_DYING; -+ } -+ -+-void nf_flow_offload_work_gc(struct work_struct *work) -++static int nf_flow_offload_gc_step(struct nf_flowtable *flow_table) -+ { -+ struct flow_offload_tuple_rhash *tuplehash; -+- struct nf_flowtable *flow_table; -+ struct rhashtable_iter hti; -+ struct flow_offload *flow; -+ int err; -+ -+- flow_table = container_of(work, struct nf_flowtable, gc_work.work); -+- -+ err = rhashtable_walk_init(&flow_table->rhashtable, &hti, GFP_KERNEL); -+ if (err) -+- goto schedule; -++ return 0; -+ -+ rhashtable_walk_start(&hti); -+ -+@@ -270,7 +267,16 @@ void nf_flow_offload_work_gc(struct work -+ out: -+ rhashtable_walk_stop(&hti); -+ rhashtable_walk_exit(&hti); -+-schedule: -++ -++ return 1; -++} -++ -++void nf_flow_offload_work_gc(struct work_struct *work) -++{ -++ struct nf_flowtable *flow_table; -++ -++ flow_table = container_of(work, struct nf_flowtable, gc_work.work); -++ nf_flow_offload_gc_step(flow_table); -+ queue_delayed_work(system_power_efficient_wq, &flow_table->gc_work, HZ); -+ } -+ EXPORT_SYMBOL_GPL(nf_flow_offload_work_gc); -+@@ -449,5 +455,12 @@ void nf_flow_table_cleanup(struct net *n -+ } -+ EXPORT_SYMBOL_GPL(nf_flow_table_cleanup); -+ -++void nf_flow_table_free(struct nf_flowtable *flow_table) -++{ -++ nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL); -++ WARN_ON(!nf_flow_offload_gc_step(flow_table)); -++} -++EXPORT_SYMBOL_GPL(nf_flow_table_free); -++ -+ MODULE_LICENSE("GPL"); -+ MODULE_AUTHOR("Pablo Neira Ayuso "); -+--- a/net/netfilter/nf_flow_table_inet.c -++++ b/net/netfilter/nf_flow_table_inet.c -+@@ -24,6 +24,7 @@ static struct nf_flowtable_type flowtabl -+ .family = NFPROTO_INET, -+ .params = &nf_flow_offload_rhash_params, -+ .gc = nf_flow_offload_work_gc, -++ .free = nf_flow_table_free, -+ .hook = nf_flow_offload_inet_hook, -+ .owner = THIS_MODULE, -+ }; -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -5298,17 +5298,12 @@ err: -+ nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS); -+ } -+ -+-static void nft_flowtable_destroy(void *ptr, void *arg) -+-{ -+- kfree(ptr); -+-} -+- -+ static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable) -+ { -+ cancel_delayed_work_sync(&flowtable->data.gc_work); -+ kfree(flowtable->name); -+- rhashtable_free_and_destroy(&flowtable->data.rhashtable, -+- nft_flowtable_destroy, NULL); -++ flowtable->data.type->free(&flowtable->data); -++ rhashtable_destroy(&flowtable->data.rhashtable); -+ module_put(flowtable->data.type->owner); -+ } -+ -diff --git a/target/linux/generic/backport-4.14/343-netfilter-nft_flow_offload-handle-netdevice-events-f.patch b/target/linux/generic/backport-4.14/343-netfilter-nft_flow_offload-handle-netdevice-events-f.patch -new file mode 100644 -index 0000000000..7f35cd7c60 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/343-netfilter-nft_flow_offload-handle-netdevice-events-f.patch -@@ -0,0 +1,96 @@ -+From: Pablo Neira Ayuso -+Date: Thu, 25 Jan 2018 12:58:55 +0100 -+Subject: [PATCH] netfilter: nft_flow_offload: handle netdevice events from -+ nf_flow_table -+ -+Move the code that deals with device events to the core. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/net/netfilter/nf_flow_table.c -++++ b/net/netfilter/nf_flow_table.c -+@@ -462,5 +462,35 @@ void nf_flow_table_free(struct nf_flowta -+ } -+ EXPORT_SYMBOL_GPL(nf_flow_table_free); -+ -++static int nf_flow_table_netdev_event(struct notifier_block *this, -++ unsigned long event, void *ptr) -++{ -++ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -++ -++ if (event != NETDEV_DOWN) -++ return NOTIFY_DONE; -++ -++ nf_flow_table_cleanup(dev_net(dev), dev); -++ -++ return NOTIFY_DONE; -++} -++ -++static struct notifier_block flow_offload_netdev_notifier = { -++ .notifier_call = nf_flow_table_netdev_event, -++}; -++ -++static int __init nf_flow_table_module_init(void) -++{ -++ return register_netdevice_notifier(&flow_offload_netdev_notifier); -++} -++ -++static void __exit nf_flow_table_module_exit(void) -++{ -++ unregister_netdevice_notifier(&flow_offload_netdev_notifier); -++} -++ -++module_init(nf_flow_table_module_init); -++module_exit(nf_flow_table_module_exit); -++ -+ MODULE_LICENSE("GPL"); -+ MODULE_AUTHOR("Pablo Neira Ayuso "); -+--- a/net/netfilter/nft_flow_offload.c -++++ b/net/netfilter/nft_flow_offload.c -+@@ -194,44 +194,14 @@ static struct nft_expr_type nft_flow_off -+ .owner = THIS_MODULE, -+ }; -+ -+-static int flow_offload_netdev_event(struct notifier_block *this, -+- unsigned long event, void *ptr) -+-{ -+- struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+- -+- if (event != NETDEV_DOWN) -+- return NOTIFY_DONE; -+- -+- nf_flow_table_cleanup(dev_net(dev), dev); -+- -+- return NOTIFY_DONE; -+-} -+- -+-static struct notifier_block flow_offload_netdev_notifier = { -+- .notifier_call = flow_offload_netdev_event, -+-}; -+- -+ static int __init nft_flow_offload_module_init(void) -+ { -+- int err; -+- -+- register_netdevice_notifier(&flow_offload_netdev_notifier); -+- -+- err = nft_register_expr(&nft_flow_offload_type); -+- if (err < 0) -+- goto register_expr; -+- -+- return 0; -+- -+-register_expr: -+- unregister_netdevice_notifier(&flow_offload_netdev_notifier); -+- return err; -++ return nft_register_expr(&nft_flow_offload_type); -+ } -+ -+ static void __exit nft_flow_offload_module_exit(void) -+ { -+ nft_unregister_expr(&nft_flow_offload_type); -+- unregister_netdevice_notifier(&flow_offload_netdev_notifier); -+ } -+ -+ module_init(nft_flow_offload_module_init); -diff --git a/target/linux/generic/backport-4.14/344-v4.16-netfilter-nf_tables-allocate-handle-and-delete-objec.patch b/target/linux/generic/backport-4.14/344-v4.16-netfilter-nf_tables-allocate-handle-and-delete-objec.patch -new file mode 100644 -index 0000000000..e6c9fd2f74 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/344-v4.16-netfilter-nf_tables-allocate-handle-and-delete-objec.patch -@@ -0,0 +1,468 @@ -+From: Harsha Sharma -+Date: Wed, 27 Dec 2017 00:59:00 +0530 -+Subject: [PATCH] netfilter: nf_tables: allocate handle and delete objects via -+ handle -+ -+This patch allows deletion of objects via unique handle which can be -+listed via '-a' option. -+ -+Signed-off-by: Harsha Sharma -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/net/netfilter/nf_tables.h -++++ b/include/net/netfilter/nf_tables.h -+@@ -370,6 +370,7 @@ void nft_unregister_set(struct nft_set_t -+ * @list: table set list node -+ * @bindings: list of set bindings -+ * @name: name of the set -++ * @handle: unique handle of the set -+ * @ktype: key type (numeric type defined by userspace, not used in the kernel) -+ * @dtype: data type (verdict or numeric type defined by userspace) -+ * @objtype: object type (see NFT_OBJECT_* definitions) -+@@ -392,6 +393,7 @@ struct nft_set { -+ struct list_head list; -+ struct list_head bindings; -+ char *name; -++ u64 handle; -+ u32 ktype; -+ u32 dtype; -+ u32 objtype; -+@@ -942,6 +944,7 @@ unsigned int nft_do_chain(struct nft_pkt -+ * @objects: stateful objects in the table -+ * @flowtables: flow tables in the table -+ * @hgenerator: handle generator state -++ * @handle: table handle -+ * @use: number of chain references to this table -+ * @flags: table flag (see enum nft_table_flags) -+ * @genmask: generation mask -+@@ -955,6 +958,7 @@ struct nft_table { -+ struct list_head objects; -+ struct list_head flowtables; -+ u64 hgenerator; -++ u64 handle; -+ u32 use; -+ u16 family:6, -+ flags:8, -+@@ -979,9 +983,9 @@ int nft_verdict_dump(struct sk_buff *skb -+ * @name: name of this stateful object -+ * @genmask: generation mask -+ * @use: number of references to this stateful object -+- * @data: object data, layout depends on type -++ * @handle: unique object handle -+ * @ops: object operations -+- * @data: pointer to object data -++ * @data: object data, layout depends on type -+ */ -+ struct nft_object { -+ struct list_head list; -+@@ -989,6 +993,7 @@ struct nft_object { -+ struct nft_table *table; -+ u32 genmask:2, -+ use:30; -++ u64 handle; -+ /* runtime data below here */ -+ const struct nft_object_ops *ops ____cacheline_aligned; -+ unsigned char data[] -+@@ -1070,6 +1075,7 @@ void nft_unregister_obj(struct nft_objec -+ * @ops_len: number of hooks in array -+ * @genmask: generation mask -+ * @use: number of references to this flow table -++ * @handle: unique object handle -+ * @data: rhashtable and garbage collector -+ * @ops: array of hooks -+ */ -+@@ -1082,6 +1088,7 @@ struct nft_flowtable { -+ int ops_len; -+ u32 genmask:2, -+ use:30; -++ u64 handle; -+ /* runtime data below here */ -+ struct nf_hook_ops *ops ____cacheline_aligned; -+ struct nf_flowtable data; -+--- a/include/uapi/linux/netfilter/nf_tables.h -++++ b/include/uapi/linux/netfilter/nf_tables.h -+@@ -174,6 +174,8 @@ enum nft_table_attributes { -+ NFTA_TABLE_NAME, -+ NFTA_TABLE_FLAGS, -+ NFTA_TABLE_USE, -++ NFTA_TABLE_HANDLE, -++ NFTA_TABLE_PAD, -+ __NFTA_TABLE_MAX -+ }; -+ #define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1) -+@@ -317,6 +319,7 @@ enum nft_set_desc_attributes { -+ * @NFTA_SET_GC_INTERVAL: garbage collection interval (NLA_U32) -+ * @NFTA_SET_USERDATA: user data (NLA_BINARY) -+ * @NFTA_SET_OBJ_TYPE: stateful object type (NLA_U32: NFT_OBJECT_*) -++ * @NFTA_SET_HANDLE: set handle (NLA_U64) -+ */ -+ enum nft_set_attributes { -+ NFTA_SET_UNSPEC, -+@@ -335,6 +338,7 @@ enum nft_set_attributes { -+ NFTA_SET_USERDATA, -+ NFTA_SET_PAD, -+ NFTA_SET_OBJ_TYPE, -++ NFTA_SET_HANDLE, -+ __NFTA_SET_MAX -+ }; -+ #define NFTA_SET_MAX (__NFTA_SET_MAX - 1) -+@@ -1314,6 +1318,7 @@ enum nft_ct_helper_attributes { -+ * @NFTA_OBJ_TYPE: stateful object type (NLA_U32) -+ * @NFTA_OBJ_DATA: stateful object data (NLA_NESTED) -+ * @NFTA_OBJ_USE: number of references to this expression (NLA_U32) -++ * @NFTA_OBJ_HANDLE: object handle (NLA_U64) -+ */ -+ enum nft_object_attributes { -+ NFTA_OBJ_UNSPEC, -+@@ -1322,6 +1327,8 @@ enum nft_object_attributes { -+ NFTA_OBJ_TYPE, -+ NFTA_OBJ_DATA, -+ NFTA_OBJ_USE, -++ NFTA_OBJ_HANDLE, -++ NFTA_OBJ_PAD, -+ __NFTA_OBJ_MAX -+ }; -+ #define NFTA_OBJ_MAX (__NFTA_OBJ_MAX - 1) -+@@ -1333,6 +1340,7 @@ enum nft_object_attributes { -+ * @NFTA_FLOWTABLE_NAME: name of this flow table (NLA_STRING) -+ * @NFTA_FLOWTABLE_HOOK: netfilter hook configuration(NLA_U32) -+ * @NFTA_FLOWTABLE_USE: number of references to this flow table (NLA_U32) -++ * @NFTA_FLOWTABLE_HANDLE: object handle (NLA_U64) -+ */ -+ enum nft_flowtable_attributes { -+ NFTA_FLOWTABLE_UNSPEC, -+@@ -1340,6 +1348,8 @@ enum nft_flowtable_attributes { -+ NFTA_FLOWTABLE_NAME, -+ NFTA_FLOWTABLE_HOOK, -+ NFTA_FLOWTABLE_USE, -++ NFTA_FLOWTABLE_HANDLE, -++ NFTA_FLOWTABLE_PAD, -+ __NFTA_FLOWTABLE_MAX -+ }; -+ #define NFTA_FLOWTABLE_MAX (__NFTA_FLOWTABLE_MAX - 1) -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -26,6 +26,7 @@ -+ static LIST_HEAD(nf_tables_expressions); -+ static LIST_HEAD(nf_tables_objects); -+ static LIST_HEAD(nf_tables_flowtables); -++static u64 table_handle; -+ -+ static void nft_ctx_init(struct nft_ctx *ctx, -+ struct net *net, -+@@ -376,6 +377,20 @@ static struct nft_table *nft_table_looku -+ return NULL; -+ } -+ -++static struct nft_table *nft_table_lookup_byhandle(const struct net *net, -++ const struct nlattr *nla, -++ u8 genmask) -++{ -++ struct nft_table *table; -++ -++ list_for_each_entry(table, &net->nft.tables, list) { -++ if (be64_to_cpu(nla_get_be64(nla)) == table->handle && -++ nft_active_genmask(table, genmask)) -++ return table; -++ } -++ return NULL; -++} -++ -+ static struct nft_table *nf_tables_table_lookup(const struct net *net, -+ const struct nlattr *nla, -+ u8 family, u8 genmask) -+@@ -392,6 +407,22 @@ static struct nft_table *nf_tables_table -+ return ERR_PTR(-ENOENT); -+ } -+ -++static struct nft_table *nf_tables_table_lookup_byhandle(const struct net *net, -++ const struct nlattr *nla, -++ u8 genmask) -++{ -++ struct nft_table *table; -++ -++ if (nla == NULL) -++ return ERR_PTR(-EINVAL); -++ -++ table = nft_table_lookup_byhandle(net, nla, genmask); -++ if (table != NULL) -++ return table; -++ -++ return ERR_PTR(-ENOENT); -++} -++ -+ static inline u64 nf_tables_alloc_handle(struct nft_table *table) -+ { -+ return ++table->hgenerator; -+@@ -438,6 +469,7 @@ static const struct nla_policy nft_table -+ [NFTA_TABLE_NAME] = { .type = NLA_STRING, -+ .len = NFT_TABLE_MAXNAMELEN - 1 }, -+ [NFTA_TABLE_FLAGS] = { .type = NLA_U32 }, -++ [NFTA_TABLE_HANDLE] = { .type = NLA_U64 }, -+ }; -+ -+ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net, -+@@ -459,7 +491,9 @@ static int nf_tables_fill_table_info(str -+ -+ if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) || -+ nla_put_be32(skb, NFTA_TABLE_FLAGS, htonl(table->flags)) || -+- nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use))) -++ nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)) || -++ nla_put_be64(skb, NFTA_TABLE_HANDLE, cpu_to_be64(table->handle), -++ NFTA_TABLE_PAD)) -+ goto nla_put_failure; -+ -+ nlmsg_end(skb, nlh); -+@@ -718,6 +752,7 @@ static int nf_tables_newtable(struct net -+ INIT_LIST_HEAD(&table->flowtables); -+ table->family = family; -+ table->flags = flags; -++ table->handle = ++table_handle; -+ -+ nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla); -+ err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE); -+@@ -835,11 +870,18 @@ static int nf_tables_deltable(struct net -+ struct nft_ctx ctx; -+ -+ nft_ctx_init(&ctx, net, skb, nlh, 0, NULL, NULL, nla); -+- if (family == AF_UNSPEC || nla[NFTA_TABLE_NAME] == NULL) -++ if (family == AF_UNSPEC || -++ (!nla[NFTA_TABLE_NAME] && !nla[NFTA_TABLE_HANDLE])) -+ return nft_flush(&ctx, family); -+ -+- table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], family, -+- genmask); -++ if (nla[NFTA_TABLE_HANDLE]) -++ table = nf_tables_table_lookup_byhandle(net, -++ nla[NFTA_TABLE_HANDLE], -++ genmask); -++ else -++ table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], -++ family, genmask); -++ -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+@@ -1596,6 +1638,7 @@ static int nf_tables_delchain(struct net -+ struct nft_rule *rule; -+ int family = nfmsg->nfgen_family; -+ struct nft_ctx ctx; -++ u64 handle; -+ u32 use; -+ int err; -+ -+@@ -1604,7 +1647,12 @@ static int nf_tables_delchain(struct net -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+- chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], genmask); -++ if (nla[NFTA_CHAIN_HANDLE]) { -++ handle = be64_to_cpu(nla_get_be64(nla[NFTA_CHAIN_HANDLE])); -++ chain = nf_tables_chain_lookup_byhandle(table, handle, genmask); -++ } else { -++ chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], genmask); -++ } -+ if (IS_ERR(chain)) -+ return PTR_ERR(chain); -+ -+@@ -2579,6 +2627,7 @@ static const struct nla_policy nft_set_p -+ [NFTA_SET_USERDATA] = { .type = NLA_BINARY, -+ .len = NFT_USERDATA_MAXLEN }, -+ [NFTA_SET_OBJ_TYPE] = { .type = NLA_U32 }, -++ [NFTA_SET_HANDLE] = { .type = NLA_U64 }, -+ }; -+ -+ static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = { -+@@ -2622,6 +2671,22 @@ static struct nft_set *nf_tables_set_loo -+ return ERR_PTR(-ENOENT); -+ } -+ -++static struct nft_set *nf_tables_set_lookup_byhandle(const struct nft_table *table, -++ const struct nlattr *nla, u8 genmask) -++{ -++ struct nft_set *set; -++ -++ if (nla == NULL) -++ return ERR_PTR(-EINVAL); -++ -++ list_for_each_entry(set, &table->sets, list) { -++ if (be64_to_cpu(nla_get_be64(nla)) == set->handle && -++ nft_active_genmask(set, genmask)) -++ return set; -++ } -++ return ERR_PTR(-ENOENT); -++} -++ -+ static struct nft_set *nf_tables_set_lookup_byid(const struct net *net, -+ const struct nlattr *nla, -+ u8 genmask) -+@@ -2738,6 +2803,9 @@ static int nf_tables_fill_set(struct sk_ -+ goto nla_put_failure; -+ if (nla_put_string(skb, NFTA_SET_NAME, set->name)) -+ goto nla_put_failure; -++ if (nla_put_be64(skb, NFTA_SET_HANDLE, cpu_to_be64(set->handle), -++ NFTA_SET_PAD)) -++ goto nla_put_failure; -+ if (set->flags != 0) -+ if (nla_put_be32(skb, NFTA_SET_FLAGS, htonl(set->flags))) -+ goto nla_put_failure; -+@@ -3149,6 +3217,7 @@ static int nf_tables_newset(struct net * -+ set->udata = udata; -+ set->timeout = timeout; -+ set->gc_int = gc_int; -++ set->handle = nf_tables_alloc_handle(table); -+ -+ err = ops->init(set, &desc, nla); -+ if (err < 0) -+@@ -3208,7 +3277,10 @@ static int nf_tables_delset(struct net * -+ if (err < 0) -+ return err; -+ -+- set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask); -++ if (nla[NFTA_SET_HANDLE]) -++ set = nf_tables_set_lookup_byhandle(ctx.table, nla[NFTA_SET_HANDLE], genmask); -++ else -++ set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask); -+ if (IS_ERR(set)) -+ return PTR_ERR(set); -+ -+@@ -4277,6 +4349,21 @@ struct nft_object *nf_tables_obj_lookup( -+ } -+ EXPORT_SYMBOL_GPL(nf_tables_obj_lookup); -+ -++struct nft_object *nf_tables_obj_lookup_byhandle(const struct nft_table *table, -++ const struct nlattr *nla, -++ u32 objtype, u8 genmask) -++{ -++ struct nft_object *obj; -++ -++ list_for_each_entry(obj, &table->objects, list) { -++ if (be64_to_cpu(nla_get_be64(nla)) == obj->handle && -++ objtype == obj->ops->type->type && -++ nft_active_genmask(obj, genmask)) -++ return obj; -++ } -++ return ERR_PTR(-ENOENT); -++} -++ -+ static const struct nla_policy nft_obj_policy[NFTA_OBJ_MAX + 1] = { -+ [NFTA_OBJ_TABLE] = { .type = NLA_STRING, -+ .len = NFT_TABLE_MAXNAMELEN - 1 }, -+@@ -4284,6 +4371,7 @@ static const struct nla_policy nft_obj_p -+ .len = NFT_OBJ_MAXNAMELEN - 1 }, -+ [NFTA_OBJ_TYPE] = { .type = NLA_U32 }, -+ [NFTA_OBJ_DATA] = { .type = NLA_NESTED }, -++ [NFTA_OBJ_HANDLE] = { .type = NLA_U64}, -+ }; -+ -+ static struct nft_object *nft_obj_init(const struct nft_ctx *ctx, -+@@ -4431,6 +4519,8 @@ static int nf_tables_newobj(struct net * -+ goto err1; -+ } -+ obj->table = table; -++ obj->handle = nf_tables_alloc_handle(table); -++ -+ obj->name = nla_strdup(nla[NFTA_OBJ_NAME], GFP_KERNEL); -+ if (!obj->name) { -+ err = -ENOMEM; -+@@ -4477,7 +4567,9 @@ static int nf_tables_fill_obj_info(struc -+ nla_put_string(skb, NFTA_OBJ_NAME, obj->name) || -+ nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) || -+ nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) || -+- nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset)) -++ nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset) || -++ nla_put_be64(skb, NFTA_OBJ_HANDLE, cpu_to_be64(obj->handle), -++ NFTA_OBJ_PAD)) -+ goto nla_put_failure; -+ -+ nlmsg_end(skb, nlh); -+@@ -4675,7 +4767,7 @@ static int nf_tables_delobj(struct net * -+ u32 objtype; -+ -+ if (!nla[NFTA_OBJ_TYPE] || -+- !nla[NFTA_OBJ_NAME]) -++ (!nla[NFTA_OBJ_NAME] && !nla[NFTA_OBJ_HANDLE])) -+ return -EINVAL; -+ -+ table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], family, -+@@ -4684,7 +4776,12 @@ static int nf_tables_delobj(struct net * -+ return PTR_ERR(table); -+ -+ objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE])); -+- obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask); -++ if (nla[NFTA_OBJ_HANDLE]) -++ obj = nf_tables_obj_lookup_byhandle(table, nla[NFTA_OBJ_HANDLE], -++ objtype, genmask); -++ else -++ obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], -++ objtype, genmask); -+ if (IS_ERR(obj)) -+ return PTR_ERR(obj); -+ if (obj->use > 0) -+@@ -4756,6 +4853,7 @@ static const struct nla_policy nft_flowt -+ [NFTA_FLOWTABLE_NAME] = { .type = NLA_STRING, -+ .len = NFT_NAME_MAXLEN - 1 }, -+ [NFTA_FLOWTABLE_HOOK] = { .type = NLA_NESTED }, -++ [NFTA_FLOWTABLE_HANDLE] = { .type = NLA_U64 }, -+ }; -+ -+ struct nft_flowtable *nf_tables_flowtable_lookup(const struct nft_table *table, -+@@ -4773,6 +4871,20 @@ struct nft_flowtable *nf_tables_flowtabl -+ } -+ EXPORT_SYMBOL_GPL(nf_tables_flowtable_lookup); -+ -++struct nft_flowtable * -++nf_tables_flowtable_lookup_byhandle(const struct nft_table *table, -++ const struct nlattr *nla, u8 genmask) -++{ -++ struct nft_flowtable *flowtable; -++ -++ list_for_each_entry(flowtable, &table->flowtables, list) { -++ if (be64_to_cpu(nla_get_be64(nla)) == flowtable->handle && -++ nft_active_genmask(flowtable, genmask)) -++ return flowtable; -++ } -++ return ERR_PTR(-ENOENT); -++} -++ -+ #define NFT_FLOWTABLE_DEVICE_MAX 8 -+ -+ static int nf_tables_parse_devices(const struct nft_ctx *ctx, -+@@ -4981,6 +5093,8 @@ static int nf_tables_newflowtable(struct -+ return -ENOMEM; -+ -+ flowtable->table = table; -++ flowtable->handle = nf_tables_alloc_handle(table); -++ -+ flowtable->name = nla_strdup(nla[NFTA_FLOWTABLE_NAME], GFP_KERNEL); -+ if (!flowtable->name) { -+ err = -ENOMEM; -+@@ -5055,8 +5169,14 @@ static int nf_tables_delflowtable(struct -+ if (IS_ERR(table)) -+ return PTR_ERR(table); -+ -+- flowtable = nf_tables_flowtable_lookup(table, nla[NFTA_FLOWTABLE_NAME], -+- genmask); -++ if (nla[NFTA_FLOWTABLE_HANDLE]) -++ flowtable = nf_tables_flowtable_lookup_byhandle(table, -++ nla[NFTA_FLOWTABLE_HANDLE], -++ genmask); -++ else -++ flowtable = nf_tables_flowtable_lookup(table, -++ nla[NFTA_FLOWTABLE_NAME], -++ genmask); -+ if (IS_ERR(flowtable)) -+ return PTR_ERR(flowtable); -+ if (flowtable->use > 0) -+@@ -5089,7 +5209,9 @@ static int nf_tables_fill_flowtable_info -+ -+ if (nla_put_string(skb, NFTA_FLOWTABLE_TABLE, flowtable->table->name) || -+ nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) || -+- nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use))) -++ nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use)) || -++ nla_put_be64(skb, NFTA_FLOWTABLE_HANDLE, cpu_to_be64(flowtable->handle), -++ NFTA_FLOWTABLE_PAD)) -+ goto nla_put_failure; -+ -+ nest = nla_nest_start(skb, NFTA_FLOWTABLE_HOOK); -diff --git a/target/linux/generic/backport-4.14/345-v4.16-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch b/target/linux/generic/backport-4.14/345-v4.16-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch -new file mode 100644 -index 0000000000..331f22d19a ---- /dev/null -+++ b/target/linux/generic/backport-4.14/345-v4.16-netfilter-nf_flow_offload-fix-use-after-free-and-a-r.patch -@@ -0,0 +1,95 @@ -+From: Felix Fietkau -+Date: Wed, 7 Feb 2018 09:23:25 +0100 -+Subject: [PATCH] netfilter: nf_flow_offload: fix use-after-free and a resource -+ leak -+ -+flow_offload_del frees the flow, so all associated resource must be -+freed before. -+ -+Since the ct entry in struct flow_offload_entry was allocated by -+flow_offload_alloc, it should be freed by flow_offload_free to take care -+of the error handling path when flow_offload_add fails. -+ -+While at it, make flow_offload_del static, since it should never be -+called directly, only from the gc step -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -90,7 +90,6 @@ struct flow_offload *flow_offload_alloc( -+ void flow_offload_free(struct flow_offload *flow); -+ -+ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow); -+-void flow_offload_del(struct nf_flowtable *flow_table, struct flow_offload *flow); -+ struct flow_offload_tuple_rhash *flow_offload_lookup(struct nf_flowtable *flow_table, -+ struct flow_offload_tuple *tuple); -+ int nf_flow_table_iterate(struct nf_flowtable *flow_table, -+--- a/net/netfilter/nf_flow_table.c -++++ b/net/netfilter/nf_flow_table.c -+@@ -125,7 +125,9 @@ void flow_offload_free(struct flow_offlo -+ dst_release(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_cache); -+ dst_release(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_cache); -+ e = container_of(flow, struct flow_offload_entry, flow); -+- kfree(e); -++ nf_ct_delete(e->ct, 0, 0); -++ nf_ct_put(e->ct); -++ kfree_rcu(e, rcu_head); -+ } -+ EXPORT_SYMBOL_GPL(flow_offload_free); -+ -+@@ -149,11 +151,9 @@ int flow_offload_add(struct nf_flowtable -+ } -+ EXPORT_SYMBOL_GPL(flow_offload_add); -+ -+-void flow_offload_del(struct nf_flowtable *flow_table, -+- struct flow_offload *flow) -++static void flow_offload_del(struct nf_flowtable *flow_table, -++ struct flow_offload *flow) -+ { -+- struct flow_offload_entry *e; -+- -+ rhashtable_remove_fast(&flow_table->rhashtable, -+ &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node, -+ *flow_table->type->params); -+@@ -161,10 +161,8 @@ void flow_offload_del(struct nf_flowtabl -+ &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].node, -+ *flow_table->type->params); -+ -+- e = container_of(flow, struct flow_offload_entry, flow); -+- kfree_rcu(e, rcu_head); -++ flow_offload_free(flow); -+ } -+-EXPORT_SYMBOL_GPL(flow_offload_del); -+ -+ struct flow_offload_tuple_rhash * -+ flow_offload_lookup(struct nf_flowtable *flow_table, -+@@ -175,15 +173,6 @@ flow_offload_lookup(struct nf_flowtable -+ } -+ EXPORT_SYMBOL_GPL(flow_offload_lookup); -+ -+-static void nf_flow_release_ct(const struct flow_offload *flow) -+-{ -+- struct flow_offload_entry *e; -+- -+- e = container_of(flow, struct flow_offload_entry, flow); -+- nf_ct_delete(e->ct, 0, 0); -+- nf_ct_put(e->ct); -+-} -+- -+ int nf_flow_table_iterate(struct nf_flowtable *flow_table, -+ void (*iter)(struct flow_offload *flow, void *data), -+ void *data) -+@@ -259,10 +248,8 @@ static int nf_flow_offload_gc_step(struc -+ flow = container_of(tuplehash, struct flow_offload, tuplehash[0]); -+ -+ if (nf_flow_has_expired(flow) || -+- nf_flow_is_dying(flow)) { -++ nf_flow_is_dying(flow)) -+ flow_offload_del(flow_table, flow); -+- nf_flow_release_ct(flow); -+- } -+ } -+ out: -+ rhashtable_walk_stop(&hti); -diff --git a/target/linux/generic/backport-4.14/346-v4.16-netfilter-flowtable-infrastructure-depends-on-NETFIL.patch b/target/linux/generic/backport-4.14/346-v4.16-netfilter-flowtable-infrastructure-depends-on-NETFIL.patch -new file mode 100644 -index 0000000000..bb8c2d3e5a ---- /dev/null -+++ b/target/linux/generic/backport-4.14/346-v4.16-netfilter-flowtable-infrastructure-depends-on-NETFIL.patch -@@ -0,0 +1,73 @@ -+From: Pablo Neira Ayuso -+Date: Wed, 31 Jan 2018 18:13:39 +0100 -+Subject: [PATCH] netfilter: flowtable infrastructure depends on -+ NETFILTER_INGRESS -+ -+config NF_FLOW_TABLE depends on NETFILTER_INGRESS. If users forget to -+enable this toggle, flowtable registration fails with EOPNOTSUPP. -+ -+Moreover, turn 'select NF_FLOW_TABLE' in every flowtable family flavour -+into dependency instead, otherwise this new dependency on -+NETFILTER_INGRESS causes a warning. This also allows us to remove the -+explicit dependency between family flowtables <-> NF_TABLES and -+NF_CONNTRACK, given they depend on the NF_FLOW_TABLE core that already -+expresses the general dependencies for this new infrastructure. -+ -+Moreover, NF_FLOW_TABLE_INET depends on NF_FLOW_TABLE_IPV4 and -+NF_FLOWTABLE_IPV6, which already depends on NF_FLOW_TABLE. So we can get -+rid of direct dependency with NF_FLOW_TABLE. -+ -+In general, let's avoid 'select', it just makes things more complicated. -+ -+Reported-by: John Crispin -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/net/ipv4/netfilter/Kconfig -++++ b/net/ipv4/netfilter/Kconfig -+@@ -80,8 +80,7 @@ endif # NF_TABLES -+ -+ config NF_FLOW_TABLE_IPV4 -+ tristate "Netfilter flow table IPv4 module" -+- depends on NF_CONNTRACK && NF_TABLES -+- select NF_FLOW_TABLE -++ depends on NF_FLOW_TABLE -+ help -+ This option adds the flow table IPv4 support. -+ -+--- a/net/ipv6/netfilter/Kconfig -++++ b/net/ipv6/netfilter/Kconfig -+@@ -101,8 +101,7 @@ endif # NF_TABLES -+ -+ config NF_FLOW_TABLE_IPV6 -+ tristate "Netfilter flow table IPv6 module" -+- depends on NF_CONNTRACK && NF_TABLES -+- select NF_FLOW_TABLE -++ depends on NF_FLOW_TABLE -+ help -+ This option adds the flow table IPv6 support. -+ -+--- a/net/netfilter/Kconfig -++++ b/net/netfilter/Kconfig -+@@ -676,8 +676,8 @@ endif # NF_TABLES -+ -+ config NF_FLOW_TABLE_INET -+ tristate "Netfilter flow table mixed IPv4/IPv6 module" -+- depends on NF_FLOW_TABLE_IPV4 && NF_FLOW_TABLE_IPV6 -+- select NF_FLOW_TABLE -++ depends on NF_FLOW_TABLE_IPV4 -++ depends on NF_FLOW_TABLE_IPV6 -+ help -+ This option adds the flow table mixed IPv4/IPv6 support. -+ -+@@ -685,7 +685,9 @@ config NF_FLOW_TABLE_INET -+ -+ config NF_FLOW_TABLE -+ tristate "Netfilter flow table module" -+- depends on NF_CONNTRACK && NF_TABLES -++ depends on NETFILTER_INGRESS -++ depends on NF_CONNTRACK -++ depends on NF_TABLES -+ help -+ This option adds the flow table core infrastructure. -+ -diff --git a/target/linux/generic/backport-4.14/347-v4.16-netfilter-remove-duplicated-include.patch b/target/linux/generic/backport-4.14/347-v4.16-netfilter-remove-duplicated-include.patch -new file mode 100644 -index 0000000000..c8a0972725 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/347-v4.16-netfilter-remove-duplicated-include.patch -@@ -0,0 +1,29 @@ -+From: Wei Yongjun -+Date: Wed, 10 Jan 2018 13:06:46 +0000 -+Subject: [PATCH] netfilter: remove duplicated include -+ -+Signed-off-by: Wei Yongjun -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/net/ipv6/netfilter/nf_flow_table_ipv6.c -++++ b/net/ipv6/netfilter/nf_flow_table_ipv6.c -+@@ -5,7 +5,6 @@ -+ #include -+ #include -+ #include -+-#include -+ #include -+ #include -+ #include -+--- a/net/netfilter/nf_queue.c -++++ b/net/netfilter/nf_queue.c -+@@ -15,8 +15,6 @@ -+ #include -+ #include -+ #include -+-#include -+-#include -+ #include -+ #include -+ #include -diff --git a/target/linux/generic/backport-4.14/348-v4.18-netfilter-nf_flow_table-use-IP_CT_DIR_-values-for-FL.patch b/target/linux/generic/backport-4.14/348-v4.18-netfilter-nf_flow_table-use-IP_CT_DIR_-values-for-FL.patch -new file mode 100644 -index 0000000000..382b33c078 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/348-v4.18-netfilter-nf_flow_table-use-IP_CT_DIR_-values-for-FL.patch -@@ -0,0 +1,35 @@ -+From: Felix Fietkau -+Date: Fri, 16 Feb 2018 09:41:18 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: use IP_CT_DIR_* values for -+ FLOW_OFFLOAD_DIR_* -+ -+Simplifies further code cleanups -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -6,6 +6,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ -+ struct nf_flowtable; -+@@ -27,11 +28,10 @@ struct nf_flowtable { -+ }; -+ -+ enum flow_offload_tuple_dir { -+- FLOW_OFFLOAD_DIR_ORIGINAL, -+- FLOW_OFFLOAD_DIR_REPLY, -+- __FLOW_OFFLOAD_DIR_MAX = FLOW_OFFLOAD_DIR_REPLY, -++ FLOW_OFFLOAD_DIR_ORIGINAL = IP_CT_DIR_ORIGINAL, -++ FLOW_OFFLOAD_DIR_REPLY = IP_CT_DIR_REPLY, -++ FLOW_OFFLOAD_DIR_MAX = IP_CT_DIR_MAX -+ }; -+-#define FLOW_OFFLOAD_DIR_MAX (__FLOW_OFFLOAD_DIR_MAX + 1) -+ -+ struct flow_offload_tuple { -+ union { -diff --git a/target/linux/generic/backport-4.14/349-v4.18-netfilter-nf_flow_table-clean-up-flow_offload_alloc.patch b/target/linux/generic/backport-4.14/349-v4.18-netfilter-nf_flow_table-clean-up-flow_offload_alloc.patch -new file mode 100644 -index 0000000000..39ea757f04 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/349-v4.18-netfilter-nf_flow_table-clean-up-flow_offload_alloc.patch -@@ -0,0 +1,118 @@ -+From: Felix Fietkau -+Date: Fri, 16 Feb 2018 09:42:32 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: clean up flow_offload_alloc -+ -+Reduce code duplication and make it much easier to read -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/netfilter/nf_flow_table.c -++++ b/net/netfilter/nf_flow_table.c -+@@ -16,6 +16,38 @@ struct flow_offload_entry { -+ struct rcu_head rcu_head; -+ }; -+ -++static void -++flow_offload_fill_dir(struct flow_offload *flow, struct nf_conn *ct, -++ struct nf_flow_route *route, -++ enum flow_offload_tuple_dir dir) -++{ -++ struct flow_offload_tuple *ft = &flow->tuplehash[dir].tuple; -++ struct nf_conntrack_tuple *ctt = &ct->tuplehash[dir].tuple; -++ -++ ft->dir = dir; -++ -++ switch (ctt->src.l3num) { -++ case NFPROTO_IPV4: -++ ft->src_v4 = ctt->src.u3.in; -++ ft->dst_v4 = ctt->dst.u3.in; -++ break; -++ case NFPROTO_IPV6: -++ ft->src_v6 = ctt->src.u3.in6; -++ ft->dst_v6 = ctt->dst.u3.in6; -++ break; -++ } -++ -++ ft->l3proto = ctt->src.l3num; -++ ft->l4proto = ctt->dst.protonum; -++ ft->src_port = ctt->src.u.tcp.port; -++ ft->dst_port = ctt->dst.u.tcp.port; -++ -++ ft->iifidx = route->tuple[dir].ifindex; -++ ft->oifidx = route->tuple[!dir].ifindex; -++ -++ ft->dst_cache = route->tuple[dir].dst; -++} -++ -+ struct flow_offload * -+ flow_offload_alloc(struct nf_conn *ct, struct nf_flow_route *route) -+ { -+@@ -40,65 +72,8 @@ flow_offload_alloc(struct nf_conn *ct, s -+ -+ entry->ct = ct; -+ -+- switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num) { -+- case NFPROTO_IPV4: -+- flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_v4 = -+- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.in; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_v4 = -+- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.in; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_v4 = -+- ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.in; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_v4 = -+- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.in; -+- break; -+- case NFPROTO_IPV6: -+- flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_v6 = -+- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.in6; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_v6 = -+- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.in6; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_v6 = -+- ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.in6; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_v6 = -+- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.in6; -+- break; -+- } -+- -+- flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.l3proto = -+- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.l4proto = -+- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.l3proto = -+- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.l4proto = -+- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; -+- -+- flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_cache = -+- route->tuple[FLOW_OFFLOAD_DIR_ORIGINAL].dst; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_cache = -+- route->tuple[FLOW_OFFLOAD_DIR_REPLY].dst; -+- -+- flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_port = -+- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.tcp.port; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_port = -+- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.tcp.port; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_port = -+- ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.tcp.port; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_port = -+- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.tcp.port; -+- -+- flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dir = -+- FLOW_OFFLOAD_DIR_ORIGINAL; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dir = -+- FLOW_OFFLOAD_DIR_REPLY; -+- -+- flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.iifidx = -+- route->tuple[FLOW_OFFLOAD_DIR_ORIGINAL].ifindex; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.oifidx = -+- route->tuple[FLOW_OFFLOAD_DIR_REPLY].ifindex; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.iifidx = -+- route->tuple[FLOW_OFFLOAD_DIR_REPLY].ifindex; -+- flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.oifidx = -+- route->tuple[FLOW_OFFLOAD_DIR_ORIGINAL].ifindex; -++ flow_offload_fill_dir(flow, ct, route, FLOW_OFFLOAD_DIR_ORIGINAL); -++ flow_offload_fill_dir(flow, ct, route, FLOW_OFFLOAD_DIR_REPLY); -+ -+ if (ct->status & IPS_SRC_NAT) -+ flow->flags |= FLOW_OFFLOAD_SNAT; -diff --git a/target/linux/generic/backport-4.14/350-v4.18-ipv6-make-ip6_dst_mtu_forward-inline.patch b/target/linux/generic/backport-4.14/350-v4.18-ipv6-make-ip6_dst_mtu_forward-inline.patch -new file mode 100644 -index 0000000000..1c52cf51c6 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/350-v4.18-ipv6-make-ip6_dst_mtu_forward-inline.patch -@@ -0,0 +1,80 @@ -+From: Felix Fietkau -+Date: Fri, 16 Feb 2018 10:54:24 +0100 -+Subject: [PATCH] ipv6: make ip6_dst_mtu_forward inline -+ -+Removes a direct dependency on ipv6.ko -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/include/net/ip6_route.h -++++ b/include/net/ip6_route.h -+@@ -253,4 +253,26 @@ static inline bool rt6_duplicate_nexthop -+ ipv6_addr_equal(&a->rt6i_gateway, &b->rt6i_gateway) && -+ !lwtunnel_cmp_encap(a->dst.lwtstate, b->dst.lwtstate); -+ } -++ -++static inline unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst) -++{ -++ unsigned int mtu; -++ struct inet6_dev *idev; -++ -++ if (dst_metric_locked(dst, RTAX_MTU)) { -++ mtu = dst_metric_raw(dst, RTAX_MTU); -++ if (mtu) -++ return mtu; -++ } -++ -++ mtu = IPV6_MIN_MTU; -++ rcu_read_lock(); -++ idev = __in6_dev_get(dst->dev); -++ if (idev) -++ mtu = idev->cnf.mtu6; -++ rcu_read_unlock(); -++ -++ return mtu; -++} -++ -+ #endif -+--- a/include/net/ipv6.h -++++ b/include/net/ipv6.h -+@@ -860,8 +860,6 @@ static inline struct sk_buff *ip6_finish -+ &inet6_sk(sk)->cork); -+ } -+ -+-unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst); -+- -+ int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst, -+ struct flowi6 *fl6); -+ struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, struct flowi6 *fl6, -+--- a/net/ipv6/ip6_output.c -++++ b/net/ipv6/ip6_output.c -+@@ -381,28 +381,6 @@ static inline int ip6_forward_finish(str -+ return dst_output(net, sk, skb); -+ } -+ -+-unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst) -+-{ -+- unsigned int mtu; -+- struct inet6_dev *idev; -+- -+- if (dst_metric_locked(dst, RTAX_MTU)) { -+- mtu = dst_metric_raw(dst, RTAX_MTU); -+- if (mtu) -+- return mtu; -+- } -+- -+- mtu = IPV6_MIN_MTU; -+- rcu_read_lock(); -+- idev = __in6_dev_get(dst->dev); -+- if (idev) -+- mtu = idev->cnf.mtu6; -+- rcu_read_unlock(); -+- -+- return mtu; -+-} -+-EXPORT_SYMBOL_GPL(ip6_dst_mtu_forward); -+- -+ static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu) -+ { -+ if (skb->len <= mtu) -diff --git a/target/linux/generic/backport-4.14/351-v4.18-netfilter-nf_flow_table-cache-mtu-in-struct-flow_off.patch b/target/linux/generic/backport-4.14/351-v4.18-netfilter-nf_flow_table-cache-mtu-in-struct-flow_off.patch -new file mode 100644 -index 0000000000..e2015e72ac ---- /dev/null -+++ b/target/linux/generic/backport-4.14/351-v4.18-netfilter-nf_flow_table-cache-mtu-in-struct-flow_off.patch -@@ -0,0 +1,145 @@ -+From: Felix Fietkau -+Date: Fri, 16 Feb 2018 10:57:23 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: cache mtu in struct -+ flow_offload_tuple -+ -+Reduces the number of cache lines touched in the offload forwarding path -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -55,6 +55,8 @@ struct flow_offload_tuple { -+ -+ int oifidx; -+ -++ u16 mtu; -++ -+ struct dst_entry *dst_cache; -+ }; -+ -+--- a/net/ipv4/netfilter/nf_flow_table_ipv4.c -++++ b/net/ipv4/netfilter/nf_flow_table_ipv4.c -+@@ -177,7 +177,7 @@ static int nf_flow_tuple_ip(struct sk_bu -+ } -+ -+ /* Based on ip_exceeds_mtu(). */ -+-static bool __nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) -++static bool nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) -+ { -+ if (skb->len <= mtu) -+ return false; -+@@ -191,17 +191,6 @@ static bool __nf_flow_exceeds_mtu(const -+ return true; -+ } -+ -+-static bool nf_flow_exceeds_mtu(struct sk_buff *skb, const struct rtable *rt) -+-{ -+- u32 mtu; -+- -+- mtu = ip_dst_mtu_maybe_forward(&rt->dst, true); -+- if (__nf_flow_exceeds_mtu(skb, mtu)) -+- return true; -+- -+- return false; -+-} -+- -+ unsigned int -+ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, -+ const struct nf_hook_state *state) -+@@ -232,9 +221,9 @@ nf_flow_offload_ip_hook(void *priv, stru -+ -+ dir = tuplehash->tuple.dir; -+ flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); -+- -+ rt = (const struct rtable *)flow->tuplehash[dir].tuple.dst_cache; -+- if (unlikely(nf_flow_exceeds_mtu(skb, rt))) -++ -++ if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu))) -+ return NF_ACCEPT; -+ -+ if (skb_try_make_writable(skb, sizeof(*iph))) -+--- a/net/ipv6/netfilter/nf_flow_table_ipv6.c -++++ b/net/ipv6/netfilter/nf_flow_table_ipv6.c -+@@ -173,7 +173,7 @@ static int nf_flow_tuple_ipv6(struct sk_ -+ } -+ -+ /* Based on ip_exceeds_mtu(). */ -+-static bool __nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) -++static bool nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) -+ { -+ if (skb->len <= mtu) -+ return false; -+@@ -184,17 +184,6 @@ static bool __nf_flow_exceeds_mtu(const -+ return true; -+ } -+ -+-static bool nf_flow_exceeds_mtu(struct sk_buff *skb, const struct rt6_info *rt) -+-{ -+- u32 mtu; -+- -+- mtu = ip6_dst_mtu_forward(&rt->dst); -+- if (__nf_flow_exceeds_mtu(skb, mtu)) -+- return true; -+- -+- return false; -+-} -+- -+ unsigned int -+ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, -+ const struct nf_hook_state *state) -+@@ -225,9 +214,9 @@ nf_flow_offload_ipv6_hook(void *priv, st -+ -+ dir = tuplehash->tuple.dir; -+ flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); -+- -+ rt = (struct rt6_info *)flow->tuplehash[dir].tuple.dst_cache; -+- if (unlikely(nf_flow_exceeds_mtu(skb, rt))) -++ -++ if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu))) -+ return NF_ACCEPT; -+ -+ if (skb_try_make_writable(skb, sizeof(*ip6h))) -+--- a/net/netfilter/nf_flow_table.c -++++ b/net/netfilter/nf_flow_table.c -+@@ -4,6 +4,8 @@ -+ #include -+ #include -+ #include -++#include -++#include -+ #include -+ #include -+ #include -+@@ -23,6 +25,7 @@ flow_offload_fill_dir(struct flow_offloa -+ { -+ struct flow_offload_tuple *ft = &flow->tuplehash[dir].tuple; -+ struct nf_conntrack_tuple *ctt = &ct->tuplehash[dir].tuple; -++ struct dst_entry *dst = route->tuple[dir].dst; -+ -+ ft->dir = dir; -+ -+@@ -30,10 +33,12 @@ flow_offload_fill_dir(struct flow_offloa -+ case NFPROTO_IPV4: -+ ft->src_v4 = ctt->src.u3.in; -+ ft->dst_v4 = ctt->dst.u3.in; -++ ft->mtu = ip_dst_mtu_maybe_forward(dst, true); -+ break; -+ case NFPROTO_IPV6: -+ ft->src_v6 = ctt->src.u3.in6; -+ ft->dst_v6 = ctt->dst.u3.in6; -++ ft->mtu = ip6_dst_mtu_forward(dst); -+ break; -+ } -+ -+@@ -44,8 +49,7 @@ flow_offload_fill_dir(struct flow_offloa -+ -+ ft->iifidx = route->tuple[dir].ifindex; -+ ft->oifidx = route->tuple[!dir].ifindex; -+- -+- ft->dst_cache = route->tuple[dir].dst; -++ ft->dst_cache = dst; -+ } -+ -+ struct flow_offload * -diff --git a/target/linux/generic/backport-4.14/352-v4.18-netfilter-nf_flow_table-rename-nf_flow_table.c-to-nf.patch b/target/linux/generic/backport-4.14/352-v4.18-netfilter-nf_flow_table-rename-nf_flow_table.c-to-nf.patch -new file mode 100644 -index 0000000000..5df56dd643 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/352-v4.18-netfilter-nf_flow_table-rename-nf_flow_table.c-to-nf.patch -@@ -0,0 +1,952 @@ -+From: Felix Fietkau -+Date: Fri, 16 Feb 2018 11:08:47 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: rename nf_flow_table.c to -+ nf_flow_table_core.c -+ -+Preparation for adding more code to the same module -+ -+Signed-off-by: Felix Fietkau -+--- -+ rename net/netfilter/{nf_flow_table.c => nf_flow_table_core.c} (100%) -+ -+--- a/net/netfilter/Makefile -++++ b/net/netfilter/Makefile -+@@ -113,6 +113,8 @@ obj-$(CONFIG_NFT_FWD_NETDEV) += nft_fwd_ -+ -+ # flow table infrastructure -+ obj-$(CONFIG_NF_FLOW_TABLE) += nf_flow_table.o -++nf_flow_table-objs := nf_flow_table_core.o -++ -+ obj-$(CONFIG_NF_FLOW_TABLE_INET) += nf_flow_table_inet.o -+ -+ # generic X tables -+--- a/net/netfilter/nf_flow_table.c -++++ /dev/null -+@@ -1,462 +0,0 @@ -+-#include -+-#include -+-#include -+-#include -+-#include -+-#include -+-#include -+-#include -+-#include -+-#include -+-#include -+-#include -+-#include -+- -+-struct flow_offload_entry { -+- struct flow_offload flow; -+- struct nf_conn *ct; -+- struct rcu_head rcu_head; -+-}; -+- -+-static void -+-flow_offload_fill_dir(struct flow_offload *flow, struct nf_conn *ct, -+- struct nf_flow_route *route, -+- enum flow_offload_tuple_dir dir) -+-{ -+- struct flow_offload_tuple *ft = &flow->tuplehash[dir].tuple; -+- struct nf_conntrack_tuple *ctt = &ct->tuplehash[dir].tuple; -+- struct dst_entry *dst = route->tuple[dir].dst; -+- -+- ft->dir = dir; -+- -+- switch (ctt->src.l3num) { -+- case NFPROTO_IPV4: -+- ft->src_v4 = ctt->src.u3.in; -+- ft->dst_v4 = ctt->dst.u3.in; -+- ft->mtu = ip_dst_mtu_maybe_forward(dst, true); -+- break; -+- case NFPROTO_IPV6: -+- ft->src_v6 = ctt->src.u3.in6; -+- ft->dst_v6 = ctt->dst.u3.in6; -+- ft->mtu = ip6_dst_mtu_forward(dst); -+- break; -+- } -+- -+- ft->l3proto = ctt->src.l3num; -+- ft->l4proto = ctt->dst.protonum; -+- ft->src_port = ctt->src.u.tcp.port; -+- ft->dst_port = ctt->dst.u.tcp.port; -+- -+- ft->iifidx = route->tuple[dir].ifindex; -+- ft->oifidx = route->tuple[!dir].ifindex; -+- ft->dst_cache = dst; -+-} -+- -+-struct flow_offload * -+-flow_offload_alloc(struct nf_conn *ct, struct nf_flow_route *route) -+-{ -+- struct flow_offload_entry *entry; -+- struct flow_offload *flow; -+- -+- if (unlikely(nf_ct_is_dying(ct) || -+- !atomic_inc_not_zero(&ct->ct_general.use))) -+- return NULL; -+- -+- entry = kzalloc(sizeof(*entry), GFP_ATOMIC); -+- if (!entry) -+- goto err_ct_refcnt; -+- -+- flow = &entry->flow; -+- -+- if (!dst_hold_safe(route->tuple[FLOW_OFFLOAD_DIR_ORIGINAL].dst)) -+- goto err_dst_cache_original; -+- -+- if (!dst_hold_safe(route->tuple[FLOW_OFFLOAD_DIR_REPLY].dst)) -+- goto err_dst_cache_reply; -+- -+- entry->ct = ct; -+- -+- flow_offload_fill_dir(flow, ct, route, FLOW_OFFLOAD_DIR_ORIGINAL); -+- flow_offload_fill_dir(flow, ct, route, FLOW_OFFLOAD_DIR_REPLY); -+- -+- if (ct->status & IPS_SRC_NAT) -+- flow->flags |= FLOW_OFFLOAD_SNAT; -+- else if (ct->status & IPS_DST_NAT) -+- flow->flags |= FLOW_OFFLOAD_DNAT; -+- -+- return flow; -+- -+-err_dst_cache_reply: -+- dst_release(route->tuple[FLOW_OFFLOAD_DIR_ORIGINAL].dst); -+-err_dst_cache_original: -+- kfree(entry); -+-err_ct_refcnt: -+- nf_ct_put(ct); -+- -+- return NULL; -+-} -+-EXPORT_SYMBOL_GPL(flow_offload_alloc); -+- -+-void flow_offload_free(struct flow_offload *flow) -+-{ -+- struct flow_offload_entry *e; -+- -+- dst_release(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_cache); -+- dst_release(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_cache); -+- e = container_of(flow, struct flow_offload_entry, flow); -+- nf_ct_delete(e->ct, 0, 0); -+- nf_ct_put(e->ct); -+- kfree_rcu(e, rcu_head); -+-} -+-EXPORT_SYMBOL_GPL(flow_offload_free); -+- -+-void flow_offload_dead(struct flow_offload *flow) -+-{ -+- flow->flags |= FLOW_OFFLOAD_DYING; -+-} -+-EXPORT_SYMBOL_GPL(flow_offload_dead); -+- -+-int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow) -+-{ -+- flow->timeout = (u32)jiffies; -+- -+- rhashtable_insert_fast(&flow_table->rhashtable, -+- &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node, -+- *flow_table->type->params); -+- rhashtable_insert_fast(&flow_table->rhashtable, -+- &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].node, -+- *flow_table->type->params); -+- return 0; -+-} -+-EXPORT_SYMBOL_GPL(flow_offload_add); -+- -+-static void flow_offload_del(struct nf_flowtable *flow_table, -+- struct flow_offload *flow) -+-{ -+- rhashtable_remove_fast(&flow_table->rhashtable, -+- &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node, -+- *flow_table->type->params); -+- rhashtable_remove_fast(&flow_table->rhashtable, -+- &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].node, -+- *flow_table->type->params); -+- -+- flow_offload_free(flow); -+-} -+- -+-struct flow_offload_tuple_rhash * -+-flow_offload_lookup(struct nf_flowtable *flow_table, -+- struct flow_offload_tuple *tuple) -+-{ -+- return rhashtable_lookup_fast(&flow_table->rhashtable, tuple, -+- *flow_table->type->params); -+-} -+-EXPORT_SYMBOL_GPL(flow_offload_lookup); -+- -+-int nf_flow_table_iterate(struct nf_flowtable *flow_table, -+- void (*iter)(struct flow_offload *flow, void *data), -+- void *data) -+-{ -+- struct flow_offload_tuple_rhash *tuplehash; -+- struct rhashtable_iter hti; -+- struct flow_offload *flow; -+- int err; -+- -+- err = rhashtable_walk_init(&flow_table->rhashtable, &hti, GFP_KERNEL); -+- if (err) -+- return err; -+- -+- rhashtable_walk_start(&hti); -+- -+- while ((tuplehash = rhashtable_walk_next(&hti))) { -+- if (IS_ERR(tuplehash)) { -+- err = PTR_ERR(tuplehash); -+- if (err != -EAGAIN) -+- goto out; -+- -+- continue; -+- } -+- if (tuplehash->tuple.dir) -+- continue; -+- -+- flow = container_of(tuplehash, struct flow_offload, tuplehash[0]); -+- -+- iter(flow, data); -+- } -+-out: -+- rhashtable_walk_stop(&hti); -+- rhashtable_walk_exit(&hti); -+- -+- return err; -+-} -+-EXPORT_SYMBOL_GPL(nf_flow_table_iterate); -+- -+-static inline bool nf_flow_has_expired(const struct flow_offload *flow) -+-{ -+- return (__s32)(flow->timeout - (u32)jiffies) <= 0; -+-} -+- -+-static inline bool nf_flow_is_dying(const struct flow_offload *flow) -+-{ -+- return flow->flags & FLOW_OFFLOAD_DYING; -+-} -+- -+-static int nf_flow_offload_gc_step(struct nf_flowtable *flow_table) -+-{ -+- struct flow_offload_tuple_rhash *tuplehash; -+- struct rhashtable_iter hti; -+- struct flow_offload *flow; -+- int err; -+- -+- err = rhashtable_walk_init(&flow_table->rhashtable, &hti, GFP_KERNEL); -+- if (err) -+- return 0; -+- -+- rhashtable_walk_start(&hti); -+- -+- while ((tuplehash = rhashtable_walk_next(&hti))) { -+- if (IS_ERR(tuplehash)) { -+- err = PTR_ERR(tuplehash); -+- if (err != -EAGAIN) -+- goto out; -+- -+- continue; -+- } -+- if (tuplehash->tuple.dir) -+- continue; -+- -+- flow = container_of(tuplehash, struct flow_offload, tuplehash[0]); -+- -+- if (nf_flow_has_expired(flow) || -+- nf_flow_is_dying(flow)) -+- flow_offload_del(flow_table, flow); -+- } -+-out: -+- rhashtable_walk_stop(&hti); -+- rhashtable_walk_exit(&hti); -+- -+- return 1; -+-} -+- -+-void nf_flow_offload_work_gc(struct work_struct *work) -+-{ -+- struct nf_flowtable *flow_table; -+- -+- flow_table = container_of(work, struct nf_flowtable, gc_work.work); -+- nf_flow_offload_gc_step(flow_table); -+- queue_delayed_work(system_power_efficient_wq, &flow_table->gc_work, HZ); -+-} -+-EXPORT_SYMBOL_GPL(nf_flow_offload_work_gc); -+- -+-static u32 flow_offload_hash(const void *data, u32 len, u32 seed) -+-{ -+- const struct flow_offload_tuple *tuple = data; -+- -+- return jhash(tuple, offsetof(struct flow_offload_tuple, dir), seed); -+-} -+- -+-static u32 flow_offload_hash_obj(const void *data, u32 len, u32 seed) -+-{ -+- const struct flow_offload_tuple_rhash *tuplehash = data; -+- -+- return jhash(&tuplehash->tuple, offsetof(struct flow_offload_tuple, dir), seed); -+-} -+- -+-static int flow_offload_hash_cmp(struct rhashtable_compare_arg *arg, -+- const void *ptr) -+-{ -+- const struct flow_offload_tuple *tuple = arg->key; -+- const struct flow_offload_tuple_rhash *x = ptr; -+- -+- if (memcmp(&x->tuple, tuple, offsetof(struct flow_offload_tuple, dir))) -+- return 1; -+- -+- return 0; -+-} -+- -+-const struct rhashtable_params nf_flow_offload_rhash_params = { -+- .head_offset = offsetof(struct flow_offload_tuple_rhash, node), -+- .hashfn = flow_offload_hash, -+- .obj_hashfn = flow_offload_hash_obj, -+- .obj_cmpfn = flow_offload_hash_cmp, -+- .automatic_shrinking = true, -+-}; -+-EXPORT_SYMBOL_GPL(nf_flow_offload_rhash_params); -+- -+-static int nf_flow_nat_port_tcp(struct sk_buff *skb, unsigned int thoff, -+- __be16 port, __be16 new_port) -+-{ -+- struct tcphdr *tcph; -+- -+- if (!pskb_may_pull(skb, thoff + sizeof(*tcph)) || -+- skb_try_make_writable(skb, thoff + sizeof(*tcph))) -+- return -1; -+- -+- tcph = (void *)(skb_network_header(skb) + thoff); -+- inet_proto_csum_replace2(&tcph->check, skb, port, new_port, true); -+- -+- return 0; -+-} -+- -+-static int nf_flow_nat_port_udp(struct sk_buff *skb, unsigned int thoff, -+- __be16 port, __be16 new_port) -+-{ -+- struct udphdr *udph; -+- -+- if (!pskb_may_pull(skb, thoff + sizeof(*udph)) || -+- skb_try_make_writable(skb, thoff + sizeof(*udph))) -+- return -1; -+- -+- udph = (void *)(skb_network_header(skb) + thoff); -+- if (udph->check || skb->ip_summed == CHECKSUM_PARTIAL) { -+- inet_proto_csum_replace2(&udph->check, skb, port, -+- new_port, true); -+- if (!udph->check) -+- udph->check = CSUM_MANGLED_0; -+- } -+- -+- return 0; -+-} -+- -+-static int nf_flow_nat_port(struct sk_buff *skb, unsigned int thoff, -+- u8 protocol, __be16 port, __be16 new_port) -+-{ -+- switch (protocol) { -+- case IPPROTO_TCP: -+- if (nf_flow_nat_port_tcp(skb, thoff, port, new_port) < 0) -+- return NF_DROP; -+- break; -+- case IPPROTO_UDP: -+- if (nf_flow_nat_port_udp(skb, thoff, port, new_port) < 0) -+- return NF_DROP; -+- break; -+- } -+- -+- return 0; -+-} -+- -+-int nf_flow_snat_port(const struct flow_offload *flow, -+- struct sk_buff *skb, unsigned int thoff, -+- u8 protocol, enum flow_offload_tuple_dir dir) -+-{ -+- struct flow_ports *hdr; -+- __be16 port, new_port; -+- -+- if (!pskb_may_pull(skb, thoff + sizeof(*hdr)) || -+- skb_try_make_writable(skb, thoff + sizeof(*hdr))) -+- return -1; -+- -+- hdr = (void *)(skb_network_header(skb) + thoff); -+- -+- switch (dir) { -+- case FLOW_OFFLOAD_DIR_ORIGINAL: -+- port = hdr->source; -+- new_port = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_port; -+- hdr->source = new_port; -+- break; -+- case FLOW_OFFLOAD_DIR_REPLY: -+- port = hdr->dest; -+- new_port = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_port; -+- hdr->dest = new_port; -+- break; -+- default: -+- return -1; -+- } -+- -+- return nf_flow_nat_port(skb, thoff, protocol, port, new_port); -+-} -+-EXPORT_SYMBOL_GPL(nf_flow_snat_port); -+- -+-int nf_flow_dnat_port(const struct flow_offload *flow, -+- struct sk_buff *skb, unsigned int thoff, -+- u8 protocol, enum flow_offload_tuple_dir dir) -+-{ -+- struct flow_ports *hdr; -+- __be16 port, new_port; -+- -+- if (!pskb_may_pull(skb, thoff + sizeof(*hdr)) || -+- skb_try_make_writable(skb, thoff + sizeof(*hdr))) -+- return -1; -+- -+- hdr = (void *)(skb_network_header(skb) + thoff); -+- -+- switch (dir) { -+- case FLOW_OFFLOAD_DIR_ORIGINAL: -+- port = hdr->dest; -+- new_port = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_port; -+- hdr->dest = new_port; -+- break; -+- case FLOW_OFFLOAD_DIR_REPLY: -+- port = hdr->source; -+- new_port = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_port; -+- hdr->source = new_port; -+- break; -+- default: -+- return -1; -+- } -+- -+- return nf_flow_nat_port(skb, thoff, protocol, port, new_port); -+-} -+-EXPORT_SYMBOL_GPL(nf_flow_dnat_port); -+- -+-static void nf_flow_table_do_cleanup(struct flow_offload *flow, void *data) -+-{ -+- struct net_device *dev = data; -+- -+- if (dev && flow->tuplehash[0].tuple.iifidx != dev->ifindex) -+- return; -+- -+- flow_offload_dead(flow); -+-} -+- -+-static void nf_flow_table_iterate_cleanup(struct nf_flowtable *flowtable, -+- void *data) -+-{ -+- nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, data); -+- flush_delayed_work(&flowtable->gc_work); -+-} -+- -+-void nf_flow_table_cleanup(struct net *net, struct net_device *dev) -+-{ -+- nft_flow_table_iterate(net, nf_flow_table_iterate_cleanup, dev); -+-} -+-EXPORT_SYMBOL_GPL(nf_flow_table_cleanup); -+- -+-void nf_flow_table_free(struct nf_flowtable *flow_table) -+-{ -+- nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL); -+- WARN_ON(!nf_flow_offload_gc_step(flow_table)); -+-} -+-EXPORT_SYMBOL_GPL(nf_flow_table_free); -+- -+-static int nf_flow_table_netdev_event(struct notifier_block *this, -+- unsigned long event, void *ptr) -+-{ -+- struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+- -+- if (event != NETDEV_DOWN) -+- return NOTIFY_DONE; -+- -+- nf_flow_table_cleanup(dev_net(dev), dev); -+- -+- return NOTIFY_DONE; -+-} -+- -+-static struct notifier_block flow_offload_netdev_notifier = { -+- .notifier_call = nf_flow_table_netdev_event, -+-}; -+- -+-static int __init nf_flow_table_module_init(void) -+-{ -+- return register_netdevice_notifier(&flow_offload_netdev_notifier); -+-} -+- -+-static void __exit nf_flow_table_module_exit(void) -+-{ -+- unregister_netdevice_notifier(&flow_offload_netdev_notifier); -+-} -+- -+-module_init(nf_flow_table_module_init); -+-module_exit(nf_flow_table_module_exit); -+- -+-MODULE_LICENSE("GPL"); -+-MODULE_AUTHOR("Pablo Neira Ayuso "); -+--- /dev/null -++++ b/net/netfilter/nf_flow_table_core.c -+@@ -0,0 +1,462 @@ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++struct flow_offload_entry { -++ struct flow_offload flow; -++ struct nf_conn *ct; -++ struct rcu_head rcu_head; -++}; -++ -++static void -++flow_offload_fill_dir(struct flow_offload *flow, struct nf_conn *ct, -++ struct nf_flow_route *route, -++ enum flow_offload_tuple_dir dir) -++{ -++ struct flow_offload_tuple *ft = &flow->tuplehash[dir].tuple; -++ struct nf_conntrack_tuple *ctt = &ct->tuplehash[dir].tuple; -++ struct dst_entry *dst = route->tuple[dir].dst; -++ -++ ft->dir = dir; -++ -++ switch (ctt->src.l3num) { -++ case NFPROTO_IPV4: -++ ft->src_v4 = ctt->src.u3.in; -++ ft->dst_v4 = ctt->dst.u3.in; -++ ft->mtu = ip_dst_mtu_maybe_forward(dst, true); -++ break; -++ case NFPROTO_IPV6: -++ ft->src_v6 = ctt->src.u3.in6; -++ ft->dst_v6 = ctt->dst.u3.in6; -++ ft->mtu = ip6_dst_mtu_forward(dst); -++ break; -++ } -++ -++ ft->l3proto = ctt->src.l3num; -++ ft->l4proto = ctt->dst.protonum; -++ ft->src_port = ctt->src.u.tcp.port; -++ ft->dst_port = ctt->dst.u.tcp.port; -++ -++ ft->iifidx = route->tuple[dir].ifindex; -++ ft->oifidx = route->tuple[!dir].ifindex; -++ ft->dst_cache = dst; -++} -++ -++struct flow_offload * -++flow_offload_alloc(struct nf_conn *ct, struct nf_flow_route *route) -++{ -++ struct flow_offload_entry *entry; -++ struct flow_offload *flow; -++ -++ if (unlikely(nf_ct_is_dying(ct) || -++ !atomic_inc_not_zero(&ct->ct_general.use))) -++ return NULL; -++ -++ entry = kzalloc(sizeof(*entry), GFP_ATOMIC); -++ if (!entry) -++ goto err_ct_refcnt; -++ -++ flow = &entry->flow; -++ -++ if (!dst_hold_safe(route->tuple[FLOW_OFFLOAD_DIR_ORIGINAL].dst)) -++ goto err_dst_cache_original; -++ -++ if (!dst_hold_safe(route->tuple[FLOW_OFFLOAD_DIR_REPLY].dst)) -++ goto err_dst_cache_reply; -++ -++ entry->ct = ct; -++ -++ flow_offload_fill_dir(flow, ct, route, FLOW_OFFLOAD_DIR_ORIGINAL); -++ flow_offload_fill_dir(flow, ct, route, FLOW_OFFLOAD_DIR_REPLY); -++ -++ if (ct->status & IPS_SRC_NAT) -++ flow->flags |= FLOW_OFFLOAD_SNAT; -++ else if (ct->status & IPS_DST_NAT) -++ flow->flags |= FLOW_OFFLOAD_DNAT; -++ -++ return flow; -++ -++err_dst_cache_reply: -++ dst_release(route->tuple[FLOW_OFFLOAD_DIR_ORIGINAL].dst); -++err_dst_cache_original: -++ kfree(entry); -++err_ct_refcnt: -++ nf_ct_put(ct); -++ -++ return NULL; -++} -++EXPORT_SYMBOL_GPL(flow_offload_alloc); -++ -++void flow_offload_free(struct flow_offload *flow) -++{ -++ struct flow_offload_entry *e; -++ -++ dst_release(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_cache); -++ dst_release(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_cache); -++ e = container_of(flow, struct flow_offload_entry, flow); -++ nf_ct_delete(e->ct, 0, 0); -++ nf_ct_put(e->ct); -++ kfree_rcu(e, rcu_head); -++} -++EXPORT_SYMBOL_GPL(flow_offload_free); -++ -++void flow_offload_dead(struct flow_offload *flow) -++{ -++ flow->flags |= FLOW_OFFLOAD_DYING; -++} -++EXPORT_SYMBOL_GPL(flow_offload_dead); -++ -++int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow) -++{ -++ flow->timeout = (u32)jiffies; -++ -++ rhashtable_insert_fast(&flow_table->rhashtable, -++ &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node, -++ *flow_table->type->params); -++ rhashtable_insert_fast(&flow_table->rhashtable, -++ &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].node, -++ *flow_table->type->params); -++ return 0; -++} -++EXPORT_SYMBOL_GPL(flow_offload_add); -++ -++static void flow_offload_del(struct nf_flowtable *flow_table, -++ struct flow_offload *flow) -++{ -++ rhashtable_remove_fast(&flow_table->rhashtable, -++ &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node, -++ *flow_table->type->params); -++ rhashtable_remove_fast(&flow_table->rhashtable, -++ &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].node, -++ *flow_table->type->params); -++ -++ flow_offload_free(flow); -++} -++ -++struct flow_offload_tuple_rhash * -++flow_offload_lookup(struct nf_flowtable *flow_table, -++ struct flow_offload_tuple *tuple) -++{ -++ return rhashtable_lookup_fast(&flow_table->rhashtable, tuple, -++ *flow_table->type->params); -++} -++EXPORT_SYMBOL_GPL(flow_offload_lookup); -++ -++int nf_flow_table_iterate(struct nf_flowtable *flow_table, -++ void (*iter)(struct flow_offload *flow, void *data), -++ void *data) -++{ -++ struct flow_offload_tuple_rhash *tuplehash; -++ struct rhashtable_iter hti; -++ struct flow_offload *flow; -++ int err; -++ -++ err = rhashtable_walk_init(&flow_table->rhashtable, &hti, GFP_KERNEL); -++ if (err) -++ return err; -++ -++ rhashtable_walk_start(&hti); -++ -++ while ((tuplehash = rhashtable_walk_next(&hti))) { -++ if (IS_ERR(tuplehash)) { -++ err = PTR_ERR(tuplehash); -++ if (err != -EAGAIN) -++ goto out; -++ -++ continue; -++ } -++ if (tuplehash->tuple.dir) -++ continue; -++ -++ flow = container_of(tuplehash, struct flow_offload, tuplehash[0]); -++ -++ iter(flow, data); -++ } -++out: -++ rhashtable_walk_stop(&hti); -++ rhashtable_walk_exit(&hti); -++ -++ return err; -++} -++EXPORT_SYMBOL_GPL(nf_flow_table_iterate); -++ -++static inline bool nf_flow_has_expired(const struct flow_offload *flow) -++{ -++ return (__s32)(flow->timeout - (u32)jiffies) <= 0; -++} -++ -++static inline bool nf_flow_is_dying(const struct flow_offload *flow) -++{ -++ return flow->flags & FLOW_OFFLOAD_DYING; -++} -++ -++static int nf_flow_offload_gc_step(struct nf_flowtable *flow_table) -++{ -++ struct flow_offload_tuple_rhash *tuplehash; -++ struct rhashtable_iter hti; -++ struct flow_offload *flow; -++ int err; -++ -++ err = rhashtable_walk_init(&flow_table->rhashtable, &hti, GFP_KERNEL); -++ if (err) -++ return 0; -++ -++ rhashtable_walk_start(&hti); -++ -++ while ((tuplehash = rhashtable_walk_next(&hti))) { -++ if (IS_ERR(tuplehash)) { -++ err = PTR_ERR(tuplehash); -++ if (err != -EAGAIN) -++ goto out; -++ -++ continue; -++ } -++ if (tuplehash->tuple.dir) -++ continue; -++ -++ flow = container_of(tuplehash, struct flow_offload, tuplehash[0]); -++ -++ if (nf_flow_has_expired(flow) || -++ nf_flow_is_dying(flow)) -++ flow_offload_del(flow_table, flow); -++ } -++out: -++ rhashtable_walk_stop(&hti); -++ rhashtable_walk_exit(&hti); -++ -++ return 1; -++} -++ -++void nf_flow_offload_work_gc(struct work_struct *work) -++{ -++ struct nf_flowtable *flow_table; -++ -++ flow_table = container_of(work, struct nf_flowtable, gc_work.work); -++ nf_flow_offload_gc_step(flow_table); -++ queue_delayed_work(system_power_efficient_wq, &flow_table->gc_work, HZ); -++} -++EXPORT_SYMBOL_GPL(nf_flow_offload_work_gc); -++ -++static u32 flow_offload_hash(const void *data, u32 len, u32 seed) -++{ -++ const struct flow_offload_tuple *tuple = data; -++ -++ return jhash(tuple, offsetof(struct flow_offload_tuple, dir), seed); -++} -++ -++static u32 flow_offload_hash_obj(const void *data, u32 len, u32 seed) -++{ -++ const struct flow_offload_tuple_rhash *tuplehash = data; -++ -++ return jhash(&tuplehash->tuple, offsetof(struct flow_offload_tuple, dir), seed); -++} -++ -++static int flow_offload_hash_cmp(struct rhashtable_compare_arg *arg, -++ const void *ptr) -++{ -++ const struct flow_offload_tuple *tuple = arg->key; -++ const struct flow_offload_tuple_rhash *x = ptr; -++ -++ if (memcmp(&x->tuple, tuple, offsetof(struct flow_offload_tuple, dir))) -++ return 1; -++ -++ return 0; -++} -++ -++const struct rhashtable_params nf_flow_offload_rhash_params = { -++ .head_offset = offsetof(struct flow_offload_tuple_rhash, node), -++ .hashfn = flow_offload_hash, -++ .obj_hashfn = flow_offload_hash_obj, -++ .obj_cmpfn = flow_offload_hash_cmp, -++ .automatic_shrinking = true, -++}; -++EXPORT_SYMBOL_GPL(nf_flow_offload_rhash_params); -++ -++static int nf_flow_nat_port_tcp(struct sk_buff *skb, unsigned int thoff, -++ __be16 port, __be16 new_port) -++{ -++ struct tcphdr *tcph; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*tcph)) || -++ skb_try_make_writable(skb, thoff + sizeof(*tcph))) -++ return -1; -++ -++ tcph = (void *)(skb_network_header(skb) + thoff); -++ inet_proto_csum_replace2(&tcph->check, skb, port, new_port, true); -++ -++ return 0; -++} -++ -++static int nf_flow_nat_port_udp(struct sk_buff *skb, unsigned int thoff, -++ __be16 port, __be16 new_port) -++{ -++ struct udphdr *udph; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*udph)) || -++ skb_try_make_writable(skb, thoff + sizeof(*udph))) -++ return -1; -++ -++ udph = (void *)(skb_network_header(skb) + thoff); -++ if (udph->check || skb->ip_summed == CHECKSUM_PARTIAL) { -++ inet_proto_csum_replace2(&udph->check, skb, port, -++ new_port, true); -++ if (!udph->check) -++ udph->check = CSUM_MANGLED_0; -++ } -++ -++ return 0; -++} -++ -++static int nf_flow_nat_port(struct sk_buff *skb, unsigned int thoff, -++ u8 protocol, __be16 port, __be16 new_port) -++{ -++ switch (protocol) { -++ case IPPROTO_TCP: -++ if (nf_flow_nat_port_tcp(skb, thoff, port, new_port) < 0) -++ return NF_DROP; -++ break; -++ case IPPROTO_UDP: -++ if (nf_flow_nat_port_udp(skb, thoff, port, new_port) < 0) -++ return NF_DROP; -++ break; -++ } -++ -++ return 0; -++} -++ -++int nf_flow_snat_port(const struct flow_offload *flow, -++ struct sk_buff *skb, unsigned int thoff, -++ u8 protocol, enum flow_offload_tuple_dir dir) -++{ -++ struct flow_ports *hdr; -++ __be16 port, new_port; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*hdr)) || -++ skb_try_make_writable(skb, thoff + sizeof(*hdr))) -++ return -1; -++ -++ hdr = (void *)(skb_network_header(skb) + thoff); -++ -++ switch (dir) { -++ case FLOW_OFFLOAD_DIR_ORIGINAL: -++ port = hdr->source; -++ new_port = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_port; -++ hdr->source = new_port; -++ break; -++ case FLOW_OFFLOAD_DIR_REPLY: -++ port = hdr->dest; -++ new_port = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_port; -++ hdr->dest = new_port; -++ break; -++ default: -++ return -1; -++ } -++ -++ return nf_flow_nat_port(skb, thoff, protocol, port, new_port); -++} -++EXPORT_SYMBOL_GPL(nf_flow_snat_port); -++ -++int nf_flow_dnat_port(const struct flow_offload *flow, -++ struct sk_buff *skb, unsigned int thoff, -++ u8 protocol, enum flow_offload_tuple_dir dir) -++{ -++ struct flow_ports *hdr; -++ __be16 port, new_port; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*hdr)) || -++ skb_try_make_writable(skb, thoff + sizeof(*hdr))) -++ return -1; -++ -++ hdr = (void *)(skb_network_header(skb) + thoff); -++ -++ switch (dir) { -++ case FLOW_OFFLOAD_DIR_ORIGINAL: -++ port = hdr->dest; -++ new_port = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_port; -++ hdr->dest = new_port; -++ break; -++ case FLOW_OFFLOAD_DIR_REPLY: -++ port = hdr->source; -++ new_port = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_port; -++ hdr->source = new_port; -++ break; -++ default: -++ return -1; -++ } -++ -++ return nf_flow_nat_port(skb, thoff, protocol, port, new_port); -++} -++EXPORT_SYMBOL_GPL(nf_flow_dnat_port); -++ -++static void nf_flow_table_do_cleanup(struct flow_offload *flow, void *data) -++{ -++ struct net_device *dev = data; -++ -++ if (dev && flow->tuplehash[0].tuple.iifidx != dev->ifindex) -++ return; -++ -++ flow_offload_dead(flow); -++} -++ -++static void nf_flow_table_iterate_cleanup(struct nf_flowtable *flowtable, -++ void *data) -++{ -++ nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, data); -++ flush_delayed_work(&flowtable->gc_work); -++} -++ -++void nf_flow_table_cleanup(struct net *net, struct net_device *dev) -++{ -++ nft_flow_table_iterate(net, nf_flow_table_iterate_cleanup, dev); -++} -++EXPORT_SYMBOL_GPL(nf_flow_table_cleanup); -++ -++void nf_flow_table_free(struct nf_flowtable *flow_table) -++{ -++ nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL); -++ WARN_ON(!nf_flow_offload_gc_step(flow_table)); -++} -++EXPORT_SYMBOL_GPL(nf_flow_table_free); -++ -++static int nf_flow_table_netdev_event(struct notifier_block *this, -++ unsigned long event, void *ptr) -++{ -++ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -++ -++ if (event != NETDEV_DOWN) -++ return NOTIFY_DONE; -++ -++ nf_flow_table_cleanup(dev_net(dev), dev); -++ -++ return NOTIFY_DONE; -++} -++ -++static struct notifier_block flow_offload_netdev_notifier = { -++ .notifier_call = nf_flow_table_netdev_event, -++}; -++ -++static int __init nf_flow_table_module_init(void) -++{ -++ return register_netdevice_notifier(&flow_offload_netdev_notifier); -++} -++ -++static void __exit nf_flow_table_module_exit(void) -++{ -++ unregister_netdevice_notifier(&flow_offload_netdev_notifier); -++} -++ -++module_init(nf_flow_table_module_init); -++module_exit(nf_flow_table_module_exit); -++ -++MODULE_LICENSE("GPL"); -++MODULE_AUTHOR("Pablo Neira Ayuso "); -diff --git a/target/linux/generic/backport-4.14/353-v4.18-netfilter-nf_flow_table-move-ipv4-offload-hook-code-.patch b/target/linux/generic/backport-4.14/353-v4.18-netfilter-nf_flow_table-move-ipv4-offload-hook-code-.patch -new file mode 100644 -index 0000000000..e25a66f934 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/353-v4.18-netfilter-nf_flow_table-move-ipv4-offload-hook-code-.patch -@@ -0,0 +1,522 @@ -+From: Felix Fietkau -+Date: Sat, 17 Feb 2018 11:49:44 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: move ipv4 offload hook code to -+ nf_flow_table -+ -+Allows some minor code sharing with the ipv6 hook code and is also -+useful as preparation for adding iptables support for offload -+ -+Signed-off-by: Felix Fietkau -+--- -+ create mode 100644 net/netfilter/nf_flow_table_ip.c -+ -+--- a/net/ipv4/netfilter/nf_flow_table_ipv4.c -++++ b/net/ipv4/netfilter/nf_flow_table_ipv4.c -+@@ -2,248 +2,8 @@ -+ #include -+ #include -+ #include -+-#include -+-#include -+-#include -+-#include -+-#include -+ #include -+ #include -+-/* For layer 4 checksum field offset. */ -+-#include -+-#include -+- -+-static int nf_flow_nat_ip_tcp(struct sk_buff *skb, unsigned int thoff, -+- __be32 addr, __be32 new_addr) -+-{ -+- struct tcphdr *tcph; -+- -+- if (!pskb_may_pull(skb, thoff + sizeof(*tcph)) || -+- skb_try_make_writable(skb, thoff + sizeof(*tcph))) -+- return -1; -+- -+- tcph = (void *)(skb_network_header(skb) + thoff); -+- inet_proto_csum_replace4(&tcph->check, skb, addr, new_addr, true); -+- -+- return 0; -+-} -+- -+-static int nf_flow_nat_ip_udp(struct sk_buff *skb, unsigned int thoff, -+- __be32 addr, __be32 new_addr) -+-{ -+- struct udphdr *udph; -+- -+- if (!pskb_may_pull(skb, thoff + sizeof(*udph)) || -+- skb_try_make_writable(skb, thoff + sizeof(*udph))) -+- return -1; -+- -+- udph = (void *)(skb_network_header(skb) + thoff); -+- if (udph->check || skb->ip_summed == CHECKSUM_PARTIAL) { -+- inet_proto_csum_replace4(&udph->check, skb, addr, -+- new_addr, true); -+- if (!udph->check) -+- udph->check = CSUM_MANGLED_0; -+- } -+- -+- return 0; -+-} -+- -+-static int nf_flow_nat_ip_l4proto(struct sk_buff *skb, struct iphdr *iph, -+- unsigned int thoff, __be32 addr, -+- __be32 new_addr) -+-{ -+- switch (iph->protocol) { -+- case IPPROTO_TCP: -+- if (nf_flow_nat_ip_tcp(skb, thoff, addr, new_addr) < 0) -+- return NF_DROP; -+- break; -+- case IPPROTO_UDP: -+- if (nf_flow_nat_ip_udp(skb, thoff, addr, new_addr) < 0) -+- return NF_DROP; -+- break; -+- } -+- -+- return 0; -+-} -+- -+-static int nf_flow_snat_ip(const struct flow_offload *flow, struct sk_buff *skb, -+- struct iphdr *iph, unsigned int thoff, -+- enum flow_offload_tuple_dir dir) -+-{ -+- __be32 addr, new_addr; -+- -+- switch (dir) { -+- case FLOW_OFFLOAD_DIR_ORIGINAL: -+- addr = iph->saddr; -+- new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_v4.s_addr; -+- iph->saddr = new_addr; -+- break; -+- case FLOW_OFFLOAD_DIR_REPLY: -+- addr = iph->daddr; -+- new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_v4.s_addr; -+- iph->daddr = new_addr; -+- break; -+- default: -+- return -1; -+- } -+- csum_replace4(&iph->check, addr, new_addr); -+- -+- return nf_flow_nat_ip_l4proto(skb, iph, thoff, addr, new_addr); -+-} -+- -+-static int nf_flow_dnat_ip(const struct flow_offload *flow, struct sk_buff *skb, -+- struct iphdr *iph, unsigned int thoff, -+- enum flow_offload_tuple_dir dir) -+-{ -+- __be32 addr, new_addr; -+- -+- switch (dir) { -+- case FLOW_OFFLOAD_DIR_ORIGINAL: -+- addr = iph->daddr; -+- new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_v4.s_addr; -+- iph->daddr = new_addr; -+- break; -+- case FLOW_OFFLOAD_DIR_REPLY: -+- addr = iph->saddr; -+- new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_v4.s_addr; -+- iph->saddr = new_addr; -+- break; -+- default: -+- return -1; -+- } -+- -+- return nf_flow_nat_ip_l4proto(skb, iph, thoff, addr, new_addr); -+-} -+- -+-static int nf_flow_nat_ip(const struct flow_offload *flow, struct sk_buff *skb, -+- enum flow_offload_tuple_dir dir) -+-{ -+- struct iphdr *iph = ip_hdr(skb); -+- unsigned int thoff = iph->ihl * 4; -+- -+- if (flow->flags & FLOW_OFFLOAD_SNAT && -+- (nf_flow_snat_port(flow, skb, thoff, iph->protocol, dir) < 0 || -+- nf_flow_snat_ip(flow, skb, iph, thoff, dir) < 0)) -+- return -1; -+- if (flow->flags & FLOW_OFFLOAD_DNAT && -+- (nf_flow_dnat_port(flow, skb, thoff, iph->protocol, dir) < 0 || -+- nf_flow_dnat_ip(flow, skb, iph, thoff, dir) < 0)) -+- return -1; -+- -+- return 0; -+-} -+- -+-static bool ip_has_options(unsigned int thoff) -+-{ -+- return thoff != sizeof(struct iphdr); -+-} -+- -+-static int nf_flow_tuple_ip(struct sk_buff *skb, const struct net_device *dev, -+- struct flow_offload_tuple *tuple) -+-{ -+- struct flow_ports *ports; -+- unsigned int thoff; -+- struct iphdr *iph; -+- -+- if (!pskb_may_pull(skb, sizeof(*iph))) -+- return -1; -+- -+- iph = ip_hdr(skb); -+- thoff = iph->ihl * 4; -+- -+- if (ip_is_fragment(iph) || -+- unlikely(ip_has_options(thoff))) -+- return -1; -+- -+- if (iph->protocol != IPPROTO_TCP && -+- iph->protocol != IPPROTO_UDP) -+- return -1; -+- -+- thoff = iph->ihl * 4; -+- if (!pskb_may_pull(skb, thoff + sizeof(*ports))) -+- return -1; -+- -+- ports = (struct flow_ports *)(skb_network_header(skb) + thoff); -+- -+- tuple->src_v4.s_addr = iph->saddr; -+- tuple->dst_v4.s_addr = iph->daddr; -+- tuple->src_port = ports->source; -+- tuple->dst_port = ports->dest; -+- tuple->l3proto = AF_INET; -+- tuple->l4proto = iph->protocol; -+- tuple->iifidx = dev->ifindex; -+- -+- return 0; -+-} -+- -+-/* Based on ip_exceeds_mtu(). */ -+-static bool nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) -+-{ -+- if (skb->len <= mtu) -+- return false; -+- -+- if ((ip_hdr(skb)->frag_off & htons(IP_DF)) == 0) -+- return false; -+- -+- if (skb_is_gso(skb) && skb_gso_validate_mtu(skb, mtu)) -+- return false; -+- -+- return true; -+-} -+- -+-unsigned int -+-nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, -+- const struct nf_hook_state *state) -+-{ -+- struct flow_offload_tuple_rhash *tuplehash; -+- struct nf_flowtable *flow_table = priv; -+- struct flow_offload_tuple tuple = {}; -+- enum flow_offload_tuple_dir dir; -+- struct flow_offload *flow; -+- struct net_device *outdev; -+- const struct rtable *rt; -+- struct iphdr *iph; -+- __be32 nexthop; -+- -+- if (skb->protocol != htons(ETH_P_IP)) -+- return NF_ACCEPT; -+- -+- if (nf_flow_tuple_ip(skb, state->in, &tuple) < 0) -+- return NF_ACCEPT; -+- -+- tuplehash = flow_offload_lookup(flow_table, &tuple); -+- if (tuplehash == NULL) -+- return NF_ACCEPT; -+- -+- outdev = dev_get_by_index_rcu(state->net, tuplehash->tuple.oifidx); -+- if (!outdev) -+- return NF_ACCEPT; -+- -+- dir = tuplehash->tuple.dir; -+- flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); -+- rt = (const struct rtable *)flow->tuplehash[dir].tuple.dst_cache; -+- -+- if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu))) -+- return NF_ACCEPT; -+- -+- if (skb_try_make_writable(skb, sizeof(*iph))) -+- return NF_DROP; -+- -+- if (flow->flags & (FLOW_OFFLOAD_SNAT | FLOW_OFFLOAD_DNAT) && -+- nf_flow_nat_ip(flow, skb, dir) < 0) -+- return NF_DROP; -+- -+- flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT; -+- iph = ip_hdr(skb); -+- ip_decrease_ttl(iph); -+- -+- skb->dev = outdev; -+- nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr); -+- neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb); -+- -+- return NF_STOLEN; -+-} -+-EXPORT_SYMBOL_GPL(nf_flow_offload_ip_hook); -+ -+ static struct nf_flowtable_type flowtable_ipv4 = { -+ .family = NFPROTO_IPV4, -+--- a/net/netfilter/Makefile -++++ b/net/netfilter/Makefile -+@@ -113,7 +113,7 @@ obj-$(CONFIG_NFT_FWD_NETDEV) += nft_fwd_ -+ -+ # flow table infrastructure -+ obj-$(CONFIG_NF_FLOW_TABLE) += nf_flow_table.o -+-nf_flow_table-objs := nf_flow_table_core.o -++nf_flow_table-objs := nf_flow_table_core.o nf_flow_table_ip.o -+ -+ obj-$(CONFIG_NF_FLOW_TABLE_INET) += nf_flow_table_inet.o -+ -+--- /dev/null -++++ b/net/netfilter/nf_flow_table_ip.c -+@@ -0,0 +1,245 @@ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++/* For layer 4 checksum field offset. */ -++#include -++#include -++ -++static int nf_flow_nat_ip_tcp(struct sk_buff *skb, unsigned int thoff, -++ __be32 addr, __be32 new_addr) -++{ -++ struct tcphdr *tcph; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*tcph)) || -++ skb_try_make_writable(skb, thoff + sizeof(*tcph))) -++ return -1; -++ -++ tcph = (void *)(skb_network_header(skb) + thoff); -++ inet_proto_csum_replace4(&tcph->check, skb, addr, new_addr, true); -++ -++ return 0; -++} -++ -++static int nf_flow_nat_ip_udp(struct sk_buff *skb, unsigned int thoff, -++ __be32 addr, __be32 new_addr) -++{ -++ struct udphdr *udph; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*udph)) || -++ skb_try_make_writable(skb, thoff + sizeof(*udph))) -++ return -1; -++ -++ udph = (void *)(skb_network_header(skb) + thoff); -++ if (udph->check || skb->ip_summed == CHECKSUM_PARTIAL) { -++ inet_proto_csum_replace4(&udph->check, skb, addr, -++ new_addr, true); -++ if (!udph->check) -++ udph->check = CSUM_MANGLED_0; -++ } -++ -++ return 0; -++} -++ -++static int nf_flow_nat_ip_l4proto(struct sk_buff *skb, struct iphdr *iph, -++ unsigned int thoff, __be32 addr, -++ __be32 new_addr) -++{ -++ switch (iph->protocol) { -++ case IPPROTO_TCP: -++ if (nf_flow_nat_ip_tcp(skb, thoff, addr, new_addr) < 0) -++ return NF_DROP; -++ break; -++ case IPPROTO_UDP: -++ if (nf_flow_nat_ip_udp(skb, thoff, addr, new_addr) < 0) -++ return NF_DROP; -++ break; -++ } -++ -++ return 0; -++} -++ -++static int nf_flow_snat_ip(const struct flow_offload *flow, struct sk_buff *skb, -++ struct iphdr *iph, unsigned int thoff, -++ enum flow_offload_tuple_dir dir) -++{ -++ __be32 addr, new_addr; -++ -++ switch (dir) { -++ case FLOW_OFFLOAD_DIR_ORIGINAL: -++ addr = iph->saddr; -++ new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_v4.s_addr; -++ iph->saddr = new_addr; -++ break; -++ case FLOW_OFFLOAD_DIR_REPLY: -++ addr = iph->daddr; -++ new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_v4.s_addr; -++ iph->daddr = new_addr; -++ break; -++ default: -++ return -1; -++ } -++ csum_replace4(&iph->check, addr, new_addr); -++ -++ return nf_flow_nat_ip_l4proto(skb, iph, thoff, addr, new_addr); -++} -++ -++static int nf_flow_dnat_ip(const struct flow_offload *flow, struct sk_buff *skb, -++ struct iphdr *iph, unsigned int thoff, -++ enum flow_offload_tuple_dir dir) -++{ -++ __be32 addr, new_addr; -++ -++ switch (dir) { -++ case FLOW_OFFLOAD_DIR_ORIGINAL: -++ addr = iph->daddr; -++ new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_v4.s_addr; -++ iph->daddr = new_addr; -++ break; -++ case FLOW_OFFLOAD_DIR_REPLY: -++ addr = iph->saddr; -++ new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_v4.s_addr; -++ iph->saddr = new_addr; -++ break; -++ default: -++ return -1; -++ } -++ -++ return nf_flow_nat_ip_l4proto(skb, iph, thoff, addr, new_addr); -++} -++ -++static int nf_flow_nat_ip(const struct flow_offload *flow, struct sk_buff *skb, -++ enum flow_offload_tuple_dir dir) -++{ -++ struct iphdr *iph = ip_hdr(skb); -++ unsigned int thoff = iph->ihl * 4; -++ -++ if (flow->flags & FLOW_OFFLOAD_SNAT && -++ (nf_flow_snat_port(flow, skb, thoff, iph->protocol, dir) < 0 || -++ nf_flow_snat_ip(flow, skb, iph, thoff, dir) < 0)) -++ return -1; -++ if (flow->flags & FLOW_OFFLOAD_DNAT && -++ (nf_flow_dnat_port(flow, skb, thoff, iph->protocol, dir) < 0 || -++ nf_flow_dnat_ip(flow, skb, iph, thoff, dir) < 0)) -++ return -1; -++ -++ return 0; -++} -++ -++static bool ip_has_options(unsigned int thoff) -++{ -++ return thoff != sizeof(struct iphdr); -++} -++ -++static int nf_flow_tuple_ip(struct sk_buff *skb, const struct net_device *dev, -++ struct flow_offload_tuple *tuple) -++{ -++ struct flow_ports *ports; -++ unsigned int thoff; -++ struct iphdr *iph; -++ -++ if (!pskb_may_pull(skb, sizeof(*iph))) -++ return -1; -++ -++ iph = ip_hdr(skb); -++ thoff = iph->ihl * 4; -++ -++ if (ip_is_fragment(iph) || -++ unlikely(ip_has_options(thoff))) -++ return -1; -++ -++ if (iph->protocol != IPPROTO_TCP && -++ iph->protocol != IPPROTO_UDP) -++ return -1; -++ -++ thoff = iph->ihl * 4; -++ if (!pskb_may_pull(skb, thoff + sizeof(*ports))) -++ return -1; -++ -++ ports = (struct flow_ports *)(skb_network_header(skb) + thoff); -++ -++ tuple->src_v4.s_addr = iph->saddr; -++ tuple->dst_v4.s_addr = iph->daddr; -++ tuple->src_port = ports->source; -++ tuple->dst_port = ports->dest; -++ tuple->l3proto = AF_INET; -++ tuple->l4proto = iph->protocol; -++ tuple->iifidx = dev->ifindex; -++ -++ return 0; -++} -++ -++/* Based on ip_exceeds_mtu(). */ -++static bool nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) -++{ -++ if (skb->len <= mtu) -++ return false; -++ -++ if ((ip_hdr(skb)->frag_off & htons(IP_DF)) == 0) -++ return false; -++ -++ if (skb_is_gso(skb) && skb_gso_validate_mtu(skb, mtu)) -++ return false; -++ -++ return true; -++} -++ -++unsigned int -++nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, -++ const struct nf_hook_state *state) -++{ -++ struct flow_offload_tuple_rhash *tuplehash; -++ struct nf_flowtable *flow_table = priv; -++ struct flow_offload_tuple tuple = {}; -++ enum flow_offload_tuple_dir dir; -++ struct flow_offload *flow; -++ struct net_device *outdev; -++ const struct rtable *rt; -++ struct iphdr *iph; -++ __be32 nexthop; -++ -++ if (skb->protocol != htons(ETH_P_IP)) -++ return NF_ACCEPT; -++ -++ if (nf_flow_tuple_ip(skb, state->in, &tuple) < 0) -++ return NF_ACCEPT; -++ -++ tuplehash = flow_offload_lookup(flow_table, &tuple); -++ if (tuplehash == NULL) -++ return NF_ACCEPT; -++ -++ outdev = dev_get_by_index_rcu(state->net, tuplehash->tuple.oifidx); -++ if (!outdev) -++ return NF_ACCEPT; -++ -++ dir = tuplehash->tuple.dir; -++ flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); -++ rt = (const struct rtable *)flow->tuplehash[dir].tuple.dst_cache; -++ -++ if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu))) -++ return NF_ACCEPT; -++ -++ if (skb_try_make_writable(skb, sizeof(*iph))) -++ return NF_DROP; -++ -++ if (flow->flags & (FLOW_OFFLOAD_SNAT | FLOW_OFFLOAD_DNAT) && -++ nf_flow_nat_ip(flow, skb, dir) < 0) -++ return NF_DROP; -++ -++ flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT; -++ iph = ip_hdr(skb); -++ ip_decrease_ttl(iph); -++ -++ skb->dev = outdev; -++ nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr); -++ neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb); -++ -++ return NF_STOLEN; -++} -++EXPORT_SYMBOL_GPL(nf_flow_offload_ip_hook); -diff --git a/target/linux/generic/backport-4.14/354-v4.18-netfilter-nf_flow_table-move-ip-header-check-out-of-.patch b/target/linux/generic/backport-4.14/354-v4.18-netfilter-nf_flow_table-move-ip-header-check-out-of-.patch -new file mode 100644 -index 0000000000..4ee5532438 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/354-v4.18-netfilter-nf_flow_table-move-ip-header-check-out-of-.patch -@@ -0,0 +1,32 @@ -+From: Felix Fietkau -+Date: Sat, 17 Feb 2018 11:51:20 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: move ip header check out of -+ nf_flow_exceeds_mtu -+ -+Allows the function to be shared with the IPv6 hook code -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/netfilter/nf_flow_table_ip.c -++++ b/net/netfilter/nf_flow_table_ip.c -+@@ -181,9 +181,6 @@ static bool nf_flow_exceeds_mtu(const st -+ if (skb->len <= mtu) -+ return false; -+ -+- if ((ip_hdr(skb)->frag_off & htons(IP_DF)) == 0) -+- return false; -+- -+ if (skb_is_gso(skb) && skb_gso_validate_mtu(skb, mtu)) -+ return false; -+ -+@@ -222,7 +219,8 @@ nf_flow_offload_ip_hook(void *priv, stru -+ flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); -+ rt = (const struct rtable *)flow->tuplehash[dir].tuple.dst_cache; -+ -+- if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu))) -++ if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu)) && -++ (ip_hdr(skb)->frag_off & htons(IP_DF)) != 0) -+ return NF_ACCEPT; -+ -+ if (skb_try_make_writable(skb, sizeof(*iph))) -diff --git a/target/linux/generic/backport-4.14/355-v4.18-netfilter-nf_flow_table-move-ipv6-offload-hook-code-.patch b/target/linux/generic/backport-4.14/355-v4.18-netfilter-nf_flow_table-move-ipv6-offload-hook-code-.patch -new file mode 100644 -index 0000000000..20ab0ed504 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/355-v4.18-netfilter-nf_flow_table-move-ipv6-offload-hook-code-.patch -@@ -0,0 +1,483 @@ -+From: Felix Fietkau -+Date: Sat, 17 Feb 2018 11:55:51 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: move ipv6 offload hook code to -+ nf_flow_table -+ -+Useful as preparation for adding iptables support for offload -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/ipv6/netfilter/nf_flow_table_ipv6.c -++++ b/net/ipv6/netfilter/nf_flow_table_ipv6.c -+@@ -3,240 +3,8 @@ -+ #include -+ #include -+ #include -+-#include -+-#include -+-#include -+-#include -+-#include -+ #include -+ #include -+-/* For layer 4 checksum field offset. */ -+-#include -+-#include -+- -+-static int nf_flow_nat_ipv6_tcp(struct sk_buff *skb, unsigned int thoff, -+- struct in6_addr *addr, -+- struct in6_addr *new_addr) -+-{ -+- struct tcphdr *tcph; -+- -+- if (!pskb_may_pull(skb, thoff + sizeof(*tcph)) || -+- skb_try_make_writable(skb, thoff + sizeof(*tcph))) -+- return -1; -+- -+- tcph = (void *)(skb_network_header(skb) + thoff); -+- inet_proto_csum_replace16(&tcph->check, skb, addr->s6_addr32, -+- new_addr->s6_addr32, true); -+- -+- return 0; -+-} -+- -+-static int nf_flow_nat_ipv6_udp(struct sk_buff *skb, unsigned int thoff, -+- struct in6_addr *addr, -+- struct in6_addr *new_addr) -+-{ -+- struct udphdr *udph; -+- -+- if (!pskb_may_pull(skb, thoff + sizeof(*udph)) || -+- skb_try_make_writable(skb, thoff + sizeof(*udph))) -+- return -1; -+- -+- udph = (void *)(skb_network_header(skb) + thoff); -+- if (udph->check || skb->ip_summed == CHECKSUM_PARTIAL) { -+- inet_proto_csum_replace16(&udph->check, skb, addr->s6_addr32, -+- new_addr->s6_addr32, true); -+- if (!udph->check) -+- udph->check = CSUM_MANGLED_0; -+- } -+- -+- return 0; -+-} -+- -+-static int nf_flow_nat_ipv6_l4proto(struct sk_buff *skb, struct ipv6hdr *ip6h, -+- unsigned int thoff, struct in6_addr *addr, -+- struct in6_addr *new_addr) -+-{ -+- switch (ip6h->nexthdr) { -+- case IPPROTO_TCP: -+- if (nf_flow_nat_ipv6_tcp(skb, thoff, addr, new_addr) < 0) -+- return NF_DROP; -+- break; -+- case IPPROTO_UDP: -+- if (nf_flow_nat_ipv6_udp(skb, thoff, addr, new_addr) < 0) -+- return NF_DROP; -+- break; -+- } -+- -+- return 0; -+-} -+- -+-static int nf_flow_snat_ipv6(const struct flow_offload *flow, -+- struct sk_buff *skb, struct ipv6hdr *ip6h, -+- unsigned int thoff, -+- enum flow_offload_tuple_dir dir) -+-{ -+- struct in6_addr addr, new_addr; -+- -+- switch (dir) { -+- case FLOW_OFFLOAD_DIR_ORIGINAL: -+- addr = ip6h->saddr; -+- new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_v6; -+- ip6h->saddr = new_addr; -+- break; -+- case FLOW_OFFLOAD_DIR_REPLY: -+- addr = ip6h->daddr; -+- new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_v6; -+- ip6h->daddr = new_addr; -+- break; -+- default: -+- return -1; -+- } -+- -+- return nf_flow_nat_ipv6_l4proto(skb, ip6h, thoff, &addr, &new_addr); -+-} -+- -+-static int nf_flow_dnat_ipv6(const struct flow_offload *flow, -+- struct sk_buff *skb, struct ipv6hdr *ip6h, -+- unsigned int thoff, -+- enum flow_offload_tuple_dir dir) -+-{ -+- struct in6_addr addr, new_addr; -+- -+- switch (dir) { -+- case FLOW_OFFLOAD_DIR_ORIGINAL: -+- addr = ip6h->daddr; -+- new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_v6; -+- ip6h->daddr = new_addr; -+- break; -+- case FLOW_OFFLOAD_DIR_REPLY: -+- addr = ip6h->saddr; -+- new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_v6; -+- ip6h->saddr = new_addr; -+- break; -+- default: -+- return -1; -+- } -+- -+- return nf_flow_nat_ipv6_l4proto(skb, ip6h, thoff, &addr, &new_addr); -+-} -+- -+-static int nf_flow_nat_ipv6(const struct flow_offload *flow, -+- struct sk_buff *skb, -+- enum flow_offload_tuple_dir dir) -+-{ -+- struct ipv6hdr *ip6h = ipv6_hdr(skb); -+- unsigned int thoff = sizeof(*ip6h); -+- -+- if (flow->flags & FLOW_OFFLOAD_SNAT && -+- (nf_flow_snat_port(flow, skb, thoff, ip6h->nexthdr, dir) < 0 || -+- nf_flow_snat_ipv6(flow, skb, ip6h, thoff, dir) < 0)) -+- return -1; -+- if (flow->flags & FLOW_OFFLOAD_DNAT && -+- (nf_flow_dnat_port(flow, skb, thoff, ip6h->nexthdr, dir) < 0 || -+- nf_flow_dnat_ipv6(flow, skb, ip6h, thoff, dir) < 0)) -+- return -1; -+- -+- return 0; -+-} -+- -+-static int nf_flow_tuple_ipv6(struct sk_buff *skb, const struct net_device *dev, -+- struct flow_offload_tuple *tuple) -+-{ -+- struct flow_ports *ports; -+- struct ipv6hdr *ip6h; -+- unsigned int thoff; -+- -+- if (!pskb_may_pull(skb, sizeof(*ip6h))) -+- return -1; -+- -+- ip6h = ipv6_hdr(skb); -+- -+- if (ip6h->nexthdr != IPPROTO_TCP && -+- ip6h->nexthdr != IPPROTO_UDP) -+- return -1; -+- -+- thoff = sizeof(*ip6h); -+- if (!pskb_may_pull(skb, thoff + sizeof(*ports))) -+- return -1; -+- -+- ports = (struct flow_ports *)(skb_network_header(skb) + thoff); -+- -+- tuple->src_v6 = ip6h->saddr; -+- tuple->dst_v6 = ip6h->daddr; -+- tuple->src_port = ports->source; -+- tuple->dst_port = ports->dest; -+- tuple->l3proto = AF_INET6; -+- tuple->l4proto = ip6h->nexthdr; -+- tuple->iifidx = dev->ifindex; -+- -+- return 0; -+-} -+- -+-/* Based on ip_exceeds_mtu(). */ -+-static bool nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) -+-{ -+- if (skb->len <= mtu) -+- return false; -+- -+- if (skb_is_gso(skb) && skb_gso_validate_mtu(skb, mtu)) -+- return false; -+- -+- return true; -+-} -+- -+-unsigned int -+-nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, -+- const struct nf_hook_state *state) -+-{ -+- struct flow_offload_tuple_rhash *tuplehash; -+- struct nf_flowtable *flow_table = priv; -+- struct flow_offload_tuple tuple = {}; -+- enum flow_offload_tuple_dir dir; -+- struct flow_offload *flow; -+- struct net_device *outdev; -+- struct in6_addr *nexthop; -+- struct ipv6hdr *ip6h; -+- struct rt6_info *rt; -+- -+- if (skb->protocol != htons(ETH_P_IPV6)) -+- return NF_ACCEPT; -+- -+- if (nf_flow_tuple_ipv6(skb, state->in, &tuple) < 0) -+- return NF_ACCEPT; -+- -+- tuplehash = flow_offload_lookup(flow_table, &tuple); -+- if (tuplehash == NULL) -+- return NF_ACCEPT; -+- -+- outdev = dev_get_by_index_rcu(state->net, tuplehash->tuple.oifidx); -+- if (!outdev) -+- return NF_ACCEPT; -+- -+- dir = tuplehash->tuple.dir; -+- flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); -+- rt = (struct rt6_info *)flow->tuplehash[dir].tuple.dst_cache; -+- -+- if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu))) -+- return NF_ACCEPT; -+- -+- if (skb_try_make_writable(skb, sizeof(*ip6h))) -+- return NF_DROP; -+- -+- if (flow->flags & (FLOW_OFFLOAD_SNAT | FLOW_OFFLOAD_DNAT) && -+- nf_flow_nat_ipv6(flow, skb, dir) < 0) -+- return NF_DROP; -+- -+- flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT; -+- ip6h = ipv6_hdr(skb); -+- ip6h->hop_limit--; -+- -+- skb->dev = outdev; -+- nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6); -+- neigh_xmit(NEIGH_ND_TABLE, outdev, nexthop, skb); -+- -+- return NF_STOLEN; -+-} -+-EXPORT_SYMBOL_GPL(nf_flow_offload_ipv6_hook); -+ -+ static struct nf_flowtable_type flowtable_ipv6 = { -+ .family = NFPROTO_IPV6, -+--- a/net/netfilter/nf_flow_table_ip.c -++++ b/net/netfilter/nf_flow_table_ip.c -+@@ -4,8 +4,11 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -++#include -++#include -+ #include -+ #include -+ /* For layer 4 checksum field offset. */ -+@@ -241,3 +244,215 @@ nf_flow_offload_ip_hook(void *priv, stru -+ return NF_STOLEN; -+ } -+ EXPORT_SYMBOL_GPL(nf_flow_offload_ip_hook); -++ -++static int nf_flow_nat_ipv6_tcp(struct sk_buff *skb, unsigned int thoff, -++ struct in6_addr *addr, -++ struct in6_addr *new_addr) -++{ -++ struct tcphdr *tcph; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*tcph)) || -++ skb_try_make_writable(skb, thoff + sizeof(*tcph))) -++ return -1; -++ -++ tcph = (void *)(skb_network_header(skb) + thoff); -++ inet_proto_csum_replace16(&tcph->check, skb, addr->s6_addr32, -++ new_addr->s6_addr32, true); -++ -++ return 0; -++} -++ -++static int nf_flow_nat_ipv6_udp(struct sk_buff *skb, unsigned int thoff, -++ struct in6_addr *addr, -++ struct in6_addr *new_addr) -++{ -++ struct udphdr *udph; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*udph)) || -++ skb_try_make_writable(skb, thoff + sizeof(*udph))) -++ return -1; -++ -++ udph = (void *)(skb_network_header(skb) + thoff); -++ if (udph->check || skb->ip_summed == CHECKSUM_PARTIAL) { -++ inet_proto_csum_replace16(&udph->check, skb, addr->s6_addr32, -++ new_addr->s6_addr32, true); -++ if (!udph->check) -++ udph->check = CSUM_MANGLED_0; -++ } -++ -++ return 0; -++} -++ -++static int nf_flow_nat_ipv6_l4proto(struct sk_buff *skb, struct ipv6hdr *ip6h, -++ unsigned int thoff, struct in6_addr *addr, -++ struct in6_addr *new_addr) -++{ -++ switch (ip6h->nexthdr) { -++ case IPPROTO_TCP: -++ if (nf_flow_nat_ipv6_tcp(skb, thoff, addr, new_addr) < 0) -++ return NF_DROP; -++ break; -++ case IPPROTO_UDP: -++ if (nf_flow_nat_ipv6_udp(skb, thoff, addr, new_addr) < 0) -++ return NF_DROP; -++ break; -++ } -++ -++ return 0; -++} -++ -++static int nf_flow_snat_ipv6(const struct flow_offload *flow, -++ struct sk_buff *skb, struct ipv6hdr *ip6h, -++ unsigned int thoff, -++ enum flow_offload_tuple_dir dir) -++{ -++ struct in6_addr addr, new_addr; -++ -++ switch (dir) { -++ case FLOW_OFFLOAD_DIR_ORIGINAL: -++ addr = ip6h->saddr; -++ new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_v6; -++ ip6h->saddr = new_addr; -++ break; -++ case FLOW_OFFLOAD_DIR_REPLY: -++ addr = ip6h->daddr; -++ new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_v6; -++ ip6h->daddr = new_addr; -++ break; -++ default: -++ return -1; -++ } -++ -++ return nf_flow_nat_ipv6_l4proto(skb, ip6h, thoff, &addr, &new_addr); -++} -++ -++static int nf_flow_dnat_ipv6(const struct flow_offload *flow, -++ struct sk_buff *skb, struct ipv6hdr *ip6h, -++ unsigned int thoff, -++ enum flow_offload_tuple_dir dir) -++{ -++ struct in6_addr addr, new_addr; -++ -++ switch (dir) { -++ case FLOW_OFFLOAD_DIR_ORIGINAL: -++ addr = ip6h->daddr; -++ new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_v6; -++ ip6h->daddr = new_addr; -++ break; -++ case FLOW_OFFLOAD_DIR_REPLY: -++ addr = ip6h->saddr; -++ new_addr = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_v6; -++ ip6h->saddr = new_addr; -++ break; -++ default: -++ return -1; -++ } -++ -++ return nf_flow_nat_ipv6_l4proto(skb, ip6h, thoff, &addr, &new_addr); -++} -++ -++static int nf_flow_nat_ipv6(const struct flow_offload *flow, -++ struct sk_buff *skb, -++ enum flow_offload_tuple_dir dir) -++{ -++ struct ipv6hdr *ip6h = ipv6_hdr(skb); -++ unsigned int thoff = sizeof(*ip6h); -++ -++ if (flow->flags & FLOW_OFFLOAD_SNAT && -++ (nf_flow_snat_port(flow, skb, thoff, ip6h->nexthdr, dir) < 0 || -++ nf_flow_snat_ipv6(flow, skb, ip6h, thoff, dir) < 0)) -++ return -1; -++ if (flow->flags & FLOW_OFFLOAD_DNAT && -++ (nf_flow_dnat_port(flow, skb, thoff, ip6h->nexthdr, dir) < 0 || -++ nf_flow_dnat_ipv6(flow, skb, ip6h, thoff, dir) < 0)) -++ return -1; -++ -++ return 0; -++} -++ -++static int nf_flow_tuple_ipv6(struct sk_buff *skb, const struct net_device *dev, -++ struct flow_offload_tuple *tuple) -++{ -++ struct flow_ports *ports; -++ struct ipv6hdr *ip6h; -++ unsigned int thoff; -++ -++ if (!pskb_may_pull(skb, sizeof(*ip6h))) -++ return -1; -++ -++ ip6h = ipv6_hdr(skb); -++ -++ if (ip6h->nexthdr != IPPROTO_TCP && -++ ip6h->nexthdr != IPPROTO_UDP) -++ return -1; -++ -++ thoff = sizeof(*ip6h); -++ if (!pskb_may_pull(skb, thoff + sizeof(*ports))) -++ return -1; -++ -++ ports = (struct flow_ports *)(skb_network_header(skb) + thoff); -++ -++ tuple->src_v6 = ip6h->saddr; -++ tuple->dst_v6 = ip6h->daddr; -++ tuple->src_port = ports->source; -++ tuple->dst_port = ports->dest; -++ tuple->l3proto = AF_INET6; -++ tuple->l4proto = ip6h->nexthdr; -++ tuple->iifidx = dev->ifindex; -++ -++ return 0; -++} -++ -++unsigned int -++nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, -++ const struct nf_hook_state *state) -++{ -++ struct flow_offload_tuple_rhash *tuplehash; -++ struct nf_flowtable *flow_table = priv; -++ struct flow_offload_tuple tuple = {}; -++ enum flow_offload_tuple_dir dir; -++ struct flow_offload *flow; -++ struct net_device *outdev; -++ struct in6_addr *nexthop; -++ struct ipv6hdr *ip6h; -++ struct rt6_info *rt; -++ -++ if (skb->protocol != htons(ETH_P_IPV6)) -++ return NF_ACCEPT; -++ -++ if (nf_flow_tuple_ipv6(skb, state->in, &tuple) < 0) -++ return NF_ACCEPT; -++ -++ tuplehash = flow_offload_lookup(flow_table, &tuple); -++ if (tuplehash == NULL) -++ return NF_ACCEPT; -++ -++ outdev = dev_get_by_index_rcu(state->net, tuplehash->tuple.oifidx); -++ if (!outdev) -++ return NF_ACCEPT; -++ -++ dir = tuplehash->tuple.dir; -++ flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); -++ rt = (struct rt6_info *)flow->tuplehash[dir].tuple.dst_cache; -++ -++ if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu))) -++ return NF_ACCEPT; -++ -++ if (skb_try_make_writable(skb, sizeof(*ip6h))) -++ return NF_DROP; -++ -++ if (flow->flags & (FLOW_OFFLOAD_SNAT | FLOW_OFFLOAD_DNAT) && -++ nf_flow_nat_ipv6(flow, skb, dir) < 0) -++ return NF_DROP; -++ -++ flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT; -++ ip6h = ipv6_hdr(skb); -++ ip6h->hop_limit--; -++ -++ skb->dev = outdev; -++ nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6); -++ neigh_xmit(NEIGH_ND_TABLE, outdev, nexthop, skb); -++ -++ return NF_STOLEN; -++} -++EXPORT_SYMBOL_GPL(nf_flow_offload_ipv6_hook); -diff --git a/target/linux/generic/backport-4.14/356-v4.18-netfilter-nf_flow_table-relax-mixed-ipv4-ipv6-flowta.patch b/target/linux/generic/backport-4.14/356-v4.18-netfilter-nf_flow_table-relax-mixed-ipv4-ipv6-flowta.patch -new file mode 100644 -index 0000000000..b5fe25a1d6 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/356-v4.18-netfilter-nf_flow_table-relax-mixed-ipv4-ipv6-flowta.patch -@@ -0,0 +1,23 @@ -+From: Felix Fietkau -+Date: Sat, 17 Feb 2018 12:02:28 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: relax mixed ipv4/ipv6 flowtable -+ dependencies -+ -+Since the offload hook code was moved, this table no longer depends on -+the IPv4 and IPv6 flowtable modules -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/netfilter/Kconfig -++++ b/net/netfilter/Kconfig -+@@ -676,8 +676,7 @@ endif # NF_TABLES -+ -+ config NF_FLOW_TABLE_INET -+ tristate "Netfilter flow table mixed IPv4/IPv6 module" -+- depends on NF_FLOW_TABLE_IPV4 -+- depends on NF_FLOW_TABLE_IPV6 -++ depends on NF_FLOW_TABLE -+ help -+ This option adds the flow table mixed IPv4/IPv6 support. -+ -diff --git a/target/linux/generic/backport-4.14/357-v4.18-netfilter-nf_flow_table-move-init-code-to-nf_flow_ta.patch b/target/linux/generic/backport-4.14/357-v4.18-netfilter-nf_flow_table-move-init-code-to-nf_flow_ta.patch -new file mode 100644 -index 0000000000..96acb6887e ---- /dev/null -+++ b/target/linux/generic/backport-4.14/357-v4.18-netfilter-nf_flow_table-move-init-code-to-nf_flow_ta.patch -@@ -0,0 +1,298 @@ -+From: Felix Fietkau -+Date: Sun, 18 Feb 2018 18:16:31 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: move init code to -+ nf_flow_table_core.c -+ -+Reduces duplication of .gc and .params in flowtable type definitions and -+makes the API clearer -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -14,9 +14,8 @@ struct nf_flowtable; -+ struct nf_flowtable_type { -+ struct list_head list; -+ int family; -+- void (*gc)(struct work_struct *work); -++ int (*init)(struct nf_flowtable *ft); -+ void (*free)(struct nf_flowtable *ft); -+- const struct rhashtable_params *params; -+ nf_hookfn *hook; -+ struct module *owner; -+ }; -+@@ -100,9 +99,8 @@ int nf_flow_table_iterate(struct nf_flow -+ -+ void nf_flow_table_cleanup(struct net *net, struct net_device *dev); -+ -++int nf_flow_table_init(struct nf_flowtable *flow_table); -+ void nf_flow_table_free(struct nf_flowtable *flow_table); -+-void nf_flow_offload_work_gc(struct work_struct *work); -+-extern const struct rhashtable_params nf_flow_offload_rhash_params; -+ -+ void flow_offload_dead(struct flow_offload *flow); -+ -+--- a/net/ipv4/netfilter/nf_flow_table_ipv4.c -++++ b/net/ipv4/netfilter/nf_flow_table_ipv4.c -+@@ -7,8 +7,7 @@ -+ -+ static struct nf_flowtable_type flowtable_ipv4 = { -+ .family = NFPROTO_IPV4, -+- .params = &nf_flow_offload_rhash_params, -+- .gc = nf_flow_offload_work_gc, -++ .init = nf_flow_table_init, -+ .free = nf_flow_table_free, -+ .hook = nf_flow_offload_ip_hook, -+ .owner = THIS_MODULE, -+--- a/net/ipv6/netfilter/nf_flow_table_ipv6.c -++++ b/net/ipv6/netfilter/nf_flow_table_ipv6.c -+@@ -8,8 +8,7 @@ -+ -+ static struct nf_flowtable_type flowtable_ipv6 = { -+ .family = NFPROTO_IPV6, -+- .params = &nf_flow_offload_rhash_params, -+- .gc = nf_flow_offload_work_gc, -++ .init = nf_flow_table_init, -+ .free = nf_flow_table_free, -+ .hook = nf_flow_offload_ipv6_hook, -+ .owner = THIS_MODULE, -+--- a/net/netfilter/nf_flow_table_core.c -++++ b/net/netfilter/nf_flow_table_core.c -+@@ -116,16 +116,50 @@ void flow_offload_dead(struct flow_offlo -+ } -+ EXPORT_SYMBOL_GPL(flow_offload_dead); -+ -++static u32 flow_offload_hash(const void *data, u32 len, u32 seed) -++{ -++ const struct flow_offload_tuple *tuple = data; -++ -++ return jhash(tuple, offsetof(struct flow_offload_tuple, dir), seed); -++} -++ -++static u32 flow_offload_hash_obj(const void *data, u32 len, u32 seed) -++{ -++ const struct flow_offload_tuple_rhash *tuplehash = data; -++ -++ return jhash(&tuplehash->tuple, offsetof(struct flow_offload_tuple, dir), seed); -++} -++ -++static int flow_offload_hash_cmp(struct rhashtable_compare_arg *arg, -++ const void *ptr) -++{ -++ const struct flow_offload_tuple *tuple = arg->key; -++ const struct flow_offload_tuple_rhash *x = ptr; -++ -++ if (memcmp(&x->tuple, tuple, offsetof(struct flow_offload_tuple, dir))) -++ return 1; -++ -++ return 0; -++} -++ -++static const struct rhashtable_params nf_flow_offload_rhash_params = { -++ .head_offset = offsetof(struct flow_offload_tuple_rhash, node), -++ .hashfn = flow_offload_hash, -++ .obj_hashfn = flow_offload_hash_obj, -++ .obj_cmpfn = flow_offload_hash_cmp, -++ .automatic_shrinking = true, -++}; -++ -+ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow) -+ { -+ flow->timeout = (u32)jiffies; -+ -+ rhashtable_insert_fast(&flow_table->rhashtable, -+ &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node, -+- *flow_table->type->params); -++ nf_flow_offload_rhash_params); -+ rhashtable_insert_fast(&flow_table->rhashtable, -+ &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].node, -+- *flow_table->type->params); -++ nf_flow_offload_rhash_params); -+ return 0; -+ } -+ EXPORT_SYMBOL_GPL(flow_offload_add); -+@@ -135,10 +169,10 @@ static void flow_offload_del(struct nf_f -+ { -+ rhashtable_remove_fast(&flow_table->rhashtable, -+ &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node, -+- *flow_table->type->params); -++ nf_flow_offload_rhash_params); -+ rhashtable_remove_fast(&flow_table->rhashtable, -+ &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].node, -+- *flow_table->type->params); -++ nf_flow_offload_rhash_params); -+ -+ flow_offload_free(flow); -+ } -+@@ -148,7 +182,7 @@ flow_offload_lookup(struct nf_flowtable -+ struct flow_offload_tuple *tuple) -+ { -+ return rhashtable_lookup_fast(&flow_table->rhashtable, tuple, -+- *flow_table->type->params); -++ nf_flow_offload_rhash_params); -+ } -+ EXPORT_SYMBOL_GPL(flow_offload_lookup); -+ -+@@ -237,7 +271,7 @@ out: -+ return 1; -+ } -+ -+-void nf_flow_offload_work_gc(struct work_struct *work) -++static void nf_flow_offload_work_gc(struct work_struct *work) -+ { -+ struct nf_flowtable *flow_table; -+ -+@@ -245,42 +279,6 @@ void nf_flow_offload_work_gc(struct work -+ nf_flow_offload_gc_step(flow_table); -+ queue_delayed_work(system_power_efficient_wq, &flow_table->gc_work, HZ); -+ } -+-EXPORT_SYMBOL_GPL(nf_flow_offload_work_gc); -+- -+-static u32 flow_offload_hash(const void *data, u32 len, u32 seed) -+-{ -+- const struct flow_offload_tuple *tuple = data; -+- -+- return jhash(tuple, offsetof(struct flow_offload_tuple, dir), seed); -+-} -+- -+-static u32 flow_offload_hash_obj(const void *data, u32 len, u32 seed) -+-{ -+- const struct flow_offload_tuple_rhash *tuplehash = data; -+- -+- return jhash(&tuplehash->tuple, offsetof(struct flow_offload_tuple, dir), seed); -+-} -+- -+-static int flow_offload_hash_cmp(struct rhashtable_compare_arg *arg, -+- const void *ptr) -+-{ -+- const struct flow_offload_tuple *tuple = arg->key; -+- const struct flow_offload_tuple_rhash *x = ptr; -+- -+- if (memcmp(&x->tuple, tuple, offsetof(struct flow_offload_tuple, dir))) -+- return 1; -+- -+- return 0; -+-} -+- -+-const struct rhashtable_params nf_flow_offload_rhash_params = { -+- .head_offset = offsetof(struct flow_offload_tuple_rhash, node), -+- .hashfn = flow_offload_hash, -+- .obj_hashfn = flow_offload_hash_obj, -+- .obj_cmpfn = flow_offload_hash_cmp, -+- .automatic_shrinking = true, -+-}; -+-EXPORT_SYMBOL_GPL(nf_flow_offload_rhash_params); -+ -+ static int nf_flow_nat_port_tcp(struct sk_buff *skb, unsigned int thoff, -+ __be16 port, __be16 new_port) -+@@ -398,6 +396,24 @@ int nf_flow_dnat_port(const struct flow_ -+ } -+ EXPORT_SYMBOL_GPL(nf_flow_dnat_port); -+ -++int nf_flow_table_init(struct nf_flowtable *flowtable) -++{ -++ int err; -++ -++ INIT_DEFERRABLE_WORK(&flowtable->gc_work, nf_flow_offload_work_gc); -++ -++ err = rhashtable_init(&flowtable->rhashtable, -++ &nf_flow_offload_rhash_params); -++ if (err < 0) -++ return err; -++ -++ queue_delayed_work(system_power_efficient_wq, -++ &flowtable->gc_work, HZ); -++ -++ return 0; -++} -++EXPORT_SYMBOL_GPL(nf_flow_table_init); -++ -+ static void nf_flow_table_do_cleanup(struct flow_offload *flow, void *data) -+ { -+ struct net_device *dev = data; -+@@ -423,8 +439,10 @@ EXPORT_SYMBOL_GPL(nf_flow_table_cleanup) -+ -+ void nf_flow_table_free(struct nf_flowtable *flow_table) -+ { -++ cancel_delayed_work_sync(&flow_table->gc_work); -+ nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL); -+ WARN_ON(!nf_flow_offload_gc_step(flow_table)); -++ rhashtable_destroy(&flow_table->rhashtable); -+ } -+ EXPORT_SYMBOL_GPL(nf_flow_table_free); -+ -+--- a/net/netfilter/nf_flow_table_inet.c -++++ b/net/netfilter/nf_flow_table_inet.c -+@@ -22,8 +22,7 @@ nf_flow_offload_inet_hook(void *priv, st -+ -+ static struct nf_flowtable_type flowtable_inet = { -+ .family = NFPROTO_INET, -+- .params = &nf_flow_offload_rhash_params, -+- .gc = nf_flow_offload_work_gc, -++ .init = nf_flow_table_init, -+ .free = nf_flow_table_free, -+ .hook = nf_flow_offload_inet_hook, -+ .owner = THIS_MODULE, -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -5108,40 +5108,38 @@ static int nf_tables_newflowtable(struct -+ } -+ -+ flowtable->data.type = type; -+- err = rhashtable_init(&flowtable->data.rhashtable, type->params); -++ err = type->init(&flowtable->data); -+ if (err < 0) -+ goto err3; -+ -+ err = nf_tables_flowtable_parse_hook(&ctx, nla[NFTA_FLOWTABLE_HOOK], -+ flowtable); -+ if (err < 0) -+- goto err3; -++ goto err4; -+ -+ for (i = 0; i < flowtable->ops_len; i++) { -+ err = nf_register_net_hook(net, &flowtable->ops[i]); -+ if (err < 0) -+- goto err4; -++ goto err5; -+ } -+ -+ err = nft_trans_flowtable_add(&ctx, NFT_MSG_NEWFLOWTABLE, flowtable); -+ if (err < 0) -+- goto err5; -+- -+- INIT_DEFERRABLE_WORK(&flowtable->data.gc_work, type->gc); -+- queue_delayed_work(system_power_efficient_wq, -+- &flowtable->data.gc_work, HZ); -++ goto err6; -+ -+ list_add_tail_rcu(&flowtable->list, &table->flowtables); -+ table->use++; -+ -+ return 0; -+-err5: -++err6: -+ i = flowtable->ops_len; -+-err4: -++err5: -+ for (k = i - 1; k >= 0; k--) -+ nf_unregister_net_hook(net, &flowtable->ops[i]); -+ -+ kfree(flowtable->ops); -++err4: -++ flowtable->data.type->free(&flowtable->data); -+ err3: -+ module_put(type->owner); -+ err2: -+@@ -5422,10 +5420,8 @@ err: -+ -+ static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable) -+ { -+- cancel_delayed_work_sync(&flowtable->data.gc_work); -+ kfree(flowtable->name); -+ flowtable->data.type->free(&flowtable->data); -+- rhashtable_destroy(&flowtable->data.rhashtable); -+ module_put(flowtable->data.type->owner); -+ } -+ -diff --git a/target/linux/generic/backport-4.14/358-v4.18-netfilter-nf_flow_table-fix-priv-pointer-for-netdev-.patch b/target/linux/generic/backport-4.14/358-v4.18-netfilter-nf_flow_table-fix-priv-pointer-for-netdev-.patch -new file mode 100644 -index 0000000000..ea86e761d7 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/358-v4.18-netfilter-nf_flow_table-fix-priv-pointer-for-netdev-.patch -@@ -0,0 +1,22 @@ -+From: Felix Fietkau -+Date: Tue, 20 Feb 2018 14:48:51 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: fix priv pointer for netdev hook -+ -+The offload ip hook expects a pointer to the flowtable, not to the -+rhashtable. Since the rhashtable is the first member, this is safe for -+the moment, but breaks as soon as the structure layout changes -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -4974,7 +4974,7 @@ static int nf_tables_flowtable_parse_hoo -+ flowtable->ops[i].pf = NFPROTO_NETDEV; -+ flowtable->ops[i].hooknum = hooknum; -+ flowtable->ops[i].priority = priority; -+- flowtable->ops[i].priv = &flowtable->data.rhashtable; -++ flowtable->ops[i].priv = &flowtable->data; -+ flowtable->ops[i].hook = flowtable->data.type->hook; -+ flowtable->ops[i].dev = dev_array[i]; -+ } -diff --git a/target/linux/generic/backport-4.14/359-v4.18-netfilter-nf_flow_table-track-flow-tables-in-nf_flow.patch b/target/linux/generic/backport-4.14/359-v4.18-netfilter-nf_flow_table-track-flow-tables-in-nf_flow.patch -new file mode 100644 -index 0000000000..643189b5c0 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/359-v4.18-netfilter-nf_flow_table-track-flow-tables-in-nf_flow.patch -@@ -0,0 +1,114 @@ -+From: Felix Fietkau -+Date: Tue, 20 Feb 2018 14:08:14 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: track flow tables in nf_flow_table -+ directly -+ -+Avoids having nf_flow_table depend on nftables (useful for future -+iptables backport work) -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -21,6 +21,7 @@ struct nf_flowtable_type { -+ }; -+ -+ struct nf_flowtable { -++ struct list_head list; -+ struct rhashtable rhashtable; -+ const struct nf_flowtable_type *type; -+ struct delayed_work gc_work; -+--- a/include/net/netfilter/nf_tables.h -++++ b/include/net/netfilter/nf_tables.h -+@@ -1097,9 +1097,6 @@ struct nft_flowtable { -+ struct nft_flowtable *nf_tables_flowtable_lookup(const struct nft_table *table, -+ const struct nlattr *nla, -+ u8 genmask); -+-void nft_flow_table_iterate(struct net *net, -+- void (*iter)(struct nf_flowtable *flowtable, void *data), -+- void *data); -+ -+ void nft_register_flowtable_type(struct nf_flowtable_type *type); -+ void nft_unregister_flowtable_type(struct nf_flowtable_type *type); -+--- a/net/netfilter/nf_flow_table_core.c -++++ b/net/netfilter/nf_flow_table_core.c -+@@ -18,6 +18,9 @@ struct flow_offload_entry { -+ struct rcu_head rcu_head; -+ }; -+ -++static DEFINE_MUTEX(flowtable_lock); -++static LIST_HEAD(flowtables); -++ -+ static void -+ flow_offload_fill_dir(struct flow_offload *flow, struct nf_conn *ct, -+ struct nf_flow_route *route, -+@@ -410,6 +413,10 @@ int nf_flow_table_init(struct nf_flowtab -+ queue_delayed_work(system_power_efficient_wq, -+ &flowtable->gc_work, HZ); -+ -++ mutex_lock(&flowtable_lock); -++ list_add(&flowtable->list, &flowtables); -++ mutex_unlock(&flowtable_lock); -++ -+ return 0; -+ } -+ EXPORT_SYMBOL_GPL(nf_flow_table_init); -+@@ -425,20 +432,28 @@ static void nf_flow_table_do_cleanup(str -+ } -+ -+ static void nf_flow_table_iterate_cleanup(struct nf_flowtable *flowtable, -+- void *data) -++ struct net_device *dev) -+ { -+- nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, data); -++ nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, dev); -+ flush_delayed_work(&flowtable->gc_work); -+ } -+ -+ void nf_flow_table_cleanup(struct net *net, struct net_device *dev) -+ { -+- nft_flow_table_iterate(net, nf_flow_table_iterate_cleanup, dev); -++ struct nf_flowtable *flowtable; -++ -++ mutex_lock(&flowtable_lock); -++ list_for_each_entry(flowtable, &flowtables, list) -++ nf_flow_table_iterate_cleanup(flowtable, dev); -++ mutex_unlock(&flowtable_lock); -+ } -+ EXPORT_SYMBOL_GPL(nf_flow_table_cleanup); -+ -+ void nf_flow_table_free(struct nf_flowtable *flow_table) -+ { -++ mutex_lock(&flowtable_lock); -++ list_del(&flow_table->list); -++ mutex_unlock(&flowtable_lock); -+ cancel_delayed_work_sync(&flow_table->gc_work); -+ nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL); -+ WARN_ON(!nf_flow_offload_gc_step(flow_table)); -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -5018,23 +5018,6 @@ static const struct nf_flowtable_type *n -+ return ERR_PTR(-ENOENT); -+ } -+ -+-void nft_flow_table_iterate(struct net *net, -+- void (*iter)(struct nf_flowtable *flowtable, void *data), -+- void *data) -+-{ -+- struct nft_flowtable *flowtable; -+- const struct nft_table *table; -+- -+- nfnl_lock(NFNL_SUBSYS_NFTABLES); -+- list_for_each_entry(table, &net->nft.tables, list) { -+- list_for_each_entry(flowtable, &table->flowtables, list) { -+- iter(&flowtable->data, data); -+- } -+- } -+- nfnl_unlock(NFNL_SUBSYS_NFTABLES); -+-} -+-EXPORT_SYMBOL_GPL(nft_flow_table_iterate); -+- -+ static void nft_unregister_flowtable_net_hooks(struct net *net, -+ struct nft_flowtable *flowtable) -+ { -diff --git a/target/linux/generic/backport-4.14/360-v4.18-netfilter-nf_flow_table-make-flow_offload_dead-inlin.patch b/target/linux/generic/backport-4.14/360-v4.18-netfilter-nf_flow_table-make-flow_offload_dead-inlin.patch -new file mode 100644 -index 0000000000..d33400c729 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/360-v4.18-netfilter-nf_flow_table-make-flow_offload_dead-inlin.patch -@@ -0,0 +1,38 @@ -+From: Felix Fietkau -+Date: Sun, 25 Feb 2018 15:37:27 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: make flow_offload_dead inline -+ -+It is too trivial to keep as a separate exported function -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -103,7 +103,10 @@ void nf_flow_table_cleanup(struct net *n -+ int nf_flow_table_init(struct nf_flowtable *flow_table); -+ void nf_flow_table_free(struct nf_flowtable *flow_table); -+ -+-void flow_offload_dead(struct flow_offload *flow); -++static inline void flow_offload_dead(struct flow_offload *flow) -++{ -++ flow->flags |= FLOW_OFFLOAD_DYING; -++} -+ -+ int nf_flow_snat_port(const struct flow_offload *flow, -+ struct sk_buff *skb, unsigned int thoff, -+--- a/net/netfilter/nf_flow_table_core.c -++++ b/net/netfilter/nf_flow_table_core.c -+@@ -113,12 +113,6 @@ void flow_offload_free(struct flow_offlo -+ } -+ EXPORT_SYMBOL_GPL(flow_offload_free); -+ -+-void flow_offload_dead(struct flow_offload *flow) -+-{ -+- flow->flags |= FLOW_OFFLOAD_DYING; -+-} -+-EXPORT_SYMBOL_GPL(flow_offload_dead); -+- -+ static u32 flow_offload_hash(const void *data, u32 len, u32 seed) -+ { -+ const struct flow_offload_tuple *tuple = data; -diff --git a/target/linux/generic/backport-4.14/361-v4.18-netfilter-nf_flow_table-add-a-new-flow-state-for-tea.patch b/target/linux/generic/backport-4.14/361-v4.18-netfilter-nf_flow_table-add-a-new-flow-state-for-tea.patch -new file mode 100644 -index 0000000000..30cebfac60 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/361-v4.18-netfilter-nf_flow_table-add-a-new-flow-state-for-tea.patch -@@ -0,0 +1,83 @@ -+From: Felix Fietkau -+Date: Sun, 25 Feb 2018 15:38:31 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: add a new flow state for -+ tearing down offloading -+ -+Will be used to tear down the offload entry while keeping the conntrack -+entry alive. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -68,6 +68,7 @@ struct flow_offload_tuple_rhash { -+ #define FLOW_OFFLOAD_SNAT 0x1 -+ #define FLOW_OFFLOAD_DNAT 0x2 -+ #define FLOW_OFFLOAD_DYING 0x4 -++#define FLOW_OFFLOAD_TEARDOWN 0x8 -+ -+ struct flow_offload { -+ struct flow_offload_tuple_rhash tuplehash[FLOW_OFFLOAD_DIR_MAX]; -+@@ -103,6 +104,7 @@ void nf_flow_table_cleanup(struct net *n -+ int nf_flow_table_init(struct nf_flowtable *flow_table); -+ void nf_flow_table_free(struct nf_flowtable *flow_table); -+ -++void flow_offload_teardown(struct flow_offload *flow); -+ static inline void flow_offload_dead(struct flow_offload *flow) -+ { -+ flow->flags |= FLOW_OFFLOAD_DYING; -+--- a/net/netfilter/nf_flow_table_core.c -++++ b/net/netfilter/nf_flow_table_core.c -+@@ -174,6 +174,12 @@ static void flow_offload_del(struct nf_f -+ flow_offload_free(flow); -+ } -+ -++void flow_offload_teardown(struct flow_offload *flow) -++{ -++ flow->flags |= FLOW_OFFLOAD_TEARDOWN; -++} -++EXPORT_SYMBOL_GPL(flow_offload_teardown); -++ -+ struct flow_offload_tuple_rhash * -+ flow_offload_lookup(struct nf_flowtable *flow_table, -+ struct flow_offload_tuple *tuple) -+@@ -226,11 +232,6 @@ static inline bool nf_flow_has_expired(c -+ return (__s32)(flow->timeout - (u32)jiffies) <= 0; -+ } -+ -+-static inline bool nf_flow_is_dying(const struct flow_offload *flow) -+-{ -+- return flow->flags & FLOW_OFFLOAD_DYING; -+-} -+- -+ static int nf_flow_offload_gc_step(struct nf_flowtable *flow_table) -+ { -+ struct flow_offload_tuple_rhash *tuplehash; -+@@ -258,7 +259,8 @@ static int nf_flow_offload_gc_step(struc -+ flow = container_of(tuplehash, struct flow_offload, tuplehash[0]); -+ -+ if (nf_flow_has_expired(flow) || -+- nf_flow_is_dying(flow)) -++ (flow->flags & (FLOW_OFFLOAD_DYING | -++ FLOW_OFFLOAD_TEARDOWN))) -+ flow_offload_del(flow_table, flow); -+ } -+ out: -+@@ -419,10 +421,14 @@ static void nf_flow_table_do_cleanup(str -+ { -+ struct net_device *dev = data; -+ -+- if (dev && flow->tuplehash[0].tuple.iifidx != dev->ifindex) -++ if (!dev) { -++ flow_offload_teardown(flow); -+ return; -++ } -+ -+- flow_offload_dead(flow); -++ if (flow->tuplehash[0].tuple.iifidx == dev->ifindex || -++ flow->tuplehash[1].tuple.iifidx == dev->ifindex) -++ flow_offload_dead(flow); -+ } -+ -+ static void nf_flow_table_iterate_cleanup(struct nf_flowtable *flowtable, -diff --git a/target/linux/generic/backport-4.14/362-v4.18-netfilter-nf_flow_table-in-flow_offload_lookup-skip-.patch b/target/linux/generic/backport-4.14/362-v4.18-netfilter-nf_flow_table-in-flow_offload_lookup-skip-.patch -new file mode 100644 -index 0000000000..d14ac97a59 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/362-v4.18-netfilter-nf_flow_table-in-flow_offload_lookup-skip-.patch -@@ -0,0 +1,36 @@ -+From: Felix Fietkau -+Date: Sun, 25 Feb 2018 15:39:56 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: in flow_offload_lookup, skip -+ entries being deleted -+ -+Preparation for sending flows back to the slow path -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/netfilter/nf_flow_table_core.c -++++ b/net/netfilter/nf_flow_table_core.c -+@@ -184,8 +184,21 @@ struct flow_offload_tuple_rhash * -+ flow_offload_lookup(struct nf_flowtable *flow_table, -+ struct flow_offload_tuple *tuple) -+ { -+- return rhashtable_lookup_fast(&flow_table->rhashtable, tuple, -+- nf_flow_offload_rhash_params); -++ struct flow_offload_tuple_rhash *tuplehash; -++ struct flow_offload *flow; -++ int dir; -++ -++ tuplehash = rhashtable_lookup_fast(&flow_table->rhashtable, tuple, -++ nf_flow_offload_rhash_params); -++ if (!tuplehash) -++ return NULL; -++ -++ dir = tuplehash->tuple.dir; -++ flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); -++ if (flow->flags & (FLOW_OFFLOAD_DYING | FLOW_OFFLOAD_TEARDOWN)) -++ return NULL; -++ -++ return tuplehash; -+ } -+ EXPORT_SYMBOL_GPL(flow_offload_lookup); -+ -diff --git a/target/linux/generic/backport-4.14/363-v4.18-netfilter-nf_flow_table-add-support-for-sending-flow.patch b/target/linux/generic/backport-4.14/363-v4.18-netfilter-nf_flow_table-add-support-for-sending-flow.patch -new file mode 100644 -index 0000000000..905880fead ---- /dev/null -+++ b/target/linux/generic/backport-4.14/363-v4.18-netfilter-nf_flow_table-add-support-for-sending-flow.patch -@@ -0,0 +1,99 @@ -+From: Felix Fietkau -+Date: Sun, 25 Feb 2018 15:41:11 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: add support for sending flows -+ back to the slow path -+ -+Reset the timeout. For TCP, also set the state to indicate to use the -+next incoming packets to reset window tracking. -+This allows the slow path to take over again once the offload state has -+been torn down -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/netfilter/nf_flow_table_core.c -++++ b/net/netfilter/nf_flow_table_core.c -+@@ -100,6 +100,43 @@ err_ct_refcnt: -+ } -+ EXPORT_SYMBOL_GPL(flow_offload_alloc); -+ -++static void flow_offload_fixup_tcp(struct ip_ct_tcp *tcp) -++{ -++ tcp->state = TCP_CONNTRACK_ESTABLISHED; -++ tcp->seen[0].td_maxwin = 0; -++ tcp->seen[1].td_maxwin = 0; -++} -++ -++static void flow_offload_fixup_ct_state(struct nf_conn *ct) -++{ -++ const struct nf_conntrack_l4proto *l4proto; -++ struct net *net = nf_ct_net(ct); -++ unsigned int *timeouts; -++ unsigned int timeout; -++ int l4num; -++ -++ l4num = nf_ct_protonum(ct); -++ if (l4num == IPPROTO_TCP) -++ flow_offload_fixup_tcp(&ct->proto.tcp); -++ -++ l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), l4num); -++ if (!l4proto) -++ return; -++ -++ timeouts = l4proto->get_timeouts(net); -++ if (!timeouts) -++ return; -++ -++ if (l4num == IPPROTO_TCP) -++ timeout = timeouts[TCP_CONNTRACK_ESTABLISHED]; -++ else if (l4num == IPPROTO_UDP) -++ timeout = timeouts[UDP_CT_REPLIED]; -++ else -++ return; -++ -++ ct->timeout = nfct_time_stamp + timeout; -++} -++ -+ void flow_offload_free(struct flow_offload *flow) -+ { -+ struct flow_offload_entry *e; -+@@ -107,7 +144,8 @@ void flow_offload_free(struct flow_offlo -+ dst_release(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_cache); -+ dst_release(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_cache); -+ e = container_of(flow, struct flow_offload_entry, flow); -+- nf_ct_delete(e->ct, 0, 0); -++ if (flow->flags & FLOW_OFFLOAD_DYING) -++ nf_ct_delete(e->ct, 0, 0); -+ nf_ct_put(e->ct); -+ kfree_rcu(e, rcu_head); -+ } -+@@ -164,6 +202,8 @@ EXPORT_SYMBOL_GPL(flow_offload_add); -+ static void flow_offload_del(struct nf_flowtable *flow_table, -+ struct flow_offload *flow) -+ { -++ struct flow_offload_entry *e; -++ -+ rhashtable_remove_fast(&flow_table->rhashtable, -+ &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node, -+ nf_flow_offload_rhash_params); -+@@ -171,12 +211,20 @@ static void flow_offload_del(struct nf_f -+ &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].node, -+ nf_flow_offload_rhash_params); -+ -++ e = container_of(flow, struct flow_offload_entry, flow); -++ clear_bit(IPS_OFFLOAD_BIT, &e->ct->status); -++ -+ flow_offload_free(flow); -+ } -+ -+ void flow_offload_teardown(struct flow_offload *flow) -+ { -++ struct flow_offload_entry *e; -++ -+ flow->flags |= FLOW_OFFLOAD_TEARDOWN; -++ -++ e = container_of(flow, struct flow_offload_entry, flow); -++ flow_offload_fixup_ct_state(e->ct); -+ } -+ EXPORT_SYMBOL_GPL(flow_offload_teardown); -+ -diff --git a/target/linux/generic/backport-4.14/364-v4.18-netfilter-nf_flow_table-tear-down-TCP-flows-if-RST-o.patch b/target/linux/generic/backport-4.14/364-v4.18-netfilter-nf_flow_table-tear-down-TCP-flows-if-RST-o.patch -new file mode 100644 -index 0000000000..8b0024cd8d ---- /dev/null -+++ b/target/linux/generic/backport-4.14/364-v4.18-netfilter-nf_flow_table-tear-down-TCP-flows-if-RST-o.patch -@@ -0,0 +1,81 @@ -+From: Felix Fietkau -+Date: Sun, 25 Feb 2018 15:42:58 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: tear down TCP flows if RST or -+ FIN was seen -+ -+Allow the slow path to handle the shutdown of the connection with proper -+timeouts -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/netfilter/nf_flow_table_ip.c -++++ b/net/netfilter/nf_flow_table_ip.c -+@@ -15,6 +15,23 @@ -+ #include -+ #include -+ -++static int nf_flow_tcp_state_check(struct flow_offload *flow, -++ struct sk_buff *skb, unsigned int thoff) -++{ -++ struct tcphdr *tcph; -++ -++ if (!pskb_may_pull(skb, thoff + sizeof(*tcph))) -++ return -1; -++ -++ tcph = (void *)(skb_network_header(skb) + thoff); -++ if (unlikely(tcph->fin || tcph->rst)) { -++ flow_offload_teardown(flow); -++ return -1; -++ } -++ -++ return 0; -++} -++ -+ static int nf_flow_nat_ip_tcp(struct sk_buff *skb, unsigned int thoff, -+ __be32 addr, __be32 new_addr) -+ { -+@@ -118,10 +135,9 @@ static int nf_flow_dnat_ip(const struct -+ } -+ -+ static int nf_flow_nat_ip(const struct flow_offload *flow, struct sk_buff *skb, -+- enum flow_offload_tuple_dir dir) -++ unsigned int thoff, enum flow_offload_tuple_dir dir) -+ { -+ struct iphdr *iph = ip_hdr(skb); -+- unsigned int thoff = iph->ihl * 4; -+ -+ if (flow->flags & FLOW_OFFLOAD_SNAT && -+ (nf_flow_snat_port(flow, skb, thoff, iph->protocol, dir) < 0 || -+@@ -201,6 +217,7 @@ nf_flow_offload_ip_hook(void *priv, stru -+ struct flow_offload *flow; -+ struct net_device *outdev; -+ const struct rtable *rt; -++ unsigned int thoff; -+ struct iphdr *iph; -+ __be32 nexthop; -+ -+@@ -229,8 +246,12 @@ nf_flow_offload_ip_hook(void *priv, stru -+ if (skb_try_make_writable(skb, sizeof(*iph))) -+ return NF_DROP; -+ -++ thoff = ip_hdr(skb)->ihl * 4; -++ if (nf_flow_tcp_state_check(flow, skb, thoff)) -++ return NF_ACCEPT; -++ -+ if (flow->flags & (FLOW_OFFLOAD_SNAT | FLOW_OFFLOAD_DNAT) && -+- nf_flow_nat_ip(flow, skb, dir) < 0) -++ nf_flow_nat_ip(flow, skb, thoff, dir) < 0) -+ return NF_DROP; -+ -+ flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT; -+@@ -438,6 +459,9 @@ nf_flow_offload_ipv6_hook(void *priv, st -+ if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu))) -+ return NF_ACCEPT; -+ -++ if (nf_flow_tcp_state_check(flow, skb, sizeof(*ip6h))) -++ return NF_ACCEPT; -++ -+ if (skb_try_make_writable(skb, sizeof(*ip6h))) -+ return NF_DROP; -+ -diff --git a/target/linux/generic/backport-4.14/365-v4.16-netfilter-nf_flow_table-fix-checksum-when-handling-D.patch b/target/linux/generic/backport-4.14/365-v4.16-netfilter-nf_flow_table-fix-checksum-when-handling-D.patch -new file mode 100644 -index 0000000000..372c8d59ef ---- /dev/null -+++ b/target/linux/generic/backport-4.14/365-v4.16-netfilter-nf_flow_table-fix-checksum-when-handling-D.patch -@@ -0,0 +1,19 @@ -+From: Felix Fietkau -+Date: Sun, 25 Feb 2018 17:22:55 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: fix checksum when handling DNAT -+ -+Add a missing call to csum_replace4 like on SNAT -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/netfilter/nf_flow_table_ip.c -++++ b/net/netfilter/nf_flow_table_ip.c -+@@ -130,6 +130,7 @@ static int nf_flow_dnat_ip(const struct -+ default: -+ return -1; -+ } -++ csum_replace4(&iph->check, addr, new_addr); -+ -+ return nf_flow_nat_ip_l4proto(skb, iph, thoff, addr, new_addr); -+ } -diff --git a/target/linux/generic/backport-4.14/366-netfilter-nft_flow_offload-Fix-reverse-route-lookup.patch b/target/linux/generic/backport-4.14/366-netfilter-nft_flow_offload-Fix-reverse-route-lookup.patch -new file mode 100644 -index 0000000000..e91aaa91d7 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/366-netfilter-nft_flow_offload-Fix-reverse-route-lookup.patch -@@ -0,0 +1,39 @@ -+From: wenxu -+Date: Wed, 9 Jan 2019 10:40:11 +0800 -+Subject: [PATCH] netfilter: nft_flow_offload: Fix reverse route lookup -+ -+Using the following example: -+ -+ client 1.1.1.7 ---> 2.2.2.7 which dnat to 10.0.0.7 server -+ -+The first reply packet (ie. syn+ack) uses an incorrect destination -+address for the reverse route lookup since it uses: -+ -+ daddr = ct->tuplehash[!dir].tuple.dst.u3.ip; -+ -+which is 2.2.2.7 in the scenario that is described above, while this -+should be: -+ -+ daddr = ct->tuplehash[dir].tuple.src.u3.ip; -+ -+that is 10.0.0.7. -+ -+Signed-off-by: wenxu -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/net/netfilter/nft_flow_offload.c -++++ b/net/netfilter/nft_flow_offload.c -+@@ -29,10 +29,10 @@ static int nft_flow_route(const struct n -+ memset(&fl, 0, sizeof(fl)); -+ switch (nft_pf(pkt)) { -+ case NFPROTO_IPV4: -+- fl.u.ip4.daddr = ct->tuplehash[!dir].tuple.dst.u3.ip; -++ fl.u.ip4.daddr = ct->tuplehash[dir].tuple.src.u3.ip; -+ break; -+ case NFPROTO_IPV6: -+- fl.u.ip6.daddr = ct->tuplehash[!dir].tuple.dst.u3.in6; -++ fl.u.ip6.daddr = ct->tuplehash[dir].tuple.src.u3.in6; -+ break; -+ } -+ -diff --git a/target/linux/generic/backport-4.14/367-v4.18-netfilter-nf_flow_table-add-missing-condition-for-TC.patch b/target/linux/generic/backport-4.14/367-v4.18-netfilter-nf_flow_table-add-missing-condition-for-TC.patch -new file mode 100644 -index 0000000000..2a470f77e3 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/367-v4.18-netfilter-nf_flow_table-add-missing-condition-for-TC.patch -@@ -0,0 +1,48 @@ -+From: Felix Fietkau -+Date: Fri, 23 Mar 2018 17:15:22 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: add missing condition for TCP state -+ check -+ -+Avoid looking at unrelated fields in UDP packets -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/netfilter/nf_flow_table_ip.c -++++ b/net/netfilter/nf_flow_table_ip.c -+@@ -15,11 +15,14 @@ -+ #include -+ #include -+ -+-static int nf_flow_tcp_state_check(struct flow_offload *flow, -+- struct sk_buff *skb, unsigned int thoff) -++static int nf_flow_state_check(struct flow_offload *flow, int proto, -++ struct sk_buff *skb, unsigned int thoff) -+ { -+ struct tcphdr *tcph; -+ -++ if (proto != IPPROTO_TCP) -++ return 0; -++ -+ if (!pskb_may_pull(skb, thoff + sizeof(*tcph))) -+ return -1; -+ -+@@ -248,7 +251,7 @@ nf_flow_offload_ip_hook(void *priv, stru -+ return NF_DROP; -+ -+ thoff = ip_hdr(skb)->ihl * 4; -+- if (nf_flow_tcp_state_check(flow, skb, thoff)) -++ if (nf_flow_state_check(flow, ip_hdr(skb)->protocol, skb, thoff)) -+ return NF_ACCEPT; -+ -+ if (flow->flags & (FLOW_OFFLOAD_SNAT | FLOW_OFFLOAD_DNAT) && -+@@ -460,7 +463,8 @@ nf_flow_offload_ipv6_hook(void *priv, st -+ if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu))) -+ return NF_ACCEPT; -+ -+- if (nf_flow_tcp_state_check(flow, skb, sizeof(*ip6h))) -++ if (nf_flow_state_check(flow, ipv6_hdr(skb)->nexthdr, skb, -++ sizeof(*ip6h))) -+ return NF_ACCEPT; -+ -+ if (skb_try_make_writable(skb, sizeof(*ip6h))) -diff --git a/target/linux/generic/backport-4.14/368-v4.18-netfilter-nf_flow_table-fix-offloading-connections-w.patch b/target/linux/generic/backport-4.14/368-v4.18-netfilter-nf_flow_table-fix-offloading-connections-w.patch -new file mode 100644 -index 0000000000..f3d83a1536 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/368-v4.18-netfilter-nf_flow_table-fix-offloading-connections-w.patch -@@ -0,0 +1,23 @@ -+From: Felix Fietkau -+Date: Fri, 23 Mar 2018 19:12:30 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: fix offloading connections with -+ SNAT+DNAT -+ -+Pass all NAT types to the flow offload struct, otherwise parts of the -+address/port pair do not get translated properly, causing connection -+stalls -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/netfilter/nf_flow_table_core.c -++++ b/net/netfilter/nf_flow_table_core.c -+@@ -84,7 +84,7 @@ flow_offload_alloc(struct nf_conn *ct, s -+ -+ if (ct->status & IPS_SRC_NAT) -+ flow->flags |= FLOW_OFFLOAD_SNAT; -+- else if (ct->status & IPS_DST_NAT) -++ if (ct->status & IPS_DST_NAT) -+ flow->flags |= FLOW_OFFLOAD_DNAT; -+ -+ return flow; -diff --git a/target/linux/generic/backport-4.14/369-v4.18-netfilter-nf_flow_table-attach-dst-to-skbs.patch b/target/linux/generic/backport-4.14/369-v4.18-netfilter-nf_flow_table-attach-dst-to-skbs.patch -new file mode 100644 -index 0000000000..ad72d65c77 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/369-v4.18-netfilter-nf_flow_table-attach-dst-to-skbs.patch -@@ -0,0 +1,49 @@ -+From: "Jason A. Donenfeld" -+Date: Wed, 30 May 2018 20:43:15 +0200 -+Subject: [PATCH] netfilter: nf_flow_table: attach dst to skbs -+ -+Some drivers, such as vxlan and wireguard, use the skb's dst in order to -+determine things like PMTU. They therefore loose functionality when flow -+offloading is enabled. So, we ensure the skb has it before xmit'ing it -+in the offloading path. -+ -+Signed-off-by: Jason A. Donenfeld -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/net/netfilter/nf_flow_table_ip.c -++++ b/net/netfilter/nf_flow_table_ip.c -+@@ -220,7 +220,7 @@ nf_flow_offload_ip_hook(void *priv, stru -+ enum flow_offload_tuple_dir dir; -+ struct flow_offload *flow; -+ struct net_device *outdev; -+- const struct rtable *rt; -++ struct rtable *rt; -+ unsigned int thoff; -+ struct iphdr *iph; -+ __be32 nexthop; -+@@ -241,7 +241,7 @@ nf_flow_offload_ip_hook(void *priv, stru -+ -+ dir = tuplehash->tuple.dir; -+ flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); -+- rt = (const struct rtable *)flow->tuplehash[dir].tuple.dst_cache; -++ rt = (struct rtable *)flow->tuplehash[dir].tuple.dst_cache; -+ -+ if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu)) && -+ (ip_hdr(skb)->frag_off & htons(IP_DF)) != 0) -+@@ -264,6 +264,7 @@ nf_flow_offload_ip_hook(void *priv, stru -+ -+ skb->dev = outdev; -+ nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr); -++ skb_dst_set_noref(skb, &rt->dst); -+ neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb); -+ -+ return NF_STOLEN; -+@@ -480,6 +481,7 @@ nf_flow_offload_ipv6_hook(void *priv, st -+ -+ skb->dev = outdev; -+ nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6); -++ skb_dst_set_noref(skb, &rt->dst); -+ neigh_xmit(NEIGH_ND_TABLE, outdev, nexthop, skb); -+ -+ return NF_STOLEN; -diff --git a/target/linux/generic/backport-4.14/370-netfilter-nf_flow_table-fix-offloaded-connection-tim.patch b/target/linux/generic/backport-4.14/370-netfilter-nf_flow_table-fix-offloaded-connection-tim.patch -new file mode 100644 -index 0000000000..d82854908f ---- /dev/null -+++ b/target/linux/generic/backport-4.14/370-netfilter-nf_flow_table-fix-offloaded-connection-tim.patch -@@ -0,0 +1,110 @@ -+From: Felix Fietkau -+Date: Wed, 13 Jun 2018 12:33:39 +0200 -+Subject: [PATCH] netfilter: nf_flow_table: fix offloaded connection timeout -+ corner case -+ -+The full teardown of offloaded flows is deferred to a gc work item, -+however processing of packets by netfilter needs to happen immediately -+after a teardown is requested, because the conntrack state needs to be -+fixed up. -+ -+Since the IPS_OFFLOAD_BIT is still kept until the teardown is complete, -+the netfilter conntrack gc can accidentally bump the timeout of a -+connection where offload was just stopped, causing a conntrack entry -+leak. -+ -+Fix this by moving the conntrack timeout bumping from conntrack core to -+the nf_flow_offload and add a check to prevent bogus timeout bumps. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/netfilter/nf_conntrack_core.c -++++ b/net/netfilter/nf_conntrack_core.c -+@@ -1054,18 +1054,6 @@ static bool gc_worker_can_early_drop(con -+ return false; -+ } -+ -+-#define DAY (86400 * HZ) -+- -+-/* Set an arbitrary timeout large enough not to ever expire, this save -+- * us a check for the IPS_OFFLOAD_BIT from the packet path via -+- * nf_ct_is_expired(). -+- */ -+-static void nf_ct_offload_timeout(struct nf_conn *ct) -+-{ -+- if (nf_ct_expires(ct) < DAY / 2) -+- ct->timeout = nfct_time_stamp + DAY; -+-} -+- -+ static void gc_worker(struct work_struct *work) -+ { -+ unsigned int min_interval = max(HZ / GC_MAX_BUCKETS_DIV, 1u); -+@@ -1102,10 +1090,8 @@ static void gc_worker(struct work_struct -+ tmp = nf_ct_tuplehash_to_ctrack(h); -+ -+ scanned++; -+- if (test_bit(IPS_OFFLOAD_BIT, &tmp->status)) { -+- nf_ct_offload_timeout(tmp); -++ if (test_bit(IPS_OFFLOAD_BIT, &tmp->status)) -+ continue; -+- } -+ -+ if (nf_ct_is_expired(tmp)) { -+ nf_ct_gc_expired(tmp); -+--- a/net/netfilter/nf_flow_table_core.c -++++ b/net/netfilter/nf_flow_table_core.c -+@@ -185,8 +185,27 @@ static const struct rhashtable_params nf -+ .automatic_shrinking = true, -+ }; -+ -++#define DAY (86400 * HZ) -++ -++/* Set an arbitrary timeout large enough not to ever expire, this save -++ * us a check for the IPS_OFFLOAD_BIT from the packet path via -++ * nf_ct_is_expired(). -++ */ -++static void nf_ct_offload_timeout(struct flow_offload *flow) -++{ -++ struct flow_offload_entry *entry; -++ struct nf_conn *ct; -++ -++ entry = container_of(flow, struct flow_offload_entry, flow); -++ ct = entry->ct; -++ -++ if (nf_ct_expires(ct) < DAY / 2) -++ ct->timeout = nfct_time_stamp + DAY; -++} -++ -+ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow) -+ { -++ nf_ct_offload_timeout(flow); -+ flow->timeout = (u32)jiffies; -+ -+ rhashtable_insert_fast(&flow_table->rhashtable, -+@@ -307,6 +326,8 @@ static int nf_flow_offload_gc_step(struc -+ rhashtable_walk_start(&hti); -+ -+ while ((tuplehash = rhashtable_walk_next(&hti))) { -++ bool teardown; -++ -+ if (IS_ERR(tuplehash)) { -+ err = PTR_ERR(tuplehash); -+ if (err != -EAGAIN) -+@@ -319,9 +340,13 @@ static int nf_flow_offload_gc_step(struc -+ -+ flow = container_of(tuplehash, struct flow_offload, tuplehash[0]); -+ -+- if (nf_flow_has_expired(flow) || -+- (flow->flags & (FLOW_OFFLOAD_DYING | -+- FLOW_OFFLOAD_TEARDOWN))) -++ teardown = flow->flags & (FLOW_OFFLOAD_DYING | -++ FLOW_OFFLOAD_TEARDOWN); -++ -++ if (!teardown) -++ nf_ct_offload_timeout(flow); -++ -++ if (nf_flow_has_expired(flow) || teardown) -+ flow_offload_del(flow_table, flow); -+ } -+ out: -diff --git a/target/linux/generic/backport-4.14/371-netfilter-nf_flow_table-fix-up-ct-state-of-flows-aft.patch b/target/linux/generic/backport-4.14/371-netfilter-nf_flow_table-fix-up-ct-state-of-flows-aft.patch -new file mode 100644 -index 0000000000..fb14a284ae ---- /dev/null -+++ b/target/linux/generic/backport-4.14/371-netfilter-nf_flow_table-fix-up-ct-state-of-flows-aft.patch -@@ -0,0 +1,24 @@ -+From: Felix Fietkau -+Date: Thu, 14 Jun 2018 11:20:09 +0200 -+Subject: [PATCH] netfilter: nf_flow_table: fix up ct state of flows after -+ timeout -+ -+If a connection simply times out instead of being torn down, it is left -+active with a long timeout. Fix this by calling flow_offload_fixup_ct_state -+here as well. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/netfilter/nf_flow_table_core.c -++++ b/net/netfilter/nf_flow_table_core.c -+@@ -233,6 +233,9 @@ static void flow_offload_del(struct nf_f -+ e = container_of(flow, struct flow_offload_entry, flow); -+ clear_bit(IPS_OFFLOAD_BIT, &e->ct->status); -+ -++ if (!(flow->flags & FLOW_OFFLOAD_TEARDOWN)) -++ flow_offload_fixup_ct_state(e->ct); -++ -+ flow_offload_free(flow); -+ } -+ -diff --git a/target/linux/generic/backport-4.14/372-netfilter-nft_flow_offload-fix-interaction-with-vrf-.patch b/target/linux/generic/backport-4.14/372-netfilter-nft_flow_offload-fix-interaction-with-vrf-.patch -new file mode 100644 -index 0000000000..f0a8b19eec ---- /dev/null -+++ b/target/linux/generic/backport-4.14/372-netfilter-nft_flow_offload-fix-interaction-with-vrf-.patch -@@ -0,0 +1,86 @@ -+From: wenxu -+Date: Thu, 10 Jan 2019 14:51:35 +0800 -+Subject: [PATCH] netfilter: nft_flow_offload: fix interaction with vrf slave -+ device -+ -+In the forward chain, the iif is changed from slave device to master vrf -+device. Thus, flow offload does not find a match on the lower slave -+device. -+ -+This patch uses the cached route, ie. dst->dev, to update the iif and -+oif fields in the flow entry. -+ -+After this patch, the following example works fine: -+ -+ # ip addr add dev eth0 1.1.1.1/24 -+ # ip addr add dev eth1 10.0.0.1/24 -+ # ip link add user1 type vrf table 1 -+ # ip l set user1 up -+ # ip l set dev eth0 master user1 -+ # ip l set dev eth1 master user1 -+ -+ # nft add table firewall -+ # nft add flowtable f fb1 { hook ingress priority 0 \; devices = { eth0, eth1 } \; } -+ # nft add chain f ftb-all {type filter hook forward priority 0 \; policy accept \; } -+ # nft add rule f ftb-all ct zone 1 ip protocol tcp flow offload @fb1 -+ # nft add rule f ftb-all ct zone 1 ip protocol udp flow offload @fb1 -+ -+Signed-off-by: wenxu -+Signed-off-by: Pablo Neira Ayuso -+--- -+ -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -84,7 +84,6 @@ struct flow_offload { -+ struct nf_flow_route { -+ struct { -+ struct dst_entry *dst; -+- int ifindex; -+ } tuple[FLOW_OFFLOAD_DIR_MAX]; -+ }; -+ -+--- a/net/netfilter/nf_flow_table_core.c -++++ b/net/netfilter/nf_flow_table_core.c -+@@ -28,6 +28,7 @@ flow_offload_fill_dir(struct flow_offloa -+ { -+ struct flow_offload_tuple *ft = &flow->tuplehash[dir].tuple; -+ struct nf_conntrack_tuple *ctt = &ct->tuplehash[dir].tuple; -++ struct dst_entry *other_dst = route->tuple[!dir].dst; -+ struct dst_entry *dst = route->tuple[dir].dst; -+ -+ ft->dir = dir; -+@@ -50,8 +51,8 @@ flow_offload_fill_dir(struct flow_offloa -+ ft->src_port = ctt->src.u.tcp.port; -+ ft->dst_port = ctt->dst.u.tcp.port; -+ -+- ft->iifidx = route->tuple[dir].ifindex; -+- ft->oifidx = route->tuple[!dir].ifindex; -++ ft->iifidx = other_dst->dev->ifindex; -++ ft->oifidx = dst->dev->ifindex; -+ ft->dst_cache = dst; -+ } -+ -+--- a/net/netfilter/nft_flow_offload.c -++++ b/net/netfilter/nft_flow_offload.c -+@@ -30,9 +30,11 @@ static int nft_flow_route(const struct n -+ switch (nft_pf(pkt)) { -+ case NFPROTO_IPV4: -+ fl.u.ip4.daddr = ct->tuplehash[dir].tuple.src.u3.ip; -++ fl.u.ip4.flowi4_oif = nft_in(pkt)->ifindex; -+ break; -+ case NFPROTO_IPV6: -+ fl.u.ip6.daddr = ct->tuplehash[dir].tuple.src.u3.in6; -++ fl.u.ip6.flowi6_oif = nft_in(pkt)->ifindex; -+ break; -+ } -+ -+@@ -41,9 +43,7 @@ static int nft_flow_route(const struct n -+ return -ENOENT; -+ -+ route->tuple[dir].dst = this_dst; -+- route->tuple[dir].ifindex = nft_in(pkt)->ifindex; -+ route->tuple[!dir].dst = other_dst; -+- route->tuple[!dir].ifindex = nft_out(pkt)->ifindex; -+ -+ return 0; -+ } -diff --git a/target/linux/generic/backport-4.14/380-v5.3-net-sched-Introduce-act_ctinfo-action.patch b/target/linux/generic/backport-4.14/380-v5.3-net-sched-Introduce-act_ctinfo-action.patch -new file mode 100644 -index 0000000000..96f458f9c9 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/380-v5.3-net-sched-Introduce-act_ctinfo-action.patch -@@ -0,0 +1,640 @@ -+From 85fc2a6db8279c5e43c38ef7e715d14e57287997 Mon Sep 17 00:00:00 2001 -+From: Kevin Darbyshire-Bryant -+Date: Wed, 13 Mar 2019 20:54:49 +0000 -+Subject: [PATCH] net: sched: Backport Introduce act_ctinfo action -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+ctinfo is a new tc filter action module. It is designed to restore -+information contained in firewall conntrack marks to other packet fields -+and is typically used on packet ingress paths. At present it has two -+independent sub-functions or operating modes, DSCP restoration mode & -+skb mark restoration mode. -+ -+The DSCP restore mode: -+ -+This mode copies DSCP values that have been placed in the firewall -+conntrack mark back into the IPv4/v6 diffserv fields of relevant -+packets. -+ -+The DSCP restoration is intended for use and has been found useful for -+restoring ingress classifications based on egress classifications across -+links that bleach or otherwise change DSCP, typically home ISP Internet -+links. Restoring DSCP on ingress on the WAN link allows qdiscs such as -+but by no means limited to CAKE to shape inbound packets according to -+policies that are easier to set & mark on egress. -+ -+Ingress classification is traditionally a challenging task since -+iptables rules haven't yet run and tc filter/eBPF programs are pre-NAT -+lookups, hence are unable to see internal IPv4 addresses as used on the -+typical home masquerading gateway. Thus marking the connection in some -+manner on egress for later restoration of classification on ingress is -+easier to implement. -+ -+Parameters related to DSCP restore mode: -+ -+dscpmask - a 32 bit mask of 6 contiguous bits and indicate bits of the -+conntrack mark field contain the DSCP value to be restored. -+ -+statemask - a 32 bit mask of (usually) 1 bit length, outside the area -+specified by dscpmask. This represents a conditional operation flag -+whereby the DSCP is only restored if the flag is set. This is useful to -+implement a 'one shot' iptables based classification where the -+'complicated' iptables rules are only run once to classify the -+connection on initial (egress) packet and subsequent packets are all -+marked/restored with the same DSCP. A mask of zero disables the -+conditional behaviour ie. the conntrack mark DSCP bits are always -+restored to the ip diffserv field (assuming the conntrack entry is found -+& the skb is an ipv4/ipv6 type) -+ -+e.g. dscpmask 0xfc000000 statemask 0x01000000 -+ -+|----0xFC----conntrack mark----000000---| -+| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0| -+| DSCP | unused | flag |unused | -+|-----------------------0x01---000000---| -+ | | -+ | | -+ ---| Conditional flag -+ v only restore if set -+|-ip diffserv-| -+| 6 bits | -+|-------------| -+ -+The skb mark restore mode (cpmark): -+ -+This mode copies the firewall conntrack mark to the skb's mark field. -+It is completely the functional equivalent of the existing act_connmark -+action with the additional feature of being able to apply a mask to the -+restored value. -+ -+Parameters related to skb mark restore mode: -+ -+mask - a 32 bit mask applied to the firewall conntrack mark to mask out -+bits unwanted for restoration. This can be useful where the conntrack -+mark is being used for different purposes by different applications. If -+not specified and by default the whole mark field is copied (i.e. -+default mask of 0xffffffff) -+ -+e.g. mask 0x00ffffff to mask out the top 8 bits being used by the -+aforementioned DSCP restore mode. -+ -+|----0x00----conntrack mark----ffffff---| -+| Bits 31-24 | | -+| DSCP & flag| some value here | -+|---------------------------------------| -+ | -+ | -+ v -+|------------skb mark-------------------| -+| | | -+| zeroed | | -+|---------------------------------------| -+ -+Overall parameters: -+ -+zone - conntrack zone -+ -+control - action related control (reclassify | pipe | drop | continue | -+ok | goto chain ) -+ -+Signed-off-by: Kevin Darbyshire-Bryant -+Reviewed-by: Toke Høiland-Jørgensen -+Acked-by: Cong Wang -+Signed-off-by: David S. Miller -+ -+Backport -+Signed-off-by: Kevin Darbyshire-Bryant -+--- -+ include/net/tc_act/tc_ctinfo.h | 33 +++ -+ include/uapi/linux/pkt_cls.h | 3 +- -+ include/uapi/linux/tc_act/tc_ctinfo.h | 29 ++ -+ net/sched/Kconfig | 13 + -+ net/sched/Makefile | 1 + -+ net/sched/act_ctinfo.c | 405 ++++++++++++++++++++++++++ -+ 6 files changed, 482 insertions(+), 1 deletion(-) -+ create mode 100644 include/net/tc_act/tc_ctinfo.h -+ create mode 100644 include/uapi/linux/tc_act/tc_ctinfo.h -+ create mode 100644 net/sched/act_ctinfo.c -+ -+--- /dev/null -++++ b/include/net/tc_act/tc_ctinfo.h -+@@ -0,0 +1,33 @@ -++/* SPDX-License-Identifier: GPL-2.0 */ -++#ifndef __NET_TC_CTINFO_H -++#define __NET_TC_CTINFO_H -++ -++#include -++ -++struct tcf_ctinfo_params { -++ struct rcu_head rcu; -++ struct net *net; -++ u32 dscpmask; -++ u32 dscpstatemask; -++ u32 cpmarkmask; -++ u16 zone; -++ u8 mode; -++ u8 dscpmaskshift; -++}; -++ -++struct tcf_ctinfo { -++ struct tc_action common; -++ struct tcf_ctinfo_params __rcu *params; -++ u64 stats_dscp_set; -++ u64 stats_dscp_error; -++ u64 stats_cpmark_set; -++}; -++ -++enum { -++ CTINFO_MODE_DSCP = BIT(0), -++ CTINFO_MODE_CPMARK = BIT(1) -++}; -++ -++#define to_ctinfo(a) ((struct tcf_ctinfo *)a) -++ -++#endif /* __NET_TC_CTINFO_H */ -+--- a/include/uapi/linux/pkt_cls.h -++++ b/include/uapi/linux/pkt_cls.h -+@@ -66,7 +66,8 @@ enum { -+ TCA_ID_UNSPEC=0, -+ TCA_ID_POLICE=1, -+ /* other actions go here */ -+- __TCA_ID_MAX=255 -++ TCA_ID_CTINFO=27, -++ __TCA_ID_MAX = 255 -+ }; -+ -+ #define TCA_ID_MAX __TCA_ID_MAX -+--- /dev/null -++++ b/include/uapi/linux/tc_act/tc_ctinfo.h -+@@ -0,0 +1,29 @@ -++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -++#ifndef __UAPI_TC_CTINFO_H -++#define __UAPI_TC_CTINFO_H -++ -++#include -++#include -++ -++struct tc_ctinfo { -++ tc_gen; -++}; -++ -++enum { -++ TCA_CTINFO_UNSPEC, -++ TCA_CTINFO_PAD, -++ TCA_CTINFO_TM, -++ TCA_CTINFO_ACT, -++ TCA_CTINFO_ZONE, -++ TCA_CTINFO_PARMS_DSCP_MASK, -++ TCA_CTINFO_PARMS_DSCP_STATEMASK, -++ TCA_CTINFO_PARMS_CPMARK_MASK, -++ TCA_CTINFO_STATS_DSCP_SET, -++ TCA_CTINFO_STATS_DSCP_ERROR, -++ TCA_CTINFO_STATS_CPMARK_SET, -++ __TCA_CTINFO_MAX -++}; -++ -++#define TCA_CTINFO_MAX (__TCA_CTINFO_MAX - 1) -++ -++#endif -+--- a/net/sched/Kconfig -++++ b/net/sched/Kconfig -+@@ -808,6 +808,19 @@ config NET_ACT_CONNMARK -+ To compile this code as a module, choose M here: the -+ module will be called act_connmark. -+ -++config NET_ACT_CTINFO -++ tristate "Netfilter Connmark to DSCP Retriever" -++ depends on NET_CLS_ACT && NETFILTER && IP_NF_IPTABLES -++ depends on NF_CONNTRACK && NF_CONNTRACK_MARK -++ help -++ Say Y here to allow transfer of a connmark stored DSCP into -++ ipv4/v6 diffserv -++ -++ If unsure, say N. -++ -++ To compile this code as a module, choose M here: the -++ module will be called act_ctinfo. -++ -+ config NET_ACT_SKBMOD -+ tristate "skb data modification action" -+ depends on NET_CLS_ACT -+--- a/net/sched/Makefile -++++ b/net/sched/Makefile -+@@ -21,6 +21,7 @@ obj-$(CONFIG_NET_ACT_CSUM) += act_csum.o -+ obj-$(CONFIG_NET_ACT_VLAN) += act_vlan.o -+ obj-$(CONFIG_NET_ACT_BPF) += act_bpf.o -+ obj-$(CONFIG_NET_ACT_CONNMARK) += act_connmark.o -++obj-$(CONFIG_NET_ACT_CTINFO) += act_ctinfo.o -+ obj-$(CONFIG_NET_ACT_SKBMOD) += act_skbmod.o -+ obj-$(CONFIG_NET_ACT_IFE) += act_ife.o -+ obj-$(CONFIG_NET_IFE_SKBMARK) += act_meta_mark.o -+--- /dev/null -++++ b/net/sched/act_ctinfo.c -+@@ -0,0 +1,405 @@ -++// SPDX-License-Identifier: GPL-2.0+ -++/* net/sched/act_ctinfo.c netfilter ctinfo connmark actions -++ * -++ * Copyright (c) 2019 Kevin Darbyshire-Bryant -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include -++#include -++#include -++#include -++ -++static struct tc_action_ops act_ctinfo_ops; -++static unsigned int ctinfo_net_id; -++ -++static void tcf_ctinfo_dscp_set(struct nf_conn *ct, struct tcf_ctinfo *ca, -++ struct tcf_ctinfo_params *cp, -++ struct sk_buff *skb, int wlen, int proto) -++{ -++ u8 dscp,newdscp; -++ -++ newdscp = (((ct->mark & cp->dscpmask) >> cp->dscpmaskshift) << 2) & -++ ~INET_ECN_MASK; -++ -++ /* mark contains DSCP so restore DSCP bits from ct->mark into diffserv */ -++ /* using overlimits stats to count how many DSCP updates */ -++ switch (proto) { -++ case NFPROTO_IPV4: -++ dscp = ipv4_get_dsfield(ip_hdr(skb)) & ~INET_ECN_MASK; -++ if (dscp != newdscp) { -++ if (likely(!skb_try_make_writable(skb, wlen))) { -++ ipv4_change_dsfield(ip_hdr(skb), -++ INET_ECN_MASK, -++ newdscp); -++ ca->stats_dscp_set++; -++ } else { -++ ca->stats_dscp_error++; -++ } -++ } -++ break; -++ case NFPROTO_IPV6: -++ dscp = ipv6_get_dsfield(ipv6_hdr(skb)) & ~INET_ECN_MASK; -++ if (dscp != newdscp) { -++ if (likely(!skb_try_make_writable(skb, wlen))) { -++ ipv6_change_dsfield(ipv6_hdr(skb), -++ INET_ECN_MASK, -++ newdscp); -++ ca->stats_dscp_set++; -++ } else { -++ ca->stats_dscp_error++; -++ } -++ } -++ break; -++ default: -++ break; -++ } -++} -++ -++static void tcf_ctinfo_cpmark_set(struct nf_conn *ct, struct tcf_ctinfo *ca, -++ struct tcf_ctinfo_params *cp, -++ struct sk_buff *skb) -++{ -++ ca->stats_cpmark_set++; -++ skb->mark = ct->mark & cp->cpmarkmask; -++} -++ -++static int tcf_ctinfo_act(struct sk_buff *skb, const struct tc_action *a, -++ struct tcf_result *res) -++{ -++ const struct nf_conntrack_tuple_hash *thash = NULL; -++ struct tcf_ctinfo *ca = to_ctinfo(a); -++ struct nf_conntrack_tuple tuple; -++ struct nf_conntrack_zone zone; -++ enum ip_conntrack_info ctinfo; -++ struct tcf_ctinfo_params *cp; -++ struct nf_conn *ct; -++ int proto, wlen; -++ int action; -++ -++ cp = rcu_dereference_bh(ca->params); -++ -++ tcf_lastuse_update(&ca->tcf_tm); -++ bstats_update(&ca->tcf_bstats, skb); -++ action = READ_ONCE(ca->tcf_action); -++ -++ wlen = skb_network_offset(skb); -++ if (tc_skb_protocol(skb) == htons(ETH_P_IP)) { -++ wlen += sizeof(struct iphdr); -++ if (!pskb_may_pull(skb, wlen)) -++ goto out; -++ -++ proto = NFPROTO_IPV4; -++ } else if (tc_skb_protocol(skb) == htons(ETH_P_IPV6)) { -++ wlen += sizeof(struct ipv6hdr); -++ if (!pskb_may_pull(skb, wlen)) -++ goto out; -++ -++ proto = NFPROTO_IPV6; -++ } else { -++ goto out; -++ } -++ -++ ct = nf_ct_get(skb, &ctinfo); -++ if (!ct) { /* look harder, usually ingress */ -++ if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), -++ proto, cp->net, &tuple)) -++ goto out; -++ zone.id = cp->zone; -++ zone.dir = NF_CT_DEFAULT_ZONE_DIR; -++ -++ thash = nf_conntrack_find_get(cp->net, &zone, &tuple); -++ if (!thash) -++ goto out; -++ -++ ct = nf_ct_tuplehash_to_ctrack(thash); -++ } -++ -++ if (cp->mode & CTINFO_MODE_DSCP) -++ if (!cp->dscpstatemask || (ct->mark & cp->dscpstatemask)) -++ tcf_ctinfo_dscp_set(ct, ca, cp, skb, wlen, proto); -++ -++ if (cp->mode & CTINFO_MODE_CPMARK) -++ tcf_ctinfo_cpmark_set(ct, ca, cp, skb); -++ -++ if (thash) -++ nf_ct_put(ct); -++out: -++ return action; -++} -++ -++static const struct nla_policy ctinfo_policy[TCA_CTINFO_MAX + 1] = { -++ [TCA_CTINFO_ACT] = { .len = sizeof(struct -++ tc_ctinfo) }, -++ [TCA_CTINFO_ZONE] = { .type = NLA_U16 }, -++ [TCA_CTINFO_PARMS_DSCP_MASK] = { .type = NLA_U32 }, -++ [TCA_CTINFO_PARMS_DSCP_STATEMASK] = { .type = NLA_U32 }, -++ [TCA_CTINFO_PARMS_CPMARK_MASK] = { .type = NLA_U32 }, -++}; -++ -++static int tcf_ctinfo_init(struct net *net, struct nlattr *nla, -++ struct nlattr *est, struct tc_action **a, -++ int ovr, int bind) -++{ -++ struct tc_action_net *tn = net_generic(net, ctinfo_net_id); -++ struct nlattr *tb[TCA_CTINFO_MAX + 1]; -++ struct tcf_ctinfo_params *cp_new; -++/* struct tcf_chain *goto_ch = NULL; */ -++ u32 dscpmask = 0, dscpstatemask; -++ struct tc_ctinfo *actparm; -++ struct tcf_ctinfo *ci; -++ u8 dscpmaskshift; -++ int ret = 0, err; -++ -++ if (!nla) -++ return -EINVAL; -++ -++ err = nla_parse_nested(tb, TCA_CTINFO_MAX, nla, ctinfo_policy, NULL); -++ if (err < 0) -++ return err; -++ -++ if (!tb[TCA_CTINFO_ACT]) -++ return -EINVAL; -++ actparm = nla_data(tb[TCA_CTINFO_ACT]); -++ -++ /* do some basic validation here before dynamically allocating things */ -++ /* that we would otherwise have to clean up. */ -++ if (tb[TCA_CTINFO_PARMS_DSCP_MASK]) { -++ dscpmask = nla_get_u32(tb[TCA_CTINFO_PARMS_DSCP_MASK]); -++ /* need contiguous 6 bit mask */ -++ dscpmaskshift = dscpmask ? __ffs(dscpmask) : 0; -++ if ((~0 & (dscpmask >> dscpmaskshift)) != 0x3f) -++ return -EINVAL; -++ dscpstatemask = tb[TCA_CTINFO_PARMS_DSCP_STATEMASK] ? -++ nla_get_u32(tb[TCA_CTINFO_PARMS_DSCP_STATEMASK]) : 0; -++ /* mask & statemask must not overlap */ -++ if (dscpmask & dscpstatemask) -++ return -EINVAL; -++ } -++ /* done the validation:now to the actual action allocation */ -++ err = tcf_idr_check(tn, actparm->index, a, bind); -++ if (!err) { -++ ret = tcf_idr_create(tn, actparm->index, est, a, -++ &act_ctinfo_ops, bind, false); -++ if (ret) { -++ /* tcf_idr_cleanup(tn, actparm->index); */ -++ return ret; -++ } -++ ret = ACT_P_CREATED; -++ } else if (err > 0) { -++ if (bind) /* don't override defaults */ -++ return 0; -++ if (!ovr) { -++ tcf_idr_release(*a, bind); -++ return -EEXIST; -++ } -++ } else { -++ return err; -++ } -++ -++/* err = tcf_action_check_ctrlact(actparm->action, tp, &goto_ch, extack); -++ if (err < 0) -++ goto release_idr; -++ */ -++ -++ ci = to_ctinfo(*a); -++ -++ cp_new = kzalloc(sizeof(*cp_new), GFP_KERNEL); -++ if (unlikely(!cp_new)) { -++ err = -ENOMEM; -++ goto put_chain; -++ } -++ -++ cp_new->net = net; -++ cp_new->zone = tb[TCA_CTINFO_ZONE] ? -++ nla_get_u16(tb[TCA_CTINFO_ZONE]) : 0; -++ if (dscpmask) { -++ cp_new->dscpmask = dscpmask; -++ cp_new->dscpmaskshift = dscpmaskshift; -++ cp_new->dscpstatemask = dscpstatemask; -++ cp_new->mode |= CTINFO_MODE_DSCP; -++ } -++ -++ if (tb[TCA_CTINFO_PARMS_CPMARK_MASK]) { -++ cp_new->cpmarkmask = nla_get_u32(tb[TCA_CTINFO_PARMS_CPMARK_MASK]); -++ cp_new->mode |= CTINFO_MODE_CPMARK; -++ } -++ -++ spin_lock_bh(&ci->tcf_lock); -++/* goto_ch = tcf_action_set_ctrlact(*a, actparm->action, goto_ch); */ -++ ci->tcf_action = actparm->action; -++ rcu_swap_protected(ci->params, cp_new, -++ lockdep_is_held(&ci->tcf_lock)); -++ spin_unlock_bh(&ci->tcf_lock); -++ -++/* if (goto_ch) -++ tcf_chain_put_by_act(goto_ch); */ -++ if (cp_new) -++ kfree_rcu(cp_new, rcu); -++ -++ if (ret == ACT_P_CREATED) -++ tcf_idr_insert(tn, *a); -++ -++ return ret; -++ -++put_chain: -++/* if (goto_ch) -++ tcf_chain_put_by_act(goto_ch); */ -++/*release_idr:*/ -++ tcf_idr_release(*a, bind); -++ return err; -++} -++ -++static int tcf_ctinfo_dump(struct sk_buff *skb, struct tc_action *a, -++ int bind, int ref) -++{ -++ struct tcf_ctinfo *ci = to_ctinfo(a); -++ struct tc_ctinfo opt = { -++ .index = ci->tcf_index, -++ .refcnt = ci->tcf_refcnt - ref, -++ .bindcnt = ci->tcf_bindcnt - bind, -++ }; -++ unsigned char *b = skb_tail_pointer(skb); -++ struct tcf_ctinfo_params *cp; -++ struct tcf_t t; -++ -++ spin_lock_bh(&ci->tcf_lock); -++ cp = rcu_dereference_protected(ci->params, -++ lockdep_is_held(&ci->tcf_lock)); -++ -++ tcf_tm_dump(&t, &ci->tcf_tm); -++ if (nla_put_64bit(skb, TCA_CTINFO_TM, sizeof(t), &t, TCA_CTINFO_PAD)) -++ goto nla_put_failure; -++ -++ opt.action = ci->tcf_action; -++ if (nla_put(skb, TCA_CTINFO_ACT, sizeof(opt), &opt)) -++ goto nla_put_failure; -++ -++ if (nla_put_u16(skb, TCA_CTINFO_ZONE, cp->zone)) -++ goto nla_put_failure; -++ -++ if (cp->mode & CTINFO_MODE_DSCP) { -++ if (nla_put_u32(skb, TCA_CTINFO_PARMS_DSCP_MASK, -++ cp->dscpmask)) -++ goto nla_put_failure; -++ if (nla_put_u32(skb, TCA_CTINFO_PARMS_DSCP_STATEMASK, -++ cp->dscpstatemask)) -++ goto nla_put_failure; -++ } -++ -++ if (cp->mode & CTINFO_MODE_CPMARK) { -++ if (nla_put_u32(skb, TCA_CTINFO_PARMS_CPMARK_MASK, -++ cp->cpmarkmask)) -++ goto nla_put_failure; -++ } -++ -++ if (nla_put_u64_64bit(skb, TCA_CTINFO_STATS_DSCP_SET, -++ ci->stats_dscp_set, TCA_CTINFO_PAD)) -++ goto nla_put_failure; -++ -++ if (nla_put_u64_64bit(skb, TCA_CTINFO_STATS_DSCP_ERROR, -++ ci->stats_dscp_error, TCA_CTINFO_PAD)) -++ goto nla_put_failure; -++ -++ if (nla_put_u64_64bit(skb, TCA_CTINFO_STATS_CPMARK_SET, -++ ci->stats_cpmark_set, TCA_CTINFO_PAD)) -++ goto nla_put_failure; -++ -++ spin_unlock_bh(&ci->tcf_lock); -++ return skb->len; -++ -++nla_put_failure: -++ spin_unlock_bh(&ci->tcf_lock); -++ nlmsg_trim(skb, b); -++ return -1; -++} -++ -++static int tcf_ctinfo_walker(struct net *net, struct sk_buff *skb, -++ struct netlink_callback *cb, int type, -++ const struct tc_action_ops *ops) -++{ -++ struct tc_action_net *tn = net_generic(net, ctinfo_net_id); -++ -++ return tcf_generic_walker(tn, skb, cb, type, ops); -++} -++ -++static int tcf_ctinfo_search(struct net *net, struct tc_action **a, u32 index) -++{ -++ struct tc_action_net *tn = net_generic(net, ctinfo_net_id); -++ -++ return tcf_idr_search(tn, a, index); -++} -++ -++static void tcf_ctinfo_cleanup(struct tc_action *a, int bind) -++{ -++ struct tcf_ctinfo *ci = to_ctinfo(a); -++ struct tcf_ctinfo_params *cp; -++ -++ cp = rcu_dereference_protected(ci->params, 1); -++ if (cp) -++ kfree_rcu(cp, rcu); -++} -++ -++static struct tc_action_ops act_ctinfo_ops = { -++ .kind = "ctinfo", -++ .type = TCA_ID_CTINFO, -++ .owner = THIS_MODULE, -++ .act = tcf_ctinfo_act, -++ .dump = tcf_ctinfo_dump, -++ .init = tcf_ctinfo_init, -++ .cleanup= tcf_ctinfo_cleanup, -++ .walk = tcf_ctinfo_walker, -++ .lookup = tcf_ctinfo_search, -++ .size = sizeof(struct tcf_ctinfo), -++}; -++ -++static __net_init int ctinfo_init_net(struct net *net) -++{ -++ struct tc_action_net *tn = net_generic(net, ctinfo_net_id); -++ -++ return tc_action_net_init(net, tn, &act_ctinfo_ops); -++} -++ -++static void __net_exit ctinfo_exit_net(struct net *net) -++{ -++ struct tc_action_net *tn = net_generic(net, ctinfo_net_id); -++ -++ tc_action_net_exit(tn); -++} -++ -++static struct pernet_operations ctinfo_net_ops = { -++ .init = ctinfo_init_net, -++ .exit = ctinfo_exit_net, -++ .id = &ctinfo_net_id, -++ .size = sizeof(struct tc_action_net), -++}; -++ -++static int __init ctinfo_init_module(void) -++{ -++ return tcf_register_action(&act_ctinfo_ops, &ctinfo_net_ops); -++} -++ -++static void __exit ctinfo_cleanup_module(void) -++{ -++ tcf_unregister_action(&act_ctinfo_ops, &ctinfo_net_ops); -++} -++ -++module_init(ctinfo_init_module); -++module_exit(ctinfo_cleanup_module); -++MODULE_AUTHOR("Kevin Darbyshire-Bryant "); -++MODULE_DESCRIPTION("Conntrack mark to DSCP restoring"); -++MODULE_LICENSE("GPL"); -diff --git a/target/linux/generic/backport-4.14/400-v4.16-leds-trigger-Introduce-a-NETDEV-trigger.patch b/target/linux/generic/backport-4.14/400-v4.16-leds-trigger-Introduce-a-NETDEV-trigger.patch -new file mode 100644 -index 0000000000..b7d680a11b ---- /dev/null -+++ b/target/linux/generic/backport-4.14/400-v4.16-leds-trigger-Introduce-a-NETDEV-trigger.patch -@@ -0,0 +1,588 @@ -+From 06f502f57d0d7728f9fa0f157ec5e4111ddb98f6 Mon Sep 17 00:00:00 2001 -+From: Ben Whitten -+Date: Sun, 10 Dec 2017 21:17:55 +0000 -+Subject: [PATCH] leds: trigger: Introduce a NETDEV trigger -+ -+This commit introduces a NETDEV trigger for named device -+activity. Available triggers are link, rx, and tx. -+ -+Signed-off-by: Ben Whitten -+Acked-by: Pavel Machek -+Signed-off-by: Jacek Anaszewski -+--- -+ .../ABI/testing/sysfs-class-led-trigger-netdev | 45 ++ -+ drivers/leds/trigger/Kconfig | 7 + -+ drivers/leds/trigger/Makefile | 1 + -+ drivers/leds/trigger/ledtrig-netdev.c | 496 +++++++++++++++++++++ -+ 4 files changed, 549 insertions(+) -+ create mode 100644 Documentation/ABI/testing/sysfs-class-led-trigger-netdev -+ create mode 100644 drivers/leds/trigger/ledtrig-netdev.c -+ -+--- /dev/null -++++ b/Documentation/ABI/testing/sysfs-class-led-trigger-netdev -+@@ -0,0 +1,45 @@ -++What: /sys/class/leds//device_name -++Date: Dec 2017 -++KernelVersion: 4.16 -++Contact: linux-leds@vger.kernel.org -++Description: -++ Specifies the network device name to monitor. -++ -++What: /sys/class/leds//interval -++Date: Dec 2017 -++KernelVersion: 4.16 -++Contact: linux-leds@vger.kernel.org -++Description: -++ Specifies the duration of the LED blink in milliseconds. -++ Defaults to 50 ms. -++ -++What: /sys/class/leds//link -++Date: Dec 2017 -++KernelVersion: 4.16 -++Contact: linux-leds@vger.kernel.org -++Description: -++ Signal the link state of the named network device. -++ If set to 0 (default), the LED's normal state is off. -++ If set to 1, the LED's normal state reflects the link state -++ of the named network device. -++ Setting this value also immediately changes the LED state. -++ -++What: /sys/class/leds//tx -++Date: Dec 2017 -++KernelVersion: 4.16 -++Contact: linux-leds@vger.kernel.org -++Description: -++ Signal transmission of data on the named network device. -++ If set to 0 (default), the LED will not blink on transmission. -++ If set to 1, the LED will blink for the milliseconds specified -++ in interval to signal transmission. -++ -++What: /sys/class/leds//rx -++Date: Dec 2017 -++KernelVersion: 4.16 -++Contact: linux-leds@vger.kernel.org -++Description: -++ Signal reception of data on the named network device. -++ If set to 0 (default), the LED will not blink on reception. -++ If set to 1, the LED will blink for the milliseconds specified -++ in interval to signal reception. -+--- a/drivers/leds/trigger/Kconfig -++++ b/drivers/leds/trigger/Kconfig -+@@ -126,4 +126,11 @@ config LEDS_TRIGGER_PANIC -+ a different trigger. -+ If unsure, say Y. -+ -++config LEDS_TRIGGER_NETDEV -++ tristate "LED Netdev Trigger" -++ depends on NET && LEDS_TRIGGERS -++ help -++ This allows LEDs to be controlled by network device activity. -++ If unsure, say Y. -++ -+ endif # LEDS_TRIGGERS -+--- a/drivers/leds/trigger/Makefile -++++ b/drivers/leds/trigger/Makefile -+@@ -11,3 +11,4 @@ obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += -+ obj-$(CONFIG_LEDS_TRIGGER_TRANSIENT) += ledtrig-transient.o -+ obj-$(CONFIG_LEDS_TRIGGER_CAMERA) += ledtrig-camera.o -+ obj-$(CONFIG_LEDS_TRIGGER_PANIC) += ledtrig-panic.o -++obj-$(CONFIG_LEDS_TRIGGER_NETDEV) += ledtrig-netdev.o -+--- /dev/null -++++ b/drivers/leds/trigger/ledtrig-netdev.c -+@@ -0,0 +1,496 @@ -++// SPDX-License-Identifier: GPL-2.0 -++// Copyright 2017 Ben Whitten -++// Copyright 2007 Oliver Jowett -++// -++// LED Kernel Netdev Trigger -++// -++// Toggles the LED to reflect the link and traffic state of a named net device -++// -++// Derived from ledtrig-timer.c which is: -++// Copyright 2005-2006 Openedhand Ltd. -++// Author: Richard Purdie -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include "../leds.h" -++ -++/* -++ * Configurable sysfs attributes: -++ * -++ * device_name - network device name to monitor -++ * interval - duration of LED blink, in milliseconds -++ * link - LED's normal state reflects whether the link is up -++ * (has carrier) or not -++ * tx - LED blinks on transmitted data -++ * rx - LED blinks on receive data -++ * -++ */ -++ -++struct led_netdev_data { -++ spinlock_t lock; -++ -++ struct delayed_work work; -++ struct notifier_block notifier; -++ -++ struct led_classdev *led_cdev; -++ struct net_device *net_dev; -++ -++ char device_name[IFNAMSIZ]; -++ atomic_t interval; -++ unsigned int last_activity; -++ -++ unsigned long mode; -++#define NETDEV_LED_LINK 0 -++#define NETDEV_LED_TX 1 -++#define NETDEV_LED_RX 2 -++#define NETDEV_LED_MODE_LINKUP 3 -++}; -++ -++enum netdev_led_attr { -++ NETDEV_ATTR_LINK, -++ NETDEV_ATTR_TX, -++ NETDEV_ATTR_RX -++}; -++ -++static void set_baseline_state(struct led_netdev_data *trigger_data) -++{ -++ int current_brightness; -++ struct led_classdev *led_cdev = trigger_data->led_cdev; -++ -++ current_brightness = led_cdev->brightness; -++ if (current_brightness) -++ led_cdev->blink_brightness = current_brightness; -++ if (!led_cdev->blink_brightness) -++ led_cdev->blink_brightness = led_cdev->max_brightness; -++ -++ if (!test_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode)) -++ led_set_brightness(led_cdev, LED_OFF); -++ else { -++ if (test_bit(NETDEV_LED_LINK, &trigger_data->mode)) -++ led_set_brightness(led_cdev, -++ led_cdev->blink_brightness); -++ else -++ led_set_brightness(led_cdev, LED_OFF); -++ -++ /* If we are looking for RX/TX start periodically -++ * checking stats -++ */ -++ if (test_bit(NETDEV_LED_TX, &trigger_data->mode) || -++ test_bit(NETDEV_LED_RX, &trigger_data->mode)) -++ schedule_delayed_work(&trigger_data->work, 0); -++ } -++} -++ -++static ssize_t device_name_show(struct device *dev, -++ struct device_attribute *attr, char *buf) -++{ -++ struct led_classdev *led_cdev = dev_get_drvdata(dev); -++ struct led_netdev_data *trigger_data = led_cdev->trigger_data; -++ ssize_t len; -++ -++ spin_lock_bh(&trigger_data->lock); -++ len = sprintf(buf, "%s\n", trigger_data->device_name); -++ spin_unlock_bh(&trigger_data->lock); -++ -++ return len; -++} -++ -++static ssize_t device_name_store(struct device *dev, -++ struct device_attribute *attr, const char *buf, -++ size_t size) -++{ -++ struct led_classdev *led_cdev = dev_get_drvdata(dev); -++ struct led_netdev_data *trigger_data = led_cdev->trigger_data; -++ -++ if (size >= IFNAMSIZ) -++ return -EINVAL; -++ -++ cancel_delayed_work_sync(&trigger_data->work); -++ -++ spin_lock_bh(&trigger_data->lock); -++ -++ if (trigger_data->net_dev) { -++ dev_put(trigger_data->net_dev); -++ trigger_data->net_dev = NULL; -++ } -++ -++ strncpy(trigger_data->device_name, buf, size); -++ if (size > 0 && trigger_data->device_name[size - 1] == '\n') -++ trigger_data->device_name[size - 1] = 0; -++ -++ if (trigger_data->device_name[0] != 0) -++ trigger_data->net_dev = -++ dev_get_by_name(&init_net, trigger_data->device_name); -++ -++ clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); -++ if (trigger_data->net_dev != NULL) -++ if (netif_carrier_ok(trigger_data->net_dev)) -++ set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); -++ -++ trigger_data->last_activity = 0; -++ -++ set_baseline_state(trigger_data); -++ spin_unlock_bh(&trigger_data->lock); -++ -++ return size; -++} -++ -++static DEVICE_ATTR_RW(device_name); -++ -++static ssize_t netdev_led_attr_show(struct device *dev, char *buf, -++ enum netdev_led_attr attr) -++{ -++ struct led_classdev *led_cdev = dev_get_drvdata(dev); -++ struct led_netdev_data *trigger_data = led_cdev->trigger_data; -++ int bit; -++ -++ switch (attr) { -++ case NETDEV_ATTR_LINK: -++ bit = NETDEV_LED_LINK; -++ break; -++ case NETDEV_ATTR_TX: -++ bit = NETDEV_LED_TX; -++ break; -++ case NETDEV_ATTR_RX: -++ bit = NETDEV_LED_RX; -++ break; -++ default: -++ return -EINVAL; -++ } -++ -++ return sprintf(buf, "%u\n", test_bit(bit, &trigger_data->mode)); -++} -++ -++static ssize_t netdev_led_attr_store(struct device *dev, const char *buf, -++ size_t size, enum netdev_led_attr attr) -++{ -++ struct led_classdev *led_cdev = dev_get_drvdata(dev); -++ struct led_netdev_data *trigger_data = led_cdev->trigger_data; -++ unsigned long state; -++ int ret; -++ int bit; -++ -++ ret = kstrtoul(buf, 0, &state); -++ if (ret) -++ return ret; -++ -++ switch (attr) { -++ case NETDEV_ATTR_LINK: -++ bit = NETDEV_LED_LINK; -++ break; -++ case NETDEV_ATTR_TX: -++ bit = NETDEV_LED_TX; -++ break; -++ case NETDEV_ATTR_RX: -++ bit = NETDEV_LED_RX; -++ break; -++ default: -++ return -EINVAL; -++ } -++ -++ cancel_delayed_work_sync(&trigger_data->work); -++ -++ if (state) -++ set_bit(bit, &trigger_data->mode); -++ else -++ clear_bit(bit, &trigger_data->mode); -++ -++ set_baseline_state(trigger_data); -++ -++ return size; -++} -++ -++static ssize_t link_show(struct device *dev, -++ struct device_attribute *attr, char *buf) -++{ -++ return netdev_led_attr_show(dev, buf, NETDEV_ATTR_LINK); -++} -++ -++static ssize_t link_store(struct device *dev, -++ struct device_attribute *attr, const char *buf, size_t size) -++{ -++ return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_LINK); -++} -++ -++static DEVICE_ATTR_RW(link); -++ -++static ssize_t tx_show(struct device *dev, -++ struct device_attribute *attr, char *buf) -++{ -++ return netdev_led_attr_show(dev, buf, NETDEV_ATTR_TX); -++} -++ -++static ssize_t tx_store(struct device *dev, -++ struct device_attribute *attr, const char *buf, size_t size) -++{ -++ return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_TX); -++} -++ -++static DEVICE_ATTR_RW(tx); -++ -++static ssize_t rx_show(struct device *dev, -++ struct device_attribute *attr, char *buf) -++{ -++ return netdev_led_attr_show(dev, buf, NETDEV_ATTR_RX); -++} -++ -++static ssize_t rx_store(struct device *dev, -++ struct device_attribute *attr, const char *buf, size_t size) -++{ -++ return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_RX); -++} -++ -++static DEVICE_ATTR_RW(rx); -++ -++static ssize_t interval_show(struct device *dev, -++ struct device_attribute *attr, char *buf) -++{ -++ struct led_classdev *led_cdev = dev_get_drvdata(dev); -++ struct led_netdev_data *trigger_data = led_cdev->trigger_data; -++ -++ return sprintf(buf, "%u\n", -++ jiffies_to_msecs(atomic_read(&trigger_data->interval))); -++} -++ -++static ssize_t interval_store(struct device *dev, -++ struct device_attribute *attr, const char *buf, -++ size_t size) -++{ -++ struct led_classdev *led_cdev = dev_get_drvdata(dev); -++ struct led_netdev_data *trigger_data = led_cdev->trigger_data; -++ unsigned long value; -++ int ret; -++ -++ ret = kstrtoul(buf, 0, &value); -++ if (ret) -++ return ret; -++ -++ /* impose some basic bounds on the timer interval */ -++ if (value >= 5 && value <= 10000) { -++ cancel_delayed_work_sync(&trigger_data->work); -++ -++ atomic_set(&trigger_data->interval, msecs_to_jiffies(value)); -++ set_baseline_state(trigger_data); /* resets timer */ -++ } -++ -++ return size; -++} -++ -++static DEVICE_ATTR_RW(interval); -++ -++static int netdev_trig_notify(struct notifier_block *nb, -++ unsigned long evt, void *dv) -++{ -++ struct net_device *dev = -++ netdev_notifier_info_to_dev((struct netdev_notifier_info *)dv); -++ struct led_netdev_data *trigger_data = container_of(nb, -++ struct -++ led_netdev_data, -++ notifier); -++ -++ if (evt != NETDEV_UP && evt != NETDEV_DOWN && evt != NETDEV_CHANGE -++ && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER -++ && evt != NETDEV_CHANGENAME) -++ return NOTIFY_DONE; -++ -++ if (strcmp(dev->name, trigger_data->device_name)) -++ return NOTIFY_DONE; -++ -++ cancel_delayed_work_sync(&trigger_data->work); -++ -++ spin_lock_bh(&trigger_data->lock); -++ -++ clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); -++ switch (evt) { -++ case NETDEV_REGISTER: -++ if (trigger_data->net_dev) -++ dev_put(trigger_data->net_dev); -++ dev_hold(dev); -++ trigger_data->net_dev = dev; -++ break; -++ case NETDEV_CHANGENAME: -++ case NETDEV_UNREGISTER: -++ if (trigger_data->net_dev) { -++ dev_put(trigger_data->net_dev); -++ trigger_data->net_dev = NULL; -++ } -++ break; -++ case NETDEV_UP: -++ case NETDEV_CHANGE: -++ if (netif_carrier_ok(dev)) -++ set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); -++ break; -++ } -++ -++ set_baseline_state(trigger_data); -++ -++ spin_unlock_bh(&trigger_data->lock); -++ -++ return NOTIFY_DONE; -++} -++ -++/* here's the real work! */ -++static void netdev_trig_work(struct work_struct *work) -++{ -++ struct led_netdev_data *trigger_data = container_of(work, -++ struct -++ led_netdev_data, -++ work.work); -++ struct rtnl_link_stats64 *dev_stats; -++ unsigned int new_activity; -++ struct rtnl_link_stats64 temp; -++ unsigned long interval; -++ int invert; -++ -++ /* If we dont have a device, insure we are off */ -++ if (!trigger_data->net_dev) { -++ led_set_brightness(trigger_data->led_cdev, LED_OFF); -++ return; -++ } -++ -++ /* If we are not looking for RX/TX then return */ -++ if (!test_bit(NETDEV_LED_TX, &trigger_data->mode) && -++ !test_bit(NETDEV_LED_RX, &trigger_data->mode)) -++ return; -++ -++ dev_stats = dev_get_stats(trigger_data->net_dev, &temp); -++ new_activity = -++ (test_bit(NETDEV_LED_TX, &trigger_data->mode) ? -++ dev_stats->tx_packets : 0) + -++ (test_bit(NETDEV_LED_RX, &trigger_data->mode) ? -++ dev_stats->rx_packets : 0); -++ -++ if (trigger_data->last_activity != new_activity) { -++ led_stop_software_blink(trigger_data->led_cdev); -++ -++ invert = test_bit(NETDEV_LED_LINK, &trigger_data->mode); -++ interval = jiffies_to_msecs( -++ atomic_read(&trigger_data->interval)); -++ /* base state is ON (link present) */ -++ led_blink_set_oneshot(trigger_data->led_cdev, -++ &interval, -++ &interval, -++ invert); -++ trigger_data->last_activity = new_activity; -++ } -++ -++ schedule_delayed_work(&trigger_data->work, -++ (atomic_read(&trigger_data->interval)*2)); -++} -++ -++static void netdev_trig_activate(struct led_classdev *led_cdev) -++{ -++ struct led_netdev_data *trigger_data; -++ int rc; -++ -++ trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL); -++ if (!trigger_data) -++ return; -++ -++ spin_lock_init(&trigger_data->lock); -++ -++ trigger_data->notifier.notifier_call = netdev_trig_notify; -++ trigger_data->notifier.priority = 10; -++ -++ INIT_DELAYED_WORK(&trigger_data->work, netdev_trig_work); -++ -++ trigger_data->led_cdev = led_cdev; -++ trigger_data->net_dev = NULL; -++ trigger_data->device_name[0] = 0; -++ -++ trigger_data->mode = 0; -++ atomic_set(&trigger_data->interval, msecs_to_jiffies(50)); -++ trigger_data->last_activity = 0; -++ -++ led_cdev->trigger_data = trigger_data; -++ -++ rc = device_create_file(led_cdev->dev, &dev_attr_device_name); -++ if (rc) -++ goto err_out; -++ rc = device_create_file(led_cdev->dev, &dev_attr_link); -++ if (rc) -++ goto err_out_device_name; -++ rc = device_create_file(led_cdev->dev, &dev_attr_rx); -++ if (rc) -++ goto err_out_link; -++ rc = device_create_file(led_cdev->dev, &dev_attr_tx); -++ if (rc) -++ goto err_out_rx; -++ rc = device_create_file(led_cdev->dev, &dev_attr_interval); -++ if (rc) -++ goto err_out_tx; -++ rc = register_netdevice_notifier(&trigger_data->notifier); -++ if (rc) -++ goto err_out_interval; -++ return; -++ -++err_out_interval: -++ device_remove_file(led_cdev->dev, &dev_attr_interval); -++err_out_tx: -++ device_remove_file(led_cdev->dev, &dev_attr_tx); -++err_out_rx: -++ device_remove_file(led_cdev->dev, &dev_attr_rx); -++err_out_link: -++ device_remove_file(led_cdev->dev, &dev_attr_link); -++err_out_device_name: -++ device_remove_file(led_cdev->dev, &dev_attr_device_name); -++err_out: -++ led_cdev->trigger_data = NULL; -++ kfree(trigger_data); -++} -++ -++static void netdev_trig_deactivate(struct led_classdev *led_cdev) -++{ -++ struct led_netdev_data *trigger_data = led_cdev->trigger_data; -++ -++ if (trigger_data) { -++ unregister_netdevice_notifier(&trigger_data->notifier); -++ -++ device_remove_file(led_cdev->dev, &dev_attr_device_name); -++ device_remove_file(led_cdev->dev, &dev_attr_link); -++ device_remove_file(led_cdev->dev, &dev_attr_rx); -++ device_remove_file(led_cdev->dev, &dev_attr_tx); -++ device_remove_file(led_cdev->dev, &dev_attr_interval); -++ -++ cancel_delayed_work_sync(&trigger_data->work); -++ -++ if (trigger_data->net_dev) -++ dev_put(trigger_data->net_dev); -++ -++ kfree(trigger_data); -++ } -++} -++ -++static struct led_trigger netdev_led_trigger = { -++ .name = "netdev", -++ .activate = netdev_trig_activate, -++ .deactivate = netdev_trig_deactivate, -++}; -++ -++static int __init netdev_trig_init(void) -++{ -++ return led_trigger_register(&netdev_led_trigger); -++} -++ -++static void __exit netdev_trig_exit(void) -++{ -++ led_trigger_unregister(&netdev_led_trigger); -++} -++ -++module_init(netdev_trig_init); -++module_exit(netdev_trig_exit); -++ -++MODULE_AUTHOR("Ben Whitten "); -++MODULE_AUTHOR("Oliver Jowett "); -++MODULE_DESCRIPTION("Netdev LED trigger"); -++MODULE_LICENSE("GPL v2"); -diff --git a/target/linux/generic/backport-4.14/401-v5.2-leds-trigger-netdev-fix-refcnt-leak-on-interface-ren.patch b/target/linux/generic/backport-4.14/401-v5.2-leds-trigger-netdev-fix-refcnt-leak-on-interface-ren.patch -new file mode 100644 -index 0000000000..32682627fc ---- /dev/null -+++ b/target/linux/generic/backport-4.14/401-v5.2-leds-trigger-netdev-fix-refcnt-leak-on-interface-ren.patch -@@ -0,0 +1,69 @@ -+From dd7590a3ab3f0804ed5e930295e2caa5979e3958 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Thu, 28 Feb 2019 22:57:33 +0100 -+Subject: [PATCH] leds: trigger: netdev: fix refcnt leak on interface rename -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+Renaming a netdev-trigger-tracked interface was resulting in an -+unbalanced dev_hold(). -+ -+Example: -+> iw phy phy0 interface add foo type __ap -+> echo netdev > trigger -+> echo foo > device_name -+> ip link set foo name bar -+> iw dev bar del -+[ 237.355366] unregister_netdevice: waiting for bar to become free. Usage count = 1 -+[ 247.435362] unregister_netdevice: waiting for bar to become free. Usage count = 1 -+[ 257.545366] unregister_netdevice: waiting for bar to become free. Usage count = 1 -+ -+Above problem was caused by trigger checking a dev->name which obviously -+changes after renaming an interface. It meant missing all further events -+including the NETDEV_UNREGISTER which is required for calling dev_put(). -+ -+This change fixes that by: -+1) Comparing device struct *address* for notification-filtering purposes -+2) Dropping unneeded NETDEV_CHANGENAME code (no behavior change) -+ -+Fixes: 06f502f57d0d ("leds: trigger: Introduce a NETDEV trigger") -+Signed-off-by: Rafał Miłecki -+Acked-by: Pavel Machek -+Signed-off-by: Jacek Anaszewski -+--- -+ drivers/leds/trigger/ledtrig-netdev.c | 13 +++++-------- -+ 1 file changed, 5 insertions(+), 8 deletions(-) -+ -+--- a/drivers/leds/trigger/ledtrig-netdev.c -++++ b/drivers/leds/trigger/ledtrig-netdev.c -+@@ -299,11 +299,11 @@ static int netdev_trig_notify(struct not -+ notifier); -+ -+ if (evt != NETDEV_UP && evt != NETDEV_DOWN && evt != NETDEV_CHANGE -+- && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER -+- && evt != NETDEV_CHANGENAME) -++ && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER) -+ return NOTIFY_DONE; -+ -+- if (strcmp(dev->name, trigger_data->device_name)) -++ if (!(dev == trigger_data->net_dev || -++ (evt == NETDEV_REGISTER && !strcmp(dev->name, trigger_data->device_name)))) -+ return NOTIFY_DONE; -+ -+ cancel_delayed_work_sync(&trigger_data->work); -+@@ -318,12 +318,9 @@ static int netdev_trig_notify(struct not -+ dev_hold(dev); -+ trigger_data->net_dev = dev; -+ break; -+- case NETDEV_CHANGENAME: -+ case NETDEV_UNREGISTER: -+- if (trigger_data->net_dev) { -+- dev_put(trigger_data->net_dev); -+- trigger_data->net_dev = NULL; -+- } -++ dev_put(trigger_data->net_dev); -++ trigger_data->net_dev = NULL; -+ break; -+ case NETDEV_UP: -+ case NETDEV_CHANGE: -diff --git a/target/linux/generic/backport-4.14/402-leds-trigger-netdev-fix-handling-on-interface-rename.patch b/target/linux/generic/backport-4.14/402-leds-trigger-netdev-fix-handling-on-interface-rename.patch -new file mode 100644 -index 0000000000..ae7d6e8bcb ---- /dev/null -+++ b/target/linux/generic/backport-4.14/402-leds-trigger-netdev-fix-handling-on-interface-rename.patch -@@ -0,0 +1,49 @@ -+From 0ff035231edca3713c3d0839c44e64a4ac41ef38 Mon Sep 17 00:00:00 2001 -+From: Martin Schiller -+Date: Thu, 24 Oct 2019 15:09:23 +0200 -+Subject: [PATCH] leds: trigger: netdev: fix handling on interface rename -+ -+The NETDEV_CHANGENAME code is not "unneeded" like it is stated in commit -+4cb6560514fa ("leds: trigger: netdev: fix refcnt leak on interface -+rename"). -+ -+The event was accidentally misinterpreted equivalent to -+NETDEV_UNREGISTER, but should be equivalent to NETDEV_REGISTER. -+ -+This was the case in the original code from the openwrt project. -+ -+Otherwise, you are unable to set netdev led triggers for (non-existent) -+netdevices, which has to be renamed. This is the case, for example, for -+ppp interfaces in openwrt. -+ -+Fixes: 06f502f57d0d ("leds: trigger: Introduce a NETDEV trigger") -+Fixes: 4cb6560514fa ("leds: trigger: netdev: fix refcnt leak on interface rename") -+Signed-off-by: Martin Schiller -+--- -+ drivers/leds/trigger/ledtrig-netdev.c | 5 ++++- -+ 1 file changed, 4 insertions(+), 1 deletion(-) -+ -+--- a/drivers/leds/trigger/ledtrig-netdev.c -++++ b/drivers/leds/trigger/ledtrig-netdev.c -+@@ -299,10 +299,12 @@ static int netdev_trig_notify(struct not -+ notifier); -+ -+ if (evt != NETDEV_UP && evt != NETDEV_DOWN && evt != NETDEV_CHANGE -+- && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER) -++ && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER -++ && evt != NETDEV_CHANGENAME) -+ return NOTIFY_DONE; -+ -+ if (!(dev == trigger_data->net_dev || -++ (evt == NETDEV_CHANGENAME && !strcmp(dev->name, trigger_data->device_name)) || -+ (evt == NETDEV_REGISTER && !strcmp(dev->name, trigger_data->device_name)))) -+ return NOTIFY_DONE; -+ -+@@ -312,6 +314,7 @@ static int netdev_trig_notify(struct not -+ -+ clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); -+ switch (evt) { -++ case NETDEV_CHANGENAME: -+ case NETDEV_REGISTER: -+ if (trigger_data->net_dev) -+ dev_put(trigger_data->net_dev); -diff --git a/target/linux/generic/backport-4.14/410-mtd-fix-calculating-partition-end-address.patch b/target/linux/generic/backport-4.14/410-mtd-fix-calculating-partition-end-address.patch -new file mode 100644 -index 0000000000..ec25eef7a9 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/410-mtd-fix-calculating-partition-end-address.patch -@@ -0,0 +1,28 @@ -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Mon, 9 Mar 2020 08:30:19 +0100 -+Subject: [PATCH] mtd: fix calculating partition end address -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This fixes check for partitions that don't start at beginning of their -+parents. Missing partition's offset in formula could result in forcing -+read-only incorrectly. -+ -+Fixes: 6750f61a13a0 ("mtd: improve calculating partition boundaries when checking for alignment") -+Signed-off-by: Rafał Miłecki -+--- -+ drivers/mtd/mtdpart.c | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/drivers/mtd/mtdpart.c -++++ b/drivers/mtd/mtdpart.c -+@@ -582,7 +582,7 @@ static struct mtd_part *allocate_partiti -+ part->name); -+ } -+ -+- tmp = part_absolute_offset(parent) + slave->mtd.size; -++ tmp = part_absolute_offset(parent) + slave->offset + slave->mtd.size; -+ remainder = do_div(tmp, wr_alignment); -+ if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) { -+ slave->mtd.flags &= ~MTD_WRITEABLE; -diff --git a/target/linux/generic/backport-4.14/420-enable-CONFIG_MMC_SDHCI_IO_ACCESSORS.patch b/target/linux/generic/backport-4.14/420-enable-CONFIG_MMC_SDHCI_IO_ACCESSORS.patch -new file mode 100644 -index 0000000000..eabfc64378 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/420-enable-CONFIG_MMC_SDHCI_IO_ACCESSORS.patch -@@ -0,0 +1,23 @@ -+From: Vijay Viswanath -+Date: Wed, 27 Sep 2017 11:04:42 +0530 -+Subject: [PATCH v2 3/4] mmc: Kconfig: Enable CONFIG_MMC_SDHCI_IO_ACCESSORS -+ -+Enable CONFIG_MMC_SDHCI_IO_ACCESSORS so that SDHC controller specific -+register read and write APIs, if registered, can be used. -+ -+Signed-off-by: Vijay Viswanath -+Acked-by: Adrian Hunter -+--- -+ drivers/mmc/host/Kconfig | 1 + -+ 1 file changed, 1 insertion(+) -+ -+--- a/drivers/mmc/host/Kconfig -++++ b/drivers/mmc/host/Kconfig -+@@ -310,6 +310,7 @@ config MMC_SDHCI_BCM_KONA -+ tristate "SDHCI support on Broadcom KONA platform" -+ depends on ARCH_BCM_MOBILE -+ depends on MMC_SDHCI_PLTFM -++ select MMC_SDHCI_IO_ACCESSORS -+ help -+ This selects the Broadcom Kona Secure Digital Host Controller -+ Interface(SDHCI) support. -diff --git a/target/linux/generic/backport-4.14/500-v4.20-ubifs-Fix-default-compression-selection-in-ubifs.patch b/target/linux/generic/backport-4.14/500-v4.20-ubifs-Fix-default-compression-selection-in-ubifs.patch -new file mode 100644 -index 0000000000..4782fc9ed8 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/500-v4.20-ubifs-Fix-default-compression-selection-in-ubifs.patch -@@ -0,0 +1,37 @@ -+From: Gabor Juhos -+Subject: fs: ubifs: fix default compression selection in ubifs -+ -+Signed-off-by: Gabor Juhos -+--- -+ fs/ubifs/sb.c | 13 ++++++++++++- -+ 1 file changed, 12 insertions(+), 1 deletion(-) -+ -+--- a/fs/ubifs/sb.c -++++ b/fs/ubifs/sb.c -+@@ -63,6 +63,17 @@ -+ /* Default time granularity in nanoseconds */ -+ #define DEFAULT_TIME_GRAN 1000000000 -+ -++static int get_default_compressor(void) -++{ -++ if (ubifs_compr_present(UBIFS_COMPR_LZO)) -++ return UBIFS_COMPR_LZO; -++ -++ if (ubifs_compr_present(UBIFS_COMPR_ZLIB)) -++ return UBIFS_COMPR_ZLIB; -++ -++ return UBIFS_COMPR_NONE; -++} -++ -+ /** -+ * create_default_filesystem - format empty UBI volume. -+ * @c: UBIFS file-system description object -+@@ -186,7 +197,7 @@ static int create_default_filesystem(str -+ if (c->mount_opts.override_compr) -+ sup->default_compr = cpu_to_le16(c->mount_opts.compr_type); -+ else -+- sup->default_compr = cpu_to_le16(UBIFS_COMPR_LZO); -++ sup->default_compr = cpu_to_le16(get_default_compressor()); -+ -+ generate_random_uuid(sup->uuid); -+ -diff --git a/target/linux/generic/backport-4.14/900-v4.18-firmware-dmi-Add-access-to-the-SKU-ID-string.patch b/target/linux/generic/backport-4.14/900-v4.18-firmware-dmi-Add-access-to-the-SKU-ID-string.patch -new file mode 100644 -index 0000000000..9c80b47607 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/900-v4.18-firmware-dmi-Add-access-to-the-SKU-ID-string.patch -@@ -0,0 +1,57 @@ -+From b23908d3c48a37c46c6a26df2cdeab1610b360ba Mon Sep 17 00:00:00 2001 -+From: Simon Glass -+Date: Sun, 17 Jun 2018 14:09:42 +0200 -+Subject: [PATCH] firmware: dmi: Add access to the SKU ID string -+ -+This is used in some systems from user space for determining the identity -+of the device. -+ -+Expose this as a file so that that user-space tools don't need to read -+from /sys/firmware/dmi/tables/DMI -+ -+Signed-off-by: Simon Glass -+Signed-off-by: Jean Delvare -+--- -+ drivers/firmware/dmi-id.c | 2 ++ -+ drivers/firmware/dmi_scan.c | 1 + -+ include/linux/mod_devicetable.h | 1 + -+ 3 files changed, 4 insertions(+) -+ -+--- a/drivers/firmware/dmi-id.c -++++ b/drivers/firmware/dmi-id.c -+@@ -47,6 +47,7 @@ DEFINE_DMI_ATTR_WITH_SHOW(product_name, -+ DEFINE_DMI_ATTR_WITH_SHOW(product_version, 0444, DMI_PRODUCT_VERSION); -+ DEFINE_DMI_ATTR_WITH_SHOW(product_serial, 0400, DMI_PRODUCT_SERIAL); -+ DEFINE_DMI_ATTR_WITH_SHOW(product_uuid, 0400, DMI_PRODUCT_UUID); -++DEFINE_DMI_ATTR_WITH_SHOW(product_sku, 0444, DMI_PRODUCT_SKU); -+ DEFINE_DMI_ATTR_WITH_SHOW(product_family, 0444, DMI_PRODUCT_FAMILY); -+ DEFINE_DMI_ATTR_WITH_SHOW(board_vendor, 0444, DMI_BOARD_VENDOR); -+ DEFINE_DMI_ATTR_WITH_SHOW(board_name, 0444, DMI_BOARD_NAME); -+@@ -193,6 +194,7 @@ static void __init dmi_id_init_attr_tabl -+ ADD_DMI_ATTR(product_serial, DMI_PRODUCT_SERIAL); -+ ADD_DMI_ATTR(product_uuid, DMI_PRODUCT_UUID); -+ ADD_DMI_ATTR(product_family, DMI_PRODUCT_FAMILY); -++ ADD_DMI_ATTR(product_sku, DMI_PRODUCT_SKU); -+ ADD_DMI_ATTR(board_vendor, DMI_BOARD_VENDOR); -+ ADD_DMI_ATTR(board_name, DMI_BOARD_NAME); -+ ADD_DMI_ATTR(board_version, DMI_BOARD_VERSION); -+--- a/drivers/firmware/dmi_scan.c -++++ b/drivers/firmware/dmi_scan.c -+@@ -435,6 +435,7 @@ static void __init dmi_decode(const stru -+ dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); -+ dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7); -+ dmi_save_uuid(dm, DMI_PRODUCT_UUID, 8); -++ dmi_save_ident(dm, DMI_PRODUCT_SKU, 25); -+ dmi_save_ident(dm, DMI_PRODUCT_FAMILY, 26); -+ break; -+ case 2: /* Base Board Information */ -+--- a/include/linux/mod_devicetable.h -++++ b/include/linux/mod_devicetable.h -+@@ -471,6 +471,7 @@ enum dmi_field { -+ DMI_PRODUCT_VERSION, -+ DMI_PRODUCT_SERIAL, -+ DMI_PRODUCT_UUID, -++ DMI_PRODUCT_SKU, -+ DMI_PRODUCT_FAMILY, -+ DMI_BOARD_VENDOR, -+ DMI_BOARD_NAME, -diff --git a/target/linux/generic/backport-4.14/950-tty-serial-exar-generalize-rs485-setup.patch b/target/linux/generic/backport-4.14/950-tty-serial-exar-generalize-rs485-setup.patch -new file mode 100644 -index 0000000000..c4c4cfcb71 ---- /dev/null -+++ b/target/linux/generic/backport-4.14/950-tty-serial-exar-generalize-rs485-setup.patch -@@ -0,0 +1,75 @@ -+From 9d9398944488cd3a3e1e0912b26fbc4d5921e547 Mon Sep 17 00:00:00 2001 -+From: Daniel Golle -+Date: Mon, 4 Jun 2018 23:33:07 +0200 -+Subject: [PATCH] tty: serial: exar: generalize RS485 setup -+ -+Move the non-board-specific part of the RS485 initialization from -+iot2040_rs485_config function to a new generic function used also for -+other boards. -+This allows using TIOCGRS485 and TIOCSRS485 on boards (such as mPCIe -+serial IO modules) which are hard-wired to RS485 or have jumpers for -+their configurations. -+ -+Signed-off-by: Daniel Golle -+Reviewed-by: Jan Kiszka -+Signed-off-by: Greg Kroah-Hartman -+--- -+ drivers/tty/serial/8250/8250_exar.c | 38 +++++++++++++++++++---------- -+ 1 file changed, 25 insertions(+), 13 deletions(-) -+ -+--- a/drivers/tty/serial/8250/8250_exar.c -++++ b/drivers/tty/serial/8250/8250_exar.c -+@@ -293,8 +293,32 @@ static int xr17v35x_register_gpio(struct -+ return 0; -+ } -+ -++static int generic_rs485_config(struct uart_port *port, -++ struct serial_rs485 *rs485) -++{ -++ bool is_rs485 = !!(rs485->flags & SER_RS485_ENABLED); -++ u8 __iomem *p = port->membase; -++ u8 value; -++ -++ value = readb(p + UART_EXAR_FCTR); -++ if (is_rs485) -++ value |= UART_FCTR_EXAR_485; -++ else -++ value &= ~UART_FCTR_EXAR_485; -++ -++ writeb(value, p + UART_EXAR_FCTR); -++ -++ if (is_rs485) -++ writeb(UART_EXAR_RS485_DLY(4), p + UART_MSR); -++ -++ port->rs485 = *rs485; -++ -++ return 0; -++} -++ -+ static const struct exar8250_platform exar8250_default_platform = { -+ .register_gpio = xr17v35x_register_gpio, -++ .rs485_config = generic_rs485_config, -+ }; -+ -+ static int iot2040_rs485_config(struct uart_port *port, -+@@ -327,19 +351,7 @@ static int iot2040_rs485_config(struct u -+ value |= mode; -+ writeb(value, p + UART_EXAR_MPIOLVL_7_0); -+ -+- value = readb(p + UART_EXAR_FCTR); -+- if (is_rs485) -+- value |= UART_FCTR_EXAR_485; -+- else -+- value &= ~UART_FCTR_EXAR_485; -+- writeb(value, p + UART_EXAR_FCTR); -+- -+- if (is_rs485) -+- writeb(UART_EXAR_RS485_DLY(4), p + UART_MSR); -+- -+- port->rs485 = *rs485; -+- -+- return 0; -++ return generic_rs485_config(port, rs485); -+ } -+ -+ static const struct property_entry iot2040_gpio_properties[] = { -diff --git a/target/linux/generic/config-4.14 b/target/linux/generic/config-4.14 -new file mode 100644 -index 0000000000..6bf7dac5e3 ---- /dev/null -+++ b/target/linux/generic/config-4.14 -@@ -0,0 +1,5793 @@ -+# CONFIG_104_QUAD_8 is not set -+CONFIG_32BIT=y -+# CONFIG_6LOWPAN is not set -+# CONFIG_6LOWPAN_DEBUGFS is not set -+# CONFIG_6PACK is not set -+# CONFIG_8139CP is not set -+# CONFIG_8139TOO is not set -+# CONFIG_9P_FS is not set -+# CONFIG_AB3100_CORE is not set -+# CONFIG_AB8500_CORE is not set -+# CONFIG_ABP060MG is not set -+# CONFIG_ABX500_CORE is not set -+# CONFIG_ACCESSIBILITY is not set -+# CONFIG_ACENIC is not set -+# CONFIG_ACERHDF is not set -+# CONFIG_ACORN_PARTITION is not set -+# CONFIG_ACPI_ALS is not set -+# CONFIG_ACPI_APEI is not set -+# CONFIG_ACPI_BUTTON is not set -+# CONFIG_ACPI_CONFIGFS is not set -+# CONFIG_ACPI_CUSTOM_METHOD is not set -+# CONFIG_ACPI_EXTLOG is not set -+# CONFIG_ACPI_HED is not set -+# CONFIG_ACPI_NFIT is not set -+# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set -+# CONFIG_ACPI_TABLE_UPGRADE is not set -+# CONFIG_ACPI_VIDEO is not set -+# CONFIG_AD2S1200 is not set -+# CONFIG_AD2S1210 is not set -+# CONFIG_AD2S90 is not set -+# CONFIG_AD5064 is not set -+# CONFIG_AD525X_DPOT is not set -+# CONFIG_AD5360 is not set -+# CONFIG_AD5380 is not set -+# CONFIG_AD5421 is not set -+# CONFIG_AD5446 is not set -+# CONFIG_AD5449 is not set -+# CONFIG_AD5504 is not set -+# CONFIG_AD5592R is not set -+# CONFIG_AD5593R is not set -+# CONFIG_AD5624R_SPI is not set -+# CONFIG_AD5686 is not set -+# CONFIG_AD5755 is not set -+# CONFIG_AD5761 is not set -+# CONFIG_AD5764 is not set -+# CONFIG_AD5791 is not set -+# CONFIG_AD5933 is not set -+# CONFIG_AD7150 is not set -+# CONFIG_AD7152 is not set -+# CONFIG_AD7192 is not set -+# CONFIG_AD7266 is not set -+# CONFIG_AD7280 is not set -+# CONFIG_AD7291 is not set -+# CONFIG_AD7298 is not set -+# CONFIG_AD7303 is not set -+# CONFIG_AD7476 is not set -+# CONFIG_AD7606 is not set -+# CONFIG_AD7746 is not set -+# CONFIG_AD7766 is not set -+# CONFIG_AD7780 is not set -+# CONFIG_AD7791 is not set -+# CONFIG_AD7793 is not set -+# CONFIG_AD7816 is not set -+# CONFIG_AD7887 is not set -+# CONFIG_AD7923 is not set -+# CONFIG_AD799X is not set -+# CONFIG_AD8366 is not set -+# CONFIG_AD8801 is not set -+# CONFIG_AD9523 is not set -+# CONFIG_AD9832 is not set -+# CONFIG_AD9834 is not set -+# CONFIG_ADAPTEC_STARFIRE is not set -+# CONFIG_ADE7753 is not set -+# CONFIG_ADE7754 is not set -+# CONFIG_ADE7758 is not set -+# CONFIG_ADE7759 is not set -+# CONFIG_ADE7854 is not set -+# CONFIG_ADF4350 is not set -+# CONFIG_ADFS_FS is not set -+# CONFIG_ADIS16060 is not set -+# CONFIG_ADIS16080 is not set -+# CONFIG_ADIS16130 is not set -+# CONFIG_ADIS16136 is not set -+# CONFIG_ADIS16201 is not set -+# CONFIG_ADIS16203 is not set -+# CONFIG_ADIS16209 is not set -+# CONFIG_ADIS16240 is not set -+# CONFIG_ADIS16260 is not set -+# CONFIG_ADIS16400 is not set -+# CONFIG_ADIS16480 is not set -+# CONFIG_ADJD_S311 is not set -+# CONFIG_ADM6996_PHY is not set -+# CONFIG_ADM8211 is not set -+# CONFIG_ADT7316 is not set -+CONFIG_ADVISE_SYSCALLS=y -+# CONFIG_ADXL345_I2C is not set -+# CONFIG_ADXL345_SPI is not set -+# CONFIG_ADXRS450 is not set -+CONFIG_AEABI=y -+# CONFIG_AFE4403 is not set -+# CONFIG_AFE4404 is not set -+# CONFIG_AFFS_FS is not set -+# CONFIG_AFS_FS is not set -+# CONFIG_AF_KCM is not set -+# CONFIG_AF_RXRPC is not set -+# CONFIG_AF_RXRPC_INJECT_LOSS is not set -+# CONFIG_AF_RXRPC_IPV6 is not set -+# CONFIG_AGP is not set -+# CONFIG_AHCI_CEVA is not set -+# CONFIG_AHCI_IMX is not set -+# CONFIG_AHCI_MVEBU is not set -+# CONFIG_AHCI_QORIQ is not set -+CONFIG_AIO=y -+# CONFIG_AIRO is not set -+# CONFIG_AIRO_CS is not set -+# CONFIG_AIX_PARTITION is not set -+# CONFIG_AK09911 is not set -+# CONFIG_AK8974 is not set -+# CONFIG_AK8975 is not set -+# CONFIG_AL3320A is not set -+# CONFIG_ALIM7101_WDT is not set -+CONFIG_ALLOW_DEV_COREDUMP=y -+# CONFIG_ALTERA_MBOX is not set -+# CONFIG_ALTERA_MSGDMA is not set -+# CONFIG_ALTERA_STAPL is not set -+# CONFIG_ALTERA_TSE is not set -+# CONFIG_ALX is not set -+# CONFIG_AM2315 is not set -+# CONFIG_AM335X_PHY_USB is not set -+# CONFIG_AMBA_PL08X is not set -+# CONFIG_AMD8111_ETH is not set -+# CONFIG_AMD_MEM_ENCRYPT is not set -+# CONFIG_AMD_PHY is not set -+# CONFIG_AMD_XGBE is not set -+# CONFIG_AMD_XGBE_HAVE_ECC is not set -+# CONFIG_AMIGA_PARTITION is not set -+# CONFIG_AMILO_RFKILL is not set -+# CONFIG_ANDROID is not set -+CONFIG_ANON_INODES=y -+# CONFIG_APDS9300 is not set -+# CONFIG_APDS9802ALS is not set -+# CONFIG_APDS9960 is not set -+# CONFIG_APM8018X is not set -+# CONFIG_APM_EMULATION is not set -+# CONFIG_APPLE_GMUX is not set -+# CONFIG_APPLE_PROPERTIES is not set -+# CONFIG_APPLICOM is not set -+# CONFIG_AQTION is not set -+# CONFIG_AQUANTIA_PHY is not set -+# CONFIG_AR5523 is not set -+# CONFIG_AR7 is not set -+# CONFIG_AR8216_PHY is not set -+# CONFIG_AR8216_PHY_LEDS is not set -+# CONFIG_ARCH_ACTIONS is not set -+# CONFIG_ARCH_ALPINE is not set -+# CONFIG_ARCH_ARTPEC is not set -+# CONFIG_ARCH_ASPEED is not set -+# CONFIG_ARCH_AT91 is not set -+# CONFIG_ARCH_BCM is not set -+# CONFIG_ARCH_BCM2835 is not set -+# CONFIG_ARCH_BCM_21664 is not set -+# CONFIG_ARCH_BCM_23550 is not set -+# CONFIG_ARCH_BCM_281XX is not set -+# CONFIG_ARCH_BCM_5301X is not set -+# CONFIG_ARCH_BCM_53573 is not set -+# CONFIG_ARCH_BCM_63XX is not set -+# CONFIG_ARCH_BCM_CYGNUS is not set -+# CONFIG_ARCH_BCM_IPROC is not set -+# CONFIG_ARCH_BCM_NSP is not set -+# CONFIG_ARCH_BERLIN is not set -+# CONFIG_ARCH_BRCMSTB is not set -+# CONFIG_ARCH_CLPS711X is not set -+# CONFIG_ARCH_CNS3XXX is not set -+# CONFIG_ARCH_DAVINCI is not set -+# CONFIG_ARCH_DIGICOLOR is not set -+# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set -+# CONFIG_ARCH_DOVE is not set -+# CONFIG_ARCH_EBSA110 is not set -+# CONFIG_ARCH_EP93XX is not set -+# CONFIG_ARCH_EXYNOS is not set -+CONFIG_ARCH_FLATMEM_ENABLE=y -+# CONFIG_ARCH_FOOTBRIDGE is not set -+# CONFIG_ARCH_GEMINI is not set -+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y -+# CONFIG_ARCH_HAS_ILOG2_U32 is not set -+# CONFIG_ARCH_HAS_ILOG2_U64 is not set -+CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y -+# CONFIG_ARCH_HI3xxx is not set -+# CONFIG_ARCH_HIGHBANK is not set -+# CONFIG_ARCH_HISI is not set -+# CONFIG_ARCH_INTEGRATOR is not set -+# CONFIG_ARCH_IOP13XX is not set -+# CONFIG_ARCH_IOP32X is not set -+# CONFIG_ARCH_IOP33X is not set -+# CONFIG_ARCH_IXP4XX is not set -+# CONFIG_ARCH_KEYSTONE is not set -+# CONFIG_ARCH_KS8695 is not set -+# CONFIG_ARCH_LAYERSCAPE is not set -+# CONFIG_ARCH_LG1K is not set -+# CONFIG_ARCH_LPC32XX is not set -+# CONFIG_ARCH_MEDIATEK is not set -+# CONFIG_ARCH_MESON is not set -+CONFIG_ARCH_MMAP_RND_BITS=8 -+CONFIG_ARCH_MMAP_RND_BITS_MAX=16 -+CONFIG_ARCH_MMAP_RND_BITS_MIN=8 -+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 -+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 -+# CONFIG_ARCH_MMP is not set -+# CONFIG_ARCH_MULTIPLATFORM is not set -+# CONFIG_ARCH_MULTI_V6 is not set -+# CONFIG_ARCH_MULTI_V7 is not set -+# CONFIG_ARCH_MV78XX0 is not set -+# CONFIG_ARCH_MVEBU is not set -+# CONFIG_ARCH_MXC is not set -+# CONFIG_ARCH_MXS is not set -+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set -+# CONFIG_ARCH_NETX is not set -+# CONFIG_ARCH_NOMADIK is not set -+# CONFIG_ARCH_NSPIRE is not set -+# CONFIG_ARCH_OMAP is not set -+# CONFIG_ARCH_OMAP1 is not set -+# CONFIG_ARCH_OMAP2 is not set -+# CONFIG_ARCH_OMAP2PLUS is not set -+# CONFIG_ARCH_OMAP3 is not set -+# CONFIG_ARCH_OMAP4 is not set -+# CONFIG_ARCH_ORION5X is not set -+# CONFIG_ARCH_OXNAS is not set -+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -+# CONFIG_ARCH_PICOXCELL is not set -+# CONFIG_ARCH_PRIMA2 is not set -+# CONFIG_ARCH_PXA is not set -+# CONFIG_ARCH_QCOM is not set -+# CONFIG_ARCH_REALTEK is not set -+# CONFIG_ARCH_REALVIEW is not set -+# CONFIG_ARCH_RENESAS is not set -+# CONFIG_ARCH_ROCKCHIP is not set -+# CONFIG_ARCH_RPC is not set -+# CONFIG_ARCH_S3C24XX is not set -+# CONFIG_ARCH_S3C64XX is not set -+# CONFIG_ARCH_S5PV210 is not set -+# CONFIG_ARCH_SA1100 is not set -+# CONFIG_ARCH_SEATTLE is not set -+# CONFIG_ARCH_SHMOBILE is not set -+# CONFIG_ARCH_SIRF is not set -+# CONFIG_ARCH_SOCFPGA is not set -+# CONFIG_ARCH_SPRD is not set -+# CONFIG_ARCH_STI is not set -+# CONFIG_ARCH_STRATIX10 is not set -+# CONFIG_ARCH_SUNXI is not set -+# CONFIG_ARCH_TANGO is not set -+# CONFIG_ARCH_TEGRA is not set -+# CONFIG_ARCH_THUNDER is not set -+# CONFIG_ARCH_THUNDER2 is not set -+# CONFIG_ARCH_U300 is not set -+# CONFIG_ARCH_U8500 is not set -+# CONFIG_ARCH_UNIPHIER is not set -+# CONFIG_ARCH_VERSATILE is not set -+# CONFIG_ARCH_VEXPRESS is not set -+# CONFIG_ARCH_VIRT is not set -+# CONFIG_ARCH_VT8500 is not set -+# CONFIG_ARCH_VULCAN is not set -+# CONFIG_ARCH_W90X900 is not set -+# CONFIG_ARCH_WANTS_THP_SWAP is not set -+# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set -+# CONFIG_ARCH_WM8505 is not set -+# CONFIG_ARCH_WM8750 is not set -+# CONFIG_ARCH_WM8850 is not set -+# CONFIG_ARCH_XGENE is not set -+# CONFIG_ARCH_ZX is not set -+# CONFIG_ARCH_ZYNQ is not set -+# CONFIG_ARCH_ZYNQMP is not set -+# CONFIG_ARCNET is not set -+# CONFIG_ARC_EMAC is not set -+# CONFIG_ARM64_ERRATUM_1024718 is not set -+# CONFIG_ARM64_ERRATUM_819472 is not set -+# CONFIG_ARM64_ERRATUM_824069 is not set -+# CONFIG_ARM64_ERRATUM_826319 is not set -+# CONFIG_ARM64_ERRATUM_827319 is not set -+# CONFIG_ARM64_ERRATUM_832075 is not set -+# CONFIG_ARM64_ERRATUM_834220 is not set -+# CONFIG_ARM64_ERRATUM_843419 is not set -+# CONFIG_ARM64_ERRATUM_845719 is not set -+# CONFIG_ARM64_ERRATUM_858921 is not set -+# CONFIG_ARM64_RELOC_TEST is not set -+CONFIG_ARM64_SW_TTBR0_PAN=y -+# CONFIG_ARM_APPENDED_DTB is not set -+# CONFIG_ARM_ARCH_TIMER is not set -+# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set -+# CONFIG_ARM_CCI is not set -+# CONFIG_ARM_CCI400_PMU is not set -+# CONFIG_ARM_CCI5xx_PMU is not set -+# CONFIG_ARM_CCN is not set -+# CONFIG_ARM_CPUIDLE is not set -+CONFIG_ARM_CPU_TOPOLOGY=y -+# CONFIG_ARM_CRYPTO is not set -+CONFIG_ARM_DMA_MEM_BUFFERABLE=y -+# CONFIG_ARM_ERRATA_326103 is not set -+# CONFIG_ARM_ERRATA_364296 is not set -+# CONFIG_ARM_ERRATA_411920 is not set -+# CONFIG_ARM_ERRATA_430973 is not set -+# CONFIG_ARM_ERRATA_458693 is not set -+# CONFIG_ARM_ERRATA_460075 is not set -+# CONFIG_ARM_ERRATA_643719 is not set -+# CONFIG_ARM_ERRATA_720789 is not set -+# CONFIG_ARM_ERRATA_742230 is not set -+# CONFIG_ARM_ERRATA_742231 is not set -+# CONFIG_ARM_ERRATA_743622 is not set -+# CONFIG_ARM_ERRATA_751472 is not set -+# CONFIG_ARM_ERRATA_754322 is not set -+# CONFIG_ARM_ERRATA_754327 is not set -+# CONFIG_ARM_ERRATA_764369 is not set -+# CONFIG_ARM_ERRATA_773022 is not set -+# CONFIG_ARM_ERRATA_775420 is not set -+# CONFIG_ARM_ERRATA_798181 is not set -+# CONFIG_ARM_ERRATA_818325_852422 is not set -+# CONFIG_ARM_ERRATA_821420 is not set -+# CONFIG_ARM_ERRATA_825619 is not set -+# CONFIG_ARM_ERRATA_852421 is not set -+# CONFIG_ARM_ERRATA_852423 is not set -+CONFIG_ARM_GIC_MAX_NR=1 -+# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set -+# CONFIG_ARM_KPROBES_TEST is not set -+# CONFIG_ARM_MHU is not set -+# CONFIG_ARM_MODULE_PLTS is not set -+# CONFIG_ARM_PATCH_PHYS_VIRT is not set -+# CONFIG_ARM_PSCI is not set -+# CONFIG_ARM_PSCI_CHECKER is not set -+# CONFIG_ARM_PTDUMP is not set -+# CONFIG_ARM_SBSA_WATCHDOG is not set -+# CONFIG_ARM_SCPI_PROTOCOL is not set -+# CONFIG_ARM_TIMER_SP804 is not set -+# CONFIG_ARM_UNWIND is not set -+# CONFIG_ARM_VIRT_EXT is not set -+# CONFIG_AS3935 is not set -+# CONFIG_ASM9260_TIMER is not set -+# CONFIG_ASUS_LAPTOP is not set -+# CONFIG_ASUS_WIRELESS is not set -+# CONFIG_ASYMMETRIC_KEY_TYPE is not set -+# CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE is not set -+# CONFIG_ASYNC_RAID6_TEST is not set -+# CONFIG_ASYNC_TX_DMA is not set -+# CONFIG_AT76C50X_USB is not set -+# CONFIG_AT803X_PHY is not set -+# CONFIG_AT91_SAMA5D2_ADC is not set -+# CONFIG_ATA is not set -+# CONFIG_ATAGS is not set -+CONFIG_ATAGS_PROC=y -+# CONFIG_ATALK is not set -+# CONFIG_ATARI_PARTITION is not set -+# CONFIG_ATA_ACPI is not set -+CONFIG_ATA_BMDMA=y -+# CONFIG_ATA_GENERIC is not set -+# CONFIG_ATA_LEDS is not set -+# CONFIG_ATA_NONSTANDARD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_ATA_PIIX is not set -+CONFIG_ATA_SFF=y -+# CONFIG_ATA_VERBOSE_ERROR is not set -+# CONFIG_ATH10K is not set -+# CONFIG_ATH25 is not set -+# CONFIG_ATH5K is not set -+# CONFIG_ATH6KL is not set -+# CONFIG_ATH79 is not set -+# CONFIG_ATH9K is not set -+# CONFIG_ATH9K_HTC is not set -+# CONFIG_ATH_DEBUG is not set -+# CONFIG_ATL1 is not set -+# CONFIG_ATL1C is not set -+# CONFIG_ATL1E is not set -+# CONFIG_ATL2 is not set -+# CONFIG_ATLAS_PH_SENSOR is not set -+# CONFIG_ATM is not set -+# CONFIG_ATMEL is not set -+# CONFIG_ATMEL_PIT is not set -+# CONFIG_ATMEL_SSC is not set -+# CONFIG_ATM_AMBASSADOR is not set -+# CONFIG_ATM_BR2684 is not set -+CONFIG_ATM_BR2684_IPFILTER=y -+# CONFIG_ATM_CLIP is not set -+CONFIG_ATM_CLIP_NO_ICMP=y -+# CONFIG_ATM_DRIVERS is not set -+# CONFIG_ATM_DUMMY is not set -+# CONFIG_ATM_ENI is not set -+# CONFIG_ATM_FIRESTREAM is not set -+# CONFIG_ATM_FORE200E is not set -+# CONFIG_ATM_HE is not set -+# CONFIG_ATM_HORIZON is not set -+# CONFIG_ATM_IA is not set -+# CONFIG_ATM_IDT77252 is not set -+# CONFIG_ATM_LANAI is not set -+# CONFIG_ATM_LANE is not set -+# CONFIG_ATM_MPOA is not set -+# CONFIG_ATM_NICSTAR is not set -+# CONFIG_ATM_SOLOS is not set -+# CONFIG_ATM_TCP is not set -+# CONFIG_ATM_ZATM is not set -+# CONFIG_ATOMIC64_SELFTEST is not set -+# CONFIG_ATP is not set -+# CONFIG_AUDIT is not set -+# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set -+# CONFIG_AURORA_NB8800 is not set -+# CONFIG_AUTOFS4_FS is not set -+# CONFIG_AUTO_ZRELADDR is not set -+# CONFIG_AUXDISPLAY is not set -+# CONFIG_AX25 is not set -+# CONFIG_AX25_DAMA_SLAVE is not set -+# CONFIG_AX88796 is not set -+# CONFIG_AXP20X_ADC is not set -+# CONFIG_AXP20X_POWER is not set -+# CONFIG_AXP288_ADC is not set -+# CONFIG_AXP288_FUEL_GAUGE is not set -+# CONFIG_B43 is not set -+# CONFIG_B43LEGACY is not set -+# CONFIG_B44 is not set -+# CONFIG_B53 is not set -+# CONFIG_BACKLIGHT_ADP8860 is not set -+# CONFIG_BACKLIGHT_ADP8870 is not set -+# CONFIG_BACKLIGHT_APPLE is not set -+# CONFIG_BACKLIGHT_ARCXCNN is not set -+# CONFIG_BACKLIGHT_BD6107 is not set -+# CONFIG_BACKLIGHT_GENERIC is not set -+# CONFIG_BACKLIGHT_GPIO is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+# CONFIG_BACKLIGHT_LM3630A is not set -+# CONFIG_BACKLIGHT_LM3639 is not set -+# CONFIG_BACKLIGHT_LP855X is not set -+# CONFIG_BACKLIGHT_LV5207LP is not set -+# CONFIG_BACKLIGHT_PANDORA is not set -+# CONFIG_BACKLIGHT_PM8941_WLED is not set -+# CONFIG_BACKLIGHT_PWM is not set -+# CONFIG_BACKLIGHT_RPI is not set -+# CONFIG_BACKLIGHT_SAHARA is not set -+# CONFIG_BACKTRACE_SELF_TEST is not set -+CONFIG_BASE_FULL=y -+CONFIG_BASE_SMALL=0 -+# CONFIG_BATMAN_ADV is not set -+# CONFIG_BATTERY_BQ27XXX is not set -+# CONFIG_BATTERY_BQ27XXX_HDQ is not set -+# CONFIG_BATTERY_DS2760 is not set -+# CONFIG_BATTERY_DS2780 is not set -+# CONFIG_BATTERY_DS2781 is not set -+# CONFIG_BATTERY_DS2782 is not set -+# CONFIG_BATTERY_GAUGE_LTC2941 is not set -+# CONFIG_BATTERY_GOLDFISH is not set -+# CONFIG_BATTERY_LEGO_EV3 is not set -+# CONFIG_BATTERY_MAX17040 is not set -+# CONFIG_BATTERY_MAX17042 is not set -+# CONFIG_BATTERY_MAX1721X is not set -+# CONFIG_BATTERY_SBS is not set -+# CONFIG_BAYCOM_EPP is not set -+# CONFIG_BAYCOM_PAR is not set -+# CONFIG_BAYCOM_SER_FDX is not set -+# CONFIG_BAYCOM_SER_HDX is not set -+# CONFIG_BCACHE is not set -+# CONFIG_BCM47XX is not set -+# CONFIG_BCM63XX is not set -+# CONFIG_BCM63XX_PHY is not set -+# CONFIG_BCM7038_WDT is not set -+# CONFIG_BCM7XXX_PHY is not set -+# CONFIG_BCM87XX_PHY is not set -+# CONFIG_BCMA is not set -+# CONFIG_BCMA_DRIVER_GPIO is not set -+CONFIG_BCMA_POSSIBLE=y -+# CONFIG_BCMGENET is not set -+# CONFIG_BCM_IPROC_ADC is not set -+# CONFIG_BCM_KONA_USB2_PHY is not set -+# CONFIG_BCM_SBA_RAID is not set -+# CONFIG_BDI_SWITCH is not set -+# CONFIG_BE2ISCSI is not set -+# CONFIG_BE2NET is not set -+# CONFIG_BEFS_FS is not set -+# CONFIG_BFS_FS is not set -+# CONFIG_BGMAC is not set -+# CONFIG_BH1750 is not set -+# CONFIG_BH1780 is not set -+# CONFIG_BIG_KEYS is not set -+# CONFIG_BIG_LITTLE is not set -+# CONFIG_BINARY_PRINTF is not set -+# CONFIG_BINFMT_AOUT is not set -+CONFIG_BINFMT_ELF=y -+# CONFIG_BINFMT_FLAT is not set -+# CONFIG_BINFMT_MISC is not set -+CONFIG_BINFMT_SCRIPT=y -+CONFIG_BITREVERSE=y -+# CONFIG_BLK_CMDLINE_PARSER is not set -+# CONFIG_BLK_DEBUG_FS is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -+# CONFIG_BLK_DEV_4DRIVES is not set -+# CONFIG_BLK_DEV_AEC62XX is not set -+# CONFIG_BLK_DEV_ALI14XX is not set -+# CONFIG_BLK_DEV_ALI15X3 is not set -+# CONFIG_BLK_DEV_AMD74XX is not set -+# CONFIG_BLK_DEV_ATIIXP is not set -+# CONFIG_BLK_DEV_BSG is not set -+# CONFIG_BLK_DEV_BSGLIB is not set -+# CONFIG_BLK_DEV_CMD640 is not set -+# CONFIG_BLK_DEV_CMD64X is not set -+# CONFIG_BLK_DEV_COW_COMMON is not set -+# CONFIG_BLK_DEV_CRYPTOLOOP is not set -+# CONFIG_BLK_DEV_CS5520 is not set -+# CONFIG_BLK_DEV_CS5530 is not set -+# CONFIG_BLK_DEV_CS5535 is not set -+# CONFIG_BLK_DEV_CS5536 is not set -+# CONFIG_BLK_DEV_CY82C693 is not set -+# CONFIG_BLK_DEV_DAC960 is not set -+# CONFIG_BLK_DEV_DELKIN is not set -+# CONFIG_BLK_DEV_DRBD is not set -+# CONFIG_BLK_DEV_DTC2278 is not set -+# CONFIG_BLK_DEV_FD is not set -+# CONFIG_BLK_DEV_GENERIC is not set -+# CONFIG_BLK_DEV_HPT366 is not set -+# CONFIG_BLK_DEV_HT6560B is not set -+# CONFIG_BLK_DEV_IDEACPI is not set -+# CONFIG_BLK_DEV_IDECD is not set -+# CONFIG_BLK_DEV_IDECS is not set -+# CONFIG_BLK_DEV_IDEPCI is not set -+# CONFIG_BLK_DEV_IDEPNP is not set -+# CONFIG_BLK_DEV_IDETAPE is not set -+# CONFIG_BLK_DEV_IDE_AU1XXX is not set -+# CONFIG_BLK_DEV_IDE_SATA is not set -+CONFIG_BLK_DEV_INITRD=y -+# CONFIG_BLK_DEV_INTEGRITY is not set -+# CONFIG_BLK_DEV_IO_TRACE is not set -+# CONFIG_BLK_DEV_IT8172 is not set -+# CONFIG_BLK_DEV_IT8213 is not set -+# CONFIG_BLK_DEV_IT821X is not set -+# CONFIG_BLK_DEV_JMICRON is not set -+# CONFIG_BLK_DEV_LOOP is not set -+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 -+# CONFIG_BLK_DEV_NBD is not set -+# CONFIG_BLK_DEV_NS87415 is not set -+# CONFIG_BLK_DEV_NULL_BLK is not set -+# CONFIG_BLK_DEV_NVME is not set -+# CONFIG_BLK_DEV_OFFBOARD is not set -+# CONFIG_BLK_DEV_OPTI621 is not set -+# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set -+# CONFIG_BLK_DEV_PDC202XX_NEW is not set -+# CONFIG_BLK_DEV_PDC202XX_OLD is not set -+# CONFIG_BLK_DEV_PIIX is not set -+# CONFIG_BLK_DEV_PLATFORM is not set -+# CONFIG_BLK_DEV_PMEM is not set -+# CONFIG_BLK_DEV_QD65XX is not set -+# CONFIG_BLK_DEV_RAM is not set -+# CONFIG_BLK_DEV_RBD is not set -+# CONFIG_BLK_DEV_RSXX is not set -+# CONFIG_BLK_DEV_RZ1000 is not set -+# CONFIG_BLK_DEV_SC1200 is not set -+# CONFIG_BLK_DEV_SD is not set -+# CONFIG_BLK_DEV_SIIMAGE is not set -+# CONFIG_BLK_DEV_SIS5513 is not set -+# CONFIG_BLK_DEV_SKD is not set -+# CONFIG_BLK_DEV_SL82C105 is not set -+# CONFIG_BLK_DEV_SLC90E66 is not set -+# CONFIG_BLK_DEV_SR is not set -+# CONFIG_BLK_DEV_SVWKS is not set -+# CONFIG_BLK_DEV_SX8 is not set -+# CONFIG_BLK_DEV_TC86C001 is not set -+# CONFIG_BLK_DEV_THROTTLING is not set -+# CONFIG_BLK_DEV_TRIFLEX is not set -+# CONFIG_BLK_DEV_TRM290 is not set -+# CONFIG_BLK_DEV_UMC8672 is not set -+# CONFIG_BLK_DEV_UMEM is not set -+# CONFIG_BLK_DEV_VIA82CXXX is not set -+# CONFIG_BLK_DEV_ZONED is not set -+# CONFIG_BLK_SED_OPAL is not set -+# CONFIG_BLK_WBT is not set -+CONFIG_BLOCK=y -+# CONFIG_BMA180 is not set -+# CONFIG_BMA220 is not set -+# CONFIG_BMC150_ACCEL is not set -+# CONFIG_BMC150_MAGN is not set -+# CONFIG_BMC150_MAGN_I2C is not set -+# CONFIG_BMC150_MAGN_SPI is not set -+# CONFIG_BMG160 is not set -+# CONFIG_BMI160_I2C is not set -+# CONFIG_BMI160_SPI is not set -+# CONFIG_BMIPS_GENERIC is not set -+# CONFIG_BMP280 is not set -+# CONFIG_BNA is not set -+# CONFIG_BNX2 is not set -+# CONFIG_BNX2X is not set -+# CONFIG_BNX2X_SRIOV is not set -+# CONFIG_BNXT is not set -+# CONFIG_BONDING is not set -+# CONFIG_BOOKE_WDT is not set -+CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT=3 -+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -+# CONFIG_BOOT_PRINTK_DELAY is not set -+CONFIG_BOOT_RAW=y -+CONFIG_BPF=y -+CONFIG_BPF_JIT=y -+# CONFIG_BPF_JIT_ALWAYS_ON is not set -+# CONFIG_BPF_STREAM_PARSER is not set -+CONFIG_BPF_SYSCALL=y -+# CONFIG_BPQETHER is not set -+CONFIG_BQL=y -+CONFIG_BRANCH_PROFILE_NONE=y -+# CONFIG_BRCMFMAC is not set -+# CONFIG_BRCMSMAC is not set -+# CONFIG_BRCMSTB_GISB_ARB is not set -+CONFIG_BRIDGE=y -+# CONFIG_BRIDGE_EBT_802_3 is not set -+# CONFIG_BRIDGE_EBT_AMONG is not set -+# CONFIG_BRIDGE_EBT_ARP is not set -+# CONFIG_BRIDGE_EBT_ARPREPLY is not set -+# CONFIG_BRIDGE_EBT_BROUTE is not set -+# CONFIG_BRIDGE_EBT_DNAT is not set -+# CONFIG_BRIDGE_EBT_IP is not set -+# CONFIG_BRIDGE_EBT_IP6 is not set -+# CONFIG_BRIDGE_EBT_LIMIT is not set -+# CONFIG_BRIDGE_EBT_LOG is not set -+# CONFIG_BRIDGE_EBT_MARK is not set -+# CONFIG_BRIDGE_EBT_MARK_T is not set -+# CONFIG_BRIDGE_EBT_NFLOG is not set -+# CONFIG_BRIDGE_EBT_PKTTYPE is not set -+# CONFIG_BRIDGE_EBT_REDIRECT is not set -+# CONFIG_BRIDGE_EBT_SNAT is not set -+# CONFIG_BRIDGE_EBT_STP is not set -+# CONFIG_BRIDGE_EBT_T_FILTER is not set -+# CONFIG_BRIDGE_EBT_T_NAT is not set -+# CONFIG_BRIDGE_EBT_VLAN is not set -+CONFIG_BRIDGE_IGMP_SNOOPING=y -+# CONFIG_BRIDGE_NETFILTER is not set -+# CONFIG_BRIDGE_NF_EBTABLES is not set -+CONFIG_BRIDGE_VLAN_FILTERING=y -+# CONFIG_BROADCOM_PHY is not set -+CONFIG_BROKEN_ON_SMP=y -+# CONFIG_BSD_DISKLABEL is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_BSD_PROCESS_ACCT_V3 is not set -+# CONFIG_BT is not set -+# CONFIG_BTRFS_ASSERT is not set -+# CONFIG_BTRFS_DEBUG is not set -+# CONFIG_BTRFS_FS is not set -+# CONFIG_BTRFS_FS_POSIX_ACL is not set -+# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set -+# CONFIG_BT_ATH3K is not set -+# CONFIG_BT_BNEP is not set -+CONFIG_BT_BNEP_MC_FILTER=y -+CONFIG_BT_BNEP_PROTO_FILTER=y -+# CONFIG_BT_BREDR is not set -+# CONFIG_BT_CMTP is not set -+# CONFIG_BT_HCIBCM203X is not set -+# CONFIG_BT_HCIBFUSB is not set -+# CONFIG_BT_HCIBLUECARD is not set -+# CONFIG_BT_HCIBPA10X is not set -+# CONFIG_BT_HCIBT3C is not set -+# CONFIG_BT_HCIBTSDIO is not set -+# CONFIG_BT_HCIBTUART is not set -+# CONFIG_BT_HCIBTUSB is not set -+# CONFIG_BT_HCIBTUSB_RTL is not set -+# CONFIG_BT_HCIDTL1 is not set -+# CONFIG_BT_HCIUART is not set -+# CONFIG_BT_HCIUART_3WIRE is not set -+# CONFIG_BT_HCIUART_AG6XX is not set -+# CONFIG_BT_HCIUART_ATH3K is not set -+CONFIG_BT_HCIUART_BCSP=y -+CONFIG_BT_HCIUART_H4=y -+# CONFIG_BT_HCIUART_LL is not set -+# CONFIG_BT_HCIUART_MRVL is not set -+# CONFIG_BT_HCIUART_QCA is not set -+# CONFIG_BT_HCIVHCI is not set -+# CONFIG_BT_HIDP is not set -+# CONFIG_BT_HS is not set -+# CONFIG_BT_LE is not set -+# CONFIG_BT_LEDS is not set -+# CONFIG_BT_MRVL is not set -+# CONFIG_BT_RFCOMM is not set -+CONFIG_BT_RFCOMM_TTY=y -+# CONFIG_BT_SELFTEST is not set -+CONFIG_BUG=y -+# CONFIG_BUG_ON_DATA_CORRUPTION is not set -+CONFIG_BUILDTIME_EXTABLE_SORT=y -+# CONFIG_BUILD_BIN2C is not set -+# CONFIG_C2PORT is not set -+CONFIG_CACHE_L2X0_PMU=y -+# CONFIG_CADENCE_WATCHDOG is not set -+# CONFIG_CAIF is not set -+# CONFIG_CAN is not set -+# CONFIG_CAN_BCM is not set -+# CONFIG_CAN_DEBUG_DEVICES is not set -+# CONFIG_CAN_DEV is not set -+# CONFIG_CAN_GS_USB is not set -+# CONFIG_CAN_GW is not set -+# CONFIG_CAN_HI311X is not set -+# CONFIG_CAN_IFI_CANFD is not set -+# CONFIG_CAN_MCBA_USB is not set -+# CONFIG_CAN_M_CAN is not set -+# CONFIG_CAN_PEAK_PCIEFD is not set -+# CONFIG_CAN_RAW is not set -+# CONFIG_CAN_RCAR is not set -+# CONFIG_CAN_RCAR_CANFD is not set -+# CONFIG_CAN_SLCAN is not set -+# CONFIG_CAN_SUN4I is not set -+# CONFIG_CAN_VCAN is not set -+# CONFIG_CAN_VXCAN is not set -+# CONFIG_CAPI_AVM is not set -+# CONFIG_CAPI_EICON is not set -+# CONFIG_CAPI_TRACE is not set -+CONFIG_CARDBUS=y -+# CONFIG_CARDMAN_4000 is not set -+# CONFIG_CARDMAN_4040 is not set -+# CONFIG_CARL9170 is not set -+# CONFIG_CASSINI is not set -+# CONFIG_CAVIUM_CPT is not set -+# CONFIG_CAVIUM_ERRATUM_22375 is not set -+# CONFIG_CAVIUM_ERRATUM_23144 is not set -+# CONFIG_CAVIUM_ERRATUM_23154 is not set -+# CONFIG_CAVIUM_ERRATUM_27456 is not set -+# CONFIG_CAVIUM_ERRATUM_30115 is not set -+# CONFIG_CAVIUM_OCTEON_SOC is not set -+# CONFIG_CB710_CORE is not set -+# CONFIG_CC10001_ADC is not set -+# CONFIG_CCS811 is not set -+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+# CONFIG_CC_STACKPROTECTOR is not set -+CONFIG_CC_STACKPROTECTOR_NONE=y -+# CONFIG_CC_STACKPROTECTOR_REGULAR is not set -+# CONFIG_CC_STACKPROTECTOR_STRONG is not set -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_CEPH_FS is not set -+# CONFIG_CEPH_LIB is not set -+# CONFIG_CFG80211 is not set -+# CONFIG_CFG80211_CERTIFICATION_ONUS is not set -+# CONFIG_CFQ_GROUP_IOSCHED is not set -+# CONFIG_CGROUPS is not set -+# CONFIG_CHARGER_BQ2415X is not set -+# CONFIG_CHARGER_BQ24190 is not set -+# CONFIG_CHARGER_BQ24257 is not set -+# CONFIG_CHARGER_BQ24735 is not set -+# CONFIG_CHARGER_BQ25890 is not set -+# CONFIG_CHARGER_DETECTOR_MAX14656 is not set -+# CONFIG_CHARGER_GPIO is not set -+# CONFIG_CHARGER_ISP1704 is not set -+# CONFIG_CHARGER_LP8727 is not set -+# CONFIG_CHARGER_LTC3651 is not set -+# CONFIG_CHARGER_MANAGER is not set -+# CONFIG_CHARGER_MAX8903 is not set -+# CONFIG_CHARGER_RT9455 is not set -+# CONFIG_CHARGER_SBS is not set -+# CONFIG_CHARGER_SMB347 is not set -+# CONFIG_CHARGER_TWL4030 is not set -+# CONFIG_CHECKPOINT_RESTORE is not set -+# CONFIG_CHELSIO_T1 is not set -+# CONFIG_CHELSIO_T3 is not set -+# CONFIG_CHELSIO_T4 is not set -+# CONFIG_CHELSIO_T4VF is not set -+# CONFIG_CHROME_PLATFORMS is not set -+# CONFIG_CHR_DEV_OSST is not set -+# CONFIG_CHR_DEV_SCH is not set -+# CONFIG_CHR_DEV_SG is not set -+# CONFIG_CHR_DEV_ST is not set -+# CONFIG_CICADA_PHY is not set -+# CONFIG_CIFS is not set -+# CONFIG_CIFS_ACL is not set -+CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y -+# CONFIG_CIFS_DEBUG is not set -+# CONFIG_CIFS_DEBUG2 is not set -+# CONFIG_CIFS_FSCACHE is not set -+# CONFIG_CIFS_NFSD_EXPORT is not set -+CONFIG_CIFS_POSIX=y -+# CONFIG_CIFS_SMB2 is not set -+CONFIG_CIFS_STATS=y -+# CONFIG_CIFS_STATS2 is not set -+# CONFIG_CIFS_WEAK_PW_HASH is not set -+# CONFIG_CIFS_XATTR is not set -+# CONFIG_CIO_DAC is not set -+# CONFIG_CLEANCACHE is not set -+# CONFIG_CLKSRC_VERSATILE is not set -+# CONFIG_CLK_HSDK is not set -+# CONFIG_CLK_QORIQ is not set -+# CONFIG_CLOCK_THERMAL is not set -+CONFIG_CLS_U32_MARK=y -+# CONFIG_CLS_U32_PERF is not set -+# CONFIG_CM32181 is not set -+# CONFIG_CM3232 is not set -+# CONFIG_CM3323 is not set -+# CONFIG_CM3605 is not set -+# CONFIG_CM36651 is not set -+# CONFIG_CMA is not set -+CONFIG_CMDLINE="" -+# CONFIG_CMDLINE_BOOL is not set -+# CONFIG_CMDLINE_EXTEND is not set -+# CONFIG_CMDLINE_FORCE is not set -+# CONFIG_CMDLINE_FROM_BOOTLOADER is not set -+# CONFIG_CMDLINE_PARTITION is not set -+# CONFIG_CNIC is not set -+# CONFIG_CODA_FS is not set -+# CONFIG_CODE_PATCHING_SELFTEST is not set -+# CONFIG_COMEDI is not set -+# CONFIG_COMMON_CLK_CDCE706 is not set -+# CONFIG_COMMON_CLK_CDCE925 is not set -+# CONFIG_COMMON_CLK_CS2000_CP is not set -+# CONFIG_COMMON_CLK_IPROC is not set -+# CONFIG_COMMON_CLK_NXP is not set -+# CONFIG_COMMON_CLK_PIC32 is not set -+# CONFIG_COMMON_CLK_PWM is not set -+# CONFIG_COMMON_CLK_PXA is not set -+# CONFIG_COMMON_CLK_QCOM is not set -+# CONFIG_COMMON_CLK_SI514 is not set -+# CONFIG_COMMON_CLK_SI5351 is not set -+# CONFIG_COMMON_CLK_SI570 is not set -+# CONFIG_COMMON_CLK_VC5 is not set -+# CONFIG_COMMON_CLK_VERSATILE is not set -+# CONFIG_COMMON_CLK_XGENE is not set -+# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set -+CONFIG_COMPACTION=y -+# CONFIG_COMPAL_LAPTOP is not set -+# CONFIG_COMPAT is not set -+# CONFIG_COMPAT_BRK is not set -+# CONFIG_COMPILE_TEST is not set -+# CONFIG_CONFIGFS_FS is not set -+# CONFIG_CONNECTOR is not set -+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 -+CONFIG_CONSTRUCTORS=y -+# CONFIG_CONTEXT_SWITCH_TRACER is not set -+# CONFIG_COPS is not set -+# CONFIG_CORDIC is not set -+# CONFIG_COREDUMP is not set -+# CONFIG_CORESIGHT is not set -+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -+# CONFIG_CORTINA_PHY is not set -+# CONFIG_CPA_DEBUG is not set -+# CONFIG_CPU_DCACHE_DISABLE is not set -+# CONFIG_CPU_FREQ is not set -+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set -+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set -+# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set -+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -+# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set -+# CONFIG_CPU_FREQ_STAT_DETAILS is not set -+# CONFIG_CPU_IDLE is not set -+# CONFIG_CPU_IDLE_GOV_MENU is not set -+# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set -+# CONFIG_CPU_NO_EFFICIENT_FFS is not set -+CONFIG_CPU_SW_DOMAIN_PAN=y -+# CONFIG_CRAMFS is not set -+CONFIG_CRASHLOG=y -+# CONFIG_CRASH_DUMP is not set -+# CONFIG_CRC16 is not set -+CONFIG_CRC32=y -+# CONFIG_CRC32_BIT is not set -+CONFIG_CRC32_SARWATE=y -+# CONFIG_CRC32_SELFTEST is not set -+# CONFIG_CRC32_SLICEBY4 is not set -+# CONFIG_CRC32_SLICEBY8 is not set -+# CONFIG_CRC4 is not set -+# CONFIG_CRC7 is not set -+# CONFIG_CRC8 is not set -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC_ITU_T is not set -+# CONFIG_CRC_T10DIF is not set -+CONFIG_CROSS_COMPILE="" -+# CONFIG_CROSS_MEMORY_ATTACH is not set -+CONFIG_CRYPTO=y -+# CONFIG_CRYPTO_842 is not set -+# CONFIG_CRYPTO_AEAD is not set -+CONFIG_CRYPTO_AES=y -+# CONFIG_CRYPTO_AES_586 is not set -+# CONFIG_CRYPTO_AES_ARM is not set -+# CONFIG_CRYPTO_AES_ARM_BS is not set -+# CONFIG_CRYPTO_AES_NI_INTEL is not set -+# CONFIG_CRYPTO_AES_TI is not set -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_ALGAPI2=y -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+# CONFIG_CRYPTO_ANUBIS is not set -+# CONFIG_CRYPTO_ARC4 is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_BLKCIPHER2=y -+# CONFIG_CRYPTO_BLOWFISH is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_CAST5 is not set -+# CONFIG_CRYPTO_CAST6 is not set -+# CONFIG_CRYPTO_CBC is not set -+# CONFIG_CRYPTO_CCM is not set -+# CONFIG_CRYPTO_CHACHA20 is not set -+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set -+# CONFIG_CRYPTO_CMAC is not set -+# CONFIG_CRYPTO_CRC32 is not set -+# CONFIG_CRYPTO_CRC32C is not set -+# CONFIG_CRYPTO_CRC32C_INTEL is not set -+# CONFIG_CRYPTO_CRCT10DIF is not set -+# CONFIG_CRYPTO_CRYPTD is not set -+# CONFIG_CRYPTO_CTR is not set -+# CONFIG_CRYPTO_CTS is not set -+# CONFIG_CRYPTO_DEFLATE is not set -+# CONFIG_CRYPTO_DES is not set -+# CONFIG_CRYPTO_DEV_ATMEL_AES is not set -+# CONFIG_CRYPTO_DEV_ATMEL_AUTHENC is not set -+# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set -+# CONFIG_CRYPTO_DEV_ATMEL_SHA is not set -+# CONFIG_CRYPTO_DEV_ATMEL_TDES is not set -+# CONFIG_CRYPTO_DEV_CAVIUM_ZIP is not set -+# CONFIG_CRYPTO_DEV_CCP is not set -+# CONFIG_CRYPTO_DEV_CCREE is not set -+# CONFIG_CRYPTO_DEV_FSL_CAAM is not set -+# CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC is not set -+# CONFIG_CRYPTO_DEV_HIFN_795X is not set -+# CONFIG_CRYPTO_DEV_IMGTEC_HASH is not set -+# CONFIG_CRYPTO_DEV_MARVELL_CESA is not set -+# CONFIG_CRYPTO_DEV_MV_CESA is not set -+# CONFIG_CRYPTO_DEV_MXC_SCC is not set -+# CONFIG_CRYPTO_DEV_MXS_DCP is not set -+# CONFIG_CRYPTO_DEV_NITROX_CNN55XX is not set -+# CONFIG_CRYPTO_DEV_QAT_C3XXX is not set -+# CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set -+# CONFIG_CRYPTO_DEV_QAT_C62X is not set -+# CONFIG_CRYPTO_DEV_QAT_C62XVF is not set -+# CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set -+# CONFIG_CRYPTO_DEV_QAT_DH895xCCVF is not set -+# CONFIG_CRYPTO_DEV_QCE is not set -+# CONFIG_CRYPTO_DEV_S5P is not set -+# CONFIG_CRYPTO_DEV_SAFEXCEL is not set -+# CONFIG_CRYPTO_DEV_SAHARA is not set -+# CONFIG_CRYPTO_DEV_TALITOS is not set -+# CONFIG_CRYPTO_DEV_VIRTIO is not set -+# CONFIG_CRYPTO_DH is not set -+# CONFIG_CRYPTO_DRBG_CTR is not set -+# CONFIG_CRYPTO_DRBG_HASH is not set -+# CONFIG_CRYPTO_DRBG_MENU is not set -+# CONFIG_CRYPTO_ECB is not set -+# CONFIG_CRYPTO_ECDH is not set -+# CONFIG_CRYPTO_ECHAINIV is not set -+# CONFIG_CRYPTO_FCRYPT is not set -+# CONFIG_CRYPTO_FIPS is not set -+# CONFIG_CRYPTO_GCM is not set -+# CONFIG_CRYPTO_GF128MUL is not set -+# CONFIG_CRYPTO_GHASH is not set -+# CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set -+# CONFIG_CRYPTO_HASH is not set -+# CONFIG_CRYPTO_HMAC is not set -+# CONFIG_CRYPTO_HW is not set -+# CONFIG_CRYPTO_JITTERENTROPY is not set -+# CONFIG_CRYPTO_KEYWRAP is not set -+# CONFIG_CRYPTO_KHAZAD is not set -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_LZ4 is not set -+# CONFIG_CRYPTO_LZ4HC is not set -+# CONFIG_CRYPTO_LZO is not set -+# CONFIG_CRYPTO_MANAGER is not set -+# CONFIG_CRYPTO_MANAGER2 is not set -+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -+# CONFIG_CRYPTO_MCRYPTD is not set -+# CONFIG_CRYPTO_MD4 is not set -+# CONFIG_CRYPTO_MD5 is not set -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_NULL is not set -+# CONFIG_CRYPTO_PCBC is not set -+# CONFIG_CRYPTO_PCOMP is not set -+# CONFIG_CRYPTO_PCOMP2 is not set -+CONFIG_CRYPTO_PCRYPT=y -+# CONFIG_CRYPTO_POLY1305 is not set -+# CONFIG_CRYPTO_RMD128 is not set -+# CONFIG_CRYPTO_RMD160 is not set -+# CONFIG_CRYPTO_RMD256 is not set -+# CONFIG_CRYPTO_RMD320 is not set -+# CONFIG_CRYPTO_RNG is not set -+# CONFIG_CRYPTO_RSA is not set -+# CONFIG_CRYPTO_SALSA20 is not set -+# CONFIG_CRYPTO_SALSA20_586 is not set -+# CONFIG_CRYPTO_SEED is not set -+# CONFIG_CRYPTO_SEQIV is not set -+# CONFIG_CRYPTO_SERPENT is not set -+# CONFIG_CRYPTO_SHA1 is not set -+# CONFIG_CRYPTO_SHA1_ARM is not set -+# CONFIG_CRYPTO_SHA256 is not set -+# CONFIG_CRYPTO_SHA3 is not set -+# CONFIG_CRYPTO_SHA512 is not set -+# CONFIG_CRYPTO_TEA is not set -+# CONFIG_CRYPTO_TEST is not set -+# CONFIG_CRYPTO_TGR192 is not set -+# CONFIG_CRYPTO_TWOFISH is not set -+# CONFIG_CRYPTO_TWOFISH_586 is not set -+# CONFIG_CRYPTO_TWOFISH_COMMON is not set -+# CONFIG_CRYPTO_USER is not set -+# CONFIG_CRYPTO_USER_API_AEAD is not set -+# CONFIG_CRYPTO_USER_API_HASH is not set -+# CONFIG_CRYPTO_USER_API_RNG is not set -+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -+# CONFIG_CRYPTO_VMAC is not set -+# CONFIG_CRYPTO_WP512 is not set -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_ZLIB is not set -+# CONFIG_CS5535_MFGPT is not set -+# CONFIG_CS89x0 is not set -+# CONFIG_CUSE is not set -+# CONFIG_CW1200 is not set -+# CONFIG_CXL_AFU_DRIVER_OPS is not set -+# CONFIG_CXL_BASE is not set -+# CONFIG_CXL_EEH is not set -+# CONFIG_CXL_KERNEL_API is not set -+# CONFIG_CXL_LIB is not set -+# CONFIG_CYPRESS_FIRMWARE is not set -+# CONFIG_DA280 is not set -+# CONFIG_DA311 is not set -+# CONFIG_DAVICOM_PHY is not set -+# CONFIG_DAX is not set -+# CONFIG_DCB is not set -+# CONFIG_DDR is not set -+# CONFIG_DEBUG_ALIGN_RODATA is not set -+# CONFIG_DEBUG_ATOMIC_SLEEP is not set -+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -+# CONFIG_DEBUG_BUGVERBOSE is not set -+# CONFIG_DEBUG_CREDENTIALS is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_EFI is not set -+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -+CONFIG_DEBUG_FS=y -+# CONFIG_DEBUG_GPIO is not set -+# CONFIG_DEBUG_HIGHMEM is not set -+# CONFIG_DEBUG_ICEDCC is not set -+# CONFIG_DEBUG_INFO is not set -+# CONFIG_DEBUG_INFO_DWARF4 is not set -+CONFIG_DEBUG_INFO_REDUCED=y -+# CONFIG_DEBUG_INFO_SPLIT is not set -+CONFIG_DEBUG_KERNEL=y -+# CONFIG_DEBUG_KMEMLEAK is not set -+# CONFIG_DEBUG_KOBJECT is not set -+# CONFIG_DEBUG_KOBJECT_RELEASE is not set -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_LL is not set -+# CONFIG_DEBUG_LL_UART_8250 is not set -+# CONFIG_DEBUG_LL_UART_PL01X is not set -+# CONFIG_DEBUG_LOCKDEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_DEBUG_LOCK_ALLOC is not set -+# CONFIG_DEBUG_MEMORY_INIT is not set -+# CONFIG_DEBUG_MUTEXES is not set -+# CONFIG_DEBUG_NOTIFIERS is not set -+# CONFIG_DEBUG_NX_TEST is not set -+# CONFIG_DEBUG_OBJECTS is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_DEBUG_PAGE_REF is not set -+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set -+# CONFIG_DEBUG_PER_CPU_MAPS is not set -+# CONFIG_DEBUG_PINCTRL is not set -+# CONFIG_DEBUG_PI_LIST is not set -+# CONFIG_DEBUG_PREEMPT is not set -+# CONFIG_DEBUG_RODATA_TEST is not set -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_DEBUG_SECTION_MISMATCH is not set -+# CONFIG_DEBUG_SEMIHOSTING is not set -+# CONFIG_DEBUG_SG is not set -+# CONFIG_DEBUG_SHIRQ is not set -+# CONFIG_DEBUG_SLAB is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+# CONFIG_DEBUG_STACKOVERFLOW is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set -+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set -+# CONFIG_DEBUG_TIMEKEEPING is not set -+# CONFIG_DEBUG_UART_8250_PALMCHIP is not set -+# CONFIG_DEBUG_UART_BCM63XX is not set -+# CONFIG_DEBUG_VIRTUAL is not set -+# CONFIG_DEBUG_VM is not set -+# CONFIG_DEBUG_VM_PGFLAGS is not set -+# CONFIG_DEBUG_VM_RB is not set -+# CONFIG_DEBUG_VM_VMACACHE is not set -+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set -+# CONFIG_DEBUG_WX is not set -+# CONFIG_DEBUG_ZBOOT is not set -+# CONFIG_DECNET is not set -+CONFIG_DEFAULT_CUBIC=y -+CONFIG_DEFAULT_DEADLINE=y -+CONFIG_DEFAULT_HOSTNAME="(none)" -+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 -+CONFIG_DEFAULT_IOSCHED="deadline" -+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -+# CONFIG_DEFAULT_NOOP is not set -+# CONFIG_DEFAULT_RENO is not set -+CONFIG_DEFAULT_SECURITY="" -+CONFIG_DEFAULT_SECURITY_DAC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+# CONFIG_DELL_LAPTOP is not set -+# CONFIG_DELL_RBTN is not set -+# CONFIG_DELL_SMO8800 is not set -+# CONFIG_DEPRECATED_PARAM_STRUCT is not set -+# CONFIG_DETECT_HUNG_TASK is not set -+# CONFIG_DEVKMEM is not set -+# CONFIG_DEVMEM is not set -+CONFIG_DEVPORT=y -+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -+# CONFIG_DEVTMPFS is not set -+# CONFIG_DEVTMPFS_MOUNT is not set -+# CONFIG_DEV_DAX is not set -+# CONFIG_DGAP is not set -+# CONFIG_DGNC is not set -+# CONFIG_DHT11 is not set -+# CONFIG_DISCONTIGMEM_MANUAL is not set -+# CONFIG_DISPLAY_CONNECTOR_ANALOG_TV is not set -+# CONFIG_DISPLAY_CONNECTOR_DVI is not set -+# CONFIG_DISPLAY_CONNECTOR_HDMI is not set -+# CONFIG_DISPLAY_ENCODER_TFP410 is not set -+# CONFIG_DISPLAY_ENCODER_TPD12S015 is not set -+# CONFIG_DISPLAY_PANEL_DPI is not set -+# CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02 is not set -+# CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1 is not set -+# CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1 is not set -+# CONFIG_DL2K is not set -+# CONFIG_DLM is not set -+# CONFIG_DM9000 is not set -+# CONFIG_DMADEVICES is not set -+# CONFIG_DMADEVICES_DEBUG is not set -+# CONFIG_DMARD06 is not set -+# CONFIG_DMARD09 is not set -+# CONFIG_DMARD10 is not set -+# CONFIG_DMASCC is not set -+# CONFIG_DMATEST is not set -+# CONFIG_DMA_API_DEBUG is not set -+# CONFIG_DMA_ENGINE is not set -+# CONFIG_DMA_FENCE_TRACE is not set -+# CONFIG_DMA_JZ4780 is not set -+# CONFIG_DMA_NOOP_OPS is not set -+# CONFIG_DMA_SHARED_BUFFER is not set -+# CONFIG_DMA_VIRT_OPS is not set -+# CONFIG_DM_CACHE is not set -+# CONFIG_DM_DEBUG is not set -+# CONFIG_DM_DELAY is not set -+# CONFIG_DM_ERA is not set -+# CONFIG_DM_FLAKEY is not set -+# CONFIG_DM_INTEGRITY is not set -+# CONFIG_DM_LOG_USERSPACE is not set -+# CONFIG_DM_LOG_WRITES is not set -+# CONFIG_DM_MQ_DEFAULT is not set -+# CONFIG_DM_MULTIPATH is not set -+# CONFIG_DM_RAID is not set -+# CONFIG_DM_SWITCH is not set -+# CONFIG_DM_THIN_PROVISIONING is not set -+# CONFIG_DM_UEVENT is not set -+# CONFIG_DM_VERITY is not set -+# CONFIG_DM_ZERO is not set -+# CONFIG_DNET is not set -+# CONFIG_DNOTIFY is not set -+# CONFIG_DNS_RESOLVER is not set -+CONFIG_DOUBLEFAULT=y -+# CONFIG_DP83848_PHY is not set -+# CONFIG_DP83867_PHY is not set -+# CONFIG_DPOT_DAC is not set -+CONFIG_DQL=y -+# CONFIG_DRAGONRISE_FF is not set -+# CONFIG_DRM is not set -+# CONFIG_DRM_AMDGPU is not set -+# CONFIG_DRM_AMDGPU_CIK is not set -+# CONFIG_DRM_AMDGPU_GART_DEBUGFS is not set -+# CONFIG_DRM_AMDGPU_SI is not set -+# CONFIG_DRM_AMDGPU_USERPTR is not set -+# CONFIG_DRM_AMD_ACP is not set -+# CONFIG_DRM_ANALOGIX_ANX78XX is not set -+# CONFIG_DRM_ARCPGU is not set -+# CONFIG_DRM_ARMADA is not set -+# CONFIG_DRM_AST is not set -+# CONFIG_DRM_BOCHS is not set -+# CONFIG_DRM_CIRRUS_QEMU is not set -+# CONFIG_DRM_DEBUG_MM is not set -+# CONFIG_DRM_DEBUG_MM_SELFTEST is not set -+# CONFIG_DRM_DP_AUX_CHARDEV is not set -+# CONFIG_DRM_DUMB_VGA_DAC is not set -+# CONFIG_DRM_DW_HDMI_CEC is not set -+# CONFIG_DRM_ETNAVIV is not set -+# CONFIG_DRM_EXYNOS is not set -+# CONFIG_DRM_FBDEV_EMULATION is not set -+# CONFIG_DRM_FSL_DCU is not set -+# CONFIG_DRM_GMA500 is not set -+# CONFIG_DRM_HDLCD is not set -+# CONFIG_DRM_HISI_HIBMC is not set -+# CONFIG_DRM_HISI_KIRIN is not set -+# CONFIG_DRM_I2C_ADV7511 is not set -+# CONFIG_DRM_I2C_CH7006 is not set -+# CONFIG_DRM_I2C_NXP_TDA998X is not set -+# CONFIG_DRM_I2C_SIL164 is not set -+# CONFIG_DRM_I915 is not set -+# CONFIG_DRM_LEGACY is not set -+# CONFIG_DRM_LIB_RANDOM is not set -+# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set -+# CONFIG_DRM_LVDS_ENCODER is not set -+# CONFIG_DRM_MALI_DISPLAY is not set -+# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set -+# CONFIG_DRM_MGAG200 is not set -+# CONFIG_DRM_MXSFB is not set -+# CONFIG_DRM_NOUVEAU is not set -+# CONFIG_DRM_NXP_PTN3460 is not set -+# CONFIG_DRM_OMAP is not set -+# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set -+# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set -+# CONFIG_DRM_PANEL_LG_LG4573 is not set -+# CONFIG_DRM_PANEL_LVDS is not set -+# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set -+# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set -+# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set -+# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set -+# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set -+# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set -+# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set -+# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set -+# CONFIG_DRM_PARADE_PS8622 is not set -+# CONFIG_DRM_PL111 is not set -+# CONFIG_DRM_QXL is not set -+# CONFIG_DRM_RADEON is not set -+# CONFIG_DRM_RADEON_USERPTR is not set -+# CONFIG_DRM_RCAR_DW_HDMI is not set -+# CONFIG_DRM_SII902X is not set -+# CONFIG_DRM_SIL_SII8620 is not set -+# CONFIG_DRM_STI is not set -+# CONFIG_DRM_STM is not set -+# CONFIG_DRM_SUN4I is not set -+# CONFIG_DRM_TILCDC is not set -+# CONFIG_DRM_TINYDRM is not set -+# CONFIG_DRM_TI_TFP410 is not set -+# CONFIG_DRM_TOSHIBA_TC358767 is not set -+# CONFIG_DRM_UDL is not set -+# CONFIG_DRM_VBOXVIDEO is not set -+# CONFIG_DRM_VGEM is not set -+# CONFIG_DRM_VIRTIO_GPU is not set -+# CONFIG_DRM_VMWGFX is not set -+# CONFIG_DS1682 is not set -+# CONFIG_DS1803 is not set -+# CONFIG_DST_CACHE is not set -+# CONFIG_DTLK is not set -+# CONFIG_DUMMY is not set -+CONFIG_DUMMY_CONSOLE_COLUMNS=80 -+CONFIG_DUMMY_CONSOLE_ROWS=25 -+# CONFIG_DUMMY_IRQ is not set -+# CONFIG_DVB_AU8522_V4L is not set -+# CONFIG_DVB_CORE is not set -+# CONFIG_DVB_DUMMY_FE is not set -+# CONFIG_DVB_TUNER_DIB0070 is not set -+# CONFIG_DVB_TUNER_DIB0090 is not set -+# CONFIG_DWC_XLGMAC is not set -+# CONFIG_DWMAC_IPQ806X is not set -+# CONFIG_DWMAC_LPC18XX is not set -+# CONFIG_DWMAC_MESON is not set -+# CONFIG_DWMAC_ROCKCHIP is not set -+# CONFIG_DWMAC_SOCFPGA is not set -+# CONFIG_DWMAC_STI is not set -+# CONFIG_DW_DMAC is not set -+# CONFIG_DW_DMAC_PCI is not set -+# CONFIG_DW_WATCHDOG is not set -+# CONFIG_DYNAMIC_DEBUG is not set -+# CONFIG_E100 is not set -+# CONFIG_E1000 is not set -+# CONFIG_E1000E is not set -+# CONFIG_E1000E_HWTS is not set -+# CONFIG_EARLY_PRINTK_8250 is not set -+# CONFIG_EARLY_PRINTK_USB_XDBC is not set -+# CONFIG_ECHO is not set -+# CONFIG_ECRYPT_FS is not set -+# CONFIG_EDAC is not set -+# CONFIG_EEEPC_LAPTOP is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_EEPROM_93XX46 is not set -+# CONFIG_EEPROM_AT24 is not set -+# CONFIG_EEPROM_AT25 is not set -+# CONFIG_EEPROM_DIGSY_MTC_CFG is not set -+# CONFIG_EEPROM_IDT_89HPESX is not set -+# CONFIG_EEPROM_LEGACY is not set -+# CONFIG_EEPROM_MAX6875 is not set -+# CONFIG_EFI is not set -+CONFIG_EFI_PARTITION=y -+# CONFIG_EFS_FS is not set -+CONFIG_ELFCORE=y -+# CONFIG_ELF_CORE is not set -+# CONFIG_EMAC_ROCKCHIP is not set -+CONFIG_EMBEDDED=y -+# CONFIG_EM_TIMER_STI is not set -+# CONFIG_ENABLE_MUST_CHECK is not set -+CONFIG_ENABLE_WARN_DEPRECATED=y -+# CONFIG_ENA_ETHERNET is not set -+# CONFIG_ENC28J60 is not set -+# CONFIG_ENCLOSURE_SERVICES is not set -+# CONFIG_ENCRYPTED_KEYS is not set -+# CONFIG_ENCX24J600 is not set -+# CONFIG_ENIC is not set -+# CONFIG_ENVELOPE_DETECTOR is not set -+# CONFIG_EPAPR_PARAVIRT is not set -+# CONFIG_EPIC100 is not set -+CONFIG_EPOLL=y -+# CONFIG_EQUALIZER is not set -+# CONFIG_ET131X is not set -+CONFIG_ETHERNET=y -+# CONFIG_ETHOC is not set -+CONFIG_EVENTFD=y -+CONFIG_EXPERT=y -+CONFIG_EXPORTFS=y -+# CONFIG_EXPORTFS_BLOCK_OPS is not set -+# CONFIG_EXT2_FS is not set -+# CONFIG_EXT2_FS_XATTR is not set -+# CONFIG_EXT3_FS is not set -+# CONFIG_EXT4_DEBUG is not set -+# CONFIG_EXT4_ENCRYPTION is not set -+# CONFIG_EXT4_FS is not set -+# CONFIG_EXT4_FS_POSIX_ACL is not set -+# CONFIG_EXT4_FS_SECURITY is not set -+CONFIG_EXT4_USE_FOR_EXT2=y -+# CONFIG_EXTCON is not set -+# CONFIG_EXTCON_ADC_JACK is not set -+# CONFIG_EXTCON_AXP288 is not set -+# CONFIG_EXTCON_GPIO is not set -+# CONFIG_EXTCON_INTEL_INT3496 is not set -+# CONFIG_EXTCON_MAX3355 is not set -+# CONFIG_EXTCON_QCOM_SPMI_MISC is not set -+# CONFIG_EXTCON_RT8973A is not set -+# CONFIG_EXTCON_SM5502 is not set -+# CONFIG_EXTCON_USB_GPIO is not set -+CONFIG_EXTRA_FIRMWARE="" -+CONFIG_EXTRA_TARGETS="" -+# CONFIG_EXYNOS_ADC is not set -+# CONFIG_EXYNOS_VIDEO is not set -+# CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set -+# CONFIG_EZX_PCAP is not set -+# CONFIG_F2FS_FAULT_INJECTION is not set -+# CONFIG_F2FS_FS is not set -+# CONFIG_F2FS_FS_ENCRYPTION is not set -+# CONFIG_F2FS_FS_POSIX_ACL is not set -+# CONFIG_F2FS_IO_TRACE is not set -+# CONFIG_FAIR_GROUP_SCHED is not set -+# CONFIG_FANOTIFY is not set -+CONFIG_FAT_DEFAULT_CODEPAGE=437 -+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -+# CONFIG_FAT_DEFAULT_UTF8 is not set -+# CONFIG_FAT_FS is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_FB is not set -+# CONFIG_FB_3DFX is not set -+# CONFIG_FB_ARC is not set -+# CONFIG_FB_ARK is not set -+# CONFIG_FB_ARMCLCD is not set -+# CONFIG_FB_ASILIANT is not set -+# CONFIG_FB_ATY is not set -+# CONFIG_FB_ATY128 is not set -+# CONFIG_FB_AUO_K190X is not set -+# CONFIG_FB_BACKLIGHT is not set -+# CONFIG_FB_BIG_ENDIAN is not set -+# CONFIG_FB_BOOT_VESA_SUPPORT is not set -+# CONFIG_FB_BOTH_ENDIAN is not set -+# CONFIG_FB_BROADSHEET is not set -+# CONFIG_FB_CARMINE is not set -+# CONFIG_FB_CFB_COPYAREA is not set -+# CONFIG_FB_CFB_FILLRECT is not set -+# CONFIG_FB_CFB_IMAGEBLIT is not set -+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -+# CONFIG_FB_CIRRUS is not set -+# CONFIG_FB_CYBER2000 is not set -+# CONFIG_FB_DA8XX is not set -+# CONFIG_FB_DDC is not set -+# CONFIG_FB_FLEX is not set -+# CONFIG_FB_FOREIGN_ENDIAN is not set -+# CONFIG_FB_GEODE is not set -+# CONFIG_FB_GOLDFISH is not set -+# CONFIG_FB_HGA is not set -+# CONFIG_FB_I740 is not set -+# CONFIG_FB_IBM_GXT4500 is not set -+# CONFIG_FB_IMSTT is not set -+# CONFIG_FB_IMX is not set -+# CONFIG_FB_KYRO is not set -+# CONFIG_FB_LE80578 is not set -+# CONFIG_FB_LITTLE_ENDIAN is not set -+# CONFIG_FB_MACMODES is not set -+# CONFIG_FB_MATROX is not set -+# CONFIG_FB_MB862XX is not set -+# CONFIG_FB_METRONOME is not set -+# CONFIG_FB_MODE_HELPERS is not set -+# CONFIG_FB_MXS is not set -+# CONFIG_FB_N411 is not set -+# CONFIG_FB_NEOMAGIC is not set -+CONFIG_FB_NOTIFY=y -+# CONFIG_FB_NVIDIA is not set -+# CONFIG_FB_OF is not set -+# CONFIG_FB_OMAP2 is not set -+# CONFIG_FB_OPENCORES is not set -+# CONFIG_FB_PM2 is not set -+# CONFIG_FB_PM3 is not set -+# CONFIG_FB_PS3 is not set -+# CONFIG_FB_PXA is not set -+# CONFIG_FB_RADEON is not set -+# CONFIG_FB_RIVA is not set -+# CONFIG_FB_S1D13XXX is not set -+# CONFIG_FB_S3 is not set -+# CONFIG_FB_SAVAGE is not set -+# CONFIG_FB_SIMPLE is not set -+# CONFIG_FB_SIS is not set -+# CONFIG_FB_SM712 is not set -+# CONFIG_FB_SM750 is not set -+# CONFIG_FB_SMSCUFX is not set -+# CONFIG_FB_SSD1307 is not set -+# CONFIG_FB_SVGALIB is not set -+# CONFIG_FB_SYS_COPYAREA is not set -+# CONFIG_FB_SYS_FILLRECT is not set -+# CONFIG_FB_SYS_FOPS is not set -+# CONFIG_FB_SYS_IMAGEBLIT is not set -+# CONFIG_FB_TFT is not set -+# CONFIG_FB_TFT_AGM1264K_FL is not set -+# CONFIG_FB_TFT_BD663474 is not set -+# CONFIG_FB_TFT_FBTFT_DEVICE is not set -+# CONFIG_FB_TFT_HX8340BN is not set -+# CONFIG_FB_TFT_HX8347D is not set -+# CONFIG_FB_TFT_HX8353D is not set -+# CONFIG_FB_TFT_HX8357D is not set -+# CONFIG_FB_TFT_ILI9163 is not set -+# CONFIG_FB_TFT_ILI9320 is not set -+# CONFIG_FB_TFT_ILI9325 is not set -+# CONFIG_FB_TFT_ILI9340 is not set -+# CONFIG_FB_TFT_ILI9341 is not set -+# CONFIG_FB_TFT_ILI9481 is not set -+# CONFIG_FB_TFT_ILI9486 is not set -+# CONFIG_FB_TFT_PCD8544 is not set -+# CONFIG_FB_TFT_RA8875 is not set -+# CONFIG_FB_TFT_S6D02A1 is not set -+# CONFIG_FB_TFT_S6D1121 is not set -+# CONFIG_FB_TFT_SH1106 is not set -+# CONFIG_FB_TFT_SSD1289 is not set -+# CONFIG_FB_TFT_SSD1305 is not set -+# CONFIG_FB_TFT_SSD1306 is not set -+# CONFIG_FB_TFT_SSD1325 is not set -+# CONFIG_FB_TFT_SSD1331 is not set -+# CONFIG_FB_TFT_SSD1351 is not set -+# CONFIG_FB_TFT_ST7735R is not set -+# CONFIG_FB_TFT_ST7789V is not set -+# CONFIG_FB_TFT_TINYLCD is not set -+# CONFIG_FB_TFT_TLS8204 is not set -+# CONFIG_FB_TFT_UC1611 is not set -+# CONFIG_FB_TFT_UC1701 is not set -+# CONFIG_FB_TFT_UPD161704 is not set -+# CONFIG_FB_TFT_WATTEROTT is not set -+# CONFIG_FB_TILEBLITTING is not set -+# CONFIG_FB_TMIO is not set -+# CONFIG_FB_TRIDENT is not set -+# CONFIG_FB_UDL is not set -+# CONFIG_FB_UVESA is not set -+# CONFIG_FB_VGA16 is not set -+# CONFIG_FB_VIA is not set -+# CONFIG_FB_VIRTUAL is not set -+# CONFIG_FB_VOODOO1 is not set -+# CONFIG_FB_VT8623 is not set -+# CONFIG_FB_XGI is not set -+# CONFIG_FCOE is not set -+# CONFIG_FCOE_FNIC is not set -+# CONFIG_FDDI is not set -+# CONFIG_FEALNX is not set -+# CONFIG_FENCE_TRACE is not set -+# CONFIG_FHANDLE is not set -+CONFIG_FIB_RULES=y -+CONFIG_FILE_LOCKING=y -+# CONFIG_FIREWIRE is not set -+# CONFIG_FIREWIRE_NOSY is not set -+# CONFIG_FIREWIRE_SERIAL is not set -+# CONFIG_FIRMWARE_EDID is not set -+# CONFIG_FIRMWARE_IN_KERNEL is not set -+# CONFIG_FIRMWARE_MEMMAP is not set -+# CONFIG_FIXED_PHY is not set -+CONFIG_FLATMEM=y -+CONFIG_FLATMEM_MANUAL=y -+CONFIG_FLAT_NODE_MEM_MAP=y -+# CONFIG_FM10K is not set -+# CONFIG_FMC is not set -+# CONFIG_FORCEDETH is not set -+CONFIG_FORCE_MAX_ZONEORDER=11 -+CONFIG_FORTIFY_SOURCE=y -+# CONFIG_FPGA is not set -+# CONFIG_FRAMEBUFFER_CONSOLE is not set -+# CONFIG_FRAME_POINTER is not set -+CONFIG_FRAME_WARN=1024 -+# CONFIG_FREEZER is not set -+# CONFIG_FRONTSWAP is not set -+# CONFIG_FSCACHE is not set -+# CONFIG_FSI is not set -+# CONFIG_FSL_EDMA is not set -+# CONFIG_FSL_ERRATUM_A008585 is not set -+# CONFIG_FSL_MC_BUS is not set -+# CONFIG_FSL_PQ_MDIO is not set -+# CONFIG_FSL_XGMAC_MDIO is not set -+CONFIG_FSNOTIFY=y -+# CONFIG_FS_DAX is not set -+# CONFIG_FS_ENCRYPTION is not set -+# CONFIG_FS_POSIX_ACL is not set -+# CONFIG_FTGMAC100 is not set -+# CONFIG_FTL is not set -+# CONFIG_FTMAC100 is not set -+# CONFIG_FTRACE is not set -+# CONFIG_FTRACE_STARTUP_TEST is not set -+# CONFIG_FTR_FIXUP_SELFTEST is not set -+# CONFIG_FUJITSU_ES is not set -+# CONFIG_FUJITSU_LAPTOP is not set -+# CONFIG_FUJITSU_TABLET is not set -+# CONFIG_FUNCTION_TRACER is not set -+# CONFIG_FUSE_FS is not set -+# CONFIG_FUSION is not set -+# CONFIG_FUSION_FC is not set -+# CONFIG_FUSION_SAS is not set -+# CONFIG_FUSION_SPI is not set -+CONFIG_FUTEX=y -+CONFIG_FUTEX_PI=y -+# CONFIG_FW_CFG_SYSFS is not set -+CONFIG_FW_LOADER=y -+CONFIG_FW_LOADER_USER_HELPER=y -+CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y -+CONFIG_GACT_PROB=y -+# CONFIG_GADGET_UAC1 is not set -+# CONFIG_GAMEPORT is not set -+# CONFIG_GATEWORKS_GW16083 is not set -+# CONFIG_GCC_PLUGINS is not set -+# CONFIG_GCC_PLUGIN_CYC_COMPLEXITY is not set -+# CONFIG_GCC_PLUGIN_LATENT_ENTROPY is not set -+# CONFIG_GCC_PLUGIN_RANDSTRUCT is not set -+# CONFIG_GCC_PLUGIN_STRUCTLEAK is not set -+# CONFIG_GCOV is not set -+# CONFIG_GCOV_KERNEL is not set -+# CONFIG_GDB_SCRIPTS is not set -+# CONFIG_GENERIC_ADC_BATTERY is not set -+# CONFIG_GENERIC_ADC_THERMAL is not set -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+# CONFIG_GENERIC_CPU_DEVICES is not set -+CONFIG_GENERIC_HWEIGHT=y -+# CONFIG_GENERIC_IRQ_DEBUGFS is not set -+CONFIG_GENERIC_IRQ_PROBE=y -+CONFIG_GENERIC_NET_UTILS=y -+# CONFIG_GENERIC_PHY is not set -+# CONFIG_GENEVE is not set -+# CONFIG_GENWQE is not set -+# CONFIG_GFS2_FS is not set -+# CONFIG_GIGASET_CAPI is not set -+# CONFIG_GIGASET_DEBUG is not set -+# CONFIG_GIGASET_DUMMYLL is not set -+# CONFIG_GLOB_SELFTEST is not set -+# CONFIG_GOLDFISH is not set -+# CONFIG_GOOGLE_FIRMWARE is not set -+# CONFIG_GP2AP020A00F is not set -+# CONFIG_GPIOLIB is not set -+# CONFIG_GPIO_74X164 is not set -+# CONFIG_GPIO_74XX_MMIO is not set -+# CONFIG_GPIO_ADNP is not set -+# CONFIG_GPIO_ADP5588 is not set -+# CONFIG_GPIO_ALTERA is not set -+# CONFIG_GPIO_AMD8111 is not set -+# CONFIG_GPIO_AMDPT is not set -+# CONFIG_GPIO_BCM_KONA is not set -+# CONFIG_GPIO_BT8XX is not set -+# CONFIG_GPIO_CS5535 is not set -+# CONFIG_GPIO_DWAPB is not set -+# CONFIG_GPIO_EM is not set -+# CONFIG_GPIO_EXAR is not set -+# CONFIG_GPIO_F7188X is not set -+# CONFIG_GPIO_FTGPIO010 is not set -+# CONFIG_GPIO_GENERIC_PLATFORM is not set -+# CONFIG_GPIO_GPIO_MM is not set -+# CONFIG_GPIO_GRGPIO is not set -+# CONFIG_GPIO_ICH is not set -+# CONFIG_GPIO_IT87 is not set -+# CONFIG_GPIO_LYNXPOINT is not set -+# CONFIG_GPIO_MAX7300 is not set -+# CONFIG_GPIO_MAX7301 is not set -+# CONFIG_GPIO_MAX732X is not set -+# CONFIG_GPIO_MC33880 is not set -+# CONFIG_GPIO_MCP23S08 is not set -+# CONFIG_GPIO_ML_IOH is not set -+# CONFIG_GPIO_MOCKUP is not set -+# CONFIG_GPIO_MPC8XXX is not set -+# CONFIG_GPIO_PCA953X is not set -+# CONFIG_GPIO_PCF857X is not set -+# CONFIG_GPIO_PCH is not set -+# CONFIG_GPIO_PCI_IDIO_16 is not set -+# CONFIG_GPIO_PISOSR is not set -+# CONFIG_GPIO_PL061 is not set -+# CONFIG_GPIO_RCAR is not set -+# CONFIG_GPIO_RDC321X is not set -+# CONFIG_GPIO_SCH is not set -+# CONFIG_GPIO_SCH311X is not set -+# CONFIG_GPIO_SX150X is not set -+# CONFIG_GPIO_SYSCON is not set -+CONFIG_GPIO_SYSFS=y -+# CONFIG_GPIO_TPIC2810 is not set -+# CONFIG_GPIO_TS4900 is not set -+# CONFIG_GPIO_TS5500 is not set -+# CONFIG_GPIO_VX855 is not set -+# CONFIG_GPIO_WATCHDOG is not set -+# CONFIG_GPIO_WS16C48 is not set -+# CONFIG_GPIO_XGENE is not set -+# CONFIG_GPIO_XILINX is not set -+# CONFIG_GPIO_XRA1403 is not set -+# CONFIG_GPIO_ZEVIO is not set -+# CONFIG_GPIO_ZX is not set -+# CONFIG_GREENASIA_FF is not set -+# CONFIG_GREYBUS is not set -+# CONFIG_GS_FPGABOOT is not set -+# CONFIG_GTP is not set -+# CONFIG_HAMACHI is not set -+# CONFIG_HAMRADIO is not set -+# CONFIG_HAPPYMEAL is not set -+CONFIG_HARDENED_USERCOPY=y -+# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set -+# CONFIG_HARDLOCKUP_DETECTOR is not set -+# CONFIG_HAVE_AOUT is not set -+CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y -+# CONFIG_HAVE_ARCH_HASH is not set -+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -+# CONFIG_HAVE_ARCH_VMAP_STACK is not set -+CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y -+# CONFIG_HAVE_ARM_ARCH_TIMER is not set -+CONFIG_HAVE_EXIT_THREAD=y -+CONFIG_HAVE_GCC_PLUGINS=y -+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -+CONFIG_HAVE_KERNEL_BZIP2=y -+CONFIG_HAVE_KERNEL_CAT=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_KPROBES=y -+CONFIG_HAVE_KRETPROBES=y -+CONFIG_HAVE_NMI=y -+# CONFIG_HCALL_STATS is not set -+# CONFIG_HDC100X is not set -+# CONFIG_HDLC is not set -+# CONFIG_HDLC_CISCO is not set -+# CONFIG_HDLC_FR is not set -+# CONFIG_HDLC_PPP is not set -+# CONFIG_HDLC_RAW is not set -+# CONFIG_HDLC_RAW_ETH is not set -+# CONFIG_HDMI_LPE_AUDIO is not set -+# CONFIG_HDQ_MASTER_OMAP is not set -+# CONFIG_HEADERS_CHECK is not set -+# CONFIG_HERMES is not set -+# CONFIG_HFSPLUS_FS is not set -+# CONFIG_HFSPLUS_FS_POSIX_ACL is not set -+# CONFIG_HFS_FS is not set -+# CONFIG_HFS_FS_POSIX_ACL is not set -+# CONFIG_HI8435 is not set -+# CONFIG_HIBERNATION is not set -+# CONFIG_HID is not set -+# CONFIG_HIDRAW is not set -+# CONFIG_HID_A4TECH is not set -+# CONFIG_HID_ACCUTOUCH is not set -+# CONFIG_HID_ACRUX is not set -+# CONFIG_HID_ACRUX_FF is not set -+# CONFIG_HID_ALPS is not set -+# CONFIG_HID_APPLE is not set -+# CONFIG_HID_APPLEIR is not set -+# CONFIG_HID_ASUS is not set -+# CONFIG_HID_AUREAL is not set -+# CONFIG_HID_BATTERY_STRENGTH is not set -+# CONFIG_HID_BELKIN is not set -+# CONFIG_HID_BETOP_FF is not set -+# CONFIG_HID_CHERRY is not set -+# CONFIG_HID_CHICONY is not set -+# CONFIG_HID_CMEDIA is not set -+# CONFIG_HID_CORSAIR is not set -+# CONFIG_HID_CP2112 is not set -+# CONFIG_HID_CYPRESS is not set -+# CONFIG_HID_DRAGONRISE is not set -+# CONFIG_HID_ELECOM is not set -+# CONFIG_HID_ELO is not set -+# CONFIG_HID_EMS_FF is not set -+# CONFIG_HID_EZKEY is not set -+# CONFIG_HID_GEMBIRD is not set -+# CONFIG_HID_GENERIC is not set -+# CONFIG_HID_GFRM is not set -+# CONFIG_HID_GREENASIA is not set -+# CONFIG_HID_GT683R is not set -+# CONFIG_HID_GYRATION is not set -+# CONFIG_HID_HOLTEK is not set -+# CONFIG_HID_ICADE is not set -+# CONFIG_HID_ITE is not set -+# CONFIG_HID_KENSINGTON is not set -+# CONFIG_HID_KEYTOUCH is not set -+# CONFIG_HID_KYE is not set -+# CONFIG_HID_LCPOWER is not set -+# CONFIG_HID_LED is not set -+# CONFIG_HID_LENOVO is not set -+# CONFIG_HID_LOGITECH is not set -+# CONFIG_HID_LOGITECH_DJ is not set -+# CONFIG_HID_LOGITECH_HIDPP is not set -+# CONFIG_HID_MAGICMOUSE is not set -+# CONFIG_HID_MAYFLASH is not set -+# CONFIG_HID_MICROSOFT is not set -+# CONFIG_HID_MONTEREY is not set -+# CONFIG_HID_MULTITOUCH is not set -+# CONFIG_HID_NTI is not set -+# CONFIG_HID_NTRIG is not set -+# CONFIG_HID_ORTEK is not set -+# CONFIG_HID_PANTHERLORD is not set -+# CONFIG_HID_PENMOUNT is not set -+# CONFIG_HID_PETALYNX is not set -+# CONFIG_HID_PICOLCD is not set -+# CONFIG_HID_PID is not set -+# CONFIG_HID_PLANTRONICS is not set -+# CONFIG_HID_PRIMAX is not set -+# CONFIG_HID_PRODIKEYS is not set -+# CONFIG_HID_RETRODE is not set -+# CONFIG_HID_RMI is not set -+# CONFIG_HID_ROCCAT is not set -+# CONFIG_HID_SAITEK is not set -+# CONFIG_HID_SAMSUNG is not set -+# CONFIG_HID_SENSOR_HUB is not set -+# CONFIG_HID_SMARTJOYPLUS is not set -+# CONFIG_HID_SONY is not set -+# CONFIG_HID_SPEEDLINK is not set -+# CONFIG_HID_STEELSERIES is not set -+# CONFIG_HID_SUNPLUS is not set -+# CONFIG_HID_THINGM is not set -+# CONFIG_HID_THRUSTMASTER is not set -+# CONFIG_HID_TIVO is not set -+# CONFIG_HID_TOPSEED is not set -+# CONFIG_HID_TWINHAN is not set -+# CONFIG_HID_UCLOGIC is not set -+# CONFIG_HID_UDRAW_PS3 is not set -+# CONFIG_HID_WACOM is not set -+# CONFIG_HID_WALTOP is not set -+# CONFIG_HID_WIIMOTE is not set -+# CONFIG_HID_XINMO is not set -+# CONFIG_HID_ZEROPLUS is not set -+# CONFIG_HID_ZYDACRON is not set -+# CONFIG_HIGHMEM is not set -+CONFIG_HIGH_RES_TIMERS=y -+# CONFIG_HINIC is not set -+# CONFIG_HIP04_ETH is not set -+# CONFIG_HIPPI is not set -+# CONFIG_HISILICON_ERRATUM_161010101 is not set -+# CONFIG_HISI_FEMAC is not set -+# CONFIG_HIX5HD2_GMAC is not set -+# CONFIG_HMC6352 is not set -+# CONFIG_HNS is not set -+# CONFIG_HNS3 is not set -+# CONFIG_HNS_DSAF is not set -+# CONFIG_HNS_ENET is not set -+# CONFIG_HOSTAP is not set -+# CONFIG_HOSTAP_CS is not set -+# CONFIG_HOSTAP_PCI is not set -+# CONFIG_HOSTAP_PLX is not set -+# CONFIG_HOTPLUG_CPU is not set -+# CONFIG_HOTPLUG_PCI is not set -+# CONFIG_HP03 is not set -+# CONFIG_HP100 is not set -+# CONFIG_HP206C is not set -+CONFIG_HPET_MMAP_DEFAULT=y -+# CONFIG_HPFS_FS is not set -+# CONFIG_HP_ILO is not set -+# CONFIG_HP_WIRELESS is not set -+# CONFIG_HSI is not set -+# CONFIG_HSR is not set -+# CONFIG_HTC_EGPIO is not set -+# CONFIG_HTC_I2CPLD is not set -+# CONFIG_HTC_PASIC3 is not set -+# CONFIG_HTS221 is not set -+# CONFIG_HTU21 is not set -+# CONFIG_HUGETLB_PAGE is not set -+# CONFIG_HUGETLBFS is not set -+# CONFIG_HVC_DCC is not set -+# CONFIG_HVC_UDBG is not set -+# CONFIG_HWLAT_TRACER is not set -+# CONFIG_HWMON is not set -+# CONFIG_HWMON_DEBUG_CHIP is not set -+# CONFIG_HWMON_VID is not set -+# CONFIG_HWSPINLOCK is not set -+# CONFIG_HWSPINLOCK_OMAP is not set -+CONFIG_HW_PERF_EVENTS=y -+# CONFIG_HW_RANDOM is not set -+# CONFIG_HW_RANDOM_AMD is not set -+# CONFIG_HW_RANDOM_ATMEL is not set -+# CONFIG_HW_RANDOM_CAVIUM is not set -+# CONFIG_HW_RANDOM_EXYNOS is not set -+# CONFIG_HW_RANDOM_GEODE is not set -+# CONFIG_HW_RANDOM_INTEL is not set -+# CONFIG_HW_RANDOM_IPROC_RNG200 is not set -+# CONFIG_HW_RANDOM_OMAP is not set -+# CONFIG_HW_RANDOM_OMAP3_ROM is not set -+# CONFIG_HW_RANDOM_PPC4XX is not set -+# CONFIG_HW_RANDOM_TIMERIOMEM is not set -+# CONFIG_HW_RANDOM_TPM is not set -+# CONFIG_HW_RANDOM_VIA is not set -+# CONFIG_HW_RANDOM_VIRTIO is not set -+# CONFIG_HX711 is not set -+# CONFIG_HYPERV is not set -+# CONFIG_HYPERV_TSCPAGE is not set -+# CONFIG_HYSDN is not set -+CONFIG_HZ=100 -+CONFIG_HZ_100=y -+# CONFIG_HZ_1000 is not set -+# CONFIG_HZ_1024 is not set -+# CONFIG_HZ_128 is not set -+# CONFIG_HZ_200 is not set -+# CONFIG_HZ_24 is not set -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_256 is not set -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_48 is not set -+# CONFIG_HZ_500 is not set -+# CONFIG_HZ_PERIODIC is not set -+# CONFIG_I2C is not set -+# CONFIG_I2C_ALGOBIT is not set -+# CONFIG_I2C_ALGOPCA is not set -+# CONFIG_I2C_ALGOPCF is not set -+# CONFIG_I2C_ALI1535 is not set -+# CONFIG_I2C_ALI1563 is not set -+# CONFIG_I2C_ALI15X3 is not set -+# CONFIG_I2C_AMD756 is not set -+# CONFIG_I2C_AMD8111 is not set -+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set -+# CONFIG_I2C_AU1550 is not set -+# CONFIG_I2C_BCM2835 is not set -+# CONFIG_I2C_BCM_IPROC is not set -+# CONFIG_I2C_CADENCE is not set -+# CONFIG_I2C_CBUS_GPIO is not set -+# CONFIG_I2C_CHARDEV is not set -+# CONFIG_I2C_COMPAT is not set -+# CONFIG_I2C_DEBUG_ALGO is not set -+# CONFIG_I2C_DEBUG_BUS is not set -+# CONFIG_I2C_DEBUG_CORE is not set -+# CONFIG_I2C_DEMUX_PINCTRL is not set -+# CONFIG_I2C_DESIGNWARE_PCI is not set -+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -+# CONFIG_I2C_DIOLAN_U2C is not set -+# CONFIG_I2C_EG20T is not set -+# CONFIG_I2C_ELEKTOR is not set -+# CONFIG_I2C_EMEV2 is not set -+# CONFIG_I2C_GPIO is not set -+# CONFIG_I2C_HELPER_AUTO is not set -+# CONFIG_I2C_HID is not set -+# CONFIG_I2C_I801 is not set -+# CONFIG_I2C_IBM_IIC is not set -+# CONFIG_I2C_IMG is not set -+# CONFIG_I2C_ISCH is not set -+# CONFIG_I2C_ISMT is not set -+# CONFIG_I2C_MLXCPLD is not set -+# CONFIG_I2C_MPC is not set -+# CONFIG_I2C_MUX is not set -+# CONFIG_I2C_MUX_GPIO is not set -+# CONFIG_I2C_MUX_GPMUX is not set -+# CONFIG_I2C_MUX_LTC4306 is not set -+# CONFIG_I2C_MUX_MLXCPLD is not set -+# CONFIG_I2C_MUX_PCA9541 is not set -+# CONFIG_I2C_MUX_PCA954x is not set -+# CONFIG_I2C_MUX_PINCTRL is not set -+# CONFIG_I2C_MUX_REG is not set -+# CONFIG_I2C_MV64XXX is not set -+# CONFIG_I2C_NFORCE2 is not set -+# CONFIG_I2C_NOMADIK is not set -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_OCTEON is not set -+# CONFIG_I2C_PARPORT is not set -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_PCA_ISA is not set -+# CONFIG_I2C_PCA_PLATFORM is not set -+# CONFIG_I2C_PIIX4 is not set -+# CONFIG_I2C_PXA_PCI is not set -+# CONFIG_I2C_RCAR is not set -+# CONFIG_I2C_RK3X is not set -+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set -+# CONFIG_I2C_S3C2410 is not set -+# CONFIG_I2C_SCMI is not set -+# CONFIG_I2C_SH_MOBILE is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_SIS5595 is not set -+# CONFIG_I2C_SIS630 is not set -+# CONFIG_I2C_SIS96X is not set -+# CONFIG_I2C_SLAVE is not set -+# CONFIG_I2C_SMBUS is not set -+# CONFIG_I2C_STUB is not set -+# CONFIG_I2C_TAOS_EVM is not set -+# CONFIG_I2C_THUNDERX is not set -+# CONFIG_I2C_TINY_USB is not set -+# CONFIG_I2C_VERSATILE is not set -+# CONFIG_I2C_VIA is not set -+# CONFIG_I2C_VIAPRO is not set -+# CONFIG_I2C_XILINX is not set -+# CONFIG_I40E is not set -+# CONFIG_I40EVF is not set -+# CONFIG_I6300ESB_WDT is not set -+# CONFIG_I82092 is not set -+# CONFIG_I82365 is not set -+# CONFIG_IAQCORE is not set -+# CONFIG_IBM_ASM is not set -+# CONFIG_IBM_EMAC_DEBUG is not set -+# CONFIG_IBM_EMAC_EMAC4 is not set -+# CONFIG_IBM_EMAC_MAL_CLR_ICINTSTAT is not set -+# CONFIG_IBM_EMAC_MAL_COMMON_ERR is not set -+# CONFIG_IBM_EMAC_NO_FLOW_CTRL is not set -+# CONFIG_IBM_EMAC_RGMII is not set -+# CONFIG_IBM_EMAC_TAH is not set -+# CONFIG_IBM_EMAC_ZMII is not set -+# CONFIG_ICPLUS_PHY is not set -+# CONFIG_ICS932S401 is not set -+# CONFIG_IDE is not set -+# CONFIG_IDEAPAD_LAPTOP is not set -+# CONFIG_IDE_GD is not set -+# CONFIG_IDE_PROC_FS is not set -+# CONFIG_IDE_TASK_IOCTL is not set -+# CONFIG_IDLE_PAGE_TRACKING is not set -+# CONFIG_IEEE802154 is not set -+# CONFIG_IEEE802154_ADF7242 is not set -+# CONFIG_IEEE802154_ATUSB is not set -+# CONFIG_IEEE802154_CA8210 is not set -+# CONFIG_IFB is not set -+# CONFIG_IGB is not set -+# CONFIG_IGBVF is not set -+# CONFIG_IIO is not set -+# CONFIG_IIO_BUFFER_CB is not set -+# CONFIG_IIO_CONFIGFS is not set -+CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 -+# CONFIG_IIO_INTERRUPT_TRIGGER is not set -+# CONFIG_IIO_MUX is not set -+# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set -+# CONFIG_IIO_SIMPLE_DUMMY is not set -+# CONFIG_IIO_SSP_SENSORHUB is not set -+# CONFIG_IIO_ST_ACCEL_3AXIS is not set -+# CONFIG_IIO_ST_GYRO_3AXIS is not set -+# CONFIG_IIO_ST_LSM6DSX is not set -+# CONFIG_IIO_ST_MAGN_3AXIS is not set -+# CONFIG_IIO_ST_PRESS is not set -+# CONFIG_IIO_SW_DEVICE is not set -+# CONFIG_IIO_SW_TRIGGER is not set -+# CONFIG_IIO_SYSFS_TRIGGER is not set -+# CONFIG_IKCONFIG is not set -+# CONFIG_IKCONFIG_PROC is not set -+# CONFIG_IMAGE_CMDLINE_HACK is not set -+# CONFIG_IMGPDC_WDT is not set -+# CONFIG_IMG_MDC_DMA is not set -+# CONFIG_IMX7D_ADC is not set -+# CONFIG_IMX_IPUV3_CORE is not set -+# CONFIG_IMX_THERMAL is not set -+# CONFIG_INA2XX_ADC is not set -+CONFIG_INET=y -+# CONFIG_INET6_AH is not set -+# CONFIG_INET6_ESP is not set -+# CONFIG_INET6_IPCOMP is not set -+# CONFIG_INET6_TUNNEL is not set -+# CONFIG_INET6_XFRM_MODE_BEET is not set -+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET6_XFRM_TUNNEL is not set -+# CONFIG_INET_AH is not set -+# CONFIG_INET_DIAG is not set -+# CONFIG_INET_ESP is not set -+# CONFIG_INET_IPCOMP is not set -+# CONFIG_INET_LRO is not set -+# CONFIG_INET_TCP_DIAG is not set -+# CONFIG_INET_TUNNEL is not set -+# CONFIG_INET_UDP_DIAG is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_TUNNEL is not set -+# CONFIG_INFINIBAND is not set -+# CONFIG_INFTL is not set -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+# CONFIG_INLINE_READ_LOCK is not set -+# CONFIG_INLINE_READ_LOCK_BH is not set -+# CONFIG_INLINE_READ_LOCK_IRQ is not set -+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set -+# CONFIG_INLINE_READ_TRYLOCK is not set -+CONFIG_INLINE_READ_UNLOCK=y -+# CONFIG_INLINE_READ_UNLOCK_BH is not set -+CONFIG_INLINE_READ_UNLOCK_IRQ=y -+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set -+# CONFIG_INLINE_SPIN_LOCK is not set -+# CONFIG_INLINE_SPIN_LOCK_BH is not set -+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set -+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set -+# CONFIG_INLINE_SPIN_TRYLOCK is not set -+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set -+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set -+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set -+# CONFIG_INLINE_WRITE_LOCK is not set -+# CONFIG_INLINE_WRITE_LOCK_BH is not set -+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set -+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set -+# CONFIG_INLINE_WRITE_TRYLOCK is not set -+CONFIG_INLINE_WRITE_UNLOCK=y -+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set -+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -+CONFIG_INOTIFY_USER=y -+# CONFIG_INPUT is not set -+# CONFIG_INPUT_AD714X is not set -+# CONFIG_INPUT_ADXL34X is not set -+# CONFIG_INPUT_APANEL is not set -+# CONFIG_INPUT_ATI_REMOTE2 is not set -+# CONFIG_INPUT_ATLAS_BTNS is not set -+# CONFIG_INPUT_ATMEL_CAPTOUCH is not set -+# CONFIG_INPUT_AXP20X_PEK is not set -+# CONFIG_INPUT_BMA150 is not set -+# CONFIG_INPUT_CM109 is not set -+# CONFIG_INPUT_CMA3000 is not set -+# CONFIG_INPUT_DRV260X_HAPTICS is not set -+# CONFIG_INPUT_DRV2665_HAPTICS is not set -+# CONFIG_INPUT_DRV2667_HAPTICS is not set -+# CONFIG_INPUT_E3X0_BUTTON is not set -+# CONFIG_INPUT_EVBUG is not set -+# CONFIG_INPUT_EVDEV is not set -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_GP2A is not set -+# CONFIG_INPUT_GPIO_BEEPER is not set -+# CONFIG_INPUT_GPIO_DECODER is not set -+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -+# CONFIG_INPUT_GPIO_TILT_POLLED is not set -+# CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set -+# CONFIG_INPUT_IMS_PCU is not set -+# CONFIG_INPUT_JOYDEV is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_KEYBOARD is not set -+# CONFIG_INPUT_KEYSPAN_REMOTE is not set -+# CONFIG_INPUT_KXTJ9 is not set -+# CONFIG_INPUT_LEDS is not set -+# CONFIG_INPUT_MATRIXKMAP is not set -+# CONFIG_INPUT_MAX8997_HAPTIC is not set -+CONFIG_INPUT_MISC=y -+# CONFIG_INPUT_MMA8450 is not set -+# CONFIG_INPUT_MOUSE is not set -+# CONFIG_INPUT_MOUSEDEV is not set -+# CONFIG_INPUT_MPU3050 is not set -+# CONFIG_INPUT_PALMAS_PWRBUTTON is not set -+# CONFIG_INPUT_PCF8574 is not set -+# CONFIG_INPUT_PCSPKR is not set -+# CONFIG_INPUT_POLLDEV is not set -+# CONFIG_INPUT_POWERMATE is not set -+# CONFIG_INPUT_PWM_BEEPER is not set -+# CONFIG_INPUT_PWM_VIBRA is not set -+# CONFIG_INPUT_REGULATOR_HAPTIC is not set -+# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set -+# CONFIG_INPUT_SPARSEKMAP is not set -+# CONFIG_INPUT_TABLET is not set -+# CONFIG_INPUT_TOUCHSCREEN is not set -+# CONFIG_INPUT_TPS65218_PWRBUTTON is not set -+# CONFIG_INPUT_TWL4030_PWRBUTTON is not set -+# CONFIG_INPUT_TWL4030_VIBRA is not set -+# CONFIG_INPUT_TWL6040_VIBRA is not set -+# CONFIG_INPUT_UINPUT is not set -+# CONFIG_INPUT_WISTRON_BTNS is not set -+# CONFIG_INPUT_YEALINK is not set -+# CONFIG_INT340X_THERMAL is not set -+# CONFIG_INTEL_CHT_INT33FE is not set -+# CONFIG_INTEL_HID_EVENT is not set -+# CONFIG_INTEL_IDLE is not set -+# CONFIG_INTEL_IDMA64 is not set -+# CONFIG_INTEL_IOATDMA is not set -+# CONFIG_INTEL_ISH_HID is not set -+# CONFIG_INTEL_MEI is not set -+# CONFIG_INTEL_MEI_ME is not set -+# CONFIG_INTEL_MEI_TXE is not set -+# CONFIG_INTEL_MIC_CARD is not set -+# CONFIG_INTEL_MIC_HOST is not set -+# CONFIG_INTEL_MID_PTI is not set -+# CONFIG_INTEL_OAKTRAIL is not set -+# CONFIG_INTEL_PMC_CORE is not set -+# CONFIG_INTEL_PUNIT_IPC is not set -+# CONFIG_INTEL_RST is not set -+# CONFIG_INTEL_SMARTCONNECT is not set -+# CONFIG_INTEL_SOC_PMIC is not set -+# CONFIG_INTEL_SOC_PMIC_CHTWC is not set -+# CONFIG_INTEL_TH is not set -+# CONFIG_INTEL_VBTN is not set -+# CONFIG_INTEL_XWAY_PHY is not set -+# CONFIG_INTERVAL_TREE_TEST is not set -+# CONFIG_INV_MPU6050_I2C is not set -+# CONFIG_INV_MPU6050_IIO is not set -+# CONFIG_INV_MPU6050_SPI is not set -+# CONFIG_IOMMU_SUPPORT is not set -+# CONFIG_IOSCHED_BFQ is not set -+# CONFIG_IOSCHED_CFQ is not set -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IO_STRICT_DEVMEM=y -+# CONFIG_IP17XX_PHY is not set -+# CONFIG_IP6_NF_FILTER is not set -+# CONFIG_IP6_NF_IPTABLES is not set -+# CONFIG_IP6_NF_MANGLE is not set -+# CONFIG_IP6_NF_MATCH_AH is not set -+# CONFIG_IP6_NF_MATCH_EUI64 is not set -+# CONFIG_IP6_NF_MATCH_FRAG is not set -+# CONFIG_IP6_NF_MATCH_HL is not set -+# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set -+# CONFIG_IP6_NF_MATCH_MH is not set -+# CONFIG_IP6_NF_MATCH_OPTS is not set -+# CONFIG_IP6_NF_MATCH_RPFILTER is not set -+# CONFIG_IP6_NF_MATCH_RT is not set -+# CONFIG_IP6_NF_NAT is not set -+# CONFIG_IP6_NF_RAW is not set -+# CONFIG_IP6_NF_SECURITY is not set -+# CONFIG_IP6_NF_TARGET_HL is not set -+# CONFIG_IP6_NF_TARGET_REJECT is not set -+# CONFIG_IP6_NF_TARGET_SYNPROXY is not set -+# CONFIG_IPACK_BUS is not set -+# CONFIG_IPC_NS is not set -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_IPV6 is not set -+# CONFIG_IPV6_FOU is not set -+# CONFIG_IPV6_FOU_TUNNEL is not set -+# CONFIG_IPV6_ILA is not set -+# CONFIG_IPV6_MIP6 is not set -+# CONFIG_IPV6_MROUTE is not set -+# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set -+# CONFIG_IPV6_MULTIPLE_TABLES is not set -+CONFIG_IPV6_NDISC_NODETYPE=y -+# CONFIG_IPV6_OPTIMISTIC_DAD is not set -+# CONFIG_IPV6_ROUTER_PREF is not set -+# CONFIG_IPV6_ROUTE_INFO is not set -+# CONFIG_IPV6_SEG6_HMAC is not set -+# CONFIG_IPV6_SEG6_LWTUNNEL is not set -+# CONFIG_IPV6_SIT is not set -+# CONFIG_IPV6_SIT_6RD is not set -+# CONFIG_IPV6_TUNNEL is not set -+# CONFIG_IPV6_VTI is not set -+# CONFIG_IPVLAN is not set -+# CONFIG_IPW2100 is not set -+# CONFIG_IPW2100_DEBUG is not set -+CONFIG_IPW2100_MONITOR=y -+# CONFIG_IPW2200 is not set -+# CONFIG_IPW2200_DEBUG is not set -+CONFIG_IPW2200_MONITOR=y -+# CONFIG_IPW2200_PROMISCUOUS is not set -+# CONFIG_IPW2200_QOS is not set -+# CONFIG_IPW2200_RADIOTAP is not set -+# CONFIG_IPWIRELESS is not set -+# CONFIG_IPX is not set -+CONFIG_IP_ADVANCED_ROUTER=y -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_FIB_TRIE_STATS is not set -+# CONFIG_IP_MROUTE is not set -+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_MULTIPLE_TABLES=y -+# CONFIG_IP_NF_ARPFILTER is not set -+# CONFIG_IP_NF_ARPTABLES is not set -+# CONFIG_IP_NF_ARP_MANGLE is not set -+# CONFIG_IP_NF_FILTER is not set -+# CONFIG_IP_NF_IPTABLES is not set -+# CONFIG_IP_NF_MANGLE is not set -+# CONFIG_IP_NF_MATCH_AH is not set -+# CONFIG_IP_NF_MATCH_ECN is not set -+# CONFIG_IP_NF_MATCH_RPFILTER is not set -+# CONFIG_IP_NF_MATCH_TTL is not set -+# CONFIG_IP_NF_RAW is not set -+# CONFIG_IP_NF_SECURITY is not set -+# CONFIG_IP_NF_TARGET_CLUSTERIP is not set -+# CONFIG_IP_NF_TARGET_ECN is not set -+# CONFIG_IP_NF_TARGET_MASQUERADE is not set -+# CONFIG_IP_NF_TARGET_NETMAP is not set -+# CONFIG_IP_NF_TARGET_REDIRECT is not set -+# CONFIG_IP_NF_TARGET_REJECT is not set -+# CONFIG_IP_NF_TARGET_SYNPROXY is not set -+# CONFIG_IP_NF_TARGET_TTL is not set -+# CONFIG_IP_PIMSM_V1 is not set -+# CONFIG_IP_PIMSM_V2 is not set -+# CONFIG_IP_PNP is not set -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+# CONFIG_IP_SCTP is not set -+# CONFIG_IP_SET is not set -+# CONFIG_IP_SET_HASH_IPMAC is not set -+# CONFIG_IP_VS is not set -+# CONFIG_IRDA is not set -+# CONFIG_IRQSOFF_TRACER is not set -+# CONFIG_IRQ_ALL_CPUS is not set -+# CONFIG_IRQ_DOMAIN_DEBUG is not set -+# CONFIG_IRQ_POLL is not set -+# CONFIG_IRQ_TIME_ACCOUNTING is not set -+# CONFIG_IR_GPIO_CIR is not set -+# CONFIG_IR_HIX5HD2 is not set -+# CONFIG_IR_IGORPLUGUSB is not set -+# CONFIG_IR_IGUANA is not set -+# CONFIG_IR_IMG is not set -+# CONFIG_IR_IMON is not set -+# CONFIG_IR_JVC_DECODER is not set -+# CONFIG_IR_LIRC_CODEC is not set -+# CONFIG_IR_MCEUSB is not set -+# CONFIG_IR_NEC_DECODER is not set -+# CONFIG_IR_RC5_DECODER is not set -+# CONFIG_IR_RC6_DECODER is not set -+# CONFIG_IR_REDRAT3 is not set -+# CONFIG_IR_SONY_DECODER is not set -+# CONFIG_IR_STREAMZAP is not set -+# CONFIG_IR_TTUSBIR is not set -+# CONFIG_ISA_BUS is not set -+# CONFIG_ISA_BUS_API is not set -+# CONFIG_ISCSI_BOOT_SYSFS is not set -+# CONFIG_ISCSI_TCP is not set -+CONFIG_ISDN=y -+# CONFIG_ISDN_AUDIO is not set -+# CONFIG_ISDN_CAPI is not set -+# CONFIG_ISDN_CAPI_CAPIDRV is not set -+# CONFIG_ISDN_DIVERSION is not set -+# CONFIG_ISDN_DRV_ACT2000 is not set -+# CONFIG_ISDN_DRV_GIGASET is not set -+# CONFIG_ISDN_DRV_HISAX is not set -+# CONFIG_ISDN_DRV_ICN is not set -+# CONFIG_ISDN_DRV_LOOP is not set -+# CONFIG_ISDN_DRV_PCBIT is not set -+# CONFIG_ISDN_DRV_SC is not set -+# CONFIG_ISDN_I4L is not set -+# CONFIG_ISL29003 is not set -+# CONFIG_ISL29020 is not set -+# CONFIG_ISL29125 is not set -+# CONFIG_ISO9660_FS is not set -+# CONFIG_ISS4xx is not set -+# CONFIG_ITG3200 is not set -+# CONFIG_IWL3945 is not set -+# CONFIG_IWLWIFI is not set -+# CONFIG_IXGB is not set -+# CONFIG_IXGBE is not set -+# CONFIG_IXGBEVF is not set -+# CONFIG_JBD2_DEBUG is not set -+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set -+# CONFIG_JFFS2_CMODE_NONE is not set -+CONFIG_JFFS2_CMODE_PRIORITY=y -+# CONFIG_JFFS2_CMODE_SIZE is not set -+CONFIG_JFFS2_COMPRESSION_OPTIONS=y -+CONFIG_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+# CONFIG_JFFS2_FS_POSIX_ACL is not set -+# CONFIG_JFFS2_FS_SECURITY is not set -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+CONFIG_JFFS2_FS_XATTR=y -+CONFIG_JFFS2_LZMA=y -+# CONFIG_JFFS2_LZO is not set -+CONFIG_JFFS2_RTIME=y -+# CONFIG_JFFS2_RUBIN is not set -+CONFIG_JFFS2_SUMMARY=y -+# CONFIG_JFFS2_ZLIB is not set -+# CONFIG_JFS_DEBUG is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_JFS_POSIX_ACL is not set -+# CONFIG_JFS_SECURITY is not set -+# CONFIG_JFS_STATISTICS is not set -+# CONFIG_JME is not set -+CONFIG_JOLIET=y -+# CONFIG_JSA1212 is not set -+# CONFIG_JUMP_LABEL is not set -+# CONFIG_KALLSYMS is not set -+# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set -+# CONFIG_KALLSYMS_ALL is not set -+CONFIG_KALLSYMS_BASE_RELATIVE=y -+# CONFIG_KALLSYMS_UNCOMPRESSED is not set -+# CONFIG_KARMA_PARTITION is not set -+# CONFIG_KASAN is not set -+# CONFIG_KCOV is not set -+# CONFIG_KERNEL_BZIP2 is not set -+# CONFIG_KERNEL_CAT is not set -+# CONFIG_KERNEL_GZIP is not set -+# CONFIG_KERNEL_LZ4 is not set -+# CONFIG_KERNEL_LZMA is not set -+# CONFIG_KERNEL_LZO is not set -+CONFIG_KERNEL_MODE_NEON=y -+CONFIG_KERNEL_XZ=y -+CONFIG_KERNFS=y -+# CONFIG_KEXEC is not set -+# CONFIG_KEXEC_FILE is not set -+# CONFIG_KEYBOARD_ADC is not set -+# CONFIG_KEYBOARD_ADP5588 is not set -+# CONFIG_KEYBOARD_ADP5589 is not set -+# CONFIG_KEYBOARD_ATKBD is not set -+# CONFIG_KEYBOARD_BCM is not set -+# CONFIG_KEYBOARD_CAP11XX is not set -+# CONFIG_KEYBOARD_DLINK_DIR685 is not set -+# CONFIG_KEYBOARD_GPIO is not set -+# CONFIG_KEYBOARD_GPIO_POLLED is not set -+# CONFIG_KEYBOARD_LKKBD is not set -+# CONFIG_KEYBOARD_LM8323 is not set -+# CONFIG_KEYBOARD_LM8333 is not set -+# CONFIG_KEYBOARD_MATRIX is not set -+# CONFIG_KEYBOARD_MAX7359 is not set -+# CONFIG_KEYBOARD_MCS is not set -+# CONFIG_KEYBOARD_MPR121 is not set -+# CONFIG_KEYBOARD_NEWTON is not set -+# CONFIG_KEYBOARD_OMAP4 is not set -+# CONFIG_KEYBOARD_OPENCORES is not set -+# CONFIG_KEYBOARD_PXA27x is not set -+# CONFIG_KEYBOARD_QT1070 is not set -+# CONFIG_KEYBOARD_QT2160 is not set -+# CONFIG_KEYBOARD_SAMSUNG is not set -+# CONFIG_KEYBOARD_SH_KEYSC is not set -+# CONFIG_KEYBOARD_SNVS_PWRKEY is not set -+# CONFIG_KEYBOARD_STMPE is not set -+# CONFIG_KEYBOARD_STOWAWAY is not set -+# CONFIG_KEYBOARD_SUNKBD is not set -+# CONFIG_KEYBOARD_TCA6416 is not set -+# CONFIG_KEYBOARD_TCA8418 is not set -+# CONFIG_KEYBOARD_TEGRA is not set -+# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set -+# CONFIG_KEYBOARD_TWL4030 is not set -+# CONFIG_KEYBOARD_XTKBD is not set -+# CONFIG_KEYS is not set -+# CONFIG_KEY_DH_OPERATIONS is not set -+# CONFIG_KGDB is not set -+# CONFIG_KMEMCHECK is not set -+# CONFIG_KMX61 is not set -+# CONFIG_KPROBES is not set -+# CONFIG_KPROBES_SANITY_TEST is not set -+# CONFIG_KS7010 is not set -+# CONFIG_KS8842 is not set -+# CONFIG_KS8851 is not set -+# CONFIG_KS8851_MLL is not set -+# CONFIG_KSM is not set -+# CONFIG_KSZ884X_PCI is not set -+CONFIG_KUSER_HELPERS=y -+# CONFIG_KVM_AMD is not set -+# CONFIG_KVM_GUEST is not set -+# CONFIG_KVM_INTEL is not set -+# CONFIG_KXCJK1013 is not set -+# CONFIG_KXSD9 is not set -+# CONFIG_L2TP is not set -+# CONFIG_L2TP_ETH is not set -+# CONFIG_L2TP_IP is not set -+# CONFIG_L2TP_V3 is not set -+# CONFIG_LANMEDIA is not set -+# CONFIG_LANTIQ is not set -+# CONFIG_LAPB is not set -+# CONFIG_LASAT is not set -+# CONFIG_LATENCYTOP is not set -+# CONFIG_LATTICE_ECP3_CONFIG is not set -+CONFIG_LBDAF=y -+# CONFIG_LCD_AMS369FG06 is not set -+# CONFIG_LCD_HX8357 is not set -+# CONFIG_LCD_ILI922X is not set -+# CONFIG_LCD_ILI9320 is not set -+# CONFIG_LCD_L4F00242T03 is not set -+# CONFIG_LCD_LD9040 is not set -+# CONFIG_LCD_LMS283GF05 is not set -+# CONFIG_LCD_LMS501KF03 is not set -+# CONFIG_LCD_LTV350QV is not set -+# CONFIG_LCD_S6E63M0 is not set -+# CONFIG_LCD_TDO24M is not set -+# CONFIG_LCD_VGG2432A4 is not set -+CONFIG_LDISC_AUTOLOAD=y -+# CONFIG_LDM_PARTITION is not set -+CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y -+# CONFIG_LEDS_BCM6328 is not set -+# CONFIG_LEDS_BCM6358 is not set -+# CONFIG_LEDS_BD2802 is not set -+# CONFIG_LEDS_BLINKM is not set -+CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y -+CONFIG_LEDS_CLASS=y -+# CONFIG_LEDS_CLASS_FLASH is not set -+# CONFIG_LEDS_DAC124S085 is not set -+# CONFIG_LEDS_GPIO is not set -+# CONFIG_LEDS_INTEL_SS4200 is not set -+# CONFIG_LEDS_IS31FL319X is not set -+# CONFIG_LEDS_IS31FL32XX is not set -+# CONFIG_LEDS_LM3530 is not set -+# CONFIG_LEDS_LM355x is not set -+# CONFIG_LEDS_LM3642 is not set -+# CONFIG_LEDS_LP3944 is not set -+# CONFIG_LEDS_LP3952 is not set -+# CONFIG_LEDS_LP5521 is not set -+# CONFIG_LEDS_LP5523 is not set -+# CONFIG_LEDS_LP5562 is not set -+# CONFIG_LEDS_LP8501 is not set -+# CONFIG_LEDS_LP8860 is not set -+# CONFIG_LEDS_LT3593 is not set -+# CONFIG_LEDS_MLXCPLD is not set -+# CONFIG_LEDS_NIC78BX is not set -+# CONFIG_LEDS_NS2 is not set -+# CONFIG_LEDS_OT200 is not set -+# CONFIG_LEDS_PCA9532 is not set -+# CONFIG_LEDS_PCA955X is not set -+# CONFIG_LEDS_PCA963X is not set -+# CONFIG_LEDS_PWM is not set -+# CONFIG_LEDS_REGULATOR is not set -+# CONFIG_LEDS_SYSCON is not set -+# CONFIG_LEDS_TCA6507 is not set -+# CONFIG_LEDS_TLC591XX is not set -+CONFIG_LEDS_TRIGGERS=y -+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set -+# CONFIG_LEDS_TRIGGER_CAMERA is not set -+# CONFIG_LEDS_TRIGGER_CPU is not set -+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y -+# CONFIG_LEDS_TRIGGER_DISK is not set -+# CONFIG_LEDS_TRIGGER_GPIO is not set -+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set -+# CONFIG_LEDS_TRIGGER_MTD is not set -+CONFIG_LEDS_TRIGGER_NETDEV=y -+# CONFIG_LEDS_TRIGGER_ONESHOT is not set -+# CONFIG_LEDS_TRIGGER_PANIC is not set -+CONFIG_LEDS_TRIGGER_TIMER=y -+# CONFIG_LEDS_TRIGGER_TRANSIENT is not set -+# CONFIG_LEDS_USER is not set -+# CONFIG_LED_TRIGGER_PHY is not set -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_LGUEST is not set -+# CONFIG_LIB80211 is not set -+# CONFIG_LIB80211_CRYPT_CCMP is not set -+# CONFIG_LIB80211_CRYPT_TKIP is not set -+# CONFIG_LIB80211_CRYPT_WEP is not set -+# CONFIG_LIB80211_DEBUG is not set -+# CONFIG_LIBCRC32C is not set -+# CONFIG_LIBERTAS is not set -+# CONFIG_LIBERTAS_THINFIRM is not set -+# CONFIG_LIBERTAS_USB is not set -+# CONFIG_LIBFC is not set -+# CONFIG_LIBFCOE is not set -+# CONFIG_LIBIPW_DEBUG is not set -+# CONFIG_LIBNVDIMM is not set -+# CONFIG_LIDAR_LITE_V2 is not set -+# CONFIG_LIQUIDIO is not set -+# CONFIG_LIQUIDIO_VF is not set -+# CONFIG_LIRC_STAGING is not set -+# CONFIG_LIS3L02DQ is not set -+# CONFIG_LKDTM is not set -+CONFIG_LLC=y -+# CONFIG_LLC2 is not set -+# CONFIG_LMP91000 is not set -+# CONFIG_LNET is not set -+CONFIG_LOCALVERSION="" -+# CONFIG_LOCALVERSION_AUTO is not set -+# CONFIG_LOCKD is not set -+CONFIG_LOCKDEP_SUPPORT=y -+CONFIG_LOCKD_V4=y -+# CONFIG_LOCKUP_DETECTOR is not set -+# CONFIG_LOCK_STAT is not set -+# CONFIG_LOCK_TORTURE_TEST is not set -+# CONFIG_LOGFS is not set -+# CONFIG_LOGIG940_FF is not set -+# CONFIG_LOGIRUMBLEPAD2_FF is not set -+# CONFIG_LOGITECH_FF is not set -+# CONFIG_LOGIWHEELS_FF is not set -+# CONFIG_LOGO is not set -+CONFIG_LOG_BUF_SHIFT=17 -+CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 -+# CONFIG_LOONGSON_MC146818 is not set -+# CONFIG_LPC_ICH is not set -+# CONFIG_LPC_SCH is not set -+# CONFIG_LP_CONSOLE is not set -+# CONFIG_LSI_ET1011C_PHY is not set -+# CONFIG_LTC2471 is not set -+# CONFIG_LTC2485 is not set -+# CONFIG_LTC2497 is not set -+# CONFIG_LTC2632 is not set -+# CONFIG_LTE_GDM724X is not set -+# CONFIG_LTPC is not set -+# CONFIG_LTR501 is not set -+# CONFIG_LUSTRE_FS is not set -+# CONFIG_LWTUNNEL is not set -+# CONFIG_LXT_PHY is not set -+# CONFIG_LZ4HC_COMPRESS is not set -+# CONFIG_LZ4_COMPRESS is not set -+# CONFIG_LZ4_DECOMPRESS is not set -+CONFIG_LZMA_COMPRESS=y -+CONFIG_LZMA_DECOMPRESS=y -+# CONFIG_LZO_COMPRESS is not set -+# CONFIG_LZO_DECOMPRESS is not set -+# CONFIG_M62332 is not set -+# CONFIG_MAC80211 is not set -+# CONFIG_MAC80211_MESSAGE_TRACING is not set -+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -+# CONFIG_MACB is not set -+# CONFIG_MACH_ASM9260 is not set -+# CONFIG_MACH_DECSTATION is not set -+# CONFIG_MACH_INGENIC is not set -+# CONFIG_MACH_JAZZ is not set -+# CONFIG_MACH_JZ4740 is not set -+# CONFIG_MACH_LOONGSON32 is not set -+# CONFIG_MACH_LOONGSON64 is not set -+# CONFIG_MACH_PIC32 is not set -+# CONFIG_MACH_PISTACHIO is not set -+# CONFIG_MACH_TX39XX is not set -+# CONFIG_MACH_TX49XX is not set -+# CONFIG_MACH_VR41XX is not set -+# CONFIG_MACH_XILFPGA is not set -+# CONFIG_MACINTOSH_DRIVERS is not set -+# CONFIG_MACSEC is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_MACVTAP is not set -+# CONFIG_MAC_EMUMOUSEBTN is not set -+# CONFIG_MAC_PARTITION is not set -+# CONFIG_MAG3110 is not set -+# CONFIG_MAGIC_SYSRQ is not set -+CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 -+# CONFIG_MAGIC_SYSRQ_SERIAL is not set -+# CONFIG_MAILBOX is not set -+# CONFIG_MANDATORY_FILE_LOCKING is not set -+# CONFIG_MANGLE_BOOTARGS is not set -+# CONFIG_MARVELL_10G_PHY is not set -+# CONFIG_MARVELL_PHY is not set -+# CONFIG_MAX1027 is not set -+# CONFIG_MAX11100 is not set -+# CONFIG_MAX1118 is not set -+# CONFIG_MAX1363 is not set -+# CONFIG_MAX30100 is not set -+# CONFIG_MAX30102 is not set -+# CONFIG_MAX44000 is not set -+# CONFIG_MAX517 is not set -+# CONFIG_MAX5481 is not set -+# CONFIG_MAX5487 is not set -+# CONFIG_MAX5821 is not set -+# CONFIG_MAX63XX_WATCHDOG is not set -+# CONFIG_MAX9611 is not set -+# CONFIG_MAXIM_THERMOCOUPLE is not set -+CONFIG_MAY_USE_DEVLINK=y -+# CONFIG_MC3230 is not set -+# CONFIG_MCB is not set -+# CONFIG_MCP320X is not set -+# CONFIG_MCP3422 is not set -+# CONFIG_MCP4131 is not set -+# CONFIG_MCP4531 is not set -+# CONFIG_MCP4725 is not set -+# CONFIG_MCP4922 is not set -+# CONFIG_MCPM is not set -+# CONFIG_MD is not set -+# CONFIG_MDIO_BCM_UNIMAC is not set -+# CONFIG_MDIO_BITBANG is not set -+# CONFIG_MDIO_BUS_MUX_GPIO is not set -+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set -+# CONFIG_MDIO_DEVICE is not set -+# CONFIG_MDIO_HISI_FEMAC is not set -+# CONFIG_MDIO_OCTEON is not set -+# CONFIG_MDIO_THUNDER is not set -+# CONFIG_MD_FAULTY is not set -+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set -+# CONFIG_MEDIA_ATTACH is not set -+# CONFIG_MEDIA_CAMERA_SUPPORT is not set -+# CONFIG_MEDIA_CEC_SUPPORT is not set -+# CONFIG_MEDIA_CONTROLLER is not set -+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set -+# CONFIG_MEDIA_PCI_SUPPORT is not set -+# CONFIG_MEDIA_RADIO_SUPPORT is not set -+# CONFIG_MEDIA_RC_SUPPORT is not set -+# CONFIG_MEDIA_SDR_SUPPORT is not set -+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set -+# CONFIG_MEDIA_SUPPORT is not set -+# CONFIG_MEDIA_USB_SUPPORT is not set -+# CONFIG_MEGARAID_LEGACY is not set -+# CONFIG_MEGARAID_NEWGEN is not set -+# CONFIG_MEGARAID_SAS is not set -+CONFIG_MEMBARRIER=y -+# CONFIG_MEMORY is not set -+# CONFIG_MEMORY_FAILURE is not set -+# CONFIG_MEMSTICK is not set -+# CONFIG_MEMTEST is not set -+# CONFIG_MEN_A21_WDT is not set -+# CONFIG_MESON_SM is not set -+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -+# CONFIG_MFD_88PM800 is not set -+# CONFIG_MFD_88PM805 is not set -+# CONFIG_MFD_88PM860X is not set -+# CONFIG_MFD_AAT2870_CORE is not set -+# CONFIG_MFD_ACT8945A is not set -+# CONFIG_MFD_ARIZONA_I2C is not set -+# CONFIG_MFD_ARIZONA_SPI is not set -+# CONFIG_MFD_AS3711 is not set -+# CONFIG_MFD_AS3722 is not set -+# CONFIG_MFD_ASIC3 is not set -+# CONFIG_MFD_ATMEL_FLEXCOM is not set -+# CONFIG_MFD_ATMEL_HLCDC is not set -+# CONFIG_MFD_AXP20X is not set -+# CONFIG_MFD_AXP20X_I2C is not set -+# CONFIG_MFD_BCM590XX is not set -+# CONFIG_MFD_BD9571MWV is not set -+# CONFIG_MFD_CORE is not set -+# CONFIG_MFD_CPCAP is not set -+# CONFIG_MFD_CROS_EC is not set -+# CONFIG_MFD_CS5535 is not set -+# CONFIG_MFD_DA9052_I2C is not set -+# CONFIG_MFD_DA9052_SPI is not set -+# CONFIG_MFD_DA9055 is not set -+# CONFIG_MFD_DA9062 is not set -+# CONFIG_MFD_DA9063 is not set -+# CONFIG_MFD_DA9150 is not set -+# CONFIG_MFD_DLN2 is not set -+# CONFIG_MFD_EXYNOS_LPASS is not set -+# CONFIG_MFD_HI6421_PMIC is not set -+# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set -+# CONFIG_MFD_JANZ_CMODIO is not set -+# CONFIG_MFD_KEMPLD is not set -+# CONFIG_MFD_LM3533 is not set -+# CONFIG_MFD_LP3943 is not set -+# CONFIG_MFD_LP8788 is not set -+# CONFIG_MFD_MAX14577 is not set -+# CONFIG_MFD_MAX77620 is not set -+# CONFIG_MFD_MAX77686 is not set -+# CONFIG_MFD_MAX77693 is not set -+# CONFIG_MFD_MAX77843 is not set -+# CONFIG_MFD_MAX8907 is not set -+# CONFIG_MFD_MAX8925 is not set -+# CONFIG_MFD_MAX8997 is not set -+# CONFIG_MFD_MAX8998 is not set -+# CONFIG_MFD_MC13XXX is not set -+# CONFIG_MFD_MC13XXX_I2C is not set -+# CONFIG_MFD_MC13XXX_SPI is not set -+# CONFIG_MFD_MENF21BMC is not set -+# CONFIG_MFD_MT6397 is not set -+# CONFIG_MFD_OMAP_USB_HOST is not set -+# CONFIG_MFD_PALMAS is not set -+# CONFIG_MFD_PCF50633 is not set -+# CONFIG_MFD_PM8921_CORE is not set -+# CONFIG_MFD_PM8XXX is not set -+# CONFIG_MFD_RC5T583 is not set -+# CONFIG_MFD_RDC321X is not set -+# CONFIG_MFD_RETU is not set -+# CONFIG_MFD_RK808 is not set -+# CONFIG_MFD_RN5T618 is not set -+# CONFIG_MFD_RT5033 is not set -+# CONFIG_MFD_RTSX_PCI is not set -+# CONFIG_MFD_RTSX_USB is not set -+# CONFIG_MFD_SEC_CORE is not set -+# CONFIG_MFD_SI476X_CORE is not set -+# CONFIG_MFD_SKY81452 is not set -+# CONFIG_MFD_SM501 is not set -+# CONFIG_MFD_SMSC is not set -+# CONFIG_MFD_STMPE is not set -+# CONFIG_MFD_SYSCON is not set -+# CONFIG_MFD_T7L66XB is not set -+# CONFIG_MFD_TC3589X is not set -+# CONFIG_MFD_TC6387XB is not set -+# CONFIG_MFD_TC6393XB is not set -+# CONFIG_MFD_TIMBERDALE is not set -+# CONFIG_MFD_TI_AM335X_TSCADC is not set -+# CONFIG_MFD_TI_LMU is not set -+# CONFIG_MFD_TI_LP873X is not set -+# CONFIG_MFD_TI_LP87565 is not set -+# CONFIG_MFD_TMIO is not set -+# CONFIG_MFD_TPS65086 is not set -+# CONFIG_MFD_TPS65090 is not set -+# CONFIG_MFD_TPS65217 is not set -+# CONFIG_MFD_TPS65218 is not set -+# CONFIG_MFD_TPS6586X is not set -+# CONFIG_MFD_TPS65910 is not set -+# CONFIG_MFD_TPS65912 is not set -+# CONFIG_MFD_TPS65912_I2C is not set -+# CONFIG_MFD_TPS65912_SPI is not set -+# CONFIG_MFD_TPS68470 is not set -+# CONFIG_MFD_TPS80031 is not set -+# CONFIG_MFD_VIPERBOARD is not set -+# CONFIG_MFD_VX855 is not set -+# CONFIG_MFD_WL1273_CORE is not set -+# CONFIG_MFD_WM831X is not set -+# CONFIG_MFD_WM831X_I2C is not set -+# CONFIG_MFD_WM831X_SPI is not set -+# CONFIG_MFD_WM8350_I2C is not set -+# CONFIG_MFD_WM8400 is not set -+# CONFIG_MFD_WM8994 is not set -+# CONFIG_MG_DISK is not set -+# CONFIG_MICREL_KS8995MA is not set -+# CONFIG_MICREL_PHY is not set -+# CONFIG_MICROCHIP_KSZ is not set -+# CONFIG_MICROCHIP_PHY is not set -+# CONFIG_MICROSEMI_PHY is not set -+# CONFIG_MIGRATION is not set -+CONFIG_MII=y -+# CONFIG_MIKROTIK_RB532 is not set -+# CONFIG_MIKROTIK is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set -+# CONFIG_MINIX_SUBPARTITION is not set -+# CONFIG_MIPS_ALCHEMY is not set -+# CONFIG_MIPS_CDMM is not set -+# CONFIG_MIPS_COBALT is not set -+# CONFIG_MIPS_FPU_EMULATOR is not set -+# CONFIG_MIPS_GENERIC is not set -+# CONFIG_MIPS_MALTA is not set -+# CONFIG_MIPS_O32_FP64_SUPPORT is not set -+# CONFIG_MIPS_PARAVIRT is not set -+# CONFIG_MIPS_PLATFORM_DEVICES is not set -+# CONFIG_MIPS_SEAD3 is not set -+CONFIG_MISC_FILESYSTEMS=y -+# CONFIG_MISDN is not set -+# CONFIG_MISDN_AVMFRITZ is not set -+# CONFIG_MISDN_HFCPCI is not set -+# CONFIG_MISDN_HFCUSB is not set -+# CONFIG_MISDN_INFINEON is not set -+# CONFIG_MISDN_NETJET is not set -+# CONFIG_MISDN_SPEEDFAX is not set -+# CONFIG_MISDN_W6692 is not set -+# CONFIG_MKISS is not set -+# CONFIG_MLX4_CORE is not set -+# CONFIG_MLX4_EN is not set -+# CONFIG_MLX5_CORE is not set -+# CONFIG_MLX90614 is not set -+# CONFIG_MLXFW is not set -+# CONFIG_MLXSW_CORE is not set -+# CONFIG_MLX_CPLD_PLATFORM is not set -+# CONFIG_MLX_PLATFORM is not set -+# CONFIG_MMA7455_I2C is not set -+# CONFIG_MMA7455_SPI is not set -+# CONFIG_MMA7660 is not set -+# CONFIG_MMA8452 is not set -+# CONFIG_MMA9551 is not set -+# CONFIG_MMA9553 is not set -+# CONFIG_MMC is not set -+# CONFIG_MMC35240 is not set -+# CONFIG_MMC_ARMMMCI is not set -+# CONFIG_MMC_AU1X is not set -+# CONFIG_MMC_BLOCK is not set -+CONFIG_MMC_BLOCK_BOUNCE=y -+CONFIG_MMC_BLOCK_MINORS=8 -+# CONFIG_MMC_CAVIUM_THUNDERX is not set -+# CONFIG_MMC_CB710 is not set -+# CONFIG_MMC_DEBUG is not set -+# CONFIG_MMC_DW is not set -+# CONFIG_MMC_MTK is not set -+# CONFIG_MMC_MVSDIO is not set -+# CONFIG_MMC_S3C is not set -+# CONFIG_MMC_SDHCI is not set -+# CONFIG_MMC_SDHCI_ACPI is not set -+# CONFIG_MMC_SDHCI_BCM_KONA is not set -+# CONFIG_MMC_SDHCI_CADENCE is not set -+# CONFIG_MMC_SDHCI_F_SDH30 is not set -+# CONFIG_MMC_SDHCI_IPROC is not set -+# CONFIG_MMC_SDHCI_MSM is not set -+# CONFIG_MMC_SDHCI_OF_ARASAN is not set -+# CONFIG_MMC_SDHCI_OF_AT91 is not set -+# CONFIG_MMC_SDHCI_OF_ESDHC is not set -+# CONFIG_MMC_SDHCI_OF_HLWD is not set -+# CONFIG_MMC_SDHCI_PXAV2 is not set -+# CONFIG_MMC_SDHCI_PXAV3 is not set -+# CONFIG_MMC_SDHCI_S3C is not set -+# CONFIG_MMC_SDHCI_XENON is not set -+# CONFIG_MMC_SDRICOH_CS is not set -+# CONFIG_MMC_SPI is not set -+# CONFIG_MMC_TEST is not set -+# CONFIG_MMC_TOSHIBA_PCI is not set -+# CONFIG_MMC_USDHI6ROL0 is not set -+# CONFIG_MMC_USHC is not set -+# CONFIG_MMC_VIA_SDMMC is not set -+# CONFIG_MMC_VUB300 is not set -+# CONFIG_MMIOTRACE is not set -+CONFIG_MMU=y -+CONFIG_MODULES=y -+# CONFIG_MODULE_COMPRESS is not set -+# CONFIG_MODULE_FORCE_LOAD is not set -+# CONFIG_MODULE_FORCE_UNLOAD is not set -+# CONFIG_MODULE_SIG is not set -+# CONFIG_MODULE_SRCVERSION_ALL is not set -+CONFIG_MODULE_STRIPPED=y -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_MODVERSIONS is not set -+# CONFIG_MOST is not set -+# CONFIG_MOUSE_APPLETOUCH is not set -+# CONFIG_MOUSE_ELAN_I2C is not set -+# CONFIG_MOUSE_GPIO is not set -+# CONFIG_MOUSE_INPORT is not set -+# CONFIG_MOUSE_LOGIBM is not set -+# CONFIG_MOUSE_PC110PAD is not set -+# CONFIG_MOUSE_PS2_FOCALTECH is not set -+# CONFIG_MOUSE_PS2_SENTELIC is not set -+# CONFIG_MOUSE_SYNAPTICS_I2C is not set -+# CONFIG_MOUSE_SYNAPTICS_USB is not set -+# CONFIG_MPL115 is not set -+# CONFIG_MPL115_I2C is not set -+# CONFIG_MPL115_SPI is not set -+# CONFIG_MPL3115 is not set -+# CONFIG_MPLS is not set -+# CONFIG_MPU3050_I2C is not set -+# CONFIG_MQ_IOSCHED_DEADLINE is not set -+# CONFIG_MQ_IOSCHED_KYBER is not set -+# CONFIG_MS5611 is not set -+# CONFIG_MS5637 is not set -+# CONFIG_MSDOS_FS is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_MSI_BITMAP_SELFTEST is not set -+# CONFIG_MSI_LAPTOP is not set -+CONFIG_MTD=y -+# CONFIG_MTD_ABSENT is not set -+# CONFIG_MTD_AFS_PARTS is not set -+# CONFIG_MTD_AR7_PARTS is not set -+CONFIG_MTD_BLKDEVS=y -+CONFIG_MTD_BLOCK=y -+# CONFIG_MTD_BLOCK2MTD is not set -+CONFIG_MTD_CFI=y -+# CONFIG_MTD_CFI_ADV_OPTIONS is not set -+CONFIG_MTD_CFI_AMDSTD=y -+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -+CONFIG_MTD_CFI_I1=y -+CONFIG_MTD_CFI_I2=y -+# CONFIG_MTD_CFI_I4 is not set -+# CONFIG_MTD_CFI_I8 is not set -+CONFIG_MTD_CFI_INTELEXT=y -+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -+CONFIG_MTD_CFI_NOSWAP=y -+# CONFIG_MTD_CFI_STAA is not set -+CONFIG_MTD_CFI_UTIL=y -+# CONFIG_MTD_CMDLINE_PARTS is not set -+CONFIG_MTD_COMPLEX_MAPPINGS=y -+# CONFIG_MTD_DATAFLASH is not set -+# CONFIG_MTD_DOCG3 is not set -+CONFIG_MTD_GEN_PROBE=y -+# CONFIG_MTD_GPIO_ADDR is not set -+# CONFIG_MTD_INTEL_VR_NOR is not set -+# CONFIG_MTD_JEDECPROBE is not set -+# CONFIG_MTD_LATCH_ADDR is not set -+# CONFIG_MTD_LPDDR is not set -+# CONFIG_MTD_LPDDR2_NVM is not set -+# CONFIG_MTD_M25P80 is not set -+CONFIG_MTD_MAP_BANK_WIDTH_1=y -+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -+CONFIG_MTD_MAP_BANK_WIDTH_2=y -+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -+CONFIG_MTD_MAP_BANK_WIDTH_4=y -+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -+# CONFIG_MTD_MCHP23K256 is not set -+# CONFIG_MTD_MT81xx_NOR is not set -+# CONFIG_MTD_MTDRAM is not set -+# CONFIG_MTD_MYLOADER_PARTS is not set -+# CONFIG_MTD_NAND is not set -+# CONFIG_MTD_NAND_AMS_DELTA is not set -+# CONFIG_MTD_NAND_AR934X is not set -+# CONFIG_MTD_NAND_AR934X_HW_ECC is not set -+# CONFIG_MTD_NAND_ATMEL is not set -+# CONFIG_MTD_NAND_AU1550 is not set -+# CONFIG_MTD_NAND_BCH is not set -+# CONFIG_MTD_NAND_BF5XX is not set -+# CONFIG_MTD_NAND_BRCMNAND is not set -+# CONFIG_MTD_NAND_CAFE is not set -+# CONFIG_MTD_NAND_CM_X270 is not set -+# CONFIG_MTD_NAND_CS553X is not set -+# CONFIG_MTD_NAND_DAVINCI is not set -+# CONFIG_MTD_NAND_DENALI is not set -+# CONFIG_MTD_NAND_DENALI_DT is not set -+# CONFIG_MTD_NAND_DENALI_PCI is not set -+CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xff108018 -+# CONFIG_MTD_NAND_DISKONCHIP is not set -+# CONFIG_MTD_NAND_DOCG4 is not set -+# CONFIG_MTD_NAND_ECC is not set -+# CONFIG_MTD_NAND_ECC_BCH is not set -+# CONFIG_MTD_NAND_ECC_SMC is not set -+# CONFIG_MTD_NAND_FSL_ELBC is not set -+# CONFIG_MTD_NAND_FSL_IFC is not set -+# CONFIG_MTD_NAND_FSL_UPM is not set -+# CONFIG_MTD_NAND_FSMC is not set -+# CONFIG_MTD_NAND_GPIO is not set -+# CONFIG_MTD_NAND_GPMI_NAND is not set -+# CONFIG_MTD_NAND_HISI504 is not set -+CONFIG_MTD_NAND_IDS=y -+# CONFIG_MTD_NAND_JZ4740 is not set -+# CONFIG_MTD_NAND_MPC5121_NFC is not set -+# CONFIG_MTD_NAND_MTK is not set -+# CONFIG_MTD_NAND_MXC is not set -+# CONFIG_MTD_NAND_NANDSIM is not set -+# CONFIG_MTD_NAND_NDFC is not set -+# CONFIG_MTD_NAND_NUC900 is not set -+# CONFIG_MTD_NAND_OMAP2 is not set -+# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set -+# CONFIG_MTD_NAND_ORION is not set -+# CONFIG_MTD_NAND_PASEMI is not set -+# CONFIG_MTD_NAND_PLATFORM is not set -+# CONFIG_MTD_NAND_PXA3xx is not set -+# CONFIG_MTD_NAND_RB4XX is not set -+# CONFIG_MTD_NAND_RB750 is not set -+# CONFIG_MTD_NAND_RICOH is not set -+# CONFIG_MTD_NAND_S3C2410 is not set -+# CONFIG_MTD_NAND_SHARPSL is not set -+# CONFIG_MTD_NAND_SH_FLCTL is not set -+# CONFIG_MTD_NAND_SOCRATES is not set -+# CONFIG_MTD_NAND_TMIO is not set -+# CONFIG_MTD_NAND_TXX9NDFMC is not set -+CONFIG_MTD_OF_PARTS=y -+# CONFIG_MTD_ONENAND is not set -+# CONFIG_MTD_OOPS is not set -+# CONFIG_MTD_OTP is not set -+# CONFIG_MTD_PARTITIONED_MASTER is not set -+# CONFIG_MTD_PCI is not set -+# CONFIG_MTD_PCMCIA is not set -+# CONFIG_MTD_PHRAM is not set -+# CONFIG_MTD_PHYSMAP is not set -+# CONFIG_MTD_PHYSMAP_COMPAT is not set -+CONFIG_MTD_PHYSMAP_OF=y -+# CONFIG_MTD_PHYSMAP_OF_GEMINI is not set -+# CONFIG_MTD_PHYSMAP_OF_VERSATILE is not set -+# CONFIG_MTD_PLATRAM is not set -+# CONFIG_MTD_PMC551 is not set -+# CONFIG_MTD_RAM is not set -+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 -+# CONFIG_MTD_REDBOOT_PARTS is not set -+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set -+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set -+# CONFIG_MTD_ROM is not set -+CONFIG_MTD_ROOTFS_ROOT_DEV=y -+# CONFIG_MTD_ROUTERBOOT_PARTS is not set -+# CONFIG_MTD_SLRAM is not set -+# CONFIG_MTD_SM_COMMON is not set -+# CONFIG_MTD_SPINAND_MT29F is not set -+# CONFIG_MTD_SPI_NOR is not set -+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=4096 -+CONFIG_MTD_SPLIT=y -+# CONFIG_MTD_SPLIT_BCM_WFI_FW is not set -+# CONFIG_MTD_SPLIT_BRNIMAGE_FW is not set -+# CONFIG_MTD_SPLIT_EVA_FW is not set -+# CONFIG_MTD_SPLIT_FIRMWARE is not set -+CONFIG_MTD_SPLIT_FIRMWARE_NAME="firmware" -+# CONFIG_MTD_SPLIT_FIT_FW is not set -+# CONFIG_MTD_SPLIT_JIMAGE_FW is not set -+# CONFIG_MTD_SPLIT_LZMA_FW is not set -+# CONFIG_MTD_SPLIT_MINOR_FW is not set -+# CONFIG_MTD_SPLIT_SEAMA_FW is not set -+CONFIG_MTD_SPLIT_SQUASHFS_ROOT=y -+CONFIG_MTD_SPLIT_SUPPORT=y -+# CONFIG_MTD_SPLIT_TPLINK_FW is not set -+# CONFIG_MTD_SPLIT_TRX_FW is not set -+# CONFIG_MTD_SPLIT_UIMAGE_FW is not set -+# CONFIG_MTD_SPLIT_WRGG_FW is not set -+# CONFIG_MTD_SST25L is not set -+# CONFIG_MTD_SWAP is not set -+# CONFIG_MTD_TESTS is not set -+# CONFIG_MTD_UBI is not set -+# CONFIG_MTD_UIMAGE_SPLIT is not set -+# CONFIG_MTD_VIRT_CONCAT is not set -+CONFIG_MULTIUSER=y -+# CONFIG_MUTEX_SPIN_ON_OWNER is not set -+# CONFIG_MV643XX_ETH is not set -+# CONFIG_MVMDIO is not set -+# CONFIG_MVNETA_BM is not set -+# CONFIG_MVSW61XX_PHY is not set -+# CONFIG_MVSWITCH_PHY is not set -+# CONFIG_MV_XOR_V2 is not set -+# CONFIG_MWAVE is not set -+# CONFIG_MWL8K is not set -+# CONFIG_MXC4005 is not set -+# CONFIG_MXC6255 is not set -+# CONFIG_MYRI10GE is not set -+# CONFIG_NAMESPACES is not set -+# CONFIG_NATIONAL_PHY is not set -+# CONFIG_NATSEMI is not set -+# CONFIG_NAU7802 is not set -+# CONFIG_NBPFAXI_DMA is not set -+# CONFIG_NCP_FS is not set -+# CONFIG_NE2000 is not set -+# CONFIG_NE2K_PCI is not set -+# CONFIG_NEC_MARKEINS is not set -+CONFIG_NET=y -+# CONFIG_NETCONSOLE is not set -+CONFIG_NETDEVICES=y -+# CONFIG_NETFILTER is not set -+# CONFIG_NETFILTER_ADVANCED is not set -+# CONFIG_NETFILTER_DEBUG is not set -+# CONFIG_NETFILTER_INGRESS is not set -+# CONFIG_NETFILTER_NETLINK is not set -+# CONFIG_NETFILTER_NETLINK_ACCT is not set -+# CONFIG_NETFILTER_NETLINK_GLUE_CT is not set -+# CONFIG_NETFILTER_NETLINK_LOG is not set -+# CONFIG_NETFILTER_NETLINK_QUEUE is not set -+# CONFIG_NETFILTER_XTABLES is not set -+# CONFIG_NETFILTER_XT_CONNMARK is not set -+# CONFIG_NETFILTER_XT_MARK is not set -+# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set -+# CONFIG_NETFILTER_XT_MATCH_BPF is not set -+# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set -+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set -+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set -+# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set -+# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set -+# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set -+# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set -+# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set -+# CONFIG_NETFILTER_XT_MATCH_CPU is not set -+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set -+# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set -+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -+# CONFIG_NETFILTER_XT_MATCH_ECN is not set -+# CONFIG_NETFILTER_XT_MATCH_ESP is not set -+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set -+# CONFIG_NETFILTER_XT_MATCH_HELPER is not set -+# CONFIG_NETFILTER_XT_MATCH_HL is not set -+# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set -+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set -+# CONFIG_NETFILTER_XT_MATCH_L2TP is not set -+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set -+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set -+# CONFIG_NETFILTER_XT_MATCH_MAC is not set -+# CONFIG_NETFILTER_XT_MATCH_MARK is not set -+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set -+# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set -+# CONFIG_NETFILTER_XT_MATCH_OSF is not set -+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set -+# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set -+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set -+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set -+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set -+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set -+# CONFIG_NETFILTER_XT_MATCH_REALM is not set -+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set -+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set -+# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set -+# CONFIG_NETFILTER_XT_MATCH_STATE is not set -+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set -+# CONFIG_NETFILTER_XT_MATCH_STRING is not set -+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set -+# CONFIG_NETFILTER_XT_MATCH_TIME is not set -+# CONFIG_NETFILTER_XT_MATCH_U32 is not set -+# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set -+# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set -+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set -+# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set -+# CONFIG_NETFILTER_XT_TARGET_CT is not set -+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -+# CONFIG_NETFILTER_XT_TARGET_HL is not set -+# CONFIG_NETFILTER_XT_TARGET_HMARK is not set -+# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set -+# CONFIG_NETFILTER_XT_TARGET_LED is not set -+# CONFIG_NETFILTER_XT_TARGET_LOG is not set -+# CONFIG_NETFILTER_XT_TARGET_MARK is not set -+# CONFIG_NETFILTER_XT_TARGET_NETMAP is not set -+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set -+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set -+# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set -+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set -+# CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set -+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set -+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set -+# CONFIG_NETFILTER_XT_TARGET_TEE is not set -+# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set -+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set -+# CONFIG_NETLINK_DIAG is not set -+# CONFIG_NETLINK_MMAP is not set -+# CONFIG_NETPOLL is not set -+# CONFIG_NETROM is not set -+CONFIG_NETWORK_FILESYSTEMS=y -+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -+# CONFIG_NETWORK_SECMARK is not set -+# CONFIG_NETXEN_NIC is not set -+# CONFIG_NET_9P is not set -+# CONFIG_NET_ACT_BPF is not set -+# CONFIG_NET_ACT_CSUM is not set -+# CONFIG_NET_ACT_GACT is not set -+# CONFIG_NET_ACT_IFE is not set -+# CONFIG_NET_ACT_IPT is not set -+# CONFIG_NET_ACT_MIRRED is not set -+# CONFIG_NET_ACT_NAT is not set -+# CONFIG_NET_ACT_PEDIT is not set -+# CONFIG_NET_ACT_POLICE is not set -+# CONFIG_NET_ACT_SAMPLE is not set -+# CONFIG_NET_ACT_SIMP is not set -+# CONFIG_NET_ACT_SKBEDIT is not set -+# CONFIG_NET_ACT_SKBMOD is not set -+# CONFIG_NET_ACT_TUNNEL_KEY is not set -+# CONFIG_NET_ACT_VLAN is not set -+CONFIG_NET_CADENCE=y -+# CONFIG_NET_CALXEDA_XGMAC is not set -+CONFIG_NET_CLS=y -+# CONFIG_NET_CLS_ACT is not set -+# CONFIG_NET_CLS_BASIC is not set -+# CONFIG_NET_CLS_BPF is not set -+# CONFIG_NET_CLS_FLOW is not set -+# CONFIG_NET_CLS_FLOWER is not set -+# CONFIG_NET_CLS_FW is not set -+CONFIG_NET_CLS_IND=y -+# CONFIG_NET_CLS_MATCHALL is not set -+# CONFIG_NET_CLS_ROUTE4 is not set -+# CONFIG_NET_CLS_RSVP is not set -+# CONFIG_NET_CLS_RSVP6 is not set -+# CONFIG_NET_CLS_TCINDEX is not set -+# CONFIG_NET_CLS_U32 is not set -+CONFIG_NET_CORE=y -+# CONFIG_NET_DEVLINK is not set -+# CONFIG_NET_DROP_MONITOR is not set -+# CONFIG_NET_DSA is not set -+# CONFIG_NET_DSA_BCM_SF2 is not set -+# CONFIG_NET_DSA_LOOP is not set -+# CONFIG_NET_DSA_MT7530 is not set -+# CONFIG_NET_DSA_MV88E6060 is not set -+# CONFIG_NET_DSA_MV88E6123_61_65 is not set -+# CONFIG_NET_DSA_MV88E6131 is not set -+# CONFIG_NET_DSA_MV88E6171 is not set -+# CONFIG_NET_DSA_MV88E6352 is not set -+# CONFIG_NET_DSA_MV88E6XXX is not set -+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set -+# CONFIG_NET_DSA_QCA8K is not set -+# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set -+# CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set -+# CONFIG_NET_DSA_TAG_DSA is not set -+# CONFIG_NET_DSA_TAG_EDSA is not set -+# CONFIG_NET_EMATCH is not set -+# CONFIG_NET_EMATCH_CANID is not set -+# CONFIG_NET_EMATCH_CMP is not set -+# CONFIG_NET_EMATCH_META is not set -+# CONFIG_NET_EMATCH_NBYTE is not set -+CONFIG_NET_EMATCH_STACK=32 -+# CONFIG_NET_EMATCH_TEXT is not set -+# CONFIG_NET_EMATCH_U32 is not set -+# CONFIG_NET_FC is not set -+# CONFIG_NET_FOU is not set -+# CONFIG_NET_FOU_IP_TUNNELS is not set -+# CONFIG_NET_IFE is not set -+# CONFIG_NET_IPGRE is not set -+CONFIG_NET_IPGRE_BROADCAST=y -+# CONFIG_NET_IPGRE_DEMUX is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPVTI is not set -+# CONFIG_NET_IP_TUNNEL is not set -+# CONFIG_NET_KEY is not set -+# CONFIG_NET_KEY_MIGRATE is not set -+# CONFIG_NET_L3_MASTER_DEV is not set -+# CONFIG_NET_MPLS_GSO is not set -+# CONFIG_NET_NCSI is not set -+# CONFIG_NET_NSH is not set -+# CONFIG_NET_PACKET_ENGINE is not set -+# CONFIG_NET_PKTGEN is not set -+# CONFIG_NET_POLL_CONTROLLER is not set -+# CONFIG_NET_PTP_CLASSIFY is not set -+CONFIG_NET_RX_BUSY_POLL=y -+# CONFIG_NET_SB1000 is not set -+CONFIG_NET_SCHED=y -+# CONFIG_NET_SCH_ATM is not set -+# CONFIG_NET_SCH_CBQ is not set -+# CONFIG_NET_SCH_CHOKE is not set -+# CONFIG_NET_SCH_CODEL is not set -+# CONFIG_NET_SCH_DEFAULT is not set -+# CONFIG_NET_SCH_DRR is not set -+# CONFIG_NET_SCH_DSMARK is not set -+CONFIG_NET_SCH_FIFO=y -+# CONFIG_NET_SCH_FQ is not set -+CONFIG_NET_SCH_FQ_CODEL=y -+# CONFIG_NET_SCH_GRED is not set -+# CONFIG_NET_SCH_HFSC is not set -+# CONFIG_NET_SCH_HHF is not set -+# CONFIG_NET_SCH_HTB is not set -+# CONFIG_NET_SCH_INGRESS is not set -+# CONFIG_NET_SCH_MQPRIO is not set -+# CONFIG_NET_SCH_MULTIQ is not set -+# CONFIG_NET_SCH_NETEM is not set -+# CONFIG_NET_SCH_PIE is not set -+# CONFIG_NET_SCH_PLUG is not set -+# CONFIG_NET_SCH_PRIO is not set -+# CONFIG_NET_SCH_QFQ is not set -+# CONFIG_NET_SCH_RED is not set -+# CONFIG_NET_SCH_SFB is not set -+# CONFIG_NET_SCH_SFQ is not set -+# CONFIG_NET_SCH_TBF is not set -+# CONFIG_NET_SCH_TEQL is not set -+# CONFIG_NET_SCTPPROBE is not set -+# CONFIG_NET_SWITCHDEV is not set -+# CONFIG_NET_TCPPROBE is not set -+# CONFIG_NET_TEAM is not set -+# CONFIG_NET_TULIP is not set -+# CONFIG_NET_UDP_TUNNEL is not set -+CONFIG_NET_VENDOR_3COM=y -+CONFIG_NET_VENDOR_8390=y -+CONFIG_NET_VENDOR_ADAPTEC=y -+CONFIG_NET_VENDOR_AGERE=y -+CONFIG_NET_VENDOR_ALACRITECH=y -+CONFIG_NET_VENDOR_ALTEON=y -+CONFIG_NET_VENDOR_AMAZON=y -+CONFIG_NET_VENDOR_AMD=y -+CONFIG_NET_VENDOR_AQUANTIA=y -+CONFIG_NET_VENDOR_ARC=y -+CONFIG_NET_VENDOR_ATHEROS=y -+CONFIG_NET_VENDOR_AURORA=y -+CONFIG_NET_VENDOR_BROADCOM=y -+CONFIG_NET_VENDOR_BROCADE=y -+CONFIG_NET_VENDOR_CAVIUM=y -+CONFIG_NET_VENDOR_CHELSIO=y -+CONFIG_NET_VENDOR_CIRRUS=y -+CONFIG_NET_VENDOR_CISCO=y -+CONFIG_NET_VENDOR_DEC=y -+CONFIG_NET_VENDOR_DLINK=y -+CONFIG_NET_VENDOR_EMULEX=y -+CONFIG_NET_VENDOR_EXAR=y -+CONFIG_NET_VENDOR_EZCHIP=y -+CONFIG_NET_VENDOR_FARADAY=y -+CONFIG_NET_VENDOR_FREESCALE=y -+CONFIG_NET_VENDOR_FUJITSU=y -+CONFIG_NET_VENDOR_HISILICON=y -+CONFIG_NET_VENDOR_HP=y -+CONFIG_NET_VENDOR_HUAWEI=y -+CONFIG_NET_VENDOR_I825XX=y -+CONFIG_NET_VENDOR_IBM=y -+CONFIG_NET_VENDOR_INTEL=y -+CONFIG_NET_VENDOR_MARVELL=y -+CONFIG_NET_VENDOR_MELLANOX=y -+CONFIG_NET_VENDOR_MICREL=y -+CONFIG_NET_VENDOR_MICROCHIP=y -+CONFIG_NET_VENDOR_MYRI=y -+CONFIG_NET_VENDOR_NATSEMI=y -+CONFIG_NET_VENDOR_NETRONOME=y -+CONFIG_NET_VENDOR_NVIDIA=y -+CONFIG_NET_VENDOR_OKI=y -+CONFIG_NET_VENDOR_QLOGIC=y -+CONFIG_NET_VENDOR_QUALCOMM=y -+CONFIG_NET_VENDOR_RDC=y -+CONFIG_NET_VENDOR_REALTEK=y -+CONFIG_NET_VENDOR_RENESAS=y -+CONFIG_NET_VENDOR_ROCKER=y -+CONFIG_NET_VENDOR_SAMSUNG=y -+CONFIG_NET_VENDOR_SEEQ=y -+CONFIG_NET_VENDOR_SILAN=y -+CONFIG_NET_VENDOR_SIS=y -+CONFIG_NET_VENDOR_SMSC=y -+CONFIG_NET_VENDOR_SOLARFLARE=y -+CONFIG_NET_VENDOR_STMICRO=y -+CONFIG_NET_VENDOR_SUN=y -+CONFIG_NET_VENDOR_SYNOPSYS=y -+CONFIG_NET_VENDOR_TEHUTI=y -+CONFIG_NET_VENDOR_TI=y -+CONFIG_NET_VENDOR_TOSHIBA=y -+CONFIG_NET_VENDOR_VIA=y -+CONFIG_NET_VENDOR_WIZNET=y -+CONFIG_NET_VENDOR_XILINX=y -+CONFIG_NET_VENDOR_XIRCOM=y -+# CONFIG_NET_VRF is not set -+# CONFIG_NET_XGENE is not set -+CONFIG_NEW_LEDS=y -+# CONFIG_NFC is not set -+# CONFIG_NFP is not set -+# CONFIG_NFSD is not set -+# CONFIG_NFSD_V2_ACL is not set -+CONFIG_NFSD_V3=y -+# CONFIG_NFSD_V3_ACL is not set -+# CONFIG_NFSD_V4 is not set -+# CONFIG_NFS_ACL_SUPPORT is not set -+CONFIG_NFS_COMMON=y -+# CONFIG_NFS_FS is not set -+# CONFIG_NFS_FSCACHE is not set -+# CONFIG_NFS_SWAP is not set -+# CONFIG_NFS_V2 is not set -+CONFIG_NFS_V3=y -+# CONFIG_NFS_V3_ACL is not set -+# CONFIG_NFS_V4 is not set -+# CONFIG_NFS_V4_1 is not set -+# CONFIG_NFTL is not set -+# CONFIG_NFT_BRIDGE_META is not set -+# CONFIG_NFT_BRIDGE_REJECT is not set -+# CONFIG_NFT_DUP_IPV4 is not set -+# CONFIG_NFT_DUP_IPV6 is not set -+# CONFIG_NFT_FIB_IPV4 is not set -+# CONFIG_NFT_FIB_IPV6 is not set -+# CONFIG_NFT_FIB_NETDEV is not set -+# CONFIG_NFT_FLOW_OFFLOAD is not set -+# CONFIG_NFT_OBJREF is not set -+# CONFIG_NFT_RT is not set -+# CONFIG_NFT_SET_BITMAP is not set -+# CONFIG_NF_CONNTRACK is not set -+# CONFIG_NF_CONNTRACK_AMANDA is not set -+# CONFIG_NF_CONNTRACK_EVENTS is not set -+# CONFIG_NF_CONNTRACK_FTP is not set -+# CONFIG_NF_CONNTRACK_H323 is not set -+# CONFIG_NF_CONNTRACK_IPV4 is not set -+# CONFIG_NF_CONNTRACK_IPV6 is not set -+# CONFIG_NF_CONNTRACK_IRC is not set -+# CONFIG_NF_CONNTRACK_MARK is not set -+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set -+# CONFIG_NF_CONNTRACK_PPTP is not set -+CONFIG_NF_CONNTRACK_PROCFS=y -+# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set -+# CONFIG_NF_CONNTRACK_SANE is not set -+# CONFIG_NF_CONNTRACK_SIP is not set -+# CONFIG_NF_CONNTRACK_SNMP is not set -+# CONFIG_NF_CONNTRACK_TFTP is not set -+# CONFIG_NF_CONNTRACK_TIMEOUT is not set -+# CONFIG_NF_CONNTRACK_TIMESTAMP is not set -+# CONFIG_NF_CONNTRACK_ZONES is not set -+# CONFIG_NF_CT_NETLINK is not set -+# CONFIG_NF_CT_NETLINK_TIMEOUT is not set -+# CONFIG_NF_CT_PROTO_DCCP is not set -+# CONFIG_NF_CT_PROTO_GRE is not set -+# CONFIG_NF_CT_PROTO_SCTP is not set -+# CONFIG_NF_CT_PROTO_UDPLITE is not set -+# CONFIG_NF_DEFRAG_IPV4 is not set -+# CONFIG_NF_DUP_IPV4 is not set -+# CONFIG_NF_DUP_IPV6 is not set -+# CONFIG_NF_FLOW_TABLE is not set -+# CONFIG_NF_LOG_ARP is not set -+# CONFIG_NF_LOG_IPV4 is not set -+# CONFIG_NF_LOG_NETDEV is not set -+# CONFIG_NF_NAT is not set -+# CONFIG_NF_NAT_AMANDA is not set -+# CONFIG_NF_NAT_FTP is not set -+# CONFIG_NF_NAT_H323 is not set -+# CONFIG_NF_NAT_IPV6 is not set -+# CONFIG_NF_NAT_IRC is not set -+# CONFIG_NF_NAT_MASQUERADE_IPV4 is not set -+# CONFIG_NF_NAT_MASQUERADE_IPV6 is not set -+# CONFIG_NF_NAT_NEEDED is not set -+# CONFIG_NF_NAT_PPTP is not set -+# CONFIG_NF_NAT_PROTO_GRE is not set -+# CONFIG_NF_NAT_SIP is not set -+# CONFIG_NF_NAT_SNMP_BASIC is not set -+# CONFIG_NF_NAT_TFTP is not set -+# CONFIG_NF_REJECT_IPV4 is not set -+# CONFIG_NF_REJECT_IPV6 is not set -+# CONFIG_NF_SOCKET_IPV4 is not set -+# CONFIG_NF_SOCKET_IPV6 is not set -+# CONFIG_NF_TABLES is not set -+# CONFIG_NF_TABLES_NETDEV is not set -+# CONFIG_NI65 is not set -+# CONFIG_NI903X_WDT is not set -+# CONFIG_NIC7018_WDT is not set -+# CONFIG_NILFS2_FS is not set -+# CONFIG_NIU is not set -+CONFIG_NLATTR=y -+# CONFIG_NLMON is not set -+# CONFIG_NLM_XLP_BOARD is not set -+# CONFIG_NLM_XLR_BOARD is not set -+# CONFIG_NLS is not set -+# CONFIG_NLS_ASCII is not set -+# CONFIG_NLS_CODEPAGE_1250 is not set -+# CONFIG_NLS_CODEPAGE_1251 is not set -+# CONFIG_NLS_CODEPAGE_437 is not set -+# CONFIG_NLS_CODEPAGE_737 is not set -+# CONFIG_NLS_CODEPAGE_775 is not set -+# CONFIG_NLS_CODEPAGE_850 is not set -+# CONFIG_NLS_CODEPAGE_852 is not set -+# CONFIG_NLS_CODEPAGE_855 is not set -+# CONFIG_NLS_CODEPAGE_857 is not set -+# CONFIG_NLS_CODEPAGE_860 is not set -+# CONFIG_NLS_CODEPAGE_861 is not set -+# CONFIG_NLS_CODEPAGE_862 is not set -+# CONFIG_NLS_CODEPAGE_863 is not set -+# CONFIG_NLS_CODEPAGE_864 is not set -+# CONFIG_NLS_CODEPAGE_865 is not set -+# CONFIG_NLS_CODEPAGE_866 is not set -+# CONFIG_NLS_CODEPAGE_869 is not set -+# CONFIG_NLS_CODEPAGE_874 is not set -+# CONFIG_NLS_CODEPAGE_932 is not set -+# CONFIG_NLS_CODEPAGE_936 is not set -+# CONFIG_NLS_CODEPAGE_949 is not set -+# CONFIG_NLS_CODEPAGE_950 is not set -+CONFIG_NLS_DEFAULT="iso8859-1" -+# CONFIG_NLS_ISO8859_1 is not set -+# CONFIG_NLS_ISO8859_13 is not set -+# CONFIG_NLS_ISO8859_14 is not set -+# CONFIG_NLS_ISO8859_15 is not set -+# CONFIG_NLS_ISO8859_2 is not set -+# CONFIG_NLS_ISO8859_3 is not set -+# CONFIG_NLS_ISO8859_4 is not set -+# CONFIG_NLS_ISO8859_5 is not set -+# CONFIG_NLS_ISO8859_6 is not set -+# CONFIG_NLS_ISO8859_7 is not set -+# CONFIG_NLS_ISO8859_8 is not set -+# CONFIG_NLS_ISO8859_9 is not set -+# CONFIG_NLS_KOI8_R is not set -+# CONFIG_NLS_KOI8_U is not set -+# CONFIG_NLS_MAC_CELTIC is not set -+# CONFIG_NLS_MAC_CENTEURO is not set -+# CONFIG_NLS_MAC_CROATIAN is not set -+# CONFIG_NLS_MAC_CYRILLIC is not set -+# CONFIG_NLS_MAC_GAELIC is not set -+# CONFIG_NLS_MAC_GREEK is not set -+# CONFIG_NLS_MAC_ICELAND is not set -+# CONFIG_NLS_MAC_INUIT is not set -+# CONFIG_NLS_MAC_ROMAN is not set -+# CONFIG_NLS_MAC_ROMANIAN is not set -+# CONFIG_NLS_MAC_TURKISH is not set -+# CONFIG_NLS_UTF8 is not set -+CONFIG_NMI_LOG_BUF_SHIFT=13 -+# CONFIG_NOP_USB_XCEIV is not set -+# CONFIG_NORTEL_HERMES is not set -+# CONFIG_NOTIFIER_ERROR_INJECTION is not set -+# CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT is not set -+# CONFIG_NOZOMI is not set -+# CONFIG_NO_BOOTMEM is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_NO_HZ_FULL is not set -+# CONFIG_NO_HZ_IDLE is not set -+# CONFIG_NS83820 is not set -+# CONFIG_NTB is not set -+# CONFIG_NTFS_DEBUG is not set -+# CONFIG_NTFS_FS is not set -+# CONFIG_NTFS_RW is not set -+# CONFIG_NTP_PPS is not set -+# CONFIG_NVM is not set -+# CONFIG_NVMEM is not set -+# CONFIG_NVMEM_BCM_OCOTP is not set -+# CONFIG_NVMEM_IMX_OCOTP is not set -+# CONFIG_NVME_FC is not set -+# CONFIG_NVME_TARGET is not set -+# CONFIG_NVRAM is not set -+# CONFIG_NV_TCO is not set -+# CONFIG_NXP_STB220 is not set -+# CONFIG_NXP_STB225 is not set -+# CONFIG_N_GSM is not set -+# CONFIG_OABI_COMPAT is not set -+# CONFIG_OBS600 is not set -+# CONFIG_OCFS2_FS is not set -+# CONFIG_OF_OVERLAY is not set -+# CONFIG_OF_UNITTEST is not set -+# CONFIG_OMAP2_DSS_DEBUG is not set -+# CONFIG_OMAP2_DSS_DEBUGFS is not set -+# CONFIG_OMAP2_DSS_SDI is not set -+# CONFIG_OMAP_OCP2SCP is not set -+# CONFIG_OMAP_USB2 is not set -+# CONFIG_OMFS_FS is not set -+# CONFIG_OPENVSWITCH is not set -+# CONFIG_OPROFILE is not set -+# CONFIG_OPROFILE_EVENT_MULTIPLEX is not set -+# CONFIG_OPT3001 is not set -+CONFIG_OPTIMIZE_INLINING=y -+# CONFIG_ORANGEFS_FS is not set -+# CONFIG_ORION_WATCHDOG is not set -+# CONFIG_OSF_PARTITION is not set -+CONFIG_OVERLAY_FS=y -+# CONFIG_OVERLAY_FS_INDEX is not set -+# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set -+# CONFIG_OWL_LOADER is not set -+# CONFIG_P54_COMMON is not set -+# CONFIG_PA12203001 is not set -+CONFIG_PACKET=y -+# CONFIG_PACKET_DIAG is not set -+# CONFIG_PAGE_EXTENSION is not set -+# CONFIG_PAGE_OWNER is not set -+# CONFIG_PAGE_POISONING is not set -+# CONFIG_PAGE_SIZE_16KB is not set -+# CONFIG_PAGE_SIZE_32KB is not set -+CONFIG_PAGE_SIZE_4KB=y -+# CONFIG_PAGE_SIZE_64KB is not set -+# CONFIG_PAGE_SIZE_8KB is not set -+# CONFIG_PALMAS_GPADC is not set -+# CONFIG_PANASONIC_LAPTOP is not set -+# CONFIG_PANEL is not set -+CONFIG_PANIC_ON_OOPS=y -+CONFIG_PANIC_ON_OOPS_VALUE=1 -+CONFIG_PANIC_TIMEOUT=1 -+# CONFIG_PANTHERLORD_FF is not set -+# CONFIG_PARAVIRT is not set -+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -+# CONFIG_PARPORT is not set -+# CONFIG_PARPORT_1284 is not set -+# CONFIG_PARPORT_AX88796 is not set -+# CONFIG_PARPORT_GSC is not set -+# CONFIG_PARPORT_PC is not set -+CONFIG_PARTITION_ADVANCED=y -+# CONFIG_PATA_ALI is not set -+# CONFIG_PATA_AMD is not set -+# CONFIG_PATA_ARASAN_CF is not set -+# CONFIG_PATA_ARTOP is not set -+# CONFIG_PATA_ATIIXP is not set -+# CONFIG_PATA_ATP867X is not set -+# CONFIG_PATA_CMD640_PCI is not set -+# CONFIG_PATA_CMD64X is not set -+# CONFIG_PATA_CS5520 is not set -+# CONFIG_PATA_CS5530 is not set -+# CONFIG_PATA_CS5535 is not set -+# CONFIG_PATA_CS5536 is not set -+# CONFIG_PATA_CYPRESS is not set -+# CONFIG_PATA_EFAR is not set -+# CONFIG_PATA_HPT366 is not set -+# CONFIG_PATA_HPT37X is not set -+# CONFIG_PATA_HPT3X2N is not set -+# CONFIG_PATA_HPT3X3 is not set -+# CONFIG_PATA_IMX is not set -+# CONFIG_PATA_ISAPNP is not set -+# CONFIG_PATA_IT8213 is not set -+# CONFIG_PATA_IT821X is not set -+# CONFIG_PATA_JMICRON is not set -+# CONFIG_PATA_LEGACY is not set -+# CONFIG_PATA_MARVELL is not set -+# CONFIG_PATA_MPIIX is not set -+# CONFIG_PATA_NETCELL is not set -+# CONFIG_PATA_NINJA32 is not set -+# CONFIG_PATA_NS87410 is not set -+# CONFIG_PATA_NS87415 is not set -+# CONFIG_PATA_OCTEON_CF is not set -+# CONFIG_PATA_OF_PLATFORM is not set -+# CONFIG_PATA_OLDPIIX is not set -+# CONFIG_PATA_OPTI is not set -+# CONFIG_PATA_OPTIDMA is not set -+# CONFIG_PATA_PCMCIA is not set -+# CONFIG_PATA_PDC2027X is not set -+# CONFIG_PATA_PDC_OLD is not set -+# CONFIG_PATA_PLATFORM is not set -+# CONFIG_PATA_QDI is not set -+# CONFIG_PATA_RADISYS is not set -+# CONFIG_PATA_RDC is not set -+# CONFIG_PATA_RZ1000 is not set -+# CONFIG_PATA_SC1200 is not set -+# CONFIG_PATA_SCH is not set -+# CONFIG_PATA_SERVERWORKS is not set -+# CONFIG_PATA_SIL680 is not set -+# CONFIG_PATA_SIS is not set -+# CONFIG_PATA_TOSHIBA is not set -+# CONFIG_PATA_TRIFLEX is not set -+# CONFIG_PATA_VIA is not set -+# CONFIG_PATA_WINBOND is not set -+# CONFIG_PATA_WINBOND_VLB is not set -+# CONFIG_PC104 is not set -+# CONFIG_PC300TOO is not set -+# CONFIG_PCCARD is not set -+# CONFIG_PCH_DMA is not set -+# CONFIG_PCH_GBE is not set -+# CONFIG_PCH_PHUB is not set -+# CONFIG_PCI is not set -+# CONFIG_PCI200SYN is not set -+# CONFIG_PCIEAER_INJECT is not set -+# CONFIG_PCIEASPM is not set -+# CONFIG_PCIEPORTBUS is not set -+# CONFIG_PCIE_ALTERA is not set -+# CONFIG_PCIE_ARMADA_8K is not set -+# CONFIG_PCIE_DPC is not set -+# CONFIG_PCIE_DW_PLAT is not set -+# CONFIG_PCIE_ECRC is not set -+# CONFIG_PCIE_IPROC is not set -+# CONFIG_PCIE_KIRIN is not set -+# CONFIG_PCIE_PTM is not set -+# CONFIG_PCIPCWATCHDOG is not set -+# CONFIG_PCI_ATMEL is not set -+# CONFIG_PCI_CNB20LE_QUIRK is not set -+# CONFIG_PCI_DEBUG is not set -+# CONFIG_PCI_DISABLE_COMMON_QUIRKS is not set -+# CONFIG_PCI_ENDPOINT is not set -+# CONFIG_PCI_ENDPOINT_TEST is not set -+# CONFIG_PCI_FTPCI100 is not set -+# CONFIG_PCI_HERMES is not set -+# CONFIG_PCI_HISI is not set -+# CONFIG_PCI_HOST_GENERIC is not set -+# CONFIG_PCI_HOST_THUNDER_ECAM is not set -+# CONFIG_PCI_HOST_THUNDER_PEM is not set -+# CONFIG_PCI_IOV is not set -+# CONFIG_PCI_LAYERSCAPE is not set -+# CONFIG_PCI_MSI is not set -+# CONFIG_PCI_PASID is not set -+# CONFIG_PCI_PRI is not set -+CONFIG_PCI_QUIRKS=y -+# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set -+# CONFIG_PCI_STUB is not set -+# CONFIG_PCI_SW_SWITCHTEC is not set -+CONFIG_PCI_SYSCALL=y -+# CONFIG_PCI_XGENE is not set -+# CONFIG_PCMCIA is not set -+# CONFIG_PCMCIA_3C574 is not set -+# CONFIG_PCMCIA_3C589 is not set -+# CONFIG_PCMCIA_AHA152X is not set -+# CONFIG_PCMCIA_ATMEL is not set -+# CONFIG_PCMCIA_AXNET is not set -+# CONFIG_PCMCIA_DEBUG is not set -+# CONFIG_PCMCIA_FDOMAIN is not set -+# CONFIG_PCMCIA_FMVJ18X is not set -+# CONFIG_PCMCIA_HERMES is not set -+# CONFIG_PCMCIA_LOAD_CIS is not set -+# CONFIG_PCMCIA_NINJA_SCSI is not set -+# CONFIG_PCMCIA_NMCLAN is not set -+# CONFIG_PCMCIA_PCNET is not set -+# CONFIG_PCMCIA_QLOGIC is not set -+# CONFIG_PCMCIA_RAYCS is not set -+# CONFIG_PCMCIA_SMC91C92 is not set -+# CONFIG_PCMCIA_SPECTRUM is not set -+# CONFIG_PCMCIA_SYM53C500 is not set -+# CONFIG_PCMCIA_WL3501 is not set -+# CONFIG_PCMCIA_XIRC2PS is not set -+# CONFIG_PCMCIA_XIRCOM is not set -+# CONFIG_PCNET32 is not set -+# CONFIG_PCSPKR_PLATFORM is not set -+# CONFIG_PD6729 is not set -+# CONFIG_PDA_POWER is not set -+# CONFIG_PDC_ADMA is not set -+# CONFIG_PERCPU_STATS is not set -+# CONFIG_PERCPU_TEST is not set -+# CONFIG_PERF_EVENTS is not set -+# CONFIG_PERF_EVENTS_AMD_POWER is not set -+# CONFIG_PERSISTENT_KEYRINGS is not set -+# CONFIG_PHANTOM is not set -+# CONFIG_PHONET is not set -+# CONFIG_PHYLIB is not set -+# CONFIG_PHYS_ADDR_T_64BIT is not set -+# CONFIG_PHY_CPCAP_USB is not set -+# CONFIG_PHY_EXYNOS_DP_VIDEO is not set -+# CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set -+# CONFIG_PHY_PXA_28NM_HSIC is not set -+# CONFIG_PHY_PXA_28NM_USB2 is not set -+# CONFIG_PHY_QCOM_DWC3 is not set -+# CONFIG_PHY_SAMSUNG_USB2 is not set -+# CONFIG_PHY_XGENE is not set -+# CONFIG_PI433 is not set -+# CONFIG_PID_IN_CONTEXTIDR is not set -+# CONFIG_PID_NS is not set -+CONFIG_PINCONF=y -+# CONFIG_PINCTRL is not set -+# CONFIG_PINCTRL_AMD is not set -+# CONFIG_PINCTRL_EXYNOS is not set -+# CONFIG_PINCTRL_EXYNOS5440 is not set -+# CONFIG_PINCTRL_MCP23S08 is not set -+# CONFIG_PINCTRL_MSM8X74 is not set -+CONFIG_PINCTRL_SINGLE=y -+# CONFIG_PINCTRL_SX150X is not set -+CONFIG_PINMUX=y -+# CONFIG_PKCS7_MESSAGE_PARSER is not set -+# CONFIG_PL320_MBOX is not set -+# CONFIG_PL330_DMA is not set -+# CONFIG_PLATFORM_MHU is not set -+# CONFIG_PLAT_SPEAR is not set -+# CONFIG_PLIP is not set -+# CONFIG_PLX_HERMES is not set -+# CONFIG_PM is not set -+# CONFIG_PMBUS is not set -+# CONFIG_PMC_MSP is not set -+# CONFIG_PMIC_ADP5520 is not set -+# CONFIG_PMIC_DA903X is not set -+# CONFIG_PM_AUTOSLEEP is not set -+# CONFIG_PM_DEVFREQ is not set -+# CONFIG_PM_WAKELOCKS is not set -+# CONFIG_POSIX_MQUEUE is not set -+CONFIG_POSIX_TIMERS=y -+# CONFIG_POWERCAP is not set -+# CONFIG_POWER_AVS is not set -+# CONFIG_POWER_RESET is not set -+# CONFIG_POWER_RESET_BRCMKONA is not set -+# CONFIG_POWER_RESET_BRCMSTB is not set -+# CONFIG_POWER_RESET_GPIO is not set -+# CONFIG_POWER_RESET_GPIO_RESTART is not set -+# CONFIG_POWER_RESET_LTC2952 is not set -+# CONFIG_POWER_RESET_PIIX4_POWEROFF is not set -+# CONFIG_POWER_RESET_RESTART is not set -+# CONFIG_POWER_RESET_SYSCON is not set -+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set -+# CONFIG_POWER_RESET_VERSATILE is not set -+# CONFIG_POWER_RESET_XGENE is not set -+# CONFIG_POWER_SUPPLY is not set -+# CONFIG_POWER_SUPPLY_DEBUG is not set -+# CONFIG_PPC4xx_GPIO is not set -+# CONFIG_PPC_16K_PAGES is not set -+# CONFIG_PPC_256K_PAGES is not set -+CONFIG_PPC_4K_PAGES=y -+# CONFIG_PPC_64K_PAGES is not set -+# CONFIG_PPC_DISABLE_WERROR is not set -+# CONFIG_PPC_EMULATED_STATS is not set -+# CONFIG_PPC_EPAPR_HV_BYTECHAN is not set -+# CONFIG_PPP is not set -+# CONFIG_PPPOATM is not set -+# CONFIG_PPPOE is not set -+# CONFIG_PPPOL2TP is not set -+# CONFIG_PPP_ASYNC is not set -+# CONFIG_PPP_BSDCOMP is not set -+# CONFIG_PPP_DEFLATE is not set -+CONFIG_PPP_FILTER=y -+# CONFIG_PPP_MPPE is not set -+CONFIG_PPP_MULTILINK=y -+# CONFIG_PPP_SYNC_TTY is not set -+# CONFIG_PPS is not set -+# CONFIG_PPS_CLIENT_GPIO is not set -+# CONFIG_PPS_CLIENT_KTIMER is not set -+# CONFIG_PPS_CLIENT_LDISC is not set -+# CONFIG_PPS_CLIENT_PARPORT is not set -+# CONFIG_PPS_DEBUG is not set -+# CONFIG_PPTP is not set -+# CONFIG_PREEMPT is not set -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_TRACER is not set -+# CONFIG_PREEMPT_VOLUNTARY is not set -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+CONFIG_PRINTK=y -+CONFIG_PRINTK_NMI=y -+CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 -+# CONFIG_PRINTK_TIME is not set -+CONFIG_PRINT_STACK_DEPTH=64 -+# CONFIG_PRISM2_USB is not set -+# CONFIG_PRISM54 is not set -+# CONFIG_PROC_CHILDREN is not set -+CONFIG_PROC_FS=y -+# CONFIG_PROC_KCORE is not set -+# CONFIG_PROC_PAGE_MONITOR is not set -+CONFIG_PROC_STRIPPED=y -+CONFIG_PROC_SYSCTL=y -+# CONFIG_PROFILE_ALL_BRANCHES is not set -+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -+# CONFIG_PROFILING is not set -+# CONFIG_PROVE_LOCKING is not set -+# CONFIG_PROVE_RCU is not set -+# CONFIG_PROVE_RCU_REPEATEDLY is not set -+# CONFIG_PSAMPLE is not set -+# CONFIG_PSB6970_PHY is not set -+# CONFIG_PSTORE is not set -+# CONFIG_PTP_1588_CLOCK is not set -+# CONFIG_PTP_1588_CLOCK_IXP46X is not set -+# CONFIG_PTP_1588_CLOCK_KVM is not set -+# CONFIG_PTP_1588_CLOCK_PCH is not set -+# CONFIG_PUBLIC_KEY_ALGO_RSA is not set -+# CONFIG_PWM is not set -+# CONFIG_PWM_FSL_FTM is not set -+# CONFIG_PWM_PCA9685 is not set -+CONFIG_PWRSEQ_EMMC=y -+# CONFIG_PWRSEQ_SD8787 is not set -+CONFIG_PWRSEQ_SIMPLE=y -+# CONFIG_QCA7000 is not set -+# CONFIG_QCA7000_SPI is not set -+# CONFIG_QCA7000_UART is not set -+# CONFIG_QCOM_EMAC is not set -+# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set -+# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set -+# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set -+# CONFIG_QCOM_HIDMA is not set -+# CONFIG_QCOM_HIDMA_MGMT is not set -+# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set -+# CONFIG_QCOM_SPMI_IADC is not set -+# CONFIG_QCOM_SPMI_TEMP_ALARM is not set -+# CONFIG_QCOM_SPMI_VADC is not set -+# CONFIG_QED is not set -+# CONFIG_QLA3XXX is not set -+# CONFIG_QLCNIC is not set -+# CONFIG_QLGE is not set -+# CONFIG_QNX4FS_FS is not set -+# CONFIG_QNX6FS_FS is not set -+# CONFIG_QORIQ_CPUFREQ is not set -+# CONFIG_QORIQ_THERMAL is not set -+# CONFIG_QSEMI_PHY is not set -+# CONFIG_QUEUED_LOCK_STAT is not set -+# CONFIG_QUOTA is not set -+# CONFIG_QUOTACTL is not set -+# CONFIG_QUOTA_DEBUG is not set -+# CONFIG_R3964 is not set -+# CONFIG_R6040 is not set -+# CONFIG_R8169 is not set -+# CONFIG_R8188EU is not set -+# CONFIG_R8712U is not set -+# CONFIG_R8723AU is not set -+# CONFIG_RADIO_ADAPTERS is not set -+# CONFIG_RADIO_AZTECH is not set -+# CONFIG_RADIO_CADET is not set -+# CONFIG_RADIO_GEMTEK is not set -+# CONFIG_RADIO_MAXIRADIO is not set -+# CONFIG_RADIO_RTRACK is not set -+# CONFIG_RADIO_RTRACK2 is not set -+# CONFIG_RADIO_SF16FMI is not set -+# CONFIG_RADIO_SF16FMR2 is not set -+# CONFIG_RADIO_TERRATEC is not set -+# CONFIG_RADIO_TRUST is not set -+# CONFIG_RADIO_TYPHOON is not set -+# CONFIG_RADIO_ZOLTRIX is not set -+# CONFIG_RAID_ATTRS is not set -+# CONFIG_RALINK is not set -+# CONFIG_RANDOM32_SELFTEST is not set -+# CONFIG_RAPIDIO is not set -+# CONFIG_RAS is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_RBTREE_TEST is not set -+CONFIG_RCU_CPU_STALL_TIMEOUT=60 -+# CONFIG_RCU_EQS_DEBUG is not set -+# CONFIG_RCU_EXPEDITE_BOOT is not set -+CONFIG_RCU_EXPERT=y -+CONFIG_RCU_FANOUT=32 -+CONFIG_RCU_FANOUT_LEAF=16 -+# CONFIG_RCU_FAST_NO_HZ is not set -+CONFIG_RCU_KTHREAD_PRIO=0 -+# CONFIG_RCU_NOCB_CPU is not set -+# CONFIG_RCU_PERF_TEST is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY=3 -+# CONFIG_RCU_TRACE is not set -+# CONFIG_RC_ATI_REMOTE is not set -+# CONFIG_RC_CORE is not set -+# CONFIG_RC_DECODERS is not set -+# CONFIG_RC_LOOPBACK is not set -+# CONFIG_RC_MAP is not set -+# CONFIG_RDS is not set -+# CONFIG_RD_BZIP2 is not set -+# CONFIG_RD_GZIP is not set -+# CONFIG_RD_LZ4 is not set -+# CONFIG_RD_LZMA is not set -+# CONFIG_RD_LZO is not set -+# CONFIG_RD_XZ is not set -+# CONFIG_READABLE_ASM is not set -+# CONFIG_REALTEK_PHY is not set -+# CONFIG_REDWOOD is not set -+# CONFIG_REFCOUNT_FULL is not set -+# CONFIG_REGMAP is not set -+# CONFIG_REGMAP_I2C is not set -+# CONFIG_REGMAP_MMIO is not set -+# CONFIG_REGMAP_SPI is not set -+# CONFIG_REGULATOR is not set -+# CONFIG_REGULATOR_ACT8865 is not set -+# CONFIG_REGULATOR_AD5398 is not set -+# CONFIG_REGULATOR_ANATOP is not set -+# CONFIG_REGULATOR_DA9210 is not set -+# CONFIG_REGULATOR_DA9211 is not set -+# CONFIG_REGULATOR_DEBUG is not set -+# CONFIG_REGULATOR_FAN53555 is not set -+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set -+# CONFIG_REGULATOR_GPIO is not set -+# CONFIG_REGULATOR_ISL6271A is not set -+# CONFIG_REGULATOR_ISL9305 is not set -+# CONFIG_REGULATOR_LP3971 is not set -+# CONFIG_REGULATOR_LP3972 is not set -+# CONFIG_REGULATOR_LP872X is not set -+# CONFIG_REGULATOR_LP8755 is not set -+# CONFIG_REGULATOR_LTC3589 is not set -+# CONFIG_REGULATOR_LTC3676 is not set -+# CONFIG_REGULATOR_MAX1586 is not set -+# CONFIG_REGULATOR_MAX8649 is not set -+# CONFIG_REGULATOR_MAX8660 is not set -+# CONFIG_REGULATOR_MAX8952 is not set -+# CONFIG_REGULATOR_MAX8973 is not set -+# CONFIG_REGULATOR_MT6311 is not set -+# CONFIG_REGULATOR_PFUZE100 is not set -+# CONFIG_REGULATOR_PV88060 is not set -+# CONFIG_REGULATOR_PV88080 is not set -+# CONFIG_REGULATOR_PV88090 is not set -+# CONFIG_REGULATOR_PWM is not set -+# CONFIG_REGULATOR_TI_ABB is not set -+# CONFIG_REGULATOR_TPS51632 is not set -+# CONFIG_REGULATOR_TPS62360 is not set -+# CONFIG_REGULATOR_TPS65023 is not set -+# CONFIG_REGULATOR_TPS6507X is not set -+# CONFIG_REGULATOR_TPS65132 is not set -+# CONFIG_REGULATOR_TPS6524X is not set -+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set -+# CONFIG_REGULATOR_VCTRL is not set -+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set -+# CONFIG_REISERFS_CHECK is not set -+# CONFIG_REISERFS_FS is not set -+# CONFIG_REISERFS_FS_POSIX_ACL is not set -+# CONFIG_REISERFS_FS_SECURITY is not set -+# CONFIG_REISERFS_FS_XATTR is not set -+# CONFIG_REISERFS_PROC_INFO is not set -+# CONFIG_RELAY is not set -+# CONFIG_RELOCATABLE is not set -+# CONFIG_REMOTEPROC is not set -+# CONFIG_RESET_ATH79 is not set -+# CONFIG_RESET_BERLIN is not set -+# CONFIG_RESET_CONTROLLER is not set -+# CONFIG_RESET_IMX7 is not set -+# CONFIG_RESET_LANTIQ is not set -+# CONFIG_RESET_LPC18XX is not set -+# CONFIG_RESET_MESON is not set -+# CONFIG_RESET_PISTACHIO is not set -+# CONFIG_RESET_SOCFPGA is not set -+# CONFIG_RESET_STM32 is not set -+# CONFIG_RESET_SUNXI is not set -+# CONFIG_RESET_TEGRA_BPMP is not set -+# CONFIG_RESET_TI_SYSCON is not set -+# CONFIG_RESET_ZYNQ is not set -+# CONFIG_RFD_FTL is not set -+CONFIG_RFKILL=y -+# CONFIG_RFKILL_FULL is not set -+# CONFIG_RFKILL_GPIO is not set -+# CONFIG_RFKILL_INPUT is not set -+# CONFIG_RFKILL_LEDS is not set -+# CONFIG_RFKILL_REGULATOR is not set -+# CONFIG_RING_BUFFER_BENCHMARK is not set -+# CONFIG_RING_BUFFER_STARTUP_TEST is not set -+# CONFIG_RMI4_CORE is not set -+# CONFIG_RMNET is not set -+# CONFIG_ROCKCHIP_PHY is not set -+# CONFIG_ROCKER is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_ROSE is not set -+# CONFIG_RPCSEC_GSS_KRB5 is not set -+# CONFIG_RPMSG_QCOM_GLINK_RPM is not set -+# CONFIG_RPR0521 is not set -+# CONFIG_RT2X00 is not set -+# CONFIG_RTC_CLASS is not set -+# CONFIG_RTC_DEBUG is not set -+# CONFIG_RTC_DRV_ABB5ZES3 is not set -+# CONFIG_RTC_DRV_ABX80X is not set -+# CONFIG_RTC_DRV_ARMADA38X is not set -+# CONFIG_RTC_DRV_AU1XXX is not set -+# CONFIG_RTC_DRV_BQ32K is not set -+# CONFIG_RTC_DRV_BQ4802 is not set -+CONFIG_RTC_DRV_CMOS=y -+# CONFIG_RTC_DRV_DS1286 is not set -+# CONFIG_RTC_DRV_DS1302 is not set -+# CONFIG_RTC_DRV_DS1305 is not set -+# CONFIG_RTC_DRV_DS1307 is not set -+# CONFIG_RTC_DRV_DS1307_CENTURY is not set -+# CONFIG_RTC_DRV_DS1307_HWMON is not set -+# CONFIG_RTC_DRV_DS1343 is not set -+# CONFIG_RTC_DRV_DS1347 is not set -+# CONFIG_RTC_DRV_DS1374 is not set -+# CONFIG_RTC_DRV_DS1390 is not set -+# CONFIG_RTC_DRV_DS1511 is not set -+# CONFIG_RTC_DRV_DS1553 is not set -+# CONFIG_RTC_DRV_DS1672 is not set -+# CONFIG_RTC_DRV_DS1685_FAMILY is not set -+# CONFIG_RTC_DRV_DS1742 is not set -+# CONFIG_RTC_DRV_DS2404 is not set -+# CONFIG_RTC_DRV_DS3232 is not set -+# CONFIG_RTC_DRV_DS3234 is not set -+# CONFIG_RTC_DRV_EM3027 is not set -+# CONFIG_RTC_DRV_EP93XX is not set -+# CONFIG_RTC_DRV_FM3130 is not set -+# CONFIG_RTC_DRV_FTRTC010 is not set -+# CONFIG_RTC_DRV_GENERIC is not set -+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set -+# CONFIG_RTC_DRV_HYM8563 is not set -+# CONFIG_RTC_DRV_ISL12022 is not set -+# CONFIG_RTC_DRV_ISL12057 is not set -+# CONFIG_RTC_DRV_ISL1208 is not set -+# CONFIG_RTC_DRV_M41T80 is not set -+# CONFIG_RTC_DRV_M41T93 is not set -+# CONFIG_RTC_DRV_M41T94 is not set -+# CONFIG_RTC_DRV_M48T35 is not set -+# CONFIG_RTC_DRV_M48T59 is not set -+# CONFIG_RTC_DRV_M48T86 is not set -+# CONFIG_RTC_DRV_MAX6900 is not set -+# CONFIG_RTC_DRV_MAX6902 is not set -+# CONFIG_RTC_DRV_MAX6916 is not set -+# CONFIG_RTC_DRV_MCP795 is not set -+# CONFIG_RTC_DRV_MOXART is not set -+# CONFIG_RTC_DRV_MPC5121 is not set -+# CONFIG_RTC_DRV_MSM6242 is not set -+# CONFIG_RTC_DRV_OMAP is not set -+# CONFIG_RTC_DRV_PCF2123 is not set -+# CONFIG_RTC_DRV_PCF2127 is not set -+# CONFIG_RTC_DRV_PCF85063 is not set -+# CONFIG_RTC_DRV_PCF8523 is not set -+# CONFIG_RTC_DRV_PCF8563 is not set -+# CONFIG_RTC_DRV_PCF8583 is not set -+# CONFIG_RTC_DRV_PL030 is not set -+# CONFIG_RTC_DRV_PL031 is not set -+# CONFIG_RTC_DRV_PS3 is not set -+# CONFIG_RTC_DRV_PT7C4338 is not set -+# CONFIG_RTC_DRV_R7301 is not set -+# CONFIG_RTC_DRV_R9701 is not set -+# CONFIG_RTC_DRV_RP5C01 is not set -+# CONFIG_RTC_DRV_RS5C348 is not set -+# CONFIG_RTC_DRV_RS5C372 is not set -+# CONFIG_RTC_DRV_RTC7301 is not set -+# CONFIG_RTC_DRV_RV3029C2 is not set -+# CONFIG_RTC_DRV_RV8803 is not set -+# CONFIG_RTC_DRV_RX4581 is not set -+# CONFIG_RTC_DRV_RX6110 is not set -+# CONFIG_RTC_DRV_RX8010 is not set -+# CONFIG_RTC_DRV_RX8025 is not set -+# CONFIG_RTC_DRV_RX8581 is not set -+# CONFIG_RTC_DRV_S35390A is not set -+# CONFIG_RTC_DRV_SNVS is not set -+# CONFIG_RTC_DRV_STK17TA8 is not set -+# CONFIG_RTC_DRV_SUN6I is not set -+# CONFIG_RTC_DRV_TEST is not set -+# CONFIG_RTC_DRV_V3020 is not set -+# CONFIG_RTC_DRV_X1205 is not set -+# CONFIG_RTC_DRV_XGENE is not set -+# CONFIG_RTC_DRV_ZYNQMP is not set -+CONFIG_RTC_HCTOSYS=y -+CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -+CONFIG_RTC_INTF_DEV=y -+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -+CONFIG_RTC_INTF_PROC=y -+CONFIG_RTC_INTF_SYSFS=y -+CONFIG_RTC_LIB=y -+# CONFIG_RTC_NVMEM is not set -+CONFIG_RTC_SYSTOHC=y -+CONFIG_RTC_SYSTOHC_DEVICE="rtc0" -+# CONFIG_RTL8180 is not set -+# CONFIG_RTL8187 is not set -+# CONFIG_RTL8192E is not set -+# CONFIG_RTL8192U is not set -+# CONFIG_RTL8306_PHY is not set -+# CONFIG_RTL8366RB_PHY is not set -+# CONFIG_RTL8366S_PHY is not set -+# CONFIG_RTL8366_SMI is not set -+# CONFIG_RTL8366_SMI_DEBUG_FS is not set -+# CONFIG_RTL8367B_PHY is not set -+# CONFIG_RTL8367_PHY is not set -+# CONFIG_RTLLIB is not set -+# CONFIG_RTL_CARDS is not set -+# CONFIG_RTS5208 is not set -+CONFIG_RT_MUTEXES=y -+# CONFIG_RUNTIME_DEBUG is not set -+CONFIG_RWSEM_GENERIC_SPINLOCK=y -+CONFIG_RXKAD=y -+# CONFIG_S2IO is not set -+# CONFIG_SAMPLES is not set -+# CONFIG_SAMSUNG_LAPTOP is not set -+# CONFIG_SATA_ACARD_AHCI is not set -+# CONFIG_SATA_AHCI is not set -+# CONFIG_SATA_AHCI_PLATFORM is not set -+# CONFIG_SATA_DWC is not set -+# CONFIG_SATA_FSL is not set -+# CONFIG_SATA_HIGHBANK is not set -+# CONFIG_SATA_INIC162X is not set -+# CONFIG_SATA_MV is not set -+# CONFIG_SATA_NV is not set -+# CONFIG_SATA_PMP is not set -+# CONFIG_SATA_PROMISE is not set -+# CONFIG_SATA_QSTOR is not set -+# CONFIG_SATA_RCAR is not set -+# CONFIG_SATA_SIL is not set -+# CONFIG_SATA_SIL24 is not set -+# CONFIG_SATA_SIS is not set -+# CONFIG_SATA_SVW is not set -+# CONFIG_SATA_SX4 is not set -+# CONFIG_SATA_ULI is not set -+# CONFIG_SATA_VIA is not set -+# CONFIG_SATA_VITESSE is not set -+# CONFIG_SBC_FITPC2_WATCHDOG is not set -+CONFIG_SBITMAP=y -+# CONFIG_SC92031 is not set -+# CONFIG_SCA3000 is not set -+# CONFIG_SCACHE_DEBUGFS is not set -+# CONFIG_SCC is not set -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_SCHED_AUTOGROUP is not set -+# CONFIG_SCHED_DEBUG is not set -+CONFIG_SCHED_HRTICK=y -+# CONFIG_SCHED_MC is not set -+CONFIG_SCHED_OMIT_FRAME_POINTER=y -+# CONFIG_SCHED_SMT is not set -+# CONFIG_SCHED_STACK_END_CHECK is not set -+# CONFIG_SCHED_TRACER is not set -+# CONFIG_SCR24X is not set -+# CONFIG_SCSI is not set -+# CONFIG_SCSI_3W_9XXX is not set -+# CONFIG_SCSI_3W_SAS is not set -+# CONFIG_SCSI_7000FASST is not set -+# CONFIG_SCSI_AACRAID is not set -+# CONFIG_SCSI_ACARD is not set -+# CONFIG_SCSI_ADVANSYS is not set -+# CONFIG_SCSI_AHA152X is not set -+# CONFIG_SCSI_AHA1542 is not set -+# CONFIG_SCSI_AIC79XX is not set -+# CONFIG_SCSI_AIC7XXX is not set -+# CONFIG_SCSI_AIC94XX is not set -+# CONFIG_SCSI_AM53C974 is not set -+# CONFIG_SCSI_ARCMSR is not set -+# CONFIG_SCSI_BFA_FC is not set -+# CONFIG_SCSI_BNX2X_FCOE is not set -+# CONFIG_SCSI_BNX2_ISCSI is not set -+# CONFIG_SCSI_BUSLOGIC is not set -+# CONFIG_SCSI_CHELSIO_FCOE is not set -+# CONFIG_SCSI_CONSTANTS is not set -+# CONFIG_SCSI_CXGB3_ISCSI is not set -+# CONFIG_SCSI_CXGB4_ISCSI is not set -+# CONFIG_SCSI_DC395x is not set -+# CONFIG_SCSI_DEBUG is not set -+# CONFIG_SCSI_DH is not set -+CONFIG_SCSI_DMA=y -+# CONFIG_SCSI_DMX3191D is not set -+# CONFIG_SCSI_DPT_I2O is not set -+# CONFIG_SCSI_DTC3280 is not set -+# CONFIG_SCSI_EATA is not set -+# CONFIG_SCSI_ESAS2R is not set -+# CONFIG_SCSI_FC_ATTRS is not set -+# CONFIG_SCSI_FUTURE_DOMAIN is not set -+# CONFIG_SCSI_GDTH is not set -+# CONFIG_SCSI_GENERIC_NCR5380 is not set -+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set -+# CONFIG_SCSI_HISI_SAS is not set -+# CONFIG_SCSI_HPSA is not set -+# CONFIG_SCSI_HPTIOP is not set -+# CONFIG_SCSI_IN2000 is not set -+# CONFIG_SCSI_INIA100 is not set -+# CONFIG_SCSI_INITIO is not set -+# CONFIG_SCSI_IPR is not set -+# CONFIG_SCSI_IPS is not set -+# CONFIG_SCSI_ISCI is not set -+# CONFIG_SCSI_ISCSI_ATTRS is not set -+# CONFIG_SCSI_LOGGING is not set -+CONFIG_SCSI_LOWLEVEL=y -+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set -+# CONFIG_SCSI_LPFC is not set -+CONFIG_SCSI_MOD=y -+# CONFIG_SCSI_MPT2SAS is not set -+# CONFIG_SCSI_MPT3SAS is not set -+# CONFIG_SCSI_MQ_DEFAULT is not set -+# CONFIG_SCSI_MVSAS is not set -+# CONFIG_SCSI_MVSAS_DEBUG is not set -+# CONFIG_SCSI_MVUMI is not set -+# CONFIG_SCSI_NCR53C406A is not set -+# CONFIG_SCSI_NETLINK is not set -+# CONFIG_SCSI_NSP32 is not set -+# CONFIG_SCSI_OSD_INITIATOR is not set -+# CONFIG_SCSI_PAS16 is not set -+# CONFIG_SCSI_PM8001 is not set -+# CONFIG_SCSI_PMCRAID is not set -+CONFIG_SCSI_PROC_FS=y -+# CONFIG_SCSI_QLA_FC is not set -+# CONFIG_SCSI_QLA_ISCSI is not set -+# CONFIG_SCSI_QLOGIC_1280 is not set -+# CONFIG_SCSI_QLOGIC_FAS is not set -+# CONFIG_SCSI_SAS_ATTRS is not set -+# CONFIG_SCSI_SAS_LIBSAS is not set -+# CONFIG_SCSI_SCAN_ASYNC is not set -+# CONFIG_SCSI_SMARTPQI is not set -+# CONFIG_SCSI_SNIC is not set -+# CONFIG_SCSI_SPI_ATTRS is not set -+# CONFIG_SCSI_SRP_ATTRS is not set -+# CONFIG_SCSI_STEX is not set -+# CONFIG_SCSI_SYM53C416 is not set -+# CONFIG_SCSI_SYM53C8XX_2 is not set -+# CONFIG_SCSI_T128 is not set -+# CONFIG_SCSI_U14_34F is not set -+# CONFIG_SCSI_UFSHCD is not set -+# CONFIG_SCSI_ULTRASTOR is not set -+# CONFIG_SCSI_VIRTIO is not set -+# CONFIG_SCSI_WD719X is not set -+# CONFIG_SCx200_ACB is not set -+# CONFIG_SDIO_UART is not set -+# CONFIG_SECCOMP is not set -+CONFIG_SECTION_MISMATCH_WARN_ONLY=y -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITYFS is not set -+CONFIG_SECURITY_DMESG_RESTRICT=y -+CONFIG_SELECT_MEMORY_MODEL=y -+# CONFIG_SENSORS_ABITUGURU is not set -+# CONFIG_SENSORS_ABITUGURU3 is not set -+# CONFIG_SENSORS_ACPI_POWER is not set -+# CONFIG_SENSORS_AD7314 is not set -+# CONFIG_SENSORS_AD7414 is not set -+# CONFIG_SENSORS_AD7418 is not set -+# CONFIG_SENSORS_ADC128D818 is not set -+# CONFIG_SENSORS_ADCXX is not set -+# CONFIG_SENSORS_ADM1021 is not set -+# CONFIG_SENSORS_ADM1025 is not set -+# CONFIG_SENSORS_ADM1026 is not set -+# CONFIG_SENSORS_ADM1029 is not set -+# CONFIG_SENSORS_ADM1031 is not set -+# CONFIG_SENSORS_ADM1275 is not set -+# CONFIG_SENSORS_ADM9240 is not set -+# CONFIG_SENSORS_ADS1015 is not set -+# CONFIG_SENSORS_ADS7828 is not set -+# CONFIG_SENSORS_ADS7871 is not set -+# CONFIG_SENSORS_ADT7310 is not set -+# CONFIG_SENSORS_ADT7410 is not set -+# CONFIG_SENSORS_ADT7411 is not set -+# CONFIG_SENSORS_ADT7462 is not set -+# CONFIG_SENSORS_ADT7470 is not set -+# CONFIG_SENSORS_ADT7475 is not set -+# CONFIG_SENSORS_AMC6821 is not set -+# CONFIG_SENSORS_APDS990X is not set -+# CONFIG_SENSORS_APPLESMC is not set -+# CONFIG_SENSORS_ASB100 is not set -+# CONFIG_SENSORS_ASC7621 is not set -+# CONFIG_SENSORS_ASPEED is not set -+# CONFIG_SENSORS_ATK0110 is not set -+# CONFIG_SENSORS_ATXP1 is not set -+# CONFIG_SENSORS_BH1770 is not set -+# CONFIG_SENSORS_BH1780 is not set -+# CONFIG_SENSORS_CORETEMP is not set -+# CONFIG_SENSORS_DELL_SMM is not set -+# CONFIG_SENSORS_DME1737 is not set -+# CONFIG_SENSORS_DS1621 is not set -+# CONFIG_SENSORS_DS620 is not set -+# CONFIG_SENSORS_EMC1403 is not set -+# CONFIG_SENSORS_EMC2103 is not set -+# CONFIG_SENSORS_EMC6W201 is not set -+# CONFIG_SENSORS_F71805F is not set -+# CONFIG_SENSORS_F71882FG is not set -+# CONFIG_SENSORS_F75375S is not set -+# CONFIG_SENSORS_FAM15H_POWER is not set -+# CONFIG_SENSORS_FSCHMD is not set -+# CONFIG_SENSORS_FTSTEUTATES is not set -+# CONFIG_SENSORS_G760A is not set -+# CONFIG_SENSORS_G762 is not set -+# CONFIG_SENSORS_GL518SM is not set -+# CONFIG_SENSORS_GL520SM is not set -+# CONFIG_SENSORS_GPIO_FAN is not set -+# CONFIG_SENSORS_GSC is not set -+# CONFIG_SENSORS_HDAPS is not set -+# CONFIG_SENSORS_HIH6130 is not set -+# CONFIG_SENSORS_HMC5843 is not set -+# CONFIG_SENSORS_HMC5843_I2C is not set -+# CONFIG_SENSORS_HMC5843_SPI is not set -+# CONFIG_SENSORS_HTU21 is not set -+# CONFIG_SENSORS_I5500 is not set -+# CONFIG_SENSORS_I5K_AMB is not set -+# CONFIG_SENSORS_IBM_CFFPS is not set -+# CONFIG_SENSORS_IIO_HWMON is not set -+# CONFIG_SENSORS_INA209 is not set -+# CONFIG_SENSORS_INA2XX is not set -+# CONFIG_SENSORS_INA3221 is not set -+# CONFIG_SENSORS_IR35221 is not set -+# CONFIG_SENSORS_ISL29018 is not set -+# CONFIG_SENSORS_ISL29028 is not set -+# CONFIG_SENSORS_IT87 is not set -+# CONFIG_SENSORS_JC42 is not set -+# CONFIG_SENSORS_K10TEMP is not set -+# CONFIG_SENSORS_K8TEMP is not set -+# CONFIG_SENSORS_LINEAGE is not set -+# CONFIG_SENSORS_LIS3LV02D is not set -+# CONFIG_SENSORS_LIS3_I2C is not set -+# CONFIG_SENSORS_LIS3_SPI is not set -+# CONFIG_SENSORS_LM25066 is not set -+# CONFIG_SENSORS_LM63 is not set -+# CONFIG_SENSORS_LM70 is not set -+# CONFIG_SENSORS_LM73 is not set -+# CONFIG_SENSORS_LM75 is not set -+# CONFIG_SENSORS_LM77 is not set -+# CONFIG_SENSORS_LM78 is not set -+# CONFIG_SENSORS_LM80 is not set -+# CONFIG_SENSORS_LM83 is not set -+# CONFIG_SENSORS_LM85 is not set -+# CONFIG_SENSORS_LM87 is not set -+# CONFIG_SENSORS_LM90 is not set -+# CONFIG_SENSORS_LM92 is not set -+# CONFIG_SENSORS_LM93 is not set -+# CONFIG_SENSORS_LM95234 is not set -+# CONFIG_SENSORS_LM95241 is not set -+# CONFIG_SENSORS_LM95245 is not set -+# CONFIG_SENSORS_LTC2945 is not set -+# CONFIG_SENSORS_LTC2978 is not set -+# CONFIG_SENSORS_LTC2990 is not set -+# CONFIG_SENSORS_LTC3815 is not set -+# CONFIG_SENSORS_LTC4151 is not set -+# CONFIG_SENSORS_LTC4215 is not set -+# CONFIG_SENSORS_LTC4222 is not set -+# CONFIG_SENSORS_LTC4245 is not set -+# CONFIG_SENSORS_LTC4260 is not set -+# CONFIG_SENSORS_LTC4261 is not set -+# CONFIG_SENSORS_MAX1111 is not set -+# CONFIG_SENSORS_MAX16064 is not set -+# CONFIG_SENSORS_MAX16065 is not set -+# CONFIG_SENSORS_MAX1619 is not set -+# CONFIG_SENSORS_MAX1668 is not set -+# CONFIG_SENSORS_MAX197 is not set -+# CONFIG_SENSORS_MAX20751 is not set -+# CONFIG_SENSORS_MAX31722 is not set -+# CONFIG_SENSORS_MAX31790 is not set -+# CONFIG_SENSORS_MAX34440 is not set -+# CONFIG_SENSORS_MAX6639 is not set -+# CONFIG_SENSORS_MAX6642 is not set -+# CONFIG_SENSORS_MAX6650 is not set -+# CONFIG_SENSORS_MAX6697 is not set -+# CONFIG_SENSORS_MAX8688 is not set -+# CONFIG_SENSORS_MCP3021 is not set -+# CONFIG_SENSORS_NCT6683 is not set -+# CONFIG_SENSORS_NCT6775 is not set -+# CONFIG_SENSORS_NCT7802 is not set -+# CONFIG_SENSORS_NCT7904 is not set -+# CONFIG_SENSORS_NSA320 is not set -+# CONFIG_SENSORS_NTC_THERMISTOR is not set -+# CONFIG_SENSORS_PC87360 is not set -+# CONFIG_SENSORS_PC87427 is not set -+# CONFIG_SENSORS_PCF8591 is not set -+# CONFIG_SENSORS_PMBUS is not set -+# CONFIG_SENSORS_POWR1220 is not set -+# CONFIG_SENSORS_PWM_FAN is not set -+# CONFIG_SENSORS_SCH5627 is not set -+# CONFIG_SENSORS_SCH5636 is not set -+# CONFIG_SENSORS_SCH56XX_COMMON is not set -+# CONFIG_SENSORS_SHT15 is not set -+# CONFIG_SENSORS_SHT21 is not set -+# CONFIG_SENSORS_SHT3x is not set -+# CONFIG_SENSORS_SHTC1 is not set -+# CONFIG_SENSORS_SIS5595 is not set -+# CONFIG_SENSORS_SMM665 is not set -+# CONFIG_SENSORS_SMSC47B397 is not set -+# CONFIG_SENSORS_SMSC47M1 is not set -+# CONFIG_SENSORS_SMSC47M192 is not set -+# CONFIG_SENSORS_STTS751 is not set -+# CONFIG_SENSORS_TC654 is not set -+# CONFIG_SENSORS_TC74 is not set -+# CONFIG_SENSORS_THMC50 is not set -+# CONFIG_SENSORS_TMP102 is not set -+# CONFIG_SENSORS_TMP103 is not set -+# CONFIG_SENSORS_TMP108 is not set -+# CONFIG_SENSORS_TMP401 is not set -+# CONFIG_SENSORS_TMP421 is not set -+# CONFIG_SENSORS_TPS40422 is not set -+# CONFIG_SENSORS_TPS53679 is not set -+# CONFIG_SENSORS_TSL2550 is not set -+# CONFIG_SENSORS_TSL2563 is not set -+# CONFIG_SENSORS_UCD9000 is not set -+# CONFIG_SENSORS_UCD9200 is not set -+# CONFIG_SENSORS_VEXPRESS is not set -+# CONFIG_SENSORS_VIA686A is not set -+# CONFIG_SENSORS_VIA_CPUTEMP is not set -+# CONFIG_SENSORS_VT1211 is not set -+# CONFIG_SENSORS_VT8231 is not set -+# CONFIG_SENSORS_W83627EHF is not set -+# CONFIG_SENSORS_W83627HF is not set -+# CONFIG_SENSORS_W83781D is not set -+# CONFIG_SENSORS_W83791D is not set -+# CONFIG_SENSORS_W83792D is not set -+# CONFIG_SENSORS_W83793 is not set -+# CONFIG_SENSORS_W83795 is not set -+# CONFIG_SENSORS_W83L785TS is not set -+# CONFIG_SENSORS_W83L786NG is not set -+# CONFIG_SENSORS_XGENE is not set -+# CONFIG_SENSORS_ZL6100 is not set -+CONFIG_SERIAL_8250=y -+# CONFIG_SERIAL_8250_ACCENT is not set -+# CONFIG_SERIAL_8250_ASPEED_VUART is not set -+# CONFIG_SERIAL_8250_BOCA is not set -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_CS is not set -+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -+# CONFIG_SERIAL_8250_DETECT_IRQ is not set -+CONFIG_SERIAL_8250_DMA=y -+# CONFIG_SERIAL_8250_DW is not set -+# CONFIG_SERIAL_8250_EM is not set -+# CONFIG_SERIAL_8250_EXAR is not set -+# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set -+# CONFIG_SERIAL_8250_EXTENDED is not set -+# CONFIG_SERIAL_8250_FINTEK is not set -+# CONFIG_SERIAL_8250_FOURPORT is not set -+# CONFIG_SERIAL_8250_HUB6 is not set -+# CONFIG_SERIAL_8250_INGENIC is not set -+# CONFIG_SERIAL_8250_LPSS is not set -+# CONFIG_SERIAL_8250_MANY_PORTS is not set -+# CONFIG_SERIAL_8250_MID is not set -+# CONFIG_SERIAL_8250_MOXA is not set -+CONFIG_SERIAL_8250_NR_UARTS=2 -+# CONFIG_SERIAL_8250_PCI is not set -+# CONFIG_SERIAL_8250_RSA is not set -+# CONFIG_SERIAL_8250_RT288X is not set -+CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -+# CONFIG_SERIAL_ALTERA_JTAGUART is not set -+# CONFIG_SERIAL_ALTERA_UART is not set -+# CONFIG_SERIAL_AMBA_PL010 is not set -+# CONFIG_SERIAL_ARC is not set -+# CONFIG_SERIAL_BCM63XX is not set -+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_DEV_BUS is not set -+CONFIG_SERIAL_EARLYCON=y -+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -+# CONFIG_SERIAL_FSL_LPUART is not set -+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set -+# CONFIG_SERIAL_IFX6X60 is not set -+# CONFIG_SERIAL_JSM is not set -+# CONFIG_SERIAL_MAX3100 is not set -+# CONFIG_SERIAL_MAX310X is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+# CONFIG_SERIAL_OF_PLATFORM is not set -+# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set -+# CONFIG_SERIAL_PCH_UART is not set -+# CONFIG_SERIAL_RP2 is not set -+# CONFIG_SERIAL_SC16IS7XX is not set -+# CONFIG_SERIAL_SCCNXP is not set -+# CONFIG_SERIAL_SH_SCI is not set -+# CONFIG_SERIAL_STM32 is not set -+# CONFIG_SERIAL_ST_ASC is not set -+# CONFIG_SERIAL_TIMBERDALE is not set -+# CONFIG_SERIAL_UARTLITE is not set -+# CONFIG_SERIAL_XILINX_PS_UART is not set -+# CONFIG_SERIO is not set -+# CONFIG_SERIO_ALTERA_PS2 is not set -+# CONFIG_SERIO_AMBAKMI is not set -+# CONFIG_SERIO_APBPS2 is not set -+# CONFIG_SERIO_ARC_PS2 is not set -+# CONFIG_SERIO_CT82C710 is not set -+# CONFIG_SERIO_GPIO_PS2 is not set -+# CONFIG_SERIO_I8042 is not set -+# CONFIG_SERIO_LIBPS2 is not set -+# CONFIG_SERIO_PARKBD is not set -+# CONFIG_SERIO_PCIPS2 is not set -+# CONFIG_SERIO_PS2MULT is not set -+# CONFIG_SERIO_RAW is not set -+# CONFIG_SERIO_SERPORT is not set -+# CONFIG_SERIO_SUN4I_PS2 is not set -+# CONFIG_SFC is not set -+# CONFIG_SFC_FALCON is not set -+# CONFIG_SFI is not set -+# CONFIG_SGETMASK_SYSCALL is not set -+# CONFIG_SGI_IOC4 is not set -+# CONFIG_SGI_IP22 is not set -+# CONFIG_SGI_IP27 is not set -+# CONFIG_SGI_IP28 is not set -+# CONFIG_SGI_IP32 is not set -+# CONFIG_SGI_PARTITION is not set -+# CONFIG_SGL_ALLOC is not set -+# CONFIG_SG_POOL is not set -+# CONFIG_SG_SPLIT is not set -+CONFIG_SHMEM=y -+# CONFIG_SH_ETH is not set -+# CONFIG_SH_TIMER_CMT is not set -+# CONFIG_SH_TIMER_MTU2 is not set -+# CONFIG_SH_TIMER_TMU is not set -+# CONFIG_SI1145 is not set -+# CONFIG_SI7005 is not set -+# CONFIG_SI7020 is not set -+# CONFIG_SIBYTE_BIGSUR is not set -+# CONFIG_SIBYTE_CARMEL is not set -+# CONFIG_SIBYTE_CRHINE is not set -+# CONFIG_SIBYTE_CRHONE is not set -+# CONFIG_SIBYTE_LITTLESUR is not set -+# CONFIG_SIBYTE_RHONE is not set -+# CONFIG_SIBYTE_SENTOSA is not set -+# CONFIG_SIBYTE_SWARM is not set -+CONFIG_SIGNALFD=y -+# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set -+# CONFIG_SIMPLE_GPIO is not set -+# CONFIG_SIMPLE_PM_BUS is not set -+# CONFIG_SIS190 is not set -+# CONFIG_SIS900 is not set -+# CONFIG_SKGE is not set -+# CONFIG_SKY2 is not set -+# CONFIG_SKY2_DEBUG is not set -+# CONFIG_SLAB is not set -+CONFIG_SLABINFO=y -+# CONFIG_SLAB_FREELIST_HARDENED is not set -+# CONFIG_SLAB_FREELIST_RANDOM is not set -+CONFIG_SLAB_MERGE_DEFAULT=y -+# CONFIG_SLHC is not set -+# CONFIG_SLICOSS is not set -+# CONFIG_SLIP is not set -+# CONFIG_SLOB is not set -+CONFIG_SLUB=y -+CONFIG_SLUB_CPU_PARTIAL=y -+# CONFIG_SLUB_DEBUG is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_SLUB_MEMCG_SYSFS_ON is not set -+# CONFIG_SLUB_STATS is not set -+# CONFIG_SMARTJOYPLUS_FF is not set -+# CONFIG_SMC911X is not set -+# CONFIG_SMC9194 is not set -+# CONFIG_SMC91X is not set -+# CONFIG_SMP is not set -+# CONFIG_SMSC911X is not set -+# CONFIG_SMSC9420 is not set -+# CONFIG_SMSC_PHY is not set -+# CONFIG_SM_FTL is not set -+# CONFIG_SND is not set -+# CONFIG_SND_AC97_POWER_SAVE is not set -+# CONFIG_SND_AD1816A is not set -+# CONFIG_SND_AD1848 is not set -+# CONFIG_SND_AD1889 is not set -+# CONFIG_SND_ADLIB is not set -+# CONFIG_SND_ALI5451 is not set -+# CONFIG_SND_ALOOP is not set -+# CONFIG_SND_ALS100 is not set -+# CONFIG_SND_ALS300 is not set -+# CONFIG_SND_ALS4000 is not set -+# CONFIG_SND_ARM is not set -+# CONFIG_SND_ASIHPI is not set -+# CONFIG_SND_ATIIXP is not set -+# CONFIG_SND_ATIIXP_MODEM is not set -+# CONFIG_SND_ATMEL_AC97C is not set -+# CONFIG_SND_ATMEL_SOC is not set -+# CONFIG_SND_AU8810 is not set -+# CONFIG_SND_AU8820 is not set -+# CONFIG_SND_AU8830 is not set -+# CONFIG_SND_AUDIO_GRAPH_CARD is not set -+# CONFIG_SND_AUDIO_GRAPH_SCU_CARD is not set -+# CONFIG_SND_AW2 is not set -+# CONFIG_SND_AZT2320 is not set -+# CONFIG_SND_AZT3328 is not set -+# CONFIG_SND_BCD2000 is not set -+# CONFIG_SND_BT87X is not set -+# CONFIG_SND_CA0106 is not set -+# CONFIG_SND_CMI8330 is not set -+# CONFIG_SND_CMIPCI is not set -+# CONFIG_SND_CS4231 is not set -+# CONFIG_SND_CS4236 is not set -+# CONFIG_SND_CS4281 is not set -+# CONFIG_SND_CS46XX is not set -+# CONFIG_SND_CS5530 is not set -+# CONFIG_SND_CS5535AUDIO is not set -+# CONFIG_SND_CTXFI is not set -+# CONFIG_SND_DARLA20 is not set -+# CONFIG_SND_DARLA24 is not set -+# CONFIG_SND_DEBUG is not set -+# CONFIG_SND_DESIGNWARE_I2S is not set -+CONFIG_SND_DRIVERS=y -+# CONFIG_SND_DUMMY is not set -+# CONFIG_SND_DYNAMIC_MINORS is not set -+# CONFIG_SND_ECHO3G is not set -+# CONFIG_SND_EDMA_SOC is not set -+# CONFIG_SND_EMU10K1 is not set -+# CONFIG_SND_EMU10K1X is not set -+# CONFIG_SND_EMU10K1_SEQ is not set -+# CONFIG_SND_ENS1370 is not set -+# CONFIG_SND_ENS1371 is not set -+# CONFIG_SND_ES1688 is not set -+# CONFIG_SND_ES18XX is not set -+# CONFIG_SND_ES1938 is not set -+# CONFIG_SND_ES1968 is not set -+# CONFIG_SND_FIREWIRE is not set -+# CONFIG_SND_FM801 is not set -+# CONFIG_SND_GINA20 is not set -+# CONFIG_SND_GINA24 is not set -+# CONFIG_SND_GUSCLASSIC is not set -+# CONFIG_SND_GUSEXTREME is not set -+# CONFIG_SND_GUSMAX is not set -+# CONFIG_SND_HDA_INTEL is not set -+CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 -+CONFIG_SND_HDA_PREALLOC_SIZE=64 -+# CONFIG_SND_HDSP is not set -+# CONFIG_SND_HDSPM is not set -+# CONFIG_SND_HRTIMER is not set -+# CONFIG_SND_HWDEP is not set -+# CONFIG_SND_I2S_HI6210_I2S is not set -+# CONFIG_SND_ICE1712 is not set -+# CONFIG_SND_ICE1724 is not set -+# CONFIG_SND_INDIGO is not set -+# CONFIG_SND_INDIGODJ is not set -+# CONFIG_SND_INDIGODJX is not set -+# CONFIG_SND_INDIGOIO is not set -+# CONFIG_SND_INDIGOIOX is not set -+# CONFIG_SND_INTEL8X0 is not set -+# CONFIG_SND_INTEL8X0M is not set -+# CONFIG_SND_INTERWAVE is not set -+# CONFIG_SND_INTERWAVE_STB is not set -+# CONFIG_SND_ISA is not set -+# CONFIG_SND_KIRKWOOD_SOC is not set -+# CONFIG_SND_KORG1212 is not set -+# CONFIG_SND_LAYLA20 is not set -+# CONFIG_SND_LAYLA24 is not set -+# CONFIG_SND_LOLA is not set -+# CONFIG_SND_LX6464ES is not set -+# CONFIG_SND_MAESTRO3 is not set -+# CONFIG_SND_MIA is not set -+# CONFIG_SND_MIPS is not set -+# CONFIG_SND_MIRO is not set -+# CONFIG_SND_MIXART is not set -+# CONFIG_SND_MIXER_OSS is not set -+# CONFIG_SND_MONA is not set -+# CONFIG_SND_MPC52xx_SOC_EFIKA is not set -+# CONFIG_SND_MPU401 is not set -+# CONFIG_SND_MTPAV is not set -+# CONFIG_SND_MTS64 is not set -+# CONFIG_SND_MXS_SOC is not set -+# CONFIG_SND_NM256 is not set -+# CONFIG_SND_OPL3SA2 is not set -+# CONFIG_SND_OPL3_LIB_SEQ is not set -+# CONFIG_SND_OPL4_LIB_SEQ is not set -+# CONFIG_SND_OPTI92X_AD1848 is not set -+# CONFIG_SND_OPTI92X_CS4231 is not set -+# CONFIG_SND_OPTI93X is not set -+CONFIG_SND_OSSEMUL=y -+# CONFIG_SND_OXYGEN is not set -+CONFIG_SND_PCI=y -+# CONFIG_SND_PCM is not set -+# CONFIG_SND_PCMCIA is not set -+# CONFIG_SND_PCM_OSS is not set -+CONFIG_SND_PCM_OSS_PLUGINS=y -+# CONFIG_SND_PCM_TIMER is not set -+# CONFIG_SND_PCM_XRUN_DEBUG is not set -+# CONFIG_SND_PCXHR is not set -+# CONFIG_SND_PDAUDIOCF is not set -+# CONFIG_SND_PORTMAN2X4 is not set -+# CONFIG_SND_POWERPC_SOC is not set -+# CONFIG_SND_PPC is not set -+CONFIG_SND_PROC_FS=y -+# CONFIG_SND_RAWMIDI is not set -+# CONFIG_SND_RAWMIDI_SEQ is not set -+# CONFIG_SND_RIPTIDE is not set -+# CONFIG_SND_RME32 is not set -+# CONFIG_SND_RME96 is not set -+# CONFIG_SND_RME9652 is not set -+# CONFIG_SND_RTCTIMER is not set -+# CONFIG_SND_SB16 is not set -+# CONFIG_SND_SB8 is not set -+# CONFIG_SND_SBAWE is not set -+# CONFIG_SND_SBAWE_SEQ is not set -+# CONFIG_SND_SE6X is not set -+# CONFIG_SND_SEQUENCER is not set -+# CONFIG_SND_SERIAL_U16550 is not set -+# CONFIG_SND_SIMPLE_CARD is not set -+# CONFIG_SND_SIMPLE_SCU_CARD is not set -+# CONFIG_SND_SIS7019 is not set -+# CONFIG_SND_SOC is not set -+# CONFIG_SND_SOC_AC97_CODEC is not set -+# CONFIG_SND_SOC_ADAU1701 is not set -+# CONFIG_SND_SOC_ADAU1761_I2C is not set -+# CONFIG_SND_SOC_ADAU1761_SPI is not set -+# CONFIG_SND_SOC_ADAU7002 is not set -+# CONFIG_SND_SOC_AK4104 is not set -+# CONFIG_SND_SOC_AK4554 is not set -+# CONFIG_SND_SOC_AK4613 is not set -+# CONFIG_SND_SOC_AK4642 is not set -+# CONFIG_SND_SOC_AK5386 is not set -+# CONFIG_SND_SOC_ALC5623 is not set -+# CONFIG_SND_SOC_AMD_ACP is not set -+# CONFIG_SND_SOC_AU1XAUDIO is not set -+# CONFIG_SND_SOC_AU1XPSC is not set -+# CONFIG_SND_SOC_BT_SCO is not set -+# CONFIG_SND_SOC_CS35L32 is not set -+# CONFIG_SND_SOC_CS35L33 is not set -+# CONFIG_SND_SOC_CS35L34 is not set -+# CONFIG_SND_SOC_CS35L35 is not set -+# CONFIG_SND_SOC_CS4265 is not set -+# CONFIG_SND_SOC_CS4270 is not set -+# CONFIG_SND_SOC_CS4271 is not set -+# CONFIG_SND_SOC_CS4271_I2C is not set -+# CONFIG_SND_SOC_CS4271_SPI is not set -+# CONFIG_SND_SOC_CS42L42 is not set -+# CONFIG_SND_SOC_CS42L51_I2C is not set -+# CONFIG_SND_SOC_CS42L52 is not set -+# CONFIG_SND_SOC_CS42L56 is not set -+# CONFIG_SND_SOC_CS42L73 is not set -+# CONFIG_SND_SOC_CS42XX8_I2C is not set -+# CONFIG_SND_SOC_CS43130 is not set -+# CONFIG_SND_SOC_CS4349 is not set -+# CONFIG_SND_SOC_CS53L30 is not set -+# CONFIG_SND_SOC_DIO2125 is not set -+# CONFIG_SND_SOC_ES7134 is not set -+# CONFIG_SND_SOC_ES8316 is not set -+# CONFIG_SND_SOC_ES8328 is not set -+# CONFIG_SND_SOC_ES8328_I2C is not set -+# CONFIG_SND_SOC_ES8328_SPI is not set -+# CONFIG_SND_SOC_EUKREA_TLV320 is not set -+# CONFIG_SND_SOC_FSL_ASOC_CARD is not set -+# CONFIG_SND_SOC_FSL_ASRC is not set -+# CONFIG_SND_SOC_FSL_ESAI is not set -+# CONFIG_SND_SOC_FSL_SAI is not set -+# CONFIG_SND_SOC_FSL_SPDIF is not set -+# CONFIG_SND_SOC_FSL_SSI is not set -+# CONFIG_SND_SOC_GTM601 is not set -+# CONFIG_SND_SOC_ICS43432 is not set -+# CONFIG_SND_SOC_IMG is not set -+# CONFIG_SND_SOC_IMX_AUDMUX is not set -+# CONFIG_SND_SOC_IMX_ES8328 is not set -+# CONFIG_SND_SOC_IMX_SPDIF is not set -+# CONFIG_SND_SOC_IMX_WM8962 is not set -+# CONFIG_SND_SOC_INNO_RK3036 is not set -+# CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH is not set -+# CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH is not set -+# CONFIG_SND_SOC_INTEL_BXT_RT298_MACH is not set -+# CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH is not set -+# CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH is not set -+# CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH is not set -+# CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH is not set -+# CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH is not set -+# CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH is not set -+# CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH is not set -+# CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH is not set -+# CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH is not set -+# CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH is not set -+# CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH is not set -+# CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH is not set -+# CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH is not set -+# CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH is not set -+# CONFIG_SND_SOC_INTEL_SKL_RT286_MACH is not set -+# CONFIG_SND_SOC_INTEL_SST is not set -+# CONFIG_SND_SOC_MAX98504 is not set -+# CONFIG_SND_SOC_MAX9860 is not set -+# CONFIG_SND_SOC_MAX98927 is not set -+# CONFIG_SND_SOC_MEDIATEK is not set -+# CONFIG_SND_SOC_MPC5200_AC97 is not set -+# CONFIG_SND_SOC_MPC5200_I2S is not set -+# CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set -+# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set -+# CONFIG_SND_SOC_MT2701 is not set -+# CONFIG_SND_SOC_MT8173 is not set -+# CONFIG_SND_SOC_NAU8540 is not set -+# CONFIG_SND_SOC_NAU8810 is not set -+# CONFIG_SND_SOC_NAU8824 is not set -+# CONFIG_SND_SOC_PCM1681 is not set -+# CONFIG_SND_SOC_PCM1792A is not set -+# CONFIG_SND_SOC_PCM179X_I2C is not set -+# CONFIG_SND_SOC_PCM179X_SPI is not set -+# CONFIG_SND_SOC_PCM3168A_I2C is not set -+# CONFIG_SND_SOC_PCM3168A_SPI is not set -+# CONFIG_SND_SOC_PCM512x_I2C is not set -+# CONFIG_SND_SOC_PCM512x_SPI is not set -+# CONFIG_SND_SOC_QCOM is not set -+# CONFIG_SND_SOC_RT5616 is not set -+# CONFIG_SND_SOC_RT5631 is not set -+# CONFIG_SND_SOC_RT5677_SPI is not set -+# CONFIG_SND_SOC_SGTL5000 is not set -+# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set -+# CONFIG_SND_SOC_SPDIF is not set -+# CONFIG_SND_SOC_SSM2602_I2C is not set -+# CONFIG_SND_SOC_SSM2602_SPI is not set -+# CONFIG_SND_SOC_SSM4567 is not set -+# CONFIG_SND_SOC_STA32X is not set -+# CONFIG_SND_SOC_STA350 is not set -+# CONFIG_SND_SOC_STI_SAS is not set -+# CONFIG_SND_SOC_TAS2552 is not set -+# CONFIG_SND_SOC_TAS5086 is not set -+# CONFIG_SND_SOC_TAS571X is not set -+# CONFIG_SND_SOC_TAS5720 is not set -+# CONFIG_SND_SOC_TFA9879 is not set -+# CONFIG_SND_SOC_TLV320AIC23_I2C is not set -+# CONFIG_SND_SOC_TLV320AIC23_SPI is not set -+# CONFIG_SND_SOC_TLV320AIC31XX is not set -+# CONFIG_SND_SOC_TLV320AIC3X is not set -+# CONFIG_SND_SOC_TPA6130A2 is not set -+# CONFIG_SND_SOC_TS3A227E is not set -+# CONFIG_SND_SOC_WM8510 is not set -+# CONFIG_SND_SOC_WM8523 is not set -+# CONFIG_SND_SOC_WM8524 is not set -+# CONFIG_SND_SOC_WM8580 is not set -+# CONFIG_SND_SOC_WM8711 is not set -+# CONFIG_SND_SOC_WM8728 is not set -+# CONFIG_SND_SOC_WM8731 is not set -+# CONFIG_SND_SOC_WM8737 is not set -+# CONFIG_SND_SOC_WM8741 is not set -+# CONFIG_SND_SOC_WM8750 is not set -+# CONFIG_SND_SOC_WM8753 is not set -+# CONFIG_SND_SOC_WM8770 is not set -+# CONFIG_SND_SOC_WM8776 is not set -+# CONFIG_SND_SOC_WM8804_I2C is not set -+# CONFIG_SND_SOC_WM8804_SPI is not set -+# CONFIG_SND_SOC_WM8903 is not set -+# CONFIG_SND_SOC_WM8960 is not set -+# CONFIG_SND_SOC_WM8962 is not set -+# CONFIG_SND_SOC_WM8974 is not set -+# CONFIG_SND_SOC_WM8978 is not set -+# CONFIG_SND_SOC_WM8985 is not set -+# CONFIG_SND_SOC_XTFPGA_I2S is not set -+# CONFIG_SND_SOC_ZX_AUD96P22 is not set -+# CONFIG_SND_SONICVIBES is not set -+# CONFIG_SND_SPI is not set -+# CONFIG_SND_SSCAPE is not set -+# CONFIG_SND_SUN4I_CODEC is not set -+# CONFIG_SND_SUPPORT_OLD_API is not set -+# CONFIG_SND_TIMER is not set -+# CONFIG_SND_TRIDENT is not set -+CONFIG_SND_USB=y -+# CONFIG_SND_USB_6FIRE is not set -+# CONFIG_SND_USB_AUDIO is not set -+# CONFIG_SND_USB_CAIAQ is not set -+# CONFIG_SND_USB_HIFACE is not set -+# CONFIG_SND_USB_POD is not set -+# CONFIG_SND_USB_PODHD is not set -+# CONFIG_SND_USB_TONEPORT is not set -+# CONFIG_SND_USB_UA101 is not set -+# CONFIG_SND_USB_US122L is not set -+# CONFIG_SND_USB_USX2Y is not set -+# CONFIG_SND_USB_VARIAX is not set -+# CONFIG_SND_VERBOSE_PRINTK is not set -+CONFIG_SND_VERBOSE_PROCFS=y -+# CONFIG_SND_VIA82XX is not set -+# CONFIG_SND_VIA82XX_MODEM is not set -+# CONFIG_SND_VIRTUOSO is not set -+# CONFIG_SND_VX222 is not set -+# CONFIG_SND_VXPOCKET is not set -+# CONFIG_SND_WAVEFRONT is not set -+CONFIG_SND_X86=y -+# CONFIG_SND_YMFPCI is not set -+# CONFIG_SNI_RM is not set -+# CONFIG_SOCK_CGROUP_DATA is not set -+# CONFIG_SOC_AM33XX is not set -+# CONFIG_SOC_AM43XX is not set -+# CONFIG_SOC_BRCMSTB is not set -+# CONFIG_SOC_CAMERA is not set -+# CONFIG_SOC_DRA7XX is not set -+# CONFIG_SOC_HAS_OMAP2_SDRC is not set -+# CONFIG_SOC_OMAP5 is not set -+# CONFIG_SOC_TI is not set -+# CONFIG_SOFTLOCKUP_DETECTOR is not set -+# CONFIG_SOFT_WATCHDOG is not set -+# CONFIG_SOLARIS_X86_PARTITION is not set -+# CONFIG_SONYPI is not set -+# CONFIG_SONY_LAPTOP is not set -+# CONFIG_SOUND is not set -+# CONFIG_SOUND_OSS_CORE is not set -+# CONFIG_SOUND_PRIME is not set -+# CONFIG_SP5100_TCO is not set -+# CONFIG_SPARSEMEM_MANUAL is not set -+# CONFIG_SPARSEMEM_STATIC is not set -+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -+# CONFIG_SPARSE_IRQ is not set -+# CONFIG_SPARSE_RCU_POINTER is not set -+# CONFIG_SPEAKUP is not set -+# CONFIG_SPI is not set -+# CONFIG_SPINLOCK_TEST is not set -+# CONFIG_SPI_ALTERA is not set -+# CONFIG_SPI_AU1550 is not set -+# CONFIG_SPI_AXI_SPI_ENGINE is not set -+# CONFIG_SPI_BCM2835 is not set -+# CONFIG_SPI_BCM_QSPI is not set -+# CONFIG_SPI_BITBANG is not set -+# CONFIG_SPI_BUTTERFLY is not set -+# CONFIG_SPI_CADENCE is not set -+# CONFIG_SPI_CADENCE_QUADSPI is not set -+# CONFIG_SPI_DEBUG is not set -+# CONFIG_SPI_DESIGNWARE is not set -+# CONFIG_SPI_FSL_DSPI is not set -+# CONFIG_SPI_FSL_ESPI is not set -+# CONFIG_SPI_FSL_SPI is not set -+# CONFIG_SPI_GPIO is not set -+# CONFIG_SPI_GPIO_OLD is not set -+# CONFIG_SPI_IMG_SPFI is not set -+# CONFIG_SPI_LM70_LLP is not set -+# CONFIG_SPI_LOOPBACK_TEST is not set -+# CONFIG_SPI_MASTER is not set -+# CONFIG_SPI_MPC52xx is not set -+# CONFIG_SPI_MPC52xx_PSC is not set -+# CONFIG_SPI_OCTEON is not set -+# CONFIG_SPI_OC_TINY is not set -+# CONFIG_SPI_ORION is not set -+# CONFIG_SPI_PL022 is not set -+# CONFIG_SPI_PPC4xx is not set -+# CONFIG_SPI_PXA2XX is not set -+# CONFIG_SPI_PXA2XX_PCI is not set -+# CONFIG_SPI_ROCKCHIP is not set -+# CONFIG_SPI_S3C64XX is not set -+# CONFIG_SPI_SC18IS602 is not set -+# CONFIG_SPI_SLAVE is not set -+# CONFIG_SPI_SPIDEV is not set -+# CONFIG_SPI_THUNDERX is not set -+# CONFIG_SPI_TI_QSPI is not set -+# CONFIG_SPI_TLE62X0 is not set -+# CONFIG_SPI_TOPCLIFF_PCH is not set -+# CONFIG_SPI_XCOMM is not set -+# CONFIG_SPI_XILINX is not set -+# CONFIG_SPI_XWAY is not set -+# CONFIG_SPI_ZYNQMP_GQSPI is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+# CONFIG_SPMI is not set -+CONFIG_SQUASHFS=y -+# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set -+# CONFIG_SQUASHFS_DECOMP_MULTI is not set -+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y -+# CONFIG_SQUASHFS_DECOMP_SINGLE is not set -+CONFIG_SQUASHFS_EMBEDDED=y -+# CONFIG_SQUASHFS_FILE_CACHE is not set -+CONFIG_SQUASHFS_FILE_DIRECT=y -+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -+# CONFIG_SQUASHFS_LZ4 is not set -+# CONFIG_SQUASHFS_LZO is not set -+# CONFIG_SQUASHFS_XATTR is not set -+CONFIG_SQUASHFS_XZ=y -+# CONFIG_SQUASHFS_ZLIB is not set -+# CONFIG_SQUASHFS_ZSTD is not set -+# CONFIG_SRAM is not set -+# CONFIG_SRF04 is not set -+# CONFIG_SRF08 is not set -+# CONFIG_SSB is not set -+# CONFIG_SSB_DEBUG is not set -+# CONFIG_SSB_DRIVER_GPIO is not set -+# CONFIG_SSB_HOST_SOC is not set -+# CONFIG_SSB_PCMCIAHOST is not set -+CONFIG_SSB_POSSIBLE=y -+# CONFIG_SSB_SDIOHOST is not set -+# CONFIG_SSB_SILENT is not set -+# CONFIG_SSFDC is not set -+# CONFIG_STACKTRACE is not set -+CONFIG_STACKTRACE_SUPPORT=y -+# CONFIG_STACK_TRACER is not set -+# CONFIG_STACK_VALIDATION is not set -+CONFIG_STAGING=y -+# CONFIG_STAGING_BOARD is not set -+# CONFIG_STAGING_MEDIA is not set -+CONFIG_STANDALONE=y -+# CONFIG_STATIC_KEYS_SELFTEST is not set -+# CONFIG_STATIC_USERMODEHELPER is not set -+CONFIG_STDBINUTILS=y -+# CONFIG_STE10XP is not set -+# CONFIG_STE_MODEM_RPROC is not set -+# CONFIG_STK3310 is not set -+# CONFIG_STK8312 is not set -+# CONFIG_STK8BA50 is not set -+# CONFIG_STM is not set -+# CONFIG_STMMAC_ETH is not set -+# CONFIG_STMMAC_PCI is not set -+# CONFIG_STMMAC_PLATFORM is not set -+# CONFIG_STM_DUMMY is not set -+# CONFIG_STM_SOURCE_CONSOLE is not set -+CONFIG_STP=y -+# CONFIG_STREAM_PARSER is not set -+# CONFIG_STRICT_DEVMEM is not set -+CONFIG_STRICT_KERNEL_RWX=y -+CONFIG_STRICT_MODULE_RWX=y -+# CONFIG_STRING_SELFTEST is not set -+CONFIG_STRIP_ASM_SYMS=y -+# CONFIG_STX104 is not set -+# CONFIG_SUN4I_GPADC is not set -+# CONFIG_SUNDANCE is not set -+# CONFIG_SUNGEM is not set -+# CONFIG_SUNRPC is not set -+# CONFIG_SUNRPC_DEBUG is not set -+# CONFIG_SUNRPC_GSS is not set -+# CONFIG_SUNXI_SRAM is not set -+# CONFIG_SUN_PARTITION is not set -+# CONFIG_SURFACE_3_BUTTON is not set -+# CONFIG_SUSPEND is not set -+# CONFIG_SUSPEND_SKIP_SYNC is not set -+CONFIG_SWAP=y -+# CONFIG_SWCONFIG is not set -+# CONFIG_SWCONFIG_B53 is not set -+# CONFIG_SWCONFIG_B53_MDIO_DRIVER is not set -+# CONFIG_SWCONFIG_B53_MMAP_DRIVER is not set -+# CONFIG_SWCONFIG_B53_SPI_DRIVER is not set -+# CONFIG_SWCONFIG_B53_SRAB_DRIVER is not set -+# CONFIG_SWCONFIG_LEDS is not set -+# CONFIG_SW_SYNC is not set -+# CONFIG_SX9500 is not set -+# CONFIG_SXGBE_ETH is not set -+# CONFIG_SYNCLINK_CS is not set -+# CONFIG_SYNC_FILE is not set -+# CONFIG_SYNOPSYS_DWC_ETH_QOS is not set -+CONFIG_SYN_COOKIES=y -+# CONFIG_SYSCON_REBOOT_MODE is not set -+CONFIG_SYSCTL=y -+# CONFIG_SYSCTL_SYSCALL is not set -+CONFIG_SYSFS=y -+# CONFIG_SYSFS_DEPRECATED is not set -+# CONFIG_SYSFS_DEPRECATED_V2 is not set -+# CONFIG_SYSFS_SYSCALL is not set -+# CONFIG_SYSTEMPORT is not set -+# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set -+# CONFIG_SYSTEM_DATA_VERIFICATION is not set -+# CONFIG_SYSTEM_TRUSTED_KEYRING is not set -+CONFIG_SYSTEM_TRUSTED_KEYS="" -+# CONFIG_SYSV68_PARTITION is not set -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_SYSV_FS is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_T5403 is not set -+# CONFIG_TARGET_CORE is not set -+# CONFIG_TASKSTATS is not set -+# CONFIG_TASKS_RCU is not set -+# CONFIG_TASK_XACCT is not set -+# CONFIG_TC35815 is not set -+# CONFIG_TCG_ATMEL is not set -+# CONFIG_TCG_CRB is not set -+# CONFIG_TCG_INFINEON is not set -+# CONFIG_TCG_NSC is not set -+# CONFIG_TCG_ST33_I2C is not set -+# CONFIG_TCG_TIS is not set -+# CONFIG_TCG_TIS_I2C_ATMEL is not set -+# CONFIG_TCG_TIS_I2C_INFINEON is not set -+# CONFIG_TCG_TIS_I2C_NUVOTON is not set -+# CONFIG_TCG_TIS_SPI is not set -+# CONFIG_TCG_TIS_ST33ZP24_I2C is not set -+# CONFIG_TCG_TIS_ST33ZP24_SPI is not set -+# CONFIG_TCG_TPM is not set -+# CONFIG_TCG_VTPM_PROXY is not set -+# CONFIG_TCG_XEN is not set -+# CONFIG_TCIC is not set -+CONFIG_TCP_CONG_ADVANCED=y -+# CONFIG_TCP_CONG_BBR is not set -+# CONFIG_TCP_CONG_BIC is not set -+# CONFIG_TCP_CONG_CDG is not set -+CONFIG_TCP_CONG_CUBIC=y -+# CONFIG_TCP_CONG_DCTCP is not set -+# CONFIG_TCP_CONG_HSTCP is not set -+# CONFIG_TCP_CONG_HTCP is not set -+# CONFIG_TCP_CONG_HYBLA is not set -+# CONFIG_TCP_CONG_ILLINOIS is not set -+# CONFIG_TCP_CONG_LP is not set -+# CONFIG_TCP_CONG_NV is not set -+# CONFIG_TCP_CONG_SCALABLE is not set -+# CONFIG_TCP_CONG_VEGAS is not set -+# CONFIG_TCP_CONG_VENO is not set -+# CONFIG_TCP_CONG_WESTWOOD is not set -+# CONFIG_TCP_CONG_YEAH is not set -+# CONFIG_TCP_MD5SIG is not set -+# CONFIG_TCS3414 is not set -+# CONFIG_TCS3472 is not set -+# CONFIG_TEE is not set -+# CONFIG_TEGRA_AHB is not set -+# CONFIG_TEGRA_HOST1X is not set -+# CONFIG_TEHUTI is not set -+# CONFIG_TERANETICS_PHY is not set -+# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set -+# CONFIG_TEST_BITMAP is not set -+# CONFIG_TEST_BPF is not set -+# CONFIG_TEST_FIRMWARE is not set -+# CONFIG_TEST_HASH is not set -+# CONFIG_TEST_HEXDUMP is not set -+# CONFIG_TEST_KASAN is not set -+# CONFIG_TEST_KMOD is not set -+# CONFIG_TEST_KSTRTOX is not set -+# CONFIG_TEST_LIST_SORT is not set -+# CONFIG_TEST_LKM is not set -+# CONFIG_TEST_POWER is not set -+# CONFIG_TEST_PRINTF is not set -+# CONFIG_TEST_RHASHTABLE is not set -+# CONFIG_TEST_SORT is not set -+# CONFIG_TEST_STATIC_KEYS is not set -+# CONFIG_TEST_STRING_HELPERS is not set -+# CONFIG_TEST_SYSCTL is not set -+# CONFIG_TEST_UDELAY is not set -+# CONFIG_TEST_USER_COPY is not set -+# CONFIG_TEST_UUID is not set -+CONFIG_TEXTSEARCH=y -+# CONFIG_TEXTSEARCH_BM is not set -+# CONFIG_TEXTSEARCH_FSM is not set -+# CONFIG_TEXTSEARCH_KMP is not set -+# CONFIG_THERMAL is not set -+# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set -+# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set -+# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set -+# CONFIG_THERMAL_EMULATION is not set -+# CONFIG_THERMAL_GOV_BANG_BANG is not set -+# CONFIG_THERMAL_GOV_FAIR_SHARE is not set -+# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set -+# CONFIG_THERMAL_GOV_USER_SPACE is not set -+# CONFIG_THERMAL_HWMON is not set -+# CONFIG_THERMAL_WRITABLE_TRIPS is not set -+# CONFIG_THINKPAD_ACPI is not set -+CONFIG_THIN_ARCHIVES=y -+# CONFIG_THRUSTMASTER_FF is not set -+# CONFIG_THUNDERBOLT is not set -+# CONFIG_THUNDER_NIC_BGX is not set -+# CONFIG_THUNDER_NIC_PF is not set -+# CONFIG_THUNDER_NIC_RGX is not set -+# CONFIG_THUNDER_NIC_VF is not set -+# CONFIG_TICK_CPU_ACCOUNTING is not set -+CONFIG_TICK_ONESHOT=y -+# CONFIG_TIFM_CORE is not set -+# CONFIG_TIGON3 is not set -+# CONFIG_TIMB_DMA is not set -+CONFIG_TIMERFD=y -+# CONFIG_TIMER_STATS is not set -+CONFIG_TINY_RCU=y -+# CONFIG_TIPC is not set -+# CONFIG_TI_ADC081C is not set -+# CONFIG_TI_ADC0832 is not set -+# CONFIG_TI_ADC084S021 is not set -+# CONFIG_TI_ADC108S102 is not set -+# CONFIG_TI_ADC12138 is not set -+# CONFIG_TI_ADC128S052 is not set -+# CONFIG_TI_ADC161S626 is not set -+# CONFIG_TI_ADS1015 is not set -+# CONFIG_TI_ADS7950 is not set -+# CONFIG_TI_ADS8688 is not set -+# CONFIG_TI_AM335X_ADC is not set -+# CONFIG_TI_CPSW is not set -+# CONFIG_TI_CPSW_ALE is not set -+# CONFIG_TI_CPTS is not set -+# CONFIG_TI_DAC7512 is not set -+# CONFIG_TI_DAVINCI_CPDMA is not set -+# CONFIG_TI_DAVINCI_MDIO is not set -+# CONFIG_TI_ST is not set -+# CONFIG_TI_SYSCON_RESET is not set -+# CONFIG_TI_TLC4541 is not set -+# CONFIG_TLAN is not set -+# CONFIG_TLS is not set -+# CONFIG_TMD_HERMES is not set -+# CONFIG_TMP006 is not set -+# CONFIG_TMP007 is not set -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+CONFIG_TMPFS_XATTR=y -+# CONFIG_TOPSTAR_LAPTOP is not set -+# CONFIG_TORTURE_TEST is not set -+# CONFIG_TOSHIBA_HAPS is not set -+# CONFIG_TOUCHSCREEN_88PM860X is not set -+# CONFIG_TOUCHSCREEN_AD7877 is not set -+# CONFIG_TOUCHSCREEN_AD7879 is not set -+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set -+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set -+# CONFIG_TOUCHSCREEN_ADS7846 is not set -+# CONFIG_TOUCHSCREEN_AR1021_I2C is not set -+# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set -+# CONFIG_TOUCHSCREEN_ATMEL_MXT_T37 is not set -+# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set -+# CONFIG_TOUCHSCREEN_BU21013 is not set -+# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set -+# CONFIG_TOUCHSCREEN_COLIBRI_VF50 is not set -+# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set -+# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set -+# CONFIG_TOUCHSCREEN_CYTTSP4_I2C is not set -+# CONFIG_TOUCHSCREEN_CYTTSP4_SPI is not set -+# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set -+# CONFIG_TOUCHSCREEN_CYTTSP_I2C is not set -+# CONFIG_TOUCHSCREEN_CYTTSP_SPI is not set -+# CONFIG_TOUCHSCREEN_DA9034 is not set -+# CONFIG_TOUCHSCREEN_DA9052 is not set -+# CONFIG_TOUCHSCREEN_DYNAPRO is not set -+# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set -+# CONFIG_TOUCHSCREEN_EETI is not set -+# CONFIG_TOUCHSCREEN_EGALAX is not set -+# CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set -+# CONFIG_TOUCHSCREEN_EKTF2127 is not set -+# CONFIG_TOUCHSCREEN_ELAN is not set -+# CONFIG_TOUCHSCREEN_ELO is not set -+# CONFIG_TOUCHSCREEN_FUJITSU is not set -+# CONFIG_TOUCHSCREEN_GOODIX is not set -+# CONFIG_TOUCHSCREEN_GUNZE is not set -+# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set -+# CONFIG_TOUCHSCREEN_HP600 is not set -+# CONFIG_TOUCHSCREEN_HP7XX is not set -+# CONFIG_TOUCHSCREEN_HTCPEN is not set -+# CONFIG_TOUCHSCREEN_ILI210X is not set -+# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set -+# CONFIG_TOUCHSCREEN_INEXIO is not set -+# CONFIG_TOUCHSCREEN_IPAQ_MICRO is not set -+# CONFIG_TOUCHSCREEN_IPROC is not set -+# CONFIG_TOUCHSCREEN_LPC32XX is not set -+# CONFIG_TOUCHSCREEN_MAX11801 is not set -+# CONFIG_TOUCHSCREEN_MC13783 is not set -+# CONFIG_TOUCHSCREEN_MCS5000 is not set -+# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set -+# CONFIG_TOUCHSCREEN_MIGOR is not set -+# CONFIG_TOUCHSCREEN_MK712 is not set -+# CONFIG_TOUCHSCREEN_MMS114 is not set -+# CONFIG_TOUCHSCREEN_MTOUCH is not set -+# CONFIG_TOUCHSCREEN_MX25 is not set -+# CONFIG_TOUCHSCREEN_MXS_LRADC is not set -+# CONFIG_TOUCHSCREEN_PCAP is not set -+# CONFIG_TOUCHSCREEN_PENMOUNT is not set -+# CONFIG_TOUCHSCREEN_PIXCIR is not set -+# CONFIG_TOUCHSCREEN_PROPERTIES is not set -+# CONFIG_TOUCHSCREEN_RM_TS is not set -+# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set -+# CONFIG_TOUCHSCREEN_S3C2410 is not set -+# CONFIG_TOUCHSCREEN_SILEAD is not set -+# CONFIG_TOUCHSCREEN_SIS_I2C is not set -+# CONFIG_TOUCHSCREEN_ST1232 is not set -+# CONFIG_TOUCHSCREEN_STMFTS is not set -+# CONFIG_TOUCHSCREEN_STMPE is not set -+# CONFIG_TOUCHSCREEN_SUN4I is not set -+# CONFIG_TOUCHSCREEN_SUR40 is not set -+# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set -+# CONFIG_TOUCHSCREEN_SX8654 is not set -+# CONFIG_TOUCHSCREEN_TI_AM335X_TSC is not set -+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set -+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set -+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set -+# CONFIG_TOUCHSCREEN_TPS6507X is not set -+# CONFIG_TOUCHSCREEN_TS4800 is not set -+# CONFIG_TOUCHSCREEN_TSC2004 is not set -+# CONFIG_TOUCHSCREEN_TSC2005 is not set -+# CONFIG_TOUCHSCREEN_TSC2007 is not set -+# CONFIG_TOUCHSCREEN_TSC2007_IIO is not set -+# CONFIG_TOUCHSCREEN_TSC200X_CORE is not set -+# CONFIG_TOUCHSCREEN_TSC_SERIO is not set -+# CONFIG_TOUCHSCREEN_UCB1400 is not set -+# CONFIG_TOUCHSCREEN_USB_3M is not set -+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set -+# CONFIG_TOUCHSCREEN_USB_DMC_TSC10 is not set -+# CONFIG_TOUCHSCREEN_USB_E2I is not set -+# CONFIG_TOUCHSCREEN_USB_EASYTOUCH is not set -+# CONFIG_TOUCHSCREEN_USB_EGALAX is not set -+# CONFIG_TOUCHSCREEN_USB_ELO is not set -+# CONFIG_TOUCHSCREEN_USB_ETT_TC45USB is not set -+# CONFIG_TOUCHSCREEN_USB_ETURBO is not set -+# CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH is not set -+# CONFIG_TOUCHSCREEN_USB_GOTOP is not set -+# CONFIG_TOUCHSCREEN_USB_GUNZE is not set -+# CONFIG_TOUCHSCREEN_USB_IDEALTEK is not set -+# CONFIG_TOUCHSCREEN_USB_IRTOUCH is not set -+# CONFIG_TOUCHSCREEN_USB_ITM is not set -+# CONFIG_TOUCHSCREEN_USB_JASTEC is not set -+# CONFIG_TOUCHSCREEN_USB_NEXIO is not set -+# CONFIG_TOUCHSCREEN_USB_PANJIT is not set -+# CONFIG_TOUCHSCREEN_USB_ZYTRONIC is not set -+# CONFIG_TOUCHSCREEN_W90X900 is not set -+# CONFIG_TOUCHSCREEN_WACOM_I2C is not set -+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set -+# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set -+# CONFIG_TOUCHSCREEN_WM831X is not set -+# CONFIG_TOUCHSCREEN_WM9705 is not set -+# CONFIG_TOUCHSCREEN_WM9712 is not set -+# CONFIG_TOUCHSCREEN_WM9713 is not set -+# CONFIG_TOUCHSCREEN_WM97XX is not set -+# CONFIG_TOUCHSCREEN_WM97XX_ATMEL is not set -+# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set -+# CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE is not set -+# CONFIG_TOUCHSCREEN_ZET6223 is not set -+# CONFIG_TOUCHSCREEN_ZFORCE is not set -+# CONFIG_TPL0102 is not set -+# CONFIG_TPS6105X is not set -+# CONFIG_TPS65010 is not set -+# CONFIG_TPS6507X is not set -+# CONFIG_TRACEPOINT_BENCHMARK is not set -+# CONFIG_TRACER_SNAPSHOT is not set -+# CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set -+# CONFIG_TRACE_BRANCH_PROFILING is not set -+# CONFIG_TRACE_EVAL_MAP_FILE is not set -+CONFIG_TRACE_IRQFLAGS_SUPPORT=y -+# CONFIG_TRACE_SINK is not set -+# CONFIG_TRACING_EVENTS_GPIO is not set -+CONFIG_TRACING_SUPPORT=y -+CONFIG_TRAD_SIGNALS=y -+# CONFIG_TRANSPARENT_HUGEPAGE is not set -+# CONFIG_TREE_RCU is not set -+# CONFIG_TREE_RCU_TRACE is not set -+# CONFIG_TRIM_UNUSED_KSYMS is not set -+# CONFIG_TRUSTED_KEYS is not set -+# CONFIG_TSL2583 is not set -+# CONFIG_TSL2x7x is not set -+# CONFIG_TSL4531 is not set -+# CONFIG_TSYS01 is not set -+# CONFIG_TSYS02D is not set -+# CONFIG_TTPCI_EEPROM is not set -+CONFIG_TTY=y -+# CONFIG_TTY_PRINTK is not set -+# CONFIG_TUN is not set -+# CONFIG_TUN_VNET_CROSS_LE is not set -+# CONFIG_TWL4030_CORE is not set -+# CONFIG_TWL4030_MADC is not set -+# CONFIG_TWL6030_GPADC is not set -+# CONFIG_TWL6040_CORE is not set -+# CONFIG_TYPEC_TCPM is not set -+# CONFIG_TYPEC_UCSI is not set -+# CONFIG_TYPHOON is not set -+# CONFIG_UACCESS_WITH_MEMCPY is not set -+# CONFIG_UBIFS_ATIME_SUPPORT is not set -+# CONFIG_UBIFS_FS_ENCRYPTION is not set -+# CONFIG_UBIFS_FS_SECURITY is not set -+# CONFIG_UBSAN is not set -+# CONFIG_UCB1400_CORE is not set -+# CONFIG_UCSI is not set -+# CONFIG_UDF_FS is not set -+CONFIG_UDF_NLS=y -+CONFIG_UEVENT_HELPER=y -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+# CONFIG_UFS_FS is not set -+# CONFIG_UHID is not set -+CONFIG_UID16=y -+# CONFIG_UIO is not set -+# CONFIG_ULTRA is not set -+# CONFIG_ULTRIX_PARTITION is not set -+CONFIG_UNIX=y -+CONFIG_UNIX98_PTYS=y -+# CONFIG_UNIXWARE_DISKLABEL is not set -+# CONFIG_UNIX_DIAG is not set -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_UPROBES is not set -+# CONFIG_UPROBE_EVENTS is not set -+# CONFIG_US5182D is not set -+# CONFIG_USB is not set -+# CONFIG_USBIP_CORE is not set -+CONFIG_USBIP_VHCI_HC_PORTS=8 -+CONFIG_USBIP_VHCI_NR_HCS=1 -+# CONFIG_USBIP_VUDC is not set -+# CONFIG_USBPCWATCHDOG is not set -+# CONFIG_USB_ACM is not set -+# CONFIG_USB_ADUTUX is not set -+CONFIG_USB_ALI_M5632=y -+# CONFIG_USB_AMD5536UDC is not set -+CONFIG_USB_AN2720=y -+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set -+# CONFIG_USB_APPLEDISPLAY is not set -+CONFIG_USB_ARCH_HAS_HCD=y -+CONFIG_USB_ARMLINUX=y -+# CONFIG_USB_ATM is not set -+# CONFIG_USB_BDC_UDC is not set -+CONFIG_USB_BELKIN=y -+# CONFIG_USB_C67X00_HCD is not set -+# CONFIG_USB_CATC is not set -+# CONFIG_USB_CDC_COMPOSITE is not set -+# CONFIG_USB_CHAOSKEY is not set -+# CONFIG_USB_CHIPIDEA is not set -+# CONFIG_USB_CONFIGFS is not set -+# CONFIG_USB_CXACRU is not set -+# CONFIG_USB_CYPRESS_CY7C63 is not set -+# CONFIG_USB_CYTHERM is not set -+CONFIG_USB_DEFAULT_PERSIST=y -+# CONFIG_USB_DSBR is not set -+# CONFIG_USB_DUMMY_HCD is not set -+# CONFIG_USB_DWC2 is not set -+# CONFIG_USB_DWC2_DEBUG is not set -+# CONFIG_USB_DWC2_DUAL_ROLE is not set -+# CONFIG_USB_DWC2_HOST is not set -+# CONFIG_USB_DWC2_PERIPHERAL is not set -+# CONFIG_USB_DWC3 is not set -+# CONFIG_USB_DWC3_EXYNOS is not set -+# CONFIG_USB_DWC3_KEYSTONE is not set -+# CONFIG_USB_DWC3_OF_SIMPLE is not set -+# CONFIG_USB_DWC3_PCI is not set -+# CONFIG_USB_DWC3_QCOM is not set -+# CONFIG_USB_DYNAMIC_MINORS is not set -+# CONFIG_USB_EG20T is not set -+# CONFIG_USB_EHCI_ATH79 is not set -+# CONFIG_USB_EHCI_HCD is not set -+# CONFIG_USB_EHCI_HCD_AT91 is not set -+# CONFIG_USB_EHCI_HCD_OMAP is not set -+# CONFIG_USB_EHCI_HCD_PPC_OF is not set -+# CONFIG_USB_EHCI_MSM is not set -+# CONFIG_USB_EHCI_MV is not set -+CONFIG_USB_EHCI_ROOT_HUB_TT=y -+CONFIG_USB_EHCI_TT_NEWSCHED=y -+# CONFIG_USB_EHSET_TEST_FIXTURE is not set -+# CONFIG_USB_EMI26 is not set -+# CONFIG_USB_EMI62 is not set -+# CONFIG_USB_EPSON2888 is not set -+# CONFIG_USB_EZUSB_FX2 is not set -+# CONFIG_USB_FOTG210_HCD is not set -+# CONFIG_USB_FOTG210_UDC is not set -+# CONFIG_USB_FSL_USB2 is not set -+# CONFIG_USB_FTDI_ELAN is not set -+# CONFIG_USB_FUNCTIONFS is not set -+# CONFIG_USB_FUSB300 is not set -+# CONFIG_USB_GADGET is not set -+# CONFIG_USB_GADGETFS is not set -+# CONFIG_USB_GADGET_DEBUG is not set -+# CONFIG_USB_GADGET_DEBUG_FILES is not set -+# CONFIG_USB_GADGET_DEBUG_FS is not set -+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 -+CONFIG_USB_GADGET_VBUS_DRAW=2 -+# CONFIG_USB_GADGET_XILINX is not set -+# CONFIG_USB_GL860 is not set -+# CONFIG_USB_GOKU is not set -+# CONFIG_USB_GPIO_VBUS is not set -+# CONFIG_USB_GR_UDC is not set -+# CONFIG_USB_GSPCA is not set -+# CONFIG_USB_GSPCA_BENQ is not set -+# CONFIG_USB_GSPCA_CONEX is not set -+# CONFIG_USB_GSPCA_CPIA1 is not set -+# CONFIG_USB_GSPCA_DTCS033 is not set -+# CONFIG_USB_GSPCA_ETOMS is not set -+# CONFIG_USB_GSPCA_FINEPIX is not set -+# CONFIG_USB_GSPCA_JEILINJ is not set -+# CONFIG_USB_GSPCA_JL2005BCD is not set -+# CONFIG_USB_GSPCA_KINECT is not set -+# CONFIG_USB_GSPCA_KONICA is not set -+# CONFIG_USB_GSPCA_MARS is not set -+# CONFIG_USB_GSPCA_MR97310A is not set -+# CONFIG_USB_GSPCA_NW80X is not set -+# CONFIG_USB_GSPCA_OV519 is not set -+# CONFIG_USB_GSPCA_OV534 is not set -+# CONFIG_USB_GSPCA_OV534_9 is not set -+# CONFIG_USB_GSPCA_PAC207 is not set -+# CONFIG_USB_GSPCA_PAC7302 is not set -+# CONFIG_USB_GSPCA_PAC7311 is not set -+# CONFIG_USB_GSPCA_SE401 is not set -+# CONFIG_USB_GSPCA_SN9C2028 is not set -+# CONFIG_USB_GSPCA_SN9C20X is not set -+# CONFIG_USB_GSPCA_SONIXB is not set -+# CONFIG_USB_GSPCA_SONIXJ is not set -+# CONFIG_USB_GSPCA_SPCA1528 is not set -+# CONFIG_USB_GSPCA_SPCA500 is not set -+# CONFIG_USB_GSPCA_SPCA501 is not set -+# CONFIG_USB_GSPCA_SPCA505 is not set -+# CONFIG_USB_GSPCA_SPCA506 is not set -+# CONFIG_USB_GSPCA_SPCA508 is not set -+# CONFIG_USB_GSPCA_SPCA561 is not set -+# CONFIG_USB_GSPCA_SQ905 is not set -+# CONFIG_USB_GSPCA_SQ905C is not set -+# CONFIG_USB_GSPCA_SQ930X is not set -+# CONFIG_USB_GSPCA_STK014 is not set -+# CONFIG_USB_GSPCA_STK1135 is not set -+# CONFIG_USB_GSPCA_STV0680 is not set -+# CONFIG_USB_GSPCA_SUNPLUS is not set -+# CONFIG_USB_GSPCA_T613 is not set -+# CONFIG_USB_GSPCA_TOPRO is not set -+# CONFIG_USB_GSPCA_TOUPTEK is not set -+# CONFIG_USB_GSPCA_TV8532 is not set -+# CONFIG_USB_GSPCA_VC032X is not set -+# CONFIG_USB_GSPCA_VICAM is not set -+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set -+# CONFIG_USB_GSPCA_ZC3XX is not set -+# CONFIG_USB_G_ACM_MS is not set -+# CONFIG_USB_G_DBGP is not set -+# CONFIG_USB_G_HID is not set -+# CONFIG_USB_G_MULTI is not set -+# CONFIG_USB_G_NCM is not set -+# CONFIG_USB_G_NOKIA is not set -+# CONFIG_USB_G_PRINTER is not set -+# CONFIG_USB_G_SERIAL is not set -+# CONFIG_USB_G_WEBCAM is not set -+# CONFIG_USB_HCD_TEST_MODE is not set -+# CONFIG_USB_HID is not set -+# CONFIG_USB_HIDDEV is not set -+# CONFIG_USB_HSIC_USB3503 is not set -+# CONFIG_USB_HSIC_USB4604 is not set -+# CONFIG_USB_HSO is not set -+# CONFIG_USB_HUB_USB251XB is not set -+# CONFIG_USB_HWA_HCD is not set -+# CONFIG_USB_IDMOUSE is not set -+# CONFIG_USB_IMX21_HCD is not set -+# CONFIG_USB_IOWARRIOR is not set -+# CONFIG_USB_IPHETH is not set -+# CONFIG_USB_ISIGHTFW is not set -+# CONFIG_USB_ISP116X_HCD is not set -+# CONFIG_USB_ISP1301 is not set -+# CONFIG_USB_ISP1362_HCD is not set -+# CONFIG_USB_ISP1760 is not set -+# CONFIG_USB_ISP1760_HCD is not set -+# CONFIG_USB_KAWETH is not set -+# CONFIG_USB_KBD is not set -+# CONFIG_USB_KC2190 is not set -+# CONFIG_USB_LAN78XX is not set -+# CONFIG_USB_LCD is not set -+# CONFIG_USB_LD is not set -+# CONFIG_USB_LED is not set -+# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set -+# CONFIG_USB_LED_TRIG is not set -+# CONFIG_USB_LEGOTOWER is not set -+# CONFIG_USB_LINK_LAYER_TEST is not set -+# CONFIG_USB_M5602 is not set -+# CONFIG_USB_M66592 is not set -+# CONFIG_USB_MASS_STORAGE is not set -+# CONFIG_USB_MAX3421_HCD is not set -+# CONFIG_USB_MDC800 is not set -+# CONFIG_USB_MICROTEK is not set -+# CONFIG_USB_MIDI_GADGET is not set -+# CONFIG_USB_MON is not set -+# CONFIG_USB_MOUSE is not set -+# CONFIG_USB_MSM_OTG is not set -+# CONFIG_USB_MTU3 is not set -+# CONFIG_USB_MUSB_HDRC is not set -+# CONFIG_USB_MV_U3D is not set -+# CONFIG_USB_MV_UDC is not set -+# CONFIG_USB_MXS_PHY is not set -+# CONFIG_USB_NET2272 is not set -+# CONFIG_USB_NET2280 is not set -+# CONFIG_USB_NET_AX88179_178A is not set -+# CONFIG_USB_NET_AX8817X is not set -+# CONFIG_USB_NET_CDCETHER is not set -+# CONFIG_USB_NET_CDC_EEM is not set -+# CONFIG_USB_NET_CDC_MBIM is not set -+# CONFIG_USB_NET_CDC_NCM is not set -+# CONFIG_USB_NET_CDC_SUBSET is not set -+# CONFIG_USB_NET_CH9200 is not set -+# CONFIG_USB_NET_CX82310_ETH is not set -+# CONFIG_USB_NET_DM9601 is not set -+# CONFIG_USB_NET_DRIVERS is not set -+# CONFIG_USB_NET_GL620A is not set -+# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set -+# CONFIG_USB_NET_INT51X1 is not set -+# CONFIG_USB_NET_KALMIA is not set -+# CONFIG_USB_NET_MCS7830 is not set -+# CONFIG_USB_NET_NET1080 is not set -+# CONFIG_USB_NET_PLUSB is not set -+# CONFIG_USB_NET_QMI_WWAN is not set -+# CONFIG_USB_NET_RNDIS_HOST is not set -+# CONFIG_USB_NET_RNDIS_WLAN is not set -+# CONFIG_USB_NET_SMSC75XX is not set -+# CONFIG_USB_NET_SMSC95XX is not set -+# CONFIG_USB_NET_SR9700 is not set -+# CONFIG_USB_NET_SR9800 is not set -+# CONFIG_USB_NET_ZAURUS is not set -+# CONFIG_USB_OHCI_HCD is not set -+# CONFIG_USB_OHCI_HCD_PCI is not set -+# CONFIG_USB_OHCI_HCD_PPC_OF is not set -+# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set -+# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set -+# CONFIG_USB_OHCI_HCD_SSB is not set -+CONFIG_USB_OHCI_LITTLE_ENDIAN=y -+# CONFIG_USB_OTG is not set -+# CONFIG_USB_OTG_BLACKLIST_HUB is not set -+# CONFIG_USB_OTG_FSM is not set -+# CONFIG_USB_OTG_WHITELIST is not set -+# CONFIG_USB_OXU210HP_HCD is not set -+# CONFIG_USB_PCI is not set -+# CONFIG_USB_PEGASUS is not set -+# CONFIG_USB_PHY is not set -+# CONFIG_USB_PRINTER is not set -+# CONFIG_USB_PWC_INPUT_EVDEV is not set -+# CONFIG_USB_PXA27X is not set -+# CONFIG_USB_R8A66597 is not set -+# CONFIG_USB_R8A66597_HCD is not set -+# CONFIG_USB_RCAR_PHY is not set -+# CONFIG_USB_RENESAS_USBHS is not set -+# CONFIG_USB_RIO500 is not set -+# CONFIG_USB_RTL8150 is not set -+# CONFIG_USB_RTL8152 is not set -+# CONFIG_USB_S2255 is not set -+# CONFIG_USB_SERIAL is not set -+# CONFIG_USB_SERIAL_AIRCABLE is not set -+# CONFIG_USB_SERIAL_ARK3116 is not set -+# CONFIG_USB_SERIAL_BELKIN is not set -+# CONFIG_USB_SERIAL_CH341 is not set -+# CONFIG_USB_SERIAL_CP210X is not set -+# CONFIG_USB_SERIAL_CYBERJACK is not set -+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set -+# CONFIG_USB_SERIAL_DEBUG is not set -+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -+# CONFIG_USB_SERIAL_EDGEPORT is not set -+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set -+# CONFIG_USB_SERIAL_EMPEG is not set -+# CONFIG_USB_SERIAL_F81232 is not set -+# CONFIG_USB_SERIAL_F8153X is not set -+# CONFIG_USB_SERIAL_FTDI_SIO is not set -+# CONFIG_USB_SERIAL_GARMIN is not set -+CONFIG_USB_SERIAL_GENERIC=y -+# CONFIG_USB_SERIAL_IPAQ is not set -+# CONFIG_USB_SERIAL_IPW is not set -+# CONFIG_USB_SERIAL_IR is not set -+# CONFIG_USB_SERIAL_IUU is not set -+# CONFIG_USB_SERIAL_KEYSPAN is not set -+CONFIG_USB_SERIAL_KEYSPAN_MPR=y -+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y -+CONFIG_USB_SERIAL_KEYSPAN_USA19=y -+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y -+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y -+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y -+CONFIG_USB_SERIAL_KEYSPAN_USA28=y -+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y -+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y -+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y -+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y -+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y -+# CONFIG_USB_SERIAL_KLSI is not set -+# CONFIG_USB_SERIAL_KOBIL_SCT is not set -+# CONFIG_USB_SERIAL_MCT_U232 is not set -+# CONFIG_USB_SERIAL_METRO is not set -+# CONFIG_USB_SERIAL_MOS7715_PARPORT is not set -+# CONFIG_USB_SERIAL_MOS7720 is not set -+# CONFIG_USB_SERIAL_MOS7840 is not set -+# CONFIG_USB_SERIAL_MXUPORT is not set -+# CONFIG_USB_SERIAL_NAVMAN is not set -+# CONFIG_USB_SERIAL_OMNINET is not set -+# CONFIG_USB_SERIAL_OPTICON is not set -+# CONFIG_USB_SERIAL_OPTION is not set -+# CONFIG_USB_SERIAL_OTI6858 is not set -+# CONFIG_USB_SERIAL_PL2303 is not set -+# CONFIG_USB_SERIAL_QCAUX is not set -+# CONFIG_USB_SERIAL_QT2 is not set -+# CONFIG_USB_SERIAL_QUALCOMM is not set -+# CONFIG_USB_SERIAL_SAFE is not set -+CONFIG_USB_SERIAL_SAFE_PADDED=y -+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set -+# CONFIG_USB_SERIAL_SIMPLE is not set -+# CONFIG_USB_SERIAL_SPCP8X5 is not set -+# CONFIG_USB_SERIAL_SSU100 is not set -+# CONFIG_USB_SERIAL_SYMBOL is not set -+# CONFIG_USB_SERIAL_TI is not set -+# CONFIG_USB_SERIAL_UPD78F0730 is not set -+# CONFIG_USB_SERIAL_VISOR is not set -+# CONFIG_USB_SERIAL_WHITEHEAT is not set -+# CONFIG_USB_SERIAL_WISHBONE is not set -+# CONFIG_USB_SERIAL_XIRCOM is not set -+# CONFIG_USB_SERIAL_XSENS_MT is not set -+# CONFIG_USB_SEVSEG is not set -+# CONFIG_USB_SIERRA_NET is not set -+# CONFIG_USB_SISUSBVGA is not set -+# CONFIG_USB_SL811_HCD is not set -+# CONFIG_USB_SNP_UDC_PLAT is not set -+# CONFIG_USB_SPEEDTOUCH is not set -+# CONFIG_USB_STKWEBCAM is not set -+# CONFIG_USB_STORAGE is not set -+# CONFIG_USB_STORAGE_ALAUDA is not set -+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -+# CONFIG_USB_STORAGE_DATAFAB is not set -+# CONFIG_USB_STORAGE_DEBUG is not set -+# CONFIG_USB_STORAGE_ENE_UB6250 is not set -+# CONFIG_USB_STORAGE_FREECOM is not set -+# CONFIG_USB_STORAGE_ISD200 is not set -+# CONFIG_USB_STORAGE_JUMPSHOT is not set -+# CONFIG_USB_STORAGE_KARMA is not set -+# CONFIG_USB_STORAGE_ONETOUCH is not set -+# CONFIG_USB_STORAGE_REALTEK is not set -+# CONFIG_USB_STORAGE_SDDR09 is not set -+# CONFIG_USB_STORAGE_SDDR55 is not set -+# CONFIG_USB_STORAGE_USBAT is not set -+# CONFIG_USB_STV06XX is not set -+# CONFIG_USB_SUPPORT is not set -+# CONFIG_USB_SWITCH_FSA9480 is not set -+# CONFIG_USB_TEST is not set -+# CONFIG_USB_TMC is not set -+# CONFIG_USB_TRANCEVIBRATOR is not set -+# CONFIG_USB_UAS is not set -+# CONFIG_USB_UEAGLEATM is not set -+# CONFIG_USB_ULPI is not set -+# CONFIG_USB_ULPI_BUS is not set -+# CONFIG_USB_USBNET is not set -+# CONFIG_USB_USS720 is not set -+# CONFIG_USB_VIDEO_CLASS is not set -+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -+# CONFIG_USB_VL600 is not set -+# CONFIG_USB_WDM is not set -+# CONFIG_USB_WHCI_HCD is not set -+# CONFIG_USB_WUSB is not set -+# CONFIG_USB_WUSB_CBAF is not set -+# CONFIG_USB_XHCI_HCD is not set -+# CONFIG_USB_XHCI_MVEBU is not set -+# CONFIG_USB_XHCI_TEGRA is not set -+# CONFIG_USB_XUSBATM is not set -+# CONFIG_USB_YUREX is not set -+# CONFIG_USB_ZD1201 is not set -+# CONFIG_USB_ZERO is not set -+# CONFIG_USB_ZR364XX is not set -+# CONFIG_USELIB is not set -+# CONFIG_USERFAULTFD is not set -+# CONFIG_USE_OF is not set -+# CONFIG_UTS_NS is not set -+# CONFIG_UWB is not set -+# CONFIG_U_SERIAL_CONSOLE is not set -+# CONFIG_V4L_MEM2MEM_DRIVERS is not set -+# CONFIG_V4L_TEST_DRIVERS is not set -+# CONFIG_VCNL4000 is not set -+# CONFIG_VDSO is not set -+# CONFIG_VEML6070 is not set -+# CONFIG_VETH is not set -+# CONFIG_VEXPRESS_CONFIG is not set -+# CONFIG_VF610_ADC is not set -+# CONFIG_VF610_DAC is not set -+# CONFIG_VFAT_FS is not set -+# CONFIG_VGASTATE is not set -+# CONFIG_VGA_ARB is not set -+# CONFIG_VGA_SWITCHEROO is not set -+# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set -+# CONFIG_VHOST_NET is not set -+# CONFIG_VHOST_VSOCK is not set -+# CONFIG_VIA_RHINE is not set -+# CONFIG_VIA_VELOCITY is not set -+# CONFIG_VIDEO_ADV7170 is not set -+# CONFIG_VIDEO_ADV7175 is not set -+# CONFIG_VIDEO_ADV7180 is not set -+# CONFIG_VIDEO_ADV7183 is not set -+# CONFIG_VIDEO_ADV7343 is not set -+# CONFIG_VIDEO_ADV7393 is not set -+# CONFIG_VIDEO_ADV_DEBUG is not set -+# CONFIG_VIDEO_AK881X is not set -+# CONFIG_VIDEO_BT819 is not set -+# CONFIG_VIDEO_BT848 is not set -+# CONFIG_VIDEO_BT856 is not set -+# CONFIG_VIDEO_BT866 is not set -+# CONFIG_VIDEO_CAFE_CCIC is not set -+# CONFIG_VIDEO_CS3308 is not set -+# CONFIG_VIDEO_CS5345 is not set -+# CONFIG_VIDEO_CS53L32A is not set -+# CONFIG_VIDEO_CX231XX is not set -+# CONFIG_VIDEO_CX2341X is not set -+# CONFIG_VIDEO_CX25840 is not set -+# CONFIG_VIDEO_CX88 is not set -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_VIDEO_DM6446_CCDC is not set -+# CONFIG_VIDEO_DT3155 is not set -+# CONFIG_VIDEO_EM28XX is not set -+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -+# CONFIG_VIDEO_GO7007 is not set -+# CONFIG_VIDEO_HDPVR is not set -+# CONFIG_VIDEO_HEXIUM_GEMINI is not set -+# CONFIG_VIDEO_HEXIUM_ORION is not set -+# CONFIG_VIDEO_IR_I2C is not set -+# CONFIG_VIDEO_IVTV is not set -+# CONFIG_VIDEO_KS0127 is not set -+# CONFIG_VIDEO_M52790 is not set -+# CONFIG_VIDEO_ML86V7667 is not set -+# CONFIG_VIDEO_MSP3400 is not set -+# CONFIG_VIDEO_MT9M111 is not set -+# CONFIG_VIDEO_MT9V011 is not set -+# CONFIG_VIDEO_MXB is not set -+# CONFIG_VIDEO_NOON010PC30 is not set -+# CONFIG_VIDEO_OMAP2_VOUT is not set -+# CONFIG_VIDEO_OV2640 is not set -+# CONFIG_VIDEO_OV2659 is not set -+# CONFIG_VIDEO_OV6650 is not set -+# CONFIG_VIDEO_OV7640 is not set -+# CONFIG_VIDEO_OV7670 is not set -+# CONFIG_VIDEO_PVRUSB2 is not set -+# CONFIG_VIDEO_SAA6588 is not set -+# CONFIG_VIDEO_SAA6752HS is not set -+# CONFIG_VIDEO_SAA7110 is not set -+# CONFIG_VIDEO_SAA711X is not set -+# CONFIG_VIDEO_SAA7127 is not set -+# CONFIG_VIDEO_SAA7134 is not set -+# CONFIG_VIDEO_SAA717X is not set -+# CONFIG_VIDEO_SAA7185 is not set -+# CONFIG_VIDEO_SH_MOBILE_CEU is not set -+# CONFIG_VIDEO_SONY_BTF_MPX is not set -+# CONFIG_VIDEO_SR030PC30 is not set -+# CONFIG_VIDEO_TDA7432 is not set -+# CONFIG_VIDEO_TDA9840 is not set -+# CONFIG_VIDEO_TEA6415C is not set -+# CONFIG_VIDEO_TEA6420 is not set -+# CONFIG_VIDEO_THS7303 is not set -+# CONFIG_VIDEO_THS8200 is not set -+# CONFIG_VIDEO_TIMBERDALE is not set -+# CONFIG_VIDEO_TLV320AIC23B is not set -+# CONFIG_VIDEO_TM6000 is not set -+# CONFIG_VIDEO_TVAUDIO is not set -+# CONFIG_VIDEO_TVP514X is not set -+# CONFIG_VIDEO_TVP5150 is not set -+# CONFIG_VIDEO_TVP7002 is not set -+# CONFIG_VIDEO_TW2804 is not set -+# CONFIG_VIDEO_TW9903 is not set -+# CONFIG_VIDEO_TW9906 is not set -+# CONFIG_VIDEO_UDA1342 is not set -+# CONFIG_VIDEO_UPD64031A is not set -+# CONFIG_VIDEO_UPD64083 is not set -+# CONFIG_VIDEO_USBTV is not set -+# CONFIG_VIDEO_USBVISION is not set -+# CONFIG_VIDEO_V4L2 is not set -+# CONFIG_VIDEO_VP27SMPX is not set -+# CONFIG_VIDEO_VPX3220 is not set -+# CONFIG_VIDEO_VS6624 is not set -+# CONFIG_VIDEO_WM8739 is not set -+# CONFIG_VIDEO_WM8775 is not set -+# CONFIG_VIDEO_ZORAN is not set -+# CONFIG_VIRTIO_BALLOON is not set -+# CONFIG_VIRTIO_BLK_SCSI is not set -+# CONFIG_VIRTIO_INPUT is not set -+# CONFIG_VIRTIO_MMIO is not set -+# CONFIG_VIRTIO_PCI is not set -+# CONFIG_VIRTUALIZATION is not set -+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set -+# CONFIG_VIRT_DRIVERS is not set -+CONFIG_VIRT_TO_BUS=y -+# CONFIG_VITESSE_PHY is not set -+# CONFIG_VL6180 is not set -+CONFIG_VLAN_8021Q=y -+# CONFIG_VLAN_8021Q_GVRP is not set -+# CONFIG_VLAN_8021Q_MVRP is not set -+# CONFIG_VME_BUS is not set -+# CONFIG_VMSPLIT_1G is not set -+# CONFIG_VMSPLIT_2G is not set -+# CONFIG_VMSPLIT_2G_OPT is not set -+CONFIG_VMSPLIT_3G=y -+# CONFIG_VMSPLIT_3G_OPT is not set -+# CONFIG_VMWARE_PVSCSI is not set -+# CONFIG_VMXNET3 is not set -+# CONFIG_VM_EVENT_COUNTERS is not set -+# CONFIG_VOP_BUS is not set -+# CONFIG_VORTEX is not set -+# CONFIG_VSOCKETS is not set -+# CONFIG_VT is not set -+# CONFIG_VT6655 is not set -+# CONFIG_VT6656 is not set -+# CONFIG_VXFS_FS is not set -+# CONFIG_VXGE is not set -+# CONFIG_VXLAN is not set -+# CONFIG_VZ89X is not set -+# CONFIG_W1 is not set -+# CONFIG_W1_CON is not set -+# CONFIG_W1_MASTER_DS1WM is not set -+# CONFIG_W1_MASTER_DS2482 is not set -+# CONFIG_W1_MASTER_DS2490 is not set -+# CONFIG_W1_MASTER_GPIO is not set -+# CONFIG_W1_MASTER_MATROX is not set -+# CONFIG_W1_SLAVE_DS2405 is not set -+# CONFIG_W1_SLAVE_DS2406 is not set -+# CONFIG_W1_SLAVE_DS2408 is not set -+# CONFIG_W1_SLAVE_DS2413 is not set -+# CONFIG_W1_SLAVE_DS2423 is not set -+# CONFIG_W1_SLAVE_DS2431 is not set -+# CONFIG_W1_SLAVE_DS2433 is not set -+# CONFIG_W1_SLAVE_DS2438 is not set -+# CONFIG_W1_SLAVE_DS2760 is not set -+# CONFIG_W1_SLAVE_DS2780 is not set -+# CONFIG_W1_SLAVE_DS2781 is not set -+# CONFIG_W1_SLAVE_DS2805 is not set -+# CONFIG_W1_SLAVE_DS28E04 is not set -+# CONFIG_W1_SLAVE_SMEM is not set -+# CONFIG_W1_SLAVE_THERM is not set -+# CONFIG_W83627HF_WDT is not set -+# CONFIG_W83877F_WDT is not set -+# CONFIG_W83977F_WDT is not set -+# CONFIG_WAN is not set -+# CONFIG_WANXL is not set -+# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set -+CONFIG_WATCHDOG=y -+# CONFIG_WATCHDOG_CORE is not set -+CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y -+# CONFIG_WATCHDOG_NOWAYOUT is not set -+# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set -+# CONFIG_WATCHDOG_SYSFS is not set -+# CONFIG_WD80x3 is not set -+# CONFIG_WDAT_WDT is not set -+# CONFIG_WDTPCI is not set -+CONFIG_WEXT_CORE=y -+CONFIG_WEXT_PRIV=y -+CONFIG_WEXT_PROC=y -+CONFIG_WEXT_SPY=y -+CONFIG_WILINK_PLATFORM_DATA=y -+# CONFIG_WIMAX is not set -+CONFIG_WIRELESS=y -+CONFIG_WIRELESS_EXT=y -+# CONFIG_WIRELESS_WDS is not set -+# CONFIG_WIZNET_W5100 is not set -+# CONFIG_WIZNET_W5300 is not set -+# CONFIG_WL1251 is not set -+# CONFIG_WL12XX is not set -+# CONFIG_WL18XX is not set -+CONFIG_WLAN=y -+# CONFIG_WLAN_VENDOR_ADMTEK is not set -+# CONFIG_WLAN_VENDOR_ATH is not set -+# CONFIG_WLAN_VENDOR_ATMEL is not set -+# CONFIG_WLAN_VENDOR_BROADCOM is not set -+# CONFIG_WLAN_VENDOR_CISCO is not set -+# CONFIG_WLAN_VENDOR_INTEL is not set -+# CONFIG_WLAN_VENDOR_INTERSIL is not set -+# CONFIG_WLAN_VENDOR_MARVELL is not set -+# CONFIG_WLAN_VENDOR_MEDIATEK is not set -+# CONFIG_WLAN_VENDOR_QUANTENNA is not set -+# CONFIG_WLAN_VENDOR_RALINK is not set -+# CONFIG_WLAN_VENDOR_REALTEK is not set -+# CONFIG_WLAN_VENDOR_RSI is not set -+# CONFIG_WLAN_VENDOR_ST is not set -+# CONFIG_WLAN_VENDOR_TI is not set -+# CONFIG_WLAN_VENDOR_ZYDAS is not set -+# CONFIG_WLCORE is not set -+CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y -+# CONFIG_WQ_WATCHDOG is not set -+# CONFIG_WW_MUTEX_SELFTEST is not set -+# CONFIG_X25 is not set -+# CONFIG_X509_CERTIFICATE_PARSER is not set -+# CONFIG_X86_PKG_TEMP_THERMAL is not set -+CONFIG_X86_SYSFB=y -+# CONFIG_XEN is not set -+CONFIG_XFRM=y -+# CONFIG_XFRM_IPCOMP is not set -+# CONFIG_XFRM_MIGRATE is not set -+# CONFIG_XFRM_STATISTICS is not set -+# CONFIG_XFRM_SUB_POLICY is not set -+# CONFIG_XFRM_USER is not set -+# CONFIG_XFS_DEBUG is not set -+# CONFIG_XFS_FS is not set -+# CONFIG_XFS_POSIX_ACL is not set -+# CONFIG_XFS_QUOTA is not set -+# CONFIG_XFS_RT is not set -+# CONFIG_XFS_WARN is not set -+# CONFIG_XILINX_AXI_EMAC is not set -+# CONFIG_XILINX_DMA is not set -+# CONFIG_XILINX_EMACLITE is not set -+# CONFIG_XILINX_GMII2RGMII is not set -+# CONFIG_XILINX_LL_TEMAC is not set -+# CONFIG_XILINX_WATCHDOG is not set -+# CONFIG_XILINX_ZYNQMP_DMA is not set -+# CONFIG_XILLYBUS is not set -+# CONFIG_XIP_KERNEL is not set -+# CONFIG_XMON is not set -+CONFIG_XZ_DEC=y -+# CONFIG_XZ_DEC_ARM is not set -+# CONFIG_XZ_DEC_ARMTHUMB is not set -+# CONFIG_XZ_DEC_BCJ is not set -+# CONFIG_XZ_DEC_IA64 is not set -+# CONFIG_XZ_DEC_POWERPC is not set -+# CONFIG_XZ_DEC_SPARC is not set -+# CONFIG_XZ_DEC_TEST is not set -+# CONFIG_XZ_DEC_X86 is not set -+# CONFIG_YAM is not set -+# CONFIG_YELLOWFIN is not set -+# CONFIG_YENTA is not set -+# CONFIG_YENTA_O2 is not set -+# CONFIG_YENTA_RICOH is not set -+# CONFIG_YENTA_TI is not set -+# CONFIG_YENTA_TOSHIBA is not set -+# CONFIG_ZBUD is not set -+# CONFIG_ZD1211RW is not set -+# CONFIG_ZD1211RW_DEBUG is not set -+# CONFIG_ZEROPLUS_FF is not set -+# CONFIG_ZIIRAVE_WATCHDOG is not set -+# CONFIG_ZISOFS is not set -+# CONFIG_ZLIB_DEFLATE is not set -+# CONFIG_ZLIB_INFLATE is not set -+CONFIG_ZONE_DMA=y -+# CONFIG_ZPA2326 is not set -+# CONFIG_ZPOOL is not set -+# CONFIG_ZRAM is not set -+# CONFIG_ZSMALLOC is not set -+# CONFIG_ZX_TDM is not set -diff --git a/target/linux/generic/hack-4.14/204-module_strip.patch b/target/linux/generic/hack-4.14/204-module_strip.patch -new file mode 100644 -index 0000000000..c53963c530 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/204-module_strip.patch -@@ -0,0 +1,208 @@ -+From a779a482fb9b9f8fcdf8b2519c789b4b9bb5dd05 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Fri, 7 Jul 2017 16:56:48 +0200 -+Subject: build: add a hack for removing non-essential module info -+ -+Signed-off-by: Felix Fietkau -+--- -+ include/linux/module.h | 13 ++++++++----- -+ include/linux/moduleparam.h | 15 ++++++++++++--- -+ init/Kconfig | 7 +++++++ -+ kernel/module.c | 5 ++++- -+ scripts/mod/modpost.c | 12 ++++++++++++ -+ 5 files changed, 43 insertions(+), 9 deletions(-) -+ -+--- a/include/linux/module.h -++++ b/include/linux/module.h -+@@ -158,6 +158,7 @@ extern void cleanup_module(void); -+ -+ /* Generic info of form tag = "info" */ -+ #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info) -++#define MODULE_INFO_STRIP(tag, info) __MODULE_INFO_STRIP(tag, tag, info) -+ -+ /* For userspace: you can also call me... */ -+ #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias) -+@@ -201,12 +202,12 @@ extern void cleanup_module(void); -+ * Author(s), use "Name " or just "Name", for multiple -+ * authors use multiple MODULE_AUTHOR() statements/lines. -+ */ -+-#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author) -++#define MODULE_AUTHOR(_author) MODULE_INFO_STRIP(author, _author) -+ -+ /* What your module does. */ -+-#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description) -++#define MODULE_DESCRIPTION(_description) MODULE_INFO_STRIP(description, _description) -+ -+-#ifdef MODULE -++#if defined(MODULE) && !defined(CONFIG_MODULE_STRIPPED) -+ /* Creates an alias so file2alias.c can find device table. */ -+ #define MODULE_DEVICE_TABLE(type, name) \ -+ extern typeof(name) __mod_##type##__##name##_device_table \ -+@@ -233,7 +234,9 @@ extern typeof(name) __mod_##type##__##na -+ */ -+ -+ #if defined(MODULE) || !defined(CONFIG_SYSFS) -+-#define MODULE_VERSION(_version) MODULE_INFO(version, _version) -++#define MODULE_VERSION(_version) MODULE_INFO_STRIP(version, _version) -++#elif defined(CONFIG_MODULE_STRIPPED) -++#define MODULE_VERSION(_version) __MODULE_INFO_DISABLED(version) -+ #else -+ #define MODULE_VERSION(_version) \ -+ static struct module_version_attribute ___modver_attr = { \ -+@@ -255,7 +258,7 @@ extern typeof(name) __mod_##type##__##na -+ /* Optional firmware file (or files) needed by the module -+ * format is simply firmware file name. Multiple firmware -+ * files require multiple MODULE_FIRMWARE() specifiers */ -+-#define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware) -++#define MODULE_FIRMWARE(_firmware) MODULE_INFO_STRIP(firmware, _firmware) -+ -+ struct notifier_block; -+ -+--- a/include/linux/moduleparam.h -++++ b/include/linux/moduleparam.h -+@@ -17,6 +17,16 @@ -+ /* Chosen so that structs with an unsigned long line up. */ -+ #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long)) -+ -++/* This struct is here for syntactic coherency, it is not used */ -++#define __MODULE_INFO_DISABLED(name) \ -++ struct __UNIQUE_ID(name) {} -++ -++#ifdef CONFIG_MODULE_STRIPPED -++#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO_DISABLED(name) -++#else -++#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO(tag, name, info) -++#endif -++ -+ #ifdef MODULE -+ #define __MODULE_INFO(tag, name, info) \ -+ static const char __UNIQUE_ID(name)[] \ -+@@ -24,8 +34,7 @@ static const char __UNIQUE_ID(name)[] -+ = __stringify(tag) "=" info -+ #else /* !MODULE */ -+ /* This struct is here for syntactic coherency, it is not used */ -+-#define __MODULE_INFO(tag, name, info) \ -+- struct __UNIQUE_ID(name) {} -++#define __MODULE_INFO(tag, name, info) __MODULE_INFO_DISABLED(name) -+ #endif -+ #define __MODULE_PARM_TYPE(name, _type) \ -+ __MODULE_INFO(parmtype, name##type, #name ":" _type) -+@@ -33,7 +42,7 @@ static const char __UNIQUE_ID(name)[] -+ /* One for each parameter, describing how to use it. Some files do -+ multiple of these per line, so can't just use MODULE_INFO. */ -+ #define MODULE_PARM_DESC(_parm, desc) \ -+- __MODULE_INFO(parm, _parm, #_parm ":" desc) -++ __MODULE_INFO_STRIP(parm, _parm, #_parm ":" desc) -+ -+ struct kernel_param; -+ -+--- a/init/Kconfig -++++ b/init/Kconfig -+@@ -1903,6 +1903,13 @@ config TRIM_UNUSED_KSYMS -+ -+ If unsure, or if you need to build out-of-tree modules, say N. -+ -++config MODULE_STRIPPED -++ bool "Reduce module size" -++ depends on MODULES -++ help -++ Remove module parameter descriptions, author info, version, aliases, -++ device tables, etc. -++ -+ endif # MODULES -+ -+ config MODULES_TREE_LOOKUP -+--- a/kernel/module.c -++++ b/kernel/module.c -+@@ -3024,9 +3024,11 @@ static struct module *setup_load_info(st -+ -+ static int check_modinfo(struct module *mod, struct load_info *info, int flags) -+ { -+- const char *modmagic = get_modinfo(info, "vermagic"); -+ int err; -+ -++#ifndef CONFIG_MODULE_STRIPPED -++ const char *modmagic = get_modinfo(info, "vermagic"); -++ -+ if (flags & MODULE_INIT_IGNORE_VERMAGIC) -+ modmagic = NULL; -+ -+@@ -3047,6 +3049,7 @@ static int check_modinfo(struct module * -+ mod->name); -+ add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK); -+ } -++#endif -+ -+ check_modinfo_retpoline(mod, info); -+ -+--- a/scripts/mod/modpost.c -++++ b/scripts/mod/modpost.c -+@@ -1996,7 +1996,9 @@ static void read_symbols(char *modname) -+ symname = remove_dot(info.strtab + sym->st_name); -+ -+ handle_modversions(mod, &info, sym, symname); -++#ifndef CONFIG_MODULE_STRIPPED -+ handle_moddevtable(mod, &info, sym, symname); -++#endif -+ } -+ if (!is_vmlinux(modname) || -+ (is_vmlinux(modname) && vmlinux_section_warnings)) -+@@ -2157,8 +2159,10 @@ static void add_header(struct buffer *b, -+ buf_printf(b, "#include \n"); -+ buf_printf(b, "#include \n"); -+ buf_printf(b, "\n"); -++#ifndef CONFIG_MODULE_STRIPPED -+ buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); -+ buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n"); -++#endif -+ buf_printf(b, "\n"); -+ buf_printf(b, "__visible struct module __this_module\n"); -+ buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n"); -+@@ -2175,8 +2179,10 @@ static void add_header(struct buffer *b, -+ -+ static void add_intree_flag(struct buffer *b, int is_intree) -+ { -++#ifndef CONFIG_MODULE_STRIPPED -+ if (is_intree) -+ buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n"); -++#endif -+ } -+ -+ /* Cannot check for assembler */ -+@@ -2189,10 +2195,12 @@ static void add_retpoline(struct buffer -+ -+ static void add_staging_flag(struct buffer *b, const char *name) -+ { -++#ifndef CONFIG_MODULE_STRIPPED -+ static const char *staging_dir = "drivers/staging"; -+ -+ if (strncmp(staging_dir, name, strlen(staging_dir)) == 0) -+ buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); -++#endif -+ } -+ -+ /** -+@@ -2291,11 +2299,13 @@ static void add_depends(struct buffer *b -+ -+ static void add_srcversion(struct buffer *b, struct module *mod) -+ { -++#ifndef CONFIG_MODULE_STRIPPED -+ if (mod->srcversion[0]) { -+ buf_printf(b, "\n"); -+ buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n", -+ mod->srcversion); -+ } -++#endif -+ } -+ -+ static void write_if_changed(struct buffer *b, const char *fname) -+@@ -2532,7 +2542,9 @@ int main(int argc, char **argv) -+ add_staging_flag(&buf, mod->name); -+ err |= add_versions(&buf, mod); -+ add_depends(&buf, mod, modules); -++#ifndef CONFIG_MODULE_STRIPPED -+ add_moddevtable(&buf, mod); -++#endif -+ add_srcversion(&buf, mod); -+ -+ sprintf(fname, "%s.mod.c", mod->name); -diff --git a/target/linux/generic/hack-4.14/207-disable-modorder.patch b/target/linux/generic/hack-4.14/207-disable-modorder.patch -new file mode 100644 -index 0000000000..0cfb4d33ec ---- /dev/null -+++ b/target/linux/generic/hack-4.14/207-disable-modorder.patch -@@ -0,0 +1,44 @@ -+From c9ef4ab0f54356ee9f91d9676ea0ec123840ddc7 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Fri, 7 Jul 2017 16:57:33 +0200 -+Subject: kernel: do not build modules.order -+ -+It is not needed for anything on the system and skipping this saves some -+build time, especially in cases where there is nothing to do. -+ -+lede-commit: afc1675833a7bf5df094f59f7250369520646d04 -+Signed-off-by: Felix Fietkau -+--- -+ Makefile | 2 -- -+ scripts/Makefile.build | 2 +- -+ 2 files changed, 1 insertion(+), 3 deletions(-) -+ -+--- a/Makefile -++++ b/Makefile -+@@ -1260,7 +1260,6 @@ endif -+ -+ PHONY += modules -+ modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin -+- $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order -+ @$(kecho) ' Building modules, stage 2.'; -+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost -+ -+@@ -1289,7 +1288,6 @@ _modinst_: -+ rm -f $(MODLIB)/build ; \ -+ ln -s $(CURDIR) $(MODLIB)/build ; \ -+ fi -+- @cp -f $(objtree)/modules.order $(MODLIB)/ -+ @cp -f $(objtree)/modules.builtin $(MODLIB)/ -+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst -+ -+--- a/scripts/Makefile.build -++++ b/scripts/Makefile.build -+@@ -94,7 +94,7 @@ modorder-target := $(obj)/modules.order -+ # We keep a list of all modules in $(MODVERDIR) -+ -+ __build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \ -+- $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \ -++ $(if $(KBUILD_MODULES),$(obj-m)) \ -+ $(subdir-ym) $(always) -+ @: -+ -diff --git a/target/linux/generic/hack-4.14/210-darwin_scripts_include.patch b/target/linux/generic/hack-4.14/210-darwin_scripts_include.patch -new file mode 100644 -index 0000000000..95c7ea4232 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/210-darwin_scripts_include.patch -@@ -0,0 +1,3065 @@ -+From db7c30dcd9a0391bf13b62c9f91e144d762ef43a Mon Sep 17 00:00:00 2001 -+From: Florian Fainelli -+Date: Fri, 7 Jul 2017 17:00:49 +0200 -+Subject: Add an OSX specific patch to make the kernel be compiled -+ -+lede-commit: 3fc2a24f0422b2f55f9ed43f116db3111f700526 -+Signed-off-by: Florian Fainelli -+--- -+ scripts/kconfig/Makefile | 3 + -+ scripts/mod/elf.h | 3007 ++++++++++++++++++++++++++++++++++++++++++++ -+ scripts/mod/mk_elfconfig.c | 4 + -+ scripts/mod/modpost.h | 4 + -+ 4 files changed, 3018 insertions(+) -+ create mode 100644 scripts/mod/elf.h -+ -+--- a/scripts/kconfig/Makefile -++++ b/scripts/kconfig/Makefile -+@@ -164,6 +164,9 @@ check-lxdialog := $(srctree)/$(src)/lxd -+ # we really need to do so. (Do not call gcc as part of make mrproper) -+ HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \ -+ -DLOCALE -++ifeq ($(shell uname -s),Darwin) -++HOST_LOADLIBES += -lncurses -++endif -+ -+ # =========================================================================== -+ # Shared Makefile for the various kconfig executables: -+--- /dev/null -++++ b/scripts/mod/elf.h -+@@ -0,0 +1,3007 @@ -++/* This file defines standard ELF types, structures, and macros. -++ Copyright (C) 1995-2012 Free Software Foundation, Inc. -++ This file is part of the GNU C Library. -++ -++ The GNU C Library is free software; you can redistribute it and/or -++ modify it under the terms of the GNU Lesser General Public -++ License as published by the Free Software Foundation; either -++ version 2.1 of the License, or (at your option) any later version. -++ -++ The GNU C Library 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 -++ Lesser General Public License for more details. -++ -++ You should have received a copy of the GNU Lesser General Public -++ License along with the GNU C Library; if not, see -++ . */ -++ -++#ifndef _ELF_H -++#define _ELF_H 1 -++ -++/* Standard ELF types. */ -++ -++#include -++ -++/* Type for a 16-bit quantity. */ -++typedef uint16_t Elf32_Half; -++typedef uint16_t Elf64_Half; -++ -++/* Types for signed and unsigned 32-bit quantities. */ -++typedef uint32_t Elf32_Word; -++typedef int32_t Elf32_Sword; -++typedef uint32_t Elf64_Word; -++typedef int32_t Elf64_Sword; -++ -++/* Types for signed and unsigned 64-bit quantities. */ -++typedef uint64_t Elf32_Xword; -++typedef int64_t Elf32_Sxword; -++typedef uint64_t Elf64_Xword; -++typedef int64_t Elf64_Sxword; -++ -++/* Type of addresses. */ -++typedef uint32_t Elf32_Addr; -++typedef uint64_t Elf64_Addr; -++ -++/* Type of file offsets. */ -++typedef uint32_t Elf32_Off; -++typedef uint64_t Elf64_Off; -++ -++/* Type for section indices, which are 16-bit quantities. */ -++typedef uint16_t Elf32_Section; -++typedef uint16_t Elf64_Section; -++ -++/* Type for version symbol information. */ -++typedef Elf32_Half Elf32_Versym; -++typedef Elf64_Half Elf64_Versym; -++ -++ -++/* The ELF file header. This appears at the start of every ELF file. */ -++ -++#define EI_NIDENT (16) -++ -++typedef struct -++{ -++ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ -++ Elf32_Half e_type; /* Object file type */ -++ Elf32_Half e_machine; /* Architecture */ -++ Elf32_Word e_version; /* Object file version */ -++ Elf32_Addr e_entry; /* Entry point virtual address */ -++ Elf32_Off e_phoff; /* Program header table file offset */ -++ Elf32_Off e_shoff; /* Section header table file offset */ -++ Elf32_Word e_flags; /* Processor-specific flags */ -++ Elf32_Half e_ehsize; /* ELF header size in bytes */ -++ Elf32_Half e_phentsize; /* Program header table entry size */ -++ Elf32_Half e_phnum; /* Program header table entry count */ -++ Elf32_Half e_shentsize; /* Section header table entry size */ -++ Elf32_Half e_shnum; /* Section header table entry count */ -++ Elf32_Half e_shstrndx; /* Section header string table index */ -++} Elf32_Ehdr; -++ -++typedef struct -++{ -++ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ -++ Elf64_Half e_type; /* Object file type */ -++ Elf64_Half e_machine; /* Architecture */ -++ Elf64_Word e_version; /* Object file version */ -++ Elf64_Addr e_entry; /* Entry point virtual address */ -++ Elf64_Off e_phoff; /* Program header table file offset */ -++ Elf64_Off e_shoff; /* Section header table file offset */ -++ Elf64_Word e_flags; /* Processor-specific flags */ -++ Elf64_Half e_ehsize; /* ELF header size in bytes */ -++ Elf64_Half e_phentsize; /* Program header table entry size */ -++ Elf64_Half e_phnum; /* Program header table entry count */ -++ Elf64_Half e_shentsize; /* Section header table entry size */ -++ Elf64_Half e_shnum; /* Section header table entry count */ -++ Elf64_Half e_shstrndx; /* Section header string table index */ -++} Elf64_Ehdr; -++ -++/* Fields in the e_ident array. The EI_* macros are indices into the -++ array. The macros under each EI_* macro are the values the byte -++ may have. */ -++ -++#define EI_MAG0 0 /* File identification byte 0 index */ -++#define ELFMAG0 0x7f /* Magic number byte 0 */ -++ -++#define EI_MAG1 1 /* File identification byte 1 index */ -++#define ELFMAG1 'E' /* Magic number byte 1 */ -++ -++#define EI_MAG2 2 /* File identification byte 2 index */ -++#define ELFMAG2 'L' /* Magic number byte 2 */ -++ -++#define EI_MAG3 3 /* File identification byte 3 index */ -++#define ELFMAG3 'F' /* Magic number byte 3 */ -++ -++/* Conglomeration of the identification bytes, for easy testing as a word. */ -++#define ELFMAG "\177ELF" -++#define SELFMAG 4 -++ -++#define EI_CLASS 4 /* File class byte index */ -++#define ELFCLASSNONE 0 /* Invalid class */ -++#define ELFCLASS32 1 /* 32-bit objects */ -++#define ELFCLASS64 2 /* 64-bit objects */ -++#define ELFCLASSNUM 3 -++ -++#define EI_DATA 5 /* Data encoding byte index */ -++#define ELFDATANONE 0 /* Invalid data encoding */ -++#define ELFDATA2LSB 1 /* 2's complement, little endian */ -++#define ELFDATA2MSB 2 /* 2's complement, big endian */ -++#define ELFDATANUM 3 -++ -++#define EI_VERSION 6 /* File version byte index */ -++ /* Value must be EV_CURRENT */ -++ -++#define EI_OSABI 7 /* OS ABI identification */ -++#define ELFOSABI_NONE 0 /* UNIX System V ABI */ -++#define ELFOSABI_SYSV 0 /* Alias. */ -++#define ELFOSABI_HPUX 1 /* HP-UX */ -++#define ELFOSABI_NETBSD 2 /* NetBSD. */ -++#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */ -++#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */ -++#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ -++#define ELFOSABI_AIX 7 /* IBM AIX. */ -++#define ELFOSABI_IRIX 8 /* SGI Irix. */ -++#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ -++#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ -++#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ -++#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ -++#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ -++#define ELFOSABI_ARM 97 /* ARM */ -++#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ -++ -++#define EI_ABIVERSION 8 /* ABI version */ -++ -++#define EI_PAD 9 /* Byte index of padding bytes */ -++ -++/* Legal values for e_type (object file type). */ -++ -++#define ET_NONE 0 /* No file type */ -++#define ET_REL 1 /* Relocatable file */ -++#define ET_EXEC 2 /* Executable file */ -++#define ET_DYN 3 /* Shared object file */ -++#define ET_CORE 4 /* Core file */ -++#define ET_NUM 5 /* Number of defined types */ -++#define ET_LOOS 0xfe00 /* OS-specific range start */ -++#define ET_HIOS 0xfeff /* OS-specific range end */ -++#define ET_LOPROC 0xff00 /* Processor-specific range start */ -++#define ET_HIPROC 0xffff /* Processor-specific range end */ -++ -++/* Legal values for e_machine (architecture). */ -++ -++#define EM_NONE 0 /* No machine */ -++#define EM_M32 1 /* AT&T WE 32100 */ -++#define EM_SPARC 2 /* SUN SPARC */ -++#define EM_386 3 /* Intel 80386 */ -++#define EM_68K 4 /* Motorola m68k family */ -++#define EM_88K 5 /* Motorola m88k family */ -++#define EM_860 7 /* Intel 80860 */ -++#define EM_MIPS 8 /* MIPS R3000 big-endian */ -++#define EM_S370 9 /* IBM System/370 */ -++#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ -++ -++#define EM_PARISC 15 /* HPPA */ -++#define EM_VPP500 17 /* Fujitsu VPP500 */ -++#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ -++#define EM_960 19 /* Intel 80960 */ -++#define EM_PPC 20 /* PowerPC */ -++#define EM_PPC64 21 /* PowerPC 64-bit */ -++#define EM_S390 22 /* IBM S390 */ -++ -++#define EM_V800 36 /* NEC V800 series */ -++#define EM_FR20 37 /* Fujitsu FR20 */ -++#define EM_RH32 38 /* TRW RH-32 */ -++#define EM_RCE 39 /* Motorola RCE */ -++#define EM_ARM 40 /* ARM */ -++#define EM_FAKE_ALPHA 41 /* Digital Alpha */ -++#define EM_SH 42 /* Hitachi SH */ -++#define EM_SPARCV9 43 /* SPARC v9 64-bit */ -++#define EM_TRICORE 44 /* Siemens Tricore */ -++#define EM_ARC 45 /* Argonaut RISC Core */ -++#define EM_H8_300 46 /* Hitachi H8/300 */ -++#define EM_H8_300H 47 /* Hitachi H8/300H */ -++#define EM_H8S 48 /* Hitachi H8S */ -++#define EM_H8_500 49 /* Hitachi H8/500 */ -++#define EM_IA_64 50 /* Intel Merced */ -++#define EM_MIPS_X 51 /* Stanford MIPS-X */ -++#define EM_COLDFIRE 52 /* Motorola Coldfire */ -++#define EM_68HC12 53 /* Motorola M68HC12 */ -++#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ -++#define EM_PCP 55 /* Siemens PCP */ -++#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ -++#define EM_NDR1 57 /* Denso NDR1 microprocessor */ -++#define EM_STARCORE 58 /* Motorola Start*Core processor */ -++#define EM_ME16 59 /* Toyota ME16 processor */ -++#define EM_ST100 60 /* STMicroelectronic ST100 processor */ -++#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ -++#define EM_X86_64 62 /* AMD x86-64 architecture */ -++#define EM_PDSP 63 /* Sony DSP Processor */ -++ -++#define EM_FX66 66 /* Siemens FX66 microcontroller */ -++#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ -++#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ -++#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ -++#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ -++#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ -++#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ -++#define EM_SVX 73 /* Silicon Graphics SVx */ -++#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ -++#define EM_VAX 75 /* Digital VAX */ -++#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ -++#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ -++#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ -++#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ -++#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ -++#define EM_HUANY 81 /* Harvard University machine-independent object files */ -++#define EM_PRISM 82 /* SiTera Prism */ -++#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ -++#define EM_FR30 84 /* Fujitsu FR30 */ -++#define EM_D10V 85 /* Mitsubishi D10V */ -++#define EM_D30V 86 /* Mitsubishi D30V */ -++#define EM_V850 87 /* NEC v850 */ -++#define EM_M32R 88 /* Mitsubishi M32R */ -++#define EM_MN10300 89 /* Matsushita MN10300 */ -++#define EM_MN10200 90 /* Matsushita MN10200 */ -++#define EM_PJ 91 /* picoJava */ -++#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ -++#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ -++#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ -++#define EM_TILEPRO 188 /* Tilera TILEPro */ -++#define EM_TILEGX 191 /* Tilera TILE-Gx */ -++#define EM_NUM 192 -++ -++/* If it is necessary to assign new unofficial EM_* values, please -++ pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the -++ chances of collision with official or non-GNU unofficial values. */ -++ -++#define EM_ALPHA 0x9026 -++ -++/* Legal values for e_version (version). */ -++ -++#define EV_NONE 0 /* Invalid ELF version */ -++#define EV_CURRENT 1 /* Current version */ -++#define EV_NUM 2 -++ -++/* Section header. */ -++ -++typedef struct -++{ -++ Elf32_Word sh_name; /* Section name (string tbl index) */ -++ Elf32_Word sh_type; /* Section type */ -++ Elf32_Word sh_flags; /* Section flags */ -++ Elf32_Addr sh_addr; /* Section virtual addr at execution */ -++ Elf32_Off sh_offset; /* Section file offset */ -++ Elf32_Word sh_size; /* Section size in bytes */ -++ Elf32_Word sh_link; /* Link to another section */ -++ Elf32_Word sh_info; /* Additional section information */ -++ Elf32_Word sh_addralign; /* Section alignment */ -++ Elf32_Word sh_entsize; /* Entry size if section holds table */ -++} Elf32_Shdr; -++ -++typedef struct -++{ -++ Elf64_Word sh_name; /* Section name (string tbl index) */ -++ Elf64_Word sh_type; /* Section type */ -++ Elf64_Xword sh_flags; /* Section flags */ -++ Elf64_Addr sh_addr; /* Section virtual addr at execution */ -++ Elf64_Off sh_offset; /* Section file offset */ -++ Elf64_Xword sh_size; /* Section size in bytes */ -++ Elf64_Word sh_link; /* Link to another section */ -++ Elf64_Word sh_info; /* Additional section information */ -++ Elf64_Xword sh_addralign; /* Section alignment */ -++ Elf64_Xword sh_entsize; /* Entry size if section holds table */ -++} Elf64_Shdr; -++ -++/* Special section indices. */ -++ -++#define SHN_UNDEF 0 /* Undefined section */ -++#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ -++#define SHN_LOPROC 0xff00 /* Start of processor-specific */ -++#define SHN_BEFORE 0xff00 /* Order section before all others -++ (Solaris). */ -++#define SHN_AFTER 0xff01 /* Order section after all others -++ (Solaris). */ -++#define SHN_HIPROC 0xff1f /* End of processor-specific */ -++#define SHN_LOOS 0xff20 /* Start of OS-specific */ -++#define SHN_HIOS 0xff3f /* End of OS-specific */ -++#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ -++#define SHN_COMMON 0xfff2 /* Associated symbol is common */ -++#define SHN_XINDEX 0xffff /* Index is in extra table. */ -++#define SHN_HIRESERVE 0xffff /* End of reserved indices */ -++ -++/* Legal values for sh_type (section type). */ -++ -++#define SHT_NULL 0 /* Section header table entry unused */ -++#define SHT_PROGBITS 1 /* Program data */ -++#define SHT_SYMTAB 2 /* Symbol table */ -++#define SHT_STRTAB 3 /* String table */ -++#define SHT_RELA 4 /* Relocation entries with addends */ -++#define SHT_HASH 5 /* Symbol hash table */ -++#define SHT_DYNAMIC 6 /* Dynamic linking information */ -++#define SHT_NOTE 7 /* Notes */ -++#define SHT_NOBITS 8 /* Program space with no data (bss) */ -++#define SHT_REL 9 /* Relocation entries, no addends */ -++#define SHT_SHLIB 10 /* Reserved */ -++#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ -++#define SHT_INIT_ARRAY 14 /* Array of constructors */ -++#define SHT_FINI_ARRAY 15 /* Array of destructors */ -++#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ -++#define SHT_GROUP 17 /* Section group */ -++#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ -++#define SHT_NUM 19 /* Number of defined types. */ -++#define SHT_LOOS 0x60000000 /* Start OS-specific. */ -++#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ -++#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ -++#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ -++#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ -++#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ -++#define SHT_SUNW_move 0x6ffffffa -++#define SHT_SUNW_COMDAT 0x6ffffffb -++#define SHT_SUNW_syminfo 0x6ffffffc -++#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ -++#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ -++#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ -++#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ -++#define SHT_HIOS 0x6fffffff /* End OS-specific type */ -++#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ -++#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ -++#define SHT_LOUSER 0x80000000 /* Start of application-specific */ -++#define SHT_HIUSER 0x8fffffff /* End of application-specific */ -++ -++/* Legal values for sh_flags (section flags). */ -++ -++#define SHF_WRITE (1 << 0) /* Writable */ -++#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ -++#define SHF_EXECINSTR (1 << 2) /* Executable */ -++#define SHF_MERGE (1 << 4) /* Might be merged */ -++#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ -++#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ -++#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ -++#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling -++ required */ -++#define SHF_GROUP (1 << 9) /* Section is member of a group. */ -++#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ -++#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ -++#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ -++#define SHF_ORDERED (1 << 30) /* Special ordering requirement -++ (Solaris). */ -++#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless -++ referenced or allocated (Solaris).*/ -++ -++/* Section group handling. */ -++#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ -++ -++/* Symbol table entry. */ -++ -++typedef struct -++{ -++ Elf32_Word st_name; /* Symbol name (string tbl index) */ -++ Elf32_Addr st_value; /* Symbol value */ -++ Elf32_Word st_size; /* Symbol size */ -++ unsigned char st_info; /* Symbol type and binding */ -++ unsigned char st_other; /* Symbol visibility */ -++ Elf32_Section st_shndx; /* Section index */ -++} Elf32_Sym; -++ -++typedef struct -++{ -++ Elf64_Word st_name; /* Symbol name (string tbl index) */ -++ unsigned char st_info; /* Symbol type and binding */ -++ unsigned char st_other; /* Symbol visibility */ -++ Elf64_Section st_shndx; /* Section index */ -++ Elf64_Addr st_value; /* Symbol value */ -++ Elf64_Xword st_size; /* Symbol size */ -++} Elf64_Sym; -++ -++/* The syminfo section if available contains additional information about -++ every dynamic symbol. */ -++ -++typedef struct -++{ -++ Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ -++ Elf32_Half si_flags; /* Per symbol flags */ -++} Elf32_Syminfo; -++ -++typedef struct -++{ -++ Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ -++ Elf64_Half si_flags; /* Per symbol flags */ -++} Elf64_Syminfo; -++ -++/* Possible values for si_boundto. */ -++#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ -++#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ -++#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ -++ -++/* Possible bitmasks for si_flags. */ -++#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ -++#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ -++#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ -++#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy -++ loaded */ -++/* Syminfo version values. */ -++#define SYMINFO_NONE 0 -++#define SYMINFO_CURRENT 1 -++#define SYMINFO_NUM 2 -++ -++ -++/* How to extract and insert information held in the st_info field. */ -++ -++#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) -++#define ELF32_ST_TYPE(val) ((val) & 0xf) -++#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) -++ -++/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ -++#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) -++#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) -++#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) -++ -++/* Legal values for ST_BIND subfield of st_info (symbol binding). */ -++ -++#define STB_LOCAL 0 /* Local symbol */ -++#define STB_GLOBAL 1 /* Global symbol */ -++#define STB_WEAK 2 /* Weak symbol */ -++#define STB_NUM 3 /* Number of defined types. */ -++#define STB_LOOS 10 /* Start of OS-specific */ -++#define STB_GNU_UNIQUE 10 /* Unique symbol. */ -++#define STB_HIOS 12 /* End of OS-specific */ -++#define STB_LOPROC 13 /* Start of processor-specific */ -++#define STB_HIPROC 15 /* End of processor-specific */ -++ -++/* Legal values for ST_TYPE subfield of st_info (symbol type). */ -++ -++#define STT_NOTYPE 0 /* Symbol type is unspecified */ -++#define STT_OBJECT 1 /* Symbol is a data object */ -++#define STT_FUNC 2 /* Symbol is a code object */ -++#define STT_SECTION 3 /* Symbol associated with a section */ -++#define STT_FILE 4 /* Symbol's name is file name */ -++#define STT_COMMON 5 /* Symbol is a common data object */ -++#define STT_TLS 6 /* Symbol is thread-local data object*/ -++#define STT_NUM 7 /* Number of defined types. */ -++#define STT_LOOS 10 /* Start of OS-specific */ -++#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */ -++#define STT_HIOS 12 /* End of OS-specific */ -++#define STT_LOPROC 13 /* Start of processor-specific */ -++#define STT_HIPROC 15 /* End of processor-specific */ -++ -++ -++/* Symbol table indices are found in the hash buckets and chain table -++ of a symbol hash table section. This special index value indicates -++ the end of a chain, meaning no further symbols are found in that bucket. */ -++ -++#define STN_UNDEF 0 /* End of a chain. */ -++ -++ -++/* How to extract and insert information held in the st_other field. */ -++ -++#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) -++ -++/* For ELF64 the definitions are the same. */ -++#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) -++ -++/* Symbol visibility specification encoded in the st_other field. */ -++#define STV_DEFAULT 0 /* Default symbol visibility rules */ -++#define STV_INTERNAL 1 /* Processor specific hidden class */ -++#define STV_HIDDEN 2 /* Sym unavailable in other modules */ -++#define STV_PROTECTED 3 /* Not preemptible, not exported */ -++ -++ -++/* Relocation table entry without addend (in section of type SHT_REL). */ -++ -++typedef struct -++{ -++ Elf32_Addr r_offset; /* Address */ -++ Elf32_Word r_info; /* Relocation type and symbol index */ -++} Elf32_Rel; -++ -++/* I have seen two different definitions of the Elf64_Rel and -++ Elf64_Rela structures, so we'll leave them out until Novell (or -++ whoever) gets their act together. */ -++/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ -++ -++typedef struct -++{ -++ Elf64_Addr r_offset; /* Address */ -++ Elf64_Xword r_info; /* Relocation type and symbol index */ -++} Elf64_Rel; -++ -++/* Relocation table entry with addend (in section of type SHT_RELA). */ -++ -++typedef struct -++{ -++ Elf32_Addr r_offset; /* Address */ -++ Elf32_Word r_info; /* Relocation type and symbol index */ -++ Elf32_Sword r_addend; /* Addend */ -++} Elf32_Rela; -++ -++typedef struct -++{ -++ Elf64_Addr r_offset; /* Address */ -++ Elf64_Xword r_info; /* Relocation type and symbol index */ -++ Elf64_Sxword r_addend; /* Addend */ -++} Elf64_Rela; -++ -++/* How to extract and insert information held in the r_info field. */ -++ -++#define ELF32_R_SYM(val) ((val) >> 8) -++#define ELF32_R_TYPE(val) ((val) & 0xff) -++#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) -++ -++#define ELF64_R_SYM(i) ((i) >> 32) -++#define ELF64_R_TYPE(i) ((i) & 0xffffffff) -++#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) -++ -++/* Program segment header. */ -++ -++typedef struct -++{ -++ Elf32_Word p_type; /* Segment type */ -++ Elf32_Off p_offset; /* Segment file offset */ -++ Elf32_Addr p_vaddr; /* Segment virtual address */ -++ Elf32_Addr p_paddr; /* Segment physical address */ -++ Elf32_Word p_filesz; /* Segment size in file */ -++ Elf32_Word p_memsz; /* Segment size in memory */ -++ Elf32_Word p_flags; /* Segment flags */ -++ Elf32_Word p_align; /* Segment alignment */ -++} Elf32_Phdr; -++ -++typedef struct -++{ -++ Elf64_Word p_type; /* Segment type */ -++ Elf64_Word p_flags; /* Segment flags */ -++ Elf64_Off p_offset; /* Segment file offset */ -++ Elf64_Addr p_vaddr; /* Segment virtual address */ -++ Elf64_Addr p_paddr; /* Segment physical address */ -++ Elf64_Xword p_filesz; /* Segment size in file */ -++ Elf64_Xword p_memsz; /* Segment size in memory */ -++ Elf64_Xword p_align; /* Segment alignment */ -++} Elf64_Phdr; -++ -++/* Special value for e_phnum. This indicates that the real number of -++ program headers is too large to fit into e_phnum. Instead the real -++ value is in the field sh_info of section 0. */ -++ -++#define PN_XNUM 0xffff -++ -++/* Legal values for p_type (segment type). */ -++ -++#define PT_NULL 0 /* Program header table entry unused */ -++#define PT_LOAD 1 /* Loadable program segment */ -++#define PT_DYNAMIC 2 /* Dynamic linking information */ -++#define PT_INTERP 3 /* Program interpreter */ -++#define PT_NOTE 4 /* Auxiliary information */ -++#define PT_SHLIB 5 /* Reserved */ -++#define PT_PHDR 6 /* Entry for header table itself */ -++#define PT_TLS 7 /* Thread-local storage segment */ -++#define PT_NUM 8 /* Number of defined types */ -++#define PT_LOOS 0x60000000 /* Start of OS-specific */ -++#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ -++#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ -++#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ -++#define PT_LOSUNW 0x6ffffffa -++#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ -++#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ -++#define PT_HISUNW 0x6fffffff -++#define PT_HIOS 0x6fffffff /* End of OS-specific */ -++#define PT_LOPROC 0x70000000 /* Start of processor-specific */ -++#define PT_HIPROC 0x7fffffff /* End of processor-specific */ -++ -++/* Legal values for p_flags (segment flags). */ -++ -++#define PF_X (1 << 0) /* Segment is executable */ -++#define PF_W (1 << 1) /* Segment is writable */ -++#define PF_R (1 << 2) /* Segment is readable */ -++#define PF_MASKOS 0x0ff00000 /* OS-specific */ -++#define PF_MASKPROC 0xf0000000 /* Processor-specific */ -++ -++/* Legal values for note segment descriptor types for core files. */ -++ -++#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ -++#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ -++#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ -++#define NT_PRXREG 4 /* Contains copy of prxregset struct */ -++#define NT_TASKSTRUCT 4 /* Contains copy of task structure */ -++#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ -++#define NT_AUXV 6 /* Contains copy of auxv array */ -++#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ -++#define NT_ASRS 8 /* Contains copy of asrset struct */ -++#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ -++#define NT_PSINFO 13 /* Contains copy of psinfo struct */ -++#define NT_PRCRED 14 /* Contains copy of prcred struct */ -++#define NT_UTSNAME 15 /* Contains copy of utsname struct */ -++#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ -++#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ -++#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */ -++#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */ -++#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ -++#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ -++#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ -++#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ -++#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ -++#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ -++ -++/* Legal values for the note segment descriptor types for object files. */ -++ -++#define NT_VERSION 1 /* Contains a version string. */ -++ -++ -++/* Dynamic section entry. */ -++ -++typedef struct -++{ -++ Elf32_Sword d_tag; /* Dynamic entry type */ -++ union -++ { -++ Elf32_Word d_val; /* Integer value */ -++ Elf32_Addr d_ptr; /* Address value */ -++ } d_un; -++} Elf32_Dyn; -++ -++typedef struct -++{ -++ Elf64_Sxword d_tag; /* Dynamic entry type */ -++ union -++ { -++ Elf64_Xword d_val; /* Integer value */ -++ Elf64_Addr d_ptr; /* Address value */ -++ } d_un; -++} Elf64_Dyn; -++ -++/* Legal values for d_tag (dynamic entry type). */ -++ -++#define DT_NULL 0 /* Marks end of dynamic section */ -++#define DT_NEEDED 1 /* Name of needed library */ -++#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ -++#define DT_PLTGOT 3 /* Processor defined value */ -++#define DT_HASH 4 /* Address of symbol hash table */ -++#define DT_STRTAB 5 /* Address of string table */ -++#define DT_SYMTAB 6 /* Address of symbol table */ -++#define DT_RELA 7 /* Address of Rela relocs */ -++#define DT_RELASZ 8 /* Total size of Rela relocs */ -++#define DT_RELAENT 9 /* Size of one Rela reloc */ -++#define DT_STRSZ 10 /* Size of string table */ -++#define DT_SYMENT 11 /* Size of one symbol table entry */ -++#define DT_INIT 12 /* Address of init function */ -++#define DT_FINI 13 /* Address of termination function */ -++#define DT_SONAME 14 /* Name of shared object */ -++#define DT_RPATH 15 /* Library search path (deprecated) */ -++#define DT_SYMBOLIC 16 /* Start symbol search here */ -++#define DT_REL 17 /* Address of Rel relocs */ -++#define DT_RELSZ 18 /* Total size of Rel relocs */ -++#define DT_RELENT 19 /* Size of one Rel reloc */ -++#define DT_PLTREL 20 /* Type of reloc in PLT */ -++#define DT_DEBUG 21 /* For debugging; unspecified */ -++#define DT_TEXTREL 22 /* Reloc might modify .text */ -++#define DT_JMPREL 23 /* Address of PLT relocs */ -++#define DT_BIND_NOW 24 /* Process relocations of object */ -++#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ -++#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ -++#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ -++#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ -++#define DT_RUNPATH 29 /* Library search path */ -++#define DT_FLAGS 30 /* Flags for the object being loaded */ -++#define DT_ENCODING 32 /* Start of encoded range */ -++#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ -++#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ -++#define DT_NUM 34 /* Number used */ -++#define DT_LOOS 0x6000000d /* Start of OS-specific */ -++#define DT_HIOS 0x6ffff000 /* End of OS-specific */ -++#define DT_LOPROC 0x70000000 /* Start of processor-specific */ -++#define DT_HIPROC 0x7fffffff /* End of processor-specific */ -++#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ -++ -++/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the -++ Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's -++ approach. */ -++#define DT_VALRNGLO 0x6ffffd00 -++#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ -++#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ -++#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ -++#define DT_CHECKSUM 0x6ffffdf8 -++#define DT_PLTPADSZ 0x6ffffdf9 -++#define DT_MOVEENT 0x6ffffdfa -++#define DT_MOVESZ 0x6ffffdfb -++#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ -++#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting -++ the following DT_* entry. */ -++#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ -++#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ -++#define DT_VALRNGHI 0x6ffffdff -++#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ -++#define DT_VALNUM 12 -++ -++/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the -++ Dyn.d_un.d_ptr field of the Elf*_Dyn structure. -++ -++ If any adjustment is made to the ELF object after it has been -++ built these entries will need to be adjusted. */ -++#define DT_ADDRRNGLO 0x6ffffe00 -++#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */ -++#define DT_TLSDESC_PLT 0x6ffffef6 -++#define DT_TLSDESC_GOT 0x6ffffef7 -++#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ -++#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ -++#define DT_CONFIG 0x6ffffefa /* Configuration information. */ -++#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ -++#define DT_AUDIT 0x6ffffefc /* Object auditing. */ -++#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ -++#define DT_MOVETAB 0x6ffffefe /* Move table. */ -++#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ -++#define DT_ADDRRNGHI 0x6ffffeff -++#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ -++#define DT_ADDRNUM 11 -++ -++/* The versioning entry types. The next are defined as part of the -++ GNU extension. */ -++#define DT_VERSYM 0x6ffffff0 -++ -++#define DT_RELACOUNT 0x6ffffff9 -++#define DT_RELCOUNT 0x6ffffffa -++ -++/* These were chosen by Sun. */ -++#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ -++#define DT_VERDEF 0x6ffffffc /* Address of version definition -++ table */ -++#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ -++#define DT_VERNEED 0x6ffffffe /* Address of table with needed -++ versions */ -++#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ -++#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ -++#define DT_VERSIONTAGNUM 16 -++ -++/* Sun added these machine-independent extensions in the "processor-specific" -++ range. Be compatible. */ -++#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ -++#define DT_FILTER 0x7fffffff /* Shared object to get values from */ -++#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) -++#define DT_EXTRANUM 3 -++ -++/* Values of `d_un.d_val' in the DT_FLAGS entry. */ -++#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */ -++#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */ -++#define DF_TEXTREL 0x00000004 /* Object contains text relocations */ -++#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ -++#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ -++ -++/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 -++ entry in the dynamic section. */ -++#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ -++#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ -++#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ -++#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ -++#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ -++#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ -++#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ -++#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */ -++#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */ -++#define DF_1_TRANS 0x00000200 -++#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */ -++#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */ -++#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */ -++#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/ -++#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */ -++#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */ -++#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ -++ -++/* Flags for the feature selection in DT_FEATURE_1. */ -++#define DTF_1_PARINIT 0x00000001 -++#define DTF_1_CONFEXP 0x00000002 -++ -++/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */ -++#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */ -++#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not -++ generally available. */ -++ -++/* Version definition sections. */ -++ -++typedef struct -++{ -++ Elf32_Half vd_version; /* Version revision */ -++ Elf32_Half vd_flags; /* Version information */ -++ Elf32_Half vd_ndx; /* Version Index */ -++ Elf32_Half vd_cnt; /* Number of associated aux entries */ -++ Elf32_Word vd_hash; /* Version name hash value */ -++ Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ -++ Elf32_Word vd_next; /* Offset in bytes to next verdef -++ entry */ -++} Elf32_Verdef; -++ -++typedef struct -++{ -++ Elf64_Half vd_version; /* Version revision */ -++ Elf64_Half vd_flags; /* Version information */ -++ Elf64_Half vd_ndx; /* Version Index */ -++ Elf64_Half vd_cnt; /* Number of associated aux entries */ -++ Elf64_Word vd_hash; /* Version name hash value */ -++ Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ -++ Elf64_Word vd_next; /* Offset in bytes to next verdef -++ entry */ -++} Elf64_Verdef; -++ -++ -++/* Legal values for vd_version (version revision). */ -++#define VER_DEF_NONE 0 /* No version */ -++#define VER_DEF_CURRENT 1 /* Current version */ -++#define VER_DEF_NUM 2 /* Given version number */ -++ -++/* Legal values for vd_flags (version information flags). */ -++#define VER_FLG_BASE 0x1 /* Version definition of file itself */ -++#define VER_FLG_WEAK 0x2 /* Weak version identifier */ -++ -++/* Versym symbol index values. */ -++#define VER_NDX_LOCAL 0 /* Symbol is local. */ -++#define VER_NDX_GLOBAL 1 /* Symbol is global. */ -++#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ -++#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ -++ -++/* Auxialiary version information. */ -++ -++typedef struct -++{ -++ Elf32_Word vda_name; /* Version or dependency names */ -++ Elf32_Word vda_next; /* Offset in bytes to next verdaux -++ entry */ -++} Elf32_Verdaux; -++ -++typedef struct -++{ -++ Elf64_Word vda_name; /* Version or dependency names */ -++ Elf64_Word vda_next; /* Offset in bytes to next verdaux -++ entry */ -++} Elf64_Verdaux; -++ -++ -++/* Version dependency section. */ -++ -++typedef struct -++{ -++ Elf32_Half vn_version; /* Version of structure */ -++ Elf32_Half vn_cnt; /* Number of associated aux entries */ -++ Elf32_Word vn_file; /* Offset of filename for this -++ dependency */ -++ Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ -++ Elf32_Word vn_next; /* Offset in bytes to next verneed -++ entry */ -++} Elf32_Verneed; -++ -++typedef struct -++{ -++ Elf64_Half vn_version; /* Version of structure */ -++ Elf64_Half vn_cnt; /* Number of associated aux entries */ -++ Elf64_Word vn_file; /* Offset of filename for this -++ dependency */ -++ Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ -++ Elf64_Word vn_next; /* Offset in bytes to next verneed -++ entry */ -++} Elf64_Verneed; -++ -++ -++/* Legal values for vn_version (version revision). */ -++#define VER_NEED_NONE 0 /* No version */ -++#define VER_NEED_CURRENT 1 /* Current version */ -++#define VER_NEED_NUM 2 /* Given version number */ -++ -++/* Auxiliary needed version information. */ -++ -++typedef struct -++{ -++ Elf32_Word vna_hash; /* Hash value of dependency name */ -++ Elf32_Half vna_flags; /* Dependency specific information */ -++ Elf32_Half vna_other; /* Unused */ -++ Elf32_Word vna_name; /* Dependency name string offset */ -++ Elf32_Word vna_next; /* Offset in bytes to next vernaux -++ entry */ -++} Elf32_Vernaux; -++ -++typedef struct -++{ -++ Elf64_Word vna_hash; /* Hash value of dependency name */ -++ Elf64_Half vna_flags; /* Dependency specific information */ -++ Elf64_Half vna_other; /* Unused */ -++ Elf64_Word vna_name; /* Dependency name string offset */ -++ Elf64_Word vna_next; /* Offset in bytes to next vernaux -++ entry */ -++} Elf64_Vernaux; -++ -++ -++/* Legal values for vna_flags. */ -++#define VER_FLG_WEAK 0x2 /* Weak version identifier */ -++ -++ -++/* Auxiliary vector. */ -++ -++/* This vector is normally only used by the program interpreter. The -++ usual definition in an ABI supplement uses the name auxv_t. The -++ vector is not usually defined in a standard file, but it -++ can't hurt. We rename it to avoid conflicts. The sizes of these -++ types are an arrangement between the exec server and the program -++ interpreter, so we don't fully specify them here. */ -++ -++typedef struct -++{ -++ uint32_t a_type; /* Entry type */ -++ union -++ { -++ uint32_t a_val; /* Integer value */ -++ /* We use to have pointer elements added here. We cannot do that, -++ though, since it does not work when using 32-bit definitions -++ on 64-bit platforms and vice versa. */ -++ } a_un; -++} Elf32_auxv_t; -++ -++typedef struct -++{ -++ uint64_t a_type; /* Entry type */ -++ union -++ { -++ uint64_t a_val; /* Integer value */ -++ /* We use to have pointer elements added here. We cannot do that, -++ though, since it does not work when using 32-bit definitions -++ on 64-bit platforms and vice versa. */ -++ } a_un; -++} Elf64_auxv_t; -++ -++/* Legal values for a_type (entry type). */ -++ -++#define AT_NULL 0 /* End of vector */ -++#define AT_IGNORE 1 /* Entry should be ignored */ -++#define AT_EXECFD 2 /* File descriptor of program */ -++#define AT_PHDR 3 /* Program headers for program */ -++#define AT_PHENT 4 /* Size of program header entry */ -++#define AT_PHNUM 5 /* Number of program headers */ -++#define AT_PAGESZ 6 /* System page size */ -++#define AT_BASE 7 /* Base address of interpreter */ -++#define AT_FLAGS 8 /* Flags */ -++#define AT_ENTRY 9 /* Entry point of program */ -++#define AT_NOTELF 10 /* Program is not ELF */ -++#define AT_UID 11 /* Real uid */ -++#define AT_EUID 12 /* Effective uid */ -++#define AT_GID 13 /* Real gid */ -++#define AT_EGID 14 /* Effective gid */ -++#define AT_CLKTCK 17 /* Frequency of times() */ -++ -++/* Some more special a_type values describing the hardware. */ -++#define AT_PLATFORM 15 /* String identifying platform. */ -++#define AT_HWCAP 16 /* Machine dependent hints about -++ processor capabilities. */ -++ -++/* This entry gives some information about the FPU initialization -++ performed by the kernel. */ -++#define AT_FPUCW 18 /* Used FPU control word. */ -++ -++/* Cache block sizes. */ -++#define AT_DCACHEBSIZE 19 /* Data cache block size. */ -++#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */ -++#define AT_UCACHEBSIZE 21 /* Unified cache block size. */ -++ -++/* A special ignored value for PPC, used by the kernel to control the -++ interpretation of the AUXV. Must be > 16. */ -++#define AT_IGNOREPPC 22 /* Entry should be ignored. */ -++ -++#define AT_SECURE 23 /* Boolean, was exec setuid-like? */ -++ -++#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/ -++ -++#define AT_RANDOM 25 /* Address of 16 random bytes. */ -++ -++#define AT_EXECFN 31 /* Filename of executable. */ -++ -++/* Pointer to the global system page used for system calls and other -++ nice things. */ -++#define AT_SYSINFO 32 -++#define AT_SYSINFO_EHDR 33 -++ -++/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains -++ log2 of line size; mask those to get cache size. */ -++#define AT_L1I_CACHESHAPE 34 -++#define AT_L1D_CACHESHAPE 35 -++#define AT_L2_CACHESHAPE 36 -++#define AT_L3_CACHESHAPE 37 -++ -++/* Note section contents. Each entry in the note section begins with -++ a header of a fixed form. */ -++ -++typedef struct -++{ -++ Elf32_Word n_namesz; /* Length of the note's name. */ -++ Elf32_Word n_descsz; /* Length of the note's descriptor. */ -++ Elf32_Word n_type; /* Type of the note. */ -++} Elf32_Nhdr; -++ -++typedef struct -++{ -++ Elf64_Word n_namesz; /* Length of the note's name. */ -++ Elf64_Word n_descsz; /* Length of the note's descriptor. */ -++ Elf64_Word n_type; /* Type of the note. */ -++} Elf64_Nhdr; -++ -++/* Known names of notes. */ -++ -++/* Solaris entries in the note section have this name. */ -++#define ELF_NOTE_SOLARIS "SUNW Solaris" -++ -++/* Note entries for GNU systems have this name. */ -++#define ELF_NOTE_GNU "GNU" -++ -++ -++/* Defined types of notes for Solaris. */ -++ -++/* Value of descriptor (one word) is desired pagesize for the binary. */ -++#define ELF_NOTE_PAGESIZE_HINT 1 -++ -++ -++/* Defined note types for GNU systems. */ -++ -++/* ABI information. The descriptor consists of words: -++ word 0: OS descriptor -++ word 1: major version of the ABI -++ word 2: minor version of the ABI -++ word 3: subminor version of the ABI -++*/ -++#define NT_GNU_ABI_TAG 1 -++#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */ -++ -++/* Known OSes. These values can appear in word 0 of an -++ NT_GNU_ABI_TAG note section entry. */ -++#define ELF_NOTE_OS_LINUX 0 -++#define ELF_NOTE_OS_GNU 1 -++#define ELF_NOTE_OS_SOLARIS2 2 -++#define ELF_NOTE_OS_FREEBSD 3 -++ -++/* Synthetic hwcap information. The descriptor begins with two words: -++ word 0: number of entries -++ word 1: bitmask of enabled entries -++ Then follow variable-length entries, one byte followed by a -++ '\0'-terminated hwcap name string. The byte gives the bit -++ number to test if enabled, (1U << bit) & bitmask. */ -++#define NT_GNU_HWCAP 2 -++ -++/* Build ID bits as generated by ld --build-id. -++ The descriptor consists of any nonzero number of bytes. */ -++#define NT_GNU_BUILD_ID 3 -++ -++/* Version note generated by GNU gold containing a version string. */ -++#define NT_GNU_GOLD_VERSION 4 -++ -++ -++/* Move records. */ -++typedef struct -++{ -++ Elf32_Xword m_value; /* Symbol value. */ -++ Elf32_Word m_info; /* Size and index. */ -++ Elf32_Word m_poffset; /* Symbol offset. */ -++ Elf32_Half m_repeat; /* Repeat count. */ -++ Elf32_Half m_stride; /* Stride info. */ -++} Elf32_Move; -++ -++typedef struct -++{ -++ Elf64_Xword m_value; /* Symbol value. */ -++ Elf64_Xword m_info; /* Size and index. */ -++ Elf64_Xword m_poffset; /* Symbol offset. */ -++ Elf64_Half m_repeat; /* Repeat count. */ -++ Elf64_Half m_stride; /* Stride info. */ -++} Elf64_Move; -++ -++/* Macro to construct move records. */ -++#define ELF32_M_SYM(info) ((info) >> 8) -++#define ELF32_M_SIZE(info) ((unsigned char) (info)) -++#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) -++ -++#define ELF64_M_SYM(info) ELF32_M_SYM (info) -++#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) -++#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) -++ -++ -++/* Motorola 68k specific definitions. */ -++ -++/* Values for Elf32_Ehdr.e_flags. */ -++#define EF_CPU32 0x00810000 -++ -++/* m68k relocs. */ -++ -++#define R_68K_NONE 0 /* No reloc */ -++#define R_68K_32 1 /* Direct 32 bit */ -++#define R_68K_16 2 /* Direct 16 bit */ -++#define R_68K_8 3 /* Direct 8 bit */ -++#define R_68K_PC32 4 /* PC relative 32 bit */ -++#define R_68K_PC16 5 /* PC relative 16 bit */ -++#define R_68K_PC8 6 /* PC relative 8 bit */ -++#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ -++#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ -++#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ -++#define R_68K_GOT32O 10 /* 32 bit GOT offset */ -++#define R_68K_GOT16O 11 /* 16 bit GOT offset */ -++#define R_68K_GOT8O 12 /* 8 bit GOT offset */ -++#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ -++#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ -++#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ -++#define R_68K_PLT32O 16 /* 32 bit PLT offset */ -++#define R_68K_PLT16O 17 /* 16 bit PLT offset */ -++#define R_68K_PLT8O 18 /* 8 bit PLT offset */ -++#define R_68K_COPY 19 /* Copy symbol at runtime */ -++#define R_68K_GLOB_DAT 20 /* Create GOT entry */ -++#define R_68K_JMP_SLOT 21 /* Create PLT entry */ -++#define R_68K_RELATIVE 22 /* Adjust by program base */ -++#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */ -++#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */ -++#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */ -++#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */ -++#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */ -++#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */ -++#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */ -++#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */ -++#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */ -++#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */ -++#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */ -++#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */ -++#define R_68K_TLS_LE32 37 /* 32 bit offset relative to -++ static TLS block */ -++#define R_68K_TLS_LE16 38 /* 16 bit offset relative to -++ static TLS block */ -++#define R_68K_TLS_LE8 39 /* 8 bit offset relative to -++ static TLS block */ -++#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */ -++#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */ -++#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */ -++/* Keep this the last entry. */ -++#define R_68K_NUM 43 -++ -++/* Intel 80386 specific definitions. */ -++ -++/* i386 relocs. */ -++ -++#define R_386_NONE 0 /* No reloc */ -++#define R_386_32 1 /* Direct 32 bit */ -++#define R_386_PC32 2 /* PC relative 32 bit */ -++#define R_386_GOT32 3 /* 32 bit GOT entry */ -++#define R_386_PLT32 4 /* 32 bit PLT address */ -++#define R_386_COPY 5 /* Copy symbol at runtime */ -++#define R_386_GLOB_DAT 6 /* Create GOT entry */ -++#define R_386_JMP_SLOT 7 /* Create PLT entry */ -++#define R_386_RELATIVE 8 /* Adjust by program base */ -++#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ -++#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ -++#define R_386_32PLT 11 -++#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ -++#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS -++ block offset */ -++#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block -++ offset */ -++#define R_386_TLS_LE 17 /* Offset relative to static TLS -++ block */ -++#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of -++ general dynamic thread local data */ -++#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of -++ local dynamic thread local data -++ in LE code */ -++#define R_386_16 20 -++#define R_386_PC16 21 -++#define R_386_8 22 -++#define R_386_PC8 23 -++#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic -++ thread local data */ -++#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ -++#define R_386_TLS_GD_CALL 26 /* Relocation for call to -++ __tls_get_addr() */ -++#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ -++#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic -++ thread local data in LE code */ -++#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ -++#define R_386_TLS_LDM_CALL 30 /* Relocation for call to -++ __tls_get_addr() in LDM code */ -++#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ -++#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ -++#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS -++ block offset */ -++#define R_386_TLS_LE_32 34 /* Negated offset relative to static -++ TLS block */ -++#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ -++#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ -++#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ -++/* 38? */ -++#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */ -++#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS -++ descriptor for -++ relaxation. */ -++#define R_386_TLS_DESC 41 /* TLS descriptor containing -++ pointer to code and to -++ argument, returning the TLS -++ offset for the symbol. */ -++#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */ -++/* Keep this the last entry. */ -++#define R_386_NUM 43 -++ -++/* SUN SPARC specific definitions. */ -++ -++/* Legal values for ST_TYPE subfield of st_info (symbol type). */ -++ -++#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */ -++ -++/* Values for Elf64_Ehdr.e_flags. */ -++ -++#define EF_SPARCV9_MM 3 -++#define EF_SPARCV9_TSO 0 -++#define EF_SPARCV9_PSO 1 -++#define EF_SPARCV9_RMO 2 -++#define EF_SPARC_LEDATA 0x800000 /* little endian data */ -++#define EF_SPARC_EXT_MASK 0xFFFF00 -++#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ -++#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ -++#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */ -++#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */ -++ -++/* SPARC relocs. */ -++ -++#define R_SPARC_NONE 0 /* No reloc */ -++#define R_SPARC_8 1 /* Direct 8 bit */ -++#define R_SPARC_16 2 /* Direct 16 bit */ -++#define R_SPARC_32 3 /* Direct 32 bit */ -++#define R_SPARC_DISP8 4 /* PC relative 8 bit */ -++#define R_SPARC_DISP16 5 /* PC relative 16 bit */ -++#define R_SPARC_DISP32 6 /* PC relative 32 bit */ -++#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ -++#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ -++#define R_SPARC_HI22 9 /* High 22 bit */ -++#define R_SPARC_22 10 /* Direct 22 bit */ -++#define R_SPARC_13 11 /* Direct 13 bit */ -++#define R_SPARC_LO10 12 /* Truncated 10 bit */ -++#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ -++#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ -++#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ -++#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ -++#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ -++#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ -++#define R_SPARC_COPY 19 /* Copy symbol at runtime */ -++#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ -++#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ -++#define R_SPARC_RELATIVE 22 /* Adjust by program base */ -++#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ -++ -++/* Additional Sparc64 relocs. */ -++ -++#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ -++#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ -++#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ -++#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ -++#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ -++#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ -++#define R_SPARC_10 30 /* Direct 10 bit */ -++#define R_SPARC_11 31 /* Direct 11 bit */ -++#define R_SPARC_64 32 /* Direct 64 bit */ -++#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */ -++#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ -++#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ -++#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ -++#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ -++#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ -++#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ -++#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ -++#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ -++#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */ -++#define R_SPARC_7 43 /* Direct 7 bit */ -++#define R_SPARC_5 44 /* Direct 5 bit */ -++#define R_SPARC_6 45 /* Direct 6 bit */ -++#define R_SPARC_DISP64 46 /* PC relative 64 bit */ -++#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ -++#define R_SPARC_HIX22 48 /* High 22 bit complemented */ -++#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ -++#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ -++#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ -++#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ -++#define R_SPARC_REGISTER 53 /* Global register usage */ -++#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ -++#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ -++#define R_SPARC_TLS_GD_HI22 56 -++#define R_SPARC_TLS_GD_LO10 57 -++#define R_SPARC_TLS_GD_ADD 58 -++#define R_SPARC_TLS_GD_CALL 59 -++#define R_SPARC_TLS_LDM_HI22 60 -++#define R_SPARC_TLS_LDM_LO10 61 -++#define R_SPARC_TLS_LDM_ADD 62 -++#define R_SPARC_TLS_LDM_CALL 63 -++#define R_SPARC_TLS_LDO_HIX22 64 -++#define R_SPARC_TLS_LDO_LOX10 65 -++#define R_SPARC_TLS_LDO_ADD 66 -++#define R_SPARC_TLS_IE_HI22 67 -++#define R_SPARC_TLS_IE_LO10 68 -++#define R_SPARC_TLS_IE_LD 69 -++#define R_SPARC_TLS_IE_LDX 70 -++#define R_SPARC_TLS_IE_ADD 71 -++#define R_SPARC_TLS_LE_HIX22 72 -++#define R_SPARC_TLS_LE_LOX10 73 -++#define R_SPARC_TLS_DTPMOD32 74 -++#define R_SPARC_TLS_DTPMOD64 75 -++#define R_SPARC_TLS_DTPOFF32 76 -++#define R_SPARC_TLS_DTPOFF64 77 -++#define R_SPARC_TLS_TPOFF32 78 -++#define R_SPARC_TLS_TPOFF64 79 -++#define R_SPARC_GOTDATA_HIX22 80 -++#define R_SPARC_GOTDATA_LOX10 81 -++#define R_SPARC_GOTDATA_OP_HIX22 82 -++#define R_SPARC_GOTDATA_OP_LOX10 83 -++#define R_SPARC_GOTDATA_OP 84 -++#define R_SPARC_H34 85 -++#define R_SPARC_SIZE32 86 -++#define R_SPARC_SIZE64 87 -++#define R_SPARC_WDISP10 88 -++#define R_SPARC_JMP_IREL 248 -++#define R_SPARC_IRELATIVE 249 -++#define R_SPARC_GNU_VTINHERIT 250 -++#define R_SPARC_GNU_VTENTRY 251 -++#define R_SPARC_REV32 252 -++/* Keep this the last entry. */ -++#define R_SPARC_NUM 253 -++ -++/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ -++ -++#define DT_SPARC_REGISTER 0x70000001 -++#define DT_SPARC_NUM 2 -++ -++/* MIPS R3000 specific definitions. */ -++ -++/* Legal values for e_flags field of Elf32_Ehdr. */ -++ -++#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ -++#define EF_MIPS_PIC 2 /* Contains PIC code */ -++#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ -++#define EF_MIPS_XGOT 8 -++#define EF_MIPS_64BIT_WHIRL 16 -++#define EF_MIPS_ABI2 32 -++#define EF_MIPS_ABI_ON32 64 -++#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ -++ -++/* Legal values for MIPS architecture level. */ -++ -++#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ -++#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ -++#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ -++#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ -++#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ -++#define EF_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ -++#define EF_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ -++ -++/* The following are non-official names and should not be used. */ -++ -++#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ -++#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ -++#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ -++#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ -++#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ -++#define E_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ -++#define E_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ -++ -++/* Special section indices. */ -++ -++#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ -++#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ -++#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ -++#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ -++#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ -++ -++/* Legal values for sh_type field of Elf32_Shdr. */ -++ -++#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */ -++#define SHT_MIPS_MSYM 0x70000001 -++#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */ -++#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ -++#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ -++#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/ -++#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */ -++#define SHT_MIPS_PACKAGE 0x70000007 -++#define SHT_MIPS_PACKSYM 0x70000008 -++#define SHT_MIPS_RELD 0x70000009 -++#define SHT_MIPS_IFACE 0x7000000b -++#define SHT_MIPS_CONTENT 0x7000000c -++#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ -++#define SHT_MIPS_SHDR 0x70000010 -++#define SHT_MIPS_FDESC 0x70000011 -++#define SHT_MIPS_EXTSYM 0x70000012 -++#define SHT_MIPS_DENSE 0x70000013 -++#define SHT_MIPS_PDESC 0x70000014 -++#define SHT_MIPS_LOCSYM 0x70000015 -++#define SHT_MIPS_AUXSYM 0x70000016 -++#define SHT_MIPS_OPTSYM 0x70000017 -++#define SHT_MIPS_LOCSTR 0x70000018 -++#define SHT_MIPS_LINE 0x70000019 -++#define SHT_MIPS_RFDESC 0x7000001a -++#define SHT_MIPS_DELTASYM 0x7000001b -++#define SHT_MIPS_DELTAINST 0x7000001c -++#define SHT_MIPS_DELTACLASS 0x7000001d -++#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ -++#define SHT_MIPS_DELTADECL 0x7000001f -++#define SHT_MIPS_SYMBOL_LIB 0x70000020 -++#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ -++#define SHT_MIPS_TRANSLATE 0x70000022 -++#define SHT_MIPS_PIXIE 0x70000023 -++#define SHT_MIPS_XLATE 0x70000024 -++#define SHT_MIPS_XLATE_DEBUG 0x70000025 -++#define SHT_MIPS_WHIRL 0x70000026 -++#define SHT_MIPS_EH_REGION 0x70000027 -++#define SHT_MIPS_XLATE_OLD 0x70000028 -++#define SHT_MIPS_PDR_EXCEPTION 0x70000029 -++ -++/* Legal values for sh_flags field of Elf32_Shdr. */ -++ -++#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ -++#define SHF_MIPS_MERGE 0x20000000 -++#define SHF_MIPS_ADDR 0x40000000 -++#define SHF_MIPS_STRINGS 0x80000000 -++#define SHF_MIPS_NOSTRIP 0x08000000 -++#define SHF_MIPS_LOCAL 0x04000000 -++#define SHF_MIPS_NAMES 0x02000000 -++#define SHF_MIPS_NODUPE 0x01000000 -++ -++ -++/* Symbol tables. */ -++ -++/* MIPS specific values for `st_other'. */ -++#define STO_MIPS_DEFAULT 0x0 -++#define STO_MIPS_INTERNAL 0x1 -++#define STO_MIPS_HIDDEN 0x2 -++#define STO_MIPS_PROTECTED 0x3 -++#define STO_MIPS_PLT 0x8 -++#define STO_MIPS_SC_ALIGN_UNUSED 0xff -++ -++/* MIPS specific values for `st_info'. */ -++#define STB_MIPS_SPLIT_COMMON 13 -++ -++/* Entries found in sections of type SHT_MIPS_GPTAB. */ -++ -++typedef union -++{ -++ struct -++ { -++ Elf32_Word gt_current_g_value; /* -G value used for compilation */ -++ Elf32_Word gt_unused; /* Not used */ -++ } gt_header; /* First entry in section */ -++ struct -++ { -++ Elf32_Word gt_g_value; /* If this value were used for -G */ -++ Elf32_Word gt_bytes; /* This many bytes would be used */ -++ } gt_entry; /* Subsequent entries in section */ -++} Elf32_gptab; -++ -++/* Entry found in sections of type SHT_MIPS_REGINFO. */ -++ -++typedef struct -++{ -++ Elf32_Word ri_gprmask; /* General registers used */ -++ Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ -++ Elf32_Sword ri_gp_value; /* $gp register value */ -++} Elf32_RegInfo; -++ -++/* Entries found in sections of type SHT_MIPS_OPTIONS. */ -++ -++typedef struct -++{ -++ unsigned char kind; /* Determines interpretation of the -++ variable part of descriptor. */ -++ unsigned char size; /* Size of descriptor, including header. */ -++ Elf32_Section section; /* Section header index of section affected, -++ 0 for global options. */ -++ Elf32_Word info; /* Kind-specific information. */ -++} Elf_Options; -++ -++/* Values for `kind' field in Elf_Options. */ -++ -++#define ODK_NULL 0 /* Undefined. */ -++#define ODK_REGINFO 1 /* Register usage information. */ -++#define ODK_EXCEPTIONS 2 /* Exception processing options. */ -++#define ODK_PAD 3 /* Section padding options. */ -++#define ODK_HWPATCH 4 /* Hardware workarounds performed */ -++#define ODK_FILL 5 /* record the fill value used by the linker. */ -++#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ -++#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ -++#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ -++ -++/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ -++ -++#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ -++#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ -++#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ -++#define OEX_SMM 0x20000 /* Force sequential memory mode? */ -++#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ -++#define OEX_PRECISEFP OEX_FPDBUG -++#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ -++ -++#define OEX_FPU_INVAL 0x10 -++#define OEX_FPU_DIV0 0x08 -++#define OEX_FPU_OFLO 0x04 -++#define OEX_FPU_UFLO 0x02 -++#define OEX_FPU_INEX 0x01 -++ -++/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ -++ -++#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ -++#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ -++#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ -++#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ -++ -++#define OPAD_PREFIX 0x1 -++#define OPAD_POSTFIX 0x2 -++#define OPAD_SYMBOL 0x4 -++ -++/* Entry found in `.options' section. */ -++ -++typedef struct -++{ -++ Elf32_Word hwp_flags1; /* Extra flags. */ -++ Elf32_Word hwp_flags2; /* Extra flags. */ -++} Elf_Options_Hw; -++ -++/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ -++ -++#define OHWA0_R4KEOP_CHECKED 0x00000001 -++#define OHWA1_R4KEOP_CLEAN 0x00000002 -++ -++/* MIPS relocs. */ -++ -++#define R_MIPS_NONE 0 /* No reloc */ -++#define R_MIPS_16 1 /* Direct 16 bit */ -++#define R_MIPS_32 2 /* Direct 32 bit */ -++#define R_MIPS_REL32 3 /* PC relative 32 bit */ -++#define R_MIPS_26 4 /* Direct 26 bit shifted */ -++#define R_MIPS_HI16 5 /* High 16 bit */ -++#define R_MIPS_LO16 6 /* Low 16 bit */ -++#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ -++#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ -++#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ -++#define R_MIPS_PC16 10 /* PC relative 16 bit */ -++#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ -++#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ -++ -++#define R_MIPS_SHIFT5 16 -++#define R_MIPS_SHIFT6 17 -++#define R_MIPS_64 18 -++#define R_MIPS_GOT_DISP 19 -++#define R_MIPS_GOT_PAGE 20 -++#define R_MIPS_GOT_OFST 21 -++#define R_MIPS_GOT_HI16 22 -++#define R_MIPS_GOT_LO16 23 -++#define R_MIPS_SUB 24 -++#define R_MIPS_INSERT_A 25 -++#define R_MIPS_INSERT_B 26 -++#define R_MIPS_DELETE 27 -++#define R_MIPS_HIGHER 28 -++#define R_MIPS_HIGHEST 29 -++#define R_MIPS_CALL_HI16 30 -++#define R_MIPS_CALL_LO16 31 -++#define R_MIPS_SCN_DISP 32 -++#define R_MIPS_REL16 33 -++#define R_MIPS_ADD_IMMEDIATE 34 -++#define R_MIPS_PJUMP 35 -++#define R_MIPS_RELGOT 36 -++#define R_MIPS_JALR 37 -++#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */ -++#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */ -++#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */ -++#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */ -++#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */ -++#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */ -++#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */ -++#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */ -++#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */ -++#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */ -++#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */ -++#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */ -++#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */ -++#define R_MIPS_GLOB_DAT 51 -++#define R_MIPS_COPY 126 -++#define R_MIPS_JUMP_SLOT 127 -++/* Keep this the last entry. */ -++#define R_MIPS_NUM 128 -++ -++/* Legal values for p_type field of Elf32_Phdr. */ -++ -++#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ -++#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ -++#define PT_MIPS_OPTIONS 0x70000002 -++ -++/* Special program header types. */ -++ -++#define PF_MIPS_LOCAL 0x10000000 -++ -++/* Legal values for d_tag field of Elf32_Dyn. */ -++ -++#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ -++#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ -++#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ -++#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ -++#define DT_MIPS_FLAGS 0x70000005 /* Flags */ -++#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ -++#define DT_MIPS_MSYM 0x70000007 -++#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ -++#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ -++#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ -++#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ -++#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ -++#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ -++#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ -++#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ -++#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ -++#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ -++#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ -++#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in -++ DT_MIPS_DELTA_CLASS. */ -++#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ -++#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in -++ DT_MIPS_DELTA_INSTANCE. */ -++#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ -++#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in -++ DT_MIPS_DELTA_RELOC. */ -++#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta -++ relocations refer to. */ -++#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in -++ DT_MIPS_DELTA_SYM. */ -++#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the -++ class declaration. */ -++#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in -++ DT_MIPS_DELTA_CLASSSYM. */ -++#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ -++#define DT_MIPS_PIXIE_INIT 0x70000023 -++#define DT_MIPS_SYMBOL_LIB 0x70000024 -++#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 -++#define DT_MIPS_LOCAL_GOTIDX 0x70000026 -++#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 -++#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 -++#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ -++#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ -++#define DT_MIPS_DYNSTR_ALIGN 0x7000002b -++#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ -++#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve -++ function stored in GOT. */ -++#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added -++ by rld on dlopen() calls. */ -++#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ -++#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ -++#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ -++/* The address of .got.plt in an executable using the new non-PIC ABI. */ -++#define DT_MIPS_PLTGOT 0x70000032 -++/* The base of the PLT in an executable using the new non-PIC ABI if that -++ PLT is writable. For a non-writable PLT, this is omitted or has a zero -++ value. */ -++#define DT_MIPS_RWPLT 0x70000034 -++#define DT_MIPS_NUM 0x35 -++ -++/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ -++ -++#define RHF_NONE 0 /* No flags */ -++#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ -++#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ -++#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ -++#define RHF_NO_MOVE (1 << 3) -++#define RHF_SGI_ONLY (1 << 4) -++#define RHF_GUARANTEE_INIT (1 << 5) -++#define RHF_DELTA_C_PLUS_PLUS (1 << 6) -++#define RHF_GUARANTEE_START_INIT (1 << 7) -++#define RHF_PIXIE (1 << 8) -++#define RHF_DEFAULT_DELAY_LOAD (1 << 9) -++#define RHF_REQUICKSTART (1 << 10) -++#define RHF_REQUICKSTARTED (1 << 11) -++#define RHF_CORD (1 << 12) -++#define RHF_NO_UNRES_UNDEF (1 << 13) -++#define RHF_RLD_ORDER_SAFE (1 << 14) -++ -++/* Entries found in sections of type SHT_MIPS_LIBLIST. */ -++ -++typedef struct -++{ -++ Elf32_Word l_name; /* Name (string table index) */ -++ Elf32_Word l_time_stamp; /* Timestamp */ -++ Elf32_Word l_checksum; /* Checksum */ -++ Elf32_Word l_version; /* Interface version */ -++ Elf32_Word l_flags; /* Flags */ -++} Elf32_Lib; -++ -++typedef struct -++{ -++ Elf64_Word l_name; /* Name (string table index) */ -++ Elf64_Word l_time_stamp; /* Timestamp */ -++ Elf64_Word l_checksum; /* Checksum */ -++ Elf64_Word l_version; /* Interface version */ -++ Elf64_Word l_flags; /* Flags */ -++} Elf64_Lib; -++ -++ -++/* Legal values for l_flags. */ -++ -++#define LL_NONE 0 -++#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ -++#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ -++#define LL_REQUIRE_MINOR (1 << 2) -++#define LL_EXPORTS (1 << 3) -++#define LL_DELAY_LOAD (1 << 4) -++#define LL_DELTA (1 << 5) -++ -++/* Entries found in sections of type SHT_MIPS_CONFLICT. */ -++ -++typedef Elf32_Addr Elf32_Conflict; -++ -++ -++/* HPPA specific definitions. */ -++ -++/* Legal values for e_flags field of Elf32_Ehdr. */ -++ -++#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ -++#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ -++#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ -++#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ -++#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch -++ prediction. */ -++#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ -++#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ -++ -++/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ -++ -++#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ -++#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ -++#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ -++ -++/* Additional section indeces. */ -++ -++#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared -++ symbols in ANSI C. */ -++#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ -++ -++/* Legal values for sh_type field of Elf32_Shdr. */ -++ -++#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ -++#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ -++#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ -++ -++/* Legal values for sh_flags field of Elf32_Shdr. */ -++ -++#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ -++#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ -++#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ -++ -++/* Legal values for ST_TYPE subfield of st_info (symbol type). */ -++ -++#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ -++ -++#define STT_HP_OPAQUE (STT_LOOS + 0x1) -++#define STT_HP_STUB (STT_LOOS + 0x2) -++ -++/* HPPA relocs. */ -++ -++#define R_PARISC_NONE 0 /* No reloc. */ -++#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ -++#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ -++#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ -++#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ -++#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ -++#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ -++#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ -++#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ -++#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ -++#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ -++#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ -++#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ -++#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ -++#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ -++#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ -++#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ -++#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ -++#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ -++#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ -++#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ -++#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ -++#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ -++#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ -++#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ -++#define R_PARISC_FPTR64 64 /* 64 bits function address. */ -++#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ -++#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */ -++#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */ -++#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ -++#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ -++#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ -++#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ -++#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ -++#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ -++#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ -++#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ -++#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ -++#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ -++#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ -++#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ -++#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ -++#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ -++#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ -++#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ -++#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ -++#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ -++#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ -++#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ -++#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ -++#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ -++#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ -++#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ -++#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ -++#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ -++#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ -++#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ -++#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ -++#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ -++#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ -++#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ -++#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ -++#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ -++#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ -++#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ -++#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ -++#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ -++#define R_PARISC_LORESERVE 128 -++#define R_PARISC_COPY 128 /* Copy relocation. */ -++#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ -++#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ -++#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ -++#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ -++#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ -++#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ -++#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ -++#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ -++#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ -++#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ -++#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ -++#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ -++#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ -++#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ -++#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ -++#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ -++#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ -++#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ -++#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ -++#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ -++#define R_PARISC_GNU_VTENTRY 232 -++#define R_PARISC_GNU_VTINHERIT 233 -++#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */ -++#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */ -++#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */ -++#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */ -++#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */ -++#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */ -++#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */ -++#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */ -++#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */ -++#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */ -++#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */ -++#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */ -++#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L -++#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R -++#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L -++#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R -++#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32 -++#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64 -++#define R_PARISC_HIRESERVE 255 -++ -++/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ -++ -++#define PT_HP_TLS (PT_LOOS + 0x0) -++#define PT_HP_CORE_NONE (PT_LOOS + 0x1) -++#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) -++#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) -++#define PT_HP_CORE_COMM (PT_LOOS + 0x4) -++#define PT_HP_CORE_PROC (PT_LOOS + 0x5) -++#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) -++#define PT_HP_CORE_STACK (PT_LOOS + 0x7) -++#define PT_HP_CORE_SHM (PT_LOOS + 0x8) -++#define PT_HP_CORE_MMF (PT_LOOS + 0x9) -++#define PT_HP_PARALLEL (PT_LOOS + 0x10) -++#define PT_HP_FASTBIND (PT_LOOS + 0x11) -++#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) -++#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) -++#define PT_HP_STACK (PT_LOOS + 0x14) -++ -++#define PT_PARISC_ARCHEXT 0x70000000 -++#define PT_PARISC_UNWIND 0x70000001 -++ -++/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ -++ -++#define PF_PARISC_SBP 0x08000000 -++ -++#define PF_HP_PAGE_SIZE 0x00100000 -++#define PF_HP_FAR_SHARED 0x00200000 -++#define PF_HP_NEAR_SHARED 0x00400000 -++#define PF_HP_CODE 0x01000000 -++#define PF_HP_MODIFY 0x02000000 -++#define PF_HP_LAZYSWAP 0x04000000 -++#define PF_HP_SBP 0x08000000 -++ -++ -++/* Alpha specific definitions. */ -++ -++/* Legal values for e_flags field of Elf64_Ehdr. */ -++ -++#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ -++#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ -++ -++/* Legal values for sh_type field of Elf64_Shdr. */ -++ -++/* These two are primerily concerned with ECOFF debugging info. */ -++#define SHT_ALPHA_DEBUG 0x70000001 -++#define SHT_ALPHA_REGINFO 0x70000002 -++ -++/* Legal values for sh_flags field of Elf64_Shdr. */ -++ -++#define SHF_ALPHA_GPREL 0x10000000 -++ -++/* Legal values for st_other field of Elf64_Sym. */ -++#define STO_ALPHA_NOPV 0x80 /* No PV required. */ -++#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ -++ -++/* Alpha relocs. */ -++ -++#define R_ALPHA_NONE 0 /* No reloc */ -++#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ -++#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ -++#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ -++#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ -++#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ -++#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ -++#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ -++#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ -++#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ -++#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ -++#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ -++#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ -++#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ -++#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */ -++#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ -++#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ -++#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ -++#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ -++#define R_ALPHA_TLS_GD_HI 28 -++#define R_ALPHA_TLSGD 29 -++#define R_ALPHA_TLS_LDM 30 -++#define R_ALPHA_DTPMOD64 31 -++#define R_ALPHA_GOTDTPREL 32 -++#define R_ALPHA_DTPREL64 33 -++#define R_ALPHA_DTPRELHI 34 -++#define R_ALPHA_DTPRELLO 35 -++#define R_ALPHA_DTPREL16 36 -++#define R_ALPHA_GOTTPREL 37 -++#define R_ALPHA_TPREL64 38 -++#define R_ALPHA_TPRELHI 39 -++#define R_ALPHA_TPRELLO 40 -++#define R_ALPHA_TPREL16 41 -++/* Keep this the last entry. */ -++#define R_ALPHA_NUM 46 -++ -++/* Magic values of the LITUSE relocation addend. */ -++#define LITUSE_ALPHA_ADDR 0 -++#define LITUSE_ALPHA_BASE 1 -++#define LITUSE_ALPHA_BYTOFF 2 -++#define LITUSE_ALPHA_JSR 3 -++#define LITUSE_ALPHA_TLS_GD 4 -++#define LITUSE_ALPHA_TLS_LDM 5 -++ -++/* Legal values for d_tag of Elf64_Dyn. */ -++#define DT_ALPHA_PLTRO (DT_LOPROC + 0) -++#define DT_ALPHA_NUM 1 -++ -++/* PowerPC specific declarations */ -++ -++/* Values for Elf32/64_Ehdr.e_flags. */ -++#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ -++ -++/* Cygnus local bits below */ -++#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ -++#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib -++ flag */ -++ -++/* PowerPC relocations defined by the ABIs */ -++#define R_PPC_NONE 0 -++#define R_PPC_ADDR32 1 /* 32bit absolute address */ -++#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ -++#define R_PPC_ADDR16 3 /* 16bit absolute address */ -++#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ -++#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ -++#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ -++#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ -++#define R_PPC_ADDR14_BRTAKEN 8 -++#define R_PPC_ADDR14_BRNTAKEN 9 -++#define R_PPC_REL24 10 /* PC relative 26 bit */ -++#define R_PPC_REL14 11 /* PC relative 16 bit */ -++#define R_PPC_REL14_BRTAKEN 12 -++#define R_PPC_REL14_BRNTAKEN 13 -++#define R_PPC_GOT16 14 -++#define R_PPC_GOT16_LO 15 -++#define R_PPC_GOT16_HI 16 -++#define R_PPC_GOT16_HA 17 -++#define R_PPC_PLTREL24 18 -++#define R_PPC_COPY 19 -++#define R_PPC_GLOB_DAT 20 -++#define R_PPC_JMP_SLOT 21 -++#define R_PPC_RELATIVE 22 -++#define R_PPC_LOCAL24PC 23 -++#define R_PPC_UADDR32 24 -++#define R_PPC_UADDR16 25 -++#define R_PPC_REL32 26 -++#define R_PPC_PLT32 27 -++#define R_PPC_PLTREL32 28 -++#define R_PPC_PLT16_LO 29 -++#define R_PPC_PLT16_HI 30 -++#define R_PPC_PLT16_HA 31 -++#define R_PPC_SDAREL16 32 -++#define R_PPC_SECTOFF 33 -++#define R_PPC_SECTOFF_LO 34 -++#define R_PPC_SECTOFF_HI 35 -++#define R_PPC_SECTOFF_HA 36 -++ -++/* PowerPC relocations defined for the TLS access ABI. */ -++#define R_PPC_TLS 67 /* none (sym+add)@tls */ -++#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */ -++#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */ -++#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ -++#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ -++#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ -++#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */ -++#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */ -++#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ -++#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ -++#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ -++#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */ -++#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ -++#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ -++#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ -++#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ -++#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ -++#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ -++#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ -++#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ -++#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */ -++#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */ -++#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ -++#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ -++#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */ -++#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ -++#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ -++#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ -++ -++/* The remaining relocs are from the Embedded ELF ABI, and are not -++ in the SVR4 ELF ABI. */ -++#define R_PPC_EMB_NADDR32 101 -++#define R_PPC_EMB_NADDR16 102 -++#define R_PPC_EMB_NADDR16_LO 103 -++#define R_PPC_EMB_NADDR16_HI 104 -++#define R_PPC_EMB_NADDR16_HA 105 -++#define R_PPC_EMB_SDAI16 106 -++#define R_PPC_EMB_SDA2I16 107 -++#define R_PPC_EMB_SDA2REL 108 -++#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ -++#define R_PPC_EMB_MRKREF 110 -++#define R_PPC_EMB_RELSEC16 111 -++#define R_PPC_EMB_RELST_LO 112 -++#define R_PPC_EMB_RELST_HI 113 -++#define R_PPC_EMB_RELST_HA 114 -++#define R_PPC_EMB_BIT_FLD 115 -++#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ -++ -++/* Diab tool relocations. */ -++#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ -++#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ -++#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ -++#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ -++#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ -++#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ -++ -++/* GNU extension to support local ifunc. */ -++#define R_PPC_IRELATIVE 248 -++ -++/* GNU relocs used in PIC code sequences. */ -++#define R_PPC_REL16 249 /* half16 (sym+add-.) */ -++#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */ -++#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */ -++#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */ -++ -++/* This is a phony reloc to handle any old fashioned TOC16 references -++ that may still be in object files. */ -++#define R_PPC_TOC16 255 -++ -++/* PowerPC specific values for the Dyn d_tag field. */ -++#define DT_PPC_GOT (DT_LOPROC + 0) -++#define DT_PPC_NUM 1 -++ -++/* PowerPC64 relocations defined by the ABIs */ -++#define R_PPC64_NONE R_PPC_NONE -++#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */ -++#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */ -++#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */ -++#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */ -++#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */ -++#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ -++#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */ -++#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN -++#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN -++#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */ -++#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */ -++#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN -++#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN -++#define R_PPC64_GOT16 R_PPC_GOT16 -++#define R_PPC64_GOT16_LO R_PPC_GOT16_LO -++#define R_PPC64_GOT16_HI R_PPC_GOT16_HI -++#define R_PPC64_GOT16_HA R_PPC_GOT16_HA -++ -++#define R_PPC64_COPY R_PPC_COPY -++#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT -++#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT -++#define R_PPC64_RELATIVE R_PPC_RELATIVE -++ -++#define R_PPC64_UADDR32 R_PPC_UADDR32 -++#define R_PPC64_UADDR16 R_PPC_UADDR16 -++#define R_PPC64_REL32 R_PPC_REL32 -++#define R_PPC64_PLT32 R_PPC_PLT32 -++#define R_PPC64_PLTREL32 R_PPC_PLTREL32 -++#define R_PPC64_PLT16_LO R_PPC_PLT16_LO -++#define R_PPC64_PLT16_HI R_PPC_PLT16_HI -++#define R_PPC64_PLT16_HA R_PPC_PLT16_HA -++ -++#define R_PPC64_SECTOFF R_PPC_SECTOFF -++#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO -++#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI -++#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA -++#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */ -++#define R_PPC64_ADDR64 38 /* doubleword64 S + A */ -++#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */ -++#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */ -++#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */ -++#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */ -++#define R_PPC64_UADDR64 43 /* doubleword64 S + A */ -++#define R_PPC64_REL64 44 /* doubleword64 S + A - P */ -++#define R_PPC64_PLT64 45 /* doubleword64 L + A */ -++#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */ -++#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */ -++#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */ -++#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */ -++#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */ -++#define R_PPC64_TOC 51 /* doubleword64 .TOC */ -++#define R_PPC64_PLTGOT16 52 /* half16* M + A */ -++#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */ -++#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */ -++#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */ -++ -++#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */ -++#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */ -++#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */ -++#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */ -++#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */ -++#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */ -++#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */ -++#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */ -++#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */ -++#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */ -++#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */ -++ -++/* PowerPC64 relocations defined for the TLS access ABI. */ -++#define R_PPC64_TLS 67 /* none (sym+add)@tls */ -++#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */ -++#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */ -++#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ -++#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ -++#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ -++#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */ -++#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */ -++#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ -++#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ -++#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ -++#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */ -++#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ -++#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ -++#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ -++#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ -++#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ -++#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ -++#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ -++#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ -++#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */ -++#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */ -++#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ -++#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ -++#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */ -++#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */ -++#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */ -++#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */ -++#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */ -++#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */ -++#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */ -++#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */ -++#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */ -++#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */ -++#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */ -++#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */ -++#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */ -++#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ -++#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ -++#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ -++ -++/* GNU extension to support local ifunc. */ -++#define R_PPC64_JMP_IREL 247 -++#define R_PPC64_IRELATIVE 248 -++#define R_PPC64_REL16 249 /* half16 (sym+add-.) */ -++#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */ -++#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */ -++#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */ -++ -++/* PowerPC64 specific values for the Dyn d_tag field. */ -++#define DT_PPC64_GLINK (DT_LOPROC + 0) -++#define DT_PPC64_OPD (DT_LOPROC + 1) -++#define DT_PPC64_OPDSZ (DT_LOPROC + 2) -++#define DT_PPC64_NUM 3 -++ -++ -++/* ARM specific declarations */ -++ -++/* Processor specific flags for the ELF header e_flags field. */ -++#define EF_ARM_RELEXEC 0x01 -++#define EF_ARM_HASENTRY 0x02 -++#define EF_ARM_INTERWORK 0x04 -++#define EF_ARM_APCS_26 0x08 -++#define EF_ARM_APCS_FLOAT 0x10 -++#define EF_ARM_PIC 0x20 -++#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ -++#define EF_ARM_NEW_ABI 0x80 -++#define EF_ARM_OLD_ABI 0x100 -++#define EF_ARM_SOFT_FLOAT 0x200 -++#define EF_ARM_VFP_FLOAT 0x400 -++#define EF_ARM_MAVERICK_FLOAT 0x800 -++ -++ -++/* Other constants defined in the ARM ELF spec. version B-01. */ -++/* NB. These conflict with values defined above. */ -++#define EF_ARM_SYMSARESORTED 0x04 -++#define EF_ARM_DYNSYMSUSESEGIDX 0x08 -++#define EF_ARM_MAPSYMSFIRST 0x10 -++#define EF_ARM_EABIMASK 0XFF000000 -++ -++/* Constants defined in AAELF. */ -++#define EF_ARM_BE8 0x00800000 -++#define EF_ARM_LE8 0x00400000 -++ -++#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) -++#define EF_ARM_EABI_UNKNOWN 0x00000000 -++#define EF_ARM_EABI_VER1 0x01000000 -++#define EF_ARM_EABI_VER2 0x02000000 -++#define EF_ARM_EABI_VER3 0x03000000 -++#define EF_ARM_EABI_VER4 0x04000000 -++#define EF_ARM_EABI_VER5 0x05000000 -++ -++/* Additional symbol types for Thumb. */ -++#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ -++#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ -++ -++/* ARM-specific values for sh_flags */ -++#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ -++#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined -++ in the input to a link step. */ -++ -++/* ARM-specific program header flags */ -++#define PF_ARM_SB 0x10000000 /* Segment contains the location -++ addressed by the static base. */ -++#define PF_ARM_PI 0x20000000 /* Position-independent segment. */ -++#define PF_ARM_ABS 0x40000000 /* Absolute segment. */ -++ -++/* Processor specific values for the Phdr p_type field. */ -++#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */ -++ -++/* Processor specific values for the Shdr sh_type field. */ -++#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */ -++#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */ -++#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */ -++ -++ -++/* ARM relocs. */ -++ -++#define R_ARM_NONE 0 /* No reloc */ -++#define R_ARM_PC24 1 /* PC relative 26 bit branch */ -++#define R_ARM_ABS32 2 /* Direct 32 bit */ -++#define R_ARM_REL32 3 /* PC relative 32 bit */ -++#define R_ARM_PC13 4 -++#define R_ARM_ABS16 5 /* Direct 16 bit */ -++#define R_ARM_ABS12 6 /* Direct 12 bit */ -++#define R_ARM_THM_ABS5 7 -++#define R_ARM_ABS8 8 /* Direct 8 bit */ -++#define R_ARM_SBREL32 9 -++#define R_ARM_THM_PC22 10 -++#define R_ARM_THM_PC8 11 -++#define R_ARM_AMP_VCALL9 12 -++#define R_ARM_SWI24 13 /* Obsolete static relocation. */ -++#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */ -++#define R_ARM_THM_SWI8 14 -++#define R_ARM_XPC25 15 -++#define R_ARM_THM_XPC22 16 -++#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ -++#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ -++#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ -++#define R_ARM_COPY 20 /* Copy symbol at runtime */ -++#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ -++#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ -++#define R_ARM_RELATIVE 23 /* Adjust by program base */ -++#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ -++#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ -++#define R_ARM_GOT32 26 /* 32 bit GOT entry */ -++#define R_ARM_PLT32 27 /* 32 bit PLT address */ -++#define R_ARM_ALU_PCREL_7_0 32 -++#define R_ARM_ALU_PCREL_15_8 33 -++#define R_ARM_ALU_PCREL_23_15 34 -++#define R_ARM_LDR_SBREL_11_0 35 -++#define R_ARM_ALU_SBREL_19_12 36 -++#define R_ARM_ALU_SBREL_27_20 37 -++#define R_ARM_TLS_GOTDESC 90 -++#define R_ARM_TLS_CALL 91 -++#define R_ARM_TLS_DESCSEQ 92 -++#define R_ARM_THM_TLS_CALL 93 -++#define R_ARM_GNU_VTENTRY 100 -++#define R_ARM_GNU_VTINHERIT 101 -++#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ -++#define R_ARM_THM_PC9 103 /* thumb conditional branch */ -++#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic -++ thread local data */ -++#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic -++ thread local data */ -++#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS -++ block */ -++#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of -++ static TLS block offset */ -++#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static -++ TLS block */ -++#define R_ARM_THM_TLS_DESCSEQ 129 -++#define R_ARM_IRELATIVE 160 -++#define R_ARM_RXPC25 249 -++#define R_ARM_RSBREL32 250 -++#define R_ARM_THM_RPC22 251 -++#define R_ARM_RREL32 252 -++#define R_ARM_RABS22 253 -++#define R_ARM_RPC24 254 -++#define R_ARM_RBASE 255 -++/* Keep this the last entry. */ -++#define R_ARM_NUM 256 -++ -++/* IA-64 specific declarations. */ -++ -++/* Processor specific flags for the Ehdr e_flags field. */ -++#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */ -++#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */ -++#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */ -++ -++/* Processor specific values for the Phdr p_type field. */ -++#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ -++#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ -++#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12) -++#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13) -++#define PT_IA_64_HP_STACK (PT_LOOS + 0x14) -++ -++/* Processor specific flags for the Phdr p_flags field. */ -++#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ -++ -++/* Processor specific values for the Shdr sh_type field. */ -++#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */ -++#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */ -++ -++/* Processor specific flags for the Shdr sh_flags field. */ -++#define SHF_IA_64_SHORT 0x10000000 /* section near gp */ -++#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */ -++ -++/* Processor specific values for the Dyn d_tag field. */ -++#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) -++#define DT_IA_64_NUM 1 -++ -++/* IA-64 relocations. */ -++#define R_IA64_NONE 0x00 /* none */ -++#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */ -++#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */ -++#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */ -++#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */ -++#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */ -++#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */ -++#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */ -++#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */ -++#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */ -++#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */ -++#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */ -++#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */ -++#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */ -++#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */ -++#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */ -++#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */ -++#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */ -++#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */ -++#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */ -++#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */ -++#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */ -++#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */ -++#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */ -++#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */ -++#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */ -++#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */ -++#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */ -++#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */ -++#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */ -++#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */ -++#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */ -++#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */ -++#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */ -++#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */ -++#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */ -++#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */ -++#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */ -++#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */ -++#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */ -++#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */ -++#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */ -++#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */ -++#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */ -++#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */ -++#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */ -++#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */ -++#define R_IA64_REL32MSB 0x6c /* data 4 + REL */ -++#define R_IA64_REL32LSB 0x6d /* data 4 + REL */ -++#define R_IA64_REL64MSB 0x6e /* data 8 + REL */ -++#define R_IA64_REL64LSB 0x6f /* data 8 + REL */ -++#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */ -++#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */ -++#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */ -++#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */ -++#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */ -++#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */ -++#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */ -++#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */ -++#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */ -++#define R_IA64_COPY 0x84 /* copy relocation */ -++#define R_IA64_SUB 0x85 /* Addend and symbol difference */ -++#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */ -++#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */ -++#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */ -++#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */ -++#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */ -++#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */ -++#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */ -++#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */ -++#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */ -++#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */ -++#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */ -++#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */ -++#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */ -++#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */ -++#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */ -++#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */ -++#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */ -++#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */ -++#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */ -++ -++/* SH specific declarations */ -++ -++/* Processor specific flags for the ELF header e_flags field. */ -++#define EF_SH_MACH_MASK 0x1f -++#define EF_SH_UNKNOWN 0x0 -++#define EF_SH1 0x1 -++#define EF_SH2 0x2 -++#define EF_SH3 0x3 -++#define EF_SH_DSP 0x4 -++#define EF_SH3_DSP 0x5 -++#define EF_SH4AL_DSP 0x6 -++#define EF_SH3E 0x8 -++#define EF_SH4 0x9 -++#define EF_SH2E 0xb -++#define EF_SH4A 0xc -++#define EF_SH2A 0xd -++#define EF_SH4_NOFPU 0x10 -++#define EF_SH4A_NOFPU 0x11 -++#define EF_SH4_NOMMU_NOFPU 0x12 -++#define EF_SH2A_NOFPU 0x13 -++#define EF_SH3_NOMMU 0x14 -++#define EF_SH2A_SH4_NOFPU 0x15 -++#define EF_SH2A_SH3_NOFPU 0x16 -++#define EF_SH2A_SH4 0x17 -++#define EF_SH2A_SH3E 0x18 -++ -++/* SH relocs. */ -++#define R_SH_NONE 0 -++#define R_SH_DIR32 1 -++#define R_SH_REL32 2 -++#define R_SH_DIR8WPN 3 -++#define R_SH_IND12W 4 -++#define R_SH_DIR8WPL 5 -++#define R_SH_DIR8WPZ 6 -++#define R_SH_DIR8BP 7 -++#define R_SH_DIR8W 8 -++#define R_SH_DIR8L 9 -++#define R_SH_SWITCH16 25 -++#define R_SH_SWITCH32 26 -++#define R_SH_USES 27 -++#define R_SH_COUNT 28 -++#define R_SH_ALIGN 29 -++#define R_SH_CODE 30 -++#define R_SH_DATA 31 -++#define R_SH_LABEL 32 -++#define R_SH_SWITCH8 33 -++#define R_SH_GNU_VTINHERIT 34 -++#define R_SH_GNU_VTENTRY 35 -++#define R_SH_TLS_GD_32 144 -++#define R_SH_TLS_LD_32 145 -++#define R_SH_TLS_LDO_32 146 -++#define R_SH_TLS_IE_32 147 -++#define R_SH_TLS_LE_32 148 -++#define R_SH_TLS_DTPMOD32 149 -++#define R_SH_TLS_DTPOFF32 150 -++#define R_SH_TLS_TPOFF32 151 -++#define R_SH_GOT32 160 -++#define R_SH_PLT32 161 -++#define R_SH_COPY 162 -++#define R_SH_GLOB_DAT 163 -++#define R_SH_JMP_SLOT 164 -++#define R_SH_RELATIVE 165 -++#define R_SH_GOTOFF 166 -++#define R_SH_GOTPC 167 -++/* Keep this the last entry. */ -++#define R_SH_NUM 256 -++ -++/* S/390 specific definitions. */ -++ -++/* Valid values for the e_flags field. */ -++ -++#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */ -++ -++/* Additional s390 relocs */ -++ -++#define R_390_NONE 0 /* No reloc. */ -++#define R_390_8 1 /* Direct 8 bit. */ -++#define R_390_12 2 /* Direct 12 bit. */ -++#define R_390_16 3 /* Direct 16 bit. */ -++#define R_390_32 4 /* Direct 32 bit. */ -++#define R_390_PC32 5 /* PC relative 32 bit. */ -++#define R_390_GOT12 6 /* 12 bit GOT offset. */ -++#define R_390_GOT32 7 /* 32 bit GOT offset. */ -++#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ -++#define R_390_COPY 9 /* Copy symbol at runtime. */ -++#define R_390_GLOB_DAT 10 /* Create GOT entry. */ -++#define R_390_JMP_SLOT 11 /* Create PLT entry. */ -++#define R_390_RELATIVE 12 /* Adjust by program base. */ -++#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */ -++#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ -++#define R_390_GOT16 15 /* 16 bit GOT offset. */ -++#define R_390_PC16 16 /* PC relative 16 bit. */ -++#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ -++#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ -++#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ -++#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ -++#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ -++#define R_390_64 22 /* Direct 64 bit. */ -++#define R_390_PC64 23 /* PC relative 64 bit. */ -++#define R_390_GOT64 24 /* 64 bit GOT offset. */ -++#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ -++#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ -++#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */ -++#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */ -++#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */ -++#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */ -++#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */ -++#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */ -++#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */ -++#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */ -++#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */ -++#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */ -++#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */ -++#define R_390_TLS_GDCALL 38 /* Tag for function call in general -++ dynamic TLS code. */ -++#define R_390_TLS_LDCALL 39 /* Tag for function call in local -++ dynamic TLS code. */ -++#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic -++ thread local data. */ -++#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic -++ thread local data. */ -++#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS -++ block offset. */ -++#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS -++ block offset. */ -++#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS -++ block offset. */ -++#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic -++ thread local data in LE code. */ -++#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic -++ thread local data in LE code. */ -++#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for -++ negated static TLS block offset. */ -++#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for -++ negated static TLS block offset. */ -++#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for -++ negated static TLS block offset. */ -++#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to -++ static TLS block. */ -++#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to -++ static TLS block. */ -++#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS -++ block. */ -++#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS -++ block. */ -++#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */ -++#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ -++#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS -++ block. */ -++#define R_390_20 57 /* Direct 20 bit. */ -++#define R_390_GOT20 58 /* 20 bit GOT offset. */ -++#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ -++#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS -++ block offset. */ -++#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */ -++/* Keep this the last entry. */ -++#define R_390_NUM 62 -++ -++ -++/* CRIS relocations. */ -++#define R_CRIS_NONE 0 -++#define R_CRIS_8 1 -++#define R_CRIS_16 2 -++#define R_CRIS_32 3 -++#define R_CRIS_8_PCREL 4 -++#define R_CRIS_16_PCREL 5 -++#define R_CRIS_32_PCREL 6 -++#define R_CRIS_GNU_VTINHERIT 7 -++#define R_CRIS_GNU_VTENTRY 8 -++#define R_CRIS_COPY 9 -++#define R_CRIS_GLOB_DAT 10 -++#define R_CRIS_JUMP_SLOT 11 -++#define R_CRIS_RELATIVE 12 -++#define R_CRIS_16_GOT 13 -++#define R_CRIS_32_GOT 14 -++#define R_CRIS_16_GOTPLT 15 -++#define R_CRIS_32_GOTPLT 16 -++#define R_CRIS_32_GOTREL 17 -++#define R_CRIS_32_PLT_GOTREL 18 -++#define R_CRIS_32_PLT_PCREL 19 -++ -++#define R_CRIS_NUM 20 -++ -++ -++/* AMD x86-64 relocations. */ -++#define R_X86_64_NONE 0 /* No reloc */ -++#define R_X86_64_64 1 /* Direct 64 bit */ -++#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ -++#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ -++#define R_X86_64_PLT32 4 /* 32 bit PLT address */ -++#define R_X86_64_COPY 5 /* Copy symbol at runtime */ -++#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ -++#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ -++#define R_X86_64_RELATIVE 8 /* Adjust by program base */ -++#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative -++ offset to GOT */ -++#define R_X86_64_32 10 /* Direct 32 bit zero extended */ -++#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ -++#define R_X86_64_16 12 /* Direct 16 bit zero extended */ -++#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ -++#define R_X86_64_8 14 /* Direct 8 bit sign extended */ -++#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ -++#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ -++#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ -++#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ -++#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset -++ to two GOT entries for GD symbol */ -++#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset -++ to two GOT entries for LD symbol */ -++#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ -++#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset -++ to GOT entry for IE symbol */ -++#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ -++#define R_X86_64_PC64 24 /* PC relative 64 bit */ -++#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ -++#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative -++ offset to GOT */ -++#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */ -++#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset -++ to GOT entry */ -++#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */ -++#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */ -++#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset -++ to PLT entry */ -++#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */ -++#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */ -++#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */ -++#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS -++ descriptor. */ -++#define R_X86_64_TLSDESC 36 /* TLS descriptor. */ -++#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ -++#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */ -++ -++#define R_X86_64_NUM 39 -++ -++ -++/* AM33 relocations. */ -++#define R_MN10300_NONE 0 /* No reloc. */ -++#define R_MN10300_32 1 /* Direct 32 bit. */ -++#define R_MN10300_16 2 /* Direct 16 bit. */ -++#define R_MN10300_8 3 /* Direct 8 bit. */ -++#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ -++#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ -++#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ -++#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */ -++#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */ -++#define R_MN10300_24 9 /* Direct 24 bit. */ -++#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */ -++#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */ -++#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */ -++#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */ -++#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */ -++#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */ -++#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */ -++#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */ -++#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */ -++#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */ -++#define R_MN10300_COPY 20 /* Copy symbol at runtime. */ -++#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */ -++#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */ -++#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ -++ -++#define R_MN10300_NUM 24 -++ -++ -++/* M32R relocs. */ -++#define R_M32R_NONE 0 /* No reloc. */ -++#define R_M32R_16 1 /* Direct 16 bit. */ -++#define R_M32R_32 2 /* Direct 32 bit. */ -++#define R_M32R_24 3 /* Direct 24 bit. */ -++#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */ -++#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */ -++#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */ -++#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */ -++#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */ -++#define R_M32R_LO16 9 /* Low 16 bit. */ -++#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */ -++#define R_M32R_GNU_VTINHERIT 11 -++#define R_M32R_GNU_VTENTRY 12 -++/* M32R relocs use SHT_RELA. */ -++#define R_M32R_16_RELA 33 /* Direct 16 bit. */ -++#define R_M32R_32_RELA 34 /* Direct 32 bit. */ -++#define R_M32R_24_RELA 35 /* Direct 24 bit. */ -++#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */ -++#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */ -++#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */ -++#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */ -++#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */ -++#define R_M32R_LO16_RELA 41 /* Low 16 bit */ -++#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */ -++#define R_M32R_RELA_GNU_VTINHERIT 43 -++#define R_M32R_RELA_GNU_VTENTRY 44 -++#define R_M32R_REL32 45 /* PC relative 32 bit. */ -++ -++#define R_M32R_GOT24 48 /* 24 bit GOT entry */ -++#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */ -++#define R_M32R_COPY 50 /* Copy symbol at runtime */ -++#define R_M32R_GLOB_DAT 51 /* Create GOT entry */ -++#define R_M32R_JMP_SLOT 52 /* Create PLT entry */ -++#define R_M32R_RELATIVE 53 /* Adjust by program base */ -++#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */ -++#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */ -++#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned -++ low */ -++#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed -++ low */ -++#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */ -++#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to -++ GOT with unsigned low */ -++#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to -++ GOT with signed low */ -++#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to -++ GOT */ -++#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT -++ with unsigned low */ -++#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT -++ with signed low */ -++#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */ -++#define R_M32R_NUM 256 /* Keep this the last entry. */ -++ -++ -++/* TILEPro relocations. */ -++#define R_TILEPRO_NONE 0 /* No reloc */ -++#define R_TILEPRO_32 1 /* Direct 32 bit */ -++#define R_TILEPRO_16 2 /* Direct 16 bit */ -++#define R_TILEPRO_8 3 /* Direct 8 bit */ -++#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */ -++#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */ -++#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */ -++#define R_TILEPRO_LO16 7 /* Low 16 bit */ -++#define R_TILEPRO_HI16 8 /* High 16 bit */ -++#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */ -++#define R_TILEPRO_COPY 10 /* Copy relocation */ -++#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */ -++#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */ -++#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */ -++#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */ -++#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */ -++#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */ -++#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */ -++#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */ -++#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */ -++#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */ -++#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */ -++#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */ -++#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */ -++#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */ -++#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */ -++#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */ -++#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */ -++#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */ -++#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */ -++#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */ -++#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */ -++#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */ -++#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */ -++#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */ -++#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */ -++#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */ -++#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */ -++#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */ -++#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */ -++#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */ -++#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */ -++#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */ -++#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */ -++#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */ -++#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */ -++#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */ -++#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */ -++#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */ -++#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */ -++#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */ -++#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */ -++#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */ -++#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */ -++#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */ -++#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */ -++/* Relocs 56-59 are currently not defined. */ -++#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */ -++#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */ -++#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */ -++#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */ -++#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */ -++#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */ -++#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */ -++#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */ -++#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */ -++#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */ -++#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */ -++#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */ -++#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */ -++#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */ -++#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */ -++#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */ -++#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */ -++#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */ -++#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */ -++#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */ -++#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */ -++#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */ -++#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */ -++#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */ -++#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */ -++#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */ -++#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */ -++#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */ -++#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */ -++#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */ -++#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */ -++#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */ -++#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */ -++ -++#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ -++#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ -++ -++#define R_TILEPRO_NUM 130 -++ -++ -++/* TILE-Gx relocations. */ -++#define R_TILEGX_NONE 0 /* No reloc */ -++#define R_TILEGX_64 1 /* Direct 64 bit */ -++#define R_TILEGX_32 2 /* Direct 32 bit */ -++#define R_TILEGX_16 3 /* Direct 16 bit */ -++#define R_TILEGX_8 4 /* Direct 8 bit */ -++#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */ -++#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */ -++#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */ -++#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */ -++#define R_TILEGX_HW0 9 /* hword 0 16-bit */ -++#define R_TILEGX_HW1 10 /* hword 1 16-bit */ -++#define R_TILEGX_HW2 11 /* hword 2 16-bit */ -++#define R_TILEGX_HW3 12 /* hword 3 16-bit */ -++#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */ -++#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */ -++#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */ -++#define R_TILEGX_COPY 16 /* Copy relocation */ -++#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */ -++#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */ -++#define R_TILEGX_RELATIVE 19 /* Adjust by program base */ -++#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */ -++#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */ -++#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */ -++#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */ -++#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */ -++#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */ -++#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */ -++#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */ -++#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */ -++#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */ -++#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */ -++#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */ -++#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */ -++#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */ -++#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */ -++#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */ -++#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */ -++#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */ -++#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */ -++#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */ -++#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */ -++#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */ -++#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */ -++#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */ -++#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */ -++#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */ -++#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */ -++#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */ -++#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */ -++#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */ -++#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */ -++#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */ -++#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */ -++#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */ -++#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */ -++#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */ -++#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */ -++#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */ -++#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */ -++#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */ -++#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */ -++#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */ -++#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */ -++#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */ -++#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */ -++#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */ -++/* Relocs 66-71 are currently not defined. */ -++#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */ -++#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */ -++#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */ -++#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */ -++/* Relocs 76-77 are currently not defined. */ -++#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */ -++#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */ -++#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */ -++#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */ -++#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */ -++#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */ -++#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */ -++#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */ -++#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */ -++#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */ -++#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */ -++#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */ -++/* Relocs 90-91 are currently not defined. */ -++#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */ -++#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */ -++/* Relocs 94-99 are currently not defined. */ -++#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */ -++#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */ -++#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */ -++#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */ -++/* Relocs 104-105 are currently not defined. */ -++#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */ -++#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */ -++#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */ -++#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */ -++#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */ -++#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */ -++#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */ -++#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */ -++#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */ -++#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */ -++#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */ -++#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */ -++#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */ -++#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */ -++#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */ -++#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */ -++ -++#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ -++#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ -++ -++#define R_TILEGX_NUM 130 -++ -++#endif /* elf.h */ -+--- a/scripts/mod/mk_elfconfig.c -++++ b/scripts/mod/mk_elfconfig.c -+@@ -2,7 +2,11 @@ -+ #include -+ #include -+ #include -++#ifndef __APPLE__ -+ #include -++#else -++#include "elf.h" -++#endif -+ -+ int -+ main(int argc, char **argv) -+--- a/scripts/mod/modpost.h -++++ b/scripts/mod/modpost.h -+@@ -8,7 +8,11 @@ -+ #include -+ #include -+ #include -++#if !(defined(__APPLE__) || defined(__CYGWIN__)) -+ #include -++#else -++#include "elf.h" -++#endif -+ -+ #include "elfconfig.h" -+ -diff --git a/target/linux/generic/hack-4.14/211-host_tools_portability.patch b/target/linux/generic/hack-4.14/211-host_tools_portability.patch -new file mode 100644 -index 0000000000..d806df8a5f ---- /dev/null -+++ b/target/linux/generic/hack-4.14/211-host_tools_portability.patch -@@ -0,0 +1,40 @@ -+From 7f698012384ccb1ed10cc758acfd085096fdb307 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Fri, 7 Jul 2017 17:02:03 +0200 -+Subject: kernel: fix linux 4.9 host tools portability issues -+ -+Signed-off-by: Felix Fietkau -+--- -+ tools/build/Build.include | 2 +- -+ tools/perf/pmu-events/jevents.c | 1 + -+ tools/perf/pmu-events/json.c | 1 - -+ 3 files changed, 2 insertions(+), 2 deletions(-) -+ -+--- a/tools/build/Build.include -++++ b/tools/build/Build.include -+@@ -98,4 +98,4 @@ cxx_flags = -Wp,-MD,$(depfile) -Wp,-MT,$ -+ ### -+ ## HOSTCC C flags -+ -+-host_c_flags = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(CHOSTFLAGS) -D"BUILD_STR(s)=\#s" $(CHOSTFLAGS_$(basetarget).o) $(CHOSTFLAGS_$(obj)) -++host_c_flags = -MD -MF $(depfile) -MT $@ $(CHOSTFLAGS) -D"BUILD_STR(s)=\#s" $(CHOSTFLAGS_$(basetarget).o) $(CHOSTFLAGS_$(obj)) -+--- a/tools/perf/pmu-events/jevents.c -++++ b/tools/perf/pmu-events/jevents.c -+@@ -35,6 +35,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ #include -+--- a/tools/perf/pmu-events/json.c -++++ b/tools/perf/pmu-events/json.c -+@@ -38,7 +38,6 @@ -+ #include -+ #include "jsmn.h" -+ #include "json.h" -+-#include -+ -+ -+ static char *mapfile(const char *fn, size_t *size) -diff --git a/target/linux/generic/hack-4.14/212-byteshift_portability.patch b/target/linux/generic/hack-4.14/212-byteshift_portability.patch -new file mode 100644 -index 0000000000..1a5ac87988 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/212-byteshift_portability.patch -@@ -0,0 +1,65 @@ -+From 48232d3d931c95953ce2ddfe7da7bb164aef6a73 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Fri, 7 Jul 2017 17:03:16 +0200 -+Subject: linux-3.6: fix portability of some includes files in tools/ used on the host -+ -+lede-commit: 6040b1d29ab1f047c5e49b748abcb6a3196add28 -+Signed-off-by: Felix Fietkau -+--- -+ tools/include/tools/be_byteshift.h | 4 ++++ -+ tools/include/tools/le_byteshift.h | 4 ++++ -+ tools/include/tools/linux_types.h | 22 ++++++++++++++++++++++ -+ 3 files changed, 30 insertions(+) -+ create mode 100644 tools/include/tools/linux_types.h -+ -+--- a/tools/include/tools/be_byteshift.h -++++ b/tools/include/tools/be_byteshift.h -+@@ -2,6 +2,10 @@ -+ #ifndef _TOOLS_BE_BYTESHIFT_H -+ #define _TOOLS_BE_BYTESHIFT_H -+ -++#ifndef __linux__ -++#include "linux_types.h" -++#endif -++ -+ #include -+ -+ static inline uint16_t __get_unaligned_be16(const uint8_t *p) -+--- a/tools/include/tools/le_byteshift.h -++++ b/tools/include/tools/le_byteshift.h -+@@ -2,6 +2,10 @@ -+ #ifndef _TOOLS_LE_BYTESHIFT_H -+ #define _TOOLS_LE_BYTESHIFT_H -+ -++#ifndef __linux__ -++#include "linux_types.h" -++#endif -++ -+ #include -+ -+ static inline uint16_t __get_unaligned_le16(const uint8_t *p) -+--- /dev/null -++++ b/tools/include/tools/linux_types.h -+@@ -0,0 +1,22 @@ -++#ifndef __LINUX_TYPES_H -++#define __LINUX_TYPES_H -++ -++#include -++ -++typedef uint8_t __u8; -++typedef uint8_t __be8; -++typedef uint8_t __le8; -++ -++typedef uint16_t __u16; -++typedef uint16_t __be16; -++typedef uint16_t __le16; -++ -++typedef uint32_t __u32; -++typedef uint32_t __be32; -++typedef uint32_t __le32; -++ -++typedef uint64_t __u64; -++typedef uint64_t __be64; -++typedef uint64_t __le64; -++ -++#endif -diff --git a/target/linux/generic/hack-4.14/214-spidev_h_portability.patch b/target/linux/generic/hack-4.14/214-spidev_h_portability.patch -new file mode 100644 -index 0000000000..093f600c85 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/214-spidev_h_portability.patch -@@ -0,0 +1,24 @@ -+From be9be95ff10e16a5b4ad36f903978d0cc5747024 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Fri, 7 Jul 2017 17:04:08 +0200 -+Subject: kernel: fix linux/spi/spidev.h portability issues with musl -+ -+Felix will try to get this define included into musl -+ -+lede-commit: 795e7cf60de19e7a076a46874fab7bb88b43bbff -+Signed-off-by: Felix Fietkau -+--- -+ include/uapi/linux/spi/spidev.h | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/include/uapi/linux/spi/spidev.h -++++ b/include/uapi/linux/spi/spidev.h -+@@ -113,7 +113,7 @@ struct spi_ioc_transfer { -+ -+ /* not all platforms use or _IOC_TYPECHECK() ... */ -+ #define SPI_MSGSIZE(N) \ -+- ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \ -++ ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << 13)) \ -+ ? ((N)*(sizeof (struct spi_ioc_transfer))) : 0) -+ #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)]) -+ -diff --git a/target/linux/generic/hack-4.14/220-gc_sections.patch b/target/linux/generic/hack-4.14/220-gc_sections.patch -new file mode 100644 -index 0000000000..6a4475fc6e ---- /dev/null -+++ b/target/linux/generic/hack-4.14/220-gc_sections.patch -@@ -0,0 +1,258 @@ -+From e3d8676f5722b7622685581e06e8f53e6138e3ab Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Sat, 15 Jul 2017 23:42:36 +0200 -+Subject: use -ffunction-sections, -fdata-sections and --gc-sections -+ -+In combination with kernel symbol export stripping this significantly reduces -+the kernel image size. Used on both ARM and MIPS architectures. -+ -+Signed-off-by: Felix Fietkau -+Signed-off-by: Jonas Gorski -+Signed-off-by: Gabor Juhos -+--- -+ Makefile | 10 +++---- -+ arch/arm/Kconfig | 1 + -+ arch/arm/boot/compressed/Makefile | 1 + -+ arch/arm/kernel/vmlinux.lds.S | 26 ++++++++-------- -+ arch/mips/Kconfig | 1 + -+ arch/mips/kernel/vmlinux.lds.S | 4 +-- -+ include/asm-generic/vmlinux.lds.h | 63 ++++++++++++++++++++------------------- -+ 7 files changed, 55 insertions(+), 51 deletions(-) -+ -+--- a/Makefile -++++ b/Makefile -+@@ -272,6 +272,11 @@ else -+ scripts/Kbuild.include: ; -+ include scripts/Kbuild.include -+ -++ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION -++KBUILD_CFLAGS_KERNEL += $(call cc-option,-ffunction-sections,) -++KBUILD_CFLAGS_KERNEL += $(call cc-option,-fdata-sections,) -++endif -++ -+ # Read KERNELRELEASE from include/config/kernel.release (if it exists) -+ KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null) -+ KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION) -+@@ -779,11 +784,6 @@ ifdef CONFIG_DEBUG_SECTION_MISMATCH -+ KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once) -+ endif -+ -+-ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION -+-KBUILD_CFLAGS += $(call cc-option,-ffunction-sections,) -+-KBUILD_CFLAGS += $(call cc-option,-fdata-sections,) -+-endif -+- -+ # arch Makefile may override CC so keep this after arch Makefile is included -+ NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) -+ CHECKFLAGS += $(NOSTDINC_FLAGS) -+--- a/arch/arm/Kconfig -++++ b/arch/arm/Kconfig -+@@ -91,6 +91,7 @@ config ARM -+ select HAVE_UID16 -+ select HAVE_VIRT_CPU_ACCOUNTING_GEN -+ select IRQ_FORCED_THREADING -++ select LD_DEAD_CODE_DATA_ELIMINATION -+ select MODULES_USE_ELF_REL -+ select NO_BOOTMEM -+ select OF_EARLY_FLATTREE if OF -+--- a/arch/arm/boot/compressed/Makefile -++++ b/arch/arm/boot/compressed/Makefile -+@@ -103,6 +103,7 @@ ifeq ($(CONFIG_FUNCTION_TRACER),y) -+ ORIG_CFLAGS := $(KBUILD_CFLAGS) -+ KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) -+ endif -++KBUILD_CFLAGS_KERNEL := $(patsubst -f%-sections,,$(KBUILD_CFLAGS_KERNEL)) -+ -+ # -fstack-protector-strong triggers protection checks in this code, -+ # but it is being used too early to link to meaningful stack_chk logic. -+--- a/arch/arm/kernel/vmlinux.lds.S -++++ b/arch/arm/kernel/vmlinux.lds.S -+@@ -18,7 +18,7 @@ -+ #define PROC_INFO \ -+ . = ALIGN(4); \ -+ VMLINUX_SYMBOL(__proc_info_begin) = .; \ -+- *(.proc.info.init) \ -++ KEEP(*(.proc.info.init)) \ -+ VMLINUX_SYMBOL(__proc_info_end) = .; -+ -+ #define HYPERVISOR_TEXT \ -+@@ -29,11 +29,11 @@ -+ #define IDMAP_TEXT \ -+ ALIGN_FUNCTION(); \ -+ VMLINUX_SYMBOL(__idmap_text_start) = .; \ -+- *(.idmap.text) \ -++ KEEP(*(.idmap.text)) \ -+ VMLINUX_SYMBOL(__idmap_text_end) = .; \ -+ . = ALIGN(PAGE_SIZE); \ -+ VMLINUX_SYMBOL(__hyp_idmap_text_start) = .; \ -+- *(.hyp.idmap.text) \ -++ KEEP(*(.hyp.idmap.text)) \ -+ VMLINUX_SYMBOL(__hyp_idmap_text_end) = .; -+ -+ #ifdef CONFIG_HOTPLUG_CPU -+@@ -106,7 +106,7 @@ SECTIONS -+ _stext = .; /* Text and read-only data */ -+ IDMAP_TEXT -+ __exception_text_start = .; -+- *(.exception.text) -++ KEEP(*(.exception.text)) -+ __exception_text_end = .; -+ IRQENTRY_TEXT -+ SOFTIRQENTRY_TEXT -+@@ -135,7 +135,7 @@ SECTIONS -+ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { -+ __start___ex_table = .; -+ #ifdef CONFIG_MMU -+- *(__ex_table) -++ KEEP(*(__ex_table)) -+ #endif -+ __stop___ex_table = .; -+ } -+@@ -147,12 +147,12 @@ SECTIONS -+ . = ALIGN(8); -+ .ARM.unwind_idx : { -+ __start_unwind_idx = .; -+- *(.ARM.exidx*) -++ KEEP(*(.ARM.exidx*)) -+ __stop_unwind_idx = .; -+ } -+ .ARM.unwind_tab : { -+ __start_unwind_tab = .; -+- *(.ARM.extab*) -++ KEEP(*(.ARM.extab*)) -+ __stop_unwind_tab = .; -+ } -+ #endif -+@@ -172,14 +172,14 @@ SECTIONS -+ */ -+ __vectors_start = .; -+ .vectors 0xffff0000 : AT(__vectors_start) { -+- *(.vectors) -++ KEEP(*(.vectors)) -+ } -+ . = __vectors_start + SIZEOF(.vectors); -+ __vectors_end = .; -+ -+ __stubs_start = .; -+ .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) { -+- *(.stubs) -++ KEEP(*(.stubs)) -+ } -+ . = __stubs_start + SIZEOF(.stubs); -+ __stubs_end = .; -+@@ -195,24 +195,24 @@ SECTIONS -+ } -+ .init.arch.info : { -+ __arch_info_begin = .; -+- *(.arch.info.init) -++ KEEP(*(.arch.info.init)) -+ __arch_info_end = .; -+ } -+ .init.tagtable : { -+ __tagtable_begin = .; -+- *(.taglist.init) -++ KEEP(*(.taglist.init)) -+ __tagtable_end = .; -+ } -+ #ifdef CONFIG_SMP_ON_UP -+ .init.smpalt : { -+ __smpalt_begin = .; -+- *(.alt.smp.init) -++ KEEP(*(.alt.smp.init)) -+ __smpalt_end = .; -+ } -+ #endif -+ .init.pv_table : { -+ __pv_table_begin = .; -+- *(.pv_table) -++ KEEP(*(.pv_table)) -+ __pv_table_end = .; -+ } -+ .init.data : { -+--- a/arch/mips/Kconfig -++++ b/arch/mips/Kconfig -+@@ -40,6 +40,7 @@ config MIPS -+ select HAVE_CBPF_JIT if (!64BIT && !CPU_MICROMIPS) -+ select HAVE_EBPF_JIT if (64BIT && !CPU_MICROMIPS) -+ select HAVE_CC_STACKPROTECTOR -++ select LD_DEAD_CODE_DATA_ELIMINATION -+ select HAVE_CONTEXT_TRACKING -+ select HAVE_COPY_THREAD_TLS -+ select HAVE_C_RECORDMCOUNT -+--- a/arch/mips/kernel/vmlinux.lds.S -++++ b/arch/mips/kernel/vmlinux.lds.S -+@@ -72,7 +72,7 @@ SECTIONS -+ /* Exception table for data bus errors */ -+ __dbe_table : { -+ __start___dbe_table = .; -+- *(__dbe_table) -++ KEEP(*(__dbe_table)) -+ __stop___dbe_table = .; -+ } -+ -+@@ -123,7 +123,7 @@ SECTIONS -+ . = ALIGN(4); -+ .mips.machines.init : AT(ADDR(.mips.machines.init) - LOAD_OFFSET) { -+ __mips_machines_start = .; -+- *(.mips.machines.init) -++ KEEP(*(.mips.machines.init)) -+ __mips_machines_end = .; -+ } -+ -+--- a/include/asm-generic/vmlinux.lds.h -++++ b/include/asm-generic/vmlinux.lds.h -+@@ -105,7 +105,7 @@ -+ #ifdef CONFIG_FTRACE_MCOUNT_RECORD -+ #define MCOUNT_REC() . = ALIGN(8); \ -+ VMLINUX_SYMBOL(__start_mcount_loc) = .; \ -+- *(__mcount_loc) \ -++ KEEP(*(__mcount_loc)) \ -+ VMLINUX_SYMBOL(__stop_mcount_loc) = .; -+ #else -+ #define MCOUNT_REC() -+@@ -113,7 +113,7 @@ -+ -+ #ifdef CONFIG_TRACE_BRANCH_PROFILING -+ #define LIKELY_PROFILE() VMLINUX_SYMBOL(__start_annotated_branch_profile) = .; \ -+- *(_ftrace_annotated_branch) \ -++ KEEP(*(_ftrace_annotated_branch)) \ -+ VMLINUX_SYMBOL(__stop_annotated_branch_profile) = .; -+ #else -+ #define LIKELY_PROFILE() -+@@ -121,7 +121,7 @@ -+ -+ #ifdef CONFIG_PROFILE_ALL_BRANCHES -+ #define BRANCH_PROFILE() VMLINUX_SYMBOL(__start_branch_profile) = .; \ -+- *(_ftrace_branch) \ -++ KEEP(*(_ftrace_branch)) \ -+ VMLINUX_SYMBOL(__stop_branch_profile) = .; -+ #else -+ #define BRANCH_PROFILE() -+@@ -237,7 +237,8 @@ -+ LIKELY_PROFILE() \ -+ BRANCH_PROFILE() \ -+ TRACE_PRINTKS() \ -+- TRACEPOINT_STR() -++ TRACEPOINT_STR() \ -++ *(.data.[a-zA-Z_]*) -+ -+ /* -+ * Data section helpers -+@@ -497,7 +498,7 @@ -+ #define ENTRY_TEXT \ -+ ALIGN_FUNCTION(); \ -+ VMLINUX_SYMBOL(__entry_text_start) = .; \ -+- *(.entry.text) \ -++ KEEP(*(.entry.text)) \ -+ VMLINUX_SYMBOL(__entry_text_end) = .; -+ -+ #define IRQENTRY_TEXT \ -+@@ -604,7 +605,7 @@ -+ . = ALIGN(sbss_align); \ -+ .sbss : AT(ADDR(.sbss) - LOAD_OFFSET) { \ -+ *(.dynsbss) \ -+- *(.sbss) \ -++ *(.sbss .sbss.*) \ -+ *(.scommon) \ -+ } -+ -diff --git a/target/linux/generic/hack-4.14/221-module_exports.patch b/target/linux/generic/hack-4.14/221-module_exports.patch -new file mode 100644 -index 0000000000..003175c223 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/221-module_exports.patch -@@ -0,0 +1,101 @@ -+From b14784e7883390c20ed3ff904892255404a5914b Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Fri, 7 Jul 2017 17:05:53 +0200 -+Subject: add an optional config option for stripping all unnecessary symbol exports from the kernel image -+ -+lede-commit: bb5a40c64b7c4f4848509fa0a6625055fc9e66cc -+Signed-off-by: Felix Fietkau -+--- -+ include/asm-generic/vmlinux.lds.h | 18 +++++++++++++++--- -+ include/linux/export.h | 9 ++++++++- -+ scripts/Makefile.build | 2 +- -+ 3 files changed, 24 insertions(+), 5 deletions(-) -+ -+--- a/include/asm-generic/vmlinux.lds.h -++++ b/include/asm-generic/vmlinux.lds.h -+@@ -54,6 +54,16 @@ -+ #define LOAD_OFFSET 0 -+ #endif -+ -++#ifndef SYMTAB_KEEP -++#define SYMTAB_KEEP KEEP(*(SORT(___ksymtab+*))) -++#define SYMTAB_KEEP_GPL KEEP(*(SORT(___ksymtab_gpl+*))) -++#endif -++ -++#ifndef SYMTAB_DISCARD -++#define SYMTAB_DISCARD -++#define SYMTAB_DISCARD_GPL -++#endif -++ -+ #include -+ -+ /* Align . to a 8 byte boundary equals to maximum function alignment. */ -+@@ -342,14 +352,14 @@ -+ /* Kernel symbol table: Normal symbols */ \ -+ __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ -+ VMLINUX_SYMBOL(__start___ksymtab) = .; \ -+- KEEP(*(SORT(___ksymtab+*))) \ -++ SYMTAB_KEEP \ -+ VMLINUX_SYMBOL(__stop___ksymtab) = .; \ -+ } \ -+ \ -+ /* Kernel symbol table: GPL-only symbols */ \ -+ __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \ -+ VMLINUX_SYMBOL(__start___ksymtab_gpl) = .; \ -+- KEEP(*(SORT(___ksymtab_gpl+*))) \ -++ SYMTAB_KEEP_GPL \ -+ VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \ -+ } \ -+ \ -+@@ -411,7 +421,7 @@ -+ \ -+ /* Kernel symbol table: strings */ \ -+ __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ -+- *(__ksymtab_strings) \ -++ *(__ksymtab_strings+*) \ -+ } \ -+ \ -+ /* __*init sections */ \ -+@@ -796,6 +806,8 @@ -+ EXIT_TEXT \ -+ EXIT_DATA \ -+ EXIT_CALL \ -++ SYMTAB_DISCARD \ -++ SYMTAB_DISCARD_GPL \ -+ *(.discard) \ -+ *(.discard.*) \ -+ } -+--- a/include/linux/export.h -++++ b/include/linux/export.h -+@@ -60,12 +60,19 @@ extern struct module __this_module; -+ #define __CRC_SYMBOL(sym, sec) -+ #endif -+ -++#ifdef MODULE -++#define __EXPORT_SUFFIX(sym) -++#else -++#define __EXPORT_SUFFIX(sym) "+" #sym -++#endif -++ -+ /* For every exported symbol, place a struct in the __ksymtab section */ -+ #define ___EXPORT_SYMBOL(sym, sec) \ -+ extern typeof(sym) sym; \ -+ __CRC_SYMBOL(sym, sec) \ -+ static const char __kstrtab_##sym[] \ -+- __attribute__((section("__ksymtab_strings"), aligned(1))) \ -++ __attribute__((section("__ksymtab_strings" \ -++ __EXPORT_SUFFIX(sym)), aligned(1))) \ -+ = VMLINUX_SYMBOL_STR(sym); \ -+ static const struct kernel_symbol __ksymtab_##sym \ -+ __used \ -+--- a/scripts/Makefile.build -++++ b/scripts/Makefile.build -+@@ -432,7 +432,7 @@ targets += $(extra-y) $(MAKECMDGOALS) $( -+ # Linker scripts preprocessor (.lds.S -> .lds) -+ # --------------------------------------------------------------------------- -+ quiet_cmd_cpp_lds_S = LDS $@ -+- cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -U$(ARCH) \ -++ cmd_cpp_lds_S = $(CPP) $(EXTRA_LDSFLAGS) $(cpp_flags) -P -U$(ARCH) \ -+ -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $< -+ -+ $(obj)/%.lds: $(src)/%.lds.S FORCE -diff --git a/target/linux/generic/hack-4.14/230-openwrt_lzma_options.patch b/target/linux/generic/hack-4.14/230-openwrt_lzma_options.patch -new file mode 100644 -index 0000000000..3ae578c271 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/230-openwrt_lzma_options.patch -@@ -0,0 +1,71 @@ -+From b3d00b452467f621317953d9e4c6f9ae8dcfd271 Mon Sep 17 00:00:00 2001 -+From: Imre Kaloz -+Date: Fri, 7 Jul 2017 17:06:55 +0200 -+Subject: use the openwrt lzma options for now -+ -+lede-commit: 548de949f392049420a6a1feeef118b30ab8ea8c -+Signed-off-by: Imre Kaloz -+--- -+ lib/decompress.c | 1 + -+ scripts/Makefile.lib | 2 +- -+ scripts/gen_initramfs_list.sh | 10 +++++----- -+ 3 files changed, 7 insertions(+), 6 deletions(-) -+ -+--- a/lib/decompress.c -++++ b/lib/decompress.c -+@@ -49,6 +49,7 @@ static const struct compress_format comp -+ { {0x1f, 0x9e}, "gzip", gunzip }, -+ { {0x42, 0x5a}, "bzip2", bunzip2 }, -+ { {0x5d, 0x00}, "lzma", unlzma }, -++ { {0x6d, 0x00}, "lzma-openwrt", unlzma }, -+ { {0xfd, 0x37}, "xz", unxz }, -+ { {0x89, 0x4c}, "lzo", unlzo }, -+ { {0x02, 0x21}, "lz4", unlz4 }, -+--- a/scripts/Makefile.lib -++++ b/scripts/Makefile.lib -+@@ -348,7 +348,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^) -+ -+ quiet_cmd_lzma = LZMA $@ -+ cmd_lzma = (cat $(filter-out FORCE,$^) | \ -+- lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ -++ lzma e -d20 -lc1 -lp2 -pb2 -eos -si -so && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ -+ (rm -f $@ ; false) -+ -+ quiet_cmd_lzo = LZO $@ -+--- a/scripts/gen_initramfs_list.sh -++++ b/scripts/gen_initramfs_list.sh -+@@ -229,7 +229,7 @@ cpio_list= -+ output="/dev/stdout" -+ output_file="" -+ is_cpio_compressed= -+-compr="gzip -n -9 -f" -++compr="gzip -n -9 -f -" -+ -+ arg="$1" -+ case "$arg" in -+@@ -245,13 +245,13 @@ case "$arg" in -+ output=${cpio_list} -+ echo "$output_file" | grep -q "\.gz$" \ -+ && [ -x "`which gzip 2> /dev/null`" ] \ -+- && compr="gzip -n -9 -f" -++ && compr="gzip -n -9 -f -" -+ echo "$output_file" | grep -q "\.bz2$" \ -+ && [ -x "`which bzip2 2> /dev/null`" ] \ -+- && compr="bzip2 -9 -f" -++ && compr="bzip2 -9 -f -" -+ echo "$output_file" | grep -q "\.lzma$" \ -+ && [ -x "`which lzma 2> /dev/null`" ] \ -+- && compr="lzma -9 -f" -++ && compr="lzma e -d20 -lc1 -lp2 -pb2 -eos -si -so" -+ echo "$output_file" | grep -q "\.xz$" \ -+ && [ -x "`which xz 2> /dev/null`" ] \ -+ && compr="xz --check=crc32 --lzma2=dict=1MiB" -+@@ -320,7 +320,7 @@ if [ ! -z ${output_file} ]; then -+ if [ "${is_cpio_compressed}" = "compressed" ]; then -+ cat ${cpio_tfile} > ${output_file} -+ else -+- (cat ${cpio_tfile} | ${compr} - > ${output_file}) \ -++ (cat ${cpio_tfile} | ${compr} > ${output_file}) \ -+ || (rm -f ${output_file} ; false) -+ fi -+ [ -z ${cpio_file} ] && rm ${cpio_tfile} -diff --git a/target/linux/generic/hack-4.14/250-netfilter_depends.patch b/target/linux/generic/hack-4.14/250-netfilter_depends.patch -new file mode 100644 -index 0000000000..a8fe5d4175 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/250-netfilter_depends.patch -@@ -0,0 +1,27 @@ -+From: Felix Fietkau -+Subject: hack: net: remove bogus netfilter dependencies -+ -+lede-commit: 589d2a377dee27d206fc3725325309cf649e4df6 -+Signed-off-by: Felix Fietkau -+--- -+ net/netfilter/Kconfig | 2 -- -+ 1 file changed, 2 deletions(-) -+ -+--- a/net/netfilter/Kconfig -++++ b/net/netfilter/Kconfig -+@@ -229,7 +229,6 @@ config NF_CONNTRACK_FTP -+ -+ config NF_CONNTRACK_H323 -+ tristate "H.323 protocol support" -+- depends on IPV6 || IPV6=n -+ depends on NETFILTER_ADVANCED -+ help -+ H.323 is a VoIP signalling protocol from ITU-T. As one of the most -+@@ -1052,7 +1051,6 @@ config NETFILTER_XT_TARGET_SECMARK -+ -+ config NETFILTER_XT_TARGET_TCPMSS -+ tristate '"TCPMSS" target support' -+- depends on IPV6 || IPV6=n -+ default m if NETFILTER_ADVANCED=n -+ ---help--- -+ This option adds a `TCPMSS' target, which allows you to alter the -diff --git a/target/linux/generic/hack-4.14/251-sound_kconfig.patch b/target/linux/generic/hack-4.14/251-sound_kconfig.patch -new file mode 100644 -index 0000000000..5bf5c01ad3 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/251-sound_kconfig.patch -@@ -0,0 +1,197 @@ -+From da3c50704f14132f4adf80d48e9a4cd5d46e54c9 Mon Sep 17 00:00:00 2001 -+From: John Crispin -+Date: Fri, 7 Jul 2017 17:09:21 +0200 -+Subject: kconfig: owrt specifc dependencies -+ -+Signed-off-by: John Crispin -+--- -+ crypto/Kconfig | 10 +++++----- -+ drivers/bcma/Kconfig | 1 + -+ drivers/ssb/Kconfig | 3 ++- -+ lib/Kconfig | 8 ++++---- -+ net/netfilter/Kconfig | 2 +- -+ net/wireless/Kconfig | 17 ++++++++++------- -+ sound/core/Kconfig | 4 ++-- -+ 7 files changed, 25 insertions(+), 20 deletions(-) -+ -+--- a/crypto/Kconfig -++++ b/crypto/Kconfig -+@@ -33,7 +33,7 @@ config CRYPTO_FIPS -+ this is. -+ -+ config CRYPTO_ALGAPI -+- tristate -++ tristate "ALGAPI" -+ select CRYPTO_ALGAPI2 -+ help -+ This option provides the API for cryptographic algorithms. -+@@ -42,7 +42,7 @@ config CRYPTO_ALGAPI2 -+ tristate -+ -+ config CRYPTO_AEAD -+- tristate -++ tristate "AEAD" -+ select CRYPTO_AEAD2 -+ select CRYPTO_ALGAPI -+ -+@@ -53,7 +53,7 @@ config CRYPTO_AEAD2 -+ select CRYPTO_RNG2 -+ -+ config CRYPTO_BLKCIPHER -+- tristate -++ tristate "BLKCIPHER" -+ select CRYPTO_BLKCIPHER2 -+ select CRYPTO_ALGAPI -+ -+@@ -64,7 +64,7 @@ config CRYPTO_BLKCIPHER2 -+ select CRYPTO_WORKQUEUE -+ -+ config CRYPTO_HASH -+- tristate -++ tristate "HASH" -+ select CRYPTO_HASH2 -+ select CRYPTO_ALGAPI -+ -+@@ -73,7 +73,7 @@ config CRYPTO_HASH2 -+ select CRYPTO_ALGAPI2 -+ -+ config CRYPTO_RNG -+- tristate -++ tristate "RNG" -+ select CRYPTO_RNG2 -+ select CRYPTO_ALGAPI -+ -+--- a/drivers/bcma/Kconfig -++++ b/drivers/bcma/Kconfig -+@@ -15,6 +15,7 @@ menuconfig BCMA -+ config BCMA_BLOCKIO -+ bool -+ depends on BCMA -++ default y -+ -+ config BCMA_HOST_PCI_POSSIBLE -+ bool -+--- a/drivers/ssb/Kconfig -++++ b/drivers/ssb/Kconfig -+@@ -29,6 +29,7 @@ config SSB_SPROM -+ config SSB_BLOCKIO -+ bool -+ depends on SSB -++ default y -+ -+ config SSB_PCIHOST_POSSIBLE -+ bool -+@@ -49,7 +50,7 @@ config SSB_PCIHOST -+ config SSB_B43_PCI_BRIDGE -+ bool -+ depends on SSB_PCIHOST -+- default n -++ default y -+ -+ config SSB_PCMCIAHOST_POSSIBLE -+ bool -+--- a/lib/Kconfig -++++ b/lib/Kconfig -+@@ -358,16 +358,16 @@ config BCH_CONST_T -+ # Textsearch support is select'ed if needed -+ # -+ config TEXTSEARCH -+- bool -++ boolean "Textsearch support" -+ -+ config TEXTSEARCH_KMP -+- tristate -++ tristate "Textsearch KMP" -+ -+ config TEXTSEARCH_BM -+- tristate -++ tristate "Textsearch BM" -+ -+ config TEXTSEARCH_FSM -+- tristate -++ tristate "Textsearch FSM" -+ -+ config BTREE -+ bool -+--- a/net/netfilter/Kconfig -++++ b/net/netfilter/Kconfig -+@@ -10,7 +10,7 @@ config NETFILTER_INGRESS -+ infrastructure. -+ -+ config NETFILTER_NETLINK -+- tristate -++ tristate "Netfilter NFNETLINK interface" -+ -+ config NETFILTER_FAMILY_BRIDGE -+ bool -+--- a/net/wireless/Kconfig -++++ b/net/wireless/Kconfig -+@@ -1,5 +1,5 @@ -+ config WIRELESS_EXT -+- bool -++ bool "Wireless extensions" -+ -+ config WEXT_CORE -+ def_bool y -+@@ -11,10 +11,10 @@ config WEXT_PROC -+ depends on WEXT_CORE -+ -+ config WEXT_SPY -+- bool -++ bool "WEXT_SPY" -+ -+ config WEXT_PRIV -+- bool -++ bool "WEXT_PRIV" -+ -+ config CFG80211 -+ tristate "cfg80211 - wireless configuration API" -+@@ -188,7 +188,7 @@ config CFG80211_WEXT_EXPORT -+ wext compatibility symbols to be exported. -+ -+ config LIB80211 -+- tristate -++ tristate "LIB80211" -+ default n -+ help -+ This options enables a library of common routines used -+@@ -197,13 +197,16 @@ config LIB80211 -+ Drivers should select this themselves if needed. -+ -+ config LIB80211_CRYPT_WEP -+- tristate -++ tristate "LIB80211_CRYPT_WEP" -++ select LIB80211 -+ -+ config LIB80211_CRYPT_CCMP -+- tristate -++ tristate "LIB80211_CRYPT_CCMP" -++ select LIB80211 -+ -+ config LIB80211_CRYPT_TKIP -+- tristate -++ tristate "LIB80211_CRYPT_TKIP" -++ select LIB80211 -+ -+ config LIB80211_DEBUG -+ bool "lib80211 debugging messages" -+--- a/sound/core/Kconfig -++++ b/sound/core/Kconfig -+@@ -16,7 +16,7 @@ config SND_DMAENGINE_PCM -+ tristate -+ -+ config SND_HWDEP -+- tristate -++ tristate "Sound hardware support" -+ -+ config SND_SEQ_DEVICE -+ tristate -+@@ -26,7 +26,7 @@ config SND_RAWMIDI -+ select SND_SEQ_DEVICE if SND_SEQUENCER != n -+ -+ config SND_COMPRESS_OFFLOAD -+- tristate -++ tristate "Compression offloading support" -+ -+ config SND_JACK -+ bool -diff --git a/target/linux/generic/hack-4.14/259-regmap_dynamic.patch b/target/linux/generic/hack-4.14/259-regmap_dynamic.patch -new file mode 100644 -index 0000000000..2cbd791b28 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/259-regmap_dynamic.patch -@@ -0,0 +1,105 @@ -+From 811d9e2268a62b830cfe93cd8bc929afcb8b198b Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Sat, 15 Jul 2017 21:12:38 +0200 -+Subject: kernel: move regmap bloat out of the kernel image if it is only being used in modules -+ -+lede-commit: 96f39119815028073583e4fca3a9c5fe9141e998 -+Signed-off-by: Felix Fietkau -+--- -+ drivers/base/regmap/Kconfig | 15 ++++++++++----- -+ drivers/base/regmap/Makefile | 12 ++++++++---- -+ drivers/base/regmap/regmap.c | 3 +++ -+ include/linux/regmap.h | 2 +- -+ 4 files changed, 22 insertions(+), 10 deletions(-) -+ -+--- a/drivers/base/regmap/Kconfig -++++ b/drivers/base/regmap/Kconfig -+@@ -4,9 +4,8 @@ -+ # subsystems should select the appropriate symbols. -+ -+ config REGMAP -+- default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ) -+ select IRQ_DOMAIN if REGMAP_IRQ -+- bool -++ tristate -+ -+ config REGCACHE_COMPRESSED -+ select LZO_COMPRESS -+@@ -18,22 +17,29 @@ config REGMAP_AC97 -+ -+ config REGMAP_I2C -+ tristate -++ select REGMAP -+ depends on I2C -+ -+ config REGMAP_SPI -+ tristate -++ select REGMAP -++ depends on SPI_MASTER -+ depends on SPI -+ -+ config REGMAP_SPMI -++ select REGMAP -+ tristate -+ depends on SPMI -+ -+ config REGMAP_W1 -++ select REGMAP -+ tristate -+ depends on W1 -+ -+ config REGMAP_MMIO -+ tristate -++ select REGMAP -+ -+ config REGMAP_IRQ -++ select REGMAP -+ bool -+--- a/drivers/base/regmap/Makefile -++++ b/drivers/base/regmap/Makefile -+@@ -2,10 +2,14 @@ -+ # For include/trace/define_trace.h to include trace.h -+ CFLAGS_regmap.o := -I$(src) -+ -+-obj-$(CONFIG_REGMAP) += regmap.o regcache.o -+-obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-flat.o -+-obj-$(CONFIG_REGCACHE_COMPRESSED) += regcache-lzo.o -+-obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o -++regmap-core-objs = regmap.o regcache.o regcache-rbtree.o regcache-flat.o -++ifdef CONFIG_DEBUG_FS -++regmap-core-objs += regmap-debugfs.o -++endif -++ifdef CONFIG_REGCACHE_COMPRESSED -++regmap-core-objs += regcache-lzo.o -++endif -++obj-$(CONFIG_REGMAP) += regmap-core.o -+ obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o -+ obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o -+ obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o -+--- a/drivers/base/regmap/regmap.c -++++ b/drivers/base/regmap/regmap.c -+@@ -13,6 +13,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ #include -+@@ -2928,3 +2929,5 @@ static int __init regmap_initcall(void) -+ return 0; -+ } -+ postcore_initcall(regmap_initcall); -++ -++MODULE_LICENSE("GPL"); -+--- a/include/linux/regmap.h -++++ b/include/linux/regmap.h -+@@ -139,7 +139,7 @@ struct reg_sequence { -+ pollret ?: ((cond) ? 0 : -ETIMEDOUT); \ -+ }) -+ -+-#ifdef CONFIG_REGMAP -++#if IS_REACHABLE(CONFIG_REGMAP) -+ -+ enum regmap_endian { -+ /* Unspecified -> 0 -> Backwards compatible default */ -diff --git a/target/linux/generic/hack-4.14/260-crypto_test_dependencies.patch b/target/linux/generic/hack-4.14/260-crypto_test_dependencies.patch -new file mode 100644 -index 0000000000..3cdc0973ec ---- /dev/null -+++ b/target/linux/generic/hack-4.14/260-crypto_test_dependencies.patch -@@ -0,0 +1,60 @@ -+From fd1799b0bf5efa46dd3e6dfbbf3955564807e508 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Fri, 7 Jul 2017 17:12:51 +0200 -+Subject: kernel: prevent cryptomgr from pulling in useless extra dependencies for tests that are not run -+ -+Reduces kernel size after LZMA by about 5k on MIPS -+ -+lede-commit: 044c316167e076479a344c59905e5b435b84a77f -+Signed-off-by: Felix Fietkau -+--- -+ crypto/Kconfig | 13 ++++++------- -+ crypto/algboss.c | 4 ++++ -+ 2 files changed, 10 insertions(+), 7 deletions(-) -+ -+--- a/crypto/Kconfig -++++ b/crypto/Kconfig -+@@ -143,13 +143,13 @@ config CRYPTO_MANAGER -+ cbc(aes). -+ -+ config CRYPTO_MANAGER2 -+- def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y) -+- select CRYPTO_AEAD2 -+- select CRYPTO_HASH2 -+- select CRYPTO_BLKCIPHER2 -+- select CRYPTO_AKCIPHER2 -+- select CRYPTO_KPP2 -+- select CRYPTO_ACOMP2 -++ def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y && !CRYPTO_MANAGER_DISABLE_TESTS) -++ select CRYPTO_AEAD2 if !CRYPTO_MANAGER_DISABLE_TESTS -++ select CRYPTO_HASH2 if !CRYPTO_MANAGER_DISABLE_TESTS -++ select CRYPTO_BLKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS -++ select CRYPTO_AKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS -++ select CRYPTO_KPP2 if !CRYPTO_MANAGER_DISABLE_TESTS -++ select CRYPTO_ACOMP2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ -+ config CRYPTO_USER -+ tristate "Userspace cryptographic algorithm configuration" -+@@ -162,7 +162,6 @@ config CRYPTO_USER -+ config CRYPTO_MANAGER_DISABLE_TESTS -+ bool "Disable run-time self tests" -+ default y -+- depends on CRYPTO_MANAGER2 -+ help -+ Disable run-time self tests that normally take place at -+ algorithm registration. -+--- a/crypto/algboss.c -++++ b/crypto/algboss.c -+@@ -246,8 +246,12 @@ static int cryptomgr_schedule_test(struc -+ type = alg->cra_flags; -+ -+ /* Do not test internal algorithms. */ -++#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS -++ type |= CRYPTO_ALG_TESTED; -++#else -+ if (type & CRYPTO_ALG_INTERNAL) -+ type |= CRYPTO_ALG_TESTED; -++#endif -+ -+ param->type = type; -+ -diff --git a/target/linux/generic/hack-4.14/280-rfkill-stubs.patch b/target/linux/generic/hack-4.14/280-rfkill-stubs.patch -new file mode 100644 -index 0000000000..85d01a6d10 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/280-rfkill-stubs.patch -@@ -0,0 +1,84 @@ -+From 236c1acdfef5958010ac9814a9872e0a46fd78ee Mon Sep 17 00:00:00 2001 -+From: John Crispin -+Date: Fri, 7 Jul 2017 17:13:44 +0200 -+Subject: rfkill: add fake rfkill support -+ -+allow building of modules depending on RFKILL even if RFKILL is not enabled. -+ -+Signed-off-by: John Crispin -+--- -+ include/linux/rfkill.h | 2 +- -+ net/Makefile | 2 +- -+ net/rfkill/Kconfig | 14 +++++++++----- -+ net/rfkill/Makefile | 2 +- -+ 4 files changed, 12 insertions(+), 8 deletions(-) -+ -+--- a/include/linux/rfkill.h -++++ b/include/linux/rfkill.h -+@@ -64,7 +64,7 @@ struct rfkill_ops { -+ int (*set_block)(void *data, bool blocked); -+ }; -+ -+-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) -++#if defined(CONFIG_RFKILL_FULL) || defined(CONFIG_RFKILL_FULL_MODULE) -+ /** -+ * rfkill_alloc - allocate rfkill structure -+ * @name: name of the struct -- the string is not copied internally -+--- a/net/Makefile -++++ b/net/Makefile -+@@ -53,7 +53,7 @@ obj-$(CONFIG_TIPC) += tipc/ -+ obj-$(CONFIG_NETLABEL) += netlabel/ -+ obj-$(CONFIG_IUCV) += iucv/ -+ obj-$(CONFIG_SMC) += smc/ -+-obj-$(CONFIG_RFKILL) += rfkill/ -++obj-$(CONFIG_RFKILL_FULL) += rfkill/ -+ obj-$(CONFIG_NET_9P) += 9p/ -+ obj-$(CONFIG_CAIF) += caif/ -+ ifneq ($(CONFIG_DCB),) -+--- a/net/rfkill/Kconfig -++++ b/net/rfkill/Kconfig -+@@ -1,7 +1,11 @@ -+ # -+ # RF switch subsystem configuration -+ # -+-menuconfig RFKILL -++config RFKILL -++ bool -++ default y -++ -++menuconfig RFKILL_FULL -+ tristate "RF switch subsystem support" -+ help -+ Say Y here if you want to have control over RF switches -+@@ -13,19 +17,19 @@ menuconfig RFKILL -+ # LED trigger support -+ config RFKILL_LEDS -+ bool -+- depends on RFKILL -++ depends on RFKILL_FULL -+ depends on LEDS_TRIGGERS = y || RFKILL = LEDS_TRIGGERS -+ default y -+ -+ config RFKILL_INPUT -+ bool "RF switch input support" if EXPERT -+- depends on RFKILL -++ depends on RFKILL_FULL -+ depends on INPUT = y || RFKILL = INPUT -+ default y if !EXPERT -+ -+ config RFKILL_GPIO -+ tristate "GPIO RFKILL driver" -+- depends on RFKILL -++ depends on RFKILL_FULL -+ depends on GPIOLIB || COMPILE_TEST -+ default n -+ help -+--- a/net/rfkill/Makefile -++++ b/net/rfkill/Makefile -+@@ -4,5 +4,5 @@ -+ -+ rfkill-y += core.o -+ rfkill-$(CONFIG_RFKILL_INPUT) += input.o -+-obj-$(CONFIG_RFKILL) += rfkill.o -++obj-$(CONFIG_RFKILL_FULL) += rfkill.o -+ obj-$(CONFIG_RFKILL_GPIO) += rfkill-gpio.o -diff --git a/target/linux/generic/hack-4.14/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch b/target/linux/generic/hack-4.14/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch -new file mode 100644 -index 0000000000..c07ccf9474 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch -@@ -0,0 +1,66 @@ -+From: Ben Menchaca -+Date: Fri, 7 Jun 2013 18:35:22 -0500 -+Subject: MIPS: r4k_cache: use more efficient cache blast -+ -+Optimize the compiler output for larger cache blast cases that are -+common for DMA-based networking. -+ -+Signed-off-by: Ben Menchaca -+Signed-off-by: Felix Fietkau -+--- -+--- a/arch/mips/include/asm/r4kcache.h -++++ b/arch/mips/include/asm/r4kcache.h -+@@ -683,16 +683,48 @@ static inline void prot##extra##blast_## -+ unsigned long end) \ -+ { \ -+ unsigned long lsize = cpu_##desc##_line_size(); \ -++ unsigned long lsize_2 = lsize * 2; \ -++ unsigned long lsize_3 = lsize * 3; \ -++ unsigned long lsize_4 = lsize * 4; \ -++ unsigned long lsize_5 = lsize * 5; \ -++ unsigned long lsize_6 = lsize * 6; \ -++ unsigned long lsize_7 = lsize * 7; \ -++ unsigned long lsize_8 = lsize * 8; \ -+ unsigned long addr = start & ~(lsize - 1); \ -+- unsigned long aend = (end - 1) & ~(lsize - 1); \ -++ unsigned long aend = (end + lsize - 1) & ~(lsize - 1); \ -++ int lines = (aend - addr) / lsize; \ -+ \ -+ __##pfx##flush_prologue \ -+ \ -+- while (1) { \ -++ while (lines >= 8) { \ -++ prot##cache_op(hitop, addr); \ -++ prot##cache_op(hitop, addr + lsize); \ -++ prot##cache_op(hitop, addr + lsize_2); \ -++ prot##cache_op(hitop, addr + lsize_3); \ -++ prot##cache_op(hitop, addr + lsize_4); \ -++ prot##cache_op(hitop, addr + lsize_5); \ -++ prot##cache_op(hitop, addr + lsize_6); \ -++ prot##cache_op(hitop, addr + lsize_7); \ -++ addr += lsize_8; \ -++ lines -= 8; \ -++ } \ -++ \ -++ if (lines & 0x4) { \ -++ prot##cache_op(hitop, addr); \ -++ prot##cache_op(hitop, addr + lsize); \ -++ prot##cache_op(hitop, addr + lsize_2); \ -++ prot##cache_op(hitop, addr + lsize_3); \ -++ addr += lsize_4; \ -++ } \ -++ \ -++ if (lines & 0x2) { \ -++ prot##cache_op(hitop, addr); \ -++ prot##cache_op(hitop, addr + lsize); \ -++ addr += lsize_2; \ -++ } \ -++ \ -++ if (lines & 0x1) { \ -+ prot##cache_op(hitop, addr); \ -+- if (addr == aend) \ -+- break; \ -+- addr += lsize; \ -+ } \ -+ \ -+ __##pfx##flush_epilogue \ -diff --git a/target/linux/generic/hack-4.14/301-mips_image_cmdline_hack.patch b/target/linux/generic/hack-4.14/301-mips_image_cmdline_hack.patch -new file mode 100644 -index 0000000000..9bcd2a4401 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/301-mips_image_cmdline_hack.patch -@@ -0,0 +1,38 @@ -+From: John Crispin -+Subject: hack: kernel: add generic image_cmdline hack to MIPS targets -+ -+lede-commit: d59f5b3a987a48508257a0ddbaeadc7909f9f976 -+Signed-off-by: Gabor Juhos -+--- -+ arch/mips/Kconfig | 4 ++++ -+ arch/mips/kernel/head.S | 6 ++++++ -+ 2 files changed, 10 insertions(+) -+ -+--- a/arch/mips/Kconfig -++++ b/arch/mips/Kconfig -+@@ -1159,6 +1159,10 @@ config SYNC_R4K -+ config MIPS_MACHINE -+ def_bool n -+ -++config IMAGE_CMDLINE_HACK -++ bool "OpenWrt specific image command line hack" -++ default n -++ -+ config NO_IOPORT_MAP -+ def_bool n -+ -+--- a/arch/mips/kernel/head.S -++++ b/arch/mips/kernel/head.S -+@@ -79,6 +79,12 @@ FEXPORT(__kernel_entry) -+ j kernel_entry -+ #endif -+ -++#ifdef CONFIG_IMAGE_CMDLINE_HACK -++ .ascii "CMDLINE:" -++EXPORT(__image_cmdline) -++ .fill 0x400 -++#endif /* CONFIG_IMAGE_CMDLINE_HACK */ -++ -+ __REF -+ -+ NESTED(kernel_entry, 16, sp) # kernel entry point -diff --git a/target/linux/generic/hack-4.14/321-powerpc_crtsavres_prereq.patch b/target/linux/generic/hack-4.14/321-powerpc_crtsavres_prereq.patch -new file mode 100644 -index 0000000000..3f81b2e05f ---- /dev/null -+++ b/target/linux/generic/hack-4.14/321-powerpc_crtsavres_prereq.patch -@@ -0,0 +1,38 @@ -+From 107c0964cb8db7ca28ac5199426414fdab3c274d Mon Sep 17 00:00:00 2001 -+From: "Alexandros C. Couloumbis" -+Date: Fri, 7 Jul 2017 17:14:51 +0200 -+Subject: hack: arch: powerpc: drop register save/restore library from modules -+ -+Upstream GCC uses a libgcc function for saving/restoring registers. This -+makes the code bigger, and upstream kernels need to carry that function -+for every single kernel module. Our GCC is patched to avoid those -+references, so we can drop the extra bloat for modules. -+ -+lede-commit: e8e1084654f50904e6bf77b70b2de3f137d7b3ec -+Signed-off-by: Alexandros C. Couloumbis -+--- -+ arch/powerpc/Makefile | 1 - -+ 1 file changed, 1 deletion(-) -+ -+--- a/arch/powerpc/Makefile -++++ b/arch/powerpc/Makefile -+@@ -59,19 +59,6 @@ machine-$(CONFIG_PPC64) += 64 -+ machine-$(CONFIG_CPU_LITTLE_ENDIAN) += le -+ UTS_MACHINE := $(subst $(space),,$(machine-y)) -+ -+-# XXX This needs to be before we override LD below -+-ifdef CONFIG_PPC32 -+-KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o -+-else -+-ifeq ($(call ld-ifversion, -ge, 225000000, y),y) -+-# Have the linker provide sfpr if possible. -+-# There is a corresponding test in arch/powerpc/lib/Makefile -+-KBUILD_LDFLAGS_MODULE += --save-restore-funcs -+-else -+-KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o -+-endif -+-endif -+- -+ ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y) -+ override LD += -EL -+ LDEMULATION := lppc -diff --git a/target/linux/generic/hack-4.14/400-mt29f_spinand-fix-memleak.patch b/target/linux/generic/hack-4.14/400-mt29f_spinand-fix-memleak.patch -new file mode 100644 -index 0000000000..d479aba01a ---- /dev/null -+++ b/target/linux/generic/hack-4.14/400-mt29f_spinand-fix-memleak.patch -@@ -0,0 +1,90 @@ -+--- a/drivers/staging/mt29f_spinand/mt29f_spinand.c -++++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c -+@@ -492,7 +492,7 @@ static int spinand_program_page(struct s -+ #ifdef CONFIG_MTD_SPINAND_ONDIEECC -+ unsigned int i, j; -+ -+- wbuf = devm_kzalloc(&spi_nand->dev, CACHE_BUF, GFP_KERNEL); -++ wbuf = kzalloc(CACHE_BUF, GFP_KERNEL); -+ if (!wbuf) -+ return -ENOMEM; -+ -+@@ -500,7 +500,7 @@ static int spinand_program_page(struct s -+ retval = spinand_read_page(spi_nand, page_id, 0, CACHE_BUF, wbuf); -+ if (retval < 0) { -+ dev_err(&spi_nand->dev, "ecc error on read page!!!\n"); -+- return retval; -++ goto cleanup; -+ } -+ -+ for (i = offset, j = 0; i < len; i++, j++) -+@@ -510,7 +510,7 @@ static int spinand_program_page(struct s -+ retval = spinand_enable_ecc(spi_nand); -+ if (retval < 0) { -+ dev_err(&spi_nand->dev, "enable ecc failed!!\n"); -+- return retval; -++ goto cleanup; -+ } -+ } -+ #else -+@@ -519,7 +519,7 @@ static int spinand_program_page(struct s -+ retval = spinand_write_enable(spi_nand); -+ if (retval < 0) { -+ dev_err(&spi_nand->dev, "write enable failed!!\n"); -+- return retval; -++ goto cleanup; -+ } -+ if (wait_till_ready(spi_nand)) -+ dev_err(&spi_nand->dev, "wait timedout!!!\n"); -+@@ -527,23 +527,24 @@ static int spinand_program_page(struct s -+ retval = spinand_program_data_to_cache(spi_nand, page_id, -+ offset, len, wbuf); -+ if (retval < 0) -+- return retval; -++ goto cleanup; -+ retval = spinand_program_execute(spi_nand, page_id); -+ if (retval < 0) -+- return retval; -++ goto cleanup; -+ while (1) { -+ retval = spinand_read_status(spi_nand, &status); -+ if (retval < 0) { -+ dev_err(&spi_nand->dev, -+ "error %d reading status register\n", retval); -+- return retval; -++ goto cleanup; -+ } -+ -+ if ((status & STATUS_OIP_MASK) == STATUS_READY) { -+ if ((status & STATUS_P_FAIL_MASK) == STATUS_P_FAIL) { -+ dev_err(&spi_nand->dev, -+ "program error, page %d\n", page_id); -+- return -1; -++ retval = -1; -++ goto cleanup; -+ } -+ break; -+ } -+@@ -553,13 +554,20 @@ static int spinand_program_page(struct s -+ retval = spinand_disable_ecc(spi_nand); -+ if (retval < 0) { -+ dev_err(&spi_nand->dev, "disable ecc failed!!\n"); -+- return retval; -++ goto cleanup; -+ } -+ enable_hw_ecc = 0; -+ } -++ kfree(wbuf); -+ #endif -+- -+ return 0; -++ -++cleanup: -++#ifdef CONFIG_MTD_SPINAND_ONDIEECC -++ kfree(wbuf); -++#endif -++ return retval; -++ -+ } -+ -+ /** -diff --git a/target/linux/generic/hack-4.14/531-debloat_lzma.patch b/target/linux/generic/hack-4.14/531-debloat_lzma.patch -new file mode 100644 -index 0000000000..2e453cc2f2 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/531-debloat_lzma.patch -@@ -0,0 +1,1040 @@ -+From 3fd297761ac246c54d7723c57fca95c112b99465 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Sat, 15 Jul 2017 21:15:44 +0200 -+Subject: lzma: de-bloat the lzma library used by jffs2 -+ -+lede-commit: 3fd1dd08fbcbb78b34efefd32c3032e5c99108d6 -+Signed-off-by: Felix Fietkau -+--- -+ include/linux/lzma/LzFind.h | 17 --- -+ include/linux/lzma/LzmaDec.h | 101 --------------- -+ include/linux/lzma/LzmaEnc.h | 20 --- -+ lib/lzma/LzFind.c | 287 ++++--------------------------------------- -+ lib/lzma/LzmaDec.c | 86 +------------ -+ lib/lzma/LzmaEnc.c | 172 ++------------------------ -+ 6 files changed, 42 insertions(+), 641 deletions(-) -+ -+--- a/include/linux/lzma/LzFind.h -++++ b/include/linux/lzma/LzFind.h -+@@ -55,11 +55,6 @@ typedef struct _CMatchFinder -+ -+ #define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) -+ -+-int MatchFinder_NeedMove(CMatchFinder *p); -+-Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); -+-void MatchFinder_MoveBlock(CMatchFinder *p); -+-void MatchFinder_ReadIfRequired(CMatchFinder *p); -+- -+ void MatchFinder_Construct(CMatchFinder *p); -+ -+ /* Conditions: -+@@ -70,12 +65,6 @@ int MatchFinder_Create(CMatchFinder *p, -+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, -+ ISzAlloc *alloc); -+ void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); -+-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); -+-void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); -+- -+-UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, -+- UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, -+- UInt32 *distances, UInt32 maxLen); -+ -+ /* -+ Conditions: -+@@ -102,12 +91,6 @@ typedef struct _IMatchFinder -+ -+ void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); -+ -+-void MatchFinder_Init(CMatchFinder *p); -+-UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -+-UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -+-void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -+-void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -+- -+ #ifdef __cplusplus -+ } -+ #endif -+--- a/include/linux/lzma/LzmaDec.h -++++ b/include/linux/lzma/LzmaDec.h -+@@ -31,14 +31,6 @@ typedef struct _CLzmaProps -+ UInt32 dicSize; -+ } CLzmaProps; -+ -+-/* LzmaProps_Decode - decodes properties -+-Returns: -+- SZ_OK -+- SZ_ERROR_UNSUPPORTED - Unsupported properties -+-*/ -+- -+-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); -+- -+ -+ /* ---------- LZMA Decoder state ---------- */ -+ -+@@ -70,8 +62,6 @@ typedef struct -+ -+ #define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } -+ -+-void LzmaDec_Init(CLzmaDec *p); -+- -+ /* There are two types of LZMA streams: -+ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. -+ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ -+@@ -108,97 +98,6 @@ typedef enum -+ -+ /* ELzmaStatus is used only as output value for function call */ -+ -+- -+-/* ---------- Interfaces ---------- */ -+- -+-/* There are 3 levels of interfaces: -+- 1) Dictionary Interface -+- 2) Buffer Interface -+- 3) One Call Interface -+- You can select any of these interfaces, but don't mix functions from different -+- groups for same object. */ -+- -+- -+-/* There are two variants to allocate state for Dictionary Interface: -+- 1) LzmaDec_Allocate / LzmaDec_Free -+- 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs -+- You can use variant 2, if you set dictionary buffer manually. -+- For Buffer Interface you must always use variant 1. -+- -+-LzmaDec_Allocate* can return: -+- SZ_OK -+- SZ_ERROR_MEM - Memory allocation error -+- SZ_ERROR_UNSUPPORTED - Unsupported properties -+-*/ -+- -+-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); -+-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); -+- -+-SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); -+-void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); -+- -+-/* ---------- Dictionary Interface ---------- */ -+- -+-/* You can use it, if you want to eliminate the overhead for data copying from -+- dictionary to some other external buffer. -+- You must work with CLzmaDec variables directly in this interface. -+- -+- STEPS: -+- LzmaDec_Constr() -+- LzmaDec_Allocate() -+- for (each new stream) -+- { -+- LzmaDec_Init() -+- while (it needs more decompression) -+- { -+- LzmaDec_DecodeToDic() -+- use data from CLzmaDec::dic and update CLzmaDec::dicPos -+- } -+- } -+- LzmaDec_Free() -+-*/ -+- -+-/* LzmaDec_DecodeToDic -+- -+- The decoding to internal dictionary buffer (CLzmaDec::dic). -+- You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! -+- -+-finishMode: -+- It has meaning only if the decoding reaches output limit (dicLimit). -+- LZMA_FINISH_ANY - Decode just dicLimit bytes. -+- LZMA_FINISH_END - Stream must be finished after dicLimit. -+- -+-Returns: -+- SZ_OK -+- status: -+- LZMA_STATUS_FINISHED_WITH_MARK -+- LZMA_STATUS_NOT_FINISHED -+- LZMA_STATUS_NEEDS_MORE_INPUT -+- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK -+- SZ_ERROR_DATA - Data error -+-*/ -+- -+-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, -+- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); -+- -+- -+-/* ---------- Buffer Interface ---------- */ -+- -+-/* It's zlib-like interface. -+- See LzmaDec_DecodeToDic description for information about STEPS and return results, -+- but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need -+- to work with CLzmaDec variables manually. -+- -+-finishMode: -+- It has meaning only if the decoding reaches output limit (*destLen). -+- LZMA_FINISH_ANY - Decode just destLen bytes. -+- LZMA_FINISH_END - Stream must be finished after (*destLen). -+-*/ -+- -+-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, -+- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); -+- -+- -+ /* ---------- One Call Interface ---------- */ -+ -+ /* LzmaDecode -+--- a/include/linux/lzma/LzmaEnc.h -++++ b/include/linux/lzma/LzmaEnc.h -+@@ -31,9 +31,6 @@ typedef struct _CLzmaEncProps -+ } CLzmaEncProps; -+ -+ void LzmaEncProps_Init(CLzmaEncProps *p); -+-void LzmaEncProps_Normalize(CLzmaEncProps *p); -+-UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); -+- -+ -+ /* ---------- CLzmaEncHandle Interface ---------- */ -+ -+@@ -53,26 +50,9 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc * -+ void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); -+ SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); -+ SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); -+-SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, -+- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -+ SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -+ -+-/* ---------- One Call Interface ---------- */ -+- -+-/* LzmaEncode -+-Return code: -+- SZ_OK - OK -+- SZ_ERROR_MEM - Memory allocation error -+- SZ_ERROR_PARAM - Incorrect paramater -+- SZ_ERROR_OUTPUT_EOF - output buffer overflow -+- SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -+-*/ -+- -+-SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+- const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, -+- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -+- -+ #ifdef __cplusplus -+ } -+ #endif -+--- a/lib/lzma/LzFind.c -++++ b/lib/lzma/LzFind.c -+@@ -14,9 +14,15 @@ -+ -+ #define kStartMaxLen 3 -+ -++#if 0 -++#define DIRECT_INPUT p->directInput -++#else -++#define DIRECT_INPUT 1 -++#endif -++ -+ static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) -+ { -+- if (!p->directInput) -++ if (!DIRECT_INPUT) -+ { -+ alloc->Free(alloc, p->bufferBase); -+ p->bufferBase = 0; -+@@ -28,7 +34,7 @@ static void LzInWindow_Free(CMatchFinder -+ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) -+ { -+ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; -+- if (p->directInput) -++ if (DIRECT_INPUT) -+ { -+ p->blockSize = blockSize; -+ return 1; -+@@ -42,12 +48,12 @@ static int LzInWindow_Create(CMatchFinde -+ return (p->bufferBase != 0); -+ } -+ -+-Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } -+-Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } -++static Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } -++static Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } -+ -+-UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } -++static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } -+ -+-void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) -++static void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) -+ { -+ p->posLimit -= subValue; -+ p->pos -= subValue; -+@@ -58,7 +64,7 @@ static void MatchFinder_ReadBlock(CMatch -+ { -+ if (p->streamEndWasReached || p->result != SZ_OK) -+ return; -+- if (p->directInput) -++ if (DIRECT_INPUT) -+ { -+ UInt32 curSize = 0xFFFFFFFF - p->streamPos; -+ if (curSize > p->directInputRem) -+@@ -89,7 +95,7 @@ static void MatchFinder_ReadBlock(CMatch -+ } -+ } -+ -+-void MatchFinder_MoveBlock(CMatchFinder *p) -++static void MatchFinder_MoveBlock(CMatchFinder *p) -+ { -+ memmove(p->bufferBase, -+ p->buffer - p->keepSizeBefore, -+@@ -97,22 +103,14 @@ void MatchFinder_MoveBlock(CMatchFinder -+ p->buffer = p->bufferBase + p->keepSizeBefore; -+ } -+ -+-int MatchFinder_NeedMove(CMatchFinder *p) -++static int MatchFinder_NeedMove(CMatchFinder *p) -+ { -+- if (p->directInput) -++ if (DIRECT_INPUT) -+ return 0; -+ /* if (p->streamEndWasReached) return 0; */ -+ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); -+ } -+ -+-void MatchFinder_ReadIfRequired(CMatchFinder *p) -+-{ -+- if (p->streamEndWasReached) -+- return; -+- if (p->keepSizeAfter >= p->streamPos - p->pos) -+- MatchFinder_ReadBlock(p); -+-} -+- -+ static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) -+ { -+ if (MatchFinder_NeedMove(p)) -+@@ -268,7 +266,7 @@ static void MatchFinder_SetLimits(CMatch -+ p->posLimit = p->pos + limit; -+ } -+ -+-void MatchFinder_Init(CMatchFinder *p) -++static void MatchFinder_Init(CMatchFinder *p) -+ { -+ UInt32 i; -+ for (i = 0; i < p->hashSizeSum; i++) -+@@ -287,7 +285,7 @@ static UInt32 MatchFinder_GetSubValue(CM -+ return (p->pos - p->historySize - 1) & kNormalizeMask; -+ } -+ -+-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) -++static void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) -+ { -+ UInt32 i; -+ for (i = 0; i < numItems; i++) -+@@ -319,38 +317,7 @@ static void MatchFinder_CheckLimits(CMat -+ MatchFinder_SetLimits(p); -+ } -+ -+-static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+- UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, -+- UInt32 *distances, UInt32 maxLen) -+-{ -+- son[_cyclicBufferPos] = curMatch; -+- for (;;) -+- { -+- UInt32 delta = pos - curMatch; -+- if (cutValue-- == 0 || delta >= _cyclicBufferSize) -+- return distances; -+- { -+- const Byte *pb = cur - delta; -+- curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; -+- if (pb[maxLen] == cur[maxLen] && *pb == *cur) -+- { -+- UInt32 len = 0; -+- while (++len != lenLimit) -+- if (pb[len] != cur[len]) -+- break; -+- if (maxLen < len) -+- { -+- *distances++ = maxLen = len; -+- *distances++ = delta - 1; -+- if (len == lenLimit) -+- return distances; -+- } -+- } -+- } -+- } -+-} -+- -+-UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -++static UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, -+ UInt32 *distances, UInt32 maxLen) -+ { -+@@ -460,10 +427,10 @@ static void SkipMatchesSpec(UInt32 lenLi -+ p->buffer++; \ -+ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); -+ -+-#define MOVE_POS_RET MOVE_POS return offset; -+- -+ static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } -+ -++#define MOVE_POS_RET MatchFinder_MovePos(p); return offset; -++ -+ #define GET_MATCHES_HEADER2(minLen, ret_op) \ -+ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ -+ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ -+@@ -479,62 +446,7 @@ static void MatchFinder_MovePos(CMatchFi -+ distances + offset, maxLen) - distances); MOVE_POS_RET; -+ -+ #define SKIP_FOOTER \ -+- SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; -+- -+-static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+-{ -+- UInt32 offset; -+- GET_MATCHES_HEADER(2) -+- HASH2_CALC; -+- curMatch = p->hash[hashValue]; -+- p->hash[hashValue] = p->pos; -+- offset = 0; -+- GET_MATCHES_FOOTER(offset, 1) -+-} -+- -+-UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+-{ -+- UInt32 offset; -+- GET_MATCHES_HEADER(3) -+- HASH_ZIP_CALC; -+- curMatch = p->hash[hashValue]; -+- p->hash[hashValue] = p->pos; -+- offset = 0; -+- GET_MATCHES_FOOTER(offset, 2) -+-} -+- -+-static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+-{ -+- UInt32 hash2Value, delta2, maxLen, offset; -+- GET_MATCHES_HEADER(3) -+- -+- HASH3_CALC; -+- -+- delta2 = p->pos - p->hash[hash2Value]; -+- curMatch = p->hash[kFix3HashSize + hashValue]; -+- -+- p->hash[hash2Value] = -+- p->hash[kFix3HashSize + hashValue] = p->pos; -+- -+- -+- maxLen = 2; -+- offset = 0; -+- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -+- { -+- for (; maxLen != lenLimit; maxLen++) -+- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -+- break; -+- distances[0] = maxLen; -+- distances[1] = delta2 - 1; -+- offset = 2; -+- if (maxLen == lenLimit) -+- { -+- SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); -+- MOVE_POS_RET; -+- } -+- } -+- GET_MATCHES_FOOTER(offset, maxLen) -+-} -++ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MatchFinder_MovePos(p); -+ -+ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+ { -+@@ -583,108 +495,6 @@ static UInt32 Bt4_MatchFinder_GetMatches -+ GET_MATCHES_FOOTER(offset, maxLen) -+ } -+ -+-static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+-{ -+- UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; -+- GET_MATCHES_HEADER(4) -+- -+- HASH4_CALC; -+- -+- delta2 = p->pos - p->hash[ hash2Value]; -+- delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; -+- curMatch = p->hash[kFix4HashSize + hashValue]; -+- -+- p->hash[ hash2Value] = -+- p->hash[kFix3HashSize + hash3Value] = -+- p->hash[kFix4HashSize + hashValue] = p->pos; -+- -+- maxLen = 1; -+- offset = 0; -+- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -+- { -+- distances[0] = maxLen = 2; -+- distances[1] = delta2 - 1; -+- offset = 2; -+- } -+- if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) -+- { -+- maxLen = 3; -+- distances[offset + 1] = delta3 - 1; -+- offset += 2; -+- delta2 = delta3; -+- } -+- if (offset != 0) -+- { -+- for (; maxLen != lenLimit; maxLen++) -+- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -+- break; -+- distances[offset - 2] = maxLen; -+- if (maxLen == lenLimit) -+- { -+- p->son[p->cyclicBufferPos] = curMatch; -+- MOVE_POS_RET; -+- } -+- } -+- if (maxLen < 3) -+- maxLen = 3; -+- offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), -+- distances + offset, maxLen) - (distances)); -+- MOVE_POS_RET -+-} -+- -+-UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+-{ -+- UInt32 offset; -+- GET_MATCHES_HEADER(3) -+- HASH_ZIP_CALC; -+- curMatch = p->hash[hashValue]; -+- p->hash[hashValue] = p->pos; -+- offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), -+- distances, 2) - (distances)); -+- MOVE_POS_RET -+-} -+- -+-static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+-{ -+- do -+- { -+- SKIP_HEADER(2) -+- HASH2_CALC; -+- curMatch = p->hash[hashValue]; -+- p->hash[hashValue] = p->pos; -+- SKIP_FOOTER -+- } -+- while (--num != 0); -+-} -+- -+-void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+-{ -+- do -+- { -+- SKIP_HEADER(3) -+- HASH_ZIP_CALC; -+- curMatch = p->hash[hashValue]; -+- p->hash[hashValue] = p->pos; -+- SKIP_FOOTER -+- } -+- while (--num != 0); -+-} -+- -+-static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+-{ -+- do -+- { -+- UInt32 hash2Value; -+- SKIP_HEADER(3) -+- HASH3_CALC; -+- curMatch = p->hash[kFix3HashSize + hashValue]; -+- p->hash[hash2Value] = -+- p->hash[kFix3HashSize + hashValue] = p->pos; -+- SKIP_FOOTER -+- } -+- while (--num != 0); -+-} -+- -+ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+ { -+ do -+@@ -701,61 +511,12 @@ static void Bt4_MatchFinder_Skip(CMatchF -+ while (--num != 0); -+ } -+ -+-static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+-{ -+- do -+- { -+- UInt32 hash2Value, hash3Value; -+- SKIP_HEADER(4) -+- HASH4_CALC; -+- curMatch = p->hash[kFix4HashSize + hashValue]; -+- p->hash[ hash2Value] = -+- p->hash[kFix3HashSize + hash3Value] = -+- p->hash[kFix4HashSize + hashValue] = p->pos; -+- p->son[p->cyclicBufferPos] = curMatch; -+- MOVE_POS -+- } -+- while (--num != 0); -+-} -+- -+-void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+-{ -+- do -+- { -+- SKIP_HEADER(3) -+- HASH_ZIP_CALC; -+- curMatch = p->hash[hashValue]; -+- p->hash[hashValue] = p->pos; -+- p->son[p->cyclicBufferPos] = curMatch; -+- MOVE_POS -+- } -+- while (--num != 0); -+-} -+- -+ void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) -+ { -+ vTable->Init = (Mf_Init_Func)MatchFinder_Init; -+ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; -+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; -+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; -+- if (!p->btMode) -+- { -+- vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; -+- vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; -+- } -+- else if (p->numHashBytes == 2) -+- { -+- vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; -+- vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; -+- } -+- else if (p->numHashBytes == 3) -+- { -+- vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; -+- vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; -+- } -+- else -+- { -+- vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; -+- vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; -+- } -++ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; -++ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; -+ } -+--- a/lib/lzma/LzmaDec.c -++++ b/lib/lzma/LzmaDec.c -+@@ -682,7 +682,7 @@ static void LzmaDec_InitRc(CLzmaDec *p, -+ p->needFlush = 0; -+ } -+ -+-void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) -++static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) -+ { -+ p->needFlush = 1; -+ p->remainLen = 0; -+@@ -698,7 +698,7 @@ void LzmaDec_InitDicAndState(CLzmaDec *p -+ p->needInitState = 1; -+ } -+ -+-void LzmaDec_Init(CLzmaDec *p) -++static void LzmaDec_Init(CLzmaDec *p) -+ { -+ p->dicPos = 0; -+ LzmaDec_InitDicAndState(p, True, True); -+@@ -716,7 +716,7 @@ static void LzmaDec_InitStateReal(CLzmaD -+ p->needInitState = 0; -+ } -+ -+-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, -++static SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, -+ ELzmaFinishMode finishMode, ELzmaStatus *status) -+ { -+ SizeT inSize = *srcLen; -+@@ -837,65 +837,13 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, Si -+ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; -+ } -+ -+-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) -+-{ -+- SizeT outSize = *destLen; -+- SizeT inSize = *srcLen; -+- *srcLen = *destLen = 0; -+- for (;;) -+- { -+- SizeT inSizeCur = inSize, outSizeCur, dicPos; -+- ELzmaFinishMode curFinishMode; -+- SRes res; -+- if (p->dicPos == p->dicBufSize) -+- p->dicPos = 0; -+- dicPos = p->dicPos; -+- if (outSize > p->dicBufSize - dicPos) -+- { -+- outSizeCur = p->dicBufSize; -+- curFinishMode = LZMA_FINISH_ANY; -+- } -+- else -+- { -+- outSizeCur = dicPos + outSize; -+- curFinishMode = finishMode; -+- } -+- -+- res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); -+- src += inSizeCur; -+- inSize -= inSizeCur; -+- *srcLen += inSizeCur; -+- outSizeCur = p->dicPos - dicPos; -+- memcpy(dest, p->dic + dicPos, outSizeCur); -+- dest += outSizeCur; -+- outSize -= outSizeCur; -+- *destLen += outSizeCur; -+- if (res != 0) -+- return res; -+- if (outSizeCur == 0 || outSize == 0) -+- return SZ_OK; -+- } -+-} -+- -+-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) -++static void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) -+ { -+ alloc->Free(alloc, p->probs); -+ p->probs = 0; -+ } -+ -+-static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) -+-{ -+- alloc->Free(alloc, p->dic); -+- p->dic = 0; -+-} -+- -+-void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) -+-{ -+- LzmaDec_FreeProbs(p, alloc); -+- LzmaDec_FreeDict(p, alloc); -+-} -+- -+-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) -++static SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) -+ { -+ UInt32 dicSize; -+ Byte d; -+@@ -935,7 +883,7 @@ static SRes LzmaDec_AllocateProbs2(CLzma -+ return SZ_OK; -+ } -+ -+-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -++static SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -+ { -+ CLzmaProps propNew; -+ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -+@@ -943,28 +891,6 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p, -+ p->prop = propNew; -+ return SZ_OK; -+ } -+- -+-SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -+-{ -+- CLzmaProps propNew; -+- SizeT dicBufSize; -+- RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -+- RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); -+- dicBufSize = propNew.dicSize; -+- if (p->dic == 0 || dicBufSize != p->dicBufSize) -+- { -+- LzmaDec_FreeDict(p, alloc); -+- p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); -+- if (p->dic == 0) -+- { -+- LzmaDec_FreeProbs(p, alloc); -+- return SZ_ERROR_MEM; -+- } -+- } -+- p->dicBufSize = dicBufSize; -+- p->prop = propNew; -+- return SZ_OK; -+-} -+ -+ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, -+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, -+--- a/lib/lzma/LzmaEnc.c -++++ b/lib/lzma/LzmaEnc.c -+@@ -53,7 +53,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p) -+ p->writeEndMark = 0; -+ } -+ -+-void LzmaEncProps_Normalize(CLzmaEncProps *p) -++static void LzmaEncProps_Normalize(CLzmaEncProps *p) -+ { -+ int level = p->level; -+ if (level < 0) level = 5; -+@@ -76,7 +76,7 @@ void LzmaEncProps_Normalize(CLzmaEncProp -+ #endif -+ } -+ -+-UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) -++static UInt32 __maybe_unused LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) -+ { -+ CLzmaEncProps props = *props2; -+ LzmaEncProps_Normalize(&props); -+@@ -93,7 +93,7 @@ UInt32 LzmaEncProps_GetDictSize(const CL -+ -+ #define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } -+ -+-UInt32 GetPosSlot1(UInt32 pos) -++static UInt32 GetPosSlot1(UInt32 pos) -+ { -+ UInt32 res; -+ BSR2_RET(pos, res); -+@@ -107,7 +107,7 @@ UInt32 GetPosSlot1(UInt32 pos) -+ #define kNumLogBits (9 + (int)sizeof(size_t) / 2) -+ #define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) -+ -+-void LzmaEnc_FastPosInit(Byte *g_FastPos) -++static void LzmaEnc_FastPosInit(Byte *g_FastPos) -+ { -+ int c = 2, slotFast; -+ g_FastPos[0] = 0; -+@@ -339,58 +339,6 @@ typedef struct -+ CSaveState saveState; -+ } CLzmaEnc; -+ -+-void LzmaEnc_SaveState(CLzmaEncHandle pp) -+-{ -+- CLzmaEnc *p = (CLzmaEnc *)pp; -+- CSaveState *dest = &p->saveState; -+- int i; -+- dest->lenEnc = p->lenEnc; -+- dest->repLenEnc = p->repLenEnc; -+- dest->state = p->state; -+- -+- for (i = 0; i < kNumStates; i++) -+- { -+- memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); -+- memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); -+- } -+- for (i = 0; i < kNumLenToPosStates; i++) -+- memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); -+- memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); -+- memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); -+- memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); -+- memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); -+- memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); -+- memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); -+- memcpy(dest->reps, p->reps, sizeof(p->reps)); -+- memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); -+-} -+- -+-void LzmaEnc_RestoreState(CLzmaEncHandle pp) -+-{ -+- CLzmaEnc *dest = (CLzmaEnc *)pp; -+- const CSaveState *p = &dest->saveState; -+- int i; -+- dest->lenEnc = p->lenEnc; -+- dest->repLenEnc = p->repLenEnc; -+- dest->state = p->state; -+- -+- for (i = 0; i < kNumStates; i++) -+- { -+- memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); -+- memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); -+- } -+- for (i = 0; i < kNumLenToPosStates; i++) -+- memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); -+- memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); -+- memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); -+- memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); -+- memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); -+- memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); -+- memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); -+- memcpy(dest->reps, p->reps, sizeof(p->reps)); -+- memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); -+-} -+- -+ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) -+ { -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+@@ -600,7 +548,7 @@ static void LitEnc_EncodeMatched(CRangeE -+ while (symbol < 0x10000); -+ } -+ -+-void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) -++static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) -+ { -+ UInt32 i; -+ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) -+@@ -1676,7 +1624,7 @@ static void FillDistancesPrices(CLzmaEnc -+ p->matchPriceCount = 0; -+ } -+ -+-void LzmaEnc_Construct(CLzmaEnc *p) -++static void LzmaEnc_Construct(CLzmaEnc *p) -+ { -+ RangeEnc_Construct(&p->rc); -+ MatchFinder_Construct(&p->matchFinderBase); -+@@ -1709,7 +1657,7 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc * -+ return p; -+ } -+ -+-void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) -++static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) -+ { -+ alloc->Free(alloc, p->litProbs); -+ alloc->Free(alloc, p->saveState.litProbs); -+@@ -1717,7 +1665,7 @@ void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAl -+ p->saveState.litProbs = 0; -+ } -+ -+-void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) -++static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) -+ { -+ #ifndef _7ZIP_ST -+ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); -+@@ -1947,7 +1895,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, U -+ return SZ_OK; -+ } -+ -+-void LzmaEnc_Init(CLzmaEnc *p) -++static void LzmaEnc_Init(CLzmaEnc *p) -+ { -+ UInt32 i; -+ p->state = 0; -+@@ -2005,7 +1953,7 @@ void LzmaEnc_Init(CLzmaEnc *p) -+ p->lpMask = (1 << p->lp) - 1; -+ } -+ -+-void LzmaEnc_InitPrices(CLzmaEnc *p) -++static void LzmaEnc_InitPrices(CLzmaEnc *p) -+ { -+ if (!p->fastMode) -+ { -+@@ -2037,26 +1985,6 @@ static SRes LzmaEnc_AllocAndInit(CLzmaEn -+ return SZ_OK; -+ } -+ -+-static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, -+- ISzAlloc *alloc, ISzAlloc *allocBig) -+-{ -+- CLzmaEnc *p = (CLzmaEnc *)pp; -+- p->matchFinderBase.stream = inStream; -+- p->needInit = 1; -+- p->rc.outStream = outStream; -+- return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); -+-} -+- -+-SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, -+- ISeqInStream *inStream, UInt32 keepWindowSize, -+- ISzAlloc *alloc, ISzAlloc *allocBig) -+-{ -+- CLzmaEnc *p = (CLzmaEnc *)pp; -+- p->matchFinderBase.stream = inStream; -+- p->needInit = 1; -+- return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -+-} -+- -+ static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) -+ { -+ p->matchFinderBase.directInput = 1; -+@@ -2064,7 +1992,7 @@ static void LzmaEnc_SetInputBuf(CLzmaEnc -+ p->matchFinderBase.directInputRem = srcLen; -+ } -+ -+-SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, -++static SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, -+ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -+ { -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+@@ -2074,7 +2002,7 @@ SRes LzmaEnc_MemPrepare(CLzmaEncHandle p -+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -+ } -+ -+-void LzmaEnc_Finish(CLzmaEncHandle pp) -++static void LzmaEnc_Finish(CLzmaEncHandle pp) -+ { -+ #ifndef _7ZIP_ST -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+@@ -2107,53 +2035,6 @@ static size_t MyWrite(void *pp, const vo -+ return size; -+ } -+ -+- -+-UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) -+-{ -+- const CLzmaEnc *p = (CLzmaEnc *)pp; -+- return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); -+-} -+- -+-const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) -+-{ -+- const CLzmaEnc *p = (CLzmaEnc *)pp; -+- return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; -+-} -+- -+-SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, -+- Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) -+-{ -+- CLzmaEnc *p = (CLzmaEnc *)pp; -+- UInt64 nowPos64; -+- SRes res; -+- CSeqOutStreamBuf outStream; -+- -+- outStream.funcTable.Write = MyWrite; -+- outStream.data = dest; -+- outStream.rem = *destLen; -+- outStream.overflow = False; -+- -+- p->writeEndMark = False; -+- p->finished = False; -+- p->result = SZ_OK; -+- -+- if (reInit) -+- LzmaEnc_Init(p); -+- LzmaEnc_InitPrices(p); -+- nowPos64 = p->nowPos64; -+- RangeEnc_Init(&p->rc); -+- p->rc.outStream = &outStream.funcTable; -+- -+- res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); -+- -+- *unpackSize = (UInt32)(p->nowPos64 - nowPos64); -+- *destLen -= outStream.rem; -+- if (outStream.overflow) -+- return SZ_ERROR_OUTPUT_EOF; -+- -+- return res; -+-} -+- -+ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) -+ { -+ SRes res = SZ_OK; -+@@ -2184,13 +2065,6 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, -+ return res; -+ } -+ -+-SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, -+- ISzAlloc *alloc, ISzAlloc *allocBig) -+-{ -+- RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); -+- return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); -+-} -+- -+ SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) -+ { -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+@@ -2247,25 +2121,3 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp -+ return SZ_ERROR_OUTPUT_EOF; -+ return res; -+ } -+- -+-SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+- const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, -+- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) -+-{ -+- CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); -+- SRes res; -+- if (p == 0) -+- return SZ_ERROR_MEM; -+- -+- res = LzmaEnc_SetProps(p, props); -+- if (res == SZ_OK) -+- { -+- res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); -+- if (res == SZ_OK) -+- res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, -+- writeEndMark, progress, alloc, allocBig); -+- } -+- -+- LzmaEnc_Destroy(p, alloc, allocBig); -+- return res; -+-} -diff --git a/target/linux/generic/hack-4.14/640-bridge-only-accept-EAP-locally.patch b/target/linux/generic/hack-4.14/640-bridge-only-accept-EAP-locally.patch -new file mode 100644 -index 0000000000..fbe9ab0876 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/640-bridge-only-accept-EAP-locally.patch -@@ -0,0 +1,82 @@ -+From: Felix Fietkau -+Date: Fri, 7 Jul 2017 17:18:54 +0200 -+Subject: bridge: only accept EAP locally -+ -+When bridging, do not forward EAP frames to other ports, only deliver -+them locally, regardless of the state. -+ -+Signed-off-by: Felix Fietkau -+[add disable_eap_hack sysfs attribute] -+Signed-off-by: Etienne Champetier -+--- -+ -+--- a/net/bridge/br_input.c -++++ b/net/bridge/br_input.c -+@@ -166,10 +166,14 @@ int br_handle_frame_finish(struct net *n -+ } -+ } -+ -++ BR_INPUT_SKB_CB(skb)->brdev = br->dev; -++ -++ if (skb->protocol == htons(ETH_P_PAE) && !br->disable_eap_hack) -++ return br_pass_frame_up(skb); -++ -+ if (p->state == BR_STATE_LEARNING) -+ goto drop; -+ -+- BR_INPUT_SKB_CB(skb)->brdev = br->dev; -+ BR_INPUT_SKB_CB(skb)->src_port_isolated = !!(p->flags & BR_ISOLATED); -+ -+ if (IS_ENABLED(CONFIG_INET) && skb->protocol == htons(ETH_P_ARP)) -+--- a/net/bridge/br_private.h -++++ b/net/bridge/br_private.h -+@@ -320,6 +320,8 @@ struct net_bridge { -+ u16 group_fwd_mask; -+ u16 group_fwd_mask_required; -+ -++ bool disable_eap_hack; -++ -+ /* STP */ -+ bridge_id designated_root; -+ bridge_id bridge_id; -+--- a/net/bridge/br_sysfs_br.c -++++ b/net/bridge/br_sysfs_br.c -+@@ -170,6 +170,30 @@ static ssize_t group_fwd_mask_store(stru -+ } -+ static DEVICE_ATTR_RW(group_fwd_mask); -+ -++static ssize_t disable_eap_hack_show(struct device *d, -++ struct device_attribute *attr, -++ char *buf) -++{ -++ struct net_bridge *br = to_bridge(d); -++ return sprintf(buf, "%u\n", br->disable_eap_hack); -++} -++ -++static int set_disable_eap_hack(struct net_bridge *br, unsigned long val) -++{ -++ br->disable_eap_hack = !!val; -++ -++ return 0; -++} -++ -++static ssize_t disable_eap_hack_store(struct device *d, -++ struct device_attribute *attr, -++ const char *buf, -++ size_t len) -++{ -++ return store_bridge_parm(d, buf, len, set_disable_eap_hack); -++} -++static DEVICE_ATTR_RW(disable_eap_hack); -++ -+ static ssize_t priority_show(struct device *d, struct device_attribute *attr, -+ char *buf) -+ { -+@@ -817,6 +841,7 @@ static struct attribute *bridge_attrs[] -+ &dev_attr_ageing_time.attr, -+ &dev_attr_stp_state.attr, -+ &dev_attr_group_fwd_mask.attr, -++ &dev_attr_disable_eap_hack.attr, -+ &dev_attr_priority.attr, -+ &dev_attr_bridge_id.attr, -+ &dev_attr_root_id.attr, -diff --git a/target/linux/generic/hack-4.14/645-netfilter-connmark-introduce-set-dscpmark.patch b/target/linux/generic/hack-4.14/645-netfilter-connmark-introduce-set-dscpmark.patch -new file mode 100644 -index 0000000000..1ecc95bf22 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/645-netfilter-connmark-introduce-set-dscpmark.patch -@@ -0,0 +1,124 @@ -+From f1627abea333781d3e2a61bac4c7fd4502395741 Mon Sep 17 00:00:00 2001 -+From: Kevin Darbyshire-Bryant -+Date: Sat, 23 Mar 2019 09:29:49 +0000 -+Subject: [PATCH] netfilter: connmark: introduce set-dscpmark -+ -+set-dscpmark is a method of storing the DSCP of an ip packet into -+conntrack mark. In combination with a suitable tc filter action -+(act_ctinfo) DSCP values are able to be stored in the mark on egress and -+restored on ingress across links that otherwise alter or bleach DSCP. -+ -+This is useful for qdiscs such as CAKE which are able to shape according -+to policies based on DSCP. -+ -+Ingress classification is traditionally a challenging task since -+iptables rules haven't yet run and tc filter/eBPF programs are pre-NAT -+lookups, hence are unable to see internal IPv4 addresses as used on the -+typical home masquerading gateway. -+ -+x_tables CONNMARK set-dscpmark target solves the problem of storing the -+DSCP to the conntrack mark in a way suitable for the new act_ctinfo tc -+action to restore. -+ -+The set-dscpmark option accepts 2 parameters, a 32bit 'dscpmask' and a -+32bit 'statemask'. The dscp mask must be 6 contiguous bits and -+represents the area where the DSCP will be stored in the connmark. The -+state mask is a minimum 1 bit length mask that must not overlap with the -+dscpmask. It represents a flag which is set when the DSCP has been -+stored in the conntrack mark. This is useful to implement a 'one shot' -+iptables based classification where the 'complicated' iptables rules are -+only run once to classify the connection on initial (egress) packet and -+subsequent packets are all marked/restored with the same DSCP. A state -+mask of zero disables the setting of a status bit/s. -+ -+example syntax with a suitably modified iptables user space application: -+ -+iptables -A QOS_MARK_eth0 -t mangle -j CONNMARK --set-dscpmark 0xfc000000/0x01000000 -+ -+Would store the DSCP in the top 6 bits of the 32bit mark field, and use -+the LSB of the top byte as the 'DSCP has been stored' marker. -+ -+|----0xFC----conntrack mark----000000---| -+| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0| -+| DSCP | unused | flag |unused | -+|-----------------------0x01---000000---| -+ ^ ^ -+ | | -+ ---| Conditional flag -+ | set this when dscp -+|-ip diffserv-| stored in mark -+| 6 bits | -+|-------------| -+ -+an identically configured tc action to restore looks like: -+ -+tc filter show dev eth0 ingress -+filter parent ffff: protocol all pref 10 u32 chain 0 -+filter parent ffff: protocol all pref 10 u32 chain 0 fh 800: ht divisor 1 -+filter parent ffff: protocol all pref 10 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1: not_in_hw -+ match 00000000/00000000 at 0 -+ action order 1: ctinfo zone 0 pipe -+ index 2 ref 1 bind 1 dscp 0xfc000000/0x1000000 -+ -+ action order 2: mirred (Egress Redirect to device ifb4eth0) stolen -+ index 1 ref 1 bind 1 -+ -+|----0xFC----conntrack mark----000000---| -+| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0| -+| DSCP | unused | flag |unused | -+|-----------------------0x01---000000---| -+ | | -+ | | -+ ---| Conditional flag -+ v only restore if set -+|-ip diffserv-| -+| 6 bits | -+|-------------| -+ -+Signed-off-by: Kevin Darbyshire-Bryant -+--- -+ net/netfilter/xt_connmark.c | 19 +++++++++++++++++-- -+ 1 file changed, 17 insertions(+), 2 deletions(-) -+ -+--- a/net/netfilter/xt_connmark.c -++++ b/net/netfilter/xt_connmark.c -+@@ -42,6 +42,7 @@ connmark_tg(struct sk_buff *skb, const s -+ enum ip_conntrack_info ctinfo; -+ struct nf_conn *ct; -+ u_int32_t newmark; -++ u_int8_t dscp, maskshift; -+ -+ ct = nf_ct_get(skb, &ctinfo); -+ if (ct == NULL) -+@@ -49,7 +50,21 @@ connmark_tg(struct sk_buff *skb, const s -+ -+ switch (info->mode) { -+ case XT_CONNMARK_SET: -+- newmark = (ct->mark & ~info->ctmask) ^ info->ctmark; -++ if (info->nfmask & 0x80000000) { -++ newmark = (ct->mark & ~info->ctmask) ^ info->ctmark; -++ } else { -++ if (skb->protocol == htons(ETH_P_IP)) -++ dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2; -++ else if (skb->protocol == htons(ETH_P_IPV6)) -++ dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2; -++ else /* protocol doesn't have diffserv */ -++ break; -++ -++ /* nfmask contains the mask shift value */ -++ maskshift = info->nfmask & 0x1f; -++ newmark = (ct->mark & ~info->ctmark) | -++ (info->ctmask | (dscp << maskshift)); -++ } -+ if (ct->mark != newmark) { -+ ct->mark = newmark; -+ nf_conntrack_event_cache(IPCT_MARK, ct); -+@@ -57,7 +72,7 @@ connmark_tg(struct sk_buff *skb, const s -+ break; -+ case XT_CONNMARK_SAVE: -+ newmark = (ct->mark & ~info->ctmask) ^ -+- (skb->mark & info->nfmask); -++ (skb->mark & info->nfmask); -+ if (ct->mark != newmark) { -+ ct->mark = newmark; -+ nf_conntrack_event_cache(IPCT_MARK, ct); -diff --git a/target/linux/generic/hack-4.14/647-netfilter-flow-acct.patch b/target/linux/generic/hack-4.14/647-netfilter-flow-acct.patch -new file mode 100644 -index 0000000000..f58b8bc716 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/647-netfilter-flow-acct.patch -@@ -0,0 +1,70 @@ -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -163,6 +163,8 @@ struct nf_flow_table_hw { -+ int nf_flow_table_hw_register(const struct nf_flow_table_hw *offload); -+ void nf_flow_table_hw_unregister(const struct nf_flow_table_hw *offload); -+ -++void nf_flow_table_acct(struct flow_offload *flow, struct sk_buff *skb, int dir); -++ -+ extern struct work_struct nf_flow_offload_hw_work; -+ -+ #define MODULE_ALIAS_NF_FLOWTABLE(family) \ -+--- a/net/netfilter/nf_flow_table_core.c -++++ b/net/netfilter/nf_flow_table_core.c -+@@ -11,6 +11,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ struct flow_offload_entry { -+ struct flow_offload flow; -+@@ -152,6 +153,22 @@ void flow_offload_free(struct flow_offlo -+ } -+ EXPORT_SYMBOL_GPL(flow_offload_free); -+ -++void nf_flow_table_acct(struct flow_offload *flow, struct sk_buff *skb, int dir) -++{ -++ struct flow_offload_entry *entry; -++ struct nf_conn_acct *acct; -++ -++ entry = container_of(flow, struct flow_offload_entry, flow); -++ acct = nf_conn_acct_find(entry->ct); -++ if (acct) { -++ struct nf_conn_counter *counter = acct->counter; -++ -++ atomic64_inc(&counter[dir].packets); -++ atomic64_add(skb->len, &counter[dir].bytes); -++ } -++} -++EXPORT_SYMBOL_GPL(nf_flow_table_acct); -++ -+ static u32 flow_offload_hash(const void *data, u32 len, u32 seed) -+ { -+ const struct flow_offload_tuple *tuple = data; -+--- a/net/netfilter/nf_flow_table_ip.c -++++ b/net/netfilter/nf_flow_table_ip.c -+@@ -11,6 +11,7 @@ -+ #include -+ #include -+ #include -++ -+ /* For layer 4 checksum field offset. */ -+ #include -+ #include -+@@ -265,6 +266,7 @@ nf_flow_offload_ip_hook(void *priv, stru -+ skb->dev = outdev; -+ nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr); -+ skb_dst_set_noref(skb, &rt->dst); -++ nf_flow_table_acct(flow, skb, dir); -+ neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb); -+ -+ return NF_STOLEN; -+@@ -482,6 +484,7 @@ nf_flow_offload_ipv6_hook(void *priv, st -+ skb->dev = outdev; -+ nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6); -+ skb_dst_set_noref(skb, &rt->dst); -++ nf_flow_table_acct(flow, skb, dir); -+ neigh_xmit(NEIGH_ND_TABLE, outdev, nexthop, skb); -+ -+ return NF_STOLEN; -diff --git a/target/linux/generic/hack-4.14/650-netfilter-add-xt_OFFLOAD-target.patch b/target/linux/generic/hack-4.14/650-netfilter-add-xt_OFFLOAD-target.patch -new file mode 100644 -index 0000000000..7c93feccdc ---- /dev/null -+++ b/target/linux/generic/hack-4.14/650-netfilter-add-xt_OFFLOAD-target.patch -@@ -0,0 +1,553 @@ -+From: Felix Fietkau -+Date: Tue, 20 Feb 2018 15:56:02 +0100 -+Subject: [PATCH] netfilter: add xt_OFFLOAD target -+ -+Signed-off-by: Felix Fietkau -+--- -+ create mode 100644 net/netfilter/xt_OFFLOAD.c -+ -+--- a/net/ipv4/netfilter/Kconfig -++++ b/net/ipv4/netfilter/Kconfig -+@@ -76,8 +76,6 @@ config NF_TABLES_ARP -+ help -+ This option enables the ARP support for nf_tables. -+ -+-endif # NF_TABLES -+- -+ config NF_FLOW_TABLE_IPV4 -+ tristate "Netfilter flow table IPv4 module" -+ depends on NF_FLOW_TABLE -+@@ -86,6 +84,8 @@ config NF_FLOW_TABLE_IPV4 -+ -+ To compile it as a module, choose M here. -+ -++endif # NF_TABLES -++ -+ config NF_DUP_IPV4 -+ tristate "Netfilter IPv4 packet duplication to alternate destination" -+ depends on !NF_CONNTRACK || NF_CONNTRACK -+--- a/net/ipv6/netfilter/Kconfig -++++ b/net/ipv6/netfilter/Kconfig -+@@ -97,7 +97,6 @@ config NFT_FIB_IPV6 -+ multicast or blackhole. -+ -+ endif # NF_TABLES_IPV6 -+-endif # NF_TABLES -+ -+ config NF_FLOW_TABLE_IPV6 -+ tristate "Netfilter flow table IPv6 module" -+@@ -107,6 +106,8 @@ config NF_FLOW_TABLE_IPV6 -+ -+ To compile it as a module, choose M here. -+ -++endif # NF_TABLES -++ -+ config NF_DUP_IPV6 -+ tristate "Netfilter IPv6 packet duplication to alternate destination" -+ depends on !NF_CONNTRACK || NF_CONNTRACK -+--- a/net/netfilter/Kconfig -++++ b/net/netfilter/Kconfig -+@@ -671,8 +671,6 @@ config NFT_FIB_NETDEV -+ -+ endif # NF_TABLES_NETDEV -+ -+-endif # NF_TABLES -+- -+ config NF_FLOW_TABLE_INET -+ tristate "Netfilter flow table mixed IPv4/IPv6 module" -+ depends on NF_FLOW_TABLE -+@@ -681,11 +679,12 @@ config NF_FLOW_TABLE_INET -+ -+ To compile it as a module, choose M here. -+ -++endif # NF_TABLES -++ -+ config NF_FLOW_TABLE -+ tristate "Netfilter flow table module" -+ depends on NETFILTER_INGRESS -+ depends on NF_CONNTRACK -+- depends on NF_TABLES -+ help -+ This option adds the flow table core infrastructure. -+ -+@@ -974,6 +973,15 @@ config NETFILTER_XT_TARGET_NOTRACK -+ depends on NETFILTER_ADVANCED -+ select NETFILTER_XT_TARGET_CT -+ -++config NETFILTER_XT_TARGET_FLOWOFFLOAD -++ tristate '"FLOWOFFLOAD" target support' -++ depends on NF_FLOW_TABLE -++ depends on NETFILTER_INGRESS -++ help -++ This option adds a `FLOWOFFLOAD' target, which uses the nf_flow_offload -++ module to speed up processing of packets by bypassing the usual -++ netfilter chains -++ -+ config NETFILTER_XT_TARGET_RATEEST -+ tristate '"RATEEST" target support' -+ depends on NETFILTER_ADVANCED -+--- a/net/netfilter/Makefile -++++ b/net/netfilter/Makefile -+@@ -134,6 +134,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF -+ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o -+ obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o -+ obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o -++obj-$(CONFIG_NETFILTER_XT_TARGET_FLOWOFFLOAD) += xt_FLOWOFFLOAD.o -+ obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o -+ obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_HMARK.o -+ obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o -+--- /dev/null -++++ b/net/netfilter/xt_FLOWOFFLOAD.c -+@@ -0,0 +1,422 @@ -++/* -++ * Copyright (C) 2018 Felix Fietkau -++ * -++ * This program is free software; you can redistribute it and/or modify -++ * it under the terms of the GNU General Public License version 2 as -++ * published by the Free Software Foundation. -++ */ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++static struct nf_flowtable nf_flowtable; -++static HLIST_HEAD(hooks); -++static DEFINE_SPINLOCK(hooks_lock); -++static struct delayed_work hook_work; -++ -++struct xt_flowoffload_hook { -++ struct hlist_node list; -++ struct nf_hook_ops ops; -++ struct net *net; -++ bool registered; -++ bool used; -++}; -++ -++static unsigned int -++xt_flowoffload_net_hook(void *priv, struct sk_buff *skb, -++ const struct nf_hook_state *state) -++{ -++ switch (skb->protocol) { -++ case htons(ETH_P_IP): -++ return nf_flow_offload_ip_hook(priv, skb, state); -++ case htons(ETH_P_IPV6): -++ return nf_flow_offload_ipv6_hook(priv, skb, state); -++ } -++ -++ return NF_ACCEPT; -++} -++ -++static int -++xt_flowoffload_create_hook(struct net_device *dev) -++{ -++ struct xt_flowoffload_hook *hook; -++ struct nf_hook_ops *ops; -++ -++ hook = kzalloc(sizeof(*hook), GFP_ATOMIC); -++ if (!hook) -++ return -ENOMEM; -++ -++ ops = &hook->ops; -++ ops->pf = NFPROTO_NETDEV; -++ ops->hooknum = NF_NETDEV_INGRESS; -++ ops->priority = 10; -++ ops->priv = &nf_flowtable; -++ ops->hook = xt_flowoffload_net_hook; -++ ops->dev = dev; -++ -++ hlist_add_head(&hook->list, &hooks); -++ mod_delayed_work(system_power_efficient_wq, &hook_work, 0); -++ -++ return 0; -++} -++ -++static struct xt_flowoffload_hook * -++flow_offload_lookup_hook(struct net_device *dev) -++{ -++ struct xt_flowoffload_hook *hook; -++ -++ hlist_for_each_entry(hook, &hooks, list) { -++ if (hook->ops.dev == dev) -++ return hook; -++ } -++ -++ return NULL; -++} -++ -++static void -++xt_flowoffload_check_device(struct net_device *dev) -++{ -++ struct xt_flowoffload_hook *hook; -++ -++ spin_lock_bh(&hooks_lock); -++ hook = flow_offload_lookup_hook(dev); -++ if (hook) -++ hook->used = true; -++ else -++ xt_flowoffload_create_hook(dev); -++ spin_unlock_bh(&hooks_lock); -++} -++ -++static void -++xt_flowoffload_register_hooks(void) -++{ -++ struct xt_flowoffload_hook *hook; -++ -++restart: -++ hlist_for_each_entry(hook, &hooks, list) { -++ if (hook->registered) -++ continue; -++ -++ hook->registered = true; -++ hook->net = dev_net(hook->ops.dev); -++ spin_unlock_bh(&hooks_lock); -++ nf_register_net_hook(hook->net, &hook->ops); -++ spin_lock_bh(&hooks_lock); -++ goto restart; -++ } -++ -++} -++ -++static void -++xt_flowoffload_cleanup_hooks(void) -++{ -++ struct xt_flowoffload_hook *hook; -++ -++restart: -++ hlist_for_each_entry(hook, &hooks, list) { -++ if (hook->used || !hook->registered) -++ continue; -++ -++ hlist_del(&hook->list); -++ spin_unlock_bh(&hooks_lock); -++ nf_unregister_net_hook(hook->net, &hook->ops); -++ kfree(hook); -++ spin_lock_bh(&hooks_lock); -++ goto restart; -++ } -++ -++} -++ -++static void -++xt_flowoffload_check_hook(struct flow_offload *flow, void *data) -++{ -++ struct flow_offload_tuple *tuple = &flow->tuplehash[0].tuple; -++ struct xt_flowoffload_hook *hook; -++ bool *found = data; -++ -++ spin_lock_bh(&hooks_lock); -++ hlist_for_each_entry(hook, &hooks, list) { -++ if (hook->ops.dev->ifindex != tuple->iifidx && -++ hook->ops.dev->ifindex != tuple->oifidx) -++ continue; -++ -++ hook->used = true; -++ *found = true; -++ } -++ spin_unlock_bh(&hooks_lock); -++} -++ -++static void -++xt_flowoffload_hook_work(struct work_struct *work) -++{ -++ struct xt_flowoffload_hook *hook; -++ bool found = false; -++ int err; -++ -++ spin_lock_bh(&hooks_lock); -++ xt_flowoffload_register_hooks(); -++ hlist_for_each_entry(hook, &hooks, list) -++ hook->used = false; -++ spin_unlock_bh(&hooks_lock); -++ -++ err = nf_flow_table_iterate(&nf_flowtable, xt_flowoffload_check_hook, -++ &found); -++ if (err && err != -EAGAIN) -++ goto out; -++ -++ spin_lock_bh(&hooks_lock); -++ xt_flowoffload_cleanup_hooks(); -++ spin_unlock_bh(&hooks_lock); -++ -++out: -++ if (found) -++ queue_delayed_work(system_power_efficient_wq, &hook_work, HZ); -++} -++ -++static bool -++xt_flowoffload_skip(struct sk_buff *skb, int family) -++{ -++ if (skb_sec_path(skb)) -++ return true; -++ -++ if (family == NFPROTO_IPV4) { -++ const struct ip_options *opt = &(IPCB(skb)->opt); -++ -++ if (unlikely(opt->optlen)) -++ return true; -++ } -++ -++ return false; -++} -++ -++static struct dst_entry * -++xt_flowoffload_dst(const struct nf_conn *ct, enum ip_conntrack_dir dir, -++ const struct xt_action_param *par, int ifindex) -++{ -++ struct dst_entry *dst = NULL; -++ struct flowi fl; -++ -++ memset(&fl, 0, sizeof(fl)); -++ switch (xt_family(par)) { -++ case NFPROTO_IPV4: -++ fl.u.ip4.daddr = ct->tuplehash[dir].tuple.src.u3.ip; -++ fl.u.ip4.flowi4_oif = ifindex; -++ break; -++ case NFPROTO_IPV6: -++ fl.u.ip6.saddr = ct->tuplehash[dir].tuple.dst.u3.in6; -++ fl.u.ip6.daddr = ct->tuplehash[dir].tuple.src.u3.in6; -++ fl.u.ip6.flowi6_oif = ifindex; -++ break; -++ } -++ -++ nf_route(xt_net(par), &dst, &fl, false, xt_family(par)); -++ -++ return dst; -++} -++ -++static int -++xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct, -++ const struct xt_action_param *par, -++ struct nf_flow_route *route, enum ip_conntrack_dir dir) -++{ -++ struct dst_entry *this_dst, *other_dst; -++ -++ this_dst = xt_flowoffload_dst(ct, !dir, par, xt_out(par)->ifindex); -++ other_dst = xt_flowoffload_dst(ct, dir, par, xt_in(par)->ifindex); -++ -++ route->tuple[dir].dst = this_dst; -++ route->tuple[!dir].dst = other_dst; -++ -++ if (!this_dst || !other_dst) -++ return -ENOENT; -++ -++ if (dst_xfrm(this_dst) || dst_xfrm(other_dst)) -++ return -EINVAL; -++ -++ return 0; -++} -++ -++static unsigned int -++flowoffload_tg(struct sk_buff *skb, const struct xt_action_param *par) -++{ -++ const struct xt_flowoffload_target_info *info = par->targinfo; -++ struct tcphdr _tcph, *tcph = NULL; -++ enum ip_conntrack_info ctinfo; -++ enum ip_conntrack_dir dir; -++ struct nf_flow_route route; -++ struct flow_offload *flow = NULL; -++ struct nf_conn *ct; -++ struct net *net; -++ -++ if (xt_flowoffload_skip(skb, xt_family(par))) -++ return XT_CONTINUE; -++ -++ ct = nf_ct_get(skb, &ctinfo); -++ if (ct == NULL) -++ return XT_CONTINUE; -++ -++ switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) { -++ case IPPROTO_TCP: -++ if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED) -++ return XT_CONTINUE; -++ -++ tcph = skb_header_pointer(skb, par->thoff, -++ sizeof(_tcph), &_tcph); -++ if (unlikely(!tcph || tcph->fin || tcph->rst)) -++ return XT_CONTINUE; -++ break; -++ case IPPROTO_UDP: -++ break; -++ default: -++ return XT_CONTINUE; -++ } -++ -++ if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) || -++ ct->status & IPS_SEQ_ADJUST) -++ return XT_CONTINUE; -++ -++ if (!nf_ct_is_confirmed(ct)) -++ return XT_CONTINUE; -++ -++ if (!xt_in(par) || !xt_out(par)) -++ return XT_CONTINUE; -++ -++ if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status)) -++ return XT_CONTINUE; -++ -++ dir = CTINFO2DIR(ctinfo); -++ -++ if (xt_flowoffload_route(skb, ct, par, &route, dir) == 0) -++ flow = flow_offload_alloc(ct, &route); -++ -++ dst_release(route.tuple[dir].dst); -++ dst_release(route.tuple[!dir].dst); -++ -++ if (!flow) -++ goto err_flow_route; -++ -++ if (tcph) { -++ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; -++ ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; -++ } -++ -++ if (flow_offload_add(&nf_flowtable, flow) < 0) -++ goto err_flow_add; -++ -++ xt_flowoffload_check_device(xt_in(par)); -++ xt_flowoffload_check_device(xt_out(par)); -++ -++ net = read_pnet(&nf_flowtable.ft_net); -++ if (!net) -++ write_pnet(&nf_flowtable.ft_net, xt_net(par)); -++ -++ if (info->flags & XT_FLOWOFFLOAD_HW) -++ nf_flow_offload_hw_add(xt_net(par), flow, ct); -++ -++ return XT_CONTINUE; -++ -++err_flow_add: -++ flow_offload_free(flow); -++err_flow_route: -++ clear_bit(IPS_OFFLOAD_BIT, &ct->status); -++ return XT_CONTINUE; -++} -++ -++ -++static int flowoffload_chk(const struct xt_tgchk_param *par) -++{ -++ struct xt_flowoffload_target_info *info = par->targinfo; -++ -++ if (info->flags & ~XT_FLOWOFFLOAD_MASK) -++ return -EINVAL; -++ -++ return 0; -++} -++ -++static struct xt_target offload_tg_reg __read_mostly = { -++ .family = NFPROTO_UNSPEC, -++ .name = "FLOWOFFLOAD", -++ .revision = 0, -++ .targetsize = sizeof(struct xt_flowoffload_target_info), -++ .usersize = sizeof(struct xt_flowoffload_target_info), -++ .checkentry = flowoffload_chk, -++ .target = flowoffload_tg, -++ .me = THIS_MODULE, -++}; -++ -++static int xt_flowoffload_table_init(struct nf_flowtable *table) -++{ -++ table->flags = NF_FLOWTABLE_F_HW; -++ nf_flow_table_init(table); -++ return 0; -++} -++ -++static void xt_flowoffload_table_cleanup(struct nf_flowtable *table) -++{ -++ nf_flow_table_free(table); -++} -++ -++static int flow_offload_netdev_event(struct notifier_block *this, -++ unsigned long event, void *ptr) -++{ -++ struct xt_flowoffload_hook *hook = NULL; -++ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -++ -++ if (event != NETDEV_UNREGISTER) -++ return NOTIFY_DONE; -++ -++ spin_lock_bh(&hooks_lock); -++ hook = flow_offload_lookup_hook(dev); -++ if (hook) { -++ hlist_del(&hook->list); -++ } -++ spin_unlock_bh(&hooks_lock); -++ if (hook) { -++ nf_unregister_net_hook(hook->net, &hook->ops); -++ kfree(hook); -++ } -++ -++ nf_flow_table_cleanup(dev_net(dev), dev); -++ -++ return NOTIFY_DONE; -++} -++ -++static struct notifier_block flow_offload_netdev_notifier = { -++ .notifier_call = flow_offload_netdev_event, -++}; -++ -++static int __init xt_flowoffload_tg_init(void) -++{ -++ int ret; -++ -++ register_netdevice_notifier(&flow_offload_netdev_notifier); -++ -++ INIT_DELAYED_WORK(&hook_work, xt_flowoffload_hook_work); -++ -++ ret = xt_flowoffload_table_init(&nf_flowtable); -++ if (ret) -++ return ret; -++ -++ ret = xt_register_target(&offload_tg_reg); -++ if (ret) -++ xt_flowoffload_table_cleanup(&nf_flowtable); -++ -++ return ret; -++} -++ -++static void __exit xt_flowoffload_tg_exit(void) -++{ -++ xt_unregister_target(&offload_tg_reg); -++ xt_flowoffload_table_cleanup(&nf_flowtable); -++ unregister_netdevice_notifier(&flow_offload_netdev_notifier); -++} -++ -++MODULE_LICENSE("GPL"); -++module_init(xt_flowoffload_tg_init); -++module_exit(xt_flowoffload_tg_exit); -+--- a/net/netfilter/nf_flow_table_core.c -++++ b/net/netfilter/nf_flow_table_core.c -+@@ -6,7 +6,6 @@ -+ #include -+ #include -+ #include -+-#include -+ #include -+ #include -+ #include -+--- /dev/null -++++ b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h -+@@ -0,0 +1,17 @@ -++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -++#ifndef _XT_FLOWOFFLOAD_H -++#define _XT_FLOWOFFLOAD_H -++ -++#include -++ -++enum { -++ XT_FLOWOFFLOAD_HW = 1 << 0, -++ -++ XT_FLOWOFFLOAD_MASK = XT_FLOWOFFLOAD_HW -++}; -++ -++struct xt_flowoffload_target_info { -++ __u32 flags; -++}; -++ -++#endif /* _XT_FLOWOFFLOAD_H */ -diff --git a/target/linux/generic/hack-4.14/651-wireless_mesh_header.patch b/target/linux/generic/hack-4.14/651-wireless_mesh_header.patch -new file mode 100644 -index 0000000000..f545d8ebbc ---- /dev/null -+++ b/target/linux/generic/hack-4.14/651-wireless_mesh_header.patch -@@ -0,0 +1,24 @@ -+From 6d3bc769657b0ee7c7506dad9911111c4226a7ea Mon Sep 17 00:00:00 2001 -+From: Imre Kaloz -+Date: Fri, 7 Jul 2017 17:21:05 +0200 -+Subject: mac80211: increase wireless mesh header size -+ -+lede-commit 3d4466cfd8f75f717efdb1f96fdde3c70d865fc1 -+Signed-off-by: Imre Kaloz -+--- -+ include/linux/netdevice.h | 4 ++-- -+ 1 file changed, 2 insertions(+), 2 deletions(-) -+ -+--- a/include/linux/netdevice.h -++++ b/include/linux/netdevice.h -+@@ -138,8 +138,8 @@ static inline bool dev_xmit_complete(int -+ -+ #if defined(CONFIG_HYPERV_NET) -+ # define LL_MAX_HEADER 128 -+-#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) -+-# if defined(CONFIG_MAC80211_MESH) -++#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) || 1 -++# if defined(CONFIG_MAC80211_MESH) || 1 -+ # define LL_MAX_HEADER 128 -+ # else -+ # define LL_MAX_HEADER 96 -diff --git a/target/linux/generic/hack-4.14/660-fq_codel_defaults.patch b/target/linux/generic/hack-4.14/660-fq_codel_defaults.patch -new file mode 100644 -index 0000000000..b923a2d206 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/660-fq_codel_defaults.patch -@@ -0,0 +1,27 @@ -+From a6ccb238939b25851474a279b20367fd24a0e816 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Fri, 7 Jul 2017 17:21:53 +0200 -+Subject: hack: net: fq_codel: tune defaults for small devices -+ -+Assume that x86_64 devices always have a big memory and do not need this -+optimization compared to devices with only 32 MB or 64 MB RAM. -+ -+Signed-off-by: Felix Fietkau -+--- -+ net/sched/sch_fq_codel.c | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/net/sched/sch_fq_codel.c -++++ b/net/sched/sch_fq_codel.c -+@@ -471,7 +471,11 @@ static int fq_codel_init(struct Qdisc *s -+ -+ sch->limit = 10*1024; -+ q->flows_cnt = 1024; -++#ifdef CONFIG_X86_64 -+ q->memory_limit = 32 << 20; /* 32 MBytes */ -++#else -++ q->memory_limit = 4 << 20; /* 4 MBytes */ -++#endif -+ q->drop_batch_size = 64; -+ q->quantum = psched_mtu(qdisc_dev(sch)); -+ INIT_LIST_HEAD(&q->new_flows); -diff --git a/target/linux/generic/hack-4.14/661-use_fq_codel_by_default.patch b/target/linux/generic/hack-4.14/661-use_fq_codel_by_default.patch -new file mode 100644 -index 0000000000..6a7d554c20 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/661-use_fq_codel_by_default.patch -@@ -0,0 +1,94 @@ -+From 1d418f7e88035ed7a94073f6354246c66e9193e9 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Fri, 7 Jul 2017 17:22:58 +0200 -+Subject: fq_codel: switch default qdisc from pfifo_fast to fq_codel and remove pfifo_fast -+ -+Signed-off-by: Felix Fietkau -+--- -+ include/net/sch_generic.h | 3 ++- -+ net/sched/Kconfig | 3 ++- -+ net/sched/sch_api.c | 2 +- -+ net/sched/sch_fq_codel.c | 3 ++- -+ net/sched/sch_generic.c | 4 ++-- -+ 5 files changed, 9 insertions(+), 6 deletions(-) -+ -+--- a/include/net/sch_generic.h -++++ b/include/net/sch_generic.h -+@@ -373,12 +373,13 @@ extern struct Qdisc_ops noop_qdisc_ops; -+ extern struct Qdisc_ops pfifo_fast_ops; -+ extern struct Qdisc_ops mq_qdisc_ops; -+ extern struct Qdisc_ops noqueue_qdisc_ops; -++extern struct Qdisc_ops fq_codel_qdisc_ops; -+ extern const struct Qdisc_ops *default_qdisc_ops; -+ static inline const struct Qdisc_ops * -+ get_default_qdisc_ops(const struct net_device *dev, int ntx) -+ { -+ return ntx < dev->real_num_tx_queues ? -+- default_qdisc_ops : &pfifo_fast_ops; -++ default_qdisc_ops : &fq_codel_qdisc_ops; -+ } -+ -+ struct Qdisc_class_common { -+--- a/net/sched/Kconfig -++++ b/net/sched/Kconfig -+@@ -3,8 +3,9 @@ -+ # -+ -+ menuconfig NET_SCHED -+- bool "QoS and/or fair queueing" -++ def_bool y -+ select NET_SCH_FIFO -++ select NET_SCH_FQ_CODEL -+ ---help--- -+ When the kernel has several packets to send out over a network -+ 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 -+@@ -2031,7 +2031,7 @@ static int __init pktsched_init(void) -+ return err; -+ } -+ -+- register_qdisc(&pfifo_fast_ops); -++ register_qdisc(&fq_codel_qdisc_ops); -+ register_qdisc(&pfifo_qdisc_ops); -+ register_qdisc(&bfifo_qdisc_ops); -+ register_qdisc(&pfifo_head_drop_qdisc_ops); -+--- a/net/sched/sch_fq_codel.c -++++ b/net/sched/sch_fq_codel.c -+@@ -700,7 +700,7 @@ static const struct Qdisc_class_ops fq_c -+ .walk = fq_codel_walk, -+ }; -+ -+-static struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = { -++struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = { -+ .cl_ops = &fq_codel_class_ops, -+ .id = "fq_codel", -+ .priv_size = sizeof(struct fq_codel_sched_data), -+@@ -715,6 +715,7 @@ static struct Qdisc_ops fq_codel_qdisc_o -+ .dump_stats = fq_codel_dump_stats, -+ .owner = THIS_MODULE, -+ }; -++EXPORT_SYMBOL(fq_codel_qdisc_ops); -+ -+ static int __init fq_codel_module_init(void) -+ { -+--- a/net/sched/sch_generic.c -++++ b/net/sched/sch_generic.c -+@@ -32,7 +32,7 @@ -+ #include -+ -+ /* Qdisc to use by default */ -+-const struct Qdisc_ops *default_qdisc_ops = &pfifo_fast_ops; -++const struct Qdisc_ops *default_qdisc_ops = &fq_codel_qdisc_ops; -+ EXPORT_SYMBOL(default_qdisc_ops); -+ -+ /* Main transmission queue. */ -+@@ -765,7 +765,7 @@ static void attach_one_default_qdisc(str -+ void *_unused) -+ { -+ struct Qdisc *qdisc; -+- const struct Qdisc_ops *ops = default_qdisc_ops; -++ const struct Qdisc_ops *ops = &fq_codel_qdisc_ops; -+ -+ if (dev->priv_flags & IFF_NO_QUEUE) -+ ops = &noqueue_qdisc_ops; -diff --git a/target/linux/generic/hack-4.14/662-remove_pfifo_fast.patch b/target/linux/generic/hack-4.14/662-remove_pfifo_fast.patch -new file mode 100644 -index 0000000000..d1a17a4bac ---- /dev/null -+++ b/target/linux/generic/hack-4.14/662-remove_pfifo_fast.patch -@@ -0,0 +1,159 @@ -+From b531d492d5ef1cf9dba0f4888eb5fd8624a6d762 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Fri, 7 Jul 2017 17:23:42 +0200 -+Subject: net: sched: switch default qdisc from pfifo_fast to fq_codel and remove pfifo_fast -+ -+Signed-off-by: Felix Fietkau -+--- -+ net/sched/sch_generic.c | 140 ------------------------------------------------ -+ 1 file changed, 140 deletions(-) -+ -+--- a/net/sched/sch_generic.c -++++ b/net/sched/sch_generic.c -+@@ -454,146 +454,6 @@ struct Qdisc_ops noqueue_qdisc_ops __rea -+ .owner = THIS_MODULE, -+ }; -+ -+-static const u8 prio2band[TC_PRIO_MAX + 1] = { -+- 1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1 -+-}; -+- -+-/* 3-band FIFO queue: old style, but should be a bit faster than -+- generic prio+fifo combination. -+- */ -+- -+-#define PFIFO_FAST_BANDS 3 -+- -+-/* -+- * Private data for a pfifo_fast scheduler containing: -+- * - queues for the three band -+- * - bitmap indicating which of the bands contain skbs -+- */ -+-struct pfifo_fast_priv { -+- u32 bitmap; -+- struct qdisc_skb_head q[PFIFO_FAST_BANDS]; -+-}; -+- -+-/* -+- * Convert a bitmap to the first band number where an skb is queued, where: -+- * bitmap=0 means there are no skbs on any band. -+- * bitmap=1 means there is an skb on band 0. -+- * bitmap=7 means there are skbs on all 3 bands, etc. -+- */ -+-static const int bitmap2band[] = {-1, 0, 1, 0, 2, 0, 1, 0}; -+- -+-static inline struct qdisc_skb_head *band2list(struct pfifo_fast_priv *priv, -+- int band) -+-{ -+- return priv->q + band; -+-} -+- -+-static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc *qdisc, -+- struct sk_buff **to_free) -+-{ -+- if (qdisc->q.qlen < qdisc_dev(qdisc)->tx_queue_len) { -+- int band = prio2band[skb->priority & TC_PRIO_MAX]; -+- struct pfifo_fast_priv *priv = qdisc_priv(qdisc); -+- struct qdisc_skb_head *list = band2list(priv, band); -+- -+- priv->bitmap |= (1 << band); -+- qdisc->q.qlen++; -+- return __qdisc_enqueue_tail(skb, qdisc, list); -+- } -+- -+- return qdisc_drop(skb, qdisc, to_free); -+-} -+- -+-static struct sk_buff *pfifo_fast_dequeue(struct Qdisc *qdisc) -+-{ -+- struct pfifo_fast_priv *priv = qdisc_priv(qdisc); -+- int band = bitmap2band[priv->bitmap]; -+- -+- if (likely(band >= 0)) { -+- struct qdisc_skb_head *qh = band2list(priv, band); -+- struct sk_buff *skb = __qdisc_dequeue_head(qh); -+- -+- if (likely(skb != NULL)) { -+- qdisc_qstats_backlog_dec(qdisc, skb); -+- qdisc_bstats_update(qdisc, skb); -+- } -+- -+- qdisc->q.qlen--; -+- if (qh->qlen == 0) -+- priv->bitmap &= ~(1 << band); -+- -+- return skb; -+- } -+- -+- return NULL; -+-} -+- -+-static struct sk_buff *pfifo_fast_peek(struct Qdisc *qdisc) -+-{ -+- struct pfifo_fast_priv *priv = qdisc_priv(qdisc); -+- int band = bitmap2band[priv->bitmap]; -+- -+- if (band >= 0) { -+- struct qdisc_skb_head *qh = band2list(priv, band); -+- -+- return qh->head; -+- } -+- -+- return NULL; -+-} -+- -+-static void pfifo_fast_reset(struct Qdisc *qdisc) -+-{ -+- int prio; -+- struct pfifo_fast_priv *priv = qdisc_priv(qdisc); -+- -+- for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) -+- __qdisc_reset_queue(band2list(priv, prio)); -+- -+- priv->bitmap = 0; -+- qdisc->qstats.backlog = 0; -+- qdisc->q.qlen = 0; -+-} -+- -+-static int pfifo_fast_dump(struct Qdisc *qdisc, struct sk_buff *skb) -+-{ -+- struct tc_prio_qopt opt = { .bands = PFIFO_FAST_BANDS }; -+- -+- memcpy(&opt.priomap, prio2band, TC_PRIO_MAX + 1); -+- if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt)) -+- goto nla_put_failure; -+- return skb->len; -+- -+-nla_put_failure: -+- return -1; -+-} -+- -+-static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt) -+-{ -+- int prio; -+- struct pfifo_fast_priv *priv = qdisc_priv(qdisc); -+- -+- for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) -+- qdisc_skb_head_init(band2list(priv, prio)); -+- -+- /* Can by-pass the queue discipline */ -+- qdisc->flags |= TCQ_F_CAN_BYPASS; -+- return 0; -+-} -+- -+-struct Qdisc_ops pfifo_fast_ops __read_mostly = { -+- .id = "pfifo_fast", -+- .priv_size = sizeof(struct pfifo_fast_priv), -+- .enqueue = pfifo_fast_enqueue, -+- .dequeue = pfifo_fast_dequeue, -+- .peek = pfifo_fast_peek, -+- .init = pfifo_fast_init, -+- .reset = pfifo_fast_reset, -+- .dump = pfifo_fast_dump, -+- .owner = THIS_MODULE, -+-}; -+-EXPORT_SYMBOL(pfifo_fast_ops); -+- -+ static struct lock_class_key qdisc_tx_busylock; -+ static struct lock_class_key qdisc_running_key; -+ -diff --git a/target/linux/generic/hack-4.14/700-swconfig_switch_drivers.patch b/target/linux/generic/hack-4.14/700-swconfig_switch_drivers.patch -new file mode 100644 -index 0000000000..f9df475500 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/700-swconfig_switch_drivers.patch -@@ -0,0 +1,140 @@ -+From 36e516290611e613aa92996cb4339561452695b4 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Fri, 7 Jul 2017 17:24:23 +0200 -+Subject: net: swconfig: adds openwrt switch layer -+ -+Signed-off-by: Felix Fietkau -+--- -+ drivers/net/phy/Kconfig | 83 +++++++++++++++++++++++++++++++++++++++++++++++ -+ drivers/net/phy/Makefile | 15 +++++++++ -+ include/uapi/linux/Kbuild | 1 + -+ 3 files changed, 99 insertions(+) -+ -+--- a/drivers/net/phy/Kconfig -++++ b/drivers/net/phy/Kconfig -+@@ -198,6 +198,89 @@ config LED_TRIGGER_PHY -+ Mbps or Gbps -+ -+ -++comment "Switch configuration API + drivers" -++ -++config SWCONFIG -++ tristate "Switch configuration API" -++ ---help--- -++ Switch configuration API using netlink. This allows -++ you to configure the VLAN features of certain switches. -++ -++config SWCONFIG_LEDS -++ bool "Switch LED trigger support" -++ depends on (SWCONFIG && LEDS_TRIGGERS) -++ -++config ADM6996_PHY -++ tristate "Driver for ADM6996 switches" -++ select SWCONFIG -++ ---help--- -++ Currently supports the ADM6996FC and ADM6996M switches. -++ Support for FC is very limited. -++ -++config AR8216_PHY -++ tristate "Driver for Atheros AR8216 switches" -++ select ETHERNET_PACKET_MANGLE -++ select SWCONFIG -++ -++config AR8216_PHY_LEDS -++ bool "Atheros AR8216 switch LED support" -++ depends on (AR8216_PHY && LEDS_CLASS) -++ -++source "drivers/net/phy/b53/Kconfig" -++ -++config IP17XX_PHY -++ tristate "Driver for IC+ IP17xx switches" -++ select SWCONFIG -++ -++config MVSWITCH_PHY -++ tristate "Driver for Marvell 88E6060 switches" -++ select ETHERNET_PACKET_MANGLE -++ -++config MVSW61XX_PHY -++ tristate "Driver for Marvell 88E6171/6172 switches" -++ select SWCONFIG -++ -++config PSB6970_PHY -++ tristate "Lantiq XWAY Tantos (PSB6970) Ethernet switch" -++ select SWCONFIG -++ select ETHERNET_PACKET_MANGLE -++ -++config RTL8306_PHY -++ tristate "Driver for Realtek RTL8306S switches" -++ select SWCONFIG -++ -++config RTL8366_SMI -++ tristate "Driver for the RTL8366 SMI interface" -++ depends on GPIOLIB -++ ---help--- -++ This module implements the SMI interface protocol which is used -++ by some RTL8366 ethernet switch devices via the generic GPIO API. -++ -++if RTL8366_SMI -++ -++config RTL8366_SMI_DEBUG_FS -++ bool "RTL8366 SMI interface debugfs support" -++ depends on DEBUG_FS -++ default n -++ -++config RTL8366S_PHY -++ tristate "Driver for the Realtek RTL8366S switch" -++ select SWCONFIG -++ -++config RTL8366RB_PHY -++ tristate "Driver for the Realtek RTL8366RB switch" -++ select SWCONFIG -++ -++config RTL8367_PHY -++ tristate "Driver for the Realtek RTL8367R/M switches" -++ select SWCONFIG -++ -++config RTL8367B_PHY -++ tristate "Driver fot the Realtek RTL8367R-VB switch" -++ select SWCONFIG -++ -++endif # RTL8366_SMI -++ -+ comment "MII PHY device drivers" -+ -+ config SFP -+--- a/drivers/net/phy/Makefile -++++ b/drivers/net/phy/Makefile -+@@ -22,6 +22,21 @@ libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_ -+ obj-$(CONFIG_PHYLINK) += phylink.o -+ obj-$(CONFIG_PHYLIB) += libphy.o -+ -++obj-$(CONFIG_SWCONFIG) += swconfig.o -++obj-$(CONFIG_ADM6996_PHY) += adm6996.o -++obj-$(CONFIG_AR8216_PHY) += ar8216.o ar8327.o -++obj-$(CONFIG_SWCONFIG_B53) += b53/ -++obj-$(CONFIG_IP17XX_PHY) += ip17xx.o -++obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o -++obj-$(CONFIG_MVSW61XX_PHY) += mvsw61xx.o -++obj-$(CONFIG_PSB6970_PHY) += psb6970.o -++obj-$(CONFIG_RTL8306_PHY) += rtl8306.o -++obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o -++obj-$(CONFIG_RTL8366S_PHY) += rtl8366s.o -++obj-$(CONFIG_RTL8366RB_PHY) += rtl8366rb.o -++obj-$(CONFIG_RTL8367_PHY) += rtl8367.o -++obj-$(CONFIG_RTL8367B_PHY) += rtl8367b.o -++ -+ obj-$(CONFIG_MDIO_BCM_IPROC) += mdio-bcm-iproc.o -+ obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o -+ obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o -+--- a/include/linux/platform_data/b53.h -++++ b/include/linux/platform_data/b53.h -+@@ -25,6 +25,9 @@ struct b53_platform_data { -+ u32 chip_id; -+ u16 enabled_ports; -+ -++ /* allow to specify an ethX alias */ -++ const char *alias; -++ -+ /* only used by MMAP'd driver */ -+ unsigned big_endian:1; -+ void __iomem *regs; -diff --git a/target/linux/generic/hack-4.14/702-phy_add_aneg_done_function.patch b/target/linux/generic/hack-4.14/702-phy_add_aneg_done_function.patch -new file mode 100644 -index 0000000000..5885c8fae6 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/702-phy_add_aneg_done_function.patch -@@ -0,0 +1,27 @@ -+--- a/include/linux/phy.h -++++ b/include/linux/phy.h -+@@ -549,6 +549,12 @@ struct phy_driver { -+ /* Determines the negotiated speed and duplex */ -+ int (*read_status)(struct phy_device *phydev); -+ -++ /* -++ * Update the value in phydev->link to reflect the -++ * current link value -++ */ -++ int (*update_link)(struct phy_device *phydev); -++ -+ /* Clears any pending interrupts */ -+ int (*ack_interrupt)(struct phy_device *phydev); -+ -+--- a/drivers/net/phy/phy_device.c -++++ b/drivers/net/phy/phy_device.c -+@@ -1466,6 +1466,9 @@ int genphy_update_link(struct phy_device -+ { -+ int status; -+ -++ if (phydev->drv && phydev->drv->update_link) -++ return phydev->drv->update_link(phydev); -++ -+ /* Do a fake read */ -+ status = phy_read(phydev, MII_BMSR); -+ if (status < 0) -diff --git a/target/linux/generic/hack-4.14/721-phy_packets.patch b/target/linux/generic/hack-4.14/721-phy_packets.patch -new file mode 100644 -index 0000000000..d67171054d ---- /dev/null -+++ b/target/linux/generic/hack-4.14/721-phy_packets.patch -@@ -0,0 +1,176 @@ -+From ffe387740bbe88dd88bbe04d6375902708003d6e Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Fri, 7 Jul 2017 17:25:00 +0200 -+Subject: net: add packet mangeling patch -+ -+Signed-off-by: Felix Fietkau -+--- -+ include/linux/netdevice.h | 11 +++++++++++ -+ include/linux/skbuff.h | 14 ++++---------- -+ net/Kconfig | 6 ++++++ -+ net/core/dev.c | 18 ++++++++++++++---- -+ net/core/skbuff.c | 17 +++++++++++++++++ -+ net/ethernet/eth.c | 6 ++++++ -+ 6 files changed, 58 insertions(+), 14 deletions(-) -+ -+--- a/include/linux/netdevice.h -++++ b/include/linux/netdevice.h -+@@ -1415,6 +1415,7 @@ enum netdev_priv_flags { -+ IFF_PHONY_HEADROOM = 1<<26, -+ IFF_MACSEC = 1<<27, -+ IFF_L3MDEV_RX_HANDLER = 1<<28, -++ IFF_NO_IP_ALIGN = 1<<29, -+ }; -+ -+ #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN -+@@ -1445,6 +1446,7 @@ enum netdev_priv_flags { -+ #define IFF_RXFH_CONFIGURED IFF_RXFH_CONFIGURED -+ #define IFF_MACSEC IFF_MACSEC -+ #define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER -++#define IFF_NO_IP_ALIGN IFF_NO_IP_ALIGN -+ -+ /** -+ * struct net_device - The DEVICE structure. -+@@ -1731,6 +1733,11 @@ struct net_device { -+ const struct xfrmdev_ops *xfrmdev_ops; -+ #endif -+ -++#ifdef CONFIG_ETHERNET_PACKET_MANGLE -++ void (*eth_mangle_rx)(struct net_device *dev, struct sk_buff *skb); -++ struct sk_buff *(*eth_mangle_tx)(struct net_device *dev, struct sk_buff *skb); -++#endif -++ -+ const struct header_ops *header_ops; -+ -+ unsigned int flags; -+@@ -1805,6 +1812,10 @@ struct net_device { -+ struct mpls_dev __rcu *mpls_ptr; -+ #endif -+ -++#ifdef CONFIG_ETHERNET_PACKET_MANGLE -++ void *phy_ptr; /* PHY device specific data */ -++#endif -++ -+ /* -+ * Cache lines mostly used on receive path (including eth_type_trans()) -+ */ -+--- a/include/linux/skbuff.h -++++ b/include/linux/skbuff.h -+@@ -2532,6 +2532,10 @@ static inline int pskb_trim(struct sk_bu -+ return (len < skb->len) ? __pskb_trim(skb, len) : 0; -+ } -+ -++extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, -++ unsigned int length, gfp_t gfp); -++ -++ -+ /** -+ * pskb_trim_unique - remove end from a paged unique (not cloned) buffer -+ * @skb: buffer to alter -+@@ -2663,16 +2667,6 @@ static inline struct sk_buff *dev_alloc_ -+ } -+ -+ -+-static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, -+- unsigned int length, gfp_t gfp) -+-{ -+- struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); -+- -+- if (NET_IP_ALIGN && skb) -+- skb_reserve(skb, NET_IP_ALIGN); -+- return skb; -+-} -+- -+ static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, -+ unsigned int length) -+ { -+--- a/net/Kconfig -++++ b/net/Kconfig -+@@ -25,6 +25,12 @@ menuconfig NET -+ -+ if NET -+ -++config ETHERNET_PACKET_MANGLE -++ bool -++ help -++ This option can be selected by phy drivers that need to mangle -++ packets going in or out of an ethernet device. -++ -+ config WANT_COMPAT_NETLINK_MESSAGES -+ bool -+ help -+--- a/net/core/dev.c -++++ b/net/core/dev.c -+@@ -3001,10 +3001,20 @@ static int xmit_one(struct sk_buff *skb, -+ if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all)) -+ dev_queue_xmit_nit(skb, dev); -+ -+- len = skb->len; -+- trace_net_dev_start_xmit(skb, dev); -+- rc = netdev_start_xmit(skb, dev, txq, more); -+- trace_net_dev_xmit(skb, rc, dev, len); -++#ifdef CONFIG_ETHERNET_PACKET_MANGLE -++ if (!dev->eth_mangle_tx || -++ (skb = dev->eth_mangle_tx(dev, skb)) != NULL) -++#else -++ if (1) -++#endif -++ { -++ len = skb->len; -++ trace_net_dev_start_xmit(skb, dev); -++ rc = netdev_start_xmit(skb, dev, txq, more); -++ trace_net_dev_xmit(skb, rc, dev, len); -++ } else { -++ rc = NETDEV_TX_OK; -++ } -+ -+ return rc; -+ } -+--- a/net/core/skbuff.c -++++ b/net/core/skbuff.c -+@@ -63,6 +63,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include -+ #include -+@@ -503,6 +504,22 @@ skb_fail: -+ } -+ EXPORT_SYMBOL(__napi_alloc_skb); -+ -++struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, -++ unsigned int length, gfp_t gfp) -++{ -++ struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); -++ -++#ifdef CONFIG_ETHERNET_PACKET_MANGLE -++ if (dev && (dev->priv_flags & IFF_NO_IP_ALIGN)) -++ return skb; -++#endif -++ -++ if (NET_IP_ALIGN && skb) -++ skb_reserve(skb, NET_IP_ALIGN); -++ return skb; -++} -++EXPORT_SYMBOL(__netdev_alloc_skb_ip_align); -++ -+ void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, -+ int size, unsigned int truesize) -+ { -+--- a/net/ethernet/eth.c -++++ b/net/ethernet/eth.c -+@@ -172,6 +172,12 @@ __be16 eth_type_trans(struct sk_buff *sk -+ const struct ethhdr *eth; -+ -+ skb->dev = dev; -++ -++#ifdef CONFIG_ETHERNET_PACKET_MANGLE -++ if (dev->eth_mangle_rx) -++ dev->eth_mangle_rx(dev, skb); -++#endif -++ -+ skb_reset_mac_header(skb); -+ -+ eth = (struct ethhdr *)skb->data; -diff --git a/target/linux/generic/hack-4.14/773-bgmac-add-srab-switch.patch b/target/linux/generic/hack-4.14/773-bgmac-add-srab-switch.patch -new file mode 100644 -index 0000000000..33a18a8352 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/773-bgmac-add-srab-switch.patch -@@ -0,0 +1,98 @@ -+From 3cb240533ab787899dc7f17aa7d6c5b4810e2e58 Mon Sep 17 00:00:00 2001 -+From: Hauke Mehrtens -+Date: Fri, 7 Jul 2017 17:26:01 +0200 -+Subject: bcm53xx: bgmac: use srab switch driver -+ -+use the srab switch driver on these SoCs. -+ -+Signed-off-by: Hauke Mehrtens -+--- -+ drivers/net/ethernet/broadcom/bgmac-bcma.c | 1 + -+ drivers/net/ethernet/broadcom/bgmac.c | 24 ++++++++++++++++++++++++ -+ drivers/net/ethernet/broadcom/bgmac.h | 4 ++++ -+ 3 files changed, 29 insertions(+) -+ -+--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c -++++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c -+@@ -268,6 +268,7 @@ static int bgmac_probe(struct bcma_devic -+ bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; -+ bgmac->feature_flags |= BGMAC_FEAT_NO_RESET; -+ bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500; -++ bgmac->feature_flags |= BGMAC_FEAT_SRAB; -+ break; -+ default: -+ bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; -+--- a/drivers/net/ethernet/broadcom/bgmac.c -++++ b/drivers/net/ethernet/broadcom/bgmac.c -+@@ -12,6 +12,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ #include -+@@ -1410,6 +1411,17 @@ static const struct ethtool_ops bgmac_et -+ .set_link_ksettings = phy_ethtool_set_link_ksettings, -+ }; -+ -++static struct b53_platform_data bgmac_b53_pdata = { -++}; -++ -++static struct platform_device bgmac_b53_dev = { -++ .name = "b53-srab-switch", -++ .id = -1, -++ .dev = { -++ .platform_data = &bgmac_b53_pdata, -++ }, -++}; -++ -+ /************************************************** -+ * MII -+ **************************************************/ -+@@ -1539,6 +1551,14 @@ int bgmac_enet_probe(struct bgmac *bgmac -+ net_dev->hw_features = net_dev->features; -+ net_dev->vlan_features = net_dev->features; -+ -++ if ((bgmac->feature_flags & BGMAC_FEAT_SRAB) && !bgmac_b53_pdata.regs) { -++ bgmac_b53_pdata.regs = ioremap_nocache(0x18007000, 0x1000); -++ -++ err = platform_device_register(&bgmac_b53_dev); -++ if (!err) -++ bgmac->b53_device = &bgmac_b53_dev; -++ } -++ -+ err = register_netdev(bgmac->net_dev); -+ if (err) { -+ dev_err(bgmac->dev, "Cannot register net device\n"); -+@@ -1561,6 +1581,10 @@ EXPORT_SYMBOL_GPL(bgmac_enet_probe); -+ -+ void bgmac_enet_remove(struct bgmac *bgmac) -+ { -++ if (bgmac->b53_device) -++ platform_device_unregister(&bgmac_b53_dev); -++ bgmac->b53_device = NULL; -++ -+ unregister_netdev(bgmac->net_dev); -+ phy_disconnect(bgmac->net_dev->phydev); -+ netif_napi_del(&bgmac->napi); -+--- a/drivers/net/ethernet/broadcom/bgmac.h -++++ b/drivers/net/ethernet/broadcom/bgmac.h -+@@ -427,6 +427,7 @@ -+ #define BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII BIT(18) -+ #define BGMAC_FEAT_CC7_IF_TYPE_RGMII BIT(19) -+ #define BGMAC_FEAT_IDM_MASK BIT(20) -++#define BGMAC_FEAT_SRAB BIT(21) -+ -+ struct bgmac_slot_info { -+ union { -+@@ -532,6 +533,9 @@ struct bgmac { -+ void (*cmn_maskset32)(struct bgmac *bgmac, u16 offset, u32 mask, -+ u32 set); -+ int (*phy_connect)(struct bgmac *bgmac); -++ -++ /* platform device for associated switch */ -++ struct platform_device *b53_device; -+ }; -+ -+ struct bgmac *bgmac_alloc(struct device *dev); -diff --git a/target/linux/generic/hack-4.14/901-debloat_sock_diag.patch b/target/linux/generic/hack-4.14/901-debloat_sock_diag.patch -new file mode 100644 -index 0000000000..2f2b8eb705 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/901-debloat_sock_diag.patch -@@ -0,0 +1,136 @@ -+From 3b6115d6b57a263bdc8c9b1df273bd4a7955eead Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Sat, 8 Jul 2017 08:16:31 +0200 -+Subject: debloat: add some debloat patches, strip down procfs and make O_DIRECT support optional, saves ~15K after lzma on MIPS -+ -+Signed-off-by: Felix Fietkau -+--- -+ net/Kconfig | 3 +++ -+ net/core/Makefile | 3 ++- -+ net/core/sock.c | 2 ++ -+ net/ipv4/Kconfig | 1 + -+ net/netlink/Kconfig | 1 + -+ net/packet/Kconfig | 1 + -+ net/unix/Kconfig | 1 + -+ 7 files changed, 11 insertions(+), 1 deletion(-) -+ -+--- a/net/Kconfig -++++ b/net/Kconfig -+@@ -97,6 +97,9 @@ source "net/netlabel/Kconfig" -+ -+ endif # if INET -+ -++config SOCK_DIAG -++ bool -++ -+ config NETWORK_SECMARK -+ bool "Security Marking" -+ help -+--- a/net/core/Makefile -++++ b/net/core/Makefile -+@@ -10,9 +10,10 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core. -+ -+ obj-y += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \ -+ neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ -+- sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \ -++ dev_ioctl.o tso.o sock_reuseport.o \ -+ fib_notifier.o -+ -++obj-$(CONFIG_SOCK_DIAG) += sock_diag.o -+ obj-y += net-sysfs.o -+ obj-$(CONFIG_PROC_FS) += net-procfs.o -+ obj-$(CONFIG_NET_PKTGEN) += pktgen.o -+--- a/net/core/sock.c -++++ b/net/core/sock.c -+@@ -528,6 +528,18 @@ discard_and_relse: -+ } -+ EXPORT_SYMBOL(__sk_receive_skb); -+ -++u64 sock_gen_cookie(struct sock *sk) -++{ -++ while (1) { -++ u64 res = atomic64_read(&sk->sk_cookie); -++ -++ if (res) -++ return res; -++ res = atomic64_inc_return(&sock_net(sk)->cookie_gen); -++ atomic64_cmpxchg(&sk->sk_cookie, 0, res); -++ } -++} -++ -+ struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie) -+ { -+ struct dst_entry *dst = __sk_dst_get(sk); -+@@ -1599,9 +1611,11 @@ void sk_destruct(struct sock *sk) -+ -+ static void __sk_free(struct sock *sk) -+ { -++#ifdef CONFIG_SOCK_DIAG -+ if (unlikely(sk->sk_net_refcnt && sock_diag_has_destroy_listeners(sk))) -+ sock_diag_broadcast_destroy(sk); -+ else -++#endif -+ sk_destruct(sk); -+ } -+ -+--- a/net/core/sock_diag.c -++++ b/net/core/sock_diag.c -+@@ -19,18 +19,6 @@ static int (*inet_rcv_compat)(struct sk_ -+ static DEFINE_MUTEX(sock_diag_table_mutex); -+ static struct workqueue_struct *broadcast_wq; -+ -+-u64 sock_gen_cookie(struct sock *sk) -+-{ -+- while (1) { -+- u64 res = atomic64_read(&sk->sk_cookie); -+- -+- if (res) -+- return res; -+- res = atomic64_inc_return(&sock_net(sk)->cookie_gen); -+- atomic64_cmpxchg(&sk->sk_cookie, 0, res); -+- } -+-} -+- -+ int sock_diag_check_cookie(struct sock *sk, const __u32 *cookie) -+ { -+ u64 res; -+--- a/net/ipv4/Kconfig -++++ b/net/ipv4/Kconfig -+@@ -421,6 +421,7 @@ config INET_XFRM_MODE_BEET -+ -+ config INET_DIAG -+ tristate "INET: socket monitoring interface" -++ select SOCK_DIAG -+ default y -+ ---help--- -+ Support for INET (TCP, DCCP, etc) socket monitoring interface used by -+--- a/net/netlink/Kconfig -++++ b/net/netlink/Kconfig -+@@ -4,6 +4,7 @@ -+ -+ config NETLINK_DIAG -+ tristate "NETLINK: socket monitoring interface" -++ select SOCK_DIAG -+ default n -+ ---help--- -+ Support for NETLINK socket monitoring interface used by the ss tool. -+--- a/net/packet/Kconfig -++++ b/net/packet/Kconfig -+@@ -18,6 +18,7 @@ config PACKET -+ config PACKET_DIAG -+ tristate "Packet: sockets monitoring interface" -+ depends on PACKET -++ select SOCK_DIAG -+ default n -+ ---help--- -+ Support for PF_PACKET sockets monitoring interface used by the ss tool. -+--- a/net/unix/Kconfig -++++ b/net/unix/Kconfig -+@@ -22,6 +22,7 @@ config UNIX -+ config UNIX_DIAG -+ tristate "UNIX: socket monitoring interface" -+ depends on UNIX -++ select SOCK_DIAG -+ default n -+ ---help--- -+ Support for UNIX socket monitoring interface used by the ss tool. -diff --git a/target/linux/generic/hack-4.14/902-debloat_proc.patch b/target/linux/generic/hack-4.14/902-debloat_proc.patch -new file mode 100644 -index 0000000000..3cf89b7421 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/902-debloat_proc.patch -@@ -0,0 +1,405 @@ -+From 9e3f1d0805b2d919904dd9a4ff0d956314cc3cba Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Sat, 8 Jul 2017 08:20:09 +0200 -+Subject: debloat: procfs -+ -+Signed-off-by: Felix Fietkau -+--- -+ fs/locks.c | 2 ++ -+ fs/proc/Kconfig | 5 +++++ -+ fs/proc/consoles.c | 3 +++ -+ fs/proc/proc_tty.c | 11 ++++++++++- -+ include/net/snmp.h | 18 +++++++++++++++++- -+ ipc/msg.c | 3 +++ -+ ipc/sem.c | 2 ++ -+ ipc/shm.c | 2 ++ -+ ipc/util.c | 3 +++ -+ kernel/exec_domain.c | 2 ++ -+ kernel/irq/proc.c | 9 +++++++++ -+ kernel/time/timer_list.c | 2 ++ -+ mm/vmalloc.c | 2 ++ -+ mm/vmstat.c | 8 +++++--- -+ net/8021q/vlanproc.c | 6 ++++++ -+ net/core/net-procfs.c | 18 ++++++++++++------ -+ net/core/sock.c | 2 ++ -+ net/ipv4/fib_trie.c | 18 ++++++++++++------ -+ net/ipv4/proc.c | 3 +++ -+ net/ipv4/route.c | 3 +++ -+ 20 files changed, 105 insertions(+), 17 deletions(-) -+ -+--- a/fs/locks.c -++++ b/fs/locks.c -+@@ -2812,6 +2812,8 @@ static const struct file_operations proc -+ -+ static int __init proc_locks_init(void) -+ { -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return 0; -+ proc_create("locks", 0, NULL, &proc_locks_operations); -+ return 0; -+ } -+--- a/fs/proc/Kconfig -++++ b/fs/proc/Kconfig -+@@ -81,3 +81,8 @@ config PROC_CHILDREN -+ -+ Say Y if you are running any user-space software which takes benefit from -+ this interface. For example, rkt is such a piece of software. -++ -++config PROC_STRIPPED -++ default n -++ depends on EXPERT -++ bool "Strip non-essential /proc functionality to reduce code size" -+--- a/fs/proc/consoles.c -++++ b/fs/proc/consoles.c -+@@ -106,6 +106,9 @@ static const struct file_operations proc -+ -+ static int __init proc_consoles_init(void) -+ { -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return 0; -++ -+ proc_create("consoles", 0, NULL, &proc_consoles_operations); -+ return 0; -+ } -+--- a/fs/proc/proc_tty.c -++++ b/fs/proc/proc_tty.c -+@@ -145,7 +145,10 @@ static const struct file_operations proc -+ void proc_tty_register_driver(struct tty_driver *driver) -+ { -+ struct proc_dir_entry *ent; -+- -++ -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return; -++ -+ if (!driver->driver_name || driver->proc_entry || -+ !driver->ops->proc_fops) -+ return; -+@@ -162,6 +165,9 @@ void proc_tty_unregister_driver(struct t -+ { -+ struct proc_dir_entry *ent; -+ -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return; -++ -+ ent = driver->proc_entry; -+ if (!ent) -+ return; -+@@ -176,6 +182,9 @@ void proc_tty_unregister_driver(struct t -+ */ -+ void __init proc_tty_init(void) -+ { -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return; -++ -+ if (!proc_mkdir("tty", NULL)) -+ return; -+ proc_mkdir("tty/ldisc", NULL); /* Preserved: it's userspace visible */ -+--- a/include/net/snmp.h -++++ b/include/net/snmp.h -+@@ -123,6 +123,21 @@ struct linux_xfrm_mib { -+ #define DECLARE_SNMP_STAT(type, name) \ -+ extern __typeof__(type) __percpu *name -+ -++#ifdef CONFIG_PROC_STRIPPED -++#define __SNMP_STATS_DUMMY(mib) \ -++ do { (void) mib->mibs[0]; } while(0) -++ -++#define __SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) -++#define SNMP_INC_STATS_ATOMIC_LONG(mib, field) __SNMP_STATS_DUMMY(mib) -++#define SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) -++#define SNMP_DEC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) -++#define __SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib) -++#define SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib) -++#define SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib) -++#define __SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib) -++ -++#else -++ -+ #define __SNMP_INC_STATS(mib, field) \ -+ __this_cpu_inc(mib->mibs[field]) -+ -+@@ -153,8 +168,9 @@ struct linux_xfrm_mib { -+ __this_cpu_add(ptr[basefield##OCTETS], addend); \ -+ } while (0) -+ -++#endif -+ -+-#if BITS_PER_LONG==32 -++#if (BITS_PER_LONG==32) && !defined(CONFIG_PROC_STRIPPED) -+ -+ #define __SNMP_ADD_STATS64(mib, field, addend) \ -+ do { \ -+--- a/ipc/msg.c -++++ b/ipc/msg.c -+@@ -1208,6 +1208,9 @@ int __init msg_init(void) -+ { -+ const int err = msg_init_ns(&init_ipc_ns); -+ -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return err; -++ -+ ipc_init_proc_interface("sysvipc/msg", -+ " key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n", -+ IPC_MSG_IDS, sysvipc_msg_proc_show); -+--- a/ipc/sem.c -++++ b/ipc/sem.c -+@@ -207,6 +207,8 @@ int __init sem_init(void) -+ { -+ const int err = sem_init_ns(&init_ipc_ns); -+ -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return err; -+ ipc_init_proc_interface("sysvipc/sem", -+ " key semid perms nsems uid gid cuid cgid otime ctime\n", -+ IPC_SEM_IDS, sysvipc_sem_proc_show); -+--- a/ipc/shm.c -++++ b/ipc/shm.c -+@@ -122,6 +122,8 @@ pure_initcall(ipc_ns_init); -+ -+ void __init shm_init(void) -+ { -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return; -+ ipc_init_proc_interface("sysvipc/shm", -+ #if BITS_PER_LONG <= 32 -+ " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n", -+--- a/ipc/util.c -++++ b/ipc/util.c -+@@ -141,6 +141,9 @@ void __init ipc_init_proc_interface(cons -+ struct proc_dir_entry *pde; -+ struct ipc_proc_iface *iface; -+ -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return; -++ -+ iface = kmalloc(sizeof(*iface), GFP_KERNEL); -+ if (!iface) -+ return; -+--- a/kernel/exec_domain.c -++++ b/kernel/exec_domain.c -+@@ -42,6 +42,8 @@ static const struct file_operations exec -+ -+ static int __init proc_execdomains_init(void) -+ { -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return 0; -+ proc_create("execdomains", 0, NULL, &execdomains_proc_fops); -+ return 0; -+ } -+--- a/kernel/irq/proc.c -++++ b/kernel/irq/proc.c -+@@ -418,6 +418,9 @@ void register_irq_proc(unsigned int irq, -+ void __maybe_unused *irqp = (void *)(unsigned long) irq; -+ char name [MAX_NAMELEN]; -+ -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) -++ return; -++ -+ if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip)) -+ return; -+ -+@@ -471,6 +474,9 @@ void unregister_irq_proc(unsigned int ir -+ { -+ char name [MAX_NAMELEN]; -+ -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) -++ return; -++ -+ if (!root_irq_dir || !desc->dir) -+ return; -+ #ifdef CONFIG_SMP -+@@ -509,6 +515,9 @@ void init_irq_proc(void) -+ unsigned int irq; -+ struct irq_desc *desc; -+ -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) -++ return; -++ -+ /* create /proc/irq */ -+ root_irq_dir = proc_mkdir("irq", NULL); -+ if (!root_irq_dir) -+--- a/kernel/time/timer_list.c -++++ b/kernel/time/timer_list.c -+@@ -390,6 +390,8 @@ static int __init init_timer_list_procfs -+ { -+ struct proc_dir_entry *pe; -+ -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return 0; -+ pe = proc_create("timer_list", 0400, NULL, &timer_list_fops); -+ if (!pe) -+ return -ENOMEM; -+--- a/mm/vmalloc.c -++++ b/mm/vmalloc.c -+@@ -2798,6 +2798,8 @@ static const struct file_operations proc -+ -+ static int __init proc_vmalloc_init(void) -+ { -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return 0; -+ proc_create("vmallocinfo", S_IRUSR, NULL, &proc_vmalloc_operations); -+ return 0; -+ } -+--- a/mm/vmstat.c -++++ b/mm/vmstat.c -+@@ -1951,10 +1951,12 @@ void __init init_mm_internals(void) -+ start_shepherd_timer(); -+ #endif -+ #ifdef CONFIG_PROC_FS -+- proc_create("buddyinfo", 0444, NULL, &buddyinfo_file_operations); -+- proc_create("pagetypeinfo", 0400, NULL, &pagetypeinfo_file_operations); -++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { -++ proc_create("buddyinfo", 0444, NULL, &buddyinfo_file_operations); -++ proc_create("pagetypeinfo", 0400, NULL, &pagetypeinfo_file_operations); -++ proc_create("zoneinfo", 0444, NULL, &zoneinfo_file_operations); -++ } -+ proc_create("vmstat", 0444, NULL, &vmstat_file_operations); -+- proc_create("zoneinfo", 0444, NULL, &zoneinfo_file_operations); -+ #endif -+ } -+ -+--- a/net/8021q/vlanproc.c -++++ b/net/8021q/vlanproc.c -+@@ -127,6 +127,9 @@ void vlan_proc_cleanup(struct net *net) -+ { -+ struct vlan_net *vn = net_generic(net, vlan_net_id); -+ -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return; -++ -+ if (vn->proc_vlan_conf) -+ remove_proc_entry(name_conf, vn->proc_vlan_dir); -+ -+@@ -146,6 +149,9 @@ int __net_init vlan_proc_init(struct net -+ { -+ struct vlan_net *vn = net_generic(net, vlan_net_id); -+ -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return 0; -++ -+ vn->proc_vlan_dir = proc_net_mkdir(net, name_root, net->proc_net); -+ if (!vn->proc_vlan_dir) -+ goto err; -+--- a/net/core/net-procfs.c -++++ b/net/core/net-procfs.c -+@@ -320,10 +320,12 @@ static int __net_init dev_proc_net_init( -+ -+ if (!proc_create("dev", S_IRUGO, net->proc_net, &dev_seq_fops)) -+ goto out; -+- if (!proc_create("softnet_stat", S_IRUGO, net->proc_net, -++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -++ !proc_create("softnet_stat", S_IRUGO, net->proc_net, -+ &softnet_seq_fops)) -+ goto out_dev; -+- if (!proc_create("ptype", S_IRUGO, net->proc_net, &ptype_seq_fops)) -++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -++ !proc_create("ptype", S_IRUGO, net->proc_net, &ptype_seq_fops)) -+ goto out_softnet; -+ -+ if (wext_proc_init(net)) -+@@ -332,9 +334,11 @@ static int __net_init dev_proc_net_init( -+ out: -+ return rc; -+ out_ptype: -+- remove_proc_entry("ptype", net->proc_net); -++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ remove_proc_entry("ptype", net->proc_net); -+ out_softnet: -+- remove_proc_entry("softnet_stat", net->proc_net); -++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ remove_proc_entry("softnet_stat", net->proc_net); -+ out_dev: -+ remove_proc_entry("dev", net->proc_net); -+ goto out; -+@@ -344,8 +348,10 @@ static void __net_exit dev_proc_net_exit -+ { -+ wext_proc_exit(net); -+ -+- remove_proc_entry("ptype", net->proc_net); -+- remove_proc_entry("softnet_stat", net->proc_net); -++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { -++ remove_proc_entry("ptype", net->proc_net); -++ remove_proc_entry("softnet_stat", net->proc_net); -++ } -+ remove_proc_entry("dev", net->proc_net); -+ } -+ -+--- a/net/core/sock.c -++++ b/net/core/sock.c -+@@ -3389,6 +3389,8 @@ static __net_initdata struct pernet_oper -+ -+ static int __init proto_init(void) -+ { -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return 0; -+ return register_pernet_subsys(&proto_net_ops); -+ } -+ -+--- a/net/ipv4/fib_trie.c -++++ b/net/ipv4/fib_trie.c -+@@ -2743,10 +2743,12 @@ static const struct file_operations fib_ -+ -+ int __net_init fib_proc_init(struct net *net) -+ { -+- if (!proc_create("fib_trie", S_IRUGO, net->proc_net, &fib_trie_fops)) -++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -++ !proc_create("fib_trie", S_IRUGO, net->proc_net, &fib_trie_fops)) -+ goto out1; -+ -+- if (!proc_create("fib_triestat", S_IRUGO, net->proc_net, -++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -++ !proc_create("fib_triestat", S_IRUGO, net->proc_net, -+ &fib_triestat_fops)) -+ goto out2; -+ -+@@ -2756,17 +2758,21 @@ int __net_init fib_proc_init(struct net -+ return 0; -+ -+ out3: -+- remove_proc_entry("fib_triestat", net->proc_net); -++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ remove_proc_entry("fib_triestat", net->proc_net); -+ out2: -+- remove_proc_entry("fib_trie", net->proc_net); -++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ remove_proc_entry("fib_trie", net->proc_net); -+ out1: -+ return -ENOMEM; -+ } -+ -+ void __net_exit fib_proc_exit(struct net *net) -+ { -+- remove_proc_entry("fib_trie", net->proc_net); -+- remove_proc_entry("fib_triestat", net->proc_net); -++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { -++ remove_proc_entry("fib_trie", net->proc_net); -++ remove_proc_entry("fib_triestat", net->proc_net); -++ } -+ remove_proc_entry("route", net->proc_net); -+ } -+ -+--- a/net/ipv4/proc.c -++++ b/net/ipv4/proc.c -+@@ -559,6 +559,9 @@ static __net_initdata struct pernet_oper -+ -+ int __init ip_misc_proc_init(void) -+ { -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return 0; -++ -+ return register_pernet_subsys(&ip_proc_ops); -+ } -+ -+--- a/net/ipv4/route.c -++++ b/net/ipv4/route.c -+@@ -426,6 +426,9 @@ static struct pernet_operations ip_rt_pr -+ -+ static int __init ip_rt_proc_init(void) -+ { -++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -++ return 0; -++ -+ return register_pernet_subsys(&ip_rt_proc_ops); -+ } -+ -diff --git a/target/linux/generic/hack-4.14/904-debloat_dma_buf.patch b/target/linux/generic/hack-4.14/904-debloat_dma_buf.patch -new file mode 100644 -index 0000000000..9fd8894225 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/904-debloat_dma_buf.patch -@@ -0,0 +1,64 @@ -+From e3692cb2fcd5ba1244512a0f43b8118f65f1c375 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Sat, 8 Jul 2017 08:20:43 +0200 -+Subject: debloat: dmabuf -+ -+Signed-off-by: Felix Fietkau -+--- -+ drivers/base/Kconfig | 2 +- -+ drivers/dma-buf/Makefile | 10 +++++++--- -+ drivers/dma-buf/dma-buf.c | 4 +++- -+ kernel/sched/core.c | 1 + -+ 4 files changed, 12 insertions(+), 5 deletions(-) -+ -+--- a/drivers/base/Kconfig -++++ b/drivers/base/Kconfig -+@@ -246,7 +246,7 @@ config SOC_BUS -+ source "drivers/base/regmap/Kconfig" -+ -+ config DMA_SHARED_BUFFER -+- bool -++ tristate -+ default n -+ select ANON_INODES -+ select IRQ_WORK -+--- a/drivers/dma-buf/Makefile -++++ b/drivers/dma-buf/Makefile -+@@ -1,3 +1,7 @@ -+-obj-y := dma-buf.o dma-fence.o dma-fence-array.o reservation.o seqno-fence.o -+-obj-$(CONFIG_SYNC_FILE) += sync_file.o -+-obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o -++obj-$(CONFIG_DMA_SHARED_BUFFER) := dma-shared-buffer.o -++ -++dma-buf-objs-y := dma-buf.o dma-fence.o dma-fence-array.o reservation.o seqno-fence.o -++dma-buf-objs-$(CONFIG_SYNC_FILE) += sync_file.o -++dma-buf-objs-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o -++ -++dma-shared-buffer-objs := $(dma-buf-objs-y) -+--- a/drivers/dma-buf/dma-buf.c -++++ b/drivers/dma-buf/dma-buf.c -+@@ -34,6 +34,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include -+ -+@@ -1206,4 +1207,5 @@ static void __exit dma_buf_deinit(void) -+ { -+ dma_buf_uninit_debugfs(); -+ } -+-__exitcall(dma_buf_deinit); -++module_exit(dma_buf_deinit); -++MODULE_LICENSE("GPL"); -+--- a/kernel/sched/core.c -++++ b/kernel/sched/core.c -+@@ -2165,6 +2165,7 @@ int wake_up_state(struct task_struct *p, -+ { -+ return try_to_wake_up(p, state, 0); -+ } -++EXPORT_SYMBOL_GPL(wake_up_state); -+ -+ /* -+ * Perform scheduler related setup for a newly forked process p. -diff --git a/target/linux/generic/hack-4.14/910-kobject_uevent.patch b/target/linux/generic/hack-4.14/910-kobject_uevent.patch -new file mode 100644 -index 0000000000..113fbb54b3 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/910-kobject_uevent.patch -@@ -0,0 +1,32 @@ -+From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Sun, 16 Jul 2017 16:56:10 +0200 -+Subject: lib: add uevent_next_seqnum() -+ -+Signed-off-by: Felix Fietkau -+--- -+ include/linux/kobject.h | 5 +++++ -+ lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++ -+ 2 files changed, 42 insertions(+) -+ -+--- a/lib/kobject_uevent.c -++++ b/lib/kobject_uevent.c -+@@ -176,6 +176,18 @@ out: -+ return r; -+ } -+ -++u64 uevent_next_seqnum(void) -++{ -++ u64 seq; -++ -++ mutex_lock(&uevent_sock_mutex); -++ seq = ++uevent_seqnum; -++ mutex_unlock(&uevent_sock_mutex); -++ -++ return seq; -++} -++EXPORT_SYMBOL_GPL(uevent_next_seqnum); -++ -+ /** -+ * kobject_synth_uevent - send synthetic uevent with arguments -+ * -diff --git a/target/linux/generic/hack-4.14/911-kobject_add_broadcast_uevent.patch b/target/linux/generic/hack-4.14/911-kobject_add_broadcast_uevent.patch -new file mode 100644 -index 0000000000..bf46428854 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/911-kobject_add_broadcast_uevent.patch -@@ -0,0 +1,76 @@ -+From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Sun, 16 Jul 2017 16:56:10 +0200 -+Subject: lib: add uevent_next_seqnum() -+ -+Signed-off-by: Felix Fietkau -+--- -+ include/linux/kobject.h | 5 +++++ -+ lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++ -+ 2 files changed, 42 insertions(+) -+ -+--- a/include/linux/kobject.h -++++ b/include/linux/kobject.h -+@@ -32,6 +32,8 @@ -+ #define UEVENT_NUM_ENVP 32 /* number of env pointers */ -+ #define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */ -+ -++struct sk_buff; -++ -+ #ifdef CONFIG_UEVENT_HELPER -+ /* path to the userspace helper executed on an event */ -+ extern char uevent_helper[]; -+@@ -241,4 +243,7 @@ int kobject_synth_uevent(struct kobject -+ __printf(2, 3) -+ int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...); -+ -++int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, -++ gfp_t allocation); -++ -+ #endif /* _KOBJECT_H_ */ -+--- a/lib/kobject_uevent.c -++++ b/lib/kobject_uevent.c -+@@ -602,6 +602,43 @@ int add_uevent_var(struct kobj_uevent_en -+ EXPORT_SYMBOL_GPL(add_uevent_var); -+ -+ #if defined(CONFIG_NET) -++int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, -++ gfp_t allocation) -++{ -++ struct uevent_sock *ue_sk; -++ int err = 0; -++ -++ /* send netlink message */ -++ mutex_lock(&uevent_sock_mutex); -++ list_for_each_entry(ue_sk, &uevent_sock_list, list) { -++ struct sock *uevent_sock = ue_sk->sk; -++ struct sk_buff *skb2; -++ -++ skb2 = skb_clone(skb, allocation); -++ if (!skb2) -++ break; -++ -++ err = netlink_broadcast(uevent_sock, skb2, pid, group, -++ allocation); -++ if (err) -++ break; -++ } -++ mutex_unlock(&uevent_sock_mutex); -++ -++ kfree_skb(skb); -++ return err; -++} -++#else -++int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, -++ gfp_t allocation) -++{ -++ kfree_skb(skb); -++ return 0; -++} -++#endif -++EXPORT_SYMBOL_GPL(broadcast_uevent); -++ -++#if defined(CONFIG_NET) -+ static int uevent_net_init(struct net *net) -+ { -+ struct uevent_sock *ue_sk; -diff --git a/target/linux/generic/hack-4.14/921-always-create-console-node-in-initramfs.patch b/target/linux/generic/hack-4.14/921-always-create-console-node-in-initramfs.patch -new file mode 100644 -index 0000000000..6eeddcc3c6 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/921-always-create-console-node-in-initramfs.patch -@@ -0,0 +1,40 @@ -+From 5d301596fdc72f6cb672f72eb3c66e7cddefb103 Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Sat, 8 Jul 2017 08:26:02 +0200 -+Subject: initramfs: always create console node -+ -+Signed-off-by: Felix Fietkau -+--- -+ scripts/gen_initramfs_list.sh | 14 ++++++++++++++ -+ 1 file changed, 14 insertions(+) -+ -+--- a/scripts/gen_initramfs_list.sh -++++ b/scripts/gen_initramfs_list.sh -+@@ -59,6 +59,18 @@ default_initramfs() { -+ EOF -+ } -+ -++list_openwrt_initramfs() { -++ : -++} -++ -++openwrt_initramfs() { -++ # make sure that /dev/console exists -++ cat <<-EOF >> ${output} -++ dir /dev 0755 0 0 -++ nod /dev/console 0600 0 0 c 5 1 -++ EOF -++} -++ -+ filetype() { -+ local argv1="$1" -+ -+@@ -180,6 +192,8 @@ dir_filelist() { -+ if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then -+ ${dep_list}print_mtime "$1" -+ -++ ${dep_list}openwrt_initramfs -++ -+ echo "${dirlist}" | \ -+ while read x; do -+ ${dep_list}parse ${x} -diff --git a/target/linux/generic/hack-4.14/930-crashlog.patch b/target/linux/generic/hack-4.14/930-crashlog.patch -new file mode 100644 -index 0000000000..9d09dbd760 ---- /dev/null -+++ b/target/linux/generic/hack-4.14/930-crashlog.patch -@@ -0,0 +1,338 @@ -+From 6b1ab74a9917012d0c559edc4ed299d9228ac89f Mon Sep 17 00:00:00 2001 -+From: Felix Fietkau -+Date: Sat, 8 Jul 2017 08:26:47 +0200 -+Subject: kernel: add the new 'crashlog' feature -+ -+this tries to store kernel oops/panic logs in a fixed location in RAM to -+recover them available to user space using debugfs -+ -+Signed-off-by: Felix Fietkau -+--- -+ include/linux/crashlog.h | 17 ++++ -+ init/Kconfig | 4 + -+ kernel/Makefile | 1 + -+ kernel/crashlog.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++ -+ kernel/module.c | 3 + -+ mm/bootmem.c | 2 + -+ mm/memblock.c | 5 ++ -+ 7 files changed, 245 insertions(+) -+ create mode 100644 include/linux/crashlog.h -+ create mode 100644 kernel/crashlog.c -+ -+--- /dev/null -++++ b/include/linux/crashlog.h -+@@ -0,0 +1,17 @@ -++#ifndef __CRASHLOG_H -++#define __CRASHLOG_H -++ -++#ifdef CONFIG_CRASHLOG -++void crashlog_init_bootmem(struct bootmem_data *bdata); -++void crashlog_init_memblock(phys_addr_t addr, phys_addr_t size); -++#else -++static inline void crashlog_init_bootmem(struct bootmem_data *bdata) -++{ -++} -++ -++static inline void crashlog_init_memblock(phys_addr_t addr, phys_addr_t size) -++{ -++} -++#endif -++ -++#endif -+--- a/init/Kconfig -++++ b/init/Kconfig -+@@ -1009,6 +1009,10 @@ config RELAY -+ -+ If unsure, say N. -+ -++config CRASHLOG -++ bool "Crash logging" -++ depends on (!NO_BOOTMEM || HAVE_MEMBLOCK) -++ -+ config BLK_DEV_INITRD -+ bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" -+ depends on BROKEN || !FRV -+--- a/kernel/Makefile -++++ b/kernel/Makefile -+@@ -110,6 +110,7 @@ obj-$(CONFIG_CONTEXT_TRACKING) += contex -+ obj-$(CONFIG_TORTURE_TEST) += torture.o -+ -+ obj-$(CONFIG_HAS_IOMEM) += memremap.o -++obj-$(CONFIG_CRASHLOG) += crashlog.o -+ -+ $(obj)/configs.o: $(obj)/config_data.h -+ -+--- /dev/null -++++ b/kernel/crashlog.c -+@@ -0,0 +1,213 @@ -++/* -++ * Crash information logger -++ * Copyright (C) 2010 Felix Fietkau -++ * -++ * Based on ramoops.c -++ * Copyright (C) 2010 Marco Stornelli -++ * -++ * This program is free software; you can redistribute it and/or -++ * modify it under the terms of the GNU General Public License -++ * version 2 as published by the Free Software Foundation. -++ * -++ * This program is distributed in the hope that it will be useful, but -++ * WITHOUT ANY WARRANTY; without even the implied warranty of -++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -++ * General Public License for more details. -++ * -++ * 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 -++ -++#define CRASHLOG_PAGES 4 -++#define CRASHLOG_SIZE (CRASHLOG_PAGES * PAGE_SIZE) -++#define CRASHLOG_MAGIC 0xa1eedead -++ -++/* -++ * Start the log at 1M before the end of RAM, as some boot loaders like -++ * to use the end of the RAM for stack usage and other things -++ * If this fails, fall back to using the last part. -++ */ -++#define CRASHLOG_OFFSET (1024 * 1024) -++ -++struct crashlog_data { -++ u32 magic; -++ u32 len; -++ u8 data[]; -++}; -++ -++static struct debugfs_blob_wrapper crashlog_blob; -++static unsigned long crashlog_addr = 0; -++static struct crashlog_data *crashlog_buf; -++static struct kmsg_dumper dump; -++static bool first = true; -++ -++extern struct list_head *crashlog_modules; -++ -++static bool crashlog_set_addr(phys_addr_t addr, phys_addr_t size) -++{ -++ /* Limit to lower 64 MB to avoid highmem */ -++ phys_addr_t limit = 64 * 1024 * 1024; -++ -++ if (crashlog_addr) -++ return false; -++ -++ if (addr > limit) -++ return false; -++ -++ if (addr + size > limit) -++ size = limit - addr; -++ -++ crashlog_addr = addr; -++ -++ if (addr + size > CRASHLOG_OFFSET) -++ crashlog_addr += size - CRASHLOG_OFFSET; -++ -++ return true; -++} -++ -++#ifndef CONFIG_NO_BOOTMEM -++void __init crashlog_init_bootmem(bootmem_data_t *bdata) -++{ -++ phys_addr_t start, end; -++ -++ start = PFN_PHYS(bdata->node_low_pfn); -++ end = PFN_PHYS(bdata->node_min_pfn); -++ if (!crashlog_set_addr(start, end - start)) -++ return; -++ -++ if (reserve_bootmem(crashlog_addr, CRASHLOG_SIZE, BOOTMEM_EXCLUSIVE) < 0) { -++ printk("Crashlog failed to allocate RAM at address 0x%lx\n", -++ crashlog_addr); -++ crashlog_addr = 0; -++ } -++} -++#endif -++ -++#ifdef CONFIG_HAVE_MEMBLOCK -++void __init_memblock crashlog_init_memblock(phys_addr_t addr, phys_addr_t size) -++{ -++ if (!crashlog_set_addr(addr, size)) -++ return; -++ -++ if (memblock_reserve(crashlog_addr, CRASHLOG_SIZE)) { -++ printk("Crashlog failed to allocate RAM at address 0x%lx\n", -++ crashlog_addr); -++ crashlog_addr = 0; -++ } -++} -++#endif -++ -++static void __init crashlog_copy(void) -++{ -++ if (crashlog_buf->magic != CRASHLOG_MAGIC) -++ return; -++ -++ if (!crashlog_buf->len || crashlog_buf->len > -++ CRASHLOG_SIZE - sizeof(*crashlog_buf)) -++ return; -++ -++ crashlog_blob.size = crashlog_buf->len; -++ crashlog_blob.data = kmemdup(crashlog_buf->data, -++ crashlog_buf->len, GFP_KERNEL); -++ -++ debugfs_create_blob("crashlog", 0700, NULL, &crashlog_blob); -++} -++ -++static int get_maxlen(void) -++{ -++ return CRASHLOG_SIZE - sizeof(*crashlog_buf) - crashlog_buf->len; -++} -++ -++static void crashlog_printf(const char *fmt, ...) -++{ -++ va_list args; -++ int len = get_maxlen(); -++ -++ if (!len) -++ return; -++ -++ va_start(args, fmt); -++ crashlog_buf->len += vscnprintf( -++ &crashlog_buf->data[crashlog_buf->len], -++ len, fmt, args); -++ va_end(args); -++} -++ -++static void crashlog_do_dump(struct kmsg_dumper *dumper, -++ enum kmsg_dump_reason reason) -++{ -++ struct timeval tv; -++ struct module *m; -++ char *buf; -++ size_t len; -++ -++ if (!first) -++ crashlog_printf("\n===================================\n"); -++ -++ do_gettimeofday(&tv); -++ crashlog_printf("Time: %lu.%lu\n", -++ (long)tv.tv_sec, (long)tv.tv_usec); -++ -++ if (first) { -++ crashlog_printf("Modules:"); -++ list_for_each_entry(m, crashlog_modules, list) { -++ crashlog_printf("\t%s@%p+%x", m->name, -++ m->core_layout.base, m->core_layout.size, -++ m->init_layout.base, m->init_layout.size); -++ } -++ crashlog_printf("\n"); -++ first = false; -++ } -++ -++ buf = (char *)&crashlog_buf->data[crashlog_buf->len]; -++ -++ kmsg_dump_get_buffer(dumper, true, buf, get_maxlen(), &len); -++ -++ crashlog_buf->len += len; -++} -++ -++ -++int __init crashlog_init_fs(void) -++{ -++ struct page *pages[CRASHLOG_PAGES]; -++ pgprot_t prot; -++ int i; -++ -++ if (!crashlog_addr) { -++ printk("No memory allocated for crashlog\n"); -++ return -ENOMEM; -++ } -++ -++ printk("Crashlog allocated RAM at address 0x%lx\n", (unsigned long) crashlog_addr); -++ for (i = 0; i < CRASHLOG_PAGES; i++) -++ pages[i] = pfn_to_page((crashlog_addr >> PAGE_SHIFT) + i); -++ -++ prot = pgprot_writecombine(PAGE_KERNEL); -++ crashlog_buf = vmap(pages, CRASHLOG_PAGES, VM_MAP, prot); -++ -++ crashlog_copy(); -++ -++ crashlog_buf->magic = CRASHLOG_MAGIC; -++ crashlog_buf->len = 0; -++ -++ dump.max_reason = KMSG_DUMP_OOPS; -++ dump.dump = crashlog_do_dump; -++ kmsg_dump_register(&dump); -++ -++ return 0; -++} -++module_init(crashlog_init_fs); -+--- a/kernel/module.c -++++ b/kernel/module.c -+@@ -256,6 +256,9 @@ static void mod_update_bounds(struct mod -+ #ifdef CONFIG_KGDB_KDB -+ struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ -+ #endif /* CONFIG_KGDB_KDB */ -++#ifdef CONFIG_CRASHLOG -++struct list_head *crashlog_modules = &modules; -++#endif -+ -+ static void module_assert_mutex(void) -+ { -+--- a/mm/bootmem.c -++++ b/mm/bootmem.c -+@@ -15,6 +15,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ #include -+@@ -175,6 +176,7 @@ static unsigned long __init free_all_boo -+ if (!bdata->node_bootmem_map) -+ return 0; -+ -++ crashlog_init_bootmem(bdata); -+ map = bdata->node_bootmem_map; -+ start = bdata->node_min_pfn; -+ end = bdata->node_low_pfn; -+--- a/mm/memblock.c -++++ b/mm/memblock.c -+@@ -19,6 +19,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include -+ #include -+@@ -483,6 +484,8 @@ static void __init_memblock memblock_ins -+ memblock_set_region_node(rgn, nid); -+ type->cnt++; -+ type->total_size += size; -++ if (type == &memblock.memory) -++ crashlog_init_memblock(base, size); -+ } -+ -+ /** -+@@ -522,6 +525,8 @@ int __init_memblock memblock_add_range(s -+ type->regions[0].flags = flags; -+ memblock_set_region_node(&type->regions[0], nid); -+ type->total_size = size; -++ if (type == &memblock.memory) -++ crashlog_init_memblock(base, size); -+ return 0; -+ } -+ repeat: -diff --git a/target/linux/generic/pending-4.14/0931-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch b/target/linux/generic/pending-4.14/0931-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch -new file mode 100644 -index 0000000000..0c4a13f9df ---- /dev/null -+++ b/target/linux/generic/pending-4.14/0931-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch -@@ -0,0 +1,38 @@ -+From d9c8bc8c1408f3e8529db6e4e04017b4c579c342 Mon Sep 17 00:00:00 2001 -+From: Pawel Dembicki -+Date: Sun, 18 Feb 2018 17:08:04 +0100 -+Subject: [PATCH] w1: gpio: fix problem with platfom data in w1-gpio -+ -+In devices, where fdt is used, is impossible to apply platform data -+without proper fdt node. -+ -+This patch allow to use platform data in devices with fdt. -+ -+Signed-off-by: Pawel Dembicki -+--- -+ drivers/w1/masters/w1-gpio.c | 7 +++---- -+ 1 file changed, 3 insertions(+), 4 deletions(-) -+ -+--- a/drivers/w1/masters/w1-gpio.c -++++ b/drivers/w1/masters/w1-gpio.c -+@@ -112,17 +112,16 @@ static int w1_gpio_probe_dt(struct platf -+ static int w1_gpio_probe(struct platform_device *pdev) -+ { -+ struct w1_bus_master *master; -+- struct w1_gpio_platform_data *pdata; -++ struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); -+ int err; -+ -+- if (of_have_populated_dt()) { -++ if (of_have_populated_dt() && !pdata) { -+ err = w1_gpio_probe_dt(pdev); -+ if (err < 0) -+ return err; -++ pdata = dev_get_platdata(&pdev->dev); -+ } -+ -+- pdata = dev_get_platdata(&pdev->dev); -+- -+ if (!pdata) { -+ dev_err(&pdev->dev, "No configuration data\n"); -+ return -ENXIO; -diff --git a/target/linux/generic/pending-4.14/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch b/target/linux/generic/pending-4.14/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch -new file mode 100644 -index 0000000000..92e86b24e7 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch -@@ -0,0 +1,57 @@ -+From: Felix Fietkau -+Date: Wed, 18 Apr 2018 10:50:05 +0200 -+Subject: [PATCH] MIPS: only process negative stack offsets on stack traces -+ -+Fixes endless back traces in cases where the compiler emits a stack -+pointer increase in a branch delay slot (probably for some form of -+function return). -+ -+[ 3.475442] BUG: MAX_STACK_TRACE_ENTRIES too low! -+[ 3.480070] turning off the locking correctness validator. -+[ 3.485521] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.14.34 #0 -+[ 3.491475] Stack : 00000000 00000000 00000000 00000000 80e0fce2 00000034 00000000 00000000 -+[ 3.499764] 87c3838c 80696377 8061047c 00000000 00000001 00000001 87c2d850 6534689f -+[ 3.508059] 00000000 00000000 80e10000 00000000 00000000 000000cf 0000000f 00000000 -+[ 3.516353] 00000000 806a0000 00076891 00000000 00000000 00000000 ffffffff 00000000 -+[ 3.524648] 806c0000 00000004 80e10000 806a0000 00000003 80690000 00000000 80700000 -+[ 3.532942] ... -+[ 3.535362] Call Trace: -+[ 3.537818] [<80010a48>] show_stack+0x58/0x100 -+[ 3.542207] [<804c2f78>] dump_stack+0xe8/0x170 -+[ 3.546613] [<80079f90>] save_trace+0xf0/0x110 -+[ 3.551010] [<8007b1ec>] mark_lock+0x33c/0x78c -+[ 3.555413] [<8007bf48>] __lock_acquire+0x2ac/0x1a08 -+[ 3.560337] [<8007de60>] lock_acquire+0x64/0x8c -+[ 3.564846] [<804e1570>] _raw_spin_lock_irqsave+0x54/0x78 -+[ 3.570186] [<801b618c>] kernfs_notify+0x94/0xac -+[ 3.574770] [<801b7b10>] sysfs_notify+0x74/0xa0 -+[ 3.579257] [<801b618c>] kernfs_notify+0x94/0xac -+[ 3.583839] [<801b7b10>] sysfs_notify+0x74/0xa0 -+[ 3.588329] [<801b618c>] kernfs_notify+0x94/0xac -+[ 3.592911] [<801b7b10>] sysfs_notify+0x74/0xa0 -+[ 3.597401] [<801b618c>] kernfs_notify+0x94/0xac -+[ 3.601983] [<801b7b10>] sysfs_notify+0x74/0xa0 -+[ 3.606473] [<801b618c>] kernfs_notify+0x94/0xac -+[ 3.611055] [<801b7b10>] sysfs_notify+0x74/0xa0 -+[ 3.615545] [<801b618c>] kernfs_notify+0x94/0xac -+[ 3.620125] [<801b7b10>] sysfs_notify+0x74/0xa0 -+[ 3.624619] [<801b618c>] kernfs_notify+0x94/0xac -+[ 3.629197] [<801b7b10>] sysfs_notify+0x74/0xa0 -+[ 3.633691] [<801b618c>] kernfs_notify+0x94/0xac -+[ 3.638269] [<801b7b10>] sysfs_notify+0x74/0xa0 -+[ 3.642763] [<801b618c>] kernfs_notify+0x94/0xac -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/arch/mips/kernel/process.c -++++ b/arch/mips/kernel/process.c -+@@ -360,6 +360,8 @@ static inline int is_sp_move_ins(union m -+ -+ if (ip->i_format.opcode == addiu_op || -+ ip->i_format.opcode == daddiu_op) { -++ if (ip->i_format.simmediate > 0) -++ return 0; -+ *frame_size = -ip->i_format.simmediate; -+ return 1; -+ } -diff --git a/target/linux/generic/pending-4.14/103-MIPS-perf-ath79-Fix-perfcount-IRQ-assignment.patch b/target/linux/generic/pending-4.14/103-MIPS-perf-ath79-Fix-perfcount-IRQ-assignment.patch -new file mode 100644 -index 0000000000..1990e87055 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/103-MIPS-perf-ath79-Fix-perfcount-IRQ-assignment.patch -@@ -0,0 +1,110 @@ -+From 852a88f35f4b7e5ebb717fed3c3a3330d5ad4336 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Petr=20=C5=A0tetiar?= -+Date: Wed, 10 Apr 2019 16:43:27 +0200 -+Subject: [PATCH v2] MIPS: perf: ath79: Fix perfcount IRQ assignment -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+Currently it's not possible to use perf on ath79 due to genirq flags -+mismatch happening on static virtual IRQ 13 which is used for -+performance counters hardware IRQ 5. -+ -+On TP-Link Archer C7v5: -+ -+ CPU0 -+ 2: 0 MIPS 2 ath9k -+ 4: 318 MIPS 4 19000000.eth -+ 7: 55034 MIPS 7 timer -+ 8: 1236 MISC 3 ttyS0 -+ 12: 0 INTC 1 ehci_hcd:usb1 -+ 13: 0 gpio-ath79 2 keys -+ 14: 0 gpio-ath79 5 keys -+ 15: 31 AR724X PCI 1 ath10k_pci -+ -+ $ perf top -+ genirq: Flags mismatch irq 13. 00014c83 (mips_perf_pmu) vs. 00002003 (keys) -+ -+On TP-Link Archer C7v4: -+ -+ CPU0 -+ 4: 0 MIPS 4 19000000.eth -+ 5: 7135 MIPS 5 1a000000.eth -+ 7: 98379 MIPS 7 timer -+ 8: 30 MISC 3 ttyS0 -+ 12: 90028 INTC 0 ath9k -+ 13: 5520 INTC 1 ehci_hcd:usb1 -+ 14: 4623 INTC 2 ehci_hcd:usb2 -+ 15: 32844 AR724X PCI 1 ath10k_pci -+ 16: 0 gpio-ath79 16 keys -+ 23: 0 gpio-ath79 23 keys -+ -+ $ perf top -+ genirq: Flags mismatch irq 13. 00014c80 (mips_perf_pmu) vs. 00000080 (ehci_hcd:usb1) -+ -+This problem is happening, because currently statically assigned virtual -+IRQ 13 for performance counters is not claimed during the initialization -+of MIPS PMU during the bootup, so the IRQ subsystem doesn't know, that -+this interrupt isn't available for further use. -+ -+So this patch fixes the issue by simply booking hardware IRQ 5 for MIPS PMU. -+ -+Tested-by: Kevin 'ldir' Darbyshire-Bryant -+Signed-off-by: Petr Štetiar -+--- -+ -+Changes since v1: -+ -+ I've incorporated two comments which I've received on IRC from blogic and -+ I've also reworded the commit message to match the changes in v2 of this -+ patch. -+ -+ * use actual hardware perfcount IRQ 5 instead of the virtual IRQ 13 -+ * dropped the CONFIG_PERF_EVENTS ifdef around irq_create_mapping -+ -+ arch/mips/ath79/setup.c | 6 ------ -+ drivers/irqchip/irq-ath79-misc.c | 11 +++++++++++ -+ 2 files changed, 11 insertions(+), 6 deletions(-) -+ -+--- a/arch/mips/ath79/setup.c -++++ b/arch/mips/ath79/setup.c -+@@ -183,12 +183,6 @@ const char *get_system_type(void) -+ return ath79_sys_type; -+ } -+ -+-int get_c0_perfcount_int(void) -+-{ -+- return ATH79_MISC_IRQ(5); -+-} -+-EXPORT_SYMBOL_GPL(get_c0_perfcount_int); -+- -+ unsigned int get_c0_compare_int(void) -+ { -+ return CP0_LEGACY_COMPARE_IRQ; -+--- a/drivers/irqchip/irq-ath79-misc.c -++++ b/drivers/irqchip/irq-ath79-misc.c -+@@ -22,6 +22,15 @@ -+ #define AR71XX_RESET_REG_MISC_INT_ENABLE 4 -+ -+ #define ATH79_MISC_IRQ_COUNT 32 -++#define ATH79_MISC_PERF_IRQ 5 -++ -++static int ath79_perfcount_irq; -++ -++int get_c0_perfcount_int(void) -++{ -++ return ath79_perfcount_irq; -++} -++EXPORT_SYMBOL_GPL(get_c0_perfcount_int); -+ -+ static void ath79_misc_irq_handler(struct irq_desc *desc) -+ { -+@@ -113,6 +122,8 @@ static void __init ath79_misc_intc_domai -+ { -+ void __iomem *base = domain->host_data; -+ -++ ath79_perfcount_irq = irq_create_mapping(domain, ATH79_MISC_PERF_IRQ); -++ -+ /* Disable and clear all interrupts */ -+ __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE); -+ __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); -diff --git a/target/linux/generic/pending-4.14/110-ehci_hcd_ignore_oc.patch b/target/linux/generic/pending-4.14/110-ehci_hcd_ignore_oc.patch -new file mode 100644 -index 0000000000..b45b1c079c ---- /dev/null -+++ b/target/linux/generic/pending-4.14/110-ehci_hcd_ignore_oc.patch -@@ -0,0 +1,79 @@ -+From: Florian Fainelli -+Subject: USB: EHCI: add ignore_oc flag to disable overcurrent checking -+ -+This patch adds an ignore_oc flag which can be set by EHCI controller -+not supporting or wanting to disable overcurrent checking. The EHCI -+platform data in include/linux/usb/ehci_pdriver.h is also augmented to -+take advantage of this new flag. -+ -+Signed-off-by: Florian Fainelli -+--- -+ drivers/usb/host/ehci-hcd.c | 2 +- -+ drivers/usb/host/ehci-hub.c | 4 ++-- -+ drivers/usb/host/ehci-platform.c | 1 + -+ drivers/usb/host/ehci.h | 1 + -+ include/linux/usb/ehci_pdriver.h | 1 + -+ 5 files changed, 6 insertions(+), 3 deletions(-) -+ -+--- a/drivers/usb/host/ehci-hcd.c -++++ b/drivers/usb/host/ehci-hcd.c -+@@ -651,7 +651,7 @@ static int ehci_run (struct usb_hcd *hcd -+ "USB %x.%x started, EHCI %x.%02x%s\n", -+ ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), -+ temp >> 8, temp & 0xff, -+- ignore_oc ? ", overcurrent ignored" : ""); -++ (ignore_oc || ehci->ignore_oc) ? ", overcurrent ignored" : ""); -+ -+ ehci_writel(ehci, INTR_MASK, -+ &ehci->regs->intr_enable); /* Turn On Interrupts */ -+--- a/drivers/usb/host/ehci-hub.c -++++ b/drivers/usb/host/ehci-hub.c -+@@ -646,7 +646,7 @@ ehci_hub_status_data (struct usb_hcd *hc -+ * always set, seem to clear PORT_OCC and PORT_CSC when writing to -+ * PORT_POWER; that's surprising, but maybe within-spec. -+ */ -+- if (!ignore_oc) -++ if (!ignore_oc && !ehci->ignore_oc) -+ mask = PORT_CSC | PORT_PEC | PORT_OCC; -+ else -+ mask = PORT_CSC | PORT_PEC; -+@@ -1016,7 +1016,7 @@ int ehci_hub_control( -+ if (temp & PORT_PEC) -+ status |= USB_PORT_STAT_C_ENABLE << 16; -+ -+- if ((temp & PORT_OCC) && !ignore_oc){ -++ if ((temp & PORT_OCC) && (!ignore_oc && !ehci->ignore_oc)){ -+ status |= USB_PORT_STAT_C_OVERCURRENT << 16; -+ -+ /* -+--- a/drivers/usb/host/ehci-platform.c -++++ b/drivers/usb/host/ehci-platform.c -+@@ -263,6 +263,8 @@ static int ehci_platform_probe(struct pl -+ hcd->has_tt = 1; -+ if (pdata->reset_on_resume) -+ priv->reset_on_resume = true; -++ if (pdata->ignore_oc) -++ ehci->ignore_oc = 1; -+ -+ #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO -+ if (ehci->big_endian_mmio) { -+--- a/drivers/usb/host/ehci.h -++++ b/drivers/usb/host/ehci.h -+@@ -231,6 +231,7 @@ struct ehci_hcd { /* one per controlle -+ unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */ -+ unsigned need_oc_pp_cycle:1; /* MPC834X port power */ -+ unsigned imx28_write_fix:1; /* For Freescale i.MX28 */ -++ unsigned ignore_oc:1; -+ -+ /* required for usb32 quirk */ -+ #define OHCI_CTRL_HCFS (3 << 6) -+--- a/include/linux/usb/ehci_pdriver.h -++++ b/include/linux/usb/ehci_pdriver.h -+@@ -49,6 +49,7 @@ struct usb_ehci_pdata { -+ unsigned no_io_watchdog:1; -+ unsigned reset_on_resume:1; -+ unsigned dma_mask_64:1; -++ unsigned ignore_oc:1; -+ -+ /* Turn on all power and clocks */ -+ int (*power_on)(struct platform_device *pdev); -diff --git a/target/linux/generic/pending-4.14/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch b/target/linux/generic/pending-4.14/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch -new file mode 100644 -index 0000000000..44e7fa70a3 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch -@@ -0,0 +1,82 @@ -+From: Tobias Wolf -+Subject: mm: Fix alloc_node_mem_map with ARCH_PFN_OFFSET calculation -+ -+An rt288x (ralink) based router (Belkin F5D8235 v1) does not boot with any -+kernel beyond version 4.3 resulting in: -+ -+BUG: Bad page state in process swapper pfn:086ac -+ -+bisect resulted in: -+ -+a1c34a3bf00af2cede839879502e12dc68491ad5 is the first bad commit -+commit a1c34a3bf00af2cede839879502e12dc68491ad5 -+Author: Laura Abbott -+Date: Thu Nov 5 18:48:46 2015 -0800 -+ -+ mm: Don't offset memmap for flatmem -+ -+ Srinivas Kandagatla reported bad page messages when trying to remove the -+ bottom 2MB on an ARM based IFC6410 board -+ -+ BUG: Bad page state in process swapper pfn:fffa8 -+ page:ef7fb500 count:0 mapcount:0 mapping: (null) index:0x0 -+ flags: 0x96640253(locked|error|dirty|active|arch_1|reclaim|mlocked) -+ page dumped because: PAGE_FLAGS_CHECK_AT_FREE flag(s) set -+ bad because of flags: -+ flags: 0x200041(locked|active|mlocked) -+ Modules linked in: -+ CPU: 0 PID: 0 Comm: swapper Not tainted 3.19.0-rc3-00007-g412f9ba-dirty -+#816 -+ Hardware name: Qualcomm (Flattened Device Tree) -+ unwind_backtrace -+ show_stack -+ dump_stack -+ bad_page -+ free_pages_prepare -+ free_hot_cold_page -+ __free_pages -+ free_highmem_page -+ mem_init -+ start_kernel -+ Disabling lock debugging due to kernel taint -+ [...] -+:040000 040000 2de013c372345fd471cd58f0553c9b38b0ef1cc4 -+0a8156f848733dfa21e16c196dfb6c0a76290709 M mm -+ -+This fix for ARM does not account ARCH_PFN_OFFSET for mem_map as later used by -+page_to_pfn anymore. -+ -+The following output was generated with two hacked in printk statements: -+ -+printk("before %p vs. %p or %p\n", mem_map, mem_map - offset, mem_map - -+(pgdat->node_start_pfn - ARCH_PFN_OFFSET)); -+ if (page_to_pfn(mem_map) != pgdat->node_start_pfn) -+ mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET); -+printk("after %p\n", mem_map); -+ -+Output: -+ -+[ 0.000000] before 8861b280 vs. 8861b280 or 8851b280 -+[ 0.000000] after 8851b280 -+ -+As seen in the first line mem_map with subtraction of offset does not equal the -+mem_map after subtraction of ARCH_PFN_OFFSET. -+ -+After adding the offset of ARCH_PFN_OFFSET as well to mem_map as the -+previously calculated offset is zero for the named platform it is able to boot -+4.4 and 4.9-rc7 again. -+ -+Signed-off-by: Tobias Wolf -+--- -+ -+--- a/mm/page_alloc.c -++++ b/mm/page_alloc.c -+@@ -6146,7 +6146,7 @@ static void __ref alloc_node_mem_map(str -+ mem_map = NODE_DATA(0)->node_mem_map; -+ #if defined(CONFIG_HAVE_MEMBLOCK_NODE_MAP) || defined(CONFIG_FLATMEM) -+ if (page_to_pfn(mem_map) != pgdat->node_start_pfn) -+- mem_map -= offset; -++ mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET); -+ #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */ -+ } -+ #endif -diff --git a/target/linux/generic/pending-4.14/130-add-linux-spidev-compatible-si3210.patch b/target/linux/generic/pending-4.14/130-add-linux-spidev-compatible-si3210.patch -new file mode 100644 -index 0000000000..3a42182c97 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/130-add-linux-spidev-compatible-si3210.patch -@@ -0,0 +1,18 @@ -+From: Giuseppe Lippolis -+Subject: Add the linux,spidev compatible in spidev Several device in ramips have this binding in the dts -+ -+Signed-off-by: Giuseppe Lippolis -+--- -+ drivers/spi/spidev.c | 1 + -+ 1 file changed, 1 insertion(+) -+ -+--- a/drivers/spi/spidev.c -++++ b/drivers/spi/spidev.c -+@@ -672,6 +672,7 @@ static const struct of_device_id spidev_ -+ { .compatible = "lineartechnology,ltc2488" }, -+ { .compatible = "ge,achc" }, -+ { .compatible = "semtech,sx1301" }, -++ { .compatible = "siliconlabs,si3210" }, -+ {}, -+ }; -+ MODULE_DEVICE_TABLE(of, spidev_dt_ids); -diff --git a/target/linux/generic/pending-4.14/131-spi-use-gpio_set_value_cansleep-for-setting-chipsele.patch b/target/linux/generic/pending-4.14/131-spi-use-gpio_set_value_cansleep-for-setting-chipsele.patch -new file mode 100644 -index 0000000000..9603385aed ---- /dev/null -+++ b/target/linux/generic/pending-4.14/131-spi-use-gpio_set_value_cansleep-for-setting-chipsele.patch -@@ -0,0 +1,20 @@ -+From: Felix Fietkau -+Subject: spi: use gpio_set_value_cansleep for setting chipselect GPIO -+ -+Sleeping is safe inside spi_transfer_one_message, and some GPIO chips -+need to sleep for setting values -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/spi/spi.c -++++ b/drivers/spi/spi.c -+@@ -729,7 +729,7 @@ static void spi_set_cs(struct spi_device -+ enable = !enable; -+ -+ if (gpio_is_valid(spi->cs_gpio)) { -+- gpio_set_value(spi->cs_gpio, !enable); -++ gpio_set_value_cansleep(spi->cs_gpio, !enable); -+ /* Some SPI masters need both GPIO CS & slave_select */ -+ if ((spi->controller->flags & SPI_MASTER_GPIO_SS) && -+ spi->controller->set_cs) -diff --git a/target/linux/generic/pending-4.14/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch b/target/linux/generic/pending-4.14/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch -new file mode 100644 -index 0000000000..c97e93250b ---- /dev/null -+++ b/target/linux/generic/pending-4.14/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch -@@ -0,0 +1,62 @@ -+From: Felix Fietkau -+Subject: jffs2: use .rename2 and add RENAME_WHITEOUT support -+ -+It is required for renames on overlayfs -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/fs/jffs2/dir.c -++++ b/fs/jffs2/dir.c -+@@ -752,6 +752,24 @@ static int jffs2_mknod (struct inode *di -+ return ret; -+ } -+ -++static int jffs2_whiteout (struct inode *old_dir, struct dentry *old_dentry) -++{ -++ struct dentry *wh; -++ int err; -++ -++ wh = d_alloc(old_dentry->d_parent, &old_dentry->d_name); -++ if (!wh) -++ return -ENOMEM; -++ -++ err = jffs2_mknod(old_dir, wh, S_IFCHR | WHITEOUT_MODE, -++ WHITEOUT_DEV); -++ if (err) -++ return err; -++ -++ d_rehash(wh); -++ return 0; -++} -++ -+ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, -+ struct inode *new_dir_i, struct dentry *new_dentry, -+ unsigned int flags) -+@@ -762,7 +780,7 @@ static int jffs2_rename (struct inode *o -+ uint8_t type; -+ uint32_t now; -+ -+- if (flags & ~RENAME_NOREPLACE) -++ if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT)) -+ return -EINVAL; -+ -+ /* The VFS will check for us and prevent trying to rename a -+@@ -828,9 +846,14 @@ static int jffs2_rename (struct inode *o -+ if (d_is_dir(old_dentry) && !victim_f) -+ inc_nlink(new_dir_i); -+ -+- /* Unlink the original */ -+- ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), -+- old_dentry->d_name.name, old_dentry->d_name.len, NULL, now); -++ if (flags & RENAME_WHITEOUT) -++ /* Replace with whiteout */ -++ ret = jffs2_whiteout(old_dir_i, old_dentry); -++ else -++ /* Unlink the original */ -++ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), -++ old_dentry->d_name.name, -++ old_dentry->d_name.len, NULL, now); -+ -+ /* We don't touch inode->i_nlink */ -+ -diff --git a/target/linux/generic/pending-4.14/141-jffs2-add-RENAME_EXCHANGE-support.patch b/target/linux/generic/pending-4.14/141-jffs2-add-RENAME_EXCHANGE-support.patch -new file mode 100644 -index 0000000000..093a73ab66 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/141-jffs2-add-RENAME_EXCHANGE-support.patch -@@ -0,0 +1,73 @@ -+From: Felix Fietkau -+Subject: jffs2: add RENAME_EXCHANGE support -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/fs/jffs2/dir.c -++++ b/fs/jffs2/dir.c -+@@ -777,18 +777,31 @@ static int jffs2_rename (struct inode *o -+ int ret; -+ struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); -+ struct jffs2_inode_info *victim_f = NULL; -++ struct inode *fst_inode = d_inode(old_dentry); -++ struct inode *snd_inode = d_inode(new_dentry); -+ uint8_t type; -+ uint32_t now; -+ -+- if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT)) -++ if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT|RENAME_EXCHANGE)) -+ return -EINVAL; -+ -++ if ((flags & RENAME_EXCHANGE) && (old_dir_i != new_dir_i)) { -++ if (S_ISDIR(fst_inode->i_mode) && !S_ISDIR(snd_inode->i_mode)) { -++ inc_nlink(new_dir_i); -++ drop_nlink(old_dir_i); -++ } -++ else if (!S_ISDIR(fst_inode->i_mode) && S_ISDIR(snd_inode->i_mode)) { -++ drop_nlink(new_dir_i); -++ inc_nlink(old_dir_i); -++ } -++ } -++ -+ /* The VFS will check for us and prevent trying to rename a -+ * file over a directory and vice versa, but if it's a directory, -+ * the VFS can't check whether the victim is empty. The filesystem -+ * needs to do that for itself. -+ */ -+- if (d_really_is_positive(new_dentry)) { -++ if (d_really_is_positive(new_dentry) && !(flags & RENAME_EXCHANGE)) { -+ victim_f = JFFS2_INODE_INFO(d_inode(new_dentry)); -+ if (d_is_dir(new_dentry)) { -+ struct jffs2_full_dirent *fd; -+@@ -823,7 +836,7 @@ static int jffs2_rename (struct inode *o -+ if (ret) -+ return ret; -+ -+- if (victim_f) { -++ if (victim_f && !(flags & RENAME_EXCHANGE)) { -+ /* There was a victim. Kill it off nicely */ -+ if (d_is_dir(new_dentry)) -+ clear_nlink(d_inode(new_dentry)); -+@@ -849,6 +862,12 @@ static int jffs2_rename (struct inode *o -+ if (flags & RENAME_WHITEOUT) -+ /* Replace with whiteout */ -+ ret = jffs2_whiteout(old_dir_i, old_dentry); -++ else if (flags & RENAME_EXCHANGE) -++ /* Replace the original */ -++ ret = jffs2_do_link(c, JFFS2_INODE_INFO(old_dir_i), -++ d_inode(new_dentry)->i_ino, type, -++ old_dentry->d_name.name, old_dentry->d_name.len, -++ now); -+ else -+ /* Unlink the original */ -+ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), -+@@ -880,7 +899,7 @@ static int jffs2_rename (struct inode *o -+ return ret; -+ } -+ -+- if (d_is_dir(old_dentry)) -++ if (d_is_dir(old_dentry) && !(flags & RENAME_EXCHANGE)) -+ drop_nlink(old_dir_i); -+ -+ new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now); -diff --git a/target/linux/generic/pending-4.14/150-bridge_allow_receiption_on_disabled_port.patch b/target/linux/generic/pending-4.14/150-bridge_allow_receiption_on_disabled_port.patch -new file mode 100644 -index 0000000000..d50280a881 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/150-bridge_allow_receiption_on_disabled_port.patch -@@ -0,0 +1,47 @@ -+From: Stephen Hemminger -+Subject: bridge: allow receiption on disabled port -+ -+When an ethernet device is enslaved to a bridge, and the bridge STP -+detects loss of carrier (or operational state down), then normally -+packet receiption is blocked. -+ -+This breaks control applications like WPA which maybe expecting to -+receive packets to negotiate to bring link up. The bridge needs to -+block forwarding packets from these disabled ports, but there is no -+hard requirement to not allow local packet delivery. -+ -+Signed-off-by: Stephen Hemminger -+Signed-off-by: Felix Fietkau -+ -+--- a/net/bridge/br_input.c -++++ b/net/bridge/br_input.c -+@@ -237,7 +237,10 @@ static void __br_handle_local_finish(str -+ /* note: already called with rcu_read_lock */ -+ static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb) -+ { -+- __br_handle_local_finish(skb); -++ struct net_bridge_port *p = br_port_get_rcu(skb->dev); -++ -++ if (p->state != BR_STATE_DISABLED) -++ __br_handle_local_finish(skb); -+ -+ /* return 1 to signal the okfn() was called so it's ok to use the skb */ -+ return 1; -+@@ -332,6 +335,17 @@ rx_handler_result_t br_handle_frame(stru -+ -+ forward: -+ switch (p->state) { -++ case BR_STATE_DISABLED: -++ if (ether_addr_equal(p->br->dev->dev_addr, dest)) -++ skb->pkt_type = PACKET_HOST; -++ -++ if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, -++ dev_net(skb->dev), NULL, skb, skb->dev, NULL, -++ br_handle_local_finish) == 1) { -++ return RX_HANDLER_PASS; -++ } -++ break; -++ -+ case BR_STATE_FORWARDING: -+ rhook = rcu_dereference(br_should_route_hook); -+ if (rhook) { -diff --git a/target/linux/generic/pending-4.14/161-mtd-part-add-generic-parsing-of-linux-part-probe.patch b/target/linux/generic/pending-4.14/161-mtd-part-add-generic-parsing-of-linux-part-probe.patch -new file mode 100644 -index 0000000000..bf0c289227 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/161-mtd-part-add-generic-parsing-of-linux-part-probe.patch -@@ -0,0 +1,172 @@ -+From: Hauke Mehrtens -+Subject: mtd: part: add generic parsing of linux,part-probe -+ -+This moves the linux,part-probe device tree parsing code from -+physmap_of.c to mtdpart.c. Now all drivers can use this feature by just -+providing a reference to their device tree node in struct -+mtd_part_parser_data. -+ -+THIS METHOD HAS BEEN DEPRECATED -+ -+Linux supports "compatible" property in the "partitions" subnode now. It -+should be used to specify partitions format (and trigger proper parser -+usage) if needed. -+ -+Signed-off-by: Hauke Mehrtens -+--- -+ Documentation/devicetree/bindings/mtd/nand.txt | 16 +++++++++ -+ drivers/mtd/maps/physmap_of.c | 46 +------------------------- -+ drivers/mtd/mtdpart.c | 45 +++++++++++++++++++++++++ -+ 3 files changed, 62 insertions(+), 45 deletions(-) -+ -+--- a/Documentation/devicetree/bindings/mtd/nand.txt -++++ b/Documentation/devicetree/bindings/mtd/nand.txt -+@@ -44,6 +44,22 @@ Optional NAND chip properties: -+ used by the upper layers, and you want to make your NAND -+ as reliable as possible. -+ -++- linux,part-probe: list of name as strings of the partition parser -++ which should be used to parse the partition table. -++ They will be tried in the specified ordering and -++ the next one will be used if the previous one -++ failed. -++ -++ Example: linux,part-probe = "cmdlinepart", "ofpart"; -++ -++ This is also the default value, which will be used -++ if this attribute is not specified. It could be -++ that the flash driver in use overwrote the default -++ value and uses some other default. -++ -++ Possible values are: bcm47xxpart, afs, ar7part, -++ ofoldpart, ofpart, bcm63xxpart, RedBoot, cmdlinepart -++ -+ The ECC strength and ECC step size properties define the correction capability -+ of a controller. Together, they say a controller can correct "{strength} bit -+ errors per {size} bytes". -+--- a/drivers/mtd/maps/physmap_of_core.c -++++ b/drivers/mtd/maps/physmap_of_core.c -+@@ -105,37 +105,9 @@ static struct mtd_info *obsolete_probe(s -+ static const char * const part_probe_types_def[] = { -+ "cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL }; -+ -+-static const char * const *of_get_probes(struct device_node *dp) -+-{ -+- const char **res; -+- int count; -+- -+- count = of_property_count_strings(dp, "linux,part-probe"); -+- if (count < 0) -+- return part_probe_types_def; -+- -+- res = kzalloc((count + 1) * sizeof(*res), GFP_KERNEL); -+- if (!res) -+- return NULL; -+- -+- count = of_property_read_string_array(dp, "linux,part-probe", res, -+- count); -+- if (count < 0) -+- return NULL; -+- -+- return res; -+-} -+- -+-static void of_free_probes(const char * const *probes) -+-{ -+- if (probes != part_probe_types_def) -+- kfree(probes); -+-} -+- -+ static const struct of_device_id of_flash_match[]; -+ static int of_flash_probe(struct platform_device *dev) -+ { -+- const char * const *part_probe_types; -+ const struct of_device_id *match; -+ struct device_node *dp = dev->dev.of_node; -+ struct resource res; -+@@ -293,14 +265,8 @@ static int of_flash_probe(struct platfor -+ -+ info->cmtd->dev.parent = &dev->dev; -+ mtd_set_of_node(info->cmtd, dp); -+- part_probe_types = of_get_probes(dp); -+- if (!part_probe_types) { -+- err = -ENOMEM; -+- goto err_out; -+- } -+- mtd_device_parse_register(info->cmtd, part_probe_types, NULL, -++ mtd_device_parse_register(info->cmtd, part_probe_types_def, NULL, -+ NULL, 0); -+- of_free_probes(part_probe_types); -+ -+ kfree(mtd_list); -+ -+--- a/drivers/mtd/mtdpart.c -++++ b/drivers/mtd/mtdpart.c -+@@ -29,6 +29,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ -+@@ -869,6 +870,37 @@ void deregister_mtd_parser(struct mtd_pa -+ } -+ EXPORT_SYMBOL_GPL(deregister_mtd_parser); -+ -++#include -++ -++/* -++ * Parses the linux,part-probe device tree property. -++ * When a non null value is returned it has to be freed with kfree() by -++ * the caller. -++ */ -++static const char * const *of_get_probes(struct device_node *dp) -++{ -++ const char **res; -++ int count; -++ -++ count = of_property_count_strings(dp, "linux,part-probe"); -++ if (count < 0) -++ return NULL; -++ -++ res = kzalloc((count + 1) * sizeof(*res), GFP_KERNEL); -++ if (!res) -++ return NULL; -++ -++ count = of_property_read_string_array(dp, "linux,part-probe", res, -++ count); -++ if (count < 0) -++ return NULL; -++ -++ pr_warn("Support for the generic \"linux,part-probe\" has been deprecated and will be removed soon"); -++ BUILD_BUG_ON(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)); -++ -++ return res; -++} -++ -+ /* -+ * Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you -+ * are changing this array! -+@@ -1018,6 +1050,13 @@ int parse_mtd_partitions(struct mtd_info -+ struct mtd_partitions pparts = { }; -+ struct mtd_part_parser *parser; -+ int ret, err = 0; -++ const char *const *types_of = NULL; -++ -++ if (mtd_get_of_node(master)) { -++ types_of = of_get_probes(mtd_get_of_node(master)); -++ if (types_of != NULL) -++ types = types_of; -++ } -+ -+ if (!types) -+ types = mtd_is_partition(master) ? default_subpartition_types : -+@@ -1059,6 +1098,7 @@ int parse_mtd_partitions(struct mtd_info -+ if (ret < 0 && !err) -+ err = ret; -+ } -++ kfree(types_of); -+ return err; -+ } -+ -diff --git a/target/linux/generic/pending-4.14/171-usb-dwc2-Fix-inefficient-copy-of-unaligned-buffers.patch b/target/linux/generic/pending-4.14/171-usb-dwc2-Fix-inefficient-copy-of-unaligned-buffers.patch -new file mode 100644 -index 0000000000..7f21fefc25 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/171-usb-dwc2-Fix-inefficient-copy-of-unaligned-buffers.patch -@@ -0,0 +1,50 @@ -+From 81da1738eee68f1961e03bdeb2d60cf0eb4dd713 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Antti=20Sepp=C3=A4l=C3=A4?= -+Date: Thu, 5 Jul 2018 12:06:18 +0300 -+Subject: [PATCH 2/2] usb: dwc2: Fix inefficient copy of unaligned buffers -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+Make sure only to copy any actual data rather than the whole buffer, -+when releasing the temporary buffer used for unaligned non-isochronous -+transfers. -+ -+Taken directly from commit 0efd937e27d5e ("USB: ehci-tegra: fix inefficient -+copy of unaligned buffers") -+ -+Tested with Lantiq xRX200 (MIPS) and RPi Model B Rev 2 (ARM) -+ -+Signed-off-by: Antti Seppälä -+--- -+ drivers/usb/dwc2/hcd.c | 12 +++++++++--- -+ 1 file changed, 9 insertions(+), 3 deletions(-) -+ -+--- a/drivers/usb/dwc2/hcd.c -++++ b/drivers/usb/dwc2/hcd.c -+@@ -2669,6 +2669,7 @@ static int dwc2_alloc_split_dma_aligned_ -+ static void dwc2_free_dma_aligned_buffer(struct urb *urb) -+ { -+ void *stored_xfer_buffer; -++ size_t length; -+ -+ if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER)) -+ return; -+@@ -2679,9 +2680,14 @@ static void dwc2_free_dma_aligned_buffer -+ dma_get_cache_alignment()), -+ sizeof(urb->transfer_buffer)); -+ -+- if (usb_urb_dir_in(urb)) -+- memcpy(stored_xfer_buffer, urb->transfer_buffer, -+- urb->transfer_buffer_length); -++ if (usb_urb_dir_in(urb)) { -++ if (usb_pipeisoc(urb->pipe)) -++ length = urb->transfer_buffer_length; -++ else -++ length = urb->actual_length; -++ -++ memcpy(stored_xfer_buffer, urb->transfer_buffer, length); -++ } -+ kfree(urb->transfer_buffer); -+ urb->transfer_buffer = stored_xfer_buffer; -+ -diff --git a/target/linux/generic/pending-4.14/180-net-phy-at803x-add-support-for-AT8032.patch b/target/linux/generic/pending-4.14/180-net-phy-at803x-add-support-for-AT8032.patch -new file mode 100644 -index 0000000000..828b160be9 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/180-net-phy-at803x-add-support-for-AT8032.patch -@@ -0,0 +1,73 @@ -+From: Felix Fietkau -+Subject: net: phy: at803x: add support for AT8032 -+ -+Like AT8030, this PHY needs the GPIO reset workaround -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/phy/at803x.c -++++ b/drivers/net/phy/at803x.c -+@@ -62,8 +62,10 @@ -+ -+ #define ATH8030_PHY_ID 0x004dd076 -+ #define ATH8031_PHY_ID 0x004dd074 -++#define ATH8032_PHY_ID 0x004dd023 -+ #define ATH8035_PHY_ID 0x004dd072 -+ #define AT803X_PHY_ID_MASK 0xffffffef -++#define AT8032_PHY_ID_MASK 0xffffffff -+ -+ MODULE_DESCRIPTION("Atheros 803x PHY driver"); -+ MODULE_AUTHOR("Matus Ujhelyi"); -+@@ -256,7 +258,8 @@ static int at803x_probe(struct phy_devic -+ if (!priv) -+ return -ENOMEM; -+ -+- if (phydev->drv->phy_id != ATH8030_PHY_ID) -++ if (phydev->drv->phy_id != ATH8030_PHY_ID && -++ phydev->drv->phy_id != ATH8032_PHY_ID) -+ goto does_not_require_reset_workaround; -+ -+ gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); -+@@ -332,7 +335,7 @@ static void at803x_link_change_notify(st -+ struct at803x_priv *priv = phydev->priv; -+ -+ /* -+- * Conduct a hardware reset for AT8030 every time a link loss is -++ * Conduct a hardware reset for AT8030/2 every time a link loss is -+ * signalled. This is necessary to circumvent a hardware bug that -+ * occurs when the cable is unplugged while TX packets are pending -+ * in the FIFO. In such cases, the FIFO enters an error mode it -+@@ -444,6 +447,24 @@ static struct phy_driver at803x_driver[] -+ .aneg_done = at803x_aneg_done, -+ .ack_interrupt = &at803x_ack_interrupt, -+ .config_intr = &at803x_config_intr, -++}, { -++ /* ATHEROS 8032 */ -++ .phy_id = ATH8032_PHY_ID, -++ .name = "Atheros 8032 ethernet", -++ .phy_id_mask = AT8032_PHY_ID_MASK, -++ .probe = at803x_probe, -++ .config_init = at803x_config_init, -++ .link_change_notify = at803x_link_change_notify, -++ .set_wol = at803x_set_wol, -++ .get_wol = at803x_get_wol, -++ .suspend = at803x_suspend, -++ .resume = at803x_resume, -++ .features = PHY_BASIC_FEATURES, -++ .flags = PHY_HAS_INTERRUPT, -++ .config_aneg = genphy_config_aneg, -++ .read_status = genphy_read_status, -++ .ack_interrupt = at803x_ack_interrupt, -++ .config_intr = at803x_config_intr, -+ } }; -+ -+ module_phy_driver(at803x_driver); -+@@ -451,6 +472,7 @@ module_phy_driver(at803x_driver); -+ static struct mdio_device_id __maybe_unused atheros_tbl[] = { -+ { ATH8030_PHY_ID, AT803X_PHY_ID_MASK }, -+ { ATH8031_PHY_ID, AT803X_PHY_ID_MASK }, -++ { ATH8032_PHY_ID, AT8032_PHY_ID_MASK }, -+ { ATH8035_PHY_ID, AT803X_PHY_ID_MASK }, -+ { } -+ }; -diff --git a/target/linux/generic/pending-4.14/190-2-5-e1000e-Fix-wrong-comment-related-to-link-detection.patch b/target/linux/generic/pending-4.14/190-2-5-e1000e-Fix-wrong-comment-related-to-link-detection.patch -new file mode 100644 -index 0000000000..aaf21f075f ---- /dev/null -+++ b/target/linux/generic/pending-4.14/190-2-5-e1000e-Fix-wrong-comment-related-to-link-detection.patch -@@ -0,0 +1,43 @@ -+From patchwork Fri Jul 21 18:36:24 2017 -+Content-Type: text/plain; charset="utf-8" -+MIME-Version: 1.0 -+Content-Transfer-Encoding: 7bit -+Subject: [2/5] e1000e: Fix wrong comment related to link detection -+From: Benjamin Poirier -+X-Patchwork-Id: 9857489 -+Message-Id: <20170721183627.13373-2-bpoirier@suse.com> -+To: Jeff Kirsher -+Cc: Lennart Sorensen , -+ intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org, -+ linux-kernel@vger.kernel.org -+Date: Fri, 21 Jul 2017 11:36:24 -0700 -+ -+Reading e1000e_check_for_copper_link() shows that get_link_status is set to -+false after link has been detected. Therefore, it stays TRUE until then. -+ -+Signed-off-by: Benjamin Poirier -+Tested-by: Aaron Brown -+--- -+ drivers/net/ethernet/intel/e1000e/netdev.c | 4 ++-- -+ 1 file changed, 2 insertions(+), 2 deletions(-) -+ -+--- a/drivers/net/ethernet/intel/e1000e/netdev.c -++++ b/drivers/net/ethernet/intel/e1000e/netdev.c -+@@ -5080,7 +5080,7 @@ static bool e1000e_has_link(struct e1000 -+ -+ /* get_link_status is set on LSC (link status) interrupt or -+ * Rx sequence error interrupt. get_link_status will stay -+- * false until the check_for_link establishes link -++ * true until the check_for_link establishes link -+ * for copper adapters ONLY -+ */ -+ switch (hw->phy.media_type) { -+@@ -5098,7 +5098,7 @@ static bool e1000e_has_link(struct e1000 -+ break; -+ case e1000_media_type_internal_serdes: -+ ret_val = hw->mac.ops.check_for_link(hw); -+- link_active = adapter->hw.mac.serdes_has_link; -++ link_active = hw->mac.serdes_has_link; -+ break; -+ default: -+ case e1000_media_type_unknown: -diff --git a/target/linux/generic/pending-4.14/201-extra_optimization.patch b/target/linux/generic/pending-4.14/201-extra_optimization.patch -new file mode 100644 -index 0000000000..aef36a8c11 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/201-extra_optimization.patch -@@ -0,0 +1,28 @@ -+From: Felix Fietkau -+Subject: Upgrade to Linux 2.6.19 -+ -+- Includes large parts of the patch from #1021 by dpalffy -+- Includes RB532 NAND driver changes by n0-1 -+ -+[john@phrozen.org: feix will add this to his upstream queue] -+ -+lede-commit: bff468813f78f81e36ebb2a3f4354de7365e640f -+Signed-off-by: Felix Fietkau -+--- -+ Makefile | 6 +++--- -+ 1 file changed, 3 insertions(+), 3 deletions(-) -+ -+--- a/Makefile -++++ b/Makefile -+@@ -652,9 +652,9 @@ KBUILD_CFLAGS += $(call cc-disable-warni -+ KBUILD_CFLAGS += $(call cc-disable-warning, attribute-alias) -+ -+ ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE -+-KBUILD_CFLAGS += -Os -++KBUILD_CFLAGS += -Os $(EXTRA_OPTIMIZATION) -+ else -+-KBUILD_CFLAGS += -O2 -++KBUILD_CFLAGS += -O2 -fno-reorder-blocks -fno-tree-ch $(EXTRA_OPTIMIZATION) -+ endif -+ -+ # Tell gcc to never replace conditional load with a non-conditional one -diff --git a/target/linux/generic/pending-4.14/203-kallsyms_uncompressed.patch b/target/linux/generic/pending-4.14/203-kallsyms_uncompressed.patch -new file mode 100644 -index 0000000000..1f5c83e94f ---- /dev/null -+++ b/target/linux/generic/pending-4.14/203-kallsyms_uncompressed.patch -@@ -0,0 +1,119 @@ -+From: Felix Fietkau -+Subject: kernel: add a config option for keeping the kallsyms table uncompressed, saving ~9kb kernel size after lzma on ar71xx -+ -+[john@phrozen.org: added to my upstream queue 30.12.2016] -+lede-commit: e0e3509b5ce2ccf93d4d67ea907613f5f7ec2eed -+Signed-off-by: Felix Fietkau -+--- -+ init/Kconfig | 11 +++++++++++ -+ kernel/kallsyms.c | 8 ++++++++ -+ scripts/kallsyms.c | 12 ++++++++++++ -+ scripts/link-vmlinux.sh | 4 ++++ -+ 4 files changed, 35 insertions(+) -+ -+--- a/init/Kconfig -++++ b/init/Kconfig -+@@ -1081,6 +1081,17 @@ config SYSCTL_ARCH_UNALIGN_ALLOW -+ the unaligned access emulation. -+ see arch/parisc/kernel/unaligned.c for reference -+ -++config KALLSYMS_UNCOMPRESSED -++ bool "Keep kallsyms uncompressed" -++ depends on KALLSYMS -++ help -++ Normally kallsyms contains compressed symbols (using a token table), -++ reducing the uncompressed kernel image size. Keeping the symbol table -++ uncompressed significantly improves the size of this part in compressed -++ kernel images. -++ -++ Say N unless you need compressed kernel images to be small. -++ -+ config HAVE_PCSPKR_PLATFORM -+ bool -+ -+--- a/kernel/kallsyms.c -++++ b/kernel/kallsyms.c -+@@ -108,6 +108,11 @@ static unsigned int kallsyms_expand_symb -+ * For every byte on the compressed symbol data, copy the table -+ * entry for that byte. -+ */ -++#ifdef CONFIG_KALLSYMS_UNCOMPRESSED -++ memcpy(result, data + 1, len - 1); -++ result += len - 1; -++ len = 0; -++#endif -+ while (len) { -+ tptr = &kallsyms_token_table[kallsyms_token_index[*data]]; -+ data++; -+@@ -140,6 +145,9 @@ tail: -+ */ -+ static char kallsyms_get_symbol_type(unsigned int off) -+ { -++#ifdef CONFIG_KALLSYMS_UNCOMPRESSED -++ return kallsyms_names[off + 1]; -++#endif -+ /* -+ * Get just the first code, look it up in the token table, -+ * and return the first char from this token. -+--- a/scripts/kallsyms.c -++++ b/scripts/kallsyms.c -+@@ -61,6 +61,7 @@ static struct addr_range percpu_range = -+ static struct sym_entry *table; -+ static unsigned int table_size, table_cnt; -+ static int all_symbols = 0; -++static int uncompressed = 0; -+ static int absolute_percpu = 0; -+ static char symbol_prefix_char = '\0'; -+ static int base_relative = 0; -+@@ -461,6 +462,9 @@ static void write_src(void) -+ -+ free(markers); -+ -++ if (uncompressed) -++ return; -++ -+ output_label("kallsyms_token_table"); -+ off = 0; -+ for (i = 0; i < 256; i++) { -+@@ -521,6 +525,9 @@ static void *find_token(unsigned char *s -+ { -+ int i; -+ -++ if (uncompressed) -++ return NULL; -++ -+ for (i = 0; i < len - 1; i++) { -+ if (str[i] == token[0] && str[i+1] == token[1]) -+ return &str[i]; -+@@ -593,6 +600,9 @@ static void optimize_result(void) -+ { -+ int i, best; -+ -++ if (uncompressed) -++ return; -++ -+ /* using the '\0' symbol last allows compress_symbols to use standard -+ * fast string functions */ -+ for (i = 255; i >= 0; i--) { -+@@ -781,6 +791,8 @@ int main(int argc, char **argv) -+ symbol_prefix_char = *p; -+ } else if (strcmp(argv[i], "--base-relative") == 0) -+ base_relative = 1; -++ else if (strcmp(argv[i], "--uncompressed") == 0) -++ uncompressed = 1; -+ else -+ usage(); -+ } -+--- a/scripts/link-vmlinux.sh -++++ b/scripts/link-vmlinux.sh -+@@ -164,6 +164,10 @@ kallsyms() -+ kallsymopt="${kallsymopt} --base-relative" -+ fi -+ -++ if [ -n "${CONFIG_KALLSYMS_UNCOMPRESSED}" ]; then -++ kallsymopt="${kallsymopt} --uncompressed" -++ fi -++ -+ local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ -+ ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}" -+ -diff --git a/target/linux/generic/pending-4.14/205-backtrace_module_info.patch b/target/linux/generic/pending-4.14/205-backtrace_module_info.patch -new file mode 100644 -index 0000000000..4040f91021 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/205-backtrace_module_info.patch -@@ -0,0 +1,45 @@ -+From: Felix Fietkau -+Subject: kernel: when KALLSYMS is disabled, print module address + size for matching backtrace entries -+ -+[john@phrozen.org: felix will add this to his upstream queue] -+ -+lede-commit 53827cdc824556cda910b23ce5030c363b8f1461 -+Signed-off-by: Felix Fietkau -+--- -+ lib/vsprintf.c | 15 +++++++++++---- -+ 1 file changed, 11 insertions(+), 4 deletions(-) -+ -+--- a/lib/vsprintf.c -++++ b/lib/vsprintf.c -+@@ -670,8 +670,10 @@ char *symbol_string(char *buf, char *end -+ struct printf_spec spec, const char *fmt) -+ { -+ unsigned long value; -+-#ifdef CONFIG_KALLSYMS -+ char sym[KSYM_SYMBOL_LEN]; -++#ifndef CONFIG_KALLSYMS -++ struct module *mod; -++ int len; -+ #endif -+ -+ if (fmt[1] == 'R') -+@@ -685,11 +687,16 @@ char *symbol_string(char *buf, char *end -+ sprint_symbol(sym, value); -+ else -+ sprint_symbol_no_offset(sym, value); -+- -+- return string(buf, end, sym, spec); -+ #else -+- return special_hex_number(buf, end, value, sizeof(void *)); -++ len = snprintf(sym, sizeof(sym), "0x%lx", value); -++ -++ mod = __module_address(value); -++ if (mod) -++ snprintf(sym + len, sizeof(sym) - len, " [%s@%p+0x%x]", -++ mod->name, mod->core_layout.base, -++ mod->core_layout.size); -+ #endif -++ return string(buf, end, sym, spec); -+ } -+ -+ static noinline_for_stack -diff --git a/target/linux/generic/pending-4.14/220-optimize_inlining.patch b/target/linux/generic/pending-4.14/220-optimize_inlining.patch -new file mode 100644 -index 0000000000..76aabf86db ---- /dev/null -+++ b/target/linux/generic/pending-4.14/220-optimize_inlining.patch -@@ -0,0 +1,165 @@ -+--- a/arch/arm/kernel/atags.h -++++ b/arch/arm/kernel/atags.h -+@@ -5,7 +5,7 @@ void convert_to_tag_list(struct tag *tag -+ const struct machine_desc *setup_machine_tags(phys_addr_t __atags_pointer, -+ unsigned int machine_nr); -+ #else -+-static inline const struct machine_desc * -++static inline const struct machine_desc * __init __noreturn -+ setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) -+ { -+ early_print("no ATAGS support: can't continue\n"); -+--- a/arch/arm64/include/asm/cpufeature.h -++++ b/arch/arm64/include/asm/cpufeature.h -+@@ -347,7 +347,7 @@ static inline bool cpu_have_feature(unsi -+ } -+ -+ /* System capability check for constant caps */ -+-static inline bool __cpus_have_const_cap(int num) -++static __always_inline bool __cpus_have_const_cap(int num) -+ { -+ if (num >= ARM64_NCAPS) -+ return false; -+@@ -361,7 +361,7 @@ static inline bool cpus_have_cap(unsigne -+ return test_bit(num, cpu_hwcaps); -+ } -+ -+-static inline bool cpus_have_const_cap(int num) -++static __always_inline bool cpus_have_const_cap(int num) -+ { -+ if (static_branch_likely(&arm64_const_caps_ready)) -+ return __cpus_have_const_cap(num); -+--- a/arch/mips/include/asm/bitops.h -++++ b/arch/mips/include/asm/bitops.h -+@@ -462,7 +462,7 @@ static inline void __clear_bit_unlock(un -+ * Return the bit position (0..63) of the most significant 1 bit in a word -+ * Returns -1 if no 1 bit exists -+ */ -+-static inline unsigned long __fls(unsigned long word) -++static __always_inline unsigned long __fls(unsigned long word) -+ { -+ int num; -+ -+@@ -528,7 +528,7 @@ static inline unsigned long __fls(unsign -+ * Returns 0..SZLONG-1 -+ * Undefined if no bit exists, so code should check against 0 first. -+ */ -+-static inline unsigned long __ffs(unsigned long word) -++static __always_inline unsigned long __ffs(unsigned long word) -+ { -+ return __fls(word & -word); -+ } -+--- a/arch/mips/kernel/cpu-bugs64.c -++++ b/arch/mips/kernel/cpu-bugs64.c -+@@ -42,8 +42,8 @@ static inline void align_mod(const int a -+ : GCC_IMM_ASM() (align), GCC_IMM_ASM() (mod)); -+ } -+ -+-static inline void mult_sh_align_mod(long *v1, long *v2, long *w, -+- const int align, const int mod) -++static __always_inline void mult_sh_align_mod(long *v1, long *v2, long *w, -++ const int align, const int mod) -+ { -+ unsigned long flags; -+ int m1, m2; -+--- a/arch/powerpc/kernel/prom_init.c -++++ b/arch/powerpc/kernel/prom_init.c -+@@ -474,14 +474,14 @@ static int __init prom_next_node(phandle -+ } -+ } -+ -+-static inline int prom_getprop(phandle node, const char *pname, -+- void *value, size_t valuelen) -++static inline int __init prom_getprop(phandle node, const char *pname, -++ void *value, size_t valuelen) -+ { -+ return call_prom("getprop", 4, 1, node, ADDR(pname), -+ (u32)(unsigned long) value, (u32) valuelen); -+ } -+ -+-static inline int prom_getproplen(phandle node, const char *pname) -++static inline int __init prom_getproplen(phandle node, const char *pname) -+ { -+ return call_prom("getproplen", 2, 1, node, ADDR(pname)); -+ } -+--- a/arch/s390/include/asm/cpacf.h -++++ b/arch/s390/include/asm/cpacf.h -+@@ -184,7 +184,7 @@ static inline int __cpacf_check_opcode(u -+ } -+ } -+ -+-static inline int cpacf_query(unsigned int opcode, cpacf_mask_t *mask) -++static __always_inline int cpacf_query(unsigned int opcode, cpacf_mask_t *mask) -+ { -+ if (__cpacf_check_opcode(opcode)) { -+ __cpacf_query(opcode, mask); -+--- a/arch/x86/Kconfig.debug -++++ b/arch/x86/Kconfig.debug -+@@ -284,20 +284,6 @@ config CPA_DEBUG -+ ---help--- -+ Do change_page_attr() self-tests every 30 seconds. -+ -+-config OPTIMIZE_INLINING -+- bool "Allow gcc to uninline functions marked 'inline'" -+- ---help--- -+- This option determines if the kernel forces gcc to inline the functions -+- developers have marked 'inline'. Doing so takes away freedom from gcc to -+- do what it thinks is best, which is desirable for the gcc 3.x series of -+- compilers. The gcc 4.x series have a rewritten inlining algorithm and -+- enabling this option will generate a smaller kernel there. Hopefully -+- this algorithm is so good that allowing gcc 4.x and above to make the -+- decision will become the default in the future. Until then this option -+- is there to test gcc for this. -+- -+- If unsure, say N. -+- -+ config DEBUG_ENTRY -+ bool "Debug low-level entry code" -+ depends on DEBUG_KERNEL -+--- a/lib/Kconfig.debug -++++ b/lib/Kconfig.debug -+@@ -305,6 +305,20 @@ config HEADERS_CHECK -+ exported to $(INSTALL_HDR_PATH) (usually 'usr/include' in -+ your build tree), to make sure they're suitable. -+ -++config OPTIMIZE_INLINING -++ bool "Allow compiler to uninline functions marked 'inline'" -++ help -++ This option determines if the kernel forces gcc to inline the functions -++ developers have marked 'inline'. Doing so takes away freedom from gcc to -++ do what it thinks is best, which is desirable for the gcc 3.x series of -++ compilers. The gcc 4.x series have a rewritten inlining algorithm and -++ enabling this option will generate a smaller kernel there. Hopefully -++ this algorithm is so good that allowing gcc 4.x and above to make the -++ decision will become the default in the future. Until then this option -++ is there to test gcc for this. -++ -++ If unsure, say N. -++ -+ config DEBUG_SECTION_MISMATCH -+ bool "Enable full Section mismatch analysis" -+ help -+--- a/arch/x86/Kconfig -++++ b/arch/x86/Kconfig -+@@ -296,9 +296,6 @@ config ZONE_DMA32 -+ config AUDIT_ARCH -+ def_bool y if X86_64 -+ -+-config ARCH_SUPPORTS_OPTIMIZED_INLINING -+- def_bool y -+- -+ config ARCH_SUPPORTS_DEBUG_PAGEALLOC -+ def_bool y -+ -+--- a/include/linux/compiler-gcc.h -++++ b/include/linux/compiler-gcc.h -+@@ -90,8 +90,7 @@ -+ * of extern inline functions at link time. -+ * A lot of inline functions can cause havoc with function tracing. -+ */ -+-#if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \ -+- !defined(CONFIG_OPTIMIZE_INLINING) || (__GNUC__ < 4) -++#if !defined(CONFIG_OPTIMIZE_INLINING) || (__GNUC__ < 4) -+ #define inline \ -+ inline __attribute__((always_inline, unused)) notrace __gnu_inline -+ #else -diff --git a/target/linux/generic/pending-4.14/240-remove-unsane-filenames-from-deps_initramfs-list.patch b/target/linux/generic/pending-4.14/240-remove-unsane-filenames-from-deps_initramfs-list.patch -new file mode 100644 -index 0000000000..c0dfe49c9b ---- /dev/null -+++ b/target/linux/generic/pending-4.14/240-remove-unsane-filenames-from-deps_initramfs-list.patch -@@ -0,0 +1,46 @@ -+From: Gabor Juhos -+Subject: usr: sanitize deps_initramfs list -+ -+If any filename in the intramfs dependency -+list contains a colon, that causes a kernel -+build error like this: -+ -+/devel/openwrt/build_dir/linux-ar71xx_generic/linux-3.6.6/usr/Makefile:58: *** multiple target patterns. Stop. -+make[5]: *** [usr] Error 2 -+ -+Fix it by removing such filenames from the -+deps_initramfs list. -+ -+Signed-off-by: Gabor Juhos -+--- -+ usr/Makefile | 8 +++++--- -+ 1 file changed, 5 insertions(+), 3 deletions(-) -+ -+--- a/usr/Makefile -++++ b/usr/Makefile -+@@ -42,20 +42,22 @@ ifneq ($(wildcard $(obj)/$(datafile_d_y) -+ include $(obj)/$(datafile_d_y) -+ endif -+ -++deps_initramfs_sane := $(foreach v,$(deps_initramfs),$(if $(findstring :,$(v)),,$(v))) -++ -+ quiet_cmd_initfs = GEN $@ -+ cmd_initfs = $(initramfs) -o $@ $(ramfs-args) $(ramfs-input) -+ -+ targets := $(datafile_y) -+ -+ # do not try to update files included in initramfs -+-$(deps_initramfs): ; -++$(deps_initramfs_sane): ; -+ -+-$(deps_initramfs): klibcdirs -++$(deps_initramfs_sane): klibcdirs -+ # We rebuild initramfs_data.cpio if: -+ # 1) Any included file is newer then initramfs_data.cpio -+ # 2) There are changes in which files are included (added or deleted) -+ # 3) If gen_init_cpio are newer than initramfs_data.cpio -+ # 4) arguments to gen_initramfs.sh changes -+-$(obj)/$(datafile_y): $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs -++$(obj)/$(datafile_y): $(obj)/gen_init_cpio $(deps_initramfs_sane) klibcdirs -+ $(Q)$(initramfs) -l $(ramfs-input) > $(obj)/$(datafile_d_y) -+ $(call if_changed,initfs) -diff --git a/target/linux/generic/pending-4.14/261-enable_wilink_platform_without_drivers.patch b/target/linux/generic/pending-4.14/261-enable_wilink_platform_without_drivers.patch -new file mode 100644 -index 0000000000..9955ab3c0b ---- /dev/null -+++ b/target/linux/generic/pending-4.14/261-enable_wilink_platform_without_drivers.patch -@@ -0,0 +1,20 @@ -+From: Imre Kaloz -+Subject: [PATCH] hack: net: wireless: make the wl12xx glue code available with -+ compat-wireless, too -+ -+Signed-off-by: Imre Kaloz -+--- -+ drivers/net/wireless/ti/Kconfig | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/drivers/net/wireless/ti/Kconfig -++++ b/drivers/net/wireless/ti/Kconfig -+@@ -19,7 +19,7 @@ source "drivers/net/wireless/ti/wlcore/K -+ -+ config WILINK_PLATFORM_DATA -+ bool "TI WiLink platform data" -+- depends on WLCORE_SDIO || WL1251_SDIO -++ depends on WLCORE_SDIO || WL1251_SDIO || ARCH_OMAP2PLUS -+ default y -+ ---help--- -+ Small platform data bit needed to pass data to the sdio modules. -diff --git a/target/linux/generic/pending-4.14/270-platform-mikrotik-build-bits.patch b/target/linux/generic/pending-4.14/270-platform-mikrotik-build-bits.patch -new file mode 100644 -index 0000000000..15dfcb2eba ---- /dev/null -+++ b/target/linux/generic/pending-4.14/270-platform-mikrotik-build-bits.patch -@@ -0,0 +1,31 @@ -+From c2deb5ef01a0ef09088832744cbace9e239a6ee0 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= -+Date: Tue, 24 Mar 2020 22:11:50 +0100 -+Subject: [PATCH] generic: platform/mikrotik build bits (4.14) -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This patch adds platform/mikrotik kernel build bits -+ -+Signed-off-by: Thibaut VARÈNE -+--- -+ drivers/platform/Kconfig | 2 ++ -+ drivers/platform/Makefile | 1 + -+ 2 files changed, 3 insertions(+) -+ -+--- a/drivers/platform/Kconfig -++++ b/drivers/platform/Kconfig -+@@ -8,3 +8,5 @@ endif -+ source "drivers/platform/goldfish/Kconfig" -+ -+ source "drivers/platform/chrome/Kconfig" -++ -++source "drivers/platform/mikrotik/Kconfig" -+--- a/drivers/platform/Makefile -++++ b/drivers/platform/Makefile -+@@ -8,3 +8,4 @@ obj-$(CONFIG_MIPS) += mips/ -+ obj-$(CONFIG_OLPC) += olpc/ -+ obj-$(CONFIG_GOLDFISH) += goldfish/ -+ obj-$(CONFIG_CHROME_PLATFORMS) += chrome/ -++obj-$(CONFIG_MIKROTIK) += mikrotik/ -diff --git a/target/linux/generic/pending-4.14/300-mips_expose_boot_raw.patch b/target/linux/generic/pending-4.14/300-mips_expose_boot_raw.patch -new file mode 100644 -index 0000000000..71dff9b930 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/300-mips_expose_boot_raw.patch -@@ -0,0 +1,40 @@ -+From: Mark Miller -+Subject: mips: expose CONFIG_BOOT_RAW -+ -+This exposes the CONFIG_BOOT_RAW symbol in Kconfig. This is needed on -+certain Broadcom chipsets running CFE in order to load the kernel. -+ -+Signed-off-by: Mark Miller -+Acked-by: Rob Landley -+--- -+--- a/arch/mips/Kconfig -++++ b/arch/mips/Kconfig -+@@ -1068,9 +1068,6 @@ config FW_ARC -+ config ARCH_MAY_HAVE_PC_FDC -+ bool -+ -+-config BOOT_RAW -+- bool -+- -+ config CEVT_BCM1480 -+ bool -+ -+@@ -2968,6 +2965,18 @@ choice -+ bool "Extend builtin kernel arguments with bootloader arguments" -+ endchoice -+ -++config BOOT_RAW -++ bool "Enable the kernel to be executed from the load address" -++ default n -++ help -++ Allow the kernel to be executed from the load address for -++ bootloaders which cannot read the ELF format. This places -++ a jump to start_kernel at the load address. -++ -++ If unsure, say N. -++ -++ -++ -+ endmenu -+ -+ config LOCKDEP_SUPPORT -diff --git a/target/linux/generic/pending-4.14/302-mips_no_branch_likely.patch b/target/linux/generic/pending-4.14/302-mips_no_branch_likely.patch -new file mode 100644 -index 0000000000..0e4600237d ---- /dev/null -+++ b/target/linux/generic/pending-4.14/302-mips_no_branch_likely.patch -@@ -0,0 +1,22 @@ -+From: Felix Fietkau -+Subject: mips: use -mno-branch-likely for kernel and userspace -+ -+saves ~11k kernel size after lzma and ~12k squashfs size in the -+ -+lede-commit: 41a039f46450ffae9483d6216422098669da2900 -+Signed-off-by: Felix Fietkau -+--- -+ arch/mips/Makefile | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/arch/mips/Makefile -++++ b/arch/mips/Makefile -+@@ -90,7 +90,7 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin -+ # machines may also. Since BFD is incredibly buggy with respect to -+ # crossformat linking we rely on the elf2ecoff tool for format conversion. -+ # -+-cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -++cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely -+ cflags-y += -msoft-float -+ LDFLAGS_vmlinux += -G 0 -static -n -nostdlib -+ KBUILD_AFLAGS_MODULE += -mlong-calls -diff --git a/target/linux/generic/pending-4.14/304-mips_disable_fpu.patch b/target/linux/generic/pending-4.14/304-mips_disable_fpu.patch -new file mode 100644 -index 0000000000..47983df948 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/304-mips_disable_fpu.patch -@@ -0,0 +1,137 @@ -+From: Manuel Lauss -+Subject: [RFC PATCH v4 2/2] MIPS: make FPU emulator optional -+ -+This small patch makes the MIPS FPU emulator optional. The kernel -+kills float-users on systems without a hardware FPU by sending a SIGILL. -+ -+Disabling the emulator shrinks vmlinux by about 54kBytes (32bit, -+optimizing for size). -+ -+Signed-off-by: Manuel Lauss -+--- -+v4: rediffed because of patch 1/2, should now work with micromips as well -+v3: updated patch description with size savings. -+v2: incorporated changes suggested by Jonas Gorski -+ force the fpu emulator on for micromips: relocating the parts -+ of the mmips code in the emulator to other areas would be a -+ much larger change; I went the cheap route instead with this. -+ -+ arch/mips/Kbuild | 2 +- -+ arch/mips/Kconfig | 14 ++++++++++++++ -+ arch/mips/include/asm/fpu.h | 5 +++-- -+ arch/mips/include/asm/fpu_emulator.h | 15 +++++++++++++++ -+ 4 files changed, 33 insertions(+), 3 deletions(-) -+ -+--- a/arch/mips/Kconfig -++++ b/arch/mips/Kconfig -+@@ -2892,6 +2892,20 @@ config MIPS_O32_FP64_SUPPORT -+ -+ If unsure, say N. -+ -++config MIPS_FPU_EMULATOR -++ bool "MIPS FPU Emulator" -++ default y -++ help -++ This option lets you disable the built-in MIPS FPU (Coprocessor 1) -++ emulator, which handles floating-point instructions on processors -++ without a hardware FPU. It is generally a good idea to keep the -++ emulator built-in, unless you are perfectly sure you have a -++ complete soft-float environment. With the emulator disabled, all -++ users of float operations will be killed with an illegal instr- -++ uction exception. -++ -++ Say Y, please. -++ -+ config USE_OF -+ bool -+ select OF -+--- a/arch/mips/Makefile -++++ b/arch/mips/Makefile -+@@ -326,7 +326,7 @@ OBJCOPYFLAGS += --remove-section=.regin -+ head-y := arch/mips/kernel/head.o -+ -+ libs-y += arch/mips/lib/ -+-libs-y += arch/mips/math-emu/ -++libs-$(CONFIG_MIPS_FPU_EMULATOR) += arch/mips/math-emu/ -+ -+ # See arch/mips/Kbuild for content of core part of the kernel -+ core-y += arch/mips/ -+--- a/arch/mips/include/asm/fpu.h -++++ b/arch/mips/include/asm/fpu.h -+@@ -230,8 +230,10 @@ static inline int init_fpu(void) -+ /* Restore FRE */ -+ write_c0_config5(config5); -+ enable_fpu_hazard(); -+- } else -++ } else if (IS_ENABLED(CONFIG_MIPS_FPU_EMULATOR)) -+ fpu_emulator_init_fpu(); -++ else -++ ret = SIGILL; -+ -+ return ret; -+ } -+--- a/arch/mips/include/asm/fpu_emulator.h -++++ b/arch/mips/include/asm/fpu_emulator.h -+@@ -30,6 +30,7 @@ -+ #include -+ #include -+ -++#ifdef CONFIG_MIPS_FPU_EMULATOR -+ #ifdef CONFIG_DEBUG_FS -+ -+ struct mips_fpu_emulator_stats { -+@@ -179,6 +180,16 @@ do { \ -+ extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, -+ struct mips_fpu_struct *ctx, int has_fpu, -+ void __user **fault_addr); -++#else /* no CONFIG_MIPS_FPU_EMULATOR */ -++static inline int fpu_emulator_cop1Handler(struct pt_regs *xcp, -++ struct mips_fpu_struct *ctx, int has_fpu, -++ void __user **fault_addr) -++{ -++ *fault_addr = NULL; -++ return SIGILL; /* we don't speak MIPS FPU */ -++} -++#endif /* CONFIG_MIPS_FPU_EMULATOR */ -++ -+ void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr, -+ struct task_struct *tsk); -+ int process_fpemu_return(int sig, void __user *fault_addr, -+--- a/arch/mips/include/asm/dsemul.h -++++ b/arch/mips/include/asm/dsemul.h -+@@ -41,6 +41,7 @@ struct task_struct; -+ extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir, -+ unsigned long branch_pc, unsigned long cont_pc); -+ -++#ifdef CONFIG_MIPS_FPU_EMULATOR -+ /** -+ * do_dsemulret() - Return from a delay slot 'emulation' frame -+ * @xcp: User thread register context. -+@@ -88,5 +89,27 @@ extern bool dsemul_thread_rollback(struc -+ * before @mm is freed in order to avoid memory leaks. -+ */ -+ extern void dsemul_mm_cleanup(struct mm_struct *mm); -++#else -++static inline bool do_dsemulret(struct pt_regs *xcp) -++{ -++ return false; -++} -++ -++static inline bool dsemul_thread_cleanup(struct task_struct *tsk) -++{ -++ return false; -++} -++ -++static inline bool dsemul_thread_rollback(struct pt_regs *regs) -++{ -++ return false; -++} -++ -++static inline void dsemul_mm_cleanup(struct mm_struct *mm) -++{ -++ -++} -++ -++#endif -+ -+ #endif /* __MIPS_ASM_DSEMUL_H__ */ -diff --git a/target/linux/generic/pending-4.14/305-mips_module_reloc.patch b/target/linux/generic/pending-4.14/305-mips_module_reloc.patch -new file mode 100644 -index 0000000000..609a96db49 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/305-mips_module_reloc.patch -@@ -0,0 +1,371 @@ -+From: Felix Fietkau -+Subject: mips: replace -mlong-calls with -mno-long-calls to make function calls faster in kernel modules to achieve this, try to -+ -+lede-commit: 3b3d64743ba2a874df9d70cd19e242205b0a788c -+Signed-off-by: Felix Fietkau -+--- -+ arch/mips/Makefile | 5 + -+ arch/mips/include/asm/module.h | 5 + -+ arch/mips/kernel/module.c | 279 ++++++++++++++++++++++++++++++++++++++++- -+ 3 files changed, 284 insertions(+), 5 deletions(-) -+ -+--- a/arch/mips/Makefile -++++ b/arch/mips/Makefile -+@@ -93,8 +93,18 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin -+ cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely -+ cflags-y += -msoft-float -+ LDFLAGS_vmlinux += -G 0 -static -n -nostdlib -++ifdef CONFIG_64BIT -+ KBUILD_AFLAGS_MODULE += -mlong-calls -+ KBUILD_CFLAGS_MODULE += -mlong-calls -++else -++ ifdef CONFIG_DYNAMIC_FTRACE -++ KBUILD_AFLAGS_MODULE += -mlong-calls -++ KBUILD_CFLAGS_MODULE += -mlong-calls -++ else -++ KBUILD_AFLAGS_MODULE += -mno-long-calls -++ KBUILD_CFLAGS_MODULE += -mno-long-calls -++ endif -++endif -+ -+ ifeq ($(CONFIG_RELOCATABLE),y) -+ LDFLAGS_vmlinux += --emit-relocs -+--- a/arch/mips/include/asm/module.h -++++ b/arch/mips/include/asm/module.h -+@@ -12,6 +12,11 @@ struct mod_arch_specific { -+ const struct exception_table_entry *dbe_start; -+ const struct exception_table_entry *dbe_end; -+ struct mips_hi16 *r_mips_hi16_list; -++ -++ void *phys_plt_tbl; -++ void *virt_plt_tbl; -++ unsigned int phys_plt_offset; -++ unsigned int virt_plt_offset; -+ }; -+ -+ typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */ -+--- a/arch/mips/kernel/module.c -++++ b/arch/mips/kernel/module.c -+@@ -44,14 +44,221 @@ struct mips_hi16 { -+ static LIST_HEAD(dbe_list); -+ static DEFINE_SPINLOCK(dbe_lock); -+ -+-#ifdef MODULE_START -++/* -++ * Get the potential max trampolines size required of the init and -++ * non-init sections. Only used if we cannot find enough contiguous -++ * physically mapped memory to put the module into. -++ */ -++static unsigned int -++get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, -++ const char *secstrings, unsigned int symindex, bool is_init) -++{ -++ unsigned long ret = 0; -++ unsigned int i, j; -++ Elf_Sym *syms; -++ -++ /* Everything marked ALLOC (this includes the exported symbols) */ -++ for (i = 1; i < hdr->e_shnum; ++i) { -++ unsigned int info = sechdrs[i].sh_info; -++ -++ if (sechdrs[i].sh_type != SHT_REL -++ && sechdrs[i].sh_type != SHT_RELA) -++ continue; -++ -++ /* Not a valid relocation section? */ -++ if (info >= hdr->e_shnum) -++ continue; -++ -++ /* Don't bother with non-allocated sections */ -++ if (!(sechdrs[info].sh_flags & SHF_ALLOC)) -++ continue; -++ -++ /* If it's called *.init*, and we're not init, we're -++ not interested */ -++ if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0) -++ != is_init) -++ continue; -++ -++ syms = (Elf_Sym *) sechdrs[symindex].sh_addr; -++ if (sechdrs[i].sh_type == SHT_REL) { -++ Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr; -++ unsigned int size = sechdrs[i].sh_size / sizeof(*rel); -++ -++ for (j = 0; j < size; ++j) { -++ Elf_Sym *sym; -++ -++ if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26) -++ continue; -++ -++ sym = syms + ELF_MIPS_R_SYM(rel[j]); -++ if (!is_init && sym->st_shndx != SHN_UNDEF) -++ continue; -++ -++ ret += 4 * sizeof(int); -++ } -++ } else { -++ Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr; -++ unsigned int size = sechdrs[i].sh_size / sizeof(*rela); -++ -++ for (j = 0; j < size; ++j) { -++ Elf_Sym *sym; -++ -++ if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26) -++ continue; -++ -++ sym = syms + ELF_MIPS_R_SYM(rela[j]); -++ if (!is_init && sym->st_shndx != SHN_UNDEF) -++ continue; -++ -++ ret += 4 * sizeof(int); -++ } -++ } -++ } -++ -++ return ret; -++} -++ -++#ifndef MODULE_START -++static void *alloc_phys(unsigned long size) -++{ -++ unsigned order; -++ struct page *page; -++ struct page *p; -++ -++ size = PAGE_ALIGN(size); -++ order = get_order(size); -++ -++ page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN | -++ __GFP_THISNODE, order); -++ if (!page) -++ return NULL; -++ -++ split_page(page, order); -++ -++ /* mark all pages except for the last one */ -++ for (p = page; p + 1 < page + (size >> PAGE_SHIFT); ++p) -++ set_bit(PG_owner_priv_1, &p->flags); -++ -++ for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p) -++ __free_page(p); -++ -++ return page_address(page); -++} -++#endif -++ -++static void free_phys(void *ptr) -++{ -++ struct page *page; -++ bool free; -++ -++ page = virt_to_page(ptr); -++ do { -++ free = test_and_clear_bit(PG_owner_priv_1, &page->flags); -++ __free_page(page); -++ page++; -++ } while (free); -++} -++ -++ -+ void *module_alloc(unsigned long size) -+ { -++#ifdef MODULE_START -+ return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END, -+ GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE, -+ __builtin_return_address(0)); -++#else -++ void *ptr; -++ -++ if (size == 0) -++ return NULL; -++ -++ ptr = alloc_phys(size); -++ -++ /* If we failed to allocate physically contiguous memory, -++ * fall back to regular vmalloc. The module loader code will -++ * create jump tables to handle long jumps */ -++ if (!ptr) -++ return vmalloc(size); -++ -++ return ptr; -++#endif -+ } -++ -++static inline bool is_phys_addr(void *ptr) -++{ -++#ifdef CONFIG_64BIT -++ return (KSEGX((unsigned long)ptr) == CKSEG0); -++#else -++ return (KSEGX(ptr) == KSEG0); -+ #endif -++} -++ -++/* Free memory returned from module_alloc */ -++void module_memfree(void *module_region) -++{ -++ if (is_phys_addr(module_region)) -++ free_phys(module_region); -++ else -++ vfree(module_region); -++} -++ -++static void *__module_alloc(int size, bool phys) -++{ -++ void *ptr; -++ -++ if (phys) -++ ptr = kmalloc(size, GFP_KERNEL); -++ else -++ ptr = vmalloc(size); -++ return ptr; -++} -++ -++static void __module_free(void *ptr) -++{ -++ if (is_phys_addr(ptr)) -++ kfree(ptr); -++ else -++ vfree(ptr); -++} -++ -++int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, -++ char *secstrings, struct module *mod) -++{ -++ unsigned int symindex = 0; -++ unsigned int core_size, init_size; -++ int i; -++ -++ mod->arch.phys_plt_offset = 0; -++ mod->arch.virt_plt_offset = 0; -++ mod->arch.phys_plt_tbl = NULL; -++ mod->arch.virt_plt_tbl = NULL; -++ -++ if (IS_ENABLED(CONFIG_64BIT)) -++ return 0; -++ -++ for (i = 1; i < hdr->e_shnum; i++) -++ if (sechdrs[i].sh_type == SHT_SYMTAB) -++ symindex = i; -++ -++ core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false); -++ init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true); -++ -++ if ((core_size + init_size) == 0) -++ return 0; -++ -++ mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1); -++ if (!mod->arch.phys_plt_tbl) -++ return -ENOMEM; -++ -++ mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0); -++ if (!mod->arch.virt_plt_tbl) { -++ __module_free(mod->arch.phys_plt_tbl); -++ mod->arch.phys_plt_tbl = NULL; -++ return -ENOMEM; -++ } -++ -++ return 0; -++} -+ -+ static int apply_r_mips_none(struct module *me, u32 *location, -+ u32 base, Elf_Addr v, bool rela) -+@@ -67,9 +274,40 @@ static int apply_r_mips_32(struct module -+ return 0; -+ } -+ -++static Elf_Addr add_plt_entry_to(unsigned *plt_offset, -++ void *start, Elf_Addr v) -++{ -++ unsigned *tramp = start + *plt_offset; -++ *plt_offset += 4 * sizeof(int); -++ -++ /* adjust carry for addiu */ -++ if (v & 0x00008000) -++ v += 0x10000; -++ -++ tramp[0] = 0x3c190000 | (v >> 16); /* lui t9, hi16 */ -++ tramp[1] = 0x27390000 | (v & 0xffff); /* addiu t9, t9, lo16 */ -++ tramp[2] = 0x03200008; /* jr t9 */ -++ tramp[3] = 0x00000000; /* nop */ -++ -++ return (Elf_Addr) tramp; -++} -++ -++static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v) -++{ -++ if (is_phys_addr(location)) -++ return add_plt_entry_to(&me->arch.phys_plt_offset, -++ me->arch.phys_plt_tbl, v); -++ else -++ return add_plt_entry_to(&me->arch.virt_plt_offset, -++ me->arch.virt_plt_tbl, v); -++ -++} -++ -+ static int apply_r_mips_26(struct module *me, u32 *location, -+ u32 base, Elf_Addr v, bool rela) -+ { -++ u32 ofs = base & 0x03ffffff; -++ -+ if (v % 4) { -+ pr_err("module %s: dangerous R_MIPS_26 relocation\n", -+ me->name); -+@@ -77,13 +315,17 @@ static int apply_r_mips_26(struct module -+ } -+ -+ if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { -+- pr_err("module %s: relocation overflow\n", -+- me->name); -+- return -ENOEXEC; -++ v = add_plt_entry(me, location, v + (ofs << 2)); -++ if (!v) { -++ pr_err("module %s: relocation overflow\n", -++ me->name); -++ return -ENOEXEC; -++ } -++ ofs = 0; -+ } -+ -+ *location = (*location & ~0x03ffffff) | -+- ((base + (v >> 2)) & 0x03ffffff); -++ ((ofs + (v >> 2)) & 0x03ffffff); -+ -+ return 0; -+ } -+@@ -459,9 +701,36 @@ int module_finalize(const Elf_Ehdr *hdr, -+ list_add(&me->arch.dbe_list, &dbe_list); -+ spin_unlock_irq(&dbe_lock); -+ } -++ -++ /* Get rid of the fixup trampoline if we're running the module -++ * from physically mapped address space */ -++ if (me->arch.phys_plt_offset == 0) { -++ __module_free(me->arch.phys_plt_tbl); -++ me->arch.phys_plt_tbl = NULL; -++ } -++ if (me->arch.virt_plt_offset == 0) { -++ __module_free(me->arch.virt_plt_tbl); -++ me->arch.virt_plt_tbl = NULL; -++ } -++ -+ return 0; -+ } -+ -++void module_arch_freeing_init(struct module *mod) -++{ -++ if (mod->state == MODULE_STATE_LIVE) -++ return; -++ -++ if (mod->arch.phys_plt_tbl) { -++ __module_free(mod->arch.phys_plt_tbl); -++ mod->arch.phys_plt_tbl = NULL; -++ } -++ if (mod->arch.virt_plt_tbl) { -++ __module_free(mod->arch.virt_plt_tbl); -++ mod->arch.virt_plt_tbl = NULL; -++ } -++} -++ -+ void module_arch_cleanup(struct module *mod) -+ { -+ spin_lock_irq(&dbe_lock); -diff --git a/target/linux/generic/pending-4.14/306-mips_mem_functions_performance.patch b/target/linux/generic/pending-4.14/306-mips_mem_functions_performance.patch -new file mode 100644 -index 0000000000..e73cfd61b3 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/306-mips_mem_functions_performance.patch -@@ -0,0 +1,106 @@ -+From: Felix Fietkau -+Subject: [PATCH] mips: allow the compiler to optimize memset, memcmp, memcpy for better performance and (in some instances) smaller code -+ -+lede-commit: 07e59c7bc7f375f792ec9734be42fe4fa391a8bb -+Signed-off-by: Felix Fietkau -+--- -+ arch/mips/boot/compressed/Makefile | 3 ++- -+ arch/mips/include/asm/string.h | 38 ++++++++++++++++++++++++++++++++++++++ -+ arch/mips/lib/Makefile | 2 +- -+ arch/mips/lib/memcmp.c | 22 ++++++++++++++++++++++ -+ 4 files changed, 63 insertions(+), 2 deletions(-) -+ create mode 100644 arch/mips/lib/memcmp.c -+ -+--- a/arch/mips/boot/compressed/Makefile -++++ b/arch/mips/boot/compressed/Makefile -+@@ -23,7 +23,8 @@ KBUILD_CFLAGS := $(filter-out -pg, $(KBU -+ KBUILD_CFLAGS := $(filter-out -fstack-protector, $(KBUILD_CFLAGS)) -+ -+ KBUILD_CFLAGS := $(KBUILD_CFLAGS) -D__KERNEL__ \ -+- -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" -++ -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" \ -++ -D__ZBOOT__ -+ -+ KBUILD_AFLAGS := $(KBUILD_AFLAGS) -D__ASSEMBLY__ \ -+ -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \ -+--- a/arch/mips/include/asm/string.h -++++ b/arch/mips/include/asm/string.h -+@@ -140,4 +140,42 @@ extern void *memcpy(void *__to, __const_ -+ #define __HAVE_ARCH_MEMMOVE -+ extern void *memmove(void *__dest, __const__ void *__src, size_t __n); -+ -++#ifndef __ZBOOT__ -++#define memset(__s, __c, len) \ -++({ \ -++ size_t __len = (len); \ -++ void *__ret; \ -++ if (__builtin_constant_p(len) && __len >= 64) \ -++ __ret = memset((__s), (__c), __len); \ -++ else \ -++ __ret = __builtin_memset((__s), (__c), __len); \ -++ __ret; \ -++}) -++ -++#define memcpy(dst, src, len) \ -++({ \ -++ size_t __len = (len); \ -++ void *__ret; \ -++ if (__builtin_constant_p(len) && __len >= 64) \ -++ __ret = memcpy((dst), (src), __len); \ -++ else \ -++ __ret = __builtin_memcpy((dst), (src), __len); \ -++ __ret; \ -++}) -++ -++#define memmove(dst, src, len) \ -++({ \ -++ size_t __len = (len); \ -++ void *__ret; \ -++ if (__builtin_constant_p(len) && __len >= 64) \ -++ __ret = memmove((dst), (src), __len); \ -++ else \ -++ __ret = __builtin_memmove((dst), (src), __len); \ -++ __ret; \ -++}) -++ -++#define __HAVE_ARCH_MEMCMP -++#define memcmp(src1, src2, len) __builtin_memcmp((src1), (src2), (len)) -++#endif -++ -+ #endif /* _ASM_STRING_H */ -+--- a/arch/mips/lib/Makefile -++++ b/arch/mips/lib/Makefile -+@@ -5,7 +5,7 @@ -+ -+ lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \ -+ mips-atomic.o strncpy_user.o \ -+- strnlen_user.o uncached.o -++ strnlen_user.o uncached.o memcmp.o -+ -+ obj-y += iomap.o iomap_copy.o -+ obj-$(CONFIG_PCI) += iomap-pci.o -+--- /dev/null -++++ b/arch/mips/lib/memcmp.c -+@@ -0,0 +1,22 @@ -++/* -++ * copied from linux/lib/string.c -++ * -++ * Copyright (C) 1991, 1992 Linus Torvalds -++ */ -++ -++#include -++#include -++ -++#undef memcmp -++int memcmp(const void *cs, const void *ct, size_t count) -++{ -++ const unsigned char *su1, *su2; -++ int res = 0; -++ -++ for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) -++ if ((res = *su1 - *su2) != 0) -++ break; -++ return res; -++} -++EXPORT_SYMBOL(memcmp); -++ -diff --git a/target/linux/generic/pending-4.14/307-mips_highmem_offset.patch b/target/linux/generic/pending-4.14/307-mips_highmem_offset.patch -new file mode 100644 -index 0000000000..0529b0c5c8 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/307-mips_highmem_offset.patch -@@ -0,0 +1,19 @@ -+From: Felix Fietkau -+Subject: kernel: adjust mips highmem offset to avoid the need for -mlong-calls on systems with >256M RAM -+ -+Signed-off-by: Felix Fietkau -+--- -+ arch/mips/include/asm/mach-generic/spaces.h | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/arch/mips/include/asm/mach-generic/spaces.h -++++ b/arch/mips/include/asm/mach-generic/spaces.h -+@@ -46,7 +46,7 @@ -+ * Memory above this physical address will be considered highmem. -+ */ -+ #ifndef HIGHMEM_START -+-#define HIGHMEM_START _AC(0x20000000, UL) -++#define HIGHMEM_START _AC(0x10000000, UL) -+ #endif -+ -+ #endif /* CONFIG_32BIT */ -diff --git a/target/linux/generic/pending-4.14/308-mips32r2_tune.patch b/target/linux/generic/pending-4.14/308-mips32r2_tune.patch -new file mode 100644 -index 0000000000..a67306031c ---- /dev/null -+++ b/target/linux/generic/pending-4.14/308-mips32r2_tune.patch -@@ -0,0 +1,22 @@ -+From: Felix Fietkau -+Subject: kernel: add -mtune=34kc to MIPS CFLAGS when building for mips32r2 -+ -+This provides a good tradeoff across at least 24Kc-74Kc, while also -+producing smaller code. -+ -+Signed-off-by: Felix Fietkau -+--- -+ arch/mips/Makefile | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/arch/mips/Makefile -++++ b/arch/mips/Makefile -+@@ -166,7 +166,7 @@ cflags-$(CONFIG_CPU_VR41XX) += -march=r4 -+ cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap -+ cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap -+ cflags-$(CONFIG_CPU_MIPS32_R1) += -march=mips32 -Wa,--trap -+-cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -Wa,--trap -++cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -mtune=34kc -Wa,--trap -+ cflags-$(CONFIG_CPU_MIPS32_R6) += -march=mips32r6 -Wa,--trap -modd-spreg -+ cflags-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,--trap -+ cflags-$(CONFIG_CPU_MIPS64_R2) += -march=mips64r2 -Wa,--trap -diff --git a/target/linux/generic/pending-4.14/309-MIPS-Add-CPU-option-reporting-to-proc-cpuinfo.patch b/target/linux/generic/pending-4.14/309-MIPS-Add-CPU-option-reporting-to-proc-cpuinfo.patch -new file mode 100644 -index 0000000000..954830509c ---- /dev/null -+++ b/target/linux/generic/pending-4.14/309-MIPS-Add-CPU-option-reporting-to-proc-cpuinfo.patch -@@ -0,0 +1,140 @@ -+From 87ec87c2ad615c1a177cd08ef5fa29fc739f6e50 Mon Sep 17 00:00:00 2001 -+From: Hauke Mehrtens -+Date: Sun, 23 Dec 2018 18:06:53 +0100 -+Subject: [PATCH] MIPS: Add CPU option reporting to /proc/cpuinfo -+ -+Many MIPS CPUs have optional CPU features which are not activates for -+all CPU cores. Print the CPU options which are implemented in the core -+in /proc/cpuinfo. This makes it possible to see what features are -+supported and which are not supported. This should cover all standard -+MIPS extensions, before it only printed information about the main MIPS -+ASEs. -+ -+Signed-off-by: Hauke Mehrtens -+--- -+ arch/mips/kernel/proc.c | 116 ++++++++++++++++++++++++++++++++++++++++ -+ 1 file changed, 116 insertions(+) -+ -+--- a/arch/mips/kernel/proc.c -++++ b/arch/mips/kernel/proc.c -+@@ -130,6 +130,120 @@ static int show_cpuinfo(struct seq_file -+ seq_printf(m, "micromips kernel\t: %s\n", -+ (read_c0_config3() & MIPS_CONF3_ISA_OE) ? "yes" : "no"); -+ } -++ -++ seq_printf(m, "Options implemented\t:"); -++ if (cpu_has_tlb) -++ seq_printf(m, "%s", " tlb"); -++ if (cpu_has_ftlb) -++ seq_printf(m, "%s", " ftlb"); -++ if (cpu_has_tlbinv) -++ seq_printf(m, "%s", " tlbinv"); -++ if (cpu_has_segments) -++ seq_printf(m, "%s", " segments"); -++ if (cpu_has_rixiex) -++ seq_printf(m, "%s", " rixiex"); -++ if (cpu_has_ldpte) -++ seq_printf(m, "%s", " ldpte"); -++ if (cpu_has_maar) -++ seq_printf(m, "%s", " maar"); -++ if (cpu_has_rw_llb) -++ seq_printf(m, "%s", " rw_llb"); -++ if (cpu_has_4kex) -++ seq_printf(m, "%s", " 4kex"); -++ if (cpu_has_3k_cache) -++ seq_printf(m, "%s", " 3k_cache"); -++ if (cpu_has_4k_cache) -++ seq_printf(m, "%s", " 4k_cache"); -++ if (cpu_has_6k_cache) -++ seq_printf(m, "%s", " 6k_cache"); -++ if (cpu_has_8k_cache) -++ seq_printf(m, "%s", " 8k_cache"); -++ if (cpu_has_tx39_cache) -++ seq_printf(m, "%s", " tx39_cache"); -++ if (cpu_has_octeon_cache) -++ seq_printf(m, "%s", " octeon_cache"); -++ if (cpu_has_fpu) -++ seq_printf(m, "%s", " fpu"); -++ if (cpu_has_32fpr) -++ seq_printf(m, "%s", " 32fpr"); -++ if (cpu_has_cache_cdex_p) -++ seq_printf(m, "%s", " cache_cdex_p"); -++ if (cpu_has_cache_cdex_s) -++ seq_printf(m, "%s", " cache_cdex_s"); -++ if (cpu_has_prefetch) -++ seq_printf(m, "%s", " prefetch"); -++ if (cpu_has_mcheck) -++ seq_printf(m, "%s", " mcheck"); -++ if (cpu_has_ejtag) -++ seq_printf(m, "%s", " ejtag"); -++ if (cpu_has_llsc) -++ seq_printf(m, "%s", " llsc"); -++ if (cpu_has_bp_ghist) -++ seq_printf(m, "%s", " bp_ghist"); -++ if (cpu_has_guestctl0ext) -++ seq_printf(m, "%s", " guestctl0ext"); -++ if (cpu_has_guestctl1) -++ seq_printf(m, "%s", " guestctl1"); -++ if (cpu_has_guestctl2) -++ seq_printf(m, "%s", " guestctl2"); -++ if (cpu_has_guestid) -++ seq_printf(m, "%s", " guestid"); -++ if (cpu_has_drg) -++ seq_printf(m, "%s", " drg"); -++ if (cpu_has_rixi) -++ seq_printf(m, "%s", " rixi"); -++ if (cpu_has_lpa) -++ seq_printf(m, "%s", " lpa"); -++ if (cpu_has_mvh) -++ seq_printf(m, "%s", " mvh"); -++ if (cpu_has_vtag_icache) -++ seq_printf(m, "%s", " vtag_icache"); -++ if (cpu_has_dc_aliases) -++ seq_printf(m, "%s", " dc_aliases"); -++ if (cpu_has_ic_fills_f_dc) -++ seq_printf(m, "%s", " ic_fills_f_dc"); -++ if (cpu_has_pindexed_dcache) -++ seq_printf(m, "%s", " pindexed_dcache"); -++ if (cpu_has_userlocal) -++ seq_printf(m, "%s", " userlocal"); -++ if (cpu_has_nofpuex) -++ seq_printf(m, "%s", " nofpuex"); -++ if (cpu_has_vint) -++ seq_printf(m, "%s", " vint"); -++ if (cpu_has_veic) -++ seq_printf(m, "%s", " veic"); -++ if (cpu_has_inclusive_pcaches) -++ seq_printf(m, "%s", " inclusive_pcaches"); -++ if (cpu_has_perf_cntr_intr_bit) -++ seq_printf(m, "%s", " perf_cntr_intr_bit"); -++ if (cpu_has_ufr) -++ seq_printf(m, "%s", " ufr"); -++ if (cpu_has_fre) -++ seq_printf(m, "%s", " fre"); -++ if (cpu_has_cdmm) -++ seq_printf(m, "%s", " cdmm"); -++ if (cpu_has_small_pages) -++ seq_printf(m, "%s", " small_pages"); -++ if (cpu_has_nan_legacy) -++ seq_printf(m, "%s", " nan_legacy"); -++ if (cpu_has_nan_2008) -++ seq_printf(m, "%s", " nan_2008"); -++ if (cpu_has_ebase_wg) -++ seq_printf(m, "%s", " ebase_wg"); -++ if (cpu_has_badinstr) -++ seq_printf(m, "%s", " badinstr"); -++ if (cpu_has_badinstrp) -++ seq_printf(m, "%s", " badinstrp"); -++ if (cpu_has_contextconfig) -++ seq_printf(m, "%s", " contextconfig"); -++ if (cpu_has_perf) -++ seq_printf(m, "%s", " perf"); -++ if (cpu_has_shared_ftlb_ram) -++ seq_printf(m, "%s", " shared_ftlb_ram"); -++ if (cpu_has_shared_ftlb_entries) -++ seq_printf(m, "%s", " shared_ftlb_entries"); -++ seq_printf(m, "\n"); -++ -+ seq_printf(m, "shadow register sets\t: %d\n", -+ cpu_data[n].srsets); -+ seq_printf(m, "kscratch registers\t: %d\n", -diff --git a/target/linux/generic/pending-4.14/310-arm_module_unresolved_weak_sym.patch b/target/linux/generic/pending-4.14/310-arm_module_unresolved_weak_sym.patch -new file mode 100644 -index 0000000000..bc9f0a4c4d ---- /dev/null -+++ b/target/linux/generic/pending-4.14/310-arm_module_unresolved_weak_sym.patch -@@ -0,0 +1,22 @@ -+From: Felix Fietkau -+Subject: fix errors in unresolved weak symbols on arm -+ -+lede-commit: 570699d4838a907c3ef9f2819bf19eb72997b32f -+Signed-off-by: Felix Fietkau -+--- -+ arch/arm/kernel/module.c | 4 ++++ -+ 1 file changed, 4 insertions(+) -+ -+--- a/arch/arm/kernel/module.c -++++ b/arch/arm/kernel/module.c -+@@ -95,6 +95,10 @@ apply_relocate(Elf32_Shdr *sechdrs, cons -+ return -ENOEXEC; -+ } -+ -++ if ((IS_ERR_VALUE(sym->st_value) || !sym->st_value) && -++ ELF_ST_BIND(sym->st_info) == STB_WEAK) -++ continue; -++ -+ loc = dstsec->sh_addr + rel->r_offset; -+ -+ switch (ELF32_R_TYPE(rel->r_info)) { -diff --git a/target/linux/generic/pending-4.14/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch b/target/linux/generic/pending-4.14/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch -new file mode 100644 -index 0000000000..44d85b5b86 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch -@@ -0,0 +1,274 @@ -+From: Yousong Zhou -+Subject: MIPS: kexec: Accept command line parameters from userspace. -+ -+Signed-off-by: Yousong Zhou -+--- -+ arch/mips/kernel/machine_kexec.c | 153 +++++++++++++++++++++++++++++++----- -+ arch/mips/kernel/machine_kexec.h | 20 +++++ -+ arch/mips/kernel/relocate_kernel.S | 21 +++-- -+ 3 files changed, 167 insertions(+), 27 deletions(-) -+ create mode 100644 arch/mips/kernel/machine_kexec.h -+ -+--- a/arch/mips/kernel/machine_kexec.c -++++ b/arch/mips/kernel/machine_kexec.c -+@@ -10,14 +10,11 @@ -+ #include -+ #include -+ -++#include -+ #include -+ #include -+- -+-extern const unsigned char relocate_new_kernel[]; -+-extern const size_t relocate_new_kernel_size; -+- -+-extern unsigned long kexec_start_address; -+-extern unsigned long kexec_indirection_page; -++#include -++#include "machine_kexec.h" -+ -+ int (*_machine_kexec_prepare)(struct kimage *) = NULL; -+ void (*_machine_kexec_shutdown)(void) = NULL; -+@@ -28,6 +25,101 @@ atomic_t kexec_ready_to_reboot = ATOMIC_ -+ void (*_crash_smp_send_stop)(void) = NULL; -+ #endif -+ -++static void machine_kexec_print_args(void) -++{ -++ unsigned long argc = (int)kexec_args[0]; -++ int i; -++ -++ pr_info("kexec_args[0] (argc): %lu\n", argc); -++ pr_info("kexec_args[1] (argv): %p\n", (void *)kexec_args[1]); -++ pr_info("kexec_args[2] (env ): %p\n", (void *)kexec_args[2]); -++ pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]); -++ -++ for (i = 0; i < argc; i++) { -++ pr_info("kexec_argv[%d] = %p, %s\n", -++ i, kexec_argv[i], kexec_argv[i]); -++ } -++} -++ -++static void machine_kexec_init_argv(struct kimage *image) -++{ -++ void __user *buf = NULL; -++ size_t bufsz; -++ size_t size; -++ int i; -++ -++ bufsz = 0; -++ for (i = 0; i < image->nr_segments; i++) { -++ struct kexec_segment *seg; -++ -++ seg = &image->segment[i]; -++ if (seg->bufsz < 6) -++ continue; -++ -++ if (strncmp((char *) seg->buf, "kexec ", 6)) -++ continue; -++ -++ buf = seg->buf; -++ bufsz = seg->bufsz; -++ break; -++ } -++ -++ if (!buf) -++ return; -++ -++ size = KEXEC_COMMAND_LINE_SIZE; -++ size = min(size, bufsz); -++ if (size < bufsz) -++ pr_warn("kexec command line truncated to %zd bytes\n", size); -++ -++ /* Copy to kernel space */ -++ if (copy_from_user(kexec_argv_buf, buf, size)) -++ pr_warn("kexec command line copy to kernel space failed\n"); -++ -++ kexec_argv_buf[size - 1] = 0; -++} -++ -++static void machine_kexec_parse_argv(struct kimage *image) -++{ -++ char *reboot_code_buffer; -++ int reloc_delta; -++ char *ptr; -++ int argc; -++ int i; -++ -++ ptr = kexec_argv_buf; -++ argc = 0; -++ -++ /* -++ * convert command line string to array of parameters -++ * (as bootloader does). -++ */ -++ while (ptr && *ptr && (KEXEC_MAX_ARGC > argc)) { -++ if (*ptr == ' ') { -++ *ptr++ = '\0'; -++ continue; -++ } -++ -++ kexec_argv[argc++] = ptr; -++ ptr = strchr(ptr, ' '); -++ } -++ -++ if (!argc) -++ return; -++ -++ kexec_args[0] = argc; -++ kexec_args[1] = (unsigned long)kexec_argv; -++ kexec_args[2] = 0; -++ kexec_args[3] = 0; -++ -++ reboot_code_buffer = page_address(image->control_code_page); -++ reloc_delta = reboot_code_buffer - (char *)kexec_relocate_new_kernel; -++ -++ kexec_args[1] += reloc_delta; -++ for (i = 0; i < argc; i++) -++ kexec_argv[i] += reloc_delta; -++} -++ -+ static void kexec_image_info(const struct kimage *kimage) -+ { -+ unsigned long i; -+@@ -52,6 +144,18 @@ int -+ machine_kexec_prepare(struct kimage *kimage) -+ { -+ kexec_image_info(kimage); -++ /* -++ * Whenever arguments passed from kexec-tools, Init the arguments as -++ * the original ones to try avoiding booting failure. -++ */ -++ -++ kexec_args[0] = fw_arg0; -++ kexec_args[1] = fw_arg1; -++ kexec_args[2] = fw_arg2; -++ kexec_args[3] = fw_arg3; -++ -++ machine_kexec_init_argv(kimage); -++ machine_kexec_parse_argv(kimage); -+ -+ if (_machine_kexec_prepare) -+ return _machine_kexec_prepare(kimage); -+@@ -89,10 +193,12 @@ machine_kexec(struct kimage *image) -+ unsigned long *ptr; -+ -+ reboot_code_buffer = -+- (unsigned long)page_address(image->control_code_page); -++ (unsigned long)page_address(image->control_code_page); -++ pr_info("reboot_code_buffer = %p\n", (void *)reboot_code_buffer); -+ -+ kexec_start_address = -+ (unsigned long) phys_to_virt(image->start); -++ pr_info("kexec_start_address = %p\n", (void *)kexec_start_address); -+ -+ if (image->type == KEXEC_TYPE_DEFAULT) { -+ kexec_indirection_page = -+@@ -100,9 +206,19 @@ machine_kexec(struct kimage *image) -+ } else { -+ kexec_indirection_page = (unsigned long)&image->head; -+ } -++ pr_info("kexec_indirection_page = %p\n", (void *)kexec_indirection_page); -+ -+- memcpy((void*)reboot_code_buffer, relocate_new_kernel, -+- relocate_new_kernel_size); -++ pr_info("Where is memcpy: %p\n", memcpy); -++ pr_info("kexec_relocate_new_kernel = %p, kexec_relocate_new_kernel_end = %p\n", -++ (void *)kexec_relocate_new_kernel, &kexec_relocate_new_kernel_end); -++ pr_info("Copy %lu bytes from %p to %p\n", KEXEC_RELOCATE_NEW_KERNEL_SIZE, -++ (void *)kexec_relocate_new_kernel, (void *)reboot_code_buffer); -++ memcpy((void*)reboot_code_buffer, kexec_relocate_new_kernel, -++ KEXEC_RELOCATE_NEW_KERNEL_SIZE); -++ -++ pr_info("Before _print_args().\n"); -++ machine_kexec_print_args(); -++ pr_info("Before eval loop.\n"); -+ -+ /* -+ * The generic kexec code builds a page list with physical -+@@ -124,15 +240,16 @@ machine_kexec(struct kimage *image) -+ /* -+ * we do not want to be bothered. -+ */ -++ pr_info("Before irq_disable.\n"); -+ local_irq_disable(); -+ -+- printk("Will call new kernel at %08lx\n", image->start); -+- printk("Bye ...\n"); -++ pr_info("Will call new kernel at %08lx\n", image->start); -++ pr_info("Bye ...\n"); -+ __flush_cache_all(); -+ #ifdef CONFIG_SMP -+ /* All secondary cpus now may jump to kexec_wait cycle */ -+ relocated_kexec_smp_wait = reboot_code_buffer + -+- (void *)(kexec_smp_wait - relocate_new_kernel); -++ (void *)(kexec_smp_wait - kexec_relocate_new_kernel); -+ smp_wmb(); -+ atomic_set(&kexec_ready_to_reboot, 1); -+ #endif -+--- /dev/null -++++ b/arch/mips/kernel/machine_kexec.h -+@@ -0,0 +1,20 @@ -++#ifndef _MACHINE_KEXEC_H -++#define _MACHINE_KEXEC_H -++ -++#ifndef __ASSEMBLY__ -++extern const unsigned char kexec_relocate_new_kernel[]; -++extern unsigned long kexec_relocate_new_kernel_end; -++extern unsigned long kexec_start_address; -++extern unsigned long kexec_indirection_page; -++ -++extern char kexec_argv_buf[]; -++extern char *kexec_argv[]; -++ -++#define KEXEC_RELOCATE_NEW_KERNEL_SIZE ((unsigned long)&kexec_relocate_new_kernel_end - (unsigned long)kexec_relocate_new_kernel) -++#endif /* !__ASSEMBLY__ */ -++ -++#define KEXEC_COMMAND_LINE_SIZE 256 -++#define KEXEC_ARGV_SIZE (KEXEC_COMMAND_LINE_SIZE / 16) -++#define KEXEC_MAX_ARGC (KEXEC_ARGV_SIZE / sizeof(long)) -++ -++#endif -+--- a/arch/mips/kernel/relocate_kernel.S -++++ b/arch/mips/kernel/relocate_kernel.S -+@@ -12,8 +12,9 @@ -+ #include -+ #include -+ #include -++#include "machine_kexec.h" -+ -+-LEAF(relocate_new_kernel) -++LEAF(kexec_relocate_new_kernel) -+ PTR_L a0, arg0 -+ PTR_L a1, arg1 -+ PTR_L a2, arg2 -+@@ -98,7 +99,7 @@ done: -+ #endif -+ /* jump to kexec_start_address */ -+ j s1 -+- END(relocate_new_kernel) -++ END(kexec_relocate_new_kernel) -+ -+ #ifdef CONFIG_SMP -+ /* -+@@ -184,9 +185,15 @@ kexec_indirection_page: -+ PTR 0 -+ .size kexec_indirection_page, PTRSIZE -+ -+-relocate_new_kernel_end: -++kexec_argv_buf: -++ EXPORT(kexec_argv_buf) -++ .skip KEXEC_COMMAND_LINE_SIZE -++ .size kexec_argv_buf, KEXEC_COMMAND_LINE_SIZE -++ -++kexec_argv: -++ EXPORT(kexec_argv) -++ .skip KEXEC_ARGV_SIZE -++ .size kexec_argv, KEXEC_ARGV_SIZE -+ -+-relocate_new_kernel_size: -+- EXPORT(relocate_new_kernel_size) -+- PTR relocate_new_kernel_end - relocate_new_kernel -+- .size relocate_new_kernel_size, PTRSIZE -++kexec_relocate_new_kernel_end: -++ EXPORT(kexec_relocate_new_kernel_end) -diff --git a/target/linux/generic/pending-4.14/332-arc-add-OWRTDTB-section.patch b/target/linux/generic/pending-4.14/332-arc-add-OWRTDTB-section.patch -new file mode 100644 -index 0000000000..1b75bf2a06 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/332-arc-add-OWRTDTB-section.patch -@@ -0,0 +1,84 @@ -+From 34ef04f3845ed2b47d57dd9d3b795b16e1f8185a Mon Sep 17 00:00:00 2001 -+From: Evgeniy Didin -+Date: Fri, 15 Mar 2019 18:53:38 +0300 -+Subject: [PATCH] arc add OWRTDTB section -+ -+This change allows OpenWRT to patch resulting kernel binary with -+external .dtb. -+ -+That allows us to re-use exactky the same vmlinux on different boards -+given its ARC core configurations match (at least cache line sizes etc). -+ -+""patch-dtb" searches for ASCII "OWRTDTB:" strign and copies external -+.dtb right after it, keeping the string in place. -+ -+Signed-off-by: Eugeniy Paltsev -+Signed-off-by: Alexey Brodkin -+Signed-off-by: Evgeniy Didin -+--- -+ arch/arc/kernel/head.S | 10 ++++++++++ -+ arch/arc/kernel/setup.c | 4 +++- -+ arch/arc/kernel/vmlinux.lds.S | 13 +++++++++++++ -+ 3 files changed, 26 insertions(+), 1 deletion(-) -+ -+--- a/arch/arc/kernel/head.S -++++ b/arch/arc/kernel/head.S -+@@ -59,6 +59,16 @@ -+ #endif -+ .endm -+ -++ ; Here "patch-dtb" will embed external .dtb -++ ; Note "patch-dtb" searches for ASCII "OWRTDTB:" string -++ ; and pastes .dtb right after it, hense the string precedes -++ ; __image_dtb symbol. -++ .section .owrt, "aw",@progbits -++ .ascii "OWRTDTB:" -++ENTRY(__image_dtb) -++ .fill 0x4000 -++END(__image_dtb) -++ -+ .section .init.text, "ax",@progbits -+ -+ ;---------------------------------------------------------------- -+--- a/arch/arc/kernel/setup.c -++++ b/arch/arc/kernel/setup.c -+@@ -438,6 +438,8 @@ static inline bool uboot_arg_invalid(uns -+ /* We always pass 0 as magic from U-boot */ -+ #define UBOOT_MAGIC_VALUE 0 -+ -++extern struct boot_param_header __image_dtb; -++ -+ void __init handle_uboot_args(void) -+ { -+ bool use_embedded_dtb = true; -+@@ -478,7 +480,7 @@ ignore_uboot_args: -+ #endif -+ -+ if (use_embedded_dtb) { -+- machine_desc = setup_machine_fdt(__dtb_start); -++ machine_desc = setup_machine_fdt(&__image_dtb); -+ if (!machine_desc) -+ panic("Embedded DT invalid\n"); -+ } -+--- a/arch/arc/kernel/vmlinux.lds.S -++++ b/arch/arc/kernel/vmlinux.lds.S -+@@ -29,6 +29,19 @@ SECTIONS -+ */ -+ -+ . = CONFIG_LINUX_LINK_BASE; -++ /* -++ * In OpenWRT we want to patch built binary embedding .dtb of choice. -++ * This is implemented with "patch-dtb" utility which searches for -++ * "OWRTDTB:" string in first 16k of image and if it is found -++ * copies .dtb right after mentioned string. -++ * -++ * Note: "OWRTDTB:" won't be overwritten with .dtb, .dtb will follow it. -++ */ -++ .owrt : { -++ *(.owrt) -++ . = ALIGN(PAGE_SIZE); -++ } -++ -+ -+ _int_vec_base_lds = .; -+ .vector : { -diff --git a/target/linux/generic/pending-4.14/333-arc-enable-unaligned-access-in-kernel-mode.patch b/target/linux/generic/pending-4.14/333-arc-enable-unaligned-access-in-kernel-mode.patch -new file mode 100644 -index 0000000000..4e0265aef5 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/333-arc-enable-unaligned-access-in-kernel-mode.patch -@@ -0,0 +1,24 @@ -+From: Alexey Brodkin -+Subject: arc: enable unaligned access in kernel mode -+ -+This enables misaligned access handling even in kernel mode. -+Some wireless drivers (ath9k-htc and mt7601u) use misaligned accesses -+here and there and to cope with that without fixing stuff in the drivers -+we're just gracefully handling it on ARC. -+ -+Signed-off-by: Alexey Brodkin -+--- -+ arch/arc/kernel/unaligned.c | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/arch/arc/kernel/unaligned.c -++++ b/arch/arc/kernel/unaligned.c -+@@ -206,7 +206,7 @@ int misaligned_fixup(unsigned long addre -+ char buf[TASK_COMM_LEN]; -+ -+ /* handle user mode only and only if enabled by sysadmin */ -+- if (!user_mode(regs) || !unaligned_enabled) -++ if (!unaligned_enabled) -+ return 1; -+ -+ if (no_unaligned_warning) { -diff --git a/target/linux/generic/pending-4.14/340-MIPS-mm-remove-mips_dma_mapping_error.patch b/target/linux/generic/pending-4.14/340-MIPS-mm-remove-mips_dma_mapping_error.patch -new file mode 100644 -index 0000000000..8d6cada842 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/340-MIPS-mm-remove-mips_dma_mapping_error.patch -@@ -0,0 +1,32 @@ -+From: Felix Fietkau -+Date: Tue, 5 Dec 2017 12:34:31 +0100 -+Subject: [PATCH] MIPS: mm: remove mips_dma_mapping_error -+ -+dma_mapping_error() already checks if ops->mapping_error is a null -+pointer -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/arch/mips/mm/dma-default.c -++++ b/arch/mips/mm/dma-default.c -+@@ -373,11 +373,6 @@ static void mips_dma_sync_sg_for_device( -+ } -+ } -+ -+-static int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) -+-{ -+- return 0; -+-} -+- -+ static int mips_dma_supported(struct device *dev, u64 mask) -+ { -+ return plat_dma_supported(dev, mask); -+@@ -406,7 +401,6 @@ static const struct dma_map_ops mips_def -+ .sync_single_for_device = mips_dma_sync_single_for_device, -+ .sync_sg_for_cpu = mips_dma_sync_sg_for_cpu, -+ .sync_sg_for_device = mips_dma_sync_sg_for_device, -+- .mapping_error = mips_dma_mapping_error, -+ .dma_supported = mips_dma_supported -+ }; -+ -diff --git a/target/linux/generic/pending-4.14/341-MIPS-mm-remove-no-op-dma_map_ops-where-possible.patch b/target/linux/generic/pending-4.14/341-MIPS-mm-remove-no-op-dma_map_ops-where-possible.patch -new file mode 100644 -index 0000000000..6f5f11350a ---- /dev/null -+++ b/target/linux/generic/pending-4.14/341-MIPS-mm-remove-no-op-dma_map_ops-where-possible.patch -@@ -0,0 +1,140 @@ -+From: Felix Fietkau -+Date: Tue, 5 Dec 2017 12:46:01 +0100 -+Subject: [PATCH] MIPS: mm: remove no-op dma_map_ops where possible -+ -+If no post-DMA flush is required, and the platform does not provide -+plat_unmap_dma_mem(), there is no need to include unmap or sync_for_cpu -+ops. -+ -+With this patch they are compiled out to improve icache footprint -+on devices that handle lots of DMA traffic (especially network routers). -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/arch/mips/Kconfig -++++ b/arch/mips/Kconfig -+@@ -221,6 +221,7 @@ config BMIPS_GENERIC -+ select BRCMSTB_L2_IRQ -+ select IRQ_MIPS_CPU -+ select DMA_NONCOHERENT -++ select DMA_UNMAP_POST_FLUSH -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ select SYS_SUPPORTS_BIG_ENDIAN -+@@ -346,6 +347,7 @@ config MACH_JAZZ -+ select CSRC_R4K -+ select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN -+ select GENERIC_ISA_DMA -++ select DMA_UNMAP_POST_FLUSH -+ select HAVE_PCSPKR_PLATFORM -+ select IRQ_MIPS_CPU -+ select I8253 -+@@ -1129,6 +1131,9 @@ config DMA_NONCOHERENT -+ bool -+ select NEED_DMA_MAP_STATE -+ -++config DMA_UNMAP_POST_FLUSH -++ bool -++ -+ config NEED_DMA_MAP_STATE -+ bool -+ -+@@ -1653,6 +1658,7 @@ config CPU_R10000 -+ select CPU_SUPPORTS_64BIT_KERNEL -+ select CPU_SUPPORTS_HIGHMEM -+ select CPU_SUPPORTS_HUGEPAGES -++ select DMA_UNMAP_POST_FLUSH -+ help -+ MIPS Technologies R10000-series processors. -+ -+@@ -1901,9 +1907,11 @@ config SYS_HAS_CPU_MIPS32_R3_5 -+ bool -+ -+ config SYS_HAS_CPU_MIPS32_R5 -++ select DMA_UNMAP_POST_FLUSH -+ bool -+ -+ config SYS_HAS_CPU_MIPS32_R6 -++ select DMA_UNMAP_POST_FLUSH -+ bool -+ -+ config SYS_HAS_CPU_MIPS64_R1 -+@@ -1913,6 +1921,7 @@ config SYS_HAS_CPU_MIPS64_R2 -+ bool -+ -+ config SYS_HAS_CPU_MIPS64_R6 -++ select DMA_UNMAP_POST_FLUSH -+ bool -+ -+ config SYS_HAS_CPU_R3000 -+--- a/arch/mips/mm/dma-default.c -++++ b/arch/mips/mm/dma-default.c -+@@ -267,8 +267,9 @@ static inline void __dma_sync(struct pag -+ } while (left); -+ } -+ -+-static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, -+- size_t size, enum dma_data_direction direction, unsigned long attrs) -++static void __maybe_unused -++mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, -++ enum dma_data_direction direction, unsigned long attrs) -+ { -+ if (cpu_needs_post_dma_flush(dev) && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) -+ __dma_sync(dma_addr_to_page(dev, dma_addr), -+@@ -308,9 +309,10 @@ static dma_addr_t mips_dma_map_page(stru -+ return plat_map_dma_mem_page(dev, page) + offset; -+ } -+ -+-static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, -+- int nhwentries, enum dma_data_direction direction, -+- unsigned long attrs) -++static void __maybe_unused -++mips_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, -++ int nhwentries, enum dma_data_direction direction, -++ unsigned long attrs) -+ { -+ int i; -+ struct scatterlist *sg; -+@@ -325,8 +327,9 @@ static void mips_dma_unmap_sg(struct dev -+ } -+ } -+ -+-static void mips_dma_sync_single_for_cpu(struct device *dev, -+- dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) -++static void __maybe_unused -++mips_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, -++ size_t size, enum dma_data_direction direction) -+ { -+ if (cpu_needs_post_dma_flush(dev)) -+ __dma_sync(dma_addr_to_page(dev, dma_handle), -+@@ -342,9 +345,9 @@ static void mips_dma_sync_single_for_dev -+ dma_handle & ~PAGE_MASK, size, direction); -+ } -+ -+-static void mips_dma_sync_sg_for_cpu(struct device *dev, -+- struct scatterlist *sglist, int nelems, -+- enum dma_data_direction direction) -++static void __maybe_unused -++mips_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist, -++ int nelems, enum dma_data_direction direction) -+ { -+ int i; -+ struct scatterlist *sg; -+@@ -394,12 +397,14 @@ static const struct dma_map_ops mips_def -+ .free = mips_dma_free_coherent, -+ .mmap = mips_dma_mmap, -+ .map_page = mips_dma_map_page, -+- .unmap_page = mips_dma_unmap_page, -+ .map_sg = mips_dma_map_sg, -++#ifdef CONFIG_DMA_UNMAP_POST_FLUSH -++ .unmap_page = mips_dma_unmap_page, -+ .unmap_sg = mips_dma_unmap_sg, -+ .sync_single_for_cpu = mips_dma_sync_single_for_cpu, -+- .sync_single_for_device = mips_dma_sync_single_for_device, -+ .sync_sg_for_cpu = mips_dma_sync_sg_for_cpu, -++#endif -++ .sync_single_for_device = mips_dma_sync_single_for_device, -+ .sync_sg_for_device = mips_dma_sync_sg_for_device, -+ .dma_supported = mips_dma_supported -+ }; -diff --git a/target/linux/generic/pending-4.14/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch b/target/linux/generic/pending-4.14/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch -new file mode 100644 -index 0000000000..e3ae02a067 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch -@@ -0,0 +1,24 @@ -+From 8cabf9d8bd67d3f8603a4c1ceedaa629a7212be8 Mon Sep 17 00:00:00 2001 -+From: Pawel Dembicki -+Date: Fri, 24 May 2019 17:56:19 +0200 -+Subject: [PATCH] powerpc: Enable kernel XZ compression option on PPC_85xx -+ -+Enable kernel XZ compression option on PPC_85xx. Tested with -+simpleImage on TP-Link TL-WDR4900 (Freescale P1014 processor). -+ -+Suggested-by: Christian Lamparter -+Signed-off-by: Pawel Dembicki -+--- -+ arch/powerpc/Kconfig | 1 + -+ 1 file changed, 1 insertion(+) -+ -+--- a/arch/powerpc/Kconfig -++++ b/arch/powerpc/Kconfig -+@@ -199,6 +199,7 @@ config PPC -+ select HAVE_IOREMAP_PROT -+ select HAVE_IRQ_EXIT_ON_IRQ_STACK -+ select HAVE_KERNEL_GZIP -++ select HAVE_KERNEL_XZ if PPC_85xx -+ select HAVE_KPROBES -+ select HAVE_KPROBES_ON_FTRACE -+ select HAVE_KRETPROBES -diff --git a/target/linux/generic/pending-4.14/400-mtd-add-rootfs-split-support.patch b/target/linux/generic/pending-4.14/400-mtd-add-rootfs-split-support.patch -new file mode 100644 -index 0000000000..10ad99585d ---- /dev/null -+++ b/target/linux/generic/pending-4.14/400-mtd-add-rootfs-split-support.patch -@@ -0,0 +1,108 @@ -+From: Felix Fietkau -+Subject: make rootfs split/detection more generic - patch can be moved to generic-2.6 after testing on other platforms -+ -+lede-commit: 328e660b31f0937d52c5ae3d6e7029409918a9df -+Signed-off-by: Felix Fietkau -+--- -+ drivers/mtd/Kconfig | 17 +++++++++++++++++ -+ drivers/mtd/mtdpart.c | 35 +++++++++++++++++++++++++++++++++++ -+ include/linux/mtd/partitions.h | 2 ++ -+ 3 files changed, 54 insertions(+) -+ -+--- a/drivers/mtd/Kconfig -++++ b/drivers/mtd/Kconfig -+@@ -12,6 +12,23 @@ menuconfig MTD -+ -+ if MTD -+ -++menu "OpenWrt specific MTD options" -++ -++config MTD_ROOTFS_ROOT_DEV -++ bool "Automatically set 'rootfs' partition to be root filesystem" -++ default y -++ -++config MTD_SPLIT_FIRMWARE -++ bool "Automatically split firmware partition for kernel+rootfs" -++ default y -++ -++config MTD_SPLIT_FIRMWARE_NAME -++ string "Firmware partition name" -++ depends on MTD_SPLIT_FIRMWARE -++ default "firmware" -++ -++endmenu -++ -+ config MTD_TESTS -+ tristate "MTD tests support (DANGEROUS)" -+ depends on m -+--- a/drivers/mtd/mtdpart.c -++++ b/drivers/mtd/mtdpart.c -+@@ -29,11 +29,13 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ #include -+ -+ #include "mtdcore.h" -++#include "mtdsplit/mtdsplit.h" -+ -+ /* Our partition linked list */ -+ static LIST_HEAD(mtd_partitions); -+@@ -53,6 +55,8 @@ struct mtd_part { -+ struct list_head list; -+ }; -+ -++static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part); -++ -+ /* -+ * Given a pointer to the MTD object in the mtd_part structure, we can retrieve -+ * the pointer to that structure. -+@@ -671,6 +675,7 @@ int mtd_add_partition(struct mtd_info *p -+ if (ret) -+ goto err_remove_part; -+ -++ mtd_partition_split(parent, new); -+ mtd_add_partition_attrs(new); -+ -+ return 0; -+@@ -757,6 +762,29 @@ int mtd_del_partition(struct mtd_info *m -+ } -+ EXPORT_SYMBOL_GPL(mtd_del_partition); -+ -++#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME -++#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME -++#else -++#define SPLIT_FIRMWARE_NAME "unused" -++#endif -++ -++static void split_firmware(struct mtd_info *master, struct mtd_part *part) -++{ -++} -++ -++static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part) -++{ -++ static int rootfs_found = 0; -++ -++ if (rootfs_found) -++ return; -++ -++ if (IS_ENABLED(CONFIG_MTD_SPLIT_FIRMWARE) && -++ !strcmp(part->mtd.name, SPLIT_FIRMWARE_NAME) && -++ !of_find_property(mtd_get_of_node(&part->mtd), "compatible", NULL)) -++ split_firmware(master, part); -++} -++ -+ /* -+ * This function, given a master MTD object and a partition table, creates -+ * and registers slave MTD objects which are bound to the master according to -+@@ -797,6 +825,7 @@ int add_mtd_partitions(struct mtd_info * -+ goto err_del_partitions; -+ } -+ -++ mtd_partition_split(master, slave); -+ mtd_add_partition_attrs(slave); -+ /* Look for subpartitions */ -+ parse_mtd_partitions(&slave->mtd, parts[i].types, NULL); -diff --git a/target/linux/generic/pending-4.14/401-mtd-add-support-for-different-partition-parser-types.patch b/target/linux/generic/pending-4.14/401-mtd-add-support-for-different-partition-parser-types.patch -new file mode 100644 -index 0000000000..057d473684 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/401-mtd-add-support-for-different-partition-parser-types.patch -@@ -0,0 +1,142 @@ -+From: Gabor Juhos -+Subject: mtd: add support for different partition parser types -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/mtd/mtdpart.c | 56 ++++++++++++++++++++++++++++++++++++++++ -+ include/linux/mtd/partitions.h | 11 ++++++++ -+ 2 files changed, 67 insertions(+) -+ -+--- a/drivers/mtd/mtdpart.c -++++ b/drivers/mtd/mtdpart.c -+@@ -56,6 +56,10 @@ struct mtd_part { -+ }; -+ -+ static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part); -++static int parse_mtd_partitions_by_type(struct mtd_info *master, -++ enum mtd_parser_type type, -++ const struct mtd_partition **pparts, -++ struct mtd_part_parser_data *data); -+ -+ /* -+ * Given a pointer to the MTD object in the mtd_part structure, we can retrieve -+@@ -762,6 +766,36 @@ int mtd_del_partition(struct mtd_info *m -+ } -+ EXPORT_SYMBOL_GPL(mtd_del_partition); -+ -++static int -++run_parsers_by_type(struct mtd_part *slave, enum mtd_parser_type type) -++{ -++ struct mtd_partition *parts; -++ int nr_parts; -++ int i; -++ -++ nr_parts = parse_mtd_partitions_by_type(&slave->mtd, type, (const struct mtd_partition **)&parts, -++ NULL); -++ if (nr_parts <= 0) -++ return nr_parts; -++ -++ if (WARN_ON(!parts)) -++ return 0; -++ -++ for (i = 0; i < nr_parts; i++) { -++ /* adjust partition offsets */ -++ parts[i].offset += slave->offset; -++ -++ mtd_add_partition(slave->parent, -++ parts[i].name, -++ parts[i].offset, -++ parts[i].size); -++ } -++ -++ kfree(parts); -++ -++ return nr_parts; -++} -++ -+ #ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME -+ #define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME -+ #else -+@@ -1147,6 +1181,61 @@ void mtd_part_parser_cleanup(struct mtd_ -+ } -+ } -+ -++static struct mtd_part_parser * -++get_partition_parser_by_type(enum mtd_parser_type type, -++ struct mtd_part_parser *start) -++{ -++ struct mtd_part_parser *p, *ret = NULL; -++ -++ spin_lock(&part_parser_lock); -++ -++ p = list_prepare_entry(start, &part_parsers, list); -++ if (start) -++ mtd_part_parser_put(start); -++ -++ list_for_each_entry_continue(p, &part_parsers, list) { -++ if (p->type == type && try_module_get(p->owner)) { -++ ret = p; -++ break; -++ } -++ } -++ -++ spin_unlock(&part_parser_lock); -++ -++ return ret; -++} -++ -++static int parse_mtd_partitions_by_type(struct mtd_info *master, -++ enum mtd_parser_type type, -++ const struct mtd_partition **pparts, -++ struct mtd_part_parser_data *data) -++{ -++ struct mtd_part_parser *prev = NULL; -++ int ret = 0; -++ -++ while (1) { -++ struct mtd_part_parser *parser; -++ -++ parser = get_partition_parser_by_type(type, prev); -++ if (!parser) -++ break; -++ -++ ret = (*parser->parse_fn)(master, pparts, data); -++ -++ if (ret > 0) { -++ mtd_part_parser_put(parser); -++ printk(KERN_NOTICE -++ "%d %s partitions found on MTD device %s\n", -++ ret, parser->name, master->name); -++ break; -++ } -++ -++ prev = parser; -++ } -++ -++ return ret; -++} -++ -+ int mtd_is_partition(const struct mtd_info *mtd) -+ { -+ struct mtd_part *part; -+--- a/include/linux/mtd/partitions.h -++++ b/include/linux/mtd/partitions.h -+@@ -73,6 +73,10 @@ struct mtd_part_parser_data { -+ * Functions dealing with the various ways of partitioning the space -+ */ -+ -++enum mtd_parser_type { -++ MTD_PARSER_TYPE_DEVICE = 0, -++}; -++ -+ struct mtd_part_parser { -+ struct list_head list; -+ struct module *owner; -+@@ -81,6 +85,7 @@ struct mtd_part_parser { -+ int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, -+ struct mtd_part_parser_data *); -+ void (*cleanup)(const struct mtd_partition *pparts, int nr_parts); -++ enum mtd_parser_type type; -+ }; -+ -+ /* Container for passing around a set of parsed partitions */ -diff --git a/target/linux/generic/pending-4.14/402-mtd-use-typed-mtd-parsers-for-rootfs-and-firmware-split.patch b/target/linux/generic/pending-4.14/402-mtd-use-typed-mtd-parsers-for-rootfs-and-firmware-split.patch -new file mode 100644 -index 0000000000..2cc06dd463 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/402-mtd-use-typed-mtd-parsers-for-rootfs-and-firmware-split.patch -@@ -0,0 +1,44 @@ -+From: Gabor Juhos -+Subject: kernel/3.10: allow to use partition parsers for rootfs and firmware split -+ -+lede-commit: 3b71cd94bc9517bc25267dccb393b07d4b54564e -+Signed-off-by: Gabor Juhos -+--- -+ drivers/mtd/mtdpart.c | 37 +++++++++++++++++++++++++++++++++++++ -+ include/linux/mtd/partitions.h | 2 ++ -+ 2 files changed, 39 insertions(+) -+ -+--- a/drivers/mtd/mtdpart.c -++++ b/drivers/mtd/mtdpart.c -+@@ -804,6 +804,7 @@ run_parsers_by_type(struct mtd_part *sla -+ -+ static void split_firmware(struct mtd_info *master, struct mtd_part *part) -+ { -++ run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE); -+ } -+ -+ static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part) -+@@ -813,6 +814,12 @@ static void mtd_partition_split(struct m -+ if (rootfs_found) -+ return; -+ -++ if (!strcmp(part->mtd.name, "rootfs")) { -++ run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS); -++ -++ rootfs_found = 1; -++ } -++ -+ if (IS_ENABLED(CONFIG_MTD_SPLIT_FIRMWARE) && -+ !strcmp(part->mtd.name, SPLIT_FIRMWARE_NAME) && -+ !of_find_property(mtd_get_of_node(&part->mtd), "compatible", NULL)) -+--- a/include/linux/mtd/partitions.h -++++ b/include/linux/mtd/partitions.h -+@@ -75,6 +75,8 @@ struct mtd_part_parser_data { -+ -+ enum mtd_parser_type { -+ MTD_PARSER_TYPE_DEVICE = 0, -++ MTD_PARSER_TYPE_ROOTFS, -++ MTD_PARSER_TYPE_FIRMWARE, -+ }; -+ -+ struct mtd_part_parser { -diff --git a/target/linux/generic/pending-4.14/403-mtd-hook-mtdsplit-to-Kbuild.patch b/target/linux/generic/pending-4.14/403-mtd-hook-mtdsplit-to-Kbuild.patch -new file mode 100644 -index 0000000000..89c202bc0d ---- /dev/null -+++ b/target/linux/generic/pending-4.14/403-mtd-hook-mtdsplit-to-Kbuild.patch -@@ -0,0 +1,32 @@ -+From: Gabor Juhos -+Subject: [PATCH] kernel/3.10: move squashfs check from rootfs split code into a separate file -+ -+lede-commit: d89bea92b31b4e157a0fa438e75370f089f73427 -+Signed-off-by: Gabor Juhos -+--- -+ drivers/mtd/Kconfig | 2 ++ -+ drivers/mtd/Makefile | 2 ++ -+ 2 files changed, 4 insertions(+) -+ -+--- a/drivers/mtd/Kconfig -++++ b/drivers/mtd/Kconfig -+@@ -27,6 +27,8 @@ config MTD_SPLIT_FIRMWARE_NAME -+ depends on MTD_SPLIT_FIRMWARE -+ default "firmware" -+ -++source "drivers/mtd/mtdsplit/Kconfig" -++ -+ endmenu -+ -+ config MTD_TESTS -+--- a/drivers/mtd/Makefile -++++ b/drivers/mtd/Makefile -+@@ -7,6 +7,8 @@ -+ obj-$(CONFIG_MTD) += mtd.o -+ mtd-y := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o mtdchar.o -+ -++obj-$(CONFIG_MTD_SPLIT) += mtdsplit/ -++ -+ obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o -+ obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o -+ obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o -diff --git a/target/linux/generic/pending-4.14/404-mtd-add-more-helper-functions.patch b/target/linux/generic/pending-4.14/404-mtd-add-more-helper-functions.patch -new file mode 100644 -index 0000000000..7b481ffb47 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/404-mtd-add-more-helper-functions.patch -@@ -0,0 +1,76 @@ -+From: Gabor Juhos -+Subject: kernel/3.10: add separate rootfs partition parser -+ -+lede-commit: daec7ad7688415156e2730e401503d09bd3acf91 -+Signed-off-by: Gabor Juhos -+--- -+ drivers/mtd/mtdpart.c | 29 +++++++++++++++++++++++++++++ -+ include/linux/mtd/mtd.h | 18 ++++++++++++++++++ -+ include/linux/mtd/partitions.h | 2 ++ -+ 3 files changed, 49 insertions(+) -+ -+--- a/drivers/mtd/mtdpart.c -++++ b/drivers/mtd/mtdpart.c -+@@ -1260,6 +1260,24 @@ int mtd_is_partition(const struct mtd_in -+ } -+ EXPORT_SYMBOL_GPL(mtd_is_partition); -+ -++struct mtd_info *mtdpart_get_master(const struct mtd_info *mtd) -++{ -++ if (!mtd_is_partition(mtd)) -++ return (struct mtd_info *)mtd; -++ -++ return mtd_to_part(mtd)->parent; -++} -++EXPORT_SYMBOL_GPL(mtdpart_get_master); -++ -++uint64_t mtdpart_get_offset(const struct mtd_info *mtd) -++{ -++ if (!mtd_is_partition(mtd)) -++ return 0; -++ -++ return mtd_to_part(mtd)->offset; -++} -++EXPORT_SYMBOL_GPL(mtdpart_get_offset); -++ -+ /* Returns the size of the entire flash chip */ -+ uint64_t mtd_get_device_size(const struct mtd_info *mtd) -+ { -+--- a/include/linux/mtd/mtd.h -++++ b/include/linux/mtd/mtd.h -+@@ -494,6 +494,24 @@ static inline uint32_t mtd_mod_by_eb(uin -+ return do_div(sz, mtd->erasesize); -+ } -+ -++static inline uint64_t mtd_roundup_to_eb(uint64_t sz, struct mtd_info *mtd) -++{ -++ if (mtd_mod_by_eb(sz, mtd) == 0) -++ return sz; -++ -++ /* Round up to next erase block */ -++ return (mtd_div_by_eb(sz, mtd) + 1) * mtd->erasesize; -++} -++ -++static inline uint64_t mtd_rounddown_to_eb(uint64_t sz, struct mtd_info *mtd) -++{ -++ if (mtd_mod_by_eb(sz, mtd) == 0) -++ return sz; -++ -++ /* Round down to the start of the current erase block */ -++ return (mtd_div_by_eb(sz, mtd)) * mtd->erasesize; -++} -++ -+ static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd) -+ { -+ if (mtd->writesize_shift) -+--- a/include/linux/mtd/partitions.h -++++ b/include/linux/mtd/partitions.h -+@@ -116,6 +116,8 @@ int mtd_is_partition(const struct mtd_in -+ int mtd_add_partition(struct mtd_info *master, const char *name, -+ long long offset, long long length); -+ int mtd_del_partition(struct mtd_info *master, int partno); -++struct mtd_info *mtdpart_get_master(const struct mtd_info *mtd); -++uint64_t mtdpart_get_offset(const struct mtd_info *mtd); -+ uint64_t mtd_get_device_size(const struct mtd_info *mtd); -+ -+ #endif -diff --git a/target/linux/generic/pending-4.14/411-mtd-partial_eraseblock_write.patch b/target/linux/generic/pending-4.14/411-mtd-partial_eraseblock_write.patch -new file mode 100644 -index 0000000000..52f1cb5abf ---- /dev/null -+++ b/target/linux/generic/pending-4.14/411-mtd-partial_eraseblock_write.patch -@@ -0,0 +1,153 @@ -+From: Felix Fietkau -+Subject: mtd: implement write support for partitions covering only a part of an eraseblock (buffer data that would otherwise be erased) -+ -+lede-commit: 87a8e8ac1067f58ba831c4aae443f3655c31cd80 -+Signed-off-by: Felix Fietkau -+--- -+ drivers/mtd/mtdpart.c | 90 ++++++++++++++++++++++++++++++++++++++++++++----- -+ include/linux/mtd/mtd.h | 4 +++ -+ 2 files changed, 85 insertions(+), 9 deletions(-) -+ -+--- a/drivers/mtd/mtdpart.c -++++ b/drivers/mtd/mtdpart.c -+@@ -37,6 +37,8 @@ -+ #include "mtdcore.h" -+ #include "mtdsplit/mtdsplit.h" -+ -++#define MTD_ERASE_PARTIAL 0x8000 /* partition only covers parts of an erase block */ -++ -+ /* Our partition linked list */ -+ static LIST_HEAD(mtd_partitions); -+ static DEFINE_MUTEX(mtd_partitions_mutex); -+@@ -255,13 +257,61 @@ static int part_erase(struct mtd_info *m -+ struct mtd_part *part = mtd_to_part(mtd); -+ int ret; -+ -++ -++ instr->partial_start = false; -++ if (mtd->flags & MTD_ERASE_PARTIAL) { -++ size_t readlen = 0; -++ u64 mtd_ofs; -++ -++ instr->erase_buf = kmalloc(part->parent->erasesize, GFP_ATOMIC); -++ if (!instr->erase_buf) -++ return -ENOMEM; -++ -++ mtd_ofs = part->offset + instr->addr; -++ instr->erase_buf_ofs = do_div(mtd_ofs, part->parent->erasesize); -++ -++ if (instr->erase_buf_ofs > 0) { -++ instr->addr -= instr->erase_buf_ofs; -++ ret = mtd_read(part->parent, -++ instr->addr + part->offset, -++ part->parent->erasesize, -++ &readlen, instr->erase_buf); -++ -++ instr->len += instr->erase_buf_ofs; -++ instr->partial_start = true; -++ } else { -++ mtd_ofs = part->offset + part->mtd.size; -++ instr->erase_buf_ofs = part->parent->erasesize - -++ do_div(mtd_ofs, part->parent->erasesize); -++ -++ if (instr->erase_buf_ofs > 0) { -++ instr->len += instr->erase_buf_ofs; -++ ret = mtd_read(part->parent, -++ part->offset + instr->addr + -++ instr->len - part->parent->erasesize, -++ part->parent->erasesize, &readlen, -++ instr->erase_buf); -++ } else { -++ ret = 0; -++ } -++ } -++ if (ret < 0) { -++ kfree(instr->erase_buf); -++ return ret; -++ } -++ -++ } -++ -+ instr->addr += part->offset; -+ ret = part->parent->_erase(part->parent, instr); -+ if (ret) { -+ if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) -+ instr->fail_addr -= part->offset; -+ instr->addr -= part->offset; -++ if (mtd->flags & MTD_ERASE_PARTIAL) -++ kfree(instr->erase_buf); -+ } -++ -+ return ret; -+ } -+ -+@@ -269,6 +319,25 @@ void mtd_erase_callback(struct erase_inf -+ { -+ if (instr->mtd->_erase == part_erase) { -+ struct mtd_part *part = mtd_to_part(instr->mtd); -++ size_t wrlen = 0; -++ -++ if (instr->mtd->flags & MTD_ERASE_PARTIAL) { -++ if (instr->partial_start) { -++ part->parent->_write(part->parent, -++ instr->addr, instr->erase_buf_ofs, -++ &wrlen, instr->erase_buf); -++ instr->addr += instr->erase_buf_ofs; -++ } else { -++ instr->len -= instr->erase_buf_ofs; -++ part->parent->_write(part->parent, -++ instr->addr + instr->len, -++ instr->erase_buf_ofs, &wrlen, -++ instr->erase_buf + -++ part->parent->erasesize - -++ instr->erase_buf_ofs); -++ } -++ kfree(instr->erase_buf); -++ } -+ -+ if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) -+ instr->fail_addr -= part->offset; -+@@ -584,19 +653,22 @@ static struct mtd_part *allocate_partiti -+ remainder = do_div(tmp, wr_alignment); -+ if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) { -+ /* Doesn't start on a boundary of major erase size */ -+- /* FIXME: Let it be writable if it is on a boundary of -+- * _minor_ erase size though */ -+- slave->mtd.flags &= ~MTD_WRITEABLE; -+- printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n", -+- part->name); -++ slave->mtd.flags |= MTD_ERASE_PARTIAL; -++ if (((u32)slave->mtd.size) > parent->erasesize) -++ slave->mtd.flags &= ~MTD_WRITEABLE; -++ else -++ slave->mtd.erasesize = slave->mtd.size; -+ } -+ -+ tmp = part_absolute_offset(parent) + slave->offset + slave->mtd.size; -+ remainder = do_div(tmp, wr_alignment); -+ if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) { -+- slave->mtd.flags &= ~MTD_WRITEABLE; -+- printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n", -+- part->name); -++ slave->mtd.flags |= MTD_ERASE_PARTIAL; -++ -++ if ((u32)slave->mtd.size > parent->erasesize) -++ slave->mtd.flags &= ~MTD_WRITEABLE; -++ else -++ slave->mtd.erasesize = slave->mtd.size; -+ } -+ -+ mtd_set_ooblayout(&slave->mtd, &part_ooblayout_ops); -+--- a/include/linux/mtd/mtd.h -++++ b/include/linux/mtd/mtd.h -+@@ -56,6 +56,10 @@ struct erase_info { -+ u_long priv; -+ u_char state; -+ struct erase_info *next; -++ -++ u8 *erase_buf; -++ u32 erase_buf_ofs; -++ bool partial_start; -+ }; -+ -+ struct mtd_erase_region_info { -diff --git a/target/linux/generic/pending-4.14/412-mtd-partial_eraseblock_unlock.patch b/target/linux/generic/pending-4.14/412-mtd-partial_eraseblock_unlock.patch -new file mode 100644 -index 0000000000..3ac3496c69 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/412-mtd-partial_eraseblock_unlock.patch -@@ -0,0 +1,40 @@ -+From: Tim Harvey -+Subject: mtd: allow partial block unlock -+ -+This allows sysupgrade for devices such as the Gateworks Avila/Cambria -+product families based on the ixp4xx using the redboot bootloader with -+combined FIS directory and RedBoot config partitions on larger FLASH -+devices with larger eraseblocks. -+ -+This second iteration of this patch addresses previous issues: -+- whitespace breakage fixed -+- unlock in all scenarios -+- simplification and fix logic bug -+ -+[john@phrozen.org: this should be moved to the ixp4xx folder] -+ -+Signed-off-by: Tim Harvey -+--- -+ drivers/mtd/mtdpart.c | 11 ++++++++++- -+ 1 file changed, 10 insertions(+), 1 deletion(-) -+ -+--- a/drivers/mtd/mtdpart.c -++++ b/drivers/mtd/mtdpart.c -+@@ -357,7 +357,16 @@ static int part_lock(struct mtd_info *mt -+ static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) -+ { -+ struct mtd_part *part = mtd_to_part(mtd); -+- return part->parent->_unlock(part->parent, ofs + part->offset, len); -++ -++ ofs += part->offset; -++ -++ if (mtd->flags & MTD_ERASE_PARTIAL) { -++ /* round up len to next erasesize and round down offset to prev block */ -++ len = (mtd_div_by_eb(len, part->parent) + 1) * part->parent->erasesize; -++ ofs &= ~(part->parent->erasesize - 1); -++ } -++ -++ return part->parent->_unlock(part->parent, ofs, len); -+ } -+ -+ static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) -diff --git a/target/linux/generic/pending-4.14/419-mtd-redboot-add-of_match_table-with-DT-binding.patch b/target/linux/generic/pending-4.14/419-mtd-redboot-add-of_match_table-with-DT-binding.patch -new file mode 100644 -index 0000000000..fbf9a0553c ---- /dev/null -+++ b/target/linux/generic/pending-4.14/419-mtd-redboot-add-of_match_table-with-DT-binding.patch -@@ -0,0 +1,31 @@ -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Subject: [PATCH] mtd: redboot: add of_match_table with DT binding -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This allows parsing RedBoot compatible partitions for properly described -+flash device in DT. -+ -+Signed-off-by: Rafał Miłecki -+--- -+ -+--- a/drivers/mtd/redboot.c -++++ b/drivers/mtd/redboot.c -+@@ -289,9 +289,16 @@ static int parse_redboot_partitions(stru -+ return ret; -+ } -+ -++static const struct of_device_id redboot_parser_of_match_table[] = { -++ { .compatible = "ecoscentric,redboot-fis-partitions" }, -++ {}, -++}; -++MODULE_DEVICE_TABLE(of, redboot_parser_of_match_table); -++ -+ static struct mtd_part_parser redboot_parser = { -+ .parse_fn = parse_redboot_partitions, -+ .name = "RedBoot", -++ .of_match_table = redboot_parser_of_match_table, -+ }; -+ module_mtd_part_parser(redboot_parser); -+ -diff --git a/target/linux/generic/pending-4.14/420-mtd-redboot_space.patch b/target/linux/generic/pending-4.14/420-mtd-redboot_space.patch -new file mode 100644 -index 0000000000..85fbe0512d ---- /dev/null -+++ b/target/linux/generic/pending-4.14/420-mtd-redboot_space.patch -@@ -0,0 +1,41 @@ -+From: Felix Fietkau -+Subject: add patch for including unpartitioned space in the rootfs partition for redboot devices (if applicable) -+ -+[john@phrozen.org: used by ixp and others] -+ -+lede-commit: 394918851f84e4d00fa16eb900e7700e95091f00 -+Signed-off-by: Felix Fietkau -+--- -+ drivers/mtd/redboot.c | 19 +++++++++++++------ -+ 1 file changed, 13 insertions(+), 6 deletions(-) -+ -+--- a/drivers/mtd/redboot.c -++++ b/drivers/mtd/redboot.c -+@@ -265,14 +265,21 @@ static int parse_redboot_partitions(stru -+ #endif -+ names += strlen(names)+1; -+ -+-#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED -+ if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) { -+- i++; -+- parts[i].offset = parts[i-1].size + parts[i-1].offset; -+- parts[i].size = fl->next->img->flash_base - parts[i].offset; -+- parts[i].name = nullname; -+- } -++ if (!strcmp(parts[i].name, "rootfs")) { -++ parts[i].size = fl->next->img->flash_base; -++ parts[i].size &= ~(master->erasesize - 1); -++ parts[i].size -= parts[i].offset; -++#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED -++ nrparts--; -++ } else { -++ i++; -++ parts[i].offset = parts[i-1].size + parts[i-1].offset; -++ parts[i].size = fl->next->img->flash_base - parts[i].offset; -++ parts[i].name = nullname; -+ #endif -++ } -++ } -+ tmp_fl = fl; -+ fl = fl->next; -+ kfree(tmp_fl); -diff --git a/target/linux/generic/pending-4.14/430-mtd-add-myloader-partition-parser.patch b/target/linux/generic/pending-4.14/430-mtd-add-myloader-partition-parser.patch -new file mode 100644 -index 0000000000..bf6670a91e ---- /dev/null -+++ b/target/linux/generic/pending-4.14/430-mtd-add-myloader-partition-parser.patch -@@ -0,0 +1,229 @@ -+From: Florian Fainelli -+Subject: Add myloader partition table parser -+ -+[john@phozen.org: shoud be upstreamable] -+ -+lede-commit: d8bf22859b51faa09d22c056fe221a45d2f7a3b8 -+Signed-off-by: Florian Fainelli -+[add myloader.c to patch] -+Signed-off-by: Adrian Schmutzler -+ -+--- a/drivers/mtd/Kconfig -++++ b/drivers/mtd/Kconfig -+@@ -178,6 +178,22 @@ menu "Partition parsers" -+ source "drivers/mtd/parsers/Kconfig" -+ endmenu -+ -++config MTD_MYLOADER_PARTS -++ tristate "MyLoader partition parsing" -++ depends on ADM5120 || ATH25 || ATH79 -++ ---help--- -++ MyLoader is a bootloader which allows the user to define partitions -++ in flash devices, by putting a table in the second erase block -++ on the device, similar to a partition table. This table gives the -++ offsets and lengths of the user defined partitions. -++ -++ If you need code which can detect and parse these tables, and -++ register MTD 'partitions' corresponding to each image detected, -++ enable this option. -++ -++ You will still need the parsing functions to be called by the driver -++ for your particular device. It won't happen automatically. -++ -+ comment "User Modules And Translation Layers" -+ -+ # -+--- a/drivers/mtd/Makefile -++++ b/drivers/mtd/Makefile -+@@ -16,6 +16,7 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o -+ obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o -+ obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o -+ obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o -++obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o -+ obj-y += parsers/ -+ -+ # 'Users' - code which presents functionality to userspace. -+--- /dev/null -++++ b/drivers/mtd/myloader.c -+@@ -0,0 +1,181 @@ -++/* -++ * Parse MyLoader-style flash partition tables and produce a Linux partition -++ * array to match. -++ * -++ * Copyright (C) 2007-2009 Gabor Juhos -++ * -++ * This file was based on drivers/mtd/redboot.c -++ * Author: Red Hat, Inc. - David Woodhouse -++ * -++ * This program is free software; you can redistribute it and/or modify it -++ * under the terms of the GNU General Public License version 2 as published -++ * by the Free Software Foundation. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#define BLOCK_LEN_MIN 0x10000 -++#define PART_NAME_LEN 32 -++ -++struct part_data { -++ struct mylo_partition_table tab; -++ char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN]; -++}; -++ -++static int myloader_parse_partitions(struct mtd_info *master, -++ const struct mtd_partition **pparts, -++ struct mtd_part_parser_data *data) -++{ -++ struct part_data *buf; -++ struct mylo_partition_table *tab; -++ struct mylo_partition *part; -++ struct mtd_partition *mtd_parts; -++ struct mtd_partition *mtd_part; -++ int num_parts; -++ int ret, i; -++ size_t retlen; -++ char *names; -++ unsigned long offset; -++ unsigned long blocklen; -++ -++ buf = vmalloc(sizeof(*buf)); -++ if (!buf) { -++ return -ENOMEM; -++ goto out; -++ } -++ tab = &buf->tab; -++ -++ blocklen = master->erasesize; -++ if (blocklen < BLOCK_LEN_MIN) -++ blocklen = BLOCK_LEN_MIN; -++ -++ offset = blocklen; -++ -++ /* Find the partition table */ -++ for (i = 0; i < 4; i++, offset += blocklen) { -++ printk(KERN_DEBUG "%s: searching for MyLoader partition table" -++ " at offset 0x%lx\n", master->name, offset); -++ -++ ret = mtd_read(master, offset, sizeof(*buf), &retlen, -++ (void *)buf); -++ if (ret) -++ goto out_free_buf; -++ -++ if (retlen != sizeof(*buf)) { -++ ret = -EIO; -++ goto out_free_buf; -++ } -++ -++ /* Check for Partition Table magic number */ -++ if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS)) -++ break; -++ -++ } -++ -++ if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) { -++ printk(KERN_DEBUG "%s: no MyLoader partition table found\n", -++ master->name); -++ ret = 0; -++ goto out_free_buf; -++ } -++ -++ /* The MyLoader and the Partition Table is always present */ -++ num_parts = 2; -++ -++ /* Detect number of used partitions */ -++ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) { -++ part = &tab->partitions[i]; -++ -++ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE) -++ continue; -++ -++ num_parts++; -++ } -++ -++ mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) + -++ num_parts * PART_NAME_LEN), GFP_KERNEL); -++ -++ if (!mtd_parts) { -++ ret = -ENOMEM; -++ goto out_free_buf; -++ } -++ -++ mtd_part = mtd_parts; -++ names = (char *)&mtd_parts[num_parts]; -++ -++ strncpy(names, "myloader", PART_NAME_LEN); -++ mtd_part->name = names; -++ mtd_part->offset = 0; -++ mtd_part->size = offset; -++ mtd_part->mask_flags = MTD_WRITEABLE; -++ mtd_part++; -++ names += PART_NAME_LEN; -++ -++ strncpy(names, "partition_table", PART_NAME_LEN); -++ mtd_part->name = names; -++ mtd_part->offset = offset; -++ mtd_part->size = blocklen; -++ mtd_part->mask_flags = MTD_WRITEABLE; -++ mtd_part++; -++ names += PART_NAME_LEN; -++ -++ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) { -++ part = &tab->partitions[i]; -++ -++ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE) -++ continue; -++ -++ if ((buf->names[i][0]) && (buf->names[i][0] != '\xff')) -++ strncpy(names, buf->names[i], PART_NAME_LEN); -++ else -++ snprintf(names, PART_NAME_LEN, "partition%d", i); -++ -++ mtd_part->offset = le32_to_cpu(part->addr); -++ mtd_part->size = le32_to_cpu(part->size); -++ mtd_part->name = names; -++ mtd_part++; -++ names += PART_NAME_LEN; -++ } -++ -++ *pparts = mtd_parts; -++ ret = num_parts; -++ -++ out_free_buf: -++ vfree(buf); -++ out: -++ return ret; -++} -++ -++static struct mtd_part_parser myloader_mtd_parser = { -++ .owner = THIS_MODULE, -++ .parse_fn = myloader_parse_partitions, -++ .name = "MyLoader", -++}; -++ -++static int __init myloader_mtd_parser_init(void) -++{ -++ register_mtd_parser(&myloader_mtd_parser); -++ -++ return 0; -++} -++ -++static void __exit myloader_mtd_parser_exit(void) -++{ -++ deregister_mtd_parser(&myloader_mtd_parser); -++} -++ -++module_init(myloader_mtd_parser_init); -++module_exit(myloader_mtd_parser_exit); -++ -++MODULE_AUTHOR("Gabor Juhos "); -++MODULE_DESCRIPTION("Parsing code for MyLoader partition tables"); -++MODULE_LICENSE("GPL v2"); -diff --git a/target/linux/generic/pending-4.14/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch b/target/linux/generic/pending-4.14/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch -new file mode 100644 -index 0000000000..d54c284c34 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch -@@ -0,0 +1,68 @@ -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Subject: [PATCH] mtd: bcm47xxpart: check for bad blocks when calculating offsets -+ -+Signed-off-by: Rafał Miłecki -+--- -+ -+--- a/drivers/mtd/parsers/parser_trx.c -++++ b/drivers/mtd/parsers/parser_trx.c -+@@ -29,6 +29,33 @@ struct trx_header { -+ uint32_t offset[3]; -+ } __packed; -+ -++/* -++ * Calculate real end offset (address) for a given amount of data. It checks -++ * all blocks skipping bad ones. -++ */ -++static size_t parser_trx_real_offset(struct mtd_info *mtd, size_t bytes) -++{ -++ size_t real_offset = 0; -++ -++ if (mtd_block_isbad(mtd, real_offset)) -++ pr_warn("Base offset shouldn't be at bad block"); -++ -++ while (bytes >= mtd->erasesize) { -++ bytes -= mtd->erasesize; -++ real_offset += mtd->erasesize; -++ while (mtd_block_isbad(mtd, real_offset)) { -++ real_offset += mtd->erasesize; -++ -++ if (real_offset >= mtd->size) -++ return real_offset - mtd->erasesize; -++ } -++ } -++ -++ real_offset += bytes; -++ -++ return real_offset; -++} -++ -+ static const char *parser_trx_data_part_name(struct mtd_info *master, -+ size_t offset) -+ { -+@@ -83,21 +110,21 @@ static int parser_trx_parse(struct mtd_i -+ if (trx.offset[2]) { -+ part = &parts[curr_part++]; -+ part->name = "loader"; -+- part->offset = trx.offset[i]; -++ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); -+ i++; -+ } -+ -+ if (trx.offset[i]) { -+ part = &parts[curr_part++]; -+ part->name = "linux"; -+- part->offset = trx.offset[i]; -++ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); -+ i++; -+ } -+ -+ if (trx.offset[i]) { -+ part = &parts[curr_part++]; -+- part->name = parser_trx_data_part_name(mtd, trx.offset[i]); -+- part->offset = trx.offset[i]; -++ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); -++ part->name = parser_trx_data_part_name(mtd, part->offset); -+ i++; -+ } -+ -diff --git a/target/linux/generic/pending-4.14/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch b/target/linux/generic/pending-4.14/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch -new file mode 100644 -index 0000000000..a6d0828b99 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch -@@ -0,0 +1,37 @@ -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Subject: mtd: bcm47xxpart: detect T_Meter partition -+ -+It can be found on many Netgear devices. It consists of many 0x30 blocks -+starting with 4D 54. -+ -+Signed-off-by: Rafał Miłecki -+--- -+ drivers/mtd/bcm47xxpart.c | 10 ++++++++++ -+ 1 file changed, 10 insertions(+) -+ -+--- a/drivers/mtd/bcm47xxpart.c -++++ b/drivers/mtd/bcm47xxpart.c -+@@ -39,6 +39,7 @@ -+ #define NVRAM_HEADER 0x48534C46 /* FLSH */ -+ #define POT_MAGIC1 0x54544f50 /* POTT */ -+ #define POT_MAGIC2 0x504f /* OP */ -++#define T_METER_MAGIC 0x4D540000 /* MT */ -+ #define ML_MAGIC1 0x39685a42 -+ #define ML_MAGIC2 0x26594131 -+ #define TRX_MAGIC 0x30524448 -+@@ -182,6 +183,15 @@ static int bcm47xxpart_parse(struct mtd_ -+ MTD_WRITEABLE); -+ continue; -+ } -++ -++ /* T_Meter */ -++ if ((le32_to_cpu(buf[0x000 / 4]) & 0xFFFF0000) == T_METER_MAGIC && -++ (le32_to_cpu(buf[0x030 / 4]) & 0xFFFF0000) == T_METER_MAGIC && -++ (le32_to_cpu(buf[0x060 / 4]) & 0xFFFF0000) == T_METER_MAGIC) { -++ bcm47xxpart_add_part(&parts[curr_part++], "T_Meter", offset, -++ MTD_WRITEABLE); -++ continue; -++ } -+ -+ /* TRX */ -+ if (buf[0x000 / 4] == TRX_MAGIC) { -diff --git a/target/linux/generic/pending-4.14/435-mtd-add-routerbootpart-parser-config.patch b/target/linux/generic/pending-4.14/435-mtd-add-routerbootpart-parser-config.patch -new file mode 100644 -index 0000000000..946af76f5b ---- /dev/null -+++ b/target/linux/generic/pending-4.14/435-mtd-add-routerbootpart-parser-config.patch -@@ -0,0 +1,36 @@ -+From 4437e01fb6bca63fccdba5d6c44888b0935885c2 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= -+Date: Tue, 24 Mar 2020 11:45:07 +0100 -+Subject: [PATCH] generic: routerboot partition build bits (4.14) -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This patch adds routerbootpart kernel build bits -+ -+Signed-off-by: Thibaut VARÈNE -+--- -+ drivers/mtd/parsers/Kconfig | 9 +++++++++ -+ drivers/mtd/parsers/Makefile | 1 + -+ 2 files changed, 10 insertions(+) -+ -+--- a/drivers/mtd/parsers/Kconfig -++++ b/drivers/mtd/parsers/Kconfig -+@@ -6,3 +6,12 @@ config MTD_PARSER_TRX -+ may contain up to 3/4 partitions (depending on the version). -+ This driver will parse TRX header and report at least two partitions: -+ kernel and rootfs. -++ -++config MTD_ROUTERBOOT_PARTS -++ tristate "RouterBoot flash partition parser" -++ depends on MTD && OF -++ help -++ MikroTik RouterBoot is implemented as a multi segment system on the -++ flash, some of which are fixed and some of which are located at -++ variable offsets. This parser handles both cases via properly -++ formatted DTS. -+--- a/drivers/mtd/parsers/Makefile -++++ b/drivers/mtd/parsers/Makefile -+@@ -1 +1,2 @@ -+ obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o -++obj-$(CONFIG_MTD_ROUTERBOOT_PARTS) += routerbootpart.o -diff --git a/target/linux/generic/pending-4.14/440-block2mtd_init.patch b/target/linux/generic/pending-4.14/440-block2mtd_init.patch -new file mode 100644 -index 0000000000..8834788732 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/440-block2mtd_init.patch -@@ -0,0 +1,116 @@ -+From: Felix Fietkau -+Subject: block2mtd -+ -+Signed-off-by: Felix Fietkau -+--- -+ drivers/mtd/devices/block2mtd.c | 30 ++++++++++++++++++++---------- -+ 1 file changed, 20 insertions(+), 10 deletions(-) -+ -+--- a/drivers/mtd/devices/block2mtd.c -++++ b/drivers/mtd/devices/block2mtd.c -+@@ -26,6 +26,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #include -+ #include -+@@ -219,7 +220,7 @@ static void block2mtd_free_device(struct -+ -+ -+ static struct block2mtd_dev *add_device(char *devname, int erase_size, -+- int timeout) -++ const char *mtdname, int timeout) -+ { -+ #ifndef MODULE -+ int i; -+@@ -227,6 +228,7 @@ static struct block2mtd_dev *add_device( -+ const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL; -+ struct block_device *bdev = ERR_PTR(-ENODEV); -+ struct block2mtd_dev *dev; -++ struct mtd_partition *part; -+ char *name; -+ -+ if (!devname) -+@@ -283,13 +285,16 @@ static struct block2mtd_dev *add_device( -+ -+ /* Setup the MTD structure */ -+ /* make the name contain the block device in */ -+- name = kasprintf(GFP_KERNEL, "block2mtd: %s", devname); -++ if (!mtdname) -++ mtdname = devname; -++ name = kmalloc(strlen(mtdname) + 1, GFP_KERNEL); -+ if (!name) -+ goto err_destroy_mutex; -+ -++ strcpy(name, mtdname); -+ dev->mtd.name = name; -+ -+- dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; -++ dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK & ~(erase_size - 1); -+ dev->mtd.erasesize = erase_size; -+ dev->mtd.writesize = 1; -+ dev->mtd.writebufsize = PAGE_SIZE; -+@@ -302,7 +307,11 @@ static struct block2mtd_dev *add_device( -+ dev->mtd.priv = dev; -+ dev->mtd.owner = THIS_MODULE; -+ -+- if (mtd_device_register(&dev->mtd, NULL, 0)) { -++ part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL); -++ part->name = name; -++ part->offset = 0; -++ part->size = dev->mtd.size; -++ if (mtd_device_register(&dev->mtd, part, 1)) { -+ /* Device didn't get added, so free the entry */ -+ goto err_destroy_mutex; -+ } -+@@ -310,8 +319,7 @@ static struct block2mtd_dev *add_device( -+ list_add(&dev->list, &blkmtd_device_list); -+ pr_info("mtd%d: [%s] erase_size = %dKiB [%d]\n", -+ dev->mtd.index, -+- dev->mtd.name + strlen("block2mtd: "), -+- dev->mtd.erasesize >> 10, dev->mtd.erasesize); -++ mtdname, dev->mtd.erasesize >> 10, dev->mtd.erasesize); -+ return dev; -+ -+ err_destroy_mutex: -+@@ -384,7 +392,7 @@ static int block2mtd_setup2(const char * -+ /* 80 for device, 12 for erase size, 80 for name, 8 for timeout */ -+ char buf[80 + 12 + 80 + 8]; -+ char *str = buf; -+- char *token[2]; -++ char *token[3]; -+ char *name; -+ size_t erase_size = PAGE_SIZE; -+ unsigned long timeout = MTD_DEFAULT_TIMEOUT; -+@@ -398,7 +406,7 @@ static int block2mtd_setup2(const char * -+ strcpy(str, val); -+ kill_final_newline(str); -+ -+- for (i = 0; i < 2; i++) -++ for (i = 0; i < 3; i++) -+ token[i] = strsep(&str, ","); -+ -+ if (str) { -+@@ -424,8 +432,10 @@ static int block2mtd_setup2(const char * -+ return 0; -+ } -+ } -++ if (token[2] && (strlen(token[2]) + 1 > 80)) -++ pr_err("mtd device name too long\n"); -+ -+- add_device(name, erase_size, timeout); -++ add_device(name, erase_size, token[2], timeout); -+ -+ return 0; -+ } -+@@ -459,7 +469,7 @@ static int block2mtd_setup(const char *v -+ -+ -+ module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); -+-MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=[,]\""); -++MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=[,[,]]\""); -+ -+ static int __init block2mtd_init(void) -+ { -diff --git a/target/linux/generic/pending-4.14/441-block2mtd_probe.patch b/target/linux/generic/pending-4.14/441-block2mtd_probe.patch -new file mode 100644 -index 0000000000..fee970ab61 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/441-block2mtd_probe.patch -@@ -0,0 +1,47 @@ -+From: Felix Fietkau -+Subject: block2mtd -+ -+Signed-off-by: Felix Fietkau -+--- -+ drivers/mtd/devices/block2mtd.c | 9 ++++++--- -+ 1 file changed, 6 insertions(+), 3 deletions(-) -+ -+--- a/drivers/mtd/devices/block2mtd.c -++++ b/drivers/mtd/devices/block2mtd.c -+@@ -392,7 +392,7 @@ static int block2mtd_setup2(const char * -+ /* 80 for device, 12 for erase size, 80 for name, 8 for timeout */ -+ char buf[80 + 12 + 80 + 8]; -+ char *str = buf; -+- char *token[3]; -++ char *token[4]; -+ char *name; -+ size_t erase_size = PAGE_SIZE; -+ unsigned long timeout = MTD_DEFAULT_TIMEOUT; -+@@ -406,7 +406,7 @@ static int block2mtd_setup2(const char * -+ strcpy(str, val); -+ kill_final_newline(str); -+ -+- for (i = 0; i < 3; i++) -++ for (i = 0; i < 4; i++) -+ token[i] = strsep(&str, ","); -+ -+ if (str) { -+@@ -435,6 +435,9 @@ static int block2mtd_setup2(const char * -+ if (token[2] && (strlen(token[2]) + 1 > 80)) -+ pr_err("mtd device name too long\n"); -+ -++ if (token[3] && kstrtoul(token[3], 0, &timeout)) -++ pr_err("invalid timeout\n"); -++ -+ add_device(name, erase_size, token[2], timeout); -+ -+ return 0; -+@@ -469,7 +472,7 @@ static int block2mtd_setup(const char *v -+ -+ -+ module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); -+-MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=[,[,]]\""); -++MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=[,[,[,]]]\""); -+ -+ static int __init block2mtd_init(void) -+ { -diff --git a/target/linux/generic/pending-4.14/450-mtd-m25p80-allow-fallback-from-spi_flash_read-to-reg.patch b/target/linux/generic/pending-4.14/450-mtd-m25p80-allow-fallback-from-spi_flash_read-to-reg.patch -new file mode 100644 -index 0000000000..accd63df58 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/450-mtd-m25p80-allow-fallback-from-spi_flash_read-to-reg.patch -@@ -0,0 +1,36 @@ -+From: Felix Fietkau -+Date: Fri, 23 Feb 2018 17:12:16 +0100 -+Subject: [PATCH] mtd: m25p80: allow fallback from spi_flash_read to regular -+ SPI transfer -+ -+Some flash controllers, e.g. on the ath79 platform can support a fast -+flash read via memory mapping, but only if the flash chip is in -+3-byte address mode. -+ -+Since spi_flash_read_supported does not have access to the same data as -+spi_flash_read, the driver can't detect an unsupported call until m25p80 -+has decided to use spi_flash_read. -+ -+Allow the driver to indicate a fallback to a regular SPI transfer by -+returning -EOPNOTSUPP -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/mtd/devices/m25p80.c -++++ b/drivers/mtd/devices/m25p80.c -+@@ -170,9 +170,11 @@ static ssize_t m25p80_read(struct spi_no -+ msg.data_nbits = data_nbits; -+ -+ ret = spi_flash_read(spi, &msg); -+- if (ret < 0) -+- return ret; -+- return msg.retlen; -++ if (ret != -EOPNOTSUPP) { -++ if (ret < 0) -++ return ret; -++ return msg.retlen; -++ } -+ } -+ -+ spi_message_init(&m); -diff --git a/target/linux/generic/pending-4.14/450-mtd-spi-nor-allow-NOR-driver-to-write-fewer-bytes-th.patch b/target/linux/generic/pending-4.14/450-mtd-spi-nor-allow-NOR-driver-to-write-fewer-bytes-th.patch -new file mode 100644 -index 0000000000..571c9b885f ---- /dev/null -+++ b/target/linux/generic/pending-4.14/450-mtd-spi-nor-allow-NOR-driver-to-write-fewer-bytes-th.patch -@@ -0,0 +1,36 @@ -+From: Felix Fietkau -+Date: Thu, 22 Feb 2018 11:11:57 +0100 -+Subject: [PATCH] mtd: spi-nor: allow NOR driver to write fewer bytes than -+ requested -+ -+The write size can be constrained by the maximum message/transfer size -+of the SPI controller. Only check for ret = 0 to avoid an infinite loop. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/mtd/spi-nor/spi-nor.c -++++ b/drivers/mtd/spi-nor/spi-nor.c -+@@ -1377,7 +1377,7 @@ static int spi_nor_write(struct mtd_info -+ -+ write_enable(nor); -+ ret = nor->write(nor, addr, page_remain, buf + i); -+- if (ret < 0) -++ if (ret <= 0) -+ goto write_err; -+ written = ret; -+ -+@@ -1386,13 +1386,6 @@ static int spi_nor_write(struct mtd_info -+ goto write_err; -+ *retlen += written; -+ i += written; -+- if (written != page_remain) { -+- dev_err(nor->dev, -+- "While writing %zu bytes written %zd bytes\n", -+- page_remain, written); -+- ret = -EIO; -+- goto write_err; -+- } -+ } -+ -+ write_err: -diff --git a/target/linux/generic/pending-4.14/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch b/target/linux/generic/pending-4.14/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch -new file mode 100644 -index 0000000000..41f9d31cb0 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch -@@ -0,0 +1,25 @@ -+From: Felix Fietkau -+Subject: kernel: disable cfi cmdset 0002 erase suspend -+ -+on some platforms, erase suspend leads to data corruption and lockups when write -+ops collide with erase ops. this has been observed on the buffalo wzr-hp-g300nh. -+rather than play whack-a-mole with a hard to reproduce issue on a variety of devices, -+simply disable erase suspend, as it will usually not produce any useful gain on -+the small filesystems used on embedded hardware. -+ -+Signed-off-by: Felix Fietkau -+--- -+ drivers/mtd/chips/cfi_cmdset_0002.c | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/drivers/mtd/chips/cfi_cmdset_0002.c -++++ b/drivers/mtd/chips/cfi_cmdset_0002.c -+@@ -811,7 +811,7 @@ static int get_chip(struct map_info *map -+ return 0; -+ -+ case FL_ERASING: -+- if (!cfip || !(cfip->EraseSuspend & (0x1|0x2)) || -++ if (1 /* no suspend */ || !cfip || !(cfip->EraseSuspend & (0x1|0x2)) || -+ !(mode == FL_READY || mode == FL_POINT || -+ (mode == FL_WRITING && (cfip->EraseSuspend & 0x2)))) -+ goto sleep; -diff --git a/target/linux/generic/pending-4.14/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch b/target/linux/generic/pending-4.14/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch -new file mode 100644 -index 0000000000..932f219cf2 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch -@@ -0,0 +1,17 @@ -+From: George Kashperko -+Subject: Issue map read after Write Buffer Load command to ensure chip is ready to receive data. -+ -+Signed-off-by: George Kashperko -+--- -+ drivers/mtd/chips/cfi_cmdset_0002.c | 1 + -+ 1 file changed, 1 insertion(+) -+--- a/drivers/mtd/chips/cfi_cmdset_0002.c -++++ b/drivers/mtd/chips/cfi_cmdset_0002.c -+@@ -1839,6 +1839,7 @@ static int __xipram do_write_buffer(stru -+ -+ /* Write Buffer Load */ -+ map_write(map, CMD(0x25), cmd_adr); -++ (void) map_read(map, cmd_adr); -+ -+ chip->state = FL_WRITING_TO_BUFFER; -+ -diff --git a/target/linux/generic/pending-4.14/465-m25p80-mx-disable-software-protection.patch b/target/linux/generic/pending-4.14/465-m25p80-mx-disable-software-protection.patch -new file mode 100644 -index 0000000000..b41710276f ---- /dev/null -+++ b/target/linux/generic/pending-4.14/465-m25p80-mx-disable-software-protection.patch -@@ -0,0 +1,18 @@ -+From: Felix Fietkau -+Subject: Disable software protection bits for Macronix flashes. -+ -+Signed-off-by: Felix Fietkau -+--- -+ drivers/mtd/spi-nor/spi-nor.c | 1 + -+ 1 file changed, 1 insertion(+) -+ -+--- a/drivers/mtd/spi-nor/spi-nor.c -++++ b/drivers/mtd/spi-nor/spi-nor.c -+@@ -2714,6 +2714,7 @@ int spi_nor_scan(struct spi_nor *nor, co -+ -+ if (JEDEC_MFR(info) == SNOR_MFR_ATMEL || -+ JEDEC_MFR(info) == SNOR_MFR_INTEL || -++ JEDEC_MFR(info) == SNOR_MFR_MACRONIX || -+ JEDEC_MFR(info) == SNOR_MFR_SST || -+ info->flags & SPI_NOR_HAS_LOCK) { -+ write_enable(nor); -diff --git a/target/linux/generic/pending-4.14/466-Revert-mtd-spi-nor-fix-Spansion-regressions-aliased-.patch b/target/linux/generic/pending-4.14/466-Revert-mtd-spi-nor-fix-Spansion-regressions-aliased-.patch -new file mode 100644 -index 0000000000..55d9709761 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/466-Revert-mtd-spi-nor-fix-Spansion-regressions-aliased-.patch -@@ -0,0 +1,37 @@ -+From: Matthias Schiffer -+Date: Tue, 9 Jan 2018 20:41:48 +0100 -+Subject: [PATCH] Revert "mtd: spi-nor: fix Spansion regressions (aliased with -+ Winbond)" -+ -+This reverts commit 67b9bcd36906e12a15ffec19463afbbd6a41660e. -+ -+The underlying issue breaking Spansion flash has been fixed with "mtd: spi-nor: -+wait until lock/unlock operations are ready" and "mtd: spi-nor: wait for SR_WIP -+to clear on initial unlock", so we can support unlocking for Winbond flash -+again. -+ -+Signed-off-by: Matthias Schiffer -+--- -+ drivers/mtd/spi-nor/spi-nor.c | 4 +++- -+ 1 file changed, 3 insertions(+), 1 deletion(-) -+ -+--- a/drivers/mtd/spi-nor/spi-nor.c -++++ b/drivers/mtd/spi-nor/spi-nor.c -+@@ -2716,6 +2716,7 @@ int spi_nor_scan(struct spi_nor *nor, co -+ JEDEC_MFR(info) == SNOR_MFR_INTEL || -+ JEDEC_MFR(info) == SNOR_MFR_MACRONIX || -+ JEDEC_MFR(info) == SNOR_MFR_SST || -++ JEDEC_MFR(info) == SNOR_MFR_WINBOND || -+ info->flags & SPI_NOR_HAS_LOCK) { -+ write_enable(nor); -+ write_sr(nor, 0); -+@@ -2734,7 +2735,8 @@ int spi_nor_scan(struct spi_nor *nor, co -+ -+ /* NOR protection support for STmicro/Micron chips and similar */ -+ if (JEDEC_MFR(info) == SNOR_MFR_MICRON || -+- info->flags & SPI_NOR_HAS_LOCK) { -++ JEDEC_MFR(info) == SNOR_MFR_WINBOND || -++ info->flags & SPI_NOR_HAS_LOCK) { -+ nor->flash_lock = stm_lock; -+ nor->flash_unlock = stm_unlock; -+ nor->flash_is_locked = stm_is_locked; -diff --git a/target/linux/generic/pending-4.14/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch b/target/linux/generic/pending-4.14/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch -new file mode 100644 -index 0000000000..0f4ea32688 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/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 -+@@ -39,6 +39,17 @@ config SPI_ASPEED_SMC -+ and support for the SPI flash memory controller (SPI) for -+ the host firmware. The implementation only supports SPI NOR. -+ -++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 && !ARCH_EBSA110) -+--- a/drivers/mtd/spi-nor/spi-nor.c -++++ b/drivers/mtd/spi-nor/spi-nor.c -+@@ -2561,10 +2561,12 @@ static int spi_nor_select_erase(struct s -+ -+ #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.14/475-mtd-spi-nor-Add-Winbond-w25q128jv-support.patch b/target/linux/generic/pending-4.14/475-mtd-spi-nor-Add-Winbond-w25q128jv-support.patch -new file mode 100644 -index 0000000000..f751bfd3b2 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/475-mtd-spi-nor-Add-Winbond-w25q128jv-support.patch -@@ -0,0 +1,34 @@ -+From: Robert Marko -+To: linux-mtd@lists.infradead.org -+Subject: mtd: spi-nor: Add Winbond w25q128jv support -+Date: Mon, 25 Jun 2018 13:17:48 +0200 -+ -+Datasheet: -+http://www.winbond.com/resource-files/w25q128jv%20revf%2003272018%20plus.pdf -+ -+Testing done on Mikrotik Routerboard wAP R board. -+It does not support Dual or Quad modes. -+ -+Signed-off-by: Robert Marko -+--- -+ -+Changes in v2: -+ - Correct the title -+--- -+ drivers/mtd/spi-nor/spi-nor.c | 5 +++++ -+ 1 file changed, 5 insertions(+) -+ -+--- a/drivers/mtd/spi-nor/spi-nor.c -++++ b/drivers/mtd/spi-nor/spi-nor.c -+@@ -1165,6 +1165,11 @@ static const struct flash_info spi_nor_i -+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) -+ }, -++ { -++ "w25q128jv", INFO(0xef7018, 0, 64 * 1024, 256, -++ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -++ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) -++ }, -+ { "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) }, -diff --git a/target/linux/generic/pending-4.14/476-mtd-spi-nor-add-eon-en25q128.patch b/target/linux/generic/pending-4.14/476-mtd-spi-nor-add-eon-en25q128.patch -new file mode 100644 -index 0000000000..ac1fda5159 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/476-mtd-spi-nor-add-eon-en25q128.patch -@@ -0,0 +1,18 @@ -+From: Piotr Dymacz -+Subject: kernel/mtd: add support for EON EN25Q128 -+ -+Signed-off-by: Piotr Dymacz -+--- -+ drivers/mtd/spi-nor/spi-nor.c | 1 + -+ 1 file changed, 1 insertion(+) -+ -+--- a/drivers/mtd/spi-nor/spi-nor.c -++++ b/drivers/mtd/spi-nor/spi-nor.c -+@@ -954,6 +954,7 @@ static const struct flash_info spi_nor_i -+ { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, -+ { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, -+ { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, -++ { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256, SECT_4K) }, -+ { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, -+ { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, -+ { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, -diff --git a/target/linux/generic/pending-4.14/477-mtd-add-spi-nor-add-mx25u3235f.patch b/target/linux/generic/pending-4.14/477-mtd-add-spi-nor-add-mx25u3235f.patch -new file mode 100644 -index 0000000000..2d94959c5c ---- /dev/null -+++ b/target/linux/generic/pending-4.14/477-mtd-add-spi-nor-add-mx25u3235f.patch -@@ -0,0 +1,18 @@ -+From: André Valentin -+Subject: linux/mtd: add id for mx25u3235f needed by ZyXEL NBG6817 -+ -+Signed-off-by: André Valentin -+--- -+ drivers/mtd/spi-nor/spi-nor.c | 1 + -+ 1 file changed, 1 insertion(+) -+ -+--- a/drivers/mtd/spi-nor/spi-nor.c -++++ b/drivers/mtd/spi-nor/spi-nor.c -+@@ -1022,6 +1022,7 @@ static const struct flash_info spi_nor_i -+ { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) }, -+ { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, -+ { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) }, -++ { "mx25u3235f", INFO(0xc22536, 0, 64 * 1024, 64, 0) }, -+ { "mx25u2033e", INFO(0xc22532, 0, 64 * 1024, 4, SECT_4K) }, -+ { "mx25u4035", INFO(0xc22533, 0, 64 * 1024, 8, SECT_4K) }, -+ { "mx25u8035", INFO(0xc22534, 0, 64 * 1024, 16, SECT_4K) }, -diff --git a/target/linux/generic/pending-4.14/478-mtd-spi-nor-Add-support-for-XM25QH64A-and-XM25QH128A.patch b/target/linux/generic/pending-4.14/478-mtd-spi-nor-Add-support-for-XM25QH64A-and-XM25QH128A.patch -new file mode 100644 -index 0000000000..4ecf53621d ---- /dev/null -+++ b/target/linux/generic/pending-4.14/478-mtd-spi-nor-Add-support-for-XM25QH64A-and-XM25QH128A.patch -@@ -0,0 +1,30 @@ -+From b02f3405c935a28200db26b63e42086057565cf4 Mon Sep 17 00:00:00 2001 -+From: Hauke Mehrtens -+Date: Sat, 31 Mar 2018 20:09:54 +0200 -+Subject: [PATCH] mtd: spi-nor: Add support for XM25QH64A and XM25QH128A -+ -+These devices are produced by Wuhan Xinxin Semiconductor Manufacturing -+Corp. (XMC) and found on some routers from Chinese manufactures. -+ -+The data sheets can be found here: -+http://www.xmcwh.com/Uploads/2018-03-01/5a9799e4cb355.pdf -+http://www.xmcwh.com/Uploads/2018-02-05/5a77e6dbe968b.pdf -+ -+Signed-off-by: Hauke Mehrtens -+--- -+ drivers/mtd/spi-nor/spi-nor.c | 4 ++++ -+ 1 file changed, 4 insertions(+) -+ -+--- a/drivers/mtd/spi-nor/spi-nor.c -++++ b/drivers/mtd/spi-nor/spi-nor.c -+@@ -1192,6 +1192,10 @@ static const struct flash_info spi_nor_i -+ { "3S400AN", S3AN_INFO(0x1f2400, 256, 264) }, -+ { "3S700AN", S3AN_INFO(0x1f2500, 512, 264) }, -+ { "3S1400AN", S3AN_INFO(0x1f2600, 512, 528) }, -++ -++ /* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */ -++ { "XM25QH64A", INFO(0x207017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -++ { "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { }, -+ }; -+ -diff --git a/target/linux/generic/pending-4.14/479-mtd-spi-nor-add-eon-en25qh32.patch b/target/linux/generic/pending-4.14/479-mtd-spi-nor-add-eon-en25qh32.patch -new file mode 100644 -index 0000000000..b8d5101514 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/479-mtd-spi-nor-add-eon-en25qh32.patch -@@ -0,0 +1,10 @@ -+--- a/drivers/mtd/spi-nor/spi-nor.c -++++ b/drivers/mtd/spi-nor/spi-nor.c -+@@ -955,6 +955,7 @@ static const struct flash_info spi_nor_i -+ { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, -+ { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256, SECT_4K) }, -++ { "en25qh32", INFO(0x1c7016, 0, 64 * 1024, 64, 0) }, -+ { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, -+ { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, -+ { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, -diff --git a/target/linux/generic/pending-4.14/479-mtd-spi-nor-add-eon-en25qh64.patch b/target/linux/generic/pending-4.14/479-mtd-spi-nor-add-eon-en25qh64.patch -new file mode 100644 -index 0000000000..c290a784d0 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/479-mtd-spi-nor-add-eon-en25qh64.patch -@@ -0,0 +1,10 @@ -+--- a/drivers/mtd/spi-nor/spi-nor.c -++++ b/drivers/mtd/spi-nor/spi-nor.c -+@@ -956,6 +956,7 @@ static const struct flash_info spi_nor_i -+ { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256, SECT_4K) }, -+ { "en25qh32", INFO(0x1c7016, 0, 64 * 1024, 64, 0) }, -++ { "en25qh64", INFO(0x1c7017, 0, 64 * 1024, 128, 0) }, -+ { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, -+ { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, -+ { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, -diff --git a/target/linux/generic/pending-4.14/479-mtd-spi-nor-add-xtx-xt25f128b.patch b/target/linux/generic/pending-4.14/479-mtd-spi-nor-add-xtx-xt25f128b.patch -new file mode 100644 -index 0000000000..7545cf8427 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/479-mtd-spi-nor-add-xtx-xt25f128b.patch -@@ -0,0 +1,42 @@ -+From patchwork Thu Feb 6 17:19:41 2020 -+Content-Type: text/plain; charset="utf-8" -+MIME-Version: 1.0 -+Content-Transfer-Encoding: 7bit -+X-Patchwork-Submitter: Daniel Golle -+X-Patchwork-Id: 1234465 -+Date: Thu, 6 Feb 2020 19:19:41 +0200 -+From: Daniel Golle -+To: linux-mtd@lists.infradead.org -+Subject: [PATCH v2] mtd: spi-nor: Add support for xt25f128b chip -+Message-ID: <20200206171941.GA2398@makrotopia.org> -+MIME-Version: 1.0 -+Content-Disposition: inline -+List-Subscribe: , -+ -+Cc: Eitan Cohen , Piotr Dymacz , -+ Tudor Ambarus -+Sender: "linux-mtd" -+Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org -+ -+Add XT25F128B made by XTX Technology (Shenzhen) Limited. -+This chip supports dual and quad read and uniform 4K-byte erase. -+Verified on Teltonika RUT955 which comes with XT25F128B in recent -+versions of the device. -+ -+Signed-off-by: Daniel Golle -+--- -+ drivers/mtd/spi-nor/spi-nor.c | 4 ++++ -+ 1 file changed, 4 insertions(+) -+ -+--- a/drivers/mtd/spi-nor/spi-nor.c -++++ b/drivers/mtd/spi-nor/spi-nor.c -+@@ -1198,6 +1198,9 @@ static const struct flash_info spi_nor_i -+ /* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */ -+ { "XM25QH64A", INFO(0x207017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -++ -++ /* XTX Technology (Shenzhen) Limited */ -++ { "xt25f128b", INFO(0x0B4018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { }, -+ }; -+ -diff --git a/target/linux/generic/pending-4.14/480-mtd-set-rootfs-to-be-root-dev.patch b/target/linux/generic/pending-4.14/480-mtd-set-rootfs-to-be-root-dev.patch -new file mode 100644 -index 0000000000..6cddaf01b7 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/480-mtd-set-rootfs-to-be-root-dev.patch -@@ -0,0 +1,38 @@ -+From: Gabor Juhos -+Subject: kernel/3.1[02]: move MTD root device setup code to mtdcore -+ -+The current code only allows to automatically set -+root device on MTD partitions. Move the code to MTD -+core to allow to use it with all MTD devices. -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/mtd/mtdcore.c | 10 ++++++++++ -+ 1 file changed, 10 insertions(+) -+ -+--- a/drivers/mtd/mtdcore.c -++++ b/drivers/mtd/mtdcore.c -+@@ -41,6 +41,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include -+ #include -+@@ -578,6 +579,15 @@ int add_mtd_device(struct mtd_info *mtd) -+ of this try_ nonsense, and no bitching about it -+ either. :) */ -+ __module_get(THIS_MODULE); -++ -++ if (!strcmp(mtd->name, "rootfs") && -++ IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && -++ ROOT_DEV == 0) { -++ pr_notice("mtd: device %d (%s) set to be root filesystem\n", -++ mtd->index, mtd->name); -++ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index); -++ } -++ -+ return 0; -+ -+ fail_added: -diff --git a/target/linux/generic/pending-4.14/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch b/target/linux/generic/pending-4.14/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch -new file mode 100644 -index 0000000000..4e632b05a0 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch -@@ -0,0 +1,24 @@ -+From d68b4aa22e8c625685bfad642dd7337948dc0ad1 Mon Sep 17 00:00:00 2001 -+From: Koen Vandeputte -+Date: Mon, 6 Jan 2020 13:07:56 +0100 -+Subject: [PATCH] mtd: spi-nor: add support for Gigadevice GD25D05 -+ -+Signed-off-by: Koen Vandeputte -+--- -+ drivers/mtd/spi-nor/spi-nor.c | 5 +++++ -+ 1 file changed, 5 insertions(+) -+ -+--- a/drivers/mtd/spi-nor/spi-nor.c -++++ b/drivers/mtd/spi-nor/spi-nor.c -+@@ -976,6 +976,11 @@ static const struct flash_info spi_nor_i -+ -+ /* GigaDevice */ -+ { -++ "gd25d05", INFO(0xc84010, 0, 64 * 1024, 1, -++ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -++ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) -++ }, -++ { -+ "gd25q16", INFO(0xc84015, 0, 64 * 1024, 32, -+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) -diff --git a/target/linux/generic/pending-4.14/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch b/target/linux/generic/pending-4.14/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch -new file mode 100644 -index 0000000000..992aa4662e ---- /dev/null -+++ b/target/linux/generic/pending-4.14/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch -@@ -0,0 +1,97 @@ -+From: Daniel Golle -+Subject: ubi: auto-attach mtd device named "ubi" or "data" on boot -+ -+Signed-off-by: Daniel Golle -+--- -+ drivers/mtd/ubi/build.c | 36 ++++++++++++++++++++++++++++++++++++ -+ 1 file changed, 36 insertions(+) -+ -+--- a/drivers/mtd/ubi/build.c -++++ b/drivers/mtd/ubi/build.c -+@@ -1172,6 +1172,73 @@ static struct mtd_info * __init open_mtd -+ return mtd; -+ } -+ -++/* -++ * This function tries attaching mtd partitions named either "ubi" or "data" -++ * during boot. -++ */ -++static void __init ubi_auto_attach(void) -++{ -++ int err; -++ struct mtd_info *mtd; -++ loff_t offset = 0; -++ size_t len; -++ char magic[4]; -++ -++ /* try attaching mtd device named "ubi" or "data" */ -++ mtd = open_mtd_device("ubi"); -++ if (IS_ERR(mtd)) -++ mtd = open_mtd_device("data"); -++ -++ if (IS_ERR(mtd)) -++ return; -++ -++ /* get the first not bad block */ -++ if (mtd_can_have_bb(mtd)) -++ while (mtd_block_isbad(mtd, offset)) { -++ offset += mtd->erasesize; -++ -++ if (offset > mtd->size) { -++ pr_err("UBI error: Failed to find a non-bad " -++ "block on mtd%d\n", mtd->index); -++ goto cleanup; -++ } -++ } -++ -++ /* check if the read from flash was successful */ -++ err = mtd_read(mtd, offset, 4, &len, (void *) magic); -++ if ((err && !mtd_is_bitflip(err)) || len != 4) { -++ pr_err("UBI error: unable to read from mtd%d\n", mtd->index); -++ goto cleanup; -++ } -++ -++ /* check for a valid ubi magic */ -++ if (strncmp(magic, "UBI#", 4)) { -++ pr_err("UBI error: no valid UBI magic found inside mtd%d\n", mtd->index); -++ goto cleanup; -++ } -++ -++ /* don't auto-add media types where UBI doesn't makes sense */ -++ if (mtd->type != MTD_NANDFLASH && -++ mtd->type != MTD_NORFLASH && -++ mtd->type != MTD_DATAFLASH && -++ mtd->type != MTD_MLCNANDFLASH) -++ goto cleanup; -++ -++ mutex_lock(&ubi_devices_mutex); -++ pr_notice("UBI: auto-attach mtd%d\n", mtd->index); -++ err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0); -++ mutex_unlock(&ubi_devices_mutex); -++ if (err < 0) { -++ pr_err("UBI error: cannot attach mtd%d\n", mtd->index); -++ goto cleanup; -++ } -++ -++ return; -++ -++cleanup: -++ put_mtd_device(mtd); -++} -++ -+ static int __init ubi_init(void) -+ { -+ int err, i, k; -+@@ -1255,6 +1322,12 @@ static int __init ubi_init(void) -+ } -+ } -+ -++ /* auto-attach mtd devices only if built-in to the kernel and no ubi.mtd -++ * parameter was given */ -++ if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && -++ !ubi_is_module() && !mtd_devs) -++ ubi_auto_attach(); -++ -+ err = ubiblock_init(); -+ if (err) { -+ pr_err("UBI error: block: cannot initialize, error %d\n", err); -diff --git a/target/linux/generic/pending-4.14/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-4.14/491-ubi-auto-create-ubiblock-device-for-rootfs.patch -new file mode 100644 -index 0000000000..cb2d525610 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/491-ubi-auto-create-ubiblock-device-for-rootfs.patch -@@ -0,0 +1,66 @@ -+From: Daniel Golle -+Subject: ubi: auto-create ubiblock device for rootfs -+ -+Signed-off-by: Daniel Golle -+--- -+ drivers/mtd/ubi/block.c | 42 ++++++++++++++++++++++++++++++++++++++++++ -+ 1 file changed, 42 insertions(+) -+ -+--- a/drivers/mtd/ubi/block.c -++++ b/drivers/mtd/ubi/block.c -+@@ -633,6 +633,44 @@ static void __init ubiblock_create_from_ -+ } -+ } -+ -++#define UBIFS_NODE_MAGIC 0x06101831 -++static inline int ubi_vol_is_ubifs(struct ubi_volume_desc *desc) -++{ -++ int ret; -++ uint32_t magic_of, magic; -++ ret = ubi_read(desc, 0, (char *)&magic_of, 0, 4); -++ if (ret) -++ return 0; -++ magic = le32_to_cpu(magic_of); -++ return magic == UBIFS_NODE_MAGIC; -++} -++ -++static void __init ubiblock_create_auto_rootfs(void) -++{ -++ int ubi_num, ret, is_ubifs; -++ struct ubi_volume_desc *desc; -++ struct ubi_volume_info vi; -++ -++ for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) { -++ desc = ubi_open_volume_nm(ubi_num, "rootfs", UBI_READONLY); -++ if (IS_ERR(desc)) -++ continue; -++ -++ ubi_get_volume_info(desc, &vi); -++ is_ubifs = ubi_vol_is_ubifs(desc); -++ ubi_close_volume(desc); -++ if (is_ubifs) -++ break; -++ -++ ret = ubiblock_create(&vi); -++ if (ret) -++ pr_err("UBI error: block: can't add '%s' volume, err=%d\n", -++ vi.name, ret); -++ /* always break if we get here */ -++ break; -++ } -++} -++ -+ static void ubiblock_remove_all(void) -+ { -+ struct ubiblock *next; -+@@ -665,6 +703,10 @@ int __init ubiblock_init(void) -+ */ -+ ubiblock_create_from_param(); -+ -++ /* auto-attach "rootfs" volume if existing and non-ubifs */ -++ if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV)) -++ ubiblock_create_auto_rootfs(); -++ -+ /* -+ * Block devices are only created upon user requests, so we ignore -+ * existing volumes. -diff --git a/target/linux/generic/pending-4.14/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch b/target/linux/generic/pending-4.14/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch -new file mode 100644 -index 0000000000..3c82a064eb ---- /dev/null -+++ b/target/linux/generic/pending-4.14/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch -@@ -0,0 +1,51 @@ -+From: Daniel Golle -+Subject: try auto-mounting ubi0:rootfs in init/do_mounts.c -+ -+Signed-off-by: Daniel Golle -+--- -+ init/do_mounts.c | 26 +++++++++++++++++++++++++- -+ 1 file changed, 25 insertions(+), 1 deletion(-) -+ -+--- a/init/do_mounts.c -++++ b/init/do_mounts.c -+@@ -437,7 +437,28 @@ retry: -+ out: -+ put_page(page); -+ } -+- -++ -++static int __init mount_ubi_rootfs(void) -++{ -++ int flags = MS_SILENT; -++ int err, tried = 0; -++ -++ while (tried < 2) { -++ err = do_mount_root("ubi0:rootfs", "ubifs", flags, \ -++ root_mount_data); -++ switch (err) { -++ case -EACCES: -++ flags |= MS_RDONLY; -++ tried++; -++ break; -++ default: -++ return err; -++ } -++ } -++ -++ return -EINVAL; -++} -++ -+ #ifdef CONFIG_ROOT_NFS -+ -+ #define NFSROOT_TIMEOUT_MIN 5 -+@@ -531,6 +552,10 @@ void __init mount_root(void) -+ change_floppy("root floppy"); -+ } -+ #endif -++#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV -++ if (!mount_ubi_rootfs()) -++ return; -++#endif -+ #ifdef CONFIG_BLOCK -+ { -+ int err = create_dev("/dev/root", ROOT_DEV); -diff --git a/target/linux/generic/pending-4.14/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch b/target/linux/generic/pending-4.14/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch -new file mode 100644 -index 0000000000..1bb53ada7f ---- /dev/null -+++ b/target/linux/generic/pending-4.14/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch -@@ -0,0 +1,34 @@ -+From: Daniel Golle -+Subject: ubi: set ROOT_DEV to ubiblock "rootfs" if unset -+ -+Signed-off-by: Daniel Golle -+--- -+ drivers/mtd/ubi/block.c | 10 ++++++++++ -+ 1 file changed, 10 insertions(+) -+ -+--- a/drivers/mtd/ubi/block.c -++++ b/drivers/mtd/ubi/block.c -+@@ -50,6 +50,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "ubi-media.h" -+ #include "ubi.h" -+@@ -445,6 +446,15 @@ int ubiblock_create(struct ubi_volume_in -+ dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)", -+ dev->ubi_num, dev->vol_id, vi->name); -+ mutex_unlock(&devices_mutex); -++ -++ if (!strcmp(vi->name, "rootfs") && -++ IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && -++ ROOT_DEV == 0) { -++ pr_notice("ubiblock: device ubiblock%d_%d (%s) set to be root filesystem\n", -++ dev->ubi_num, dev->vol_id, vi->name); -++ ROOT_DEV = MKDEV(gd->major, gd->first_minor); -++ } -++ -+ return 0; -+ -+ out_free_queue: -diff --git a/target/linux/generic/pending-4.14/494-mtd-ubi-add-EOF-marker-support.patch b/target/linux/generic/pending-4.14/494-mtd-ubi-add-EOF-marker-support.patch -new file mode 100644 -index 0000000000..a3b58dd66f ---- /dev/null -+++ b/target/linux/generic/pending-4.14/494-mtd-ubi-add-EOF-marker-support.patch -@@ -0,0 +1,60 @@ -+From: Gabor Juhos -+Subject: mtd: add EOF marker support to the UBI layer -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/mtd/ubi/attach.c | 25 ++++++++++++++++++++++--- -+ drivers/mtd/ubi/ubi.h | 1 + -+ 2 files changed, 23 insertions(+), 3 deletions(-) -+ -+--- a/drivers/mtd/ubi/attach.c -++++ b/drivers/mtd/ubi/attach.c -+@@ -939,6 +939,13 @@ static bool vol_ignored(int vol_id) -+ #endif -+ } -+ -++static bool ec_hdr_has_eof(struct ubi_ec_hdr *ech) -++{ -++ return ech->padding1[0] == 'E' && -++ ech->padding1[1] == 'O' && -++ ech->padding1[2] == 'F'; -++} -++ -+ /** -+ * scan_peb - scan and process UBI headers of a PEB. -+ * @ubi: UBI device description object -+@@ -971,9 +978,21 @@ static int scan_peb(struct ubi_device *u -+ return 0; -+ } -+ -+- err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); -+- if (err < 0) -+- return err; -++ if (!ai->eof_found) { -++ err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); -++ if (err < 0) -++ return err; -++ -++ if (ec_hdr_has_eof(ech)) { -++ pr_notice("UBI: EOF marker found, PEBs from %d will be erased\n", -++ pnum); -++ ai->eof_found = true; -++ } -++ } -++ -++ if (ai->eof_found) -++ err = UBI_IO_FF_BITFLIPS; -++ -+ switch (err) { -+ case 0: -+ break; -+--- a/drivers/mtd/ubi/ubi.h -++++ b/drivers/mtd/ubi/ubi.h -+@@ -785,6 +785,7 @@ struct ubi_attach_info { -+ int mean_ec; -+ uint64_t ec_sum; -+ int ec_count; -++ bool eof_found; -+ struct kmem_cache *aeb_slab_cache; -+ struct ubi_ec_hdr *ech; -+ struct ubi_vid_io_buf *vidb; -diff --git a/target/linux/generic/pending-4.14/495-mtd-core-add-get_mtd_device_by_node.patch b/target/linux/generic/pending-4.14/495-mtd-core-add-get_mtd_device_by_node.patch -new file mode 100644 -index 0000000000..2886742d4d ---- /dev/null -+++ b/target/linux/generic/pending-4.14/495-mtd-core-add-get_mtd_device_by_node.patch -@@ -0,0 +1,75 @@ -+From 1bd1b740f208d1cf4071932cc51860d37266c402 Mon Sep 17 00:00:00 2001 -+From: Bernhard Frauendienst -+Date: Sat, 1 Sep 2018 00:30:11 +0200 -+Subject: [PATCH 495/497] mtd: core: add get_mtd_device_by_node -+ -+Add function to retrieve a mtd device by its OF node. Since drivers can -+assign arbitrary names to mtd devices in the absence of a label -+property, there is no other reliable way to retrieve a mtd device for a -+given OF node. -+ -+Signed-off-by: Bernhard Frauendienst -+Reviewed-by: Miquel Raynal -+--- -+ drivers/mtd/mtdcore.c | 38 ++++++++++++++++++++++++++++++++++++++ -+ include/linux/mtd/mtd.h | 2 ++ -+ 2 files changed, 40 insertions(+) -+ -+--- a/drivers/mtd/mtdcore.c -++++ b/drivers/mtd/mtdcore.c -+@@ -924,6 +924,44 @@ out_unlock: -+ } -+ EXPORT_SYMBOL_GPL(get_mtd_device_nm); -+ -++/** -++ * get_mtd_device_by_node - obtain a validated handle for an MTD device -++ * by of_node -++ * @of_node: OF node of MTD device to open -++ * -++ * This function returns MTD device description structure in case of -++ * success and an error code in case of failure. -++ */ -++struct mtd_info *get_mtd_device_by_node(const struct device_node *of_node) -++{ -++ int err = -ENODEV; -++ struct mtd_info *mtd = NULL, *other; -++ -++ mutex_lock(&mtd_table_mutex); -++ -++ mtd_for_each_device(other) { -++ if (of_node == other->dev.of_node) { -++ mtd = other; -++ break; -++ } -++ } -++ -++ if (!mtd) -++ goto out_unlock; -++ -++ err = __get_mtd_device(mtd); -++ if (err) -++ goto out_unlock; -++ -++ mutex_unlock(&mtd_table_mutex); -++ return mtd; -++ -++out_unlock: -++ mutex_unlock(&mtd_table_mutex); -++ return ERR_PTR(err); -++} -++EXPORT_SYMBOL_GPL(get_mtd_device_by_node); -++ -+ void put_mtd_device(struct mtd_info *mtd) -+ { -+ mutex_lock(&mtd_table_mutex); -+--- a/include/linux/mtd/mtd.h -++++ b/include/linux/mtd/mtd.h -+@@ -580,6 +580,8 @@ extern struct mtd_info *get_mtd_device(s -+ extern int __get_mtd_device(struct mtd_info *mtd); -+ extern void __put_mtd_device(struct mtd_info *mtd); -+ extern struct mtd_info *get_mtd_device_nm(const char *name); -++extern struct mtd_info *get_mtd_device_by_node( -++ const struct device_node *of_node); -+ extern void put_mtd_device(struct mtd_info *mtd); -+ -+ -diff --git a/target/linux/generic/pending-4.14/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch b/target/linux/generic/pending-4.14/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch -new file mode 100644 -index 0000000000..01f3b9ec2d ---- /dev/null -+++ b/target/linux/generic/pending-4.14/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch -@@ -0,0 +1,52 @@ -+From 5734c6669fba7ddb5ef491ccff7159d15dba0b59 Mon Sep 17 00:00:00 2001 -+From: Bernhard Frauendienst -+Date: Wed, 5 Sep 2018 01:32:51 +0200 -+Subject: [PATCH 496/497] dt-bindings: add bindings for mtd-concat devices -+ -+Document virtual mtd-concat device bindings. -+ -+Signed-off-by: Bernhard Frauendienst -+--- -+ .../devicetree/bindings/mtd/mtd-concat.txt | 36 +++++++++++++++++++ -+ 1 file changed, 36 insertions(+) -+ create mode 100644 Documentation/devicetree/bindings/mtd/mtd-concat.txt -+ -+--- /dev/null -++++ b/Documentation/devicetree/bindings/mtd/mtd-concat.txt -+@@ -0,0 +1,36 @@ -++Virtual MTD concat device -++ -++Requires properties: -++- devices: list of phandles to mtd nodes that should be concatenated -++ -++Example: -++ -++&spi { -++ flash0: flash@0 { -++ ... -++ }; -++ flash1: flash@1 { -++ ... -++ }; -++}; -++ -++flash { -++ compatible = "mtd-concat"; -++ -++ devices = <&flash0 &flash1>; -++ -++ partitions { -++ compatible = "fixed-partitions"; -++ -++ partition@0 { -++ label = "boot"; -++ reg = <0x0000000 0x0040000>; -++ read-only; -++ }; -++ -++ partition@40000 { -++ label = "firmware"; -++ reg = <0x0040000 0x1fc0000>; -++ }; -++ } -++} -diff --git a/target/linux/generic/pending-4.14/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch b/target/linux/generic/pending-4.14/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch -new file mode 100644 -index 0000000000..94acc883f3 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch -@@ -0,0 +1,216 @@ -+From e53f712d8eac71f54399b61038ccf87d2cee99d7 Mon Sep 17 00:00:00 2001 -+From: Bernhard Frauendienst -+Date: Sat, 25 Aug 2018 12:35:22 +0200 -+Subject: [PATCH 497/497] mtd: mtdconcat: add dt driver for concat devices -+ -+Some mtd drivers like physmap variants have support for concatenating -+multiple mtd devices, but there is no generic way to define such a -+concat device from within the device tree. -+ -+This is useful for some SoC boards that use multiple flash chips as -+memory banks of a single mtd device, with partitions spanning chip -+borders. -+ -+This commit adds a driver for creating virtual mtd-concat devices. They -+must have a compatible = "mtd-concat" line, and define a list of devices -+to concat in the 'devices' property, for example: -+ -+flash { -+ compatible = "mtd-concat"; -+ -+ devices = <&flash0 &flash1>; -+ -+ partitions { -+ ... -+ }; -+}; -+ -+The driver is added to the very end of the mtd Makefile to increase the -+likelyhood of all child devices already being loaded at the time of -+probing, preventing unnecessary deferred probes. -+ -+Signed-off-by: Bernhard Frauendienst -+--- -+ drivers/mtd/Kconfig | 2 + -+ drivers/mtd/Makefile | 3 + -+ drivers/mtd/composite/Kconfig | 12 +++ -+ drivers/mtd/composite/Makefile | 6 ++ -+ drivers/mtd/composite/virt_concat.c | 128 ++++++++++++++++++++++++++++ -+ 5 files changed, 151 insertions(+) -+ create mode 100644 drivers/mtd/composite/Kconfig -+ create mode 100644 drivers/mtd/composite/Makefile -+ create mode 100644 drivers/mtd/composite/virt_concat.c -+ -+--- a/drivers/mtd/Kconfig -++++ b/drivers/mtd/Kconfig -+@@ -377,4 +377,6 @@ source "drivers/mtd/spi-nor/Kconfig" -+ -+ source "drivers/mtd/ubi/Kconfig" -+ -++source "drivers/mtd/composite/Kconfig" -++ -+ endif # MTD -+--- a/drivers/mtd/Makefile -++++ b/drivers/mtd/Makefile -+@@ -39,3 +39,6 @@ obj-y += chips/ lpddr/ maps/ devices/ n -+ -+ obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ -+ obj-$(CONFIG_MTD_UBI) += ubi/ -++ -++# Composite drivers must be loaded last -++obj-y += composite/ -+--- /dev/null -++++ b/drivers/mtd/composite/Kconfig -+@@ -0,0 +1,12 @@ -++menu "Composite MTD device drivers" -++ depends on MTD!=n -++ -++config MTD_VIRT_CONCAT -++ tristate "Virtual concat MTD device" -++ help -++ This driver allows creation of a virtual MTD concat device, which -++ concatenates multiple underlying MTD devices to a single device. -++ This is required by some SoC boards where multiple memory banks are -++ used as one device with partitions spanning across device boundaries. -++ -++endmenu -+--- /dev/null -++++ b/drivers/mtd/composite/Makefile -+@@ -0,0 +1,6 @@ -++# SPDX-License-Identifier: GPL-2.0 -++# -++# linux/drivers/mtd/composite/Makefile -++# -++ -++obj-$(CONFIG_MTD_VIRT_CONCAT) += virt_concat.o -+--- /dev/null -++++ b/drivers/mtd/composite/virt_concat.c -+@@ -0,0 +1,128 @@ -++// SPDX-License-Identifier: GPL-2.0+ -++/* -++ * Virtual concat MTD device driver -++ * -++ * Copyright (C) 2018 Bernhard Frauendienst -++ * Author: Bernhard Frauendienst, kernel@nospam.obeliks.de -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++/* -++ * struct of_virt_concat - platform device driver data. -++ * @cmtd the final mtd_concat device -++ * @num_devices the number of devices in @devices -++ * @devices points to an array of devices already loaded -++ */ -++struct of_virt_concat { -++ struct mtd_info *cmtd; -++ int num_devices; -++ struct mtd_info **devices; -++}; -++ -++static int virt_concat_remove(struct platform_device *pdev) -++{ -++ struct of_virt_concat *info; -++ int i; -++ -++ info = platform_get_drvdata(pdev); -++ if (!info) -++ return 0; -++ -++ // unset data for when this is called after a probe error -++ platform_set_drvdata(pdev, NULL); -++ -++ if (info->cmtd) { -++ mtd_device_unregister(info->cmtd); -++ mtd_concat_destroy(info->cmtd); -++ } -++ -++ if (info->devices) { -++ for (i = 0; i < info->num_devices; i++) -++ put_mtd_device(info->devices[i]); -++ } -++ -++ return 0; -++} -++ -++static int virt_concat_probe(struct platform_device *pdev) -++{ -++ struct device_node *node = pdev->dev.of_node; -++ struct of_phandle_iterator it; -++ struct of_virt_concat *info; -++ struct mtd_info *mtd; -++ int err = 0, count; -++ -++ count = of_count_phandle_with_args(node, "devices", NULL); -++ if (count <= 0) -++ return -EINVAL; -++ -++ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); -++ if (!info) -++ return -ENOMEM; -++ info->devices = devm_kcalloc(&pdev->dev, count, -++ sizeof(*(info->devices)), GFP_KERNEL); -++ if (!info->devices) { -++ err = -ENOMEM; -++ goto err_remove; -++ } -++ -++ platform_set_drvdata(pdev, info); -++ -++ of_for_each_phandle(&it, err, node, "devices", NULL, 0) { -++ mtd = get_mtd_device_by_node(it.node); -++ if (IS_ERR(mtd)) { -++ of_node_put(it.node); -++ err = -EPROBE_DEFER; -++ goto err_remove; -++ } -++ -++ info->devices[info->num_devices++] = mtd; -++ } -++ -++ info->cmtd = mtd_concat_create(info->devices, info->num_devices, -++ dev_name(&pdev->dev)); -++ if (!info->cmtd) { -++ err = -ENXIO; -++ goto err_remove; -++ } -++ -++ info->cmtd->dev.parent = &pdev->dev; -++ mtd_set_of_node(info->cmtd, node); -++ mtd_device_register(info->cmtd, NULL, 0); -++ -++ return 0; -++ -++err_remove: -++ virt_concat_remove(pdev); -++ -++ return err; -++} -++ -++static const struct of_device_id virt_concat_of_match[] = { -++ { .compatible = "mtd-concat", }, -++ { /* sentinel */ } -++}; -++MODULE_DEVICE_TABLE(of, virt_concat_of_match); -++ -++static struct platform_driver virt_concat_driver = { -++ .probe = virt_concat_probe, -++ .remove = virt_concat_remove, -++ .driver = { -++ .name = "virt-mtdconcat", -++ .of_match_table = virt_concat_of_match, -++ }, -++}; -++ -++module_platform_driver(virt_concat_driver); -++ -++MODULE_LICENSE("GPL v2"); -++MODULE_AUTHOR("Bernhard Frauendienst "); -++MODULE_DESCRIPTION("Virtual concat MTD device driver"); -diff --git a/target/linux/generic/pending-4.14/530-jffs2_make_lzma_available.patch b/target/linux/generic/pending-4.14/530-jffs2_make_lzma_available.patch -new file mode 100644 -index 0000000000..e74a6a11ed ---- /dev/null -+++ b/target/linux/generic/pending-4.14/530-jffs2_make_lzma_available.patch -@@ -0,0 +1,5180 @@ -+From: Alexandros C. Couloumbis -+Subject: fs: add jffs2/lzma support (not activated by default yet) -+ -+lede-commit: c2c88d315fa0e881f8b19da07b62859b915b11b2 -+Signed-off-by: Alexandros C. Couloumbis -+--- -+ fs/jffs2/Kconfig | 9 + -+ fs/jffs2/Makefile | 3 + -+ fs/jffs2/compr.c | 6 + -+ fs/jffs2/compr.h | 10 +- -+ fs/jffs2/compr_lzma.c | 128 +++ -+ fs/jffs2/super.c | 33 +- -+ include/linux/lzma.h | 62 ++ -+ include/linux/lzma/LzFind.h | 115 +++ -+ include/linux/lzma/LzHash.h | 54 + -+ include/linux/lzma/LzmaDec.h | 231 +++++ -+ include/linux/lzma/LzmaEnc.h | 80 ++ -+ include/linux/lzma/Types.h | 226 +++++ -+ include/uapi/linux/jffs2.h | 1 + -+ lib/Kconfig | 6 + -+ lib/Makefile | 12 + -+ lib/lzma/LzFind.c | 761 ++++++++++++++ -+ lib/lzma/LzmaDec.c | 999 +++++++++++++++++++ -+ lib/lzma/LzmaEnc.c | 2271 ++++++++++++++++++++++++++++++++++++++++++ -+ lib/lzma/Makefile | 7 + -+ 19 files changed, 5008 insertions(+), 6 deletions(-) -+ create mode 100644 fs/jffs2/compr_lzma.c -+ create mode 100644 include/linux/lzma.h -+ create mode 100644 include/linux/lzma/LzFind.h -+ create mode 100644 include/linux/lzma/LzHash.h -+ create mode 100644 include/linux/lzma/LzmaDec.h -+ create mode 100644 include/linux/lzma/LzmaEnc.h -+ create mode 100644 include/linux/lzma/Types.h -+ create mode 100644 lib/lzma/LzFind.c -+ create mode 100644 lib/lzma/LzmaDec.c -+ create mode 100644 lib/lzma/LzmaEnc.c -+ create mode 100644 lib/lzma/Makefile -+ -+--- a/fs/jffs2/Kconfig -++++ b/fs/jffs2/Kconfig -+@@ -139,6 +139,15 @@ config JFFS2_LZO -+ This feature was added in July, 2007. Say 'N' if you need -+ compatibility with older bootloaders or kernels. -+ -++config JFFS2_LZMA -++ bool "JFFS2 LZMA compression support" if JFFS2_COMPRESSION_OPTIONS -++ select LZMA_COMPRESS -++ select LZMA_DECOMPRESS -++ depends on JFFS2_FS -++ default n -++ help -++ JFFS2 wrapper to the LZMA C SDK -++ -+ config JFFS2_RTIME -+ bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS -+ depends on JFFS2_FS -+--- a/fs/jffs2/Makefile -++++ b/fs/jffs2/Makefile -+@@ -19,4 +19,7 @@ jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rub -+ jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o -+ jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o -+ jffs2-$(CONFIG_JFFS2_LZO) += compr_lzo.o -++jffs2-$(CONFIG_JFFS2_LZMA) += compr_lzma.o -+ jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o -++ -++CFLAGS_compr_lzma.o += -Iinclude/linux -Ilib/lzma -+--- a/fs/jffs2/compr.c -++++ b/fs/jffs2/compr.c -+@@ -378,6 +378,9 @@ int __init jffs2_compressors_init(void) -+ #ifdef CONFIG_JFFS2_LZO -+ jffs2_lzo_init(); -+ #endif -++#ifdef CONFIG_JFFS2_LZMA -++ jffs2_lzma_init(); -++#endif -+ /* Setting default compression mode */ -+ #ifdef CONFIG_JFFS2_CMODE_NONE -+ jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; -+@@ -401,6 +404,9 @@ int __init jffs2_compressors_init(void) -+ int jffs2_compressors_exit(void) -+ { -+ /* Unregistering compressors */ -++#ifdef CONFIG_JFFS2_LZMA -++ jffs2_lzma_exit(); -++#endif -+ #ifdef CONFIG_JFFS2_LZO -+ jffs2_lzo_exit(); -+ #endif -+--- a/fs/jffs2/compr.h -++++ b/fs/jffs2/compr.h -+@@ -29,9 +29,9 @@ -+ #define JFFS2_DYNRUBIN_PRIORITY 20 -+ #define JFFS2_LZARI_PRIORITY 30 -+ #define JFFS2_RTIME_PRIORITY 50 -+-#define JFFS2_ZLIB_PRIORITY 60 -+-#define JFFS2_LZO_PRIORITY 80 -+- -++#define JFFS2_LZMA_PRIORITY 70 -++#define JFFS2_ZLIB_PRIORITY 80 -++#define JFFS2_LZO_PRIORITY 90 -+ -+ #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */ -+ #define JFFS2_DYNRUBIN_DISABLED /* for decompression */ -+@@ -101,5 +101,9 @@ void jffs2_zlib_exit(void); -+ int jffs2_lzo_init(void); -+ void jffs2_lzo_exit(void); -+ #endif -++#ifdef CONFIG_JFFS2_LZMA -++int jffs2_lzma_init(void); -++void jffs2_lzma_exit(void); -++#endif -+ -+ #endif /* __JFFS2_COMPR_H__ */ -+--- /dev/null -++++ b/fs/jffs2/compr_lzma.c -+@@ -0,0 +1,128 @@ -++/* -++ * JFFS2 -- Journalling Flash File System, Version 2. -++ * -++ * For licensing information, see the file 'LICENCE' in this directory. -++ * -++ * JFFS2 wrapper to the LZMA C SDK -++ * -++ */ -++ -++#include -++#include "compr.h" -++ -++#ifdef __KERNEL__ -++ static DEFINE_MUTEX(deflate_mutex); -++#endif -++ -++CLzmaEncHandle *p; -++Byte propsEncoded[LZMA_PROPS_SIZE]; -++SizeT propsSize = sizeof(propsEncoded); -++ -++STATIC void lzma_free_workspace(void) -++{ -++ LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc); -++} -++ -++STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props) -++{ -++ if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL) -++ { -++ PRINT_ERROR("Failed to allocate lzma deflate workspace\n"); -++ return -ENOMEM; -++ } -++ -++ if (LzmaEnc_SetProps(p, props) != SZ_OK) -++ { -++ lzma_free_workspace(); -++ return -1; -++ } -++ -++ if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK) -++ { -++ lzma_free_workspace(); -++ return -1; -++ } -++ -++ return 0; -++} -++ -++STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out, -++ uint32_t *sourcelen, uint32_t *dstlen) -++{ -++ SizeT compress_size = (SizeT)(*dstlen); -++ int ret; -++ -++ #ifdef __KERNEL__ -++ mutex_lock(&deflate_mutex); -++ #endif -++ -++ ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen, -++ 0, NULL, &lzma_alloc, &lzma_alloc); -++ -++ #ifdef __KERNEL__ -++ mutex_unlock(&deflate_mutex); -++ #endif -++ -++ if (ret != SZ_OK) -++ return -1; -++ -++ *dstlen = (uint32_t)compress_size; -++ -++ return 0; -++} -++ -++STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out, -++ uint32_t srclen, uint32_t destlen) -++{ -++ int ret; -++ SizeT dl = (SizeT)destlen; -++ SizeT sl = (SizeT)srclen; -++ ELzmaStatus status; -++ -++ ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded, -++ propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc); -++ -++ if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen) -++ return -1; -++ -++ return 0; -++} -++ -++static struct jffs2_compressor jffs2_lzma_comp = { -++ .priority = JFFS2_LZMA_PRIORITY, -++ .name = "lzma", -++ .compr = JFFS2_COMPR_LZMA, -++ .compress = &jffs2_lzma_compress, -++ .decompress = &jffs2_lzma_decompress, -++ .disabled = 0, -++}; -++ -++int INIT jffs2_lzma_init(void) -++{ -++ int ret; -++ CLzmaEncProps props; -++ LzmaEncProps_Init(&props); -++ -++ props.dictSize = LZMA_BEST_DICT(0x2000); -++ props.level = LZMA_BEST_LEVEL; -++ props.lc = LZMA_BEST_LC; -++ props.lp = LZMA_BEST_LP; -++ props.pb = LZMA_BEST_PB; -++ props.fb = LZMA_BEST_FB; -++ -++ ret = lzma_alloc_workspace(&props); -++ if (ret < 0) -++ return ret; -++ -++ ret = jffs2_register_compressor(&jffs2_lzma_comp); -++ if (ret) -++ lzma_free_workspace(); -++ -++ return ret; -++} -++ -++void jffs2_lzma_exit(void) -++{ -++ jffs2_unregister_compressor(&jffs2_lzma_comp); -++ lzma_free_workspace(); -++} -+--- a/fs/jffs2/super.c -++++ b/fs/jffs2/super.c -+@@ -374,14 +374,41 @@ static int __init init_jffs2_fs(void) -+ BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68); -+ BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32); -+ -+- pr_info("version 2.2." -++ pr_info("version 2.2" -+ #ifdef CONFIG_JFFS2_FS_WRITEBUFFER -+ " (NAND)" -+ #endif -+ #ifdef CONFIG_JFFS2_SUMMARY -+- " (SUMMARY) " -++ " (SUMMARY)" -+ #endif -+- " © 2001-2006 Red Hat, Inc.\n"); -++#ifdef CONFIG_JFFS2_ZLIB -++ " (ZLIB)" -++#endif -++#ifdef CONFIG_JFFS2_LZO -++ " (LZO)" -++#endif -++#ifdef CONFIG_JFFS2_LZMA -++ " (LZMA)" -++#endif -++#ifdef CONFIG_JFFS2_RTIME -++ " (RTIME)" -++#endif -++#ifdef CONFIG_JFFS2_RUBIN -++ " (RUBIN)" -++#endif -++#ifdef CONFIG_JFFS2_CMODE_NONE -++ " (CMODE_NONE)" -++#endif -++#ifdef CONFIG_JFFS2_CMODE_PRIORITY -++ " (CMODE_PRIORITY)" -++#endif -++#ifdef CONFIG_JFFS2_CMODE_SIZE -++ " (CMODE_SIZE)" -++#endif -++#ifdef CONFIG_JFFS2_CMODE_FAVOURLZO -++ " (CMODE_FAVOURLZO)" -++#endif -++ " (c) 2001-2006 Red Hat, Inc.\n"); -+ -+ jffs2_inode_cachep = kmem_cache_create("jffs2_i", -+ sizeof(struct jffs2_inode_info), -+--- /dev/null -++++ b/include/linux/lzma.h -+@@ -0,0 +1,62 @@ -++#ifndef __LZMA_H__ -++#define __LZMA_H__ -++ -++#ifdef __KERNEL__ -++ #include -++ #include -++ #include -++ #include -++ #include -++ #define LZMA_MALLOC vmalloc -++ #define LZMA_FREE vfree -++ #define PRINT_ERROR(msg) printk(KERN_WARNING #msg) -++ #define INIT __init -++ #define STATIC static -++#else -++ #include -++ #include -++ #include -++ #include -++ #include -++ #include -++ #include -++ #include -++ #ifndef PAGE_SIZE -++ extern int page_size; -++ #define PAGE_SIZE page_size -++ #endif -++ #define LZMA_MALLOC malloc -++ #define LZMA_FREE free -++ #define PRINT_ERROR(msg) fprintf(stderr, msg) -++ #define INIT -++ #define STATIC -++#endif -++ -++#include "lzma/LzmaDec.h" -++#include "lzma/LzmaEnc.h" -++ -++#define LZMA_BEST_LEVEL (9) -++#define LZMA_BEST_LC (0) -++#define LZMA_BEST_LP (0) -++#define LZMA_BEST_PB (0) -++#define LZMA_BEST_FB (273) -++ -++#define LZMA_BEST_DICT(n) (((int)((n) / 2)) * 2) -++ -++static void *p_lzma_malloc(void *p, size_t size) -++{ -++ if (size == 0) -++ return NULL; -++ -++ return LZMA_MALLOC(size); -++} -++ -++static void p_lzma_free(void *p, void *address) -++{ -++ if (address != NULL) -++ LZMA_FREE(address); -++} -++ -++static ISzAlloc lzma_alloc = {p_lzma_malloc, p_lzma_free}; -++ -++#endif -+--- /dev/null -++++ b/include/linux/lzma/LzFind.h -+@@ -0,0 +1,115 @@ -++/* LzFind.h -- Match finder for LZ algorithms -++2009-04-22 : Igor Pavlov : Public domain */ -++ -++#ifndef __LZ_FIND_H -++#define __LZ_FIND_H -++ -++#include "Types.h" -++ -++#ifdef __cplusplus -++extern "C" { -++#endif -++ -++typedef UInt32 CLzRef; -++ -++typedef struct _CMatchFinder -++{ -++ Byte *buffer; -++ UInt32 pos; -++ UInt32 posLimit; -++ UInt32 streamPos; -++ UInt32 lenLimit; -++ -++ UInt32 cyclicBufferPos; -++ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ -++ -++ UInt32 matchMaxLen; -++ CLzRef *hash; -++ CLzRef *son; -++ UInt32 hashMask; -++ UInt32 cutValue; -++ -++ Byte *bufferBase; -++ ISeqInStream *stream; -++ int streamEndWasReached; -++ -++ UInt32 blockSize; -++ UInt32 keepSizeBefore; -++ UInt32 keepSizeAfter; -++ -++ UInt32 numHashBytes; -++ int directInput; -++ size_t directInputRem; -++ int btMode; -++ int bigHash; -++ UInt32 historySize; -++ UInt32 fixedHashSize; -++ UInt32 hashSizeSum; -++ UInt32 numSons; -++ SRes result; -++ UInt32 crc[256]; -++} CMatchFinder; -++ -++#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) -++#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) -++ -++#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) -++ -++int MatchFinder_NeedMove(CMatchFinder *p); -++Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); -++void MatchFinder_MoveBlock(CMatchFinder *p); -++void MatchFinder_ReadIfRequired(CMatchFinder *p); -++ -++void MatchFinder_Construct(CMatchFinder *p); -++ -++/* Conditions: -++ historySize <= 3 GB -++ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB -++*/ -++int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, -++ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, -++ ISzAlloc *alloc); -++void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); -++void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); -++void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); -++ -++UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, -++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, -++ UInt32 *distances, UInt32 maxLen); -++ -++/* -++Conditions: -++ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. -++ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function -++*/ -++ -++typedef void (*Mf_Init_Func)(void *object); -++typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); -++typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); -++typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); -++typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); -++typedef void (*Mf_Skip_Func)(void *object, UInt32); -++ -++typedef struct _IMatchFinder -++{ -++ Mf_Init_Func Init; -++ Mf_GetIndexByte_Func GetIndexByte; -++ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; -++ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; -++ Mf_GetMatches_Func GetMatches; -++ Mf_Skip_Func Skip; -++} IMatchFinder; -++ -++void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); -++ -++void MatchFinder_Init(CMatchFinder *p); -++UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -++UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -++void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -++void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -++ -++#ifdef __cplusplus -++} -++#endif -++ -++#endif -+--- /dev/null -++++ b/include/linux/lzma/LzHash.h -+@@ -0,0 +1,54 @@ -++/* LzHash.h -- HASH functions for LZ algorithms -++2009-02-07 : Igor Pavlov : Public domain */ -++ -++#ifndef __LZ_HASH_H -++#define __LZ_HASH_H -++ -++#define kHash2Size (1 << 10) -++#define kHash3Size (1 << 16) -++#define kHash4Size (1 << 20) -++ -++#define kFix3HashSize (kHash2Size) -++#define kFix4HashSize (kHash2Size + kHash3Size) -++#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) -++ -++#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); -++ -++#define HASH3_CALC { \ -++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -++ hash2Value = temp & (kHash2Size - 1); \ -++ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } -++ -++#define HASH4_CALC { \ -++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -++ hash2Value = temp & (kHash2Size - 1); \ -++ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -++ hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } -++ -++#define HASH5_CALC { \ -++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -++ hash2Value = temp & (kHash2Size - 1); \ -++ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -++ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ -++ hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ -++ hash4Value &= (kHash4Size - 1); } -++ -++/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ -++#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; -++ -++ -++#define MT_HASH2_CALC \ -++ hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); -++ -++#define MT_HASH3_CALC { \ -++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -++ hash2Value = temp & (kHash2Size - 1); \ -++ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } -++ -++#define MT_HASH4_CALC { \ -++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -++ hash2Value = temp & (kHash2Size - 1); \ -++ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -++ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } -++ -++#endif -+--- /dev/null -++++ b/include/linux/lzma/LzmaDec.h -+@@ -0,0 +1,231 @@ -++/* LzmaDec.h -- LZMA Decoder -++2009-02-07 : Igor Pavlov : Public domain */ -++ -++#ifndef __LZMA_DEC_H -++#define __LZMA_DEC_H -++ -++#include "Types.h" -++ -++#ifdef __cplusplus -++extern "C" { -++#endif -++ -++/* #define _LZMA_PROB32 */ -++/* _LZMA_PROB32 can increase the speed on some CPUs, -++ but memory usage for CLzmaDec::probs will be doubled in that case */ -++ -++#ifdef _LZMA_PROB32 -++#define CLzmaProb UInt32 -++#else -++#define CLzmaProb UInt16 -++#endif -++ -++ -++/* ---------- LZMA Properties ---------- */ -++ -++#define LZMA_PROPS_SIZE 5 -++ -++typedef struct _CLzmaProps -++{ -++ unsigned lc, lp, pb; -++ UInt32 dicSize; -++} CLzmaProps; -++ -++/* LzmaProps_Decode - decodes properties -++Returns: -++ SZ_OK -++ SZ_ERROR_UNSUPPORTED - Unsupported properties -++*/ -++ -++SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); -++ -++ -++/* ---------- LZMA Decoder state ---------- */ -++ -++/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. -++ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ -++ -++#define LZMA_REQUIRED_INPUT_MAX 20 -++ -++typedef struct -++{ -++ CLzmaProps prop; -++ CLzmaProb *probs; -++ Byte *dic; -++ const Byte *buf; -++ UInt32 range, code; -++ SizeT dicPos; -++ SizeT dicBufSize; -++ UInt32 processedPos; -++ UInt32 checkDicSize; -++ unsigned state; -++ UInt32 reps[4]; -++ unsigned remainLen; -++ int needFlush; -++ int needInitState; -++ UInt32 numProbs; -++ unsigned tempBufSize; -++ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; -++} CLzmaDec; -++ -++#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } -++ -++void LzmaDec_Init(CLzmaDec *p); -++ -++/* There are two types of LZMA streams: -++ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. -++ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ -++ -++typedef enum -++{ -++ LZMA_FINISH_ANY, /* finish at any point */ -++ LZMA_FINISH_END /* block must be finished at the end */ -++} ELzmaFinishMode; -++ -++/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! -++ -++ You must use LZMA_FINISH_END, when you know that current output buffer -++ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. -++ -++ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, -++ and output value of destLen will be less than output buffer size limit. -++ You can check status result also. -++ -++ You can use multiple checks to test data integrity after full decompression: -++ 1) Check Result and "status" variable. -++ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. -++ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. -++ You must use correct finish mode in that case. */ -++ -++typedef enum -++{ -++ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ -++ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ -++ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ -++ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ -++ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ -++} ELzmaStatus; -++ -++/* ELzmaStatus is used only as output value for function call */ -++ -++ -++/* ---------- Interfaces ---------- */ -++ -++/* There are 3 levels of interfaces: -++ 1) Dictionary Interface -++ 2) Buffer Interface -++ 3) One Call Interface -++ You can select any of these interfaces, but don't mix functions from different -++ groups for same object. */ -++ -++ -++/* There are two variants to allocate state for Dictionary Interface: -++ 1) LzmaDec_Allocate / LzmaDec_Free -++ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs -++ You can use variant 2, if you set dictionary buffer manually. -++ For Buffer Interface you must always use variant 1. -++ -++LzmaDec_Allocate* can return: -++ SZ_OK -++ SZ_ERROR_MEM - Memory allocation error -++ SZ_ERROR_UNSUPPORTED - Unsupported properties -++*/ -++ -++SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); -++void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); -++ -++SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); -++void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); -++ -++/* ---------- Dictionary Interface ---------- */ -++ -++/* You can use it, if you want to eliminate the overhead for data copying from -++ dictionary to some other external buffer. -++ You must work with CLzmaDec variables directly in this interface. -++ -++ STEPS: -++ LzmaDec_Constr() -++ LzmaDec_Allocate() -++ for (each new stream) -++ { -++ LzmaDec_Init() -++ while (it needs more decompression) -++ { -++ LzmaDec_DecodeToDic() -++ use data from CLzmaDec::dic and update CLzmaDec::dicPos -++ } -++ } -++ LzmaDec_Free() -++*/ -++ -++/* LzmaDec_DecodeToDic -++ -++ The decoding to internal dictionary buffer (CLzmaDec::dic). -++ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! -++ -++finishMode: -++ It has meaning only if the decoding reaches output limit (dicLimit). -++ LZMA_FINISH_ANY - Decode just dicLimit bytes. -++ LZMA_FINISH_END - Stream must be finished after dicLimit. -++ -++Returns: -++ SZ_OK -++ status: -++ LZMA_STATUS_FINISHED_WITH_MARK -++ LZMA_STATUS_NOT_FINISHED -++ LZMA_STATUS_NEEDS_MORE_INPUT -++ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK -++ SZ_ERROR_DATA - Data error -++*/ -++ -++SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, -++ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); -++ -++ -++/* ---------- Buffer Interface ---------- */ -++ -++/* It's zlib-like interface. -++ See LzmaDec_DecodeToDic description for information about STEPS and return results, -++ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need -++ to work with CLzmaDec variables manually. -++ -++finishMode: -++ It has meaning only if the decoding reaches output limit (*destLen). -++ LZMA_FINISH_ANY - Decode just destLen bytes. -++ LZMA_FINISH_END - Stream must be finished after (*destLen). -++*/ -++ -++SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, -++ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); -++ -++ -++/* ---------- One Call Interface ---------- */ -++ -++/* LzmaDecode -++ -++finishMode: -++ It has meaning only if the decoding reaches output limit (*destLen). -++ LZMA_FINISH_ANY - Decode just destLen bytes. -++ LZMA_FINISH_END - Stream must be finished after (*destLen). -++ -++Returns: -++ SZ_OK -++ status: -++ LZMA_STATUS_FINISHED_WITH_MARK -++ LZMA_STATUS_NOT_FINISHED -++ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK -++ SZ_ERROR_DATA - Data error -++ SZ_ERROR_MEM - Memory allocation error -++ SZ_ERROR_UNSUPPORTED - Unsupported properties -++ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). -++*/ -++ -++SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, -++ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, -++ ELzmaStatus *status, ISzAlloc *alloc); -++ -++#ifdef __cplusplus -++} -++#endif -++ -++#endif -+--- /dev/null -++++ b/include/linux/lzma/LzmaEnc.h -+@@ -0,0 +1,80 @@ -++/* LzmaEnc.h -- LZMA Encoder -++2009-02-07 : Igor Pavlov : Public domain */ -++ -++#ifndef __LZMA_ENC_H -++#define __LZMA_ENC_H -++ -++#include "Types.h" -++ -++#ifdef __cplusplus -++extern "C" { -++#endif -++ -++#define LZMA_PROPS_SIZE 5 -++ -++typedef struct _CLzmaEncProps -++{ -++ int level; /* 0 <= level <= 9 */ -++ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version -++ (1 << 12) <= dictSize <= (1 << 30) for 64-bit version -++ default = (1 << 24) */ -++ int lc; /* 0 <= lc <= 8, default = 3 */ -++ int lp; /* 0 <= lp <= 4, default = 0 */ -++ int pb; /* 0 <= pb <= 4, default = 2 */ -++ int algo; /* 0 - fast, 1 - normal, default = 1 */ -++ int fb; /* 5 <= fb <= 273, default = 32 */ -++ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ -++ int numHashBytes; /* 2, 3 or 4, default = 4 */ -++ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ -++ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ -++ int numThreads; /* 1 or 2, default = 2 */ -++} CLzmaEncProps; -++ -++void LzmaEncProps_Init(CLzmaEncProps *p); -++void LzmaEncProps_Normalize(CLzmaEncProps *p); -++UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); -++ -++ -++/* ---------- CLzmaEncHandle Interface ---------- */ -++ -++/* LzmaEnc_* functions can return the following exit codes: -++Returns: -++ SZ_OK - OK -++ SZ_ERROR_MEM - Memory allocation error -++ SZ_ERROR_PARAM - Incorrect paramater in props -++ SZ_ERROR_WRITE - Write callback error. -++ SZ_ERROR_PROGRESS - some break from progress callback -++ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -++*/ -++ -++typedef void * CLzmaEncHandle; -++ -++CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); -++void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); -++SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); -++SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); -++SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, -++ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -++SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -++ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -++ -++/* ---------- One Call Interface ---------- */ -++ -++/* LzmaEncode -++Return code: -++ SZ_OK - OK -++ SZ_ERROR_MEM - Memory allocation error -++ SZ_ERROR_PARAM - Incorrect paramater -++ SZ_ERROR_OUTPUT_EOF - output buffer overflow -++ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -++*/ -++ -++SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -++ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, -++ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -++ -++#ifdef __cplusplus -++} -++#endif -++ -++#endif -+--- /dev/null -++++ b/include/linux/lzma/Types.h -+@@ -0,0 +1,226 @@ -++/* Types.h -- Basic types -++2009-11-23 : Igor Pavlov : Public domain */ -++ -++#ifndef __7Z_TYPES_H -++#define __7Z_TYPES_H -++ -++#include -++ -++#ifdef _WIN32 -++#include -++#endif -++ -++#ifndef EXTERN_C_BEGIN -++#ifdef __cplusplus -++#define EXTERN_C_BEGIN extern "C" { -++#define EXTERN_C_END } -++#else -++#define EXTERN_C_BEGIN -++#define EXTERN_C_END -++#endif -++#endif -++ -++EXTERN_C_BEGIN -++ -++#define SZ_OK 0 -++ -++#define SZ_ERROR_DATA 1 -++#define SZ_ERROR_MEM 2 -++#define SZ_ERROR_CRC 3 -++#define SZ_ERROR_UNSUPPORTED 4 -++#define SZ_ERROR_PARAM 5 -++#define SZ_ERROR_INPUT_EOF 6 -++#define SZ_ERROR_OUTPUT_EOF 7 -++#define SZ_ERROR_READ 8 -++#define SZ_ERROR_WRITE 9 -++#define SZ_ERROR_PROGRESS 10 -++#define SZ_ERROR_FAIL 11 -++#define SZ_ERROR_THREAD 12 -++ -++#define SZ_ERROR_ARCHIVE 16 -++#define SZ_ERROR_NO_ARCHIVE 17 -++ -++typedef int SRes; -++ -++#ifdef _WIN32 -++typedef DWORD WRes; -++#else -++typedef int WRes; -++#endif -++ -++#ifndef RINOK -++#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } -++#endif -++ -++typedef unsigned char Byte; -++typedef short Int16; -++typedef unsigned short UInt16; -++ -++#ifdef _LZMA_UINT32_IS_ULONG -++typedef long Int32; -++typedef unsigned long UInt32; -++#else -++typedef int Int32; -++typedef unsigned int UInt32; -++#endif -++ -++#ifdef _SZ_NO_INT_64 -++ -++/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. -++ NOTES: Some code will work incorrectly in that case! */ -++ -++typedef long Int64; -++typedef unsigned long UInt64; -++ -++#else -++ -++#if defined(_MSC_VER) || defined(__BORLANDC__) -++typedef __int64 Int64; -++typedef unsigned __int64 UInt64; -++#else -++typedef long long int Int64; -++typedef unsigned long long int UInt64; -++#endif -++ -++#endif -++ -++#ifdef _LZMA_NO_SYSTEM_SIZE_T -++typedef UInt32 SizeT; -++#else -++typedef size_t SizeT; -++#endif -++ -++typedef int Bool; -++#define True 1 -++#define False 0 -++ -++ -++#ifdef _WIN32 -++#define MY_STD_CALL __stdcall -++#else -++#define MY_STD_CALL -++#endif -++ -++#ifdef _MSC_VER -++ -++#if _MSC_VER >= 1300 -++#define MY_NO_INLINE __declspec(noinline) -++#else -++#define MY_NO_INLINE -++#endif -++ -++#define MY_CDECL __cdecl -++#define MY_FAST_CALL __fastcall -++ -++#else -++ -++#define MY_CDECL -++#define MY_FAST_CALL -++ -++#endif -++ -++ -++/* The following interfaces use first parameter as pointer to structure */ -++ -++typedef struct -++{ -++ SRes (*Read)(void *p, void *buf, size_t *size); -++ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. -++ (output(*size) < input(*size)) is allowed */ -++} ISeqInStream; -++ -++/* it can return SZ_ERROR_INPUT_EOF */ -++SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); -++SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); -++SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); -++ -++typedef struct -++{ -++ size_t (*Write)(void *p, const void *buf, size_t size); -++ /* Returns: result - the number of actually written bytes. -++ (result < size) means error */ -++} ISeqOutStream; -++ -++typedef enum -++{ -++ SZ_SEEK_SET = 0, -++ SZ_SEEK_CUR = 1, -++ SZ_SEEK_END = 2 -++} ESzSeek; -++ -++typedef struct -++{ -++ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ -++ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -++} ISeekInStream; -++ -++typedef struct -++{ -++ SRes (*Look)(void *p, void **buf, size_t *size); -++ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. -++ (output(*size) > input(*size)) is not allowed -++ (output(*size) < input(*size)) is allowed */ -++ SRes (*Skip)(void *p, size_t offset); -++ /* offset must be <= output(*size) of Look */ -++ -++ SRes (*Read)(void *p, void *buf, size_t *size); -++ /* reads directly (without buffer). It's same as ISeqInStream::Read */ -++ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -++} ILookInStream; -++ -++SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); -++SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); -++ -++/* reads via ILookInStream::Read */ -++SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); -++SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); -++ -++#define LookToRead_BUF_SIZE (1 << 14) -++ -++typedef struct -++{ -++ ILookInStream s; -++ ISeekInStream *realStream; -++ size_t pos; -++ size_t size; -++ Byte buf[LookToRead_BUF_SIZE]; -++} CLookToRead; -++ -++void LookToRead_CreateVTable(CLookToRead *p, int lookahead); -++void LookToRead_Init(CLookToRead *p); -++ -++typedef struct -++{ -++ ISeqInStream s; -++ ILookInStream *realStream; -++} CSecToLook; -++ -++void SecToLook_CreateVTable(CSecToLook *p); -++ -++typedef struct -++{ -++ ISeqInStream s; -++ ILookInStream *realStream; -++} CSecToRead; -++ -++void SecToRead_CreateVTable(CSecToRead *p); -++ -++typedef struct -++{ -++ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); -++ /* Returns: result. (result != SZ_OK) means break. -++ Value (UInt64)(Int64)-1 for size means unknown value. */ -++} ICompressProgress; -++ -++typedef struct -++{ -++ void *(*Alloc)(void *p, size_t size); -++ void (*Free)(void *p, void *address); /* address can be 0 */ -++} ISzAlloc; -++ -++#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) -++#define IAlloc_Free(p, a) (p)->Free((p), a) -++ -++EXTERN_C_END -++ -++#endif -+--- a/include/uapi/linux/jffs2.h -++++ b/include/uapi/linux/jffs2.h -+@@ -46,6 +46,7 @@ -+ #define JFFS2_COMPR_DYNRUBIN 0x05 -+ #define JFFS2_COMPR_ZLIB 0x06 -+ #define JFFS2_COMPR_LZO 0x07 -++#define JFFS2_COMPR_LZMA 0x08 -+ /* Compatibility flags. */ -+ #define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ -+ #define JFFS2_NODE_ACCURATE 0x2000 -+--- a/lib/Kconfig -++++ b/lib/Kconfig -+@@ -259,6 +259,12 @@ config ZSTD_DECOMPRESS -+ -+ source "lib/xz/Kconfig" -+ -++config LZMA_COMPRESS -++ tristate -++ -++config LZMA_DECOMPRESS -++ tristate -++ -+ # -+ # These all provide a common interface (hence the apparent duplication with -+ # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.) -+--- a/lib/Makefile -++++ b/lib/Makefile -+@@ -3,6 +3,16 @@ -+ # Makefile for some libs needed in the kernel. -+ # -+ -++ifdef CONFIG_JFFS2_ZLIB -++ CONFIG_ZLIB_INFLATE:=y -++ CONFIG_ZLIB_DEFLATE:=y -++endif -++ -++ifdef CONFIG_JFFS2_LZMA -++ CONFIG_LZMA_DECOMPRESS:=y -++ CONFIG_LZMA_COMPRESS:=y -++endif -++ -+ ifdef CONFIG_FUNCTION_TRACER -+ ORIG_CFLAGS := $(KBUILD_CFLAGS) -+ KBUILD_CFLAGS = $(subst $(CC_FLAGS_FTRACE),,$(ORIG_CFLAGS)) -+@@ -134,6 +144,8 @@ obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ -+ obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/ -+ obj-$(CONFIG_XZ_DEC) += xz/ -+ obj-$(CONFIG_RAID6_PQ) += raid6/ -++obj-$(CONFIG_LZMA_COMPRESS) += lzma/ -++obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/ -+ -+ lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o -+ lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o -+--- /dev/null -++++ b/lib/lzma/LzFind.c -+@@ -0,0 +1,761 @@ -++/* LzFind.c -- Match finder for LZ algorithms -++2009-04-22 : Igor Pavlov : Public domain */ -++ -++#include -++ -++#include "LzFind.h" -++#include "LzHash.h" -++ -++#define kEmptyHashValue 0 -++#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) -++#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ -++#define kNormalizeMask (~(kNormalizeStepMin - 1)) -++#define kMaxHistorySize ((UInt32)3 << 30) -++ -++#define kStartMaxLen 3 -++ -++static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) -++{ -++ if (!p->directInput) -++ { -++ alloc->Free(alloc, p->bufferBase); -++ p->bufferBase = 0; -++ } -++} -++ -++/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ -++ -++static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) -++{ -++ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; -++ if (p->directInput) -++ { -++ p->blockSize = blockSize; -++ return 1; -++ } -++ if (p->bufferBase == 0 || p->blockSize != blockSize) -++ { -++ LzInWindow_Free(p, alloc); -++ p->blockSize = blockSize; -++ p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); -++ } -++ return (p->bufferBase != 0); -++} -++ -++Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } -++Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } -++ -++UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } -++ -++void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) -++{ -++ p->posLimit -= subValue; -++ p->pos -= subValue; -++ p->streamPos -= subValue; -++} -++ -++static void MatchFinder_ReadBlock(CMatchFinder *p) -++{ -++ if (p->streamEndWasReached || p->result != SZ_OK) -++ return; -++ if (p->directInput) -++ { -++ UInt32 curSize = 0xFFFFFFFF - p->streamPos; -++ if (curSize > p->directInputRem) -++ curSize = (UInt32)p->directInputRem; -++ p->directInputRem -= curSize; -++ p->streamPos += curSize; -++ if (p->directInputRem == 0) -++ p->streamEndWasReached = 1; -++ return; -++ } -++ for (;;) -++ { -++ Byte *dest = p->buffer + (p->streamPos - p->pos); -++ size_t size = (p->bufferBase + p->blockSize - dest); -++ if (size == 0) -++ return; -++ p->result = p->stream->Read(p->stream, dest, &size); -++ if (p->result != SZ_OK) -++ return; -++ if (size == 0) -++ { -++ p->streamEndWasReached = 1; -++ return; -++ } -++ p->streamPos += (UInt32)size; -++ if (p->streamPos - p->pos > p->keepSizeAfter) -++ return; -++ } -++} -++ -++void MatchFinder_MoveBlock(CMatchFinder *p) -++{ -++ memmove(p->bufferBase, -++ p->buffer - p->keepSizeBefore, -++ (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); -++ p->buffer = p->bufferBase + p->keepSizeBefore; -++} -++ -++int MatchFinder_NeedMove(CMatchFinder *p) -++{ -++ if (p->directInput) -++ return 0; -++ /* if (p->streamEndWasReached) return 0; */ -++ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); -++} -++ -++void MatchFinder_ReadIfRequired(CMatchFinder *p) -++{ -++ if (p->streamEndWasReached) -++ return; -++ if (p->keepSizeAfter >= p->streamPos - p->pos) -++ MatchFinder_ReadBlock(p); -++} -++ -++static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) -++{ -++ if (MatchFinder_NeedMove(p)) -++ MatchFinder_MoveBlock(p); -++ MatchFinder_ReadBlock(p); -++} -++ -++static void MatchFinder_SetDefaultSettings(CMatchFinder *p) -++{ -++ p->cutValue = 32; -++ p->btMode = 1; -++ p->numHashBytes = 4; -++ p->bigHash = 0; -++} -++ -++#define kCrcPoly 0xEDB88320 -++ -++void MatchFinder_Construct(CMatchFinder *p) -++{ -++ UInt32 i; -++ p->bufferBase = 0; -++ p->directInput = 0; -++ p->hash = 0; -++ MatchFinder_SetDefaultSettings(p); -++ -++ for (i = 0; i < 256; i++) -++ { -++ UInt32 r = i; -++ int j; -++ for (j = 0; j < 8; j++) -++ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); -++ p->crc[i] = r; -++ } -++} -++ -++static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) -++{ -++ alloc->Free(alloc, p->hash); -++ p->hash = 0; -++} -++ -++void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) -++{ -++ MatchFinder_FreeThisClassMemory(p, alloc); -++ LzInWindow_Free(p, alloc); -++} -++ -++static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) -++{ -++ size_t sizeInBytes = (size_t)num * sizeof(CLzRef); -++ if (sizeInBytes / sizeof(CLzRef) != num) -++ return 0; -++ return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); -++} -++ -++int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, -++ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, -++ ISzAlloc *alloc) -++{ -++ UInt32 sizeReserv; -++ if (historySize > kMaxHistorySize) -++ { -++ MatchFinder_Free(p, alloc); -++ return 0; -++ } -++ sizeReserv = historySize >> 1; -++ if (historySize > ((UInt32)2 << 30)) -++ sizeReserv = historySize >> 2; -++ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); -++ -++ p->keepSizeBefore = historySize + keepAddBufferBefore + 1; -++ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; -++ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ -++ if (LzInWindow_Create(p, sizeReserv, alloc)) -++ { -++ UInt32 newCyclicBufferSize = historySize + 1; -++ UInt32 hs; -++ p->matchMaxLen = matchMaxLen; -++ { -++ p->fixedHashSize = 0; -++ if (p->numHashBytes == 2) -++ hs = (1 << 16) - 1; -++ else -++ { -++ hs = historySize - 1; -++ hs |= (hs >> 1); -++ hs |= (hs >> 2); -++ hs |= (hs >> 4); -++ hs |= (hs >> 8); -++ hs >>= 1; -++ hs |= 0xFFFF; /* don't change it! It's required for Deflate */ -++ if (hs > (1 << 24)) -++ { -++ if (p->numHashBytes == 3) -++ hs = (1 << 24) - 1; -++ else -++ hs >>= 1; -++ } -++ } -++ p->hashMask = hs; -++ hs++; -++ if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; -++ if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; -++ if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; -++ hs += p->fixedHashSize; -++ } -++ -++ { -++ UInt32 prevSize = p->hashSizeSum + p->numSons; -++ UInt32 newSize; -++ p->historySize = historySize; -++ p->hashSizeSum = hs; -++ p->cyclicBufferSize = newCyclicBufferSize; -++ p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); -++ newSize = p->hashSizeSum + p->numSons; -++ if (p->hash != 0 && prevSize == newSize) -++ return 1; -++ MatchFinder_FreeThisClassMemory(p, alloc); -++ p->hash = AllocRefs(newSize, alloc); -++ if (p->hash != 0) -++ { -++ p->son = p->hash + p->hashSizeSum; -++ return 1; -++ } -++ } -++ } -++ MatchFinder_Free(p, alloc); -++ return 0; -++} -++ -++static void MatchFinder_SetLimits(CMatchFinder *p) -++{ -++ UInt32 limit = kMaxValForNormalize - p->pos; -++ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; -++ if (limit2 < limit) -++ limit = limit2; -++ limit2 = p->streamPos - p->pos; -++ if (limit2 <= p->keepSizeAfter) -++ { -++ if (limit2 > 0) -++ limit2 = 1; -++ } -++ else -++ limit2 -= p->keepSizeAfter; -++ if (limit2 < limit) -++ limit = limit2; -++ { -++ UInt32 lenLimit = p->streamPos - p->pos; -++ if (lenLimit > p->matchMaxLen) -++ lenLimit = p->matchMaxLen; -++ p->lenLimit = lenLimit; -++ } -++ p->posLimit = p->pos + limit; -++} -++ -++void MatchFinder_Init(CMatchFinder *p) -++{ -++ UInt32 i; -++ for (i = 0; i < p->hashSizeSum; i++) -++ p->hash[i] = kEmptyHashValue; -++ p->cyclicBufferPos = 0; -++ p->buffer = p->bufferBase; -++ p->pos = p->streamPos = p->cyclicBufferSize; -++ p->result = SZ_OK; -++ p->streamEndWasReached = 0; -++ MatchFinder_ReadBlock(p); -++ MatchFinder_SetLimits(p); -++} -++ -++static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) -++{ -++ return (p->pos - p->historySize - 1) & kNormalizeMask; -++} -++ -++void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) -++{ -++ UInt32 i; -++ for (i = 0; i < numItems; i++) -++ { -++ UInt32 value = items[i]; -++ if (value <= subValue) -++ value = kEmptyHashValue; -++ else -++ value -= subValue; -++ items[i] = value; -++ } -++} -++ -++static void MatchFinder_Normalize(CMatchFinder *p) -++{ -++ UInt32 subValue = MatchFinder_GetSubValue(p); -++ MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); -++ MatchFinder_ReduceOffsets(p, subValue); -++} -++ -++static void MatchFinder_CheckLimits(CMatchFinder *p) -++{ -++ if (p->pos == kMaxValForNormalize) -++ MatchFinder_Normalize(p); -++ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) -++ MatchFinder_CheckAndMoveAndRead(p); -++ if (p->cyclicBufferPos == p->cyclicBufferSize) -++ p->cyclicBufferPos = 0; -++ MatchFinder_SetLimits(p); -++} -++ -++static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, -++ UInt32 *distances, UInt32 maxLen) -++{ -++ son[_cyclicBufferPos] = curMatch; -++ for (;;) -++ { -++ UInt32 delta = pos - curMatch; -++ if (cutValue-- == 0 || delta >= _cyclicBufferSize) -++ return distances; -++ { -++ const Byte *pb = cur - delta; -++ curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; -++ if (pb[maxLen] == cur[maxLen] && *pb == *cur) -++ { -++ UInt32 len = 0; -++ while (++len != lenLimit) -++ if (pb[len] != cur[len]) -++ break; -++ if (maxLen < len) -++ { -++ *distances++ = maxLen = len; -++ *distances++ = delta - 1; -++ if (len == lenLimit) -++ return distances; -++ } -++ } -++ } -++ } -++} -++ -++UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, -++ UInt32 *distances, UInt32 maxLen) -++{ -++ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; -++ CLzRef *ptr1 = son + (_cyclicBufferPos << 1); -++ UInt32 len0 = 0, len1 = 0; -++ for (;;) -++ { -++ UInt32 delta = pos - curMatch; -++ if (cutValue-- == 0 || delta >= _cyclicBufferSize) -++ { -++ *ptr0 = *ptr1 = kEmptyHashValue; -++ return distances; -++ } -++ { -++ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); -++ const Byte *pb = cur - delta; -++ UInt32 len = (len0 < len1 ? len0 : len1); -++ if (pb[len] == cur[len]) -++ { -++ if (++len != lenLimit && pb[len] == cur[len]) -++ while (++len != lenLimit) -++ if (pb[len] != cur[len]) -++ break; -++ if (maxLen < len) -++ { -++ *distances++ = maxLen = len; -++ *distances++ = delta - 1; -++ if (len == lenLimit) -++ { -++ *ptr1 = pair[0]; -++ *ptr0 = pair[1]; -++ return distances; -++ } -++ } -++ } -++ if (pb[len] < cur[len]) -++ { -++ *ptr1 = curMatch; -++ ptr1 = pair + 1; -++ curMatch = *ptr1; -++ len1 = len; -++ } -++ else -++ { -++ *ptr0 = curMatch; -++ ptr0 = pair; -++ curMatch = *ptr0; -++ len0 = len; -++ } -++ } -++ } -++} -++ -++static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) -++{ -++ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; -++ CLzRef *ptr1 = son + (_cyclicBufferPos << 1); -++ UInt32 len0 = 0, len1 = 0; -++ for (;;) -++ { -++ UInt32 delta = pos - curMatch; -++ if (cutValue-- == 0 || delta >= _cyclicBufferSize) -++ { -++ *ptr0 = *ptr1 = kEmptyHashValue; -++ return; -++ } -++ { -++ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); -++ const Byte *pb = cur - delta; -++ UInt32 len = (len0 < len1 ? len0 : len1); -++ if (pb[len] == cur[len]) -++ { -++ while (++len != lenLimit) -++ if (pb[len] != cur[len]) -++ break; -++ { -++ if (len == lenLimit) -++ { -++ *ptr1 = pair[0]; -++ *ptr0 = pair[1]; -++ return; -++ } -++ } -++ } -++ if (pb[len] < cur[len]) -++ { -++ *ptr1 = curMatch; -++ ptr1 = pair + 1; -++ curMatch = *ptr1; -++ len1 = len; -++ } -++ else -++ { -++ *ptr0 = curMatch; -++ ptr0 = pair; -++ curMatch = *ptr0; -++ len0 = len; -++ } -++ } -++ } -++} -++ -++#define MOVE_POS \ -++ ++p->cyclicBufferPos; \ -++ p->buffer++; \ -++ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); -++ -++#define MOVE_POS_RET MOVE_POS return offset; -++ -++static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } -++ -++#define GET_MATCHES_HEADER2(minLen, ret_op) \ -++ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ -++ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ -++ cur = p->buffer; -++ -++#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) -++#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) -++ -++#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue -++ -++#define GET_MATCHES_FOOTER(offset, maxLen) \ -++ offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ -++ distances + offset, maxLen) - distances); MOVE_POS_RET; -++ -++#define SKIP_FOOTER \ -++ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; -++ -++static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -++{ -++ UInt32 offset; -++ GET_MATCHES_HEADER(2) -++ HASH2_CALC; -++ curMatch = p->hash[hashValue]; -++ p->hash[hashValue] = p->pos; -++ offset = 0; -++ GET_MATCHES_FOOTER(offset, 1) -++} -++ -++UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -++{ -++ UInt32 offset; -++ GET_MATCHES_HEADER(3) -++ HASH_ZIP_CALC; -++ curMatch = p->hash[hashValue]; -++ p->hash[hashValue] = p->pos; -++ offset = 0; -++ GET_MATCHES_FOOTER(offset, 2) -++} -++ -++static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -++{ -++ UInt32 hash2Value, delta2, maxLen, offset; -++ GET_MATCHES_HEADER(3) -++ -++ HASH3_CALC; -++ -++ delta2 = p->pos - p->hash[hash2Value]; -++ curMatch = p->hash[kFix3HashSize + hashValue]; -++ -++ p->hash[hash2Value] = -++ p->hash[kFix3HashSize + hashValue] = p->pos; -++ -++ -++ maxLen = 2; -++ offset = 0; -++ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -++ { -++ for (; maxLen != lenLimit; maxLen++) -++ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -++ break; -++ distances[0] = maxLen; -++ distances[1] = delta2 - 1; -++ offset = 2; -++ if (maxLen == lenLimit) -++ { -++ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); -++ MOVE_POS_RET; -++ } -++ } -++ GET_MATCHES_FOOTER(offset, maxLen) -++} -++ -++static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -++{ -++ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; -++ GET_MATCHES_HEADER(4) -++ -++ HASH4_CALC; -++ -++ delta2 = p->pos - p->hash[ hash2Value]; -++ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; -++ curMatch = p->hash[kFix4HashSize + hashValue]; -++ -++ p->hash[ hash2Value] = -++ p->hash[kFix3HashSize + hash3Value] = -++ p->hash[kFix4HashSize + hashValue] = p->pos; -++ -++ maxLen = 1; -++ offset = 0; -++ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -++ { -++ distances[0] = maxLen = 2; -++ distances[1] = delta2 - 1; -++ offset = 2; -++ } -++ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) -++ { -++ maxLen = 3; -++ distances[offset + 1] = delta3 - 1; -++ offset += 2; -++ delta2 = delta3; -++ } -++ if (offset != 0) -++ { -++ for (; maxLen != lenLimit; maxLen++) -++ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -++ break; -++ distances[offset - 2] = maxLen; -++ if (maxLen == lenLimit) -++ { -++ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); -++ MOVE_POS_RET; -++ } -++ } -++ if (maxLen < 3) -++ maxLen = 3; -++ GET_MATCHES_FOOTER(offset, maxLen) -++} -++ -++static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -++{ -++ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; -++ GET_MATCHES_HEADER(4) -++ -++ HASH4_CALC; -++ -++ delta2 = p->pos - p->hash[ hash2Value]; -++ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; -++ curMatch = p->hash[kFix4HashSize + hashValue]; -++ -++ p->hash[ hash2Value] = -++ p->hash[kFix3HashSize + hash3Value] = -++ p->hash[kFix4HashSize + hashValue] = p->pos; -++ -++ maxLen = 1; -++ offset = 0; -++ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -++ { -++ distances[0] = maxLen = 2; -++ distances[1] = delta2 - 1; -++ offset = 2; -++ } -++ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) -++ { -++ maxLen = 3; -++ distances[offset + 1] = delta3 - 1; -++ offset += 2; -++ delta2 = delta3; -++ } -++ if (offset != 0) -++ { -++ for (; maxLen != lenLimit; maxLen++) -++ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -++ break; -++ distances[offset - 2] = maxLen; -++ if (maxLen == lenLimit) -++ { -++ p->son[p->cyclicBufferPos] = curMatch; -++ MOVE_POS_RET; -++ } -++ } -++ if (maxLen < 3) -++ maxLen = 3; -++ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), -++ distances + offset, maxLen) - (distances)); -++ MOVE_POS_RET -++} -++ -++UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -++{ -++ UInt32 offset; -++ GET_MATCHES_HEADER(3) -++ HASH_ZIP_CALC; -++ curMatch = p->hash[hashValue]; -++ p->hash[hashValue] = p->pos; -++ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), -++ distances, 2) - (distances)); -++ MOVE_POS_RET -++} -++ -++static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -++{ -++ do -++ { -++ SKIP_HEADER(2) -++ HASH2_CALC; -++ curMatch = p->hash[hashValue]; -++ p->hash[hashValue] = p->pos; -++ SKIP_FOOTER -++ } -++ while (--num != 0); -++} -++ -++void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -++{ -++ do -++ { -++ SKIP_HEADER(3) -++ HASH_ZIP_CALC; -++ curMatch = p->hash[hashValue]; -++ p->hash[hashValue] = p->pos; -++ SKIP_FOOTER -++ } -++ while (--num != 0); -++} -++ -++static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -++{ -++ do -++ { -++ UInt32 hash2Value; -++ SKIP_HEADER(3) -++ HASH3_CALC; -++ curMatch = p->hash[kFix3HashSize + hashValue]; -++ p->hash[hash2Value] = -++ p->hash[kFix3HashSize + hashValue] = p->pos; -++ SKIP_FOOTER -++ } -++ while (--num != 0); -++} -++ -++static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -++{ -++ do -++ { -++ UInt32 hash2Value, hash3Value; -++ SKIP_HEADER(4) -++ HASH4_CALC; -++ curMatch = p->hash[kFix4HashSize + hashValue]; -++ p->hash[ hash2Value] = -++ p->hash[kFix3HashSize + hash3Value] = p->pos; -++ p->hash[kFix4HashSize + hashValue] = p->pos; -++ SKIP_FOOTER -++ } -++ while (--num != 0); -++} -++ -++static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -++{ -++ do -++ { -++ UInt32 hash2Value, hash3Value; -++ SKIP_HEADER(4) -++ HASH4_CALC; -++ curMatch = p->hash[kFix4HashSize + hashValue]; -++ p->hash[ hash2Value] = -++ p->hash[kFix3HashSize + hash3Value] = -++ p->hash[kFix4HashSize + hashValue] = p->pos; -++ p->son[p->cyclicBufferPos] = curMatch; -++ MOVE_POS -++ } -++ while (--num != 0); -++} -++ -++void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -++{ -++ do -++ { -++ SKIP_HEADER(3) -++ HASH_ZIP_CALC; -++ curMatch = p->hash[hashValue]; -++ p->hash[hashValue] = p->pos; -++ p->son[p->cyclicBufferPos] = curMatch; -++ MOVE_POS -++ } -++ while (--num != 0); -++} -++ -++void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) -++{ -++ vTable->Init = (Mf_Init_Func)MatchFinder_Init; -++ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; -++ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; -++ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; -++ if (!p->btMode) -++ { -++ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; -++ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; -++ } -++ else if (p->numHashBytes == 2) -++ { -++ vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; -++ vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; -++ } -++ else if (p->numHashBytes == 3) -++ { -++ vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; -++ vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; -++ } -++ else -++ { -++ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; -++ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; -++ } -++} -+--- /dev/null -++++ b/lib/lzma/LzmaDec.c -+@@ -0,0 +1,999 @@ -++/* LzmaDec.c -- LZMA Decoder -++2009-09-20 : Igor Pavlov : Public domain */ -++ -++#include "LzmaDec.h" -++ -++#include -++ -++#define kNumTopBits 24 -++#define kTopValue ((UInt32)1 << kNumTopBits) -++ -++#define kNumBitModelTotalBits 11 -++#define kBitModelTotal (1 << kNumBitModelTotalBits) -++#define kNumMoveBits 5 -++ -++#define RC_INIT_SIZE 5 -++ -++#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } -++ -++#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -++#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); -++#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); -++#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ -++ { UPDATE_0(p); i = (i + i); A0; } else \ -++ { UPDATE_1(p); i = (i + i) + 1; A1; } -++#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) -++ -++#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } -++#define TREE_DECODE(probs, limit, i) \ -++ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } -++ -++/* #define _LZMA_SIZE_OPT */ -++ -++#ifdef _LZMA_SIZE_OPT -++#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) -++#else -++#define TREE_6_DECODE(probs, i) \ -++ { i = 1; \ -++ TREE_GET_BIT(probs, i); \ -++ TREE_GET_BIT(probs, i); \ -++ TREE_GET_BIT(probs, i); \ -++ TREE_GET_BIT(probs, i); \ -++ TREE_GET_BIT(probs, i); \ -++ TREE_GET_BIT(probs, i); \ -++ i -= 0x40; } -++#endif -++ -++#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } -++ -++#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -++#define UPDATE_0_CHECK range = bound; -++#define UPDATE_1_CHECK range -= bound; code -= bound; -++#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ -++ { UPDATE_0_CHECK; i = (i + i); A0; } else \ -++ { UPDATE_1_CHECK; i = (i + i) + 1; A1; } -++#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) -++#define TREE_DECODE_CHECK(probs, limit, i) \ -++ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } -++ -++ -++#define kNumPosBitsMax 4 -++#define kNumPosStatesMax (1 << kNumPosBitsMax) -++ -++#define kLenNumLowBits 3 -++#define kLenNumLowSymbols (1 << kLenNumLowBits) -++#define kLenNumMidBits 3 -++#define kLenNumMidSymbols (1 << kLenNumMidBits) -++#define kLenNumHighBits 8 -++#define kLenNumHighSymbols (1 << kLenNumHighBits) -++ -++#define LenChoice 0 -++#define LenChoice2 (LenChoice + 1) -++#define LenLow (LenChoice2 + 1) -++#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -++#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) -++#define kNumLenProbs (LenHigh + kLenNumHighSymbols) -++ -++ -++#define kNumStates 12 -++#define kNumLitStates 7 -++ -++#define kStartPosModelIndex 4 -++#define kEndPosModelIndex 14 -++#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) -++ -++#define kNumPosSlotBits 6 -++#define kNumLenToPosStates 4 -++ -++#define kNumAlignBits 4 -++#define kAlignTableSize (1 << kNumAlignBits) -++ -++#define kMatchMinLen 2 -++#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) -++ -++#define IsMatch 0 -++#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) -++#define IsRepG0 (IsRep + kNumStates) -++#define IsRepG1 (IsRepG0 + kNumStates) -++#define IsRepG2 (IsRepG1 + kNumStates) -++#define IsRep0Long (IsRepG2 + kNumStates) -++#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -++#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -++#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -++#define LenCoder (Align + kAlignTableSize) -++#define RepLenCoder (LenCoder + kNumLenProbs) -++#define Literal (RepLenCoder + kNumLenProbs) -++ -++#define LZMA_BASE_SIZE 1846 -++#define LZMA_LIT_SIZE 768 -++ -++#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) -++ -++#if Literal != LZMA_BASE_SIZE -++StopCompilingDueBUG -++#endif -++ -++#define LZMA_DIC_MIN (1 << 12) -++ -++/* First LZMA-symbol is always decoded. -++And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization -++Out: -++ Result: -++ SZ_OK - OK -++ SZ_ERROR_DATA - Error -++ p->remainLen: -++ < kMatchSpecLenStart : normal remain -++ = kMatchSpecLenStart : finished -++ = kMatchSpecLenStart + 1 : Flush marker -++ = kMatchSpecLenStart + 2 : State Init Marker -++*/ -++ -++static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -++{ -++ CLzmaProb *probs = p->probs; -++ -++ unsigned state = p->state; -++ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; -++ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; -++ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; -++ unsigned lc = p->prop.lc; -++ -++ Byte *dic = p->dic; -++ SizeT dicBufSize = p->dicBufSize; -++ SizeT dicPos = p->dicPos; -++ -++ UInt32 processedPos = p->processedPos; -++ UInt32 checkDicSize = p->checkDicSize; -++ unsigned len = 0; -++ -++ const Byte *buf = p->buf; -++ UInt32 range = p->range; -++ UInt32 code = p->code; -++ -++ do -++ { -++ CLzmaProb *prob; -++ UInt32 bound; -++ unsigned ttt; -++ unsigned posState = processedPos & pbMask; -++ -++ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; -++ IF_BIT_0(prob) -++ { -++ unsigned symbol; -++ UPDATE_0(prob); -++ prob = probs + Literal; -++ if (checkDicSize != 0 || processedPos != 0) -++ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + -++ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); -++ -++ if (state < kNumLitStates) -++ { -++ state -= (state < 4) ? state : 3; -++ symbol = 1; -++ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); -++ } -++ else -++ { -++ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -++ unsigned offs = 0x100; -++ state -= (state < 10) ? 3 : 6; -++ symbol = 1; -++ do -++ { -++ unsigned bit; -++ CLzmaProb *probLit; -++ matchByte <<= 1; -++ bit = (matchByte & offs); -++ probLit = prob + offs + bit + symbol; -++ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) -++ } -++ while (symbol < 0x100); -++ } -++ dic[dicPos++] = (Byte)symbol; -++ processedPos++; -++ continue; -++ } -++ else -++ { -++ UPDATE_1(prob); -++ prob = probs + IsRep + state; -++ IF_BIT_0(prob) -++ { -++ UPDATE_0(prob); -++ state += kNumStates; -++ prob = probs + LenCoder; -++ } -++ else -++ { -++ UPDATE_1(prob); -++ if (checkDicSize == 0 && processedPos == 0) -++ return SZ_ERROR_DATA; -++ prob = probs + IsRepG0 + state; -++ IF_BIT_0(prob) -++ { -++ UPDATE_0(prob); -++ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; -++ IF_BIT_0(prob) -++ { -++ UPDATE_0(prob); -++ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -++ dicPos++; -++ processedPos++; -++ state = state < kNumLitStates ? 9 : 11; -++ continue; -++ } -++ UPDATE_1(prob); -++ } -++ else -++ { -++ UInt32 distance; -++ UPDATE_1(prob); -++ prob = probs + IsRepG1 + state; -++ IF_BIT_0(prob) -++ { -++ UPDATE_0(prob); -++ distance = rep1; -++ } -++ else -++ { -++ UPDATE_1(prob); -++ prob = probs + IsRepG2 + state; -++ IF_BIT_0(prob) -++ { -++ UPDATE_0(prob); -++ distance = rep2; -++ } -++ else -++ { -++ UPDATE_1(prob); -++ distance = rep3; -++ rep3 = rep2; -++ } -++ rep2 = rep1; -++ } -++ rep1 = rep0; -++ rep0 = distance; -++ } -++ state = state < kNumLitStates ? 8 : 11; -++ prob = probs + RepLenCoder; -++ } -++ { -++ unsigned limit, offset; -++ CLzmaProb *probLen = prob + LenChoice; -++ IF_BIT_0(probLen) -++ { -++ UPDATE_0(probLen); -++ probLen = prob + LenLow + (posState << kLenNumLowBits); -++ offset = 0; -++ limit = (1 << kLenNumLowBits); -++ } -++ else -++ { -++ UPDATE_1(probLen); -++ probLen = prob + LenChoice2; -++ IF_BIT_0(probLen) -++ { -++ UPDATE_0(probLen); -++ probLen = prob + LenMid + (posState << kLenNumMidBits); -++ offset = kLenNumLowSymbols; -++ limit = (1 << kLenNumMidBits); -++ } -++ else -++ { -++ UPDATE_1(probLen); -++ probLen = prob + LenHigh; -++ offset = kLenNumLowSymbols + kLenNumMidSymbols; -++ limit = (1 << kLenNumHighBits); -++ } -++ } -++ TREE_DECODE(probLen, limit, len); -++ len += offset; -++ } -++ -++ if (state >= kNumStates) -++ { -++ UInt32 distance; -++ prob = probs + PosSlot + -++ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); -++ TREE_6_DECODE(prob, distance); -++ if (distance >= kStartPosModelIndex) -++ { -++ unsigned posSlot = (unsigned)distance; -++ int numDirectBits = (int)(((distance >> 1) - 1)); -++ distance = (2 | (distance & 1)); -++ if (posSlot < kEndPosModelIndex) -++ { -++ distance <<= numDirectBits; -++ prob = probs + SpecPos + distance - posSlot - 1; -++ { -++ UInt32 mask = 1; -++ unsigned i = 1; -++ do -++ { -++ GET_BIT2(prob + i, i, ; , distance |= mask); -++ mask <<= 1; -++ } -++ while (--numDirectBits != 0); -++ } -++ } -++ else -++ { -++ numDirectBits -= kNumAlignBits; -++ do -++ { -++ NORMALIZE -++ range >>= 1; -++ -++ { -++ UInt32 t; -++ code -= range; -++ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ -++ distance = (distance << 1) + (t + 1); -++ code += range & t; -++ } -++ /* -++ distance <<= 1; -++ if (code >= range) -++ { -++ code -= range; -++ distance |= 1; -++ } -++ */ -++ } -++ while (--numDirectBits != 0); -++ prob = probs + Align; -++ distance <<= kNumAlignBits; -++ { -++ unsigned i = 1; -++ GET_BIT2(prob + i, i, ; , distance |= 1); -++ GET_BIT2(prob + i, i, ; , distance |= 2); -++ GET_BIT2(prob + i, i, ; , distance |= 4); -++ GET_BIT2(prob + i, i, ; , distance |= 8); -++ } -++ if (distance == (UInt32)0xFFFFFFFF) -++ { -++ len += kMatchSpecLenStart; -++ state -= kNumStates; -++ break; -++ } -++ } -++ } -++ rep3 = rep2; -++ rep2 = rep1; -++ rep1 = rep0; -++ rep0 = distance + 1; -++ if (checkDicSize == 0) -++ { -++ if (distance >= processedPos) -++ return SZ_ERROR_DATA; -++ } -++ else if (distance >= checkDicSize) -++ return SZ_ERROR_DATA; -++ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; -++ } -++ -++ len += kMatchMinLen; -++ -++ if (limit == dicPos) -++ return SZ_ERROR_DATA; -++ { -++ SizeT rem = limit - dicPos; -++ unsigned curLen = ((rem < len) ? (unsigned)rem : len); -++ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); -++ -++ processedPos += curLen; -++ -++ len -= curLen; -++ if (pos + curLen <= dicBufSize) -++ { -++ Byte *dest = dic + dicPos; -++ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; -++ const Byte *lim = dest + curLen; -++ dicPos += curLen; -++ do -++ *(dest) = (Byte)*(dest + src); -++ while (++dest != lim); -++ } -++ else -++ { -++ do -++ { -++ dic[dicPos++] = dic[pos]; -++ if (++pos == dicBufSize) -++ pos = 0; -++ } -++ while (--curLen != 0); -++ } -++ } -++ } -++ } -++ while (dicPos < limit && buf < bufLimit); -++ NORMALIZE; -++ p->buf = buf; -++ p->range = range; -++ p->code = code; -++ p->remainLen = len; -++ p->dicPos = dicPos; -++ p->processedPos = processedPos; -++ p->reps[0] = rep0; -++ p->reps[1] = rep1; -++ p->reps[2] = rep2; -++ p->reps[3] = rep3; -++ p->state = state; -++ -++ return SZ_OK; -++} -++ -++static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) -++{ -++ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) -++ { -++ Byte *dic = p->dic; -++ SizeT dicPos = p->dicPos; -++ SizeT dicBufSize = p->dicBufSize; -++ unsigned len = p->remainLen; -++ UInt32 rep0 = p->reps[0]; -++ if (limit - dicPos < len) -++ len = (unsigned)(limit - dicPos); -++ -++ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) -++ p->checkDicSize = p->prop.dicSize; -++ -++ p->processedPos += len; -++ p->remainLen -= len; -++ while (len-- != 0) -++ { -++ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -++ dicPos++; -++ } -++ p->dicPos = dicPos; -++ } -++} -++ -++static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -++{ -++ do -++ { -++ SizeT limit2 = limit; -++ if (p->checkDicSize == 0) -++ { -++ UInt32 rem = p->prop.dicSize - p->processedPos; -++ if (limit - p->dicPos > rem) -++ limit2 = p->dicPos + rem; -++ } -++ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); -++ if (p->processedPos >= p->prop.dicSize) -++ p->checkDicSize = p->prop.dicSize; -++ LzmaDec_WriteRem(p, limit); -++ } -++ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); -++ -++ if (p->remainLen > kMatchSpecLenStart) -++ { -++ p->remainLen = kMatchSpecLenStart; -++ } -++ return 0; -++} -++ -++typedef enum -++{ -++ DUMMY_ERROR, /* unexpected end of input stream */ -++ DUMMY_LIT, -++ DUMMY_MATCH, -++ DUMMY_REP -++} ELzmaDummy; -++ -++static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) -++{ -++ UInt32 range = p->range; -++ UInt32 code = p->code; -++ const Byte *bufLimit = buf + inSize; -++ CLzmaProb *probs = p->probs; -++ unsigned state = p->state; -++ ELzmaDummy res; -++ -++ { -++ CLzmaProb *prob; -++ UInt32 bound; -++ unsigned ttt; -++ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); -++ -++ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; -++ IF_BIT_0_CHECK(prob) -++ { -++ UPDATE_0_CHECK -++ -++ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ -++ -++ prob = probs + Literal; -++ if (p->checkDicSize != 0 || p->processedPos != 0) -++ prob += (LZMA_LIT_SIZE * -++ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + -++ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); -++ -++ if (state < kNumLitStates) -++ { -++ unsigned symbol = 1; -++ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); -++ } -++ else -++ { -++ unsigned matchByte = p->dic[p->dicPos - p->reps[0] + -++ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; -++ unsigned offs = 0x100; -++ unsigned symbol = 1; -++ do -++ { -++ unsigned bit; -++ CLzmaProb *probLit; -++ matchByte <<= 1; -++ bit = (matchByte & offs); -++ probLit = prob + offs + bit + symbol; -++ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) -++ } -++ while (symbol < 0x100); -++ } -++ res = DUMMY_LIT; -++ } -++ else -++ { -++ unsigned len; -++ UPDATE_1_CHECK; -++ -++ prob = probs + IsRep + state; -++ IF_BIT_0_CHECK(prob) -++ { -++ UPDATE_0_CHECK; -++ state = 0; -++ prob = probs + LenCoder; -++ res = DUMMY_MATCH; -++ } -++ else -++ { -++ UPDATE_1_CHECK; -++ res = DUMMY_REP; -++ prob = probs + IsRepG0 + state; -++ IF_BIT_0_CHECK(prob) -++ { -++ UPDATE_0_CHECK; -++ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; -++ IF_BIT_0_CHECK(prob) -++ { -++ UPDATE_0_CHECK; -++ NORMALIZE_CHECK; -++ return DUMMY_REP; -++ } -++ else -++ { -++ UPDATE_1_CHECK; -++ } -++ } -++ else -++ { -++ UPDATE_1_CHECK; -++ prob = probs + IsRepG1 + state; -++ IF_BIT_0_CHECK(prob) -++ { -++ UPDATE_0_CHECK; -++ } -++ else -++ { -++ UPDATE_1_CHECK; -++ prob = probs + IsRepG2 + state; -++ IF_BIT_0_CHECK(prob) -++ { -++ UPDATE_0_CHECK; -++ } -++ else -++ { -++ UPDATE_1_CHECK; -++ } -++ } -++ } -++ state = kNumStates; -++ prob = probs + RepLenCoder; -++ } -++ { -++ unsigned limit, offset; -++ CLzmaProb *probLen = prob + LenChoice; -++ IF_BIT_0_CHECK(probLen) -++ { -++ UPDATE_0_CHECK; -++ probLen = prob + LenLow + (posState << kLenNumLowBits); -++ offset = 0; -++ limit = 1 << kLenNumLowBits; -++ } -++ else -++ { -++ UPDATE_1_CHECK; -++ probLen = prob + LenChoice2; -++ IF_BIT_0_CHECK(probLen) -++ { -++ UPDATE_0_CHECK; -++ probLen = prob + LenMid + (posState << kLenNumMidBits); -++ offset = kLenNumLowSymbols; -++ limit = 1 << kLenNumMidBits; -++ } -++ else -++ { -++ UPDATE_1_CHECK; -++ probLen = prob + LenHigh; -++ offset = kLenNumLowSymbols + kLenNumMidSymbols; -++ limit = 1 << kLenNumHighBits; -++ } -++ } -++ TREE_DECODE_CHECK(probLen, limit, len); -++ len += offset; -++ } -++ -++ if (state < 4) -++ { -++ unsigned posSlot; -++ prob = probs + PosSlot + -++ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << -++ kNumPosSlotBits); -++ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); -++ if (posSlot >= kStartPosModelIndex) -++ { -++ int numDirectBits = ((posSlot >> 1) - 1); -++ -++ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ -++ -++ if (posSlot < kEndPosModelIndex) -++ { -++ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; -++ } -++ else -++ { -++ numDirectBits -= kNumAlignBits; -++ do -++ { -++ NORMALIZE_CHECK -++ range >>= 1; -++ code -= range & (((code - range) >> 31) - 1); -++ /* if (code >= range) code -= range; */ -++ } -++ while (--numDirectBits != 0); -++ prob = probs + Align; -++ numDirectBits = kNumAlignBits; -++ } -++ { -++ unsigned i = 1; -++ do -++ { -++ GET_BIT_CHECK(prob + i, i); -++ } -++ while (--numDirectBits != 0); -++ } -++ } -++ } -++ } -++ } -++ NORMALIZE_CHECK; -++ return res; -++} -++ -++ -++static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) -++{ -++ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); -++ p->range = 0xFFFFFFFF; -++ p->needFlush = 0; -++} -++ -++void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) -++{ -++ p->needFlush = 1; -++ p->remainLen = 0; -++ p->tempBufSize = 0; -++ -++ if (initDic) -++ { -++ p->processedPos = 0; -++ p->checkDicSize = 0; -++ p->needInitState = 1; -++ } -++ if (initState) -++ p->needInitState = 1; -++} -++ -++void LzmaDec_Init(CLzmaDec *p) -++{ -++ p->dicPos = 0; -++ LzmaDec_InitDicAndState(p, True, True); -++} -++ -++static void LzmaDec_InitStateReal(CLzmaDec *p) -++{ -++ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); -++ UInt32 i; -++ CLzmaProb *probs = p->probs; -++ for (i = 0; i < numProbs; i++) -++ probs[i] = kBitModelTotal >> 1; -++ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; -++ p->state = 0; -++ p->needInitState = 0; -++} -++ -++SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, -++ ELzmaFinishMode finishMode, ELzmaStatus *status) -++{ -++ SizeT inSize = *srcLen; -++ (*srcLen) = 0; -++ LzmaDec_WriteRem(p, dicLimit); -++ -++ *status = LZMA_STATUS_NOT_SPECIFIED; -++ -++ while (p->remainLen != kMatchSpecLenStart) -++ { -++ int checkEndMarkNow; -++ -++ if (p->needFlush != 0) -++ { -++ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) -++ p->tempBuf[p->tempBufSize++] = *src++; -++ if (p->tempBufSize < RC_INIT_SIZE) -++ { -++ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -++ return SZ_OK; -++ } -++ if (p->tempBuf[0] != 0) -++ return SZ_ERROR_DATA; -++ -++ LzmaDec_InitRc(p, p->tempBuf); -++ p->tempBufSize = 0; -++ } -++ -++ checkEndMarkNow = 0; -++ if (p->dicPos >= dicLimit) -++ { -++ if (p->remainLen == 0 && p->code == 0) -++ { -++ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; -++ return SZ_OK; -++ } -++ if (finishMode == LZMA_FINISH_ANY) -++ { -++ *status = LZMA_STATUS_NOT_FINISHED; -++ return SZ_OK; -++ } -++ if (p->remainLen != 0) -++ { -++ *status = LZMA_STATUS_NOT_FINISHED; -++ return SZ_ERROR_DATA; -++ } -++ checkEndMarkNow = 1; -++ } -++ -++ if (p->needInitState) -++ LzmaDec_InitStateReal(p); -++ -++ if (p->tempBufSize == 0) -++ { -++ SizeT processed; -++ const Byte *bufLimit; -++ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) -++ { -++ int dummyRes = LzmaDec_TryDummy(p, src, inSize); -++ if (dummyRes == DUMMY_ERROR) -++ { -++ memcpy(p->tempBuf, src, inSize); -++ p->tempBufSize = (unsigned)inSize; -++ (*srcLen) += inSize; -++ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -++ return SZ_OK; -++ } -++ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) -++ { -++ *status = LZMA_STATUS_NOT_FINISHED; -++ return SZ_ERROR_DATA; -++ } -++ bufLimit = src; -++ } -++ else -++ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; -++ p->buf = src; -++ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) -++ return SZ_ERROR_DATA; -++ processed = (SizeT)(p->buf - src); -++ (*srcLen) += processed; -++ src += processed; -++ inSize -= processed; -++ } -++ else -++ { -++ unsigned rem = p->tempBufSize, lookAhead = 0; -++ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) -++ p->tempBuf[rem++] = src[lookAhead++]; -++ p->tempBufSize = rem; -++ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) -++ { -++ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); -++ if (dummyRes == DUMMY_ERROR) -++ { -++ (*srcLen) += lookAhead; -++ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -++ return SZ_OK; -++ } -++ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) -++ { -++ *status = LZMA_STATUS_NOT_FINISHED; -++ return SZ_ERROR_DATA; -++ } -++ } -++ p->buf = p->tempBuf; -++ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) -++ return SZ_ERROR_DATA; -++ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); -++ (*srcLen) += lookAhead; -++ src += lookAhead; -++ inSize -= lookAhead; -++ p->tempBufSize = 0; -++ } -++ } -++ if (p->code == 0) -++ *status = LZMA_STATUS_FINISHED_WITH_MARK; -++ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; -++} -++ -++SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) -++{ -++ SizeT outSize = *destLen; -++ SizeT inSize = *srcLen; -++ *srcLen = *destLen = 0; -++ for (;;) -++ { -++ SizeT inSizeCur = inSize, outSizeCur, dicPos; -++ ELzmaFinishMode curFinishMode; -++ SRes res; -++ if (p->dicPos == p->dicBufSize) -++ p->dicPos = 0; -++ dicPos = p->dicPos; -++ if (outSize > p->dicBufSize - dicPos) -++ { -++ outSizeCur = p->dicBufSize; -++ curFinishMode = LZMA_FINISH_ANY; -++ } -++ else -++ { -++ outSizeCur = dicPos + outSize; -++ curFinishMode = finishMode; -++ } -++ -++ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); -++ src += inSizeCur; -++ inSize -= inSizeCur; -++ *srcLen += inSizeCur; -++ outSizeCur = p->dicPos - dicPos; -++ memcpy(dest, p->dic + dicPos, outSizeCur); -++ dest += outSizeCur; -++ outSize -= outSizeCur; -++ *destLen += outSizeCur; -++ if (res != 0) -++ return res; -++ if (outSizeCur == 0 || outSize == 0) -++ return SZ_OK; -++ } -++} -++ -++void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) -++{ -++ alloc->Free(alloc, p->probs); -++ p->probs = 0; -++} -++ -++static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) -++{ -++ alloc->Free(alloc, p->dic); -++ p->dic = 0; -++} -++ -++void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) -++{ -++ LzmaDec_FreeProbs(p, alloc); -++ LzmaDec_FreeDict(p, alloc); -++} -++ -++SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) -++{ -++ UInt32 dicSize; -++ Byte d; -++ -++ if (size < LZMA_PROPS_SIZE) -++ return SZ_ERROR_UNSUPPORTED; -++ else -++ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); -++ -++ if (dicSize < LZMA_DIC_MIN) -++ dicSize = LZMA_DIC_MIN; -++ p->dicSize = dicSize; -++ -++ d = data[0]; -++ if (d >= (9 * 5 * 5)) -++ return SZ_ERROR_UNSUPPORTED; -++ -++ p->lc = d % 9; -++ d /= 9; -++ p->pb = d / 5; -++ p->lp = d % 5; -++ -++ return SZ_OK; -++} -++ -++static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) -++{ -++ UInt32 numProbs = LzmaProps_GetNumProbs(propNew); -++ if (p->probs == 0 || numProbs != p->numProbs) -++ { -++ LzmaDec_FreeProbs(p, alloc); -++ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); -++ p->numProbs = numProbs; -++ if (p->probs == 0) -++ return SZ_ERROR_MEM; -++ } -++ return SZ_OK; -++} -++ -++SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -++{ -++ CLzmaProps propNew; -++ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -++ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); -++ p->prop = propNew; -++ return SZ_OK; -++} -++ -++SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -++{ -++ CLzmaProps propNew; -++ SizeT dicBufSize; -++ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -++ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); -++ dicBufSize = propNew.dicSize; -++ if (p->dic == 0 || dicBufSize != p->dicBufSize) -++ { -++ LzmaDec_FreeDict(p, alloc); -++ p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); -++ if (p->dic == 0) -++ { -++ LzmaDec_FreeProbs(p, alloc); -++ return SZ_ERROR_MEM; -++ } -++ } -++ p->dicBufSize = dicBufSize; -++ p->prop = propNew; -++ return SZ_OK; -++} -++ -++SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, -++ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, -++ ELzmaStatus *status, ISzAlloc *alloc) -++{ -++ CLzmaDec p; -++ SRes res; -++ SizeT inSize = *srcLen; -++ SizeT outSize = *destLen; -++ *srcLen = *destLen = 0; -++ if (inSize < RC_INIT_SIZE) -++ return SZ_ERROR_INPUT_EOF; -++ -++ LzmaDec_Construct(&p); -++ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); -++ if (res != 0) -++ return res; -++ p.dic = dest; -++ p.dicBufSize = outSize; -++ -++ LzmaDec_Init(&p); -++ -++ *srcLen = inSize; -++ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); -++ -++ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) -++ res = SZ_ERROR_INPUT_EOF; -++ -++ (*destLen) = p.dicPos; -++ LzmaDec_FreeProbs(&p, alloc); -++ return res; -++} -+--- /dev/null -++++ b/lib/lzma/LzmaEnc.c -+@@ -0,0 +1,2271 @@ -++/* LzmaEnc.c -- LZMA Encoder -++2009-11-24 : Igor Pavlov : Public domain */ -++ -++#include -++ -++/* #define SHOW_STAT */ -++/* #define SHOW_STAT2 */ -++ -++#if defined(SHOW_STAT) || defined(SHOW_STAT2) -++#include -++#endif -++ -++#include "LzmaEnc.h" -++ -++/* disable MT */ -++#define _7ZIP_ST -++ -++#include "LzFind.h" -++#ifndef _7ZIP_ST -++#include "LzFindMt.h" -++#endif -++ -++#ifdef SHOW_STAT -++static int ttt = 0; -++#endif -++ -++#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) -++ -++#define kBlockSize (9 << 10) -++#define kUnpackBlockSize (1 << 18) -++#define kMatchArraySize (1 << 21) -++#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) -++ -++#define kNumMaxDirectBits (31) -++ -++#define kNumTopBits 24 -++#define kTopValue ((UInt32)1 << kNumTopBits) -++ -++#define kNumBitModelTotalBits 11 -++#define kBitModelTotal (1 << kNumBitModelTotalBits) -++#define kNumMoveBits 5 -++#define kProbInitValue (kBitModelTotal >> 1) -++ -++#define kNumMoveReducingBits 4 -++#define kNumBitPriceShiftBits 4 -++#define kBitPrice (1 << kNumBitPriceShiftBits) -++ -++void LzmaEncProps_Init(CLzmaEncProps *p) -++{ -++ p->level = 5; -++ p->dictSize = p->mc = 0; -++ p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; -++ p->writeEndMark = 0; -++} -++ -++void LzmaEncProps_Normalize(CLzmaEncProps *p) -++{ -++ int level = p->level; -++ if (level < 0) level = 5; -++ p->level = level; -++ if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); -++ if (p->lc < 0) p->lc = 3; -++ if (p->lp < 0) p->lp = 0; -++ if (p->pb < 0) p->pb = 2; -++ if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); -++ if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); -++ if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); -++ if (p->numHashBytes < 0) p->numHashBytes = 4; -++ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); -++ if (p->numThreads < 0) -++ p->numThreads = -++ #ifndef _7ZIP_ST -++ ((p->btMode && p->algo) ? 2 : 1); -++ #else -++ 1; -++ #endif -++} -++ -++UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) -++{ -++ CLzmaEncProps props = *props2; -++ LzmaEncProps_Normalize(&props); -++ return props.dictSize; -++} -++ -++/* #define LZMA_LOG_BSR */ -++/* Define it for Intel's CPU */ -++ -++ -++#ifdef LZMA_LOG_BSR -++ -++#define kDicLogSizeMaxCompress 30 -++ -++#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } -++ -++UInt32 GetPosSlot1(UInt32 pos) -++{ -++ UInt32 res; -++ BSR2_RET(pos, res); -++ return res; -++} -++#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -++#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } -++ -++#else -++ -++#define kNumLogBits (9 + (int)sizeof(size_t) / 2) -++#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) -++ -++void LzmaEnc_FastPosInit(Byte *g_FastPos) -++{ -++ int c = 2, slotFast; -++ g_FastPos[0] = 0; -++ g_FastPos[1] = 1; -++ -++ for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) -++ { -++ UInt32 k = (1 << ((slotFast >> 1) - 1)); -++ UInt32 j; -++ for (j = 0; j < k; j++, c++) -++ g_FastPos[c] = (Byte)slotFast; -++ } -++} -++ -++#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ -++ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ -++ res = p->g_FastPos[pos >> i] + (i * 2); } -++/* -++#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ -++ p->g_FastPos[pos >> 6] + 12 : \ -++ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } -++*/ -++ -++#define GetPosSlot1(pos) p->g_FastPos[pos] -++#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -++#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } -++ -++#endif -++ -++ -++#define LZMA_NUM_REPS 4 -++ -++typedef unsigned CState; -++ -++typedef struct -++{ -++ UInt32 price; -++ -++ CState state; -++ int prev1IsChar; -++ int prev2; -++ -++ UInt32 posPrev2; -++ UInt32 backPrev2; -++ -++ UInt32 posPrev; -++ UInt32 backPrev; -++ UInt32 backs[LZMA_NUM_REPS]; -++} COptimal; -++ -++#define kNumOpts (1 << 12) -++ -++#define kNumLenToPosStates 4 -++#define kNumPosSlotBits 6 -++#define kDicLogSizeMin 0 -++#define kDicLogSizeMax 32 -++#define kDistTableSizeMax (kDicLogSizeMax * 2) -++ -++ -++#define kNumAlignBits 4 -++#define kAlignTableSize (1 << kNumAlignBits) -++#define kAlignMask (kAlignTableSize - 1) -++ -++#define kStartPosModelIndex 4 -++#define kEndPosModelIndex 14 -++#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) -++ -++#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) -++ -++#ifdef _LZMA_PROB32 -++#define CLzmaProb UInt32 -++#else -++#define CLzmaProb UInt16 -++#endif -++ -++#define LZMA_PB_MAX 4 -++#define LZMA_LC_MAX 8 -++#define LZMA_LP_MAX 4 -++ -++#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) -++ -++ -++#define kLenNumLowBits 3 -++#define kLenNumLowSymbols (1 << kLenNumLowBits) -++#define kLenNumMidBits 3 -++#define kLenNumMidSymbols (1 << kLenNumMidBits) -++#define kLenNumHighBits 8 -++#define kLenNumHighSymbols (1 << kLenNumHighBits) -++ -++#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) -++ -++#define LZMA_MATCH_LEN_MIN 2 -++#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) -++ -++#define kNumStates 12 -++ -++typedef struct -++{ -++ CLzmaProb choice; -++ CLzmaProb choice2; -++ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; -++ CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; -++ CLzmaProb high[kLenNumHighSymbols]; -++} CLenEnc; -++ -++typedef struct -++{ -++ CLenEnc p; -++ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; -++ UInt32 tableSize; -++ UInt32 counters[LZMA_NUM_PB_STATES_MAX]; -++} CLenPriceEnc; -++ -++typedef struct -++{ -++ UInt32 range; -++ Byte cache; -++ UInt64 low; -++ UInt64 cacheSize; -++ Byte *buf; -++ Byte *bufLim; -++ Byte *bufBase; -++ ISeqOutStream *outStream; -++ UInt64 processed; -++ SRes res; -++} CRangeEnc; -++ -++typedef struct -++{ -++ CLzmaProb *litProbs; -++ -++ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; -++ CLzmaProb isRep[kNumStates]; -++ CLzmaProb isRepG0[kNumStates]; -++ CLzmaProb isRepG1[kNumStates]; -++ CLzmaProb isRepG2[kNumStates]; -++ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; -++ -++ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; -++ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; -++ CLzmaProb posAlignEncoder[1 << kNumAlignBits]; -++ -++ CLenPriceEnc lenEnc; -++ CLenPriceEnc repLenEnc; -++ -++ UInt32 reps[LZMA_NUM_REPS]; -++ UInt32 state; -++} CSaveState; -++ -++typedef struct -++{ -++ IMatchFinder matchFinder; -++ void *matchFinderObj; -++ -++ #ifndef _7ZIP_ST -++ Bool mtMode; -++ CMatchFinderMt matchFinderMt; -++ #endif -++ -++ CMatchFinder matchFinderBase; -++ -++ #ifndef _7ZIP_ST -++ Byte pad[128]; -++ #endif -++ -++ UInt32 optimumEndIndex; -++ UInt32 optimumCurrentIndex; -++ -++ UInt32 longestMatchLength; -++ UInt32 numPairs; -++ UInt32 numAvail; -++ COptimal opt[kNumOpts]; -++ -++ #ifndef LZMA_LOG_BSR -++ Byte g_FastPos[1 << kNumLogBits]; -++ #endif -++ -++ UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; -++ UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; -++ UInt32 numFastBytes; -++ UInt32 additionalOffset; -++ UInt32 reps[LZMA_NUM_REPS]; -++ UInt32 state; -++ -++ UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; -++ UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; -++ UInt32 alignPrices[kAlignTableSize]; -++ UInt32 alignPriceCount; -++ -++ UInt32 distTableSize; -++ -++ unsigned lc, lp, pb; -++ unsigned lpMask, pbMask; -++ -++ CLzmaProb *litProbs; -++ -++ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; -++ CLzmaProb isRep[kNumStates]; -++ CLzmaProb isRepG0[kNumStates]; -++ CLzmaProb isRepG1[kNumStates]; -++ CLzmaProb isRepG2[kNumStates]; -++ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; -++ -++ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; -++ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; -++ CLzmaProb posAlignEncoder[1 << kNumAlignBits]; -++ -++ CLenPriceEnc lenEnc; -++ CLenPriceEnc repLenEnc; -++ -++ unsigned lclp; -++ -++ Bool fastMode; -++ -++ CRangeEnc rc; -++ -++ Bool writeEndMark; -++ UInt64 nowPos64; -++ UInt32 matchPriceCount; -++ Bool finished; -++ Bool multiThread; -++ -++ SRes result; -++ UInt32 dictSize; -++ UInt32 matchFinderCycles; -++ -++ int needInit; -++ -++ CSaveState saveState; -++} CLzmaEnc; -++ -++void LzmaEnc_SaveState(CLzmaEncHandle pp) -++{ -++ CLzmaEnc *p = (CLzmaEnc *)pp; -++ CSaveState *dest = &p->saveState; -++ int i; -++ dest->lenEnc = p->lenEnc; -++ dest->repLenEnc = p->repLenEnc; -++ dest->state = p->state; -++ -++ for (i = 0; i < kNumStates; i++) -++ { -++ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); -++ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); -++ } -++ for (i = 0; i < kNumLenToPosStates; i++) -++ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); -++ memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); -++ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); -++ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); -++ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); -++ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); -++ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); -++ memcpy(dest->reps, p->reps, sizeof(p->reps)); -++ memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); -++} -++ -++void LzmaEnc_RestoreState(CLzmaEncHandle pp) -++{ -++ CLzmaEnc *dest = (CLzmaEnc *)pp; -++ const CSaveState *p = &dest->saveState; -++ int i; -++ dest->lenEnc = p->lenEnc; -++ dest->repLenEnc = p->repLenEnc; -++ dest->state = p->state; -++ -++ for (i = 0; i < kNumStates; i++) -++ { -++ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); -++ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); -++ } -++ for (i = 0; i < kNumLenToPosStates; i++) -++ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); -++ memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); -++ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); -++ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); -++ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); -++ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); -++ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); -++ memcpy(dest->reps, p->reps, sizeof(p->reps)); -++ memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); -++} -++ -++SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) -++{ -++ CLzmaEnc *p = (CLzmaEnc *)pp; -++ CLzmaEncProps props = *props2; -++ LzmaEncProps_Normalize(&props); -++ -++ if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || -++ props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30)) -++ return SZ_ERROR_PARAM; -++ p->dictSize = props.dictSize; -++ p->matchFinderCycles = props.mc; -++ { -++ unsigned fb = props.fb; -++ if (fb < 5) -++ fb = 5; -++ if (fb > LZMA_MATCH_LEN_MAX) -++ fb = LZMA_MATCH_LEN_MAX; -++ p->numFastBytes = fb; -++ } -++ p->lc = props.lc; -++ p->lp = props.lp; -++ p->pb = props.pb; -++ p->fastMode = (props.algo == 0); -++ p->matchFinderBase.btMode = props.btMode; -++ { -++ UInt32 numHashBytes = 4; -++ if (props.btMode) -++ { -++ if (props.numHashBytes < 2) -++ numHashBytes = 2; -++ else if (props.numHashBytes < 4) -++ numHashBytes = props.numHashBytes; -++ } -++ p->matchFinderBase.numHashBytes = numHashBytes; -++ } -++ -++ p->matchFinderBase.cutValue = props.mc; -++ -++ p->writeEndMark = props.writeEndMark; -++ -++ #ifndef _7ZIP_ST -++ /* -++ if (newMultiThread != _multiThread) -++ { -++ ReleaseMatchFinder(); -++ _multiThread = newMultiThread; -++ } -++ */ -++ p->multiThread = (props.numThreads > 1); -++ #endif -++ -++ return SZ_OK; -++} -++ -++static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; -++static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; -++static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; -++static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; -++ -++#define IsCharState(s) ((s) < 7) -++ -++#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) -++ -++#define kInfinityPrice (1 << 30) -++ -++static void RangeEnc_Construct(CRangeEnc *p) -++{ -++ p->outStream = 0; -++ p->bufBase = 0; -++} -++ -++#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) -++ -++#define RC_BUF_SIZE (1 << 16) -++static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) -++{ -++ if (p->bufBase == 0) -++ { -++ p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); -++ if (p->bufBase == 0) -++ return 0; -++ p->bufLim = p->bufBase + RC_BUF_SIZE; -++ } -++ return 1; -++} -++ -++static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) -++{ -++ alloc->Free(alloc, p->bufBase); -++ p->bufBase = 0; -++} -++ -++static void RangeEnc_Init(CRangeEnc *p) -++{ -++ /* Stream.Init(); */ -++ p->low = 0; -++ p->range = 0xFFFFFFFF; -++ p->cacheSize = 1; -++ p->cache = 0; -++ -++ p->buf = p->bufBase; -++ -++ p->processed = 0; -++ p->res = SZ_OK; -++} -++ -++static void RangeEnc_FlushStream(CRangeEnc *p) -++{ -++ size_t num; -++ if (p->res != SZ_OK) -++ return; -++ num = p->buf - p->bufBase; -++ if (num != p->outStream->Write(p->outStream, p->bufBase, num)) -++ p->res = SZ_ERROR_WRITE; -++ p->processed += num; -++ p->buf = p->bufBase; -++} -++ -++static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) -++{ -++ if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) -++ { -++ Byte temp = p->cache; -++ do -++ { -++ Byte *buf = p->buf; -++ *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); -++ p->buf = buf; -++ if (buf == p->bufLim) -++ RangeEnc_FlushStream(p); -++ temp = 0xFF; -++ } -++ while (--p->cacheSize != 0); -++ p->cache = (Byte)((UInt32)p->low >> 24); -++ } -++ p->cacheSize++; -++ p->low = (UInt32)p->low << 8; -++} -++ -++static void RangeEnc_FlushData(CRangeEnc *p) -++{ -++ int i; -++ for (i = 0; i < 5; i++) -++ RangeEnc_ShiftLow(p); -++} -++ -++static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) -++{ -++ do -++ { -++ p->range >>= 1; -++ p->low += p->range & (0 - ((value >> --numBits) & 1)); -++ if (p->range < kTopValue) -++ { -++ p->range <<= 8; -++ RangeEnc_ShiftLow(p); -++ } -++ } -++ while (numBits != 0); -++} -++ -++static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) -++{ -++ UInt32 ttt = *prob; -++ UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; -++ if (symbol == 0) -++ { -++ p->range = newBound; -++ ttt += (kBitModelTotal - ttt) >> kNumMoveBits; -++ } -++ else -++ { -++ p->low += newBound; -++ p->range -= newBound; -++ ttt -= ttt >> kNumMoveBits; -++ } -++ *prob = (CLzmaProb)ttt; -++ if (p->range < kTopValue) -++ { -++ p->range <<= 8; -++ RangeEnc_ShiftLow(p); -++ } -++} -++ -++static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) -++{ -++ symbol |= 0x100; -++ do -++ { -++ RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); -++ symbol <<= 1; -++ } -++ while (symbol < 0x10000); -++} -++ -++static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) -++{ -++ UInt32 offs = 0x100; -++ symbol |= 0x100; -++ do -++ { -++ matchByte <<= 1; -++ RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); -++ symbol <<= 1; -++ offs &= ~(matchByte ^ symbol); -++ } -++ while (symbol < 0x10000); -++} -++ -++void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) -++{ -++ UInt32 i; -++ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) -++ { -++ const int kCyclesBits = kNumBitPriceShiftBits; -++ UInt32 w = i; -++ UInt32 bitCount = 0; -++ int j; -++ for (j = 0; j < kCyclesBits; j++) -++ { -++ w = w * w; -++ bitCount <<= 1; -++ while (w >= ((UInt32)1 << 16)) -++ { -++ w >>= 1; -++ bitCount++; -++ } -++ } -++ ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); -++ } -++} -++ -++ -++#define GET_PRICE(prob, symbol) \ -++ p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; -++ -++#define GET_PRICEa(prob, symbol) \ -++ ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; -++ -++#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] -++#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] -++ -++#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] -++#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] -++ -++static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) -++{ -++ UInt32 price = 0; -++ symbol |= 0x100; -++ do -++ { -++ price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); -++ symbol <<= 1; -++ } -++ while (symbol < 0x10000); -++ return price; -++} -++ -++static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) -++{ -++ UInt32 price = 0; -++ UInt32 offs = 0x100; -++ symbol |= 0x100; -++ do -++ { -++ matchByte <<= 1; -++ price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); -++ symbol <<= 1; -++ offs &= ~(matchByte ^ symbol); -++ } -++ while (symbol < 0x10000); -++ return price; -++} -++ -++ -++static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -++{ -++ UInt32 m = 1; -++ int i; -++ for (i = numBitLevels; i != 0;) -++ { -++ UInt32 bit; -++ i--; -++ bit = (symbol >> i) & 1; -++ RangeEnc_EncodeBit(rc, probs + m, bit); -++ m = (m << 1) | bit; -++ } -++} -++ -++static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -++{ -++ UInt32 m = 1; -++ int i; -++ for (i = 0; i < numBitLevels; i++) -++ { -++ UInt32 bit = symbol & 1; -++ RangeEnc_EncodeBit(rc, probs + m, bit); -++ m = (m << 1) | bit; -++ symbol >>= 1; -++ } -++} -++ -++static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) -++{ -++ UInt32 price = 0; -++ symbol |= (1 << numBitLevels); -++ while (symbol != 1) -++ { -++ price += GET_PRICEa(probs[symbol >> 1], symbol & 1); -++ symbol >>= 1; -++ } -++ return price; -++} -++ -++static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) -++{ -++ UInt32 price = 0; -++ UInt32 m = 1; -++ int i; -++ for (i = numBitLevels; i != 0; i--) -++ { -++ UInt32 bit = symbol & 1; -++ symbol >>= 1; -++ price += GET_PRICEa(probs[m], bit); -++ m = (m << 1) | bit; -++ } -++ return price; -++} -++ -++ -++static void LenEnc_Init(CLenEnc *p) -++{ -++ unsigned i; -++ p->choice = p->choice2 = kProbInitValue; -++ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) -++ p->low[i] = kProbInitValue; -++ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) -++ p->mid[i] = kProbInitValue; -++ for (i = 0; i < kLenNumHighSymbols; i++) -++ p->high[i] = kProbInitValue; -++} -++ -++static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) -++{ -++ if (symbol < kLenNumLowSymbols) -++ { -++ RangeEnc_EncodeBit(rc, &p->choice, 0); -++ RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); -++ } -++ else -++ { -++ RangeEnc_EncodeBit(rc, &p->choice, 1); -++ if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) -++ { -++ RangeEnc_EncodeBit(rc, &p->choice2, 0); -++ RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); -++ } -++ else -++ { -++ RangeEnc_EncodeBit(rc, &p->choice2, 1); -++ RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); -++ } -++ } -++} -++ -++static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) -++{ -++ UInt32 a0 = GET_PRICE_0a(p->choice); -++ UInt32 a1 = GET_PRICE_1a(p->choice); -++ UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); -++ UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); -++ UInt32 i = 0; -++ for (i = 0; i < kLenNumLowSymbols; i++) -++ { -++ if (i >= numSymbols) -++ return; -++ prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); -++ } -++ for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) -++ { -++ if (i >= numSymbols) -++ return; -++ prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); -++ } -++ for (; i < numSymbols; i++) -++ prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); -++} -++ -++static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) -++{ -++ LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); -++ p->counters[posState] = p->tableSize; -++} -++ -++static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) -++{ -++ UInt32 posState; -++ for (posState = 0; posState < numPosStates; posState++) -++ LenPriceEnc_UpdateTable(p, posState, ProbPrices); -++} -++ -++static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) -++{ -++ LenEnc_Encode(&p->p, rc, symbol, posState); -++ if (updatePrice) -++ if (--p->counters[posState] == 0) -++ LenPriceEnc_UpdateTable(p, posState, ProbPrices); -++} -++ -++ -++ -++ -++static void MovePos(CLzmaEnc *p, UInt32 num) -++{ -++ #ifdef SHOW_STAT -++ ttt += num; -++ printf("\n MovePos %d", num); -++ #endif -++ if (num != 0) -++ { -++ p->additionalOffset += num; -++ p->matchFinder.Skip(p->matchFinderObj, num); -++ } -++} -++ -++static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) -++{ -++ UInt32 lenRes = 0, numPairs; -++ p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); -++ numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); -++ #ifdef SHOW_STAT -++ printf("\n i = %d numPairs = %d ", ttt, numPairs / 2); -++ ttt++; -++ { -++ UInt32 i; -++ for (i = 0; i < numPairs; i += 2) -++ printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); -++ } -++ #endif -++ if (numPairs > 0) -++ { -++ lenRes = p->matches[numPairs - 2]; -++ if (lenRes == p->numFastBytes) -++ { -++ const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -++ UInt32 distance = p->matches[numPairs - 1] + 1; -++ UInt32 numAvail = p->numAvail; -++ if (numAvail > LZMA_MATCH_LEN_MAX) -++ numAvail = LZMA_MATCH_LEN_MAX; -++ { -++ const Byte *pby2 = pby - distance; -++ for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); -++ } -++ } -++ } -++ p->additionalOffset++; -++ *numDistancePairsRes = numPairs; -++ return lenRes; -++} -++ -++ -++#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; -++#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; -++#define IsShortRep(p) ((p)->backPrev == 0) -++ -++static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) -++{ -++ return -++ GET_PRICE_0(p->isRepG0[state]) + -++ GET_PRICE_0(p->isRep0Long[state][posState]); -++} -++ -++static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) -++{ -++ UInt32 price; -++ if (repIndex == 0) -++ { -++ price = GET_PRICE_0(p->isRepG0[state]); -++ price += GET_PRICE_1(p->isRep0Long[state][posState]); -++ } -++ else -++ { -++ price = GET_PRICE_1(p->isRepG0[state]); -++ if (repIndex == 1) -++ price += GET_PRICE_0(p->isRepG1[state]); -++ else -++ { -++ price += GET_PRICE_1(p->isRepG1[state]); -++ price += GET_PRICE(p->isRepG2[state], repIndex - 2); -++ } -++ } -++ return price; -++} -++ -++static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) -++{ -++ return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + -++ GetPureRepPrice(p, repIndex, state, posState); -++} -++ -++static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) -++{ -++ UInt32 posMem = p->opt[cur].posPrev; -++ UInt32 backMem = p->opt[cur].backPrev; -++ p->optimumEndIndex = cur; -++ do -++ { -++ if (p->opt[cur].prev1IsChar) -++ { -++ MakeAsChar(&p->opt[posMem]) -++ p->opt[posMem].posPrev = posMem - 1; -++ if (p->opt[cur].prev2) -++ { -++ p->opt[posMem - 1].prev1IsChar = False; -++ p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; -++ p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; -++ } -++ } -++ { -++ UInt32 posPrev = posMem; -++ UInt32 backCur = backMem; -++ -++ backMem = p->opt[posPrev].backPrev; -++ posMem = p->opt[posPrev].posPrev; -++ -++ p->opt[posPrev].backPrev = backCur; -++ p->opt[posPrev].posPrev = cur; -++ cur = posPrev; -++ } -++ } -++ while (cur != 0); -++ *backRes = p->opt[0].backPrev; -++ p->optimumCurrentIndex = p->opt[0].posPrev; -++ return p->optimumCurrentIndex; -++} -++ -++#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) -++ -++static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) -++{ -++ UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur; -++ UInt32 matchPrice, repMatchPrice, normalMatchPrice; -++ UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; -++ UInt32 *matches; -++ const Byte *data; -++ Byte curByte, matchByte; -++ if (p->optimumEndIndex != p->optimumCurrentIndex) -++ { -++ const COptimal *opt = &p->opt[p->optimumCurrentIndex]; -++ UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; -++ *backRes = opt->backPrev; -++ p->optimumCurrentIndex = opt->posPrev; -++ return lenRes; -++ } -++ p->optimumCurrentIndex = p->optimumEndIndex = 0; -++ -++ if (p->additionalOffset == 0) -++ mainLen = ReadMatchDistances(p, &numPairs); -++ else -++ { -++ mainLen = p->longestMatchLength; -++ numPairs = p->numPairs; -++ } -++ -++ numAvail = p->numAvail; -++ if (numAvail < 2) -++ { -++ *backRes = (UInt32)(-1); -++ return 1; -++ } -++ if (numAvail > LZMA_MATCH_LEN_MAX) -++ numAvail = LZMA_MATCH_LEN_MAX; -++ -++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -++ repMaxIndex = 0; -++ for (i = 0; i < LZMA_NUM_REPS; i++) -++ { -++ UInt32 lenTest; -++ const Byte *data2; -++ reps[i] = p->reps[i]; -++ data2 = data - (reps[i] + 1); -++ if (data[0] != data2[0] || data[1] != data2[1]) -++ { -++ repLens[i] = 0; -++ continue; -++ } -++ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); -++ repLens[i] = lenTest; -++ if (lenTest > repLens[repMaxIndex]) -++ repMaxIndex = i; -++ } -++ if (repLens[repMaxIndex] >= p->numFastBytes) -++ { -++ UInt32 lenRes; -++ *backRes = repMaxIndex; -++ lenRes = repLens[repMaxIndex]; -++ MovePos(p, lenRes - 1); -++ return lenRes; -++ } -++ -++ matches = p->matches; -++ if (mainLen >= p->numFastBytes) -++ { -++ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; -++ MovePos(p, mainLen - 1); -++ return mainLen; -++ } -++ curByte = *data; -++ matchByte = *(data - (reps[0] + 1)); -++ -++ if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2) -++ { -++ *backRes = (UInt32)-1; -++ return 1; -++ } -++ -++ p->opt[0].state = (CState)p->state; -++ -++ posState = (position & p->pbMask); -++ -++ { -++ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); -++ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + -++ (!IsCharState(p->state) ? -++ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : -++ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); -++ } -++ -++ MakeAsChar(&p->opt[1]); -++ -++ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); -++ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); -++ -++ if (matchByte == curByte) -++ { -++ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); -++ if (shortRepPrice < p->opt[1].price) -++ { -++ p->opt[1].price = shortRepPrice; -++ MakeAsShortRep(&p->opt[1]); -++ } -++ } -++ lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]); -++ -++ if (lenEnd < 2) -++ { -++ *backRes = p->opt[1].backPrev; -++ return 1; -++ } -++ -++ p->opt[1].posPrev = 0; -++ for (i = 0; i < LZMA_NUM_REPS; i++) -++ p->opt[0].backs[i] = reps[i]; -++ -++ len = lenEnd; -++ do -++ p->opt[len--].price = kInfinityPrice; -++ while (len >= 2); -++ -++ for (i = 0; i < LZMA_NUM_REPS; i++) -++ { -++ UInt32 repLen = repLens[i]; -++ UInt32 price; -++ if (repLen < 2) -++ continue; -++ price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); -++ do -++ { -++ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; -++ COptimal *opt = &p->opt[repLen]; -++ if (curAndLenPrice < opt->price) -++ { -++ opt->price = curAndLenPrice; -++ opt->posPrev = 0; -++ opt->backPrev = i; -++ opt->prev1IsChar = False; -++ } -++ } -++ while (--repLen >= 2); -++ } -++ -++ normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); -++ -++ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); -++ if (len <= mainLen) -++ { -++ UInt32 offs = 0; -++ while (len > matches[offs]) -++ offs += 2; -++ for (; ; len++) -++ { -++ COptimal *opt; -++ UInt32 distance = matches[offs + 1]; -++ -++ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; -++ UInt32 lenToPosState = GetLenToPosState(len); -++ if (distance < kNumFullDistances) -++ curAndLenPrice += p->distancesPrices[lenToPosState][distance]; -++ else -++ { -++ UInt32 slot; -++ GetPosSlot2(distance, slot); -++ curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; -++ } -++ opt = &p->opt[len]; -++ if (curAndLenPrice < opt->price) -++ { -++ opt->price = curAndLenPrice; -++ opt->posPrev = 0; -++ opt->backPrev = distance + LZMA_NUM_REPS; -++ opt->prev1IsChar = False; -++ } -++ if (len == matches[offs]) -++ { -++ offs += 2; -++ if (offs == numPairs) -++ break; -++ } -++ } -++ } -++ -++ cur = 0; -++ -++ #ifdef SHOW_STAT2 -++ if (position >= 0) -++ { -++ unsigned i; -++ printf("\n pos = %4X", position); -++ for (i = cur; i <= lenEnd; i++) -++ printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); -++ } -++ #endif -++ -++ for (;;) -++ { -++ UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; -++ UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; -++ Bool nextIsChar; -++ Byte curByte, matchByte; -++ const Byte *data; -++ COptimal *curOpt; -++ COptimal *nextOpt; -++ -++ cur++; -++ if (cur == lenEnd) -++ return Backward(p, backRes, cur); -++ -++ newLen = ReadMatchDistances(p, &numPairs); -++ if (newLen >= p->numFastBytes) -++ { -++ p->numPairs = numPairs; -++ p->longestMatchLength = newLen; -++ return Backward(p, backRes, cur); -++ } -++ position++; -++ curOpt = &p->opt[cur]; -++ posPrev = curOpt->posPrev; -++ if (curOpt->prev1IsChar) -++ { -++ posPrev--; -++ if (curOpt->prev2) -++ { -++ state = p->opt[curOpt->posPrev2].state; -++ if (curOpt->backPrev2 < LZMA_NUM_REPS) -++ state = kRepNextStates[state]; -++ else -++ state = kMatchNextStates[state]; -++ } -++ else -++ state = p->opt[posPrev].state; -++ state = kLiteralNextStates[state]; -++ } -++ else -++ state = p->opt[posPrev].state; -++ if (posPrev == cur - 1) -++ { -++ if (IsShortRep(curOpt)) -++ state = kShortRepNextStates[state]; -++ else -++ state = kLiteralNextStates[state]; -++ } -++ else -++ { -++ UInt32 pos; -++ const COptimal *prevOpt; -++ if (curOpt->prev1IsChar && curOpt->prev2) -++ { -++ posPrev = curOpt->posPrev2; -++ pos = curOpt->backPrev2; -++ state = kRepNextStates[state]; -++ } -++ else -++ { -++ pos = curOpt->backPrev; -++ if (pos < LZMA_NUM_REPS) -++ state = kRepNextStates[state]; -++ else -++ state = kMatchNextStates[state]; -++ } -++ prevOpt = &p->opt[posPrev]; -++ if (pos < LZMA_NUM_REPS) -++ { -++ UInt32 i; -++ reps[0] = prevOpt->backs[pos]; -++ for (i = 1; i <= pos; i++) -++ reps[i] = prevOpt->backs[i - 1]; -++ for (; i < LZMA_NUM_REPS; i++) -++ reps[i] = prevOpt->backs[i]; -++ } -++ else -++ { -++ UInt32 i; -++ reps[0] = (pos - LZMA_NUM_REPS); -++ for (i = 1; i < LZMA_NUM_REPS; i++) -++ reps[i] = prevOpt->backs[i - 1]; -++ } -++ } -++ curOpt->state = (CState)state; -++ -++ curOpt->backs[0] = reps[0]; -++ curOpt->backs[1] = reps[1]; -++ curOpt->backs[2] = reps[2]; -++ curOpt->backs[3] = reps[3]; -++ -++ curPrice = curOpt->price; -++ nextIsChar = False; -++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -++ curByte = *data; -++ matchByte = *(data - (reps[0] + 1)); -++ -++ posState = (position & p->pbMask); -++ -++ curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); -++ { -++ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); -++ curAnd1Price += -++ (!IsCharState(state) ? -++ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : -++ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); -++ } -++ -++ nextOpt = &p->opt[cur + 1]; -++ -++ if (curAnd1Price < nextOpt->price) -++ { -++ nextOpt->price = curAnd1Price; -++ nextOpt->posPrev = cur; -++ MakeAsChar(nextOpt); -++ nextIsChar = True; -++ } -++ -++ matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); -++ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); -++ -++ if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) -++ { -++ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); -++ if (shortRepPrice <= nextOpt->price) -++ { -++ nextOpt->price = shortRepPrice; -++ nextOpt->posPrev = cur; -++ MakeAsShortRep(nextOpt); -++ nextIsChar = True; -++ } -++ } -++ numAvailFull = p->numAvail; -++ { -++ UInt32 temp = kNumOpts - 1 - cur; -++ if (temp < numAvailFull) -++ numAvailFull = temp; -++ } -++ -++ if (numAvailFull < 2) -++ continue; -++ numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); -++ -++ if (!nextIsChar && matchByte != curByte) /* speed optimization */ -++ { -++ /* try Literal + rep0 */ -++ UInt32 temp; -++ UInt32 lenTest2; -++ const Byte *data2 = data - (reps[0] + 1); -++ UInt32 limit = p->numFastBytes + 1; -++ if (limit > numAvailFull) -++ limit = numAvailFull; -++ -++ for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); -++ lenTest2 = temp - 1; -++ if (lenTest2 >= 2) -++ { -++ UInt32 state2 = kLiteralNextStates[state]; -++ UInt32 posStateNext = (position + 1) & p->pbMask; -++ UInt32 nextRepMatchPrice = curAnd1Price + -++ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -++ GET_PRICE_1(p->isRep[state2]); -++ /* for (; lenTest2 >= 2; lenTest2--) */ -++ { -++ UInt32 curAndLenPrice; -++ COptimal *opt; -++ UInt32 offset = cur + 1 + lenTest2; -++ while (lenEnd < offset) -++ p->opt[++lenEnd].price = kInfinityPrice; -++ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -++ opt = &p->opt[offset]; -++ if (curAndLenPrice < opt->price) -++ { -++ opt->price = curAndLenPrice; -++ opt->posPrev = cur + 1; -++ opt->backPrev = 0; -++ opt->prev1IsChar = True; -++ opt->prev2 = False; -++ } -++ } -++ } -++ } -++ -++ startLen = 2; /* speed optimization */ -++ { -++ UInt32 repIndex; -++ for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) -++ { -++ UInt32 lenTest; -++ UInt32 lenTestTemp; -++ UInt32 price; -++ const Byte *data2 = data - (reps[repIndex] + 1); -++ if (data[0] != data2[0] || data[1] != data2[1]) -++ continue; -++ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); -++ while (lenEnd < cur + lenTest) -++ p->opt[++lenEnd].price = kInfinityPrice; -++ lenTestTemp = lenTest; -++ price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); -++ do -++ { -++ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; -++ COptimal *opt = &p->opt[cur + lenTest]; -++ if (curAndLenPrice < opt->price) -++ { -++ opt->price = curAndLenPrice; -++ opt->posPrev = cur; -++ opt->backPrev = repIndex; -++ opt->prev1IsChar = False; -++ } -++ } -++ while (--lenTest >= 2); -++ lenTest = lenTestTemp; -++ -++ if (repIndex == 0) -++ startLen = lenTest + 1; -++ -++ /* if (_maxMode) */ -++ { -++ UInt32 lenTest2 = lenTest + 1; -++ UInt32 limit = lenTest2 + p->numFastBytes; -++ UInt32 nextRepMatchPrice; -++ if (limit > numAvailFull) -++ limit = numAvailFull; -++ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); -++ lenTest2 -= lenTest + 1; -++ if (lenTest2 >= 2) -++ { -++ UInt32 state2 = kRepNextStates[state]; -++ UInt32 posStateNext = (position + lenTest) & p->pbMask; -++ UInt32 curAndLenCharPrice = -++ price + p->repLenEnc.prices[posState][lenTest - 2] + -++ GET_PRICE_0(p->isMatch[state2][posStateNext]) + -++ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), -++ data[lenTest], data2[lenTest], p->ProbPrices); -++ state2 = kLiteralNextStates[state2]; -++ posStateNext = (position + lenTest + 1) & p->pbMask; -++ nextRepMatchPrice = curAndLenCharPrice + -++ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -++ GET_PRICE_1(p->isRep[state2]); -++ -++ /* for (; lenTest2 >= 2; lenTest2--) */ -++ { -++ UInt32 curAndLenPrice; -++ COptimal *opt; -++ UInt32 offset = cur + lenTest + 1 + lenTest2; -++ while (lenEnd < offset) -++ p->opt[++lenEnd].price = kInfinityPrice; -++ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -++ opt = &p->opt[offset]; -++ if (curAndLenPrice < opt->price) -++ { -++ opt->price = curAndLenPrice; -++ opt->posPrev = cur + lenTest + 1; -++ opt->backPrev = 0; -++ opt->prev1IsChar = True; -++ opt->prev2 = True; -++ opt->posPrev2 = cur; -++ opt->backPrev2 = repIndex; -++ } -++ } -++ } -++ } -++ } -++ } -++ /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ -++ if (newLen > numAvail) -++ { -++ newLen = numAvail; -++ for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); -++ matches[numPairs] = newLen; -++ numPairs += 2; -++ } -++ if (newLen >= startLen) -++ { -++ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); -++ UInt32 offs, curBack, posSlot; -++ UInt32 lenTest; -++ while (lenEnd < cur + newLen) -++ p->opt[++lenEnd].price = kInfinityPrice; -++ -++ offs = 0; -++ while (startLen > matches[offs]) -++ offs += 2; -++ curBack = matches[offs + 1]; -++ GetPosSlot2(curBack, posSlot); -++ for (lenTest = /*2*/ startLen; ; lenTest++) -++ { -++ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; -++ UInt32 lenToPosState = GetLenToPosState(lenTest); -++ COptimal *opt; -++ if (curBack < kNumFullDistances) -++ curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; -++ else -++ curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; -++ -++ opt = &p->opt[cur + lenTest]; -++ if (curAndLenPrice < opt->price) -++ { -++ opt->price = curAndLenPrice; -++ opt->posPrev = cur; -++ opt->backPrev = curBack + LZMA_NUM_REPS; -++ opt->prev1IsChar = False; -++ } -++ -++ if (/*_maxMode && */lenTest == matches[offs]) -++ { -++ /* Try Match + Literal + Rep0 */ -++ const Byte *data2 = data - (curBack + 1); -++ UInt32 lenTest2 = lenTest + 1; -++ UInt32 limit = lenTest2 + p->numFastBytes; -++ UInt32 nextRepMatchPrice; -++ if (limit > numAvailFull) -++ limit = numAvailFull; -++ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); -++ lenTest2 -= lenTest + 1; -++ if (lenTest2 >= 2) -++ { -++ UInt32 state2 = kMatchNextStates[state]; -++ UInt32 posStateNext = (position + lenTest) & p->pbMask; -++ UInt32 curAndLenCharPrice = curAndLenPrice + -++ GET_PRICE_0(p->isMatch[state2][posStateNext]) + -++ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), -++ data[lenTest], data2[lenTest], p->ProbPrices); -++ state2 = kLiteralNextStates[state2]; -++ posStateNext = (posStateNext + 1) & p->pbMask; -++ nextRepMatchPrice = curAndLenCharPrice + -++ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -++ GET_PRICE_1(p->isRep[state2]); -++ -++ /* for (; lenTest2 >= 2; lenTest2--) */ -++ { -++ UInt32 offset = cur + lenTest + 1 + lenTest2; -++ UInt32 curAndLenPrice; -++ COptimal *opt; -++ while (lenEnd < offset) -++ p->opt[++lenEnd].price = kInfinityPrice; -++ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -++ opt = &p->opt[offset]; -++ if (curAndLenPrice < opt->price) -++ { -++ opt->price = curAndLenPrice; -++ opt->posPrev = cur + lenTest + 1; -++ opt->backPrev = 0; -++ opt->prev1IsChar = True; -++ opt->prev2 = True; -++ opt->posPrev2 = cur; -++ opt->backPrev2 = curBack + LZMA_NUM_REPS; -++ } -++ } -++ } -++ offs += 2; -++ if (offs == numPairs) -++ break; -++ curBack = matches[offs + 1]; -++ if (curBack >= kNumFullDistances) -++ GetPosSlot2(curBack, posSlot); -++ } -++ } -++ } -++ } -++} -++ -++#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) -++ -++static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) -++{ -++ UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i; -++ const Byte *data; -++ const UInt32 *matches; -++ -++ if (p->additionalOffset == 0) -++ mainLen = ReadMatchDistances(p, &numPairs); -++ else -++ { -++ mainLen = p->longestMatchLength; -++ numPairs = p->numPairs; -++ } -++ -++ numAvail = p->numAvail; -++ *backRes = (UInt32)-1; -++ if (numAvail < 2) -++ return 1; -++ if (numAvail > LZMA_MATCH_LEN_MAX) -++ numAvail = LZMA_MATCH_LEN_MAX; -++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -++ -++ repLen = repIndex = 0; -++ for (i = 0; i < LZMA_NUM_REPS; i++) -++ { -++ UInt32 len; -++ const Byte *data2 = data - (p->reps[i] + 1); -++ if (data[0] != data2[0] || data[1] != data2[1]) -++ continue; -++ for (len = 2; len < numAvail && data[len] == data2[len]; len++); -++ if (len >= p->numFastBytes) -++ { -++ *backRes = i; -++ MovePos(p, len - 1); -++ return len; -++ } -++ if (len > repLen) -++ { -++ repIndex = i; -++ repLen = len; -++ } -++ } -++ -++ matches = p->matches; -++ if (mainLen >= p->numFastBytes) -++ { -++ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; -++ MovePos(p, mainLen - 1); -++ return mainLen; -++ } -++ -++ mainDist = 0; /* for GCC */ -++ if (mainLen >= 2) -++ { -++ mainDist = matches[numPairs - 1]; -++ while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) -++ { -++ if (!ChangePair(matches[numPairs - 3], mainDist)) -++ break; -++ numPairs -= 2; -++ mainLen = matches[numPairs - 2]; -++ mainDist = matches[numPairs - 1]; -++ } -++ if (mainLen == 2 && mainDist >= 0x80) -++ mainLen = 1; -++ } -++ -++ if (repLen >= 2 && ( -++ (repLen + 1 >= mainLen) || -++ (repLen + 2 >= mainLen && mainDist >= (1 << 9)) || -++ (repLen + 3 >= mainLen && mainDist >= (1 << 15)))) -++ { -++ *backRes = repIndex; -++ MovePos(p, repLen - 1); -++ return repLen; -++ } -++ -++ if (mainLen < 2 || numAvail <= 2) -++ return 1; -++ -++ p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); -++ if (p->longestMatchLength >= 2) -++ { -++ UInt32 newDistance = matches[p->numPairs - 1]; -++ if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || -++ (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || -++ (p->longestMatchLength > mainLen + 1) || -++ (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) -++ return 1; -++ } -++ -++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -++ for (i = 0; i < LZMA_NUM_REPS; i++) -++ { -++ UInt32 len, limit; -++ const Byte *data2 = data - (p->reps[i] + 1); -++ if (data[0] != data2[0] || data[1] != data2[1]) -++ continue; -++ limit = mainLen - 1; -++ for (len = 2; len < limit && data[len] == data2[len]; len++); -++ if (len >= limit) -++ return 1; -++ } -++ *backRes = mainDist + LZMA_NUM_REPS; -++ MovePos(p, mainLen - 2); -++ return mainLen; -++} -++ -++static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) -++{ -++ UInt32 len; -++ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); -++ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); -++ p->state = kMatchNextStates[p->state]; -++ len = LZMA_MATCH_LEN_MIN; -++ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -++ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); -++ RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); -++ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); -++} -++ -++static SRes CheckErrors(CLzmaEnc *p) -++{ -++ if (p->result != SZ_OK) -++ return p->result; -++ if (p->rc.res != SZ_OK) -++ p->result = SZ_ERROR_WRITE; -++ if (p->matchFinderBase.result != SZ_OK) -++ p->result = SZ_ERROR_READ; -++ if (p->result != SZ_OK) -++ p->finished = True; -++ return p->result; -++} -++ -++static SRes Flush(CLzmaEnc *p, UInt32 nowPos) -++{ -++ /* ReleaseMFStream(); */ -++ p->finished = True; -++ if (p->writeEndMark) -++ WriteEndMarker(p, nowPos & p->pbMask); -++ RangeEnc_FlushData(&p->rc); -++ RangeEnc_FlushStream(&p->rc); -++ return CheckErrors(p); -++} -++ -++static void FillAlignPrices(CLzmaEnc *p) -++{ -++ UInt32 i; -++ for (i = 0; i < kAlignTableSize; i++) -++ p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); -++ p->alignPriceCount = 0; -++} -++ -++static void FillDistancesPrices(CLzmaEnc *p) -++{ -++ UInt32 tempPrices[kNumFullDistances]; -++ UInt32 i, lenToPosState; -++ for (i = kStartPosModelIndex; i < kNumFullDistances; i++) -++ { -++ UInt32 posSlot = GetPosSlot1(i); -++ UInt32 footerBits = ((posSlot >> 1) - 1); -++ UInt32 base = ((2 | (posSlot & 1)) << footerBits); -++ tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); -++ } -++ -++ for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) -++ { -++ UInt32 posSlot; -++ const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; -++ UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; -++ for (posSlot = 0; posSlot < p->distTableSize; posSlot++) -++ posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); -++ for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) -++ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); -++ -++ { -++ UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; -++ UInt32 i; -++ for (i = 0; i < kStartPosModelIndex; i++) -++ distancesPrices[i] = posSlotPrices[i]; -++ for (; i < kNumFullDistances; i++) -++ distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; -++ } -++ } -++ p->matchPriceCount = 0; -++} -++ -++void LzmaEnc_Construct(CLzmaEnc *p) -++{ -++ RangeEnc_Construct(&p->rc); -++ MatchFinder_Construct(&p->matchFinderBase); -++ #ifndef _7ZIP_ST -++ MatchFinderMt_Construct(&p->matchFinderMt); -++ p->matchFinderMt.MatchFinder = &p->matchFinderBase; -++ #endif -++ -++ { -++ CLzmaEncProps props; -++ LzmaEncProps_Init(&props); -++ LzmaEnc_SetProps(p, &props); -++ } -++ -++ #ifndef LZMA_LOG_BSR -++ LzmaEnc_FastPosInit(p->g_FastPos); -++ #endif -++ -++ LzmaEnc_InitPriceTables(p->ProbPrices); -++ p->litProbs = 0; -++ p->saveState.litProbs = 0; -++} -++ -++CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) -++{ -++ void *p; -++ p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); -++ if (p != 0) -++ LzmaEnc_Construct((CLzmaEnc *)p); -++ return p; -++} -++ -++void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) -++{ -++ alloc->Free(alloc, p->litProbs); -++ alloc->Free(alloc, p->saveState.litProbs); -++ p->litProbs = 0; -++ p->saveState.litProbs = 0; -++} -++ -++void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) -++{ -++ #ifndef _7ZIP_ST -++ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); -++ #endif -++ MatchFinder_Free(&p->matchFinderBase, allocBig); -++ LzmaEnc_FreeLits(p, alloc); -++ RangeEnc_Free(&p->rc, alloc); -++} -++ -++void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) -++{ -++ LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); -++ alloc->Free(alloc, p); -++} -++ -++static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) -++{ -++ UInt32 nowPos32, startPos32; -++ if (p->needInit) -++ { -++ p->matchFinder.Init(p->matchFinderObj); -++ p->needInit = 0; -++ } -++ -++ if (p->finished) -++ return p->result; -++ RINOK(CheckErrors(p)); -++ -++ nowPos32 = (UInt32)p->nowPos64; -++ startPos32 = nowPos32; -++ -++ if (p->nowPos64 == 0) -++ { -++ UInt32 numPairs; -++ Byte curByte; -++ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) -++ return Flush(p, nowPos32); -++ ReadMatchDistances(p, &numPairs); -++ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); -++ p->state = kLiteralNextStates[p->state]; -++ curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); -++ LitEnc_Encode(&p->rc, p->litProbs, curByte); -++ p->additionalOffset--; -++ nowPos32++; -++ } -++ -++ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) -++ for (;;) -++ { -++ UInt32 pos, len, posState; -++ -++ if (p->fastMode) -++ len = GetOptimumFast(p, &pos); -++ else -++ len = GetOptimum(p, nowPos32, &pos); -++ -++ #ifdef SHOW_STAT2 -++ printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); -++ #endif -++ -++ posState = nowPos32 & p->pbMask; -++ if (len == 1 && pos == (UInt32)-1) -++ { -++ Byte curByte; -++ CLzmaProb *probs; -++ const Byte *data; -++ -++ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); -++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; -++ curByte = *data; -++ probs = LIT_PROBS(nowPos32, *(data - 1)); -++ if (IsCharState(p->state)) -++ LitEnc_Encode(&p->rc, probs, curByte); -++ else -++ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); -++ p->state = kLiteralNextStates[p->state]; -++ } -++ else -++ { -++ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); -++ if (pos < LZMA_NUM_REPS) -++ { -++ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); -++ if (pos == 0) -++ { -++ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); -++ RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); -++ } -++ else -++ { -++ UInt32 distance = p->reps[pos]; -++ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); -++ if (pos == 1) -++ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); -++ else -++ { -++ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); -++ RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); -++ if (pos == 3) -++ p->reps[3] = p->reps[2]; -++ p->reps[2] = p->reps[1]; -++ } -++ p->reps[1] = p->reps[0]; -++ p->reps[0] = distance; -++ } -++ if (len == 1) -++ p->state = kShortRepNextStates[p->state]; -++ else -++ { -++ LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -++ p->state = kRepNextStates[p->state]; -++ } -++ } -++ else -++ { -++ UInt32 posSlot; -++ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); -++ p->state = kMatchNextStates[p->state]; -++ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -++ pos -= LZMA_NUM_REPS; -++ GetPosSlot(pos, posSlot); -++ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); -++ -++ if (posSlot >= kStartPosModelIndex) -++ { -++ UInt32 footerBits = ((posSlot >> 1) - 1); -++ UInt32 base = ((2 | (posSlot & 1)) << footerBits); -++ UInt32 posReduced = pos - base; -++ -++ if (posSlot < kEndPosModelIndex) -++ RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); -++ else -++ { -++ RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); -++ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); -++ p->alignPriceCount++; -++ } -++ } -++ p->reps[3] = p->reps[2]; -++ p->reps[2] = p->reps[1]; -++ p->reps[1] = p->reps[0]; -++ p->reps[0] = pos; -++ p->matchPriceCount++; -++ } -++ } -++ p->additionalOffset -= len; -++ nowPos32 += len; -++ if (p->additionalOffset == 0) -++ { -++ UInt32 processed; -++ if (!p->fastMode) -++ { -++ if (p->matchPriceCount >= (1 << 7)) -++ FillDistancesPrices(p); -++ if (p->alignPriceCount >= kAlignTableSize) -++ FillAlignPrices(p); -++ } -++ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) -++ break; -++ processed = nowPos32 - startPos32; -++ if (useLimits) -++ { -++ if (processed + kNumOpts + 300 >= maxUnpackSize || -++ RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) -++ break; -++ } -++ else if (processed >= (1 << 15)) -++ { -++ p->nowPos64 += nowPos32 - startPos32; -++ return CheckErrors(p); -++ } -++ } -++ } -++ p->nowPos64 += nowPos32 - startPos32; -++ return Flush(p, nowPos32); -++} -++ -++#define kBigHashDicLimit ((UInt32)1 << 24) -++ -++static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -++{ -++ UInt32 beforeSize = kNumOpts; -++ Bool btMode; -++ if (!RangeEnc_Alloc(&p->rc, alloc)) -++ return SZ_ERROR_MEM; -++ btMode = (p->matchFinderBase.btMode != 0); -++ #ifndef _7ZIP_ST -++ p->mtMode = (p->multiThread && !p->fastMode && btMode); -++ #endif -++ -++ { -++ unsigned lclp = p->lc + p->lp; -++ if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) -++ { -++ LzmaEnc_FreeLits(p, alloc); -++ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); -++ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); -++ if (p->litProbs == 0 || p->saveState.litProbs == 0) -++ { -++ LzmaEnc_FreeLits(p, alloc); -++ return SZ_ERROR_MEM; -++ } -++ p->lclp = lclp; -++ } -++ } -++ -++ p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); -++ -++ if (beforeSize + p->dictSize < keepWindowSize) -++ beforeSize = keepWindowSize - p->dictSize; -++ -++ #ifndef _7ZIP_ST -++ if (p->mtMode) -++ { -++ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); -++ p->matchFinderObj = &p->matchFinderMt; -++ MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); -++ } -++ else -++ #endif -++ { -++ if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) -++ return SZ_ERROR_MEM; -++ p->matchFinderObj = &p->matchFinderBase; -++ MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); -++ } -++ return SZ_OK; -++} -++ -++void LzmaEnc_Init(CLzmaEnc *p) -++{ -++ UInt32 i; -++ p->state = 0; -++ for (i = 0 ; i < LZMA_NUM_REPS; i++) -++ p->reps[i] = 0; -++ -++ RangeEnc_Init(&p->rc); -++ -++ -++ for (i = 0; i < kNumStates; i++) -++ { -++ UInt32 j; -++ for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) -++ { -++ p->isMatch[i][j] = kProbInitValue; -++ p->isRep0Long[i][j] = kProbInitValue; -++ } -++ p->isRep[i] = kProbInitValue; -++ p->isRepG0[i] = kProbInitValue; -++ p->isRepG1[i] = kProbInitValue; -++ p->isRepG2[i] = kProbInitValue; -++ } -++ -++ { -++ UInt32 num = 0x300 << (p->lp + p->lc); -++ for (i = 0; i < num; i++) -++ p->litProbs[i] = kProbInitValue; -++ } -++ -++ { -++ for (i = 0; i < kNumLenToPosStates; i++) -++ { -++ CLzmaProb *probs = p->posSlotEncoder[i]; -++ UInt32 j; -++ for (j = 0; j < (1 << kNumPosSlotBits); j++) -++ probs[j] = kProbInitValue; -++ } -++ } -++ { -++ for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) -++ p->posEncoders[i] = kProbInitValue; -++ } -++ -++ LenEnc_Init(&p->lenEnc.p); -++ LenEnc_Init(&p->repLenEnc.p); -++ -++ for (i = 0; i < (1 << kNumAlignBits); i++) -++ p->posAlignEncoder[i] = kProbInitValue; -++ -++ p->optimumEndIndex = 0; -++ p->optimumCurrentIndex = 0; -++ p->additionalOffset = 0; -++ -++ p->pbMask = (1 << p->pb) - 1; -++ p->lpMask = (1 << p->lp) - 1; -++} -++ -++void LzmaEnc_InitPrices(CLzmaEnc *p) -++{ -++ if (!p->fastMode) -++ { -++ FillDistancesPrices(p); -++ FillAlignPrices(p); -++ } -++ -++ p->lenEnc.tableSize = -++ p->repLenEnc.tableSize = -++ p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; -++ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); -++ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); -++} -++ -++static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -++{ -++ UInt32 i; -++ for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) -++ if (p->dictSize <= ((UInt32)1 << i)) -++ break; -++ p->distTableSize = i * 2; -++ -++ p->finished = False; -++ p->result = SZ_OK; -++ RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); -++ LzmaEnc_Init(p); -++ LzmaEnc_InitPrices(p); -++ p->nowPos64 = 0; -++ return SZ_OK; -++} -++ -++static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, -++ ISzAlloc *alloc, ISzAlloc *allocBig) -++{ -++ CLzmaEnc *p = (CLzmaEnc *)pp; -++ p->matchFinderBase.stream = inStream; -++ p->needInit = 1; -++ p->rc.outStream = outStream; -++ return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); -++} -++ -++SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, -++ ISeqInStream *inStream, UInt32 keepWindowSize, -++ ISzAlloc *alloc, ISzAlloc *allocBig) -++{ -++ CLzmaEnc *p = (CLzmaEnc *)pp; -++ p->matchFinderBase.stream = inStream; -++ p->needInit = 1; -++ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -++} -++ -++static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) -++{ -++ p->matchFinderBase.directInput = 1; -++ p->matchFinderBase.bufferBase = (Byte *)src; -++ p->matchFinderBase.directInputRem = srcLen; -++} -++ -++SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, -++ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -++{ -++ CLzmaEnc *p = (CLzmaEnc *)pp; -++ LzmaEnc_SetInputBuf(p, src, srcLen); -++ p->needInit = 1; -++ -++ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -++} -++ -++void LzmaEnc_Finish(CLzmaEncHandle pp) -++{ -++ #ifndef _7ZIP_ST -++ CLzmaEnc *p = (CLzmaEnc *)pp; -++ if (p->mtMode) -++ MatchFinderMt_ReleaseStream(&p->matchFinderMt); -++ #else -++ pp = pp; -++ #endif -++} -++ -++typedef struct -++{ -++ ISeqOutStream funcTable; -++ Byte *data; -++ SizeT rem; -++ Bool overflow; -++} CSeqOutStreamBuf; -++ -++static size_t MyWrite(void *pp, const void *data, size_t size) -++{ -++ CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; -++ if (p->rem < size) -++ { -++ size = p->rem; -++ p->overflow = True; -++ } -++ memcpy(p->data, data, size); -++ p->rem -= size; -++ p->data += size; -++ return size; -++} -++ -++ -++UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) -++{ -++ const CLzmaEnc *p = (CLzmaEnc *)pp; -++ return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); -++} -++ -++const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) -++{ -++ const CLzmaEnc *p = (CLzmaEnc *)pp; -++ return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; -++} -++ -++SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, -++ Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) -++{ -++ CLzmaEnc *p = (CLzmaEnc *)pp; -++ UInt64 nowPos64; -++ SRes res; -++ CSeqOutStreamBuf outStream; -++ -++ outStream.funcTable.Write = MyWrite; -++ outStream.data = dest; -++ outStream.rem = *destLen; -++ outStream.overflow = False; -++ -++ p->writeEndMark = False; -++ p->finished = False; -++ p->result = SZ_OK; -++ -++ if (reInit) -++ LzmaEnc_Init(p); -++ LzmaEnc_InitPrices(p); -++ nowPos64 = p->nowPos64; -++ RangeEnc_Init(&p->rc); -++ p->rc.outStream = &outStream.funcTable; -++ -++ res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); -++ -++ *unpackSize = (UInt32)(p->nowPos64 - nowPos64); -++ *destLen -= outStream.rem; -++ if (outStream.overflow) -++ return SZ_ERROR_OUTPUT_EOF; -++ -++ return res; -++} -++ -++static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) -++{ -++ SRes res = SZ_OK; -++ -++ #ifndef _7ZIP_ST -++ Byte allocaDummy[0x300]; -++ int i = 0; -++ for (i = 0; i < 16; i++) -++ allocaDummy[i] = (Byte)i; -++ #endif -++ -++ for (;;) -++ { -++ res = LzmaEnc_CodeOneBlock(p, False, 0, 0); -++ if (res != SZ_OK || p->finished != 0) -++ break; -++ if (progress != 0) -++ { -++ res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); -++ if (res != SZ_OK) -++ { -++ res = SZ_ERROR_PROGRESS; -++ break; -++ } -++ } -++ } -++ LzmaEnc_Finish(p); -++ return res; -++} -++ -++SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, -++ ISzAlloc *alloc, ISzAlloc *allocBig) -++{ -++ RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); -++ return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); -++} -++ -++SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) -++{ -++ CLzmaEnc *p = (CLzmaEnc *)pp; -++ int i; -++ UInt32 dictSize = p->dictSize; -++ if (*size < LZMA_PROPS_SIZE) -++ return SZ_ERROR_PARAM; -++ *size = LZMA_PROPS_SIZE; -++ props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); -++ -++ for (i = 11; i <= 30; i++) -++ { -++ if (dictSize <= ((UInt32)2 << i)) -++ { -++ dictSize = (2 << i); -++ break; -++ } -++ if (dictSize <= ((UInt32)3 << i)) -++ { -++ dictSize = (3 << i); -++ break; -++ } -++ } -++ -++ for (i = 0; i < 4; i++) -++ props[1 + i] = (Byte)(dictSize >> (8 * i)); -++ return SZ_OK; -++} -++ -++SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -++ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) -++{ -++ SRes res; -++ CLzmaEnc *p = (CLzmaEnc *)pp; -++ -++ CSeqOutStreamBuf outStream; -++ -++ LzmaEnc_SetInputBuf(p, src, srcLen); -++ -++ outStream.funcTable.Write = MyWrite; -++ outStream.data = dest; -++ outStream.rem = *destLen; -++ outStream.overflow = False; -++ -++ p->writeEndMark = writeEndMark; -++ -++ p->rc.outStream = &outStream.funcTable; -++ res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); -++ if (res == SZ_OK) -++ res = LzmaEnc_Encode2(p, progress); -++ -++ *destLen -= outStream.rem; -++ if (outStream.overflow) -++ return SZ_ERROR_OUTPUT_EOF; -++ return res; -++} -++ -++SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -++ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, -++ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) -++{ -++ CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); -++ SRes res; -++ if (p == 0) -++ return SZ_ERROR_MEM; -++ -++ res = LzmaEnc_SetProps(p, props); -++ if (res == SZ_OK) -++ { -++ res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); -++ if (res == SZ_OK) -++ res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, -++ writeEndMark, progress, alloc, allocBig); -++ } -++ -++ LzmaEnc_Destroy(p, alloc, allocBig); -++ return res; -++} -+--- /dev/null -++++ b/lib/lzma/Makefile -+@@ -0,0 +1,7 @@ -++lzma_compress-objs := LzFind.o LzmaEnc.o -++lzma_decompress-objs := LzmaDec.o -++ -++obj-$(CONFIG_LZMA_COMPRESS) += lzma_compress.o -++obj-$(CONFIG_LZMA_DECOMPRESS) += lzma_decompress.o -++ -++EXTRA_CFLAGS += -Iinclude/linux -Iinclude/linux/lzma -include types.h -diff --git a/target/linux/generic/pending-4.14/532-jffs2_eofdetect.patch b/target/linux/generic/pending-4.14/532-jffs2_eofdetect.patch -new file mode 100644 -index 0000000000..e9952c6d84 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/532-jffs2_eofdetect.patch -@@ -0,0 +1,65 @@ -+From: Felix Fietkau -+Subject: fs: jffs2: EOF marker -+ -+Signed-off-by: Felix Fietkau -+--- -+ fs/jffs2/build.c | 10 ++++++++++ -+ fs/jffs2/scan.c | 21 +++++++++++++++++++-- -+ 2 files changed, 29 insertions(+), 2 deletions(-) -+ -+--- a/fs/jffs2/build.c -++++ b/fs/jffs2/build.c -+@@ -117,6 +117,16 @@ static int jffs2_build_filesystem(struct -+ dbg_fsbuild("scanned flash completely\n"); -+ jffs2_dbg_dump_block_lists_nolock(c); -+ -++ if (c->flags & (1 << 7)) { -++ printk("%s(): unlocking the mtd device... ", __func__); -++ mtd_unlock(c->mtd, 0, c->mtd->size); -++ printk("done.\n"); -++ -++ printk("%s(): erasing all blocks after the end marker... ", __func__); -++ jffs2_erase_pending_blocks(c, -1); -++ printk("done.\n"); -++ } -++ -+ dbg_fsbuild("pass 1 starting\n"); -+ c->flags |= JFFS2_SB_FLAG_BUILDING; -+ /* Now scan the directory tree, increasing nlink according to every dirent found. */ -+--- a/fs/jffs2/scan.c -++++ b/fs/jffs2/scan.c -+@@ -148,8 +148,14 @@ int jffs2_scan_medium(struct jffs2_sb_in -+ /* reset summary info for next eraseblock scan */ -+ jffs2_sum_reset_collected(s); -+ -+- ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), -+- buf_size, s); -++ if (c->flags & (1 << 7)) { -++ if (mtd_block_isbad(c->mtd, jeb->offset)) -++ ret = BLK_STATE_BADBLOCK; -++ else -++ ret = BLK_STATE_ALLFF; -++ } else -++ ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), -++ buf_size, s); -+ -+ if (ret < 0) -+ goto out; -+@@ -561,6 +567,17 @@ full_scan: -+ return err; -+ } -+ -++ if ((buf[0] == 0xde) && -++ (buf[1] == 0xad) && -++ (buf[2] == 0xc0) && -++ (buf[3] == 0xde)) { -++ /* end of filesystem. erase everything after this point */ -++ printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset); -++ c->flags |= (1 << 7); -++ -++ return BLK_STATE_ALLFF; -++ } -++ -+ /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ -+ ofs = 0; -+ max_ofs = EMPTY_SCAN_SIZE(c->sector_size); -diff --git a/target/linux/generic/pending-4.14/600-netfilter_conntrack_flush.patch b/target/linux/generic/pending-4.14/600-netfilter_conntrack_flush.patch -new file mode 100644 -index 0000000000..10da96b7ed ---- /dev/null -+++ b/target/linux/generic/pending-4.14/600-netfilter_conntrack_flush.patch -@@ -0,0 +1,95 @@ -+From: Felix Fietkau -+Subject: netfilter: add support for flushing conntrack via /proc -+ -+lede-commit 8193bbe59a74d34d6a26d4a8cb857b1952905314 -+Signed-off-by: Felix Fietkau -+--- -+ net/netfilter/nf_conntrack_standalone.c | 59 ++++++++++++++++++++++++++++++++- -+ 1 file changed, 58 insertions(+), 1 deletion(-) -+ -+--- a/net/netfilter/nf_conntrack_standalone.c -++++ b/net/netfilter/nf_conntrack_standalone.c -+@@ -17,6 +17,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ #ifdef CONFIG_SYSCTL -+ #include -+@@ -381,10 +382,66 @@ static int ct_open(struct inode *inode, -+ sizeof(struct ct_iter_state)); -+ } -+ -++struct kill_request { -++ u16 family; -++ union nf_inet_addr addr; -++}; -++ -++static int kill_matching(struct nf_conn *i, void *data) -++{ -++ struct kill_request *kr = data; -++ struct nf_conntrack_tuple *t1 = &i->tuplehash[IP_CT_DIR_ORIGINAL].tuple; -++ struct nf_conntrack_tuple *t2 = &i->tuplehash[IP_CT_DIR_REPLY].tuple; -++ -++ if (!kr->family) -++ return 1; -++ -++ if (t1->src.l3num != kr->family) -++ return 0; -++ -++ return (nf_inet_addr_cmp(&kr->addr, &t1->src.u3) || -++ nf_inet_addr_cmp(&kr->addr, &t1->dst.u3) || -++ nf_inet_addr_cmp(&kr->addr, &t2->src.u3) || -++ nf_inet_addr_cmp(&kr->addr, &t2->dst.u3)); -++} -++ -++static ssize_t ct_file_write(struct file *file, const char __user *buf, -++ size_t count, loff_t *ppos) -++{ -++ struct seq_file *seq = file->private_data; -++ struct net *net = seq_file_net(seq); -++ struct kill_request kr = { }; -++ char req[INET6_ADDRSTRLEN] = { }; -++ -++ if (count == 0) -++ return 0; -++ -++ if (count >= INET6_ADDRSTRLEN) -++ count = INET6_ADDRSTRLEN - 1; -++ -++ if (copy_from_user(req, buf, count)) -++ return -EFAULT; -++ -++ if (strnchr(req, count, ':')) { -++ kr.family = AF_INET6; -++ if (!in6_pton(req, count, (void *)&kr.addr, '\n', NULL)) -++ return -EINVAL; -++ } else if (strnchr(req, count, '.')) { -++ kr.family = AF_INET; -++ if (!in4_pton(req, count, (void *)&kr.addr, '\n', NULL)) -++ return -EINVAL; -++ } -++ -++ nf_ct_iterate_cleanup_net(net, kill_matching, &kr, 0, 0); -++ -++ return count; -++} -++ -+ static const struct file_operations ct_file_ops = { -+ .owner = THIS_MODULE, -+ .open = ct_open, -+ .read = seq_read, -++ .write = ct_file_write, -+ .llseek = seq_lseek, -+ .release = seq_release_net, -+ }; -+@@ -488,7 +545,7 @@ static int nf_conntrack_standalone_init_ -+ kuid_t root_uid; -+ kgid_t root_gid; -+ -+- pde = proc_create("nf_conntrack", 0440, net->proc_net, &ct_file_ops); -++ pde = proc_create("nf_conntrack", 0660, net->proc_net, &ct_file_ops); -+ if (!pde) -+ goto out_nf_conntrack; -+ -diff --git a/target/linux/generic/pending-4.14/610-netfilter_match_bypass_default_checks.patch b/target/linux/generic/pending-4.14/610-netfilter_match_bypass_default_checks.patch -new file mode 100644 -index 0000000000..2541230ff5 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/610-netfilter_match_bypass_default_checks.patch -@@ -0,0 +1,110 @@ -+From: Felix Fietkau -+Subject: kernel: add a new version of my netfilter speedup patches for linux 2.6.39 and 3.0 -+ -+Signed-off-by: Felix Fietkau -+--- -+ include/uapi/linux/netfilter_ipv4/ip_tables.h | 1 + -+ net/ipv4/netfilter/ip_tables.c | 37 +++++++++++++++++++++++++++ -+ 2 files changed, 38 insertions(+) -+ -+--- a/include/uapi/linux/netfilter_ipv4/ip_tables.h -++++ b/include/uapi/linux/netfilter_ipv4/ip_tables.h -+@@ -89,6 +89,7 @@ struct ipt_ip { -+ #define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */ -+ #define IPT_F_GOTO 0x02 /* Set if jump is a goto */ -+ #define IPT_F_MASK 0x03 /* All possible flag bits mask. */ -++#define IPT_F_NO_DEF_MATCH 0x80 /* Internal: no default match rules present */ -+ -+ /* Values for "inv" field in struct ipt_ip. */ -+ #define IPT_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */ -+--- a/net/ipv4/netfilter/ip_tables.c -++++ b/net/ipv4/netfilter/ip_tables.c -+@@ -52,6 +52,9 @@ ip_packet_match(const struct iphdr *ip, -+ { -+ unsigned long ret; -+ -++ if (ipinfo->flags & IPT_F_NO_DEF_MATCH) -++ return true; -++ -+ if (NF_INVF(ipinfo, IPT_INV_SRCIP, -+ (ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) || -+ NF_INVF(ipinfo, IPT_INV_DSTIP, -+@@ -82,6 +85,29 @@ ip_packet_match(const struct iphdr *ip, -+ return true; -+ } -+ -++static void -++ip_checkdefault(struct ipt_ip *ip) -++{ -++ static const char iface_mask[IFNAMSIZ] = {}; -++ -++ if (ip->invflags || ip->flags & IPT_F_FRAG) -++ return; -++ -++ if (memcmp(ip->iniface_mask, iface_mask, IFNAMSIZ) != 0) -++ return; -++ -++ if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0) -++ return; -++ -++ if (ip->smsk.s_addr || ip->dmsk.s_addr) -++ return; -++ -++ if (ip->proto) -++ return; -++ -++ ip->flags |= IPT_F_NO_DEF_MATCH; -++} -++ -+ static bool -+ ip_checkentry(const struct ipt_ip *ip) -+ { -+@@ -537,6 +563,8 @@ find_check_entry(struct ipt_entry *e, st -+ struct xt_mtchk_param mtpar; -+ struct xt_entry_match *ematch; -+ -++ ip_checkdefault(&e->ip); -++ -+ if (!xt_percpu_counter_alloc(alloc_state, &e->counters)) -+ return -ENOMEM; -+ -+@@ -818,6 +846,7 @@ copy_entries_to_user(unsigned int total_ -+ const struct xt_table_info *private = table->private; -+ int ret = 0; -+ const void *loc_cpu_entry; -++ u8 flags; -+ -+ counters = alloc_counters(table); -+ if (IS_ERR(counters)) -+@@ -845,6 +874,14 @@ copy_entries_to_user(unsigned int total_ -+ goto free_counters; -+ } -+ -++ flags = e->ip.flags & IPT_F_MASK; -++ if (copy_to_user(userptr + off -++ + offsetof(struct ipt_entry, ip.flags), -++ &flags, sizeof(flags)) != 0) { -++ ret = -EFAULT; -++ goto free_counters; -++ } -++ -+ for (i = sizeof(struct ipt_entry); -+ i < e->target_offset; -+ i += m->u.match_size) { -+@@ -1227,12 +1264,15 @@ compat_copy_entry_to_user(struct ipt_ent -+ compat_uint_t origsize; -+ const struct xt_entry_match *ematch; -+ int ret = 0; -++ u8 flags = e->ip.flags & IPT_F_MASK; -+ -+ origsize = *size; -+ ce = *dstptr; -+ if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 || -+ copy_to_user(&ce->counters, &counters[i], -+- sizeof(counters[i])) != 0) -++ sizeof(counters[i])) != 0 || -++ copy_to_user(&ce->ip.flags, &flags, -++ sizeof(flags)) != 0) -+ return -EFAULT; -+ -+ *dstptr += sizeof(struct compat_ipt_entry); -diff --git a/target/linux/generic/pending-4.14/611-netfilter_match_bypass_default_table.patch b/target/linux/generic/pending-4.14/611-netfilter_match_bypass_default_table.patch -new file mode 100644 -index 0000000000..11f07e12b3 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/611-netfilter_match_bypass_default_table.patch -@@ -0,0 +1,111 @@ -+From: Felix Fietkau -+Subject: netfilter: match bypass default table -+ -+Signed-off-by: Felix Fietkau -+--- -+ net/ipv4/netfilter/ip_tables.c | 79 +++++++++++++++++++++++++++++++----------- -+ 1 file changed, 58 insertions(+), 21 deletions(-) -+ -+--- a/net/ipv4/netfilter/ip_tables.c -++++ b/net/ipv4/netfilter/ip_tables.c -+@@ -248,6 +248,33 @@ struct ipt_entry *ipt_next_entry(const s -+ return (void *)entry + entry->next_offset; -+ } -+ -++static bool -++ipt_handle_default_rule(struct ipt_entry *e, unsigned int *verdict) -++{ -++ struct xt_entry_target *t; -++ struct xt_standard_target *st; -++ -++ if (e->target_offset != sizeof(struct ipt_entry)) -++ return false; -++ -++ if (!(e->ip.flags & IPT_F_NO_DEF_MATCH)) -++ return false; -++ -++ t = ipt_get_target(e); -++ if (t->u.kernel.target->target) -++ return false; -++ -++ st = (struct xt_standard_target *) t; -++ if (st->verdict == XT_RETURN) -++ return false; -++ -++ if (st->verdict >= 0) -++ return false; -++ -++ *verdict = (unsigned)(-st->verdict) - 1; -++ return true; -++} -++ -+ /* Returns one of the generic firewall policies, like NF_ACCEPT. */ -+ unsigned int -+ ipt_do_table(struct sk_buff *skb, -+@@ -268,24 +295,8 @@ ipt_do_table(struct sk_buff *skb, -+ unsigned int addend; -+ -+ /* Initialization */ -+- stackidx = 0; -+- ip = ip_hdr(skb); -+- indev = state->in ? state->in->name : nulldevname; -+- outdev = state->out ? state->out->name : nulldevname; -+- /* We handle fragments by dealing with the first fragment as -+- * if it was a normal packet. All other fragments are treated -+- * normally, except that they will NEVER match rules that ask -+- * things we don't know, ie. tcp syn flag or ports). If the -+- * rule is also a fragment-specific rule, non-fragments won't -+- * match it. */ -+- acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; -+- acpar.thoff = ip_hdrlen(skb); -+- acpar.hotdrop = false; -+- acpar.state = state; -+- -+ WARN_ON(!(table->valid_hooks & (1 << hook))); -+ local_bh_disable(); -+- addend = xt_write_recseq_begin(); -+ private = table->private; -+ cpu = smp_processor_id(); -+ /* -+@@ -294,6 +305,23 @@ ipt_do_table(struct sk_buff *skb, -+ */ -+ smp_read_barrier_depends(); -+ table_base = private->entries; -++ -++ e = get_entry(table_base, private->hook_entry[hook]); -++ if (ipt_handle_default_rule(e, &verdict)) { -++ struct xt_counters *counter; -++ -++ counter = xt_get_this_cpu_counter(&e->counters); -++ ADD_COUNTER(*counter, skb->len, 1); -++ local_bh_enable(); -++ return verdict; -++ } -++ -++ stackidx = 0; -++ ip = ip_hdr(skb); -++ indev = state->in ? state->in->name : nulldevname; -++ outdev = state->out ? state->out->name : nulldevname; -++ -++ addend = xt_write_recseq_begin(); -+ jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; -+ -+ /* Switch to alternate jumpstack if we're being invoked via TEE. -+@@ -306,7 +334,16 @@ ipt_do_table(struct sk_buff *skb, -+ if (static_key_false(&xt_tee_enabled)) -+ jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated); -+ -+- e = get_entry(table_base, private->hook_entry[hook]); -++ /* We handle fragments by dealing with the first fragment as -++ * if it was a normal packet. All other fragments are treated -++ * normally, except that they will NEVER match rules that ask -++ * things we don't know, ie. tcp syn flag or ports). If the -++ * rule is also a fragment-specific rule, non-fragments won't -++ * match it. */ -++ acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; -++ acpar.thoff = ip_hdrlen(skb); -++ acpar.hotdrop = false; -++ acpar.state = state; -+ -+ do { -+ const struct xt_entry_target *t; -diff --git a/target/linux/generic/pending-4.14/612-netfilter_match_reduce_memory_access.patch b/target/linux/generic/pending-4.14/612-netfilter_match_reduce_memory_access.patch -new file mode 100644 -index 0000000000..183c74c1c7 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/612-netfilter_match_reduce_memory_access.patch -@@ -0,0 +1,22 @@ -+From: Felix Fietkau -+Subject: netfilter: reduce match memory access -+ -+Signed-off-by: Felix Fietkau -+--- -+ net/ipv4/netfilter/ip_tables.c | 4 ++-- -+ 1 file changed, 2 insertions(+), 2 deletions(-) -+ -+--- a/net/ipv4/netfilter/ip_tables.c -++++ b/net/ipv4/netfilter/ip_tables.c -+@@ -55,9 +55,9 @@ ip_packet_match(const struct iphdr *ip, -+ if (ipinfo->flags & IPT_F_NO_DEF_MATCH) -+ return true; -+ -+- if (NF_INVF(ipinfo, IPT_INV_SRCIP, -++ if (NF_INVF(ipinfo, IPT_INV_SRCIP, ipinfo->smsk.s_addr && -+ (ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) || -+- NF_INVF(ipinfo, IPT_INV_DSTIP, -++ NF_INVF(ipinfo, IPT_INV_DSTIP, ipinfo->dmsk.s_addr && -+ (ip->daddr & ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr)) -+ return false; -+ -diff --git a/target/linux/generic/pending-4.14/613-netfilter_optional_tcp_window_check.patch b/target/linux/generic/pending-4.14/613-netfilter_optional_tcp_window_check.patch -new file mode 100644 -index 0000000000..69c165bb41 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/613-netfilter_optional_tcp_window_check.patch -@@ -0,0 +1,44 @@ -+From: Felix Fietkau -+Subject: netfilter: optional tcp window check -+ -+Signed-off-by: Felix Fietkau -+--- -+ net/netfilter/nf_conntrack_proto_tcp.c | 13 +++++++++++++ -+ 1 file changed, 13 insertions(+) -+ -+--- a/net/netfilter/nf_conntrack_proto_tcp.c -++++ b/net/netfilter/nf_conntrack_proto_tcp.c -+@@ -33,6 +33,9 @@ -+ #include -+ #include -+ -++/* Do not check the TCP window for incoming packets */ -++static int nf_ct_tcp_no_window_check __read_mostly = 1; -++ -+ /* "Be conservative in what you do, -+ be liberal in what you accept from others." -+ If it's non-zero, we mark only out of window RST segments as INVALID. */ -+@@ -508,6 +511,9 @@ static bool tcp_in_window(const struct n -+ s32 receiver_offset; -+ bool res, in_recv_win; -+ -++ if (nf_ct_tcp_no_window_check) -++ return true; -++ -+ /* -+ * Get the required data from the packet. -+ */ -+@@ -1489,6 +1495,13 @@ static struct ctl_table tcp_sysctl_table -+ .mode = 0644, -+ .proc_handler = proc_dointvec, -+ }, -++ { -++ .procname = "nf_conntrack_tcp_no_window_check", -++ .data = &nf_ct_tcp_no_window_check, -++ .maxlen = sizeof(unsigned int), -++ .mode = 0644, -++ .proc_handler = proc_dointvec, -++ }, -+ { } -+ }; -+ #endif /* CONFIG_SYSCTL */ -diff --git a/target/linux/generic/pending-4.14/620-net_sched-codel-do-not-defer-queue-length-update.patch b/target/linux/generic/pending-4.14/620-net_sched-codel-do-not-defer-queue-length-update.patch -new file mode 100644 -index 0000000000..b3c35ee350 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/620-net_sched-codel-do-not-defer-queue-length-update.patch -@@ -0,0 +1,86 @@ -+From: Konstantin Khlebnikov -+Date: Mon, 21 Aug 2017 11:14:14 +0300 -+Subject: [PATCH] net_sched/codel: do not defer queue length update -+ -+When codel wants to drop last packet in ->dequeue() it cannot call -+qdisc_tree_reduce_backlog() right away - it will notify parent qdisc -+about zero qlen and HTB/HFSC will deactivate class. The same class will -+be deactivated second time by caller of ->dequeue(). Currently codel and -+fq_codel defer update. This triggers warning in HFSC when it's qlen != 0 -+but there is no active classes. -+ -+This patch update parent queue length immediately: just temporary increase -+qlen around qdisc_tree_reduce_backlog() to prevent first class deactivation -+if we have skb to return. -+ -+This might open another problem in HFSC - now operation peek could fail and -+deactivate parent class. -+ -+Signed-off-by: Konstantin Khlebnikov -+Link: https://bugzilla.kernel.org/show_bug.cgi?id=109581 -+--- -+ -+--- a/net/sched/sch_codel.c -++++ b/net/sched/sch_codel.c -+@@ -95,11 +95,17 @@ static struct sk_buff *codel_qdisc_deque -+ &q->stats, qdisc_pkt_len, codel_get_enqueue_time, -+ drop_func, dequeue_func); -+ -+- /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0, -+- * or HTB crashes. Defer it for next round. -++ /* If our qlen is 0 qdisc_tree_reduce_backlog() will deactivate -++ * parent class, dequeue in parent qdisc will do the same if we -++ * return skb. Temporary increment qlen if we have skb. -+ */ -+- if (q->stats.drop_count && sch->q.qlen) { -+- qdisc_tree_reduce_backlog(sch, q->stats.drop_count, q->stats.drop_len); -++ if (q->stats.drop_count) { -++ if (skb) -++ sch->q.qlen++; -++ qdisc_tree_reduce_backlog(sch, q->stats.drop_count, -++ q->stats.drop_len); -++ if (skb) -++ sch->q.qlen--; -+ q->stats.drop_count = 0; -+ q->stats.drop_len = 0; -+ } -+--- a/net/sched/sch_fq_codel.c -++++ b/net/sched/sch_fq_codel.c -+@@ -316,6 +316,21 @@ begin: -+ flow->dropped += q->cstats.drop_count - prev_drop_count; -+ flow->dropped += q->cstats.ecn_mark - prev_ecn_mark; -+ -++ /* If our qlen is 0 qdisc_tree_reduce_backlog() will deactivate -++ * parent class, dequeue in parent qdisc will do the same if we -++ * return skb. Temporary increment qlen if we have skb. -++ */ -++ if (q->cstats.drop_count) { -++ if (skb) -++ sch->q.qlen++; -++ qdisc_tree_reduce_backlog(sch, q->cstats.drop_count, -++ q->cstats.drop_len); -++ if (skb) -++ sch->q.qlen--; -++ q->cstats.drop_count = 0; -++ q->cstats.drop_len = 0; -++ } -++ -+ if (!skb) { -+ /* force a pass through old_flows to prevent starvation */ -+ if ((head == &q->new_flows) && !list_empty(&q->old_flows)) -+@@ -326,15 +341,6 @@ begin: -+ } -+ qdisc_bstats_update(sch, skb); -+ flow->deficit -= qdisc_pkt_len(skb); -+- /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0, -+- * or HTB crashes. Defer it for next round. -+- */ -+- if (q->cstats.drop_count && sch->q.qlen) { -+- qdisc_tree_reduce_backlog(sch, q->cstats.drop_count, -+- q->cstats.drop_len); -+- q->cstats.drop_count = 0; -+- q->cstats.drop_len = 0; -+- } -+ return skb; -+ } -+ -diff --git a/target/linux/generic/pending-4.14/630-packet_socket_type.patch b/target/linux/generic/pending-4.14/630-packet_socket_type.patch -new file mode 100644 -index 0000000000..c4bd5fdaba ---- /dev/null -+++ b/target/linux/generic/pending-4.14/630-packet_socket_type.patch -@@ -0,0 +1,138 @@ -+From: Felix Fietkau -+Subject: net: add an optimization for dealing with raw sockets -+ -+lede-commit: 4898039703d7315f0f3431c860123338ec3be0f6 -+Signed-off-by: Felix Fietkau -+--- -+ include/uapi/linux/if_packet.h | 3 +++ -+ net/packet/af_packet.c | 34 +++++++++++++++++++++++++++------- -+ net/packet/internal.h | 1 + -+ 3 files changed, 31 insertions(+), 7 deletions(-) -+ -+--- a/include/uapi/linux/if_packet.h -++++ b/include/uapi/linux/if_packet.h -+@@ -32,6 +32,8 @@ struct sockaddr_ll { -+ #define PACKET_KERNEL 7 /* To kernel space */ -+ /* Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space */ -+ #define PACKET_FASTROUTE 6 /* Fastrouted frame */ -++#define PACKET_MASK_ANY 0xffffffff /* mask for packet type bits */ -++ -+ -+ /* Packet socket options */ -+ -+@@ -57,6 +59,7 @@ struct sockaddr_ll { -+ #define PACKET_QDISC_BYPASS 20 -+ #define PACKET_ROLLOVER_STATS 21 -+ #define PACKET_FANOUT_DATA 22 -++#define PACKET_RECV_TYPE 23 -+ -+ #define PACKET_FANOUT_HASH 0 -+ #define PACKET_FANOUT_LB 1 -+--- a/net/packet/af_packet.c -++++ b/net/packet/af_packet.c -+@@ -1836,6 +1836,7 @@ static int packet_rcv_spkt(struct sk_buf -+ { -+ struct sock *sk; -+ struct sockaddr_pkt *spkt; -++ struct packet_sock *po; -+ -+ /* -+ * When we registered the protocol we saved the socket in the data -+@@ -1843,6 +1844,7 @@ static int packet_rcv_spkt(struct sk_buf -+ */ -+ -+ sk = pt->af_packet_priv; -++ po = pkt_sk(sk); -+ -+ /* -+ * Yank back the headers [hope the device set this -+@@ -1855,7 +1857,7 @@ static int packet_rcv_spkt(struct sk_buf -+ * so that this procedure is noop. -+ */ -+ -+- if (skb->pkt_type == PACKET_LOOPBACK) -++ if (!(po->pkt_type & (1 << skb->pkt_type))) -+ goto out; -+ -+ if (!net_eq(dev_net(dev), sock_net(sk))) -+@@ -2082,12 +2084,12 @@ static int packet_rcv(struct sk_buff *sk -+ unsigned int snaplen, res; -+ bool is_drop_n_account = false; -+ -+- if (skb->pkt_type == PACKET_LOOPBACK) -+- goto drop; -+- -+ sk = pt->af_packet_priv; -+ po = pkt_sk(sk); -+ -++ if (!(po->pkt_type & (1 << skb->pkt_type))) -++ goto drop; -++ -+ if (!net_eq(dev_net(dev), sock_net(sk))) -+ goto drop; -+ -+@@ -2214,12 +2216,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); -+ -+- if (skb->pkt_type == PACKET_LOOPBACK) -+- goto drop; -+- -+ sk = pt->af_packet_priv; -+ po = pkt_sk(sk); -+ -++ if (!(po->pkt_type & (1 << skb->pkt_type))) -++ goto drop; -++ -+ if (!net_eq(dev_net(dev), sock_net(sk))) -+ goto drop; -+ -+@@ -3313,6 +3315,7 @@ static int packet_create(struct net *net -+ mutex_init(&po->pg_vec_lock); -+ po->rollover = NULL; -+ po->prot_hook.func = packet_rcv; -++ po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK); -+ -+ if (sock->type == SOCK_PACKET) -+ po->prot_hook.func = packet_rcv_spkt; -+@@ -3935,6 +3938,16 @@ packet_setsockopt(struct socket *sock, i -+ po->xmit = val ? packet_direct_xmit : dev_queue_xmit; -+ return 0; -+ } -++ case PACKET_RECV_TYPE: -++ { -++ unsigned int val; -++ if (optlen != sizeof(val)) -++ return -EINVAL; -++ if (copy_from_user(&val, optval, sizeof(val))) -++ return -EFAULT; -++ po->pkt_type = val & ~BIT(PACKET_LOOPBACK); -++ return 0; -++ } -+ default: -+ return -ENOPROTOOPT; -+ } -+@@ -3987,6 +4000,13 @@ static int packet_getsockopt(struct sock -+ case PACKET_VNET_HDR: -+ val = po->has_vnet_hdr; -+ break; -++ case PACKET_RECV_TYPE: -++ if (len > sizeof(unsigned int)) -++ len = sizeof(unsigned int); -++ val = po->pkt_type; -++ -++ data = &val; -++ break; -+ case PACKET_VERSION: -+ val = po->tp_version; -+ break; -+--- a/net/packet/internal.h -++++ b/net/packet/internal.h -+@@ -135,6 +135,7 @@ struct packet_sock { -+ struct net_device __rcu *cached_dev; -+ int (*xmit)(struct sk_buff *skb); -+ struct packet_type prot_hook ____cacheline_aligned_in_smp; -++ unsigned int pkt_type; -+ }; -+ -+ static struct packet_sock *pkt_sk(struct sock *sk) -diff --git a/target/linux/generic/pending-4.14/640-netfilter-nf_flow_table-add-hardware-offload-support.patch b/target/linux/generic/pending-4.14/640-netfilter-nf_flow_table-add-hardware-offload-support.patch -new file mode 100644 -index 0000000000..f2aa14c238 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/640-netfilter-nf_flow_table-add-hardware-offload-support.patch -@@ -0,0 +1,565 @@ -+From: Pablo Neira Ayuso -+Date: Thu, 11 Jan 2018 16:32:00 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: add hardware offload support -+ -+This patch adds the infrastructure to offload flows to hardware, in case -+the nic/switch comes with built-in flow tables capabilities. -+ -+If the hardware comes with no hardware flow tables or they have -+limitations in terms of features, the existing infrastructure falls back -+to the software flow table implementation. -+ -+The software flow table garbage collector skips entries that resides in -+the hardware, so the hardware will be responsible for releasing this -+flow table entry too via flow_offload_dead(). -+ -+Hardware configuration, either to add or to delete entries, is done from -+the hardware offload workqueue, to ensure this is done from user context -+given that we may sleep when grabbing the mdio mutex. -+ -+Signed-off-by: Pablo Neira Ayuso -+--- -+ create mode 100644 net/netfilter/nf_flow_table_hw.c -+ -+--- a/include/linux/netdevice.h -++++ b/include/linux/netdevice.h -+@@ -826,6 +826,13 @@ struct xfrmdev_ops { -+ }; -+ #endif -+ -++struct flow_offload; -++ -++enum flow_offload_type { -++ FLOW_OFFLOAD_ADD = 0, -++ FLOW_OFFLOAD_DEL, -++}; -++ -+ /* -+ * This structure defines the management hooks for network devices. -+ * The following hooks can be defined; unless noted otherwise, they are -+@@ -1057,6 +1064,10 @@ struct xfrmdev_ops { -+ * int (*ndo_bridge_dellink)(struct net_device *dev, struct nlmsghdr *nlh, -+ * u16 flags); -+ * -++ * int (*ndo_flow_offload)(enum flow_offload_type type, -++ * struct flow_offload *flow); -++ * Adds/deletes flow entry to/from net device flowtable. -++ * -+ * int (*ndo_change_carrier)(struct net_device *dev, bool new_carrier); -+ * Called to change device carrier. Soft-devices (like dummy, team, etc) -+ * which do not represent real hardware may define this to allow their -+@@ -1281,6 +1292,8 @@ struct net_device_ops { -+ int (*ndo_bridge_dellink)(struct net_device *dev, -+ struct nlmsghdr *nlh, -+ u16 flags); -++ int (*ndo_flow_offload)(enum flow_offload_type type, -++ struct flow_offload *flow); -+ int (*ndo_change_carrier)(struct net_device *dev, -+ bool new_carrier); -+ int (*ndo_get_phys_port_id)(struct net_device *dev, -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -20,11 +20,17 @@ struct nf_flowtable_type { -+ struct module *owner; -+ }; -+ -++enum nf_flowtable_flags { -++ NF_FLOWTABLE_F_HW = 0x1, -++}; -++ -+ struct nf_flowtable { -+ struct list_head list; -+ struct rhashtable rhashtable; -+ const struct nf_flowtable_type *type; -++ u32 flags; -+ struct delayed_work gc_work; -++ possible_net_t ft_net; -+ }; -+ -+ enum flow_offload_tuple_dir { -+@@ -69,6 +75,7 @@ struct flow_offload_tuple_rhash { -+ #define FLOW_OFFLOAD_DNAT 0x2 -+ #define FLOW_OFFLOAD_DYING 0x4 -+ #define FLOW_OFFLOAD_TEARDOWN 0x8 -++#define FLOW_OFFLOAD_HW 0x10 -+ -+ struct flow_offload { -+ struct flow_offload_tuple_rhash tuplehash[FLOW_OFFLOAD_DIR_MAX]; -+@@ -125,6 +132,22 @@ unsigned int nf_flow_offload_ip_hook(voi -+ unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, -+ const struct nf_hook_state *state); -+ -++void nf_flow_offload_hw_add(struct net *net, struct flow_offload *flow, -++ struct nf_conn *ct); -++void nf_flow_offload_hw_del(struct net *net, struct flow_offload *flow); -++ -++struct nf_flow_table_hw { -++ struct module *owner; -++ void (*add)(struct net *net, struct flow_offload *flow, -++ struct nf_conn *ct); -++ void (*del)(struct net *net, struct flow_offload *flow); -++}; -++ -++int nf_flow_table_hw_register(const struct nf_flow_table_hw *offload); -++void nf_flow_table_hw_unregister(const struct nf_flow_table_hw *offload); -++ -++extern struct work_struct nf_flow_offload_hw_work; -++ -+ #define MODULE_ALIAS_NF_FLOWTABLE(family) \ -+ MODULE_ALIAS("nf-flowtable-" __stringify(family)) -+ -+--- a/include/uapi/linux/netfilter/nf_tables.h -++++ b/include/uapi/linux/netfilter/nf_tables.h -+@@ -1341,6 +1341,7 @@ enum nft_object_attributes { -+ * @NFTA_FLOWTABLE_HOOK: netfilter hook configuration(NLA_U32) -+ * @NFTA_FLOWTABLE_USE: number of references to this flow table (NLA_U32) -+ * @NFTA_FLOWTABLE_HANDLE: object handle (NLA_U64) -++ * @NFTA_FLOWTABLE_FLAGS: flags (NLA_U32) -+ */ -+ enum nft_flowtable_attributes { -+ NFTA_FLOWTABLE_UNSPEC, -+@@ -1350,6 +1351,7 @@ enum nft_flowtable_attributes { -+ NFTA_FLOWTABLE_USE, -+ NFTA_FLOWTABLE_HANDLE, -+ NFTA_FLOWTABLE_PAD, -++ NFTA_FLOWTABLE_FLAGS, -+ __NFTA_FLOWTABLE_MAX -+ }; -+ #define NFTA_FLOWTABLE_MAX (__NFTA_FLOWTABLE_MAX - 1) -+--- a/net/netfilter/Kconfig -++++ b/net/netfilter/Kconfig -+@@ -692,6 +692,15 @@ config NF_FLOW_TABLE -+ -+ To compile it as a module, choose M here. -+ -++config NF_FLOW_TABLE_HW -++ tristate "Netfilter flow table hardware offload module" -++ depends on NF_FLOW_TABLE -++ help -++ This option adds hardware offload support for the flow table core -++ infrastructure. -++ -++ To compile it as a module, choose M here. -++ -+ config NETFILTER_XTABLES -+ tristate "Netfilter Xtables support (required for ip_tables)" -+ default m if NETFILTER_ADVANCED=n -+--- a/net/netfilter/Makefile -++++ b/net/netfilter/Makefile -+@@ -116,6 +116,7 @@ obj-$(CONFIG_NF_FLOW_TABLE) += nf_flow_t -+ nf_flow_table-objs := nf_flow_table_core.o nf_flow_table_ip.o -+ -+ obj-$(CONFIG_NF_FLOW_TABLE_INET) += nf_flow_table_inet.o -++obj-$(CONFIG_NF_FLOW_TABLE_HW) += nf_flow_table_hw.o -+ -+ # generic X tables -+ obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o -+--- a/net/netfilter/nf_flow_table_core.c -++++ b/net/netfilter/nf_flow_table_core.c -+@@ -219,10 +219,16 @@ int flow_offload_add(struct nf_flowtable -+ } -+ EXPORT_SYMBOL_GPL(flow_offload_add); -+ -++static inline bool nf_flow_in_hw(const struct flow_offload *flow) -++{ -++ return flow->flags & FLOW_OFFLOAD_HW; -++} -++ -+ static void flow_offload_del(struct nf_flowtable *flow_table, -+ struct flow_offload *flow) -+ { -+ struct flow_offload_entry *e; -++ struct net *net = read_pnet(&flow_table->ft_net); -+ -+ rhashtable_remove_fast(&flow_table->rhashtable, -+ &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node, -+@@ -237,6 +243,9 @@ static void flow_offload_del(struct nf_f -+ if (!(flow->flags & FLOW_OFFLOAD_TEARDOWN)) -+ flow_offload_fixup_ct_state(e->ct); -+ -++ if (nf_flow_in_hw(flow)) -++ nf_flow_offload_hw_del(net, flow); -++ -+ flow_offload_free(flow); -+ } -+ -+@@ -350,6 +359,9 @@ static int nf_flow_offload_gc_step(struc -+ if (!teardown) -+ nf_ct_offload_timeout(flow); -+ -++ if (nf_flow_in_hw(flow) && !teardown) -++ continue; -++ -+ if (nf_flow_has_expired(flow) || teardown) -+ flow_offload_del(flow_table, flow); -+ } -+@@ -485,10 +497,43 @@ int nf_flow_dnat_port(const struct flow_ -+ } -+ EXPORT_SYMBOL_GPL(nf_flow_dnat_port); -+ -++static const struct nf_flow_table_hw __rcu *nf_flow_table_hw_hook __read_mostly; -++ -++static int nf_flow_offload_hw_init(struct nf_flowtable *flow_table) -++{ -++ const struct nf_flow_table_hw *offload; -++ -++ if (!rcu_access_pointer(nf_flow_table_hw_hook)) -++ request_module("nf-flow-table-hw"); -++ -++ rcu_read_lock(); -++ offload = rcu_dereference(nf_flow_table_hw_hook); -++ if (!offload) -++ goto err_no_hw_offload; -++ -++ if (!try_module_get(offload->owner)) -++ goto err_no_hw_offload; -++ -++ rcu_read_unlock(); -++ -++ return 0; -++ -++err_no_hw_offload: -++ rcu_read_unlock(); -++ -++ return -EOPNOTSUPP; -++} -++ -+ int nf_flow_table_init(struct nf_flowtable *flowtable) -+ { -+ int err; -+ -++ if (flowtable->flags & NF_FLOWTABLE_F_HW) { -++ err = nf_flow_offload_hw_init(flowtable); -++ if (err) -++ return err; -++ } -++ -+ INIT_DEFERRABLE_WORK(&flowtable->gc_work, nf_flow_offload_work_gc); -+ -+ err = rhashtable_init(&flowtable->rhashtable, -+@@ -526,6 +571,8 @@ static void nf_flow_table_iterate_cleanu -+ { -+ nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, dev); -+ flush_delayed_work(&flowtable->gc_work); -++ if (flowtable->flags & NF_FLOWTABLE_F_HW) -++ flush_work(&nf_flow_offload_hw_work); -+ } -+ -+ void nf_flow_table_cleanup(struct net *net, struct net_device *dev) -+@@ -539,6 +586,26 @@ void nf_flow_table_cleanup(struct net *n -+ } -+ EXPORT_SYMBOL_GPL(nf_flow_table_cleanup); -+ -++struct work_struct nf_flow_offload_hw_work; -++EXPORT_SYMBOL_GPL(nf_flow_offload_hw_work); -++ -++/* Give the hardware workqueue the chance to remove entries from hardware.*/ -++static void nf_flow_offload_hw_free(struct nf_flowtable *flowtable) -++{ -++ const struct nf_flow_table_hw *offload; -++ -++ flush_work(&nf_flow_offload_hw_work); -++ -++ rcu_read_lock(); -++ offload = rcu_dereference(nf_flow_table_hw_hook); -++ if (!offload) { -++ rcu_read_unlock(); -++ return; -++ } -++ module_put(offload->owner); -++ rcu_read_unlock(); -++} -++ -+ void nf_flow_table_free(struct nf_flowtable *flow_table) -+ { -+ mutex_lock(&flowtable_lock); -+@@ -548,9 +615,58 @@ void nf_flow_table_free(struct nf_flowta -+ nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL); -+ WARN_ON(!nf_flow_offload_gc_step(flow_table)); -+ rhashtable_destroy(&flow_table->rhashtable); -++ if (flow_table->flags & NF_FLOWTABLE_F_HW) -++ nf_flow_offload_hw_free(flow_table); -+ } -+ EXPORT_SYMBOL_GPL(nf_flow_table_free); -+ -++/* Must be called from user context. */ -++void nf_flow_offload_hw_add(struct net *net, struct flow_offload *flow, -++ struct nf_conn *ct) -++{ -++ const struct nf_flow_table_hw *offload; -++ -++ rcu_read_lock(); -++ offload = rcu_dereference(nf_flow_table_hw_hook); -++ if (offload) -++ offload->add(net, flow, ct); -++ rcu_read_unlock(); -++} -++EXPORT_SYMBOL_GPL(nf_flow_offload_hw_add); -++ -++/* Must be called from user context. */ -++void nf_flow_offload_hw_del(struct net *net, struct flow_offload *flow) -++{ -++ const struct nf_flow_table_hw *offload; -++ -++ rcu_read_lock(); -++ offload = rcu_dereference(nf_flow_table_hw_hook); -++ if (offload) -++ offload->del(net, flow); -++ rcu_read_unlock(); -++} -++EXPORT_SYMBOL_GPL(nf_flow_offload_hw_del); -++ -++int nf_flow_table_hw_register(const struct nf_flow_table_hw *offload) -++{ -++ if (rcu_access_pointer(nf_flow_table_hw_hook)) -++ return -EBUSY; -++ -++ rcu_assign_pointer(nf_flow_table_hw_hook, offload); -++ -++ return 0; -++} -++EXPORT_SYMBOL_GPL(nf_flow_table_hw_register); -++ -++void nf_flow_table_hw_unregister(const struct nf_flow_table_hw *offload) -++{ -++ WARN_ON(rcu_access_pointer(nf_flow_table_hw_hook) != offload); -++ rcu_assign_pointer(nf_flow_table_hw_hook, NULL); -++ -++ synchronize_rcu(); -++} -++EXPORT_SYMBOL_GPL(nf_flow_table_hw_unregister); -++ -+ static int nf_flow_table_netdev_event(struct notifier_block *this, -+ unsigned long event, void *ptr) -+ { -+--- /dev/null -++++ b/net/netfilter/nf_flow_table_hw.c -+@@ -0,0 +1,169 @@ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++static DEFINE_SPINLOCK(flow_offload_hw_pending_list_lock); -++static LIST_HEAD(flow_offload_hw_pending_list); -++ -++static DEFINE_MUTEX(nf_flow_offload_hw_mutex); -++ -++struct flow_offload_hw { -++ struct list_head list; -++ enum flow_offload_type type; -++ struct flow_offload *flow; -++ struct nf_conn *ct; -++ possible_net_t flow_hw_net; -++}; -++ -++static int do_flow_offload_hw(struct net *net, struct flow_offload *flow, -++ int type) -++{ -++ struct net_device *indev; -++ int ret, ifindex; -++ -++ ifindex = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.iifidx; -++ indev = dev_get_by_index(net, ifindex); -++ if (WARN_ON(!indev)) -++ return 0; -++ -++ mutex_lock(&nf_flow_offload_hw_mutex); -++ ret = indev->netdev_ops->ndo_flow_offload(type, flow); -++ mutex_unlock(&nf_flow_offload_hw_mutex); -++ -++ dev_put(indev); -++ -++ return ret; -++} -++ -++static void flow_offload_hw_work_add(struct flow_offload_hw *offload) -++{ -++ struct net *net; -++ int ret; -++ -++ if (nf_ct_is_dying(offload->ct)) -++ return; -++ -++ net = read_pnet(&offload->flow_hw_net); -++ ret = do_flow_offload_hw(net, offload->flow, FLOW_OFFLOAD_ADD); -++ if (ret >= 0) -++ offload->flow->flags |= FLOW_OFFLOAD_HW; -++} -++ -++static void flow_offload_hw_work_del(struct flow_offload_hw *offload) -++{ -++ struct net *net = read_pnet(&offload->flow_hw_net); -++ -++ do_flow_offload_hw(net, offload->flow, FLOW_OFFLOAD_DEL); -++} -++ -++static void flow_offload_hw_work(struct work_struct *work) -++{ -++ struct flow_offload_hw *offload, *next; -++ LIST_HEAD(hw_offload_pending); -++ -++ spin_lock_bh(&flow_offload_hw_pending_list_lock); -++ list_replace_init(&flow_offload_hw_pending_list, &hw_offload_pending); -++ spin_unlock_bh(&flow_offload_hw_pending_list_lock); -++ -++ list_for_each_entry_safe(offload, next, &hw_offload_pending, list) { -++ switch (offload->type) { -++ case FLOW_OFFLOAD_ADD: -++ flow_offload_hw_work_add(offload); -++ break; -++ case FLOW_OFFLOAD_DEL: -++ flow_offload_hw_work_del(offload); -++ break; -++ } -++ if (offload->ct) -++ nf_conntrack_put(&offload->ct->ct_general); -++ list_del(&offload->list); -++ kfree(offload); -++ } -++} -++ -++static void flow_offload_queue_work(struct flow_offload_hw *offload) -++{ -++ spin_lock_bh(&flow_offload_hw_pending_list_lock); -++ list_add_tail(&offload->list, &flow_offload_hw_pending_list); -++ spin_unlock_bh(&flow_offload_hw_pending_list_lock); -++ -++ schedule_work(&nf_flow_offload_hw_work); -++} -++ -++static void flow_offload_hw_add(struct net *net, struct flow_offload *flow, -++ struct nf_conn *ct) -++{ -++ struct flow_offload_hw *offload; -++ -++ offload = kmalloc(sizeof(struct flow_offload_hw), GFP_ATOMIC); -++ if (!offload) -++ return; -++ -++ nf_conntrack_get(&ct->ct_general); -++ offload->type = FLOW_OFFLOAD_ADD; -++ offload->ct = ct; -++ offload->flow = flow; -++ write_pnet(&offload->flow_hw_net, net); -++ -++ flow_offload_queue_work(offload); -++} -++ -++static void flow_offload_hw_del(struct net *net, struct flow_offload *flow) -++{ -++ struct flow_offload_hw *offload; -++ -++ offload = kmalloc(sizeof(struct flow_offload_hw), GFP_ATOMIC); -++ if (!offload) -++ return; -++ -++ offload->type = FLOW_OFFLOAD_DEL; -++ offload->ct = NULL; -++ offload->flow = flow; -++ write_pnet(&offload->flow_hw_net, net); -++ -++ flow_offload_queue_work(offload); -++} -++ -++static const struct nf_flow_table_hw flow_offload_hw = { -++ .add = flow_offload_hw_add, -++ .del = flow_offload_hw_del, -++ .owner = THIS_MODULE, -++}; -++ -++static int __init nf_flow_table_hw_module_init(void) -++{ -++ INIT_WORK(&nf_flow_offload_hw_work, flow_offload_hw_work); -++ nf_flow_table_hw_register(&flow_offload_hw); -++ -++ return 0; -++} -++ -++static void __exit nf_flow_table_hw_module_exit(void) -++{ -++ struct flow_offload_hw *offload, *next; -++ LIST_HEAD(hw_offload_pending); -++ -++ nf_flow_table_hw_unregister(&flow_offload_hw); -++ cancel_work_sync(&nf_flow_offload_hw_work); -++ -++ list_for_each_entry_safe(offload, next, &hw_offload_pending, list) { -++ if (offload->ct) -++ nf_conntrack_put(&offload->ct->ct_general); -++ list_del(&offload->list); -++ kfree(offload); -++ } -++} -++ -++module_init(nf_flow_table_hw_module_init); -++module_exit(nf_flow_table_hw_module_exit); -++ -++MODULE_LICENSE("GPL"); -++MODULE_AUTHOR("Pablo Neira Ayuso "); -++MODULE_ALIAS("nf-flow-table-hw"); -+--- a/net/netfilter/nf_tables_api.c -++++ b/net/netfilter/nf_tables_api.c -+@@ -4961,6 +4961,14 @@ static int nf_tables_flowtable_parse_hoo -+ if (err < 0) -+ goto err1; -+ -++ for (i = 0; i < n; i++) { -++ if (flowtable->data.flags & NF_FLOWTABLE_F_HW && -++ !dev_array[i]->netdev_ops->ndo_flow_offload) { -++ err = -EOPNOTSUPP; -++ goto err1; -++ } -++ } -++ -+ ops = kzalloc(sizeof(struct nf_hook_ops) * n, GFP_KERNEL); -+ if (!ops) { -+ err = -ENOMEM; -+@@ -5091,10 +5099,19 @@ static int nf_tables_newflowtable(struct -+ } -+ -+ flowtable->data.type = type; -++ write_pnet(&flowtable->data.ft_net, net); -++ -+ err = type->init(&flowtable->data); -+ if (err < 0) -+ goto err3; -+ -++ if (nla[NFTA_FLOWTABLE_FLAGS]) { -++ flowtable->data.flags = -++ ntohl(nla_get_be32(nla[NFTA_FLOWTABLE_FLAGS])); -++ if (flowtable->data.flags & ~NF_FLOWTABLE_F_HW) -++ goto err4; -++ } -++ -+ err = nf_tables_flowtable_parse_hook(&ctx, nla[NFTA_FLOWTABLE_HOOK], -+ flowtable); -+ if (err < 0) -+@@ -5192,7 +5209,8 @@ static int nf_tables_fill_flowtable_info -+ nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) || -+ nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use)) || -+ nla_put_be64(skb, NFTA_FLOWTABLE_HANDLE, cpu_to_be64(flowtable->handle), -+- NFTA_FLOWTABLE_PAD)) -++ NFTA_FLOWTABLE_PAD) || -++ nla_put_be32(skb, NFTA_FLOWTABLE_FLAGS, htonl(flowtable->data.flags))) -+ goto nla_put_failure; -+ -+ nest = nla_nest_start(skb, NFTA_FLOWTABLE_HOOK); -+--- a/net/netfilter/nft_flow_offload.c -++++ b/net/netfilter/nft_flow_offload.c -+@@ -110,6 +110,9 @@ static void nft_flow_offload_eval(const -+ if (ret < 0) -+ goto err_flow_add; -+ -++ if (flowtable->flags & NF_FLOWTABLE_F_HW) -++ nf_flow_offload_hw_add(nft_net(pkt), flow, ct); -++ -+ return; -+ -+ err_flow_add: -diff --git a/target/linux/generic/pending-4.14/641-netfilter-nf_flow_table-support-hw-offload-through-v.patch b/target/linux/generic/pending-4.14/641-netfilter-nf_flow_table-support-hw-offload-through-v.patch -new file mode 100644 -index 0000000000..e1b13a1ad4 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/641-netfilter-nf_flow_table-support-hw-offload-through-v.patch -@@ -0,0 +1,306 @@ -+From: Felix Fietkau -+Date: Thu, 15 Mar 2018 20:46:31 +0100 -+Subject: [PATCH] netfilter: nf_flow_table: support hw offload through -+ virtual interfaces -+ -+There are hardware offload devices that support offloading VLANs and -+PPPoE devices. Additionally, it is useful to be able to offload packets -+routed through bridge interfaces as well. -+Add support for finding the path to the offload device through these -+virtual interfaces, while collecting useful parameters for the offload -+device, like VLAN ID/protocol, PPPoE session and Ethernet MAC address. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/include/linux/netdevice.h -++++ b/include/linux/netdevice.h -+@@ -827,6 +827,7 @@ struct xfrmdev_ops { -+ #endif -+ -+ struct flow_offload; -++struct flow_offload_hw_path; -+ -+ enum flow_offload_type { -+ FLOW_OFFLOAD_ADD = 0, -+@@ -1064,8 +1065,15 @@ enum flow_offload_type { -+ * int (*ndo_bridge_dellink)(struct net_device *dev, struct nlmsghdr *nlh, -+ * u16 flags); -+ * -++ * int (*ndo_flow_offload_check)(struct flow_offload_hw_path *path); -++ * For virtual devices like bridges, vlan, and pppoe, fill in the -++ * underlying network device that can be used for offloading connections. -++ * Return an error if offloading is not supported. -++ * -+ * int (*ndo_flow_offload)(enum flow_offload_type type, -+- * struct flow_offload *flow); -++ * struct flow_offload *flow, -++ * struct flow_offload_hw_path *src, -++ * struct flow_offload_hw_path *dest); -+ * Adds/deletes flow entry to/from net device flowtable. -+ * -+ * int (*ndo_change_carrier)(struct net_device *dev, bool new_carrier); -+@@ -1292,8 +1300,11 @@ struct net_device_ops { -+ int (*ndo_bridge_dellink)(struct net_device *dev, -+ struct nlmsghdr *nlh, -+ u16 flags); -++ int (*ndo_flow_offload_check)(struct flow_offload_hw_path *path); -+ int (*ndo_flow_offload)(enum flow_offload_type type, -+- struct flow_offload *flow); -++ struct flow_offload *flow, -++ struct flow_offload_hw_path *src, -++ struct flow_offload_hw_path *dest); -+ int (*ndo_change_carrier)(struct net_device *dev, -+ bool new_carrier); -+ int (*ndo_get_phys_port_id)(struct net_device *dev, -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -86,6 +86,21 @@ struct flow_offload { -+ }; -+ }; -+ -++#define FLOW_OFFLOAD_PATH_ETHERNET BIT(0) -++#define FLOW_OFFLOAD_PATH_VLAN BIT(1) -++#define FLOW_OFFLOAD_PATH_PPPOE BIT(2) -++ -++struct flow_offload_hw_path { -++ struct net_device *dev; -++ u32 flags; -++ -++ u8 eth_src[ETH_ALEN]; -++ u8 eth_dest[ETH_ALEN]; -++ u16 vlan_proto; -++ u16 vlan_id; -++ u16 pppoe_sid; -++}; -++ -+ #define NF_FLOW_TIMEOUT (30 * HZ) -+ -+ struct nf_flow_route { -+--- a/net/netfilter/nf_flow_table_hw.c -++++ b/net/netfilter/nf_flow_table_hw.c -+@@ -19,48 +19,77 @@ struct flow_offload_hw { -+ enum flow_offload_type type; -+ struct flow_offload *flow; -+ struct nf_conn *ct; -+- possible_net_t flow_hw_net; -++ -++ struct flow_offload_hw_path src; -++ struct flow_offload_hw_path dest; -+ }; -+ -+-static int do_flow_offload_hw(struct net *net, struct flow_offload *flow, -+- int type) -++static void flow_offload_check_ethernet(struct flow_offload_tuple *tuple, -++ struct dst_entry *dst, -++ struct flow_offload_hw_path *path) -+ { -+- struct net_device *indev; -+- int ret, ifindex; -++ struct net_device *dev = path->dev; -++ struct neighbour *n; -+ -+- ifindex = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.iifidx; -+- indev = dev_get_by_index(net, ifindex); -+- if (WARN_ON(!indev)) -+- return 0; -+- -+- mutex_lock(&nf_flow_offload_hw_mutex); -+- ret = indev->netdev_ops->ndo_flow_offload(type, flow); -+- mutex_unlock(&nf_flow_offload_hw_mutex); -++ if (dev->type != ARPHRD_ETHER) -++ return; -+ -+- dev_put(indev); -++ memcpy(path->eth_src, path->dev->dev_addr, ETH_ALEN); -++ n = dst_neigh_lookup(dst, &tuple->src_v4); -++ if (!n) -++ return; -+ -+- return ret; -++ memcpy(path->eth_dest, n->ha, ETH_ALEN); -++ path->flags |= FLOW_OFFLOAD_PATH_ETHERNET; -++ neigh_release(n); -+ } -+ -+-static void flow_offload_hw_work_add(struct flow_offload_hw *offload) -++static int flow_offload_check_path(struct net *net, -++ struct flow_offload_tuple *tuple, -++ struct dst_entry *dst, -++ struct flow_offload_hw_path *path) -+ { -+- struct net *net; -+- int ret; -++ struct net_device *dev; -+ -+- if (nf_ct_is_dying(offload->ct)) -+- return; -++ dev = dev_get_by_index_rcu(net, tuple->iifidx); -++ if (!dev) -++ return -ENOENT; -++ -++ path->dev = dev; -++ flow_offload_check_ethernet(tuple, dst, path); -+ -+- net = read_pnet(&offload->flow_hw_net); -+- ret = do_flow_offload_hw(net, offload->flow, FLOW_OFFLOAD_ADD); -+- if (ret >= 0) -+- offload->flow->flags |= FLOW_OFFLOAD_HW; -++ if (dev->netdev_ops->ndo_flow_offload_check) -++ return dev->netdev_ops->ndo_flow_offload_check(path); -++ -++ return 0; -+ } -+ -+-static void flow_offload_hw_work_del(struct flow_offload_hw *offload) -++static int do_flow_offload_hw(struct flow_offload_hw *offload) -+ { -+- struct net *net = read_pnet(&offload->flow_hw_net); -++ struct net_device *src_dev = offload->src.dev; -++ struct net_device *dest_dev = offload->dest.dev; -++ int ret; -++ -++ ret = src_dev->netdev_ops->ndo_flow_offload(offload->type, -++ offload->flow, -++ &offload->src, -++ &offload->dest); -++ -++ /* restore devices in case the driver mangled them */ -++ offload->src.dev = src_dev; -++ offload->dest.dev = dest_dev; -+ -+- do_flow_offload_hw(net, offload->flow, FLOW_OFFLOAD_DEL); -++ return ret; -++} -++ -++static void flow_offload_hw_free(struct flow_offload_hw *offload) -++{ -++ dev_put(offload->src.dev); -++ dev_put(offload->dest.dev); -++ if (offload->ct) -++ nf_conntrack_put(&offload->ct->ct_general); -++ list_del(&offload->list); -++ kfree(offload); -+ } -+ -+ static void flow_offload_hw_work(struct work_struct *work) -+@@ -73,18 +102,22 @@ static void flow_offload_hw_work(struct -+ spin_unlock_bh(&flow_offload_hw_pending_list_lock); -+ -+ list_for_each_entry_safe(offload, next, &hw_offload_pending, list) { -++ mutex_lock(&nf_flow_offload_hw_mutex); -+ switch (offload->type) { -+ case FLOW_OFFLOAD_ADD: -+- flow_offload_hw_work_add(offload); -++ if (nf_ct_is_dying(offload->ct)) -++ break; -++ -++ if (do_flow_offload_hw(offload) >= 0) -++ offload->flow->flags |= FLOW_OFFLOAD_HW; -+ break; -+ case FLOW_OFFLOAD_DEL: -+- flow_offload_hw_work_del(offload); -++ do_flow_offload_hw(offload); -+ break; -+ } -+- if (offload->ct) -+- nf_conntrack_put(&offload->ct->ct_general); -+- list_del(&offload->list); -+- kfree(offload); -++ mutex_unlock(&nf_flow_offload_hw_mutex); -++ -++ flow_offload_hw_free(offload); -+ } -+ } -+ -+@@ -97,20 +130,56 @@ static void flow_offload_queue_work(stru -+ schedule_work(&nf_flow_offload_hw_work); -+ } -+ -++static struct flow_offload_hw * -++flow_offload_hw_prepare(struct net *net, struct flow_offload *flow) -++{ -++ struct flow_offload_hw_path src = {}; -++ struct flow_offload_hw_path dest = {}; -++ struct flow_offload_tuple *tuple_s, *tuple_d; -++ struct flow_offload_hw *offload = NULL; -++ -++ rcu_read_lock_bh(); -++ -++ tuple_s = &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple; -++ tuple_d = &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple; -++ -++ if (flow_offload_check_path(net, tuple_s, tuple_d->dst_cache, &src)) -++ goto out; -++ -++ if (flow_offload_check_path(net, tuple_d, tuple_s->dst_cache, &dest)) -++ goto out; -++ -++ if (!src.dev->netdev_ops->ndo_flow_offload) -++ goto out; -++ -++ offload = kzalloc(sizeof(struct flow_offload_hw), GFP_ATOMIC); -++ if (!offload) -++ goto out; -++ -++ dev_hold(src.dev); -++ dev_hold(dest.dev); -++ offload->src = src; -++ offload->dest = dest; -++ offload->flow = flow; -++ -++out: -++ rcu_read_unlock_bh(); -++ -++ return offload; -++} -++ -+ static void flow_offload_hw_add(struct net *net, struct flow_offload *flow, -+ struct nf_conn *ct) -+ { -+ struct flow_offload_hw *offload; -+ -+- offload = kmalloc(sizeof(struct flow_offload_hw), GFP_ATOMIC); -++ offload = flow_offload_hw_prepare(net, flow); -+ if (!offload) -+ return; -+ -+ nf_conntrack_get(&ct->ct_general); -+ offload->type = FLOW_OFFLOAD_ADD; -+ offload->ct = ct; -+- offload->flow = flow; -+- write_pnet(&offload->flow_hw_net, net); -+ -+ flow_offload_queue_work(offload); -+ } -+@@ -119,14 +188,11 @@ static void flow_offload_hw_del(struct n -+ { -+ struct flow_offload_hw *offload; -+ -+- offload = kmalloc(sizeof(struct flow_offload_hw), GFP_ATOMIC); -++ offload = flow_offload_hw_prepare(net, flow); -+ if (!offload) -+ return; -+ -+ offload->type = FLOW_OFFLOAD_DEL; -+- offload->ct = NULL; -+- offload->flow = flow; -+- write_pnet(&offload->flow_hw_net, net); -+ -+ flow_offload_queue_work(offload); -+ } -+@@ -153,12 +219,8 @@ static void __exit nf_flow_table_hw_modu -+ nf_flow_table_hw_unregister(&flow_offload_hw); -+ cancel_work_sync(&nf_flow_offload_hw_work); -+ -+- list_for_each_entry_safe(offload, next, &hw_offload_pending, list) { -+- if (offload->ct) -+- nf_conntrack_put(&offload->ct->ct_general); -+- list_del(&offload->list); -+- kfree(offload); -+- } -++ list_for_each_entry_safe(offload, next, &hw_offload_pending, list) -++ flow_offload_hw_free(offload); -+ } -+ -+ module_init(nf_flow_table_hw_module_init); -diff --git a/target/linux/generic/pending-4.14/642-net-8021q-support-hardware-flow-table-offload.patch b/target/linux/generic/pending-4.14/642-net-8021q-support-hardware-flow-table-offload.patch -new file mode 100644 -index 0000000000..4adad67d54 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/642-net-8021q-support-hardware-flow-table-offload.patch -@@ -0,0 +1,60 @@ -+From: Felix Fietkau -+Date: Thu, 15 Mar 2018 20:49:58 +0100 -+Subject: [PATCH] net: 8021q: support hardware flow table offload -+ -+Add the VLAN ID and protocol information -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/8021q/vlan_dev.c -++++ b/net/8021q/vlan_dev.c -+@@ -32,6 +32,10 @@ -+ #include -+ #include -+ #include -++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) -++#include -++#include -++#endif -+ -+ #include "vlan.h" -+ #include "vlanproc.h" -+@@ -769,6 +773,27 @@ static int vlan_dev_get_iflink(const str -+ return real_dev->ifindex; -+ } -+ -++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) -++static int vlan_dev_flow_offload_check(struct flow_offload_hw_path *path) -++{ -++ struct net_device *dev = path->dev; -++ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); -++ -++ if (path->flags & FLOW_OFFLOAD_PATH_VLAN) -++ return -EEXIST; -++ -++ path->flags |= FLOW_OFFLOAD_PATH_VLAN; -++ path->vlan_proto = vlan->vlan_proto; -++ path->vlan_id = vlan->vlan_id; -++ path->dev = vlan->real_dev; -++ -++ if (vlan->real_dev->netdev_ops->ndo_flow_offload_check) -++ return vlan->real_dev->netdev_ops->ndo_flow_offload_check(path); -++ -++ return 0; -++} -++#endif /* CONFIG_NF_FLOW_TABLE */ -++ -+ static const struct ethtool_ops vlan_ethtool_ops = { -+ .get_link_ksettings = vlan_ethtool_get_link_ksettings, -+ .get_drvinfo = vlan_ethtool_get_drvinfo, -+@@ -806,6 +831,9 @@ static const struct net_device_ops vlan_ -+ .ndo_fix_features = vlan_dev_fix_features, -+ .ndo_get_lock_subclass = vlan_dev_get_lock_subclass, -+ .ndo_get_iflink = vlan_dev_get_iflink, -++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) -++ .ndo_flow_offload_check = vlan_dev_flow_offload_check, -++#endif -+ }; -+ -+ static void vlan_dev_free(struct net_device *dev) -diff --git a/target/linux/generic/pending-4.14/643-net-bridge-support-hardware-flow-table-offload.patch b/target/linux/generic/pending-4.14/643-net-bridge-support-hardware-flow-table-offload.patch -new file mode 100644 -index 0000000000..b54d3cb48f ---- /dev/null -+++ b/target/linux/generic/pending-4.14/643-net-bridge-support-hardware-flow-table-offload.patch -@@ -0,0 +1,61 @@ -+From: Felix Fietkau -+Date: Thu, 15 Mar 2018 20:50:37 +0100 -+Subject: [PATCH] net: bridge: support hardware flow table offload -+ -+Look up the real device and pass it on -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/bridge/br_device.c -++++ b/net/bridge/br_device.c -+@@ -18,6 +18,10 @@ -+ #include -+ #include -+ #include -++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) -++#include -++#include -++#endif -+ -+ #include -+ #include "br_private.h" -+@@ -346,6 +350,28 @@ static const struct ethtool_ops br_ethto -+ .get_link = ethtool_op_get_link, -+ }; -+ -++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) -++static int br_flow_offload_check(struct flow_offload_hw_path *path) -++{ -++ struct net_device *dev = path->dev; -++ struct net_bridge *br = netdev_priv(dev); -++ struct net_bridge_fdb_entry *dst; -++ -++ if (!(path->flags & FLOW_OFFLOAD_PATH_ETHERNET)) -++ return -EINVAL; -++ -++ dst = br_fdb_find_rcu(br, path->eth_dest, path->vlan_id); -++ if (!dst || !dst->dst) -++ return -ENOENT; -++ -++ path->dev = dst->dst->dev; -++ if (path->dev->netdev_ops->ndo_flow_offload_check) -++ return path->dev->netdev_ops->ndo_flow_offload_check(path); -++ -++ return 0; -++} -++#endif /* CONFIG_NF_FLOW_TABLE */ -++ -+ static const struct net_device_ops br_netdev_ops = { -+ .ndo_open = br_dev_open, -+ .ndo_stop = br_dev_stop, -+@@ -373,6 +399,9 @@ static const struct net_device_ops br_ne -+ .ndo_bridge_setlink = br_setlink, -+ .ndo_bridge_dellink = br_dellink, -+ .ndo_features_check = passthru_features_check, -++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) -++ .ndo_flow_offload_check = br_flow_offload_check, -++#endif -+ }; -+ -+ static struct device_type br_type = { -diff --git a/target/linux/generic/pending-4.14/644-net-pppoe-support-hardware-flow-table-offload.patch b/target/linux/generic/pending-4.14/644-net-pppoe-support-hardware-flow-table-offload.patch -new file mode 100644 -index 0000000000..191cbcfb82 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/644-net-pppoe-support-hardware-flow-table-offload.patch -@@ -0,0 +1,125 @@ -+From: Felix Fietkau -+Date: Thu, 15 Mar 2018 21:15:00 +0100 -+Subject: [PATCH] net: pppoe: support hardware flow table offload -+ -+Pass on the PPPoE session ID and the remote MAC address -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/ppp/ppp_generic.c -++++ b/drivers/net/ppp/ppp_generic.c -+@@ -56,6 +56,11 @@ -+ #include -+ #include -+ -++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) -++#include -++#include -++#endif -++ -+ #define PPP_VERSION "2.4.2" -+ -+ /* -+@@ -1382,12 +1387,37 @@ static void ppp_dev_priv_destructor(stru -+ ppp_destroy_interface(ppp); -+ } -+ -++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) -++static int ppp_flow_offload_check(struct flow_offload_hw_path *path) -++{ -++ struct ppp *ppp = netdev_priv(path->dev); -++ struct ppp_channel *chan; -++ struct channel *pch; -++ -++ if (ppp->flags & SC_MULTILINK) -++ return -EOPNOTSUPP; -++ -++ if (list_empty(&ppp->channels)) -++ return -ENODEV; -++ -++ pch = list_first_entry(&ppp->channels, struct channel, clist); -++ chan = pch->chan; -++ if (!chan->ops->flow_offload_check) -++ return -EOPNOTSUPP; -++ -++ return chan->ops->flow_offload_check(chan, path); -++} -++#endif /* CONFIG_NF_FLOW_TABLE */ -++ -+ static const struct net_device_ops ppp_netdev_ops = { -+ .ndo_init = ppp_dev_init, -+ .ndo_uninit = ppp_dev_uninit, -+ .ndo_start_xmit = ppp_start_xmit, -+ .ndo_do_ioctl = ppp_net_ioctl, -+ .ndo_get_stats64 = ppp_get_stats64, -++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) -++ .ndo_flow_offload_check = ppp_flow_offload_check, -++#endif -+ }; -+ -+ static struct device_type ppp_type = { -+--- a/drivers/net/ppp/pppoe.c -++++ b/drivers/net/ppp/pppoe.c -+@@ -78,6 +78,11 @@ -+ #include -+ #include -+ -++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) -++#include -++#include -++#endif -++ -+ #include -+ #include -+ #include -+@@ -981,8 +986,36 @@ static int pppoe_xmit(struct ppp_channel -+ return __pppoe_xmit(sk, skb); -+ } -+ -++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) -++static int pppoe_flow_offload_check(struct ppp_channel *chan, -++ struct flow_offload_hw_path *path) -++{ -++ struct sock *sk = (struct sock *)chan->private; -++ struct pppox_sock *po = pppox_sk(sk); -++ struct net_device *dev = po->pppoe_dev; -++ -++ if (sock_flag(sk, SOCK_DEAD) || -++ !(sk->sk_state & PPPOX_CONNECTED) || !dev) -++ return -ENODEV; -++ -++ path->dev = po->pppoe_dev; -++ path->flags |= FLOW_OFFLOAD_PATH_PPPOE; -++ memcpy(path->eth_src, po->pppoe_dev->dev_addr, ETH_ALEN); -++ memcpy(path->eth_dest, po->pppoe_pa.remote, ETH_ALEN); -++ path->pppoe_sid = be16_to_cpu(po->num); -++ -++ if (path->dev->netdev_ops->ndo_flow_offload_check) -++ return path->dev->netdev_ops->ndo_flow_offload_check(path); -++ -++ return 0; -++} -++#endif /* CONFIG_NF_FLOW_TABLE */ -++ -+ static const struct ppp_channel_ops pppoe_chan_ops = { -+ .start_xmit = pppoe_xmit, -++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) -++ .flow_offload_check = pppoe_flow_offload_check, -++#endif -+ }; -+ -+ static int pppoe_recvmsg(struct socket *sock, struct msghdr *m, -+--- a/include/linux/ppp_channel.h -++++ b/include/linux/ppp_channel.h -+@@ -32,6 +32,10 @@ struct ppp_channel_ops { -+ int (*start_xmit)(struct ppp_channel *, struct sk_buff *); -+ /* Handle an ioctl call that has come in via /dev/ppp. */ -+ int (*ioctl)(struct ppp_channel *, unsigned int, unsigned long); -++ -++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) -++ int (*flow_offload_check)(struct ppp_channel *, struct flow_offload_hw_path *); -++#endif -+ }; -+ -+ struct ppp_channel { -diff --git a/target/linux/generic/pending-4.14/645-netfilter-nf_flow_table-rework-hardware-offload-time.patch b/target/linux/generic/pending-4.14/645-netfilter-nf_flow_table-rework-hardware-offload-time.patch -new file mode 100644 -index 0000000000..ad6f42bb4e ---- /dev/null -+++ b/target/linux/generic/pending-4.14/645-netfilter-nf_flow_table-rework-hardware-offload-time.patch -@@ -0,0 +1,37 @@ -+From: Felix Fietkau -+Date: Sun, 25 Mar 2018 21:10:55 +0200 -+Subject: [PATCH] netfilter: nf_flow_table: rework hardware offload timeout -+ handling -+ -+Some offload implementations send keepalive packets + explicit -+notifications of TCP FIN/RST packets. In this case it is more convenient -+to simply let the driver update flow->timeout handling and use the -+regular flow offload gc step. -+ -+For drivers that manage their own lifetime, a separate flag can be set -+to avoid gc timeouts. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -76,6 +76,7 @@ struct flow_offload_tuple_rhash { -+ #define FLOW_OFFLOAD_DYING 0x4 -+ #define FLOW_OFFLOAD_TEARDOWN 0x8 -+ #define FLOW_OFFLOAD_HW 0x10 -++#define FLOW_OFFLOAD_KEEP 0x20 -+ -+ struct flow_offload { -+ struct flow_offload_tuple_rhash tuplehash[FLOW_OFFLOAD_DIR_MAX]; -+--- a/net/netfilter/nf_flow_table_core.c -++++ b/net/netfilter/nf_flow_table_core.c -+@@ -359,7 +359,7 @@ static int nf_flow_offload_gc_step(struc -+ if (!teardown) -+ nf_ct_offload_timeout(flow); -+ -+- if (nf_flow_in_hw(flow) && !teardown) -++ if ((flow->flags & FLOW_OFFLOAD_KEEP) && !teardown) -+ continue; -+ -+ if (nf_flow_has_expired(flow) || teardown) -diff --git a/target/linux/generic/pending-4.14/646-netfilter-nf_flow_table-rework-private-driver-data.patch b/target/linux/generic/pending-4.14/646-netfilter-nf_flow_table-rework-private-driver-data.patch -new file mode 100644 -index 0000000000..f94d7ad301 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/646-netfilter-nf_flow_table-rework-private-driver-data.patch -@@ -0,0 +1,25 @@ -+From: Felix Fietkau -+Date: Fri, 27 Apr 2018 14:42:14 +0200 -+Subject: [PATCH] netfilter: nf_flow_table: rework private driver data -+ -+Move the timeout out of the union, since it can be shared between the -+driver and the stack. Add a private pointer that the driver can use to -+point to its own data structures -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/include/net/netfilter/nf_flow_table.h -++++ b/include/net/netfilter/nf_flow_table.h -+@@ -81,9 +81,10 @@ struct flow_offload_tuple_rhash { -+ struct flow_offload { -+ struct flow_offload_tuple_rhash tuplehash[FLOW_OFFLOAD_DIR_MAX]; -+ u32 flags; -++ u32 timeout; -+ union { -+ /* Your private driver data here. */ -+- u32 timeout; -++ void *priv; -+ }; -+ }; -+ -diff --git a/target/linux/generic/pending-4.14/655-increase_skb_pad.patch b/target/linux/generic/pending-4.14/655-increase_skb_pad.patch -new file mode 100644 -index 0000000000..fa47fe62a8 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/655-increase_skb_pad.patch -@@ -0,0 +1,20 @@ -+From: Felix Fietkau -+Subject: kernel: add a few patches for avoiding unnecessary skb reallocations - significantly improves ethernet<->wireless performance -+ -+lede-commit: 6f89cffc9add6939d44a6b54cf9a5e77849aa7fd -+Signed-off-by: Felix Fietkau -+--- -+ include/linux/skbuff.h | 2 +- -+ 1 file changed, 1 insertion(+), 1 deletion(-) -+ -+--- a/include/linux/skbuff.h -++++ b/include/linux/skbuff.h -+@@ -2496,7 +2496,7 @@ static inline int pskb_network_may_pull( -+ * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8) -+ */ -+ #ifndef NET_SKB_PAD -+-#define NET_SKB_PAD max(32, L1_CACHE_BYTES) -++#define NET_SKB_PAD max(64, L1_CACHE_BYTES) -+ #endif -+ -+ int ___pskb_trim(struct sk_buff *skb, unsigned int len); -diff --git a/target/linux/generic/pending-4.14/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch b/target/linux/generic/pending-4.14/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch -new file mode 100644 -index 0000000000..96c8ae9c12 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch -@@ -0,0 +1,500 @@ -+From: Steven Barth -+Subject: Add support for MAP-E FMRs (mesh mode) -+ -+MAP-E FMRs (draft-ietf-softwire-map-10) are rules for IPv4-communication -+between MAP CEs (mesh mode) without the need to forward such data to a -+border relay. This is similar to how 6rd works but for IPv4 over IPv6. -+ -+Signed-off-by: Steven Barth -+--- -+ include/net/ip6_tunnel.h | 13 ++ -+ include/uapi/linux/if_tunnel.h | 13 ++ -+ net/ipv6/ip6_tunnel.c | 276 +++++++++++++++++++++++++++++++++++++++-- -+ 3 files changed, 291 insertions(+), 11 deletions(-) -+ -+--- a/include/net/ip6_tunnel.h -++++ b/include/net/ip6_tunnel.h -+@@ -18,6 +18,18 @@ -+ /* determine capability on a per-packet basis */ -+ #define IP6_TNL_F_CAP_PER_PACKET 0x40000 -+ -++/* IPv6 tunnel FMR */ -++struct __ip6_tnl_fmr { -++ struct __ip6_tnl_fmr *next; /* next fmr in list */ -++ struct in6_addr ip6_prefix; -++ struct in_addr ip4_prefix; -++ -++ __u8 ip6_prefix_len; -++ __u8 ip4_prefix_len; -++ __u8 ea_len; -++ __u8 offset; -++}; -++ -+ struct __ip6_tnl_parm { -+ char name[IFNAMSIZ]; /* name of tunnel device */ -+ int link; /* ifindex of underlying L2 interface */ -+@@ -29,6 +41,7 @@ struct __ip6_tnl_parm { -+ __u32 flags; /* tunnel flags */ -+ struct in6_addr laddr; /* local tunnel end-point address */ -+ struct in6_addr raddr; /* remote tunnel end-point address */ -++ struct __ip6_tnl_fmr *fmrs; /* FMRs */ -+ -+ __be16 i_flags; -+ __be16 o_flags; -+--- a/include/uapi/linux/if_tunnel.h -++++ b/include/uapi/linux/if_tunnel.h -+@@ -77,10 +77,23 @@ enum { -+ IFLA_IPTUN_ENCAP_DPORT, -+ IFLA_IPTUN_COLLECT_METADATA, -+ IFLA_IPTUN_FWMARK, -++ IFLA_IPTUN_FMRS, -+ __IFLA_IPTUN_MAX, -+ }; -+ #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1) -+ -++enum { -++ IFLA_IPTUN_FMR_UNSPEC, -++ IFLA_IPTUN_FMR_IP6_PREFIX, -++ IFLA_IPTUN_FMR_IP4_PREFIX, -++ IFLA_IPTUN_FMR_IP6_PREFIX_LEN, -++ IFLA_IPTUN_FMR_IP4_PREFIX_LEN, -++ IFLA_IPTUN_FMR_EA_LEN, -++ IFLA_IPTUN_FMR_OFFSET, -++ __IFLA_IPTUN_FMR_MAX, -++}; -++#define IFLA_IPTUN_FMR_MAX (__IFLA_IPTUN_FMR_MAX - 1) -++ -+ enum tunnel_encap_types { -+ TUNNEL_ENCAP_NONE, -+ TUNNEL_ENCAP_FOU, -+--- a/net/ipv6/ip6_tunnel.c -++++ b/net/ipv6/ip6_tunnel.c -+@@ -16,6 +16,8 @@ -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -++ * Changes: -++ * Steven Barth : MAP-E FMR support -+ */ -+ -+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+@@ -72,9 +74,9 @@ static bool log_ecn_error = true; -+ module_param(log_ecn_error, bool, 0644); -+ MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN"); -+ -+-static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2) -++static u32 HASH(const struct in6_addr *addr) -+ { -+- u32 hash = ipv6_addr_hash(addr1) ^ ipv6_addr_hash(addr2); -++ u32 hash = ipv6_addr_hash(addr); -+ -+ return hash_32(hash, IP6_TUNNEL_HASH_SIZE_SHIFT); -+ } -+@@ -141,20 +143,29 @@ static struct net_device_stats *ip6_get_ -+ static struct ip6_tnl * -+ ip6_tnl_lookup(struct net *net, const struct in6_addr *remote, const struct in6_addr *local) -+ { -+- unsigned int hash = HASH(remote, local); -++ unsigned int hash = HASH(local); -+ struct ip6_tnl *t; -+ struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); -+ struct in6_addr any; -++ struct __ip6_tnl_fmr *fmr; -+ -+ for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { -+- if (ipv6_addr_equal(local, &t->parms.laddr) && -+- ipv6_addr_equal(remote, &t->parms.raddr) && -+- (t->dev->flags & IFF_UP)) -++ if (!ipv6_addr_equal(local, &t->parms.laddr) || -++ !(t->dev->flags & IFF_UP)) -++ continue; -++ -++ if (ipv6_addr_equal(remote, &t->parms.raddr)) -+ return t; -++ -++ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) { -++ if (ipv6_prefix_equal(remote, &fmr->ip6_prefix, -++ fmr->ip6_prefix_len)) -++ return t; -++ } -+ } -+ -+ memset(&any, 0, sizeof(any)); -+- hash = HASH(&any, local); -++ hash = HASH(local); -+ for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { -+ if (ipv6_addr_equal(local, &t->parms.laddr) && -+ ipv6_addr_any(&t->parms.raddr) && -+@@ -162,7 +173,7 @@ ip6_tnl_lookup(struct net *net, const st -+ return t; -+ } -+ -+- hash = HASH(remote, &any); -++ hash = HASH(&any); -+ for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { -+ if (ipv6_addr_equal(remote, &t->parms.raddr) && -+ ipv6_addr_any(&t->parms.laddr) && -+@@ -202,7 +213,7 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n, -+ -+ if (!ipv6_addr_any(remote) || !ipv6_addr_any(local)) { -+ prio = 1; -+- h = HASH(remote, local); -++ h = HASH(local); -+ } -+ return &ip6n->tnls[prio][h]; -+ } -+@@ -383,6 +394,12 @@ ip6_tnl_dev_uninit(struct net_device *de -+ struct net *net = t->net; -+ struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); -+ -++ while (t->parms.fmrs) { -++ struct __ip6_tnl_fmr *next = t->parms.fmrs->next; -++ kfree(t->parms.fmrs); -++ t->parms.fmrs = next; -++ } -++ -+ if (dev == ip6n->fb_tnl_dev) -+ RCU_INIT_POINTER(ip6n->tnls_wc[0], NULL); -+ else -+@@ -779,6 +796,107 @@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t, -+ } -+ EXPORT_SYMBOL_GPL(ip6_tnl_rcv_ctl); -+ -++/** -++ * ip4ip6_fmr_calc - calculate target / source IPv6-address based on FMR -++ * @dest: destination IPv6 address buffer -++ * @skb: received socket buffer -++ * @fmr: MAP FMR -++ * @xmit: Calculate for xmit or rcv -++ **/ -++static void ip4ip6_fmr_calc(struct in6_addr *dest, -++ const struct iphdr *iph, const uint8_t *end, -++ const struct __ip6_tnl_fmr *fmr, bool xmit) -++{ -++ int psidlen = fmr->ea_len - (32 - fmr->ip4_prefix_len); -++ u8 *portp = NULL; -++ bool use_dest_addr; -++ const struct iphdr *dsth = iph; -++ -++ if ((u8*)dsth >= end) -++ return; -++ -++ /* find significant IP header */ -++ if (iph->protocol == IPPROTO_ICMP) { -++ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4); -++ if (ih && ((u8*)&ih[1]) <= end && ( -++ ih->type == ICMP_DEST_UNREACH || -++ ih->type == ICMP_SOURCE_QUENCH || -++ ih->type == ICMP_TIME_EXCEEDED || -++ ih->type == ICMP_PARAMETERPROB || -++ ih->type == ICMP_REDIRECT)) -++ dsth = (const struct iphdr*)&ih[1]; -++ } -++ -++ /* in xmit-path use dest port by default and source port only if -++ this is an ICMP reply to something else; vice versa in rcv-path */ -++ use_dest_addr = (xmit && dsth == iph) || (!xmit && dsth != iph); -++ -++ /* get dst port */ -++ if (((u8*)&dsth[1]) <= end && ( -++ dsth->protocol == IPPROTO_UDP || -++ dsth->protocol == IPPROTO_TCP || -++ dsth->protocol == IPPROTO_SCTP || -++ dsth->protocol == IPPROTO_DCCP)) { -++ /* for UDP, TCP, SCTP and DCCP source and dest port -++ follow IPv4 header directly */ -++ portp = ((u8*)dsth) + dsth->ihl * 4; -++ -++ if (use_dest_addr) -++ portp += sizeof(u16); -++ } else if (iph->protocol == IPPROTO_ICMP) { -++ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4); -++ -++ /* use icmp identifier as port */ -++ if (((u8*)&ih) <= end && ( -++ (use_dest_addr && ( -++ ih->type == ICMP_ECHOREPLY || -++ ih->type == ICMP_TIMESTAMPREPLY || -++ ih->type == ICMP_INFO_REPLY || -++ ih->type == ICMP_ADDRESSREPLY)) || -++ (!use_dest_addr && ( -++ ih->type == ICMP_ECHO || -++ ih->type == ICMP_TIMESTAMP || -++ ih->type == ICMP_INFO_REQUEST || -++ ih->type == ICMP_ADDRESS) -++ ))) -++ portp = (u8*)&ih->un.echo.id; -++ } -++ -++ if ((portp && &portp[2] <= end) || psidlen == 0) { -++ int frombyte = fmr->ip6_prefix_len / 8; -++ int fromrem = fmr->ip6_prefix_len % 8; -++ int bytes = sizeof(struct in6_addr) - frombyte; -++ const u32 *addr = (use_dest_addr) ? &iph->daddr : &iph->saddr; -++ u64 eabits = ((u64)ntohl(*addr)) << (32 + fmr->ip4_prefix_len); -++ u64 t = 0; -++ -++ /* extract PSID from port and add it to eabits */ -++ u16 psidbits = 0; -++ if (psidlen > 0) { -++ psidbits = ((u16)portp[0]) << 8 | ((u16)portp[1]); -++ psidbits >>= 16 - psidlen - fmr->offset; -++ psidbits = (u16)(psidbits << (16 - psidlen)); -++ eabits |= ((u64)psidbits) << (48 - (fmr->ea_len - psidlen)); -++ } -++ -++ /* rewrite destination address */ -++ *dest = fmr->ip6_prefix; -++ memcpy(&dest->s6_addr[10], addr, sizeof(*addr)); -++ dest->s6_addr16[7] = htons(psidbits >> (16 - psidlen)); -++ -++ if (bytes > sizeof(u64)) -++ bytes = sizeof(u64); -++ -++ /* insert eabits */ -++ memcpy(&t, &dest->s6_addr[frombyte], bytes); -++ t = be64_to_cpu(t) & ~(((((u64)1) << fmr->ea_len) - 1) -++ << (64 - fmr->ea_len - fromrem)); -++ t = cpu_to_be64(t | (eabits >> fromrem)); -++ memcpy(&dest->s6_addr[frombyte], &t, bytes); -++ } -++} -++ -++ -+ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb, -+ const struct tnl_ptk_info *tpi, -+ struct metadata_dst *tun_dst, -+@@ -831,6 +949,27 @@ static int __ip6_tnl_rcv(struct ip6_tnl -+ skb_reset_network_header(skb); -+ memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); -+ -++ if (tpi->proto == htons(ETH_P_IP) && tunnel->parms.fmrs && -++ !ipv6_addr_equal(&ipv6h->saddr, &tunnel->parms.raddr)) { -++ /* Packet didn't come from BR, so lookup FMR */ -++ struct __ip6_tnl_fmr *fmr; -++ struct in6_addr expected = tunnel->parms.raddr; -++ for (fmr = tunnel->parms.fmrs; fmr; fmr = fmr->next) -++ if (ipv6_prefix_equal(&ipv6h->saddr, -++ &fmr->ip6_prefix, fmr->ip6_prefix_len)) -++ break; -++ -++ /* Check that IPv6 matches IPv4 source to prevent spoofing */ -++ if (fmr) -++ ip4ip6_fmr_calc(&expected, ip_hdr(skb), -++ skb_tail_pointer(skb), fmr, false); -++ -++ if (!ipv6_addr_equal(&ipv6h->saddr, &expected)) { -++ rcu_read_unlock(); -++ goto drop; -++ } -++ } -++ -+ __skb_tunnel_rx(skb, tunnel->dev, tunnel->net); -+ -+ err = dscp_ecn_decapsulate(tunnel, ipv6h, skb); -+@@ -963,6 +1102,7 @@ static void init_tel_txopt(struct ipv6_t -+ opt->ops.opt_nflen = 8; -+ } -+ -++ -+ /** -+ * ip6_tnl_addr_conflict - compare packet addresses to tunnel's own -+ * @t: the outgoing tunnel device -+@@ -1305,6 +1445,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str -+ { -+ struct ip6_tnl *t = netdev_priv(dev); -+ struct ipv6hdr *ipv6h; -++ struct __ip6_tnl_fmr *fmr; -+ int encap_limit = -1; -+ __u16 offset; -+ struct flowi6 fl6; -+@@ -1372,6 +1513,18 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str -+ fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL); -+ dsfield = INET_ECN_encapsulate(dsfield, ipv6_get_dsfield(ipv6h)); -+ -++ /* try to find matching FMR */ -++ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) { -++ unsigned mshift = 32 - fmr->ip4_prefix_len; -++ if (ntohl(fmr->ip4_prefix.s_addr) >> mshift == -++ ntohl(ip_hdr(skb)->daddr) >> mshift) -++ break; -++ } -++ -++ /* change dstaddr according to FMR */ -++ if (fmr) -++ ip4ip6_fmr_calc(&fl6.daddr, ip_hdr(skb), skb_tail_pointer(skb), fmr, true); -++ -+ if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) -+ return -1; -+ -+@@ -1498,6 +1651,14 @@ ip6_tnl_change(struct ip6_tnl *t, const -+ t->parms.link = p->link; -+ t->parms.proto = p->proto; -+ t->parms.fwmark = p->fwmark; -++ -++ while (t->parms.fmrs) { -++ struct __ip6_tnl_fmr *next = t->parms.fmrs->next; -++ kfree(t->parms.fmrs); -++ t->parms.fmrs = next; -++ } -++ t->parms.fmrs = p->fmrs; -++ -+ dst_cache_reset(&t->dst_cache); -+ ip6_tnl_link_config(t); -+ return 0; -+@@ -1536,6 +1697,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_ -+ p->flowinfo = u->flowinfo; -+ p->link = u->link; -+ p->proto = u->proto; -++ p->fmrs = NULL; -+ memcpy(p->name, u->name, sizeof(u->name)); -+ } -+ -+@@ -1920,6 +2082,15 @@ static int ip6_tnl_validate(struct nlatt -+ return 0; -+ } -+ -++static const struct nla_policy ip6_tnl_fmr_policy[IFLA_IPTUN_FMR_MAX + 1] = { -++ [IFLA_IPTUN_FMR_IP6_PREFIX] = { .len = sizeof(struct in6_addr) }, -++ [IFLA_IPTUN_FMR_IP4_PREFIX] = { .len = sizeof(struct in_addr) }, -++ [IFLA_IPTUN_FMR_IP6_PREFIX_LEN] = { .type = NLA_U8 }, -++ [IFLA_IPTUN_FMR_IP4_PREFIX_LEN] = { .type = NLA_U8 }, -++ [IFLA_IPTUN_FMR_EA_LEN] = { .type = NLA_U8 }, -++ [IFLA_IPTUN_FMR_OFFSET] = { .type = NLA_U8 } -++}; -++ -+ static void ip6_tnl_netlink_parms(struct nlattr *data[], -+ struct __ip6_tnl_parm *parms) -+ { -+@@ -1957,6 +2128,46 @@ static void ip6_tnl_netlink_parms(struct -+ -+ if (data[IFLA_IPTUN_FWMARK]) -+ parms->fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]); -++ -++ if (data[IFLA_IPTUN_FMRS]) { -++ unsigned rem; -++ struct nlattr *fmr; -++ nla_for_each_nested(fmr, data[IFLA_IPTUN_FMRS], rem) { -++ struct nlattr *fmrd[IFLA_IPTUN_FMR_MAX + 1], *c; -++ struct __ip6_tnl_fmr *nfmr; -++ -++ nla_parse_nested(fmrd, IFLA_IPTUN_FMR_MAX, -++ fmr, ip6_tnl_fmr_policy, NULL); -++ -++ if (!(nfmr = kzalloc(sizeof(*nfmr), GFP_KERNEL))) -++ continue; -++ -++ nfmr->offset = 6; -++ -++ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX])) -++ nla_memcpy(&nfmr->ip6_prefix, fmrd[IFLA_IPTUN_FMR_IP6_PREFIX], -++ sizeof(nfmr->ip6_prefix)); -++ -++ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX])) -++ nla_memcpy(&nfmr->ip4_prefix, fmrd[IFLA_IPTUN_FMR_IP4_PREFIX], -++ sizeof(nfmr->ip4_prefix)); -++ -++ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX_LEN])) -++ nfmr->ip6_prefix_len = nla_get_u8(c); -++ -++ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX_LEN])) -++ nfmr->ip4_prefix_len = nla_get_u8(c); -++ -++ if ((c = fmrd[IFLA_IPTUN_FMR_EA_LEN])) -++ nfmr->ea_len = nla_get_u8(c); -++ -++ if ((c = fmrd[IFLA_IPTUN_FMR_OFFSET])) -++ nfmr->offset = nla_get_u8(c); -++ -++ nfmr->next = parms->fmrs; -++ parms->fmrs = nfmr; -++ } -++ } -+ } -+ -+ static bool ip6_tnl_netlink_encap_parms(struct nlattr *data[], -+@@ -2072,6 +2283,12 @@ static void ip6_tnl_dellink(struct net_d -+ -+ static size_t ip6_tnl_get_size(const struct net_device *dev) -+ { -++ const struct ip6_tnl *t = netdev_priv(dev); -++ struct __ip6_tnl_fmr *c; -++ int fmrs = 0; -++ for (c = t->parms.fmrs; c; c = c->next) -++ ++fmrs; -++ -+ return -+ /* IFLA_IPTUN_LINK */ -+ nla_total_size(4) + -+@@ -2101,6 +2318,24 @@ static size_t ip6_tnl_get_size(const str -+ nla_total_size(0) + -+ /* IFLA_IPTUN_FWMARK */ -+ nla_total_size(4) + -++ /* IFLA_IPTUN_FMRS */ -++ nla_total_size(0) + -++ ( -++ /* nest */ -++ nla_total_size(0) + -++ /* IFLA_IPTUN_FMR_IP6_PREFIX */ -++ nla_total_size(sizeof(struct in6_addr)) + -++ /* IFLA_IPTUN_FMR_IP4_PREFIX */ -++ nla_total_size(sizeof(struct in_addr)) + -++ /* IFLA_IPTUN_FMR_EA_LEN */ -++ nla_total_size(1) + -++ /* IFLA_IPTUN_FMR_IP6_PREFIX_LEN */ -++ nla_total_size(1) + -++ /* IFLA_IPTUN_FMR_IP4_PREFIX_LEN */ -++ nla_total_size(1) + -++ /* IFLA_IPTUN_FMR_OFFSET */ -++ nla_total_size(1) -++ ) * fmrs + -+ 0; -+ } -+ -+@@ -2108,6 +2343,9 @@ static int ip6_tnl_fill_info(struct sk_b -+ { -+ struct ip6_tnl *tunnel = netdev_priv(dev); -+ struct __ip6_tnl_parm *parm = &tunnel->parms; -++ struct __ip6_tnl_fmr *c; -++ int fmrcnt = 0; -++ struct nlattr *fmrs; -+ -+ if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || -+ nla_put_in6_addr(skb, IFLA_IPTUN_LOCAL, &parm->laddr) || -+@@ -2117,9 +2355,27 @@ static int ip6_tnl_fill_info(struct sk_b -+ nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) || -+ nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) || -+ nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto) || -+- nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark)) -++ nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark) || -++ !(fmrs = nla_nest_start(skb, IFLA_IPTUN_FMRS))) -+ goto nla_put_failure; -+ -++ for (c = parm->fmrs; c; c = c->next) { -++ struct nlattr *fmr = nla_nest_start(skb, ++fmrcnt); -++ if (!fmr || -++ nla_put(skb, IFLA_IPTUN_FMR_IP6_PREFIX, -++ sizeof(c->ip6_prefix), &c->ip6_prefix) || -++ nla_put(skb, IFLA_IPTUN_FMR_IP4_PREFIX, -++ sizeof(c->ip4_prefix), &c->ip4_prefix) || -++ nla_put_u8(skb, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, c->ip6_prefix_len) || -++ nla_put_u8(skb, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, c->ip4_prefix_len) || -++ nla_put_u8(skb, IFLA_IPTUN_FMR_EA_LEN, c->ea_len) || -++ nla_put_u8(skb, IFLA_IPTUN_FMR_OFFSET, c->offset)) -++ goto nla_put_failure; -++ -++ nla_nest_end(skb, fmr); -++ } -++ nla_nest_end(skb, fmrs); -++ -+ if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, tunnel->encap.type) || -+ nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT, tunnel->encap.sport) || -+ nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT, tunnel->encap.dport) || -+@@ -2159,6 +2415,7 @@ static const struct nla_policy ip6_tnl_p -+ [IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 }, -+ [IFLA_IPTUN_COLLECT_METADATA] = { .type = NLA_FLAG }, -+ [IFLA_IPTUN_FWMARK] = { .type = NLA_U32 }, -++ [IFLA_IPTUN_FMRS] = { .type = NLA_NESTED }, -+ }; -+ -+ static struct rtnl_link_ops ip6_link_ops __read_mostly = { -diff --git a/target/linux/generic/pending-4.14/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-4.14/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch -new file mode 100644 -index 0000000000..3839865712 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch -@@ -0,0 +1,255 @@ -+From: Jonas Gorski -+Subject: ipv6: allow rejecting with "source address failed policy" -+ -+RFC6204 L-14 requires rejecting traffic from invalid addresses with -+ICMPv6 Destination Unreachable, Code 5 (Source address failed ingress/ -+egress policy) on the LAN side, so add an appropriate rule for that. -+ -+Signed-off-by: Jonas Gorski -+--- -+ include/net/netns/ipv6.h | 1 + -+ include/uapi/linux/fib_rules.h | 4 +++ -+ include/uapi/linux/rtnetlink.h | 1 + -+ net/ipv4/fib_semantics.c | 4 +++ -+ net/ipv4/fib_trie.c | 1 + -+ net/ipv4/ipmr.c | 1 + -+ net/ipv6/fib6_rules.c | 4 +++ -+ net/ipv6/ip6mr.c | 2 ++ -+ net/ipv6/route.c | 58 +++++++++++++++++++++++++++++++++++++++++- -+ 9 files changed, 75 insertions(+), 1 deletion(-) -+ -+--- a/include/net/netns/ipv6.h -++++ b/include/net/netns/ipv6.h -+@@ -69,6 +69,7 @@ struct netns_ipv6 { -+ #ifdef CONFIG_IPV6_MULTIPLE_TABLES -+ bool fib6_has_custom_rules; -+ struct rt6_info *ip6_prohibit_entry; -++ struct rt6_info *ip6_policy_failed_entry; -+ struct rt6_info *ip6_blk_hole_entry; -+ struct fib6_table *fib6_local_tbl; -+ struct fib_rules_ops *fib6_rules_ops; -+--- a/include/uapi/linux/fib_rules.h -++++ b/include/uapi/linux/fib_rules.h -+@@ -73,6 +73,10 @@ enum { -+ FR_ACT_BLACKHOLE, /* Drop without notification */ -+ FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */ -+ FR_ACT_PROHIBIT, /* Drop with EACCES */ -++ FR_ACT_RES9, -++ FR_ACT_RES10, -++ FR_ACT_RES11, -++ FR_ACT_POLICY_FAILED, /* Drop with EACCES */ -+ __FR_ACT_MAX, -+ }; -+ -+--- a/include/uapi/linux/rtnetlink.h -++++ b/include/uapi/linux/rtnetlink.h -+@@ -221,6 +221,7 @@ enum { -+ RTN_THROW, /* Not in this table */ -+ RTN_NAT, /* Translate this address */ -+ RTN_XRESOLVE, /* Use external resolver */ -++ RTN_POLICY_FAILED, /* Failed ingress/egress policy */ -+ __RTN_MAX -+ }; -+ -+--- a/net/ipv4/fib_semantics.c -++++ b/net/ipv4/fib_semantics.c -+@@ -139,6 +139,10 @@ const struct fib_prop fib_props[RTN_MAX -+ .error = -EINVAL, -+ .scope = RT_SCOPE_NOWHERE, -+ }, -++ [RTN_POLICY_FAILED] = { -++ .error = -EACCES, -++ .scope = RT_SCOPE_UNIVERSE, -++ }, -+ }; -+ -+ static void rt_fibinfo_free(struct rtable __rcu **rtp) -+--- a/net/ipv4/fib_trie.c -++++ b/net/ipv4/fib_trie.c -+@@ -2472,6 +2472,7 @@ static const char *const rtn_type_names[ -+ [RTN_THROW] = "THROW", -+ [RTN_NAT] = "NAT", -+ [RTN_XRESOLVE] = "XRESOLVE", -++ [RTN_POLICY_FAILED] = "POLICY_FAILED", -+ }; -+ -+ static inline const char *rtn_type(char *buf, size_t len, unsigned int t) -+--- a/net/ipv4/ipmr.c -++++ b/net/ipv4/ipmr.c -+@@ -163,6 +163,7 @@ static int ipmr_rule_action(struct fib_r -+ case FR_ACT_UNREACHABLE: -+ return -ENETUNREACH; -+ case FR_ACT_PROHIBIT: -++ case FR_ACT_POLICY_FAILED: -+ return -EACCES; -+ case FR_ACT_BLACKHOLE: -+ default: -+--- a/net/ipv6/fib6_rules.c -++++ b/net/ipv6/fib6_rules.c -+@@ -121,6 +121,10 @@ static int fib6_rule_action(struct fib_r -+ err = -EACCES; -+ rt = net->ipv6.ip6_prohibit_entry; -+ goto discard_pkt; -++ case FR_ACT_POLICY_FAILED: -++ err = -EACCES; -++ rt = net->ipv6.ip6_policy_failed_entry; -++ goto discard_pkt; -+ } -+ -+ tb_id = fib_rule_get_table(rule, arg); -+--- a/net/ipv6/ip6mr.c -++++ b/net/ipv6/ip6mr.c -+@@ -170,6 +170,8 @@ static int ip6mr_rule_action(struct fib_ -+ return -ENETUNREACH; -+ case FR_ACT_PROHIBIT: -+ return -EACCES; -++ case FR_ACT_POLICY_FAILED: -++ return -EACCES; -+ case FR_ACT_BLACKHOLE: -+ default: -+ return -EINVAL; -+--- a/net/ipv6/route.c -++++ b/net/ipv6/route.c -+@@ -91,6 +91,8 @@ static int ip6_pkt_discard(struct sk_bu -+ static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb); -+ static int ip6_pkt_prohibit(struct sk_buff *skb); -+ static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb); -++static int ip6_pkt_policy_failed(struct sk_buff *skb); -++static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb); -+ static void ip6_link_failure(struct sk_buff *skb); -+ static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, -+ struct sk_buff *skb, u32 mtu, -+@@ -323,6 +325,21 @@ static const struct rt6_info ip6_prohibi -+ .rt6i_ref = ATOMIC_INIT(1), -+ }; -+ -++static const struct rt6_info ip6_policy_failed_entry_template = { -++ .dst = { -++ .__refcnt = ATOMIC_INIT(1), -++ .__use = 1, -++ .obsolete = DST_OBSOLETE_FORCE_CHK, -++ .error = -EACCES, -++ .input = ip6_pkt_policy_failed, -++ .output = ip6_pkt_policy_failed_out, -++ }, -++ .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), -++ .rt6i_protocol = RTPROT_KERNEL, -++ .rt6i_metric = ~(u32) 0, -++ .rt6i_ref = ATOMIC_INIT(1), -++}; -++ -+ static const struct rt6_info ip6_blk_hole_entry_template = { -+ .dst = { -+ .__refcnt = ATOMIC_INIT(1), -+@@ -2056,6 +2073,11 @@ static struct rt6_info *ip6_route_info_c -+ rt->dst.output = ip6_pkt_prohibit_out; -+ rt->dst.input = ip6_pkt_prohibit; -+ break; -++ case RTN_POLICY_FAILED: -++ rt->dst.error = -EACCES; -++ rt->dst.output = ip6_pkt_policy_failed_out; -++ rt->dst.input = ip6_pkt_policy_failed; -++ break; -+ case RTN_THROW: -+ case RTN_UNREACHABLE: -+ default: -+@@ -2781,6 +2803,17 @@ static int ip6_pkt_prohibit_out(struct n -+ return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); -+ } -+ -++static int ip6_pkt_policy_failed(struct sk_buff *skb) -++{ -++ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_INNOROUTES); -++} -++ -++static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb) -++{ -++ skb->dev = skb_dst(skb)->dev; -++ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_OUTNOROUTES); -++} -++ -+ /* -+ * Allocate a dst for local (unicast / anycast) address. -+ */ -+@@ -3017,7 +3050,8 @@ static int rtm_to_fib6_config(struct sk_ -+ if (rtm->rtm_type == RTN_UNREACHABLE || -+ rtm->rtm_type == RTN_BLACKHOLE || -+ rtm->rtm_type == RTN_PROHIBIT || -+- rtm->rtm_type == RTN_THROW) -++ rtm->rtm_type == RTN_THROW || -++ rtm->rtm_type == RTN_POLICY_FAILED) -+ cfg->fc_flags |= RTF_REJECT; -+ -+ if (rtm->rtm_type == RTN_LOCAL) -+@@ -3517,6 +3551,9 @@ static int rt6_fill_node(struct net *net -+ case -EACCES: -+ rtm->rtm_type = RTN_PROHIBIT; -+ break; -++ case -EPERM: -++ rtm->rtm_type = RTN_POLICY_FAILED; -++ break; -+ case -EAGAIN: -+ rtm->rtm_type = RTN_THROW; -+ break; -+@@ -3835,6 +3872,8 @@ static int ip6_route_dev_notify(struct n -+ #ifdef CONFIG_IPV6_MULTIPLE_TABLES -+ net->ipv6.ip6_prohibit_entry->dst.dev = dev; -+ net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev); -++ net->ipv6.ip6_policy_failed_entry->dst.dev = dev; -++ net->ipv6.ip6_policy_failed_entry->rt6i_idev = in6_dev_get(dev); -+ net->ipv6.ip6_blk_hole_entry->dst.dev = dev; -+ net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev); -+ #endif -+@@ -3846,6 +3885,7 @@ static int ip6_route_dev_notify(struct n -+ in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev); -+ #ifdef CONFIG_IPV6_MULTIPLE_TABLES -+ in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev); -++ in6_dev_put_clear(&net->ipv6.ip6_policy_failed_entry->rt6i_idev); -+ in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev); -+ #endif -+ } -+@@ -4062,6 +4102,17 @@ static int __net_init ip6_route_net_init -+ net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; -+ dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst, -+ ip6_template_metrics, true); -++ -++ net->ipv6.ip6_policy_failed_entry = -++ kmemdup(&ip6_policy_failed_entry_template, -++ sizeof(*net->ipv6.ip6_policy_failed_entry), GFP_KERNEL); -++ if (!net->ipv6.ip6_policy_failed_entry) -++ goto out_ip6_blk_hole_entry; -++ net->ipv6.ip6_policy_failed_entry->dst.path = -++ (struct dst_entry *)net->ipv6.ip6_policy_failed_entry; -++ net->ipv6.ip6_policy_failed_entry->dst.ops = &net->ipv6.ip6_dst_ops; -++ dst_init_metrics(&net->ipv6.ip6_policy_failed_entry->dst, -++ ip6_template_metrics, true); -+ #endif -+ -+ net->ipv6.sysctl.flush_delay = 0; -+@@ -4080,6 +4131,8 @@ out: -+ return ret; -+ -+ #ifdef CONFIG_IPV6_MULTIPLE_TABLES -++out_ip6_blk_hole_entry: -++ kfree(net->ipv6.ip6_blk_hole_entry); -+ out_ip6_prohibit_entry: -+ kfree(net->ipv6.ip6_prohibit_entry); -+ out_ip6_null_entry: -+@@ -4097,6 +4150,7 @@ static void __net_exit ip6_route_net_exi -+ #ifdef CONFIG_IPV6_MULTIPLE_TABLES -+ kfree(net->ipv6.ip6_prohibit_entry); -+ kfree(net->ipv6.ip6_blk_hole_entry); -++ kfree(net->ipv6.ip6_policy_failed_entry); -+ #endif -+ dst_entries_destroy(&net->ipv6.ip6_dst_ops); -+ } -+@@ -4170,6 +4224,9 @@ void __init ip6_route_init_special_entri -+ init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); -+ init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; -+ init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); -++ init_net.ipv6.ip6_policy_failed_entry->dst.dev = init_net.loopback_dev; -++ init_net.ipv6.ip6_policy_failed_entry->rt6i_idev = -++ in6_dev_get(init_net.loopback_dev); -+ #endif -+ } -+ -diff --git a/target/linux/generic/pending-4.14/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch b/target/linux/generic/pending-4.14/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch -new file mode 100644 -index 0000000000..cfea527e3d ---- /dev/null -+++ b/target/linux/generic/pending-4.14/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch -@@ -0,0 +1,50 @@ -+From: Jonas Gorski -+Subject: net: provide defines for _POLICY_FAILED until all code is updated -+ -+Upstream introduced ICMPV6_POLICY_FAIL for code 5 of destination -+unreachable, conflicting with our name. -+ -+Add appropriate defines to allow our code to build with the new -+name until we have updated our local patches for older kernels -+and userspace packages. -+ -+Signed-off-by: Jonas Gorski -+--- -+ include/uapi/linux/fib_rules.h | 2 ++ -+ include/uapi/linux/icmpv6.h | 2 ++ -+ include/uapi/linux/rtnetlink.h | 2 ++ -+ 3 files changed, 6 insertions(+) -+ -+--- a/include/uapi/linux/fib_rules.h -++++ b/include/uapi/linux/fib_rules.h -+@@ -80,6 +80,8 @@ enum { -+ __FR_ACT_MAX, -+ }; -+ -++#define FR_ACT_FAILED_POLICY FR_ACT_POLICY_FAILED -++ -+ #define FR_ACT_MAX (__FR_ACT_MAX - 1) -+ -+ #endif -+--- a/include/uapi/linux/icmpv6.h -++++ b/include/uapi/linux/icmpv6.h -+@@ -119,6 +119,8 @@ struct icmp6hdr { -+ #define ICMPV6_POLICY_FAIL 5 -+ #define ICMPV6_REJECT_ROUTE 6 -+ -++#define ICMPV6_FAILED_POLICY ICMPV6_POLICY_FAIL -++ -+ /* -+ * Codes for Time Exceeded -+ */ -+--- a/include/uapi/linux/rtnetlink.h -++++ b/include/uapi/linux/rtnetlink.h -+@@ -225,6 +225,8 @@ enum { -+ __RTN_MAX -+ }; -+ -++#define RTN_FAILED_POLICY RTN_POLICY_FAILED -++ -+ #define RTN_MAX (__RTN_MAX - 1) -+ -+ -diff --git a/target/linux/generic/pending-4.14/680-NET-skip-GRO-for-foreign-MAC-addresses.patch b/target/linux/generic/pending-4.14/680-NET-skip-GRO-for-foreign-MAC-addresses.patch -new file mode 100644 -index 0000000000..cf0e50f2d9 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/680-NET-skip-GRO-for-foreign-MAC-addresses.patch -@@ -0,0 +1,152 @@ -+From: Felix Fietkau -+Subject: net: replace GRO optimization patch with a new one that supports VLANs/bridges with different MAC addresses -+ -+Signed-off-by: Felix Fietkau -+--- -+ include/linux/netdevice.h | 2 ++ -+ include/linux/skbuff.h | 3 ++- -+ net/core/dev.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ -+ net/ethernet/eth.c | 18 +++++++++++++++++- -+ 4 files changed, 69 insertions(+), 2 deletions(-) -+ -+--- a/include/linux/netdevice.h -++++ b/include/linux/netdevice.h -+@@ -1771,6 +1771,8 @@ struct net_device { -+ struct netdev_hw_addr_list mc; -+ struct netdev_hw_addr_list dev_addrs; -+ -++ unsigned char local_addr_mask[MAX_ADDR_LEN]; -++ -+ #ifdef CONFIG_SYSFS -+ struct kset *queues_kset; -+ #endif -+--- a/include/linux/skbuff.h -++++ b/include/linux/skbuff.h -+@@ -782,6 +782,7 @@ struct sk_buff { -+ __u8 tc_redirected:1; -+ __u8 tc_from_ingress:1; -+ #endif -++ __u8 gro_skip:1; -+ -+ #ifdef CONFIG_NET_SCHED -+ __u16 tc_index; /* traffic control index */ -+--- a/net/core/dev.c -++++ b/net/core/dev.c -+@@ -4802,6 +4802,9 @@ static enum gro_result dev_gro_receive(s -+ enum gro_result ret; -+ int grow; -+ -++ if (skb->gro_skip) -++ goto normal; -++ -+ if (netif_elide_gro(skb->dev)) -+ goto normal; -+ -+@@ -6279,6 +6282,48 @@ static void __netdev_adjacent_dev_unlink -+ &upper_dev->adj_list.lower); -+ } -+ -++static void __netdev_addr_mask(unsigned char *mask, const unsigned char *addr, -++ struct net_device *dev) -++{ -++ int i; -++ -++ for (i = 0; i < dev->addr_len; i++) -++ mask[i] |= addr[i] ^ dev->dev_addr[i]; -++} -++ -++static void __netdev_upper_mask(unsigned char *mask, struct net_device *dev, -++ struct net_device *lower) -++{ -++ struct net_device *cur; -++ struct list_head *iter; -++ -++ netdev_for_each_upper_dev_rcu(dev, cur, iter) { -++ __netdev_addr_mask(mask, cur->dev_addr, lower); -++ __netdev_upper_mask(mask, cur, lower); -++ } -++} -++ -++static void __netdev_update_addr_mask(struct net_device *dev) -++{ -++ unsigned char mask[MAX_ADDR_LEN]; -++ struct net_device *cur; -++ struct list_head *iter; -++ -++ memset(mask, 0, sizeof(mask)); -++ __netdev_upper_mask(mask, dev, dev); -++ memcpy(dev->local_addr_mask, mask, dev->addr_len); -++ -++ netdev_for_each_lower_dev(dev, cur, iter) -++ __netdev_update_addr_mask(cur); -++} -++ -++static void netdev_update_addr_mask(struct net_device *dev) -++{ -++ rcu_read_lock(); -++ __netdev_update_addr_mask(dev); -++ rcu_read_unlock(); -++} -++ -+ static int __netdev_upper_dev_link(struct net_device *dev, -+ struct net_device *upper_dev, bool master, -+ void *upper_priv, void *upper_info) -+@@ -6317,6 +6362,7 @@ static int __netdev_upper_dev_link(struc -+ if (ret) -+ return ret; -+ -++ netdev_update_addr_mask(dev); -+ ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, dev, -+ &changeupper_info.info); -+ ret = notifier_to_errno(ret); -+@@ -6394,6 +6440,7 @@ void netdev_upper_dev_unlink(struct net_ -+ -+ __netdev_adjacent_dev_unlink_neighbour(dev, upper_dev); -+ -++ netdev_update_addr_mask(dev); -+ call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, dev, -+ &changeupper_info.info); -+ } -+@@ -6958,6 +7005,7 @@ int dev_set_mac_address(struct net_devic -+ if (err) -+ return err; -+ dev->addr_assign_type = NET_ADDR_SET; -++ netdev_update_addr_mask(dev); -+ call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); -+ add_device_randomness(dev->dev_addr, dev->addr_len); -+ return 0; -+--- a/net/ethernet/eth.c -++++ b/net/ethernet/eth.c -+@@ -144,6 +144,18 @@ u32 eth_get_headlen(void *data, unsigned -+ } -+ EXPORT_SYMBOL(eth_get_headlen); -+ -++static inline bool -++eth_check_local_mask(const void *addr1, const void *addr2, const void *mask) -++{ -++ const u16 *a1 = addr1; -++ const u16 *a2 = addr2; -++ const u16 *m = mask; -++ -++ return (((a1[0] ^ a2[0]) & ~m[0]) | -++ ((a1[1] ^ a2[1]) & ~m[1]) | -++ ((a1[2] ^ a2[2]) & ~m[2])); -++} -++ -+ /** -+ * eth_type_trans - determine the packet's protocol ID. -+ * @skb: received socket data -+@@ -172,8 +184,12 @@ __be16 eth_type_trans(struct sk_buff *sk -+ skb->pkt_type = PACKET_MULTICAST; -+ } -+ else if (unlikely(!ether_addr_equal_64bits(eth->h_dest, -+- dev->dev_addr))) -++ dev->dev_addr))) { -+ skb->pkt_type = PACKET_OTHERHOST; -++ if (eth_check_local_mask(eth->h_dest, dev->dev_addr, -++ dev->local_addr_mask)) -++ skb->gro_skip = 1; -++ } -+ -+ /* -+ * Some variants of DSA tagging don't have an ethertype field -diff --git a/target/linux/generic/pending-4.14/681-NET-add-of_get_mac_address_mtd.patch b/target/linux/generic/pending-4.14/681-NET-add-of_get_mac_address_mtd.patch -new file mode 100644 -index 0000000000..2b89a05238 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/681-NET-add-of_get_mac_address_mtd.patch -@@ -0,0 +1,133 @@ -+From: John Crispin -+Subject: NET: add mtd-mac-address support to of_get_mac_address() -+ -+Many embedded devices have information such as mac addresses stored inside mtd -+devices. This patch allows us to add a property inside a node describing a -+network interface. The new property points at a mtd partition with an offset -+where the mac address can be found. -+ -+Signed-off-by: John Crispin -+Signed-off-by: Felix Fietkau -+--- -+ drivers/of/of_net.c | 37 +++++++++++++++++++++++++++++++++++++ -+ include/linux/of_net.h | 1 + -+ 2 files changed, 38 insertions(+) -+ -+--- a/drivers/of/of_net.c -++++ b/drivers/of/of_net.c -+@@ -10,6 +10,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ /** -+ * of_get_phy_mode - Get phy mode for given device_node -+@@ -38,7 +39,7 @@ int of_get_phy_mode(struct device_node * -+ } -+ EXPORT_SYMBOL_GPL(of_get_phy_mode); -+ -+-static const void *of_get_mac_addr(struct device_node *np, const char *name) -++static void *of_get_mac_addr(struct device_node *np, const char *name) -+ { -+ struct property *pp = of_find_property(np, name, NULL); -+ -+@@ -47,6 +48,79 @@ static const void *of_get_mac_addr(struc -+ return NULL; -+ } -+ -++static const void *of_get_mac_address_mtd(struct device_node *np) -++{ -++#ifdef CONFIG_MTD -++ struct device_node *mtd_np = NULL; -++ struct property *prop; -++ size_t retlen; -++ int size, ret; -++ struct mtd_info *mtd; -++ const char *part; -++ const __be32 *list; -++ phandle phandle; -++ u32 mac_inc = 0; -++ u8 mac[ETH_ALEN]; -++ void *addr; -++ u32 inc_idx; -++ -++ list = of_get_property(np, "mtd-mac-address", &size); -++ if (!list || (size != (2 * sizeof(*list)))) -++ return NULL; -++ -++ phandle = be32_to_cpup(list++); -++ if (phandle) -++ mtd_np = of_find_node_by_phandle(phandle); -++ -++ if (!mtd_np) -++ return NULL; -++ -++ part = of_get_property(mtd_np, "label", NULL); -++ if (!part) -++ part = mtd_np->name; -++ -++ mtd = get_mtd_device_nm(part); -++ if (IS_ERR(mtd)) -++ return NULL; -++ -++ ret = mtd_read(mtd, be32_to_cpup(list), 6, &retlen, mac); -++ put_mtd_device(mtd); -++ -++ if (of_property_read_u32(np, "mtd-mac-address-increment-byte", &inc_idx)) -++ inc_idx = 5; -++ if (inc_idx > 5) -++ return NULL; -++ -++ if (!of_property_read_u32(np, "mtd-mac-address-increment", &mac_inc)) -++ mac[inc_idx] += mac_inc; -++ -++ if (!is_valid_ether_addr(mac)) -++ return NULL; -++ -++ addr = of_get_mac_addr(np, "mac-address"); -++ if (addr) { -++ memcpy(addr, mac, ETH_ALEN); -++ return addr; -++ } -++ -++ prop = kzalloc(sizeof(*prop), GFP_KERNEL); -++ if (!prop) -++ return NULL; -++ -++ prop->name = "mac-address"; -++ prop->length = ETH_ALEN; -++ prop->value = kmemdup(mac, ETH_ALEN, GFP_KERNEL); -++ if (!prop->value || of_add_property(np, prop)) -++ goto free; -++ -++ return prop->value; -++free: -++ kfree(prop->value); -++ kfree(prop); -++#endif -++ return NULL; -++} -++ -+ /** -+ * Search the device tree for the best MAC address to use. 'mac-address' is -+ * checked first, because that is supposed to contain to "most recent" MAC -+@@ -64,11 +138,18 @@ static const void *of_get_mac_addr(struc -+ * addresses. Some older U-Boots only initialized 'local-mac-address'. In -+ * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists -+ * but is all zeros. -++ * -++ * If a mtd-mac-address property exists, try to fetch the MAC address from the -++ * specified mtd device, and store it as a 'mac-address' property -+ */ -+ const void *of_get_mac_address(struct device_node *np) -+ { -+ const void *addr; -+ -++ addr = of_get_mac_address_mtd(np); -++ if (addr) -++ return addr; -++ -+ addr = of_get_mac_addr(np, "mac-address"); -+ if (addr) -+ return addr; -diff --git a/target/linux/generic/pending-4.14/690-net-add-support-for-threaded-NAPI-polling.patch b/target/linux/generic/pending-4.14/690-net-add-support-for-threaded-NAPI-polling.patch -new file mode 100644 -index 0000000000..1a531cb8fc ---- /dev/null -+++ b/target/linux/generic/pending-4.14/690-net-add-support-for-threaded-NAPI-polling.patch -@@ -0,0 +1,339 @@ -+From: Felix Fietkau -+Date: Sun, 26 Jul 2020 14:03:21 +0200 -+Subject: [PATCH] net: add support for threaded NAPI polling -+ -+For some drivers (especially 802.11 drivers), doing a lot of work in the NAPI -+poll function does not perform well. Since NAPI poll is bound to the CPU it -+was scheduled from, we can easily end up with a few very busy CPUs spending -+most of their time in softirq/ksoftirqd and some idle ones. -+ -+Introduce threaded NAPI for such drivers based on a workqueue. The API is the -+same except for using netif_threaded_napi_add instead of netif_napi_add. -+ -+In my tests with mt76 on MT7621 using threaded NAPI + a thread for tx scheduling -+improves LAN->WLAN bridging throughput by 10-50%. Throughput without threaded -+NAPI is wildly inconsistent, depending on the CPU that runs the tx scheduling -+thread. -+ -+With threaded NAPI it seems stable and consistent (and higher than the best -+results I got without it). -+ -+Based on a patch by Hillf Danton -+ -+Cc: Hillf Danton -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/include/linux/netdevice.h -++++ b/include/linux/netdevice.h -+@@ -326,6 +326,7 @@ struct napi_struct { -+ struct list_head dev_list; -+ struct hlist_node napi_hash_node; -+ unsigned int napi_id; -++ struct work_struct work; -+ }; -+ -+ enum { -+@@ -336,6 +337,7 @@ enum { -+ NAPI_STATE_HASHED, /* In NAPI hash (busy polling possible) */ -+ NAPI_STATE_NO_BUSY_POLL,/* Do not add in napi_hash, no busy polling */ -+ NAPI_STATE_IN_BUSY_POLL,/* sk_busy_loop() owns this NAPI */ -++ NAPI_STATE_THREADED, /* Use threaded NAPI */ -+ }; -+ -+ enum { -+@@ -346,6 +348,7 @@ enum { -+ NAPIF_STATE_HASHED = BIT(NAPI_STATE_HASHED), -+ NAPIF_STATE_NO_BUSY_POLL = BIT(NAPI_STATE_NO_BUSY_POLL), -+ NAPIF_STATE_IN_BUSY_POLL = BIT(NAPI_STATE_IN_BUSY_POLL), -++ NAPIF_STATE_THREADED = BIT(NAPI_STATE_THREADED), -+ }; -+ -+ enum gro_result { -+@@ -2093,6 +2096,26 @@ void netif_napi_add(struct net_device *d -+ int (*poll)(struct napi_struct *, int), int weight); -+ -+ /** -++ * netif_threaded_napi_add - initialize a NAPI context -++ * @dev: network device -++ * @napi: NAPI context -++ * @poll: polling function -++ * @weight: default weight -++ * -++ * This variant of netif_napi_add() should be used from drivers using NAPI -++ * with CPU intensive poll functions. -++ * This will schedule polling from a high priority workqueue -++ */ -++static inline void netif_threaded_napi_add(struct net_device *dev, -++ struct napi_struct *napi, -++ int (*poll)(struct napi_struct *, int), -++ int weight) -++{ -++ set_bit(NAPI_STATE_THREADED, &napi->state); -++ netif_napi_add(dev, napi, poll, weight); -++} -++ -++/** -+ * netif_tx_napi_add - initialize a NAPI context -+ * @dev: network device -+ * @napi: NAPI context -+--- a/net/core/dev.c -++++ b/net/core/dev.c -+@@ -160,6 +160,7 @@ static DEFINE_SPINLOCK(offload_lock); -+ struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly; -+ struct list_head ptype_all __read_mostly; /* Taps */ -+ static struct list_head offload_base __read_mostly; -++static struct workqueue_struct *napi_workq __read_mostly; -+ -+ static int netif_rx_internal(struct sk_buff *skb); -+ static int call_netdevice_notifiers_info(unsigned long val, -+@@ -5237,6 +5238,11 @@ void __napi_schedule(struct napi_struct -+ { -+ unsigned long flags; -+ -++ if (test_bit(NAPI_STATE_THREADED, &n->state)) { -++ queue_work(napi_workq, &n->work); -++ return; -++ } -++ -+ local_irq_save(flags); -+ ____napi_schedule(this_cpu_ptr(&softnet_data), n); -+ local_irq_restore(flags); -+@@ -5284,6 +5290,11 @@ EXPORT_SYMBOL(napi_schedule_prep); -+ */ -+ void __napi_schedule_irqoff(struct napi_struct *n) -+ { -++ if (test_bit(NAPI_STATE_THREADED, &n->state)) { -++ queue_work(napi_workq, &n->work); -++ return; -++ } -++ -+ ____napi_schedule(this_cpu_ptr(&softnet_data), n); -+ } -+ EXPORT_SYMBOL(__napi_schedule_irqoff); -+@@ -5521,6 +5532,82 @@ static enum hrtimer_restart napi_watchdo -+ return HRTIMER_NORESTART; -+ } -+ -++static int __napi_poll(struct napi_struct *n, bool *repoll) -++{ -++ int work, weight; -++ -++ weight = n->weight; -++ -++ /* This NAPI_STATE_SCHED test is for avoiding a race -++ * with netpoll's poll_napi(). Only the entity which -++ * obtains the lock and sees NAPI_STATE_SCHED set will -++ * actually make the ->poll() call. Therefore we avoid -++ * accidentally calling ->poll() when NAPI is not scheduled. -++ */ -++ work = 0; -++ if (test_bit(NAPI_STATE_SCHED, &n->state)) { -++ work = n->poll(n, weight); -++ trace_napi_poll(n, work, weight); -++ } -++ -++ WARN_ON_ONCE(work > weight); -++ -++ if (likely(work < weight)) -++ return work; -++ -++ /* Drivers must not modify the NAPI state if they -++ * consume the entire weight. In such cases this code -++ * still "owns" the NAPI instance and therefore can -++ * move the instance around on the list at-will. -++ */ -++ if (unlikely(napi_disable_pending(n))) { -++ napi_complete(n); -++ return work; -++ } -++ -++ if (n->gro_list) { -++ /* flush too old packets -++ * If HZ < 1000, flush all packets. -++ */ -++ napi_gro_flush(n, HZ >= 1000); -++ } -++ -++ *repoll = true; -++ -++ return work; -++} -++ -++static void napi_workfn(struct work_struct *work) -++{ -++ struct napi_struct *n = container_of(work, struct napi_struct, work); -++ void *have; -++ -++ for (;;) { -++ bool repoll = false; -++ -++ local_bh_disable(); -++ -++ have = netpoll_poll_lock(n); -++ __napi_poll(n, &repoll); -++ netpoll_poll_unlock(have); -++ -++ local_bh_enable(); -++ -++ if (!repoll) -++ return; -++ -++ if (!need_resched()) -++ continue; -++ -++ /* -++ * have to pay for the latency of task switch even if -++ * napi is scheduled -++ */ -++ queue_work(napi_workq, work); -++ return; -++ } -++} -++ -+ void netif_napi_add(struct net_device *dev, struct napi_struct *napi, -+ int (*poll)(struct napi_struct *, int), int weight) -+ { -+@@ -5540,6 +5627,7 @@ void netif_napi_add(struct net_device *d -+ #ifdef CONFIG_NETPOLL -+ napi->poll_owner = -1; -+ #endif -++ INIT_WORK(&napi->work, napi_workfn); -+ set_bit(NAPI_STATE_SCHED, &napi->state); -+ napi_hash_add(napi); -+ } -+@@ -5565,6 +5653,7 @@ EXPORT_SYMBOL(napi_disable); -+ void netif_napi_del(struct napi_struct *napi) -+ { -+ might_sleep(); -++ cancel_work_sync(&napi->work); -+ if (napi_hash_del(napi)) -+ synchronize_net(); -+ list_del_init(&napi->dev_list); -+@@ -5578,48 +5667,18 @@ EXPORT_SYMBOL(netif_napi_del); -+ -+ static int napi_poll(struct napi_struct *n, struct list_head *repoll) -+ { -++ bool do_repoll = false; -+ void *have; -+- int work, weight; -++ int work; -+ -+ list_del_init(&n->poll_list); -+ -+ have = netpoll_poll_lock(n); -+ -+- weight = n->weight; -+- -+- /* This NAPI_STATE_SCHED test is for avoiding a race -+- * with netpoll's poll_napi(). Only the entity which -+- * obtains the lock and sees NAPI_STATE_SCHED set will -+- * actually make the ->poll() call. Therefore we avoid -+- * accidentally calling ->poll() when NAPI is not scheduled. -+- */ -+- work = 0; -+- if (test_bit(NAPI_STATE_SCHED, &n->state)) { -+- work = n->poll(n, weight); -+- trace_napi_poll(n, work, weight); -+- } -+- -+- WARN_ON_ONCE(work > weight); -+- -+- if (likely(work < weight)) -+- goto out_unlock; -++ work = __napi_poll(n, &do_repoll); -+ -+- /* Drivers must not modify the NAPI state if they -+- * consume the entire weight. In such cases this code -+- * still "owns" the NAPI instance and therefore can -+- * move the instance around on the list at-will. -+- */ -+- if (unlikely(napi_disable_pending(n))) { -+- napi_complete(n); -++ if (!do_repoll) -+ goto out_unlock; -+- } -+- -+- if (n->gro_list) { -+- /* flush too old packets -+- * If HZ < 1000, flush all packets. -+- */ -+- napi_gro_flush(n, HZ >= 1000); -+- } -+ -+ /* Some drivers may have called napi_schedule -+ * prior to exhausting their budget. -+@@ -8855,6 +8914,10 @@ static int __init net_dev_init(void) -+ sd->backlog.weight = weight_p; -+ } -+ -++ napi_workq = alloc_workqueue("napi_workq", WQ_UNBOUND | WQ_HIGHPRI, -++ WQ_UNBOUND_MAX_ACTIVE | WQ_SYSFS); -++ BUG_ON(!napi_workq); -++ -+ dev_boot_phase = 0; -+ -+ /* The loopback device is special if any other network devices -+--- a/net/core/net-sysfs.c -++++ b/net/core/net-sysfs.c -+@@ -441,6 +441,52 @@ static ssize_t proto_down_store(struct d -+ } -+ NETDEVICE_SHOW_RW(proto_down, fmt_dec); -+ -++static int change_napi_threaded(struct net_device *dev, unsigned long val) -++{ -++ struct napi_struct *napi; -++ -++ if (list_empty(&dev->napi_list)) -++ return -EOPNOTSUPP; -++ -++ list_for_each_entry(napi, &dev->napi_list, dev_list) { -++ if (val) -++ set_bit(NAPI_STATE_THREADED, &napi->state); -++ else -++ clear_bit(NAPI_STATE_THREADED, &napi->state); -++ } -++ -++ return 0; -++} -++ -++static ssize_t napi_threaded_store(struct device *dev, -++ struct device_attribute *attr, -++ const char *buf, size_t len) -++{ -++ return netdev_store(dev, attr, buf, len, change_napi_threaded); -++} -++ -++static ssize_t napi_threaded_show(struct device *dev, -++ struct device_attribute *attr, -++ char *buf) -++{ -++ struct net_device *netdev = to_net_dev(dev); -++ struct napi_struct *napi; -++ bool enabled = false; -++ -++ if (!rtnl_trylock()) -++ return restart_syscall(); -++ -++ list_for_each_entry(napi, &netdev->napi_list, dev_list) { -++ if (test_bit(NAPI_STATE_THREADED, &napi->state)) -++ enabled = true; -++ } -++ -++ rtnl_unlock(); -++ -++ return sprintf(buf, fmt_dec, enabled); -++} -++static DEVICE_ATTR_RW(napi_threaded); -++ -+ static ssize_t phys_port_id_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+ { -+@@ -536,6 +582,7 @@ static struct attribute *net_class_attrs -+ &dev_attr_flags.attr, -+ &dev_attr_tx_queue_len.attr, -+ &dev_attr_gro_flush_timeout.attr, -++ &dev_attr_napi_threaded.attr, -+ &dev_attr_phys_port_id.attr, -+ &dev_attr_phys_port_name.attr, -+ &dev_attr_phys_switch_id.attr, -diff --git a/target/linux/generic/pending-4.14/703-phy-add-detach-callback-to-struct-phy_driver.patch b/target/linux/generic/pending-4.14/703-phy-add-detach-callback-to-struct-phy_driver.patch -new file mode 100644 -index 0000000000..03579657ee ---- /dev/null -+++ b/target/linux/generic/pending-4.14/703-phy-add-detach-callback-to-struct-phy_driver.patch -@@ -0,0 +1,38 @@ -+From: Gabor Juhos -+Subject: generic: add detach callback to struct phy_driver -+ -+lede-commit: fe61fc2d7d0b3fb348b502f68f98243b3ddf5867 -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/phy/phy_device.c | 3 +++ -+ include/linux/phy.h | 6 ++++++ -+ 2 files changed, 9 insertions(+) -+ -+--- a/drivers/net/phy/phy_device.c -++++ b/drivers/net/phy/phy_device.c -+@@ -1110,6 +1110,9 @@ void phy_detach(struct phy_device *phyde -+ struct module *ndev_owner = dev->dev.parent->driver->owner; -+ struct mii_bus *bus; -+ -++ if (phydev->drv && phydev->drv->detach) -++ phydev->drv->detach(phydev); -++ -+ if (phydev->sysfs_links) { -+ sysfs_remove_link(&dev->dev.kobj, "phydev"); -+ sysfs_remove_link(&phydev->mdio.dev.kobj, "attached_dev"); -+--- a/include/linux/phy.h -++++ b/include/linux/phy.h -+@@ -561,6 +561,12 @@ struct phy_driver { -+ */ -+ int (*did_interrupt)(struct phy_device *phydev); -+ -++ /* -++ * Called before an ethernet device is detached -++ * from the PHY. -++ */ -++ void (*detach)(struct phy_device *phydev); -++ -+ /* Clears up any memory if needed */ -+ void (*remove)(struct phy_device *phydev); -+ -diff --git a/target/linux/generic/pending-4.14/734-net-phy-at803x-allow-to-configure-via-pdata.patch b/target/linux/generic/pending-4.14/734-net-phy-at803x-allow-to-configure-via-pdata.patch -new file mode 100644 -index 0000000000..27bbf572e9 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/734-net-phy-at803x-allow-to-configure-via-pdata.patch -@@ -0,0 +1,142 @@ -+From: Gabor Juhos -+Subject: net: phy: allow to configure AR803x PHYs via platform data -+ -+Add a patch for the at803x phy driver, in order to be able -+to configure some register settings via platform data. -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/net/phy/at803x.c | 56 ++++++++++++++++++++++++++++++++ -+ include/linux/platform_data/phy-at803x.h | 11 +++++++ -+ 2 files changed, 67 insertions(+) -+ create mode 100644 include/linux/platform_data/phy-at803x.h -+ -+--- a/drivers/net/phy/at803x.c -++++ b/drivers/net/phy/at803x.c -+@@ -12,12 +12,14 @@ -+ */ -+ -+ #include -++#include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -++#include -+ -+ #define AT803X_INTR_ENABLE 0x12 -+ #define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15) -+@@ -45,6 +47,11 @@ -+ #define AT803X_REG_CHIP_CONFIG 0x1f -+ #define AT803X_BT_BX_REG_SEL 0x8000 -+ -++#define AT803X_PCS_SMART_EEE_CTRL3 0x805D -++#define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_MASK 0x3 -++#define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_SHIFT 12 -++#define AT803X_SMART_EEE_CTRL3_LPI_EN BIT(8) -++ -+ #define AT803X_DEBUG_ADDR 0x1D -+ #define AT803X_DEBUG_DATA 0x1E -+ -+@@ -74,6 +81,7 @@ MODULE_LICENSE("GPL"); -+ struct at803x_priv { -+ bool phy_reset:1; -+ struct gpio_desc *gpiod_reset; -++ int prev_speed; -+ }; -+ -+ struct at803x_context { -+@@ -274,8 +282,16 @@ does_not_require_reset_workaround: -+ return 0; -+ } -+ -++static void at803x_disable_smarteee(struct phy_device *phydev) -++{ -++ phy_write_mmd(phydev, MDIO_MMD_PCS, AT803X_PCS_SMART_EEE_CTRL3, -++ 1 << AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_SHIFT); -++ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0); -++} -++ -+ static int at803x_config_init(struct phy_device *phydev) -+ { -++ struct at803x_platform_data *pdata; -+ int ret; -+ -+ ret = genphy_config_init(phydev); -+@@ -296,6 +312,26 @@ static int at803x_config_init(struct phy -+ return ret; -+ } -+ -++ pdata = dev_get_platdata(&phydev->mdio.dev); -++ if (pdata) { -++ if (pdata->disable_smarteee) -++ at803x_disable_smarteee(phydev); -++ -++ if (pdata->enable_rgmii_rx_delay) -++ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0, -++ AT803X_DEBUG_RX_CLK_DLY_EN); -++ else -++ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, -++ AT803X_DEBUG_RX_CLK_DLY_EN, 0); -++ -++ if (pdata->enable_rgmii_tx_delay) -++ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0, -++ AT803X_DEBUG_TX_CLK_DLY_EN); -++ else -++ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, -++ AT803X_DEBUG_TX_CLK_DLY_EN, 0); -++ } -++ -+ return 0; -+ } -+ -+@@ -333,6 +369,8 @@ static int at803x_config_intr(struct phy -+ static void at803x_link_change_notify(struct phy_device *phydev) -+ { -+ struct at803x_priv *priv = phydev->priv; -++ struct at803x_platform_data *pdata; -++ pdata = dev_get_platdata(&phydev->mdio.dev); -+ -+ /* -+ * Conduct a hardware reset for AT8030/2 every time a link loss is -+@@ -361,6 +399,24 @@ static void at803x_link_change_notify(st -+ } else { -+ priv->phy_reset = false; -+ } -++ if (pdata && pdata->fixup_rgmii_tx_delay && -++ phydev->speed != priv->prev_speed) { -++ switch (phydev->speed) { -++ case SPEED_10: -++ case SPEED_100: -++ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0, -++ AT803X_DEBUG_TX_CLK_DLY_EN); -++ break; -++ case SPEED_1000: -++ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, -++ AT803X_DEBUG_TX_CLK_DLY_EN, 0); -++ break; -++ default: -++ break; -++ } -++ -++ priv->prev_speed = phydev->speed; -++ } -+ } -+ -+ static int at803x_aneg_done(struct phy_device *phydev) -+--- /dev/null -++++ b/include/linux/platform_data/phy-at803x.h -+@@ -0,0 +1,11 @@ -++#ifndef _PHY_AT803X_PDATA_H -++#define _PHY_AT803X_PDATA_H -++ -++struct at803x_platform_data { -++ int disable_smarteee:1; -++ int enable_rgmii_tx_delay:1; -++ int enable_rgmii_rx_delay:1; -++ int fixup_rgmii_tx_delay:1; -++}; -++ -++#endif /* _PHY_AT803X_PDATA_H */ -diff --git a/target/linux/generic/pending-4.14/735-net-phy-at803x-fix-at8033-sgmii-mode.patch b/target/linux/generic/pending-4.14/735-net-phy-at803x-fix-at8033-sgmii-mode.patch -new file mode 100644 -index 0000000000..8c5c21b1bc ---- /dev/null -+++ b/target/linux/generic/pending-4.14/735-net-phy-at803x-fix-at8033-sgmii-mode.patch -@@ -0,0 +1,51 @@ -+From: Roman Yeryomin -+Subject: kernel: add at803x fix for sgmii mode -+ -+Some (possibly broken) bootloaders incorreclty initialize at8033 -+phy. This patch enables sgmii autonegotiation mode. -+ -+[john@phrozen.org: felix added this to his upstream queue] -+ -+Signed-off-by: Roman Yeryomin -+--- -+ drivers/net/phy/at803x.c | 25 +++++++++++++++++++++++++ -+ 1 file changed, 25 insertions(+) -+ -+--- a/drivers/net/phy/at803x.c -++++ b/drivers/net/phy/at803x.c -+@@ -46,6 +46,7 @@ -+ #define AT803X_FUNC_DATA 0x4003 -+ #define AT803X_REG_CHIP_CONFIG 0x1f -+ #define AT803X_BT_BX_REG_SEL 0x8000 -++#define AT803X_SGMII_ANEG_EN 0x1000 -+ -+ #define AT803X_PCS_SMART_EEE_CTRL3 0x805D -+ #define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_MASK 0x3 -+@@ -293,6 +294,27 @@ static int at803x_config_init(struct phy -+ { -+ struct at803x_platform_data *pdata; -+ int ret; -++ u32 v; -++ -++ if (phydev->drv->phy_id == ATH8031_PHY_ID && -++ phydev->interface == PHY_INTERFACE_MODE_SGMII) -++ { -++ v = phy_read(phydev, AT803X_REG_CHIP_CONFIG); -++ /* select SGMII/fiber page */ -++ ret = phy_write(phydev, AT803X_REG_CHIP_CONFIG, -++ v & ~AT803X_BT_BX_REG_SEL); -++ if (ret) -++ return ret; -++ /* enable SGMII autonegotiation */ -++ ret = phy_write(phydev, MII_BMCR, AT803X_SGMII_ANEG_EN); -++ if (ret) -++ return ret; -++ /* select copper page */ -++ ret = phy_write(phydev, AT803X_REG_CHIP_CONFIG, -++ v | AT803X_BT_BX_REG_SEL); -++ if (ret) -++ return ret; -++ } -+ -+ ret = genphy_config_init(phydev); -+ if (ret < 0) -diff --git a/target/linux/generic/pending-4.14/810-pci_disable_common_quirks.patch b/target/linux/generic/pending-4.14/810-pci_disable_common_quirks.patch -new file mode 100644 -index 0000000000..1d10af647f ---- /dev/null -+++ b/target/linux/generic/pending-4.14/810-pci_disable_common_quirks.patch -@@ -0,0 +1,60 @@ -+From: Gabor Juhos -+Subject: debloat: add kernel config option to disabling common PCI quirks -+ -+Signed-off-by: Gabor Juhos -+--- -+ drivers/pci/Kconfig | 6 ++++++ -+ drivers/pci/quirks.c | 6 ++++++ -+ 2 files changed, 12 insertions(+) -+ -+--- a/drivers/pci/Kconfig -++++ b/drivers/pci/Kconfig -+@@ -71,6 +71,12 @@ config XEN_PCIDEV_FRONTEND -+ The PCI device frontend driver allows the kernel to import arbitrary -+ PCI devices from a PCI backend to support PCI driver domains. -+ -++config PCI_DISABLE_COMMON_QUIRKS -++ bool "PCI disable common quirks" -++ depends on PCI -++ help -++ If you don't know what to do here, say N. -++ -+ config HT_IRQ -+ bool "Interrupts on hypertransport devices" -+ default y -+--- a/drivers/pci/quirks.c -++++ b/drivers/pci/quirks.c -+@@ -44,6 +44,7 @@ static void quirk_mmio_always_on(struct -+ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID, -+ PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on); -+ -++#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS -+ /* The Mellanox Tavor device gives false positive parity errors -+ * Mark this device with a broken_parity_status, to allow -+ * PCI scanning code to "skip" this now blacklisted device. -+@@ -3108,6 +3109,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I -+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata); -+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata); -+ -++#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */ -+ -+ /* -+ * Ivytown NTB BAR sizes are misreported by the hardware due to an erratum. To -+@@ -3164,6 +3166,8 @@ static void fixup_debug_report(struct pc -+ } -+ } -+ -++#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS -++ -+ /* -+ * Some BIOS implementations leave the Intel GPU interrupts enabled, -+ * even though no one is handling them (f.e. i915 driver is never loaded). -+@@ -3202,6 +3206,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN -+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); -+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0152, disable_igfx_irq); -+ -++#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */ -++ -+ /* -+ * PCI devices which are on Intel chips can skip the 10ms delay -+ * before entering D3 mode. -diff --git a/target/linux/generic/pending-4.14/811-pci_disable_usb_common_quirks.patch b/target/linux/generic/pending-4.14/811-pci_disable_usb_common_quirks.patch -new file mode 100644 -index 0000000000..aeb13c5ef7 ---- /dev/null -+++ b/target/linux/generic/pending-4.14/811-pci_disable_usb_common_quirks.patch -@@ -0,0 +1,115 @@ -+From: Felix Fietkau -+Subject: debloat: disable common USB quirks -+ -+Signed-off-by: Felix Fietkau -+--- -+ drivers/usb/host/pci-quirks.c | 16 ++++++++++++++++ -+ drivers/usb/host/pci-quirks.h | 18 +++++++++++++++++- -+ include/linux/usb/hcd.h | 7 +++++++ -+ 3 files changed, 40 insertions(+), 1 deletion(-) -+ -+--- a/drivers/usb/host/pci-quirks.c -++++ b/drivers/usb/host/pci-quirks.c -+@@ -124,6 +124,8 @@ struct amd_chipset_type { -+ u8 rev; -+ }; -+ -++#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS -++ -+ static struct amd_chipset_info { -+ struct pci_dev *nb_dev; -+ struct pci_dev *smbus_dev; -+@@ -627,6 +629,10 @@ bool usb_amd_pt_check_port(struct device -+ } -+ EXPORT_SYMBOL_GPL(usb_amd_pt_check_port); -+ -++#endif /* CONFIG_PCI_DISABLE_COMMON_QUIRKS */ -++ -++#if IS_ENABLED(CONFIG_USB_UHCI_HCD) -++ -+ /* -+ * Make sure the controller is completely inactive, unable to -+ * generate interrupts or do DMA. -+@@ -706,8 +712,17 @@ reset_needed: -+ uhci_reset_hc(pdev, base); -+ return 1; -+ } -++#else -++int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) -++{ -++ return 0; -++} -++ -++#endif -+ EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); -+ -++#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS -++ -+ static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask) -+ { -+ u16 cmd; -+@@ -1294,3 +1309,4 @@ bool usb_xhci_needs_pci_reset(struct pci -+ return false; -+ } -+ EXPORT_SYMBOL_GPL(usb_xhci_needs_pci_reset); -++#endif -+--- a/drivers/usb/host/pci-quirks.h -++++ b/drivers/usb/host/pci-quirks.h -+@@ -5,6 +5,9 @@ -+ #ifdef CONFIG_USB_PCI -+ void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); -+ int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); -++#endif /* CONFIG_USB_PCI */ -++ -++#if defined(CONFIG_USB_PCI) && !defined(CONFIG_PCI_DISABLE_COMMON_QUIRKS) -+ int usb_amd_find_chipset_info(void); -+ int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev); -+ bool usb_amd_hang_symptom_quirk(void); -+@@ -20,6 +23,18 @@ bool usb_xhci_needs_pci_reset(struct pci -+ bool usb_amd_pt_check_port(struct device *device, int port); -+ #else -+ struct pci_dev; -++static inline int usb_amd_find_chipset_info(void) -++{ -++ return 0; -++} -++static inline bool usb_amd_hang_symptom_quirk(void) -++{ -++ return false; -++} -++static inline bool usb_amd_prefetch_quirk(void) -++{ -++ return false; -++} -+ static inline void usb_amd_quirk_pll_disable(void) {} -+ static inline void usb_amd_quirk_pll_enable(void) {} -+ static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {} -+@@ -30,6 +45,11 @@ static inline bool usb_amd_pt_check_port -+ { -+ return false; -+ } -++static inline void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev) {} -++static inline bool usb_xhci_needs_pci_reset(struct pci_dev *pdev) -++{ -++ return false; -++} -+ #endif /* CONFIG_USB_PCI */ -+ -+ #endif /* __LINUX_USB_PCI_QUIRKS_H */ -+--- a/include/linux/usb/hcd.h -++++ b/include/linux/usb/hcd.h -+@@ -465,7 +465,14 @@ extern int usb_hcd_pci_probe(struct pci_ -+ extern void usb_hcd_pci_remove(struct pci_dev *dev); -+ extern void usb_hcd_pci_shutdown(struct pci_dev *dev); -+ -++#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS -+ extern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev); -++#else -++static inline int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev) -++{ -++ return 0; -++} -++#endif -+ -+ #ifdef CONFIG_PM -+ extern const struct dev_pm_ops usb_hcd_pci_pm_ops; -diff --git a/target/linux/generic/pending-4.14/834-ledtrig-libata.patch b/target/linux/generic/pending-4.14/834-ledtrig-libata.patch -new file mode 100644 -index 0000000000..8a15efdc0e ---- /dev/null -+++ b/target/linux/generic/pending-4.14/834-ledtrig-libata.patch -@@ -0,0 +1,149 @@ -+From: Daniel Golle -+Subject: libata: add ledtrig support -+ -+This adds a LED trigger for each ATA port indicating disk activity. -+ -+As this is needed only on specific platforms (NAS SoCs and such), -+these platforms should define ARCH_WANTS_LIBATA_LEDS if there -+are boards with LED(s) intended to indicate ATA disk activity and -+need the OS to take care of that. -+In that way, if not selected, LED trigger support not will be -+included in libata-core and both, codepaths and structures remain -+untouched. -+ -+Signed-off-by: Daniel Golle -+--- -+ drivers/ata/Kconfig | 16 ++++++++++++++++ -+ drivers/ata/libata-core.c | 41 +++++++++++++++++++++++++++++++++++++++++ -+ include/linux/libata.h | 9 +++++++++ -+ 3 files changed, 66 insertions(+) -+ -+--- a/drivers/ata/Kconfig -++++ b/drivers/ata/Kconfig -+@@ -46,6 +46,22 @@ config ATA_VERBOSE_ERROR -+ -+ If unsure, say Y. -+ -++config ARCH_WANT_LIBATA_LEDS -++ bool -++ -++config ATA_LEDS -++ bool "support ATA port LED triggers" -++ depends on ARCH_WANT_LIBATA_LEDS -++ select NEW_LEDS -++ select LEDS_CLASS -++ select LEDS_TRIGGERS -++ default y -++ help -++ This option adds a LED trigger for each registered ATA port. -++ It is used to drive disk activity leds connected via GPIO. -++ -++ If unsure, say N. -++ -+ config ATA_ACPI -+ bool "ATA ACPI Support" -+ depends on ACPI -+--- a/drivers/ata/libata-core.c -++++ b/drivers/ata/libata-core.c -+@@ -730,6 +730,19 @@ u64 ata_tf_read_block(const struct ata_t -+ return block; -+ } -+ -++#ifdef CONFIG_ATA_LEDS -++#define LIBATA_BLINK_DELAY 20 /* ms */ -++static inline void ata_led_act(struct ata_port *ap) -++{ -++ unsigned long led_delay = LIBATA_BLINK_DELAY; -++ -++ if (unlikely(!ap->ledtrig)) -++ return; -++ -++ led_trigger_blink_oneshot(ap->ledtrig, &led_delay, &led_delay, 0); -++} -++#endif -++ -+ /** -+ * ata_build_rw_tf - Build ATA taskfile for given read/write request -+ * @tf: Target ATA taskfile -+@@ -5123,6 +5136,9 @@ struct ata_queued_cmd *ata_qc_new_init(s -+ if (tag < 0) -+ return NULL; -+ } -++#ifdef CONFIG_ATA_LEDS -++ ata_led_act(ap); -++#endif -+ -+ qc = __ata_qc_from_tag(ap, tag); -+ qc->tag = tag; -+@@ -6024,6 +6040,9 @@ struct ata_port *ata_port_alloc(struct a -+ ap->stats.unhandled_irq = 1; -+ ap->stats.idle_irq = 1; -+ #endif -++#ifdef CONFIG_ATA_LEDS -++ ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); -++#endif -+ ata_sff_port_init(ap); -+ -+ return ap; -+@@ -6045,6 +6064,12 @@ static void ata_host_release(struct devi -+ -+ kfree(ap->pmp_link); -+ kfree(ap->slave_link); -++#ifdef CONFIG_ATA_LEDS -++ if (ap->ledtrig) { -++ led_trigger_unregister(ap->ledtrig); -++ kfree(ap->ledtrig); -++ }; -++#endif -+ kfree(ap); -+ host->ports[i] = NULL; -+ } -+@@ -6491,7 +6516,23 @@ int ata_host_register(struct ata_host *h -+ host->ports[i]->print_id = atomic_inc_return(&ata_print_id); -+ host->ports[i]->local_port_no = i + 1; -+ } -++#ifdef CONFIG_ATA_LEDS -++ for (i = 0; i < host->n_ports; i++) { -++ if (unlikely(!host->ports[i]->ledtrig)) -++ continue; -+ -++ snprintf(host->ports[i]->ledtrig_name, -++ sizeof(host->ports[i]->ledtrig_name), "ata%u", -++ host->ports[i]->print_id); -++ -++ host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name; -++ -++ if (led_trigger_register(host->ports[i]->ledtrig)) { -++ kfree(host->ports[i]->ledtrig); -++ host->ports[i]->ledtrig = NULL; -++ } -++ } -++#endif -+ /* Create associated sysfs transport objects */ -+ for (i = 0; i < host->n_ports; i++) { -+ rc = ata_tport_add(host->dev,host->ports[i]); -+--- a/include/linux/libata.h -++++ b/include/linux/libata.h -+@@ -39,6 +39,9 @@ -+ #include -+ #include -+ #include -++#ifdef CONFIG_ATA_LEDS -++#include -++#endif -+ -+ /* -+ * Define if arch has non-standard setup. This is a _PCI_ standard -+@@ -893,6 +896,12 @@ struct ata_port { -+ #ifdef CONFIG_ATA_ACPI -+ struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */ -+ #endif -++ -++#ifdef CONFIG_ATA_LEDS -++ struct led_trigger *ledtrig; -++ char ledtrig_name[8]; -++#endif -++ -+ /* owned by EH */ -+ u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned; -+ }; -diff --git a/target/linux/generic/pending-4.14/920-mangle_bootargs.patch b/target/linux/generic/pending-4.14/920-mangle_bootargs.patch -new file mode 100644 -index 0000000000..2f6a52c23d ---- /dev/null -+++ b/target/linux/generic/pending-4.14/920-mangle_bootargs.patch -@@ -0,0 +1,71 @@ -+From: Imre Kaloz -+Subject: init: add CONFIG_MANGLE_BOOTARGS and disable it by default -+ -+Enabling this option renames the bootloader supplied root= -+and rootfstype= variables, which might have to be know but -+would break the automatisms OpenWrt uses. -+ -+Signed-off-by: Imre Kaloz -+--- -+ init/Kconfig | 9 +++++++++ -+ init/main.c | 24 ++++++++++++++++++++++++ -+ 2 files changed, 33 insertions(+) -+ -+--- a/init/Kconfig -++++ b/init/Kconfig -+@@ -1427,6 +1427,15 @@ config EMBEDDED -+ an embedded system so certain expert options are available -+ for configuration. -+ -++config MANGLE_BOOTARGS -++ bool "Rename offending bootargs" -++ depends on EXPERT -++ help -++ Sometimes the bootloader passed bogus root= and rootfstype= -++ parameters to the kernel, and while you want to ignore them, -++ you need to know the values f.e. to support dual firmware -++ layouts on the flash. -++ -+ config HAVE_PERF_EVENTS -+ bool -+ help -+--- a/init/main.c -++++ b/init/main.c -+@@ -358,6 +358,29 @@ static inline void setup_nr_cpu_ids(void -+ static inline void smp_prepare_cpus(unsigned int maxcpus) { } -+ #endif -+ -++#ifdef CONFIG_MANGLE_BOOTARGS -++static void __init mangle_bootargs(char *command_line) -++{ -++ char *rootdev; -++ char *rootfs; -++ -++ rootdev = strstr(command_line, "root=/dev/mtdblock"); -++ -++ if (rootdev) -++ strncpy(rootdev, "mangled_rootblock=", 18); -++ -++ rootfs = strstr(command_line, "rootfstype"); -++ -++ if (rootfs) -++ strncpy(rootfs, "mangled_fs", 10); -++ -++} -++#else -++static void __init mangle_bootargs(char *command_line) -++{ -++} -++#endif -++ -+ /* -+ * We need to store the untouched command line for future reference. -+ * We also need to store the touched command line since the parameter -+@@ -539,6 +562,7 @@ asmlinkage __visible void __init start_k -+ add_device_randomness(command_line, strlen(command_line)); -+ boot_init_stack_canary(); -+ mm_init_cpumask(&init_mm); -++ mangle_bootargs(command_line); -+ setup_command_line(command_line); -+ setup_nr_cpu_ids(); -+ setup_per_cpu_areas(); -diff --git a/tools/Makefile b/tools/Makefile -index a2665dbc9a..0b8727205e 100644 ---- a/tools/Makefile -+++ b/tools/Makefile -@@ -30,7 +30,7 @@ tools-$(BUILD_B43_TOOLS) += b43-tools - tools-$(BUILD_ISL) += isl - tools-$(BUILD_TOOLCHAIN) += expat gmp libelf mpc mpfr - tools-$(CONFIG_TARGET_apm821xx)$(CONFIG_TARGET_gemini) += genext2fs --tools-$(CONFIG_TARGET_ath79) += lzma-old squashfs -+tools-$(CONFIG_TARGET_ath79)tools-$(CONFIG_TARGET_ar71xx) += lzma-old squashfs - tools-$(CONFIG_TARGET_mxs) += elftosb sdimage - tools-$(CONFIG_TARGET_tegra) += cbootimage cbootimage-configs - tools-$(CONFIG_USES_MINOR) += kernel2minor --- -2.25.1 - diff --git a/profiles/mikrotik_nand.yml b/profiles/mikrotik_nand.yml deleted file mode 100644 index f05418a1d..000000000 --- a/profiles/mikrotik_nand.yml +++ /dev/null @@ -1,21 +0,0 @@ ---- -profile: nand-large-ac -target: ar71xx -subtarget: mikrotik -description: Build image for the Mikrotik RouterBoards -image: bin/targets/ar71xx/mikrotik/openwrt-ar71xx-mikrotik-nand-large-ac-squashfs-sysupgrade.bin -include: - - ucentral-ap-mikrotik -packages: - - ath10k-firmware-qca4019-ct-htt - - ath10k-firmware-qca9888-ct-htt - - ath10k-firmware-qca9984-ct-htt - - ath10k-board-qca9887 - - ath10k-board-qca9888 - - ath10k-board-qca988x - - ath10k-board-qca9984 - - ath10k-board-qca99x0 -diffconfig: | - # CONFIG_PACKAGE_ath10k-firmware-qca4019-ct is not set - # CONFIG_PACKAGE_ath10k-firmware-qca9888-ct is not set - # CONFIG_PACKAGE_ath10k-firmware-qca9984-ct is not set